import { Platform } from "react-native";
import {
    MPosControllerLabelPrinter,
    Label_Bitmap_Font,
    Label_Vector_Font,
    Label_BarcodeType,
    Label_Barcode_Text,
    Label_CharacterSet,
    Label_drawBlock_Option,
    Label_InternationalCharset,
    Label_MaxiCodeMode,
    Label_MediaType,
    Label_Rotation,
    Label_PDF417_BarcodeOrigin,
    Label_PDF417_HRI,
    Label_PDF417_ECC,
    Label_PDF417_COMPRESSION,
    Label_QRCode_Model,
    Label_QRCode_EccLevel,
    Label_Code49_HRI,
    Label_Code49_StartingMode,
    Label_DataCompression,
    Label_CompressType,
    Label_CodaBlock_Mode,
    Label_MSI_HRI,
    Label_PLESSEY_HRI,
    Label_RSS_BarcodeType,
    Label_Orientation,
    Label_RFID_Type,
    Label_RFID_DataType,
    DeviceType,
    InterfaceType,
    APIResponse,
    TransactionMode,
} from "react-native-bixolon-bgatelib";

export class MPosLabelController {
    private static mPosLabelPrinter = new MPosControllerLabelPrinter();

    private onGetOccurredDatabackgroundMap = new Map<String, NodeJS.Timeout>;
    async openService(
        interfaceType: InterfaceType, 
        address: string,
        commandMode: number,
        deviceID: number,
        outputCompletedEvent?: (deviceid: number) => void,
        dataEvent?: (deviceid: number, data: Array<number>) => void): Promise<number> {
        await MPosLabelController.mPosLabelPrinter.selectInterface(interfaceType, address);
        await MPosLabelController.mPosLabelPrinter.selectCommandMode(commandMode);
        if (Platform.OS == "ios" || Platform.OS == "windows") {
            await MPosLabelController.mPosLabelPrinter.setKeepNetworkConnection(1);
        }

        let timeout = 3;
        let result = await MPosLabelController.mPosLabelPrinter.openService(deviceID, timeout);

        if (Platform.OS == "android") {
            await MPosLabelController.mPosLabelPrinter.setKeepNetworkConnection(1);
        }

        if (result == 0 || result == 1) {
            if (Platform.OS == 'android') {
                let intervalID = setInterval(async () => {
                    await this.onGetOccuredData(MPosLabelController.mPosLabelPrinter, dataEvent);
                }, 500);
                let backgroundMapValue = this.onGetOccurredDatabackgroundMap.get("label");

                if(backgroundMapValue != undefined) {
                    clearInterval(backgroundMapValue);
                }
                this.onGetOccurredDatabackgroundMap.set("label", intervalID);
            }
            MPosLabelController.mPosLabelPrinter.outputCompletedEvent = outputCompletedEvent;
            MPosLabelController.mPosLabelPrinter.dataEvent = dataEvent;
        }

        return result;
    }

        // For Android
        async onGetOccuredData(controller: any, dataEvent?: (b: number, a: number[]) => void): Promise<void> {
            var data: number[]|null = await controller.getOccuredData(); // controller must have getOccuredData method
            console.log('onGetOccuredData data: ' + data);
            if (data != null) {
                let deviceId = data.shift();
    
                if (deviceId != undefined) {
                    dataEvent?.call(this, deviceId, data);
                }
            }
            controller.getOccuredData();
        }

    async closeService(): Promise<number> {
        let timeout = 3;
        let result = await MPosLabelController.mPosLabelPrinter.closeService(timeout);

        return result;
    }

    async printLabelSample(labelMediaType: Label_MediaType = Label_MediaType.LABEL_MEDIA_TYPE_GAP) {
        try {
            let dotsPerUnit = 203 / 25.4;
            await MPosLabelController.mPosLabelPrinter.setTransaction(TransactionMode.MPOS_TRANSACTION_IN);
            await MPosLabelController.mPosLabelPrinter.setDensity(10);
            await MPosLabelController.mPosLabelPrinter.setMargin(0, 0);
            await MPosLabelController.mPosLabelPrinter.setOrientation(Label_Orientation.LABEL_ORIENTATION_BOTTOM);
            await MPosLabelController.mPosLabelPrinter.setAutoCutter(0, 0);
            await MPosLabelController.mPosLabelPrinter.setRewinder(0);
            await MPosLabelController.mPosLabelPrinter.setWidth(Math.floor(dotsPerUnit * 52));
            await MPosLabelController.mPosLabelPrinter.setLength(
                Math.floor(dotsPerUnit * 75),
                Math.floor(dotsPerUnit * 3),
                labelMediaType,
                0);
            await MPosLabelController.mPosLabelPrinter.drawBlock(0, 0,
                Math.floor(dotsPerUnit * 52),
                Math.floor(dotsPerUnit * 73),
                Label_drawBlock_Option.LABEL_BOX,
                Math.floor(dotsPerUnit * 2));
            await MPosLabelController.mPosLabelPrinter.setCharacterset(Label_CharacterSet.LABEL_CODEPAGE_PC437, Label_InternationalCharset.LABEL_ICS_USA);
            await MPosLabelController.mPosLabelPrinter.drawTextDeviceFont("Device Font",
                Math.floor(dotsPerUnit * 6),
                Math.floor(dotsPerUnit * 7),
                Label_Bitmap_Font.LABEL_DEVICE_FONT_15PT, 1, 1, 0, Label_Rotation.LABEL_ROTATION_0, 0, 0, 0, 0);
            await MPosLabelController.mPosLabelPrinter.drawTextVectorFont("Vector Font",
                Math.floor(dotsPerUnit * 6),
                Math.floor(dotsPerUnit * 13),
                Label_Vector_Font.LABEL_VECTOR_FONT_ASCII, 30, 30, 0, 0, 0, 0, 0, 0, 0);
            await MPosLabelController.mPosLabelPrinter.drawBarcode1D("0987654321",
                Math.floor(dotsPerUnit * 37),
                Math.floor(dotsPerUnit * 19),
                Label_BarcodeType.LABEL_BARCODE_CODE128, 2, 2, 128, Label_Barcode_Text.LABEL_BARCODE_TEXT_BELOW3, 0, 1);
            await MPosLabelController.mPosLabelPrinter.drawBase64Image(this.imgInBase64Format(),
                Math.floor(dotsPerUnit * 6),
                Math.floor(dotsPerUnit * 46),
                300, 128, 1, Label_CompressType.LABEL_IMAGE_RLE);
            await MPosLabelController.mPosLabelPrinter.printBuffer(1);
            await MPosLabelController.mPosLabelPrinter.setTransaction(TransactionMode.MPOS_TRANSACTION_OUT);
        } catch (e) {
            console.error("Exception : " + e);
        }
    }

