/*
 * SDK Pullenti Unitext, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software. 
 * This class is generated using the converter UniSharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

const Utils = require("./../../../unisharp/Utils");
const KeyValuePair = require("./../../../unisharp/KeyValuePair");
const RefOutArgWrapper = require("./../../../unisharp/RefOutArgWrapper");
const Stream = require("./../../../unisharp/Stream");
const MemoryStream = require("./../../../unisharp/MemoryStream");

const Stshi = require("./Stshi");
const MiscHelper = require("./../../../util/MiscHelper");
const Stshif = require("./Stshif");
const LSD = require("./LSD");
const StshiLsd = require("./StshiLsd");
const StdfPost2000OrNone = require("./StdfPost2000OrNone");
const GRFSTD = require("./GRFSTD");
const GrLPUpxSw = require("./GrLPUpxSw");
const Xst = require("./Xst");
const Xstz = require("./Xstz");
const StkParaGRLPUPX = require("./StkParaGRLPUPX");
const StkTableGRLPUPX = require("./StkTableGRLPUPX");
const StkCharUpxGrLPUpxRM = require("./StkCharUpxGrLPUpxRM");
const UpxTapx = require("./UpxTapx");
const DTTM = require("./DTTM");
const StkListGRLPUPX = require("./StkListGRLPUPX");
const UpxRm = require("./UpxRm");
const StkParaUpxGrLPUpxRM = require("./StkParaUpxGrLPUpxRM");
const UpxPapx = require("./UpxPapx");
const StkCharGRLPUPX = require("./StkCharGRLPUPX");
const UpxChpx = require("./UpxChpx");
const StdfBase = require("./StdfBase");
const FcCompressed = require("./FcCompressed");
const Pcd = require("./Pcd");
const Prm = require("./Prm");
const SinglePropertyModifiers = require("./SinglePropertyModifiers");
const Prl = require("./Prl");
const Prc = require("./Prc");
const ReadUtils = require("./ReadUtils");
const Pcdt = require("./Pcdt");
const PlcPcd = require("./PlcPcd");
const Clx = require("./Clx");
const Sprm = require("./Sprm");
const Chpx = require("./Chpx");
const ChpxFkp = require("./ChpxFkp");
const STSH = require("./STSH");
const Stdf = require("./Stdf");
const STD = require("./STD");
const PapxFkp = require("./PapxFkp");
const PlcBtePapx = require("./PlcBtePapx");
const PapxInFkps = require("./PapxInFkps");
const PlcBteChpx = require("./PlcBteChpx");
const GrpPrlAndIstd = require("./GrpPrlAndIstd");

class BasicTypesReader {
    
    static readClx(s, length) {
        let position = 0;
        let prcs = new Array();
        if (length < 1) 
            return null;
        let clxt = ReadUtils.readByte(s);
        position++;
        while (clxt === Prc.defaultClxt) {
            let read = 0;
            let wrapread411 = new RefOutArgWrapper();
            prcs.push(BasicTypesReader.readPrcWithoutCltx(s, length - position, wrapread411));
            read = wrapread411.value;
            position += read;
            if (position >= length) 
                return null;
            clxt = ReadUtils.readByte(s);
            position++;
        }
        if (clxt !== Pcdt.defaultClxt) 
            return null;
        let pcdt = BasicTypesReader.readPcdtWithoutClxt(s, length - position);
        let clx = new Clx();
        clx.rgPrc = prcs;
        clx.pcdt = pcdt;
        return clx;
    }
    
    static readCPs(s, length) {
        let res = new Array();
        while ((s.position + (4)) <= s.length && length > 0) {
            let ui = ReadUtils.readInt(s);
            if (ui < 0) 
                break;
            res.push(ui);
            length -= 4;
        }
        return res;
    }
    
    static readPcdtWithoutClxt(s, length) {
        if (length < ReadUtils.dWordSize) 
            throw new Error("Invalid Prc: length");
        let read = 0;
        let pcdt = new Pcdt();
        pcdt.clxt = Pcdt.defaultClxt;
        let wrapread412 = new RefOutArgWrapper(read);
        pcdt.lcb = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.dWordSize, wrapread412), 0, 'uint', 4);
        read = wrapread412.value;
        if (((read) + (pcdt.lcb)) > length) 
            throw new Error("Invalid Prc: length");
        pcdt.plcPcd = BasicTypesReader.readPlcPcd(s, pcdt.lcb);
        return pcdt;
    }
    
    static readPlcPcd(s, length) {
        if (Utils.compareUnsigned(length, 4) < 0) 
            throw new Error("Invalid Prc: length (0)");
        let n = PlcPcd.calcLength(length);
        let read = 0;
        let plcPcd = new PlcPcd();
        plcPcd.cPs = Array(n + 1).fill(0);
        for (let i = 0; i <= n; i++) {
            let wrapread413 = new RefOutArgWrapper(read);
            plcPcd.cPs[i] = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.dWordSize, wrapread413), 0, 'uint', 4);
            read = wrapread413.value;
        }
        plcPcd.pcds = Array(n).fill(null);
        for (let i = 0; i < n; i++) {
            plcPcd.pcds[i] = BasicTypesReader.readPcd(s);
            read += Pcd.size;
        }
        if (read !== (length)) 
            throw new Error("Invalid PlcPcd: length");
        return plcPcd;
    }
    
    static readPcd(s) {
        let data = ReadUtils.readExact(s, Pcd.size);
        let pcd = new Pcd();
        pcd.fNoParaLast = (((data[0]) & 0x01)) !== 0;
        pcd.fR1 = (((data[0]) & 0x02)) !== 0;
        pcd.fDirty = (((data[0]) & 0x04)) !== 0;
        let uCompressed = Utils.bytesToObject(data, 2, 'uint', 4);
        let comressed = new FcCompressed();
        comressed.fc = ((uCompressed) & 0x3FFFFFFF);
        comressed.fCompressed = (((uCompressed) & 0x40000000)) !== 0;
        pcd.fc = comressed;
        let uPrm = Utils.bytesToObject(data, 6, 'ushort', 2);
        let prm = new Prm();
        prm.prm = uPrm;
        pcd.prm = prm;
        return pcd;
    }
    
    static readPrcWithoutCltx(s, length, read) {
        if (length < ReadUtils.wordSize) 
            throw new Error("Invalid Prc: length");
        read.value = 0;
        let prc = new Prc();
        prc.clxt = Prc.defaultClxt;
        prc.cbGrpprl = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'short', 2);
        let cbGrpprl = prc.cbGrpprl;
        if ((length < cbGrpprl) || (cbGrpprl < 0)) 
            throw new Error("Invalid Prc: array length");
        prc.grpPrl = BasicTypesReader.readPrls(s, cbGrpprl, read);
        return prc;
    }
    
    static readPrls(s, length, read) {
        let prls = new Array();
        let position = 0;
        while (position < length) {
            let readPortion = 0;
            if ((length - position) === 1) 
                readPortion = 1;
            else 
                try {
                    let wrapreadPortion414 = new RefOutArgWrapper();
                    let prl = BasicTypesReader.readPrl(s, length - position, wrapreadPortion414);
                    readPortion = wrapreadPortion414.value;
                    if (prl === null) 
                        break;
                    prls.push(prl);
                } catch (ex415) {
                    break;
                }
            position += readPortion;
        }
        read.value += position;
        return prls;
    }
    
    static readPrl(s, length, read) {
        if (length < 2) 
            throw new Error("Invalid Prl: length");
        read.value = 0;
        let prl = new Prl(BasicTypesReader.readSprm(s, read), null);
        let operandLength = BasicTypesReader.getLengthFromSprm(prl.sprm);
        if (operandLength < 0) {
            if (Utils.compareUnsigned(prl.sprm.sprm, SinglePropertyModifiers.sprmPChgTabs) == 0) {
                if ((read.value + ReadUtils.byteSize) > length) 
                    throw new Error("Invalid Prl: operand length (1)");
                operandLength = ReadUtils.readByteRef(s, read);
                if (operandLength === 255) {
                    if ((read.value + ReadUtils.byteSize) > length) 
                        throw new Error("Invalid Prl: operand length (2)");
                    operandLength = ReadUtils.readByteRef(s, read);
                    let ms = new MemoryStream(); 
                    try {
                        let cTabs = ReadUtils.readByte(s);
                        ms.writeByte(cTabs);
                        let delPortionSize = 1 + ((cTabs) * 4);
                        if ((read.value + delPortionSize) > length) 
                            throw new Error("Invalid Prl: operand length (3)");
                        let data = ReadUtils.readExact(s, (cTabs) * 4);
                        ms.write(data, 0, data.length);
                        if ((read.value + 1 + delPortionSize) > length) 
                            throw new Error("Invalid Prl: operand length (4)");
                        cTabs = ReadUtils.readByte(s);
                        ms.writeByte(cTabs);
                        let addPortionSize = 1 + ((cTabs) * 3);
                        if ((read.value + delPortionSize + addPortionSize) > length) 
                            throw new Error("Invalid Prl: operand length (5)");
                        data = ReadUtils.readExact(s, (cTabs) * 3);
                        ms.write(data, 0, data.length);
                        data = ms.toByteArray();
                        operandLength = data.length;
                        prl.operand = data;
                    }
                    finally {
                        ms.close();
                    }
                    read.value += operandLength;
                    return prl;
                }
            }
            else if (Utils.compareUnsigned(prl.sprm.sprm, SinglePropertyModifiers.sprmTDefTable) == 0) {
                if ((read.value + ReadUtils.wordSize) > length) 
                    return null;
                operandLength = (Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'ushort', 2)) + 1;
            }
            else {
                if ((read.value + ReadUtils.byteSize) > length) 
                    return null;
                operandLength = ReadUtils.readByteRef(s, read);
            }
        }
        if ((read.value + operandLength) > length) 
            return null;
        prl.operand = ReadUtils.readExactRef(s, operandLength, read);
        return prl;
    }
    
    static readSprm(s, read) {
        let data = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'ushort', 2);
        if (Utils.compareUnsigned(data, SinglePropertyModifiers.sprmTVertMerge) == 0 || Utils.compareUnsigned(data, SinglePropertyModifiers.sprmTMerge) == 0) {
        }
        return new Sprm(data);
    }
    
    static getLengthFromSprm(sprm) {
        switch (sprm.spra) { 
        case 0: 
        case 1: {
            return 1;
        }
        case 2: 
        case 4: 
        case 5: {
            return 2;
        }
        case 3: {
            return 4;
        }
        case 6: {
            return -1;
        }
        case 7: {
            return 3;
        }
        default: {
            throw new Error("Invalid Sprm.spra value");
        }
        }
    }
    
    static readPlcfBtePapx(s, length) {
        let n = PlcBtePapx.getLength(length);
        let plcfBtePapx = new PlcBtePapx();
        plcfBtePapx.aFC = Array(n + 1).fill(0);
        for (let i = 0; i <= n; i++) {
            plcfBtePapx.aFC[i] = Utils.bytesToObject(ReadUtils.readExact(s, ReadUtils.dWordSize), 0, 'uint', 4);
        }
        plcfBtePapx.aPnBtePapx = Array(n).fill(0);
        for (let i = 0; i < n; i++) {
            let pn = Utils.bytesToObject(ReadUtils.readExact(s, ReadUtils.dWordSize), 0, 'uint', 4);
            plcfBtePapx.aPnBtePapx[i] = pn;
        }
        return plcfBtePapx;
    }
    
    static readPapxFkp(s, err) {
        err.value = false;
        let data = ReadUtils.readExact(s, PapxFkp.size);
        let dataStream = new MemoryStream(data); 
        try {
            let papxFkp = new PapxFkp();
            papxFkp.cpara = data[PapxFkp.size - 1];
            let cpara = papxFkp.cpara;
            if ((cpara < 1) || cpara > 0x1D) 
                throw new Error("Invalid PapxFkp: cpara");
            papxFkp.rgfc = Array(cpara + 1).fill(0);
            for (let i = 0; i <= cpara; i++) {
                papxFkp.rgfc[i] = Utils.bytesToObject(data, i * 4, 'uint', 4);
            }
            papxFkp.rgbx = Array(cpara).fill(null);
            let rgbxOffset = ((cpara + 1)) * 4;
            for (let i = 0; i < cpara; i++) {
                let bOffset = data[rgbxOffset + (i * 13)];
                let papxInFkpsOffset = 2 * (bOffset);
                let papxInFkps = new PapxInFkps();
                papxInFkps.cb = data[papxInFkpsOffset++];
                let grpprlInPapxLength = 0;
                if (papxInFkps.cb === (0)) {
                    let cb_ = data[papxInFkpsOffset++];
                    grpprlInPapxLength = 2 * cb_;
                }
                else 
                    grpprlInPapxLength = (2 * (papxInFkps.cb)) - 1;
                let grpPrlAndIstd = new GrpPrlAndIstd();
                grpPrlAndIstd.istd = Utils.bytesToObject(data, papxInFkpsOffset, 'ushort', 2);
                dataStream.position = papxInFkpsOffset + 2;
                let position = 2;
                papxInFkps.grpprlInPapx = grpPrlAndIstd;
                papxFkp.rgbx[i] = new KeyValuePair(bOffset, papxInFkps);
                try {
                    let wrapposition416 = new RefOutArgWrapper(position);
                    grpPrlAndIstd.grpprl = BasicTypesReader.readPrls(dataStream, grpprlInPapxLength - position, wrapposition416);
                    position = wrapposition416.value;
                } catch (ex) {
                    err.value = true;
                    break;
                }
            }
            return papxFkp;
        }
        finally {
            dataStream.close();
        }
    }
    
    static readPlcBteChpx(s, length) {
        let n = PlcBteChpx.getLength(length);
        let plcfBteChpx = new PlcBteChpx();
        plcfBteChpx.aFC = Array(n + 1).fill(0);
        for (let i = 0; i <= n; i++) {
            plcfBteChpx.aFC[i] = Utils.bytesToObject(ReadUtils.readExact(s, ReadUtils.dWordSize), 0, 'uint', 4);
        }
        plcfBteChpx.aPnBteChpx = Array(n).fill(0);
        for (let i = 0; i < n; i++) {
            let pn = Utils.bytesToObject(ReadUtils.readExact(s, ReadUtils.dWordSize), 0, 'uint', 4);
            plcfBteChpx.aPnBteChpx[i] = pn;
        }
        return plcfBteChpx;
    }
    
    static readChpxFkp(s) {
        let data = ReadUtils.readExact(s, ChpxFkp.size);
        let dataStream = new MemoryStream(data); 
        try {
            let chpxFkp = new ChpxFkp();
            chpxFkp.crun = data[PapxFkp.size - 1];
            let crun = chpxFkp.crun;
            if ((crun < 1) || crun > 0x65) 
                throw new Error("Invalid ChpxFkp: cpara");
            chpxFkp.rgfc = Array(crun + 1).fill(0);
            for (let i = 0; i <= crun; i++) {
                chpxFkp.rgfc[i] = Utils.bytesToObject(data, i * ReadUtils.dWordSize, 'uint', 4);
            }
            chpxFkp.rgb = Array(crun).fill(null);
            let rgbOffset = ((crun + 1)) * ReadUtils.dWordSize;
            for (let i = 0; i < crun; i++) {
                let offset = data[rgbOffset + i];
                let chpxFkpOffset = 2 * (offset);
                let chpx = new Chpx();
                chpx.cb = data[chpxFkpOffset++];
                let grpprlLength = chpx.cb;
                dataStream.position = chpxFkpOffset;
                let position = 0;
                let wrapposition417 = new RefOutArgWrapper(position);
                chpx.grpprl = BasicTypesReader.readPrls(dataStream, grpprlLength - position, wrapposition417);
                position = wrapposition417.value;
                chpxFkp.rgb[i] = new KeyValuePair(offset, chpx);
            }
            return chpxFkp;
        }
        finally {
            dataStream.close();
        }
    }
    
    static readStsh(s, stshLength) {
        let read = 0;
        let stsh = new STSH();
        read = 0;
        let wrapread421 = new RefOutArgWrapper(read);
        let cbStshi = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, wrapread421), 0, 'ushort', 2);
        read = wrapread421.value;
        let readPortion = 0;
        let wrapreadPortion420 = new RefOutArgWrapper();
        let stshi = BasicTypesReader.readStshi(s, cbStshi, wrapreadPortion420);
        readPortion = wrapreadPortion420.value;
        read += readPortion;
        stsh.stshi = stshi;
        stsh.rglpstd = Array(stsh.stshi.stshif.cstd).fill(null);
        for (let i = 0; i < stsh.rglpstd.length; i++) {
            let wrapread419 = new RefOutArgWrapper(read);
            let cbStd = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, wrapread419), 0, 'ushort', 2);
            read = wrapread419.value;
            if (Utils.compareUnsigned(cbStd, 0) > 0) {
                let wrapreadPortion418 = new RefOutArgWrapper();
                let std = BasicTypesReader.readStd(s, cbStd, stshi.stshif.cbSTDBaseInFile, wrapreadPortion418);
                readPortion = wrapreadPortion418.value;
                stsh.rglpstd[i] = std;
                read += readPortion;
            }
        }
        return stsh;
    }
    
    static readStd(s, length, stdfLength, read) {
        let std = new STD();
        read.value = 0;
        let stdf = new Stdf();
        let stdfBase = new StdfBase();
        let data = ReadUtils.readExactRef(s, StdfBase.size, read);
        stdfBase.sti = ((Utils.bytesToObject(data, 0, 'ushort', 2)) & 0xFFF);
        stdfBase.stk = ((data[2]) & 0x0F);
        stdfBase.istdBase = ((Utils.bytesToObject(data, 2, 'ushort', 2)) >>> 4);
        stdfBase.cupx = ((data[4]) & 0x0F);
        stdfBase.istdNext = ((Utils.bytesToObject(data, 4, 'ushort', 2)) >>> 4);
        stdfBase.bchUpe = Utils.bytesToObject(data, 6, 'ushort', 2);
        let grfstdData = Utils.bytesToObject(data, 8, 'ushort', 2);
        let grfstd = new GRFSTD();
        grfstd.fAutoRedef = (((grfstdData) & 0x0001)) !== 0;
        grfstd.fHidden = (((grfstdData) & 0x0002)) !== 0;
        grfstd.f97LidsSet = (((grfstdData) & 0x0004)) !== 0;
        grfstd.fCopyLang = (((grfstdData) & 0x0008)) !== 0;
        grfstd.fPersonalCompose = (((grfstdData) & 0x0010)) !== 0;
        grfstd.fPersonalReply = (((grfstdData) & 0x0020)) !== 0;
        grfstd.fPersonal = (((grfstdData) & 0x0040)) !== 0;
        grfstd.fSemiHidden = (((grfstdData) & 0x0100)) !== 0;
        grfstd.fLocked = (((grfstdData) & 0x0200)) !== 0;
        grfstd.fUnhideWhenUsed = (((grfstdData) & 0x0800)) !== 0;
        grfstd.fQFormat = (((grfstdData) & 0x1000)) !== 0;
        stdfBase.grfstd = grfstd;
        stdf.stdfBase = stdfBase;
        if ((StdfBase.size + StdfPost2000OrNone.size) <= (stdfLength)) {
            data = ReadUtils.readExactRef(s, StdfPost2000OrNone.size, read);
            let stdfPost2000 = new StdfPost2000OrNone();
            stdfPost2000.istdLink = ((Utils.bytesToObject(data, 0, 'ushort', 2)) & 0xFFF);
            stdfPost2000.fHasOriginalStyle = (((data[1]) & 0x10)) !== 0;
            stdfPost2000.rsid = Utils.bytesToObject(data, 2, 'uint', 4);
            stdfPost2000.iPriority = ((Utils.bytesToObject(data, 6, 'ushort', 2)) >>> 4);
            stdf.stdfPost2000OrNone = stdfPost2000;
        }
        else 
            stdf.stdfPost2000OrNone = null;
        std.stdf = stdf;
        std.xstzName = BasicTypesReader.readXstz(s, (length) - read.value, read);
        switch (std.stdf.stdfBase.stk) { 
        case GrLPUpxSw.stkParaGRLPUPXStkValue: {
            std.grLPUpxSw = BasicTypesReader.readStkParaGRLPUPX(s, (length) - read.value, read);
            break;
        }
        case GrLPUpxSw.stkCharGRLPUPXStkValue: {
            std.grLPUpxSw = BasicTypesReader.readStkCharGRLPUPX(s, (length) - read.value, read);
            break;
        }
        case GrLPUpxSw.stkTableGRLPUPXStkValue: {
            std.grLPUpxSw = BasicTypesReader.readStkTableGRLPUPX(s, (length) - read.value, read);
            break;
        }
        case GrLPUpxSw.stkListGRLPUPXStkValue: {
            std.grLPUpxSw = BasicTypesReader.readStkListGRLPUPX(s, (length) - read.value, read);
            break;
        }
        default: {
            throw new Error("Invalid Std: stk");
        }
        }
        return std;
    }
    
    static readXstz(s, length, read) {
        let xstz = new Xstz();
        xstz.xst = new Xst();
        if (length < ReadUtils.wordSize) 
            throw new Error("Invalid Xst: length (0)");
        xstz.xst.cch = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'ushort', 2);
        if (length < (ReadUtils.wordSize + (2 * (xstz.xst.cch)))) 
            throw new Error("Invalid Xst: length (1)");
        xstz.xst.rgtchar = MiscHelper.decodeStringUnicode(ReadUtils.readExactRef(s, 2 * (xstz.xst.cch), read), 0, -1).split('');
        if (length < (ReadUtils.wordSize + (2 * (xstz.xst.cch)) + ReadUtils.wordSize)) 
            throw new Error("Invalid Xstz: length");
        let zeros = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'ushort', 2);
        if (Utils.compareUnsigned(zeros, 0) != 0) 
            throw new Error("Invalid Xstz: no zeros");
        return xstz;
    }
    
    static readStshi(s, length, read) {
        let stshi = new Stshi();
        read.value = 0;
        if (length < 18) 
            throw new Error("Invalid Stshi: length (0)");
        let data = ReadUtils.readExactRef(s, 18, read);
        let stshif = new Stshif();
        stshif.cstd = Utils.bytesToObject(data, 0, 'ushort', 2);
        stshif.cbSTDBaseInFile = Utils.bytesToObject(data, 2, 'ushort', 2);
        stshif.stiMaxWhenSaved = Utils.bytesToObject(data, 6, 'ushort', 2);
        stshif.istdMaxFixedWhenSaved = Utils.bytesToObject(data, 8, 'ushort', 2);
        stshif.nVerBuiltInNamesWhenSaved = Utils.bytesToObject(data, 10, 'ushort', 2);
        stshif.ftcAsci = Utils.bytesToObject(data, 12, 'short', 2);
        stshif.ftcFE = Utils.bytesToObject(data, 14, 'short', 2);
        stshif.ftcOther = Utils.bytesToObject(data, 16, 'short', 2);
        stshi.stshif = stshif;
        if (read.value < length) 
            stshi.ftcBi = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'short', 2);
        if (read.value < length) {
            let stshiLsd = new StshiLsd();
            stshiLsd.cbLSD = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'ushort', 2);
            stshiLsd.mpstiilsd = Array(stshif.stiMaxWhenSaved).fill(null);
            for (let i = 0; i < stshiLsd.mpstiilsd.length; i++) {
                data = ReadUtils.readExactRef(s, stshiLsd.cbLSD, read);
                let lsd = new LSD();
                lsd.fLocked = (((data[0]) & 0x01)) !== 0;
                lsd.fSemiHidden = (((data[0]) & 0x02)) !== 0;
                lsd.fUnhideWhenUsed = (((data[0]) & 0x04)) !== 0;
                lsd.fQFormat = (((data[0]) & 0x08)) !== 0;
                lsd.iPriority = (((data[1]) << 4) | (((data[0]) >>> 4)));
                stshiLsd.mpstiilsd[i] = lsd;
            }
            stshi.stshiLsd = stshiLsd;
        }
        if (read.value < length) {
            let grpprlChpStandard_cbGrpprl = Utils.bytesToObject(ReadUtils.readExact(s, ReadUtils.dWordSize), 0, 'int', 4);
            ReadUtils.skip(s, grpprlChpStandard_cbGrpprl);
            read.value += (4 + grpprlChpStandard_cbGrpprl);
            let grpprlPapStandard_cbGrpprl = Utils.bytesToObject(ReadUtils.readExact(s, ReadUtils.dWordSize), 0, 'int', 4);
            ReadUtils.skip(s, grpprlPapStandard_cbGrpprl);
            read.value += (4 + grpprlPapStandard_cbGrpprl);
        }
        return stshi;
    }
    
    static readStkParaGRLPUPX(s, length, read) {
        let position = 0;
        let stkParaGRLPUPX = new StkParaGRLPUPX();
        let wrapposition426 = new RefOutArgWrapper(position);
        stkParaGRLPUPX.upxPapx = BasicTypesReader.readUpxPapx(s, length - position, wrapposition426);
        position = wrapposition426.value;
        let wrapposition425 = new RefOutArgWrapper(position);
        stkParaGRLPUPX.upxChpx = BasicTypesReader.readUpxChpx(s, length - position, wrapposition425);
        position = wrapposition425.value;
        if (position < length) {
            let stkParaUpxGrLPUpxRM = new StkParaUpxGrLPUpxRM();
            let wrapposition424 = new RefOutArgWrapper(position);
            stkParaUpxGrLPUpxRM.upxRm = BasicTypesReader.readUpxRm(s, length - position, wrapposition424);
            position = wrapposition424.value;
            let wrapposition423 = new RefOutArgWrapper(position);
            stkParaUpxGrLPUpxRM.upxPapxRM = BasicTypesReader.readUpxPapx(s, length - position, wrapposition423);
            position = wrapposition423.value;
            let wrapposition422 = new RefOutArgWrapper(position);
            stkParaUpxGrLPUpxRM.upxChpxRM = BasicTypesReader.readUpxChpx(s, length - position, wrapposition422);
            position = wrapposition422.value;
            stkParaGRLPUPX.stkParaLPUpxGrLPUpxRM = stkParaUpxGrLPUpxRM;
            ReadUtils.skip(s, length - position);
        }
        read.value += length;
        return stkParaGRLPUPX;
    }
    
    static readUpxRm(s, length, read) {
        if (length < UpxRm.size) 
            throw new Error("Invalid UpxRm: length");
        let upxRm = new UpxRm();
        upxRm.date = BasicTypesReader.readDTTM(s, read);
        upxRm.ibstAuthor = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'short', 2);
        return upxRm;
    }
    
    static readUpxPapx(s, length, read) {
        let upxPapx = new UpxPapx();
        let cbUpx = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'ushort', 2);
        if (((cbUpx) + ReadUtils.wordSize) > length) 
            throw new Error("Invalid UpxPapx: length");
        upxPapx.istd = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'ushort', 2);
        upxPapx.grpprlPapx = BasicTypesReader.readPrls(s, (cbUpx) - ReadUtils.wordSize, read);
        if ((((cbUpx) & 1)) !== 0) 
            ReadUtils.readByteRef(s, read);
        return upxPapx;
    }
    
    static readUpxChpx(s, length, read) {
        let upxChpx = new UpxChpx();
        let cbUpx = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'ushort', 2);
        if (((cbUpx) + ReadUtils.wordSize) > length) 
            throw new Error("Invalid UpxChpx: length");
        upxChpx.grpprlChpx = BasicTypesReader.readPrls(s, cbUpx, read);
        if ((((cbUpx) & 1)) !== 0) 
            ReadUtils.readByteRef(s, read);
        return upxChpx;
    }
    
    static readStkCharGRLPUPX(s, length, read) {
        let position = 0;
        let stkCharGRLPUPX = new StkCharGRLPUPX();
        let wrapposition429 = new RefOutArgWrapper(position);
        stkCharGRLPUPX.upxChpx = BasicTypesReader.readUpxChpx(s, length - position, wrapposition429);
        position = wrapposition429.value;
        if (position < length) {
            let stkCharUpxGrLPUpxRM = new StkCharUpxGrLPUpxRM();
            let wrapposition428 = new RefOutArgWrapper(position);
            stkCharUpxGrLPUpxRM.upxRm = BasicTypesReader.readUpxRm(s, length - position, wrapposition428);
            position = wrapposition428.value;
            let wrapposition427 = new RefOutArgWrapper(position);
            stkCharUpxGrLPUpxRM.upxChpxRM = BasicTypesReader.readUpxChpx(s, length - position, wrapposition427);
            position = wrapposition427.value;
            stkCharGRLPUPX.stkCharLPUpxGrLPUpxRM = stkCharUpxGrLPUpxRM;
            ReadUtils.skip(s, length - position);
        }
        read.value += length;
        return stkCharGRLPUPX;
    }
    
    static readStkTableGRLPUPX(s, length, read) {
        let stkTableGRLPUPX = new StkTableGRLPUPX();
        let position = 0;
        let wrapposition432 = new RefOutArgWrapper(position);
        stkTableGRLPUPX.upxTapx = BasicTypesReader.readUpxTapx(s, length - position, wrapposition432);
        position = wrapposition432.value;
        let wrapposition431 = new RefOutArgWrapper(position);
        stkTableGRLPUPX.upxPapx = BasicTypesReader.readUpxPapx(s, length - position, wrapposition431);
        position = wrapposition431.value;
        let wrapposition430 = new RefOutArgWrapper(position);
        stkTableGRLPUPX.upxChpx = BasicTypesReader.readUpxChpx(s, length - position, wrapposition430);
        position = wrapposition430.value;
        read.value += position;
        return stkTableGRLPUPX;
    }
    
    static readUpxTapx(s, length, read) {
        let upxTapx = new UpxTapx();
        let cbUpx = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.wordSize, read), 0, 'ushort', 2);
        if (((cbUpx) + ReadUtils.wordSize) > length) 
            throw new Error("Invalid UpxTapx: length");
        upxTapx.grpprlTapx = BasicTypesReader.readPrls(s, cbUpx, read);
        if ((((cbUpx) & 1)) !== 0) 
            ReadUtils.readByteRef(s, read);
        return upxTapx;
    }
    
    static readStkListGRLPUPX(s, length, read) {
        let position = 0;
        let stkListGRLPUPX = new StkListGRLPUPX();
        let wrapposition433 = new RefOutArgWrapper(position);
        stkListGRLPUPX.upxPapx = BasicTypesReader.readUpxPapx(s, length - position, wrapposition433);
        position = wrapposition433.value;
        read.value += position;
        return stkListGRLPUPX;
    }
    
    static readDTTM(s, read) {
        let dttmData = Utils.bytesToObject(ReadUtils.readExactRef(s, ReadUtils.dWordSize, read), 0, 'uint', 4);
        return BasicTypesReader.parseDTTM(dttmData);
    }
    
    static parseDTTM(dttmData) {
        let dttm = new DTTM();
        dttm.mint = ((dttmData) & 0x3F);
        dttm.hr = ((((dttmData) >>> 6)) & 0x1F);
        dttm.dom = ((((dttmData) >>> 11)) & 0x1F);
        dttm.mon = ((((dttmData) >>> 16)) & 0x0F);
        dttm.year = ((((dttmData) >>> 20)) & 0x1FF);
        dttm.wdy = ((((dttmData) >>> 29)) & 0x07);
        return dttm;
    }
}


module.exports = BasicTypesReader