    async printLabelBarcodes(labelMediaType: Label_MediaType = Label_MediaType.LABEL_MEDIA_TYPE_GAP) {
        try {
            let dotsPerUnit = 203 / 25.4;
            console.log('Printer Status: ' + await MPosLabelController.mPosLabelPrinter.checkPrinterStatus());
            await MPosLabelController.mPosLabelPrinter.setTransaction(TransactionMode.MPOS_TRANSACTION_IN);
            await MPosLabelController.mPosLabelPrinter.setDensity(10);
            await MPosLabelController.mPosLabelPrinter.setMargin(0, 0);
            await MPosLabelController.mPosLabelPrinter.setOrientation(Label_Orientation.LABEL_ORIENTATION_BOTTOM);
            await MPosLabelController.mPosLabelPrinter.setAutoCutter(0, 0);
            await MPosLabelController.mPosLabelPrinter.setRewinder(0);
            await MPosLabelController.mPosLabelPrinter.setOffset(0);
            await MPosLabelController.mPosLabelPrinter.setCuttingPosition(0);
            await MPosLabelController.mPosLabelPrinter.setWidth(Math.floor(dotsPerUnit * 52));
            await MPosLabelController.mPosLabelPrinter.setLength(Math.floor(dotsPerUnit * 360), Math.floor(dotsPerUnit * 3), labelMediaType, 0);
            await MPosLabelController.mPosLabelPrinter.drawBlock(Math.floor(dotsPerUnit * 8),
                Math.floor(dotsPerUnit * 7),
                Math.floor(dotsPerUnit * 32),
                Math.floor(dotsPerUnit * 23),
                Label_drawBlock_Option.LABEL_BOX, 3
            );
            await MPosLabelController.mPosLabelPrinter.drawCircle(
                Math.floor(dotsPerUnit * 35),
                Math.floor(dotsPerUnit * 7), 3, 2
            );
            await MPosLabelController.mPosLabelPrinter.drawBarcode1D('12345$%+-.',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 10),
                Label_BarcodeType.LABEL_BARCODE_CODE39, 1, 2, 80, Label_Barcode_Text.LABEL_BARCODE_TEXT_BELOW, 0, 0
            );
            await MPosLabelController.mPosLabelPrinter.drawBarcode1D('>A1234567890',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 30),
                Label_BarcodeType.LABEL_BARCODE_CODE128, 1, 2, 80, Label_Barcode_Text.LABEL_BARCODE_TEXT_BELOW, 0, 0
            );
            await MPosLabelController.mPosLabelPrinter.drawBarcodeMaxiCode('MPosLabelController is a MaxiCode by BIXOLON',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 50),
                Label_MaxiCodeMode.LABEL_MAXICODE_MODE_4
            );
            await MPosLabelController.mPosLabelPrinter.drawBarcodePDF417('MPosLabelController is a PDF417 by BIXOLON',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 85),
                30, 5,
                Label_PDF417_ECC.LABEL_PDF417_ECC_0,
                Label_PDF417_COMPRESSION.LABEL_PDF417_DATA_COMPRESSION_TEXT,
                Label_PDF417_HRI.LABEL_PDF417_TEXT_NONE,
                Label_PDF417_BarcodeOrigin.LABEL_PDF417_ORIGIN_POINT_UPPER_LEFT,
                2, 4, 0
            );
            await MPosLabelController.mPosLabelPrinter.drawBarcodeQRCode('QR코드입니다',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 95),
                4, Label_QRCode_Model.LABEL_QRCODE_MODEL_1, Label_QRCode_EccLevel.LABEL_QRCODE_ECC_H, 0
            );
            await MPosLabelController.mPosLabelPrinter.drawBarcodeDataMatrix('MPosLabelController is a DataMatrix',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 115),
                4, 0, 0
            );

            /*
            await MPosLabelController.mPosLabelPrinter.drawBarcodeRSS('12345678901|MPosLabelController is composite info',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 135),
                Label_RSS_BarcodeType.LABEL_RSS14, 2, 1, 20, 10, 0
            );
 
            await MPosLabelController.mPosLabelPrinter.drawBarcodeTLC39('123456,ABCD12345678901234,5551212,88899',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 155),
                2, 4, 50, 3, 2, 0
            );
 
            await MPosLabelController.mPosLabelPrinter.drawBarcodePlessey('12345',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 175),
                2, 4, 60, 1, Label_PLESSEY_HRI.LABEL_BARCODE_TEXT_NONE, 0
            );
 
            await MPosLabelController.mPosLabelPrinter.drawBarcodeMSI('123456',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 195),
                2, 4, 75, 1, 1, Label_MSI_HRI.LABEL_BARCODE_TEXT_BELOW, 0
            );
 
            await MPosLabelController.mPosLabelPrinter.drawBarcodeIMB('0123456709498765432101234567891',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 225), 1, 0
            );
 
            await MPosLabelController.mPosLabelPrinter.drawBarcodeMicroPDF('MPosLabelController is a Micro-PDF by BIXOLON',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 245), 3, 3, 12, 0
            );
 
            await MPosLabelController.mPosLabelPrinter.drawBarcodeCodaBlock('BIXOLON BARCODE TEST 123BIXOLON BARCODE TEST 123BIXOLON BARCODE TEST 123BIXOLON BARCODE TEST 123',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 265),
                2, 4, 30, 0, 30, Label_CodaBlock_Mode.LABEL_CODABLOCK_MODE_F, 4
            );
 
            await MPosLabelController.mPosLabelPrinter.drawBarcodeCode49('MPosLabelController is a Code49',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 285),
                1, 2, 80, Label_Code49_HRI.LABEL_BARCODE_TEXT_BELOW, Label_Code49_StartingMode.LABEL_AUTOMATIC, 0
            );
 
            await MPosLabelController.mPosLabelPrinter.drawBarcodeAztec('MPosLabelController is an Aztec Code by BIXOLON',
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 340),
                5, 0, 0, 0, 1, '1', 0
            );
            */

            await MPosLabelController.mPosLabelPrinter.printBuffer(1);
            await MPosLabelController.mPosLabelPrinter.setTransaction(TransactionMode.MPOS_TRANSACTION_OUT);
        } catch (e) {
            console.error("Exception : " + e)
        }
    }

    async printLabelRFID() {
        try {
            let dotsPerUnit = 203 / 25.4;

            await MPosLabelController.mPosLabelPrinter.setTransaction(TransactionMode.MPOS_TRANSACTION_IN);
            await MPosLabelController.mPosLabelPrinter.drawTextVectorFont("RFID TEST",
                Math.floor(dotsPerUnit * 10),
                Math.floor(dotsPerUnit * 10),
                Label_Vector_Font.LABEL_VECTOR_FONT_ASCII, 30, 30, 0, 0, 0, 0, 0, 0, 0);
            //await MPosLabelController.mPosLabelPrinter.setRFIDPosition(20);
            //await MPosLabelController.mPosLabelPrinter.setEPCDataStructure(64, "2,3,14,20,25");
            await MPosLabelController.mPosLabelPrinter.setupRFID(Label_RFID_Type.LABEL_RFID_EPC_GEN2, 3, 2, 15);
            await MPosLabelController.mPosLabelPrinter.writeRFID(Label_RFID_DataType.LABEL_RFID_ASCII, 4, '987654321012'.length, '987654321012');
            await MPosLabelController.mPosLabelPrinter.printBuffer(1);
            await MPosLabelController.mPosLabelPrinter.setTransaction(TransactionMode.MPOS_TRANSACTION_OUT);
        } catch (e) {
            console.error("Exception : " + e)
        }
    }

    async directIO(data: number[]) {
        await MPosLabelController.mPosLabelPrinter.directIO(data);
    }

    imgInBase64Format(): string {
        return "iVBORw0KGgoAAAANSUhEUgAAALYAAAAcCAIAAABDFdLbAAAf90lEQVR42u17eZxV1ZXu2cMZ7lwF" +
            "BaLSYpwJCgQlNkblGYcWFYJMIqMjtrMRx5/aSfr1L902MYkaZFIUUUSiEqPG5GkSJkXJM1Gj7YQ4" +
            "tKiIFFV3PNPeu9da59yigELp7vff67IE6tYZ9l7729/61rCZ0sqCL4N/MMasvf7CO4zZ5cOdnwC/" +
            "NnQdfUr/J58Y/Aj+2v11jB5smg9jXXfS4wzdw9IXm66X9jS2rgeaXa5L7k3GpvAnGArjzOIcLk6u" +
            "MabLIs3XM7PjcxzALrZKHsdSE7A9WdLsGLhpjpQ1J46/1fgJ/KGZMYkFcFwWZ+ll3W7dMSe244Od" +
            "F4Sx7kvUNfgdljX0tfOdrNsNOE0WKwWD0JYluv/yq5HRXEkYe5y8WSkGs+JC0Iu11jQMozlPrM6b" +
            "o9P0J6ISrteRJdwuI/Fu6IDfamXwaRxWLx2XUgrWEy1m8HOyJQ6bdxuVbv6pVcTxPh4bSwiRDFXX" +
            "O8LOz0zHJ6zWrmPfCgLLBDAGy/Yst8DyvXlrf9mrv+COwOdpK1aMgx3hpcLAtMBmWjHpMHoL62aT" +
            "9FtrbmkOAxd7hAgYB2yicNm14TIZfBQ3ovbNqryFVz7XfsVSAY8tA5i1bcvNWpk+VnEfp7W/yLaI" +
            "5DkqgpvRNMxweCGMDXBuCcZZlym6lqn7l4piMIZhOMQUIjAtBs9gyYJ2IZHTMnGYb23bh42314iP" +
            "/myEQwYHw+juQOS7wSNUvi1dnS+wbB+732F830OdfD/BBS2aMThgwIW2uKiXv/BfXGLaP7IsO1lU" +
            "uIDFsR4wpOW4KczO1d9e7a9/SHh5MrERKubZNnb4iOyhI4RTZDoGc6fwoQUwSD7KcNtv/yj+62/j" +
            "T99GuBiFLKBxSsLSMXPd4yblDxzOVWwJGWkdf/Fu9G/Px++uFls/5o1OFteNiRl+wztjfDosKZOK" +
            "C+XmdWkfsc/hbNCZ3sATZaYFHivATIIB7OF6LXlY7/BXzY+2fSakSHc1DkGJ/Qe6I6Z6XkGYHvgY" +
            "kYEGoOfg5hEwWlXZGrzzvHprtfnsTVnpYFGZRT5cIxThiDEFI+RMCY87jsn2ivoeYh/4bXvIaLfP" +
            "QSIxJuCX4cTRLsKq/fkJtXEDt3iyxrq5avBCnS05R5/l7TfEUjCJ9IKE/2B/V/7vividtRZiAJcP" +
            "PtWu4ww+MzvgaNb+3B368VsyjqsRz/hYmjWZHH+AlYdlZ8AH3OCtMHAOL7EEPAQgFjBb51rV4f/L" +
            "O+Hi7EEjOE4N3igA0ErF2x+7Say+07VLgEaAjMUV1ziCADhi9A97nTa78+WHzcJpXj5nuMusWBMQ" +
            "Qi31oSc4U36R630AMA3DdyG8kR5gqkLWX13ReOIWr/0zacM4RTf8wqiDQAs1c0HvY86Fn+vbNoXP" +
            "/YxveFKEncKWXNpxYh6ibpiKoVnSMiuOPCEMTE7VgbCifoPkdy91h09xhORAeIB9YBQm2ldc76y+" +
            "y3Y8oDKd4NfgrMJGg0+akz/5amnM7hCh7aqI5eE5PAo6K+uXqjWLvS/egf1mpEC7CqETUoRtDT/r" +
            "LiZQyDgAwzjUUezn+7IR07PHX2j3PkDicgHhgMnl9ndXs3kTvahigHuMSPmU0UrC3KI4LLTxyXcX" +
            "hpwFoMdbaFxA/ZW3nvPnTsoKBbOD7QK8BDMwcRhm93EvXsraH7lSvrCY5doSktQWZ02iAgLDFdAq" +
            "BhvB82CcFppFIEhhsYAwwFnAhTFrlGvF/cVZt2RHzHRMxLUEK6ig3L5wcmbTCzxTAqvDtek6w/9B" +
            "pT50TGnmEq2D8uO3eGsXikzRQiAiacFIrOoX1UFjCxcudry8SCyrcTyay9onf43nTcjWvjRexqKR" +
            "pMMF08OtlUp4woX58T8Gu9ffXxc8eqP76Rss5zLmJB4AsApwFzoEt8XAGQHHMEfaIraBElzamqFF" +
            "fB2HZR2raOSlhQk/lposzQR40+rcsfbGdcbN8nQXpdLD1Lbp71yUmXSn5D0oEXwdUaAFFFjfXnn4" +
            "Svn6rzO2YxxPE8HSFgQ7R8iy4P2tiKOtbXDfRtgmfRMyP6520Gj0H5K98IFc2yGW9mlP2u3rH3Ae" +
            "nc3dDK4h7FP0ACalMBySVo26339I4cqnPC8Hr+D4a+BHWf3jPeZXN7FsEUbCFawTbGUmTNyoN9zz" +
            "72Xty660X1xiZYsAc86b5IR/wbg1QAnXAFCN3g5mAZTuWlLSBfghTEvb8APwb803lpw+P/ut8dLg" +
            "Hoj9Sufi6e7G1dwpKRMLclmJVjBhNRg2oTRtIfnvuPKbOfL3cxw7oxJXKGCKxqpXaoedlJl8R7b3" +
            "QcAs6HGlrP/7K/4Dl2U7NjKR0akJuEXQBhPo+vZg+OT8tPlC2I3P3w7uGp1ptIPJYFzgf/BS0kXG" +
            "1EO7VfU+gJf6Gu4Zv1Ns+0h2fCyFjZtBxQa1DtFlHCu/Gpx+Y+uZt+Da4Pbh9XkTxLurlJeFlyd8" +
            "rQC6sHaNDvOdWYWJc0AVdHfP3SECNgS8V+6d5ryyUpZalEXYwJmAyaSIagGMofVgq6UPc4s8ClV5" +
            "s/xyo4Rdx7NgQ9jeyAzg1MFT1jv9A0/IX/WEIxwAOpBB+0tLxYrZ0nY1QZQ3xSnaXKOHkFr79Yo1" +
            "c1Fu+CQBBsEVh90gy2sXmMevB6+KPsAoYnsjma77oTt9Ptv+8BVy/QNWtgVvEAJdE+wzWCSkRa4H" +
            "jBClXhZ5FrRw+Qv16b+5tS+M7aE8RXgiknAcYJZGpT7g2MIVK10HdpgV+NXOxdMyG9dwp6CQ+BgR" +
            "BCEtrDeGjmudsRApjSMTdS6/Tq6d5+Z6gYIDjjO4IExUy40Dj3VnPZwt9IVXBNs/rtwzMbf1HQu1" +
            "C6466Su6H0YdlYP9hmevXGF7rfCmjmVXuesXi1xJA3+A4EiNK1lcrfb+Zm7GXG+/o3hT26qw3Pmr" +
            "/+2uv9/2soR62CzkdGC1lR9m2pzLV3r7HE60wSvzJ9jvrbKcrFZ4HSqLRPLXO9iJF2fH/4T3FM8Y" +
            "BeETaBpZfvO31n0zbcfR6FdQDYHD5uSt/EhZE39SGDEVrpfNG7e/stIsvzKLlrJhPEibeD063yis" +
            "qvFzWo6/gMMACCLuitkcIIIKhvNEAdHftMFJnwaVRv+ji9f+RjLYDCh5YetW1i5Qv7zBzhSslGQ5" +
            "uBywVN0PvBmLECL2+iWgZawEIkoh6EBoh2Hcdqjz/acdt9SlfQBGjS1vB49clfnkdW5LmCTxL3ok" +
            "op2wAbx505psrwNRpSNEpmeQRQAioKXEzhAZX5qxQBpypcz2wfUsm+385WGebaXXk/TVQte21YaO" +
            "LV20FG7umDc18+aTPN8Lec1Cp5SQvBaGB5Vq74OyFz2U6zsQFgNmvv0nJ+a2vKWlhyDC6wiN8Nxq" +
            "e3jaja1jbkMKVtpK9hu3ap+9FvzsjBwoZGPzVCAjWigQZfE5P289ZgLMAtamOn+CfG8NBEGJNVGZ" +
            "A0MgRNrZCbOyE+7gPWUPCCIGoomtv/qHzJq5zM2jgkFS13QtELRfbzmw5cbVjsygLk9kJufg6zrv" +
            "PMPZ/Aq386BIgGK1QZePax9W4uHTC+feBQIKNhRCBByN4+rUIaQQEbj7MaADgHEdR5HS589vGTyW" +
            "AV/Cb7sgki1oK9n1CBHYeWEYONMXAEQut9c/2AWR5PW4mpEK+h2Zv+ZpB4IXhKVF7M+AJ+trFoon" +
            "f0DuhpEHZRjDoecxceDb1/0+238oQaRSuXeG9/5q5u4EEd5kkRZgEVwBYmBQ+PVy5akfipcecJws" +
            "RoNgVJgnTCmM1LCzrWxBvPCgK2zFKbogjmdEIlZc83P72+fd533jGAEuVogwqNfuOMnb9oESLqIN" +
            "n0NcC7asbNNn3lYcdXOSo0hCJXhKZfPrjTtHFyBcSyCCQS4qJxheDM88+/bC8TOBiwBNBJHVlp35" +
            "z0HEIEQA1tsf/b774kPa9UgYklVp34jI7+x7eNtVz9oZRE+aKbFYFNVr8yeKD18UTp5R5kZTUAR7" +
            "E8xohozPzVzEKLuDEPnlbC53hYg0LAC1okhEA8DChn/wyPyspY6dY0CEomeIIIuEgTdt0a4QIeEN" +
            "4aoFmrvWb3DLlSthZChYBcpXMFrMebhhhVl+hZA2Pr6ZgcHBMBNExrt5VbbPYahu/UrHfdM9YBG3" +
            "2ANEhoxrmbkQuR9Al4TDsGOAKu6dkn31STvXK4bwnWwBPseEPnoyUBWcqBCRITCSg08h0sdtcX9p" +
            "8Ggeo+uB2cVRtTbnFKfjAyZscg4p6cIWtCpb4zNuLZ1xC2vGHZpETWXzX4M7z8yDVkSI0JXEIyAw" +
            "A6D4sT8uHHceSDNguN0h0nQ0XwMRnWBx+dXyT8ss2zXIu4gR3IHMklG9o+2ItmsAIoVmcgJIg+uw" +
            "Xl4w0d60DtQJqYc0MwIUGMchHzImM/Ne3jNE8MkQMscyXy/1KrT/O2bCDAYrYDAz+WelYybvESIM" +
            "okrdCCNn2vzdIKJohwpUm7V+Rxav+Z2dyGkrTU8Elu588LL8q48bCNUSfWsoCwKDCcp+v0E5mKRX" +
            "ZHsJEa0lzMTQhmWU8Kh8XnlwVvbtNSxfYKieaOd25XM0BajwgcCED7BwDMQ56qbiqdcKku2UnQR4" +
            "V+s/O8Vp/wDFNU8TpsmO0tUtu0AkeXJl8xvhnaNyIFs4xbJCpAsLr4AVGPvj0nHnGeLz3SGiMDr4" +
            "WkcDzwHK45VHZ8uXlxjXtdDlkhwijwMiqdJnUO9rfiN3QAS/VdioLpgo3yeIYMwn0iAF/GnsmyHj" +
            "cjOJjBnbvhuLoJ4CNs+0+Cdd7a1bZFe24ucm1hCBHvLd0qzltpuBx1V7gghs0CiI7GnzdnM0CpEL" +
            "rI8Em+ljRt/m9R1AuRJwQUHw5ebw1Wec9//gMBQi6N5xopRmiAJfx3zKLwrDz0XfD+jdS4hQ+IBR" +
            "Ewpk+K3jd3zeWHGd8+bTPFNkSSIvFZaGSAtDC/jPVqEfqui02aVRNwKlYLSGaECuiKJq/Y6TnS8/" +
            "ZLbXzBcmdC5VbYs+/dbSmT1ABFkEYhjOukFEgw+PIGQZ9/8GIjDM2qPXyg0PMlAMEBQkERGSoeEh" +
            "QGRg72t+JzN5lgaVOPa4CREwI0YmKUQs9G6xr4aMy4MZiUV6hAiDhWGOuWiZ9eb/yfzhp1a2FwmD" +
            "OAoafNby/KDTeM8QAUceB0HoTr1nV4g0ixcYY4ooDqMGxoE6zauKqGED/2fy9BhMr8FYAMzGb0S5" +
            "fcwpVxROuhyegOTOJWqR+2a6G//4tRABVa1wJ0Ug5BkmiexG0NlYNCX3/kuwEkRfmAZP/AXsK4zL" +
            "ABSd2+rfnlY8b4FDkTPmlDnlXpsQsXuCiK5tUXsPETRzHIOlx99e+tsZ+r8FEWAKhXmdnSDSvA4G" +
            "E1Y7+wxsA9oGLdJ1VxdENq3jzm4QiXwzdJw3c6Ho0dFQMtcogIgU0++T/Q6p/8sJeWEwOAWLN76s" +
            "DhrdOusReFy9J4hIEzeC0Jk6b3eIKGIMgRl6rIdoSzeTfFh3kcaijY1JFkO0biLbCQedlh15hbs/" +
            "hZFRjBUKgFMIcpXyInsFEWAQTCeQx1ZG2GXwvneNtz3HUEo4WYxUHwDhRLWw/7EuhDCFNpamPhOr" +
            "wPh5FNX2ABEe17aa/wJExt1eGvHfgwjqcpit+C9ApEJapEeIqKHjsnuECNU7wV0Yh0+dWxhy1vZl" +
            "l2VeWKYLRU6YBY0lZj3acsgJlbXzCCKlnSCi40bUI0Qw6IU1SxJmoEiwkpDktjFJANBJaqLIK0lM" +
            "gRnxSOZ130PEsDOyR58jvJKANWM2ssjiae7GNXsDkUTwJnVSsLeKg/K9U5131tjAIpwEZReLgA/W" +
            "QaN1gHfhkly/gWD41L0AA2H0Yggi1f+BCMU+4MWBalw55e7C0NG1j18O589www6QaFhvCerhN0e3" +
            "Xnx/Zd1i67FrbLfYTHU1WSQEiNzTA0Tw/QKvFDrwLWlxD+tXSY0srouwbsOP2RaUi6lwsgQLIJgJ" +
            "wzAefm5+6s8zTi4Neu/7T0AECx0QPTM7ZLryxG3O6rnCzRuWlsqSHGQKERNFbl6fekNh5MWcSkWa" +
            "fAz59q+BiAKIjLq1eMb/FxBREABA1Gy51pS7ikPGxCYuP3odLLfMQjyhQG1GMsMveZx//oZedrnr" +
            "FeO9hAiyDZCFjoPcfnzKnEzvgzGoQ7/DIKSOt38SvLDcfudZwW2WaCLMOVBRzAqDaocadUvvs26D" +
            "BQvR0ewVRIje4PUKRBu8qfPpf5S/n+t4NmUbkvpHErimtEWkEvoRqsjiibOoYhRKLHBQCWrPjgYX" +
            "srp1TxHNThDhvGvxYh03IdJz0Lu3EMEymNhVrupm00dYLe8sV78SIhjR7IAIxQd7hAhzrMl3l4aO" +
            "Adv6H/0lXnCOqypKOEzxOGiPjr/A3m+Q9dgNtp3dWxYBiBjJZFir7TusBDGYkIlYTZZIUeNFZd6k" +
            "3NvPay9Hd1H2EhyT4CKu1nIH5K55xm7Z1zQq5cVfo0UY1g6NSZKkKH5ledU8/tgNIl8AOhEK8x47" +
            "8EG5SCoOccw1xTVfSzbh9syIGVLFghJD1FLAorBan3Oy3f6hsT3eHSKSx+Wt+sxbSqNu3Q0ir4d3" +
            "js4RRFLpk3g+g40tatztLShX8d27QQRthhCptbORs7Ljd4II9QAkEgormUCKCJGXH2Suq5Og16QJ" +
            "Lk4s0qcniPQkVylQDiHoHevNvPdrWAQgcu7drcAiOgYTbH/4kuyflluZFswnRpGf76MP+47z55XC" +
            "tjUZEHAL8cDXOBoD/4CQp8/h+auftd0sVWHQVKATI9jatqivm88f+b4otGFyhkoNsNhYSVZRCBt5" +
            "xn3Fo07fG4hgAVChxkGMcVb9+JX4FxOyqm6ES1kOTbVEC58MS9GoWq7DLJsq3IgeoAvfdq2JdxSP" +
            "nghTIqNjC1nsV+s/PdnZ9qHuBhFF21ZVvzRj/rF42nXWrhB5LbhzdB6nkdYpCCFY+YsUskjLcXsD" +
            "kYty43/Omg1uOFsqDaXFc9BTTFSWf19uWMZgPfADTsE8zlOEtT2xSA8QwUI7kJrPjxrnnb+Qfy1E" +
            "Jt/dMnSMoQaa6vsvxneN9rwspuPBTSsdea4II6JgClG+GiJUhoZhAEQaQZ8jilf/hvK+2H9EHT0W" +
            "Jk5su/rcT50nbzP53qRZkpysFkicOgD9OP7O3LGTVKNMEPkqR8MxvMZwMJLC37Q+XHpZtrxZY1sX" +
            "OYzEtVCRH3RRdMTfWVvfcMqfMZm1dJoGMSqMYKNOnZcdNlZSWASSJAKI3HGK2/6BBgBR6Ae0Yyhn" +
            "aspf6u/9qHja9TidrkQ1Y2l21UQxJmRTiFBrgonhVWf/S/E7M3t2NMms4Mm1Djby73Pj/7V7F1zX" +
            "SlvNGnr10avky48y2+lWbMP0oIganW2HtRFEutoJYeVN1CgjRNZa1HaTps4osRzHVT5kbGbm4q+B" +
            "iIUsQhAxFuUXOh640PvLSgsVSYLlGGNYeHhas9rF0Sy7wn7xAZ1tadZokA8sTLM2wrYjCzc8Z2O5" +
            "Ii3jJXXReuen4cJJmc/eMU5WUzmNcrKgOuFS3dCST5/fctTpYaNMEc3aPUBkfMvMBUi9OlbSrm95" +
            "uz5vcqFzk+X2gk80JeVxj2FuVel62T/opNw1v47e+kO09O/zje2xm0kqNfB7G/aZKMgL5hYHjrKw" +
            "eglxWL3+ryc52z+wuEPbGHUhwhh8IrAIQOSU66mXL3mFxr316Vv+z08vIEQ4tcGQRMLuPOXDVePm" +
            "tIyYmmj23SGiE8fkd9QHj3FHXkoFYZM2BWLIjuE8rIy7/xE817uy4ip7/cMcS8rk+NPWHMZVvdzn" +
            "m72v/q10MrABTNILBDFDFKIW+WANc4pUG2FW0rgGCxthjaY4YyHbA0TQheso4k0WwR8h0uW1jS9E" +
            "i87JoEtw0+QdkQfN2dqVRTqWXSGBRbCjhxxN4jzR+jrKlMyp1zr7HIaJB4uYvb6t8fk78rVn7G0b" +
            "uZ1NEMOxSEEVdMHBnlFmH2/27zLF/VSj0rl4mrcbi6SV3mFn95q2CAurXMZKle8Z5767iudKiSJN" +
            "FgntBv/Xq9X9j8xecF+u7RCQQbW/PqeWnp9VkWVnwfjEb6CN67Vcb3vK3PzAUxjtle13neV9+BJ3" +
            "aZDk73EpBGeNzupR40sXLuaEe9Fsv62++mtryQWOA6wjYT2pNkytXyoOuWQXP1Q8+ATK64rK/Anu" +
            "e2t0V6WXLKuT5j+j46Tt0EqbsFFqYRoa3FUYHfq3hUsfq6++lz9zs2sXYgzWsJEtqeIZHTZYPnvj" +
            "816vAazZOgoDCzo3138yKt/4QkmJrglLG5hmRnT7lfD060ujbhbkQXaFCIo3LMiEls2mzG0ZMgbb" +
            "iLAXxIpUWH7k6vwroEjyuKWsnXvEtUkh4ofO9AQiXSzSlPHpXldxTNzAqGEM408VMR0wKTlzddqm" +
            "YSUtixoGz7SpdkbHX1o6Zw5mjhuV6uKZ7vurWNoMwHVX92xYbQyb1DJtPsawYaXx+G18w1LhZNG6" +
            "zawLylfQv0HNbznUuXiJt+/h8GrsmYBNsGGZtfxaCGA4tq2gsyHkN+pOq7xgcfHQkfCWzvXL2MOz" +
            "7FyLIeQmehoWC2vZioXfHOkcdabT6wCsHNRrwfurxZ8ek0EHExLFlab8IdAJLFOj7g8eW7jgfuBV" +
            "2mSiMm+ifPePxvWQkZO6kWkGr8Ykvb/NKCzZQ9RtBxEm6KHzH/IOHFa546Rc5yfaK2DHRuJ+wIhg" +
            "vTAI9j2cD5/m9jucg54NQ/+LjfHLy7xP3+SObVHHBRaHYXmkLf3OeqG/c82vs60HMoJIx0tL7QQi" +
            "rCsfASDRIcSeqaPBriiF7dqivnGtunearaOkxdpKyYTGAtES1ocpuzptLmt/+Ap3/QMq14qLbXU1" +
            "EhPjoBxAasXu1XR4CdzoWydCQdEmwoJb3KiF+w3KXbbSLe0DH0V+rbJoivvBC1wWQcwLxB3pP+z9" +
            "qzaGTGqdOR8uqzx+q7XqF162RTc9B7WWklOL6pGS1uXLeh36XZ10zhqM9dAvrLtPP/EPjggtkcEo" +
            "h4IFu9FZLgzIXLLU6z8YdMP2ZVfl1i+RXt5IJ2FBC1uwqTZYq0VhnQvQypLrhsVtJ9sSS+q/pFQ5" +
            "lc219reW9z82P2spdsDo0EKaFeV7zpYb1xrpJYExT6REYtq0lzVRHixpSuPY5YuaAlbDTLqn19Fj" +
            "t/zpl3zZJbAhLJmhthdyq9jwrEQYRo0KHkzg4G5iGwzv5ZWX4dRCbZL+SFg/v1IGwM9YUDp6ktaR" +
            "NNj32rF+if3Y9Vx6aZpakwYAoAnHOufu1m99LxWaRBgAgvZFUzNvPCuASGi8aY8nTzpS4e/YbwTu" +
            "tHvY1pW3OM/ezgt9sOCa5Mea2oqTU0h8E4YrKFNMEjQTuxqpiZFNyHXsMzs64uTcuNuzfQ9iGDhj" +
            "o0PnAxfmQBaB+0i6v5Eb4PWRrvvBibOK5/y0tmoBW3a1U8gZSyRtf7SSMY9FZALfa5Fj/jl/3BRs" +
            "X00O3TDqsmPYQVDbsDxeMTsT1bi0sb+DU4jQKNf7Huyed3/+gGPCqFpetUA8d5cdbuNORkAohBta" +
            "UlNnjPGMSdISNh1awHAPFT3sSJBvoR/yTHzUqPyY27y2bzAcALk0JjsWTnXeeIpj2pdwQQFLU5/y" +
            "hElYKtuShAhReaR85piLH2kZeBJcUH79qejpf8p+9haEmoBgLWyhqQjLMRnEsK801JZs0hGlJ3EP" +
            "R8A0EciLfYeKUdcWhozFjIhFvcoAkVdW2A9eLDFWklaSHcfdHkXCNRc82DLwVDqbYyWnNICMq++v" +
            "8+dOyOuaAZdNXcDNQxJ44oWZsKaMd9FDrPO9tcHzd9lb3o4hjiCQNmeYFMWpu4Wb5JAUXZAcAiLO" +
            "lm7suZZTYm0HiSNP9w47XgoH9BUm8FHy8Oqml8KnfuRVtkGIxKzEM1kc9sm+B+XG/tDrO/DLJ3+U" +
            "2/CIAXdAzTJp6gX7U7jqPzg38hL7b4YB42GfdZphS9MMMYZ/0t+4Plo1j297j8U66Y0FMRCCYjj9" +
            "puK3Jwl0KSL49DV/3YN800uifTNXNaZISMLVBjtJ0bnr5IRGTD03TMHOzvXRA4a7IyZ7h42U4F71" +
            "jvM9sIO3f7TBrPyBXfuS6s7YMq53NCxYOzZY+g9qItRhYIQedGrL935APgmcNwtrW+sbVlh/ecpu" +
            "3wQKCU+sUAd1cvSL4rBkL1KnMvh47ppcKe79DXn0BG/4BOmWkHpMsl6wh2UYdFR/ebO9cQM4CUUZ" +
            "DoEpA6a+9b386dc5MoMVPDyZoLqIpPzqM2bVXLu2LW1bpBHjmSMMh5kafGrhhFksiEMjbF39Io0y" +
            "WdMYSb7bNE+fpQxKURE6HOxzhm/se6BzRTJhFkWdH9hOilIpRpkSW8CcfMd5KkygZ3tRxwtpBL/T" +
            "2nGcyiRyydgOc/K0SekoCcInPUCmkC2xkoMLClIXlU1DqIYh7BoyLHMLAndWcr4C20BjiIk2vaQ/" +
            "fc3a+gHr2KIb7Saug9kxDobxO1mRKepCm249SO4/SA4Ynu29X8IAaORmdEKnx+JQOhy2gV+mRnm2" +
            "I7Td9VjTjrCXginJ3KJAw9MJJggssLMTj3M1PnzN+vClaMsHcvtm7W9TjSrXoaCwQsuMcIq82Bq3" +
            "9BN9j5TfGObuN1jQGlEnkkXlCXD2mkzvoA2qW+kUXSIUwB6OAGtjmYIcbbMchmOnE2sxrFS9zNhO" +
            "o6c2Wzs5yoSY2v3EY/NoI76ha65mNyvsOOyV9gTtZJr0cGLzzGP6yK57TJObu9+389cOfJqdzhh2" +
            "/bLrMGgPt+7yT5Y0AMaAJ2BQHTUMxERGJ1uBCYfZGQbRJmCFO6naM90f3/3VO0bd3RysxxHQmclm" +
            "AKy7bk4D4uSIKObmY6zIQhAb1nUcMNJ2pMkksz1AMMTYws7wdNc2b0yPr3bZIn0j2/2MKa1kcpK0" +
            "axbpP77qlC4+9j8AI/iGIBw8z5IAAAAASUVORK5CYII=";
    }
}