diff --git a/media/isp/release_camera_engine_rkaiq_rv1106_arm-rockchip830-linux-uclibcgnueabihf/isp_iqfiles/mis5001_CMK-OT2115-PC1_30IRC-F16.json b/media/isp/release_camera_engine_rkaiq_rv1106_arm-rockchip830-linux-uclibcgnueabihf/isp_iqfiles/mis5001_CMK-OT2115-PC1_30IRC-F16.json new file mode 100644 index 000000000..3a6c7b17b --- /dev/null +++ b/media/isp/release_camera_engine_rkaiq_rv1106_arm-rockchip830-linux-uclibcgnueabihf/isp_iqfiles/mis5001_CMK-OT2115-PC1_30IRC-F16.json @@ -0,0 +1,8397 @@ +{ + "sensor_calib": { + "resolution": { + "width": 2592, + "height": 1944 + }, + "Gain2Reg": { + "GainMode": "EXPGAIN_MODE_LINEAR", + "GainRange": [1, 16, 128, 0, 1, 128, 2048], + "GainRange_len": 7 + }, + "Time2Reg": { + "fCoeff": [0, 0, 1, 0.5] + }, + "CISGainSet": { + "CISAgainRange": { + "Min": 1, + "Max": 16 + }, + "CISExtraAgainRange": { + "Min": 1, + "Max": 1 + }, + "CISDgainRange": { + "Min": 1, + "Max": 16 + }, + "CISIspDgainRange": { + "Min": 1, + "Max": 8 + }, + "CISHdrGainIndSetEn": 0 + }, + "CISTimeSet": { + "Linear": { + "CISTimeRegMin": 1, + "CISLinTimeRegMaxFac": { + "fCoeff": [1, 8] + }, + "CISTimeRegOdevity": { + "fCoeff": [1, 0] + } + }, + "Hdr": [{ + "name": "HDR_TWO_FRAME", + "CISTimeRegUnEqualEn": 0, + "CISTimeRegMin": 0, + "CISHdrTimeRegSumFac": { + "fCoeff": [0, 0] + }, + "CISTimeRegMax": { + "Coeff": [0, 0, 0] + }, + "CISTimeRegOdevity": { + "fCoeff": [0, 0] + } + }, { + "name": "HDR_THREE_FRAME", + "CISTimeRegUnEqualEn": 0, + "CISTimeRegMin": 0, + "CISHdrTimeRegSumFac": { + "fCoeff": [0, 0] + }, + "CISTimeRegMax": { + "Coeff": [0, 0, 0] + }, + "CISTimeRegOdevity": { + "fCoeff": [0, 0] + } + }] + }, + "CISHdrSet": { + "hdr_en": 1, + "hdr_mode": "RK_AIQ_ISP_HDR_MODE_2_LINE_HDR", + "line_mode": "RKAIQ_SENSOR_HDR_MODE_STAGGER" + }, + "CISDcgSet": { + "Linear": { + "support_en": 0, + "dcg_optype": "RK_AIQ_OP_MODE_AUTO", + "dcg_mode": { + "Coeff": [0, 0, 0] + }, + "dcg_ratio": 0, + "sync_switch": 0, + "lcg2hcg_gain_th": 0, + "hcg2lcg_gain_th": 0 + }, + "Hdr": { + "support_en": 0, + "dcg_optype": "RK_AIQ_OP_MODE_AUTO", + "dcg_mode": { + "Coeff": [0, 0, 0] + }, + "dcg_ratio": 0, + "sync_switch": 0, + "lcg2hcg_gain_th": 0, + "hcg2lcg_gain_th": 0 + } + }, + "CISExpUpdate": { + "Linear": { + "time_update": 2, + "gain_update": 2, + "dcg_update": 0 + }, + "Hdr": { + "time_update": 0, + "gain_update": 0, + "dcg_update": 0 + } + }, + "CISMinFps": 10, + "CISFlip": 0 + }, + "module_calib": { + "sensor_module": { + "FNumber": 1.6, + "EFL": 5.2, + "LensT": 90, + "IRCutT": 90 + } + }, + "main_scene": [{ + "name": "normal", + "sub_scene": [{ + "name": "day", + "scene_isp32": { + "ae_calib": { + "CommCtrl": { + "Enable": 1, + "AecRunInterval": 0, + "AecOpType": "RK_AIQ_OP_MODE_AUTO", + "HistStatsMode": "CAM_HISTV2_MODE_Y", + "RawStatsMode": "CAM_RAWSTATSV2_MODE_Y", + "YRangeMode": "CAM_YRANGEV2_MODE_FULL", + "AecGridWeight": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 3, 4, 4, 4, 3, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 3, 4, 4, 4, 3, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 3, 4, 4, 4, 3, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "AecManualCtrl": { + "LinearAE": { + "ManualTimeEn": 1, + "ManualGainEn": 1, + "ManualIspDgainEn": 1, + "TimeValue": 0.01, + "GainValue": 1, + "IspDGainValue": 1 + }, + "HdrAE": { + "ManualTimeEn": 1, + "ManualGainEn": 1, + "ManualIspDgainEn": 1, + "TimeValue": [0.01, 0.02, 0.03], + "GainValue": [1, 1, 1], + "IspDGainValue": [1, 1, 1] + } + }, + "AecSpeed": { + "SmoothEn": 1, + "DampOver": 0.15, + "DampUnder": 0.45, + "DampDark2Bright": 0.15, + "DampBright2Dark": 0.45, + "DyDamp": { + "DyDampEn": 1, + "SlowOPType": "RK_AIQ_OP_MODE_AUTO", + "SlowRange": 10, + "SlowDamp": 0.95 + } + }, + "AecDelay": { + "DelayType": "DELAY_TYPE_FRAME", + "BlackDelay": 2, + "WhiteDelay": 2 + }, + "AecFrameRateMode": { + "isFpsFix": 0, + "FpsValue": 30 + }, + "AecAntiFlicker": { + "enable": 1, + "Frequency": "AECV2_FLICKER_FREQUENCY_50HZ", + "Mode": "AECV2_ANTIFLICKER_AUTO_MODE" + }, + "AecEnvLvCalib": { + "Enable": 0, + "CalibFNumber": 1.6, + "CurveCoeff": [0.02859, 0.5972] + }, + "AecWinScale": { + "InRawWinScale": { + "h_offs": 0, + "v_offs": 0, + "h_size": 1, + "v_size": 1 + }, + "TmoRawWinScale": { + "h_offs": 0.1, + "v_offs": 0.1, + "h_size": 0.9, + "v_size": 0.9 + }, + "YuvWinScale": { + "h_offs": 0, + "v_offs": 0, + "h_size": 1, + "v_size": 1 + } + } + }, + "LinearAeCtrl": { + "RawStatsEn": 1, + "ToleranceIn": 8, + "ToleranceOut": 10, + "Evbias": 0, + "StrategyMode": "AECV2_STRATEGY_MODE_LOWLIGHT", + "InitExp": { + "InitTimeValue": 0.003, + "InitGainValue": 1, + "InitIspDGainValue": 1, + "InitPIrisGainValue": 512, + "InitDCIrisDutyValue": 100, + "InitHDCIrisTargetValue": 1023 + }, + "Route": { + "TimeDot": [0, 0.03, 0.03, 0.04, 0.04, 0.04], + "TimeDot_len": 6, + "GainDot": [1, 1, 2, 2, 4, 16], + "GainDot_len": 6, + "IspDGainDot": [1, 1, 1, 1, 1, 4], + "IspDGainDot_len": 6, + "PIrisDot": [512, 512, 512, 512, 512, 512], + "PIrisDot_len": 6 + }, + "DySetpoint": { + "ExpLevel": [0, 0.03, 0.15, 0.5, 1, 3], + "ExpLevel_len": 6, + "DySetpoint": [45, 42, 40, 38, 35, 30], + "DySetpoint_len": 6 + }, + "BackLightCtrl": { + "Enable": 0, + "StrBias": 0, + "MeasArea": "AECV2_MEASURE_AREA_AUTO", + "OEROILowTh": 150, + "LumaDistTh": 10, + "LvLowTh": 0.3125, + "LvHighTh": 7.5, + "BacklitSetPoint": { + "ExpLevel": [0.096, 0.192, 0.384, 0.576, 0.96, 1.344], + "ExpLevel_len": 6, + "NonOEPdfTh": [0.4, 0.45, 0.55, 0.65, 0.75, 1], + "NonOEPdfTh_len": 6, + "LowLightPdfTh": [0.2, 0.2, 0.22, 0.25, 0.3, 0.35], + "LowLightPdfTh_len": 6, + "TargetLLLuma": [25, 22, 20, 18, 15, 12], + "TargetLLLuma_len": 6 + } + }, + "OverExpCtrl": { + "Enable": 0, + "StrBias": 0, + "MaxWeight": 8, + "HighLightTh": 150, + "LowLightTh": 30, + "OverExpSetPoint": { + "OEpdf": [0.01, 0.02, 0.03, 0.04, 0.05, 0.07], + "OEpdf_len": 6, + "LowLightWeight": [1, 1, 1, 1, 1, 1], + "LowLightWeight_len": 6, + "HighLightWeight": [4, 3, 3, 3, 2, 2], + "HighLightWeight_len": 6 + } + } + }, + "HdrAeCtrl": { + "ToleranceIn": 10, + "ToleranceOut": 15, + "Evbias": 0, + "StrategyMode": "AECV2_STRATEGY_MODE_LOWLIGHT", + "LumaDistTh": 10, + "InitExp": { + "InitTimeValue": [0.0005, 0.003, 0.003], + "InitGainValue": [1, 1, 1], + "InitIspDGainValue": [1, 1, 1], + "InitPIrisGainValue": 512, + "InitDCIrisDutyValue": 100, + "InitHDCIrisTargetValue": 1023 + }, + "Route": { + "Frm0TimeDot": [0, 0.003, 0.003, 0.003, 0.003, 0.003], + "Frm0TimeDot_len": 6, + "Frm0GainDot": [1, 1, 4, 8, 15.5, 32], + "Frm0GainDot_len": 6, + "Frm0IspDGainDot": [1, 1, 1, 1, 1, 1], + "Frm0IspDGainDot_len": 6, + "Frm1TimeDot": [0, 0.03, 0.03, 0.03, 0.03, 0.03], + "Frm1TimeDot_len": 6, + "Frm1GainDot": [1, 1, 4, 8, 15.5, 64], + "Frm1GainDot_len": 6, + "Frm1IspDGainDot": [1, 1, 1, 1, 1, 1], + "Frm1IspDGainDot_len": 6, + "Frm2TimeDot": [0, 0.03, 0.03, 0.03, 0.03, 0.03], + "Frm2TimeDot_len": 6, + "Frm2GainDot": [1, 1, 4, 8, 15.5, 64], + "Frm2GainDot_len": 6, + "Frm2IspDGainDot": [1, 1, 1, 1, 1, 1], + "Frm2IspDGainDot_len": 6, + "PIrisDot": [512, 512, 512, 512, 512, 512], + "PIrisDot_len": 6 + }, + "ExpRatioCtrl": { + "ExpRatioType": "AECV2_HDR_RATIOTYPE_MODE_AUTO", + "ExpRatio": { + "RatioExpDot": [0, 0.1, 0.3, 0.5, 0.7, 1], + "RatioExpDot_len": 6, + "M2SRatioFix": [4, 4, 4, 4, 4, 4], + "M2SRatioFix_len": 6, + "L2MRatioFix": [4, 4, 4, 4, 4, 4], + "L2MRatioFix_len": 6, + "M2SRatioMax": [64, 64, 64, 64, 64, 64], + "M2SRatioMax_len": 6, + "L2MRatioMax": [32, 32, 30, 28, 26, 24], + "L2MRatioMax_len": 6 + } + }, + "LongFrmMode": { + "mode": "AECV2_HDR_LONGFRMMODE_DISABLE", + "SfrmMinLine": 2, + "LfrmModeExpTh": 0.62 + }, + "LframeCtrl": { + "OEROILowTh": 150, + "LvLowTh": 0.3125, + "LvHighTh": 7.5, + "LfrmSetPoint": { + "LExpLevel": [0, 0.0192, 0.0576, 0.096, 0.192, 0.384], + "LExpLevel_len": 6, + "NonOEPdfTh": [0.4, 0.45, 0.55, 0.65, 0.75, 1], + "NonOEPdfTh_len": 6, + "LowLightPdfTh": [0.2, 0.22, 0.25, 0.3, 0.35, 0.4], + "LowLightPdfTh_len": 6, + "LSetPoint": [75, 70, 65, 60, 45, 40], + "LSetPoint_len": 6, + "TargetLLLuma": [35, 32, 30, 28, 25, 20], + "TargetLLLuma_len": 6 + } + }, + "MframeCtrl": { + "MExpLevel": [0.096, 0.192, 0.384, 0.96, 1.344, 1.92], + "MExpLevel_len": 6, + "MSetPoint": [60, 60, 55, 50, 45, 40], + "MSetPoint_len": 6 + }, + "SframeCtrl": { + "HLROIExpandEn": 0, + "HLLumaTolerance": 12, + "SfrmSetPoint": { + "SExpLevel": [0, 0.0048, 0.0144, 0.024, 0.0384, 0.0576], + "SExpLevel_len": 6, + "SSetPoint": [18, 18, 15, 12, 12, 12], + "SSetPoint_len": 6, + "TargetHLLuma": [100, 100, 100, 90, 80, 70], + "TargetHLLuma_len": 6 + } + } + }, + "IrisCtrl": { + "Enable": 0, + "IrisType": "IRISV2_DC_TYPE", + "ManualEn": 0, + "ManualAttr": { + "PIrisGainValue": 1, + "DCIrisHoldValue": 30, + "HDCIrisTargetValue": 1023 + }, + "InitAttr": { + "PIrisGainValue": 512, + "DCIrisHoldValue": 100, + "HDCIrisTargetValue": 1023 + }, + "PIrisAttr": { + "TotalStep": 81, + "EffcStep": 44, + "ZeroIsMax": 1, + "StepTable": [512, 511, 506, 499, 491, 483, 474, 465, 456, 446, 437, 427, 417, 408, 398, 388, 378, 368, 359, 349, 339, 329, 319, 309, 300, 290, 280, 271, 261, 252, 242, 233, 224, 214, 205, 196, 187, 178, 170, 161, 153, 144, 136, 128, 120, 112, 105, 98, 90, 83, 77, 70, 64, 58, 52, 46, 41, 36, 31, 27, 23, 19, 16, 13, 10, 8, 6, 4, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "DCIrisAttr": { + "Kp": 0.5, + "Ki": 0.2, + "Kd": 0.3, + "MinPwmDuty": 0, + "MaxPwmDuty": 100, + "OpenPwmDuty": 40, + "ClosePwmDuty": 22 + }, + "HDCIrisAttr": { + "DampOver": 0.15, + "DampUnder": 0.45, + "ZeroIsMax": 0, + "MinTarget": 0, + "MaxTarget": 1023, + "ZoomTargetDot": [0], + "ZoomDot": [0], + "IrisTargetDot": [0], + "GainDot": [0], + "ZoomTargetDot_len": 1, + "IrisTargetDot_len": 1 + } + }, + "SyncTest": { + "Enable": 0, + "IntervalFrm": 60, + "AlterExp": { + "LinearAE": [{ + "TimeValue": 0.02, + "GainValue": 1, + "IspDGainValue": 1, + "PIrisGainValue": 1, + "DcgMode": 0 + }, { + "TimeValue": 0.02, + "GainValue": 6, + "IspDGainValue": 1, + "PIrisGainValue": 29, + "DcgMode": 0 + }], + "LinearAE_len": 2, + "HdrAE": [{ + "TimeValue": [0.01, 0.02, 0.03], + "GainValue": [1, 1, 1], + "IspDGainValue": [1, 1, 1], + "PIrisGainValue": 1, + "DcgMode": [0, 0, 0] + }, { + "TimeValue": [0.01, 0.02, 0.03], + "GainValue": [6, 6, 1], + "IspDGainValue": [1, 1, 1], + "PIrisGainValue": 29, + "DcgMode": [0, 0, 0] + }], + "HdrAE_len": 2 + } + } + }, + "wb_v32": { + "control": { + "byPass": 0, + "mode": "CALIB_WB_MODE_AUTO" + }, + "manualPara": { + "mode": "CALIB_MWB_MODE_WBGAIN", + "cfg": { + "mwbGain": [1.6, 1, 1, 1.68], + "scene": "CALIB_WB_SCENE_DAYLIGHT", + "cct": { + "CCT": 5000, + "CCRI": 0 + } + } + }, + "autoPara": { + "rawSelectPara": { + "frameChooseMode": "CALIB_AWB_INPUT_BAYERNR", + "frameChoose": 0 + }, + "blc2ForAwb": { + "enable": 0, + "offset": { + "ISO": [50, 100, 200, 400, 800, 1600, 3200, 10000, 12800, 25600, 51200, 102400, 204800], + "ISO_len": 13, + "R_Channel": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "R_Channel_len": 13, + "Gr_Channel": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "Gr_Channel_len": 13, + "Gb_Channel": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "Gb_Channel_len": 13, + "B_Channel": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "B_Channel_len": 13 + } + }, + "lscBypass": 0, + "uvDetectionEnable": 1, + "xyDetectionEnable": 1, + "yuvDetectionEnable": 1, + "blkStatisticsEnable": 1, + "downScaleMode": "CALIB_AWB_DS_4X4", + "blkMeasureMode": "CALIB_AWB_BLK_STAT_MODE_AL_V201", + "mainWindow": { + "mode": "CALIB_AWB_WINDOW_CFG_AUTO", + "window": [0, 0, 1, 1] + }, + "limitRange": { + "lumaValue": [0], + "lumaValue_len": 1, + "maxR": [230], + "maxR_len": 1, + "minR": [3], + "minR_len": 1, + "maxG": [230], + "maxG_len": 1, + "minG": [3], + "minG_len": 1, + "maxB": [230], + "maxB_len": 1, + "minB": [3], + "minB_len": 1, + "maxY": [230], + "maxY_len": 1, + "minY": [3], + "minY_len": 1 + }, + "rgb2TcsPara": { + "pseudoLuminanceWeight": [0.373836, 0.376081, 0.250083], + "rotationMat": [-0.525228, 0.850962, -0.433202, 0.850962, 0.525228, 0.534355, 0, 0, 1] + }, + "rgb2RotationYuvMat": [0.037109, 0.134766, 0.011719, 35.1875, -0.080078, -0.003906, 0.076172, 132.0625, 0.054688, -0.056641, 0.042969, 109.125, 0, 0, 0, 1], + "extraWpRange": [{ + "domain": "CALIB_AWB_EXTRA_RANGE_DOMAIN_UV", + "mode": "CALIB_AWB_EXCLUDE_WP_MODE", + "region": [0, 0, 0, 0], + "weightInculde": { + "lumaValue": [0], + "lumaValue_len": 1, + "weight": [0], + "weight_len": 1 + } + }, { + "domain": "CALIB_AWB_EXTRA_RANGE_DOMAIN_UV", + "mode": "CALIB_AWB_EXCLUDE_WP_MODE", + "region": [0, 0, 0, 0], + "weightInculde": { + "lumaValue": [0], + "lumaValue_len": 1, + "weight": [0], + "weight_len": 1 + } + }, { + "domain": "CALIB_AWB_EXTRA_RANGE_DOMAIN_UV", + "mode": "CALIB_AWB_EXCLUDE_WP_MODE", + "region": [0, 0, 0, 0], + "weightInculde": { + "lumaValue": [0], + "lumaValue_len": 1, + "weight": [0], + "weight_len": 1 + } + }, { + "domain": "CALIB_AWB_EXTRA_RANGE_DOMAIN_UV", + "mode": "CALIB_AWB_EXCLUDE_WP_MODE", + "region": [0, 0, 0, 0], + "weightInculde": { + "lumaValue": [0], + "lumaValue_len": 1, + "weight": [0], + "weight_len": 1 + } + }, { + "domain": "CALIB_AWB_EXTRA_RANGE_DOMAIN_UV", + "mode": "CALIB_AWB_EXCLUDE_WP_MODE", + "region": [0, 0, 0, 0], + "weightInculde": { + "lumaValue": [0], + "lumaValue_len": 1, + "weight": [0], + "weight_len": 1 + } + }, { + "domain": "CALIB_AWB_EXTRA_RANGE_DOMAIN_UV", + "mode": "CALIB_AWB_EXCLUDE_WP_MODE", + "region": [0, 0, 0, 0], + "weightInculde": { + "lumaValue": [0], + "lumaValue_len": 1, + "weight": [0], + "weight_len": 1 + } + }, { + "domain": "CALIB_AWB_EXTRA_RANGE_DOMAIN_UV", + "mode": "CALIB_AWB_EXCLUDE_WP_MODE", + "region": [0, 0, 0, 0], + "weightInculde": { + "lumaValue": [0], + "lumaValue_len": 1, + "weight": [0], + "weight_len": 1 + } + }], + "wpDiffLumaWeight": { + "enable": 0, + "wpDiffWeiEnableTh": { + "wpDiffWeiNoTh": 0.004, + "wpDiffWeiLvValueTh": 64 + }, + "wpDiffwei_y": [0, 16, 32, 64, 96, 128, 192, 224, 240], + "perfectBin": [0, 0, 0, 1, 1, 1, 1, 0], + "wpDiffWeightLvSet": [{ + "LvValue": 256, + "ratioSet": [{ + "ratioValue": 0, + "weight": [1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "ratioValue": 0.01, + "weight": [1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "ratioValue": 0.1, + "weight": [1, 1, 1, 1, 1, 1, 1, 1, 1] + }], + "ratioSet_len": 3 + }, { + "LvValue": 8192, + "ratioSet": [{ + "ratioValue": 0, + "weight": [1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "ratioValue": 0.01, + "weight": [1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "ratioValue": 0.1, + "weight": [0, 0, 0.2, 0.5, 1, 1, 1, 0.5, 0] + }], + "ratioSet_len": 3 + }], + "wpDiffWeightLvSet_len": 2 + }, + "wpDiffBlkWeiEnable": 0, + "wpDiffBlkWeight": [6, 6, 6, 8, 8, 8, 8, 10, 8, 8, 8, 8, 6, 6, 6, 6, 6, 8, 8, 10, 10, 12, 12, 12, 10, 10, 8, 8, 6, 6, 6, 8, 10, 12, 14, 16, 18, 20, 18, 16, 14, 12, 10, 8, 6, 8, 8, 12, 16, 22, 26, 30, 32, 30, 26, 22, 16, 12, 8, 8, 8, 10, 14, 22, 28, 36, 42, 46, 42, 36, 28, 22, 14, 10, 8, 8, 10, 16, 26, 36, 46, 54, 58, 54, 46, 36, 26, 16, 10, 8, 8, 12, 18, 30, 42, 54, 63, 63, 63, 54, 42, 30, 18, 12, 8, 10, 12, 20, 32, 46, 58, 63, 63, 63, 58, 46, 32, 20, 12, 10, 8, 12, 18, 30, 42, 54, 63, 63, 63, 54, 42, 30, 18, 12, 8, 8, 10, 16, 26, 36, 46, 54, 58, 54, 46, 36, 26, 16, 10, 8, 8, 10, 14, 22, 28, 36, 42, 46, 42, 36, 28, 22, 14, 10, 8, 8, 8, 12, 16, 22, 26, 30, 32, 30, 26, 22, 16, 12, 8, 8, 6, 8, 10, 12, 14, 16, 18, 20, 18, 16, 14, 12, 10, 8, 6, 6, 6, 8, 8, 10, 10, 12, 12, 12, 10, 10, 8, 8, 6, 6, 6, 6, 6, 8, 8, 8, 8, 10, 8, 8, 8, 8, 6, 6, 6], + "lightSources": [{ + "name": "A", + "doorType": "CALIB_AWB_DOOR_TYPE_INDOOR", + "standardGainValue": [1.3363, 1, 1, 2.6164], + "uvRegion": { + "u": [126.2, 51.3, 45.5, 125.7], + "v": [126.7, 97.2, 117.6, 127.6] + }, + "xyRegion": { + "normal": [-1.4845, -1.0901, 0.0974, -0.0966], + "big": [-1.4845, -1.0901, 0.1274, -0.1084] + }, + "rtYuvRegion": { + "thcurve_u": [50, 54, 70, 78, 110, 142], + "thcure_th": [1, 2, 4, 6, 8, 11], + "lineVector": [10, 138.0625, 108.5, 186.875, 99.5, 111.5], + "disP1P2": 15 + }, + "staWeight": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 90, 75], + "dayGainLvThSet": [1024, 8192], + "defaultDayGainLow": [1.855, 1, 1, 1.6082], + "defaultDayGainHigh": [2.1624, 1, 1, 1.407], + "weight": { + "lumaValue": [0, 2, 4, 8, 32, 128], + "lumaValue_len": 6, + "weight": [1, 1, 1, 1, 1, 1], + "weight_len": 6 + } + }, { + "name": "CWF", + "doorType": "CALIB_AWB_DOOR_TYPE_INDOOR", + "standardGainValue": [1.8167, 1, 1, 2.3045], + "uvRegion": { + "u": [127.2, 70.5, 57.8, 126.4], + "v": [125.8, 66.7, 87.9, 126.4] + }, + "xyRegion": { + "normal": [-1.0896, -0.6207, -0.0419, -0.1612], + "big": [-1.0896, -0.6207, -0.0419, -0.1912] + }, + "rtYuvRegion": { + "thcurve_u": [50, 54, 70, 78, 110, 142], + "thcure_th": [1, 2, 4, 6, 8, 11], + "lineVector": [10, 135.5, 109.375, 189.9375, 116.25, 104.1875], + "disP1P2": 15 + }, + "staWeight": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 90, 75], + "dayGainLvThSet": [1024, 8192], + "defaultDayGainLow": [1.855, 1, 1, 1.6082], + "defaultDayGainHigh": [2.1624, 1, 1, 1.407], + "weight": { + "lumaValue": [0, 2, 4, 8, 32, 128], + "lumaValue_len": 6, + "weight": [1, 1, 1, 1, 1, 1], + "weight_len": 6 + } + }, { + "name": "D50", + "doorType": "CALIB_AWB_DOOR_TYPE_AMBIGUITY", + "standardGainValue": [1.855, 1, 1, 1.6082], + "uvRegion": { + "u": [127.8, 96.3, 70.2, 127], + "v": [125.8, 51.4, 66.4, 125.9] + }, + "xyRegion": { + "normal": [-0.6207, -0.2669, 0.1148, -0.1496], + "big": [-0.6207, -0.2669, 0.1448, -0.1638] + }, + "rtYuvRegion": { + "thcurve_u": [50, 54, 70, 78, 110, 142], + "thcure_th": [1, 2, 4, 6, 8, 11], + "lineVector": [10, 133.375, 109, 191, 130.5, 110], + "disP1P2": 15 + }, + "staWeight": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 90, 75], + "dayGainLvThSet": [1024, 8192], + "defaultDayGainLow": [1.855, 1, 1, 1.6082], + "defaultDayGainHigh": [2.1624, 1, 1, 1.407], + "weight": { + "lumaValue": [0, 2, 4, 8, 32, 128], + "lumaValue_len": 6, + "weight": [1, 1, 1, 1, 1, 1], + "weight_len": 6 + } + }, { + "name": "D65", + "doorType": "CALIB_AWB_DOOR_TYPE_OUTDOOR", + "standardGainValue": [2.1624, 1, 1, 1.407], + "uvRegion": { + "u": [129.1, 118.8, 96.5, 127.6], + "v": [125.7, 44.7, 51.9, 125.9] + }, + "xyRegion": { + "normal": [-0.2669, -0.0303, 0.1075, -0.1364], + "big": [-0.2669, -0.0303, 0.1209, -0.1502] + }, + "rtYuvRegion": { + "thcurve_u": [50, 54, 70, 78, 110, 142], + "thcure_th": [1, 2, 4, 6, 8, 11], + "lineVector": [10, 131.3125, 108.8125, 190.625, 143.1875, 110.1875], + "disP1P2": 15 + }, + "staWeight": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 90, 75], + "dayGainLvThSet": [1024, 8192], + "defaultDayGainLow": [1.855, 1, 1, 1.6082], + "defaultDayGainHigh": [2.1624, 1, 1, 1.407], + "weight": { + "lumaValue": [0, 2, 4, 8, 32, 128], + "lumaValue_len": 6, + "weight": [1, 1, 1, 1, 1, 1], + "weight_len": 6 + } + }, { + "name": "D75", + "doorType": "CALIB_AWB_DOOR_TYPE_OUTDOOR", + "standardGainValue": [2.142, 1, 1, 1.2426], + "uvRegion": { + "u": [129.5, 140, 114.3, 128.2], + "v": [125.7, 46.9, 45.5, 125.8] + }, + "xyRegion": { + "normal": [-0.0306, 0.1163, 0.1102, -0.1439], + "big": [-0.0306, 0.1163, 0.1241, -0.1514] + }, + "rtYuvRegion": { + "thcurve_u": [50, 54, 70, 78, 110, 142], + "thcure_th": [1, 2, 4, 6, 8, 11], + "lineVector": [10, 130.5625, 109.125, 190.0625, 149, 112.5625], + "disP1P2": 15 + }, + "staWeight": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 90, 75], + "dayGainLvThSet": [1024, 8192], + "defaultDayGainLow": [1.855, 1, 1, 1.6082], + "defaultDayGainHigh": [2.1624, 1, 1, 1.407], + "weight": { + "lumaValue": [0, 2, 4, 8, 32, 128], + "lumaValue_len": 6, + "weight": [1, 1, 1, 1, 1, 1], + "weight_len": 6 + } + }, { + "name": "HZ", + "doorType": "CALIB_AWB_DOOR_TYPE_INDOOR", + "standardGainValue": [1.1093, 1, 1, 3.2581], + "uvRegion": { + "u": [125.8, 46.6, 45.6, 125.7], + "v": [128.7, 142.3, 117.6, 127.6] + }, + "xyRegion": { + "normal": [-1.9214, -1.4845, 0.0798, -0.1005], + "big": [-1.9214, -1.4845, 0.0895, -0.1305] + }, + "rtYuvRegion": { + "thcurve_u": [50, 54, 70, 78, 110, 142], + "thcure_th": [1, 2, 4, 6, 8, 11], + "lineVector": [10, 140.3125, 107.875, 182.5, 86, 115.625], + "disP1P2": 15 + }, + "staWeight": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 90, 75], + "dayGainLvThSet": [1024, 8192], + "defaultDayGainLow": [1.855, 1, 1, 1.6082], + "defaultDayGainHigh": [2.1624, 1, 1, 1.407], + "weight": { + "lumaValue": [0, 2, 4, 8, 32, 128], + "lumaValue_len": 6, + "weight": [1, 1, 1, 1, 1, 1], + "weight_len": 6 + } + }, { + "name": "TL84", + "doorType": "CALIB_AWB_DOOR_TYPE_INDOOR", + "standardGainValue": [1.6116, 1, 1, 2.2523], + "uvRegion": { + "u": [126.8, 64.2, 51.5, 126.2], + "v": [125.8, 77.8, 97.3, 126.7] + }, + "xyRegion": { + "normal": [-1.0901, -0.6207, 0.1111, -0.0429], + "big": [-1.0901, -0.6207, 0.1243, -0.0429] + }, + "rtYuvRegion": { + "thcurve_u": [50, 54, 70, 78, 110, 142], + "thcure_th": [1, 2, 4, 6, 8, 11], + "lineVector": [10, 136.375, 108.1875, 189.3125, 111.8125, 109.0625], + "disP1P2": 15 + }, + "staWeight": [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 90, 75], + "dayGainLvThSet": [1024, 8192], + "defaultDayGainLow": [1.855, 1, 1, 1.6082], + "defaultDayGainHigh": [2.1624, 1, 1, 1.407], + "weight": { + "lumaValue": [0, 2, 4, 8, 32, 128], + "lumaValue_len": 6, + "weight": [1, 1, 1, 1, 1, 1], + "weight_len": 6 + } + }], + "lightSources_len": 7, + "earlierAwbAct": { + "enable": 1, + "mode": "CALIB_AWB_EARLACT_XYREG_FIXED", + "xyRegion": [{ + "normal": [-273, 65, 81, -113], + "big": [-273, 65, 112, -143] + }, { + "normal": [-894, -273, 118, -165], + "big": [-894, -273, 148, -196] + }, { + "normal": [-1520, -894, 100, -83], + "big": [-1520, -894, 130, -113] + }, { + "normal": [-1968, -1520, 61, -103], + "big": [-1968, -1520, 92, -134] + }] + } + }, + "autoExtPara": { + "lightSourceForFirstFrame": "D50", + "smartRun": { + "enable": 1, + "cfg": { + "lumaValue": [0], + "lumaValue_len": 1, + "lvVarTh": [0.001], + "lvVarTh_len": 1, + "wbgainAlgDiffTh": [0.005], + "wbgainAlgDiffTh_len": 1, + "wbgainHwDiffTh": [0.05], + "wbgainHwDiffTh_len": 1 + } + }, + "tolerance": { + "lumaValue": [256, 512, 32768, 131072], + "lumaValue_len": 4, + "toleranceValue": [0, 0, 0, 0], + "toleranceValue_len": 4 + }, + "runInterval": { + "lumaValue": [256, 512, 32768, 131072], + "lumaValue_len": 4, + "intervalValue": [0, 0, 0, 0], + "intervalValue_len": 4 + }, + "dampFactor": { + "dFStep": 0.05, + "dFMin": 0.7, + "dFMax": 0.9, + "lvIIRsize": 4, + "lvVarTh": 0.04 + }, + "wbGainAdjust": { + "enable": 0, + "ctrlDataSelt": "AWB_CTRL_DATA_LV", + "adjDataSelt": "AWB_GAIN_ADJ_DATA_GAIN", + "lutAll": [{ + "ctlData": 128, + "rgct_in_ds": [0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2], + "bgcri_in_ds": [4.2, 3.9, 3.6, 3.3, 3, 2.7, 2.4, 2.1, 1.8, 1.5, 1.2], + "rgct_lut_out": [0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2, 0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2, 0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2, 0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2, 0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2, 0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2, 0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2, 0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2, 0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2, 0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2, 0.8, 1.1, 1.4, 1.7, 2, 2.3, 2.6, 2.9, 3.2], + "bgcri_lut_out": [4.2, 4.2, 4.2, 4.2, 4.2, 4.2, 4.2, 4.2, 4.2, 3.9, 3.9, 3.9, 3.9, 3.9, 3.9, 3.9, 3.9, 3.9, 3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 3.3, 3.3, 3.3, 3.3, 3.3, 3.3, 3.3, 3.3, 3.3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2.7, 2.7, 2.7, 2.7, 2.7, 2.7, 2.7, 2.7, 2.7, 2.4, 2.4, 2.4, 2.4, 2.4, 2.4, 2.4, 2.4, 2.4, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2] + }], + "lutAll_len": 1 + }, + "wbGainDaylightClip": { + "enable": 0, + "outdoor_cct_min": 5000 + }, + "wbGainClip": { + "enable": 0, + "cct": [1000, 2856, 4100, 6500, 7500, 10000], + "cct_len": 6, + "cri_bound_up": [0.3, 0.3, 0.3, 0.3, 0.3, 0.3], + "cri_bound_up_len": 6, + "cri_bound_low": [0.3, 0.3, 0.3, 0.3, 0.3, 0.3], + "cri_bound_low_len": 6 + }, + "division": { + "lumaValThLow": 110, + "lumaValThLow2": 200, + "lumaValThHigh": 65536, + "lumaValThHigh2": 65600, + "wpNumTh": { + "lumaValue": [0], + "lumaValue_len": 1, + "low": [150], + "low_len": 1, + "high": [216], + "high_len": 1 + } + }, + "defaultNightGain": [1.855, 1, 1, 1.6082], + "lumaValueMatrix": [0, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144], + "defaultNightGainWeight": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "probCalcDis": { + "proDis_THH": 6.6124, + "proDis_THL": 0.0269 + }, + "probCalcLv": { + "outdoorLumaValThLow": 30000, + "outdoorLumaValThHigh": 45745 + }, + "probCalcWp": { + "wpNumPercTh": 0.0031, + "wpNumPercTh2": 0.2 + }, + "converged": { + "varThforUnDamp": 0.005, + "varThforDamp": 0.005 + }, + "xyRegionStableSelection": { + "enable": 1, + "wpNumTh": { + "lumaValue": [0], + "lumaValue_len": 1, + "forBigType": [216], + "forBigType_len": 1, + "forExtraType": [216], + "forExtraType_len": 1 + }, + "xyTypeListSize": 50, + "varianceLumaTh": 0.06 + }, + "weightForNightGainCalc": [25, 25, 25, 25], + "weightForNightGainCalc_len": 4, + "singleColorProces": { + "enable": 1, + "mode": "AWB_SGC_CALL_INITIAL", + "colorBlock": [{ + "index": 15, + "meanC": 28.89649, + "meanH": 39.442471, + "ct": [2000, 5000, 6500], + "disTh": [900, 900, 900] + }, { + "index": 13, + "meanC": 24.278437, + "meanH": -75.102058, + "ct": [2000, 5000, 6500], + "disTh": [900, 900, 900] + }, { + "index": 5, + "meanC": 12.683658, + "meanH": -66.402748, + "ct": [2000, 5000, 6500], + "disTh": [900, 900, 900] + }, { + "index": 10, + "meanC": 12.094868, + "meanH": -36.849483, + "ct": [2000, 5000, 6500], + "disTh": [900, 900, 900] + }, { + "index": 14, + "meanC": 18.890467, + "meanH": 151.683365, + "ct": [2000, 5000, 6500], + "disTh": [900, 900, 900] + }, { + "index": 16, + "meanC": 34.846539, + "meanH": 93.63662, + "ct": [2000, 5000, 6500], + "disTh": [900, 900, 900] + }], + "colorBlock_len": 6, + "lsUsedForEstimation": [{ + "name": "A", + "RGain": 1.336335, + "BGain": 2.616357 + }, { + "name": "TL84", + "RGain": 1.611648, + "BGain": 2.252276 + }, { + "name": "D50", + "RGain": 1.854963, + "BGain": 1.608214 + }], + "lsUsedForEstimation_len": 3, + "illuEstListSize": 10, + "alpha": 0.9, + "wgtClrGradX": [50, 100, 150, 200, 300, 600], + "wgtClrGradY": [1, 1, 0.5, 0.5, 0.2, 0], + "wgtDisX": [200, 400, 900, 1200, 2000, 3000], + "wgtDisCt": [2000, 5000, 6500], + "wgtDisHCtY": [1, 1, 1, 0, 0, 0], + "wgtDisMCtY": [1, 1, 1, 0, 0, 0], + "wgtDisLCtY": [1, 1, 1, 0, 0, 0], + "wgtLvX": [0, 32, 64, 128, 256, 2048, 4096, 8192], + "wgtLvY": [0, 0.5, 1, 1, 1, 1, 1, 1], + "wgtWpNumthX": [20, 100, 500, 1000, 2000, 2000], + "wgtWpNumthY": [1, 1, 0.5, 0.1, 0, 0], + "illuMchPrt": -1, + "useSgcResth": 0.6, + "updateDpWbgnTh": 2000, + "updateDpWbgnTh2": 0.8, + "updateEstWbgnTh": 2000 + }, + "lineRgBg": [-0.825738, -0.564054, -2.57923], + "lineRgProjCCT": [1, -0.000227, 0.688885], + "remosaicCfg": { + "enable": 0, + "applyInvWbGainEnable": 1, + "sensorWbGain": [1, 1, 1, 1] + }, + "wbGainOffset": { + "enable": 0, + "offset": [0, 0, 0, 0] + }, + "avaSiteRec": { + "enable": 1, + "frameNum": 3, + "fullFileName": "/tmp/avaSiteInfo", + "avaEnable": 1, + "wbgainTh": 0.2, + "lvValueTh": 2 + } + } + }, + "ablcV32_calib": { + "Blc0TuningPara": { + "enable": 1, + "BLC_Data": { + "ISO": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "R_Channel": [126.625, 126.4375, 125.5625, 124.1875, 122.4375, 122.4375, 122.4375, 122.4375, 122.4375, 122.4375, 122.4375, 122.4375, 122.4375], + "Gr_Channel": [126.625, 126.375, 126, 124.1875, 122.4375, 122.4375, 122.4375, 122.4375, 122.4375, 122.4375, 122.4375, 122.4375, 122.4375], + "Gb_Channel": [127.6875, 128.25, 127.625, 125.3125, 125, 125, 125, 125, 125, 125, 125, 125, 125], + "B_Channel": [127.6875, 128.25, 127.625, 125.3125, 125, 125, 125, 125, 125, 125, 125, 125, 125] + } + }, + "Blc1TuningPara": { + "enable": 1, + "BLC_Data": { + "ISO": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "R_Channel": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "Gr_Channel": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "Gb_Channel": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "B_Channel": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + } + }, + "BlcObPara": { + "enable": 1, + "BLC_OB_Data": { + "ISO": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "isp_ob_Offset": [7.125, 7.3125, 9.6875, 8.75, 21.6875, 21.6875, 21.6875, 21.6875, 21.6875, 21.6875, 21.6875, 21.6875, 21.6875], + "isp_ob_preDgain": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + } + } + }, + "ccm_calib_v2": { + "control": { + "enable": 1, + "wbgain_tolerance": 0, + "gain_tolerance": 0.2 + }, + "lumaCCM": { + "rgb2y_para": [38, 75, 15], + "asym_enable": 0, + "y_alp_sym": { + "highy_adj_en": 1, + "bound_pos_bit": 8, + "gain_yalp_curve": [{ + "iso": 50, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 100, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 200, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 400, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 800, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 1600, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 3200, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 6400, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 12800, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 25600, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 51200, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 102400, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }, { + "iso": 204800, + "y_alpha_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024] + }] + }, + "y_alp_asym": { + "bound_pos_bit": 8, + "right_pos_bit": 8, + "gain_yalp_curve": [{ + "iso": 50, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 100, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 200, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 400, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 800, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 1600, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 3200, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 6400, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 12800, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 25600, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 51200, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 102400, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }, { + "iso": 204800, + "y_alpha_lcurve": [512, 512, 512, 512, 512, 640, 768, 896, 1024], + "y_alpha_rcurve": [1024, 896, 768, 640, 512, 512, 512, 512, 512] + }] + }, + "gain_alphaScale_curve": { + "gain": [1, 2, 4, 8, 16, 32, 64, 128, 256], + "scale": [1, 1, 1, 1, 1, 1, 1, 1, 1] + } + }, + "enhCCM": { + "enh_adj_en": 0, + "enh_rat": { + "gains": [1, 2, 4, 8, 16, 128, 255, 512, 850], + "enh_rat_max": [1, 1, 1, 1, 1, 1, 1, 1, 1] + }, + "enh_rgb2y_para": [38, 75, 15] + }, + "TuningPara": { + "damp_enable": 1, + "illu_estim": { + "interp_enable": 0, + "default_illu": "A", + "weightRB": [1, 1], + "prob_limit": 0.2, + "frame_no": 8 + }, + "aCcmCof": [{ + "name": "A", + "awbGain": [1.3363, 2.6183], + "minDist": 0.05, + "matrixUsed": ["A_100", "A_74"], + "matrixUsed_len": 2, + "gain_sat_curve": { + "gains": [1, 4, 8, 16], + "sat": [100, 100, 100, 100] + } + }, { + "name": "CWF", + "awbGain": [1.8164, 2.3069], + "minDist": 0.05, + "matrixUsed": ["CWF_100", "CWF_74"], + "matrixUsed_len": 2, + "gain_sat_curve": { + "gains": [1, 4, 8, 16], + "sat": [100, 100, 100, 100] + } + }, { + "name": "D50", + "awbGain": [1.8556, 1.6092], + "minDist": 0.05, + "matrixUsed": ["D50_100", "D50_74"], + "matrixUsed_len": 2, + "gain_sat_curve": { + "gains": [1, 4, 8, 16], + "sat": [100, 100, 100, 100] + } + }, { + "name": "D65", + "awbGain": [2.1625, 1.4074], + "minDist": 0.05, + "matrixUsed": ["D65_100", "D65_74"], + "matrixUsed_len": 2, + "gain_sat_curve": { + "gains": [1, 4, 8, 16], + "sat": [100, 100, 100, 100] + } + }, { + "name": "D75", + "awbGain": [2.143, 1.2437], + "minDist": 0.05, + "matrixUsed": ["D75_100", "D75_74"], + "matrixUsed_len": 2, + "gain_sat_curve": { + "gains": [1, 4, 8, 16], + "sat": [100, 100, 100, 100] + } + }, { + "name": "HZ", + "awbGain": [1.1096, 3.2636], + "minDist": 0.05, + "matrixUsed": ["HZ_100", "HZ_74"], + "matrixUsed_len": 2, + "gain_sat_curve": { + "gains": [1, 4, 8, 16], + "sat": [100, 100, 100, 100] + } + }, { + "name": "TL84", + "awbGain": [1.6118, 2.2537], + "minDist": 0.05, + "matrixUsed": ["TL84_100", "TL84_74"], + "matrixUsed_len": 2, + "gain_sat_curve": { + "gains": [1, 4, 8, 16], + "sat": [100, 100, 100, 100] + } + }], + "aCcmCof_len": 7, + "matrixAll": [{ + "name": "A_100", + "illumination": "A", + "saturation": 100, + "ccMatrix": [1.6225, -0.5325, -0.09, -0.4633, 1.5363, -0.073, 0.0721, -1.1879, 2.1158], + "ccOffsets": [0, 0, 0] + }, { + "name": "A_74", + "illumination": "A", + "saturation": 74, + "ccMatrix": [1.2584, -0.2371, -0.0213, -0.2852, 1.2949, -0.0097, 0.1102, -0.7205, 1.6103], + "ccOffsets": [0, 0, 0] + }, { + "name": "CWF_100", + "illumination": "CWF", + "saturation": 100, + "ccMatrix": [2.072, -0.9613, -0.1106, -0.5001, 1.5172, -0.017, 0.061, -0.8124, 1.7514], + "ccOffsets": [0, 0, 0] + }, { + "name": "CWF_74", + "illumination": "CWF", + "saturation": 74, + "ccMatrix": [1.62, -0.5794, -0.0406, -0.2834, 1.2555, 0.0279, 0.1308, -0.4676, 1.3368], + "ccOffsets": [0, 0, 0] + }, { + "name": "D50_100", + "illumination": "D50", + "saturation": 100, + "ccMatrix": [1.7175, -0.596, -0.1215, -0.3329, 1.4994, -0.1664, 0.0278, -0.6267, 1.5989], + "ccOffsets": [0, 0, 0] + }, { + "name": "D50_74", + "illumination": "D50", + "saturation": 74, + "ccMatrix": [1.3546, -0.2778, -0.0768, -0.1627, 1.2735, -0.1108, 0.1034, -0.2991, 1.1957], + "ccOffsets": [0, 0, 0] + }, { + "name": "D65_100", + "illumination": "D65", + "saturation": 100, + "ccMatrix": [1.7998, -0.694, -0.1058, -0.2756, 1.4722, -0.1966, 0.0215, -0.5652, 1.5437], + "ccOffsets": [0, 0, 0] + }, { + "name": "D65_74", + "illumination": "D65", + "saturation": 74, + "ccMatrix": [1.4304, -0.3602, -0.0702, -0.1053, 1.2434, -0.1381, 0.1137, -0.2635, 1.1498], + "ccOffsets": [0, 0, 0] + }, { + "name": "D75_100", + "illumination": "D75", + "saturation": 100, + "ccMatrix": [1.8253, -0.687, -0.1382, -0.2933, 1.498, -0.2048, 0.0067, -0.471, 1.4643], + "ccOffsets": [0, 0, 0] + }, { + "name": "D75_74", + "illumination": "D75", + "saturation": 74, + "ccMatrix": [1.4481, -0.3478, -0.1003, -0.1195, 1.2698, -0.1503, 0.1016, -0.1865, 1.085], + "ccOffsets": [0, 0, 0] + }, { + "name": "HZ_100", + "illumination": "HZ", + "saturation": 100, + "ccMatrix": [1.5244, -0.2446, -0.2798, -0.5359, 1.4871, 0.0489, 0.013, -1.6517, 2.6387], + "ccOffsets": [0, 0, 0] + }, { + "name": "HZ_74", + "illumination": "HZ", + "saturation": 74, + "ccMatrix": [1.1653, -0.023, -0.1423, -0.3594, 1.2596, 0.0997, 0.046, -1.0627, 2.0167], + "ccOffsets": [0, 0, 0] + }, { + "name": "TL84_100", + "illumination": "TL84", + "saturation": 100, + "ccMatrix": [1.7758, -0.6397, -0.1361, -0.4462, 1.5505, -0.1042, 0.0509, -0.8561, 1.8052], + "ccOffsets": [0, 0, 0] + }, { + "name": "TL84_74", + "illumination": "TL84", + "saturation": 74, + "ccMatrix": [1.3857, -0.3126, -0.0731, -0.2586, 1.3089, -0.0503, 0.1083, -0.4712, 1.3629], + "ccOffsets": [0, 0, 0] + }], + "matrixAll_len": 14 + } + }, + "lut3d_calib": { + "common": { + "enable": 0, + "gain_tolerance": 0.1 + }, + "ALut3D": { + "damp_en": 0, + "lutAll": [{ + "name": "D65", + "awbGain": [1.65055, 1.51472], + "gain_alpha": { + "gain": [1, 2, 4, 8, 16, 32, 64, 128, 256], + "alpha": [1, 1, 1, 1, 1, 1, 1, 1, 1] + }, + "Table": { + "look_up_table_r": [0, 116, 236, 355, 475, 595, 720, 859, 981, 0, 123, 231, 344, 463, 584, 716, 862, 980, 0, 123, 247, 358, 464, 583, 727, 867, 969, 0, 118, 246, 372, 485, 602, 734, 847, 946, 0, 110, 246, 391, 502, 614, 727, 839, 949, 0, 102, 242, 396, 527, 628, 738, 854, 952, 0, 90, 235, 370, 496, 628, 745, 860, 971, 0, 72, 226, 366, 495, 617, 744, 870, 984, 0, 112, 247, 377, 506, 632, 755, 879, 993, 7, 119, 233, 361, 487, 611, 733, 869, 989, 21, 130, 256, 384, 504, 618, 743, 878, 1001, 0, 96, 237, 338, 475, 611, 753, 885, 988, 0, 41, 207, 331, 469, 629, 771, 882, 959, 0, 2, 198, 368, 487, 609, 743, 858, 958, 0, 0, 187, 358, 520, 625, 733, 863, 958, 0, 0, 175, 342, 479, 619, 742, 848, 974, 0, 0, 160, 336, 478, 606, 738, 867, 986, 0, 113, 248, 377, 506, 633, 756, 879, 994, 25, 128, 241, 348, 473, 601, 740, 891, 1004, 22, 130, 256, 377, 498, 620, 763, 908, 1017, 68, 129, 259, 384, 512, 646, 786, 911, 1023, 39, 81, 227, 367, 478, 601, 749, 875, 997, 0, 0, 172, 315, 479, 590, 727, 861, 985, 0, 0, 123, 280, 475, 594, 699, 841, 973, 0, 0, 85, 257, 433, 571, 687, 804, 984, 0, 0, 14, 232, 427, 575, 704, 832, 992, 0, 114, 249, 378, 507, 634, 757, 880, 995, 56, 136, 258, 363, 465, 587, 719, 863, 1010, 55, 150, 262, 376, 486, 607, 731, 876, 1012, 45, 137, 257, 384, 512, 635, 768, 918, 1018, 119, 163, 257, 388, 512, 647, 783, 907, 1023, 112, 136, 210, 366, 503, 639, 716, 841, 1023, 0, 0, 134, 331, 447, 617, 706, 804, 1007, 0, 0, 92, 244, 380, 547, 681, 790, 1004, 0, 0, 14, 203, 343, 520, 661, 784, 1003, 0, 110, 249, 380, 508, 635, 759, 882, 997, 88, 152, 258, 388, 485, 583, 701, 826, 977, 85, 164, 267, 390, 495, 598, 717, 844, 1001, 82, 153, 262, 384, 510, 629, 748, 879, 1005, 81, 159, 262, 385, 512, 664, 797, 909, 1014, 170, 206, 267, 385, 517, 640, 767, 895, 1019, 173, 192, 231, 359, 505, 640, 767, 873, 1011, 90, 113, 166, 291, 452, 569, 738, 870, 1012, 0, 0, 0, 217, 419, 534, 684, 845, 1020, 0, 88, 243, 379, 509, 636, 762, 885, 1000, 120, 172, 266, 385, 511, 607, 701, 818, 940, 116, 182, 275, 391, 515, 614, 712, 829, 960, 119, 178, 283, 397, 516, 630, 741, 858, 993, 106, 165, 266, 387, 516, 664, 791, 899, 998, 125, 188, 277, 387, 513, 640, 767, 895, 1005, 221, 250, 300, 385, 513, 646, 767, 895, 1016, 228, 245, 278, 334, 490, 634, 768, 895, 1013, 180, 194, 227, 281, 464, 548, 669, 865, 1017, 0, 76, 235, 371, 507, 638, 765, 888, 1004, 153, 196, 279, 387, 515, 633, 728, 819, 935, 146, 204, 286, 394, 518, 640, 734, 828, 952, 151, 203, 302, 407, 533, 647, 750, 852, 989, 147, 194, 288, 395, 518, 660, 785, 893, 992, 132, 192, 276, 391, 514, 640, 767, 895, 997, 171, 222, 302, 397, 514, 641, 768, 895, 1004, 272, 297, 341, 404, 513, 641, 775, 895, 1018, 281, 295, 326, 370, 479, 606, 747, 886, 1017, 389, 402, 432, 477, 529, 635, 766, 892, 1009, 185, 221, 295, 395, 513, 648, 756, 850, 936, 176, 228, 302, 401, 518, 648, 762, 855, 952, 181, 226, 316, 419, 540, 662, 772, 867, 989, 184, 227, 307, 417, 536, 663, 789, 888, 991, 170, 209, 285, 402, 518, 642, 768, 894, 995, 164, 218, 298, 400, 517, 642, 768, 895, 1000, 220, 261, 332, 418, 519, 641, 768, 895, 1006, 432, 423, 391, 436, 514, 647, 770, 898, 1020, 494, 506, 536, 584, 647, 719, 789, 895, 1015, 217, 249, 314, 407, 524, 644, 777, 878, 972, 206, 237, 314, 417, 541, 665, 796, 895, 987, 211, 224, 287, 422, 558, 697, 838, 921, 1001, 216, 225, 259, 402, 546, 688, 841, 923, 1003, 212, 219, 238, 371, 523, 667, 818, 926, 1005, 194, 198, 210, 298, 487, 647, 794, 931, 1008, 402, 413, 439, 482, 540, 611, 772, 928, 1012, 599, 605, 621, 646, 683, 732, 791, 897, 1017, 796, 800, 810, 827, 851, 884, 924, 970, 1023], + "look_up_table_g": [0, 32, 113, 243, 379, 514, 673, 907, 1167, 512, 517, 563, 639, 720, 805, 929, 1146, 1341, 1023, 1027, 1033, 1067, 1134, 1231, 1403, 1582, 1677, 1535, 1539, 1543, 1550, 1576, 1676, 1834, 1919, 2009, 2046, 2052, 2053, 2136, 2085, 2100, 2168, 2259, 2357, 2558, 2564, 2564, 2600, 2643, 2601, 2611, 2673, 2715, 3070, 3076, 3077, 3078, 3084, 3106, 3097, 3120, 3153, 3582, 3588, 3590, 3590, 3592, 3600, 3605, 3613, 3637, 4093, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 23, 36, 152, 235, 320, 420, 603, 848, 1119, 490, 509, 512, 512, 550, 649, 798, 1023, 1212, 1022, 1043, 1048, 1103, 1114, 1183, 1318, 1467, 1604, 1535, 1559, 1576, 1600, 1604, 1695, 1821, 1892, 1985, 2046, 2069, 2079, 2162, 2142, 2140, 2173, 2251, 2341, 2558, 2575, 2587, 2598, 2677, 2629, 2642, 2678, 2708, 3070, 3083, 3095, 3094, 3097, 3118, 3104, 3138, 3150, 3582, 3592, 3605, 3604, 3605, 3611, 3614, 3619, 3637, 4093, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 78, 78, 123, 334, 439, 523, 593, 678, 1024, 523, 514, 516, 541, 593, 650, 700, 780, 1112, 988, 1022, 1020, 1023, 1023, 1054, 1121, 1270, 1429, 1527, 1548, 1562, 1559, 1648, 1713, 1806, 1853, 1903, 2045, 2067, 2088, 2113, 2185, 2259, 2283, 2301, 2291, 2558, 2574, 2602, 2627, 2692, 2745, 2762, 2719, 2687, 3070, 3083, 3109, 3133, 3134, 3154, 3169, 3199, 3144, 3582, 3592, 3619, 3641, 3637, 3640, 3651, 3663, 3637, 4093, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 180, 180, 149, 260, 504, 632, 725, 804, 935, 552, 552, 570, 571, 659, 734, 802, 885, 1096, 1008, 1020, 1025, 1023, 1023, 1041, 1083, 1138, 1415, 1486, 1512, 1534, 1530, 1535, 1572, 1620, 1615, 1756, 2025, 2040, 2068, 2065, 2060, 2047, 2191, 2235, 2202, 2556, 2572, 2595, 2596, 2630, 2590, 2715, 2739, 2634, 3068, 3081, 3106, 3134, 3170, 3173, 3183, 3225, 3128, 3580, 3591, 3617, 3644, 3679, 3687, 3700, 3721, 3635, 4093, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 297, 299, 293, 212, 401, 669, 815, 924, 1006, 591, 610, 626, 620, 650, 797, 898, 998, 1028, 1058, 1048, 1037, 1046, 1038, 1069, 1126, 1212, 1368, 1501, 1515, 1532, 1536, 1535, 1620, 1631, 1596, 1723, 1983, 2002, 2038, 2046, 2039, 2047, 2047, 2047, 2131, 2523, 2534, 2565, 2573, 2563, 2558, 2559, 2602, 2612, 3059, 3069, 3091, 3110, 3123, 3159, 3113, 3112, 3116, 3578, 3589, 3615, 3636, 3638, 3675, 3679, 3650, 3628, 4090, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 414, 417, 417, 398, 302, 541, 835, 990, 1114, 644, 684, 697, 692, 643, 746, 942, 1063, 1134, 1080, 1083, 1073, 1095, 1089, 1095, 1159, 1255, 1276, 1540, 1550, 1544, 1538, 1555, 1626, 1614, 1613, 1675, 1996, 2008, 2026, 2047, 2047, 2047, 2047, 2047, 2122, 2481, 2495, 2528, 2557, 2558, 2549, 2559, 2559, 2579, 3023, 3031, 3055, 3092, 3085, 3075, 3070, 3071, 3107, 3557, 3565, 3584, 3616, 3606, 3667, 3710, 3631, 3616, 4090, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 531, 535, 536, 530, 489, 412, 682, 1003, 1159, 709, 765, 774, 777, 751, 680, 852, 1090, 1183, 1112, 1129, 1123, 1147, 1194, 1123, 1173, 1274, 1277, 1588, 1585, 1564, 1559, 1593, 1659, 1634, 1611, 1693, 2026, 2040, 2044, 2049, 2049, 2047, 2047, 2047, 2147, 2492, 2501, 2519, 2546, 2559, 2559, 2559, 2559, 2616, 2978, 2989, 3017, 3055, 3069, 3069, 3060, 3071, 3083, 3522, 3529, 3547, 3582, 3600, 3608, 3608, 3597, 3606, 4014, 4018, 4028, 4047, 4081, 4095, 4095, 4095, 4095, 649, 651, 654, 652, 636, 558, 535, 823, 1173, 783, 849, 856, 862, 855, 809, 755, 967, 1195, 1154, 1171, 1184, 1228, 1272, 1256, 1166, 1251, 1270, 1609, 1619, 1599, 1594, 1638, 1689, 1661, 1635, 1688, 2078, 2084, 2078, 2062, 2056, 2059, 2052, 2055, 2145, 2517, 2527, 2540, 2550, 2560, 2559, 2559, 2559, 2622, 2989, 2996, 3011, 3037, 3065, 3071, 3071, 3071, 3108, 3443, 3460, 3506, 3545, 3580, 3577, 3580, 3578, 3588, 3964, 3966, 3972, 3983, 4000, 4027, 4071, 4095, 4095, 766, 769, 772, 772, 798, 750, 615, 664, 964, 862, 839, 836, 843, 860, 807, 642, 678, 982, 1203, 1156, 1031, 1083, 1160, 1071, 717, 887, 1214, 1638, 1624, 1564, 1540, 1585, 1608, 1312, 1446, 1652, 2117, 2117, 2106, 2077, 2050, 2018, 1950, 1976, 2121, 2558, 2567, 2589, 2619, 2593, 2561, 2527, 2495, 2606, 2976, 2981, 2995, 3020, 3056, 3105, 3072, 3026, 3098, 3390, 3395, 3408, 3431, 3464, 3508, 3562, 3583, 3595, 3782, 3787, 3799, 3820, 3852, 3895, 3950, 4016, 4095], + "look_up_table_b": [0, 4, 15, 32, 58, 83, 103, 105, 86, 2, 0, 18, 40, 65, 89, 103, 111, 68, 7, 0, 0, 35, 68, 99, 114, 111, 0, 16, 0, 0, 0, 52, 92, 111, 86, 0, 30, 0, 0, 0, 0, 52, 100, 10, 0, 48, 0, 0, 0, 0, 0, 25, 68, 154, 67, 0, 0, 0, 0, 0, 0, 11, 154, 86, 0, 0, 0, 0, 0, 0, 0, 0, 105, 90, 104, 116, 131, 176, 260, 336, 485, 93, 118, 107, 101, 99, 102, 118, 120, 103, 151, 129, 128, 128, 132, 144, 153, 165, 63, 136, 112, 106, 121, 140, 154, 163, 167, 0, 136, 99, 0, 23, 124, 147, 160, 106, 0, 139, 92, 0, 0, 7, 112, 125, 53, 0, 145, 107, 0, 0, 0, 0, 71, 99, 157, 153, 120, 0, 0, 0, 0, 22, 94, 157, 163, 132, 0, 0, 0, 0, 0, 10, 0, 174, 164, 170, 180, 189, 220, 290, 358, 499, 196, 214, 238, 227, 217, 211, 198, 162, 143, 228, 248, 253, 250, 246, 244, 231, 209, 115, 295, 258, 258, 256, 256, 259, 261, 260, 151, 269, 260, 224, 235, 225, 247, 260, 234, 0, 271, 253, 218, 133, 160, 173, 200, 173, 0, 270, 252, 208, 84, 0, 0, 123, 221, 166, 271, 255, 204, 56, 0, 0, 79, 179, 163, 275, 259, 195, 0, 0, 0, 0, 92, 0, 280, 274, 274, 282, 287, 303, 354, 408, 531, 299, 315, 330, 359, 347, 337, 327, 313, 254, 328, 327, 321, 358, 364, 361, 360, 354, 258, 391, 381, 380, 384, 384, 379, 380, 357, 276, 439, 407, 385, 387, 384, 390, 396, 393, 309, 409, 401, 385, 370, 375, 383, 345, 353, 209, 399, 391, 381, 350, 280, 361, 281, 339, 184, 405, 395, 372, 323, 204, 171, 229, 259, 174, 403, 393, 363, 316, 174, 49, 0, 164, 23, 404, 398, 395, 394, 400, 408, 437, 481, 583, 403, 415, 434, 454, 480, 468, 457, 447, 426, 436, 422, 423, 429, 479, 480, 474, 468, 418, 444, 466, 488, 486, 502, 502, 496, 497, 425, 546, 526, 511, 509, 512, 531, 530, 516, 431, 583, 557, 520, 513, 515, 512, 512, 511, 488, 548, 543, 524, 515, 518, 512, 511, 500, 431, 534, 530, 521, 514, 452, 372, 476, 489, 384, 535, 530, 516, 495, 465, 384, 375, 454, 182, 539, 532, 527, 521, 518, 523, 537, 571, 652, 506, 515, 534, 551, 585, 601, 588, 577, 567, 543, 517, 523, 537, 569, 600, 597, 589, 570, 554, 556, 566, 551, 569, 606, 618, 611, 576, 606, 601, 617, 632, 644, 665, 659, 640, 581, 696, 676, 657, 635, 637, 639, 640, 639, 595, 728, 707, 669, 642, 641, 644, 640, 640, 631, 688, 684, 668, 643, 643, 646, 640, 639, 578, 673, 670, 660, 644, 650, 551, 435, 585, 533, 661, 658, 658, 658, 649, 644, 649, 672, 734, 610, 617, 633, 653, 666, 713, 722, 708, 698, 650, 616, 625, 640, 655, 702, 721, 715, 707, 662, 649, 650, 642, 651, 676, 720, 733, 723, 669, 679, 710, 728, 724, 756, 772, 766, 725, 769, 749, 756, 755, 760, 766, 767, 767, 727, 845, 829, 806, 777, 764, 765, 767, 767, 734, 872, 855, 820, 783, 770, 769, 772, 768, 762, 828, 825, 812, 787, 771, 767, 751, 757, 725, 822, 820, 815, 806, 787, 778, 770, 780, 824, 713, 719, 733, 753, 771, 781, 838, 843, 826, 757, 719, 728, 743, 760, 771, 830, 842, 839, 769, 758, 746, 757, 773, 769, 815, 841, 866, 779, 770, 799, 804, 794, 810, 838, 857, 868, 817, 814, 836, 858, 875, 876, 888, 889, 871, 927, 909, 898, 893, 885, 892, 895, 895, 874, 991, 980, 957, 926, 897, 892, 893, 895, 877, 991, 985, 969, 931, 899, 897, 896, 897, 893, 958, 957, 954, 949, 942, 931, 912, 896, 921, 817, 822, 834, 852, 888, 891, 906, 961, 964, 864, 880, 887, 908, 936, 932, 928, 981, 979, 876, 921, 1002, 1002, 1003, 1004, 983, 1012, 993, 887, 918, 1001, 1003, 1004, 1005, 1010, 1013, 995, 894, 914, 970, 1002, 1006, 1007, 1010, 1015, 998, 984, 990, 1005, 1005, 1005, 1009, 1011, 1016, 1003, 1012, 1012, 1012, 1013, 1013, 1010, 1012, 1016, 1008, 1009, 1009, 1010, 1011, 1013, 1015, 1017, 1017, 1015, 1007, 1007, 1008, 1009, 1010, 1012, 1015, 1019, 1023] + } + }, { + "name": "TL84", + "awbGain": [1.14932, 2.23636], + "gain_alpha": { + "gain": [1, 2, 4, 8, 16, 32, 64, 128, 256], + "alpha": [1, 1, 1, 1, 1, 1, 1, 1, 1] + }, + "Table": { + "look_up_table_r": [0, 119, 241, 363, 485, 607, 741, 900, 1009, 0, 125, 248, 371, 492, 612, 756, 913, 1009, 0, 122, 251, 375, 495, 629, 796, 935, 1008, 0, 121, 243, 377, 504, 673, 842, 927, 1001, 0, 117, 246, 414, 520, 651, 774, 876, 1000, 0, 111, 245, 369, 500, 629, 765, 880, 1002, 0, 108, 242, 370, 490, 621, 755, 896, 1008, 0, 103, 238, 368, 493, 609, 747, 881, 1012, 0, 121, 250, 379, 506, 631, 752, 881, 1003, 4, 126, 241, 362, 484, 606, 748, 920, 1009, 0, 128, 243, 363, 505, 621, 765, 911, 1009, 0, 118, 256, 370, 496, 633, 798, 926, 1008, 0, 58, 215, 371, 512, 698, 847, 920, 1009, 0, 21, 202, 369, 534, 668, 781, 881, 1009, 0, 0, 197, 343, 477, 630, 765, 887, 1008, 0, 0, 193, 343, 473, 611, 758, 894, 1008, 0, 0, 187, 341, 476, 597, 741, 884, 1012, 0, 123, 251, 379, 506, 631, 753, 881, 1003, 15, 124, 251, 364, 485, 606, 752, 897, 1008, 27, 128, 253, 383, 498, 616, 767, 915, 1008, 0, 128, 256, 381, 476, 600, 784, 924, 1007, 0, 87, 248, 384, 497, 650, 810, 900, 1009, 0, 20, 234, 379, 511, 636, 761, 877, 1009, 0, 0, 178, 319, 482, 615, 738, 880, 1008, 0, 0, 109, 277, 425, 575, 734, 871, 1009, 0, 0, 73, 266, 426, 562, 717, 870, 1013, 0, 127, 253, 380, 507, 633, 753, 882, 1004, 35, 128, 250, 378, 488, 607, 728, 860, 973, 50, 142, 252, 381, 498, 610, 729, 861, 997, 34, 138, 256, 382, 487, 619, 769, 905, 1007, 0, 128, 256, 384, 509, 630, 714, 826, 1010, 0, 89, 230, 377, 512, 632, 729, 855, 1011, 0, 0, 191, 365, 508, 639, 758, 864, 1010, 0, 0, 115, 350, 493, 638, 766, 876, 1009, 0, 0, 74, 293, 425, 589, 729, 866, 1013, 10, 131, 256, 382, 509, 635, 756, 883, 1005, 62, 138, 250, 379, 504, 612, 731, 851, 971, 73, 154, 256, 374, 504, 616, 731, 851, 992, 98, 159, 262, 381, 503, 632, 757, 880, 1008, 41, 149, 260, 383, 511, 662, 752, 882, 1009, 0, 128, 256, 384, 512, 637, 760, 863, 1012, 0, 91, 219, 363, 505, 639, 763, 871, 1012, 0, 1, 159, 335, 495, 637, 767, 889, 1011, 0, 0, 69, 301, 482, 623, 767, 895, 1013, 12, 133, 258, 385, 511, 637, 761, 885, 1007, 89, 151, 254, 374, 506, 630, 735, 854, 974, 97, 170, 262, 375, 503, 628, 738, 854, 993, 116, 180, 275, 385, 507, 634, 764, 870, 1009, 113, 178, 271, 382, 506, 668, 789, 896, 1009, 51, 159, 265, 385, 511, 639, 763, 868, 1011, 0, 128, 256, 384, 512, 639, 765, 890, 1014, 0, 89, 217, 356, 494, 633, 767, 892, 1013, 0, 0, 170, 315, 469, 616, 765, 895, 1014, 9, 131, 257, 385, 512, 639, 764, 887, 1010, 115, 168, 262, 375, 501, 634, 757, 858, 978, 122, 188, 271, 378, 499, 633, 753, 862, 996, 138, 201, 287, 390, 514, 636, 760, 883, 1010, 164, 207, 290, 395, 517, 665, 793, 901, 1011, 121, 198, 281, 391, 510, 638, 765, 888, 1012, 61, 163, 270, 388, 511, 639, 767, 892, 1013, 1, 128, 256, 384, 512, 639, 767, 893, 1016, 0, 85, 219, 349, 489, 614, 759, 895, 1016, 27, 139, 261, 386, 512, 640, 767, 891, 1013, 141, 187, 272, 379, 498, 629, 761, 883, 980, 147, 206, 282, 384, 505, 626, 760, 880, 997, 161, 217, 300, 399, 523, 651, 766, 883, 1010, 183, 234, 307, 407, 521, 652, 788, 896, 1011, 191, 233, 302, 405, 513, 634, 758, 889, 1013, 128, 205, 295, 399, 515, 636, 768, 893, 1014, 72, 166, 276, 391, 514, 631, 766, 895, 1016, 1, 128, 256, 383, 512, 640, 767, 895, 1019, 28, 139, 261, 387, 513, 641, 768, 895, 1018, 168, 207, 285, 387, 508, 635, 760, 888, 1001, 173, 185, 279, 392, 523, 656, 778, 895, 1001, 184, 193, 262, 392, 524, 657, 801, 896, 1002, 203, 208, 251, 387, 523, 657, 794, 898, 1003, 230, 233, 241, 375, 514, 647, 785, 901, 1005, 200, 208, 228, 335, 499, 641, 775, 905, 1008, 135, 139, 188, 347, 488, 622, 768, 907, 1012, 83, 84, 186, 348, 491, 627, 759, 895, 1017, 5, 130, 257, 384, 512, 640, 767, 895, 1023], + "look_up_table_g": [0, 23, 78, 174, 289, 404, 542, 825, 1067, 512, 514, 520, 543, 588, 646, 777, 1072, 1205, 1023, 1027, 1028, 1030, 1028, 1075, 1280, 1491, 1470, 1535, 1538, 1545, 1542, 1543, 1748, 1948, 1842, 1673, 2047, 2050, 2052, 2256, 2119, 2108, 2133, 2083, 2100, 2559, 2562, 2564, 2568, 2597, 2570, 2558, 2579, 2593, 3071, 3074, 3075, 3078, 3086, 3088, 3083, 3064, 3089, 3583, 3586, 3588, 3589, 3593, 3605, 3603, 3597, 3572, 4094, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4074, 16, 6, 81, 186, 302, 416, 510, 575, 1005, 512, 512, 535, 569, 533, 597, 734, 1029, 1156, 1024, 1030, 1023, 1049, 1030, 1084, 1304, 1480, 1448, 1536, 1558, 1569, 1590, 1580, 1797, 1948, 1819, 1628, 2048, 2068, 2078, 2218, 2207, 2158, 2117, 2073, 2080, 2559, 2577, 2584, 2588, 2596, 2570, 2559, 2567, 2585, 3071, 3085, 3092, 3094, 3101, 3101, 3080, 3069, 3089, 3583, 3594, 3601, 3602, 3606, 3617, 3611, 3595, 3573, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4074, 61, 58, 23, 171, 306, 425, 526, 611, 822, 521, 527, 518, 513, 576, 646, 719, 841, 1000, 1023, 1023, 1024, 1028, 1095, 1198, 1244, 1355, 1349, 1536, 1551, 1542, 1536, 1553, 1722, 1854, 1754, 1616, 2048, 2068, 2060, 2051, 2045, 2135, 2126, 2086, 2079, 2560, 2577, 2590, 2604, 2590, 2589, 2601, 2583, 2584, 3072, 3085, 3109, 3126, 3138, 3138, 3111, 3105, 3089, 3583, 3594, 3618, 3632, 3638, 3648, 3637, 3613, 3575, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4075, 142, 129, 139, 48, 278, 417, 545, 659, 791, 545, 563, 585, 543, 584, 689, 775, 862, 822, 1027, 1030, 1031, 1022, 1049, 1061, 1060, 1190, 1204, 1536, 1536, 1536, 1536, 1539, 1597, 1714, 1757, 1602, 2048, 2058, 2064, 2054, 2048, 2058, 2108, 2131, 2077, 2560, 2577, 2586, 2572, 2563, 2559, 2564, 2609, 2582, 3072, 3085, 3109, 3090, 3086, 3072, 3068, 3094, 3088, 3584, 3595, 3618, 3622, 3638, 3628, 3624, 3616, 3579, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4076, 248, 238, 228, 201, 90, 388, 523, 658, 784, 583, 614, 628, 655, 571, 659, 774, 862, 805, 1049, 1050, 1056, 1060, 1031, 1038, 1063, 1170, 1097, 1538, 1541, 1543, 1541, 1537, 1679, 1760, 1733, 1581, 2047, 2048, 2048, 2047, 2048, 2051, 2060, 2115, 2077, 2560, 2567, 2577, 2575, 2566, 2559, 2565, 2597, 2579, 3072, 3085, 3101, 3099, 3084, 3074, 3071, 3078, 3087, 3583, 3595, 3619, 3619, 3602, 3598, 3583, 3582, 3585, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4078, 354, 345, 332, 339, 222, 149, 501, 629, 768, 634, 681, 686, 680, 661, 610, 733, 852, 788, 1070, 1082, 1091, 1111, 1111, 1064, 1036, 1148, 1084, 1550, 1554, 1556, 1563, 1570, 1692, 1722, 1664, 1574, 2049, 2052, 2053, 2055, 2053, 2049, 2054, 2106, 2075, 2559, 2559, 2559, 2559, 2559, 2559, 2562, 2567, 2578, 3072, 3078, 3086, 3089, 3087, 3078, 3071, 3076, 3084, 3584, 3595, 3606, 3615, 3612, 3605, 3586, 3583, 3589, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4081, 461, 454, 439, 425, 449, 243, 217, 618, 735, 697, 752, 749, 738, 743, 651, 647, 805, 753, 1101, 1126, 1138, 1160, 1240, 1176, 1093, 1087, 1066, 1575, 1577, 1578, 1585, 1617, 1730, 1702, 1606, 1562, 2055, 2061, 2062, 2066, 2065, 2057, 2055, 2063, 2066, 2561, 2562, 2564, 2565, 2567, 2564, 2561, 2563, 2574, 3071, 3071, 3071, 3071, 3071, 3071, 3071, 3073, 3082, 3584, 3589, 3595, 3601, 3600, 3607, 3593, 3583, 3591, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4085, 568, 562, 545, 525, 523, 550, 264, 284, 739, 771, 823, 819, 808, 832, 826, 662, 677, 754, 1140, 1169, 1192, 1235, 1325, 1383, 1212, 1122, 1061, 1595, 1609, 1611, 1621, 1658, 1745, 1733, 1622, 1557, 2076, 2080, 2080, 2083, 2093, 2098, 2097, 2078, 2060, 2565, 2568, 2572, 2573, 2577, 2570, 2563, 2566, 2567, 3073, 3074, 3075, 3076, 3078, 3083, 3075, 3073, 3077, 3583, 3583, 3583, 3583, 3583, 3583, 3583, 3583, 3588, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4090, 674, 669, 655, 634, 696, 725, 633, 293, 533, 849, 739, 718, 720, 781, 802, 676, 528, 770, 1189, 1141, 1048, 1153, 1337, 1388, 972, 1026, 1162, 1623, 1608, 1562, 1550, 1639, 1757, 1591, 1530, 1619, 2100, 2099, 2089, 2071, 2056, 2045, 2022, 2037, 2100, 2578, 2583, 2596, 2604, 2583, 2565, 2553, 2543, 2592, 3075, 3082, 3094, 3094, 3094, 3097, 3074, 3058, 3090, 3585, 3592, 3600, 3598, 3596, 3594, 3593, 3585, 3592, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095], + "look_up_table_b": [0, 6, 19, 43, 73, 102, 123, 133, 194, 1, 3, 22, 44, 73, 101, 118, 142, 203, 2, 0, 10, 51, 75, 96, 116, 157, 219, 6, 0, 0, 24, 80, 119, 139, 166, 195, 10, 0, 0, 0, 24, 94, 129, 173, 198, 18, 0, 0, 0, 0, 67, 133, 175, 206, 27, 0, 0, 0, 0, 0, 89, 158, 205, 37, 0, 0, 0, 0, 0, 0, 112, 391, 50, 52, 78, 96, 129, 194, 292, 311, 547, 103, 129, 134, 144, 157, 173, 180, 144, 232, 128, 128, 135, 141, 134, 152, 163, 190, 235, 127, 123, 131, 130, 141, 156, 178, 213, 251, 126, 85, 56, 111, 145, 174, 197, 219, 209, 127, 67, 9, 0, 109, 150, 180, 212, 208, 129, 61, 0, 0, 0, 141, 181, 213, 218, 132, 72, 0, 0, 0, 0, 158, 200, 242, 136, 84, 0, 0, 0, 0, 12, 172, 405, 141, 142, 156, 167, 187, 233, 320, 336, 558, 213, 230, 257, 261, 269, 278, 287, 287, 307, 226, 236, 247, 256, 261, 269, 274, 275, 308, 256, 256, 256, 257, 274, 291, 281, 286, 311, 254, 242, 252, 256, 280, 287, 287, 294, 294, 254, 230, 244, 252, 272, 271, 267, 285, 298, 253, 228, 207, 174, 215, 249, 255, 286, 305, 253, 229, 168, 95, 24, 101, 228, 268, 319, 254, 231, 153, 62, 10, 0, 131, 245, 439, 256, 257, 262, 273, 283, 309, 379, 392, 584, 323, 340, 348, 386, 389, 396, 404, 413, 424, 337, 326, 320, 366, 385, 390, 398, 408, 416, 366, 363, 374, 381, 384, 386, 388, 400, 412, 384, 384, 384, 384, 385, 398, 421, 431, 398, 381, 374, 370, 380, 384, 388, 423, 417, 405, 382, 365, 357, 374, 381, 383, 423, 408, 413, 381, 365, 335, 365, 368, 387, 412, 415, 420, 380, 364, 328, 326, 291, 317, 343, 385, 494, 380, 381, 382, 388, 396, 409, 452, 472, 628, 434, 448, 462, 477, 514, 516, 523, 530, 538, 448, 428, 435, 434, 500, 513, 519, 526, 538, 448, 459, 467, 461, 488, 511, 513, 524, 535, 498, 488, 493, 503, 510, 540, 544, 535, 528, 511, 512, 512, 511, 512, 512, 516, 533, 519, 509, 505, 497, 499, 508, 512, 513, 532, 528, 509, 498, 484, 487, 503, 510, 511, 524, 532, 509, 498, 472, 474, 495, 499, 512, 520, 570, 509, 509, 509, 509, 514, 522, 543, 568, 687, 544, 556, 572, 582, 614, 643, 643, 651, 657, 557, 529, 543, 556, 587, 632, 641, 647, 663, 565, 554, 558, 545, 558, 610, 640, 643, 666, 590, 585, 596, 605, 619, 666, 674, 655, 661, 627, 615, 621, 623, 631, 638, 642, 651, 654, 639, 639, 639, 639, 639, 639, 640, 643, 644, 637, 634, 627, 625, 627, 636, 639, 639, 651, 635, 629, 619, 612, 616, 623, 638, 639, 664, 638, 638, 638, 638, 638, 641, 650, 674, 759, 655, 664, 680, 692, 700, 748, 771, 770, 778, 666, 636, 651, 667, 679, 733, 762, 769, 789, 678, 653, 653, 651, 665, 688, 741, 769, 795, 677, 679, 690, 698, 691, 737, 771, 779, 792, 729, 712, 724, 729, 743, 756, 762, 770, 787, 755, 746, 747, 750, 752, 759, 766, 770, 780, 767, 767, 767, 767, 767, 767, 767, 768, 770, 764, 762, 758, 752, 753, 752, 762, 767, 776, 763, 763, 763, 764, 766, 766, 768, 784, 840, 765, 773, 787, 801, 809, 819, 881, 900, 896, 775, 748, 763, 779, 805, 801, 869, 892, 910, 789, 765, 755, 774, 809, 807, 842, 875, 919, 794, 776, 786, 789, 781, 798, 838, 864, 918, 810, 806, 820, 826, 836, 843, 855, 875, 915, 863, 849, 848, 856, 860, 884, 888, 889, 912, 883, 877, 874, 877, 878, 886, 890, 893, 906, 895, 895, 895, 895, 895, 895, 895, 895, 896, 892, 892, 892, 892, 893, 893, 894, 895, 929, 876, 882, 895, 911, 952, 956, 953, 1012, 1019, 884, 944, 953, 979, 1010, 1005, 979, 1020, 1020, 898, 944, 1009, 1010, 1009, 1007, 1010, 1020, 1020, 908, 940, 1006, 1010, 1011, 1010, 1010, 1020, 1020, 905, 927, 987, 1006, 1011, 1014, 1013, 1020, 1020, 953, 962, 986, 1000, 1005, 1013, 1015, 1019, 1021, 995, 1002, 1015, 1014, 1012, 1006, 1016, 1017, 1021, 1010, 1015, 1020, 1020, 1019, 1019, 1018, 1019, 1022, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023] + } + }, { + "name": "A", + "awbGain": [1.02044, 2.52558], + "gain_alpha": { + "gain": [1, 2, 4, 8, 16, 32, 64, 128, 256], + "alpha": [1, 1, 1, 1, 1, 1, 1, 1, 1] + }, + "Table": { + "look_up_table_r": [0, 128, 256, 384, 512, 639, 767, 895, 1023, 0, 110, 238, 384, 512, 639, 767, 895, 1023, 0, 128, 220, 358, 475, 622, 767, 895, 1023, 0, 128, 256, 330, 479, 595, 713, 831, 1023, 0, 128, 256, 384, 440, 599, 716, 833, 951, 0, 128, 256, 384, 512, 550, 720, 837, 953, 0, 128, 256, 384, 512, 639, 660, 841, 957, 0, 112, 256, 384, 512, 639, 750, 770, 962, 0, 128, 256, 384, 512, 639, 767, 875, 880, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 234, 384, 512, 639, 767, 895, 1023, 0, 117, 258, 440, 512, 639, 767, 895, 1023, 0, 118, 249, 440, 555, 689, 823, 895, 1023, 0, 129, 222, 350, 555, 692, 786, 915, 959, 0, 130, 215, 343, 470, 692, 789, 918, 961, 0, 128, 208, 352, 480, 590, 776, 921, 964, 0, 128, 219, 347, 475, 603, 728, 905, 969, 0, 128, 240, 384, 512, 639, 767, 878, 898, 0, 128, 256, 384, 512, 639, 767, 895, 1023, 0, 140, 256, 384, 512, 639, 767, 895, 1023, 0, 128, 256, 371, 469, 590, 767, 895, 1023, 0, 112, 256, 419, 522, 594, 767, 895, 1023, 0, 125, 234, 358, 516, 650, 880, 950, 1023, 0, 126, 230, 354, 482, 645, 883, 914, 969, 0, 128, 237, 371, 498, 625, 880, 917, 972, 0, 128, 256, 336, 480, 608, 718, 904, 976, 0, 128, 256, 384, 512, 639, 767, 895, 916, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 144, 256, 384, 511, 639, 767, 895, 1023, 0, 131, 277, 384, 512, 593, 767, 895, 1023, 0, 128, 256, 384, 503, 619, 717, 895, 1023, 0, 128, 226, 384, 536, 696, 722, 895, 1023, 0, 123, 224, 384, 512, 696, 778, 945, 1006, 0, 128, 229, 358, 482, 610, 773, 948, 979, 0, 128, 256, 386, 471, 599, 726, 947, 983, 0, 128, 256, 384, 512, 639, 767, 895, 934, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 155, 256, 384, 511, 639, 767, 895, 1023, 0, 149, 279, 384, 511, 639, 767, 895, 1023, 0, 128, 266, 399, 512, 639, 721, 895, 1023, 0, 128, 256, 384, 512, 630, 725, 895, 1023, 0, 128, 256, 384, 511, 664, 778, 895, 1023, 0, 120, 224, 351, 489, 614, 772, 938, 987, 0, 128, 256, 382, 513, 605, 733, 939, 990, 0, 128, 256, 384, 512, 639, 767, 895, 952, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 160, 256, 384, 511, 639, 767, 895, 1023, 0, 154, 284, 384, 512, 639, 767, 895, 1023, 0, 152, 274, 418, 511, 639, 767, 895, 1023, 0, 128, 256, 406, 526, 639, 767, 895, 1023, 0, 128, 256, 384, 512, 639, 755, 895, 1023, 0, 128, 256, 384, 482, 639, 803, 951, 1023, 0, 128, 248, 378, 509, 630, 761, 952, 997, 0, 128, 256, 384, 511, 639, 767, 895, 969, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 287, 384, 511, 639, 767, 895, 1023, 0, 128, 275, 412, 512, 640, 767, 895, 1023, 0, 154, 262, 402, 535, 640, 767, 895, 1023, 0, 128, 256, 384, 521, 661, 767, 895, 1023, 0, 128, 256, 384, 512, 639, 767, 874, 1023, 0, 128, 256, 384, 511, 623, 756, 898, 1005, 0, 128, 256, 384, 511, 639, 767, 895, 987, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 256, 416, 511, 639, 767, 895, 1023, 0, 128, 256, 410, 538, 639, 767, 895, 1023, 0, 128, 282, 408, 533, 655, 767, 895, 1023, 0, 128, 256, 384, 511, 642, 779, 895, 1023, 0, 128, 256, 384, 512, 639, 767, 895, 1023, 0, 128, 256, 384, 512, 639, 767, 895, 1005, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 256, 384, 511, 639, 767, 895, 1023, 0, 128, 256, 384, 512, 639, 767, 895, 1023, 0, 128, 256, 384, 512, 639, 767, 895, 1023, 0, 128, 256, 384, 512, 639, 767, 895, 1023, 0, 128, 256, 384, 512, 639, 767, 895, 1023], + "look_up_table_g": [0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 485, 534, 512, 512, 512, 512, 512, 512, 1024, 1024, 969, 1059, 1069, 1104, 1024, 1024, 1024, 1536, 1536, 1536, 1454, 1585, 1592, 1603, 1614, 1536, 2047, 2048, 2048, 2048, 1939, 2112, 2117, 2126, 2137, 2559, 2559, 2559, 2559, 2559, 2423, 2639, 2643, 2651, 3071, 3071, 3071, 3071, 3071, 3071, 2908, 3167, 3169, 3583, 3710, 3583, 3583, 3583, 3583, 3687, 3393, 3696, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 512, 599, 512, 512, 512, 512, 512, 512, 1024, 1068, 982, 1145, 1024, 1024, 1024, 1024, 1024, 1536, 1574, 1835, 1654, 1664, 1688, 1714, 1536, 1536, 2048, 2041, 2320, 2302, 2177, 2203, 2193, 2213, 2126, 2559, 2551, 2887, 2879, 2853, 2714, 2710, 2728, 2638, 3071, 3071, 3453, 3324, 3312, 3405, 3168, 3245, 3155, 3583, 3583, 3874, 3874, 3866, 3851, 3830, 3694, 3679, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 625, 512, 512, 512, 512, 512, 512, 512, 1024, 1024, 1024, 1075, 1199, 1228, 1024, 1024, 1024, 1536, 1599, 1536, 1610, 1462, 1731, 1536, 1536, 1536, 2048, 2057, 2136, 2209, 1964, 1961, 2289, 2226, 2047, 2559, 2566, 2661, 2754, 2737, 2461, 2804, 2705, 2627, 3071, 3071, 3148, 3661, 3669, 3652, 3308, 3222, 3141, 3583, 3583, 3583, 3965, 3835, 3824, 3917, 3680, 3663, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3932, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 721, 512, 512, 512, 512, 512, 512, 512, 1024, 1217, 1079, 1024, 1024, 1208, 1024, 1024, 1024, 1536, 1536, 1536, 1536, 1571, 1617, 1740, 1536, 1536, 2048, 2048, 2165, 2048, 2099, 2168, 2243, 2047, 2048, 2559, 2580, 2688, 2559, 2830, 2678, 2473, 2712, 2639, 3071, 3071, 3177, 3173, 3266, 3248, 2973, 3227, 3128, 3583, 3583, 3583, 3575, 3911, 3902, 3877, 3738, 3647, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3959, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 599, 512, 512, 512, 512, 512, 512, 512, 1024, 1090, 1250, 1095, 1024, 1024, 1024, 1024, 1024, 1536, 1536, 1747, 1574, 1536, 1536, 1720, 1536, 1536, 2048, 2048, 2048, 2048, 2048, 2083, 2222, 2048, 2048, 2559, 2559, 2559, 2559, 2559, 2611, 2486, 2559, 2559, 3071, 3101, 3199, 3200, 3159, 3233, 2988, 3200, 3116, 3583, 3583, 3583, 3590, 3577, 3855, 3837, 3712, 3632, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3986, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 616, 512, 512, 512, 512, 512, 512, 512, 1024, 1104, 1289, 1105, 1105, 1024, 1024, 1024, 1024, 1536, 1615, 1781, 1624, 1536, 1536, 1536, 1536, 1536, 2048, 2048, 2048, 2091, 2086, 2047, 2048, 2047, 2048, 2559, 2559, 2559, 2559, 2559, 2559, 2610, 2559, 2559, 3071, 3071, 3071, 3071, 3189, 3071, 3145, 3192, 3071, 3583, 3583, 3613, 3604, 3593, 3622, 3882, 3701, 3618, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4013, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 512, 512, 512, 512, 512, 512, 512, 512, 1024, 1024, 1442, 1024, 1024, 1024, 1024, 1024, 1024, 1536, 1536, 1926, 1801, 1617, 1616, 1536, 1536, 1536, 2048, 2141, 2435, 2293, 2274, 2118, 2048, 2048, 2048, 2559, 2559, 2559, 2559, 2770, 2614, 2559, 2559, 2559, 3071, 3071, 3071, 3071, 3071, 3071, 3071, 3159, 3071, 3583, 3583, 3583, 3583, 3583, 3647, 3627, 3541, 3606, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4041, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 512, 512, 512, 512, 512, 512, 512, 512, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1536, 1536, 1536, 1640, 1536, 1536, 1536, 1536, 1536, 2048, 2048, 2048, 2128, 2135, 2047, 2047, 2048, 2048, 2559, 2559, 2653, 2639, 2626, 2769, 2559, 2559, 2559, 3071, 3071, 3071, 3071, 3071, 3265, 3184, 3071, 3071, 3583, 3583, 3583, 3583, 3583, 3583, 3583, 3583, 3583, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4068, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 512, 512, 512, 512, 512, 512, 512, 512, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2047, 2048, 2559, 2559, 2559, 2559, 2559, 2559, 2559, 2559, 2559, 3071, 3071, 3071, 3071, 3071, 3071, 3071, 3071, 3071, 3583, 3583, 3583, 3583, 3583, 3583, 3583, 3583, 3583, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095], + "look_up_table_b": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 0, 0, 0, 0, 0, 0, 0, 14, 26, 36, 17, 0, 0, 0, 0, 0, 0, 20, 33, 44, 54, 64, 0, 0, 0, 0, 0, 27, 40, 51, 62, 72, 0, 0, 0, 0, 0, 34, 47, 59, 70, 0, 0, 0, 0, 0, 0, 41, 54, 66, 0, 0, 0, 0, 0, 0, 0, 48, 61, 0, 0, 0, 0, 0, 0, 0, 0, 54, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 149, 128, 128, 128, 128, 128, 128, 128, 139, 125, 72, 128, 128, 128, 128, 128, 128, 149, 53, 71, 85, 78, 73, 128, 128, 128, 151, 60, 64, 84, 75, 109, 108, 192, 128, 156, 46, 48, 54, 76, 106, 105, 190, 128, 128, 32, 65, 68, 44, 104, 102, 186, 128, 128, 55, 55, 57, 61, 66, 100, 182, 128, 128, 96, 128, 128, 128, 128, 102, 175, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 244, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 269, 298, 306, 256, 256, 256, 256, 274, 256, 220, 245, 301, 256, 256, 256, 256, 277, 278, 215, 251, 245, 143, 200, 256, 256, 281, 282, 207, 211, 250, 140, 237, 310, 256, 256, 299, 108, 106, 111, 143, 234, 307, 256, 256, 256, 160, 193, 196, 172, 232, 303, 256, 256, 256, 256, 256, 256, 256, 256, 297, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 368, 384, 384, 384, 384, 384, 384, 384, 384, 381, 370, 384, 384, 431, 384, 384, 384, 384, 384, 384, 384, 393, 405, 433, 384, 384, 384, 384, 403, 384, 359, 327, 429, 384, 384, 384, 408, 406, 384, 316, 327, 373, 334, 401, 384, 384, 422, 410, 335, 339, 378, 331, 428, 384, 384, 384, 412, 302, 304, 310, 331, 424, 384, 384, 384, 384, 384, 384, 384, 384, 418, 512, 512, 512, 512, 511, 511, 511, 511, 511, 511, 490, 512, 512, 511, 511, 511, 511, 511, 511, 490, 488, 494, 511, 511, 511, 511, 511, 512, 512, 502, 502, 511, 512, 558, 512, 511, 512, 512, 511, 511, 512, 521, 554, 512, 512, 512, 512, 512, 512, 511, 487, 501, 511, 512, 512, 541, 549, 534, 534, 471, 507, 468, 548, 512, 512, 512, 537, 535, 443, 448, 468, 544, 512, 512, 512, 512, 512, 512, 512, 512, 539, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 613, 639, 639, 639, 639, 639, 639, 639, 639, 613, 611, 619, 619, 639, 639, 639, 639, 639, 615, 621, 617, 639, 639, 639, 639, 639, 639, 639, 639, 617, 630, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 653, 639, 639, 639, 639, 639, 639, 659, 639, 604, 583, 639, 639, 639, 669, 664, 660, 661, 565, 583, 665, 639, 639, 639, 639, 639, 639, 639, 639, 660, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 736, 767, 767, 767, 767, 767, 767, 767, 767, 748, 739, 747, 747, 767, 767, 767, 767, 741, 761, 749, 744, 750, 767, 767, 767, 767, 767, 767, 767, 757, 754, 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, 789, 767, 767, 767, 767, 767, 767, 786, 779, 765, 785, 767, 767, 767, 767, 767, 767, 767, 767, 781, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 869, 895, 895, 895, 895, 895, 895, 895, 895, 869, 873, 895, 895, 895, 895, 895, 895, 869, 871, 874, 879, 895, 895, 895, 895, 895, 895, 895, 895, 892, 883, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 902, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023] + } + }], + "lutAll_len": 3 + } + }, + "adegamma_calib": { + "DegammaTuningPara": { + "degamma_en": 0, + "X_axis": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "curve_R": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "curve_G": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "curve_B": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + } + }, + "agic_calib_v21": { + "GicTuningPara": { + "enable": 1, + "gr_ration": 0, + "GicData": { + "ISO": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "ISO_len": 13, + "min_busy_thre": [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], + "min_busy_thre_len": 13, + "min_grad_thr1": [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16], + "min_grad_thr1_len": 13, + "min_grad_thr2": [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + "min_grad_thr2_len": 13, + "k_grad1": [64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64], + "k_grad1_len": 13, + "k_grad2": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + "k_grad2_len": 13, + "gb_thre": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "gb_thre_len": 13, + "maxCorV": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], + "maxCorV_len": 13, + "maxCorVboth": [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20], + "maxCorVboth_len": 13, + "dark_thre": [120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120], + "dark_thre_len": 13, + "dark_threHi": [240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240], + "dark_threHi_len": 13, + "k_grad1_dark": [64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64], + "k_grad1_dark_len": 13, + "k_grad2_dark": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + "k_grad2_dark_len": 13, + "min_grad_thr_dark1": [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16], + "min_grad_thr_dark1_len": 13, + "min_grad_thr_dark2": [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + "min_grad_thr_dark2_len": 13, + "noiseCurve_0": [0.6979, 0.9812, 1.3629, 1.8796, 2.534, 3.5836, 5.068, 7.1672, 5.2349, 5.9984, 8.483, 11.9968, 16.9661], + "noiseCurve_0_len": 13, + "noiseCurve_1": [1.0115, 1.511, 3.0947, 5.6983, 12.1182, 17.1377, 24.2364, 34.2755, 159.113, 254.409, 359.789, 508.819, 719.578], + "noiseCurve_1_len": 13, + "NoiseScale": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "NoiseScale_len": 13, + "NoiseBase": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "NoiseBase_len": 13, + "globalStrength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "globalStrength_len": 13, + "diff_clip": [32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767], + "diff_clip_len": 13 + } + } + }, + "debayer_v2": { + "param": { + "debayer_en": 1, + "lowfreq_filter1": [-2, 2, -4, 4], + "highfreq_filter2": [-1, 2, -2, 4], + "c_alpha_gaus_coe": [64, 32, 16], + "c_guid_gaus_coe": [64, 32, 16], + "c_ce_gaus_coe": [64, 32, 16], + "g_interp": { + "iso": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "debayer_clip_en": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "debayer_gain_offset": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + "debayer_max_ratio": [4, 4, 4, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1] + }, + "g_drctwgt": { + "iso": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "debayer_hf_offset": [4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095], + "debayer_thed0": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3], + "debayer_thed1": [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6], + "debayer_dist_scale": [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + "debayer_select_thed": [13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13] + }, + "g_filter": { + "iso": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "debayer_gfilter_en": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "debayer_gfilter_offset": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, + "c_filter": { + "iso": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "debayer_cfilter_en": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "debayer_loggd_offset": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "debayer_cfilter_str": [0.0313, 0.0313, 0.0313, 0.0313, 0.0313, 0.0313, 0.0313, 0.0313, 0.0313, 0.0313, 0.0313, 0.0313, 0.0313], + "debayer_wet_clip": [7.25, 7.25, 7.25, 7.25, 7.25, 7.25, 7.25, 7.25, 7.25, 7.25, 7.25, 7.25, 7.25], + "debayer_wet_ghost": [0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03], + "debayer_wgtslope": [0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7], + "debayer_bf_sgm": [0.0266, 0.0266, 0.0266, 0.0266, 0.0266, 0.0266, 0.0266, 0.0266, 0.0266, 0.0266, 0.0266, 0.0266, 0.0266], + "debayer_bf_clip": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "debayer_bf_curwgt": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "debayer_loghf_offset": [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], + "debayer_alpha_offset": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "debayer_alpha_scale": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "debayer_edge_offset": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "debayer_edge_scale": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + } + } + }, + "amerge_calib_v12": { + "MergeTuningPara": { + "BaseFrm": "BASEFRAME_LONG", + "CtrlDataType": "CTRLDATATYPE_ENVLV", + "ByPassThr": 0, + "LongFrmModeData": { + "EnableEachChn": 0, + "OECurve": { + "CtrlData": [0, 0.005, 0.01, 0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1], + "Smooth": [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4], + "Offset": [210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210] + }, + "MDCurve": { + "MoveCoef": [0, 0.005, 0.01, 0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1], + "LM_smooth": [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4], + "LM_offset": [0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38], + "MS_smooth": [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4], + "MS_offset": [0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38] + }, + "EachChnCurve": { + "CtrlData": [0, 0.005, 0.01, 0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1], + "Smooth": [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4], + "Offset": [0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38, 0.38] + }, + "OECurve_damp": 0.3, + "MDCurveLM_damp": 0.3, + "MDCurveMS_damp": 0.3 + }, + "ShortFrmModeData": { + "OECurve": { + "CtrlData": [0, 0.005, 0.01, 0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1], + "Smooth": [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4], + "Offset": [210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210] + }, + "MDCurve": { + "MoveCoef": [0, 0.005, 0.01, 0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1], + "Coef": [0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05], + "ms_thd0": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "lm_thd0": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "OECurve_damp": 0, + "MDCurve_damp": 0 + } + } + }, + "adrc_calib_v12": { + "DrcTuningPara": { + "Enable": 1, + "CtrlDataType": "CTRLDATATYPE_ISO", + "DrcGain": { + "CtrlData": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "DrcGain": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "Alpha": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "Clip": [64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64] + }, + "HiLight": { + "HiLightData": { + "CtrlData": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "Strength": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "gas_t": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "gas_l0": 24, + "gas_l1": 10, + "gas_l2": 10, + "gas_l3": 5 + }, + "LocalSetting": { + "LocalData": { + "CtrlData": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "LocalWeit": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "LocalAutoEnable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "LocalAutoWeit": [0.037477, 0.037477, 0.037477, 0.037477, 0.037477, 0.037477, 0.037477, 0.037477, 0.037477, 0.037477, 0.037477, 0.037477, 0.037477], + "GlobalContrast": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "LoLitContrast": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "MotionData": { + "MotionCoef": [0, 0.005, 0.01, 0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1], + "MotionStr": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "curPixWeit": 0.653, + "preFrameWeit": 0.719, + "Range_force_sgm": 0, + "Range_sgm_cur": 0.2, + "Range_sgm_pre": 0.2, + "Space_sgm_cur": 2944, + "Space_sgm_pre": 4095 + }, + "CompressSetting": { + "Mode": "COMPRESS_AUTO", + "Manual_curve": [0, 558, 1087, 1588, 2063, 2515, 2944, 3353, 3744, 4473, 5139, 5751, 6316, 6838, 7322, 7772, 8192] + }, + "Scale_y": [0, 2, 20, 76, 193, 381, 631, 772, 919, 1066, 1211, 1479, 1700, 1863, 1968, 2024, 2048], + "ByPassThr": 0, + "Edge_Weit": 0.0627451, + "OutPutLongFrame": 0, + "IIR_frame": 2, + "damp": 0.9 + } + }, + "agamma_calib_v11": { + "GammaTuningPara": { + "Gamma_en": 1, + "Gamma_out_offset": 0, + "Gamma_curve": [0, 12, 24, 36, 47, 58, 70, 80, 91, 112, 132, 152, 171, 207, 241, 274, 305, 364, 418, 468, 515, 601, 679, 750, 815, 933, 1038, 1132, 1217, 1370, 1504, 1623, 1731, 1922, 2088, 2236, 2369, 2603, 2806, 2986, 3149, 3297, 3434, 3561, 3680, 3792, 3898, 3999, 4095] + } + }, + "adehaze_calib_v12": { + "DehazeTuningPara": { + "Enable": 1, + "CtrlDataType": "CTRLDATATYPE_ISO", + "cfg_alpha": 0, + "ByPassThr": 0, + "dehaze_setting": { + "en": 0, + "air_lc_en": 1, + "stab_fnum": 8, + "sigma": 255, + "wt_sigma": 8, + "air_sigma": 120, + "tmax_sigma": 0.01, + "pre_wet": 8, + "DehazeData": { + "CtrlData": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "dc_min_th": [64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64], + "dc_max_th": [192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192], + "yhist_th": [249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249], + "yblk_th": [0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002], + "dark_th": [250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250], + "bright_min": [180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180], + "bright_max": [240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240], + "wt_max": [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9], + "air_min": [200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200], + "air_max": [250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250], + "tmax_base": [125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125], + "tmax_off": [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], + "tmax_max": [0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8], + "cfg_wt": [0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8], + "cfg_air": [210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210], + "cfg_tmax": [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2], + "dc_weitcur": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "bf_weight": [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5], + "range_sigma": [0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14], + "space_sigma_pre": [0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14], + "space_sigma_cur": [0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14] + } + }, + "enhance_setting": { + "en": 1, + "color_deviate_en": 1, + "enh_luma_en": 0, + "EnhanceData": [{ + "CtrlData": 50, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 100, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 200, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 400, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 800, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 1600, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 3200, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 6400, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 12800, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 25600, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 51200, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 102400, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }, { + "CtrlData": 204800, + "enhance_curve": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "enh_luma": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "enhance_value": 1, + "enhance_chroma": 1 + }] + }, + "hist_setting": { + "en": 0, + "hist_para_en": 1, + "hist_wr": { + "mode": "HIST_WR_MANUAL", + "manual_curve": [{ + "CtrlData": 50, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 100, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 200, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 400, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 800, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 1600, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 3200, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 6400, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 12800, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 25600, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 51200, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 102400, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }, { + "CtrlData": 204800, + "curve_x": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023], + "curve_y": [0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1023] + }], + "semiauto_curve": { + "CtrlData": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "clim0": [2, 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2], + "clim1": [2, 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2], + "dark_th": [64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64] + } + }, + "HistData": { + "CtrlData": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "hist_gratio": [2, 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2], + "hist_th_off": [64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64], + "hist_k": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + "hist_min": [0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015], + "hist_scale": [0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09], + "cfg_gratio": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + } + } + } + }, + "adpcc_calib": { + "DpccTuningPara": { + "Enable": 1, + "Fast_Mode": { + "Fast_mode_en": 1, + "Single_enable": 1, + "Double_enable": 1, + "Triple_enable": 0, + "Fast_Data": { + "ISO": [50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800], + "ISO_len": 13, + "Single_level": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "Single_level_len": 13, + "Double_level": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "Double_level_len": 13, + "Triple_level": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "Triple_level_len": 13 + } + }, + "Expert_Mode": { + "stage1_Enable": 1, + "grayscale_mode": 0, + "dpcc_out_sel": 1, + "stage1_g_3x3": 0, + "stage1_rb_3x3": 0, + "stage1_inc_rb_center": 1, + "stage1_inc_g_center": 1, + "rk_out_sel": 1, + "SetEnable": { + "ISO": [50, 100, 200, 400, 800, 1500, 1507, 1510, 3200, 6400, 12800, 102400, 204800], + "fix_set": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "set1": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "set2": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "set3": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "set1": { + "RK": { + "RK_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_sw_mindis": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "g_sw_mindis": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "sw_dis_scale_min": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "sw_dis_scale_max": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "LC": { + "LC_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_line_thr": [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + "g_line_thr": [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + "rb_line_mad_fac": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + "g_line_mad_fac": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] + }, + "PG": { + "PG_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_pg_fac": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + "g_pg_fac": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] + }, + "RND": { + "RND_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_rnd_thr": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], + "g_rnd_thr": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], + "rb_rnd_offs": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3], + "g_rnd_offs": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] + }, + "RG": { + "RG_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_rg_fac": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "g_rg_fac": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32] + }, + "RO": { + "RO_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_ro_lim": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + "g_ro_lim": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + } + }, + "set2": { + "RK": { + "RK_enable": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "rb_sw_mindis": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "g_sw_mindis": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "sw_dis_scale_min": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "sw_dis_scale_max": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "LC": { + "LC_enable": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "rb_line_thr": [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16], + "g_line_thr": [24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24], + "rb_line_mad_fac": [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16], + "g_line_mad_fac": [12, 12, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, + "PG": { + "PG_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_pg_fac": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + "g_pg_fac": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] + }, + "RND": { + "RND_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_rnd_thr": [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + "g_rnd_thr": [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + "rb_rnd_offs": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "g_rnd_offs": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "RG": { + "RG_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_rg_fac": [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + "g_rg_fac": [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8] + }, + "RO": { + "RO_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_ro_lim": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "g_ro_lim": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + } + }, + "set3": { + "RK": { + "RK_enable": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "rb_sw_mindis": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "g_sw_mindis": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "sw_dis_scale_min": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "sw_dis_scale_max": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "LC": { + "LC_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_line_thr": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "g_line_thr": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "rb_line_mad_fac": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + "g_line_mad_fac": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] + }, + "PG": { + "PG_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_pg_fac": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + "g_pg_fac": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] + }, + "RND": { + "RND_enable": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "rb_rnd_thr": [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + "g_rnd_thr": [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6], + "rb_rnd_offs": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3], + "g_rnd_offs": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] + }, + "RG": { + "RG_enable": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "rb_rg_fac": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + "g_rg_fac": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] + }, + "RO": { + "RO_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "rb_ro_lim": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + "g_ro_lim": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + } + } + }, + "Dpcc_pdaf": { + "en": 0, + "point_en": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "offsetx": 0, + "offsety": 0, + "wrapx": 0, + "wrapy": 0, + "wrapx_num": 0, + "wrapy_num": 0, + "point_x": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "point_y": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "forward_med": 0 + }, + "Sensor_dpcc": { + "sensor_dpcc_auto_en": 0, + "max_level": 20, + "SensorDpcc_Data": { + "ISO": [50, 100, 200, 400, 800, 1500, 1507, 1510, 3200, 6400, 12800, 102400, 204800], + "ISO_len": 13, + "level_single": [19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19], + "level_single_len": 13, + "level_multiple": [19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19], + "level_multiple_len": 13 + } + } + } + }, + "aldch": { + "param": { + "ldch_en": 0, + "meshfile": "LDCH_mesh_2688_1520_os04a10_4IR", + "correct_level": 254, + "correct_level_max": 254, + "light_center": [1374.76, 812.909], + "coefficient": [-1861.96, 0.000550519, -5.76694e-007, 2.26542e-010] + } + }, + "cpsl": { + "param": { + "enable": 0, + "mode": "RK_AIQ_OP_MODE_AUTO", + "force_gray": 1, + "light_src": "LED", + "auto_adjust_sens": 50, + "auto_on2off_th": 3000, + "auto_off2on_th": 100, + "auto_sw_interval": 0, + "manual_on": 0, + "manual_strength": 100 + } + }, + "cproc": { + "param": { + "enable": 1, + "brightness": 128, + "contrast": 128, + "saturation": 128, + "hue": 128 + } + }, + "ie": { + "param": { + "enable": 0, + "mode": 0 + } + }, + "colorAsGrey": { + "param": { + "enable": 0, + "skip_frame": 10 + } + }, + "lsc_v2": { + "common": { + "enable": 1, + "resolutionAll": [{ + "name": "2592x1944", + "lsc_sect_size_x": [162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162], + "lsc_sect_size_y": [121, 122, 121, 122, 121, 122, 121, 122, 121, 122, 121, 122, 121, 122, 121, 122] + }], + "resolutionAll_len": 1 + }, + "alscCoef": { + "damp_enable": 1, + "illAll": [{ + "usedForCase": 0, + "name": "A", + "wbGain": [1.3363, 2.6183], + "tableUsed": [{ + "name": "A_70" + }, { + "name": "A_100" + }], + "tableUsed_len": 2, + "gains": [1, 4, 8, 16], + "gains_len": 4, + "vig": [100, 100, 90, 70], + "vig_len": 4 + }, { + "usedForCase": 0, + "name": "CWF", + "wbGain": [1.8164, 2.3069], + "tableUsed": [{ + "name": "CWF_70" + }, { + "name": "CWF_100" + }], + "tableUsed_len": 2, + "gains": [1, 4, 8, 16], + "gains_len": 4, + "vig": [100, 100, 90, 70], + "vig_len": 4 + }, { + "usedForCase": 0, + "name": "D50", + "wbGain": [1.8556, 1.6092], + "tableUsed": [{ + "name": "D50_70" + }, { + "name": "D50_100" + }], + "tableUsed_len": 2, + "gains": [1, 4, 8, 16], + "gains_len": 4, + "vig": [100, 100, 90, 70], + "vig_len": 4 + }, { + "usedForCase": 0, + "name": "D65", + "wbGain": [2.1625, 1.4074], + "tableUsed": [{ + "name": "D65_70" + }, { + "name": "D65_100" + }], + "tableUsed_len": 2, + "gains": [1, 4, 8, 16], + "gains_len": 4, + "vig": [100, 100, 90, 70], + "vig_len": 4 + }, { + "usedForCase": 0, + "name": "D75", + "wbGain": [2.143, 1.2437], + "tableUsed": [{ + "name": "D75_70" + }, { + "name": "D75_100" + }], + "tableUsed_len": 2, + "gains": [1, 4, 8, 16], + "gains_len": 4, + "vig": [100, 100, 90, 70], + "vig_len": 4 + }, { + "usedForCase": 0, + "name": "HZ", + "wbGain": [1.1096, 3.2636], + "tableUsed": [{ + "name": "HZ_70" + }, { + "name": "HZ_100" + }], + "tableUsed_len": 2, + "gains": [1, 4, 8, 16], + "gains_len": 4, + "vig": [100, 100, 90, 70], + "vig_len": 4 + }, { + "usedForCase": 0, + "name": "TL84", + "wbGain": [1.6118, 2.2537], + "tableUsed": [{ + "name": "TL84_70" + }, { + "name": "TL84_100" + }], + "tableUsed_len": 2, + "gains": [1, 4, 8, 16], + "gains_len": 4, + "vig": [100, 100, 90, 70], + "vig_len": 4 + }], + "illAll_len": 7 + }, + "tbl": { + "tableAll": [{ + "name": "2592x1944_A_70", + "resolution": "2592x1944", + "illumination": "A", + "vignetting": 70, + "lsc_samples_red": { + "uCoeff": [2663, 2229, 2015, 1848, 1729, 1628, 1571, 1513, 1511, 1547, 1608, 1667, 1796, 1935, 2125, 2463, 3043, 2445, 2065, 1861, 1727, 1604, 1492, 1433, 1413, 1405, 1420, 1471, 1547, 1652, 1806, 1987, 2220, 2650, 2230, 1952, 1774, 1605, 1494, 1388, 1335, 1304, 1303, 1314, 1368, 1441, 1543, 1666, 1861, 2077, 2408, 2085, 1856, 1657, 1510, 1401, 1316, 1253, 1212, 1208, 1212, 1279, 1360, 1440, 1586, 1731, 1944, 2262, 1982, 1774, 1593, 1454, 1328, 1237, 1171, 1140, 1126, 1153, 1196, 1267, 1366, 1506, 1673, 1867, 2168, 1917, 1702, 1526, 1387, 1271, 1188, 1109, 1083, 1067, 1083, 1142, 1216, 1307, 1444, 1624, 1812, 2026, 1869, 1650, 1491, 1347, 1223, 1139, 1088, 1039, 1045, 1055, 1101, 1165, 1264, 1405, 1553, 1757, 1995, 1850, 1629, 1469, 1303, 1194, 1111, 1045, 1034, 1036, 1043, 1067, 1138, 1247, 1383, 1530, 1728, 1974, 1848, 1645, 1450, 1311, 1197, 1100, 1039, 1024, 1028, 1037, 1055, 1128, 1239, 1350, 1510, 1713, 1933, 1816, 1615, 1449, 1311, 1187, 1095, 1045, 1036, 1034, 1043, 1058, 1130, 1235, 1373, 1523, 1713, 1942, 1839, 1635, 1461, 1324, 1224, 1117, 1053, 1037, 1037, 1047, 1077, 1156, 1253, 1391, 1548, 1741, 2006, 1883, 1655, 1499, 1354, 1245, 1152, 1089, 1068, 1055, 1065, 1126, 1190, 1291, 1410, 1588, 1782, 2039, 1919, 1748, 1541, 1406, 1302, 1214, 1150, 1098, 1098, 1121, 1162, 1246, 1328, 1471, 1623, 1830, 2108, 2025, 1785, 1615, 1467, 1368, 1272, 1209, 1175, 1166, 1182, 1237, 1298, 1409, 1540, 1708, 1918, 2206, 2120, 1888, 1694, 1548, 1432, 1360, 1285, 1257, 1246, 1271, 1305, 1386, 1475, 1624, 1783, 2017, 2338, 2283, 1992, 1780, 1652, 1536, 1448, 1384, 1344, 1346, 1356, 1410, 1476, 1582, 1725, 1903, 2122, 2513, 2497, 2096, 1924, 1743, 1614, 1529, 1481, 1446, 1447, 1452, 1509, 1584, 1686, 1840, 2029, 2311, 2768] + }, + "lsc_samples_greenR": { + "uCoeff": [2530, 2132, 1922, 1783, 1677, 1579, 1528, 1504, 1481, 1500, 1540, 1607, 1714, 1841, 2006, 2320, 2809, 2282, 1974, 1804, 1662, 1560, 1477, 1408, 1391, 1379, 1395, 1436, 1503, 1604, 1732, 1884, 2123, 2485, 2094, 1882, 1714, 1567, 1466, 1382, 1320, 1288, 1289, 1301, 1351, 1402, 1493, 1632, 1787, 1996, 2252, 1992, 1792, 1616, 1491, 1386, 1303, 1239, 1194, 1197, 1214, 1263, 1327, 1425, 1536, 1687, 1887, 2164, 1922, 1707, 1555, 1411, 1320, 1222, 1179, 1132, 1130, 1143, 1182, 1254, 1345, 1475, 1614, 1798, 2028, 1837, 1653, 1495, 1366, 1263, 1176, 1113, 1076, 1070, 1084, 1134, 1205, 1301, 1411, 1572, 1737, 1943, 1798, 1606, 1454, 1322, 1222, 1138, 1076, 1040, 1039, 1040, 1091, 1165, 1254, 1377, 1522, 1696, 1919, 1796, 1577, 1424, 1307, 1190, 1102, 1040, 1039, 1043, 1036, 1061, 1130, 1231, 1353, 1488, 1668, 1885, 1771, 1597, 1419, 1287, 1187, 1093, 1037, 1028, 1024, 1037, 1054, 1125, 1219, 1337, 1474, 1659, 1878, 1767, 1575, 1418, 1289, 1192, 1092, 1043, 1037, 1033, 1045, 1051, 1125, 1214, 1341, 1492, 1658, 1842, 1782, 1588, 1432, 1310, 1204, 1121, 1060, 1037, 1043, 1052, 1073, 1143, 1240, 1356, 1503, 1685, 1877, 1815, 1619, 1464, 1349, 1236, 1148, 1090, 1058, 1052, 1061, 1121, 1176, 1274, 1379, 1539, 1725, 1969, 1861, 1686, 1521, 1386, 1278, 1195, 1134, 1098, 1098, 1116, 1148, 1228, 1319, 1435, 1583, 1758, 2021, 1917, 1735, 1575, 1445, 1342, 1261, 1201, 1169, 1151, 1174, 1213, 1282, 1376, 1500, 1631, 1834, 2098, 2028, 1814, 1638, 1520, 1409, 1330, 1271, 1242, 1237, 1246, 1297, 1357, 1446, 1566, 1723, 1909, 2192, 2147, 1920, 1730, 1600, 1490, 1418, 1365, 1322, 1329, 1339, 1374, 1459, 1534, 1677, 1808, 2043, 2360, 2325, 2043, 1829, 1710, 1610, 1509, 1454, 1425, 1409, 1438, 1468, 1535, 1643, 1753, 1949, 2181, 2609] + }, + "lsc_samples_greenB": { + "uCoeff": [2486, 2130, 1920, 1762, 1655, 1580, 1527, 1477, 1469, 1488, 1534, 1604, 1706, 1868, 2019, 2304, 2817, 2249, 1986, 1813, 1662, 1553, 1475, 1414, 1375, 1364, 1386, 1433, 1499, 1586, 1720, 1875, 2112, 2504, 2069, 1872, 1684, 1553, 1455, 1364, 1314, 1293, 1275, 1293, 1333, 1403, 1505, 1615, 1770, 1983, 2269, 1986, 1757, 1594, 1471, 1371, 1287, 1225, 1203, 1190, 1207, 1244, 1320, 1413, 1528, 1679, 1862, 2139, 1896, 1700, 1534, 1408, 1304, 1215, 1160, 1127, 1117, 1134, 1184, 1254, 1342, 1464, 1608, 1792, 2015, 1849, 1640, 1492, 1359, 1246, 1160, 1107, 1070, 1070, 1074, 1124, 1198, 1301, 1408, 1554, 1729, 1984, 1793, 1589, 1455, 1306, 1210, 1130, 1061, 1030, 1030, 1042, 1084, 1157, 1257, 1364, 1502, 1684, 1928, 1771, 1582, 1413, 1292, 1193, 1093, 1045, 1028, 1034, 1030, 1057, 1131, 1218, 1348, 1489, 1668, 1882, 1750, 1579, 1414, 1282, 1170, 1085, 1034, 1024, 1027, 1028, 1050, 1115, 1212, 1332, 1478, 1651, 1864, 1771, 1565, 1416, 1285, 1174, 1093, 1030, 1030, 1034, 1036, 1058, 1115, 1214, 1336, 1475, 1645, 1892, 1761, 1585, 1426, 1295, 1193, 1110, 1045, 1028, 1028, 1042, 1070, 1141, 1233, 1349, 1502, 1669, 1902, 1780, 1618, 1462, 1335, 1226, 1138, 1080, 1045, 1044, 1058, 1113, 1175, 1261, 1386, 1525, 1717, 1956, 1847, 1664, 1500, 1377, 1279, 1188, 1126, 1092, 1083, 1099, 1142, 1215, 1313, 1438, 1580, 1766, 1976, 1921, 1695, 1554, 1439, 1327, 1245, 1192, 1150, 1147, 1171, 1213, 1272, 1371, 1482, 1630, 1824, 2087, 2009, 1788, 1620, 1506, 1400, 1324, 1260, 1229, 1221, 1246, 1280, 1347, 1446, 1567, 1716, 1918, 2167, 2115, 1895, 1718, 1589, 1478, 1392, 1345, 1317, 1306, 1329, 1372, 1426, 1534, 1673, 1818, 2037, 2327, 2301, 2018, 1836, 1685, 1574, 1485, 1452, 1404, 1406, 1420, 1470, 1531, 1626, 1775, 1941, 2163, 2575] + }, + "lsc_samples_blue": { + "uCoeff": [2490, 2111, 1932, 1788, 1667, 1586, 1534, 1474, 1494, 1499, 1543, 1625, 1720, 1843, 2035, 2234, 2736, 2296, 1953, 1774, 1633, 1534, 1466, 1399, 1370, 1379, 1376, 1445, 1490, 1588, 1717, 1890, 2095, 2439, 2085, 1871, 1688, 1560, 1436, 1362, 1317, 1283, 1260, 1302, 1343, 1389, 1473, 1603, 1749, 1949, 2157, 1997, 1782, 1615, 1462, 1369, 1301, 1224, 1194, 1184, 1199, 1246, 1318, 1395, 1509, 1658, 1850, 2104, 1946, 1681, 1534, 1404, 1285, 1202, 1155, 1110, 1110, 1133, 1175, 1234, 1342, 1455, 1564, 1742, 1997, 1832, 1643, 1509, 1370, 1243, 1160, 1107, 1072, 1064, 1081, 1129, 1184, 1276, 1402, 1539, 1700, 1889, 1794, 1603, 1449, 1308, 1207, 1133, 1064, 1032, 1032, 1040, 1068, 1137, 1228, 1338, 1496, 1655, 1846, 1789, 1576, 1431, 1298, 1183, 1107, 1040, 1024, 1032, 1028, 1051, 1129, 1208, 1313, 1465, 1639, 1829, 1780, 1577, 1416, 1274, 1174, 1093, 1032, 1028, 1024, 1032, 1048, 1101, 1198, 1315, 1434, 1622, 1833, 1763, 1559, 1400, 1299, 1174, 1093, 1032, 1040, 1032, 1024, 1043, 1110, 1197, 1308, 1459, 1611, 1788, 1760, 1572, 1435, 1302, 1182, 1110, 1060, 1044, 1028, 1044, 1064, 1128, 1229, 1332, 1470, 1635, 1821, 1814, 1603, 1444, 1323, 1222, 1137, 1084, 1048, 1044, 1051, 1101, 1159, 1260, 1360, 1506, 1656, 1862, 1819, 1674, 1492, 1363, 1268, 1182, 1128, 1093, 1084, 1101, 1151, 1207, 1310, 1394, 1538, 1697, 1921, 1909, 1680, 1531, 1417, 1330, 1242, 1177, 1155, 1136, 1159, 1192, 1258, 1369, 1461, 1611, 1787, 2001, 2038, 1772, 1629, 1483, 1387, 1298, 1257, 1221, 1206, 1226, 1269, 1336, 1421, 1530, 1684, 1866, 2110, 2121, 1873, 1687, 1589, 1463, 1388, 1334, 1312, 1295, 1305, 1359, 1430, 1500, 1643, 1761, 2014, 2285, 2354, 1981, 1757, 1631, 1516, 1419, 1370, 1378, 1330, 1362, 1421, 1455, 1557, 1688, 1868, 2068, 2368] + } + }, { + "name": "2592x1944_A_100", + "resolution": "2592x1944", + "illumination": "A", + "vignetting": 100, + "lsc_samples_red": { + "uCoeff": [3334, 2621, 2275, 2024, 1854, 1721, 1644, 1574, 1569, 1610, 1684, 1765, 1932, 2134, 2414, 2927, 3873, 2943, 2363, 2054, 1854, 1689, 1551, 1477, 1449, 1438, 1457, 1517, 1610, 1743, 1946, 2202, 2560, 3236, 2608, 2185, 1918, 1694, 1551, 1423, 1360, 1324, 1321, 1334, 1394, 1481, 1606, 1765, 2024, 2342, 2851, 2393, 2039, 1765, 1574, 1438, 1337, 1266, 1221, 1216, 1221, 1293, 1384, 1481, 1659, 1854, 2151, 2621, 2238, 1925, 1679, 1501, 1353, 1249, 1177, 1143, 1129, 1157, 1203, 1281, 1394, 1560, 1771, 2039, 2468, 2142, 1829, 1596, 1423, 1287, 1195, 1111, 1084, 1068, 1084, 1145, 1224, 1327, 1485, 1705, 1959, 2284, 2070, 1759, 1551, 1374, 1235, 1143, 1089, 1039, 1045, 1055, 1102, 1170, 1278, 1438, 1620, 1886, 2229, 2039, 1732, 1521, 1327, 1203, 1113, 1045, 1034, 1036, 1043, 1068, 1141, 1258, 1412, 1592, 1848, 2193, 2032, 1748, 1501, 1334, 1205, 1102, 1039, 1024, 1028, 1037, 1055, 1131, 1249, 1377, 1569, 1829, 2142, 2002, 1715, 1501, 1334, 1195, 1097, 1045, 1036, 1034, 1043, 1059, 1133, 1246, 1401, 1583, 1829, 2159, 2032, 1743, 1517, 1350, 1235, 1120, 1053, 1037, 1037, 1047, 1078, 1160, 1266, 1423, 1615, 1867, 2238, 2093, 1776, 1565, 1387, 1260, 1157, 1091, 1068, 1055, 1066, 1129, 1197, 1308, 1449, 1664, 1925, 2294, 2159, 1892, 1620, 1449, 1324, 1224, 1155, 1100, 1100, 1124, 1167, 1258, 1353, 1521, 1715, 1995, 2393, 2313, 1952, 1715, 1526, 1401, 1290, 1219, 1182, 1172, 1190, 1249, 1318, 1446, 1606, 1823, 2117, 2548, 2468, 2101, 1823, 1629, 1481, 1391, 1305, 1272, 1260, 1287, 1327, 1420, 1530, 1715, 1932, 2265, 2752, 2724, 2265, 1952, 1765, 1610, 1497, 1420, 1374, 1374, 1387, 1449, 1530, 1664, 1854, 2101, 2436, 3040, 3091, 2446, 2159, 1899, 1721, 1606, 1543, 1497, 1497, 1505, 1574, 1669, 1805, 2017, 2294, 2724, 3482] + }, + "lsc_samples_greenR": { + "uCoeff": [3168, 2508, 2170, 1953, 1798, 1669, 1599, 1564, 1538, 1561, 1613, 1701, 1844, 2030, 2279, 2757, 3575, 2747, 2258, 1991, 1784, 1643, 1535, 1451, 1426, 1412, 1431, 1481, 1564, 1693, 1867, 2088, 2449, 3035, 2449, 2107, 1853, 1654, 1522, 1417, 1344, 1307, 1307, 1321, 1377, 1440, 1554, 1729, 1943, 2251, 2666, 2286, 1969, 1721, 1554, 1423, 1324, 1251, 1203, 1205, 1223, 1277, 1351, 1466, 1606, 1807, 2088, 2508, 2170, 1853, 1639, 1457, 1344, 1234, 1185, 1135, 1133, 1147, 1189, 1268, 1372, 1528, 1709, 1964, 2308, 2053, 1776, 1564, 1401, 1279, 1183, 1116, 1077, 1071, 1085, 1137, 1213, 1321, 1451, 1650, 1877, 2190, 1991, 1713, 1512, 1349, 1234, 1142, 1077, 1040, 1039, 1040, 1092, 1170, 1268, 1409, 1588, 1820, 2144, 1980, 1677, 1475, 1331, 1199, 1104, 1040, 1039, 1043, 1036, 1062, 1133, 1242, 1382, 1548, 1784, 2094, 1948, 1697, 1469, 1309, 1195, 1095, 1037, 1028, 1024, 1037, 1054, 1128, 1229, 1364, 1531, 1771, 2082, 1948, 1673, 1469, 1312, 1201, 1094, 1043, 1037, 1033, 1045, 1052, 1128, 1225, 1369, 1551, 1771, 2047, 1969, 1693, 1487, 1336, 1215, 1124, 1060, 1037, 1043, 1052, 1074, 1147, 1253, 1387, 1568, 1807, 2094, 2018, 1737, 1528, 1382, 1251, 1153, 1092, 1058, 1052, 1062, 1124, 1183, 1291, 1417, 1613, 1863, 2216, 2094, 1825, 1599, 1428, 1300, 1205, 1138, 1100, 1100, 1119, 1153, 1240, 1344, 1484, 1673, 1917, 2294, 2190, 1897, 1673, 1503, 1374, 1279, 1211, 1175, 1157, 1181, 1225, 1302, 1412, 1564, 1741, 2024, 2424, 2361, 2018, 1763, 1599, 1457, 1361, 1291, 1257, 1251, 1262, 1319, 1390, 1500, 1654, 1867, 2144, 2580, 2562, 2183, 1897, 1709, 1561, 1466, 1401, 1351, 1356, 1369, 1412, 1512, 1613, 1802, 1996, 2346, 2855, 2878, 2384, 2053, 1863, 1717, 1585, 1515, 1475, 1457, 1490, 1531, 1617, 1758, 1922, 2203, 2571, 3283] + }, + "lsc_samples_greenB": { + "uCoeff": [3112, 2505, 2167, 1930, 1775, 1670, 1598, 1536, 1526, 1549, 1606, 1698, 1835, 2060, 2294, 2738, 3586, 2707, 2272, 2001, 1784, 1635, 1533, 1457, 1410, 1396, 1422, 1478, 1560, 1674, 1854, 2078, 2436, 3058, 2419, 2096, 1821, 1639, 1510, 1399, 1338, 1313, 1292, 1313, 1359, 1442, 1567, 1711, 1925, 2236, 2686, 2279, 1930, 1698, 1533, 1407, 1308, 1237, 1212, 1198, 1216, 1257, 1343, 1454, 1598, 1798, 2060, 2479, 2141, 1845, 1617, 1454, 1328, 1227, 1166, 1130, 1120, 1138, 1191, 1268, 1369, 1516, 1702, 1957, 2294, 2066, 1762, 1560, 1394, 1262, 1166, 1109, 1071, 1071, 1075, 1127, 1206, 1321, 1448, 1632, 1869, 2236, 1985, 1694, 1513, 1333, 1222, 1134, 1062, 1030, 1030, 1042, 1085, 1162, 1271, 1396, 1567, 1807, 2154, 1952, 1682, 1463, 1316, 1202, 1095, 1045, 1028, 1034, 1030, 1058, 1134, 1229, 1377, 1549, 1784, 2090, 1925, 1678, 1463, 1304, 1178, 1087, 1034, 1024, 1027, 1028, 1050, 1118, 1222, 1359, 1536, 1762, 2066, 1952, 1662, 1466, 1308, 1182, 1095, 1030, 1030, 1034, 1036, 1059, 1118, 1225, 1364, 1533, 1757, 2103, 1946, 1690, 1481, 1321, 1204, 1113, 1045, 1028, 1028, 1042, 1071, 1145, 1246, 1380, 1567, 1789, 2122, 1979, 1736, 1526, 1367, 1240, 1143, 1082, 1045, 1044, 1059, 1116, 1182, 1278, 1424, 1598, 1854, 2201, 2078, 1802, 1577, 1419, 1301, 1198, 1130, 1094, 1085, 1102, 1147, 1227, 1338, 1487, 1670, 1925, 2243, 2194, 1854, 1651, 1497, 1359, 1262, 1202, 1156, 1153, 1178, 1225, 1292, 1407, 1546, 1740, 2013, 2411, 2339, 1990, 1744, 1584, 1448, 1354, 1280, 1244, 1235, 1262, 1301, 1380, 1500, 1655, 1859, 2154, 2550, 2523, 2154, 1884, 1698, 1549, 1439, 1380, 1346, 1333, 1359, 1410, 1478, 1613, 1798, 2007, 2339, 2814, 2848, 2355, 2060, 1835, 1678, 1560, 1513, 1454, 1454, 1472, 1533, 1613, 1740, 1946, 2194, 2550, 3240] + }, + "lsc_samples_blue": { + "uCoeff": [3118, 2483, 2181, 1958, 1788, 1676, 1606, 1533, 1551, 1560, 1616, 1720, 1850, 2032, 2312, 2655, 3482, 2764, 2235, 1958, 1753, 1616, 1524, 1442, 1405, 1412, 1412, 1490, 1551, 1676, 1850, 2095, 2416, 2979, 2438, 2095, 1825, 1646, 1490, 1397, 1341, 1302, 1277, 1322, 1369, 1427, 1533, 1698, 1902, 2198, 2554, 2292, 1958, 1720, 1524, 1405, 1322, 1236, 1203, 1192, 1208, 1259, 1341, 1435, 1578, 1776, 2047, 2438, 2198, 1825, 1616, 1450, 1309, 1214, 1161, 1113, 1113, 1137, 1182, 1248, 1369, 1507, 1656, 1902, 2273, 2047, 1765, 1578, 1405, 1259, 1166, 1109, 1073, 1065, 1082, 1132, 1192, 1296, 1442, 1616, 1837, 2129, 1987, 1709, 1507, 1335, 1219, 1137, 1065, 1032, 1032, 1040, 1069, 1142, 1242, 1369, 1560, 1776, 2063, 1972, 1676, 1482, 1322, 1192, 1109, 1040, 1024, 1032, 1028, 1052, 1132, 1219, 1341, 1524, 1753, 2032, 1958, 1676, 1466, 1296, 1182, 1095, 1032, 1028, 1024, 1032, 1048, 1104, 1208, 1341, 1490, 1731, 2032, 1944, 1656, 1450, 1322, 1182, 1095, 1032, 1040, 1032, 1024, 1044, 1113, 1208, 1335, 1516, 1720, 1987, 1944, 1676, 1490, 1328, 1192, 1113, 1060, 1044, 1028, 1044, 1065, 1132, 1242, 1362, 1533, 1753, 2032, 2017, 1720, 1507, 1355, 1236, 1142, 1086, 1048, 1044, 1052, 1104, 1166, 1277, 1397, 1578, 1788, 2095, 2047, 1812, 1569, 1405, 1290, 1192, 1132, 1095, 1086, 1104, 1156, 1219, 1335, 1442, 1626, 1850, 2181, 2181, 1837, 1626, 1474, 1362, 1259, 1187, 1161, 1142, 1166, 1203, 1277, 1405, 1524, 1720, 1972, 2312, 2373, 1972, 1753, 1560, 1435, 1328, 1277, 1236, 1219, 1242, 1290, 1369, 1474, 1616, 1825, 2095, 2483, 2530, 2129, 1850, 1698, 1533, 1435, 1369, 1341, 1322, 1335, 1397, 1482, 1578, 1765, 1944, 2312, 2764, 2914, 2312, 1972, 1776, 1616, 1490, 1427, 1427, 1376, 1412, 1482, 1533, 1666, 1850, 2112, 2438, 2979] + } + }, { + "name": "2592x1944_CWF_70", + "resolution": "2592x1944", + "illumination": "CWF", + "vignetting": 70, + "lsc_samples_red": { + "uCoeff": [2534, 2146, 1955, 1787, 1654, 1593, 1526, 1495, 1476, 1505, 1542, 1617, 1741, 1865, 2072, 2338, 2890, 2280, 1983, 1817, 1666, 1568, 1476, 1413, 1387, 1371, 1391, 1432, 1507, 1589, 1739, 1914, 2133, 2523, 2103, 1898, 1710, 1564, 1457, 1387, 1330, 1288, 1277, 1295, 1338, 1408, 1501, 1640, 1778, 1989, 2276, 1979, 1773, 1629, 1488, 1385, 1285, 1233, 1182, 1189, 1205, 1246, 1324, 1416, 1537, 1689, 1889, 2176, 1937, 1713, 1567, 1410, 1310, 1216, 1169, 1127, 1117, 1136, 1184, 1254, 1341, 1476, 1628, 1811, 2032, 1873, 1665, 1499, 1369, 1251, 1168, 1097, 1082, 1061, 1085, 1122, 1199, 1295, 1411, 1566, 1755, 2035, 1837, 1608, 1465, 1316, 1202, 1124, 1063, 1031, 1031, 1046, 1088, 1154, 1246, 1371, 1518, 1693, 1901, 1802, 1603, 1420, 1298, 1188, 1100, 1044, 1024, 1036, 1036, 1056, 1122, 1228, 1349, 1491, 1673, 1893, 1796, 1603, 1431, 1279, 1179, 1095, 1036, 1024, 1024, 1036, 1051, 1114, 1211, 1337, 1471, 1667, 1850, 1764, 1573, 1426, 1291, 1179, 1084, 1036, 1026, 1026, 1026, 1051, 1122, 1210, 1337, 1476, 1640, 1867, 1813, 1605, 1431, 1300, 1203, 1111, 1048, 1036, 1031, 1039, 1069, 1136, 1233, 1355, 1503, 1687, 1886, 1827, 1626, 1471, 1348, 1228, 1144, 1087, 1045, 1039, 1058, 1111, 1174, 1262, 1385, 1535, 1699, 1918, 1885, 1672, 1506, 1366, 1276, 1187, 1120, 1089, 1084, 1099, 1151, 1213, 1314, 1423, 1568, 1759, 1986, 1954, 1727, 1578, 1449, 1336, 1250, 1194, 1155, 1144, 1155, 1217, 1278, 1368, 1486, 1640, 1834, 2097, 2034, 1826, 1660, 1506, 1409, 1325, 1267, 1231, 1228, 1249, 1296, 1348, 1454, 1552, 1715, 1921, 2190, 2151, 1895, 1733, 1602, 1489, 1421, 1354, 1326, 1320, 1334, 1375, 1443, 1529, 1693, 1834, 2053, 2359, 2373, 2020, 1847, 1716, 1578, 1485, 1437, 1410, 1404, 1435, 1451, 1516, 1623, 1766, 1930, 2175, 2570] + }, + "lsc_samples_greenR": { + "uCoeff": [2504, 2111, 1896, 1754, 1665, 1562, 1494, 1482, 1473, 1482, 1524, 1612, 1683, 1819, 1999, 2270, 2740, 2242, 1957, 1791, 1659, 1544, 1464, 1399, 1374, 1359, 1386, 1430, 1489, 1573, 1710, 1864, 2105, 2437, 2075, 1863, 1687, 1546, 1446, 1374, 1311, 1278, 1266, 1286, 1318, 1384, 1484, 1607, 1749, 1954, 2241, 1953, 1769, 1603, 1481, 1364, 1295, 1228, 1187, 1188, 1208, 1241, 1319, 1403, 1525, 1665, 1852, 2073, 1892, 1691, 1546, 1403, 1306, 1219, 1159, 1126, 1114, 1128, 1176, 1252, 1336, 1452, 1590, 1774, 2022, 1831, 1640, 1482, 1356, 1240, 1162, 1103, 1071, 1060, 1081, 1124, 1194, 1286, 1401, 1550, 1711, 1946, 1785, 1597, 1446, 1315, 1209, 1120, 1063, 1041, 1031, 1041, 1083, 1151, 1254, 1360, 1510, 1663, 1888, 1761, 1580, 1410, 1297, 1189, 1096, 1041, 1031, 1028, 1032, 1053, 1127, 1220, 1335, 1475, 1651, 1873, 1746, 1588, 1413, 1286, 1177, 1090, 1028, 1028, 1024, 1024, 1042, 1108, 1211, 1327, 1464, 1629, 1839, 1720, 1564, 1408, 1282, 1179, 1088, 1039, 1031, 1031, 1034, 1049, 1116, 1206, 1329, 1463, 1637, 1849, 1773, 1586, 1431, 1306, 1191, 1106, 1048, 1034, 1032, 1038, 1066, 1128, 1222, 1337, 1489, 1645, 1880, 1785, 1605, 1468, 1326, 1223, 1142, 1088, 1048, 1038, 1051, 1116, 1172, 1257, 1372, 1509, 1687, 1907, 1846, 1664, 1500, 1380, 1273, 1198, 1127, 1091, 1088, 1103, 1139, 1211, 1304, 1421, 1562, 1743, 1952, 1919, 1708, 1556, 1432, 1334, 1254, 1192, 1149, 1150, 1163, 1206, 1274, 1370, 1479, 1612, 1810, 2053, 2011, 1789, 1635, 1507, 1407, 1314, 1265, 1228, 1219, 1240, 1283, 1348, 1434, 1550, 1693, 1883, 2167, 2120, 1895, 1732, 1597, 1480, 1400, 1343, 1316, 1305, 1326, 1366, 1431, 1520, 1663, 1791, 2004, 2313, 2342, 2009, 1843, 1698, 1582, 1508, 1447, 1404, 1407, 1419, 1454, 1532, 1612, 1734, 1895, 2151, 2515] + }, + "lsc_samples_greenB": { + "uCoeff": [2446, 2096, 1932, 1765, 1651, 1570, 1510, 1495, 1485, 1495, 1524, 1592, 1709, 1827, 2010, 2294, 2808, 2234, 1973, 1798, 1657, 1547, 1470, 1411, 1376, 1363, 1391, 1422, 1486, 1591, 1712, 1882, 2118, 2458, 2081, 1856, 1681, 1557, 1451, 1368, 1315, 1273, 1276, 1283, 1334, 1400, 1487, 1608, 1760, 1988, 2241, 1957, 1767, 1608, 1467, 1379, 1292, 1229, 1200, 1191, 1207, 1249, 1318, 1409, 1532, 1692, 1870, 2112, 1891, 1684, 1536, 1406, 1303, 1224, 1158, 1130, 1126, 1139, 1184, 1253, 1338, 1457, 1605, 1776, 2033, 1835, 1630, 1486, 1360, 1257, 1168, 1110, 1071, 1066, 1080, 1125, 1193, 1292, 1409, 1568, 1738, 1967, 1779, 1605, 1443, 1314, 1216, 1127, 1072, 1034, 1034, 1041, 1092, 1155, 1247, 1375, 1507, 1689, 1912, 1759, 1567, 1416, 1290, 1190, 1102, 1044, 1034, 1034, 1037, 1057, 1120, 1219, 1345, 1481, 1660, 1866, 1757, 1581, 1416, 1288, 1180, 1088, 1037, 1030, 1031, 1038, 1055, 1118, 1208, 1333, 1479, 1657, 1867, 1739, 1561, 1408, 1288, 1174, 1093, 1041, 1024, 1030, 1038, 1055, 1118, 1217, 1333, 1478, 1643, 1857, 1767, 1577, 1428, 1296, 1199, 1110, 1049, 1034, 1035, 1038, 1074, 1135, 1233, 1357, 1493, 1678, 1884, 1788, 1613, 1450, 1331, 1224, 1142, 1087, 1054, 1048, 1054, 1110, 1173, 1267, 1379, 1517, 1701, 1927, 1854, 1666, 1510, 1374, 1274, 1191, 1129, 1091, 1087, 1103, 1148, 1218, 1305, 1431, 1573, 1740, 1980, 1912, 1705, 1564, 1438, 1328, 1253, 1187, 1159, 1156, 1171, 1211, 1282, 1372, 1489, 1628, 1809, 2066, 1998, 1788, 1629, 1498, 1391, 1318, 1264, 1233, 1222, 1235, 1284, 1343, 1434, 1557, 1703, 1898, 2174, 2098, 1893, 1704, 1578, 1484, 1403, 1347, 1308, 1307, 1330, 1365, 1428, 1530, 1661, 1794, 2015, 2313, 2257, 1990, 1826, 1659, 1579, 1496, 1436, 1412, 1389, 1407, 1451, 1516, 1627, 1745, 1894, 2158, 2593] + }, + "lsc_samples_blue": { + "uCoeff": [2405, 2079, 1941, 1774, 1672, 1592, 1544, 1506, 1509, 1506, 1551, 1615, 1704, 1844, 1998, 2315, 2771, 2248, 1945, 1773, 1626, 1542, 1453, 1419, 1389, 1361, 1399, 1425, 1486, 1569, 1692, 1864, 2084, 2378, 2100, 1872, 1686, 1560, 1448, 1370, 1312, 1280, 1271, 1295, 1321, 1398, 1479, 1604, 1746, 1944, 2196, 1954, 1767, 1594, 1484, 1374, 1298, 1226, 1207, 1185, 1207, 1244, 1318, 1403, 1514, 1664, 1821, 2062, 1943, 1692, 1525, 1410, 1301, 1236, 1162, 1115, 1116, 1135, 1173, 1244, 1337, 1438, 1572, 1771, 1951, 1840, 1634, 1492, 1370, 1266, 1173, 1116, 1070, 1063, 1081, 1124, 1181, 1279, 1396, 1529, 1705, 1860, 1778, 1600, 1446, 1320, 1213, 1143, 1070, 1030, 1037, 1044, 1092, 1142, 1234, 1343, 1482, 1634, 1852, 1764, 1566, 1424, 1295, 1184, 1109, 1047, 1040, 1044, 1037, 1063, 1128, 1205, 1319, 1445, 1633, 1817, 1766, 1590, 1412, 1286, 1181, 1095, 1047, 1037, 1024, 1040, 1044, 1105, 1210, 1315, 1447, 1599, 1796, 1756, 1551, 1425, 1286, 1181, 1106, 1044, 1044, 1040, 1040, 1057, 1112, 1200, 1325, 1452, 1616, 1795, 1801, 1562, 1421, 1299, 1200, 1132, 1056, 1047, 1044, 1047, 1070, 1131, 1226, 1339, 1469, 1618, 1809, 1847, 1609, 1448, 1343, 1225, 1149, 1095, 1070, 1047, 1053, 1116, 1165, 1251, 1362, 1504, 1662, 1840, 1836, 1665, 1498, 1369, 1276, 1201, 1142, 1087, 1098, 1105, 1142, 1213, 1301, 1408, 1536, 1734, 1958, 1921, 1714, 1542, 1432, 1320, 1245, 1188, 1165, 1162, 1173, 1209, 1268, 1357, 1468, 1583, 1773, 2053, 1978, 1768, 1603, 1491, 1389, 1317, 1253, 1233, 1225, 1233, 1272, 1320, 1437, 1530, 1684, 1855, 2088, 2063, 1878, 1713, 1559, 1460, 1407, 1329, 1313, 1298, 1322, 1373, 1417, 1505, 1651, 1784, 1979, 2237, 2286, 1990, 1786, 1640, 1514, 1463, 1431, 1380, 1366, 1381, 1416, 1490, 1579, 1695, 1858, 2071, 2408] + } + }, { + "name": "2592x1944_CWF_100", + "resolution": "2592x1944", + "illumination": "CWF", + "vignetting": 100, + "lsc_samples_red": { + "uCoeff": [3165, 2518, 2209, 1958, 1773, 1683, 1596, 1556, 1534, 1567, 1614, 1710, 1873, 2051, 2353, 2777, 3677, 2742, 2267, 2004, 1788, 1651, 1534, 1456, 1422, 1404, 1427, 1476, 1567, 1677, 1873, 2122, 2461, 3074, 2461, 2122, 1849, 1651, 1512, 1422, 1355, 1306, 1294, 1314, 1364, 1446, 1561, 1737, 1932, 2243, 2691, 2267, 1949, 1737, 1550, 1422, 1306, 1246, 1191, 1197, 1214, 1260, 1347, 1456, 1608, 1810, 2091, 2518, 2186, 1857, 1651, 1456, 1334, 1228, 1175, 1131, 1120, 1140, 1191, 1268, 1368, 1528, 1723, 1976, 2315, 2091, 1788, 1567, 1404, 1268, 1175, 1100, 1083, 1062, 1086, 1125, 1207, 1314, 1451, 1645, 1898, 2291, 2032, 1717, 1523, 1343, 1214, 1128, 1064, 1031, 1031, 1046, 1089, 1159, 1260, 1404, 1584, 1818, 2122, 1985, 1703, 1471, 1322, 1197, 1102, 1044, 1024, 1036, 1036, 1057, 1125, 1239, 1377, 1550, 1788, 2101, 1976, 1703, 1481, 1302, 1187, 1097, 1036, 1024, 1024, 1036, 1051, 1117, 1221, 1364, 1528, 1780, 2051, 1940, 1670, 1476, 1314, 1187, 1086, 1036, 1026, 1026, 1026, 1051, 1125, 1221, 1364, 1534, 1751, 2071, 2004, 1710, 1486, 1326, 1214, 1114, 1049, 1036, 1031, 1039, 1070, 1140, 1246, 1386, 1567, 1810, 2101, 2032, 1744, 1534, 1381, 1242, 1150, 1089, 1046, 1039, 1059, 1114, 1181, 1279, 1422, 1608, 1833, 2154, 2122, 1810, 1584, 1408, 1298, 1197, 1125, 1091, 1086, 1102, 1156, 1225, 1338, 1471, 1657, 1915, 2255, 2231, 1890, 1677, 1507, 1368, 1268, 1204, 1162, 1150, 1162, 1228, 1298, 1404, 1550, 1751, 2022, 2419, 2366, 2032, 1788, 1584, 1456, 1355, 1287, 1246, 1242, 1264, 1318, 1381, 1507, 1638, 1857, 2154, 2578, 2563, 2154, 1898, 1710, 1561, 1471, 1390, 1355, 1347, 1364, 1413, 1496, 1608, 1818, 2022, 2353, 2851, 2928, 2353, 2071, 1865, 1683, 1561, 1496, 1461, 1451, 1486, 1512, 1596, 1737, 1932, 2175, 2563, 3236] + }, + "lsc_samples_greenR": { + "uCoeff": [3128, 2477, 2142, 1921, 1785, 1650, 1562, 1543, 1531, 1543, 1595, 1705, 1811, 2001, 2270, 2696, 3486, 2696, 2237, 1975, 1781, 1625, 1521, 1441, 1409, 1391, 1422, 1474, 1549, 1661, 1842, 2067, 2429, 2969, 2429, 2083, 1824, 1632, 1500, 1409, 1335, 1296, 1283, 1305, 1344, 1422, 1543, 1702, 1901, 2204, 2649, 2237, 1945, 1709, 1543, 1401, 1316, 1241, 1196, 1196, 1217, 1255, 1342, 1443, 1595, 1785, 2050, 2399, 2136, 1833, 1629, 1449, 1330, 1231, 1165, 1130, 1117, 1132, 1183, 1266, 1363, 1503, 1683, 1935, 2304, 2044, 1761, 1549, 1391, 1257, 1169, 1106, 1072, 1061, 1082, 1127, 1202, 1305, 1441, 1629, 1850, 2191, 1975, 1705, 1503, 1342, 1221, 1124, 1064, 1041, 1031, 1041, 1084, 1156, 1268, 1393, 1575, 1785, 2107, 1940, 1679, 1460, 1321, 1198, 1098, 1041, 1031, 1028, 1032, 1054, 1130, 1231, 1363, 1534, 1765, 2078, 1921, 1687, 1463, 1309, 1185, 1092, 1028, 1028, 1024, 1024, 1042, 1111, 1221, 1354, 1521, 1740, 2039, 1892, 1661, 1457, 1305, 1187, 1090, 1039, 1031, 1031, 1034, 1049, 1119, 1217, 1356, 1521, 1748, 2050, 1960, 1690, 1486, 1332, 1202, 1109, 1049, 1034, 1032, 1038, 1067, 1132, 1235, 1368, 1552, 1765, 2095, 1986, 1721, 1531, 1358, 1237, 1148, 1090, 1049, 1038, 1052, 1119, 1179, 1274, 1409, 1581, 1820, 2142, 2078, 1802, 1578, 1422, 1294, 1208, 1132, 1093, 1090, 1106, 1144, 1223, 1328, 1469, 1650, 1897, 2217, 2191, 1869, 1654, 1489, 1366, 1272, 1202, 1156, 1156, 1170, 1217, 1294, 1406, 1543, 1721, 1996, 2369, 2340, 1991, 1761, 1585, 1454, 1344, 1285, 1243, 1233, 1255, 1305, 1381, 1486, 1636, 1833, 2112, 2551, 2526, 2154, 1897, 1705, 1552, 1449, 1378, 1344, 1332, 1356, 1404, 1483, 1598, 1785, 1975, 2297, 2795, 2890, 2340, 2067, 1846, 1687, 1585, 1506, 1454, 1454, 1469, 1515, 1612, 1725, 1897, 2136, 2534, 3167] + }, + "lsc_samples_greenB": { + "uCoeff": [3055, 2460, 2183, 1933, 1770, 1658, 1579, 1556, 1543, 1556, 1595, 1684, 1839, 2010, 2282, 2725, 3573, 2687, 2255, 1983, 1779, 1629, 1528, 1454, 1411, 1395, 1427, 1466, 1546, 1680, 1844, 2087, 2444, 2995, 2436, 2076, 1817, 1644, 1506, 1403, 1339, 1291, 1293, 1302, 1360, 1438, 1546, 1703, 1913, 2242, 2649, 2242, 1943, 1714, 1528, 1416, 1313, 1242, 1209, 1199, 1216, 1263, 1341, 1449, 1602, 1813, 2070, 2444, 2134, 1826, 1619, 1452, 1327, 1236, 1164, 1134, 1129, 1143, 1191, 1267, 1365, 1509, 1699, 1938, 2317, 2048, 1750, 1553, 1395, 1274, 1175, 1113, 1072, 1067, 1081, 1128, 1201, 1311, 1449, 1647, 1880, 2215, 1968, 1714, 1500, 1341, 1228, 1131, 1073, 1034, 1034, 1041, 1093, 1160, 1261, 1408, 1572, 1813, 2134, 1938, 1665, 1466, 1313, 1199, 1105, 1044, 1034, 1034, 1037, 1058, 1123, 1230, 1373, 1540, 1774, 2070, 1933, 1680, 1466, 1311, 1188, 1090, 1037, 1030, 1031, 1038, 1055, 1121, 1218, 1360, 1537, 1770, 2070, 1913, 1658, 1457, 1311, 1182, 1095, 1041, 1024, 1030, 1038, 1055, 1121, 1228, 1360, 1537, 1754, 2059, 1953, 1680, 1483, 1322, 1210, 1113, 1050, 1034, 1035, 1038, 1075, 1139, 1246, 1388, 1556, 1800, 2099, 1989, 1730, 1512, 1363, 1238, 1148, 1089, 1055, 1048, 1055, 1113, 1180, 1284, 1416, 1589, 1835, 2165, 2087, 1804, 1589, 1416, 1295, 1201, 1134, 1093, 1089, 1106, 1153, 1230, 1329, 1480, 1662, 1894, 2248, 2183, 1866, 1662, 1495, 1360, 1271, 1197, 1166, 1162, 1178, 1222, 1302, 1408, 1553, 1738, 1994, 2383, 2324, 1989, 1754, 1575, 1438, 1348, 1284, 1248, 1236, 1250, 1306, 1375, 1486, 1644, 1844, 2128, 2560, 2500, 2152, 1866, 1684, 1556, 1452, 1383, 1336, 1334, 1360, 1403, 1480, 1609, 1783, 1978, 2310, 2796, 2785, 2317, 2048, 1804, 1684, 1572, 1495, 1463, 1435, 1457, 1512, 1595, 1742, 1909, 2134, 2542, 3265] + }, + "lsc_samples_blue": { + "uCoeff": [3004, 2440, 2193, 1943, 1793, 1682, 1615, 1568, 1568, 1568, 1623, 1708, 1834, 2028, 2269, 2750, 3526, 2704, 2223, 1955, 1745, 1623, 1510, 1462, 1424, 1393, 1436, 1469, 1546, 1656, 1823, 2067, 2404, 2897, 2458, 2094, 1823, 1647, 1503, 1405, 1336, 1298, 1288, 1314, 1347, 1436, 1538, 1699, 1898, 2193, 2596, 2238, 1943, 1699, 1546, 1411, 1319, 1239, 1216, 1193, 1216, 1258, 1341, 1443, 1583, 1783, 2016, 2386, 2193, 1834, 1607, 1456, 1325, 1248, 1168, 1119, 1119, 1139, 1180, 1258, 1364, 1489, 1664, 1932, 2223, 2054, 1754, 1560, 1405, 1283, 1180, 1119, 1071, 1064, 1082, 1127, 1189, 1298, 1436, 1607, 1844, 2094, 1967, 1708, 1503, 1347, 1225, 1147, 1071, 1030, 1037, 1044, 1093, 1147, 1248, 1375, 1546, 1754, 2067, 1943, 1664, 1475, 1319, 1193, 1112, 1047, 1040, 1044, 1037, 1064, 1131, 1216, 1347, 1503, 1745, 2016, 1943, 1690, 1462, 1309, 1189, 1097, 1047, 1037, 1024, 1040, 1044, 1108, 1220, 1341, 1503, 1708, 1991, 1932, 1647, 1475, 1309, 1189, 1108, 1044, 1044, 1040, 1040, 1057, 1115, 1211, 1352, 1510, 1726, 1991, 1991, 1664, 1475, 1325, 1211, 1135, 1057, 1047, 1044, 1047, 1071, 1135, 1239, 1370, 1531, 1736, 2016, 2054, 1726, 1510, 1375, 1239, 1155, 1097, 1071, 1047, 1054, 1119, 1172, 1268, 1399, 1576, 1793, 2067, 2067, 1803, 1576, 1411, 1298, 1211, 1147, 1089, 1100, 1108, 1147, 1225, 1325, 1456, 1623, 1887, 2223, 2193, 1876, 1639, 1489, 1352, 1263, 1198, 1172, 1168, 1180, 1220, 1288, 1393, 1531, 1690, 1955, 2369, 2301, 1967, 1726, 1568, 1436, 1347, 1273, 1248, 1239, 1248, 1293, 1352, 1489, 1615, 1823, 2080, 2458, 2458, 2135, 1876, 1664, 1531, 1456, 1364, 1341, 1325, 1352, 1411, 1469, 1583, 1773, 1967, 2269, 2704, 2821, 2318, 2003, 1783, 1615, 1538, 1489, 1430, 1411, 1430, 1475, 1568, 1690, 1854, 2094, 2440, 3032] + } + }, { + "name": "2592x1944_D50_70", + "resolution": "2592x1944", + "illumination": "D50", + "vignetting": 70, + "lsc_samples_red": { + "uCoeff": [2656, 2220, 1990, 1862, 1699, 1614, 1541, 1505, 1502, 1534, 1565, 1651, 1769, 1910, 2112, 2423, 3101, 2392, 2052, 1826, 1698, 1588, 1507, 1451, 1393, 1390, 1416, 1454, 1533, 1628, 1775, 1936, 2194, 2602, 2163, 1917, 1729, 1595, 1477, 1398, 1340, 1298, 1296, 1318, 1356, 1430, 1516, 1656, 1825, 2051, 2334, 2072, 1813, 1639, 1503, 1391, 1309, 1242, 1206, 1193, 1227, 1263, 1328, 1418, 1566, 1710, 1930, 2185, 1992, 1746, 1573, 1431, 1317, 1228, 1178, 1139, 1122, 1145, 1191, 1263, 1355, 1496, 1630, 1835, 2107, 1875, 1674, 1514, 1384, 1272, 1177, 1111, 1078, 1070, 1083, 1131, 1211, 1302, 1433, 1579, 1777, 2007, 1864, 1638, 1473, 1331, 1224, 1133, 1075, 1037, 1042, 1057, 1092, 1163, 1256, 1386, 1547, 1726, 1974, 1811, 1610, 1447, 1306, 1199, 1108, 1049, 1037, 1031, 1039, 1063, 1125, 1225, 1358, 1506, 1698, 1933, 1814, 1623, 1433, 1307, 1190, 1096, 1037, 1037, 1026, 1039, 1055, 1122, 1223, 1347, 1502, 1686, 1889, 1806, 1592, 1443, 1306, 1183, 1091, 1044, 1029, 1024, 1037, 1063, 1125, 1222, 1350, 1490, 1677, 1906, 1840, 1632, 1455, 1316, 1208, 1119, 1055, 1037, 1031, 1049, 1075, 1139, 1242, 1374, 1525, 1715, 1945, 1844, 1643, 1483, 1344, 1247, 1150, 1082, 1057, 1042, 1067, 1116, 1181, 1283, 1391, 1552, 1741, 1982, 1949, 1729, 1528, 1406, 1279, 1198, 1138, 1096, 1091, 1116, 1154, 1228, 1334, 1450, 1600, 1805, 2057, 1984, 1757, 1604, 1454, 1345, 1263, 1198, 1168, 1149, 1168, 1222, 1293, 1383, 1512, 1665, 1851, 2156, 2065, 1845, 1663, 1535, 1419, 1334, 1277, 1240, 1231, 1254, 1300, 1362, 1466, 1589, 1759, 1952, 2226, 2199, 1979, 1753, 1616, 1523, 1420, 1374, 1335, 1328, 1357, 1389, 1452, 1558, 1705, 1870, 2094, 2441, 2430, 2094, 1875, 1741, 1605, 1508, 1462, 1429, 1406, 1442, 1498, 1555, 1665, 1796, 1990, 2228, 2667] + }, + "lsc_samples_greenR": { + "uCoeff": [2429, 2116, 1915, 1783, 1657, 1571, 1502, 1489, 1470, 1494, 1535, 1604, 1692, 1808, 2013, 2245, 2840, 2264, 1976, 1796, 1648, 1546, 1464, 1406, 1369, 1366, 1384, 1429, 1489, 1586, 1715, 1875, 2081, 2443, 2077, 1847, 1688, 1555, 1452, 1369, 1311, 1284, 1269, 1283, 1332, 1396, 1493, 1598, 1751, 1965, 2235, 1962, 1763, 1606, 1481, 1363, 1285, 1224, 1194, 1180, 1196, 1238, 1312, 1405, 1520, 1676, 1848, 2119, 1890, 1690, 1533, 1413, 1305, 1223, 1153, 1121, 1111, 1127, 1170, 1249, 1326, 1455, 1604, 1766, 2003, 1832, 1639, 1476, 1359, 1246, 1161, 1110, 1073, 1056, 1073, 1119, 1188, 1278, 1392, 1549, 1709, 1927, 1772, 1591, 1446, 1306, 1203, 1127, 1064, 1025, 1028, 1035, 1081, 1154, 1242, 1359, 1489, 1667, 1874, 1757, 1561, 1414, 1290, 1179, 1102, 1035, 1030, 1030, 1024, 1053, 1121, 1212, 1334, 1475, 1649, 1863, 1715, 1583, 1404, 1277, 1171, 1086, 1030, 1024, 1024, 1031, 1044, 1111, 1207, 1315, 1465, 1623, 1841, 1747, 1562, 1404, 1283, 1171, 1086, 1031, 1025, 1024, 1030, 1050, 1114, 1202, 1318, 1464, 1637, 1843, 1750, 1571, 1428, 1307, 1192, 1111, 1040, 1030, 1032, 1035, 1065, 1127, 1221, 1331, 1487, 1658, 1887, 1789, 1604, 1457, 1326, 1223, 1136, 1073, 1053, 1038, 1056, 1113, 1168, 1258, 1372, 1516, 1692, 1933, 1835, 1667, 1495, 1376, 1267, 1191, 1124, 1088, 1081, 1096, 1143, 1205, 1308, 1417, 1567, 1736, 1933, 1905, 1711, 1556, 1442, 1335, 1249, 1184, 1149, 1144, 1161, 1202, 1271, 1361, 1477, 1624, 1800, 2047, 1998, 1790, 1615, 1491, 1397, 1314, 1257, 1222, 1220, 1231, 1276, 1345, 1438, 1538, 1694, 1890, 2152, 2112, 1872, 1716, 1575, 1479, 1405, 1348, 1308, 1294, 1324, 1361, 1428, 1508, 1656, 1801, 1996, 2289, 2265, 2030, 1813, 1693, 1588, 1507, 1424, 1405, 1403, 1416, 1460, 1525, 1614, 1749, 1904, 2132, 2502] + }, + "lsc_samples_greenB": { + "uCoeff": [2478, 2109, 1921, 1769, 1659, 1563, 1523, 1484, 1472, 1471, 1523, 1595, 1713, 1834, 2025, 2261, 2796, 2215, 1977, 1788, 1653, 1544, 1465, 1407, 1378, 1367, 1391, 1422, 1493, 1591, 1716, 1871, 2101, 2481, 2070, 1864, 1685, 1556, 1442, 1365, 1303, 1276, 1270, 1291, 1331, 1393, 1494, 1611, 1766, 1960, 2250, 1956, 1764, 1608, 1470, 1372, 1289, 1236, 1200, 1191, 1207, 1247, 1306, 1403, 1527, 1666, 1855, 2119, 1884, 1699, 1538, 1411, 1309, 1214, 1158, 1129, 1116, 1132, 1179, 1242, 1338, 1447, 1601, 1785, 2027, 1828, 1640, 1486, 1353, 1253, 1162, 1105, 1071, 1062, 1082, 1122, 1193, 1286, 1402, 1561, 1732, 1956, 1773, 1592, 1449, 1322, 1214, 1128, 1067, 1032, 1027, 1040, 1082, 1155, 1252, 1363, 1496, 1696, 1896, 1745, 1570, 1418, 1287, 1188, 1094, 1038, 1027, 1028, 1032, 1056, 1122, 1219, 1330, 1485, 1649, 1864, 1738, 1580, 1408, 1283, 1174, 1091, 1032, 1024, 1024, 1034, 1045, 1109, 1210, 1322, 1469, 1644, 1852, 1725, 1560, 1406, 1287, 1174, 1086, 1034, 1024, 1024, 1034, 1053, 1114, 1213, 1324, 1471, 1643, 1854, 1756, 1579, 1423, 1289, 1194, 1101, 1047, 1034, 1027, 1038, 1074, 1137, 1226, 1342, 1482, 1660, 1881, 1785, 1609, 1462, 1333, 1223, 1137, 1076, 1048, 1047, 1049, 1109, 1171, 1264, 1379, 1521, 1693, 1911, 1821, 1649, 1503, 1367, 1273, 1187, 1127, 1089, 1078, 1106, 1146, 1216, 1304, 1424, 1575, 1741, 1969, 1878, 1694, 1554, 1417, 1321, 1242, 1181, 1152, 1140, 1164, 1204, 1271, 1364, 1481, 1617, 1810, 2053, 1986, 1776, 1632, 1485, 1401, 1315, 1261, 1224, 1215, 1239, 1270, 1344, 1444, 1553, 1703, 1896, 2188, 2111, 1878, 1712, 1580, 1471, 1391, 1337, 1310, 1298, 1312, 1370, 1421, 1528, 1653, 1792, 2014, 2332, 2344, 2005, 1824, 1677, 1571, 1480, 1434, 1390, 1391, 1412, 1450, 1526, 1630, 1750, 1921, 2146, 2542] + }, + "lsc_samples_blue": { + "uCoeff": [2427, 2102, 1938, 1778, 1637, 1579, 1521, 1470, 1477, 1496, 1543, 1599, 1696, 1816, 1981, 2212, 2669, 2222, 1941, 1768, 1618, 1534, 1448, 1401, 1373, 1355, 1381, 1417, 1479, 1562, 1694, 1852, 2055, 2365, 2111, 1834, 1668, 1551, 1445, 1364, 1304, 1272, 1273, 1278, 1314, 1380, 1465, 1597, 1727, 1908, 2169, 2006, 1765, 1575, 1467, 1363, 1287, 1219, 1191, 1182, 1191, 1241, 1305, 1382, 1497, 1641, 1831, 2066, 1904, 1688, 1532, 1406, 1307, 1216, 1157, 1123, 1115, 1128, 1162, 1228, 1312, 1430, 1581, 1727, 1959, 1823, 1640, 1467, 1353, 1242, 1162, 1105, 1068, 1058, 1073, 1115, 1182, 1264, 1391, 1526, 1675, 1865, 1770, 1592, 1433, 1307, 1213, 1133, 1061, 1038, 1033, 1033, 1073, 1141, 1224, 1339, 1471, 1623, 1857, 1748, 1569, 1424, 1289, 1184, 1095, 1033, 1026, 1026, 1033, 1050, 1121, 1198, 1319, 1465, 1619, 1825, 1751, 1575, 1395, 1272, 1173, 1090, 1033, 1024, 1024, 1033, 1038, 1102, 1196, 1302, 1443, 1591, 1767, 1716, 1537, 1403, 1278, 1185, 1098, 1031, 1033, 1035, 1035, 1047, 1107, 1196, 1309, 1434, 1601, 1765, 1742, 1564, 1421, 1291, 1198, 1115, 1050, 1035, 1045, 1035, 1056, 1122, 1213, 1324, 1448, 1614, 1794, 1760, 1595, 1450, 1334, 1214, 1132, 1085, 1057, 1038, 1056, 1107, 1159, 1231, 1343, 1489, 1666, 1862, 1803, 1655, 1484, 1367, 1273, 1180, 1122, 1082, 1085, 1097, 1141, 1210, 1288, 1387, 1545, 1697, 1919, 1904, 1689, 1537, 1398, 1323, 1231, 1180, 1149, 1140, 1148, 1195, 1257, 1335, 1462, 1592, 1767, 1983, 1957, 1752, 1611, 1485, 1382, 1298, 1252, 1211, 1209, 1217, 1259, 1326, 1409, 1530, 1673, 1855, 2084, 2093, 1840, 1685, 1561, 1460, 1383, 1332, 1307, 1290, 1299, 1342, 1410, 1479, 1636, 1731, 1965, 2271, 2214, 1951, 1737, 1619, 1520, 1466, 1395, 1361, 1350, 1372, 1399, 1472, 1563, 1708, 1842, 2032, 2372] + } + }, { + "name": "2592x1944_D50_100", + "resolution": "2592x1944", + "illumination": "D50", + "vignetting": 100, + "lsc_samples_red": { + "uCoeff": [3324, 2607, 2247, 2041, 1822, 1704, 1613, 1566, 1560, 1595, 1638, 1747, 1904, 2102, 2400, 2873, 3943, 2873, 2347, 2012, 1822, 1671, 1566, 1494, 1428, 1423, 1453, 1499, 1595, 1718, 1912, 2145, 2529, 3174, 2529, 2145, 1870, 1684, 1532, 1433, 1364, 1317, 1313, 1338, 1382, 1468, 1577, 1754, 1984, 2309, 2760, 2373, 1993, 1747, 1566, 1428, 1330, 1255, 1215, 1201, 1236, 1277, 1351, 1458, 1638, 1830, 2134, 2529, 2247, 1895, 1658, 1478, 1342, 1240, 1184, 1143, 1125, 1149, 1198, 1277, 1382, 1548, 1725, 2003, 2400, 2092, 1799, 1583, 1419, 1289, 1184, 1113, 1079, 1071, 1084, 1134, 1219, 1321, 1473, 1658, 1921, 2259, 2061, 1747, 1532, 1359, 1236, 1137, 1076, 1037, 1042, 1057, 1093, 1168, 1270, 1419, 1613, 1854, 2201, 1993, 1711, 1499, 1330, 1208, 1110, 1049, 1037, 1031, 1039, 1063, 1128, 1236, 1386, 1566, 1814, 2145, 1993, 1725, 1483, 1330, 1198, 1098, 1037, 1037, 1026, 1039, 1055, 1125, 1233, 1373, 1560, 1799, 2092, 1984, 1691, 1494, 1330, 1191, 1093, 1044, 1029, 1024, 1037, 1063, 1128, 1233, 1377, 1548, 1791, 2113, 2032, 1739, 1510, 1342, 1219, 1122, 1055, 1037, 1031, 1049, 1076, 1143, 1255, 1405, 1589, 1838, 2167, 2051, 1761, 1548, 1377, 1262, 1155, 1084, 1057, 1042, 1068, 1119, 1188, 1301, 1428, 1626, 1878, 2224, 2189, 1870, 1607, 1448, 1301, 1208, 1143, 1098, 1093, 1119, 1159, 1240, 1359, 1499, 1691, 1965, 2334, 2259, 1921, 1704, 1510, 1377, 1281, 1208, 1175, 1155, 1175, 1233, 1313, 1419, 1577, 1776, 2041, 2485, 2400, 2051, 1791, 1613, 1468, 1364, 1297, 1255, 1244, 1270, 1321, 1395, 1521, 1677, 1904, 2189, 2623, 2623, 2247, 1921, 1725, 1595, 1468, 1409, 1364, 1355, 1386, 1428, 1504, 1638, 1830, 2061, 2400, 2953, 3016, 2442, 2102, 1895, 1711, 1583, 1521, 1478, 1453, 1494, 1560, 1638, 1783, 1965, 2247, 2623, 3350] + }, + "lsc_samples_greenR": { + "uCoeff": [3040, 2485, 2162, 1954, 1777, 1659, 1572, 1549, 1527, 1553, 1606, 1697, 1821, 1990, 2288, 2662, 3612, 2720, 2260, 1979, 1769, 1627, 1521, 1448, 1404, 1399, 1420, 1473, 1549, 1674, 1848, 2078, 2398, 2980, 2429, 2067, 1825, 1641, 1506, 1404, 1334, 1302, 1286, 1302, 1358, 1434, 1553, 1693, 1904, 2213, 2643, 2247, 1938, 1712, 1543, 1399, 1306, 1237, 1203, 1188, 1205, 1252, 1334, 1445, 1589, 1794, 2044, 2453, 2132, 1834, 1616, 1459, 1329, 1235, 1159, 1124, 1114, 1131, 1177, 1262, 1353, 1506, 1697, 1928, 2281, 2044, 1761, 1543, 1394, 1262, 1168, 1112, 1074, 1057, 1074, 1122, 1196, 1297, 1431, 1627, 1848, 2169, 1959, 1697, 1503, 1334, 1215, 1131, 1065, 1025, 1028, 1035, 1082, 1159, 1256, 1391, 1553, 1790, 2090, 1933, 1659, 1465, 1313, 1188, 1104, 1035, 1030, 1030, 1024, 1053, 1124, 1223, 1361, 1534, 1761, 2067, 1885, 1682, 1453, 1299, 1179, 1088, 1030, 1024, 1024, 1031, 1044, 1114, 1217, 1341, 1521, 1732, 2039, 1919, 1659, 1453, 1306, 1179, 1088, 1031, 1025, 1024, 1030, 1050, 1117, 1213, 1344, 1521, 1748, 2044, 1933, 1674, 1482, 1332, 1203, 1114, 1040, 1030, 1032, 1035, 1066, 1131, 1233, 1361, 1549, 1777, 2102, 1990, 1720, 1521, 1358, 1237, 1141, 1075, 1053, 1038, 1057, 1116, 1175, 1275, 1409, 1589, 1825, 2169, 2061, 1803, 1572, 1417, 1288, 1201, 1129, 1090, 1083, 1099, 1148, 1217, 1332, 1465, 1656, 1890, 2194, 2169, 1871, 1652, 1497, 1366, 1266, 1194, 1155, 1150, 1168, 1213, 1290, 1396, 1540, 1732, 1985, 2360, 2323, 1990, 1740, 1566, 1445, 1344, 1277, 1237, 1233, 1247, 1297, 1378, 1491, 1623, 1834, 2119, 2536, 2519, 2125, 1880, 1682, 1549, 1453, 1383, 1336, 1320, 1353, 1399, 1479, 1586, 1777, 1985, 2288, 2770, 2812, 2367, 2033, 1843, 1693, 1582, 1482, 1453, 1450, 1467, 1521, 1606, 1728, 1914, 2150, 2510, 3142] + }, + "lsc_samples_greenB": { + "uCoeff": [3101, 2477, 2169, 1939, 1779, 1650, 1594, 1544, 1529, 1529, 1594, 1687, 1844, 2018, 2302, 2680, 3556, 2661, 2261, 1970, 1774, 1625, 1522, 1449, 1413, 1400, 1427, 1466, 1554, 1679, 1849, 2073, 2421, 3026, 2421, 2085, 1822, 1642, 1495, 1400, 1326, 1294, 1287, 1310, 1357, 1430, 1554, 1706, 1920, 2207, 2661, 2240, 1939, 1714, 1532, 1408, 1310, 1249, 1209, 1199, 1216, 1261, 1328, 1443, 1597, 1783, 2051, 2453, 2126, 1844, 1621, 1457, 1333, 1226, 1164, 1132, 1119, 1136, 1186, 1255, 1365, 1498, 1694, 1949, 2309, 2039, 1762, 1554, 1387, 1270, 1169, 1107, 1072, 1063, 1083, 1125, 1201, 1305, 1441, 1639, 1872, 2201, 1960, 1698, 1507, 1350, 1226, 1132, 1068, 1032, 1027, 1040, 1083, 1160, 1266, 1395, 1560, 1822, 2114, 1920, 1668, 1469, 1310, 1197, 1096, 1038, 1027, 1028, 1032, 1056, 1125, 1230, 1357, 1544, 1762, 2068, 1910, 1679, 1457, 1305, 1182, 1093, 1032, 1024, 1024, 1034, 1045, 1112, 1220, 1348, 1526, 1754, 2051, 1895, 1657, 1455, 1310, 1182, 1088, 1034, 1024, 1024, 1034, 1053, 1117, 1224, 1350, 1529, 1754, 2056, 1939, 1683, 1477, 1314, 1205, 1104, 1047, 1034, 1027, 1038, 1075, 1141, 1239, 1372, 1544, 1779, 2096, 1985, 1725, 1526, 1365, 1237, 1142, 1078, 1048, 1047, 1050, 1112, 1178, 1281, 1416, 1594, 1826, 2144, 2045, 1783, 1580, 1408, 1294, 1197, 1132, 1091, 1080, 1109, 1151, 1228, 1328, 1472, 1664, 1895, 2234, 2138, 1853, 1650, 1472, 1352, 1259, 1191, 1158, 1146, 1171, 1215, 1290, 1400, 1544, 1725, 1996, 2367, 2309, 1975, 1758, 1560, 1449, 1345, 1281, 1239, 1228, 1255, 1290, 1377, 1498, 1639, 1844, 2126, 2579, 2518, 2132, 1876, 1687, 1541, 1438, 1372, 1338, 1324, 1340, 1408, 1472, 1607, 1774, 1975, 2309, 2821, 2909, 2338, 2045, 1826, 1675, 1554, 1492, 1438, 1438, 1463, 1510, 1607, 1745, 1915, 2169, 2527, 3193] + }, + "lsc_samples_blue": { + "uCoeff": [3037, 2469, 2188, 1948, 1756, 1667, 1592, 1529, 1534, 1555, 1615, 1692, 1825, 1999, 2252, 2623, 3394, 2669, 2220, 1948, 1736, 1615, 1504, 1443, 1408, 1387, 1417, 1461, 1539, 1649, 1825, 2052, 2368, 2885, 2469, 2052, 1804, 1637, 1499, 1399, 1327, 1290, 1290, 1297, 1339, 1417, 1524, 1692, 1877, 2148, 2565, 2297, 1940, 1679, 1529, 1399, 1308, 1232, 1200, 1190, 1200, 1255, 1327, 1421, 1565, 1756, 2025, 2392, 2148, 1832, 1615, 1452, 1331, 1228, 1163, 1126, 1118, 1132, 1169, 1241, 1339, 1480, 1673, 1885, 2231, 2034, 1762, 1534, 1387, 1258, 1169, 1107, 1069, 1059, 1074, 1118, 1190, 1283, 1430, 1603, 1811, 2099, 1957, 1698, 1490, 1335, 1225, 1137, 1062, 1038, 1033, 1033, 1074, 1146, 1238, 1370, 1534, 1743, 2071, 1924, 1667, 1475, 1312, 1193, 1097, 1033, 1026, 1026, 1033, 1050, 1124, 1209, 1346, 1524, 1729, 2025, 1924, 1673, 1443, 1294, 1181, 1092, 1033, 1024, 1024, 1033, 1038, 1105, 1206, 1327, 1499, 1698, 1957, 1885, 1632, 1452, 1301, 1193, 1100, 1031, 1033, 1035, 1035, 1047, 1110, 1206, 1335, 1490, 1710, 1957, 1924, 1667, 1475, 1316, 1209, 1118, 1050, 1035, 1045, 1035, 1057, 1126, 1225, 1354, 1509, 1729, 1999, 1957, 1710, 1514, 1366, 1228, 1137, 1087, 1057, 1038, 1057, 1110, 1166, 1248, 1379, 1560, 1797, 2089, 2025, 1790, 1560, 1408, 1294, 1190, 1126, 1084, 1087, 1100, 1146, 1222, 1312, 1434, 1632, 1847, 2178, 2168, 1847, 1632, 1452, 1354, 1248, 1190, 1155, 1146, 1155, 1206, 1276, 1370, 1524, 1698, 1948, 2286, 2275, 1948, 1736, 1560, 1430, 1327, 1272, 1225, 1222, 1232, 1279, 1358, 1461, 1615, 1811, 2080, 2456, 2496, 2089, 1847, 1667, 1529, 1430, 1366, 1335, 1316, 1327, 1379, 1461, 1555, 1756, 1908, 2252, 2748, 2748, 2275, 1948, 1762, 1620, 1539, 1452, 1408, 1395, 1421, 1457, 1550, 1673, 1869, 2080, 2392, 2979] + } + }, { + "name": "2592x1944_D65_70", + "resolution": "2592x1944", + "illumination": "D65", + "vignetting": 70, + "lsc_samples_red": { + "uCoeff": [2670, 2202, 1986, 1827, 1710, 1621, 1539, 1505, 1501, 1499, 1565, 1619, 1733, 1893, 2079, 2386, 2928, 2316, 2024, 1856, 1693, 1587, 1495, 1426, 1404, 1384, 1398, 1443, 1533, 1629, 1766, 1937, 2162, 2616, 2148, 1906, 1722, 1582, 1478, 1392, 1332, 1303, 1290, 1293, 1347, 1419, 1528, 1648, 1801, 2028, 2336, 2088, 1831, 1646, 1511, 1397, 1311, 1248, 1208, 1201, 1204, 1269, 1324, 1435, 1561, 1713, 1915, 2184, 1984, 1745, 1578, 1430, 1308, 1227, 1175, 1136, 1129, 1146, 1190, 1274, 1346, 1500, 1633, 1834, 2114, 1948, 1691, 1507, 1376, 1262, 1170, 1111, 1079, 1067, 1096, 1129, 1213, 1308, 1422, 1561, 1773, 2017, 1849, 1635, 1476, 1329, 1218, 1131, 1069, 1042, 1027, 1051, 1096, 1157, 1260, 1384, 1543, 1718, 1984, 1817, 1619, 1443, 1303, 1200, 1116, 1048, 1027, 1033, 1039, 1053, 1136, 1228, 1361, 1508, 1700, 1922, 1789, 1618, 1427, 1300, 1185, 1088, 1039, 1033, 1024, 1036, 1048, 1118, 1232, 1347, 1484, 1660, 1904, 1791, 1589, 1426, 1304, 1193, 1098, 1036, 1024, 1036, 1036, 1064, 1118, 1224, 1357, 1494, 1661, 1900, 1811, 1615, 1446, 1311, 1211, 1118, 1042, 1048, 1033, 1048, 1066, 1146, 1249, 1374, 1531, 1696, 1925, 1852, 1643, 1488, 1357, 1241, 1149, 1085, 1053, 1039, 1066, 1118, 1182, 1271, 1397, 1537, 1756, 1968, 1908, 1696, 1524, 1392, 1286, 1203, 1139, 1102, 1098, 1116, 1149, 1231, 1327, 1452, 1597, 1776, 2051, 1964, 1750, 1589, 1451, 1346, 1261, 1203, 1162, 1152, 1170, 1210, 1287, 1369, 1497, 1659, 1868, 2164, 2061, 1819, 1661, 1519, 1415, 1343, 1277, 1241, 1229, 1241, 1286, 1372, 1449, 1597, 1759, 1949, 2227, 2185, 1937, 1765, 1618, 1503, 1426, 1364, 1344, 1320, 1347, 1396, 1454, 1546, 1692, 1867, 2088, 2380, 2441, 2077, 1882, 1741, 1608, 1513, 1471, 1442, 1414, 1436, 1491, 1557, 1654, 1769, 1945, 2260, 2788] + }, + "lsc_samples_greenR": { + "uCoeff": [2471, 2136, 1928, 1765, 1665, 1580, 1515, 1480, 1462, 1488, 1519, 1582, 1695, 1826, 2000, 2275, 2796, 2235, 1986, 1802, 1649, 1550, 1474, 1410, 1364, 1374, 1378, 1429, 1487, 1584, 1712, 1880, 2122, 2482, 2066, 1851, 1697, 1558, 1450, 1372, 1309, 1281, 1273, 1280, 1322, 1398, 1489, 1601, 1757, 1962, 2239, 1976, 1769, 1610, 1473, 1366, 1297, 1229, 1194, 1175, 1206, 1249, 1320, 1412, 1529, 1677, 1856, 2092, 1893, 1701, 1555, 1407, 1299, 1228, 1164, 1131, 1113, 1142, 1173, 1247, 1341, 1452, 1595, 1777, 1999, 1816, 1647, 1485, 1359, 1256, 1167, 1101, 1071, 1061, 1076, 1122, 1197, 1299, 1403, 1543, 1727, 1929, 1780, 1597, 1447, 1320, 1219, 1130, 1060, 1037, 1039, 1042, 1084, 1150, 1244, 1354, 1508, 1669, 1895, 1752, 1574, 1417, 1289, 1186, 1103, 1046, 1034, 1024, 1033, 1054, 1126, 1223, 1332, 1486, 1643, 1861, 1753, 1584, 1415, 1284, 1172, 1086, 1031, 1031, 1024, 1027, 1042, 1119, 1211, 1334, 1472, 1635, 1840, 1737, 1561, 1409, 1286, 1181, 1091, 1031, 1033, 1031, 1031, 1045, 1115, 1205, 1321, 1473, 1644, 1872, 1769, 1585, 1442, 1309, 1201, 1110, 1049, 1031, 1031, 1037, 1063, 1135, 1232, 1353, 1495, 1668, 1863, 1807, 1611, 1461, 1338, 1228, 1132, 1078, 1054, 1042, 1053, 1119, 1173, 1262, 1379, 1513, 1699, 1906, 1868, 1664, 1504, 1382, 1269, 1191, 1125, 1094, 1085, 1101, 1143, 1211, 1306, 1405, 1570, 1739, 1969, 1924, 1709, 1543, 1433, 1326, 1244, 1189, 1156, 1148, 1165, 1202, 1268, 1361, 1481, 1626, 1797, 2061, 2012, 1790, 1628, 1506, 1405, 1325, 1270, 1225, 1218, 1235, 1278, 1348, 1433, 1548, 1692, 1906, 2188, 2132, 1888, 1706, 1584, 1472, 1394, 1346, 1321, 1304, 1330, 1376, 1433, 1525, 1648, 1802, 2033, 2319, 2344, 2014, 1843, 1705, 1581, 1503, 1440, 1405, 1404, 1413, 1452, 1522, 1599, 1746, 1914, 2134, 2602] + }, + "lsc_samples_greenB": { + "uCoeff": [2445, 2084, 1906, 1757, 1655, 1558, 1520, 1492, 1479, 1483, 1538, 1584, 1696, 1826, 2000, 2264, 2774, 2233, 1968, 1793, 1647, 1541, 1467, 1407, 1380, 1362, 1380, 1422, 1496, 1586, 1714, 1860, 2099, 2447, 2051, 1857, 1690, 1557, 1440, 1372, 1316, 1277, 1267, 1286, 1330, 1387, 1482, 1599, 1753, 1955, 2254, 1957, 1756, 1597, 1466, 1369, 1284, 1228, 1193, 1190, 1207, 1246, 1317, 1403, 1521, 1670, 1861, 2112, 1893, 1690, 1527, 1404, 1302, 1216, 1158, 1123, 1120, 1129, 1179, 1245, 1336, 1457, 1590, 1769, 2024, 1817, 1637, 1474, 1354, 1252, 1162, 1107, 1074, 1053, 1077, 1120, 1194, 1290, 1411, 1552, 1707, 1946, 1785, 1591, 1437, 1313, 1210, 1127, 1062, 1033, 1033, 1037, 1080, 1148, 1240, 1369, 1511, 1683, 1890, 1748, 1562, 1408, 1302, 1183, 1091, 1039, 1030, 1036, 1030, 1057, 1123, 1211, 1342, 1467, 1654, 1861, 1749, 1576, 1404, 1280, 1173, 1084, 1033, 1028, 1024, 1033, 1044, 1111, 1216, 1318, 1457, 1637, 1836, 1721, 1552, 1403, 1282, 1173, 1084, 1030, 1028, 1025, 1033, 1053, 1120, 1208, 1324, 1476, 1615, 1857, 1756, 1562, 1421, 1295, 1190, 1103, 1044, 1030, 1031, 1037, 1065, 1140, 1220, 1346, 1481, 1646, 1881, 1778, 1606, 1458, 1324, 1224, 1135, 1079, 1049, 1040, 1054, 1108, 1170, 1256, 1369, 1521, 1687, 1941, 1837, 1650, 1494, 1376, 1270, 1188, 1122, 1096, 1079, 1097, 1141, 1216, 1307, 1424, 1560, 1744, 1975, 1902, 1693, 1545, 1417, 1319, 1245, 1188, 1155, 1143, 1157, 1201, 1273, 1362, 1475, 1617, 1798, 2034, 1962, 1781, 1622, 1479, 1391, 1314, 1260, 1226, 1219, 1236, 1274, 1344, 1427, 1554, 1694, 1890, 2163, 2087, 1872, 1707, 1576, 1468, 1403, 1346, 1314, 1300, 1328, 1360, 1426, 1511, 1654, 1793, 1995, 2307, 2304, 2014, 1808, 1661, 1548, 1477, 1451, 1410, 1404, 1412, 1449, 1515, 1620, 1733, 1931, 2140, 2528] + }, + "lsc_samples_blue": { + "uCoeff": [2415, 2113, 1872, 1761, 1666, 1553, 1504, 1471, 1465, 1468, 1521, 1585, 1697, 1815, 1983, 2218, 2673, 2221, 1935, 1769, 1621, 1533, 1452, 1391, 1370, 1362, 1359, 1413, 1480, 1568, 1671, 1839, 2061, 2366, 2081, 1835, 1682, 1533, 1430, 1359, 1308, 1274, 1275, 1273, 1318, 1388, 1460, 1583, 1730, 1914, 2168, 1973, 1749, 1589, 1461, 1362, 1284, 1224, 1190, 1180, 1195, 1234, 1303, 1382, 1501, 1641, 1811, 2081, 1840, 1701, 1512, 1400, 1288, 1209, 1152, 1122, 1120, 1131, 1164, 1238, 1317, 1432, 1580, 1742, 1941, 1798, 1619, 1484, 1363, 1251, 1170, 1108, 1079, 1062, 1066, 1112, 1185, 1273, 1393, 1513, 1685, 1885, 1775, 1577, 1431, 1323, 1215, 1121, 1066, 1034, 1030, 1032, 1079, 1140, 1223, 1336, 1458, 1632, 1841, 1752, 1569, 1412, 1288, 1184, 1106, 1032, 1030, 1034, 1032, 1050, 1120, 1209, 1316, 1444, 1616, 1799, 1747, 1568, 1405, 1270, 1166, 1083, 1032, 1026, 1024, 1032, 1043, 1107, 1194, 1307, 1442, 1598, 1797, 1743, 1549, 1392, 1269, 1177, 1090, 1041, 1032, 1030, 1034, 1047, 1110, 1203, 1296, 1439, 1604, 1772, 1739, 1545, 1413, 1296, 1197, 1112, 1047, 1041, 1036, 1041, 1063, 1124, 1221, 1327, 1448, 1636, 1792, 1775, 1590, 1446, 1315, 1213, 1133, 1083, 1057, 1043, 1046, 1110, 1167, 1247, 1347, 1493, 1652, 1863, 1803, 1652, 1479, 1360, 1271, 1180, 1121, 1094, 1087, 1097, 1133, 1201, 1291, 1394, 1533, 1701, 1923, 1873, 1675, 1520, 1403, 1315, 1234, 1191, 1154, 1142, 1156, 1196, 1263, 1333, 1448, 1577, 1770, 2007, 1992, 1761, 1604, 1480, 1390, 1300, 1238, 1218, 1206, 1230, 1268, 1325, 1402, 1509, 1658, 1860, 2096, 2101, 1860, 1697, 1540, 1462, 1389, 1333, 1294, 1283, 1302, 1346, 1415, 1499, 1637, 1756, 1965, 2222, 2216, 1928, 1762, 1627, 1516, 1467, 1387, 1354, 1355, 1372, 1415, 1473, 1582, 1670, 1845, 2046, 2538] + } + }, { + "name": "2592x1944_D65_100", + "resolution": "2592x1944", + "illumination": "D65", + "vignetting": 100, + "lsc_samples_red": { + "uCoeff": [3335, 2582, 2240, 2000, 1834, 1711, 1610, 1567, 1560, 1560, 1639, 1711, 1863, 2082, 2359, 2829, 3720, 2785, 2313, 2046, 1816, 1670, 1553, 1469, 1440, 1417, 1434, 1488, 1595, 1719, 1903, 2145, 2491, 3185, 2509, 2132, 1863, 1670, 1533, 1428, 1357, 1322, 1307, 1312, 1373, 1457, 1588, 1744, 1956, 2283, 2763, 2391, 2011, 1753, 1574, 1434, 1332, 1261, 1217, 1209, 1213, 1283, 1347, 1476, 1632, 1834, 2119, 2527, 2240, 1893, 1662, 1476, 1332, 1239, 1181, 1139, 1132, 1150, 1197, 1288, 1373, 1553, 1727, 2000, 2407, 2171, 1816, 1574, 1411, 1279, 1177, 1114, 1080, 1067, 1097, 1132, 1221, 1327, 1463, 1639, 1914, 2268, 2046, 1744, 1533, 1357, 1230, 1135, 1070, 1042, 1027, 1051, 1097, 1162, 1274, 1417, 1610, 1844, 2212, 2000, 1719, 1494, 1327, 1209, 1118, 1048, 1027, 1033, 1039, 1054, 1139, 1239, 1389, 1567, 1816, 2132, 1967, 1719, 1476, 1322, 1193, 1090, 1039, 1033, 1024, 1036, 1048, 1121, 1243, 1373, 1540, 1770, 2107, 1967, 1686, 1476, 1327, 1201, 1100, 1036, 1024, 1036, 1036, 1064, 1121, 1234, 1384, 1553, 1770, 2107, 2000, 1719, 1501, 1337, 1221, 1121, 1042, 1048, 1033, 1048, 1067, 1150, 1261, 1405, 1595, 1816, 2145, 2058, 1761, 1553, 1389, 1256, 1154, 1087, 1054, 1039, 1067, 1121, 1189, 1288, 1434, 1610, 1893, 2212, 2145, 1834, 1602, 1434, 1307, 1213, 1143, 1104, 1100, 1118, 1154, 1243, 1352, 1501, 1686, 1934, 2328, 2240, 1914, 1686, 1507, 1378, 1279, 1213, 1169, 1158, 1177, 1221, 1307, 1405, 1560, 1770, 2058, 2491, 2391, 2023, 1788, 1595, 1463, 1373, 1297, 1256, 1243, 1256, 1307, 1405, 1501, 1686, 1903, 2185, 2620, 2601, 2198, 1934, 1727, 1574, 1476, 1400, 1373, 1347, 1378, 1434, 1507, 1624, 1816, 2058, 2391, 2875, 3022, 2423, 2107, 1893, 1711, 1588, 1533, 1494, 1463, 1488, 1553, 1639, 1770, 1934, 2198, 2660, 3499] + }, + "lsc_samples_greenR": { + "uCoeff": [3086, 2504, 2175, 1933, 1786, 1668, 1585, 1541, 1519, 1548, 1591, 1672, 1822, 2008, 2270, 2698, 3552, 2688, 2270, 1986, 1769, 1631, 1531, 1452, 1399, 1407, 1413, 1473, 1548, 1672, 1845, 2082, 2445, 3022, 2413, 2070, 1836, 1645, 1503, 1407, 1333, 1299, 1290, 1299, 1347, 1435, 1548, 1695, 1908, 2208, 2649, 2263, 1943, 1715, 1535, 1402, 1318, 1242, 1203, 1183, 1215, 1263, 1343, 1452, 1598, 1795, 2053, 2421, 2137, 1845, 1638, 1452, 1323, 1240, 1170, 1134, 1116, 1146, 1180, 1261, 1368, 1503, 1687, 1938, 2277, 2024, 1769, 1551, 1394, 1272, 1174, 1103, 1072, 1061, 1077, 1125, 1205, 1318, 1443, 1620, 1864, 2169, 1970, 1703, 1503, 1347, 1231, 1134, 1061, 1037, 1039, 1042, 1085, 1155, 1257, 1386, 1574, 1791, 2112, 1928, 1672, 1467, 1313, 1195, 1105, 1046, 1034, 1024, 1033, 1055, 1129, 1234, 1360, 1544, 1756, 2064, 1928, 1683, 1464, 1306, 1180, 1088, 1031, 1031, 1024, 1027, 1042, 1122, 1221, 1360, 1528, 1744, 2036, 1908, 1657, 1458, 1309, 1189, 1093, 1031, 1033, 1031, 1031, 1045, 1118, 1215, 1347, 1531, 1752, 2076, 1954, 1687, 1497, 1335, 1211, 1113, 1049, 1031, 1031, 1037, 1064, 1139, 1244, 1383, 1557, 1786, 2076, 2008, 1727, 1525, 1370, 1242, 1137, 1080, 1055, 1042, 1054, 1122, 1180, 1279, 1415, 1585, 1831, 2143, 2100, 1800, 1581, 1424, 1290, 1201, 1129, 1096, 1087, 1103, 1148, 1223, 1330, 1452, 1657, 1893, 2235, 2195, 1869, 1638, 1488, 1357, 1261, 1199, 1163, 1154, 1172, 1213, 1288, 1396, 1544, 1735, 1980, 2373, 2335, 1991, 1752, 1581, 1452, 1355, 1290, 1240, 1231, 1250, 1299, 1381, 1485, 1634, 1831, 2137, 2574, 2538, 2143, 1869, 1691, 1541, 1443, 1381, 1350, 1330, 1360, 1413, 1485, 1602, 1769, 1986, 2328, 2802, 2902, 2350, 2064, 1854, 1683, 1578, 1500, 1455, 1452, 1464, 1512, 1602, 1711, 1908, 2162, 2512, 3266] + }, + "lsc_samples_greenB": { + "uCoeff": [3054, 2444, 2150, 1924, 1775, 1644, 1590, 1553, 1537, 1543, 1611, 1674, 1824, 2009, 2270, 2685, 3524, 2685, 2249, 1976, 1767, 1622, 1524, 1449, 1415, 1394, 1415, 1466, 1557, 1674, 1847, 2059, 2419, 2980, 2396, 2077, 1828, 1644, 1493, 1407, 1340, 1295, 1284, 1305, 1355, 1424, 1540, 1693, 1904, 2201, 2666, 2242, 1929, 1701, 1527, 1405, 1305, 1241, 1202, 1198, 1216, 1260, 1340, 1443, 1590, 1788, 2059, 2444, 2137, 1833, 1608, 1449, 1326, 1228, 1164, 1126, 1123, 1133, 1186, 1258, 1363, 1509, 1682, 1929, 2305, 2025, 1758, 1540, 1389, 1268, 1169, 1109, 1075, 1053, 1078, 1123, 1202, 1309, 1452, 1629, 1842, 2188, 1976, 1697, 1493, 1340, 1222, 1131, 1063, 1033, 1033, 1037, 1081, 1153, 1253, 1402, 1577, 1806, 2107, 1924, 1659, 1458, 1326, 1192, 1093, 1039, 1030, 1036, 1030, 1058, 1126, 1222, 1370, 1524, 1767, 2065, 1924, 1674, 1452, 1302, 1181, 1086, 1033, 1028, 1024, 1033, 1044, 1114, 1226, 1343, 1512, 1746, 2031, 1890, 1647, 1452, 1305, 1181, 1086, 1030, 1028, 1025, 1033, 1053, 1123, 1218, 1350, 1534, 1721, 2059, 1939, 1662, 1475, 1321, 1200, 1106, 1044, 1030, 1031, 1037, 1066, 1144, 1232, 1376, 1543, 1762, 2095, 1976, 1721, 1521, 1355, 1238, 1140, 1081, 1050, 1040, 1055, 1111, 1177, 1273, 1405, 1594, 1819, 2182, 2065, 1784, 1570, 1418, 1291, 1198, 1126, 1098, 1081, 1099, 1146, 1228, 1331, 1472, 1647, 1899, 2242, 2169, 1851, 1640, 1472, 1350, 1262, 1198, 1162, 1149, 1164, 1212, 1293, 1397, 1537, 1725, 1981, 2342, 2277, 1981, 1746, 1553, 1438, 1343, 1280, 1241, 1232, 1251, 1295, 1376, 1478, 1640, 1833, 2119, 2545, 2485, 2125, 1870, 1682, 1537, 1452, 1381, 1343, 1326, 1358, 1397, 1478, 1587, 1775, 1976, 2284, 2787, 2852, 2350, 2025, 1806, 1647, 1550, 1512, 1460, 1452, 1463, 1509, 1594, 1733, 1894, 2182, 2519, 3173] + }, + "lsc_samples_blue": { + "uCoeff": [3017, 2478, 2111, 1928, 1787, 1639, 1574, 1531, 1522, 1527, 1593, 1676, 1825, 1996, 2250, 2630, 3396, 2671, 2211, 1950, 1739, 1613, 1509, 1433, 1405, 1394, 1394, 1457, 1540, 1655, 1800, 2036, 2375, 2881, 2431, 2052, 1819, 1618, 1483, 1394, 1332, 1292, 1292, 1292, 1343, 1425, 1518, 1676, 1879, 2155, 2565, 2260, 1921, 1693, 1522, 1398, 1305, 1236, 1199, 1188, 1204, 1248, 1326, 1421, 1569, 1757, 2004, 2408, 2077, 1845, 1593, 1445, 1312, 1221, 1158, 1125, 1123, 1135, 1171, 1251, 1343, 1483, 1671, 1900, 2211, 2004, 1739, 1550, 1398, 1267, 1177, 1110, 1080, 1062, 1067, 1115, 1193, 1292, 1433, 1588, 1819, 2120, 1965, 1682, 1487, 1350, 1227, 1125, 1067, 1034, 1030, 1032, 1080, 1145, 1236, 1368, 1522, 1751, 2052, 1928, 1666, 1462, 1312, 1193, 1108, 1032, 1030, 1034, 1032, 1051, 1123, 1219, 1343, 1500, 1727, 1996, 1921, 1666, 1453, 1292, 1174, 1085, 1032, 1026, 1024, 1032, 1043, 1110, 1204, 1332, 1496, 1704, 1988, 1914, 1644, 1441, 1292, 1185, 1092, 1041, 1032, 1030, 1034, 1047, 1113, 1213, 1322, 1496, 1710, 1965, 1921, 1644, 1466, 1322, 1207, 1115, 1047, 1041, 1036, 1041, 1064, 1128, 1233, 1357, 1509, 1751, 1996, 1973, 1704, 1509, 1346, 1227, 1138, 1085, 1058, 1043, 1047, 1113, 1174, 1264, 1383, 1564, 1781, 2094, 2027, 1787, 1554, 1402, 1292, 1190, 1125, 1096, 1089, 1099, 1138, 1213, 1315, 1441, 1618, 1852, 2183, 2137, 1832, 1613, 1457, 1346, 1251, 1201, 1161, 1148, 1163, 1207, 1283, 1368, 1509, 1682, 1950, 2311, 2311, 1958, 1727, 1554, 1437, 1329, 1257, 1233, 1219, 1245, 1289, 1357, 1453, 1593, 1794, 2085, 2466, 2502, 2111, 1859, 1644, 1531, 1437, 1368, 1322, 1309, 1332, 1383, 1466, 1574, 1757, 1936, 2250, 2685, 2743, 2250, 1973, 1769, 1613, 1540, 1445, 1402, 1402, 1421, 1474, 1550, 1693, 1825, 2085, 2408, 3185] + } + }, { + "name": "2592x1944_D75_70", + "resolution": "2592x1944", + "illumination": "D75", + "vignetting": 70, + "lsc_samples_red": { + "uCoeff": [2700, 2201, 1991, 1850, 1725, 1634, 1552, 1532, 1529, 1543, 1582, 1675, 1787, 1899, 2105, 2428, 2974, 2376, 2081, 1847, 1694, 1586, 1504, 1446, 1401, 1389, 1420, 1459, 1531, 1643, 1768, 1963, 2191, 2642, 2159, 1947, 1751, 1609, 1489, 1386, 1340, 1302, 1294, 1318, 1357, 1423, 1526, 1643, 1836, 2041, 2385, 2075, 1842, 1663, 1522, 1409, 1313, 1247, 1210, 1193, 1224, 1262, 1333, 1433, 1567, 1714, 1936, 2206, 1990, 1756, 1586, 1436, 1331, 1237, 1178, 1135, 1125, 1146, 1197, 1266, 1375, 1486, 1638, 1858, 2091, 1920, 1694, 1529, 1391, 1275, 1187, 1126, 1083, 1068, 1097, 1141, 1207, 1310, 1438, 1585, 1778, 2008, 1839, 1647, 1475, 1345, 1229, 1134, 1077, 1042, 1034, 1056, 1097, 1159, 1258, 1389, 1551, 1734, 1959, 1846, 1619, 1459, 1314, 1205, 1111, 1050, 1034, 1037, 1037, 1069, 1141, 1230, 1369, 1509, 1726, 1932, 1809, 1632, 1450, 1311, 1189, 1102, 1037, 1032, 1032, 1042, 1050, 1125, 1223, 1352, 1505, 1683, 1915, 1814, 1600, 1449, 1315, 1192, 1102, 1042, 1024, 1034, 1042, 1058, 1135, 1226, 1356, 1498, 1683, 1934, 1853, 1628, 1456, 1330, 1211, 1116, 1056, 1037, 1034, 1048, 1074, 1146, 1247, 1366, 1522, 1721, 1975, 1885, 1660, 1497, 1364, 1242, 1144, 1090, 1060, 1058, 1068, 1128, 1180, 1283, 1409, 1556, 1749, 1992, 1936, 1711, 1527, 1404, 1296, 1202, 1146, 1105, 1096, 1119, 1165, 1237, 1331, 1462, 1602, 1808, 2058, 2017, 1772, 1599, 1470, 1356, 1270, 1202, 1171, 1161, 1180, 1222, 1288, 1396, 1511, 1668, 1883, 2147, 2105, 1839, 1675, 1545, 1429, 1343, 1288, 1257, 1238, 1244, 1307, 1364, 1474, 1596, 1751, 1962, 2240, 2215, 1967, 1772, 1624, 1515, 1433, 1376, 1336, 1333, 1349, 1409, 1474, 1571, 1709, 1875, 2088, 2417, 2430, 2089, 1873, 1733, 1601, 1528, 1468, 1426, 1434, 1448, 1476, 1556, 1656, 1781, 1950, 2198, 2681] + }, + "lsc_samples_greenR": { + "uCoeff": [2535, 2135, 1912, 1786, 1662, 1583, 1524, 1480, 1469, 1488, 1538, 1603, 1718, 1830, 2003, 2282, 2802, 2278, 1980, 1808, 1665, 1544, 1479, 1417, 1379, 1364, 1380, 1426, 1493, 1585, 1715, 1874, 2114, 2462, 2084, 1873, 1699, 1568, 1454, 1374, 1317, 1284, 1282, 1290, 1335, 1395, 1486, 1600, 1757, 1962, 2252, 1975, 1778, 1609, 1476, 1368, 1288, 1235, 1196, 1188, 1203, 1250, 1314, 1406, 1524, 1670, 1854, 2121, 1901, 1704, 1552, 1410, 1296, 1218, 1168, 1131, 1124, 1138, 1179, 1250, 1336, 1459, 1596, 1781, 2023, 1840, 1648, 1491, 1362, 1251, 1164, 1105, 1072, 1061, 1082, 1121, 1195, 1286, 1404, 1550, 1737, 1933, 1822, 1600, 1454, 1319, 1214, 1123, 1062, 1037, 1033, 1039, 1082, 1150, 1250, 1358, 1498, 1677, 1903, 1753, 1575, 1420, 1296, 1191, 1099, 1039, 1025, 1030, 1027, 1055, 1125, 1215, 1334, 1478, 1656, 1866, 1755, 1590, 1417, 1281, 1178, 1088, 1035, 1029, 1027, 1032, 1042, 1118, 1209, 1321, 1455, 1637, 1863, 1757, 1562, 1416, 1290, 1179, 1089, 1038, 1030, 1024, 1033, 1049, 1116, 1210, 1329, 1481, 1641, 1853, 1780, 1583, 1428, 1302, 1198, 1106, 1050, 1035, 1030, 1035, 1064, 1138, 1226, 1349, 1499, 1665, 1880, 1790, 1612, 1461, 1329, 1225, 1138, 1076, 1050, 1045, 1052, 1112, 1171, 1260, 1379, 1511, 1687, 1908, 1857, 1666, 1507, 1376, 1268, 1186, 1132, 1098, 1082, 1098, 1145, 1215, 1310, 1417, 1568, 1743, 1977, 1929, 1718, 1562, 1433, 1325, 1251, 1193, 1155, 1149, 1156, 1203, 1275, 1367, 1482, 1630, 1811, 2087, 1994, 1796, 1622, 1502, 1403, 1322, 1267, 1233, 1217, 1230, 1278, 1351, 1438, 1556, 1707, 1891, 2184, 2147, 1890, 1733, 1585, 1492, 1403, 1347, 1308, 1312, 1332, 1365, 1427, 1522, 1665, 1803, 2009, 2331, 2332, 2008, 1840, 1686, 1566, 1501, 1447, 1413, 1405, 1418, 1463, 1528, 1625, 1735, 1904, 2171, 2526] + }, + "lsc_samples_greenB": { + "uCoeff": [2470, 2133, 1923, 1764, 1673, 1584, 1534, 1475, 1464, 1482, 1537, 1596, 1690, 1817, 2026, 2271, 2811, 2246, 1976, 1794, 1662, 1559, 1469, 1407, 1376, 1366, 1393, 1437, 1493, 1587, 1712, 1885, 2101, 2455, 2071, 1852, 1696, 1561, 1452, 1371, 1317, 1282, 1274, 1290, 1330, 1403, 1489, 1625, 1769, 1964, 2243, 1971, 1773, 1600, 1477, 1374, 1291, 1231, 1197, 1190, 1201, 1250, 1309, 1402, 1523, 1671, 1866, 2145, 1903, 1682, 1534, 1414, 1304, 1221, 1162, 1128, 1113, 1138, 1177, 1254, 1333, 1457, 1610, 1771, 2008, 1824, 1628, 1494, 1355, 1252, 1169, 1104, 1073, 1060, 1084, 1122, 1191, 1290, 1396, 1552, 1718, 1965, 1787, 1598, 1444, 1324, 1219, 1124, 1069, 1034, 1035, 1038, 1080, 1158, 1242, 1364, 1506, 1678, 1924, 1773, 1567, 1419, 1296, 1192, 1096, 1042, 1025, 1032, 1032, 1054, 1122, 1222, 1336, 1483, 1649, 1849, 1735, 1582, 1408, 1286, 1176, 1088, 1035, 1025, 1025, 1034, 1048, 1113, 1214, 1326, 1469, 1641, 1843, 1744, 1564, 1405, 1284, 1178, 1094, 1035, 1025, 1024, 1030, 1051, 1116, 1213, 1329, 1470, 1625, 1837, 1750, 1575, 1417, 1298, 1191, 1108, 1048, 1029, 1029, 1042, 1066, 1135, 1231, 1346, 1499, 1662, 1881, 1798, 1610, 1464, 1328, 1220, 1142, 1081, 1053, 1037, 1054, 1113, 1166, 1263, 1374, 1522, 1688, 1920, 1837, 1663, 1492, 1382, 1268, 1188, 1121, 1093, 1090, 1099, 1143, 1211, 1304, 1424, 1567, 1743, 1984, 1891, 1707, 1558, 1432, 1325, 1246, 1186, 1150, 1144, 1159, 1206, 1277, 1359, 1479, 1621, 1815, 2075, 2006, 1786, 1624, 1500, 1401, 1319, 1262, 1227, 1218, 1238, 1282, 1339, 1433, 1558, 1696, 1894, 2182, 2094, 1892, 1702, 1583, 1472, 1399, 1347, 1314, 1302, 1316, 1354, 1428, 1518, 1662, 1794, 2010, 2311, 2295, 2003, 1820, 1672, 1563, 1490, 1435, 1420, 1399, 1410, 1464, 1516, 1620, 1747, 1910, 2150, 2605] + }, + "lsc_samples_blue": { + "uCoeff": [2474, 2080, 1883, 1755, 1653, 1574, 1502, 1482, 1454, 1471, 1528, 1609, 1696, 1818, 1978, 2235, 2738, 2238, 1934, 1775, 1631, 1541, 1449, 1396, 1372, 1365, 1365, 1411, 1484, 1573, 1683, 1847, 2041, 2406, 2069, 1854, 1662, 1537, 1435, 1360, 1307, 1271, 1263, 1271, 1314, 1378, 1465, 1581, 1734, 1919, 2190, 1955, 1748, 1597, 1451, 1365, 1284, 1217, 1190, 1178, 1188, 1235, 1293, 1383, 1505, 1632, 1817, 2050, 1882, 1696, 1518, 1395, 1302, 1209, 1156, 1125, 1110, 1132, 1167, 1235, 1324, 1435, 1568, 1728, 1950, 1830, 1623, 1473, 1352, 1249, 1161, 1107, 1069, 1059, 1071, 1110, 1185, 1266, 1383, 1520, 1675, 1894, 1763, 1579, 1435, 1317, 1218, 1122, 1069, 1032, 1035, 1037, 1071, 1133, 1224, 1336, 1473, 1632, 1833, 1744, 1559, 1406, 1281, 1184, 1096, 1038, 1037, 1037, 1030, 1051, 1121, 1204, 1312, 1439, 1605, 1803, 1731, 1562, 1399, 1275, 1176, 1087, 1032, 1029, 1024, 1037, 1045, 1104, 1196, 1298, 1434, 1592, 1784, 1719, 1547, 1398, 1274, 1177, 1095, 1040, 1035, 1032, 1037, 1047, 1110, 1194, 1310, 1433, 1596, 1794, 1742, 1551, 1416, 1297, 1194, 1114, 1047, 1038, 1030, 1043, 1055, 1118, 1213, 1315, 1447, 1613, 1805, 1779, 1587, 1443, 1324, 1223, 1136, 1093, 1055, 1045, 1050, 1106, 1159, 1244, 1356, 1488, 1647, 1841, 1844, 1653, 1484, 1359, 1269, 1185, 1122, 1087, 1086, 1095, 1139, 1204, 1281, 1385, 1526, 1694, 1902, 1896, 1698, 1535, 1413, 1322, 1232, 1183, 1146, 1138, 1149, 1188, 1255, 1338, 1451, 1579, 1749, 1981, 1985, 1755, 1601, 1485, 1375, 1306, 1253, 1218, 1206, 1227, 1259, 1321, 1412, 1512, 1672, 1844, 2085, 2100, 1859, 1684, 1551, 1467, 1377, 1323, 1303, 1292, 1307, 1345, 1409, 1490, 1627, 1760, 1956, 2229, 2231, 1922, 1767, 1622, 1516, 1450, 1399, 1358, 1355, 1361, 1416, 1471, 1563, 1704, 1832, 2055, 2423] + } + }, { + "name": "2592x1944_D75_100", + "resolution": "2592x1944", + "illumination": "D75", + "vignetting": 100, + "lsc_samples_red": { + "uCoeff": [3378, 2589, 2248, 2026, 1852, 1727, 1625, 1593, 1587, 1605, 1657, 1772, 1921, 2088, 2393, 2880, 3784, 2860, 2379, 2036, 1819, 1671, 1563, 1489, 1437, 1422, 1457, 1505, 1593, 1734, 1904, 2177, 2525, 3219, 2525, 2177, 1895, 1699, 1545, 1422, 1365, 1321, 1312, 1338, 1383, 1462, 1587, 1742, 1996, 2299, 2820, 2379, 2026, 1772, 1587, 1447, 1334, 1260, 1219, 1201, 1233, 1276, 1356, 1473, 1638, 1835, 2142, 2557, 2248, 1904, 1671, 1483, 1356, 1249, 1184, 1138, 1128, 1150, 1204, 1280, 1402, 1539, 1734, 2026, 2379, 2142, 1819, 1599, 1427, 1292, 1194, 1128, 1084, 1069, 1098, 1144, 1215, 1329, 1478, 1664, 1921, 2261, 2036, 1757, 1533, 1374, 1241, 1138, 1078, 1042, 1034, 1056, 1098, 1164, 1272, 1422, 1618, 1860, 2188, 2036, 1720, 1511, 1338, 1215, 1113, 1050, 1034, 1037, 1037, 1069, 1144, 1241, 1397, 1569, 1844, 2142, 1987, 1734, 1500, 1334, 1197, 1104, 1037, 1032, 1032, 1042, 1050, 1128, 1233, 1379, 1563, 1795, 2120, 1996, 1699, 1500, 1338, 1201, 1104, 1042, 1024, 1034, 1042, 1058, 1138, 1237, 1383, 1557, 1795, 2142, 2046, 1734, 1511, 1356, 1222, 1119, 1056, 1037, 1034, 1048, 1075, 1150, 1260, 1397, 1587, 1844, 2200, 2099, 1780, 1563, 1397, 1256, 1150, 1092, 1061, 1058, 1069, 1131, 1187, 1300, 1447, 1631, 1886, 2236, 2177, 1852, 1605, 1447, 1317, 1212, 1150, 1107, 1098, 1122, 1170, 1249, 1356, 1511, 1692, 1968, 2338, 2299, 1940, 1699, 1528, 1388, 1288, 1212, 1177, 1167, 1187, 1233, 1308, 1432, 1575, 1780, 2077, 2479, 2450, 2046, 1803, 1625, 1478, 1374, 1308, 1272, 1252, 1260, 1329, 1397, 1528, 1685, 1895, 2200, 2639, 2639, 2236, 1940, 1734, 1587, 1483, 1412, 1365, 1360, 1379, 1447, 1528, 1651, 1835, 2067, 2393, 2921, 3007, 2435, 2099, 1886, 1706, 1605, 1528, 1478, 1483, 1500, 1539, 1638, 1772, 1949, 2200, 2589, 3378] + }, + "lsc_samples_greenR": { + "uCoeff": [3171, 2511, 2159, 1956, 1784, 1673, 1596, 1539, 1525, 1548, 1611, 1696, 1847, 2012, 2277, 2707, 3565, 2742, 2264, 1993, 1788, 1627, 1537, 1459, 1414, 1397, 1416, 1471, 1554, 1673, 1847, 2078, 2437, 2999, 2437, 2094, 1839, 1656, 1509, 1409, 1341, 1303, 1299, 1309, 1361, 1433, 1545, 1696, 1911, 2210, 2663, 2264, 1956, 1714, 1539, 1404, 1309, 1248, 1205, 1196, 1212, 1264, 1337, 1446, 1593, 1788, 2052, 2459, 2148, 1847, 1636, 1456, 1320, 1230, 1174, 1134, 1127, 1142, 1186, 1264, 1363, 1511, 1690, 1942, 2302, 2052, 1769, 1560, 1397, 1267, 1171, 1107, 1073, 1062, 1083, 1124, 1203, 1305, 1443, 1627, 1876, 2176, 2017, 1707, 1511, 1347, 1226, 1127, 1063, 1037, 1033, 1039, 1083, 1155, 1264, 1390, 1563, 1799, 2126, 1933, 1673, 1471, 1320, 1200, 1101, 1039, 1025, 1030, 1027, 1055, 1128, 1226, 1361, 1537, 1769, 2068, 1928, 1690, 1466, 1303, 1186, 1090, 1035, 1029, 1027, 1032, 1042, 1121, 1219, 1347, 1511, 1746, 2062, 1933, 1659, 1466, 1313, 1188, 1091, 1038, 1030, 1024, 1033, 1049, 1119, 1221, 1356, 1539, 1750, 2052, 1965, 1686, 1482, 1328, 1208, 1109, 1050, 1035, 1030, 1035, 1065, 1142, 1239, 1379, 1563, 1784, 2094, 1993, 1728, 1525, 1361, 1239, 1144, 1078, 1051, 1045, 1053, 1115, 1178, 1277, 1416, 1583, 1819, 2142, 2088, 1803, 1583, 1419, 1289, 1196, 1136, 1100, 1084, 1101, 1150, 1226, 1334, 1464, 1656, 1898, 2246, 2199, 1881, 1659, 1490, 1356, 1269, 1203, 1161, 1155, 1163, 1214, 1295, 1402, 1545, 1739, 1998, 2409, 2321, 1998, 1746, 1580, 1451, 1352, 1287, 1248, 1230, 1245, 1299, 1383, 1490, 1643, 1847, 2120, 2573, 2557, 2148, 1898, 1693, 1563, 1451, 1383, 1337, 1339, 1361, 1402, 1479, 1599, 1788, 1988, 2302, 2817, 2885, 2341, 2062, 1835, 1669, 1577, 1506, 1464, 1453, 1469, 1525, 1608, 1739, 1898, 2148, 2557, 3183] + }, + "lsc_samples_greenB": { + "uCoeff": [3090, 2509, 2172, 1932, 1796, 1675, 1607, 1534, 1520, 1542, 1610, 1688, 1816, 1997, 2303, 2694, 3577, 2703, 2260, 1978, 1785, 1642, 1526, 1449, 1411, 1399, 1430, 1483, 1554, 1675, 1844, 2091, 2422, 2991, 2422, 2071, 1835, 1648, 1507, 1406, 1341, 1301, 1291, 1309, 1356, 1442, 1548, 1723, 1924, 2212, 2652, 2260, 1950, 1705, 1540, 1411, 1312, 1244, 1206, 1198, 1210, 1264, 1332, 1442, 1592, 1789, 2065, 2487, 2150, 1823, 1617, 1460, 1328, 1233, 1168, 1131, 1116, 1142, 1184, 1268, 1360, 1509, 1705, 1932, 2284, 2035, 1748, 1563, 1390, 1268, 1176, 1106, 1074, 1061, 1085, 1125, 1199, 1309, 1435, 1629, 1856, 2212, 1978, 1705, 1501, 1352, 1231, 1128, 1070, 1034, 1035, 1038, 1081, 1163, 1255, 1396, 1571, 1800, 2150, 1955, 1665, 1470, 1320, 1201, 1098, 1042, 1025, 1032, 1032, 1054, 1125, 1233, 1363, 1542, 1762, 2050, 1906, 1681, 1457, 1309, 1184, 1090, 1035, 1025, 1025, 1034, 1048, 1116, 1224, 1352, 1526, 1751, 2040, 1919, 1661, 1454, 1307, 1187, 1096, 1035, 1025, 1024, 1030, 1051, 1119, 1224, 1356, 1528, 1733, 2035, 1932, 1678, 1470, 1324, 1201, 1111, 1048, 1029, 1029, 1042, 1067, 1139, 1244, 1376, 1563, 1781, 2096, 2002, 1726, 1528, 1360, 1234, 1148, 1083, 1054, 1037, 1055, 1116, 1173, 1280, 1411, 1595, 1820, 2155, 2065, 1800, 1568, 1425, 1289, 1198, 1125, 1095, 1092, 1102, 1148, 1222, 1328, 1472, 1655, 1898, 2254, 2155, 1868, 1655, 1488, 1356, 1264, 1196, 1156, 1150, 1166, 1217, 1297, 1394, 1542, 1730, 2002, 2395, 2335, 1987, 1748, 1577, 1449, 1349, 1282, 1242, 1231, 1253, 1303, 1371, 1485, 1645, 1835, 2123, 2571, 2494, 2150, 1864, 1691, 1542, 1447, 1383, 1343, 1328, 1345, 1390, 1480, 1595, 1785, 1978, 2303, 2793, 2840, 2335, 2040, 1820, 1665, 1565, 1493, 1472, 1447, 1460, 1526, 1595, 1733, 1911, 2155, 2532, 3283] + }, + "lsc_samples_blue": { + "uCoeff": [3095, 2447, 2126, 1923, 1775, 1664, 1573, 1541, 1509, 1530, 1600, 1702, 1823, 1999, 2248, 2651, 3484, 2694, 2211, 1957, 1751, 1623, 1506, 1438, 1407, 1398, 1401, 1456, 1544, 1660, 1813, 2048, 2352, 2931, 2420, 2073, 1799, 1623, 1489, 1395, 1331, 1290, 1280, 1290, 1339, 1416, 1523, 1676, 1885, 2161, 2589, 2241, 1923, 1702, 1513, 1401, 1305, 1230, 1199, 1186, 1197, 1249, 1315, 1422, 1573, 1747, 2011, 2377, 2126, 1838, 1600, 1441, 1326, 1221, 1162, 1128, 1113, 1136, 1174, 1249, 1350, 1486, 1660, 1885, 2218, 2041, 1742, 1541, 1387, 1265, 1168, 1109, 1070, 1060, 1072, 1113, 1193, 1285, 1422, 1596, 1809, 2133, 1952, 1685, 1492, 1345, 1230, 1126, 1070, 1032, 1035, 1037, 1072, 1138, 1237, 1367, 1537, 1751, 2048, 1923, 1656, 1456, 1305, 1193, 1098, 1038, 1037, 1037, 1030, 1051, 1124, 1215, 1339, 1496, 1715, 1999, 1902, 1660, 1447, 1297, 1184, 1089, 1032, 1029, 1024, 1037, 1045, 1107, 1206, 1323, 1489, 1698, 1975, 1891, 1643, 1447, 1297, 1186, 1097, 1040, 1035, 1032, 1037, 1047, 1113, 1204, 1336, 1489, 1702, 1987, 1923, 1652, 1469, 1323, 1204, 1117, 1047, 1038, 1030, 1043, 1056, 1122, 1226, 1345, 1509, 1729, 2011, 1981, 1702, 1506, 1356, 1237, 1142, 1095, 1056, 1045, 1051, 1109, 1166, 1261, 1392, 1559, 1775, 2067, 2073, 1789, 1559, 1401, 1290, 1195, 1126, 1089, 1088, 1098, 1144, 1215, 1305, 1431, 1612, 1844, 2161, 2161, 1859, 1631, 1469, 1353, 1249, 1193, 1152, 1144, 1156, 1199, 1275, 1372, 1513, 1685, 1929, 2287, 2311, 1952, 1724, 1562, 1422, 1336, 1273, 1233, 1219, 1242, 1280, 1353, 1463, 1596, 1809, 2067, 2456, 2502, 2113, 1844, 1656, 1537, 1425, 1358, 1331, 1318, 1336, 1381, 1460, 1566, 1747, 1940, 2241, 2694, 2761, 2241, 1981, 1765, 1615, 1523, 1456, 1407, 1401, 1410, 1476, 1548, 1672, 1864, 2067, 2420, 3053] + } + }, { + "name": "2592x1944_HZ_70", + "resolution": "2592x1944", + "illumination": "HZ", + "vignetting": 70, + "lsc_samples_red": { + "uCoeff": [2629, 2253, 2021, 1823, 1723, 1638, 1540, 1538, 1526, 1531, 1590, 1664, 1791, 1948, 2151, 2470, 2966, 2436, 2063, 1872, 1710, 1598, 1507, 1440, 1414, 1404, 1423, 1471, 1550, 1644, 1799, 1987, 2245, 2689, 2241, 1963, 1745, 1612, 1489, 1396, 1333, 1304, 1298, 1316, 1365, 1436, 1539, 1663, 1858, 2107, 2374, 2086, 1845, 1662, 1522, 1406, 1306, 1244, 1214, 1203, 1226, 1278, 1351, 1454, 1576, 1738, 1957, 2254, 2017, 1761, 1596, 1445, 1333, 1234, 1175, 1136, 1132, 1152, 1193, 1274, 1379, 1512, 1661, 1879, 2163, 1919, 1700, 1531, 1396, 1272, 1178, 1122, 1078, 1071, 1096, 1143, 1210, 1316, 1441, 1614, 1819, 2089, 1889, 1648, 1496, 1347, 1230, 1135, 1075, 1047, 1040, 1050, 1097, 1174, 1275, 1402, 1565, 1760, 2019, 1845, 1634, 1467, 1320, 1193, 1109, 1047, 1032, 1034, 1038, 1067, 1140, 1245, 1389, 1539, 1732, 1995, 1832, 1632, 1449, 1305, 1190, 1100, 1042, 1030, 1024, 1040, 1062, 1137, 1232, 1371, 1521, 1720, 1948, 1835, 1612, 1451, 1313, 1194, 1100, 1040, 1029, 1030, 1040, 1070, 1137, 1232, 1369, 1515, 1729, 1972, 1868, 1645, 1463, 1328, 1209, 1126, 1057, 1047, 1038, 1047, 1082, 1160, 1259, 1396, 1542, 1746, 1998, 1867, 1666, 1501, 1365, 1252, 1154, 1104, 1057, 1053, 1066, 1128, 1196, 1300, 1422, 1585, 1796, 2024, 1954, 1728, 1553, 1416, 1301, 1208, 1149, 1100, 1090, 1114, 1174, 1241, 1339, 1480, 1648, 1832, 2131, 2014, 1797, 1603, 1490, 1368, 1274, 1209, 1172, 1159, 1185, 1229, 1312, 1398, 1538, 1710, 1919, 2191, 2127, 1879, 1691, 1548, 1436, 1353, 1295, 1255, 1241, 1273, 1311, 1388, 1490, 1614, 1779, 2030, 2311, 2242, 1999, 1794, 1647, 1539, 1446, 1391, 1342, 1341, 1370, 1400, 1483, 1580, 1743, 1901, 2133, 2482, 2501, 2151, 1926, 1761, 1646, 1535, 1478, 1431, 1444, 1474, 1499, 1602, 1700, 1826, 2032, 2304, 2793] + }, + "lsc_samples_greenR": { + "uCoeff": [2515, 2155, 1968, 1774, 1679, 1585, 1529, 1501, 1494, 1491, 1560, 1600, 1720, 1850, 2038, 2330, 2813, 2281, 1975, 1821, 1676, 1554, 1488, 1434, 1384, 1382, 1392, 1438, 1502, 1602, 1722, 1907, 2124, 2508, 2109, 1874, 1701, 1581, 1466, 1375, 1320, 1292, 1287, 1292, 1350, 1403, 1502, 1617, 1783, 1985, 2321, 1994, 1779, 1623, 1490, 1379, 1294, 1239, 1204, 1189, 1215, 1256, 1329, 1418, 1547, 1679, 1905, 2138, 1928, 1723, 1553, 1421, 1323, 1230, 1169, 1132, 1132, 1141, 1186, 1254, 1356, 1471, 1608, 1809, 2040, 1865, 1658, 1489, 1368, 1260, 1180, 1111, 1083, 1064, 1091, 1128, 1205, 1296, 1407, 1562, 1733, 1977, 1809, 1607, 1459, 1330, 1220, 1134, 1075, 1045, 1039, 1046, 1094, 1161, 1256, 1373, 1518, 1703, 1899, 1783, 1588, 1431, 1297, 1192, 1109, 1042, 1034, 1033, 1033, 1068, 1132, 1226, 1355, 1480, 1680, 1881, 1763, 1597, 1423, 1282, 1185, 1098, 1040, 1031, 1024, 1042, 1048, 1128, 1222, 1344, 1481, 1649, 1863, 1760, 1580, 1426, 1291, 1186, 1098, 1040, 1034, 1033, 1046, 1062, 1125, 1216, 1338, 1494, 1645, 1862, 1783, 1594, 1443, 1314, 1204, 1123, 1054, 1042, 1042, 1045, 1078, 1151, 1242, 1357, 1498, 1678, 1899, 1805, 1633, 1472, 1351, 1237, 1152, 1087, 1061, 1055, 1061, 1125, 1176, 1275, 1401, 1531, 1715, 1958, 1866, 1677, 1523, 1396, 1280, 1201, 1133, 1102, 1100, 1107, 1153, 1230, 1315, 1434, 1583, 1779, 2022, 1936, 1717, 1572, 1444, 1342, 1261, 1206, 1168, 1158, 1168, 1222, 1284, 1377, 1502, 1645, 1830, 2081, 2025, 1800, 1653, 1512, 1410, 1335, 1280, 1242, 1234, 1250, 1292, 1359, 1454, 1569, 1725, 1911, 2211, 2149, 1912, 1736, 1606, 1491, 1419, 1361, 1329, 1321, 1346, 1376, 1439, 1539, 1679, 1810, 2027, 2344, 2380, 2024, 1843, 1713, 1587, 1508, 1449, 1425, 1423, 1434, 1499, 1537, 1623, 1764, 1929, 2189, 2578] + }, + "lsc_samples_greenB": { + "uCoeff": [2463, 2099, 1909, 1775, 1650, 1578, 1532, 1495, 1482, 1499, 1541, 1617, 1713, 1848, 2044, 2316, 2815, 2276, 1992, 1813, 1668, 1558, 1476, 1406, 1381, 1377, 1389, 1434, 1500, 1595, 1724, 1890, 2128, 2520, 2084, 1863, 1699, 1575, 1452, 1375, 1321, 1287, 1270, 1292, 1338, 1409, 1497, 1628, 1783, 1995, 2280, 1993, 1765, 1618, 1475, 1382, 1298, 1237, 1198, 1193, 1211, 1256, 1322, 1413, 1543, 1697, 1881, 2141, 1912, 1695, 1542, 1414, 1309, 1216, 1169, 1133, 1117, 1136, 1188, 1262, 1344, 1471, 1614, 1801, 2040, 1859, 1646, 1489, 1361, 1256, 1168, 1108, 1071, 1062, 1086, 1126, 1201, 1303, 1419, 1566, 1745, 1968, 1797, 1598, 1453, 1318, 1206, 1124, 1063, 1038, 1041, 1052, 1096, 1164, 1252, 1369, 1509, 1686, 1928, 1770, 1598, 1424, 1296, 1195, 1103, 1041, 1033, 1033, 1036, 1056, 1134, 1229, 1356, 1491, 1663, 1897, 1758, 1599, 1422, 1285, 1179, 1087, 1038, 1025, 1024, 1036, 1052, 1117, 1219, 1334, 1492, 1661, 1878, 1766, 1570, 1422, 1285, 1178, 1092, 1039, 1030, 1028, 1044, 1055, 1126, 1228, 1341, 1481, 1652, 1872, 1774, 1583, 1439, 1299, 1196, 1101, 1051, 1033, 1032, 1044, 1070, 1142, 1237, 1359, 1509, 1679, 1882, 1802, 1616, 1469, 1336, 1233, 1140, 1084, 1052, 1045, 1055, 1119, 1180, 1271, 1379, 1533, 1708, 1973, 1833, 1679, 1501, 1382, 1274, 1191, 1128, 1087, 1082, 1100, 1147, 1216, 1309, 1441, 1565, 1774, 1987, 1932, 1711, 1563, 1438, 1327, 1248, 1195, 1158, 1146, 1170, 1209, 1278, 1376, 1490, 1640, 1833, 2089, 2004, 1792, 1638, 1507, 1405, 1325, 1264, 1228, 1227, 1243, 1280, 1352, 1442, 1558, 1719, 1924, 2170, 2124, 1895, 1722, 1585, 1482, 1400, 1349, 1317, 1308, 1326, 1362, 1435, 1535, 1676, 1818, 2033, 2340, 2330, 2031, 1831, 1676, 1565, 1492, 1433, 1424, 1398, 1412, 1462, 1526, 1647, 1749, 1926, 2187, 2572] + }, + "lsc_samples_blue": { + "uCoeff": [2587, 2155, 1991, 1777, 1697, 1602, 1558, 1543, 1535, 1532, 1580, 1636, 1748, 1885, 2014, 2372, 2788, 2339, 2002, 1796, 1666, 1537, 1481, 1425, 1412, 1405, 1411, 1442, 1510, 1591, 1745, 1854, 2167, 2400, 2161, 1873, 1694, 1578, 1463, 1375, 1309, 1299, 1301, 1314, 1350, 1419, 1500, 1622, 1806, 1951, 2265, 1996, 1788, 1612, 1498, 1374, 1304, 1238, 1214, 1208, 1227, 1259, 1335, 1407, 1535, 1683, 1874, 2064, 1928, 1734, 1547, 1402, 1326, 1232, 1178, 1137, 1120, 1143, 1196, 1265, 1365, 1465, 1599, 1752, 1970, 1857, 1692, 1482, 1375, 1270, 1170, 1120, 1089, 1073, 1089, 1120, 1208, 1298, 1407, 1575, 1739, 1935, 1857, 1624, 1460, 1331, 1232, 1149, 1084, 1048, 1043, 1048, 1073, 1166, 1259, 1387, 1496, 1695, 1912, 1782, 1616, 1417, 1302, 1193, 1115, 1048, 1043, 1043, 1038, 1069, 1137, 1232, 1338, 1490, 1674, 1850, 1786, 1591, 1408, 1295, 1182, 1099, 1048, 1024, 1034, 1038, 1058, 1126, 1212, 1324, 1460, 1622, 1787, 1768, 1570, 1417, 1303, 1194, 1110, 1048, 1043, 1038, 1048, 1048, 1126, 1226, 1331, 1480, 1622, 1836, 1777, 1588, 1431, 1308, 1205, 1120, 1057, 1058, 1043, 1043, 1068, 1137, 1224, 1345, 1485, 1668, 1829, 1847, 1616, 1474, 1334, 1243, 1153, 1083, 1063, 1048, 1057, 1120, 1177, 1262, 1383, 1521, 1699, 1916, 1901, 1678, 1495, 1377, 1288, 1193, 1142, 1110, 1099, 1115, 1166, 1211, 1326, 1437, 1567, 1724, 1977, 1906, 1703, 1570, 1440, 1327, 1240, 1193, 1152, 1153, 1170, 1212, 1275, 1365, 1475, 1635, 1796, 2048, 2055, 1782, 1621, 1494, 1399, 1328, 1275, 1258, 1237, 1242, 1289, 1343, 1434, 1568, 1721, 1866, 2174, 2144, 1898, 1715, 1585, 1479, 1391, 1340, 1322, 1299, 1329, 1373, 1434, 1528, 1679, 1780, 2018, 2244, 2304, 1923, 1768, 1644, 1519, 1425, 1401, 1352, 1373, 1371, 1408, 1482, 1580, 1719, 1892, 2071, 2498] + } + }, { + "name": "2592x1944_HZ_100", + "resolution": "2592x1944", + "illumination": "HZ", + "vignetting": 100, + "lsc_samples_red": { + "uCoeff": [3287, 2644, 2280, 1998, 1847, 1731, 1613, 1601, 1586, 1594, 1666, 1763, 1928, 2146, 2448, 2937, 3775, 2937, 2361, 2066, 1837, 1683, 1567, 1483, 1450, 1438, 1460, 1517, 1613, 1736, 1939, 2204, 2592, 3287, 2623, 2196, 1889, 1704, 1545, 1432, 1358, 1323, 1315, 1336, 1392, 1476, 1601, 1763, 2022, 2378, 2812, 2395, 2028, 1773, 1586, 1444, 1328, 1257, 1223, 1211, 1236, 1292, 1375, 1496, 1649, 1863, 2168, 2613, 2280, 1911, 1683, 1493, 1358, 1246, 1181, 1140, 1135, 1156, 1200, 1289, 1407, 1567, 1759, 2053, 2466, 2146, 1827, 1601, 1432, 1289, 1185, 1125, 1079, 1072, 1097, 1146, 1218, 1336, 1483, 1696, 1968, 2353, 2092, 1759, 1556, 1375, 1241, 1139, 1076, 1047, 1040, 1050, 1099, 1179, 1289, 1435, 1633, 1889, 2256, 2034, 1740, 1520, 1344, 1203, 1112, 1047, 1032, 1034, 1038, 1067, 1144, 1257, 1419, 1601, 1852, 2218, 2016, 1736, 1500, 1328, 1198, 1102, 1042, 1030, 1024, 1040, 1062, 1140, 1243, 1398, 1582, 1837, 2161, 2022, 1713, 1503, 1336, 1203, 1102, 1040, 1029, 1030, 1040, 1070, 1140, 1243, 1398, 1575, 1847, 2189, 2066, 1754, 1520, 1355, 1220, 1129, 1058, 1047, 1038, 1047, 1083, 1165, 1272, 1428, 1609, 1873, 2226, 2079, 1787, 1567, 1398, 1267, 1160, 1106, 1058, 1053, 1067, 1131, 1203, 1318, 1460, 1662, 1939, 2280, 2196, 1873, 1633, 1460, 1323, 1218, 1154, 1102, 1092, 1117, 1179, 1253, 1364, 1531, 1740, 1998, 2421, 2303, 1968, 1704, 1549, 1401, 1292, 1220, 1179, 1165, 1192, 1241, 1333, 1435, 1605, 1827, 2119, 2532, 2476, 2092, 1822, 1629, 1486, 1384, 1315, 1270, 1255, 1289, 1333, 1422, 1545, 1704, 1928, 2280, 2720, 2676, 2272, 1968, 1759, 1613, 1496, 1428, 1372, 1369, 1401, 1438, 1538, 1662, 1873, 2099, 2448, 3004, 3102, 2513, 2161, 1917, 1754, 1613, 1538, 1483, 1493, 1527, 1563, 1687, 1822, 1998, 2295, 2720, 3514] + }, + "lsc_samples_greenR": { + "uCoeff": [3145, 2529, 2220, 1945, 1800, 1675, 1601, 1563, 1553, 1553, 1634, 1695, 1851, 2038, 2319, 2771, 3580, 2750, 2261, 2010, 1800, 1637, 1547, 1477, 1419, 1416, 1428, 1483, 1563, 1691, 1856, 2116, 2452, 3065, 2469, 2097, 1841, 1671, 1521, 1411, 1345, 1311, 1304, 1311, 1376, 1442, 1563, 1715, 1940, 2240, 2750, 2290, 1956, 1731, 1553, 1416, 1316, 1252, 1213, 1197, 1225, 1270, 1353, 1459, 1619, 1800, 2110, 2478, 2179, 1870, 1637, 1468, 1348, 1242, 1175, 1136, 1135, 1145, 1193, 1268, 1384, 1524, 1703, 1977, 2326, 2085, 1782, 1557, 1403, 1277, 1187, 1114, 1084, 1065, 1092, 1131, 1213, 1316, 1448, 1641, 1875, 2226, 2004, 1715, 1517, 1358, 1231, 1138, 1076, 1045, 1039, 1046, 1095, 1166, 1270, 1406, 1584, 1828, 2122, 1966, 1691, 1483, 1321, 1202, 1112, 1042, 1034, 1033, 1033, 1068, 1136, 1237, 1384, 1540, 1796, 2091, 1940, 1699, 1474, 1304, 1193, 1100, 1040, 1031, 1024, 1042, 1048, 1131, 1233, 1371, 1540, 1761, 2067, 1940, 1679, 1477, 1314, 1195, 1100, 1040, 1034, 1033, 1046, 1062, 1128, 1227, 1366, 1553, 1757, 2067, 1972, 1699, 1499, 1340, 1215, 1126, 1055, 1042, 1042, 1045, 1079, 1155, 1255, 1389, 1563, 1800, 2116, 2010, 1752, 1537, 1384, 1252, 1158, 1089, 1062, 1055, 1062, 1128, 1183, 1293, 1439, 1605, 1851, 2206, 2097, 1818, 1601, 1439, 1302, 1211, 1138, 1104, 1102, 1110, 1158, 1242, 1340, 1483, 1671, 1940, 2297, 2213, 1880, 1671, 1502, 1374, 1279, 1217, 1175, 1164, 1175, 1233, 1304, 1414, 1567, 1757, 2021, 2404, 2357, 2004, 1782, 1591, 1459, 1366, 1300, 1257, 1248, 1266, 1314, 1392, 1508, 1656, 1870, 2147, 2602, 2565, 2173, 1904, 1715, 1563, 1468, 1397, 1358, 1348, 1376, 1414, 1492, 1619, 1805, 1999, 2326, 2837, 2952, 2364, 2067, 1865, 1691, 1584, 1508, 1477, 1471, 1486, 1563, 1619, 1740, 1930, 2179, 2584, 3243] + }, + "lsc_samples_greenB": { + "uCoeff": [3080, 2464, 2154, 1946, 1769, 1668, 1604, 1557, 1540, 1561, 1615, 1713, 1844, 2036, 2326, 2754, 3583, 2744, 2280, 2001, 1792, 1641, 1534, 1448, 1416, 1411, 1425, 1479, 1561, 1684, 1858, 2097, 2456, 3080, 2439, 2084, 1839, 1665, 1507, 1411, 1346, 1306, 1287, 1311, 1364, 1448, 1557, 1726, 1940, 2251, 2701, 2288, 1940, 1726, 1537, 1419, 1320, 1250, 1207, 1201, 1220, 1270, 1346, 1454, 1615, 1820, 2084, 2482, 2161, 1839, 1626, 1460, 1333, 1228, 1175, 1137, 1120, 1140, 1195, 1277, 1372, 1524, 1709, 1968, 2326, 2078, 1769, 1557, 1396, 1273, 1175, 1111, 1072, 1063, 1087, 1129, 1209, 1323, 1460, 1645, 1888, 2216, 1990, 1705, 1511, 1346, 1217, 1128, 1064, 1038, 1041, 1052, 1098, 1169, 1266, 1402, 1575, 1810, 2154, 1951, 1701, 1476, 1320, 1205, 1106, 1041, 1033, 1033, 1036, 1056, 1138, 1241, 1385, 1551, 1778, 2109, 1935, 1701, 1473, 1308, 1187, 1089, 1038, 1025, 1024, 1036, 1052, 1120, 1230, 1361, 1551, 1774, 2084, 1946, 1668, 1473, 1308, 1187, 1094, 1039, 1030, 1028, 1044, 1055, 1129, 1239, 1369, 1540, 1765, 2078, 1962, 1688, 1495, 1325, 1207, 1104, 1052, 1033, 1032, 1044, 1071, 1146, 1250, 1391, 1575, 1801, 2097, 2007, 1734, 1534, 1369, 1248, 1146, 1086, 1053, 1045, 1056, 1122, 1187, 1289, 1416, 1607, 1844, 2223, 2060, 1820, 1578, 1425, 1296, 1201, 1133, 1089, 1084, 1103, 1152, 1228, 1333, 1491, 1653, 1935, 2258, 2209, 1873, 1661, 1495, 1359, 1266, 1205, 1165, 1152, 1177, 1220, 1298, 1413, 1554, 1752, 2024, 2414, 2333, 1995, 1765, 1586, 1454, 1356, 1284, 1243, 1241, 1259, 1301, 1385, 1495, 1645, 1863, 2161, 2554, 2535, 2154, 1888, 1693, 1554, 1448, 1385, 1346, 1335, 1356, 1399, 1488, 1615, 1801, 2007, 2333, 2832, 2890, 2373, 2054, 1824, 1668, 1568, 1491, 1476, 1445, 1463, 1524, 1607, 1765, 1914, 2175, 2582, 3236] + }, + "lsc_samples_blue": { + "uCoeff": [3235, 2529, 2246, 1948, 1819, 1693, 1631, 1607, 1595, 1595, 1655, 1733, 1881, 2076, 2292, 2821, 3548, 2821, 2292, 1983, 1790, 1619, 1539, 1468, 1448, 1439, 1448, 1487, 1572, 1680, 1881, 2057, 2501, 2933, 2529, 2096, 1834, 1668, 1518, 1411, 1334, 1318, 1318, 1334, 1376, 1458, 1561, 1720, 1965, 2201, 2683, 2292, 1965, 1720, 1561, 1411, 1326, 1251, 1223, 1216, 1237, 1273, 1359, 1448, 1607, 1804, 2076, 2392, 2179, 1881, 1631, 1448, 1351, 1244, 1184, 1141, 1123, 1147, 1203, 1280, 1393, 1518, 1693, 1914, 2246, 2076, 1819, 1550, 1411, 1287, 1177, 1123, 1090, 1074, 1090, 1123, 1216, 1318, 1448, 1655, 1881, 2179, 2057, 1733, 1518, 1359, 1244, 1153, 1085, 1048, 1043, 1048, 1074, 1171, 1273, 1420, 1561, 1819, 2137, 1965, 1720, 1468, 1326, 1203, 1118, 1048, 1043, 1043, 1038, 1069, 1141, 1244, 1367, 1550, 1790, 2057, 1965, 1693, 1458, 1318, 1190, 1101, 1048, 1024, 1034, 1038, 1058, 1129, 1223, 1351, 1518, 1733, 1983, 1948, 1668, 1468, 1326, 1203, 1112, 1048, 1043, 1038, 1048, 1048, 1129, 1237, 1359, 1539, 1733, 2038, 1965, 1693, 1487, 1334, 1216, 1123, 1058, 1058, 1043, 1043, 1069, 1141, 1237, 1376, 1550, 1790, 2038, 2057, 1733, 1539, 1367, 1258, 1159, 1085, 1064, 1048, 1058, 1123, 1184, 1280, 1420, 1595, 1834, 2158, 2137, 1819, 1572, 1420, 1310, 1203, 1147, 1112, 1101, 1118, 1171, 1223, 1351, 1487, 1655, 1881, 2246, 2179, 1865, 1668, 1497, 1359, 1258, 1203, 1159, 1159, 1177, 1223, 1295, 1402, 1539, 1747, 1983, 2366, 2392, 1983, 1747, 1572, 1448, 1359, 1295, 1273, 1251, 1258, 1310, 1376, 1487, 1655, 1865, 2096, 2559, 2559, 2158, 1881, 1693, 1550, 1439, 1376, 1351, 1326, 1359, 1411, 1487, 1607, 1804, 1965, 2316, 2716, 2857, 2246, 1983, 1790, 1619, 1497, 1458, 1402, 1420, 1420, 1468, 1561, 1693, 1881, 2137, 2445, 3143] + } + }, { + "name": "2592x1944_TL84_70", + "resolution": "2592x1944", + "illumination": "TL84", + "vignetting": 70, + "lsc_samples_red": { + "uCoeff": [2468, 2136, 1921, 1785, 1673, 1584, 1520, 1498, 1490, 1507, 1555, 1604, 1709, 1865, 2056, 2323, 2852, 2267, 1994, 1799, 1653, 1556, 1465, 1410, 1370, 1356, 1385, 1431, 1497, 1592, 1739, 1892, 2121, 2548, 2065, 1893, 1698, 1564, 1458, 1365, 1313, 1272, 1276, 1285, 1335, 1401, 1488, 1608, 1786, 1985, 2278, 1998, 1789, 1592, 1479, 1373, 1283, 1223, 1195, 1182, 1198, 1251, 1318, 1400, 1531, 1683, 1886, 2180, 1917, 1699, 1543, 1407, 1298, 1220, 1165, 1116, 1113, 1126, 1185, 1252, 1337, 1461, 1610, 1787, 2020, 1864, 1659, 1490, 1353, 1243, 1167, 1101, 1072, 1057, 1082, 1126, 1199, 1285, 1409, 1549, 1741, 1978, 1806, 1597, 1460, 1314, 1212, 1125, 1060, 1035, 1026, 1037, 1082, 1146, 1241, 1373, 1507, 1685, 1897, 1777, 1582, 1434, 1284, 1183, 1093, 1037, 1031, 1031, 1026, 1053, 1118, 1221, 1337, 1499, 1661, 1889, 1788, 1581, 1404, 1278, 1181, 1081, 1033, 1026, 1026, 1033, 1042, 1105, 1217, 1322, 1467, 1657, 1884, 1772, 1576, 1412, 1284, 1172, 1091, 1033, 1033, 1024, 1031, 1054, 1118, 1205, 1333, 1475, 1657, 1905, 1795, 1598, 1438, 1296, 1194, 1108, 1044, 1035, 1033, 1037, 1067, 1139, 1229, 1354, 1480, 1675, 1881, 1796, 1619, 1469, 1332, 1225, 1132, 1081, 1054, 1042, 1056, 1105, 1170, 1266, 1372, 1521, 1696, 1928, 1864, 1676, 1507, 1384, 1269, 1191, 1128, 1083, 1083, 1103, 1143, 1215, 1305, 1428, 1569, 1756, 2008, 1942, 1717, 1560, 1437, 1337, 1247, 1182, 1154, 1142, 1158, 1209, 1271, 1361, 1474, 1626, 1845, 2097, 2015, 1805, 1635, 1497, 1405, 1326, 1264, 1222, 1219, 1237, 1272, 1356, 1424, 1553, 1703, 1913, 2168, 2176, 1905, 1716, 1590, 1487, 1400, 1345, 1316, 1296, 1331, 1372, 1437, 1532, 1679, 1820, 2009, 2336, 2333, 2024, 1846, 1701, 1570, 1475, 1426, 1410, 1397, 1419, 1461, 1514, 1598, 1745, 1918, 2188, 2560] + }, + "lsc_samples_greenR": { + "uCoeff": [2422, 2112, 1914, 1763, 1660, 1577, 1506, 1473, 1469, 1484, 1530, 1606, 1698, 1804, 1986, 2255, 2787, 2202, 1962, 1791, 1648, 1550, 1459, 1400, 1377, 1379, 1387, 1415, 1488, 1582, 1703, 1876, 2083, 2426, 2063, 1865, 1690, 1557, 1450, 1369, 1310, 1272, 1273, 1291, 1328, 1399, 1488, 1608, 1756, 1955, 2246, 1979, 1768, 1613, 1478, 1368, 1294, 1226, 1192, 1182, 1201, 1246, 1304, 1406, 1515, 1668, 1842, 2101, 1900, 1702, 1535, 1406, 1300, 1218, 1166, 1128, 1120, 1134, 1175, 1242, 1326, 1462, 1596, 1772, 2003, 1829, 1644, 1490, 1354, 1246, 1169, 1101, 1075, 1067, 1075, 1120, 1191, 1281, 1403, 1537, 1714, 1945, 1784, 1585, 1445, 1321, 1219, 1124, 1061, 1033, 1031, 1040, 1081, 1149, 1241, 1354, 1499, 1664, 1901, 1755, 1568, 1424, 1290, 1190, 1101, 1040, 1024, 1025, 1033, 1058, 1134, 1219, 1336, 1474, 1652, 1873, 1749, 1582, 1416, 1273, 1174, 1083, 1027, 1025, 1024, 1033, 1046, 1115, 1207, 1320, 1464, 1634, 1831, 1749, 1558, 1410, 1282, 1174, 1090, 1037, 1031, 1027, 1034, 1047, 1116, 1200, 1327, 1457, 1631, 1846, 1751, 1577, 1429, 1308, 1204, 1108, 1046, 1034, 1034, 1041, 1062, 1139, 1232, 1341, 1494, 1651, 1870, 1783, 1611, 1465, 1341, 1225, 1146, 1080, 1054, 1044, 1059, 1115, 1163, 1255, 1375, 1512, 1692, 1905, 1832, 1664, 1504, 1381, 1278, 1195, 1127, 1098, 1090, 1101, 1146, 1215, 1298, 1421, 1560, 1745, 1952, 1914, 1721, 1558, 1442, 1332, 1248, 1195, 1154, 1146, 1165, 1203, 1264, 1367, 1481, 1623, 1796, 2062, 1997, 1784, 1620, 1501, 1398, 1321, 1264, 1231, 1226, 1242, 1283, 1344, 1423, 1558, 1694, 1887, 2167, 2104, 1909, 1720, 1596, 1482, 1403, 1343, 1310, 1301, 1317, 1365, 1432, 1524, 1648, 1799, 2011, 2314, 2325, 2020, 1834, 1710, 1563, 1510, 1442, 1395, 1410, 1408, 1464, 1533, 1618, 1738, 1912, 2106, 2510] + }, + "lsc_samples_greenB": { + "uCoeff": [2433, 2107, 1891, 1778, 1652, 1565, 1503, 1464, 1466, 1485, 1520, 1597, 1685, 1826, 2010, 2278, 2781, 2224, 1962, 1789, 1651, 1546, 1465, 1405, 1379, 1363, 1389, 1421, 1482, 1580, 1699, 1864, 2092, 2436, 2086, 1843, 1687, 1549, 1446, 1371, 1313, 1272, 1268, 1287, 1324, 1395, 1486, 1607, 1758, 1961, 2251, 1967, 1761, 1604, 1475, 1363, 1285, 1229, 1192, 1179, 1194, 1249, 1311, 1400, 1522, 1667, 1866, 2111, 1888, 1694, 1540, 1405, 1298, 1217, 1161, 1118, 1111, 1128, 1173, 1242, 1340, 1447, 1594, 1774, 2030, 1817, 1623, 1481, 1357, 1249, 1164, 1104, 1071, 1057, 1075, 1116, 1187, 1281, 1397, 1556, 1718, 1950, 1785, 1592, 1438, 1310, 1200, 1117, 1063, 1033, 1033, 1040, 1087, 1149, 1243, 1360, 1508, 1680, 1894, 1757, 1556, 1404, 1288, 1194, 1092, 1040, 1024, 1028, 1033, 1057, 1123, 1218, 1329, 1468, 1647, 1866, 1745, 1570, 1407, 1275, 1174, 1084, 1031, 1024, 1024, 1031, 1041, 1111, 1196, 1323, 1455, 1637, 1854, 1737, 1556, 1404, 1279, 1174, 1086, 1028, 1025, 1024, 1031, 1050, 1116, 1212, 1323, 1457, 1622, 1876, 1753, 1576, 1425, 1295, 1191, 1103, 1043, 1031, 1028, 1034, 1065, 1127, 1227, 1344, 1483, 1653, 1885, 1795, 1606, 1451, 1327, 1220, 1138, 1079, 1046, 1041, 1047, 1109, 1169, 1255, 1374, 1522, 1692, 1916, 1841, 1664, 1489, 1372, 1269, 1184, 1124, 1087, 1076, 1099, 1140, 1208, 1298, 1420, 1561, 1733, 1964, 1892, 1709, 1546, 1424, 1318, 1247, 1184, 1143, 1143, 1158, 1200, 1266, 1357, 1478, 1618, 1799, 2056, 2005, 1777, 1619, 1486, 1389, 1314, 1255, 1218, 1212, 1229, 1270, 1337, 1427, 1539, 1694, 1885, 2149, 2086, 1886, 1708, 1576, 1463, 1399, 1344, 1313, 1299, 1313, 1361, 1419, 1518, 1651, 1797, 2000, 2313, 2325, 1996, 1817, 1668, 1564, 1469, 1433, 1411, 1387, 1416, 1450, 1524, 1624, 1753, 1911, 2152, 2614] + }, + "lsc_samples_blue": { + "uCoeff": [2491, 2110, 1913, 1768, 1662, 1561, 1538, 1496, 1477, 1494, 1552, 1590, 1685, 1850, 2002, 2258, 2788, 2266, 1924, 1780, 1643, 1543, 1455, 1417, 1380, 1359, 1379, 1421, 1468, 1586, 1683, 1860, 2044, 2397, 2086, 1844, 1684, 1554, 1438, 1356, 1305, 1285, 1266, 1295, 1321, 1408, 1468, 1597, 1754, 1939, 2194, 1970, 1764, 1603, 1464, 1362, 1282, 1231, 1190, 1188, 1199, 1244, 1306, 1388, 1502, 1647, 1839, 2080, 1885, 1678, 1548, 1413, 1291, 1223, 1163, 1122, 1122, 1134, 1179, 1250, 1319, 1442, 1574, 1768, 1982, 1848, 1651, 1488, 1362, 1247, 1166, 1112, 1070, 1063, 1080, 1115, 1182, 1284, 1377, 1524, 1677, 1867, 1773, 1610, 1436, 1308, 1224, 1125, 1070, 1040, 1037, 1040, 1080, 1152, 1231, 1337, 1469, 1643, 1847, 1803, 1568, 1416, 1285, 1186, 1097, 1043, 1030, 1037, 1040, 1052, 1122, 1210, 1319, 1455, 1616, 1822, 1764, 1568, 1404, 1286, 1178, 1097, 1040, 1027, 1024, 1037, 1047, 1107, 1203, 1304, 1445, 1601, 1771, 1743, 1545, 1416, 1281, 1182, 1097, 1040, 1030, 1030, 1027, 1060, 1115, 1198, 1320, 1456, 1602, 1799, 1746, 1579, 1424, 1309, 1189, 1111, 1047, 1043, 1040, 1040, 1059, 1125, 1222, 1332, 1458, 1638, 1815, 1774, 1602, 1450, 1315, 1221, 1140, 1090, 1060, 1043, 1047, 1111, 1171, 1246, 1355, 1491, 1670, 1883, 1855, 1664, 1495, 1356, 1272, 1185, 1125, 1093, 1086, 1097, 1140, 1201, 1295, 1412, 1546, 1702, 1924, 1915, 1701, 1545, 1410, 1326, 1240, 1189, 1159, 1143, 1146, 1206, 1274, 1340, 1457, 1601, 1750, 2028, 1953, 1765, 1612, 1487, 1399, 1316, 1269, 1225, 1199, 1229, 1268, 1342, 1414, 1517, 1674, 1862, 2124, 2097, 1848, 1700, 1560, 1479, 1385, 1333, 1301, 1288, 1306, 1354, 1427, 1487, 1635, 1758, 1972, 2273, 2216, 1951, 1804, 1621, 1524, 1429, 1377, 1378, 1346, 1354, 1426, 1483, 1580, 1673, 1814, 2058, 2466] + } + }, { + "name": "2592x1944_TL84_100", + "resolution": "2592x1944", + "illumination": "TL84", + "vignetting": 100, + "lsc_samples_red": { + "uCoeff": [3081, 2508, 2164, 1957, 1794, 1673, 1589, 1557, 1547, 1568, 1627, 1697, 1836, 2051, 2335, 2757, 3624, 2725, 2278, 1982, 1774, 1638, 1522, 1452, 1405, 1388, 1421, 1475, 1557, 1679, 1872, 2096, 2443, 3101, 2418, 2115, 1836, 1650, 1512, 1400, 1337, 1290, 1293, 1304, 1360, 1439, 1547, 1703, 1941, 2235, 2694, 2290, 1966, 1697, 1542, 1409, 1304, 1236, 1204, 1189, 1207, 1265, 1341, 1439, 1600, 1801, 2087, 2522, 2164, 1843, 1627, 1452, 1322, 1232, 1171, 1119, 1116, 1129, 1192, 1265, 1364, 1512, 1703, 1949, 2301, 2078, 1780, 1557, 1388, 1259, 1174, 1103, 1073, 1058, 1083, 1129, 1207, 1304, 1448, 1627, 1880, 2225, 1999, 1703, 1517, 1341, 1223, 1129, 1061, 1035, 1026, 1037, 1083, 1151, 1255, 1405, 1573, 1808, 2115, 1957, 1679, 1484, 1307, 1192, 1095, 1037, 1031, 1031, 1026, 1054, 1121, 1232, 1364, 1557, 1774, 2096, 1966, 1679, 1452, 1300, 1189, 1083, 1033, 1026, 1026, 1033, 1042, 1108, 1226, 1348, 1522, 1767, 2087, 1949, 1673, 1461, 1307, 1180, 1093, 1033, 1033, 1024, 1031, 1054, 1121, 1216, 1360, 1532, 1767, 2115, 1982, 1703, 1493, 1322, 1204, 1111, 1044, 1035, 1033, 1037, 1068, 1143, 1242, 1384, 1542, 1794, 2096, 1999, 1735, 1532, 1364, 1239, 1137, 1083, 1054, 1042, 1056, 1108, 1177, 1283, 1409, 1594, 1829, 2164, 2096, 1815, 1583, 1426, 1290, 1201, 1132, 1085, 1085, 1105, 1148, 1226, 1329, 1475, 1656, 1910, 2278, 2214, 1880, 1656, 1493, 1368, 1265, 1192, 1160, 1148, 1165, 1220, 1290, 1396, 1537, 1735, 2033, 2418, 2346, 2007, 1760, 1573, 1452, 1356, 1283, 1236, 1232, 1252, 1293, 1388, 1475, 1638, 1843, 2144, 2549, 2591, 2164, 1880, 1697, 1557, 1448, 1380, 1345, 1322, 1360, 1409, 1489, 1610, 1801, 2007, 2301, 2823, 2892, 2358, 2069, 1850, 1673, 1547, 1484, 1461, 1443, 1470, 1522, 1594, 1710, 1910, 2164, 2577, 3228] + }, + "lsc_samples_greenR": { + "uCoeff": [3023, 2480, 2157, 1933, 1780, 1665, 1574, 1531, 1525, 1544, 1601, 1699, 1824, 1984, 2255, 2676, 3541, 2647, 2241, 1974, 1768, 1632, 1516, 1442, 1412, 1412, 1423, 1459, 1547, 1669, 1833, 2078, 2400, 2952, 2415, 2084, 1828, 1643, 1504, 1404, 1334, 1290, 1290, 1310, 1353, 1437, 1547, 1703, 1908, 2201, 2657, 2268, 1943, 1719, 1541, 1404, 1315, 1239, 1201, 1189, 1210, 1260, 1327, 1445, 1584, 1785, 2039, 2431, 2144, 1847, 1618, 1451, 1324, 1230, 1172, 1131, 1123, 1137, 1182, 1255, 1353, 1513, 1688, 1933, 2282, 2039, 1764, 1557, 1389, 1262, 1176, 1103, 1076, 1068, 1076, 1123, 1199, 1299, 1442, 1614, 1851, 2188, 1974, 1691, 1501, 1348, 1230, 1128, 1062, 1033, 1031, 1040, 1082, 1154, 1255, 1386, 1564, 1785, 2120, 1933, 1665, 1474, 1313, 1199, 1103, 1040, 1024, 1025, 1033, 1059, 1137, 1230, 1363, 1531, 1764, 2078, 1923, 1680, 1465, 1295, 1182, 1085, 1027, 1025, 1024, 1033, 1046, 1118, 1216, 1346, 1519, 1743, 2028, 1923, 1654, 1459, 1304, 1182, 1092, 1037, 1031, 1027, 1034, 1047, 1119, 1210, 1353, 1513, 1739, 2050, 1933, 1680, 1483, 1334, 1214, 1111, 1046, 1034, 1034, 1041, 1063, 1143, 1245, 1371, 1557, 1768, 2084, 1984, 1727, 1528, 1373, 1239, 1151, 1082, 1054, 1044, 1059, 1118, 1170, 1272, 1412, 1584, 1824, 2138, 2061, 1802, 1580, 1423, 1299, 1205, 1131, 1100, 1092, 1103, 1151, 1226, 1322, 1468, 1647, 1898, 2214, 2182, 1884, 1654, 1498, 1363, 1266, 1205, 1160, 1152, 1172, 1214, 1283, 1402, 1544, 1731, 1979, 2377, 2325, 1984, 1743, 1577, 1445, 1351, 1283, 1245, 1239, 1257, 1304, 1376, 1474, 1643, 1833, 2114, 2548, 2505, 2169, 1884, 1703, 1551, 1451, 1378, 1339, 1327, 1346, 1402, 1483, 1601, 1768, 1984, 2303, 2796, 2883, 2354, 2055, 1860, 1665, 1584, 1501, 1445, 1457, 1459, 1525, 1614, 1731, 1903, 2157, 2480, 3165] + }, + "lsc_samples_greenB": { + "uCoeff": [3037, 2475, 2131, 1950, 1771, 1652, 1571, 1522, 1522, 1545, 1591, 1690, 1811, 2009, 2283, 2703, 3534, 2673, 2241, 1971, 1771, 1627, 1522, 1447, 1414, 1395, 1425, 1465, 1541, 1667, 1829, 2065, 2410, 2964, 2442, 2059, 1824, 1634, 1500, 1406, 1337, 1290, 1285, 1306, 1349, 1433, 1545, 1702, 1910, 2208, 2663, 2255, 1935, 1710, 1538, 1398, 1306, 1242, 1201, 1186, 1203, 1263, 1334, 1439, 1591, 1784, 2065, 2442, 2131, 1838, 1623, 1450, 1322, 1229, 1167, 1121, 1114, 1131, 1180, 1255, 1367, 1497, 1686, 1935, 2312, 2025, 1742, 1548, 1392, 1265, 1171, 1106, 1072, 1058, 1076, 1119, 1195, 1299, 1436, 1634, 1856, 2194, 1976, 1698, 1494, 1337, 1211, 1121, 1064, 1033, 1033, 1040, 1088, 1154, 1257, 1392, 1574, 1802, 2112, 1935, 1652, 1453, 1311, 1203, 1094, 1040, 1024, 1028, 1033, 1058, 1126, 1229, 1356, 1525, 1759, 2071, 1919, 1667, 1456, 1297, 1182, 1086, 1031, 1024, 1024, 1031, 1041, 1114, 1205, 1349, 1510, 1746, 2054, 1910, 1652, 1453, 1301, 1182, 1088, 1028, 1025, 1024, 1031, 1050, 1119, 1223, 1349, 1513, 1730, 2083, 1935, 1679, 1479, 1320, 1201, 1106, 1043, 1031, 1028, 1034, 1066, 1131, 1240, 1374, 1545, 1771, 2100, 1998, 1722, 1513, 1359, 1234, 1143, 1081, 1046, 1041, 1047, 1112, 1176, 1272, 1411, 1595, 1824, 2150, 2071, 1802, 1564, 1414, 1290, 1194, 1128, 1089, 1078, 1101, 1145, 1219, 1322, 1467, 1648, 1885, 2228, 2156, 1871, 1641, 1479, 1349, 1265, 1194, 1149, 1149, 1165, 1211, 1285, 1392, 1541, 1726, 1982, 2371, 2334, 1976, 1742, 1561, 1436, 1344, 1274, 1232, 1225, 1244, 1290, 1369, 1479, 1623, 1833, 2112, 2526, 2483, 2143, 1871, 1682, 1532, 1447, 1379, 1342, 1325, 1342, 1398, 1470, 1595, 1771, 1982, 2290, 2795, 2883, 2326, 2036, 1815, 1667, 1541, 1491, 1462, 1433, 1467, 1510, 1605, 1738, 1919, 2156, 2535, 3296] + }, + "lsc_samples_blue": { + "uCoeff": [3109, 2478, 2155, 1939, 1782, 1648, 1608, 1555, 1533, 1555, 1624, 1682, 1811, 2035, 2273, 2680, 3543, 2724, 2198, 1962, 1763, 1624, 1512, 1459, 1415, 1391, 1415, 1465, 1526, 1673, 1811, 2060, 2355, 2917, 2442, 2060, 1821, 1640, 1492, 1391, 1329, 1303, 1283, 1314, 1346, 1446, 1526, 1691, 1906, 2183, 2595, 2258, 1939, 1708, 1526, 1397, 1303, 1244, 1199, 1195, 1208, 1258, 1329, 1427, 1570, 1763, 2035, 2406, 2127, 1821, 1632, 1459, 1314, 1235, 1169, 1125, 1125, 1137, 1186, 1263, 1346, 1492, 1665, 1928, 2258, 2060, 1772, 1555, 1397, 1263, 1173, 1114, 1071, 1064, 1081, 1118, 1190, 1303, 1415, 1600, 1811, 2100, 1962, 1717, 1492, 1335, 1235, 1129, 1071, 1040, 1037, 1040, 1081, 1157, 1244, 1368, 1533, 1763, 2060, 1986, 1665, 1465, 1308, 1195, 1099, 1043, 1030, 1037, 1040, 1053, 1125, 1221, 1346, 1512, 1726, 2022, 1939, 1665, 1452, 1308, 1186, 1099, 1040, 1027, 1024, 1037, 1047, 1110, 1212, 1329, 1499, 1708, 1962, 1917, 1640, 1465, 1303, 1190, 1099, 1040, 1030, 1030, 1027, 1060, 1118, 1208, 1346, 1512, 1708, 1998, 1928, 1682, 1478, 1335, 1199, 1114, 1047, 1043, 1040, 1040, 1060, 1129, 1235, 1362, 1519, 1754, 2022, 1974, 1717, 1512, 1346, 1235, 1145, 1092, 1060, 1043, 1047, 1114, 1178, 1263, 1391, 1562, 1801, 2113, 2086, 1801, 1570, 1397, 1293, 1195, 1129, 1095, 1088, 1099, 1145, 1212, 1319, 1459, 1632, 1852, 2183, 2183, 1862, 1640, 1465, 1357, 1258, 1199, 1165, 1149, 1153, 1217, 1293, 1374, 1519, 1708, 1928, 2338, 2273, 1962, 1735, 1562, 1446, 1346, 1288, 1239, 1212, 1244, 1288, 1374, 1465, 1600, 1811, 2086, 2497, 2497, 2100, 1862, 1665, 1548, 1433, 1368, 1329, 1314, 1335, 1391, 1478, 1562, 1754, 1939, 2258, 2747, 2747, 2273, 2022, 1763, 1624, 1499, 1433, 1427, 1391, 1403, 1485, 1562, 1691, 1831, 2047, 2424, 3109] + } + }], + "tableAll_len": 14 + } + }, + "bayer2dnr_v23": { + "Version": "V23", + "CalibPara": { + "Setting": [{ + "SNR_Mode": "LSNR", + "Sensor_Mode": "lcg", + "Calib_ISO": [{ + "iso": 50, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [106, 111, 113, 115, 117, 117, 116, 115, 113, 111, 109, 107, 105, 103, 103, 103] + }, { + "iso": 100, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [139, 147, 151, 154, 156, 156, 155, 154, 152, 150, 148, 146, 144, 142, 140, 138] + }, { + "iso": 200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [178, 191, 198, 201, 205, 205, 204, 203, 201, 198, 196, 193, 191, 188, 186, 184] + }, { + "iso": 400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [275, 292, 301, 307, 312, 312, 310, 308, 304, 300, 296, 291, 287, 283, 279, 276] + }, { + "iso": 800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [313, 339, 351, 357, 363, 364, 363, 360, 357, 354, 350, 346, 342, 339, 336, 334] + }, { + "iso": 1600, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [442, 479, 496, 505, 514, 515, 513, 510, 506, 501, 495, 490, 484, 479, 476, 472] + }, { + "iso": 3200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [626, 678, 701, 714, 726, 728, 725, 721, 715, 708, 700, 692, 685, 678, 673, 668] + }, { + "iso": 6400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [884, 959, 992, 1011, 1027, 1030, 1026, 1020, 1011, 1001, 991, 979, 968, 959, 951, 945] + }, { + "iso": 12800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1450, 1457, 1456, 1450, 1435, 1423, 1419, 1420, 1420, 1414, 1401, 1378, 1349, 1319, 1292, 1270] + }, { + "iso": 25600, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1702, 1789, 1841, 1876, 1918, 1941, 1953, 1955, 1949, 1934, 1910, 1879, 1844, 1809, 1778, 1751] + }, { + "iso": 51200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1851, 1847, 1845, 1843, 1842, 1844, 1846, 1848, 1848, 1848, 1846, 1842, 1837, 1830, 1821, 1812] + }, { + "iso": 102400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1851, 1847, 1845, 1843, 1842, 1844, 1846, 1848, 1848, 1848, 1846, 1842, 1837, 1830, 1821, 1812] + }, { + "iso": 204800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1851, 1847, 1845, 1843, 1842, 1844, 1846, 1848, 1848, 1848, 1846, 1842, 1837, 1830, 1821, 1812] + }], + "Calib_ISO_len": 13 + }, { + "SNR_Mode": "HSNR", + "Sensor_Mode": "hcg", + "Calib_ISO": [{ + "iso": 50, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [91, 93, 95, 96, 97, 97, 95, 92, 89, 84, 78, 72, 67, 62, 58, 58] + }, { + "iso": 100, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [159, 150, 143, 138, 131, 128, 127, 126, 124, 120, 114, 105, 95, 85, 79, 83] + }, { + "iso": 200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [377, 329, 285, 246, 184, 150, 143, 153, 168, 178, 180, 174, 158, 134, 108, 94] + }, { + "iso": 400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [442, 400, 362, 329, 278, 248, 235, 234, 237, 239, 238, 230, 215, 194, 169, 147] + }, { + "iso": 800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1084, 940, 806, 682, 463, 297, 212, 228, 288, 341, 371, 374, 348, 294, 216, 139] + }, { + "iso": 1600, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1198, 1066, 945, 834, 650, 520, 451, 434, 445, 463, 471, 462, 432, 380, 314, 255] + }, { + "iso": 3200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1427, 1297, 1179, 1073, 896, 770, 691, 650, 631, 619, 603, 574, 529, 467, 395, 334] + }, { + "iso": 6400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1866, 1741, 1626, 1521, 1340, 1197, 1089, 1009, 950, 903, 859, 811, 754, 684, 599, 502] + }, { + "iso": 12800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [2833, 2634, 2452, 2285, 2000, 1775, 1603, 1473, 1369, 1278, 1187, 1085, 969, 840, 713, 628] + }, { + "iso": 25600, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [3113, 2912, 2728, 2560, 2276, 2056, 1894, 1780, 1699, 1636, 1576, 1507, 1420, 1309, 1168, 996] + }, { + "iso": 51200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [5009, 4518, 4064, 3649, 2946, 2425, 2091, 1924, 1873, 1872, 1868, 1834, 1758, 1655, 1565, 1567] + }, { + "iso": 102400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [768, 768, 768, 768, 640, 640, 640, 640, 512, 512, 512, 512, 512, 512, 512, 384] + }, { + "iso": 204800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [768, 768, 768, 768, 640, 640, 640, 640, 512, 512, 512, 512, 512, 512, 512, 384] + }], + "Calib_ISO_len": 13 + }], + "Setting_len": 2, + "Blc_Ref": [{ + "iso": 50, + "Reference_r": 119.5, + "Reference_gr": 119.5, + "Reference_gb": 120.5625, + "Reference_b": 120.5625 + }, { + "iso": 100, + "Reference_r": 119.125, + "Reference_gr": 119.0625, + "Reference_gb": 120.9375, + "Reference_b": 120.9375 + }, { + "iso": 200, + "Reference_r": 115.875, + "Reference_gr": 116.3125, + "Reference_gb": 117.9375, + "Reference_b": 117.9375 + }, { + "iso": 400, + "Reference_r": 115.4375, + "Reference_gr": 115.4375, + "Reference_gb": 116.5625, + "Reference_b": 116.5625 + }, { + "iso": 800, + "Reference_r": 100.75, + "Reference_gr": 100.75, + "Reference_gb": 103.3125, + "Reference_b": 103.3125 + }, { + "iso": 1600, + "Reference_r": 100.75, + "Reference_gr": 100.75, + "Reference_gb": 103.3125, + "Reference_b": 103.3125 + }, { + "iso": 3200, + "Reference_r": 100.75, + "Reference_gr": 100.75, + "Reference_gb": 103.3125, + "Reference_b": 103.3125 + }, { + "iso": 6400, + "Reference_r": 100.75, + "Reference_gr": 100.75, + "Reference_gb": 103.3125, + "Reference_b": 103.3125 + }, { + "iso": 12800, + "Reference_r": 100.75, + "Reference_gr": 100.75, + "Reference_gb": 103.3125, + "Reference_b": 103.3125 + }, { + "iso": 25600, + "Reference_r": 100.75, + "Reference_gr": 100.75, + "Reference_gb": 103.3125, + "Reference_b": 103.3125 + }, { + "iso": 51200, + "Reference_r": 100.75, + "Reference_gr": 100.75, + "Reference_gb": 103.3125, + "Reference_b": 103.3125 + }, { + "iso": 102400, + "Reference_r": 100.75, + "Reference_gr": 100.75, + "Reference_gb": 103.3125, + "Reference_b": 103.3125 + }, { + "iso": 204800, + "Reference_r": 100.75, + "Reference_gr": 100.75, + "Reference_gb": 103.3125, + "Reference_b": 103.3125 + }], + "Blc_Ref_len": 13 + }, + "TuningPara": { + "enable": 1, + "hdrdgain_ctrl_en": 0, + "Setting": [{ + "SNR_Mode": "LSNR", + "Sensor_Mode": "lcg", + "Tuning_ISO": [{ + "iso": 50, + "gauss_guide": 0, + "filter_strength": 0.3, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.1, + "gain_bypass": 0, + "gain_scale": 1, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 100, + "gauss_guide": 0, + "filter_strength": 0.3, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.1, + "gain_bypass": 0, + "gain_scale": 1, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 200, + "gauss_guide": 0, + "filter_strength": 0.4, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.1, + "gain_bypass": 0, + "gain_scale": 1.5, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 400, + "gauss_guide": 0, + "filter_strength": 0.5, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.2, + "gain_bypass": 0, + "gain_scale": 1.5, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 800, + "gauss_guide": 0, + "filter_strength": 0.7, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.3, + "gain_bypass": 0, + "gain_scale": 2, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 1600, + "gauss_guide": 1, + "filter_strength": 0.8, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.3, + "gain_bypass": 0, + "gain_scale": 2, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 3200, + "gauss_guide": 1, + "filter_strength": 0.8, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.3, + "gain_bypass": 0, + "gain_scale": 3, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 6400, + "gauss_guide": 1, + "filter_strength": 0.8, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.3, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 12800, + "gauss_guide": 1, + "filter_strength": 1, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.5, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 25600, + "gauss_guide": 1, + "filter_strength": 1, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.6, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 51200, + "gauss_guide": 1, + "filter_strength": 1, + "edgesofts": 1, + "ratio": 0, + "weight": 0.5, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 102400, + "gauss_guide": 0, + "filter_strength": 1, + "edgesofts": 1, + "ratio": 0.01, + "weight": 1, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 204800, + "gauss_guide": 0, + "filter_strength": 2, + "edgesofts": 2, + "ratio": 0.01, + "weight": 1, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }], + "Tuning_ISO_len": 13 + }, { + "SNR_Mode": "HSNR", + "Sensor_Mode": "hcg", + "Tuning_ISO": [{ + "iso": 50, + "gauss_guide": 0, + "filter_strength": 0.3, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.5, + "gain_bypass": 0, + "gain_scale": 1, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 100, + "gauss_guide": 0, + "filter_strength": 0.3, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.5, + "gain_bypass": 0, + "gain_scale": 1, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 200, + "gauss_guide": 0, + "filter_strength": 0.4, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.5, + "gain_bypass": 0, + "gain_scale": 1.5, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 400, + "gauss_guide": 0, + "filter_strength": 0.5, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.4, + "gain_bypass": 0, + "gain_scale": 2, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 800, + "gauss_guide": 0, + "filter_strength": 0.7, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.3, + "gain_bypass": 0, + "gain_scale": 2.5, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 1600, + "gauss_guide": 1, + "filter_strength": 0.8, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.3, + "gain_bypass": 0, + "gain_scale": 3, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 3200, + "gauss_guide": 1, + "filter_strength": 0.8, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.3, + "gain_bypass": 0, + "gain_scale": 3, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 6400, + "gauss_guide": 1, + "filter_strength": 0.8, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.3, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 12800, + "gauss_guide": 1, + "filter_strength": 0.8, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.5, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 25600, + "gauss_guide": 1, + "filter_strength": 0.7, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.7, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 51200, + "gauss_guide": 1, + "filter_strength": 1, + "edgesofts": 1, + "ratio": 0.01, + "weight": 0.8, + "gain_bypass": 0, + "gain_scale": 2.5, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 102400, + "gauss_guide": 0, + "filter_strength": 1, + "edgesofts": 1, + "ratio": 0.01, + "weight": 1, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }, { + "iso": 204800, + "gauss_guide": 0, + "filter_strength": 2, + "edgesofts": 2, + "ratio": 0.01, + "weight": 1, + "gain_bypass": 0, + "gain_scale": 4, + "pix_diff": 16383, + "diff_thld": 1023, + "trans_mode": 0, + "trans_offset": 256, + "itrans_offset": 32768, + "trans_datmax": 1048580, + "hdr_dgain_scale_s": 1, + "hdr_dgain_scale_m": 1, + "gain_adj": { + "gain_lumapoint": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], + "gain_adj": [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256] + } + }], + "Tuning_ISO_len": 13 + }], + "Setting_len": 2 + } + }, + "bayertnr_v23": { + "Version": "V23", + "CalibPara": { + "Setting": [{ + "SNR_Mode": "LSNR", + "Sensor_Mode": "lcg", + "Calib_ISO": [{ + "iso": 50, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [106, 111, 113, 115, 117, 117, 116, 115, 113, 111, 109, 107, 105, 103, 103, 103], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20], + "hi_sigma": [167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167] + }, { + "iso": 100, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [139, 147, 151, 154, 156, 156, 155, 154, 152, 150, 148, 146, 144, 142, 140, 138], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [20, 20, 20, 22, 23, 23, 23, 22, 21, 20, 20, 20, 20, 20, 20, 20], + "hi_sigma": [167, 167, 167, 176, 187, 188, 184, 178, 170, 167, 167, 167, 167, 167, 167, 167] + }, { + "iso": 200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [178, 191, 198, 201, 205, 205, 204, 203, 201, 198, 196, 193, 191, 188, 186, 184], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [25, 26, 27, 28, 28, 28, 28, 28, 27, 27, 27, 26, 26, 25, 25, 25], + "hi_sigma": [203, 209, 219, 225, 230, 230, 229, 226, 223, 220, 216, 212, 208, 205, 203, 203] + }, { + "iso": 400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [275, 292, 301, 307, 312, 312, 310, 308, 304, 300, 296, 291, 287, 283, 279, 276], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [34, 36, 37, 38, 39, 39, 38, 38, 38, 37, 37, 36, 35, 35, 34, 34], + "hi_sigma": [275, 292, 301, 307, 312, 312, 310, 308, 304, 300, 296, 291, 287, 283, 279, 276] + }, { + "iso": 800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [313, 339, 351, 357, 363, 364, 363, 360, 357, 354, 350, 346, 342, 339, 336, 334], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [40, 43, 45, 45, 46, 46, 46, 46, 45, 45, 44, 44, 43, 43, 43, 42], + "hi_sigma": [322, 347, 360, 367, 373, 374, 373, 370, 367, 363, 359, 355, 351, 347, 344, 342] + }, { + "iso": 1600, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [442, 479, 496, 505, 514, 515, 513, 510, 506, 501, 495, 490, 484, 479, 476, 472], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [55, 59, 62, 63, 64, 64, 64, 63, 63, 62, 61, 61, 60, 59, 59, 59], + "hi_sigma": [442, 479, 496, 505, 514, 515, 513, 510, 506, 501, 495, 490, 484, 479, 476, 472] + }, { + "iso": 3200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [626, 678, 701, 714, 726, 728, 725, 721, 715, 708, 700, 692, 685, 678, 673, 668], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [78, 84, 87, 89, 90, 91, 90, 90, 89, 88, 87, 86, 85, 84, 84, 83], + "hi_sigma": [626, 678, 701, 714, 726, 728, 725, 721, 715, 708, 700, 692, 685, 678, 673, 668] + }, { + "iso": 6400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [884, 959, 992, 1011, 1027, 1030, 1026, 1020, 1011, 1001, 991, 979, 968, 959, 951, 945], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [110, 119, 124, 126, 128, 128, 128, 127, 126, 125, 123, 122, 121, 119, 118, 118], + "hi_sigma": [884, 959, 992, 1011, 1027, 1030, 1026, 1020, 1011, 1001, 991, 979, 968, 959, 951, 945] + }, { + "iso": 12800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1450, 1457, 1456, 1450, 1435, 1423, 1419, 1420, 1420, 1414, 1401, 1378, 1349, 1319, 1292, 1270], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [181, 182, 182, 181, 179, 177, 177, 177, 177, 176, 175, 172, 168, 164, 161, 158], + "hi_sigma": [1450, 1457, 1456, 1450, 1435, 1423, 1419, 1420, 1420, 1414, 1401, 1378, 1349, 1319, 1292, 1270] + }, { + "iso": 25600, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1702, 1789, 1841, 1876, 1918, 1941, 1953, 1955, 1949, 1934, 1910, 1879, 1844, 1809, 1778, 1751], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [212, 223, 230, 234, 239, 242, 244, 244, 243, 241, 238, 234, 230, 226, 222, 218], + "hi_sigma": [1702, 1789, 1841, 1876, 1918, 1941, 1953, 1955, 1949, 1934, 1910, 1879, 1844, 1809, 1778, 1751] + }, { + "iso": 51200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1851, 1847, 1845, 1843, 1842, 1844, 1846, 1848, 1848, 1848, 1846, 1842, 1837, 1830, 1821, 1812], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [409, 406, 404, 402, 399, 398, 398, 399, 400, 400, 400, 399, 398, 395, 391, 391], + "hi_sigma": [1856, 1851, 1848, 1846, 1845, 1847, 1850, 1852, 1853, 1852, 1849, 1845, 1838, 1829, 1819, 1807] + }, { + "iso": 102400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1851, 1847, 1845, 1843, 1842, 1844, 1846, 1848, 1848, 1848, 1846, 1842, 1837, 1830, 1821, 1812], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [409, 406, 404, 402, 399, 398, 398, 399, 400, 400, 400, 399, 398, 395, 391, 391], + "hi_sigma": [1856, 1851, 1848, 1846, 1845, 1847, 1850, 1852, 1853, 1852, 1849, 1845, 1838, 1829, 1819, 1807] + }, { + "iso": 204800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1851, 1847, 1845, 1843, 1842, 1844, 1846, 1848, 1848, 1848, 1846, 1842, 1837, 1830, 1821, 1812], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [409, 406, 404, 402, 399, 398, 398, 399, 400, 400, 400, 399, 398, 395, 391, 391], + "hi_sigma": [1856, 1851, 1848, 1846, 1845, 1847, 1850, 1852, 1853, 1852, 1849, 1845, 1838, 1829, 1819, 1807] + }], + "Calib_ISO_len": 13 + }, { + "SNR_Mode": "HSNR", + "Sensor_Mode": "hcg", + "Calib_ISO": [{ + "iso": 50, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [93, 106, 115, 121, 128, 130, 128, 124, 117, 110, 103, 95, 88, 87, 87, 87], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "hi_sigma": [256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256] + }, { + "iso": 100, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [124, 143, 156, 166, 177, 180, 177, 172, 163, 154, 144, 134, 124, 116, 108, 101], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "hi_sigma": [256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256] + }, { + "iso": 200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [182, 207, 225, 237, 251, 254, 251, 242, 231, 217, 203, 189, 176, 165, 154, 142], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "hi_sigma": [256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256] + }, { + "iso": 400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [262, 297, 321, 338, 357, 361, 356, 344, 327, 308, 288, 269, 251, 234, 219, 202], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "hi_sigma": [262, 297, 321, 338, 357, 361, 356, 344, 327, 308, 288, 269, 256, 256, 256, 256] + }, { + "iso": 800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [405, 448, 479, 500, 523, 525, 515, 495, 469, 441, 412, 384, 358, 335, 312, 287], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "hi_sigma": [405, 448, 479, 500, 523, 525, 515, 495, 469, 441, 412, 384, 358, 335, 312, 287] + }, { + "iso": 1600, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [587, 624, 652, 671, 690, 691, 678, 656, 627, 595, 560, 525, 491, 457, 422, 383], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 32, 41, 49, 58, 62, 62, 60, 57, 53, 48, 42, 37, 32, 32, 32], + "hi_sigma": [587, 624, 652, 671, 690, 691, 678, 656, 627, 595, 560, 525, 491, 457, 422, 383] + }, { + "iso": 3200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [618, 760, 855, 919, 991, 1010, 995, 958, 908, 851, 794, 740, 692, 648, 606, 552], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 46, 70, 84, 98, 103, 101, 96, 88, 79, 69, 59, 50, 44, 39, 34], + "hi_sigma": [618, 760, 855, 919, 991, 1010, 995, 958, 908, 851, 794, 740, 692, 648, 606, 552] + }, { + "iso": 6400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [881, 1087, 1225, 1320, 1426, 1456, 1438, 1388, 1318, 1238, 1155, 1076, 1004, 937, 869, 784], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 32, 49, 116, 168, 186, 188, 180, 167, 150, 133, 117, 105, 97, 90, 81], + "hi_sigma": [881, 1087, 1225, 1320, 1426, 1456, 1438, 1388, 1318, 1238, 1155, 1076, 1004, 937, 869, 784] + }, { + "iso": 12800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1227, 1514, 1710, 1849, 2014, 2077, 2074, 2024, 1942, 1839, 1725, 1605, 1484, 1362, 1231, 1076], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 39, 131, 176, 233, 265, 283, 290, 286, 274, 253, 225, 190, 148, 99, 44], + "hi_sigma": [1227, 1514, 1710, 1849, 2014, 2077, 2074, 2024, 1942, 1839, 1725, 1605, 1484, 1362, 1231, 1076] + }, { + "iso": 25600, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [1819, 2060, 2254, 2413, 2650, 2803, 2889, 2916, 2892, 2821, 2705, 2548, 2350, 2113, 1836, 1520], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [516, 425, 352, 304, 293, 358, 440, 509, 557, 580, 575, 542, 479, 387, 264, 98], + "hi_sigma": [1819, 2060, 2254, 2413, 2650, 2803, 2889, 2916, 2892, 2821, 2705, 2548, 2350, 2113, 1836, 1520] + }, { + "iso": 51200, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [159, 188, 208, 222, 238, 243, 240, 233, 222, 209, 195, 182, 170, 159, 149, 138], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "hi_sigma": [256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256] + }, { + "iso": 102400, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [159, 188, 208, 222, 238, 243, 240, 233, 222, 209, 195, 182, 170, 159, 149, 138], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "hi_sigma": [256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256] + }, { + "iso": 204800, + "lumapoint": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "sigma": [159, 188, 208, 222, 238, 243, 240, 233, 222, 209, 195, 182, 170, 159, 149, 138], + "lumapoint2": [512, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336], + "lo_sigma": [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32], + "hi_sigma": [256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256] + }], + "Calib_ISO_len": 13 + }], + "Setting_len": 2 + }, + "TuningPara": { + "enable": 1, + "thumbds_w": 8, + "thumbds_h": 4, + "trans_en": 0, + "lo_enable": 1, + "Setting": [{ + "SNR_Mode": "LSNR", + "Sensor_Mode": "lcg", + "Tuning_ISO": [{ + "iso": 50, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 0.3, + "lo_filter_thed0": 2, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.1, + "hi_filter_thed0": 4, + "hi_filter_rat1": 0.1, + "hi_filter_thed1": 160, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 100, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 0.3, + "lo_filter_thed0": 2, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.15, + "hi_filter_thed0": 4, + "hi_filter_rat1": 0.1, + "hi_filter_thed1": 240, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 200, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 0.3, + "lo_filter_thed0": 2, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.15, + "hi_filter_thed0": 4, + "hi_filter_rat1": 0.1, + "hi_filter_thed1": 280, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 400, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 0.3, + "lo_filter_thed0": 2, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.15, + "hi_filter_thed0": 4, + "hi_filter_rat1": 0.1, + "hi_filter_thed1": 360, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 800, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 0.4, + "lo_filter_thed0": 4, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.15, + "hi_filter_thed0": 2, + "hi_filter_rat1": 0.15, + "hi_filter_thed1": 400, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 1600, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.06, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 0.5, + "lo_filter_thed0": 4, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.2, + "hi_filter_thed0": 2, + "hi_filter_rat1": 0.3, + "hi_filter_thed1": 480, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 3200, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 0.5, + "lo_filter_thed0": 12, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.25, + "hi_filter_thed0": 2, + "hi_filter_rat1": 0.3, + "hi_filter_thed1": 540, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 6400, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 0.5, + "lo_filter_thed0": 32, + "hi_filter_abs_ctrl": 1, + "hi_filter_filt_bay": 1, + "hi_filter_filt_avg": 1, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.4, + "hi_filter_thed0": 8, + "hi_filter_rat1": 0.1, + "hi_filter_thed1": 960, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 12800, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 1, + "hi_filter_filt_bay": 1, + "hi_filter_filt_avg": 1, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.5, + "hi_filter_thed0": 8, + "hi_filter_rat1": 0.1, + "hi_filter_thed1": 1000, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 25600, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 1, + "hi_filter_filt_bay": 1, + "hi_filter_filt_avg": 1, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.4, + "hi_filter_thed0": 8, + "hi_filter_rat1": 0.1, + "hi_filter_thed1": 1000, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 51200, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03125, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 0.5, + "lo_filter_thed0": 50, + "hi_filter_abs_ctrl": 1, + "hi_filter_filt_bay": 1, + "hi_filter_filt_avg": 1, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0.5, + "hi_filter_thed0": 8, + "hi_filter_rat1": 0.1, + "hi_filter_thed1": 1500, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 102400, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 0.5, + "lo_clipwgt": 0.125, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 1, + "hi_filter_thed0": 1024, + "hi_filter_rat1": 16, + "hi_filter_thed1": 4095, + "guass_guide_coeff0": 0, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 204800, + "hi_enable": 0, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 1, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 8, + "hi_filter_strength": 1, + "lo_clipwgt": 0.125, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 2, + "hi_filter_thed0": 4095, + "hi_filter_rat1": 16, + "hi_filter_thed1": 4095, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }], + "Tuning_ISO_len": 13 + }, { + "SNR_Mode": "HSNR", + "Sensor_Mode": "hcg", + "Tuning_ISO": [{ + "iso": 50, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 100, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 200, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 400, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 800, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 1600, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1.5, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 3200, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1, + "hi_filter_strength": 1.5, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 6400, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 1.5, + "hi_filter_strength": 1.6, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 12800, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 2, + "hi_filter_strength": 2, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 25600, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 2, + "hi_filter_strength": 2, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 51200, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 2, + "hi_filter_strength": 2, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 102400, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 2, + "hi_filter_strength": 2, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }, { + "iso": 204800, + "hi_enable": 1, + "lo_med_en": 1, + "lo_gsbay_en": 1, + "lo_gslum_en": 1, + "hi_med_en": 1, + "hi_gslum_en": 1, + "wgt_use_mode": 0, + "wgt_mge_mode": 1, + "hi_guass": 0, + "kl_guass": 0, + "global_pk_en": 0, + "global_pksq": 1024, + "lo_filter_strength": 2, + "hi_filter_strength": 2, + "lo_clipwgt": 0.03215, + "soft_threshold_ratio": 0, + "hi_wgt_comp": 0.16, + "hidif_th": 32767, + "lo_filter_rat0": 1, + "lo_filter_thed0": 0, + "hi_filter_abs_ctrl": 0, + "hi_filter_filt_bay": 0, + "hi_filter_filt_avg": 0, + "hi_filter_filt_mode": 4, + "hi_filter_rat0": 0, + "hi_filter_thed0": 256, + "hi_filter_rat1": 0, + "hi_filter_thed1": 1024, + "guass_guide_coeff0": 16, + "guass_guide_coeff1": 8, + "guass_guide_coeff2": 16, + "guass_guide_coeff3": 8 + }], + "Tuning_ISO_len": 13 + }], + "Setting_len": 2 + } + }, + "ynr_v22": { + "Version": "V22", + "CalibPara": { + "Setting": [{ + "SNR_Mode": "LSNR", + "Sensor_Mode": "lcg", + "Calib_ISO": [{ + "iso": 50, + "sigma_curve": [-1.0704534e-012, 9.59988710747e-009, -2.98770428344142e-005, 0.0367235988378525, 6.1354341506958], + "ynr_lci": 0.261, + "ynr_hci": 0.252 + }, { + "iso": 100, + "sigma_curve": [-1.62946512e-012, 1.475918498528e-008, -4.65335360786412e-005, 0.0582773014903069, 4.26375579833984], + "ynr_lci": 0.262, + "ynr_hci": 0.24 + }, { + "iso": 200, + "sigma_curve": [-2.64321182e-012, 2.439001711707e-008, -7.9015335359145e-005, 0.103473775088787, -6.69485139846802], + "ynr_lci": 0.271, + "ynr_hci": 0.238 + }, { + "iso": 400, + "sigma_curve": [-3.86016002e-012, 3.506774959305e-008, -0.000111157853098121, 0.140963718295097, -4.94111204147339], + "ynr_lci": 0.267, + "ynr_hci": 0.229 + }, { + "iso": 800, + "sigma_curve": [-6.07670338e-012, 5.565359728621e-008, -0.000178284404682927, 0.228970438241959, -20.7933616638184], + "ynr_lci": 0.27, + "ynr_hci": 0.228 + }, { + "iso": 1600, + "sigma_curve": [-8.59375592e-012, 7.870607277027e-008, -0.000252132216701284, 0.323813110589981, -29.4062557220459], + "ynr_lci": 0.27, + "ynr_hci": 0.228 + }, { + "iso": 3200, + "sigma_curve": [-1.215340675e-011, 1.1130719457242e-007, -0.000356568809365854, 0.457940876483917, -41.5867233276367], + "ynr_lci": 0.27, + "ynr_hci": 0.228 + }, { + "iso": 6400, + "sigma_curve": [-1.718751183e-011, 1.5741214554055e-007, -0.000504264433402568, 0.647626221179962, -58.8125114440918], + "ynr_lci": 0.27, + "ynr_hci": 0.228 + }, { + "iso": 12800, + "sigma_curve": [-2.031949956e-011, 1.7461699997057e-007, -0.000520054018124938, 0.562116026878357, 180.182998657227], + "ynr_lci": 0.246, + "ynr_hci": 0.18 + }, { + "iso": 25600, + "sigma_curve": [-8.62921973e-012, 6.986780221041e-008, -0.00023041499662213, 0.306571990251541, 345.350006103516], + "ynr_lci": 0.256, + "ynr_hci": 0.192 + }, { + "iso": 51200, + "sigma_curve": [-1.687899993e-011, 1.4281299343111e-007, -0.000423458986915648, 0.447443008422852, 256.085998535156], + "ynr_lci": 0.247, + "ynr_hci": 0.178 + }, { + "iso": 102400, + "sigma_curve": [-1.687899993e-011, 1.4281299343111e-007, -0.000423458986915648, 0.447443008422852, 256.085998535156], + "ynr_lci": 0.247, + "ynr_hci": 0.178 + }, { + "iso": 204800, + "sigma_curve": [-1.687899993e-011, 1.4281299343111e-007, -0.000423458986915648, 0.447443008422852, 256.085998535156], + "ynr_lci": 0.247, + "ynr_hci": 0.178 + }], + "Calib_ISO_len": 13 + }, { + "SNR_Mode": "HSNR", + "Sensor_Mode": "hcg", + "Calib_ISO": [{ + "iso": 50, + "sigma_curve": [-2.69646e-013, 2.86064e-009, -1.0481e-005, 0.012482, 14.805], + "ynr_lci": 0.226678, + "ynr_hci": 0.289415 + }, { + "iso": 100, + "sigma_curve": [-6.12691e-013, 5.89558e-009, -2.01077e-005, 0.0243184, 15.9406], + "ynr_lci": 0.215314, + "ynr_hci": 0.259995 + }, { + "iso": 200, + "sigma_curve": [7.09575e-014, 3.7711e-011, -2.56293e-006, 0.000338655, 38.6948], + "ynr_lci": 0.214596, + "ynr_hci": 0.228294 + }, { + "iso": 400, + "sigma_curve": [1.02018e-012, -8.86816e-009, 2.58194e-005, -0.036919, 69.0676], + "ynr_lci": 0.226733, + "ynr_hci": 0.217653 + }, { + "iso": 800, + "sigma_curve": [-5.61747e-012, 5.51053e-008, -0.00019652, 0.289936, -83.1767], + "ynr_lci": 0.242544, + "ynr_hci": 0.225505 + }, { + "iso": 1600, + "sigma_curve": [-7.40282e-012, 7.23099e-008, -0.000253899, 0.358878, -78.3104], + "ynr_lci": 0.205196, + "ynr_hci": 0.204973 + }, { + "iso": 3200, + "sigma_curve": [-2.26312e-012, 2.208e-008, -7.31596e-005, 0.0590642, 157.423], + "ynr_lci": 0.184429, + "ynr_hci": 0.184878 + }, { + "iso": 6400, + "sigma_curve": [-6.95027e-012, 6.71032e-008, -0.000225873, 0.244609, 175.853], + "ynr_lci": 0.17518, + "ynr_hci": 0.173976 + }, { + "iso": 12800, + "sigma_curve": [-1.92617e-011, 1.8905e-007, -0.000663475, 0.882172, -34.6649], + "ynr_lci": 0.187721, + "ynr_hci": 0.180997 + }, { + "iso": 25600, + "sigma_curve": [-2.34723e-011, 2.29904e-007, -0.000815695, 1.12713, -82.7871], + "ynr_lci": 0.192701, + "ynr_hci": 0.195909 + }, { + "iso": 51200, + "sigma_curve": [-1.55114e-011, 1.48433e-007, -0.000552589, 0.803504, 197.286], + "ynr_lci": 0.187182, + "ynr_hci": 0.199207 + }, { + "iso": 102400, + "sigma_curve": [-7.80229e-013, 6.77367e-009, -2.20431e-005, 0.0298751, 10.9382], + "ynr_lci": 0.5, + "ynr_hci": 1 + }, { + "iso": 204800, + "sigma_curve": [-7.80229e-013, 6.77367e-009, -2.20431e-005, 0.0298751, 10.9382], + "ynr_lci": 0.5, + "ynr_hci": 1 + }], + "Calib_ISO_len": 13 + }], + "Setting_len": 2 + }, + "TuningPara": { + "enable": 1, + "Setting": [{ + "SNR_Mode": "LSNR", + "Sensor_Mode": "lcg", + "Tuning_ISO": [{ + "iso": 50, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 1, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 1, + "low_thred_adj": 8, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 8, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 0.6, + "hi_gain_alpha": 1, + "hi_center_weight": 8, + "hi_weight_offset": 0.05, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.3, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 100, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 1, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 1, + "low_thred_adj": 8, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 8, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 0.8, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.4, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 200, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 1, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 1, + "low_thred_adj": 8, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 8, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.4, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 400, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 2, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 2, + "low_thred_adj": 8, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 6, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.4, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 800, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.2, + "ynr_adjust_scale": 2, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 2, + "low_thred_adj": 8, + "low_peak_supress": 0.4, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 4, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.5, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 1600, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.2, + "ynr_adjust_scale": 2, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1.3, 1.3, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1.3, 1.3, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 2, + "low_thred_adj": 8, + "low_peak_supress": 0.3, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 4, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.05, + "hi_min_sigma": 0.005, + "hi_nr_weight": 0.5, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6] + }, { + "iso": 3200, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.2, + "ynr_adjust_scale": 3, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1.3, 1.3, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1.3, 1.3, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 2, + "low_thred_adj": 8, + "low_peak_supress": 0.2, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 2, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.05, + "hi_min_sigma": 0.005, + "hi_nr_weight": 0.5, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1.2, 1.5, 1.8, 2.4, 3, 3.5, 3.8, 4.2, 5] + }, { + "iso": 6400, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.2, + "ynr_adjust_scale": 3, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1.3, 1.3, 1.2, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1.3, 1.3, 1.2, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 2, + "low_thred_adj": 8, + "low_peak_supress": 0.1, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 2, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.05, + "hi_min_sigma": 0.015, + "hi_nr_weight": 0.5, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1.1, 1.2, 2.4, 3.6, 4.8, 6, 7.3, 8.5] + }, { + "iso": 12800, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.2, + "ynr_adjust_scale": 2, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1.3, 1.3, 1.2, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1.3, 1.3, 1.2, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 2, + "low_thred_adj": 8, + "low_peak_supress": 0.1, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 1, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 2, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.05, + "hi_min_sigma": 0.02, + "hi_nr_weight": 0.5, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1.1, 1.2, 2.4, 3.6, 4.8, 6, 7.3, 8.5] + }, { + "iso": 25600, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.1, + "ynr_adjust_scale": 2, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1.3, 1.3, 1.2, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1.3, 1.3, 1.2, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 2, + "low_thred_adj": 8, + "low_peak_supress": 0.1, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 1, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 4, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.05, + "hi_min_sigma": 0.05, + "hi_nr_weight": 0.6, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1.3, 1.5, 2, 3.5, 5.5, 8, 11, 15] + }, { + "iso": 51200, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.1, + "ynr_adjust_scale": 2, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 4, + "low_thred_adj": 8, + "low_peak_supress": 0.1, + "low_edge_adj_thresh": 2, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.5, + "low_dist_adj": 1, + "low_weight": 0.3, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 4, + "hi_gain_alpha": 1, + "hi_center_weight": 0.08, + "hi_weight_offset": 0.05, + "hi_min_sigma": 0.1, + "hi_nr_weight": 0.6, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 102400, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 1, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 2, + "low_bf2": 5, + "low_thred_adj": 5, + "low_peak_supress": 0.3, + "low_edge_adj_thresh": 8, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.1, + "low_dist_adj": 8, + "low_weight": 0.5, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.4, + "hi_bf_scale": 5, + "hi_gain_alpha": 1, + "hi_center_weight": 0.05, + "hi_weight_offset": 0.05, + "hi_min_sigma": 0.2, + "hi_nr_weight": 1, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 204800, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.1, + "ynr_adjust_scale": 0.5, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 4, + "low_bf2": 16, + "low_thred_adj": 31, + "low_peak_supress": 0.3, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.1, + "low_dist_adj": 8, + "low_weight": 0.5, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.4, + "hi_bf_scale": 16, + "hi_gain_alpha": 1, + "hi_center_weight": 1, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 1, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }], + "Tuning_ISO_len": 13 + }, { + "SNR_Mode": "HSNR", + "Sensor_Mode": "hcg", + "Tuning_ISO": [{ + "iso": 50, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 1, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 0.5, + "low_thred_adj": 0.5, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.4, + "low_dist_adj": 8, + "low_weight": 0.5, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.2, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.5, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 100, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 1, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 0.5, + "low_thred_adj": 0.5, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.35, + "low_dist_adj": 8, + "low_weight": 0.5, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.2, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.5, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 200, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 1.5, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 0.5, + "low_thred_adj": 0.5, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.3, + "low_dist_adj": 8, + "low_weight": 0.5, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.2, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.8, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.5, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 400, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 2, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 0.5, + "low_thred_adj": 0.5, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.25, + "low_dist_adj": 8, + "low_weight": 0.5, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.7, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.78, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 800, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 2, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.4, + "low_bf2": 0.5, + "low_thred_adj": 0.4, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.2, + "low_dist_adj": 8, + "low_weight": 0.5, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.7, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.55, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 1600, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 3, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 0.5, + "low_thred_adj": 0.3, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.2, + "low_dist_adj": 8, + "low_weight": 0.5, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1.5, + "hi_gain_alpha": 1, + "hi_center_weight": 0.7, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.55, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 3200, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 4, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 0.5, + "low_thred_adj": 0.3, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.2, + "low_dist_adj": 8, + "low_weight": 0.78, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 2, + "hi_gain_alpha": 1, + "hi_center_weight": 0.7, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.4, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 6400, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 5, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.5, + "low_bf2": 0.5, + "low_thred_adj": 0.4, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.2, + "low_dist_adj": 8, + "low_weight": 0.78, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 0.7, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.4, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 12800, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 6, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 0.6, + "low_bf2": 0.6, + "low_thred_adj": 0.6, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.2, + "low_dist_adj": 8, + "low_weight": 0.78, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.3, + "hi_bf_scale": 1.5, + "hi_gain_alpha": 1, + "hi_center_weight": 0.6, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.5, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 25600, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 8, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 1, + "low_bf2": 1, + "low_thred_adj": 0.9, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.2, + "low_dist_adj": 8, + "low_weight": 0.85, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.4, + "hi_bf_scale": 2, + "hi_gain_alpha": 1, + "hi_center_weight": 0.5, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.5, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 51200, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 8, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 1, + "low_bf2": 1, + "low_thred_adj": 1, + "low_peak_supress": 0.5, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.2, + "low_dist_adj": 8, + "low_weight": 0.85, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.4, + "hi_bf_scale": 2, + "hi_gain_alpha": 1, + "hi_center_weight": 0.5, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.6, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 102400, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 6, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 1, + "low_bf2": 1, + "low_thred_adj": 1, + "low_peak_supress": 0.3, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.3, + "low_dist_adj": 8, + "low_weight": 0.6, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.4, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 1, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.78, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }, { + "iso": 204800, + "ynr_bft3x3_bypass": 0, + "ynr_lbft5x5_bypass": 0, + "ynr_lgft3x3_bypass": 0, + "ynr_flt1x1_bypass": 0, + "ynr_nlm11x11_bypass": 0, + "ynr_thumb_mix_cur_en": 0, + "ynr_global_gain_alpha": 0, + "ynr_global_gain": 1, + "ynr_adjust_thresh": 0.3, + "ynr_adjust_scale": 6, + "lumaPara": { + "lo_lumaPoint": [0, 32, 64, 128, 192, 256], + "lo_ratio": [1, 1, 1, 1, 1, 1], + "hi_lumaPoint": [0, 32, 64, 128, 192, 256], + "hi_ratio": [1, 1, 1, 1, 1, 1] + }, + "low_bf1": 1, + "low_bf2": 1, + "low_thred_adj": 1, + "low_peak_supress": 0.3, + "low_edge_adj_thresh": 7, + "low_lbf_weight_thresh": 0.25, + "low_center_weight": 0.3, + "low_dist_adj": 8, + "low_weight": 0.6, + "low_filt1_strength": 0.7, + "low_filt2_strength": 0.85, + "low_bi_weight": 0.4, + "hi_bf_scale": 1, + "hi_gain_alpha": 1, + "hi_center_weight": 1, + "hi_weight_offset": 0.0498, + "hi_min_sigma": 0.0068, + "hi_nr_weight": 0.78, + "hi_filter_coeff1_1": 7, + "hi_filter_coeff1_2": 6, + "hi_filter_coeff1_3": 3, + "hi_filter_coeff2_1": 6, + "hi_filter_coeff2_2": 5, + "hi_filter_coeff2_3": 3, + "rnr_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }], + "Tuning_ISO_len": 13 + }], + "Setting_len": 2 + } + }, + "cnr_v30": { + "Version": "V30", + "TuningPara": { + "enable": 1, + "Setting": [{ + "SNR_Mode": "LSNR", + "Sensor_Mode": "lcg", + "Tuning_ISO": [{ + "iso": 50, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.0039, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.0078, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.0314, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 0.3, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.7, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 100, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.005, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.0078, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.0314, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 0.3, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.6, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 200, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.01, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.01, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.04, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 0.3, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.5, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 400, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.02, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.02, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.04, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 0.5, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.4, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 800, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.03, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.03, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.05, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 0.8, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.3, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 1600, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.04, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.04, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.05, + "bf_uvgain": 3.5, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.2, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 3200, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.05, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.05, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.04, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.2, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 6400, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.06, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.1, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.1, + "bf_uvgain": 2.5, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.15, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.3, 0.2, 0.1, 0.1, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 12800, + "down_scale_x": 8, + "down_scale_y": 6, + "thumb_sigma": 0.08, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.18, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.1, + "bf_uvgain": 2, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.1, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 25600, + "down_scale_x": 8, + "down_scale_y": 6, + "thumb_sigma": 0.08, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.12, + "chroma_filter_wgt_clip": 10, + "anti_chroma_ghost": 0.03, + "chroma_filter_uv_gain": 0.2, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.1, + "bf_uvgain": 1.5, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 32, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.1, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 51200, + "down_scale_x": 8, + "down_scale_y": 6, + "thumb_sigma": 0.8121, + "thumb_bf_ratio": 0.65, + "chroma_filter_strength": 0.05, + "chroma_filter_wgt_clip": 8, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.6, + "bf_uvgain": 1, + "bf_ratio": 0.2, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 32, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.1, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 1, 1, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 102400, + "down_scale_x": 8, + "down_scale_y": 6, + "thumb_sigma": 0.7, + "thumb_bf_ratio": 0.7, + "chroma_filter_strength": 0.08, + "chroma_filter_wgt_clip": 5, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.6, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.002, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 1, 1, 0.6, 0.2, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 204800, + "down_scale_x": 8, + "down_scale_y": 6, + "thumb_sigma": 0.5, + "thumb_bf_ratio": 0.7, + "chroma_filter_strength": 0.3, + "chroma_filter_wgt_clip": 8, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.8, + "bf_uvgain": 1, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.01, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 1, 1, 0.7, 0.4, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }], + "Tuning_ISO_len": 13 + }, { + "SNR_Mode": "HSNR", + "Sensor_Mode": "hcg", + "Tuning_ISO": [{ + "iso": 50, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.0039, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.0078, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.0314, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.7, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 100, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.005, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.0078, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.0314, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.6, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 200, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.01, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.01, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.04, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.5, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 400, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.02, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.02, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.04, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.4, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 800, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.03, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.03, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.05, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.3, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 1600, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.04, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.04, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.05, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.2, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 3200, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.05, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.05, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.06, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.2, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 6400, + "down_scale_x": 8, + "down_scale_y": 6, + "thumb_sigma": 0.06, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.06, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.07, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.15, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 12800, + "down_scale_x": 8, + "down_scale_y": 6, + "thumb_sigma": 0.1, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.1, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.1, + "bf_uvgain": 2.4, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.1, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 25600, + "down_scale_x": 8, + "down_scale_y": 6, + "thumb_sigma": 0.15, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.15, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.1, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.15, + "bf_uvgain": 1.5, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.1, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 51200, + "down_scale_x": 8, + "down_scale_y": 6, + "thumb_sigma": 0.2, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.2, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.2, + "bf_uvgain": 1.5, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.1, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 102400, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.0039, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.0078, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.0314, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.002, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }, { + "iso": 204800, + "down_scale_x": 4, + "down_scale_y": 4, + "thumb_sigma": 0.0039, + "thumb_bf_ratio": 1, + "chroma_filter_strength": 0.0078, + "chroma_filter_wgt_clip": 0.9, + "anti_chroma_ghost": 0.0313, + "chroma_filter_uv_gain": 0.333, + "wgt_slope": 0.7, + "gaus_ratio": 1, + "bf_sigmaR": 0.0314, + "bf_uvgain": 3, + "bf_ratio": 0.0625, + "hbf_wgt_clip": 0.0078, + "bf_wgt0_sel": 0, + "global_alpha": 1, + "saturation_adj_offset": 0, + "saturation_adj_ratio": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gain_scale": 0.01, + "global_gain_thumb": 1, + "global_gain_alpha_thumb": 0, + "gain_adj_strength_ratio": [1, 0.7, 0.5, 0.3, 0.2, 0.1, 0.1, 0.09, 0.07, 0.05, 0.03, 0.02, 0.02], + "thumb_filter_wgt_coeff": [1, 1, 1, 1], + "gaus_coeff": [48, 28, 6, 28, 17, 4] + }], + "Tuning_ISO_len": 13 + }], + "Setting_len": 2 + } + }, + "sharp_v33": { + "Version": "V33", + "TuningPara": { + "enable": 1, + "sharp_ratio_seperate_en": 0, + "kernel_sigma_enable": 1, + "Center_Mode": 1, + "Setting": [{ + "SNR_Mode": "LSNR", + "Sensor_Mode": "lcg", + "Tuning_ISO": [{ + "iso": 50, + "exgain_bypass": 0, + "pbf_gain": 0.4, + "pbf_ratio": 0.2, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 5, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.5, + "bf_ratio": 0.25, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.1, + "enhance_bit": 3, + "noiseclip_mode": 1, + "noise_sigma_clip": 2, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 128, 256, 320, 384, 512, 768, 1024], + "luma_sigma": [20, 24, 24, 28, 28, 28, 24, 20], + "hf_clip": [64, 108, 172, 256, 324, 388, 348, 348] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 100, + "exgain_bypass": 0, + "pbf_gain": 0.6, + "pbf_ratio": 0.3, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 5, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.8, + "bf_ratio": 0.4, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.1, + "enhance_bit": 3, + "noiseclip_mode": 1, + "noise_sigma_clip": 2, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 128, 256, 320, 384, 512, 768, 1024], + "luma_sigma": [20, 24, 28, 32, 32, 32, 28, 24], + "hf_clip": [64, 96, 128, 172, 256, 348, 328, 308] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 200, + "exgain_bypass": 0, + "pbf_gain": 0.8, + "pbf_ratio": 0.4, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 5, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.8, + "bf_ratio": 0.4, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.1, + "enhance_bit": 3, + "noiseclip_mode": 1, + "noise_sigma_clip": 2, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 128, 256, 320, 384, 512, 768, 1024], + "luma_sigma": [24, 28, 32, 36, 40, 40, 36, 32], + "hf_clip": [48, 72, 128, 156, 208, 256, 256, 228] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 400, + "exgain_bypass": 0, + "pbf_gain": 1, + "pbf_ratio": 0.5, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 5, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 1, + "bf_ratio": 0.5, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.1, + "enhance_bit": 3, + "noiseclip_mode": 1, + "noise_sigma_clip": 2, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 128, 256, 320, 384, 512, 768, 1024], + "luma_sigma": [28, 32, 36, 44, 48, 48, 42, 36], + "hf_clip": [48, 72, 96, 128, 156, 192, 240, 240] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 800, + "exgain_bypass": 0, + "pbf_gain": 1, + "pbf_ratio": 0.3, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 4, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 1, + "bf_ratio": 0.5, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.1, + "enhance_bit": 3, + "noiseclip_mode": 1, + "noise_sigma_clip": 2, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 128, 256, 320, 384, 512, 768, 1024], + "luma_sigma": [32, 36, 44, 48, 48, 48, 44, 40], + "hf_clip": [24, 36, 64, 96, 128, 168, 192, 192] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 1600, + "exgain_bypass": 0, + "pbf_gain": 1, + "pbf_ratio": 0.5, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 3, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 1, + "bf_ratio": 0.6, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.1, + "enhance_bit": 4, + "noiseclip_mode": 1, + "noise_sigma_clip": 2, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 128, 256, 320, 384, 512, 768, 1024], + "luma_sigma": [36, 40, 48, 56, 64, 64, 56, 48], + "hf_clip": [20, 48, 96, 128, 156, 192, 192, 178] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 0.9, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 3200, + "exgain_bypass": 0, + "pbf_gain": 1.2, + "pbf_ratio": 0.5, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 3, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 1.2, + "bf_ratio": 0.6, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.1, + "enhance_bit": 4, + "noiseclip_mode": 1, + "noise_sigma_clip": 2, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 0.5, 0.1, 0.05, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 80, 80, 64, 56], + "hf_clip": [20, 32, 48, 72, 108, 156, 156, 128] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 0.85, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 6400, + "exgain_bypass": 0, + "pbf_gain": 1.5, + "pbf_ratio": 0.5, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 8, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 1.5, + "bf_ratio": 0.6, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.4, + "enhance_bit": 4, + "noiseclip_mode": 1, + "noise_sigma_clip": 2, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 0.8, 0.5, 0.3, 0.1, 0.01, 0.01, 0.01, 0.01, 0.01], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [16, 32, 48, 64, 96, 128, 128, 96] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 0.8, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 12800, + "exgain_bypass": 0, + "pbf_gain": 2, + "pbf_ratio": 0.5, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 8, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 2, + "bf_ratio": 0.6, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.5, + "enhance_bit": 4, + "noiseclip_mode": 1, + "noise_sigma_clip": 2, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 0.8, 0.5, 0.3, 0.1, 0.01, 0.01, 0.01, 0.01, 0.01], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [12, 24, 36, 48, 80, 96, 96, 80] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 0.8, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 25600, + "exgain_bypass": 0, + "pbf_gain": 2, + "pbf_ratio": 0.3, + "pbf_add": 0, + "gaus_ratio": 0.5, + "sharp_ratio": 6, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 2, + "bf_ratio": 0.6, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.6, + "enhance_bit": 4, + "noiseclip_mode": 1, + "noise_sigma_clip": 1, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [24, 48, 80, 112, 128, 160, 128, 104] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 0.75, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 51200, + "exgain_bypass": 0, + "pbf_gain": 2, + "pbf_ratio": 0.4, + "pbf_add": 0, + "gaus_ratio": 0.5, + "sharp_ratio": 4, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 2, + "bf_ratio": 0.6, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0.8, + "enhance_bit": 4, + "noiseclip_mode": 1, + "noise_sigma_clip": 1, + "gain_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [24, 48, 80, 112, 128, 160, 128, 104] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 0.7, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 102400, + "exgain_bypass": 0, + "pbf_gain": 0.6, + "pbf_ratio": 0.6, + "pbf_add": 0, + "gaus_ratio": 0.5, + "sharp_ratio": 6, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.4, + "bf_ratio": 0.4, + "bf_add": 32, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0, + "enhance_bit": 0, + "noiseclip_mode": 0, + "noise_sigma_clip": 0, + "gain_adj_sharp_strength": [0.5, 0.5, 0.5, 0.5, 0.3, 0.3, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [16, 32, 64, 80, 80, 80, 80, 80] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1.2, + "hfBilateralFilter_sigma": 1.2, + "GaussianFilter_sigma": 1.8, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 204800, + "exgain_bypass": 0, + "pbf_gain": 0.2, + "pbf_ratio": 0.2, + "pbf_add": 1, + "gaus_ratio": 1, + "sharp_ratio": 0.5, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 4, + "bf_ratio": 1, + "bf_add": 32, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 0, + "enhance_bit": 0, + "noiseclip_mode": 0, + "noise_sigma_clip": 0, + "gain_adj_sharp_strength": [1, 1, 0.5, 0.3, 0.3, 0.3, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [16, 32, 64, 80, 80, 80, 80, 80] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 2, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }], + "Tuning_ISO_len": 13 + }, { + "SNR_Mode": "HSNR", + "Sensor_Mode": "hcg", + "Tuning_ISO": [{ + "iso": 50, + "exgain_bypass": 0, + "pbf_gain": 0.5, + "pbf_ratio": 0.3, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 8, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.5, + "bf_ratio": 0.4, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [8, 12, 16, 16, 24, 20, 16, 16], + "hf_clip": [180, 180, 180, 180, 180, 180, 180, 180] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 100, + "exgain_bypass": 0, + "pbf_gain": 0.5, + "pbf_ratio": 0.3, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 8, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.5, + "bf_ratio": 0.3, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [12, 16, 20, 24, 28, 24, 20, 20], + "hf_clip": [180, 180, 180, 180, 180, 180, 180, 180] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 200, + "exgain_bypass": 0, + "pbf_gain": 0.3, + "pbf_ratio": 0.3, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 8, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.3, + "bf_ratio": 0.3, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [24, 32, 40, 48, 56, 48, 48, 40], + "hf_clip": [180, 180, 180, 180, 180, 180, 180, 180] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 400, + "exgain_bypass": 0, + "pbf_gain": 0.3, + "pbf_ratio": 0.3, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 8, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.3, + "bf_ratio": 0.3, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [32, 40, 48, 56, 64, 56, 48, 40], + "hf_clip": [180, 180, 180, 180, 180, 180, 180, 180] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 800, + "exgain_bypass": 0, + "pbf_gain": 0.3, + "pbf_ratio": 0.3, + "pbf_add": 0, + "gaus_ratio": 0, + "sharp_ratio": 8, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.3, + "bf_ratio": 0.4, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [40, 48, 56, 64, 80, 64, 56, 48], + "hf_clip": [180, 180, 180, 180, 180, 180, 180, 180] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 1600, + "exgain_bypass": 0, + "pbf_gain": 0.35, + "pbf_ratio": 0.3, + "pbf_add": 0, + "gaus_ratio": 0.3, + "sharp_ratio": 8, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.4, + "bf_ratio": 0.4, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [180, 180, 180, 180, 180, 180, 180, 180] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 3200, + "exgain_bypass": 0, + "pbf_gain": 0.3, + "pbf_ratio": 0, + "pbf_add": 0, + "gaus_ratio": 0.4, + "sharp_ratio": 7, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.4, + "bf_ratio": 0, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [180, 180, 180, 180, 180, 180, 180, 180] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 6400, + "exgain_bypass": 0, + "pbf_gain": 0.3, + "pbf_ratio": 0, + "pbf_add": 0, + "gaus_ratio": 0.5, + "sharp_ratio": 6, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 5, + "bf_ratio": 0.7, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [150, 150, 150, 150, 150, 150, 150, 150] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 12800, + "exgain_bypass": 0, + "pbf_gain": 0.4, + "pbf_ratio": 0.2, + "pbf_add": 0, + "gaus_ratio": 0.7, + "sharp_ratio": 5, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.5, + "bf_ratio": 0.2, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [120, 120, 120, 120, 120, 120, 120, 120] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 25600, + "exgain_bypass": 0, + "pbf_gain": 0.5, + "pbf_ratio": 0.5, + "pbf_add": 0, + "gaus_ratio": 0.8, + "sharp_ratio": 3, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.6, + "bf_ratio": 0.6, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [100, 100, 100, 100, 100, 100, 100, 100] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 51200, + "exgain_bypass": 0, + "pbf_gain": 0.5, + "pbf_ratio": 0.6, + "pbf_add": 0, + "gaus_ratio": 0.8, + "sharp_ratio": 3, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 0.5, + "bf_ratio": 0.8, + "bf_add": 0, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [100, 100, 100, 100, 100, 100, 100, 100] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.1621, 0.0983, 0.0596, 0.0219, 0.0133, 0.003], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 1, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 102400, + "exgain_bypass": 0, + "pbf_gain": 0.8, + "pbf_ratio": 0.4, + "pbf_add": 1, + "gaus_ratio": 0.4, + "sharp_ratio": 3, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 4, + "bf_ratio": 0.8, + "bf_add": 32, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [96, 128, 160, 192, 224, 192, 160, 0] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 2, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }, { + "iso": 204800, + "exgain_bypass": 0, + "pbf_gain": 0.8, + "pbf_ratio": 0.4, + "pbf_add": 1, + "gaus_ratio": 0.4, + "sharp_ratio": 8, + "sharp_ratio_0": 4, + "sharp_ratio_1": 4, + "bf_gain": 4, + "bf_ratio": 1, + "bf_add": 32, + "global_gain": 1, + "global_gain_alpha": 0, + "local_gainscale": 1, + "global_hf_clip_pos": 0, + "noiseclip_strength": 1, + "enhance_bit": 3, + "noiseclip_mode": 0, + "noise_sigma_clip": 1023, + "gain_adj_sharp_strength": [1, 0.9, 0.7, 0.5, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.07, 0.05, 0.001], + "dis_adj_sharp_strength": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "luma_para": { + "luma_point": [0, 64, 128, 256, 384, 640, 896, 1024], + "luma_sigma": [48, 56, 64, 80, 96, 80, 64, 56], + "hf_clip": [96, 128, 160, 192, 224, 192, 160, 0] + }, + "kernel_para": { + "prefilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "hfBilateralFilter_coeff": [0.2042, 0.1238, 0.0751], + "GaussianFilter_coeff_0": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232], + "GaussianFilter_coeff_1": [0.0632, 0.0558, 0.0492, 0.0383, 0.0338, 0.0232] + }, + "kernel_sigma": { + "prefilter_sigma": 1, + "hfBilateralFilter_sigma": 1, + "GaussianFilter_sigma": 2, + "GaussianFilter_radius": 2, + "GaussianFilter_sigma_0": 1, + "GaussianFilter_sigma_1": 1, + "GaussianFilter_radius_0": 2, + "GaussianFilter_radius_1": 2 + } + }], + "Tuning_ISO_len": 13 + }], + "Setting_len": 2 + } + }, + "ainr_v1": { + "Version": "V1", + "TuningPara": { + "enable": 1, + "gain_max": 8192, + "gain_tab_len": 13, + "tuning_visual_flag": 0, + "dynamicSw": [32, 64], + "luma_point": [0, 16, 64, 128, 196, 256], + "Tuning_ISO": [{ + "iso": 50, + "gain": 1, + "sigma": 2, + "shade": 0, + "sharp": 0, + "min_luma": 0, + "sat_scale": 1, + "dark_contrast": 0, + "ai_ratio": 0, + "mot_thresh": 5, + "static_thresh": 10, + "mot_nr_stren": 0, + "luma_sigma": [3, 3, 3, 3, 3, 3] + }, { + "iso": 400, + "gain": 8, + "sigma": 2, + "shade": 0, + "sharp": 1, + "min_luma": 0, + "sat_scale": 1, + "dark_contrast": 0, + "ai_ratio": 0, + "mot_thresh": 5, + "static_thresh": 10, + "mot_nr_stren": 0, + "luma_sigma": [3, 3, 3, 3, 3, 3] + }, { + "iso": 3200, + "gain": 64, + "sigma": 3, + "shade": 0, + "sharp": 1.5, + "min_luma": 0, + "sat_scale": 1, + "dark_contrast": 0, + "ai_ratio": 0.5, + "mot_thresh": 5, + "static_thresh": 20, + "mot_nr_stren": 1, + "luma_sigma": [4, 4, 8, 8, 4, 2] + }, { + "iso": 6400, + "gain": 128, + "sigma": 3, + "shade": 0, + "sharp": 2, + "min_luma": 0, + "sat_scale": 1, + "dark_contrast": 0, + "ai_ratio": 0.8, + "mot_thresh": 5, + "static_thresh": 20, + "mot_nr_stren": 0.5, + "luma_sigma": [6, 8, 12, 12, 7, 7] + }, { + "iso": 12800, + "gain": 256, + "sigma": 5, + "shade": 0, + "sharp": 2, + "min_luma": 0, + "sat_scale": 1, + "dark_contrast": 0, + "ai_ratio": 0.8, + "mot_thresh": 5, + "static_thresh": 20, + "mot_nr_stren": 0.3, + "luma_sigma": [6, 12, 20, 18, 10, 8] + }, { + "iso": 25600, + "gain": 512, + "sigma": 5, + "shade": 0, + "sharp": 2, + "min_luma": 0, + "sat_scale": 1, + "dark_contrast": 0, + "ai_ratio": 0.8, + "mot_thresh": 5, + "static_thresh": 15, + "mot_nr_stren": 0.3, + "luma_sigma": [8, 12, 16, 18, 6, 4] + }, { + "iso": 51200, + "gain": 1024, + "sigma": 32, + "shade": 0, + "sharp": 2, + "min_luma": 98, + "sat_scale": 1, + "dark_contrast": 0, + "ai_ratio": 0.8, + "mot_thresh": 5, + "static_thresh": 15, + "mot_nr_stren": 0.3, + "luma_sigma": [3, 12, 20, 20, 12, 3] + }, { + "iso": 102400, + "gain": 2048, + "sigma": 32, + "shade": 0, + "sharp": 4, + "min_luma": 98, + "sat_scale": 1, + "dark_contrast": 0, + "ai_ratio": 0.8, + "mot_thresh": 5, + "static_thresh": 15, + "mot_nr_stren": 0.3, + "luma_sigma": [8, 18, 20, 20, 12, 10] + }, { + "iso": 204800, + "gain": 4096, + "sigma": 32, + "shade": 0, + "sharp": 2, + "min_luma": 128, + "sat_scale": 1, + "dark_contrast": 0, + "ai_ratio": 1, + "mot_thresh": 5, + "static_thresh": 15, + "mot_nr_stren": 0, + "luma_sigma": [20, 30, 38, 38, 28, 20] + }, { + "iso": 409600, + "gain": 8192, + "sigma": 32, + "shade": 0, + "sharp": 0, + "min_luma": 98, + "sat_scale": 1, + "dark_contrast": 0, + "ai_ratio": 0.8, + "mot_thresh": 5, + "static_thresh": 15, + "mot_nr_stren": 0.2, + "luma_sigma": [12, 12, 16, 18, 12, 12] + }], + "Tuning_ISO_len": 10 + } + }, + "cac_v11": { + "SettingPara": { + "enable": 0, + "psf_path": "CAC_sc401ai_OT01_40IRC_F16/cac_map_hw_2592x1944.bin", + "psf_shift_bits": 2, + "center_en": 0, + "center_x": 0, + "center_y": 0 + }, + "TuningPara": { + "SettingByIso": [{ + "iso": 50, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 0, + "flat_thed_r": 0, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 100, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 200, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 400, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 800, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 1600, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 3200, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 6400, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 12800, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 25600, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 51200, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 102400, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 204800, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }, { + "iso": 409600, + "bypass": 0, + "global_strength": 0, + "strength_table": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "clip_g_mode": "RKAIQ_CAC_CLIP_G_MODE_MINIMAL", + "neg_clip0_enable": 1, + "edge_detect_en": 1, + "flat_thed_b": 1, + "flat_thed_r": 1, + "offset_b": 0, + "offset_r": 0, + "expo_det_b_en": 1, + "expo_det_r_en": 1, + "expo_thed_b": 4090, + "expo_thed_r": 4090, + "expo_adj_b": 4090, + "expo_adj_r": 4090 + }], + "SettingByIso_len": 14 + } + }, + "af_v31": { + "TuningPara": { + "af_mode": "CalibDbV2_AFMODE_CONT_PICTURE", + "win_h_offs": 0, + "win_v_offs": 0, + "win_h_size": 0, + "win_v_size": 0, + "video_win_h_offs": 0, + "video_win_v_offs": 0, + "video_win_h_size": 0, + "video_win_v_size": 0, + "fixed_mode": { + "code": 8 + }, + "macro_mode": { + "code": 32 + }, + "infinity_mode": { + "code": 32 + }, + "contrast_af": { + "enable": 1, + "Afss": "CalibDbV2_AFSS_ADAPTIVE_RANGE", + "FullDir": "CalibDbV2_AF_ADAPTIVE_SEARCH", + "FullRangeTbl": [0, 4, 64], + "AdaptiveDir": "CalibDbV2_AF_ADAPTIVE_SEARCH", + "AdaptRangeTbl": [0, 8, 16, 24, 32, 40, 48, 56, 64], + "AdaptRangeTbl_len": 9, + "FineSearchStep": [4, 4, 4, 4, 4, 4, 4, 4, 4], + "FineSearchStep_len": 9, + "SkipCurveFitGain": 1, + "TrigThers": [0.075], + "TrigThers_len": 1, + "TrigThersFv": [0], + "TrigThersFv_len": 1, + "LumaTrigThers": 0.05, + "ExpTrigThers": 0.03, + "ChangedFrames": 10, + "StableThers": 0.02, + "StableFrames": 3, + "StableTime": 200, + "SceneDiffEnable": 0, + "SceneDiffThers": 0, + "SceneDiffBlkThers": 0, + "CenterSceneDiffThers": 0, + "ValidMaxMinRatio": 0, + "ValidValueThers": 0, + "OutFocusValue": 200, + "OutFocusPos": 64, + "LowLumaValue": 0, + "LowLumaPos": 64, + "WeightEnable": 0, + "Weight": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "SearchPauseLumaEnable": 1, + "SearchPauseLumaThers": 0.05, + "SearchLumaStableFrames": 3, + "SearchLumaStableThers": 0.02, + "Stage1QuickFoundThers": 0.04, + "Stage2QuickFoundThers": 0.2, + "FlatValue": 0, + "PointLightLumaTh": 3000, + "PointLightCntTh": 300, + "ZoomCfg": { + "QuickFoundThersZoomIdx": [0], + "QuickFoundThersZoomIdx_len": 1, + "QuickFoundThers": [0], + "QuickFoundThers_len": 1, + "SearchStepZoomIdx": [0], + "SearchStepZoomIdx_len": 1, + "SearchStep": [0], + "SearchStep_len": 1, + "StopStepZoomIdx": [0], + "StopStepZoomIdx_len": 1, + "StopStep": [0], + "StopStep_len": 1, + "SkipHighPassZoomIdx": 0, + "SkipHighPassGain": 0, + "SwitchDirZoomIdx": 1000, + "SpotlightHighlightRatio": 0.014, + "SpotlightLumaRatio": [0.3, 0.5, 0.8], + "SpotlightBlkCnt": [0.2, 0.5, 0.25] + } + }, + "video_contrast_af": { + "enable": 1, + "Afss": "CalibDbV2_AFSS_ADAPTIVE_RANGE", + "FullDir": "CalibDbV2_AF_ADAPTIVE_SEARCH", + "FullRangeTbl": [0, 4, 64], + "AdaptiveDir": "CalibDbV2_AF_ADAPTIVE_SEARCH", + "AdaptRangeTbl": [0, 8, 16, 24, 32, 40, 48, 56, 64], + "AdaptRangeTbl_len": 9, + "FineSearchStep": [4, 4, 4, 4, 4, 4, 4, 4, 4], + "FineSearchStep_len": 9, + "SkipCurveFitGain": 1, + "TrigThers": [0.15], + "TrigThers_len": 1, + "TrigThersFv": [0], + "TrigThersFv_len": 1, + "LumaTrigThers": 1, + "ExpTrigThers": 1, + "ChangedFrames": 10, + "StableThers": 0.02, + "StableFrames": 20, + "StableTime": 200, + "SceneDiffEnable": 0, + "SceneDiffThers": 0, + "SceneDiffBlkThers": 0, + "CenterSceneDiffThers": 0, + "ValidMaxMinRatio": 0, + "ValidValueThers": 0, + "OutFocusValue": 200, + "OutFocusPos": 64, + "LowLumaValue": 0, + "LowLumaPos": 64, + "WeightEnable": 0, + "Weight": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "SearchPauseLumaEnable": 1, + "SearchPauseLumaThers": 0.05, + "SearchLumaStableFrames": 3, + "SearchLumaStableThers": 0.02, + "Stage1QuickFoundThers": 0.04, + "Stage2QuickFoundThers": 0.2, + "FlatValue": 0, + "PointLightLumaTh": 912, + "PointLightCntTh": 20, + "ZoomCfg": { + "QuickFoundThersZoomIdx": [0], + "QuickFoundThersZoomIdx_len": 1, + "QuickFoundThers": [0], + "QuickFoundThers_len": 1, + "SearchStepZoomIdx": [0], + "SearchStepZoomIdx_len": 1, + "SearchStep": [0], + "SearchStep_len": 1, + "StopStepZoomIdx": [0], + "StopStepZoomIdx_len": 1, + "StopStep": [0], + "StopStep_len": 1, + "SkipHighPassZoomIdx": 0, + "SkipHighPassGain": 0, + "SwitchDirZoomIdx": 1000, + "SpotlightHighlightRatio": 0.014, + "SpotlightLumaRatio": [0.3, 0.5, 0.8], + "SpotlightBlkCnt": [0.2, 0.5, 0.25] + } + }, + "laser_af": { + "enable": 0, + "vcmDot": [0, 16, 32, 40, 48, 56, 64], + "distanceDot": [0.2, 0.24, 0.34, 0.4, 0.66, 1, 3] + }, + "vcmcfg": { + "max_logical_pos": 64, + "start_current": -1, + "rated_current": -1, + "step_mode": -1, + "extra_delay": 0, + "posture_diff": 0.1 + }, + "zoomfocus_tbl": { + "widemod_deviate": 10, + "telemod_deviate": 10, + "focus_backval": 0, + "zoom_move_dot": [0], + "zoom_move_dot_len": 1, + "zoom_move_step": [16], + "zoom_move_step_len": 1, + "focal_length": [0], + "focal_length_len": 1, + "zoomcode": [0], + "zoomcode_len": 1, + "focuscode": [{ + "pos": 0.5, + "code": [0], + "code_len": 1 + }, { + "pos": -1, + "code": [0], + "code_len": 1 + }], + "focuscode_len": 2, + "ZoomSearchTbl": [0], + "ZoomSearchTbl_len": 1, + "ZoomSearchRefCurveIdx": 0, + "FocusSearchMargin": 50, + "FocusSearchPlusRange": [0], + "FocusSearchPlusRange_len": 1, + "FocusStage1Step": 1, + "QuickFndRate": 0.3, + "QuickFndMinFv": 200, + "searchZoomRange": 100, + "searchFocusRange": 100, + "searchEmax": 100, + "searchEavg": 100, + "IsZoomFocusRec": 0, + "ZoomInfoDir": "/userdata", + "ZoomInitIndex": 0 + }, + "zoom_meas": [{ + "zoom_idx": 0, + "measiso": [{ + "iso": 50, + "idx": 0, + "spotlt_scene_idx": 0 + }, { + "iso": 100, + "idx": 0, + "spotlt_scene_idx": 0 + }, { + "iso": 200, + "idx": 0, + "spotlt_scene_idx": 0 + }, { + "iso": 400, + "idx": 0, + "spotlt_scene_idx": 0 + }, { + "iso": 800, + "idx": 0, + "spotlt_scene_idx": 0 + }, { + "iso": 1600, + "idx": 1, + "spotlt_scene_idx": 1 + }, { + "iso": 3200, + "idx": 1, + "spotlt_scene_idx": 1 + }, { + "iso": 6400, + "idx": 1, + "spotlt_scene_idx": 1 + }, { + "iso": 12800, + "idx": 1, + "spotlt_scene_idx": 1 + }, { + "iso": 25600, + "idx": 1, + "spotlt_scene_idx": 1 + }, { + "iso": 51200, + "idx": 1, + "spotlt_scene_idx": 1 + }, { + "iso": 102400, + "idx": 1, + "spotlt_scene_idx": 1 + }, { + "iso": 204800, + "idx": 1, + "spotlt_scene_idx": 1 + }], + "measiso_len": 13 + }], + "zoom_meas_len": 1, + "meascfg_tbl": [{ + "tbl_idx": 0, + "from_awb": 0, + "from_ynr": 0, + "afmThres": 4, + "gammaY": [0, 45, 108, 179, 245, 344, 409, 459, 500, 567, 622, 676, 759, 833, 896, 962, 1023], + "gaus_coe": [0, 64, 0, 0, 64, 0, 0, 0, 0], + "dnscl_mode": "CalibDbV2_AF_DNSCL_1", + "v1fv_reliable": 0.2, + "v2fv_reliable": 0.2, + "v1_fir_sel": 1, + "v1_band": [0.042, 0.14], + "v1_iir_coe": [-265, 686, 512], + "v1_fir_coe": [-124, 0, 124], + "v2_band": [0.055, 0.125], + "v2_iir_coe": [-325, 724, 512], + "v2_fir_coe": [-94, 0, 94], + "h1_band": [0.042, 0.14], + "h1_iir1_coe": [512, 557, -276, 460, 0, -460], + "h1_iir2_coe": [100, 870, -399, 191, 0, -191], + "h2_band": [0.055, 0.125], + "h2_iir1_coe": [415, 648, -344, 403, 0, -403], + "h2_iir2_coe": [96, 854, -409, 156, 0, -156], + "ldg_en": 0, + "ve_ldg_lumth_l": 64, + "ve_ldg_gain_l": 28, + "ve_ldg_gslp_l": 1286, + "ve_ldg_lumth_h": 185, + "ve_ldg_gain_h": 8, + "ve_ldg_gslp_h": 1400, + "ho_ldg_lumth_l": 64, + "ho_ldg_gain_l": 28, + "ho_ldg_gslp_l": 1286, + "ho_ldg_lumth_h": 185, + "ho_ldg_gain_h": 8, + "ho_ldg_gslp_h": 1400, + "v_fv_thresh": 4, + "h_fv_thresh": 4, + "highlit_thresh": 912, + "v_fv_ratio": 0.5 + }, { + "tbl_idx": 1, + "from_awb": 0, + "from_ynr": 0, + "afmThres": 4, + "gammaY": [0, 45, 108, 179, 245, 344, 409, 459, 500, 567, 622, 676, 759, 833, 896, 962, 1023], + "gaus_coe": [0, 64, 0, 0, 64, 0, 0, 0, 0], + "dnscl_mode": "CalibDbV2_AF_DNSCL_1", + "v1fv_reliable": 0.2, + "v2fv_reliable": 0.2, + "v1_fir_sel": 1, + "v1_band": [0.025, 0.075], + "v1_iir_coe": [-372, 851, 465], + "v1_fir_coe": [-77, 0, 77], + "v2_band": [0.042, 0.14], + "v2_iir_coe": [-265, 686, 512], + "v2_fir_coe": [-124, 0, 124], + "h1_band": [0.025, 0.075], + "h1_iir1_coe": [203, 811, -375, 673, 0, -673], + "h1_iir2_coe": [31, 945, -448, 323, 0, -323], + "h2_band": [0.042, 0.14], + "h2_iir1_coe": [512, 557, -276, 460, 0, -460], + "h2_iir2_coe": [100, 870, -399, 191, 0, -191], + "ldg_en": 1, + "ve_ldg_lumth_l": 64, + "ve_ldg_gain_l": 28, + "ve_ldg_gslp_l": 1286, + "ve_ldg_lumth_h": 185, + "ve_ldg_gain_h": 8, + "ve_ldg_gslp_h": 1400, + "ho_ldg_lumth_l": 64, + "ho_ldg_gain_l": 28, + "ho_ldg_gslp_l": 1286, + "ho_ldg_lumth_h": 185, + "ho_ldg_gain_h": 8, + "ho_ldg_gslp_h": 1400, + "v_fv_thresh": 32, + "h_fv_thresh": 32, + "highlit_thresh": 912, + "v_fv_ratio": 0.5 + }], + "meascfg_tbl_len": 2 + } + }, + "gain_v2": { + "Version": "V2", + "TuningPara": { + "hdrgain_ctrl_enable": 0, + "Setting": [{ + "SNR_Mode": "LSNR", + "Sensor_Mode": "lcg", + "Tuning_ISO": [{ + "iso": 50, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 100, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 200, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 400, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 800, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 1600, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 3200, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 6400, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 12800, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 25600, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 51200, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 102400, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 204800, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }], + "Tuning_ISO_len": 13 + }, { + "SNR_Mode": "HSNR", + "Sensor_Mode": "hcg", + "Tuning_ISO": [{ + "iso": 50, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 100, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 200, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 400, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 800, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 1600, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 3200, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 6400, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 12800, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 25600, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 51200, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 102400, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }, { + "iso": 204800, + "hdr_gain_scale_s": 1, + "hdr_gain_scale_m": 1 + }], + "Tuning_ISO_len": 13 + }], + "Setting_len": 2 + } + }, + "csm": { + "TuningPara": { + "op_mode": "RK_AIQ_OP_MODE_AUTO", + "full_range": 1, + "y_offset": 0, + "c_offset": 0, + "coeff": [0.299, 0.587, 0.114, -0.169, -0.331, 0.5, 0.5, -0.419, -0.081] + } + }, + "cgc": { + "TuningPara": { + "op_mode": "RK_AIQ_OP_MODE_AUTO", + "cgc_ratio_en": 0, + "cgc_yuv_limit": 0 + } + } + } + }], + "sub_scene_len": 1 + }], + "main_scene_len": 1, + "uapi": [], + "uapi_len": 0, + "sys_static_cfg": { + "algoSwitch": { + "enable": 0, + "disable_algos": ["DISABLE_AF"], + "disable_algos_len": 1 + } + } +} \ No newline at end of file diff --git a/project/app/rkipc/rkipc/src/rv1106_ipc/CMakeLists.txt b/project/app/rkipc/rkipc/src/rv1106_ipc/CMakeLists.txt index 800a6b086..a2dde8941 100644 --- a/project/app/rkipc/rkipc/src/rv1106_ipc/CMakeLists.txt +++ b/project/app/rkipc/rkipc/src/rv1106_ipc/CMakeLists.txt @@ -69,6 +69,7 @@ install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) install(FILES rkipc-300w.ini DESTINATION share) install(FILES rkipc-400w.ini DESTINATION share) install(FILES rkipc-500w.ini DESTINATION share) +install(FILES rkipc-mis5001-500w.ini DESTINATION share) install(FILES rkipc-800w.ini DESTINATION share) install(FILES ../../common/speaker_test.wav DESTINATION share) install(PROGRAMS RkLunch.sh DESTINATION bin) diff --git a/project/app/rkipc/rkipc/src/rv1106_ipc/RkLunch.sh b/project/app/rkipc/rkipc/src/rv1106_ipc/RkLunch.sh index f68873ef1..d3b0f32b2 100644 --- a/project/app/rkipc/rkipc/src/rv1106_ipc/RkLunch.sh +++ b/project/app/rkipc/rkipc/src/rv1106_ipc/RkLunch.sh @@ -73,6 +73,10 @@ post_chk() { default_rkipc_ini=/tmp/rkipc-factory-config.ini if [ ! -f "/oem/usr/share/rkipc.ini" ]; then + lsmod | grep mis5001 + if [ $? -eq 0 ]; then + ln -s -f /oem/usr/share/rkipc-mis5001-500w.ini $default_rkipc_ini + fi lsmod | grep sc530ai if [ $? -eq 0 ]; then ln -s -f /oem/usr/share/rkipc-500w.ini $default_rkipc_ini diff --git a/project/app/rkipc/rkipc/src/rv1106_ipc/rkipc-mis5001-500w.ini b/project/app/rkipc/rkipc/src/rv1106_ipc/rkipc-mis5001-500w.ini new file mode 100644 index 000000000..f789dc3f6 --- /dev/null +++ b/project/app/rkipc/rkipc/src/rv1106_ipc/rkipc-mis5001-500w.ini @@ -0,0 +1,542 @@ +[audio.0] +enable = 0 +card_name = hw:0,0 +encode_type = G711A +format = S16 +sample_rate = 8000 +channels = 1 +frame_size = 1152 +bit_rate = 16000 +input = mic_in +volume = 50 +enable_aed = 0 +enable_bcd = 0 +enable_vqe = 1 +vqe_cfg = /oem/usr/share/vqefiles/config_aivqe.json + +[video.source] +enable_aiq = 1 +enable_vo = 0 +vo_dev_id = 3 ; 0 is hdmi, 3 is mipi +enable_ivs = 1 +enable_jpeg = 1 +enable_venc_0 = 1 +enable_venc_1 = 1 +enable_venc_2 = 0 +enable_npu = 0 +npu_fps = 10 +enable_rtsp = 1 +enable_rtmp = 0 +rotation = 0 ; available value:0 90 180 270 + +[video.0] +buffer_size = 2519424 ; w * h / 2 +buffer_count = 4 +enable_refer_buffer_share = 1 +stream_type = mainStream +video_type = compositeStream +max_width = 2592 +max_height = 1944 +width = 2592 +height = 1944 +rc_mode = CBR +rc_quality = high +src_frame_rate_den = 1 +src_frame_rate_num = 25 +dst_frame_rate_den = 1 +dst_frame_rate_num = 25 +target_rate = 0 +mid_rate = 2048 +max_rate = 4096 +min_rate = 0 +output_data_type = H.265 +smart = close +h264_profile = high +gop = 50 +smartp_viridrlen = 25 +gop_mode = normalP +stream_smooth = 50 +enable_motion_deblur = 1 +motion_deblur_strength = 3 +enable_motion_static_switch = 0 +frame_min_i_qp = 26 +frame_min_qp = 28 +frame_max_i_qp = 51 +frame_max_qp = 51 +scalinglist = 0 +enable_debreath_effect = 0 +debreath_effect_strength = 16 +thrd_i = 0,0,0,0,3,3,5,5,8,8,8,15,15,20,25,25 +thrd_p = 0,0,0,0,3,3,5,5,8,8,8,15,15,20,25,25 +aq_step_i = -8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,7,8 +aq_step_p = -8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,7,8 +qbias_enable = 1 +qbias_i = 171 +qbias_p = 85 +flt_str_i = 0 +flt_str_p = 0 +cu_dqp = 1 +anti_ring = 2 +anti_line = 2 +lambds = 4 + +[video.1] +input_buffer_count = 2 ; only wrap can use one buffer +buffer_size = 202752 ; w * h / 2 +buffer_count = 4 +enable_refer_buffer_share = 1 +stream_type = subStream +video_type = compositeStream +max_width = 704 +max_height = 576 +width = 704 +height = 576 +rc_mode = CBR +rc_quality = high +src_frame_rate_den = 1 +src_frame_rate_num = 25 +dst_frame_rate_den = 1 +dst_frame_rate_num = 25 +target_rate = 0 +mid_rate = 256 +max_rate = 512 +min_rate = 0 +output_data_type = H.265 +smart = close +h264_profile = high +gop = 50 +smartp_viridrlen = 25 +gop_mode = normalP +stream_smooth = 50 +enable_motion_deblur = 1 +motion_deblur_strength = 3 +enable_motion_static_switch = 0 +frame_min_i_qp = 26 +frame_min_qp = 28 +frame_max_i_qp = 51 +frame_max_qp = 51 +scalinglist = 0 +enable_debreath_effect = 0 +debreath_effect_strength = 16 +cu_dqp = 1 +anti_ring = 2 +anti_line = 2 +lambds = 4 + +[video.2] +max_width = 960 +max_height = 540 +width = 960 +height = 540 + +[ivs] +smear = 0 +weightp = 0 +md = 1 +od = 1 +md_sensibility = 3 ;available: 1 2 3,max 3 + +[video.jpeg] +width = 1920 +height = 1080 +jpeg_buffer_size = 1048576 ; 1024KB +jpeg_qfactor = 70 +enable_cycle_snapshot = 0 +snapshot_interval_ms = 1000 + +[isp] +scenario = normal ; normal or custom1 +init_form_ini = 1 +normal_scene = day +custom1_scene = night +ircut_open_gpio = 36 +ircut_close_gpio = 35 + +; isp.0 +[isp.0.adjustment] +contrast = 50 +brightness = 50 +saturation = 50 +sharpness = 50 +fps = 25 +hue = 50 + +[isp.0.exposure] +iris_type = auto +exposure_mode = auto +gain_mode = auto +auto_iris_level = 5 +auto_exposure_enabled = 1 +audo_gain_enabled = 1 +exposure_time = 1/6 +exposure_gain = 1 + +[isp.0.night_to_day] +night_to_day = day +night_to_day_filter_level = 5 +night_to_day_filter_time = 5 +dawn_time = 07:00:00 +dusk_time = 18:00:00 +ircut_filter_action = day +over_exposure_suppress = open +over_exposure_suppress_type = auto +fill_light_mode = IR +brightness_adjustment_mode = auto +light_brightness = 1 +distance_level = 1 + +[isp.0.blc] +blc_region = close +blc_strength = 1 +wdr = close +wdr_level = 0 +hdr = close +hdr_level = 1 +hlc = close +hlc_level = 0 +dark_boost_level = 0 +position_x = 0 +position_y = 0 +blc_region_width = 120 +blc_region_high = 92 + +[isp.0.white_blance] +white_blance_style = autoWhiteBalance +white_blance_red = 50 +white_blance_green = 50 +white_blance_blue = 50 + +[isp.0.enhancement] +noise_reduce_mode = close +denoise_level = 50 +spatial_denoise_level = 50 +temporal_denoise_level = 50 +dehaze = close +dehaze_level = 0 +dis = close +gray_scale_mode = [0-255] +distortion_correction = close +ldch_level = 0 + +[isp.0.video_adjustment] +image_flip = close +scene_mode = indoor +power_line_frequency_mode = PAL(50HZ) + +[isp.0.auto_focus] +af_mode = semi-auto +zoom_level = 0 +focus_level = 0 + +; isp.1 +[isp.1.adjustment] +contrast = 50 +brightness = 75 +saturation = 50 +sharpness = 50 +fps = 25 +hue = 50 + +[isp.1.exposure] +iris_type = auto +exposure_mode = auto +gain_mode = auto +auto_iris_level = 5 +auto_exposure_enabled = 1 +audo_gain_enabled = 1 +exposure_time = 1/6 +exposure_gain = 1 + +[isp.1.night_to_day] +night_to_day = day +night_to_day_filter_level = 5 +night_to_day_filter_time = 5 +dawn_time = 07:00:00 +dusk_time = 18:00:00 +ircut_filter_action = day +over_exposure_suppress = open +over_exposure_suppress_type = auto +fill_light_mode = IR +brightness_adjustment_mode = auto +light_brightness = 1 +distance_level = 1 + +[isp.1.blc] +blc_region = close +blc_strength = 1 +wdr = close +wdr_level = 0 +hdr = close +hdr_level = 1 +hlc = close +hlc_level = 0 +dark_boost_level = 0 +position_x = 0 +position_y = 0 +blc_region_width = 120 +blc_region_high = 92 + +[isp.1.white_blance] +white_blance_style = autoWhiteBalance +white_blance_red = 50 +white_blance_green = 50 +white_blance_blue = 50 + +[isp.1.enhancement] +noise_reduce_mode = close +denoise_level = 50 +spatial_denoise_level = 50 +temporal_denoise_level = 50 +dehaze = close +dehaze_level = 0 +dis = close +gray_scale_mode = [0-255] +distortion_correction = close +ldch_level = 0 + +[isp.1.video_adjustment] +image_flip = close +scene_mode = indoor +power_line_frequency_mode = PAL(50HZ) + +[isp.1.auto_focus] +af_mode = semi-auto +zoom_level = 0 +focus_level = 0 + +[storage] +mount_path = /userdata +free_size_del_min = 500; MB +free_size_del_max = 1000; MB +num_limit_enable = 1; limit by file num + +[storage.0] +enable = 0 +folder_name = video0 +file_format = mp4 ; flv,ts +file_duration = 60 +video_quota = 30 +file_max_num = 300 + +[storage.1] +enable = 0 +folder_name = video1 +file_format = mp4 ; flv,ts +file_duration = 60 +video_quota = 30 +file_max_num = 300 + +[storage.2] +enable = 0 +folder_name = video2 +file_format = mp4 ; flv,ts +file_duration = 60 +video_quota = 30 +file_max_num = 300 + +[system.device_info] +deivce_name = RK IP Camera +telecontrol_id = 88 +model = RK-003 +serial_number = RK-003-A +firmware_version = V0.2.6 build 202108 +encoder_version = V1.0 build 202108 +web_version = V2.12.2 build 202108 +plugin_version = V1.0.0.0 +channels_number = 1 +hard_disks_number = 1 +alarm_inputs_number = 0 +alarm_outputs_number = 0 +firmware_version_info = CP-3-B +manufacturer = Rockchip +hardware_id = c3d9b8674f4b94f6 +user_num = 1 + +[capability.video] +0 = {"disabled":[{"name":"sStreamType","options":{"subStream":{"sSmart":"close"},"thirdStream":{"sSmart":"close"}},"type":"disabled/limit"},{"name":"sRCMode","options":{"CBR":{"sRCQuality":null}},"type":"disabled"},{"name":"sOutputDataType","options":{"H.265":{"sH264Profile":null}},"type":"disabled"},{"name":"unspport","options":{"iStreamSmooth":null,"sVideoType":null},"type":"disabled"}],"dynamic":{"sSmart":{"open":{"iMinRate":{"dynamicRange":{"max":"iMaxRate","maxRate":1,"min":"iMaxRate","minRate":0.125},"type":"dynamicRange"}}},"sStreamType":{"mainStream":{"iMaxRate":{"options":[256,512,1024,2048,3072,4096,6144],"type":"options"},"sResolution":{"options":["2880*1616","1920*1080","1280*720","960*540","640*360","320*240"],"type":"options"}},"subStream":{"iMaxRate" +1 = :{"options":[128,256,512],"type":"options"},"sResolution":{"options":["704*576","640*480","352*288","320*240"],"type":"options"}},"thirdStream":{"iMaxRate":{"options":[256,512],"type":"options"},"sResolution":{"options":["416*416"],"type":"options"}}}},"layout":{"encoder":["sStreamType","sVideoType","sResolution","sRCMode","sRCQuality","sFrameRate","sOutputDataType","sSmart","sH264Profile","sGOPMode","iMaxRate","iGOP","iStreamSmooth"]},"static":{"iGOP":{"range":{"max":400,"min":1},"type":"range"},"iStreamSmooth":{"range":{"max":100,"min":1,"step":1},"type":"range"},"sFrameRate":{"dynamicRange":{"max":"sFrameRateIn","maxRate":1},"options":["1/2","1","2","4","6","8","10","12","14","16","18","20","25","30"],"type":"options/dynamicRange"},"sH264Profile":{"options":["high","main","baseline"],"type":"options"},"sOutputDataType":{"options" +2 = :["H.264","H.265"],"type":"options"},"sRCMode":{"options":["CBR","VBR"],"type":"options"},"sRCQuality":{"options":["lowest","lower","low","medium","high","higher","highest"],"type":"options"},"sGOPMode":{"options":["normalP","smartP"],"type":"options"},"sSmart":{"options":["open","close"],"type":"options"},"sStreamType":{"options":["mainStream","subStream","thirdStream"],"type":"options"},"sVideoType":{"options":["videoStream","compositeStream"],"type":"options"}}} + +[capability.image_adjustment] +0 = {"layout":{"image_adjustment":["iBrightness","iContrast","iSaturation","iSharpness","iHue"]},"static":{"iBrightness":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iContrast":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iHue":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iSaturation":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iSharpness":{"range":{"max":100,"min":0,"step":1},"type":"range"}}} + +[capability.image_blc] +0 = {"disabled":[{"name":"sHLC","options":{"open":{"sBLCRegion":null}},"type":"disabled"},{"name":"sBLCRegion","options":{"open":{"iDarkBoostLevel":null,"iHLCLevel":null,"sHLC":null}},"type":"disabled"}],"dynamic":{"sBLCRegion":{"open":{"iBLCStrength":{"range":{"max":100,"min":0,"step":1},"type":"range"}}},"sHDR":{"HDR2":{"iHDRLevel":{"options":[1,2,3,4],"type":"options"}},"close":{"sBLCRegion":{"options":["close","open"],"type":"options"},"sHLC":{"options" +1 = :["close","open"],"type":"options"}}},"sHLC":{"open":{"iDarkBoostLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iHLCLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}}},"sWDR":{"open":{"iWDRLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}}}},"layout":{"image_blc":["sHDR","iHDRLevel","sBLCRegion","iBLCStrength","sHLC","iHLCLevel"]},"static":{"sHDR":{"options":["close","HDR2"],"type":"options"}}} + +[capability.image_enhancement] +0 = {"dynamic":{"sDehaze":{"open":{"iDehazeLevel":{"range":{"max":10,"min":0,"step":1},"type":"range"}}},"sDistortionCorrection":{"FEC":{"iFecLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}},"LDCH":{"iLdchLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}}},"sNoiseReduceMode":{"2dnr":{"iSpatialDenoiseLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}},"3dnr":{"iTemporalDenoiseLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}},"mixnr":{"iSpatialDenoiseLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iTemporalDenoiseLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}}}},"layout" +1 = :{"image_enhancement":["sNoiseReduceMode","iSpatialDenoiseLevel","iTemporalDenoiseLevel","sDehaze","iDehazeLevel","sGrayScaleMode","sDistortionCorrection","iLdchLevel","iFecLevel"]},"static":{"sDIS":{"options":["open","close"],"type":"options"},"sDehaze":{"options":["open","close","auto"],"type":"options"},"sDistortionCorrection":{"options":["LDCH","close"],"type":"options"},"sFEC":{"options":["open","close"],"type":"options"},"sGrayScaleMode":{"options":["[0-255]","[16-235]"],"type":"options"},"sNoiseReduceMode":{"options":["close","2dnr","3dnr","mixnr"],"type":"options"}}} + +[capability.image_exposure] +0 = {"dynamic":{"sExposureMode":{"auto":{"iAutoIrisLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}},"manual":{"sExposureTime":{"options":["1","1/3","1/6","1/12","1/25","1/50","1/100","1/150","1/200","1/250","1/500","1/750","1/1000","1/2000","1/4000","1/10000","1/100000"],"type":"options"},"sGainMode":{"options":["auto","manual"],"type":"options"}}},"sGainMode":{"manual":{"iExposureGain":{"range":{"max":100,"min":1,"step":1},"type":"range"}}}},"layout":{"image_exposure":["sExposureMode","sExposureTime","sGainMode","iExposureGain","iFPS"]},"static":{"sExposureMode":{"options":["auto","manual"],"type":"options"},"iFPS":{"range":{"max":30,"min":0,"step":1},"type":"range"}}} + +[capability.image_night_to_day] +0 = {"disabled":[{"name":"sNightToDay","options":{"day":{"iLightBrightness":null,"sFillLightMode":null},"night":{"iDarkBoostLevel":null,"iHDRLevel":null,"iHLCLevel":null,"sHDR":null,"sHLC":"close"}},"type":"disabled"}],"dynamic":{"sNightToDay":{"auto":{"iNightToDayFilterLevel":{"options":[0,1,2,3,4,5,6,7],"type":"options"},"iNightToDayFilterTime":{"range":{"max":10,"min":3,"step":1},"type":"range"}},"schedule":{"sDawnTime":{"input":"time","type":"input"},"sDuskTime":{"input":"time","type":"input"}}},"sOverexposeSuppress":{"open" +1 = :{"sOverexposeSuppressType":{"options":["auto","manual"],"type":"options"}}},"sOverexposeSuppressType":{"manual":{"iDistanceLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}}}},"layout":{"image_night_to_day":["sNightToDay","iNightToDayFilterLevel","iNightToDayFilterTime","sDawnTime","sDuskTime","sFillLightMode","iLightBrightness"]},"static":{"iLightBrightness":{"range":{"max":100,"min":0,"step":10},"type":"range"},"sNightToDay":{"options":["day","night"],"type":"options"},"sFillLightMode":{"type":"options","options":["IR"]}}} + +[capability.image_video_adjustment] +0 = {"layout":{"image_video_adjustment":["sPowerLineFrequencyMode","sImageFlip","iImageRotation"]},"static":{"sImageFlip":{"options":["close","flip","mirror","centrosymmetric"],"type":"options"},"sPowerLineFrequencyMode":{"options":["PAL(50HZ)","NTSC(60HZ)"],"type":"options"},"sSceneMode":{"options":["indoor","outdoor"],"type":"options"},"iImageRotation":{"options":[0,90,180,270],"type":"options"}}} + +[capability.image_white_blance] +0 = {"dynamic":{"sWhiteBlanceStyle":{"manualWhiteBalance":{"iWhiteBalanceBlue":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iWhiteBalanceGreen":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iWhiteBalanceRed":{"range":{"max":100,"min":0,"step":1},"type":"range"}}}},"layout":{"image_white_blance":["sWhiteBlanceStyle","iWhiteBalanceRed","iWhiteBalanceGreen","iWhiteBalanceBlue"]},"static":{"sWhiteBlanceStyle":{"options":["manualWhiteBalance","autoWhiteBalance","lockingWhiteBalance","fluorescentLamp","incandescent","warmLight","naturalLight"],"type":"options"}}} + +[user.0] +user_name = admin +password = YWRtaW4= +user_level = 1 ; administrator=0 operator=1 user=2 + +[osd.common] +enable_osd = 1 +is_presistent_text = 1 +attribute = transparent/not-flashing +font_size = 32 +font_color_mode = customize +font_color = fff799 +alignment = customize +boundary = 0 +font_path = /oem/usr/share/simsun_en.ttf +normalized_screen_width = 704 +normalized_screen_height = 480 + +[osd.0] +type = channelName +enabled = 0 +position_x = 1104 +position_y = 640 +display_text = Camera 01 + +[osd.1] +type = dateTime +enabled = 1 +position_x = 16 +position_y = 16 +date_style = CHR-YYYY-MM-DD +time_style = 24hour +display_week_enabled = 0 + +[osd.2] +type = character +enabled = 0 +position_x = 0 +position_y = 0 +display_text = null + +[osd.3] +type = character +enabled = 0 +position_x = 0 +position_y = 0 +display_text = null + +[osd.4] +type = privacyMask +enabled = 0 +position_x = 0 +position_y = 0 +width = 0 +height = 0 + +[osd.5] +type = privacyMask +enabled = 0 +position_x = 0 +position_y = 0 +width = 0 +height = 0 + +[osd.6] +type = image +enabled = 0 +position_x = 16 +position_y = 640 +image_path = /userdata/image.bmp + +[event.regional_invasion] +enabled = 1 +position_x = 0 +position_y = 0 +width = 700 +height = 560 +proportion = 1 +sensitivity_level = 90 +time_threshold = 1 +rockiva_model_type = small ;big medium small + +[roi.0] +stream_type = mainStream +id = 1 +enabled = 0 +name = test +position_x = 0 +position_y = 0 +width = 0 +height = 0 +quality_level = 3 + +[roi.1] +stream_type = mainStream +id = 2 +enabled = 0 +name = test +position_x = 0 +position_y = 0 +width = 0 +height = 0 +quality_level = 3 + +[roi.2] +stream_type = subStream +id = 1 +enabled = 0 +name = test +position_x = 0 +position_y = 0 +width = 0 +height = 0 +quality_level = 3 + +[roi.3] +stream_type = subStream +id = 2 +enabled = 0 +name = test +position_x = 0 +position_y = 0 +width = 0 +height = 0 +quality_level = 3 + +[roi.4] +stream_type = thirdStream +id = 1 +enabled = 0 +name = test +position_x = 0 +position_y = 0 +width = 0 +height = 0 +quality_level = 3 + +[roi.5] +stream_type = thirdStream +id = 2 +enabled = 0 +name = test +position_x = 0 +position_y = 0 +width = 0 +height = 0 +quality_level = 3 + +[region_clip.1] +enabled = 0 +position_x = 0 +position_y = 0 +width = 640 +height = 480 + +[network.ntp] +enable = 1 +refresh_time_s = 60 +ntp_server = 119.28.183.184 diff --git a/project/app/uvc_app_tiny/.gitignore b/project/app/uvc_app_tiny/.gitignore new file mode 100644 index 000000000..bb44f1ab7 --- /dev/null +++ b/project/app/uvc_app_tiny/.gitignore @@ -0,0 +1,2 @@ +out/ +build/ diff --git a/project/app/uvc_app_tiny/Makefile b/project/app/uvc_app_tiny/Makefile new file mode 100644 index 000000000..5bfe2d518 --- /dev/null +++ b/project/app/uvc_app_tiny/Makefile @@ -0,0 +1,102 @@ + +ifeq ($(APP_PARAM), ) + APP_PARAM:=../Makefile.param + include $(APP_PARAM) +endif + +export LC_ALL=C +SHELL:=/bin/bash + +CURRENT_DIR := $(shell pwd) + +PKG_NAME := uvc_app +PKG_BIN ?= out +PKG_BUILD ?= build + +# debug: build cmake with more message +# PKG_CONF_OPTS += -DCMAKE_VERBOSE_MAKEFILE=ON +# +RK_UVC_APP_CONFIG := + +ifeq ($(RK_ENABLE_FASTBOOT),y) +PKG_CONF_OPTS += -DRK_ENABLE_FASTBOOT=ON +RK_APP_OPTS += -DRK_ENABLE_FASTBOOT +endif + +ifeq ($(RK_APP_CHIP), rv1106) +ifneq (, $(filter UVC_TINY, $(RK_APP_TYPE))) + RK_UVC_APP_CONFIG := -DCOMPILE_FOR_MPI=ON +else +$(info ### disable make uvc demo) +endif +else +$(info ### unknow RK_APP_CHIP) +endif + +RK_APP_CFLAGS = -I $(RK_APP_MEDIA_INCLUDE_PATH) \ + -I $(RK_APP_MEDIA_INCLUDE_PATH)/libdrm \ + -I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq \ + -I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/uAPI \ + -I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/uAPI2 \ + -I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/algos \ + -I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/common \ + -I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/xcore \ + -I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/iq_parser \ + -I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/iq_parser_v2 \ + -I $(RK_APP_MEDIA_INCLUDE_PATH)/easymedia +RK_APP_LDFLAGS = -L $(RK_APP_MEDIA_LIBS_PATH) + +RK_APP_OPTS += -Wl,-rpath-link,$(RK_APP_MEDIA_LIBS_PATH):$(RK_APP_PATH_LIB_INCLUDE)/root/usr/lib +PKG_CONF_OPTS += -DCMAKE_C_FLAGS="$(RK_APP_CFLAGS) $(RK_APP_LDFLAGS) $(RK_APP_OPTS)" \ + -DCMAKE_CXX_FLAGS="$(RK_APP_CFLAGS) $(RK_APP_LDFLAGS) $(RK_APP_OPTS)" + +PKG_CONF_OPTS += -DUVC_APP_CROSS_COMPILE="$(RK_APP_CROSS)" + +# define project/cfg/BoardConfig*.mk +ifneq ($(RK_UVC_APP_CONFIG),) +PKG_TARGET := uvc_app-build +$(info ** $(PKG_NAME) build $(RK_APP_TYPE) **) +endif + +ifeq ($(PKG_BIN),) +$(error ### $(CURRENT_DIR): PKG_BIN is NULL, Please Check !!!) +endif + +all: $(PKG_TARGET) + @echo "build $(PKG_NAME) done" + +uvc_app-build: + @echo "RK_APP_CHIP is $(RK_APP_CHIP)" + @echo "RK_APP_TYPE is $(RK_APP_TYPE)" + rm -rf $(PKG_BIN) $(PKG_BUILD); \ + mkdir -p $(PKG_BIN); + mkdir -p $(PKG_BUILD); + pushd $(PKG_BUILD)/; \ + rm -rf CMakeCache.txt; \ + cmake $(CURRENT_DIR)/$(PKG_NAME)/ \ + -DCMAKE_C_COMPILER=$(RK_APP_CROSS)-gcc \ + -DCMAKE_CXX_COMPILER=$(RK_APP_CROSS)-g++ \ + -DCMAKE_INSTALL_PREFIX="$(CURRENT_DIR)/$(PKG_BIN)" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_COLOR_MAKEFILE=OFF \ + -DCMAKE_SYSTEM_NAME=Linux \ + $(RK_UVC_APP_CONFIG) \ + $(PKG_CONF_OPTS) ;\ + make -j$(RK_APP_JOBS) || exit -1; \ + make install; \ + popd; + $(call MAROC_COPY_PKG_TO_APP_OUTPUT, $(RK_APP_OUTPUT), $(PKG_BIN)) + +clean: + @rm -rf $(PKG_BIN) $(PKG_BUILD) + +distclean: clean + +info: +ifneq ($(RK_UVC_APP_CONFIG),) + @echo -e "$(C_YELLOW)-------------------------------------------------------------------------$(C_NORMAL)" + @echo -e "RK_APP_TYPE=$(RK_APP_TYPE)" + @echo -e "option support as follow:" + @echo -e " UVC" + @echo -e "$(C_YELLOW)-------------------------------------------------------------------------$(C_NORMAL)" +endif diff --git a/project/app/uvc_app_tiny/config_ini/rkuvc.ini b/project/app/uvc_app_tiny/config_ini/rkuvc.ini new file mode 100755 index 000000000..37b15a99a --- /dev/null +++ b/project/app/uvc_app_tiny/config_ini/rkuvc.ini @@ -0,0 +1,81 @@ +[video.source] +enable_aiq = 1 +enable_vo = 0 +enable_npu = 0 +enable_uac = 0 +enable_2uvc = 0 + +[isp.0.adjustment] +contrast = 50 +brightness = 50 +saturation = 50 +sharpness = 50 +fps = 30 +hue = 50 + +[isp.0.exposure] +iris_type = auto +exposure_mode = auto +gain_mode = auto +auto_iris_level = 5 +auto_exposure_enabled = 1 +audo_gain_enabled = 1 +exposure_time = 1/6 +exposure_gain = 1 + +[isp.0.night_to_day] +night_to_day = day +night_to_day_filter_level = 5 +night_to_day_filter_time = 5 +dawn_time = 07:00:00 +dusk_time = 18:00:00 +ircut_filter_action = day +over_exposure_suppress = open +over_exposure_suppress_type = auto +fill_light_mode = IR +brightness_adjustment_mode = auto +light_brightness = 1 +distance_level = 1 + +[isp.0.blc] +blc_region = close +blc_strength = 1 +wdr = close +wdr_level = 0 +hdr = close +hdr_level = 1 +hlc = close +hlc_level = 0 +dark_boost_level = 0 +position_x = 0 +position_y = 0 +blc_region_width = 120 +blc_region_high = 92 + +[isp.0.white_blance] +white_blance_style = autoWhiteBalance +white_blance_ct = 5000 + +[isp.0.enhancement] +noise_reduce_mode = close +denoise_level = 50 +spatial_denoise_level = 50 +temporal_denoise_level = 50 +dehaze = close +dehaze_level = 0 +dis = close +gray_scale_mode = [0-255] +image_rotation = 0 +distortion_correction = close +ldch_level = 0 + +[isp.0.video_adjustment] +image_flip = close +scene_mode = indoor +power_line_frequency_mode = PAL(50HZ) + +[isp.0.auto_focus] +af_mode = semi-auto +zoom_level = 0 +focus_level = 0 + diff --git a/project/app/uvc_app_tiny/config_ini/uvc_mpi_cfg.conf b/project/app/uvc_app_tiny/config_ini/uvc_mpi_cfg.conf new file mode 100755 index 000000000..6a7f471f8 --- /dev/null +++ b/project/app/uvc_app_tiny/config_ini/uvc_mpi_cfg.conf @@ -0,0 +1,728 @@ +{ + "index_0": { + "version" : 1, + "common_cfg": { + "version" : 1, + "property" : { + "param_init": { + "check_param_change_thread": "off", + "uvc_debug": "off", + "yuyv_debug": "off", + "nn_enable": "off", + "uvc_debug_file_name": "/data/uvc.bin", + "uvc_debug_file_cnt": 0, + "nn_debug_file_name": "/data/nn.bin", + "nn_debug_file_cnt": 0, + "uvc_enable_vpss": "off", + "geometric_output": "16:9" + }, + "param_change": { + } + } + }, + "eptz_cfg": { + "version" : 2, + "param_init": { + "enable": "on", + "enable_boot": "off", + "debug": "off", + "align": 2, + "zoom_speed": 3, + "fast_move_frame_judge": 40, + "zoom_frame_judge": 40, + "iterate_x": 10, + "iterate_y": 5, + "ratio": 0.4 + }, + "param_change": { + } + }, + "vi_cfg": { + "version" : 1, + "uvc" : { + "param_init": { + "dev_id": 0, + "channel_id": 0, + "buf_cnt": 1, + "assign_width": 0, + "assign_height": 0, + "min_width": 1920, + "min_height": 1080, + "max_width": 2880, + "max_height": 1616, + "format": "nv12", + "dev_name": "null", + "fps": "0:0", + "memory_type": 4, + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "nn" : { + "param_init": { + "dev_id": 0, + "channel_id": 1, + "assign_width": 512, + "assign_height": 288, + "format": "nv12", + "buf_cnt": 1, + "dev_name": "null", + "fps": "0:0", + "memory_type": 4, + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + } + }, + "vpss_cfg": { + "version" : 1, + "uvc" : { + "param_init": { + "group_id": 0, + "channel_id": 0, + "buf_cnt": 1, + "fps": "0:0", + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "nn" : { + "param_init": { + "group_id": 1, + "channel_id": 0, + "format": "bgr888", + "assign_width": 512, + "assign_height": 288, + "buf_cnt": 1, + "fps": "0:0", + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + } + }, + "venc_cfg": { + "version" : 1, + "common" : { + "param_init": { + "channel_id": 0, + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "mjpeg": { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "rc_mode": "fixqp", + "fps": "0:0", + "range": "full", + "sei": "off", + "qfactor": 85, + "qfactor_min": 30, + "qfactor_max": 99, + "bps": 60000 + }, + "1280*720p30": { + "qfactor": 80, + "qfactor_min": 60, + "qfactor_max": 90, + "bps": 70000 + }, + "1920*1080p30": { + "qfactor": 75, + "qfactor_min": 50, + "qfactor_max": 90, + "bps": 80000 + }, + "2560*1440p30": { + "qfactor": 70, + "qfactor_min": 50, + "qfactor_max": 90, + "bps": 90000 + }, + "2880*1616@30": { + "qfactor": 70, + "qfactor_min": 50, + "qfactor_max": 90, + "bps": 90000 + } + }, + "param_change": { + } + }, + "h264" : { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "gop": 60, + "rc_mode": "cbr", + "fps": "0:0", + "range": "full", + "qp": "26:4:20:40:8:48:2:1", + "sei": "off", + "profile": 100, + "vi_len": 30, + "gop_mode": 0, + "bps": 10000, + "force_idr": "5:5:20000" + }, + "1920*1080p30": { + "bps": 10000, + "force_idr": "5:5:30000" + }, + "2880*1616p30": { + "bps": 15000, + "force_idr": "5:5:40000" + }, + "2560*1440p30": { + "bps": 15000, + "force_idr": "5:5:40000" + } + }, + "param_change": { + } + }, + "h265" : { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "gop": 60, + "rc_mode": "cbr", + "fps": "0:0", + "range": "full", + "qp": "26:4:20:40:8:48:2:1", + "sei": "off", + "vi_len": 30, + "gop_mode": 0, + "bps": 10000, + "force_idr": "5:5:20000" + }, + "1920*1080p30": { + "bps": 10000, + "force_idr": "5:5:30000" + }, + "2560*1440p30": { + "bps": 15000, + "force_idr": "5:5:40000" + }, + "2880*1616p30": { + "bps": 15000, + "force_idr": "5:5:40000" + } + }, + "param_change": { + } + } + }, + "osd_cfg": { + "version" : 1, + "param_init": { + "enable": "off", + "force_use_vpss": "off" + }, + "param_change": { + } + } + }, + "index_1": { + "version" : 1, + "common_cfg": { + "version" : 1, + "property" : { + "param_init": { + "check_param_change_thread": "off", + "uvc_debug": "off", + "yuyv_debug": "off", + "nn_enable": "off", + "uvc_debug_file_name": "/data/uvc1.bin", + "uvc_debug_file_cnt": 0, + "nn_debug_file_name": "/data/nn1.bin", + "nn_debug_file_cnt": 0, + "uvc_enable_vpss": "off", + "geometric_output": "16:9" + }, + "param_change": { + } + } + }, + "eptz_cfg": { + "version" : 2, + "param_init": { + "enable": "on", + "enable_boot": "off", + "debug": "off", + "align": 2, + "zoom_speed": 3, + "fast_move_frame_judge": 40, + "zoom_frame_judge": 40, + "iterate_x": 10, + "iterate_y": 5, + "ratio": 0.4 + }, + "param_change": { + } + }, + "vi_cfg": { + "version" : 1, + "uvc" : { + "param_init": { + "dev_id": 1, + "channel_id": 0, + "buf_cnt": 1, + "assign_width": 0, + "assign_height": 0, + "min_width": 1280, + "min_height": 720, + "max_width": 2880, + "max_height": 1616, + "format": "nv12", + "dev_name": "null", + "fps": "0:0", + "memory_type": 4, + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "nn" : { + "param_init": { + "dev_id": 1, + "channel_id": 1, + "assign_width": 512, + "assign_height": 288, + "format": "nv12", + "buf_cnt": 1, + "dev_name": "null", + "fps": "0:0", + "memory_type": 4, + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + } + }, + "vpss_cfg": { + "version" : 1, + "uvc" : { + "param_init": { + "group_id": 1, + "channel_id": 0, + "buf_cnt": 1, + "fps": "0:0", + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "nn" : { + "param_init": { + "group_id": 1, + "channel_id": 0, + "format": "bgr888", + "assign_width": 512, + "assign_height": 288, + "buf_cnt": 1, + "fps": "0:0", + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + } + }, + "venc_cfg": { + "version" : 1, + "common" : { + "param_init": { + "channel_id": 1, + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "mjpeg": { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "rc_mode": "fixqp", + "fps": "0:0", + "range": "full", + "sei": "off", + "qfactor": 85, + "qfactor_min": 30, + "qfactor_max": 99, + "bps": 60000 + }, + "1280*720p30": { + "qfactor": 80, + "qfactor_min": 60, + "qfactor_max": 90, + "bps": 70000 + }, + "1920*1080p30": { + "qfactor": 75, + "qfactor_min": 50, + "qfactor_max": 90, + "bps": 80000 + }, + "2560*1440p30": { + "qfactor": 70, + "qfactor_min": 50, + "qfactor_max": 90, + "bps": 90000 + }, + "2880*1616@30": { + "qfactor": 70, + "qfactor_min": 50, + "qfactor_max": 90, + "bps": 90000 + } + }, + "param_change": { + } + }, + "h264" : { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "gop": 60, + "rc_mode": "cbr", + "fps": "0:0", + "range": "full", + "qp": "26:4:20:40:8:48:2:1", + "sei": "off", + "profile": 100, + "vi_len": 30, + "gop_mode": 0, + "bps": 10000, + "force_idr": "5:5:20000" + }, + "1920*1080p30": { + "bps": 10000, + "force_idr": "5:5:30000" + }, + "2560*1440p30": { + "bps": 15000, + "force_idr": "5:5:40000" + }, + "2880*1616p30": { + "bps": 15000, + "force_idr": "5:5:40000" + } + }, + "param_change": { + } + }, + "h265" : { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "gop": 60, + "rc_mode": "cbr", + "fps": "0:0", + "range": "full", + "qp": "26:4:20:40:8:48:2:1", + "sei": "off", + "vi_len": 30, + "gop_mode": 0, + "bps": 10000, + "force_idr": "5:5:20000" + }, + "1920*1080p30": { + "bps": 10000, + "force_idr": "5:5:30000" + }, + "2560*1440p30": { + "bps": 15000, + "force_idr": "5:5:40000" + }, + "2880*1616p30": { + "bps": 15000, + "force_idr": "5:5:40000" + } + }, + "param_change": { + } + } + }, + "osd_cfg": { + "version" : 1, + "param_init": { + "enable": "off", + "force_use_vpss": "off" + }, + "param_change": { + } + } + }, + "index_2": { + "version" : 1, + "common_cfg": { + "version" : 1, + "property" : { + "param_init": { + "check_param_change_thread": "off", + "uvc_debug": "off", + "yuyv_debug": "off", + "nn_enable": "off", + "uvc_debug_file_name": "/data/uvc2.bin", + "uvc_debug_file_cnt": 0, + "nn_debug_file_name": "/data/nn2.bin", + "nn_debug_file_cnt": 0, + "uvc_enable_vpss": "off", + "geometric_output": "16:9" + }, + "param_change": { + } + } + }, + "eptz_cfg": { + "version" : 2, + "param_init": { + "enable": "on", + "enable_boot": "off", + "debug": "off", + "align": 2, + "zoom_speed": 3, + "fast_move_frame_judge": 40, + "zoom_frame_judge": 40, + "iterate_x": 10, + "iterate_y": 5, + "ratio": 0.4 + }, + "param_change": { + } + }, + "vi_cfg": { + "version" : 1, + "uvc" : { + "param_init": { + "dev_id": 2, + "channel_id": 0, + "buf_cnt": 1, + "assign_width": 0, + "assign_height": 0, + "min_width": 640, + "min_height": 480, + "max_width": 2880, + "max_height": 1616, + "format": "nv12", + "dev_name": "null", + "fps": "0:0", + "memory_type": 4, + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "nn" : { + "param_init": { + "dev_id": 2, + "channel_id": 1, + "assign_width": 512, + "assign_height": 288, + "format": "nv12", + "buf_cnt": 1, + "dev_name": "null", + "fps": "0:0", + "memory_type": 4, + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + } + }, + "vpss_cfg": { + "version" : 1, + "uvc" : { + "param_init": { + "group_id": 2, + "channel_id": 0, + "buf_cnt": 1, + "fps": "0:0", + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "nn" : { + "param_init": { + "group_id": 1, + "channel_id": 0, + "format": "bgr888", + "assign_width": 512, + "assign_height": 288, + "buf_cnt": 1, + "fps": "0:0", + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + } + }, + "venc_cfg": { + "version" : 1, + "common" : { + "param_init": { + "channel_id": 2, + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "mjpeg": { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "rc_mode": "fixqp", + "fps": "0:0", + "range": "full", + "sei": "off", + "qfactor": 85, + "qfactor_min": 30, + "qfactor_max": 99, + "bps": 60000 + }, + "1280*720p30": { + "qfactor": 80, + "qfactor_min": 60, + "qfactor_max": 90, + "bps": 70000 + }, + "1920*1080p30": { + "qfactor": 75, + "qfactor_min": 50, + "qfactor_max": 90, + "bps": 80000 + }, + "2560*1440p30": { + "qfactor": 70, + "qfactor_min": 50, + "qfactor_max": 90, + "bps": 90000 + }, + "2880*1616@30": { + "qfactor": 70, + "qfactor_min": 50, + "qfactor_max": 90, + "bps": 90000 + } + }, + "param_change": { + } + }, + "h264" : { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "gop": 60, + "rc_mode": "cbr", + "fps": "0:0", + "range": "full", + "qp": "26:4:20:40:8:48:2:1", + "sei": "off", + "profile": 100, + "vi_len": 30, + "gop_mode": 0, + "bps": 10000, + "force_idr": "5:5:20000" + }, + "1920*1080p30": { + "bps": 10000, + "force_idr": "5:5:30000" + }, + "2560*1440p30": { + "bps": 15000, + "force_idr": "5:5:40000" + }, + "2880*1616p30": { + "bps": 15000, + "force_idr": "5:5:40000" + } + }, + "param_change": { + } + }, + "h265" : { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "gop": 60, + "rc_mode": "cbr", + "fps": "0:0", + "range": "full", + "qp": "26:4:20:40:8:48:2:1", + "sei": "off", + "vi_len": 30, + "gop_mode": 0, + "bps": 10000, + "force_idr": "5:5:20000" + }, + "1920*1080p30": { + "bps": 10000, + "force_idr": "5:5:30000" + }, + "2560*1440p30": { + "bps": 15000, + "force_idr": "5:5:40000" + }, + "2880*1616p30": { + "bps": 15000, + "force_idr": "5:5:40000" + } + }, + "param_change": { + } + } + }, + "osd_cfg": { + "version" : 1, + "param_init": { + "enable": "off", + "force_use_vpss": "off" + }, + "param_change": { + } + } + } +} diff --git a/project/app/uvc_app_tiny/uvc_app/CMakeLists.txt b/project/app/uvc_app_tiny/uvc_app/CMakeLists.txt new file mode 100755 index 000000000..5635181e0 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/CMakeLists.txt @@ -0,0 +1,116 @@ +cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR) +set(CMAKE_CXX_STANDARD 11) +add_definitions(-DDBUG) +add_definitions(-g) +PROJECT(rk_mpi_uvc) +include(FindPkgConfig) + +include_directories(uvc) +include_directories(uvc/cJSON) +include_directories(isp) +include_directories(param) + +include_directories(${PROJECT_SOURCE_DIR}/include + ${CMAKE_SYSROOT}/usr/include/rkaiq/ + ${CMAKE_SYSROOT}/usr/include/rkaiq/uAPI + ${CMAKE_SYSROOT}/usr/include/rkaiq/uAPI2 + ${CMAKE_SYSROOT}/usr/include/rkaiq/algos + ${CMAKE_SYSROOT}/usr/include/rkaiq/common + ${CMAKE_SYSROOT}/usr/include/rkaiq/xcore + ${CMAKE_SYSROOT}/usr/include/rkaiq/iq_parser + ${CMAKE_SYSROOT}/usr/include/rkaiq/iq_parser_v2 + ${CMAKE_SYSROOT}/usr/include/libdrm + ) + +option(COMPILE_FOR_UVC_UAC "compile for uac" OFF) +if(COMPILE_FOR_UVC_UAC) + include(uac/uac.cmake) +endif() + +set(LIB_SOURCE + uvc/uvc-gadget.c + uvc/uvc_video.cpp + uvc/uvc_control.cpp + uvc/uvc_process.cpp + uvc/uvc_mpi_config.c + uvc/uvc_mpi_venc.cpp + uvc/uvc_mpi_vi.cpp + uvc/uvc_mpi_vpss.cpp + uvc/uevent.c + uvc/uvc_configfs.c + uvc/camera_control.c + uvc/camera_pu_control.c + uvc/cJSON/cJSON.c + uvc/osd.c + isp/isp.c + param/dictionary.c + param/iniparser.c + param/param.c +) + +if(COMPILE_FOR_UVC_UAC) +add_definitions(-DCOMPILE_FOR_UVC_UAC) +set(SOURCE + main.c + ${LIB_SOURCE} + ${UAC_SOURCE} +) + +else() + +set(SOURCE + main.c + ${LIB_SOURCE} +) + +endif() + +if (RK_ENABLE_FASTBOOT) +set(RK_MPI_UVC_DEPENDENT_LIBS + pthread + rt + rkaiq + librockit.a + librockchip_mpp.a + librkaudio_detect.a + libaec_bf_process.a + librga.a +) + message(STATUS "RK_ENABLE_FASTBOOT is enabled.") +else() + set(RK_MPI_UVC_DEPENDENT_LIBS + pthread + rt + rkaiq + rockit + ) + message(STATUS "RK_ENABLE_FASTBOOT is disabled.") +endif() +set(RK_MPI_UVC_INC + ${CMAKE_CURRENT_SOURCE_DIR}/uvc/ +) + +add_definitions(-fno-rtti) + +ADD_EXECUTABLE(rk_mpi_uvc ${SOURCE}) +link_directories(${PROJECT_SOURCE_DIR}/lib/) +target_link_libraries(rk_mpi_uvc ${RK_MPI_UVC_DEPENDENT_LIBS}) + +install(DIRECTORY ./uvc DESTINATION include + FILES_MATCHING PATTERN "*.h") + +install(TARGETS rk_mpi_uvc DESTINATION bin) +install(FILES uvc_mpi_cfg.conf DESTINATION share) +install(FILES rkuvc.ini DESTINATION share) +install(FILES usb_config.sh DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_WRITE GROUP_EXECUTE + WORLD_READ WORLD_WRITE WORLD_EXECUTE) +#install(FILES RkLunch.sh DESTINATION bin +# PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE +# GROUP_READ GROUP_WRITE GROUP_EXECUTE +# WORLD_READ WORLD_WRITE WORLD_EXECUTE) +#install(FILES RkLunch-stop.sh DESTINATION bin +# PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE +# GROUP_READ GROUP_WRITE GROUP_EXECUTE +# WORLD_READ WORLD_WRITE WORLD_EXECUTE) \ No newline at end of file diff --git a/project/app/uvc_app_tiny/uvc_app/LICENSE b/project/app/uvc_app_tiny/uvc_app/LICENSE new file mode 100755 index 000000000..d04b1cb4c --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/LICENSE @@ -0,0 +1,28 @@ +// Copyright 2021 Rockchip Electronics Co.,Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. diff --git a/project/app/uvc_app_tiny/uvc_app/RkLunch-stop.sh b/project/app/uvc_app_tiny/uvc_app/RkLunch-stop.sh new file mode 100755 index 000000000..2f3914183 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/RkLunch-stop.sh @@ -0,0 +1,30 @@ +#!/bin/sh +program_kill() +{ + P_PID=`ps | grep $1 | grep -v grep | awk '{print $1}'` + test -z ${P_PID} || kill -9 ${P_PID} +} + +echo "Stop Application ..." +program_kill RkLunch.sh +killall rk_mpi_uvc & + +cnt=0 +while [ 1 ]; +do + sleep 1 + cnt=$(( cnt + 1 )) + if [ $cnt -eq 8 ]; then + echo "killall -9 rk_mpi_uvc" + killall -9 rk_mpi_uvc + sleep 0.1 + break + fi + ps|grep rk_mpi_uvc|grep -v grep + if [ $? -ne 0 ]; then + echo "rk_mpi_uvc exit" + break + else + echo "rk_mpi_uvc active" + fi +done diff --git a/project/app/uvc_app_tiny/uvc_app/RkLunch.sh b/project/app/uvc_app_tiny/uvc_app/RkLunch.sh new file mode 100755 index 000000000..71eea5db8 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/RkLunch.sh @@ -0,0 +1,105 @@ +#!/bin/sh +check_usb_state() +{ + if [[ ! -f "/oem/usr/bin/rk_mpi_uvc" && ! -f "/usr/bin/rk_mpi_uvc" ]]; then + return 1 + fi + PID=`ps |grep rk_mpi_uvc |grep -v grep | wc -l` + if [ $PID -le 0 ];then + echo " exit rk_mpi_uvc ,restart it for uvc recovery..." + killall adbd + sleep 1 + killall -9 adbd + rm -rf /sys/kernel/config/usb_gadget/rockchip/configs/b.1/f* + echo none > /sys/kernel/config/usb_gadget/rockchip/UDC + rmdir /sys/kernel/config/usb_gadget/rockchip/functions/ffs.adb + rmdir /sys/kernel/config/usb_gadget/rockchip/functions/uac* + UDC=`ls /sys/class/udc/| awk '{print $1}'` + echo $UDC > /sys/bus/platform/drivers/dwc3/unbind + echo $UDC > /sys/bus/platform/drivers/dwc3/bind + /oem/usr/bin/usb_config.sh uac1 #off #disable adb + if [ -d "/oem/usr/share/iqfiles" ];then + rk_mpi_uvc -c /tmp/rkuvc.ini -a /oem/usr/share/iqfiles & + else + rk_mpi_uvc & + fi + fi +} + +post_chk() +{ + #TODO: ensure /userdata mount done + cnt=0 + while [ $cnt -lt 30 ]; + do + cnt=$(( cnt + 1 )) + if mount | grep -w userdata; then + break + fi + sleep .1 + done + + # if ko exist, install ko first + default_ko_dir=/ko + if [ -f "/oem/usr/ko/insmod_ko.sh" ];then + default_ko_dir=/oem/usr/ko + fi + if [ -f "$default_ko_dir/insmod_ko.sh" ];then + cd $default_ko_dir && sh insmod_ko.sh && cd - + fi + + # if /data/rkuvc not exist, cp /usr/share + rkuvc_ini=/tmp/rkuvc.ini + default_rkuvc_ini=/usr/share/rkuvc.ini + if [ ! -f "$default_rkuvc_ini" ];then + default_rkuvc_ini=/oem/usr/share/rkuvc.ini + fi + if [ ! -f "$default_rkuvc_ini" ];then + echo "Error: not found rkuvc.ini !!!" + exit -1 + fi + if [ ! -f "$rkuvc_ini" ]; then + cp $default_rkuvc_ini $rkuvc_ini -f + fi + + export rt_log_level=3 + export rk_mpi_uvc_log_level=2 + export uac_app_log_level=2 + + touch /tmp/uvc_no_timeout + /oem/usr/bin/usb_config.sh uac1 + ifconfig lo 127.0.0.1 + + if [ -d "/oem/usr/share/iqfiles" ];then + rk_mpi_uvc -c /tmp/rkuvc.ini -a /oem/usr/share/iqfiles & + else + rk_mpi_uvc & + fi + + while true + do + sleep 2 + if [ -f "/tmp/uvc_stop_check" ]; then + echo " stop check usb state sh " && break + else + check_usb_state + fi + + if [ -f "/tmp/reboot_loader" ]; then + echo "exec reboot loader cmd..." + reboot loader & + fi + done +} +start_app() +{ + if [ -f "/etc/init.d/S50usbdevice" ];then + mv /etc/init.d/S50usbdevice /etc/S50usbdevice -f + fi + echo "##### start uvc app ..." + post_chk & +} +ulimit -c unlimited +echo "/data/core-%p-%e" > /proc/sys/kernel/core_pattern + +start_app diff --git a/project/app/uvc_app_tiny/uvc_app/format.sh b/project/app/uvc_app_tiny/uvc_app/format.sh new file mode 100755 index 000000000..46a997e94 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/format.sh @@ -0,0 +1,9 @@ +#!/bin/bash +## +## Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved. +## Use of this source code is governed by a BSD-style license that can be +## found in the LICENSE file. +## + +find . -name "*.c" -o -name "*.h" | xargs clang-format -style=file -i +find . -name "*.cpp" -o -name "*.h" | xargs clang-format -style=file -i diff --git a/project/app/uvc_app_tiny/uvc_app/isp/isp.c b/project/app/uvc_app_tiny/uvc_app/isp/isp.c new file mode 100644 index 000000000..b130f181b --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/isp/isp.c @@ -0,0 +1,1293 @@ +#include "iniparser.h" +#include "param.h" +#include "uvc_log.h" +#include +#include +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "isp.c" + +#define MAX_AIQ_CTX 8 +char g_iq_file_dir_[256]; + +static int rkuvc_aiq_use_group = 0; +static rk_aiq_sys_ctx_t *g_aiq_ctx[MAX_AIQ_CTX]; +static rk_aiq_camgroup_ctx_t *g_camera_group_ctx[MAX_AIQ_CTX]; +rk_aiq_working_mode_t g_WDRMode[MAX_AIQ_CTX]; +rk_aiq_wb_gain_t gs_wb_gain = {2.083900, 1.000000, 1.000000, 2.018500}; + +#define RK_ISP_CHECK_CAMERA_ID(CAMERA_ID) \ + do { \ + if (rkuvc_aiq_use_group) { \ + if (CAMERA_ID >= MAX_AIQ_CTX || !g_camera_group_ctx[CAMERA_ID]) { \ + LOG_ERROR("camera_group_id is over 3 or not init\n"); \ + return -1; \ + } \ + } else { \ + if (CAMERA_ID >= MAX_AIQ_CTX || !g_aiq_ctx[CAMERA_ID]) { \ + LOG_ERROR("camera_id is over 3 or not init\n"); \ + return -1; \ + } \ + } \ + } while (0) + +#define RK_ISP_CHECK_NORMAL_MODE(CAMERA_ID) \ + do { \ + if (g_WDRMode[cam_id] != RK_AIQ_WORKING_MODE_NORMAL) { \ + LOG_ERROR("Not support in HDR mode\n"); \ + return 0; \ + } \ + } while (0) + +rk_aiq_sys_ctx_t *rkuvc_aiq_get_ctx(int cam_id) { + if (rkuvc_aiq_use_group) + return (rk_aiq_sys_ctx_t *)g_camera_group_ctx[cam_id]; + + return g_aiq_ctx[cam_id]; +} + +int sample_common_isp_init(int cam_id, rk_aiq_working_mode_t WDRMode, + bool MultiCam, const char *iq_file_dir) { + if (cam_id >= MAX_AIQ_CTX) { + LOG_ERROR("%s : cam_id is over 3\n", __FUNCTION__); + return -1; + } + setlinebuf(stdout); + if (iq_file_dir == NULL) { + LOG_ERROR("rk_isp_init : not start.\n"); + g_aiq_ctx[cam_id] = NULL; + return 0; + } + + // must set HDR_MODE, before init + g_WDRMode[cam_id] = WDRMode; + char hdr_str[16]; + snprintf(hdr_str, sizeof(hdr_str), "%d", (int)WDRMode); + setenv("HDR_MODE", hdr_str, 1); + + rk_aiq_sys_ctx_t *aiq_ctx; + rk_aiq_static_info_t aiq_static_info; + rk_aiq_uapi2_sysctl_enumStaticMetas(cam_id, &aiq_static_info); + if (aiq_static_info.sensor_info.phyId == -1) { + LOG_INFO("WARN: aiq_static_info.sensor_info.phyId is %d\n", + aiq_static_info.sensor_info.phyId); + } + + LOG_INFO("ID: %d, sensor_name is %s, iqfiles is %s\n", cam_id, + aiq_static_info.sensor_info.sensor_name, iq_file_dir); + + int ret; + if (WDRMode == RK_AIQ_WORKING_MODE_NORMAL) + ret = rk_aiq_uapi2_sysctl_preInit_scene( + aiq_static_info.sensor_info.sensor_name, "normal", "day"); + else + ret = rk_aiq_uapi2_sysctl_preInit_scene( + aiq_static_info.sensor_info.sensor_name, "hdr", "day"); + if (ret < 0) + LOG_ERROR("%s: failed to set scene\n", + aiq_static_info.sensor_info.sensor_name); + +#if 1 + aiq_ctx = rk_aiq_uapi2_sysctl_init(aiq_static_info.sensor_info.sensor_name, + iq_file_dir, NULL, NULL); +// LOG_ERROR("tmp force use m00_b_imx464 3-001a\n"); +#else + if (cam_id == 0) + aiq_ctx = rk_aiq_uapi2_sysctl_init("m02_b_imx464 3-001a", iq_file_dir, NULL, + NULL); + else if (cam_id == 1) + aiq_ctx = rk_aiq_uapi2_sysctl_init("m03_b_imx464 3-0036", iq_file_dir, NULL, + NULL); + else if (cam_id == 2) + aiq_ctx = rk_aiq_uapi2_sysctl_init("m00_b_imx464 4-001a", iq_file_dir, NULL, + NULL); + else if (cam_id == 3) + aiq_ctx = rk_aiq_uapi2_sysctl_init("m01_b_imx464 4-0036", iq_file_dir, NULL, + NULL); + else if (cam_id == 4) + aiq_ctx = rk_aiq_uapi2_sysctl_init("m04_b_imx464 5-001a", iq_file_dir, NULL, + NULL); + else if (cam_id == 5) + aiq_ctx = rk_aiq_uapi2_sysctl_init("m05_b_imx464 5-0036", iq_file_dir, NULL, + NULL); +#endif + // if (MultiCam) + // rk_aiq_uapi2_sysctl_setMulCamConc(aiq_ctx, true); + + g_aiq_ctx[cam_id] = aiq_ctx; + + return 0; +} + +int sample_common_isp_run(int cam_id) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + if (rk_aiq_uapi2_sysctl_prepare(g_aiq_ctx[cam_id], 0, 0, g_WDRMode[cam_id])) { + LOG_ERROR("rkaiq engine prepare failed !\n"); + g_aiq_ctx[cam_id] = NULL; + return -1; + } + LOG_INFO("cam_id:%d,rk_aiq_uapi2_sysctl_init/prepare succeed\n", cam_id); + if (rk_aiq_uapi2_sysctl_start(g_aiq_ctx[cam_id])) { + LOG_ERROR("cam_id:%d,rk_aiq_uapi2_sysctl_start failed\n", cam_id); + return -1; + } + LOG_INFO("cam_id:%d,rk_aiq_uapi2_sysctl_start succeed\n", cam_id); + return 0; +} + +int isp_camera_group_init(int cam_group_id, rk_aiq_working_mode_t WDRMode, + bool MultiCam, const char *iq_file_dir) { + int ret; + rk_aiq_sys_ctx_t *aiq_ctx; + rk_aiq_static_info_t aiq_static_info; + char sensor_name_array[6][128]; + rk_aiq_camgroup_instance_cfg_t camgroup_cfg; + memset(&camgroup_cfg, 0, sizeof(camgroup_cfg)); + + camgroup_cfg.sns_num = rk_param_get_int("avs:sensor_num", 6); + LOG_INFO("camgroup_cfg.sns_num is %d\n", camgroup_cfg.sns_num); + for (int i = 0; i < camgroup_cfg.sns_num; i++) { + rk_aiq_uapi2_sysctl_enumStaticMetas(i, &aiq_static_info); + LOG_INFO("cam_group_id:%d, cam_id: %d, sensor_name is %s, iqfiles is %s\n", + cam_group_id, i, aiq_static_info.sensor_info.sensor_name, + iq_file_dir); + memcpy(sensor_name_array[i], aiq_static_info.sensor_info.sensor_name, + strlen(aiq_static_info.sensor_info.sensor_name) + 1); + camgroup_cfg.sns_ent_nm_array[i] = sensor_name_array[i]; + LOG_INFO("camgroup_cfg.sns_ent_nm_array[%d] is %s\n", i, + camgroup_cfg.sns_ent_nm_array[i]); + if (WDRMode == RK_AIQ_WORKING_MODE_NORMAL) + ret = rk_aiq_uapi2_sysctl_preInit_scene( + aiq_static_info.sensor_info.sensor_name, "normal", "day"); + else + ret = rk_aiq_uapi2_sysctl_preInit_scene( + aiq_static_info.sensor_info.sensor_name, "hdr", "day"); + if (ret < 0) + LOG_ERROR("%s: failed to set scene\n", + aiq_static_info.sensor_info.sensor_name); + } + + camgroup_cfg.config_file_dir = iq_file_dir; + g_camera_group_ctx[cam_group_id] = + rk_aiq_uapi2_camgroup_create(&camgroup_cfg); + if (!g_camera_group_ctx[cam_group_id]) { + LOG_ERROR("create camgroup ctx error!\n"); + return -1; + } + LOG_INFO("rk_aiq_uapi2_camgroup_create over\n"); + ret = + rk_aiq_uapi2_camgroup_prepare(g_camera_group_ctx[cam_group_id], WDRMode); + LOG_INFO("rk_aiq_uapi2_camgroup_prepare over\n"); + ret |= rk_aiq_uapi2_camgroup_start(g_camera_group_ctx[cam_group_id]); + LOG_INFO("rk_aiq_uapi2_camgroup_start over\n"); + + return ret; +} + +int isp_camera_group_stop(int cam_group_id) { + RK_ISP_CHECK_CAMERA_ID(cam_group_id); + LOG_INFO("rk_aiq_uapi2_camgroup_stop enter\n"); + rk_aiq_uapi2_camgroup_stop(g_camera_group_ctx[cam_group_id]); + LOG_INFO("rk_aiq_uapi2_camgroup_destroy enter\n"); + rk_aiq_uapi2_camgroup_destroy(g_camera_group_ctx[cam_group_id]); + LOG_INFO("rk_aiq_uapi2_camgroup_destroy exit\n"); + g_camera_group_ctx[cam_group_id] = NULL; + + return 0; +} + +int rk_isp_set_frame_rate(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret; + char entry[128] = {'\0'}; + Uapi_ExpSwAttrV2_t expSwAttr; + LOG_INFO("start %d\n", value); + ret = rk_aiq_user_api2_ae_getExpSwAttr(rkuvc_aiq_get_ctx(cam_id), &expSwAttr); + expSwAttr.stAuto.stFrmRate.isFpsFix = true; + expSwAttr.stAuto.stFrmRate.FpsValue = value; + ret = rk_aiq_user_api2_ae_setExpSwAttr(rkuvc_aiq_get_ctx(cam_id), expSwAttr); + LOG_INFO("end, %d\n", value); + + snprintf(entry, 127, "isp.%d.adjustment:fps", cam_id); + // rk_param_set_int(entry, value); + + return 0; +} + +// image adjustment + +int rk_isp_get_contrast(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.adjustment:contrast", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_contrast(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret; + char entry[128] = {'\0'}; + acp_attrib_t attrib; + ret = rk_aiq_user_api2_acp_GetAttrib(rkuvc_aiq_get_ctx(cam_id), &attrib); + attrib.contrast = value * 2.55; // value[0,255] + ret |= rk_aiq_user_api2_acp_SetAttrib(rkuvc_aiq_get_ctx(cam_id), &attrib); + snprintf(entry, 127, "isp.%d.adjustment:contrast", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_brightness(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.adjustment:brightness", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_brightness(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret; + char entry[128] = {'\0'}; + acp_attrib_t attrib; + ret = rk_aiq_user_api2_acp_GetAttrib(rkuvc_aiq_get_ctx(cam_id), &attrib); + attrib.brightness = value * 2.55; // value[0,255] + ret |= rk_aiq_user_api2_acp_SetAttrib(rkuvc_aiq_get_ctx(cam_id), &attrib); + snprintf(entry, 127, "isp.%d.adjustment:brightness", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_saturation(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.adjustment:saturation", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_saturation(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret; + char entry[128] = {'\0'}; + acp_attrib_t attrib; + ret = rk_aiq_user_api2_acp_GetAttrib(rkuvc_aiq_get_ctx(cam_id), &attrib); + attrib.saturation = value * 2.55; // value[0,255] + ret |= rk_aiq_user_api2_acp_SetAttrib(rkuvc_aiq_get_ctx(cam_id), &attrib); + snprintf(entry, 127, "isp.%d.adjustment:saturation", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_sharpness(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.adjustment:sharpness", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_sharpness(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret = 0; + ret = rk_aiq_uapi2_setSharpness(rkuvc_aiq_get_ctx(cam_id), value); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.adjustment:sharpness", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_hue(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.adjustment:hue", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_hue(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret; + char entry[128] = {'\0'}; + acp_attrib_t attrib; + ret = rk_aiq_user_api2_acp_GetAttrib(rkuvc_aiq_get_ctx(cam_id), &attrib); + attrib.hue = value * 2.55; // value[0,255] + ret |= rk_aiq_user_api2_acp_SetAttrib(rkuvc_aiq_get_ctx(cam_id), &attrib); + snprintf(entry, 127, "isp.%d.adjustment:hue", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_hue_mode(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.adjustment:hueauto", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_hue_mode(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + if (value == 1) + value = 50; // auto + else { + rk_isp_get_hue(cam_id, &value); + if (value == -1) + value = 50; + } + LOG_INFO("hue_mode: value: %d\n", value); + int ret; + char entry[128] = {'\0'}; + acp_attrib_t attrib; + ret = rk_aiq_user_api2_acp_GetAttrib(rkuvc_aiq_get_ctx(cam_id), &attrib); + attrib.hue = value * 2.55; // value[0,255] + ret |= rk_aiq_user_api2_acp_SetAttrib(rkuvc_aiq_get_ctx(cam_id), &attrib); + snprintf(entry, 127, "isp.%d.adjustment:hueauto", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +// exposure +int rk_isp_get_exposure_mode(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.exposure:exposure_mode", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_exposure_mode(int cam_id, const char *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + Uapi_ExpSwAttrV2_t expSwAttr; + rk_aiq_user_api2_ae_getExpSwAttr(rkuvc_aiq_get_ctx(cam_id), &expSwAttr); + if (!strcmp(value, "auto")) { + expSwAttr.AecOpType = RK_AIQ_OP_MODE_AUTO; + } else { + if (g_WDRMode[cam_id] != RK_AIQ_WORKING_MODE_NORMAL) { + expSwAttr.AecOpType = RK_AIQ_OP_MODE_MANUAL; + expSwAttr.stManual.HdrAE.ManualGainEn = true; + expSwAttr.stManual.HdrAE.ManualTimeEn = true; + } else { + expSwAttr.AecOpType = RK_AIQ_OP_MODE_MANUAL; + expSwAttr.stManual.LinearAE.ManualGainEn = true; + expSwAttr.stManual.LinearAE.ManualTimeEn = true; + } + } + int ret = + rk_aiq_user_api2_ae_setExpSwAttr(rkuvc_aiq_get_ctx(cam_id), expSwAttr); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.exposure:exposure_mode", cam_id); + rk_param_set_string(entry, value); + + return 0; +} + +int rk_isp_get_gain_mode(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.exposure:gain_mode", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_gain_mode(int cam_id, const char *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + Uapi_ExpSwAttrV2_t stExpSwAttr; + + rk_aiq_user_api2_ae_getExpSwAttr(rkuvc_aiq_get_ctx(cam_id), &stExpSwAttr); + if (!strcmp(value, "auto")) { + stExpSwAttr.stManual.LinearAE.ManualGainEn = false; + stExpSwAttr.stManual.HdrAE.ManualGainEn = false; + } else { + stExpSwAttr.stManual.LinearAE.ManualGainEn = true; + stExpSwAttr.stManual.HdrAE.ManualGainEn = true; + } + int ret = + rk_aiq_user_api2_ae_setExpSwAttr(rkuvc_aiq_get_ctx(cam_id), stExpSwAttr); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.exposure:gain_mode", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_exposure_time(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.exposure:exposure_time", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_exposure_time(int cam_id, const char *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + Uapi_ExpSwAttrV2_t stExpSwAttr; + float den, num, result; + if (strchr(value, '/') == NULL) { + den = 1; + sscanf(value, "%f", &result); + } else { + sscanf(value, "%f/%f", &num, &den); + result = num / den; + } + rk_aiq_user_api2_ae_getExpSwAttr(rkuvc_aiq_get_ctx(cam_id), &stExpSwAttr); + stExpSwAttr.stManual.LinearAE.TimeValue = result; + stExpSwAttr.stManual.HdrAE.TimeValue[0] = result; + stExpSwAttr.stManual.HdrAE.TimeValue[1] = result; + stExpSwAttr.stManual.HdrAE.TimeValue[2] = result; + int ret = + rk_aiq_user_api2_ae_setExpSwAttr(rkuvc_aiq_get_ctx(cam_id), stExpSwAttr); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.exposure:exposure_time", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_exposure_gain(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.exposure:exposure_gain", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_exposure_gain(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + Uapi_ExpSwAttrV2_t stExpSwAttr; + float gain_set = (value * 1.0f); + rk_aiq_user_api2_ae_getExpSwAttr(rkuvc_aiq_get_ctx(cam_id), &stExpSwAttr); + stExpSwAttr.stManual.LinearAE.GainValue = gain_set; + stExpSwAttr.stManual.HdrAE.GainValue[0] = gain_set; + stExpSwAttr.stManual.HdrAE.GainValue[1] = gain_set; + stExpSwAttr.stManual.HdrAE.GainValue[2] = gain_set; + int ret = + rk_aiq_user_api2_ae_setExpSwAttr(rkuvc_aiq_get_ctx(cam_id), stExpSwAttr); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.exposure:exposure_gain", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +// blc +int rk_isp_get_hdr(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:hdr", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_hdr(int cam_id, const char *value) { + int ret; + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:hdr", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_blc_region(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:blc_region", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_blc_region(int cam_id, const char *value) { + int ret; + RK_ISP_CHECK_CAMERA_ID(cam_id); + RK_ISP_CHECK_NORMAL_MODE(cam_id); + Uapi_LinExpAttrV2_t LineExpAttr; + + ret = rk_aiq_user_api2_ae_getLinExpAttr(rkuvc_aiq_get_ctx(cam_id), + &LineExpAttr); + if (!strcmp(value, "close")) + LineExpAttr.Params.BackLightCtrl.Enable = 0; + else + LineExpAttr.Params.BackLightCtrl.Enable = 1; + LineExpAttr.Params.BackLightCtrl.MeasArea = AECV2_MEASURE_AREA_AUTO; + LineExpAttr.Params.BackLightCtrl.StrBias = 0; + ret = + rk_aiq_user_api2_ae_setLinExpAttr(rkuvc_aiq_get_ctx(cam_id), LineExpAttr); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:blc_region", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_hlc(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:hlc", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_hlc(int cam_id, const char *value) { + int ret; + RK_ISP_CHECK_CAMERA_ID(cam_id); + RK_ISP_CHECK_NORMAL_MODE(cam_id); + Uapi_LinExpAttrV2_t LinExpAttr; + + ret = + rk_aiq_user_api2_ae_getLinExpAttr(rkuvc_aiq_get_ctx(cam_id), &LinExpAttr); + if (ret) + LOG_ERROR("get exp attr failed\n"); + if (!strcmp(value, "close")) + LinExpAttr.Params.OverExpCtrl.Enable = 0; + else + LinExpAttr.Params.OverExpCtrl.Enable = 1; + LinExpAttr.Params.OverExpCtrl.StrBias = 0; + ret = + rk_aiq_user_api2_ae_setLinExpAttr(rkuvc_aiq_get_ctx(cam_id), LinExpAttr); + if (ret) + LOG_ERROR("set exp attr failed\n"); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:hlc", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_hdr_level(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:hdr_level", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_hdr_level(int cam_id, int value) { + int ret; + RK_ISP_CHECK_CAMERA_ID(cam_id); + rk_aiq_uapi2_setDrcGain(rkuvc_aiq_get_ctx(cam_id), (float)value, 0.1, + 16); // Gain: [1, 8] + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:hdr_level", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_blc_strength(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:blc_strength", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_blc_strength(int cam_id, int value) { + int ret; + RK_ISP_CHECK_CAMERA_ID(cam_id); + RK_ISP_CHECK_NORMAL_MODE(cam_id); + Uapi_LinExpAttrV2_t LineExpAttr; + + ret = rk_aiq_user_api2_ae_getLinExpAttr(rkuvc_aiq_get_ctx(cam_id), + &LineExpAttr); + if (ret) + LOG_ERROR("getLinExpAttr error\n"); + if (LineExpAttr.Params.BackLightCtrl.Enable == 0) { + LOG_ERROR("blc mode is not enabled\n"); + return 0; + } + LineExpAttr.Params.BackLightCtrl.StrBias = value; + ret = + rk_aiq_user_api2_ae_setLinExpAttr(rkuvc_aiq_get_ctx(cam_id), LineExpAttr); + if (ret) + LOG_ERROR("setLinExpAttr error\n"); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:blc_strength", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_hlc_level(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:hlc_level", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_hlc_level(int cam_id, int value) { + int ret; + RK_ISP_CHECK_CAMERA_ID(cam_id); + RK_ISP_CHECK_NORMAL_MODE(cam_id); + Uapi_LinExpAttrV2_t LineExpAttr; + + if (value == 0) + value = 1; + ret = rk_aiq_user_api2_ae_getLinExpAttr(rkuvc_aiq_get_ctx(cam_id), + &LineExpAttr); + if (ret) + LOG_ERROR("getLinExpAttr error\n"); + if (LineExpAttr.Params.OverExpCtrl.Enable == 0) { + LOG_ERROR("hlc mode is not enabled\n"); + return 0; + } + LineExpAttr.Params.OverExpCtrl.StrBias = value; + ret = + rk_aiq_user_api2_ae_setLinExpAttr(rkuvc_aiq_get_ctx(cam_id), LineExpAttr); + if (ret) + LOG_ERROR("setLinExpAttr error\n"); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:hlc_level", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_dark_boost_level(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:dark_boost_level", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_dark_boost_level(int cam_id, int value) { + int ret; + RK_ISP_CHECK_CAMERA_ID(cam_id); + LOG_ERROR("ISP3.0 do not support tmo api\n"); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:dark_boost_level", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +// white_blance +int rk_isp_get_white_blance_style(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.white_blance:white_blance_style", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_white_blance_style(int cam_id, const char *value) { + int ret; + RK_ISP_CHECK_CAMERA_ID(cam_id); + rk_aiq_uapiV2_wb_opMode_t attr; + + if (!strcmp(value, "manualWhiteBalance")) { + attr.mode = RK_AIQ_WB_MODE_MANUAL; + } else { + attr.mode = RK_AIQ_WB_MODE_AUTO; + } + ret = rk_aiq_user_api2_awb_SetWpModeAttrib(rkuvc_aiq_get_ctx(cam_id), attr); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.white_blance:white_blance_style", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_white_blance_ct(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.white_blance:white_blance_red", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_white_blance_ct(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret; + rk_aiq_uapiV2_wb_opMode_t mode_attr; + + rk_aiq_user_api2_awb_GetWpModeAttrib(rkuvc_aiq_get_ctx(cam_id), &mode_attr); + if (mode_attr.mode == RK_AIQ_WB_MODE_AUTO) { + LOG_WARN("white blance is auto, not support set color temperature\n"); + return 0; + } + ret = rk_aiq_uapi2_setMWBCT(rkuvc_aiq_get_ctx(cam_id), value); + + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.white_blance:white_blance_ct", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +// enhancement + +int rk_isp_get_noise_reduce_mode(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:noise_reduce_mode", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +// Turn off noise reduction, the actual default value is set to 50, +// and it is done in the interface of setting level +int rk_isp_set_noise_reduce_mode(int cam_id, const char *value) { + int ret; + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:noise_reduce_mode", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_dehaze(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:dehaze", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_dehaze(int cam_id, const char *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret; + char entry[128] = {'\0'}; + // adehaze_sw_V2_t attr; + // memset(&attr, 0, sizeof(attr)); + // attr.sync.sync_mode = RK_AIQ_UAPI_MODE_DEFAULT; + // if (!strcmp(value, "close")) { + // attr.mode = DEHAZE_API_BYPASS; + // } else if (!strcmp(value, "open")) { + // attr.mode = DEHAZE_API_MANUAL; + // } else if (!strcmp(value, "auto")) { + // attr.mode = DEHAZE_API_DEHAZE_AUTO; + // } + // ret = rk_aiq_user_api2_adehaze_setSwAttrib(rkuvc_aiq_get_ctx(cam_id), + // attr); + snprintf(entry, 127, "isp.%d.enhancement:dehaze", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_gray_scale_mode(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:gray_scale_mode", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_gray_scale_mode(int cam_id, const char *value) { + int ret; + char entry[128] = {'\0'}; + RK_ISP_CHECK_CAMERA_ID(cam_id); + rk_aiq_uapi_acsm_attrib_t attr; + rk_aiq_user_api2_acsm_GetAttrib(rkuvc_aiq_get_ctx(cam_id), &attr); + if (!strcmp(value, "[16-235]")) + attr.param.full_range = false; + else + attr.param.full_range = true; + rk_aiq_user_api2_acsm_SetAttrib(rkuvc_aiq_get_ctx(cam_id), &attr); + snprintf(entry, 127, "isp.%d.enhancement:gray_scale_mode", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_distortion_correction(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:distortion_correction", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_distortion_correction(int cam_id, const char *value) { + int ret; + RK_ISP_CHECK_CAMERA_ID(cam_id); + rk_aiq_ldch_attrib_t ldchAttr; + ret = rk_aiq_user_api2_aldch_GetAttrib(rkuvc_aiq_get_ctx(cam_id), &ldchAttr); + if (!strcmp(value, "close")) + ldchAttr.en = false; + else + ldchAttr.en = true; + ret = rk_aiq_user_api2_aldch_SetAttrib(rkuvc_aiq_get_ctx(cam_id), &ldchAttr); + + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:distortion_correction", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_spatial_denoise_level(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:spatial_denoise_level", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_spatial_denoise_level(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret = 0; + const char *noise_reduce_mode; + rk_aiq_ynr_strength_v3_t ynrStrenght; + rk_aiq_bayer2dnr_strength_v2_t bayer2dnrV2Strenght; + + rk_isp_get_noise_reduce_mode(cam_id, &noise_reduce_mode); + LOG_DEBUG("noise_reduce_mode is %s, value is %d\n", noise_reduce_mode, value); + if ((!strcmp(noise_reduce_mode, "close")) || + (!strcmp(noise_reduce_mode, "3dnr"))) { + value = 50; + LOG_DEBUG("noise_reduce_mode is %s, value is %d\n", noise_reduce_mode, + value); + } + ynrStrenght.sync.sync_mode = RK_AIQ_UAPI_MODE_SYNC; + ynrStrenght.percent = value / 100.0; + ret = rk_aiq_user_api2_aynrV3_SetStrength(rkuvc_aiq_get_ctx(cam_id), + &ynrStrenght); + bayer2dnrV2Strenght.sync.sync_mode = RK_AIQ_UAPI_MODE_SYNC; + bayer2dnrV2Strenght.percent = value / 100.0; + ret = rk_aiq_user_api2_abayer2dnrV2_SetStrength(rkuvc_aiq_get_ctx(cam_id), + &bayer2dnrV2Strenght); + + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:spatial_denoise_level", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_temporal_denoise_level(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:temporal_denoise_level", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_temporal_denoise_level(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret = 0; + const char *noise_reduce_mode; + rk_aiq_bayertnr_strength_v2_t bayertnrV2Strenght; + + rk_isp_get_noise_reduce_mode(cam_id, &noise_reduce_mode); + LOG_DEBUG("noise_reduce_mode is %s, value is %d\n", noise_reduce_mode, value); + if ((!strcmp(noise_reduce_mode, "close")) || + (!strcmp(noise_reduce_mode, "2dnr"))) { + value = 50; + LOG_DEBUG("noise_reduce_mode is %s, value is %d\n", noise_reduce_mode, + value); + } + bayertnrV2Strenght.sync.sync_mode = RK_AIQ_UAPI_MODE_SYNC; + bayertnrV2Strenght.percent = value / 100.0; + ret = rk_aiq_user_api2_abayertnrV2_SetStrength(rkuvc_aiq_get_ctx(cam_id), + &bayertnrV2Strenght); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:temporal_denoise_level", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_dehaze_level(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:dehaze_level", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_dehaze_level(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret; + // adehaze_sw_V2_t attr; + + // attr.sync.sync_mode = RK_AIQ_UAPI_MODE_DEFAULT; + // attr.sync.done = false; + // attr.mode = DEHAZE_API_DEHAZE_MANUAL; + // attr.stDehazeManu.level = value; + // int ret = rk_aiq_user_api2_adehaze_setSwAttrib(rkuvc_aiq_get_ctx(cam_id), + // attr); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:dehaze_level", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +int rk_isp_get_fec_level(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:fec_level", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_fec_level(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + // int ret = rk_aiq_uapi2_setFecCorrectLevel(g_aiq_ctx[cam_id], + // (int)(value * 2.55)); // [0-100] + // -> [0->255] + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:fec_level", cam_id); + rk_param_set_int(entry, value); + + return 0; +} + +int rk_isp_get_ldch_level(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:ldch_level", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_set_ldch_level(int cam_id, int value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret = 0; + rk_aiq_ldch_attrib_t ldchAttr; + + value = value < 0 ? 0 : value; + ret = rk_aiq_user_api2_aldch_GetAttrib(rkuvc_aiq_get_ctx(cam_id), &ldchAttr); + ldchAttr.correct_level = (int)(value * 2.53 + 2); // [0, 100] -> [2 , 255] + ret = rk_aiq_user_api2_aldch_SetAttrib(rkuvc_aiq_get_ctx(cam_id), &ldchAttr); + + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.enhancement:ldch_level", cam_id); + rk_param_set_int(entry, value); + + return ret; +} + +// video_adjustment +int rk_isp_get_power_line_frequency_mode(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.video_adjustment:power_line_frequency_mode", + cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_power_line_frequency_mode(int cam_id, const char *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret; + char entry[128] = {'\0'}; + Uapi_ExpSwAttrV2_t expSwAttr; + + ret = rk_aiq_user_api2_ae_getExpSwAttr(rkuvc_aiq_get_ctx(cam_id), &expSwAttr); + if (!strcmp(value, "NTSC(60HZ)")) { + expSwAttr.stAuto.stAntiFlicker.enable = true; + expSwAttr.stAuto.stAntiFlicker.Frequency = AECV2_FLICKER_FREQUENCY_60HZ; + } else { + expSwAttr.stAuto.stAntiFlicker.enable = true; + expSwAttr.stAuto.stAntiFlicker.Frequency = AECV2_FLICKER_FREQUENCY_50HZ; + } + ret = rk_aiq_user_api2_ae_setExpSwAttr(rkuvc_aiq_get_ctx(cam_id), expSwAttr); + snprintf(entry, 127, "isp.%d.video_adjustment:power_line_frequency_mode", + cam_id); + //rk_param_set_string(entry, value); + + return ret; +} + +int rk_isp_get_image_flip(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.video_adjustment:image_flip", cam_id); + *value = rk_param_get_string(entry, NULL); + + return 0; +} + +int rk_isp_set_image_flip(int cam_id, const char *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret, mirror, flip; + char entry[128] = {'\0'}; + if (!strcmp(value, "close")) { + mirror = 0; + flip = 0; + } + if (!strcmp(value, "flip")) { + mirror = 0; + flip = 1; + } + if (!strcmp(value, "mirror")) { + mirror = 1; + flip = 0; + } + if (!strcmp(value, "centrosymmetric")) { + mirror = 1; + flip = 1; + } + rk_aiq_uapi2_setMirrorFlip(rkuvc_aiq_get_ctx(cam_id), mirror, flip, 4); // + // skip 4 frame + snprintf(entry, 127, "isp.%d.video_adjustment:image_flip", cam_id); + rk_param_set_string(entry, value); + + return ret; +} + +// auto focus + +int rk_isp_get_af_mode(int cam_id, const char **value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.auto_focus:af_mode", cam_id); + *value = rk_param_get_string(entry, "auto"); + + return 0; +} + +int rk_isp_set_af_mode(int cam_id, const char *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret = 0; + char entry[128] = {'\0'}; + opMode_t af_mode = OP_AUTO; + if (value == NULL) + return -1; + if (!strcmp(value, "auto")) { + af_mode = OP_AUTO; + } else if (!strcmp(value, "semi-auto")) { + af_mode = OP_SEMI_AUTO; + } else if (!strcmp(value, "manual")) { + af_mode = OP_MANUAL; + } else { + return -1; + } + ret = rk_aiq_uapi2_setFocusMode(rkuvc_aiq_get_ctx(cam_id), af_mode); + LOG_INFO("set af mode: %s, ret: %d\n", value, ret); + snprintf(entry, 127, "isp.%d.auto_focus:af_mode", cam_id); + rk_param_set_string(entry, value); + + return 0; +} + +int rk_isp_get_zoom_level(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.auto_focus:zoom_level", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_get_focus_level(int cam_id, int *value) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.auto_focus:focus_level", cam_id); + *value = rk_param_get_int(entry, -1); + + return 0; +} + +int rk_isp_af_zoom_change(int cam_id, int change) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret = 0; + int code = 0; + char entry[128] = {'\0'}; + + rk_aiq_af_zoomrange af_zoom_range = {0}; + ret = rk_aiq_uapi2_getZoomRange(rkuvc_aiq_get_ctx(cam_id), &af_zoom_range); + if (ret) { + LOG_ERROR("get zoom range fail: %d\n", ret); + return ret; + } + rk_aiq_uapi2_getOpZoomPosition(rkuvc_aiq_get_ctx(cam_id), &code); + code += change; + if ((code < af_zoom_range.min_pos) || (code > af_zoom_range.max_pos)) { + LOG_ERROR("set zoom: %d over range [%d, %d]\n", code, af_zoom_range.min_pos, + af_zoom_range.max_pos); + ret = -1; + } + ret = rk_aiq_uapi2_setOpZoomPosition(rkuvc_aiq_get_ctx(cam_id), code); + LOG_INFO("set zoom: %d, ret: %d\n", code, ret); + snprintf(entry, 127, "isp.%d.auto_focus:zoom_level", cam_id); + rk_param_set_int(entry, code); + + return ret; +} + +int rk_isp_af_focus_change(int cam_id, int change) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret = 0; + short code = 0; + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.auto_focus:af_mode", cam_id); + const char *af_mode = rk_param_get_string(entry, "auto"); + if (!strcmp(af_mode, "auto")) + return 0; + + rk_aiq_af_focusrange af_focus_range = {0}; + ret = rk_aiq_uapi2_getFocusRange(rkuvc_aiq_get_ctx(cam_id), &af_focus_range); + if (ret) { + LOG_ERROR("get focus range fail: %d\n", ret); + return ret; + } + rk_aiq_uapi2_getFocusPosition(rkuvc_aiq_get_ctx(cam_id), &code); + code += change; + if ((code < af_focus_range.min_pos) || (code > af_focus_range.max_pos)) { + LOG_ERROR("before set getFocusPosition: %d over range (%d, %d)\n", code, + af_focus_range.min_pos, af_focus_range.max_pos); + return -1; + } + ret = rk_aiq_uapi2_setFocusPosition(rkuvc_aiq_get_ctx(cam_id), code); + LOG_INFO("set setFocusPosition: %d, ret: %d\n", code, ret); + snprintf(entry, 127, "isp.%d.auto_focus:focus_level", cam_id); + rk_param_set_int(entry, code); + + return ret; +} + +int rk_isp_af_zoom_in(int cam_id) { return rk_isp_af_zoom_change(cam_id, 20); } + +int rk_isp_af_zoom_out(int cam_id) { + return rk_isp_af_zoom_change(cam_id, -20); +} + +int rk_isp_af_focus_in(int cam_id) { return rk_isp_af_focus_change(cam_id, 1); } + +int rk_isp_af_focus_out(int cam_id) { + return rk_isp_af_focus_change(cam_id, -1); +} + +int rk_isp_af_focus_once(int cam_id) { + LOG_INFO("af_focus_once\n"); + return rk_aiq_uapi2_endOpZoomChange(rkuvc_aiq_get_ctx(cam_id)); +} + +int rk_isp_set_from_ini(int cam_id) { + RK_ISP_CHECK_CAMERA_ID(cam_id); + int ret = 0; + LOG_INFO("start\n"); + rk_isp_set_frame_rate(cam_id, rk_param_get_int("isp.0.adjustment:fps", 30)); + // rk_isp_set_contrast(cam_id, rk_param_get_int("isp.0.adjustment:contrast", + // 50)); + // rk_isp_set_brightness(cam_id, + // rk_param_get_int("isp.0.adjustment:brightness", 50)); + // rk_isp_set_saturation(cam_id, + // rk_param_get_int("isp.0.adjustment:saturation", 50)); + // rk_isp_set_sharpness(cam_id, rk_param_get_int("isp.0.adjustment:sharpness", + // 50)); + // rk_isp_set_hue(cam_id, rk_param_get_int("isp.0.adjustment:hue", 50)); + LOG_INFO("end\n"); + + return ret; +} + +int rk_isp_init(int cam_id, char *iqfile_path) { + LOG_INFO("cam_id is %d\n", cam_id); + int ret; + rkuvc_aiq_use_group = 0; + if (iqfile_path) + memcpy(g_iq_file_dir_, iqfile_path, strlen(iqfile_path)); + else + memcpy(g_iq_file_dir_, "/etc/iqfiles", strlen("/etc/iqfiles")); + LOG_INFO("g_iq_file_dir_ is %s\n", g_iq_file_dir_); + + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:hdr", cam_id); + const char *hdr_mode = rk_param_get_string(entry, "close"); + LOG_INFO("cam_id is %d, hdr_mode is %s\n", cam_id, hdr_mode); + if (!strcmp(hdr_mode, "HDR2")) { + ret = sample_common_isp_init(cam_id, RK_AIQ_WORKING_MODE_ISP_HDR2, true, + g_iq_file_dir_); + // rk_aiq_uapi2_sysctl_switch_scene(g_aiq_ctx[cam_id], "hdr" , "day"); + } else { + ret = sample_common_isp_init(cam_id, RK_AIQ_WORKING_MODE_NORMAL, true, + g_iq_file_dir_); + // rk_aiq_uapi2_sysctl_switch_scene(g_aiq_ctx[cam_id], "normal" , "day"); + } + + ret |= sample_common_isp_run(cam_id); + ret |= rk_isp_set_from_ini(cam_id); + + return ret; +} + +int rk_isp_deinit(int cam_id) { + LOG_INFO("cam_id is %d\n", cam_id); + RK_ISP_CHECK_CAMERA_ID(cam_id); + LOG_INFO("rk_aiq_uapi2_sysctl_stop enter\n"); + rk_aiq_uapi2_sysctl_stop(g_aiq_ctx[cam_id], false); + LOG_INFO("rk_aiq_uapi2_sysctl_deinit enter\n"); + rk_aiq_uapi2_sysctl_deinit(g_aiq_ctx[cam_id]); + LOG_INFO("rk_aiq_uapi2_sysctl_deinit exit\n"); + g_aiq_ctx[cam_id] = NULL; + + return 0; +} + +int rk_isp_group_init(int cam_group_id, char *iqfile_path) { + LOG_INFO("cam_group_id is %d\n", cam_group_id); + int ret; + rkuvc_aiq_use_group = 1; + if (iqfile_path) + memcpy(g_iq_file_dir_, iqfile_path, strlen(iqfile_path)); + else + memcpy(g_iq_file_dir_, "/etc/iqfiles", strlen("/etc/iqfiles")); + LOG_INFO("g_iq_file_dir_ is %s\n", g_iq_file_dir_); + + char entry[128] = {'\0'}; + snprintf(entry, 127, "isp.%d.blc:hdr", cam_group_id); + const char *hdr_mode = rk_param_get_string(entry, "close"); + LOG_INFO("cam_group_id is %d, hdr_mode is %s\n", cam_group_id, hdr_mode); + if (!strcmp(hdr_mode, "HDR2")) { + ret = isp_camera_group_init(cam_group_id, RK_AIQ_WORKING_MODE_ISP_HDR2, + false, g_iq_file_dir_); + } else { + ret = isp_camera_group_init(cam_group_id, RK_AIQ_WORKING_MODE_NORMAL, false, + g_iq_file_dir_); + } + ret |= rk_isp_set_from_ini(cam_group_id); + + return ret; +} + +int rk_isp_group_deinit(int cam_group_id) { + LOG_INFO("cam_group_id is %d\n", cam_group_id); + return isp_camera_group_stop(cam_group_id); +} diff --git a/project/app/uvc_app_tiny/uvc_app/isp/isp.h b/project/app/uvc_app_tiny/uvc_app/isp/isp.h new file mode 100644 index 000000000..368d412a3 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/isp/isp.h @@ -0,0 +1,79 @@ +int rk_isp_init(int cam_id, char *iqfile_path); +int rk_isp_deinit(int cam_id); +int rk_isp_group_init(int cam_group_id, char *iqfile_path); +int rk_isp_group_deinit(int cam_group_id); +int rk_isp_set_frame_rate(int cam_id, int value); +// image adjustment +int rk_isp_get_contrast(int cam_id, int *value); +int rk_isp_set_contrast(int cam_id, int value); +int rk_isp_get_brightness(int cam_id, int *value); +int rk_isp_set_brightness(int cam_id, int value); +int rk_isp_get_saturation(int cam_id, int *value); +int rk_isp_set_saturation(int cam_id, int value); +int rk_isp_get_sharpness(int cam_id, int *value); +int rk_isp_set_sharpness(int cam_id, int value); +int rk_isp_get_hue(int cam_id, int *value); +int rk_isp_set_hue(int cam_id, int value); +int rk_isp_get_hue_mode(int cam_id, int *value); +int rk_isp_set_hue_mode(int cam_id, int value); +// exposure +int rk_isp_get_exposure_mode(int cam_id, const char **value); +int rk_isp_set_exposure_mode(int cam_id, const char *value); +int rk_isp_get_gain_mode(int cam_id, const char **value); +int rk_isp_set_gain_mode(int cam_id, const char *value); +int rk_isp_get_exposure_time(int cam_id, const char **value); +int rk_isp_set_exposure_time(int cam_id, const char *value); +int rk_isp_get_exposure_gain(int cam_id, int *value); +int rk_isp_set_exposure_gain(int cam_id, int value); +// blc +int rk_isp_get_hdr(int cam_id, const char **value); +int rk_isp_set_hdr(int cam_id, const char *value); +int rk_isp_get_blc_region(int cam_id, const char **value); +int rk_isp_set_blc_region(int cam_id, const char *value); +int rk_isp_get_hlc(int cam_id, const char **value); +int rk_isp_set_hlc(int cam_id, const char *value); +int rk_isp_get_hdr_level(int cam_id, int *value); +int rk_isp_set_hdr_level(int cam_id, int value); +int rk_isp_get_blc_strength(int cam_id, int *value); +int rk_isp_set_blc_strength(int cam_id, int value); +int rk_isp_get_hlc_level(int cam_id, int *value); +int rk_isp_set_hlc_level(int cam_id, int value); +int rk_isp_get_dark_boost_level(int cam_id, int *value); +int rk_isp_set_dark_boost_level(int cam_id, int value); +// white_blance +int rk_isp_get_white_blance_style(int cam_id, const char **value); +int rk_isp_set_white_blance_style(int cam_id, const char *value); +int rk_isp_get_white_blance_ct(int cam_id, int *value); +int rk_isp_set_white_blance_ct(int cam_id, int value); +// enhancement +int rk_isp_get_noise_reduce_mode(int cam_id, const char **value); +int rk_isp_set_noise_reduce_mode(int cam_id, const char *value); +int rk_isp_get_dehaze(int cam_id, const char **value); +int rk_isp_set_dehaze(int cam_id, const char *value); +int rk_isp_get_gray_scale_mode(int cam_id, const char **value); +// int rk_isp_set_gray_scale_mode(int cam_id, const char *value); +int rk_isp_get_distortion_correction(int cam_id, const char **value); +int rk_isp_set_distortion_correction(int cam_id, const char *value); +int rk_isp_get_spatial_denoise_level(int cam_id, int *value); +int rk_isp_set_spatial_denoise_level(int cam_id, int value); +int rk_isp_get_temporal_denoise_level(int cam_id, int *value); +int rk_isp_set_temporal_denoise_level(int cam_id, int value); +int rk_isp_get_dehaze_level(int cam_id, int *value); +int rk_isp_set_dehaze_level(int cam_id, int value); +int rk_isp_get_ldch_level(int cam_id, int *value); +int rk_isp_set_ldch_level(int cam_id, int value); +// video_adjustment +int rk_isp_get_power_line_frequency_mode(int cam_id, const char **value); +int rk_isp_set_power_line_frequency_mode(int cam_id, const char *value); +int rk_isp_get_image_flip(int cam_id, const char **value); +int rk_isp_set_image_flip(int cam_id, const char *value); +// auto focus +int rk_isp_get_af_mode(int cam_id, const char **value); +int rk_isp_set_af_mode(int cam_id, const char *value); +int rk_isp_get_zoom_level(int cam_id, int *value); +int rk_isp_get_focus_level(int cam_id, int *value); +int rk_isp_af_zoom_in(int cam_id); +int rk_isp_af_zoom_out(int cam_id); +int rk_isp_af_focus_in(int cam_id); +int rk_isp_af_focus_out(int cam_id); +int rk_isp_af_focus_once(int cam_id); diff --git a/project/app/uvc_app_tiny/uvc_app/main.c b/project/app/uvc_app_tiny/uvc_app/main.c new file mode 100755 index 000000000..d0ea7d561 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/main.c @@ -0,0 +1,189 @@ +#include "camera_control.h" +#include "isp.h" +#include "param.h" +#include "rk_mpi_sys.h" +#include "uevent.h" +#include "uevent.h" +#include "uvc_control.h" +#include "uvc_log.h" +#include "uvc_video.h" +#include +#include +#include +#include + +#ifdef COMPILE_FOR_UVC_UAC +#include "uac_control.h" +#include "uac_log.h" +#include "uac_uevent.h" +#include +#include +#endif + +#define LOG_TAG "rk_mpi_uvc" +#define UVC_VERSION "SDK V2.01" +enum { LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG }; +int rkuvc_log_level = LOG_DEBUG; +char *rkuvc_ini_path_ = NULL; +char *rkuvc_iq_file_path_ = NULL; +// int enable_minilog = 0; +// int rk_mpi_uvc_log_level = LOG_LEVEL_INFO; +// int app_quit; + +static const char short_options[] = "c:a:l:"; +static const struct option long_options[] = { + {"config", required_argument, NULL, 'c'}, + {"aiq_file", no_argument, NULL, 'a'}, + {"log_level", no_argument, NULL, 'l'}, + {"help", no_argument, NULL, 'h'}, + {0, 0, 0, 0}}; + +static void usage_tip(FILE *fp, int argc, char **argv) { + fprintf(fp, "Usage: %s [options]\n" + "Version %s\n" + "Options:\n" + "-c | --config rkuvc ini file, default is " + "/userdata/rkuvc.ini, need to be writable\n" + "-a | --aiq_file aiq file dir path, default is /etc/iqfiles\n" + "-l | --log_level log_level [0/1/2/3], default is 2\n" + "-h | --help for help \n\n" + "\n", + argv[0], "V1.0"); +} + +#ifdef COMPILE_FOR_UVC_UAC + +void *uac_app_thread(void *arg) { + prctl(PR_SET_NAME, "uac_pthread", 0, 0, 0); + + LOG_INFO("uac uevent version = 1.0\n"); + // create uac control + char *ch; + int type = 0; // UAC_API_MPI; + // rkuac_get_opt(argc, argv); + + int result = uac_control_create(type); + if (result < 0) { + LOG_ERROR("uac_control_create fail\n"); + goto err_monitor; + } + + // register uevent monitor + uac_uevent_monitor_run(); + + while (1) { + usleep(100000); + } + +err_monitor: + pthread_detach(pthread_self()); + pthread_exit(NULL); +} +int uac_app_run() { + pthread_t tid; + + return pthread_create(&tid, NULL, uac_app_thread, NULL); +} +#endif + +void rkuvc_get_opt(int argc, char *argv[]) { + for (;;) { + int idx; + int c; + c = getopt_long(argc, argv, short_options, long_options, &idx); + if (-1 == c) + break; + switch (c) { + case 0: /* getopt_long() flag */ + break; + case 'c': + rkuvc_ini_path_ = optarg; + break; + case 'a': + rkuvc_iq_file_path_ = optarg; + break; + case 'l': + rkuvc_log_level = atoi(optarg); + break; + case 'h': + usage_tip(stdout, argc, argv); + exit(EXIT_SUCCESS); + default: + usage_tip(stderr, argc, argv); + exit(EXIT_FAILURE); + } + } +} +void sigterm_handler(int sig) { + LOG_INFO("signal %d\n", sig); + app_quit = sig; +} + +int main(int argc, char *argv[]) { + int fd; + int ret; + unsigned int handle; + char *buffer; + int handle_fd; + size_t size; + int i = 0; + int width, height; + int y, uv; + int extra_cnt = 0; + uint32_t flags = 0; + int media_set = 0; + RK_S32 s32Ret = RK_FAILURE; + rk_mpi_uvc_log_level = LOG_LEVEL_INFO; + app_quit = 0; + signal(SIGQUIT, sigterm_handler); + signal(SIGTERM, sigterm_handler); + char *log_level = getenv("rk_mpi_uvc_log_level"); + if (log_level) { + LOG_INFO("rk_mpi_uvc_log_level=%d", atoi(log_level)); + rk_mpi_uvc_log_level = atoi(log_level); + } + LOG_INFO("VERSION:%s %s %s \n", UVC_VERSION, __DATE__, __TIME__); + rkuvc_get_opt(argc, argv); + LOG_INFO("rkuvc_ini_path_ is %s, rkuvc_iq_file_path_ is %s, rkuvc_log_level " + "is %d\n", + rkuvc_ini_path_, rkuvc_iq_file_path_, rkuvc_log_level); + rk_param_init(rkuvc_ini_path_); + camera_control_init(); + s32Ret = RK_MPI_SYS_Init(); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_SYS_Init %x\n", s32Ret); + return -1; + } + uvc_control_start_setcallback(camera_control_start); + uvc_control_stop_setcallback(camera_control_stop); + uevent_monitor_run(UVC_CONTROL_CAMERA); + uvc_control_run(UVC_CONTROL_CAMERA); + +#ifdef COMPILE_FOR_UVC_UAC + uac_app_log_level = LOG_DEBUG; + char *uac_log_level = getenv("uac_app_log_level"); + if (uac_log_level) { + uac_app_log_level = atoi(uac_log_level); + } + if (rk_param_get_int("video.source:enable_uac", 0)) + uac_app_run(); +#endif + + while (1) { + if (0 == uvc_control_loop()) + break; + usleep(100000); + } + uvc_video_id_exit_all(); + camera_control_deinit(); +#ifdef COMPILE_FOR_UVC_UAC + if (rk_param_get_int("video.source:enable_uac", 0)) { + LOG_INFO("uac control destory...\n"); + uac_control_destory(); + } +#endif + RK_MPI_SYS_Exit(); + rk_param_deinit(); + LOG_INFO("uvc_app exit.\n"); + return 0; +} diff --git a/project/app/uvc_app_tiny/uvc_app/param/dictionary.c b/project/app/uvc_app_tiny/uvc_app/param/dictionary.c new file mode 100644 index 000000000..faa57373d --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/param/dictionary.c @@ -0,0 +1,375 @@ +/*-------------------------------------------------------------------------*/ +/** + @file dictionary.c + @author N. Devillard + @brief Implements a dictionary for string variables. + + This module implements a simple dictionary object, i.e. a list + of string/string associations. This object is useful to store e.g. + informations retrieved from a configuration file (ini files). +*/ +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ +#include "dictionary.h" + +#include +#include +#include +#include + +/** Maximum value size for integers and doubles. */ +#define MAXVALSZ 1024 + +/** Minimal allocated number of entries in a dictionary */ +#define DICTMINSZ 128 + +/** Invalid key token */ +#define DICT_INVALID_KEY ((char *)-1) + +/*--------------------------------------------------------------------------- + Private functions + ---------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ +/** + @brief Duplicate a string + @param s String to duplicate + @return Pointer to a newly allocated string, to be freed with free() + + This is a replacement for strdup(). This implementation is provided + for systems that do not have it. + */ +/*--------------------------------------------------------------------------*/ +static char *xstrdup(const char *s) { + char *t; + size_t len; + if (!s) + return NULL; + + len = strlen(s) + 1; + t = (char *)malloc(len); + if (t) { + memcpy(t, s, len); + } + return t; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Double the size of the dictionary + @param d Dictionary to grow + @return This function returns non-zero in case of failure + */ +/*--------------------------------------------------------------------------*/ +static int dictionary_grow(dictionary *d) { + char **new_val; + char **new_key; + unsigned *new_hash; + + new_val = (char **)calloc(d->size * 2, sizeof *d->val); + new_key = (char **)calloc(d->size * 2, sizeof *d->key); + new_hash = (unsigned *)calloc(d->size * 2, sizeof *d->hash); + if (!new_val || !new_key || !new_hash) { + /* An allocation failed, leave the dictionary unchanged */ + if (new_val) + free(new_val); + if (new_key) + free(new_key); + if (new_hash) + free(new_hash); + return -1; + } + /* Initialize the newly allocated space */ + memcpy(new_val, d->val, d->size * sizeof(char *)); + memcpy(new_key, d->key, d->size * sizeof(char *)); + memcpy(new_hash, d->hash, d->size * sizeof(unsigned)); + /* Delete previous data */ + free(d->val); + free(d->key); + free(d->hash); + /* Actually update the dictionary */ + d->size *= 2; + d->val = new_val; + d->key = new_key; + d->hash = new_hash; + return 0; +} + +/*--------------------------------------------------------------------------- + Function codes + ---------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------*/ +/** + @brief Compute the hash key for a string. + @param key Character string to use for key. + @return 1 unsigned int on at least 32 bits. + + This hash function has been taken from an Article in Dr Dobbs Journal. + This is normally a collision-free function, distributing keys evenly. + The key is stored anyway in the struct so that collision can be avoided + by comparing the key itself in last resort. + */ +/*--------------------------------------------------------------------------*/ +unsigned dictionary_hash(const char *key) { + size_t len; + unsigned hash; + size_t i; + + if (!key) + return 0; + + len = strlen(key); + for (hash = 0, i = 0; i < len; i++) { + hash += (unsigned)key[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Create a new dictionary object. + @param size Optional initial size of the dictionary. + @return 1 newly allocated dictionary object. + + This function allocates a new dictionary object of given size and returns + it. If you do not know in advance (roughly) the number of entries in the + dictionary, give size=0. + */ +/*-------------------------------------------------------------------------*/ +dictionary *dictionary_new(size_t size) { + dictionary *d; + + /* If no size was specified, allocate space for DICTMINSZ */ + if (size < DICTMINSZ) + size = DICTMINSZ; + + d = (dictionary *)calloc(1, sizeof *d); + + if (d) { + d->size = size; + d->val = (char **)calloc(size, sizeof *d->val); + d->key = (char **)calloc(size, sizeof *d->key); + d->hash = (unsigned *)calloc(size, sizeof *d->hash); + } + return d; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a dictionary object + @param d dictionary object to deallocate. + @return void + + Deallocate a dictionary object and all memory associated to it. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_del(dictionary *d) { + ssize_t i; + + if (d == NULL) + return; + for (i = 0; i < d->size; i++) { + if (d->key[i] != NULL) + free(d->key[i]); + if (d->val[i] != NULL) + free(d->val[i]); + } + free(d->val); + free(d->key); + free(d->hash); + free(d); + return; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get a value from a dictionary. + @param d dictionary object to search. + @param key Key to look for in the dictionary. + @param def Default value to return if key not found. + @return 1 pointer to internally allocated character string. + + This function locates a key in a dictionary and returns a pointer to its + value, or the passed 'def' pointer if no such key can be found in + dictionary. The returned character pointer points to data internal to the + dictionary object, you should not try to free it or modify it. + */ +/*--------------------------------------------------------------------------*/ +const char *dictionary_get(const dictionary *d, const char *key, + const char *def) { + unsigned hash; + ssize_t i; + + hash = dictionary_hash(key); + for (i = 0; i < d->size; i++) { + if (d->key[i] == NULL) + continue; + /* Compare hash */ + if (hash == d->hash[i]) { + /* Compare string, to avoid hash collisions */ + if (!strcmp(key, d->key[i])) { + return d->val[i]; + } + } + } + return def; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Set a value in a dictionary. + @param d dictionary object to modify. + @param key Key to modify or add. + @param val Value to add. + @return int 0 if Ok, anything else otherwise + + If the given key is found in the dictionary, the associated value is + replaced by the provided one. If the key cannot be found in the + dictionary, it is added to it. + + It is Ok to provide a NULL value for val, but NULL values for the dictionary + or the key are considered as errors: the function will return immediately + in such a case. + + Notice that if you dictionary_set a variable to NULL, a call to + dictionary_get will return a NULL value: the variable will be found, and + its value (NULL) is returned. In other words, setting the variable + content to NULL is equivalent to deleting the variable from the + dictionary. It is not possible (in this implementation) to have a key in + the dictionary without value. + + This function returns non-zero in case of failure. + */ +/*--------------------------------------------------------------------------*/ +int dictionary_set(dictionary *d, const char *key, const char *val) { + ssize_t i; + unsigned hash; + + if (d == NULL || key == NULL) + return -1; + + /* Compute hash for this key */ + hash = dictionary_hash(key); + /* Find if value is already in dictionary */ + if (d->n > 0) { + for (i = 0; i < d->size; i++) { + if (d->key[i] == NULL) + continue; + if (hash == d->hash[i]) { /* Same hash value */ + if (!strcmp(key, d->key[i])) { /* Same key */ + /* Found a value: modify and return */ + if (d->val[i] != NULL) + free(d->val[i]); + d->val[i] = (val ? xstrdup(val) : NULL); + /* Value has been modified: return */ + return 0; + } + } + } + } + /* Add a new value */ + /* See if dictionary needs to grow */ + if (d->n == d->size) { + /* Reached maximum size: reallocate dictionary */ + if (dictionary_grow(d) != 0) + return -1; + } + + /* Insert key in the first empty slot. Start at d->n and wrap at + d->size. Because d->n < d->size this will necessarily + terminate. */ + for (i = d->n; d->key[i];) { + if (++i == d->size) + i = 0; + } + /* Copy key */ + d->key[i] = xstrdup(key); + d->val[i] = (val ? xstrdup(val) : NULL); + d->hash[i] = hash; + d->n++; + return 0; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a key in a dictionary + @param d dictionary object to modify. + @param key Key to remove. + @return void + + This function deletes a key in a dictionary. Nothing is done if the + key cannot be found. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_unset(dictionary *d, const char *key) { + unsigned hash; + ssize_t i; + + if (key == NULL || d == NULL) { + return; + } + + hash = dictionary_hash(key); + for (i = 0; i < d->size; i++) { + if (d->key[i] == NULL) + continue; + /* Compare hash */ + if (hash == d->hash[i]) { + /* Compare string, to avoid hash collisions */ + if (!strcmp(key, d->key[i])) { + /* Found key */ + break; + } + } + } + if (i >= d->size) + /* Key not found */ + return; + + free(d->key[i]); + d->key[i] = NULL; + if (d->val[i] != NULL) { + free(d->val[i]); + d->val[i] = NULL; + } + d->hash[i] = 0; + d->n--; + return; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump + @param f Opened file pointer. + @return void + + Dumps a dictionary onto an opened file pointer. Key pairs are printed out + as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as + output file pointers. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_dump(const dictionary *d, FILE *out) { + ssize_t i; + + if (d == NULL || out == NULL) + return; + if (d->n < 1) { + fprintf(out, "empty dictionary\n"); + return; + } + for (i = 0; i < d->size; i++) { + if (d->key[i]) { + fprintf(out, "%20s\t[%s]\n", d->key[i], d->val[i] ? d->val[i] : "UNDEF"); + } + } + return; +} diff --git a/project/app/uvc_app_tiny/uvc_app/param/dictionary.h b/project/app/uvc_app_tiny/uvc_app/param/dictionary.h new file mode 100644 index 000000000..d8dd45733 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/param/dictionary.h @@ -0,0 +1,170 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file dictionary.h + @author N. Devillard + @brief Implements a dictionary for string variables. + + This module implements a simple dictionary object, i.e. a list + of string/string associations. This object is useful to store e.g. + informations retrieved from a configuration file (ini files). +*/ +/*--------------------------------------------------------------------------*/ + +#ifndef _DICTIONARY_H_ +#define _DICTIONARY_H_ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + New types + ---------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ +/** + @brief Dictionary object + + This object contains a list of string/string associations. Each + association is identified by a unique string key. Looking up values + in the dictionary is speeded up by the use of a (hopefully collision-free) + hash function. + */ +/*-------------------------------------------------------------------------*/ +typedef struct _dictionary_ { + int n; /** Number of entries in dictionary */ + ssize_t size; /** Storage size */ + char **val; /** List of string values */ + char **key; /** List of string keys */ + unsigned *hash; /** List of hash values for keys */ +} dictionary; + +/*--------------------------------------------------------------------------- + Function prototypes + ---------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ +/** + @brief Compute the hash key for a string. + @param key Character string to use for key. + @return 1 unsigned int on at least 32 bits. + + This hash function has been taken from an Article in Dr Dobbs Journal. + This is normally a collision-free function, distributing keys evenly. + The key is stored anyway in the struct so that collision can be avoided + by comparing the key itself in last resort. + */ +/*--------------------------------------------------------------------------*/ +unsigned dictionary_hash(const char *key); + +/*-------------------------------------------------------------------------*/ +/** + @brief Create a new dictionary object. + @param size Optional initial size of the dictionary. + @return 1 newly allocated dictionary object. + + This function allocates a new dictionary object of given size and returns + it. If you do not know in advance (roughly) the number of entries in the + dictionary, give size=0. + */ +/*--------------------------------------------------------------------------*/ +dictionary *dictionary_new(size_t size); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a dictionary object + @param d dictionary object to deallocate. + @return void + + Deallocate a dictionary object and all memory associated to it. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_del(dictionary *vd); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get a value from a dictionary. + @param d dictionary object to search. + @param key Key to look for in the dictionary. + @param def Default value to return if key not found. + @return 1 pointer to internally allocated character string. + + This function locates a key in a dictionary and returns a pointer to its + value, or the passed 'def' pointer if no such key can be found in + dictionary. The returned character pointer points to data internal to the + dictionary object, you should not try to free it or modify it. + */ +/*--------------------------------------------------------------------------*/ +const char *dictionary_get(const dictionary *d, const char *key, + const char *def); + +/*-------------------------------------------------------------------------*/ +/** + @brief Set a value in a dictionary. + @param d dictionary object to modify. + @param key Key to modify or add. + @param val Value to add. + @return int 0 if Ok, anything else otherwise + + If the given key is found in the dictionary, the associated value is + replaced by the provided one. If the key cannot be found in the + dictionary, it is added to it. + + It is Ok to provide a NULL value for val, but NULL values for the dictionary + or the key are considered as errors: the function will return immediately + in such a case. + + Notice that if you dictionary_set a variable to NULL, a call to + dictionary_get will return a NULL value: the variable will be found, and + its value (NULL) is returned. In other words, setting the variable + content to NULL is equivalent to deleting the variable from the + dictionary. It is not possible (in this implementation) to have a key in + the dictionary without value. + + This function returns non-zero in case of failure. + */ +/*--------------------------------------------------------------------------*/ +int dictionary_set(dictionary *vd, const char *key, const char *val); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a key in a dictionary + @param d dictionary object to modify. + @param key Key to remove. + @return void + + This function deletes a key in a dictionary. Nothing is done if the + key cannot be found. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_unset(dictionary *d, const char *key); + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump + @param f Opened file pointer. + @return void + + Dumps a dictionary onto an opened file pointer. Key pairs are printed out + as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as + output file pointers. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_dump(const dictionary *d, FILE *out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/param/iniparser.c b/project/app/uvc_app_tiny/uvc_app/param/iniparser.c new file mode 100644 index 000000000..1aeb5ce0f --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/param/iniparser.c @@ -0,0 +1,820 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file iniparser.c + @author N. Devillard + @brief Parser for ini files. +*/ +/*--------------------------------------------------------------------------*/ +/*---------------------------- Includes ------------------------------------*/ +#include "iniparser.h" +#include +#include + +/*---------------------------- Defines -------------------------------------*/ +#define ASCIILINESZ (1024) +#define INI_INVALID_KEY ((char *)-1) + +/*--------------------------------------------------------------------------- + Private to this module + ---------------------------------------------------------------------------*/ +/** + * This enum stores the status for each parsed line (internal use only). + */ +typedef enum _line_status_ { + LINE_UNPROCESSED, + LINE_ERROR, + LINE_EMPTY, + LINE_COMMENT, + LINE_SECTION, + LINE_VALUE +} line_status; + +/*-------------------------------------------------------------------------*/ +/** + @brief Convert a string to lowercase. + @param in String to convert. + @param out Output buffer. + @param len Size of the out buffer. + @return ptr to the out buffer or NULL if an error occured. + + This function convert a string into lowercase. + At most len - 1 elements of the input string will be converted. + */ +/*--------------------------------------------------------------------------*/ +static const char *strlwc(const char *in, char *out, unsigned len) { + unsigned i; + + if (in == NULL || out == NULL || len == 0) + return NULL; + i = 0; + while (in[i] != '\0' && i < len - 1) { + out[i] = (char)tolower((int)in[i]); + i++; + } + out[i] = '\0'; + return out; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Duplicate a string + @param s String to duplicate + @return Pointer to a newly allocated string, to be freed with free() + + This is a replacement for strdup(). This implementation is provided + for systems that do not have it. + */ +/*--------------------------------------------------------------------------*/ +static char *xstrdup(const char *s) { + char *t; + size_t len; + if (!s) + return NULL; + + len = strlen(s) + 1; + t = (char *)malloc(len); + if (t) { + memcpy(t, s, len); + } + return t; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Remove blanks at the beginning and the end of a string. + @param str String to parse and alter. + @return unsigned New size of the string. + */ +/*--------------------------------------------------------------------------*/ +static unsigned strstrip(char *s) { + char *last = NULL; + char *dest = s; + + if (s == NULL) + return 0; + + last = s + strlen(s); + while (isspace((int)*s) && *s) + s++; + while (last > s) { + if (!isspace((int)*(last - 1))) + break; + last--; + } + *last = (char)0; + + memmove(dest, s, last - s + 1); + return last - s; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Default error callback for iniparser: wraps `fprintf(stderr, ...)`. + */ +/*--------------------------------------------------------------------------*/ +static int default_error_callback(const char *format, ...) { + int ret; + va_list argptr; + va_start(argptr, format); + ret = vfprintf(stderr, format, argptr); + va_end(argptr); + return ret; +} + +static int (*iniparser_error_callback)(const char *, + ...) = default_error_callback; + +/*-------------------------------------------------------------------------*/ +/** + @brief Configure a function to receive the error messages. + @param errback Function to call. + + By default, the error will be printed on stderr. If a null pointer is passed + as errback the error callback will be switched back to default. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_set_error_callback(int (*errback)(const char *, ...)) { + if (errback) { + iniparser_error_callback = errback; + } else { + iniparser_error_callback = default_error_callback; + } +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get number of sections in a dictionary + @param d Dictionary to examine + @return int Number of sections found in dictionary + + This function returns the number of sections found in a dictionary. + The test to recognize sections is done on the string stored in the + dictionary: a section name is given as "section" whereas a key is + stored as "section:key", thus the test looks for entries that do not + contain a colon. + + This clearly fails in the case a section name contains a colon, but + this should simply be avoided. + + This function returns -1 in case of error. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getnsec(const dictionary *d) { + int i; + int nsec; + + if (d == NULL) + return -1; + nsec = 0; + for (i = 0; i < d->size; i++) { + if (d->key[i] == NULL) + continue; + if (strchr(d->key[i], ':') == NULL) { + nsec++; + } + } + return nsec; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get name for section n in a dictionary. + @param d Dictionary to examine + @param n Section number (from 0 to nsec-1). + @return Pointer to char string + + This function locates the n-th section in a dictionary and returns + its name as a pointer to a string statically allocated inside the + dictionary. Do not free or modify the returned string! + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ +const char *iniparser_getsecname(const dictionary *d, int n) { + int i; + int foundsec; + + if (d == NULL || n < 0) + return NULL; + foundsec = 0; + for (i = 0; i < d->size; i++) { + if (d->key[i] == NULL) + continue; + if (strchr(d->key[i], ':') == NULL) { + foundsec++; + if (foundsec > n) + break; + } + } + if (foundsec <= n) { + return NULL; + } + return d->key[i]; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump. + @param f Opened file pointer to dump to. + @return void + + This function prints out the contents of a dictionary, one element by + line, onto the provided file pointer. It is OK to specify @c stderr + or @c stdout as output files. This function is meant for debugging + purposes mostly. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump(const dictionary *d, FILE *f) { + int i; + + if (d == NULL || f == NULL) + return; + for (i = 0; i < d->size; i++) { + if (d->key[i] == NULL) + continue; + if (d->val[i] != NULL) { + fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]); + } else { + fprintf(f, "[%s]=UNDEF\n", d->key[i]); + } + } + return; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary to a loadable ini file + @param d Dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given dictionary into a loadable ini file. + It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump_ini(const dictionary *d, FILE *f) { + int i; + int nsec; + const char *secname; + + if (d == NULL || f == NULL) + return; + + nsec = iniparser_getnsec(d); + if (nsec < 1) { + /* No section in file: dump all keys as they are */ + for (i = 0; i < d->size; i++) { + if (d->key[i] == NULL) + continue; + fprintf(f, "%s = %s\n", d->key[i], d->val[i]); + } + return; + } + for (i = 0; i < nsec; i++) { + secname = iniparser_getsecname(d, i); + iniparser_dumpsection_ini(d, secname, f); + } + fprintf(f, "\n"); + return; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary section to a loadable ini file + @param d Dictionary to dump + @param s Section name of dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given section of a given dictionary into a loadable ini + file. It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dumpsection_ini(const dictionary *d, const char *s, FILE *f) { + int j; + char keym[ASCIILINESZ + 1]; + int seclen; + + if (d == NULL || f == NULL) + return; + if (!iniparser_find_entry(d, s)) + return; + + seclen = (int)strlen(s); + fprintf(f, "\n[%s]\n", s); + sprintf(keym, "%s:", s); + for (j = 0; j < d->size; j++) { + if (d->key[j] == NULL) + continue; + if (!strncmp(d->key[j], keym, seclen + 1)) { + fprintf(f, "%-30s = %s\n", d->key[j] + seclen + 1, + d->val[j] ? d->val[j] : ""); + } + } + fprintf(f, "\n"); + return; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @return Number of keys in section + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getsecnkeys(const dictionary *d, const char *s) { + int seclen, nkeys; + char keym[ASCIILINESZ + 1]; + int j; + + nkeys = 0; + + if (d == NULL) + return nkeys; + if (!iniparser_find_entry(d, s)) + return nkeys; + + seclen = (int)strlen(s); + strlwc(s, keym, sizeof(keym)); + keym[seclen] = ':'; + + for (j = 0; j < d->size; j++) { + if (d->key[j] == NULL) + continue; + if (!strncmp(d->key[j], keym, seclen + 1)) + nkeys++; + } + + return nkeys; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @param keys Already allocated array to store the keys in + @return The pointer passed as `keys` argument or NULL in case of error + + This function queries a dictionary and finds all keys in a given section. + The keys argument should be an array of pointers which size has been + determined by calling `iniparser_getsecnkeys` function prior to this one. + + Each pointer in the returned char pointer-to-pointer is pointing to + a string allocated in the dictionary; do not free or modify them. + */ +/*--------------------------------------------------------------------------*/ +const char **iniparser_getseckeys(const dictionary *d, const char *s, + const char **keys) { + int i, j, seclen; + char keym[ASCIILINESZ + 1]; + + if (d == NULL || keys == NULL) + return NULL; + if (!iniparser_find_entry(d, s)) + return NULL; + + seclen = (int)strlen(s); + strlwc(s, keym, sizeof(keym)); + keym[seclen] = ':'; + + i = 0; + + for (j = 0; j < d->size; j++) { + if (d->key[j] == NULL) + continue; + if (!strncmp(d->key[j], keym, seclen + 1)) { + keys[i] = d->key[j]; + i++; + } + } + + return keys; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key + @param d Dictionary to search + @param key Key string to look for + @param def Default value to return if key not found. + @return pointer to statically allocated character string + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the pointer passed as 'def' is returned. + The returned char pointer is pointing to a string allocated in + the dictionary, do not free or modify it. + */ +/*--------------------------------------------------------------------------*/ +const char *iniparser_getstring(const dictionary *d, const char *key, + const char *def) { + const char *lc_key; + const char *sval; + char tmp_str[ASCIILINESZ + 1]; + + if (d == NULL || key == NULL) + return def; + + lc_key = strlwc(key, tmp_str, sizeof(tmp_str)); + sval = dictionary_get(d, lc_key, def); + return sval; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an long int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return long integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + "42" -> 42 + "042" -> 34 (octal -> decimal) + "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +long int iniparser_getlongint(const dictionary *d, const char *key, + long int notfound) { + const char *str; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str == INI_INVALID_KEY) + return notfound; + return strtol(str, NULL, 0); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + "42" -> 42 + "042" -> 34 (octal -> decimal) + "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getint(const dictionary *d, const char *key, int notfound) { + return (int)iniparser_getlongint(d, key, notfound); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a double + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return double + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + */ +/*--------------------------------------------------------------------------*/ +double iniparser_getdouble(const dictionary *d, const char *key, + double notfound) { + const char *str; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str == INI_INVALID_KEY) + return notfound; + return atof(str); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a boolean + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + A true boolean is found if one of the following is matched: + + - A string starting with 'y' + - A string starting with 'Y' + - A string starting with 't' + - A string starting with 'T' + - A string starting with '1' + + A false boolean is found if one of the following is matched: + + - A string starting with 'n' + - A string starting with 'N' + - A string starting with 'f' + - A string starting with 'F' + - A string starting with '0' + + The notfound value returned if no boolean is identified, does not + necessarily have to be 0 or 1. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getboolean(const dictionary *d, const char *key, int notfound) { + int ret; + const char *c; + + c = iniparser_getstring(d, key, INI_INVALID_KEY); + if (c == INI_INVALID_KEY) + return notfound; + if (c[0] == 'y' || c[0] == 'Y' || c[0] == '1' || c[0] == 't' || c[0] == 'T') { + ret = 1; + } else if (c[0] == 'n' || c[0] == 'N' || c[0] == '0' || c[0] == 'f' || + c[0] == 'F') { + ret = 0; + } else { + ret = notfound; + } + return ret; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Finds out if a given entry exists in a dictionary + @param ini Dictionary to search + @param entry Name of the entry to look for + @return integer 1 if entry exists, 0 otherwise + + Finds out if a given entry exists in the dictionary. Since sections + are stored as keys with NULL associated values, this is the only way + of querying for the presence of sections in a dictionary. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_find_entry(const dictionary *ini, const char *entry) { + int found = 0; + if (iniparser_getstring(ini, entry, INI_INVALID_KEY) != INI_INVALID_KEY) { + found = 1; + } + return found; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Set an entry in a dictionary. + @param ini Dictionary to modify. + @param entry Entry to modify (entry name) + @param val New value to associate to the entry. + @return int 0 if Ok, -1 otherwise. + + If the given entry can be found in the dictionary, it is modified to + contain the provided value. If it cannot be found, the entry is created. + It is Ok to set val to NULL. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_set(dictionary *ini, const char *entry, const char *val) { + char tmp_str[ASCIILINESZ + 1]; + return dictionary_set(ini, strlwc(entry, tmp_str, sizeof(tmp_str)), val); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete an entry in a dictionary + @param ini Dictionary to modify + @param entry Entry to delete (entry name) + @return void + + If the given entry can be found, it is deleted from the dictionary. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_unset(dictionary *ini, const char *entry) { + char tmp_str[ASCIILINESZ + 1]; + dictionary_unset(ini, strlwc(entry, tmp_str, sizeof(tmp_str))); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Load a single line from an INI file + @param input_line Input line, may be concatenated multi-line input + @param section Output space to store section + @param key Output space to store key + @param value Output space to store value + @return line_status value + */ +/*--------------------------------------------------------------------------*/ +static line_status iniparser_line(const char *input_line, char *section, + char *key, char *value) { + line_status sta; + char *line = NULL; + size_t len; + + line = xstrdup(input_line); + len = strstrip(line); + + sta = LINE_UNPROCESSED; + if (len < 1) { + /* Empty line */ + sta = LINE_EMPTY; + } else if (line[0] == '#' || line[0] == ';') { + /* Comment line */ + sta = LINE_COMMENT; + } else if (line[0] == '[' && line[len - 1] == ']') { + /* Section name */ + sscanf(line, "[%[^]]", section); + strstrip(section); + strlwc(section, section, len); + sta = LINE_SECTION; + } else if (sscanf(line, "%[^=] = \"%[^\"]\"", key, value) == 2 || + sscanf(line, "%[^=] = '%[^\']'", key, value) == 2) { + /* Usual key=value with quotes, with or without comments */ + strstrip(key); + strlwc(key, key, len); + /* Don't strip spaces from values surrounded with quotes */ + sta = LINE_VALUE; + } else if (sscanf(line, "%[^=] = %[^;#]", key, value) == 2) { + /* Usual key=value without quotes, with or without comments */ + strstrip(key); + strlwc(key, key, len); + strstrip(value); + /* + * sscanf cannot handle '' or "" as empty values + * this is done here + */ + if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) { + value[0] = 0; + } + sta = LINE_VALUE; + } else if (sscanf(line, "%[^=] = %[;#]", key, value) == 2 || + sscanf(line, "%[^=] %[=]", key, value) == 2) { + /* + * Special cases: + * key= + * key=; + * key=# + */ + strstrip(key); + strlwc(key, key, len); + value[0] = 0; + sta = LINE_VALUE; + } else { + /* Generate syntax error */ + sta = LINE_ERROR; + } + + free(line); + return sta; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param ininame Name of the ini file to read. + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the name of the file to be read. It returns a dictionary object that + should not be accessed directly, but through accessor functions + instead. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary *iniparser_load(const char *ininame) { + FILE *in; + + char line[ASCIILINESZ + 1]; + char section[ASCIILINESZ + 1]; + char key[ASCIILINESZ + 1]; + char tmp[(ASCIILINESZ * 2) + 2]; + char val[ASCIILINESZ + 1]; + + int last = 0; + int len; + int lineno = 0; + int errs = 0; + int mem_err = 0; + + dictionary *dict; + + if ((in = fopen(ininame, "r")) == NULL) { + iniparser_error_callback("iniparser: cannot open %s\n", ininame); + return NULL; + } + + dict = dictionary_new(0); + if (!dict) { + fclose(in); + return NULL; + } + + memset(line, 0, ASCIILINESZ); + memset(section, 0, ASCIILINESZ); + memset(key, 0, ASCIILINESZ); + memset(val, 0, ASCIILINESZ); + last = 0; + + while (fgets(line + last, ASCIILINESZ - last, in) != NULL) { + lineno++; + len = (int)strlen(line) - 1; + if (len <= 0) + continue; + /* Safety check against buffer overflows */ + if (line[len] != '\n' && !feof(in)) { + iniparser_error_callback("iniparser: input line too long in %s (%d)\n", + ininame, lineno); + dictionary_del(dict); + fclose(in); + return NULL; + } + /* Get rid of \n and spaces at end of line */ + while ((len >= 0) && ((line[len] == '\n') || (isspace(line[len])))) { + line[len] = 0; + len--; + } + if (len < 0) { /* Line was entirely \n and/or spaces */ + len = 0; + } + /* Detect multi-line */ + if (line[len] == '\\') { + /* Multi-line value */ + last = len; + continue; + } else { + last = 0; + } + switch (iniparser_line(line, section, key, val)) { + case LINE_EMPTY: + case LINE_COMMENT: + break; + + case LINE_SECTION: + mem_err = dictionary_set(dict, section, NULL); + break; + + case LINE_VALUE: + sprintf(tmp, "%s:%s", section, key); + mem_err = dictionary_set(dict, tmp, val); + break; + + case LINE_ERROR: + iniparser_error_callback("iniparser: syntax error in %s (%d):\n-> %s\n", + ininame, lineno, line); + errs++; + break; + + default: + break; + } + memset(line, 0, ASCIILINESZ); + last = 0; + if (mem_err < 0) { + iniparser_error_callback("iniparser: memory allocation failure\n"); + break; + } + } + if (errs) { + dictionary_del(dict); + dict = NULL; + } + fclose(in); + return dict; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Free all memory associated to an ini dictionary + @param d Dictionary to free + @return void + + Free all memory associated to an ini dictionary. + It is mandatory to call this function before the dictionary object + gets out of the current context. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_freedict(dictionary *d) { dictionary_del(d); } diff --git a/project/app/uvc_app_tiny/uvc_app/param/iniparser.h b/project/app/uvc_app_tiny/uvc_app/param/iniparser.h new file mode 100644 index 000000000..0946857ec --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/param/iniparser.h @@ -0,0 +1,356 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file iniparser.h + @author N. Devillard + @brief Parser for ini files. +*/ +/*--------------------------------------------------------------------------*/ + +#ifndef _INIPARSER_H_ +#define _INIPARSER_H_ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ + +#include +#include +#include + +/* + * The following #include is necessary on many Unixes but not Linux. + * It is not needed for Windows platforms. + * Uncomment it if needed. + */ +/* #include */ + +#include "dictionary.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------*/ +/** + @brief Configure a function to receive the error messages. + @param errback Function to call. + + By default, the error will be printed on stderr. If a null pointer is passed + as errback the error callback will be switched back to default. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_set_error_callback(int (*errback)(const char *, ...)); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get number of sections in a dictionary + @param d Dictionary to examine + @return int Number of sections found in dictionary + + This function returns the number of sections found in a dictionary. + The test to recognize sections is done on the string stored in the + dictionary: a section name is given as "section" whereas a key is + stored as "section:key", thus the test looks for entries that do not + contain a colon. + + This clearly fails in the case a section name contains a colon, but + this should simply be avoided. + + This function returns -1 in case of error. + */ +/*--------------------------------------------------------------------------*/ + +int iniparser_getnsec(const dictionary *d); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get name for section n in a dictionary. + @param d Dictionary to examine + @param n Section number (from 0 to nsec-1). + @return Pointer to char string + + This function locates the n-th section in a dictionary and returns + its name as a pointer to a string statically allocated inside the + dictionary. Do not free or modify the returned string! + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ + +const char *iniparser_getsecname(const dictionary *d, int n); + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary to a loadable ini file + @param d Dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given dictionary into a loadable ini file. + It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_dump_ini(const dictionary *d, FILE *f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary section to a loadable ini file + @param d Dictionary to dump + @param s Section name of dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given section of a given dictionary into a loadable ini + file. It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_dumpsection_ini(const dictionary *d, const char *s, FILE *f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump. + @param f Opened file pointer to dump to. + @return void + + This function prints out the contents of a dictionary, one element by + line, onto the provided file pointer. It is OK to specify @c stderr + or @c stdout as output files. This function is meant for debugging + purposes mostly. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump(const dictionary *d, FILE *f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @return Number of keys in section + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getsecnkeys(const dictionary *d, const char *s); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @param keys Already allocated array to store the keys in + @return The pointer passed as `keys` argument or NULL in case of error + + This function queries a dictionary and finds all keys in a given section. + The keys argument should be an array of pointers which size has been + determined by calling `iniparser_getsecnkeys` function prior to this one. + + Each pointer in the returned char pointer-to-pointer is pointing to + a string allocated in the dictionary; do not free or modify them. + */ +/*--------------------------------------------------------------------------*/ +const char **iniparser_getseckeys(const dictionary *d, const char *s, + const char **keys); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key + @param d Dictionary to search + @param key Key string to look for + @param def Default value to return if key not found. + @return pointer to statically allocated character string + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the pointer passed as 'def' is returned. + The returned char pointer is pointing to a string allocated in + the dictionary, do not free or modify it. + */ +/*--------------------------------------------------------------------------*/ +const char *iniparser_getstring(const dictionary *d, const char *key, + const char *def); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getint(const dictionary *d, const char *key, int notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an long int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + */ +/*--------------------------------------------------------------------------*/ +long int iniparser_getlongint(const dictionary *d, const char *key, + long int notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a double + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return double + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + */ +/*--------------------------------------------------------------------------*/ +double iniparser_getdouble(const dictionary *d, const char *key, + double notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a boolean + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + A true boolean is found if one of the following is matched: + + - A string starting with 'y' + - A string starting with 'Y' + - A string starting with 't' + - A string starting with 'T' + - A string starting with '1' + + A false boolean is found if one of the following is matched: + + - A string starting with 'n' + - A string starting with 'N' + - A string starting with 'f' + - A string starting with 'F' + - A string starting with '0' + + The notfound value returned if no boolean is identified, does not + necessarily have to be 0 or 1. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getboolean(const dictionary *d, const char *key, int notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Set an entry in a dictionary. + @param ini Dictionary to modify. + @param entry Entry to modify (entry name) + @param val New value to associate to the entry. + @return int 0 if Ok, -1 otherwise. + + If the given entry can be found in the dictionary, it is modified to + contain the provided value. If it cannot be found, the entry is created. + It is Ok to set val to NULL. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_set(dictionary *ini, const char *entry, const char *val); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete an entry in a dictionary + @param ini Dictionary to modify + @param entry Entry to delete (entry name) + @return void + + If the given entry can be found, it is deleted from the dictionary. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_unset(dictionary *ini, const char *entry); + +/*-------------------------------------------------------------------------*/ +/** + @brief Finds out if a given entry exists in a dictionary + @param ini Dictionary to search + @param entry Name of the entry to look for + @return integer 1 if entry exists, 0 otherwise + + Finds out if a given entry exists in the dictionary. Since sections + are stored as keys with NULL associated values, this is the only way + of querying for the presence of sections in a dictionary. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_find_entry(const dictionary *ini, const char *entry); + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param ininame Name of the ini file to read. + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the name of the file to be read. It returns a dictionary object that + should not be accessed directly, but through accessor functions + instead. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary *iniparser_load(const char *ininame); + +/*-------------------------------------------------------------------------*/ +/** + @brief Free all memory associated to an ini dictionary + @param d Dictionary to free + @return void + + Free all memory associated to an ini dictionary. + It is mandatory to call this function before the dictionary object + gets out of the current context. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_freedict(dictionary *d); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/param/param.c b/project/app/uvc_app_tiny/uvc_app/param/param.c new file mode 100644 index 000000000..ab638f16e --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/param/param.c @@ -0,0 +1,139 @@ +// Copyright 2021 Rockchip Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#include "iniparser.h" +#include "uvc_log.h" +#include +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "param.c" + +char g_ini_path_[256]; +dictionary *g_ini_d_; +static pthread_mutex_t g_param_mutex = PTHREAD_MUTEX_INITIALIZER; + +int rk_param_dump() { + const char *section_name; + const char *keys[32]; + int section_keys; + int section_num = iniparser_getnsec(g_ini_d_); + LOG_INFO("section_num is %d\n", section_num); + + for (int i = 0; i < section_num; i++) { + section_name = iniparser_getsecname(g_ini_d_, i); + LOG_INFO("section_name is %s\n", section_name); + section_keys = iniparser_getsecnkeys(g_ini_d_, section_name); + for (int j = 0; j < section_keys; j++) { + iniparser_getseckeys(g_ini_d_, section_name, keys); + LOG_INFO("%s = %s\n", keys[j], + iniparser_getstring(g_ini_d_, keys[j], "")); + } + } + + return 0; +} + +int rk_param_save() { + FILE *fp = fopen(g_ini_path_, "w"); + if (fp == NULL) { + LOG_ERROR("%s, fopen error!\n", g_ini_path_); + iniparser_freedict(g_ini_d_); + g_ini_d_ = NULL; + return -1; + } + iniparser_dump_ini(g_ini_d_, fp); + + fflush(fp); + fclose(fp); + + return 0; +} + +int rk_param_get_int(const char *entry, int default_val) { + int ret; + pthread_mutex_lock(&g_param_mutex); + ret = iniparser_getint(g_ini_d_, entry, default_val); + pthread_mutex_unlock(&g_param_mutex); + + return ret; +} + +int rk_param_set_int(const char *entry, int val) { + char tmp[8]; + sprintf(tmp, "%d", val); + pthread_mutex_lock(&g_param_mutex); + iniparser_set(g_ini_d_, entry, tmp); + rk_param_save(); + pthread_mutex_unlock(&g_param_mutex); + + return 0; +} + +const char *rk_param_get_string(const char *entry, const char *default_val) { + const char *ret; + pthread_mutex_lock(&g_param_mutex); + ret = iniparser_getstring(g_ini_d_, entry, default_val); + pthread_mutex_unlock(&g_param_mutex); + + return ret; +} + +int rk_param_set_string(const char *entry, const char *val) { + pthread_mutex_lock(&g_param_mutex); + iniparser_set(g_ini_d_, entry, val); + rk_param_save(); + pthread_mutex_unlock(&g_param_mutex); + + return 0; +} + +int rk_param_init(char *ini_path) { + LOG_INFO("%s\n", __func__); + pthread_mutex_lock(&g_param_mutex); + g_ini_d_ = NULL; + if (ini_path) + memcpy(g_ini_path_, ini_path, strlen(ini_path)); + else + memcpy(g_ini_path_, "/oem/usr/share/rkuvc.ini", strlen("/oem/usr/share/rkuvc.ini")); + LOG_INFO("g_ini_path_ is %s\n", g_ini_path_); + + g_ini_d_ = iniparser_load(g_ini_path_); + if (g_ini_d_ == NULL) { + LOG_ERROR("iniparser_load error!\n"); + return -1; + } + rk_param_dump(); + pthread_mutex_unlock(&g_param_mutex); + + return 0; +} + +int rk_param_deinit() { + LOG_INFO("%s\n", __func__); + if (g_ini_d_ == NULL) + return 0; + pthread_mutex_lock(&g_param_mutex); + rk_param_save(); + if (g_ini_d_) + iniparser_freedict(g_ini_d_); + pthread_mutex_unlock(&g_param_mutex); + + return 0; +} + +int rk_param_reload() { + LOG_INFO("%s\n", __func__); + pthread_mutex_lock(&g_param_mutex); + if (g_ini_d_) + iniparser_freedict(g_ini_d_); + g_ini_d_ = iniparser_load(g_ini_path_); + if (g_ini_d_ == NULL) { + LOG_ERROR("iniparser_load error!\n"); + return -1; + } + rk_param_dump(); + pthread_mutex_unlock(&g_param_mutex); + + return 0; +} diff --git a/project/app/uvc_app_tiny/uvc_app/param/param.h b/project/app/uvc_app_tiny/uvc_app/param/param.h new file mode 100644 index 000000000..b12a32269 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/param/param.h @@ -0,0 +1,28 @@ +// Copyright 2021 Rockchip Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#include "iniparser.h" + +extern dictionary *g_ini_d_; + +int rk_param_get_int(const char *entry, int default_val); +int rk_param_set_int(const char *entry, int val); +const char *rk_param_get_string(const char *entry, const char *default_val); +int rk_param_set_string(const char *entry, const char *val); +int rk_param_save(); +int rk_param_init(char *ini_path); +int rk_param_deinit(); +int rk_param_reload(); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/project/app/uvc_app_tiny/uvc_app/rkuvc.ini b/project/app/uvc_app_tiny/uvc_app/rkuvc.ini new file mode 100644 index 000000000..ca284a981 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/rkuvc.ini @@ -0,0 +1,82 @@ +[video.source] +enable_aiq = 1 +enable_vo = 0 +enable_npu = 0 +enable_uac = 0 + +[isp.0.adjustment] +contrast = 50 +brightness = 50 +saturation = 50 +sharpness = 50 +fps = 30 +hue = 50 + +[isp.0.exposure] +iris_type = auto +exposure_mode = auto +gain_mode = auto +auto_iris_level = 5 +auto_exposure_enabled = 1 +audo_gain_enabled = 1 +exposure_time = 1/6 +exposure_gain = 1 + +[isp.0.night_to_day] +night_to_day = day +night_to_day_filter_level = 5 +night_to_day_filter_time = 5 +dawn_time = 07:00:00 +dusk_time = 18:00:00 +ircut_filter_action = day +over_exposure_suppress = open +over_exposure_suppress_type = auto +fill_light_mode = IR +brightness_adjustment_mode = auto +light_brightness = 1 +distance_level = 1 + +[isp.0.blc] +blc_region = close +blc_strength = 1 +wdr = close +wdr_level = 0 +hdr = close +hdr_level = 1 +hlc = close +hlc_level = 0 +dark_boost_level = 0 +position_x = 0 +position_y = 0 +blc_region_width = 120 +blc_region_high = 92 + +[isp.0.white_blance] +white_blance_style = autoWhiteBalance +white_blance_red = 50 +white_blance_green = 50 +white_blance_blue = 50 + +[isp.0.enhancement] +noise_reduce_mode = close +denoise_level = 50 +spatial_denoise_level = 50 +temporal_denoise_level = 50 +dehaze = close +dehaze_level = 0 +dis = close +gray_scale_mode = [0-255] +image_rotation = 0 +distortion_correction = close +ldch_level = 0 + +[isp.0.video_adjustment] +image_flip = close +scene_mode = indoor +power_line_frequency_mode = PAL(50HZ) + +[isp.0.auto_focus] +af_mode = semi-auto +zoom_level = 0 +focus_level = 0 + diff --git a/project/app/uvc_app_tiny/uvc_app/uac/configs/configs_skv.json b/project/app/uvc_app_tiny/uvc_app/uac/configs/configs_skv.json new file mode 100755 index 000000000..ff67383c2 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/configs/configs_skv.json @@ -0,0 +1,79 @@ +{ + "skv_configs": { + "aec": { + "status" : "disable", + "drop_ref_channel" : 0, + "delay_len" : 0, + "look_ahead" : 0 + }, + "bf": { + "status" : "enable", + "targ" : 0, + "drop_ref_channel" : 0 + }, + "fast_aec": { + "status" : "enable" + }, + "aes": { + "status" : "enable", + "beta_up": "float:0.0005", + "beta_down": "float:0.01" + }, + "gsc": { + "status" : "disable", + "method" : 0 + }, + "agc": { + "status" : "enable", + "attack_time" : "float:100.0", + "release_time" : "float:400.0", + "attenuate_time" : "float:1000", + "max_gain" : "float:30.0", + "max_peak" : "float:-1.0", + "fRth0": "float:-65", + "fRth1" : "float:-50", + "fRth2" : "float:-35", + "fRk0" : "float:2.5", + "fRk1" : "float:0.8", + "fRk2" : "float:0.4", + "fLineGainDb" : "float:10.0", + "swSmL0" : 40, + "swSmL1" : 80, + "swSmL2" : 80 + }, + "anr": { + "status" : "enable", + "noiseFactor" : "float:0.88", + "swU" : 10, + "psiMin" : "float:0.02", + "psiMax" : "float:0.516", + "fGmin" : "float:0.1" + }, + "nlp": { + "status" : "disable", + "band_pass_thd" : "10,10,10,5,5,5,0,0", + "super_est_factor" : "6,10,10,10,10,10,6,6" + }, + "dereverb": { + "status" : "disable", + "rlsLg" : 4, + "curveLg" : 10, + "delay" : 2, + "forgetting" : "float:0.98", + "t60" : "float:1.5", + "coCoeff" : "float:2.0" + }, + "cng": { + "status" : "disable", + "fGain" : "float:2.0", + "fMpy" : "float:5", + "fSmoothAlpha" : "float:0.92", + "fSpeechGain" : "float:0.3" + }, + "dtd": { + "status" : "disable", + "ksiThd_high" : "float:0.7", + "ksiThd_low" : "float:0.5" + } + } +} diff --git a/project/app/uvc_app_tiny/uvc_app/uac/doc/zh-cn/Rockchip_Developer_Guide_Linux_1126_1109_UACApp_CN.pdf b/project/app/uvc_app_tiny/uvc_app/uac/doc/zh-cn/Rockchip_Developer_Guide_Linux_1126_1109_UACApp_CN.pdf new file mode 100755 index 000000000..6f8727435 Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/doc/zh-cn/Rockchip_Developer_Guide_Linux_1126_1109_UACApp_CN.pdf differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/doc/zh-cn/Rockchip_Developer_Guide_Microphone_Array_TEST_CN.pdf b/project/app/uvc_app_tiny/uvc_app/uac/doc/zh-cn/Rockchip_Developer_Guide_Microphone_Array_TEST_CN.pdf new file mode 100755 index 000000000..9a563a3fc Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/doc/zh-cn/Rockchip_Developer_Guide_Microphone_Array_TEST_CN.pdf differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/doc/zh-cn/Rockchip_Quick_Start_Linux_UAC_CN.pdf b/project/app/uvc_app_tiny/uvc_app/uac/doc/zh-cn/Rockchip_Quick_Start_Linux_UAC_CN.pdf new file mode 100755 index 000000000..cc717d74b Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/doc/zh-cn/Rockchip_Quick_Start_Linux_UAC_CN.pdf differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/include/mpi_control_common.h b/project/app/uvc_app_tiny/uvc_app/uac/src/include/mpi_control_common.h new file mode 100644 index 000000000..7179e95e0 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/include/mpi_control_common.h @@ -0,0 +1,93 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef SRC_MPI_MPI_CONTROL_H_ +#define SRC_MPI_MPI_CONTROL_H_ + +#ifdef __cplusplus + +#include "uac_common_def.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define UAC_MPI_ENABLE (1 << 1) +#define MIC_SPK_SOUNDCARD_INDEX 0 + +typedef enum _UacMpiType { + UAC_MPI_TYPE_AI = 0, + UAC_MPI_TYPE_AO = 1, + UAC_MPI_TYPE_AF_VQE = 2, + UAC_MPI_TYPE_MAX +} UacMpiType; + +typedef enum _UacMpiAODevId { + AO_USB_DEV, // ao[0] + AO_SPK_DEV, // ao[1] +} UacMpiAODevId; + +typedef enum _UacMpiAIDevId { + AI_MIC_DEV, // ai[0] + AI_USB_DEV, // ai[1] +} UacMpiAIDevId; + +typedef enum _UacMpiAFChnId { + AF_VQE_CHN, // af[0] +} UacMpiAFChnId; + +typedef struct _UacMpiIdConfig { + AUDIO_DEV aoDevId; + AUDIO_DEV aiDevId; + AO_CHN aoChnId; + AI_CHN aiChnId; + AF_CHN vqeChnId; +} UacMpiIdConfig; + +typedef struct _UacMpiStream { + int flag; + UacMpiIdConfig idCfg; + UacAudioConfig config; +} UacMpiStream; + +class UacMpiUtil { +public: + static const char *getSndCardName(UacMpiType type, int mode); + static RK_U32 getSndCardChannels(UacMpiType type, int mode); + static RK_U32 getSndCardSampleRate(UacMpiType type, int mode); + static AUDIO_BIT_WIDTH_E getSndCardbitWidth(UacMpiType type, int mode); + static RK_U32 getDataSamplerate(UacMpiType type, int mode); + static AUDIO_BIT_WIDTH_E getDataBitwidth(UacMpiType type, int mode); + static AUDIO_SOUND_MODE_E getDataSoundmode(UacMpiType type, int mode); + static const char *getVqeCfgPath(); + static RK_U32 getVqeSampleRate(); + static RK_U32 getVqeChannels(); + static RK_U32 getVqeChnLayout(); + static RK_U32 getVqeRefLayout(); + static RK_U32 getVqeMicLayout(); +}; + +void mpi_set_samplerate(int type, UacMpiStream &streamCfg); +void mpi_set_volume(int type, UacMpiStream &streamCfg); +void mpi_set_ppm(int type, UacMpiStream &streamCfg); + +#endif +#endif // SRC_MPI_MPI_CONTROL_H_ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_amixer.h b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_amixer.h new file mode 100644 index 000000000..c8c9a8d6a --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_amixer.h @@ -0,0 +1,61 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef SRC_MPI_MPI_UAC_AMIXER_H_ +#define SRC_MPI_MPI_UAC_AMIXER_H_ + +#include "rk_common.h" + +typedef enum _HARDWARE_REF_MODE { + HARDWARE_REF_DISABLE = 0, // disable hardware ref channel + HARDWARE_REF_MODE1, // 4chn: 2 mic + 1 ref + HARDWARE_REF_MODE2, // 2chn: 1 mic + 1 ref + HARDWARE_REF_MODE2_SWAP // 2chn: 1 ref + 1 mic +} HARDWARE_REF_MODE; + +typedef struct _MpiChnAttrConfigMap { + RK_U32 u32Index; + RK_U32 u32Channels; + RK_U32 u32MicLayout; + RK_U32 u32RefLayout; + const char *chMode; +} MpiChnAttrConfigMap; + +// the hardware of our RV1106's evb board support mode2 +const static int sRefMode = HARDWARE_REF_MODE2; +const static MpiChnAttrConfigMap sChnAttrCfgs[] = { + {HARDWARE_REF_DISABLE, 2, 0x3, 0x0, + "Disable"}, // disable hardware ref channel + {HARDWARE_REF_MODE1, 4, 0x3, 0xc, "Mode1"}, // 4chn: 2 mic + 1 ref + {HARDWARE_REF_MODE2, 2, 0x1, 0x2, + "Mode2"}, // 2chn: 1 mic(ADC Left) + 1 ref(DAC Right) + {HARDWARE_REF_MODE2_SWAP, 2, 0x2, 0x1, + "Mode2 Swap"}, // 2chn: 1 ref(DAC Left) + 1 mic(ADC Right) +}; + +class UACAmixer { +public: + static RK_S32 set(AUDIO_DEV AmixDevId, const char *ctrlName, + const char *value); + static RK_S32 get(AUDIO_DEV AmixDevId, const char *ctrlName); + static void dumpContents(AUDIO_DEV AmixDevId); +}; + +RK_S32 amix_set_ref_mode(AUDIO_DEV AoDevId); +RK_S32 amix_set_ppm(AUDIO_DEV AoDevId, RK_S32 ppm); + +#endif // SRC_MPI_MPI_UAC_AMIXER_H_ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_common_def.h b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_common_def.h new file mode 100644 index 000000000..d55ba7880 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_common_def.h @@ -0,0 +1,87 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef SRC_INCLUDE_UAC_COMMON_DEF_H_ +#define SRC_INCLUDE_UAC_COMMON_DEF_H_ +#ifdef __cplusplus + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OPT_SAMPLE_RATE "opt_samaple_rate" +#define OPT_CHANNELS "opt_channel" +#define OPT_VOLUME "opt_volume" +#define OPT_MUTE "opt_mute" +#define OPT_CONFIGS "opt_configs" +#define OPT_PPM "opt_ppm" + +#define OPT_SET_ALSA_CAPTURE "set_capture_config" +#define OPT_SET_RESAMPLE "set_resample_config" +#define OPT_SET_VOLUME "set_volume_config" +#define OPT_SET_CONFIG "set_config" +#define OPT_SET_PPM "set_ppm" + +#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) + +#define GET_ENTRY_VALUE(INPUT1, INPUT2, MAP, KEY1, KEY2, VALUE) \ + do { \ + for (size_t i = 0; i < ARRAY_ELEMS(MAP); i++) { \ + if (INPUT1 == MAP[i].KEY1 && INPUT2 == MAP[i].KEY2) \ + return MAP[i].VALUE; \ + } \ + } while (0) + +enum UacStreamType { + // our device record datas from usb, pc/remote->our device + UAC_STREAM_RECORD = 0, + // play datas to usb, our device->pc/remote + UAC_STREAM_PLAYBACK, + UAC_STREAM_MAX +}; + +typedef struct _UacAudioConfig { + int samplerate; + union { + int intVol; + float floatVol; + }; + int mute; + int ppm; +} UacAudioConfig; + +uint64_t getRelativeTimeMs(); +uint64_t getRelativeTimeUs(); +#endif +#endif // SRC_INCLUDE_UAC_COMMON_DEF_H_ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control.h b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control.h new file mode 100644 index 000000000..03afe4037 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control.h @@ -0,0 +1,56 @@ +/* + * Copyright 2020 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef SRC_INCLUDE_UAC_CONTROL_H_ +#define SRC_INCLUDE_UAC_CONTROL_H_ + +#include "uac_common_def.h" + +enum UacApiType { UAC_API_MPI = 0, UAC_API_GRAPH = 1, UAC_API_MAX }; + +#ifdef __cplusplus +class UACControl { +public: + UACControl() {} + virtual ~UACControl() {} + +public: + virtual int uacStart() = 0; + virtual void uacStop() = 0; + virtual void uacSetSampleRate(int sampleRate) = 0; + virtual void uacSetVolume(int volume) = 0; + virtual void uacSetMute(int mute) = 0; + virtual void uacSetPpm(int ppm) = 0; +}; +#endif +#ifdef __cplusplus +extern "C" { +#endif + +int uac_start(int mode); +void uac_stop(int mode); +void uac_set_sample_rate(int mode, int samplerate); +void uac_set_volume(int mode, int volume); +void uac_set_mute(int mode, int mute); +void uac_set_ppm(int mode, int ppm); + +int uac_control_create(int type); +void uac_control_destory(); +#ifdef __cplusplus +} +#endif + +#endif // SRC_INCLUDE_UAC_CONTROL_H_ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_factory.h b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_factory.h new file mode 100755 index 000000000..b7a0d77c6 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_factory.h @@ -0,0 +1,28 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef SRC_INCLUDE_UAC_CONTROL_FACTORY_H +#define SRC_INCLUDE_UAC_CONTROL_FACTORY_H +#ifdef __cplusplus +#include "uac_common_def.h" +#include "uac_control.h" + +class UacControlFactory { +public: + static UACControl *create(UacApiType type, int mode); +}; +#endif +#endif // SRC_INCLUDE_UAC_CONTROL_FACTORY_H \ No newline at end of file diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_graph.h b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_graph.h new file mode 100644 index 000000000..07c7fb96d --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_graph.h @@ -0,0 +1,40 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef SRC_INCLUDE_UAC_CONTROL_GRAPH_H_ +#define SRC_INCLUDE_UAC_CONTROL_GRAPH_H_ +#ifdef __cplusplus + +#include "uac_control.h" + +class UACControlGraph : public UACControl { +public: + UACControlGraph(int mode); + virtual ~UACControlGraph(); + +public: + virtual int uacStart(); + virtual void uacStop(); + virtual void uacSetSampleRate(int sampleRate); + virtual void uacSetVolume(int volume); + virtual void uacSetMute(int mute); + virtual void uacSetPpm(int ppm); + +private: + void *mCtx; +}; +#endif +#endif // SRC_INCLUDE_UAC_CONTROL_GRAPH_H_ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_mpi.h b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_mpi.h new file mode 100644 index 000000000..99c43150d --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_mpi.h @@ -0,0 +1,49 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef SRC_INCLUDE_UAC_CONTROL_MPI_H_ +#define SRC_INCLUDE_UAC_CONTROL_MPI_H_ +#ifdef __cplusplus +#include "uac_control.h" + +class UACControlMpi : public UACControl { +public: + UACControlMpi(int mode); + virtual ~UACControlMpi(); + +public: + virtual int uacStart(); + virtual void uacStop(); + virtual void uacSetSampleRate(int sampleRate); + virtual void uacSetVolume(int volume); + virtual void uacSetMute(int mute); + virtual void uacSetPpm(int ppm); + +protected: + int startAi(); + int startVqe(); + int startAo(); + void streamBind(); + int stopAi(); + int stopVqe(); + int stopAo(); + void streamUnBind(); + +private: + void *mCtx; +}; +#endif +#endif // SRC_INCLUDE_UAC_CONTROL_MPI_H_ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_log.h b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_log.h new file mode 100644 index 000000000..d4b837d0a --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_log.h @@ -0,0 +1,63 @@ +// Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SRC_INCLUDE_UAC_LOGGER_H_ +#define SRC_INCLUDE_UAC_LOGGER_H_ +//#ifdef __cplusplus + +#ifdef uac_minilogGER +#include "minilogger/log.h" +#else +#include +#include +#include +#define uac_minilog_warn(...) +#define uac_minilog_error(...) +#define uac_minilog_info(...) +#define uac_minilog_debug(...) +#define __uac_minilog_log_init(...) +#endif + +extern int uac_app_log_level; + +#define LOG_LEVEL_ERROR 0 +#define LOG_LEVEL_WARN 1 +#define LOG_LEVEL_INFO 2 +#define LOG_LEVEL_DEBUG 3 + +#ifndef LOG_TAG +#define LOG_TAG "uac_app" +#endif + +#define ALOGI(format, ...) \ + do { \ + if (uac_app_log_level < LOG_LEVEL_INFO) \ + break; \ + \ fprintf(stderr, "[%s][%s]:" format, LOG_TAG, __FUNCTION__, \ + ##__VA_ARGS__); \ + } while (0) + +#define ALOGW(format, ...) \ + do { \ + if (uac_app_log_level < LOG_LEVEL_WARN) \ + break; \ + \ fprintf(stderr, "[%s][%s]:" format, LOG_TAG, __FUNCTION__, \ + ##__VA_ARGS__); \ + } while (0) + +#define ALOGE(format, ...) \ + do { \ + if (uac_app_log_level < LOG_LEVEL_ERROR) \ + break; \ + fprintf(stderr, "[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \ + } while (0) + +#define ALOGD(format, ...) \ + do { \ + if (uac_app_log_level < LOG_LEVEL_DEBUG) \ + break; \ + fprintf(stderr, "[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \ + } while (0) +//#endif +#endif // SRC_INCLUDE_UAC_LOGGER_H_ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_uevent.h b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_uevent.h new file mode 100644 index 000000000..1148bb5b9 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_uevent.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef SRC_INCLUDE_UEVENT_H_ +#define SRC_INCLUDE_UEVENT_H_ + +#include +#include +#include + +struct _uevent { + char *strs[30]; + int size; +}; +#ifdef __cplusplus +extern "C" { +#endif +int uac_uevent_monitor_run(); +#ifdef __cplusplus +} +#endif + +#endif // SRC_INCLUDE_UEVENT_H_ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/mpi/uac_control_mpi.cpp b/project/app/uvc_app_tiny/uvc_app/uac/src/mpi/uac_control_mpi.cpp new file mode 100644 index 000000000..80082e9bf --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/mpi/uac_control_mpi.cpp @@ -0,0 +1,536 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +//#ifdef __cplusplus + +#include "uac_control_mpi.h" +#include "mpi_control_common.h" +#include "uac_amixer.h" +#include "uac_log.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#define LOG_TAG "uac_mpi" +#endif + +#define OPEN_VQE 1 + +typedef struct _UacControlMpi { + int mode; + UacMpiStream stream; +} UacControlMpi; + +UacControlMpi *getContextMpi(void *context) { + UacControlMpi *ctx = reinterpret_cast(context); + return ctx; +} + +UACControlMpi::UACControlMpi(int mode) { + UacControlMpi *ctx = (UacControlMpi *)calloc(1, sizeof(UacControlMpi)); + memset(ctx, 0, sizeof(UacControlMpi)); + + ctx->mode = mode; + ctx->stream.config.intVol = 100; + ctx->stream.config.mute = 0; + ctx->stream.config.ppm = 0; + + if (mode == UAC_STREAM_PLAYBACK) { + ctx->stream.idCfg.aiDevId = (AUDIO_DEV)AI_MIC_DEV; + ctx->stream.idCfg.aoDevId = (AUDIO_DEV)AO_USB_DEV; + ctx->stream.config.samplerate = + UacMpiUtil::getDataSamplerate(UAC_MPI_TYPE_AO, ctx->mode); + } else if (mode == UAC_STREAM_RECORD) { + ctx->stream.idCfg.aiDevId = (AUDIO_DEV)AI_USB_DEV; + ctx->stream.idCfg.aoDevId = (AUDIO_DEV)AO_SPK_DEV; + ctx->stream.config.samplerate = + UacMpiUtil::getDataSamplerate(UAC_MPI_TYPE_AI, ctx->mode); + + // always set index of spk's sound card(hw:0,0) + amix_set_ref_mode(MIC_SPK_SOUNDCARD_INDEX); + } + + mCtx = reinterpret_cast(ctx); +} + +UACControlMpi::~UACControlMpi() { + UacControlMpi *ctx = getContextMpi(mCtx); + if (ctx) { + free(ctx); + } + + mCtx = NULL; +} + +void UACControlMpi::uacSetSampleRate(int sampleRate) { + UacControlMpi *ctx = getContextMpi(mCtx); + ctx->stream.config.samplerate = sampleRate; + ALOGD("mode = %d, sampleRate = %d\n", ctx->mode, sampleRate); + if ((ctx->stream.flag &= UAC_MPI_ENABLE) == UAC_MPI_ENABLE) { + mpi_set_samplerate(ctx->mode, ctx->stream); + } +} + +void UACControlMpi::uacSetVolume(int volume) { + UacControlMpi *ctx = getContextMpi(mCtx); + ALOGD("mode = %d, volume = %d\n", ctx->mode, volume); + ctx->stream.config.intVol = volume; + if ((ctx->stream.flag &= UAC_MPI_ENABLE) == UAC_MPI_ENABLE) { + mpi_set_volume(ctx->mode, ctx->stream); + } +} + +void UACControlMpi::uacSetMute(int mute) { + UacControlMpi *ctx = getContextMpi(mCtx); + ALOGD("mode = %d, mute = %d\n", ctx->mode, mute); + ctx->stream.config.mute = mute; + if ((ctx->stream.flag &= UAC_MPI_ENABLE) == UAC_MPI_ENABLE) { + mpi_set_volume(ctx->mode, ctx->stream); + } +} + +void UACControlMpi::uacSetPpm(int ppm) { + ALOGD("ppm = %d\n", ppm); + UacControlMpi *ctx = getContextMpi(mCtx); + ctx->stream.config.ppm = ppm; + if ((ctx->stream.flag &= UAC_MPI_ENABLE) == UAC_MPI_ENABLE) { + mpi_set_ppm(ctx->mode, ctx->stream); + } +} + +int UACControlMpi::uacStart() { + uacStop(); + int ret = 0; + UacControlMpi *ctx = getContextMpi(mCtx); + ret = startAi(); + if (ret != 0) { + goto __FAILED; + } + + /* + * only add 3A process in playback(data flow: 1106's mic-->pc/host), + * do not add 3A process in record(data flow: pc/host-->1106's spk ) + * for avoid sound like music process by 3A + */ + if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) { + ret = startVqe(); + if (ret != 0) { + goto __FAILED; + } + } + + ret = startAo(); + if (ret != 0) { + goto __FAILED; + } + + mpi_set_samplerate(ctx->mode, ctx->stream); + mpi_set_volume(ctx->mode, ctx->stream); + mpi_set_ppm(ctx->mode, ctx->stream); + + streamBind(); + ctx->stream.flag |= UAC_MPI_ENABLE; + return 0; + +__FAILED: + return -1; +} + +void UACControlMpi::uacStop() { + UacControlMpi *ctx = getContextMpi(mCtx); + ALOGD("stop mode = %d, flag = %d\n", ctx->mode, ctx->stream.flag); + if ((ctx->stream.flag &= UAC_MPI_ENABLE) == UAC_MPI_ENABLE) { + streamUnBind(); + stopAi(); + if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) { + stopVqe(); + } + stopAo(); + ctx->stream.flag &= (~UAC_MPI_ENABLE); + } +} + +int UACControlMpi::startAi() { + UacControlMpi *ctx = getContextMpi(mCtx); + AUDIO_DEV aiDevId = ctx->stream.idCfg.aiDevId; + AI_CHN aiChn = ctx->stream.idCfg.aiChnId; + ALOGD("this:%p, startAi(dev:%d, chn:%d), mode : %d\n", this, aiDevId, aiChn, + ctx->mode); + const char *cardName = RK_NULL; + RK_S32 result = 0; + AUDIO_SAMPLE_RATE_E rate; + AIO_ATTR_S aiAttr; + memset(&aiAttr, 0, sizeof(AIO_ATTR_S)); + + cardName = UacMpiUtil::getSndCardName(UAC_MPI_TYPE_AI, ctx->mode); + snprintf(reinterpret_cast(aiAttr.u8CardName), + sizeof(aiAttr.u8CardName), "%s", cardName); + aiAttr.soundCard.channels = + UacMpiUtil::getSndCardChannels(UAC_MPI_TYPE_AI, ctx->mode); + aiAttr.soundCard.sampleRate = + UacMpiUtil::getSndCardSampleRate(UAC_MPI_TYPE_AI, ctx->mode); + aiAttr.soundCard.bitWidth = + UacMpiUtil::getSndCardbitWidth(UAC_MPI_TYPE_AI, ctx->mode); + + /* + * 1. if datas are sended from pc to uac device, the ai device is usb, + * we set the samplerate which uevent report. + * 2. if datas are sended from uac device to pc, the ai device is mic, + we use the a fix samplerate like 16000. + */ + if (ctx->mode == UAC_STREAM_PLAYBACK) { + if (OPEN_VQE) { + rate = (AUDIO_SAMPLE_RATE_E)UacMpiUtil::getVqeSampleRate(); + } else { + rate = (AUDIO_SAMPLE_RATE_E)UacMpiUtil::getSndCardSampleRate( + UAC_MPI_TYPE_AI, ctx->mode); + } + } else { + rate = (AUDIO_SAMPLE_RATE_E)ctx->stream.config.samplerate; + // update samplerate of usb cards which coming from uevent + aiAttr.soundCard.sampleRate = rate; + } + + aiAttr.enBitwidth = UacMpiUtil::getDataBitwidth(UAC_MPI_TYPE_AI, ctx->mode); + aiAttr.enSamplerate = rate; + aiAttr.enSoundmode = UacMpiUtil::getDataSoundmode(UAC_MPI_TYPE_AI, ctx->mode); + ALOGD("this:%p, startAi(dev:%d, chn:%d), enSamplerate : %d\n", this, aiDevId, + aiChn, aiAttr.enSamplerate); + aiAttr.u32FrmNum = 4; + aiAttr.u32PtNumPerFrm = 1024; + aiAttr.u32EXFlag = 0; + aiAttr.u32ChnCnt = 2; + result = RK_MPI_AI_SetPubAttr(aiDevId, &aiAttr); + if (result != 0) { + ALOGE("ai set attr(dev:%d) fail, reason = %x\n", aiDevId, result); + goto __FAILED; + } + + result = RK_MPI_AI_Enable(aiDevId); + if (result != 0) { + ALOGE("ai enable(dev:%d) fail, reason = %x\n", aiDevId, result); + goto __FAILED; + } + + result = RK_MPI_AI_EnableChn(aiDevId, aiChn); + if (result != 0) { + ALOGE("ai enable channel(dev:%d, chn:%d) fail, reason = %x\n", aiDevId, + aiChn, result); + return RK_FAILURE; + } + + /* + * If 3A filter is after ai, and the samplerate of ai's datas is not support + * by 3A, + * enable resample to convert the samplerate. + */ + if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) { + result = RK_MPI_AI_EnableReSmp(aiDevId, aiChn, aiAttr.enSamplerate); + if (result != 0) { + ALOGE("ai enable resample(dev:%d, chn:%d) fail, reason = %x\n", aiDevId, + aiChn, result); + return RK_FAILURE; + } + } else { + // disable resample in ai, this means the samplerate of output of ai is the + // samplerate of sound card + result = RK_MPI_AI_DisableReSmp(aiDevId, aiChn); + if (result != 0) { + ALOGE("ai disable resample(dev:%d, chn:%d) fail, reason = %x\n", aiDevId, + aiChn, result); + return RK_FAILURE; + } + } + return 0; +__FAILED: + return -1; +} + +// init 3A filter +int UACControlMpi::startVqe() { + UacControlMpi *ctx = getContextMpi(mCtx); + AF_CHN vqeChnId = ctx->stream.idCfg.vqeChnId; + RK_S32 result; + AF_ATTR_S attr; + ALOGD("this:%p, startVqe(chn:%d), mode : %d\n", this, vqeChnId, ctx->mode); + memset(&attr, 0, sizeof(AF_ATTR_S)); + + attr.enType = AUDIO_FILTER_3A; + attr.u32InBufCount = 2; + attr.u32OutBufCount = 2; + + snprintf(reinterpret_cast(attr.st3AAttr.cfgPath), + sizeof(attr.st3AAttr.cfgPath), "%s", UacMpiUtil::getVqeCfgPath()); + attr.st3AAttr.u32SampleRate = UacMpiUtil::getVqeSampleRate(); + attr.st3AAttr.enBitWidth = AUDIO_BIT_WIDTH_16; + attr.st3AAttr.u32Channels = UacMpiUtil::getVqeChannels(); + attr.st3AAttr.u32ChnLayout = UacMpiUtil::getVqeChnLayout(); + attr.st3AAttr.u32RecLayout = UacMpiUtil::getVqeMicLayout(); + attr.st3AAttr.u32RefLayout = UacMpiUtil::getVqeRefLayout(); + result = RK_MPI_AF_Create(vqeChnId, &attr); + if (result != RK_SUCCESS) { + ALOGE("create af vqe(chn:%d) fail, reason = %x\n", vqeChnId, result); + return RK_FAILURE; + } + + return 0; +__FAILED: + return -1; +} + +int UACControlMpi::startAo() { + UacControlMpi *ctx = getContextMpi(mCtx); + AUDIO_DEV aoDevId = ctx->stream.idCfg.aoDevId; + AO_CHN aoChn = ctx->stream.idCfg.aoChnId; + ALOGD("this:%p, startAo(dev:%d, chn:%d), mode : %d\n", this, aoDevId, aoChn, + ctx->mode); + const char *cardName = RK_NULL; + RK_S32 result; + AIO_ATTR_S aoAttr; + AUDIO_SAMPLE_RATE_E rate; + AUDIO_SOUND_MODE_E soundMode; + memset(&aoAttr, 0, sizeof(AIO_ATTR_S)); + + cardName = UacMpiUtil::getSndCardName(UAC_MPI_TYPE_AO, ctx->mode); + snprintf(reinterpret_cast(aoAttr.u8CardName), + sizeof(aoAttr.u8CardName), "%s", cardName); + + /* + * 1. if datas is from pc to uac device, the ao device is spk, + we use the a fix samplerate like 48000. + * 2. if datas is from uac device to pc, the ao device is usb, + * we set the samplerate which uevent report. + */ + if (ctx->mode == UAC_STREAM_RECORD) { + rate = (AUDIO_SAMPLE_RATE_E)UacMpiUtil::getSndCardSampleRate( + UAC_MPI_TYPE_AO, ctx->mode); + } else { + rate = (AUDIO_SAMPLE_RATE_E)ctx->stream.config.samplerate; + } + + aoAttr.soundCard.channels = + UacMpiUtil::getSndCardChannels(UAC_MPI_TYPE_AO, ctx->mode); + aoAttr.soundCard.sampleRate = rate; + aoAttr.soundCard.bitWidth = + UacMpiUtil::getSndCardbitWidth(UAC_MPI_TYPE_AO, ctx->mode); + + aoAttr.enBitwidth = UacMpiUtil::getDataBitwidth(UAC_MPI_TYPE_AO, ctx->mode); + if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) { + rate = (AUDIO_SAMPLE_RATE_E)UacMpiUtil::getVqeSampleRate(); + } + aoAttr.enSamplerate = rate; + soundMode = UacMpiUtil::getDataSoundmode(UAC_MPI_TYPE_AO, ctx->mode); + if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) { + soundMode = AUDIO_SOUND_MODE_MONO; + } + aoAttr.enSoundmode = soundMode; + ALOGD("this:%p, startAo(dev:%d, chn:%d), mode : %d, enSamplerate = %d\n", + this, aoDevId, aoChn, ctx->mode, aoAttr.enSamplerate); + aoAttr.u32FrmNum = 4; + aoAttr.u32PtNumPerFrm = 1024; + aoAttr.u32EXFlag = 0; + aoAttr.u32ChnCnt = 2; + result = RK_MPI_AO_SetPubAttr(aoDevId, &aoAttr); + if (result != 0) { + ALOGE("ao set attr(dev:%d) fail, reason = %x\n", aoDevId, result); + goto __FAILED; + } + + result = RK_MPI_AO_Enable(aoDevId); + if (result != 0) { + ALOGE("ao enable(dev:%d) fail, reason = %x\n", aoDevId, result); + goto __FAILED; + } + + result = RK_MPI_AO_EnableChn(aoDevId, aoChn); + if (result != 0) { + ALOGE("ao enable channel(dev:%d, chn:%d) fail, reason = %x\n", aoDevId, + aoChn, result); + return RK_FAILURE; + } + + result = RK_MPI_AO_EnableReSmp(aoDevId, aoChn, aoAttr.enSamplerate); + if (result != 0) { + ALOGE("ao enable resample(dev:%d, chn:%d) fail, reason = %x\n", aoDevId, + aoChn, result); + return RK_FAILURE; + } + + if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) { + result = RK_MPI_AO_SetTrackMode(aoDevId, AUDIO_TRACK_OUT_STEREO); + if (result != 0) { + ALOGE("ao enable track mode(dev:%d, chn:%d) fail, reason = %x\n", aoDevId, + aoChn, result); + return RK_FAILURE; + } + } + return 0; +__FAILED: + return -1; +} + +void UACControlMpi::streamBind() { + UacControlMpi *ctx = getContextMpi(mCtx); + MPP_CHN_S stSrcChn, stDstChn; + // have af, the data flow is ai-->af-->ao + if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) { + // ai bind af, this means data from ai to af + stSrcChn.enModId = RK_ID_AI; + stSrcChn.s32DevId = ctx->stream.idCfg.aiDevId; + stSrcChn.s32ChnId = ctx->stream.idCfg.aiChnId; + + stDstChn.enModId = RK_ID_AF; + stDstChn.s32DevId = 0; + stDstChn.s32ChnId = ctx->stream.idCfg.vqeChnId; + ALOGD("AiBindVqe(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode, + stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId, + stDstChn.s32ChnId); + RK_MPI_SYS_Bind(&stSrcChn, &stDstChn); + + // af bind ao, this means data from af to ao + stSrcChn.enModId = RK_ID_AF; + stSrcChn.s32DevId = 0; + stSrcChn.s32ChnId = ctx->stream.idCfg.vqeChnId; + + stDstChn.enModId = RK_ID_AO; + stDstChn.s32DevId = ctx->stream.idCfg.aoDevId; + stDstChn.s32ChnId = ctx->stream.idCfg.aoChnId; + ALOGD("VqeBindAo(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode, + stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId, + stDstChn.s32ChnId); + RK_MPI_SYS_Bind(&stSrcChn, &stDstChn); + } else { + // no af, the data flow is ai-->ao + stSrcChn.enModId = RK_ID_AI; + stSrcChn.s32DevId = ctx->stream.idCfg.aiDevId; + stSrcChn.s32ChnId = ctx->stream.idCfg.aiChnId; + + stDstChn.enModId = RK_ID_AO; + stDstChn.s32DevId = ctx->stream.idCfg.aoDevId; + stDstChn.s32ChnId = ctx->stream.idCfg.aoChnId; + ALOGD("AiBindAO(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode, + stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId, + stDstChn.s32ChnId); + RK_MPI_SYS_Bind(&stSrcChn, &stDstChn); + } +} + +int UACControlMpi::stopAi() { + UacControlMpi *ctx = getContextMpi(mCtx); + AUDIO_DEV aiDevId = ctx->stream.idCfg.aiDevId; + AI_CHN aiChn = ctx->stream.idCfg.aiChnId; + ALOGD("this:%p, stopAi(dev:%d, chn:%d), mode : %d\n", this, aiDevId, aiChn, + ctx->mode); + RK_MPI_AI_DisableReSmp(aiDevId, aiChn); + RK_S32 result = RK_MPI_AI_DisableChn(aiDevId, aiChn); + if (result != 0) { + ALOGE("ai disable channel(dev:%d, chn:%d) fail, reason = %x\n", aiDevId, + aiChn, result); + return RK_FAILURE; + } + + result = RK_MPI_AI_Disable(aiDevId); + if (result != 0) { + ALOGE("ai disable(dev:%d) fail, reason = %x\n", aiDevId, result); + return RK_FAILURE; + } + + return 0; +__FAILED: + return -1; +} + +int UACControlMpi::stopVqe() { + UacControlMpi *ctx = getContextMpi(mCtx); + AF_CHN vqeChn = ctx->stream.idCfg.vqeChnId; + ALOGD("this:%p, stopVqe(chn:%d), mode : %d\n", this, vqeChn, ctx->mode); + RK_S32 result = RK_MPI_AF_Destroy(vqeChn); + if (result != 0) { + ALOGE("vqe disable(dev:%d) fail, reason = %x\n", vqeChn, result); + return RK_FAILURE; + } + + return 0; +__FAILED: + return -1; +} + +int UACControlMpi::stopAo() { + UacControlMpi *ctx = getContextMpi(mCtx); + AUDIO_DEV aoDevId = ctx->stream.idCfg.aoDevId; + AO_CHN aoChn = ctx->stream.idCfg.aoChnId; + ALOGD("this:%p, stopAo(dev:%d, chn:%d), mode : %d\n", this, aoDevId, aoChn, + ctx->mode); + RK_MPI_AO_DisableReSmp(aoDevId, aoChn); + RK_S32 result = RK_MPI_AO_DisableChn(aoDevId, aoChn); + if (result != 0) { + ALOGE("ao disable channel(dev:%d, chn:%d) fail, reason = %x\n", aoDevId, + aoChn, result); + return RK_FAILURE; + } + + result = RK_MPI_AO_Disable(aoDevId); + if (result != 0) { + ALOGE("ao disable(dev:%d) fail, reason = %x\n", aoDevId, result); + return RK_FAILURE; + } + + return 0; +__FAILED: + return -1; +} + +void UACControlMpi::streamUnBind() { + UacControlMpi *ctx = getContextMpi(mCtx); + MPP_CHN_S stSrcChn, stDstChn; + if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) { + stSrcChn.enModId = RK_ID_AI; + stSrcChn.s32DevId = ctx->stream.idCfg.aiDevId; + stSrcChn.s32ChnId = ctx->stream.idCfg.aiChnId; + + stDstChn.enModId = RK_ID_AF; + stDstChn.s32DevId = 0; + stDstChn.s32ChnId = ctx->stream.idCfg.vqeChnId; + ALOGD("AiUnBindVqe(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode, + stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId, + stDstChn.s32ChnId); + RK_MPI_SYS_UnBind(&stSrcChn, &stDstChn); + + stSrcChn.enModId = RK_ID_AF; + stSrcChn.s32DevId = 0; + stSrcChn.s32ChnId = ctx->stream.idCfg.vqeChnId; + + stDstChn.enModId = RK_ID_AO; + stDstChn.s32DevId = ctx->stream.idCfg.aoDevId; + stDstChn.s32ChnId = ctx->stream.idCfg.aoChnId; + ALOGD("VqeUnBindAo(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode, + stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId, + stDstChn.s32ChnId); + RK_MPI_SYS_UnBind(&stSrcChn, &stDstChn); + } else { + stSrcChn.enModId = RK_ID_AI; + stSrcChn.s32DevId = ctx->stream.idCfg.aiDevId; + stSrcChn.s32ChnId = ctx->stream.idCfg.aiChnId; + + stDstChn.enModId = RK_ID_AO; + stDstChn.s32DevId = ctx->stream.idCfg.aoDevId; + stDstChn.s32ChnId = ctx->stream.idCfg.aoChnId; + ALOGD("AiUnBindAO(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode, + stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId, + stDstChn.s32ChnId); + RK_MPI_SYS_UnBind(&stSrcChn, &stDstChn); + } +} +//#endif \ No newline at end of file diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/mpi_common/mpi_control_common.cpp b/project/app/uvc_app_tiny/uvc_app/uac/src/mpi_common/mpi_control_common.cpp new file mode 100755 index 000000000..d55e5fd58 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/mpi_common/mpi_control_common.cpp @@ -0,0 +1,174 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +//#ifdef __cplusplus + +#include "mpi_control_common.h" +#include "uac_amixer.h" +#include "uac_log.h" +#include "uac_log.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#define LOG_TAG "mpi_contol_comm" +#endif + +typedef struct _MpiAioDeviceAttrConfigMap { + UacMpiType mpiType; + int uacMode; + + const char *sndCardname; + RK_U32 sndCardChannels; + RK_U32 sndCardSampleRate; + AUDIO_BIT_WIDTH_E sndCardbitWidth; + + RK_U32 dataSamplerate; + AUDIO_BIT_WIDTH_E dataBitwidth; + AUDIO_SOUND_MODE_E dataSoundmode; +} MpiAioDeviceAttrConfigMap; + +const static MpiAioDeviceAttrConfigMap sAioDevAttrCfgs[] = { + // usb + {UAC_MPI_TYPE_AI, UAC_STREAM_RECORD, "hw:1,0", 2, 44100, AUDIO_BIT_WIDTH_16, + 44100, AUDIO_BIT_WIDTH_16, AUDIO_SOUND_MODE_STEREO}, + // mic + {UAC_MPI_TYPE_AI, UAC_STREAM_PLAYBACK, "hw:0,0", 2, 16000, + AUDIO_BIT_WIDTH_16, 16000, AUDIO_BIT_WIDTH_16, AUDIO_SOUND_MODE_STEREO}, + // spk + {UAC_MPI_TYPE_AO, UAC_STREAM_RECORD, "hw:0,0", 2, 16000, AUDIO_BIT_WIDTH_16, + 16000, AUDIO_BIT_WIDTH_16, AUDIO_SOUND_MODE_STEREO}, + // usb + {UAC_MPI_TYPE_AO, UAC_STREAM_PLAYBACK, "hw:1,0", 2, 44100, + AUDIO_BIT_WIDTH_16, 44100, AUDIO_BIT_WIDTH_16, AUDIO_SOUND_MODE_STEREO}, +}; + +const static char *sAfVqeCfgPath = "/oem/usr/share/uac_app/configs_skv.json"; +#define VQE_SAMPLERATE 16000 +RK_U32 UacMpiUtil::getSndCardSampleRate(UacMpiType type, int mode) { + GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode, + sndCardSampleRate); + return 0; +} + +const char *UacMpiUtil::getSndCardName(UacMpiType type, int mode) { + GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode, sndCardname); + return NULL; +} + +RK_U32 UacMpiUtil::getSndCardChannels(UacMpiType type, int mode) { + GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode, + sndCardChannels); + return 0; +} + +AUDIO_BIT_WIDTH_E UacMpiUtil::getSndCardbitWidth(UacMpiType type, int mode) { + GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode, + sndCardbitWidth); + return AUDIO_BIT_WIDTH_BUTT; +} + +RK_U32 UacMpiUtil::getDataSamplerate(UacMpiType type, int mode) { + GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode, + dataSamplerate); + return 0; +} + +AUDIO_BIT_WIDTH_E UacMpiUtil::getDataBitwidth(UacMpiType type, int mode) { + GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode, dataBitwidth); + return AUDIO_BIT_WIDTH_BUTT; +} + +AUDIO_SOUND_MODE_E UacMpiUtil::getDataSoundmode(UacMpiType type, int mode) { + GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode, dataSoundmode); + return AUDIO_SOUND_MODE_BUTT; +} + +const char *UacMpiUtil::getVqeCfgPath() { return sAfVqeCfgPath; } + +RK_U32 UacMpiUtil::getVqeSampleRate() { return VQE_SAMPLERATE; } + +RK_U32 UacMpiUtil::getVqeChannels() { + return sChnAttrCfgs[sRefMode].u32Channels; +} + +RK_U32 UacMpiUtil::getVqeChnLayout() { + RK_U32 layout = + sChnAttrCfgs[sRefMode].u32MicLayout + sChnAttrCfgs[sRefMode].u32RefLayout; + return layout; +} + +RK_U32 UacMpiUtil::getVqeRefLayout() { + return sChnAttrCfgs[sRefMode].u32RefLayout; +} + +RK_U32 UacMpiUtil::getVqeMicLayout() { + return sChnAttrCfgs[sRefMode].u32MicLayout; +} + +void mpi_set_samplerate(int type, UacMpiStream &streamCfg) { + int sampleRate = streamCfg.config.samplerate; + if (sampleRate == 0) + return; + AUDIO_DEV aiDevId = streamCfg.idCfg.aiDevId; + AI_CHN aiChn = streamCfg.idCfg.aiChnId; + AUDIO_DEV aoDevId = streamCfg.idCfg.aoDevId; + AO_CHN aoChn = streamCfg.idCfg.aoChnId; + ALOGD("type = %d, sampleRate = %d\n", type, sampleRate); + /* + * 1. for usb capture, we update audio config to capture + * 2. for usb playback, if there is resample before usb playback, + * we set audio config to this resample, the new config will + * pass to usb playback from resample to usb playback when + * the datas move from resample to usb. + * 3. we alway use samperate=48K to open mic and speaker, + * because usually, they use the same group i2s, and + * not allowned to use diffrent samplerate. + */ + if (type == UAC_STREAM_RECORD) { + // the usb record always the first node + AI_CHN_ATTR_S params; + memset(¶ms, 0, sizeof(AI_CHN_ATTR_S)); + params.u32SampleRate = sampleRate; + params.enChnAttr = AUDIO_CHN_ATTR_RATE; + RK_MPI_AI_SetChnAttr(aiDevId, aiChn, ¶ms); + } else { + // find the resample before usb playback + AO_CHN_ATTR_S params; + memset(¶ms, 0, sizeof(AO_CHN_ATTR_S)); + params.u32SampleRate = sampleRate; + params.enChnAttr = AUDIO_CHN_ATTR_RATE; + RK_MPI_AO_SetChnAttr(aoDevId, aoChn, ¶ms); + } +} + +void mpi_set_volume(int type, UacMpiStream &streamCfg) { + int mute = streamCfg.config.mute; + int volume = streamCfg.config.intVol; + AUDIO_DEV aoDevId = streamCfg.idCfg.aoDevId; + ALOGD("type = %d, mute = %d, volume = %d\n", type, mute, volume); + AUDIO_FADE_S aFade; + memset(&aFade, 0, sizeof(AUDIO_FADE_S)); + + RK_BOOL bMute = (mute == 0) ? RK_FALSE : RK_TRUE; + RK_MPI_AO_SetMute(aoDevId, bMute, &aFade); + RK_MPI_AO_SetVolume(aoDevId, volume); +} + +void mpi_set_ppm(int type, UacMpiStream &streamCfg) { + int ppm = streamCfg.config.ppm; + amix_set_ppm(MIC_SPK_SOUNDCARD_INDEX, ppm); +} +//#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/mpi_common/uac_amixer.cpp b/project/app/uvc_app_tiny/uvc_app/uac/src/mpi_common/uac_amixer.cpp new file mode 100644 index 000000000..187ed164f --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/mpi_common/uac_amixer.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "uac_amixer.h" +#include "rk_mpi_amix.h" +#include "uac_log.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#define LOG_TAG "amixer" +#endif + +const static char *sRefCtrlName = "I2STDM Digital Loopback Mode"; +const static char *sPpmCtrlName = "PCM Clk Compensation In PPM"; + +RK_S32 UACAmixer::set(AUDIO_DEV AmixDevId, const char *ctrlName, + const char *value) { + ALOGD("AmixDevId = %d, ctrl = %s, value = %s", AmixDevId, ctrlName, value); + return RK_MPI_AMIX_SetControl(AmixDevId, ctrlName, (char *)value); +} + +RK_S32 UACAmixer::get(AUDIO_DEV AmixDevId, const char *ctrlName) { + return RK_MPI_AMIX_GetControl(AmixDevId, ctrlName, NULL); +} + +void UACAmixer::dumpContents(AUDIO_DEV AmixDevId) { + RK_MPI_AMIX_ListContents(AmixDevId); +} + +RK_S32 amix_set_ref_mode(AUDIO_DEV AoDevId) { + return UACAmixer::set(AoDevId, sRefCtrlName, sChnAttrCfgs[sRefMode].chMode); +} + +RK_S32 amix_set_ppm(AUDIO_DEV AoDevId, RK_S32 ppm) { + char str[64]; + snprintf(str, sizeof(str), "%d", ppm); + return UACAmixer::set(AoDevId, sPpmCtrlName, str); +} diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/uac_common_def.cpp b/project/app/uvc_app_tiny/uvc_app/uac/src/uac_common_def.cpp new file mode 100644 index 000000000..65cc7d437 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/uac_common_def.cpp @@ -0,0 +1,30 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +//#ifdef __cplusplus +#include "uac_common_def.h" + +uint64_t getRelativeTimeMs() { + return getRelativeTimeUs() / 1000; /* milliseconds */ +} + +uint64_t getRelativeTimeUs() { + struct timespec time = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &time); + return (uint64_t)time.tv_sec * 1000000LL + + (uint64_t)time.tv_nsec / 1000; /* microseconds */ +} +//#endif \ No newline at end of file diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/uac_control.cpp b/project/app/uvc_app_tiny/uvc_app/uac/src/uac_control.cpp new file mode 100644 index 000000000..4aafd7ac4 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/uac_control.cpp @@ -0,0 +1,147 @@ +/* + * Copyright 2020 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +//#ifdef __cplusplus + +#include "uac_control.h" +#include "uac_control_factory.h" +#include "uac_log.h" +#ifdef UAC_MPI +#include "mpi_control_common.h" +#endif + +int uac_app_log_level; + +typedef struct _UacControls { + int mode; + UACControl *uac; + pthread_mutex_t mutex; +} UacControls; + +static UacControls *gUAControl = NULL; +int uac_control_create(int type) { + int i = 0; + char *ch = NULL; + if (type == UAC_API_GRAPH) { + ch = (char *)"graph"; + } else if (type == UAC_API_MPI) { + ch = (char *)"mpi"; + } + + ALOGD("-------------uac use %s--------------\n", ch); + if (!gUAControl) { + uac_control_destory(); + } + + gUAControl = (UacControls *)calloc(UAC_STREAM_MAX, sizeof(UacControls)); + if (!gUAControl) { + ALOGE("fail to malloc memory!\n"); + return -1; + } + + memset(gUAControl, 0, sizeof(UacControls)); + for (i = 0; i < UAC_STREAM_MAX; i++) { + gUAControl[i].mode = i; + pthread_mutex_init(&gUAControl[i].mutex, NULL); + + gUAControl[i].uac = UacControlFactory::create((UacApiType)type, i); + if (!gUAControl[i].uac) { + uac_control_destory(); + return -1; + } + } + + return 0; +} + +void uac_control_destory() { + if (gUAControl == NULL) + return; + + int i = 0; + UACControl *uac = NULL; + if (gUAControl) { + for (i = 0; i < UAC_STREAM_MAX; i++) { + uac = gUAControl[i].uac; + if (uac) + delete uac; + gUAControl[i].uac = NULL; + pthread_mutex_destroy(&gUAControl[i].mutex); + } + } + + free(gUAControl); + gUAControl = NULL; +} + +UacControls *getControlContext(int mode) { return &gUAControl[mode]; } + +int uac_start(int mode) { + int ret = 0; + UacControls *uacs = getControlContext(mode); + pthread_mutex_lock(&uacs->mutex); + if (mode == uacs->mode) { + ret = uacs->uac->uacStart(); + } + pthread_mutex_unlock(&uacs->mutex); + return ret; +} + +void uac_stop(int mode) { + UacControls *uacs = getControlContext(mode); + pthread_mutex_lock(&uacs->mutex); + if (mode == uacs->mode) { + uacs->uac->uacStop(); + } + pthread_mutex_unlock(&uacs->mutex); +} + +void uac_set_sample_rate(int mode, int samplerate) { + UacControls *uacs = getControlContext(mode); + pthread_mutex_lock(&uacs->mutex); + if (mode == uacs->mode) { + uacs->uac->uacSetSampleRate(samplerate); + } + pthread_mutex_unlock(&uacs->mutex); +} + +void uac_set_volume(int mode, int volume) { + UacControls *uacs = getControlContext(mode); + pthread_mutex_lock(&uacs->mutex); + if (mode == uacs->mode) { + uacs->uac->uacSetVolume(volume); + } + pthread_mutex_unlock(&uacs->mutex); +} + +void uac_set_mute(int mode, int mute) { + UacControls *uacs = getControlContext(mode); + pthread_mutex_lock(&uacs->mutex); + if (mode == uacs->mode) { + uacs->uac->uacSetMute(mute); + } + pthread_mutex_unlock(&uacs->mutex); +} + +void uac_set_ppm(int mode, int ppm) { + UacControls *uacs = getControlContext(mode); + pthread_mutex_lock(&uacs->mutex); + if (mode == uacs->mode) { + uacs->uac->uacSetPpm(ppm); + } + pthread_mutex_unlock(&uacs->mutex); +} +//#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/uac_control_factory.cpp b/project/app/uvc_app_tiny/uvc_app/uac/src/uac_control_factory.cpp new file mode 100644 index 000000000..9cd26d119 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/uac_control_factory.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2022 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +//#ifdef __cplusplus + +#include "uac_control_factory.h" +#include "uac_control_graph.h" +#include "uac_control_mpi.h" +#include "uac_log.h" + +UACControl *createUacGraph(int mode) { + UACControl *uac = NULL; +#ifdef UAC_GRAPH + uac = new UACControlGraph(mode); +#endif + return uac; +} + +UACControl *createUacMpi(int mode) { + UACControl *uac = NULL; +#ifdef UAC_MPI + uac = new UACControlMpi(mode); +#endif + return uac; +} + +UACControl *UacControlFactory::create(UacApiType type, int mode) { + UACControl *uac = NULL; + switch (type) { + case UAC_API_MPI: + uac = createUacMpi(mode); + break; + case UAC_API_GRAPH: + uac = createUacGraph(mode); + break; + default: + ALOGD("unkown UacApiType(%d), please check!\n", type); + break; + } + + return uac; +} +//#endif \ No newline at end of file diff --git a/project/app/uvc_app_tiny/uvc_app/uac/src/uac_uevent.cpp b/project/app/uvc_app_tiny/uvc_app/uac/src/uac_uevent.cpp new file mode 100644 index 000000000..c3b19ad08 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/src/uac_uevent.cpp @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +//#ifdef __cplusplus + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "uac_control.h" +#include "uac_log.h" +#include "uac_uevent.h" +#include +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#define LOG_TAG "audio_event" +#endif + +/* + * case 1: + * the UAC1 uevent when pc/remote close(play sound of usb close) + * + * strs[0] = ACTION=change + * strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0 // UAC2_Gadget + * strs[2] = SUBSYSTEM=u_audio + * strs[3] = USB_STATE=SET_INTERFACE + * strs[4] = STREAM_DIRECTION=OUT + * strs[5] = STREAM_STATE=OFF + * + * + * case 2: + * the UAC1 uevent when pc/remote play start(play sound of usb open) + * + * strs[0] = ACTION=change + * strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0 + * strs[2] = SUBSYSTEM=u_audio + * strs[3] = USB_STATE=SET_INTERFACE + * strs[4] = STREAM_DIRECTION=OUT + * strs[5] = STREAM_STATE=ON + * + * + * case 3: + * the UAC1 uevent when pc/remote capture start(record sound of usb open) + * + * strs[0] = ACTION=change + * strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0 + * strs[2] = SUBSYSTEM=u_audio + * strs[3] = USB_STATE=SET_INTERFACE + * strs[4] = STREAM_DIRECTION=IN + * strs[5] = STREAM_STATE=ON + * + * + * case 4: + * the UAC1 uevent when pc/remote capture stop(record sound of usb open) + * + * strs[0] = ACTION=change + * strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0 + * strs[2] = SUBSYSTEM=u_audio + * strs[3] = USB_STATE=SET_INTERFACE + * strs[4] = STREAM_DIRECTION=IN + * strs[5] = STREAM_STATE=OFF + * + * + * case 5: + * the UAC1 uevent + * + * strs[0] = ACTION=change + * strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0 + * strs[2] = SUBSYSTEM=u_audio + * strs[3] = USB_STATE=SET_SAMPLE_RATE + * strs[4] = STREAM_DIRECTION=IN + * strs[5] = SAMPLE_RATE=48000 + */ +#define UAC_UEVENT_AUDIO "SUBSYSTEM=u_audio" +#define UAC_UEVENT_SET_INTERFACE "USB_STATE=SET_INTERFACE" +#define UAC_UEVENT_SET_SAMPLE_RATE "USB_STATE=SET_SAMPLE_RATE" +#define UAC_UEVENT_SET_VOLUME "USB_STATE=SET_VOLUME" +#define UAC_UEVENT_SET_MUTE "USB_STATE=SET_MUTE" +#define UAC_UEVENT_SET_AUDIO_CLK "USB_STATE=SET_AUDIO_CLK" + +#define UAC_STREAM_DIRECT "STREAM_DIRECTION=" +#define UAC_STREAM_STATE "STREAM_STATE=" +#define UAC_SAMPLE_RATE "SAMPLE_RATE=" +#define UAC_SET_VOLUME "VOLUME=" +#define UAC_SET_MUTE "MUTE=" +#define UAC_PPM "PPM=" + +// remote device/pc->our device +#define UAC_REMOTE_PLAY "OUT" + +// our device->remote device/pc +#define UAC_REMOTE_CAPTURE "IN" + +// sound card is opened +#define UAC_STREAM_START "ON" + +// sound card is closed +#define UAC_STREAM_STOP "OFF" + +enum UAC_UEVENT_KEY { + UAC_KEY_AUDIO = 2, + UAC_KEY_USB_STATE = 3, + UAC_KEY_DIRECTION = 4, + UAC_KEY_PPM = 4, + UAC_KEY_STREAM_STATE = 5, + UAC_KEY_SAMPLE_RATE = UAC_KEY_STREAM_STATE, + UAC_KEY_VOLUME = UAC_KEY_STREAM_STATE, + UAC_KEY_MUTE = UAC_KEY_STREAM_STATE, +}; + +bool compare(const char *dst, const char *srt) { + if ((dst == NULL) || (srt == NULL)) + return false; + + if (!strncmp(dst, srt, strlen(srt))) { + return true; + } + + return false; +} + +void audio_play(const struct _uevent *uevent) { + char *direct = uevent->strs[UAC_KEY_DIRECTION]; + char *status = uevent->strs[UAC_KEY_STREAM_STATE]; + + if (compare(direct, UAC_STREAM_DIRECT) && compare(status, UAC_STREAM_STATE)) { + char *device = &direct[strlen(UAC_STREAM_DIRECT)]; + char *state = &status[strlen(UAC_STREAM_STATE)]; + // remote device/pc open/close usb sound card to write data + if (compare(device, UAC_REMOTE_PLAY)) { + if (compare(UAC_STREAM_START, state)) { + // stream start, we need to open usb card to record datas + ALOGD("remote device/pc start to play data to us, we need to open usb " + "to capture datas\n"); + uac_start(UAC_STREAM_RECORD); + } else if (compare(UAC_STREAM_STOP, state)) { + ALOGD("remote device/pc stop to play data to us, we need to stop " + "capture datas\n"); + uac_stop(UAC_STREAM_RECORD); + } + } else if (compare(device, UAC_REMOTE_CAPTURE)) { + // our device->remote device/pc + if (compare(UAC_STREAM_START, state)) { + // stream start, we need to open usb card to record datas + ALOGD("remote device/pc start to record from us, we need to open usb " + "to send datas\n"); + uac_start(UAC_STREAM_PLAYBACK); + } else if (compare(UAC_STREAM_STOP, state)) { + ALOGD("remote device/pc stop to record from us, we need to stop write " + "datas to usb\n"); + uac_stop(UAC_STREAM_PLAYBACK); + } + } + } +} + +void audio_set_samplerate(const struct _uevent *uevent) { + char *direct = uevent->strs[UAC_KEY_DIRECTION]; + char *samplerate = uevent->strs[UAC_KEY_SAMPLE_RATE]; + ALOGD("%s: %s\n", __FUNCTION__, direct); + ALOGD("%s: %s\n", __FUNCTION__, samplerate); + if (compare(direct, UAC_STREAM_DIRECT)) { + char *device = &direct[strlen(UAC_STREAM_DIRECT)]; + char *rate = &samplerate[strlen(UAC_SAMPLE_RATE)]; + int sampleRate = atoi(rate); + if (compare(device, UAC_REMOTE_PLAY)) { + ALOGD("set samplerate %d to usb record\n", sampleRate); + uac_set_sample_rate(UAC_STREAM_RECORD, sampleRate); + } else if (compare(device, UAC_REMOTE_CAPTURE)) { + ALOGD("set samplerate %d to usb playback\n", sampleRate); + uac_set_sample_rate(UAC_STREAM_PLAYBACK, sampleRate); + } + } +} + +/* + * strs[0] = ACTION=change + * strs[1] = DEVPATH=/devicges/virtual/u_audio/UAC1_Gadgeta 0 + * strs[2] = SUBSYSTEM=u_audio + * strs[3] = USB_STATE=SET_VOLUME + * strs[4] = STREAM_DIRECTION=OUT + * strs[5] = VOLUME=0x7FFF + * index db + * 0x7FFF: 127.9961 + * ...... + * 0x0100: 1.0000 + * ...... + * 0x0002: 0.0078 + * 0x0001: 0.0039 + * 0x0000: 0.0000 + * 0xFFFF: -0.0039 + * 0xFFFE: -0.0078 + * ...... + * 0xFE00: -1.0000 + * ...... + * 0x8002: -127.9922 + * 0x8001: -127.9961 + * + */ +void audio_set_volume(const struct _uevent *uevent) { + char *direct = uevent->strs[UAC_KEY_DIRECTION]; + char *volumeStr = uevent->strs[UAC_KEY_VOLUME]; + int unit = 0x100; + ALOGD("direct = %s volume = %s\n", direct, volumeStr); + if (compare(direct, UAC_STREAM_DIRECT)) { + char *device = &direct[strlen(UAC_STREAM_DIRECT)]; + short volume = 0; + float db = 0; + sscanf(volumeStr, "VOLUME=0x%x", &volume); + db = volume / (float)unit; + double precent = pow(10, db / 10); + int precentInt = (int)(precent * 100); + ALOGD("set db = %f, precent = %lf, precentInt = %d\n", db, precent, + precentInt); + if (compare(device, UAC_REMOTE_PLAY)) { + ALOGD("set volume %d to usb record\n", precentInt); + uac_set_volume(UAC_STREAM_RECORD, precentInt); + } else if (compare(device, UAC_REMOTE_CAPTURE)) { + ALOGD("set volume %d to usb playback\n", precentInt); + uac_set_volume(UAC_STREAM_PLAYBACK, precentInt); + } + } +} + +/* + * strs[0] = ACTION=change + * strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0 + * strs[2] = SUBSYSTEM=u_audio + * strs[3] = USB_STATE=SET_MUTE + * strs[4] = STREAM_DIRECTION=OUT + * strs[5] = MUTE=1 +*/ +void audio_set_mute(const struct _uevent *uevent) { + char *direct = uevent->strs[UAC_KEY_DIRECTION]; + char *muteStr = uevent->strs[UAC_KEY_MUTE]; + ALOGD("direct = %s mute = %s\n", direct, muteStr); + + if (compare(direct, UAC_STREAM_DIRECT)) { + char *device = &direct[strlen(UAC_STREAM_DIRECT)]; + int mute = 0; + sscanf(muteStr, "MUTE=%d", &mute); + if (compare(device, UAC_REMOTE_PLAY)) { + ALOGD("set mute = %d to usb record\n", mute); + uac_set_mute(UAC_STREAM_RECORD, mute); + } else if (compare(device, UAC_REMOTE_CAPTURE)) { + ALOGD("set mute = %d to usb playback\n", mute); + uac_set_mute(UAC_STREAM_PLAYBACK, mute); + } + } +} + +/* + * strs[0] = ACTION=change + * strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0 + * strs[2] = SUBSYSTEM=u_audio + * strs[3] = USB_STATE=SET_AUDIO_CLK + * strs[4] = PPM=-21 + * strs[5] = SEQNUM=1573 + */ +void audio_set_ppm(const struct _uevent *uevent) { + char *ppmStr = uevent->strs[UAC_KEY_PPM]; + + if (compare(ppmStr, UAC_PPM)) { + int ppm = 0; + sscanf(ppmStr, "PPM=%d", &ppm); + uac_set_ppm(UAC_STREAM_RECORD, ppm); + uac_set_ppm(UAC_STREAM_PLAYBACK, ppm); + } +} + +void audio_event(const struct _uevent *uevent) { + char *event = uevent->strs[UAC_KEY_USB_STATE]; + char *direct = uevent->strs[UAC_KEY_DIRECTION]; + char *status = uevent->strs[UAC_KEY_STREAM_STATE]; + ALOGD("event = %s\n", event); + ALOGD("direct = %s\n", direct); + ALOGD("status = %s\n", status); + if ((event == NULL) || (direct == NULL) || (status == NULL)) { + return; + } + + bool setInterface = compare(event, UAC_UEVENT_SET_INTERFACE); + bool setSampleRate = compare(event, UAC_UEVENT_SET_SAMPLE_RATE); + bool setVolume = compare(event, UAC_UEVENT_SET_VOLUME); + bool setMute = compare(event, UAC_UEVENT_SET_MUTE); + bool setClk = compare(event, UAC_UEVENT_SET_AUDIO_CLK); + if (!setInterface && !setSampleRate && !setVolume && !setMute && !setClk) { + return; + } + + if (setInterface) { + ALOGD("uevent---------------audio_play\n"); + audio_play(uevent); + } else if (setSampleRate) { + ALOGD("uevent---------------audio_set_samplerate\n"); + audio_set_samplerate(uevent); + } else if (setVolume) { + ALOGD("uevent---------------setVolume\n"); + audio_set_volume(uevent); + } else if (setMute) { + ALOGD("uevent---------------setMute\n"); + audio_set_mute(uevent); + } else if (setClk) { + ALOGD("uevent---------------setClk\n"); + audio_set_ppm(uevent); + } +} + +static void parse_event(const struct _uevent *event) { + if (event->size <= 0) + return; + +#if 0 + for (int i = 0 ; i < 10; i++) { + if (event->strs[i] != NULL) { + ALOGD("strs[%d] = %s\n", i, event->strs[i]); + } + } +#endif + + if (compare(event->strs[UAC_KEY_AUDIO], UAC_UEVENT_AUDIO)) { + audio_event(event); + } +} + +static void *uac_event_monitor_thread(void *arg) { + int sockfd; + int i, j, len; + char buf[512]; + struct iovec iov; + struct msghdr msg; + struct sockaddr_nl sa; + struct _uevent event; + // uint32_t flags = *(uint32_t *)arg; + + prctl(PR_SET_NAME, "event_monitor", 0, 0, 0); + + memset(&sa, 0, sizeof(sa)); + sa.nl_family = AF_NETLINK; + sa.nl_groups = NETLINK_KOBJECT_UEVENT; + sa.nl_pid = 0; + memset(&msg, 0, sizeof(msg)); + iov.iov_base = (void *)buf; + iov.iov_len = sizeof(buf); + msg.msg_name = (void *)&sa; + msg.msg_namelen = sizeof(sa); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT); + if (sockfd == -1) { + ALOGE("socket creating failed:%s\n", strerror(errno)); + goto err_event_monitor; + } + + if (bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { + ALOGE("bind error:%s\n", strerror(errno)); + goto err_event_monitor; + } + + while (1) { + event.size = 0; + len = recvmsg(sockfd, &msg, 0); + if (len < 0) { + ALOGD("receive error\n"); + } else if (len < 32 || len > sizeof(buf)) { + ALOGD("invalid message"); + } else { + for (i = 0, j = 0; i < len; i++) { + if (*(buf + i) == '\0' && (i + 1) != len) { + event.strs[j++] = buf + i + 1; + event.size = j; + } + } + } + parse_event(&event); + } + +err_event_monitor: + pthread_detach(pthread_self()); + pthread_exit(NULL); +} + +int uac_uevent_monitor_run() { + pthread_t tid; + + return pthread_create(&tid, NULL, uac_event_monitor_thread, NULL); +} +//#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uac/test/Sine1k_48k_16b.wav b/project/app/uvc_app_tiny/uvc_app/uac/test/Sine1k_48k_16b.wav new file mode 100755 index 000000000..609426b9f Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/test/Sine1k_48k_16b.wav differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/test/mute.wav b/project/app/uvc_app_tiny/uvc_app/uac/test/mute.wav new file mode 100755 index 000000000..c3efcd4d1 Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/test/mute.wav differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/test/swp_48k_16b.wav b/project/app/uvc_app_tiny/uvc_app/uac/test/swp_48k_16b.wav new file mode 100755 index 000000000..0f413b839 Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/test/swp_48k_16b.wav differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/test/white_noise.wav b/project/app/uvc_app_tiny/uvc_app/uac/test/white_noise.wav new file mode 100755 index 000000000..6c6041a48 Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/test/white_noise.wav differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/test/需求模板_语音算法_rk3xxx_xx客户.xlsx b/project/app/uvc_app_tiny/uvc_app/uac/test/需求模板_语音算法_rk3xxx_xx客户.xlsx new file mode 100755 index 000000000..b2f97d5a4 Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/test/需求模板_语音算法_rk3xxx_xx客户.xlsx differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/tools/tinycap b/project/app/uvc_app_tiny/uvc_app/uac/tools/tinycap new file mode 100755 index 000000000..46a3a2dfb Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/tools/tinycap differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/tools/tinymix b/project/app/uvc_app_tiny/uvc_app/uac/tools/tinymix new file mode 100755 index 000000000..b7fd42582 Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/tools/tinymix differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/tools/tinyplay b/project/app/uvc_app_tiny/uvc_app/uac/tools/tinyplay new file mode 100755 index 000000000..89b4651ea Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uac/tools/tinyplay differ diff --git a/project/app/uvc_app_tiny/uvc_app/uac/uac.cmake b/project/app/uvc_app_tiny/uvc_app/uac/uac.cmake new file mode 100755 index 000000000..4ca3ddad4 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uac/uac.cmake @@ -0,0 +1,61 @@ +##PROJECT(uac) + +include_directories(uac/src) +include_directories(uac/src/include) + +option(UAC_GRAPH "uac open graph" OFF) +option(UAC_MPI "uac open mpi" ON) + +if (${UAC_GRAPH}) + add_definitions(-DUAC_GRAPH) + set(SOURCE_FILES_GRAPH + ${CMAKE_CURRENT_LIST_DIR}/src/graph/graph_control.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/graph/uac_control_graph.cpp + ) + message(STATUS "Build With Rockit Graph") +else() + message(STATUS "Build None Rockit Graph") +endif() + +if (${UAC_MPI}) + add_definitions(-DUAC_MPI) + set(SOURCE_FILES_MPI + ${CMAKE_CURRENT_LIST_DIR}/src/mpi/uac_control_mpi.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mpi_common/uac_amixer.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mpi_common/mpi_control_common.cpp + ) + message(STATUS "Build With Rockit Mpi") +else() + message(STATUS "Build None Rockit Mpi") +endif() + +set(UAC_SOURCE + ${CMAKE_CURRENT_LIST_DIR}/src/uac_uevent.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/uac_control.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/uac_common_def.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/uac_control_factory.cpp + ${SOURCE_FILES_GRAPH} + ${SOURCE_FILES_MPI} +) + +#set(UAC_DEPENDENT_LIBS +# pthread +# rockit +#) + +#set(UAC_AUDIO_ALGORITHM +# ${CMAKE_CURRENT_LIST_DIR}/libs/libaec_bf_process.so) +#install(FILES ${UAC_AUDIO_ALGORITHM} DESTINATION lib) + +#ADD_EXECUTABLE(uac_app ${UAC_SOURCE}) +#target_link_libraries(uac_app ${UAC_APP_DEPENDENT_LIBS}) + +install(DIRECTORY ./uac DESTINATION include + FILES_MATCHING PATTERN "*.h") + +option(ENABLE_DEMO_BOARD "use demo board conf" OFF) +if (${ENABLE_DEMO_BOARD}) + install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/configs/demo/ DESTINATION share/uac_app FILES_MATCHING PATTERN "*.json") +else() + install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/configs/ DESTINATION share/uac_app FILES_MATCHING PATTERN "configs_skv.json") +endif() diff --git a/project/app/uvc_app_tiny/uvc_app/usb_config.sh b/project/app/uvc_app_tiny/uvc_app/usb_config.sh new file mode 100755 index 000000000..ea0cdc98b --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/usb_config.sh @@ -0,0 +1,406 @@ +#!/bin/sh + +# UVC_MULTI_OPTIONS: Defines the options for UVC_MULTI variable. +# Available options: off (close), one (Expand a device), two (Expand two devices) +UVC_MULTI=one + +CDC_ENABLE=NO +USB_FUNCTIONS_DIR=/sys/kernel/config/usb_gadget/rockchip/functions +USB_CONFIGS_DIR=/sys/kernel/config/usb_gadget/rockchip/configs/b.1 + +configure_uvc_resolution_yuyv() +{ + UVC_DISPLAY_W=$1 + UVC_DISPLAY_H=$2 + UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/uncompressed/u/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p + mkdir ${UVC_DISPLAY_DIR} + echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth + echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight + echo 333333 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMinBitRate + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*2)) > ${UVC_DISPLAY_DIR}/dwMaxVideoFrameBufferSize + echo -e "333333\n666666\n1000000\n2000000" > ${UVC_DISPLAY_DIR}/dwFrameInterval +} + +configure_uvc_resolution_yuyv_720p() +{ + UVC_DISPLAY_W=$1 + UVC_DISPLAY_H=$2 + UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/uncompressed/u/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p + mkdir ${UVC_DISPLAY_DIR} + echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth + echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight + echo 1000000 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMinBitRate + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*2)) > ${UVC_DISPLAY_DIR}/dwMaxVideoFrameBufferSize + echo -e "1000000\n2000000" > ${UVC_DISPLAY_DIR}/dwFrameInterval +} + +configure_uvc_resolution_yuyv_1080p() +{ + UVC_DISPLAY_W=$1 + UVC_DISPLAY_H=$2 + UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/uncompressed/u/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p + mkdir ${UVC_DISPLAY_DIR} + echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth + echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight + echo 2500000 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMinBitRate + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*2)) > ${UVC_DISPLAY_DIR}/dwMaxVideoFrameBufferSize + echo -e "2500000\n5000000" > ${UVC_DISPLAY_DIR}/dwFrameInterval +} + +configure_uvc_resolution_mjpeg() +{ + UVC_DISPLAY_W=$1 + UVC_DISPLAY_H=$2 + UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/mjpeg/m/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p + mkdir ${UVC_DISPLAY_DIR} + echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth + echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight + echo 333333 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMinBitRate + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*2)) > ${UVC_DISPLAY_DIR}/dwMaxVideoFrameBufferSize + echo -e "333333\n666666\n1000000\n2000000" > ${UVC_DISPLAY_DIR}/dwFrameInterval +} +configure_uvc_resolution_h264() +{ + UVC_DISPLAY_W=$1 + UVC_DISPLAY_H=$2 + UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f1/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p + mkdir ${UVC_DISPLAY_DIR} + echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth + echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight + echo 333333 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*10)) > ${UVC_DISPLAY_DIR}/dwMinBitRate + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*10)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate + echo -e "333333\n400000\n500000\n666666\n1000000\n2000000" > ${UVC_DISPLAY_DIR}/dwFrameInterval + echo -ne \\x48\\x32\\x36\\x34\\x00\\x00\\x10\\x00\\x80\\x00\\x00\\xaa\\x00\\x38\\x9b\\x71 > ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f1/guidFormat +} +configure_uvc_resolution_h265() +{ + UVC_DISPLAY_W=$1 + UVC_DISPLAY_H=$2 + UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f2/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p + mkdir ${UVC_DISPLAY_DIR} + echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth + echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight + echo 333333 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*10)) > ${UVC_DISPLAY_DIR}/dwMinBitRate + echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*10)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate + echo -e "333333\n400000\n500000\n666666" > ${UVC_DISPLAY_DIR}/dwFrameInterval + echo -ne \\x48\\x32\\x36\\x35\\x00\\x00\\x10\\x00\\x80\\x00\\x00\\xaa\\x00\\x38\\x9b\\x71 > ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f2/guidFormat +} + +cdc_device_config() +{ + mkdir ${USB_FUNCTIONS_DIR}/acm.g0 + CONFIG_STR=`cat /sys/kernel/config/usb_gadget/rockchip/configs/b.1/strings/0x409/configuration` + STR=${CONFIG_STR}_acm + echo $STR > ${USB_CONFIGS_DIR}/strings/0x409/configuration + USB_CNT=`echo $STR | awk -F"_" '{print NF-1}'` + let USB_CNT=USB_CNT+2 + if [ $UVC_MULTI = one ];then + let USB_CNT=USB_CNT+1 + elif [ $UVC_MULTI = two ];then + let USB_CNT=USB_CNT+2 + fi + echo "acm on++++++ ${USB_CNT}" + ln -s ${USB_FUNCTIONS_DIR}/acm.g0 ${USB_CONFIGS_DIR}/f${USB_CNT} +} + +uvc_device_config() +{ + UVC_GS=$1 + UVC_NAME=$2 + mkdir ${USB_FUNCTIONS_DIR}/$UVC_GS + echo $UVC_NAME > ${USB_FUNCTIONS_DIR}/$UVC_GS/device_name + echo $UVC_NAME > ${USB_FUNCTIONS_DIR}/$UVC_GS/function_name + if [ $UVC_MULTI = one ];then + echo 2048 > ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming_maxpacket + elif [ $UVC_MULTI = two ];then + echo 1024 > ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming_maxpacket + else + echo 3072 > ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming_maxpacket + fi + echo 2 > ${USB_FUNCTIONS_DIR}/$UVC_GS/uvc_num_request + #echo 1 > /sys/kernel/config/usb_gadget/rockchip/functions/$UVC_GS/streaming_bulk + + mkdir ${USB_FUNCTIONS_DIR}/$UVC_GS/control/header/h + ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/control/header/h ${USB_FUNCTIONS_DIR}/$UVC_GS/control/class/fs/h + ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/control/header/h ${USB_FUNCTIONS_DIR}/$UVC_GS/control/class/ss/h + ##YUYV support config + mkdir /sys/kernel/config/usb_gadget/rockchip/functions/$UVC_GS/streaming/uncompressed/u + configure_uvc_resolution_yuyv 320 240 + configure_uvc_resolution_yuyv 640 480 + configure_uvc_resolution_yuyv_720p 1280 720 + #configure_uvc_resolution_yuyv_1080p 1920 1080 + + ##mjpeg support config + mkdir ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/mjpeg/m + configure_uvc_resolution_mjpeg 320 240 + configure_uvc_resolution_mjpeg 640 360 + configure_uvc_resolution_mjpeg 640 480 + configure_uvc_resolution_mjpeg 768 448 + configure_uvc_resolution_mjpeg 1280 720 + configure_uvc_resolution_mjpeg 1024 768 + configure_uvc_resolution_mjpeg 1920 1080 + configure_uvc_resolution_mjpeg 2048 1536 +# configure_uvc_resolution_mjpeg 2560 1440 + + ## h.264 support config + mkdir ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f1 + configure_uvc_resolution_h264 640 480 + configure_uvc_resolution_h264 1280 720 + configure_uvc_resolution_h264 1920 1080 + configure_uvc_resolution_h264 2048 1536 +# configure_uvc_resolution_h264 2560 1440 + + ## h.265 support config + mkdir ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f2 + configure_uvc_resolution_h265 640 480 + configure_uvc_resolution_h265 1280 720 + configure_uvc_resolution_h265 1920 1080 + configure_uvc_resolution_h265 2048 1536 + #configure_uvc_resolution_h265 2560 1440 + + mkdir /sys/kernel/config/usb_gadget/rockchip/functions/$UVC_GS/streaming/header/h + ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/uncompressed/u ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h/u + ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/mjpeg/m ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h/m + ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f1 ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h/f1 + ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f2 ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h/f2 + ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/class/fs/h + ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/class/hs/h + ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/class/ss/h +} +uac1_device_config() +{ + UAC=$1 + mkdir ${USB_FUNCTIONS_DIR}/${UAC}.gs0 + UAC_GS0=${USB_FUNCTIONS_DIR}/${UAC}.gs0 + echo 3 > ${UAC_GS0}/p_chmask + echo 2 > ${UAC_GS0}/p_ssize + echo 1 > ${UAC_GS0}/p_mute_present + echo 1 > ${UAC_GS0}/p_volume_present + echo -5120 > ${UAC_GS0}/p_volume_min #-20db min must > -96db + echo 8000,16000,44100,48000 > ${UAC_GS0}/p_srate + + echo 3 > ${UAC_GS0}/c_chmask + echo 2 > ${UAC_GS0}/c_ssize + echo 4 > ${UAC_GS0}/req_number + echo 1 > ${UAC_GS0}/c_mute_present + echo 1 > ${UAC_GS0}/c_volume_present + echo -3200 > ${UAC_GS0}/c_volume_min #-12.5db + echo 0 > ${UAC_GS0}/c_volume_max #0db + echo 32 > ${UAC_GS0}/c_volume_res #0.125db + echo 8000,16000,44100,48000 > ${UAC_GS0}/c_srate + + if [ $UVC_MULTI = one ];then + ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f3 + elif [ $UVC_MULTI = two ];then + ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f4 + else + ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f2 + fi +} +uac2_device_config() +{ + UAC=$1 + mkdir ${USB_FUNCTIONS_DIR}/${UAC}.gs0 + UAC_GS0=${USB_FUNCTIONS_DIR}/${UAC}.gs0 + echo 3 > ${UAC_GS0}/p_chmask + echo 2 > ${UAC_GS0}/p_ssize + echo 1 > ${UAC_GS0}/p_mute_present + echo 1 > ${UAC_GS0}/p_volume_present + echo -5120 > ${UAC_GS0}/p_volume_min #-20db min must > -96db + echo 8000,16000,44100,48000 > ${UAC_GS0}/p_srate + + echo 3 > ${UAC_GS0}/c_chmask + echo 2 > ${UAC_GS0}/c_ssize + echo 4 > ${UAC_GS0}/req_number + echo 1 > ${UAC_GS0}/c_mute_present + echo 1 > ${UAC_GS0}/c_volume_present + echo -3200 > ${UAC_GS0}/c_volume_min #-12.5db + echo 0 > ${UAC_GS0}/c_volume_max #0db + echo 32 > ${UAC_GS0}/c_volume_res #0.125db + echo 8000,16000,44100,48000 > ${UAC_GS0}/c_srate + + if [ $UVC_MULTI = one ];then + ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f3 + elif [ $UVC_MULTI = two ];then + ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f4 + else + ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f2 + fi +} +pre_run_rndis() +{ + RNDIS_STR="rndis" + if ( echo $1 |grep -q "rndis" ); then + #sleep 1 + IP_FILE=/data/uvc_xu_ip_save + echo "config usb0 IP..." + if [ -f $IP_FILE ]; then + for line in `cat $IP_FILE` + do + echo "save ip is: $line" + ifconfig usb0 $line + done + else + ifconfig usb0 172.16.110.6 + fi + ifconfig usb0 up + fi +} + +insmod /oem/usr/ko/usb-common.ko +insmod /oem/usr/ko/usbcore.ko +insmod /oem/usr/ko/udc-core.ko +insmod /oem/usr/ko/libcomposite.ko +insmod /oem/usr/ko/usb_f_fs.ko + +#UAC +insmod /oem/usr/ko/u_audio.ko +insmod /oem/usr/ko/usb_f_uac2.ko +insmod /oem/usr/ko/usb_f_uac1.ko + +#UVC +insmod /oem/usr/ko/usb_f_uvc.ko + +if [ "$CDC_ENABLE" = "YES" ];then + insmod /oem/usr/ko/u_serial.ko + insmod /oem/usr/ko/usb_f_acm.ko +fi +insmod /oem/usr/ko/phy-rockchip-inno-usb2.ko +insmod /oem/usr/ko/dwc3-of-simple.ko +insmod /oem/usr/ko/dwc3.ko + +##main +#init usb config +ifconfig lo up # for adb ok +/etc/init.d/S10udev stop +umount /sys/kernel/config +mkdir /dev/usb-ffs +mount -t configfs none /sys/kernel/config +mkdir -p /sys/kernel/config/usb_gadget/rockchip +mkdir -p /sys/kernel/config/usb_gadget/rockchip/strings/0x409 +mkdir -p ${USB_CONFIGS_DIR}/strings/0x409 +echo 0x2207 > /sys/kernel/config/usb_gadget/rockchip/idVendor +echo 0x0310 > /sys/kernel/config/usb_gadget/rockchip/bcdDevice +echo 0x0200 > /sys/kernel/config/usb_gadget/rockchip/bcdUSB +echo 239 > /sys/kernel/config/usb_gadget/rockchip/bDeviceClass +echo 2 > /sys/kernel/config/usb_gadget/rockchip/bDeviceSubClass +echo 1 > /sys/kernel/config/usb_gadget/rockchip/bDeviceProtocol +SERIAL_NUM=`cat /proc/cpuinfo |grep Serial | awk -F ":" '{print $2}'` +echo "serialnumber is $SERIAL_NUM" +echo $SERIAL_NUM > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/serialnumber +echo "rockchip" > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/manufacturer +echo "UVC" > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/product +echo 0x1 > /sys/kernel/config/usb_gadget/rockchip/os_desc/b_vendor_code +echo "MSFT100" > /sys/kernel/config/usb_gadget/rockchip/os_desc/qw_sign +echo 500 > /sys/kernel/config/usb_gadget/rockchip/configs/b.1/MaxPower +#ln -s /sys/kernel/config/usb_gadget/rockchip/configs/b.1 /sys/kernel/config/usb_gadget/rockchip/os_desc/b.1 + +#Windows computers will remember the device by default. +#Changing the pid does not require re-uninstalling and loading the windows driver. +echo 0x0016 > /sys/kernel/config/usb_gadget/rockchip/idProduct +if [ $UVC_MULTI = one ];then + echo 0x0018 > /sys/kernel/config/usb_gadget/rockchip/idProduct +elif [ $UVC_MULTI = two ];then + echo 0x001A > /sys/kernel/config/usb_gadget/rockchip/idProduct +fi + +#uvc config init +uvc_device_config uvc.gs1 "UVC RGB" +if [ $UVC_MULTI = one ];then + uvc_device_config uvc.gs2 "RK UVC" +elif [ $UVC_MULTI = two ];then + uvc_device_config uvc.gs2 "RK UVC 1" + uvc_device_config uvc.gs3 "RK UVC 2" +fi +##reset config,del default adb config +if [ -e ${USB_CONFIGS_DIR}/ffs.adb ]; then + #for rk1808 kernel 4.4 + rm -f ${USB_CONFIGS_DIR}/ffs.adb +else + ls ${USB_CONFIGS_DIR} | grep f[0-9] | xargs -I {} rm ${USB_CONFIGS_DIR}/{} +fi + +case "$1" in +rndis) + # config rndis + mkdir /sys/kernel/config/usb_gadget/rockchip/functions/rndis.gs0 + echo "uvc_rndis" > ${USB_CONFIGS_DIR}/strings/0x409/configuration + if [ $UVC_MULTI = one ];then + ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f3 + elif [ $UVC_MULTI = two ];then + ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f4 + else + ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f2 + fi + echo "config uvc and rndis..." + ;; +uac1) + uac1_device_config uac1 + echo "uvc_uac1" > ${USB_CONFIGS_DIR}/strings/0x409/configuration + echo "config uvc and uac1..." + ;; +uac2) + uac2_device_config uac2 + echo "uvc_uac2" > ${USB_CONFIGS_DIR}/strings/0x409/configuration + echo "config uvc and uac2..." + ;; +uac1_rndis) + #uac_device_config uac1 + mkdir /sys/kernel/config/usb_gadget/rockchip/functions/rndis.gs0 + if [ $UVC_MULTI = one ];then + ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f4 + elif [ $UVC_MULTI = two ];then + ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f5 + else + ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f3 + fi + uac1_device_config uac1 + echo "uvc_uac1_rndis" > ${USB_CONFIGS_DIR}/strings/0x409/configuration + echo "config uvc and uac1 rndis..." + ;; +uac2_rndis) + #uac_device_config uac2 + mkdir /sys/kernel/config/usb_gadget/rockchip/functions/rndis.gs0 + if [ $UVC_MULTI = one ];then + ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f4 + elif [ $UVC_MULTI = two ];then + ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f5 + else + ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f3 + fi + uac2_device_config uac2 + echo "uvc_uac2_rndis" > ${USB_CONFIGS_DIR}/strings/0x409/configuration + echo "config uvc and uac2 rndis..." + ;; +*) + echo "uvc" > ${USB_CONFIGS_DIR}/strings/0x409/configuration + echo "config uvc ..." +esac + +ln -s ${USB_FUNCTIONS_DIR}/uvc.gs1 ${USB_CONFIGS_DIR}/f1 +if [ $UVC_MULTI = one ];then + ln -s ${USB_FUNCTIONS_DIR}/uvc.gs2 ${USB_CONFIGS_DIR}/f2 +elif [ $UVC_MULTI = two ];then + ln -s ${USB_FUNCTIONS_DIR}/uvc.gs2 ${USB_CONFIGS_DIR}/f2 + ln -s ${USB_FUNCTIONS_DIR}/uvc.gs3 ${USB_CONFIGS_DIR}/f3 +fi +if [ "$CDC_ENABLE" = "YES" ];then + cdc_device_config +fi + +UDC=`ls /sys/class/udc/| awk '{print $1}'` +echo $UDC > /sys/kernel/config/usb_gadget/rockchip/UDC + +if [ "$1" ]; then + pre_run_rndis $1 +fi diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/cJSON/cJSON.c b/project/app/uvc_app_tiny/uvc_app/uvc/cJSON/cJSON.c new file mode 100644 index 000000000..23418f1c9 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/cJSON/cJSON.c @@ -0,0 +1,1095 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +#include "cJSON.h" +#include +#include +#include +#include +#include +#include +#include + +static const char *ep; + +const char *cJSON_GetErrorPtr(void) { return ep; } + +static int cJSON_strcasecmp(const char *s1, const char *s2) { + if (!s1) + return (s1 == s2) ? 0 : 1; + if (!s2) + return 1; + for (; tolower(*s1) == tolower(*s2); ++s1, ++s2) + if (*s1 == 0) + return 0; + return tolower(*(const unsigned char *)s1) - + tolower(*(const unsigned char *)s2); +} + +static void *(*cJSON_malloc)(size_t sz) = malloc; +static void (*cJSON_free)(void *ptr) = free; + +static char *cJSON_strdup(const char *str) { + size_t len; + char *copy; + + len = strlen(str) + 1; + if (!(copy = (char *)cJSON_malloc(len))) + return 0; + memcpy(copy, str, len); + return copy; +} + +void cJSON_InitHooks(cJSON_Hooks *hooks) { + if (!hooks) /* Reset hooks */ + { + cJSON_malloc = malloc; + cJSON_free = free; + return; + } + + cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc; + cJSON_free = (hooks->free_fn) ? hooks->free_fn : free; +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(void) { + cJSON *node = (cJSON *)cJSON_malloc(sizeof(cJSON)); + if (node) + memset(node, 0, sizeof(cJSON)); + return node; +} + +/* Delete a cJSON structure. */ +void cJSON_Delete(cJSON *c) { + cJSON *next; + while (c) { + next = c->next; + if (!(c->type & cJSON_IsReference) && c->child) + cJSON_Delete(c->child); + if (!(c->type & cJSON_IsReference) && c->valuestring) + cJSON_free(c->valuestring); + if (c->string) + cJSON_free(c->string); + cJSON_free(c); + c = next; + } +} + +/* Parse the input text to generate a number, and populate the result into item. + */ +static const char *parse_number(cJSON *item, const char *num) { + double n = 0, sign = 1, scale = 0; + int subscale = 0, signsubscale = 1; + + if (*num == '-') + sign = -1, num++; /* Has sign? */ + if (*num == '0') + num++; /* is zero */ + if (*num >= '1' && *num <= '9') + do + n = (n * 10.0) + (*num++ - '0'); + while (*num >= '0' && *num <= '9'); /* Number? */ + if (*num == '.' && num[1] >= '0' && num[1] <= '9') { + num++; /* Fractional part? */ + do + n = (n * 10.0) + (*num++ - '0'), scale--; + while (*num >= '0' && *num <= '9'); + } + if (*num == 'e' || *num == 'E') /* Exponent? */ + { + num++; + if (*num == '+') + num++; + else if (*num == '-') + signsubscale = -1, num++; /* With sign? */ + while (*num >= '0' && *num <= '9') + subscale = (subscale * 10) + (*num++ - '0'); /* Number? */ + } + + n = sign * n * + pow(10.0, (scale + subscale * signsubscale)); /* number = +/- + number.fraction * + 10^+/- exponent */ + + item->valuedouble = n; + item->valueint = (int)n; + item->type = cJSON_Number; + return num; +} + +/* Render the number nicely from the given item into a string. */ +static char *print_number(cJSON *item) { + char *str; + double d = item->valuedouble; + if (fabs(((double)item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && + d >= INT_MIN) { + str = (char *)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ + if (str) + sprintf(str, "%d", item->valueint); + } else { + str = (char *)cJSON_malloc(64); /* This is a nice tradeoff. */ + if (str) { + if (fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60) + sprintf(str, "%.0f", d); + else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9) + sprintf(str, "%e", d); + else + sprintf(str, "%f", d); + } + } + return str; +} + +static unsigned parse_hex4(const char *str) { + unsigned h = 0; + if (*str >= '0' && *str <= '9') + h += (*str) - '0'; + else if (*str >= 'A' && *str <= 'F') + h += 10 + (*str) - 'A'; + else if (*str >= 'a' && *str <= 'f') + h += 10 + (*str) - 'a'; + else + return 0; + h = h << 4; + str++; + if (*str >= '0' && *str <= '9') + h += (*str) - '0'; + else if (*str >= 'A' && *str <= 'F') + h += 10 + (*str) - 'A'; + else if (*str >= 'a' && *str <= 'f') + h += 10 + (*str) - 'a'; + else + return 0; + h = h << 4; + str++; + if (*str >= '0' && *str <= '9') + h += (*str) - '0'; + else if (*str >= 'A' && *str <= 'F') + h += 10 + (*str) - 'A'; + else if (*str >= 'a' && *str <= 'f') + h += 10 + (*str) - 'a'; + else + return 0; + h = h << 4; + str++; + if (*str >= '0' && *str <= '9') + h += (*str) - '0'; + else if (*str >= 'A' && *str <= 'F') + h += 10 + (*str) - 'A'; + else if (*str >= 'a' && *str <= 'f') + h += 10 + (*str) - 'a'; + else + return 0; + return h; +} + +/* Parse the input text into an unescaped cstring, and populate item. */ +static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, + 0xF0, 0xF8, 0xFC}; +static const char *parse_string(cJSON *item, const char *str) { + const char *ptr = str + 1; + char *ptr2; + char *out; + int len = 0; + unsigned uc, uc2; + if (*str != '\"') { + ep = str; /* not a string! */ + return 0; + } + + while (*ptr != '\"' && *ptr && ++len) + if (*ptr++ == '\\') + ptr++; /* Skip escaped quotes. */ + + out = (char *)cJSON_malloc( + len + 1); /* This is how long we need for the string, roughly. */ + if (!out) + return 0; + + ptr = str + 1; + ptr2 = out; + while (*ptr != '\"' && *ptr) { + if (*ptr != '\\') + *ptr2++ = *ptr++; + else { + ptr++; + switch (*ptr) { + case 'b': + *ptr2++ = '\b'; + break; + case 'f': + *ptr2++ = '\f'; + break; + case 'n': + *ptr2++ = '\n'; + break; + case 'r': + *ptr2++ = '\r'; + break; + case 't': + *ptr2++ = '\t'; + break; + case 'u': /* transcode utf16 to utf8. */ + uc = parse_hex4(ptr + 1); + ptr += 4; /* get the unicode char. */ + + if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) + break; /* check for invalid. */ + + if (uc >= 0xD800 && uc <= 0xDBFF) /* UTF16 surrogate pairs. */ + { + if (ptr[1] != '\\' || ptr[2] != 'u') + break; /* missing second-half of surrogate. */ + uc2 = parse_hex4(ptr + 3); + ptr += 6; + if (uc2 < 0xDC00 || uc2 > 0xDFFF) + break; /* invalid second-half of surrogate. */ + uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF)); + } + + len = 4; + if (uc < 0x80) + len = 1; + else if (uc < 0x800) + len = 2; + else if (uc < 0x10000) + len = 3; + ptr2 += len; + + switch (len) { + case 4: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 3: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 2: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 1: + *--ptr2 = (uc | firstByteMark[len]); + } + ptr2 += len; + break; + default: + *ptr2++ = *ptr; + break; + } + ptr++; + } + } + *ptr2 = 0; + if (*ptr == '\"') + ptr++; + item->valuestring = out; + item->type = cJSON_String; + return ptr; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static char *print_string_ptr(const char *str) { + const char *ptr; + char *ptr2, *out; + int len = 0; + unsigned char token; + + if (!str) + return cJSON_strdup(""); + ptr = str; + while ((token = *ptr) && ++len) { + if (strchr("\"\\\b\f\n\r\t", token)) + len++; + else if (token < 32) + len += 5; + ptr++; + } + + out = (char *)cJSON_malloc(len + 3); + if (!out) + return 0; + + ptr2 = out; + ptr = str; + *ptr2++ = '\"'; + while (*ptr) { + if ((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\') + *ptr2++ = *ptr++; + else { + *ptr2++ = '\\'; + switch (token = *ptr++) { + case '\\': + *ptr2++ = '\\'; + break; + case '\"': + *ptr2++ = '\"'; + break; + case '\b': + *ptr2++ = 'b'; + break; + case '\f': + *ptr2++ = 'f'; + break; + case '\n': + *ptr2++ = 'n'; + break; + case '\r': + *ptr2++ = 'r'; + break; + case '\t': + *ptr2++ = 't'; + break; + default: + sprintf(ptr2, "u%04x", token); + ptr2 += 5; + break; /* escape and print */ + } + } + } + *ptr2++ = '\"'; + *ptr2++ = 0; + return out; +} +/* Invote print_string_ptr (which is useful) on an item. */ +static char *print_string(cJSON *item) { + return print_string_ptr(item->valuestring); +} + +/* Predeclare these prototypes. */ +static const char *parse_value(cJSON *item, const char *value); +static char *print_value(cJSON *item, int depth, int fmt); +static const char *parse_array(cJSON *item, const char *value); +static char *print_array(cJSON *item, int depth, int fmt); +static const char *parse_object(cJSON *item, const char *value); +static char *print_object(cJSON *item, int depth, int fmt); + +/* Utility to jump whitespace and cr/lf */ +static const char *skip(const char *in) { + while (in && *in && (unsigned char)*in <= 32) + in++; + return in; +} + +/* Parse an object - create a new root, and populate. */ +cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, + int require_null_terminated) { + const char *end = 0; + cJSON *c = cJSON_New_Item(); + ep = 0; + if (!c) + return 0; /* memory fail */ + + end = parse_value(c, skip(value)); + if (!end) { + cJSON_Delete(c); /* parse failure. ep is set. */ + return 0; + } + + /* if we require null-terminated JSON without appended garbage, skip and then + * check for a null terminator */ + if (require_null_terminated) { + end = skip(end); + if (*end) { + cJSON_Delete(c); + ep = end; + return 0; + } + } + if (return_parse_end) + *return_parse_end = end; + return c; +} +/* Default options for cJSON_Parse */ +cJSON *cJSON_Parse(const char *value) { + return cJSON_ParseWithOpts(value, 0, 0); +} + +/* Render a cJSON item/entity/structure to text. */ +char *cJSON_Print(cJSON *item) { return print_value(item, 0, 1); } +char *cJSON_PrintUnformatted(cJSON *item) { return print_value(item, 0, 0); } + +/* Parser core - when encountering text, process appropriately. */ +static const char *parse_value(cJSON *item, const char *value) { + if (!value) + return 0; /* Fail on null. */ + if (!strncmp(value, "null", 4)) { + item->type = cJSON_NULL; + return value + 4; + } + if (!strncmp(value, "false", 5)) { + item->type = cJSON_False; + return value + 5; + } + if (!strncmp(value, "true", 4)) { + item->type = cJSON_True; + item->valueint = 1; + return value + 4; + } + if (*value == '\"') { + return parse_string(item, value); + } + if (*value == '-' || (*value >= '0' && *value <= '9')) { + return parse_number(item, value); + } + if (*value == '[') { + return parse_array(item, value); + } + if (*value == '{') { + return parse_object(item, value); + } + + ep = value; + return 0; /* failure. */ +} + +/* Render a value to text. */ +static char *print_value(cJSON *item, int depth, int fmt) { + char *out = 0; + if (!item) + return 0; + switch ((item->type) & 255) { + case cJSON_NULL: + out = cJSON_strdup("null"); + break; + case cJSON_False: + out = cJSON_strdup("false"); + break; + case cJSON_True: + out = cJSON_strdup("true"); + break; + case cJSON_Number: + out = print_number(item); + break; + case cJSON_String: + out = print_string(item); + break; + case cJSON_Array: + out = print_array(item, depth, fmt); + break; + case cJSON_Object: + out = print_object(item, depth, fmt); + break; + } + return out; +} + +/* Build an array from input text. */ +static const char *parse_array(cJSON *item, const char *value) { + cJSON *child; + if (*value != '[') { + ep = value; /* not an array! */ + return 0; + } + + item->type = cJSON_Array; + value = skip(value + 1); + if (*value == ']') + return value + 1; /* empty array. */ + + item->child = child = cJSON_New_Item(); + if (!item->child) + return 0; /* memory fail */ + value = skip( + parse_value(child, skip(value))); /* skip any spacing, get the value. */ + if (!value) + return 0; + + while (*value == ',') { + cJSON *new_item; + if (!(new_item = cJSON_New_Item())) + return 0; /* memory fail */ + child->next = new_item; + new_item->prev = child; + child = new_item; + value = skip(parse_value(child, skip(value + 1))); + if (!value) + return 0; /* memory fail */ + } + + if (*value == ']') + return value + 1; /* end of array */ + ep = value; + return 0; /* malformed. */ +} + +/* Render an array to text */ +static char *print_array(cJSON *item, int depth, int fmt) { + char **entries; + char *out = 0, *ptr, *ret; + int len = 5; + cJSON *child = item->child; + int numentries = 0, i = 0, fail = 0; + + /* How many entries in the array? */ + while (child) + numentries++, child = child->next; + /* Explicitly handle numentries==0 */ + if (!numentries) { + out = (char *)cJSON_malloc(3); + if (out) + strcpy(out, "[]"); + return out; + } + /* Allocate an array to hold the values for each */ + entries = (char **)cJSON_malloc(numentries * sizeof(char *)); + if (!entries) + return 0; + memset(entries, 0, numentries * sizeof(char *)); + /* Retrieve all the results: */ + child = item->child; + while (child && !fail) { + ret = print_value(child, depth + 1, fmt); + entries[i++] = ret; + if (ret) + len += strlen(ret) + 2 + (fmt ? 1 : 0); + else + fail = 1; + child = child->next; + } + + /* If we didn't fail, try to malloc the output string */ + if (!fail) + out = (char *)cJSON_malloc(len); + /* If that fails, we fail. */ + if (!out) + fail = 1; + + /* Handle failure. */ + if (fail) { + for (i = 0; i < numentries; i++) + if (entries[i]) + cJSON_free(entries[i]); + cJSON_free(entries); + return 0; + } + + /* Compose the output array. */ + *out = '['; + ptr = out + 1; + *ptr = 0; + for (i = 0; i < numentries; i++) { + strcpy(ptr, entries[i]); + ptr += strlen(entries[i]); + if (i != numentries - 1) { + *ptr++ = ','; + if (fmt) + *ptr++ = ' '; + *ptr = 0; + } + cJSON_free(entries[i]); + } + cJSON_free(entries); + *ptr++ = ']'; + *ptr++ = 0; + return out; +} + +/* Build an object from the text. */ +static const char *parse_object(cJSON *item, const char *value) { + cJSON *child; + if (*value != '{') { + ep = value; /* not an object! */ + return 0; + } + + item->type = cJSON_Object; + value = skip(value + 1); + if (*value == '}') + return value + 1; /* empty array. */ + + item->child = child = cJSON_New_Item(); + if (!item->child) + return 0; + value = skip(parse_string(child, skip(value))); + if (!value) + return 0; + child->string = child->valuestring; + child->valuestring = 0; + if (*value != ':') { + ep = value; /* fail! */ + return 0; + } + value = skip(parse_value( + child, skip(value + 1))); /* skip any spacing, get the value. */ + if (!value) + return 0; + + while (*value == ',') { + cJSON *new_item; + if (!(new_item = cJSON_New_Item())) + return 0; /* memory fail */ + child->next = new_item; + new_item->prev = child; + child = new_item; + value = skip(parse_string(child, skip(value + 1))); + if (!value) + return 0; + child->string = child->valuestring; + child->valuestring = 0; + if (*value != ':') { + ep = value; /* fail! */ + return 0; + } + value = skip(parse_value( + child, skip(value + 1))); /* skip any spacing, get the value. */ + if (!value) + return 0; + } + + if (*value == '}') + return value + 1; /* end of array */ + ep = value; + return 0; /* malformed. */ +} + +/* Render an object to text. */ +static char *print_object(cJSON *item, int depth, int fmt) { + char **entries = 0, **names = 0; + char *out = 0, *ptr, *ret, *str; + int len = 7, i = 0, j; + cJSON *child = item->child; + int numentries = 0, fail = 0; + /* Count the number of entries. */ + while (child) + numentries++, child = child->next; + /* Explicitly handle empty object case */ + if (!numentries) { + out = (char *)cJSON_malloc(fmt ? depth + 4 : 3); + if (!out) + return 0; + ptr = out; + *ptr++ = '{'; + if (fmt) { + *ptr++ = '\n'; + for (i = 0; i < depth - 1; i++) + *ptr++ = '\t'; + } + *ptr++ = '}'; + *ptr++ = 0; + return out; + } + /* Allocate space for the names and the objects */ + entries = (char **)cJSON_malloc(numentries * sizeof(char *)); + if (!entries) + return 0; + names = (char **)cJSON_malloc(numentries * sizeof(char *)); + if (!names) { + cJSON_free(entries); + return 0; + } + memset(entries, 0, sizeof(char *) * numentries); + memset(names, 0, sizeof(char *) * numentries); + + /* Collect all the results into our arrays: */ + child = item->child; + depth++; + if (fmt) + len += depth; + while (child) { + names[i] = str = print_string_ptr(child->string); + entries[i++] = ret = print_value(child, depth, fmt); + if (str && ret) + len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0); + else + fail = 1; + child = child->next; + } + + /* Try to allocate the output string */ + if (!fail) + out = (char *)cJSON_malloc(len); + if (!out) + fail = 1; + + /* Handle failure */ + if (fail) { + for (i = 0; i < numentries; i++) { + if (names[i]) + cJSON_free(names[i]); + if (entries[i]) + cJSON_free(entries[i]); + } + cJSON_free(names); + cJSON_free(entries); + return 0; + } + + /* Compose the output: */ + *out = '{'; + ptr = out + 1; + if (fmt) + *ptr++ = '\n'; + *ptr = 0; + for (i = 0; i < numentries; i++) { + if (fmt) + for (j = 0; j < depth; j++) + *ptr++ = '\t'; + strcpy(ptr, names[i]); + ptr += strlen(names[i]); + *ptr++ = ':'; + if (fmt) + *ptr++ = '\t'; + strcpy(ptr, entries[i]); + ptr += strlen(entries[i]); + if (i != numentries - 1) + *ptr++ = ','; + if (fmt) + *ptr++ = '\n'; + *ptr = 0; + cJSON_free(names[i]); + cJSON_free(entries[i]); + } + + cJSON_free(names); + cJSON_free(entries); + if (fmt) + for (i = 0; i < depth - 1; i++) + *ptr++ = '\t'; + *ptr++ = '}'; + *ptr++ = 0; + return out; +} + +/* Get Array size/item / object item. */ +int cJSON_GetArraySize(cJSON *array) { + cJSON *c = array->child; + int i = 0; + while (c) + i++, c = c->next; + return i; +} +cJSON *cJSON_GetArrayItem(cJSON *array, int item) { + cJSON *c = array->child; + while (c && item > 0) + item--, c = c->next; + return c; +} +cJSON *cJSON_GetObjectItem(cJSON *object, const char *string) { + cJSON *c = object->child; + while (c && cJSON_strcasecmp(c->string, string)) + c = c->next; + return c; +} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev, cJSON *item) { + prev->next = item; + item->prev = prev; +} +/* Utility for handling references. */ +static cJSON *create_reference(cJSON *item) { + cJSON *ref = cJSON_New_Item(); + if (!ref) + return 0; + memcpy(ref, item, sizeof(cJSON)); + ref->string = 0; + ref->type |= cJSON_IsReference; + ref->next = ref->prev = 0; + return ref; +} + +/* Add item to array/object. */ +void cJSON_AddItemToArray(cJSON *array, cJSON *item) { + cJSON *c = array->child; + if (!item) + return; + if (!c) { + array->child = item; + } else { + while (c && c->next) + c = c->next; + suffix_object(c, item); + } +} +void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) { + if (!item) + return; + if (item->string) + cJSON_free(item->string); + item->string = cJSON_strdup(string); + cJSON_AddItemToArray(object, item); +} +void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) { + cJSON_AddItemToArray(array, create_reference(item)); +} +void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, + cJSON *item) { + cJSON_AddItemToObject(object, string, create_reference(item)); +} + +cJSON *cJSON_DetachItemFromArray(cJSON *array, int which) { + cJSON *c = array->child; + while (c && which > 0) + c = c->next, which--; + if (!c) + return 0; + if (c->prev) + c->prev->next = c->next; + if (c->next) + c->next->prev = c->prev; + if (c == array->child) + array->child = c->next; + c->prev = c->next = 0; + return c; +} +void cJSON_DeleteItemFromArray(cJSON *array, int which) { + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} +cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string) { + int i = 0; + cJSON *c = object->child; + while (c && cJSON_strcasecmp(c->string, string)) + i++, c = c->next; + if (c) + return cJSON_DetachItemFromArray(object, i); + return 0; +} +void cJSON_DeleteItemFromObject(cJSON *object, const char *string) { + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +/* Replace array/object items with new ones. */ +void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) { + cJSON *c = array->child; + while (c && which > 0) + c = c->next, which--; + if (!c) + return; + newitem->next = c->next; + newitem->prev = c->prev; + if (newitem->next) + newitem->next->prev = newitem; + if (c == array->child) + array->child = newitem; + else + newitem->prev->next = newitem; + c->next = c->prev = 0; + cJSON_Delete(c); +} +void cJSON_ReplaceItemInObject(cJSON *object, const char *string, + cJSON *newitem) { + int i = 0; + cJSON *c = object->child; + while (c && cJSON_strcasecmp(c->string, string)) + i++, c = c->next; + if (c) { + newitem->string = cJSON_strdup(string); + cJSON_ReplaceItemInArray(object, i, newitem); + } +} + +/* Create basic types: */ +cJSON *cJSON_CreateNull(void) { + cJSON *item = cJSON_New_Item(); + if (item) + item->type = cJSON_NULL; + return item; +} +cJSON *cJSON_CreateTrue(void) { + cJSON *item = cJSON_New_Item(); + if (item) + item->type = cJSON_True; + return item; +} +cJSON *cJSON_CreateFalse(void) { + cJSON *item = cJSON_New_Item(); + if (item) + item->type = cJSON_False; + return item; +} +cJSON *cJSON_CreateBool(int b) { + cJSON *item = cJSON_New_Item(); + if (item) + item->type = b ? cJSON_True : cJSON_False; + return item; +} +cJSON *cJSON_CreateNumber(double num) { + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_Number; + item->valuedouble = num; + item->valueint = (int)num; + } + return item; +} +cJSON *cJSON_CreateString(const char *string) { + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_String; + item->valuestring = cJSON_strdup(string); + } + return item; +} +cJSON *cJSON_CreateArray(void) { + cJSON *item = cJSON_New_Item(); + if (item) + item->type = cJSON_Array; + return item; +} +cJSON *cJSON_CreateObject(void) { + cJSON *item = cJSON_New_Item(); + if (item) + item->type = cJSON_Object; + return item; +} + +/* Create Arrays: */ +cJSON *cJSON_CreateIntArray(const int *numbers, int count) { + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateNumber(numbers[i]); + if (!i) + a->child = n; + else + suffix_object(p, n); + p = n; + } + return a; +} +cJSON *cJSON_CreateFloatArray(const float *numbers, int count) { + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateNumber(numbers[i]); + if (!i) + a->child = n; + else + suffix_object(p, n); + p = n; + } + return a; +} +cJSON *cJSON_CreateDoubleArray(const double *numbers, int count) { + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateNumber(numbers[i]); + if (!i) + a->child = n; + else + suffix_object(p, n); + p = n; + } + return a; +} +cJSON *cJSON_CreateStringArray(const char **strings, int count) { + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateString(strings[i]); + if (!i) + a->child = n; + else + suffix_object(p, n); + p = n; + } + return a; +} + +/* Duplication */ +cJSON *cJSON_Duplicate(cJSON *item, int recurse) { + cJSON *newitem, *cptr, *nptr = 0, *newchild; + /* Bail on bad ptr */ + if (!item) + return 0; + /* Create new item */ + newitem = cJSON_New_Item(); + if (!newitem) + return 0; + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference), + newitem->valueint = item->valueint, newitem->valuedouble = item->valuedouble; + if (item->valuestring) { + newitem->valuestring = cJSON_strdup(item->valuestring); + if (!newitem->valuestring) { + cJSON_Delete(newitem); + return 0; + } + } + if (item->string) { + newitem->string = cJSON_strdup(item->string); + if (!newitem->string) { + cJSON_Delete(newitem); + return 0; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + return newitem; + /* Walk the ->next chain for the child. */ + cptr = item->child; + while (cptr) { + newchild = cJSON_Duplicate( + cptr, 1); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) { + cJSON_Delete(newitem); + return 0; + } + if (nptr) { + nptr->next = newchild, + newchild->prev = nptr; /* If newitem->child already set, then crosswire + ->prev and ->next and move on */ + nptr = newchild; + } else { + newitem->child = newchild; /* Set newitem->child and move to it */ + nptr = newchild; + } + cptr = cptr->next; + } + return newitem; +} + +void cJSON_Minify(char *json) { + char *into = json; + while (*json) { + if (*json == ' ') + json++; + else if (*json == '\t') + json++; // Whitespace characters. + else if (*json == '\r') + json++; + else if (*json == '\n') + json++; + else if (*json == '/' && json[1] == '/') + while (*json && *json != '\n') + json++; // double-slash comments, to end of line. + else if (*json == '/' && json[1] == '*') { + while (*json && !(*json == '*' && json[1] == '/')) + json++; // multiline comments. + json += 2; + } else if (*json == '\"') { + *into++ = *json++; // string literals, which are \" sensitive. + while (*json && *json != '\"') { + if (*json == '\\') + *into++ = *json++; + *into++ = *json++; + } + *into++ = *json++; + } else + *into++ = *json++; // All other characters. + } + *into = 0; // and null-terminate. +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/cJSON/cJSON.h b/project/app/uvc_app_tiny/uvc_app/uvc/cJSON/cJSON.h new file mode 100644 index 000000000..9b1c7e4bb --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/cJSON/cJSON.h @@ -0,0 +1,171 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" { +#endif +#include + +/* cJSON Types: */ +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +#define cJSON_IsReference 256 + +/* The cJSON structure: */ +typedef struct cJSON { + struct cJSON *next, + *prev; /* next/prev allow you to walk array/object chains. Alternatively, + use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON + *child; /* An array or object item will have a child pointer pointing + to a chain of the items in the array/object. */ + + int type; /* The type of the item, as above. */ + + char *valuestring; /* The item's string, if type==cJSON_String */ + int valueint; /* The item's number, if type==cJSON_Number */ + double valuedouble; /* The item's number, if type==cJSON_Number */ + + char *string; /* The item's name string, if this item is the child of, or is + in the list of subitems of an object. */ +} cJSON; + +typedef struct cJSON_Hooks { + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +/* Supply malloc, realloc and free functions to cJSON */ +extern void cJSON_InitHooks(cJSON_Hooks *hooks); + +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. + * Call cJSON_Delete when finished. */ +extern cJSON *cJSON_Parse(const char *value); +/* Render a cJSON entity to text for transfer/storage. Free the char* when + * finished. */ +extern char *cJSON_Print(cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. + * Free the char* when finished. */ +extern char *cJSON_PrintUnformatted(cJSON *item); +/* Delete a cJSON entity and all subentities. */ +extern void cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +extern int cJSON_GetArraySize(cJSON *array); +/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. + */ +extern cJSON *cJSON_GetArrayItem(cJSON *array, int item); +/* Get item "string" from object. Case insensitive. */ +extern cJSON *cJSON_GetObjectItem(cJSON *object, const char *string); + +/* For analysing failed parses. This returns a pointer to the parse error. + * You'll probably need to look a few chars back to make sense of it. Defined + * when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +extern const char *cJSON_GetErrorPtr(void); + +/* These calls create a cJSON item of the appropriate type. */ +extern cJSON *cJSON_CreateNull(void); +extern cJSON *cJSON_CreateTrue(void); +extern cJSON *cJSON_CreateFalse(void); +extern cJSON *cJSON_CreateBool(int b); +extern cJSON *cJSON_CreateNumber(double num); +extern cJSON *cJSON_CreateString(const char *string); +extern cJSON *cJSON_CreateArray(void); +extern cJSON *cJSON_CreateObject(void); + +/* These utilities create an Array of count items. */ +extern cJSON *cJSON_CreateIntArray(const int *numbers, int count); +extern cJSON *cJSON_CreateFloatArray(const float *numbers, int count); +extern cJSON *cJSON_CreateDoubleArray(const double *numbers, int count); +extern cJSON *cJSON_CreateStringArray(const char **strings, int count); + +/* Append item to the specified array/object. */ +extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemToObject(cJSON *object, const char *string, + cJSON *item); +/* Append reference to item to the specified array/object. Use this when you + * want to add an existing cJSON to a new cJSON, but don't want to corrupt your + * existing cJSON. */ +extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, + cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +extern cJSON *cJSON_DetachItemFromArray(cJSON *array, int which); +extern void cJSON_DeleteItemFromArray(cJSON *array, int which); +extern cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string); +extern void cJSON_DeleteItemFromObject(cJSON *object, const char *string); + +/* Update array items. */ +extern void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +extern void cJSON_ReplaceItemInObject(cJSON *object, const char *string, + cJSON *newitem); + +/* Duplicate a cJSON item */ +extern cJSON *cJSON_Duplicate(cJSON *item, int recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new +memory that will +need to be released. With recurse!=0, it will duplicate any children connected +to the item. +The item->next and ->prev pointers are always zero on return from Duplicate. */ + +/* ParseWithOpts allows you to require (and check) that the JSON is null + * terminated, and to retrieve the pointer to the final byte parsed. */ +extern cJSON *cJSON_ParseWithOpts(const char *value, + const char **return_parse_end, + int require_null_terminated); + +extern void cJSON_Minify(char *json); + +/* Macros for creating things quickly. */ +#define cJSON_AddNullToObject(object, name) \ + cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object, name) \ + cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object, name) \ + cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddBoolToObject(object, name, b) \ + cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) +#define cJSON_AddNumberToObject(object, name, n) \ + cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object, name, s) \ + cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +/* When assigning an integer value, it needs to be propagated to valuedouble + * too. */ +#define cJSON_SetIntValue(object, val) \ + ((object) ? (object)->valueint = (object)->valuedouble = (val) : (val)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/camera_control.c b/project/app/uvc_app_tiny/uvc_app/uvc/camera_control.c new file mode 100644 index 000000000..37f4dcbcc --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/camera_control.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "camera_control.h" +#include "isp.h" +#include "param.h" +#include "uvc_log.h" + +extern char *rkuvc_iq_file_path_; + +struct Camera_Stream {}; + +void video_record_signal(struct Camera_Stream *stream) {} + +static void camera_stop(struct Camera_Stream *stream) { + LOG_INFO("%s \n", __func__); +} + +static void *uvc_camera(void *arg) {} + +int camera_control_start(int id, int width, int height, int fps, int format, + int eptz) { + if (rk_param_get_int("video.source:enable_aiq", 1)) + camera_control_set_rate(id, fps); + return 0; +} + +void camera_control_stop(int id) { + LOG_INFO("%s: id:%d\n", __func__, id); + int ret = 0; + if (rk_param_get_int("video.source:enable_aiq", 1)) + ret |= rk_isp_deinit(id); + if (rk_param_get_int("video.source:enable_aiq", 1)) + ret |= rk_isp_init(id, rkuvc_iq_file_path_); + return ret; +} + +void camera_control_init() { + LOG_INFO("%s \n", __func__); + if (rk_param_get_int("video.source:enable_aiq", 1)) { + rk_isp_init(0, rkuvc_iq_file_path_); + rk_isp_set_frame_rate(0, rk_param_get_int("isp.0.adjustment:fps", 30)); + if (rk_param_get_int("video.source:enable_2uvc", 0)) + rk_isp_init(1, rkuvc_iq_file_path_); + } else { + LOG_INFO("%s disabled aiq \n", __func__); + } +} + +void camera_control_set_rate(int index, int rate) { + LOG_INFO("camera index:%d rate:%d \n", index, rate); + if (rk_param_get_int("video.source:enable_aiq", 1)) { + rk_isp_set_frame_rate(index, rate); + } +} +void camera_control_set_zoom(int val) { LOG_INFO("set_zoom:%d\n", val); } + +void camera_control_set_pan(int val) { LOG_INFO("set_pan:%d\n", val); } + +void camera_control_set_tilt(int val) { LOG_INFO("set_tilt:%d\n", val); } + +void camera_control_set_roll(int val) { + LOG_INFO("set_roll:%d\n", val); + // todo +} + +void camera_control_deinit() { + LOG_INFO("%s \n", __func__); + if (rk_param_get_int("video.source:enable_aiq", 1)) { + rk_isp_deinit(0); + if (rk_param_get_int("video.source:enable_2uvc", 0)) + rk_isp_deinit(1); + } +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/camera_control.h b/project/app/uvc_app_tiny/uvc_app/uvc/camera_control.h new file mode 100755 index 000000000..1737c6076 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/camera_control.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __CARERA_CONTROL_H__ +#define __CARERA_CONTROL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "isp.h" +#include "param.h" +#include + +void camera_control_init(); +void camera_control_deinit(); +int camera_control_start(int id, int width, int height, int fps, int format, + int eptz); +void camera_control_stop(int id); +void camera_control_set_zoom(int val); +void camera_control_set_pan(int val); +void camera_control_set_tilt(int val); +void camera_control_set_roll(int val); +void camera_control_set_rate(int index, int rate); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/camera_pu_control.c b/project/app/uvc_app_tiny/uvc_app/uvc/camera_pu_control.c new file mode 100644 index 000000000..8c386756a --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/camera_pu_control.c @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "camera_pu_control.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "uvc_log.h" +#include + +int video_record_set_brightness(int brightness) { + rk_isp_set_brightness(0, brightness); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_contrast(int contrast) { + rk_isp_set_contrast(0, contrast); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_hue(int hue) { + rk_isp_set_hue(0, hue); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_staturation(int staturation) { + rk_isp_set_saturation(0, staturation); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_sharpness(int sharpness) { + rk_isp_set_sharpness(0, sharpness); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_fps(int fixfps) { + rk_isp_set_frame_rate(0, fixfps); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_gamma(int gamma) { + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_white_balance_temperature(int balance) { + //[2800,6500] + LOG_INFO("WhiteBalance color temperature is %d \n", balance); + rk_isp_set_white_blance_ct(0, balance); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_white_balance_temperature_auto(int balance) { + if (balance == 1) + rk_isp_set_white_blance_style(0, "autoWhiteBalance"); + else + rk_isp_set_white_blance_style(0, "manualWhiteBalance"); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_gain(int gain) { + rk_isp_set_exposure_gain(0, gain); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_hue_auto(int hue_auto) { + rk_isp_set_hue_mode(0, hue_auto); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_frequency_mode(int mode) { + if (mode == 1) + rk_isp_set_power_line_frequency_mode(0, "PAL(50HZ)"); + else + rk_isp_set_power_line_frequency_mode(0, "NTSC(60HZ)"); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_roll_mode(int mode) { + switch (mode) { + case 0: { + rk_isp_set_image_flip(0, "close"); + break; + } + case 1: { + rk_isp_set_image_flip(0, "flip"); + break; + } + case 2: { + rk_isp_set_image_flip(0, "centrosymmetric"); + break; + } + case 3: { + rk_isp_set_image_flip(0, "mirror"); + break; + } + default: { + rk_isp_set_image_flip(0, "close"); + break; + } + } + return 0; +} + +int video_record_set_exposure_time(int time) { + char str[8]; + sprintf(str, "%f", ((float)time / 10000)); + rk_isp_set_exposure_time(0, str); + LOG_INFO("%s \n", __func__); + return 0; +} + +int video_record_set_ae_mode(int mode) { + if (mode == 2) { + LOG_DEBUG("AE:set auto mode!!\n"); + rk_isp_set_exposure_mode(0, "auto"); + } else { + LOG_DEBUG("AE:set manual mode!!\n"); + rk_isp_set_exposure_mode(0, "manual"); + } + LOG_INFO("%s \n", __func__); + return 0; +} + +void camera_pu_control_init(int type, int def, int min, int max) { + LOG_DEBUG("%s!\n", __func__); +} + +int camera_pu_control_get(int type, int def) { + LOG_DEBUG("%s!\n", __func__); + return def; +} + +int check_ispserver_work() { + if (rk_param_get_int("video.source:enable_aiq", 1)) + return 1; + else + return 0; +} + +int camera_pu_control_set(int type, int value) { + LOG_DEBUG("%s! type is %d,value is %d\n", __func__, type, value); + if (!check_ispserver_work()) { + LOG_INFO("check ispserver is no ready,pu set fail!\n"); + return 0; + } + switch (type) { + case UVC_PU_BRIGHTNESS_CONTROL: + video_record_set_brightness(value); + break; + case UVC_PU_CONTRAST_CONTROL: + video_record_set_contrast(value); + break; + case UVC_PU_HUE_CONTROL: + video_record_set_hue(value); + break; + case UVC_PU_SATURATION_CONTROL: + video_record_set_staturation(value); + break; + case UVC_PU_SHARPNESS_CONTROL: + video_record_set_sharpness(value); + break; + case UVC_PU_GAMMA_CONTROL: + // video_record_set_gamma(value); + break; + case UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL: + video_record_set_white_balance_temperature(value); + break; + case UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL: + video_record_set_white_balance_temperature_auto(value); + break; + case UVC_PU_GAIN_CONTROL: + video_record_set_gain(value); + break; + case UVC_PU_HUE_AUTO_CONTROL: + video_record_set_hue_auto(value); + break; + case UVC_PU_POWER_LINE_FREQUENCY_CONTROL: + video_record_set_frequency_mode(value); + break; + case UVC_PU_FPS_CONTROL: + video_record_set_fps(value); + break; + case UVC_PU_ROLL_CONTROL: + video_record_set_roll_mode(value); + break; + case UVC_PU_EXPOSURE_TIME_CONTROL: + video_record_set_exposure_time(value); + break; + case UVC_PU_AE_MODE_CONTROL: + video_record_set_ae_mode(value); + break; + default: + LOG_DEBUG("====unknow pu cmd.\n"); + break; + } + return 0; +} + +int camera_pu_control_check(int deviceid) { + LOG_DEBUG("%s!\n", __func__); + return 0; +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/camera_pu_control.h b/project/app/uvc_app_tiny/uvc_app/uvc/camera_pu_control.h new file mode 100755 index 000000000..2d4d9dfed --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/camera_pu_control.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __CARERA_PU_CONTROL_H__ +#define __CARERA_PU_CONTROL_H__ +#include "camera_control.h" +#include + +void camera_pu_control_init(int type, int def, int min, int max); +int camera_pu_control_get(int type, int def); +int camera_pu_control_set(int type, int value); +int camera_pu_control_check(int deviceid); +int check_ispserver_work(); + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/osd.c b/project/app/uvc_app_tiny/uvc_app/uvc/osd.c new file mode 100755 index 000000000..c51e12eb8 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/osd.c @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "osd.h" +#include "osd_rockchip_logo.h" +#include "uvc_log.h" +#include "uvc_mpi_config.h" +#include "uvc_video.h" + +static RK_S32 osd_create(RGN_HANDLE handle, MPP_CHN_S *mppChn, RK_U32 layer, + RECT_S *rect) { + RK_S32 s32Ret = RK_SUCCESS; + RGN_ATTR_S stRgnAttr; + RGN_CHN_ATTR_S stRgnChnAttr; + if (mppChn->enModId == RK_ID_VPSS) + stRgnAttr.enType = OVERLAY_EX_RGN; + else + stRgnAttr.enType = OVERLAY_RGN; + stRgnAttr.unAttr.stOverlay.enPixelFmt = RK_FMT_RGBA8888; + stRgnAttr.unAttr.stOverlay.stSize.u32Width = rect->u32Width; + stRgnAttr.unAttr.stOverlay.stSize.u32Height = rect->u32Height; + stRgnAttr.unAttr.stOverlay.u32ClutNum = 0; + + s32Ret = RK_MPI_RGN_Create(handle, &stRgnAttr); + if (RK_SUCCESS != s32Ret) { + LOG_ERROR("RK_MPI_RGN_Create (%d) failed with %#x!\n", handle, s32Ret); + RK_MPI_RGN_Destroy(handle); + return s32Ret; + } + memset(&stRgnChnAttr, 0, sizeof(stRgnChnAttr)); + stRgnChnAttr.bShow = RK_TRUE; + stRgnChnAttr.enType = stRgnAttr.enType; + stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = rect->s32X; + stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = rect->s32Y; + stRgnChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = 0; + stRgnChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = 255; + stRgnChnAttr.unChnAttr.stOverlayChn.u32Layer = layer; + stRgnChnAttr.unChnAttr.stOverlayChn.stQpInfo.bEnable = RK_FALSE; + + s32Ret = RK_MPI_RGN_AttachToChn(handle, mppChn, &stRgnChnAttr); + if (RK_SUCCESS != s32Ret) { + LOG_ERROR("RK_MPI_RGN_AttachToChn (%d) failed with %#x!\n", handle, s32Ret); + } + + return s32Ret; +} + +static RK_S32 osd_destroy(RGN_HANDLE handle, MPP_CHN_S *mppChn) { + RK_S32 s32Ret = RK_SUCCESS; + + s32Ret = RK_MPI_RGN_DetachFromChn(handle, mppChn); + if (RK_SUCCESS != s32Ret) { + LOG_ERROR("RK_MPI_RGN_DetachFrmChn (%d) failed with %#x!\n", handle, + s32Ret); + } + s32Ret = RK_MPI_RGN_Destroy(handle); + if (RK_SUCCESS != s32Ret) { + LOG_ERROR("RK_MPI_RGN_Destroy [%d] failed with %#x\n", handle, s32Ret); + } + + return s32Ret; +} + +static RK_S32 osd_show_or_hide(RGN_HANDLE handle, const MPP_CHN_S *mppChn, + RK_BOOL bShow) { + RGN_CHN_ATTR_S stChnAttr; + RK_S32 s32Ret = RK_SUCCESS; + + if (RK_NULL == mppChn) { + LOG_ERROR("input parameter is null. it is invaild!\n"); + return RK_FAILURE; + } + + s32Ret = RK_MPI_RGN_GetDisplayAttr(handle, mppChn, &stChnAttr); + if (RK_SUCCESS != s32Ret) { + LOG_ERROR("RK_MPI_RGN_GetDisplayAttr (%d)) failed with %#x!\n", handle, + s32Ret); + return RK_FAILURE; + } + + stChnAttr.bShow = bShow; + + s32Ret = RK_MPI_RGN_SetDisplayAttr(handle, mppChn, &stChnAttr); + if (RK_SUCCESS != s32Ret) { + LOG_ERROR("RK_MPI_RGN_SetDisplayAttr (%d)) failed with %#x!\n", handle, + s32Ret); + return RK_FAILURE; + } + + return RK_SUCCESS; +} + +static RK_S32 osd_test_show_rockchip_logo(RGN_HANDLE handle) { + RK_S32 s32Ret = RK_SUCCESS; + RGN_CANVAS_INFO_S stCanvasInfo; + RK_U32 *data; + FILE *p; + + LOG_ERROR("test show rockchip logo\n"); + memset(&stCanvasInfo, 0, sizeof(RGN_CANVAS_INFO_S)); + + s32Ret = RK_MPI_RGN_GetCanvasInfo(handle, &stCanvasInfo); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_RGN_GetCanvasInfo failed with %#x!\n", s32Ret); + } + + data = (RK_U32 *)stCanvasInfo.u64VirAddr; + p = fopen("/data/rockchip-logo-320-96.rgba", "r"); + if (p) { + fread(data, 4, stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight, p); + fclose(p); + } else { +// no osd file, copy array to rgn +#if 1 // test rgba data to set 0 + memcpy(data, u32BGRA8888RKLOGO, + stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight * 4); +#else // test rgba data + for (RK_U32 i = 0; i < stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight; + i++) { + // RK_FMT_RGBA8888 + if (i < stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight / 4) + data[i] = 0xff000000; // black + else if (i < stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight / 2) + data[i] = 0xffff0000; // blue + else if (i < stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight / 4 * 3) + data[i] = 0xff00ff00; // green + else + data[i] = 0xff0000ff; // red + } +#endif + } + + s32Ret = RK_MPI_RGN_UpdateCanvas(handle); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_RGN_UpdateCanvas failed with %#x!\n", s32Ret); + } + + return s32Ret; +} + +static RK_S32 osd_test_init(UVC_MPI_CFG *uvcCfg) { + RGN_HANDLE handle = 0; + MPP_CHN_S mppChn; + RK_U32 layer = 0; + RECT_S rect; + RK_S32 s32Ret; + + if (uvcCfg->uvc_cfg.fcc == V4L2_PIX_FMT_YUYV || + uvcCfg->osd_cfg.force_use_vpss) { + mppChn.enModId = RK_ID_VPSS; + mppChn.s32DevId = uvcCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].group_id; + mppChn.s32ChnId = uvcCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].channel_id; + } else { + mppChn.enModId = RK_ID_VENC; + mppChn.s32DevId = 0; + mppChn.s32ChnId = uvcCfg->venc_cfg.common_cfg.channel_id; + } + rect.s32X = 100; + rect.s32Y = 200; + rect.u32Width = 320; // need align 16 + rect.u32Height = 96; // need align 16 + + s32Ret = osd_create(handle, &mppChn, layer, &rect); + s32Ret = osd_test_show_rockchip_logo(handle); + // defalut is show, if want hide this osd, refer to below setting + // osd_show_or_hide(handle, &mppChn, RK_FALSE); + + return s32Ret; +} + +static RK_S32 osd_test_deinit(UVC_MPI_CFG *uvcCfg) { + RK_S32 s32Ret; + MPP_CHN_S mppChn; + RGN_HANDLE handle = 0; + + if (uvcCfg->uvc_cfg.fcc == V4L2_PIX_FMT_YUYV || + uvcCfg->osd_cfg.force_use_vpss) { + mppChn.enModId = RK_ID_VPSS; + mppChn.s32DevId = uvcCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].group_id; + mppChn.s32ChnId = uvcCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].channel_id; + } else { + mppChn.enModId = RK_ID_VENC; + mppChn.s32DevId = 0; + mppChn.s32ChnId = uvcCfg->venc_cfg.common_cfg.channel_id; + } + + return osd_destroy(handle, &mppChn); +} + +RK_S32 osd_start(UVC_MPI_CFG *uvcCfg) { + RK_S32 s32Ret; + + // now just for test run + s32Ret = osd_test_init(uvcCfg); + + // TODO(user) you can comment the code above, and implement it yourself + return s32Ret; +} + +RK_S32 osd_stop(UVC_MPI_CFG *uvcCfg) { + RK_S32 s32Ret; + + // now just for test run + s32Ret = osd_test_deinit(uvcCfg); + + // TODO(user) you can comment the code above, and implement it yourself + return s32Ret; +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/osd.h b/project/app/uvc_app_tiny/uvc_app/uvc/osd.h new file mode 100755 index 000000000..444e7b6eb --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/osd.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __OSD_H__ +#define __OSD_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "rk_common.h" +#include "rk_mpi_rgn.h" +#include "uvc_mpi_config.h" + +RK_S32 osd_start(UVC_MPI_CFG *uvcCfg); +RK_S32 osd_stop(UVC_MPI_CFG *uvcCfg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/osd_rockchip_logo.h b/project/app/uvc_app_tiny/uvc_app/uvc/osd_rockchip_logo.h new file mode 100755 index 000000000..275e1263c --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/osd_rockchip_logo.h @@ -0,0 +1,5167 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __OSD_RK_LOGO_H__ +#define __OSD_RK_LOGO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +const unsigned int u32BGRA8888RKLOGO[320 * 96] = { + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffafcfe, 0xffecf7fd, 0xffddeffc, 0xffcde9fa, + 0xffc6e7f9, 0xffe0f2fc, 0xfffafdff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffeffff, 0xfff8fbfe, 0xffe3f3fd, 0xffd4eefc, 0xffcef0fe, + 0xffc4effd, 0xffb3e7fd, 0xff7dd1fb, 0xff4cbcf4, 0xff6dc9f5, 0xffc3eafb, + 0xfff5fbfe, 0xfffeffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffdfeff, 0xffe8f4fd, 0xffd6f0fc, 0xffd2f3fe, + 0xffcaedfc, 0xffbce5fa, 0xffb2dff8, 0xffaadcf6, 0xff9ed7f5, 0xff4ebbf1, + 0xff28b5f4, 0xff34bdf8, 0xff72d2f8, 0xffd3f0fb, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe7f4fd, 0xffd4f1fd, + 0xffcdeffc, 0xffbfe5f9, 0xffb5e1f8, 0xffacddf7, 0xffa2d9f6, 0xff9ad5f4, + 0xff92d1f4, 0xff4fbcf0, 0xff28b1ee, 0xff29b6ef, 0xff2bbdf4, 0xff5acffa, + 0xffd7f2fc, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfeff, 0xffe3f1fc, + 0xffcfeffe, 0xffc5eafb, 0xffb8e2f8, 0xffaedef7, 0xffa5daf6, 0xff9cd6f5, + 0xff94d2f4, 0xff86cdf3, 0xff5bbff0, 0xff2db2ee, 0xff28b3ee, 0xff29b6ee, + 0xff29baef, 0xff2bc1f4, 0xff5ed4fb, 0xffdaf4fd, 0xfffeffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffebf4fc, 0xffbee2fa, 0xffc0e9fb, 0xffb2dff8, 0xffa9dcf7, 0xff9fd7f6, + 0xff97d4f5, 0xff8ed0f4, 0xff70c4f1, 0xff44b7ef, 0xff28b0ed, 0xff28b3ee, + 0xff29b5ee, 0xff29b8ef, 0xff29bbf0, 0xff29bef0, 0xff2dc8f7, 0xff7fdefa, + 0xfff7fdfe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffdfeff, 0xffb7d8f7, 0xffa2d7f9, 0xffafdff8, 0xffa4d9f7, + 0xff9bd5f5, 0xff93d2f4, 0xff86cdf3, 0xff5cbcf0, 0xff31aeed, 0xff27afed, + 0xff29b2ee, 0xff29b5ee, 0xff29b7ef, 0xff29baef, 0xff29bdf0, 0xff29c0f0, + 0xff29c4f3, 0xff37cef7, 0xffd3f4fd, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff5fafd, 0xff60aaf0, 0xff8ecdf8, + 0xff9fd8f5, 0xff94d3f5, 0xff8acef3, 0xff68bef0, 0xff3aacec, 0xff26a8eb, + 0xff28aeec, 0xff29b1ee, 0xff29b4ee, 0xff29b7ee, 0xff29b9ef, 0xff29bcef, + 0xff29bff0, 0xff29c2f1, 0xff29c5f1, 0xff2acff9, 0xff7de0f8, 0xfffdfeff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd9eafa, + 0xff3291eb, 0xff5eb1f0, 0xff8acef3, 0xff78c5f1, 0xff50b2ee, 0xff2da4eb, + 0xff27a7ec, 0xff29aced, 0xff29b1ed, 0xff29b3ee, 0xff29b6ef, 0xff29b8ef, + 0xff29bbf0, 0xff29bef0, 0xff29c1f1, 0xff29c4f1, 0xff29c7f2, 0xff29cbf5, + 0xff51d7f8, 0xffeafafe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffb3d6f7, 0xff2b93f1, 0xff2c94e8, 0xff3ba1ea, 0xff33a1ea, + 0xff29a0eb, 0xff28a6eb, 0xff29abed, 0xff29afed, 0xff29b2ee, 0xff29b5ee, + 0xff29b8ef, 0xff29baef, 0xff29bdf0, 0xff29c0f0, 0xff29c3f1, 0xff29c6f2, + 0xff29c8f2, 0xff29cbf3, 0xff42dcfc, 0xffcdf4fc, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xff9bcaf4, 0xff2a98f2, 0xff2895e8, + 0xff2899e9, 0xff289fe9, 0xff29a4eb, 0xff29aaec, 0xff29aeed, 0xff29b1ed, + 0xff29b4ee, 0xff29b7ef, 0xff29b9ef, 0xff29bcef, 0xff29bff0, 0xff29c1f1, + 0xff29c4f1, 0xff29c7f2, 0xff29caf2, 0xff29ccf3, 0xff3bddfd, 0xffbbf0fc, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xff95c8f4, + 0xff2a9af2, 0xff2998e9, 0xff299dea, 0xff29a3ea, 0xff29a7ec, 0xff29aded, + 0xff29b0ee, 0xff29b3ee, 0xff29b6ee, 0xff29b9ef, 0xff29bbf0, 0xff29bef0, + 0xff29c0f1, 0xff29c3f1, 0xff29c6f2, 0xff29c9f2, 0xff29ccf3, 0xff29cef4, + 0xff39defd, 0xffb6f0fb, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffa1d1f5, 0xff2a9ef4, 0xff299be9, 0xff29a0ea, 0xff29a6eb, + 0xff29aaec, 0xff29afed, 0xff29b2ee, 0xff29b5ee, 0xff29b8ef, 0xff29baef, + 0xff29bdf0, 0xff29bff0, 0xff29c2f1, 0xff29c5f1, 0xff29c8f2, 0xff29cbf3, + 0xff29cdf3, 0xff29d0f4, 0xff3de2fd, 0xffc0f2fc, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffbedff9, 0xff2ca0f1, 0xff299fea, + 0xff29a4eb, 0xff29a9eb, 0xff29aded, 0xff29b1ed, 0xff29b3ee, 0xff29b6ee, + 0xff29b9ef, 0xff29bbf0, 0xff29bef0, 0xff29c1f0, 0xff29c4f1, 0xff29c6f2, + 0xff29caf2, 0xff29ccf3, 0xff29cff3, 0xff29d2f5, 0xff45e2fd, 0xffd6f7fd, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe5f2fd, + 0xff35a4ed, 0xff29a3ed, 0xff29a7ec, 0xff29abec, 0xff29b0ed, 0xff29b3ee, + 0xff29b5ee, 0xff29b8ef, 0xff29bbef, 0xff29bdf0, 0xff29c0f1, 0xff29c3f1, + 0xff29c6f2, 0xff29c8f2, 0xff29ccf3, 0xff29cef3, 0xff29d1f4, 0xff2ad7f8, + 0xff58e1f9, 0xfff2fdfe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffafdff, 0xff73c5f6, 0xff2aaaf1, 0xff29abec, 0xff29afed, + 0xff29b2ee, 0xff29b4ee, 0xff29b7ef, 0xff29baef, 0xff29bdf0, 0xff29bff0, + 0xff29c2f1, 0xff29c5f1, 0xff29c7f2, 0xff29caf2, 0xff29cef3, 0xff29d0f4, + 0xff29d3f4, 0xff2bdefb, 0xff9feefb, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff9f5f2, 0xfff7efea, 0xfff7f0eb, + 0xfff7f0eb, 0xfff7f0eb, 0xfff7f0eb, 0xfff7f0eb, 0xfff7f0eb, 0xfff7f0eb, + 0xfff7f0eb, 0xfff7f0eb, 0xfff7f0eb, 0xfff7f0eb, 0xfff6efea, 0xfff8f3ef, + 0xfffefefd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfaf9, 0xfffbf6f4, + 0xfffaf6f3, 0xfffaf6f2, 0xfffaf5f1, 0xfffaf4f1, 0xfff8f3ef, 0xfff8f2ee, + 0xfff8f1ed, 0xfff7f1ec, 0xfff7f0ec, 0xfff7f0ec, 0xfff7f1eb, 0xfff7efea, + 0xfff8f2ee, 0xfffefefd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffeffff, 0xffbbe3f9, 0xff3cb5f5, + 0xff29aeee, 0xff29b1ed, 0xff29b4ee, 0xff29b6ef, 0xff29b9ef, 0xff29bcf0, + 0xff29bff0, 0xff29c1f1, 0xff29c4f1, 0xff29c7f2, 0xff29c9f3, 0xff29ccf3, + 0xff29d0f4, 0xff29d2f4, 0xff2ad9f7, 0xff45e1fa, 0xffe0f9fe, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff8f2ee, 0xffc38d67, + 0xffad6330, 0xffad6431, 0xffad6431, 0xffad6431, 0xffad6431, 0xffad6431, + 0xffad6431, 0xffad6431, 0xffad6431, 0xffad6431, 0xffad6431, 0xffad6431, + 0xffaf642f, 0xffc5926f, 0xfffdfdfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffbf7f4, + 0xffcfa181, 0xffb57040, 0xffb26e3f, 0xffb16d3d, 0xffb16c3c, 0xffb16b3a, + 0xffaf6a38, 0xffaf6936, 0xffaf6734, 0xffad6532, 0xffad6532, 0xffad6431, + 0xffad6531, 0xffae6430, 0xffc8936e, 0xfffaf6f4, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff1f9fd, 0xff7fcff8, 0xff2db6f4, 0xff29b3ee, 0xff29b5ee, 0xff29b8ef, + 0xff29bbef, 0xff29bef0, 0xff29c1f0, 0xff29c3f1, 0xff29c6f2, 0xff29c9f2, + 0xff29cbf3, 0xff29cef3, 0xff29d1f4, 0xff29d4f5, 0xff34dffc, 0xff9feffb, + 0xfffbfeff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffecdace, 0xffb2632c, 0xff9b4000, 0xff9a4000, 0xff9a4000, 0xff9a4000, + 0xff9a4000, 0xff9a4000, 0xff9a4000, 0xff9a4000, 0xff9a4000, 0xff9a4000, + 0xff9a4000, 0xff9a4000, 0xffa04301, 0xffcc9d7c, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff5ede8, 0xffb0652f, 0xff9f4200, 0xff9c4100, 0xff9c4100, + 0xff9c4100, 0xff9c4100, 0xff9c4101, 0xff9c4101, 0xff9c4101, 0xff9b4101, + 0xff9b4101, 0xff9b4101, 0xff9b4100, 0xff9f4303, 0xffce9f7e, 0xfffdfaf9, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe5f5fd, 0xff63caf7, 0xff2ab9f4, + 0xff29b8f0, 0xff29b9ef, 0xff29bcf0, 0xff29bff0, 0xff29c3f1, 0xff29c5f2, + 0xff29c8f2, 0xff29caf2, 0xff29cdf3, 0xff29d0f3, 0xff29d4f6, 0xff2edcfb, + 0xff85ebfc, 0xffeffcfe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffdfcfb, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, + 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, + 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, + 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, + 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, + 0xfffdfbf9, 0xfffdfbf9, 0xfffdfbf9, 0xfffcfbf9, 0xfffffeff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffdfc4b0, 0xffa75216, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4302, 0xffe0c3b0, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffecdbd0, 0xffa04b0e, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa54f13, + 0xffdec1ad, 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffd6f0fc, 0xff61cdf7, 0xff2dc1f8, 0xff29bdf1, 0xff29bef0, 0xff29c1f1, + 0xff29c5f1, 0xff29c7f2, 0xff29caf2, 0xff29ccf3, 0xff29cff3, 0xff29d5f7, + 0xff2fddfb, 0xff7be9fc, 0xffeafbfe, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffecddd1, 0xffbb794b, 0xffaf6532, 0xffae6532, + 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, + 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, + 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, + 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, + 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, 0xffae6532, 0xffaf6533, + 0xffb47040, 0xffc18961, 0xffd2a789, 0xffe6d1c1, 0xfff3eae3, 0xfffcf9f7, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfbf9, 0xffcea283, 0xff9c4404, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4001, + 0xffa35015, 0xfff2e7de, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd9b69d, + 0xff9e4202, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4001, 0xffb26630, 0xffedded3, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffeffff, 0xffe8f8fd, 0xff97dffa, 0xff45cdfb, + 0xff32c9f9, 0xff2bc6f4, 0xff2ac9f4, 0xff29cbf4, 0xff2acef5, 0xff2bd2f7, + 0xff34dcfd, 0xff55e3fd, 0xffaaeffc, 0xfff1fdfe, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffffefe, 0xffdbbaa4, 0xffa14709, + 0xff9d4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, + 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, + 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, + 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, + 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, 0xff9c4100, + 0xff9c4100, 0xff9c4100, 0xff9d4201, 0xff9e4201, 0xff9e4302, 0xffa14b0e, + 0xffb36b37, 0xffcc9e7d, 0xffecdbd0, 0xfffdfbfa, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff9f4f0, + 0xffbf8257, 0xff9d4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9d4101, 0xffb56f3d, 0xfff9f3f0, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffc38e68, 0xff9e4201, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9c4102, 0xffbc7e53, 0xfff9f3ef, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffd4f3fd, 0xff9de4fa, 0xff74ddfb, 0xff60ddfd, 0xff5cddfd, + 0xff63e2fd, 0xff7be5fc, 0xffa6eefd, 0xffe5fafe, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefdfc, + 0xffca9874, 0xff9d4201, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4001, 0xff9c4101, 0xff9f4507, 0xffb26630, 0xffd6b197, + 0xfffefdfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff5ede7, 0xffaf642e, 0xff9c4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, 0xffc58f68, 0xfffbf8f6, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffbf8f5, 0xffb06b39, 0xff9c4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa14606, 0xffcca182, + 0xfffefefd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcfeff, 0xfff0fbfe, + 0xffe5f9fe, 0xffe2f8fe, 0xffe7fafe, 0xfff3fcfe, 0xfffdffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffcf9f7, 0xffb16937, 0xff9d4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4001, 0xffa04301, 0xffcb9c79, 0xfff9f4f0, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe8d4c6, 0xff9e4709, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9f480a, + 0xffd7b49c, 0xfffefdfd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffecdcd0, 0xffa8561b, + 0xff9a4000, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xffa34b0d, 0xffe5d0c0, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff4eae3, 0xffa04b0f, 0xff9b4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa54e11, 0xffd5b196, + 0xfffdfbf9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd6b196, + 0xff9e4202, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4001, 0xffaa581e, 0xffe5cfbf, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffdcbda7, 0xffa54d10, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4100, 0xffa7581f, 0xfff7f1ec, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffdfc4af, + 0xff9f4302, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9c4101, 0xffb0642e, 0xffefe1d7, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffffefe, 0xffc18861, 0xff9e4201, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xffb56b39, 0xfff0e3da, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffdfcfb, 0xffca9c7c, 0xffa04606, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9e4201, 0xffbb7d51, 0xfffefefe, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffffefe, 0xffc79673, 0xff9f4201, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9d4201, 0xffd0a585, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefdfd, 0xfffcf9f6, 0xfffbf7f4, 0xfffbf7f4, 0xfffbf8f5, + 0xfffdfbfa, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff9f3ef, 0xffac6330, 0xff9b4100, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4202, 0xffbe845c, + 0xfffaf6f3, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff6efea, 0xffbc7d50, 0xff9b4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9e4303, + 0xffd4ac91, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff9f4f0, 0xffb47143, 0xff9b4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4200, + 0xffb57241, 0xfffefefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefefe, 0xfff5ece6, + 0xffe8d4c5, 0xffd9b9a3, 0xffcfa589, 0xffc99977, 0xffc18c65, 0xffbf875f, + 0xffbe865e, 0xffc08962, 0xffc5936f, 0xffcda283, 0xffd8b69e, 0xffe6cfc1, + 0xfff7efea, 0xfffffffe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffebd9cd, 0xffa85419, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa14606, 0xffcfa386, 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffffffe, 0xfffefdfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffeedfd5, + 0xffb26731, 0xff9a4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4001, 0xffa24c10, 0xffe7d2c3, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfcfc, 0xfff9f4f1, + 0xfff5eee8, 0xffefe5dd, 0xffebded4, 0xffe5d5c9, 0xffe2d1c3, 0xffe2d1c3, + 0xffe4d2c6, 0xffe5d4c8, 0xffe6d6cb, 0xffe8dacf, 0xffece0d7, 0xfff2eae4, + 0xfffaf8f5, 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffebd9cc, 0xffae5e25, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4100, 0xffa35219, 0xfff7f1ec, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffdfbfb, 0xfff6eeea, 0xffe7d2c3, 0xffd0a485, + 0xffb77648, 0xffa8581f, 0xffa54e11, 0xffa44a0b, 0xffa14707, 0xff9f4505, + 0xff9e4303, 0xff9c4202, 0xff9c4202, 0xff9d4202, 0xff9f4404, 0xffa14606, + 0xffa44a0a, 0xffa64d10, 0xffa85a23, 0xffbd7f54, 0xffdab89f, 0xfff3e7df, + 0xfffcf9f7, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffdfcfb, 0xfff9f4f0, 0xfff4ebe4, 0xfff0e3da, 0xffe8d5c7, 0xffe0c5b1, + 0xffd9b7a0, 0xffd3a98d, 0xffce9f7f, 0xffcb9b79, 0xffca9976, 0xffc99773, + 0xffc89470, 0xffc7936e, 0xffc6916c, 0xffc6926d, 0xffc7936f, 0xffc89571, + 0xffc99673, 0xffca9875, 0xffcb9a78, 0xffcb9b79, 0xffcda080, 0xfff9f4f0, + 0xffd8b69e, 0xffa44c0d, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa54b0c, 0xffe3cab8, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcf9f7, 0xffdfc1ac, + 0xffbb7c50, 0xffb67547, 0xffb67547, 0xffb67547, 0xffb67547, 0xffb67547, + 0xffb67547, 0xffb67547, 0xffb67547, 0xffb67547, 0xffb67547, 0xffb67547, + 0xffb67547, 0xffb77547, 0xffb87647, 0xffbc8157, 0xffe4cebd, 0xfffefefe, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffefefe, 0xfffcf9f7, 0xfff7f0ea, 0xfff3e9e1, + 0xffeee0d6, 0xffe8d4c6, 0xffe2c9b6, 0xffdabaa2, 0xffd6af94, 0xffd3aa8e, + 0xffd0a586, 0xffcfa181, 0xffcd9e7d, 0xffcc9e7c, 0xffcea07f, 0xffd0a384, + 0xffd2a789, 0xffd3aa8d, 0xffd3ab8f, 0xffd4ac91, 0xffd7b399, 0xffdab9a2, + 0xfff4ebe4, 0xffe3cbba, 0xffa44f13, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9b4101, 0xffb46c39, 0xfff3e8e1, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffdfbfb, 0xfffcf9f8, 0xfffbf7f4, 0xfffaf6f4, 0xfffcf8f6, + 0xfffdfcfa, 0xfffffffe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffefefe, 0xfffefdfc, 0xfffdfcfb, 0xfffcfaf8, 0xfffbf8f6, 0xfffaf6f4, + 0xfff8f4f1, 0xfff7f2ee, 0xfff5f0eb, 0xfff4eee9, 0xfff3ece7, 0xfff2eae4, + 0xfff2eae3, 0xfff1e8e2, 0xfff1e8e1, 0xfff1e8e0, 0xfff8f4f0, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff9f6f3, 0xffe4d1c3, 0xffd7bda8, 0xffd1b29b, + 0xffcba990, 0xffc59d80, 0xffbe9372, 0xffb78964, 0xffb07c55, 0xffa97247, + 0xffa2673a, 0xff9e6031, 0xff9a5a29, 0xff965320, 0xff99531e, 0xff99521c, + 0xff99511b, 0xff99511b, 0xff99521b, 0xff99531c, 0xff99521c, 0xff99531e, + 0xff985320, 0xff995726, 0xff9f6334, 0xffab754c, 0xffc09778, 0xffd3b7a2, + 0xffe9dcd0, 0xfff6efeb, 0xfffdfbfb, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffdbbba5, 0xffa64f12, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9c4101, 0xff9d4201, 0xff9e4201, 0xff9d4201, 0xff9d4101, 0xff9c4101, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, 0xffa0490d, 0xfff2e5dd, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffefe2d8, 0xffd3ac90, 0xffbb794a, + 0xffa34d10, 0xff9e4301, 0xff9d4200, 0xff9b4100, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4100, 0xff9e4201, + 0xff9f4505, 0xffb26733, 0xffcfa181, 0xfff1e4db, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff9f4f0, 0xffe6cfbe, 0xffd2ab90, 0xffc38961, 0xffb56d3a, 0xffaa5a22, + 0xffa04a0e, 0xff9c4304, 0xff9b4202, 0xff9f4202, 0xffa04301, 0xffa04301, + 0xffa04200, 0xff9f4200, 0xff9f4200, 0xff9f4200, 0xff9f4200, 0xff9f4200, + 0xff9f4200, 0xff9f4200, 0xff9f4200, 0xff9f4200, 0xffa04200, 0xffa34401, + 0xffaa5b23, 0xfff9f4f1, 0xffc79673, 0xff9e4404, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, 0xffa4531a, 0xfff3eae3, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffaf5f1, + 0xffd5ae92, 0xffa85316, 0xff9e4200, 0xff9d4200, 0xff9d4200, 0xff9d4200, + 0xff9d4200, 0xff9d4200, 0xff9d4200, 0xff9d4200, 0xff9d4200, 0xff9d4200, + 0xff9d4200, 0xff9d4200, 0xff9d4200, 0xffa14300, 0xffb26127, 0xffd9b79e, + 0xfffaf6f3, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffdfbfa, 0xffeeded3, 0xffddbea8, 0xffca9978, + 0xffbc7c4f, 0xffb26834, 0xffa7561c, 0xff9f490c, 0xff9c4405, 0xff9c4202, + 0xff9d4202, 0xff9e4302, 0xff9f4302, 0xffa04302, 0xffa04302, 0xffa04301, + 0xffa04302, 0xffa04302, 0xff9f4302, 0xff9f4302, 0xff9e4202, 0xff9d4202, + 0xff9e4302, 0xffa85419, 0xffe9d5c8, 0xffd2aa8d, 0xff9d4303, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4102, 0xffc38c65, + 0xfff9f5f1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefdfd, 0xfff8f2ee, + 0xffeeded4, 0xffe3cbba, 0xffdabaa3, 0xffcfa689, 0xffc89978, 0xffc5916c, + 0xffc5906a, 0xffc79571, 0xffcfa687, 0xffdabba4, 0xffe9d6c8, 0xfff9f5f1, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffcfaf9, 0xffdecaba, 0xffcead95, 0xffc8a58c, 0xffc39e81, + 0xffbf9677, 0xffbd9270, 0xffb98b67, 0xffb5845e, 0xffb27e55, 0xffaf784e, + 0xffad754a, 0xffaa6f42, 0xffa76b3d, 0xffa5693b, 0xffa46637, 0xffa36535, + 0xffd8beab, 0xfffffffe, 0x00ffffff, 0x00ffffff, 0xffe5d5c9, 0xffa3612f, + 0xff8f460e, 0xff8f460e, 0xff91470f, 0xff92470e, 0xff91460e, 0xff90460d, + 0xff90460d, 0xff8f460d, 0xff8f450d, 0xff8e450d, 0xff8e450d, 0xff8d450d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xff8d450d, 0xff8e450d, 0xff90460d, + 0xff91470d, 0xff90470f, 0xff995723, 0xffb37e56, 0xffccab92, 0xffeaded4, + 0xfffefdfd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffcf9f8, 0xffc99b7a, 0xff9d4405, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4305, 0xffae6430, 0xffb16a38, 0xffb26b38, 0xffb16a37, + 0xffaf6632, 0xffa65820, 0xff9e490c, 0xff9e4302, 0xff9e4201, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xffa04a0d, 0xffefe2d9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff9f4f0, 0xffd8b59c, 0xffb36935, + 0xffa34a0b, 0xff9c4101, 0xff9a4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffa14708, 0xffb7713f, + 0xffe2cab8, 0xfffdfcfb, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffbf7f5, 0xffdbbda5, 0xffbb7c50, 0xffac5a1f, 0xffa0480a, 0xff9c4102, + 0xff9c4101, 0xff9b4101, 0xff9a4001, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9e4201, 0xffc0865d, 0xfff6eee8, 0xffbb7b4d, 0xff9b4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4201, + 0xffb16d3c, 0xfffefcfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff8f2ee, 0xffcc9d7b, 0xffa65013, 0xff9b4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4201, 0xffb1642e, + 0xffe5cebd, 0xfffdfcfb, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffdfbfa, 0xffe7d1c2, 0xffc5926d, 0xffb1642d, + 0xffa65114, 0xff9c4304, 0xff9c4101, 0xff9b4101, 0xff9b4101, 0xff9a4001, + 0xff9a4001, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9b4101, 0xffb46c39, 0xfff0e3da, 0xffc0855b, + 0xff9e4201, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa2490b, 0xffd5af95, 0xfffefefd, 0xfffdfcfa, 0xfff0e4db, 0xffdcbba3, + 0xffc6926f, 0xffb57345, 0xffb1642d, 0xffab581d, 0xffa54e10, 0xff9e4607, + 0xff9b4203, 0xff9b4101, 0xff9b4101, 0xff9b4102, 0xff9e4606, 0xffa54e11, + 0xffaf5e26, 0xffbc7f54, 0xffdfc3ae, 0xfffefcfb, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff7f2ee, 0xffb17f58, 0xff944c15, + 0xff914912, 0xff8e460f, 0xff8d450e, 0xff8e450e, 0xff8e450d, 0xff8f450d, + 0xff8e450d, 0xff8f450d, 0xff8f450d, 0xff8f450d, 0xff8e450d, 0xff8e450d, + 0xff8f450d, 0xff9c5824, 0xffe3d1c3, 0x00ffffff, 0x00ffffff, 0xfffffefe, + 0xffd9c1af, 0xff96501a, 0xff8d440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xff8e450d, 0xff8f450d, + 0xff944c16, 0xffa76a3c, 0xffd0b098, 0xfff8f3f0, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff5ede7, 0xffbb7849, 0xff9b4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9c4100, 0xffae6532, 0xfffcfaf9, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfaf9, 0xfff7efea, 0xffe5cebf, + 0xffc38d67, 0xffa8551c, 0xff9b4202, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4001, 0xffa14b0f, 0xfff4e9e2, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffbf8f6, 0xffe4cbba, 0xffb16834, + 0xff9f4201, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9c4101, 0xffa54e10, 0xffd0a687, 0xfffcf9f7, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffffffe, + 0xfff7efea, 0xffdbb9a2, 0xffb1652f, 0xffa04302, 0xff9c4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9d4404, 0xffdab9a0, 0xffebd9cd, + 0xffae6029, 0xff9a4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9e4301, 0xffca9977, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff3e8e1, 0xffba784b, 0xff9d4101, 0xff9a4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa04607, + 0xffbe835a, 0xfff1e6dd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff9f4f0, 0xffe3c8b6, 0xffb97649, 0xff9f4404, + 0xff9e4200, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4102, 0xffc38c65, + 0xfff6eee9, 0xffa85a23, 0xff9c4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa65216, 0xffcb9e7e, 0xffc99773, 0xffad612c, + 0xff9f4608, 0xffa04301, 0xff9e4201, 0xff9b4000, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, 0xff9f4302, 0xffbf8055, + 0xffeeddd4, 0xfffefdfd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff7f2ed, + 0xffae7a51, 0xff90460d, 0xff8e450d, 0xff8e450d, 0xff8e450d, 0xff8d440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8e450d, 0xffb0794f, 0xfff3eae4, 0x00ffffff, + 0x00ffffff, 0xfffdfbfa, 0xffc5a083, 0xff8e460e, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xff91460d, 0xffac7347, + 0xffeee4dc, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffeedfd5, + 0xffaa5b23, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9e4202, 0xffc58f69, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffbf7f5, 0xffdfc2ad, 0xffa7551a, 0xff9a4100, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9c4100, 0xffa85922, 0xfffaf5f2, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff9f4f0, 0xffd2a88b, + 0xffab591f, 0xff9d4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffa44d0f, + 0xffd8b69e, 0xfffdfbfb, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffedded2, 0xffbf8459, 0xffa44e11, 0xff9c4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffa6541a, + 0xffe9d7ca, 0xffe0c4b1, 0xffa14c0f, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xff9d4404, 0xffdcbca6, 0x00ffffff, + 0x00ffffff, 0xfffefdfd, 0xffead8cb, 0xffbc7c4e, 0xff9e4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, + 0xffa44d0e, 0xffc5906a, 0xfff5ede7, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff1e5dd, 0xffc7916d, 0xffa9551b, + 0xff9e4202, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa14809, 0xffd1a98d, 0xffefe0d5, 0xff9e4607, 0xff9a4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4204, 0xff9d4609, + 0xff9e4202, 0xff9c4101, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xffa04505, 0xffb97546, 0xffeee0d6, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffaf7f4, 0xffcfae95, 0xffbb8c68, 0xffb78762, 0xffb6845e, + 0xffb6835d, 0xffa4693c, 0xff8f4710, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff914811, 0xffbf9778, + 0xfffcf9f8, 0x00ffffff, 0x00ffffff, 0xfffbf8f6, 0xffb88661, 0xff8f450d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff91460d, 0xffb27b52, 0xffede0d8, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffdfc3ae, 0xff9e4607, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xff9e4405, 0xffdcbca6, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefcfc, + 0xffca9a78, 0xff9e4202, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9e4201, + 0xffb77648, 0xfffefefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffbf7f5, + 0xffc69069, 0xffa44c0e, 0xff9a4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffae5f26, 0xffe4cdbd, 0xfffffefe, 0x00ffffff, + 0x00ffffff, 0xfffdfbfa, 0xffe3cab8, 0xffb26833, 0xff9e4403, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4101, 0xffb77140, 0xfff2e7df, 0xffcea181, 0xff9c4203, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffa55319, + 0xffecdbd0, 0x00ffffff, 0xfffdfcfb, 0xffe3cab7, 0xffb16530, 0xff9e4405, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4101, 0xffaa571b, 0xffd4ac91, 0xfff8f2ee, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfcfb, 0xffe5cebd, 0xffb36b39, + 0xffa04606, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa95418, 0xffe1c7b4, 0xffd9b9a3, 0xffa04301, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa04505, 0xffbd7f54, + 0xfffdfcfa, 0x00ffffff, 0x00ffffff, 0xfffffefe, 0xfffbf8f6, 0xfff9f4f1, + 0xfff8f3ef, 0xfff7f2ee, 0xfff6f1ec, 0xffc39e81, 0xff924b13, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff9a531c, 0xffd7bfac, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff8f3f0, + 0xffa46739, 0xff8f450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff924912, 0xffb88763, + 0xfff5efea, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffc99674, 0xff9f4202, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffaa5a22, 0xffeedfd6, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffe2c8b6, 0xff9c4404, 0xff9a4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9e4303, 0xffd2a88b, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff6ede7, 0xffc58e67, 0xffa04403, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, 0xffa8561c, 0xffdec2ad, + 0xfffefdfd, 0x00ffffff, 0xfffefdfd, 0xffdab69d, 0xffab571d, 0xff9b4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xff9a4101, 0xff9c4101, 0xff9d4101, 0xff9d4101, 0xff9d4201, 0xff9d4201, + 0xff9d4101, 0xff9d4101, 0xff9f4303, 0xffc5916c, 0xfff8f3ef, 0xffba7a4c, + 0xff9d4201, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9c4101, 0xffb77240, 0xfff4ebe5, 0xfffaf5f1, 0xffd8b49a, 0xffa65216, + 0xff9c4100, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9d4303, 0xffae612a, 0xffe3c9b7, 0xfffefeff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfbfa, 0xffd7b297, + 0xffaa571c, 0xff9c4100, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9a4001, + 0xff9b4101, 0xff9c4101, 0xff9c4101, 0xff9c4101, 0xff9c4101, 0xff9c4101, + 0xff9a4001, 0xff9a4001, 0xff994001, 0xff9a4001, 0xffae612b, 0xfff1e5db, + 0xffc38f6a, 0xff9f4201, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xffa14605, 0xffddc0ac, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff6f1ec, 0xffb3815a, + 0xff8e460e, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8d440d, 0xff9f6030, 0xffefe6de, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffeee2da, 0xff934e19, 0xff8d450d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xff8e450d, 0xff8f450d, 0xff8f450d, + 0xff8f450d, 0xff8f450d, 0xff8d450d, 0xff8d440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8d440d, 0xff924912, 0xffd1b39c, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefdfd, 0xffb46f3e, + 0xff9d4200, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffbb7a4c, 0xfff6eee9, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe1c5b2, 0xff9c4304, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9b4101, 0xffa7541a, 0xffe9d5c7, 0x00ffffff, + 0x00ffffff, 0xfffaf6f3, 0xffcb9774, 0xffa34a0c, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa04607, + 0xffd4ae95, 0xfffbf8f5, 0x00ffffff, 0xfffffefe, 0xffe0c5b2, 0xffaa551a, + 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4100, 0xff9f4300, + 0xff9f4302, 0xff9d4405, 0xffa25015, 0xffac5f2a, 0xffb36b39, 0xffb97647, + 0xffba784a, 0xffba794a, 0xffb87547, 0xffb46d3b, 0xffb56b36, 0xffdbbba6, + 0xfff9f3ef, 0xffa7571e, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9b4102, 0xffc58e68, 0xfff8f1ec, 0xffcea080, + 0xffa65216, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa04404, 0xffb67241, 0xffe6cfbe, 0xfffefdfd, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfbf9, + 0xffd8b69e, 0xffa85316, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4100, 0xff9f4301, + 0xff9d4202, 0xff9e480c, 0xffa85921, 0xffac5e28, 0xffab5e27, 0xffab5e27, + 0xffab5e27, 0xffab5c25, 0xffa35116, 0xff9c4406, 0xff9f4302, 0xffa34401, + 0xffb67446, 0xfff6eee9, 0xffb47041, 0xff9b4100, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9d4202, 0xffbb7f54, 0xfff9f4f1, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffecdfd6, 0xffa86a3c, 0xff8d450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff90450d, 0xffaf7d56, 0xfffdfbfa, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffddc7b6, 0xff91470e, 0xff8c440d, + 0xff8d450d, 0xff8f450d, 0xff91470e, 0xff90460e, 0xff904913, 0xff985624, + 0xffa26435, 0xffa66b3e, 0xffa76b3e, 0xffa26537, 0xff9a5826, 0xff904812, + 0xff91470e, 0xff90460d, 0xff8d450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8f450d, 0xffa56a3e, 0xfffaf7f4, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff2e7e0, 0xffa24f13, 0xff9a4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4406, + 0xffcc9f7f, 0xfffcfaf9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffcda180, 0xff9d4202, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9e4304, 0xffc38b63, + 0xfff9f3ef, 0x00ffffff, 0xfffdfcfb, 0xffd3ab8f, 0xffa14708, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4101, 0xffa04707, 0xffa85114, 0xffaa5519, 0xffa85216, 0xffa2490a, + 0xff9c4202, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa04607, 0xffc89571, 0xfffdfbfa, 0x00ffffff, 0xfffefdfd, 0xffe2c9b6, + 0xffaf5f27, 0xff9b4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xff9b4101, 0xffa04708, 0xffab571d, + 0xffb16a39, 0xffc5926d, 0xffdab8a0, 0xffe8d4c5, 0xfff3e8e1, 0xfff7f1ed, + 0xfff9f4f0, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfff9f4f0, + 0xfff9f4ef, 0xfffcfaf9, 0xffe9d5c7, 0xff9d4304, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa14a0b, 0xffcb9f7f, + 0xffc59069, 0xffa24807, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9b4001, 0xffa34a0b, 0xffc1875e, 0xfff4eae3, + 0xfffefefd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffdfbfa, 0xffd8b49a, 0xffa95519, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xff9f4606, 0xffa9561b, + 0xffb16c3a, 0xffcb9c7b, 0xffdfc1ac, 0xffedded4, 0xfff6efe9, 0xfff8f2ed, + 0xfff8f2ed, 0xfff8f2ed, 0xfff8f2ed, 0xfff7f1ec, 0xfff3e8e1, 0xffe8d5c7, + 0xffdbbaa2, 0xffd0a181, 0xffdec0ab, 0xffead8cb, 0xffae5e25, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xff9a4101, 0xff9b4101, 0xff9b4101, 0xff9a4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffaf6027, 0xffe9d6c9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffffffe, 0xffdcc5b4, 0xff96511c, 0xff8d440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff92470e, + 0xffcfb098, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffc6a286, + 0xff9d5219, 0xff9e5925, 0xffa06335, 0xffb17f59, 0xffc6a084, 0xffdbc3b1, + 0xffe8dbd0, 0xfff2eae4, 0xfff7f2ee, 0xfff8f3f0, 0xfff8f4f0, 0xfff8f2ef, + 0xfff3ece6, 0xffe6d7cc, 0xffd4b9a3, 0xffb88966, 0xff9e5c2b, 0xff924a13, + 0xff8d440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff985019, 0xffdfcaba, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffdfc2af, 0xffa44a09, 0xff9a4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xffa85217, 0xffdec2af, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff5ece6, 0xffae642f, 0xff9c4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xffaa5920, 0xffe5cfbf, 0x00ffffff, 0x00ffffff, 0xffe6d1c2, 0xffa8561c, + 0xff9b4100, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9f4505, 0xffb16530, 0xffcb9e7d, 0xffdec2ad, 0xffe4ccbc, + 0xffe0c5b2, 0xffd1a98c, 0xffb87443, 0xff9d4304, 0xff9a4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9c4102, 0xffb77445, 0xfff3e9e2, 0x00ffffff, 0x00ffffff, + 0xfff1e4db, 0xffb36b38, 0xff9c4200, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9d4101, 0xffa24b0e, 0xffb77343, + 0xffcda283, 0xffe9d5c6, 0xfff8f3ee, 0xfffffefe, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd4ae93, 0xffa04301, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9e4607, 0xffa7571f, 0xffa04607, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffa55114, 0xffcd9e7e, + 0xfff8f2ee, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffe3cbba, 0xffa9581d, 0xff9b4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa04506, 0xffb0642d, + 0xffca9b78, 0xffe6d0c0, 0xfff8f3ee, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffffffe, 0xffdbbca6, + 0xffa74f13, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xff9d4101, 0xff9f470a, 0xffaf622c, 0xffb97647, 0xffba7849, 0xffae622b, + 0xff9f4606, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa54f12, 0xffdcbea9, 0xfffffffe, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfcfc, 0xffc49e81, 0xff8f460e, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8d440d, 0xff934e19, 0xffeadcd2, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffefefe, 0xffd8bfad, 0xffd3b59e, 0xffe1cfc1, 0xfff2eae4, 0xfffdfcfb, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfcfc, + 0xffe8d9ce, 0xffbf9474, 0xff944d16, 0xff8d450d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff934911, 0xffc59f83, 0xfffefefd, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffffffe, 0xffcb9e7e, 0xffa04504, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xffaf622b, 0xffeedfd4, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff8f2ed, 0xffc79471, 0xff9f4506, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xffa04301, 0xffcc9f7f, 0xfffdfaf8, 0x00ffffff, 0xfff6efe9, + 0xffc08458, 0xff9e4304, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa04505, 0xffbf8459, 0xffebd9cc, 0xfffcfaf8, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefdfc, 0xfff0e4da, 0xffbf8459, + 0xff9e4403, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xffa85316, 0xffddbfaa, 0xfffefdfc, + 0x00ffffff, 0xfffefefe, 0xffc79572, 0xffa04403, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9e4201, 0xffb06632, + 0xffdbbaa3, 0xfff3e9e1, 0xfffdfcfb, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefdfd, + 0xffc08a62, 0xff9e4200, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, 0xffa44c0f, + 0xffd9b59e, 0xfff9f5f2, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff3eae3, 0xffb36c3a, 0xff9c4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4100, 0xffa04809, + 0xffcb9a77, 0xffecdbce, 0xfffbf9f7, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffdfaf9, 0xffcc9e7e, 0xff9e4405, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4001, 0xffa14606, 0xffb46e3d, 0xffd9b8a0, 0xffeeded4, 0xfff4eae3, + 0xfff4ebe5, 0xffedddd3, 0xffcb9a78, 0xff9d4404, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9f4608, 0xffd2aa8d, + 0xfffdfcfb, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcfaf8, + 0xffad774e, 0xff90460d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8f450d, 0xffa86d40, 0xfff6f0ec, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffffefe, 0xfffdfbfa, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff8f4f0, 0xffc39a7d, 0xff914912, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8f450e, 0xffb2825d, + 0xfff9f5f2, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff6efea, + 0xffb87749, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4100, 0xffbb8056, + 0xfffcfaf8, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffcf9f7, 0xffebd9cc, 0xffba784a, 0xff9e4403, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa14708, 0xffc1875e, 0xfffcfaf8, 0x00ffffff, + 0xfffefdfd, 0xffd7b298, 0xffa1490a, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xffa04606, 0xffc48e67, 0xfffcfbf9, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff2e7df, 0xffb87443, 0xff9b4102, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9e4201, 0xffc28d66, + 0xfffdfbfa, 0x00ffffff, 0xfffefefe, 0xffdfc4b1, 0xffa64f11, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, 0xffac5a20, + 0xffd5ae92, 0xfff9f3ef, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff4eae3, 0xffaf6633, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9f4505, + 0xffb66e3b, 0xffe6cfbf, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff9f4f0, 0xffc58e67, + 0xffa04504, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9f4506, + 0xffb66f3d, 0xffe6cfbf, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff6efea, 0xffbd7d50, 0xff9c4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9d4303, 0xffaf612a, 0xffddbea9, 0xfffbf7f5, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcf9f7, 0xffc6916c, + 0xff9d4404, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9d4405, 0xffcea486, 0xfffdfbfa, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffefe6df, 0xff944e19, 0xff8d440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff90460f, 0xffc39c7d, + 0xfffcfaf8, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff6f1ed, 0xffb78763, 0xff8f4710, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8d440d, 0xffac7348, 0xfff1e9e2, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffebdace, 0xffb1632c, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa04301, 0xffd2ab8f, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffbf8f6, 0xffe7d2c3, 0xffcb9d7d, 0xffaf622b, + 0xff9d4101, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xffa14606, 0xffc08459, 0xfff1e5dd, + 0x00ffffff, 0x00ffffff, 0xfff9f4f0, 0xffb16936, 0xff9c4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffb5703e, + 0xfff1e6dd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffffefe, 0xffd1a98d, 0xffa14607, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xffa14a0d, 0xffead8cb, 0x00ffffff, 0x00ffffff, 0xfff6eee8, 0xffbe8054, + 0xff9d4303, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4201, + 0xffae612b, 0xffdfc2ad, 0xfffefdfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe6d2c2, 0xffac5a20, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xff9d4201, 0xffbe7f53, 0xffedddd1, 0xfffefdfd, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffffefe, + 0xffe1c6b2, 0xffa75419, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9d4101, 0xffba7748, 0xffecdcd0, 0xfffefefd, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff1e4db, 0xffaf632b, + 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff984001, 0xff9e4303, 0xffb67040, 0xffe6d0c1, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffe1c7b5, 0xffa65215, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9f4607, 0xffd2aa8e, 0xfffdfcfb, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd7beac, 0xff91470e, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff97511d, 0xffd8bfad, 0xfffefefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffffefe, 0xffd9c1ae, 0xff9b5620, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xffaa6e40, 0xffede3da, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffffefe, 0xffdec1ac, 0xffa54f12, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4001, 0xff9d4405, 0xffe8d3c6, 0xfff8f2ee, 0xfff6eee8, + 0xfff0e4db, 0xffe9d7c9, 0xffdcbca5, 0xffc99a78, 0xffb57345, 0xffaa571c, + 0xffa04608, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffa34909, 0xffc58b64, + 0xfff5ece6, 0xfffffefe, 0x00ffffff, 0x00ffffff, 0xffdfc3af, 0xffa04505, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa65114, 0xffdbbba4, 0xfffefdfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffe7d2c3, 0xffa34b0d, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9d4201, 0xffbc7e51, 0xfffbf8f7, 0x00ffffff, 0xfffffefe, + 0xffe0c4b1, 0xffa55014, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4001, 0xffaf612b, 0xffe3cbba, 0xfffdfcfb, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffffefe, 0xffd8b69d, + 0xffa44c0f, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4001, 0xffa34b0c, 0xffc38a62, 0xfff4ebe4, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffbf9f7, 0xffb97749, 0xff9d4202, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9c4101, 0xffab5c23, 0xffefe2d9, 0xfffffffe, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffe5cebe, 0xffa0490d, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9c4100, 0xffb56f3f, 0xffeddcd1, + 0xfffefdfd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffead7ca, 0xffb06028, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa1490b, 0xffd6b399, + 0xfffefdfd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefefd, 0xffbb906f, + 0xff90460d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8d440d, 0xffa66839, 0xffeaddd2, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff0e7e0, + 0xffa4683a, 0xff8d440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xffa96d3e, + 0xffece1d8, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcfaf8, 0xffcb9c7b, + 0xff9c4302, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4205, 0xffb06733, + 0xffae622d, 0xffa95921, 0xffa24c11, 0xff9c4304, 0xff9e4302, 0xff9f4301, + 0xff9d4100, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9d4202, 0xffaf6028, + 0xffd3aa8e, 0xfffbf7f5, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffbf7f5, + 0xffb97c50, 0xff9d4100, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffb77445, 0xfff7f0eb, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff2e7de, 0xffa14c11, 0xff9a4101, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xffa24c0f, 0xffdcbea8, 0xfffffefe, + 0x00ffffff, 0xfffdfaf9, 0xffbe8055, 0xff9d4201, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4001, 0xffa64f13, 0xffe5cebf, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffbf7f5, 0xffc6936f, 0xff9c4303, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffaa561c, 0xffd4ad91, 0xfff9f5f1, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe2c8b7, 0xff9e4403, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xffa44f13, 0xffdcbda7, 0xfffffefe, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffd1a789, 0xff9e4202, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4001, 0xffa8551c, + 0xffedddd2, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffebd9cd, + 0xffb1632b, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa54e11, 0xffddbfaa, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff3eae4, 0xffa56a3c, 0xff8d450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8f450e, 0xffb2835e, 0xfff9f5f3, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffdfbfa, 0xffb1805b, 0xff8f450d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8d440d, 0xffaa6e40, 0xffede2da, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff9f4f0, 0xffbc7b4e, 0xff9c4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9c4101, 0xff9c4101, 0xff9b4101, 0xff9b4001, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4100, 0xffa24809, + 0xffbc7b4d, 0xffe8d5c6, 0xfffcf9f7, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffead8cc, 0xffac5d24, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9f4301, 0xffcea486, 0xfffffffe, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff4eae3, 0xffa04e12, + 0xff9a4101, 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, 0xffb36834, + 0xffeedfd5, 0x00ffffff, 0x00ffffff, 0xfff3e7df, 0xffa24f12, 0xff9b4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9e4404, 0xffc99976, 0xfffefefe, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff5ede7, 0xffbb794a, 0xff9b4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9c4201, 0xffad5d25, 0xffddbca6, 0xfffcf9f7, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcf9f7, 0xffbe845b, + 0xff9e4100, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4201, 0xffbb7c51, + 0xfff5ede8, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffbd8258, 0xff9e4201, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9f4505, 0xffcfa283, 0xfffefdfd, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffe8d4c6, 0xffad5d24, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa95519, 0xffe2c7b6, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffe1cdbf, 0xff9f5b28, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff944a12, + 0xffc9a88e, 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffbe9474, 0xff91470d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xffac7245, 0xffefe6df, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff2e8e0, 0xffa7571d, 0xff9b4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9c4303, 0xffa64f10, + 0xffb57140, 0xffddbea9, 0xfff8f2ee, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffefdfd, 0xffd4af94, 0xffa34a0b, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9e4505, + 0xffedddd0, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffeee0d5, 0xffa14c0f, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff9d4203, 0xffc18b65, 0xfffbf7f4, 0x00ffffff, 0x00ffffff, 0xffd6b096, + 0xffa04301, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, 0xffb36935, + 0xffeedfd5, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffeeded4, 0xffaa5a22, + 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffb06734, 0xffe9d6c7, + 0xfffefcfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffe9d5c6, 0xffad5c23, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa54d0d, 0xffd8b49d, 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffaf5f2, + 0xffa85c25, 0xff9c4100, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4101, 0xffb36935, 0xffefe0d6, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe1c6b4, 0xffa54f14, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffaf5f27, 0xffe9d6c8, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfcfb, 0xffcaa98f, 0xff934b15, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8d440d, 0xff974f19, 0xffe5d5c9, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffc39d80, 0xff91470d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8e450d, 0xffad7950, + 0xfff5efea, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe2c8b6, 0xff9d4404, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4102, 0xffa75318, + 0xffc08358, 0xffdab8a0, 0xfff7f0eb, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff9f4f0, 0xffc28962, + 0xff9c4202, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9c4101, 0xffa85a24, 0xfffcfaf7, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffe3cbba, 0xffa44b0c, 0xff9a4001, 0xff994001, + 0xff994001, 0xff994001, 0xffa44b0b, 0xffd6b39a, 0x00ffffff, 0x00ffffff, + 0xfffdfaf8, 0xffba7f55, 0xff9d4100, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9e4304, 0xffc6936f, 0xfffcf8f6, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffdfc3af, 0xff9e4608, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4100, + 0xffb26a37, 0xffeedfd5, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefcfc, 0xffd2aa8e, 0xffa1480a, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffaa561b, 0xffebd9cd, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffead9cc, 0xffa34b0e, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9f4606, 0xffc99b79, 0xfffcfaf8, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefdfc, 0xffd3ac90, + 0xff9d4406, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffb36935, 0xfff1e4db, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff7f1ed, + 0xffb68560, 0xff8e450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8f450d, 0xff9e6132, 0xfffaf6f4, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffffefe, 0xffbb8f6e, 0xff91460d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8f460e, 0xffb68966, 0xfffbf9f6, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffcea182, 0xff9f4301, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, + 0xffb06734, 0xffe2c9b7, 0xfff7f0ea, 0xfffefefd, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff3e8e1, 0xffb76f3e, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9d4201, 0xffbb7b4e, 0xfffefefe, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd4af95, 0xffa34807, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa75216, 0xffe8d4c6, + 0x00ffffff, 0x00ffffff, 0xfff2e6de, 0xffaf6430, 0xff9a4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa44b0d, 0xffd5b299, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffcea080, 0xff9e4202, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9f4606, 0xffc48c64, 0xfff9f3ef, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff8f2ee, 0xffc0865b, 0xff9c4102, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, 0xffa75720, 0xfff2e6de, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd8b79f, 0xffa34808, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa85316, + 0xffe4cebd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffcf9f7, 0xffc58f69, 0xff9d4102, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffb67547, 0xfff8f1ed, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffefe4dc, 0xffa56838, 0xff8e450d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff90460e, 0xffb68662, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff7f2ee, 0xffa97248, 0xff8e450d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff924a11, 0xffc6a287, 0xfffffefe, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffcfaf9, 0xffb47244, 0xff9c4100, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffa95921, 0xffecdbcf, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffecdbcf, 0xffa6551b, 0xff9a4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4201, 0xffcb9b79, + 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffbf9f6, + 0xffbf875f, 0xff9c4302, 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, + 0xffaa5f29, 0xfff8f2ee, 0x00ffffff, 0x00ffffff, 0xffe2cab8, 0xffab571a, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa85114, 0xffe0c5b1, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefefd, 0xffb57243, 0xff9d4201, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9e4302, + 0xffcfa485, 0xfffefcfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff0e2d9, + 0xffae602a, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4000, + 0xffa8581f, 0xfff0e2d9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfaf9, 0xffc28e69, + 0xff9d4303, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9d4200, 0xffb47243, 0xfffcf9f7, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff9f3ef, 0xffb16733, 0xff9c4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9f4202, 0xffc5926e, 0xfffffefd, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffdcc6b6, 0xff914b15, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff914710, 0xffd3b7a2, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffffefe, 0xffdbc4b3, + 0xff9c5723, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff974f18, 0xffdcc6b5, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff0e4db, 0xffaa5a22, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9c4404, 0xffa35016, 0xff9d4505, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9e4201, 0xffc48f68, + 0xfffefefd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe3cbba, 0xff9f490c, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4102, 0xffd4ad91, 0xfffffffe, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff1e5dd, 0xffb46d3a, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff9e4200, 0xffb87749, 0xfffefdfd, 0x00ffffff, 0xfffffefe, + 0xffd7b59e, 0xffa44d0e, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa64e11, 0xffdcbda7, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff7f0ec, + 0xffa5551b, 0xff9b4100, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffa9551b, 0xffe5cfbf, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffe6d0c1, 0xffa04a0e, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa85215, 0xffe2cab8, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff5ece6, 0xffb77444, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9e4202, 0xffd0a586, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff0e3da, 0xffa14c10, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa14504, + 0xffd5b097, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffc6a184, + 0xff90460e, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8d440d, 0xff995523, 0xffe7d8cd, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff7f3ef, 0xffba8c68, 0xff904810, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d450d, + 0xff995622, 0xfff1e7e0, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffdfc2ae, + 0xffa75013, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa75114, 0xffcda183, + 0xffaf6129, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4101, 0xffa8551a, 0xffe8d4c7, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffdbbba5, 0xff9b4304, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9b4203, 0xffd8b59c, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe3cab8, 0xffa8551a, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff9f4201, 0xffc6916c, 0x00ffffff, + 0x00ffffff, 0xfffdfcfb, 0xffcda183, 0xff9e4506, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9f4506, 0xffc99a77, 0xfffcfaf8, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffdfcfb, 0xffe0c6b3, 0xffa1490a, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4203, 0xffb97445, + 0xffefe2d9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd7b49b, 0xff9c4203, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9f4506, 0xffc99875, + 0xfffcf8f6, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefdfd, 0xffe5cfbe, 0xffae5e25, 0xff9a4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9f480b, 0xffe8d5c7, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffddbea9, 0xff9f4302, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xffa04607, 0xffe7d2c3, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffefefe, 0xffad784f, 0xff90460d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8e450d, 0xffac7347, 0xfff2eae3, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefefe, 0xffd7bca9, 0xff97511c, 0xff8d440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff90460d, 0xffab764d, 0xfffefcfc, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffdfcfb, 0xffcb9d7e, 0xffa04607, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xffab5d26, 0xfff2e6df, 0xffc5916d, 0xff9f4201, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9d4303, 0xffc1875e, 0xfff8f2ee, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffd6b299, 0xff9b4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4303, 0xffd8b69e, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcfaf8, 0xffcb9c7a, + 0xff9d4303, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9e4201, + 0xffd2a98b, 0x00ffffff, 0x00ffffff, 0xfffbf7f4, 0xffc48f6a, 0xff9c4102, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, 0xffaf622a, + 0xffe8d4c6, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff5ebe5, 0xffd6af93, 0xffac5e26, 0xff9a4102, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xff9b4304, 0xff9a4103, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9e4303, 0xffc28a62, 0xfffaf6f4, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffcc9c7a, + 0xff9f4302, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4001, 0xffaa5a21, 0xffe2c8b6, 0xfffffefe, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffaf5f2, 0xffe0c2ad, 0xffb16732, 0xff9c4303, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9f490d, 0xff9c4508, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, + 0xffb26a38, 0xfff7efea, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefefd, 0xffc28d67, 0xff9f4201, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9b4001, 0xffa25016, 0xfff8f2ee, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff5efea, 0xff985623, 0xff8e450d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8f460e, + 0xffbd9371, 0xfffaf6f4, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffdfcfb, 0xffe4d2c5, 0xff9e5b29, 0xff8e450d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff914710, 0xffcfae96, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff7f0eb, 0xffbe8055, 0xff9b4102, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9d4100, 0xffb77649, 0xfffdfcfa, 0xffe9d5c7, 0xffa14809, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xffa8561b, 0xffe3c9b7, 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd6b197, 0xff9b4102, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4102, 0xffd5ae93, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff6efe9, 0xffaf6630, 0xff9c4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9e4202, 0xffdab89f, 0x00ffffff, 0x00ffffff, 0xfff9f4f0, + 0xffc0875f, 0xff9a4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9d4304, 0xffb97a4c, 0xfff8f2ed, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffbf6f3, 0xffdfc3af, 0xffba7a4c, 0xffa44c0e, 0xff9b4101, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9e4709, 0xffab622e, + 0xff9d4405, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4001, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa44b0c, 0xffdabaa3, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffc28a63, 0xff9e4201, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, 0xffb26a37, 0xfff1e5dc, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffeddcd0, 0xffc6916c, 0xffa9551a, + 0xff9c4101, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa65116, + 0xffb47345, 0xffa04a0d, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9c4101, 0xffc58f68, 0xfffbf7f4, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff7f0ec, 0xffaf6836, 0xff9b4100, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4201, 0xffb4703f, + 0xfffefefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe2d0c2, 0xff964e16, + 0xff8d440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff954d17, 0xffceb098, 0xfffefdfd, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfcfb, 0xffdcc5b4, 0xffa76b3d, + 0xff8f460e, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8e450d, 0xff9c5a27, + 0xffe9dbd0, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffedded2, 0xffb0642e, + 0xff9a4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9e4201, 0xffcea283, 0x00ffffff, + 0xfffefdfc, 0xffbb7d50, 0xff9d4201, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9d4202, 0xffbb7b4d, 0xfffaf5f2, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffdabaa2, 0xff9b4203, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9d4201, 0xffc6926d, 0xfffffefe, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefefe, 0xffd6b196, 0xff9f4403, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9d4202, 0xffddbfa9, 0x00ffffff, + 0x00ffffff, 0xfff8f2ee, 0xffbf845b, 0xff9b4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9f4403, 0xffb87749, + 0xffe7d1c2, 0xfffaf6f2, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffcfaf8, 0xfff5ebe5, 0xffdec1ac, 0xffb57040, 0xffa34b0d, 0xff9c4102, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa24c10, + 0xffbb8057, 0xffab5f29, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4101, 0xffa25016, 0xffa04a0d, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4001, 0xffac5c25, 0xffe6d1c2, 0xfffefefd, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffbb7e52, 0xff9e4201, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9d4202, 0xffb16936, 0xffe3c9b7, 0xfffaf5f2, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefdfd, 0xfff8f2ee, 0xffebdacd, 0xffcd9e7c, 0xffa7541a, + 0xff9f4504, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, + 0xffa85316, 0xffcc9e7d, 0xffb16835, 0xff9b4102, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xffa14a0c, 0xffd8b69e, 0xfffefdfd, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe5cebe, + 0xffa9561b, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9d4201, 0xffcb9c7a, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffcdae96, 0xff944a12, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff9f5c28, 0xffe0cdbe, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff8f3ef, 0xffd0af97, 0xffddc8b8, + 0xfff1e8e1, 0xfff8f5f2, 0xfffefdfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffaf6f4, 0xffece0d7, 0xffc39b7c, + 0xff97521d, 0xff8f460e, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff90470f, 0xffbb8d6b, 0xfff8f4f1, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffe0c5b3, 0xffa24c0f, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9f4506, + 0xffe4ccbc, 0x00ffffff, 0x00ffffff, 0xffe1c5b1, 0xffa44d11, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa04707, + 0xffe0c5b2, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffe1c8b6, 0xff9e480b, 0xff9a4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, 0xffae632f, + 0xfffbf9f7, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffeedfd4, 0xffaf642d, 0xff9b4100, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4202, + 0xffddbea8, 0x00ffffff, 0x00ffffff, 0xfff9f3ef, 0xffc0865d, 0xff9b4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9c4101, 0xffa9571d, 0xffc58f69, 0xffe1c7b4, 0xfff0e4da, + 0xfffbf8f5, 0xfffefefd, 0x00ffffff, 0x00ffffff, 0xfffefdfd, 0xfffbf8f5, + 0xfff3e8e1, 0xffe6d0c0, 0xffcda080, 0xffb66f3c, 0xffa1480a, 0xff9d4200, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xffa14708, 0xffc89571, 0xffbf8459, 0xffa04606, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9e4201, 0xffcd9f7f, + 0xffc8936e, 0xffa14608, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9d4302, 0xffba794b, 0xfff3e9e1, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffb87647, + 0xff9e4201, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, 0xffa85419, 0xffc58f68, + 0xffe5cdbd, 0xfff6ede7, 0xfffefdfb, 0x00ffffff, 0x00ffffff, 0xfffefdfd, + 0xfffbf7f5, 0xfff4eae3, 0xffe7d2c3, 0xffd7b39a, 0xffc1855b, 0xffa8571c, + 0xff9f4303, 0xff9a4100, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4001, 0xffab581e, 0xffd6b197, 0xffbf845b, 0xff9e4404, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffac5c23, + 0xffe7d2c3, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffefdfc, 0xffd0a88c, 0xffa24809, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4001, 0xff9f480b, 0xffdfc3b0, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffcfbf9, 0xffb98e6c, 0xff90470f, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xffa56739, + 0xfff0e6df, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe2d1c3, + 0xffa3602c, 0xff924b14, 0xffa6683b, 0xffbb8c6a, 0xffcfb19a, 0xffdecaba, + 0xffebdfd5, 0xfff4efe9, 0xfffaf7f4, 0xfffdfcfb, 0xfffefefe, 0xfffefefe, + 0xfffefcfc, 0xfffbf8f7, 0xfff5eeea, 0xffeadcd3, 0xffdbc4b3, 0xffbe9371, + 0xffa16333, 0xff914810, 0xff8d450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff9c5823, 0xffdbc5b4, 0xfffffefe, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefefe, 0xffcfa384, 0xff9d4203, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4101, 0xffa8571f, 0xfff3e9e1, 0x00ffffff, 0x00ffffff, 0xfff5ece5, + 0xffba7849, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9c4101, 0xffb8774a, 0xfff9f3ef, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffebdacd, 0xffa55419, + 0xff9a4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xffa04606, 0xffdfc3b0, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff4eae4, 0xffbe8156, + 0xff9e4505, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9e4202, 0xffd8b59d, 0x00ffffff, 0x00ffffff, 0xfffbf7f4, + 0xffc48e6a, 0xff9b4102, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xff9c4303, + 0xffaa551a, 0xffb06531, 0xffb97d51, 0xffc59370, 0xffcda081, 0xffcc9e7f, + 0xffc4906c, 0xffb97c51, 0xffb16836, 0xffad5b21, 0xff9f4507, 0xff9c4101, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4001, 0xffa04505, 0xffc99875, 0xffd1a789, 0xffa44d0f, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xff9d4304, 0xffe4ccbb, 0xfff0e2d8, 0xffb46c3a, 0xff9b4100, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xffa24809, 0xffcb9b7a, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffbc7f53, 0xff9e4201, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4101, 0xff9d4303, 0xffac581f, 0xffb46f3f, 0xffc28d67, 0xffc89876, + 0xffc89976, 0xffc28e69, 0xffba7c52, 0xffb16a38, 0xffae5c22, 0xffa34b0d, + 0xff9c4102, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4100, 0xffa75317, 0xffdbb9a1, 0xffd2a98d, 0xffa24808, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4001, 0xffb46e3a, 0xfff2e7df, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff8f3ef, 0xffc0865d, 0xff9c4102, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffac5d26, 0xffecddd2, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff5efea, 0xffad784e, 0xff8e440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8f450d, 0xffae7c55, 0xfffbf8f6, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffcfaf9, 0xffc8a589, 0xff914913, 0xff8d440d, 0xff8f450d, 0xff8f450e, + 0xff944d17, 0xff9e5a26, 0xffa56737, 0xffa77045, 0xffaf7c56, 0xffb88c6a, + 0xffbd9373, 0xffbc9374, 0xffba8d6d, 0xffb1815b, 0xffa77045, 0xffa56635, + 0xff9b5622, 0xff8f460e, 0xff8e450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8f450d, 0xffb17d56, 0xfff7f3ef, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefcfb, 0xffb77343, 0xff9d4201, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9c4101, 0xffbe7f53, 0xfff9f4f1, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffdbbca6, 0xffa65012, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa54d0f, 0xffd5b197, + 0xfffefcfb, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff3e8e0, 0xffb66e3c, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, 0xffa7561d, 0xffd8b59c, + 0xfff2e6de, 0xfff9f3ef, 0xfffaf5f2, 0xfff6efe9, 0xffefe0d6, 0xffdab8a1, + 0xffae6029, 0xff9d4201, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9e4201, 0xffcc9f7e, 0x00ffffff, + 0x00ffffff, 0xfffefdfc, 0xffd0a789, 0xffa04608, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9c4100, 0xff9e4100, + 0xffa04300, 0xffa04200, 0xff9e4100, 0xff9c4100, 0xff9a4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffa95519, 0xffd3ad92, 0xffddc0ab, 0xffa04606, + 0xff9b4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffa95b22, 0xfff5ebe5, 0x00ffffff, 0xffebdcd0, + 0xffa9561b, 0xff9b4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9f4404, 0xffdec0ab, 0xfffefcfc, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffcea181, 0xff9e4202, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4100, + 0xff9d4100, 0xff9f4200, 0xff9f4200, 0xff9e4100, 0xff9c4101, 0xff9a4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9c4202, 0xffaa5a21, 0xffe2c8b6, 0xffd7b399, + 0xffa85114, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9d4302, 0xffc18b64, 0xfffcfaf9, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffeeded4, 0xffb0622c, + 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, + 0xffbe7e53, 0xfff7efea, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffede2d9, + 0xffa96c3e, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff92470d, 0xffc49e82, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff0e7df, 0xffa46738, 0xff8e450d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xff8d450d, + 0xff8e450d, 0xff90450d, 0xff90460d, 0xff90460d, 0xff90450d, 0xff8f450d, + 0xff8d450d, 0xff8d440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xff97501a, + 0xffe8d9ce, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff8f2ee, + 0xffa35218, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4304, 0xffcda080, + 0xfffdfbf9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff6ede7, 0xffb36d3b, + 0xff9b4100, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4101, 0xffb77141, 0xfff3e9e1, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff9f4f1, 0xffc38b64, 0xff9b4202, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4101, 0xffa34d10, 0xffb6713e, 0xffbe855c, 0xffc08962, 0xffbc7e51, + 0xffb26630, 0xffa04809, 0xff9c4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9e4200, + 0xffbb7f55, 0xfffefefe, 0x00ffffff, 0x00ffffff, 0xffdec1ac, 0xffa85215, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9c4100, 0xffa9561a, 0xffd9b7a0, 0xffe5cebd, + 0xffaf632d, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, 0xffbb794c, 0xfff9f3f0, + 0x00ffffff, 0x00ffffff, 0xffd6b095, 0xffa54e10, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, + 0xffb26834, 0xffebdbcf, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe0c5b1, + 0xff9e4708, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9d4302, 0xffb16733, 0xffe2c6b4, + 0xffdfc1ad, 0xffaa5a21, 0xff9a4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa14605, 0xffd2ab8f, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffdfc4b0, 0xffa0490c, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9e4606, 0xffcb9d7c, 0xfffdfbf9, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffe6d7cb, 0xffa36332, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff92470e, 0xffd7beab, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd3b7a1, 0xff924912, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff914810, 0xffbc9170, 0xfffefdfd, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffe5cfc0, 0xff9f4404, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa55013, 0xffdfc3ae, 0xfffffffe, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffefefe, 0xffd5b096, 0xffa04403, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xffa04708, 0xffd5b095, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefefe, 0xffd7b59d, + 0xffa44d0f, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4101, 0xff9b4101, 0xff9b4101, + 0xff9b4102, 0xff9b4101, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffa95c25, 0xfff5ede6, 0x00ffffff, 0x00ffffff, + 0xfff1e3da, 0xffb0642e, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xff9e4404, 0xffb26632, 0xffe1c7b4, + 0xffecdacf, 0xffb46d3a, 0xff9d4404, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4203, + 0xffcb9b7a, 0xfffcfaf8, 0x00ffffff, 0x00ffffff, 0xfff8f3ef, 0xffc7936e, + 0xffa04707, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9f4505, 0xffc0845a, 0xfff7efea, 0x00ffffff, + 0x00ffffff, 0xfff0e3da, 0xffaf642e, 0xff9b4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa04405, 0xffb56f3c, + 0xffead7cb, 0xffe7d1c2, 0xffaa5b23, 0xff9b4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xffa34909, 0xffe4ccbb, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffc89672, 0xff9e4201, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xffa75215, 0xffdec1ac, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe0ccbe, 0xff9d5a27, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d440d, + 0xff904811, 0xffe8dacf, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff8f4f0, + 0xffa76e43, 0xff8f450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8f460e, 0xffac7347, 0xffece0d6, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffcda284, 0xffa04300, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4001, 0xffb2652f, 0xffedddd2, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff6efea, 0xffac602a, 0xff9c4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, + 0xffaa5c24, 0xfff6eee9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff2e7df, 0xffb36936, 0xff9b4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa54c0e, 0xffdab9a3, + 0xfffffefe, 0x00ffffff, 0xfffffefd, 0xffc99a78, 0xff9e4301, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffa34b0c, 0xffbf8358, + 0xfff0e3d9, 0xfff1e4dc, 0xffb46c39, 0xff9d4201, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xffa44e11, 0xffddbfaa, 0xfffffefe, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff4ece6, 0xffba794b, 0xff9d4100, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9e4302, + 0xffcda181, 0xfffdfcfb, 0x00ffffff, 0xfffbf8f5, 0xffca9976, 0xff9f4506, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4001, 0xffa34a0d, + 0xffc48961, 0xfff1e7df, 0xffe4cdbd, 0xffae632d, 0xff9c4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffa25015, 0xfff5ede7, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfbfa, 0xffac622d, 0xff9c4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffad602a, + 0xfff0e4db, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffdcc6b6, + 0xff9a5520, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8e450d, 0xff965320, 0xfff7f1ed, 0x00ffffff, 0x00ffffff, + 0xfffefdfc, 0xffd1b49e, 0xff974f18, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8e450d, 0xffa2612f, 0xffe2d0c2, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffbf8f6, 0xffb97c51, + 0xff9c4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9b4102, 0xffb9794d, 0xfff8f2ed, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfcfa, + 0xffcea181, 0xff9e4405, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa04404, 0xffd1a98d, 0xfffefefd, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefdfd, 0xffd2ac8f, 0xff9f4301, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9c4203, 0xffbe7f53, 0xfff5ede7, 0x00ffffff, 0x00ffffff, 0xfff0e2d8, + 0xffa75418, 0xff9b4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9d4200, 0xffa75419, + 0xffd1a485, 0xfff5ece6, 0xfff0e3da, 0xffbe7d50, 0xff9e4303, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4001, 0xffaf6028, 0xffe9d6c9, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffead8cc, 0xffaa591f, + 0xff9c4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9b4101, 0xffa9571c, 0xffe4ccbc, 0x00ffffff, 0x00ffffff, + 0xffe8d3c5, 0xffac5b22, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, + 0xff9f4707, 0xffcfa181, 0xfff6ede8, 0xffecdbcf, 0xffb16833, 0xff9d4302, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9d4100, 0xffb06834, 0xfffefdfc, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff0e2d9, + 0xffa0470a, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9d4100, 0xffb8794e, 0xfffcfaf9, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffdbc5b4, 0xff99531f, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8f450d, 0xffa06334, 0xfffcfaf9, + 0x00ffffff, 0x00ffffff, 0xfff0e7e0, 0xffae774d, 0xff8e460e, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8e450d, 0xff99531d, 0xffd5baa5, + 0xfffdfdfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffefe0d6, 0xffb0642d, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa04504, + 0xffcca080, 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffecdacf, 0xffb1642f, 0xff9b4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffb1652f, + 0xffebd9ce, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffaf5f2, 0xffba794a, 0xff9f4505, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9a4101, 0xffa04606, 0xffbe8055, 0xfff3e8e1, 0x00ffffff, + 0x00ffffff, 0xfffefdfc, 0xffd6b298, 0xffa44f12, 0xff9b4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffa44c0e, + 0xffb97646, 0xffead8cb, 0xfffcf9f8, 0xffecdbcf, 0xffb56e3c, 0xff9e4404, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffb77545, + 0xfff5ede8, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffefdfc, 0xffdbbaa4, 0xffa75318, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4102, 0xffb56e3b, + 0xffeddcd1, 0xfffffffe, 0xfffefdfc, 0xffd3ad91, 0xffa34909, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xff9e4405, 0xffb26731, 0xffdcbca6, 0xfffbf8f6, 0xffead7ca, 0xffb06632, + 0xff9d4202, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9f4301, + 0xffc38a62, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffd5b096, 0xffa14402, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa04301, 0xffd1a78a, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffddc8b7, 0xff9a5621, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8f450d, + 0xffaa7348, 0xfffcfbfa, 0x00ffffff, 0xfffdfcfb, 0xffc9a78c, 0xff964e17, + 0xff924d17, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xff8f460e, 0xffa56434, + 0xffd7bca8, 0xfffcfaf8, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffe0c4b1, 0xffa95418, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xffa34a09, 0xffe1c7b4, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcf9f7, 0xffc99876, + 0xffa04505, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9f4606, 0xffcc9c7a, 0xfffcf8f6, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffffffe, 0xffecdace, 0xffb6703e, 0xff9e4303, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9c4101, 0xffa54e10, 0xffc69069, 0xfff3e9e1, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffaf4f1, 0xffd1a687, + 0xffa44e12, 0xff9c4101, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, 0xff9d4202, + 0xffb46a36, 0xffd5ad92, 0xfff7f0eb, 0x00ffffff, 0xfff5ebe5, 0xffb7703e, + 0xff9e4201, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9e4303, 0xffc4926e, 0xfffdfcfb, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffaf6f3, 0xffcd9e7e, 0xffa14708, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9e4403, 0xffc0865e, 0xfffbf7f4, 0x00ffffff, 0xfffbf8f6, + 0xffc58e67, 0xffa44a0b, 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9c4101, 0xffa34c0e, 0xffc2885f, 0xffedddd1, 0xfffefefd, 0xfff3e9e2, + 0xffbb794a, 0xff9e4302, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9d4202, 0xffd2a98b, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffcf9f7, 0xffbd845a, 0xff9d4201, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9e4506, 0xffe8d3c5, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe4d2c5, + 0xffa15f2d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff90460d, 0xffad764c, 0xfffdfbfa, 0x00ffffff, 0xffeaddd2, + 0xffa05e2a, 0xffaf794f, 0xffad7850, 0xff8f450d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8e440d, 0xff944b13, + 0xffad754a, 0xffe4d2c5, 0xfffdfcfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfcfb, 0xffcfa689, 0xff9f4707, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9a4100, 0xffa35015, 0xfff4eae3, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffead8cb, 0xffa55014, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9b4101, 0xffa95a22, 0xffefe1d7, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefdfc, + 0xffebd9cd, 0xffb56c39, 0xff9f4301, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9f4301, 0xffab5d25, 0xffd8b399, + 0xfff8f1ed, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffaf5f2, 0xffd6b298, 0xffab581d, 0xff9f4201, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4100, 0xffa04301, + 0xffa8561c, 0xffcb9b78, 0xffefe0d6, 0xfffdfbf9, 0x00ffffff, 0x00ffffff, + 0xffe3cab9, 0xffaa5315, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xffa34807, 0xffd8b69e, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff7f1ec, 0xffb87546, 0xff9e4201, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa34a0a, 0xffd9b8a0, + 0x00ffffff, 0x00ffffff, 0xfff5ece6, 0xffcb9875, 0xffa44a0b, 0xff9c4100, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9b4100, 0xffa14402, 0xffad612c, 0xffd7b399, 0xfff7efea, 0x00ffffff, + 0x00ffffff, 0xffe8d3c6, 0xffa8551a, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9d4608, 0xffdfc3b0, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff0e3da, 0xffb26733, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9c4101, + 0xffa8581f, 0xfff7f0ea, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffefe5dd, 0xffaa6e42, 0xff8d440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8f450d, 0xffa4683b, 0xfffcfaf9, + 0xfff2e9e3, 0xffb17c53, 0xffa86b3d, 0xffe6d7cb, 0xffa87147, 0xff8f450d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8e440d, 0xff92470e, + 0xff9d5a29, 0xffc8a488, 0xffeee4db, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcf9f6, + 0xffc99876, 0xff9c4303, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9b4100, 0xffa75921, + 0xfff9f4f1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff5ede7, 0xffab5e27, 0xff9b4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, + 0xffa1490b, 0xffe3c9b6, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffaf6f3, 0xffcb9a77, 0xffa75214, 0xff9c4201, + 0xff9a4001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9c4101, 0xffa85215, + 0xffc38a62, 0xffeedfd4, 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffedded3, 0xffc08257, + 0xffa85217, 0xff9c4102, 0xff9b4001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9b4101, + 0xff9e4404, 0xffab581d, 0xffbf835a, 0xffe5cebc, 0xfffefdfc, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffdcbea8, 0xffa74f11, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xffa44a0a, 0xffe0c5b2, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffcb9b7a, 0xffa24708, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9f4301, 0xffc5906b, 0xfffaf6f3, 0x00ffffff, 0xfffdfcfb, 0xffe2c7b4, + 0xffb46b37, 0xffa14608, 0xff9b4101, 0xff9a4001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9a4001, 0xff9b4101, 0xff9e4404, 0xffad5b20, 0xffc6906c, 0xffefe0d6, + 0xfffffefe, 0x00ffffff, 0x00ffffff, 0xffe1c9b8, 0xffa24d10, 0xff9a4001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa14b0e, + 0xffe5cebd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffead8cb, 0xffb06027, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff9c4101, 0xffb06531, 0xfffaf5f1, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff5eee9, 0xffae7950, 0xff8e450d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8e450d, + 0xff9c5b2a, 0xffeadcd2, 0xffdac1ae, 0xffa15f2d, 0xffbe9271, 0xfff2eae4, + 0xffa16537, 0xff8e450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8e450d, 0xff8f450d, + 0xff914912, 0xffa05c28, 0xffb78864, 0xffe4d3c6, 0xfffdfcfb, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff6eee9, 0xffbb7a4c, 0xff9b4101, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff9e4201, 0xffbb7c50, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xffcc9d7c, 0xff9e4202, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9e4200, 0xffb97a4d, 0xfffbf7f5, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffbf7f4, + 0xffdab8a1, 0xffb77343, 0xff9d4403, 0xff9d4100, 0xff9a4001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff9c4100, 0xff9e4301, 0xffa34f13, + 0xffbd7e52, 0xffddbda6, 0xfff9f5f1, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfff6f0eb, 0xffdfc2ad, 0xffc08257, 0xffa9591f, 0xff9e4404, + 0xff9f4301, 0xff9d4200, 0xff9c4100, 0xff9b4100, 0xff9a4001, 0xff9a4001, + 0xff9a4001, 0xff9a4001, 0xff9a4001, 0xff9b4100, 0xff9d4200, 0xff9e4201, + 0xff9e4607, 0xffb26935, 0xffc99673, 0xffe3cbb8, 0xfff9f4f1, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefcfb, 0xffcc9d7d, 0xffa14606, + 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, + 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9d4100, + 0xffa34e11, 0xfff2e6de, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff4eae4, + 0xffbb7a4d, 0xff9e4302, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, + 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, + 0xff9b4100, 0xff9b4100, 0xff9c4100, 0xffa75013, 0xffd8b59c, 0xfffdfbfa, + 0x00ffffff, 0x00ffffff, 0xffeeded4, 0xffce9e7e, 0xffb26732, 0xff9d4404, + 0xff9e4201, 0xff9c4100, 0xff9a4000, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xff9b4100, + 0xff9c4100, 0xff9e4201, 0xff9e4404, 0xffb0652e, 0xffc9956f, 0xffe5cdbb, + 0xfffcf8f6, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffffefe, 0xffd2a689, + 0xff9f4303, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, + 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, + 0xff9d4200, 0xffac5c23, 0xffeddfd4, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefefe, 0xffd9b8a1, 0xffa54d0f, 0xff9b4100, 0xff9b4100, + 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9b4100, + 0xff9b4100, 0xff9b4100, 0xff9b4100, 0xff9f4300, 0xffc38960, 0xfffcf9f7, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefdfd, + 0xffcaa88f, 0xff944a12, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xffa66838, 0xffa25f2c, 0xffbb8d6b, + 0xfff4eeea, 0xffebddd4, 0xff995522, 0xff8d440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d440d, + 0xff8d440d, 0xff8e450d, 0xff8f450d, 0xff90460d, 0xff91470e, 0xff904810, + 0xff97531f, 0xffac7349, 0xffc59f82, 0xffe0ccbc, 0xfff9f5f3, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffefe2d8, 0xffab5b23, 0xff9b4101, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff9e4302, 0xffd1a88a, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffeeded3, 0xffa95920, 0xff9b4101, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff994001, + 0xff994001, 0xff994001, 0xff994001, 0xff994001, 0xff9a4001, 0xffa65012, + 0xffddc0ab, 0xfffefefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfffdfcfb, 0xfff5ede6, 0xffd9b59c, 0xffba794c, + 0xffa65318, 0xffa44a0a, 0xffa04505, 0xff9b4101, 0xff9a4001, 0xff9a4001, + 0xff9a4001, 0xff9a4001, 0xff9a4001, 0xff9a4001, 0xff9a4001, 0xff9a4001, + 0xff9b4001, 0xff9b4101, 0xff9e4304, 0xffa34809, 0xffa64e12, 0xffad6531, + 0xffc79470, 0xffe7d1c1, 0xfff7f1ec, 0xfffefdfd, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefefe, 0xfff8f2ed, + 0xffeedfd4, 0xffdcbca5, 0xffc8946f, 0xffb67547, 0xffab612c, 0xffa4531a, + 0xffa44f14, 0xffa54f13, 0xffa54f13, 0xffa55014, 0xffa45015, 0xffa75921, + 0xffb57142, 0xffca9976, 0xffdfc3b0, 0xfff4e9e2, 0xfffbf8f5, 0xfffffefe, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffaf5f2, + 0xffc79673, 0xffac5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, + 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, + 0xffaa5f2a, 0xffac6028, 0xffbb7e52, 0xfffdfcfb, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefefd, 0xffe9d5c7, 0xffb97646, 0xffaa5e29, 0xffaa5f2a, + 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, + 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffac5f29, + 0xffbc7e52, 0xfff1e6de, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcf9f6, + 0xfff3e9e1, 0xffdbbaa2, 0xffc38c65, 0xffb06935, 0xffa35015, 0xffa54e10, + 0xffa44c0d, 0xffa44c0d, 0xffa54b0c, 0xffa54b0c, 0xffa44c0d, 0xffa54e0f, + 0xffa54f12, 0xffa6551c, 0xffb26c3b, 0xffc7926d, 0xffddbda6, 0xfff3e8e0, + 0xfffaf7f4, 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffefefe, 0xffca9975, 0xffae602a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, + 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, + 0xffaa5f2a, 0xffaa5f2a, 0xffac602a, 0xffc3885f, 0xfff5ede7, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcfaf8, 0xffd0a78a, 0xffac602b, + 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, + 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffaa5f2a, 0xffad622c, + 0xffdab79f, 0xfffefdfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xfff4ede8, 0xffa36737, 0xff90460e, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8d440d, 0xff90470f, 0xffa15d29, + 0xffcca98f, 0xfff5efeb, 0x00ffffff, 0xffd8c1ae, 0xff99511a, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff924a13, 0xff98511b, + 0xff99521c, 0xff99521c, 0xff99521c, 0xff99521c, 0xff99521c, 0xff99521c, + 0xff99521c, 0xff99531e, 0xff975320, 0xff9a5929, 0xffa3693c, 0xffaf7b54, + 0xffc19878, 0xffd6baa6, 0xffe8dacf, 0xfff3ece7, 0xfffbf9f7, 0xfffffffe, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffdfc0ab, + 0xffa24605, 0xff9e4201, 0xff9d4201, 0xff9d4201, 0xff9d4201, 0xff9d4201, + 0xff9d4201, 0xff9d4201, 0xff9d4201, 0xff9d4201, 0xff9d4201, 0xff9d4201, + 0xff9d4201, 0xff9d4201, 0xff9d4201, 0xff9e4201, 0xffa34c0e, 0xffe5cfbf, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffbf7f5, 0xffca9773, + 0xffa24605, 0xff9d4201, 0xff9d4201, 0xff9d4201, 0xff9d4201, 0xff9d4201, + 0xff9d4201, 0xff9d4201, 0xff9d4201, 0xff9d4201, 0xff9d4202, 0xff9d4202, + 0xff9d4202, 0xff9d4202, 0xff9d4202, 0xff9d4202, 0xff9d4202, 0xff9d4202, + 0xff9d4202, 0xff9f4402, 0xffb97544, 0xfff3e8e0, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffdfbfa, 0xfff0e2d8, 0xffd9b79f, 0xffc89876, 0xffb97c51, + 0xffb6703f, 0xffb36833, 0xffb0622a, 0xffaf5e25, 0xffae5d24, 0xffaf5e25, + 0xffb0622a, 0xffb36833, 0xffb66f3e, 0xffb8784b, 0xffc6936f, 0xffd5af95, + 0xffe8d4c5, 0xfff9f5f1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffaf6f3, 0xfff4eae3, 0xfff0e2d8, 0xffeddcd0, 0xffecdbce, 0xffeeded3, + 0xfff1e5dc, 0xfff7f0eb, 0xfffefefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffefefd, 0xfffaf7f4, 0xfff9f4f1, 0xfffaf5f2, 0xfffaf5f2, + 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, + 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfff9f4f1, 0xfffcf8f6, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffbf8f6, + 0xfff9f4f1, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, + 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, + 0xfffaf5f2, 0xfffaf5f2, 0xfff9f3ef, 0xfffdfaf9, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffcf9f8, + 0xfff0e3db, 0xffe8d3c5, 0xffe0c6b4, 0xffdec2ad, 0xffddc0ab, 0xffddc0ab, + 0xffdfc3b0, 0xffe4cebd, 0xffecdbd0, 0xfff4ebe4, 0xfffdfcfb, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffaf6f3, 0xfffaf5f1, 0xfffaf5f2, + 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, + 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffcf8f6, + 0xfffffefe, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffffefe, + 0xfffbf7f5, 0xfff9f5f1, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, + 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, 0xfffaf5f2, + 0xfffaf5f2, 0xfffaf5f2, 0xfffefcfb, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe2cfc1, + 0xffa86d3f, 0xff924b14, 0xff8e450e, 0xff8e450e, 0xff914912, 0xffa2612f, + 0xffb88864, 0xffe7d7cc, 0x00ffffff, 0x00ffffff, 0xfffefdfd, 0xffc5a185, + 0xff934a12, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8f470f, + 0xffb98d6c, 0xffe4d2c5, 0xffe4d4c7, 0xffe4d4c7, 0xffe4d4c7, 0xffe4d4c7, + 0xffe4d4c7, 0xffe4d4c7, 0xffe4d3c7, 0xffe9dbd1, 0xffefe5dd, 0xfff4ede8, + 0xfffcfaf8, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffe1c3ae, 0xffc5885c, 0xffc2865c, 0xffc2865c, 0xffc2865c, + 0xffc2865c, 0xffc2865c, 0xffc2865c, 0xffc2865c, 0xffc2865c, 0xffc2865c, + 0xffc2865c, 0xffc2865c, 0xffc2865c, 0xffc2865c, 0xffc2865c, 0xffc3865c, + 0xffcc9873, 0xfff5ece5, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffffffe, 0xffe9d7c9, 0xffca9168, 0xffc2865c, 0xffc2875c, 0xffc2875c, + 0xffc2875d, 0xffc2885e, 0xffc2885e, 0xffc38960, 0xffc48a60, 0xffc48a61, + 0xffc48b62, 0xffc48b63, 0xffc48b63, 0xffc58c64, 0xffc48c64, 0xffc48c64, + 0xffc58e66, 0xffc58e66, 0xffc68f67, 0xffc68f68, 0xffcb9772, 0xffeedfd4, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffdfcfb, 0xfff8f2ee, 0xfff2e7e0, 0xffeedfd4, 0xffead8cb, 0xffe8d5c7, + 0xffe8d4c6, 0xffe8d5c7, 0xffead8cb, 0xffedded4, 0xfff2e7df, 0xfff7f1ec, + 0xfffdfbf9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffdfcfb, 0xffecdfd5, 0xffd0b098, 0xffc1997b, 0xffc29b7c, + 0xffceaf97, 0xffe5d6c9, 0xfff8f3ef, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfff9f5f1, 0xffb58561, 0xff8e460e, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff964f19, 0xffd4b8a4, 0xfffffefe, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfbf9, 0xfffbf8f5, 0xfffbf7f5, + 0xfffbf7f5, 0xfffbf7f5, 0xfffbf7f5, 0xfffbf7f5, 0xfffbf7f5, 0xfffbf7f5, + 0xfffbf7f5, 0xfffbf7f5, 0xfffbf7f5, 0xfffbf7f5, 0xfffbf7f5, 0xfffbf7f5, + 0xfffbf7f5, 0xfffbf7f5, 0xfffcf9f7, 0xfffffefe, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefdfd, 0xfffcf9f6, 0xfffbf7f5, + 0xfffbf8f5, 0xfffbf8f5, 0xfffbf8f5, 0xfffbf8f5, 0xfffbf8f5, 0xfffbf8f5, + 0xfffbf8f6, 0xfffbf8f6, 0xfffbf8f6, 0xfffbf8f6, 0xfffbf8f6, 0xfffbf8f6, + 0xfffbf8f6, 0xfffbf8f6, 0xfffbf8f6, 0xfffbf8f6, 0xfffcf9f6, 0xfffcf9f7, + 0xfffcf8f6, 0xfffefdfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffdfdfc, + 0xfffcfaf9, 0xfffcfaf9, 0xfffefdfc, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffeee4dd, 0xffab7145, 0xff8d450d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xffa05d29, 0xffe1cec0, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffe5d4c8, 0xff9f5e2b, + 0xff8d440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xffa7693a, + 0xffeee2d9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefefe, + 0xffd7bfab, 0xff944d18, 0xff8d440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8d450d, 0xffab764e, 0xfff7f3f0, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xfffdfcfa, 0xffc49c7f, 0xff8f450e, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff91460d, 0xffbf9779, 0xfffffffe, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffbf9f7, 0xffb27f58, 0xff8f460d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff93480e, 0xffd1b59f, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff8f4f0, + 0xff9f6030, 0xff8e450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff914710, 0xffe5d5c9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0xffeadcd3, 0xff914a14, 0xff8d440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8d440d, 0xff94501c, 0xfff6f1ee, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xffd7beab, 0xff91470e, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff90450d, 0xffa4693c, 0xfffefefd, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfffefefe, 0xffc0987b, + 0xff91470e, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff90460d, + 0xffb98b67, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0xfffbf8f6, 0xffac7750, 0xff8f450d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, 0xff8c440d, + 0xff8c440d, 0xff8f460e, 0xffccaa90, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0xffefe5de, 0xffa56535, 0xff91460e, 0xff90460e, + 0xff90460e, 0xff90460e, 0xff90460e, 0xff90460e, 0xff90460e, 0xff90460e, + 0xff90460e, 0xff90460e, 0xff91460e, 0xff964e17, 0xffdcc5b4, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xfff9f6f3, 0xffeaddd2, + 0xffe7d8cd, 0xffe7d8cd, 0xffe7d8cd, 0xffe7d8cd, 0xffe7d8cd, 0xffe7d8cd, + 0xffe7d8cd, 0xffe7d8cd, 0xffe7d8cd, 0xffe7d8cd, 0xffe7d8cd, 0xffeadcd1, + 0xfffaf7f4, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/rockchip-logo-320-96.rgba b/project/app/uvc_app_tiny/uvc_app/uvc/rockchip-logo-320-96.rgba new file mode 100755 index 000000000..a67bda82b Binary files /dev/null and b/project/app/uvc_app_tiny/uvc_app/uvc/rockchip-logo-320-96.rgba differ diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uevent.c b/project/app/uvc_app_tiny/uvc_app/uvc/uevent.c new file mode 100644 index 000000000..461ebc76d --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uevent.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "uevent.h" +#include "uvc_control.h" +#include "uvc_log.h" + +extern int app_quit; + +static void handle_uvc_event(struct uevent *uevent) { + if (strcmp(uevent->subsystem, "android_usb")) + return; + + if (!strcmp(uevent->usb_state, "DISCONNECTED")) { + LOG_INFO("udc disconnected\n"); + app_quit = 1; + } else if (!strcmp(uevent->usb_state, "CONNECTED")) { + LOG_INFO("udc connected\n"); + } else if (!strcmp(uevent->usb_state, "CONFIGURED")) { + LOG_INFO("udc configured\n"); + } else { + LOG_INFO("unknow usb event\n"); + } +} + +static void parse_event(const char *msg, struct uevent *uevent) { + uevent->action = ""; + uevent->path = ""; + uevent->subsystem = ""; + uevent->usb_state = ""; + uevent->device_name = ""; + + while (*msg) { + if (!strncmp(msg, "ACTION=", 7)) { + msg += 7; + uevent->action = msg; + } else if (!strncmp(msg, "DEVPATH=", 8)) { + msg += 8; + uevent->path = msg; + } else if (!strncmp(msg, "SUBSYSTEM=", 10)) { + msg += 10; + uevent->subsystem = msg; + } else if (!strncmp(msg, "USB_STATE=", 10)) { + msg += 10; + uevent->usb_state = msg; + } else if (!strncmp(msg, "DEVNAME=", 8)) { + msg += 8; + uevent->device_name = msg; + } + /* advance to after the next \0 */ + while (*msg++) + ; + } + + LOG_DEBUG("event { '%s', '%s', '%s', '%s', '%s' }\n", uevent->action, + uevent->path, uevent->subsystem, uevent->usb_state, + uevent->device_name); + handle_uvc_event(uevent); +} + +static void *event_monitor_thread(void *arg) { + int sockfd; + int i, j, len; + char buf[1024 + 2]; + struct iovec iov; + struct msghdr msg; + struct sockaddr_nl sa; + struct uevent uevent; + uint32_t flags = *(uint32_t *)arg; + + prctl(PR_SET_NAME, "event_monitor", 0, 0, 0); + + memset(&sa, 0, sizeof(sa)); + sa.nl_family = AF_NETLINK; + sa.nl_groups = NETLINK_KOBJECT_UEVENT; + sa.nl_pid = 0; + memset(&msg, 0, sizeof(msg)); + iov.iov_base = (void *)buf; + iov.iov_len = sizeof(buf); + msg.msg_name = (void *)&sa; + msg.msg_namelen = sizeof(sa); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT); + if (sockfd == -1) { + LOG_ERROR("socket creating failed:%s\n", strerror(errno)); + goto err_event_monitor; + } + + if (bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { + LOG_ERROR("bind error:%s\n", strerror(errno)); + goto err_event_monitor; + } + + while (1) { + len = recvmsg(sockfd, &msg, 0); + if (len < 0) { + LOG_ERROR("receive error\n"); + } else if (len < 32 || len > sizeof(buf)) { + LOG_INFO("invalid message"); + } else { + buf[len] = '\0'; + buf[len + 1] = '\0'; + parse_event(buf, &uevent); + } + } + +err_event_monitor: + pthread_detach(pthread_self()); + pthread_exit(NULL); +} + +int uevent_monitor_run(uint32_t flags) { + pthread_t tid; + + return pthread_create(&tid, NULL, event_monitor_thread, &flags); +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uevent.h b/project/app/uvc_app_tiny/uvc_app/uvc/uevent.h new file mode 100644 index 000000000..4cb594138 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uevent.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __UEVENT_H__ +#define __UEVENT_H__ + +#include +#include +#include + +struct uevent { + const char *action; + const char *path; + const char *subsystem; + const char *usb_state; + const char *device_name; +}; + +int uevent_monitor_run(uint32_t flags); + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc-gadget.c b/project/app/uvc_app_tiny/uvc_app/uvc/uvc-gadget.c new file mode 100644 index 000000000..29e71c49d --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc-gadget.c @@ -0,0 +1,3942 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "camera_control.h" +#include "camera_pu_control.h" +#include "uvc-gadget.h" +#include "uvc_log.h" +#include "uvc_process_unit.h" +#include "uvc_video.h" +extern void camera_control_set_zoom(int val); + +/* Enable debug prints. */ +//#define ENABLE_BUFFER_DEBUG +#define ENABLE_USB_REQUEST_DEBUG + +#define CLEAR(x) memset(&(x), 0, sizeof(x)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +#define clamp(val, min, max) \ + ({ \ + typeof(val) __val = (val); \ + typeof(min) __min = (min); \ + typeof(max) __max = (max); \ + (void)(&__val == &__min); \ + (void)(&__val == &__max); \ + __val = __val < __min ? __min : __val; \ + __val > __max ? __max : __val; \ + }) + +#define pixfmtstr(x) \ + (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, ((x) >> 24) & 0xff + +static int silent = 1; +#define DBG(...) \ + do { \ + if (silent) \ + LOG_INFO(__VA_ARGS__); \ + } while (0) + +/* + * The UVC webcam gadget kernel driver (g_webcam.ko) supports changing + * the Brightness attribute of the Processing Unit (PU). by default. If + * the underlying video capture device supports changing the Brightness + * attribute of the image being acquired (like the Virtual Video, VIVI + * driver), then we should route this UVC request to the respective + * video capture device. + * + * Incase, there is no actual video capture device associated with the + * UVC gadget and we wish to use this application as the final + * destination of the UVC specific requests then we should return + * pre-cooked (static) responses to GET_CUR(BRIGHTNESS) and + * SET_CUR(BRIGHTNESS) commands to keep command verifier test tools like + * UVC class specific test suite of USBCV, happy. + * + * Note that the values taken below are in sync with the VIVI driver and + * must be changed for your specific video capture device. These values + * also work well in case there in no actual video capture device. + */ +#define PU_BRIGHTNESS_MIN_VAL 0 +#define PU_BRIGHTNESS_MAX_VAL 100 +#define PU_BRIGHTNESS_STEP_SIZE 1 +#define PU_BRIGHTNESS_DEFAULT_VAL 50 + +#define PU_CONTRAST_MIN_VAL 0 +#define PU_CONTRAST_MAX_VAL 100 +#define PU_CONTRAST_STEP_SIZE 1 +#define PU_CONTRAST_DEFAULT_VAL 50 + +#define PU_HUE_MIN_VAL 0 +#define PU_HUE_MAX_VAL 100 +#define PU_HUE_STEP_SIZE 1 +#define PU_HUE_DEFAULT_VAL 50 + +#define PU_SATURATION_MIN_VAL 0 +#define PU_SATURATION_MAX_VAL 100 +#define PU_SATURATION_STEP_SIZE 1 +#define PU_SATURATION_DEFAULT_VAL 50 + +#define PU_SHARPNESS_MIN_VAL 0 +#define PU_SHARPNESS_MAX_VAL 100 +#define PU_SHARPNESS_STEP_SIZE 1 +#define PU_SHARPNESS_DEFAULT_VAL 50 + +#define PU_GAMMA_MIN_VAL 1 +#define PU_GAMMA_MAX_VAL 500 +#define PU_GAMMA_STEP_SIZE 1 +#define PU_GAMMA_DEFAULT_VAL 100 // 1.0 + +#define PU_WHITE_BALANCE_TEMPERATURE_MIN_VAL 2800 +#define PU_WHITE_BALANCE_TEMPERATURE_MAX_VAL 6500 +#define PU_WHITE_BALANCE_TEMPERATURE_STEP_SIZE 37 +#define PU_WHITE_BALANCE_TEMPERATURE_DEFAULT_VAL 5000 + +#define PU_GAIN_MIN_VAL 0 +#define PU_GAIN_MAX_VAL 5 +#define PU_GAIN_STEP_SIZE 1 +#define PU_GAIN_DEFAULT_VAL 1 + +#define PU_HUE_AUTO_DEFAULT_VAL 0 + +// ZOOM +#define CT_ZOOM_ABSOLUTE_CONTROL_MIN_VAL 10 +#define CT_ZOOM_ABSOLUTE_CONTROL_MAX_VAL 50 +#define CT_ZOOM_ABSOLUTE_CONTROL_STEP_SIZE 1 +#define CT_ZOOM_ABSOLUTE_CONTROL_DEFAULT_VAL 10 + +// PANTILT +#define CT_PANTILT_ABSOLUTE_CONTROL_MIN_VAL -36000 +#define CT_PANTILT_ABSOLUTE_CONTROL_MAX_VAL 36000 +#define CT_PANTILT_ABSOLUTE_CONTROL_STEP_SIZE 3600 +#define CT_PANTILT_ABSOLUTE_CONTROL_DEFAULT_VAL 0 + +// ROLL +#define CT_ROLL_ABSOLUTE_CONTROL_MIN_VAL 0 +#define CT_ROLL_ABSOLUTE_CONTROL_MAX_VAL 3 +#define CT_ROLL_ABSOLUTE_CONTROL_STEP_SIZE 1 +#define CT_ROLL_ABSOLUTE_CONTROL_DEFAULT_VAL 0 + +// EXPOSURE_TIME_ABSOLUTE +#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL_MIN_VAL 5 +#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL_MAX_VAL 2500 +#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL_STEP_SIZE 1 // 100us +#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL_DEFAULT_VAL \ + 312 // 5 10 20 39 78 156 312 625 1250 2500 (-11 ~ -2) + +// IRIS_ABSOLUTE +#define CT_IRIS_ABSOLUTE_CONTROL_MIN_VAL 0 +#define CT_IRIS_ABSOLUTE_CONTROL_MAX_VAL 10 +#define CT_IRIS_ABSOLUTE_CONTROL_STEP_SIZE 1 +#define CT_IRIS_ABSOLUTE_CONTROL_DEFAULT_VAL 5 + +#define PU_DIGITAL_MULTIPLIER_CONTROL_MIN_VAL 10 +#define PU_DIGITAL_MULTIPLIER_CONTROL_MAX_VAL 50 +#define PU_DIGITAL_MULTIPLIER_CONTROL_STEP_SIZE 1 +#define PU_DIGITAL_MULTIPLIER_CONTROL_DEFAULT_VAL 10 + +#define XU_CAMERA_VERSION_DEFAULT "1100010233010110010" +#define XU_EPTZ_FLAG_DEFAULT_VAL 0 +#define XU_H265_DEFAULT_VAL 0 + +/* --------------------------------------------------------------------------- + * V4L2 and UVC device instances + */ + +/* Represents a V4L2 based video capture device */ +struct v4l2_device { + /* v4l2 device specific */ + int v4l2_fd; + int is_streaming; + char *v4l2_devname; + + /* v4l2 buffer specific */ + enum io_method io; + struct buffer *mem; + unsigned int nbufs; + + /* v4l2 buffer queue and dequeue counters */ + unsigned long long int qbuf_count; + unsigned long long int dqbuf_count; + + /* uvc device hook */ + struct uvc_device *udev; +}; + +void update_camera_ip(struct uvc_device *dev) { + char cmd[32] = {0}; + char ip[20] = {0}; + int num = + snprintf(ip, sizeof(ip), "%d.%d.%d.%d", dev->ex_ip_data[0], + dev->ex_ip_data[1], dev->ex_ip_data[2], dev->ex_ip_data[3]); + snprintf(cmd, 32, "ifconfig usb0 %d.%d.%d.%d", dev->ex_ip_data[0], + dev->ex_ip_data[1], dev->ex_ip_data[2], dev->ex_ip_data[3]); + // system("ifconfig usb0 down"); + LOG_DEBUG("update_camera_ip num:%d,cmd:%s\n", num, cmd); + system(cmd); + // system("ifconfig usb0 up"); + + char *next = "/data/uvc_xu_ip_save"; + FILE *fp_output = NULL; + strncpy(cmd, next, 32); + cmd[strlen(next)] = '\0'; + fp_output = fopen(cmd, "w+b"); + if (NULL == fp_output) { + LOG_ERROR("failed to open uvc xu ip file %s\n", cmd); + } else { + ip[num + 1] = "\0"; + fwrite(ip, num + 1, 1, fp_output); + fclose(fp_output); + } +} + +/* --------------------------------------------------------------------------- + * V4L2 streaming related + */ + +static int v4l2_uninit_device(struct v4l2_device *dev) { + unsigned int i; + int ret; + + switch (dev->io) { + case IO_METHOD_MMAP: + for (i = 0; i < dev->nbufs; ++i) { + ret = munmap(dev->mem[i].start, dev->mem[i].length); + if (ret < 0) { + LOG_ERROR("V4L2: munmap failed\n"); + return ret; + } + } + + free(dev->mem); + break; + + case IO_METHOD_USERPTR: + default: + break; + } + + return 0; +} + +static int v4l2_reqbufs_mmap(struct v4l2_device *dev, int nbufs) { + struct v4l2_requestbuffers req; + unsigned int i = 0; + int ret; + + CLEAR(req); + + req.count = nbufs; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(dev->v4l2_fd, VIDIOC_REQBUFS, &req); + if (ret < 0) { + if (ret == -EINVAL) + LOG_ERROR("V4L2: does not support memory mapping\n"); + else + LOG_ERROR("V4L2: VIDIOC_REQBUFS error %s (%d).\n", strerror(errno), + errno); + goto err; + } + + if (!req.count) + return 0; + + if (req.count < 2) { + LOG_ERROR("V4L2: Insufficient buffer memory.\n"); + ret = -EINVAL; + goto err; + } + + /* Map the buffers. */ + dev->mem = calloc(req.count, sizeof dev->mem[0]); + if (!dev->mem) { + LOG_ERROR("V4L2: Out of memory\n"); + ret = -ENOMEM; + goto err; + } + + for (i = 0; i < req.count; ++i) { + memset(&dev->mem[i].buf, 0, sizeof(dev->mem[i].buf)); + + dev->mem[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + dev->mem[i].buf.memory = V4L2_MEMORY_MMAP; + dev->mem[i].buf.index = i; + + ret = ioctl(dev->v4l2_fd, VIDIOC_QUERYBUF, &(dev->mem[i].buf)); + if (ret < 0) { + LOG_ERROR("V4L2: VIDIOC_QUERYBUF failed for buf %d: " + "%s (%d).\n", + i, strerror(errno), errno); + ret = -EINVAL; + goto err_free; + } + + dev->mem[i].start = mmap(NULL /* start anywhere */, dev->mem[i].buf.length, + PROT_READ | PROT_WRITE /* required */, + MAP_SHARED /* recommended */, dev->v4l2_fd, + dev->mem[i].buf.m.offset); + + if (MAP_FAILED == dev->mem[i].start) { + LOG_ERROR("V4L2: Unable to map buffer %u: %s (%d).\n", i, strerror(errno), + errno); + dev->mem[i].length = 0; + ret = -EINVAL; + goto err_free; + } + + dev->mem[i].length = dev->mem[i].buf.length; + LOG_DEBUG("V4L2: Buffer %u mapped at address %p.\n", i, dev->mem[i].start); + } + + dev->nbufs = req.count; + LOG_DEBUG("V4L2: %u buffers allocated.\n", req.count); + + return 0; + +err_free: + free(dev->mem); +err: + return ret; +} + +static int v4l2_reqbufs_userptr(struct v4l2_device *dev, int nbufs) { + struct v4l2_requestbuffers req; + int ret; + + CLEAR(req); + + req.count = nbufs; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_USERPTR; + + ret = ioctl(dev->v4l2_fd, VIDIOC_REQBUFS, &req); + if (ret < 0) { + if (ret == -EINVAL) + LOG_ERROR("V4L2: does not support user pointer i/o\n"); + else + LOG_ERROR("V4L2: VIDIOC_REQBUFS error %s (%d).\n", strerror(errno), + errno); + return ret; + } + + dev->nbufs = req.count; + LOG_DEBUG("V4L2: %u buffers allocated.\n", req.count); + + return 0; +} + +static int v4l2_reqbufs(struct v4l2_device *dev, int nbufs) { + int ret = 0; + + switch (dev->io) { + case IO_METHOD_MMAP: + ret = v4l2_reqbufs_mmap(dev, nbufs); + break; + + case IO_METHOD_USERPTR: + ret = v4l2_reqbufs_userptr(dev, nbufs); + break; + + default: + LOG_ERROR("no support such io:%d\n", dev->io); + ret = -EINVAL; + break; + } + + return ret; +} + +static int v4l2_qbuf_mmap(struct v4l2_device *dev) { + unsigned int i; + int ret; + + for (i = 0; i < dev->nbufs; ++i) { + memset(&dev->mem[i].buf, 0, sizeof(dev->mem[i].buf)); + + dev->mem[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + dev->mem[i].buf.memory = V4L2_MEMORY_MMAP; + dev->mem[i].buf.index = i; + + ret = ioctl(dev->v4l2_fd, VIDIOC_QBUF, &(dev->mem[i].buf)); + if (ret < 0) { + LOG_ERROR("V4L2: VIDIOC_QBUF failed : %s (%d).\n", strerror(errno), + errno); + return ret; + } + + dev->qbuf_count++; + } + + return 0; +} + +static int v4l2_qbuf(struct v4l2_device *dev) { + int ret = 0; + + switch (dev->io) { + case IO_METHOD_MMAP: + ret = v4l2_qbuf_mmap(dev); + break; + + case IO_METHOD_USERPTR: + /* Empty. */ + ret = 0; + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int v4l2_process_data(struct v4l2_device *dev) { + int ret; + struct v4l2_buffer vbuf; + struct v4l2_buffer ubuf; + + /* Return immediately if V4l2 streaming has not yet started. */ + if (!dev->is_streaming) + return 0; + + if (dev->udev->first_buffer_queued) + if (dev->dqbuf_count >= dev->qbuf_count) + return 0; + + /* Dequeue spent buffer rom V4L2 domain. */ + CLEAR(vbuf); + + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + switch (dev->io) { + case IO_METHOD_USERPTR: + vbuf.memory = V4L2_MEMORY_USERPTR; + break; + + case IO_METHOD_MMAP: + default: + vbuf.memory = V4L2_MEMORY_MMAP; + break; + } + + ret = ioctl(dev->v4l2_fd, VIDIOC_DQBUF, &vbuf); + if (ret < 0) + return ret; + + dev->dqbuf_count++; + +#ifdef ENABLE_BUFFER_DEBUG + LOG_INFO("Dequeueing buffer at V4L2 side = %d\n", vbuf.index); +#endif + + /* Queue video buffer to UVC domain. */ + CLEAR(ubuf); + + ubuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + switch (dev->udev->io) { + case IO_METHOD_MMAP: + ubuf.memory = V4L2_MEMORY_MMAP; + ubuf.length = vbuf.length; + ubuf.index = vbuf.index; + ubuf.bytesused = vbuf.bytesused; + break; + + case IO_METHOD_USERPTR: + default: + ubuf.memory = V4L2_MEMORY_USERPTR; + ubuf.m.userptr = (unsigned long)dev->mem[vbuf.index].start; + ubuf.length = dev->mem[vbuf.index].length; + ubuf.index = vbuf.index; + ubuf.bytesused = vbuf.bytesused; + break; + } + + ret = ioctl(dev->udev->uvc_fd, VIDIOC_QBUF, &ubuf); + if (ret < 0) { + LOG_ERROR("UVC: Unable to queue buffer %d: %s (%d).\n", ubuf.index, + strerror(errno), errno); + /* Check for a USB disconnect/shutdown event. */ + if (errno == ENODEV) { + dev->udev->uvc_shutdown_requested = 1; + LOG_INFO("UVC: Possible USB shutdown requested from " + "Host, seen during VIDIOC_QBUF\n"); + return 0; + } else { + return ret; + } + } + + dev->udev->qbuf_count++; + +#ifdef ENABLE_BUFFER_DEBUG + LOG_INFO("Queueing buffer at UVC side = %d\n", ubuf.index); +#endif + + if (!dev->udev->first_buffer_queued && !dev->udev->run_standalone) { + uvc_video_stream(dev->udev, 1); + dev->udev->first_buffer_queued = 1; + dev->udev->is_streaming = 1; + } + + return 0; +} + +/* --------------------------------------------------------------------------- + * V4L2 generic stuff + */ + +static int v4l2_get_format(struct v4l2_device *dev) { + struct v4l2_format fmt; + int ret; + + CLEAR(fmt); + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + ret = ioctl(dev->v4l2_fd, VIDIOC_G_FMT, &fmt); + if (ret < 0) { + LOG_ERROR("V4L2: Unable to get format: %s (%d).\n", strerror(errno), errno); + return ret; + } + + LOG_DEBUG("V4L2: Getting current format: %c%c%c%c %ux%u\n", + pixfmtstr(fmt.fmt.pix.pixelformat), fmt.fmt.pix.width, + fmt.fmt.pix.height); + + return 0; +} + +static int v4l2_set_format(struct v4l2_device *dev, struct v4l2_format *fmt) { + int ret; + + ret = ioctl(dev->v4l2_fd, VIDIOC_S_FMT, fmt); + if (ret < 0) { + LOG_ERROR("V4L2: Unable to set format %s (%d).\n", strerror(errno), errno); + return ret; + } + + LOG_DEBUG("V4L2: Setting format to: %c%c%c%c %ux%u\n", + pixfmtstr(fmt->fmt.pix.pixelformat), fmt->fmt.pix.width, + fmt->fmt.pix.height); + + return 0; +} + +static int v4l2_set_ctrl(struct v4l2_device *dev, int new_val, int ctrl) { + struct v4l2_queryctrl queryctrl; + struct v4l2_control control; + int ret; + + CLEAR(queryctrl); + + switch (ctrl) { + case V4L2_CID_BRIGHTNESS: + queryctrl.id = V4L2_CID_BRIGHTNESS; + ret = ioctl(dev->v4l2_fd, VIDIOC_QUERYCTRL, &queryctrl); + if (-1 == ret) { + if (errno != EINVAL) + LOG_ERROR("V4L2: VIDIOC_QUERYCTRL" + " failed: %s (%d).\n", + strerror(errno), errno); + else + LOG_ERROR("V4L2_CID_BRIGHTNESS is not" + " supported: %s (%d).\n", + strerror(errno), errno); + + return ret; + } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { + LOG_ERROR("V4L2_CID_BRIGHTNESS is not supported.\n"); + ret = -EINVAL; + return ret; + } else { + CLEAR(control); + control.id = V4L2_CID_BRIGHTNESS; + control.value = new_val; + + ret = ioctl(dev->v4l2_fd, VIDIOC_S_CTRL, &control); + if (-1 == ret) { + LOG_ERROR("V4L2: VIDIOC_S_CTRL failed: %s (%d).\n", strerror(errno), + errno); + return ret; + } + } + LOG_INFO("V4L2: Brightness control changed to value = 0x%x\n", new_val); + break; + + default: + /* TODO: We don't support any other controls. */ + return -EINVAL; + } + + return 0; +} + +static int v4l2_start_capturing(struct v4l2_device *dev) { + int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + int ret; + + ret = ioctl(dev->v4l2_fd, VIDIOC_STREAMON, &type); + if (ret < 0) { + LOG_ERROR("V4L2: Unable to start streaming: %s (%d).\n", strerror(errno), + errno); + return ret; + } + + LOG_DEBUG("V4L2: Starting video stream.\n"); + + return 0; +} + +static int v4l2_stop_capturing(struct v4l2_device *dev) { + enum v4l2_buf_type type; + int ret; + + switch (dev->io) { + case IO_METHOD_MMAP: + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + ret = ioctl(dev->v4l2_fd, VIDIOC_STREAMOFF, &type); + if (ret < 0) { + LOG_ERROR("V4L2: VIDIOC_STREAMOFF failed: %s (%d).\n", strerror(errno), + errno); + return ret; + } + + break; + default: + /* Nothing to do. */ + break; + } + + return 0; +} + +static int v4l2_open(struct v4l2_device **v4l2, char *devname, + struct v4l2_format *s_fmt) { + struct v4l2_device *dev; + struct v4l2_capability cap; + int fd; + int ret = -EINVAL; + + fd = open(devname, O_RDWR | O_NONBLOCK, 0); + if (fd == -1) { + LOG_ERROR("V4L2: device open failed: %s (%d).\n", strerror(errno), errno); + return ret; + } + + ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); + if (ret < 0) { + LOG_ERROR("V4L2: VIDIOC_QUERYCAP failed: %s (%d).\n", strerror(errno), + errno); + goto err; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + LOG_ERROR("V4L2: %s is no video capture device\n", devname); + goto err; + } + + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + LOG_ERROR("V4L2: %s does not support streaming i/o\n", devname); + goto err; + } + + dev = calloc(1, sizeof *dev); + if (dev == NULL) { + ret = -ENOMEM; + goto err; + } + + LOG_DEBUG("V4L2 device is %s on bus %s\n", cap.card, cap.bus_info); + + dev->v4l2_fd = fd; + + /* Get the default image format supported. */ + ret = v4l2_get_format(dev); + if (ret < 0) + goto err_free; + + /* + * Set the desired image format. + * Note: VIDIOC_S_FMT may change width and height. + */ + ret = v4l2_set_format(dev, s_fmt); + if (ret < 0) + goto err_free; + + /* Get the changed image format. */ + ret = v4l2_get_format(dev); + if (ret < 0) + goto err_free; + + LOG_DEBUG("v4l2 open succeeded, file descriptor = %d\n", fd); + + *v4l2 = dev; + + return 0; + +err_free: + free(dev); +err: + close(fd); + + return ret; +} + +static void v4l2_close(struct v4l2_device *dev) { + close(dev->v4l2_fd); + free(dev); +} + +/* --------------------------------------------------------------------------- + * UVC generic stuff + */ + +static int uvc_video_set_format(struct uvc_device *dev) { + struct v4l2_format fmt; + int ret; + + CLEAR(fmt); + + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + fmt.fmt.pix.width = dev->width; + fmt.fmt.pix.height = dev->height; + fmt.fmt.pix.pixelformat = dev->fcc; + fmt.fmt.pix.field = V4L2_FIELD_NONE; + if (dev->fcc == V4L2_PIX_FMT_MJPEG) + fmt.fmt.pix.sizeimage = dev->width * dev->height/*1.5*/; + if ((dev->fcc == V4L2_PIX_FMT_H264) || (dev->fcc == V4L2_PIX_FMT_H265)) +#ifdef RK_ENABLE_FASTBOOT + fmt.fmt.pix.sizeimage = dev->width * dev->height / 2; +#else + fmt.fmt.pix.sizeimage = dev->width * dev->height; +#endif + ret = ioctl(dev->uvc_fd, VIDIOC_S_FMT, &fmt); + if (ret < 0) { + LOG_ERROR("UVC: Unable to set format %s (%d).\n", strerror(errno), errno); + return ret; + } + + LOG_INFO("UVC: Setting format to: %c%c%c%c %ux%u\n", pixfmtstr(dev->fcc), + dev->width, dev->height); + + return 0; +} + +int uvc_video_stream(struct uvc_device *dev, int enable) { + int type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + int ret; + + if (!enable) { + ret = ioctl(dev->uvc_fd, VIDIOC_STREAMOFF, &type); + if (ret < 0) { + LOG_ERROR("UVC: VIDIOC_STREAMOFF failed: %s (%d).\n", strerror(errno), + errno); + return ret; + } + + LOG_DEBUG("UVC: Stopping video stream.\n"); + + return 0; + } + + ret = ioctl(dev->uvc_fd, VIDIOC_STREAMON, &type); + if (ret < 0) { + LOG_ERROR("UVC: Unable to start streaming %s (%d).\n", strerror(errno), + errno); + return ret; + } + + LOG_DEBUG("UVC: Starting video stream.\n"); + + dev->uvc_shutdown_requested = 0; + + return 0; +} + +static int uvc_uninit_device(struct uvc_device *dev) { + unsigned int i; + int ret; + + switch (dev->io) { + case IO_METHOD_MMAP: + for (i = 0; i < dev->nbufs; ++i) { + ret = munmap(dev->mem[i].start, dev->mem[i].length); + if (ret < 0) { + LOG_ERROR("UVC: munmap failed\n"); + return ret; + } + } + + free(dev->mem); + break; + + case IO_METHOD_USERPTR: + + if (dev->run_standalone) { + for (i = 0; i < dev->nbufs; ++i) + free(dev->dummy_buf[i].start); + + free(dev->dummy_buf); + } + break; + case IO_METHOD_DMA_BUFF: + + break; + default: + break; + } + + return 0; +} + +static int uvc_open(struct uvc_device **uvc, char *devname) { + struct uvc_device *dev; + struct v4l2_capability cap; + int fd; + int ret = -EINVAL; + + fd = open(devname, O_RDWR | O_NONBLOCK); + if (fd == -1) { + LOG_ERROR("UVC: device open failed: %s (%d).\n", strerror(errno), errno); + return ret; + } + + ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); + if (ret < 0) { + LOG_ERROR("UVC: unable to query uvc device: %s (%d)\n", strerror(errno), + errno); + goto err; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { + LOG_ERROR("UVC: %s is no video output device\n", devname); + goto err; + } + + dev = calloc(1, sizeof *dev); + if (dev == NULL) { + ret = -ENOMEM; + goto err; + } + + LOG_DEBUG("uvc device is %s on bus %s\n", cap.card, cap.bus_info); + LOG_DEBUG("uvc open succeeded, file descriptor = %d\n", fd); + + dev->uvc_fd = fd; + dev->eptz_flag = XU_EPTZ_FLAG_DEFAULT_VAL; + dev->xu_h265 = XU_H265_DEFAULT_VAL; + camera_pu_control_init(UVC_PU_BRIGHTNESS_CONTROL, PU_BRIGHTNESS_DEFAULT_VAL, + PU_BRIGHTNESS_MIN_VAL, PU_BRIGHTNESS_MAX_VAL); + dev->brightness_val = camera_pu_control_get(UVC_PU_BRIGHTNESS_CONTROL, + PU_BRIGHTNESS_DEFAULT_VAL); + + camera_pu_control_init(UVC_PU_CONTRAST_CONTROL, PU_CONTRAST_DEFAULT_VAL, + PU_CONTRAST_MIN_VAL, PU_CONTRAST_MAX_VAL); + dev->contrast_val = + camera_pu_control_get(UVC_PU_CONTRAST_CONTROL, PU_CONTRAST_DEFAULT_VAL); + + camera_pu_control_init(UVC_PU_HUE_CONTROL, PU_HUE_DEFAULT_VAL, PU_HUE_MIN_VAL, + PU_HUE_MAX_VAL); + dev->hue_val = camera_pu_control_get(UVC_PU_HUE_CONTROL, PU_HUE_DEFAULT_VAL); + + camera_pu_control_init(UVC_PU_SATURATION_CONTROL, PU_SATURATION_DEFAULT_VAL, + PU_SATURATION_MIN_VAL, PU_SATURATION_MAX_VAL); + dev->saturation_val = camera_pu_control_get(UVC_PU_SATURATION_CONTROL, + PU_SATURATION_DEFAULT_VAL); + + camera_pu_control_init(UVC_PU_SHARPNESS_CONTROL, PU_SHARPNESS_DEFAULT_VAL, + PU_SHARPNESS_MIN_VAL, PU_SHARPNESS_MAX_VAL); + dev->sharpness_val = + camera_pu_control_get(UVC_PU_SHARPNESS_CONTROL, PU_SHARPNESS_DEFAULT_VAL); + + camera_pu_control_init(UVC_PU_GAMMA_CONTROL, PU_GAMMA_DEFAULT_VAL, + PU_GAMMA_MIN_VAL, PU_GAMMA_MAX_VAL); + dev->gamma_val = + camera_pu_control_get(UVC_PU_GAMMA_CONTROL, PU_GAMMA_DEFAULT_VAL); + + camera_pu_control_init(UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL, + PU_WHITE_BALANCE_TEMPERATURE_DEFAULT_VAL, + PU_WHITE_BALANCE_TEMPERATURE_MIN_VAL, + PU_WHITE_BALANCE_TEMPERATURE_MAX_VAL); + dev->white_balance_temperature_val = + camera_pu_control_get(UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL, + PU_WHITE_BALANCE_TEMPERATURE_DEFAULT_VAL); + + camera_pu_control_init(UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, 1, 0, + 1); + dev->white_balance_temperature_auto_val = + camera_pu_control_get(UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, 1); + + camera_pu_control_init(UVC_PU_GAIN_CONTROL, PU_GAIN_DEFAULT_VAL, + PU_GAIN_MIN_VAL, PU_GAIN_MAX_VAL); + dev->gain_val = + camera_pu_control_get(UVC_PU_GAIN_CONTROL, PU_GAIN_DEFAULT_VAL); + + camera_pu_control_init(UVC_PU_HUE_AUTO_CONTROL, 1, 0, 1); + dev->hue_auto_val = camera_pu_control_get(UVC_PU_HUE_AUTO_CONTROL, 1); + camera_pu_control_set(UVC_PU_POWER_LINE_FREQUENCY_CONTROL, + 1); // set default AntiFlickerMode 1:50hz,2:60hz + dev->power_line_frequency_val = V4L2_CID_POWER_LINE_FREQUENCY_50HZ; + + // zoom + dev->zoom_val = CT_ZOOM_ABSOLUTE_CONTROL_DEFAULT_VAL; + // pan + dev->pan_val = CT_PANTILT_ABSOLUTE_CONTROL_DEFAULT_VAL; + // tilt + dev->tilt_val = CT_PANTILT_ABSOLUTE_CONTROL_DEFAULT_VAL; + // roll + dev->roll_val = CT_ROLL_ABSOLUTE_CONTROL_DEFAULT_VAL; + // exposure_time + dev->exposure_time_val = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL_DEFAULT_VAL; + // ae mode + dev->ae_mode_val = 0x02; // Auto Mode – auto Exposure Time, auto Iris + + char *ver = XU_CAMERA_VERSION_DEFAULT; + strncpy(dev->ex_sn_data, ver, MAX_UVC_REQUEST_DATA_LENGTH); + memset(dev->ex_tool_ctrl1, 0, sizeof(dev->ex_tool_ctrl1)); + + *uvc = dev; + return 0; + +err: + close(fd); + return ret; +} + +static void uvc_close(struct uvc_device *dev) { + if (dev) { + if (dev->uvc_fd) + close(dev->uvc_fd); + if (dev->vbuf_info) + free(dev->vbuf_info); + if (dev->imgdata) + free(dev->imgdata); + free(dev); + } +} + +/* --------------------------------------------------------------------------- + * UVC streaming related + */ +static void uvc_video_release_cache_buffer(struct uvc_device *dev, + struct v4l2_buffer *buf) { + uvc_user_release_cache_buffer(dev, buf, dev->video_id); +} + +static struct uvc_buffer *uvc_video_fill_buffer(struct uvc_device *dev, + struct v4l2_buffer *buf) { + return uvc_user_fill_buffer(dev, buf, dev->video_id); +} + +static int uvc_video_process(struct uvc_device *dev) { + struct v4l2_buffer vbuf; + unsigned int i; + int ret; + int retry_cnt = 0; + bool get_ok = false; + struct uvc_buffer *uvc_buf = NULL; + + /* + * Return immediately if UVC video output device has not started + * streaming yet. + */ + if (!dev->is_streaming) { + usleep(10000); + return 0; + } +#ifdef ENABLE_BUFFER_TIME_DEBUG + struct timeval process_time; + gettimeofday(&process_time, NULL); + LOG_ERROR("UVC V4L2 READY TO WRITE BUFFER:%d.%d (s)", process_time.tv_sec, + process_time.tv_usec); +#endif + /* Prepare a v4l2 buffer to be dequeued from UVC domain. */ + CLEAR(dev->ubuf); + + dev->ubuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + switch (dev->io) { + case IO_METHOD_MMAP: + dev->ubuf.memory = V4L2_MEMORY_MMAP; + break; + + case IO_METHOD_USERPTR: + dev->ubuf.memory = V4L2_MEMORY_USERPTR; + break; + case IO_METHOD_DMA_BUFF: + default: + dev->ubuf.memory = V4L2_MEMORY_DMABUF; + break; + } + + if (dev->run_standalone) { + REDQBUF: + do { + ret = ioctl(dev->uvc_fd, VIDIOC_DQBUF, &dev->ubuf); + if (ret == 0) { + dev->dqbuf_count++; + uvc_video_release_cache_buffer(dev, &dev->ubuf); + LOG_DEBUG( + "dev->dqbuf_count:%lld, %d: DeQueued buffer at UVC side = %d\n", + dev->dqbuf_count, dev->video_id, dev->ubuf.index); + } else if (ret < 0) { + break; + // when stream on(not qbuf ever) dqbuf will go here. + } else { + LOG_ERROR("%d: UVC: Unable to DeQueued buffer: %s (%d) ret(%d).\n", + dev->video_id, strerror(errno), errno, ret); + } + } while (ret == 0); + + do { + if (!uvc_buf) + uvc_buf = uvc_video_fill_buffer(dev, &dev->ubuf); + if (!uvc_buf) { // !dev->ubuf.bytesused && !dev->ubuf.m.fd + dev->drop_count++; + LOG_INFO("%d: UVC: Unable to queue buffer length is 0, dqbuf:%lld " + "qbuf:%lld drop count:%d\n", + dev->video_id, dev->dqbuf_count, dev->qbuf_count, + dev->drop_count); + if (dev->qbuf_count && retry_cnt < 50) { + retry_cnt++; + goto REDQBUF; // ret null packet will cause uvc err between send + // data(need alloc a null buf fix this case?) + } else { + // todo: how to aviod this case? + return 0; + } + } + ret = ioctl(dev->uvc_fd, VIDIOC_QBUF, &dev->ubuf); + if (ret < 0 && errno != 19) { // 19:No such device,disconnect + dev->try_count++; + LOG_ERROR("%d: UVC: Unable to queue buffer:fd:%d frame:%p %s " + "(%d).retry qbuf:%d\n", + dev->video_id, uvc_buf->fd, uvc_buf->frame, strerror(errno), + errno, dev->try_count); + // uvc_buffer_read_set(dev->video_id, uvc_buf); + // wait for moment + usleep(1000); + // reqbuf this uvc_buf + goto REDQBUF; + // return ret; // will err if just return. + } else { + dev->qbuf_count++; + uvc_buffer_write_set(dev->video_id, uvc_buf); + // for save mb buf(when destory uvc need clear cache mb buf) + uvc_buffer_cache_set(dev->video_id, uvc_buf); + } + LOG_DEBUG("dev->qbuf_count:%lld,%d: ReQueueing buffer at UVC side = %d " + "size = %d\n", + dev->qbuf_count, dev->video_id, dev->ubuf.index, + dev->ubuf.bytesused); +#ifdef ENABLE_BUFFER_TIME_DEBUG + struct timeval buffer_time; + gettimeofday(&buffer_time, NULL); + LOG_ERROR("UVC V4L2 BUFFER TIME END:%d.%d (s)", buffer_time.tv_sec, + buffer_time.tv_usec); +#endif + uvc_buf = NULL; + } while (uvc_buffer_read_enable(dev->video_id)); + } + + return 0; +} + +static int uvc_video_qbuf_mmap(struct uvc_device *dev) { + unsigned int i; + int ret; + + for (i = 0; i < dev->nbufs; ++i) { + memset(&dev->mem[i].buf, 0, sizeof(dev->mem[i].buf)); + + dev->mem[i].buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + dev->mem[i].buf.memory = V4L2_MEMORY_MMAP; + dev->mem[i].buf.index = i; + + ret = ioctl(dev->uvc_fd, VIDIOC_QBUF, &(dev->mem[i].buf)); + if (ret < 0) { + LOG_ERROR("UVC: VIDIOC_QBUF failed : %s (%d).\n", strerror(errno), errno); + return ret; + } + + dev->qbuf_count++; + } + + return 0; +} + +static int uvc_video_qbuf_userptr(struct uvc_device *dev) { + unsigned int i; + int ret; + + /* UVC standalone setup. */ + if (dev->run_standalone) { + for (i = 0; i < dev->nbufs; ++i) { + struct v4l2_buffer buf; + + CLEAR(buf); + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + buf.memory = V4L2_MEMORY_USERPTR; + buf.m.userptr = (unsigned long)dev->dummy_buf[i].start; + buf.length = dev->dummy_buf[i].length; + buf.index = i; + + ret = ioctl(dev->uvc_fd, VIDIOC_QBUF, &buf); + if (ret < 0) { + LOG_ERROR("UVC: VIDIOC_QBUF failed : %s (%d).\n", strerror(errno), + errno); + return ret; + } + + dev->qbuf_count++; + } + } + + return 0; +} + +int uvc_video_qbuf(struct uvc_device *dev) { + int ret = 0; + + switch (dev->io) { + case IO_METHOD_MMAP: + ret = uvc_video_qbuf_mmap(dev); + break; + + case IO_METHOD_USERPTR: + ret = uvc_video_qbuf_userptr(dev); + break; + case IO_METHOD_DMA_BUFF: + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int uvc_video_reqbufs_mmap(struct uvc_device *dev, int nbufs) { + struct v4l2_requestbuffers rb; + unsigned int i; + int ret; + + CLEAR(rb); + + rb.count = nbufs; + rb.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + rb.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(dev->uvc_fd, VIDIOC_REQBUFS, &rb); + if (ret < 0) { + if (ret == -EINVAL) + LOG_ERROR("UVC: does not support memory mapping\n"); + else + LOG_ERROR("UVC: Unable to allocate buffers: %s (%d).\n", strerror(errno), + errno); + goto err; + } + + if (!rb.count) + return 0; + + if (rb.count < 2) { + LOG_ERROR("UVC: Insufficient buffer memory.\n"); + ret = -EINVAL; + goto err; + } + + /* Map the buffers. */ + dev->mem = calloc(rb.count, sizeof dev->mem[0]); + if (!dev->mem) { + LOG_ERROR("UVC: Out of memory\n"); + ret = -ENOMEM; + goto err; + } + + for (i = 0; i < rb.count; ++i) { + memset(&dev->mem[i].buf, 0, sizeof(dev->mem[i].buf)); + + dev->mem[i].buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + dev->mem[i].buf.memory = V4L2_MEMORY_MMAP; + dev->mem[i].buf.index = i; + + ret = ioctl(dev->uvc_fd, VIDIOC_QUERYBUF, &(dev->mem[i].buf)); + if (ret < 0) { + LOG_ERROR("UVC: VIDIOC_QUERYBUF failed for buf %d: " + "%s (%d).\n", + i, strerror(errno), errno); + ret = -EINVAL; + goto err_free; + } + + dev->mem[i].start = mmap(NULL /* start anywhere */, dev->mem[i].buf.length, + PROT_READ | PROT_WRITE /* required */, + MAP_SHARED /* recommended */, dev->uvc_fd, + dev->mem[i].buf.m.offset); + + if (MAP_FAILED == dev->mem[i].start) { + LOG_ERROR("UVC: Unable to map buffer %u: %s (%d).\n", i, strerror(errno), + errno); + dev->mem[i].length = 0; + ret = -EINVAL; + goto err_free; + } + + dev->mem[i].length = dev->mem[i].buf.length; + LOG_DEBUG("UVC: Buffer %u mapped at address %p.\n", i, dev->mem[i].start); + } + + dev->nbufs = rb.count; + LOG_DEBUG("UVC: %u buffers allocated.\n", rb.count); + + return 0; + +err_free: + free(dev->mem); +err: + return ret; +} + +static int uvc_video_reqbufs_dmabuff(struct uvc_device *dev, int nbufs) { + struct v4l2_requestbuffers rb; + unsigned int i, j, bpl = 0, payload_size; + int ret; + + CLEAR(rb); + + rb.count = nbufs; + rb.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + rb.memory = V4L2_MEMORY_DMABUF; + + ret = ioctl(dev->uvc_fd, VIDIOC_REQBUFS, &rb); + if (ret < 0) { + if (ret == -EINVAL) + LOG_ERROR("UVC: does not support dma buff i/o\n"); + else + LOG_ERROR("UVC: VIDIOC_REQBUFS error %s (%d).\n", strerror(errno), errno); + goto err; + } + + if (!rb.count) + return 0; +err: + return ret; +} + +static int uvc_video_reqbufs_userptr(struct uvc_device *dev, int nbufs) { + struct v4l2_requestbuffers rb; + unsigned int i, j, bpl = 0, payload_size; + int ret; + + CLEAR(rb); + + rb.count = nbufs; + rb.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + rb.memory = V4L2_MEMORY_USERPTR; + + ret = ioctl(dev->uvc_fd, VIDIOC_REQBUFS, &rb); + if (ret < 0) { + if (ret == -EINVAL) + LOG_ERROR("UVC: does not support user pointer i/o\n"); + else + LOG_ERROR("UVC: VIDIOC_REQBUFS error %s (%d).\n", strerror(errno), errno); + goto err; + } + + if (!rb.count) + return 0; + + dev->nbufs = rb.count; + LOG_DEBUG("UVC: %u buffers allocated.\n", rb.count); + + if (dev->run_standalone) { + /* Allocate buffers to hold dummy data pattern. */ + dev->dummy_buf = calloc(rb.count, sizeof dev->dummy_buf[0]); + if (!dev->dummy_buf) { + LOG_ERROR("UVC: Out of memory\n"); + ret = -ENOMEM; + goto err; + } + + switch (dev->fcc) { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_NV12: + bpl = dev->width * 2; + payload_size = dev->width * dev->height * 2; + break; + case V4L2_PIX_FMT_MJPEG: + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_H265: + payload_size = dev->imgsize; + break; + default: + return -1; + } + + for (i = 0; i < rb.count; ++i) { + dev->dummy_buf[i].length = payload_size; + dev->dummy_buf[i].start = malloc(payload_size); + if (!dev->dummy_buf[i].start) { + LOG_ERROR("UVC: Out of memory\n"); + ret = -ENOMEM; + goto err; + } + + if (V4L2_PIX_FMT_YUYV == dev->fcc) + for (j = 0; j < dev->height; ++j) + memset(dev->dummy_buf[i].start + j * bpl, dev->color++, bpl); + + if (V4L2_PIX_FMT_MJPEG == dev->fcc && dev->imgdata) + memcpy(dev->dummy_buf[i].start, dev->imgdata, dev->imgsize); + } + } + + return 0; + +err: + return ret; +} + +int uvc_video_reqbufs(struct uvc_device *dev, int nbufs) { + int ret = 0; + + switch (dev->io) { + case IO_METHOD_MMAP: + ret = uvc_video_reqbufs_mmap(dev, nbufs); + break; + + case IO_METHOD_USERPTR: + ret = uvc_video_reqbufs_userptr(dev, nbufs); + break; + case IO_METHOD_DMA_BUFF: + ret = uvc_video_reqbufs_dmabuff(dev, nbufs); + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/* + * This function is called in response to either: + * - A SET_ALT(interface 1, alt setting 1) command from USB host, + * if the UVC gadget supports an ISOCHRONOUS video streaming endpoint + * or, + * + * - A UVC_VS_COMMIT_CONTROL command from USB host, if the UVC gadget + * supports a BULK type video streaming endpoint. + */ +static int uvc_handle_streamon_event(struct uvc_device *dev) { + int ret; + if (!dev->run_standalone) { + /* UVC - V4L2 integrated path. */ + if (IO_METHOD_USERPTR == dev->vdev->io) { + /* + * Ensure that the V4L2 video capture device has already + * some buffers queued. + */ + ret = v4l2_reqbufs(dev->vdev, dev->vdev->nbufs); + if (ret < 0) + goto err; + } + ret = v4l2_qbuf(dev->vdev); + if (ret < 0) + goto err; + + /* Start V4L2 capturing now. */ + ret = v4l2_start_capturing(dev->vdev); + if (ret < 0) + goto err; + + dev->vdev->is_streaming = 1; + } + + /* Common setup. */ + if (dev->run_standalone) { + dev->first_buffer_queued = 1; + dev->is_streaming = 1; + } + + uvc_control_streamon(dev); + + set_uvc_control_start(dev->video_id, dev->width, dev->height, dev->fps, + dev->fcc, dev->eptz_flag); + return 0; + +err: + return ret; +} + +/* --------------------------------------------------------------------------- + * UVC Request processing + */ + +static void uvc_fill_streaming_control(struct uvc_device *dev, + struct uvc_streaming_control *ctrl, + int iformat, int iframe, + unsigned int ival) { + const struct uvc_function_config_format *format; + const struct uvc_function_config_frame *frame; + unsigned int i; + + /* + * Restrict the iformat, iframe and ival to valid values. Negative + * values for iformat or iframe will result in the maximum valid value + * being selected. + */ + iformat = clamp((unsigned int)iformat, 1U, dev->fc->streaming.num_formats); + format = &dev->fc->streaming.formats[iformat - 1]; + + iframe = clamp((unsigned int)iframe, 1U, format->num_frames); + frame = &format->frames[iframe - 1]; + + for (i = 0; i < frame->num_intervals; ++i) { + if (ival <= frame->intervals[i]) { + ival = frame->intervals[i]; + break; + } + } + if (i == frame->num_intervals) + ival = frame->intervals[frame->num_intervals - 1]; + + memset(ctrl, 0, sizeof *ctrl); + + ctrl->bmHint = 1; + ctrl->bFormatIndex = iformat; + ctrl->bFrameIndex = iframe; + ctrl->dwFrameInterval = ival; + + dev->width = frame->width; + dev->height = frame->height; + dev->fcc = format->fcc; + switch (format->fcc) { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_NV12: + ctrl->dwMaxVideoFrameSize = frame->width * frame->height * 2; + break; + case V4L2_PIX_FMT_MJPEG: + dev->imgsize = frame->width * frame->height; + ctrl->dwMaxVideoFrameSize = dev->imgsize; + break; + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_H265: +#ifdef RK_ENABLE_FASTBOOT + dev->imgsize = frame->width * frame->height / 2; +#else + dev->imgsize = frame->width * frame->height; +#endif + ctrl->dwMaxVideoFrameSize = dev->imgsize; + break; + } + LOG_INFO("dev->fcc:%d,dev->width:%d,dev->height:%d,dev->imgsize:%d,ctrl->" + "dwFrameInterval:%d\n", + dev->fcc, dev->width, dev->height, dev->imgsize, + ctrl->dwFrameInterval); + + /* TODO: the UVC maxpayload transfer size should be filled + * by the driver. + */ + if (!dev->bulk) { + ctrl->dwMaxPayloadTransferSize = + dev->fc->streaming.ep + .wMaxPacketSize; /*get_uvc_streaming_maxpacket();/*(dev->maxpkt) * +(dev->mult + 1) * (dev->burst + 1);*/ + LOG_INFO("+++++++++dwMaxPayloadTransferSize:%d\n", + ctrl->dwMaxPayloadTransferSize); + } else { + ctrl->dwMaxPayloadTransferSize = ctrl->dwMaxVideoFrameSize; + } + + ctrl->bmFramingInfo = 3; + ctrl->bPreferedVersion = 1; + ctrl->bMaxVersion = 1; +} + +static void uvc_events_process_standard(struct uvc_device *dev, + struct usb_ctrlrequest *ctrl, + struct uvc_request_data *resp) { + LOG_DEBUG("standard request\n"); + (void)dev; + (void)ctrl; + (void)resp; +} + +static void uvc_events_process_control(struct uvc_device *dev, uint8_t req, + uint8_t cs, uint8_t entity_id, + uint8_t len, + struct uvc_request_data *resp) { + LOG_DEBUG("req = %d cs = %d entity_id =%d len = %d \n", req, cs, entity_id, + len); + dev->cs = cs; + dev->entity_id = entity_id; + + switch (entity_id) { + case UVC_CTRL_INTERFACE_ID: + switch (cs) { + case UVC_VC_REQUEST_ERROR_CODE_CONTROL: + /* Send the request error code last prepared. */ + resp->data[0] = dev->request_error_code.data[0]; + resp->length = dev->request_error_code.length; + break; + + default: + /* + * If we were not supposed to handle this + * 'cs', prepare an error code response. + */ + dev->request_error_code.data[0] = 0x06; + dev->request_error_code.length = 1; + break; + } + break; + + /* Camera terminal unit 'UVC_VC_INPUT_TERMINAL'. */ + case UVC_CTRL_CAMERA_TERMINAL_ID: + switch (cs) { + case UVC_CT_ZOOM_ABSOLUTE_CONTROL: + switch (req) { + LOG_INFO("UVC_CT_ZOOM_ABSOLUTE_CONTROL:req=%d \n", req); + case UVC_SET_CUR: + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + resp->data[0] = CT_ZOOM_ABSOLUTE_CONTROL_MIN_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + resp->data[0] = CT_ZOOM_ABSOLUTE_CONTROL_MAX_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 2; + memcpy(&resp->data[0], &dev->zoom_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = CT_ZOOM_ABSOLUTE_CONTROL_DEFAULT_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + resp->data[0] = CT_ZOOM_ABSOLUTE_CONTROL_STEP_SIZE; // must be 1 + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_CT_PANTILT_ABSOLUTE_CONTROL: + switch (req) { + LOG_INFO("UVC_CT_PANTILT_ABSOLUTE_CONTROL:req=%d len:%d\n", req, len); + case UVC_SET_CUR: + // resp->data[0] = 0x0; + // resp->data[4] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: { + int a = CT_PANTILT_ABSOLUTE_CONTROL_MIN_VAL; + int b = CT_PANTILT_ABSOLUTE_CONTROL_MIN_VAL; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &a, 4); + memcpy(&resp->data[4], &b, 4); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_MAX: { + int c = CT_PANTILT_ABSOLUTE_CONTROL_MAX_VAL; + int d = CT_PANTILT_ABSOLUTE_CONTROL_MAX_VAL; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &c, 4); + memcpy(&resp->data[4], &d, 4); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_CUR: { + resp->length = len; + memset(resp->data, 0, sizeof(resp->data)); + memcpy(&resp->data[0], &dev->pan_val, 4); + memcpy(&resp->data[4], &dev->tilt_val, 4); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_INFO: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x03; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: { + int e = CT_PANTILT_ABSOLUTE_CONTROL_STEP_SIZE; + int f = CT_PANTILT_ABSOLUTE_CONTROL_STEP_SIZE; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &e, 4); + memcpy(&resp->data[4], &f, 4); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_DEF: + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_CT_ROLL_ABSOLUTE_CONTROL: + switch (req) { + LOG_DEBUG("UVC_CT_ROLL_ABSOLUTE_CONTROL:req=%d len:%d\n", req, len); + case UVC_SET_CUR: + // resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: { + short min = CT_ROLL_ABSOLUTE_CONTROL_MIN_VAL; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &min, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_MAX: { + short max = CT_ROLL_ABSOLUTE_CONTROL_MAX_VAL; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &max, resp->length); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_CUR: + resp->length = len; + memcpy(&resp->data[0], &dev->roll_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = CT_ROLL_ABSOLUTE_CONTROL_STEP_SIZE; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_CT_AE_MODE_CONTROL: + switch (req) { + case UVC_SET_CUR: + /* Incase of auto exposure, attempts to + * programmatically set the auto-adjusted + * controls are ignored. + */ + resp->data[0] = 0x01; + resp->length = 1; + /* + * For every successfully handled control + * request set the request error code to no + * error. + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + + case UVC_GET_INFO: + /* + * TODO: We support Set and Get requests, but + * don't support async updates on an video + * status (interrupt) endpoint as of + * now. + */ + resp->data[0] = 0x03; + resp->length = 1; + /* + * For every successfully handled control + * request set the request error code to no + * error. + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + + case UVC_GET_CUR: + resp->length = 1; + /* Auto Mode - auto Exposure Time, auto Iris. */ + memcpy(&resp->data[0], &dev->ae_mode_val, resp->length); + /* + * For every successfully handled control + * request set the request error code to no + * error. + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + case UVC_GET_RES: + /* Auto Mode - auto Exposure Time, auto Iris. */ + resp->data[0] = 0x02; + resp->length = 1; + /* + * For every successfully handled control + * request set the request error code to no + * error. + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + /* + * We don't support this control, so STALL the + * control ep. + */ + resp->length = -EL2HLT; + /* + * For every unsupported control request + * set the request error code to appropriate + * value. + */ + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_CT_FOCUS_AUTO_CONTROL: + switch (req) { + case UVC_SET_CUR: + /* Incase of auto exposure, attempts to + * programmatically set the auto-adjusted + * controls are ignored. + */ + resp->data[0] = 0x01; + resp->length = 1; + /* + * For every successfully handled control + * request set the request error code to no + * error. + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + + case UVC_GET_INFO: + /* + * TODO: We support Set and Get requests, but + * don't support async updates on an video + * status (interrupt) endpoint as of + * now. + */ + resp->data[0] = 0x03; + resp->length = 1; + /* + * For every successfully handled control + * request set the request error code to no + * error. + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + + case UVC_GET_CUR: + case UVC_GET_DEF: + case UVC_GET_RES: + resp->data[0] = 1; + resp->length = 1; + /* + * For every successfully handled control + * request set the request error code to no + * error. + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + /* + * We don't support this control, so STALL the + * control ep. + */ + resp->length = -EL2HLT; + /* + * For every unsupported control request + * set the request error code to appropriate + * value. + */ + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_CT_FOCUS_ABSOLUTE_CONTROL: { + /* + * We don't support this control, so STALL the + * control ep. + */ + resp->length = -EL2HLT; + /* + * For every unsupported control request + * set the request error code to appropriate + * value. + */ + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + } break; + case UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL: + LOG_DEBUG("++++++++UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL req:%d", req); + switch (req) { + case UVC_SET_CUR: + // resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: { + int min_time = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL_MIN_VAL; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &min_time, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_MAX: { + int max_time = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL_MAX_VAL; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &max_time, resp->length); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_CUR: + resp->length = len; + memcpy(&resp->data[0], &dev->exposure_time_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL_STEP_SIZE; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: { + int def_time = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL_DEFAULT_VAL; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &def_time, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + default: + /* + * We don't support this control, so STALL the + * control ep. + */ + resp->length = -EL2HLT; + /* + * For every unsupported control request + * set the request error code to appropriate + * value. + */ + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + } + break; + case UVC_CT_IRIS_ABSOLUTE_CONTROL: + LOG_DEBUG("++++++++UVC_CT_IRIS_ABSOLUTE_CONTROL req:%d", req); + switch (req) { + case UVC_SET_CUR: + // resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: { + int min_time = CT_IRIS_ABSOLUTE_CONTROL_MIN_VAL; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &min_time, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_MAX: { + int max_time = CT_IRIS_ABSOLUTE_CONTROL_MAX_VAL; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &max_time, resp->length); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_CUR: + resp->length = len; + memcpy(&resp->data[0], &dev->iris_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = CT_IRIS_ABSOLUTE_CONTROL_STEP_SIZE; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: { + int def_time = CT_IRIS_ABSOLUTE_CONTROL_DEFAULT_VAL; + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + memcpy(&resp->data, &def_time, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + default: + /* + * We don't support this control, so STALL the + * control ep. + */ + resp->length = -EL2HLT; + /* + * For every unsupported control request + * set the request error code to appropriate + * value. + */ + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + } + break; + + default: + LOG_DEBUG("++++++++Input Terminal usb default req ,cs:%d", cs); + switch (req) { + case UVC_GET_LEN: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = sizeof(resp->data); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_SET_CUR: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + memset(resp->data, 0xFF, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 1; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + } + break; + + /* processing unit 'UVC_VC_PROCESSING_UNIT' */ + case UVC_CTRL_PROCESSING_UNIT_ID: + switch (cs) { + case UVC_PU_BRIGHTNESS_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->data[0] = 0x0; + resp->length = len; + /* + * For every successfully handled control + * request set the request error code to no + * error + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + LOG_INFO("set brightness\n"); + break; + case UVC_GET_MIN: + resp->data[0] = PU_BRIGHTNESS_MIN_VAL; + resp->length = 2; + /* + * For every successfully handled control + * request set the request error code to no + * error + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + resp->data[0] = PU_BRIGHTNESS_MAX_VAL; + resp->length = 2; + /* + * For every successfully handled control + * request set the request error code to no + * error + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 2; + memcpy(&resp->data[0], &dev->brightness_val, resp->length); + /* + * For every successfully handled control + * request set the request error code to no + * error + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + /* + * We support Set and Get requests and don't + * support async updates on an interrupt endpt + */ + resp->data[0] = 0x03; + resp->length = 1; + /* + * For every successfully handled control + * request, set the request error code to no + * error. + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = PU_BRIGHTNESS_DEFAULT_VAL; + resp->length = 2; + /* + * For every successfully handled control + * request, set the request error code to no + * error. + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + resp->data[0] = PU_BRIGHTNESS_STEP_SIZE; + resp->length = 2; + /* + * For every successfully handled control + * request, set the request error code to no + * error. + */ + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + /* + * We don't support this control, so STALL the + * default control ep. + */ + resp->length = -EL2HLT; + /* + * For every unsupported control request + * set the request error code to appropriate + * code. + */ + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_CONTRAST_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + resp->data[0] = PU_CONTRAST_MIN_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + resp->data[0] = PU_CONTRAST_MAX_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 2; + memcpy(&resp->data[0], &dev->contrast_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = PU_CONTRAST_DEFAULT_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + resp->data[0] = PU_CONTRAST_STEP_SIZE; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_HUE_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + resp->data[0] = PU_HUE_MIN_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + resp->data[0] = PU_HUE_MAX_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 2; + memcpy(&resp->data[0], &dev->hue_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = PU_HUE_DEFAULT_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + resp->data[0] = PU_HUE_STEP_SIZE; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_SATURATION_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + resp->data[0] = PU_SATURATION_MIN_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + resp->data[0] = PU_SATURATION_MAX_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 2; + memcpy(&resp->data[0], &dev->saturation_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = PU_SATURATION_DEFAULT_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + resp->data[0] = PU_SATURATION_STEP_SIZE; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_SHARPNESS_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + resp->data[0] = PU_SHARPNESS_MIN_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + resp->data[0] = PU_SHARPNESS_MAX_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 2; + memcpy(&resp->data[0], &dev->sharpness_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = PU_SHARPNESS_DEFAULT_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + resp->data[0] = PU_SHARPNESS_STEP_SIZE; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_GAMMA_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + resp->data[0] = PU_GAMMA_MIN_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + resp->data[0] = PU_GAMMA_MAX_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 2; + memcpy(&resp->data[0], &dev->gamma_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = PU_GAMMA_DEFAULT_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + resp->data[0] = PU_GAMMA_STEP_SIZE; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: { + int wbt_min = PU_WHITE_BALANCE_TEMPERATURE_MIN_VAL; + resp->length = 2; + memcpy(&resp->data[0], &wbt_min, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_MAX: { + int wbt_max = PU_WHITE_BALANCE_TEMPERATURE_MAX_VAL; + resp->length = 2; + memcpy(&resp->data[0], &wbt_max, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_CUR: + resp->length = 2; + memcpy(&resp->data[0], &dev->white_balance_temperature_val, + resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: { + int wbt_def = PU_WHITE_BALANCE_TEMPERATURE_DEFAULT_VAL; + resp->length = 2; + memcpy(&resp->data[0], &wbt_def, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + case UVC_GET_RES: { + int wbt_res = PU_WHITE_BALANCE_TEMPERATURE_STEP_SIZE; + resp->length = 2; + memcpy(&resp->data[0], &wbt_res, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + } + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 1; + resp->data[0] = dev->white_balance_temperature_auto_val; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + break; + case UVC_GET_DEF: + resp->data[0] = 1; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_GAIN_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + resp->data[0] = PU_GAIN_MIN_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + resp->data[0] = PU_GAIN_MAX_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 2; + memcpy(&resp->data[0], &dev->gain_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = PU_GAIN_DEFAULT_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + resp->data[0] = PU_GAIN_STEP_SIZE; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_HUE_AUTO_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->data[0] = 1; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 1; + resp->data[0] = dev->hue_auto_val; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = 1; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_POWER_LINE_FREQUENCY_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->data[0] = 1; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + resp->data[0] = 0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + resp->data[0] = 2; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + resp->data[0] = 1; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 1; + memcpy(&resp->data[0], &dev->power_line_frequency_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 3; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = 1; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case UVC_PU_DIGITAL_MULTIPLIER_CONTROL: + switch (req) { + case UVC_SET_CUR: + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + resp->data[0] = PU_DIGITAL_MULTIPLIER_CONTROL_MIN_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + resp->data[0] = PU_DIGITAL_MULTIPLIER_CONTROL_MAX_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = 2; + memcpy(&resp->data[0], &dev->zoom_val, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + resp->data[0] = PU_DIGITAL_MULTIPLIER_CONTROL_DEFAULT_VAL; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + resp->data[0] = PU_DIGITAL_MULTIPLIER_CONTROL_STEP_SIZE; + resp->length = 2; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + default: + LOG_DEBUG("++++++++Processing unit usb default req ,cs:%d", cs); + switch (req) { + case UVC_GET_LEN: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = sizeof(resp->data); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_SET_CUR: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + memset(resp->data, 0xFF, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 1; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + } + + break; + + /* Extension unit 'UVC_VC_Extension_Unit'. */ + case UVC_CTRL_XU_UNIT_ID: + switch (cs) { + case CMD_TOOLS_CTRL_1: + switch (req) { + case UVC_GET_LEN: + resp->data[0] = 0x4; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_SET_CUR: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + memset(resp->data, 0xFF, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = + len < sizeof(dev->ex_tool_ctrl1) ? len : sizeof(dev->ex_tool_ctrl1); + memcpy(resp->data, dev->ex_tool_ctrl1, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 1; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + case CMD_GET_CAMERA_VERSION: + switch (req) { + case UVC_GET_LEN: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = sizeof(resp->data); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_SET_CUR: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + memset(resp->data, 0xFF, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = + len < sizeof(dev->ex_sn_data) ? len : sizeof(dev->ex_sn_data); + memcpy(resp->data, dev->ex_sn_data, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 1; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + + case CMD_SET_CAMERA_IP: + switch (req) { + case UVC_GET_LEN: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = sizeof(resp->data); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_SET_CUR: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + memset(resp->data, 0xFF, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = + len < sizeof(dev->ex_ip_data) ? len : sizeof(dev->ex_ip_data); + memcpy(resp->data, dev->ex_ip_data, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 1; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + + case CMD_SET_H265: + switch (req) { + case UVC_GET_LEN: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = sizeof(resp->data); + resp->length = 4; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_SET_CUR: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x0; + resp->length = 4; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + memset(resp->data, 0, sizeof(resp->data)); + resp->length = 4; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + memset(resp->data, 0xFF, sizeof(resp->data)); + resp->length = 4; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + resp->length = len < sizeof(dev->xu_h265) ? len : sizeof(dev->xu_h265); + memcpy(&resp->data[0], &dev->xu_h265, resp->length); + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0; + resp->length = 4; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 1; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + + default: + LOG_DEBUG("+++++++++Extension unit usb default req ,cs:%d", cs); + switch (req) { + case UVC_GET_LEN: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = sizeof(resp->data); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_SET_CUR: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MIN: + memset(resp->data, 0, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_MAX: + memset(resp->data, 0xFF, sizeof(resp->data)); + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_CUR: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0x0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_DEF: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 0; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + case UVC_GET_RES: + memset(resp->data, 0, sizeof(resp->data)); + resp->data[0] = 1; + resp->length = len; + dev->request_error_code.data[0] = 0x00; + dev->request_error_code.length = 1; + break; + default: + resp->length = -EL2HLT; + dev->request_error_code.data[0] = 0x07; + dev->request_error_code.length = 1; + break; + } + break; + /* + * We don't support this control, so STALL the control + * ep. + resp->length = -EL2HLT; + /* + * If we were not supposed to handle this + * 'cs', prepare a Request Error Code response. + dev->request_error_code.data[0] = 0x06; + dev->request_error_code.length = 1; + break; + */ + } + break; + + default: + /* + * If we were not supposed to handle this + * 'cs', prepare a Request Error Code response. + */ + dev->request_error_code.data[0] = 0x06; + dev->request_error_code.length = 1; + break; + } + if (resp->length == -EL2HLT) { + LOG_DEBUG("unsupported: req=%02x, cs=%d, entity_id=%d, len=%d\n", req, cs, + entity_id, len); + resp->length = 0; + } + LOG_DEBUG("control request (req %02x cs %02x)\n", req, cs); +} + +static void uvc_events_process_streaming(struct uvc_device *dev, uint8_t req, + uint8_t cs, + struct uvc_request_data *resp) { + struct uvc_streaming_control *ctrl; + + LOG_DEBUG("streaming request (req %02x cs %02x)\n", req, cs); + + if (cs != UVC_VS_PROBE_CONTROL && cs != UVC_VS_COMMIT_CONTROL) + return; + + ctrl = (struct uvc_streaming_control *)&resp->data; + resp->length = sizeof *ctrl; + + switch (req) { + case UVC_SET_CUR: + dev->control = cs; + resp->length = 34; + break; + + case UVC_GET_CUR: + if (cs == UVC_VS_PROBE_CONTROL) + memcpy(ctrl, &dev->probe, sizeof *ctrl); + else + memcpy(ctrl, &dev->commit, sizeof *ctrl); +#if 1 + LOG_DEBUG("bmHint: %u\n", ctrl->bmHint); + LOG_DEBUG("bFormatIndex: %u\n", ctrl->bFormatIndex); + LOG_DEBUG("bFrameIndex: %u\n", ctrl->bFrameIndex); + LOG_DEBUG("dwFrameInterval: %u\n", ctrl->dwFrameInterval); + LOG_DEBUG("wKeyFrameRate: %u\n", ctrl->wKeyFrameRate); + LOG_DEBUG("wPFrameRate: %u\n", ctrl->wPFrameRate); + LOG_DEBUG("wCompQuality: %u\n", ctrl->wCompQuality); + LOG_DEBUG("wCompWindowSize: %u\n", ctrl->wCompWindowSize); + LOG_DEBUG("wDelay: %u\n", ctrl->wDelay); + LOG_DEBUG("dwMaxVideoFrameSize: %u\n", ctrl->dwMaxVideoFrameSize); + LOG_DEBUG("dwMaxPayloadTransferSize: %u\n", ctrl->dwMaxPayloadTransferSize); + LOG_DEBUG("dwClockFrequency: %u\n", ctrl->dwClockFrequency); + LOG_DEBUG("bmFramingInfo: %u\n", ctrl->bmFramingInfo); + LOG_DEBUG("bPreferedVersion: %u\n", ctrl->bPreferedVersion); + LOG_DEBUG("bMinVersion: %u\n", ctrl->bMinVersion); + LOG_DEBUG("bMaxVersion: %u\n", ctrl->bMaxVersion); +#endif + break; + + case UVC_GET_MIN: + case UVC_GET_MAX: + case UVC_GET_DEF: + if (req == UVC_GET_MAX) + uvc_fill_streaming_control(dev, ctrl, -1, -1, UINT_MAX); + else + uvc_fill_streaming_control(dev, ctrl, 1, 1, 0); + break; + + case UVC_GET_RES: + CLEAR(ctrl); + break; + + case UVC_GET_LEN: + resp->data[0] = 0x00; + resp->data[1] = 0x22; + resp->length = 2; + break; + + case UVC_GET_INFO: + resp->data[0] = 0x03; + resp->length = 1; + break; + } +} + +static void uvc_events_process_class(struct uvc_device *dev, + struct usb_ctrlrequest *ctrl, + struct uvc_request_data *resp) { + if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE) + return; + unsigned int interface = ctrl->wIndex & 0xff; + + if (interface == dev->fc->control.intf.bInterfaceNumber) { + uvc_events_process_control(dev, ctrl->bRequest, ctrl->wValue >> 8, + ctrl->wIndex >> 8, ctrl->wLength, resp); + } else if (interface == dev->fc->streaming.intf.bInterfaceNumber) { + uvc_events_process_streaming(dev, ctrl->bRequest, ctrl->wValue >> 8, resp); + } +} + +static void uvc_events_process_setup(struct uvc_device *dev, + struct usb_ctrlrequest *ctrl, + struct uvc_request_data *resp) { + dev->control = 0; + +#ifdef ENABLE_USB_REQUEST_DEBUG + LOG_DEBUG("\nbRequestType %02x bRequest %02x wValue %04x wIndex %04x " + "wLength %04x\n", + ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, ctrl->wIndex, + ctrl->wLength); +#endif + + switch (ctrl->bRequestType & USB_TYPE_MASK) { + case USB_TYPE_STANDARD: + uvc_events_process_standard(dev, ctrl, resp); + break; + + case USB_TYPE_CLASS: + uvc_events_process_class(dev, ctrl, resp); + break; + + default: + break; + } +} + +static int uvc_events_process_control_data(struct uvc_device *dev, uint8_t cs, + uint8_t entity_id, + struct uvc_request_data *data) { + unsigned int *val = (unsigned int *)data->data; + LOG_DEBUG(" data = %d, length = %d , current_cs = %d\n", *val, data->length, + dev->cs); + switch (entity_id) { + case 1: + switch (cs) { + case UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL: + if (sizeof(dev->exposure_time_val) >= data->length) { + memcpy(&dev->exposure_time_val, data->data, data->length); + LOG_INFO("set exposure_time :%d \n", dev->exposure_time_val); + camera_pu_control_set(UVC_PU_EXPOSURE_TIME_CONTROL, + dev->exposure_time_val); + } + break; + case UVC_CT_IRIS_ABSOLUTE_CONTROL: + if (sizeof(dev->iris_val) >= data->length) { + memcpy(&dev->iris_val, data->data, data->length); + LOG_INFO("set iris value :%d \n", dev->iris_val); + } + break; + case UVC_CT_AE_MODE_CONTROL: + if (sizeof(dev->ae_mode_val) >= data->length) { + memcpy(&dev->ae_mode_val, data->data, data->length); + LOG_INFO("set AE Mode :%d \n", dev->ae_mode_val); + camera_pu_control_set(UVC_PU_AE_MODE_CONTROL, dev->ae_mode_val); + } + break; + + default: + break; + } + + break; + /* Processing unit 'UVC_VC_PROCESSING_UNIT'. */ + case 2: + switch (cs) { + case UVC_PU_BRIGHTNESS_CONTROL: + if (sizeof(dev->brightness_val) >= data->length) { + memcpy(&dev->brightness_val, data->data, data->length); + } + if (!dev->run_standalone) + /* + * Try to change the Brightness attribute on + * Video capture device. Note that this try may + * succeed or end up with some error on the + * video capture side. By default to keep tools + * like USBCV's UVC test suite happy, we are + * maintaining a local copy of the current + * brightness value in 'dev->brightness_val' + * variable and we return the same value to the + * Host on receiving a GET_CUR(BRIGHTNESS) + * control request. + * + * FIXME: Keeping in view the point discussed + * above, notice that we ignore the return value + * from the function call below. To be strictly + * compliant, we should return the same value + * accordingly. + */ + v4l2_set_ctrl(dev->vdev, dev->brightness_val, V4L2_CID_BRIGHTNESS); + + break; + case UVC_PU_CONTRAST_CONTROL: + LOG_INFO("UVC_PU_CONTRAST_CONTROL receive\n"); + if (sizeof(dev->contrast_val) >= data->length) { + memcpy(&dev->contrast_val, data->data, data->length); + LOG_INFO("UVC_PU_CONTRAST_CONTROL: 0x%02x 0x%02x\n", data->data[0], + data->data[1]); + } + break; + case UVC_PU_HUE_CONTROL: + if (sizeof(dev->hue_val) >= data->length) { + memcpy(&dev->hue_val, data->data, data->length); + } + break; + case UVC_PU_SATURATION_CONTROL: + if (sizeof(dev->saturation_val) >= data->length) { + memcpy(&dev->saturation_val, data->data, data->length); + } + break; + case UVC_PU_SHARPNESS_CONTROL: + if (sizeof(dev->sharpness_val) >= data->length) + memcpy(&dev->sharpness_val, data->data, data->length); + break; + case UVC_PU_GAMMA_CONTROL: + if (sizeof(dev->gamma_val) >= data->length) + memcpy(&dev->gamma_val, data->data, data->length); + break; + case UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL: + LOG_INFO("UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL: 0x%02x 0x%02x\n", + data->data[0], data->data[1]); + if (sizeof(dev->white_balance_temperature_val) >= data->length) { + memcpy(&dev->white_balance_temperature_val, data->data, data->length); + } + break; + case UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL: + LOG_INFO("UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL: 0x%02x\n", + data->data[0]); + if (sizeof(dev->white_balance_temperature_auto_val) >= data->length) { + memcpy(&dev->white_balance_temperature_auto_val, data->data, + data->length); + } + break; + case UVC_PU_GAIN_CONTROL: + if (sizeof(dev->gain_val) >= data->length) + memcpy(&dev->gain_val, data->data, data->length); + break; + case UVC_PU_HUE_AUTO_CONTROL: + if (sizeof(dev->hue_auto_val) >= data->length) + memcpy(&dev->hue_auto_val, data->data, data->length); + break; + case UVC_PU_POWER_LINE_FREQUENCY_CONTROL: + if (sizeof(dev->power_line_frequency_val) >= data->length) { + memcpy(&dev->power_line_frequency_val, data->data, data->length); + } + break; + case UVC_PU_DIGITAL_MULTIPLIER_CONTROL: + if (sizeof(dev->zoom_val) >= data->length) { + memcpy(&dev->zoom_val, data->data, data->length); + camera_control_set_zoom(dev->zoom_val); + } + break; + default: + break; + } + camera_pu_control_set(cs, *val); + if (uvc_pu_control_cb) + uvc_pu_control_cb(cs, *val); + + break; + /* Extension unit 'UVC_VC_Extension_Unit'. */ + case 6: + switch (cs) { + case CMD_TOOLS_CTRL_1: + if (sizeof(dev->ex_tool_ctrl1) >= data->length) { + memset(dev->ex_tool_ctrl1, 0, sizeof(dev->ex_tool_ctrl1)); + memcpy(dev->ex_tool_ctrl1, data->data, data->length); + LOG_INFO("Extension:CMD_TOOLS_CTRL_1 set cur data: 0x%02x 0x%02x " + "0x%02x 0x%02x\n", + data->data[0], data->data[1], data->data[2], data->data[3]); + unsigned int command = 0; + memcpy(&command, dev->ex_tool_ctrl1, sizeof(command)); + if (command == 0xFFFFFFFF) { + LOG_INFO("recive host reboot loader cmd"); + // system("reboot loader &"); + system("touch /tmp/reboot_loader &"); + } + } + break; + + case CMD_GET_CAMERA_VERSION: + if (sizeof(dev->ex_sn_data) >= data->length) { + memset(dev->ex_sn_data, 0, sizeof(dev->ex_sn_data)); + memcpy(dev->ex_sn_data, data->data, data->length); + LOG_INFO("Extension:CMD_GET_CAMERA_VERSION set cur data: 0x%02x 0x%02x " + "0x%02x\n", + data->data[0], data->data[1], data->data[2]); + } + break; + + case CMD_SET_CAMERA_IP: + if (sizeof(dev->ex_ip_data) >= data->length) { + memcpy(dev->ex_ip_data, data->data, data->length); + LOG_INFO("CMD_SET_CAMERA_IP : %d.%d.%d.%d \n", dev->ex_ip_data[0], + dev->ex_ip_data[1], dev->ex_ip_data[2], dev->ex_ip_data[3]); + update_camera_ip(dev); + } + break; + + case CMD_SET_H265: + if (sizeof(dev->xu_h265) >= data->length) { + memcpy(&dev->xu_h265, data->data, data->length); + LOG_INFO("Extension: CMD_SET_H265 set cur data: %d\n", dev->xu_h265); + } + break; + + default: + break; + } + break; + + default: + break; + } + LOG_DEBUG("Control Request data phase (cs %02x data %d entity %02x)\n", cs, + *val, entity_id); + return 0; +} + +static int uvc_events_process_data(struct uvc_device *dev, + struct uvc_request_data *data) { + struct uvc_streaming_control *target; + struct uvc_streaming_control *ctrl; + struct v4l2_format fmt; + int ret = 0; + + if (dev->usb_state == USB_STATE_INIT) { + dev->usb_state = USB_STATE_FIRST_CMD; + struct timespec now_tm = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &now_tm); + dev->first_cmd_pts = + now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; // us + } + + switch (dev->control) { + case UVC_VS_PROBE_CONTROL: + LOG_DEBUG("setting probe control, length = %d\n", data->length); + target = &dev->probe; + break; + + case UVC_VS_COMMIT_CONTROL: + LOG_DEBUG("setting commit control, length = %d\n", data->length); + target = &dev->commit; + break; + + default: + LOG_DEBUG("setting process control, length = %d\n", data->length); + + LOG_DEBUG("cs: %u, entity_id: %u\n", dev->cs, dev->entity_id); + ret = uvc_events_process_control_data(dev, dev->cs, dev->entity_id, data); + if (ret < 0) + goto err; + + return 0; + } + + ctrl = (struct uvc_streaming_control *)&data->data; + if (dev->control == UVC_VS_PROBE_CONTROL) { +#if 1 + LOG_DEBUG("host probe want ++++vs config:\n"); + LOG_DEBUG("bmHint: %u\n", ctrl->bmHint); + LOG_DEBUG("bFormatIndex: %u\n", ctrl->bFormatIndex); + LOG_DEBUG("bFrameIndex: %u\n", ctrl->bFrameIndex); + LOG_DEBUG("dwFrameInterval: %u\n", ctrl->dwFrameInterval); + LOG_DEBUG("wKeyFrameRate: %u\n", ctrl->wKeyFrameRate); + LOG_DEBUG("wPFrameRate: %u\n", ctrl->wPFrameRate); + LOG_DEBUG("wCompQuality: %u\n", ctrl->wCompQuality); + LOG_DEBUG("wCompWindowSize: %u\n", ctrl->wCompWindowSize); + LOG_DEBUG("wDelay: %u\n", ctrl->wDelay); + LOG_DEBUG("dwMaxVideoFrameSize: %u\n", ctrl->dwMaxVideoFrameSize); + LOG_DEBUG("dwMaxPayloadTransferSize: %u\n", ctrl->dwMaxPayloadTransferSize); + LOG_DEBUG("dwClockFrequency: %u\n", ctrl->dwClockFrequency); + LOG_DEBUG("bmFramingInfo: %u\n", ctrl->bmFramingInfo); + LOG_DEBUG("bPreferedVersion: %u\n", ctrl->bPreferedVersion); + LOG_DEBUG("bMinVersion: %u\n", ctrl->bMinVersion); + LOG_DEBUG("bMaxVersion: %u\n", ctrl->bMaxVersion); +#endif + } + uvc_fill_streaming_control(dev, target, ctrl->bFormatIndex, ctrl->bFrameIndex, + ctrl->dwFrameInterval); + dev->fps = 10000000 / target->dwFrameInterval; + // uvc_control_config(dev); + + if (dev->control == UVC_VS_COMMIT_CONTROL) { + if (uvc_video_get_uvc_process(dev->video_id)) + return 0; + + uvc_control_config(dev); + + /* + * Try to set the default format at the V4L2 video capture + * device as requested by the user. + */ + CLEAR(fmt); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.fmt.pix.field = V4L2_FIELD_ANY; + fmt.fmt.pix.width = dev->width; + fmt.fmt.pix.height = dev->height; + fmt.fmt.pix.pixelformat = dev->fcc; + + switch (dev->fcc) { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_NV12: + fmt.fmt.pix.sizeimage = (fmt.fmt.pix.width * fmt.fmt.pix.height * 2); + break; + case V4L2_PIX_FMT_MJPEG: + fmt.fmt.pix.sizeimage = (fmt.fmt.pix.width * fmt.fmt.pix.height); + break; + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_H265: +#ifdef RK_ENABLE_FASTBOOT + fmt.fmt.pix.sizeimage = (fmt.fmt.pix.width * fmt.fmt.pix.height) / 2; +#else + fmt.fmt.pix.sizeimage = (fmt.fmt.pix.width * fmt.fmt.pix.height); +#endif + break; + } + + uvc_set_user_resolution(fmt.fmt.pix.width, fmt.fmt.pix.height, + dev->video_id); + uvc_set_user_fcc(fmt.fmt.pix.pixelformat, dev->video_id); + if (uvc_buffer_init(dev)) + goto err; + + /* + * As per the new commit command received from the UVC host + * change the current format selection at both UVC and V4L2 + * sides. + */ + ret = uvc_video_set_format(dev); + if (ret < 0) + goto err; + + if (!dev->run_standalone) { + /* UVC - V4L2 integrated path. */ + ret = v4l2_set_format(dev->vdev, &fmt); + if (ret < 0) + goto err; + } + + if (dev->bulk) { + ret = uvc_handle_streamon_event(dev); + if (ret < 0) + goto err; + } + } + + return 0; + +err: + return ret; +} + +static void uvc_events_process(struct uvc_device *dev) { + struct v4l2_event v4l2_event; + struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; + struct uvc_request_data resp; + int ret = 0; + + ret = ioctl(dev->uvc_fd, VIDIOC_DQEVENT, &v4l2_event); + if (ret < 0) { + LOG_ERROR("VIDIOC_DQEVENT failed: %s (%d)\n", strerror(errno), errno); + return; + } + + memset(&resp, 0, sizeof resp); + resp.length = -EL2HLT; + + switch (v4l2_event.type) { + case UVC_EVENT_CONNECT: + return; + + case UVC_EVENT_DISCONNECT: + dev->uvc_shutdown_requested = 1; + LOG_DEBUG("UVC: Possible USB shutdown requested from " + "Host, seen via UVC_EVENT_DISCONNECT \n"); + return; + + case UVC_EVENT_SETUP: + LOG_DEBUG("uvc_events_process:UVC_EVENT_SETUP \n"); + if (dev->suspend) { + dev->suspend = 0; + set_uvc_control_suspend(0); + } + uvc_events_process_setup(dev, &uvc_event->req, &resp); + break; + + case UVC_EVENT_DATA: + LOG_DEBUG("uvc_events_process:UVC_EVENT_DATA \n"); + ret = uvc_events_process_data(dev, &uvc_event->data); + if (ret < 0) + break; + + return; + + case UVC_EVENT_STREAMON: + LOG_INFO("uvc_events_process:UVC_EVENT_STREAMON dev->io=%d dev->bulk:%d, " + "video_id:%d\n", + dev->io, dev->bulk, dev->video_id); +#ifdef ENABLE_BUFFER_TIME_DEBUG + struct timeval buffer_time; + gettimeofday(&buffer_time, NULL); + LOG_ERROR("UVC STREAMON START TIME:%d.%d (us)", buffer_time.tv_sec, + buffer_time.tv_usec); +#endif + if (!dev->bulk) + uvc_handle_streamon_event(dev); + dev->drop_count = 0; + dev->get_buf_count = 0; + dev->qbuf_count = 0; + dev->dqbuf_count = 0; + dev->try_count = 0; + dev->usb_state = USB_STATE_FIRST_GET_READY; + + struct timespec now_tm = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &now_tm); + dev->stream_on_pts = + now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; // us + +#if UVC_DYNAMIC_DEBUG_FPS + uvc_debug_info.stream_on_pts = dev->stream_on_pts; + uvc_debug_info.first_frm = true; + gettimeofday(&uvc_debug_info.enter_time, NULL); +#endif + return; + + case UVC_EVENT_STREAMOFF: + LOG_INFO("uvc_events_process:UVC_EVENT_STREAMOFF enter\n"); + uvc_control_streamoff(dev->video_id); + // uvc_buffer_deinit(dev->video_id); + // sleep(1); + /* Stop V4L2 streaming... */ + if (!dev->run_standalone && dev->vdev->is_streaming) { + /* UVC - V4L2 integrated path. */ + v4l2_stop_capturing(dev->vdev); + v4l2_uninit_device(dev->vdev); + v4l2_reqbufs(dev->vdev, 0); + dev->vdev->is_streaming = 0; + } + + set_uvc_control_stop(dev->video_id); + /* ... and now UVC streaming.. */ + if (dev->is_streaming) { + uvc_video_stream(dev, 0); + uvc_uninit_device(dev); + uvc_video_reqbufs(dev, 0); + dev->is_streaming = 0; + dev->first_buffer_queued = 0; + } + dev->usb_state = USB_STATE_INIT; + LOG_INFO("UVC_EVENT_STREAMOFF exit\n"); + return; + case UVC_EVENT_RESUME: + LOG_INFO("UVC_EVENT_RESUME:\n"); + if (dev->suspend) { + dev->suspend = 0; + set_uvc_control_suspend(0); + } + return; + case UVC_EVENT_SUSPEND: + LOG_INFO("UVC_EVENT_SUSPEND\n"); + set_uvc_control_suspend(1); + dev->suspend = 1; + return; + } + + ret = ioctl(dev->uvc_fd, UVCIOC_SEND_RESPONSE, &resp); + if (ret < 0) { + LOG_ERROR("UVCIOC_S_EVENT failed: %s (%d)\n", strerror(errno), errno); + return; + } +} + +static void uvc_events_init(struct uvc_device *dev) { + struct v4l2_event_subscription sub; + unsigned int payload_size; + + switch (dev->fcc) { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_NV12: + payload_size = dev->width * dev->height * 2; + break; + case V4L2_PIX_FMT_MJPEG: + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_H265: + payload_size = dev->imgsize; + break; + default: + return; + } + + uvc_fill_streaming_control(dev, &dev->probe, 1, 1, 0); + uvc_fill_streaming_control(dev, &dev->commit, 1, 1, 0); + + if (dev->bulk) { + /* FIXME Crude hack, must be negotiated with the driver. */ + dev->probe.dwMaxPayloadTransferSize = dev->commit.dwMaxPayloadTransferSize = + payload_size; + } + + memset(&sub, 0, sizeof sub); + sub.type = UVC_EVENT_SETUP; + ioctl(dev->uvc_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); + sub.type = UVC_EVENT_DATA; + ioctl(dev->uvc_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); + sub.type = UVC_EVENT_STREAMON; + ioctl(dev->uvc_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); + sub.type = UVC_EVENT_STREAMOFF; + ioctl(dev->uvc_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); + sub.type = UVC_EVENT_RESUME; + ioctl(dev->uvc_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); + sub.type = UVC_EVENT_SUSPEND; + ioctl(dev->uvc_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); +} + +/* --------------------------------------------------------------------------- + * main + */ + +static void image_load(struct uvc_device *dev, const char *img) { + int fd = -1; + + if (img == NULL) + return; + + fd = open(img, O_RDONLY); + if (fd == -1) { + LOG_ERROR("Unable to open MJPEG image '%s'\n", img); + return; + } + + dev->imgsize = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + dev->imgdata = malloc(dev->imgsize); + if (dev->imgdata == NULL) { + LOG_ERROR("Unable to allocate memory for MJPEG image\n"); + dev->imgsize = 0; + return; + } + + read(fd, dev->imgdata, dev->imgsize); + close(fd); +} + +extern int app_quit; +int uvc_gadget_main(struct uvc_function_config *fc) { + struct uvc_device *udev = NULL; + struct v4l2_device *vdev; + struct timeval tv; + struct v4l2_format fmt; + char uvc_devname[32] = {0}; + char *v4l2_devname = "/dev/video0"; + char *mjpeg_image = NULL; + fd_set fdsv, fdsu; + int ret, nfds; + int bulk_mode = 0; + int dummy_data_gen_mode = 1; + /* Frame format/resolution related params. */ + int default_format = 1; + int default_resolution = 1; + /* USB speed related params */ + int mult = 0; + int burst = 0; + enum usb_device_speed speed = USB_SPEED_HIGH; /* High-Speed 1109 is usb 2.0*/ +#if (UVC_IO_METHOD == UVC_IO_METHOD_MMAP) + enum io_method uvc_io_method = IO_METHOD_MMAP; +#elif (UVC_IO_METHOD == UVC_IO_METHOD_USERPTR) + enum io_method uvc_io_method = IO_METHOD_USERPTR; +#else + enum io_method uvc_io_method = IO_METHOD_DMA_BUFF; +#endif + int id = fc->video; + snprintf(uvc_devname, sizeof(uvc_devname), "/dev/video%d", id); + + /* Open the UVC device. */ + ret = uvc_open(&udev, uvc_devname); + if (udev == NULL || ret < 0) + return 1; + + udev->uvc_devname = uvc_devname; + udev->video_id = id; + udev->fc = fc; + + /* Set parameters as passed by user. */ + udev->width = (default_resolution == 0) ? 640 : 1280; + udev->height = (default_resolution == 0) ? 480 : 720; + udev->imgsize = (default_format == 0) + ? (udev->width * udev->height * 2) + : (udev->width * udev->height); + switch (default_format) { + case 1: + udev->fcc = V4L2_PIX_FMT_MJPEG; + break; + + case 2: + udev->fcc = V4L2_PIX_FMT_H264; + break; + + case 3: + udev->fcc = V4L2_PIX_FMT_H265; + break; + + case 0: + default: + udev->fcc = V4L2_PIX_FMT_YUYV; + break; + } + uvc_set_user_fcc(udev->fcc, udev->video_id); + udev->io = uvc_io_method; + udev->bulk = bulk_mode; + udev->nbufs = 0; + udev->mult = mult; + udev->burst = burst; + udev->speed = speed; + udev->control = 0; + + if (dummy_data_gen_mode || mjpeg_image) + /* UVC standalone setup. */ + udev->run_standalone = 1; + switch (speed) { + case USB_SPEED_FULL: + /* Full Speed. */ + if (bulk_mode) + udev->maxpkt = 64; + else + udev->maxpkt = 1023; + break; + + case USB_SPEED_HIGH: + /* High Speed. */ + if (bulk_mode) + udev->maxpkt = 512; + else + udev->maxpkt = 1024; + break; + + case USB_SPEED_SUPER: + default: + /* Super Speed. */ + if (bulk_mode) + udev->maxpkt = 1024; + else + udev->maxpkt = 1024; + break; + } + + if (mjpeg_image) + image_load(udev, mjpeg_image); + + /* Init UVC events. */ + uvc_events_init(udev); + uvc_set_user_run_state(true, udev->video_id); + + while (uvc_get_user_run_state(udev->video_id)) { + FD_ZERO(&fdsu); + /* We want both setup and data events on UVC interface.. */ + FD_SET(udev->uvc_fd, &fdsu); + fd_set efds = fdsu; + fd_set dfds = fdsu; + /* Timeout. */ + tv.tv_sec = 5; + tv.tv_usec = 0; + ret = select(udev->uvc_fd + 1, NULL, &dfds, &efds, &tv); + if (-1 == ret) { + LOG_ERROR("select error %d, %s\n", errno, strerror(errno)); + if (EINTR == errno) + continue; + + break; + } + + if (0 == ret) { + if (udev->bulk) + continue; + LOG_ERROR("select timeout\n"); + if (!access("/tmp/uvc_no_timeout", 0)) + continue; + break; + } + + if (app_quit) { + LOG_ERROR("app quit=%d...\n", app_quit); + if (3 == app_quit) { + uvc_control_inbuf_deinit(); + break; + app_quit = 0; + } else + break; + } + if (FD_ISSET(udev->uvc_fd, &efds)) + uvc_events_process(udev); + if (FD_ISSET(udev->uvc_fd, &dfds)) + uvc_video_process(udev); + } + + set_uvc_control_stop(id); + if (udev->is_streaming) { + /* ... and now UVC streaming.. */ + uvc_video_stream(udev, 0); + uvc_uninit_device(udev); + uvc_video_reqbufs(udev, 0); + udev->is_streaming = 0; + } + uvc_control_streamoff(id); + uvc_control_delete(id); + uvc_close(udev); + set_uvc_control_restart(); + LOG_INFO("uvc_gadget_main exit"); + + return 0; +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc-gadget.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc-gadget.h new file mode 100755 index 000000000..d9a10559f --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc-gadget.h @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _UVC_GADGET_H_ +#define _UVC_GADGET_H_ + +#include +#include +#include + +#define UVC_EVENT_FIRST (V4L2_EVENT_PRIVATE_START + 0) +#define UVC_EVENT_CONNECT (V4L2_EVENT_PRIVATE_START + 0) +#define UVC_EVENT_DISCONNECT (V4L2_EVENT_PRIVATE_START + 1) +#define UVC_EVENT_STREAMON (V4L2_EVENT_PRIVATE_START + 2) +#define UVC_EVENT_STREAMOFF (V4L2_EVENT_PRIVATE_START + 3) +#define UVC_EVENT_SETUP (V4L2_EVENT_PRIVATE_START + 4) +#define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5) +#define UVC_EVENT_SUSPEND (V4L2_EVENT_PRIVATE_START + 6) +#define UVC_EVENT_RESUME (V4L2_EVENT_PRIVATE_START + 7) +#define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 8) + +#define MAX_UVC_REQUEST_DATA_LENGTH 60 + +#define UVC_CTRL_INTERFACE_ID 0x00 +#define UVC_CTRL_CAMERA_TERMINAL_ID 0x01 +#define UVC_CTRL_PROCESSING_UNIT_ID 0x02 +#define UVC_CTRL_EXTENSION_UNIT_ID 0x03 +#define UVC_CTRL_OUTPUT_TERMINAL_ID 0x04 +#define UVC_CTRL_XU_UNIT_ID 0x06 + +struct uvc_request_data { + __s32 length; + __u8 data[60]; +}; + +struct uvc_event { + union { + enum usb_device_speed speed; + struct usb_ctrlrequest req; + struct uvc_request_data data; + }; +}; + +#define UVCIOC_SEND_RESPONSE _IOW('U', 1, struct uvc_request_data) + +#define UVC_INTF_CONTROL 0 +#define UVC_INTF_STREAMING 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "uvc_control.h" +#include "uvc_video.h" + +#include +#include +#include + +#include "uvc_configfs.h" +#include +#include +#include + +#define V4L2_PIX_FMT_H265 \ + v4l2_fourcc('H', '2', '6', '5') /* H265 with start codes */ +#define UVC_PU_FPS_CONTROL 0xff +#define UVC_PU_ROLL_CONTROL 0xfd +#define UVC_PU_EXPOSURE_TIME_CONTROL 0xfc +#define UVC_PU_AE_MODE_CONTROL 0xfb + +/* --------------------------------------------------------------------------- + * Generic stuff + */ + +enum XuCmd { + CMD_TOOLS_CTRL_1 = 0x01, + CMD_GET_CAMERA_VERSION, + CMD_SHUTDOWN_CAMERA, + CMD_RESET_CAMERA, + CMD_SET_MOTOR_RATE = 0x06, + CMD_SET_MOTOR_BY_STEPS = 0x07, + CMD_SET_MOTOR_BY_USER = 0x08, + CMD_STOP_MOTOR_BY_USER = 0x09, + CMD_SET_CAMERA_IP = 0x0a, + CMD_SET_H265 = 0x0b, + CMD_MAX_NUM = CMD_SET_H265, +}; + +/* IO methods supported */ +enum io_method { + IO_METHOD_MMAP, + IO_METHOD_USERPTR, + IO_METHOD_DMA_BUFF, +}; + +#define UVC_IO_METHOD_MMAP 0 +#define UVC_IO_METHOD_USERPTR 1 +#define UVC_IO_METHOD_DMA_BUFF 2 + +#define USE_MPI_BUF_TO_UVC_VIDEO_BUFFER 1 +#define UVC_IO_METHOD UVC_IO_METHOD_USERPTR + +/* Buffer representing one video frame */ +struct buffer { + struct v4l2_buffer buf; + void *start; + size_t length; +}; + +struct v4l2_buffer_info { + // struct uvc_buffer *uvc_buf; + void *frame; // mb + int fd; + int index; + unsigned long userptr; +}; + +enum USB_STATE { + USB_STATE_INIT, + USB_STATE_FIRST_CMD, + USB_STATE_FIRST_GET_READY, + USB_STATE_FIRST_GET_OK, + USB_STATE_FIRST_SEND_OK, + USB_STATE_NORMAL_RUN +}; + +/* Represents a UVC based video output device */ +struct uvc_device { + int video_id; + /* uvc device specific */ + int uvc_fd; + int is_streaming; + int run_standalone; + char *uvc_devname; + struct uvc_function_config *fc; + int suspend; + int need_bypass; + /* uvc control request specific */ + struct uvc_streaming_control probe; + struct uvc_streaming_control commit; + int control; + struct uvc_request_data request_error_code; + unsigned int brightness_val; + unsigned short contrast_val; + int hue_val; + unsigned int saturation_val; + unsigned int sharpness_val; + unsigned int gamma_val; + unsigned int white_balance_temperature_val; + unsigned int white_balance_temperature_auto_val; + unsigned int gain_val; + unsigned int hue_auto_val; + unsigned int zoom_val; + int pan_val; + int tilt_val; + short roll_val; + short iris_val; + int exposure_time_val; + unsigned char ae_mode_val; + unsigned char power_line_frequency_val; + unsigned char ex_tool_ctrl1[4]; + unsigned char ex_sn_data[MAX_UVC_REQUEST_DATA_LENGTH]; + unsigned char ex_ip_data[MAX_UVC_REQUEST_DATA_LENGTH]; // + unsigned char ex_date_data[MAX_UVC_REQUEST_DATA_LENGTH]; + unsigned int eptz_flag; + unsigned int xu_h265; + + /* uvc buffer specific */ + enum io_method io; + struct buffer *mem; + struct buffer *dummy_buf; + int nbufs; + unsigned int fcc; + unsigned int width; + unsigned int height; + unsigned int fps; + + unsigned int bulk; + uint8_t color; + unsigned int imgsize; + void *imgdata; + + /* USB speed specific */ + int mult; + int burst; + int maxpkt; + enum usb_device_speed speed; + + /* uvc specific flags */ + int first_buffer_queued; + int uvc_shutdown_requested; + + /* uvc buffer queue and dequeue counters */ + unsigned long long int qbuf_count; + unsigned long long int dqbuf_count; + + /* v4l2 device hook */ + struct v4l2_device *vdev; + uint8_t cs; + uint8_t entity_id; + struct v4l2_buffer ubuf; + + struct v4l2_buffer_info *vbuf_info; + int drop_count; + int try_count; + enum USB_STATE usb_state; + unsigned int first_usb_get_ready_pts; + unsigned int first_usb_get_ok_pts; + unsigned int first_usb_send_ok_pts; + unsigned int first_cmd_pts; + unsigned int stream_on_pts; + int get_buf_count; +}; + +int uvc_gadget_main(struct uvc_function_config *fc); +int uvc_video_reqbufs(struct uvc_device *dev, int nbufs); +int uvc_video_stream(struct uvc_device *dev, int enable); + +#ifdef __cplusplus +} +#endif + +#endif /* _UVC_GADGET_H_ */ diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_configfs.c b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_configfs.c new file mode 100644 index 000000000..28cbdd31c --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_configfs.c @@ -0,0 +1,693 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * ConfigFS Gadget device handling + * + * Copyright (C) 2020 Rockchip Electronics Co., Ltd. + * + */ + +/* To provide basename and asprintf from the GNU library. */ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "uvc_configfs.h" + +#define V4L2_PIX_FMT_H265 \ + v4l2_fourcc('H', '2', '6', '5') /* H265 with start codes */ + +#define UVC_FUNCTION_NAME "uvc*" + +#define UVC_GUID_FORMAT_MJPEG \ + { \ + 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, \ + 0x38, 0x9b, 0x71 \ + } +#define UVC_GUID_FORMAT_YUY2 \ + { \ + 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, \ + 0x38, 0x9b, 0x71 \ + } +#define UVC_GUID_FORMAT_NV12 \ + { \ + 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, \ + 0x38, 0x9b, 0x71 \ + } +#define UVC_GUID_FORMAT_H264 \ + { \ + 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, \ + 0x38, 0x9b, 0x71 \ + } +#define UVC_GUID_FORMAT_H265 \ + { \ + 'H', '2', '6', '5', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, \ + 0x38, 0x9b, 0x71 \ + } + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +struct uvc_function_format_info { + uint8_t guid[16]; + uint32_t fcc; +}; + +static struct uvc_function_format_info uvc_formats[] = { + { + .guid = UVC_GUID_FORMAT_YUY2, .fcc = V4L2_PIX_FMT_YUYV, + }, + { + .guid = UVC_GUID_FORMAT_MJPEG, .fcc = V4L2_PIX_FMT_MJPEG, + }, + { + .guid = UVC_GUID_FORMAT_H264, .fcc = V4L2_PIX_FMT_H264, + }, + { + .guid = UVC_GUID_FORMAT_H265, .fcc = V4L2_PIX_FMT_H265, + }, + { + .guid = UVC_GUID_FORMAT_NV12, .fcc = V4L2_PIX_FMT_NV12, + }}; + +/* ----------------------------------------------------------------------------- + * Path handling and support + */ +static char *path_join(const char *dirname, const char *name) { + char *path; + int ret; + + ret = asprintf(&path, "%s/%s", dirname, name); + + /* + * asprintf returns -1 on allocation or other errors, leaving 'path' + * undefined. We shouldn't even call free(path) here. We want to return + * NULL on error, so we must manually set it. + */ + if (ret < 0) + path = NULL; + + return path; +} + +static char *path_glob_index_match(const char *g, unsigned int index) { + glob_t globbuf; + char *match = NULL; + + glob(g, 0, NULL, &globbuf); + + if (globbuf.gl_pathc > index) + match = strdup(globbuf.gl_pathv[index]); + + globfree(&globbuf); + + return match; +} + +/* + * Find and return the full path of the first directory entry that satisfies + * the match function. + */ +static char *dir_first_match(const char *dir, + int (*match)(const struct dirent *)) { + struct dirent **entries; + unsigned int i; + int n_entries; + char *path; + + n_entries = scandir(dir, &entries, match, alphasort); + if (n_entries < 0) + return NULL; + + if (n_entries == 0) { + free(entries); + return NULL; + } + + path = path_join(dir, entries[0]->d_name); + + for (i = 0; i < (unsigned int)n_entries; ++i) + free(entries[i]); + + free(entries); + + return path; +} + +/* ----------------------------------------------------------------------------- + * Attribute handling + */ +static int attribute_read(const char *path, const char *file, void *buf, + unsigned int len) { + char *f; + int ret; + int fd; + + f = path_join(path, file); + if (!f) + return -ENOMEM; + + fd = open(f, O_RDONLY); + free(f); + if (fd == -1) { + printf("Failed to open attribute %s: %s\n", file, strerror(errno)); + return -ENOENT; + } + + ret = read(fd, buf, len); + close(fd); + + if (ret < 0) { + printf("Failed to read attribute %s: %s\n", file, strerror(errno)); + return -ENODATA; + } + + return len; +} + +static int attribute_read_uint(const char *path, const char *file, + unsigned int *val) { + char buf[11] = {0}; + char *endptr; + int ret; + + ret = attribute_read(path, file, buf, sizeof(buf) - 1); + if (ret < 0) + return ret; + + buf[ret] = '\0'; + errno = 0; + + /* base 0: Autodetect hex, octal, decimal. */ + *val = strtoul(buf, &endptr, 0); + if (errno) + return -errno; + + if (endptr == buf) + return -ENODATA; + + return 0; +} + +static char *attribute_read_str(const char *path, const char *file) { + char buf[1024] = {0}; + char *p; + int ret; + + ret = attribute_read(path, file, buf, sizeof(buf) - 1); + if (ret < 0) + return NULL; + + buf[ret] = '\0'; + + p = strrchr(buf, '\n'); + if (p == NULL) + return NULL; + if (p != buf) + *p = '\0'; + + return strdup(buf); +} + +static char *configfs_find_uvc_function(unsigned int index) { + const char *target = UVC_FUNCTION_NAME; + const char *format; + char *func_path; + char *path; + int ret; + + format = "%s/usb_gadget/*/functions/%s"; + ret = asprintf(&path, format, "/sys/kernel/config", target); + if (!ret) + return NULL; + + func_path = path_glob_index_match(path, index); + + free(path); + + return func_path; +} + +static int udc_find_video_device(const char *udc, const char *function) { + char *vpath; + char *video = NULL; + glob_t globbuf; + int video_id = -1; + unsigned int i; + int ret; + + ret = asprintf(&vpath, "/sys/class/udc/%s/device/gadget/video4linux/video*", + udc ? udc : "*"); + if (!ret) + return -1; + + glob(vpath, 0, NULL, &globbuf); + free(vpath); + + for (i = 0; i < globbuf.gl_pathc; ++i) { + char *config; + bool match; + + /* Match on the first if no search string. */ + if (!function) + break; + + config = attribute_read_str(globbuf.gl_pathv[i], "function_name"); + match = strcmp(function, config) == 0; + free(config); + if (match) + break; + } + + if (i < globbuf.gl_pathc) { + const char *v = basename(globbuf.gl_pathv[i]); + video = path_join("/dev", v); + if (sscanf(video, "/dev/video%d", &video_id) != 1) + video_id = -1; + free(video); + } + + globfree(&globbuf); + + return video_id; +} + +/* + * configfs_free_uvc_function - Free a uvc_function_config object + * @fc: The uvc_function_config to be freed + * + * Free the given @fc function previously allocated by a call to + * configfs_parse_uvc_function(). + */ +void configfs_free_uvc_function(struct uvc_function_config *fc) { + unsigned int i, j; + + free(fc->udc); + free(fc->dev_name); + + for (i = 0; i < fc->streaming.num_formats; ++i) { + struct uvc_function_config_format *format = &fc->streaming.formats[i]; + + for (j = 0; j < format->num_frames; ++j) { + struct uvc_function_config_frame *frame = &format->frames[j]; + + free(frame->intervals); + } + free(format->frames); + } + free(fc->streaming.formats); + free(fc); +} + +#define configfs_parse_child(parent, child, cfg, parse) \ + ({ \ + char *__path; \ + int __ret; \ + \ + __path = path_join((parent), (child)); \ + if (__path) { \ + __ret = parse(__path, (cfg)); \ + free(__path); \ + } else { \ + __ret = -ENOMEM; \ + } \ + \ + __ret; \ + }) + +static int configfs_parse_interface(const char *path, + struct uvc_function_config_interface *cfg) { + int ret; + + ret = attribute_read_uint(path, "bInterfaceNumber", &cfg->bInterfaceNumber); + + return ret; +} + +static int configfs_parse_control(const char *path, + struct uvc_function_config_control *cfg) { + int ret; + + ret = configfs_parse_interface(path, &cfg->intf); + + return ret; +} + +static int +configfs_parse_streaming_frame(const char *path, + struct uvc_function_config_frame *frame) { + char *intervals; + char *p; + int ret = 0; + + ret = ret ?: attribute_read_uint(path, "bFrameIndex", &frame->index); + ret = ret ?: attribute_read_uint(path, "wWidth", &frame->width); + ret = ret ?: attribute_read_uint(path, "wHeight", &frame->height); + if (ret) + return ret; + + intervals = attribute_read_str(path, "dwFrameInterval"); + if (!intervals) + return -EINVAL; + + for (p = intervals; *p;) { + unsigned int interval; + unsigned int *mem; + char *endp; + size_t size; + + interval = strtoul(p, &endp, 10); + if (*endp != '\0' && *endp != '\n') { + ret = -EINVAL; + break; + } + + p = *endp ? endp + 1 : endp; + + size = sizeof *frame->intervals * (frame->num_intervals + 1); + mem = realloc(frame->intervals, size); + if (!mem) { + ret = -ENOMEM; + break; + } + frame->intervals = mem; + frame->intervals[frame->num_intervals++] = interval; + } + free(intervals); + + return ret; +} + +static int frame_filter(const struct dirent *ent) { + /* Accept all directories but "." and "..". */ + if (ent->d_type != DT_DIR) + return 0; + if (!strcmp(ent->d_name, ".")) + return 0; + if (!strcmp(ent->d_name, "..")) + return 0; + return 1; +} + +static int frame_compare(const void *a, const void *b) { + const struct uvc_function_config_frame *fa = a; + const struct uvc_function_config_frame *fb = b; + + if (fa->index < fb->index) + return -1; + else if (fa->index == fb->index) + return 0; + else + return 1; +} + +static int +configfs_parse_streaming_format(const char *path, + struct uvc_function_config_format *format) { + struct dirent **entries; + char link_target[1024] = {0}; + char *segment; + unsigned int i; + int n_entries; + int ret; + + ret = attribute_read_uint(path, "bFormatIndex", &format->index); + if (ret < 0) + return ret; + + ret = readlink(path, link_target, sizeof(link_target) - 1); + if (ret < 0) + return ret; + + link_target[ret] = '\0'; + + /* + * Extract the second-to-last path component of the link target, + * which contains the format descriptor type name as exposed by + * the UVC function driver. + */ + segment = strrchr(link_target, '/'); + if (!segment) + return -EINVAL; + *segment = '\0'; + segment = strrchr(link_target, '/'); + if (!segment) + return -EINVAL; + segment++; + if (!strcmp(segment, "framebased")) { + ret = + attribute_read(path, "guidFormat", format->guid, sizeof(format->guid)); + } else if (!strcmp(segment, "mjpeg")) { + static const uint8_t guid[16] = UVC_GUID_FORMAT_MJPEG; + memcpy(format->guid, guid, 16); + } else if (!strcmp(segment, "uncompressed")) { + ret = + attribute_read(path, "guidFormat", format->guid, sizeof(format->guid)); + if (ret < 0) + return ret; + } else { + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(uvc_formats); ++i) { + if (!memcmp(uvc_formats[i].guid, format->guid, 16)) { + format->fcc = uvc_formats[i].fcc; + break; + } + } + + /* Find all entries corresponding to a frame and parse them. */ + n_entries = scandir(path, &entries, frame_filter, alphasort); + if (n_entries < 0) + return -errno; + + if (n_entries == 0) { + free(entries); + return -EINVAL; + } + + format->num_frames = n_entries; + format->frames = calloc(sizeof *format->frames, format->num_frames); + if (!format->frames) + return -ENOMEM; + + for (i = 0; i < (unsigned int)n_entries; ++i) { + char *frame; + + frame = path_join(path, entries[i]->d_name); + if (!frame) { + ret = -ENOMEM; + goto done; + } + + ret = configfs_parse_streaming_frame(frame, &format->frames[i]); + free(frame); + if (ret < 0) + goto done; + } + + /* Sort the frames by index. */ + qsort(format->frames, format->num_frames, sizeof *format->frames, + frame_compare); + +done: + for (i = 0; i < (unsigned int)n_entries; ++i) + free(entries[i]); + free(entries); + + return ret; +} + +static int format_filter(const struct dirent *ent) { + char *path; + bool valid; + + /* + * Accept all links that point to a directory containing a + * "bFormatIndex" file. + */ + if (ent->d_type != DT_LNK) + return 0; + + path = path_join(ent->d_name, "bFormatIndex"); + if (!path) + return 0; + + valid = access(path, R_OK); + free(path); + return valid; +} + +static int format_compare(const void *a, const void *b) { + const struct uvc_function_config_format *fa = a; + const struct uvc_function_config_format *fb = b; + + if (fa->index < fb->index) + return -1; + else if (fa->index == fb->index) + return 0; + else + return 1; +} + +static int +configfs_parse_streaming_header(const char *path, + struct uvc_function_config_streaming *cfg) { + struct dirent **entries; + unsigned int i; + int n_entries; + int ret; + + /* Find all entries corresponding to a format and parse them. */ + n_entries = scandir(path, &entries, format_filter, alphasort); + if (n_entries < 0) + return -errno; + + if (n_entries == 0) { + free(entries); + return -EINVAL; + } + + cfg->num_formats = n_entries; + cfg->formats = calloc(sizeof *cfg->formats, cfg->num_formats); + if (!cfg->formats) + return -ENOMEM; + + for (i = 0; i < (unsigned int)n_entries; ++i) { + char *format; + + format = path_join(path, entries[i]->d_name); + if (!format) { + ret = -ENOMEM; + goto done; + } + + ret = configfs_parse_streaming_format(format, &cfg->formats[i]); + free(format); + if (ret < 0) + goto done; + } + + /* Sort the formats by index. */ + qsort(cfg->formats, cfg->num_formats, sizeof *cfg->formats, format_compare); + +done: + for (i = 0; i < (unsigned int)n_entries; ++i) + free(entries[i]); + free(entries); + + return ret; +} + +static int link_filter(const struct dirent *ent) { + /* Accept all links. */ + return ent->d_type == DT_LNK; +} + +static int configfs_parse_streaming(const char *path, + struct uvc_function_config_streaming *cfg) { + char *header; + char *class; + int ret; + + ret = configfs_parse_interface(path, &cfg->intf); + if (ret < 0) + return ret; + /* + * Handle the high-speed class descriptors only for now. Find the first + * link to the class descriptors. + */ + class = path_join(path, "class/hs"); + if (!class) + return -ENOMEM; + + header = dir_first_match(class, link_filter); + free(class); + if (!header) + return -EINVAL; + + ret = configfs_parse_streaming_header(header, cfg); + free(header); + return ret; +} + +static int configfs_parse_uvc(const char *fpath, + struct uvc_function_config *fc) { + int ret = 0; + + ret = ret ?: configfs_parse_child(fpath, "control", &fc->control, + configfs_parse_control); + ret = ret ?: configfs_parse_child(fpath, "streaming", &fc->streaming, + configfs_parse_streaming); + + /* + * These parameters should be part of the streaming interface in + * ConfigFS, but for legacy reasons they are located directly in the + * function directory. + */ + ret = ret ?: attribute_read_uint(fpath, "streaming_interval", + &fc->streaming.ep.bInterval); + ret = ret ?: attribute_read_uint(fpath, "streaming_maxburst", + &fc->streaming.ep.bMaxBurst); + ret = ret ?: attribute_read_uint(fpath, "streaming_maxpacket", + &fc->streaming.ep.wMaxPacketSize); + + return ret; +} + +struct uvc_function_config *configfs_parse_uvc_function(unsigned int index) { + struct uvc_function_config *fc; + char *fpath; + char *function; + int ret = 0; + + fc = malloc(sizeof *fc); + if (fc == NULL) + return NULL; + + memset(fc, 0, sizeof *fc); + + /* Find the function in ConfigFS. */ + fpath = configfs_find_uvc_function(index); + if (!fpath) { + free(fc); + printf("[configfs_parse_uvc_function] configfs_find_uvc_function error!\n"); + return NULL; + } + + function = basename(fpath); + + fc->dev_name = attribute_read_str(fpath, "device_name"); + if (fc->dev_name == NULL) + fc->dev_name = "UVC CAMERA"; + fc->udc = attribute_read_str(fpath, "../../UDC"); + fc->video = udc_find_video_device(fc->udc, function); + printf("fc->dev_name:%s, fc->udc:%s, fc->video:%d \n", fc->dev_name, fc->udc, + fc->video); + if (fc->video < 0) { + ret = -ENODEV; + goto done; + } + fc->index = index; + + ret = configfs_parse_uvc(fpath, fc); + +done: + if (ret) { + configfs_free_uvc_function(fc); + printf("[configfs_parse_uvc_function] configfs_free_uvc_function\n"); + fc = NULL; + } + + free(fpath); + + return fc; +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_configfs.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_configfs.h new file mode 100644 index 000000000..324a12d41 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_configfs.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * ConfigFS Gadget device handling + * + * Copyright (C) 2020 Rockchip Electronics Co., Ltd. + * + */ + +#ifndef __UVC_CONFIGFS_H__ +#define __UVC_CONFIGFS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/* + * struct uvc_function_config_endpoint - Endpoint parameters + * @bInterval: Transfer interval (interrupt and isochronous only) + * @bMaxBurst: Transfer burst size (super-speed only) + * @wMaxPacketSize: Maximum packet size (including the multiplier) + */ +struct uvc_function_config_endpoint { + unsigned int bInterval; + unsigned int bMaxBurst; + unsigned int wMaxPacketSize; +}; + +/* + * struct uvc_function_config_interface - Interface parameters + * @bInterfaceNumber: Interface number + */ +struct uvc_function_config_interface { + unsigned int bInterfaceNumber; +}; + +/* + * struct uvc_function_config_control - Control interface parameters + * @intf: Generic interface parameters + */ +struct uvc_function_config_control { + struct uvc_function_config_interface intf; +}; + +/* + * struct uvc_function_config_frame - Streaming frame parameters + * @index: Frame index in the UVC descriptors + * @width: Frame width in pixels + * @height: Frame height in pixels + * @num_intervals: Number of entries in the intervals array + * @intervals: Array of frame intervals + */ +struct uvc_function_config_frame { + unsigned int index; + unsigned int width; + unsigned int height; + unsigned int num_intervals; + unsigned int *intervals; +}; + +/* + * struct uvc_function_config_format - Streaming format parameters + * @index: Format index in the UVC descriptors + * @guid: Format GUID + * @fcc: V4L2 pixel format + * @num_frames: Number of entries in the frames array + * @frames: Array of frame descriptors + */ +struct uvc_function_config_format { + unsigned int index; + uint8_t guid[16]; + unsigned int fcc; + unsigned int num_frames; + struct uvc_function_config_frame *frames; +}; + +/* + * struct uvc_function_config_streaming - Streaming interface parameters + * @intf: Generic interface parameters + * @ep: Endpoint parameters + * @num_formats: Number of entries in the formats array + * @formats: Array of format descriptors + */ +struct uvc_function_config_streaming { + struct uvc_function_config_interface intf; + struct uvc_function_config_endpoint ep; + + unsigned int num_formats; + struct uvc_function_config_format *formats; +}; + +/* + * struct uvc_function_config - UVC function configuration parameters + * @video: Full path to the video device node + * @udc: UDC name + * @control: Control interface configuration + * @streaming: Streaming interface configuration + */ +struct uvc_function_config { + int video; + int video_src; + unsigned int index; + char *udc; + char *dev_name; + + struct uvc_function_config_control control; + struct uvc_function_config_streaming streaming; +}; + +struct uvc_function_config *configfs_parse_uvc_function(unsigned int index); +void configfs_free_uvc_function(struct uvc_function_config *fc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_control.cpp b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_control.cpp new file mode 100644 index 000000000..e72944e43 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_control.cpp @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "uvc_control.h" +#include "camera_control.h" +#include "uevent.h" +#include "uvc-gadget.h" +#include "uvc_configfs.h" +#include "uvc_log.h" +#include "uvc_process_unit.h" +#include "uvc_video.h" +#include +#include +#include +#include +#include +#include +#include + +#define UVC_STREAMING_INTF_PATH \ + "/sys/kernel/config/usb_gadget/rockchip/functions/uvc.gs6/streaming/" \ + "bInterfaceNumber" + +#define UVC_STREAMING_MAXPACKET_PATH \ + "/sys/kernel/config/usb_gadget/rockchip/functions/uvc.gs6/" \ + "streaming_maxpacket" +int enable_minilog; +int rk_mpi_uvc_log_level; +int app_quit; +int uvc_ir_cnt; +int uvc_rgb_cnt; + +static int (*camera_start_callback)(int id, int width, int height, int fps, + int format, int eptz); +static void (*camera_stop_callback)(int id); +uvc_pu_control_callback_t uvc_pu_control_cb = NULL; + +struct uvc_ctrl { + int id; + bool start; + bool stop; + int width; + int height; + int fps; + int format; + int eptz; + int suspend; + struct uvc_function_config *fc; +}; + +static struct uvc_ctrl uvc_ctrl[CAM_MAX_NUM] = { + {.id = -1, .start = false, .stop = false, .width = -1, .height = -1, .fps = -1, .format = 1, .eptz = 0, .suspend = 0, .fc = NULL}, + {.id = -1, .start = false, .stop = false, .width = -1, .height = -1, .fps = -1, .format = 1, .eptz = 0, .suspend = 0, .fc = NULL}, + {.id = -1, .start = false, .stop = false, .width = -1, .height = -1, .fps = -1, .format = 1, .eptz = 0, .suspend = 0, .fc = NULL}, +}; + +static std::map gUVCIdCtlInfoMap; +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +static int uvc_streaming_intf = -1; +static int uvc_streaming_maxpacket = 1024; + +bool uvc_process_init_flag = false; +bool uvc_process_config_flag = false; + +static pthread_t run_id = 0; +static bool uvc_restart = false; +static bool run_flag = true; +static uint32_t uvc_flags = UVC_CONTROL_CAMERA; + +static pthread_mutex_t run_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t run_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t video_added = PTHREAD_COND_INITIALIZER; + +static int32_t g_suspend; + +static void query_uvc_streaming_maxpacket(void) { + int fd; + + fd = open(UVC_STREAMING_MAXPACKET_PATH, O_RDONLY); + if (fd >= 0) { + char intf[32] = {0}; + read(fd, intf, sizeof(intf) - 1); + uvc_streaming_maxpacket = atoi(intf); + if (uvc_streaming_maxpacket < 1023) + uvc_streaming_maxpacket = 1024; + LOG_DEBUG("uvc_streaming_maxpacket = %d\n", uvc_streaming_maxpacket); + close(fd); + } else { + LOG_ERROR("open %s failed!\n", UVC_STREAMING_MAXPACKET_PATH); + } +} + +int get_uvc_streaming_maxpacket(void) { return uvc_streaming_maxpacket; } + +static void query_uvc_streaming_intf(void) { + int fd; + + fd = open(UVC_STREAMING_INTF_PATH, O_RDONLY); + if (fd >= 0) { + char intf[32] = {0}; + read(fd, intf, sizeof(intf) - 1); + uvc_streaming_intf = atoi(intf); + LOG_DEBUG("uvc_streaming_intf = %d\n", uvc_streaming_intf); + close(fd); + } else { + LOG_ERROR("open %s failed!\n", UVC_STREAMING_INTF_PATH); + } +} + +void register_uvc_pu_control_callback(uvc_pu_control_callback_t cb) { + uvc_pu_control_cb = cb; +} + +void uvc_control_start_setcallback(int (*callback)(int fd, int width, + int height, int fps, + int format, int eptz)) { + camera_start_callback = callback; +} + +void uvc_control_stop_setcallback(void (*callback)(int fd)) { + camera_stop_callback = callback; +} + +static void get_uvc_index_to_name(unsigned int index, char *name) { + if (strstr(name, "depth") || strstr(name, "DEPTH") || strstr(name, "ir") || + strstr(name, "IR")) { + uvc_ir_cnt = index; + LOG_DEBUG("uvc_ir_cnt = %d, name:%s\n", uvc_ir_cnt, name); + } else if (strstr(name, "rgb") || strstr(name, "RGB")) { + uvc_rgb_cnt = index; + LOG_DEBUG("uvc_rgb_cnt = %d, name:%s\n", uvc_rgb_cnt, name); + } +} + +int check_uvc_video_id(void) { + bool find_dev = false; + struct uvc_function_config *fc[CAM_MAX_NUM] = {}; + for (uint32_t i = 0; i < CAM_MAX_NUM; i++) { + fc[i] = configfs_parse_uvc_function(i); + if (fc[i]) { + get_uvc_index_to_name(fc[i]->index, fc[i]->dev_name); + uvc_ctrl[i].id = fc[i]->video; + uvc_ctrl[i].fc = fc[i]; + find_dev = true; + LOG_DEBUG("uvc_function_config fc->video:%d,fc->streaming.num_formats:%d", + fc[i]->video, uvc_ctrl[i].fc->streaming.num_formats); + } + } + + if (false == find_dev) { + LOG_WARN("Please configure uvc...\n"); + return -1; + } + + return 0; +} + +void add_uvc_video() { + for (uint32_t i = 0; i < CAM_MAX_NUM; i++) { + if (uvc_ctrl[i].id >= 0) { + uvc_video_id_add(uvc_ctrl[i].fc); + LOG_INFO("uvc_ctrl:%u, id:%d, fc->video:%d\n",i , uvc_ctrl[i].id, uvc_ctrl[i].fc->video); + } + } +} + +int uvc_control_loop(void) { + if (uvc_restart) { + // uvc_video_id_exit_all(); + // add_uvc_video(); + uvc_restart = false; + return 0; + } + unsigned int i; + for (i = 0; i < CAM_MAX_NUM; i++) { + if (uvc_ctrl[i].stop) { + if (camera_stop_callback) + camera_stop_callback(i); + uvc_ctrl[i].stop = false; + } + + if (uvc_ctrl[i].start) { + LOG_INFO("%s: video_id:%d, width:%d,height:%d,fps:%d,format:%d,eptz:%d !\n", + __func__, uvc_ctrl[i].id, uvc_ctrl[i].width, uvc_ctrl[i].height, + uvc_ctrl[i].fps, uvc_ctrl[i].format, uvc_ctrl[i].eptz); + if (camera_start_callback) { + LOG_INFO("%s camera_start_callback start!\n", __func__); + camera_start_callback(i, uvc_ctrl[i].width, uvc_ctrl[i].height, + uvc_ctrl[i].fps, uvc_ctrl[i].format, + uvc_ctrl[i].eptz); + } + uvc_ctrl[i].start = false; + } + } + if (g_suspend) { + if (access("/tmp/uvc_no_suspend", 0)) { + sleep(5); + if (g_suspend) { + LOG_INFO("uvc ready to suspend...\n"); + g_suspend = 0; + system("touch /tmp/uvc_goto_suspend"); + } + } + } + return 1; +} + +int uvc_control_run(uint32_t flags) { + uvc_ir_cnt = -1; + uvc_rgb_cnt = -1; + uvc_flags = flags; + if ((flags & UVC_CONTROL_CHECK_STRAIGHT) || (flags & UVC_CONTROL_CAMERA)) { + if (!check_uvc_video_id()) { + add_uvc_video(); + } + } + + return 0; +} + +void set_uvc_control_suspend(int suspend) { + LOG_INFO("suspend is %d\n", suspend); + g_suspend = suspend; + if ((suspend == 0) && !access("/tmp/uvc_goto_suspend", 0)) + system("rm /tmp/uvc_goto_suspend"); +} + +// TODO: use video id start uvc_ctrl +void set_uvc_control_start(int video_id, int width, int height, int fps, + int format, int eptz) { + LOG_DEBUG("%s: video_id:%d\n", __func__, video_id); + for (int i = 0; i < CAM_MAX_NUM; i++) { + if (uvc_ctrl[i].id == video_id) { + LOG_DEBUG("%s: camera:%d, video_id:%d, width:%d,height:%d,fps:%d,eptz:%d!\n", + __func__, i, video_id, width, height, fps, eptz); + uvc_ctrl[i].id = video_id; + uvc_ctrl[i].width = width; + uvc_ctrl[i].height = height; + uvc_ctrl[i].fps = fps; + uvc_ctrl[i].format = format; + uvc_ctrl[i].start = true; + uvc_ctrl[i].eptz = eptz; + } + } +} + +// TODO: use video id stop uvc_ctrl +void set_uvc_control_stop(int video_id) { + LOG_INFO("%s:video_id:%d\n", __func__, video_id); + for (int i = 0; i < CAM_MAX_NUM; i++) { + if (uvc_ctrl[i].id == video_id) + uvc_ctrl[i].stop = true; + } +} + +void set_uvc_control_restart(void) { + if (uvc_flags & UVC_CONTROL_CAMERA) { + LOG_INFO("received uvc to exit,restart to recovery now!\n"); + // system("killall -9 uvc_app &"); + uvc_restart = true; + } +} + +UVC_CTRL_INFO uvc_find_uvc_ctrl_info_by_id(int id) { + for (std::map::iterator iter = gUVCIdCtlInfoMap.begin(); + iter != gUVCIdCtlInfoMap.end(); ++iter) { + if (iter->first == id) { + LOG_DEBUG("index:%d find uvc_enc:%p by id:%d\n", iter->second.index, + &iter->second, id); + // iter->second.index = index; + return iter->second; + } + } + UVC_CTRL_INFO uvc_ctrl_info; + for (int i = 0; i < CAM_MAX_NUM; i++) { + if (uvc_ctrl[i].id == id) + uvc_ctrl_info.index = i; + } + // uvc_ctrl_info.index = gUVCIdCtlInfoMap.size(); + gUVCIdCtlInfoMap.insert(std::map::value_type(id, uvc_ctrl_info)); + + LOG_INFO("index:%d new uvc_ctrl_info:%p by id:%d\n", uvc_ctrl_info.index, + &uvc_ctrl_info, id); + + return uvc_ctrl_info; +} + +void uvc_control_config(struct uvc_device *dev) { + pthread_mutex_lock(&lock); + UVC_CTRL_INFO uvc_ctrl_info = uvc_find_uvc_ctrl_info_by_id(dev->video_id); + uvc_ctrl_info.width = dev->width; + uvc_ctrl_info.height = dev->height; + uvc_ctrl_info.fcc = dev->fcc; + uvc_ctrl_info.fps = dev->fps; + uvc_ctrl_info.eptz[UVC_EPTZ_AUTO] = dev->eptz_flag; // read by cfg + uvc_ctrl_info.video_id = dev->video_id; + uvc_ctrl_info.eptz[UVC_EPTZ_ZOOM] = 10; + uvc_ctrl_info.eptz[UVC_EPTZ_PAN] = 0; + uvc_ctrl_info.eptz[UVC_EPTZ_TILT] = 0; + // camera_control_set_rate(uvc_ctrl_info.index, dev->fps); + dev->nbufs = uvc_process_config(uvc_ctrl_info); + if (dev->nbufs <= 0) { + LOG_ERROR("%s fail!\n", __func__); + abort(); + } + LOG_INFO("uvc_enc->video_id:%d dev->nbufs:%d\n", uvc_ctrl_info.video_id, + dev->nbufs); + uvc_process_init_flag = true; + uvc_process_config_flag = true; + pthread_mutex_unlock(&lock); +} + +void uvc_control_streamon(struct uvc_device *dev) { + pthread_mutex_lock(&lock); + UVC_CTRL_INFO uvc_ctrl_info = uvc_find_uvc_ctrl_info_by_id(dev->video_id); + uvc_ctrl_info.width = dev->width; + uvc_ctrl_info.height = dev->height; + uvc_ctrl_info.fcc = dev->fcc; + uvc_ctrl_info.fps = dev->fps; + uvc_ctrl_info.eptz[UVC_EPTZ_AUTO] = dev->eptz_flag; + uvc_ctrl_info.video_id = dev->video_id; + // uvc_ctrl_info->zoom = dev->zoom_val; // init have not zoom info + if (uvc_process_start(uvc_ctrl_info)) { + LOG_ERROR("%s fail!\n", __func__); + abort(); + } + LOG_INFO("uvc_enc->video_id:%d", uvc_ctrl_info.video_id); + uvc_process_init_flag = true; + pthread_mutex_unlock(&lock); +} + +void uvc_control_inbuf_deinit() { + pthread_mutex_lock(&lock); + // if(uvc_process_init_flag) + // uvc_encode_inbuf_deinit(&uvc_enc); + pthread_mutex_unlock(&lock); +} + +void uvc_control_streamoff(int video_id) { + pthread_mutex_lock(&lock); + if (uvc_process_init_flag) { + UVC_CTRL_INFO uvc_ctrl_info = uvc_find_uvc_ctrl_info_by_id(video_id); + uvc_process_stop(uvc_ctrl_info); + } + uvc_process_init_flag = false; + pthread_mutex_unlock(&lock); +} + +void uvc_control_delete(int video_id) { + pthread_mutex_lock(&lock); + if (uvc_process_config_flag) { + UVC_CTRL_INFO uvc_ctrl_info = uvc_find_uvc_ctrl_info_by_id(video_id); + uvc_process_delete(uvc_ctrl_info); + } + uvc_process_config_flag = false; + pthread_mutex_unlock(&lock); +} + +void uvc_control_release_frame_nonlock(struct uvc_device *dev, void *frame) { + int ret = 0; + + UVC_CTRL_INFO uvc_ctrl_info = uvc_find_uvc_ctrl_info_by_id(dev->video_id); + ret = uvc_process_release_frame(uvc_ctrl_info, frame); + if (ret < 0) { + LOG_ERROR("%s fail: %d!\n", __func__, ret); + abort(); + } +} + +void uvc_control_release_frame(struct uvc_device *dev, void *frame) { + pthread_mutex_lock(&lock); + uvc_control_release_frame_nonlock(dev, frame); + pthread_mutex_unlock(&lock); +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_control.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_control.h new file mode 100755 index 000000000..763b10a0d --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_control.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __UVC_CONTROL_H__ +#define __UVC_CONTROL_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "uvc_process_unit.h" +#include + +#ifdef USE_RK_MODULE +#define ISP_SEQ 1 +#define ISP_FMT HAL_FRMAE_FMT_NV12 +#define CIF_SEQ 0 +#define CIF_FMT HAL_FRMAE_FMT_SBGGR10 +#else +#define ISP_SEQ 0 +#define ISP_FMT HAL_FRMAE_FMT_SBGGR8 +#define CIF_SEQ 1 +#define CIF_FMT HAL_FRMAE_FMT_NV12 +#endif + +#define UVC_CONTROL_LOOP_ONCE (1 << 0) +#define UVC_CONTROL_CHECK_STRAIGHT (1 << 1) +#define UVC_CONTROL_CAMERA (1 << 2) + +extern int app_quit; + +typedef void (*uvc_pu_control_callback_t)(unsigned char cs, unsigned int val); +void register_uvc_pu_control_callback(uvc_pu_control_callback_t cb); +extern uvc_pu_control_callback_t uvc_pu_control_cb; + +void add_uvc_video(); +int uvc_control_loop(void); +int check_uvc_video_id(void); +void set_uvc_control_start(int video_id, int width, int height, int fps, + int format, int eptz); +void set_uvc_control_stop(int video_id); +void set_uvc_control_restart(void); +void uvc_control_start_setcallback(int (*callback)(int id, int width, + int height, int fps, + int format, int eptz)); +void uvc_control_stop_setcallback(void (*callback)(int id)); +void uvc_control_config(struct uvc_device *dev); +void uvc_control_streamon(struct uvc_device *dev); +void uvc_control_streamoff(int video_id); +void uvc_control_delete(int video_id); +void uvc_control_inbuf_deinit(); +int uvc_control_run(uint32_t flags); +void set_uvc_control_suspend(int suspend); +void uvc_control_release_frame(struct uvc_device *dev, void *frame); +void uvc_control_release_frame_nonlock(struct uvc_device *dev, void *frame); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_ipc_ext.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_ipc_ext.h new file mode 100644 index 000000000..d9967c48e --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_ipc_ext.h @@ -0,0 +1,52 @@ +#ifndef __UVC_IPC_EXT_H__ +#define __UVC_IPC_EXT_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#if DBUG +#define UVC_DYNAMIC_DEBUG_USE_TIME 1 // release version can set to 0 +#define UVC_DYNAMIC_DEBUG_USE_TIME_CHECK "/tmp/uvc_use_time" +#else +#define UVC_DYNAMIC_DEBUG_USE_TIME 0 +#endif + +enum UVC_IPC_EVENT { + UVC_IPC_EVENT_START = 1, + UVC_IPC_EVENT_STOP = 2, + UVC_IPC_EVENT_ENABLE_ETPTZ = 3, + UVC_IPC_EVENT_SET_ZOOM = 4, + UVC_IPC_EVENT_RET_TRANSPORT_BUF = 5, + UVC_IPC_EVENT_CONFIG_CAMERA = 6, + UVC_IPC_EVENT_SET_EPTZ_PAN = 7, + UVC_IPC_EVENT_SET_EPTZ_TILT = 8, + UVC_IPC_EVENT_ENABLE_BYPASS = 9 +}; + +enum UVC_IPC_ENC_TYPE { + UVC_IPC_ENC_YUV = 0, + UVC_IPC_ENC_MJPEG_NORMAL, + UVC_IPC_ENC_MJPEG_LOW_LATENCY, + UVC_IPC_ENC_H264, + UVC_IPC_ENC_H265 +}; + +struct CAMERA_INFO { + int width; + int height; + int vir_width; + int vir_height; + int buf_size; + int range; + enum UVC_IPC_ENC_TYPE encode_type; + int uvc_fps_set; +}; + +extern void uvc_ipc_event(enum UVC_IPC_EVENT event, void *data); +extern void uvc_ipc_reconnect(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_log.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_log.h new file mode 100644 index 000000000..d6984d081 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_log.h @@ -0,0 +1,91 @@ +// Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef _RK_LOGGER_H_ +#define _RK_LOGGER_H_ + +#ifdef ENABLE_MINILOGGER +#include "minilogger/log.h" +#else +#include +#include +#include +#define minilog_warn(...) +#define minilog_error(...) +#define minilog_info(...) +#define minilog_debug(...) +#define __minilog_log_init(...) +#endif + +extern int enable_minilog; +extern int rk_mpi_uvc_log_level; + +#define LOG_LEVEL_ERROR 0 +#define LOG_LEVEL_WARN 1 +#define LOG_LEVEL_INFO 2 +#define LOG_LEVEL_DEBUG 3 + +#ifndef LOG_TAG +#define LOG_TAG "rk_mpi_uvc" +#endif // LOG_TAG + +//#define ENABLE_BUFFER_TIME_DEBUG + +#define LOG_INFO(format, ...) \ + do { \ + if (rk_mpi_uvc_log_level < LOG_LEVEL_INFO) \ + break; \ + if (enable_minilog) \ + minilog_info("[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \ + else { \ + struct timeval tv; \ + gettimeofday(&tv, NULL); \ + fprintf(stderr, "[%d.%06d][%s][%s][%d]:" format, tv.tv_sec, tv.tv_usec, \ + LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ + } while (0) + +#define LOG_WARN(format, ...) \ + do { \ + if (rk_mpi_uvc_log_level < LOG_LEVEL_WARN) \ + break; \ + if (enable_minilog) \ + minilog_warn("[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \ + else { \ + struct timeval tv; \ + gettimeofday(&tv, NULL); \ + fprintf(stderr, "[%d.%06d][%s][%s][%d]:" format, tv.tv_sec, tv.tv_usec, \ + LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ + } while (0) + +#define LOG_ERROR(format, ...) \ + do { \ + if (rk_mpi_uvc_log_level < LOG_LEVEL_ERROR) \ + break; \ + if (enable_minilog) \ + minilog_error("[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \ + else { \ + struct timeval tv; \ + gettimeofday(&tv, NULL); \ + fprintf(stderr, "[%d.%06d][%s][%s][%d]:" format, tv.tv_sec, tv.tv_usec, \ + LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ + } while (0) + +#define LOG_DEBUG(format, ...) \ + do { \ + if (rk_mpi_uvc_log_level < LOG_LEVEL_DEBUG) \ + break; \ + if (enable_minilog) \ + minilog_debug("[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \ + else { \ + struct timeval tv; \ + gettimeofday(&tv, NULL); \ + fprintf(stderr, "[%d.%06d][%s][%s][%d]:" format, tv.tv_sec, tv.tv_usec, \ + LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ + } while (0) + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_config.c b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_config.c new file mode 100755 index 000000000..e16a7b6f4 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_config.c @@ -0,0 +1,1638 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "uvc_mpi_config.h" +#include "cJSON.h" +#include "rk_mpi_sys.h" +#include "uvc_log.h" +#include "uvc_mpi_vi.h" +#include "uvc_video.h" +#include +#include +#include +#include +#include +#include + +#define UVC_MPI_CFG_DEBUG_FILE_NAME "/data/uvc.bin" +#define UVC_MPI_CFG_NN_DEBUG_FILE_NAME "/data/nn.bin" +#define UVC_MPI_CFG_ORIGINAL_PATH "/oem/usr/share/uvc_mpi_cfg.conf" +#define UVC_MPI_CFG_MODIFY_PATH "/oem/usr/share//uvc_mpi_cfg.conf" +#define UVC_MPI_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) + +#define UVC_FIND_ENTRY_VALUE_BY_STRCMP(INPUT, MAP, KEY, VALUE) \ + if (INPUT) { \ + for (size_t i = 0; i < UVC_MPI_ARRAY_ELEMS(MAP); i++) { \ + if (!strcmp(INPUT, MAP[i].KEY)) \ + return MAP[i].VALUE; \ + } \ + } + +static void copy_str_to_array(char *dst, char *src, int dst_len) { + memset(dst, 0, dst_len); + memcpy(dst, src, strlen(src)); +} + +static unsigned long get_file_size(const char *filename) { + struct stat buf; + if (stat(filename, &buf) < 0) + return 0; + + return (unsigned long)buf.st_size; +} + +typedef struct _RkFormatNameMap { + PIXEL_FORMAT_E format; + const char *name; +} RkFormatNameMap; + +const static RkFormatNameMap sRkFormatNames[] = { + {RK_FMT_YUV420SP, "nv12"}, {RK_FMT_YUV420SP_VU, "nv21"}, + {RK_FMT_YUV422_YUYV, "yuv422yuyv"}, {RK_FMT_YUV422_UYVY, "yuv422uyvy"}, + {RK_FMT_RGB888, "rgb888"}, {RK_FMT_BGR888, "bgr888"}, + {RK_FMT_ARGB8888, "argb8888"}, {RK_FMT_BGRA8888, "bgra8888"}, +}; + +int pix_format_rt_string_to_gl(const char *stFormat) { + UVC_FIND_ENTRY_VALUE_BY_STRCMP(stFormat, sRkFormatNames, name, format); + return RK_FMT_YUV420SP; +} + +static cJSON *parse_find_uvc_index_cfg(cJSON *root, int index, bool init) { + int ret = 0; + char index_node[10] = {0}; + sprintf(index_node, "index_%d", index); + + cJSON *child = cJSON_GetObjectItem(root, index_node); + if (!child) { + LOG_ERROR("find %s fail\n", index_node); + return NULL; + } + + return child; +} + +static int parse_check_uvc_common_cfg(cJSON *root, UVC_MPI_CFG *mpiCfg, + bool init) { + int ret = 0; + + MpiUvcCommonCfg *commonCfg = &mpiCfg->common_cfg; + if (NULL == commonCfg) + return -1; + + commonCfg->change = 0; + cJSON *child = cJSON_GetObjectItem(root, "common_cfg"); + if (!child) { + LOG_ERROR("parse common_cfg err\n"); + return -1; + } + cJSON *child_version = cJSON_GetObjectItem(child, "version"); + if (child_version) { + LOG_DEBUG("parse common version:%d\n", child_version->valueint); + commonCfg->version = child_version->valueint; + } + + cJSON *child_property = cJSON_GetObjectItem(child, "property"); + if (!child_property) { + LOG_ERROR("parse common property err\n"); + return -1; + } else { + cJSON *child_property_param = NULL; + if (init) + child_property_param = cJSON_GetObjectItem(child_property, "param_init"); + else + child_property_param = + cJSON_GetObjectItem(child_property, "param_change"); + if (child_property_param) { + cJSON *child_item = cJSON_GetObjectItem(child_property_param, + "check_param_change_thread"); + if (child_item) { + commonCfg->need_check = strstr(child_item->valuestring, "on") ? 1 : 0; + commonCfg->change |= MPI_UVC_COMMON_CFG_NEED_CHECK; + } + child_item = cJSON_GetObjectItem(child_property_param, "uvc_debug"); + if (child_item) { + commonCfg->uvc_debug = strstr(child_item->valuestring, "on") ? 1 : 0; + commonCfg->change |= MPI_UVC_COMMON_CFG_UVC_DEBUG; + } + child_item = cJSON_GetObjectItem(child_property_param, "yuyv_debug"); + if (child_item) { + commonCfg->yuyv_debug = strstr(child_item->valuestring, "on") ? 1 : 0; + commonCfg->change |= MPI_UVC_COMMON_CFG_UVC_YUYV_DEBUG; + } + child_item = cJSON_GetObjectItem(child_property_param, "nn_enable"); + if (child_item) { + commonCfg->nn_enable = strstr(child_item->valuestring, "on") ? 1 : 0; + commonCfg->change |= MPI_UVC_COMMON_CFG_UVC_NN_ENABLE; + } + child_item = + cJSON_GetObjectItem(child_property_param, "uvc_debug_file_name"); + if (child_item) { + copy_str_to_array(commonCfg->uvc_debug_file, child_item->valuestring, + UVC_MPI_STREAM_SAVE_FILE_LEN); + commonCfg->change |= MPI_UVC_COMMON_CFG_UVC_DEBUG_FILE_NAME; + } + child_item = + cJSON_GetObjectItem(child_property_param, "uvc_debug_file_cnt"); + if (child_item) { + commonCfg->uvc_debug_cnt = child_item->valueint; + commonCfg->change |= MPI_UVC_COMMON_CFG_UVC_DEBUG_FILE_CNT; + } + child_item = + cJSON_GetObjectItem(child_property_param, "nn_debug_file_name"); + if (child_item) { + copy_str_to_array(commonCfg->nn_debug_file, child_item->valuestring, + UVC_MPI_STREAM_SAVE_FILE_LEN); + commonCfg->change |= MPI_UVC_COMMON_CFG_NN_DEBUG_FILE_NAME; + } + child_item = + cJSON_GetObjectItem(child_property_param, "nn_debug_file_cnt"); + if (child_item) { + commonCfg->nn_debug_cnt = child_item->valueint; + commonCfg->change |= MPI_UVC_COMMON_CFG_NN_DEBUG_FILE_CNT; + } + child_item = + cJSON_GetObjectItem(child_property_param, "geometric_output"); + if (child_item) { + RK_S32 cnt = 0; + cnt = sscanf(child_item->valuestring, "%d:%d", + &commonCfg->geometric_output_num, + &commonCfg->geometric_output_den); + if (!cnt) { + LOG_ERROR("invalid set geometric_output num:den,such as 16:9\n"); + } else { + commonCfg->change |= MPI_UVC_COMMON_CFG_GEOMETRIC_OUT; + } + } + child_item = cJSON_GetObjectItem(child_property_param, "uvc_enable_vpss"); + if (child_item) { + commonCfg->uvc_enable_vpss = + strstr(child_item->valuestring, "on") ? 1 : 0; + commonCfg->change |= MPI_UVC_COMMON_CFG_UVC_ENABLE_VPSS; + } + LOG_INFO("uvc common change:0x%x\n", commonCfg->change); + } + } + + return ret; +} + +static int parse_check_uvc_mpi_vi_cfg(cJSON *root, UVC_MPI_CFG *mpiCfg, + bool init) { + int ret = 0; + int version; + MpiViCfg *mpiViCfg = NULL; + cJSON *child_property = NULL; + + cJSON *child = cJSON_GetObjectItem(root, "vi_cfg"); + if (!child) { + LOG_ERROR("parse vi_cfg err\n"); + return -1; + } + cJSON *child_version = cJSON_GetObjectItem(child, "version"); + if (child_version) { + LOG_DEBUG("parse vi version:%d\n", child_version->valueint); + version = child_version->valueint; + } + + for (int chnType = MPI_VI_CHANNEL_TYPE_UVC; chnType < MPI_VI_CHANNEL_TYPE_MAX; + chnType++) { + mpiViCfg = &mpiCfg->vi_cfg[chnType]; + if (NULL == mpiViCfg) + return -1; + mpiViCfg->version = version; + mpiViCfg->change = 0; + switch (chnType) { + case MPI_VI_CHANNEL_TYPE_UVC: + child_property = cJSON_GetObjectItem(child, "uvc"); + break; + case MPI_VI_CHANNEL_TYPE_NN: + child_property = cJSON_GetObjectItem(child, "nn"); + break; + default: + LOG_ERROR("no support this chnType:%d\n", chnType); + child_property = NULL; + break; + } + + if (!child_property) { + LOG_ERROR("parse vi property err\n"); + return -1; + } else { + cJSON *child_property_param = NULL; + if (init) + child_property_param = + cJSON_GetObjectItem(child_property, "param_init"); + else + child_property_param = + cJSON_GetObjectItem(child_property, "param_change"); + if (child_property_param) { + cJSON *child_item = cJSON_GetObjectItem(child_property_param, "dev_id"); + if (child_item) { + mpiViCfg->dev_id = child_item->valueint; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_DEV_ID; + } + child_item = cJSON_GetObjectItem(child_property_param, "channel_id"); + if (child_item) { + mpiViCfg->channel_id = child_item->valueint; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_CHANNEL_ID; + } + child_item = cJSON_GetObjectItem(child_property_param, "buf_cnt"); + if (child_item) { + mpiViCfg->buf_cnt = child_item->valueint; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_BUF_CNT; + } + child_item = cJSON_GetObjectItem(child_property_param, "memory_type"); + if (child_item) { + switch (child_item->valueint) { + case 1: + mpiViCfg->memory_type = VI_V4L2_MEMORY_TYPE_MMAP; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MEMORY_TYPE; + break; + case 2: + mpiViCfg->memory_type = VI_V4L2_MEMORY_TYPE_USERPTR; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MEMORY_TYPE; + break; + case 3: + mpiViCfg->memory_type = VI_V4L2_MEMORY_TYPE_OVERLAY; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MEMORY_TYPE; + break; + case 4: + mpiViCfg->memory_type = VI_V4L2_MEMORY_TYPE_DMABUF; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MEMORY_TYPE; + break; + default: + LOG_WARN("memory_type:%d not support\n", child_item->valueint); + mpiViCfg->memory_type = VI_V4L2_MEMORY_TYPE_DMABUF; + break; + } + } + child_item = cJSON_GetObjectItem(child_property_param, "fbc"); + if (child_item) { + mpiViCfg->fbc = strstr(child_item->valuestring, "on") + ? COMPRESS_AFBC_16x16 + : COMPRESS_MODE_NONE; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_FBC; + } + child_item = cJSON_GetObjectItem(child_property_param, "fps"); + if (child_item) { + RK_S32 cnt = 0; + cnt = sscanf(child_item->valuestring, "%d:%d", &mpiViCfg->fps_in, + &mpiViCfg->fps_out); + if (!cnt) { + LOG_ERROR("invalid set vi fps in:out,such as 30:25\n"); + } else { + mpiViCfg->change |= MPI_VI_CFG_CHANGE_FPS; + } + } + child_item = cJSON_GetObjectItem(child_property_param, "rotation"); + if (child_item) { + switch (child_item->valueint) { + case 0: + mpiViCfg->rotation = ROTATION_0; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_ROTATION; + break; + case 90: + mpiViCfg->rotation = ROTATION_90; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_ROTATION; + break; + case 180: + mpiViCfg->rotation = ROTATION_180; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_ROTATION; + break; + case 270: + mpiViCfg->rotation = ROTATION_270; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_ROTATION; + break; + default: + LOG_WARN("rotation:%d not support\n", child_item->valueint); + mpiViCfg->rotation = ROTATION_0; + break; + } + } + child_item = cJSON_GetObjectItem(child_property_param, "mirror"); + if (child_item) { + switch (child_item->valueint) { + case 0: + mpiViCfg->mirror = MIRROR_NONE; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MIRROR; + break; + case 1: + mpiViCfg->mirror = MIRROR_HORIZONTAL; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MIRROR; + break; + case 2: + mpiViCfg->mirror = MIRROR_VERTICAL; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MIRROR; + break; + case 3: + mpiViCfg->mirror = MIRROR_BOTH; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MIRROR; + break; + default: + LOG_WARN("mirror:%d not support\n", child_item->valueint); + mpiViCfg->mirror = MIRROR_NONE; + break; + } + } + child_item = cJSON_GetObjectItem(child_property_param, "dev_name"); + if (child_item) { + copy_str_to_array(mpiViCfg->dev_name, child_item->valuestring, + MAX_VI_ENTITY_NAME_LEN); + mpiViCfg->change |= MPI_VI_CFG_CHANGE_DEV_NAME; + } + child_item = cJSON_GetObjectItem(child_property_param, "assign_width"); + if (child_item) { + mpiViCfg->assign_width = child_item->valueint; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_ASSIGN_WIDTH; + } + child_item = cJSON_GetObjectItem(child_property_param, "assign_height"); + if (child_item) { + mpiViCfg->assign_height = child_item->valueint; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_ASSIGN_HEIGHT; + } + child_item = cJSON_GetObjectItem(child_property_param, "min_width"); + if (child_item) { + mpiViCfg->min_width = child_item->valueint; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MIN_WIDTH; + } + child_item = cJSON_GetObjectItem(child_property_param, "min_height"); + if (child_item) { + mpiViCfg->min_height = child_item->valueint; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MIN_HEIGHT; + } + child_item = cJSON_GetObjectItem(child_property_param, "max_width"); + if (child_item) { + mpiViCfg->max_width = child_item->valueint; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MAX_WIDTH; + } + child_item = cJSON_GetObjectItem(child_property_param, "max_height"); + if (child_item) { + mpiViCfg->max_height = child_item->valueint; + mpiViCfg->change |= MPI_VI_CFG_CHANGE_MAX_HEIGHT; + } + child_item = cJSON_GetObjectItem(child_property_param, "format"); + if (child_item) { + mpiViCfg->format = + pix_format_rt_string_to_gl(child_item->valuestring); + mpiViCfg->change |= MPI_VI_CFG_CHANGE_FORMAT; + LOG_INFO("mpiViCfg[%d]->format:0x%x\n", chnType, mpiViCfg->format); + } + LOG_INFO("vi_cfg[%d] change:0x%x\n", chnType, mpiViCfg->change); + } else { + LOG_WARN("no find vi_cfg[%d] param_init or param_change\n", chnType); + } + } + } + + return ret; +} + +static int parse_check_uvc_mpi_vpss_cfg(cJSON *root, UVC_MPI_CFG *mpiCfg, + bool init) { + int ret = 0; + int version; + MpiVpssCfg *mpiVpssCfg = NULL; + cJSON *child_property = NULL; + + cJSON *child = cJSON_GetObjectItem(root, "vpss_cfg"); + if (!child) { + LOG_ERROR("parse vpss_cfg err\n"); + return -1; + } + cJSON *child_version = cJSON_GetObjectItem(child, "version"); + if (child_version) { + LOG_DEBUG("parse vi version:%d\n", child_version->valueint); + version = child_version->valueint; + } + + for (int chnType = MPI_VPSS_CHANNEL_TYPE_UVC; + chnType < MPI_VPSS_CHANNEL_TYPE_MAX; chnType++) { + mpiVpssCfg = &mpiCfg->vpss_cfg[chnType]; + if (NULL == mpiVpssCfg) + return -1; + mpiVpssCfg->version = version; + mpiVpssCfg->change = 0; + switch (chnType) { + case MPI_VPSS_CHANNEL_TYPE_UVC: + child_property = cJSON_GetObjectItem(child, "uvc"); + break; + case MPI_VPSS_CHANNEL_TYPE_NN: + child_property = cJSON_GetObjectItem(child, "nn"); + break; + default: + LOG_ERROR("no support this chnType:%d\n", chnType); + child_property = NULL; + break; + } + + for (int chn = 0; chn < 1; chn++) { + if (!child_property) { + LOG_ERROR("parse vpss property err\n"); + return -1; + } else { + cJSON *child_property_param = NULL; + if (init) + child_property_param = + cJSON_GetObjectItem(child_property, "param_init"); + else + child_property_param = + cJSON_GetObjectItem(child_property, "param_change"); + if (child_property_param) { + cJSON *child_item = + cJSON_GetObjectItem(child_property_param, "group_id"); + if (child_item) { + mpiVpssCfg->group_id = child_item->valueint; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_GROUP_ID; + } + child_item = cJSON_GetObjectItem(child_property_param, "channel_id"); + if (child_item) { + mpiVpssCfg->channel_id = child_item->valueint; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_CHANNEL_ID; + } + child_item = cJSON_GetObjectItem(child_property_param, "buf_cnt"); + if (child_item) { + mpiVpssCfg->buf_cnt = child_item->valueint; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_BUF_CNT; + } + child_item = cJSON_GetObjectItem(child_property_param, "fbc"); + if (child_item) { + mpiVpssCfg->fbc = strstr(child_item->valuestring, "on") + ? COMPRESS_AFBC_16x16 + : COMPRESS_MODE_NONE; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_FBC; + } + child_item = cJSON_GetObjectItem(child_property_param, "fps"); + if (child_item) { + RK_S32 cnt = 0; + cnt = sscanf(child_item->valuestring, "%d:%d", &mpiVpssCfg->fps_in, + &mpiVpssCfg->fps_out); + if (!cnt) { + LOG_ERROR("invalid set vpss fps in:out,such as 30:25\n"); + } else { + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_FPS; + } + } + child_item = cJSON_GetObjectItem(child_property_param, "format"); + if (child_item) { + mpiVpssCfg->format = + pix_format_rt_string_to_gl(child_item->valuestring); + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_FORMAT; + LOG_INFO("mpiVpssCfg[%d]->format:0x%x\n", chnType, + mpiVpssCfg->format); + } + child_item = + cJSON_GetObjectItem(child_property_param, "assign_width"); + if (child_item) { + mpiVpssCfg->assign_width = child_item->valueint; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_ASSIGN_WIDTH; + } + child_item = + cJSON_GetObjectItem(child_property_param, "assign_height"); + if (child_item) { + mpiVpssCfg->assign_height = child_item->valueint; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_ASSIGN_HEIGHT; + } + child_item = cJSON_GetObjectItem(child_property_param, "rotation"); + if (child_item) { + switch (child_item->valueint) { + case 0: + mpiVpssCfg->rotation = ROTATION_0; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_ROTATION; + break; + case 90: + mpiVpssCfg->rotation = ROTATION_90; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_ROTATION; + break; + case 180: + mpiVpssCfg->rotation = ROTATION_180; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_ROTATION; + break; + case 270: + mpiVpssCfg->rotation = ROTATION_270; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_ROTATION; + break; + default: + LOG_WARN("rotation:%d not support\n", child_item->valueint); + mpiVpssCfg->rotation = ROTATION_0; + break; + } + } + child_item = cJSON_GetObjectItem(child_property_param, "mirror"); + if (child_item) { + switch (child_item->valueint) { + case 0: + mpiVpssCfg->mirror = MIRROR_NONE; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_MIRROR; + break; + case 1: + mpiVpssCfg->mirror = MIRROR_HORIZONTAL; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_MIRROR; + break; + case 2: + mpiVpssCfg->mirror = MIRROR_VERTICAL; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_MIRROR; + break; + case 3: + mpiVpssCfg->mirror = MIRROR_BOTH; + mpiVpssCfg->change |= MPI_VPSS_CFG_CHANGE_MIRROR; + break; + default: + LOG_WARN("mirror:%d not support\n", child_item->valueint); + mpiVpssCfg->mirror = MIRROR_NONE; + break; + } + } + LOG_INFO("vpss_cfg change:0x%x\n", mpiVpssCfg->change); + } else { + LOG_WARN("no find vpss_cfg param_init or param_change\n"); + } + } + } + } + + return ret; +} + +static int parse_check_uvc_mpi_venc_common_cfg(cJSON *root, UVC_MPI_CFG *mpiCfg, + bool init) { + int ret = 0; + + MpiVencCommonCfg *mpiVencCommonCfg = &mpiCfg->venc_cfg.common_cfg; + if (NULL == mpiVencCommonCfg) + return -1; + + mpiVencCommonCfg->change = 0; + cJSON *child_common = cJSON_GetObjectItem(root, "common"); + if (!child_common) { + LOG_ERROR("parse venc_cfg common err\n"); + return -1; + } else { + cJSON *child_common_param = NULL; + if (init) { + child_common_param = cJSON_GetObjectItem(child_common, "param_init"); + mpiVencCommonCfg->change |= MPI_VENC_COMMON_CFG_CHANGE_CREATE; + } else { + child_common_param = cJSON_GetObjectItem(child_common, "param_change"); + } + if (child_common_param) { + cJSON *child_item = cJSON_GetObjectItem(child_common_param, "rotation"); + if (child_item) { + switch (child_item->valueint) { + case 0: + mpiVencCommonCfg->rotation = ROTATION_0; + mpiVencCommonCfg->change |= MPI_VENC_COMMON_CFG_CHANGE_ROTATION; + break; + case 90: + mpiVencCommonCfg->rotation = ROTATION_90; + mpiVencCommonCfg->change |= MPI_VENC_COMMON_CFG_CHANGE_ROTATION; + break; + case 180: + mpiVencCommonCfg->rotation = ROTATION_180; + mpiVencCommonCfg->change |= MPI_VENC_COMMON_CFG_CHANGE_ROTATION; + break; + case 270: + mpiVencCommonCfg->rotation = ROTATION_270; + mpiVencCommonCfg->change |= MPI_VENC_COMMON_CFG_CHANGE_ROTATION; + break; + default: + LOG_WARN("rotation:%d not support\n", child_item->valueint); + mpiVencCommonCfg->rotation = ROTATION_0; + break; + } + } + child_item = cJSON_GetObjectItem(child_common_param, "mirror"); + if (child_item) { + switch (child_item->valueint) { + case 0: + mpiVencCommonCfg->mirror = MIRROR_NONE; + mpiVencCommonCfg->change |= MPI_VENC_COMMON_CFG_CHANGE_MIRROR; + break; + case 1: + mpiVencCommonCfg->mirror = MIRROR_HORIZONTAL; + mpiVencCommonCfg->change |= MPI_VENC_COMMON_CFG_CHANGE_MIRROR; + break; + case 2: + mpiVencCommonCfg->mirror = MIRROR_VERTICAL; + mpiVencCommonCfg->change |= MPI_VENC_COMMON_CFG_CHANGE_MIRROR; + break; + case 3: + mpiVencCommonCfg->mirror = MIRROR_BOTH; + mpiVencCommonCfg->change |= MPI_VENC_COMMON_CFG_CHANGE_MIRROR; + break; + default: + LOG_WARN("mirror:%d not support\n", child_item->valueint); + mpiVencCommonCfg->mirror = MIRROR_NONE; + break; + } + } + child_item = cJSON_GetObjectItem(child_common_param, "channel_id"); + if (child_item) { + mpiVencCommonCfg->channel_id = child_item->valueint; + } + LOG_INFO("venc_cfg common change:0x%x\n", mpiVencCommonCfg->change); + } else { + LOG_WARN("no find venc_cfg common param_init or param_change\n"); + } + } + + return ret; +} + +static int parse_check_uvc_mpi_venc_mjpeg_cfg(cJSON *root, UVC_MPI_CFG *mpiCfg, + bool init) { + int ret = 0; + RK_U32 fps; + RK_U32 loop = 1; + cJSON *child_resolution_param = NULL; + + MpiVencMjpegCfg *mpiVencMjpegCfg = &mpiCfg->venc_cfg.mjpeg_cfg; + if (NULL == mpiVencMjpegCfg) + return -1; + + mpiVencMjpegCfg->change = 0; + cJSON *child_mjpeg = cJSON_GetObjectItem(root, "mjpeg"); + if (!child_mjpeg) { + LOG_ERROR("parse venc_cfg mjpeg err\n"); + return -1; + } else { + cJSON *child_mjpeg_param = NULL; + if (init) { + cJSON *child_mjpeg_param_init = + cJSON_GetObjectItem(child_mjpeg, "param_init"); + char resolution_name[15] = ""; + sprintf(resolution_name, "%d*%dp%d", mpiCfg->uvc_cfg.width, + mpiCfg->uvc_cfg.height, mpiCfg->uvc_cfg.fps); + child_resolution_param = + cJSON_GetObjectItem(child_mjpeg_param_init, resolution_name); + if (child_resolution_param) { + loop = 2; + } + child_mjpeg_param = + cJSON_GetObjectItem(child_mjpeg_param_init, "default"); + } else { + child_mjpeg_param = cJSON_GetObjectItem(child_mjpeg, "param_change"); + } + + for (RK_U32 parse = 0; parse < loop; parse++) { + if (parse == 1) { + child_mjpeg_param = child_resolution_param; + } + if (child_mjpeg_param) { + cJSON *child_item = cJSON_GetObjectItem(child_mjpeg_param, "buf_cnt"); + if (child_item) { + mpiVencMjpegCfg->buf_cnt = child_item->valueint; + mpiVencMjpegCfg->change |= MPI_VENC_MJPEG_CFG_CHANGE_BUF_CNT; + } + child_item = cJSON_GetObjectItem(child_mjpeg_param, "fbc"); + if (child_item) { + mpiVencMjpegCfg->fbc = strstr(child_item->valuestring, "on") + ? COMPRESS_AFBC_16x16 + : COMPRESS_MODE_NONE; + mpiVencMjpegCfg->change |= MPI_VENC_MJPEG_CFG_CHANGE_FBC; + } + child_item = cJSON_GetObjectItem(child_mjpeg_param, "rc_mode"); + if (child_item) { + mpiVencMjpegCfg->rc_mode = + strstr(child_item->valuestring, "cbr") + ? VENC_RC_MODE_MJPEGCBR + : strstr(child_item->valuestring, "vbr") + ? VENC_RC_MODE_MJPEGVBR + : strstr(child_item->valuestring, "fixqp") + ? VENC_RC_MODE_MJPEGFIXQP + : VENC_RC_MODE_MJPEGCBR; + mpiVencMjpegCfg->change |= MPI_VENC_MJPEG_CFG_CHANGE_RC_MODE; + } + child_item = cJSON_GetObjectItem(child_mjpeg_param, "fps"); + if (child_item) { + RK_S32 cnt = 0; + cnt = sscanf(child_item->valuestring, "%d:%d", + &mpiVencMjpegCfg->fps_in, &mpiVencMjpegCfg->fps_out); + if (!cnt) { + LOG_ERROR("invalid set mjpeg fps in:out,such as 30:25\n"); + } else { + mpiVencMjpegCfg->change |= MPI_VENC_MJPEG_CFG_CHANGE_FPS; + } + } + child_item = cJSON_GetObjectItem(child_mjpeg_param, "range"); + if (child_item) { + mpiVencMjpegCfg->range_full = + strstr(child_item->valuestring, "full") ? 1 : 0; + mpiVencMjpegCfg->change |= MPI_VENC_MJPEG_CFG_CHANGE_RANGE; + } + child_item = cJSON_GetObjectItem(child_mjpeg_param, "sei"); + if (child_item) { + mpiVencMjpegCfg->sei = child_item->valueint; + mpiVencMjpegCfg->change |= MPI_VENC_MJPEG_CFG_CHANGE_SEI; + } + child_item = cJSON_GetObjectItem(child_mjpeg_param, "qfactor"); + if (child_item) { + mpiVencMjpegCfg->qp.stParamMjpeg.u32Qfactor = child_item->valueint; + mpiVencMjpegCfg->change |= MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR; + } + child_item = cJSON_GetObjectItem(child_mjpeg_param, "qfactor_min"); + if (child_item) { + mpiVencMjpegCfg->qfactor_min = child_item->valueint; + mpiVencMjpegCfg->change |= MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR_MIN; + } + child_item = cJSON_GetObjectItem(child_mjpeg_param, "qfactor_max"); + if (child_item) { + mpiVencMjpegCfg->qfactor_max = child_item->valueint; + mpiVencMjpegCfg->change |= MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR_MAX; + } + child_item = cJSON_GetObjectItem(child_mjpeg_param, "bps"); + if (child_item) { + mpiVencMjpegCfg->bps = child_item->valueint; + mpiVencMjpegCfg->change |= MPI_VENC_MJPEG_CFG_CHANGE_BPS; + } + child_mjpeg_param = child_resolution_param; + } else { + LOG_WARN("no find venc_cfg mjpeg param_init or param_change\n"); + } + LOG_INFO("venc_cfg mjpeg change:0x%x\n", mpiVencMjpegCfg->change); + } + } + + return ret; +} + +static int parse_check_uvc_mpi_venc_h264_cfg(cJSON *root, UVC_MPI_CFG *mpiCfg, + bool init) { + int ret = 0; + RK_U32 fps; + RK_U32 loop = 1; + cJSON *child_resolution_param = NULL; + + MpiVencH264Cfg *cfg = &mpiCfg->venc_cfg.h264_cfg; + if (NULL == cfg) + return -1; + + cfg->change = 0; + cJSON *child = cJSON_GetObjectItem(root, "h264"); + if (!child) { + LOG_ERROR("parse venc_cfg h264 err\n"); + return -1; + } else { + cJSON *child_param = NULL; + if (init) { + cJSON *child_h264_param_init = cJSON_GetObjectItem(child, "param_init"); + char resolution_name[15] = ""; + sprintf(resolution_name, "%d*%dp%d", mpiCfg->uvc_cfg.width, + mpiCfg->uvc_cfg.height, mpiCfg->uvc_cfg.fps); + child_resolution_param = + cJSON_GetObjectItem(child_h264_param_init, resolution_name); + if (child_resolution_param) { + loop = 2; + } + child_param = cJSON_GetObjectItem(child_h264_param_init, "default"); + } else { + child_param = cJSON_GetObjectItem(child, "param_change"); + } + + for (RK_U32 parse = 0; parse < loop; parse++) { + if (parse == 1) { + child_param = child_resolution_param; + } + if (child_param) { + cJSON *child_item = cJSON_GetObjectItem(child_param, "buf_cnt"); + if (child_item) { + cfg->buf_cnt = child_item->valueint; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_BUF_CNT; + } + child_item = cJSON_GetObjectItem(child_param, "fbc"); + if (child_item) { + cfg->fbc = strstr(child_item->valuestring, "on") ? COMPRESS_AFBC_16x16 + : COMPRESS_MODE_NONE; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_FBC; + } + child_item = cJSON_GetObjectItem(child_param, "gop"); + if (child_item) { + cfg->gop = child_item->valueint; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_GOP; + } + child_item = cJSON_GetObjectItem(child_param, "rc_mode"); + if (child_item) { + cfg->rc_mode = + strstr(child_item->valuestring, "cbr") + ? VENC_RC_MODE_H264CBR + : strstr(child_item->valuestring, "avbr") + ? VENC_RC_MODE_H264AVBR + : strstr(child_item->valuestring, "vbr") + ? VENC_RC_MODE_H264VBR + : strstr(child_item->valuestring, "fixqp") + ? VENC_RC_MODE_H264FIXQP + : VENC_RC_MODE_H264CBR; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_RC_MODE; + } + child_item = cJSON_GetObjectItem(child_param, "fps"); + if (child_item) { + RK_S32 cnt = 0; + cnt = sscanf(child_item->valuestring, "%d:%d", &cfg->fps_in, + &cfg->fps_out); + if (!cnt) { + LOG_ERROR("invalid set H264 fps in:out,such as 30:25\n"); + } else { + cfg->change |= MPI_VENC_H264_CFG_CHANGE_FPS; + } + } + child_item = cJSON_GetObjectItem(child_param, "range"); + if (child_item) { + cfg->range_full = strstr(child_item->valuestring, "full") ? 1 : 0; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_RANGE; + } + child_item = cJSON_GetObjectItem(child_param, "qp"); + if (child_item) { + RK_S32 cnt = 0; + cnt = sscanf( + child_item->valuestring, "%d:%d:%d:%d:%d:%d:%d:%d", + &cfg->qp.s32FirstFrameStartQp, &cfg->qp.stParamH264.u32StepQp, + &cfg->qp.stParamH264.u32MinIQp, &cfg->qp.stParamH264.u32MaxIQp, + &cfg->qp.stParamH264.u32MinQp, &cfg->qp.stParamH264.u32MaxQp, + &cfg->qp.stParamH264.s32DeltIpQp, + &cfg->qp.stParamH264.s32MaxReEncodeTimes); + if (!cnt) { + LOG_ERROR("invalid set H264 qp " + "init:step:minI:maxI:minP:maxP:deltaIP:reEncodeCnt," + "such as 26:4:20:40:8:48:2:1\n"); + } else { + cfg->change |= MPI_VENC_H264_CFG_CHANGE_QP; + } + } + child_item = cJSON_GetObjectItem(child_param, "sei"); + if (child_item) { + cfg->sei = child_item->valueint; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_SEI; + } + child_item = cJSON_GetObjectItem(child_param, "profile"); + if (child_item) { + cfg->profile = child_item->valueint; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_PROFILE; + } + child_item = cJSON_GetObjectItem(child_param, "vi_len"); + if (child_item) { + cfg->gop_mode.s32VirIdrLen = child_item->valueint; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_VI_LEN; + } + child_item = cJSON_GetObjectItem(child_param, "gop_mode"); + if (child_item) { + switch (child_item->valueint) { + case 0: + cfg->gop_mode.enGopMode = VENC_GOPMODE_INIT; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_GOP_MODE; + break; + case 1: + cfg->gop_mode.enGopMode = VENC_GOPMODE_NORMALP; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_GOP_MODE; + break; + case 2: + cfg->gop_mode.enGopMode = VENC_GOPMODE_TSVC2; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_GOP_MODE; + break; + case 3: + cfg->gop_mode.enGopMode = VENC_GOPMODE_TSVC3; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_GOP_MODE; + break; + case 4: + cfg->gop_mode.enGopMode = VENC_GOPMODE_TSVC4; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_GOP_MODE; + break; + case 5: + cfg->gop_mode.enGopMode = VENC_GOPMODE_SMARTP; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_GOP_MODE; + break; + default: + LOG_WARN("gop_mode:%d not support\n", child_item->valueint); + cfg->gop_mode.enGopMode = VENC_GOPMODE_INIT; + break; + } + } + child_item = cJSON_GetObjectItem(child_param, "bps"); + if (child_item) { + cfg->bps = child_item->valueint; + cfg->change |= MPI_VENC_H264_CFG_CHANGE_BPS; + } + child_item = cJSON_GetObjectItem(child_param, "force_idr"); + if (child_item) { + RK_S32 cnt = 0; + cnt = sscanf(child_item->valuestring, "%d:%d:%d", + &mpiCfg->venc_cfg.common_cfg.idr_gop, + &mpiCfg->venc_cfg.common_cfg.idr_cnt, + &mpiCfg->venc_cfg.common_cfg.idr_bps); + if (!cnt) { + LOG_ERROR("invalid set H264 force_idr idr_gop:idr_cnt:idr_bps,such " + "as 5:5:50000\n"); + } else { + cfg->change |= MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR; + } + } + } else { + LOG_WARN("no find venc_cfg H264 param_init or param_change\n"); + } + LOG_INFO("venc_cfg H264 change:0x%x\n", cfg->change); + } + // set to idr info for the begin frame + if (cfg->change & MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR && + (mpiCfg->venc_cfg.common_cfg.idr_gop * + mpiCfg->venc_cfg.common_cfg.idr_cnt * + mpiCfg->venc_cfg.common_cfg.idr_bps)) { + mpiCfg->venc_cfg.common_cfg.normal_bps = cfg->bps; + mpiCfg->venc_cfg.common_cfg.normal_gop = cfg->gop; + cfg->gop = mpiCfg->venc_cfg.common_cfg.idr_gop; + cfg->bps = mpiCfg->venc_cfg.common_cfg.idr_bps; + LOG_INFO("force_idr:start gop:%d bps:%d\n", cfg->gop, cfg->bps); + } + } + + return ret; +} + +static int parse_check_uvc_mpi_venc_h265_cfg(cJSON *root, UVC_MPI_CFG *mpiCfg, + bool init) { + int ret = 0; + RK_U32 fps; + RK_U32 loop = 1; + cJSON *child_resolution_param = NULL; + + MpiVencH265Cfg *cfg = &mpiCfg->venc_cfg.h265_cfg; + if (NULL == cfg) + return -1; + + cfg->change = 0; + cJSON *child = cJSON_GetObjectItem(root, "h265"); + if (!child) { + LOG_ERROR("parse venc_cfg h265 err\n"); + return -1; + } else { + cJSON *child_param = NULL; + if (init) { + cJSON *child_h265_param_init = cJSON_GetObjectItem(child, "param_init"); + char resolution_name[15] = ""; + sprintf(resolution_name, "%d*%dp%d", mpiCfg->uvc_cfg.width, + mpiCfg->uvc_cfg.height, mpiCfg->uvc_cfg.fps); + child_resolution_param = + cJSON_GetObjectItem(child_h265_param_init, resolution_name); + if (child_resolution_param) { + loop = 2; + } + child_param = cJSON_GetObjectItem(child_h265_param_init, "default"); + } else { + child_param = cJSON_GetObjectItem(child, "param_change"); + } + + for (RK_U32 parse = 0; parse < loop; parse++) { + if (parse == 1) { + child_param = child_resolution_param; + } + if (child_param) { + cJSON *child_item = cJSON_GetObjectItem(child_param, "buf_cnt"); + if (child_item) { + cfg->buf_cnt = child_item->valueint; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_BUF_CNT; + } + child_item = cJSON_GetObjectItem(child_param, "fbc"); + if (child_item) { + cfg->fbc = strstr(child_item->valuestring, "on") ? COMPRESS_AFBC_16x16 + : COMPRESS_MODE_NONE; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_FBC; + } + child_item = cJSON_GetObjectItem(child_param, "gop"); + if (child_item) { + cfg->gop = child_item->valueint; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_GOP; + } + child_item = cJSON_GetObjectItem(child_param, "rc_mode"); + if (child_item) { + cfg->rc_mode = + strstr(child_item->valuestring, "cbr") + ? VENC_RC_MODE_H265CBR + : strstr(child_item->valuestring, "avbr") + ? VENC_RC_MODE_H265AVBR + : strstr(child_item->valuestring, "vbr") + ? VENC_RC_MODE_H265VBR + : strstr(child_item->valuestring, "fixqp") + ? VENC_RC_MODE_H265FIXQP + : VENC_RC_MODE_H265CBR; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_RC_MODE; + } + child_item = cJSON_GetObjectItem(child_param, "fps"); + if (child_item) { + RK_S32 cnt = 0; + cnt = sscanf(child_item->valuestring, "%d:%d", &cfg->fps_in, + &cfg->fps_out); + if (!cnt) { + LOG_ERROR("invalid set H265 fps in:out,such as 30:25\n"); + } else { + cfg->change |= MPI_VENC_H265_CFG_CHANGE_FPS; + } + } + child_item = cJSON_GetObjectItem(child_param, "range"); + if (child_item) { + cfg->range_full = strstr(child_item->valuestring, "full") ? 1 : 0; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_RANGE; + } + child_item = cJSON_GetObjectItem(child_param, "qp"); + if (child_item) { + RK_S32 cnt = 0; + cnt = sscanf( + child_item->valuestring, "%d:%d:%d:%d:%d:%d:%d:%d", + &cfg->qp.s32FirstFrameStartQp, &cfg->qp.stParamH265.u32StepQp, + &cfg->qp.stParamH265.u32MinIQp, &cfg->qp.stParamH265.u32MaxIQp, + &cfg->qp.stParamH265.u32MinQp, &cfg->qp.stParamH265.u32MaxQp, + &cfg->qp.stParamH265.s32DeltIpQp, + &cfg->qp.stParamH265.s32MaxReEncodeTimes); + if (!cnt) { + LOG_ERROR("invalid set H265 qp " + "init:step:minI:maxI:minP:maxP:deltaIP:reEncodeCnt," + "such as 26:4:20:40:8:48:2:1\n"); + } else { + cfg->change |= MPI_VENC_H265_CFG_CHANGE_QP; + } + } + child_item = cJSON_GetObjectItem(child_param, "sei"); + if (child_item) { + cfg->sei = child_item->valueint; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_SEI; + } + child_item = cJSON_GetObjectItem(child_param, "profile"); + if (child_item) { + cfg->profile = child_item->valueint; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_PROFILE; + } + child_item = cJSON_GetObjectItem(child_param, "vi_len"); + if (child_item) { + cfg->gop_mode.s32VirIdrLen = child_item->valueint; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_VI_LEN; + } + child_item = cJSON_GetObjectItem(child_param, "gop_mode"); + if (child_item) { + switch (child_item->valueint) { + case 0: + cfg->gop_mode.enGopMode = VENC_GOPMODE_INIT; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_GOP_MODE; + break; + case 1: + cfg->gop_mode.enGopMode = VENC_GOPMODE_NORMALP; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_GOP_MODE; + break; + case 2: + cfg->gop_mode.enGopMode = VENC_GOPMODE_TSVC2; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_GOP_MODE; + break; + case 3: + cfg->gop_mode.enGopMode = VENC_GOPMODE_TSVC3; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_GOP_MODE; + break; + case 4: + cfg->gop_mode.enGopMode = VENC_GOPMODE_TSVC4; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_GOP_MODE; + break; + case 5: + cfg->gop_mode.enGopMode = VENC_GOPMODE_SMARTP; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_GOP_MODE; + break; + default: + LOG_WARN("gop_mode:%d not support\n", child_item->valueint); + cfg->gop_mode.enGopMode = VENC_GOPMODE_INIT; + break; + } + } + child_item = cJSON_GetObjectItem(child_param, "bps"); + if (child_item) { + cfg->bps = child_item->valueint; + cfg->change |= MPI_VENC_H265_CFG_CHANGE_BPS; + } + child_item = cJSON_GetObjectItem(child_param, "force_idr"); + if (child_item) { + RK_S32 cnt = 0; + cnt = sscanf(child_item->valuestring, "%d:%d:%d", + &mpiCfg->venc_cfg.common_cfg.idr_gop, + &mpiCfg->venc_cfg.common_cfg.idr_cnt, + &mpiCfg->venc_cfg.common_cfg.idr_bps); + if (!cnt) { + LOG_ERROR("invalid set H265 force_idr idr_gop:idr_cnt:idr_bps,such " + "as 5:5:50000\n"); + } else { + cfg->change |= MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR; + } + } + } else { + LOG_WARN("no find venc_cfg H265 param_init or param_change\n"); + } + LOG_INFO("venc_cfg H265 change:0x%x\n", cfg->change); + } + // set to idr info for the begin frame + if (cfg->change & MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR && + (mpiCfg->venc_cfg.common_cfg.idr_gop * + mpiCfg->venc_cfg.common_cfg.idr_cnt * + mpiCfg->venc_cfg.common_cfg.idr_bps)) { + mpiCfg->venc_cfg.common_cfg.normal_bps = cfg->bps; + mpiCfg->venc_cfg.common_cfg.normal_gop = cfg->gop; + cfg->gop = mpiCfg->venc_cfg.common_cfg.idr_gop; + cfg->bps = mpiCfg->venc_cfg.common_cfg.idr_bps; + LOG_INFO("force_idr:start gop:%d bps:%d\n", cfg->gop, cfg->bps); + } + } + + return ret; +} + +static int parse_check_uvc_mpi_venc_cfg(cJSON *root, UVC_MPI_CFG *mpiCfg, + bool init) { + int ret = 0; + + cJSON *child_venc_cfg = cJSON_GetObjectItem(root, "venc_cfg"); + if (!child_venc_cfg) { + LOG_ERROR("parse venc_cfg err\n"); + return -1; + } + + switch (mpiCfg->uvc_cfg.fcc) { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_NV12: + break; + case V4L2_PIX_FMT_MJPEG: + ret |= parse_check_uvc_mpi_venc_common_cfg(child_venc_cfg, mpiCfg, init); + ret |= parse_check_uvc_mpi_venc_mjpeg_cfg(child_venc_cfg, mpiCfg, init); + break; + case V4L2_PIX_FMT_H264: + ret |= parse_check_uvc_mpi_venc_common_cfg(child_venc_cfg, mpiCfg, init); + ret |= parse_check_uvc_mpi_venc_h264_cfg(child_venc_cfg, mpiCfg, init); + break; + case V4L2_PIX_FMT_H265: + ret |= parse_check_uvc_mpi_venc_common_cfg(child_venc_cfg, mpiCfg, init); + ret |= parse_check_uvc_mpi_venc_h265_cfg(child_venc_cfg, mpiCfg, init); + break; + default: + LOG_ERROR("not support this fcc 0x%x\n", mpiCfg->uvc_cfg.fcc); + break; + } + + return ret; +} + +static int parse_check_uvc_osd_cfg(cJSON *root, UVC_MPI_CFG *mpiCfg, + bool init) { + int ret = 0; + cJSON *child_property_param = NULL; + + MpiOsdCfg *osdCfg = &mpiCfg->osd_cfg; + if (NULL == osdCfg) + return -1; + + osdCfg->change = 0; + cJSON *child = cJSON_GetObjectItem(root, "osd_cfg"); + if (!child) { + LOG_ERROR("parse osd_cfg err\n"); + return -1; + } + cJSON *child_version = cJSON_GetObjectItem(child, "version"); + if (child_version) { + LOG_DEBUG("parse osd version:%d\n", child_version->valueint); + osdCfg->version = child_version->valueint; + } + + if (init) + child_property_param = cJSON_GetObjectItem(child, "param_init"); + else + child_property_param = cJSON_GetObjectItem(child, "param_change"); + if (child_property_param) { + cJSON *child_item = cJSON_GetObjectItem(child_property_param, "enable"); + if (child_item) { + osdCfg->enable = strstr(child_item->valuestring, "on") ? 1 : 0; + osdCfg->change |= MPI_OSD_CFG_CHANGE_ENABLE_OSD; + } + child_item = cJSON_GetObjectItem(child_property_param, "force_use_vpss"); + if (child_item) { + osdCfg->force_use_vpss = strstr(child_item->valuestring, "on") ? 1 : 0; + osdCfg->change |= MPI_OSD_CFG_CHANGE_FORCE_USE_VPSS; + } + + LOG_INFO("uvc osd change:0x%x\n", osdCfg->change); + } + + return ret; +} + +#if 0 +static int parse_check_uvc_mpi_osd_cfg(cJSON *root, UVC_MPI_CFG *mpiCfg, bool init) { + int ret = 0; + RK_U32 fps; + RK_U32 loop = 1; + cJSON *child_resolution_param = NULL; + + MpiVencH265Cfg *cfg = &mpiCfg->venc_cfg.h265_cfg; + if (NULL == cfg) + return -1; + + cJSON *child_osd = cJSON_GetObjectItem(child, "osd"); + if (!child_osd) + { + LOG_INFO("no osd info\n"); + } + else + { + cJSON *child_osd_enable = cJSON_GetObjectItem(child_osd, "enable"); + if (child_osd_enable) + { + mpiVencCfg->osd_enable = strstr(child_osd_enable->valuestring, "on") ? + true : false; + } + cJSON *child_osd_count = cJSON_GetObjectItem(child_osd, "count"); + if (child_osd_count) + { + mpiVencCfg->osd_count = child_osd_count->valueint; + mpiVencCfg->osd_count = mpiVencCfg->osd_count < 0 ? 0 : + mpiVencCfg->osd_count > OSD_REGIONS_CNT ? OSD_REGIONS_CNT : + mpiVencCfg->osd_count; + } + cJSON *child_osd_plt_user = cJSON_GetObjectItem(child_osd, "plt_user"); + if (child_osd_plt_user) + { + mpiVencCfg->osd_plt_user = child_osd_plt_user->valueint; + } + + char osd_name[6] = "osd_0"; + for (int i = 0; i < mpiVencCfg->osd_count; i ++) + { + osd_name[4] = i + 48; + cJSON *child_osd_index = cJSON_GetObjectItem(child_osd, osd_name); + if (child_osd_index) + { + mpiVencCfg->osd_cfg[i].set_ok = true; + cJSON *child_osd_index_type = cJSON_GetObjectItem(child_osd_index, "type");; + if (child_osd_index_type) + { + mpiVencCfg->osd_cfg[i].type = strstr(child_osd_index_type->valuestring, "picture") ? + OSD_REGION_TYPE_PICTURE : OSD_REGION_TYPE_PICTURE; + } + cJSON *child_osd_index_enable = cJSON_GetObjectItem(child_osd_index, "enable"); + if (child_osd_index_enable) + { + mpiVencCfg->osd_cfg[i].enable = strstr(child_osd_index_enable->valuestring, "on") ? + true : false; + } + + char resolution_name[10] = ""; + sprintf(resolution_name, "%d*%d",mpiVencCfg->width, mpiVencCfg->height); + cJSON *child_osd_resolution_name = cJSON_GetObjectItem(child_osd_index, resolution_name); + if (!child_osd_resolution_name) { + child_osd_resolution_name = cJSON_GetObjectItem(child_osd_index, "common"); + } + if (child_osd_resolution_name) { + cJSON *child_osd_index_path = cJSON_GetObjectItem(child_osd_resolution_name, "path"); + if (child_osd_index_path) { + if (strlen(child_osd_index_path->valuestring) > + (MPP_ENC_OSD_IMAGE_PATH_LEN - 1)) { + LOG_ERROR("osd img path:%s, the name too long\n", + child_osd_index_path->valuestring); + mpiVencCfg->osd_cfg[i].enable = false; + mpiVencCfg->osd_cfg[i].set_ok = false; + } else { + sprintf(mpiVencCfg->osd_cfg[i].image_path, "%s", + child_osd_index_path->valuestring); + } + } + cJSON *child_osd_index_start_x = cJSON_GetObjectItem(child_osd_resolution_name, "start_x"); + if (child_osd_index_start_x) + { + mpiVencCfg->osd_cfg[i].start_x = UPALIGNTO16((int)(child_osd_index_start_x->valuedouble * mpiVencCfg->width)); + } + cJSON *child_osd_index_start_y = cJSON_GetObjectItem(child_osd_resolution_name, "start_y"); + if (child_osd_index_start_y) + { + mpiVencCfg->osd_cfg[i].start_y = UPALIGNTO16((int)(child_osd_index_start_y->valuedouble * mpiVencCfg->height)); + } + } + else + { + LOG_INFO("no such resolution_name:%s && common path\n", resolution_name); + } + } + else + { + LOG_INFO("no such osd %s\n", osd_name); + } + } + } + return ret; +} +#endif + +static int parse_check_uvc_mpi_cfg(cJSON *root, UVC_MPI_CFG *cfg, bool init) { + int ret = 0; + + LOG_INFO("parse_uvc_mpi index: %d init:%d\n", cfg->index, init); + cJSON *index_root = parse_find_uvc_index_cfg(root, cfg->index, init); + if (index_root) { + cJSON *index_version = cJSON_GetObjectItem(index_root, "version"); + if (index_version) { + LOG_INFO("parse index_version:%d\n", index_version->valueint); + cfg->version = index_version->valueint; + } + ret |= parse_check_uvc_common_cfg(index_root, cfg, init); + ret |= parse_check_uvc_mpi_vi_cfg(index_root, cfg, init); + ret |= parse_check_uvc_mpi_vpss_cfg(index_root, cfg, init); + ret |= parse_check_uvc_mpi_venc_cfg(index_root, cfg, init); + ret |= parse_check_uvc_osd_cfg(index_root, cfg, init); + } else { + ret = -1; + } + + return ret; +} + +static int read_uvc_mpi_cfg_modify_file(UVC_MPI_CFG *mpiCfg, bool init) { + int ret = -1; + unsigned long read_size = 0; + + FILE *modify_fd = fopen(UVC_MPI_CFG_MODIFY_PATH, "rb"); + unsigned long size = get_file_size(UVC_MPI_CFG_MODIFY_PATH); + LOG_DEBUG("get cfg size=%ld\n", size); + char *cfg = (char *)malloc(size); + while (read_size != size) { + read_size += fread(cfg, 1, size - read_size, modify_fd); + } + // LOG_INFO("get cfg =%s read_size=%ld\n", cfg, read_size); + cJSON *root = cJSON_Parse(cfg); + if (root == NULL) { + LOG_ERROR("the %s is broken\n", UVC_MPI_CFG_MODIFY_PATH); + } else { + ret = parse_check_uvc_mpi_cfg(root, mpiCfg, init); + } + if (modify_fd) + fclose(modify_fd); + if (cfg) + free(cfg); + if (root) + cJSON_Delete(root); + + return ret; +} + +int check_uvc_mpi_cfg_file_init(UVC_MPI_CFG *cfg) { + int ret = -1; + char cmd[128] = {0}; + if (NULL == cfg) + return -1; + + if (!access(UVC_MPI_CFG_MODIFY_PATH, F_OK)) { + ret = read_uvc_mpi_cfg_modify_file(cfg, true); + } + + if (ret) { + if (!access(UVC_MPI_CFG_ORIGINAL_PATH, F_OK)) { + sprintf(cmd, "cp %s %s", UVC_MPI_CFG_ORIGINAL_PATH, + UVC_MPI_CFG_MODIFY_PATH); + system(cmd); + LOG_DEBUG("copy enc cfg file...\n"); + ret = read_uvc_mpi_cfg_modify_file(cfg, true); + } else { + LOG_ERROR("file :%s not exit!\n", UVC_MPI_CFG_ORIGINAL_PATH); + ret = -1; + } + } + + /* if (cfg->common_cfg.need_check) { + mpiVencCfg->cfg_notify_fd = inotify_init(); + }*/ + + return ret; +} + +#if 0 +void *thread_check_mpp_enc_chenge_loop(void *user) { + int ret = 0; + int mpi_ret; + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, PTHREAD_CREATE_JOINABLE); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + MpiEncTestData *mpiVencCfg = (MpiEncTestData *)user; + int last_wd = 0; + unsigned char buf[1024] = {0}; + struct inotify_event *event = NULL; + bool modify = false; + + while (1) { + last_wd = mpiVencCfg->cfg_notify_wd; + mpiVencCfg->cfg_notify_wd = inotify_add_watch(mpiVencCfg->cfg_notify_fd, + RK_UVC_MPI_CFG_MODIFY_PATH, + IN_MODIFY | IN_DELETE_SELF); + modify = false; + if (mpiVencCfg->cfg_notify_wd != -1) { + if ((last_wd == -1 && mpiVencCfg->cfg_notify_wd == 1)) { + modify = true; + } else { + fd_set fds; + FD_ZERO(&fds); + FD_SET(mpiVencCfg->cfg_notify_fd, &fds); + + if (select(mpiVencCfg->cfg_notify_fd + 1, &fds, NULL, NULL, NULL) > 0) { + int len, index = 0; + memset(buf, 0, sizeof(buf)); + len = read(mpiVencCfg->cfg_notify_fd, &buf, sizeof(buf)); + while (len > 0 && index < len) { + event = (struct inotify_event *)(buf + index); + if (event->mask == IN_MODIFY) { + modify = true; + } else if (event->mask == IN_DELETE_SELF) { + mpiVencCfg->cfg_notify_wd = -1; + } + index += sizeof(struct inotify_event) + event->len; + } + } + + } + } + sleep(1); + if (modify) { + LOG_INFO("the enc cfg file change or creat, do update.wd=%d,last_wd=%d\n", mpiVencCfg->cfg_notify_wd, last_wd); + ret = read_uvc_mpi_cfg_modify_file(mpiVencCfg, false); + if (ret) + LOG_ERROR("error: the enc cfg file is broken.please check.\n"); + else { + mpp_ret = mpp_enc_cfg_set(mpiVencCfg, false); + dump_mpp_enc_cfg(mpiVencCfg); + if (mpp_ret) { + LOG_ERROR("mpp_enc_cfg_set failed ret %d\n", mpp_ret); + } + } + } + + inotify_rm_watch(mpiVencCfg->cfg_notify_fd, mpiVencCfg->cfg_notify_wd); + close(mpiVencCfg->cfg_notify_fd); + mpiVencCfg->cfg_notify_fd = inotify_init(); + } +} +#endif + +void uvc_mpi_cfg_set_default(UVC_MPI_CFG *mpiCfg) { + // common cfg + mpiCfg->common_cfg.change = MPI_UVC_COMMON_CFG_CHANGE_ALL; + mpiCfg->common_cfg.need_check = 0; + mpiCfg->common_cfg.uvc_debug = 0; + mpiCfg->common_cfg.uvc_debug_cnt = 0; + copy_str_to_array(mpiCfg->common_cfg.uvc_debug_file, + UVC_MPI_CFG_DEBUG_FILE_NAME, UVC_MPI_STREAM_SAVE_FILE_LEN); + copy_str_to_array(mpiCfg->common_cfg.nn_debug_file, + UVC_MPI_CFG_NN_DEBUG_FILE_NAME, + UVC_MPI_STREAM_SAVE_FILE_LEN); + mpiCfg->common_cfg.geometric_output_den = 1; + mpiCfg->common_cfg.geometric_output_num = 1; + mpiCfg->common_cfg.uvc_enable_vpss = 0; + // vi_cfg uvc + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].change = MPI_VI_CFG_CHANGE_ALL; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].dev_id = 0; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].channel_id = 0; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].assign_width = 0; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].assign_height = 0; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].min_width = 640; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].min_height = 480; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].max_width = 2560; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].max_height = 1440; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].format = RK_FMT_YUV420SP; + // 3588 need up to 3 for fps to 30 + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].buf_cnt = 3; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].fps_in = -1; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].fps_out = -1; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].fbc = COMPRESS_MODE_NONE; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].memory_type = + VI_V4L2_MEMORY_TYPE_DMABUF; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].rotation = ROTATION_0; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].mirror = MIRROR_NONE; + // vi_cfg nn + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].change = MPI_VI_CFG_CHANGE_ALL; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].dev_id = 0; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].channel_id = 1; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].assign_width = 1280; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].assign_height = 720; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].format = RK_FMT_YUV420SP; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].buf_cnt = 2; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].fps_in = -1; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].fps_out = -1; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].fbc = COMPRESS_MODE_NONE; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].memory_type = + VI_V4L2_MEMORY_TYPE_DMABUF; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].rotation = ROTATION_0; + mpiCfg->vi_cfg[MPI_VI_CHANNEL_TYPE_NN].mirror = MIRROR_NONE; + // vpss_cfg uvc + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].change = MPI_VPSS_CFG_CHANGE_ALL; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].group_id = 0; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].channel_id = + 0; // now only support chn 0 + // now the rockit limit min 3/now the rga limit min 5 + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].buf_cnt = 5; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].fps_in = -1; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].fps_out = -1; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].fbc = COMPRESS_MODE_NONE; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].rotation = ROTATION_0; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].mirror = MIRROR_NONE; + // vpss_cfg nn + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].change = MPI_VPSS_CFG_CHANGE_ALL; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].group_id = 0; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].channel_id = + 0; // now only support chn 0 + // now the rockit limit min 3/now the rga limit min 5 + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].buf_cnt = 5; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].fps_in = -1; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].fps_out = -1; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].fbc = COMPRESS_MODE_NONE; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].rotation = ROTATION_0; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].mirror = MIRROR_NONE; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].assign_width = 1280; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].assign_height = 720; + mpiCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_NN].format = RK_FMT_RGB888; + + // venc common_cfg + mpiCfg->venc_cfg.common_cfg.change = MPI_VENC_COMMON_CFG_CHANGE_ALL; + mpiCfg->venc_cfg.common_cfg.channel_id = 0; + mpiCfg->venc_cfg.common_cfg.rotation = ROTATION_0; + mpiCfg->venc_cfg.common_cfg.mirror = MIRROR_NONE; + mpiCfg->venc_cfg.common_cfg.idr_gop = 0; + mpiCfg->venc_cfg.common_cfg.idr_cnt = 0; + mpiCfg->venc_cfg.common_cfg.idr_bps = 20000; + mpiCfg->venc_cfg.common_cfg.enable_vpss = 1; + // venc mjpeg_cfg + mpiCfg->venc_cfg.mjpeg_cfg.change = MPI_VENC_MJPEG_CFG_CHANGE_ALL; + mpiCfg->venc_cfg.mjpeg_cfg.qp.stParamMjpeg.u32Qfactor = 85; + mpiCfg->venc_cfg.mjpeg_cfg.qfactor_min = 30; + mpiCfg->venc_cfg.mjpeg_cfg.qfactor_max = 99; + mpiCfg->venc_cfg.mjpeg_cfg.range_full = 1; + mpiCfg->venc_cfg.mjpeg_cfg.bps = 100000; + mpiCfg->venc_cfg.mjpeg_cfg.sei = 0; + mpiCfg->venc_cfg.mjpeg_cfg.buf_cnt = 2; + mpiCfg->venc_cfg.mjpeg_cfg.fps_in = -1; + mpiCfg->venc_cfg.mjpeg_cfg.fps_out = -1; + mpiCfg->venc_cfg.mjpeg_cfg.fbc = COMPRESS_MODE_NONE; + mpiCfg->venc_cfg.mjpeg_cfg.rc_mode = VENC_RC_MODE_MJPEGFIXQP; + // venc h264_cfg + mpiCfg->venc_cfg.h264_cfg.change = MPI_VENC_H264_CFG_CHANGE_ALL; + mpiCfg->venc_cfg.h264_cfg.gop = 60; + mpiCfg->venc_cfg.h264_cfg.range_full = 1; + mpiCfg->venc_cfg.h264_cfg.sei = 0; + mpiCfg->venc_cfg.h264_cfg.profile = 100; + mpiCfg->venc_cfg.h264_cfg.bps = 10000; + mpiCfg->venc_cfg.h264_cfg.buf_cnt = 2; + mpiCfg->venc_cfg.h264_cfg.fps_in = -1; + mpiCfg->venc_cfg.h264_cfg.fps_out = -1; + mpiCfg->venc_cfg.h264_cfg.fbc = COMPRESS_MODE_NONE; + mpiCfg->venc_cfg.h264_cfg.rc_mode = VENC_RC_MODE_H264CBR; + mpiCfg->venc_cfg.h264_cfg.qp.s32FirstFrameStartQp = 24; + mpiCfg->venc_cfg.h264_cfg.qp.stParamH264.u32StepQp = 4; + mpiCfg->venc_cfg.h264_cfg.qp.stParamH264.u32MinIQp = 20; + mpiCfg->venc_cfg.h264_cfg.qp.stParamH264.u32MaxIQp = 40; + mpiCfg->venc_cfg.h264_cfg.qp.stParamH264.u32MinQp = 10; + mpiCfg->venc_cfg.h264_cfg.qp.stParamH264.u32MaxQp = 48; + mpiCfg->venc_cfg.h264_cfg.qp.stParamH264.s32DeltIpQp = 2; + mpiCfg->venc_cfg.h264_cfg.qp.stParamH264.s32MaxReEncodeTimes = 1; + mpiCfg->venc_cfg.h264_cfg.gop_mode.enGopMode = VENC_GOPMODE_INIT; + mpiCfg->venc_cfg.h264_cfg.gop_mode.s32VirIdrLen = 30; + // venc h265_cfg + mpiCfg->venc_cfg.h265_cfg.change = MPI_VENC_H265_CFG_CHANGE_ALL; + mpiCfg->venc_cfg.h265_cfg.gop = 60; + mpiCfg->venc_cfg.h265_cfg.range_full = 1; + mpiCfg->venc_cfg.h265_cfg.sei = 0; + mpiCfg->venc_cfg.h265_cfg.profile = 100; + mpiCfg->venc_cfg.h265_cfg.bps = 10000; + mpiCfg->venc_cfg.h265_cfg.buf_cnt = 2; + mpiCfg->venc_cfg.h265_cfg.fps_in = -1; + mpiCfg->venc_cfg.h265_cfg.fps_out = -1; + mpiCfg->venc_cfg.h265_cfg.fbc = COMPRESS_MODE_NONE; + mpiCfg->venc_cfg.h265_cfg.rc_mode = VENC_RC_MODE_H265CBR; + mpiCfg->venc_cfg.h265_cfg.qp.s32FirstFrameStartQp = 24; + mpiCfg->venc_cfg.h265_cfg.qp.stParamH265.u32StepQp = 4; + mpiCfg->venc_cfg.h265_cfg.qp.stParamH265.u32MinIQp = 20; + mpiCfg->venc_cfg.h265_cfg.qp.stParamH265.u32MaxIQp = 40; + mpiCfg->venc_cfg.h265_cfg.qp.stParamH265.u32MinQp = 10; + mpiCfg->venc_cfg.h265_cfg.qp.stParamH265.u32MaxQp = 48; + mpiCfg->venc_cfg.h265_cfg.qp.stParamH265.s32DeltIpQp = 2; + mpiCfg->venc_cfg.h265_cfg.qp.stParamH265.s32MaxReEncodeTimes = 1; + mpiCfg->venc_cfg.h265_cfg.gop_mode.enGopMode = VENC_GOPMODE_INIT; + mpiCfg->venc_cfg.h265_cfg.gop_mode.s32VirIdrLen = 30; +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_config.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_config.h new file mode 100755 index 000000000..f4b872ff7 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_config.h @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __UVC_MPI_CONFIG_H__ +#define __UVC_MPI_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rk_mpi_vi.h" +#include "rk_mpi_vpss.h" +#include + +#define UVC_MPI_CFG_CHANGE_BIT(x) (1 << x) +#define UVC_MPI_STREAM_SAVE_FILE_LEN 32 +#define VPSS_MAX_CHN 1 // now only support one chn. + +typedef enum _MpiUvcCommonCfgChange { + MPI_UVC_COMMON_CFG_NEED_CHECK = UVC_MPI_CFG_CHANGE_BIT(0), + MPI_UVC_COMMON_CFG_UVC_DEBUG = UVC_MPI_CFG_CHANGE_BIT(1), + MPI_UVC_COMMON_CFG_UVC_DEBUG_FILE_NAME = UVC_MPI_CFG_CHANGE_BIT(2), + MPI_UVC_COMMON_CFG_UVC_DEBUG_FILE_CNT = UVC_MPI_CFG_CHANGE_BIT(3), + MPI_UVC_COMMON_CFG_GEOMETRIC_OUT = UVC_MPI_CFG_CHANGE_BIT(4), + MPI_UVC_COMMON_CFG_UVC_YUYV_DEBUG = UVC_MPI_CFG_CHANGE_BIT(5), + MPI_UVC_COMMON_CFG_UVC_NN_ENABLE = UVC_MPI_CFG_CHANGE_BIT(6), + MPI_UVC_COMMON_CFG_NN_DEBUG_FILE_NAME = UVC_MPI_CFG_CHANGE_BIT(7), + MPI_UVC_COMMON_CFG_NN_DEBUG_FILE_CNT = UVC_MPI_CFG_CHANGE_BIT(8), + MPI_UVC_COMMON_CFG_UVC_ENABLE_VPSS = UVC_MPI_CFG_CHANGE_BIT(9), + MPI_UVC_COMMON_CFG_CHANGE_ALL = (0xffffffff), +} MpiUvcCommonCfgChange; + +typedef enum _MpiViCfgChange { + MPI_VI_CFG_CHANGE_DEV_ID = UVC_MPI_CFG_CHANGE_BIT(0), + MPI_VI_CFG_CHANGE_CHANNEL_ID = UVC_MPI_CFG_CHANGE_BIT(1), + MPI_VI_CFG_CHANGE_BUF_CNT = UVC_MPI_CFG_CHANGE_BIT(2), + MPI_VI_CFG_CHANGE_FBC = UVC_MPI_CFG_CHANGE_BIT(3), + MPI_VI_CFG_CHANGE_MEMORY_TYPE = UVC_MPI_CFG_CHANGE_BIT(4), + MPI_VI_CFG_CHANGE_ROTATION = UVC_MPI_CFG_CHANGE_BIT(5), + MPI_VI_CFG_CHANGE_MIRROR = UVC_MPI_CFG_CHANGE_BIT(6), + MPI_VI_CFG_CHANGE_DEV_NAME = UVC_MPI_CFG_CHANGE_BIT(7), + MPI_VI_CFG_CHANGE_FPS = UVC_MPI_CFG_CHANGE_BIT(8), + MPI_VI_CFG_CHANGE_ASSIGN_WIDTH = UVC_MPI_CFG_CHANGE_BIT(9), + MPI_VI_CFG_CHANGE_ASSIGN_HEIGHT = UVC_MPI_CFG_CHANGE_BIT(10), + MPI_VI_CFG_CHANGE_MIN_WIDTH = UVC_MPI_CFG_CHANGE_BIT(11), + MPI_VI_CFG_CHANGE_MIN_HEIGHT = UVC_MPI_CFG_CHANGE_BIT(12), + MPI_VI_CFG_CHANGE_MAX_WIDTH = UVC_MPI_CFG_CHANGE_BIT(13), + MPI_VI_CFG_CHANGE_MAX_HEIGHT = UVC_MPI_CFG_CHANGE_BIT(14), + MPI_VI_CFG_CHANGE_FORMAT = UVC_MPI_CFG_CHANGE_BIT(15), + MPI_VI_CFG_CHANGE_ALL = (0xffffffff), +} MpiViCfgChange; + +typedef enum _MpiVpssCfgChange { + MPI_VPSS_CFG_CHANGE_GROUP_ID = UVC_MPI_CFG_CHANGE_BIT(0), + MPI_VPSS_CFG_CHANGE_CHANNEL_ID = UVC_MPI_CFG_CHANGE_BIT(1), + MPI_VPSS_CFG_CHANGE_BUF_CNT = UVC_MPI_CFG_CHANGE_BIT(2), + MPI_VPSS_CFG_CHANGE_FBC = UVC_MPI_CFG_CHANGE_BIT(3), + MPI_VPSS_CFG_CHANGE_ROTATION = UVC_MPI_CFG_CHANGE_BIT(4), + MPI_VPSS_CFG_CHANGE_MIRROR = UVC_MPI_CFG_CHANGE_BIT(5), + MPI_VPSS_CFG_CHANGE_FPS = UVC_MPI_CFG_CHANGE_BIT(6), + MPI_VPSS_CFG_CHANGE_FORMAT = UVC_MPI_CFG_CHANGE_BIT(7), + MPI_VPSS_CFG_CHANGE_ASSIGN_WIDTH = UVC_MPI_CFG_CHANGE_BIT(8), + MPI_VPSS_CFG_CHANGE_ASSIGN_HEIGHT = UVC_MPI_CFG_CHANGE_BIT(9), + MPI_VPSS_CFG_CHANGE_ALL = (0xffffffff), +} MpiVpssCfgChange; + +typedef enum _MpiVencCommonCfgChange { + MPI_VENC_COMMON_CFG_CHANGE_CREATE = UVC_MPI_CFG_CHANGE_BIT(0), + MPI_VENC_COMMON_CFG_CHANGE_ROTATION = UVC_MPI_CFG_CHANGE_BIT(1), + MPI_VENC_COMMON_CFG_CHANGE_MIRROR = UVC_MPI_CFG_CHANGE_BIT(2), + MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR = UVC_MPI_CFG_CHANGE_BIT(3), + MPI_VENC_COMMON_CFG_CHANGE_ALL = (0xffffffff), +} MpiVencCommonCfgChange; + +typedef enum _MpiVencMjpegCfgChange { + MPI_VENC_MJPEG_CFG_CHANGE_RC_MODE = UVC_MPI_CFG_CHANGE_BIT(0), + MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR = UVC_MPI_CFG_CHANGE_BIT(1), + MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR_MIN = UVC_MPI_CFG_CHANGE_BIT(2), // reserver + MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR_MAX = UVC_MPI_CFG_CHANGE_BIT(3), // reserver + MPI_VENC_MJPEG_CFG_CHANGE_BPS = UVC_MPI_CFG_CHANGE_BIT(4), + MPI_VENC_MJPEG_CFG_CHANGE_FPS = UVC_MPI_CFG_CHANGE_BIT(5), + MPI_VENC_MJPEG_CFG_CHANGE_BUF_CNT = UVC_MPI_CFG_CHANGE_BIT(6), + MPI_VENC_MJPEG_CFG_CHANGE_SEI = UVC_MPI_CFG_CHANGE_BIT(7), + MPI_VENC_MJPEG_CFG_CHANGE_RANGE = UVC_MPI_CFG_CHANGE_BIT(8), + MPI_VENC_MJPEG_CFG_CHANGE_FBC = UVC_MPI_CFG_CHANGE_BIT(9), + MPI_VENC_MJPEG_CFG_CHANGE_ALL = (0xffffffff), +} MpiVencMjpegCfgChange; + +typedef enum _MpiVencH264CfgChange { + MPI_VENC_H264_CFG_CHANGE_GOP = UVC_MPI_CFG_CHANGE_BIT(0), + MPI_VENC_H264_CFG_CHANGE_RC_MODE = UVC_MPI_CFG_CHANGE_BIT(1), + MPI_VENC_H264_CFG_CHANGE_BPS = UVC_MPI_CFG_CHANGE_BIT(2), + MPI_VENC_H264_CFG_CHANGE_GOP_MODE = UVC_MPI_CFG_CHANGE_BIT(3), + MPI_VENC_H264_CFG_CHANGE_VI_LEN = UVC_MPI_CFG_CHANGE_BIT(4), + MPI_VENC_H264_CFG_CHANGE_FPS = UVC_MPI_CFG_CHANGE_BIT(5), + MPI_VENC_H264_CFG_CHANGE_BUF_CNT = UVC_MPI_CFG_CHANGE_BIT(6), + MPI_VENC_H264_CFG_CHANGE_RANGE = UVC_MPI_CFG_CHANGE_BIT(7), + MPI_VENC_H264_CFG_CHANGE_SEI = UVC_MPI_CFG_CHANGE_BIT(8), + MPI_VENC_H264_CFG_CHANGE_PROFILE = UVC_MPI_CFG_CHANGE_BIT(9), + MPI_VENC_H264_CFG_CHANGE_FBC = UVC_MPI_CFG_CHANGE_BIT(10), + MPI_VENC_H264_CFG_CHANGE_QP = UVC_MPI_CFG_CHANGE_BIT(11), + MPI_VENC_H264_CFG_CHANGE_ALL = (0xffffffff), +} MpiVencH264CfgChange; + +typedef enum _MpiVencH265CfgChange { + MPI_VENC_H265_CFG_CHANGE_GOP = UVC_MPI_CFG_CHANGE_BIT(0), + MPI_VENC_H265_CFG_CHANGE_RC_MODE = UVC_MPI_CFG_CHANGE_BIT(1), + MPI_VENC_H265_CFG_CHANGE_BPS = UVC_MPI_CFG_CHANGE_BIT(2), + MPI_VENC_H265_CFG_CHANGE_GOP_MODE = UVC_MPI_CFG_CHANGE_BIT(3), + MPI_VENC_H265_CFG_CHANGE_VI_LEN = UVC_MPI_CFG_CHANGE_BIT(4), + MPI_VENC_H265_CFG_CHANGE_FPS = UVC_MPI_CFG_CHANGE_BIT(5), + MPI_VENC_H265_CFG_CHANGE_BUF_CNT = UVC_MPI_CFG_CHANGE_BIT(6), + MPI_VENC_H265_CFG_CHANGE_RANGE = UVC_MPI_CFG_CHANGE_BIT(7), + MPI_VENC_H265_CFG_CHANGE_SEI = UVC_MPI_CFG_CHANGE_BIT(8), + MPI_VENC_H265_CFG_CHANGE_PROFILE = UVC_MPI_CFG_CHANGE_BIT(9), + MPI_VENC_H265_CFG_CHANGE_FBC = UVC_MPI_CFG_CHANGE_BIT(10), + MPI_VENC_H265_CFG_CHANGE_QP = UVC_MPI_CFG_CHANGE_BIT(11), + MPI_VENC_H265_CFG_CHANGE_ALL = (0xffffffff), +} MpiVencH265CfgChange; + +typedef enum _MpiEptzCfgChange { + MPI_EPTZ_CFG_CHANGE_ENABLE_EPTZ = UVC_MPI_CFG_CHANGE_BIT(0), + MPI_EPTZ_CFG_CHANGE_ENABLE_EPTZ_BOOT = UVC_MPI_CFG_CHANGE_BIT(1), + MPI_EPTZ_CFG_CHANGE_ENABLE_DEBUG = UVC_MPI_CFG_CHANGE_BIT(2), + MPI_EPTZ_CFG_CHANGE_ALIGN = UVC_MPI_CFG_CHANGE_BIT(3), + MPI_EPTZ_CFG_CHANGE_ZOOM_SPEED = UVC_MPI_CFG_CHANGE_BIT(4), + MPI_EPTZ_CFG_CHANGE_FAST_MOVE_FRAME_JUDGE = UVC_MPI_CFG_CHANGE_BIT(5), + MPI_EPTZ_CFG_CHANGE_ZOOM_FRAME_JUDGE = UVC_MPI_CFG_CHANGE_BIT(6), + MPI_EPTZ_CFG_CHANGE_ITERATE_X = UVC_MPI_CFG_CHANGE_BIT(7), + MPI_EPTZ_CFG_CHANGE_ITERATE_Y = UVC_MPI_CFG_CHANGE_BIT(8), + MPI_EPTZ_CFG_CHANGE_RATIO = UVC_MPI_CFG_CHANGE_BIT(9), + MPI_EPTZ_CFG_CHANGE_ALL = (0xffffffff), +} MpiEptzCfgChange; + +typedef enum _MpiOsdCfgChange { + MPI_OSD_CFG_CHANGE_ENABLE_OSD = UVC_MPI_CFG_CHANGE_BIT(0), + MPI_OSD_CFG_CHANGE_FORCE_USE_VPSS = UVC_MPI_CFG_CHANGE_BIT(1), + MPI_OSD_CFG_CHANGE_ALL = (0xffffffff), +} MpiOsdCfgChange; + +typedef enum _MpiViChannelType { + MPI_VI_CHANNEL_TYPE_UVC = 0, + MPI_VI_CHANNEL_TYPE_NN = 1, + MPI_VI_CHANNEL_TYPE_MAX = 2, +} MpiViChannelType; + +typedef enum _MpiVpssChannelType { + MPI_VPSS_CHANNEL_TYPE_UVC = 0, + MPI_VPSS_CHANNEL_TYPE_NN = 1, + MPI_VPSS_CHANNEL_TYPE_MAX = 2, +} MpiVpssChannelType; + +typedef struct { + RK_U32 change; + RK_U32 channel_id; + // idr begin + RK_U32 idr_gop; + RK_U32 idr_cnt; + RK_U32 idr_bps; + RK_U32 normal_gop; + RK_U32 normal_bps; + // idr end + RK_U32 enable_vpss; + ROTATION_E rotation; + MIRROR_E mirror; +} MpiVencCommonCfg; + +typedef struct { + RK_U32 change; + RK_U32 qfactor_min; + RK_U32 qfactor_max; + RK_U32 range_full; + RK_U32 bps; + RK_U32 sei; + RK_U32 buf_cnt; + RK_S32 fps_in; + RK_S32 fps_out; + COMPRESS_MODE_E fbc; + VENC_RC_MODE_E rc_mode; + VENC_RC_PARAM_S qp; +} MpiVencMjpegCfg; + +typedef struct { + RK_U32 change; + RK_U32 gop; + RK_U32 range_full; + RK_U32 sei; + RK_U32 profile; + RK_U32 bps; + RK_U32 buf_cnt; + RK_S32 fps_in; + RK_S32 fps_out; + COMPRESS_MODE_E fbc; + VENC_RC_MODE_E rc_mode; + VENC_RC_PARAM_S qp; + VENC_GOP_ATTR_S gop_mode; +} MpiVencH264Cfg; + +typedef struct { + RK_U32 change; + RK_U32 gop; + RK_U32 range_full; + RK_U32 sei; + RK_U32 profile; + RK_U32 bps; + RK_U32 buf_cnt; + RK_S32 fps_in; + RK_S32 fps_out; + COMPRESS_MODE_E fbc; + VENC_RC_MODE_E rc_mode; + VENC_RC_PARAM_S qp; + VENC_GOP_ATTR_S gop_mode; +} MpiVencH265Cfg; + +#if 0 +#define MPP_ENC_OSD_IMAGE_PATH_LEN 32 +typedef struct { + bool set_ok; + bool enable; //dynamic on/off set this + enum OSD_REGION_TYPE type; + RK_U32 start_x; + RK_U32 start_y; + char image_path[MPP_ENC_OSD_IMAGE_PATH_LEN];//*image_path;// +// for mjpeg rga osd + RK_U32 width; + RK_U32 height; + int rga_osd_fd; + unsigned int handle; // for drm handle + uint8_t *buffer; + int drm_size; +// for mjpeg rga osd +} MpiEncOSDCfg; +#endif + +typedef struct { + RK_U32 version; + MpiVencCommonCfg common_cfg; + MpiVencMjpegCfg mjpeg_cfg; + MpiVencH264Cfg h264_cfg; + MpiVencH265Cfg h265_cfg; +} MpiVencCfg; + +typedef struct { + RK_U32 version; + RK_U32 change; + RK_U32 dev_id; + RK_U32 channel_id; + RK_U32 buf_cnt; + RK_U32 assign_width; + RK_U32 assign_height; + RK_U32 min_width; + RK_U32 min_height; + RK_U32 max_width; + RK_U32 max_height; + RK_S32 fps_in; + RK_S32 fps_out; + PIXEL_FORMAT_E format; + COMPRESS_MODE_E fbc; + VI_V4L2_MEMORY_TYPE memory_type; + ROTATION_E rotation; + MIRROR_E mirror; + RK_CHAR dev_name[MAX_VI_ENTITY_NAME_LEN]; +} MpiViCfg; + +typedef struct { + RK_U32 version; + RK_U32 change; + RK_U32 group_id; + RK_U32 channel_id; + RK_U32 buf_cnt; + RK_S32 fps_in; + RK_S32 fps_out; + RK_U32 assign_width; + RK_U32 assign_height; + PIXEL_FORMAT_E format; + COMPRESS_MODE_E fbc; + ROTATION_E rotation; + MIRROR_E mirror; +} MpiVpssCfg; + +typedef struct { + RK_U32 version; + RK_U32 change; + RK_U32 need_check; + RK_U32 uvc_debug_cnt; + RK_U32 nn_debug_cnt; + RK_U32 uvc_debug; + RK_U32 yuyv_debug; + RK_U32 nn_enable; + RK_U32 geometric_output_num; + RK_U32 geometric_output_den; + RK_U32 uvc_enable_vpss; + RK_U32 eptz_enable; + RK_U32 eptz_enable_boot; + RK_CHAR uvc_debug_file[UVC_MPI_STREAM_SAVE_FILE_LEN]; + RK_CHAR nn_debug_file[UVC_MPI_STREAM_SAVE_FILE_LEN]; +} MpiUvcCommonCfg; + +typedef struct { + RK_U32 version; + RK_U32 change; + RK_U32 enable; + RK_U32 enable_boot; + RK_U32 debug; + RK_S32 align; + RK_S32 zoom_speed; + RK_S32 fast_move_frame_judge; + RK_S32 zoom_frame_judge; + RK_S32 iterate_x; + RK_S32 iterate_y; + RK_FLOAT ratio; +} MpiUvcEptzCfg; + +typedef struct { + RK_U32 version; + RK_U32 change; + RK_U32 enable; + RK_U32 force_use_vpss; +} MpiOsdCfg; + +typedef struct { + RK_S32 width; + RK_S32 height; + RK_S32 fcc; + RK_U32 fps; +} MpiUvcCfg; + +typedef struct _rkUvcMpiCfg { + RK_U32 index; + RK_U32 version; + MpiUvcCfg uvc_cfg; // for uvc setting + MpiUvcCommonCfg common_cfg; + MpiUvcEptzCfg eptz_cfg; + MpiOsdCfg osd_cfg; + MpiViCfg vi_cfg[MPI_VI_CHANNEL_TYPE_MAX]; + MpiVpssCfg vpss_cfg[MPI_VPSS_CHANNEL_TYPE_MAX]; + MpiVencCfg venc_cfg; +} UVC_MPI_CFG; + +int check_uvc_mpi_cfg_file_init(UVC_MPI_CFG *cfg); +void uvc_mpi_cfg_set_default(UVC_MPI_CFG *mpiCfg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_venc.cpp b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_venc.cpp new file mode 100755 index 000000000..2947df4eb --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_venc.cpp @@ -0,0 +1,528 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "uvc_mpi_venc.h" +#include "rk_mpi_sys.h" +#include "uvc_log.h" +#include "uvc_video.h" +#include + +// config +static RK_S32 venc_set_gopsize(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32GopSize); +static RK_S32 venc_set_bitrate(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32BitRate); +static RK_S32 venc_set_framerate(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32FpsIn, + RK_U32 u32FpsOut); +static RK_S32 venc_set_fixqp(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32FixIQp, + RK_U32 u32FixPQp, RK_U32 u32FixBQp); +static RK_S32 venc_set_qp(VENC_RC_ATTR_S *pRcAttr, VENC_RC_PARAM_S qp); +static RK_S32 config_venc_chn_attr(UVC_MPI_CFG uvcCfg); +static RK_S32 config_venc_rc_param(UVC_MPI_CFG uvcCfg); + +UVC_VENC_CHN_CTX_S uvc_get_venc_chn_ctx(UVC_MPI_CFG uvcCfg) { + UVC_VENC_CHN_CTX_S vencChnCtx; + memset(&vencChnCtx, 0, sizeof(UVC_VENC_CHN_CTX_S)); + + vencChnCtx.devId = 0; + vencChnCtx.channelId = uvcCfg.venc_cfg.common_cfg.channel_id; + + return vencChnCtx; +} + +static void set_venc_mjpeg_attr(VENC_CHN_ATTR_S *vencAttr, UVC_MPI_CFG uvcCfg) { + vencAttr->stVencAttr.enType = RK_VIDEO_ID_MJPEG; + vencAttr->stVencAttr.u32StreamBufCnt = uvcCfg.venc_cfg.mjpeg_cfg.buf_cnt; + vencAttr->stRcAttr.enRcMode = uvcCfg.venc_cfg.mjpeg_cfg.rc_mode; + + venc_set_bitrate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.mjpeg_cfg.bps); + venc_set_framerate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.mjpeg_cfg.fps_in, + uvcCfg.venc_cfg.mjpeg_cfg.fps_out); + venc_set_qp(&vencAttr->stRcAttr, uvcCfg.venc_cfg.mjpeg_cfg.qp); +} + +static void set_venc_h264_attr(VENC_CHN_ATTR_S *vencAttr, UVC_MPI_CFG uvcCfg) { + vencAttr->stVencAttr.enType = RK_VIDEO_ID_AVC; + vencAttr->stVencAttr.u32Profile = uvcCfg.venc_cfg.h264_cfg.profile; + vencAttr->stVencAttr.u32StreamBufCnt = uvcCfg.venc_cfg.h264_cfg.buf_cnt; + vencAttr->stRcAttr.enRcMode = uvcCfg.venc_cfg.h264_cfg.rc_mode; + vencAttr->stGopAttr = uvcCfg.venc_cfg.h264_cfg.gop_mode; + + venc_set_gopsize(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h264_cfg.gop); + venc_set_bitrate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h264_cfg.bps); + venc_set_framerate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h264_cfg.fps_in, + uvcCfg.venc_cfg.h264_cfg.fps_out); + venc_set_qp(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h264_cfg.qp); + + LOG_INFO("venc gop:%d bps:%d\n", uvcCfg.venc_cfg.h264_cfg.gop, + uvcCfg.venc_cfg.h264_cfg.bps); +} + +static void set_venc_h265_attr(VENC_CHN_ATTR_S *vencAttr, UVC_MPI_CFG uvcCfg) { + vencAttr->stVencAttr.enType = RK_VIDEO_ID_HEVC; + vencAttr->stVencAttr.u32Profile = uvcCfg.venc_cfg.h265_cfg.profile; + vencAttr->stVencAttr.u32StreamBufCnt = uvcCfg.venc_cfg.h265_cfg.buf_cnt; + vencAttr->stRcAttr.enRcMode = uvcCfg.venc_cfg.h265_cfg.rc_mode; + vencAttr->stGopAttr = uvcCfg.venc_cfg.h265_cfg.gop_mode; + + venc_set_gopsize(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h265_cfg.gop); + venc_set_bitrate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h265_cfg.bps); + venc_set_framerate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h265_cfg.fps_in, + uvcCfg.venc_cfg.h265_cfg.fps_out); + venc_set_qp(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h265_cfg.qp); +} + +static VENC_CHN_ATTR_S get_venc_chn_attr(UVC_MPI_CFG uvcCfg) { + VENC_CHN_ATTR_S vencAttr; + memset(&vencAttr, 0, sizeof(VENC_CHN_ATTR_S)); + + switch (uvcCfg.uvc_cfg.fcc) { + case V4L2_PIX_FMT_MJPEG: + set_venc_mjpeg_attr(&vencAttr, uvcCfg); + break; + case V4L2_PIX_FMT_H264: + set_venc_h264_attr(&vencAttr, uvcCfg); + break; + case V4L2_PIX_FMT_H265: + set_venc_h265_attr(&vencAttr, uvcCfg); + break; + default: + LOG_ERROR("venc not support this fcc 0x%x\n", uvcCfg.uvc_cfg.fcc); + break; + } + + vencAttr.stVencAttr.enPixelFormat = RK_FMT_YUV420SP; + vencAttr.stVencAttr.enMirror = uvcCfg.venc_cfg.common_cfg.mirror; + vencAttr.stVencAttr.u32PicWidth = uvcCfg.uvc_cfg.width; + vencAttr.stVencAttr.u32PicHeight = uvcCfg.uvc_cfg.height; + vencAttr.stVencAttr.u32VirWidth = uvcCfg.uvc_cfg.width; + vencAttr.stVencAttr.u32VirHeight = uvcCfg.uvc_cfg.height; + vencAttr.stVencAttr.u32BufSize = + uvcCfg.uvc_cfg.width * uvcCfg.uvc_cfg.height * 2; + + return vencAttr; +} + +static VENC_RC_PARAM_S get_venc_rc_param(UVC_MPI_CFG uvcCfg) { + VENC_RC_PARAM_S vencRcParam; + memset(&vencRcParam, 0, sizeof(VENC_RC_PARAM_S)); + + switch (uvcCfg.uvc_cfg.fcc) { + case V4L2_PIX_FMT_MJPEG: + vencRcParam = uvcCfg.venc_cfg.mjpeg_cfg.qp; + break; + case V4L2_PIX_FMT_H264: + vencRcParam = uvcCfg.venc_cfg.h264_cfg.qp; + break; + case V4L2_PIX_FMT_H265: + vencRcParam = uvcCfg.venc_cfg.h265_cfg.qp; + break; + default: + LOG_ERROR("venc not support this fcc 0x%x\n", uvcCfg.uvc_cfg.fcc); + break; + } + + return vencRcParam; +} + +static RK_S32 config_venc_chn_attr(UVC_MPI_CFG uvcCfg) { + RK_S32 s32Ret = RK_FAILURE; + UVC_VENC_CHN_CTX_S vencChnCtx = uvc_get_venc_chn_ctx(uvcCfg); + VENC_CHN_ATTR_S vencAttr = get_venc_chn_attr(uvcCfg); + + s32Ret = RK_MPI_VENC_SetChnAttr(vencChnCtx.channelId, &vencAttr); + + return s32Ret; +} + +static RK_S32 config_venc_rc_param(UVC_MPI_CFG uvcCfg) { + RK_S32 s32Ret = RK_FAILURE; + UVC_VENC_CHN_CTX_S vencChnCtx = uvc_get_venc_chn_ctx(uvcCfg); + VENC_RC_PARAM_S vencRcParam = get_venc_rc_param(uvcCfg); + + s32Ret = RK_MPI_VENC_SetRcParam(vencChnCtx.channelId, &vencRcParam); + + return s32Ret; +} + +static RK_S32 venc_set_bitrate(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32BitRate) { + switch (pRcAttr->enRcMode) { + case VENC_RC_MODE_MJPEGCBR: + pRcAttr->stMjpegCbr.u32BitRate = u32BitRate; + break; + case VENC_RC_MODE_H264CBR: + pRcAttr->stH264Cbr.u32BitRate = u32BitRate; + break; + case VENC_RC_MODE_H265CBR: + pRcAttr->stH265Cbr.u32BitRate = u32BitRate; + break; + case VENC_RC_MODE_MJPEGVBR: + pRcAttr->stMjpegVbr.u32BitRate = u32BitRate; + break; + case VENC_RC_MODE_H264VBR: + pRcAttr->stH264Vbr.u32BitRate = u32BitRate; + break; + case VENC_RC_MODE_H265VBR: + pRcAttr->stH265Vbr.u32BitRate = u32BitRate; + break; + case VENC_RC_MODE_H264AVBR: + pRcAttr->stH264Avbr.u32BitRate = u32BitRate; + break; + case VENC_RC_MODE_H265AVBR: + pRcAttr->stH265Avbr.u32BitRate = u32BitRate; + break; + default: + return RK_ERR_VENC_NOT_SUPPORT; + } + + return RK_SUCCESS; +} + +static RK_S32 venc_set_gopsize(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32GopSize) { + switch (pRcAttr->enRcMode) { + case VENC_RC_MODE_H264CBR: + pRcAttr->stH264Cbr.u32Gop = u32GopSize; + break; + case VENC_RC_MODE_H265CBR: + pRcAttr->stH265Cbr.u32Gop = u32GopSize; + break; + case VENC_RC_MODE_H264VBR: + pRcAttr->stH264Vbr.u32Gop = u32GopSize; + break; + case VENC_RC_MODE_H265VBR: + pRcAttr->stH265Vbr.u32Gop = u32GopSize; + break; + case VENC_RC_MODE_H264AVBR: + pRcAttr->stH264Avbr.u32Gop = u32GopSize; + break; + case VENC_RC_MODE_H265AVBR: + pRcAttr->stH265Avbr.u32Gop = u32GopSize; + break; + case VENC_RC_MODE_H264FIXQP: + pRcAttr->stH264FixQp.u32Gop = u32GopSize; + break; + case VENC_RC_MODE_H265FIXQP: + pRcAttr->stH265FixQp.u32Gop = u32GopSize; + break; + default: + return RK_ERR_VENC_NOT_SUPPORT; + } + + return RK_SUCCESS; +} + +static RK_S32 venc_set_framerate(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32FpsIn, + RK_U32 u32FpsOut) { + switch (pRcAttr->enRcMode) { + case VENC_RC_MODE_MJPEGCBR: + pRcAttr->stMjpegCbr.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stMjpegCbr.u32SrcFrameRateDen = 1; + pRcAttr->stMjpegCbr.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stMjpegCbr.fr32DstFrameRateDen = 1; + break; + case VENC_RC_MODE_H264CBR: + pRcAttr->stH264Cbr.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stH264Cbr.u32SrcFrameRateDen = 1; + pRcAttr->stH264Cbr.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stH264Cbr.fr32DstFrameRateDen = 1; + break; + case VENC_RC_MODE_H265CBR: + pRcAttr->stH265Cbr.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stH265Cbr.u32SrcFrameRateDen = 1; + pRcAttr->stH265Cbr.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stH265Cbr.fr32DstFrameRateDen = 1; + break; + case VENC_RC_MODE_MJPEGVBR: + pRcAttr->stMjpegVbr.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stMjpegVbr.u32SrcFrameRateDen = 1; + pRcAttr->stMjpegVbr.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stMjpegVbr.fr32DstFrameRateDen = 1; + break; + case VENC_RC_MODE_H264VBR: + pRcAttr->stH264Vbr.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stH264Vbr.u32SrcFrameRateDen = 1; + pRcAttr->stH264Vbr.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stH264Vbr.fr32DstFrameRateDen = 1; + break; + case VENC_RC_MODE_H265VBR: + pRcAttr->stH265Vbr.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stH265Vbr.u32SrcFrameRateDen = 1; + pRcAttr->stH265Vbr.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stH265Vbr.fr32DstFrameRateDen = 1; + break; + case VENC_RC_MODE_H264AVBR: + pRcAttr->stH264Avbr.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stH264Avbr.u32SrcFrameRateDen = 1; + pRcAttr->stH264Avbr.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stH264Avbr.fr32DstFrameRateDen = 1; + break; + case VENC_RC_MODE_H265AVBR: + pRcAttr->stH265Avbr.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stH265Avbr.u32SrcFrameRateDen = 1; + pRcAttr->stH265Avbr.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stH265Avbr.fr32DstFrameRateDen = 1; + break; + case VENC_RC_MODE_MJPEGFIXQP: + pRcAttr->stMjpegFixQp.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stMjpegFixQp.u32SrcFrameRateDen = 1; + pRcAttr->stMjpegFixQp.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stMjpegFixQp.fr32DstFrameRateDen = 1; + break; + case VENC_RC_MODE_H264FIXQP: + pRcAttr->stH264FixQp.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stH264FixQp.u32SrcFrameRateDen = 1; + pRcAttr->stH264FixQp.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stH264FixQp.fr32DstFrameRateDen = 1; + break; + case VENC_RC_MODE_H265FIXQP: + pRcAttr->stH265FixQp.u32SrcFrameRateNum = u32FpsIn; + pRcAttr->stH265FixQp.u32SrcFrameRateDen = 1; + pRcAttr->stH265FixQp.fr32DstFrameRateNum = u32FpsOut; + pRcAttr->stH265FixQp.fr32DstFrameRateDen = 1; + break; + + default: + return RK_ERR_VENC_NOT_SUPPORT; + } + + return RK_SUCCESS; +} + +static RK_S32 venc_set_fixqp(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32FixIQp, + RK_U32 u32FixPQp, RK_U32 u32FixBQp) { + switch (pRcAttr->enRcMode) { + case VENC_RC_MODE_MJPEGFIXQP: + pRcAttr->stMjpegFixQp.u32Qfactor = u32FixIQp; + break; + case VENC_RC_MODE_H264FIXQP: + pRcAttr->stH264FixQp.u32IQp = u32FixIQp; + pRcAttr->stH264FixQp.u32PQp = u32FixPQp; + pRcAttr->stH264FixQp.u32BQp = u32FixBQp; + break; + case VENC_RC_MODE_H265FIXQP: + pRcAttr->stH265FixQp.u32IQp = u32FixIQp; + pRcAttr->stH265FixQp.u32PQp = u32FixPQp; + pRcAttr->stH265FixQp.u32BQp = u32FixBQp; + break; + default: + return RK_ERR_VENC_NOT_SUPPORT; + } + + return RK_SUCCESS; +} + +static RK_S32 venc_set_qp(VENC_RC_ATTR_S *pRcAttr, VENC_RC_PARAM_S qp) { + switch (pRcAttr->enRcMode) { + case VENC_RC_MODE_MJPEGFIXQP: + venc_set_fixqp(pRcAttr, qp.stParamMjpeg.u32Qfactor, + qp.stParamMjpeg.u32Qfactor, qp.stParamMjpeg.u32Qfactor); + break; + case VENC_RC_MODE_H264FIXQP: + venc_set_fixqp(pRcAttr, qp.stParamH264.u32MinIQp, qp.stParamH264.u32MinQp, + qp.stParamH264.u32MinQp); + break; + case VENC_RC_MODE_H265FIXQP: + venc_set_fixqp(pRcAttr, qp.stParamH265.u32MinIQp, qp.stParamH265.u32MinQp, + qp.stParamH265.u32MinQp); + break; + case VENC_RC_MODE_MJPEGCBR: + case VENC_RC_MODE_MJPEGVBR: + case VENC_RC_MODE_H264CBR: + case VENC_RC_MODE_H264VBR: + case VENC_RC_MODE_H264AVBR: + case VENC_RC_MODE_H265CBR: + case VENC_RC_MODE_H265VBR: + case VENC_RC_MODE_H265AVBR: + // just call RK_MPI_VENC_SetRcParam + break; + default: + return RK_ERR_VENC_NOT_SUPPORT; + } + + return RK_SUCCESS; +} + +static RK_S32 config_venc_common(UVC_MPI_CFG *uvcCfg) { + RK_S32 s32Ret = RK_FAILURE; + UVC_VENC_CHN_CTX_S vencChnCtx = uvc_get_venc_chn_ctx(*uvcCfg); + + if (uvcCfg->venc_cfg.common_cfg.change & MPI_VENC_COMMON_CFG_CHANGE_CREATE) { + VENC_CHN_ATTR_S vencAttr = get_venc_chn_attr(*uvcCfg); + s32Ret = RK_MPI_VENC_CreateChn(vencChnCtx.channelId, &vencAttr); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VENC_CreateChn fail 0x%x\n", s32Ret); + goto __FAILED; + } else { + LOG_INFO("RK_MPI_VENC_CreateChn %d\n", vencChnCtx.channelId); + } + uvcCfg->venc_cfg.common_cfg.change &= (~MPI_VENC_COMMON_CFG_CHANGE_CREATE); + uvcCfg->venc_cfg.common_cfg.change &= + (~MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR); + } else { + if (uvcCfg->venc_cfg.common_cfg.change & + MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR) { + s32Ret = config_venc_chn_attr(*uvcCfg); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("config_venc_chn_attr fail 0x%x\n", s32Ret); + goto __FAILED; + } else { + LOG_INFO("config_venc_chn_attr %d\n", vencChnCtx.channelId); + } + uvcCfg->venc_cfg.common_cfg.change &= + (~MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR); + } + } + if (uvcCfg->venc_cfg.common_cfg.change & + MPI_VENC_COMMON_CFG_CHANGE_ROTATION) { + s32Ret = RK_MPI_VENC_SetChnRotation(vencChnCtx.channelId, + uvcCfg->venc_cfg.common_cfg.rotation); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VENC_CreateChn fail 0x%x\n", s32Ret); + goto __FAILED; + } + uvcCfg->venc_cfg.common_cfg.change &= + (~MPI_VENC_COMMON_CFG_CHANGE_ROTATION); + } + +__FAILED: + return s32Ret; +} + +static RK_S32 config_venc_mjpeg(UVC_MPI_CFG *uvcCfg) { + RK_S32 s32Ret = RK_FAILURE; + + if (uvcCfg->venc_cfg.mjpeg_cfg.change & MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR) { + s32Ret = config_venc_rc_param(*uvcCfg); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VENC_CreateChn fail 0x%x\n", s32Ret); + goto __FAILED; + } + uvcCfg->venc_cfg.mjpeg_cfg.change &= (~MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR); + } + +__FAILED: + return s32Ret; +} + +static RK_S32 config_venc_h264(UVC_MPI_CFG *uvcCfg) { + RK_S32 s32Ret = RK_FAILURE; + + if (uvcCfg->venc_cfg.h264_cfg.change & MPI_VENC_H264_CFG_CHANGE_QP) { + s32Ret = config_venc_rc_param(*uvcCfg); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VENC_CreateChn fail 0x%x\n", s32Ret); + goto __FAILED; + } + uvcCfg->venc_cfg.h264_cfg.change &= (~MPI_VENC_H264_CFG_CHANGE_QP); + } + +__FAILED: + return s32Ret; +} + +static RK_S32 config_venc_h265(UVC_MPI_CFG *uvcCfg) { + RK_S32 s32Ret = RK_FAILURE; + + if (uvcCfg->venc_cfg.h265_cfg.change & MPI_VENC_H265_CFG_CHANGE_QP) { + s32Ret = config_venc_rc_param(*uvcCfg); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VENC_CreateChn fail 0x%x\n", s32Ret); + goto __FAILED; + } + uvcCfg->venc_cfg.h265_cfg.change &= (~MPI_VENC_H265_CFG_CHANGE_QP); + } + +__FAILED: + return s32Ret; +} + +RK_S32 uvc_venc_config(UVC_MPI_CFG *uvcCfg) { + RK_S32 s32Ret = RK_FAILURE; + + config_venc_common(uvcCfg); + + switch (uvcCfg->uvc_cfg.fcc) { + case V4L2_PIX_FMT_MJPEG: + config_venc_mjpeg(uvcCfg); + break; + case V4L2_PIX_FMT_H264: + config_venc_h264(uvcCfg); + break; + case V4L2_PIX_FMT_H265: + config_venc_h265(uvcCfg); + break; + default: + LOG_ERROR("venc not support this fcc 0x%x\n", uvcCfg->uvc_cfg.fcc); + break; + } + +__FAILED: + return s32Ret; +} + +RK_S32 uvc_venc_start(UVC_MPI_CFG uvcCfg) { + RK_S32 s32Ret = RK_FAILURE; + VENC_RECV_PIC_PARAM_S stRecvParam; + UVC_VENC_CHN_CTX_S vencChnCtx = uvc_get_venc_chn_ctx(uvcCfg); + + stRecvParam.s32RecvPicNum = -1; + LOG_INFO("RK_MPI_VENC_StartRecvFrame %d\n", vencChnCtx.channelId); + s32Ret = RK_MPI_VENC_StartRecvFrame(vencChnCtx.channelId, &stRecvParam); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VENC_StartRecvFrame fail 0x%x\n", s32Ret); + goto __FAILED; + } + +__FAILED: + return s32Ret; +} + +RK_S32 uvc_venc_stop(UVC_MPI_CFG uvcCfg) { + RK_S32 s32Ret = RK_FAILURE; + UVC_VENC_CHN_CTX_S vencChnCtx = uvc_get_venc_chn_ctx(uvcCfg); + + s32Ret = RK_MPI_VENC_StopRecvFrame(vencChnCtx.channelId); + if (s32Ret != RK_SUCCESS) { + return s32Ret; + } + LOG_INFO("reset enc chn:%d\n", vencChnCtx.channelId); + s32Ret = RK_MPI_VENC_ResetChn(vencChnCtx.channelId); + if (s32Ret != RK_SUCCESS) { + return s32Ret; + } + LOG_INFO("destroy enc chn:%d\n", vencChnCtx.channelId); + s32Ret = RK_MPI_VENC_DestroyChn(vencChnCtx.channelId); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VDEC_DestroyChn :%d fail %x", vencChnCtx.channelId, + s32Ret); + } + +__FAILED: + return s32Ret; +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_venc.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_venc.h new file mode 100644 index 000000000..779a8e217 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_venc.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __UVC_MPI_VENC_H__ +#define __UVC_MPI_VENC_H__ + +#include "rk_mpi_venc.h" +#include "uvc_mpi_config.h" + +typedef struct _uvcVencChnCtx { + RK_S32 devId; + RK_S32 channelId; +} UVC_VENC_CHN_CTX_S; + +UVC_VENC_CHN_CTX_S uvc_get_venc_chn_ctx(UVC_MPI_CFG uvcCfg); + +RK_S32 uvc_venc_config(UVC_MPI_CFG *uvcCfg); +RK_S32 uvc_venc_start(UVC_MPI_CFG uvcCfg); +RK_S32 uvc_venc_stop(UVC_MPI_CFG uvcCfg); + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vi.cpp b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vi.cpp new file mode 100644 index 000000000..da63f5ba4 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vi.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "uvc_mpi_vi.h" +#include "rk_mpi_sys.h" +#include "rk_mpi_vi.h" +#include "uvc_log.h" +#include "uvc_video.h" +#include + +typedef struct _rkMpiVICtx { + UVC_VI_CHN_CTX_S stChnCtx; + COMPRESS_MODE_E enCompressMode; + VI_DEV_ATTR_S stDevAttr; + VI_DEV_BIND_PIPE_S stBindPipe; + VI_CHN_ATTR_S stChnAttr; + VI_CHN_STATUS_S stChnStatus; +} MPI_VI_CTX_S; + +UVC_VI_CHN_CTX_S uvc_get_vi_chn_ctx(UVC_MPI_CFG uvcCfg, + MpiViChannelType chnType) { + UVC_VI_CHN_CTX_S viChnCtx; + memset(&viChnCtx, 0, sizeof(UVC_VI_CHN_CTX_S)); + + viChnCtx.devId = uvcCfg.vi_cfg[chnType].dev_id; + viChnCtx.pipeId = viChnCtx.devId; + viChnCtx.channelId = uvcCfg.vi_cfg[chnType].channel_id; + + return viChnCtx; +} + +static MPI_VI_CTX_S uvc_get_vi_ctx(UVC_MPI_CFG *uvcCfg, + MpiViChannelType chnType) { + MPI_VI_CTX_S viCtx; + memset(&viCtx, 0, sizeof(MPI_VI_CTX_S)); + + LOG_INFO("chnType:%d uvc out:%dx%d, vi assign_resolution:%dx%d vi_name:%s\n", + chnType, uvcCfg->uvc_cfg.width, uvcCfg->uvc_cfg.height, + uvcCfg->vi_cfg[chnType].assign_width, + uvcCfg->vi_cfg[chnType].assign_height, + uvcCfg->vi_cfg[chnType].dev_name); + + // this is for uvc vi/nn vi different cfg. + switch (chnType) { + case MPI_VI_CHANNEL_TYPE_UVC: + if (uvcCfg->vi_cfg[chnType].assign_width <= 0 || + uvcCfg->vi_cfg[chnType].assign_height <= + 0) { // not assign the vi uvc output + if (uvcCfg->uvc_cfg.width < uvcCfg->vi_cfg[chnType].min_width || + uvcCfg->uvc_cfg.height < + uvcCfg->vi_cfg[chnType] + .min_height) { // not support this resolution(too small) + uvcCfg->vi_cfg[chnType].assign_width = + uvcCfg->vi_cfg[chnType].min_width; + uvcCfg->vi_cfg[chnType].assign_height = + uvcCfg->vi_cfg[chnType].min_height; + LOG_INFO("uvc out:%dx%d, the min resolution:%dx%d\n", + uvcCfg->uvc_cfg.width, uvcCfg->uvc_cfg.height, + uvcCfg->vi_cfg[chnType].min_width, + uvcCfg->vi_cfg[chnType].min_height); + } else if (uvcCfg->uvc_cfg.width > uvcCfg->vi_cfg[chnType].max_width || + uvcCfg->uvc_cfg.height > + uvcCfg->vi_cfg[chnType].max_height) { // not support this + // resolution(too + // large) + uvcCfg->vi_cfg[chnType].assign_width = + uvcCfg->vi_cfg[chnType].max_width; + uvcCfg->vi_cfg[chnType].assign_height = + uvcCfg->vi_cfg[chnType].max_height; + LOG_INFO("uvc out:%dx%d, the max resolution:%dx%d\n", + uvcCfg->uvc_cfg.width, uvcCfg->uvc_cfg.height, + uvcCfg->vi_cfg[chnType].max_width, + uvcCfg->vi_cfg[chnType].max_height); + } else { + uvcCfg->vi_cfg[chnType].assign_width = uvcCfg->uvc_cfg.width; + uvcCfg->vi_cfg[chnType].assign_height = uvcCfg->uvc_cfg.height; + } + } + + switch (uvcCfg->uvc_cfg.fcc) { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_NV12: // reserver +#if 0 + if (uvcCfg->uvc_cfg.width == 1280) { + LOG_ERROR("vi workaround and here alloc 1 buf count!!!\n"); + uvcCfg->vi_cfg[chnType].buf_cnt = + 1; // workaround for 1280*720 vpss stuck + } +#endif + viCtx.stChnAttr.enPixelFormat = + uvcCfg->vi_cfg[chnType].format; // RK_FMT_YUV422_YUYV; + viCtx.stChnAttr.u32Depth = 0; // viCtx.stChnAttr.stIspOpt.u32BufCount; // + // bind 0; not bind u32BufCount; + break; + case V4L2_PIX_FMT_MJPEG: + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_H265: + viCtx.stChnAttr.enPixelFormat = RK_FMT_YUV420SP; + viCtx.stChnAttr.u32Depth = 0; // bind 0; not bind u32BufCount; + break; + default: + LOG_ERROR("vi not support this fcc 0x%x\n", uvcCfg->uvc_cfg.fcc); + break; + } + break; + case MPI_VI_CHANNEL_TYPE_NN: + viCtx.stChnAttr.enPixelFormat = uvcCfg->vi_cfg[chnType].format; + viCtx.stChnAttr.u32Depth = 0; + break; + default: + LOG_ERROR("vi not support this chnType 0x%x\n", chnType); + break; + } + + // common cfg + viCtx.stChnCtx = uvc_get_vi_chn_ctx(*uvcCfg, chnType); + viCtx.stChnAttr.stIspOpt.bNoUseLibV4L2 = RK_FALSE; + viCtx.stChnAttr.stIspOpt.u32BufCount = uvcCfg->vi_cfg[chnType].buf_cnt; + viCtx.stChnAttr.stIspOpt.u32BufSize = + 0; // uvcCfg.vi_cfg[chnType].width * uvcCfg.vi_cfg[chnType].height * 2; + // uvcCfg.uvc_cfg.width * uvcCfg.uvc_cfg.height; + viCtx.stChnAttr.stIspOpt.enMemoryType = uvcCfg->vi_cfg[chnType].memory_type; + if (strncmp(uvcCfg->vi_cfg[chnType].dev_name, "null", strlen("null"))) { + memcpy(viCtx.stChnAttr.stIspOpt.aEntityName, + uvcCfg->vi_cfg[chnType].dev_name, + strlen(uvcCfg->vi_cfg[chnType].dev_name)); + } + viCtx.stChnAttr.stFrameRate.s32SrcFrameRate = + uvcCfg->vi_cfg[chnType].fps_in > 0 ? uvcCfg->vi_cfg[chnType].fps_in : -1; + viCtx.stChnAttr.stFrameRate.s32DstFrameRate = + uvcCfg->vi_cfg[chnType].fps_out > 0 ? uvcCfg->vi_cfg[chnType].fps_out + : -1; + viCtx.stChnAttr.stSize.u32Width = uvcCfg->vi_cfg[chnType].assign_width; + viCtx.stChnAttr.stSize.u32Height = uvcCfg->vi_cfg[chnType].assign_height; + LOG_INFO("chnType:%d uvc out:%dx%d, vi resolution:%dx%d name:%s\n", chnType, + uvcCfg->uvc_cfg.width, uvcCfg->uvc_cfg.height, + viCtx.stChnAttr.stSize.u32Width, viCtx.stChnAttr.stSize.u32Height, + viCtx.stChnAttr.stIspOpt.aEntityName); + + return viCtx; +} + +// todo: multi vi from cfg. +RK_S32 uvc_vi_config(UVC_MPI_CFG *uvcCfg, MpiViChannelType chnType) { + RK_S32 s32Ret = RK_FAILURE; + MPI_VI_CTX_S ctx; + ctx = uvc_get_vi_ctx(uvcCfg, chnType); + + // 0. get dev config status + s32Ret = RK_MPI_VI_GetDevAttr(ctx.stChnCtx.devId, &ctx.stDevAttr); + if (s32Ret == RK_ERR_VI_NOT_CONFIG) { + // 0-1.config dev + s32Ret = RK_MPI_VI_SetDevAttr(ctx.stChnCtx.devId, &ctx.stDevAttr); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VI_SetDevAttr %x\n", s32Ret); + goto __FAILED; + } + } + // 1.get dev enable status + s32Ret = RK_MPI_VI_GetDevIsEnable(ctx.stChnCtx.devId); + if (s32Ret != RK_SUCCESS) { + // 1-2.enable dev + s32Ret = RK_MPI_VI_EnableDev(ctx.stChnCtx.devId); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VI_EnableDev %x\n", s32Ret); + goto __FAILED; + } + // 1-3.bind dev/pipe + ctx.stBindPipe.u32Num = ctx.stChnCtx.pipeId; + ctx.stBindPipe.PipeId[0] = ctx.stChnCtx.pipeId; + s32Ret = RK_MPI_VI_SetDevBindPipe(ctx.stChnCtx.devId, &ctx.stBindPipe); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VI_SetDevBindPipe %x\n", s32Ret); + goto __FAILED; + } + } + // 2.config channel + s32Ret = RK_MPI_VI_SetChnAttr(ctx.stChnCtx.pipeId, ctx.stChnCtx.channelId, + &ctx.stChnAttr); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VI_SetChnAttr %x\n", s32Ret); + goto __FAILED; + } + +__FAILED: + return s32Ret; +} + +RK_S32 uvc_vi_start(UVC_MPI_CFG uvcCfg, MpiViChannelType chnType) { + RK_S32 s32Ret = RK_FAILURE; + UVC_VI_CHN_CTX_S ctx; + ctx = uvc_get_vi_chn_ctx(uvcCfg, chnType); + + // isp&aiq init here + + // 3.enable channel + LOG_INFO("RK_MPI_VI_EnableChn %x %d %d\n", ctx.devId, ctx.pipeId, + ctx.channelId); + s32Ret = RK_MPI_VI_EnableChn(ctx.pipeId, ctx.channelId); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VI_EnableChn %x\n", s32Ret); + goto __FAILED; + } + +__FAILED: + return s32Ret; +} + +RK_S32 uvc_vi_stop(UVC_MPI_CFG uvcCfg, MpiViChannelType chnType) { + RK_S32 s32Ret = RK_FAILURE; + UVC_VI_CHN_CTX_S ctx; + ctx = uvc_get_vi_chn_ctx(uvcCfg, chnType); + + // 5. disable one chn + s32Ret = RK_MPI_VI_DisableChn(ctx.pipeId, ctx.channelId); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VI_DisableChn %x\n", s32Ret); + goto __FAILED; + } + // 6.disable dev(will diabled all chn) + s32Ret = RK_MPI_VI_DisableDev(ctx.devId); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VI_DisableDev %x\n", s32Ret); + goto __FAILED; + } + +// isp&aiq deinit here + +__FAILED: + return s32Ret; +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vi.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vi.h new file mode 100644 index 000000000..e083ed404 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vi.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __UVC_MPI_VI_H__ +#define __UVC_MPI_VI_H__ + +#include "uvc_mpi_config.h" + +typedef struct _uvcViChnCtx { + RK_S32 devId; + RK_S32 pipeId; + RK_S32 channelId; +} UVC_VI_CHN_CTX_S; + +RK_S32 uvc_vi_config(UVC_MPI_CFG *uvcCfg, MpiViChannelType chnType); +RK_S32 uvc_vi_start(UVC_MPI_CFG uvcCfg, MpiViChannelType chnType); +RK_S32 uvc_vi_stop(UVC_MPI_CFG uvcCfg, MpiViChannelType chnType); +UVC_VI_CHN_CTX_S uvc_get_vi_chn_ctx(UVC_MPI_CFG uvcCfg, + MpiViChannelType chnType); + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vpss.cpp b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vpss.cpp new file mode 100755 index 000000000..d60725d66 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vpss.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "uvc_mpi_vpss.h" +#include "rk_mpi_sys.h" +#include "rk_mpi_vpss.h" +#include "uvc_log.h" +#include "uvc_video.h" +#include + +typedef struct _rkVpssCfg { + RK_U32 u32VpssChnCnt; + VPSS_GRP_ATTR_S stGrpVpssAttr; + VPSS_CHN_ATTR_S stVpssChnAttr[VPSS_MAX_CHN_NUM]; +} VPSS_CFG_S; + +typedef struct _rkMpiVpssCtx { + UVC_VPSS_CHN_CTX_S stChnCtx; + VPSS_CFG_S stVpssCfg; +} MPI_VPSS_CTX_S; + +UVC_VPSS_CHN_CTX_S uvc_get_vpss_chn_ctx(UVC_MPI_CFG uvcCfg, + MpiVpssChannelType chnType) { + UVC_VPSS_CHN_CTX_S vpssChnCtx; + memset(&vpssChnCtx, 0, sizeof(UVC_VPSS_CHN_CTX_S)); + + vpssChnCtx.group = uvcCfg.vpss_cfg[chnType].group_id; + vpssChnCtx.channelId = uvcCfg.vpss_cfg[chnType].channel_id; + + return vpssChnCtx; +} + +// todo: read cfg +static MPI_VPSS_CTX_S uvc_get_vpss_ctx(UVC_MPI_CFG uvcCfg, + MpiVpssChannelType chnType) { + MPI_VPSS_CTX_S vpssCtx; + PIXEL_FORMAT_E outFormat = RK_FMT_YUV420SP; + int chn = uvcCfg.vpss_cfg[chnType].channel_id; + + memset(&vpssCtx, 0, sizeof(MPI_VPSS_CTX_S)); + switch (chnType) { + case MPI_VPSS_CHANNEL_TYPE_UVC: + switch (uvcCfg.uvc_cfg.fcc) { + case V4L2_PIX_FMT_YUYV: + outFormat = RK_FMT_YUV422_YUYV; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Depth = + uvcCfg.vpss_cfg[chnType].buf_cnt; + break; + case V4L2_PIX_FMT_NV12: + outFormat = RK_FMT_YUV420SP; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Depth = + uvcCfg.vpss_cfg[chnType].buf_cnt; + break; + case V4L2_PIX_FMT_MJPEG: + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_H265: + outFormat = RK_FMT_YUV420SP; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Depth = 0; // bind venc. + break; + default: + LOG_ERROR("vpss not support this fcc 0x%x\n", uvcCfg.uvc_cfg.fcc); + break; + } + vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Width = uvcCfg.uvc_cfg.width; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Height = uvcCfg.uvc_cfg.height; + break; + case MPI_VPSS_CHANNEL_TYPE_NN: + outFormat = uvcCfg.vpss_cfg[chnType].format; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Width = + uvcCfg.vpss_cfg[chnType].assign_width; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Height = + uvcCfg.vpss_cfg[chnType].assign_height; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Depth = + uvcCfg.vpss_cfg[chnType].buf_cnt; + break; + default: + LOG_ERROR("vpss not support this type 0x%x\n", chnType); + break; + } + + vpssCtx.stChnCtx = uvc_get_vpss_chn_ctx(uvcCfg, chnType); + vpssCtx.stVpssCfg.stGrpVpssAttr.u32MaxW = 4096; + vpssCtx.stVpssCfg.stGrpVpssAttr.u32MaxH = 4096; + vpssCtx.stVpssCfg.stGrpVpssAttr.enPixelFormat = outFormat; + vpssCtx.stVpssCfg.stGrpVpssAttr.stFrameRate.s32SrcFrameRate = + uvcCfg.vpss_cfg[chnType].fps_in; + vpssCtx.stVpssCfg.stGrpVpssAttr.stFrameRate.s32DstFrameRate = + uvcCfg.vpss_cfg[chnType].fps_out; + vpssCtx.stVpssCfg.stGrpVpssAttr.enCompressMode = uvcCfg.vpss_cfg[chnType].fbc; + { // chn + vpssCtx.stVpssCfg.stVpssChnAttr[chn].enChnMode = VPSS_CHN_MODE_USER; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].enDynamicRange = DYNAMIC_RANGE_SDR8; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].enPixelFormat = outFormat; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].stFrameRate.s32SrcFrameRate = -1; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].stFrameRate.s32DstFrameRate = -1; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].enCompressMode = + uvcCfg.vpss_cfg[chnType].fbc; + vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32FrameBufCnt = + uvcCfg.vpss_cfg[chnType].buf_cnt; + } + + return vpssCtx; +} + +RK_S32 uvc_vpss_config(UVC_MPI_CFG *uvcCfg, MpiVpssChannelType chnType) { + RK_S32 s32Ret = RK_FAILURE; + MPI_VPSS_CTX_S ctx; + ctx = uvc_get_vpss_ctx(*uvcCfg, chnType); + + s32Ret = + RK_MPI_VPSS_CreateGrp(ctx.stChnCtx.group, &ctx.stVpssCfg.stGrpVpssAttr); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VPSS_CreateGrp fail 0x%x\n", s32Ret); + return s32Ret; + } + + s32Ret = RK_MPI_VPSS_SetChnAttr( + ctx.stChnCtx.group, ctx.stChnCtx.channelId, + &ctx.stVpssCfg.stVpssChnAttr[ctx.stChnCtx.channelId]); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VPSS_SetChnAttr fail 0x%x\n", s32Ret); + return s32Ret; + } + + return RK_SUCCESS; +} + +// from the data. +RK_S32 uvc_vpss_config_crop(UVC_MPI_CFG uvcCfg, VPSS_CROP_INFO_S stCropInfo, + MpiVpssChannelType chnType) { + RK_S32 s32Ret = RK_FAILURE; + UVC_VPSS_CHN_CTX_S ctx; + ctx = uvc_get_vpss_chn_ctx(uvcCfg, chnType); + + s32Ret = RK_MPI_VPSS_SetChnCrop(ctx.group, ctx.channelId, &stCropInfo); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VPSS_SetChnCrop fail 0x%x\n", s32Ret); + return s32Ret; + } + + return RK_SUCCESS; +} + +RK_S32 uvc_vpss_start(UVC_MPI_CFG uvcCfg, MpiVpssChannelType chnType) { + RK_S32 s32Ret = RK_FAILURE; + UVC_VPSS_CHN_CTX_S ctx; + ctx = uvc_get_vpss_chn_ctx(uvcCfg, chnType); + + s32Ret = RK_MPI_VPSS_EnableChn(ctx.group, ctx.channelId); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VPSS_EnableChn fail 0x%x\n", s32Ret); + return s32Ret; + } + s32Ret = RK_MPI_VPSS_StartGrp(ctx.group); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VPSS_StartGrp fail 0x%x\n", s32Ret); + return s32Ret; + } + + return RK_SUCCESS; +} + +RK_S32 uvc_vpss_stop(UVC_MPI_CFG uvcCfg, MpiVpssChannelType chnType) { + RK_S32 s32Ret = RK_FAILURE; + UVC_VPSS_CHN_CTX_S ctx; + ctx = uvc_get_vpss_chn_ctx(uvcCfg, chnType); + + s32Ret = RK_MPI_VPSS_StopGrp(ctx.group); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VPSS_StopGrp fail 0x%x\n", s32Ret); + return s32Ret; + } + + s32Ret = RK_MPI_VPSS_DisableChn(ctx.group, ctx.channelId); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VPSS_DisableChn fail 0x%x\n", s32Ret); + return s32Ret; + } + + s32Ret = RK_MPI_VPSS_DestroyGrp(ctx.group); + if (s32Ret != RK_SUCCESS) { + LOG_ERROR("RK_MPI_VPSS_DestroyGrp fail 0x%x\n", s32Ret); + return s32Ret; + } + + return RK_SUCCESS; +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vpss.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vpss.h new file mode 100755 index 000000000..9e4f07513 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vpss.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __UVC_MPI_VPSS_H__ +#define __UVC_MPI_VPSS_H__ + +#include "uvc_mpi_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _uvcVpssChnCtx { + RK_S32 group; + RK_S32 channelId; +} UVC_VPSS_CHN_CTX_S; + +RK_S32 uvc_vpss_config(UVC_MPI_CFG *uvcCfg, MpiVpssChannelType chnType); +RK_S32 uvc_vpss_config_crop(UVC_MPI_CFG uvcCfg, VPSS_CROP_INFO_S stCropInfo, + MpiVpssChannelType chnType); +RK_S32 uvc_vpss_start(UVC_MPI_CFG uvcCfg, MpiVpssChannelType chnType); +RK_S32 uvc_vpss_stop(UVC_MPI_CFG uvcCfg, MpiVpssChannelType chnType); +UVC_VPSS_CHN_CTX_S uvc_get_vpss_chn_ctx(UVC_MPI_CFG uvcCfg, + MpiVpssChannelType chnType); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_process.cpp b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_process.cpp new file mode 100644 index 000000000..c4a1b0ba7 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_process.cpp @@ -0,0 +1,1036 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "uvc_process.h" +#include "osd.h" +#include "uvc_mpi_config.h" +#include "uvc_mpi_venc.h" +#include "uvc_mpi_vi.h" +#include "uvc_mpi_vpss.h" +#include "uvc_video.h" + +#include "uvc_log.h" +#include +#include +#include +#include + +#include "rk_common.h" +#include "rk_mpi_mb.h" +#include "rk_mpi_rgn.h" +#include "rk_mpi_sys.h" +#include +#include + +#define UVC_DYNAMIC_DEBUG_OUT_CHECK "/tmp/uvc_out" +#define UVC_DYNAMIC_DEBUG_FPS "/tmp/uvc_fps" + +static pthread_mutex_t gUvcProcessLock = PTHREAD_MUTEX_INITIALIZER; +static UVCProcess *gUvcProcess[CAM_MAX_NUM]; + +typedef enum _UVC_FMT_TYPE { + UVC_FMT_TYPE_DEBUG_YUYV_UVC = 0, // for debug + UVC_FMT_TYPE_VI_UVC, // now only run VI_VPSS_UVC + UVC_FMT_TYPE_VI_VENC_UVC, // now only run VI_VPSS_VENC_UVC + UVC_FMT_TYPE_VI_VPSS_UVC, + UVC_FMT_TYPE_VI_VPSS_VENC_UVC, + UVC_FMT_TYPE_MAX, +} UVCFmtType; + +typedef struct _UVC_PROCESS_BUFF { + int fd; + void *frame; +} UVCProcessBuff; + +typedef struct _UVC_VENC_TEMP_INFO { + VENC_STREAM_S stVencFrame; + VENC_STREAM_S stReleaseVencFrame; + int recvCnt; + int force_idr_cnt; +} UVCVencTempInfo; + +typedef struct _UVC_DEBUG_FILE_INFO { + int debugCnt; + FILE *pDebugFile; +} UVCDegbuFileInfo; + +typedef struct _UVC_PROCESS_CTX { + UVC_CTRL_INFO mUvcCtx; + UVC_MPI_CFG mUvcCfg; + UVC_VI_CHN_CTX_S viChnCtx; + UVC_VENC_CHN_CTX_S vencChnCtx; + UVC_VPSS_CHN_CTX_S vpssChnCtx; + UVCVencTempInfo vencTempInfo; + UVCProcessBuff *mBuff; + UVCFmtType mFmtType; + UVCDegbuFileInfo mUvcDebug; + int mUvcBuffCount; + bool mStart; + std::thread *mThread; + pthread_cond_t mCond; + pthread_mutex_t mCondMutex; + struct uvc_buffer *mUvcBuf; + // debug + MB_POOL debugPool; + int getBufCnt; + int releaseBufCnt; + // fps debug + struct timeval enterTime; + int sendCount; +} UVCProcessCtx; + +typedef void (*uvc_release_callback)(); + +static UVC_RET_TYPE do_process(UVCProcessCtx *ctx); + +// need to actually test whether need this part for prepare. +extern "C" int uvc_process_config(UVC_CTRL_INFO uvcCtrlInfo) { + RK_S32 s32Ret = RK_FAILURE; + + LOG_INFO( + "index:%d width = %d, height = %d, fcc = %d, fps = %d, auto_eptz = %d\n", + uvcCtrlInfo.index, uvcCtrlInfo.width, uvcCtrlInfo.height, uvcCtrlInfo.fcc, + uvcCtrlInfo.fps, uvcCtrlInfo.eptz[UVC_EPTZ_AUTO]); + + if ((uvcCtrlInfo.fcc == V4L2_PIX_FMT_H264) && + !access("/tmp/use_encodec_h265", 0)) { + LOG_ERROR("force use h265 encodec\n"); + uvcCtrlInfo.fcc = V4L2_PIX_FMT_H265; + } + + if (uvcCtrlInfo.index >= CAM_MAX_NUM) { + LOG_ERROR("index:%d exceed max:%d\n", uvcCtrlInfo.index, CAM_MAX_NUM); + return -1; + } + if (gUvcProcess[0] == NULL) { + // s32Ret = RK_MPI_SYS_Init(); + // if (s32Ret != RK_SUCCESS) { + // LOG_ERROR("RK_MPI_SYS_Init %x\n", s32Ret); + // return -1; + //} + } + if (gUvcProcess[uvcCtrlInfo.index] == NULL) { + LOG_INFO("new uvc process index %d\n", uvcCtrlInfo.index); + gUvcProcess[uvcCtrlInfo.index] = new UVCProcess(); + // configProcess here just do onece. + // gUvcProcess[uvcCtrlInfo.index]->configProcess(uvcCtrlInfo); + } else { + LOG_INFO("old uvc process index %d\n", uvcCtrlInfo.index); + } + return gUvcProcess[uvcCtrlInfo.index]->configProcess(uvcCtrlInfo); +} + +extern "C" int uvc_process_start(UVC_CTRL_INFO uvcCtrlInfo) { + RK_S32 s32Ret = RK_FAILURE; + + LOG_INFO("index:%d width = %d, height = %d, fcc = %d, fps = %d, eptz = %d \n", + uvcCtrlInfo.index, uvcCtrlInfo.width, uvcCtrlInfo.height, + uvcCtrlInfo.fcc, uvcCtrlInfo.fps, uvcCtrlInfo.eptz[UVC_EPTZ_AUTO]); + + if (uvcCtrlInfo.index >= CAM_MAX_NUM) { + LOG_ERROR("index:%d exceed max:%d\n", uvcCtrlInfo.index, CAM_MAX_NUM); + return -1; + } + if (gUvcProcess[uvcCtrlInfo.index]) { + gUvcProcess[uvcCtrlInfo.index]->startProcess(); + } + + return 0; +} + +extern "C" void uvc_process_stop(UVC_CTRL_INFO uvcCtrlInfo) { + LOG_INFO("stop uvc process index %d\n", uvcCtrlInfo.index); + + if (gUvcProcess[uvcCtrlInfo.index]) { + gUvcProcess[uvcCtrlInfo.index]->stopProcess(); + // delete remove to process_delete. + } +} + +extern "C" void uvc_process_delete(UVC_CTRL_INFO uvcCtrlInfo) { + LOG_INFO("delete uvc process index %d %p\n", uvcCtrlInfo.index, + gUvcProcess[uvcCtrlInfo.index]); + + if (gUvcProcess[uvcCtrlInfo.index]) { + delete gUvcProcess[uvcCtrlInfo.index]; + gUvcProcess[uvcCtrlInfo.index] = nullptr; + } +} + +extern "C" int uvc_process_release_frame(UVC_CTRL_INFO uvcCtrlInfo, + void *frame) { + if (gUvcProcess[uvcCtrlInfo.index]) { + gUvcProcess[uvcCtrlInfo.index]->releaseFrame(frame); + } + + return 0; +} + +void _uvc_process_release_frame(UVCProcessCtx *ctx, void *frame) { + MB_BLK blk = (MB_BLK)frame; + if (!blk) { + LOG_ERROR("blk is null\n"); + return; + } + ctx->releaseBufCnt++; + LOG_DEBUG("releaseFrame:%p, cnt:%d\n", blk, ctx->releaseBufCnt); + + switch (ctx->mFmtType) { + case UVC_FMT_TYPE_DEBUG_YUYV_UVC: + RK_MPI_MB_ReleaseMB(blk); + break; + case UVC_FMT_TYPE_VI_UVC: + VIDEO_FRAME_INFO_S stViFrameInfo; + stViFrameInfo.stVFrame.pMbBlk = blk; + RK_MPI_VI_ReleaseChnFrame(ctx->viChnCtx.pipeId, ctx->viChnCtx.channelId, + &stViFrameInfo); + break; + case UVC_FMT_TYPE_VI_VPSS_UVC: + VIDEO_FRAME_INFO_S stVpssFrameInfo; + stVpssFrameInfo.stVFrame.pMbBlk = blk; + RK_MPI_VPSS_ReleaseChnFrame(ctx->vpssChnCtx.group, + ctx->vpssChnCtx.channelId, &stVpssFrameInfo); + break; + case UVC_FMT_TYPE_VI_VENC_UVC: + case UVC_FMT_TYPE_VI_VPSS_VENC_UVC: + ctx->vencTempInfo.stReleaseVencFrame.pstPack->pMbBlk = blk; + RK_MPI_VENC_ReleaseStream(ctx->vencChnCtx.channelId, + &ctx->vencTempInfo.stReleaseVencFrame); + break; + default: + LOG_ERROR("not support this type:%d\n", ctx->mFmtType); + break; + } +} + +UVCProcessCtx *getUVCProcessCtx(void *ctx) { + return reinterpret_cast(ctx); +} + +int UVCProcess::initialize() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + uvc_mpi_cfg_set_default(&ctx->mUvcCfg); + + return 0; +} + +int UVCProcess::deinitialize() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + + if (ctx) + free(ctx); + + return 0; +} + +UVCProcess::UVCProcess() : mCtx(NULL) { + UVCProcessCtx *ctx = (UVCProcessCtx *)calloc(sizeof(UVCProcessCtx), 1); + mCtx = reinterpret_cast(ctx); + + initialize(); +} + +UVCProcess::~UVCProcess() { deinitialize(); } + +int UVCProcess::configVi() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); +#ifndef RK_ENABLE_FASTBOOT + uvc_vi_config(&ctx->mUvcCfg, MPI_VI_CHANNEL_TYPE_UVC); +#endif + ctx->viChnCtx = uvc_get_vi_chn_ctx(ctx->mUvcCfg, MPI_VI_CHANNEL_TYPE_UVC); + + return 0; +} + +int UVCProcess::configVenc() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); +#ifndef RK_ENABLE_FASTBOOT + uvc_venc_config(&ctx->mUvcCfg); +#endif + ctx->vencChnCtx = uvc_get_venc_chn_ctx(ctx->mUvcCfg); + + return 0; +} + +int UVCProcess::configVpss() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + uvc_vpss_config(&ctx->mUvcCfg, MPI_VPSS_CHANNEL_TYPE_UVC); + ctx->vpssChnCtx = + uvc_get_vpss_chn_ctx(ctx->mUvcCfg, MPI_VPSS_CHANNEL_TYPE_UVC); + + return 0; +} + +int UVCProcess::startVi() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); +#ifndef RK_ENABLE_FASTBOOT + uvc_vi_start(ctx->mUvcCfg, MPI_VI_CHANNEL_TYPE_UVC); +#endif + return 0; +} + +int UVCProcess::stopVi() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); +#ifndef RK_ENABLE_FASTBOOT + uvc_vi_stop(ctx->mUvcCfg, MPI_VI_CHANNEL_TYPE_UVC); +#endif + return 0; +} + +int UVCProcess::startVpss() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + uvc_vpss_start(ctx->mUvcCfg, MPI_VPSS_CHANNEL_TYPE_UVC); + + return 0; +} + +int UVCProcess::stopVpss() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + uvc_vpss_stop(ctx->mUvcCfg, MPI_VPSS_CHANNEL_TYPE_UVC); + + return 0; +} + +int UVCProcess::startVenc() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); +#ifndef RK_ENABLE_FASTBOOT + uvc_venc_start(ctx->mUvcCfg); +#endif + ctx->vencTempInfo.stVencFrame.pstPack = + reinterpret_cast(malloc(sizeof(VENC_PACK_S))); + ctx->vencTempInfo.stReleaseVencFrame.pstPack = + reinterpret_cast(malloc(sizeof(VENC_PACK_S))); + + return 0; +} + +int UVCProcess::stopVenc() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + uvc_venc_stop(ctx->mUvcCfg); + if (ctx->vencTempInfo.stVencFrame.pstPack) + free(ctx->vencTempInfo.stVencFrame.pstPack); + if (ctx->vencTempInfo.stReleaseVencFrame.pstPack) + free(ctx->vencTempInfo.stReleaseVencFrame.pstPack); + + return 0; +} + +int UVCProcess::bindViVpss() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + int ret; + MPP_CHN_S mSrcChn; + MPP_CHN_S mDestChn; + + mSrcChn.enModId = RK_ID_VI; + mSrcChn.s32DevId = ctx->viChnCtx.devId; + mSrcChn.s32ChnId = ctx->viChnCtx.channelId; + mDestChn.enModId = RK_ID_VPSS; + mDestChn.s32DevId = ctx->vpssChnCtx.group; + mDestChn.s32ChnId = ctx->vpssChnCtx.channelId; + ret = RK_MPI_SYS_Bind(&mSrcChn, &mDestChn); + + return ret; +} + +int UVCProcess::unBindViVpss() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + int ret; + MPP_CHN_S mSrcChn; + MPP_CHN_S mDestChn; + + mSrcChn.enModId = RK_ID_VI; + mSrcChn.s32DevId = ctx->viChnCtx.devId; + mSrcChn.s32ChnId = ctx->viChnCtx.channelId; + mDestChn.enModId = RK_ID_VPSS; + mDestChn.s32DevId = ctx->vpssChnCtx.group; + mDestChn.s32ChnId = ctx->vpssChnCtx.channelId; + ret = RK_MPI_SYS_UnBind(&mSrcChn, &mDestChn); + + return ret; +} + +int UVCProcess::bindViVenc() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + int ret; + MPP_CHN_S mSrcChn; + MPP_CHN_S mDestChn; + + mSrcChn.enModId = RK_ID_VI; + mSrcChn.s32DevId = ctx->viChnCtx.devId; + mSrcChn.s32ChnId = ctx->viChnCtx.channelId; + mDestChn.enModId = RK_ID_VENC; + mDestChn.s32DevId = ctx->vencChnCtx.devId; + mDestChn.s32ChnId = ctx->vencChnCtx.channelId; + ret = RK_MPI_SYS_Bind(&mSrcChn, &mDestChn); + + return ret; +} + +int UVCProcess::unBindViVenc() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + int ret; + MPP_CHN_S mSrcChn; + MPP_CHN_S mDestChn; + + mSrcChn.enModId = RK_ID_VI; + mSrcChn.s32DevId = ctx->viChnCtx.devId; + mSrcChn.s32ChnId = ctx->viChnCtx.channelId; + mDestChn.enModId = RK_ID_VENC; + mDestChn.s32DevId = ctx->vencChnCtx.devId; + mDestChn.s32ChnId = ctx->vencChnCtx.channelId; + ret = RK_MPI_SYS_UnBind(&mSrcChn, &mDestChn); + + return ret; +} + +int UVCProcess::bindVpssVenc() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + int ret; + MPP_CHN_S mSrcChn; + MPP_CHN_S mDestChn; + + mSrcChn.enModId = RK_ID_VPSS; + mSrcChn.s32DevId = ctx->vpssChnCtx.group; + mSrcChn.s32ChnId = ctx->vpssChnCtx.channelId; + mDestChn.enModId = RK_ID_VENC; + mDestChn.s32DevId = ctx->vencChnCtx.devId; + mDestChn.s32ChnId = ctx->vencChnCtx.channelId; + ret = RK_MPI_SYS_Bind(&mSrcChn, &mDestChn); + + return ret; +} + +int UVCProcess::unBindVpssVenc() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + int ret; + MPP_CHN_S mSrcChn; + MPP_CHN_S mDestChn; + + mSrcChn.enModId = RK_ID_VPSS; + mSrcChn.s32DevId = ctx->vpssChnCtx.group; + mSrcChn.s32ChnId = ctx->vpssChnCtx.channelId; + mDestChn.enModId = RK_ID_VENC; + mDestChn.s32DevId = ctx->vencChnCtx.devId; + mDestChn.s32ChnId = ctx->vencChnCtx.channelId; + ret = RK_MPI_SYS_UnBind(&mSrcChn, &mDestChn); + + return ret; +} + +int UVCProcess::configProcess(UVC_CTRL_INFO uvcCtrlInfo) { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + int32_t use_time_us, now_time_us, last_time_us; + struct timespec now_tm = {0, 0}; + int check_ret; + + if (memcmp(&ctx->mUvcCtx, &uvcCtrlInfo, sizeof(UVC_CTRL_INFO))) { + LOG_INFO("index:%d config process paramter change.\n", uvcCtrlInfo.index); + memcpy(&ctx->mUvcCtx, &uvcCtrlInfo, sizeof(UVC_CTRL_INFO)); + ctx->mUvcCfg.index = uvcCtrlInfo.index; + ctx->mUvcCfg.uvc_cfg.width = uvcCtrlInfo.width; + ctx->mUvcCfg.uvc_cfg.height = uvcCtrlInfo.height; + ctx->mUvcCfg.uvc_cfg.fps = uvcCtrlInfo.fps; + ctx->mUvcCfg.uvc_cfg.fcc = uvcCtrlInfo.fcc; + + clock_gettime(CLOCK_MONOTONIC, &now_tm); + last_time_us = now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; // us + check_ret = check_uvc_mpi_cfg_file_init(&ctx->mUvcCfg); + if (check_ret) { + // when not config need set this change here + ctx->mUvcCfg.venc_cfg.common_cfg.change |= + MPI_VENC_COMMON_CFG_CHANGE_CREATE; + } + clock_gettime(CLOCK_MONOTONIC, &now_tm); + now_time_us = now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; // us + use_time_us = now_time_us - last_time_us; + LOG_INFO("check_uvc_mpi_cfg_file_init time:%d us\n", use_time_us); + + // choice the vi uvc fmt + switch (ctx->mUvcCtx.fcc) { + case V4L2_PIX_FMT_YUYV: + if (ctx->mUvcCfg.common_cfg.uvc_enable_vpss) + ctx->mFmtType = UVC_FMT_TYPE_VI_VPSS_UVC; + else + ctx->mFmtType = UVC_FMT_TYPE_VI_UVC; + ctx->mUvcBuffCount = + ctx->mUvcCfg.vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].buf_cnt + + ctx->mUvcCfg.vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].buf_cnt; + if (ctx->mUvcCfg.common_cfg.yuyv_debug) + ctx->mFmtType = UVC_FMT_TYPE_DEBUG_YUYV_UVC; + // tmp for workaround vpss stuck + ctx->mUvcBuffCount = 1; + + break; + case V4L2_PIX_FMT_NV12: // reserver + if (ctx->mUvcCfg.common_cfg.uvc_enable_vpss) + ctx->mFmtType = UVC_FMT_TYPE_VI_VPSS_UVC; + else + ctx->mFmtType = UVC_FMT_TYPE_VI_UVC; + ctx->mUvcBuffCount = + ctx->mUvcCfg.vi_cfg[MPI_VI_CHANNEL_TYPE_UVC].buf_cnt + + ctx->mUvcCfg.vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].buf_cnt; + break; + case V4L2_PIX_FMT_MJPEG: + if (ctx->mUvcCfg.common_cfg.uvc_enable_vpss) { + ctx->mFmtType = UVC_FMT_TYPE_VI_VPSS_VENC_UVC; + ctx->mUvcBuffCount = + ctx->mUvcCfg.venc_cfg.mjpeg_cfg.buf_cnt + + ctx->mUvcCfg.vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].buf_cnt; + } else { + ctx->mFmtType = UVC_FMT_TYPE_VI_VENC_UVC; + ctx->mUvcBuffCount = ctx->mUvcCfg.venc_cfg.mjpeg_cfg.buf_cnt; + } + ctx->vencTempInfo.force_idr_cnt = 0; + break; + case V4L2_PIX_FMT_H264: + if (ctx->mUvcCfg.common_cfg.uvc_enable_vpss) { + ctx->mFmtType = UVC_FMT_TYPE_VI_VPSS_VENC_UVC; + ctx->mUvcBuffCount = + ctx->mUvcCfg.venc_cfg.h264_cfg.buf_cnt + + ctx->mUvcCfg.vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].buf_cnt; + } else { + ctx->mFmtType = UVC_FMT_TYPE_VI_VENC_UVC; + ctx->mUvcBuffCount = ctx->mUvcCfg.venc_cfg.h264_cfg.buf_cnt; + } + + ctx->vencTempInfo.force_idr_cnt = + ctx->mUvcCfg.venc_cfg.common_cfg.idr_gop * + ctx->mUvcCfg.venc_cfg.common_cfg.idr_cnt; + + break; + case V4L2_PIX_FMT_H265: + if (ctx->mUvcCfg.common_cfg.uvc_enable_vpss) { + ctx->mFmtType = UVC_FMT_TYPE_VI_VPSS_VENC_UVC; + ctx->mUvcBuffCount = + ctx->mUvcCfg.venc_cfg.h265_cfg.buf_cnt + + ctx->mUvcCfg.vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].buf_cnt; + } else { + ctx->mFmtType = UVC_FMT_TYPE_VI_VENC_UVC; + ctx->mUvcBuffCount = ctx->mUvcCfg.venc_cfg.h265_cfg.buf_cnt; + } + + ctx->vencTempInfo.force_idr_cnt = + ctx->mUvcCfg.venc_cfg.common_cfg.idr_gop * + ctx->mUvcCfg.venc_cfg.common_cfg.idr_cnt; + break; + default: + LOG_ERROR("process not support this fcc 0x%x\n", ctx->mUvcCtx.fcc); + break; + } + + switch (ctx->mFmtType) { + case UVC_FMT_TYPE_DEBUG_YUYV_UVC: + LOG_INFO("uvc debug\n"); + ctx->mUvcBuffCount = 3; + break; + case UVC_FMT_TYPE_VI_UVC: + configVi(); + break; + case UVC_FMT_TYPE_VI_VPSS_UVC: + configVi(); + configVpss(); + break; + case UVC_FMT_TYPE_VI_VENC_UVC: + configVi(); + configVenc(); + break; + case UVC_FMT_TYPE_VI_VPSS_VENC_UVC: + configVi(); + configVpss(); + configVenc(); + break; + default: + LOG_ERROR("not support this type:%d\n", ctx->mFmtType); + break; + } + } + + return ctx->mUvcBuffCount; +} + +int UVCProcess::configCropScale(RECT_S src, RECT_S dst) { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + VPSS_CROP_INFO_S stCropInfo; + memset(&stCropInfo, 0, sizeof(VPSS_CROP_INFO_S)); + + if (memcmp(&src, &dst, sizeof(RECT_S))) { + stCropInfo.bEnable = RK_TRUE; + stCropInfo.enCropCoordinate = VPSS_CROP_ABS_COOR; + stCropInfo.stCropRect = dst; + } else { // workaround + // stCropInfo.bEnable = RK_FALSE; + stCropInfo.bEnable = RK_TRUE; + stCropInfo.enCropCoordinate = VPSS_CROP_ABS_COOR; + stCropInfo.stCropRect = dst; + } + uvc_vpss_config_crop(ctx->mUvcCfg, stCropInfo, MPI_VPSS_CHANNEL_TYPE_UVC); + + return 0; +} + +int UVCProcess::resetCtx() { + RK_S32 s32Ret; + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + + if (ctx->mBuff) { + free(ctx->mBuff); + ctx->mBuff = nullptr; + } + if (ctx->mUvcBuf) + ctx->mUvcBuf = nullptr; + if (ctx->mUvcDebug.pDebugFile) + fclose(ctx->mUvcDebug.pDebugFile); + memset(&ctx->mUvcDebug, 0, sizeof(UVCDegbuFileInfo)); + memset(&ctx->mUvcCtx, 0, sizeof(UVC_CTRL_INFO)); + ctx->vencTempInfo.recvCnt = 0; + ctx->getBufCnt = 0; + ctx->releaseBufCnt = 0; + + return 0; +} + +int UVCProcess::startProcess() { + RK_S32 s32Ret; + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + ctx->mBuff = + (UVCProcessBuff *)calloc(sizeof(UVCProcessBuff), ctx->mUvcBuffCount); + + switch (ctx->mFmtType) { + case UVC_FMT_TYPE_DEBUG_YUYV_UVC: + MB_POOL_CONFIG_S stMbPoolCfg; + memset(&stMbPoolCfg, 0, sizeof(MB_POOL_CONFIG_S)); + stMbPoolCfg.u64MBSize = + ctx->mUvcCfg.uvc_cfg.width * ctx->mUvcCfg.uvc_cfg.height * 2; + stMbPoolCfg.u32MBCnt = 3; + stMbPoolCfg.enAllocType = MB_ALLOC_TYPE_DMA; + stMbPoolCfg.bPreAlloc = RK_TRUE; + ctx->debugPool = RK_MPI_MB_CreatePool(&stMbPoolCfg); + break; + case UVC_FMT_TYPE_VI_UVC: + startVi(); + break; + case UVC_FMT_TYPE_VI_VPSS_UVC: + startVi(); + startVpss(); + bindViVpss(); + break; + case UVC_FMT_TYPE_VI_VENC_UVC: + startVi(); + startVenc(); +#ifndef RK_ENABLE_FASTBOOT + bindViVenc(); +#endif + break; + case UVC_FMT_TYPE_VI_VPSS_VENC_UVC: + startVi(); + startVpss(); + startVenc(); + bindViVpss(); + bindVpssVenc(); + break; + default: + LOG_ERROR("not support this type:%d\n", ctx->mFmtType); + break; + } + + ctx->mStart = true; + // if use one thread do uvc. do not call this thread + ctx->mThread = new std::thread(threadLoop, reinterpret_cast(this)); + + if (ctx->mUvcCfg.osd_cfg.enable) + osd_start(&ctx->mUvcCfg); + + return 0; +} + +int UVCProcess::stopProcess() { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + + ctx->mStart = false; + if (ctx->mThread) { + ctx->mThread->join(); + delete ctx->mThread; + ctx->mThread = nullptr; + } + + if (ctx->mUvcCfg.osd_cfg.enable) + osd_stop(&ctx->mUvcCfg); + + uvc_buffer_deinit(ctx->mUvcCtx.video_id); + switch (ctx->mFmtType) { + case UVC_FMT_TYPE_DEBUG_YUYV_UVC: + RK_MPI_MB_DestroyPool(ctx->debugPool); + break; + case UVC_FMT_TYPE_VI_UVC: + stopVi(); + break; + case UVC_FMT_TYPE_VI_VENC_UVC: +#ifndef RK_ENABLE_FASTBOOT + unBindViVenc(); + stopVenc(); + stopVi(); +#endif + break; + case UVC_FMT_TYPE_VI_VPSS_UVC: + unBindViVpss(); + stopVpss(); + stopVi(); + break; + case UVC_FMT_TYPE_VI_VPSS_VENC_UVC: + unBindViVpss(); + unBindVpssVenc(); + stopVenc(); + stopVpss(); + stopVi(); + break; + default: + LOG_ERROR("not support this type:%d\n", ctx->mFmtType); + break; + } + resetCtx(); + + return 0; +} + +int UVCProcess::releaseFrame(void *frame) { + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + _uvc_process_release_frame(ctx, frame); + + return 0; +} + +// reserver for one thread +int UVCProcess::doProcess() { + RK_S32 s32Ret; + UVCProcessCtx *ctx = getUVCProcessCtx(mCtx); + int ret; + + ret = do_process(ctx); + + return ret; +} + +UVC_RET_TYPE queue_uvc_buf(UVCProcessCtx *ctx) { + if (!ctx->mUvcBuf) { + ctx->mUvcBuf = uvc_buffer_write_get(ctx->mUvcCtx.video_id); + LOG_DEBUG("uvc_buffer_write_get (buf: %p)\n", ctx->mUvcBuf); + } + + return UVC_RET_OK; +} + +UVC_RET_TYPE dequeue_uvc_buf(UVCProcessCtx *ctx, void *frame) { + VIDEO_FRAME_INFO_S *videoFrame; + VENC_STREAM_S *vencFrame; + int idx = 0; + + if (ctx->mUvcBuf) { + struct uvc_buffer uvc_buf; + memcpy(&uvc_buf, ctx->mUvcBuf, sizeof(struct uvc_buffer)); + + switch (ctx->mFmtType) { + case UVC_FMT_TYPE_DEBUG_YUYV_UVC: + case UVC_FMT_TYPE_VI_UVC: + case UVC_FMT_TYPE_VI_VPSS_UVC: + videoFrame = reinterpret_cast(frame); + uvc_buf.frame = reinterpret_cast(videoFrame->stVFrame.pMbBlk); + uvc_buf.buffer = RK_MPI_MB_Handle2VirAddr( + videoFrame->stVFrame.pMbBlk); // for debug file + uvc_buf.fd = RK_MPI_MB_Handle2Fd(videoFrame->stVFrame.pMbBlk); + uvc_buf.seq = videoFrame->stVFrame.u32TimeRef; + uvc_buf.pts = videoFrame->stVFrame.u64PTS; + uvc_buf.size = ctx->mUvcBuf->total_size; // tmp + uvc_buf.offset = 0; + // uvc_buf->size = RK_MPI_MB_GetLength(videoFrame->stVFrame.pMbBlk); // + // need update rockit + RK_MPI_SYS_MmzFlushCache(videoFrame->stVFrame.pMbBlk, RK_TRUE); + // LOG_INFO("uvc_buf->size:%d\n", uvc_buf->size); + break; + case UVC_FMT_TYPE_VI_VENC_UVC: + case UVC_FMT_TYPE_VI_VPSS_VENC_UVC: + vencFrame = reinterpret_cast(frame); + uvc_buf.frame = reinterpret_cast(vencFrame->pstPack->pMbBlk); + uvc_buf.buffer = RK_MPI_MB_Handle2VirAddr( + vencFrame->pstPack->pMbBlk); // for debug file + uvc_buf.fd = RK_MPI_MB_Handle2Fd(vencFrame->pstPack->pMbBlk); + uvc_buf.seq = vencFrame->u32Seq; + uvc_buf.pts = vencFrame->pstPack->u64PTS; + uvc_buf.size = vencFrame->pstPack->u32Len; + uvc_buf.offset = vencFrame->pstPack->u32Offset; + if (vencFrame->pstPack->u32Offset) { + LOG_DEBUG("u32Offset:%d\n", vencFrame->pstPack->u32Offset); + } + break; + default: + LOG_ERROR("not support this fmt:%d\n", ctx->mFmtType); + break; + } + + // for debug file + if (ctx->mUvcCfg.common_cfg.uvc_debug) { + if (ctx->mUvcDebug.pDebugFile && ctx->mUvcCfg.common_cfg.uvc_debug_cnt) { + if (ctx->mFmtType != UVC_FMT_TYPE_VI_VENC_UVC && + ctx->mFmtType != + UVC_FMT_TYPE_VI_VPSS_VENC_UVC) // venc will flush cache + RK_MPI_SYS_MmzFlushCache((MB_BLK)uvc_buf.frame, RK_TRUE); + fwrite(uvc_buf.buffer, 1, uvc_buf.size, ctx->mUvcDebug.pDebugFile); + ctx->mUvcDebug.debugCnt++; + if (ctx->mUvcDebug.debugCnt >= ctx->mUvcCfg.common_cfg.uvc_debug_cnt) { + LOG_INFO("debugCnt:%d, close debug file\n", ctx->mUvcDebug.debugCnt); + fflush(ctx->mUvcDebug.pDebugFile); + fclose(ctx->mUvcDebug.pDebugFile); + ctx->mUvcDebug.pDebugFile = NULL; + ctx->mUvcDebug.debugCnt = -1; + } + } else if (!access(UVC_DYNAMIC_DEBUG_OUT_CHECK, 0) || + (ctx->mUvcDebug.debugCnt == 0 && + ctx->mUvcCfg.common_cfg.uvc_debug_cnt)) { + ctx->mUvcDebug.pDebugFile = + fopen(ctx->mUvcCfg.common_cfg.uvc_debug_file, "w+b"); + if (ctx->mUvcDebug.pDebugFile) { + LOG_INFO("debug out file open\n"); + if (ctx->mFmtType != UVC_FMT_TYPE_VI_VENC_UVC && + ctx->mFmtType != + UVC_FMT_TYPE_VI_VPSS_VENC_UVC) // venc will flush cache + RK_MPI_SYS_MmzFlushCache((MB_BLK)uvc_buf.frame, RK_TRUE); + fwrite(uvc_buf.buffer, 1, uvc_buf.size, ctx->mUvcDebug.pDebugFile); + ctx->mUvcDebug.debugCnt = 1; + if (ctx->mUvcDebug.debugCnt >= + ctx->mUvcCfg.common_cfg.uvc_debug_cnt) { + LOG_INFO("debugCnt:%d, close debug file\n", + ctx->mUvcDebug.debugCnt); + fflush(ctx->mUvcDebug.pDebugFile); + fclose(ctx->mUvcDebug.pDebugFile); + ctx->mUvcDebug.pDebugFile = NULL; + ctx->mUvcDebug.debugCnt = -1; + } + } + if (!access(UVC_DYNAMIC_DEBUG_OUT_CHECK, 0)) { + char cmd[30]; + sprintf(cmd, "rm %s", UVC_DYNAMIC_DEBUG_OUT_CHECK); + system(cmd); + } + } + } + + for (int i = 0; i < ctx->mUvcBuffCount; i++) { + if (uvc_buf.fd == ctx->mBuff[i].fd && + uvc_buf.frame == ctx->mBuff[i].frame) { + idx = i; + break; + } else if (ctx->mBuff[i].fd) { + idx++; + } + } + if (idx == ctx->mUvcBuffCount) { + LOG_DEBUG("exceed max uvc buf:%d, abdon mb:%p\n", ctx->mUvcBuffCount, + uvc_buf.frame); + _uvc_process_release_frame(ctx, uvc_buf.frame); + } else { + uvc_buf.index = idx; + ctx->mBuff[idx].fd = uvc_buf.fd; + ctx->mBuff[idx].frame = uvc_buf.frame; + memcpy(ctx->mUvcBuf, &uvc_buf, sizeof(struct uvc_buffer)); + uvc_buffer_read_set(ctx->mUvcCtx.video_id, ctx->mUvcBuf); + LOG_DEBUG("debug info!idx:%d frame mb:%p uvc_buf->fd:%d size=%d " + "uvc_buf->seq:%d \n", + idx, uvc_buf.frame, uvc_buf.fd, uvc_buf.size, uvc_buf.seq); + ctx->mUvcBuf = NULL; + if (ctx->mUvcCfg.common_cfg.uvc_debug && + !access(UVC_DYNAMIC_DEBUG_FPS, 0)) { + ctx->sendCount++; + if (ctx->sendCount % 100 == 0) { + struct timeval now_time; + gettimeofday(&now_time, NULL); + int64_t use_timems = + (now_time.tv_sec * 1000 + now_time.tv_usec / 1000) - + (ctx->enterTime.tv_sec * 1000 + ctx->enterTime.tv_usec / 1000); + ctx->enterTime.tv_sec = now_time.tv_sec; + ctx->enterTime.tv_usec = now_time.tv_usec; + LOG_INFO("uvc process fps:%0.1f\n", (1000.0 * 100) / use_timems); + } + } + } + ctx->getBufCnt++; + LOG_DEBUG("get buff cnt:%d\n", ctx->getBufCnt); + } + + return UVC_RET_OK; +} + +static RK_S32 uvc_out_yuyv_debug(UVCProcessCtx *ctx, + VIDEO_FRAME_INFO_S *videoFrame) { + static int debugCnt; + MB_BLK blk; + RK_U8 *p; + int width, height, x, y; + width = ctx->mUvcCfg.uvc_cfg.width; + height = ctx->mUvcCfg.uvc_cfg.height; + blk = RK_MPI_MB_GetMB(ctx->debugPool, width * height * 2, RK_FALSE); + if (!blk) { + usleep(10 * 1000); + return RK_FAILURE; + } + p = (RK_U8 *)RK_MPI_MB_Handle2VirAddr(blk); + + debugCnt++; + for (y = 0; y < height; y++, p += width * 2) { + for (x = 0; x < width / 2; x++) { + p[x * 4 + 0] = x * 2 + 0 + y + debugCnt * 3; + p[x * 4 + 2] = x * 2 + 1 + y + debugCnt * 3; + p[x * 4 + 1] = 128 + y / 2 + debugCnt * 2; + p[x * 4 + 3] = 64 + x + debugCnt * 5; + } + } + + RK_MPI_SYS_MmzFlushCache(blk, RK_TRUE); + videoFrame->stVFrame.pMbBlk = blk; + + return RK_SUCCESS; +} + +static UVC_RET_TYPE uvc_out_yuv_process(UVCProcessCtx *ctx) { + VIDEO_FRAME_INFO_S videoFrame; + RK_S32 s32Ret; + UVC_RET_TYPE ret = UVC_RET_WAT; + + queue_uvc_buf(ctx); + if (!ctx->mUvcBuf) { + LOG_DEBUG("uvc_buffer_write_get null buff\n"); + usleep(2 * 1000); + } else { + if (ctx->mFmtType == UVC_FMT_TYPE_VI_UVC) + s32Ret = RK_MPI_VI_GetChnFrame(ctx->viChnCtx.pipeId, + ctx->viChnCtx.channelId, &videoFrame, 33); + else if (ctx->mFmtType == UVC_FMT_TYPE_VI_VPSS_UVC) + s32Ret = RK_MPI_VPSS_GetChnFrame( + ctx->vpssChnCtx.group, ctx->vpssChnCtx.channelId, &videoFrame, 33); + else if (ctx->mFmtType == UVC_FMT_TYPE_DEBUG_YUYV_UVC) + s32Ret = uvc_out_yuyv_debug(ctx, &videoFrame); + else + ret = UVC_RET_ERR; + + if (s32Ret == RK_SUCCESS) { + ret = dequeue_uvc_buf(ctx, (void *)&videoFrame); + } else { + LOG_DEBUG("get yuv timeout:0x%x\n", s32Ret); + // usleep(5*1000); // wait + } + } + + return ret; +} + +static UVC_RET_TYPE uvc_out_venc_process(UVCProcessCtx *ctx) { + RK_S32 s32Ret; + UVC_RET_TYPE ret = UVC_RET_WAT; + + queue_uvc_buf(ctx); + // LOG_INFO("test lqh\n"); + if (!ctx->mUvcBuf) { + LOG_DEBUG("uvc_buffer_write_get null buff\n"); + usleep(2 * 1000); + } else { + s32Ret = RK_MPI_VENC_GetStream(ctx->vencChnCtx.channelId, + &ctx->vencTempInfo.stVencFrame, 33); + if (s32Ret == RK_SUCCESS) { + ret = dequeue_uvc_buf(ctx, (void *)&ctx->vencTempInfo.stVencFrame); + ctx->vencTempInfo.recvCnt++; + } else if (s32Ret == RK_ERR_VENC_NOT_CONFIG) { + LOG_ERROR("venc chn:%d not config\n", ctx->vencChnCtx.channelId); + ret = UVC_RET_ERR; + } else { + LOG_DEBUG("get venc timeout:0x%x\n", s32Ret); + // usleep(5*1000); // wait + } + } + + return ret; +} + +// uvc_video can call this func direct to reduce thread use. +static UVC_RET_TYPE do_process(UVCProcessCtx *ctx) { + UVC_RET_TYPE ret = UVC_RET_OK; + + switch (ctx->mFmtType) { + case UVC_FMT_TYPE_DEBUG_YUYV_UVC: + case UVC_FMT_TYPE_VI_UVC: + case UVC_FMT_TYPE_VI_VPSS_UVC: + ret = uvc_out_yuv_process(ctx); + break; + case UVC_FMT_TYPE_VI_VENC_UVC: + case UVC_FMT_TYPE_VI_VPSS_VENC_UVC: + ret = uvc_out_venc_process(ctx); + break; + default: + LOG_ERROR("not support this type:%d\n", ctx->mFmtType); + ret = UVC_RET_ERR; + break; + } +#if 0 // reduce thread do this + if (ctx->mUvcCfg.common_cfg.nn_enable) { + int32_t use_time_us, now_time_us, last_time_us; + struct timespec now_tm = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &now_tm); + last_time_us = now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; // us + ctx->nnCtx->doProcess(); + clock_gettime(CLOCK_MONOTONIC, &now_tm); + now_time_us = now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; // us + use_time_us = now_time_us - last_time_us; + LOG_INFO("nn process use time:%d us\n", use_time_us); + } +#endif + + return ret; +} + +void *UVCProcess::threadLoop(void *arg) { + prctl(PR_SET_NAME, "uvcProcessThread"); + UVCProcess *uvcProcess = reinterpret_cast(arg); + UVCProcessCtx *ctx = getUVCProcessCtx(uvcProcess->getCtx()); + UVC_RET_TYPE ret = UVC_RET_OK; + + // wait uvc streamon + while (ctx->mStart && (!uvc_get_user_run_state(ctx->mUvcCtx.video_id) || + !uvc_buffer_write_enable(ctx->mUvcCtx.video_id))) { + usleep(10 * 1000); + } + + // when streamon start + while (ctx->mStart) { + ret = do_process(ctx); + if (ret == UVC_RET_ERR) + break; + } + LOG_INFO("thread type:%d exit ret:%d\n", ctx->mFmtType, ret); + + return NULL; +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_process.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_process.h new file mode 100755 index 000000000..c35e28564 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_process.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __UVC_PROCESS_H__ +#define __UVC_PROCESS_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "rk_comm_video.h" +#include "uvc_process_unit.h" + +#ifdef __cplusplus +} +#endif + +class UVCProcess { +public: + explicit UVCProcess(); + ~UVCProcess(); + void *getCtx() { return mCtx; } + int configProcess(UVC_CTRL_INFO uvc_ctrl_info); + int startProcess(); + int stopProcess(); + int doProcess(); + int releaseFrame(void *frame); + +private: + int initialize(); + int deinitialize(); + int configVi(); + int startVi(); + int stopVi(); + int configVenc(); + int startVenc(); + int stopVenc(); + int resetCtx(); + int configVpss(); + int configCropScale(RECT_S src, RECT_S dst); + int startVpss(); + int stopVpss(); + int bindViVenc(); + int unBindViVenc(); + int bindViVpss(); + int unBindViVpss(); + int bindVpssVenc(); + int unBindVpssVenc(); + static void *threadLoop(void *arg); + +private: + void *mCtx; +}; + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_process_unit.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_process_unit.h new file mode 100755 index 000000000..983d4bfb1 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_process_unit.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __UVC_PROCESS_UNIT_H__ +#define __UVC_PROCESS_UNIT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define CAM_MAX_NUM 3 + +typedef enum _UVC_EPTZ_TYPE { + UVC_EPTZ_ZOOM = 0, + UVC_EPTZ_PAN = 1, + UVC_EPTZ_TILT = 2, + UVC_EPTZ_ROLL = 3, // reserve + UVC_EPTZ_AUTO = 4, + UVC_EPTZ_MAX, +} UVC_EPTZ_TYPE; + +typedef enum _UVC_RATIO_TYPE { + VERTICAL = 0, + HORIZONTAL = 1, + UVC_RATIO_MAX, +} UVC_RATIO_TYPE; + +typedef enum _UVC_RET_TYPE { + UVC_RET_ERR = -1, + UVC_RET_OK = 0, + UVC_RET_WAT = 1, + UVC_RET_MAX, +} UVC_RET_TYPE; + +typedef struct uvc_ctrl_info { + int index; + int width; + int height; + int video_id; + int fcc; + unsigned int fps; + UVC_EPTZ_TYPE type; + int eptz[UVC_EPTZ_MAX]; +} UVC_CTRL_INFO; + +int uvc_process_config(UVC_CTRL_INFO uvc_ctrl_info); +int uvc_process_start(UVC_CTRL_INFO uvc_ctrl_info); +void uvc_process_stop(UVC_CTRL_INFO uvc_ctrl_info); +void uvc_process_delete(UVC_CTRL_INFO uvcCtrlInfo); +int uvc_process_release_frame(UVC_CTRL_INFO uvcCtrlInfo, void *frame); +int nn_process_release_frame_by_id(int frameId); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_video.cpp b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_video.cpp new file mode 100644 index 000000000..23e806f42 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_video.cpp @@ -0,0 +1,1155 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "uvc_video.h" +#include "uvc-gadget.h" +#include "uvc_log.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#if UVC_DYNAMIC_DEBUG_FPS +struct uvc_debug_info_def uvc_debug_info; +#endif + +struct uvc_buffer_list { + std::list buffer_list; + pthread_mutex_t mutex; +}; + +struct video_uvc { + struct uvc_buffer_list write; + struct uvc_buffer_list read; + struct uvc_buffer_list all; + struct uvc_buffer_list cache; + // struct uvc_buffer *cache; + pthread_t id; + bool run; + int video_id; +}; + +static std::list lst_v; +static pthread_mutex_t mtx_v = PTHREAD_MUTEX_INITIALIZER; + +static struct uvc_buffer *uvc_buffer_create(int width, int height, + struct uvc_video *v) { + struct uvc_buffer *buffer = NULL; + + buffer = (struct uvc_buffer *)calloc(1, sizeof(struct uvc_buffer)); + if (!buffer) + return NULL; + buffer->width = width; + buffer->height = height; + buffer->total_size = buffer->width * buffer->height * 2; + buffer->size = 0; // buffer->total_size; + buffer->video_id = v->id; + + LOG_INFO("uvc buffer = %p, total_size=%d\n", buffer, buffer->total_size); + + return buffer; +} + +static void uvc_buffer_push_back(struct uvc_buffer_list *uvc_buffer, + struct uvc_buffer *buffer) { + pthread_mutex_lock(&uvc_buffer->mutex); + uvc_buffer->buffer_list.push_back(buffer); + pthread_mutex_unlock(&uvc_buffer->mutex); +} + +static struct uvc_buffer * +uvc_buffer_pop_front(struct uvc_buffer_list *uvc_buffer) { + struct uvc_buffer *buffer = NULL; + + pthread_mutex_lock(&uvc_buffer->mutex); + if (!uvc_buffer->buffer_list.empty()) { + buffer = uvc_buffer->buffer_list.front(); + uvc_buffer->buffer_list.pop_front(); + } + pthread_mutex_unlock(&uvc_buffer->mutex); + return buffer; +} + +static struct uvc_buffer * +uvc_buffer_pop_assign_cache(struct uvc_buffer_list *uvc_buffer_l, + struct uvc_buffer *assign_buffer) { + struct uvc_buffer *buffer = NULL; + + pthread_mutex_lock(&uvc_buffer_l->mutex); + for (std::list::iterator i = + uvc_buffer_l->buffer_list.begin(); + i != uvc_buffer_l->buffer_list.end(); ++i) { + buffer = *i; + if (assign_buffer->fd == buffer->fd && + assign_buffer->frame == buffer->frame) { + uvc_buffer_l->buffer_list.erase(i); + break; + } + } + LOG_DEBUG( + "debug info!uvc_buffer_pop_assign_cache=fd:%d frame:%p uvc_buf:%p\n", + assign_buffer->fd, assign_buffer->frame, buffer); + pthread_mutex_unlock(&uvc_buffer_l->mutex); + return buffer; +} + +static struct uvc_buffer *uvc_buffer_front(struct uvc_buffer_list *uvc_buffer) { + struct uvc_buffer *buffer = NULL; + + pthread_mutex_lock(&uvc_buffer->mutex); + if (!uvc_buffer->buffer_list.empty()) + buffer = uvc_buffer->buffer_list.front(); + else //{printf("buff null\n"); + buffer = NULL; + // } + pthread_mutex_unlock(&uvc_buffer->mutex); + return buffer; +} + +static void _uvc_mpi_buffer_release(uvc_device *dev, struct uvc_buffer *buffer, + bool need_lock) { + if (buffer->frame) { + LOG_DEBUG( + "debug info!uvc_mpi_buffer_destroy fd:%d index:%d buf:%p->mb=%p\n", + buffer->fd, buffer->index, buffer, buffer->frame); + if (need_lock) + uvc_control_release_frame(dev, buffer->frame); + else + uvc_control_release_frame_nonlock(dev, buffer->frame); + } +} + +static void uvc_mpi_buffer_destroy(struct uvc_video *v, + struct uvc_buffer_list *uvc_buffer) { + struct uvc_buffer *buffer = NULL; + + pthread_mutex_lock(&uvc_buffer->mutex); + while (!uvc_buffer->buffer_list.empty()) { + buffer = uvc_buffer->buffer_list.front(); + _uvc_mpi_buffer_release(v->dev, buffer, false); + uvc_buffer->buffer_list.pop_front(); + } + pthread_mutex_unlock(&uvc_buffer->mutex); +} + +static void uvc_buffer_destroy(struct uvc_video *v, + struct uvc_buffer_list *uvc_buffer) { + struct uvc_buffer *buffer = NULL; + + pthread_mutex_lock(&uvc_buffer->mutex); + while (!uvc_buffer->buffer_list.empty()) { + buffer = uvc_buffer->buffer_list.front(); + LOG_INFO("free uvc buffer = %p\n", buffer); + free(buffer); + uvc_buffer->buffer_list.pop_front(); + } + pthread_mutex_unlock(&uvc_buffer->mutex); +} + +static void uvc_buffer_clear(struct uvc_buffer_list *uvc_buffer) { + pthread_mutex_lock(&uvc_buffer->mutex); + uvc_buffer->buffer_list.clear(); + pthread_mutex_unlock(&uvc_buffer->mutex); +} + +static void *uvc_gadget_pthread(void *arg) { + struct uvc_function_config *fc = (struct uvc_function_config *)arg; + int *id = (int *)arg; + + prctl(PR_SET_NAME, "uvc_gadget_pthread", 0, 0, 0); + + uvc_gadget_main(fc); + uvc_set_user_run_state(true, fc->video); + + pthread_exit(NULL); +} + +int uvc_gadget_pthread_create(struct uvc_function_config *fc) { + pthread_t *pid = NULL; + int id = fc->video; + uvc_memset_uvc_user(id); + if ((pid = uvc_video_get_uvc_pid(id))) { + if (pthread_create(pid, NULL, uvc_gadget_pthread, fc)) { + LOG_ERROR("create uvc_gadget_pthread fail!\n"); + return -1; + } + } + return 0; +} + +static int _uvc_video_id_check(int id) { + int ret = 0; + + if (!lst_v.empty()) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + ret = -1; + break; + } + } + } + + return ret; +} + +int uvc_video_id_check(int id) { + int ret = 0; + + pthread_mutex_lock(&mtx_v); + ret = _uvc_video_id_check(id); + pthread_mutex_unlock(&mtx_v); + + return ret; +} + +int uvc_video_id_add(struct uvc_function_config *fc) { + int ret = 0; + int id = fc->video; + + LOG_INFO("add uvc video id: %d\n", id); + + pthread_mutex_lock(&mtx_v); + if (!_uvc_video_id_check(id)) { + struct uvc_video *v = + (struct uvc_video *)calloc(1, sizeof(struct uvc_video)); + if (v) { + v->id = id; + lst_v.push_back(v); + pthread_mutex_unlock(&mtx_v); + uvc_gadget_pthread_create(fc); + pthread_mutex_lock(&mtx_v); + pthread_mutex_init(&v->buffer_mutex, NULL); + pthread_mutex_init(&v->user_mutex, NULL); + ret = 0; + } else { + LOG_ERROR("%s: %d: memory alloc fail.\n", __func__, __LINE__); + ret = -1; + } + } else { + LOG_WARN("%s: %d: %d already exist.\n", __func__, __LINE__, id); + ret = -1; + } + pthread_mutex_unlock(&mtx_v); + + return ret; +} + +void uvc_video_id_remove(int id) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + pthread_mutex_destroy(&l->buffer_mutex); + pthread_mutex_destroy(&l->user_mutex); + free(l); + lst_v.erase(i); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); +} + +int uvc_video_id_get(unsigned int seq) { + int ret = -1; + + pthread_mutex_lock(&mtx_v); + if (!lst_v.empty()) { + unsigned int cnt = 0; + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + if (cnt++ == seq) { + struct uvc_video *l = *i; + ret = l->id; + break; + } + } + } + pthread_mutex_unlock(&mtx_v); + + return ret; +} + +static void uvc_gadget_pthread_exit(int id); + +static int uvc_video_id_exit(int id) { + if (uvc_video_id_check(id)) { + uvc_gadget_pthread_exit(id); + uvc_video_id_remove(id); + return 0; + } + + return -1; +} + +static int _uvc_video_id_exit_all() { + int ret = -1; + + pthread_mutex_lock(&mtx_v); + if (!lst_v.empty()) { + struct uvc_video *l = lst_v.front(); + pthread_mutex_unlock(&mtx_v); + uvc_video_id_exit(l->id); + pthread_mutex_lock(&mtx_v); + ret = 0; + } + pthread_mutex_unlock(&mtx_v); + + return ret; +} + +void uvc_video_id_exit_all() { + while (!_uvc_video_id_exit_all()) + continue; +} + +static void _uvc_video_set_uvc_process(struct uvc_video *v, bool state) { + v->uvc_process = state; +} + +void uvc_video_set_uvc_process(int id, bool state) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + _uvc_video_set_uvc_process(l, state); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); +} + +static bool _uvc_video_get_uvc_process(struct uvc_video *v) { + return v->uvc_process; +} + +bool uvc_video_get_uvc_process(int id) { + bool state = false; + + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + state = _uvc_video_get_uvc_process(l); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); + + return state; +} + +pthread_t *uvc_video_get_uvc_pid(int id) { + pthread_t *tid = NULL; + + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + tid = &l->uvc_pid; + break; + } + } + } + pthread_mutex_unlock(&mtx_v); + + return tid; +} + +void uvc_video_join_uvc_pid(int id) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + if (l->uvc_pid) { + pthread_mutex_unlock(&mtx_v); + pthread_join(l->uvc_pid, NULL); + l->uvc_pid = 0; + pthread_mutex_lock(&mtx_v); + } + } + } + } + pthread_mutex_unlock(&mtx_v); +} + +static void uvc_gadget_pthread_exit(int id) { + while (!uvc_get_user_run_state(id)) + pthread_yield(); + uvc_set_user_run_state(false, id); + uvc_video_join_uvc_pid(id); +} + +static void _uvc_get_user_resolution(struct uvc_video *v, int *width, + int *height); + +static int _uvc_buffer_init(struct uvc_video *v) { + int i = 0; + int ret = 0; + struct uvc_buffer *buffer = NULL; + int width, height; + + _uvc_get_user_resolution(v, &width, &height); + + pthread_mutex_lock(&v->buffer_mutex); + + v->uvc = new video_uvc(); + if (!v->uvc) { + ret = -1; + goto exit; + } + v->uvc->id = 0; + v->uvc->video_id = v->id; + v->uvc->run = 1; + pthread_mutex_init(&v->uvc->write.mutex, NULL); + pthread_mutex_init(&v->uvc->read.mutex, NULL); + pthread_mutex_init(&v->uvc->all.mutex, NULL); + pthread_mutex_init(&v->uvc->cache.mutex, NULL); + + uvc_buffer_clear(&v->uvc->write); + uvc_buffer_clear(&v->uvc->read); + uvc_buffer_clear(&v->uvc->all); + uvc_buffer_clear(&v->uvc->cache); + + LOG_INFO("uvc_buf_cnt = %d\n", v->uvc_buf_cnt); + for (i = 0; i < v->uvc_buf_cnt; i++) { + buffer = uvc_buffer_create(width, height, v); + if (!buffer) { + ret = -1; + goto exit; + } + uvc_buffer_push_back(&v->uvc->write, buffer); + uvc_buffer_push_back(&v->uvc->all, buffer); + } + _uvc_video_set_uvc_process(v, true); + v->can_exit = true; + +exit: + pthread_mutex_unlock(&v->buffer_mutex); + return ret; +} + +int uvc_buffer_init(struct uvc_device *dev) { + int ret = -1; + int id = dev->video_id; + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + l->dev = dev; + l->uvc_buf_cnt = dev->nbufs; + ret = _uvc_buffer_init(l); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); + + return ret; +} + +static void _uvc_buffer_deinit(struct uvc_video *v) { + pthread_mutex_lock(&v->buffer_mutex); + if (v->uvc) { + v->uvc->run = 0; + _uvc_video_set_uvc_process(v, false); + LOG_INFO("_uvc_buffer_deinit read\n"); + uvc_mpi_buffer_destroy( + v, &v->uvc->read); // when close uvc or mpi get ok, will push to read. + LOG_INFO("_uvc_buffer_deinit cache\n"); + uvc_mpi_buffer_destroy(v, &v->uvc->cache); // at uvc driver buf + LOG_INFO("_uvc_buffer_deinit all\n"); + uvc_buffer_destroy(v, &v->uvc->all); + pthread_mutex_destroy(&v->uvc->write.mutex); + pthread_mutex_destroy(&v->uvc->read.mutex); + pthread_mutex_destroy(&v->uvc->all.mutex); + pthread_mutex_destroy(&v->uvc->cache.mutex); + delete v->uvc; + v->uvc = NULL; + } + pthread_mutex_unlock(&v->buffer_mutex); +} + +void uvc_buffer_deinit(int id) { + struct uvc_video *l; + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + l = *i; + if (id == l->id) { + break; + } + } + } + int wait_cnt = 0; + while (l->uvc_process && !l->can_exit) { + wait_cnt++; + usleep(1000); + if (wait_cnt > 30) { + LOG_INFO("uvc_buffer_deinit timeout 30ms,force exit!\n"); + break; + } + } + + // pthread_mutex_lock(&mtx_v); + _uvc_buffer_deinit(l); + // pthread_mutex_unlock(&mtx_v); +} + +static bool _uvc_buffer_write_enable(struct uvc_video *v) { + bool ret = false; + + if (pthread_mutex_trylock(&v->buffer_mutex)) + return ret; + if (v->uvc && uvc_buffer_front(&v->uvc->write)) + ret = true; + pthread_mutex_unlock(&v->buffer_mutex); + return ret; +} + +bool uvc_buffer_write_enable(int id) { + bool ret = false; + + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + ret = _uvc_buffer_write_enable(l); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); + + return ret; +} + +static bool _uvc_buffer_read_enable(struct uvc_video *v) { + bool ret = false; + + if (pthread_mutex_trylock(&v->buffer_mutex)) + return ret; + if (v->uvc && uvc_buffer_front(&v->uvc->read)) + ret = true; + pthread_mutex_unlock(&v->buffer_mutex); + return ret; +} + +bool uvc_buffer_read_enable(int id) { + bool ret = false; + + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + ret = _uvc_buffer_read_enable(l); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); + + return ret; +} + +struct uvc_buffer *uvc_buffer_write_get(int id) { + struct uvc_buffer *buffer = NULL; + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + l->can_exit = false; + pthread_mutex_lock(&l->buffer_mutex); + buffer = uvc_buffer_pop_front(&l->uvc->write); + pthread_mutex_unlock(&l->buffer_mutex); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); + return buffer; +} + +void uvc_buffer_write_set(int id, struct uvc_buffer *buf) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + l->can_exit = true; + pthread_mutex_lock(&l->buffer_mutex); + uvc_buffer_push_back(&l->uvc->write, buf); + pthread_mutex_unlock(&l->buffer_mutex); + break; + } + } + } + + pthread_mutex_unlock(&mtx_v); +} + +void uvc_buffer_read_set(int id, struct uvc_buffer *buf) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + l->can_exit = true; + pthread_mutex_lock(&l->buffer_mutex); + uvc_buffer_push_back(&l->uvc->read, buf); + pthread_mutex_unlock(&l->buffer_mutex); + break; + } + } + } + + pthread_mutex_unlock(&mtx_v); +} + +void uvc_buffer_cache_set(int id, struct uvc_buffer *buf) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + pthread_mutex_lock(&l->buffer_mutex); + LOG_DEBUG("set cache mb:%p\n", buf->frame); + uvc_buffer_push_back(&l->uvc->cache, buf); + pthread_mutex_unlock(&l->buffer_mutex); + break; + } + } + } + + pthread_mutex_unlock(&mtx_v); +} + +static void _uvc_set_user_resolution(struct uvc_video *v, int width, + int height) { + pthread_mutex_lock(&v->user_mutex); + v->uvc_user.width = width; + v->uvc_user.height = height; + LOG_DEBUG("uvc_user.width = %u, uvc_user.height = %u\n", v->uvc_user.width, + v->uvc_user.height); + pthread_mutex_unlock(&v->user_mutex); +} + +void uvc_set_user_resolution(int width, int height, int id) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + _uvc_set_user_resolution(l, width, height); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); +} + +static void _uvc_get_user_resolution(struct uvc_video *v, int *width, + int *height) { + pthread_mutex_lock(&v->user_mutex); + *width = v->uvc_user.width; + *height = v->uvc_user.height; + pthread_mutex_unlock(&v->user_mutex); +} + +void uvc_get_user_resolution(int *width, int *height, int id) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + _uvc_get_user_resolution(l, width, height); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); +} + +static bool _uvc_get_user_run_state(struct uvc_video *v) { + bool ret; + + pthread_mutex_lock(&v->user_mutex); + ret = v->uvc_user.run; + pthread_mutex_unlock(&v->user_mutex); + + return ret; +} + +bool uvc_get_user_run_state(int id) { + bool state = false; + + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + state = _uvc_get_user_run_state(l); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); + + return state; +} + +int uvc_video_qbuf_index(struct uvc_device *dev, struct uvc_buffer *send_buf, + int index, int len) { + unsigned int i = 0; + int ret = 0; + + if (index == 0) { + uvc_video_reqbufs(dev, dev->nbufs); + uvc_video_stream(dev, 1); + dev->vbuf_info = (struct v4l2_buffer_info *)calloc( + dev->nbufs, sizeof(struct v4l2_buffer_info)); + } else { // check if init qbuf ever + for (i = 0; i < dev->nbufs; i++) { + if (send_buf->fd == dev->vbuf_info[i].fd && + send_buf->frame == dev->vbuf_info[i].frame) { + LOG_DEBUG("debug info!index:%d find allocated i:%d fd:%d fram:%p\n", + index, i, send_buf->fd, send_buf->frame); + ret = 1; // find + break; + } + } + } + if (ret == 0) { + if (index == dev->nbufs) { + LOG_ERROR("had qbuf:%d exceed max uvc buf:%d\n", index, dev->nbufs); + ret = -1; // err, full buflist. + } else { + dev->vbuf_info[index].index = send_buf->index; + dev->vbuf_info[index].fd = send_buf->fd; + dev->vbuf_info[index].frame = send_buf->frame; + if (dev->io == IO_METHOD_USERPTR) + dev->vbuf_info[index].userptr = (unsigned long)dev->dummy_buf[send_buf->index].start; + + LOG_INFO("debug info! save index:%d send index:%d i:%d send_buf_fd:%d " + "send_buf_frame:%p " + "total:%d size:%d\n", + index, send_buf->index, i, dev->vbuf_info[index].fd, + dev->vbuf_info[index].frame, send_buf->total_size, + send_buf->size); + } + } + + return ret; +} + +static void _uvc_set_user_run_state(struct uvc_video *v, bool state) { + pthread_mutex_lock(&v->user_mutex); + v->uvc_user.run = state; + pthread_mutex_unlock(&v->user_mutex); +} + +void uvc_set_user_run_state(bool state, int id) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + _uvc_set_user_run_state(l, state); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); +} + +static void _uvc_set_user_fcc(struct uvc_video *v, unsigned int fcc) { + v->uvc_user.fcc = fcc; +} + +void uvc_set_user_fcc(unsigned int fcc, int id) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + _uvc_set_user_fcc(l, fcc); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); +} + +static unsigned int _uvc_get_user_fcc(struct uvc_video *v) { + return v->uvc_user.fcc; +} + +unsigned int uvc_get_user_fcc(int id) { + unsigned int fcc = 0; + + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + fcc = _uvc_get_user_fcc(l); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); + + return fcc; +} + +static void _uvc_memset_uvc_user(struct uvc_video *v) { + memset(&v->uvc_user, 0, sizeof(struct uvc_user)); +} + +void uvc_memset_uvc_user(int id) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + _uvc_memset_uvc_user(l); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); +} + +static bool _uvc_buffer_check(struct uvc_video *v, struct uvc_buffer *buffer) { + int width = 0, height = 0; + + _uvc_get_user_resolution(v, &width, &height); + if (buffer->width == width && buffer->height == height) + return true; + else + return false; +} + +static void uvc_delay_time_calcu_before_get(struct uvc_device *dev, + struct uvc_video *v) { +#if UVC_DYNAMIC_DEBUG_USE_TIME + if (!access(UVC_DYNAMIC_DEBUG_USE_TIME_CHECK, 0)) { + int32_t use_time_us, now_time_us; + struct timespec now_tm = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &now_tm); + now_time_us = now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; // us + use_time_us = + now_time_us - + v->last_pts; // usb send ok and calcu the latency time use last pts + LOG_INFO( + "isp->mpp->usb_ready->usb_send_ok seq:%d latency time:%d us, %d ms\n", + v->last_seq, use_time_us, use_time_us / 1000); + } + + if (dev->usb_state == USB_STATE_FIRST_GET_READY) { + int32_t use_time_us; + struct timespec now_tm = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &now_tm); + dev->usb_state = USB_STATE_FIRST_GET_OK; + dev->first_usb_get_ready_pts = + now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; + use_time_us = dev->first_usb_get_ready_pts - dev->stream_on_pts; + LOG_INFO("steamon->get_ready latency time:%d us, %d ms\n", use_time_us, + use_time_us / 1000); + use_time_us = dev->first_usb_get_ready_pts - dev->first_cmd_pts; + LOG_INFO("first_cmd->steamon->get_ready latency time:%d ms\n", + use_time_us / 1000); + } else if (dev->usb_state == USB_STATE_FIRST_SEND_OK) { + struct timespec now_tm = {0, 0}; + int32_t use_time_us; + clock_gettime(CLOCK_MONOTONIC, &now_tm); + dev->first_usb_send_ok_pts = + now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; + dev->usb_state = USB_STATE_NORMAL_RUN; + use_time_us = dev->first_usb_send_ok_pts - dev->first_cmd_pts; + LOG_INFO( + "first_cmd->steamon->get_ready->get_ok->send_ok latency time:%d ms\n", + use_time_us / 1000); + use_time_us = dev->first_usb_send_ok_pts - dev->stream_on_pts; + LOG_INFO("steamon->get_ready->get_ok->send_ok latency time:%d us, %d ms\n", + use_time_us, use_time_us / 1000); + use_time_us = dev->first_usb_send_ok_pts - v->last_pts; + LOG_INFO( + "isp->mpp->usb_ready->usb_send_ok seq:%d latency time:%d us, %d ms\n", + v->last_seq, use_time_us, use_time_us / 1000); + } +#endif +} + +static void uvc_delay_time_calcu_after_get(struct uvc_device *dev, + struct uvc_video *v, + struct uvc_buffer *buffer) { +#if UVC_DYNAMIC_DEBUG_USE_TIME + if (dev->usb_state == USB_STATE_FIRST_GET_OK) { + struct timespec now_tm = {0, 0}; + int32_t use_time_us; + clock_gettime(CLOCK_MONOTONIC, &now_tm); + dev->first_usb_get_ok_pts = + now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; + dev->usb_state = USB_STATE_FIRST_SEND_OK; + use_time_us = dev->first_usb_get_ok_pts - dev->stream_on_pts; + LOG_INFO("steamon->get_ready->get_ok seq:%d time:%d us, %d ms\n", + buffer->seq, use_time_us, use_time_us / 1000); + } + + v->last_pts = buffer->pts; + v->now_pts = buffer->pts; + v->last_seq = buffer->seq; + if (!access(UVC_DYNAMIC_DEBUG_USE_TIME_CHECK, 0)) { + int32_t use_time_us, now_time_us; + struct timespec now_tm = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &now_tm); + now_time_us = now_tm.tv_sec * 1000000LL + now_tm.tv_nsec / 1000; // us + use_time_us = now_time_us - v->now_pts; + LOG_INFO("isp->mpp->usb_ready seq:%d latency time:%d us, %d ms\n", + buffer->seq, use_time_us, use_time_us / 1000); + } +#endif +} + +struct uvc_buffer *uvc_get_enc_data(struct uvc_device *dev, struct uvc_video *v, + bool init) { + struct uvc_buffer *buffer = NULL; + int ret = 0; + v->idle_cnt = 0; + int time_out = 60; + if (init || !dev->get_buf_count) // first frm for small timeout + time_out = 30; + while (!(buffer = uvc_buffer_front(&v->uvc->read)) && + _uvc_get_user_run_state(v)) { + pthread_mutex_unlock(&mtx_v); + usleep(1000); + v->idle_cnt++; + pthread_mutex_lock(&mtx_v); + if (v->idle_cnt > time_out) { + if (!(buffer = uvc_buffer_front(&v->uvc->read)) && + _uvc_get_user_run_state(v)) // onece more check it. + { + if (init == false) { + if (v->drop_frame_cnt == 0) { + LOG_INFO("fill buf timeout %d ms\n", time_out); + } + } else { + if (v->drop_frame_cnt == 0) { + LOG_INFO("init:%d,fill buf timeout %d ms buffer:%p\n", init, + time_out, buffer); + } + } + v->drop_frame_cnt++; + if (v->drop_frame_cnt > 200) { + if (access("/tmp/uvc_camera_no_buf", 0)) { + LOG_INFO("it's already 200 frames buf no to get from CAMERA,tell " + "watchdog now\n"); + system("touch /tmp/uvc_camera_no_buf &"); + } + v->drop_frame_cnt = 0; + } + } + break; + } + } + if (buffer) { // init && + ret = uvc_video_qbuf_index(dev, buffer, dev->get_buf_count, buffer->size); + if (!ret) { + dev->get_buf_count += 1; + LOG_INFO("new qbuf index:%d\n", dev->get_buf_count); + } else if (ret == -1) { + uvc_buffer_pop_front(&v->uvc->read); + _uvc_mpi_buffer_release(dev, buffer, true); + uvc_buffer_push_back(&v->uvc->write, buffer); + LOG_INFO("abandon buffer-mb:%p\n", buffer->frame); + goto FAIL; + } + } + + if (buffer) + uvc_delay_time_calcu_after_get(dev, v, buffer); + return buffer; +FAIL: + return NULL; +} + +static struct uvc_buffer *_uvc_user_fill_buffer(struct uvc_video *v, + struct uvc_device *dev, + struct v4l2_buffer *buf) { + struct uvc_buffer *buffer = NULL; + uvc_delay_time_calcu_before_get(dev, v); + + buffer = uvc_get_enc_data(dev, v, false); + if (buffer) { + switch (dev->io) { + case IO_METHOD_DMA_BUFF: + buf->index = buffer->index; + buf->sequence = buffer->seq; + buf->m.fd = buffer->fd; + buf->reserved2 = buffer->offset; + break; + case IO_METHOD_USERPTR: + buf->index = buffer->index; + buf->sequence = buffer->seq; + buf->m.userptr = (unsigned long)dev->dummy_buf[buffer->index].start; + memset(dev->dummy_buf[buffer->index].start, 0, dev->dummy_buf[buffer->index].length); + memcpy(dev->dummy_buf[buffer->index].start, buffer->buffer, buffer->size); + buf->length = dev->dummy_buf[buffer->index].length; + break; + default: + LOG_ERROR("no support this io method:%d\n", dev->io); + break; + } + + if (_uvc_get_user_run_state(v) && _uvc_video_get_uvc_process(v)) { + // buf->bytesused = 550*1024;//for test + buf->bytesused = buffer->size; + v->drop_frame_cnt = 0; + LOG_DEBUG("debug info! i:%d fd:%d buf->bytesused=%d\n", buffer->index, + buf->m.fd, buf->bytesused); + } else { + LOG_WARN("_uvc_user_fill_buffer no go here \n"); + buf->bytesused = 0; + } + buffer = uvc_buffer_pop_front(&v->uvc->read); + } else { + buf->bytesused = 0; + buf->m.fd = 0; + } + + return buffer; +} + +struct uvc_buffer *uvc_user_fill_buffer(struct uvc_device *dev, + struct v4l2_buffer *buf, int id) { + struct uvc_buffer *buffer = NULL; + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + buffer = _uvc_user_fill_buffer(l, dev, buf); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); + + return buffer; +} + +static void _uvc_user_release_cache_buffer(struct uvc_video *v, + struct uvc_device *dev, + struct v4l2_buffer *buf) { + struct uvc_buffer buffer; + bool matching = false; + + for (int i = 0; i < dev->nbufs; i++) { + if (dev->io == IO_METHOD_DMA_BUFF && + dev->vbuf_info[i].fd == buf->m.fd && + dev->vbuf_info[i].index == buf->index) { + buffer.frame = dev->vbuf_info[i].frame; + buffer.fd = dev->vbuf_info[i].fd; + matching = true; + // LOG_ERROR("find matching:id:%d fd:%d\n", i, buf->m.fd); + break; + } else if (dev->io == IO_METHOD_USERPTR && + dev->vbuf_info[i].userptr == buf->m.userptr && + dev->vbuf_info[i].index == buf->index) { + buffer.frame = dev->vbuf_info[i].frame; + buffer.fd = dev->vbuf_info[i].fd; + matching = true; + break; + } + } + if (matching) { + uvc_buffer_pop_assign_cache(&v->uvc->cache, &buffer); + _uvc_mpi_buffer_release(dev, &buffer, true); + } else { + LOG_ERROR("not find matching: fd:%d index:%d\n", buf->m.fd, buf->index); + } +} + +// uvc driver return the buf +void uvc_user_release_cache_buffer(struct uvc_device *dev, + struct v4l2_buffer *buf, int id) { + pthread_mutex_lock(&mtx_v); + if (_uvc_video_id_check(id)) { + for (std::list::iterator i = lst_v.begin(); + i != lst_v.end(); ++i) { + struct uvc_video *l = *i; + if (id == l->id) { + _uvc_user_release_cache_buffer(l, dev, buf); + break; + } + } + } + pthread_mutex_unlock(&mtx_v); +} diff --git a/project/app/uvc_app_tiny/uvc_app/uvc/uvc_video.h b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_video.h new file mode 100755 index 000000000..224bec4fc --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc/uvc_video.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2019 Rockchip Electronics Co., Ltd. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL), available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __UVC_VIDEO_H__ +#define __UVC_VIDEO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "uvc-gadget.h" +#include +#include +#include +#include +#include + +#define V4L2_PIX_FMT_H265 \ + v4l2_fourcc('H', '2', '6', '5') /* H265 with start codes */ + +#define YUYV_AS_RAW 0 + +#define UVC_DYNAMIC_DEBUG_USE_TIME 1 // release version can set to 0 +#define UVC_DYNAMIC_DEBUG_USE_TIME_CHECK "/tmp/uvc_use_time" + +#define UVC_DYNAMIC_DEBUG_FPS 1 // release version can set to 0 +#define UVC_DYNAMIC_DEBUG_ISP_FPS_CHECK "/tmp/uvc_isp_fps" +#define UVC_DYNAMIC_DEBUG_IPC_FPS_CHECK "/tmp/uvc_ipc_fps" + +#if UVC_DYNAMIC_DEBUG_FPS +struct uvc_debug_info_def { + bool first_frm; + bool debug_isp_fps; + bool debug_ipc_fps; + float fps; + int ipc_frm; + int isp_frm; + struct timeval enter_time; + unsigned int stream_on_pts; +}; + +extern struct uvc_debug_info_def uvc_debug_info; +#endif + +struct uvc_device; + +struct uvc_buffer { + void *buffer; + size_t size; // encode out size + size_t total_size; + unsigned int offset; + int width; + int height; + int video_id; + int fd; + unsigned int pts; + unsigned int seq; + int index; + void *frame; +}; + +struct uvc_user { + unsigned int width; + unsigned int height; + bool run; + unsigned int fcc; +}; + +struct uvc_video { + int id; + bool uvc_process; + pthread_t uvc_pid; + struct video_uvc *uvc; + pthread_mutex_t buffer_mutex; + pthread_mutex_t user_mutex; + struct uvc_user uvc_user; + int uvc_buf_cnt; + int idle_cnt; + int drop_frame_cnt; + bool can_exit; + unsigned int last_pts; + unsigned int now_pts; + unsigned int last_seq; + struct uvc_device *dev; +}; + +int uvc_gadget_pthread_create(struct uvc_function_config *fc); + +int uvc_video_id_check(int id); +int uvc_video_id_add(struct uvc_function_config *fc); +void uvc_video_id_remove(int id); +void uvc_video_id_exit_all(); +int uvc_video_id_get(unsigned int seq); + +void uvc_video_set_uvc_process(int id, bool state); +bool uvc_video_get_uvc_process(int id); + +int uvc_buffer_init(struct uvc_device *dev); +void uvc_buffer_deinit(int id); +bool uvc_buffer_write_enable(int id); +void uvc_set_user_resolution(int width, int height, int id); +void uvc_get_user_resolution(int *width, int *height, int id); +bool uvc_get_user_run_state(int id); +void uvc_set_user_run_state(bool state, int id); +void uvc_set_user_fcc(unsigned int fcc, int id); +unsigned int uvc_get_user_fcc(int id); +void uvc_memset_uvc_user(int id); +pthread_t *uvc_video_get_uvc_pid(int id); +struct uvc_buffer *uvc_user_fill_buffer(struct uvc_device *dev, + struct v4l2_buffer *buf, int id); +struct uvc_buffer *uvc_get_enc_data(struct uvc_device *dev, struct uvc_video *v, + bool init); +int uvc_video_qbuf_index(struct uvc_device *dev, struct uvc_buffer *send_buf, + int index, int len); +void uvc_user_release_cache_buffer(struct uvc_device *dev, + struct v4l2_buffer *buf, int id); +bool uvc_buffer_read_enable(int id); +struct uvc_buffer *uvc_buffer_write_get(int id); +void uvc_buffer_write_set(int id, struct uvc_buffer *buf); +void uvc_buffer_read_set(int id, struct uvc_buffer *buf); +void uvc_buffer_cache_set(int id, struct uvc_buffer *buf); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/app/uvc_app_tiny/uvc_app/uvc_mpi_cfg.conf b/project/app/uvc_app_tiny/uvc_app/uvc_mpi_cfg.conf new file mode 100644 index 000000000..c3d5ed5b2 --- /dev/null +++ b/project/app/uvc_app_tiny/uvc_app/uvc_mpi_cfg.conf @@ -0,0 +1,212 @@ +{ + "index_0": { + "version" : 1, + "common_cfg": { + "version" : 1, + "property" : { + "param_init": { + "check_param_change_thread": "off", + "uvc_debug": "off", + "yuyv_debug": "off", + "nn_enable": "off", + "uvc_debug_file_name": "/data/uvc.bin", + "uvc_debug_file_cnt": 0, + "nn_debug_file_name": "/data/nn.bin", + "nn_debug_file_cnt": 0, + "uvc_enable_vpss": "on", + "geometric_output": "16:9" + }, + "param_change": { + } + } + }, + "eptz_cfg": { + "version" : 1, + "param_init": { + "enable": "on", + "enable_boot": "off", + "debug": "off" + }, + "param_change": { + } + }, + "vi_cfg": { + "version" : 1, + "uvc" : { + "param_init": { + "dev_id": 0, + "channel_id": 1, + "buf_cnt": 1, + "assign_width": 0, + "assign_height": 0, + "min_width": 640, + "min_height": 480, + "max_width": 1920, + "max_height": 1080, + "format": "nv12", + "dev_name": "null", + "fps": "0:0", + "memory_type": 4, + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "nn" : { + "param_init": { + "dev_id": 0, + "channel_id": 1, + "assign_width": 512, + "assign_height": 288, + "format": "nv12", + "buf_cnt": 1, + "dev_name": "null", + "fps": "0:0", + "memory_type": 4, + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + } + }, + "vpss_cfg": { + "version" : 1, + "uvc" : { + "param_init": { + "group_id": 0, + "channel_id": 0, + "buf_cnt": 1, + "fps": "0:0", + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "nn" : { + "param_init": { + "group_id": 1, + "channel_id": 0, + "format": "bgr888", + "assign_width": 512, + "assign_height": 288, + "buf_cnt": 1, + "fps": "0:0", + "fbc": "off", + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + } + }, + "venc_cfg": { + "version" : 1, + "common" : { + "param_init": { + "channel_id": 1, + "rotation": 0, + "mirror": 0 + }, + "param_change": { + } + }, + "mjpeg": { + "param_init": { + "default": { + "buf_cnt": 1, + "fbc": "off", + "rc_mode": "fixqp", + "fps": "0:0", + "range": "full", + "sei": "off", + "qfactor": 85, + "qfactor_min": 30, + "qfactor_max": 99, + "bps": 60000 + }, + "1280*720p30": { + "qfactor": 80, + "qfactor_min": 60, + "qfactor_max": 90, + "bps": 70000 + }, + "1920*1080p30": { + "qfactor": 75, + "qfactor_min": 50, + "qfactor_max": 90, + "bps": 80000 + } + }, + "param_change": { + } + }, + "h264" : { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "gop": 60, + "rc_mode": "cbr", + "fps": "0:0", + "range": "full", + "qp": "26:4:20:40:8:48:2:1", + "sei": "off", + "profile": 100, + "vi_len": 30, + "gop_mode": 0, + "bps": 10000, + "force_idr": "5:5:20000" + }, + "1920*1080p30": { + "bps": 10000, + "force_idr": "5:5:30000" + } + }, + "param_change": { + } + }, + "h265" : { + "param_init": { + "default": { + "buf_cnt": 2, + "fbc": "off", + "gop": 60, + "rc_mode": "cbr", + "fps": "0:0", + "range": "full", + "qp": "26:4:20:40:8:48:2:1", + "sei": "off", + "vi_len": 30, + "gop_mode": 0, + "bps": 10000, + "force_idr": "5:5:20000" + }, + "1920*1080p30": { + "bps": 10000, + "force_idr": "5:5:30000" + }, + "2560*1440p30": { + "bps": 15000, + "force_idr": "5:5:40000" + } + }, + "param_change": { + } + } + }, + "osd_cfg": { + "version" : 1, + "param_init": { + "enable": "off" + }, + "param_change": { + } + } + } +} diff --git a/project/build.sh b/project/build.sh index 9779b91fa..7685d2457 100755 --- a/project/build.sh +++ b/project/build.sh @@ -312,12 +312,12 @@ function choose_target_board() { echo -e "${C_GREEN} "${space8}选择系统版本:"${C_NORMAL}" if (("$BM_INDEX" == 1)); then - echo "${space8}${space8}[0] Buildroot(Support Rockchip official features) " + echo "${space8}${space8}[0] Buildroot " read -p "Which would you like? [0~1][default:0]: " SYS_INDEX MAX_SYS_INDEX=0 elif (("$BM_INDEX" == 0)); then - echo "${space8}${space8}[0] Buildroot(Support Rockchip official features) " - echo "${space8}${space8}[1] Ubuntu(Support for the apt package management tool)" + echo "${space8}${space8}[0] Buildroot " + echo "${space8}${space8}[1] Ubuntu " read -p "Which would you like? [0~1][default:0]: " SYS_INDEX MAX_SYS_INDEX=1 fi @@ -689,24 +689,6 @@ function build_uboot() { echo "TARGET_UBOOT_CONFIG=$RK_UBOOT_DEFCONFIG $RK_UBOOT_DEFCONFIG_FRAGMENT" echo "=========================================" - #Apply patch - if [ ! -f ${SDK_SYSDRV_DIR}/source/.uboot_patch ]; then - echo "============Apply Uboot Patch============" - cd ${SDK_ROOT_DIR} - git apply ${SDK_SYSDRV_DIR}/tools/board/uboot/*.patch - if [ $? -eq 0 ]; then - msg_info "Patch applied successfully." - touch ${SDK_SYSDRV_DIR}/source/.uboot_patch - else - msg_error "Failed to apply the patch." - exit 1 - fi - fi - - cp ${SDK_SYSDRV_DIR}/tools/board/uboot/*_defconfig ${SDK_SYSDRV_DIR}/source/uboot/u-boot/configs - cp ${SDK_SYSDRV_DIR}/tools/board/uboot/*.dts ${SDK_SYSDRV_DIR}/source/uboot/u-boot/arch/arm/dts - cp ${SDK_SYSDRV_DIR}/tools/board/uboot/*.dtsi ${SDK_SYSDRV_DIR}/source/uboot/u-boot/arch/arm/dts - local uboot_rkbin_ini tempfile target_ini_dir tempfile="$SDK_SYSDRV_DIR/source/uboot/rkbin/$RK_UBOOT_RKBIN_INI_OVERLAY" if [ -f "$tempfile" ]; then @@ -841,24 +823,6 @@ function build_sysdrv() { } function build_kernel() { - #Apply patch - if [ ! -f ${SDK_SYSDRV_DIR}/source/.kernel_patch ]; then - echo "============Apply Kernel Patch============" - cd ${SDK_ROOT_DIR} - git apply --verbose ${SDK_SYSDRV_DIR}/tools/board/kernel/*.patch - if [ $? -eq 0 ]; then - msg_info "Patch applied successfully." - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*_defconfig ${KERNEL_PATH}/arch/arm/configs/ - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.config ${KERNEL_PATH}/arch/arm/configs/ - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/kernel-drivers-video-logo_linux_clut224.ppm ${KERNEL_PATH}/drivers/video/logo/logo_linux_clut224.ppm - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.dts ${KERNEL_PATH}/arch/arm/boot/dts - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.dtsi ${KERNEL_PATH}/arch/arm/boot/dts - touch ${SDK_SYSDRV_DIR}/source/.kernel_patch - else - msg_error "Failed to apply the patch." - fi - fi - check_config RK_KERNEL_DTS RK_KERNEL_DEFCONFIG || return 0 echo "============Start building kernel============" @@ -1318,25 +1282,6 @@ function build_clean() { recovery) make kernel_clean -C ${SDK_SYSDRV_DIR} SYSDRV_BUILD_RECOVERY=y ;; - patch) - cd ${SDK_ROOT_DIR} - make uboot_clean -C ${SDK_SYSDRV_DIR} - if [ -f ${SDK_SYSDRV_DIR}/source/.uboot_patch ]; then - git apply -R --verbose ${SDK_SYSDRV_DIR}/tools/board/uboot/*.patch - rm -rf ${SDK_SYSDRV_DIR}/source/uboot/u-boot/arch/arm/dts/*luckfox* - rm -rf ${SDK_SYSDRV_DIR}/source/uboot/u-boot/configs/*luckfox* - rm ${SDK_SYSDRV_DIR}/source/.uboot_patch - fi - - make kernel_clean -C ${SDK_SYSDRV_DIR} - if [ -f ${SDK_SYSDRV_DIR}/source/.kernel_patch ]; then - git apply -R --verbose ${SDK_SYSDRV_DIR}/tools/board/kernel/*.patch - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/logo_linux_clut224.ppm ${SDK_SYSDRV_DIR}/source/kernel/drivers/video/logo/logo_linux_clut224.ppm - rm -rf ${SDK_SYSDRV_DIR}/source/kernel/arch/arm/configs/*luckfox* - rm -rf ${SDK_SYSDRV_DIR}/source/kernel/arch/arm/boot/dts/*luckfox* - rm ${SDK_SYSDRV_DIR}/source/.kernel_patch - fi - ;; all) make distclean -C ${SDK_SYSDRV_DIR} make distclean -C ${SDK_MEDIA_DIR} @@ -2212,23 +2157,6 @@ __LINK_DEFCONFIG_FROM_BOARD_CFG() { sudo chmod a+rw $SDK_CONFIG_DIR fi - if [ ! -f ${SDK_SYSDRV_DIR}/source/.kernel_patch ]; then - echo "============Apply Kernel Patch============" - cd ${SDK_ROOT_DIR} - git apply ${SDK_SYSDRV_DIR}/tools/board/kernel/*.patch - if [ $? -eq 0 ]; then - msg_info "Patch applied successfully." - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*_defconfig ${KERNEL_PATH}/arch/arm/configs/ - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.config ${KERNEL_PATH}/arch/arm/configs/ - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/kernel-drivers-video-logo_linux_clut224.ppm ${KERNEL_PATH}/drivers/video/logo/logo_linux_clut224.ppm - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.dts ${KERNEL_PATH}/arch/arm/boot/dts - cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.dtsi ${KERNEL_PATH}/arch/arm/boot/dts - touch ${SDK_SYSDRV_DIR}/source/.kernel_patch - else - msg_error "Failed to apply the patch." - fi - fi - if [ -n "$RK_KERNEL_DTS" ]; then rm -f $DTS_CONFIG ln -rfs $SDK_SYSDRV_DIR/source/kernel/arch/arm/boot/dts/$RK_KERNEL_DTS $DTS_CONFIG @@ -2295,7 +2223,9 @@ function build_mkimg() { fs_type="\$${fs_type}" fs_type=$(eval "echo ${fs_type}") - __RELEASE_FILESYSTEM_FILES $src + if [ "$LF_TARGET_ROOTFS" == "buildroot" ] || [ "$LF_TARGT_ROOTFS" == "busybox" ]; then + __RELEASE_FILESYSTEM_FILES $src + fi msg_info "src=$src" msg_info "dst=$dst" diff --git a/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra-IPC.mk b/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra-IPC.mk index 9e8f5587d..59844d5e2 100755 --- a/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra-IPC.mk +++ b/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra-IPC.mk @@ -90,7 +90,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig # RK_CAMERA_SENSOR_IQFILES format: # "iqfile1 iqfile2 iqfile3 ..." # ./build.sh media and copy /output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES -export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json" +export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json" #export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json" # Config sensor lens CAC calibrattion bin files diff --git a/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra_W-IPC.mk b/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra_W-IPC.mk index fb6c1de06..b0fa61ed9 100755 --- a/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra_W-IPC.mk +++ b/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra_W-IPC.mk @@ -90,7 +90,7 @@ export RK_KERNEL_DEFCONFIG_FRAGMENT=rv1106-bt.config # RK_CAMERA_SENSOR_IQFILES format: # "iqfile1 iqfile2 iqfile3 ..." # ./build.sh media and copy /output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES -export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json" +export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json" #export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json" # Config sensor lens CAC calibrattion bin files diff --git a/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Ultra-IPC.mk b/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Ultra-IPC.mk index e2f015cd0..7e71da984 100755 --- a/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Ultra-IPC.mk +++ b/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Ultra-IPC.mk @@ -11,7 +11,7 @@ export RK_CHIP=rv1106 # export RK_APP_TYPE=RKIPC_RV1106 # Config CMA size in environment -export RK_BOOTARGS_CMA_SIZE="1M" +export RK_BOOTARGS_CMA_SIZE="36M" # Kernel dts export RK_KERNEL_DTS=rv1106g-luckfox-pico-ultra.dts @@ -90,7 +90,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig # RK_CAMERA_SENSOR_IQFILES format: # "iqfile1 iqfile2 iqfile3 ..." # ./build.sh media and copy /output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES -export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json" +export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json" #export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json" # Config sensor lens CAC calibrattion bin files @@ -120,4 +120,4 @@ export RK_PRE_BUILD_OEM_SCRIPT=luckfox-buildroot-oem-pre.sh export RK_PRE_BUILD_USERDATA_SCRIPT=luckfox-userdata-pre.sh # declare overlay directory -export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-ultra" \ No newline at end of file +export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-ultra overlay-luckfox-ubuntu-rockchip" \ No newline at end of file diff --git a/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Ultra_W-IPC.mk b/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Ultra_W-IPC.mk index d403381cb..dd93b3b7a 100755 --- a/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Ultra_W-IPC.mk +++ b/project/cfg/BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Ultra_W-IPC.mk @@ -11,7 +11,7 @@ export RK_CHIP=rv1106 # export RK_APP_TYPE=RKIPC_RV1106 # Config CMA size in environment -export RK_BOOTARGS_CMA_SIZE="1M" +export RK_BOOTARGS_CMA_SIZE="36M" # Kernel dts export RK_KERNEL_DTS=rv1106g-luckfox-pico-ultra-w.dts @@ -93,7 +93,7 @@ export RK_KERNEL_DEFCONFIG_FRAGMENT=rv1106-bt.config # RK_CAMERA_SENSOR_IQFILES format: # "iqfile1 iqfile2 iqfile3 ..." # ./build.sh media and copy /output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES -export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json" +export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json" #export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json" # Config sensor lens CAC calibrattion bin files @@ -128,4 +128,4 @@ export RK_PRE_BUILD_OEM_SCRIPT=luckfox-buildroot-oem-pre.sh export RK_PRE_BUILD_USERDATA_SCRIPT=luckfox-userdata-pre.sh # declare overlay directory -export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-ultra" +export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-ultra overlay-luckfox-ubuntu-rockchip" diff --git a/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Max-IPC.mk b/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Max-IPC.mk index 58edd642c..831125530 100755 --- a/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Max-IPC.mk +++ b/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Max-IPC.mk @@ -87,7 +87,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig # RK_CAMERA_SENSOR_IQFILES format: # "iqfile1 iqfile2 iqfile3 ..." # ./build.sh media and copy /output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES -export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json" +export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json" #export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json" # Config sensor lens CAC calibrattion bin files diff --git a/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk b/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk index 8ea9ed25b..aede64b02 100755 --- a/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk +++ b/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk @@ -87,7 +87,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig # RK_CAMERA_SENSOR_IQFILES format: # "iqfile1 iqfile2 iqfile3 ..." # ./build.sh media and copy /output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES -export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json" +export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json" #export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json" # Config sensor lens CAC calibrattion bin files diff --git a/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1106_Luckfox_Pico_Max-IPC.mk b/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1106_Luckfox_Pico_Max-IPC.mk index 7b58a5b03..80a6ab3fc 100755 --- a/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1106_Luckfox_Pico_Max-IPC.mk +++ b/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1106_Luckfox_Pico_Max-IPC.mk @@ -11,7 +11,7 @@ export RK_CHIP=rv1106 # export RK_APP_TYPE=RKIPC_RV1106 # Config CMA size in environment -export RK_BOOTARGS_CMA_SIZE="1M" +export RK_BOOTARGS_CMA_SIZE="36M" # Kernel dts export RK_KERNEL_DTS=rv1106g-luckfox-pico-max.dts @@ -90,7 +90,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig # RK_CAMERA_SENSOR_IQFILES format: # "iqfile1 iqfile2 iqfile3 ..." # ./build.sh media and copy /output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES -export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json" +export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json" #export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json" # Config sensor lens CAC calibrattion bin files @@ -117,4 +117,4 @@ export RK_PRE_BUILD_OEM_SCRIPT=luckfox-ubuntu-oem-pre.sh export RK_PRE_BUILD_USERDATA_SCRIPT=luckfox-userdata-pre.sh # declare overlay directory -export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu overlay-luckfox-ubuntu-config" \ No newline at end of file +export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-rockchip" \ No newline at end of file diff --git a/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1106_Luckfox_Pico_Pro-IPC.mk b/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1106_Luckfox_Pico_Pro-IPC.mk index 8f5c65eed..12a5a3af1 100755 --- a/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1106_Luckfox_Pico_Pro-IPC.mk +++ b/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1106_Luckfox_Pico_Pro-IPC.mk @@ -11,7 +11,7 @@ export RK_CHIP=rv1106 # export RK_APP_TYPE=RKIPC_RV1106 # Config CMA size in environment -export RK_BOOTARGS_CMA_SIZE="1M" +export RK_BOOTARGS_CMA_SIZE="36M" # Kernel dts export RK_KERNEL_DTS=rv1106g-luckfox-pico-pro.dts @@ -90,7 +90,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig # RK_CAMERA_SENSOR_IQFILES format: # "iqfile1 iqfile2 iqfile3 ..." # ./build.sh media and copy /output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES -export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json" +export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json" #export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json" # Config sensor lens CAC calibrattion bin files @@ -117,4 +117,4 @@ export RK_PRE_BUILD_OEM_SCRIPT=luckfox-ubuntu-oem-pre.sh export RK_PRE_BUILD_USERDATA_SCRIPT=luckfox-userdata-pre.sh # declare overlay directory -export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu overlay-luckfox-ubuntu-config" \ No newline at end of file +export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-rockchip" \ No newline at end of file diff --git a/project/cfg/BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Max-IPC.mk b/project/cfg/BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Max-IPC.mk index c3fe3375c..84a3adb68 100755 --- a/project/cfg/BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Max-IPC.mk +++ b/project/cfg/BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Max-IPC.mk @@ -87,7 +87,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig # RK_CAMERA_SENSOR_IQFILES format: # "iqfile1 iqfile2 iqfile3 ..." # ./build.sh media and copy /output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES -export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json" +export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json" #export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json" # Config sensor lens CAC calibrattion bin files diff --git a/project/cfg/BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk b/project/cfg/BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk index 3d96eeb9d..8490da731 100755 --- a/project/cfg/BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk +++ b/project/cfg/BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk @@ -87,7 +87,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig # RK_CAMERA_SENSOR_IQFILES format: # "iqfile1 iqfile2 iqfile3 ..." # ./build.sh media and copy /output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES -export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json" +export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json" #export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json" # Config sensor lens CAC calibrattion bin files diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libIspFec.a b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libIspFec.a new file mode 100644 index 000000000..568afbb7d Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libIspFec.a differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libIspFec.so b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libIspFec.so new file mode 100644 index 000000000..d20356fd0 Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libIspFec.so differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libfunc_none.so b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libfunc_none.so new file mode 100644 index 000000000..a03255ea0 Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libfunc_none.so differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librga.so b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librga.so new file mode 120000 index 000000000..fd3eb3c54 --- /dev/null +++ b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librga.so @@ -0,0 +1 @@ +librga.so.2 \ No newline at end of file diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librga.so.2 b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librga.so.2 new file mode 120000 index 000000000..bc4415a99 --- /dev/null +++ b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librga.so.2 @@ -0,0 +1 @@ +librga.so.2.1.0 \ No newline at end of file diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librga.so.2.1.0 b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librga.so.2.1.0 new file mode 100644 index 000000000..f40d4d123 Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librga.so.2.1.0 differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librkaiq.a b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librkaiq.a new file mode 100644 index 000000000..e7efe09e0 Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librkaiq.a differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librkaiq.so b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librkaiq.so new file mode 100644 index 000000000..c6df8ffc2 Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librkaiq.so differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librknnmrt.so b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librknnmrt.so new file mode 100644 index 000000000..8a476f3ed Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librknnmrt.so differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librkrawstream.so b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librkrawstream.so new file mode 100644 index 000000000..86e0ed0cc Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librkrawstream.so differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockchip_mpp.a b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockchip_mpp.a new file mode 100644 index 000000000..6071e37f8 Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockchip_mpp.a differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockit.a b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockit.a new file mode 100644 index 000000000..1527c79b6 Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockit.a differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockit_full.a b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockit_full.a new file mode 100644 index 000000000..fbf04f25a Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockit_full.a differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockit_tiny.a b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockit_tiny.a new file mode 100644 index 000000000..7d2641056 Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librockit_tiny.a differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librtsp.a b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librtsp.a new file mode 100644 index 000000000..2387f6795 Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/librtsp.a differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libsample_comm.a b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libsample_comm.a new file mode 100644 index 000000000..f0baa58e9 Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libsample_comm.a differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libsmartIr.a b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libsmartIr.a new file mode 100644 index 000000000..21344c03e Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libsmartIr.a differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libsmartIr.so b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libsmartIr.so new file mode 100644 index 000000000..cee0fd3ce Binary files /dev/null and b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-rockchip/usr/lib/libsmartIr.so differ diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-ultra/etc/rc.local b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-ultra/etc/rc.local index 29f63e24b..de1b911aa 100755 --- a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-ultra/etc/rc.local +++ b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu-ultra/etc/rc.local @@ -15,9 +15,22 @@ usb_reset() { done } +wifibt_init() { + /usr/bin/wifi_bt_init.sh + if [ -z "$(ifconfig -a | grep wlan0)" ]; then + echo "Try Wi-Fi/BT init again!" + sleep 5 + /usr/bin/wifi_bt_init.sh + fi +} + +if [ -f /oem/usr/ko/insmod_ko.sh ]; then + chmod a+x /oem/usr/ko/insmod_ko.sh + /oem/usr/ko/insmod_ko.sh +fi /usr/bin/filesystem_resize.sh -/usr/bin/wifi_bt_init.sh /usr/bin/luckfox_switch_rgb_resolution & +wifibt_init & usb_mode="$(cat $USB_MODE_PATH)" /etc/init.d/S50usbdevice start diff --git a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu/etc/rc.local b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu/etc/rc.local index f84b6c663..776be1f2b 100755 --- a/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu/etc/rc.local +++ b/project/cfg/BoardConfig_IPC/overlay/overlay-luckfox-ubuntu/etc/rc.local @@ -15,6 +15,10 @@ usb_reset() { done } +if [ -f /oem/usr/ko/insmod_ko.sh ]; then + chmod a+x /oem/usr/ko/insmod_ko.sh + /oem/usr/ko/insmod_ko.sh +fi /usr/bin/filesystem_resize.sh usb_mode="$(cat $USB_MODE_PATH)" diff --git a/sysdrv/drv_ko/insmod_ko.sh b/sysdrv/drv_ko/insmod_ko.sh index 75464fca1..6f9b01944 100644 --- a/sysdrv/drv_ko/insmod_ko.sh +++ b/sysdrv/drv_ko/insmod_ko.sh @@ -14,7 +14,7 @@ __insmod() __rmmod_camera_sensor() { - for item in `echo "imx415 os04a10 sc4336 sc3336 sc530ai gc2053 sc200ai sc401ai sc450ai techpoint"` + for item in `echo "imx415 os04a10 sc4336 sc3336 sc530ai gc2053 sc200ai sc401ai sc450ai techpoint mis5001"` do if lsmod | grep $item | awk '{print $3}' |grep -w 0;then rmmod $item @@ -56,6 +56,7 @@ __insmod sc200ai.ko __insmod sc401ai.ko __insmod sc450ai.ko __insmod techpoint.ko +__insmod mis5001.ko __insmod video_rkcif.ko __insmod video_rkisp.ko diff --git a/sysdrv/tools/board/kernel/rv1103-luckfox-pico-ipc.dtsi b/sysdrv/source/kernel/arch/arm/boot/dts/rv1103-luckfox-pico-ipc.dtsi similarity index 100% rename from sysdrv/tools/board/kernel/rv1103-luckfox-pico-ipc.dtsi rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1103-luckfox-pico-ipc.dtsi diff --git a/sysdrv/tools/board/kernel/rv1103g-luckfox-pico-mini.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico-mini.dts similarity index 100% rename from sysdrv/tools/board/kernel/rv1103g-luckfox-pico-mini.dts rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico-mini.dts diff --git a/sysdrv/tools/board/kernel/rv1103g-luckfox-pico-plus.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico-plus.dts similarity index 100% rename from sysdrv/tools/board/kernel/rv1103g-luckfox-pico-plus.dts rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico-plus.dts diff --git a/sysdrv/tools/board/kernel/rv1103g-luckfox-pico-webbee.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico-webbee.dts similarity index 100% rename from sysdrv/tools/board/kernel/rv1103g-luckfox-pico-webbee.dts rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico-webbee.dts diff --git a/sysdrv/tools/board/kernel/rv1103g-luckfox-pico.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico.dts similarity index 100% rename from sysdrv/tools/board/kernel/rv1103g-luckfox-pico.dts rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico.dts diff --git a/sysdrv/tools/board/kernel/rv1106-luckfox-pico-pro-max-ipc.dtsi b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106-luckfox-pico-pro-max-ipc.dtsi similarity index 89% rename from sysdrv/tools/board/kernel/rv1106-luckfox-pico-pro-max-ipc.dtsi rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1106-luckfox-pico-pro-max-ipc.dtsi index f4f71e863..6ddf33254 100755 --- a/sysdrv/tools/board/kernel/rv1106-luckfox-pico-pro-max-ipc.dtsi +++ b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106-luckfox-pico-pro-max-ipc.dtsi @@ -124,13 +124,7 @@ csi_dphy_input1: endpoint@1 { reg = <1>; - remote-endpoint = <&sc4336_out>; - data-lanes = <1 2>; - }; - - csi_dphy_input2: endpoint@2 { - reg = <2>; - remote-endpoint = <&sc530ai_out>; + remote-endpoint = <&mis5001_out>; data-lanes = <1 2>; }; }; @@ -175,34 +169,13 @@ }; }; - sc4336: sc4336@30 { - compatible = "smartsens,sc4336"; + mis5001: mis5001@31 { + compatible = "imagedesign,mis5001"; status = "okay"; - reg = <0x30>; + reg = <0x31>; clocks = <&cru MCLK_REF_MIPI0>; clock-names = "xvclk"; - pwdn-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&mipi_refclk_out0>; - rockchip,camera-module-index = <0>; - rockchip,camera-module-facing = "back"; - rockchip,camera-module-name = "OT01"; - rockchip,camera-module-lens-name = "40IRC_F16"; - port { - sc4336_out: endpoint { - remote-endpoint = <&csi_dphy_input1>; - data-lanes = <1 2>; - }; - }; - }; - - sc530ai: sc530ai@30 { - compatible = "smartsens,sc530ai"; - status = "okay"; - reg = <0x30>; - clocks = <&cru MCLK_REF_MIPI0>; - clock-names = "xvclk"; - pwdn-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&mipi_refclk_out0>; rockchip,camera-module-index = <0>; @@ -210,8 +183,8 @@ rockchip,camera-module-name = "CMK-OT2115-PC1"; rockchip,camera-module-lens-name = "30IRC-F16"; port { - sc530ai_out: endpoint { - remote-endpoint = <&csi_dphy_input2>; + mis5001_out: endpoint { + remote-endpoint = <&csi_dphy_input1>; data-lanes = <1 2>; }; }; diff --git a/sysdrv/tools/board/kernel/rv1106-luckfox-pico-ultra-ipc.dtsi b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106-luckfox-pico-ultra-ipc.dtsi similarity index 92% rename from sysdrv/tools/board/kernel/rv1106-luckfox-pico-ultra-ipc.dtsi rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1106-luckfox-pico-ultra-ipc.dtsi index 0c2ee1f17..ac1f1a528 100755 --- a/sysdrv/tools/board/kernel/rv1106-luckfox-pico-ultra-ipc.dtsi +++ b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106-luckfox-pico-ultra-ipc.dtsi @@ -189,7 +189,7 @@ &acodec { #sound-dai-cells = <0>; - pa-ctl-gpios = <&gpio3 RK_PD3 GPIO_ACTIVE_HIGH>; + pa-ctl-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; status = "okay"; }; @@ -249,6 +249,11 @@ data-lanes = <1 2>; }; + csi_dphy_input1: endpoint@1 { + reg = <1>; + remote-endpoint = <&mis5001_out>; + data-lanes = <1 2>; + }; }; port@1 { @@ -290,6 +295,27 @@ }; }; }; + + mis5001: mis5001@31 { + compatible = "imagedesign,mis5001"; + status = "okay"; + reg = <0x31>; + clocks = <&cru MCLK_REF_MIPI0>; + clock-names = "xvclk"; + reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&mipi_refclk_out0>; + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "CMK-OT2115-PC1"; + rockchip,camera-module-lens-name = "30IRC-F16"; + port { + mis5001_out: endpoint { + remote-endpoint = <&csi_dphy_input1>; + data-lanes = <1 2>; + }; + }; + }; }; &mipi0_csi2 { @@ -470,7 +496,7 @@ pinctrl-0 = <&uart3m0_xfer &uart3m1_xfer>; }; &uart4 { - pinctrl-0 = <&uart4m0_xfer>; + pinctrl-0 = <&uart4m0_xfer &uart4m1_xfer>; }; &uart5 { pinctrl-0 = <&uart5m1_xfer>; diff --git a/sysdrv/tools/board/kernel/rv1106g-luckfox-pico-max.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-max.dts similarity index 100% rename from sysdrv/tools/board/kernel/rv1106g-luckfox-pico-max.dts rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-max.dts diff --git a/sysdrv/tools/board/kernel/rv1106g-luckfox-pico-pro-max-fastboot.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-pro-max-fastboot.dts similarity index 100% rename from sysdrv/tools/board/kernel/rv1106g-luckfox-pico-pro-max-fastboot.dts rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-pro-max-fastboot.dts diff --git a/sysdrv/tools/board/kernel/rv1106g-luckfox-pico-pro.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-pro.dts similarity index 100% rename from sysdrv/tools/board/kernel/rv1106g-luckfox-pico-pro.dts rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-pro.dts diff --git a/sysdrv/tools/board/kernel/rv1106g-luckfox-pico-ultra-fastboot.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-ultra-fastboot.dts similarity index 100% rename from sysdrv/tools/board/kernel/rv1106g-luckfox-pico-ultra-fastboot.dts rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-ultra-fastboot.dts diff --git a/sysdrv/tools/board/kernel/rv1106g-luckfox-pico-ultra-w.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-ultra-w.dts similarity index 100% rename from sysdrv/tools/board/kernel/rv1106g-luckfox-pico-ultra-w.dts rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-ultra-w.dts diff --git a/sysdrv/tools/board/kernel/rv1106g-luckfox-pico-ultra.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-ultra.dts similarity index 100% rename from sysdrv/tools/board/kernel/rv1106g-luckfox-pico-ultra.dts rename to sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-ultra.dts diff --git a/sysdrv/tools/board/kernel/luckfox_ndis_ppp.config b/sysdrv/source/kernel/arch/arm/configs/luckfox_ndis_ppp.config similarity index 100% rename from sysdrv/tools/board/kernel/luckfox_ndis_ppp.config rename to sysdrv/source/kernel/arch/arm/configs/luckfox_ndis_ppp.config diff --git a/sysdrv/tools/board/kernel/luckfox_rv1106-docker.config b/sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106-docker.config similarity index 100% rename from sysdrv/tools/board/kernel/luckfox_rv1106-docker.config rename to sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106-docker.config diff --git a/sysdrv/tools/board/kernel/luckfox_rv1106-ndis-ppp.config b/sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106-ndis-ppp.config similarity index 100% rename from sysdrv/tools/board/kernel/luckfox_rv1106-ndis-ppp.config rename to sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106-ndis-ppp.config diff --git a/sysdrv/tools/board/kernel/luckfox_rv1106-tb.config b/sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106-tb.config similarity index 100% rename from sysdrv/tools/board/kernel/luckfox_rv1106-tb.config rename to sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106-tb.config diff --git a/sysdrv/tools/board/kernel/luckfox_rv1106_linux_defconfig b/sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106_linux_defconfig similarity index 99% rename from sysdrv/tools/board/kernel/luckfox_rv1106_linux_defconfig rename to sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106_linux_defconfig index 4712f2738..152559a29 100755 --- a/sysdrv/tools/board/kernel/luckfox_rv1106_linux_defconfig +++ b/sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106_linux_defconfig @@ -196,6 +196,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_VIDEO_ROCKCHIP_CIF=m CONFIG_VIDEO_ROCKCHIP_ISP=m CONFIG_VIDEO_RK_IRCUT=y +CONFIG_VIDEO_MIS5001=m CONFIG_VIDEO_SC3336=m CONFIG_DRM=y CONFIG_DRM_EDID=y diff --git a/sysdrv/tools/board/kernel/luckfox_rv1106_linux_tb_defconfig b/sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106_linux_tb_defconfig similarity index 100% rename from sysdrv/tools/board/kernel/luckfox_rv1106_linux_tb_defconfig rename to sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106_linux_tb_defconfig diff --git a/sysdrv/source/kernel/arch/arm/configs/rv1106-bt.config b/sysdrv/source/kernel/arch/arm/configs/rv1106-bt.config new file mode 100644 index 000000000..07e74c4bd --- /dev/null +++ b/sysdrv/source/kernel/arch/arm/configs/rv1106-bt.config @@ -0,0 +1,7 @@ +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +CONFIG_RFKILL=y +CONFIG_RFKILL_RK=y diff --git a/sysdrv/source/kernel/drivers/media/i2c/Kconfig b/sysdrv/source/kernel/drivers/media/i2c/Kconfig index 06017ba2b..c00b2b78e 100644 --- a/sysdrv/source/kernel/drivers/media/i2c/Kconfig +++ b/sysdrv/source/kernel/drivers/media/i2c/Kconfig @@ -1854,6 +1854,16 @@ config VIDEO_MIS4001 This is a Video4Linux2 sensor driver for the ImageDesign MIS4001 camera. +config VIDEO_MIS5001 + tristate "ImageDesign mis5001 sensor support" + depends on I2C && VIDEO_V4L2 + select MEDIA_CONTROLLER + select VIDEO_V4L2_SUBDEV_API + select V4L2_FWNODE + help + This is a Video4Linux2 sensor driver for the ImageDesign + MIS5001 camera. + config VIDEO_MT9M001 tristate "mt9m001 support" depends on I2C && VIDEO_V4L2 diff --git a/sysdrv/source/kernel/drivers/media/i2c/Makefile b/sysdrv/source/kernel/drivers/media/i2c/Makefile index 3073b7359..b23d8a1e6 100644 --- a/sysdrv/source/kernel/drivers/media/i2c/Makefile +++ b/sysdrv/source/kernel/drivers/media/i2c/Makefile @@ -119,6 +119,7 @@ obj-$(CONFIG_VIDEO_OV13855) += ov13855.o obj-$(CONFIG_VIDEO_OV13858) += ov13858.o obj-$(CONFIG_VIDEO_MIS2031) += mis2031.o obj-$(CONFIG_VIDEO_MIS4001) += mis4001.o +obj-$(CONFIG_VIDEO_MIS5001) += mis5001.o obj-$(CONFIG_VIDEO_MT9M001) += mt9m001.o obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o obj-$(CONFIG_VIDEO_MT9M111) += mt9m111.o diff --git a/sysdrv/source/kernel/drivers/media/i2c/mis5001.c b/sysdrv/source/kernel/drivers/media/i2c/mis5001.c new file mode 100644 index 000000000..e19f36568 --- /dev/null +++ b/sysdrv/source/kernel/drivers/media/i2c/mis5001.c @@ -0,0 +1,1661 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mis5001 driver + * + * Copyright (C) 2023 Rockchip Electronics Co., Ltd. + * + * V0.0X01.0X01 first version + */ + +//#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x02) + +#ifndef V4L2_CID_DIGITAL_GAIN +#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN +#endif + +#define MIS5001_LANES 2 +#define MIS5001_BITS_PER_SAMPLE 10 +#define MIS5001_LINK_FREQ 445500000 //891Mbps Mbps/2 = MHz +#define PIXEL_RATE_WITH_337M_10BIT (MIS5001_LINK_FREQ * 2 * \ + MIS5001_LANES / MIS5001_BITS_PER_SAMPLE) +#define MIS5001_XVCLK_FREQ 27000000 + +#define MIS5001_CHIP_ID 0x1311 +#define MIS5001_REG_CHIP_ID 0x3000 + +#define MIS5001_REG_CTRL_MODE 0x3006 +#define MIS5001_MODE_SW_STANDBY 0x2 +#define MIS5001_MODE_STREAMING 0x00 + +#define MIS5001_REG_EXPOSURE_H 0x3100 +#define MIS5001_REG_EXPOSURE_L 0x3101 +#define MIS5001_EXPOSURE_MIN 2 +#define MIS5001_EXPOSURE_STEP 1 +#define MIS5001_VTS_MAX 0x7fff + +#define MIS5001_REG_DIG_GAIN 0x3A00 +#define MIS5001_REG_DIG_FINE_GAIN 0x3A01 +#define MIS5001_REG_ANA_GAIN 0x3102 +#define MIS5001_GAIN_MIN 0x80 +#define MIS5001_GAIN_MAX (0x80 * 16) +#define MIS5001_GAIN_STEP 1 +#define MIS5001_GAIN_DEFAULT 0x80 +#define REG_DELAY 0xFFFE +#define REG_NULL 0xFFFF + +#define MIS5001_REG_TEST_PATTERN 0x3400 +#define MIS5001_TEST_PATTERN_BIT_MASK BIT(3) + +#define MIS5001_REG_VTS_H 0x310c +#define MIS5001_REG_VTS_L 0x310d + +#define MIS5001_FLIP_MIRROR_REG 0x3007 +#define MIRROR_BIT_MASK BIT(0) +#define FLIP_BIT_MASK BIT(1) + + +#define MIS5001_FETCH_EXP_H(VAL) (((VAL) >> 8) & 0xFF) +#define MIS5001_FETCH_EXP_L(VAL) ((VAL) & 0xFF) + +#define MIS5001_FETCH_AGAIN_H(VAL) (((VAL) >> 8) & 0xFF) +#define MIS5001_FETCH_AGAIN_L(VAL) ((VAL) & 0xFF) + +#define MIS5001_FETCH_MIRROR(VAL, ENABLE) (ENABLE ? VAL | 0x01 : VAL & 0xFE) +#define MIS5001_FETCH_FLIP(VAL, ENABLE) (ENABLE ? VAL | 0x02 : VAL & 0xFD) + +#define MIS5001_REG_VALUE_08BIT 1 +#define MIS5001_REG_VALUE_16BIT 2 +#define MIS5001_REG_VALUE_24BIT 3 + +#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default" +#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep" +#define MIS5001_NAME "mis5001" + + +static const char * const mis5001_supply_names[] = { + "avdd", /* Analog power */ + "dovdd", /* Digital I/O power */ + "dvdd", /* Digital core power */ +}; + +#define MIS5001_NUM_SUPPLIES ARRAY_SIZE(mis5001_supply_names) + +struct regval { + u16 addr; + u8 val; +}; + +struct mis5001_mode { + u32 bus_fmt; + u32 width; + u32 height; + struct v4l2_fract max_fps; + u32 hts_def; + u32 vts_def; + u32 exp_def; + const struct regval *reg_list; + u32 hdr_mode; + u32 vc[PAD_MAX]; +}; + +struct mis5001 { + struct i2c_client *client; + struct clk *xvclk; + struct gpio_desc *reset_gpio; + struct gpio_desc *pwdn_gpio; + struct regulator_bulk_data supplies[MIS5001_NUM_SUPPLIES]; + + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + struct pinctrl_state *pins_sleep; + + struct v4l2_subdev subdev; + struct media_pad pad; + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *anal_gain; + struct v4l2_ctrl *digi_gain; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *test_pattern; + struct mutex mutex; + bool streaming; + bool power_on; + const struct mis5001_mode *cur_mode; + struct v4l2_fract cur_fps; + u32 module_index; + const char *module_facing; + const char *module_name; + const char *len_name; + u32 cur_vts; +}; + +#define to_mis5001(sd) container_of(sd, struct mis5001, subdev) + +/* + * Xclk 27Mhz + */ +static const struct regval mis5001_global_regs[] = { + {REG_NULL, 0x00}, +}; + +/* + * Xclk 27Mhz + * max_framerate 25fps + * mipi_datarate per lane 337.5Mbps, 2lane + */ +static const struct regval mis5001_linear_10_2592x1944_regs[] = { +//Sensor revision:Mis5001 +//Input clock frequency:27M +//Image output size:2592x1944 +//Frame timing and frame rate:Linear 25Fps +//System clock frequency:148.5M +//Output interface and data rate:MIPI 2Lane RAW10 891Mbps +//HTS = 310e/310f =0xBB8 +//VTS = 310c/310d =0x7BC +//Tline = 21.04377us + {0x300a, 0x01}, + {0x3006, 0x02}, + {REG_DELAY, 0x2d}, + {0x3307, 0x84}, + {0x310f, 0xb8}, + {0x310e, 0x0b}, + {0x4220, 0x2b}, + {0x4221, 0x6b}, + {0x4222, 0xab}, + {0x4223, 0xeb}, + {0x3011, 0x2b}, + {0x3302, 0x02}, + {0x310d, 0xbc}, + {0x310c, 0x07}, + {0x3115, 0x00}, + {0x3114, 0x00}, + {0x3117, 0x1f}, + {0x3116, 0x0a}, + {0x3111, 0x00}, + {0x3110, 0x00}, + {0x3113, 0x99}, + {0x3112, 0x07}, + {0x3128, 0x0f}, //FW<4096 FFF + {0x3129, 0xff}, + {0x3012, 0x03}, + {0x3306, 0x01}, + {0x3309, 0x01}, + {0x330a, 0x04}, + {0x330b, 0x09}, + {0x3f00, 0x01}, + {0x3f02, 0x07}, + {0x3f01, 0x00}, + {0x3f04, 0x2a}, + {0x3f03, 0x00}, + {0x3f06, 0xa5}, + {0x3f05, 0x04}, + {0x3f08, 0xff}, + {0x3f07, 0x1f}, + {0x3f0a, 0xa4}, + {0x3f09, 0x01}, + {0x3f0c, 0x38}, + {0x3f0b, 0x00}, + {0x3f0e, 0xff}, + {0x3f0d, 0x1f}, + {0x3f10, 0xff}, + {0x3f0f, 0x1f}, + {0x3f13, 0x07}, + {0x3f12, 0x00}, + {0x3f15, 0x9d}, + {0x3f14, 0x01}, + {0x3f17, 0x31}, + {0x3f16, 0x00}, + {0x3f19, 0x73}, + {0x3f18, 0x01}, + {0x3f1b, 0x00}, + {0x3f1a, 0x00}, + {0x3f1d, 0xa9}, + {0x3f1c, 0x04}, + {0x3f1f, 0xff}, + {0x3f1e, 0x1f}, + {0x3f21, 0xff}, + {0x3f20, 0x1f}, + {0x3f23, 0x85}, + {0x3f22, 0x00}, + {0x3f25, 0x27}, + {0x3f24, 0x01}, + {0x3f28, 0x46}, + {0x3f27, 0x00}, + {0x3f2a, 0x07}, + {0x3f29, 0x00}, + {0x3f2c, 0x3f}, + {0x3f2b, 0x00}, + {0x3f2e, 0x70}, + {0x3f2d, 0x01}, + {0x3f30, 0x38}, + {0x3f2f, 0x00}, + {0x3f32, 0x3f}, + {0x3f31, 0x00}, + {0x3f34, 0xd1}, + {0x3f33, 0x00}, + {0x3f36, 0xc0}, + {0x3f35, 0x00}, + {0x3f38, 0x2f}, + {0x3f37, 0x02}, + {0x3f3a, 0x5d}, + {0x3f39, 0x02}, + {0x3f4f, 0x5d}, + {0x3f4e, 0x02}, + {0x3f51, 0x5d}, + {0x3f50, 0x02}, + {0x3f53, 0x5d}, + {0x3f52, 0x02}, + {0x3f55, 0x50}, + {0x3f54, 0x02}, + {0x3f3c, 0x9a}, + {0x3f3b, 0x00}, + {0x3f3e, 0x09}, + {0x3f3d, 0x04}, + {0x3f40, 0x93}, + {0x3f3f, 0x01}, + {0x3f42, 0x8f}, + {0x3f41, 0x00}, + {0x3f44, 0xb0}, + {0x3f43, 0x04}, + {0x312b, 0x4a}, + {0x312a, 0x00}, + {0x312f, 0xb2}, + {0x312e, 0x00}, + {0x3124, 0x09}, + {0x4200, 0x09}, + {0x4201, 0x00}, + {0x4202, 0xa0}, + {0x4204, 0xff}, + {0x4205, 0x3f}, + {0x4214, 0x80}, + {0x420c, 0x80}, + {0x420e, 0xd0}, + {0x4216, 0x6c}, + {0x4217, 0xdc}, + {0x4218, 0x02}, + {0x4240, 0x8d}, + {0x4242, 0x03}, + {0x4224, 0x20}, + {0x4225, 0x0a}, + {0x4226, 0x98}, + {0x4227, 0x07}, + {0x4228, 0x20}, + {0x4229, 0x0a}, + {0x422a, 0x98}, + {0x422b, 0x07}, + {0x422c, 0x20}, + {0x422d, 0x0a}, + {0x422e, 0x98}, + {0x422f, 0x07}, + {0x4230, 0x20}, + {0x4231, 0x0a}, + {0x4232, 0x98}, + {0x4233, 0x07}, + {0x4509, 0x0f}, + {0x4505, 0x00}, + {0x4501, 0xff}, + {0x4502, 0x33}, + {0x4503, 0x11}, + {0x4501, 0xf0}, + {0x4502, 0x30}, + {0x4503, 0x10}, + {0x3006, 0x00}, + {0x3308, 0x04}, + {0x3A01, 0xA0}, + {0x401E, 0x3C}, + {0x401d, 0xa0}, + {0x3012, 0x03}, + {0x3500, 0x1B}, + {0x3501, 0x03}, + {0x3E00, 0x00}, + {0x3E01, 0x10}, + {0x400D, 0x30}, + {0x3508, 0x0a}, + {0x3508, 0x04}, + {0x3513, 0x01}, + {0x3514, 0x09}, + {0x3515, 0x0b}, + {0x3702, 0x80}, + {0x3704, 0x80}, + {0x3706, 0x80}, + {0x3708, 0x80}, + {0x400D, 0x30}, + {0x4004, 0x00}, + {0x4005, 0x30}, + {0x4009, 0x09}, + {0x400a, 0x48}, + {0x4006, 0x86}, + {0x4019, 0x08}, + {0x401b, 0x00}, + {0x3f42, 0x58}, + {0x3f49, 0x60}, + {0x3f38, 0x38}, + {0x3006, 0x00}, + {REG_NULL, 0x00}, +}; + +static const struct mis5001_mode supported_modes[] = { + { + .width = 2592, + .height = 1944, + .max_fps = { + .numerator = 10000, + .denominator = 300000, + }, + .exp_def = 0x0040, + .hts_def = 0xbb8, + .vts_def = 0x7bc, + .bus_fmt = MEDIA_BUS_FMT_SGRBG10_1X10, + .reg_list = mis5001_linear_10_2592x1944_regs, + .hdr_mode = NO_HDR, + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, + } +}; + +static const s64 link_freq_menu_items[] = { + MIS5001_LINK_FREQ +}; + +static const char * const mis5001_test_pattern_menu[] = { + "Disabled", + "Vertical Color Bar Type 1", + "Vertical Color Bar Type 2", + "Vertical Color Bar Type 3", + "Vertical Color Bar Type 4" +}; + +static int mis5001_write_reg(struct i2c_client *client, u16 reg, + u32 len, u32 val) +{ + u32 buf_i, val_i; + u8 buf[6]; + u8 *val_p; + __be32 val_be; + + if (len > 4) + return -EINVAL; + + buf[0] = reg >> 8; + buf[1] = reg & 0xff; + + val_be = cpu_to_be32(val); + val_p = (u8 *)&val_be; + buf_i = 2; + val_i = 4 - len; + + while (val_i < 4) + buf[buf_i++] = val_p[val_i++]; + + if (i2c_master_send(client, buf, len + 2) != len + 2) + return -EIO; + return 0; +} + +static int mis5001_write_array(struct i2c_client *client, + const struct regval *regs) +{ + u32 i; + int ret = 0; + + for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) + ret = mis5001_write_reg(client, regs[i].addr, + MIS5001_REG_VALUE_08BIT, regs[i].val); + + return ret; +} + +/* Read registers up to 4 at a time */ +static int mis5001_read_reg(struct i2c_client *client, u16 reg, unsigned int len, + u32 *val) +{ + struct i2c_msg msgs[2]; + u8 *data_be_p; + __be32 data_be = 0; + __be16 reg_addr_be = cpu_to_be16(reg); + int ret; + + if (len > 4 || !len) + return -EINVAL; + + data_be_p = (u8 *)&data_be; + /* Write register address */ + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = 2; + msgs[0].buf = (u8 *)®_addr_be; + + /* Read data from register */ + msgs[1].addr = client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = len; + msgs[1].buf = &data_be_p[4 - len]; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret != ARRAY_SIZE(msgs)) + return -EIO; + + *val = be32_to_cpu(data_be); + + return 0; +} + +static void mis5001_set_orientation_reg(struct mis5001 *mis5001, u32 en_flip_mir) +{ +/* switch (en_flip_mir) { + case 0: + mis5001_write_reg(mis5001->client, 0x3007, MIS5001_REG_VALUE_08BIT, 0x00); + mis5001_write_reg(mis5001->client, 0x3111, MIS5001_REG_VALUE_08BIT, 0x00); + mis5001_write_reg(mis5001->client, 0x3113, MIS5001_REG_VALUE_08BIT, 0x99); + mis5001_write_reg(mis5001->client, 0x3115, MIS5001_REG_VALUE_08BIT, 0x00); + mis5001_write_reg(mis5001->client, 0x3117, MIS5001_REG_VALUE_08BIT, 0x1f); + break; + case 1: + mis5001_write_reg(mis5001->client, 0x3007, MIS5001_REG_VALUE_08BIT, 0x01); + mis5001_write_reg(mis5001->client, 0x3111, MIS5001_REG_VALUE_08BIT, 0x00); + mis5001_write_reg(mis5001->client, 0x3113, MIS5001_REG_VALUE_08BIT, 0x99); + mis5001_write_reg(mis5001->client, 0x3115, MIS5001_REG_VALUE_08BIT, 0x01); + mis5001_write_reg(mis5001->client, 0x3117, MIS5001_REG_VALUE_08BIT, 0x20); + break; + case 2: + mis5001_write_reg(mis5001->client, 0x3007, MIS5001_REG_VALUE_08BIT, 0x01); + mis5001_write_reg(mis5001->client, 0x3111, MIS5001_REG_VALUE_08BIT, 0x01); + mis5001_write_reg(mis5001->client, 0x3113, MIS5001_REG_VALUE_08BIT, 0x9a); + mis5001_write_reg(mis5001->client, 0x3115, MIS5001_REG_VALUE_08BIT, 0x00); + mis5001_write_reg(mis5001->client, 0x3117, MIS5001_REG_VALUE_08BIT, 0x1f); + break; + case 3: + mis5001_write_reg(mis5001->client, 0x3007, MIS5001_REG_VALUE_08BIT, 0x03); + mis5001_write_reg(mis5001->client, 0x3111, MIS5001_REG_VALUE_08BIT, 0x01); + mis5001_write_reg(mis5001->client, 0x3113, MIS5001_REG_VALUE_08BIT, 0x9a); + mis5001_write_reg(mis5001->client, 0x3115, MIS5001_REG_VALUE_08BIT, 0x01); + mis5001_write_reg(mis5001->client, 0x3117, MIS5001_REG_VALUE_08BIT, 0x20); + break; + default: + break; + }*/ +} + +static int mis5001_set_gain_reg(struct mis5001 *mis5001, u32 gain) +{ + u8 gain_h, gain_l, u8Reg0x3102, u8Reg0x3a00, u8Reg0x3a01, u8Reg0x4003; + int ret = 0; + u8 u8Reg0x401d = 0; + + dev_dbg(&(mis5001->client->dev), KERN_EMERG "---------gain is %d\n\n", gain); + + if (gain < 128) + gain = 128; + else if (gain > MIS5001_GAIN_MAX) + gain = MIS5001_GAIN_MAX; + + if (128 <= gain && gain < 256) {//128 * 2 + gain_h = 0; + gain_l = (gain - 128) / 4; + u8Reg0x3a00 = 0; + u8Reg0x3a01 = 160; + } else if (gain >= 256 && gain < 512) {//128 * 4 + gain_h = 1; + gain_l = (gain - 256) / 8; + u8Reg0x3a00 = 0; + u8Reg0x3a01 = 160; + } else if (gain >= 512 && gain < 1024) {//128 * 8 + gain_h = 2; + gain_l = (gain - 512) / 16; + u8Reg0x3a00 = 0; + u8Reg0x3a01 = 160; + } else if (gain >= 1024 && gain < 2048) {//128 * 16 + gain_h = 3; + gain_l = (gain - 1024) / 32; + u8Reg0x3a00 = 0; + u8Reg0x3a01 = 160; + } else if (gain >= 2048 && gain < 4096) {//128 * 32 Dgain + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 0; + u8Reg0x3a01 = ((gain - 2048) / 16 + 128); + u8Reg0x3a01 = (u8Reg0x3a01 < 160) ? 160 : u8Reg0x3a01; + } else if (gain >= 4096 && gain < 8192) {//128 * 64 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 1; + u8Reg0x3a01 = ((gain - 4096) / 16); + } else if (gain >= 8192 && gain < 12288) {//128 * 96 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 2; + u8Reg0x3a01 = ((gain - 8192) / 16); + } else if (gain >= 12288 && gain < 16384) {//128 * 128 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 3; + u8Reg0x3a01 = ((gain - 12288) / 16); + } else if (gain >= 16384 && gain < 20480) {//128 * 160 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 4; + u8Reg0x3a01 = ((gain - 16384) / 16); + } else if (gain >= 20480 && gain < 24576) {//128 * 192 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 5; + u8Reg0x3a01 = ((gain - 20480) / 16); + } else if (gain >= 24576 && gain < 28672) {//128 * 224 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 6; + u8Reg0x3a01 = ((gain - 24576) / 16); + } else if (gain >= 28672 && gain < 32768) {//128 * 256 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 7; + u8Reg0x3a01 = ((gain - 28672) / 16); + } else { + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 7; + u8Reg0x3a01 = 255; + } + + u8Reg0x3102 = ((gain_h << 5) | gain_l); + + if (gain >= 128 && gain <= 256) { + u8Reg0x4003 = 0xb; + u8Reg0x401d = 0xa0; + } else { + u8Reg0x4003 = 0xa; + u8Reg0x401d = 0xa7; + } + + ret = mis5001_write_reg(mis5001->client, + 0x401d, + MIS5001_REG_VALUE_08BIT, + u8Reg0x401d); + + ret |= mis5001_write_reg(mis5001->client, + 0x4003, + MIS5001_REG_VALUE_08BIT, + u8Reg0x4003); + ret |= mis5001_write_reg(mis5001->client, + MIS5001_REG_DIG_GAIN, + MIS5001_REG_VALUE_08BIT, + u8Reg0x3a00); + ret |= mis5001_write_reg(mis5001->client, + MIS5001_REG_DIG_FINE_GAIN, + MIS5001_REG_VALUE_08BIT, + u8Reg0x3a01); + ret |= mis5001_write_reg(mis5001->client, + MIS5001_REG_ANA_GAIN, + MIS5001_REG_VALUE_08BIT, + u8Reg0x3102); + + return ret; +} + + +static int mis5001_get_reso_dist(const struct mis5001_mode *mode, + struct v4l2_mbus_framefmt *framefmt) +{ + return abs(mode->width - framefmt->width) + + abs(mode->height - framefmt->height); +} + +static const struct mis5001_mode * +mis5001_find_best_fit(struct v4l2_subdev_format *fmt) +{ + struct v4l2_mbus_framefmt *framefmt = &fmt->format; + int dist; + int cur_best_fit = 0; + int cur_best_fit_dist = -1; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { + dist = mis5001_get_reso_dist(&supported_modes[i], framefmt); + if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { + cur_best_fit_dist = dist; + cur_best_fit = i; + } + } + + return &supported_modes[cur_best_fit]; +} + +static int mis5001_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct mis5001 *mis5001 = to_mis5001(sd); + const struct mis5001_mode *mode; + s64 h_blank, vblank_def; + + mutex_lock(&mis5001->mutex); + + mode = mis5001_find_best_fit(fmt); + fmt->format.code = mode->bus_fmt; + fmt->format.width = mode->width; + fmt->format.height = mode->height; + fmt->format.field = V4L2_FIELD_NONE; + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; +#else + mutex_unlock(&mis5001->mutex); + return -ENOTTY; +#endif + } else { + mis5001->cur_mode = mode; + h_blank = mode->hts_def - mode->width; + __v4l2_ctrl_modify_range(mis5001->hblank, h_blank, + h_blank, 1, h_blank); + vblank_def = mode->vts_def - mode->height; + __v4l2_ctrl_modify_range(mis5001->vblank, vblank_def, + MIS5001_VTS_MAX - mode->height, + 1, vblank_def); + mis5001->cur_fps = mode->max_fps; + } + + mutex_unlock(&mis5001->mutex); + + return 0; +} + +static int mis5001_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct mis5001 *mis5001 = to_mis5001(sd); + const struct mis5001_mode *mode = mis5001->cur_mode; + + mutex_lock(&mis5001->mutex); + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); +#else + mutex_unlock(&mis5001->mutex); + return -ENOTTY; +#endif + } else { + fmt->format.width = mode->width; + fmt->format.height = mode->height; + fmt->format.code = mode->bus_fmt; + fmt->format.field = V4L2_FIELD_NONE; + /* format info: width/height/data type/virctual channel */ + if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR) + fmt->reserved[0] = mode->vc[fmt->pad]; + else + fmt->reserved[0] = mode->vc[PAD0]; + } + mutex_unlock(&mis5001->mutex); + + return 0; +} + +static int mis5001_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct mis5001 *mis5001 = to_mis5001(sd); + + if (code->index != 0) + return -EINVAL; + code->code = mis5001->cur_mode->bus_fmt; + + return 0; +} + +static int mis5001_enum_frame_sizes(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + if (fse->index >= ARRAY_SIZE(supported_modes)) + return -EINVAL; + + if (fse->code != supported_modes[0].bus_fmt) + return -EINVAL; + + fse->min_width = supported_modes[fse->index].width; + fse->max_width = supported_modes[fse->index].width; + fse->max_height = supported_modes[fse->index].height; + fse->min_height = supported_modes[fse->index].height; + + return 0; +} + +static int mis5001_enable_test_pattern(struct mis5001 *mis5001, u32 pattern) +{ + u32 val = 0; + int ret = 0; + + ret = mis5001_read_reg(mis5001->client, MIS5001_REG_TEST_PATTERN, + MIS5001_REG_VALUE_08BIT, &val); + if (pattern) + val |= MIS5001_TEST_PATTERN_BIT_MASK; + else + val &= ~MIS5001_TEST_PATTERN_BIT_MASK; + + ret |= mis5001_write_reg(mis5001->client, MIS5001_REG_TEST_PATTERN, + MIS5001_REG_VALUE_08BIT, val); + return ret; +} + +static int mis5001_g_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *fi) +{ + struct mis5001 *mis5001 = to_mis5001(sd); + const struct mis5001_mode *mode = mis5001->cur_mode; + + if (mis5001->streaming) + fi->interval = mis5001->cur_fps; + else + fi->interval = mode->max_fps; + + return 0; +} + +static int mis5001_g_mbus_config(struct v4l2_subdev *sd, + unsigned int pad_id, + struct v4l2_mbus_config *config) +{ + struct mis5001 *mis5001 = to_mis5001(sd); + const struct mis5001_mode *mode = mis5001->cur_mode; + u32 val = 1 << (MIS5001_LANES - 1) | + V4L2_MBUS_CSI2_CHANNEL_0 | + V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; + + if (mode->hdr_mode != NO_HDR) + val |= V4L2_MBUS_CSI2_CHANNEL_1; + if (mode->hdr_mode == HDR_X3) + val |= V4L2_MBUS_CSI2_CHANNEL_2; + + config->type = V4L2_MBUS_CSI2_DPHY; + config->flags = val; + + return 0; +} + +static void mis5001_get_module_inf(struct mis5001 *mis5001, + struct rkmodule_inf *inf) +{ + memset(inf, 0, sizeof(*inf)); + strscpy(inf->base.sensor, MIS5001_NAME, sizeof(inf->base.sensor)); + strscpy(inf->base.module, mis5001->module_name, + sizeof(inf->base.module)); + strscpy(inf->base.lens, mis5001->len_name, sizeof(inf->base.lens)); +} + +static long mis5001_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct mis5001 *mis5001 = to_mis5001(sd); + struct rkmodule_hdr_cfg *hdr; + u32 i, h, w; + long ret = 0; + u32 stream = 0; + + switch (cmd) { + case RKMODULE_GET_MODULE_INFO: + mis5001_get_module_inf(mis5001, (struct rkmodule_inf *)arg); + break; + case RKMODULE_GET_HDR_CFG: + hdr = (struct rkmodule_hdr_cfg *)arg; + hdr->esp.mode = HDR_NORMAL_VC; + hdr->hdr_mode = mis5001->cur_mode->hdr_mode; + break; + case RKMODULE_SET_HDR_CFG: + hdr = (struct rkmodule_hdr_cfg *)arg; + w = mis5001->cur_mode->width; + h = mis5001->cur_mode->height; + for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { + if (w == supported_modes[i].width && + h == supported_modes[i].height && + supported_modes[i].hdr_mode == hdr->hdr_mode) { + mis5001->cur_mode = &supported_modes[i]; + break; + } + } + if (i == ARRAY_SIZE(supported_modes)) { + dev_err(&mis5001->client->dev, + "not find hdr mode:%d %dx%d config\n", + hdr->hdr_mode, w, h); + ret = -EINVAL; + } else { + w = mis5001->cur_mode->hts_def - mis5001->cur_mode->width; + h = mis5001->cur_mode->vts_def - mis5001->cur_mode->height; + __v4l2_ctrl_modify_range(mis5001->hblank, w, w, 1, w); + __v4l2_ctrl_modify_range(mis5001->vblank, h, + MIS5001_VTS_MAX - mis5001->cur_mode->height, 1, h); + } + break; + case RKMODULE_SET_QUICK_STREAM: + + stream = *((u32 *)arg); + + if (stream) + ret = mis5001_write_reg(mis5001->client, MIS5001_REG_CTRL_MODE, + MIS5001_REG_VALUE_08BIT, MIS5001_MODE_STREAMING); + else + ret = mis5001_write_reg(mis5001->client, MIS5001_REG_CTRL_MODE, + MIS5001_REG_VALUE_08BIT, MIS5001_MODE_SW_STANDBY); + break; + default: + ret = -ENOIOCTLCMD; + break; + } + + return ret; +} + +#ifdef CONFIG_COMPAT +static long mis5001_compat_ioctl32(struct v4l2_subdev *sd, + unsigned int cmd, unsigned long arg) +{ + void __user *up = compat_ptr(arg); + struct rkmodule_inf *inf; + struct rkmodule_hdr_cfg *hdr; + struct preisp_hdrae_exp_s *hdrae; + long ret; + u32 stream = 0; + + switch (cmd) { + case RKMODULE_GET_MODULE_INFO: + inf = kzalloc(sizeof(*inf), GFP_KERNEL); + if (!inf) { + ret = -ENOMEM; + return ret; + } + + ret = mis5001_ioctl(sd, cmd, inf); + if (!ret) { + if (copy_to_user(up, inf, sizeof(*inf))) + ret = -EFAULT; + } + kfree(inf); + break; + case RKMODULE_GET_HDR_CFG: + hdr = kzalloc(sizeof(*hdr), GFP_KERNEL); + if (!hdr) { + ret = -ENOMEM; + return ret; + } + + ret = mis5001_ioctl(sd, cmd, hdr); + if (!ret) { + if (copy_to_user(up, hdr, sizeof(*hdr))) + ret = -EFAULT; + } + kfree(hdr); + break; + case RKMODULE_SET_HDR_CFG: + hdr = kzalloc(sizeof(*hdr), GFP_KERNEL); + if (!hdr) { + ret = -ENOMEM; + return ret; + } + + ret = copy_from_user(hdr, up, sizeof(*hdr)); + if (!ret) + ret = mis5001_ioctl(sd, cmd, hdr); + else + ret = -EFAULT; + kfree(hdr); + break; + case PREISP_CMD_SET_HDRAE_EXP: + hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL); + if (!hdrae) { + ret = -ENOMEM; + return ret; + } + + ret = copy_from_user(hdrae, up, sizeof(*hdrae)); + if (!ret) + ret = mis5001_ioctl(sd, cmd, hdrae); + else + ret = -EFAULT; + kfree(hdrae); + break; + case RKMODULE_SET_QUICK_STREAM: + ret = copy_from_user(&stream, up, sizeof(u32)); + if (!ret) + ret = mis5001_ioctl(sd, cmd, &stream); + else + ret = -EFAULT; + break; + default: + ret = -ENOIOCTLCMD; + break; + } + + return ret; +} +#endif + +static int __mis5001_start_stream(struct mis5001 *mis5001) +{ + int ret; + + ret = mis5001_write_array(mis5001->client, mis5001->cur_mode->reg_list); + if (ret) + return ret; + + /* In case these controls are set before streaming */ + ret = __v4l2_ctrl_handler_setup(&mis5001->ctrl_handler); + if (ret) + return ret; + + return mis5001_write_reg(mis5001->client, MIS5001_REG_CTRL_MODE, + MIS5001_REG_VALUE_08BIT, MIS5001_MODE_STREAMING); +} + +static int __mis5001_stop_stream(struct mis5001 *mis5001) +{ + return mis5001_write_reg(mis5001->client, MIS5001_REG_CTRL_MODE, + MIS5001_REG_VALUE_08BIT, MIS5001_MODE_SW_STANDBY); +} + +static int mis5001_s_stream(struct v4l2_subdev *sd, int on) +{ + struct mis5001 *mis5001 = to_mis5001(sd); + struct i2c_client *client = mis5001->client; + int ret = 0; + + mutex_lock(&mis5001->mutex); + on = !!on; + if (on == mis5001->streaming) + goto unlock_and_return; + + if (on) { + ret = pm_runtime_get_sync(&client->dev); + if (ret < 0) { + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } + + ret = __mis5001_start_stream(mis5001); + if (ret) { + v4l2_err(sd, "start stream failed while write regs\n"); + pm_runtime_put(&client->dev); + goto unlock_and_return; + } + } else { + __mis5001_stop_stream(mis5001); + pm_runtime_put(&client->dev); + } + + mis5001->streaming = on; + +unlock_and_return: + mutex_unlock(&mis5001->mutex); + + return ret; +} + +static int mis5001_s_power(struct v4l2_subdev *sd, int on) +{ + struct mis5001 *mis5001 = to_mis5001(sd); + struct i2c_client *client = mis5001->client; + int ret = 0; + + mutex_lock(&mis5001->mutex); + + /* If the power state is not modified - no work to do. */ + if (mis5001->power_on == !!on) + goto unlock_and_return; + + if (on) { + ret = pm_runtime_get_sync(&client->dev); + if (ret < 0) { + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } + + ret = mis5001_write_array(mis5001->client, mis5001_global_regs); + if (ret) { + v4l2_err(sd, "could not set init registers\n"); + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } + + mis5001->power_on = true; + } else { + pm_runtime_put(&client->dev); + mis5001->power_on = false; + } + +unlock_and_return: + mutex_unlock(&mis5001->mutex); + + return ret; +} + +/* Calculate the delay in us by clock rate and clock cycles */ +static inline u32 mis5001_cal_delay(u32 cycles) +{ + return DIV_ROUND_UP(cycles, MIS5001_XVCLK_FREQ / 1000 / 1000); +} + +static int __mis5001_power_on(struct mis5001 *mis5001) +{ + int ret; + u32 delay_us; + struct device *dev = &mis5001->client->dev; + + if (!IS_ERR_OR_NULL(mis5001->pins_default)) { + ret = pinctrl_select_state(mis5001->pinctrl, + mis5001->pins_default); + if (ret < 0) + dev_err(dev, "could not set pins\n"); + } + ret = clk_set_rate(mis5001->xvclk, MIS5001_XVCLK_FREQ); + if (ret < 0) + dev_warn(dev, "Failed to set xvclk rate (24MHz)\n"); + if (clk_get_rate(mis5001->xvclk) != MIS5001_XVCLK_FREQ) + dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); + ret = clk_prepare_enable(mis5001->xvclk); + if (ret < 0) { + dev_err(dev, "Failed to enable xvclk\n"); + return ret; + } + if (!IS_ERR(mis5001->reset_gpio)) + gpiod_set_value_cansleep(mis5001->reset_gpio, 0); + + ret = regulator_bulk_enable(MIS5001_NUM_SUPPLIES, mis5001->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators\n"); + goto disable_clk; + } + + if (!IS_ERR(mis5001->reset_gpio)) + gpiod_set_value_cansleep(mis5001->reset_gpio, 1); + + usleep_range(500, 1000); + if (!IS_ERR(mis5001->pwdn_gpio)) + gpiod_set_value_cansleep(mis5001->pwdn_gpio, 1); + + if (!IS_ERR(mis5001->reset_gpio)) + usleep_range(6000, 8000); + else + usleep_range(12000, 16000); + + /* 8192 cycles prior to first SCCB transaction */ + delay_us = mis5001_cal_delay(8192); + usleep_range(delay_us, delay_us * 2); + + return 0; + +disable_clk: + clk_disable_unprepare(mis5001->xvclk); + + return ret; +} + +static void __mis5001_power_off(struct mis5001 *mis5001) +{ + int ret; + struct device *dev = &mis5001->client->dev; + + if (!IS_ERR(mis5001->pwdn_gpio)) + gpiod_set_value_cansleep(mis5001->pwdn_gpio, 0); + clk_disable_unprepare(mis5001->xvclk); + if (!IS_ERR(mis5001->reset_gpio)) + gpiod_set_value_cansleep(mis5001->reset_gpio, 0); + if (!IS_ERR_OR_NULL(mis5001->pins_sleep)) { + ret = pinctrl_select_state(mis5001->pinctrl, + mis5001->pins_sleep); + if (ret < 0) + dev_dbg(dev, "could not set pins\n"); + } + regulator_bulk_disable(MIS5001_NUM_SUPPLIES, mis5001->supplies); +} + +static int mis5001_runtime_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct mis5001 *mis5001 = to_mis5001(sd); + + return __mis5001_power_on(mis5001); +} + +static int mis5001_runtime_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct mis5001 *mis5001 = to_mis5001(sd); + + __mis5001_power_off(mis5001); + + return 0; +} + +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API +static int mis5001_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct mis5001 *mis5001 = to_mis5001(sd); + struct v4l2_mbus_framefmt *try_fmt = + v4l2_subdev_get_try_format(sd, fh->pad, 0); + const struct mis5001_mode *def_mode = &supported_modes[0]; + + mutex_lock(&mis5001->mutex); + /* Initialize try_fmt */ + try_fmt->width = def_mode->width; + try_fmt->height = def_mode->height; + try_fmt->code = def_mode->bus_fmt; + try_fmt->field = V4L2_FIELD_NONE; + + mutex_unlock(&mis5001->mutex); + /* No crop or compose */ + + return 0; +} +#endif + +static int mis5001_enum_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_interval_enum *fie) +{ + if (fie->index >= ARRAY_SIZE(supported_modes)) + return -EINVAL; + + fie->code = supported_modes[fie->index].bus_fmt; + fie->width = supported_modes[fie->index].width; + fie->height = supported_modes[fie->index].height; + fie->interval = supported_modes[fie->index].max_fps; + fie->reserved[0] = supported_modes[fie->index].hdr_mode; + return 0; +} + +static const struct dev_pm_ops mis5001_pm_ops = { + SET_RUNTIME_PM_OPS(mis5001_runtime_suspend, + mis5001_runtime_resume, NULL) +}; + +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API +static const struct v4l2_subdev_internal_ops mis5001_internal_ops = { + .open = mis5001_open, +}; +#endif + +static const struct v4l2_subdev_core_ops mis5001_core_ops = { + .s_power = mis5001_s_power, + .ioctl = mis5001_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl32 = mis5001_compat_ioctl32, +#endif +}; + +static const struct v4l2_subdev_video_ops mis5001_video_ops = { + .s_stream = mis5001_s_stream, + .g_frame_interval = mis5001_g_frame_interval, +}; + +static const struct v4l2_subdev_pad_ops mis5001_pad_ops = { + .enum_mbus_code = mis5001_enum_mbus_code, + .enum_frame_size = mis5001_enum_frame_sizes, + .enum_frame_interval = mis5001_enum_frame_interval, + .get_fmt = mis5001_get_fmt, + .set_fmt = mis5001_set_fmt, + .get_mbus_config = mis5001_g_mbus_config, +}; + +static const struct v4l2_subdev_ops mis5001_subdev_ops = { + .core = &mis5001_core_ops, + .video = &mis5001_video_ops, + .pad = &mis5001_pad_ops, +}; + +static void mis5001_modify_fps_info(struct mis5001 *mis5001) +{ + const struct mis5001_mode *mode = mis5001->cur_mode; + + mis5001->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def / + mis5001->cur_vts; +} + +static int mis5001_set_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mis5001 *mis5001 = container_of(ctrl->handler, + struct mis5001, ctrl_handler); + struct i2c_client *client = mis5001->client; + s64 max; + int ret = 0; + u32 val = 0; + u32 u32Reg0x4007, expmin, expmax; + u64 sleep_time = 0; + + /* Propagate change of current control to all related controls */ + switch (ctrl->id) { + case V4L2_CID_VBLANK: + /* Update max exposure while meeting expected vblanking */ + max = mis5001->cur_mode->height + ctrl->val - 4; + __v4l2_ctrl_modify_range(mis5001->exposure, + mis5001->exposure->minimum, max, + mis5001->exposure->step, + mis5001->exposure->default_value); + break; + } + + if (!pm_runtime_get_if_in_use(&client->dev)) + return 0; + + switch (ctrl->id) { + case V4L2_CID_EXPOSURE: + dev_dbg(&(mis5001->client->dev), KERN_EMERG "set exposure 0x%x\n", ctrl->val); + if (mis5001->cur_mode->hdr_mode == NO_HDR) { + val = ctrl->val; + /* 4 least significant bits of expsoure are fractional part */ + ret = mis5001_write_reg(mis5001->client, + MIS5001_REG_EXPOSURE_H, + MIS5001_REG_VALUE_08BIT, + MIS5001_FETCH_EXP_H(val)); + ret |= mis5001_write_reg(mis5001->client, + MIS5001_REG_EXPOSURE_L, + MIS5001_REG_VALUE_08BIT, + MIS5001_FETCH_EXP_L(val)); + + /* Special strategy: To solve the problem of exposure layering: + * When the exposure is not fully filled, the gain will be increased, + * resulting in layering phenomenon + */ + + //When the exposure time is 1/200 (0.005) s, the exp register is 196 + expmin = (mis5001->cur_mode->max_fps.denominator / mis5001->cur_mode->max_fps.numerator) + * mis5001->cur_mode->vts_def * 1 / 200; + expmax = mis5001->cur_mode->vts_def - expmin; + if (((expmin <= val) && (expmax >= val))) + u32Reg0x4007 = 0x78; + else + u32Reg0x4007 = 0xc4; + + ret |= mis5001_write_reg(mis5001->client, + 0x4007, + MIS5001_REG_VALUE_08BIT, + u32Reg0x4007); + } + break; + case V4L2_CID_ANALOGUE_GAIN: + dev_dbg(&client->dev, "set gain 0x%x\n", ctrl->val); + if (mis5001->cur_mode->hdr_mode == NO_HDR) + ret = mis5001_set_gain_reg(mis5001, ctrl->val); + break; + case V4L2_CID_VBLANK: + dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val); + mis5001->cur_vts = ctrl->val + mis5001->cur_mode->height; + ret = mis5001_write_reg(mis5001->client, + MIS5001_REG_CTRL_MODE, + MIS5001_REG_VALUE_08BIT, + 0x02); + sleep_time = mis5001->cur_mode->max_fps.denominator / mis5001->cur_mode->max_fps.numerator * + mis5001->cur_mode->vts_def / mis5001->cur_vts; + sleep_time = div_u64(1000000, sleep_time); + usleep_range(sleep_time, sleep_time + 1000); + ret |= mis5001_write_reg(mis5001->client, + MIS5001_REG_VTS_H, + MIS5001_REG_VALUE_08BIT, + (ctrl->val + mis5001->cur_mode->height) + >> 8); + ret |= mis5001_write_reg(mis5001->client, + MIS5001_REG_VTS_L, + MIS5001_REG_VALUE_08BIT, + (ctrl->val + mis5001->cur_mode->height) + & 0xff); + ret |= mis5001_write_reg(mis5001->client, + MIS5001_REG_CTRL_MODE, + MIS5001_REG_VALUE_08BIT, + 0x00); + if (mis5001->cur_vts != mis5001->cur_mode->vts_def) + mis5001_modify_fps_info(mis5001); + break; + case V4L2_CID_TEST_PATTERN: + ret = mis5001_enable_test_pattern(mis5001, ctrl->val); + break; + case V4L2_CID_HFLIP: + ret = mis5001_read_reg(mis5001->client, MIS5001_FLIP_MIRROR_REG, + MIS5001_REG_VALUE_08BIT, &val); + if (ctrl->val) + val |= MIRROR_BIT_MASK; + else + val &= ~MIRROR_BIT_MASK; + mis5001_set_orientation_reg(mis5001, val); + break; + case V4L2_CID_VFLIP: + ret = mis5001_read_reg(mis5001->client, MIS5001_FLIP_MIRROR_REG, + MIS5001_REG_VALUE_08BIT, &val); + if (ctrl->val) + val |= FLIP_BIT_MASK; + else + val &= ~FLIP_BIT_MASK; + mis5001_set_orientation_reg(mis5001, val); + break; + default: + dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", + __func__, ctrl->id, ctrl->val); + break; + } + + pm_runtime_put(&client->dev); + + return ret; + +} + +static const struct v4l2_ctrl_ops mis5001_ctrl_ops = { + .s_ctrl = mis5001_set_ctrl, +}; + +static int mis5001_initialize_controls(struct mis5001 *mis5001) +{ + const struct mis5001_mode *mode; + struct v4l2_ctrl_handler *handler; + struct v4l2_ctrl *ctrl; + s64 exposure_max, vblank_def; + u32 h_blank; + int ret; + + handler = &mis5001->ctrl_handler; + mode = mis5001->cur_mode; + ret = v4l2_ctrl_handler_init(handler, 9); + if (ret) + return ret; + handler->lock = &mis5001->mutex; + + ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ, + 0, 0, link_freq_menu_items); + if (ctrl) + ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, + 0, PIXEL_RATE_WITH_337M_10BIT, 1, PIXEL_RATE_WITH_337M_10BIT); + + h_blank = mode->hts_def - mode->width; + mis5001->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, + h_blank, h_blank, 1, h_blank); + if (mis5001->hblank) + mis5001->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + vblank_def = mode->vts_def - mode->height; + mis5001->vblank = v4l2_ctrl_new_std(handler, &mis5001_ctrl_ops, + V4L2_CID_VBLANK, vblank_def, + MIS5001_VTS_MAX - mode->height, + 1, vblank_def); + mis5001->cur_fps = mode->max_fps; + exposure_max = mode->vts_def - 4; + mis5001->exposure = v4l2_ctrl_new_std(handler, &mis5001_ctrl_ops, + V4L2_CID_EXPOSURE, MIS5001_EXPOSURE_MIN, + exposure_max, MIS5001_EXPOSURE_STEP, + mode->exp_def); + mis5001->anal_gain = v4l2_ctrl_new_std(handler, &mis5001_ctrl_ops, + V4L2_CID_ANALOGUE_GAIN, MIS5001_GAIN_MIN, + MIS5001_GAIN_MAX, MIS5001_GAIN_STEP, + MIS5001_GAIN_DEFAULT); + mis5001->test_pattern = v4l2_ctrl_new_std_menu_items(handler, + &mis5001_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(mis5001_test_pattern_menu) - 1, + 0, 0, mis5001_test_pattern_menu); + v4l2_ctrl_new_std(handler, &mis5001_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(handler, &mis5001_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + if (handler->error) { + ret = handler->error; + dev_err(&mis5001->client->dev, + "Failed to init controls(%d)\n", ret); + goto err_free_handler; + } + + mis5001->subdev.ctrl_handler = handler; + + return 0; + +err_free_handler: + v4l2_ctrl_handler_free(handler); + + return ret; +} + +/* sensor id check */ +static int mis5001_check_sensor_id(struct mis5001 *mis5001, + struct i2c_client *client) +{ + struct device *dev = &mis5001->client->dev; + u32 id = 0; + int ret; + + ret = mis5001_read_reg(client, MIS5001_REG_CHIP_ID, + MIS5001_REG_VALUE_16BIT, &id); + + if (id != MIS5001_CHIP_ID) { + dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret); + return -ENODEV; + } + + dev_info(dev, "Detected mis4001 %04x sensor\n", MIS5001_CHIP_ID); + + return 0; +} + +static int mis5001_configure_regulators(struct mis5001 *mis5001) +{ + unsigned int i; + + for (i = 0; i < MIS5001_NUM_SUPPLIES; i++) + mis5001->supplies[i].supply = mis5001_supply_names[i]; + + return devm_regulator_bulk_get(&mis5001->client->dev, + MIS5001_NUM_SUPPLIES, + mis5001->supplies); +} + +static int mis5001_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct device_node *node = dev->of_node; + struct mis5001 *mis5001; + struct v4l2_subdev *sd; + char facing[2]; + int ret; + + dev_info(dev, "driver version: %02x.%02x.%02x", + DRIVER_VERSION >> 16, + (DRIVER_VERSION & 0xff00) >> 8, + DRIVER_VERSION & 0x00ff); + + mis5001 = devm_kzalloc(dev, sizeof(*mis5001), GFP_KERNEL); + if (!mis5001) + return -ENOMEM; + + ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX, + &mis5001->module_index); + ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING, + &mis5001->module_facing); + ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME, + &mis5001->module_name); + ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME, + &mis5001->len_name); + if (ret) { + dev_err(dev, "could not get module information!\n"); + return -EINVAL; + } + + mis5001->client = client; + mis5001->cur_mode = &supported_modes[0]; + + mis5001->xvclk = devm_clk_get(dev, "xvclk"); + if (IS_ERR(mis5001->xvclk)) { + dev_err(dev, "Failed to get xvclk\n"); + return -EINVAL; + } + + mis5001->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(mis5001->reset_gpio)) + dev_warn(dev, "Failed to get reset-gpios\n"); + + mis5001->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); + if (IS_ERR(mis5001->pwdn_gpio)) + dev_warn(dev, "Failed to get pwdn-gpios\n"); + + mis5001->pinctrl = devm_pinctrl_get(dev); + if (!IS_ERR(mis5001->pinctrl)) { + mis5001->pins_default = + pinctrl_lookup_state(mis5001->pinctrl, + OF_CAMERA_PINCTRL_STATE_DEFAULT); + if (IS_ERR(mis5001->pins_default)) + dev_err(dev, "could not get default pinstate\n"); + + mis5001->pins_sleep = + pinctrl_lookup_state(mis5001->pinctrl, + OF_CAMERA_PINCTRL_STATE_SLEEP); + if (IS_ERR(mis5001->pins_sleep)) + dev_err(dev, "could not get sleep pinstate\n"); + } else { + dev_err(dev, "no pinctrl\n"); + } + + ret = mis5001_configure_regulators(mis5001); + if (ret) { + dev_err(dev, "Failed to get power regulators\n"); + return ret; + } + + mutex_init(&mis5001->mutex); + + sd = &mis5001->subdev; + v4l2_i2c_subdev_init(sd, client, &mis5001_subdev_ops); + ret = mis5001_initialize_controls(mis5001); + if (ret) + goto err_destroy_mutex; + + ret = __mis5001_power_on(mis5001); + if (ret) + goto err_free_handler; + + ret = mis5001_check_sensor_id(mis5001, client); + if (ret) + goto err_power_off; + +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + sd->internal_ops = &mis5001_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | + V4L2_SUBDEV_FL_HAS_EVENTS; +#endif +#if defined(CONFIG_MEDIA_CONTROLLER) + mis5001->pad.flags = MEDIA_PAD_FL_SOURCE; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; + ret = media_entity_pads_init(&sd->entity, 1, &mis5001->pad); + if (ret < 0) + goto err_power_off; +#endif + + memset(facing, 0, sizeof(facing)); + if (strcmp(mis5001->module_facing, "back") == 0) + facing[0] = 'b'; + else + facing[0] = 'f'; + + snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", + mis5001->module_index, facing, + MIS5001_NAME, dev_name(sd->dev)); + ret = v4l2_async_register_subdev_sensor_common(sd); + if (ret) { + dev_err(dev, "v4l2 async register subdev failed\n"); + goto err_clean_entity; + } + + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_runtime_idle(dev); + + return 0; + +err_clean_entity: +#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&sd->entity); +#endif +err_power_off: + __mis5001_power_off(mis5001); +err_free_handler: + v4l2_ctrl_handler_free(&mis5001->ctrl_handler); +err_destroy_mutex: + mutex_destroy(&mis5001->mutex); + + return ret; +} + +static int mis5001_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct mis5001 *mis5001 = to_mis5001(sd); + + v4l2_async_unregister_subdev(sd); +#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&sd->entity); +#endif + v4l2_ctrl_handler_free(&mis5001->ctrl_handler); + mutex_destroy(&mis5001->mutex); + + pm_runtime_disable(&client->dev); + if (!pm_runtime_status_suspended(&client->dev)) + __mis5001_power_off(mis5001); + pm_runtime_set_suspended(&client->dev); + + return 0; +} + +#if IS_ENABLED(CONFIG_OF) +static const struct of_device_id mis5001_of_match[] = { + { .compatible = "imagedesign,mis5001" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mis5001_of_match); +#endif + +static const struct i2c_device_id mis5001_match_id[] = { + { "imagedesign,mis5001", 0 }, + { }, +}; + +static struct i2c_driver mis5001_i2c_driver = { + .driver = { + .name = MIS5001_NAME, + .pm = &mis5001_pm_ops, + .of_match_table = of_match_ptr(mis5001_of_match), + }, + .probe = &mis5001_probe, + .remove = &mis5001_remove, + .id_table = mis5001_match_id, +}; + +static int __init sensor_mod_init(void) +{ + return i2c_add_driver(&mis5001_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&mis5001_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION("chengdu image design mis5001 sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/sysdrv/source/kernel/drivers/of/Kconfig b/sysdrv/source/kernel/drivers/of/Kconfig index c177b4208..ae591abde 100644 --- a/sysdrv/source/kernel/drivers/of/Kconfig +++ b/sysdrv/source/kernel/drivers/of/Kconfig @@ -121,4 +121,11 @@ config OF_DMA_DEFAULT_COHERENT # arches should select this if DMA is coherent by default for OF devices bool +config OF_DTBO + bool "Device Tree DTBO" + select OF_DYNAMIC + select OF_FLATTREE + select OF_RESOLVE + help + Device Tree DTBO endif # OF diff --git a/sysdrv/source/kernel/drivers/of/Makefile b/sysdrv/source/kernel/drivers/of/Makefile index 6e1e5212f..8b4510e79 100644 --- a/sysdrv/source/kernel/drivers/of/Makefile +++ b/sysdrv/source/kernel/drivers/of/Makefile @@ -13,5 +13,6 @@ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o obj-$(CONFIG_OF_RESOLVE) += resolver.o obj-$(CONFIG_OF_OVERLAY) += overlay.o obj-$(CONFIG_OF_NUMA) += of_numa.o +obj-$(CONFIG_OF_DTBO) += dtbocfg.o obj-$(CONFIG_OF_UNITTEST) += unittest-data/ diff --git a/sysdrv/source/kernel/drivers/of/dtbocfg.c b/sysdrv/source/kernel/drivers/of/dtbocfg.c new file mode 100644 index 000000000..027bdd1ca --- /dev/null +++ b/sysdrv/source/kernel/drivers/of/dtbocfg.c @@ -0,0 +1,429 @@ +/********************************************************************************* + * + * Copyright (C) 2016-2023 Ichiro Kawazome + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "dtbocfg" +#define DRIVER_VERSION "0.1.0" + +/** + * Device Tree Overlay Item Structure + */ +struct dtbocfg_overlay_item { + struct config_item item; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)) + struct device_node* node; +#endif + int id; + void* dtbo; + int dtbo_size; +}; + +/** + * dtbocfg_overlay_create() - Create Device Tree Overlay + * @overlay: Pointer to Device Tree Overlay Item + * return Success(0) or Error Status. + */ +static int dtbocfg_overlay_item_create(struct dtbocfg_overlay_item *overlay) +{ + int ret_val; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) + { + int ovcs_id = 0; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)) + ret_val = of_overlay_fdt_apply(overlay->dtbo,overlay->dtbo_size, &ovcs_id, NULL); +#else + ret_val = of_overlay_fdt_apply(overlay->dtbo,overlay->dtbo_size, &ovcs_id); +#endif + if (ret_val != 0) { + pr_err("%s: Failed to apply overlay (ret_val=%d)\n", __func__, ret_val); + goto failed; + } + overlay->id = ovcs_id; + pr_debug("%s: apply OK(id=%d)\n", __func__, ovcs_id); + } +#else + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) + of_fdt_unflatten_tree(overlay->dtbo, NULL, &overlay->node); +#else + of_fdt_unflatten_tree(overlay->dtbo, &overlay->node); +#endif + if (overlay->node == NULL) { + pr_err("%s: failed to unflatten tree\n", __func__); + ret_val = -EINVAL; + goto failed; + } + pr_debug("%s: unflattened OK\n", __func__); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + { + int ovcs_id = 0; + + ret_val = of_overlay_apply(overlay->node, &ovcs_id); + if (ret_val != 0) { + pr_err("%s: Failed to apply overlay (ret_val=%d)\n", __func__, ret_val); + goto failed; + } + overlay->id = ovcs_id; + pr_debug("%s: apply OK(id=%d)\n", __func__, ovcs_id); + } +#else + { + of_node_set_flag(overlay->node, OF_DETACHED); + + ret_val = of_resolve_phandles(overlay->node); + if (ret_val != 0) { + pr_err("%s: Failed to resolve tree\n", __func__); + goto failed; + } + pr_debug("%s: resolved OK\n", __func__); + + ret_val = of_overlay_create(overlay->node); + if (ret_val < 0) { + pr_err("%s: Failed to create overlay (ret_val=%d)\n", __func__, ret_val); + goto failed; + } + overlay->id = ret_val; + } +#endif + +#endif + pr_debug("%s: create OK\n", __func__); + return 0; + + failed: + return ret_val; +} + +/** + * dtbocfg_overlay_item_release() - Relase Device Tree Overlay + * @overlay: Pointer to Device Tree Overlay Item + * return none + */ +static void dtbocfg_overlay_item_release(struct dtbocfg_overlay_item *overlay) +{ + if (overlay->id >= 0) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + of_overlay_remove(&overlay->id); +#else + of_overlay_destroy(overlay->id); +#endif + overlay->id = -1; + } +} + +/** + * container_of_dtbocfg_overlay_item() - Get Device Tree Overlay Item Pointer from Configuration Item + * @item: Pointer to Configuration Item + * return Pointer to Device Tree Overlay Item + */ +static inline struct dtbocfg_overlay_item* container_of_dtbocfg_overlay_item(struct config_item *item) +{ + return item ? container_of(item, struct dtbocfg_overlay_item, item) : NULL; +} + +/** + * dtbocfg_overlay_item_status_store() - Set Status Attibute + * @item: Pointer to Configuration Item + * @page: Pointer to Value Buffer + * @count: Size of Value Buffer Size + * return Stored Size or Error Status. + */ +static ssize_t dtbocfg_overlay_item_status_store(struct config_item *item, const char *buf, size_t count) +{ + struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); + ssize_t status; + unsigned long value; + if (0 != (status = kstrtoul(buf, 10, &value))) { + goto failed; + } + if (value == 0) { + if (overlay->id >= 0) { + dtbocfg_overlay_item_release(overlay); + } + } else { + if (overlay->id < 0) { + dtbocfg_overlay_item_create(overlay); + } + } + return count; + failed: + return -EPERM; +} + +/** + * dtbocfg_overlay_item_status_show() - Show Status Attibute + * @item : Pointer to Configuration Item + * @page : Pointer to Value for Store + * return String Size or Error Status. + */ +static ssize_t dtbocfg_overlay_item_status_show(struct config_item *item, char *page) +{ + struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); + return sprintf(page, "%d\n", overlay->id >= 0 ? 1 : 0); +} + +/** + * dtbocfg_overlay_item_dtbo_write() - Write Device Tree Blob to Configuration Item + * @item : Pointer to Configuration Item + * @page : Pointer to Value Buffer + * @count: Size of Value Buffer + * return Stored Size or Error Status. + */ +static ssize_t dtbocfg_overlay_item_dtbo_write(struct config_item *item, const void *buf, size_t count) +{ + struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); + + if (overlay->dtbo_size > 0) { + if (overlay->id >= 0) { + return -EPERM; + } + kfree(overlay->dtbo); + overlay->dtbo = NULL; + overlay->dtbo_size = 0; + } + + overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); + if (overlay->dtbo == NULL) { + overlay->dtbo_size = 0; + return -ENOMEM; + } else { + overlay->dtbo_size = count; + return count; + } +} + +/** + * dtbocfg_overlay_item_dtbo_read() - Read Device Tree Blob from Configuration Item + * @item : Pointer to Configuration Item + * @page : Pointer to Value for Store, or NULL to query the buffer size + * @size : Size of the supplied buffer + * return Read Size + */ +static ssize_t dtbocfg_overlay_item_dtbo_read(struct config_item *item, void *buf, size_t size) +{ + struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); + + if (overlay->dtbo == NULL) + return 0; + + if (buf != NULL) + memcpy(buf, overlay->dtbo, overlay->dtbo_size); + + return overlay->dtbo_size; +} + +/** + * Device Tree Blob Overlay Attribute Structure + */ +CONFIGFS_BIN_ATTR(dtbocfg_overlay_item_, dtbo, NULL, 1024 * 1024); // 1MiB should be way more than enough +CONFIGFS_ATTR(dtbocfg_overlay_item_, status); + +static struct configfs_attribute *dtbocfg_overlay_attrs[] = { + &dtbocfg_overlay_item_attr_status, + NULL, +}; + +static struct configfs_bin_attribute *dtbocfg_overlay_bin_attrs[] = { + &dtbocfg_overlay_item_attr_dtbo, + NULL, +}; + +/** + * dtbocfg_overlay_release() - Release Device Tree Overlay Item + * @item : Pointer to Configuration Item + * Return None + */ +static void dtbocfg_overlay_release(struct config_item *item) +{ + struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); + + pr_debug("%s\n", __func__); + + dtbocfg_overlay_item_release(overlay); + + if (overlay->dtbo) { + kfree(overlay->dtbo); + overlay->dtbo = NULL; + overlay->dtbo_size = 0; + } + + kfree(overlay); +} + +/** + * Device Tree Blob Overlay Item Structure + */ +static struct configfs_item_operations dtbocfg_overlay_item_ops = { + .release = dtbocfg_overlay_release, +}; + +static struct config_item_type dtbocfg_overlay_item_type = { + .ct_item_ops = &dtbocfg_overlay_item_ops, + .ct_attrs = dtbocfg_overlay_attrs, + .ct_bin_attrs = dtbocfg_overlay_bin_attrs, + .ct_owner = THIS_MODULE, +}; + +/** + * dtbocfg_overlay_group_make_item() - Make Device Tree Overlay Group Item + * @group: Pointer to Configuration Group + * @name : Pointer to Group Name + * Return Pointer to Device Tree Overlay Group Item + */ +static struct config_item *dtbocfg_overlay_group_make_item(struct config_group *group, const char *name) +{ + struct dtbocfg_overlay_item *overlay; + + pr_debug("%s\n", __func__); + + overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); + + if (!overlay) + return ERR_PTR(-ENOMEM); + overlay->id = -1; + overlay->dtbo = NULL; + overlay->dtbo_size = 0; + + config_item_init_type_name(&overlay->item, name, &dtbocfg_overlay_item_type); + return &overlay->item; +} + +/** + * dtbocfg_overlay_group_drop_item() - Drop Device Tree Overlay Group Item + * @group: Pointer to Configuration Group + * @item : Pointer to Device Tree Overlay Group Item + */ +static void dtbocfg_overlay_group_drop_item(struct config_group *group, struct config_item *item) +{ + struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); + + pr_debug("%s\n", __func__); + + config_item_put(&overlay->item); +} + +/** + * Device Tree Blob Overlay Sub Group Structures + */ +static struct configfs_group_operations dtbocfg_overlays_ops = { + .make_item = dtbocfg_overlay_group_make_item, + .drop_item = dtbocfg_overlay_group_drop_item, +}; + +static struct config_item_type dtbocfg_overlays_type = { + .ct_group_ops = &dtbocfg_overlays_ops, + .ct_owner = THIS_MODULE, +}; + +static struct config_group dtbocfg_overlay_group; + +/** + * Device Tree Blob Overlay Root Sub System Structures + */ +static struct configfs_group_operations dtbocfg_root_ops = { + /* empty - we don't allow anything to be created */ +}; + +static struct config_item_type dtbocfg_root_type = { + .ct_group_ops = &dtbocfg_root_ops, + .ct_owner = THIS_MODULE, +}; + +static struct configfs_subsystem dtbocfg_root_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "device-tree", + .ci_type = &dtbocfg_root_type, + }, + }, + .su_mutex = __MUTEX_INITIALIZER(dtbocfg_root_subsys.su_mutex), +}; + +/** + * dtbocfg_module_init() + */ +static int __init dtbocfg_module_init(void) +{ + int retval = 0; + + pr_info(DRIVER_NAME ": " DRIVER_VERSION "\n"); + + config_group_init(&dtbocfg_root_subsys.su_group); + config_group_init_type_name(&dtbocfg_overlay_group, "overlays", &dtbocfg_overlays_type); + + retval = configfs_register_subsystem(&dtbocfg_root_subsys); + if (retval != 0) { + pr_err( "%s: couldn't register subsys\n", __func__); + goto register_subsystem_failed; + } + + retval = configfs_register_group(&dtbocfg_root_subsys.su_group, &dtbocfg_overlay_group); + if (retval != 0) { + pr_err( "%s: couldn't register group\n", __func__); + goto register_group_failed; + } + + pr_info(DRIVER_NAME ": OK\n"); + return 0; + + register_group_failed: + configfs_unregister_subsystem(&dtbocfg_root_subsys); + register_subsystem_failed: + return retval; +} + +/** + * dtbocfg_module_exit() + */ +static void __exit dtbocfg_module_exit(void) +{ + configfs_unregister_group(&dtbocfg_overlay_group); + configfs_unregister_subsystem(&dtbocfg_root_subsys); +} + +module_init(dtbocfg_module_init); +module_exit(dtbocfg_module_exit); + +MODULE_AUTHOR("ikwzm"); +MODULE_DESCRIPTION("Device Tree Overlay Configuration File System"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sysdrv/source/kernel/drivers/of/overlay.c b/sysdrv/source/kernel/drivers/of/overlay.c index c8a0c0e9d..43a77d720 100644 --- a/sysdrv/source/kernel/drivers/of/overlay.c +++ b/sysdrv/source/kernel/drivers/of/overlay.c @@ -170,7 +170,9 @@ static int overlay_notify(struct overlay_changeset *ovcs, ret = blocking_notifier_call_chain(&overlay_notify_chain, action, &nd); - if (notifier_to_errno(ret)) { + if (ret == NOTIFY_OK || ret == NOTIFY_STOP) + return 0; + if (ret) { ret = notifier_to_errno(ret); pr_err("overlay changeset %s notifier error %d, target: %pOF\n", of_overlay_action_name[action], ret, nd.target); diff --git a/sysdrv/source/kernel/drivers/pinctrl/pinctrl-rockchip.h b/sysdrv/source/kernel/drivers/pinctrl/pinctrl-rockchip.h index 80b5552fd..dbf558d0f 100644 --- a/sysdrv/source/kernel/drivers/pinctrl/pinctrl-rockchip.h +++ b/sysdrv/source/kernel/drivers/pinctrl/pinctrl-rockchip.h @@ -18,6 +18,8 @@ #ifndef _PINCTRL_ROCKCHIP_H #define _PINCTRL_ROCKCHIP_H +#include + #define RK_GPIO0_A0 0 #define RK_GPIO0_A1 1 #define RK_GPIO0_A2 2 diff --git a/sysdrv/source/kernel/drivers/staging/fbtft/fbtft-core.c b/sysdrv/source/kernel/drivers/staging/fbtft/fbtft-core.c index d0c8d85f3..2baffa436 100644 --- a/sysdrv/source/kernel/drivers/staging/fbtft/fbtft-core.c +++ b/sysdrv/source/kernel/drivers/staging/fbtft/fbtft-core.c @@ -292,9 +292,9 @@ static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line, throughput = throughput ? (len * 1000) / throughput : 0; throughput = throughput * 1000 / 1024; - dev_info(par->info->device, - "Display update: %ld kB/s, fps=%ld\n", - throughput, fps); + // dev_info(par->info->device, + // "Display update: %ld kB/s, fps=%ld\n", + // throughput, fps); par->first_update_done = true; } } diff --git a/sysdrv/source/kernel/drivers/staging/fbtft/fbtft.h b/sysdrv/source/kernel/drivers/staging/fbtft/fbtft.h index 06afaa9d5..c3b319ed7 100644 --- a/sysdrv/source/kernel/drivers/staging/fbtft/fbtft.h +++ b/sysdrv/source/kernel/drivers/staging/fbtft/fbtft.h @@ -407,7 +407,7 @@ do { \ dev_info(dev, format, ##arg); \ } while (0) -#define fbtft_par_dbg(level, par, format, arg...) \ +/*#define fbtft_par_dbg(level, par, format, arg...) \ do { \ if (unlikely((par)->debug & (level))) \ dev_info((par)->info->device, format, ##arg); \ @@ -418,6 +418,9 @@ do { \ if (unlikely((par)->debug & (level))) \ fbtft_dbg_hex(dev, sizeof(type), buf,\ (num) * sizeof(type), format, ##arg); \ -} while (0) +} while (0)*/ + +#define fbtft_par_dbg(level, par, format, arg...) ; +#define fbtft_par_dbg_hex(level, par, dev, type, buf, num, format, arg...) ; #endif /* __LINUX_FBTFT_H */ diff --git a/sysdrv/source/kernel/drivers/usb/serial/Kconfig b/sysdrv/source/kernel/drivers/usb/serial/Kconfig index 169251ec8..bc19b65c3 100644 --- a/sysdrv/source/kernel/drivers/usb/serial/Kconfig +++ b/sysdrv/source/kernel/drivers/usb/serial/Kconfig @@ -112,6 +112,15 @@ config USB_SERIAL_CH341 To compile this driver as a module, choose M here: the module will be called ch341. +config USB_SERIAL_CH343 + tristate "USB Winchiphead CH343 Single Port Serial Driver" + help + Say Y here if you want to use a Winchiphead CH343 single port + USB to serial adapter. + + To compile this driver as a module, choose M here: the + module will be called ch343. + config USB_SERIAL_WHITEHEAT tristate "USB ConnectTech WhiteHEAT Serial Driver" select USB_EZUSB_FX2 diff --git a/sysdrv/source/kernel/drivers/usb/serial/Makefile b/sysdrv/source/kernel/drivers/usb/serial/Makefile index 2d491e434..dfab84cd4 100644 --- a/sysdrv/source/kernel/drivers/usb/serial/Makefile +++ b/sysdrv/source/kernel/drivers/usb/serial/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o +obj-$(CONFIG_USB_SERIAL_CH343) += ch343.o obj-$(CONFIG_USB_SERIAL_CP210X) += cp210x.o obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o diff --git a/sysdrv/source/kernel/drivers/usb/serial/ch343.c b/sysdrv/source/kernel/drivers/usb/serial/ch343.c new file mode 100755 index 000000000..546630210 --- /dev/null +++ b/sysdrv/source/kernel/drivers/usb/serial/ch343.c @@ -0,0 +1,2000 @@ +/* + * USB serial driver for USB to UART(s) chip ch342/ch343/ch344/ch347/ch9101/ch9102/ch9103/ch9104, etc. + * + * Copyright (C) 2022 Nanjing Qinheng Microelectronics Co., Ltd. + * Web: http://wch.cn + * Author: WCH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * System required: + * Kernel version beyond 3.4.x + * Update Log: + * V1.0 - initial version + * V1.1 - added support of chip ch344, ch9101 and ch9103 + * V1.2 - added gpio support of chip ch344 + * V1.3 - added support of chip ch347 + * V1.4 - added support of chip ch9104 + * V1.5 - added gpio character device + * - added supports for kernel version beyond 5.14.x + * - removed the gpio ioctl commands + */ + +#define DEBUG +#define VERBOSE_DEBUG + +#undef DEBUG +#undef VERBOSE_DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) +#include +#endif + +#include "ch343.h" + +#define DRIVER_AUTHOR "WCH" +#define DRIVER_DESC "USB serial driver for ch342/ch343/ch344/ch347/ch9101/ch9102/ch9103/ch9104, etc." +#define VERSION_DESC "V1.5 On 2022.12" + +#define IOCTL_MAGIC 'W' +#define IOCTL_CMD_GETCHIPTYPE _IOR(IOCTL_MAGIC, 0x84, u16) +#define IOCTL_CMD_CTRLIN _IOWR(IOCTL_MAGIC, 0x90, u16) +#define IOCTL_CMD_CTRLOUT _IOW(IOCTL_MAGIC, 0x91, u16) +#define IOCTL_CMD_GICOUNT _IOR(IOCTL_MAGIC, 0x92, u16) + +static struct usb_driver ch343_driver; +static struct tty_driver *ch343_tty_driver; +static struct usb_interface *g_intf; + +static DEFINE_IDR(ch343_minors); +static DEFINE_MUTEX(ch343_minors_lock); + +static void ch343_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old); + +/* + * Look up an ch343 structure by minor. If found and not disconnected, increment + * its refcount and return it with its mutex held. + */ +static struct ch343 *ch343_get_by_minor(unsigned int minor) +{ + struct ch343 *ch343; + + mutex_lock(&ch343_minors_lock); + ch343 = idr_find(&ch343_minors, minor); + if (ch343) { + mutex_lock(&ch343->mutex); + if (ch343->disconnected) { + mutex_unlock(&ch343->mutex); + ch343 = NULL; + } else { + tty_port_get(&ch343->port); + mutex_unlock(&ch343->mutex); + } + } + mutex_unlock(&ch343_minors_lock); + return ch343; +} + +/* + * Try to find an available minor number and if found, associate it with 'ch343'. + */ +static int ch343_alloc_minor(struct ch343 *ch343) +{ + int minor; + + mutex_lock(&ch343_minors_lock); + minor = idr_alloc(&ch343_minors, ch343, 0, CH343_TTY_MINORS, GFP_KERNEL); + mutex_unlock(&ch343_minors_lock); + + return minor; +} + +/* Release the minor number associated with 'ch343'. */ +static void ch343_release_minor(struct ch343 *ch343) +{ + mutex_lock(&ch343_minors_lock); + idr_remove(&ch343_minors, ch343->minor); + mutex_unlock(&ch343_minors_lock); +} + +/* + * Functions for CH343 control messages. + */ +static int ch343_control_out(struct ch343 *ch343, u8 request, u16 value, u16 index) +{ + int retval; + + retval = usb_autopm_get_interface(ch343->control); + if (retval) + return retval; + + retval = usb_control_msg(ch343->dev, usb_sndctrlpipe(ch343->dev, 0), request, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, value, index, NULL, 0, DEFAULT_TIMEOUT); + + usb_autopm_put_interface(ch343->control); + + return retval; +} + +static int ch343_control_in(struct ch343 *ch343, u8 request, u16 value, u16 index, char *buf, unsigned bufsize) +{ + int retval; + + retval = usb_autopm_get_interface(ch343->control); + if (retval) + return retval; + + retval = + usb_control_msg(ch343->dev, usb_rcvctrlpipe(ch343->dev, 0), request, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, value, index, buf, bufsize, DEFAULT_TIMEOUT); + + usb_autopm_put_interface(ch343->control); + + return retval; +} + +static int ch343_control_msg_out(struct ch343 *ch343, u8 request, u8 requesttype, u16 value, u16 index, void *buf, + unsigned bufsize) +{ + int retval; + char *buffer; + + buffer = kmalloc(bufsize, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + retval = copy_from_user(buffer, (char __user *)buf, bufsize); + if (retval) + goto out; + + retval = usb_autopm_get_interface(ch343->control); + if (retval) + goto out; + + retval = usb_control_msg(ch343->dev, usb_sndctrlpipe(ch343->dev, 0), request, requesttype, value, index, buf, + bufsize, DEFAULT_TIMEOUT); + + usb_autopm_put_interface(ch343->control); + +out: + kfree(buffer); + return retval; +} + +static int ch343_control_msg_in(struct ch343 *ch343, u8 request, u8 requesttype, u16 value, u16 index, void *buf, + unsigned bufsize) +{ + int retval; + char *buffer; + + buffer = kmalloc(bufsize, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + retval = usb_autopm_get_interface(ch343->control); + if (retval) + goto out; + + retval = usb_control_msg(ch343->dev, usb_rcvctrlpipe(ch343->dev, 0), request, requesttype, value, index, buffer, + bufsize, DEFAULT_TIMEOUT); + if (retval > 0) { + if (copy_to_user((char __user *)buf, buffer, retval)) { + retval = -EFAULT; + } + } + + usb_autopm_put_interface(ch343->control); + +out: + kfree(buffer); + return retval; +} + +static inline int ch343_set_control(struct ch343 *ch343, int control) +{ + if (ch343->iface <= 1) + return ch343_control_out(ch343, CMD_C2 + ch343->iface, ~control, 0x0000); + else if (ch343->iface <= 3) + return ch343_control_out(ch343, CMD_C2 + 0x10 + (ch343->iface - 2), ~control, 0x0000); + else + return -1; +} + +static inline int ch343_set_line(struct ch343 *ch343, struct usb_cdc_line_coding *line) +{ + return 0; +} + +static int ch343_get_status(struct ch343 *ch343) +{ + char *buffer; + int retval; + const unsigned size = 2; + unsigned long flags; + + buffer = kmalloc(size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + retval = ch343_control_in(ch343, CMD_R, CMD_C3 + ch343->iface, 0, buffer, size); + if (retval != size) + goto out; + + /* setup the private status if available */ + spin_lock_irqsave(&ch343->read_lock, flags); + ch343->ctrlin = (~(*buffer)) & CH343_CTI_ST; + spin_unlock_irqrestore(&ch343->read_lock, flags); + +out: + kfree(buffer); + return retval; +} + +/* -------------------------------------------------------------------------- */ + +static int ch343_configure(struct ch343 *ch343) +{ + char *buffer; + int r; + const unsigned size = 2; + u8 chiptype; + + buffer = kmalloc(size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + r = ch343_control_in(ch343, CMD_C6, 0, 0, buffer, size); + if (r != size) + goto out; + + chiptype = buffer[1]; + + switch (ch343->idProduct) { + case 0x55D2: + if (chiptype == 0x48) + ch343->chiptype = CHIP_CH342F; + else if (chiptype == 0x41) + ch343->chiptype = CHIP_CH342K; + break; + case 0x55D3: + if (chiptype == 0x08) + ch343->chiptype = CHIP_CH343GP; + else if (chiptype == 0x02) + ch343->chiptype = CHIP_CH343J; + else if (chiptype == 0x01) + ch343->chiptype = CHIP_CH343K; + else if (chiptype == 0x18) + ch343->chiptype = CHIP_CH343G_AUTOBAUD; + break; + case 0x55D4: + if (chiptype == 0x08) + ch343->chiptype = CHIP_CH9102F; + else if (chiptype == 0x09) + ch343->chiptype = CHIP_CH9102X; + break; + case 0x55D5: + if (chiptype == 0xC0) { + if ((buffer[0] & 0xF0) == 0x40) + ch343->chiptype = CHIP_CH344L; + else + ch343->chiptype = CHIP_CH344L_V2; + } else + ch343->chiptype = CHIP_CH344Q; + break; + case 0x55D7: + if (chiptype == 0x4B) + ch343->chiptype = CHIP_CH9103M; + break; + case 0x55D8: + if (chiptype == 0x08) + ch343->chiptype = CHIP_CH9101UH; + else if (chiptype == 0x0A) + ch343->chiptype = CHIP_CH9101RY; + break; + case 0x55DA: + case 0x55DB: + case 0x55DD: + ch343->chiptype = CHIP_CH347T; + break; + case 0x55DF: + ch343->chiptype = CHIP_CH9104L; + break; + default: + break; + } + + if (ch343->chiptype != CHIP_CH344L && ch343->chiptype != CHIP_CH344L_V2 && ch343->chiptype != CHIP_CH9104L) { + r = ch343_get_status(ch343); + if (r < 0) + goto out; + } + + dev_dbg(&ch343->data->dev, "%s - chip hver : 0x%2x, sver : 0x%2x, chip : %d\n", __func__, buffer[0], buffer[1], + ch343->chiptype); +out: + kfree(buffer); + return r < 0 ? r : 0; +} + +/* + * Write buffer management. + * All of these assume proper locks taken by the caller. + */ +static int ch343_wb_alloc(struct ch343 *ch343) +{ + int i, wbn; + struct ch343_wb *wb; + + wbn = 0; + i = 0; + for (;;) { + wb = &ch343->wb[wbn]; + if (!wb->use) { + wb->use = 1; + return wbn; + } + wbn = (wbn + 1) % CH343_NW; + if (++i >= CH343_NW) + return -1; + } +} + +static int ch343_wb_is_avail(struct ch343 *ch343) +{ + int i, n; + unsigned long flags; + + n = CH343_NW; + spin_lock_irqsave(&ch343->write_lock, flags); + for (i = 0; i < CH343_NW; i++) + n -= ch343->wb[i].use; + spin_unlock_irqrestore(&ch343->write_lock, flags); + return n; +} + +/* + * Finish write. Caller must hold ch343->write_lock + */ +static void ch343_write_done(struct ch343 *ch343, struct ch343_wb *wb) +{ + wb->use = 0; + ch343->transmitting--; + usb_autopm_put_interface_async(ch343->control); +} + +/* + * Poke write. + * + * the caller is responsible for locking + */ +static int ch343_start_wb(struct ch343 *ch343, struct ch343_wb *wb) +{ + int rc; + + ch343->transmitting++; + + wb->urb->transfer_buffer = wb->buf; + wb->urb->transfer_dma = wb->dmah; + wb->urb->transfer_buffer_length = wb->len; + wb->urb->dev = ch343->dev; + + rc = usb_submit_urb(wb->urb, GFP_ATOMIC); + if (rc < 0) { + dev_err(&ch343->data->dev, "%s - usb_submit_urb(write bulk) failed: %d\n", __func__, rc); + ch343_write_done(ch343, wb); + } + return rc; +} + +static void ch343_update_status(struct ch343 *ch343, unsigned char *data, size_t len) +{ + unsigned long flags; + u8 status; + u8 difference; + u8 type = data[0]; + u8 handled = 0; + + if (len < 4) + return; + + if (ch343->chiptype == CHIP_CH344L) { + if (data[0] != 0x00) + return; + type = data[1]; + } else if (ch343->chiptype == CHIP_CH344Q || ch343->chiptype == CHIP_CH344L_V2 || ch343->chiptype == CHIP_CH9104L) { + type = data[1]; + } + + if (type & CH343_CTT_M) { + status = ~data[len - 1] & CH343_CTI_ST; + if (ch343->chiptype == CHIP_CH344L || ch343->chiptype == CHIP_CH344L_V2) + status &= CH343_CTI_C; + + if (!ch343->clocal && (ch343->ctrlin & status & CH343_CTI_DC)) { + tty_port_tty_hangup(&ch343->port, false); + } + + spin_lock_irqsave(&ch343->read_lock, flags); + difference = status ^ ch343->ctrlin; + ch343->ctrlin = status; + ch343->oldcount = ch343->iocount; + + if (difference) { + if (difference & CH343_CTI_C) { + ch343->iocount.cts++; + } + if (difference & CH343_CTI_DS) { + ch343->iocount.dsr++; + } + if (difference & CH343_CTI_R) { + ch343->iocount.rng++; + } + if (difference & CH343_CTI_DC) { + ch343->iocount.dcd++; + } + spin_unlock_irqrestore(&ch343->read_lock, flags); + wake_up_interruptible(&ch343->wioctl); + } else + spin_unlock_irqrestore(&ch343->read_lock, flags); + handled = 1; + } + if (type & CH343_CTT_O) { + spin_lock_irqsave(&ch343->read_lock, flags); + ch343->oldcount = ch343->iocount; + ch343->iocount.overrun++; + spin_unlock_irqrestore(&ch343->read_lock, flags); + handled = 1; + } + if ((type & CH343_CTT_F) == CH343_CTT_F) { + spin_lock_irqsave(&ch343->read_lock, flags); + ch343->oldcount = ch343->iocount; + ch343->iocount.frame++; + spin_unlock_irqrestore(&ch343->read_lock, flags); + handled = 1; + } else if (type & CH343_CTT_P) { + spin_lock_irqsave(&ch343->read_lock, flags); + ch343->oldcount = ch343->iocount; + ch343->iocount.parity++; + spin_unlock_irqrestore(&ch343->read_lock, flags); + handled = 1; + } + if (!handled) + dev_err(&ch343->control->dev, + "%s - unknown status received:" + "len:%d, data0:0x%x, data1:0x%x\n", + __func__, (int)len, data[0], data[1]); +} + +/* Reports status changes with "interrupt" transfers */ +static void ch343_ctrl_irq(struct urb *urb) +{ + struct ch343 *ch343 = urb->context; + unsigned char *data = urb->transfer_buffer; + unsigned int len = urb->actual_length; + int status = urb->status; + int retval; + + switch (status) { + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dev_dbg(&ch343->control->dev, "%s - urb shutting down with status: %d\n", __func__, status); + return; + default: + dev_dbg(&ch343->control->dev, "%s - nonzero urb status received: %d\n", __func__, status); + goto exit; + } + + usb_mark_last_busy(ch343->dev); + ch343_update_status(ch343, data, len); +exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval && retval != -EPERM) + dev_err(&ch343->control->dev, "%s - usb_submit_urb failed: %d\n", __func__, retval); +} + +static int ch343_submit_read_urb(struct ch343 *ch343, int index, gfp_t mem_flags) +{ + int res; + + if (!test_and_clear_bit(index, &ch343->read_urbs_free)) + return 0; + + dev_vdbg(&ch343->data->dev, "%s - urb %d\n", __func__, index); + + res = usb_submit_urb(ch343->read_urbs[index], mem_flags); + if (res) { + if (res != -EPERM) { + dev_err(&ch343->data->dev, "%s - usb_submit_urb failed: %d\n", __func__, res); + } + set_bit(index, &ch343->read_urbs_free); + return res; + } + + return 0; +} + +static int ch343_submit_read_urbs(struct ch343 *ch343, gfp_t mem_flags) +{ + int res; + int i; + + for (i = 0; i < ch343->rx_buflimit; ++i) { + res = ch343_submit_read_urb(ch343, i, mem_flags); + if (res) + return res; + } + + return 0; +} + +static void ch343_process_read_urb(struct ch343 *ch343, struct urb *urb) +{ + if (!urb->actual_length) + return; + + tty_insert_flip_string(&ch343->port, urb->transfer_buffer, urb->actual_length); + tty_flip_buffer_push(&ch343->port); +} + +static void ch343_read_bulk_callback(struct urb *urb) +{ + struct ch343_rb *rb = urb->context; + struct ch343 *ch343 = rb->instance; + int status = urb->status; + + dev_vdbg(&ch343->data->dev, "%s - urb %d, len %d\n", __func__, rb->index, urb->actual_length); + + if (!ch343->dev) { + set_bit(rb->index, &ch343->read_urbs_free); + dev_dbg(&ch343->data->dev, "%s - disconnected\n", __func__); + return; + } + + if (status) { + set_bit(rb->index, &ch343->read_urbs_free); + dev_dbg(&ch343->data->dev, "%s - non-zero urb status: %d\n", __func__, status); + return; + } + + usb_mark_last_busy(ch343->dev); + ch343_process_read_urb(ch343, urb); + set_bit(rb->index, &ch343->read_urbs_free); + ch343_submit_read_urb(ch343, rb->index, GFP_ATOMIC); +} + +/* data interface wrote those outgoing bytes */ +static void ch343_write_bulk(struct urb *urb) +{ + struct ch343_wb *wb = urb->context; + struct ch343 *ch343 = wb->instance; + unsigned long flags; + int status = urb->status; + + dev_vdbg(&ch343->data->dev, "%s, len %d\n", __func__, urb->actual_length); + if (status || (urb->actual_length != urb->transfer_buffer_length)) + dev_vdbg(&ch343->data->dev, "%s - len %d/%d, status %d\n", __func__, urb->actual_length, + urb->transfer_buffer_length, status); + + spin_lock_irqsave(&ch343->write_lock, flags); + ch343_write_done(ch343, wb); + spin_unlock_irqrestore(&ch343->write_lock, flags); + schedule_work(&ch343->work); +} + +static void ch343_softint(struct work_struct *work) +{ + struct ch343 *ch343 = container_of(work, struct ch343, work); + + dev_dbg(&ch343->data->dev, "%s\n", __func__); + + tty_port_tty_wakeup(&ch343->port); +} + +/* + * TTY handlers + */ +static int ch343_tty_install(struct tty_driver *driver, struct tty_struct *tty) +{ + struct ch343 *ch343; + int retval; + + dev_dbg(tty->dev, "%s\n", __func__); + + ch343 = ch343_get_by_minor(tty->index); + if (!ch343) + return -ENODEV; + + retval = tty_standard_install(driver, tty); + if (retval) + goto error_init_termios; + + tty->driver_data = ch343; + + return 0; + +error_init_termios: + tty_port_put(&ch343->port); + return retval; +} + +static int ch343_tty_open(struct tty_struct *tty, struct file *filp) +{ + struct ch343 *ch343 = tty->driver_data; + + dev_dbg(tty->dev, "%s\n", __func__); + + return tty_port_open(&ch343->port, tty, filp); +} + +static void ch343_port_dtr_rts(struct tty_port *port, int raise) +{ + struct ch343 *ch343 = container_of(port, struct ch343, port); + int res; + + dev_dbg(&ch343->data->dev, "%s, raise:%d\n", __func__, raise); + + if (raise) + ch343->ctrlout |= CH343_CTO_D | CH343_CTO_R; + else + ch343->ctrlout &= ~(CH343_CTO_D | CH343_CTO_R); + + res = ch343_set_control(ch343, ch343->ctrlout); + if (res) + dev_err(&ch343->control->dev, "failed to set dtr/rts\n"); +} + +static int ch343_port_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct ch343 *ch343 = container_of(port, struct ch343, port); + int retval = -ENODEV; + int i; + + dev_dbg(&ch343->control->dev, "%s\n", __func__); + + mutex_lock(&ch343->mutex); + if (ch343->disconnected) + goto disconnected; + + retval = usb_autopm_get_interface(ch343->control); + if (retval) + goto error_get_interface; + + /* + * FIXME: Why do we need this? Allocating 64K of physically contiguous + * memory is really nasty... + */ + set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); + ch343->control->needs_remote_wakeup = 1; + + // retval = ch343_configure(ch343); + // if (retval) + // goto error_configure; + + ch343_tty_set_termios(tty, NULL); + + retval = usb_submit_urb(ch343->ctrlurb, GFP_KERNEL); + if (retval) { + dev_err(&ch343->control->dev, "%s - usb_submit_urb(ctrl cmd) failed\n", __func__); + goto error_submit_urb; + } + + retval = ch343_submit_read_urbs(ch343, GFP_KERNEL); + if (retval) + goto error_submit_read_urbs; + usb_autopm_put_interface(ch343->control); + + mutex_unlock(&ch343->mutex); + + return 0; + +error_submit_read_urbs: + for (i = 0; i < ch343->rx_buflimit; i++) + usb_kill_urb(ch343->read_urbs[i]); +error_submit_urb: + usb_kill_urb(ch343->ctrlurb); + // error_configure: + usb_autopm_put_interface(ch343->control); +error_get_interface: +disconnected: + mutex_unlock(&ch343->mutex); + + return usb_translate_errors(retval); +} + +static void ch343_port_destruct(struct tty_port *port) +{ + struct ch343 *ch343 = container_of(port, struct ch343, port); + + dev_dbg(&ch343->control->dev, "%s\n", __func__); + + ch343_release_minor(ch343); + usb_put_intf(ch343->control); + kfree(ch343); +} + +static void ch343_port_shutdown(struct tty_port *port) +{ + struct ch343 *ch343 = container_of(port, struct ch343, port); + struct urb *urb; + struct ch343_wb *wb; + int i; + + dev_dbg(&ch343->control->dev, "%s\n", __func__); + + usb_autopm_get_interface_no_resume(ch343->control); + ch343->control->needs_remote_wakeup = 0; + usb_autopm_put_interface(ch343->control); + + for (;;) { + urb = usb_get_from_anchor(&ch343->delayed); + if (!urb) + break; + wb = urb->context; + wb->use = 0; + usb_autopm_put_interface_async(ch343->control); + } + + usb_kill_urb(ch343->ctrlurb); + for (i = 0; i < CH343_NW; i++) + usb_kill_urb(ch343->wb[i].urb); + for (i = 0; i < ch343->rx_buflimit; i++) + usb_kill_urb(ch343->read_urbs[i]); +} + +static void ch343_tty_cleanup(struct tty_struct *tty) +{ + struct ch343 *ch343 = tty->driver_data; + dev_dbg(&ch343->control->dev, "%s\n", __func__); + tty_port_put(&ch343->port); +} + +static void ch343_tty_hangup(struct tty_struct *tty) +{ + struct ch343 *ch343 = tty->driver_data; + dev_dbg(&ch343->control->dev, "%s\n", __func__); + tty_port_hangup(&ch343->port); +} + +static void ch343_tty_close(struct tty_struct *tty, struct file *filp) +{ + struct ch343 *ch343 = tty->driver_data; + dev_dbg(&ch343->control->dev, "%s\n", __func__); + tty_port_close(&ch343->port, tty, filp); +} + +static int ch343_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + struct ch343 *ch343 = tty->driver_data; + int stat; + unsigned long flags; + int wbn; + struct ch343_wb *wb; + + if (!count) + return 0; + + dev_vdbg(&ch343->data->dev, "%s - count %d\n", __func__, count); + + spin_lock_irqsave(&ch343->write_lock, flags); + wbn = ch343_wb_alloc(ch343); + if (wbn < 0) { + spin_unlock_irqrestore(&ch343->write_lock, flags); + return 0; + } + wb = &ch343->wb[wbn]; + + if (!ch343->dev) { + wb->use = 0; + spin_unlock_irqrestore(&ch343->write_lock, flags); + return -ENODEV; + } + + count = (count > ch343->writesize) ? ch343->writesize : count; + + memcpy(wb->buf, buf, count); + wb->len = count; + + stat = usb_autopm_get_interface_async(ch343->control); + if (stat) { + wb->use = 0; + spin_unlock_irqrestore(&ch343->write_lock, flags); + return stat; + } + + if (ch343->susp_count) { + usb_anchor_urb(wb->urb, &ch343->delayed); + spin_unlock_irqrestore(&ch343->write_lock, flags); + return count; + } + + stat = ch343_start_wb(ch343, wb); + spin_unlock_irqrestore(&ch343->write_lock, flags); + + if (stat < 0) + return stat; + return count; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) +static unsigned int ch343_tty_write_room(struct tty_struct *tty) +#else +static int ch343_tty_write_room(struct tty_struct *tty) +#endif +{ + struct ch343 *ch343 = tty->driver_data; + /* + * Do not let the line discipline to know that we have a reserve, + * or it might get too enthusiastic. + */ + return ch343_wb_is_avail(ch343) ? ch343->writesize : 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) +static unsigned int ch343_tty_chars_in_buffer(struct tty_struct *tty) +#else +static int ch343_tty_chars_in_buffer(struct tty_struct *tty) +#endif +{ + struct ch343 *ch343 = tty->driver_data; + /* + * if the device was unplugged then any remaining characters fell out + * of the connector ;) + */ + if (ch343->disconnected) + return 0; + /* + * This is inaccurate (overcounts), but it works. + */ + return (CH343_NW - ch343_wb_is_avail(ch343)) * ch343->writesize; +} + +static int ch343_tty_break_ctl(struct tty_struct *tty, int state) +{ + struct ch343 *ch343 = tty->driver_data; + int retval; + uint16_t reg_contents; + uint8_t *regbuf; + + dev_dbg(&ch343->control->dev, "%s\n", __func__); + + regbuf = kmalloc(2, GFP_KERNEL); + if (!regbuf) + return -1; + + if (state != 0) { + if ((ch343->chiptype == CHIP_CH344L) || (ch343->chiptype == CHIP_CH344Q) || + (ch343->chiptype == CHIP_CH344L_V2) || (ch343->chiptype == CHIP_CH9104L)) { + regbuf[0] = ch343->iface; + regbuf[1] = 0x01; + } else { + regbuf[0] = CH343_N_B; + regbuf[1] = 0x00; + } + } else { + if ((ch343->chiptype == CHIP_CH344L) || (ch343->chiptype == CHIP_CH344Q) || + (ch343->chiptype == CHIP_CH344L_V2) || (ch343->chiptype == CHIP_CH9104L)) { + regbuf[0] = ch343->iface; + regbuf[1] = 0x00; + } else { + regbuf[0] = CH343_N_B | CH343_N_AB; + regbuf[1] = 0x00; + } + } + reg_contents = get_unaligned_le16(regbuf); + + if ((ch343->chiptype == CHIP_CH344L) || (ch343->chiptype == CHIP_CH344Q) || (ch343->chiptype == CHIP_CH344L_V2) || + (ch343->chiptype == CHIP_CH9104L)) { + retval = ch343_control_out(ch343, CMD_C4, reg_contents, 0x00); + } else { + if (ch343->iface) + retval = ch343_control_out(ch343, CMD_C4, 0x00, reg_contents); + else + retval = ch343_control_out(ch343, CMD_C4, reg_contents, 0x00); + } + + if (retval < 0) + dev_err(&ch343->control->dev, "%s - USB control write error (%d)\n", __func__, retval); + + kfree(regbuf); + + return retval; +} + +static int ch343_tty_tiocmget(struct tty_struct *tty) +{ + struct ch343 *ch343 = tty->driver_data; + unsigned long flags; + unsigned int result; + + dev_dbg(&ch343->control->dev, "%s\n", __func__); + + spin_lock_irqsave(&ch343->read_lock, flags); + result = (ch343->ctrlout & CH343_CTO_D ? TIOCM_DTR : 0) | (ch343->ctrlout & CH343_CTO_R ? TIOCM_RTS : 0) | + (ch343->ctrlin & CH343_CTI_C ? TIOCM_CTS : 0) | (ch343->ctrlin & CH343_CTI_DS ? TIOCM_DSR : 0) | + (ch343->ctrlin & CH343_CTI_R ? TIOCM_RI : 0) | (ch343->ctrlin & CH343_CTI_DC ? TIOCM_CD : 0); + spin_unlock_irqrestore(&ch343->read_lock, flags); + + return result; +} + +static int ch343_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) +{ + struct ch343 *ch343 = tty->driver_data; + unsigned int newctrl; + + dev_dbg(&ch343->control->dev, "%s\n", __func__); + + newctrl = ch343->ctrlout; + set = (set & TIOCM_DTR ? CH343_CTO_D : 0) | (set & TIOCM_RTS ? CH343_CTO_R : 0); + clear = (clear & TIOCM_DTR ? CH343_CTO_D : 0) | (clear & TIOCM_RTS ? CH343_CTO_R : 0); + + newctrl = (newctrl & ~clear) | set; + + if (ch343->ctrlout == newctrl) { + return 0; + } + + return ch343_set_control(ch343, ch343->ctrlout = newctrl); +} + +static int ch343_get_serial_info(struct ch343 *ch343, struct serial_struct __user *info) +{ + struct serial_struct tmp; + + if (!info) + return -EINVAL; + + memset(&tmp, 0, sizeof(tmp)); + tmp.flags = ASYNC_LOW_LATENCY; + tmp.xmit_fifo_size = ch343->writesize; + tmp.baud_base = le32_to_cpu(ch343->line.dwDTERate); + tmp.close_delay = ch343->port.close_delay / 10; + tmp.closing_wait = + ch343->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE : ch343->port.closing_wait / 10; + + if (copy_to_user(info, &tmp, sizeof(tmp))) + return -EFAULT; + else + return 0; +} + +static int ch343_set_serial_info(struct ch343 *ch343, struct serial_struct __user *newinfo) +{ + struct serial_struct new_serial; + unsigned int closing_wait, close_delay; + int retval = 0; + + if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) + return -EFAULT; + + close_delay = new_serial.close_delay * 10; + closing_wait = + new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; + + mutex_lock(&ch343->port.mutex); + + if (!capable(CAP_SYS_ADMIN)) { + if ((close_delay != ch343->port.close_delay) || (closing_wait != ch343->port.closing_wait)) + retval = -EPERM; + else + retval = -EOPNOTSUPP; + } else { + ch343->port.close_delay = close_delay; + ch343->port.closing_wait = closing_wait; + } + + mutex_unlock(&ch343->port.mutex); + return retval; +} + +static int ch343_wait_serial_change(struct ch343 *ch343, unsigned long arg) +{ + int rv = 0; + DECLARE_WAITQUEUE(wait, current); + struct async_icount old, new; + + do { + spin_lock_irq(&ch343->read_lock); + old = ch343->oldcount; + new = ch343->iocount; + ch343->oldcount = new; + spin_unlock_irq(&ch343->read_lock); + + if ((arg & TIOCM_CTS) && old.cts != new.cts) + break; + if ((arg & TIOCM_DSR) && old.dsr != new.dsr) + break; + if ((arg & TIOCM_RI) && old.rng != new.rng) + break; + if ((arg & TIOCM_CD) && old.dcd != new.dcd) + break; + + add_wait_queue(&ch343->wioctl, &wait); + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + remove_wait_queue(&ch343->wioctl, &wait); + if (ch343->disconnected) { + if (arg & TIOCM_CD) + break; + else + rv = -ENODEV; + } else { + if (signal_pending(current)) + rv = -ERESTARTSYS; + } + } while (!rv); + + return rv; +} + +static int ch343_get_serial_usage(struct ch343 *ch343, struct serial_icounter_struct __user *count) +{ + struct serial_icounter_struct icount; + int rv = 0; + + memset(&icount, 0, sizeof(icount)); + icount.cts = ch343->iocount.cts; + icount.dsr = ch343->iocount.dsr; + icount.rng = ch343->iocount.rng; + icount.dcd = ch343->iocount.dcd; + icount.frame = ch343->iocount.frame; + icount.overrun = ch343->iocount.overrun; + icount.parity = ch343->iocount.parity; + icount.brk = ch343->iocount.brk; + + if (copy_to_user(count, &icount, sizeof(icount)) > 0) + rv = -EFAULT; + + return rv; +} + +static int ch343_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) +{ + struct ch343 *ch343 = tty->driver_data; + int rv = 0; + unsigned long arg1, arg2, arg3, arg4, arg5, arg6; + u32 __user *argval = (u32 __user *)arg; + u8 *buffer; + + dev_dbg(&ch343->control->dev, "%s\n", __func__); + + buffer = kmalloc(512, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + switch (cmd) { + case TIOCGSERIAL: /* gets serial port data */ + rv = ch343_get_serial_info(ch343, (struct serial_struct __user *)arg); + break; + case TIOCSSERIAL: + rv = ch343_set_serial_info(ch343, (struct serial_struct __user *)arg); + break; + case TIOCMIWAIT: + rv = usb_autopm_get_interface(ch343->control); + if (rv < 0) { + rv = -EIO; + break; + } + rv = ch343_wait_serial_change(ch343, arg); + usb_autopm_put_interface(ch343->control); + break; + case IOCTL_CMD_GICOUNT: + case TIOCGICOUNT: + rv = ch343_get_serial_usage(ch343, (struct serial_icounter_struct __user *)arg); + break; + case IOCTL_CMD_GETCHIPTYPE: + if (put_user(ch343->chiptype, argval)) { + rv = -EFAULT; + goto out; + } + break; + case IOCTL_CMD_CTRLIN: + get_user(arg1, (u8 __user *)arg); + get_user(arg2, ((u8 __user *)arg + 1)); + get_user(arg3, (u16 __user *)((u8 *)arg + 2)); + get_user(arg4, (u16 __user *)((u8 *)arg + 4)); + get_user(arg5, (u16 __user *)((u8 *)arg + 6)); + arg6 = (unsigned long)((u8 __user *)arg + 8); + rv = ch343_control_msg_in(ch343, (u8)arg1, (u8)arg2, (u16)arg3, (u16)arg4, (u8 __user *)arg6, (u16)arg5); + break; + case IOCTL_CMD_CTRLOUT: + get_user(arg1, (u8 __user *)arg); + get_user(arg2, ((u8 __user *)arg + 1)); + get_user(arg3, (u16 __user *)((u8 *)arg + 2)); + get_user(arg4, (u16 __user *)((u8 *)arg + 4)); + get_user(arg5, (u16 __user *)((u8 *)arg + 6)); + arg6 = (unsigned long)((u8 __user *)arg + 8); + rv = ch343_control_msg_out(ch343, (u8)arg1, (u8)arg2, (u16)arg3, (u16)arg4, (u8 __user *)arg6, (u16)arg5); + if (rv != (u16)arg5) { + rv = -EINVAL; + goto out; + } + break; + default: + rv = -ENOIOCTLCMD; + break; + } + +out: + kfree(buffer); + return rv < 0 ? rv : 0; +} + +static int ch343_get(CHIPTYPE chiptype, unsigned int bval, unsigned char *fct, unsigned char *dvs) +{ + unsigned char a; + unsigned char b; + unsigned long c; + + if (((chiptype == CHIP_CH347T) || (chiptype == CHIP_CH344Q) || (chiptype == CHIP_CH9104L)) && bval >= 2000000) { + *fct = (unsigned char)(bval / 200); + *dvs = (unsigned char)((bval / 200) >> 8); + } + + switch (bval) { + case 6000000: + case 4000000: + case 2400000: + case 921600: + case 307200: + case 256000: + b = 7; + c = 12000000; + break; + default: + if (bval > 6000000 / 255) { + b = 3; + c = 6000000; + } else if (bval > 750000 / 255) { + b = 2; + c = 750000; + } else if (bval > 93750 / 255) { + b = 1; + c = 93750; + } else { + b = 0; + c = 11719; + } + break; + } + a = (unsigned char)(c / bval); + if (a == 0 || a == 0xFF) + return -EINVAL; + if ((c / a - bval) > (bval - c / (a + 1))) + a++; + a = 256 - a; + + *fct = a; + *dvs = b; + + return 0; +} + +static void ch343_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old) +{ + struct ch343 *ch343 = tty->driver_data; + struct ktermios *termios = &tty->termios; + struct usb_ch343_line_coding newline; + int newctrl = ch343->ctrlout; + + unsigned char dvs = 0; + unsigned char reg_count = 0; + unsigned char fct = 0; + unsigned char reg_value = 0; + unsigned short value = 0; + unsigned short index = 0; + + dev_dbg(tty->dev, "%s\n", __func__); + + if (termios_old && !tty_termios_hw_change(&tty->termios, termios_old)) { + return; + } + + newline.dwDTERate = tty_get_baud_rate(tty); + + if (newline.dwDTERate == 0) + newline.dwDTERate = 9600; + ch343_get(ch343->chiptype, newline.dwDTERate, &fct, &dvs); + + newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 1; + if (newline.bCharFormat == 2) + reg_value |= CH343_L_SB; + + newline.bParityType = + termios->c_cflag & PARENB ? (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0; + + switch (newline.bParityType) { + case 0x01: + reg_value |= CH343_L_P_O; + break; + case 0x02: + reg_value |= CH343_L_P_E; + break; + case 0x03: + reg_value |= CH343_L_P_M; + break; + case 0x04: + reg_value |= CH343_L_P_S; + break; + default: + break; + } + + switch (termios->c_cflag & CSIZE) { + case CS5: + newline.bDataBits = 5; + reg_value |= CH343_L_C5; + break; + case CS6: + newline.bDataBits = 6; + reg_value |= CH343_L_C6; + break; + case CS7: + newline.bDataBits = 7; + reg_value |= CH343_L_C7; + break; + case CS8: + default: + newline.bDataBits = 8; + reg_value |= CH343_L_C8; + break; + } + + /* FIXME: Needs to clear unsupported bits in the termios */ + ch343->clocal = ((termios->c_cflag & CLOCAL) != 0); + + if (C_BAUD(tty) == B0) { + newline.dwDTERate = ch343->line.dwDTERate; + newctrl &= ~CH343_CTO_D; + } else if (termios_old && (termios_old->c_cflag & CBAUD) == B0) { + newctrl |= CH343_CTO_D; + } + + reg_value |= CH343_L_E_R | CH343_L_E_T; + reg_count |= CH343_L_R_CT | CH343_L_R_CL | CH343_L_R_T; + + value |= reg_count; + value |= (unsigned short)reg_value << 8; + + index |= 0x00 | dvs; + index |= (unsigned short)fct << 8; + if (ch343->iface <= 1) + ch343_control_out(ch343, CMD_C1 + ch343->iface, value, index); + else if (ch343->iface <= 3) + ch343_control_out(ch343, CMD_C1 + 0x10 + (ch343->iface - 2), value, index); + + if (memcmp(&ch343->line, &newline, sizeof newline)) { + memcpy(&ch343->line, &newline, sizeof newline); + dev_dbg(&ch343->control->dev, "%s - set line: %d %d %d %d\n", __func__, newline.dwDTERate, newline.bCharFormat, + newline.bParityType, newline.bDataBits); + } + + if (C_CRTSCTS(tty)) { + newctrl |= CH343_CTO_A | CH343_CTO_R; + } else + newctrl &= ~CH343_CTO_A; + + if (newctrl != ch343->ctrlout) + ch343_set_control(ch343, ch343->ctrlout = newctrl); +} + +static const struct tty_port_operations ch343_port_ops = { + .dtr_rts = ch343_port_dtr_rts, + .shutdown = ch343_port_shutdown, + .activate = ch343_port_activate, + .destruct = ch343_port_destruct, +}; + +/* Little helpers: write/read buffers free */ +static void ch343_write_buffers_free(struct ch343 *ch343) +{ + int i; + struct ch343_wb *wb; + struct usb_device *usb_dev = interface_to_usbdev(ch343->control); + + for (wb = &ch343->wb[0], i = 0; i < CH343_NW; i++, wb++) + usb_free_coherent(usb_dev, ch343->writesize, wb->buf, wb->dmah); +} + +static void ch343_read_buffers_free(struct ch343 *ch343) +{ + struct usb_device *usb_dev = interface_to_usbdev(ch343->control); + int i; + + for (i = 0; i < ch343->rx_buflimit; i++) + usb_free_coherent(usb_dev, ch343->readsize, ch343->read_buffers[i].base, ch343->read_buffers[i].dma); +} + +/* Little helper: write buffers allocate */ +static int ch343_write_buffers_alloc(struct ch343 *ch343) +{ + int i; + struct ch343_wb *wb; + + for (wb = &ch343->wb[0], i = 0; i < CH343_NW; i++, wb++) { + wb->buf = usb_alloc_coherent(ch343->dev, ch343->writesize, GFP_KERNEL, &wb->dmah); + if (!wb->buf) { + while (i != 0) { + --i; + --wb; + usb_free_coherent(ch343->dev, ch343->writesize, wb->buf, wb->dmah); + } + return -ENOMEM; + } + } + return 0; +} + +static int ch343_open(struct inode *inode, struct file *file) +{ + struct ch343 *ch343; + struct usb_interface *interface; + int subminor; + int retval = 0; + + subminor = iminor(inode); + + interface = usb_find_interface(&ch343_driver, subminor); + if (!interface) { + pr_err("%s - error, can't find device for minor %d\n", __func__, subminor); + retval = -ENODEV; + goto exit; + } + + ch343 = usb_get_intfdata(interface); + if (!ch343) { + retval = -ENODEV; + goto exit; + } + + /* save our object in the file's private structure */ + file->private_data = ch343; + +exit: + return retval; +} + +static int ch343_release(struct inode *inode, struct file *file) +{ + struct ch343 *ch343; + + ch343 = file->private_data; + if (ch343 == NULL) + return -ENODEV; + + return 0; +} + +static long ch343_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct ch343 *ch343; + int rv = 0; + u8 *buffer; + unsigned long arg1, arg2, arg3, arg4, arg5, arg6; + u32 __user *argval = (u32 __user *)arg; + + ch343 = file->private_data; + if (ch343 == NULL) + return -ENODEV; + + buffer = kmalloc(512, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + switch (cmd) { + case IOCTL_CMD_GETCHIPTYPE: + if (put_user(ch343->chiptype, argval)) { + rv = -EFAULT; + goto out; + } + break; + case IOCTL_CMD_CTRLIN: + get_user(arg1, (u8 __user *)arg); + get_user(arg2, ((u8 __user *)arg + 1)); + get_user(arg3, (u16 __user *)((u8 *)arg + 2)); + get_user(arg4, (u16 __user *)((u8 *)arg + 4)); + get_user(arg5, (u16 __user *)((u8 *)arg + 6)); + arg6 = (unsigned long)((u8 __user *)arg + 8); + rv = ch343_control_msg_in(ch343, (u8)arg1, (u8)arg2, (u16)arg3, (u16)arg4, (u8 __user *)arg6, (u16)arg5); + break; + case IOCTL_CMD_CTRLOUT: + get_user(arg1, (u8 __user *)arg); + get_user(arg2, ((u8 __user *)arg + 1)); + get_user(arg3, (u16 __user *)((u8 *)arg + 2)); + get_user(arg4, (u16 __user *)((u8 *)arg + 4)); + get_user(arg5, (u16 __user *)((u8 *)arg + 6)); + arg6 = (unsigned long)((u8 __user *)arg + 8); + rv = ch343_control_msg_out(ch343, (u8)arg1, (u8)arg2, (u16)arg3, (u16)arg4, (u8 __user *)arg6, (u16)arg5); + if (rv != (u16)arg5) { + rv = -EINVAL; + goto out; + } + break; + default: + rv = -ENOIOCTLCMD; + break; + } + +out: + kfree(buffer); + return rv; +} + +static const struct file_operations ch343_fops = { + .owner = THIS_MODULE, + .open = ch343_open, + .unlocked_ioctl = ch343_ioctl, + .release = ch343_release, +}; + +/* + * usb class driver info in order to get a minor number from the usb core, + * and to have the device registered with the driver core + */ +static struct usb_class_driver ch343_class = { + .name = "ch343_iodev%d", + .fops = &ch343_fops, + .minor_base = USB_MINOR_BASE, +}; + +/* + * USB probe and disconnect routines. + */ +static int ch343_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct usb_cdc_union_desc *union_header = NULL; + unsigned char *buffer = intf->altsetting->extra; + int buflen = intf->altsetting->extralen; + struct usb_interface *control_interface; + struct usb_interface *data_interface; + struct usb_endpoint_descriptor *epctrl = NULL; + struct usb_endpoint_descriptor *epread = NULL; + struct usb_endpoint_descriptor *epwrite = NULL; + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct ch343 *ch343; + int minor; + int ctrlsize, readsize; + u8 *buf; + unsigned long quirks; + int num_rx_buf = CH343_NR; + int i; + unsigned int elength = 0; + struct device *tty_dev; + int rv = -ENOMEM; + + /* normal quirks */ + quirks = (unsigned long)id->driver_info; + if (!buffer) { + dev_err(&intf->dev, "Weird descriptor references\n"); + return -EINVAL; + } + + while (buflen > 0) { + elength = buffer[0]; + if (!elength) { + dev_err(&intf->dev, "skipping garbage byte\n"); + elength = 1; + goto next_desc; + } + if (buffer[1] != USB_DT_CS_INTERFACE) { + dev_err(&intf->dev, "skipping garbage\n"); + goto next_desc; + } + + switch (buffer[2]) { + case USB_CDC_UNION_TYPE: /* we've found it */ + if (elength < sizeof(struct usb_cdc_union_desc)) + goto next_desc; + if (union_header) { + dev_err(&intf->dev, + "More than one " + "union descriptor, skipping ...\n"); + goto next_desc; + } + union_header = (struct usb_cdc_union_desc *)buffer; + break; + default: + /* + * there are LOTS more CDC descriptors that + * could legitimately be found here. + */ + break; + } + next_desc: + buflen -= elength; + buffer += elength; + } + + control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); + data_interface = usb_ifnum_to_if(usb_dev, union_header->bSlaveInterface0); + + if (intf != control_interface) + return -ENODEV; + + if (usb_interface_claimed(data_interface)) { + dev_dbg(&intf->dev, "The data interface isn't available\n"); + return -EBUSY; + } + + if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || + control_interface->cur_altsetting->desc.bNumEndpoints == 0) + return -EINVAL; + + epctrl = &control_interface->cur_altsetting->endpoint[0].desc; + epwrite = &data_interface->cur_altsetting->endpoint[0].desc; + epread = &data_interface->cur_altsetting->endpoint[1].desc; + + /* workaround for switched endpoints */ + if (!usb_endpoint_dir_in(epread)) { + /* descriptors are swapped */ + dev_dbg(&intf->dev, "The data interface has switched endpoints\n"); + swap(epread, epwrite); + } + + ch343 = kzalloc(sizeof(struct ch343), GFP_KERNEL); + if (ch343 == NULL) + goto alloc_fail; + + ch343->idVendor = id->idVendor; + ch343->idProduct = id->idProduct; + ch343->iface = control_interface->cur_altsetting->desc.bInterfaceNumber / 2; + + minor = ch343_alloc_minor(ch343); + if (minor < 0) { + dev_err(&intf->dev, "no more free ch343 devices\n"); + kfree(ch343); + return -ENODEV; + } + + ctrlsize = usb_endpoint_maxp(epctrl); + readsize = usb_endpoint_maxp(epread); + ch343->writesize = usb_endpoint_maxp(epwrite) * 20; + ch343->control = control_interface; + ch343->data = data_interface; + ch343->minor = minor; + ch343->dev = usb_dev; + ch343->ctrlsize = ctrlsize; + ch343->readsize = readsize; + ch343->rx_buflimit = num_rx_buf; + + dev_dbg(&intf->dev, "ep%d ctrl: %d, ep%d read: %d, ep%d write: %d\n", usb_endpoint_num(epctrl), + usb_endpoint_maxp(epctrl), usb_endpoint_num(epread), usb_endpoint_maxp(epread), usb_endpoint_num(epwrite), + usb_endpoint_maxp(epwrite)); + + INIT_WORK(&ch343->work, ch343_softint); + init_waitqueue_head(&ch343->wioctl); + spin_lock_init(&ch343->write_lock); + spin_lock_init(&ch343->read_lock); + mutex_init(&ch343->mutex); + ch343->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); + tty_port_init(&ch343->port); + ch343->port.ops = &ch343_port_ops; + init_usb_anchor(&ch343->delayed); + ch343->quirks = quirks; + + buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &ch343->ctrl_dma); + if (!buf) + goto alloc_fail2; + ch343->ctrl_buffer = buf; + + if (ch343_write_buffers_alloc(ch343) < 0) + goto alloc_fail4; + + ch343->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); + if (!ch343->ctrlurb) + goto alloc_fail5; + + for (i = 0; i < num_rx_buf; i++) { + struct ch343_rb *rb = &(ch343->read_buffers[i]); + struct urb *urb; + + rb->base = usb_alloc_coherent(ch343->dev, readsize, GFP_KERNEL, &rb->dma); + if (!rb->base) + goto alloc_fail6; + rb->index = i; + rb->instance = ch343; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + goto alloc_fail6; + + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + urb->transfer_dma = rb->dma; + usb_fill_bulk_urb(urb, ch343->dev, ch343->rx_endpoint, rb->base, ch343->readsize, ch343_read_bulk_callback, rb); + + ch343->read_urbs[i] = urb; + __set_bit(i, &ch343->read_urbs_free); + } + for (i = 0; i < CH343_NW; i++) { + struct ch343_wb *snd = &(ch343->wb[i]); + + snd->urb = usb_alloc_urb(0, GFP_KERNEL); + if (snd->urb == NULL) + goto alloc_fail7; + + usb_fill_bulk_urb(snd->urb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), NULL, + ch343->writesize, ch343_write_bulk, snd); + snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + snd->instance = ch343; + } + + usb_set_intfdata(intf, ch343); + + usb_fill_int_urb(ch343->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress), ch343->ctrl_buffer, + ctrlsize, ch343_ctrl_irq, ch343, epctrl->bInterval ? epctrl->bInterval : 16); + ch343->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + ch343->ctrlurb->transfer_dma = ch343->ctrl_dma; + + dev_info(&intf->dev, "ttyCH343USB%d: usb to uart device\n", minor); + + usb_driver_claim_interface(&ch343_driver, data_interface, ch343); + usb_set_intfdata(data_interface, ch343); + usb_get_intf(control_interface); + + rv = ch343_configure(ch343); + if (rv) + goto alloc_fail7; + + if (ch343->iface == 0) { + /* register the device now, as it is ready */ + rv = usb_register_dev(intf, &ch343_class); + if (rv) { + /* error when registering this driver */ + dev_err(&intf->dev, "Not able to get a minor for this device.\n"); + } else { + g_intf = intf; + } + } + + tty_dev = tty_port_register_device(&ch343->port, ch343_tty_driver, minor, &control_interface->dev); + if (IS_ERR(tty_dev)) { + rv = PTR_ERR(tty_dev); + goto alloc_fail7; + } + + return 0; + +alloc_fail7: + usb_set_intfdata(intf, NULL); + for (i = 0; i < CH343_NW; i++) + usb_free_urb(ch343->wb[i].urb); +alloc_fail6: + for (i = 0; i < num_rx_buf; i++) + usb_free_urb(ch343->read_urbs[i]); + ch343_read_buffers_free(ch343); + usb_free_urb(ch343->ctrlurb); +alloc_fail5: + ch343_write_buffers_free(ch343); +alloc_fail4: + usb_free_coherent(usb_dev, ctrlsize, ch343->ctrl_buffer, ch343->ctrl_dma); +alloc_fail2: + ch343_release_minor(ch343); + kfree(ch343); +alloc_fail: + return rv; +} + +static void stop_data_traffic(struct ch343 *ch343) +{ + int i; + + usb_kill_urb(ch343->ctrlurb); + for (i = 0; i < CH343_NW; i++) + usb_kill_urb(ch343->wb[i].urb); + for (i = 0; i < ch343->rx_buflimit; i++) + usb_kill_urb(ch343->read_urbs[i]); + cancel_work_sync(&ch343->work); +} + +static void ch343_disconnect(struct usb_interface *intf) +{ + struct ch343 *ch343 = usb_get_intfdata(intf); + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct tty_struct *tty; + int i; + + dev_dbg(&intf->dev, "%s\n", __func__); + + /* sibling interface is already cleaning up */ + if (!ch343) + return; + + /* give back minor */ + if ((ch343->iface == 0) && (g_intf != NULL)) { + usb_deregister_dev(g_intf, &ch343_class); + } + + mutex_lock(&ch343->mutex); + ch343->disconnected = true; + wake_up_all(&ch343->wioctl); + usb_set_intfdata(ch343->control, NULL); + usb_set_intfdata(ch343->data, NULL); + mutex_unlock(&ch343->mutex); + + tty = tty_port_tty_get(&ch343->port); + if (tty) { + tty_vhangup(tty); + tty_kref_put(tty); + } + + stop_data_traffic(ch343); + + tty_unregister_device(ch343_tty_driver, ch343->minor); + + usb_free_urb(ch343->ctrlurb); + for (i = 0; i < CH343_NW; i++) + usb_free_urb(ch343->wb[i].urb); + for (i = 0; i < ch343->rx_buflimit; i++) + usb_free_urb(ch343->read_urbs[i]); + ch343_write_buffers_free(ch343); + usb_free_coherent(usb_dev, ch343->ctrlsize, ch343->ctrl_buffer, ch343->ctrl_dma); + ch343_read_buffers_free(ch343); + + usb_driver_release_interface(&ch343_driver, intf == ch343->control ? ch343->data : ch343->control); + + tty_port_put(&ch343->port); + dev_info(&intf->dev, "%s\n", "ch343 usb device disconnect."); +} + +#ifdef CONFIG_PM +static int ch343_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct ch343 *ch343 = usb_get_intfdata(intf); + int cnt; + + dev_dbg(&intf->dev, "%s\n", __func__); + + spin_lock_irq(&ch343->write_lock); + if (PMSG_IS_AUTO(message)) { + if (ch343->transmitting) { + spin_unlock_irq(&ch343->write_lock); + return -EBUSY; + } + } + cnt = ch343->susp_count++; + spin_unlock_irq(&ch343->write_lock); + + if (cnt) + return 0; + + stop_data_traffic(ch343); + + return 0; +} + +static int ch343_resume(struct usb_interface *intf) +{ + struct ch343 *ch343 = usb_get_intfdata(intf); + struct urb *urb; + int rv = 0; + + dev_dbg(&intf->dev, "%s\n", __func__); + + spin_lock_irq(&ch343->write_lock); + + if (--ch343->susp_count) + goto out; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) + if (tty_port_initialized(&ch343->port)) { +#else + if (test_bit(ASYNCB_INITIALIZED, &ch343->port.flags)) { +#endif + rv = usb_submit_urb(ch343->ctrlurb, GFP_ATOMIC); + + for (;;) { + urb = usb_get_from_anchor(&ch343->delayed); + if (!urb) + break; + + ch343_start_wb(ch343, urb->context); + } + + /* + * delayed error checking because we must + * do the write path at all cost + */ + if (rv < 0) + goto out; + + rv = ch343_submit_read_urbs(ch343, GFP_ATOMIC); + } +out: + spin_unlock_irq(&ch343->write_lock); + + return rv; +} + +static int ch343_reset_resume(struct usb_interface *intf) +{ + struct ch343 *ch343 = usb_get_intfdata(intf); + + dev_dbg(&intf->dev, "%s\n", __func__); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) + if (tty_port_initialized(&ch343->port)) +#else + if (test_bit(ASYNCB_INITIALIZED, &ch343->port.flags)) +#endif + tty_port_tty_hangup(&ch343->port, false); + + return ch343_resume(intf); +} + +#endif /* CONFIG_PM */ + +/* + * USB driver structure. + */ + +static const struct usb_device_id ch343_ids[] = {{USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D2, /* ch342 chip */ + USB_CDC_ACM_PROTO_AT_V25TER)}, + + {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D3, /* ch343 chip */ + USB_CDC_ACM_PROTO_AT_V25TER)}, + + {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D5, /* ch344 chip */ + USB_CDC_ACM_PROTO_AT_V25TER)}, + + {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55DA, /* ch347 chip mode0*/ + USB_CDC_ACM_PROTO_AT_V25TER)}, + + {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55DB, /* ch347 chip mode1*/ + USB_CDC_ACM_PROTO_AT_V25TER)}, + + {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55DD, /* ch347 chip mode3*/ + USB_CDC_ACM_PROTO_AT_V25TER)}, + + {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D8, /* ch9101 chip */ + USB_CDC_ACM_PROTO_AT_V25TER)}, + + {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D4, /* ch9102 chip */ + USB_CDC_ACM_PROTO_AT_V25TER)}, + + {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D7, /* ch9103 chip */ + USB_CDC_ACM_PROTO_AT_V25TER)}, + + {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55DF, /* ch9104 chip */ + USB_CDC_ACM_PROTO_AT_V25TER)}, + + {}}; + +MODULE_DEVICE_TABLE(usb, ch343_ids); + +static struct usb_driver ch343_driver = { + .name = "usb_ch343", + .probe = ch343_probe, + .disconnect = ch343_disconnect, +#ifdef CONFIG_PM + .suspend = ch343_suspend, + .resume = ch343_resume, + .reset_resume = ch343_reset_resume, +#endif + .id_table = ch343_ids, +#ifdef CONFIG_PM + .supports_autosuspend = 1, +#endif + .disable_hub_initiated_lpm = 1, +}; + +/* + * TTY driver structures. + */ +static const struct tty_operations ch343_ops = { + .install = ch343_tty_install, + .open = ch343_tty_open, + .close = ch343_tty_close, + .cleanup = ch343_tty_cleanup, + .hangup = ch343_tty_hangup, + .write = ch343_tty_write, + .write_room = ch343_tty_write_room, + .ioctl = ch343_tty_ioctl, + .chars_in_buffer = ch343_tty_chars_in_buffer, + .break_ctl = ch343_tty_break_ctl, + .set_termios = ch343_tty_set_termios, + .tiocmget = ch343_tty_tiocmget, + .tiocmset = ch343_tty_tiocmset, +}; + +/* + * Init / exit. + */ +static int __init ch343_init(void) +{ + int retval; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) + ch343_tty_driver = tty_alloc_driver(CH343_TTY_MINORS, TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(ch343_tty_driver)) + return PTR_ERR(ch343_tty_driver); +#else + ch343_tty_driver = alloc_tty_driver(CH343_TTY_MINORS); + if (!ch343_tty_driver) + return -ENOMEM; +#endif + ch343_tty_driver->driver_name = "usbch343", ch343_tty_driver->name = "ttyCH343USB", + ch343_tty_driver->major = CH343_TTY_MAJOR, ch343_tty_driver->minor_start = 0, + ch343_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, ch343_tty_driver->subtype = SERIAL_TYPE_NORMAL, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + ch343_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; +#endif + ch343_tty_driver->init_termios = tty_std_termios; + ch343_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + tty_set_operations(ch343_tty_driver, &ch343_ops); + + retval = tty_register_driver(ch343_tty_driver); + if (retval) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) + tty_driver_kref_put(ch343_tty_driver); +#else + put_tty_driver(ch343_tty_driver); +#endif + return retval; + } + + retval = usb_register(&ch343_driver); + if (retval) { + tty_unregister_driver(ch343_tty_driver); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) + tty_driver_kref_put(ch343_tty_driver); +#else + put_tty_driver(ch343_tty_driver); +#endif + return retval; + } + + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); + printk(KERN_INFO KBUILD_MODNAME ": " VERSION_DESC "\n"); + + return 0; +} + +static void __exit ch343_exit(void) +{ + usb_deregister(&ch343_driver); + tty_unregister_driver(ch343_tty_driver); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) + tty_driver_kref_put(ch343_tty_driver); +#else + put_tty_driver(ch343_tty_driver); +#endif + idr_destroy(&ch343_minors); + printk(KERN_INFO KBUILD_MODNAME + ": " + "ch343 driver exit.\n"); +} + +module_init(ch343_init); +module_exit(ch343_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_VERSION(VERSION_DESC); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(CH343_TTY_MAJOR); diff --git a/sysdrv/source/kernel/drivers/usb/serial/ch343.h b/sysdrv/source/kernel/drivers/usb/serial/ch343.h new file mode 100755 index 000000000..c53a87500 --- /dev/null +++ b/sysdrv/source/kernel/drivers/usb/serial/ch343.h @@ -0,0 +1,243 @@ +#ifndef _CH343_H +#define _CH343_H + +/* + * Baud rate and default timeout + */ +#define DEFAULT_BAUD_RATE 9600 +#define DEFAULT_TIMEOUT 2000 + +/* + * CMSPAR, some architectures can't have space and mark parity. + */ + +#ifndef CMSPAR +#define CMSPAR 0 +#endif + +/* + * Major and minor numbers. + */ + +#define CH343_TTY_MAJOR 170 +#define CH343_TTY_MINORS 256 + +#define USB_MINOR_BASE 70 + +/* + * Requests. + */ + +#define USB_RT_CH343 (USB_TYPE_CLASS | USB_RECIP_INTERFACE) + +#define CMD_R 0x95 +#define CMD_W 0x9A +#define CMD_C1 0xA1 +#define CMD_C2 0xA4 +#define CMD_C3 0x05 +#define CMD_C4 0xA8 +#define CMD_C5 0x5E +#define CMD_C6 0x5F + +#define CH343_CTO_O 0x10 +#define CH343_CTO_D 0x20 +#define CH343_CTO_R 0x40 +#define CH343_CTO_A 0x80 +#define CH343_CTI_C 0x01 +#define CH343_CTI_DS 0x02 +#define CH343_CTI_R 0x04 +#define CH343_CTI_DC 0x08 +#define CH343_CTI_ST 0x0f + +#define CH343_CTT_M 0x08 +#define CH343_CTT_F 0x44 +#define CH343_CTT_P 0x04 +#define CH343_CTT_O 0x02 + +#define CH343_LO 0x02 +#define CH343_LE 0x04 +#define CH343_LB +#define CH343_LP 0x00 +#define CH343_LF 0x40 +#define CH343_LM 0x08 + +#define CH343_L_R_CT 0x80 +#define CH343_L_R_CL 0x04 +#define CH343_L_R_T 0x08 + +#define CH343_L_E_R 0x80 +#define CH343_L_E_T 0x40 +#define CH343_L_P_S 0x38 +#define CH343_L_P_M 0x28 +#define CH343_L_P_E 0x18 +#define CH343_L_P_O 0x08 +#define CH343_L_SB 0x04 +#define CH343_L_C8 0x03 +#define CH343_L_C7 0x02 +#define CH343_L_C6 0x01 +#define CH343_L_C5 0x00 + +#define CH343_N_B 0x80 +#define CH343_N_AB 0x10 + +/* + * Internal driver structures. + */ + +/* + * The only reason to have several buffers is to accommodate assumptions + * in line disciplines. They ask for empty space amount, receive our URB size, + * and proceed to issue several 1-character writes, assuming they will fit. + * The very first write takes a complete URB. Fortunately, this only happens + * when processing onlcr, so we only need 2 buffers. These values must be + * powers of 2. + */ +#define CH343_NW 16 +#define CH343_NR 16 + +struct ch343_wb { + unsigned char *buf; + dma_addr_t dmah; + int len; + int use; + struct urb *urb; + struct ch343 *instance; +}; + +struct ch343_rb { + int size; + unsigned char *base; + dma_addr_t dma; + int index; + struct ch343 *instance; +}; + +struct usb_ch343_line_coding { + __u32 dwDTERate; + __u8 bCharFormat; +#define USB_CH343_1_STOP_BITS 0 +#define USB_CH343_1_5_STOP_BITS 1 +#define USB_CH343_2_STOP_BITS 2 + + __u8 bParityType; +#define USB_CH343_NO_PARITY 0 +#define USB_CH343_ODD_PARITY 1 +#define USB_CH343_EVEN_PARITY 2 +#define USB_CH343_MARK_PARITY 3 +#define USB_CH343_SPACE_PARITY 4 + + __u8 bDataBits; +} __attribute__((packed)); + +typedef enum { + CHIP_CH342F = 0x00, + CHIP_CH342K, + CHIP_CH343GP, + CHIP_CH343G_AUTOBAUD, + CHIP_CH343K, + CHIP_CH343J, + CHIP_CH344L, + CHIP_CH344L_V2, + CHIP_CH344Q, + CHIP_CH347T, + CHIP_CH9101UH, + CHIP_CH9101RY, + CHIP_CH9102F, + CHIP_CH9102X, + CHIP_CH9103M, + CHIP_CH9104L, +} CHIPTYPE; + +struct gpioinfo { + int group; + int pin; +}; + +struct ch343_gpio { + int gpiocount; + struct gpioinfo io[64]; +}; + +struct ch343_gpio ch343_gpios[] = { + { 0, {}}, + { 0, {}}, + { 0, {}}, + { 0, {}}, + { 0, {}}, + { 0, {}}, + /* CH344L */ + { 8, {}}, + /* CH344L-V2 */ + { 8, {}}, + /* CH344Q */ + { 8, {}}, + /* CH347T */ + { 4, {}}, + /* CH9101UH */ + { 5, {{3, 2}, {3, 3}, {1, 3}, {1, 2}, {1, 5}, {2, 4}}}, + /* CH9101RY */ + { 4, {{1, 3}, {3, 3}, {3, 2}, {2, 4}}}, + /* CH9102F */ + { 5, {{2, 1}, {2, 7}, {2, 4}, {2, 6}, {2, 3}}}, + /* CH9102X */ + { 6, {{2, 3}, {2, 5}, {2, 1}, {2, 7}, {3, 0}, {2, 2}}}, + /* CH9103M */ + {12, {{1, 3}, {1, 2}, {3, 2}, {2, 6}, {1, 0}, {1, 6}, {2, 3}, {2, 5}, {3, 0}, {2, 2}, {1, 5}, {2, 4}}}, + /* CH9104L */ + {24, {}}, +}; + +struct ch343 { + struct usb_device *dev; /* the corresponding usb device */ + struct usb_interface *control; /* control interface */ + struct usb_interface *data; /* data interface */ + struct tty_port port; /* our tty port data */ + struct urb *ctrlurb; /* urbs */ + u8 *ctrl_buffer; /* buffers of urbs */ + dma_addr_t ctrl_dma; /* dma handles of buffers */ + struct ch343_wb wb[CH343_NW]; + unsigned long read_urbs_free; + struct urb *read_urbs[CH343_NR]; + struct ch343_rb read_buffers[CH343_NR]; + int rx_buflimit; + int rx_endpoint; + spinlock_t read_lock; + int write_used; /* number of non-empty write buffers */ + int transmitting; + spinlock_t write_lock; + struct mutex mutex; + bool disconnected; + struct usb_ch343_line_coding line; /* bits, stop, parity */ + struct work_struct work; /* work queue entry for line discipline waking up */ + unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ + unsigned int ctrlout; /* output control lines (DTR, RTS) */ + struct async_icount iocount; /* counters for control line changes */ + struct async_icount oldcount; /* for comparison of counter */ + wait_queue_head_t wioctl; /* for ioctl */ + unsigned int writesize; /* max packet size for the output bulk endpoint */ + unsigned int readsize, ctrlsize; /* buffer sizes for freeing */ + unsigned int minor; /* ch343 minor number */ + unsigned char clocal; /* termios CLOCAL */ + unsigned int susp_count; /* number of suspended interfaces */ + u8 bInterval; + struct usb_anchor delayed; /* writes queued for a device about to be woken */ + unsigned long quirks; + u8 iface; + CHIPTYPE chiptype; + u16 idVendor; + u16 idProduct; + u8 gpio5dir; +}; + +#define CDC_DATA_INTERFACE_TYPE 0x0a + +/* constants describing various quirks and errors */ +#define NO_UNION_NORMAL BIT(0) +#define SINGLE_RX_URB BIT(1) +#define NO_CAP_LINE BIT(2) +#define NO_DATA_INTERFACE BIT(4) +#define IGNORE_DEVICE BIT(5) +#define QUIRK_CONTROL_LINE_STATE BIT(6) +#define CLEAR_HALT_CONDITIONS BIT(7) + +#endif diff --git a/sysdrv/source/kernel/drivers/video/fbdev/core/fbcon.c b/sysdrv/source/kernel/drivers/video/fbdev/core/fbcon.c index 27828435d..69bb83ec6 100644 --- a/sysdrv/source/kernel/drivers/video/fbdev/core/fbcon.c +++ b/sysdrv/source/kernel/drivers/video/fbdev/core/fbcon.c @@ -88,6 +88,9 @@ # define DPRINTK(fmt, args...) #endif +#define CURSOR_ENABLE 0 +#define SHOW_CENTER 1 + /* * FIXME: Locking * @@ -365,6 +368,7 @@ static int get_color(struct vc_data *vc, struct fb_info *info, static void fb_flashcursor(struct work_struct *work) { +#if CURSOR_ENABLE struct fb_info *info = container_of(work, struct fb_info, queue); struct fbcon_ops *ops = info->fbcon_par; struct vc_data *vc = NULL; @@ -395,6 +399,7 @@ static void fb_flashcursor(struct work_struct *work) ops->cursor(vc, info, mode, get_color(vc, info, c, 1), get_color(vc, info, c, 0)); console_unlock(); +#endif } static void cursor_timer_handler(struct timer_list *t) @@ -601,7 +606,12 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, if (fb_get_color_depth(&info->var, &info->fix) == 1) erase &= ~0x400; logo_height = fb_prepare_logo(info, ops->rotate); - logo_lines = DIV_ROUND_UP(logo_height, vc->vc_font.height); + +#if SHOW_CENTER + logo_height += (info->var.yres/2) - (logo_height/2); +#endif + + logo_lines = DIV_ROUND_UP(logo_height, vc->vc_font.height); q = (unsigned short *) (vc->vc_origin + vc->vc_size_row * rows); step = logo_lines * cols; @@ -1331,6 +1341,7 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) static void fbcon_cursor(struct vc_data *vc, int mode) { +#if CURSOR_ENABLE struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; int c = scr_readw((u16 *) vc->vc_pos); @@ -1352,6 +1363,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode) ops->cursor(vc, info, mode, get_color(vc, info, c, 1), get_color(vc, info, c, 0)); +#endif } static int scrollback_phys_max = 0; diff --git a/sysdrv/source/kernel/drivers/video/fbdev/core/fbmem.c b/sysdrv/source/kernel/drivers/video/fbdev/core/fbmem.c index d787a344b..690d48fba 100644 --- a/sysdrv/source/kernel/drivers/video/fbdev/core/fbmem.c +++ b/sysdrv/source/kernel/drivers/video/fbdev/core/fbmem.c @@ -38,7 +38,7 @@ #include - +#define SHOW_CENTER 1 /* * Frame buffer device initialization and setup routines */ @@ -520,6 +520,11 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, image.dy = y; } +#if SHOW_CENTER +image.dx = (info->var.xres - logo->width) / 2; +image.dy = (info->var.yres - logo->height) / 2; +#endif + image.width = logo->width; image.height = logo->height; diff --git a/sysdrv/source/kernel/drivers/video/logo/logo_linux_clut224.ppm b/sysdrv/source/kernel/drivers/video/logo/logo_linux_clut224.ppm index 3c14e43b8..25760e00a 100644 --- a/sysdrv/source/kernel/drivers/video/logo/logo_linux_clut224.ppm +++ b/sysdrv/source/kernel/drivers/video/logo/logo_linux_clut224.ppm @@ -1,1604 +1,4503 @@ P3 -# Standard 224-color Linux logo -80 80 +300 90 255 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 6 6 6 10 10 10 10 10 10 - 10 10 10 6 6 6 6 6 6 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 10 10 10 14 14 14 - 22 22 22 26 26 26 30 30 30 34 34 34 - 30 30 30 30 30 30 26 26 26 18 18 18 - 14 14 14 10 10 10 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 26 26 26 42 42 42 - 54 54 54 66 66 66 78 78 78 78 78 78 - 78 78 78 74 74 74 66 66 66 54 54 54 - 42 42 42 26 26 26 18 18 18 10 10 10 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 22 22 22 42 42 42 66 66 66 86 86 86 - 66 66 66 38 38 38 38 38 38 22 22 22 - 26 26 26 34 34 34 54 54 54 66 66 66 - 86 86 86 70 70 70 46 46 46 26 26 26 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 10 10 10 26 26 26 - 50 50 50 82 82 82 58 58 58 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 6 6 6 54 54 54 86 86 86 66 66 66 - 38 38 38 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 22 22 22 50 50 50 - 78 78 78 34 34 34 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 6 6 6 70 70 70 - 78 78 78 46 46 46 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 18 18 18 42 42 42 82 82 82 - 26 26 26 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 14 14 14 - 46 46 46 34 34 34 6 6 6 2 2 6 - 42 42 42 78 78 78 42 42 42 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 10 10 10 30 30 30 66 66 66 58 58 58 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 26 26 26 - 86 86 86 101 101 101 46 46 46 10 10 10 - 2 2 6 58 58 58 70 70 70 34 34 34 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 14 14 14 42 42 42 86 86 86 10 10 10 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 30 30 30 - 94 94 94 94 94 94 58 58 58 26 26 26 - 2 2 6 6 6 6 78 78 78 54 54 54 - 22 22 22 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 22 22 22 62 62 62 62 62 62 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 26 26 26 - 54 54 54 38 38 38 18 18 18 10 10 10 - 2 2 6 2 2 6 34 34 34 82 82 82 - 38 38 38 14 14 14 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 30 30 30 78 78 78 30 30 30 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 10 10 10 - 10 10 10 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 78 78 78 - 50 50 50 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 86 86 86 14 14 14 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 54 54 54 - 66 66 66 26 26 26 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 82 82 82 2 2 6 2 2 6 - 2 2 6 6 6 6 10 10 10 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 6 6 6 - 14 14 14 10 10 10 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 18 18 18 - 82 82 82 34 34 34 10 10 10 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 2 2 6 - 6 6 6 6 6 6 22 22 22 34 34 34 - 6 6 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 18 18 18 34 34 34 - 10 10 10 50 50 50 22 22 22 2 2 6 - 2 2 6 2 2 6 2 2 6 10 10 10 - 86 86 86 42 42 42 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 2 2 6 - 38 38 38 116 116 116 94 94 94 22 22 22 - 22 22 22 2 2 6 2 2 6 2 2 6 - 14 14 14 86 86 86 138 138 138 162 162 162 -154 154 154 38 38 38 26 26 26 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 86 86 86 46 46 46 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 14 14 14 -134 134 134 198 198 198 195 195 195 116 116 116 - 10 10 10 2 2 6 2 2 6 6 6 6 -101 98 89 187 187 187 210 210 210 218 218 218 -214 214 214 134 134 134 14 14 14 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 86 86 86 50 50 50 18 18 18 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 54 54 54 -218 218 218 195 195 195 226 226 226 246 246 246 - 58 58 58 2 2 6 2 2 6 30 30 30 -210 210 210 253 253 253 174 174 174 123 123 123 -221 221 221 234 234 234 74 74 74 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 70 70 70 58 58 58 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 82 82 82 2 2 6 106 106 106 -170 170 170 26 26 26 86 86 86 226 226 226 -123 123 123 10 10 10 14 14 14 46 46 46 -231 231 231 190 190 190 6 6 6 70 70 70 - 90 90 90 238 238 238 158 158 158 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 70 70 70 58 58 58 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 86 86 86 6 6 6 116 116 116 -106 106 106 6 6 6 70 70 70 149 149 149 -128 128 128 18 18 18 38 38 38 54 54 54 -221 221 221 106 106 106 2 2 6 14 14 14 - 46 46 46 190 190 190 198 198 198 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 74 74 74 62 62 62 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 0 - 0 0 1 0 0 0 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 94 94 94 14 14 14 101 101 101 -128 128 128 2 2 6 18 18 18 116 116 116 -118 98 46 121 92 8 121 92 8 98 78 10 -162 162 162 106 106 106 2 2 6 2 2 6 - 2 2 6 195 195 195 195 195 195 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 74 74 74 62 62 62 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 1 - 0 0 1 0 0 0 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 90 90 90 14 14 14 58 58 58 -210 210 210 26 26 26 54 38 6 154 114 10 -226 170 11 236 186 11 225 175 15 184 144 12 -215 174 15 175 146 61 37 26 9 2 2 6 - 70 70 70 246 246 246 138 138 138 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 70 70 70 66 66 66 26 26 26 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 86 86 86 14 14 14 10 10 10 -195 195 195 188 164 115 192 133 9 225 175 15 -239 182 13 234 190 10 232 195 16 232 200 30 -245 207 45 241 208 19 232 195 16 184 144 12 -218 194 134 211 206 186 42 42 42 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 50 50 50 74 74 74 30 30 30 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 34 34 34 86 86 86 14 14 14 2 2 6 -121 87 25 192 133 9 219 162 10 239 182 13 -236 186 11 232 195 16 241 208 19 244 214 54 -246 218 60 246 218 38 246 215 20 241 208 19 -241 208 19 226 184 13 121 87 25 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 50 50 50 82 82 82 34 34 34 10 10 10 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 34 34 34 82 82 82 30 30 30 61 42 6 -180 123 7 206 145 10 230 174 11 239 182 13 -234 190 10 238 202 15 241 208 19 246 218 74 -246 218 38 246 215 20 246 215 20 246 215 20 -226 184 13 215 174 15 184 144 12 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 26 26 26 94 94 94 42 42 42 14 14 14 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 50 50 50 104 69 6 -192 133 9 216 158 10 236 178 12 236 186 11 -232 195 16 241 208 19 244 214 54 245 215 43 -246 215 20 246 215 20 241 208 19 198 155 10 -200 144 11 216 158 10 156 118 10 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 6 6 6 90 90 90 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 46 46 46 22 22 22 -137 92 6 210 162 10 239 182 13 238 190 10 -238 202 15 241 208 19 246 215 20 246 215 20 -241 208 19 203 166 17 185 133 11 210 150 10 -216 158 10 210 150 10 102 78 10 2 2 6 - 6 6 6 54 54 54 14 14 14 2 2 6 - 2 2 6 62 62 62 74 74 74 30 30 30 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 34 34 34 78 78 78 50 50 50 6 6 6 - 94 70 30 139 102 15 190 146 13 226 184 13 -232 200 30 232 195 16 215 174 15 190 146 13 -168 122 10 192 133 9 210 150 10 213 154 11 -202 150 34 182 157 106 101 98 89 2 2 6 - 2 2 6 78 78 78 116 116 116 58 58 58 - 2 2 6 22 22 22 90 90 90 46 46 46 - 18 18 18 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 86 86 86 50 50 50 6 6 6 -128 128 128 174 154 114 156 107 11 168 122 10 -198 155 10 184 144 12 197 138 11 200 144 11 -206 145 10 206 145 10 197 138 11 188 164 115 -195 195 195 198 198 198 174 174 174 14 14 14 - 2 2 6 22 22 22 116 116 116 116 116 116 - 22 22 22 2 2 6 74 74 74 70 70 70 - 30 30 30 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 101 101 101 26 26 26 10 10 10 -138 138 138 190 190 190 174 154 114 156 107 11 -197 138 11 200 144 11 197 138 11 192 133 9 -180 123 7 190 142 34 190 178 144 187 187 187 -202 202 202 221 221 221 214 214 214 66 66 66 - 2 2 6 2 2 6 50 50 50 62 62 62 - 6 6 6 2 2 6 10 10 10 90 90 90 - 50 50 50 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 10 10 10 34 34 34 - 74 74 74 74 74 74 2 2 6 6 6 6 -144 144 144 198 198 198 190 190 190 178 166 146 -154 121 60 156 107 11 156 107 11 168 124 44 -174 154 114 187 187 187 190 190 190 210 210 210 -246 246 246 253 253 253 253 253 253 182 182 182 - 6 6 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 62 62 62 - 74 74 74 34 34 34 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 10 10 10 22 22 22 54 54 54 - 94 94 94 18 18 18 2 2 6 46 46 46 -234 234 234 221 221 221 190 190 190 190 190 190 -190 190 190 187 187 187 187 187 187 190 190 190 -190 190 190 195 195 195 214 214 214 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 - 82 82 82 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 14 14 14 - 86 86 86 54 54 54 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 18 18 18 46 46 46 90 90 90 - 46 46 46 18 18 18 6 6 6 182 182 182 -253 253 253 246 246 246 206 206 206 190 190 190 -190 190 190 190 190 190 190 190 190 190 190 190 -206 206 206 231 231 231 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -202 202 202 14 14 14 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 42 42 42 86 86 86 42 42 42 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 14 14 14 38 38 38 74 74 74 66 66 66 - 2 2 6 6 6 6 90 90 90 250 250 250 -253 253 253 253 253 253 238 238 238 198 198 198 -190 190 190 190 190 190 195 195 195 221 221 221 -246 246 246 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 82 82 82 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 78 78 78 70 70 70 34 34 34 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 34 34 34 66 66 66 78 78 78 6 6 6 - 2 2 6 18 18 18 218 218 218 253 253 253 -253 253 253 253 253 253 253 253 253 246 246 246 -226 226 226 231 231 231 246 246 246 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 178 178 178 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 18 18 18 90 90 90 62 62 62 - 30 30 30 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 10 10 10 26 26 26 - 58 58 58 90 90 90 18 18 18 2 2 6 - 2 2 6 110 110 110 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 231 231 231 18 18 18 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 18 18 18 94 94 94 - 54 54 54 26 26 26 10 10 10 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 22 22 22 50 50 50 - 90 90 90 26 26 26 2 2 6 2 2 6 - 14 14 14 195 195 195 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 242 242 242 54 54 54 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 38 38 38 - 86 86 86 50 50 50 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 38 38 38 82 82 82 - 34 34 34 2 2 6 2 2 6 2 2 6 - 42 42 42 195 195 195 246 246 246 253 253 253 -253 253 253 253 253 253 253 253 253 250 250 250 -242 242 242 242 242 242 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 250 250 250 246 246 246 238 238 238 -226 226 226 231 231 231 101 101 101 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 38 38 38 82 82 82 42 42 42 14 14 14 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 10 10 10 26 26 26 62 62 62 66 66 66 - 2 2 6 2 2 6 2 2 6 6 6 6 - 70 70 70 170 170 170 206 206 206 234 234 234 -246 246 246 250 250 250 250 250 250 238 238 238 -226 226 226 231 231 231 238 238 238 250 250 250 -250 250 250 250 250 250 246 246 246 231 231 231 -214 214 214 206 206 206 202 202 202 202 202 202 -198 198 198 202 202 202 182 182 182 18 18 18 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 62 62 62 66 66 66 30 30 30 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 14 14 14 42 42 42 82 82 82 18 18 18 - 2 2 6 2 2 6 2 2 6 10 10 10 - 94 94 94 182 182 182 218 218 218 242 242 242 -250 250 250 253 253 253 253 253 253 250 250 250 -234 234 234 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 246 246 246 -238 238 238 226 226 226 210 210 210 202 202 202 -195 195 195 195 195 195 210 210 210 158 158 158 - 6 6 6 14 14 14 50 50 50 14 14 14 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 86 86 86 46 46 46 - 18 18 18 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 22 22 22 54 54 54 70 70 70 2 2 6 - 2 2 6 10 10 10 2 2 6 22 22 22 -166 166 166 231 231 231 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 250 250 250 -242 242 242 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 246 246 246 -231 231 231 206 206 206 198 198 198 226 226 226 - 94 94 94 2 2 6 6 6 6 38 38 38 - 30 30 30 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 62 62 62 66 66 66 - 26 26 26 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 74 74 74 50 50 50 2 2 6 - 26 26 26 26 26 26 2 2 6 106 106 106 -238 238 238 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 246 246 246 218 218 218 202 202 202 -210 210 210 14 14 14 2 2 6 2 2 6 - 30 30 30 22 22 22 2 2 6 2 2 6 - 2 2 6 2 2 6 18 18 18 86 86 86 - 42 42 42 14 14 14 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 90 90 90 22 22 22 2 2 6 - 42 42 42 2 2 6 18 18 18 218 218 218 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 250 250 250 221 221 221 -218 218 218 101 101 101 2 2 6 14 14 14 - 18 18 18 38 38 38 10 10 10 2 2 6 - 2 2 6 2 2 6 2 2 6 78 78 78 - 58 58 58 22 22 22 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 54 54 54 82 82 82 2 2 6 26 26 26 - 22 22 22 2 2 6 123 123 123 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 250 250 250 -238 238 238 198 198 198 6 6 6 38 38 38 - 58 58 58 26 26 26 38 38 38 2 2 6 - 2 2 6 2 2 6 2 2 6 46 46 46 - 78 78 78 30 30 30 10 10 10 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 10 10 10 30 30 30 - 74 74 74 58 58 58 2 2 6 42 42 42 - 2 2 6 22 22 22 231 231 231 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 250 250 250 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 246 246 246 46 46 46 38 38 38 - 42 42 42 14 14 14 38 38 38 14 14 14 - 2 2 6 2 2 6 2 2 6 6 6 6 - 86 86 86 46 46 46 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 14 14 14 42 42 42 - 90 90 90 18 18 18 18 18 18 26 26 26 - 2 2 6 116 116 116 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 250 250 250 238 238 238 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 94 94 94 6 6 6 - 2 2 6 2 2 6 10 10 10 34 34 34 - 2 2 6 2 2 6 2 2 6 2 2 6 - 74 74 74 58 58 58 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 10 10 10 26 26 26 66 66 66 - 82 82 82 2 2 6 38 38 38 6 6 6 - 14 14 14 210 210 210 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 246 246 246 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 144 144 144 2 2 6 - 2 2 6 2 2 6 2 2 6 46 46 46 - 2 2 6 2 2 6 2 2 6 2 2 6 - 42 42 42 74 74 74 30 30 30 10 10 10 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 42 42 42 90 90 90 - 26 26 26 6 6 6 42 42 42 2 2 6 - 74 74 74 250 250 250 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 242 242 242 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 182 182 182 2 2 6 - 2 2 6 2 2 6 2 2 6 46 46 46 - 2 2 6 2 2 6 2 2 6 2 2 6 - 10 10 10 86 86 86 38 38 38 10 10 10 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 10 10 10 26 26 26 66 66 66 82 82 82 - 2 2 6 22 22 22 18 18 18 2 2 6 -149 149 149 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 206 206 206 2 2 6 - 2 2 6 2 2 6 2 2 6 38 38 38 - 2 2 6 2 2 6 2 2 6 2 2 6 - 6 6 6 86 86 86 46 46 46 14 14 14 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 18 18 18 46 46 46 86 86 86 18 18 18 - 2 2 6 34 34 34 10 10 10 6 6 6 -210 210 210 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 221 221 221 6 6 6 - 2 2 6 2 2 6 6 6 6 30 30 30 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 82 82 82 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 26 26 26 66 66 66 62 62 62 2 2 6 - 2 2 6 38 38 38 10 10 10 26 26 26 -238 238 238 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 238 238 238 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 6 6 6 - 2 2 6 2 2 6 10 10 10 30 30 30 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 58 58 58 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 78 78 78 6 6 6 2 2 6 - 2 2 6 46 46 46 14 14 14 42 42 42 -246 246 246 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 10 10 10 - 2 2 6 2 2 6 22 22 22 14 14 14 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 62 62 62 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 74 74 74 2 2 6 2 2 6 - 14 14 14 70 70 70 34 34 34 62 62 62 -250 250 250 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 246 246 246 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 14 14 14 - 2 2 6 2 2 6 30 30 30 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 62 62 62 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 54 54 54 62 62 62 2 2 6 2 2 6 - 2 2 6 30 30 30 46 46 46 70 70 70 -250 250 250 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 246 246 246 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 226 226 226 10 10 10 - 2 2 6 6 6 6 30 30 30 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 58 58 58 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 22 22 22 - 58 58 58 62 62 62 2 2 6 2 2 6 - 2 2 6 2 2 6 30 30 30 78 78 78 -250 250 250 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 246 246 246 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 206 206 206 2 2 6 - 22 22 22 34 34 34 18 14 6 22 22 22 - 26 26 26 18 18 18 6 6 6 2 2 6 - 2 2 6 82 82 82 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 26 26 26 - 62 62 62 106 106 106 74 54 14 185 133 11 -210 162 10 121 92 8 6 6 6 62 62 62 -238 238 238 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 246 246 246 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 158 158 158 18 18 18 - 14 14 14 2 2 6 2 2 6 2 2 6 - 6 6 6 18 18 18 66 66 66 38 38 38 - 6 6 6 94 94 94 50 50 50 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 10 10 10 10 10 10 18 18 18 38 38 38 - 78 78 78 142 134 106 216 158 10 242 186 14 -246 190 14 246 190 14 156 118 10 10 10 10 - 90 90 90 238 238 238 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 250 250 250 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 246 230 190 -238 204 91 238 204 91 181 142 44 37 26 9 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 38 38 38 46 46 46 - 26 26 26 106 106 106 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 14 14 14 22 22 22 - 30 30 30 38 38 38 50 50 50 70 70 70 -106 106 106 190 142 34 226 170 11 242 186 14 -246 190 14 246 190 14 246 190 14 154 114 10 - 6 6 6 74 74 74 226 226 226 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 250 250 250 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 228 184 62 -241 196 14 241 208 19 232 195 16 38 30 10 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 30 30 30 26 26 26 -203 166 17 154 142 90 66 66 66 26 26 26 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 18 18 18 38 38 38 58 58 58 - 78 78 78 86 86 86 101 101 101 123 123 123 -175 146 61 210 150 10 234 174 13 246 186 14 -246 190 14 246 190 14 246 190 14 238 190 10 -102 78 10 2 2 6 46 46 46 198 198 198 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 224 178 62 -242 186 14 241 196 14 210 166 10 22 18 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 6 6 6 121 92 8 -238 202 15 232 195 16 82 82 82 34 34 34 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 14 14 14 38 38 38 70 70 70 154 122 46 -190 142 34 200 144 11 197 138 11 197 138 11 -213 154 11 226 170 11 242 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -225 175 15 46 32 6 2 2 6 22 22 22 -158 158 158 250 250 250 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 250 250 250 242 242 242 224 178 62 -239 182 13 236 186 11 213 154 11 46 32 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 61 42 6 225 175 15 -238 190 10 236 186 11 112 100 78 42 42 42 - 14 14 14 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 22 22 22 54 54 54 154 122 46 213 154 11 -226 170 11 230 174 11 226 170 11 226 170 11 -236 178 12 242 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -241 196 14 184 144 12 10 10 10 2 2 6 - 6 6 6 116 116 116 242 242 242 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 231 231 231 198 198 198 214 170 54 -236 178 12 236 178 12 210 150 10 137 92 6 - 18 14 6 2 2 6 2 2 6 2 2 6 - 6 6 6 70 47 6 200 144 11 236 178 12 -239 182 13 239 182 13 124 112 88 58 58 58 - 22 22 22 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 70 70 70 180 133 36 226 170 11 -239 182 13 242 186 14 242 186 14 246 186 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 232 195 16 98 70 6 2 2 6 - 2 2 6 2 2 6 66 66 66 221 221 221 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 206 206 206 198 198 198 214 166 58 -230 174 11 230 174 11 216 158 10 192 133 9 -163 110 8 116 81 8 102 78 10 116 81 8 -167 114 7 197 138 11 226 170 11 239 182 13 -242 186 14 242 186 14 162 146 94 78 78 78 - 34 34 34 14 14 14 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 30 30 30 78 78 78 190 142 34 226 170 11 -239 182 13 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 241 196 14 203 166 17 22 18 6 - 2 2 6 2 2 6 2 2 6 38 38 38 -218 218 218 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 206 206 206 198 198 198 202 162 69 -226 170 11 236 178 12 224 166 10 210 150 10 -200 144 11 197 138 11 192 133 9 197 138 11 -210 150 10 226 170 11 242 186 14 246 190 14 -246 190 14 246 186 14 225 175 15 124 112 88 - 62 62 62 30 30 30 14 14 14 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 174 135 50 224 166 10 -239 182 13 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 241 196 14 139 102 15 - 2 2 6 2 2 6 2 2 6 2 2 6 - 78 78 78 250 250 250 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 214 214 214 198 198 198 190 150 46 -219 162 10 236 178 12 234 174 13 224 166 10 -216 158 10 213 154 11 213 154 11 216 158 10 -226 170 11 239 182 13 246 190 14 246 190 14 -246 190 14 246 190 14 242 186 14 206 162 42 -101 101 101 58 58 58 30 30 30 14 14 14 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 74 74 74 174 135 50 216 158 10 -236 178 12 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 241 196 14 226 184 13 - 61 42 6 2 2 6 2 2 6 2 2 6 - 22 22 22 238 238 238 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 226 226 226 187 187 187 180 133 36 -216 158 10 236 178 12 239 182 13 236 178 12 -230 174 11 226 170 11 226 170 11 230 174 11 -236 178 12 242 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 186 14 239 182 13 -206 162 42 106 106 106 66 66 66 34 34 34 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 26 26 26 70 70 70 163 133 67 213 154 11 -236 178 12 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 241 196 14 -190 146 13 18 14 6 2 2 6 2 2 6 - 46 46 46 246 246 246 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 221 221 221 86 86 86 156 107 11 -216 158 10 236 178 12 242 186 14 246 186 14 -242 186 14 239 182 13 239 182 13 242 186 14 -242 186 14 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -242 186 14 225 175 15 142 122 72 66 66 66 - 30 30 30 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 26 26 26 70 70 70 163 133 67 210 150 10 -236 178 12 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -232 195 16 121 92 8 34 34 34 106 106 106 -221 221 221 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -242 242 242 82 82 82 18 14 6 163 110 8 -216 158 10 236 178 12 242 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 242 186 14 163 133 67 - 46 46 46 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 163 133 67 210 150 10 -236 178 12 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -241 196 14 215 174 15 190 178 144 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 218 218 218 - 58 58 58 2 2 6 22 18 6 167 114 7 -216 158 10 236 178 12 246 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 186 14 242 186 14 190 150 46 - 54 54 54 22 22 22 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 38 38 38 86 86 86 180 133 36 213 154 11 -236 178 12 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 232 195 16 190 146 13 214 214 214 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 250 250 250 170 170 170 26 26 26 - 2 2 6 2 2 6 37 26 9 163 110 8 -219 162 10 239 182 13 246 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 186 14 236 178 12 224 166 10 142 122 72 - 46 46 46 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 109 106 95 192 133 9 224 166 10 -242 186 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -242 186 14 226 184 13 210 162 10 142 110 46 -226 226 226 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -198 198 198 66 66 66 2 2 6 2 2 6 - 2 2 6 2 2 6 50 34 6 156 107 11 -219 162 10 239 182 13 246 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 242 186 14 -234 174 13 213 154 11 154 122 46 66 66 66 - 30 30 30 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 22 22 22 - 58 58 58 154 121 60 206 145 10 234 174 13 -242 186 14 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 186 14 236 178 12 210 162 10 163 110 8 - 61 42 6 138 138 138 218 218 218 250 250 250 -253 253 253 253 253 253 253 253 253 250 250 250 -242 242 242 210 210 210 144 144 144 66 66 66 - 6 6 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 61 42 6 163 110 8 -216 158 10 236 178 12 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 239 182 13 230 174 11 216 158 10 -190 142 34 124 112 88 70 70 70 38 38 38 - 18 18 18 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 22 22 22 - 62 62 62 168 124 44 206 145 10 224 166 10 -236 178 12 239 182 13 242 186 14 242 186 14 -246 186 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 236 178 12 216 158 10 175 118 6 - 80 54 7 2 2 6 6 6 6 30 30 30 - 54 54 54 62 62 62 50 50 50 38 38 38 - 14 14 14 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 80 54 7 167 114 7 -213 154 11 236 178 12 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 242 186 14 239 182 13 239 182 13 -230 174 11 210 150 10 174 135 50 124 112 88 - 82 82 82 54 54 54 34 34 34 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 158 118 36 192 133 9 200 144 11 -216 158 10 219 162 10 224 166 10 226 170 11 -230 174 11 236 178 12 239 182 13 239 182 13 -242 186 14 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 186 14 230 174 11 210 150 10 163 110 8 -104 69 6 10 10 10 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 91 60 6 167 114 7 -206 145 10 230 174 11 242 186 14 246 190 14 -246 190 14 246 190 14 246 186 14 242 186 14 -239 182 13 230 174 11 224 166 10 213 154 11 -180 133 36 124 112 88 86 86 86 58 58 58 - 38 38 38 22 22 22 10 10 10 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 34 34 34 70 70 70 138 110 50 158 118 36 -167 114 7 180 123 7 192 133 9 197 138 11 -200 144 11 206 145 10 213 154 11 219 162 10 -224 166 10 230 174 11 239 182 13 242 186 14 -246 186 14 246 186 14 246 186 14 246 186 14 -239 182 13 216 158 10 185 133 11 152 99 6 -104 69 6 18 14 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 80 54 7 152 99 6 -192 133 9 219 162 10 236 178 12 239 182 13 -246 186 14 242 186 14 239 182 13 236 178 12 -224 166 10 206 145 10 192 133 9 154 121 60 - 94 94 94 62 62 62 42 42 42 22 22 22 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 18 18 18 34 34 34 58 58 58 78 78 78 -101 98 89 124 112 88 142 110 46 156 107 11 -163 110 8 167 114 7 175 118 6 180 123 7 -185 133 11 197 138 11 210 150 10 219 162 10 -226 170 11 236 178 12 236 178 12 234 174 13 -219 162 10 197 138 11 163 110 8 130 83 6 - 91 60 6 10 10 10 2 2 6 2 2 6 - 18 18 18 38 38 38 38 38 38 38 38 38 - 38 38 38 38 38 38 38 38 38 38 38 38 - 38 38 38 38 38 38 26 26 26 2 2 6 - 2 2 6 6 6 6 70 47 6 137 92 6 -175 118 6 200 144 11 219 162 10 230 174 11 -234 174 13 230 174 11 219 162 10 210 150 10 -192 133 9 163 110 8 124 112 88 82 82 82 - 50 50 50 30 30 30 14 14 14 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 22 22 22 34 34 34 - 42 42 42 58 58 58 74 74 74 86 86 86 -101 98 89 122 102 70 130 98 46 121 87 25 -137 92 6 152 99 6 163 110 8 180 123 7 -185 133 11 197 138 11 206 145 10 200 144 11 -180 123 7 156 107 11 130 83 6 104 69 6 - 50 34 6 54 54 54 110 110 110 101 98 89 - 86 86 86 82 82 82 78 78 78 78 78 78 - 78 78 78 78 78 78 78 78 78 78 78 78 - 78 78 78 82 82 82 86 86 86 94 94 94 -106 106 106 101 101 101 86 66 34 124 80 6 -156 107 11 180 123 7 192 133 9 200 144 11 -206 145 10 200 144 11 192 133 9 175 118 6 -139 102 15 109 106 95 70 70 70 42 42 42 - 22 22 22 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 10 10 10 - 14 14 14 22 22 22 30 30 30 38 38 38 - 50 50 50 62 62 62 74 74 74 90 90 90 -101 98 89 112 100 78 121 87 25 124 80 6 -137 92 6 152 99 6 152 99 6 152 99 6 -138 86 6 124 80 6 98 70 6 86 66 30 -101 98 89 82 82 82 58 58 58 46 46 46 - 38 38 38 34 34 34 34 34 34 34 34 34 - 34 34 34 34 34 34 34 34 34 34 34 34 - 34 34 34 34 34 34 38 38 38 42 42 42 - 54 54 54 82 82 82 94 86 76 91 60 6 -134 86 6 156 107 11 167 114 7 175 118 6 -175 118 6 167 114 7 152 99 6 121 87 25 -101 98 89 62 62 62 34 34 34 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 6 6 6 10 10 10 - 18 18 18 22 22 22 30 30 30 42 42 42 - 50 50 50 66 66 66 86 86 86 101 98 89 -106 86 58 98 70 6 104 69 6 104 69 6 -104 69 6 91 60 6 82 62 34 90 90 90 - 62 62 62 38 38 38 22 22 22 14 14 14 - 10 10 10 10 10 10 10 10 10 10 10 10 - 10 10 10 10 10 10 6 6 6 10 10 10 - 10 10 10 10 10 10 10 10 10 14 14 14 - 22 22 22 42 42 42 70 70 70 89 81 66 - 80 54 7 104 69 6 124 80 6 137 92 6 -134 86 6 116 81 8 100 82 52 86 86 86 - 58 58 58 30 30 30 14 14 14 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 10 10 10 14 14 14 - 18 18 18 26 26 26 38 38 38 54 54 54 - 70 70 70 86 86 86 94 86 76 89 81 66 - 89 81 66 86 86 86 74 74 74 50 50 50 - 30 30 30 14 14 14 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 18 18 18 34 34 34 58 58 58 - 82 82 82 89 81 66 89 81 66 89 81 66 - 94 86 66 94 86 76 74 74 74 50 50 50 - 26 26 26 14 14 14 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 6 6 6 14 14 14 18 18 18 - 30 30 30 38 38 38 46 46 46 54 54 54 - 50 50 50 42 42 42 30 30 30 18 18 18 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 14 14 14 26 26 26 - 38 38 38 50 50 50 58 58 58 58 58 58 - 54 54 54 42 42 42 30 30 30 18 18 18 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 6 6 6 10 10 10 14 14 14 18 18 18 - 18 18 18 14 14 14 10 10 10 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 14 14 14 18 18 18 22 22 22 22 22 22 - 18 18 18 14 14 14 10 10 10 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 +3 0 0 3 0 0 3 0 0 1 0 0 1 0 0 1 1 1 +2 1 5 1 0 5 2 0 5 2 0 1 5 0 0 5 0 0 +7 0 0 4 0 1 1 1 3 0 2 6 0 0 2 0 0 2 +0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +0 0 2 1 1 3 2 0 3 2 0 3 1 0 5 0 1 3 +0 1 0 0 1 0 1 2 0 4 0 0 5 0 0 5 0 0 +4 1 5 3 1 7 2 3 8 0 2 6 0 2 6 0 2 4 +0 2 1 0 2 4 0 0 4 0 0 5 0 0 5 0 0 4 +1 0 0 4 0 0 2 0 5 1 0 6 2 3 13 2 3 8 +0 0 4 1 0 0 4 0 0 6 0 0 4 1 3 2 0 5 +0 0 4 0 0 2 0 0 2 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 2 +1 0 6 1 0 6 1 0 5 0 0 0 1 0 0 4 0 0 +4 0 1 4 1 3 0 0 2 0 0 2 0 0 2 0 0 0 +1 0 0 1 0 0 1 0 0 0 0 2 0 0 2 0 0 2 +0 0 2 0 1 3 1 1 3 2 0 3 2 0 1 2 0 1 +0 0 0 0 0 0 2 1 0 2 1 0 4 0 1 4 0 1 +4 1 5 2 0 5 1 0 5 0 1 3 0 1 3 0 2 1 +1 1 1 1 1 1 1 1 3 1 0 5 0 0 4 0 0 2 +2 1 0 2 1 0 2 0 3 2 0 5 1 0 6 1 0 6 +0 0 2 0 0 0 2 1 0 2 1 0 4 1 3 2 0 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 0 0 2 +0 0 2 0 2 1 0 2 1 0 0 0 1 0 5 0 0 5 +1 0 6 1 0 6 0 2 4 0 1 2 0 1 0 0 1 0 +0 0 5 1 0 6 3 0 2 3 0 0 3 0 0 3 0 0 +3 0 0 3 0 0 4 0 0 2 0 1 0 0 2 0 0 2 +0 2 4 0 2 6 0 1 3 1 1 0 3 1 0 4 0 0 +3 0 0 3 0 0 2 0 3 2 0 5 1 1 3 1 1 3 +1 1 0 1 2 0 2 1 0 4 0 0 5 0 0 7 0 0 +5 0 0 5 0 0 2 1 0 2 1 0 4 0 1 4 0 1 +2 1 0 2 1 0 2 0 1 4 1 3 4 1 3 3 0 0 +1 1 0 0 2 0 0 2 0 0 1 0 0 0 0 1 0 0 +1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 2 0 0 5 0 0 5 +0 2 6 0 2 1 0 2 1 2 0 1 3 0 4 2 0 5 +1 0 6 0 0 5 0 2 4 0 2 2 0 1 0 0 1 2 +0 0 5 0 0 5 3 0 2 3 0 0 3 0 0 3 0 0 +3 0 0 4 0 0 5 0 0 4 0 0 1 0 0 0 0 2 +0 2 6 0 2 6 0 2 6 1 1 1 3 0 0 4 0 0 +4 0 0 4 0 2 2 0 5 1 0 6 0 2 6 0 2 4 +0 2 0 1 2 0 5 1 0 7 1 0 8 0 0 7 0 0 +5 0 0 5 0 0 3 0 0 1 0 0 2 0 1 2 0 1 +1 1 0 1 1 0 4 0 0 5 0 0 7 0 0 5 0 0 +1 2 0 0 3 0 0 2 0 0 2 0 0 1 0 0 0 0 +1 2 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 4 1 0 6 2 3 8 +0 2 6 0 2 1 2 1 0 5 0 0 6 1 3 6 1 3 +2 0 5 0 2 4 0 2 2 0 2 2 0 1 0 0 0 0 +0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 2 1 0 4 0 0 5 0 0 3 0 0 0 0 2 +0 2 6 0 2 6 2 3 8 0 2 6 1 0 2 4 0 0 +4 0 0 4 0 0 1 0 5 1 0 6 0 2 6 0 2 6 +0 0 2 1 0 0 5 1 0 5 1 0 2 2 0 1 1 1 +1 1 3 1 0 5 1 0 5 1 0 5 0 0 2 0 1 2 +0 1 0 0 2 0 4 0 0 7 0 0 8 0 0 7 0 0 +2 2 0 0 3 0 0 2 0 0 2 2 0 1 2 0 1 2 +0 2 1 0 3 0 0 1 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 2 1 0 6 1 0 6 +0 2 4 0 3 0 2 1 0 5 0 0 6 1 3 6 1 3 +2 0 3 0 1 3 0 1 2 0 1 0 0 1 0 0 0 0 +1 0 0 1 0 0 0 0 0 0 1 0 0 0 2 0 0 2 +0 0 2 0 0 0 4 0 0 4 0 0 3 0 0 2 0 3 +0 2 6 0 2 6 1 0 6 1 0 6 1 0 5 3 0 2 +5 0 0 4 0 1 0 0 4 0 0 5 1 0 6 0 2 6 +0 0 4 1 0 2 2 1 0 1 1 0 0 2 0 0 2 1 +0 2 6 0 2 6 1 0 6 1 0 6 0 0 5 0 2 4 +0 2 2 0 2 1 2 1 0 5 0 0 7 0 0 5 0 0 +2 1 0 0 2 0 0 1 2 0 2 4 0 0 5 0 0 4 +0 2 4 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 4 1 3 2 0 3 +1 1 1 0 2 1 1 1 1 2 0 3 3 0 4 3 0 2 +4 0 1 2 0 1 0 0 0 0 0 0 0 0 2 0 0 2 +0 0 2 1 1 1 0 0 0 0 0 2 0 0 4 0 0 4 +0 0 4 0 0 4 0 0 2 1 0 0 4 0 0 4 0 1 +2 0 1 2 0 3 1 1 3 0 0 2 0 0 2 1 0 2 +2 0 1 2 1 0 0 0 0 0 0 2 1 0 5 1 0 6 +1 0 6 1 0 5 1 0 5 0 1 3 0 2 1 0 2 1 +0 2 1 0 2 6 1 0 6 1 0 6 1 0 6 0 0 5 +0 2 6 0 2 6 0 2 6 2 0 5 4 1 5 4 1 3 +4 1 3 2 0 3 1 0 6 1 0 6 3 1 7 4 1 5 +6 1 3 4 0 0 1 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 2 1 0 +2 1 0 2 1 0 0 0 2 1 1 3 1 0 5 2 0 3 +4 0 1 4 0 0 4 0 0 3 0 0 1 0 2 1 0 2 +1 1 3 1 1 3 4 0 1 4 0 1 1 0 2 1 0 2 +1 0 5 0 0 4 0 0 2 0 0 2 2 0 1 2 0 1 +4 0 0 4 0 0 4 0 0 1 0 0 1 0 0 0 0 0 +1 1 1 1 1 0 0 0 0 1 0 0 2 0 3 2 0 5 +1 0 6 1 0 6 0 2 6 1 2 4 2 2 0 1 2 0 +1 1 0 1 1 1 0 0 5 0 0 5 0 2 6 0 2 6 +0 2 6 0 2 6 0 2 6 1 0 6 2 0 5 4 1 5 +3 0 0 3 0 0 2 0 5 2 0 5 3 1 7 4 1 5 +7 0 0 6 0 0 1 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 7 5 3 +7 1 0 7 1 0 10 9 7 1 1 1 8 8 8 2 1 5 +4 0 2 9 1 3 10 1 0 8 0 0 5 0 0 6 0 0 +7 2 6 4 1 3 7 0 0 6 0 0 11 1 0 14 1 4 +9 1 3 4 0 0 2 0 3 3 4 7 0 0 4 0 0 2 +1 0 0 3 0 0 4 0 0 4 0 0 3 0 0 1 0 0 +0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 0 0 2 +0 0 4 0 2 4 2 3 8 2 0 1 9 1 0 14 1 0 +10 1 0 4 0 0 3 3 3 2 5 5 0 2 0 5 5 3 +3 3 1 0 1 0 0 2 6 2 3 8 0 0 4 4 0 0 +7 1 0 3 0 0 0 0 0 0 1 2 2 3 8 2 3 8 +2 1 0 4 0 0 1 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 4 4 2 5 5 3 +3 3 1 3 0 0 7 5 3 2 2 0 4 1 3 10 9 7 +9 1 3 11 1 0 14 1 0 14 1 0 14 1 0 11 1 0 +6 1 3 4 1 5 4 1 3 15 7 8 11 1 0 7 0 0 +8 0 0 9 4 5 4 1 5 0 0 4 0 0 5 0 0 4 +0 0 4 1 0 0 4 0 0 4 0 0 3 0 0 1 0 0 +0 0 2 0 0 2 0 0 0 1 0 0 1 0 0 0 0 0 +0 1 2 0 1 2 3 3 5 8 8 8 8 0 0 7 0 0 +17 6 0 11 1 0 1 0 0 8 10 3 15 7 8 10 7 0 +6 0 0 7 0 0 9 4 5 9 4 5 7 2 6 9 4 5 +7 1 0 5 1 0 3 3 1 2 5 5 0 2 6 0 2 4 +2 2 0 6 5 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 4 4 2 3 3 1 +7 7 7 0 0 0 2 2 0 7 5 3 7 1 0 10 1 0 +18 0 0 22 1 2 26 1 0 26 1 0 17 1 0 11 1 0 +8 3 8 7 11 16 1 0 6 2 3 8 1 2 4 3 0 2 +7 1 0 4 0 0 3 0 0 7 7 7 0 0 4 0 0 5 +0 0 5 0 0 5 0 0 4 1 0 2 4 1 3 1 0 2 +0 0 2 0 0 2 0 0 2 0 0 2 0 0 0 0 1 0 +0 1 0 0 2 0 0 1 0 4 8 7 8 9 10 6 6 6 +4 1 3 14 1 4 14 1 0 10 1 0 18 0 0 22 1 2 +26 1 0 26 1 0 26 1 0 17 1 0 9 1 3 8 3 8 +4 1 3 1 0 0 5 1 0 7 5 3 6 4 5 2 0 1 +3 3 3 4 4 2 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 0 0 4 0 0 6 5 0 +4 8 7 1 3 4 8 10 3 11 1 0 18 0 0 48 4 0 +48 4 0 74 34 6 107 69 8 104 34 7 72 12 0 48 4 0 +26 1 0 22 1 2 10 10 9 2 3 8 0 0 5 0 0 5 +3 1 7 4 1 5 4 0 1 3 0 0 3 0 2 0 0 4 +0 0 5 0 0 5 0 0 5 0 0 4 2 0 3 2 0 3 +1 0 2 0 0 2 0 0 4 0 0 4 0 0 2 1 1 1 +1 1 0 0 2 0 4 8 7 0 2 2 0 2 6 5 7 10 +9 1 0 14 1 0 26 1 0 35 1 0 48 4 0 74 34 6 +104 34 7 104 34 7 72 12 0 48 4 0 26 1 0 22 1 2 +5 0 0 4 1 5 5 1 0 7 1 0 11 1 0 9 4 5 +3 3 3 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 0 0 7 0 0 7 5 3 +0 2 6 4 8 7 13 14 7 18 0 0 48 4 0 143 69 23 +183 101 57 210 113 41 210 113 41 216 104 20 210 113 41 183 98 20 +104 34 7 48 4 0 22 1 2 9 1 3 8 3 14 7 11 16 +2 3 13 2 3 13 8 8 8 5 0 0 7 0 0 4 0 0 +0 1 3 0 2 4 0 2 4 0 1 2 1 1 0 2 1 0 +1 0 0 0 0 2 0 0 4 0 0 4 1 1 3 2 0 3 +4 0 1 2 0 3 0 2 6 7 11 16 2 5 5 2 1 0 +25 6 3 30 1 2 72 12 0 143 69 23 210 113 41 210 113 41 +210 113 41 210 113 41 210 113 41 183 101 57 104 34 7 35 1 0 +14 1 0 8 8 8 6 6 6 3 0 0 10 1 0 11 1 0 +2 2 2 3 3 5 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 3 0 0 11 1 0 5 0 0 +2 3 8 2 3 8 10 1 0 48 4 0 143 69 23 210 113 41 +216 104 20 216 104 20 230 106 20 230 106 20 230 106 20 229 114 40 +210 113 41 183 98 20 72 12 0 35 1 0 14 1 0 8 3 8 +2 3 13 2 3 13 3 4 7 15 7 8 8 0 0 7 0 0 +1 1 1 0 2 4 0 2 4 0 2 2 1 2 0 2 1 0 +0 0 2 0 0 4 0 0 2 2 0 3 4 1 3 4 1 3 +4 1 3 2 0 5 8 9 10 1 0 0 17 6 0 22 1 2 +35 1 0 104 34 7 183 101 57 210 113 41 216 104 20 232 104 4 +230 106 20 230 106 20 230 106 20 210 113 41 183 98 20 143 69 23 +30 1 2 8 0 0 6 6 6 3 0 2 8 0 0 10 1 0 +1 0 0 8 9 10 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 0 0 11 1 0 3 0 0 +7 11 16 5 3 3 35 1 0 143 69 23 210 113 41 239 111 20 +230 106 20 230 106 20 230 106 20 230 106 20 232 104 4 222 105 4 +216 104 20 216 104 20 183 98 20 104 34 7 48 4 0 18 0 0 +8 9 10 2 3 13 1 0 5 4 0 0 8 0 0 8 0 0 +2 0 1 0 2 4 0 2 6 0 2 4 2 1 0 2 1 0 +0 0 4 0 0 4 3 0 2 5 0 0 7 0 0 5 0 0 +2 0 5 2 0 5 3 0 2 26 16 7 26 1 0 48 4 0 +143 69 23 210 113 41 216 104 20 230 106 20 241 109 9 232 104 4 +216 104 20 216 104 20 230 106 20 230 106 20 229 114 40 210 113 41 +104 34 7 22 1 2 7 1 0 3 4 7 5 0 0 9 3 6 +1 0 2 7 7 7 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 0 0 8 0 0 8 1 5 +8 3 14 11 1 0 74 34 6 183 101 57 239 111 20 239 103 3 +241 109 9 232 104 4 222 105 4 230 106 20 232 104 4 232 104 4 +232 104 4 230 106 20 230 106 20 210 113 41 143 69 23 72 12 0 +18 0 0 8 0 0 6 1 3 5 0 0 8 0 0 7 1 0 +2 0 1 0 0 4 0 2 6 0 0 5 2 0 1 2 1 0 +0 0 4 0 0 4 1 0 2 4 0 0 7 0 0 7 0 0 +4 1 3 8 0 0 22 1 2 35 1 0 104 34 7 183 101 57 +210 113 41 216 104 20 232 104 4 239 103 3 239 103 3 232 104 4 +230 106 20 230 106 20 222 105 4 232 104 4 232 104 4 216 104 20 +183 101 57 48 4 0 11 1 0 8 3 14 2 0 5 8 3 14 +4 1 3 4 1 5 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 0 0 9 1 3 9 1 3 +15 7 8 26 1 0 143 69 23 210 113 41 222 105 4 239 103 3 +239 103 3 232 104 4 232 104 4 241 109 9 239 103 3 239 103 3 +232 104 4 222 105 4 230 106 20 216 104 20 210 113 41 183 101 57 +104 34 7 30 1 2 18 0 0 14 1 0 9 1 0 7 1 0 +9 4 5 6 6 6 1 0 6 7 11 16 7 11 16 4 1 5 +3 0 4 3 4 7 2 5 5 0 2 2 9 3 6 14 1 4 +18 0 0 26 1 0 48 4 0 143 69 23 210 113 41 229 114 40 +216 104 20 230 106 20 239 103 3 239 103 3 239 103 3 239 103 3 +222 105 4 222 105 4 232 104 4 232 104 4 232 104 4 216 104 20 +210 113 41 74 34 6 26 1 0 3 1 7 3 1 7 7 2 6 +5 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 0 0 5 0 0 9 1 3 +18 1 4 35 1 0 143 100 31 216 104 20 222 105 4 239 103 3 +239 103 3 241 109 9 232 104 4 232 104 4 239 103 3 239 103 3 +232 104 4 241 109 9 241 109 9 239 111 20 222 105 4 216 104 20 +210 113 41 143 69 23 48 4 0 18 0 0 25 6 3 8 0 0 +4 0 0 3 0 0 7 11 16 7 11 16 0 0 2 20 16 18 +15 7 8 1 0 2 2 5 5 8 8 8 10 1 0 18 0 0 +48 4 0 72 12 0 143 100 31 210 113 41 229 114 40 230 106 20 +232 104 4 232 104 4 241 109 9 239 103 3 239 103 3 241 109 9 +232 104 4 232 104 4 239 112 3 232 104 4 232 104 4 230 106 20 +210 113 41 104 34 7 30 1 2 8 1 5 8 3 8 7 2 6 +4 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 11 1 0 +17 1 0 48 4 0 183 101 57 216 104 20 230 106 20 241 109 9 +241 109 9 232 104 4 222 105 4 222 105 4 232 104 4 239 112 3 +241 109 9 239 103 3 241 109 9 232 104 4 241 109 9 239 111 20 +216 104 20 210 113 41 143 100 31 74 34 6 30 1 2 22 1 2 +10 1 0 15 7 8 4 1 5 2 0 3 15 7 8 5 1 0 +6 1 3 6 4 5 6 4 5 14 1 4 26 1 0 48 4 0 +104 34 7 183 101 57 217 124 25 230 106 20 232 104 4 232 104 4 +232 104 4 232 104 4 232 104 4 239 112 3 239 112 3 241 109 9 +241 109 9 232 104 4 232 104 4 232 104 4 232 104 4 230 124 24 +210 113 41 143 69 23 35 1 0 14 1 0 9 1 3 8 1 5 +4 1 3 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 11 1 0 +18 0 0 74 34 6 210 113 41 230 106 20 230 106 20 241 109 9 +241 109 9 232 104 4 232 104 4 223 116 8 222 105 4 232 104 4 +239 103 3 241 109 9 241 109 9 232 104 4 239 103 3 239 103 3 +232 104 4 230 106 20 210 113 41 183 101 57 104 34 7 35 1 0 +26 1 0 18 0 0 6 0 0 7 5 3 3 0 0 10 9 7 +3 0 0 10 1 0 25 6 3 26 1 0 48 4 0 107 69 8 +210 113 41 217 124 25 223 116 8 232 104 4 239 112 3 239 112 3 +239 112 3 232 104 4 232 104 4 239 112 3 232 104 4 232 104 4 +241 109 9 241 109 9 241 109 9 232 104 4 222 105 4 230 106 20 +217 124 25 183 98 20 48 4 0 17 1 0 11 1 0 8 1 5 +4 1 3 3 0 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 6 1 6 5 0 +22 1 2 74 34 6 215 129 57 230 106 20 239 111 20 239 103 3 +239 103 3 241 109 9 232 104 4 232 104 4 239 126 20 239 111 20 +241 109 9 239 103 3 232 104 4 239 111 20 232 104 4 232 104 4 +241 109 9 223 116 8 223 116 8 221 134 40 210 113 41 143 69 23 +72 12 0 30 1 2 25 6 3 7 1 0 5 5 5 4 4 4 +7 5 3 18 0 0 35 1 0 104 34 7 183 98 20 221 134 40 +230 106 20 230 106 20 230 106 20 232 104 4 232 104 4 239 112 3 +241 109 9 241 109 9 241 109 9 239 111 20 230 124 24 222 105 4 +232 104 4 241 109 9 232 104 4 239 112 3 241 109 9 230 106 20 +216 104 20 183 101 57 48 4 0 17 1 0 10 1 0 6 1 3 +4 1 3 4 1 5 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 6 1 2 2 0 +22 1 2 74 34 6 210 113 41 230 106 20 239 111 20 232 104 4 +239 112 3 239 112 3 232 104 4 230 106 20 216 104 20 216 104 20 +229 114 40 239 111 20 230 106 20 230 106 20 241 109 9 239 112 3 +232 104 4 239 112 3 241 109 9 222 105 4 230 106 20 210 113 41 +183 101 57 104 34 7 35 1 0 25 6 3 8 0 0 11 1 0 +22 1 2 48 4 0 107 69 8 210 113 41 221 134 40 239 111 20 +239 111 20 239 111 20 239 111 20 239 111 20 241 109 9 241 109 9 +239 103 3 239 111 20 230 106 20 216 104 20 216 104 20 210 113 41 +230 106 20 241 109 9 232 104 4 232 104 4 241 109 9 222 105 4 +217 124 25 183 101 57 35 1 0 14 1 0 8 0 0 7 1 0 +2 0 1 6 4 5 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 2 1 0 3 0 2 2 0 +22 1 2 72 12 0 210 113 41 230 106 20 239 111 20 239 112 3 +239 112 3 232 104 4 239 111 20 217 124 25 143 69 23 104 34 7 +183 98 20 215 129 57 230 124 24 232 104 4 232 104 4 239 112 3 +240 120 3 239 103 3 232 104 4 241 109 9 239 111 20 230 124 24 +221 134 40 210 113 41 107 69 8 48 4 0 30 1 2 30 1 2 +72 12 0 143 100 31 229 114 40 230 106 20 222 105 4 232 104 4 +241 109 9 241 109 9 232 104 4 241 109 9 241 109 9 223 116 8 +230 106 20 229 114 40 210 113 41 143 69 23 104 34 7 183 98 20 +216 104 20 239 112 3 243 126 10 239 112 3 239 112 3 223 116 8 +210 113 41 143 100 31 35 1 0 8 0 0 2 2 0 4 4 2 +3 0 2 6 4 5 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 2 1 0 1 0 5 1 0 +18 0 0 72 12 0 210 113 41 230 124 24 241 109 9 241 109 9 +239 112 3 241 109 9 223 116 8 210 113 41 143 69 23 48 4 0 +72 12 0 143 100 31 210 113 41 230 124 24 239 111 20 232 104 4 +239 112 3 243 126 10 241 109 9 239 112 3 239 112 3 232 104 4 +223 116 8 230 124 24 215 129 57 183 98 20 104 34 7 104 34 7 +198 136 53 210 113 41 230 106 20 241 109 9 239 112 3 241 109 9 +241 109 9 241 109 9 232 104 4 223 116 8 223 116 8 223 116 8 +229 114 40 210 113 41 143 69 23 48 4 0 72 12 0 183 101 57 +230 124 24 232 104 4 240 120 3 232 104 4 239 112 3 230 124 24 +221 134 40 143 69 23 30 1 2 9 1 3 3 3 1 4 4 2 +3 0 4 6 4 5 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 3 3 +11 1 0 48 4 0 210 113 41 230 124 24 239 111 20 239 112 3 +241 109 9 243 126 10 223 116 8 210 113 41 143 69 23 35 1 0 +30 1 2 35 1 0 107 69 8 183 101 57 221 134 40 230 124 24 +241 109 9 241 109 9 239 112 3 232 104 4 240 120 3 239 112 3 +239 112 3 223 116 8 230 124 24 230 124 24 229 114 40 217 124 25 +217 124 25 230 124 24 223 116 8 239 112 3 239 112 3 239 112 3 +239 112 3 240 120 3 240 120 3 223 116 8 217 124 25 221 134 40 +183 101 57 104 34 7 30 1 2 35 1 0 48 4 0 198 136 53 +217 124 25 240 120 3 239 112 3 239 112 3 240 120 3 223 116 8 +210 113 41 143 69 23 26 1 0 7 1 0 3 3 1 0 3 0 +3 3 5 2 0 5 0 0 2 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 1 1 1 8 8 8 4 4 4 0 0 0 +3 3 3 0 0 0 1 1 1 3 3 3 0 0 0 0 0 0 +3 3 3 3 3 3 2 2 2 4 4 4 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 1 1 1 8 8 8 4 4 4 0 0 0 +3 3 3 0 0 0 1 1 1 3 3 3 0 0 0 0 0 0 +3 3 3 3 3 3 2 2 2 4 4 4 3 3 3 0 0 0 +1 1 1 4 4 4 0 0 0 3 3 3 5 5 5 2 2 2 +1 1 1 0 0 0 6 6 6 1 1 1 0 0 0 1 1 1 +0 0 0 0 0 0 1 1 1 3 3 3 1 1 1 0 0 0 +2 2 2 6 6 6 3 3 3 0 0 0 0 0 0 1 1 1 +4 4 4 0 0 0 0 0 0 5 5 5 2 2 2 0 0 0 +2 2 2 0 0 0 0 0 0 5 5 5 5 5 5 0 0 0 +2 2 2 10 10 9 7 7 7 0 0 0 3 3 3 0 0 0 +1 1 1 6 6 6 0 0 0 4 4 4 0 0 0 3 3 3 +6 6 6 2 2 2 0 0 0 1 1 1 3 3 3 1 1 1 +0 0 0 5 5 5 1 1 1 1 1 1 0 0 0 4 4 4 +2 2 2 4 4 4 3 3 3 0 0 0 2 2 2 7 7 7 +8 8 8 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +2 2 2 2 2 2 1 1 1 4 4 4 1 1 1 0 0 0 +0 0 0 5 5 5 6 6 6 2 2 2 1 1 1 0 0 0 +0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 +6 6 6 0 0 0 3 3 3 3 3 3 2 2 2 0 0 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 7 7 7 +4 4 4 0 0 0 2 2 2 1 1 1 0 0 0 1 1 1 +2 2 2 6 6 6 0 0 0 1 1 1 2 2 2 8 8 8 +1 1 1 1 1 1 0 0 0 1 1 1 6 6 6 4 4 4 +0 0 0 0 0 0 5 5 5 0 0 0 6 6 6 4 4 4 +0 0 0 6 6 6 4 4 4 0 0 0 0 0 0 0 0 0 +3 3 3 7 7 7 2 2 2 0 0 0 2 2 2 2 2 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 9 3 3 +11 1 0 35 1 0 210 113 41 230 124 24 239 111 20 241 109 9 +239 112 3 240 120 3 223 116 8 217 124 25 143 100 31 30 1 2 +22 1 2 18 0 0 35 1 0 104 34 7 183 98 20 210 113 41 +229 114 40 230 124 24 223 116 8 239 126 20 223 116 8 240 120 3 +243 126 10 240 120 3 239 112 3 241 109 9 241 109 9 239 111 20 +223 116 8 223 116 8 240 120 3 239 112 3 240 120 3 243 126 10 +240 120 3 223 116 8 230 124 24 217 124 25 210 113 41 143 69 23 +48 4 0 30 1 2 25 6 3 18 0 0 72 12 0 198 136 53 +217 124 25 240 120 3 240 120 3 239 112 3 240 120 3 223 116 8 +210 113 41 143 69 23 26 1 0 8 0 0 3 3 1 2 2 0 +3 3 5 2 0 3 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 4 4 2 2 2 0 0 0 2 2 2 0 0 0 0 0 0 +3 3 3 1 1 1 0 0 0 2 2 2 1 1 1 1 1 1 +3 3 3 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 4 4 2 2 2 0 0 0 2 2 2 0 0 0 0 0 0 +3 3 3 1 1 1 0 0 0 2 2 2 1 1 1 1 1 1 +3 3 3 1 1 1 0 0 0 1 1 1 7 7 7 2 2 2 +0 0 0 0 0 0 1 1 1 0 0 0 2 2 2 0 0 0 +2 2 2 5 5 5 0 0 0 1 1 1 7 7 7 5 5 5 +5 5 5 1 1 1 0 0 0 3 3 3 4 4 4 3 3 3 +1 1 1 0 0 0 0 0 0 2 2 2 5 5 5 1 1 1 +2 2 2 3 3 3 3 3 3 2 2 2 0 0 0 4 4 4 +3 3 3 2 2 2 0 0 0 0 0 0 2 2 2 3 3 3 +4 4 4 0 0 0 0 0 0 2 2 2 10 10 9 3 3 3 +1 1 1 6 6 6 0 0 0 0 0 0 2 2 2 0 0 0 +0 0 0 1 1 1 3 3 3 4 4 4 3 3 3 0 0 0 +5 5 5 8 8 8 0 0 0 0 0 0 4 4 4 8 8 8 +0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 +2 2 2 5 5 5 3 3 3 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 7 7 7 +5 5 5 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 +4 4 4 7 7 7 5 5 5 0 0 0 0 0 0 3 3 3 +0 0 0 4 4 4 5 5 5 0 0 0 1 1 1 4 4 4 +3 3 3 0 0 0 2 2 2 1 1 1 0 0 0 0 0 0 +0 0 0 6 6 6 9 9 9 0 0 0 7 7 7 6 6 6 +0 0 0 2 2 2 3 3 3 3 3 3 0 0 0 3 3 3 +1 1 1 8 8 8 8 8 8 2 2 2 0 0 0 0 0 0 +3 3 3 9 9 9 0 0 0 1 1 1 3 3 3 0 0 0 +1 1 1 1 1 1 0 0 0 1 1 1 8 8 8 1 1 1 +0 0 0 4 4 4 5 5 5 4 4 4 4 4 4 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 9 3 3 +11 1 0 35 1 0 183 98 20 230 124 24 239 111 20 239 112 3 +239 112 3 240 120 3 240 120 3 217 124 25 143 100 31 35 1 0 +22 1 2 17 1 0 22 1 2 22 1 2 48 4 0 143 69 23 +210 113 41 221 134 40 239 126 20 223 116 8 239 126 20 223 116 8 +223 116 8 240 120 3 243 126 10 239 112 3 241 109 9 239 126 20 +239 126 20 240 120 3 239 112 3 240 120 3 240 120 3 240 120 3 +223 116 8 217 124 25 221 134 40 198 136 53 104 34 7 35 1 0 +26 1 0 18 0 0 11 1 0 33 6 2 72 12 0 215 129 57 +217 124 25 240 120 3 240 120 3 239 112 3 240 120 3 223 116 8 +217 124 25 107 69 8 30 1 2 11 1 0 9 1 0 2 1 0 +3 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 1 1 1 2 2 2 4 4 4 3 3 3 2 2 2 +3 3 3 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 +3 3 3 2 2 2 2 2 2 4 4 4 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 1 1 1 2 2 2 4 4 4 3 3 3 2 2 2 +3 3 3 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 +3 3 3 2 2 2 2 2 2 4 4 4 0 0 0 1 1 1 +6 6 6 0 0 0 7 7 7 0 0 0 3 3 3 5 5 5 +0 0 0 9 9 9 0 0 0 3 3 3 5 5 5 0 0 0 +2 2 2 1 1 1 9 9 9 5 5 5 0 0 0 0 0 0 +1 1 1 0 0 0 1 1 1 6 6 6 0 0 0 5 5 5 +4 4 4 0 0 0 0 0 0 4 4 4 4 4 4 0 0 0 +3 3 3 6 6 6 3 3 3 2 2 2 0 0 0 0 0 0 +5 5 5 1 1 1 4 4 4 3 3 3 7 7 7 1 1 1 +0 0 0 3 3 3 1 1 1 2 2 2 6 6 6 1 1 1 +0 0 0 1 1 1 0 0 0 0 0 0 5 5 5 9 9 9 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 5 5 5 +2 2 2 4 4 4 0 0 0 4 4 4 4 4 4 5 5 5 +0 0 0 0 0 0 0 0 0 2 2 2 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 5 5 5 1 1 1 4 4 4 3 3 3 +0 0 0 0 0 0 4 4 4 6 6 6 6 6 6 0 0 0 +0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 5 5 5 +6 6 6 5 5 5 0 0 0 1 1 1 4 4 4 4 4 4 +1 1 1 4 4 4 0 0 0 2 2 2 7 7 7 6 6 6 +0 0 0 3 3 3 5 5 5 0 0 0 0 0 0 4 4 4 +0 0 0 0 0 0 2 2 2 1 1 1 0 0 0 8 8 8 +0 0 0 4 4 4 3 3 3 0 0 0 0 0 0 2 2 2 +1 1 1 0 0 0 4 4 4 6 6 6 0 0 0 0 0 0 +6 6 6 7 7 7 1 1 1 4 4 4 4 4 4 0 0 0 +1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 7 1 0 +10 1 0 35 1 0 183 98 20 230 124 24 239 126 20 240 120 3 +240 120 3 240 120 3 240 120 3 217 124 25 183 101 57 35 1 0 +22 1 2 14 1 0 10 1 0 14 1 0 26 1 0 35 1 0 +104 34 7 183 101 57 217 124 25 230 124 24 223 116 8 223 116 8 +243 126 10 240 120 3 240 120 3 239 112 3 241 109 9 239 111 20 +239 112 3 243 126 10 243 126 10 240 120 3 239 112 3 223 116 8 +230 124 24 215 129 57 143 100 31 74 34 6 35 1 0 30 1 2 +14 1 0 10 1 0 15 7 8 26 1 0 74 34 6 215 129 57 +217 124 25 240 120 3 240 120 3 240 120 3 240 120 3 227 127 8 +221 134 40 107 69 8 30 1 2 14 1 0 10 1 0 4 0 0 +3 3 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 2 2 4 4 4 3 3 3 0 0 0 0 0 0 1 1 1 +5 5 5 6 6 6 5 5 5 4 4 4 1 1 1 0 0 0 +1 1 1 4 4 4 4 4 4 3 3 3 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 2 2 4 4 4 3 3 3 0 0 0 0 0 0 1 1 1 +5 5 5 6 6 6 5 5 5 4 4 4 1 1 1 0 0 0 +1 1 1 4 4 4 4 4 4 3 3 3 1 1 1 1 1 1 +7 7 7 1 1 1 8 8 8 0 0 0 2 2 2 0 0 0 +0 0 0 5 5 5 4 4 4 5 5 5 4 4 4 3 3 3 +0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 2 2 2 +4 4 4 3 3 3 0 0 0 0 0 0 3 3 3 1 1 1 +0 0 0 10 10 9 10 10 9 0 0 0 0 0 0 3 3 3 +0 0 0 2 2 2 0 0 0 5 5 5 5 5 5 0 0 0 +2 2 2 4 4 4 9 9 9 0 0 0 0 0 0 0 0 0 +2 2 2 1 1 1 0 0 0 4 4 4 0 0 0 0 0 0 +3 3 3 4 4 4 2 2 2 0 0 0 0 0 0 0 0 0 +1 1 1 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 +0 0 0 1 1 1 8 8 8 1 1 1 0 0 0 5 5 5 +6 6 6 4 4 4 0 0 0 3 3 3 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 7 7 7 2 2 2 +0 0 0 3 3 3 6 6 6 0 0 0 1 1 1 2 2 2 +2 2 2 5 5 5 5 5 5 1 1 1 1 1 1 0 0 0 +0 0 0 5 5 5 1 1 1 4 4 4 2 2 2 3 3 3 +0 0 0 1 1 1 0 0 0 0 0 0 2 2 2 3 3 3 +2 2 2 0 0 0 0 0 0 5 5 5 2 2 2 5 5 5 +4 4 4 3 3 3 2 2 2 1 1 1 1 1 1 6 6 6 +4 4 4 3 3 3 1 1 1 1 1 1 4 4 4 5 5 5 +2 2 2 0 0 0 2 2 2 2 2 2 1 1 1 4 4 4 +5 5 5 1 1 1 0 0 0 1 1 1 2 2 2 0 0 0 +1 1 1 0 0 0 0 0 0 2 2 2 3 3 3 6 6 6 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 7 1 0 +8 0 0 35 1 0 143 100 31 217 124 25 239 126 20 240 120 3 +227 127 8 227 127 8 227 127 8 217 124 25 183 101 57 35 1 0 +17 1 0 8 0 0 7 0 0 26 16 7 14 1 0 17 1 0 +30 1 2 72 12 0 143 100 31 215 129 57 221 134 40 230 124 24 +240 120 3 240 120 3 240 120 3 239 112 3 241 109 9 239 126 20 +239 112 3 243 126 10 240 120 3 223 116 8 239 126 20 221 134 40 +183 98 20 143 69 23 48 4 0 26 1 0 14 1 0 11 1 0 +10 9 7 2 2 0 3 0 0 33 6 2 104 34 7 210 113 41 +217 124 25 227 127 8 240 120 3 240 120 3 240 120 3 227 127 8 +221 134 40 104 34 7 30 1 2 11 1 0 10 1 0 5 0 0 +3 3 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 2 2 2 2 2 2 1 1 1 2 2 2 +1 1 1 0 0 0 3 3 3 5 5 5 4 4 4 1 1 1 +0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 2 2 2 2 2 2 1 1 1 2 2 2 +1 1 1 0 0 0 3 3 3 5 5 5 4 4 4 1 1 1 +0 0 0 1 1 1 1 1 1 0 0 0 5 5 5 0 0 0 +1 1 1 0 0 0 4 4 4 2 2 2 4 4 4 0 0 0 +8 8 8 0 0 0 2 2 2 0 0 0 0 0 0 10 10 9 +1 1 1 2 2 2 4 4 4 9 9 9 7 7 7 1 1 1 +0 0 0 1 1 1 2 2 2 4 4 4 3 3 3 6 6 6 +0 0 0 0 0 0 0 0 0 0 0 0 7 7 7 4 4 4 +7 7 7 7 7 7 1 1 1 0 0 0 5 5 5 5 5 5 +0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 4 4 4 +4 4 4 2 2 2 2 2 2 3 3 3 4 4 4 2 2 2 +1 1 1 0 0 0 1 1 1 7 7 7 9 9 9 4 4 4 +6 6 6 0 0 0 0 0 0 2 2 2 1 1 1 3 3 3 +5 5 5 0 0 0 2 2 2 2 2 2 2 2 2 5 5 5 +2 2 2 1 1 1 2 2 2 8 8 8 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 7 7 7 2 2 2 6 6 6 0 0 0 +1 1 1 3 3 3 3 3 3 0 0 0 0 0 0 6 6 6 +5 5 5 2 2 2 0 0 0 0 0 0 5 5 5 3 3 3 +0 0 0 8 8 8 0 0 0 0 0 0 0 0 0 10 10 9 +9 9 9 0 0 0 7 7 7 3 3 3 2 2 2 0 0 0 +3 3 3 7 7 7 0 0 0 5 5 5 2 2 2 0 0 0 +1 1 1 2 2 2 3 3 3 4 4 4 3 3 3 0 0 0 +7 7 7 3 3 3 1 1 1 2 2 2 0 0 0 0 0 0 +0 0 0 5 5 5 3 3 3 0 0 0 4 4 4 8 8 8 +0 0 0 0 0 0 6 6 6 10 10 9 1 1 1 0 0 0 +2 2 2 3 3 3 6 6 6 8 8 8 1 1 1 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 4 0 0 +8 0 0 35 1 0 143 69 23 221 134 40 230 124 24 240 120 3 +227 127 8 227 127 8 239 126 20 217 124 25 183 101 57 35 1 0 +17 1 0 8 0 0 26 16 7 5 1 0 2 0 3 6 1 3 +18 1 4 26 1 0 48 4 0 107 69 8 215 129 57 221 134 40 +230 124 24 239 126 20 243 126 10 240 120 3 239 126 20 239 126 20 +239 126 20 240 120 3 230 124 24 230 124 24 221 134 40 183 98 20 +104 34 7 35 1 0 18 0 0 18 1 4 8 1 5 3 0 0 +4 4 4 7 7 7 7 5 3 26 1 0 104 34 7 210 113 41 +217 124 25 227 127 8 240 120 3 240 120 3 240 120 3 230 124 24 +215 129 57 104 34 7 30 1 2 9 1 3 9 1 3 4 0 0 +3 3 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +10 10 9 0 0 0 1 1 1 3 3 3 1 1 1 2 2 2 +2 2 2 2 2 2 0 0 0 0 0 0 3 3 3 3 3 3 +0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +10 10 9 0 0 0 1 1 1 3 3 3 1 1 1 2 2 2 +2 2 2 2 2 2 0 0 0 0 0 0 3 3 3 3 3 3 +0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 4 4 4 +10 10 9 4 4 4 3 3 3 0 0 0 3 3 3 8 8 8 +0 0 0 2 2 2 8 8 8 9 9 9 0 0 0 5 5 5 +0 0 0 0 0 0 5 5 5 3 3 3 0 0 0 0 0 0 +3 3 3 5 5 5 3 3 3 2 2 2 0 0 0 4 4 4 +0 0 0 5 5 5 5 5 5 0 0 0 4 4 4 0 0 0 +0 0 0 2 2 2 8 8 8 0 0 0 0 0 0 4 4 4 +1 1 1 1 1 1 1 1 1 9 9 9 6 6 6 2 2 2 +0 0 0 0 0 0 4 4 4 0 0 0 2 2 2 3 3 3 +5 5 5 3 3 3 0 0 0 0 0 0 3 3 3 5 5 5 +2 2 2 1 1 1 6 6 6 5 5 5 2 2 2 0 0 0 +3 3 3 4 4 4 0 0 0 3 3 3 2 2 2 3 3 3 +0 0 0 5 5 5 1 1 1 0 0 0 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +2 2 2 2 2 2 5 5 5 0 0 0 4 4 4 1 1 1 +6 6 6 1 1 1 0 0 0 4 4 4 3 3 3 3 3 3 +0 0 0 1 1 1 6 6 6 8 8 8 7 7 7 0 0 0 +3 3 3 0 0 0 0 0 0 20 16 18 1 1 1 0 0 0 +4 4 4 6 6 6 0 0 0 3 3 3 10 10 9 2 2 2 +1 1 1 8 8 8 0 0 0 2 2 2 0 0 0 3 3 3 +8 8 8 4 4 4 1 1 1 0 0 0 2 2 2 2 2 2 +2 2 2 0 0 0 0 0 0 3 3 3 5 5 5 5 5 5 +4 4 4 1 1 1 6 6 6 0 0 0 5 5 5 1 1 1 +0 0 0 10 10 9 6 6 6 0 0 0 3 3 3 4 4 4 +7 7 7 0 0 0 0 0 0 0 0 0 0 0 0 6 6 6 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 2 3 1 7 2 0 5 +8 0 0 30 1 2 143 69 23 221 134 40 227 127 8 240 120 3 +243 126 10 243 126 10 243 126 10 230 124 24 198 136 53 48 4 0 +18 0 0 9 1 3 4 0 0 10 9 7 2 2 2 2 1 0 +7 0 0 14 1 0 26 1 0 30 1 2 74 34 6 143 100 31 +215 129 57 221 134 40 230 124 24 239 126 20 230 124 24 223 116 8 +230 124 24 230 124 24 221 134 40 210 113 41 143 69 23 72 12 0 +26 1 0 14 1 0 10 9 7 2 2 2 6 6 6 10 10 9 +4 1 3 4 1 3 8 3 8 22 1 2 104 34 7 215 129 57 +217 124 25 239 126 20 243 126 10 243 126 10 240 120 3 230 124 24 +215 129 57 104 34 7 22 1 2 2 0 1 6 1 3 2 0 3 +2 3 8 3 1 7 0 0 2 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +9 9 9 0 0 0 4 4 4 9 9 9 0 0 0 0 0 0 +1 1 1 6 6 6 10 10 9 2 2 2 0 0 0 4 4 4 +3 3 3 0 0 0 2 2 2 4 4 4 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +9 9 9 0 0 0 4 4 4 9 9 9 0 0 0 0 0 0 +1 1 1 6 6 6 10 10 9 2 2 2 0 0 0 4 4 4 +3 3 3 0 0 0 2 2 2 4 4 4 0 0 0 4 4 4 +4 4 4 0 0 0 10 10 9 3 3 3 1 1 1 5 5 5 +2 2 2 20 16 18 0 0 0 4 4 4 4 4 4 1 1 1 +6 6 6 6 6 6 4 4 4 1 1 1 2 2 2 8 8 8 +7 7 7 0 0 0 0 0 0 10 10 9 4 4 4 4 4 4 +10 10 9 65 52 28 65 52 28 9 9 9 1 1 1 1 1 1 +20 16 18 0 0 0 5 5 5 7 7 7 0 0 0 4 4 4 +0 0 0 1 1 1 5 5 5 3 3 3 0 0 0 7 7 7 +10 10 9 6 6 6 6 6 6 0 0 0 10 10 9 0 0 0 +0 0 0 7 7 7 8 8 8 2 2 2 1 1 1 4 4 4 +1 1 1 2 2 2 0 0 0 0 0 0 10 10 9 6 6 6 +0 0 0 1 1 1 9 9 9 6 6 6 0 0 0 10 10 9 +1 1 1 6 6 6 0 0 0 10 10 9 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 7 7 7 20 16 18 0 0 0 +3 3 3 3 3 3 0 0 0 2 2 2 6 6 6 6 6 6 +1 1 1 6 6 6 4 4 4 0 0 0 5 5 5 9 9 9 +1 1 1 2 2 2 20 16 18 69 70 68 20 16 18 1 1 1 +0 0 0 0 0 0 20 16 18 0 0 0 9 9 9 6 6 6 +0 0 0 3 3 3 0 0 0 3 3 3 3 3 3 7 7 7 +3 3 3 0 0 0 7 7 7 5 5 5 2 2 2 3 3 3 +2 2 2 6 6 6 8 8 8 3 3 3 0 0 0 3 3 3 +5 5 5 0 0 0 1 1 1 1 1 1 3 3 3 0 0 0 +5 5 5 7 7 7 0 0 0 20 16 18 0 0 0 0 0 0 +4 4 4 1 1 1 6 6 6 10 10 9 1 1 1 3 3 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 0 5 1 0 2 0 0 0 0 1 0 0 0 0 0 0 0 +1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 +1 0 0 0 0 0 0 0 0 0 0 0 2 3 8 2 0 5 +8 0 0 30 1 2 143 69 23 217 124 25 230 124 24 243 126 10 +243 126 10 227 127 8 243 126 10 230 124 24 215 129 57 48 4 0 +18 0 0 4 0 2 4 1 3 3 3 5 6 6 6 3 3 3 +4 0 0 5 0 0 8 0 0 17 1 0 26 1 0 48 4 0 +104 34 7 183 101 57 215 129 57 221 134 40 210 113 41 215 129 57 +215 129 57 198 136 53 143 100 31 74 34 6 35 1 0 18 0 0 +9 1 3 3 1 7 6 6 6 4 4 4 1 0 0 5 0 0 +9 3 6 7 2 6 4 1 5 26 1 0 107 69 8 215 129 57 +230 124 24 239 126 20 239 126 20 239 126 20 243 126 10 230 124 24 +215 129 57 74 34 6 25 6 3 1 1 0 3 3 3 0 0 4 +2 3 8 0 2 6 0 0 2 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 20 16 18 82 82 81 126 126 126 132 133 128 126 126 124 +124 124 124 126 126 126 29 30 27 10 10 9 0 0 0 3 3 3 +5 5 5 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 20 16 18 82 82 81 126 126 126 132 133 128 126 126 124 +124 124 124 126 126 126 29 30 27 10 10 9 0 0 0 3 3 3 +5 5 5 0 0 0 0 0 0 1 1 1 6 6 6 1 1 1 +0 0 0 20 16 18 104 104 103 126 126 124 127 127 125 126 126 124 +127 127 125 119 119 117 20 16 18 1 1 1 5 5 5 0 0 0 +10 10 9 0 0 0 1 1 1 0 0 0 3 3 3 5 5 3 +0 0 0 7 5 3 69 70 68 124 124 124 164 164 161 203 203 202 +209 209 208 209 209 208 207 207 205 204 204 203 199 199 195 164 164 161 +104 104 103 20 16 18 0 0 0 5 5 5 1 1 1 6 6 6 +0 0 0 2 2 2 6 6 6 0 0 0 13 14 7 82 82 81 +124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 69 70 68 +6 6 6 0 0 0 5 5 5 3 3 3 0 0 0 1 1 1 +5 5 5 4 4 2 1 1 1 29 30 27 104 104 103 132 133 128 +126 126 126 126 126 126 119 119 117 132 133 128 126 126 126 119 119 117 +29 30 27 0 0 0 10 10 9 82 82 81 126 126 126 124 124 124 +124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 +124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 +124 124 124 124 124 124 127 127 125 127 127 125 104 104 103 20 16 18 +0 0 0 2 2 2 5 5 5 2 2 2 0 0 0 4 4 4 +2 2 2 3 3 3 0 0 0 13 14 7 86 87 84 154 154 152 +197 198 192 199 199 198 203 203 202 221 221 215 199 199 195 211 211 209 +193 193 192 141 141 139 86 87 84 20 16 18 0 0 0 4 4 4 +0 0 0 4 4 4 0 0 0 2 2 2 3 3 3 3 3 3 +0 0 0 29 30 27 86 87 84 126 126 126 126 126 126 124 124 124 +124 124 124 132 133 128 119 119 117 69 70 68 10 10 9 0 0 0 +4 4 4 2 2 2 1 1 1 0 0 0 3 3 3 2 2 2 +9 9 9 0 0 0 20 16 18 119 119 117 132 133 128 124 124 124 +124 124 124 126 126 126 132 133 128 104 104 103 29 30 27 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +8 3 14 4 1 5 0 2 1 0 3 0 0 3 0 2 1 0 +5 0 0 8 0 0 5 0 0 3 1 0 4 0 0 4 0 0 +4 0 0 2 1 0 1 2 0 0 2 0 2 2 2 6 6 6 +8 3 8 26 1 0 143 69 23 221 134 40 230 124 24 227 127 8 +227 127 8 239 126 20 227 127 8 221 134 40 215 129 57 74 34 6 +22 1 2 6 4 5 3 4 7 3 3 5 2 1 5 3 4 7 +3 4 7 3 1 7 1 0 5 2 0 3 10 1 0 14 1 0 +26 1 0 48 4 0 72 12 0 104 34 7 107 69 8 107 69 8 +74 34 6 72 12 0 30 1 2 22 1 2 17 6 0 9 1 3 +3 1 7 8 3 14 8 3 8 8 1 5 8 0 0 8 0 0 +6 1 3 6 1 3 5 3 3 18 0 0 107 69 8 215 129 57 +230 124 24 227 127 8 239 126 20 239 126 20 227 127 8 230 124 24 +215 129 57 72 12 0 33 6 2 5 5 5 3 3 5 0 0 4 +5 7 10 0 2 4 0 0 0 1 0 0 1 0 0 1 0 0 +1 0 0 1 0 0 3 0 0 1 0 0 3 0 2 1 0 2 +1 0 2 1 0 2 0 0 2 0 0 2 0 0 2 0 0 2 +1 1 1 1 1 1 126 126 124 206 206 204 208 208 206 206 207 202 +208 208 206 207 207 205 86 86 84 2 2 2 0 0 2 1 1 3 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 208 206 206 207 202 +208 208 206 207 207 205 86 86 84 3 3 1 0 0 0 2 2 0 +0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 202 207 208 203 +208 209 204 207 207 205 5 5 3 0 0 0 5 5 5 3 3 5 +2 2 2 0 0 0 0 0 0 1 1 0 7 5 3 1 2 0 +65 52 28 164 164 161 211 211 209 209 210 205 201 202 197 204 205 200 +208 209 204 209 210 205 207 208 203 209 210 205 211 212 207 205 206 201 +205 206 201 197 198 192 82 82 81 1 1 0 5 5 3 0 0 0 +0 0 0 3 3 3 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 206 206 204 208 208 206 209 209 208 82 82 81 +0 0 0 10 10 9 0 0 0 5 5 3 8 8 8 1 1 1 +0 0 0 7 5 3 3 3 1 175 176 174 209 209 208 204 204 203 +213 214 212 204 204 203 204 204 203 221 221 215 193 193 192 69 70 68 +0 0 0 3 3 3 3 4 7 126 126 126 209 209 208 206 207 202 +203 204 199 205 206 201 203 204 199 208 209 204 209 210 205 210 211 206 +207 208 203 207 208 203 207 208 203 207 208 203 207 208 203 207 208 203 +207 208 203 207 208 203 204 205 200 209 210 205 170 171 167 1 1 1 +3 3 3 3 4 7 1 2 4 1 2 4 0 0 2 10 10 9 +0 0 0 3 3 1 119 119 117 186 187 182 210 211 206 208 209 204 +207 208 203 204 205 200 205 206 201 208 209 204 205 206 201 205 206 201 +207 208 203 201 202 197 212 213 207 186 187 182 104 104 103 5 5 3 +0 0 0 6 6 6 2 2 2 0 0 0 1 1 3 3 4 7 +8 9 10 2 2 2 29 30 27 203 203 202 209 209 208 205 206 201 +207 208 203 204 205 200 206 207 202 193 193 192 29 30 27 1 1 0 +0 0 0 6 6 6 1 1 3 7 7 7 0 0 2 10 10 9 +0 0 0 10 9 7 82 82 81 207 208 203 204 205 200 213 213 209 +201 202 197 207 207 205 202 202 199 141 141 139 0 0 0 2 2 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +8 3 8 4 1 5 0 2 1 0 3 0 0 2 2 2 0 1 +7 0 0 8 0 0 3 1 0 2 1 0 2 1 0 2 1 0 +4 0 1 2 1 0 0 2 0 0 2 0 7 9 5 0 0 0 +4 1 5 22 1 2 107 69 8 221 134 40 230 124 24 239 126 20 +230 124 24 230 124 24 230 124 24 215 129 57 198 136 53 72 12 0 +11 1 0 8 9 10 2 0 3 6 4 5 8 3 8 2 0 5 +0 0 4 1 0 6 5 7 10 5 7 10 3 4 7 4 1 5 +6 1 3 8 0 0 17 1 0 26 1 0 30 1 2 30 1 2 +22 1 2 18 0 0 17 1 0 10 1 0 4 1 3 3 4 7 +2 3 13 3 1 7 8 3 14 14 1 4 11 1 0 8 0 0 +8 0 0 7 1 0 7 5 3 22 1 2 143 100 31 215 129 57 +221 134 40 230 124 24 230 124 24 230 124 24 239 126 20 230 124 24 +215 129 57 72 12 0 22 1 2 1 0 2 2 1 5 5 7 10 +5 7 10 6 6 6 0 0 0 1 0 0 1 0 0 1 0 0 +3 0 0 3 0 0 3 0 0 3 0 0 3 0 2 3 0 2 +1 0 2 1 0 2 0 0 2 0 0 2 0 0 2 0 0 2 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 2 0 0 2 1 1 3 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 3 3 1 0 0 0 2 2 0 +0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +207 208 203 207 208 203 4 4 2 2 2 0 3 3 3 0 0 2 +4 4 4 2 2 2 7 7 7 0 0 0 8 10 3 127 127 125 +207 208 203 207 208 203 203 204 199 199 199 195 207 208 202 211 212 207 +204 205 200 205 206 200 211 212 207 201 202 197 197 198 192 209 210 204 +211 212 207 201 202 197 210 211 206 141 141 139 0 0 0 2 2 0 +8 8 8 4 4 4 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 204 204 203 208 208 206 209 209 208 86 86 84 +7 5 3 2 2 0 7 5 3 2 2 0 0 0 0 7 5 3 +6 5 0 1 2 0 154 154 152 197 198 192 208 209 204 211 212 207 +202 202 199 207 207 205 221 221 215 186 187 182 69 70 68 5 5 5 +20 16 18 0 0 0 0 0 2 126 126 126 206 207 202 203 204 199 +205 206 200 211 212 207 209 210 204 206 207 201 204 205 200 204 205 200 +208 209 203 208 209 203 208 209 203 208 209 203 208 209 203 208 209 203 +208 209 204 208 209 204 212 213 207 209 210 204 170 171 167 2 2 0 +0 0 2 0 0 2 0 0 4 0 0 2 8 9 10 0 0 0 +29 30 27 164 164 161 206 207 202 208 209 204 206 207 201 206 207 201 +199 199 195 213 214 212 206 207 201 197 198 192 211 212 207 211 212 207 +205 206 200 213 213 209 203 204 199 201 202 197 211 211 209 170 171 167 +29 30 27 4 4 4 0 0 0 5 5 5 5 7 10 0 0 4 +0 0 2 10 10 9 8 8 8 104 104 103 221 221 215 201 202 197 +208 209 203 203 204 199 221 221 215 201 202 197 132 133 128 6 5 0 +10 10 9 5 5 5 3 3 5 3 4 7 0 0 2 1 1 1 +7 5 3 29 30 27 193 193 192 213 213 209 205 206 200 206 207 201 +212 213 207 203 204 199 186 187 182 29 30 27 8 8 8 1 1 1 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +7 2 6 2 0 3 0 2 4 0 2 4 0 0 5 2 0 5 +4 1 3 4 0 0 1 2 0 0 3 0 0 3 0 0 2 1 +1 1 3 1 0 5 0 2 4 0 2 4 0 2 6 8 8 8 +26 16 7 30 1 2 143 69 23 221 134 40 230 124 24 230 124 24 +217 124 25 210 113 41 215 129 57 215 129 57 183 101 57 74 34 6 +14 1 0 3 0 4 9 4 5 10 9 7 6 4 5 3 3 1 +7 5 3 9 9 9 8 3 8 3 0 2 3 0 2 2 0 3 +3 0 4 3 0 2 4 0 0 8 0 0 14 1 0 14 1 0 +14 1 0 14 1 0 10 1 0 6 0 0 4 0 0 4 4 2 +5 7 10 2 3 8 0 2 6 1 0 5 4 0 1 6 0 0 +8 0 0 8 0 0 9 1 3 18 0 0 107 72 55 170 133 50 +215 129 57 215 129 57 221 134 40 217 124 25 230 124 24 221 134 40 +215 129 57 72 12 0 22 1 2 7 11 16 1 0 5 1 0 5 +7 1 0 9 3 3 1 0 0 0 0 0 0 0 0 0 0 0 +1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 +1 0 0 1 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 3 3 1 0 0 0 2 2 0 +0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +207 208 203 207 208 203 2 2 0 4 4 2 0 0 0 0 0 0 +7 7 7 3 3 3 0 0 0 13 14 7 141 141 139 212 213 207 +203 204 199 216 217 214 197 198 192 216 217 214 208 209 204 207 208 203 +205 206 201 202 202 199 205 206 200 210 211 205 211 212 207 209 210 204 +202 202 199 211 212 207 208 209 204 201 202 197 154 154 152 10 10 9 +0 0 0 6 6 6 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 204 204 203 208 208 206 204 204 203 86 87 84 +0 0 0 0 0 0 5 5 3 5 5 3 20 16 18 0 0 0 +13 14 7 141 141 139 205 206 201 216 217 214 202 202 199 208 209 204 +206 206 204 209 209 208 186 187 182 69 70 68 4 4 4 1 1 1 +2 2 2 4 4 4 20 16 18 124 124 124 212 213 207 209 210 204 +209 210 204 206 207 201 205 206 200 207 208 202 213 213 209 212 213 207 +206 207 202 206 207 202 206 207 202 206 207 202 206 207 202 206 207 202 +206 207 202 206 207 202 206 207 201 197 198 192 164 164 161 6 6 6 +8 9 10 1 2 4 6 6 6 1 1 3 0 0 2 29 30 27 +170 171 167 203 204 199 213 214 212 199 199 195 209 210 205 213 213 209 +212 213 207 203 204 199 210 211 206 210 211 206 201 202 197 210 211 206 +221 221 215 206 207 202 205 206 201 202 202 199 211 211 209 209 209 208 +170 171 167 29 30 27 2 2 2 2 2 2 1 0 5 3 1 7 +3 4 7 2 2 2 0 0 0 7 5 3 141 141 139 212 213 207 +206 207 202 208 209 204 201 202 197 209 210 205 209 210 205 86 87 84 +0 0 0 6 6 6 8 9 10 0 0 2 8 9 10 8 8 8 +0 0 0 127 127 125 208 209 204 200 201 194 209 210 204 211 212 207 +199 199 195 203 204 199 86 87 84 0 0 0 0 0 0 4 4 4 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 2 0 1 1 1 0 2 4 0 2 6 1 0 6 2 0 5 +2 0 3 1 1 1 0 3 0 0 6 1 0 3 0 0 2 4 +0 0 5 1 0 6 0 2 6 0 2 6 1 0 6 9 3 6 +14 1 0 35 1 0 183 101 57 215 129 57 215 129 57 198 136 53 +143 100 31 143 69 23 104 34 7 72 12 0 48 4 0 22 1 2 +14 1 0 15 7 8 9 1 3 9 3 6 7 5 3 2 2 0 +0 1 0 1 0 0 7 5 3 15 7 8 6 1 3 8 1 5 +6 4 5 3 3 5 1 2 4 3 3 5 8 3 8 8 3 14 +3 1 7 3 0 2 4 0 0 10 7 0 10 7 0 3 3 1 +0 2 1 0 2 4 5 7 10 3 4 7 7 2 6 10 1 0 +11 1 0 14 1 0 14 1 4 18 0 0 26 1 0 48 4 0 +74 34 6 107 69 8 143 69 23 183 98 20 198 136 53 215 129 57 +198 136 53 107 69 8 18 0 0 8 3 8 2 0 5 7 2 6 +8 1 5 4 0 0 1 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 +1 0 0 1 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 2 2 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +208 209 204 209 210 205 0 0 0 4 4 2 0 0 0 1 1 1 +7 7 7 0 0 0 3 3 1 154 154 152 197 198 192 213 214 212 +209 210 205 197 198 192 213 214 212 203 204 199 207 208 203 204 205 200 +212 213 207 209 210 205 202 202 199 211 212 207 212 213 207 197 198 192 +202 202 199 212 213 207 209 210 205 213 214 212 193 193 192 119 119 117 +10 10 9 7 5 3 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 204 204 203 208 208 206 207 207 205 86 87 84 +0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 10 10 9 +119 119 117 213 213 209 212 213 207 203 204 199 216 217 214 206 207 202 +211 211 209 193 193 192 69 70 68 5 5 3 1 1 1 1 1 1 +0 0 0 2 2 2 0 0 2 126 126 126 201 202 197 207 208 202 +210 211 205 201 202 197 205 206 200 205 206 200 205 206 200 201 202 197 +209 210 205 209 210 205 209 210 205 209 210 205 209 210 205 209 210 205 +209 209 208 209 210 205 213 214 212 212 213 207 175 176 174 0 0 0 +0 0 0 7 7 7 20 16 18 0 0 0 29 30 27 175 176 174 +213 214 212 213 213 209 202 202 199 204 205 200 221 221 215 201 202 197 +203 204 199 209 210 205 205 206 201 207 208 203 216 217 214 206 207 202 +193 193 192 209 210 205 209 210 205 206 207 202 207 207 205 199 199 195 +216 217 214 175 176 174 29 30 27 0 0 0 0 0 2 8 9 10 +8 9 10 0 0 0 2 2 2 3 3 1 29 30 27 186 187 182 +208 209 204 205 206 201 203 204 199 213 214 212 208 209 204 175 176 174 +10 10 9 4 4 2 4 4 4 4 4 4 0 0 0 2 2 0 +69 70 68 206 207 202 206 207 202 207 208 202 209 210 204 205 206 200 +207 208 203 132 133 128 5 5 3 13 14 7 0 0 0 1 1 1 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 2 0 0 2 0 0 2 4 0 2 6 1 0 6 3 1 7 +2 0 5 0 1 3 0 2 1 0 3 0 0 3 0 0 2 4 +1 0 5 1 0 5 1 0 5 1 0 6 7 11 16 9 1 3 +17 1 0 65 52 28 163 140 97 143 100 31 104 34 7 48 4 0 +26 1 0 22 1 2 30 1 2 26 1 0 22 1 2 26 1 0 +18 0 0 14 1 0 14 1 4 4 0 1 2 2 0 6 6 6 +7 9 5 3 3 1 1 1 0 3 3 1 9 3 3 9 1 3 +8 0 0 7 0 0 3 0 2 0 0 2 0 2 4 0 2 6 +2 3 8 0 2 6 6 5 0 8 10 3 6 5 0 0 1 0 +0 1 0 5 7 10 0 0 4 4 1 3 14 1 4 17 1 0 +18 0 0 18 0 0 17 1 0 18 0 0 18 0 0 18 0 0 +26 1 0 26 1 0 22 1 2 35 1 0 74 34 6 107 69 8 +170 133 50 163 140 97 47 26 20 5 0 0 7 7 7 3 1 7 +3 1 7 3 1 7 0 0 4 0 0 2 0 0 2 0 0 2 +0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +205 206 201 209 210 205 0 0 0 3 3 1 2 2 2 3 3 3 +0 0 0 2 2 2 119 119 117 202 202 199 213 213 209 201 202 197 +213 214 212 216 217 214 199 199 198 211 211 209 186 187 182 141 141 139 +86 87 84 69 70 68 86 87 84 126 126 124 164 164 161 216 217 214 +208 209 204 204 205 200 204 204 203 199 199 195 216 217 214 208 208 206 +65 52 28 0 0 0 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 205 206 201 208 209 204 207 208 203 82 82 81 +5 5 3 5 5 3 7 7 7 0 0 0 5 5 3 104 104 103 +201 202 197 221 221 215 197 198 192 209 210 205 207 207 205 203 203 202 +199 199 195 82 82 81 1 1 1 10 10 9 1 1 1 1 1 1 +10 10 9 1 1 1 2 2 2 127 127 125 208 209 204 210 211 205 +211 212 207 207 208 202 213 213 209 186 187 182 170 171 167 170 171 167 +170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 +170 171 167 170 171 167 164 164 161 164 164 161 141 141 139 9 9 9 +4 4 4 2 2 2 0 0 0 7 7 7 132 133 128 201 202 197 +212 213 207 201 202 197 203 203 202 216 217 214 199 199 198 206 206 204 +186 187 182 119 119 117 86 87 84 86 86 84 86 87 84 119 119 117 +175 176 174 213 214 212 209 210 205 209 210 205 193 193 192 216 217 214 +203 203 202 199 199 198 141 141 139 0 0 0 7 7 7 6 6 6 +0 0 2 9 9 9 2 2 2 13 14 7 0 0 0 86 87 84 +208 209 204 202 202 199 216 217 214 201 202 197 205 206 201 210 211 206 +119 119 117 0 0 0 5 5 5 0 0 0 1 1 1 0 0 0 +170 171 167 201 202 197 206 207 202 209 210 205 203 204 199 207 208 203 +193 193 192 29 30 27 0 0 0 2 2 2 8 9 10 0 0 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 3 0 0 3 0 0 2 4 0 0 5 1 0 6 2 0 5 +1 0 6 0 0 5 0 2 4 0 2 4 0 2 4 0 1 3 +2 0 3 4 1 3 2 0 3 2 0 3 3 0 4 15 7 8 +25 6 3 65 52 28 74 34 6 35 1 0 26 1 0 22 1 2 +22 1 2 22 1 2 30 1 2 35 1 0 30 1 2 35 1 0 +35 1 0 48 4 0 35 1 0 26 1 0 22 1 2 22 1 2 +17 1 0 14 1 0 9 1 0 9 1 0 6 0 0 6 0 0 +7 0 0 9 1 3 9 3 6 5 5 5 2 3 8 2 3 8 +0 2 6 0 2 6 0 3 0 0 2 0 0 3 0 6 5 0 +6 5 0 8 0 0 17 6 0 25 6 3 30 1 2 35 1 0 +35 1 0 35 1 0 48 4 0 48 4 0 35 1 0 30 1 2 +30 1 2 30 1 2 30 1 2 22 1 2 30 1 2 35 1 0 +48 4 0 65 52 28 26 16 7 9 1 0 15 7 8 2 0 5 +3 1 7 2 3 13 0 0 5 0 0 4 0 0 4 0 0 2 +0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +202 202 199 208 209 204 0 0 0 2 2 0 3 3 3 2 2 2 +0 0 0 29 30 27 199 199 195 209 210 205 208 209 204 216 217 214 +193 193 192 207 208 203 208 208 206 127 127 125 3 3 1 5 5 3 +4 4 2 3 3 1 4 4 2 0 0 0 29 30 27 104 104 103 +193 193 192 213 213 209 211 211 209 209 209 208 213 214 212 199 199 198 +141 141 139 5 5 5 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 205 206 201 208 209 204 203 204 199 86 87 84 +3 3 1 7 5 3 0 0 0 13 14 7 104 104 103 204 204 203 +210 211 206 199 199 195 213 214 212 203 204 199 207 207 205 199 199 198 +69 70 68 3 3 1 1 1 1 1 1 1 2 2 2 5 5 5 +0 0 0 1 1 1 20 16 18 119 119 117 205 206 201 205 206 200 +210 211 205 212 213 207 197 198 192 86 87 84 8 10 3 0 1 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 2 2 0 0 0 0 10 10 9 0 0 0 +10 10 9 3 3 3 1 1 0 86 86 84 204 205 200 213 214 212 +199 199 195 202 202 199 221 221 215 202 202 199 203 203 202 126 126 126 +0 0 0 13 14 7 7 5 3 0 0 0 10 10 9 0 0 0 +29 30 27 104 104 103 199 199 195 201 202 197 221 221 215 207 208 203 +209 209 208 211 211 209 204 204 203 86 87 84 0 0 0 1 2 4 +0 0 2 9 9 9 0 0 0 2 2 0 6 6 6 3 3 1 +141 141 139 212 213 207 211 212 207 199 199 195 216 217 214 203 204 199 +213 214 212 69 70 68 0 0 0 7 7 7 3 3 1 119 119 117 +213 213 209 212 213 207 206 207 202 210 211 206 205 206 201 211 212 207 +86 86 84 0 0 0 4 4 4 0 0 0 3 3 5 1 1 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 3 0 0 3 0 0 2 1 0 0 4 0 0 4 2 0 5 +2 0 5 0 0 4 1 0 5 1 0 5 2 0 1 4 0 0 +5 0 0 7 0 0 5 0 0 4 0 0 7 7 7 7 5 3 +8 0 0 25 6 3 30 1 2 26 1 0 26 1 0 30 1 2 +48 4 0 74 34 6 107 69 8 183 98 20 198 136 53 198 136 53 +198 136 53 198 136 53 198 136 53 198 136 53 183 98 20 143 69 23 +74 34 6 48 4 0 30 1 2 17 1 0 11 1 0 3 0 2 +4 0 0 7 1 0 7 1 0 2 1 0 0 0 0 0 1 0 +3 4 7 1 3 4 1 3 4 1 7 3 6 5 0 10 7 0 +25 6 3 33 6 2 72 12 0 104 34 7 143 69 23 183 98 20 +198 136 53 198 136 53 198 136 53 210 113 41 198 136 53 183 98 20 +143 69 23 104 34 7 72 12 0 48 4 0 35 1 0 26 1 0 +18 0 0 26 16 7 11 1 0 14 1 4 8 3 8 4 1 3 +4 1 3 3 3 3 0 0 4 0 0 4 0 0 4 0 0 2 +0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 +0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 1 0 2 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +204 205 200 207 208 203 2 2 0 2 2 0 1 1 1 1 1 1 +13 14 7 124 124 124 206 207 202 209 210 205 201 202 197 203 204 199 +210 211 206 205 206 201 119 119 117 3 3 1 5 5 5 0 0 0 +0 0 0 1 1 1 5 5 5 1 1 0 0 0 0 20 16 18 +82 82 81 202 202 199 207 207 205 203 203 202 141 141 139 86 87 84 +5 5 5 1 1 1 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 205 206 201 208 209 204 206 207 202 86 87 84 +0 1 0 1 2 0 8 10 3 82 82 81 202 202 199 209 209 208 +204 205 200 213 213 209 204 204 203 204 204 203 204 204 203 69 70 68 +4 4 4 0 0 0 3 3 3 0 0 0 8 8 8 0 0 0 +3 3 3 7 7 7 0 0 0 127 127 125 206 207 202 205 206 200 +204 205 200 209 210 204 206 207 202 82 82 81 0 0 0 4 4 2 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 3 3 3 1 1 1 1 1 1 4 4 4 +1 1 1 0 0 0 13 14 7 154 154 152 211 212 207 207 208 202 +203 204 199 211 212 207 199 199 195 203 203 202 82 82 81 0 0 0 +8 8 8 0 0 0 0 0 0 3 3 3 4 4 2 0 0 0 +0 0 0 13 14 7 69 70 68 204 204 203 201 202 197 206 207 202 +197 198 192 208 209 204 205 206 201 154 154 152 8 8 8 1 2 4 +5 5 5 1 1 1 5 5 5 0 0 0 10 10 9 0 0 0 +29 30 27 175 176 174 207 208 203 211 212 207 211 212 207 197 198 192 +221 221 215 175 176 174 6 5 0 1 2 0 20 16 18 207 208 203 +201 202 197 210 211 206 211 212 207 203 204 199 203 203 202 141 141 139 +1 1 0 4 4 2 4 4 4 8 8 8 0 0 2 3 3 5 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 2 0 0 3 0 0 1 3 0 0 4 0 0 2 2 0 3 +2 0 5 1 0 5 4 1 5 4 1 3 5 0 0 5 0 0 +7 0 0 5 0 0 5 0 0 2 1 0 8 10 3 5 1 0 +17 6 0 22 1 2 26 1 0 35 1 0 74 34 6 143 100 31 +198 136 53 222 154 56 222 154 56 221 134 40 229 143 21 229 143 21 +229 143 21 229 143 21 229 143 21 229 143 21 221 134 40 221 134 40 +215 129 57 183 101 57 143 69 23 74 34 6 26 1 0 17 1 0 +11 1 0 10 1 0 9 1 0 7 1 0 7 5 3 9 9 9 +5 3 3 3 0 0 7 1 0 17 6 0 17 1 0 33 6 2 +107 69 8 143 100 31 222 154 56 222 154 56 220 161 40 229 143 21 +229 143 21 229 143 21 229 143 21 229 143 21 231 145 5 229 143 21 +221 134 40 215 129 57 215 129 57 183 101 57 107 69 8 72 12 0 +33 6 2 18 0 0 17 1 0 11 1 0 6 1 3 6 4 5 +3 0 0 4 4 2 0 0 2 0 0 4 0 0 4 0 0 2 +0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 +0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 1 0 2 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +209 210 205 209 210 205 4 4 2 1 1 0 0 0 0 0 0 0 +29 30 27 193 193 192 204 205 200 210 211 206 209 210 204 206 207 201 +213 213 209 141 141 139 2 2 0 2 2 2 0 0 2 3 3 5 +8 9 10 0 0 0 1 1 1 8 8 8 1 1 1 1 1 0 +2 2 0 124 124 124 154 154 152 69 70 68 2 2 0 7 5 3 +4 4 4 0 0 0 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 205 206 201 208 209 204 207 208 203 86 86 84 +7 5 3 3 3 1 69 70 68 197 198 192 221 221 215 203 203 202 +203 204 199 206 207 202 199 199 195 216 217 214 69 70 68 3 3 1 +2 2 2 0 0 0 1 1 1 1 1 1 0 0 0 3 3 3 +4 4 4 0 0 0 5 5 5 127 127 125 202 202 199 212 213 207 +207 208 202 203 204 199 208 209 204 86 87 84 0 0 0 3 3 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 2 2 2 5 5 5 3 3 3 0 0 0 +0 0 0 10 9 7 65 52 28 211 212 207 207 208 202 205 206 200 +209 210 204 204 205 200 211 211 209 127 127 125 0 0 2 6 6 6 +1 1 3 2 2 2 6 6 6 0 0 0 2 2 0 10 9 7 +1 1 0 0 0 0 3 3 1 119 119 117 213 213 209 207 208 203 +206 207 202 208 209 204 207 208 203 206 207 202 65 52 28 3 4 7 +0 0 0 1 1 1 6 6 6 4 4 4 1 1 0 5 5 3 +0 0 0 104 104 103 201 202 197 201 202 197 210 211 206 213 214 212 +193 193 192 212 213 207 124 124 124 2 2 0 154 154 152 208 209 204 +210 211 206 206 207 202 208 209 204 212 213 207 193 193 192 29 30 27 +3 3 1 3 3 3 6 6 6 1 2 4 3 4 7 0 0 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 2 0 1 1 0 1 1 3 1 1 3 1 1 1 2 0 1 +2 0 5 4 1 5 7 2 6 6 1 3 8 0 0 15 7 8 +4 1 3 6 4 5 7 7 7 0 0 2 2 2 0 14 1 0 +22 1 2 35 1 0 104 34 7 170 133 50 231 175 56 220 161 40 +242 158 39 229 155 20 229 155 20 229 155 20 231 145 5 231 145 5 +229 143 21 229 143 21 247 146 18 247 146 18 239 126 20 239 126 20 +230 124 24 221 134 40 221 134 40 198 136 53 143 100 31 74 34 6 +35 1 0 30 1 2 14 1 0 9 1 3 2 5 5 0 1 3 +15 7 8 17 1 0 18 0 0 48 4 0 107 69 8 198 136 53 +231 175 56 221 134 40 242 158 39 229 143 21 229 143 21 229 143 21 +229 143 21 229 143 21 231 145 5 231 145 5 246 147 4 241 129 3 +229 143 21 221 134 40 221 134 40 221 134 40 221 134 40 198 136 53 +143 69 23 72 12 0 26 1 0 14 1 0 10 7 0 2 2 0 +3 0 0 9 4 5 1 2 4 2 1 5 2 1 5 3 3 5 +0 2 2 0 2 2 2 5 5 0 2 2 0 1 0 0 1 0 +0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 1 0 2 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 3 3 1 0 0 0 2 2 0 +0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +205 206 201 210 211 206 0 0 0 2 2 0 5 5 3 3 3 1 +104 104 103 206 206 204 205 206 201 212 213 207 208 209 203 204 205 200 +201 202 197 29 30 27 0 0 0 0 0 0 1 1 3 1 1 3 +1 1 3 1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 206 207 202 208 209 204 209 210 205 86 87 84 +0 1 0 69 70 68 197 198 192 210 211 206 207 208 203 208 209 204 +211 212 207 205 206 201 213 214 212 104 104 103 0 0 0 7 5 3 +1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 0 0 0 +1 1 1 2 2 2 0 0 0 126 126 124 208 209 204 205 206 200 +207 208 202 211 212 207 206 207 202 86 87 84 2 2 0 2 2 0 +2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +2 2 2 2 2 2 1 1 3 20 16 18 0 0 0 6 6 6 +0 0 0 5 5 3 127 127 125 207 208 202 206 207 201 205 206 200 +211 212 207 207 208 202 186 187 182 7 7 7 0 0 2 7 7 7 +1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 7 7 7 0 0 0 186 187 182 204 205 200 +211 212 207 202 202 199 214 215 207 202 202 199 126 126 126 5 5 5 +0 0 0 0 0 0 3 3 3 0 0 0 7 7 7 4 4 2 +10 9 7 0 0 0 126 126 124 206 207 202 209 210 205 203 204 199 +216 217 214 201 202 197 197 198 192 119 119 117 201 202 197 212 213 207 +203 204 199 216 217 214 202 202 199 208 209 204 69 70 68 13 14 7 +0 0 0 5 5 5 3 3 5 1 1 3 1 1 3 1 1 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 0 0 1 0 0 2 0 5 2 0 3 1 1 0 1 1 0 +2 0 5 4 1 5 8 1 5 9 4 5 13 14 7 3 0 0 +3 4 7 2 3 8 0 0 5 15 7 8 26 16 7 17 1 0 +74 34 6 143 100 31 222 154 56 242 158 39 229 155 20 244 159 4 +246 158 18 246 147 4 231 145 5 231 145 5 246 147 4 246 147 4 +246 147 4 246 147 4 241 129 3 241 129 3 241 129 3 243 126 10 +243 126 10 239 126 20 239 126 20 230 124 24 217 124 25 198 136 53 +143 69 23 48 4 0 30 1 2 25 6 3 6 0 0 7 1 0 +14 1 0 33 6 2 107 69 8 170 133 50 231 175 56 242 158 39 +247 146 18 250 166 22 246 147 4 246 147 4 246 147 4 246 147 4 +231 145 5 231 145 5 231 145 5 241 129 3 241 129 3 241 129 3 +241 129 3 227 127 8 239 126 20 227 127 8 227 127 8 230 124 24 +210 113 41 183 101 57 107 69 8 35 1 0 18 0 0 11 1 0 +26 16 7 5 1 0 3 0 2 4 1 5 3 0 4 1 1 1 +0 0 0 0 2 2 6 6 6 6 6 6 0 1 0 0 1 0 +0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 1 0 2 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 3 3 1 0 0 0 2 2 0 +0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +206 207 202 208 209 204 2 2 0 3 3 1 6 6 6 0 0 0 +154 154 152 212 213 207 206 207 202 207 208 203 206 207 201 211 212 207 +141 141 139 13 14 7 1 1 1 1 1 1 1 0 5 1 0 5 +1 1 3 1 1 3 1 1 3 1 1 3 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 205 206 201 208 209 204 206 207 202 82 82 81 +65 52 28 186 187 182 207 208 203 205 206 201 213 213 209 204 205 200 +204 205 200 210 211 206 104 104 103 10 10 9 1 1 0 6 6 6 +6 6 6 3 3 3 2 2 2 0 0 0 1 1 1 0 0 0 +1 1 1 2 2 2 0 0 0 126 126 124 206 207 201 207 208 202 +205 206 200 209 210 204 208 209 204 86 86 84 0 0 0 5 5 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 3 4 7 0 0 2 0 0 0 4 4 4 +7 5 3 10 9 7 164 164 161 206 207 201 206 207 201 205 207 197 +206 207 201 209 210 204 124 124 124 3 3 3 0 0 2 2 1 5 +1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 4 4 2 0 0 0 127 127 125 209 210 205 +210 211 206 203 204 199 210 211 205 206 207 202 164 164 161 2 2 2 +5 5 5 5 5 5 3 3 3 1 1 1 2 2 2 1 1 1 +2 2 0 5 5 3 7 5 3 175 176 174 213 214 212 213 213 209 +201 202 197 211 212 207 214 215 207 203 204 199 206 207 201 208 209 203 +212 213 207 199 199 195 213 213 209 119 119 117 20 16 18 0 0 0 +0 0 0 6 6 6 1 1 3 1 1 3 3 4 7 6 6 6 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +3 0 2 3 0 4 2 0 5 2 0 5 1 1 1 1 1 1 +2 0 5 4 1 5 3 0 0 3 0 0 6 5 0 0 3 0 +2 3 8 1 0 6 7 11 16 10 1 0 26 1 0 107 69 8 +198 136 53 231 175 56 242 158 39 246 158 18 246 158 18 246 158 18 +244 159 4 233 156 5 233 156 5 231 145 5 246 147 4 246 147 4 +246 147 4 241 129 3 241 129 3 241 129 3 241 129 3 241 129 3 +243 126 10 243 126 10 239 126 20 239 126 20 230 124 24 217 124 25 +221 134 40 183 98 20 104 34 7 35 1 0 17 1 0 17 1 0 +48 4 0 143 69 23 222 154 56 231 175 56 242 158 39 246 158 18 +244 159 4 244 159 4 233 156 5 233 156 5 233 156 5 246 147 4 +231 145 5 231 145 5 241 129 3 241 129 3 241 129 3 241 129 3 +241 129 3 241 129 3 241 129 3 227 127 8 241 129 3 227 127 8 +229 143 21 217 124 25 215 129 57 143 69 23 48 4 0 30 1 2 +11 1 0 10 7 0 7 1 0 6 1 3 4 1 3 2 0 1 +3 0 2 1 1 1 0 0 2 1 2 4 0 0 2 0 0 2 +0 0 2 0 0 2 0 0 0 0 0 0 1 0 0 1 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 3 3 1 0 0 0 2 2 0 +0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +204 205 200 205 206 200 0 1 0 1 2 0 2 2 0 0 0 0 +193 193 192 209 210 205 208 209 204 205 206 200 206 207 201 214 215 207 +69 70 68 3 3 1 2 2 2 2 2 2 1 0 5 1 0 5 +1 1 3 1 1 3 1 1 3 1 1 3 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 205 206 201 208 209 204 204 205 200 104 104 103 +164 164 161 207 208 202 213 213 209 199 199 195 205 206 200 211 212 207 +213 213 209 119 119 117 20 16 18 0 0 0 7 7 7 1 1 1 +1 2 4 1 1 3 1 2 4 0 0 2 1 1 1 0 0 0 +1 1 1 2 2 2 0 0 0 126 126 124 207 208 202 211 212 205 +206 207 201 207 208 202 206 207 202 86 87 84 0 0 0 7 5 3 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 +1 1 0 1 1 0 1 1 1 0 0 0 10 10 9 8 8 8 +0 0 0 0 0 0 186 187 182 208 209 203 207 208 202 205 206 200 +204 205 200 206 207 201 65 52 28 0 0 0 1 2 4 0 0 2 +1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 +1 1 1 1 1 1 1 1 0 0 0 0 65 52 28 207 207 205 +208 209 204 204 205 200 206 207 201 210 211 206 186 187 182 0 0 0 +2 2 2 3 3 3 0 0 0 4 4 4 0 0 0 1 1 1 +3 3 1 1 1 0 0 0 0 69 70 68 201 202 197 209 210 204 +199 199 195 211 212 207 207 208 202 213 213 209 206 207 201 212 213 207 +205 206 201 208 209 204 175 176 174 6 6 6 1 1 1 0 0 0 +7 7 7 5 5 5 0 0 2 0 0 2 1 2 4 1 1 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +3 0 4 3 0 4 1 0 5 0 0 4 1 1 1 0 2 1 +2 0 5 2 0 5 7 5 3 1 2 0 0 3 0 8 10 3 +0 2 4 8 9 10 10 1 0 25 6 3 107 69 8 198 136 53 +231 175 56 225 170 23 233 156 5 246 158 18 246 158 18 244 159 4 +233 156 5 233 156 5 233 156 5 246 147 4 247 146 18 247 146 18 +246 147 4 246 147 4 241 129 3 241 129 3 241 129 3 241 129 3 +241 129 3 241 129 3 243 126 10 227 127 8 227 127 8 223 116 8 +230 124 24 221 134 40 210 113 41 104 34 7 48 4 0 48 4 0 +170 133 50 222 154 56 231 175 56 229 155 20 231 145 5 249 164 6 +249 164 6 233 156 5 233 156 5 233 156 5 233 156 5 246 147 4 +246 147 4 246 147 4 247 146 18 247 146 18 241 129 3 241 129 3 +241 129 3 241 129 3 241 129 3 241 129 3 241 129 3 241 129 3 +223 116 8 227 127 8 230 124 24 215 129 57 183 101 57 72 12 0 +30 1 2 17 6 0 8 0 0 4 0 0 4 0 0 5 1 0 +7 5 3 4 1 3 0 0 2 3 4 7 0 0 2 0 0 2 +0 0 2 0 0 2 0 0 0 0 0 0 1 0 0 1 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 2 2 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +205 206 200 208 209 203 0 1 0 1 2 0 0 0 0 20 16 18 +209 210 205 203 204 199 209 210 204 206 207 201 208 209 203 201 202 197 +10 9 7 0 0 0 3 3 3 3 3 3 1 1 3 1 0 5 +1 1 3 1 1 3 1 1 3 1 1 3 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 205 206 201 208 209 204 204 205 200 197 198 192 +211 212 207 216 217 214 201 202 197 214 215 207 207 208 202 206 207 201 +104 104 103 5 5 3 0 0 0 20 16 18 8 8 8 0 0 0 +1 2 4 1 1 3 1 2 4 0 0 2 1 1 1 0 0 0 +1 1 1 2 2 2 0 0 0 126 126 124 204 205 200 211 212 205 +211 212 207 210 211 205 197 198 192 86 87 84 7 7 7 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 2 2 0 7 7 7 0 0 0 5 5 5 +0 0 0 20 16 18 202 202 199 208 209 204 208 209 203 209 210 202 +206 207 201 193 193 192 5 5 3 1 1 0 3 3 5 1 1 3 +1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 +1 1 1 1 1 1 0 0 0 0 0 0 7 7 7 193 193 192 +207 208 203 208 209 204 205 206 200 210 211 206 203 203 202 20 16 18 +0 0 0 0 0 0 0 0 0 5 5 5 1 1 1 4 4 4 +3 3 1 13 14 7 0 0 0 8 10 3 119 119 117 213 213 209 +213 213 209 200 201 194 207 208 202 209 210 204 207 208 202 186 187 182 +209 210 205 213 213 209 82 82 81 0 0 0 5 5 5 5 5 5 +4 4 4 1 1 1 1 1 3 3 4 7 3 4 7 0 0 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +3 0 4 1 0 5 1 0 5 0 0 2 0 0 0 0 2 1 +2 0 5 2 0 5 7 5 3 6 5 0 0 6 1 0 6 1 +0 2 0 26 16 7 26 1 0 143 100 31 231 175 56 244 176 40 +225 170 23 225 170 23 242 171 21 242 171 21 233 156 5 244 159 4 +233 156 5 233 156 5 246 147 4 246 147 4 246 147 4 246 147 4 +231 145 5 231 145 5 231 145 5 227 127 8 241 129 3 241 129 3 +241 129 3 241 129 3 241 129 3 227 127 8 223 116 8 239 126 20 +223 116 8 223 116 8 221 134 40 183 98 20 143 69 23 183 98 20 +231 175 56 242 158 39 229 155 20 242 171 21 250 166 22 249 164 6 +244 159 4 244 159 4 244 159 4 246 147 4 246 147 4 246 147 4 +246 147 4 246 147 4 241 129 3 241 129 3 241 129 3 241 129 3 +241 129 3 227 127 8 241 129 3 241 129 3 241 129 3 240 120 3 +243 126 10 240 120 3 223 116 8 230 124 24 215 129 57 183 101 57 +74 34 6 30 1 2 18 0 0 10 1 0 11 1 0 7 1 0 +5 1 0 5 3 3 1 1 3 3 4 7 0 0 4 0 0 4 +0 0 4 0 0 2 0 0 0 0 0 0 1 0 0 1 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +207 208 202 214 215 207 2 2 0 6 5 0 3 3 1 69 70 68 +211 212 207 207 208 203 209 210 204 209 210 204 209 210 204 175 176 174 +0 0 0 1 1 0 1 1 1 2 2 2 1 1 3 1 1 3 +1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 3 1 1 3 0 0 0 3 3 3 0 0 0 127 127 125 +208 209 204 206 207 202 205 206 201 208 209 204 205 206 200 205 206 200 +201 202 197 210 211 205 199 199 195 207 208 202 199 199 195 175 176 174 +6 6 6 0 0 0 10 10 9 0 0 0 6 6 6 4 4 4 +1 1 3 1 1 3 1 2 4 0 0 2 1 1 1 0 0 0 +1 1 0 2 2 0 0 0 0 126 126 124 211 212 207 205 206 200 +206 207 201 208 209 203 209 210 205 186 187 182 164 164 161 170 171 167 +170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 +170 171 167 170 171 167 170 171 167 132 133 128 9 9 9 3 3 3 +4 4 4 69 70 68 213 214 212 213 214 212 207 208 202 210 211 205 +208 209 203 175 176 174 0 0 0 2 2 0 1 1 3 3 3 5 +1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 +1 1 1 1 1 1 2 2 2 1 1 1 0 0 0 175 176 174 +208 209 204 210 211 206 206 207 201 208 209 204 211 211 209 69 70 68 +5 5 5 2 2 2 1 1 1 4 4 4 2 2 2 3 3 3 +4 4 4 2 2 2 4 4 2 3 3 1 10 9 7 175 176 174 +186 187 182 212 213 207 207 208 202 200 201 194 221 221 215 210 211 205 +212 213 207 119 119 117 6 6 6 0 0 0 3 3 3 1 1 1 +0 0 0 1 1 1 5 5 5 5 5 5 2 2 2 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 4 0 0 4 0 0 4 0 0 2 0 0 0 0 0 0 +2 0 5 4 1 5 3 0 0 4 4 2 0 6 1 0 3 0 +10 1 0 22 1 2 107 69 8 231 175 56 225 170 23 242 171 21 +242 171 21 236 169 8 236 169 8 233 156 5 233 156 5 244 159 4 +233 156 5 233 156 5 246 147 4 246 147 4 231 145 5 229 143 21 +229 143 21 229 143 21 229 143 21 229 143 21 241 129 3 241 129 3 +241 129 3 241 129 3 241 129 3 241 129 3 243 126 10 223 116 8 +239 126 20 243 126 10 222 105 4 223 116 8 229 155 20 244 176 40 +229 155 20 242 171 21 242 169 5 244 159 4 244 159 4 244 159 4 +244 159 4 233 156 5 246 158 18 247 146 18 247 146 18 247 146 18 +247 146 18 247 146 18 229 143 21 229 143 21 247 146 18 247 146 18 +231 145 5 227 127 8 227 127 8 241 129 3 240 120 3 240 120 3 +240 120 3 239 112 3 243 126 10 223 116 8 217 124 25 210 113 41 +183 101 57 72 12 0 22 1 2 10 1 0 17 6 0 9 1 0 +4 0 0 6 4 5 3 0 4 0 0 2 0 0 4 0 0 4 +0 0 4 0 0 2 0 0 2 0 0 0 1 0 0 1 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +204 205 200 212 213 207 1 2 0 6 5 0 5 5 3 82 82 81 +207 208 203 210 211 206 206 207 201 210 211 205 207 208 202 164 164 161 +4 4 2 4 4 2 0 0 0 1 1 1 1 1 3 1 1 3 +1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 3 1 1 3 0 0 0 3 3 3 0 0 0 127 127 125 +208 209 204 206 207 202 205 206 201 208 209 204 214 215 207 197 198 192 +216 217 214 203 204 199 216 217 214 205 206 200 210 211 205 199 199 195 +104 104 103 13 14 7 2 2 0 0 0 0 2 2 2 5 5 5 +0 0 2 6 6 6 1 2 4 0 0 2 1 1 1 0 0 0 +1 1 0 2 2 0 0 0 0 126 126 124 207 208 202 203 204 197 +209 210 204 211 212 207 208 209 204 208 209 204 211 211 209 204 204 203 +208 208 206 208 208 206 208 209 204 208 209 204 208 209 204 208 209 203 +208 209 203 208 209 203 209 210 205 175 176 174 0 0 0 2 2 2 +5 5 5 86 86 84 202 202 199 202 202 199 206 207 202 208 209 203 +207 208 202 164 164 161 4 4 2 3 3 1 0 0 0 3 3 5 +1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 +1 1 1 1 1 1 3 3 3 1 1 1 6 6 6 164 164 161 +209 210 205 211 212 207 206 207 201 207 208 203 207 207 205 86 87 84 +4 4 4 0 0 0 1 1 1 1 1 1 2 2 2 1 1 1 +0 0 0 6 6 6 10 10 9 0 1 0 0 1 0 86 87 84 +214 215 207 205 207 197 216 217 214 204 205 198 203 204 199 212 213 207 +175 176 174 0 1 0 7 5 3 3 3 1 2 2 2 1 1 1 +0 0 0 4 4 4 3 3 3 0 0 0 0 0 0 1 1 1 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 2 0 0 2 0 0 2 0 0 0 0 1 0 1 0 0 +4 1 5 4 1 5 7 2 6 6 4 5 0 2 2 10 7 0 +17 6 0 107 69 8 222 154 56 244 176 40 250 166 22 249 164 6 +236 169 8 236 169 8 244 159 4 244 159 4 244 159 4 244 159 4 +231 145 5 247 146 18 233 156 5 233 156 5 229 143 21 229 143 21 +221 134 40 221 134 40 229 143 21 229 143 21 239 126 20 239 126 20 +243 126 10 241 129 3 241 129 3 241 129 3 239 112 3 240 120 3 +243 126 10 222 105 4 223 116 8 246 158 18 249 178 22 242 171 21 +249 176 7 249 164 6 244 159 4 233 156 5 244 159 4 249 164 6 +246 158 18 233 156 5 247 146 18 247 146 18 246 158 18 229 155 20 +229 143 21 229 143 21 221 134 40 221 134 40 230 124 24 230 124 24 +229 143 21 239 126 20 227 127 8 240 120 3 240 120 3 240 120 3 +239 112 3 243 126 10 243 126 10 239 112 3 222 105 4 230 124 24 +216 104 20 183 101 57 48 4 0 14 1 0 8 0 0 8 0 0 +7 1 0 10 9 7 6 4 5 3 4 7 0 0 5 0 0 5 +0 0 4 0 0 2 0 0 2 0 0 0 1 0 0 1 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 +1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 +204 205 200 206 207 201 0 1 0 0 1 0 3 3 1 86 87 84 +204 205 200 208 209 204 204 205 200 209 210 204 205 206 200 164 164 161 +5 5 3 5 5 3 0 0 0 2 2 2 1 1 3 1 1 3 +1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 1 3 +1 1 3 1 1 3 0 0 0 3 3 3 0 0 0 127 127 125 +208 209 204 206 207 202 205 206 201 208 209 204 197 198 192 221 221 215 +193 193 192 214 215 207 197 198 192 201 202 197 211 212 207 214 215 207 +211 211 209 69 70 68 2 2 0 13 14 7 0 0 0 0 0 0 +3 3 5 8 9 10 1 2 4 0 0 2 1 1 1 0 0 0 +1 1 0 2 2 0 0 0 0 126 126 124 206 207 201 205 207 197 +205 207 197 204 205 198 200 201 194 205 206 200 208 209 204 206 207 202 +206 207 202 206 207 202 206 207 202 206 207 202 206 207 201 206 207 201 +206 207 201 206 207 201 207 208 203 175 176 174 1 1 1 5 5 5 +0 0 0 86 87 84 209 209 208 216 217 214 207 208 203 205 206 201 +204 205 200 170 171 167 4 4 2 3 3 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 3 1 1 3 1 1 3 1 1 3 +1 1 3 1 1 3 2 2 2 1 1 1 7 5 3 164 164 161 +209 210 205 209 210 205 204 205 200 209 210 205 203 203 202 86 87 84 +1 1 1 0 0 0 2 2 2 0 0 0 1 2 4 1 1 3 +4 4 4 6 6 6 0 0 0 7 5 3 29 30 27 154 154 152 +209 210 204 204 205 198 197 198 192 221 221 215 199 199 195 207 208 202 +199 199 195 29 30 27 0 0 0 2 2 2 1 1 1 2 2 2 +1 1 1 3 3 3 0 0 0 0 0 0 6 6 6 6 6 6 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 2 0 0 2 0 1 0 0 1 0 0 1 0 0 1 0 +3 0 2 4 1 5 8 1 5 7 2 6 10 10 9 17 6 0 +33 6 2 231 175 56 244 176 40 244 159 4 249 164 6 244 159 4 +249 164 6 249 164 6 244 159 4 244 159 4 249 164 6 233 156 5 +229 155 20 242 158 39 220 161 40 221 134 40 198 136 53 183 98 20 +143 100 31 143 100 31 183 98 20 210 113 41 221 134 40 221 134 40 +230 124 24 227 127 8 227 127 8 240 120 3 243 126 10 239 112 3 +239 112 3 223 116 8 231 145 5 250 166 22 249 178 22 242 169 5 +249 164 6 249 164 6 249 164 6 242 169 5 242 169 5 233 156 5 +233 156 5 246 158 18 229 143 21 242 158 39 222 154 56 198 136 53 +183 98 20 143 100 31 143 100 31 143 100 31 183 101 57 210 113 41 +215 129 57 221 134 40 230 124 24 227 127 8 243 126 10 243 126 10 +240 120 3 240 120 3 239 112 3 241 109 9 241 109 9 232 104 4 +239 111 20 210 113 41 107 69 8 48 4 0 14 1 0 10 1 0 +7 1 0 4 1 3 3 0 2 3 4 7 0 0 5 0 0 5 +0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 207 202 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 +0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 +1 1 1 0 0 0 170 171 167 208 209 204 206 207 202 207 208 202 +211 212 207 206 207 202 6 5 0 0 1 0 3 3 1 82 82 81 +207 208 203 206 207 202 204 205 200 209 210 204 203 204 199 175 176 174 +0 0 0 5 5 3 1 1 1 5 5 5 1 1 3 1 1 3 +1 1 3 1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 1 3 +1 1 3 1 1 3 0 0 0 3 3 3 0 0 0 127 127 125 +208 209 204 206 207 202 205 206 201 208 209 204 213 213 209 200 201 194 +212 213 207 204 205 200 208 209 203 207 208 202 207 208 202 203 204 199 +203 203 202 193 193 192 29 30 27 0 0 0 6 6 6 0 0 0 +8 9 10 0 0 2 1 2 4 0 0 2 1 1 1 0 0 0 +1 1 1 2 2 0 0 0 0 126 126 124 205 206 200 211 212 205 +209 210 202 209 210 204 210 211 205 211 212 207 207 208 203 210 211 206 +207 208 203 207 208 203 207 208 203 207 208 203 207 208 203 207 208 202 +207 208 202 207 208 202 209 209 208 164 164 161 3 3 3 7 7 7 +0 0 0 86 86 84 208 208 206 202 202 199 210 211 206 203 204 199 +202 202 199 186 187 182 0 0 0 4 4 2 3 3 3 0 0 0 +1 1 1 1 1 1 1 1 3 1 1 3 1 1 3 1 1 3 +1 1 3 1 1 1 1 1 1 0 0 0 0 0 0 170 171 167 +208 209 204 207 208 203 201 202 197 212 213 207 208 208 206 82 82 81 +3 3 3 2 2 2 6 6 6 3 3 3 3 4 7 1 2 4 +1 1 1 1 1 1 3 3 1 7 5 3 69 70 68 210 211 205 +205 206 200 211 212 205 208 209 203 205 206 200 210 211 205 208 209 204 +209 210 205 154 154 152 6 6 6 0 0 0 3 3 3 3 3 3 +1 1 1 1 1 1 0 0 0 2 2 2 8 8 8 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +3 0 2 1 0 2 0 0 2 1 1 1 0 3 0 0 3 0 +1 2 0 4 0 1 8 1 5 14 1 4 25 6 3 22 1 2 +170 133 50 231 175 56 242 171 21 249 176 7 249 164 6 249 176 7 +233 156 5 242 171 21 246 158 18 246 158 18 246 158 18 242 158 39 +222 154 56 170 133 50 143 69 23 74 34 6 26 1 0 26 1 0 +33 6 2 26 1 0 30 1 2 35 1 0 74 34 6 143 69 23 +210 113 41 221 134 40 230 124 24 223 116 8 240 120 3 240 120 3 +239 112 3 227 127 8 246 158 18 249 178 22 249 176 7 242 169 5 +244 159 4 249 164 6 242 169 5 244 159 4 249 164 6 233 156 5 +229 155 20 242 158 39 222 154 56 183 98 20 107 69 8 72 12 0 +35 1 0 30 1 2 30 1 2 30 1 2 35 1 0 48 4 0 +74 34 6 143 100 31 198 136 53 221 134 40 223 116 8 239 126 20 +240 120 3 239 112 3 239 112 3 239 112 3 239 112 3 232 104 4 +232 104 4 229 114 40 210 113 41 104 34 7 26 1 0 9 1 3 +7 2 6 8 9 10 3 0 2 6 4 5 1 0 6 0 0 4 +3 0 0 3 0 0 2 1 0 1 1 3 0 0 4 0 0 4 +1 1 3 1 1 1 126 126 124 206 207 202 208 209 204 206 207 201 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 2 +0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 +1 1 1 5 5 5 124 124 124 211 211 209 201 202 197 212 213 207 +214 215 207 204 205 200 82 82 81 5 5 3 9 9 9 0 0 0 +3 4 7 1 2 4 1 1 3 1 1 3 3 4 7 0 0 0 +1 1 1 0 0 0 170 171 167 201 202 197 206 207 202 205 206 201 +213 214 212 207 207 205 1 1 0 6 6 6 0 0 0 29 30 27 +211 212 207 206 207 202 208 209 204 201 202 197 212 213 207 186 187 182 +1 1 0 13 14 7 0 0 0 7 7 7 1 2 4 3 1 7 +3 1 7 0 0 2 0 0 2 6 6 6 6 6 6 4 4 4 +1 1 1 0 0 0 8 8 8 2 2 2 0 0 0 3 3 3 +3 4 7 0 0 2 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 206 207 202 208 209 204 202 202 199 210 211 206 +206 207 202 175 176 174 204 205 200 213 213 209 201 202 197 213 214 212 +206 206 204 206 206 204 164 164 161 10 9 7 0 0 0 10 10 9 +0 0 2 8 9 10 1 2 4 3 3 5 1 1 3 0 0 0 +0 0 0 2 2 2 4 4 4 119 119 117 208 209 203 205 206 200 +213 213 209 207 208 203 207 208 203 205 206 201 211 211 209 204 204 203 +208 208 206 208 208 206 208 208 206 208 208 206 208 208 206 208 209 204 +208 209 204 208 208 206 208 208 206 175 176 174 3 3 3 0 0 0 +10 9 7 65 52 28 211 211 209 197 198 192 207 208 203 205 206 201 +202 202 199 175 176 174 0 0 0 4 4 4 6 6 6 0 0 0 +4 4 2 2 2 0 0 0 0 2 2 2 0 0 0 1 1 1 +6 6 6 0 0 0 4 4 4 2 2 0 2 2 0 175 176 174 +202 202 199 201 202 197 216 217 214 203 204 199 209 209 208 69 70 68 +8 9 10 3 3 5 1 1 3 0 0 2 8 9 10 0 0 2 +1 1 1 0 0 0 4 4 2 29 30 27 186 187 182 203 204 199 +211 212 207 205 206 200 208 209 204 204 204 203 203 203 202 216 217 214 +204 204 203 199 199 198 119 119 117 0 0 0 13 14 7 1 1 0 +7 7 7 2 2 2 0 0 2 8 9 10 1 0 5 3 3 5 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +3 0 2 1 0 2 0 0 2 0 0 0 1 0 0 1 2 0 +0 2 0 1 1 0 8 3 8 14 1 4 18 0 0 107 69 8 +220 161 40 244 176 40 236 169 8 242 169 5 249 176 7 244 159 4 +249 164 6 233 156 5 242 171 21 229 155 20 242 158 39 222 154 56 +107 69 8 74 34 6 18 0 0 14 1 0 10 1 0 7 0 0 +10 1 0 11 1 0 10 1 0 18 1 4 22 1 2 26 1 0 +72 12 0 143 69 23 210 113 41 221 134 40 223 116 8 243 126 10 +222 105 4 247 146 18 244 176 40 236 169 8 249 176 7 249 164 6 +249 164 6 244 159 4 244 159 4 249 176 7 246 158 18 242 158 39 +231 175 56 198 136 53 104 34 7 72 12 0 33 6 2 18 0 0 +14 1 4 8 3 8 9 3 6 8 0 0 17 1 0 25 6 3 +26 1 0 35 1 0 74 34 6 183 98 20 210 113 41 230 124 24 +239 111 20 239 112 3 243 126 10 241 109 9 239 112 3 232 104 4 +232 104 4 222 105 4 216 104 20 143 69 23 48 4 0 10 1 0 +6 4 5 3 0 4 6 4 5 4 1 3 1 0 5 0 0 4 +3 0 0 3 0 0 2 1 0 0 1 3 0 0 4 0 0 4 +1 1 3 1 1 1 126 126 124 206 207 202 208 209 204 206 207 201 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 2 +0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 +2 2 2 0 0 0 124 124 124 204 204 203 207 208 203 206 207 202 +201 202 197 206 207 201 86 87 84 0 0 0 0 0 0 10 10 9 +0 0 2 0 0 2 7 11 16 1 2 4 0 0 2 0 0 2 +0 0 0 2 2 2 164 164 161 213 214 212 209 210 205 211 212 207 +206 206 206 208 208 207 1 1 0 3 3 1 2 2 0 10 10 9 +193 193 192 206 207 202 205 206 201 212 213 207 206 206 204 207 207 205 +0 0 0 0 0 0 10 10 9 0 0 0 8 8 8 1 0 5 +1 0 5 8 8 8 8 8 8 0 0 2 0 0 0 0 0 0 +6 6 6 5 5 5 2 2 2 1 1 1 5 5 5 0 0 0 +0 0 2 9 9 9 0 0 0 3 3 3 0 0 0 127 127 125 +208 208 206 206 206 204 206 207 202 208 209 204 210 211 206 204 205 200 +141 141 139 1 2 0 164 164 161 201 202 197 212 213 207 199 199 195 +204 204 203 204 204 203 203 203 202 119 119 117 4 4 4 4 4 4 +8 9 10 1 2 4 1 1 3 1 2 4 3 3 5 3 3 5 +0 0 0 1 1 1 6 6 6 132 133 128 213 214 212 209 210 204 +208 209 204 204 205 200 208 209 204 175 176 174 164 164 161 170 171 167 +170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 +170 171 167 170 171 167 170 171 167 132 133 128 20 16 18 2 2 2 +0 0 0 10 9 7 199 199 195 216 217 214 210 211 206 209 210 205 +211 211 209 203 203 202 10 10 9 2 2 2 0 0 0 10 10 9 +0 0 0 1 1 0 2 2 2 6 6 6 2 2 2 0 0 0 +3 3 3 0 0 0 0 0 0 7 5 3 3 3 1 193 193 192 +213 213 209 204 205 200 205 206 200 209 210 205 204 204 203 10 10 9 +0 0 2 3 3 5 3 4 7 8 8 8 1 1 3 1 1 3 +1 1 1 8 8 8 1 1 0 132 133 128 207 208 203 212 213 207 +200 201 194 210 211 206 199 199 195 216 217 214 208 208 206 204 204 203 +207 207 205 216 217 214 175 176 174 29 30 27 0 0 0 10 10 9 +1 1 1 4 4 4 0 0 2 2 1 5 0 0 4 3 3 5 +0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 2 1 0 1 3 0 0 5 1 0 5 4 0 2 4 0 0 +0 0 0 0 2 0 1 7 3 10 7 0 26 1 0 170 133 50 +231 175 56 249 178 22 236 169 8 242 171 21 236 169 8 236 169 8 +249 164 6 249 164 6 246 158 18 242 158 39 198 136 53 74 34 6 +48 4 0 17 1 0 10 1 0 15 7 8 15 7 8 6 1 3 +5 1 0 3 1 0 9 3 3 6 0 0 11 1 0 25 6 3 +26 1 0 35 1 0 104 34 7 183 101 57 221 134 40 223 116 8 +227 127 8 244 176 40 249 178 22 236 169 8 250 166 22 249 164 6 +249 164 6 249 178 22 244 159 4 233 156 5 229 155 20 231 175 56 +143 100 31 48 4 0 25 6 3 8 0 0 3 1 0 2 6 0 +2 5 5 0 2 4 0 3 0 0 2 0 3 0 0 8 0 0 +14 1 0 17 6 0 17 1 0 48 4 0 107 69 8 215 129 57 +230 124 24 241 109 9 241 109 9 241 109 9 223 116 8 223 116 8 +241 109 9 241 109 9 230 106 20 210 113 41 104 34 7 26 1 0 +9 1 0 2 0 1 10 9 7 4 1 3 2 0 3 0 0 2 +1 0 0 1 0 0 1 1 1 0 2 1 0 0 2 0 0 2 +1 1 1 1 1 1 126 126 124 206 207 202 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 2 0 0 2 1 1 3 +0 0 2 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 +7 7 7 2 2 2 124 124 124 204 204 203 213 214 212 211 212 207 +203 204 199 214 215 207 119 119 117 4 4 2 4 4 4 2 2 2 +0 0 0 7 7 7 0 0 2 3 3 5 4 4 4 1 1 1 +6 6 6 0 0 0 175 176 174 203 203 202 199 199 195 206 207 202 +209 209 208 209 209 208 3 3 1 2 2 0 0 0 0 0 0 0 +175 176 174 209 210 205 207 208 203 201 202 197 216 217 214 199 199 195 +104 104 103 4 4 2 0 0 0 13 14 7 1 1 3 1 1 3 +0 0 2 0 0 2 1 2 4 4 4 4 8 8 8 8 8 8 +9 9 9 0 0 0 2 2 2 10 10 9 2 2 2 4 4 4 +9 9 9 0 0 0 0 0 0 3 3 1 0 0 0 127 127 125 +208 209 204 206 207 202 206 207 202 208 209 204 205 206 201 154 154 152 +0 1 0 6 5 0 29 30 27 197 198 192 202 202 199 211 211 209 +210 211 206 207 208 203 213 214 212 207 207 205 104 104 103 0 0 0 +10 10 9 0 0 0 1 1 1 1 1 1 1 1 3 3 3 5 +2 2 2 0 0 0 0 0 0 127 127 125 201 202 197 205 206 200 +210 211 205 213 213 209 202 202 199 86 87 84 10 10 9 0 0 0 +1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 +1 1 0 1 1 0 6 6 6 3 4 7 0 0 0 6 6 6 +10 9 7 0 0 0 186 187 182 205 206 201 204 205 200 205 206 201 +205 206 201 206 207 202 69 70 68 10 9 7 3 3 3 2 2 2 +6 6 6 4 4 4 0 0 0 0 0 0 0 0 0 3 3 3 +6 6 6 1 1 1 9 9 9 5 5 3 69 70 68 206 207 202 +211 212 207 206 207 202 203 204 199 207 208 203 186 187 182 4 4 4 +6 6 6 7 7 7 0 0 0 1 1 1 4 4 4 5 5 5 +0 0 0 0 0 0 86 87 84 203 203 202 213 214 212 199 199 195 +208 209 203 206 207 202 211 211 209 175 176 174 211 211 209 199 199 195 +208 208 206 209 209 208 213 214 212 141 141 139 10 10 9 7 7 7 +1 1 1 0 0 0 8 8 8 0 0 2 3 4 7 3 4 7 +0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 2 4 0 2 4 0 0 5 2 0 5 8 1 5 6 1 3 +1 0 0 0 2 0 0 6 1 8 10 3 74 34 6 231 175 56 +244 176 40 242 169 5 236 169 8 242 171 21 236 169 8 249 178 22 +231 145 5 250 166 22 242 158 39 198 136 53 74 34 6 26 1 0 +11 1 0 11 1 0 15 7 8 15 7 8 6 1 3 6 1 3 +7 5 3 6 5 0 4 0 0 7 2 6 8 3 8 8 3 14 +8 1 5 14 1 0 35 1 0 72 12 0 210 113 41 216 104 20 +246 158 18 249 178 22 236 169 8 242 169 5 249 164 6 249 164 6 +249 164 6 244 159 4 249 164 6 244 176 40 220 161 40 170 133 50 +33 6 2 17 1 0 17 6 0 5 5 3 0 6 1 0 6 1 +0 2 1 0 3 0 0 6 1 1 7 3 7 9 5 2 2 0 +6 5 0 20 16 18 14 1 4 14 1 0 48 4 0 107 69 8 +221 134 40 230 124 24 239 111 20 239 111 20 223 116 8 223 116 8 +241 109 9 241 109 9 230 106 20 210 113 41 143 100 31 35 1 0 +11 1 0 6 6 6 7 7 7 5 5 3 2 1 0 0 0 0 +1 0 0 0 0 2 1 1 3 1 1 3 0 0 0 0 0 0 +1 1 1 1 1 1 126 126 126 206 206 204 208 208 206 206 207 202 +208 209 204 207 207 205 86 86 84 2 2 2 0 0 2 1 1 3 +0 0 2 3 4 7 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 +0 0 0 2 2 2 86 87 84 203 204 199 201 202 197 208 209 203 +204 205 200 207 208 202 127 127 125 3 3 1 0 0 0 1 1 1 +6 6 6 1 1 1 1 2 4 7 7 7 0 0 0 0 0 0 +8 8 8 1 1 0 202 202 199 199 199 195 209 210 205 206 207 202 +213 214 212 203 203 202 5 5 3 7 5 3 0 0 0 7 7 7 +141 141 139 209 210 205 203 204 199 213 213 209 197 198 192 221 221 215 +154 154 152 13 14 7 5 5 3 0 0 0 0 0 0 3 3 5 +3 3 5 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 +0 0 0 20 16 18 3 3 3 0 0 0 7 7 7 10 10 9 +1 1 1 1 1 1 0 0 0 3 3 1 0 0 0 127 127 125 +208 209 204 206 207 202 206 207 202 208 209 204 211 212 207 82 82 81 +6 5 0 3 3 1 0 1 0 69 70 68 203 203 202 204 204 203 +208 209 204 211 212 207 202 202 199 211 211 209 197 198 192 69 70 68 +0 0 0 7 7 7 2 2 2 0 0 0 0 0 2 0 0 2 +3 3 3 4 4 4 0 0 0 124 124 124 212 213 207 209 210 204 +204 205 200 205 206 200 203 204 199 82 82 81 0 0 0 3 3 1 +3 3 1 3 3 1 3 3 1 3 3 1 3 3 1 3 3 1 +3 3 1 3 3 3 1 1 3 3 3 5 7 7 7 1 1 1 +1 1 0 3 3 1 164 164 161 208 209 204 210 211 206 209 210 205 +204 205 200 202 202 199 127 127 125 3 3 1 2 2 2 0 0 0 +2 2 2 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 +1 1 1 0 0 0 8 8 8 0 0 0 132 133 128 206 206 204 +206 206 204 208 209 204 213 213 209 209 209 208 154 154 152 4 4 4 +0 0 0 0 0 0 5 5 5 3 3 3 4 4 4 0 0 0 +3 3 3 20 16 18 186 187 182 202 202 199 212 213 207 204 205 200 +211 212 207 203 204 199 141 141 139 82 82 81 206 206 204 211 211 209 +211 211 209 199 199 198 207 208 203 213 213 209 104 104 103 1 1 0 +9 9 9 0 0 0 8 9 10 1 1 3 2 1 5 0 0 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 5 0 1 3 1 1 1 2 0 3 8 1 5 8 1 5 +1 0 2 0 2 0 0 6 1 10 7 0 143 100 31 231 175 56 +242 171 21 242 169 5 242 171 21 242 171 21 242 171 21 242 169 5 +242 169 5 242 171 21 231 175 56 74 34 6 25 6 3 10 7 0 +13 14 7 2 2 0 6 0 0 9 1 3 8 0 0 5 0 0 +3 0 2 3 3 3 7 5 3 6 6 6 3 1 7 2 3 13 +8 3 14 14 1 4 18 0 0 35 1 0 104 34 7 198 136 53 +242 158 39 249 178 22 249 178 22 236 169 8 249 176 7 249 164 6 +249 176 7 244 159 4 236 169 8 231 175 56 198 136 53 26 1 0 +26 16 7 20 16 18 6 0 0 2 1 0 1 1 3 1 2 4 +2 2 0 1 1 0 0 2 4 1 3 4 0 2 4 7 7 7 +7 0 0 7 0 0 6 0 0 15 7 8 18 0 0 35 1 0 +143 69 23 210 113 41 230 124 24 223 116 8 239 111 20 232 104 4 +232 104 4 241 109 9 232 104 4 216 104 20 183 101 57 48 4 0 +18 0 0 8 3 8 0 2 1 2 6 0 0 3 0 1 2 0 +1 0 0 3 0 4 4 1 5 2 0 5 0 0 2 0 0 2 +1 1 3 1 1 1 126 126 126 206 206 204 208 208 206 206 206 204 +208 208 206 207 207 205 86 86 84 2 2 2 0 0 2 1 1 3 +0 0 2 3 4 7 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +5 5 5 9 9 9 69 70 68 216 217 214 205 206 201 213 213 209 +214 215 207 209 210 204 170 171 167 0 0 0 10 9 7 10 10 9 +0 0 0 6 6 6 1 1 1 7 7 7 3 3 3 3 3 3 +1 1 0 65 52 28 209 209 208 210 211 206 216 217 214 201 202 197 +199 199 198 175 176 174 0 0 0 4 4 2 0 0 0 6 6 6 +69 70 68 205 206 201 210 211 206 202 202 199 209 210 205 206 207 202 +199 199 195 65 52 28 6 5 0 4 4 2 9 9 9 3 3 3 +3 3 3 3 3 3 2 2 2 1 1 0 1 1 0 6 6 6 +6 6 6 29 30 27 7 7 7 1 1 0 1 1 0 5 5 3 +2 2 0 6 6 6 0 0 0 3 3 1 0 0 0 127 127 125 +208 209 204 206 207 202 206 207 202 208 209 204 207 208 203 86 86 84 +3 3 1 4 4 2 4 4 2 0 0 0 104 104 103 211 211 209 +199 199 195 208 209 204 202 202 199 204 205 200 204 204 203 175 176 174 +29 30 27 0 0 0 4 4 4 5 5 5 6 6 6 1 1 1 +0 0 0 4 4 4 2 2 2 124 124 124 207 208 202 205 206 200 +206 207 201 209 210 204 211 212 207 86 87 84 2 2 0 3 3 1 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 2 3 3 5 6 6 6 0 0 0 +3 3 1 7 7 7 104 104 103 210 211 206 208 209 204 207 208 203 +210 211 206 212 213 207 186 187 182 29 30 27 0 0 0 20 16 18 +0 0 0 1 1 1 4 4 4 4 4 4 2 2 2 2 2 2 +7 7 7 20 16 18 0 0 0 29 30 27 186 187 182 206 206 204 +209 209 208 202 202 199 203 203 202 209 209 208 119 119 117 2 2 2 +3 3 3 1 1 1 4 4 4 3 3 3 0 0 0 2 2 2 +10 9 7 104 104 103 211 211 209 209 209 208 199 199 195 211 212 207 +203 204 199 201 202 197 29 30 27 10 10 9 141 141 139 216 217 214 +199 199 195 211 212 207 202 202 199 206 207 202 193 193 192 29 30 27 +0 0 0 2 2 2 1 1 3 3 4 7 0 0 2 1 1 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 0 5 1 1 3 1 1 1 2 0 1 4 1 5 4 1 5 +3 0 4 0 0 0 4 8 7 10 7 0 198 136 53 231 175 56 +242 171 21 249 176 7 242 171 21 242 171 21 249 178 22 233 156 5 +250 166 22 229 155 20 107 69 8 48 4 0 17 6 0 13 14 7 +6 5 0 3 1 0 8 0 0 15 7 8 14 1 0 7 1 0 +2 0 3 1 1 3 1 0 0 1 1 1 2 3 13 7 11 16 +8 3 14 4 0 2 8 0 0 25 6 3 35 1 0 143 100 31 +231 175 56 249 178 22 249 176 7 242 169 5 242 169 5 242 169 5 +249 176 7 236 169 8 242 171 21 222 154 56 74 34 6 25 6 3 +8 3 8 3 1 7 9 3 6 9 3 6 8 3 8 8 3 8 +9 3 6 5 1 0 1 0 0 0 0 2 3 3 5 5 3 3 +8 0 0 17 1 0 14 1 0 17 1 0 17 1 0 35 1 0 +72 12 0 183 98 20 217 124 25 223 116 8 241 109 9 232 104 4 +241 109 9 232 104 4 230 106 20 216 104 20 183 101 57 48 4 0 +26 1 0 8 1 5 0 1 0 0 6 1 0 3 0 1 2 0 +3 0 0 3 0 4 3 1 7 4 1 5 0 0 4 0 1 2 +0 1 3 1 1 1 126 126 126 206 206 204 208 208 206 206 206 204 +208 208 206 207 207 205 86 86 84 2 2 2 0 0 2 1 1 3 +0 0 2 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 2 2 0 0 0 20 16 18 202 202 199 207 208 203 203 204 199 +204 205 200 201 202 197 213 214 212 69 70 68 0 0 0 0 0 0 +0 0 0 10 10 9 0 0 0 2 2 2 10 10 9 0 0 0 +2 2 0 132 133 128 206 207 202 212 213 207 202 202 199 206 207 202 +204 204 203 154 154 152 0 0 0 0 0 0 3 3 1 0 0 0 +8 10 3 186 187 182 207 208 203 210 211 206 199 199 195 211 212 207 +207 208 203 175 176 174 6 5 0 0 1 0 0 0 0 1 1 1 +8 8 8 0 0 0 0 0 0 7 7 7 1 1 0 0 0 0 +0 0 0 154 154 152 170 171 167 82 82 81 3 3 1 0 0 0 +1 1 0 2 2 0 0 0 0 3 3 1 0 0 0 127 127 125 +208 209 204 206 207 202 206 207 202 208 209 204 208 209 204 86 86 84 +0 0 0 3 3 1 10 9 7 0 0 0 10 10 9 154 154 152 +211 212 207 208 209 204 207 208 203 211 212 207 202 202 199 213 214 212 +141 141 139 10 9 7 0 0 0 0 0 0 8 8 8 5 5 5 +0 0 0 0 0 0 0 0 0 126 126 124 207 208 202 205 207 197 +209 210 204 206 207 201 208 209 204 86 87 84 4 4 2 0 0 0 +2 2 0 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 +2 2 2 2 2 2 8 9 10 3 4 7 3 3 3 1 1 1 +5 5 3 1 1 0 29 30 27 207 208 203 205 206 201 204 205 200 +208 209 204 209 210 205 205 206 201 126 126 124 20 16 18 0 0 0 +1 1 1 4 4 4 4 4 4 0 0 0 1 1 1 6 6 6 +2 2 2 0 0 0 7 7 7 132 133 128 204 204 203 206 206 206 +211 211 209 208 208 206 208 208 206 209 209 208 29 30 27 0 0 0 +7 7 7 3 3 3 1 1 1 9 9 9 7 7 7 0 0 0 +69 70 68 204 204 203 206 206 204 216 217 214 197 198 192 207 208 203 +210 211 206 119 119 117 0 0 0 2 2 0 29 30 27 193 193 192 +201 202 197 213 214 212 209 210 205 206 207 202 213 214 212 141 141 139 +9 9 9 0 0 0 0 0 2 3 3 5 3 4 7 6 6 6 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 1 5 4 1 3 2 1 0 2 1 0 3 0 4 3 0 4 +3 0 2 3 0 4 8 3 14 17 1 0 170 133 50 231 175 56 +242 171 21 249 176 7 249 176 7 242 169 5 242 169 5 249 176 7 +244 159 4 242 158 39 183 98 20 104 34 7 72 12 0 30 1 2 +26 1 0 22 1 2 18 1 4 11 1 0 7 0 0 7 1 0 +9 4 5 9 4 5 10 9 7 2 2 2 0 0 5 0 2 6 +3 4 7 5 5 5 5 3 3 8 0 0 18 0 0 48 4 0 +231 175 56 244 176 40 242 169 5 249 176 7 242 169 5 236 169 8 +244 159 4 229 155 20 231 175 56 170 133 50 22 1 2 17 6 0 +6 1 3 4 1 5 8 1 5 8 1 5 2 0 5 2 0 5 +7 2 6 6 1 3 5 1 0 6 5 0 1 0 0 7 1 0 +14 1 0 17 1 0 22 1 2 33 6 2 48 4 0 72 12 0 +107 69 8 183 98 20 223 116 8 232 104 4 241 109 9 239 103 3 +239 103 3 232 104 4 230 106 20 210 113 41 183 101 57 48 4 0 +30 1 2 8 1 5 0 2 2 0 6 1 0 3 0 1 2 0 +4 0 0 4 1 5 3 1 7 3 1 7 0 0 4 0 1 2 +0 2 1 1 1 1 126 126 126 206 206 204 208 208 206 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +6 6 6 0 0 0 5 5 3 164 164 161 216 217 214 206 207 202 +207 208 202 209 210 204 201 202 197 164 164 161 20 16 18 3 3 1 +13 14 7 0 0 0 20 16 18 0 0 0 1 1 0 13 14 7 +69 70 68 193 193 192 207 208 203 207 208 203 203 204 199 216 217 214 +213 214 212 104 104 103 6 6 6 1 1 1 5 5 3 2 2 0 +0 1 0 119 119 117 201 202 197 213 214 212 210 211 206 201 202 197 +209 210 204 212 213 207 132 133 128 8 10 3 4 4 2 0 0 0 +10 10 9 4 4 2 0 0 0 3 3 1 0 1 0 13 14 7 +119 119 117 203 204 199 201 202 197 209 210 205 199 199 195 104 104 103 +4 4 2 1 1 0 0 0 0 3 3 1 0 1 0 127 127 125 +208 209 204 206 207 202 206 207 202 208 209 204 211 212 207 86 87 84 +20 16 18 1 1 0 0 0 0 8 8 8 0 0 0 29 30 27 +175 176 174 209 210 204 205 206 201 210 211 206 210 211 206 201 202 197 +221 221 215 104 104 103 20 16 18 0 0 0 0 0 0 5 5 5 +1 1 1 1 1 1 2 2 2 132 133 128 209 210 204 209 210 202 +214 215 207 207 208 202 209 210 205 86 87 84 7 5 3 0 0 0 +2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +2 2 2 2 2 2 1 2 4 0 0 2 3 3 3 2 2 2 +6 6 6 0 0 0 6 6 6 141 141 139 212 213 207 211 212 207 +208 209 204 203 204 199 207 208 203 199 199 195 104 104 103 13 14 7 +3 3 1 0 0 0 1 1 0 3 3 1 5 5 3 2 2 0 +0 0 0 6 6 6 104 104 103 199 199 198 211 211 209 204 204 203 +208 208 206 207 207 205 209 209 208 141 141 139 2 2 2 3 3 3 +0 0 0 0 0 0 4 4 2 10 9 7 0 0 0 10 10 9 +170 171 167 221 221 215 201 202 197 203 204 199 211 212 207 212 213 207 +175 176 174 13 14 7 7 7 7 3 3 1 0 0 0 119 119 117 +206 207 202 212 213 207 206 207 202 209 210 205 204 205 200 216 217 214 +104 104 103 7 7 7 3 3 3 0 0 0 3 4 7 0 0 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 1 3 4 0 1 2 1 0 2 1 0 4 0 2 4 0 2 +3 0 2 3 0 4 3 1 7 17 1 0 107 69 8 231 175 56 +242 171 21 242 169 5 242 169 5 236 169 8 249 176 7 242 169 5 +249 164 6 229 155 20 242 158 39 222 154 56 222 154 56 170 133 50 +143 100 31 104 34 7 48 4 0 35 1 0 26 1 0 18 0 0 +11 1 0 14 1 0 8 0 0 5 1 0 1 7 3 0 6 1 +0 1 0 2 2 0 6 6 6 7 2 6 15 7 8 22 1 2 +170 133 50 231 175 56 244 176 40 236 169 8 242 171 21 242 171 21 +242 171 21 244 176 40 222 154 56 74 34 6 17 6 0 4 0 1 +7 5 3 3 0 2 3 0 2 8 3 8 8 1 5 6 1 3 +14 1 4 14 1 0 11 1 0 17 1 0 25 6 3 26 1 0 +33 6 2 74 34 6 107 69 8 143 100 31 198 136 53 222 154 56 +222 154 56 242 158 39 227 127 8 239 112 3 243 126 10 239 103 3 +241 109 9 239 111 20 230 106 20 210 113 41 183 101 57 48 4 0 +26 1 0 14 1 4 3 3 3 0 3 0 0 3 0 1 2 0 +4 0 1 4 1 5 3 1 7 1 0 6 0 0 2 0 1 0 +1 1 1 1 1 0 126 126 124 206 207 202 208 209 204 206 207 202 +208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 +0 0 0 4 4 2 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 2 2 0 0 0 0 0 0 119 119 117 213 213 209 207 208 203 +208 209 203 209 210 204 207 208 203 216 217 214 141 141 139 29 30 27 +1 1 0 10 10 9 0 0 0 4 4 2 4 4 2 69 70 68 +193 193 192 213 214 212 207 208 203 201 202 197 211 212 207 201 202 197 +199 199 198 29 30 27 2 2 2 3 3 3 0 0 0 4 4 2 +2 2 0 2 2 0 197 198 192 204 205 200 206 207 202 205 206 201 +213 213 209 197 198 192 210 211 205 164 164 161 69 70 68 2 2 0 +0 0 0 5 5 3 1 2 0 2 2 0 29 30 27 124 124 124 +206 207 202 216 217 214 203 204 199 213 214 212 202 202 199 211 211 209 +132 133 128 2 2 0 0 0 0 3 3 1 0 1 0 127 127 125 +208 209 204 206 207 202 206 207 202 208 209 204 206 207 202 86 87 84 +1 1 0 7 7 7 5 5 5 2 2 2 6 6 6 0 0 0 +69 70 68 193 193 192 204 205 200 208 209 204 201 202 197 210 211 206 +203 203 202 199 199 198 69 70 68 13 14 7 0 0 0 4 4 4 +2 2 2 1 1 1 0 0 0 126 126 124 203 204 199 204 205 198 +210 211 205 203 204 199 208 209 204 82 82 81 4 4 2 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 2 1 2 4 7 7 7 1 1 1 +2 2 0 0 0 0 3 3 1 69 70 68 203 204 199 204 205 200 +208 209 204 208 209 204 209 210 205 213 213 209 210 211 206 126 126 124 +29 30 27 3 3 1 0 0 0 6 6 6 2 2 0 0 0 0 +29 30 27 119 119 117 209 209 208 207 207 205 207 207 205 202 202 199 +208 208 206 204 204 203 204 204 203 69 70 68 2 2 2 1 1 1 +3 3 3 2 2 2 2 2 0 0 0 0 4 4 2 124 124 124 +213 214 212 197 198 192 213 213 209 201 202 197 213 214 212 204 205 200 +86 87 84 0 1 0 2 2 0 0 0 0 10 10 9 1 1 0 +170 171 167 210 211 206 205 206 201 206 207 202 205 206 201 199 199 195 +202 202 199 29 30 27 2 2 2 0 0 0 3 3 5 1 1 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 0 0 4 0 0 1 1 0 2 0 1 5 0 0 7 0 0 +4 0 0 2 0 1 8 3 14 17 6 0 33 6 2 222 154 56 +244 176 40 249 176 7 236 169 8 236 169 8 249 176 7 249 164 6 +244 159 4 233 156 5 247 146 18 246 158 18 242 158 39 242 158 39 +222 154 56 222 154 56 222 154 56 170 133 50 143 100 31 107 69 8 +74 34 6 26 1 0 25 6 3 11 1 0 6 5 0 0 6 1 +8 10 3 10 7 0 4 0 0 6 1 3 8 3 8 11 1 0 +74 34 6 222 154 56 231 175 56 225 170 23 242 171 21 242 171 21 +225 170 23 231 175 56 143 100 31 26 1 0 14 1 0 6 1 3 +7 1 0 1 1 0 0 3 0 0 3 0 7 5 3 10 1 0 +18 0 0 26 1 0 35 1 0 74 34 6 107 69 8 143 100 31 +198 136 53 222 154 56 222 154 56 222 154 56 242 158 39 242 158 39 +246 158 18 247 146 18 241 129 3 239 112 3 239 112 3 239 112 3 +241 109 9 230 106 20 216 104 20 210 113 41 143 100 31 33 6 2 +14 1 0 15 7 8 1 0 0 1 1 1 1 1 0 2 1 0 +4 0 1 2 0 3 0 2 6 0 2 6 0 2 0 1 2 0 +0 0 0 6 6 6 124 124 124 206 207 202 210 211 206 207 208 202 +210 211 205 201 202 197 170 171 167 170 171 167 170 171 167 170 171 167 +170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 +164 164 161 175 176 174 164 164 161 170 171 167 69 70 68 2 2 2 +2 2 2 2 2 2 0 0 0 0 0 0 197 198 192 203 204 199 +208 209 203 208 209 203 203 204 199 205 206 201 210 211 206 193 193 192 +154 154 152 119 119 117 119 119 117 119 119 117 170 171 167 204 204 203 +209 209 208 204 204 203 207 208 203 204 205 200 207 208 203 208 209 204 +119 119 117 20 16 18 0 0 0 6 6 6 0 0 0 5 5 3 +0 0 0 4 4 2 86 86 84 203 203 202 213 214 212 207 208 203 +205 206 200 203 204 199 213 213 209 201 202 197 209 209 208 154 154 152 +127 127 125 124 124 124 124 124 124 141 141 139 186 187 182 212 213 207 +207 208 203 211 212 207 206 207 202 201 202 197 209 209 208 193 193 192 +69 70 68 0 0 0 5 5 3 2 2 0 0 0 0 124 124 124 +209 209 208 211 211 209 209 209 208 208 208 206 207 207 205 86 87 84 +5 5 3 0 0 0 2 2 2 0 0 0 3 3 3 0 0 0 +0 1 0 104 104 103 204 205 200 211 212 207 201 202 197 209 210 205 +202 202 199 206 206 204 186 187 182 29 30 27 0 0 0 1 1 1 +6 6 6 0 0 0 8 8 8 124 124 124 208 209 204 206 207 201 +212 213 207 207 208 202 205 206 201 82 82 81 5 5 3 0 0 0 +0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +0 0 2 0 0 2 0 0 2 0 0 2 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 127 127 125 204 204 203 +203 204 199 206 207 202 213 214 212 201 202 197 213 213 209 204 205 200 +199 199 195 154 154 152 126 126 124 119 119 117 119 119 117 154 154 152 +193 193 192 212 213 207 206 207 202 208 209 204 204 205 200 208 209 204 +210 211 206 199 199 195 132 133 128 0 0 0 6 6 6 3 3 3 +4 4 4 0 0 0 13 14 7 5 5 3 69 70 68 199 199 195 +210 211 206 212 213 207 203 204 199 213 213 209 199 199 198 164 164 161 +3 3 1 3 3 1 7 5 3 1 1 0 2 2 0 10 9 7 +69 70 68 210 211 206 206 207 202 210 211 206 206 207 202 201 202 197 +216 217 214 154 154 152 3 3 3 4 4 4 3 4 7 1 2 4 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 1 0 1 2 0 1 1 0 1 1 0 5 0 0 5 0 0 +2 1 0 1 1 0 5 7 10 4 0 0 25 6 3 143 69 23 +222 154 56 242 171 21 249 178 22 236 169 8 242 169 5 249 164 6 +244 159 4 244 159 4 246 147 4 231 145 5 231 145 5 231 145 5 +231 145 5 229 155 20 246 158 18 229 155 20 220 161 40 222 154 56 +198 136 53 170 133 50 143 100 31 74 34 6 17 1 0 26 16 7 +7 1 0 10 1 0 10 1 0 9 4 5 2 0 5 26 16 7 +18 0 0 74 34 6 170 133 50 231 175 56 231 175 56 231 175 56 +231 175 56 143 100 31 33 6 2 11 1 0 6 0 0 7 2 6 +7 7 7 1 0 0 8 10 3 5 1 0 14 1 0 33 6 2 +74 34 6 143 100 31 198 136 53 222 154 56 222 154 56 220 161 40 +229 155 20 229 155 20 247 146 18 246 158 18 246 158 18 231 145 5 +244 159 4 244 159 4 247 146 18 246 147 4 240 120 3 232 104 4 +222 105 4 216 104 20 210 113 41 198 136 53 72 12 0 11 1 0 +11 1 0 5 1 0 9 4 5 3 0 2 2 0 3 2 0 3 +4 0 1 2 0 3 0 2 6 0 2 6 1 2 0 2 1 0 +6 5 0 4 4 2 126 126 124 204 205 200 206 207 201 205 206 200 +211 212 207 209 210 204 206 207 202 206 207 202 206 206 204 206 206 204 +206 207 202 206 207 202 206 207 201 206 207 201 208 209 204 204 205 200 +199 199 198 211 211 209 209 209 208 211 211 209 86 87 84 5 5 5 +8 8 8 0 0 0 6 6 6 5 5 3 86 87 84 210 211 206 +213 214 212 193 193 192 213 214 212 209 210 205 207 208 203 207 208 203 +205 206 201 207 208 203 209 209 208 209 209 208 213 214 212 199 199 198 +204 204 203 206 206 204 204 205 200 213 214 212 210 211 206 193 193 192 +29 30 27 0 0 0 2 2 2 5 5 5 0 0 0 7 7 7 +1 1 0 0 0 0 0 0 0 119 119 117 203 204 199 208 209 204 +201 202 197 211 212 207 197 198 192 211 212 207 209 209 208 199 199 198 +204 204 203 211 211 209 206 207 202 210 211 206 213 214 212 208 209 204 +203 204 199 213 213 209 207 208 203 213 214 212 199 199 198 119 119 117 +0 0 0 20 16 18 0 0 0 3 3 1 3 3 1 124 124 124 +203 203 202 202 202 199 206 206 204 207 207 205 209 209 208 82 82 81 +1 1 0 0 0 0 4 4 4 4 4 4 8 8 8 2 2 2 +13 14 7 0 1 0 141 141 139 201 202 197 216 217 214 203 204 199 +202 202 199 209 209 208 209 209 208 154 154 152 5 5 5 5 5 5 +2 2 2 9 9 9 0 0 0 132 133 128 204 205 200 203 204 199 +207 208 202 205 206 200 206 207 202 82 82 81 2 2 0 0 0 0 +0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +0 0 2 0 0 2 0 0 2 0 0 2 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 170 171 167 +213 213 209 197 198 192 203 204 199 202 202 199 212 213 207 209 210 205 +206 207 202 199 199 195 202 202 199 211 212 207 210 211 206 209 210 205 +209 210 205 206 207 202 209 210 205 213 214 212 209 210 205 202 202 199 +205 206 201 186 187 182 0 1 0 7 5 3 0 0 0 0 0 0 +5 5 5 4 4 4 0 0 0 7 5 3 154 154 152 207 208 203 +204 205 200 205 206 201 209 210 205 209 210 205 202 202 199 69 70 68 +0 0 0 3 3 1 0 0 0 0 0 0 1 1 0 0 0 0 +13 14 7 119 119 117 216 217 214 199 199 195 210 211 206 213 214 212 +199 199 195 209 209 208 104 104 103 0 0 0 7 11 16 0 0 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 3 0 0 2 0 0 2 0 1 1 0 2 0 1 2 0 1 +1 1 0 0 2 0 3 3 3 7 7 7 10 1 0 26 1 0 +198 136 53 222 154 56 242 158 39 229 155 20 233 156 5 233 156 5 +233 156 5 233 156 5 244 159 4 244 159 4 246 158 18 229 155 20 +246 158 18 233 156 5 244 159 4 244 159 4 246 158 18 242 158 39 +220 161 40 220 161 40 222 154 56 198 136 53 170 133 50 74 34 6 +17 1 0 14 1 0 7 1 0 2 0 3 5 7 10 3 0 4 +17 6 0 25 6 3 33 6 2 107 69 8 143 100 31 107 69 8 +74 34 6 33 6 2 11 1 0 13 14 7 3 1 7 8 9 10 +1 0 0 10 1 0 14 1 0 33 6 2 107 69 8 170 133 50 +222 154 56 220 161 40 229 143 21 242 158 39 229 155 20 229 155 20 +246 158 18 246 158 18 244 159 4 244 159 4 244 159 4 244 159 4 +233 156 5 233 156 5 246 158 18 246 158 18 246 147 4 241 129 3 +239 126 20 221 134 40 222 154 56 143 69 23 25 6 3 10 7 0 +10 7 0 4 0 0 6 4 5 7 2 6 2 0 5 4 1 3 +5 0 0 4 0 1 0 2 6 0 2 6 1 1 0 2 1 0 +1 2 0 0 0 0 127 127 125 209 210 205 206 207 201 203 204 199 +205 206 200 206 207 201 207 208 203 207 208 203 207 208 203 207 208 203 +207 208 203 207 208 203 207 208 202 207 208 202 213 213 209 207 208 203 +206 206 204 206 206 204 203 203 202 208 208 206 82 82 81 0 0 0 +3 3 3 2 2 2 0 0 0 3 3 1 6 6 6 126 126 124 +202 202 199 216 217 214 201 202 197 208 209 204 208 209 204 205 206 201 +207 208 203 207 208 203 204 204 203 207 207 205 199 199 195 216 217 214 +213 214 212 203 203 202 193 193 192 211 211 209 186 187 182 69 70 68 +0 0 0 0 0 0 7 7 7 1 1 1 0 0 0 5 5 5 +0 0 0 1 1 1 5 5 3 20 16 18 119 119 117 216 217 214 +213 213 209 206 207 202 204 205 200 211 212 207 202 202 199 206 206 204 +211 211 209 209 209 208 205 206 201 205 206 201 206 207 202 202 202 199 +207 208 203 209 210 205 207 207 205 211 211 209 104 104 103 20 16 18 +9 9 9 0 0 0 3 3 3 6 6 6 4 4 2 127 127 125 +208 208 206 206 206 204 213 214 212 213 214 212 209 209 208 82 82 81 +5 5 3 3 3 1 0 0 0 0 0 0 4 4 4 1 1 1 +3 3 1 5 5 3 0 0 0 175 176 174 204 204 203 213 214 212 +204 204 203 209 209 208 208 208 206 207 207 205 124 124 124 0 0 0 +1 1 1 2 2 2 8 8 8 119 119 117 209 210 205 210 211 205 +208 209 204 208 209 204 209 209 208 86 86 84 0 0 0 2 2 2 +0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 +0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 29 30 27 +170 171 167 221 221 215 209 209 208 209 209 208 199 199 198 204 205 200 +211 212 207 211 212 207 209 210 204 206 207 201 203 204 199 201 202 197 +204 205 200 207 208 202 205 206 201 206 207 202 211 212 207 211 212 207 +175 176 174 29 30 27 5 5 3 1 1 0 5 5 5 0 0 2 +0 0 0 8 8 8 6 6 6 119 119 117 216 217 214 207 208 203 +210 211 206 205 206 201 209 210 205 216 217 214 119 119 117 0 0 0 +7 7 7 7 7 7 2 2 2 2 2 2 7 5 3 3 3 1 +0 0 0 29 30 27 186 187 182 209 210 205 208 209 204 202 202 199 +213 214 212 199 199 195 206 206 206 29 30 27 0 0 2 8 9 10 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 3 0 0 3 0 0 2 0 1 1 0 1 1 1 0 2 1 +0 2 0 0 2 0 2 2 0 1 1 0 10 10 9 17 1 0 +72 12 0 222 154 56 222 154 56 229 155 20 229 155 20 233 156 5 +233 156 5 244 159 4 244 159 4 244 159 4 246 158 18 246 158 18 +244 159 4 244 159 4 244 159 4 244 159 4 244 159 4 246 158 18 +246 158 18 229 155 20 229 155 20 244 176 40 222 154 56 198 136 53 +74 34 6 33 6 2 14 1 0 7 1 0 2 3 8 3 1 7 +8 3 8 7 1 0 7 1 0 11 1 0 18 0 0 33 6 2 +18 0 0 7 0 0 10 9 7 0 1 0 0 2 6 3 3 5 +9 3 3 25 6 3 33 6 2 143 100 31 222 154 56 220 161 40 +229 155 20 242 171 21 244 159 4 246 147 4 244 159 4 244 159 4 +244 159 4 244 159 4 246 147 4 246 147 4 244 159 4 244 159 4 +242 171 21 233 156 5 233 156 5 246 158 18 246 158 18 242 158 39 +231 175 56 222 154 56 143 100 31 30 1 2 17 6 0 9 9 9 +4 1 3 4 1 3 1 0 2 7 7 7 2 0 5 2 0 3 +4 0 0 3 0 0 0 0 5 0 2 6 1 1 0 1 2 0 +10 9 7 4 4 2 132 133 128 210 211 206 209 210 205 207 208 202 +207 208 202 212 213 207 207 208 203 207 208 203 207 208 203 207 208 203 +207 208 203 207 208 203 207 208 203 207 208 202 206 207 202 203 204 199 +209 209 208 207 207 205 204 204 203 209 209 208 86 86 84 3 3 3 +1 1 1 4 4 4 1 1 1 0 0 0 0 0 0 20 16 18 +119 119 117 201 202 197 208 209 204 216 217 214 208 209 204 199 199 195 +209 210 205 213 213 209 207 207 205 208 208 206 221 221 215 199 199 195 +207 207 205 213 214 212 213 214 212 186 187 182 82 82 81 0 0 0 +7 7 7 6 6 6 3 3 3 0 0 0 1 1 1 2 2 2 +0 0 0 4 4 4 10 9 7 0 0 0 10 9 7 104 104 103 +186 187 182 208 209 204 204 205 200 204 205 200 207 207 205 208 208 206 +207 207 205 206 206 204 206 207 202 205 206 201 207 208 203 213 214 212 +209 210 205 209 210 205 186 187 182 119 119 117 13 14 7 0 0 0 +4 4 4 10 10 9 5 5 5 0 0 0 0 0 0 126 126 124 +211 211 209 204 204 203 209 209 208 202 202 199 208 208 206 82 82 81 +4 4 2 2 2 0 2 2 2 1 1 1 6 6 6 0 0 0 +2 2 0 3 3 1 6 6 6 65 52 28 203 203 202 204 204 203 +216 217 214 199 199 198 202 202 199 207 207 205 216 217 214 86 86 84 +4 4 4 0 0 0 8 8 8 127 127 125 203 204 199 206 207 201 +203 204 199 204 205 200 207 207 205 86 87 84 1 1 1 4 4 4 +0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 +0 0 0 0 0 0 0 0 0 0 0 0 10 10 9 0 0 0 +29 30 27 141 141 139 199 199 195 203 203 202 213 214 212 202 202 199 +201 202 197 211 212 207 210 211 205 206 207 201 210 211 205 209 210 204 +207 208 202 210 211 205 213 214 212 202 202 199 197 198 192 154 154 152 +29 30 27 10 10 9 0 0 0 0 0 0 6 6 6 1 2 4 +2 2 2 0 0 0 69 70 68 202 202 199 199 199 195 208 209 204 +204 205 200 206 207 202 213 214 212 175 176 174 20 16 18 0 0 0 +5 5 5 0 0 0 5 5 5 1 1 1 2 2 2 4 4 2 +3 3 1 2 2 0 82 82 81 209 210 205 207 208 203 206 207 202 +213 214 212 204 204 203 206 206 206 154 154 152 3 4 7 6 6 6 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 3 0 0 2 0 1 1 0 1 1 0 0 2 1 0 2 4 +0 2 1 0 2 1 7 1 0 3 0 0 8 8 8 9 1 0 +22 1 2 74 34 6 198 136 53 222 154 56 242 158 39 246 158 18 +233 156 5 233 156 5 244 159 4 244 159 4 246 147 4 233 156 5 +244 159 4 233 156 5 233 156 5 244 159 4 244 159 4 244 159 4 +244 159 4 244 159 4 244 159 4 231 145 5 242 158 39 231 175 56 +222 154 56 74 34 6 18 0 0 11 1 0 5 5 5 3 4 7 +0 0 0 6 5 0 20 16 18 13 14 7 10 1 0 17 6 0 +7 1 0 8 8 8 4 4 4 7 7 7 7 9 5 1 1 0 +17 6 0 30 1 2 143 100 31 221 134 40 242 158 39 242 171 21 +236 169 8 233 156 5 233 156 5 244 159 4 244 159 4 244 159 4 +233 156 5 244 159 4 249 164 6 249 164 6 244 159 4 233 156 5 +229 155 20 229 155 20 233 156 5 246 158 18 246 158 18 242 158 39 +198 136 53 143 100 31 48 4 0 17 1 0 4 0 2 2 3 8 +2 0 5 8 3 8 5 7 10 0 1 3 0 1 3 2 0 1 +4 0 0 4 0 0 0 0 5 0 0 5 0 0 2 1 1 1 +0 0 0 3 3 3 124 124 124 199 199 195 209 210 205 209 210 205 +204 205 200 205 206 201 208 208 206 208 208 206 208 208 206 208 208 206 +208 208 206 208 209 204 208 209 204 208 209 204 208 209 204 203 204 199 +209 209 208 211 211 209 213 214 212 208 208 207 86 86 84 0 0 0 +3 4 7 0 0 2 10 10 9 0 0 0 10 10 9 0 0 0 +10 10 9 86 87 84 170 171 167 201 202 197 209 210 205 205 206 201 +209 209 208 206 206 204 199 199 198 203 203 202 202 202 199 211 211 209 +207 207 205 199 199 195 132 133 128 29 30 27 2 2 2 3 3 3 +3 3 3 1 1 1 0 0 0 1 1 1 6 6 6 3 3 3 +0 0 0 0 0 0 4 4 4 4 4 4 5 5 5 0 0 0 +29 30 27 141 141 139 208 208 206 211 211 209 206 206 206 209 209 208 +206 206 204 204 204 203 209 209 208 209 209 208 204 204 203 206 206 204 +211 211 209 164 164 161 69 70 68 0 0 0 0 0 0 7 7 7 +8 8 8 0 0 2 3 3 3 0 0 0 7 7 7 127 127 125 +209 209 208 206 206 206 207 207 205 204 204 203 207 207 205 86 87 84 +6 6 6 0 0 0 1 1 1 5 5 5 9 9 9 0 0 0 +3 3 3 0 0 0 10 10 9 0 0 0 86 87 84 208 208 207 +203 203 202 211 211 209 211 211 209 206 206 204 208 208 206 193 193 192 +69 70 68 0 0 0 0 0 0 132 133 128 204 205 200 211 212 207 +209 210 205 208 209 204 202 202 199 86 87 84 5 5 5 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +0 0 2 0 0 2 0 0 0 0 0 0 0 0 0 5 5 5 +6 6 6 2 2 2 86 86 84 193 193 192 204 204 203 208 208 206 +201 202 197 209 210 205 206 207 202 202 202 199 210 211 206 211 212 207 +204 205 200 204 205 200 197 198 192 186 187 182 86 87 84 5 5 3 +0 0 0 2 2 2 4 4 4 20 16 18 1 1 3 6 6 6 +5 5 5 10 10 9 164 164 161 207 207 205 206 207 202 213 213 209 +206 207 202 211 212 207 208 208 206 82 82 81 0 0 0 2 2 2 +0 0 2 1 1 3 6 6 6 0 0 0 0 0 0 3 3 3 +5 5 3 2 2 0 7 7 7 154 154 152 208 208 206 203 203 202 +199 199 195 216 217 214 199 199 195 213 214 212 104 104 103 0 0 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 2 1 0 2 1 2 0 1 2 0 1 0 2 1 0 2 1 +0 1 3 1 1 1 9 4 5 5 0 0 3 0 0 4 1 3 +15 7 8 14 1 0 48 4 0 143 100 31 222 154 56 222 154 56 +220 161 40 229 155 20 242 158 39 246 158 18 246 158 18 250 166 22 +244 159 4 244 159 4 244 159 4 246 158 18 244 159 4 244 159 4 +249 164 6 249 164 6 244 159 4 246 158 18 246 158 18 229 143 21 +220 161 40 222 154 56 74 34 6 22 1 2 6 5 0 3 3 5 +7 5 3 7 5 3 0 0 0 1 0 0 15 7 8 4 0 0 +1 0 2 8 9 10 1 2 4 0 3 0 2 2 0 26 16 7 +26 1 0 143 69 23 222 154 56 242 171 21 246 158 18 244 159 4 +233 156 5 233 156 5 249 164 6 244 159 4 244 159 4 244 159 4 +246 158 18 246 158 18 249 164 6 249 164 6 246 158 18 229 155 20 +220 161 40 220 161 40 242 158 39 231 175 56 222 154 56 198 136 53 +107 69 8 26 1 0 11 1 0 20 16 18 8 3 8 8 3 14 +3 1 7 2 3 8 5 7 10 0 2 4 0 2 1 1 0 0 +4 0 0 3 0 2 0 0 5 0 0 5 0 0 2 0 0 0 +7 7 7 8 9 10 82 82 81 124 124 124 132 133 128 127 127 125 +126 126 124 126 126 124 126 126 124 126 126 124 126 126 124 126 126 124 +126 126 124 126 126 124 126 126 124 126 126 124 132 133 128 126 126 124 +127 127 125 126 126 124 124 124 124 126 126 126 69 70 68 5 5 5 +1 1 3 0 0 2 3 3 3 2 2 2 4 4 4 7 5 3 +0 0 0 4 4 2 3 3 1 69 70 68 132 133 128 175 176 174 +202 202 199 206 206 204 204 204 203 211 211 209 186 187 182 164 164 161 +119 119 117 29 30 27 1 1 0 4 4 2 0 0 0 9 9 9 +0 0 0 3 3 3 3 3 3 1 1 1 1 1 1 3 3 3 +4 4 4 0 0 0 0 0 0 2 2 2 2 2 2 0 0 0 +7 7 7 10 10 9 29 30 27 124 124 124 164 164 161 186 187 182 +204 204 203 211 211 209 209 209 208 193 193 192 164 164 161 127 127 125 +65 52 28 3 3 1 3 3 3 1 1 1 4 4 4 20 16 18 +0 0 2 8 9 10 3 3 3 0 0 0 7 7 7 82 82 81 +127 127 125 124 124 124 124 124 124 132 133 128 119 119 117 69 70 68 +7 7 7 2 2 0 0 0 0 0 0 0 1 1 1 0 0 0 +4 4 4 1 1 1 4 4 4 0 0 0 10 10 9 104 104 103 +119 119 117 127 127 125 127 127 125 119 119 117 124 124 124 124 124 124 +86 87 84 8 8 8 10 10 9 82 82 81 124 124 124 127 127 125 +126 126 124 124 124 124 119 119 117 65 52 28 2 2 2 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 +0 0 2 0 0 2 0 0 0 0 0 0 0 0 0 5 5 5 +0 0 0 20 16 18 1 1 1 0 0 0 82 82 81 126 126 126 +175 176 174 197 198 192 205 206 201 210 211 206 210 211 206 193 193 192 +164 164 161 141 141 139 69 70 68 7 5 3 3 3 1 2 2 2 +4 4 4 6 6 6 3 3 5 0 0 2 1 1 3 3 3 5 +0 0 0 29 30 27 132 133 128 124 124 124 132 133 128 124 124 124 +126 126 124 127 127 125 119 119 117 13 14 7 1 1 1 0 0 0 +1 1 3 8 9 10 3 3 5 1 2 4 3 3 3 9 9 9 +0 0 0 10 9 7 0 0 0 69 70 68 132 133 128 124 124 124 +127 127 125 124 124 124 132 133 128 124 124 124 119 119 117 20 16 18 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 3 2 0 3 4 1 5 4 1 5 2 0 1 1 1 0 +2 0 1 2 0 1 3 0 0 9 4 5 15 7 8 8 3 8 +2 0 5 6 5 0 14 1 0 26 1 0 74 34 6 107 69 8 +170 133 50 222 154 56 231 175 56 222 154 56 229 155 20 229 155 20 +246 158 18 244 159 4 246 158 18 246 158 18 246 158 18 244 159 4 +244 159 4 249 164 6 244 159 4 244 159 4 250 166 22 250 166 22 +246 158 18 222 154 56 170 133 50 30 1 2 11 1 0 5 3 3 +4 1 3 7 5 3 6 1 3 9 4 5 7 7 7 5 3 3 +15 7 8 4 1 3 2 5 5 4 4 2 9 3 3 26 1 0 +72 12 0 222 154 56 220 161 40 246 158 18 244 159 4 246 158 18 +246 158 18 244 159 4 249 164 6 244 159 4 244 159 4 246 158 18 +246 158 18 244 159 4 233 156 5 246 158 18 242 171 21 242 158 39 +222 154 56 231 175 56 222 154 56 143 100 31 74 34 6 33 6 2 +17 1 0 17 6 0 15 7 8 1 0 0 9 4 5 6 4 5 +1 0 5 0 2 6 0 2 6 0 2 6 1 1 1 1 0 0 +1 0 0 0 0 2 0 0 5 0 0 5 1 0 0 1 0 0 +8 8 8 1 1 3 8 9 10 1 1 1 1 1 0 0 0 0 +1 1 0 7 5 3 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 2 0 +0 0 0 2 2 0 0 0 0 10 10 9 0 0 2 0 0 2 +1 1 3 8 9 10 0 0 2 4 4 4 0 0 0 5 5 5 +20 16 18 0 0 0 1 1 0 7 5 3 3 3 1 0 0 0 +2 2 0 4 4 2 2 2 0 3 3 1 5 5 3 4 4 2 +0 0 0 1 1 0 0 0 0 0 0 0 5 5 5 1 1 1 +3 3 3 8 8 8 6 6 6 0 0 0 0 0 0 2 2 2 +3 4 7 3 3 5 8 9 10 1 2 4 0 0 0 7 7 7 +0 0 0 4 4 4 2 2 0 6 6 6 0 0 0 3 3 3 +4 4 4 0 0 0 0 0 0 8 8 8 10 9 7 0 0 0 +2 2 2 1 1 1 2 2 2 4 4 4 6 6 6 0 0 2 +0 0 2 7 7 7 3 3 5 1 2 4 0 0 0 9 9 9 +10 10 9 4 4 4 0 0 0 4 4 2 5 5 3 0 0 0 +0 0 0 5 5 3 5 5 3 0 0 0 0 0 0 4 4 4 +2 2 2 0 0 2 8 9 10 8 9 10 0 0 0 5 5 5 +0 0 0 5 5 3 0 0 0 0 0 0 6 6 6 0 0 0 +9 9 9 5 5 5 3 3 3 10 10 9 4 4 2 2 2 0 +0 0 0 0 0 0 10 10 9 0 0 0 0 0 0 8 8 8 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 +0 0 2 0 0 2 0 0 2 0 0 2 6 6 6 0 0 2 +3 3 5 1 2 4 7 7 7 8 8 8 0 0 0 7 7 7 +1 1 1 2 2 0 1 1 0 0 0 0 1 1 0 2 2 0 +1 1 0 0 0 0 1 1 1 7 7 7 0 0 0 10 10 9 +1 1 3 2 1 5 0 0 4 5 7 10 0 0 4 3 3 5 +0 0 0 6 6 6 1 1 0 2 2 0 0 1 0 7 5 3 +2 2 0 8 10 3 5 5 3 1 1 0 0 0 0 3 3 5 +3 1 7 1 0 5 0 0 2 3 3 5 4 4 4 10 10 9 +0 0 0 6 6 6 5 5 3 1 1 0 0 0 0 10 10 9 +0 0 0 1 1 1 0 0 0 4 4 4 7 7 7 0 0 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 0 3 2 0 3 4 1 5 4 1 5 2 0 1 2 1 0 +2 0 1 2 0 1 3 3 1 7 1 0 15 7 8 8 1 5 +5 7 10 4 8 7 3 3 1 17 6 0 17 1 0 26 1 0 +30 1 2 48 4 0 107 69 8 143 100 31 170 133 50 222 154 56 +222 154 56 220 161 40 242 158 39 242 158 39 242 158 39 246 158 18 +246 158 18 246 158 18 233 156 5 250 166 22 231 145 5 244 159 4 +246 158 18 242 158 39 222 154 56 107 69 8 22 1 2 10 1 0 +6 0 0 6 4 5 6 1 3 7 2 6 0 0 2 6 6 6 +6 1 3 9 3 6 0 0 0 2 1 0 14 1 0 35 1 0 +198 136 53 222 154 56 229 155 20 250 166 22 233 156 5 233 156 5 +246 158 18 246 158 18 246 158 18 246 158 18 229 155 20 242 158 39 +242 158 39 242 158 39 242 158 39 222 154 56 198 136 53 170 133 50 +143 69 23 74 34 6 35 1 0 22 1 2 17 6 0 9 1 0 +7 1 0 4 1 3 3 3 3 6 6 6 7 1 0 3 0 0 +5 5 5 5 7 10 2 3 8 3 4 7 2 1 0 1 0 0 +0 0 0 0 0 2 0 2 4 0 0 4 1 0 0 3 0 0 +1 0 2 8 9 10 7 7 7 0 0 0 7 7 7 2 2 0 +2 2 0 1 1 0 2 2 2 2 2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 0 2 2 0 3 3 1 4 4 2 +0 0 0 7 5 3 1 1 1 3 3 3 1 1 3 3 3 5 +1 2 4 1 2 4 8 9 10 0 0 2 0 0 0 6 6 6 +0 0 0 7 7 7 1 1 0 1 1 0 0 0 0 0 0 0 +3 3 1 5 5 3 2 2 0 0 0 0 5 5 3 0 0 0 +5 5 3 3 3 1 3 3 3 5 5 5 1 1 1 7 7 7 +1 1 1 0 0 0 0 0 0 0 0 0 6 6 6 4 4 4 +0 0 2 6 6 6 0 0 2 7 11 16 1 1 1 5 5 5 +0 0 0 0 0 0 5 5 3 2 2 0 5 5 5 0 0 0 +3 3 3 7 7 7 0 0 0 0 0 0 4 4 2 2 2 0 +1 1 1 1 1 1 7 7 7 1 1 1 0 0 2 6 6 6 +7 7 7 0 0 2 0 0 2 8 9 10 9 9 9 0 0 0 +0 0 0 6 6 6 1 1 0 4 4 2 0 0 0 3 3 1 +0 0 0 0 0 0 4 4 2 5 5 3 2 2 0 4 4 4 +4 4 4 3 4 7 0 0 2 1 2 4 10 10 9 0 0 0 +10 9 7 1 1 0 7 5 3 4 4 2 0 0 0 10 9 7 +1 1 1 0 0 0 5 5 5 0 0 0 2 2 0 2 2 0 +4 4 2 1 1 0 3 3 1 1 1 0 3 3 3 1 1 1 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 +0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 1 2 4 +6 6 6 1 1 3 0 0 2 3 3 5 7 7 7 0 0 0 +1 1 1 0 0 0 3 3 1 4 4 2 0 0 0 0 0 0 +2 2 0 1 1 0 2 2 2 0 0 0 8 9 10 1 2 4 +3 3 5 3 4 7 5 7 10 0 0 2 3 4 7 6 6 6 +2 2 2 1 1 1 0 0 0 1 1 0 6 6 6 3 3 1 +4 4 2 1 1 0 0 0 0 0 0 0 9 9 9 0 0 2 +6 6 6 1 2 4 1 1 3 3 4 7 0 0 0 3 3 3 +6 6 6 1 1 1 2 2 0 1 1 0 1 1 0 0 0 0 +8 8 8 0 0 0 10 10 9 0 0 0 1 1 3 8 8 8 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 1 0 2 1 0 2 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 0 0 3 0 0 1 0 2 +0 0 2 0 1 0 0 0 0 3 0 0 8 0 0 11 1 0 +14 1 0 14 1 0 14 1 0 18 0 0 25 6 3 33 6 2 +74 34 6 143 100 31 170 133 50 222 154 56 222 154 56 220 161 40 +242 158 39 246 158 18 246 158 18 249 164 6 233 156 5 249 164 6 +250 166 22 229 155 20 242 158 39 222 154 56 48 4 0 14 1 0 +5 1 0 1 1 0 15 7 8 8 3 8 5 7 10 5 7 10 +6 1 3 3 0 0 8 10 3 10 7 0 18 0 0 107 69 8 +231 175 56 242 158 39 229 155 20 250 166 22 233 156 5 242 169 5 +246 158 18 246 158 18 246 158 18 229 155 20 231 175 56 222 154 56 +198 136 53 170 133 50 143 69 23 74 34 6 33 6 2 26 1 0 +17 1 0 11 1 0 8 0 0 5 1 0 3 1 0 3 1 0 +4 0 0 2 0 1 0 0 0 0 0 0 1 0 0 1 0 0 +0 0 0 0 0 2 0 0 2 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 2 0 0 2 0 0 0 1 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 0 0 4 1 3 4 1 3 +2 2 0 2 2 0 1 1 0 3 0 2 9 4 5 17 6 0 +14 1 0 33 6 2 33 6 2 48 4 0 107 69 8 170 133 50 +198 136 53 231 175 56 229 155 20 246 158 18 249 164 6 249 164 6 +244 159 4 250 166 22 250 166 22 231 175 56 143 100 31 33 6 2 +11 1 0 10 9 7 4 0 0 9 9 9 3 0 4 3 0 4 +6 1 3 7 5 3 4 0 0 25 6 3 48 4 0 222 154 56 +242 158 39 250 166 22 246 158 18 242 171 21 233 156 5 244 159 4 +246 147 4 242 158 39 222 154 56 198 136 53 107 69 8 74 34 6 +48 4 0 35 1 0 30 1 2 22 1 2 14 1 0 5 0 0 +2 0 1 1 1 1 0 2 0 0 2 0 1 1 0 1 0 0 +4 1 3 4 1 3 1 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 3 0 4 1 1 3 +1 1 0 0 2 0 0 2 2 0 2 4 0 2 6 1 1 3 +7 1 0 7 0 0 25 6 3 18 0 0 26 1 0 26 1 0 +74 34 6 198 136 53 231 175 56 229 155 20 249 164 6 242 169 5 +233 156 5 242 171 21 233 156 5 225 170 23 222 154 56 74 34 6 +22 1 2 11 1 0 8 0 0 6 1 3 15 7 8 8 1 5 +6 1 3 11 1 0 17 6 0 25 6 3 143 100 31 231 175 56 +242 171 21 246 158 18 249 178 22 231 145 5 250 166 22 246 158 18 +250 166 22 222 154 56 143 100 31 48 4 0 26 1 0 14 1 0 +11 1 0 11 1 0 10 1 0 6 0 0 3 0 0 3 3 1 +2 1 0 2 1 0 2 2 0 2 1 0 3 0 0 3 0 2 +4 1 5 4 1 5 1 0 2 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 2 2 1 5 1 1 3 +0 0 0 0 2 0 3 3 1 1 3 4 0 2 6 0 0 4 +8 8 8 3 0 2 7 1 0 10 1 0 25 6 3 17 1 0 +17 1 0 74 34 6 222 154 56 244 176 40 233 156 5 249 176 7 +242 169 5 242 169 5 233 156 5 242 171 21 220 161 40 198 136 53 +48 4 0 22 1 2 11 1 0 6 1 3 8 1 5 8 1 5 +6 1 3 11 1 0 17 1 0 74 34 6 222 154 56 229 155 20 +249 178 22 244 159 4 231 145 5 249 178 22 246 147 4 250 166 22 +231 175 56 198 136 53 33 6 2 14 1 0 2 2 0 0 2 6 +2 3 8 2 3 8 1 0 6 0 0 5 3 3 5 7 7 7 +2 1 0 2 1 0 2 2 0 1 0 0 3 0 0 1 0 2 +2 0 5 2 0 5 0 0 2 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 2 2 0 5 1 0 2 +1 0 0 1 0 0 2 2 0 2 2 0 2 2 0 2 1 0 +3 0 0 9 4 5 15 7 8 5 0 0 7 0 0 10 7 0 +10 7 0 25 6 3 143 100 31 231 175 56 225 170 23 242 169 5 +249 176 7 244 159 4 244 159 4 249 164 6 242 171 21 231 175 56 +107 69 8 30 1 2 26 16 7 0 0 2 5 7 10 3 4 7 +9 4 5 17 6 0 33 6 2 198 136 53 231 175 56 250 166 22 +250 166 22 244 159 4 242 169 5 242 169 5 244 159 4 244 176 40 +198 136 53 107 69 8 25 6 3 7 5 3 2 5 5 2 5 5 +0 2 2 0 2 6 2 3 8 3 4 7 4 1 5 4 0 1 +3 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 +0 2 4 0 2 4 0 1 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 2 1 0 5 1 0 5 +1 1 0 2 1 0 2 1 0 3 1 0 4 0 0 5 1 0 +15 7 8 4 0 0 9 4 5 9 3 6 3 0 0 3 0 0 +5 1 0 25 6 3 74 34 6 222 154 56 231 175 56 233 156 5 +249 164 6 244 159 4 249 164 6 244 159 4 242 169 5 229 155 20 +222 154 56 74 34 6 17 6 0 2 2 0 8 9 10 4 4 2 +10 7 0 18 0 0 143 100 31 231 175 56 242 158 39 250 166 22 +249 164 6 244 159 4 242 169 5 236 169 8 229 155 20 220 161 40 +143 100 31 26 1 0 17 6 0 0 1 0 0 2 1 1 7 3 +4 8 7 7 7 7 3 3 5 1 0 2 4 1 3 8 3 8 +3 0 2 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 +0 2 1 0 2 1 0 1 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 2 0 2 6 0 2 6 +1 2 4 0 2 2 1 1 1 2 0 1 4 1 3 4 1 3 +8 3 8 4 1 3 7 2 6 4 1 3 5 0 0 9 3 3 +5 0 0 8 0 0 22 1 2 107 69 8 231 175 56 225 170 23 +250 166 22 250 166 22 249 176 7 249 164 6 242 171 21 242 171 21 +231 175 56 170 133 50 25 6 3 26 16 7 2 2 0 7 1 0 +14 1 0 74 34 6 222 154 56 229 155 20 250 166 22 233 156 5 +249 164 6 242 169 5 236 169 8 249 178 22 225 170 23 231 175 56 +48 4 0 17 1 0 14 1 0 4 1 5 9 9 9 4 4 2 +1 0 0 1 0 0 2 2 0 7 5 3 9 4 5 8 3 8 +1 0 2 1 0 5 1 0 5 1 0 5 0 0 2 0 0 2 +1 1 3 1 1 3 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 1 3 0 2 4 +0 2 1 0 2 1 0 2 1 1 1 1 2 0 3 2 0 3 +4 1 5 8 3 8 3 0 4 4 1 3 10 9 7 7 1 0 +5 1 0 9 1 0 25 6 3 26 1 0 198 136 53 231 175 56 +242 171 21 242 171 21 242 169 5 242 169 5 242 171 21 242 171 21 +242 171 21 231 175 56 107 69 8 26 1 0 26 16 7 22 1 2 +33 6 2 170 133 50 231 175 56 242 171 21 242 169 5 249 176 7 +244 159 4 249 176 7 242 171 21 225 170 23 231 175 56 107 69 8 +26 1 0 14 1 0 6 1 3 2 0 5 4 1 3 4 1 3 +3 0 2 3 3 1 2 2 0 1 0 0 1 0 0 1 1 1 +0 0 2 0 0 4 0 0 5 1 0 5 1 0 5 1 0 5 +2 0 3 2 0 3 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 +0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 +0 0 2 0 0 2 0 0 2 1 1 1 1 1 0 1 2 0 +2 1 0 2 2 0 6 5 0 17 6 0 74 34 6 231 175 56 +244 176 40 242 171 21 249 178 22 242 171 21 242 171 21 236 169 8 +250 166 22 244 176 40 222 154 56 107 69 8 72 12 0 74 34 6 +143 100 31 231 175 56 242 171 21 236 169 8 249 176 7 242 169 5 +242 169 5 249 176 7 236 169 8 231 175 56 170 133 50 33 6 2 +25 6 3 15 7 8 4 1 5 2 3 13 3 1 7 3 1 7 +1 0 5 1 1 3 0 2 1 0 2 0 0 3 0 0 2 1 +0 1 2 0 2 4 0 0 5 1 0 6 2 0 5 4 1 5 +4 1 3 4 1 3 1 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 3 0 0 +1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 +0 0 2 0 0 2 0 0 2 1 1 1 1 1 0 1 2 0 +2 1 0 2 1 0 7 5 3 11 1 0 33 6 2 143 100 31 +220 161 40 244 176 40 242 171 21 236 169 8 236 169 8 249 176 7 +250 166 22 250 166 22 244 176 40 231 175 56 222 154 56 222 154 56 +244 176 40 242 171 21 242 171 21 249 178 22 242 169 5 242 169 5 +242 169 5 242 171 21 225 170 23 231 175 56 74 34 6 26 1 0 +17 1 0 5 0 0 1 0 6 2 3 13 1 0 6 1 0 6 +1 0 6 0 1 3 0 2 1 0 3 0 0 3 0 0 2 1 +0 2 2 0 1 2 0 2 4 0 0 4 0 0 2 1 0 2 +1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 0 0 4 0 0 6 1 3 +3 0 4 3 0 4 3 0 2 1 0 0 0 0 0 0 1 0 +0 0 2 0 0 4 0 0 4 2 0 3 2 0 1 2 0 1 +4 1 3 4 1 3 4 0 1 20 16 18 18 0 0 30 1 2 +231 175 56 220 161 40 244 176 40 242 171 21 242 169 5 242 169 5 +249 164 6 244 159 4 242 171 21 242 171 21 242 171 21 242 171 21 +242 171 21 244 159 4 249 176 7 249 176 7 244 159 4 242 171 21 +242 171 21 225 170 23 231 175 56 143 100 31 26 1 0 14 1 0 +7 0 0 5 1 0 5 7 10 0 2 6 0 0 2 1 0 2 +1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 2 1 +0 1 2 0 1 2 0 1 2 0 1 0 0 3 0 0 3 0 +0 3 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 0 0 4 0 2 3 0 4 +4 1 5 2 0 5 3 0 2 1 0 0 0 0 0 0 0 0 +0 0 2 1 0 5 2 0 5 2 0 5 4 1 3 4 1 3 +4 1 5 3 1 7 7 11 16 8 1 5 14 1 4 26 1 0 +107 69 8 231 175 56 244 176 40 242 171 21 249 176 7 249 176 7 +249 176 7 249 178 22 249 176 7 242 169 5 249 176 7 249 176 7 +249 164 6 249 176 7 242 169 5 242 169 5 249 176 7 249 178 22 +242 171 21 231 175 56 198 136 53 33 6 2 25 6 3 9 1 0 +4 0 0 6 6 6 8 9 10 0 2 2 0 0 2 1 0 0 +1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 1 0 0 2 1 0 2 1 0 3 0 0 3 0 0 3 0 +0 3 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 +1 0 5 1 0 5 1 1 1 1 1 0 0 2 0 0 2 0 +0 2 1 0 1 3 1 0 5 1 0 5 2 0 3 2 0 5 +3 1 7 2 3 13 8 3 14 2 3 13 8 3 8 22 1 2 +26 1 0 170 133 50 231 175 56 242 171 21 242 169 5 249 176 7 +249 176 7 249 176 7 242 169 5 249 176 7 249 176 7 242 169 5 +249 178 22 249 178 22 244 159 4 249 178 22 249 178 22 246 158 18 +244 176 40 231 175 56 74 34 6 14 1 0 4 0 0 3 1 7 +8 3 14 2 3 13 5 7 10 1 3 4 0 0 5 0 0 5 +1 0 6 0 0 5 1 0 5 1 0 5 1 0 2 1 0 0 +1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 +0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 0 +0 1 3 0 0 5 1 1 1 1 1 0 1 2 0 1 2 0 +1 1 1 1 1 3 1 1 3 1 1 3 1 1 1 1 1 3 +1 0 6 2 3 8 8 3 14 3 1 7 8 3 8 14 1 4 +17 1 0 48 4 0 222 154 56 231 175 56 242 171 21 236 169 8 +242 169 5 249 176 7 242 169 5 249 176 7 242 169 5 249 176 7 +236 169 8 242 169 5 242 169 5 249 178 22 242 171 21 244 176 40 +231 175 56 143 100 31 17 6 0 10 7 0 0 0 0 2 3 13 +2 3 13 2 3 13 1 0 5 3 3 3 0 0 4 0 0 5 +0 0 5 0 0 5 1 0 6 1 0 5 1 0 5 1 0 2 +1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 +1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 1 +1 0 5 1 0 6 2 0 3 2 0 1 2 1 0 2 1 0 +2 0 1 2 0 1 1 1 1 1 2 0 0 3 0 0 3 0 +0 2 1 0 2 1 0 3 0 20 16 18 1 0 5 3 1 7 +7 5 3 14 1 0 74 34 6 198 136 53 220 161 40 242 171 21 +242 171 21 249 178 22 249 178 22 249 178 22 236 169 8 249 176 7 +249 176 7 249 178 22 249 178 22 242 171 21 244 176 40 231 175 56 +143 100 31 25 6 3 10 7 0 6 5 0 10 10 9 5 7 10 +2 3 13 8 3 14 9 3 6 4 0 0 2 1 0 1 1 0 +1 1 1 1 1 3 1 0 5 1 0 5 0 0 4 0 0 2 +1 1 3 1 1 1 1 1 1 1 1 1 1 1 3 1 1 3 +1 0 5 1 1 3 0 0 2 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 1 +1 0 5 1 0 5 2 0 3 2 0 1 4 0 0 2 1 0 +4 0 1 2 0 1 1 1 0 1 2 0 0 3 0 0 3 0 +0 2 0 0 2 0 0 6 1 2 6 0 8 9 10 1 0 6 +5 7 10 7 1 0 22 1 2 48 4 0 170 133 50 231 175 56 +231 175 56 244 176 40 225 170 23 244 176 40 242 171 21 242 171 21 +242 171 21 242 171 21 225 170 23 231 175 56 231 175 56 143 100 31 +33 6 2 14 1 0 3 1 0 8 10 3 0 2 0 3 3 3 +20 16 18 3 1 7 15 7 8 6 0 0 4 0 0 2 1 0 +1 1 0 1 1 1 1 1 3 1 1 3 0 0 5 0 1 3 +0 0 2 0 0 2 0 1 0 0 1 0 0 0 2 0 0 4 +0 0 4 0 0 4 0 0 2 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 2 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 +0 1 0 0 1 0 0 1 0 0 1 0 0 0 4 1 0 6 +1 0 6 4 1 5 8 0 0 17 1 0 33 6 2 107 69 8 +198 136 53 231 175 56 231 175 56 231 175 56 244 176 40 244 176 40 +231 175 56 231 175 56 222 154 56 170 133 50 74 34 6 26 1 0 +14 1 0 9 4 5 0 2 0 0 3 0 0 3 0 0 3 0 +1 1 1 4 1 3 4 1 5 3 0 4 1 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 +0 0 2 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 2 0 1 1 0 0 0 0 2 0 0 4 +1 0 6 2 0 5 4 1 3 8 0 0 14 1 0 17 6 0 +33 6 2 74 34 6 107 69 8 143 100 31 143 100 31 143 100 31 +143 100 31 107 69 8 74 34 6 33 6 2 18 0 0 17 1 0 +15 7 8 3 1 7 0 1 3 0 3 0 0 3 0 0 3 0 +1 1 0 2 0 1 4 1 5 2 0 5 1 0 2 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 1 0 0 3 0 0 3 0 0 1 0 0 1 0 0 +0 0 2 0 0 2 1 1 3 1 1 1 10 9 7 10 7 0 +7 1 0 8 0 0 14 1 0 17 6 0 25 6 3 25 6 3 +17 6 0 11 1 0 9 1 0 7 0 0 5 0 0 6 1 3 +6 1 3 6 1 3 2 1 0 1 2 0 1 2 0 1 2 0 +1 1 0 0 2 1 1 0 5 1 0 5 0 0 2 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 3 0 0 3 0 0 1 0 0 1 0 0 +1 0 0 0 0 0 0 0 0 0 2 1 0 1 0 0 1 0 +5 5 5 7 7 7 4 1 3 1 0 0 3 0 0 4 4 4 +0 2 4 4 8 7 5 7 10 2 5 5 3 4 7 2 2 2 +3 0 2 9 4 5 4 0 0 4 0 0 4 0 0 2 0 1 +1 1 1 0 2 1 0 1 3 0 1 3 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 1 1 3 1 1 3 1 1 3 2 0 1 +2 0 1 4 0 0 5 1 0 5 1 0 10 9 7 7 5 3 +4 0 0 4 0 0 3 3 1 7 5 3 5 3 3 3 3 3 +4 8 7 4 8 7 0 3 0 0 3 0 6 5 0 6 5 0 +1 0 0 3 0 0 5 0 0 4 1 3 4 1 5 4 1 5 +2 0 3 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 1 3 0 1 3 1 1 3 1 1 1 +2 0 1 4 0 1 5 0 0 6 0 0 6 1 3 7 1 0 +9 3 3 5 1 0 1 0 0 1 0 0 2 0 1 1 1 3 +0 2 4 4 8 7 1 7 3 3 3 1 3 3 1 1 2 0 +2 2 0 10 9 7 3 0 2 3 0 4 4 1 5 4 1 5 +4 1 3 2 1 0 2 1 0 2 1 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 +1 0 2 1 0 5 3 0 4 4 1 5 8 3 8 7 2 6 +4 1 5 7 2 6 6 4 5 7 7 7 3 3 5 1 0 2 +8 3 8 8 3 8 7 2 6 4 1 3 7 2 6 6 1 3 +2 0 1 3 0 2 1 0 0 1 0 0 1 0 0 4 0 0 +4 0 0 5 0 0 5 0 0 3 1 0 1 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 +0 0 2 2 0 3 2 0 5 2 0 5 8 3 8 3 4 7 +3 1 7 3 1 7 1 1 3 0 0 2 3 3 5 7 7 7 +8 3 8 8 3 8 8 3 8 7 2 6 4 1 5 4 1 5 +4 1 5 4 4 4 0 0 0 0 0 0 1 0 0 1 0 0 +4 0 0 4 0 0 5 0 0 4 0 0 1 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 3 0 2 3 0 2 2 2 0 1 1 0 +1 1 0 0 2 0 0 2 0 0 3 0 0 3 0 0 3 0 +0 3 0 0 3 0 0 2 1 0 2 1 0 2 1 0 1 3 +1 0 5 4 1 5 2 0 5 2 0 5 0 0 4 0 0 4 +0 0 2 0 2 1 0 2 1 0 2 1 0 0 0 0 0 2 +2 0 5 2 0 5 3 1 7 3 1 7 0 0 2 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 4 1 3 4 1 3 2 2 0 1 1 0 +1 2 0 0 2 0 0 3 0 0 3 0 0 6 1 0 3 0 +0 3 0 0 3 0 0 3 0 0 3 0 0 2 1 0 2 1 +0 0 4 1 0 5 1 0 6 1 0 6 0 0 4 0 0 2 +0 0 2 0 2 1 0 2 0 0 2 0 0 0 2 0 0 4 +1 0 6 2 3 13 2 3 13 2 3 13 0 0 4 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/sysdrv/source/kernel/include/dt-bindings/soc/rockchip,boot-mode.h b/sysdrv/source/kernel/include/dt-bindings/soc/rockchip,boot-mode.h index ec4e5dd83..0a7a2133a 100644 --- a/sysdrv/source/kernel/include/dt-bindings/soc/rockchip,boot-mode.h +++ b/sysdrv/source/kernel/include/dt-bindings/soc/rockchip,boot-mode.h @@ -23,4 +23,6 @@ /* reboot system quiescent */ #define BOOT_QUIESCENT (REBOOT_FLAG + 14) +#define BOOT_TO_UBOOT (REBOOT_FLAG + 16) + #endif diff --git a/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_tb_v1.15.bin b/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_tb_v1.15.bin new file mode 100644 index 000000000..95767c2f7 Binary files /dev/null and b/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_tb_v1.15.bin differ diff --git a/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_v1.15.bin b/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_v1.15.bin new file mode 100644 index 000000000..95767c2f7 Binary files /dev/null and b/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_v1.15.bin differ diff --git a/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_tb_v1.15.bin b/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_tb_v1.15.bin index 95767c2f7..561ee6824 100644 Binary files a/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_tb_v1.15.bin and b/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_tb_v1.15.bin differ diff --git a/sysdrv/tools/board/uboot/rv1106-luckfox-emmc-tb.dts b/sysdrv/source/uboot/u-boot/arch/arm/dts/rv1106-luckfox-emmc-tb.dts similarity index 75% rename from sysdrv/tools/board/uboot/rv1106-luckfox-emmc-tb.dts rename to sysdrv/source/uboot/u-boot/arch/arm/dts/rv1106-luckfox-emmc-tb.dts index 1b4897ab4..e17ba7b49 100644 --- a/sysdrv/tools/board/uboot/rv1106-luckfox-emmc-tb.dts +++ b/sysdrv/source/uboot/u-boot/arch/arm/dts/rv1106-luckfox-emmc-tb.dts @@ -18,29 +18,29 @@ u-boot,spl-boot-order = &spi_nor, &emmc; }; - adc-keys { - compatible = "adc-keys"; - io-channels = <&saradc 0>; - io-channel-names = "buttons"; - poll-interval = <100>; - keyup-threshold-microvolt = <1800000>; - u-boot,dm-spl; - status = "okay"; + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + poll-interval = <100>; + keyup-threshold-microvolt = <1800000>; + u-boot,dm-spl; + status = "okay"; - volumeup-key { - u-boot,dm-spl; - linux,code = ; - label = "volume up"; - press-threshold-microvolt = <0>; - }; + volumeup-key { + u-boot,dm-spl; + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <0>; + }; - volumedown-key { - u-boot,dm-spl; - linux,code = ; - label = "volume down"; - press-threshold-microvolt = <400781>; - }; - }; + volumedown-key { + u-boot,dm-spl; + linux,code = ; + label = "volume down"; + press-threshold-microvolt = <400781>; + }; + }; }; diff --git a/sysdrv/tools/board/uboot/rv1106-luckfox-spi-nand-tb.dts b/sysdrv/source/uboot/u-boot/arch/arm/dts/rv1106-luckfox-spi-nand-tb.dts similarity index 75% rename from sysdrv/tools/board/uboot/rv1106-luckfox-spi-nand-tb.dts rename to sysdrv/source/uboot/u-boot/arch/arm/dts/rv1106-luckfox-spi-nand-tb.dts index bf64954f5..4d01c45c5 100644 --- a/sysdrv/tools/board/uboot/rv1106-luckfox-spi-nand-tb.dts +++ b/sysdrv/source/uboot/u-boot/arch/arm/dts/rv1106-luckfox-spi-nand-tb.dts @@ -18,29 +18,29 @@ u-boot,spl-boot-order = &spi_nand, &emmc; }; - adc-keys { - compatible = "adc-keys"; - io-channels = <&saradc 0>; - io-channel-names = "buttons"; - poll-interval = <100>; - keyup-threshold-microvolt = <1800000>; - u-boot,dm-spl; - status = "okay"; + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + poll-interval = <100>; + keyup-threshold-microvolt = <1800000>; + u-boot,dm-spl; + status = "okay"; - volumeup-key { - u-boot,dm-spl; - linux,code = ; - label = "volume up"; - press-threshold-microvolt = <0>; - }; + volumeup-key { + u-boot,dm-spl; + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <0>; + }; - volumedown-key { - u-boot,dm-spl; - linux,code = ; - label = "volume down"; - press-threshold-microvolt = <400781>; - }; - }; + volumedown-key { + u-boot,dm-spl; + linux,code = ; + label = "volume down"; + press-threshold-microvolt = <400781>; + }; + }; }; diff --git a/sysdrv/tools/board/uboot/rv1106-luckfox.dts b/sysdrv/source/uboot/u-boot/arch/arm/dts/rv1106-luckfox.dts similarity index 100% rename from sysdrv/tools/board/uboot/rv1106-luckfox.dts rename to sysdrv/source/uboot/u-boot/arch/arm/dts/rv1106-luckfox.dts diff --git a/sysdrv/source/uboot/u-boot/arch/arm/include/asm/arch-rockchip/boot_mode.h b/sysdrv/source/uboot/u-boot/arch/arm/include/asm/arch-rockchip/boot_mode.h index 063fd6b47..a34ec828f 100644 --- a/sysdrv/source/uboot/u-boot/arch/arm/include/asm/arch-rockchip/boot_mode.h +++ b/sysdrv/source/uboot/u-boot/arch/arm/include/asm/arch-rockchip/boot_mode.h @@ -28,6 +28,8 @@ /* enter bootrom download mode */ #define BOOT_BROM_DOWNLOAD 0xEF08A53C +#define BOOT_TO_UBOOT (REBOOT_FLAG + 16) + #ifndef __ASSEMBLY__ int setup_boot_mode(void); #endif diff --git a/sysdrv/source/uboot/u-boot/arch/arm/mach-rockchip/boot_mode.c b/sysdrv/source/uboot/u-boot/arch/arm/mach-rockchip/boot_mode.c index 6f4858bba..87ffa3a9b 100644 --- a/sysdrv/source/uboot/u-boot/arch/arm/mach-rockchip/boot_mode.c +++ b/sysdrv/source/uboot/u-boot/arch/arm/mach-rockchip/boot_mode.c @@ -206,6 +206,11 @@ int rockchip_get_boot_mode(void) printf("boot mode: quiescent\n"); boot_mode[PL] = BOOT_MODE_QUIESCENT; break; + case BOOT_TO_UBOOT: + printf("boot mode: uboot\n"); + boot_mode[PL] = BOOT_MODE_UBOOT_TERMINAL; + clear_boot_reg = 1; + break; default: printf("boot mode: None\n"); boot_mode[PL] = BOOT_MODE_UNDEFINE; @@ -231,6 +236,8 @@ int setup_boot_mode(void) { char env_preboot[256] = {0}; + env_set("cli", NULL); /* removed by default */ + switch (rockchip_get_boot_mode()) { case BOOT_MODE_BOOTLOADER: printf("enter fastboot!\n"); @@ -263,6 +270,10 @@ int setup_boot_mode(void) printf("enter charging!\n"); env_set("preboot", "setenv preboot; charge"); break; + case BOOT_MODE_UBOOT_TERMINAL: + printf("enter uboot!\n"); + env_set("cli", "yes"); + break; } return 0; diff --git a/sysdrv/source/uboot/u-boot/common/autoboot.c b/sysdrv/source/uboot/u-boot/common/autoboot.c index c64d566d1..9cf947b98 100644 --- a/sysdrv/source/uboot/u-boot/common/autoboot.c +++ b/sysdrv/source/uboot/u-boot/common/autoboot.c @@ -220,7 +220,8 @@ static int __abortboot(int bootdelay) #endif #ifdef CONFIG_ARCH_ROCKCHIP - if (!IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI) && ctrlc()) { /* we press ctrl+c ? */ +// if (!IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI) && ctrlc()) { /* we press ctrl+c ? */ + if ((!IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI) && ctrlc()) || env_get("cli")) { /* we press ctrl+c ? */ #else /* * Check if key already pressed diff --git a/sysdrv/source/uboot/u-boot/common/image-fit.c b/sysdrv/source/uboot/u-boot/common/image-fit.c index 0ee9eab69..632551b88 100644 --- a/sysdrv/source/uboot/u-boot/common/image-fit.c +++ b/sysdrv/source/uboot/u-boot/common/image-fit.c @@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR; #include #include +#define FDT_DEFAULT_LOAD_ADDR 0x00c00000 #define __round_mask(x, y) ((__typeof__(x))((y)-1)) #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) @@ -2140,7 +2141,13 @@ int fit_image_load_index(bootm_headers_t *images, ulong addr, ret = fit_image_select(fit, noffset, images->verify); if (ret) { bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH); - return ret; + /* Use the memory fdt directly */ + printf(" Use the memory fdt directly\n"); + *datap = FDT_DEFAULT_LOAD_ADDR; + fit_image_get_data_size(fit, noffset, (int *)&size); + *lenp = (ulong)size; + return noffset; + //return ret; } bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH); @@ -2175,7 +2182,6 @@ int fit_image_load_index(bootm_headers_t *images, ulong addr, fit_image_check_os(fit, noffset, IH_OS_ARM_TRUSTED_FIRMWARE) || fit_image_check_os(fit, noffset, IH_OS_OP_TEE) || fit_image_check_os(fit, noffset, IH_OS_U_BOOT) || - fit_image_check_os(fit, noffset, IH_OS_QNX) || fit_image_check_os(fit, noffset, IH_OS_OPENRTOS); /* @@ -2261,8 +2267,10 @@ int fit_image_load_index(bootm_headers_t *images, ulong addr, return -EXDEV; } + //printf(" Loading %s from 0x%08lx to 0x%08lx\n", + // prop_name, data, load); printf(" Loading %s from 0x%08lx to 0x%08lx\n", - prop_name, data, load); + prop_name, image_start, load); dst = map_sysmem(load, len); memmove(dst, buf, len); diff --git a/sysdrv/tools/board/uboot/luckfox_rv1106_spi_nand_tb_defconfig b/sysdrv/source/uboot/u-boot/configs/luckfox_rv1106_spi_nand_tb_defconfig similarity index 100% rename from sysdrv/tools/board/uboot/luckfox_rv1106_spi_nand_tb_defconfig rename to sysdrv/source/uboot/u-boot/configs/luckfox_rv1106_spi_nand_tb_defconfig diff --git a/sysdrv/tools/board/uboot/luckfox_rv1106_uboot_defconfig b/sysdrv/source/uboot/u-boot/configs/luckfox_rv1106_uboot_defconfig similarity index 100% rename from sysdrv/tools/board/uboot/luckfox_rv1106_uboot_defconfig rename to sysdrv/source/uboot/u-boot/configs/luckfox_rv1106_uboot_defconfig diff --git a/sysdrv/tools/board/uboot/luckfox_rv1106_uboot_emmc_tb_defconfig b/sysdrv/source/uboot/u-boot/configs/luckfox_rv1106_uboot_emmc_tb_defconfig similarity index 100% rename from sysdrv/tools/board/uboot/luckfox_rv1106_uboot_emmc_tb_defconfig rename to sysdrv/source/uboot/u-boot/configs/luckfox_rv1106_uboot_emmc_tb_defconfig diff --git a/sysdrv/tools/board/uboot/rv1106-luckfox_defconfig b/sysdrv/source/uboot/u-boot/configs/rv1106-luckfox_defconfig similarity index 100% rename from sysdrv/tools/board/uboot/rv1106-luckfox_defconfig rename to sysdrv/source/uboot/u-boot/configs/rv1106-luckfox_defconfig diff --git a/sysdrv/source/uboot/u-boot/drivers/mmc/mmc.c b/sysdrv/source/uboot/u-boot/drivers/mmc/mmc.c index 59805d33a..d352b00a3 100644 --- a/sysdrv/source/uboot/u-boot/drivers/mmc/mmc.c +++ b/sysdrv/source/uboot/u-boot/drivers/mmc/mmc.c @@ -2288,6 +2288,11 @@ int mmc_start_init(struct mmc *mmc) /* Test for SD version 2 */ err = mmc_send_if_cond(mmc); + if (err) { + mmc_go_idle(mmc); + mmc_get_blk_desc(mmc)->hwpart = 0; + mmc_send_if_cond(mmc); + } /* Now try to get the SD card's operating condition */ err = sd_send_op_cond(mmc); diff --git a/sysdrv/source/uboot/u-boot/include/boot_rkimg.h b/sysdrv/source/uboot/u-boot/include/boot_rkimg.h index 9cb709703..b5f49e247 100644 --- a/sysdrv/source/uboot/u-boot/include/boot_rkimg.h +++ b/sysdrv/source/uboot/u-boot/include/boot_rkimg.h @@ -20,6 +20,7 @@ enum _boot_mode { BOOT_MODE_WATCHDOG, BOOT_MODE_DFU, BOOT_MODE_QUIESCENT, + BOOT_MODE_UBOOT_TERMINAL, BOOT_MODE_UNDEFINE, }; diff --git a/sysdrv/tools/board/buildroot/S50sshd b/sysdrv/tools/board/buildroot/S50sshd deleted file mode 100755 index e5b9c4451..000000000 --- a/sysdrv/tools/board/buildroot/S50sshd +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh -# -# sshd Starts sshd. -# - -# Make sure the ssh-keygen progam exists -[ -f /usr/bin/ssh-keygen ] || exit 0 - -umask 077 - -start() { - chown root:root /var/empty/ - # Create any missing keys - /usr/bin/ssh-keygen -A - - printf "Starting sshd: " - /usr/sbin/sshd - touch /var/lock/sshd - echo "OK" -} -stop() { - printf "Stopping sshd: " - killall sshd - rm -f /var/lock/sshd - echo "OK" -} -restart() { - stop - start -} - -case "$1" in - start) - start - ;; - stop) - stop - ;; - restart|reload) - restart - ;; - *) - echo "Usage: $0 {start|stop|restart}" - exit 1 -esac - -exit $? - diff --git a/sysdrv/tools/board/buildroot/S99hciinit b/sysdrv/tools/board/buildroot/S99hciinit deleted file mode 100755 index 2b2f67a06..000000000 --- a/sysdrv/tools/board/buildroot/S99hciinit +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -check_hciconfig() { - if command -v hciattach &> /dev/null; then - if lsmod | grep -q "aic8800_fdrv"; then - hciattach -s 1500000 /dev/ttyS1 any 1500000 flow nosleep& - sleep 2 - if hciconfig -a | grep -q "hci0"; then - hciconfig hci0 up& - else - echo "hci0 not found or not available." - fi - else - echo "aic8800_fdrv not found." - fi - fi -} - -case $1 in - start) - check_hciconfig - ;; - *) - exit 1 - ;; -esac - diff --git a/sysdrv/tools/board/buildroot/S99python b/sysdrv/tools/board/buildroot/S99python deleted file mode 100755 index 0a3cb49b2..000000000 --- a/sysdrv/tools/board/buildroot/S99python +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh -# -# python Starts python code. -# - -# Make sure the python progam exists -[ -f /usr/bin/python ] || exit 0 - -umask 077 - -main_path="/root/main.py" -boot_path="/root/boot.py" - -start() { - # Run python progam - if [ -f $main_path ]; then - echo "running $main_path..." - python $main_path - else - if [ -f $boot_path ]; then - echo "running $boot_path..." - python $boot_path - else - echo "$main_path and $boot_path not exist ,pass..." - fi - fi - echo "OK" -} -stop() { - printf "Stopping python: " - killall python - echo "OK" -} -restart() { - stop - start -} - -case "$1" in - start) - start - ;; - stop) - stop - ;; - restart|reload) - restart - ;; - *) - echo "Usage: $0 {start|stop|restart}" - exit 1 -esac - -exit $? - diff --git a/sysdrv/tools/board/buildroot/S99rtcinit b/sysdrv/tools/board/buildroot/S99rtcinit deleted file mode 100755 index 32cc126f3..000000000 --- a/sysdrv/tools/board/buildroot/S99rtcinit +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -case $1 in -start) - if [ "$(hwclock | grep "1969")" ]; then - echo "RTC time calibration" - date -s 2024-01-01 - hwclock -w - else - echo "RTC does not require time calibration" - fi - ;; -*) - exit 1 - ;; -esac diff --git a/sysdrv/tools/board/buildroot/iomux b/sysdrv/tools/board/buildroot/iomux deleted file mode 100755 index f31c9dd86..000000000 Binary files a/sysdrv/tools/board/buildroot/iomux and /dev/null differ diff --git a/sysdrv/tools/board/buildroot/luckfox_pico_w_defconfig b/sysdrv/tools/board/buildroot/luckfox_pico_w_defconfig index addcac873..1cc919000 100755 --- a/sysdrv/tools/board/buildroot/luckfox_pico_w_defconfig +++ b/sysdrv/tools/board/buildroot/luckfox_pico_w_defconfig @@ -66,6 +66,7 @@ BR2_PACKAGE_LIBV4L=y BR2_PACKAGE_LIBV4L_UTILS=y BR2_PACKAGE_CJSON=y BR2_PACKAGE_CJSON_UTILS=y +BR2_PACKAGE_PCRE2=y BR2_PACKAGE_BLUEZ_TOOLS=y BR2_PACKAGE_BLUEZ5_UTILS_CLIENT=y BR2_PACKAGE_BLUEZ5_UTILS_TOOLS=y @@ -77,6 +78,9 @@ BR2_PACKAGE_IW=y BR2_PACKAGE_LRZSZ=y BR2_PACKAGE_NTP=y BR2_PACKAGE_OPENSSH=y +BR2_PACKAGE_PPPD=y +BR2_PACKAGE_PPPD_FILTER=y +BR2_PACKAGE_PPPD_RADIUS=y BR2_PACKAGE_SAMBA4=y BR2_PACKAGE_SOCAT=y BR2_PACKAGE_BASH=y @@ -84,6 +88,7 @@ BR2_PACKAGE_BASH_LOADABLE_EXAMPLES=y BR2_PACKAGE_DIALOG=y BR2_PACKAGE_TIME=y BR2_PACKAGE_HTOP=y +BR2_PACKAGE_PROCPS_NG=y BR2_PACKAGE_UTIL_LINUX_LIBMOUNT=y BR2_PACKAGE_NANO=y BR2_PACKAGE_HOST_DTC=y diff --git a/sysdrv/tools/board/buildroot/profile_defconfig b/sysdrv/tools/board/buildroot/profile_defconfig deleted file mode 100755 index d90ab5e34..000000000 --- a/sysdrv/tools/board/buildroot/profile_defconfig +++ /dev/null @@ -1,24 +0,0 @@ -export PATH="/bin:/sbin:/usr/bin:/usr/sbin" - -export EDITOR='/bin/vi' - -#export PS1='[\u@\h \W]# ' -if [ "$PS1" ]; then - if [ "`id -u`" -eq 0 ]; then - #export PS1='# ' - export PS1='[\u@\h \W]# ' - else - #export PS1='$ ' - export PS1='[\u@\h \W]$ ' - fi -fi - -# Source configuration files from /etc/profile.d -for i in /etc/profile.d/*.sh ; do - if [ -r "$i" ]; then - . $i - fi -done -unset i - - diff --git a/sysdrv/tools/board/buildroot/samba_defconfig b/sysdrv/tools/board/buildroot/samba_defconfig deleted file mode 100755 index 507f28a40..000000000 --- a/sysdrv/tools/board/buildroot/samba_defconfig +++ /dev/null @@ -1,13 +0,0 @@ -[global] - workgroup = WORKGROUP - server string = luckfox samba server - security = user - passdb backend = smbpasswd - smb passwd file = /etc/samba/smbpasswd -[public] - comment = public share - path = / - read only = no - user = root - create mask = 0755 - directory mask = 0755 \ No newline at end of file diff --git a/sysdrv/tools/board/buildroot/shadow_defconfig b/sysdrv/tools/board/buildroot/shadow_defconfig deleted file mode 100755 index 1eb78f42e..000000000 --- a/sysdrv/tools/board/buildroot/shadow_defconfig +++ /dev/null @@ -1,9 +0,0 @@ -root:$1$dXmV8ZLO$eNAQzSYOgRkYMJRdsHwLS1:19664:::::: -daemon:*::::::: -bin:*::::::: -sys:*::::::: -sync:*::::::: -mail:*::::::: -www-data:*::::::: -operator:*::::::: -nobody:*::::::: diff --git a/sysdrv/tools/board/buildroot/smbpasswd_defconfig b/sysdrv/tools/board/buildroot/smbpasswd_defconfig deleted file mode 100755 index 3cd8f163c..000000000 --- a/sysdrv/tools/board/buildroot/smbpasswd_defconfig +++ /dev/null @@ -1 +0,0 @@ -root:0:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:EF8BDD6C516032CDB7C15080FFE1B2D5:[U ]:LCT-5FEF3549: diff --git a/sysdrv/tools/board/buildroot/sshd_defconfig b/sysdrv/tools/board/buildroot/sshd_defconfig deleted file mode 100755 index 5d35f7282..000000000 --- a/sysdrv/tools/board/buildroot/sshd_defconfig +++ /dev/null @@ -1,116 +0,0 @@ -# $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $ - -# This is the sshd server system-wide configuration file. See -# sshd_config(5) for more information. - -# This sshd was compiled with PATH=/bin:/sbin:/usr/bin:/usr/sbin - -# The strategy used for options in the default sshd_config shipped with -# OpenSSH is to specify options with their default value where -# possible, but leave them commented. Uncommented options override the -# default value. - -#Port 22 -#AddressFamily any -#ListenAddress 0.0.0.0 -#ListenAddress :: - -#HostKey /etc/ssh/ssh_host_rsa_key -#HostKey /etc/ssh/ssh_host_ecdsa_key -#HostKey /etc/ssh/ssh_host_ed25519_key - -# Ciphers and keying -#RekeyLimit default none - -# Logging -#SyslogFacility AUTH -#LogLevel INFO - -# Authentication: - -#LoginGraceTime 2m -PermitRootLogin yes -#StrictModes yes -#MaxAuthTries 6 -#MaxSessions 10 - -#PubkeyAuthentication yes - -# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 -# but this is overridden so installations will only check .ssh/authorized_keys -AuthorizedKeysFile .ssh/authorized_keys - -#AuthorizedPrincipalsFile none - -#AuthorizedKeysCommand none -#AuthorizedKeysCommandUser nobody - -# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts -#HostbasedAuthentication no -# Change to yes if you don't trust ~/.ssh/known_hosts for -# HostbasedAuthentication -#IgnoreUserKnownHosts no -# Don't read the user's ~/.rhosts and ~/.shosts files -#IgnoreRhosts yes - -# To disable tunneled clear text passwords, change to no here! -#PasswordAuthentication yes -#PermitEmptyPasswords no - -# Change to no to disable s/key passwords -#KbdInteractiveAuthentication yes - -# Kerberos options -#KerberosAuthentication no -#KerberosOrLocalPasswd yes -#KerberosTicketCleanup yes -#KerberosGetAFSToken no - -# GSSAPI options -#GSSAPIAuthentication no -#GSSAPICleanupCredentials yes - -# Set this to 'yes' to enable PAM authentication, account processing, -# and session processing. If this is enabled, PAM authentication will -# be allowed through the KbdInteractiveAuthentication and -# PasswordAuthentication. Depending on your PAM configuration, -# PAM authentication via KbdInteractiveAuthentication may bypass -# the setting of "PermitRootLogin prohibit-password". -# If you just want the PAM account and session checks to run without -# PAM authentication, then enable this but set PasswordAuthentication -# and KbdInteractiveAuthentication to 'no'. -#UsePAM no - -#AllowAgentForwarding yes -#AllowTcpForwarding yes -#GatewayPorts no -#X11Forwarding no -#X11DisplayOffset 10 -#X11UseLocalhost yes -#PermitTTY yes -#PrintMotd yes -#PrintLastLog yes -#TCPKeepAlive yes -#PermitUserEnvironment no -#Compression delayed -#ClientAliveInterval 0 -#ClientAliveCountMax 3 -#UseDNS no -#PidFile /var/run/sshd.pid -#MaxStartups 10:30:100 -#PermitTunnel no -#ChrootDirectory none -#VersionAddendum none - -# no default banner path -#Banner none - -# override default of no subsystems -Subsystem sftp /usr/libexec/sftp-server - -# Example of overriding settings on a per-user basis -#Match User anoncvs -# X11Forwarding no -# AllowTcpForwarding no -# PermitTTY no -# ForceCommand cvs server diff --git a/sysdrv/tools/board/custom/.gitignore b/sysdrv/tools/board/custom/.gitignore deleted file mode 100644 index d964d79eb..000000000 --- a/sysdrv/tools/board/custom/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -./custom.tar.gz -./*.tar.gz diff --git a/sysdrv/tools/board/custom/custom.tar.gz b/sysdrv/tools/board/custom/custom.tar.gz deleted file mode 100644 index 9bedf8aeb..000000000 Binary files a/sysdrv/tools/board/custom/custom.tar.gz and /dev/null differ diff --git a/sysdrv/tools/board/kernel/0001-kernel-compatible-luckfox.patch b/sysdrv/tools/board/kernel/0001-kernel-compatible-luckfox.patch deleted file mode 100644 index 8593553c7..000000000 --- a/sysdrv/tools/board/kernel/0001-kernel-compatible-luckfox.patch +++ /dev/null @@ -1,2884 +0,0 @@ -From 81c6b931d822acb5650023a7bde1f997ffd0cabe Mon Sep 17 00:00:00 2001 -From: luckfox-eng29 -Date: Wed, 21 Aug 2024 11:11:23 +0800 -Subject: [PATCH] kernel compatible luckfox - ---- - .../kernel/arch/arm/configs/rv1106-bt.config | 7 + - sysdrv/source/kernel/drivers/kmpp | 2 +- - sysdrv/source/kernel/drivers/of/Kconfig | 7 + - sysdrv/source/kernel/drivers/of/Makefile | 1 + - sysdrv/source/kernel/drivers/of/dtbocfg.c | 429 ++++ - sysdrv/source/kernel/drivers/of/overlay.c | 4 +- - .../kernel/drivers/pinctrl/pinctrl-rockchip.h | 2 + - sysdrv/source/kernel/drivers/rockit-ko | 2 +- - .../kernel/drivers/staging/fbtft/fbtft-core.c | 6 +- - .../kernel/drivers/staging/fbtft/fbtft.h | 25 +- - .../source/kernel/drivers/usb/serial/Kconfig | 9 + - .../source/kernel/drivers/usb/serial/Makefile | 1 + - .../source/kernel/drivers/usb/serial/ch343.c | 2000 +++++++++++++++++ - .../source/kernel/drivers/usb/serial/ch343.h | 243 ++ - .../dt-bindings/soc/rockchip,boot-mode.h | 2 + - 15 files changed, 2723 insertions(+), 17 deletions(-) - create mode 100644 sysdrv/source/kernel/arch/arm/configs/rv1106-bt.config - create mode 100644 sysdrv/source/kernel/drivers/of/dtbocfg.c - create mode 100755 sysdrv/source/kernel/drivers/usb/serial/ch343.c - create mode 100755 sysdrv/source/kernel/drivers/usb/serial/ch343.h - -diff --git a/sysdrv/source/kernel/arch/arm/configs/rv1106-bt.config b/sysdrv/source/kernel/arch/arm/configs/rv1106-bt.config -new file mode 100644 -index 000000000..07e74c4bd ---- /dev/null -+++ b/sysdrv/source/kernel/arch/arm/configs/rv1106-bt.config -@@ -0,0 +1,7 @@ -+CONFIG_BT=y -+CONFIG_BT_RFCOMM=y -+CONFIG_BT_RFCOMM_TTY=y -+CONFIG_BT_HCIUART=y -+CONFIG_BT_HCIUART_H4=y -+CONFIG_RFKILL=y -+CONFIG_RFKILL_RK=y -diff --git a/sysdrv/source/kernel/drivers/of/Kconfig b/sysdrv/source/kernel/drivers/of/Kconfig -index c177b4208..b20cc8f1f 100644 ---- a/sysdrv/source/kernel/drivers/of/Kconfig -+++ b/sysdrv/source/kernel/drivers/of/Kconfig -@@ -121,4 +121,11 @@ config OF_DMA_DEFAULT_COHERENT - # arches should select this if DMA is coherent by default for OF devices - bool - -+config OF_DTBO -+ bool "Device Tree DTBO" -+ select OF_DYNAMIC -+ select OF_FLATTREE -+ select OF_RESOLVE -+ help -+ Device Tree DTBO - endif # OF -diff --git a/sysdrv/source/kernel/drivers/of/Makefile b/sysdrv/source/kernel/drivers/of/Makefile -index 6e1e5212f..8b4510e79 100644 ---- a/sysdrv/source/kernel/drivers/of/Makefile -+++ b/sysdrv/source/kernel/drivers/of/Makefile -@@ -13,5 +13,6 @@ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o - obj-$(CONFIG_OF_RESOLVE) += resolver.o - obj-$(CONFIG_OF_OVERLAY) += overlay.o - obj-$(CONFIG_OF_NUMA) += of_numa.o -+obj-$(CONFIG_OF_DTBO) += dtbocfg.o - - obj-$(CONFIG_OF_UNITTEST) += unittest-data/ -diff --git a/sysdrv/source/kernel/drivers/of/dtbocfg.c b/sysdrv/source/kernel/drivers/of/dtbocfg.c -new file mode 100644 -index 000000000..027bdd1ca ---- /dev/null -+++ b/sysdrv/source/kernel/drivers/of/dtbocfg.c -@@ -0,0 +1,429 @@ -+/********************************************************************************* -+ * -+ * Copyright (C) 2016-2023 Ichiro Kawazome -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ********************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "dtbocfg" -+#define DRIVER_VERSION "0.1.0" -+ -+/** -+ * Device Tree Overlay Item Structure -+ */ -+struct dtbocfg_overlay_item { -+ struct config_item item; -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)) -+ struct device_node* node; -+#endif -+ int id; -+ void* dtbo; -+ int dtbo_size; -+}; -+ -+/** -+ * dtbocfg_overlay_create() - Create Device Tree Overlay -+ * @overlay: Pointer to Device Tree Overlay Item -+ * return Success(0) or Error Status. -+ */ -+static int dtbocfg_overlay_item_create(struct dtbocfg_overlay_item *overlay) -+{ -+ int ret_val; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) -+ { -+ int ovcs_id = 0; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)) -+ ret_val = of_overlay_fdt_apply(overlay->dtbo,overlay->dtbo_size, &ovcs_id, NULL); -+#else -+ ret_val = of_overlay_fdt_apply(overlay->dtbo,overlay->dtbo_size, &ovcs_id); -+#endif -+ if (ret_val != 0) { -+ pr_err("%s: Failed to apply overlay (ret_val=%d)\n", __func__, ret_val); -+ goto failed; -+ } -+ overlay->id = ovcs_id; -+ pr_debug("%s: apply OK(id=%d)\n", __func__, ovcs_id); -+ } -+#else -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) -+ of_fdt_unflatten_tree(overlay->dtbo, NULL, &overlay->node); -+#else -+ of_fdt_unflatten_tree(overlay->dtbo, &overlay->node); -+#endif -+ if (overlay->node == NULL) { -+ pr_err("%s: failed to unflatten tree\n", __func__); -+ ret_val = -EINVAL; -+ goto failed; -+ } -+ pr_debug("%s: unflattened OK\n", __func__); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) -+ { -+ int ovcs_id = 0; -+ -+ ret_val = of_overlay_apply(overlay->node, &ovcs_id); -+ if (ret_val != 0) { -+ pr_err("%s: Failed to apply overlay (ret_val=%d)\n", __func__, ret_val); -+ goto failed; -+ } -+ overlay->id = ovcs_id; -+ pr_debug("%s: apply OK(id=%d)\n", __func__, ovcs_id); -+ } -+#else -+ { -+ of_node_set_flag(overlay->node, OF_DETACHED); -+ -+ ret_val = of_resolve_phandles(overlay->node); -+ if (ret_val != 0) { -+ pr_err("%s: Failed to resolve tree\n", __func__); -+ goto failed; -+ } -+ pr_debug("%s: resolved OK\n", __func__); -+ -+ ret_val = of_overlay_create(overlay->node); -+ if (ret_val < 0) { -+ pr_err("%s: Failed to create overlay (ret_val=%d)\n", __func__, ret_val); -+ goto failed; -+ } -+ overlay->id = ret_val; -+ } -+#endif -+ -+#endif -+ pr_debug("%s: create OK\n", __func__); -+ return 0; -+ -+ failed: -+ return ret_val; -+} -+ -+/** -+ * dtbocfg_overlay_item_release() - Relase Device Tree Overlay -+ * @overlay: Pointer to Device Tree Overlay Item -+ * return none -+ */ -+static void dtbocfg_overlay_item_release(struct dtbocfg_overlay_item *overlay) -+{ -+ if (overlay->id >= 0) { -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) -+ of_overlay_remove(&overlay->id); -+#else -+ of_overlay_destroy(overlay->id); -+#endif -+ overlay->id = -1; -+ } -+} -+ -+/** -+ * container_of_dtbocfg_overlay_item() - Get Device Tree Overlay Item Pointer from Configuration Item -+ * @item: Pointer to Configuration Item -+ * return Pointer to Device Tree Overlay Item -+ */ -+static inline struct dtbocfg_overlay_item* container_of_dtbocfg_overlay_item(struct config_item *item) -+{ -+ return item ? container_of(item, struct dtbocfg_overlay_item, item) : NULL; -+} -+ -+/** -+ * dtbocfg_overlay_item_status_store() - Set Status Attibute -+ * @item: Pointer to Configuration Item -+ * @page: Pointer to Value Buffer -+ * @count: Size of Value Buffer Size -+ * return Stored Size or Error Status. -+ */ -+static ssize_t dtbocfg_overlay_item_status_store(struct config_item *item, const char *buf, size_t count) -+{ -+ struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); -+ ssize_t status; -+ unsigned long value; -+ if (0 != (status = kstrtoul(buf, 10, &value))) { -+ goto failed; -+ } -+ if (value == 0) { -+ if (overlay->id >= 0) { -+ dtbocfg_overlay_item_release(overlay); -+ } -+ } else { -+ if (overlay->id < 0) { -+ dtbocfg_overlay_item_create(overlay); -+ } -+ } -+ return count; -+ failed: -+ return -EPERM; -+} -+ -+/** -+ * dtbocfg_overlay_item_status_show() - Show Status Attibute -+ * @item : Pointer to Configuration Item -+ * @page : Pointer to Value for Store -+ * return String Size or Error Status. -+ */ -+static ssize_t dtbocfg_overlay_item_status_show(struct config_item *item, char *page) -+{ -+ struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); -+ return sprintf(page, "%d\n", overlay->id >= 0 ? 1 : 0); -+} -+ -+/** -+ * dtbocfg_overlay_item_dtbo_write() - Write Device Tree Blob to Configuration Item -+ * @item : Pointer to Configuration Item -+ * @page : Pointer to Value Buffer -+ * @count: Size of Value Buffer -+ * return Stored Size or Error Status. -+ */ -+static ssize_t dtbocfg_overlay_item_dtbo_write(struct config_item *item, const void *buf, size_t count) -+{ -+ struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); -+ -+ if (overlay->dtbo_size > 0) { -+ if (overlay->id >= 0) { -+ return -EPERM; -+ } -+ kfree(overlay->dtbo); -+ overlay->dtbo = NULL; -+ overlay->dtbo_size = 0; -+ } -+ -+ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); -+ if (overlay->dtbo == NULL) { -+ overlay->dtbo_size = 0; -+ return -ENOMEM; -+ } else { -+ overlay->dtbo_size = count; -+ return count; -+ } -+} -+ -+/** -+ * dtbocfg_overlay_item_dtbo_read() - Read Device Tree Blob from Configuration Item -+ * @item : Pointer to Configuration Item -+ * @page : Pointer to Value for Store, or NULL to query the buffer size -+ * @size : Size of the supplied buffer -+ * return Read Size -+ */ -+static ssize_t dtbocfg_overlay_item_dtbo_read(struct config_item *item, void *buf, size_t size) -+{ -+ struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); -+ -+ if (overlay->dtbo == NULL) -+ return 0; -+ -+ if (buf != NULL) -+ memcpy(buf, overlay->dtbo, overlay->dtbo_size); -+ -+ return overlay->dtbo_size; -+} -+ -+/** -+ * Device Tree Blob Overlay Attribute Structure -+ */ -+CONFIGFS_BIN_ATTR(dtbocfg_overlay_item_, dtbo, NULL, 1024 * 1024); // 1MiB should be way more than enough -+CONFIGFS_ATTR(dtbocfg_overlay_item_, status); -+ -+static struct configfs_attribute *dtbocfg_overlay_attrs[] = { -+ &dtbocfg_overlay_item_attr_status, -+ NULL, -+}; -+ -+static struct configfs_bin_attribute *dtbocfg_overlay_bin_attrs[] = { -+ &dtbocfg_overlay_item_attr_dtbo, -+ NULL, -+}; -+ -+/** -+ * dtbocfg_overlay_release() - Release Device Tree Overlay Item -+ * @item : Pointer to Configuration Item -+ * Return None -+ */ -+static void dtbocfg_overlay_release(struct config_item *item) -+{ -+ struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); -+ -+ pr_debug("%s\n", __func__); -+ -+ dtbocfg_overlay_item_release(overlay); -+ -+ if (overlay->dtbo) { -+ kfree(overlay->dtbo); -+ overlay->dtbo = NULL; -+ overlay->dtbo_size = 0; -+ } -+ -+ kfree(overlay); -+} -+ -+/** -+ * Device Tree Blob Overlay Item Structure -+ */ -+static struct configfs_item_operations dtbocfg_overlay_item_ops = { -+ .release = dtbocfg_overlay_release, -+}; -+ -+static struct config_item_type dtbocfg_overlay_item_type = { -+ .ct_item_ops = &dtbocfg_overlay_item_ops, -+ .ct_attrs = dtbocfg_overlay_attrs, -+ .ct_bin_attrs = dtbocfg_overlay_bin_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+/** -+ * dtbocfg_overlay_group_make_item() - Make Device Tree Overlay Group Item -+ * @group: Pointer to Configuration Group -+ * @name : Pointer to Group Name -+ * Return Pointer to Device Tree Overlay Group Item -+ */ -+static struct config_item *dtbocfg_overlay_group_make_item(struct config_group *group, const char *name) -+{ -+ struct dtbocfg_overlay_item *overlay; -+ -+ pr_debug("%s\n", __func__); -+ -+ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); -+ -+ if (!overlay) -+ return ERR_PTR(-ENOMEM); -+ overlay->id = -1; -+ overlay->dtbo = NULL; -+ overlay->dtbo_size = 0; -+ -+ config_item_init_type_name(&overlay->item, name, &dtbocfg_overlay_item_type); -+ return &overlay->item; -+} -+ -+/** -+ * dtbocfg_overlay_group_drop_item() - Drop Device Tree Overlay Group Item -+ * @group: Pointer to Configuration Group -+ * @item : Pointer to Device Tree Overlay Group Item -+ */ -+static void dtbocfg_overlay_group_drop_item(struct config_group *group, struct config_item *item) -+{ -+ struct dtbocfg_overlay_item *overlay = container_of_dtbocfg_overlay_item(item); -+ -+ pr_debug("%s\n", __func__); -+ -+ config_item_put(&overlay->item); -+} -+ -+/** -+ * Device Tree Blob Overlay Sub Group Structures -+ */ -+static struct configfs_group_operations dtbocfg_overlays_ops = { -+ .make_item = dtbocfg_overlay_group_make_item, -+ .drop_item = dtbocfg_overlay_group_drop_item, -+}; -+ -+static struct config_item_type dtbocfg_overlays_type = { -+ .ct_group_ops = &dtbocfg_overlays_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_group dtbocfg_overlay_group; -+ -+/** -+ * Device Tree Blob Overlay Root Sub System Structures -+ */ -+static struct configfs_group_operations dtbocfg_root_ops = { -+ /* empty - we don't allow anything to be created */ -+}; -+ -+static struct config_item_type dtbocfg_root_type = { -+ .ct_group_ops = &dtbocfg_root_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct configfs_subsystem dtbocfg_root_subsys = { -+ .su_group = { -+ .cg_item = { -+ .ci_namebuf = "device-tree", -+ .ci_type = &dtbocfg_root_type, -+ }, -+ }, -+ .su_mutex = __MUTEX_INITIALIZER(dtbocfg_root_subsys.su_mutex), -+}; -+ -+/** -+ * dtbocfg_module_init() -+ */ -+static int __init dtbocfg_module_init(void) -+{ -+ int retval = 0; -+ -+ pr_info(DRIVER_NAME ": " DRIVER_VERSION "\n"); -+ -+ config_group_init(&dtbocfg_root_subsys.su_group); -+ config_group_init_type_name(&dtbocfg_overlay_group, "overlays", &dtbocfg_overlays_type); -+ -+ retval = configfs_register_subsystem(&dtbocfg_root_subsys); -+ if (retval != 0) { -+ pr_err( "%s: couldn't register subsys\n", __func__); -+ goto register_subsystem_failed; -+ } -+ -+ retval = configfs_register_group(&dtbocfg_root_subsys.su_group, &dtbocfg_overlay_group); -+ if (retval != 0) { -+ pr_err( "%s: couldn't register group\n", __func__); -+ goto register_group_failed; -+ } -+ -+ pr_info(DRIVER_NAME ": OK\n"); -+ return 0; -+ -+ register_group_failed: -+ configfs_unregister_subsystem(&dtbocfg_root_subsys); -+ register_subsystem_failed: -+ return retval; -+} -+ -+/** -+ * dtbocfg_module_exit() -+ */ -+static void __exit dtbocfg_module_exit(void) -+{ -+ configfs_unregister_group(&dtbocfg_overlay_group); -+ configfs_unregister_subsystem(&dtbocfg_root_subsys); -+} -+ -+module_init(dtbocfg_module_init); -+module_exit(dtbocfg_module_exit); -+ -+MODULE_AUTHOR("ikwzm"); -+MODULE_DESCRIPTION("Device Tree Overlay Configuration File System"); -+MODULE_LICENSE("Dual BSD/GPL"); -diff --git a/sysdrv/source/kernel/drivers/of/overlay.c b/sysdrv/source/kernel/drivers/of/overlay.c -index c8a0c0e9d..43a77d720 100644 ---- a/sysdrv/source/kernel/drivers/of/overlay.c -+++ b/sysdrv/source/kernel/drivers/of/overlay.c -@@ -170,7 +170,9 @@ static int overlay_notify(struct overlay_changeset *ovcs, - - ret = blocking_notifier_call_chain(&overlay_notify_chain, - action, &nd); -- if (notifier_to_errno(ret)) { -+ if (ret == NOTIFY_OK || ret == NOTIFY_STOP) -+ return 0; -+ if (ret) { - ret = notifier_to_errno(ret); - pr_err("overlay changeset %s notifier error %d, target: %pOF\n", - of_overlay_action_name[action], ret, nd.target); -diff --git a/sysdrv/source/kernel/drivers/pinctrl/pinctrl-rockchip.h b/sysdrv/source/kernel/drivers/pinctrl/pinctrl-rockchip.h -index 80b5552fd..dbf558d0f 100644 ---- a/sysdrv/source/kernel/drivers/pinctrl/pinctrl-rockchip.h -+++ b/sysdrv/source/kernel/drivers/pinctrl/pinctrl-rockchip.h -@@ -18,6 +18,8 @@ - #ifndef _PINCTRL_ROCKCHIP_H - #define _PINCTRL_ROCKCHIP_H - -+#include -+ - #define RK_GPIO0_A0 0 - #define RK_GPIO0_A1 1 - #define RK_GPIO0_A2 2 -diff --git a/sysdrv/source/kernel/drivers/staging/fbtft/fbtft-core.c b/sysdrv/source/kernel/drivers/staging/fbtft/fbtft-core.c -index d0c8d85f3..2baffa436 100644 ---- a/sysdrv/source/kernel/drivers/staging/fbtft/fbtft-core.c -+++ b/sysdrv/source/kernel/drivers/staging/fbtft/fbtft-core.c -@@ -292,9 +292,9 @@ static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line, - throughput = throughput ? (len * 1000) / throughput : 0; - throughput = throughput * 1000 / 1024; - -- dev_info(par->info->device, -- "Display update: %ld kB/s, fps=%ld\n", -- throughput, fps); -+ // dev_info(par->info->device, -+ // "Display update: %ld kB/s, fps=%ld\n", -+ // throughput, fps); - par->first_update_done = true; - } - } -diff --git a/sysdrv/source/kernel/drivers/staging/fbtft/fbtft.h b/sysdrv/source/kernel/drivers/staging/fbtft/fbtft.h -index 06afaa9d5..7f97aaef3 100644 ---- a/sysdrv/source/kernel/drivers/staging/fbtft/fbtft.h -+++ b/sysdrv/source/kernel/drivers/staging/fbtft/fbtft.h -@@ -407,17 +407,20 @@ do { \ - dev_info(dev, format, ##arg); \ - } while (0) - --#define fbtft_par_dbg(level, par, format, arg...) \ --do { \ -- if (unlikely((par)->debug & (level))) \ -- dev_info((par)->info->device, format, ##arg); \ --} while (0) -+/*#define fbtft_par_dbg(level, par, format, arg...) \ -+do { \ -+ if (unlikely((par)->debug & (level))) \ -+ dev_info((par)->info->device, format, ##arg); \ -+} while (0) -+ -+#define fbtft_par_dbg_hex(level, par, dev, type, buf, num, format, arg...) \ -+do { \ -+ if (unlikely((par)->debug & (level))) \ -+ fbtft_dbg_hex(dev, sizeof(type), buf,\ -+ (num) * sizeof(type), format, ##arg); \ -+} while (0)*/ - --#define fbtft_par_dbg_hex(level, par, dev, type, buf, num, format, arg...) \ --do { \ -- if (unlikely((par)->debug & (level))) \ -- fbtft_dbg_hex(dev, sizeof(type), buf,\ -- (num) * sizeof(type), format, ##arg); \ --} while (0) -+#define fbtft_par_dbg(level, par, format, arg...) ; -+#define fbtft_par_dbg_hex(level, par, dev, type, buf, num, format, arg...) ; - - #endif /* __LINUX_FBTFT_H */ -diff --git a/sysdrv/source/kernel/drivers/usb/serial/Kconfig b/sysdrv/source/kernel/drivers/usb/serial/Kconfig -index 169251ec8..bbac02a93 100644 ---- a/sysdrv/source/kernel/drivers/usb/serial/Kconfig -+++ b/sysdrv/source/kernel/drivers/usb/serial/Kconfig -@@ -112,6 +112,15 @@ config USB_SERIAL_CH341 - To compile this driver as a module, choose M here: the - module will be called ch341. - -+config USB_SERIAL_CH343 -+ tristate "USB Winchiphead CH343 Single Port Serial Driver" -+ help -+ Say Y here if you want to use a Winchiphead CH343 single port -+ USB to serial adapter. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called ch343. -+ - config USB_SERIAL_WHITEHEAT - tristate "USB ConnectTech WhiteHEAT Serial Driver" - select USB_EZUSB_FX2 -diff --git a/sysdrv/source/kernel/drivers/usb/serial/Makefile b/sysdrv/source/kernel/drivers/usb/serial/Makefile -index 2d491e434..dfab84cd4 100644 ---- a/sysdrv/source/kernel/drivers/usb/serial/Makefile -+++ b/sysdrv/source/kernel/drivers/usb/serial/Makefile -@@ -15,6 +15,7 @@ obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o - obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o - obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o - obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o -+obj-$(CONFIG_USB_SERIAL_CH343) += ch343.o - obj-$(CONFIG_USB_SERIAL_CP210X) += cp210x.o - obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o - obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o -diff --git a/sysdrv/source/kernel/drivers/usb/serial/ch343.c b/sysdrv/source/kernel/drivers/usb/serial/ch343.c -new file mode 100755 -index 000000000..546630210 ---- /dev/null -+++ b/sysdrv/source/kernel/drivers/usb/serial/ch343.c -@@ -0,0 +1,2000 @@ -+/* -+ * USB serial driver for USB to UART(s) chip ch342/ch343/ch344/ch347/ch9101/ch9102/ch9103/ch9104, etc. -+ * -+ * Copyright (C) 2022 Nanjing Qinheng Microelectronics Co., Ltd. -+ * Web: http://wch.cn -+ * Author: WCH -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * System required: -+ * Kernel version beyond 3.4.x -+ * Update Log: -+ * V1.0 - initial version -+ * V1.1 - added support of chip ch344, ch9101 and ch9103 -+ * V1.2 - added gpio support of chip ch344 -+ * V1.3 - added support of chip ch347 -+ * V1.4 - added support of chip ch9104 -+ * V1.5 - added gpio character device -+ * - added supports for kernel version beyond 5.14.x -+ * - removed the gpio ioctl commands -+ */ -+ -+#define DEBUG -+#define VERBOSE_DEBUG -+ -+#undef DEBUG -+#undef VERBOSE_DEBUG -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) -+#include -+#endif -+ -+#include "ch343.h" -+ -+#define DRIVER_AUTHOR "WCH" -+#define DRIVER_DESC "USB serial driver for ch342/ch343/ch344/ch347/ch9101/ch9102/ch9103/ch9104, etc." -+#define VERSION_DESC "V1.5 On 2022.12" -+ -+#define IOCTL_MAGIC 'W' -+#define IOCTL_CMD_GETCHIPTYPE _IOR(IOCTL_MAGIC, 0x84, u16) -+#define IOCTL_CMD_CTRLIN _IOWR(IOCTL_MAGIC, 0x90, u16) -+#define IOCTL_CMD_CTRLOUT _IOW(IOCTL_MAGIC, 0x91, u16) -+#define IOCTL_CMD_GICOUNT _IOR(IOCTL_MAGIC, 0x92, u16) -+ -+static struct usb_driver ch343_driver; -+static struct tty_driver *ch343_tty_driver; -+static struct usb_interface *g_intf; -+ -+static DEFINE_IDR(ch343_minors); -+static DEFINE_MUTEX(ch343_minors_lock); -+ -+static void ch343_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old); -+ -+/* -+ * Look up an ch343 structure by minor. If found and not disconnected, increment -+ * its refcount and return it with its mutex held. -+ */ -+static struct ch343 *ch343_get_by_minor(unsigned int minor) -+{ -+ struct ch343 *ch343; -+ -+ mutex_lock(&ch343_minors_lock); -+ ch343 = idr_find(&ch343_minors, minor); -+ if (ch343) { -+ mutex_lock(&ch343->mutex); -+ if (ch343->disconnected) { -+ mutex_unlock(&ch343->mutex); -+ ch343 = NULL; -+ } else { -+ tty_port_get(&ch343->port); -+ mutex_unlock(&ch343->mutex); -+ } -+ } -+ mutex_unlock(&ch343_minors_lock); -+ return ch343; -+} -+ -+/* -+ * Try to find an available minor number and if found, associate it with 'ch343'. -+ */ -+static int ch343_alloc_minor(struct ch343 *ch343) -+{ -+ int minor; -+ -+ mutex_lock(&ch343_minors_lock); -+ minor = idr_alloc(&ch343_minors, ch343, 0, CH343_TTY_MINORS, GFP_KERNEL); -+ mutex_unlock(&ch343_minors_lock); -+ -+ return minor; -+} -+ -+/* Release the minor number associated with 'ch343'. */ -+static void ch343_release_minor(struct ch343 *ch343) -+{ -+ mutex_lock(&ch343_minors_lock); -+ idr_remove(&ch343_minors, ch343->minor); -+ mutex_unlock(&ch343_minors_lock); -+} -+ -+/* -+ * Functions for CH343 control messages. -+ */ -+static int ch343_control_out(struct ch343 *ch343, u8 request, u16 value, u16 index) -+{ -+ int retval; -+ -+ retval = usb_autopm_get_interface(ch343->control); -+ if (retval) -+ return retval; -+ -+ retval = usb_control_msg(ch343->dev, usb_sndctrlpipe(ch343->dev, 0), request, -+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, value, index, NULL, 0, DEFAULT_TIMEOUT); -+ -+ usb_autopm_put_interface(ch343->control); -+ -+ return retval; -+} -+ -+static int ch343_control_in(struct ch343 *ch343, u8 request, u16 value, u16 index, char *buf, unsigned bufsize) -+{ -+ int retval; -+ -+ retval = usb_autopm_get_interface(ch343->control); -+ if (retval) -+ return retval; -+ -+ retval = -+ usb_control_msg(ch343->dev, usb_rcvctrlpipe(ch343->dev, 0), request, -+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, value, index, buf, bufsize, DEFAULT_TIMEOUT); -+ -+ usb_autopm_put_interface(ch343->control); -+ -+ return retval; -+} -+ -+static int ch343_control_msg_out(struct ch343 *ch343, u8 request, u8 requesttype, u16 value, u16 index, void *buf, -+ unsigned bufsize) -+{ -+ int retval; -+ char *buffer; -+ -+ buffer = kmalloc(bufsize, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ -+ retval = copy_from_user(buffer, (char __user *)buf, bufsize); -+ if (retval) -+ goto out; -+ -+ retval = usb_autopm_get_interface(ch343->control); -+ if (retval) -+ goto out; -+ -+ retval = usb_control_msg(ch343->dev, usb_sndctrlpipe(ch343->dev, 0), request, requesttype, value, index, buf, -+ bufsize, DEFAULT_TIMEOUT); -+ -+ usb_autopm_put_interface(ch343->control); -+ -+out: -+ kfree(buffer); -+ return retval; -+} -+ -+static int ch343_control_msg_in(struct ch343 *ch343, u8 request, u8 requesttype, u16 value, u16 index, void *buf, -+ unsigned bufsize) -+{ -+ int retval; -+ char *buffer; -+ -+ buffer = kmalloc(bufsize, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ -+ retval = usb_autopm_get_interface(ch343->control); -+ if (retval) -+ goto out; -+ -+ retval = usb_control_msg(ch343->dev, usb_rcvctrlpipe(ch343->dev, 0), request, requesttype, value, index, buffer, -+ bufsize, DEFAULT_TIMEOUT); -+ if (retval > 0) { -+ if (copy_to_user((char __user *)buf, buffer, retval)) { -+ retval = -EFAULT; -+ } -+ } -+ -+ usb_autopm_put_interface(ch343->control); -+ -+out: -+ kfree(buffer); -+ return retval; -+} -+ -+static inline int ch343_set_control(struct ch343 *ch343, int control) -+{ -+ if (ch343->iface <= 1) -+ return ch343_control_out(ch343, CMD_C2 + ch343->iface, ~control, 0x0000); -+ else if (ch343->iface <= 3) -+ return ch343_control_out(ch343, CMD_C2 + 0x10 + (ch343->iface - 2), ~control, 0x0000); -+ else -+ return -1; -+} -+ -+static inline int ch343_set_line(struct ch343 *ch343, struct usb_cdc_line_coding *line) -+{ -+ return 0; -+} -+ -+static int ch343_get_status(struct ch343 *ch343) -+{ -+ char *buffer; -+ int retval; -+ const unsigned size = 2; -+ unsigned long flags; -+ -+ buffer = kmalloc(size, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ -+ retval = ch343_control_in(ch343, CMD_R, CMD_C3 + ch343->iface, 0, buffer, size); -+ if (retval != size) -+ goto out; -+ -+ /* setup the private status if available */ -+ spin_lock_irqsave(&ch343->read_lock, flags); -+ ch343->ctrlin = (~(*buffer)) & CH343_CTI_ST; -+ spin_unlock_irqrestore(&ch343->read_lock, flags); -+ -+out: -+ kfree(buffer); -+ return retval; -+} -+ -+/* -------------------------------------------------------------------------- */ -+ -+static int ch343_configure(struct ch343 *ch343) -+{ -+ char *buffer; -+ int r; -+ const unsigned size = 2; -+ u8 chiptype; -+ -+ buffer = kmalloc(size, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ -+ r = ch343_control_in(ch343, CMD_C6, 0, 0, buffer, size); -+ if (r != size) -+ goto out; -+ -+ chiptype = buffer[1]; -+ -+ switch (ch343->idProduct) { -+ case 0x55D2: -+ if (chiptype == 0x48) -+ ch343->chiptype = CHIP_CH342F; -+ else if (chiptype == 0x41) -+ ch343->chiptype = CHIP_CH342K; -+ break; -+ case 0x55D3: -+ if (chiptype == 0x08) -+ ch343->chiptype = CHIP_CH343GP; -+ else if (chiptype == 0x02) -+ ch343->chiptype = CHIP_CH343J; -+ else if (chiptype == 0x01) -+ ch343->chiptype = CHIP_CH343K; -+ else if (chiptype == 0x18) -+ ch343->chiptype = CHIP_CH343G_AUTOBAUD; -+ break; -+ case 0x55D4: -+ if (chiptype == 0x08) -+ ch343->chiptype = CHIP_CH9102F; -+ else if (chiptype == 0x09) -+ ch343->chiptype = CHIP_CH9102X; -+ break; -+ case 0x55D5: -+ if (chiptype == 0xC0) { -+ if ((buffer[0] & 0xF0) == 0x40) -+ ch343->chiptype = CHIP_CH344L; -+ else -+ ch343->chiptype = CHIP_CH344L_V2; -+ } else -+ ch343->chiptype = CHIP_CH344Q; -+ break; -+ case 0x55D7: -+ if (chiptype == 0x4B) -+ ch343->chiptype = CHIP_CH9103M; -+ break; -+ case 0x55D8: -+ if (chiptype == 0x08) -+ ch343->chiptype = CHIP_CH9101UH; -+ else if (chiptype == 0x0A) -+ ch343->chiptype = CHIP_CH9101RY; -+ break; -+ case 0x55DA: -+ case 0x55DB: -+ case 0x55DD: -+ ch343->chiptype = CHIP_CH347T; -+ break; -+ case 0x55DF: -+ ch343->chiptype = CHIP_CH9104L; -+ break; -+ default: -+ break; -+ } -+ -+ if (ch343->chiptype != CHIP_CH344L && ch343->chiptype != CHIP_CH344L_V2 && ch343->chiptype != CHIP_CH9104L) { -+ r = ch343_get_status(ch343); -+ if (r < 0) -+ goto out; -+ } -+ -+ dev_dbg(&ch343->data->dev, "%s - chip hver : 0x%2x, sver : 0x%2x, chip : %d\n", __func__, buffer[0], buffer[1], -+ ch343->chiptype); -+out: -+ kfree(buffer); -+ return r < 0 ? r : 0; -+} -+ -+/* -+ * Write buffer management. -+ * All of these assume proper locks taken by the caller. -+ */ -+static int ch343_wb_alloc(struct ch343 *ch343) -+{ -+ int i, wbn; -+ struct ch343_wb *wb; -+ -+ wbn = 0; -+ i = 0; -+ for (;;) { -+ wb = &ch343->wb[wbn]; -+ if (!wb->use) { -+ wb->use = 1; -+ return wbn; -+ } -+ wbn = (wbn + 1) % CH343_NW; -+ if (++i >= CH343_NW) -+ return -1; -+ } -+} -+ -+static int ch343_wb_is_avail(struct ch343 *ch343) -+{ -+ int i, n; -+ unsigned long flags; -+ -+ n = CH343_NW; -+ spin_lock_irqsave(&ch343->write_lock, flags); -+ for (i = 0; i < CH343_NW; i++) -+ n -= ch343->wb[i].use; -+ spin_unlock_irqrestore(&ch343->write_lock, flags); -+ return n; -+} -+ -+/* -+ * Finish write. Caller must hold ch343->write_lock -+ */ -+static void ch343_write_done(struct ch343 *ch343, struct ch343_wb *wb) -+{ -+ wb->use = 0; -+ ch343->transmitting--; -+ usb_autopm_put_interface_async(ch343->control); -+} -+ -+/* -+ * Poke write. -+ * -+ * the caller is responsible for locking -+ */ -+static int ch343_start_wb(struct ch343 *ch343, struct ch343_wb *wb) -+{ -+ int rc; -+ -+ ch343->transmitting++; -+ -+ wb->urb->transfer_buffer = wb->buf; -+ wb->urb->transfer_dma = wb->dmah; -+ wb->urb->transfer_buffer_length = wb->len; -+ wb->urb->dev = ch343->dev; -+ -+ rc = usb_submit_urb(wb->urb, GFP_ATOMIC); -+ if (rc < 0) { -+ dev_err(&ch343->data->dev, "%s - usb_submit_urb(write bulk) failed: %d\n", __func__, rc); -+ ch343_write_done(ch343, wb); -+ } -+ return rc; -+} -+ -+static void ch343_update_status(struct ch343 *ch343, unsigned char *data, size_t len) -+{ -+ unsigned long flags; -+ u8 status; -+ u8 difference; -+ u8 type = data[0]; -+ u8 handled = 0; -+ -+ if (len < 4) -+ return; -+ -+ if (ch343->chiptype == CHIP_CH344L) { -+ if (data[0] != 0x00) -+ return; -+ type = data[1]; -+ } else if (ch343->chiptype == CHIP_CH344Q || ch343->chiptype == CHIP_CH344L_V2 || ch343->chiptype == CHIP_CH9104L) { -+ type = data[1]; -+ } -+ -+ if (type & CH343_CTT_M) { -+ status = ~data[len - 1] & CH343_CTI_ST; -+ if (ch343->chiptype == CHIP_CH344L || ch343->chiptype == CHIP_CH344L_V2) -+ status &= CH343_CTI_C; -+ -+ if (!ch343->clocal && (ch343->ctrlin & status & CH343_CTI_DC)) { -+ tty_port_tty_hangup(&ch343->port, false); -+ } -+ -+ spin_lock_irqsave(&ch343->read_lock, flags); -+ difference = status ^ ch343->ctrlin; -+ ch343->ctrlin = status; -+ ch343->oldcount = ch343->iocount; -+ -+ if (difference) { -+ if (difference & CH343_CTI_C) { -+ ch343->iocount.cts++; -+ } -+ if (difference & CH343_CTI_DS) { -+ ch343->iocount.dsr++; -+ } -+ if (difference & CH343_CTI_R) { -+ ch343->iocount.rng++; -+ } -+ if (difference & CH343_CTI_DC) { -+ ch343->iocount.dcd++; -+ } -+ spin_unlock_irqrestore(&ch343->read_lock, flags); -+ wake_up_interruptible(&ch343->wioctl); -+ } else -+ spin_unlock_irqrestore(&ch343->read_lock, flags); -+ handled = 1; -+ } -+ if (type & CH343_CTT_O) { -+ spin_lock_irqsave(&ch343->read_lock, flags); -+ ch343->oldcount = ch343->iocount; -+ ch343->iocount.overrun++; -+ spin_unlock_irqrestore(&ch343->read_lock, flags); -+ handled = 1; -+ } -+ if ((type & CH343_CTT_F) == CH343_CTT_F) { -+ spin_lock_irqsave(&ch343->read_lock, flags); -+ ch343->oldcount = ch343->iocount; -+ ch343->iocount.frame++; -+ spin_unlock_irqrestore(&ch343->read_lock, flags); -+ handled = 1; -+ } else if (type & CH343_CTT_P) { -+ spin_lock_irqsave(&ch343->read_lock, flags); -+ ch343->oldcount = ch343->iocount; -+ ch343->iocount.parity++; -+ spin_unlock_irqrestore(&ch343->read_lock, flags); -+ handled = 1; -+ } -+ if (!handled) -+ dev_err(&ch343->control->dev, -+ "%s - unknown status received:" -+ "len:%d, data0:0x%x, data1:0x%x\n", -+ __func__, (int)len, data[0], data[1]); -+} -+ -+/* Reports status changes with "interrupt" transfers */ -+static void ch343_ctrl_irq(struct urb *urb) -+{ -+ struct ch343 *ch343 = urb->context; -+ unsigned char *data = urb->transfer_buffer; -+ unsigned int len = urb->actual_length; -+ int status = urb->status; -+ int retval; -+ -+ switch (status) { -+ case 0: -+ /* success */ -+ break; -+ case -ECONNRESET: -+ case -ENOENT: -+ case -ESHUTDOWN: -+ /* this urb is terminated, clean up */ -+ dev_dbg(&ch343->control->dev, "%s - urb shutting down with status: %d\n", __func__, status); -+ return; -+ default: -+ dev_dbg(&ch343->control->dev, "%s - nonzero urb status received: %d\n", __func__, status); -+ goto exit; -+ } -+ -+ usb_mark_last_busy(ch343->dev); -+ ch343_update_status(ch343, data, len); -+exit: -+ retval = usb_submit_urb(urb, GFP_ATOMIC); -+ if (retval && retval != -EPERM) -+ dev_err(&ch343->control->dev, "%s - usb_submit_urb failed: %d\n", __func__, retval); -+} -+ -+static int ch343_submit_read_urb(struct ch343 *ch343, int index, gfp_t mem_flags) -+{ -+ int res; -+ -+ if (!test_and_clear_bit(index, &ch343->read_urbs_free)) -+ return 0; -+ -+ dev_vdbg(&ch343->data->dev, "%s - urb %d\n", __func__, index); -+ -+ res = usb_submit_urb(ch343->read_urbs[index], mem_flags); -+ if (res) { -+ if (res != -EPERM) { -+ dev_err(&ch343->data->dev, "%s - usb_submit_urb failed: %d\n", __func__, res); -+ } -+ set_bit(index, &ch343->read_urbs_free); -+ return res; -+ } -+ -+ return 0; -+} -+ -+static int ch343_submit_read_urbs(struct ch343 *ch343, gfp_t mem_flags) -+{ -+ int res; -+ int i; -+ -+ for (i = 0; i < ch343->rx_buflimit; ++i) { -+ res = ch343_submit_read_urb(ch343, i, mem_flags); -+ if (res) -+ return res; -+ } -+ -+ return 0; -+} -+ -+static void ch343_process_read_urb(struct ch343 *ch343, struct urb *urb) -+{ -+ if (!urb->actual_length) -+ return; -+ -+ tty_insert_flip_string(&ch343->port, urb->transfer_buffer, urb->actual_length); -+ tty_flip_buffer_push(&ch343->port); -+} -+ -+static void ch343_read_bulk_callback(struct urb *urb) -+{ -+ struct ch343_rb *rb = urb->context; -+ struct ch343 *ch343 = rb->instance; -+ int status = urb->status; -+ -+ dev_vdbg(&ch343->data->dev, "%s - urb %d, len %d\n", __func__, rb->index, urb->actual_length); -+ -+ if (!ch343->dev) { -+ set_bit(rb->index, &ch343->read_urbs_free); -+ dev_dbg(&ch343->data->dev, "%s - disconnected\n", __func__); -+ return; -+ } -+ -+ if (status) { -+ set_bit(rb->index, &ch343->read_urbs_free); -+ dev_dbg(&ch343->data->dev, "%s - non-zero urb status: %d\n", __func__, status); -+ return; -+ } -+ -+ usb_mark_last_busy(ch343->dev); -+ ch343_process_read_urb(ch343, urb); -+ set_bit(rb->index, &ch343->read_urbs_free); -+ ch343_submit_read_urb(ch343, rb->index, GFP_ATOMIC); -+} -+ -+/* data interface wrote those outgoing bytes */ -+static void ch343_write_bulk(struct urb *urb) -+{ -+ struct ch343_wb *wb = urb->context; -+ struct ch343 *ch343 = wb->instance; -+ unsigned long flags; -+ int status = urb->status; -+ -+ dev_vdbg(&ch343->data->dev, "%s, len %d\n", __func__, urb->actual_length); -+ if (status || (urb->actual_length != urb->transfer_buffer_length)) -+ dev_vdbg(&ch343->data->dev, "%s - len %d/%d, status %d\n", __func__, urb->actual_length, -+ urb->transfer_buffer_length, status); -+ -+ spin_lock_irqsave(&ch343->write_lock, flags); -+ ch343_write_done(ch343, wb); -+ spin_unlock_irqrestore(&ch343->write_lock, flags); -+ schedule_work(&ch343->work); -+} -+ -+static void ch343_softint(struct work_struct *work) -+{ -+ struct ch343 *ch343 = container_of(work, struct ch343, work); -+ -+ dev_dbg(&ch343->data->dev, "%s\n", __func__); -+ -+ tty_port_tty_wakeup(&ch343->port); -+} -+ -+/* -+ * TTY handlers -+ */ -+static int ch343_tty_install(struct tty_driver *driver, struct tty_struct *tty) -+{ -+ struct ch343 *ch343; -+ int retval; -+ -+ dev_dbg(tty->dev, "%s\n", __func__); -+ -+ ch343 = ch343_get_by_minor(tty->index); -+ if (!ch343) -+ return -ENODEV; -+ -+ retval = tty_standard_install(driver, tty); -+ if (retval) -+ goto error_init_termios; -+ -+ tty->driver_data = ch343; -+ -+ return 0; -+ -+error_init_termios: -+ tty_port_put(&ch343->port); -+ return retval; -+} -+ -+static int ch343_tty_open(struct tty_struct *tty, struct file *filp) -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ -+ dev_dbg(tty->dev, "%s\n", __func__); -+ -+ return tty_port_open(&ch343->port, tty, filp); -+} -+ -+static void ch343_port_dtr_rts(struct tty_port *port, int raise) -+{ -+ struct ch343 *ch343 = container_of(port, struct ch343, port); -+ int res; -+ -+ dev_dbg(&ch343->data->dev, "%s, raise:%d\n", __func__, raise); -+ -+ if (raise) -+ ch343->ctrlout |= CH343_CTO_D | CH343_CTO_R; -+ else -+ ch343->ctrlout &= ~(CH343_CTO_D | CH343_CTO_R); -+ -+ res = ch343_set_control(ch343, ch343->ctrlout); -+ if (res) -+ dev_err(&ch343->control->dev, "failed to set dtr/rts\n"); -+} -+ -+static int ch343_port_activate(struct tty_port *port, struct tty_struct *tty) -+{ -+ struct ch343 *ch343 = container_of(port, struct ch343, port); -+ int retval = -ENODEV; -+ int i; -+ -+ dev_dbg(&ch343->control->dev, "%s\n", __func__); -+ -+ mutex_lock(&ch343->mutex); -+ if (ch343->disconnected) -+ goto disconnected; -+ -+ retval = usb_autopm_get_interface(ch343->control); -+ if (retval) -+ goto error_get_interface; -+ -+ /* -+ * FIXME: Why do we need this? Allocating 64K of physically contiguous -+ * memory is really nasty... -+ */ -+ set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); -+ ch343->control->needs_remote_wakeup = 1; -+ -+ // retval = ch343_configure(ch343); -+ // if (retval) -+ // goto error_configure; -+ -+ ch343_tty_set_termios(tty, NULL); -+ -+ retval = usb_submit_urb(ch343->ctrlurb, GFP_KERNEL); -+ if (retval) { -+ dev_err(&ch343->control->dev, "%s - usb_submit_urb(ctrl cmd) failed\n", __func__); -+ goto error_submit_urb; -+ } -+ -+ retval = ch343_submit_read_urbs(ch343, GFP_KERNEL); -+ if (retval) -+ goto error_submit_read_urbs; -+ usb_autopm_put_interface(ch343->control); -+ -+ mutex_unlock(&ch343->mutex); -+ -+ return 0; -+ -+error_submit_read_urbs: -+ for (i = 0; i < ch343->rx_buflimit; i++) -+ usb_kill_urb(ch343->read_urbs[i]); -+error_submit_urb: -+ usb_kill_urb(ch343->ctrlurb); -+ // error_configure: -+ usb_autopm_put_interface(ch343->control); -+error_get_interface: -+disconnected: -+ mutex_unlock(&ch343->mutex); -+ -+ return usb_translate_errors(retval); -+} -+ -+static void ch343_port_destruct(struct tty_port *port) -+{ -+ struct ch343 *ch343 = container_of(port, struct ch343, port); -+ -+ dev_dbg(&ch343->control->dev, "%s\n", __func__); -+ -+ ch343_release_minor(ch343); -+ usb_put_intf(ch343->control); -+ kfree(ch343); -+} -+ -+static void ch343_port_shutdown(struct tty_port *port) -+{ -+ struct ch343 *ch343 = container_of(port, struct ch343, port); -+ struct urb *urb; -+ struct ch343_wb *wb; -+ int i; -+ -+ dev_dbg(&ch343->control->dev, "%s\n", __func__); -+ -+ usb_autopm_get_interface_no_resume(ch343->control); -+ ch343->control->needs_remote_wakeup = 0; -+ usb_autopm_put_interface(ch343->control); -+ -+ for (;;) { -+ urb = usb_get_from_anchor(&ch343->delayed); -+ if (!urb) -+ break; -+ wb = urb->context; -+ wb->use = 0; -+ usb_autopm_put_interface_async(ch343->control); -+ } -+ -+ usb_kill_urb(ch343->ctrlurb); -+ for (i = 0; i < CH343_NW; i++) -+ usb_kill_urb(ch343->wb[i].urb); -+ for (i = 0; i < ch343->rx_buflimit; i++) -+ usb_kill_urb(ch343->read_urbs[i]); -+} -+ -+static void ch343_tty_cleanup(struct tty_struct *tty) -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ dev_dbg(&ch343->control->dev, "%s\n", __func__); -+ tty_port_put(&ch343->port); -+} -+ -+static void ch343_tty_hangup(struct tty_struct *tty) -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ dev_dbg(&ch343->control->dev, "%s\n", __func__); -+ tty_port_hangup(&ch343->port); -+} -+ -+static void ch343_tty_close(struct tty_struct *tty, struct file *filp) -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ dev_dbg(&ch343->control->dev, "%s\n", __func__); -+ tty_port_close(&ch343->port, tty, filp); -+} -+ -+static int ch343_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ int stat; -+ unsigned long flags; -+ int wbn; -+ struct ch343_wb *wb; -+ -+ if (!count) -+ return 0; -+ -+ dev_vdbg(&ch343->data->dev, "%s - count %d\n", __func__, count); -+ -+ spin_lock_irqsave(&ch343->write_lock, flags); -+ wbn = ch343_wb_alloc(ch343); -+ if (wbn < 0) { -+ spin_unlock_irqrestore(&ch343->write_lock, flags); -+ return 0; -+ } -+ wb = &ch343->wb[wbn]; -+ -+ if (!ch343->dev) { -+ wb->use = 0; -+ spin_unlock_irqrestore(&ch343->write_lock, flags); -+ return -ENODEV; -+ } -+ -+ count = (count > ch343->writesize) ? ch343->writesize : count; -+ -+ memcpy(wb->buf, buf, count); -+ wb->len = count; -+ -+ stat = usb_autopm_get_interface_async(ch343->control); -+ if (stat) { -+ wb->use = 0; -+ spin_unlock_irqrestore(&ch343->write_lock, flags); -+ return stat; -+ } -+ -+ if (ch343->susp_count) { -+ usb_anchor_urb(wb->urb, &ch343->delayed); -+ spin_unlock_irqrestore(&ch343->write_lock, flags); -+ return count; -+ } -+ -+ stat = ch343_start_wb(ch343, wb); -+ spin_unlock_irqrestore(&ch343->write_lock, flags); -+ -+ if (stat < 0) -+ return stat; -+ return count; -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) -+static unsigned int ch343_tty_write_room(struct tty_struct *tty) -+#else -+static int ch343_tty_write_room(struct tty_struct *tty) -+#endif -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ /* -+ * Do not let the line discipline to know that we have a reserve, -+ * or it might get too enthusiastic. -+ */ -+ return ch343_wb_is_avail(ch343) ? ch343->writesize : 0; -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) -+static unsigned int ch343_tty_chars_in_buffer(struct tty_struct *tty) -+#else -+static int ch343_tty_chars_in_buffer(struct tty_struct *tty) -+#endif -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ /* -+ * if the device was unplugged then any remaining characters fell out -+ * of the connector ;) -+ */ -+ if (ch343->disconnected) -+ return 0; -+ /* -+ * This is inaccurate (overcounts), but it works. -+ */ -+ return (CH343_NW - ch343_wb_is_avail(ch343)) * ch343->writesize; -+} -+ -+static int ch343_tty_break_ctl(struct tty_struct *tty, int state) -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ int retval; -+ uint16_t reg_contents; -+ uint8_t *regbuf; -+ -+ dev_dbg(&ch343->control->dev, "%s\n", __func__); -+ -+ regbuf = kmalloc(2, GFP_KERNEL); -+ if (!regbuf) -+ return -1; -+ -+ if (state != 0) { -+ if ((ch343->chiptype == CHIP_CH344L) || (ch343->chiptype == CHIP_CH344Q) || -+ (ch343->chiptype == CHIP_CH344L_V2) || (ch343->chiptype == CHIP_CH9104L)) { -+ regbuf[0] = ch343->iface; -+ regbuf[1] = 0x01; -+ } else { -+ regbuf[0] = CH343_N_B; -+ regbuf[1] = 0x00; -+ } -+ } else { -+ if ((ch343->chiptype == CHIP_CH344L) || (ch343->chiptype == CHIP_CH344Q) || -+ (ch343->chiptype == CHIP_CH344L_V2) || (ch343->chiptype == CHIP_CH9104L)) { -+ regbuf[0] = ch343->iface; -+ regbuf[1] = 0x00; -+ } else { -+ regbuf[0] = CH343_N_B | CH343_N_AB; -+ regbuf[1] = 0x00; -+ } -+ } -+ reg_contents = get_unaligned_le16(regbuf); -+ -+ if ((ch343->chiptype == CHIP_CH344L) || (ch343->chiptype == CHIP_CH344Q) || (ch343->chiptype == CHIP_CH344L_V2) || -+ (ch343->chiptype == CHIP_CH9104L)) { -+ retval = ch343_control_out(ch343, CMD_C4, reg_contents, 0x00); -+ } else { -+ if (ch343->iface) -+ retval = ch343_control_out(ch343, CMD_C4, 0x00, reg_contents); -+ else -+ retval = ch343_control_out(ch343, CMD_C4, reg_contents, 0x00); -+ } -+ -+ if (retval < 0) -+ dev_err(&ch343->control->dev, "%s - USB control write error (%d)\n", __func__, retval); -+ -+ kfree(regbuf); -+ -+ return retval; -+} -+ -+static int ch343_tty_tiocmget(struct tty_struct *tty) -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ unsigned long flags; -+ unsigned int result; -+ -+ dev_dbg(&ch343->control->dev, "%s\n", __func__); -+ -+ spin_lock_irqsave(&ch343->read_lock, flags); -+ result = (ch343->ctrlout & CH343_CTO_D ? TIOCM_DTR : 0) | (ch343->ctrlout & CH343_CTO_R ? TIOCM_RTS : 0) | -+ (ch343->ctrlin & CH343_CTI_C ? TIOCM_CTS : 0) | (ch343->ctrlin & CH343_CTI_DS ? TIOCM_DSR : 0) | -+ (ch343->ctrlin & CH343_CTI_R ? TIOCM_RI : 0) | (ch343->ctrlin & CH343_CTI_DC ? TIOCM_CD : 0); -+ spin_unlock_irqrestore(&ch343->read_lock, flags); -+ -+ return result; -+} -+ -+static int ch343_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ unsigned int newctrl; -+ -+ dev_dbg(&ch343->control->dev, "%s\n", __func__); -+ -+ newctrl = ch343->ctrlout; -+ set = (set & TIOCM_DTR ? CH343_CTO_D : 0) | (set & TIOCM_RTS ? CH343_CTO_R : 0); -+ clear = (clear & TIOCM_DTR ? CH343_CTO_D : 0) | (clear & TIOCM_RTS ? CH343_CTO_R : 0); -+ -+ newctrl = (newctrl & ~clear) | set; -+ -+ if (ch343->ctrlout == newctrl) { -+ return 0; -+ } -+ -+ return ch343_set_control(ch343, ch343->ctrlout = newctrl); -+} -+ -+static int ch343_get_serial_info(struct ch343 *ch343, struct serial_struct __user *info) -+{ -+ struct serial_struct tmp; -+ -+ if (!info) -+ return -EINVAL; -+ -+ memset(&tmp, 0, sizeof(tmp)); -+ tmp.flags = ASYNC_LOW_LATENCY; -+ tmp.xmit_fifo_size = ch343->writesize; -+ tmp.baud_base = le32_to_cpu(ch343->line.dwDTERate); -+ tmp.close_delay = ch343->port.close_delay / 10; -+ tmp.closing_wait = -+ ch343->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE : ch343->port.closing_wait / 10; -+ -+ if (copy_to_user(info, &tmp, sizeof(tmp))) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+static int ch343_set_serial_info(struct ch343 *ch343, struct serial_struct __user *newinfo) -+{ -+ struct serial_struct new_serial; -+ unsigned int closing_wait, close_delay; -+ int retval = 0; -+ -+ if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) -+ return -EFAULT; -+ -+ close_delay = new_serial.close_delay * 10; -+ closing_wait = -+ new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; -+ -+ mutex_lock(&ch343->port.mutex); -+ -+ if (!capable(CAP_SYS_ADMIN)) { -+ if ((close_delay != ch343->port.close_delay) || (closing_wait != ch343->port.closing_wait)) -+ retval = -EPERM; -+ else -+ retval = -EOPNOTSUPP; -+ } else { -+ ch343->port.close_delay = close_delay; -+ ch343->port.closing_wait = closing_wait; -+ } -+ -+ mutex_unlock(&ch343->port.mutex); -+ return retval; -+} -+ -+static int ch343_wait_serial_change(struct ch343 *ch343, unsigned long arg) -+{ -+ int rv = 0; -+ DECLARE_WAITQUEUE(wait, current); -+ struct async_icount old, new; -+ -+ do { -+ spin_lock_irq(&ch343->read_lock); -+ old = ch343->oldcount; -+ new = ch343->iocount; -+ ch343->oldcount = new; -+ spin_unlock_irq(&ch343->read_lock); -+ -+ if ((arg & TIOCM_CTS) && old.cts != new.cts) -+ break; -+ if ((arg & TIOCM_DSR) && old.dsr != new.dsr) -+ break; -+ if ((arg & TIOCM_RI) && old.rng != new.rng) -+ break; -+ if ((arg & TIOCM_CD) && old.dcd != new.dcd) -+ break; -+ -+ add_wait_queue(&ch343->wioctl, &wait); -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule(); -+ remove_wait_queue(&ch343->wioctl, &wait); -+ if (ch343->disconnected) { -+ if (arg & TIOCM_CD) -+ break; -+ else -+ rv = -ENODEV; -+ } else { -+ if (signal_pending(current)) -+ rv = -ERESTARTSYS; -+ } -+ } while (!rv); -+ -+ return rv; -+} -+ -+static int ch343_get_serial_usage(struct ch343 *ch343, struct serial_icounter_struct __user *count) -+{ -+ struct serial_icounter_struct icount; -+ int rv = 0; -+ -+ memset(&icount, 0, sizeof(icount)); -+ icount.cts = ch343->iocount.cts; -+ icount.dsr = ch343->iocount.dsr; -+ icount.rng = ch343->iocount.rng; -+ icount.dcd = ch343->iocount.dcd; -+ icount.frame = ch343->iocount.frame; -+ icount.overrun = ch343->iocount.overrun; -+ icount.parity = ch343->iocount.parity; -+ icount.brk = ch343->iocount.brk; -+ -+ if (copy_to_user(count, &icount, sizeof(icount)) > 0) -+ rv = -EFAULT; -+ -+ return rv; -+} -+ -+static int ch343_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ int rv = 0; -+ unsigned long arg1, arg2, arg3, arg4, arg5, arg6; -+ u32 __user *argval = (u32 __user *)arg; -+ u8 *buffer; -+ -+ dev_dbg(&ch343->control->dev, "%s\n", __func__); -+ -+ buffer = kmalloc(512, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ -+ switch (cmd) { -+ case TIOCGSERIAL: /* gets serial port data */ -+ rv = ch343_get_serial_info(ch343, (struct serial_struct __user *)arg); -+ break; -+ case TIOCSSERIAL: -+ rv = ch343_set_serial_info(ch343, (struct serial_struct __user *)arg); -+ break; -+ case TIOCMIWAIT: -+ rv = usb_autopm_get_interface(ch343->control); -+ if (rv < 0) { -+ rv = -EIO; -+ break; -+ } -+ rv = ch343_wait_serial_change(ch343, arg); -+ usb_autopm_put_interface(ch343->control); -+ break; -+ case IOCTL_CMD_GICOUNT: -+ case TIOCGICOUNT: -+ rv = ch343_get_serial_usage(ch343, (struct serial_icounter_struct __user *)arg); -+ break; -+ case IOCTL_CMD_GETCHIPTYPE: -+ if (put_user(ch343->chiptype, argval)) { -+ rv = -EFAULT; -+ goto out; -+ } -+ break; -+ case IOCTL_CMD_CTRLIN: -+ get_user(arg1, (u8 __user *)arg); -+ get_user(arg2, ((u8 __user *)arg + 1)); -+ get_user(arg3, (u16 __user *)((u8 *)arg + 2)); -+ get_user(arg4, (u16 __user *)((u8 *)arg + 4)); -+ get_user(arg5, (u16 __user *)((u8 *)arg + 6)); -+ arg6 = (unsigned long)((u8 __user *)arg + 8); -+ rv = ch343_control_msg_in(ch343, (u8)arg1, (u8)arg2, (u16)arg3, (u16)arg4, (u8 __user *)arg6, (u16)arg5); -+ break; -+ case IOCTL_CMD_CTRLOUT: -+ get_user(arg1, (u8 __user *)arg); -+ get_user(arg2, ((u8 __user *)arg + 1)); -+ get_user(arg3, (u16 __user *)((u8 *)arg + 2)); -+ get_user(arg4, (u16 __user *)((u8 *)arg + 4)); -+ get_user(arg5, (u16 __user *)((u8 *)arg + 6)); -+ arg6 = (unsigned long)((u8 __user *)arg + 8); -+ rv = ch343_control_msg_out(ch343, (u8)arg1, (u8)arg2, (u16)arg3, (u16)arg4, (u8 __user *)arg6, (u16)arg5); -+ if (rv != (u16)arg5) { -+ rv = -EINVAL; -+ goto out; -+ } -+ break; -+ default: -+ rv = -ENOIOCTLCMD; -+ break; -+ } -+ -+out: -+ kfree(buffer); -+ return rv < 0 ? rv : 0; -+} -+ -+static int ch343_get(CHIPTYPE chiptype, unsigned int bval, unsigned char *fct, unsigned char *dvs) -+{ -+ unsigned char a; -+ unsigned char b; -+ unsigned long c; -+ -+ if (((chiptype == CHIP_CH347T) || (chiptype == CHIP_CH344Q) || (chiptype == CHIP_CH9104L)) && bval >= 2000000) { -+ *fct = (unsigned char)(bval / 200); -+ *dvs = (unsigned char)((bval / 200) >> 8); -+ } -+ -+ switch (bval) { -+ case 6000000: -+ case 4000000: -+ case 2400000: -+ case 921600: -+ case 307200: -+ case 256000: -+ b = 7; -+ c = 12000000; -+ break; -+ default: -+ if (bval > 6000000 / 255) { -+ b = 3; -+ c = 6000000; -+ } else if (bval > 750000 / 255) { -+ b = 2; -+ c = 750000; -+ } else if (bval > 93750 / 255) { -+ b = 1; -+ c = 93750; -+ } else { -+ b = 0; -+ c = 11719; -+ } -+ break; -+ } -+ a = (unsigned char)(c / bval); -+ if (a == 0 || a == 0xFF) -+ return -EINVAL; -+ if ((c / a - bval) > (bval - c / (a + 1))) -+ a++; -+ a = 256 - a; -+ -+ *fct = a; -+ *dvs = b; -+ -+ return 0; -+} -+ -+static void ch343_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old) -+{ -+ struct ch343 *ch343 = tty->driver_data; -+ struct ktermios *termios = &tty->termios; -+ struct usb_ch343_line_coding newline; -+ int newctrl = ch343->ctrlout; -+ -+ unsigned char dvs = 0; -+ unsigned char reg_count = 0; -+ unsigned char fct = 0; -+ unsigned char reg_value = 0; -+ unsigned short value = 0; -+ unsigned short index = 0; -+ -+ dev_dbg(tty->dev, "%s\n", __func__); -+ -+ if (termios_old && !tty_termios_hw_change(&tty->termios, termios_old)) { -+ return; -+ } -+ -+ newline.dwDTERate = tty_get_baud_rate(tty); -+ -+ if (newline.dwDTERate == 0) -+ newline.dwDTERate = 9600; -+ ch343_get(ch343->chiptype, newline.dwDTERate, &fct, &dvs); -+ -+ newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 1; -+ if (newline.bCharFormat == 2) -+ reg_value |= CH343_L_SB; -+ -+ newline.bParityType = -+ termios->c_cflag & PARENB ? (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0; -+ -+ switch (newline.bParityType) { -+ case 0x01: -+ reg_value |= CH343_L_P_O; -+ break; -+ case 0x02: -+ reg_value |= CH343_L_P_E; -+ break; -+ case 0x03: -+ reg_value |= CH343_L_P_M; -+ break; -+ case 0x04: -+ reg_value |= CH343_L_P_S; -+ break; -+ default: -+ break; -+ } -+ -+ switch (termios->c_cflag & CSIZE) { -+ case CS5: -+ newline.bDataBits = 5; -+ reg_value |= CH343_L_C5; -+ break; -+ case CS6: -+ newline.bDataBits = 6; -+ reg_value |= CH343_L_C6; -+ break; -+ case CS7: -+ newline.bDataBits = 7; -+ reg_value |= CH343_L_C7; -+ break; -+ case CS8: -+ default: -+ newline.bDataBits = 8; -+ reg_value |= CH343_L_C8; -+ break; -+ } -+ -+ /* FIXME: Needs to clear unsupported bits in the termios */ -+ ch343->clocal = ((termios->c_cflag & CLOCAL) != 0); -+ -+ if (C_BAUD(tty) == B0) { -+ newline.dwDTERate = ch343->line.dwDTERate; -+ newctrl &= ~CH343_CTO_D; -+ } else if (termios_old && (termios_old->c_cflag & CBAUD) == B0) { -+ newctrl |= CH343_CTO_D; -+ } -+ -+ reg_value |= CH343_L_E_R | CH343_L_E_T; -+ reg_count |= CH343_L_R_CT | CH343_L_R_CL | CH343_L_R_T; -+ -+ value |= reg_count; -+ value |= (unsigned short)reg_value << 8; -+ -+ index |= 0x00 | dvs; -+ index |= (unsigned short)fct << 8; -+ if (ch343->iface <= 1) -+ ch343_control_out(ch343, CMD_C1 + ch343->iface, value, index); -+ else if (ch343->iface <= 3) -+ ch343_control_out(ch343, CMD_C1 + 0x10 + (ch343->iface - 2), value, index); -+ -+ if (memcmp(&ch343->line, &newline, sizeof newline)) { -+ memcpy(&ch343->line, &newline, sizeof newline); -+ dev_dbg(&ch343->control->dev, "%s - set line: %d %d %d %d\n", __func__, newline.dwDTERate, newline.bCharFormat, -+ newline.bParityType, newline.bDataBits); -+ } -+ -+ if (C_CRTSCTS(tty)) { -+ newctrl |= CH343_CTO_A | CH343_CTO_R; -+ } else -+ newctrl &= ~CH343_CTO_A; -+ -+ if (newctrl != ch343->ctrlout) -+ ch343_set_control(ch343, ch343->ctrlout = newctrl); -+} -+ -+static const struct tty_port_operations ch343_port_ops = { -+ .dtr_rts = ch343_port_dtr_rts, -+ .shutdown = ch343_port_shutdown, -+ .activate = ch343_port_activate, -+ .destruct = ch343_port_destruct, -+}; -+ -+/* Little helpers: write/read buffers free */ -+static void ch343_write_buffers_free(struct ch343 *ch343) -+{ -+ int i; -+ struct ch343_wb *wb; -+ struct usb_device *usb_dev = interface_to_usbdev(ch343->control); -+ -+ for (wb = &ch343->wb[0], i = 0; i < CH343_NW; i++, wb++) -+ usb_free_coherent(usb_dev, ch343->writesize, wb->buf, wb->dmah); -+} -+ -+static void ch343_read_buffers_free(struct ch343 *ch343) -+{ -+ struct usb_device *usb_dev = interface_to_usbdev(ch343->control); -+ int i; -+ -+ for (i = 0; i < ch343->rx_buflimit; i++) -+ usb_free_coherent(usb_dev, ch343->readsize, ch343->read_buffers[i].base, ch343->read_buffers[i].dma); -+} -+ -+/* Little helper: write buffers allocate */ -+static int ch343_write_buffers_alloc(struct ch343 *ch343) -+{ -+ int i; -+ struct ch343_wb *wb; -+ -+ for (wb = &ch343->wb[0], i = 0; i < CH343_NW; i++, wb++) { -+ wb->buf = usb_alloc_coherent(ch343->dev, ch343->writesize, GFP_KERNEL, &wb->dmah); -+ if (!wb->buf) { -+ while (i != 0) { -+ --i; -+ --wb; -+ usb_free_coherent(ch343->dev, ch343->writesize, wb->buf, wb->dmah); -+ } -+ return -ENOMEM; -+ } -+ } -+ return 0; -+} -+ -+static int ch343_open(struct inode *inode, struct file *file) -+{ -+ struct ch343 *ch343; -+ struct usb_interface *interface; -+ int subminor; -+ int retval = 0; -+ -+ subminor = iminor(inode); -+ -+ interface = usb_find_interface(&ch343_driver, subminor); -+ if (!interface) { -+ pr_err("%s - error, can't find device for minor %d\n", __func__, subminor); -+ retval = -ENODEV; -+ goto exit; -+ } -+ -+ ch343 = usb_get_intfdata(interface); -+ if (!ch343) { -+ retval = -ENODEV; -+ goto exit; -+ } -+ -+ /* save our object in the file's private structure */ -+ file->private_data = ch343; -+ -+exit: -+ return retval; -+} -+ -+static int ch343_release(struct inode *inode, struct file *file) -+{ -+ struct ch343 *ch343; -+ -+ ch343 = file->private_data; -+ if (ch343 == NULL) -+ return -ENODEV; -+ -+ return 0; -+} -+ -+static long ch343_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ struct ch343 *ch343; -+ int rv = 0; -+ u8 *buffer; -+ unsigned long arg1, arg2, arg3, arg4, arg5, arg6; -+ u32 __user *argval = (u32 __user *)arg; -+ -+ ch343 = file->private_data; -+ if (ch343 == NULL) -+ return -ENODEV; -+ -+ buffer = kmalloc(512, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ -+ switch (cmd) { -+ case IOCTL_CMD_GETCHIPTYPE: -+ if (put_user(ch343->chiptype, argval)) { -+ rv = -EFAULT; -+ goto out; -+ } -+ break; -+ case IOCTL_CMD_CTRLIN: -+ get_user(arg1, (u8 __user *)arg); -+ get_user(arg2, ((u8 __user *)arg + 1)); -+ get_user(arg3, (u16 __user *)((u8 *)arg + 2)); -+ get_user(arg4, (u16 __user *)((u8 *)arg + 4)); -+ get_user(arg5, (u16 __user *)((u8 *)arg + 6)); -+ arg6 = (unsigned long)((u8 __user *)arg + 8); -+ rv = ch343_control_msg_in(ch343, (u8)arg1, (u8)arg2, (u16)arg3, (u16)arg4, (u8 __user *)arg6, (u16)arg5); -+ break; -+ case IOCTL_CMD_CTRLOUT: -+ get_user(arg1, (u8 __user *)arg); -+ get_user(arg2, ((u8 __user *)arg + 1)); -+ get_user(arg3, (u16 __user *)((u8 *)arg + 2)); -+ get_user(arg4, (u16 __user *)((u8 *)arg + 4)); -+ get_user(arg5, (u16 __user *)((u8 *)arg + 6)); -+ arg6 = (unsigned long)((u8 __user *)arg + 8); -+ rv = ch343_control_msg_out(ch343, (u8)arg1, (u8)arg2, (u16)arg3, (u16)arg4, (u8 __user *)arg6, (u16)arg5); -+ if (rv != (u16)arg5) { -+ rv = -EINVAL; -+ goto out; -+ } -+ break; -+ default: -+ rv = -ENOIOCTLCMD; -+ break; -+ } -+ -+out: -+ kfree(buffer); -+ return rv; -+} -+ -+static const struct file_operations ch343_fops = { -+ .owner = THIS_MODULE, -+ .open = ch343_open, -+ .unlocked_ioctl = ch343_ioctl, -+ .release = ch343_release, -+}; -+ -+/* -+ * usb class driver info in order to get a minor number from the usb core, -+ * and to have the device registered with the driver core -+ */ -+static struct usb_class_driver ch343_class = { -+ .name = "ch343_iodev%d", -+ .fops = &ch343_fops, -+ .minor_base = USB_MINOR_BASE, -+}; -+ -+/* -+ * USB probe and disconnect routines. -+ */ -+static int ch343_probe(struct usb_interface *intf, const struct usb_device_id *id) -+{ -+ struct usb_cdc_union_desc *union_header = NULL; -+ unsigned char *buffer = intf->altsetting->extra; -+ int buflen = intf->altsetting->extralen; -+ struct usb_interface *control_interface; -+ struct usb_interface *data_interface; -+ struct usb_endpoint_descriptor *epctrl = NULL; -+ struct usb_endpoint_descriptor *epread = NULL; -+ struct usb_endpoint_descriptor *epwrite = NULL; -+ struct usb_device *usb_dev = interface_to_usbdev(intf); -+ struct ch343 *ch343; -+ int minor; -+ int ctrlsize, readsize; -+ u8 *buf; -+ unsigned long quirks; -+ int num_rx_buf = CH343_NR; -+ int i; -+ unsigned int elength = 0; -+ struct device *tty_dev; -+ int rv = -ENOMEM; -+ -+ /* normal quirks */ -+ quirks = (unsigned long)id->driver_info; -+ if (!buffer) { -+ dev_err(&intf->dev, "Weird descriptor references\n"); -+ return -EINVAL; -+ } -+ -+ while (buflen > 0) { -+ elength = buffer[0]; -+ if (!elength) { -+ dev_err(&intf->dev, "skipping garbage byte\n"); -+ elength = 1; -+ goto next_desc; -+ } -+ if (buffer[1] != USB_DT_CS_INTERFACE) { -+ dev_err(&intf->dev, "skipping garbage\n"); -+ goto next_desc; -+ } -+ -+ switch (buffer[2]) { -+ case USB_CDC_UNION_TYPE: /* we've found it */ -+ if (elength < sizeof(struct usb_cdc_union_desc)) -+ goto next_desc; -+ if (union_header) { -+ dev_err(&intf->dev, -+ "More than one " -+ "union descriptor, skipping ...\n"); -+ goto next_desc; -+ } -+ union_header = (struct usb_cdc_union_desc *)buffer; -+ break; -+ default: -+ /* -+ * there are LOTS more CDC descriptors that -+ * could legitimately be found here. -+ */ -+ break; -+ } -+ next_desc: -+ buflen -= elength; -+ buffer += elength; -+ } -+ -+ control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); -+ data_interface = usb_ifnum_to_if(usb_dev, union_header->bSlaveInterface0); -+ -+ if (intf != control_interface) -+ return -ENODEV; -+ -+ if (usb_interface_claimed(data_interface)) { -+ dev_dbg(&intf->dev, "The data interface isn't available\n"); -+ return -EBUSY; -+ } -+ -+ if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || -+ control_interface->cur_altsetting->desc.bNumEndpoints == 0) -+ return -EINVAL; -+ -+ epctrl = &control_interface->cur_altsetting->endpoint[0].desc; -+ epwrite = &data_interface->cur_altsetting->endpoint[0].desc; -+ epread = &data_interface->cur_altsetting->endpoint[1].desc; -+ -+ /* workaround for switched endpoints */ -+ if (!usb_endpoint_dir_in(epread)) { -+ /* descriptors are swapped */ -+ dev_dbg(&intf->dev, "The data interface has switched endpoints\n"); -+ swap(epread, epwrite); -+ } -+ -+ ch343 = kzalloc(sizeof(struct ch343), GFP_KERNEL); -+ if (ch343 == NULL) -+ goto alloc_fail; -+ -+ ch343->idVendor = id->idVendor; -+ ch343->idProduct = id->idProduct; -+ ch343->iface = control_interface->cur_altsetting->desc.bInterfaceNumber / 2; -+ -+ minor = ch343_alloc_minor(ch343); -+ if (minor < 0) { -+ dev_err(&intf->dev, "no more free ch343 devices\n"); -+ kfree(ch343); -+ return -ENODEV; -+ } -+ -+ ctrlsize = usb_endpoint_maxp(epctrl); -+ readsize = usb_endpoint_maxp(epread); -+ ch343->writesize = usb_endpoint_maxp(epwrite) * 20; -+ ch343->control = control_interface; -+ ch343->data = data_interface; -+ ch343->minor = minor; -+ ch343->dev = usb_dev; -+ ch343->ctrlsize = ctrlsize; -+ ch343->readsize = readsize; -+ ch343->rx_buflimit = num_rx_buf; -+ -+ dev_dbg(&intf->dev, "ep%d ctrl: %d, ep%d read: %d, ep%d write: %d\n", usb_endpoint_num(epctrl), -+ usb_endpoint_maxp(epctrl), usb_endpoint_num(epread), usb_endpoint_maxp(epread), usb_endpoint_num(epwrite), -+ usb_endpoint_maxp(epwrite)); -+ -+ INIT_WORK(&ch343->work, ch343_softint); -+ init_waitqueue_head(&ch343->wioctl); -+ spin_lock_init(&ch343->write_lock); -+ spin_lock_init(&ch343->read_lock); -+ mutex_init(&ch343->mutex); -+ ch343->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); -+ tty_port_init(&ch343->port); -+ ch343->port.ops = &ch343_port_ops; -+ init_usb_anchor(&ch343->delayed); -+ ch343->quirks = quirks; -+ -+ buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &ch343->ctrl_dma); -+ if (!buf) -+ goto alloc_fail2; -+ ch343->ctrl_buffer = buf; -+ -+ if (ch343_write_buffers_alloc(ch343) < 0) -+ goto alloc_fail4; -+ -+ ch343->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); -+ if (!ch343->ctrlurb) -+ goto alloc_fail5; -+ -+ for (i = 0; i < num_rx_buf; i++) { -+ struct ch343_rb *rb = &(ch343->read_buffers[i]); -+ struct urb *urb; -+ -+ rb->base = usb_alloc_coherent(ch343->dev, readsize, GFP_KERNEL, &rb->dma); -+ if (!rb->base) -+ goto alloc_fail6; -+ rb->index = i; -+ rb->instance = ch343; -+ -+ urb = usb_alloc_urb(0, GFP_KERNEL); -+ if (!urb) -+ goto alloc_fail6; -+ -+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -+ urb->transfer_dma = rb->dma; -+ usb_fill_bulk_urb(urb, ch343->dev, ch343->rx_endpoint, rb->base, ch343->readsize, ch343_read_bulk_callback, rb); -+ -+ ch343->read_urbs[i] = urb; -+ __set_bit(i, &ch343->read_urbs_free); -+ } -+ for (i = 0; i < CH343_NW; i++) { -+ struct ch343_wb *snd = &(ch343->wb[i]); -+ -+ snd->urb = usb_alloc_urb(0, GFP_KERNEL); -+ if (snd->urb == NULL) -+ goto alloc_fail7; -+ -+ usb_fill_bulk_urb(snd->urb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), NULL, -+ ch343->writesize, ch343_write_bulk, snd); -+ snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -+ snd->instance = ch343; -+ } -+ -+ usb_set_intfdata(intf, ch343); -+ -+ usb_fill_int_urb(ch343->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress), ch343->ctrl_buffer, -+ ctrlsize, ch343_ctrl_irq, ch343, epctrl->bInterval ? epctrl->bInterval : 16); -+ ch343->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -+ ch343->ctrlurb->transfer_dma = ch343->ctrl_dma; -+ -+ dev_info(&intf->dev, "ttyCH343USB%d: usb to uart device\n", minor); -+ -+ usb_driver_claim_interface(&ch343_driver, data_interface, ch343); -+ usb_set_intfdata(data_interface, ch343); -+ usb_get_intf(control_interface); -+ -+ rv = ch343_configure(ch343); -+ if (rv) -+ goto alloc_fail7; -+ -+ if (ch343->iface == 0) { -+ /* register the device now, as it is ready */ -+ rv = usb_register_dev(intf, &ch343_class); -+ if (rv) { -+ /* error when registering this driver */ -+ dev_err(&intf->dev, "Not able to get a minor for this device.\n"); -+ } else { -+ g_intf = intf; -+ } -+ } -+ -+ tty_dev = tty_port_register_device(&ch343->port, ch343_tty_driver, minor, &control_interface->dev); -+ if (IS_ERR(tty_dev)) { -+ rv = PTR_ERR(tty_dev); -+ goto alloc_fail7; -+ } -+ -+ return 0; -+ -+alloc_fail7: -+ usb_set_intfdata(intf, NULL); -+ for (i = 0; i < CH343_NW; i++) -+ usb_free_urb(ch343->wb[i].urb); -+alloc_fail6: -+ for (i = 0; i < num_rx_buf; i++) -+ usb_free_urb(ch343->read_urbs[i]); -+ ch343_read_buffers_free(ch343); -+ usb_free_urb(ch343->ctrlurb); -+alloc_fail5: -+ ch343_write_buffers_free(ch343); -+alloc_fail4: -+ usb_free_coherent(usb_dev, ctrlsize, ch343->ctrl_buffer, ch343->ctrl_dma); -+alloc_fail2: -+ ch343_release_minor(ch343); -+ kfree(ch343); -+alloc_fail: -+ return rv; -+} -+ -+static void stop_data_traffic(struct ch343 *ch343) -+{ -+ int i; -+ -+ usb_kill_urb(ch343->ctrlurb); -+ for (i = 0; i < CH343_NW; i++) -+ usb_kill_urb(ch343->wb[i].urb); -+ for (i = 0; i < ch343->rx_buflimit; i++) -+ usb_kill_urb(ch343->read_urbs[i]); -+ cancel_work_sync(&ch343->work); -+} -+ -+static void ch343_disconnect(struct usb_interface *intf) -+{ -+ struct ch343 *ch343 = usb_get_intfdata(intf); -+ struct usb_device *usb_dev = interface_to_usbdev(intf); -+ struct tty_struct *tty; -+ int i; -+ -+ dev_dbg(&intf->dev, "%s\n", __func__); -+ -+ /* sibling interface is already cleaning up */ -+ if (!ch343) -+ return; -+ -+ /* give back minor */ -+ if ((ch343->iface == 0) && (g_intf != NULL)) { -+ usb_deregister_dev(g_intf, &ch343_class); -+ } -+ -+ mutex_lock(&ch343->mutex); -+ ch343->disconnected = true; -+ wake_up_all(&ch343->wioctl); -+ usb_set_intfdata(ch343->control, NULL); -+ usb_set_intfdata(ch343->data, NULL); -+ mutex_unlock(&ch343->mutex); -+ -+ tty = tty_port_tty_get(&ch343->port); -+ if (tty) { -+ tty_vhangup(tty); -+ tty_kref_put(tty); -+ } -+ -+ stop_data_traffic(ch343); -+ -+ tty_unregister_device(ch343_tty_driver, ch343->minor); -+ -+ usb_free_urb(ch343->ctrlurb); -+ for (i = 0; i < CH343_NW; i++) -+ usb_free_urb(ch343->wb[i].urb); -+ for (i = 0; i < ch343->rx_buflimit; i++) -+ usb_free_urb(ch343->read_urbs[i]); -+ ch343_write_buffers_free(ch343); -+ usb_free_coherent(usb_dev, ch343->ctrlsize, ch343->ctrl_buffer, ch343->ctrl_dma); -+ ch343_read_buffers_free(ch343); -+ -+ usb_driver_release_interface(&ch343_driver, intf == ch343->control ? ch343->data : ch343->control); -+ -+ tty_port_put(&ch343->port); -+ dev_info(&intf->dev, "%s\n", "ch343 usb device disconnect."); -+} -+ -+#ifdef CONFIG_PM -+static int ch343_suspend(struct usb_interface *intf, pm_message_t message) -+{ -+ struct ch343 *ch343 = usb_get_intfdata(intf); -+ int cnt; -+ -+ dev_dbg(&intf->dev, "%s\n", __func__); -+ -+ spin_lock_irq(&ch343->write_lock); -+ if (PMSG_IS_AUTO(message)) { -+ if (ch343->transmitting) { -+ spin_unlock_irq(&ch343->write_lock); -+ return -EBUSY; -+ } -+ } -+ cnt = ch343->susp_count++; -+ spin_unlock_irq(&ch343->write_lock); -+ -+ if (cnt) -+ return 0; -+ -+ stop_data_traffic(ch343); -+ -+ return 0; -+} -+ -+static int ch343_resume(struct usb_interface *intf) -+{ -+ struct ch343 *ch343 = usb_get_intfdata(intf); -+ struct urb *urb; -+ int rv = 0; -+ -+ dev_dbg(&intf->dev, "%s\n", __func__); -+ -+ spin_lock_irq(&ch343->write_lock); -+ -+ if (--ch343->susp_count) -+ goto out; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) -+ if (tty_port_initialized(&ch343->port)) { -+#else -+ if (test_bit(ASYNCB_INITIALIZED, &ch343->port.flags)) { -+#endif -+ rv = usb_submit_urb(ch343->ctrlurb, GFP_ATOMIC); -+ -+ for (;;) { -+ urb = usb_get_from_anchor(&ch343->delayed); -+ if (!urb) -+ break; -+ -+ ch343_start_wb(ch343, urb->context); -+ } -+ -+ /* -+ * delayed error checking because we must -+ * do the write path at all cost -+ */ -+ if (rv < 0) -+ goto out; -+ -+ rv = ch343_submit_read_urbs(ch343, GFP_ATOMIC); -+ } -+out: -+ spin_unlock_irq(&ch343->write_lock); -+ -+ return rv; -+} -+ -+static int ch343_reset_resume(struct usb_interface *intf) -+{ -+ struct ch343 *ch343 = usb_get_intfdata(intf); -+ -+ dev_dbg(&intf->dev, "%s\n", __func__); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) -+ if (tty_port_initialized(&ch343->port)) -+#else -+ if (test_bit(ASYNCB_INITIALIZED, &ch343->port.flags)) -+#endif -+ tty_port_tty_hangup(&ch343->port, false); -+ -+ return ch343_resume(intf); -+} -+ -+#endif /* CONFIG_PM */ -+ -+/* -+ * USB driver structure. -+ */ -+ -+static const struct usb_device_id ch343_ids[] = {{USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D2, /* ch342 chip */ -+ USB_CDC_ACM_PROTO_AT_V25TER)}, -+ -+ {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D3, /* ch343 chip */ -+ USB_CDC_ACM_PROTO_AT_V25TER)}, -+ -+ {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D5, /* ch344 chip */ -+ USB_CDC_ACM_PROTO_AT_V25TER)}, -+ -+ {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55DA, /* ch347 chip mode0*/ -+ USB_CDC_ACM_PROTO_AT_V25TER)}, -+ -+ {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55DB, /* ch347 chip mode1*/ -+ USB_CDC_ACM_PROTO_AT_V25TER)}, -+ -+ {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55DD, /* ch347 chip mode3*/ -+ USB_CDC_ACM_PROTO_AT_V25TER)}, -+ -+ {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D8, /* ch9101 chip */ -+ USB_CDC_ACM_PROTO_AT_V25TER)}, -+ -+ {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D4, /* ch9102 chip */ -+ USB_CDC_ACM_PROTO_AT_V25TER)}, -+ -+ {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55D7, /* ch9103 chip */ -+ USB_CDC_ACM_PROTO_AT_V25TER)}, -+ -+ {USB_DEVICE_INTERFACE_PROTOCOL(0x1a86, 0x55DF, /* ch9104 chip */ -+ USB_CDC_ACM_PROTO_AT_V25TER)}, -+ -+ {}}; -+ -+MODULE_DEVICE_TABLE(usb, ch343_ids); -+ -+static struct usb_driver ch343_driver = { -+ .name = "usb_ch343", -+ .probe = ch343_probe, -+ .disconnect = ch343_disconnect, -+#ifdef CONFIG_PM -+ .suspend = ch343_suspend, -+ .resume = ch343_resume, -+ .reset_resume = ch343_reset_resume, -+#endif -+ .id_table = ch343_ids, -+#ifdef CONFIG_PM -+ .supports_autosuspend = 1, -+#endif -+ .disable_hub_initiated_lpm = 1, -+}; -+ -+/* -+ * TTY driver structures. -+ */ -+static const struct tty_operations ch343_ops = { -+ .install = ch343_tty_install, -+ .open = ch343_tty_open, -+ .close = ch343_tty_close, -+ .cleanup = ch343_tty_cleanup, -+ .hangup = ch343_tty_hangup, -+ .write = ch343_tty_write, -+ .write_room = ch343_tty_write_room, -+ .ioctl = ch343_tty_ioctl, -+ .chars_in_buffer = ch343_tty_chars_in_buffer, -+ .break_ctl = ch343_tty_break_ctl, -+ .set_termios = ch343_tty_set_termios, -+ .tiocmget = ch343_tty_tiocmget, -+ .tiocmset = ch343_tty_tiocmset, -+}; -+ -+/* -+ * Init / exit. -+ */ -+static int __init ch343_init(void) -+{ -+ int retval; -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) -+ ch343_tty_driver = tty_alloc_driver(CH343_TTY_MINORS, TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); -+ if (IS_ERR(ch343_tty_driver)) -+ return PTR_ERR(ch343_tty_driver); -+#else -+ ch343_tty_driver = alloc_tty_driver(CH343_TTY_MINORS); -+ if (!ch343_tty_driver) -+ return -ENOMEM; -+#endif -+ ch343_tty_driver->driver_name = "usbch343", ch343_tty_driver->name = "ttyCH343USB", -+ ch343_tty_driver->major = CH343_TTY_MAJOR, ch343_tty_driver->minor_start = 0, -+ ch343_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, ch343_tty_driver->subtype = SERIAL_TYPE_NORMAL, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) -+ ch343_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; -+#endif -+ ch343_tty_driver->init_termios = tty_std_termios; -+ ch343_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; -+ tty_set_operations(ch343_tty_driver, &ch343_ops); -+ -+ retval = tty_register_driver(ch343_tty_driver); -+ if (retval) { -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) -+ tty_driver_kref_put(ch343_tty_driver); -+#else -+ put_tty_driver(ch343_tty_driver); -+#endif -+ return retval; -+ } -+ -+ retval = usb_register(&ch343_driver); -+ if (retval) { -+ tty_unregister_driver(ch343_tty_driver); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) -+ tty_driver_kref_put(ch343_tty_driver); -+#else -+ put_tty_driver(ch343_tty_driver); -+#endif -+ return retval; -+ } -+ -+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); -+ printk(KERN_INFO KBUILD_MODNAME ": " VERSION_DESC "\n"); -+ -+ return 0; -+} -+ -+static void __exit ch343_exit(void) -+{ -+ usb_deregister(&ch343_driver); -+ tty_unregister_driver(ch343_tty_driver); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) -+ tty_driver_kref_put(ch343_tty_driver); -+#else -+ put_tty_driver(ch343_tty_driver); -+#endif -+ idr_destroy(&ch343_minors); -+ printk(KERN_INFO KBUILD_MODNAME -+ ": " -+ "ch343 driver exit.\n"); -+} -+ -+module_init(ch343_init); -+module_exit(ch343_exit); -+ -+MODULE_AUTHOR(DRIVER_AUTHOR); -+MODULE_DESCRIPTION(DRIVER_DESC); -+MODULE_VERSION(VERSION_DESC); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS_CHARDEV_MAJOR(CH343_TTY_MAJOR); -diff --git a/sysdrv/source/kernel/drivers/usb/serial/ch343.h b/sysdrv/source/kernel/drivers/usb/serial/ch343.h -new file mode 100755 -index 000000000..c53a87500 ---- /dev/null -+++ b/sysdrv/source/kernel/drivers/usb/serial/ch343.h -@@ -0,0 +1,243 @@ -+#ifndef _CH343_H -+#define _CH343_H -+ -+/* -+ * Baud rate and default timeout -+ */ -+#define DEFAULT_BAUD_RATE 9600 -+#define DEFAULT_TIMEOUT 2000 -+ -+/* -+ * CMSPAR, some architectures can't have space and mark parity. -+ */ -+ -+#ifndef CMSPAR -+#define CMSPAR 0 -+#endif -+ -+/* -+ * Major and minor numbers. -+ */ -+ -+#define CH343_TTY_MAJOR 170 -+#define CH343_TTY_MINORS 256 -+ -+#define USB_MINOR_BASE 70 -+ -+/* -+ * Requests. -+ */ -+ -+#define USB_RT_CH343 (USB_TYPE_CLASS | USB_RECIP_INTERFACE) -+ -+#define CMD_R 0x95 -+#define CMD_W 0x9A -+#define CMD_C1 0xA1 -+#define CMD_C2 0xA4 -+#define CMD_C3 0x05 -+#define CMD_C4 0xA8 -+#define CMD_C5 0x5E -+#define CMD_C6 0x5F -+ -+#define CH343_CTO_O 0x10 -+#define CH343_CTO_D 0x20 -+#define CH343_CTO_R 0x40 -+#define CH343_CTO_A 0x80 -+#define CH343_CTI_C 0x01 -+#define CH343_CTI_DS 0x02 -+#define CH343_CTI_R 0x04 -+#define CH343_CTI_DC 0x08 -+#define CH343_CTI_ST 0x0f -+ -+#define CH343_CTT_M 0x08 -+#define CH343_CTT_F 0x44 -+#define CH343_CTT_P 0x04 -+#define CH343_CTT_O 0x02 -+ -+#define CH343_LO 0x02 -+#define CH343_LE 0x04 -+#define CH343_LB -+#define CH343_LP 0x00 -+#define CH343_LF 0x40 -+#define CH343_LM 0x08 -+ -+#define CH343_L_R_CT 0x80 -+#define CH343_L_R_CL 0x04 -+#define CH343_L_R_T 0x08 -+ -+#define CH343_L_E_R 0x80 -+#define CH343_L_E_T 0x40 -+#define CH343_L_P_S 0x38 -+#define CH343_L_P_M 0x28 -+#define CH343_L_P_E 0x18 -+#define CH343_L_P_O 0x08 -+#define CH343_L_SB 0x04 -+#define CH343_L_C8 0x03 -+#define CH343_L_C7 0x02 -+#define CH343_L_C6 0x01 -+#define CH343_L_C5 0x00 -+ -+#define CH343_N_B 0x80 -+#define CH343_N_AB 0x10 -+ -+/* -+ * Internal driver structures. -+ */ -+ -+/* -+ * The only reason to have several buffers is to accommodate assumptions -+ * in line disciplines. They ask for empty space amount, receive our URB size, -+ * and proceed to issue several 1-character writes, assuming they will fit. -+ * The very first write takes a complete URB. Fortunately, this only happens -+ * when processing onlcr, so we only need 2 buffers. These values must be -+ * powers of 2. -+ */ -+#define CH343_NW 16 -+#define CH343_NR 16 -+ -+struct ch343_wb { -+ unsigned char *buf; -+ dma_addr_t dmah; -+ int len; -+ int use; -+ struct urb *urb; -+ struct ch343 *instance; -+}; -+ -+struct ch343_rb { -+ int size; -+ unsigned char *base; -+ dma_addr_t dma; -+ int index; -+ struct ch343 *instance; -+}; -+ -+struct usb_ch343_line_coding { -+ __u32 dwDTERate; -+ __u8 bCharFormat; -+#define USB_CH343_1_STOP_BITS 0 -+#define USB_CH343_1_5_STOP_BITS 1 -+#define USB_CH343_2_STOP_BITS 2 -+ -+ __u8 bParityType; -+#define USB_CH343_NO_PARITY 0 -+#define USB_CH343_ODD_PARITY 1 -+#define USB_CH343_EVEN_PARITY 2 -+#define USB_CH343_MARK_PARITY 3 -+#define USB_CH343_SPACE_PARITY 4 -+ -+ __u8 bDataBits; -+} __attribute__((packed)); -+ -+typedef enum { -+ CHIP_CH342F = 0x00, -+ CHIP_CH342K, -+ CHIP_CH343GP, -+ CHIP_CH343G_AUTOBAUD, -+ CHIP_CH343K, -+ CHIP_CH343J, -+ CHIP_CH344L, -+ CHIP_CH344L_V2, -+ CHIP_CH344Q, -+ CHIP_CH347T, -+ CHIP_CH9101UH, -+ CHIP_CH9101RY, -+ CHIP_CH9102F, -+ CHIP_CH9102X, -+ CHIP_CH9103M, -+ CHIP_CH9104L, -+} CHIPTYPE; -+ -+struct gpioinfo { -+ int group; -+ int pin; -+}; -+ -+struct ch343_gpio { -+ int gpiocount; -+ struct gpioinfo io[64]; -+}; -+ -+struct ch343_gpio ch343_gpios[] = { -+ { 0, {}}, -+ { 0, {}}, -+ { 0, {}}, -+ { 0, {}}, -+ { 0, {}}, -+ { 0, {}}, -+ /* CH344L */ -+ { 8, {}}, -+ /* CH344L-V2 */ -+ { 8, {}}, -+ /* CH344Q */ -+ { 8, {}}, -+ /* CH347T */ -+ { 4, {}}, -+ /* CH9101UH */ -+ { 5, {{3, 2}, {3, 3}, {1, 3}, {1, 2}, {1, 5}, {2, 4}}}, -+ /* CH9101RY */ -+ { 4, {{1, 3}, {3, 3}, {3, 2}, {2, 4}}}, -+ /* CH9102F */ -+ { 5, {{2, 1}, {2, 7}, {2, 4}, {2, 6}, {2, 3}}}, -+ /* CH9102X */ -+ { 6, {{2, 3}, {2, 5}, {2, 1}, {2, 7}, {3, 0}, {2, 2}}}, -+ /* CH9103M */ -+ {12, {{1, 3}, {1, 2}, {3, 2}, {2, 6}, {1, 0}, {1, 6}, {2, 3}, {2, 5}, {3, 0}, {2, 2}, {1, 5}, {2, 4}}}, -+ /* CH9104L */ -+ {24, {}}, -+}; -+ -+struct ch343 { -+ struct usb_device *dev; /* the corresponding usb device */ -+ struct usb_interface *control; /* control interface */ -+ struct usb_interface *data; /* data interface */ -+ struct tty_port port; /* our tty port data */ -+ struct urb *ctrlurb; /* urbs */ -+ u8 *ctrl_buffer; /* buffers of urbs */ -+ dma_addr_t ctrl_dma; /* dma handles of buffers */ -+ struct ch343_wb wb[CH343_NW]; -+ unsigned long read_urbs_free; -+ struct urb *read_urbs[CH343_NR]; -+ struct ch343_rb read_buffers[CH343_NR]; -+ int rx_buflimit; -+ int rx_endpoint; -+ spinlock_t read_lock; -+ int write_used; /* number of non-empty write buffers */ -+ int transmitting; -+ spinlock_t write_lock; -+ struct mutex mutex; -+ bool disconnected; -+ struct usb_ch343_line_coding line; /* bits, stop, parity */ -+ struct work_struct work; /* work queue entry for line discipline waking up */ -+ unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ -+ unsigned int ctrlout; /* output control lines (DTR, RTS) */ -+ struct async_icount iocount; /* counters for control line changes */ -+ struct async_icount oldcount; /* for comparison of counter */ -+ wait_queue_head_t wioctl; /* for ioctl */ -+ unsigned int writesize; /* max packet size for the output bulk endpoint */ -+ unsigned int readsize, ctrlsize; /* buffer sizes for freeing */ -+ unsigned int minor; /* ch343 minor number */ -+ unsigned char clocal; /* termios CLOCAL */ -+ unsigned int susp_count; /* number of suspended interfaces */ -+ u8 bInterval; -+ struct usb_anchor delayed; /* writes queued for a device about to be woken */ -+ unsigned long quirks; -+ u8 iface; -+ CHIPTYPE chiptype; -+ u16 idVendor; -+ u16 idProduct; -+ u8 gpio5dir; -+}; -+ -+#define CDC_DATA_INTERFACE_TYPE 0x0a -+ -+/* constants describing various quirks and errors */ -+#define NO_UNION_NORMAL BIT(0) -+#define SINGLE_RX_URB BIT(1) -+#define NO_CAP_LINE BIT(2) -+#define NO_DATA_INTERFACE BIT(4) -+#define IGNORE_DEVICE BIT(5) -+#define QUIRK_CONTROL_LINE_STATE BIT(6) -+#define CLEAR_HALT_CONDITIONS BIT(7) -+ -+#endif -diff --git a/sysdrv/source/kernel/include/dt-bindings/soc/rockchip,boot-mode.h b/sysdrv/source/kernel/include/dt-bindings/soc/rockchip,boot-mode.h -index ec4e5dd83..0a7a2133a 100644 ---- a/sysdrv/source/kernel/include/dt-bindings/soc/rockchip,boot-mode.h -+++ b/sysdrv/source/kernel/include/dt-bindings/soc/rockchip,boot-mode.h -@@ -23,4 +23,6 @@ - /* reboot system quiescent */ - #define BOOT_QUIESCENT (REBOOT_FLAG + 14) - -+#define BOOT_TO_UBOOT (REBOOT_FLAG + 16) -+ - #endif --- -2.34.1 - diff --git a/sysdrv/tools/board/kernel/0002-logo-mediate.patch b/sysdrv/tools/board/kernel/0002-logo-mediate.patch deleted file mode 100644 index a753731cf..000000000 --- a/sysdrv/tools/board/kernel/0002-logo-mediate.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 94a0b2232c729c757547b88f2cbc035cef7e0bc1 Mon Sep 17 00:00:00 2001 -From: luckfox-eng29 -Date: Tue, 8 Oct 2024 21:50:54 +0800 -Subject: [PATCH] patch:logo_center - -Signed-off-by: luckfox-eng29 ---- - .../source/kernel/drivers/video/fbdev/core/fbcon.c | 14 +++++++++++++- - .../source/kernel/drivers/video/fbdev/core/fbmem.c | 7 ++++++- - 2 files changed, 19 insertions(+), 2 deletions(-) - -diff --git a/sysdrv/source/kernel/drivers/video/fbdev/core/fbcon.c b/sysdrv/source/kernel/drivers/video/fbdev/core/fbcon.c -index 27828435d..c3ac676bb 100644 ---- a/sysdrv/source/kernel/drivers/video/fbdev/core/fbcon.c -+++ b/sysdrv/source/kernel/drivers/video/fbdev/core/fbcon.c -@@ -88,6 +88,9 @@ - # define DPRINTK(fmt, args...) - #endif - -+#define CURSOR_ENABLE 0 -+#define SHOW_CENTER 1 -+ - /* - * FIXME: Locking - * -@@ -365,6 +368,7 @@ static int get_color(struct vc_data *vc, struct fb_info *info, - - static void fb_flashcursor(struct work_struct *work) - { -+#if CURSOR_ENABLE - struct fb_info *info = container_of(work, struct fb_info, queue); - struct fbcon_ops *ops = info->fbcon_par; - struct vc_data *vc = NULL; -@@ -395,6 +399,7 @@ static void fb_flashcursor(struct work_struct *work) - ops->cursor(vc, info, mode, get_color(vc, info, c, 1), - get_color(vc, info, c, 0)); - console_unlock(); -+#endif - } - - static void cursor_timer_handler(struct timer_list *t) -@@ -601,7 +606,12 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, - if (fb_get_color_depth(&info->var, &info->fix) == 1) - erase &= ~0x400; - logo_height = fb_prepare_logo(info, ops->rotate); -- logo_lines = DIV_ROUND_UP(logo_height, vc->vc_font.height); -+ -+#if SHOW_CENTER -+ logo_height += (info->var.yres/2) - (logo_height/2); -+#endif -+ -+ logo_lines = DIV_ROUND_UP(logo_height, vc->vc_font.height); - q = (unsigned short *) (vc->vc_origin + - vc->vc_size_row * rows); - step = logo_lines * cols; -@@ -1331,6 +1341,7 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) - - static void fbcon_cursor(struct vc_data *vc, int mode) - { -+#if CURSOR_ENABLE - struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; - struct fbcon_ops *ops = info->fbcon_par; - int c = scr_readw((u16 *) vc->vc_pos); -@@ -1352,6 +1363,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode) - - ops->cursor(vc, info, mode, get_color(vc, info, c, 1), - get_color(vc, info, c, 0)); -+#endif - } - - static int scrollback_phys_max = 0; -diff --git a/sysdrv/source/kernel/drivers/video/fbdev/core/fbmem.c b/sysdrv/source/kernel/drivers/video/fbdev/core/fbmem.c -index d787a344b..690d48fba 100644 ---- a/sysdrv/source/kernel/drivers/video/fbdev/core/fbmem.c -+++ b/sysdrv/source/kernel/drivers/video/fbdev/core/fbmem.c -@@ -38,7 +38,7 @@ - - #include - -- -+#define SHOW_CENTER 1 - /* - * Frame buffer device initialization and setup routines - */ -@@ -520,6 +520,11 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, - image.dy = y; - } - -+#if SHOW_CENTER -+image.dx = (info->var.xres - logo->width) / 2; -+image.dy = (info->var.yres - logo->height) / 2; -+#endif -+ - image.width = logo->width; - image.height = logo->height; - --- -2.34.1 - diff --git a/sysdrv/tools/board/kernel/kernel-drivers-video-logo_linux_clut224.ppm b/sysdrv/tools/board/kernel/kernel-drivers-video-logo_linux_clut224.ppm deleted file mode 100644 index 25760e00a..000000000 --- a/sysdrv/tools/board/kernel/kernel-drivers-video-logo_linux_clut224.ppm +++ /dev/null @@ -1,4503 +0,0 @@ -P3 -300 90 -255 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 -3 0 0 3 0 0 3 0 0 1 0 0 1 0 0 1 1 1 -2 1 5 1 0 5 2 0 5 2 0 1 5 0 0 5 0 0 -7 0 0 4 0 1 1 1 3 0 2 6 0 0 2 0 0 2 -0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -0 0 2 1 1 3 2 0 3 2 0 3 1 0 5 0 1 3 -0 1 0 0 1 0 1 2 0 4 0 0 5 0 0 5 0 0 -4 1 5 3 1 7 2 3 8 0 2 6 0 2 6 0 2 4 -0 2 1 0 2 4 0 0 4 0 0 5 0 0 5 0 0 4 -1 0 0 4 0 0 2 0 5 1 0 6 2 3 13 2 3 8 -0 0 4 1 0 0 4 0 0 6 0 0 4 1 3 2 0 5 -0 0 4 0 0 2 0 0 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 2 -1 0 6 1 0 6 1 0 5 0 0 0 1 0 0 4 0 0 -4 0 1 4 1 3 0 0 2 0 0 2 0 0 2 0 0 0 -1 0 0 1 0 0 1 0 0 0 0 2 0 0 2 0 0 2 -0 0 2 0 1 3 1 1 3 2 0 3 2 0 1 2 0 1 -0 0 0 0 0 0 2 1 0 2 1 0 4 0 1 4 0 1 -4 1 5 2 0 5 1 0 5 0 1 3 0 1 3 0 2 1 -1 1 1 1 1 1 1 1 3 1 0 5 0 0 4 0 0 2 -2 1 0 2 1 0 2 0 3 2 0 5 1 0 6 1 0 6 -0 0 2 0 0 0 2 1 0 2 1 0 4 1 3 2 0 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 0 0 2 -0 0 2 0 2 1 0 2 1 0 0 0 1 0 5 0 0 5 -1 0 6 1 0 6 0 2 4 0 1 2 0 1 0 0 1 0 -0 0 5 1 0 6 3 0 2 3 0 0 3 0 0 3 0 0 -3 0 0 3 0 0 4 0 0 2 0 1 0 0 2 0 0 2 -0 2 4 0 2 6 0 1 3 1 1 0 3 1 0 4 0 0 -3 0 0 3 0 0 2 0 3 2 0 5 1 1 3 1 1 3 -1 1 0 1 2 0 2 1 0 4 0 0 5 0 0 7 0 0 -5 0 0 5 0 0 2 1 0 2 1 0 4 0 1 4 0 1 -2 1 0 2 1 0 2 0 1 4 1 3 4 1 3 3 0 0 -1 1 0 0 2 0 0 2 0 0 1 0 0 0 0 1 0 0 -1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 2 0 0 5 0 0 5 -0 2 6 0 2 1 0 2 1 2 0 1 3 0 4 2 0 5 -1 0 6 0 0 5 0 2 4 0 2 2 0 1 0 0 1 2 -0 0 5 0 0 5 3 0 2 3 0 0 3 0 0 3 0 0 -3 0 0 4 0 0 5 0 0 4 0 0 1 0 0 0 0 2 -0 2 6 0 2 6 0 2 6 1 1 1 3 0 0 4 0 0 -4 0 0 4 0 2 2 0 5 1 0 6 0 2 6 0 2 4 -0 2 0 1 2 0 5 1 0 7 1 0 8 0 0 7 0 0 -5 0 0 5 0 0 3 0 0 1 0 0 2 0 1 2 0 1 -1 1 0 1 1 0 4 0 0 5 0 0 7 0 0 5 0 0 -1 2 0 0 3 0 0 2 0 0 2 0 0 1 0 0 0 0 -1 2 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 4 1 0 6 2 3 8 -0 2 6 0 2 1 2 1 0 5 0 0 6 1 3 6 1 3 -2 0 5 0 2 4 0 2 2 0 2 2 0 1 0 0 0 0 -0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 2 1 0 4 0 0 5 0 0 3 0 0 0 0 2 -0 2 6 0 2 6 2 3 8 0 2 6 1 0 2 4 0 0 -4 0 0 4 0 0 1 0 5 1 0 6 0 2 6 0 2 6 -0 0 2 1 0 0 5 1 0 5 1 0 2 2 0 1 1 1 -1 1 3 1 0 5 1 0 5 1 0 5 0 0 2 0 1 2 -0 1 0 0 2 0 4 0 0 7 0 0 8 0 0 7 0 0 -2 2 0 0 3 0 0 2 0 0 2 2 0 1 2 0 1 2 -0 2 1 0 3 0 0 1 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 2 1 0 6 1 0 6 -0 2 4 0 3 0 2 1 0 5 0 0 6 1 3 6 1 3 -2 0 3 0 1 3 0 1 2 0 1 0 0 1 0 0 0 0 -1 0 0 1 0 0 0 0 0 0 1 0 0 0 2 0 0 2 -0 0 2 0 0 0 4 0 0 4 0 0 3 0 0 2 0 3 -0 2 6 0 2 6 1 0 6 1 0 6 1 0 5 3 0 2 -5 0 0 4 0 1 0 0 4 0 0 5 1 0 6 0 2 6 -0 0 4 1 0 2 2 1 0 1 1 0 0 2 0 0 2 1 -0 2 6 0 2 6 1 0 6 1 0 6 0 0 5 0 2 4 -0 2 2 0 2 1 2 1 0 5 0 0 7 0 0 5 0 0 -2 1 0 0 2 0 0 1 2 0 2 4 0 0 5 0 0 4 -0 2 4 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 4 1 3 2 0 3 -1 1 1 0 2 1 1 1 1 2 0 3 3 0 4 3 0 2 -4 0 1 2 0 1 0 0 0 0 0 0 0 0 2 0 0 2 -0 0 2 1 1 1 0 0 0 0 0 2 0 0 4 0 0 4 -0 0 4 0 0 4 0 0 2 1 0 0 4 0 0 4 0 1 -2 0 1 2 0 3 1 1 3 0 0 2 0 0 2 1 0 2 -2 0 1 2 1 0 0 0 0 0 0 2 1 0 5 1 0 6 -1 0 6 1 0 5 1 0 5 0 1 3 0 2 1 0 2 1 -0 2 1 0 2 6 1 0 6 1 0 6 1 0 6 0 0 5 -0 2 6 0 2 6 0 2 6 2 0 5 4 1 5 4 1 3 -4 1 3 2 0 3 1 0 6 1 0 6 3 1 7 4 1 5 -6 1 3 4 0 0 1 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 2 1 0 -2 1 0 2 1 0 0 0 2 1 1 3 1 0 5 2 0 3 -4 0 1 4 0 0 4 0 0 3 0 0 1 0 2 1 0 2 -1 1 3 1 1 3 4 0 1 4 0 1 1 0 2 1 0 2 -1 0 5 0 0 4 0 0 2 0 0 2 2 0 1 2 0 1 -4 0 0 4 0 0 4 0 0 1 0 0 1 0 0 0 0 0 -1 1 1 1 1 0 0 0 0 1 0 0 2 0 3 2 0 5 -1 0 6 1 0 6 0 2 6 1 2 4 2 2 0 1 2 0 -1 1 0 1 1 1 0 0 5 0 0 5 0 2 6 0 2 6 -0 2 6 0 2 6 0 2 6 1 0 6 2 0 5 4 1 5 -3 0 0 3 0 0 2 0 5 2 0 5 3 1 7 4 1 5 -7 0 0 6 0 0 1 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 7 5 3 -7 1 0 7 1 0 10 9 7 1 1 1 8 8 8 2 1 5 -4 0 2 9 1 3 10 1 0 8 0 0 5 0 0 6 0 0 -7 2 6 4 1 3 7 0 0 6 0 0 11 1 0 14 1 4 -9 1 3 4 0 0 2 0 3 3 4 7 0 0 4 0 0 2 -1 0 0 3 0 0 4 0 0 4 0 0 3 0 0 1 0 0 -0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 0 0 2 -0 0 4 0 2 4 2 3 8 2 0 1 9 1 0 14 1 0 -10 1 0 4 0 0 3 3 3 2 5 5 0 2 0 5 5 3 -3 3 1 0 1 0 0 2 6 2 3 8 0 0 4 4 0 0 -7 1 0 3 0 0 0 0 0 0 1 2 2 3 8 2 3 8 -2 1 0 4 0 0 1 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 4 4 2 5 5 3 -3 3 1 3 0 0 7 5 3 2 2 0 4 1 3 10 9 7 -9 1 3 11 1 0 14 1 0 14 1 0 14 1 0 11 1 0 -6 1 3 4 1 5 4 1 3 15 7 8 11 1 0 7 0 0 -8 0 0 9 4 5 4 1 5 0 0 4 0 0 5 0 0 4 -0 0 4 1 0 0 4 0 0 4 0 0 3 0 0 1 0 0 -0 0 2 0 0 2 0 0 0 1 0 0 1 0 0 0 0 0 -0 1 2 0 1 2 3 3 5 8 8 8 8 0 0 7 0 0 -17 6 0 11 1 0 1 0 0 8 10 3 15 7 8 10 7 0 -6 0 0 7 0 0 9 4 5 9 4 5 7 2 6 9 4 5 -7 1 0 5 1 0 3 3 1 2 5 5 0 2 6 0 2 4 -2 2 0 6 5 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 4 4 2 3 3 1 -7 7 7 0 0 0 2 2 0 7 5 3 7 1 0 10 1 0 -18 0 0 22 1 2 26 1 0 26 1 0 17 1 0 11 1 0 -8 3 8 7 11 16 1 0 6 2 3 8 1 2 4 3 0 2 -7 1 0 4 0 0 3 0 0 7 7 7 0 0 4 0 0 5 -0 0 5 0 0 5 0 0 4 1 0 2 4 1 3 1 0 2 -0 0 2 0 0 2 0 0 2 0 0 2 0 0 0 0 1 0 -0 1 0 0 2 0 0 1 0 4 8 7 8 9 10 6 6 6 -4 1 3 14 1 4 14 1 0 10 1 0 18 0 0 22 1 2 -26 1 0 26 1 0 26 1 0 17 1 0 9 1 3 8 3 8 -4 1 3 1 0 0 5 1 0 7 5 3 6 4 5 2 0 1 -3 3 3 4 4 2 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 0 0 4 0 0 6 5 0 -4 8 7 1 3 4 8 10 3 11 1 0 18 0 0 48 4 0 -48 4 0 74 34 6 107 69 8 104 34 7 72 12 0 48 4 0 -26 1 0 22 1 2 10 10 9 2 3 8 0 0 5 0 0 5 -3 1 7 4 1 5 4 0 1 3 0 0 3 0 2 0 0 4 -0 0 5 0 0 5 0 0 5 0 0 4 2 0 3 2 0 3 -1 0 2 0 0 2 0 0 4 0 0 4 0 0 2 1 1 1 -1 1 0 0 2 0 4 8 7 0 2 2 0 2 6 5 7 10 -9 1 0 14 1 0 26 1 0 35 1 0 48 4 0 74 34 6 -104 34 7 104 34 7 72 12 0 48 4 0 26 1 0 22 1 2 -5 0 0 4 1 5 5 1 0 7 1 0 11 1 0 9 4 5 -3 3 3 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 0 0 7 0 0 7 5 3 -0 2 6 4 8 7 13 14 7 18 0 0 48 4 0 143 69 23 -183 101 57 210 113 41 210 113 41 216 104 20 210 113 41 183 98 20 -104 34 7 48 4 0 22 1 2 9 1 3 8 3 14 7 11 16 -2 3 13 2 3 13 8 8 8 5 0 0 7 0 0 4 0 0 -0 1 3 0 2 4 0 2 4 0 1 2 1 1 0 2 1 0 -1 0 0 0 0 2 0 0 4 0 0 4 1 1 3 2 0 3 -4 0 1 2 0 3 0 2 6 7 11 16 2 5 5 2 1 0 -25 6 3 30 1 2 72 12 0 143 69 23 210 113 41 210 113 41 -210 113 41 210 113 41 210 113 41 183 101 57 104 34 7 35 1 0 -14 1 0 8 8 8 6 6 6 3 0 0 10 1 0 11 1 0 -2 2 2 3 3 5 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 3 0 0 11 1 0 5 0 0 -2 3 8 2 3 8 10 1 0 48 4 0 143 69 23 210 113 41 -216 104 20 216 104 20 230 106 20 230 106 20 230 106 20 229 114 40 -210 113 41 183 98 20 72 12 0 35 1 0 14 1 0 8 3 8 -2 3 13 2 3 13 3 4 7 15 7 8 8 0 0 7 0 0 -1 1 1 0 2 4 0 2 4 0 2 2 1 2 0 2 1 0 -0 0 2 0 0 4 0 0 2 2 0 3 4 1 3 4 1 3 -4 1 3 2 0 5 8 9 10 1 0 0 17 6 0 22 1 2 -35 1 0 104 34 7 183 101 57 210 113 41 216 104 20 232 104 4 -230 106 20 230 106 20 230 106 20 210 113 41 183 98 20 143 69 23 -30 1 2 8 0 0 6 6 6 3 0 2 8 0 0 10 1 0 -1 0 0 8 9 10 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 0 0 11 1 0 3 0 0 -7 11 16 5 3 3 35 1 0 143 69 23 210 113 41 239 111 20 -230 106 20 230 106 20 230 106 20 230 106 20 232 104 4 222 105 4 -216 104 20 216 104 20 183 98 20 104 34 7 48 4 0 18 0 0 -8 9 10 2 3 13 1 0 5 4 0 0 8 0 0 8 0 0 -2 0 1 0 2 4 0 2 6 0 2 4 2 1 0 2 1 0 -0 0 4 0 0 4 3 0 2 5 0 0 7 0 0 5 0 0 -2 0 5 2 0 5 3 0 2 26 16 7 26 1 0 48 4 0 -143 69 23 210 113 41 216 104 20 230 106 20 241 109 9 232 104 4 -216 104 20 216 104 20 230 106 20 230 106 20 229 114 40 210 113 41 -104 34 7 22 1 2 7 1 0 3 4 7 5 0 0 9 3 6 -1 0 2 7 7 7 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 0 0 8 0 0 8 1 5 -8 3 14 11 1 0 74 34 6 183 101 57 239 111 20 239 103 3 -241 109 9 232 104 4 222 105 4 230 106 20 232 104 4 232 104 4 -232 104 4 230 106 20 230 106 20 210 113 41 143 69 23 72 12 0 -18 0 0 8 0 0 6 1 3 5 0 0 8 0 0 7 1 0 -2 0 1 0 0 4 0 2 6 0 0 5 2 0 1 2 1 0 -0 0 4 0 0 4 1 0 2 4 0 0 7 0 0 7 0 0 -4 1 3 8 0 0 22 1 2 35 1 0 104 34 7 183 101 57 -210 113 41 216 104 20 232 104 4 239 103 3 239 103 3 232 104 4 -230 106 20 230 106 20 222 105 4 232 104 4 232 104 4 216 104 20 -183 101 57 48 4 0 11 1 0 8 3 14 2 0 5 8 3 14 -4 1 3 4 1 5 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 0 0 9 1 3 9 1 3 -15 7 8 26 1 0 143 69 23 210 113 41 222 105 4 239 103 3 -239 103 3 232 104 4 232 104 4 241 109 9 239 103 3 239 103 3 -232 104 4 222 105 4 230 106 20 216 104 20 210 113 41 183 101 57 -104 34 7 30 1 2 18 0 0 14 1 0 9 1 0 7 1 0 -9 4 5 6 6 6 1 0 6 7 11 16 7 11 16 4 1 5 -3 0 4 3 4 7 2 5 5 0 2 2 9 3 6 14 1 4 -18 0 0 26 1 0 48 4 0 143 69 23 210 113 41 229 114 40 -216 104 20 230 106 20 239 103 3 239 103 3 239 103 3 239 103 3 -222 105 4 222 105 4 232 104 4 232 104 4 232 104 4 216 104 20 -210 113 41 74 34 6 26 1 0 3 1 7 3 1 7 7 2 6 -5 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 0 0 5 0 0 9 1 3 -18 1 4 35 1 0 143 100 31 216 104 20 222 105 4 239 103 3 -239 103 3 241 109 9 232 104 4 232 104 4 239 103 3 239 103 3 -232 104 4 241 109 9 241 109 9 239 111 20 222 105 4 216 104 20 -210 113 41 143 69 23 48 4 0 18 0 0 25 6 3 8 0 0 -4 0 0 3 0 0 7 11 16 7 11 16 0 0 2 20 16 18 -15 7 8 1 0 2 2 5 5 8 8 8 10 1 0 18 0 0 -48 4 0 72 12 0 143 100 31 210 113 41 229 114 40 230 106 20 -232 104 4 232 104 4 241 109 9 239 103 3 239 103 3 241 109 9 -232 104 4 232 104 4 239 112 3 232 104 4 232 104 4 230 106 20 -210 113 41 104 34 7 30 1 2 8 1 5 8 3 8 7 2 6 -4 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 11 1 0 -17 1 0 48 4 0 183 101 57 216 104 20 230 106 20 241 109 9 -241 109 9 232 104 4 222 105 4 222 105 4 232 104 4 239 112 3 -241 109 9 239 103 3 241 109 9 232 104 4 241 109 9 239 111 20 -216 104 20 210 113 41 143 100 31 74 34 6 30 1 2 22 1 2 -10 1 0 15 7 8 4 1 5 2 0 3 15 7 8 5 1 0 -6 1 3 6 4 5 6 4 5 14 1 4 26 1 0 48 4 0 -104 34 7 183 101 57 217 124 25 230 106 20 232 104 4 232 104 4 -232 104 4 232 104 4 232 104 4 239 112 3 239 112 3 241 109 9 -241 109 9 232 104 4 232 104 4 232 104 4 232 104 4 230 124 24 -210 113 41 143 69 23 35 1 0 14 1 0 9 1 3 8 1 5 -4 1 3 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 11 1 0 -18 0 0 74 34 6 210 113 41 230 106 20 230 106 20 241 109 9 -241 109 9 232 104 4 232 104 4 223 116 8 222 105 4 232 104 4 -239 103 3 241 109 9 241 109 9 232 104 4 239 103 3 239 103 3 -232 104 4 230 106 20 210 113 41 183 101 57 104 34 7 35 1 0 -26 1 0 18 0 0 6 0 0 7 5 3 3 0 0 10 9 7 -3 0 0 10 1 0 25 6 3 26 1 0 48 4 0 107 69 8 -210 113 41 217 124 25 223 116 8 232 104 4 239 112 3 239 112 3 -239 112 3 232 104 4 232 104 4 239 112 3 232 104 4 232 104 4 -241 109 9 241 109 9 241 109 9 232 104 4 222 105 4 230 106 20 -217 124 25 183 98 20 48 4 0 17 1 0 11 1 0 8 1 5 -4 1 3 3 0 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 1 0 0 6 1 6 5 0 -22 1 2 74 34 6 215 129 57 230 106 20 239 111 20 239 103 3 -239 103 3 241 109 9 232 104 4 232 104 4 239 126 20 239 111 20 -241 109 9 239 103 3 232 104 4 239 111 20 232 104 4 232 104 4 -241 109 9 223 116 8 223 116 8 221 134 40 210 113 41 143 69 23 -72 12 0 30 1 2 25 6 3 7 1 0 5 5 5 4 4 4 -7 5 3 18 0 0 35 1 0 104 34 7 183 98 20 221 134 40 -230 106 20 230 106 20 230 106 20 232 104 4 232 104 4 239 112 3 -241 109 9 241 109 9 241 109 9 239 111 20 230 124 24 222 105 4 -232 104 4 241 109 9 232 104 4 239 112 3 241 109 9 230 106 20 -216 104 20 183 101 57 48 4 0 17 1 0 10 1 0 6 1 3 -4 1 3 4 1 5 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 1 0 0 6 1 2 2 0 -22 1 2 74 34 6 210 113 41 230 106 20 239 111 20 232 104 4 -239 112 3 239 112 3 232 104 4 230 106 20 216 104 20 216 104 20 -229 114 40 239 111 20 230 106 20 230 106 20 241 109 9 239 112 3 -232 104 4 239 112 3 241 109 9 222 105 4 230 106 20 210 113 41 -183 101 57 104 34 7 35 1 0 25 6 3 8 0 0 11 1 0 -22 1 2 48 4 0 107 69 8 210 113 41 221 134 40 239 111 20 -239 111 20 239 111 20 239 111 20 239 111 20 241 109 9 241 109 9 -239 103 3 239 111 20 230 106 20 216 104 20 216 104 20 210 113 41 -230 106 20 241 109 9 232 104 4 232 104 4 241 109 9 222 105 4 -217 124 25 183 101 57 35 1 0 14 1 0 8 0 0 7 1 0 -2 0 1 6 4 5 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 2 1 0 3 0 2 2 0 -22 1 2 72 12 0 210 113 41 230 106 20 239 111 20 239 112 3 -239 112 3 232 104 4 239 111 20 217 124 25 143 69 23 104 34 7 -183 98 20 215 129 57 230 124 24 232 104 4 232 104 4 239 112 3 -240 120 3 239 103 3 232 104 4 241 109 9 239 111 20 230 124 24 -221 134 40 210 113 41 107 69 8 48 4 0 30 1 2 30 1 2 -72 12 0 143 100 31 229 114 40 230 106 20 222 105 4 232 104 4 -241 109 9 241 109 9 232 104 4 241 109 9 241 109 9 223 116 8 -230 106 20 229 114 40 210 113 41 143 69 23 104 34 7 183 98 20 -216 104 20 239 112 3 243 126 10 239 112 3 239 112 3 223 116 8 -210 113 41 143 100 31 35 1 0 8 0 0 2 2 0 4 4 2 -3 0 2 6 4 5 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 2 1 0 1 0 5 1 0 -18 0 0 72 12 0 210 113 41 230 124 24 241 109 9 241 109 9 -239 112 3 241 109 9 223 116 8 210 113 41 143 69 23 48 4 0 -72 12 0 143 100 31 210 113 41 230 124 24 239 111 20 232 104 4 -239 112 3 243 126 10 241 109 9 239 112 3 239 112 3 232 104 4 -223 116 8 230 124 24 215 129 57 183 98 20 104 34 7 104 34 7 -198 136 53 210 113 41 230 106 20 241 109 9 239 112 3 241 109 9 -241 109 9 241 109 9 232 104 4 223 116 8 223 116 8 223 116 8 -229 114 40 210 113 41 143 69 23 48 4 0 72 12 0 183 101 57 -230 124 24 232 104 4 240 120 3 232 104 4 239 112 3 230 124 24 -221 134 40 143 69 23 30 1 2 9 1 3 3 3 1 4 4 2 -3 0 4 6 4 5 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 3 3 -11 1 0 48 4 0 210 113 41 230 124 24 239 111 20 239 112 3 -241 109 9 243 126 10 223 116 8 210 113 41 143 69 23 35 1 0 -30 1 2 35 1 0 107 69 8 183 101 57 221 134 40 230 124 24 -241 109 9 241 109 9 239 112 3 232 104 4 240 120 3 239 112 3 -239 112 3 223 116 8 230 124 24 230 124 24 229 114 40 217 124 25 -217 124 25 230 124 24 223 116 8 239 112 3 239 112 3 239 112 3 -239 112 3 240 120 3 240 120 3 223 116 8 217 124 25 221 134 40 -183 101 57 104 34 7 30 1 2 35 1 0 48 4 0 198 136 53 -217 124 25 240 120 3 239 112 3 239 112 3 240 120 3 223 116 8 -210 113 41 143 69 23 26 1 0 7 1 0 3 3 1 0 3 0 -3 3 5 2 0 5 0 0 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 1 1 8 8 8 4 4 4 0 0 0 -3 3 3 0 0 0 1 1 1 3 3 3 0 0 0 0 0 0 -3 3 3 3 3 3 2 2 2 4 4 4 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 1 1 8 8 8 4 4 4 0 0 0 -3 3 3 0 0 0 1 1 1 3 3 3 0 0 0 0 0 0 -3 3 3 3 3 3 2 2 2 4 4 4 3 3 3 0 0 0 -1 1 1 4 4 4 0 0 0 3 3 3 5 5 5 2 2 2 -1 1 1 0 0 0 6 6 6 1 1 1 0 0 0 1 1 1 -0 0 0 0 0 0 1 1 1 3 3 3 1 1 1 0 0 0 -2 2 2 6 6 6 3 3 3 0 0 0 0 0 0 1 1 1 -4 4 4 0 0 0 0 0 0 5 5 5 2 2 2 0 0 0 -2 2 2 0 0 0 0 0 0 5 5 5 5 5 5 0 0 0 -2 2 2 10 10 9 7 7 7 0 0 0 3 3 3 0 0 0 -1 1 1 6 6 6 0 0 0 4 4 4 0 0 0 3 3 3 -6 6 6 2 2 2 0 0 0 1 1 1 3 3 3 1 1 1 -0 0 0 5 5 5 1 1 1 1 1 1 0 0 0 4 4 4 -2 2 2 4 4 4 3 3 3 0 0 0 2 2 2 7 7 7 -8 8 8 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 1 1 1 4 4 4 1 1 1 0 0 0 -0 0 0 5 5 5 6 6 6 2 2 2 1 1 1 0 0 0 -0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -6 6 6 0 0 0 3 3 3 3 3 3 2 2 2 0 0 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 7 7 7 -4 4 4 0 0 0 2 2 2 1 1 1 0 0 0 1 1 1 -2 2 2 6 6 6 0 0 0 1 1 1 2 2 2 8 8 8 -1 1 1 1 1 1 0 0 0 1 1 1 6 6 6 4 4 4 -0 0 0 0 0 0 5 5 5 0 0 0 6 6 6 4 4 4 -0 0 0 6 6 6 4 4 4 0 0 0 0 0 0 0 0 0 -3 3 3 7 7 7 2 2 2 0 0 0 2 2 2 2 2 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 9 3 3 -11 1 0 35 1 0 210 113 41 230 124 24 239 111 20 241 109 9 -239 112 3 240 120 3 223 116 8 217 124 25 143 100 31 30 1 2 -22 1 2 18 0 0 35 1 0 104 34 7 183 98 20 210 113 41 -229 114 40 230 124 24 223 116 8 239 126 20 223 116 8 240 120 3 -243 126 10 240 120 3 239 112 3 241 109 9 241 109 9 239 111 20 -223 116 8 223 116 8 240 120 3 239 112 3 240 120 3 243 126 10 -240 120 3 223 116 8 230 124 24 217 124 25 210 113 41 143 69 23 -48 4 0 30 1 2 25 6 3 18 0 0 72 12 0 198 136 53 -217 124 25 240 120 3 240 120 3 239 112 3 240 120 3 223 116 8 -210 113 41 143 69 23 26 1 0 8 0 0 3 3 1 2 2 0 -3 3 5 2 0 3 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 4 4 2 2 2 0 0 0 2 2 2 0 0 0 0 0 0 -3 3 3 1 1 1 0 0 0 2 2 2 1 1 1 1 1 1 -3 3 3 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 4 4 2 2 2 0 0 0 2 2 2 0 0 0 0 0 0 -3 3 3 1 1 1 0 0 0 2 2 2 1 1 1 1 1 1 -3 3 3 1 1 1 0 0 0 1 1 1 7 7 7 2 2 2 -0 0 0 0 0 0 1 1 1 0 0 0 2 2 2 0 0 0 -2 2 2 5 5 5 0 0 0 1 1 1 7 7 7 5 5 5 -5 5 5 1 1 1 0 0 0 3 3 3 4 4 4 3 3 3 -1 1 1 0 0 0 0 0 0 2 2 2 5 5 5 1 1 1 -2 2 2 3 3 3 3 3 3 2 2 2 0 0 0 4 4 4 -3 3 3 2 2 2 0 0 0 0 0 0 2 2 2 3 3 3 -4 4 4 0 0 0 0 0 0 2 2 2 10 10 9 3 3 3 -1 1 1 6 6 6 0 0 0 0 0 0 2 2 2 0 0 0 -0 0 0 1 1 1 3 3 3 4 4 4 3 3 3 0 0 0 -5 5 5 8 8 8 0 0 0 0 0 0 4 4 4 8 8 8 -0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 -2 2 2 5 5 5 3 3 3 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 7 7 7 -5 5 5 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 -4 4 4 7 7 7 5 5 5 0 0 0 0 0 0 3 3 3 -0 0 0 4 4 4 5 5 5 0 0 0 1 1 1 4 4 4 -3 3 3 0 0 0 2 2 2 1 1 1 0 0 0 0 0 0 -0 0 0 6 6 6 9 9 9 0 0 0 7 7 7 6 6 6 -0 0 0 2 2 2 3 3 3 3 3 3 0 0 0 3 3 3 -1 1 1 8 8 8 8 8 8 2 2 2 0 0 0 0 0 0 -3 3 3 9 9 9 0 0 0 1 1 1 3 3 3 0 0 0 -1 1 1 1 1 1 0 0 0 1 1 1 8 8 8 1 1 1 -0 0 0 4 4 4 5 5 5 4 4 4 4 4 4 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 9 3 3 -11 1 0 35 1 0 183 98 20 230 124 24 239 111 20 239 112 3 -239 112 3 240 120 3 240 120 3 217 124 25 143 100 31 35 1 0 -22 1 2 17 1 0 22 1 2 22 1 2 48 4 0 143 69 23 -210 113 41 221 134 40 239 126 20 223 116 8 239 126 20 223 116 8 -223 116 8 240 120 3 243 126 10 239 112 3 241 109 9 239 126 20 -239 126 20 240 120 3 239 112 3 240 120 3 240 120 3 240 120 3 -223 116 8 217 124 25 221 134 40 198 136 53 104 34 7 35 1 0 -26 1 0 18 0 0 11 1 0 33 6 2 72 12 0 215 129 57 -217 124 25 240 120 3 240 120 3 239 112 3 240 120 3 223 116 8 -217 124 25 107 69 8 30 1 2 11 1 0 9 1 0 2 1 0 -3 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 1 1 1 2 2 2 4 4 4 3 3 3 2 2 2 -3 3 3 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -3 3 3 2 2 2 2 2 2 4 4 4 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 1 1 1 2 2 2 4 4 4 3 3 3 2 2 2 -3 3 3 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -3 3 3 2 2 2 2 2 2 4 4 4 0 0 0 1 1 1 -6 6 6 0 0 0 7 7 7 0 0 0 3 3 3 5 5 5 -0 0 0 9 9 9 0 0 0 3 3 3 5 5 5 0 0 0 -2 2 2 1 1 1 9 9 9 5 5 5 0 0 0 0 0 0 -1 1 1 0 0 0 1 1 1 6 6 6 0 0 0 5 5 5 -4 4 4 0 0 0 0 0 0 4 4 4 4 4 4 0 0 0 -3 3 3 6 6 6 3 3 3 2 2 2 0 0 0 0 0 0 -5 5 5 1 1 1 4 4 4 3 3 3 7 7 7 1 1 1 -0 0 0 3 3 3 1 1 1 2 2 2 6 6 6 1 1 1 -0 0 0 1 1 1 0 0 0 0 0 0 5 5 5 9 9 9 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 5 5 5 -2 2 2 4 4 4 0 0 0 4 4 4 4 4 4 5 5 5 -0 0 0 0 0 0 0 0 0 2 2 2 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 5 5 5 1 1 1 4 4 4 3 3 3 -0 0 0 0 0 0 4 4 4 6 6 6 6 6 6 0 0 0 -0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 5 5 5 -6 6 6 5 5 5 0 0 0 1 1 1 4 4 4 4 4 4 -1 1 1 4 4 4 0 0 0 2 2 2 7 7 7 6 6 6 -0 0 0 3 3 3 5 5 5 0 0 0 0 0 0 4 4 4 -0 0 0 0 0 0 2 2 2 1 1 1 0 0 0 8 8 8 -0 0 0 4 4 4 3 3 3 0 0 0 0 0 0 2 2 2 -1 1 1 0 0 0 4 4 4 6 6 6 0 0 0 0 0 0 -6 6 6 7 7 7 1 1 1 4 4 4 4 4 4 0 0 0 -1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 7 1 0 -10 1 0 35 1 0 183 98 20 230 124 24 239 126 20 240 120 3 -240 120 3 240 120 3 240 120 3 217 124 25 183 101 57 35 1 0 -22 1 2 14 1 0 10 1 0 14 1 0 26 1 0 35 1 0 -104 34 7 183 101 57 217 124 25 230 124 24 223 116 8 223 116 8 -243 126 10 240 120 3 240 120 3 239 112 3 241 109 9 239 111 20 -239 112 3 243 126 10 243 126 10 240 120 3 239 112 3 223 116 8 -230 124 24 215 129 57 143 100 31 74 34 6 35 1 0 30 1 2 -14 1 0 10 1 0 15 7 8 26 1 0 74 34 6 215 129 57 -217 124 25 240 120 3 240 120 3 240 120 3 240 120 3 227 127 8 -221 134 40 107 69 8 30 1 2 14 1 0 10 1 0 4 0 0 -3 3 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 2 2 4 4 4 3 3 3 0 0 0 0 0 0 1 1 1 -5 5 5 6 6 6 5 5 5 4 4 4 1 1 1 0 0 0 -1 1 1 4 4 4 4 4 4 3 3 3 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 2 2 4 4 4 3 3 3 0 0 0 0 0 0 1 1 1 -5 5 5 6 6 6 5 5 5 4 4 4 1 1 1 0 0 0 -1 1 1 4 4 4 4 4 4 3 3 3 1 1 1 1 1 1 -7 7 7 1 1 1 8 8 8 0 0 0 2 2 2 0 0 0 -0 0 0 5 5 5 4 4 4 5 5 5 4 4 4 3 3 3 -0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 2 2 2 -4 4 4 3 3 3 0 0 0 0 0 0 3 3 3 1 1 1 -0 0 0 10 10 9 10 10 9 0 0 0 0 0 0 3 3 3 -0 0 0 2 2 2 0 0 0 5 5 5 5 5 5 0 0 0 -2 2 2 4 4 4 9 9 9 0 0 0 0 0 0 0 0 0 -2 2 2 1 1 1 0 0 0 4 4 4 0 0 0 0 0 0 -3 3 3 4 4 4 2 2 2 0 0 0 0 0 0 0 0 0 -1 1 1 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 -0 0 0 1 1 1 8 8 8 1 1 1 0 0 0 5 5 5 -6 6 6 4 4 4 0 0 0 3 3 3 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 7 7 7 2 2 2 -0 0 0 3 3 3 6 6 6 0 0 0 1 1 1 2 2 2 -2 2 2 5 5 5 5 5 5 1 1 1 1 1 1 0 0 0 -0 0 0 5 5 5 1 1 1 4 4 4 2 2 2 3 3 3 -0 0 0 1 1 1 0 0 0 0 0 0 2 2 2 3 3 3 -2 2 2 0 0 0 0 0 0 5 5 5 2 2 2 5 5 5 -4 4 4 3 3 3 2 2 2 1 1 1 1 1 1 6 6 6 -4 4 4 3 3 3 1 1 1 1 1 1 4 4 4 5 5 5 -2 2 2 0 0 0 2 2 2 2 2 2 1 1 1 4 4 4 -5 5 5 1 1 1 0 0 0 1 1 1 2 2 2 0 0 0 -1 1 1 0 0 0 0 0 0 2 2 2 3 3 3 6 6 6 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 7 1 0 -8 0 0 35 1 0 143 100 31 217 124 25 239 126 20 240 120 3 -227 127 8 227 127 8 227 127 8 217 124 25 183 101 57 35 1 0 -17 1 0 8 0 0 7 0 0 26 16 7 14 1 0 17 1 0 -30 1 2 72 12 0 143 100 31 215 129 57 221 134 40 230 124 24 -240 120 3 240 120 3 240 120 3 239 112 3 241 109 9 239 126 20 -239 112 3 243 126 10 240 120 3 223 116 8 239 126 20 221 134 40 -183 98 20 143 69 23 48 4 0 26 1 0 14 1 0 11 1 0 -10 9 7 2 2 0 3 0 0 33 6 2 104 34 7 210 113 41 -217 124 25 227 127 8 240 120 3 240 120 3 240 120 3 227 127 8 -221 134 40 104 34 7 30 1 2 11 1 0 10 1 0 5 0 0 -3 3 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 2 2 2 2 2 2 1 1 1 2 2 2 -1 1 1 0 0 0 3 3 3 5 5 5 4 4 4 1 1 1 -0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 2 2 2 2 2 2 1 1 1 2 2 2 -1 1 1 0 0 0 3 3 3 5 5 5 4 4 4 1 1 1 -0 0 0 1 1 1 1 1 1 0 0 0 5 5 5 0 0 0 -1 1 1 0 0 0 4 4 4 2 2 2 4 4 4 0 0 0 -8 8 8 0 0 0 2 2 2 0 0 0 0 0 0 10 10 9 -1 1 1 2 2 2 4 4 4 9 9 9 7 7 7 1 1 1 -0 0 0 1 1 1 2 2 2 4 4 4 3 3 3 6 6 6 -0 0 0 0 0 0 0 0 0 0 0 0 7 7 7 4 4 4 -7 7 7 7 7 7 1 1 1 0 0 0 5 5 5 5 5 5 -0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 4 4 4 -4 4 4 2 2 2 2 2 2 3 3 3 4 4 4 2 2 2 -1 1 1 0 0 0 1 1 1 7 7 7 9 9 9 4 4 4 -6 6 6 0 0 0 0 0 0 2 2 2 1 1 1 3 3 3 -5 5 5 0 0 0 2 2 2 2 2 2 2 2 2 5 5 5 -2 2 2 1 1 1 2 2 2 8 8 8 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 7 7 7 2 2 2 6 6 6 0 0 0 -1 1 1 3 3 3 3 3 3 0 0 0 0 0 0 6 6 6 -5 5 5 2 2 2 0 0 0 0 0 0 5 5 5 3 3 3 -0 0 0 8 8 8 0 0 0 0 0 0 0 0 0 10 10 9 -9 9 9 0 0 0 7 7 7 3 3 3 2 2 2 0 0 0 -3 3 3 7 7 7 0 0 0 5 5 5 2 2 2 0 0 0 -1 1 1 2 2 2 3 3 3 4 4 4 3 3 3 0 0 0 -7 7 7 3 3 3 1 1 1 2 2 2 0 0 0 0 0 0 -0 0 0 5 5 5 3 3 3 0 0 0 4 4 4 8 8 8 -0 0 0 0 0 0 6 6 6 10 10 9 1 1 1 0 0 0 -2 2 2 3 3 3 6 6 6 8 8 8 1 1 1 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 4 0 0 -8 0 0 35 1 0 143 69 23 221 134 40 230 124 24 240 120 3 -227 127 8 227 127 8 239 126 20 217 124 25 183 101 57 35 1 0 -17 1 0 8 0 0 26 16 7 5 1 0 2 0 3 6 1 3 -18 1 4 26 1 0 48 4 0 107 69 8 215 129 57 221 134 40 -230 124 24 239 126 20 243 126 10 240 120 3 239 126 20 239 126 20 -239 126 20 240 120 3 230 124 24 230 124 24 221 134 40 183 98 20 -104 34 7 35 1 0 18 0 0 18 1 4 8 1 5 3 0 0 -4 4 4 7 7 7 7 5 3 26 1 0 104 34 7 210 113 41 -217 124 25 227 127 8 240 120 3 240 120 3 240 120 3 230 124 24 -215 129 57 104 34 7 30 1 2 9 1 3 9 1 3 4 0 0 -3 3 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -10 10 9 0 0 0 1 1 1 3 3 3 1 1 1 2 2 2 -2 2 2 2 2 2 0 0 0 0 0 0 3 3 3 3 3 3 -0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -10 10 9 0 0 0 1 1 1 3 3 3 1 1 1 2 2 2 -2 2 2 2 2 2 0 0 0 0 0 0 3 3 3 3 3 3 -0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 4 4 4 -10 10 9 4 4 4 3 3 3 0 0 0 3 3 3 8 8 8 -0 0 0 2 2 2 8 8 8 9 9 9 0 0 0 5 5 5 -0 0 0 0 0 0 5 5 5 3 3 3 0 0 0 0 0 0 -3 3 3 5 5 5 3 3 3 2 2 2 0 0 0 4 4 4 -0 0 0 5 5 5 5 5 5 0 0 0 4 4 4 0 0 0 -0 0 0 2 2 2 8 8 8 0 0 0 0 0 0 4 4 4 -1 1 1 1 1 1 1 1 1 9 9 9 6 6 6 2 2 2 -0 0 0 0 0 0 4 4 4 0 0 0 2 2 2 3 3 3 -5 5 5 3 3 3 0 0 0 0 0 0 3 3 3 5 5 5 -2 2 2 1 1 1 6 6 6 5 5 5 2 2 2 0 0 0 -3 3 3 4 4 4 0 0 0 3 3 3 2 2 2 3 3 3 -0 0 0 5 5 5 1 1 1 0 0 0 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 5 5 5 0 0 0 4 4 4 1 1 1 -6 6 6 1 1 1 0 0 0 4 4 4 3 3 3 3 3 3 -0 0 0 1 1 1 6 6 6 8 8 8 7 7 7 0 0 0 -3 3 3 0 0 0 0 0 0 20 16 18 1 1 1 0 0 0 -4 4 4 6 6 6 0 0 0 3 3 3 10 10 9 2 2 2 -1 1 1 8 8 8 0 0 0 2 2 2 0 0 0 3 3 3 -8 8 8 4 4 4 1 1 1 0 0 0 2 2 2 2 2 2 -2 2 2 0 0 0 0 0 0 3 3 3 5 5 5 5 5 5 -4 4 4 1 1 1 6 6 6 0 0 0 5 5 5 1 1 1 -0 0 0 10 10 9 6 6 6 0 0 0 3 3 3 4 4 4 -7 7 7 0 0 0 0 0 0 0 0 0 0 0 0 6 6 6 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 2 3 1 7 2 0 5 -8 0 0 30 1 2 143 69 23 221 134 40 227 127 8 240 120 3 -243 126 10 243 126 10 243 126 10 230 124 24 198 136 53 48 4 0 -18 0 0 9 1 3 4 0 0 10 9 7 2 2 2 2 1 0 -7 0 0 14 1 0 26 1 0 30 1 2 74 34 6 143 100 31 -215 129 57 221 134 40 230 124 24 239 126 20 230 124 24 223 116 8 -230 124 24 230 124 24 221 134 40 210 113 41 143 69 23 72 12 0 -26 1 0 14 1 0 10 9 7 2 2 2 6 6 6 10 10 9 -4 1 3 4 1 3 8 3 8 22 1 2 104 34 7 215 129 57 -217 124 25 239 126 20 243 126 10 243 126 10 240 120 3 230 124 24 -215 129 57 104 34 7 22 1 2 2 0 1 6 1 3 2 0 3 -2 3 8 3 1 7 0 0 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 9 9 0 0 0 4 4 4 9 9 9 0 0 0 0 0 0 -1 1 1 6 6 6 10 10 9 2 2 2 0 0 0 4 4 4 -3 3 3 0 0 0 2 2 2 4 4 4 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 9 9 0 0 0 4 4 4 9 9 9 0 0 0 0 0 0 -1 1 1 6 6 6 10 10 9 2 2 2 0 0 0 4 4 4 -3 3 3 0 0 0 2 2 2 4 4 4 0 0 0 4 4 4 -4 4 4 0 0 0 10 10 9 3 3 3 1 1 1 5 5 5 -2 2 2 20 16 18 0 0 0 4 4 4 4 4 4 1 1 1 -6 6 6 6 6 6 4 4 4 1 1 1 2 2 2 8 8 8 -7 7 7 0 0 0 0 0 0 10 10 9 4 4 4 4 4 4 -10 10 9 65 52 28 65 52 28 9 9 9 1 1 1 1 1 1 -20 16 18 0 0 0 5 5 5 7 7 7 0 0 0 4 4 4 -0 0 0 1 1 1 5 5 5 3 3 3 0 0 0 7 7 7 -10 10 9 6 6 6 6 6 6 0 0 0 10 10 9 0 0 0 -0 0 0 7 7 7 8 8 8 2 2 2 1 1 1 4 4 4 -1 1 1 2 2 2 0 0 0 0 0 0 10 10 9 6 6 6 -0 0 0 1 1 1 9 9 9 6 6 6 0 0 0 10 10 9 -1 1 1 6 6 6 0 0 0 10 10 9 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 7 7 7 20 16 18 0 0 0 -3 3 3 3 3 3 0 0 0 2 2 2 6 6 6 6 6 6 -1 1 1 6 6 6 4 4 4 0 0 0 5 5 5 9 9 9 -1 1 1 2 2 2 20 16 18 69 70 68 20 16 18 1 1 1 -0 0 0 0 0 0 20 16 18 0 0 0 9 9 9 6 6 6 -0 0 0 3 3 3 0 0 0 3 3 3 3 3 3 7 7 7 -3 3 3 0 0 0 7 7 7 5 5 5 2 2 2 3 3 3 -2 2 2 6 6 6 8 8 8 3 3 3 0 0 0 3 3 3 -5 5 5 0 0 0 1 1 1 1 1 1 3 3 3 0 0 0 -5 5 5 7 7 7 0 0 0 20 16 18 0 0 0 0 0 0 -4 4 4 1 1 1 6 6 6 10 10 9 1 1 1 3 3 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 5 1 0 2 0 0 0 0 1 0 0 0 0 0 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 2 3 8 2 0 5 -8 0 0 30 1 2 143 69 23 217 124 25 230 124 24 243 126 10 -243 126 10 227 127 8 243 126 10 230 124 24 215 129 57 48 4 0 -18 0 0 4 0 2 4 1 3 3 3 5 6 6 6 3 3 3 -4 0 0 5 0 0 8 0 0 17 1 0 26 1 0 48 4 0 -104 34 7 183 101 57 215 129 57 221 134 40 210 113 41 215 129 57 -215 129 57 198 136 53 143 100 31 74 34 6 35 1 0 18 0 0 -9 1 3 3 1 7 6 6 6 4 4 4 1 0 0 5 0 0 -9 3 6 7 2 6 4 1 5 26 1 0 107 69 8 215 129 57 -230 124 24 239 126 20 239 126 20 239 126 20 243 126 10 230 124 24 -215 129 57 74 34 6 25 6 3 1 1 0 3 3 3 0 0 4 -2 3 8 0 2 6 0 0 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 20 16 18 82 82 81 126 126 126 132 133 128 126 126 124 -124 124 124 126 126 126 29 30 27 10 10 9 0 0 0 3 3 3 -5 5 5 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 20 16 18 82 82 81 126 126 126 132 133 128 126 126 124 -124 124 124 126 126 126 29 30 27 10 10 9 0 0 0 3 3 3 -5 5 5 0 0 0 0 0 0 1 1 1 6 6 6 1 1 1 -0 0 0 20 16 18 104 104 103 126 126 124 127 127 125 126 126 124 -127 127 125 119 119 117 20 16 18 1 1 1 5 5 5 0 0 0 -10 10 9 0 0 0 1 1 1 0 0 0 3 3 3 5 5 3 -0 0 0 7 5 3 69 70 68 124 124 124 164 164 161 203 203 202 -209 209 208 209 209 208 207 207 205 204 204 203 199 199 195 164 164 161 -104 104 103 20 16 18 0 0 0 5 5 5 1 1 1 6 6 6 -0 0 0 2 2 2 6 6 6 0 0 0 13 14 7 82 82 81 -124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 69 70 68 -6 6 6 0 0 0 5 5 5 3 3 3 0 0 0 1 1 1 -5 5 5 4 4 2 1 1 1 29 30 27 104 104 103 132 133 128 -126 126 126 126 126 126 119 119 117 132 133 128 126 126 126 119 119 117 -29 30 27 0 0 0 10 10 9 82 82 81 126 126 126 124 124 124 -124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 -124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 -124 124 124 124 124 124 127 127 125 127 127 125 104 104 103 20 16 18 -0 0 0 2 2 2 5 5 5 2 2 2 0 0 0 4 4 4 -2 2 2 3 3 3 0 0 0 13 14 7 86 87 84 154 154 152 -197 198 192 199 199 198 203 203 202 221 221 215 199 199 195 211 211 209 -193 193 192 141 141 139 86 87 84 20 16 18 0 0 0 4 4 4 -0 0 0 4 4 4 0 0 0 2 2 2 3 3 3 3 3 3 -0 0 0 29 30 27 86 87 84 126 126 126 126 126 126 124 124 124 -124 124 124 132 133 128 119 119 117 69 70 68 10 10 9 0 0 0 -4 4 4 2 2 2 1 1 1 0 0 0 3 3 3 2 2 2 -9 9 9 0 0 0 20 16 18 119 119 117 132 133 128 124 124 124 -124 124 124 126 126 126 132 133 128 104 104 103 29 30 27 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -8 3 14 4 1 5 0 2 1 0 3 0 0 3 0 2 1 0 -5 0 0 8 0 0 5 0 0 3 1 0 4 0 0 4 0 0 -4 0 0 2 1 0 1 2 0 0 2 0 2 2 2 6 6 6 -8 3 8 26 1 0 143 69 23 221 134 40 230 124 24 227 127 8 -227 127 8 239 126 20 227 127 8 221 134 40 215 129 57 74 34 6 -22 1 2 6 4 5 3 4 7 3 3 5 2 1 5 3 4 7 -3 4 7 3 1 7 1 0 5 2 0 3 10 1 0 14 1 0 -26 1 0 48 4 0 72 12 0 104 34 7 107 69 8 107 69 8 -74 34 6 72 12 0 30 1 2 22 1 2 17 6 0 9 1 3 -3 1 7 8 3 14 8 3 8 8 1 5 8 0 0 8 0 0 -6 1 3 6 1 3 5 3 3 18 0 0 107 69 8 215 129 57 -230 124 24 227 127 8 239 126 20 239 126 20 227 127 8 230 124 24 -215 129 57 72 12 0 33 6 2 5 5 5 3 3 5 0 0 4 -5 7 10 0 2 4 0 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 1 0 0 3 0 0 1 0 0 3 0 2 1 0 2 -1 0 2 1 0 2 0 0 2 0 0 2 0 0 2 0 0 2 -1 1 1 1 1 1 126 126 124 206 206 204 208 208 206 206 207 202 -208 208 206 207 207 205 86 86 84 2 2 2 0 0 2 1 1 3 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 208 206 206 207 202 -208 208 206 207 207 205 86 86 84 3 3 1 0 0 0 2 2 0 -0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 202 207 208 203 -208 209 204 207 207 205 5 5 3 0 0 0 5 5 5 3 3 5 -2 2 2 0 0 0 0 0 0 1 1 0 7 5 3 1 2 0 -65 52 28 164 164 161 211 211 209 209 210 205 201 202 197 204 205 200 -208 209 204 209 210 205 207 208 203 209 210 205 211 212 207 205 206 201 -205 206 201 197 198 192 82 82 81 1 1 0 5 5 3 0 0 0 -0 0 0 3 3 3 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 206 206 204 208 208 206 209 209 208 82 82 81 -0 0 0 10 10 9 0 0 0 5 5 3 8 8 8 1 1 1 -0 0 0 7 5 3 3 3 1 175 176 174 209 209 208 204 204 203 -213 214 212 204 204 203 204 204 203 221 221 215 193 193 192 69 70 68 -0 0 0 3 3 3 3 4 7 126 126 126 209 209 208 206 207 202 -203 204 199 205 206 201 203 204 199 208 209 204 209 210 205 210 211 206 -207 208 203 207 208 203 207 208 203 207 208 203 207 208 203 207 208 203 -207 208 203 207 208 203 204 205 200 209 210 205 170 171 167 1 1 1 -3 3 3 3 4 7 1 2 4 1 2 4 0 0 2 10 10 9 -0 0 0 3 3 1 119 119 117 186 187 182 210 211 206 208 209 204 -207 208 203 204 205 200 205 206 201 208 209 204 205 206 201 205 206 201 -207 208 203 201 202 197 212 213 207 186 187 182 104 104 103 5 5 3 -0 0 0 6 6 6 2 2 2 0 0 0 1 1 3 3 4 7 -8 9 10 2 2 2 29 30 27 203 203 202 209 209 208 205 206 201 -207 208 203 204 205 200 206 207 202 193 193 192 29 30 27 1 1 0 -0 0 0 6 6 6 1 1 3 7 7 7 0 0 2 10 10 9 -0 0 0 10 9 7 82 82 81 207 208 203 204 205 200 213 213 209 -201 202 197 207 207 205 202 202 199 141 141 139 0 0 0 2 2 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -8 3 8 4 1 5 0 2 1 0 3 0 0 2 2 2 0 1 -7 0 0 8 0 0 3 1 0 2 1 0 2 1 0 2 1 0 -4 0 1 2 1 0 0 2 0 0 2 0 7 9 5 0 0 0 -4 1 5 22 1 2 107 69 8 221 134 40 230 124 24 239 126 20 -230 124 24 230 124 24 230 124 24 215 129 57 198 136 53 72 12 0 -11 1 0 8 9 10 2 0 3 6 4 5 8 3 8 2 0 5 -0 0 4 1 0 6 5 7 10 5 7 10 3 4 7 4 1 5 -6 1 3 8 0 0 17 1 0 26 1 0 30 1 2 30 1 2 -22 1 2 18 0 0 17 1 0 10 1 0 4 1 3 3 4 7 -2 3 13 3 1 7 8 3 14 14 1 4 11 1 0 8 0 0 -8 0 0 7 1 0 7 5 3 22 1 2 143 100 31 215 129 57 -221 134 40 230 124 24 230 124 24 230 124 24 239 126 20 230 124 24 -215 129 57 72 12 0 22 1 2 1 0 2 2 1 5 5 7 10 -5 7 10 6 6 6 0 0 0 1 0 0 1 0 0 1 0 0 -3 0 0 3 0 0 3 0 0 3 0 0 3 0 2 3 0 2 -1 0 2 1 0 2 0 0 2 0 0 2 0 0 2 0 0 2 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 2 0 0 2 1 1 3 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 3 3 1 0 0 0 2 2 0 -0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -207 208 203 207 208 203 4 4 2 2 2 0 3 3 3 0 0 2 -4 4 4 2 2 2 7 7 7 0 0 0 8 10 3 127 127 125 -207 208 203 207 208 203 203 204 199 199 199 195 207 208 202 211 212 207 -204 205 200 205 206 200 211 212 207 201 202 197 197 198 192 209 210 204 -211 212 207 201 202 197 210 211 206 141 141 139 0 0 0 2 2 0 -8 8 8 4 4 4 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 204 204 203 208 208 206 209 209 208 86 86 84 -7 5 3 2 2 0 7 5 3 2 2 0 0 0 0 7 5 3 -6 5 0 1 2 0 154 154 152 197 198 192 208 209 204 211 212 207 -202 202 199 207 207 205 221 221 215 186 187 182 69 70 68 5 5 5 -20 16 18 0 0 0 0 0 2 126 126 126 206 207 202 203 204 199 -205 206 200 211 212 207 209 210 204 206 207 201 204 205 200 204 205 200 -208 209 203 208 209 203 208 209 203 208 209 203 208 209 203 208 209 203 -208 209 204 208 209 204 212 213 207 209 210 204 170 171 167 2 2 0 -0 0 2 0 0 2 0 0 4 0 0 2 8 9 10 0 0 0 -29 30 27 164 164 161 206 207 202 208 209 204 206 207 201 206 207 201 -199 199 195 213 214 212 206 207 201 197 198 192 211 212 207 211 212 207 -205 206 200 213 213 209 203 204 199 201 202 197 211 211 209 170 171 167 -29 30 27 4 4 4 0 0 0 5 5 5 5 7 10 0 0 4 -0 0 2 10 10 9 8 8 8 104 104 103 221 221 215 201 202 197 -208 209 203 203 204 199 221 221 215 201 202 197 132 133 128 6 5 0 -10 10 9 5 5 5 3 3 5 3 4 7 0 0 2 1 1 1 -7 5 3 29 30 27 193 193 192 213 213 209 205 206 200 206 207 201 -212 213 207 203 204 199 186 187 182 29 30 27 8 8 8 1 1 1 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -7 2 6 2 0 3 0 2 4 0 2 4 0 0 5 2 0 5 -4 1 3 4 0 0 1 2 0 0 3 0 0 3 0 0 2 1 -1 1 3 1 0 5 0 2 4 0 2 4 0 2 6 8 8 8 -26 16 7 30 1 2 143 69 23 221 134 40 230 124 24 230 124 24 -217 124 25 210 113 41 215 129 57 215 129 57 183 101 57 74 34 6 -14 1 0 3 0 4 9 4 5 10 9 7 6 4 5 3 3 1 -7 5 3 9 9 9 8 3 8 3 0 2 3 0 2 2 0 3 -3 0 4 3 0 2 4 0 0 8 0 0 14 1 0 14 1 0 -14 1 0 14 1 0 10 1 0 6 0 0 4 0 0 4 4 2 -5 7 10 2 3 8 0 2 6 1 0 5 4 0 1 6 0 0 -8 0 0 8 0 0 9 1 3 18 0 0 107 72 55 170 133 50 -215 129 57 215 129 57 221 134 40 217 124 25 230 124 24 221 134 40 -215 129 57 72 12 0 22 1 2 7 11 16 1 0 5 1 0 5 -7 1 0 9 3 3 1 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 1 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 3 3 1 0 0 0 2 2 0 -0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -207 208 203 207 208 203 2 2 0 4 4 2 0 0 0 0 0 0 -7 7 7 3 3 3 0 0 0 13 14 7 141 141 139 212 213 207 -203 204 199 216 217 214 197 198 192 216 217 214 208 209 204 207 208 203 -205 206 201 202 202 199 205 206 200 210 211 205 211 212 207 209 210 204 -202 202 199 211 212 207 208 209 204 201 202 197 154 154 152 10 10 9 -0 0 0 6 6 6 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 204 204 203 208 208 206 204 204 203 86 87 84 -0 0 0 0 0 0 5 5 3 5 5 3 20 16 18 0 0 0 -13 14 7 141 141 139 205 206 201 216 217 214 202 202 199 208 209 204 -206 206 204 209 209 208 186 187 182 69 70 68 4 4 4 1 1 1 -2 2 2 4 4 4 20 16 18 124 124 124 212 213 207 209 210 204 -209 210 204 206 207 201 205 206 200 207 208 202 213 213 209 212 213 207 -206 207 202 206 207 202 206 207 202 206 207 202 206 207 202 206 207 202 -206 207 202 206 207 202 206 207 201 197 198 192 164 164 161 6 6 6 -8 9 10 1 2 4 6 6 6 1 1 3 0 0 2 29 30 27 -170 171 167 203 204 199 213 214 212 199 199 195 209 210 205 213 213 209 -212 213 207 203 204 199 210 211 206 210 211 206 201 202 197 210 211 206 -221 221 215 206 207 202 205 206 201 202 202 199 211 211 209 209 209 208 -170 171 167 29 30 27 2 2 2 2 2 2 1 0 5 3 1 7 -3 4 7 2 2 2 0 0 0 7 5 3 141 141 139 212 213 207 -206 207 202 208 209 204 201 202 197 209 210 205 209 210 205 86 87 84 -0 0 0 6 6 6 8 9 10 0 0 2 8 9 10 8 8 8 -0 0 0 127 127 125 208 209 204 200 201 194 209 210 204 211 212 207 -199 199 195 203 204 199 86 87 84 0 0 0 0 0 0 4 4 4 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 2 0 1 1 1 0 2 4 0 2 6 1 0 6 2 0 5 -2 0 3 1 1 1 0 3 0 0 6 1 0 3 0 0 2 4 -0 0 5 1 0 6 0 2 6 0 2 6 1 0 6 9 3 6 -14 1 0 35 1 0 183 101 57 215 129 57 215 129 57 198 136 53 -143 100 31 143 69 23 104 34 7 72 12 0 48 4 0 22 1 2 -14 1 0 15 7 8 9 1 3 9 3 6 7 5 3 2 2 0 -0 1 0 1 0 0 7 5 3 15 7 8 6 1 3 8 1 5 -6 4 5 3 3 5 1 2 4 3 3 5 8 3 8 8 3 14 -3 1 7 3 0 2 4 0 0 10 7 0 10 7 0 3 3 1 -0 2 1 0 2 4 5 7 10 3 4 7 7 2 6 10 1 0 -11 1 0 14 1 0 14 1 4 18 0 0 26 1 0 48 4 0 -74 34 6 107 69 8 143 69 23 183 98 20 198 136 53 215 129 57 -198 136 53 107 69 8 18 0 0 8 3 8 2 0 5 7 2 6 -8 1 5 4 0 0 1 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 1 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 2 2 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -208 209 204 209 210 205 0 0 0 4 4 2 0 0 0 1 1 1 -7 7 7 0 0 0 3 3 1 154 154 152 197 198 192 213 214 212 -209 210 205 197 198 192 213 214 212 203 204 199 207 208 203 204 205 200 -212 213 207 209 210 205 202 202 199 211 212 207 212 213 207 197 198 192 -202 202 199 212 213 207 209 210 205 213 214 212 193 193 192 119 119 117 -10 10 9 7 5 3 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 204 204 203 208 208 206 207 207 205 86 87 84 -0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 10 10 9 -119 119 117 213 213 209 212 213 207 203 204 199 216 217 214 206 207 202 -211 211 209 193 193 192 69 70 68 5 5 3 1 1 1 1 1 1 -0 0 0 2 2 2 0 0 2 126 126 126 201 202 197 207 208 202 -210 211 205 201 202 197 205 206 200 205 206 200 205 206 200 201 202 197 -209 210 205 209 210 205 209 210 205 209 210 205 209 210 205 209 210 205 -209 209 208 209 210 205 213 214 212 212 213 207 175 176 174 0 0 0 -0 0 0 7 7 7 20 16 18 0 0 0 29 30 27 175 176 174 -213 214 212 213 213 209 202 202 199 204 205 200 221 221 215 201 202 197 -203 204 199 209 210 205 205 206 201 207 208 203 216 217 214 206 207 202 -193 193 192 209 210 205 209 210 205 206 207 202 207 207 205 199 199 195 -216 217 214 175 176 174 29 30 27 0 0 0 0 0 2 8 9 10 -8 9 10 0 0 0 2 2 2 3 3 1 29 30 27 186 187 182 -208 209 204 205 206 201 203 204 199 213 214 212 208 209 204 175 176 174 -10 10 9 4 4 2 4 4 4 4 4 4 0 0 0 2 2 0 -69 70 68 206 207 202 206 207 202 207 208 202 209 210 204 205 206 200 -207 208 203 132 133 128 5 5 3 13 14 7 0 0 0 1 1 1 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 2 0 0 2 0 0 2 4 0 2 6 1 0 6 3 1 7 -2 0 5 0 1 3 0 2 1 0 3 0 0 3 0 0 2 4 -1 0 5 1 0 5 1 0 5 1 0 6 7 11 16 9 1 3 -17 1 0 65 52 28 163 140 97 143 100 31 104 34 7 48 4 0 -26 1 0 22 1 2 30 1 2 26 1 0 22 1 2 26 1 0 -18 0 0 14 1 0 14 1 4 4 0 1 2 2 0 6 6 6 -7 9 5 3 3 1 1 1 0 3 3 1 9 3 3 9 1 3 -8 0 0 7 0 0 3 0 2 0 0 2 0 2 4 0 2 6 -2 3 8 0 2 6 6 5 0 8 10 3 6 5 0 0 1 0 -0 1 0 5 7 10 0 0 4 4 1 3 14 1 4 17 1 0 -18 0 0 18 0 0 17 1 0 18 0 0 18 0 0 18 0 0 -26 1 0 26 1 0 22 1 2 35 1 0 74 34 6 107 69 8 -170 133 50 163 140 97 47 26 20 5 0 0 7 7 7 3 1 7 -3 1 7 3 1 7 0 0 4 0 0 2 0 0 2 0 0 2 -0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -205 206 201 209 210 205 0 0 0 3 3 1 2 2 2 3 3 3 -0 0 0 2 2 2 119 119 117 202 202 199 213 213 209 201 202 197 -213 214 212 216 217 214 199 199 198 211 211 209 186 187 182 141 141 139 -86 87 84 69 70 68 86 87 84 126 126 124 164 164 161 216 217 214 -208 209 204 204 205 200 204 204 203 199 199 195 216 217 214 208 208 206 -65 52 28 0 0 0 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 205 206 201 208 209 204 207 208 203 82 82 81 -5 5 3 5 5 3 7 7 7 0 0 0 5 5 3 104 104 103 -201 202 197 221 221 215 197 198 192 209 210 205 207 207 205 203 203 202 -199 199 195 82 82 81 1 1 1 10 10 9 1 1 1 1 1 1 -10 10 9 1 1 1 2 2 2 127 127 125 208 209 204 210 211 205 -211 212 207 207 208 202 213 213 209 186 187 182 170 171 167 170 171 167 -170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 -170 171 167 170 171 167 164 164 161 164 164 161 141 141 139 9 9 9 -4 4 4 2 2 2 0 0 0 7 7 7 132 133 128 201 202 197 -212 213 207 201 202 197 203 203 202 216 217 214 199 199 198 206 206 204 -186 187 182 119 119 117 86 87 84 86 86 84 86 87 84 119 119 117 -175 176 174 213 214 212 209 210 205 209 210 205 193 193 192 216 217 214 -203 203 202 199 199 198 141 141 139 0 0 0 7 7 7 6 6 6 -0 0 2 9 9 9 2 2 2 13 14 7 0 0 0 86 87 84 -208 209 204 202 202 199 216 217 214 201 202 197 205 206 201 210 211 206 -119 119 117 0 0 0 5 5 5 0 0 0 1 1 1 0 0 0 -170 171 167 201 202 197 206 207 202 209 210 205 203 204 199 207 208 203 -193 193 192 29 30 27 0 0 0 2 2 2 8 9 10 0 0 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 3 0 0 3 0 0 2 4 0 0 5 1 0 6 2 0 5 -1 0 6 0 0 5 0 2 4 0 2 4 0 2 4 0 1 3 -2 0 3 4 1 3 2 0 3 2 0 3 3 0 4 15 7 8 -25 6 3 65 52 28 74 34 6 35 1 0 26 1 0 22 1 2 -22 1 2 22 1 2 30 1 2 35 1 0 30 1 2 35 1 0 -35 1 0 48 4 0 35 1 0 26 1 0 22 1 2 22 1 2 -17 1 0 14 1 0 9 1 0 9 1 0 6 0 0 6 0 0 -7 0 0 9 1 3 9 3 6 5 5 5 2 3 8 2 3 8 -0 2 6 0 2 6 0 3 0 0 2 0 0 3 0 6 5 0 -6 5 0 8 0 0 17 6 0 25 6 3 30 1 2 35 1 0 -35 1 0 35 1 0 48 4 0 48 4 0 35 1 0 30 1 2 -30 1 2 30 1 2 30 1 2 22 1 2 30 1 2 35 1 0 -48 4 0 65 52 28 26 16 7 9 1 0 15 7 8 2 0 5 -3 1 7 2 3 13 0 0 5 0 0 4 0 0 4 0 0 2 -0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -202 202 199 208 209 204 0 0 0 2 2 0 3 3 3 2 2 2 -0 0 0 29 30 27 199 199 195 209 210 205 208 209 204 216 217 214 -193 193 192 207 208 203 208 208 206 127 127 125 3 3 1 5 5 3 -4 4 2 3 3 1 4 4 2 0 0 0 29 30 27 104 104 103 -193 193 192 213 213 209 211 211 209 209 209 208 213 214 212 199 199 198 -141 141 139 5 5 5 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 205 206 201 208 209 204 203 204 199 86 87 84 -3 3 1 7 5 3 0 0 0 13 14 7 104 104 103 204 204 203 -210 211 206 199 199 195 213 214 212 203 204 199 207 207 205 199 199 198 -69 70 68 3 3 1 1 1 1 1 1 1 2 2 2 5 5 5 -0 0 0 1 1 1 20 16 18 119 119 117 205 206 201 205 206 200 -210 211 205 212 213 207 197 198 192 86 87 84 8 10 3 0 1 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 2 2 0 0 0 0 10 10 9 0 0 0 -10 10 9 3 3 3 1 1 0 86 86 84 204 205 200 213 214 212 -199 199 195 202 202 199 221 221 215 202 202 199 203 203 202 126 126 126 -0 0 0 13 14 7 7 5 3 0 0 0 10 10 9 0 0 0 -29 30 27 104 104 103 199 199 195 201 202 197 221 221 215 207 208 203 -209 209 208 211 211 209 204 204 203 86 87 84 0 0 0 1 2 4 -0 0 2 9 9 9 0 0 0 2 2 0 6 6 6 3 3 1 -141 141 139 212 213 207 211 212 207 199 199 195 216 217 214 203 204 199 -213 214 212 69 70 68 0 0 0 7 7 7 3 3 1 119 119 117 -213 213 209 212 213 207 206 207 202 210 211 206 205 206 201 211 212 207 -86 86 84 0 0 0 4 4 4 0 0 0 3 3 5 1 1 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 3 0 0 3 0 0 2 1 0 0 4 0 0 4 2 0 5 -2 0 5 0 0 4 1 0 5 1 0 5 2 0 1 4 0 0 -5 0 0 7 0 0 5 0 0 4 0 0 7 7 7 7 5 3 -8 0 0 25 6 3 30 1 2 26 1 0 26 1 0 30 1 2 -48 4 0 74 34 6 107 69 8 183 98 20 198 136 53 198 136 53 -198 136 53 198 136 53 198 136 53 198 136 53 183 98 20 143 69 23 -74 34 6 48 4 0 30 1 2 17 1 0 11 1 0 3 0 2 -4 0 0 7 1 0 7 1 0 2 1 0 0 0 0 0 1 0 -3 4 7 1 3 4 1 3 4 1 7 3 6 5 0 10 7 0 -25 6 3 33 6 2 72 12 0 104 34 7 143 69 23 183 98 20 -198 136 53 198 136 53 198 136 53 210 113 41 198 136 53 183 98 20 -143 69 23 104 34 7 72 12 0 48 4 0 35 1 0 26 1 0 -18 0 0 26 16 7 11 1 0 14 1 4 8 3 8 4 1 3 -4 1 3 3 3 3 0 0 4 0 0 4 0 0 4 0 0 2 -0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 1 0 2 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -204 205 200 207 208 203 2 2 0 2 2 0 1 1 1 1 1 1 -13 14 7 124 124 124 206 207 202 209 210 205 201 202 197 203 204 199 -210 211 206 205 206 201 119 119 117 3 3 1 5 5 5 0 0 0 -0 0 0 1 1 1 5 5 5 1 1 0 0 0 0 20 16 18 -82 82 81 202 202 199 207 207 205 203 203 202 141 141 139 86 87 84 -5 5 5 1 1 1 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 205 206 201 208 209 204 206 207 202 86 87 84 -0 1 0 1 2 0 8 10 3 82 82 81 202 202 199 209 209 208 -204 205 200 213 213 209 204 204 203 204 204 203 204 204 203 69 70 68 -4 4 4 0 0 0 3 3 3 0 0 0 8 8 8 0 0 0 -3 3 3 7 7 7 0 0 0 127 127 125 206 207 202 205 206 200 -204 205 200 209 210 204 206 207 202 82 82 81 0 0 0 4 4 2 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 3 3 3 1 1 1 1 1 1 4 4 4 -1 1 1 0 0 0 13 14 7 154 154 152 211 212 207 207 208 202 -203 204 199 211 212 207 199 199 195 203 203 202 82 82 81 0 0 0 -8 8 8 0 0 0 0 0 0 3 3 3 4 4 2 0 0 0 -0 0 0 13 14 7 69 70 68 204 204 203 201 202 197 206 207 202 -197 198 192 208 209 204 205 206 201 154 154 152 8 8 8 1 2 4 -5 5 5 1 1 1 5 5 5 0 0 0 10 10 9 0 0 0 -29 30 27 175 176 174 207 208 203 211 212 207 211 212 207 197 198 192 -221 221 215 175 176 174 6 5 0 1 2 0 20 16 18 207 208 203 -201 202 197 210 211 206 211 212 207 203 204 199 203 203 202 141 141 139 -1 1 0 4 4 2 4 4 4 8 8 8 0 0 2 3 3 5 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 2 0 0 3 0 0 1 3 0 0 4 0 0 2 2 0 3 -2 0 5 1 0 5 4 1 5 4 1 3 5 0 0 5 0 0 -7 0 0 5 0 0 5 0 0 2 1 0 8 10 3 5 1 0 -17 6 0 22 1 2 26 1 0 35 1 0 74 34 6 143 100 31 -198 136 53 222 154 56 222 154 56 221 134 40 229 143 21 229 143 21 -229 143 21 229 143 21 229 143 21 229 143 21 221 134 40 221 134 40 -215 129 57 183 101 57 143 69 23 74 34 6 26 1 0 17 1 0 -11 1 0 10 1 0 9 1 0 7 1 0 7 5 3 9 9 9 -5 3 3 3 0 0 7 1 0 17 6 0 17 1 0 33 6 2 -107 69 8 143 100 31 222 154 56 222 154 56 220 161 40 229 143 21 -229 143 21 229 143 21 229 143 21 229 143 21 231 145 5 229 143 21 -221 134 40 215 129 57 215 129 57 183 101 57 107 69 8 72 12 0 -33 6 2 18 0 0 17 1 0 11 1 0 6 1 3 6 4 5 -3 0 0 4 4 2 0 0 2 0 0 4 0 0 4 0 0 2 -0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 1 0 2 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -209 210 205 209 210 205 4 4 2 1 1 0 0 0 0 0 0 0 -29 30 27 193 193 192 204 205 200 210 211 206 209 210 204 206 207 201 -213 213 209 141 141 139 2 2 0 2 2 2 0 0 2 3 3 5 -8 9 10 0 0 0 1 1 1 8 8 8 1 1 1 1 1 0 -2 2 0 124 124 124 154 154 152 69 70 68 2 2 0 7 5 3 -4 4 4 0 0 0 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 205 206 201 208 209 204 207 208 203 86 86 84 -7 5 3 3 3 1 69 70 68 197 198 192 221 221 215 203 203 202 -203 204 199 206 207 202 199 199 195 216 217 214 69 70 68 3 3 1 -2 2 2 0 0 0 1 1 1 1 1 1 0 0 0 3 3 3 -4 4 4 0 0 0 5 5 5 127 127 125 202 202 199 212 213 207 -207 208 202 203 204 199 208 209 204 86 87 84 0 0 0 3 3 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 2 2 2 5 5 5 3 3 3 0 0 0 -0 0 0 10 9 7 65 52 28 211 212 207 207 208 202 205 206 200 -209 210 204 204 205 200 211 211 209 127 127 125 0 0 2 6 6 6 -1 1 3 2 2 2 6 6 6 0 0 0 2 2 0 10 9 7 -1 1 0 0 0 0 3 3 1 119 119 117 213 213 209 207 208 203 -206 207 202 208 209 204 207 208 203 206 207 202 65 52 28 3 4 7 -0 0 0 1 1 1 6 6 6 4 4 4 1 1 0 5 5 3 -0 0 0 104 104 103 201 202 197 201 202 197 210 211 206 213 214 212 -193 193 192 212 213 207 124 124 124 2 2 0 154 154 152 208 209 204 -210 211 206 206 207 202 208 209 204 212 213 207 193 193 192 29 30 27 -3 3 1 3 3 3 6 6 6 1 2 4 3 4 7 0 0 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 2 0 1 1 0 1 1 3 1 1 3 1 1 1 2 0 1 -2 0 5 4 1 5 7 2 6 6 1 3 8 0 0 15 7 8 -4 1 3 6 4 5 7 7 7 0 0 2 2 2 0 14 1 0 -22 1 2 35 1 0 104 34 7 170 133 50 231 175 56 220 161 40 -242 158 39 229 155 20 229 155 20 229 155 20 231 145 5 231 145 5 -229 143 21 229 143 21 247 146 18 247 146 18 239 126 20 239 126 20 -230 124 24 221 134 40 221 134 40 198 136 53 143 100 31 74 34 6 -35 1 0 30 1 2 14 1 0 9 1 3 2 5 5 0 1 3 -15 7 8 17 1 0 18 0 0 48 4 0 107 69 8 198 136 53 -231 175 56 221 134 40 242 158 39 229 143 21 229 143 21 229 143 21 -229 143 21 229 143 21 231 145 5 231 145 5 246 147 4 241 129 3 -229 143 21 221 134 40 221 134 40 221 134 40 221 134 40 198 136 53 -143 69 23 72 12 0 26 1 0 14 1 0 10 7 0 2 2 0 -3 0 0 9 4 5 1 2 4 2 1 5 2 1 5 3 3 5 -0 2 2 0 2 2 2 5 5 0 2 2 0 1 0 0 1 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 1 0 2 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 3 3 1 0 0 0 2 2 0 -0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -205 206 201 210 211 206 0 0 0 2 2 0 5 5 3 3 3 1 -104 104 103 206 206 204 205 206 201 212 213 207 208 209 203 204 205 200 -201 202 197 29 30 27 0 0 0 0 0 0 1 1 3 1 1 3 -1 1 3 1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 206 207 202 208 209 204 209 210 205 86 87 84 -0 1 0 69 70 68 197 198 192 210 211 206 207 208 203 208 209 204 -211 212 207 205 206 201 213 214 212 104 104 103 0 0 0 7 5 3 -1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 0 0 0 -1 1 1 2 2 2 0 0 0 126 126 124 208 209 204 205 206 200 -207 208 202 211 212 207 206 207 202 86 87 84 2 2 0 2 2 0 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 1 1 3 20 16 18 0 0 0 6 6 6 -0 0 0 5 5 3 127 127 125 207 208 202 206 207 201 205 206 200 -211 212 207 207 208 202 186 187 182 7 7 7 0 0 2 7 7 7 -1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 7 7 7 0 0 0 186 187 182 204 205 200 -211 212 207 202 202 199 214 215 207 202 202 199 126 126 126 5 5 5 -0 0 0 0 0 0 3 3 3 0 0 0 7 7 7 4 4 2 -10 9 7 0 0 0 126 126 124 206 207 202 209 210 205 203 204 199 -216 217 214 201 202 197 197 198 192 119 119 117 201 202 197 212 213 207 -203 204 199 216 217 214 202 202 199 208 209 204 69 70 68 13 14 7 -0 0 0 5 5 5 3 3 5 1 1 3 1 1 3 1 1 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 1 0 0 2 0 5 2 0 3 1 1 0 1 1 0 -2 0 5 4 1 5 8 1 5 9 4 5 13 14 7 3 0 0 -3 4 7 2 3 8 0 0 5 15 7 8 26 16 7 17 1 0 -74 34 6 143 100 31 222 154 56 242 158 39 229 155 20 244 159 4 -246 158 18 246 147 4 231 145 5 231 145 5 246 147 4 246 147 4 -246 147 4 246 147 4 241 129 3 241 129 3 241 129 3 243 126 10 -243 126 10 239 126 20 239 126 20 230 124 24 217 124 25 198 136 53 -143 69 23 48 4 0 30 1 2 25 6 3 6 0 0 7 1 0 -14 1 0 33 6 2 107 69 8 170 133 50 231 175 56 242 158 39 -247 146 18 250 166 22 246 147 4 246 147 4 246 147 4 246 147 4 -231 145 5 231 145 5 231 145 5 241 129 3 241 129 3 241 129 3 -241 129 3 227 127 8 239 126 20 227 127 8 227 127 8 230 124 24 -210 113 41 183 101 57 107 69 8 35 1 0 18 0 0 11 1 0 -26 16 7 5 1 0 3 0 2 4 1 5 3 0 4 1 1 1 -0 0 0 0 2 2 6 6 6 6 6 6 0 1 0 0 1 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 1 0 2 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 3 3 1 0 0 0 2 2 0 -0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -206 207 202 208 209 204 2 2 0 3 3 1 6 6 6 0 0 0 -154 154 152 212 213 207 206 207 202 207 208 203 206 207 201 211 212 207 -141 141 139 13 14 7 1 1 1 1 1 1 1 0 5 1 0 5 -1 1 3 1 1 3 1 1 3 1 1 3 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 205 206 201 208 209 204 206 207 202 82 82 81 -65 52 28 186 187 182 207 208 203 205 206 201 213 213 209 204 205 200 -204 205 200 210 211 206 104 104 103 10 10 9 1 1 0 6 6 6 -6 6 6 3 3 3 2 2 2 0 0 0 1 1 1 0 0 0 -1 1 1 2 2 2 0 0 0 126 126 124 206 207 201 207 208 202 -205 206 200 209 210 204 208 209 204 86 86 84 0 0 0 5 5 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 3 4 7 0 0 2 0 0 0 4 4 4 -7 5 3 10 9 7 164 164 161 206 207 201 206 207 201 205 207 197 -206 207 201 209 210 204 124 124 124 3 3 3 0 0 2 2 1 5 -1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 4 4 2 0 0 0 127 127 125 209 210 205 -210 211 206 203 204 199 210 211 205 206 207 202 164 164 161 2 2 2 -5 5 5 5 5 5 3 3 3 1 1 1 2 2 2 1 1 1 -2 2 0 5 5 3 7 5 3 175 176 174 213 214 212 213 213 209 -201 202 197 211 212 207 214 215 207 203 204 199 206 207 201 208 209 203 -212 213 207 199 199 195 213 213 209 119 119 117 20 16 18 0 0 0 -0 0 0 6 6 6 1 1 3 1 1 3 3 4 7 6 6 6 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -3 0 2 3 0 4 2 0 5 2 0 5 1 1 1 1 1 1 -2 0 5 4 1 5 3 0 0 3 0 0 6 5 0 0 3 0 -2 3 8 1 0 6 7 11 16 10 1 0 26 1 0 107 69 8 -198 136 53 231 175 56 242 158 39 246 158 18 246 158 18 246 158 18 -244 159 4 233 156 5 233 156 5 231 145 5 246 147 4 246 147 4 -246 147 4 241 129 3 241 129 3 241 129 3 241 129 3 241 129 3 -243 126 10 243 126 10 239 126 20 239 126 20 230 124 24 217 124 25 -221 134 40 183 98 20 104 34 7 35 1 0 17 1 0 17 1 0 -48 4 0 143 69 23 222 154 56 231 175 56 242 158 39 246 158 18 -244 159 4 244 159 4 233 156 5 233 156 5 233 156 5 246 147 4 -231 145 5 231 145 5 241 129 3 241 129 3 241 129 3 241 129 3 -241 129 3 241 129 3 241 129 3 227 127 8 241 129 3 227 127 8 -229 143 21 217 124 25 215 129 57 143 69 23 48 4 0 30 1 2 -11 1 0 10 7 0 7 1 0 6 1 3 4 1 3 2 0 1 -3 0 2 1 1 1 0 0 2 1 2 4 0 0 2 0 0 2 -0 0 2 0 0 2 0 0 0 0 0 0 1 0 0 1 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 3 3 1 0 0 0 2 2 0 -0 0 0 5 5 5 1 1 1 2 2 2 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -204 205 200 205 206 200 0 1 0 1 2 0 2 2 0 0 0 0 -193 193 192 209 210 205 208 209 204 205 206 200 206 207 201 214 215 207 -69 70 68 3 3 1 2 2 2 2 2 2 1 0 5 1 0 5 -1 1 3 1 1 3 1 1 3 1 1 3 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 205 206 201 208 209 204 204 205 200 104 104 103 -164 164 161 207 208 202 213 213 209 199 199 195 205 206 200 211 212 207 -213 213 209 119 119 117 20 16 18 0 0 0 7 7 7 1 1 1 -1 2 4 1 1 3 1 2 4 0 0 2 1 1 1 0 0 0 -1 1 1 2 2 2 0 0 0 126 126 124 207 208 202 211 212 205 -206 207 201 207 208 202 206 207 202 86 87 84 0 0 0 7 5 3 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 -1 1 0 1 1 0 1 1 1 0 0 0 10 10 9 8 8 8 -0 0 0 0 0 0 186 187 182 208 209 203 207 208 202 205 206 200 -204 205 200 206 207 201 65 52 28 0 0 0 1 2 4 0 0 2 -1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 -1 1 1 1 1 1 1 1 0 0 0 0 65 52 28 207 207 205 -208 209 204 204 205 200 206 207 201 210 211 206 186 187 182 0 0 0 -2 2 2 3 3 3 0 0 0 4 4 4 0 0 0 1 1 1 -3 3 1 1 1 0 0 0 0 69 70 68 201 202 197 209 210 204 -199 199 195 211 212 207 207 208 202 213 213 209 206 207 201 212 213 207 -205 206 201 208 209 204 175 176 174 6 6 6 1 1 1 0 0 0 -7 7 7 5 5 5 0 0 2 0 0 2 1 2 4 1 1 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -3 0 4 3 0 4 1 0 5 0 0 4 1 1 1 0 2 1 -2 0 5 2 0 5 7 5 3 1 2 0 0 3 0 8 10 3 -0 2 4 8 9 10 10 1 0 25 6 3 107 69 8 198 136 53 -231 175 56 225 170 23 233 156 5 246 158 18 246 158 18 244 159 4 -233 156 5 233 156 5 233 156 5 246 147 4 247 146 18 247 146 18 -246 147 4 246 147 4 241 129 3 241 129 3 241 129 3 241 129 3 -241 129 3 241 129 3 243 126 10 227 127 8 227 127 8 223 116 8 -230 124 24 221 134 40 210 113 41 104 34 7 48 4 0 48 4 0 -170 133 50 222 154 56 231 175 56 229 155 20 231 145 5 249 164 6 -249 164 6 233 156 5 233 156 5 233 156 5 233 156 5 246 147 4 -246 147 4 246 147 4 247 146 18 247 146 18 241 129 3 241 129 3 -241 129 3 241 129 3 241 129 3 241 129 3 241 129 3 241 129 3 -223 116 8 227 127 8 230 124 24 215 129 57 183 101 57 72 12 0 -30 1 2 17 6 0 8 0 0 4 0 0 4 0 0 5 1 0 -7 5 3 4 1 3 0 0 2 3 4 7 0 0 2 0 0 2 -0 0 2 0 0 2 0 0 0 0 0 0 1 0 0 1 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 2 2 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -205 206 200 208 209 203 0 1 0 1 2 0 0 0 0 20 16 18 -209 210 205 203 204 199 209 210 204 206 207 201 208 209 203 201 202 197 -10 9 7 0 0 0 3 3 3 3 3 3 1 1 3 1 0 5 -1 1 3 1 1 3 1 1 3 1 1 3 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 205 206 201 208 209 204 204 205 200 197 198 192 -211 212 207 216 217 214 201 202 197 214 215 207 207 208 202 206 207 201 -104 104 103 5 5 3 0 0 0 20 16 18 8 8 8 0 0 0 -1 2 4 1 1 3 1 2 4 0 0 2 1 1 1 0 0 0 -1 1 1 2 2 2 0 0 0 126 126 124 204 205 200 211 212 205 -211 212 207 210 211 205 197 198 192 86 87 84 7 7 7 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 2 2 0 7 7 7 0 0 0 5 5 5 -0 0 0 20 16 18 202 202 199 208 209 204 208 209 203 209 210 202 -206 207 201 193 193 192 5 5 3 1 1 0 3 3 5 1 1 3 -1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 -1 1 1 1 1 1 0 0 0 0 0 0 7 7 7 193 193 192 -207 208 203 208 209 204 205 206 200 210 211 206 203 203 202 20 16 18 -0 0 0 0 0 0 0 0 0 5 5 5 1 1 1 4 4 4 -3 3 1 13 14 7 0 0 0 8 10 3 119 119 117 213 213 209 -213 213 209 200 201 194 207 208 202 209 210 204 207 208 202 186 187 182 -209 210 205 213 213 209 82 82 81 0 0 0 5 5 5 5 5 5 -4 4 4 1 1 1 1 1 3 3 4 7 3 4 7 0 0 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -3 0 4 1 0 5 1 0 5 0 0 2 0 0 0 0 2 1 -2 0 5 2 0 5 7 5 3 6 5 0 0 6 1 0 6 1 -0 2 0 26 16 7 26 1 0 143 100 31 231 175 56 244 176 40 -225 170 23 225 170 23 242 171 21 242 171 21 233 156 5 244 159 4 -233 156 5 233 156 5 246 147 4 246 147 4 246 147 4 246 147 4 -231 145 5 231 145 5 231 145 5 227 127 8 241 129 3 241 129 3 -241 129 3 241 129 3 241 129 3 227 127 8 223 116 8 239 126 20 -223 116 8 223 116 8 221 134 40 183 98 20 143 69 23 183 98 20 -231 175 56 242 158 39 229 155 20 242 171 21 250 166 22 249 164 6 -244 159 4 244 159 4 244 159 4 246 147 4 246 147 4 246 147 4 -246 147 4 246 147 4 241 129 3 241 129 3 241 129 3 241 129 3 -241 129 3 227 127 8 241 129 3 241 129 3 241 129 3 240 120 3 -243 126 10 240 120 3 223 116 8 230 124 24 215 129 57 183 101 57 -74 34 6 30 1 2 18 0 0 10 1 0 11 1 0 7 1 0 -5 1 0 5 3 3 1 1 3 3 4 7 0 0 4 0 0 4 -0 0 4 0 0 2 0 0 0 0 0 0 1 0 0 1 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -207 208 202 214 215 207 2 2 0 6 5 0 3 3 1 69 70 68 -211 212 207 207 208 203 209 210 204 209 210 204 209 210 204 175 176 174 -0 0 0 1 1 0 1 1 1 2 2 2 1 1 3 1 1 3 -1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 3 1 1 3 0 0 0 3 3 3 0 0 0 127 127 125 -208 209 204 206 207 202 205 206 201 208 209 204 205 206 200 205 206 200 -201 202 197 210 211 205 199 199 195 207 208 202 199 199 195 175 176 174 -6 6 6 0 0 0 10 10 9 0 0 0 6 6 6 4 4 4 -1 1 3 1 1 3 1 2 4 0 0 2 1 1 1 0 0 0 -1 1 0 2 2 0 0 0 0 126 126 124 211 212 207 205 206 200 -206 207 201 208 209 203 209 210 205 186 187 182 164 164 161 170 171 167 -170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 -170 171 167 170 171 167 170 171 167 132 133 128 9 9 9 3 3 3 -4 4 4 69 70 68 213 214 212 213 214 212 207 208 202 210 211 205 -208 209 203 175 176 174 0 0 0 2 2 0 1 1 3 3 3 5 -1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 -1 1 1 1 1 1 2 2 2 1 1 1 0 0 0 175 176 174 -208 209 204 210 211 206 206 207 201 208 209 204 211 211 209 69 70 68 -5 5 5 2 2 2 1 1 1 4 4 4 2 2 2 3 3 3 -4 4 4 2 2 2 4 4 2 3 3 1 10 9 7 175 176 174 -186 187 182 212 213 207 207 208 202 200 201 194 221 221 215 210 211 205 -212 213 207 119 119 117 6 6 6 0 0 0 3 3 3 1 1 1 -0 0 0 1 1 1 5 5 5 5 5 5 2 2 2 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 4 0 0 4 0 0 4 0 0 2 0 0 0 0 0 0 -2 0 5 4 1 5 3 0 0 4 4 2 0 6 1 0 3 0 -10 1 0 22 1 2 107 69 8 231 175 56 225 170 23 242 171 21 -242 171 21 236 169 8 236 169 8 233 156 5 233 156 5 244 159 4 -233 156 5 233 156 5 246 147 4 246 147 4 231 145 5 229 143 21 -229 143 21 229 143 21 229 143 21 229 143 21 241 129 3 241 129 3 -241 129 3 241 129 3 241 129 3 241 129 3 243 126 10 223 116 8 -239 126 20 243 126 10 222 105 4 223 116 8 229 155 20 244 176 40 -229 155 20 242 171 21 242 169 5 244 159 4 244 159 4 244 159 4 -244 159 4 233 156 5 246 158 18 247 146 18 247 146 18 247 146 18 -247 146 18 247 146 18 229 143 21 229 143 21 247 146 18 247 146 18 -231 145 5 227 127 8 227 127 8 241 129 3 240 120 3 240 120 3 -240 120 3 239 112 3 243 126 10 223 116 8 217 124 25 210 113 41 -183 101 57 72 12 0 22 1 2 10 1 0 17 6 0 9 1 0 -4 0 0 6 4 5 3 0 4 0 0 2 0 0 4 0 0 4 -0 0 4 0 0 2 0 0 2 0 0 0 1 0 0 1 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -204 205 200 212 213 207 1 2 0 6 5 0 5 5 3 82 82 81 -207 208 203 210 211 206 206 207 201 210 211 205 207 208 202 164 164 161 -4 4 2 4 4 2 0 0 0 1 1 1 1 1 3 1 1 3 -1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 3 1 1 3 0 0 0 3 3 3 0 0 0 127 127 125 -208 209 204 206 207 202 205 206 201 208 209 204 214 215 207 197 198 192 -216 217 214 203 204 199 216 217 214 205 206 200 210 211 205 199 199 195 -104 104 103 13 14 7 2 2 0 0 0 0 2 2 2 5 5 5 -0 0 2 6 6 6 1 2 4 0 0 2 1 1 1 0 0 0 -1 1 0 2 2 0 0 0 0 126 126 124 207 208 202 203 204 197 -209 210 204 211 212 207 208 209 204 208 209 204 211 211 209 204 204 203 -208 208 206 208 208 206 208 209 204 208 209 204 208 209 204 208 209 203 -208 209 203 208 209 203 209 210 205 175 176 174 0 0 0 2 2 2 -5 5 5 86 86 84 202 202 199 202 202 199 206 207 202 208 209 203 -207 208 202 164 164 161 4 4 2 3 3 1 0 0 0 3 3 5 -1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 1 1 3 -1 1 1 1 1 1 3 3 3 1 1 1 6 6 6 164 164 161 -209 210 205 211 212 207 206 207 201 207 208 203 207 207 205 86 87 84 -4 4 4 0 0 0 1 1 1 1 1 1 2 2 2 1 1 1 -0 0 0 6 6 6 10 10 9 0 1 0 0 1 0 86 87 84 -214 215 207 205 207 197 216 217 214 204 205 198 203 204 199 212 213 207 -175 176 174 0 1 0 7 5 3 3 3 1 2 2 2 1 1 1 -0 0 0 4 4 4 3 3 3 0 0 0 0 0 0 1 1 1 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 2 0 0 2 0 0 2 0 0 0 0 1 0 1 0 0 -4 1 5 4 1 5 7 2 6 6 4 5 0 2 2 10 7 0 -17 6 0 107 69 8 222 154 56 244 176 40 250 166 22 249 164 6 -236 169 8 236 169 8 244 159 4 244 159 4 244 159 4 244 159 4 -231 145 5 247 146 18 233 156 5 233 156 5 229 143 21 229 143 21 -221 134 40 221 134 40 229 143 21 229 143 21 239 126 20 239 126 20 -243 126 10 241 129 3 241 129 3 241 129 3 239 112 3 240 120 3 -243 126 10 222 105 4 223 116 8 246 158 18 249 178 22 242 171 21 -249 176 7 249 164 6 244 159 4 233 156 5 244 159 4 249 164 6 -246 158 18 233 156 5 247 146 18 247 146 18 246 158 18 229 155 20 -229 143 21 229 143 21 221 134 40 221 134 40 230 124 24 230 124 24 -229 143 21 239 126 20 227 127 8 240 120 3 240 120 3 240 120 3 -239 112 3 243 126 10 243 126 10 239 112 3 222 105 4 230 124 24 -216 104 20 183 101 57 48 4 0 14 1 0 8 0 0 8 0 0 -7 1 0 10 9 7 6 4 5 3 4 7 0 0 5 0 0 5 -0 0 4 0 0 2 0 0 2 0 0 0 1 0 0 1 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 -1 1 0 0 0 0 170 171 167 208 209 204 206 207 201 207 208 202 -204 205 200 206 207 201 0 1 0 0 1 0 3 3 1 86 87 84 -204 205 200 208 209 204 204 205 200 209 210 204 205 206 200 164 164 161 -5 5 3 5 5 3 0 0 0 2 2 2 1 1 3 1 1 3 -1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 1 3 -1 1 3 1 1 3 0 0 0 3 3 3 0 0 0 127 127 125 -208 209 204 206 207 202 205 206 201 208 209 204 197 198 192 221 221 215 -193 193 192 214 215 207 197 198 192 201 202 197 211 212 207 214 215 207 -211 211 209 69 70 68 2 2 0 13 14 7 0 0 0 0 0 0 -3 3 5 8 9 10 1 2 4 0 0 2 1 1 1 0 0 0 -1 1 0 2 2 0 0 0 0 126 126 124 206 207 201 205 207 197 -205 207 197 204 205 198 200 201 194 205 206 200 208 209 204 206 207 202 -206 207 202 206 207 202 206 207 202 206 207 202 206 207 201 206 207 201 -206 207 201 206 207 201 207 208 203 175 176 174 1 1 1 5 5 5 -0 0 0 86 87 84 209 209 208 216 217 214 207 208 203 205 206 201 -204 205 200 170 171 167 4 4 2 3 3 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 3 1 1 3 1 1 3 1 1 3 -1 1 3 1 1 3 2 2 2 1 1 1 7 5 3 164 164 161 -209 210 205 209 210 205 204 205 200 209 210 205 203 203 202 86 87 84 -1 1 1 0 0 0 2 2 2 0 0 0 1 2 4 1 1 3 -4 4 4 6 6 6 0 0 0 7 5 3 29 30 27 154 154 152 -209 210 204 204 205 198 197 198 192 221 221 215 199 199 195 207 208 202 -199 199 195 29 30 27 0 0 0 2 2 2 1 1 1 2 2 2 -1 1 1 3 3 3 0 0 0 0 0 0 6 6 6 6 6 6 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 2 0 0 2 0 1 0 0 1 0 0 1 0 0 1 0 -3 0 2 4 1 5 8 1 5 7 2 6 10 10 9 17 6 0 -33 6 2 231 175 56 244 176 40 244 159 4 249 164 6 244 159 4 -249 164 6 249 164 6 244 159 4 244 159 4 249 164 6 233 156 5 -229 155 20 242 158 39 220 161 40 221 134 40 198 136 53 183 98 20 -143 100 31 143 100 31 183 98 20 210 113 41 221 134 40 221 134 40 -230 124 24 227 127 8 227 127 8 240 120 3 243 126 10 239 112 3 -239 112 3 223 116 8 231 145 5 250 166 22 249 178 22 242 169 5 -249 164 6 249 164 6 249 164 6 242 169 5 242 169 5 233 156 5 -233 156 5 246 158 18 229 143 21 242 158 39 222 154 56 198 136 53 -183 98 20 143 100 31 143 100 31 143 100 31 183 101 57 210 113 41 -215 129 57 221 134 40 230 124 24 227 127 8 243 126 10 243 126 10 -240 120 3 240 120 3 239 112 3 241 109 9 241 109 9 232 104 4 -239 111 20 210 113 41 107 69 8 48 4 0 14 1 0 10 1 0 -7 1 0 4 1 3 3 0 2 3 4 7 0 0 5 0 0 5 -0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 207 202 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 124 206 206 204 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 0 -0 0 0 4 4 4 1 1 1 1 1 1 2 2 2 1 1 1 -1 1 1 0 0 0 170 171 167 208 209 204 206 207 202 207 208 202 -211 212 207 206 207 202 6 5 0 0 1 0 3 3 1 82 82 81 -207 208 203 206 207 202 204 205 200 209 210 204 203 204 199 175 176 174 -0 0 0 5 5 3 1 1 1 5 5 5 1 1 3 1 1 3 -1 1 3 1 1 3 1 1 3 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 1 3 -1 1 3 1 1 3 0 0 0 3 3 3 0 0 0 127 127 125 -208 209 204 206 207 202 205 206 201 208 209 204 213 213 209 200 201 194 -212 213 207 204 205 200 208 209 203 207 208 202 207 208 202 203 204 199 -203 203 202 193 193 192 29 30 27 0 0 0 6 6 6 0 0 0 -8 9 10 0 0 2 1 2 4 0 0 2 1 1 1 0 0 0 -1 1 1 2 2 0 0 0 0 126 126 124 205 206 200 211 212 205 -209 210 202 209 210 204 210 211 205 211 212 207 207 208 203 210 211 206 -207 208 203 207 208 203 207 208 203 207 208 203 207 208 203 207 208 202 -207 208 202 207 208 202 209 209 208 164 164 161 3 3 3 7 7 7 -0 0 0 86 86 84 208 208 206 202 202 199 210 211 206 203 204 199 -202 202 199 186 187 182 0 0 0 4 4 2 3 3 3 0 0 0 -1 1 1 1 1 1 1 1 3 1 1 3 1 1 3 1 1 3 -1 1 3 1 1 1 1 1 1 0 0 0 0 0 0 170 171 167 -208 209 204 207 208 203 201 202 197 212 213 207 208 208 206 82 82 81 -3 3 3 2 2 2 6 6 6 3 3 3 3 4 7 1 2 4 -1 1 1 1 1 1 3 3 1 7 5 3 69 70 68 210 211 205 -205 206 200 211 212 205 208 209 203 205 206 200 210 211 205 208 209 204 -209 210 205 154 154 152 6 6 6 0 0 0 3 3 3 3 3 3 -1 1 1 1 1 1 0 0 0 2 2 2 8 8 8 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -3 0 2 1 0 2 0 0 2 1 1 1 0 3 0 0 3 0 -1 2 0 4 0 1 8 1 5 14 1 4 25 6 3 22 1 2 -170 133 50 231 175 56 242 171 21 249 176 7 249 164 6 249 176 7 -233 156 5 242 171 21 246 158 18 246 158 18 246 158 18 242 158 39 -222 154 56 170 133 50 143 69 23 74 34 6 26 1 0 26 1 0 -33 6 2 26 1 0 30 1 2 35 1 0 74 34 6 143 69 23 -210 113 41 221 134 40 230 124 24 223 116 8 240 120 3 240 120 3 -239 112 3 227 127 8 246 158 18 249 178 22 249 176 7 242 169 5 -244 159 4 249 164 6 242 169 5 244 159 4 249 164 6 233 156 5 -229 155 20 242 158 39 222 154 56 183 98 20 107 69 8 72 12 0 -35 1 0 30 1 2 30 1 2 30 1 2 35 1 0 48 4 0 -74 34 6 143 100 31 198 136 53 221 134 40 223 116 8 239 126 20 -240 120 3 239 112 3 239 112 3 239 112 3 239 112 3 232 104 4 -232 104 4 229 114 40 210 113 41 104 34 7 26 1 0 9 1 3 -7 2 6 8 9 10 3 0 2 6 4 5 1 0 6 0 0 4 -3 0 0 3 0 0 2 1 0 1 1 3 0 0 4 0 0 4 -1 1 3 1 1 1 126 126 124 206 207 202 208 209 204 206 207 201 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 2 -0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 -1 1 1 5 5 5 124 124 124 211 211 209 201 202 197 212 213 207 -214 215 207 204 205 200 82 82 81 5 5 3 9 9 9 0 0 0 -3 4 7 1 2 4 1 1 3 1 1 3 3 4 7 0 0 0 -1 1 1 0 0 0 170 171 167 201 202 197 206 207 202 205 206 201 -213 214 212 207 207 205 1 1 0 6 6 6 0 0 0 29 30 27 -211 212 207 206 207 202 208 209 204 201 202 197 212 213 207 186 187 182 -1 1 0 13 14 7 0 0 0 7 7 7 1 2 4 3 1 7 -3 1 7 0 0 2 0 0 2 6 6 6 6 6 6 4 4 4 -1 1 1 0 0 0 8 8 8 2 2 2 0 0 0 3 3 3 -3 4 7 0 0 2 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 206 207 202 208 209 204 202 202 199 210 211 206 -206 207 202 175 176 174 204 205 200 213 213 209 201 202 197 213 214 212 -206 206 204 206 206 204 164 164 161 10 9 7 0 0 0 10 10 9 -0 0 2 8 9 10 1 2 4 3 3 5 1 1 3 0 0 0 -0 0 0 2 2 2 4 4 4 119 119 117 208 209 203 205 206 200 -213 213 209 207 208 203 207 208 203 205 206 201 211 211 209 204 204 203 -208 208 206 208 208 206 208 208 206 208 208 206 208 208 206 208 209 204 -208 209 204 208 208 206 208 208 206 175 176 174 3 3 3 0 0 0 -10 9 7 65 52 28 211 211 209 197 198 192 207 208 203 205 206 201 -202 202 199 175 176 174 0 0 0 4 4 4 6 6 6 0 0 0 -4 4 2 2 2 0 0 0 0 2 2 2 0 0 0 1 1 1 -6 6 6 0 0 0 4 4 4 2 2 0 2 2 0 175 176 174 -202 202 199 201 202 197 216 217 214 203 204 199 209 209 208 69 70 68 -8 9 10 3 3 5 1 1 3 0 0 2 8 9 10 0 0 2 -1 1 1 0 0 0 4 4 2 29 30 27 186 187 182 203 204 199 -211 212 207 205 206 200 208 209 204 204 204 203 203 203 202 216 217 214 -204 204 203 199 199 198 119 119 117 0 0 0 13 14 7 1 1 0 -7 7 7 2 2 2 0 0 2 8 9 10 1 0 5 3 3 5 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -3 0 2 1 0 2 0 0 2 0 0 0 1 0 0 1 2 0 -0 2 0 1 1 0 8 3 8 14 1 4 18 0 0 107 69 8 -220 161 40 244 176 40 236 169 8 242 169 5 249 176 7 244 159 4 -249 164 6 233 156 5 242 171 21 229 155 20 242 158 39 222 154 56 -107 69 8 74 34 6 18 0 0 14 1 0 10 1 0 7 0 0 -10 1 0 11 1 0 10 1 0 18 1 4 22 1 2 26 1 0 -72 12 0 143 69 23 210 113 41 221 134 40 223 116 8 243 126 10 -222 105 4 247 146 18 244 176 40 236 169 8 249 176 7 249 164 6 -249 164 6 244 159 4 244 159 4 249 176 7 246 158 18 242 158 39 -231 175 56 198 136 53 104 34 7 72 12 0 33 6 2 18 0 0 -14 1 4 8 3 8 9 3 6 8 0 0 17 1 0 25 6 3 -26 1 0 35 1 0 74 34 6 183 98 20 210 113 41 230 124 24 -239 111 20 239 112 3 243 126 10 241 109 9 239 112 3 232 104 4 -232 104 4 222 105 4 216 104 20 143 69 23 48 4 0 10 1 0 -6 4 5 3 0 4 6 4 5 4 1 3 1 0 5 0 0 4 -3 0 0 3 0 0 2 1 0 0 1 3 0 0 4 0 0 4 -1 1 3 1 1 1 126 126 124 206 207 202 208 209 204 206 207 201 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 2 -0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 -2 2 2 0 0 0 124 124 124 204 204 203 207 208 203 206 207 202 -201 202 197 206 207 201 86 87 84 0 0 0 0 0 0 10 10 9 -0 0 2 0 0 2 7 11 16 1 2 4 0 0 2 0 0 2 -0 0 0 2 2 2 164 164 161 213 214 212 209 210 205 211 212 207 -206 206 206 208 208 207 1 1 0 3 3 1 2 2 0 10 10 9 -193 193 192 206 207 202 205 206 201 212 213 207 206 206 204 207 207 205 -0 0 0 0 0 0 10 10 9 0 0 0 8 8 8 1 0 5 -1 0 5 8 8 8 8 8 8 0 0 2 0 0 0 0 0 0 -6 6 6 5 5 5 2 2 2 1 1 1 5 5 5 0 0 0 -0 0 2 9 9 9 0 0 0 3 3 3 0 0 0 127 127 125 -208 208 206 206 206 204 206 207 202 208 209 204 210 211 206 204 205 200 -141 141 139 1 2 0 164 164 161 201 202 197 212 213 207 199 199 195 -204 204 203 204 204 203 203 203 202 119 119 117 4 4 4 4 4 4 -8 9 10 1 2 4 1 1 3 1 2 4 3 3 5 3 3 5 -0 0 0 1 1 1 6 6 6 132 133 128 213 214 212 209 210 204 -208 209 204 204 205 200 208 209 204 175 176 174 164 164 161 170 171 167 -170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 -170 171 167 170 171 167 170 171 167 132 133 128 20 16 18 2 2 2 -0 0 0 10 9 7 199 199 195 216 217 214 210 211 206 209 210 205 -211 211 209 203 203 202 10 10 9 2 2 2 0 0 0 10 10 9 -0 0 0 1 1 0 2 2 2 6 6 6 2 2 2 0 0 0 -3 3 3 0 0 0 0 0 0 7 5 3 3 3 1 193 193 192 -213 213 209 204 205 200 205 206 200 209 210 205 204 204 203 10 10 9 -0 0 2 3 3 5 3 4 7 8 8 8 1 1 3 1 1 3 -1 1 1 8 8 8 1 1 0 132 133 128 207 208 203 212 213 207 -200 201 194 210 211 206 199 199 195 216 217 214 208 208 206 204 204 203 -207 207 205 216 217 214 175 176 174 29 30 27 0 0 0 10 10 9 -1 1 1 4 4 4 0 0 2 2 1 5 0 0 4 3 3 5 -0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 2 1 0 1 3 0 0 5 1 0 5 4 0 2 4 0 0 -0 0 0 0 2 0 1 7 3 10 7 0 26 1 0 170 133 50 -231 175 56 249 178 22 236 169 8 242 171 21 236 169 8 236 169 8 -249 164 6 249 164 6 246 158 18 242 158 39 198 136 53 74 34 6 -48 4 0 17 1 0 10 1 0 15 7 8 15 7 8 6 1 3 -5 1 0 3 1 0 9 3 3 6 0 0 11 1 0 25 6 3 -26 1 0 35 1 0 104 34 7 183 101 57 221 134 40 223 116 8 -227 127 8 244 176 40 249 178 22 236 169 8 250 166 22 249 164 6 -249 164 6 249 178 22 244 159 4 233 156 5 229 155 20 231 175 56 -143 100 31 48 4 0 25 6 3 8 0 0 3 1 0 2 6 0 -2 5 5 0 2 4 0 3 0 0 2 0 3 0 0 8 0 0 -14 1 0 17 6 0 17 1 0 48 4 0 107 69 8 215 129 57 -230 124 24 241 109 9 241 109 9 241 109 9 223 116 8 223 116 8 -241 109 9 241 109 9 230 106 20 210 113 41 104 34 7 26 1 0 -9 1 0 2 0 1 10 9 7 4 1 3 2 0 3 0 0 2 -1 0 0 1 0 0 1 1 1 0 2 1 0 0 2 0 0 2 -1 1 1 1 1 1 126 126 124 206 207 202 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 2 0 0 2 1 1 3 -0 0 2 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 -7 7 7 2 2 2 124 124 124 204 204 203 213 214 212 211 212 207 -203 204 199 214 215 207 119 119 117 4 4 2 4 4 4 2 2 2 -0 0 0 7 7 7 0 0 2 3 3 5 4 4 4 1 1 1 -6 6 6 0 0 0 175 176 174 203 203 202 199 199 195 206 207 202 -209 209 208 209 209 208 3 3 1 2 2 0 0 0 0 0 0 0 -175 176 174 209 210 205 207 208 203 201 202 197 216 217 214 199 199 195 -104 104 103 4 4 2 0 0 0 13 14 7 1 1 3 1 1 3 -0 0 2 0 0 2 1 2 4 4 4 4 8 8 8 8 8 8 -9 9 9 0 0 0 2 2 2 10 10 9 2 2 2 4 4 4 -9 9 9 0 0 0 0 0 0 3 3 1 0 0 0 127 127 125 -208 209 204 206 207 202 206 207 202 208 209 204 205 206 201 154 154 152 -0 1 0 6 5 0 29 30 27 197 198 192 202 202 199 211 211 209 -210 211 206 207 208 203 213 214 212 207 207 205 104 104 103 0 0 0 -10 10 9 0 0 0 1 1 1 1 1 1 1 1 3 3 3 5 -2 2 2 0 0 0 0 0 0 127 127 125 201 202 197 205 206 200 -210 211 205 213 213 209 202 202 199 86 87 84 10 10 9 0 0 0 -1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 -1 1 0 1 1 0 6 6 6 3 4 7 0 0 0 6 6 6 -10 9 7 0 0 0 186 187 182 205 206 201 204 205 200 205 206 201 -205 206 201 206 207 202 69 70 68 10 9 7 3 3 3 2 2 2 -6 6 6 4 4 4 0 0 0 0 0 0 0 0 0 3 3 3 -6 6 6 1 1 1 9 9 9 5 5 3 69 70 68 206 207 202 -211 212 207 206 207 202 203 204 199 207 208 203 186 187 182 4 4 4 -6 6 6 7 7 7 0 0 0 1 1 1 4 4 4 5 5 5 -0 0 0 0 0 0 86 87 84 203 203 202 213 214 212 199 199 195 -208 209 203 206 207 202 211 211 209 175 176 174 211 211 209 199 199 195 -208 208 206 209 209 208 213 214 212 141 141 139 10 10 9 7 7 7 -1 1 1 0 0 0 8 8 8 0 0 2 3 4 7 3 4 7 -0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 2 4 0 2 4 0 0 5 2 0 5 8 1 5 6 1 3 -1 0 0 0 2 0 0 6 1 8 10 3 74 34 6 231 175 56 -244 176 40 242 169 5 236 169 8 242 171 21 236 169 8 249 178 22 -231 145 5 250 166 22 242 158 39 198 136 53 74 34 6 26 1 0 -11 1 0 11 1 0 15 7 8 15 7 8 6 1 3 6 1 3 -7 5 3 6 5 0 4 0 0 7 2 6 8 3 8 8 3 14 -8 1 5 14 1 0 35 1 0 72 12 0 210 113 41 216 104 20 -246 158 18 249 178 22 236 169 8 242 169 5 249 164 6 249 164 6 -249 164 6 244 159 4 249 164 6 244 176 40 220 161 40 170 133 50 -33 6 2 17 1 0 17 6 0 5 5 3 0 6 1 0 6 1 -0 2 1 0 3 0 0 6 1 1 7 3 7 9 5 2 2 0 -6 5 0 20 16 18 14 1 4 14 1 0 48 4 0 107 69 8 -221 134 40 230 124 24 239 111 20 239 111 20 223 116 8 223 116 8 -241 109 9 241 109 9 230 106 20 210 113 41 143 100 31 35 1 0 -11 1 0 6 6 6 7 7 7 5 5 3 2 1 0 0 0 0 -1 0 0 0 0 2 1 1 3 1 1 3 0 0 0 0 0 0 -1 1 1 1 1 1 126 126 126 206 206 204 208 208 206 206 207 202 -208 209 204 207 207 205 86 86 84 2 2 2 0 0 2 1 1 3 -0 0 2 3 4 7 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 -0 0 0 2 2 2 86 87 84 203 204 199 201 202 197 208 209 203 -204 205 200 207 208 202 127 127 125 3 3 1 0 0 0 1 1 1 -6 6 6 1 1 1 1 2 4 7 7 7 0 0 0 0 0 0 -8 8 8 1 1 0 202 202 199 199 199 195 209 210 205 206 207 202 -213 214 212 203 203 202 5 5 3 7 5 3 0 0 0 7 7 7 -141 141 139 209 210 205 203 204 199 213 213 209 197 198 192 221 221 215 -154 154 152 13 14 7 5 5 3 0 0 0 0 0 0 3 3 5 -3 3 5 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 -0 0 0 20 16 18 3 3 3 0 0 0 7 7 7 10 10 9 -1 1 1 1 1 1 0 0 0 3 3 1 0 0 0 127 127 125 -208 209 204 206 207 202 206 207 202 208 209 204 211 212 207 82 82 81 -6 5 0 3 3 1 0 1 0 69 70 68 203 203 202 204 204 203 -208 209 204 211 212 207 202 202 199 211 211 209 197 198 192 69 70 68 -0 0 0 7 7 7 2 2 2 0 0 0 0 0 2 0 0 2 -3 3 3 4 4 4 0 0 0 124 124 124 212 213 207 209 210 204 -204 205 200 205 206 200 203 204 199 82 82 81 0 0 0 3 3 1 -3 3 1 3 3 1 3 3 1 3 3 1 3 3 1 3 3 1 -3 3 1 3 3 3 1 1 3 3 3 5 7 7 7 1 1 1 -1 1 0 3 3 1 164 164 161 208 209 204 210 211 206 209 210 205 -204 205 200 202 202 199 127 127 125 3 3 1 2 2 2 0 0 0 -2 2 2 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 -1 1 1 0 0 0 8 8 8 0 0 0 132 133 128 206 206 204 -206 206 204 208 209 204 213 213 209 209 209 208 154 154 152 4 4 4 -0 0 0 0 0 0 5 5 5 3 3 3 4 4 4 0 0 0 -3 3 3 20 16 18 186 187 182 202 202 199 212 213 207 204 205 200 -211 212 207 203 204 199 141 141 139 82 82 81 206 206 204 211 211 209 -211 211 209 199 199 198 207 208 203 213 213 209 104 104 103 1 1 0 -9 9 9 0 0 0 8 9 10 1 1 3 2 1 5 0 0 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 5 0 1 3 1 1 1 2 0 3 8 1 5 8 1 5 -1 0 2 0 2 0 0 6 1 10 7 0 143 100 31 231 175 56 -242 171 21 242 169 5 242 171 21 242 171 21 242 171 21 242 169 5 -242 169 5 242 171 21 231 175 56 74 34 6 25 6 3 10 7 0 -13 14 7 2 2 0 6 0 0 9 1 3 8 0 0 5 0 0 -3 0 2 3 3 3 7 5 3 6 6 6 3 1 7 2 3 13 -8 3 14 14 1 4 18 0 0 35 1 0 104 34 7 198 136 53 -242 158 39 249 178 22 249 178 22 236 169 8 249 176 7 249 164 6 -249 176 7 244 159 4 236 169 8 231 175 56 198 136 53 26 1 0 -26 16 7 20 16 18 6 0 0 2 1 0 1 1 3 1 2 4 -2 2 0 1 1 0 0 2 4 1 3 4 0 2 4 7 7 7 -7 0 0 7 0 0 6 0 0 15 7 8 18 0 0 35 1 0 -143 69 23 210 113 41 230 124 24 223 116 8 239 111 20 232 104 4 -232 104 4 241 109 9 232 104 4 216 104 20 183 101 57 48 4 0 -18 0 0 8 3 8 0 2 1 2 6 0 0 3 0 1 2 0 -1 0 0 3 0 4 4 1 5 2 0 5 0 0 2 0 0 2 -1 1 3 1 1 1 126 126 126 206 206 204 208 208 206 206 206 204 -208 208 206 207 207 205 86 86 84 2 2 2 0 0 2 1 1 3 -0 0 2 3 4 7 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -5 5 5 9 9 9 69 70 68 216 217 214 205 206 201 213 213 209 -214 215 207 209 210 204 170 171 167 0 0 0 10 9 7 10 10 9 -0 0 0 6 6 6 1 1 1 7 7 7 3 3 3 3 3 3 -1 1 0 65 52 28 209 209 208 210 211 206 216 217 214 201 202 197 -199 199 198 175 176 174 0 0 0 4 4 2 0 0 0 6 6 6 -69 70 68 205 206 201 210 211 206 202 202 199 209 210 205 206 207 202 -199 199 195 65 52 28 6 5 0 4 4 2 9 9 9 3 3 3 -3 3 3 3 3 3 2 2 2 1 1 0 1 1 0 6 6 6 -6 6 6 29 30 27 7 7 7 1 1 0 1 1 0 5 5 3 -2 2 0 6 6 6 0 0 0 3 3 1 0 0 0 127 127 125 -208 209 204 206 207 202 206 207 202 208 209 204 207 208 203 86 86 84 -3 3 1 4 4 2 4 4 2 0 0 0 104 104 103 211 211 209 -199 199 195 208 209 204 202 202 199 204 205 200 204 204 203 175 176 174 -29 30 27 0 0 0 4 4 4 5 5 5 6 6 6 1 1 1 -0 0 0 4 4 4 2 2 2 124 124 124 207 208 202 205 206 200 -206 207 201 209 210 204 211 212 207 86 87 84 2 2 0 3 3 1 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 2 3 3 5 6 6 6 0 0 0 -3 3 1 7 7 7 104 104 103 210 211 206 208 209 204 207 208 203 -210 211 206 212 213 207 186 187 182 29 30 27 0 0 0 20 16 18 -0 0 0 1 1 1 4 4 4 4 4 4 2 2 2 2 2 2 -7 7 7 20 16 18 0 0 0 29 30 27 186 187 182 206 206 204 -209 209 208 202 202 199 203 203 202 209 209 208 119 119 117 2 2 2 -3 3 3 1 1 1 4 4 4 3 3 3 0 0 0 2 2 2 -10 9 7 104 104 103 211 211 209 209 209 208 199 199 195 211 212 207 -203 204 199 201 202 197 29 30 27 10 10 9 141 141 139 216 217 214 -199 199 195 211 212 207 202 202 199 206 207 202 193 193 192 29 30 27 -0 0 0 2 2 2 1 1 3 3 4 7 0 0 2 1 1 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 5 1 1 3 1 1 1 2 0 1 4 1 5 4 1 5 -3 0 4 0 0 0 4 8 7 10 7 0 198 136 53 231 175 56 -242 171 21 249 176 7 242 171 21 242 171 21 249 178 22 233 156 5 -250 166 22 229 155 20 107 69 8 48 4 0 17 6 0 13 14 7 -6 5 0 3 1 0 8 0 0 15 7 8 14 1 0 7 1 0 -2 0 3 1 1 3 1 0 0 1 1 1 2 3 13 7 11 16 -8 3 14 4 0 2 8 0 0 25 6 3 35 1 0 143 100 31 -231 175 56 249 178 22 249 176 7 242 169 5 242 169 5 242 169 5 -249 176 7 236 169 8 242 171 21 222 154 56 74 34 6 25 6 3 -8 3 8 3 1 7 9 3 6 9 3 6 8 3 8 8 3 8 -9 3 6 5 1 0 1 0 0 0 0 2 3 3 5 5 3 3 -8 0 0 17 1 0 14 1 0 17 1 0 17 1 0 35 1 0 -72 12 0 183 98 20 217 124 25 223 116 8 241 109 9 232 104 4 -241 109 9 232 104 4 230 106 20 216 104 20 183 101 57 48 4 0 -26 1 0 8 1 5 0 1 0 0 6 1 0 3 0 1 2 0 -3 0 0 3 0 4 3 1 7 4 1 5 0 0 4 0 1 2 -0 1 3 1 1 1 126 126 126 206 206 204 208 208 206 206 206 204 -208 208 206 207 207 205 86 86 84 2 2 2 0 0 2 1 1 3 -0 0 2 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 2 2 0 0 0 20 16 18 202 202 199 207 208 203 203 204 199 -204 205 200 201 202 197 213 214 212 69 70 68 0 0 0 0 0 0 -0 0 0 10 10 9 0 0 0 2 2 2 10 10 9 0 0 0 -2 2 0 132 133 128 206 207 202 212 213 207 202 202 199 206 207 202 -204 204 203 154 154 152 0 0 0 0 0 0 3 3 1 0 0 0 -8 10 3 186 187 182 207 208 203 210 211 206 199 199 195 211 212 207 -207 208 203 175 176 174 6 5 0 0 1 0 0 0 0 1 1 1 -8 8 8 0 0 0 0 0 0 7 7 7 1 1 0 0 0 0 -0 0 0 154 154 152 170 171 167 82 82 81 3 3 1 0 0 0 -1 1 0 2 2 0 0 0 0 3 3 1 0 0 0 127 127 125 -208 209 204 206 207 202 206 207 202 208 209 204 208 209 204 86 86 84 -0 0 0 3 3 1 10 9 7 0 0 0 10 10 9 154 154 152 -211 212 207 208 209 204 207 208 203 211 212 207 202 202 199 213 214 212 -141 141 139 10 9 7 0 0 0 0 0 0 8 8 8 5 5 5 -0 0 0 0 0 0 0 0 0 126 126 124 207 208 202 205 207 197 -209 210 204 206 207 201 208 209 204 86 87 84 4 4 2 0 0 0 -2 2 0 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 8 9 10 3 4 7 3 3 3 1 1 1 -5 5 3 1 1 0 29 30 27 207 208 203 205 206 201 204 205 200 -208 209 204 209 210 205 205 206 201 126 126 124 20 16 18 0 0 0 -1 1 1 4 4 4 4 4 4 0 0 0 1 1 1 6 6 6 -2 2 2 0 0 0 7 7 7 132 133 128 204 204 203 206 206 206 -211 211 209 208 208 206 208 208 206 209 209 208 29 30 27 0 0 0 -7 7 7 3 3 3 1 1 1 9 9 9 7 7 7 0 0 0 -69 70 68 204 204 203 206 206 204 216 217 214 197 198 192 207 208 203 -210 211 206 119 119 117 0 0 0 2 2 0 29 30 27 193 193 192 -201 202 197 213 214 212 209 210 205 206 207 202 213 214 212 141 141 139 -9 9 9 0 0 0 0 0 2 3 3 5 3 4 7 6 6 6 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 1 5 4 1 3 2 1 0 2 1 0 3 0 4 3 0 4 -3 0 2 3 0 4 8 3 14 17 1 0 170 133 50 231 175 56 -242 171 21 249 176 7 249 176 7 242 169 5 242 169 5 249 176 7 -244 159 4 242 158 39 183 98 20 104 34 7 72 12 0 30 1 2 -26 1 0 22 1 2 18 1 4 11 1 0 7 0 0 7 1 0 -9 4 5 9 4 5 10 9 7 2 2 2 0 0 5 0 2 6 -3 4 7 5 5 5 5 3 3 8 0 0 18 0 0 48 4 0 -231 175 56 244 176 40 242 169 5 249 176 7 242 169 5 236 169 8 -244 159 4 229 155 20 231 175 56 170 133 50 22 1 2 17 6 0 -6 1 3 4 1 5 8 1 5 8 1 5 2 0 5 2 0 5 -7 2 6 6 1 3 5 1 0 6 5 0 1 0 0 7 1 0 -14 1 0 17 1 0 22 1 2 33 6 2 48 4 0 72 12 0 -107 69 8 183 98 20 223 116 8 232 104 4 241 109 9 239 103 3 -239 103 3 232 104 4 230 106 20 210 113 41 183 101 57 48 4 0 -30 1 2 8 1 5 0 2 2 0 6 1 0 3 0 1 2 0 -4 0 0 4 1 5 3 1 7 3 1 7 0 0 4 0 1 2 -0 2 1 1 1 1 126 126 126 206 206 204 208 208 206 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6 6 6 0 0 0 5 5 3 164 164 161 216 217 214 206 207 202 -207 208 202 209 210 204 201 202 197 164 164 161 20 16 18 3 3 1 -13 14 7 0 0 0 20 16 18 0 0 0 1 1 0 13 14 7 -69 70 68 193 193 192 207 208 203 207 208 203 203 204 199 216 217 214 -213 214 212 104 104 103 6 6 6 1 1 1 5 5 3 2 2 0 -0 1 0 119 119 117 201 202 197 213 214 212 210 211 206 201 202 197 -209 210 204 212 213 207 132 133 128 8 10 3 4 4 2 0 0 0 -10 10 9 4 4 2 0 0 0 3 3 1 0 1 0 13 14 7 -119 119 117 203 204 199 201 202 197 209 210 205 199 199 195 104 104 103 -4 4 2 1 1 0 0 0 0 3 3 1 0 1 0 127 127 125 -208 209 204 206 207 202 206 207 202 208 209 204 211 212 207 86 87 84 -20 16 18 1 1 0 0 0 0 8 8 8 0 0 0 29 30 27 -175 176 174 209 210 204 205 206 201 210 211 206 210 211 206 201 202 197 -221 221 215 104 104 103 20 16 18 0 0 0 0 0 0 5 5 5 -1 1 1 1 1 1 2 2 2 132 133 128 209 210 204 209 210 202 -214 215 207 207 208 202 209 210 205 86 87 84 7 5 3 0 0 0 -2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 1 2 4 0 0 2 3 3 3 2 2 2 -6 6 6 0 0 0 6 6 6 141 141 139 212 213 207 211 212 207 -208 209 204 203 204 199 207 208 203 199 199 195 104 104 103 13 14 7 -3 3 1 0 0 0 1 1 0 3 3 1 5 5 3 2 2 0 -0 0 0 6 6 6 104 104 103 199 199 198 211 211 209 204 204 203 -208 208 206 207 207 205 209 209 208 141 141 139 2 2 2 3 3 3 -0 0 0 0 0 0 4 4 2 10 9 7 0 0 0 10 10 9 -170 171 167 221 221 215 201 202 197 203 204 199 211 212 207 212 213 207 -175 176 174 13 14 7 7 7 7 3 3 1 0 0 0 119 119 117 -206 207 202 212 213 207 206 207 202 209 210 205 204 205 200 216 217 214 -104 104 103 7 7 7 3 3 3 0 0 0 3 4 7 0 0 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 1 3 4 0 1 2 1 0 2 1 0 4 0 2 4 0 2 -3 0 2 3 0 4 3 1 7 17 1 0 107 69 8 231 175 56 -242 171 21 242 169 5 242 169 5 236 169 8 249 176 7 242 169 5 -249 164 6 229 155 20 242 158 39 222 154 56 222 154 56 170 133 50 -143 100 31 104 34 7 48 4 0 35 1 0 26 1 0 18 0 0 -11 1 0 14 1 0 8 0 0 5 1 0 1 7 3 0 6 1 -0 1 0 2 2 0 6 6 6 7 2 6 15 7 8 22 1 2 -170 133 50 231 175 56 244 176 40 236 169 8 242 171 21 242 171 21 -242 171 21 244 176 40 222 154 56 74 34 6 17 6 0 4 0 1 -7 5 3 3 0 2 3 0 2 8 3 8 8 1 5 6 1 3 -14 1 4 14 1 0 11 1 0 17 1 0 25 6 3 26 1 0 -33 6 2 74 34 6 107 69 8 143 100 31 198 136 53 222 154 56 -222 154 56 242 158 39 227 127 8 239 112 3 243 126 10 239 103 3 -241 109 9 239 111 20 230 106 20 210 113 41 183 101 57 48 4 0 -26 1 0 14 1 4 3 3 3 0 3 0 0 3 0 1 2 0 -4 0 1 4 1 5 3 1 7 1 0 6 0 0 2 0 1 0 -1 1 1 1 1 0 126 126 124 206 207 202 208 209 204 206 207 202 -208 209 204 207 208 203 86 86 84 2 2 0 0 0 0 1 1 1 -0 0 0 4 4 2 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 2 2 0 0 0 0 0 0 119 119 117 213 213 209 207 208 203 -208 209 203 209 210 204 207 208 203 216 217 214 141 141 139 29 30 27 -1 1 0 10 10 9 0 0 0 4 4 2 4 4 2 69 70 68 -193 193 192 213 214 212 207 208 203 201 202 197 211 212 207 201 202 197 -199 199 198 29 30 27 2 2 2 3 3 3 0 0 0 4 4 2 -2 2 0 2 2 0 197 198 192 204 205 200 206 207 202 205 206 201 -213 213 209 197 198 192 210 211 205 164 164 161 69 70 68 2 2 0 -0 0 0 5 5 3 1 2 0 2 2 0 29 30 27 124 124 124 -206 207 202 216 217 214 203 204 199 213 214 212 202 202 199 211 211 209 -132 133 128 2 2 0 0 0 0 3 3 1 0 1 0 127 127 125 -208 209 204 206 207 202 206 207 202 208 209 204 206 207 202 86 87 84 -1 1 0 7 7 7 5 5 5 2 2 2 6 6 6 0 0 0 -69 70 68 193 193 192 204 205 200 208 209 204 201 202 197 210 211 206 -203 203 202 199 199 198 69 70 68 13 14 7 0 0 0 4 4 4 -2 2 2 1 1 1 0 0 0 126 126 124 203 204 199 204 205 198 -210 211 205 203 204 199 208 209 204 82 82 81 4 4 2 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 2 1 2 4 7 7 7 1 1 1 -2 2 0 0 0 0 3 3 1 69 70 68 203 204 199 204 205 200 -208 209 204 208 209 204 209 210 205 213 213 209 210 211 206 126 126 124 -29 30 27 3 3 1 0 0 0 6 6 6 2 2 0 0 0 0 -29 30 27 119 119 117 209 209 208 207 207 205 207 207 205 202 202 199 -208 208 206 204 204 203 204 204 203 69 70 68 2 2 2 1 1 1 -3 3 3 2 2 2 2 2 0 0 0 0 4 4 2 124 124 124 -213 214 212 197 198 192 213 213 209 201 202 197 213 214 212 204 205 200 -86 87 84 0 1 0 2 2 0 0 0 0 10 10 9 1 1 0 -170 171 167 210 211 206 205 206 201 206 207 202 205 206 201 199 199 195 -202 202 199 29 30 27 2 2 2 0 0 0 3 3 5 1 1 3 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 0 0 4 0 0 1 1 0 2 0 1 5 0 0 7 0 0 -4 0 0 2 0 1 8 3 14 17 6 0 33 6 2 222 154 56 -244 176 40 249 176 7 236 169 8 236 169 8 249 176 7 249 164 6 -244 159 4 233 156 5 247 146 18 246 158 18 242 158 39 242 158 39 -222 154 56 222 154 56 222 154 56 170 133 50 143 100 31 107 69 8 -74 34 6 26 1 0 25 6 3 11 1 0 6 5 0 0 6 1 -8 10 3 10 7 0 4 0 0 6 1 3 8 3 8 11 1 0 -74 34 6 222 154 56 231 175 56 225 170 23 242 171 21 242 171 21 -225 170 23 231 175 56 143 100 31 26 1 0 14 1 0 6 1 3 -7 1 0 1 1 0 0 3 0 0 3 0 7 5 3 10 1 0 -18 0 0 26 1 0 35 1 0 74 34 6 107 69 8 143 100 31 -198 136 53 222 154 56 222 154 56 222 154 56 242 158 39 242 158 39 -246 158 18 247 146 18 241 129 3 239 112 3 239 112 3 239 112 3 -241 109 9 230 106 20 216 104 20 210 113 41 143 100 31 33 6 2 -14 1 0 15 7 8 1 0 0 1 1 1 1 1 0 2 1 0 -4 0 1 2 0 3 0 2 6 0 2 6 0 2 0 1 2 0 -0 0 0 6 6 6 124 124 124 206 207 202 210 211 206 207 208 202 -210 211 205 201 202 197 170 171 167 170 171 167 170 171 167 170 171 167 -170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 170 171 167 -164 164 161 175 176 174 164 164 161 170 171 167 69 70 68 2 2 2 -2 2 2 2 2 2 0 0 0 0 0 0 197 198 192 203 204 199 -208 209 203 208 209 203 203 204 199 205 206 201 210 211 206 193 193 192 -154 154 152 119 119 117 119 119 117 119 119 117 170 171 167 204 204 203 -209 209 208 204 204 203 207 208 203 204 205 200 207 208 203 208 209 204 -119 119 117 20 16 18 0 0 0 6 6 6 0 0 0 5 5 3 -0 0 0 4 4 2 86 86 84 203 203 202 213 214 212 207 208 203 -205 206 200 203 204 199 213 213 209 201 202 197 209 209 208 154 154 152 -127 127 125 124 124 124 124 124 124 141 141 139 186 187 182 212 213 207 -207 208 203 211 212 207 206 207 202 201 202 197 209 209 208 193 193 192 -69 70 68 0 0 0 5 5 3 2 2 0 0 0 0 124 124 124 -209 209 208 211 211 209 209 209 208 208 208 206 207 207 205 86 87 84 -5 5 3 0 0 0 2 2 2 0 0 0 3 3 3 0 0 0 -0 1 0 104 104 103 204 205 200 211 212 207 201 202 197 209 210 205 -202 202 199 206 206 204 186 187 182 29 30 27 0 0 0 1 1 1 -6 6 6 0 0 0 8 8 8 124 124 124 208 209 204 206 207 201 -212 213 207 207 208 202 205 206 201 82 82 81 5 5 3 0 0 0 -0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -0 0 2 0 0 2 0 0 2 0 0 2 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 127 127 125 204 204 203 -203 204 199 206 207 202 213 214 212 201 202 197 213 213 209 204 205 200 -199 199 195 154 154 152 126 126 124 119 119 117 119 119 117 154 154 152 -193 193 192 212 213 207 206 207 202 208 209 204 204 205 200 208 209 204 -210 211 206 199 199 195 132 133 128 0 0 0 6 6 6 3 3 3 -4 4 4 0 0 0 13 14 7 5 5 3 69 70 68 199 199 195 -210 211 206 212 213 207 203 204 199 213 213 209 199 199 198 164 164 161 -3 3 1 3 3 1 7 5 3 1 1 0 2 2 0 10 9 7 -69 70 68 210 211 206 206 207 202 210 211 206 206 207 202 201 202 197 -216 217 214 154 154 152 3 3 3 4 4 4 3 4 7 1 2 4 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 1 0 1 2 0 1 1 0 1 1 0 5 0 0 5 0 0 -2 1 0 1 1 0 5 7 10 4 0 0 25 6 3 143 69 23 -222 154 56 242 171 21 249 178 22 236 169 8 242 169 5 249 164 6 -244 159 4 244 159 4 246 147 4 231 145 5 231 145 5 231 145 5 -231 145 5 229 155 20 246 158 18 229 155 20 220 161 40 222 154 56 -198 136 53 170 133 50 143 100 31 74 34 6 17 1 0 26 16 7 -7 1 0 10 1 0 10 1 0 9 4 5 2 0 5 26 16 7 -18 0 0 74 34 6 170 133 50 231 175 56 231 175 56 231 175 56 -231 175 56 143 100 31 33 6 2 11 1 0 6 0 0 7 2 6 -7 7 7 1 0 0 8 10 3 5 1 0 14 1 0 33 6 2 -74 34 6 143 100 31 198 136 53 222 154 56 222 154 56 220 161 40 -229 155 20 229 155 20 247 146 18 246 158 18 246 158 18 231 145 5 -244 159 4 244 159 4 247 146 18 246 147 4 240 120 3 232 104 4 -222 105 4 216 104 20 210 113 41 198 136 53 72 12 0 11 1 0 -11 1 0 5 1 0 9 4 5 3 0 2 2 0 3 2 0 3 -4 0 1 2 0 3 0 2 6 0 2 6 1 2 0 2 1 0 -6 5 0 4 4 2 126 126 124 204 205 200 206 207 201 205 206 200 -211 212 207 209 210 204 206 207 202 206 207 202 206 206 204 206 206 204 -206 207 202 206 207 202 206 207 201 206 207 201 208 209 204 204 205 200 -199 199 198 211 211 209 209 209 208 211 211 209 86 87 84 5 5 5 -8 8 8 0 0 0 6 6 6 5 5 3 86 87 84 210 211 206 -213 214 212 193 193 192 213 214 212 209 210 205 207 208 203 207 208 203 -205 206 201 207 208 203 209 209 208 209 209 208 213 214 212 199 199 198 -204 204 203 206 206 204 204 205 200 213 214 212 210 211 206 193 193 192 -29 30 27 0 0 0 2 2 2 5 5 5 0 0 0 7 7 7 -1 1 0 0 0 0 0 0 0 119 119 117 203 204 199 208 209 204 -201 202 197 211 212 207 197 198 192 211 212 207 209 209 208 199 199 198 -204 204 203 211 211 209 206 207 202 210 211 206 213 214 212 208 209 204 -203 204 199 213 213 209 207 208 203 213 214 212 199 199 198 119 119 117 -0 0 0 20 16 18 0 0 0 3 3 1 3 3 1 124 124 124 -203 203 202 202 202 199 206 206 204 207 207 205 209 209 208 82 82 81 -1 1 0 0 0 0 4 4 4 4 4 4 8 8 8 2 2 2 -13 14 7 0 1 0 141 141 139 201 202 197 216 217 214 203 204 199 -202 202 199 209 209 208 209 209 208 154 154 152 5 5 5 5 5 5 -2 2 2 9 9 9 0 0 0 132 133 128 204 205 200 203 204 199 -207 208 202 205 206 200 206 207 202 82 82 81 2 2 0 0 0 0 -0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -0 0 2 0 0 2 0 0 2 0 0 2 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 170 171 167 -213 213 209 197 198 192 203 204 199 202 202 199 212 213 207 209 210 205 -206 207 202 199 199 195 202 202 199 211 212 207 210 211 206 209 210 205 -209 210 205 206 207 202 209 210 205 213 214 212 209 210 205 202 202 199 -205 206 201 186 187 182 0 1 0 7 5 3 0 0 0 0 0 0 -5 5 5 4 4 4 0 0 0 7 5 3 154 154 152 207 208 203 -204 205 200 205 206 201 209 210 205 209 210 205 202 202 199 69 70 68 -0 0 0 3 3 1 0 0 0 0 0 0 1 1 0 0 0 0 -13 14 7 119 119 117 216 217 214 199 199 195 210 211 206 213 214 212 -199 199 195 209 209 208 104 104 103 0 0 0 7 11 16 0 0 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 3 0 0 2 0 0 2 0 1 1 0 2 0 1 2 0 1 -1 1 0 0 2 0 3 3 3 7 7 7 10 1 0 26 1 0 -198 136 53 222 154 56 242 158 39 229 155 20 233 156 5 233 156 5 -233 156 5 233 156 5 244 159 4 244 159 4 246 158 18 229 155 20 -246 158 18 233 156 5 244 159 4 244 159 4 246 158 18 242 158 39 -220 161 40 220 161 40 222 154 56 198 136 53 170 133 50 74 34 6 -17 1 0 14 1 0 7 1 0 2 0 3 5 7 10 3 0 4 -17 6 0 25 6 3 33 6 2 107 69 8 143 100 31 107 69 8 -74 34 6 33 6 2 11 1 0 13 14 7 3 1 7 8 9 10 -1 0 0 10 1 0 14 1 0 33 6 2 107 69 8 170 133 50 -222 154 56 220 161 40 229 143 21 242 158 39 229 155 20 229 155 20 -246 158 18 246 158 18 244 159 4 244 159 4 244 159 4 244 159 4 -233 156 5 233 156 5 246 158 18 246 158 18 246 147 4 241 129 3 -239 126 20 221 134 40 222 154 56 143 69 23 25 6 3 10 7 0 -10 7 0 4 0 0 6 4 5 7 2 6 2 0 5 4 1 3 -5 0 0 4 0 1 0 2 6 0 2 6 1 1 0 2 1 0 -1 2 0 0 0 0 127 127 125 209 210 205 206 207 201 203 204 199 -205 206 200 206 207 201 207 208 203 207 208 203 207 208 203 207 208 203 -207 208 203 207 208 203 207 208 202 207 208 202 213 213 209 207 208 203 -206 206 204 206 206 204 203 203 202 208 208 206 82 82 81 0 0 0 -3 3 3 2 2 2 0 0 0 3 3 1 6 6 6 126 126 124 -202 202 199 216 217 214 201 202 197 208 209 204 208 209 204 205 206 201 -207 208 203 207 208 203 204 204 203 207 207 205 199 199 195 216 217 214 -213 214 212 203 203 202 193 193 192 211 211 209 186 187 182 69 70 68 -0 0 0 0 0 0 7 7 7 1 1 1 0 0 0 5 5 5 -0 0 0 1 1 1 5 5 3 20 16 18 119 119 117 216 217 214 -213 213 209 206 207 202 204 205 200 211 212 207 202 202 199 206 206 204 -211 211 209 209 209 208 205 206 201 205 206 201 206 207 202 202 202 199 -207 208 203 209 210 205 207 207 205 211 211 209 104 104 103 20 16 18 -9 9 9 0 0 0 3 3 3 6 6 6 4 4 2 127 127 125 -208 208 206 206 206 204 213 214 212 213 214 212 209 209 208 82 82 81 -5 5 3 3 3 1 0 0 0 0 0 0 4 4 4 1 1 1 -3 3 1 5 5 3 0 0 0 175 176 174 204 204 203 213 214 212 -204 204 203 209 209 208 208 208 206 207 207 205 124 124 124 0 0 0 -1 1 1 2 2 2 8 8 8 119 119 117 209 210 205 210 211 205 -208 209 204 208 209 204 209 209 208 86 86 84 0 0 0 2 2 2 -0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 -0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 29 30 27 -170 171 167 221 221 215 209 209 208 209 209 208 199 199 198 204 205 200 -211 212 207 211 212 207 209 210 204 206 207 201 203 204 199 201 202 197 -204 205 200 207 208 202 205 206 201 206 207 202 211 212 207 211 212 207 -175 176 174 29 30 27 5 5 3 1 1 0 5 5 5 0 0 2 -0 0 0 8 8 8 6 6 6 119 119 117 216 217 214 207 208 203 -210 211 206 205 206 201 209 210 205 216 217 214 119 119 117 0 0 0 -7 7 7 7 7 7 2 2 2 2 2 2 7 5 3 3 3 1 -0 0 0 29 30 27 186 187 182 209 210 205 208 209 204 202 202 199 -213 214 212 199 199 195 206 206 206 29 30 27 0 0 2 8 9 10 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 3 0 0 3 0 0 2 0 1 1 0 1 1 1 0 2 1 -0 2 0 0 2 0 2 2 0 1 1 0 10 10 9 17 1 0 -72 12 0 222 154 56 222 154 56 229 155 20 229 155 20 233 156 5 -233 156 5 244 159 4 244 159 4 244 159 4 246 158 18 246 158 18 -244 159 4 244 159 4 244 159 4 244 159 4 244 159 4 246 158 18 -246 158 18 229 155 20 229 155 20 244 176 40 222 154 56 198 136 53 -74 34 6 33 6 2 14 1 0 7 1 0 2 3 8 3 1 7 -8 3 8 7 1 0 7 1 0 11 1 0 18 0 0 33 6 2 -18 0 0 7 0 0 10 9 7 0 1 0 0 2 6 3 3 5 -9 3 3 25 6 3 33 6 2 143 100 31 222 154 56 220 161 40 -229 155 20 242 171 21 244 159 4 246 147 4 244 159 4 244 159 4 -244 159 4 244 159 4 246 147 4 246 147 4 244 159 4 244 159 4 -242 171 21 233 156 5 233 156 5 246 158 18 246 158 18 242 158 39 -231 175 56 222 154 56 143 100 31 30 1 2 17 6 0 9 9 9 -4 1 3 4 1 3 1 0 2 7 7 7 2 0 5 2 0 3 -4 0 0 3 0 0 0 0 5 0 2 6 1 1 0 1 2 0 -10 9 7 4 4 2 132 133 128 210 211 206 209 210 205 207 208 202 -207 208 202 212 213 207 207 208 203 207 208 203 207 208 203 207 208 203 -207 208 203 207 208 203 207 208 203 207 208 202 206 207 202 203 204 199 -209 209 208 207 207 205 204 204 203 209 209 208 86 86 84 3 3 3 -1 1 1 4 4 4 1 1 1 0 0 0 0 0 0 20 16 18 -119 119 117 201 202 197 208 209 204 216 217 214 208 209 204 199 199 195 -209 210 205 213 213 209 207 207 205 208 208 206 221 221 215 199 199 195 -207 207 205 213 214 212 213 214 212 186 187 182 82 82 81 0 0 0 -7 7 7 6 6 6 3 3 3 0 0 0 1 1 1 2 2 2 -0 0 0 4 4 4 10 9 7 0 0 0 10 9 7 104 104 103 -186 187 182 208 209 204 204 205 200 204 205 200 207 207 205 208 208 206 -207 207 205 206 206 204 206 207 202 205 206 201 207 208 203 213 214 212 -209 210 205 209 210 205 186 187 182 119 119 117 13 14 7 0 0 0 -4 4 4 10 10 9 5 5 5 0 0 0 0 0 0 126 126 124 -211 211 209 204 204 203 209 209 208 202 202 199 208 208 206 82 82 81 -4 4 2 2 2 0 2 2 2 1 1 1 6 6 6 0 0 0 -2 2 0 3 3 1 6 6 6 65 52 28 203 203 202 204 204 203 -216 217 214 199 199 198 202 202 199 207 207 205 216 217 214 86 86 84 -4 4 4 0 0 0 8 8 8 127 127 125 203 204 199 206 207 201 -203 204 199 204 205 200 207 207 205 86 87 84 1 1 1 4 4 4 -0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 -0 0 0 0 0 0 0 0 0 0 0 0 10 10 9 0 0 0 -29 30 27 141 141 139 199 199 195 203 203 202 213 214 212 202 202 199 -201 202 197 211 212 207 210 211 205 206 207 201 210 211 205 209 210 204 -207 208 202 210 211 205 213 214 212 202 202 199 197 198 192 154 154 152 -29 30 27 10 10 9 0 0 0 0 0 0 6 6 6 1 2 4 -2 2 2 0 0 0 69 70 68 202 202 199 199 199 195 208 209 204 -204 205 200 206 207 202 213 214 212 175 176 174 20 16 18 0 0 0 -5 5 5 0 0 0 5 5 5 1 1 1 2 2 2 4 4 2 -3 3 1 2 2 0 82 82 81 209 210 205 207 208 203 206 207 202 -213 214 212 204 204 203 206 206 206 154 154 152 3 4 7 6 6 6 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 3 0 0 2 0 1 1 0 1 1 0 0 2 1 0 2 4 -0 2 1 0 2 1 7 1 0 3 0 0 8 8 8 9 1 0 -22 1 2 74 34 6 198 136 53 222 154 56 242 158 39 246 158 18 -233 156 5 233 156 5 244 159 4 244 159 4 246 147 4 233 156 5 -244 159 4 233 156 5 233 156 5 244 159 4 244 159 4 244 159 4 -244 159 4 244 159 4 244 159 4 231 145 5 242 158 39 231 175 56 -222 154 56 74 34 6 18 0 0 11 1 0 5 5 5 3 4 7 -0 0 0 6 5 0 20 16 18 13 14 7 10 1 0 17 6 0 -7 1 0 8 8 8 4 4 4 7 7 7 7 9 5 1 1 0 -17 6 0 30 1 2 143 100 31 221 134 40 242 158 39 242 171 21 -236 169 8 233 156 5 233 156 5 244 159 4 244 159 4 244 159 4 -233 156 5 244 159 4 249 164 6 249 164 6 244 159 4 233 156 5 -229 155 20 229 155 20 233 156 5 246 158 18 246 158 18 242 158 39 -198 136 53 143 100 31 48 4 0 17 1 0 4 0 2 2 3 8 -2 0 5 8 3 8 5 7 10 0 1 3 0 1 3 2 0 1 -4 0 0 4 0 0 0 0 5 0 0 5 0 0 2 1 1 1 -0 0 0 3 3 3 124 124 124 199 199 195 209 210 205 209 210 205 -204 205 200 205 206 201 208 208 206 208 208 206 208 208 206 208 208 206 -208 208 206 208 209 204 208 209 204 208 209 204 208 209 204 203 204 199 -209 209 208 211 211 209 213 214 212 208 208 207 86 86 84 0 0 0 -3 4 7 0 0 2 10 10 9 0 0 0 10 10 9 0 0 0 -10 10 9 86 87 84 170 171 167 201 202 197 209 210 205 205 206 201 -209 209 208 206 206 204 199 199 198 203 203 202 202 202 199 211 211 209 -207 207 205 199 199 195 132 133 128 29 30 27 2 2 2 3 3 3 -3 3 3 1 1 1 0 0 0 1 1 1 6 6 6 3 3 3 -0 0 0 0 0 0 4 4 4 4 4 4 5 5 5 0 0 0 -29 30 27 141 141 139 208 208 206 211 211 209 206 206 206 209 209 208 -206 206 204 204 204 203 209 209 208 209 209 208 204 204 203 206 206 204 -211 211 209 164 164 161 69 70 68 0 0 0 0 0 0 7 7 7 -8 8 8 0 0 2 3 3 3 0 0 0 7 7 7 127 127 125 -209 209 208 206 206 206 207 207 205 204 204 203 207 207 205 86 87 84 -6 6 6 0 0 0 1 1 1 5 5 5 9 9 9 0 0 0 -3 3 3 0 0 0 10 10 9 0 0 0 86 87 84 208 208 207 -203 203 202 211 211 209 211 211 209 206 206 204 208 208 206 193 193 192 -69 70 68 0 0 0 0 0 0 132 133 128 204 205 200 211 212 207 -209 210 205 208 209 204 202 202 199 86 87 84 5 5 5 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -0 0 2 0 0 2 0 0 0 0 0 0 0 0 0 5 5 5 -6 6 6 2 2 2 86 86 84 193 193 192 204 204 203 208 208 206 -201 202 197 209 210 205 206 207 202 202 202 199 210 211 206 211 212 207 -204 205 200 204 205 200 197 198 192 186 187 182 86 87 84 5 5 3 -0 0 0 2 2 2 4 4 4 20 16 18 1 1 3 6 6 6 -5 5 5 10 10 9 164 164 161 207 207 205 206 207 202 213 213 209 -206 207 202 211 212 207 208 208 206 82 82 81 0 0 0 2 2 2 -0 0 2 1 1 3 6 6 6 0 0 0 0 0 0 3 3 3 -5 5 3 2 2 0 7 7 7 154 154 152 208 208 206 203 203 202 -199 199 195 216 217 214 199 199 195 213 214 212 104 104 103 0 0 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 2 1 0 2 1 2 0 1 2 0 1 0 2 1 0 2 1 -0 1 3 1 1 1 9 4 5 5 0 0 3 0 0 4 1 3 -15 7 8 14 1 0 48 4 0 143 100 31 222 154 56 222 154 56 -220 161 40 229 155 20 242 158 39 246 158 18 246 158 18 250 166 22 -244 159 4 244 159 4 244 159 4 246 158 18 244 159 4 244 159 4 -249 164 6 249 164 6 244 159 4 246 158 18 246 158 18 229 143 21 -220 161 40 222 154 56 74 34 6 22 1 2 6 5 0 3 3 5 -7 5 3 7 5 3 0 0 0 1 0 0 15 7 8 4 0 0 -1 0 2 8 9 10 1 2 4 0 3 0 2 2 0 26 16 7 -26 1 0 143 69 23 222 154 56 242 171 21 246 158 18 244 159 4 -233 156 5 233 156 5 249 164 6 244 159 4 244 159 4 244 159 4 -246 158 18 246 158 18 249 164 6 249 164 6 246 158 18 229 155 20 -220 161 40 220 161 40 242 158 39 231 175 56 222 154 56 198 136 53 -107 69 8 26 1 0 11 1 0 20 16 18 8 3 8 8 3 14 -3 1 7 2 3 8 5 7 10 0 2 4 0 2 1 1 0 0 -4 0 0 3 0 2 0 0 5 0 0 5 0 0 2 0 0 0 -7 7 7 8 9 10 82 82 81 124 124 124 132 133 128 127 127 125 -126 126 124 126 126 124 126 126 124 126 126 124 126 126 124 126 126 124 -126 126 124 126 126 124 126 126 124 126 126 124 132 133 128 126 126 124 -127 127 125 126 126 124 124 124 124 126 126 126 69 70 68 5 5 5 -1 1 3 0 0 2 3 3 3 2 2 2 4 4 4 7 5 3 -0 0 0 4 4 2 3 3 1 69 70 68 132 133 128 175 176 174 -202 202 199 206 206 204 204 204 203 211 211 209 186 187 182 164 164 161 -119 119 117 29 30 27 1 1 0 4 4 2 0 0 0 9 9 9 -0 0 0 3 3 3 3 3 3 1 1 1 1 1 1 3 3 3 -4 4 4 0 0 0 0 0 0 2 2 2 2 2 2 0 0 0 -7 7 7 10 10 9 29 30 27 124 124 124 164 164 161 186 187 182 -204 204 203 211 211 209 209 209 208 193 193 192 164 164 161 127 127 125 -65 52 28 3 3 1 3 3 3 1 1 1 4 4 4 20 16 18 -0 0 2 8 9 10 3 3 3 0 0 0 7 7 7 82 82 81 -127 127 125 124 124 124 124 124 124 132 133 128 119 119 117 69 70 68 -7 7 7 2 2 0 0 0 0 0 0 0 1 1 1 0 0 0 -4 4 4 1 1 1 4 4 4 0 0 0 10 10 9 104 104 103 -119 119 117 127 127 125 127 127 125 119 119 117 124 124 124 124 124 124 -86 87 84 8 8 8 10 10 9 82 82 81 124 124 124 127 127 125 -126 126 124 124 124 124 119 119 117 65 52 28 2 2 2 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 2 0 0 2 0 0 2 0 0 2 -0 0 2 0 0 2 0 0 0 0 0 0 0 0 0 5 5 5 -0 0 0 20 16 18 1 1 1 0 0 0 82 82 81 126 126 126 -175 176 174 197 198 192 205 206 201 210 211 206 210 211 206 193 193 192 -164 164 161 141 141 139 69 70 68 7 5 3 3 3 1 2 2 2 -4 4 4 6 6 6 3 3 5 0 0 2 1 1 3 3 3 5 -0 0 0 29 30 27 132 133 128 124 124 124 132 133 128 124 124 124 -126 126 124 127 127 125 119 119 117 13 14 7 1 1 1 0 0 0 -1 1 3 8 9 10 3 3 5 1 2 4 3 3 3 9 9 9 -0 0 0 10 9 7 0 0 0 69 70 68 132 133 128 124 124 124 -127 127 125 124 124 124 132 133 128 124 124 124 119 119 117 20 16 18 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 3 2 0 3 4 1 5 4 1 5 2 0 1 1 1 0 -2 0 1 2 0 1 3 0 0 9 4 5 15 7 8 8 3 8 -2 0 5 6 5 0 14 1 0 26 1 0 74 34 6 107 69 8 -170 133 50 222 154 56 231 175 56 222 154 56 229 155 20 229 155 20 -246 158 18 244 159 4 246 158 18 246 158 18 246 158 18 244 159 4 -244 159 4 249 164 6 244 159 4 244 159 4 250 166 22 250 166 22 -246 158 18 222 154 56 170 133 50 30 1 2 11 1 0 5 3 3 -4 1 3 7 5 3 6 1 3 9 4 5 7 7 7 5 3 3 -15 7 8 4 1 3 2 5 5 4 4 2 9 3 3 26 1 0 -72 12 0 222 154 56 220 161 40 246 158 18 244 159 4 246 158 18 -246 158 18 244 159 4 249 164 6 244 159 4 244 159 4 246 158 18 -246 158 18 244 159 4 233 156 5 246 158 18 242 171 21 242 158 39 -222 154 56 231 175 56 222 154 56 143 100 31 74 34 6 33 6 2 -17 1 0 17 6 0 15 7 8 1 0 0 9 4 5 6 4 5 -1 0 5 0 2 6 0 2 6 0 2 6 1 1 1 1 0 0 -1 0 0 0 0 2 0 0 5 0 0 5 1 0 0 1 0 0 -8 8 8 1 1 3 8 9 10 1 1 1 1 1 0 0 0 0 -1 1 0 7 5 3 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 2 0 -0 0 0 2 2 0 0 0 0 10 10 9 0 0 2 0 0 2 -1 1 3 8 9 10 0 0 2 4 4 4 0 0 0 5 5 5 -20 16 18 0 0 0 1 1 0 7 5 3 3 3 1 0 0 0 -2 2 0 4 4 2 2 2 0 3 3 1 5 5 3 4 4 2 -0 0 0 1 1 0 0 0 0 0 0 0 5 5 5 1 1 1 -3 3 3 8 8 8 6 6 6 0 0 0 0 0 0 2 2 2 -3 4 7 3 3 5 8 9 10 1 2 4 0 0 0 7 7 7 -0 0 0 4 4 4 2 2 0 6 6 6 0 0 0 3 3 3 -4 4 4 0 0 0 0 0 0 8 8 8 10 9 7 0 0 0 -2 2 2 1 1 1 2 2 2 4 4 4 6 6 6 0 0 2 -0 0 2 7 7 7 3 3 5 1 2 4 0 0 0 9 9 9 -10 10 9 4 4 4 0 0 0 4 4 2 5 5 3 0 0 0 -0 0 0 5 5 3 5 5 3 0 0 0 0 0 0 4 4 4 -2 2 2 0 0 2 8 9 10 8 9 10 0 0 0 5 5 5 -0 0 0 5 5 3 0 0 0 0 0 0 6 6 6 0 0 0 -9 9 9 5 5 5 3 3 3 10 10 9 4 4 2 2 2 0 -0 0 0 0 0 0 10 10 9 0 0 0 0 0 0 8 8 8 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 -0 0 2 0 0 2 0 0 2 0 0 2 6 6 6 0 0 2 -3 3 5 1 2 4 7 7 7 8 8 8 0 0 0 7 7 7 -1 1 1 2 2 0 1 1 0 0 0 0 1 1 0 2 2 0 -1 1 0 0 0 0 1 1 1 7 7 7 0 0 0 10 10 9 -1 1 3 2 1 5 0 0 4 5 7 10 0 0 4 3 3 5 -0 0 0 6 6 6 1 1 0 2 2 0 0 1 0 7 5 3 -2 2 0 8 10 3 5 5 3 1 1 0 0 0 0 3 3 5 -3 1 7 1 0 5 0 0 2 3 3 5 4 4 4 10 10 9 -0 0 0 6 6 6 5 5 3 1 1 0 0 0 0 10 10 9 -0 0 0 1 1 1 0 0 0 4 4 4 7 7 7 0 0 2 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 0 3 2 0 3 4 1 5 4 1 5 2 0 1 2 1 0 -2 0 1 2 0 1 3 3 1 7 1 0 15 7 8 8 1 5 -5 7 10 4 8 7 3 3 1 17 6 0 17 1 0 26 1 0 -30 1 2 48 4 0 107 69 8 143 100 31 170 133 50 222 154 56 -222 154 56 220 161 40 242 158 39 242 158 39 242 158 39 246 158 18 -246 158 18 246 158 18 233 156 5 250 166 22 231 145 5 244 159 4 -246 158 18 242 158 39 222 154 56 107 69 8 22 1 2 10 1 0 -6 0 0 6 4 5 6 1 3 7 2 6 0 0 2 6 6 6 -6 1 3 9 3 6 0 0 0 2 1 0 14 1 0 35 1 0 -198 136 53 222 154 56 229 155 20 250 166 22 233 156 5 233 156 5 -246 158 18 246 158 18 246 158 18 246 158 18 229 155 20 242 158 39 -242 158 39 242 158 39 242 158 39 222 154 56 198 136 53 170 133 50 -143 69 23 74 34 6 35 1 0 22 1 2 17 6 0 9 1 0 -7 1 0 4 1 3 3 3 3 6 6 6 7 1 0 3 0 0 -5 5 5 5 7 10 2 3 8 3 4 7 2 1 0 1 0 0 -0 0 0 0 0 2 0 2 4 0 0 4 1 0 0 3 0 0 -1 0 2 8 9 10 7 7 7 0 0 0 7 7 7 2 2 0 -2 2 0 1 1 0 2 2 2 2 2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 0 2 2 0 3 3 1 4 4 2 -0 0 0 7 5 3 1 1 1 3 3 3 1 1 3 3 3 5 -1 2 4 1 2 4 8 9 10 0 0 2 0 0 0 6 6 6 -0 0 0 7 7 7 1 1 0 1 1 0 0 0 0 0 0 0 -3 3 1 5 5 3 2 2 0 0 0 0 5 5 3 0 0 0 -5 5 3 3 3 1 3 3 3 5 5 5 1 1 1 7 7 7 -1 1 1 0 0 0 0 0 0 0 0 0 6 6 6 4 4 4 -0 0 2 6 6 6 0 0 2 7 11 16 1 1 1 5 5 5 -0 0 0 0 0 0 5 5 3 2 2 0 5 5 5 0 0 0 -3 3 3 7 7 7 0 0 0 0 0 0 4 4 2 2 2 0 -1 1 1 1 1 1 7 7 7 1 1 1 0 0 2 6 6 6 -7 7 7 0 0 2 0 0 2 8 9 10 9 9 9 0 0 0 -0 0 0 6 6 6 1 1 0 4 4 2 0 0 0 3 3 1 -0 0 0 0 0 0 4 4 2 5 5 3 2 2 0 4 4 4 -4 4 4 3 4 7 0 0 2 1 2 4 10 10 9 0 0 0 -10 9 7 1 1 0 7 5 3 4 4 2 0 0 0 10 9 7 -1 1 1 0 0 0 5 5 5 0 0 0 2 2 0 2 2 0 -4 4 2 1 1 0 3 3 1 1 1 0 3 3 3 1 1 1 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 -0 0 2 0 0 2 0 0 2 0 0 2 0 0 2 1 2 4 -6 6 6 1 1 3 0 0 2 3 3 5 7 7 7 0 0 0 -1 1 1 0 0 0 3 3 1 4 4 2 0 0 0 0 0 0 -2 2 0 1 1 0 2 2 2 0 0 0 8 9 10 1 2 4 -3 3 5 3 4 7 5 7 10 0 0 2 3 4 7 6 6 6 -2 2 2 1 1 1 0 0 0 1 1 0 6 6 6 3 3 1 -4 4 2 1 1 0 0 0 0 0 0 0 9 9 9 0 0 2 -6 6 6 1 2 4 1 1 3 3 4 7 0 0 0 3 3 3 -6 6 6 1 1 1 2 2 0 1 1 0 1 1 0 0 0 0 -8 8 8 0 0 0 10 10 9 0 0 0 1 1 3 8 8 8 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 0 2 1 0 2 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 0 0 3 0 0 1 0 2 -0 0 2 0 1 0 0 0 0 3 0 0 8 0 0 11 1 0 -14 1 0 14 1 0 14 1 0 18 0 0 25 6 3 33 6 2 -74 34 6 143 100 31 170 133 50 222 154 56 222 154 56 220 161 40 -242 158 39 246 158 18 246 158 18 249 164 6 233 156 5 249 164 6 -250 166 22 229 155 20 242 158 39 222 154 56 48 4 0 14 1 0 -5 1 0 1 1 0 15 7 8 8 3 8 5 7 10 5 7 10 -6 1 3 3 0 0 8 10 3 10 7 0 18 0 0 107 69 8 -231 175 56 242 158 39 229 155 20 250 166 22 233 156 5 242 169 5 -246 158 18 246 158 18 246 158 18 229 155 20 231 175 56 222 154 56 -198 136 53 170 133 50 143 69 23 74 34 6 33 6 2 26 1 0 -17 1 0 11 1 0 8 0 0 5 1 0 3 1 0 3 1 0 -4 0 0 2 0 1 0 0 0 0 0 0 1 0 0 1 0 0 -0 0 0 0 0 2 0 0 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 2 0 0 2 0 0 0 1 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 0 0 4 1 3 4 1 3 -2 2 0 2 2 0 1 1 0 3 0 2 9 4 5 17 6 0 -14 1 0 33 6 2 33 6 2 48 4 0 107 69 8 170 133 50 -198 136 53 231 175 56 229 155 20 246 158 18 249 164 6 249 164 6 -244 159 4 250 166 22 250 166 22 231 175 56 143 100 31 33 6 2 -11 1 0 10 9 7 4 0 0 9 9 9 3 0 4 3 0 4 -6 1 3 7 5 3 4 0 0 25 6 3 48 4 0 222 154 56 -242 158 39 250 166 22 246 158 18 242 171 21 233 156 5 244 159 4 -246 147 4 242 158 39 222 154 56 198 136 53 107 69 8 74 34 6 -48 4 0 35 1 0 30 1 2 22 1 2 14 1 0 5 0 0 -2 0 1 1 1 1 0 2 0 0 2 0 1 1 0 1 0 0 -4 1 3 4 1 3 1 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 3 0 4 1 1 3 -1 1 0 0 2 0 0 2 2 0 2 4 0 2 6 1 1 3 -7 1 0 7 0 0 25 6 3 18 0 0 26 1 0 26 1 0 -74 34 6 198 136 53 231 175 56 229 155 20 249 164 6 242 169 5 -233 156 5 242 171 21 233 156 5 225 170 23 222 154 56 74 34 6 -22 1 2 11 1 0 8 0 0 6 1 3 15 7 8 8 1 5 -6 1 3 11 1 0 17 6 0 25 6 3 143 100 31 231 175 56 -242 171 21 246 158 18 249 178 22 231 145 5 250 166 22 246 158 18 -250 166 22 222 154 56 143 100 31 48 4 0 26 1 0 14 1 0 -11 1 0 11 1 0 10 1 0 6 0 0 3 0 0 3 3 1 -2 1 0 2 1 0 2 2 0 2 1 0 3 0 0 3 0 2 -4 1 5 4 1 5 1 0 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 2 2 1 5 1 1 3 -0 0 0 0 2 0 3 3 1 1 3 4 0 2 6 0 0 4 -8 8 8 3 0 2 7 1 0 10 1 0 25 6 3 17 1 0 -17 1 0 74 34 6 222 154 56 244 176 40 233 156 5 249 176 7 -242 169 5 242 169 5 233 156 5 242 171 21 220 161 40 198 136 53 -48 4 0 22 1 2 11 1 0 6 1 3 8 1 5 8 1 5 -6 1 3 11 1 0 17 1 0 74 34 6 222 154 56 229 155 20 -249 178 22 244 159 4 231 145 5 249 178 22 246 147 4 250 166 22 -231 175 56 198 136 53 33 6 2 14 1 0 2 2 0 0 2 6 -2 3 8 2 3 8 1 0 6 0 0 5 3 3 5 7 7 7 -2 1 0 2 1 0 2 2 0 1 0 0 3 0 0 1 0 2 -2 0 5 2 0 5 0 0 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 2 2 0 5 1 0 2 -1 0 0 1 0 0 2 2 0 2 2 0 2 2 0 2 1 0 -3 0 0 9 4 5 15 7 8 5 0 0 7 0 0 10 7 0 -10 7 0 25 6 3 143 100 31 231 175 56 225 170 23 242 169 5 -249 176 7 244 159 4 244 159 4 249 164 6 242 171 21 231 175 56 -107 69 8 30 1 2 26 16 7 0 0 2 5 7 10 3 4 7 -9 4 5 17 6 0 33 6 2 198 136 53 231 175 56 250 166 22 -250 166 22 244 159 4 242 169 5 242 169 5 244 159 4 244 176 40 -198 136 53 107 69 8 25 6 3 7 5 3 2 5 5 2 5 5 -0 2 2 0 2 6 2 3 8 3 4 7 4 1 5 4 0 1 -3 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 -0 2 4 0 2 4 0 1 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 2 1 0 5 1 0 5 -1 1 0 2 1 0 2 1 0 3 1 0 4 0 0 5 1 0 -15 7 8 4 0 0 9 4 5 9 3 6 3 0 0 3 0 0 -5 1 0 25 6 3 74 34 6 222 154 56 231 175 56 233 156 5 -249 164 6 244 159 4 249 164 6 244 159 4 242 169 5 229 155 20 -222 154 56 74 34 6 17 6 0 2 2 0 8 9 10 4 4 2 -10 7 0 18 0 0 143 100 31 231 175 56 242 158 39 250 166 22 -249 164 6 244 159 4 242 169 5 236 169 8 229 155 20 220 161 40 -143 100 31 26 1 0 17 6 0 0 1 0 0 2 1 1 7 3 -4 8 7 7 7 7 3 3 5 1 0 2 4 1 3 8 3 8 -3 0 2 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 -0 2 1 0 2 1 0 1 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 2 0 2 6 0 2 6 -1 2 4 0 2 2 1 1 1 2 0 1 4 1 3 4 1 3 -8 3 8 4 1 3 7 2 6 4 1 3 5 0 0 9 3 3 -5 0 0 8 0 0 22 1 2 107 69 8 231 175 56 225 170 23 -250 166 22 250 166 22 249 176 7 249 164 6 242 171 21 242 171 21 -231 175 56 170 133 50 25 6 3 26 16 7 2 2 0 7 1 0 -14 1 0 74 34 6 222 154 56 229 155 20 250 166 22 233 156 5 -249 164 6 242 169 5 236 169 8 249 178 22 225 170 23 231 175 56 -48 4 0 17 1 0 14 1 0 4 1 5 9 9 9 4 4 2 -1 0 0 1 0 0 2 2 0 7 5 3 9 4 5 8 3 8 -1 0 2 1 0 5 1 0 5 1 0 5 0 0 2 0 0 2 -1 1 3 1 1 3 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 1 0 0 1 3 0 2 4 -0 2 1 0 2 1 0 2 1 1 1 1 2 0 3 2 0 3 -4 1 5 8 3 8 3 0 4 4 1 3 10 9 7 7 1 0 -5 1 0 9 1 0 25 6 3 26 1 0 198 136 53 231 175 56 -242 171 21 242 171 21 242 169 5 242 169 5 242 171 21 242 171 21 -242 171 21 231 175 56 107 69 8 26 1 0 26 16 7 22 1 2 -33 6 2 170 133 50 231 175 56 242 171 21 242 169 5 249 176 7 -244 159 4 249 176 7 242 171 21 225 170 23 231 175 56 107 69 8 -26 1 0 14 1 0 6 1 3 2 0 5 4 1 3 4 1 3 -3 0 2 3 3 1 2 2 0 1 0 0 1 0 0 1 1 1 -0 0 2 0 0 4 0 0 5 1 0 5 1 0 5 1 0 5 -2 0 3 2 0 3 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 -0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 -0 0 2 0 0 2 0 0 2 1 1 1 1 1 0 1 2 0 -2 1 0 2 2 0 6 5 0 17 6 0 74 34 6 231 175 56 -244 176 40 242 171 21 249 178 22 242 171 21 242 171 21 236 169 8 -250 166 22 244 176 40 222 154 56 107 69 8 72 12 0 74 34 6 -143 100 31 231 175 56 242 171 21 236 169 8 249 176 7 242 169 5 -242 169 5 249 176 7 236 169 8 231 175 56 170 133 50 33 6 2 -25 6 3 15 7 8 4 1 5 2 3 13 3 1 7 3 1 7 -1 0 5 1 1 3 0 2 1 0 2 0 0 3 0 0 2 1 -0 1 2 0 2 4 0 0 5 1 0 6 2 0 5 4 1 5 -4 1 3 4 1 3 1 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 3 0 0 -1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 -0 0 2 0 0 2 0 0 2 1 1 1 1 1 0 1 2 0 -2 1 0 2 1 0 7 5 3 11 1 0 33 6 2 143 100 31 -220 161 40 244 176 40 242 171 21 236 169 8 236 169 8 249 176 7 -250 166 22 250 166 22 244 176 40 231 175 56 222 154 56 222 154 56 -244 176 40 242 171 21 242 171 21 249 178 22 242 169 5 242 169 5 -242 169 5 242 171 21 225 170 23 231 175 56 74 34 6 26 1 0 -17 1 0 5 0 0 1 0 6 2 3 13 1 0 6 1 0 6 -1 0 6 0 1 3 0 2 1 0 3 0 0 3 0 0 2 1 -0 2 2 0 1 2 0 2 4 0 0 4 0 0 2 1 0 2 -1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 0 0 4 0 0 6 1 3 -3 0 4 3 0 4 3 0 2 1 0 0 0 0 0 0 1 0 -0 0 2 0 0 4 0 0 4 2 0 3 2 0 1 2 0 1 -4 1 3 4 1 3 4 0 1 20 16 18 18 0 0 30 1 2 -231 175 56 220 161 40 244 176 40 242 171 21 242 169 5 242 169 5 -249 164 6 244 159 4 242 171 21 242 171 21 242 171 21 242 171 21 -242 171 21 244 159 4 249 176 7 249 176 7 244 159 4 242 171 21 -242 171 21 225 170 23 231 175 56 143 100 31 26 1 0 14 1 0 -7 0 0 5 1 0 5 7 10 0 2 6 0 0 2 1 0 2 -1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 2 1 -0 1 2 0 1 2 0 1 2 0 1 0 0 3 0 0 3 0 -0 3 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 1 0 0 4 0 2 3 0 4 -4 1 5 2 0 5 3 0 2 1 0 0 0 0 0 0 0 0 -0 0 2 1 0 5 2 0 5 2 0 5 4 1 3 4 1 3 -4 1 5 3 1 7 7 11 16 8 1 5 14 1 4 26 1 0 -107 69 8 231 175 56 244 176 40 242 171 21 249 176 7 249 176 7 -249 176 7 249 178 22 249 176 7 242 169 5 249 176 7 249 176 7 -249 164 6 249 176 7 242 169 5 242 169 5 249 176 7 249 178 22 -242 171 21 231 175 56 198 136 53 33 6 2 25 6 3 9 1 0 -4 0 0 6 6 6 8 9 10 0 2 2 0 0 2 1 0 0 -1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 1 0 0 2 1 0 2 1 0 3 0 0 3 0 0 3 0 -0 3 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 -1 0 5 1 0 5 1 1 1 1 1 0 0 2 0 0 2 0 -0 2 1 0 1 3 1 0 5 1 0 5 2 0 3 2 0 5 -3 1 7 2 3 13 8 3 14 2 3 13 8 3 8 22 1 2 -26 1 0 170 133 50 231 175 56 242 171 21 242 169 5 249 176 7 -249 176 7 249 176 7 242 169 5 249 176 7 249 176 7 242 169 5 -249 178 22 249 178 22 244 159 4 249 178 22 249 178 22 246 158 18 -244 176 40 231 175 56 74 34 6 14 1 0 4 0 0 3 1 7 -8 3 14 2 3 13 5 7 10 1 3 4 0 0 5 0 0 5 -1 0 6 0 0 5 1 0 5 1 0 5 1 0 2 1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 -0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 0 -0 1 3 0 0 5 1 1 1 1 1 0 1 2 0 1 2 0 -1 1 1 1 1 3 1 1 3 1 1 3 1 1 1 1 1 3 -1 0 6 2 3 8 8 3 14 3 1 7 8 3 8 14 1 4 -17 1 0 48 4 0 222 154 56 231 175 56 242 171 21 236 169 8 -242 169 5 249 176 7 242 169 5 249 176 7 242 169 5 249 176 7 -236 169 8 242 169 5 242 169 5 249 178 22 242 171 21 244 176 40 -231 175 56 143 100 31 17 6 0 10 7 0 0 0 0 2 3 13 -2 3 13 2 3 13 1 0 5 3 3 3 0 0 4 0 0 5 -0 0 5 0 0 5 1 0 6 1 0 5 1 0 5 1 0 2 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 1 -1 0 5 1 0 6 2 0 3 2 0 1 2 1 0 2 1 0 -2 0 1 2 0 1 1 1 1 1 2 0 0 3 0 0 3 0 -0 2 1 0 2 1 0 3 0 20 16 18 1 0 5 3 1 7 -7 5 3 14 1 0 74 34 6 198 136 53 220 161 40 242 171 21 -242 171 21 249 178 22 249 178 22 249 178 22 236 169 8 249 176 7 -249 176 7 249 178 22 249 178 22 242 171 21 244 176 40 231 175 56 -143 100 31 25 6 3 10 7 0 6 5 0 10 10 9 5 7 10 -2 3 13 8 3 14 9 3 6 4 0 0 2 1 0 1 1 0 -1 1 1 1 1 3 1 0 5 1 0 5 0 0 4 0 0 2 -1 1 3 1 1 1 1 1 1 1 1 1 1 1 3 1 1 3 -1 0 5 1 1 3 0 0 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 2 1 -1 0 5 1 0 5 2 0 3 2 0 1 4 0 0 2 1 0 -4 0 1 2 0 1 1 1 0 1 2 0 0 3 0 0 3 0 -0 2 0 0 2 0 0 6 1 2 6 0 8 9 10 1 0 6 -5 7 10 7 1 0 22 1 2 48 4 0 170 133 50 231 175 56 -231 175 56 244 176 40 225 170 23 244 176 40 242 171 21 242 171 21 -242 171 21 242 171 21 225 170 23 231 175 56 231 175 56 143 100 31 -33 6 2 14 1 0 3 1 0 8 10 3 0 2 0 3 3 3 -20 16 18 3 1 7 15 7 8 6 0 0 4 0 0 2 1 0 -1 1 0 1 1 1 1 1 3 1 1 3 0 0 5 0 1 3 -0 0 2 0 0 2 0 1 0 0 1 0 0 0 2 0 0 4 -0 0 4 0 0 4 0 0 2 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 2 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 -0 1 0 0 1 0 0 1 0 0 1 0 0 0 4 1 0 6 -1 0 6 4 1 5 8 0 0 17 1 0 33 6 2 107 69 8 -198 136 53 231 175 56 231 175 56 231 175 56 244 176 40 244 176 40 -231 175 56 231 175 56 222 154 56 170 133 50 74 34 6 26 1 0 -14 1 0 9 4 5 0 2 0 0 3 0 0 3 0 0 3 0 -1 1 1 4 1 3 4 1 5 3 0 4 1 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 -0 0 2 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 2 0 1 1 0 0 0 0 2 0 0 4 -1 0 6 2 0 5 4 1 3 8 0 0 14 1 0 17 6 0 -33 6 2 74 34 6 107 69 8 143 100 31 143 100 31 143 100 31 -143 100 31 107 69 8 74 34 6 33 6 2 18 0 0 17 1 0 -15 7 8 3 1 7 0 1 3 0 3 0 0 3 0 0 3 0 -1 1 0 2 0 1 4 1 5 2 0 5 1 0 2 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 1 0 0 3 0 0 3 0 0 1 0 0 1 0 0 -0 0 2 0 0 2 1 1 3 1 1 1 10 9 7 10 7 0 -7 1 0 8 0 0 14 1 0 17 6 0 25 6 3 25 6 3 -17 6 0 11 1 0 9 1 0 7 0 0 5 0 0 6 1 3 -6 1 3 6 1 3 2 1 0 1 2 0 1 2 0 1 2 0 -1 1 0 0 2 1 1 0 5 1 0 5 0 0 2 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 3 0 0 3 0 0 1 0 0 1 0 0 -1 0 0 0 0 0 0 0 0 0 2 1 0 1 0 0 1 0 -5 5 5 7 7 7 4 1 3 1 0 0 3 0 0 4 4 4 -0 2 4 4 8 7 5 7 10 2 5 5 3 4 7 2 2 2 -3 0 2 9 4 5 4 0 0 4 0 0 4 0 0 2 0 1 -1 1 1 0 2 1 0 1 3 0 1 3 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 1 3 1 1 3 1 1 3 2 0 1 -2 0 1 4 0 0 5 1 0 5 1 0 10 9 7 7 5 3 -4 0 0 4 0 0 3 3 1 7 5 3 5 3 3 3 3 3 -4 8 7 4 8 7 0 3 0 0 3 0 6 5 0 6 5 0 -1 0 0 3 0 0 5 0 0 4 1 3 4 1 5 4 1 5 -2 0 3 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 1 3 0 1 3 1 1 3 1 1 1 -2 0 1 4 0 1 5 0 0 6 0 0 6 1 3 7 1 0 -9 3 3 5 1 0 1 0 0 1 0 0 2 0 1 1 1 3 -0 2 4 4 8 7 1 7 3 3 3 1 3 3 1 1 2 0 -2 2 0 10 9 7 3 0 2 3 0 4 4 1 5 4 1 5 -4 1 3 2 1 0 2 1 0 2 1 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 -1 0 2 1 0 5 3 0 4 4 1 5 8 3 8 7 2 6 -4 1 5 7 2 6 6 4 5 7 7 7 3 3 5 1 0 2 -8 3 8 8 3 8 7 2 6 4 1 3 7 2 6 6 1 3 -2 0 1 3 0 2 1 0 0 1 0 0 1 0 0 4 0 0 -4 0 0 5 0 0 5 0 0 3 1 0 1 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 -0 0 2 2 0 3 2 0 5 2 0 5 8 3 8 3 4 7 -3 1 7 3 1 7 1 1 3 0 0 2 3 3 5 7 7 7 -8 3 8 8 3 8 8 3 8 7 2 6 4 1 5 4 1 5 -4 1 5 4 4 4 0 0 0 0 0 0 1 0 0 1 0 0 -4 0 0 4 0 0 5 0 0 4 0 0 1 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 3 0 2 3 0 2 2 2 0 1 1 0 -1 1 0 0 2 0 0 2 0 0 3 0 0 3 0 0 3 0 -0 3 0 0 3 0 0 2 1 0 2 1 0 2 1 0 1 3 -1 0 5 4 1 5 2 0 5 2 0 5 0 0 4 0 0 4 -0 0 2 0 2 1 0 2 1 0 2 1 0 0 0 0 0 2 -2 0 5 2 0 5 3 1 7 3 1 7 0 0 2 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 4 1 3 4 1 3 2 2 0 1 1 0 -1 2 0 0 2 0 0 3 0 0 3 0 0 6 1 0 3 0 -0 3 0 0 3 0 0 3 0 0 3 0 0 2 1 0 2 1 -0 0 4 1 0 5 1 0 6 1 0 6 0 0 4 0 0 2 -0 0 2 0 2 1 0 2 0 0 2 0 0 0 2 0 0 4 -1 0 6 2 3 13 2 3 13 2 3 13 0 0 4 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/sysdrv/tools/board/kernel/logo_linux_clut224.ppm b/sysdrv/tools/board/kernel/logo_linux_clut224.ppm deleted file mode 100644 index 3c14e43b8..000000000 --- a/sysdrv/tools/board/kernel/logo_linux_clut224.ppm +++ /dev/null @@ -1,1604 +0,0 @@ -P3 -# Standard 224-color Linux logo -80 80 -255 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 6 6 6 10 10 10 10 10 10 - 10 10 10 6 6 6 6 6 6 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 10 10 10 14 14 14 - 22 22 22 26 26 26 30 30 30 34 34 34 - 30 30 30 30 30 30 26 26 26 18 18 18 - 14 14 14 10 10 10 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 26 26 26 42 42 42 - 54 54 54 66 66 66 78 78 78 78 78 78 - 78 78 78 74 74 74 66 66 66 54 54 54 - 42 42 42 26 26 26 18 18 18 10 10 10 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 22 22 22 42 42 42 66 66 66 86 86 86 - 66 66 66 38 38 38 38 38 38 22 22 22 - 26 26 26 34 34 34 54 54 54 66 66 66 - 86 86 86 70 70 70 46 46 46 26 26 26 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 10 10 10 26 26 26 - 50 50 50 82 82 82 58 58 58 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 6 6 6 54 54 54 86 86 86 66 66 66 - 38 38 38 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 22 22 22 50 50 50 - 78 78 78 34 34 34 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 6 6 6 70 70 70 - 78 78 78 46 46 46 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 18 18 18 42 42 42 82 82 82 - 26 26 26 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 14 14 14 - 46 46 46 34 34 34 6 6 6 2 2 6 - 42 42 42 78 78 78 42 42 42 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 10 10 10 30 30 30 66 66 66 58 58 58 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 26 26 26 - 86 86 86 101 101 101 46 46 46 10 10 10 - 2 2 6 58 58 58 70 70 70 34 34 34 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 14 14 14 42 42 42 86 86 86 10 10 10 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 30 30 30 - 94 94 94 94 94 94 58 58 58 26 26 26 - 2 2 6 6 6 6 78 78 78 54 54 54 - 22 22 22 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 22 22 22 62 62 62 62 62 62 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 26 26 26 - 54 54 54 38 38 38 18 18 18 10 10 10 - 2 2 6 2 2 6 34 34 34 82 82 82 - 38 38 38 14 14 14 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 30 30 30 78 78 78 30 30 30 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 10 10 10 - 10 10 10 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 78 78 78 - 50 50 50 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 86 86 86 14 14 14 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 54 54 54 - 66 66 66 26 26 26 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 82 82 82 2 2 6 2 2 6 - 2 2 6 6 6 6 10 10 10 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 6 6 6 - 14 14 14 10 10 10 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 18 18 18 - 82 82 82 34 34 34 10 10 10 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 2 2 6 - 6 6 6 6 6 6 22 22 22 34 34 34 - 6 6 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 18 18 18 34 34 34 - 10 10 10 50 50 50 22 22 22 2 2 6 - 2 2 6 2 2 6 2 2 6 10 10 10 - 86 86 86 42 42 42 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 2 2 6 - 38 38 38 116 116 116 94 94 94 22 22 22 - 22 22 22 2 2 6 2 2 6 2 2 6 - 14 14 14 86 86 86 138 138 138 162 162 162 -154 154 154 38 38 38 26 26 26 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 86 86 86 46 46 46 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 14 14 14 -134 134 134 198 198 198 195 195 195 116 116 116 - 10 10 10 2 2 6 2 2 6 6 6 6 -101 98 89 187 187 187 210 210 210 218 218 218 -214 214 214 134 134 134 14 14 14 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 86 86 86 50 50 50 18 18 18 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 54 54 54 -218 218 218 195 195 195 226 226 226 246 246 246 - 58 58 58 2 2 6 2 2 6 30 30 30 -210 210 210 253 253 253 174 174 174 123 123 123 -221 221 221 234 234 234 74 74 74 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 70 70 70 58 58 58 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 82 82 82 2 2 6 106 106 106 -170 170 170 26 26 26 86 86 86 226 226 226 -123 123 123 10 10 10 14 14 14 46 46 46 -231 231 231 190 190 190 6 6 6 70 70 70 - 90 90 90 238 238 238 158 158 158 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 70 70 70 58 58 58 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 86 86 86 6 6 6 116 116 116 -106 106 106 6 6 6 70 70 70 149 149 149 -128 128 128 18 18 18 38 38 38 54 54 54 -221 221 221 106 106 106 2 2 6 14 14 14 - 46 46 46 190 190 190 198 198 198 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 74 74 74 62 62 62 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 0 - 0 0 1 0 0 0 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 94 94 94 14 14 14 101 101 101 -128 128 128 2 2 6 18 18 18 116 116 116 -118 98 46 121 92 8 121 92 8 98 78 10 -162 162 162 106 106 106 2 2 6 2 2 6 - 2 2 6 195 195 195 195 195 195 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 74 74 74 62 62 62 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 1 - 0 0 1 0 0 0 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 90 90 90 14 14 14 58 58 58 -210 210 210 26 26 26 54 38 6 154 114 10 -226 170 11 236 186 11 225 175 15 184 144 12 -215 174 15 175 146 61 37 26 9 2 2 6 - 70 70 70 246 246 246 138 138 138 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 70 70 70 66 66 66 26 26 26 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 86 86 86 14 14 14 10 10 10 -195 195 195 188 164 115 192 133 9 225 175 15 -239 182 13 234 190 10 232 195 16 232 200 30 -245 207 45 241 208 19 232 195 16 184 144 12 -218 194 134 211 206 186 42 42 42 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 50 50 50 74 74 74 30 30 30 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 34 34 34 86 86 86 14 14 14 2 2 6 -121 87 25 192 133 9 219 162 10 239 182 13 -236 186 11 232 195 16 241 208 19 244 214 54 -246 218 60 246 218 38 246 215 20 241 208 19 -241 208 19 226 184 13 121 87 25 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 50 50 50 82 82 82 34 34 34 10 10 10 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 34 34 34 82 82 82 30 30 30 61 42 6 -180 123 7 206 145 10 230 174 11 239 182 13 -234 190 10 238 202 15 241 208 19 246 218 74 -246 218 38 246 215 20 246 215 20 246 215 20 -226 184 13 215 174 15 184 144 12 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 26 26 26 94 94 94 42 42 42 14 14 14 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 50 50 50 104 69 6 -192 133 9 216 158 10 236 178 12 236 186 11 -232 195 16 241 208 19 244 214 54 245 215 43 -246 215 20 246 215 20 241 208 19 198 155 10 -200 144 11 216 158 10 156 118 10 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 6 6 6 90 90 90 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 46 46 46 22 22 22 -137 92 6 210 162 10 239 182 13 238 190 10 -238 202 15 241 208 19 246 215 20 246 215 20 -241 208 19 203 166 17 185 133 11 210 150 10 -216 158 10 210 150 10 102 78 10 2 2 6 - 6 6 6 54 54 54 14 14 14 2 2 6 - 2 2 6 62 62 62 74 74 74 30 30 30 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 34 34 34 78 78 78 50 50 50 6 6 6 - 94 70 30 139 102 15 190 146 13 226 184 13 -232 200 30 232 195 16 215 174 15 190 146 13 -168 122 10 192 133 9 210 150 10 213 154 11 -202 150 34 182 157 106 101 98 89 2 2 6 - 2 2 6 78 78 78 116 116 116 58 58 58 - 2 2 6 22 22 22 90 90 90 46 46 46 - 18 18 18 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 86 86 86 50 50 50 6 6 6 -128 128 128 174 154 114 156 107 11 168 122 10 -198 155 10 184 144 12 197 138 11 200 144 11 -206 145 10 206 145 10 197 138 11 188 164 115 -195 195 195 198 198 198 174 174 174 14 14 14 - 2 2 6 22 22 22 116 116 116 116 116 116 - 22 22 22 2 2 6 74 74 74 70 70 70 - 30 30 30 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 101 101 101 26 26 26 10 10 10 -138 138 138 190 190 190 174 154 114 156 107 11 -197 138 11 200 144 11 197 138 11 192 133 9 -180 123 7 190 142 34 190 178 144 187 187 187 -202 202 202 221 221 221 214 214 214 66 66 66 - 2 2 6 2 2 6 50 50 50 62 62 62 - 6 6 6 2 2 6 10 10 10 90 90 90 - 50 50 50 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 10 10 10 34 34 34 - 74 74 74 74 74 74 2 2 6 6 6 6 -144 144 144 198 198 198 190 190 190 178 166 146 -154 121 60 156 107 11 156 107 11 168 124 44 -174 154 114 187 187 187 190 190 190 210 210 210 -246 246 246 253 253 253 253 253 253 182 182 182 - 6 6 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 62 62 62 - 74 74 74 34 34 34 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 10 10 10 22 22 22 54 54 54 - 94 94 94 18 18 18 2 2 6 46 46 46 -234 234 234 221 221 221 190 190 190 190 190 190 -190 190 190 187 187 187 187 187 187 190 190 190 -190 190 190 195 195 195 214 214 214 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 - 82 82 82 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 14 14 14 - 86 86 86 54 54 54 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 18 18 18 46 46 46 90 90 90 - 46 46 46 18 18 18 6 6 6 182 182 182 -253 253 253 246 246 246 206 206 206 190 190 190 -190 190 190 190 190 190 190 190 190 190 190 190 -206 206 206 231 231 231 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -202 202 202 14 14 14 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 42 42 42 86 86 86 42 42 42 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 14 14 14 38 38 38 74 74 74 66 66 66 - 2 2 6 6 6 6 90 90 90 250 250 250 -253 253 253 253 253 253 238 238 238 198 198 198 -190 190 190 190 190 190 195 195 195 221 221 221 -246 246 246 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 82 82 82 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 78 78 78 70 70 70 34 34 34 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 34 34 34 66 66 66 78 78 78 6 6 6 - 2 2 6 18 18 18 218 218 218 253 253 253 -253 253 253 253 253 253 253 253 253 246 246 246 -226 226 226 231 231 231 246 246 246 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 178 178 178 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 18 18 18 90 90 90 62 62 62 - 30 30 30 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 10 10 10 26 26 26 - 58 58 58 90 90 90 18 18 18 2 2 6 - 2 2 6 110 110 110 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 231 231 231 18 18 18 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 18 18 18 94 94 94 - 54 54 54 26 26 26 10 10 10 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 22 22 22 50 50 50 - 90 90 90 26 26 26 2 2 6 2 2 6 - 14 14 14 195 195 195 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 242 242 242 54 54 54 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 38 38 38 - 86 86 86 50 50 50 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 38 38 38 82 82 82 - 34 34 34 2 2 6 2 2 6 2 2 6 - 42 42 42 195 195 195 246 246 246 253 253 253 -253 253 253 253 253 253 253 253 253 250 250 250 -242 242 242 242 242 242 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 250 250 250 246 246 246 238 238 238 -226 226 226 231 231 231 101 101 101 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 38 38 38 82 82 82 42 42 42 14 14 14 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 10 10 10 26 26 26 62 62 62 66 66 66 - 2 2 6 2 2 6 2 2 6 6 6 6 - 70 70 70 170 170 170 206 206 206 234 234 234 -246 246 246 250 250 250 250 250 250 238 238 238 -226 226 226 231 231 231 238 238 238 250 250 250 -250 250 250 250 250 250 246 246 246 231 231 231 -214 214 214 206 206 206 202 202 202 202 202 202 -198 198 198 202 202 202 182 182 182 18 18 18 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 62 62 62 66 66 66 30 30 30 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 14 14 14 42 42 42 82 82 82 18 18 18 - 2 2 6 2 2 6 2 2 6 10 10 10 - 94 94 94 182 182 182 218 218 218 242 242 242 -250 250 250 253 253 253 253 253 253 250 250 250 -234 234 234 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 246 246 246 -238 238 238 226 226 226 210 210 210 202 202 202 -195 195 195 195 195 195 210 210 210 158 158 158 - 6 6 6 14 14 14 50 50 50 14 14 14 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 86 86 86 46 46 46 - 18 18 18 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 22 22 22 54 54 54 70 70 70 2 2 6 - 2 2 6 10 10 10 2 2 6 22 22 22 -166 166 166 231 231 231 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 250 250 250 -242 242 242 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 246 246 246 -231 231 231 206 206 206 198 198 198 226 226 226 - 94 94 94 2 2 6 6 6 6 38 38 38 - 30 30 30 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 62 62 62 66 66 66 - 26 26 26 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 74 74 74 50 50 50 2 2 6 - 26 26 26 26 26 26 2 2 6 106 106 106 -238 238 238 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 246 246 246 218 218 218 202 202 202 -210 210 210 14 14 14 2 2 6 2 2 6 - 30 30 30 22 22 22 2 2 6 2 2 6 - 2 2 6 2 2 6 18 18 18 86 86 86 - 42 42 42 14 14 14 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 90 90 90 22 22 22 2 2 6 - 42 42 42 2 2 6 18 18 18 218 218 218 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 250 250 250 221 221 221 -218 218 218 101 101 101 2 2 6 14 14 14 - 18 18 18 38 38 38 10 10 10 2 2 6 - 2 2 6 2 2 6 2 2 6 78 78 78 - 58 58 58 22 22 22 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 54 54 54 82 82 82 2 2 6 26 26 26 - 22 22 22 2 2 6 123 123 123 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 250 250 250 -238 238 238 198 198 198 6 6 6 38 38 38 - 58 58 58 26 26 26 38 38 38 2 2 6 - 2 2 6 2 2 6 2 2 6 46 46 46 - 78 78 78 30 30 30 10 10 10 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 10 10 10 30 30 30 - 74 74 74 58 58 58 2 2 6 42 42 42 - 2 2 6 22 22 22 231 231 231 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 250 250 250 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 246 246 246 46 46 46 38 38 38 - 42 42 42 14 14 14 38 38 38 14 14 14 - 2 2 6 2 2 6 2 2 6 6 6 6 - 86 86 86 46 46 46 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 14 14 14 42 42 42 - 90 90 90 18 18 18 18 18 18 26 26 26 - 2 2 6 116 116 116 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 250 250 250 238 238 238 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 94 94 94 6 6 6 - 2 2 6 2 2 6 10 10 10 34 34 34 - 2 2 6 2 2 6 2 2 6 2 2 6 - 74 74 74 58 58 58 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 10 10 10 26 26 26 66 66 66 - 82 82 82 2 2 6 38 38 38 6 6 6 - 14 14 14 210 210 210 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 246 246 246 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 144 144 144 2 2 6 - 2 2 6 2 2 6 2 2 6 46 46 46 - 2 2 6 2 2 6 2 2 6 2 2 6 - 42 42 42 74 74 74 30 30 30 10 10 10 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 42 42 42 90 90 90 - 26 26 26 6 6 6 42 42 42 2 2 6 - 74 74 74 250 250 250 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 242 242 242 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 182 182 182 2 2 6 - 2 2 6 2 2 6 2 2 6 46 46 46 - 2 2 6 2 2 6 2 2 6 2 2 6 - 10 10 10 86 86 86 38 38 38 10 10 10 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 10 10 10 26 26 26 66 66 66 82 82 82 - 2 2 6 22 22 22 18 18 18 2 2 6 -149 149 149 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 206 206 206 2 2 6 - 2 2 6 2 2 6 2 2 6 38 38 38 - 2 2 6 2 2 6 2 2 6 2 2 6 - 6 6 6 86 86 86 46 46 46 14 14 14 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 18 18 18 46 46 46 86 86 86 18 18 18 - 2 2 6 34 34 34 10 10 10 6 6 6 -210 210 210 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 221 221 221 6 6 6 - 2 2 6 2 2 6 6 6 6 30 30 30 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 82 82 82 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 26 26 26 66 66 66 62 62 62 2 2 6 - 2 2 6 38 38 38 10 10 10 26 26 26 -238 238 238 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 238 238 238 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 6 6 6 - 2 2 6 2 2 6 10 10 10 30 30 30 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 58 58 58 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 78 78 78 6 6 6 2 2 6 - 2 2 6 46 46 46 14 14 14 42 42 42 -246 246 246 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 10 10 10 - 2 2 6 2 2 6 22 22 22 14 14 14 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 62 62 62 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 74 74 74 2 2 6 2 2 6 - 14 14 14 70 70 70 34 34 34 62 62 62 -250 250 250 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 246 246 246 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 14 14 14 - 2 2 6 2 2 6 30 30 30 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 62 62 62 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 54 54 54 62 62 62 2 2 6 2 2 6 - 2 2 6 30 30 30 46 46 46 70 70 70 -250 250 250 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 246 246 246 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 226 226 226 10 10 10 - 2 2 6 6 6 6 30 30 30 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 58 58 58 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 22 22 22 - 58 58 58 62 62 62 2 2 6 2 2 6 - 2 2 6 2 2 6 30 30 30 78 78 78 -250 250 250 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 246 246 246 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 206 206 206 2 2 6 - 22 22 22 34 34 34 18 14 6 22 22 22 - 26 26 26 18 18 18 6 6 6 2 2 6 - 2 2 6 82 82 82 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 26 26 26 - 62 62 62 106 106 106 74 54 14 185 133 11 -210 162 10 121 92 8 6 6 6 62 62 62 -238 238 238 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 246 246 246 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 158 158 158 18 18 18 - 14 14 14 2 2 6 2 2 6 2 2 6 - 6 6 6 18 18 18 66 66 66 38 38 38 - 6 6 6 94 94 94 50 50 50 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 10 10 10 10 10 10 18 18 18 38 38 38 - 78 78 78 142 134 106 216 158 10 242 186 14 -246 190 14 246 190 14 156 118 10 10 10 10 - 90 90 90 238 238 238 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 250 250 250 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 246 230 190 -238 204 91 238 204 91 181 142 44 37 26 9 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 38 38 38 46 46 46 - 26 26 26 106 106 106 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 14 14 14 22 22 22 - 30 30 30 38 38 38 50 50 50 70 70 70 -106 106 106 190 142 34 226 170 11 242 186 14 -246 190 14 246 190 14 246 190 14 154 114 10 - 6 6 6 74 74 74 226 226 226 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 250 250 250 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 228 184 62 -241 196 14 241 208 19 232 195 16 38 30 10 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 30 30 30 26 26 26 -203 166 17 154 142 90 66 66 66 26 26 26 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 18 18 18 38 38 38 58 58 58 - 78 78 78 86 86 86 101 101 101 123 123 123 -175 146 61 210 150 10 234 174 13 246 186 14 -246 190 14 246 190 14 246 190 14 238 190 10 -102 78 10 2 2 6 46 46 46 198 198 198 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 224 178 62 -242 186 14 241 196 14 210 166 10 22 18 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 6 6 6 121 92 8 -238 202 15 232 195 16 82 82 82 34 34 34 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 14 14 14 38 38 38 70 70 70 154 122 46 -190 142 34 200 144 11 197 138 11 197 138 11 -213 154 11 226 170 11 242 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -225 175 15 46 32 6 2 2 6 22 22 22 -158 158 158 250 250 250 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 250 250 250 242 242 242 224 178 62 -239 182 13 236 186 11 213 154 11 46 32 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 61 42 6 225 175 15 -238 190 10 236 186 11 112 100 78 42 42 42 - 14 14 14 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 22 22 22 54 54 54 154 122 46 213 154 11 -226 170 11 230 174 11 226 170 11 226 170 11 -236 178 12 242 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -241 196 14 184 144 12 10 10 10 2 2 6 - 6 6 6 116 116 116 242 242 242 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 231 231 231 198 198 198 214 170 54 -236 178 12 236 178 12 210 150 10 137 92 6 - 18 14 6 2 2 6 2 2 6 2 2 6 - 6 6 6 70 47 6 200 144 11 236 178 12 -239 182 13 239 182 13 124 112 88 58 58 58 - 22 22 22 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 70 70 70 180 133 36 226 170 11 -239 182 13 242 186 14 242 186 14 246 186 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 232 195 16 98 70 6 2 2 6 - 2 2 6 2 2 6 66 66 66 221 221 221 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 206 206 206 198 198 198 214 166 58 -230 174 11 230 174 11 216 158 10 192 133 9 -163 110 8 116 81 8 102 78 10 116 81 8 -167 114 7 197 138 11 226 170 11 239 182 13 -242 186 14 242 186 14 162 146 94 78 78 78 - 34 34 34 14 14 14 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 30 30 30 78 78 78 190 142 34 226 170 11 -239 182 13 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 241 196 14 203 166 17 22 18 6 - 2 2 6 2 2 6 2 2 6 38 38 38 -218 218 218 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 206 206 206 198 198 198 202 162 69 -226 170 11 236 178 12 224 166 10 210 150 10 -200 144 11 197 138 11 192 133 9 197 138 11 -210 150 10 226 170 11 242 186 14 246 190 14 -246 190 14 246 186 14 225 175 15 124 112 88 - 62 62 62 30 30 30 14 14 14 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 174 135 50 224 166 10 -239 182 13 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 241 196 14 139 102 15 - 2 2 6 2 2 6 2 2 6 2 2 6 - 78 78 78 250 250 250 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 214 214 214 198 198 198 190 150 46 -219 162 10 236 178 12 234 174 13 224 166 10 -216 158 10 213 154 11 213 154 11 216 158 10 -226 170 11 239 182 13 246 190 14 246 190 14 -246 190 14 246 190 14 242 186 14 206 162 42 -101 101 101 58 58 58 30 30 30 14 14 14 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 74 74 74 174 135 50 216 158 10 -236 178 12 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 241 196 14 226 184 13 - 61 42 6 2 2 6 2 2 6 2 2 6 - 22 22 22 238 238 238 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 226 226 226 187 187 187 180 133 36 -216 158 10 236 178 12 239 182 13 236 178 12 -230 174 11 226 170 11 226 170 11 230 174 11 -236 178 12 242 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 186 14 239 182 13 -206 162 42 106 106 106 66 66 66 34 34 34 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 26 26 26 70 70 70 163 133 67 213 154 11 -236 178 12 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 241 196 14 -190 146 13 18 14 6 2 2 6 2 2 6 - 46 46 46 246 246 246 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 221 221 221 86 86 86 156 107 11 -216 158 10 236 178 12 242 186 14 246 186 14 -242 186 14 239 182 13 239 182 13 242 186 14 -242 186 14 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -242 186 14 225 175 15 142 122 72 66 66 66 - 30 30 30 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 26 26 26 70 70 70 163 133 67 210 150 10 -236 178 12 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -232 195 16 121 92 8 34 34 34 106 106 106 -221 221 221 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -242 242 242 82 82 82 18 14 6 163 110 8 -216 158 10 236 178 12 242 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 242 186 14 163 133 67 - 46 46 46 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 163 133 67 210 150 10 -236 178 12 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -241 196 14 215 174 15 190 178 144 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 218 218 218 - 58 58 58 2 2 6 22 18 6 167 114 7 -216 158 10 236 178 12 246 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 186 14 242 186 14 190 150 46 - 54 54 54 22 22 22 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 38 38 38 86 86 86 180 133 36 213 154 11 -236 178 12 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 232 195 16 190 146 13 214 214 214 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 250 250 250 170 170 170 26 26 26 - 2 2 6 2 2 6 37 26 9 163 110 8 -219 162 10 239 182 13 246 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 186 14 236 178 12 224 166 10 142 122 72 - 46 46 46 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 109 106 95 192 133 9 224 166 10 -242 186 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -242 186 14 226 184 13 210 162 10 142 110 46 -226 226 226 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -198 198 198 66 66 66 2 2 6 2 2 6 - 2 2 6 2 2 6 50 34 6 156 107 11 -219 162 10 239 182 13 246 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 242 186 14 -234 174 13 213 154 11 154 122 46 66 66 66 - 30 30 30 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 22 22 22 - 58 58 58 154 121 60 206 145 10 234 174 13 -242 186 14 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 186 14 236 178 12 210 162 10 163 110 8 - 61 42 6 138 138 138 218 218 218 250 250 250 -253 253 253 253 253 253 253 253 253 250 250 250 -242 242 242 210 210 210 144 144 144 66 66 66 - 6 6 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 61 42 6 163 110 8 -216 158 10 236 178 12 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 239 182 13 230 174 11 216 158 10 -190 142 34 124 112 88 70 70 70 38 38 38 - 18 18 18 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 22 22 22 - 62 62 62 168 124 44 206 145 10 224 166 10 -236 178 12 239 182 13 242 186 14 242 186 14 -246 186 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 236 178 12 216 158 10 175 118 6 - 80 54 7 2 2 6 6 6 6 30 30 30 - 54 54 54 62 62 62 50 50 50 38 38 38 - 14 14 14 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 80 54 7 167 114 7 -213 154 11 236 178 12 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 242 186 14 239 182 13 239 182 13 -230 174 11 210 150 10 174 135 50 124 112 88 - 82 82 82 54 54 54 34 34 34 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 158 118 36 192 133 9 200 144 11 -216 158 10 219 162 10 224 166 10 226 170 11 -230 174 11 236 178 12 239 182 13 239 182 13 -242 186 14 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 186 14 230 174 11 210 150 10 163 110 8 -104 69 6 10 10 10 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 91 60 6 167 114 7 -206 145 10 230 174 11 242 186 14 246 190 14 -246 190 14 246 190 14 246 186 14 242 186 14 -239 182 13 230 174 11 224 166 10 213 154 11 -180 133 36 124 112 88 86 86 86 58 58 58 - 38 38 38 22 22 22 10 10 10 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 34 34 34 70 70 70 138 110 50 158 118 36 -167 114 7 180 123 7 192 133 9 197 138 11 -200 144 11 206 145 10 213 154 11 219 162 10 -224 166 10 230 174 11 239 182 13 242 186 14 -246 186 14 246 186 14 246 186 14 246 186 14 -239 182 13 216 158 10 185 133 11 152 99 6 -104 69 6 18 14 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 80 54 7 152 99 6 -192 133 9 219 162 10 236 178 12 239 182 13 -246 186 14 242 186 14 239 182 13 236 178 12 -224 166 10 206 145 10 192 133 9 154 121 60 - 94 94 94 62 62 62 42 42 42 22 22 22 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 18 18 18 34 34 34 58 58 58 78 78 78 -101 98 89 124 112 88 142 110 46 156 107 11 -163 110 8 167 114 7 175 118 6 180 123 7 -185 133 11 197 138 11 210 150 10 219 162 10 -226 170 11 236 178 12 236 178 12 234 174 13 -219 162 10 197 138 11 163 110 8 130 83 6 - 91 60 6 10 10 10 2 2 6 2 2 6 - 18 18 18 38 38 38 38 38 38 38 38 38 - 38 38 38 38 38 38 38 38 38 38 38 38 - 38 38 38 38 38 38 26 26 26 2 2 6 - 2 2 6 6 6 6 70 47 6 137 92 6 -175 118 6 200 144 11 219 162 10 230 174 11 -234 174 13 230 174 11 219 162 10 210 150 10 -192 133 9 163 110 8 124 112 88 82 82 82 - 50 50 50 30 30 30 14 14 14 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 22 22 22 34 34 34 - 42 42 42 58 58 58 74 74 74 86 86 86 -101 98 89 122 102 70 130 98 46 121 87 25 -137 92 6 152 99 6 163 110 8 180 123 7 -185 133 11 197 138 11 206 145 10 200 144 11 -180 123 7 156 107 11 130 83 6 104 69 6 - 50 34 6 54 54 54 110 110 110 101 98 89 - 86 86 86 82 82 82 78 78 78 78 78 78 - 78 78 78 78 78 78 78 78 78 78 78 78 - 78 78 78 82 82 82 86 86 86 94 94 94 -106 106 106 101 101 101 86 66 34 124 80 6 -156 107 11 180 123 7 192 133 9 200 144 11 -206 145 10 200 144 11 192 133 9 175 118 6 -139 102 15 109 106 95 70 70 70 42 42 42 - 22 22 22 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 10 10 10 - 14 14 14 22 22 22 30 30 30 38 38 38 - 50 50 50 62 62 62 74 74 74 90 90 90 -101 98 89 112 100 78 121 87 25 124 80 6 -137 92 6 152 99 6 152 99 6 152 99 6 -138 86 6 124 80 6 98 70 6 86 66 30 -101 98 89 82 82 82 58 58 58 46 46 46 - 38 38 38 34 34 34 34 34 34 34 34 34 - 34 34 34 34 34 34 34 34 34 34 34 34 - 34 34 34 34 34 34 38 38 38 42 42 42 - 54 54 54 82 82 82 94 86 76 91 60 6 -134 86 6 156 107 11 167 114 7 175 118 6 -175 118 6 167 114 7 152 99 6 121 87 25 -101 98 89 62 62 62 34 34 34 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 6 6 6 10 10 10 - 18 18 18 22 22 22 30 30 30 42 42 42 - 50 50 50 66 66 66 86 86 86 101 98 89 -106 86 58 98 70 6 104 69 6 104 69 6 -104 69 6 91 60 6 82 62 34 90 90 90 - 62 62 62 38 38 38 22 22 22 14 14 14 - 10 10 10 10 10 10 10 10 10 10 10 10 - 10 10 10 10 10 10 6 6 6 10 10 10 - 10 10 10 10 10 10 10 10 10 14 14 14 - 22 22 22 42 42 42 70 70 70 89 81 66 - 80 54 7 104 69 6 124 80 6 137 92 6 -134 86 6 116 81 8 100 82 52 86 86 86 - 58 58 58 30 30 30 14 14 14 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 10 10 10 14 14 14 - 18 18 18 26 26 26 38 38 38 54 54 54 - 70 70 70 86 86 86 94 86 76 89 81 66 - 89 81 66 86 86 86 74 74 74 50 50 50 - 30 30 30 14 14 14 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 18 18 18 34 34 34 58 58 58 - 82 82 82 89 81 66 89 81 66 89 81 66 - 94 86 66 94 86 76 74 74 74 50 50 50 - 26 26 26 14 14 14 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 6 6 6 14 14 14 18 18 18 - 30 30 30 38 38 38 46 46 46 54 54 54 - 50 50 50 42 42 42 30 30 30 18 18 18 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 14 14 14 26 26 26 - 38 38 38 50 50 50 58 58 58 58 58 58 - 54 54 54 42 42 42 30 30 30 18 18 18 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 6 6 6 10 10 10 14 14 14 18 18 18 - 18 18 18 14 14 14 10 10 10 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 14 14 14 18 18 18 22 22 22 22 22 22 - 18 18 18 14 14 14 10 10 10 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/sysdrv/tools/board/luckfox_config/S99luckfoxconfigload b/sysdrv/tools/board/luckfox_config/S99luckfoxconfigload deleted file mode 100755 index 3f850145c..000000000 --- a/sysdrv/tools/board/luckfox_config/S99luckfoxconfigload +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -load_luckfoxconfig() { - if [ -f /usr/bin/luckfox-config ]; then - luckfox-config load - fi - if [ "$(cat /proc/device-tree/model)" == "Luckfox Pico Ultra" ] || - [ "$(cat /proc/device-tree/model)" == "Luckfox Pico Ultra W" ]; then - luckfox_switch_rgb_resolution & - fi -} - -case $1 in -start) - load_luckfoxconfig - ;; -*) - exit 1 - ;; -esac diff --git a/sysdrv/tools/board/luckfox_config/S99luckfoxcustomoverlay b/sysdrv/tools/board/luckfox_config/S99luckfoxcustomoverlay deleted file mode 100755 index 818cc4086..000000000 --- a/sysdrv/tools/board/luckfox_config/S99luckfoxcustomoverlay +++ /dev/null @@ -1,206 +0,0 @@ -#!/bin/bash -LUCKFOX_FDT_DTB=/tmp/.fdt.dtb -LUCKFOX_FDT_HDR_DTB=/tmp/.fdt_header.dtb -LUCKFOX_FDT_HDR_OVERLAY_DTS=/tmp/.fdt_header_overlay.dts -LUCKFOX_FDT_HDR_OVERLAY_DTBO=/tmp/.fdt_header_overlay.dtbo - -LUCKFOX_FDT_DUMP_TXT=/tmp/.fdt_dump.txt -LF_CUSTOM_DTS_PATH="/mnt/cfg" -SYS_OVERLAYS_PATH="/sys/kernel/config/device-tree/overlays" -LUCKFOX_CHIP_MEDIA_CLASS="emmc" -LUCKFOX_CHIP_MEDIA="/dev/mmcblk0p4" - -function luckfox_tools_check() { - if ! command -v dialog &>/dev/null; then - echo "The dialog is not installed " - exit - fi - - if ! command -v dtc &>/dev/null; then - echo "The dtc is not installed" - exit - fi - - # get media class dev - if [[ -e /dev/mmcblk0p4 ]]; then - LUCKFOX_CHIP_MEDIA_CLASS="emmc" - LUCKFOX_CHIP_MEDIA=/dev/mmcblk0p4 - elif [[ -e /dev/mmcblk1p4 ]]; then - LUCKFOX_CHIP_MEDIA_CLASS="sdmmc" - LUCKFOX_CHIP_MEDIA=/dev/mmcblk1p4 - luckfox_set_pin_parameter "SDMMC" 1 - elif [[ -e /dev/mtdblock3 ]]; then - LUCKFOX_CHIP_MEDIA_CLASS="spi_nand" - LUCKFOX_CHIP_MEDIA=/dev/mtdblock3 - else - LUCKFOX_CHIP_MEDIA_CLASS="unknown" - echo "Do not know the storage medium of Luckfox!" - exit - fi - -} - -# -- Static Overlay -- -function luckfox_sha256_convert() { - local sha256_hash=$1 - local formatted_hash="" - - for ((i = 0; i < ${#sha256_hash}; i += 8)); do - formatted_hash+="0x${sha256_hash:$i:8} " - done - - echo "$formatted_hash" -} - -function luckfox_update_fdt() { - # get fdt_header - local origin_fdt_size_hex origin_fdt_size - dd if=$LUCKFOX_CHIP_MEDIA of=$LUCKFOX_FDT_HDR_DTB bs=1 skip=0 count=2048 >/dev/null 2>&1 - - # get size - if [ ! -f $LUCKFOX_FDT_HDR_DTB ]; then - echo "$LUCKFOX_FDT_HDR_DTB can't be found!" - return - fi - origin_fdt_size_hex=$(fdtdump $LUCKFOX_FDT_HDR_DTB | grep -A 5 "fdt {" | grep "data-size" | awk '{print $3}' | tr -d ';<>') - origin_fdt_size=$(printf "%d\n" "$origin_fdt_size_hex") - - # get fdt dtb - dd if=$LUCKFOX_CHIP_MEDIA of=$LUCKFOX_FDT_DTB bs=1 skip=2048 count="$origin_fdt_size" >/dev/null 2>&1 - - # create fdt dump - if [ ! -f $LUCKFOX_FDT_DTB ]; then - echo "$LUCKFOX_FDT_DTB can't be found!" - return - fi - fdtdump $LUCKFOX_FDT_DTB >$LUCKFOX_FDT_DUMP_TXT -} - -function luckfox_fdt_overlay() { - #region - local fdt_overlay_dtbo="$1" - local fdt_dtb_size fdt_size fdt_size_hex fdt_hash_data - - fdtoverlay -i $LUCKFOX_FDT_DTB -o $LUCKFOX_FDT_DTB "$fdt_overlay_dtbo" >/dev/null 2>&1 - fdt_dtb_size=$(ls -la $LUCKFOX_FDT_DTB | awk '{print $5}') - - kernel_offset=$(fdtdump $LUCKFOX_FDT_HDR_DTB | grep -A 2 "kernel {" | grep "data-position" | sed -n 's/.*<\(0x[0-9a-fA-F]*\)>.*/\1/p') - fdt_offset=$(fdtdump $LUCKFOX_FDT_HDR_DTB | grep -A 2 "fdt {" | grep "data-position" | sed -n 's/.*<\(0x[0-9a-fA-F]*\)>.*/\1/p') - - kernel_offset_dec=$((kernel_offset)) - fdt_offset_dec=$((fdt_offset)) - result_dec=$((kernel_offset_dec - fdt_offset_dec)) - - if [ $result_dec -lt "$fdt_dtb_size" ]; then - echo "Kernel will be affected !" - fi - - dd if=$LUCKFOX_FDT_DTB of=$LUCKFOX_CHIP_MEDIA bs=1 seek=2048 count="$fdt_dtb_size" >/dev/null 2>&1 - - # fdt header - if [ ! -f $LUCKFOX_FDT_DTB ]; then - echo "$LUCKFOX_FDT_DTB can't be found!" - return - fi - fdt_size=$(ls -la $LUCKFOX_FDT_DTB | awk '{print $5}') - fdt_size_hex=$(printf "%x\n" "$fdt_size") - fdt_hash_data=$(luckfox_sha256_convert "$(sha256sum $LUCKFOX_FDT_DTB | awk '{print $1}')") - fdt_header_content=" -/dts-v1/; -/plugin/; - -&{/images/fdt}{ - data-size=<0x$fdt_size_hex>; - hash{ - value=<$fdt_hash_data>; - }; -}; -" - echo "$fdt_header_content" >$LUCKFOX_FDT_HDR_OVERLAY_DTS - dtc -I dts -O dtb $LUCKFOX_FDT_HDR_OVERLAY_DTS -o $LUCKFOX_FDT_HDR_OVERLAY_DTBO - if [ ! -f $LUCKFOX_FDT_HDR_OVERLAY_DTBO ]; then - echo "$LUCKFOX_FDT_HDR_OVERLAY_DTBO can't found!" - return - fi - fdtoverlay -i $LUCKFOX_FDT_HDR_DTB -o $LUCKFOX_FDT_HDR_DTB $LUCKFOX_FDT_HDR_OVERLAY_DTBO >/dev/null 2>&1 - dd if=$LUCKFOX_FDT_HDR_DTB of=$LUCKFOX_CHIP_MEDIA bs=1 seek=0 count=2048 >/dev/null 2>&1 - #endregion -} - -# Load the device tree dynamically -function luckfox_load_dynamic_dts() { - local dtbo_node_name - - if [ ! -d ${LF_CUSTOM_DTS_PATH}/dtbo/ ]; then - exit 1 - #echo "Can't find ${LF_CUSTOM_DTS_PATH}/dtbo dir !" - fi - - for dts_file in ${LF_CUSTOM_DTS_PATH}/dtbo/*.dts; do - #Get DTBO name - dtbo_node_name="$(basename "$dts_file" .dts)" - #Check DTBO path - if [ -d "${SYS_OVERLAYS_PATH}/${dtbo_node_name}" ]; then - echo "Node is exist" - continue - fi - - #DTS->DTBO - dtc -I dts -O dtb ${LF_CUSTOM_DTS_PATH}/dtbo/${dtbo_node_name}.dts -o \ - ${LF_CUSTOM_DTS_PATH}/dtbo/${dtbo_node_name}.dtbo - - if [ ! -f "${LF_CUSTOM_DTS_PATH}/dtbo/${dtbo_node_name}.dtbo" ]; then - echo "${dtbo_node_name}.dts to dtbo error!" - continue - else - mkdir -p ${SYS_OVERLAYS_PATH}/${dtbo_node_name} - fi - #Load and enable DTBO - cat ${LF_CUSTOM_DTS_PATH}/dtbo/${dtbo_node_name}.dtbo > \ - ${SYS_OVERLAYS_PATH}/${dtbo_node_name}/dtbo - echo 1 >${SYS_OVERLAYS_PATH}/${dtbo_node_name}/status - - rm ${LLF_CUSTOM_DTS_PATH}/dtbo/${dtbo_node_name}.dtbo - done -} - -#Overwrite the disk device tree (requires restart) -function luckfox_load_static_dts() { - local dtbo_node_name - if [ ! -d ${LF_CUSTOM_DTS_PATH}/fdt_overlay/ ]; then - echo "Can't find ${LF_CUSTOM_DTS_PATH}/fdt_overlay dir!" - fi - - for dts_file in ${LF_CUSTOM_DTS_PATH}/fdt_overlay/*.dts; do - #Get DTBO name - dtbo_node_name="$(basename "$dts_file" .dts)" - - #DTS->DTBO - dtc -I dts -O dtb ${LF_CUSTOM_DTS_PATH}/fdt_overlay/${dtbo_node_name}.dts -o \ - ${LF_CUSTOM_DTS_PATH}/fdt_overlay/${dtbo_node_name}.dtbo - - if [ ! -f "${LF_CUSTOM_DTS_PATH}/fdt_overlay/${dtbo_node_name}.dtbo" ]; then - echo "${dtbo_node_name}.dts to dtbo error!" - continue - fi - - # load to disk - luckfox_update_fdt - luckfox_fdt_overlay ${LF_CUSTOM_DTS_PATH}/fdt_overlay/${dtbo_node_name}.dtbo - rm ${LUCKFOX_FDT_OVERLAY_DTBO} - - done -} - -case $1 in -start) - luckfox_load_dynamic_dts - ;; -stop) - luckfox_tools_check - luckfox_load_static_dts - ;; -*) - exit 1 - ;; -esac diff --git a/sysdrv/tools/board/luckfox_config/luckfox-config b/sysdrv/tools/board/luckfox_config/luckfox-config deleted file mode 100755 index 8a793af82..000000000 --- a/sysdrv/tools/board/luckfox_config/luckfox-config +++ /dev/null @@ -1,2754 +0,0 @@ -#!/bin/bash -export LUCKFOX_CHIP_MODEL -export LUCKFOX_CHIP_MEDIA -export LUCKFOX_CHIP_MEDIA_CLASS - -LUCKFOX_DYNAMIC_DTS=/tmp/.overlay.dts -LUCKFOX_DYNAMIC_DTBO=/tmp/.overlay.dtbo - -LUCKFOX_FDT_DTB=/tmp/.fdt.dtb -LUCKFOX_FDT_OVERLAY_DTS=/tmp/.fdt_overlay.dts -LUCKFOX_FDT_OVERLAY_DTBO=/tmp/.fdt_overlay.dtbo -LUCKFOX_FDT_HDR_DTB=/tmp/.fdt_header.dtb -LUCKFOX_FDT_HDR_OVERLAY_DTS=/tmp/.fdt_header_overlay.dts -LUCKFOX_FDT_HDR_OVERLAY_DTBO=/tmp/.fdt_header_overlay.dtbo - -LUCKFOX_FDT_DUMP_TXT=/tmp/.fdt_dump.txt -LUCKFOX_PIN_DIAGRAM_FILE=/tmp/.pin_diagram.txt -LUCKFOX_CHANGE_TXT=/tmp/.change.txt - -LUCKFOX_CFG_FILE=/etc/luckfox.cfg - -# return -LF_OK=0 -LF_ERR=1 -LF_NONE=2 -LF_GUI_ENABLE=0 - -function luckfox_config_init() { - # check command - if ! command -v dialog &>/dev/null; then - echo "The dialog is not installed " - exit - fi - - if ! command -v dtc &>/dev/null; then - echo "The dtc is not installed" - exit - fi - - if ! command -v iomux &>/dev/null; then - echo "The iomux is not installed" - exit - fi - - # get chip model - LUCKFOX_CHIP_MODEL="$(cat /proc/device-tree/model)" >/dev/null 2>&1 - - # cteate cfg file - if [ ! -f $LUCKFOX_CFG_FILE ]; then - touch $LUCKFOX_CFG_FILE - fi - - # get media class - if [ ! -f $LUCKFOX_PIN_DIAGRAM_FILE ]; then - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ]; then - luckfox_pico_plus_pin_diagram_file - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Pro" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Max" ]; then - luckfox_pico_pro_max_pin_diagram_file - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico" ]; then - luckfox_pico_pin_diagram_file - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Mini A" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Mini B" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Mini" ]; then - luckfox_pico_mini_pin_diagram_file - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra W" ]; then - luckfox_pico_ultra_pin_diagram_file - fi - fi - - # get media class dev - if [[ -e /dev/mmcblk0p4 ]]; then - LUCKFOX_CHIP_MEDIA_CLASS="emmc" - LUCKFOX_CHIP_MEDIA=/dev/mmcblk0p4 - elif [[ -e /dev/mmcblk1p4 ]]; then - LUCKFOX_CHIP_MEDIA_CLASS="sdmmc" - LUCKFOX_CHIP_MEDIA=/dev/mmcblk1p4 - luckfox_set_pin_parameter "SDMMC" 1 - elif [[ -e /dev/mtdblock3 ]]; then - LUCKFOX_CHIP_MEDIA_CLASS="spi_nand" - LUCKFOX_CHIP_MEDIA=/dev/mtdblock3 - else - LUCKFOX_CHIP_MEDIA_CLASS="unknown" - echo "Do not know the storage medium of Luckfox!" - exit - fi - - # init - luckfox_update_fdt >/dev/null 2>&1 - - # Save Change - if [ -f $LUCKFOX_CHANGE_TXT ]; then - rm $LUCKFOX_CHANGE_TXT - fi - touch $LUCKFOX_CHANGE_TXT -} - -function luckfox_load_cfg() { - local group right_group - local multi_pins_group=() - local pin value pattern - local status - - local i2c_speed spi_cs_enable spi_miso_enable spi_speed - local pwm_main pwm_sub uart_main uart_sub i2c_main i2c_sub spi_main spi_sub - local compatible_device - - if [ ! -f $LUCKFOX_CFG_FILE ]; then - touch $LUCKFOX_CFG_FILE - fi - # To obtain all the reusable GPIO pin functions - while IFS= read -r line; do - if [[ "$line" == *"| |"* ]]; then - group=() - right_group=() - - IFS='-' read -r -a group <<<"$(echo "$line" | cut -d'|' -f1)" - IFS='-' read -r -a right_group <<<"$(echo "$line" | cut -d'|' -f3)" - group+=("${right_group[@]}") - - for pin in "${group[@]}"; do - if [[ "$pin" == *"UART"*"_RX"* ]]; then - multi_pins_group+=("$(echo "$pin" | sed -E 's/(UART[0-9]+_M[0-9]+)_.*$/\1/g' | sed 's/^ //')") - elif [[ "$pin" == *"PWM"* ]]; then - multi_pins_group+=("$(echo "$pin" | sed -E 's/(PWM[0-9]+_M[0-9]+).*$/\1/g' | sed 's/^ //')") - elif [[ "$pin" == *"I2C"*"_SCL"* ]]; then - multi_pins_group+=("$(echo "$pin" | sed -E 's/(I2C[0-9]+_M[0-9]+)_.*$/\1/g' | sed 's/^ //')") - elif [[ "$pin" == *"SPI"*"_CLK"* ]]; then - multi_pins_group+=("$(echo "$pin" | sed -E 's/(SPI[0-9]+_M[0-9]+)_.*$/\1/g' | sed 's/^ //')") - fi - done - fi - done <"$LUCKFOX_PIN_DIAGRAM_FILE" - - # RGB - value=$(luckfox_get_pin_cfg "RGB_ENABLE") - if [ "$value" == 1 ] || [ -z "$value" ]; then - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra W" ]; then - # set pins mark - luckfox_set_pin_mark "GPIO1_D0" 1 - luckfox_set_pin_mark "GPIO1_D1" 1 - luckfox_set_pin_mark "GPIO1_C2" 1 - luckfox_set_pin_mark "GPIO1_C3" 1 - luckfox_set_pin_mark "GPIO1_C1" 1 - - luckfox_set_pin_mark "GPIO1_C6" 1 - luckfox_set_pin_mark "GPIO2_A7" 1 - luckfox_set_pin_mark "GPIO2_A6" 1 - luckfox_set_pin_mark "GPIO1_D3" 1 - luckfox_set_pin_mark "GPIO1_C0" 1 - luckfox_set_pin_mark "GPIO1_D2" 1 - - luckfox_set_pin_mark "GPIO1_C7" 1 - luckfox_set_pin_mark "GPIO2_B0" 1 - luckfox_set_pin_mark "GPIO2_B1" 1 - - luckfox_set_pin_mark "GPIO1_C4" 1 - luckfox_set_pin_mark "GPIO1_C5" 1 - luckfox_set_pin_mark "GPIO2_A1" 1 - luckfox_set_pin_mark "GPIO2_A0" 1 - luckfox_set_pin_mark "GPIO2_A5" 1 - luckfox_set_pin_mark "GPIO2_A4" 1 - luckfox_set_pin_mark "GPIO2_A2" 1 - luckfox_set_pin_mark "GPIO2_A3" 1 - else - echo "Only Luckfox Pico Ultra /Luckfox Pico Ultra W support RGB" - fi - fi - - # CSI ( Priority is lower than RGB ) - value=$(luckfox_get_pin_cfg "CSI_ENABLE") - if [ -z "$value" ]; then - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra W" ]; then - luckfox_set_pin_mark "I2C4_M1_SCL" 1 - luckfox_set_pin_mark "I2C4_M1_SDA" 1 - luckfox_set_pin_mark "I2C4_M0_SCL" 1 - luckfox_set_pin_mark "I2C4_M0_SDA" 1 - fi - fi - - # FBTFT - value=$(luckfox_get_pin_cfg "FBTFT_ENABLE") - if [ "$value" == 1 ]; then - echo "FBTFT enable" - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico" ]; then - luckfox_set_pin_mark "GPIO1_A2" "$value" - luckfox_set_pin_mark "GPIO1_C0" "$value" - luckfox_set_pin_mark "GPIO1_C1" "$value" - luckfox_set_pin_mark "GPIO1_C2" "$value" - luckfox_set_pin_mark "GPIO1_C3" "$value" - luckfox_set_pin_mark "GPIO0_A4" "$value" - luckfox_fbtft_app 1 "sitronix,st7789v" - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Pro" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Max" ]; then - luckfox_set_pin_mark "GPIO2_B1" "$value" - luckfox_set_pin_mark "GPIO1_C0" "$value" - luckfox_set_pin_mark "GPIO1_C1" "$value" - luckfox_set_pin_mark "GPIO1_C2" "$value" - luckfox_set_pin_mark "GPIO1_C3" "$value" - luckfox_set_pin_mark "GPIO2_B0" "$value" - luckfox_fbtft_app 1 "sitronix,st7789v" - else - echo "FBTFT Not supported in this Luckfox-Pico Model!" - fi - elif [ "$value" == 0 ]; then - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico" ] || - [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Pro" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Max" ]; then - echo "Reset fbtft pins" - #luckfox_fbtft_app 0 - fi - fi - - # SDMMC - value=$(luckfox_get_pin_cfg "SDMMC_ENABLE") - - if [ -z "$value" ]; then - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ]; then - luckfox_set_pin_mark "GPIO3_A1" 1 - luckfox_set_pin_mark "GPIO3_A3" 1 - luckfox_set_pin_mark "GPIO3_A2" 1 - luckfox_set_pin_mark "GPIO3_A4" 1 - luckfox_set_pin_mark "GPIO3_A5" 1 - luckfox_set_pin_mark "GPIO3_A7" 1 - luckfox_set_pin_mark "GPIO3_A6" 1 - fi - else - luckfox_sdmmc_app "$value" - fi - - # Create global variables by comparing cfg files - for pin in "${multi_pins_group[@]}"; do - - # delete * - if [[ "$pin" == "*"* ]]; then - pin=$(echo "$pin" | sed 's/^.//') - fi - - value=$(grep "${pin}_STATUS=" $LUCKFOX_CFG_FILE | cut -d '=' -f 2) - # PWM - if [[ "$pin" == *"PWM"* ]]; then - pattern=".*PWM([0-9]+)_M([0-9]+).*" - if [[ $pin =~ $pattern ]]; then - pwm_main="${BASH_REMATCH[1]}" - pwm_sub="${BASH_REMATCH[2]}" - fi - - if [ -n "$value" ]; then - luckfox_pwm_app "$value" "$pwm_main" "$pwm_sub" - fi - fi - - # UART - if [[ "$pin" == *"UART"* ]]; then - pattern=".*UART([0-9]+)_M([0-9]+).*" - if [[ $pin =~ $pattern ]]; then - uart_main="${BASH_REMATCH[1]}" - uart_sub="${BASH_REMATCH[2]}" - fi - - if [ -n "$value" ]; then - luckfox_uart_app "$value" "$uart_main" "$uart_sub" - fi - fi - - # I2C - if [[ "$pin" == *"I2C"* ]]; then - pattern=".*I2C([0-9]+)_M([0-9]+).*" - if [[ $pin =~ $pattern ]]; then - i2c_main="${BASH_REMATCH[1]}" - i2c_sub="${BASH_REMATCH[2]}" - fi - - i2c_speed=$(grep "${pin}_SPEED=" "$LUCKFOX_CFG_FILE" | cut -d '=' -f 2) - - if [ -n "$value" ]; then - luckfox_i2c_app "$value" "$i2c_main" "$i2c_sub" "$i2c_speed" - fi - fi - - # SPI - if [[ "$pin" == *"SPI"* ]] && [[ "$(luckfox_get_pin_cfg "FBTFT_ENABLE")" != 1 ]]; then - pattern=".*SPI([0-9]+)_M([0-9]+).*" - if [[ $pin =~ $pattern ]]; then - spi_main="${BASH_REMATCH[1]}" - spi_sub="${BASH_REMATCH[2]}" - fi - spi_speed=$(luckfox_get_pin_cfg "${pin}_SPEED") - spi_miso_enable=$(luckfox_get_pin_cfg "${pin}_MISO_ENABLE") - spi_cs_enable=$(luckfox_get_pin_cfg "${pin}_CS_ENABLE") - - if [ -z "$spi_cs_enable" ]; then - spi_cs_enable=1 - luckfox_set_pin_cfg "${pin}_CS_ENABLE" 1 - fi - - if [ -z "$spi_miso_enable" ]; then - spi_miso_enable=1 - luckfox_set_pin_cfg "${pin}_MODE" 1 - fi - - if [ -n "$value" ]; then - luckfox_spi_app "$value" "$spi_main" "$spi_sub" "$spi_cs_enable" "$spi_miso_enable" "$spi_speed" - fi - fi - done - -} - -# ------------------- Pin Diagram --------------------- -function luckfox_pico_pro_max_pin_diagram_file() { - cat >$LUCKFOX_PIN_DIAGRAM_FILE <$LUCKFOX_PIN_DIAGRAM_FILE <$LUCKFOX_PIN_DIAGRAM_FILE <$LUCKFOX_PIN_DIAGRAM_FILE <$LUCKFOX_PIN_DIAGRAM_FILE <>"$LUCKFOX_PIN_DIAGRAM_FILE" - fi -} - -function luckfox_set_pin_cfg() { - local parameter_name="$1" - local parameter_value="$2" - - if grep -q "$parameter_name=" "$LUCKFOX_CFG_FILE"; then - sed -i "s/^$parameter_name=.*/$parameter_name=$parameter_value/" "$LUCKFOX_CFG_FILE" - else - echo "$parameter_name=$parameter_value" >>"$LUCKFOX_CFG_FILE" - fi -} - -function luckfox_set_pin_mark() { - local pin="$1" - local action="$2" - - #if grep -o -q "*$pin" "$LUCKFOX_PIN_DIAGRAM_FILE" ; then - # return - #fi - - if [ "$action" == 1 ]; then - pin=$(echo "$pin" | tr -d ' ') - sed -i "s/ \($pin\)/\*\1/" $LUCKFOX_PIN_DIAGRAM_FILE - elif [ "$action" == 0 ]; then - if [[ "$pin" == \** ]]; then - pin="${pin:1}" - fi - sed -i "s/\*\($pin\)/ \1/" $LUCKFOX_PIN_DIAGRAM_FILE - fi -} - -function luckfox_get_pin_cfg() { - local setting="$1" - value=$(grep "${setting}=" $LUCKFOX_CFG_FILE | cut -d '=' -f 2) - echo "$value" -} - -# ---------------------- APP ------------------------- -# -- General -- -function luckfox_sha256_convert() { - local sha256_hash=$1 - local formatted_hash="" - - for ((i = 0; i < ${#sha256_hash}; i += 8)); do - formatted_hash+="0x${sha256_hash:$i:8} " - done - - echo "$formatted_hash" -} - -function luckfox_get_device_name() { - local device_node="$1" - local device_node_name - - device_node_name=$(grep "$device_node =" $LUCKFOX_FDT_DUMP_TXT | awk '{print $3}' | sed 's/["";]//g') - echo "$device_node_name" -} - -function luckfox_get_pinctrl_addr() { - local pinctrl_node="$1" - local search_num="$2" - - local phandle_value - if [ -z "$search_num" ]; then - search_num=3 - fi - - phandle_value=$(grep -A "$search_num" "$pinctrl_node {" $LUCKFOX_FDT_DUMP_TXT | grep 'phandle' | awk '{print $3}' | sed 's/[<>;]//g') - echo "$phandle_value" -} - -function luckfox_get_pin_mode() { - local input="$1" - local reset_action="$2" - local flag - - IFS=' ' read -r -a phandle_values <<<"$input" - for phandle_value in "${phandle_values[@]}"; do - pins_value=$(grep -B1 "phandle = <$phandle_value>" "$LUCKFOX_FDT_DUMP_TXT" | grep "rockchip,pins" | sed -e 's/^.*<\(.*\)>.*$/\1/') - - if [ -n "$pins_value" ]; then - IFS=' ' read -r -a pins_array <<<"$pins_value" - for ((i = 0; i < ${#pins_array[@]}; i += 4)); do - gpio_bank_hex=${pins_array[i]} - gpio_num_hex=${pins_array[i + 1]} - gpio_mode_hex=${pins_array[i + 2]} - - gpio_bank=$((gpio_bank_hex)) - gpio_num=$((gpio_num_hex)) - gpio_mode=$((gpio_mode_hex)) - - current_gpio_mode_raw="$(iomux "$gpio_bank" "$gpio_num")" - current_gpio_mode=$(echo "$current_gpio_mode_raw" | sed 's/.*= \([0-9]*\)/\1/') - - if [ "$gpio_mode" == "$current_gpio_mode" ]; then - flag=1 - fi - done - echo "$flag" - return - fi - done - -} - -function luckfox_set_pin_mode() { - #region - local input="$1" - local reset_action="$2" - - IFS=' ' read -r -a phandle_values <<<"$input" - for phandle_value in "${phandle_values[@]}"; do - pins_value=$(grep -B1 "phandle = <$phandle_value>" "$LUCKFOX_FDT_DUMP_TXT" | grep "rockchip,pins" | sed -e 's/^.*<\(.*\)>.*$/\1/') - - if [ -n "$pins_value" ]; then - IFS=' ' read -r -a pins_array <<<"$pins_value" - for ((i = 0; i < ${#pins_array[@]}; i += 4)); do - gpio_bank_hex=${pins_array[i]} - gpio_num_hex=${pins_array[i + 1]} - gpio_mode_hex=${pins_array[i + 2]} - - gpio_bank=$((gpio_bank_hex)) - gpio_num=$((gpio_num_hex)) - gpio_mode=$((gpio_mode_hex)) - - if [ "$reset_action" == 1 ]; then - iomux "$gpio_bank" "$gpio_num" 0 - else - iomux "$gpio_bank" "$gpio_num" "$gpio_mode" - fi - done - else - luckfox_result_handle $LF_NONE "phandle" - fi - done - #endregion -} - -# -- Dynamic Overlay -- -function luckfox_dtbo_overlay() { - local overlay_node="$1" - local overlay_content="$2" - - if [ -z "$overlay_content" ]; then - "overlay_content" - fi - echo "$overlay_content" >$LUCKFOX_DYNAMIC_DTS - - dtc -I dts -O dtb $LUCKFOX_DYNAMIC_DTS -o $LUCKFOX_DYNAMIC_DTBO - if [ -d /sys/kernel/config/device-tree/overlays/"$overlay_node" ]; then - echo 0 >/sys/kernel/config/device-tree/overlays/"$overlay_node"/status - else - mkdir -p /sys/kernel/config/device-tree/overlays/"$overlay_node" - fi - cat $LUCKFOX_DYNAMIC_DTBO >/sys/kernel/config/device-tree/overlays/"$overlay_node"/dtbo - echo 1 >/sys/kernel/config/device-tree/overlays/"$overlay_node"/status - - # delete temp files - #rm $LUCKFOX_DYNAMIC_DTS - #rm $LUCKFOX_DYNAMIC_DTBO -} - -# -- Static Overlay -- -function luckfox_update_fdt() { - # get fdt_header - local origin_fdt_size_hex origin_fdt_size - dd if=$LUCKFOX_CHIP_MEDIA of=$LUCKFOX_FDT_HDR_DTB bs=1 skip=0 count=2048 >/dev/null 2>&1 - - # get size - if [ ! -f $LUCKFOX_FDT_HDR_DTB ]; then - luckfox_result_handle $LF_NONE $LUCKFOX_FDT_HDR_DTB - return - fi - origin_fdt_size_hex=$(fdtdump $LUCKFOX_FDT_HDR_DTB | grep -A 5 "fdt {" | grep "data-size" | awk '{print $3}' | tr -d ';<>') - origin_fdt_size=$(printf "%d\n" "$origin_fdt_size_hex") - - # get fdt dtb - dd if=$LUCKFOX_CHIP_MEDIA of=$LUCKFOX_FDT_DTB bs=1 skip=2048 count="$origin_fdt_size" >/dev/null 2>&1 - - # create fdt dump - if [ ! -f $LUCKFOX_FDT_DTB ]; then - luckfox_result_handle $LF_NONE $LUCKFOX_FDT_DTB - return - fi - fdtdump $LUCKFOX_FDT_DTB >$LUCKFOX_FDT_DUMP_TXT -} - -function luckfox_fdt_overlay() { - #region - local fdt_content="$1" - local fdt_dtb_size fdt_size fdt_size_hex fdt_hash_data - - if [ -z "$fdt_content" ]; then - luckfox_result_handle $LF_NONE "fdt_content" - return - fi - echo "$fdt_content" >$LUCKFOX_FDT_OVERLAY_DTS - # fdt overlay - dtc -I dts -O dtb $LUCKFOX_FDT_OVERLAY_DTS -o $LUCKFOX_FDT_OVERLAY_DTBO - if [ ! -f $LUCKFOX_FDT_OVERLAY_DTBO ]; then - luckfox_result_handle $LF_NONE $LUCKFOX_FDT_OVERLAY_DTBO - return - fi - - fdtoverlay -i $LUCKFOX_FDT_DTB -o $LUCKFOX_FDT_DTB $LUCKFOX_FDT_OVERLAY_DTBO >/dev/null 2>&1 - fdt_dtb_size=$(ls -la $LUCKFOX_FDT_DTB | awk '{print $5}') - - kernel_offset=$(fdtdump $LUCKFOX_FDT_HDR_DTB | grep -A 2 "kernel {" | grep "data-position" | sed -n 's/.*<\(0x[0-9a-fA-F]*\)>.*/\1/p') - fdt_offset=$(fdtdump $LUCKFOX_FDT_HDR_DTB | grep -A 2 "fdt {" | grep "data-position" | sed -n 's/.*<\(0x[0-9a-fA-F]*\)>.*/\1/p') - - kernel_offset_dec=$((kernel_offset)) - fdt_offset_dec=$((fdt_offset)) - result_dec=$((kernel_offset_dec - fdt_offset_dec)) - - if [ $result_dec -lt "$fdt_dtb_size" ]; then - luckfox_result_handle $LF_ERR "Kernel will be affected !" - fi - - dd if=$LUCKFOX_FDT_DTB of=$LUCKFOX_CHIP_MEDIA bs=1 seek=2048 count="$fdt_dtb_size" >/dev/null 2>&1 - - # fdt header - if [ ! -f $LUCKFOX_FDT_DTB ]; then - luckfox_result_handle $LF_NONE $LUCKFOX_FDT_DTB - return - fi - fdt_size=$(ls -la $LUCKFOX_FDT_DTB | awk '{print $5}') - fdt_size_hex=$(printf "%x\n" "$fdt_size") - fdt_hash_data=$(luckfox_sha256_convert "$(sha256sum $LUCKFOX_FDT_DTB | awk '{print $1}')") - fdt_header_content=" -/dts-v1/; -/plugin/; - -&{/images/fdt}{ - data-size=<0x$fdt_size_hex>; - hash{ - value=<$fdt_hash_data>; - }; -}; -" - echo "$fdt_header_content" >$LUCKFOX_FDT_HDR_OVERLAY_DTS - dtc -I dts -O dtb $LUCKFOX_FDT_HDR_OVERLAY_DTS -o $LUCKFOX_FDT_HDR_OVERLAY_DTBO - if [ ! -f $LUCKFOX_FDT_HDR_OVERLAY_DTBO ]; then - luckfox_result_handle $LF_NONE $LUCKFOX_FDT_HDR_OVERLAY_DTBO - return - fi - fdtoverlay -i $LUCKFOX_FDT_HDR_DTB -o $LUCKFOX_FDT_HDR_DTB $LUCKFOX_FDT_HDR_OVERLAY_DTBO >/dev/null 2>&1 - dd if=$LUCKFOX_FDT_HDR_DTB of=$LUCKFOX_CHIP_MEDIA bs=1 seek=0 count=2048 >/dev/null 2>&1 - #endregion -} - -function luckfox_fdt_clear() { - # delete temp file - local files=( - "$LUCKFOX_FDT_DUMP_TXT" - "$LUCKFOX_FDT_DTB" - "$LUCKFOX_FDT_OVERLAY_DTS" - "$LUCKFOX_FDT_OVERLAY_DTBO" - "$LUCKFOX_FDT_HDR_DTB" - "$LUCKFOX_FDT_HDR_OVERLAY_DTS" - "$LUCKFOX_FDT_HDR_OVERLAY_DTBO" - ) - - for file in "${files[@]}"; do - if [ -e "$file" ]; then - rm "$file" - fi - done -} - -# -- Time Setting -- -function luckfox_timezone_settings() { - dialog --msgbox "Developing" 10 30 -} - -function luckfox_time_synchronization() { - dialog --msgbox "Developing" 10 30 -} - -# -- Compatible Devices -- -function luckfox_compatible_Pico_LCD() { - #region - local action="$1" - local spi_device_name spi_pinctrl_addr spi_action - - if [ "$action" == 1 ]; then - luckfox_pwm_app 0 11 1 - luckfox_pwm_app 0 10 1 - luckfox_pwm_app 0 0 0 - luckfox_pwm_app 0 2 2 - luckfox_pwm_app 0 4 2 - luckfox_pwm_app 0 5 2 - luckfox_pwm_app 0 6 2 - luckfox_pwm_app 0 1 0 - luckfox_pwm_app 0 10 2 - luckfox_uart_app 0 3 1 - - if [ "$LUCKFOX_CHIP_MEDIA_CLASS" == "sdmmc" ] && [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ]; then - luckfox_result_handle $LF_ERR "The sdmmc system cannot drive the LCD" - elif [ "$LUCKFOX_CHIP_MEDIA_CLASS" == "spi_nand" ] && [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ]; then - luckfox_sdmmc_app 0 - luckfox_pwm_app 0 9 0 - luckfox_pwm_app 0 11 0 - luckfox_uart_app 0 5 0 - - luckfox_spi_app 1 0 0 1 0 - luckfox_gpio_app 1 c 6 up - luckfox_gpio_app 1 c 7 up - luckfox_gpio_app 1 d 1 up - luckfox_gpio_app 3 a 6 up - luckfox_gpio_app 3 a 7 up - luckfox_gpio_app 3 a 5 up - luckfox_gpio_app 3 a 2 up - - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Pro" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Max" ]; then - luckfox_uart_app 0 1 1 - luckfox_i2c_app 0 4 0 - - luckfox_spi_app 1 0 0 1 0 - luckfox_gpio_app 1 c 6 up - luckfox_gpio_app 1 c 7 up - luckfox_gpio_app 1 d 1 up - luckfox_gpio_app 2 a 4 up - luckfox_gpio_app 2 a 5 up - luckfox_gpio_app 2 a 0 up - luckfox_gpio_app 2 a 2 up - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico" ]; then - luckfox_spi_app 1 0 0 1 0 - luckfox_gpio_app 1 c 6 up - luckfox_gpio_app 1 c 7 up - luckfox_gpio_app 1 d 1 up - luckfox_gpio_app 4 b 1 up - luckfox_gpio_app 4 b 0 up - luckfox_gpio_app 4 a 6 up - luckfox_gpio_app 4 a 3 up - else - luckfox_result_handle $LF_ERR "The "$LUCKFOX_CHIP_MODEL" does not support this compatible device" - fi - fi - #endregion -} - -function luckfox_compatible_Pico_ePaper() { - #region - local action="$1" - local spi_device_name spi_pinctrl_addr spi_action - - if [ "$action" == 1 ]; then - luckfox_pwm_app 0 0 0 - luckfox_pwm_app 0 2 2 - luckfox_pwm_app 0 4 2 - luckfox_pwm_app 0 5 2 - luckfox_pwm_app 0 6 2 - luckfox_pwm_app 0 1 0 - - luckfox_spi_app 1 0 0 1 0 - fi - #endregion -} - -function luckfox_compatible_Pico-UPS-B() { - #region - local action="$1" - if [ "$action" == 1 ]; then - luckfox_pwm_app 0 0 1 - luckfox_pwm_app 0 11 2 - luckfox_i2c_app 1 3 1 1000000 - fi - #endregion -} - -function luckfox_compatible_Pico_ResTouch_LCD() { - local action="$1" - local spi_device_name spi_pinctrl_addr spi_action - - if [ "$action" == 1 ]; then - luckfox_pwm_app 0 8 1 - luckfox_pwm_app 0 0 0 - luckfox_pwm_app 0 2 2 - luckfox_pwm_app 0 1 0 - luckfox_pwm_app 0 10 2 - luckfox_uart_app 0 3 1 - luckfox_uart_app 0 4 1 - - luckfox_spi_app 1 0 0 0 1 - if [ "$LUCKFOX_CHIP_MEDIA_CLASS" == "sdmmc" ] && [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ]; then - luckfox_result_handle $LF_ERR "The sdmmc system cannot drive the use of SD cards and touch functions!" - elif [ "$LUCKFOX_CHIP_MEDIA_CLASS" == "spi_nand" ] && [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ]; then - luckfox_sdmmc_app 0 - luckfox_uart_app 0 5 0 - luckfox_i2c_app 0 0 2 - luckfox_result_handle $LF_OK - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Pro" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Max" ]; then - luckfox_uart_app 0 1 1 - luckfox_i2c_app 0 4 0 - luckfox_i2c_app 0 3 0 - luckfox_result_handle $LF_OK - else - luckfox_result_handle $LF_ERR "The "$LUCKFOX_CHIP_MODEL" does not support this compatible device" - fi - - fi -} - -function luckfox_compatible_OLED_Module() { - local action="$1" - - if [ "$action" == 1 ]; then - luckfox_pwm_app 0 11 1 - luckfox_pwm_app 0 10 1 - luckfox_pwm_app 0 8 1 - luckfox_pwm_app 0 0 1 - luckfox_pwm_app 0 11 2 - luckfox_pwm_app 0 4 2 - luckfox_pwm_app 0 5 2 - luckfox_uart_app 0 4 1 - - luckfox_spi_app 1 0 0 0 0 - luckfox_i2c_app 1 3 1 - fi -} - -function luckfox_compatible_Pico_OLED() { - local action="$1" - - if [ "$action" == 1 ]; then - luckfox_uart_app 0 3 1 - luckfox_pwm_app 0 0 0 - luckfox_pwm_app 0 0 1 - luckfox_pwm_app 0 11 2 - - luckfox_spi_app 1 0 0 0 0 - luckfox_i2c_app 1 3 1 - - if [ "$LUCKFOX_CHIP_MEDIA_CLASS" == "sdmmc" ] && [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ]; then - luckfox_result_handle $LF_ERR "The sdmmc system cannot drive the key1 " - elif [ "$LUCKFOX_CHIP_MEDIA_CLASS" == "spi_nand" ] && [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ]; then - luckfox_sdmmc_app 0 - luckfox_uart_app 0 5 0 - luckfox_gpio_app 1 d 1 up - luckfox_gpio_app 3 a 7 up - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Pro" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Max" ]; then - luckfox_uart_app 0 1 1 - luckfox_gpio_app 1 d 1 up - luckfox_gpio_app 2 a 5 up - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico" ]; then - luckfox_gpio_app 1 d 1 up - luckfox_gpio_app 4 b 0 up - else - luckfox_result_handle $LF_ERR "The "$LUCKFOX_CHIP_MODEL" does not support this compatible device" - fi - fi -} - -function luckfox_compatible_DHT11() { - #region - local action="$1" - local dht11_action - - if [ "$action" == 1 ]; then - # disable pwm - luckfox_pwm_app 0 11 1 - dht11_action=okay - else - dht11_action=disabled - fi - - local dtbo_content=" -/dts-v1/; -/plugin/; - -&{/dht11_sensor}{ - status=\"$dht11_action\"; -}; -" - luckfox_dtbo_overlay "dht11" "$dtbo_content" - #endregion -} - -function luckfox_compatible_app() { - local compatible_device="$1" - local action="$2" - local device - local compatible_group=() - - # Set up an inventory of adaptable hardware - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico" ]; then - compatible_group=(Pico_LCD Pico_ePaper Pico_UPS_B OLED_Module Pico_OLED DHT11) - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ] && [ "$LUCKFOX_CHIP_MEDIA_CLASS" == "sdmmc" ]; then - compatible_group=(Pico_ePaper Pico_UPS_B OLED_Module DHT11) - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ] && [ "$LUCKFOX_CHIP_MEDIA_CLASS" == "spi_nand" ]; then - compatible_group=(Pico_LCD Pico_ePaper Pico_UPS_B Pico_ResTouch_LCD OLED_Module Pico_OLED DHT11) - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Pro" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Max" ]; then - compatible_group=(Pico_LCD Pico_ePaper Pico_UPS_B Pico_ResTouch_LCD OLED_Module Pico_OLED DHT11) - fi - - for device in "${compatible_group[@]}"; do - if [ "$device" == "$compatible_device" ]; then - luckfox_compatible_"${compatible_device}" "$action" - return - fi - done - luckfox_result_handle "$LF_ERR" "This compatible device $compatible_device is not supported!" -} - -# -- Advanced Options -- - -function hex_add() { - local hex1=$1 - local hex2=$2 - - local dec1=$(printf "%d" 0x"$hex1") - local dec2=$(printf "%d" 0x"$hex2") - local sum_hex=$(printf "%X" $((dec1 + dec2))) - - echo "$sum_hex" -} - -function hex_shift() { - local hex=$1 - local shift_amount=$2 - - # 将十六进制数转换为十进制 - local dec=$(printf "%d" 0x$hex) - - # 计算移位数 - local shift=$((shift_amount * 2)) - - # 进行移位操作 - local shifted=$((dec << shift)) - - # 将结果转换回十六进制并输出 - printf "%X\n" $shifted -} - -function luckfox_gpio_app() { - local gpio_bank="$1" - local gpio_group="$2" - local gpio_number="$3" - local gpio_pull_mode="$4" - - local reg_addr_base reg_addr data - - PULL_MODE_DATE_NORMAL=30000 - PULL_MODE_DATE_UP=30001 - PULL_MODE_DATE_DOWN=30002 - - # GPIO Bank - RV1106_GPIO0=ff388038 - RV1106_GPIO1=ff5381C0 - RV1106_GPIO2=ff5481D0 - RV1106_GPIO3=ff5581E0 - RV1106_GPIO4=ff568070 - - #Group - A_OFFSET=0 - B_OFFSET=4 - C_OFFSET=8 - D_OFFSET=c - - case $gpio_bank in - 0) - reg_addr_base="$RV1106_GPIO0" - ;; - 1) - reg_addr_base="$RV1106_GPIO1" - ;; - 2) - reg_addr_base="$RV1106_GPIO2" - ;; - 3) - reg_addr_base="$RV1106_GPIO3" - ;; - 4) - reg_addr_base="$RV1106_GPIO4" - ;; - *) - echo "input error!" - exit - ;; - esac - - case $gpio_group in - a) - reg_addr=0x$(hex_add $reg_addr_base $A_OFFSET) - ;; - b) - reg_addr=0x$(hex_add $reg_addr_base $B_OFFSET) - ;; - c) - reg_addr=0x$(hex_add $reg_addr_base $C_OFFSET) - ;; - d) - reg_addr=0x$(hex_add $reg_addr_base $D_OFFSET) - ;; - *) - echo "input error!" - exit - ;; - esac - - case $gpio_pull_mode in - normal) - data=0x$(hex_shift $PULL_MODE_DATE_NORMAL "$gpio_number") - ;; - up) - data=0x$(hex_shift $PULL_MODE_DATE_UP "$gpio_number") - ;; - down) - data=0x$(hex_shift $PULL_MODE_DATE_DOWN "$gpio_number") - ;; - *) - echo "input error!" - exit - ;; - esac - - io -4 "$reg_addr" "$data" -} - -function luckfox_pwm_app() { - #region - local action="$1" - local pwm_main="$2" - local pwm_sub="$3" - - local pwm_device_name pwm_pinctrl_addr - pre_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "pwm${pwm_main}m${pwm_sub}-pins")") - - # status - if [ "$action" == 1 ]; then - local pwm_action=okay - luckfox_check_pin_diagram "PWM${pwm_main}_M${pwm_sub}" - pwm_pinctrl_addr=$(luckfox_get_pinctrl_addr "pwm${pwm_main}m${pwm_sub}-pins") - else - local pwm_action=disabled - pwm_pinctrl_addr="" - fi - luckfox_set_pin_mark "PWM${pwm_main}_M${pwm_sub}" "$action" - - # device addr - pwm_device_name=$(luckfox_get_device_name "pwm${pwm_main}") - - local dtbo_content=" -/dts-v1/; -/plugin/; - -&{$pwm_device_name}{ - pinctrl-0=<$pwm_pinctrl_addr>; - status=\"$pwm_action\"; -}; -" - # dtb overlay - luckfox_dtbo_overlay "pwm${pwm_main}m${pwm_sub}" "$dtbo_content" - if [ "$action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "pwm${pwm_main}m${pwm_sub}-pins")" 0 - elif [ "$action" == 0 ] && [ "$pre_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "pwm${pwm_main}m${pwm_sub}-pins")" 1 - fi - - # update cfg - luckfox_set_pin_cfg "PWM${pwm_main}_M${pwm_sub}_STATUS" "$action" - - #endregion -} - -function luckfox_check_uart() { - #region - local uart_mode="$1" - local uart_main="$2" - - # Set UART1 in Luckfox Pico Ultra W - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra W" ]; then - if [ "$uart_mode" == 0 ] && [ "$uart_main" == 1 ]; then - luckfox_result_handle "$LF_ERR" "BlueTooth is enable,Can't enable UART1" - fi - fi - #endregion -} - -function luckfox_uart_app() { - #region - local action="$1" - local uart_main="$2" - local uart_sub="$3" - - local uart_device_name uart_pinctrl_addr - local pre_action - pre_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "uart${uart_main}m${uart_sub}-xfer")") - - # status - if [ "$action" == 1 ]; then - local uart_action=okay - luckfox_check_pin_diagram "UART${uart_main}_M${uart_sub}_TX" "UART${uart_main}_M${uart_sub}_RX" - luckfox_check_uart 0 "$uart_main" - uart_pinctrl_addr=$(luckfox_get_pinctrl_addr "uart${uart_main}m${uart_sub}-xfer") - else - local uart_action=disabled - uart_pinctrl_addr="" - fi - luckfox_set_pin_mark "UART${uart_main}_M${uart_sub}_TX" "$action" - luckfox_set_pin_mark "UART${uart_main}_M${uart_sub}_RX" "$action" - # device addr - uart_device_name=$(luckfox_get_device_name "serial${uart_main}") - - local dtbo_content=" -/dts-v1/; -/plugin/; - -&{$uart_device_name}{ - pinctrl-0=<$uart_pinctrl_addr>; - status=\"$uart_action\"; -}; -" - # dtb overlay - luckfox_dtbo_overlay "uart${uart_main}m${uart_sub}" "$dtbo_content" - if [ "$action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "uart${uart_main}m${uart_sub}-xfer")" 0 - elif [ "$action" == 0 ] && [ "$pre_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "uart${uart_main}m${uart_sub}-xfer")" 1 - fi - - if [ -f "/dev/ttyS${uart_main}" ]; then - rm /dev/ttyS"${uart_main}" - fi - # update cfg - luckfox_set_pin_cfg "UART${uart_main}_M${uart_sub}_STATUS" "$action" - #endregion -} - -function luckfox_check_i2c() { - #region - local i2c_mode="$1" - local i2c_main="$2" - - local ts_status - # Set GPIO - if [ "$i2c_mode" == 0 ]; then - #check TP status - if [ "$i2c_main" == 3 ]; then - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra W" ]; then - ts_status=$(luckfox_get_pin_cfg "TS_ENABLE") - if [ "$ts_status" == 1 ]; then - luckfox_result_handle "$LF_ERR" "TouchScreen is enable,Can't config I2C3" - else - local dtbo_content=" -/dts-v1/; -/plugin/; - -&{/i2c@ff460000/touchscreen}{ - status=\"disabled\"; -}; -" - luckfox_dtbo_overlay "TouchScreen_I2C" "$dtbo_content" - fi - fi - fi - #check CSI status - if [ "$i2c_main" == 4 ]; then - csi_status=$(luckfox_get_pin_cfg "CSI_ENABLE") - # process default status - if [ -z "$csi_status" ]; then - # CSI I2C is not enabled on Ultra models by default - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra W" ]; then - "$csi_status" = 0 - else - "$csi_status" = 1 - fi - fi - - if [ "$csi_status" == 1 ]; then - luckfox_result_handle "$LF_ERR" "CSI is enable,Can't config I2C4" - fi - fi - # Set CSI or TS - elif [ "$i2c_mode" == 1 ]; then - # Enable TS - if [ "$i2c_main" == 3 ]; then - if [ "$(luckfox_get_pin_cfg "I2C3_M0_STATUS")" == 1 ] || - [ "$(luckfox_get_pin_cfg "I2C3_M1_STATUS")" == 1 ] || - [ "$(luckfox_get_pin_cfg "I2C3_M2_STATUS")" == 1 ]; then - luckfox_result_handle "$LF_ERR" "I2C3 is enable,Can't config TouchScreen" - fi - fi - # Enable CSI - if [ "$i2c_main" == 4 ]; then - if [ "$(luckfox_get_pin_cfg "I2C4_M0_STATUS")" == 1 ] || - [ "$(luckfox_get_pin_cfg "I2C4_M1_STATUS")" == 1 ] || - [ "$(luckfox_get_pin_cfg "I2C4_M2_STATUS")" == 1 ]; then - luckfox_result_handle "$LF_ERR" "I2C4 is enable,Can't config CSI" - fi - fi - fi - #endregion -} - -function luckfox_i2c_app() { - #region - local action="$1" - local i2c_main="$2" - local i2c_sub="$3" - local i2c_speed - - #check - luckfox_check_i2c 0 "$i2c_main" - - if [ -z "$4" ]; then - i2c_speed=5000000 - else - i2c_speed="$4" - fi - - local i2c_device_name i2c_pinctrl_addr - local pre_action - pre_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "i2c${i2c_main}m${i2c_sub}-xfer")") - - # status - if [ "$action" == 1 ]; then - luckfox_check_pin_diagram "I2C${i2c_main}_M${i2c_sub}_SDA" "I2C${i2c_main}_M${i2c_sub}_SCL" - i2c_pinctrl_addr=$(luckfox_get_pinctrl_addr "i2c${i2c_main}m${i2c_sub}-xfer") - local i2c_action=okay - else - i2c_pinctrl_addr="" - local i2c_action=disabled - fi - - # device addr - i2c_device_name=$(luckfox_get_device_name "i2c${i2c_main}") - - local dtbo_content=" -/dts-v1/; -/plugin/; - -&{$i2c_device_name}{ - status=\"$i2c_action\"; - clock-frequency = <$i2c_speed>; - pinctrl-0 = <$i2c_pinctrl_addr>; -}; -" - # dtb overlay - luckfox_dtbo_overlay "i2c${i2c_main}m${i2c_sub}" "$dtbo_content" - if [ "$action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "i2c${i2c_main}m${i2c_sub}-xfer")" 0 - elif [ "$action" == 0 ] && [ "$pre_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "i2c${i2c_main}m${i2c_sub}-xfer")" 1 - fi - - # update cfg - luckfox_set_pin_cfg "I2C${i2c_main}_M${i2c_sub}_STATUS" "$action" - luckfox_set_pin_cfg "I2C${i2c_main}_M${i2c_sub}_SPEED" "$i2c_speed" - luckfox_set_pin_parameter "I2C${i2c_main}_M${i2c_sub}_SPEED" "$i2c_speed" - # mark - luckfox_set_pin_mark "I2C${i2c_main}_M${i2c_sub}_SDA" "$action" - luckfox_set_pin_mark "I2C${i2c_main}_M${i2c_sub}_SCL" "$action" - - #endregion -} - -function luckfox_check_spi() { - #region - local spi_mode="$1" - local spi_main="$2" - - # Set GPIO - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico" ] || - [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Pro" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Max" ]; then - fbtft_status=$(luckfox_get_pin_cfg "FBTFT_ENABLE") - spi0m0_status=$(luckfox_get_pin_cfg "SPI0_M0_STATUS") - if [ "$spi_mode" == 0 ] && [ "$spi_main" == 0 ]; then - if [ "$fbtft_status" == 1 ]; then - luckfox_result_handle "$LF_ERR" "FBTFT is enable,Can't config SPI0" - else - local dtbo_content=" -/dts-v1/; -/plugin/; - -&{/spi@ff500000/fbtft@0}{ - status=\"disabled\"; -}; -" - luckfox_dtbo_overlay "FBTFT_SPI" "$dtbo_content" - fi - # Set FBTFT - elif [ "$spi_mode" == 1 ] && [ "$spi_main" == 0 ]; then - if [ "$spi0m0_status" == 1 ]; then - luckfox_result_handle "$LF_ERR" "SPI0M0 is enable,Can't config FBTFT" - fi - fi - fi - #endregion -} - -function luckfox_spi_app() { - #region - local action="$1" - local spi_main="$2" - local spi_sub="$3" - local cs_action="$4" - local miso_action="$5" - local spi_speed - if [ -z "$6" ]; then - spi_speed=50000000 - else - spi_speed="$6" - fi - - luckfox_check_spi 0 "$spi_main" - - local spi_device_name - local spi_pinctrl_addr="" - - # Prevent being repeatedly disabled - local pre_action pre_miso_action pre_cs_action - pre_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-clk")") - pre_miso_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-miso")") - pre_cs_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-cs0")") - - # set cfg - if [ "$action" == 1 ]; then - # check - if [ "$cs_action" == 1 ]; then - luckfox_check_pin_diagram "SPI${spi_main}_M${spi_sub}_CS0" - fi - if [ "$miso_action" == 1 ]; then - luckfox_check_pin_diagram "SPI${spi_main}_M${spi_sub}_MISO" - fi - luckfox_check_pin_diagram "SPI${spi_main}_M${spi_sub}_MOSI" - luckfox_check_pin_diagram "SPI${spi_main}_M${spi_sub}_CLK" - # phandle - spi_pinctrl_addr+=$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-clk") - spi_pinctrl_addr+=" " - spi_pinctrl_addr+=$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-mosi") - if [ "$cs_action" == 1 ]; then - spi_pinctrl_addr+=" " - spi_pinctrl_addr+=$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-cs0") - fi - if [ "$miso_action" == 1 ]; then - spi_pinctrl_addr+=" " - spi_pinctrl_addr+=$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-miso") - fi - # status - local spi_action=okay - - elif [ "$action" == 0 ]; then - # status - local spi_action=disabled - fi - - # create dtc - spi_device_name=$(luckfox_get_device_name "spi${spi_main}") - if [ "$action" == 1 ]; then - dtbo_content=" -/dts-v1/; -/plugin/; - -&{$spi_device_name}{ - status=\"$spi_action\"; - pinctrl-0 = <$spi_pinctrl_addr>; -}; - -&{$spi_device_name/spidev@0}{ - status=\"$spi_action\"; - spi-max-frequency = <$spi_speed>; -}; -" - elif [ "$action" == 0 ]; then - dtbo_content=" -/dts-v1/; -/plugin/; - -&{$spi_device_name}{ - status=\"$spi_action\"; -}; - -&{$spi_device_name/spidev@0}{ - status=\"$spi_action\"; -}; -" - fi - - # dtb overlay - luckfox_dtbo_overlay spi"${spi_main}"m"${spi_sub}" "$dtbo_content" - - # update pin fun - if [ "$action" == 1 ]; then - if [ "$pre_miso_action" == 1 ] && [ "$miso_action" == 0 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-miso")" 1 - elif [ "$miso_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-miso")" 0 - fi - - if [ "$pre_cs_action" == 1 ] && [ "$cs_action" == 0 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-cs0")" 1 - elif [ "$cs_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-cs0")" 0 - fi - - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-clk")" 0 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-mosi")" 0 - elif [ "$action" == 0 ]; then - if [ "$pre_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-clk")" 1 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-mosi")" 1 - fi - - if [ "$pre_miso_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-miso")" 1 - fi - - if [ "$pre_cs_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-cs0")" 1 - fi - fi - - # update cfg show cfg in " luckfox-config show " - luckfox_set_pin_cfg "SPI${spi_main}_M${spi_sub}_STATUS" "$action" - luckfox_set_pin_cfg "SPI${spi_main}_M${spi_sub}_CS_ENABLE" "$cs_action" - luckfox_set_pin_cfg "SPI${spi_main}_M${spi_sub}_MISO_ENABLE" "$miso_action" - luckfox_set_pin_cfg "SPI${spi_main}_M${spi_sub}_SPEED" "$spi_speed" - luckfox_set_pin_parameter "SPI${spi_main}_M${spi_sub}_SPEED" "$spi_speed" - - # mark - if [ "$cs_action" == 1 ] && [ "$action" == 1 ]; then - luckfox_set_pin_mark "SPI${spi_main}_M${spi_sub}_CS0" "$action" - else - luckfox_set_pin_mark "SPI${spi_main}_M${spi_sub}_CS0" 0 - fi - - if [ "$miso_action" == 1 ] && [ "$action" == 1 ]; then - luckfox_set_pin_mark "SPI${spi_main}_M${spi_sub}_MISO" "$action" - else - luckfox_set_pin_mark "SPI${spi_main}_M${spi_sub}_MISO" 0 - fi - luckfox_set_pin_mark "SPI${spi_main}_M${spi_sub}_CLK" "$action" - luckfox_set_pin_mark "SPI${spi_main}_M${spi_sub}_MOSI" "$action" - #endregion -} - -function luckfox_usb_app() { - #region - local usb_mode="$1" - - # update fdt - luckfox_update_fdt - - # fdt overlay content - local fdt_content=" -/dts-v1/; -/plugin/; - -&{/usbdrd/usb@ffb00000}{ - dr_mode =\"${usb_mode}\"; -}; -" - # fdt overlay - luckfox_fdt_overlay "$fdt_content" - - # update cfg - luckfox_set_pin_cfg "USB_MODE" "$usb_mode" - - #endregion -} - -function luckfox_csi_app() { - #region - local action="$1" - # update fdt - luckfox_update_fdt - - local i2c_pinctrl_addr - # create fdt overlay content - if [ "$action" == 1 ]; then - luckfox_check_i2c 1 4 - i2c_pinctrl_addr=$(luckfox_get_pinctrl_addr "i2c4m2-xfer") - local csi_action=okay - else - local csi_action=disbaled - fi - - if [ "$action" == 1 ]; then - local i2c_content=" -/dts-v1/; -/plugin/; -&{/i2c@ff470000}{ - status=\"$csi_action\"; - pinctrl-0 = <$i2c_pinctrl_addr>; -}; -" - else - local i2c_content=" -/dts-v1/; -/plugin/; -&{/i2c@ff470000}{ - status=\"$csi_action\"; -}; -" - fi - - # fdt overlay - luckfox_fdt_overlay "$i2c_content" - - # update cfg - luckfox_set_pin_cfg "CSI_ENABLE" "$action" - luckfox_set_pin_parameter "CSI_ENABLE" "$action" - - luckfox_set_pin_mark "I2C4_M0_SCL" 0 - luckfox_set_pin_mark "I2C4_M0_SDA" 0 - luckfox_set_pin_mark "I2C4_M1_SCL" 0 - luckfox_set_pin_mark "I2C4_M1_SDA" 0 - - #endregion -} - -function luckfox_rgb_check_params() { - local params=("$@") - - for param in "${params[@]}"; do - if [[ -z "$param" ]]; then - echo "Error: Parameter is empty." - return 1 - fi - - if ! [[ "$param" =~ ^[0-9]+$ ]]; then - echo "Error: Parameter '$param' is not a number." - return 1 - fi - done -} - -function luckfox_rgb_app() { - #region - local action="$1" - local rgb_mode="$2" - local rgb_clk="$3" - local rgb_h="$4" - local rgb_v="$5" - local rgb_hb="$6" - local rgb_hf="$7" - local rgb_vb="$8" - local rgb_vf="$9" - local rgb_h_len="${10}" - local rgb_v_len="${11}" - local rgb_h_active="${12}" - local rgb_v_active="${13}" - local rgb_de_active="${14}" - local rgb_pclk_active="${15}" - - local gpio0_phandle reset_gpio_action enable_gpio_action - - local pre_action - - pre_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "lcd-pins")") - # create fdt overlay content - if [ "$action" == 1 ]; then - if [ "$rgb_mode" == "reset" ]; then - reset_gpio_action=okay - enable_gpio_action=disabled - elif [ "$rgb_mode" == "enable" ]; then - reset_gpio_action=disabled - enable_gpio_action=okay - else - luckfox_result_handle $LF_ERR "Wrong rgb_mode!" - return 1 - fi - - luckfox_rgb_check_params "$rgb_clk" "$rgb_h" "$rgb_v" "$rgb_hb" "$rgb_hf" "$rgb_vb" "$rgb_vf" "$rgb_h_len" "$rgb_v_len" "$rgb_h_active" "$rgb_v_active" "$rgb_de_active" "$rgb_pclk_active" - if [[ $? -ne 0 ]]; then - luckfox_result_handle $LF_ERR "Wrong rgb_params!" - return 1 - else - # decimal to hex - rgb_clk_hex=$(printf '0x%x\n' "$rgb_clk") - rgb_h_hex=$(printf '0x%x\n' "$rgb_h") - rgb_v_hex=$(printf '0x%x\n' "$rgb_v") - rgb_hb_hex=$(printf '0x%x\n' "$rgb_hb") - rgb_hf_hex=$(printf '0x%x\n' "$rgb_hf") - rgb_vb_hex=$(printf '0x%x\n' "$rgb_vb") - rgb_vf_hex=$(printf '0x%x\n' "$rgb_vf") - rgb_h_len_hex=$(printf '0x%x\n' "$rgb_h_len") - rgb_v_len_hex=$(printf '0x%x\n' "$rgb_v_len") - rgb_h_active_hex=$(printf '0x%x\n' "$rgb_h_active") - rgb_v_active_hex=$(printf '0x%x\n' "$rgb_v_active") - rgb_de_active_hex=$(printf '0x%x\n' "$rgb_de_active") - rgb_pclk_active_hex=$(printf '0x%x\n' "$rgb_pclk_active") - - fi - - luckfox_check_pin_diagram "GPIO1_D0" "GPIO1_D1" "GPIO1_C2" "GPIO1_C3" "GPIO1_C1" \ - "GPIO1_C6" "GPIO2_A7" "GPIO2_A6" "GPIO1_D3" "GPIO1_C0" "GPIO1_D2" \ - "GPIO1_C7" "GPIO2_B0" "GPIO2_B1" \ - "GPIO1_C4" "GPIO1_C5" "GPIO2_A1" "GPIO2_A0" "GPIO2_A5" "GPIO2_A4" "GPIO2_A2" "GPIO2_A3" - - if [ "$rgb_h" -gt 640 ] || [ "$rgb_h" -gt 640 ]; then - local cma_action=okay - else - local cma_action=disabled - fi - - local rgb_action=okay - else - local rgb_action=disabled - local cma_action=disabled - fi - - # create fdt_content - local fdt_content=" -/dts-v1/; -/plugin/; - -&{/syscon@ff000000/rgb}{ - status=\"$rgb_action\"; -}; - -&{/panel}{ - status=\"$rgb_action\"; -}; - -&{/reserved-memory/linux,cma}{ - status=\"$cma_action\"; -}; - -" - # Get GPIO0 phandle - #gpio0_phandle=$(luckfox_get_pinctrl_addr "gpio@ff380000" 11) - - local lcd_time_content=" -/dts-v1/; -/plugin/; - -&{/panel/display-timings/timing0}{ - clock-frequency = <$rgb_clk_hex>; - hactive = <$rgb_h_hex>; - vactive = <$rgb_v_hex>; - hback-porch = <$rgb_hb_hex>; - hfront-porch = <$rgb_hf_hex>; - vback-porch = <$rgb_vb_hex>; - vfront-porch = <$rgb_vf_hex>; - hsync-len = <$rgb_h_len_hex>; - vsync-len = <$rgb_v_len_hex>; - hsync-active = <$rgb_h_active_hex>; - vsync-active = <$rgb_v_active_hex>; - de-active = <$rgb_de_active_hex>; - pixelclk-active = <$rgb_pclk_active_hex>; -}; -" - - # fdt overlay - luckfox_fdt_overlay "$fdt_content" - if [ "$action" == 1 ]; then - luckfox_fdt_overlay "$lcd_time_content" - elif [ "$action" == 0 ] && [ "$pre_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "lcd-pins")" 1 - fi - - # update cfg - luckfox_set_pin_cfg "RGB_ENABLE" "$action" - if [ "$action" == 1 ]; then - luckfox_set_pin_cfg "RGB_MODE" "$rgb_mode" - luckfox_set_pin_cfg "RGB_CLK" "$rgb_clk" - luckfox_set_pin_cfg "RGB_HACTIVE" "$rgb_h" - luckfox_set_pin_cfg "RGB_VACTIVE" "$rgb_v" - luckfox_set_pin_cfg "RGB_HBACKPORCH" "$rgb_hb" - luckfox_set_pin_cfg "RGB_HFRONTPORCH" "$rgb_hf" - luckfox_set_pin_cfg "RGB_VBACKPORCH" "$rgb_vb" - luckfox_set_pin_cfg "RGB_VFRONTPORCH" "$rgb_vf" - luckfox_set_pin_cfg "RGB_HSYNC_LEN" "$rgb_h_len" - luckfox_set_pin_cfg "RGB_VSYNC_LEN" "$rgb_v_len" - luckfox_set_pin_cfg "RGB_HSYNC_ACTIVE" "$rgb_h_active" - luckfox_set_pin_cfg "RGB_VSYNC_ACTIVE" "$rgb_v_active" - luckfox_set_pin_cfg "RGB_DE_ACTIVE" "$rgb_de_active" - luckfox_set_pin_cfg "RGB_PCLK_ACTIVE" "$rgb_pclk_active" - - luckfox_set_pin_parameter "RGB_MODE" "$rgb_mode" - luckfox_set_pin_parameter "RGB_CLK" "$rgb_clk" - luckfox_set_pin_parameter "RGB_HACTIVE" "$rgb_h" - luckfox_set_pin_parameter "RGB_VACTIVE" "$rgb_v" - luckfox_set_pin_parameter "RGB_HBACKPORCH" "$rgb_hb" - luckfox_set_pin_parameter "RGB_HFRONTPORCH" "$rgb_hf" - luckfox_set_pin_parameter "RGB_VBACKPORCH" "$rgb_vb" - luckfox_set_pin_parameter "RGB_VFRONTPORCH" "$rgb_vf" - luckfox_set_pin_parameter "RGB_HSYNC_LEN" "$rgb_h_len" - luckfox_set_pin_parameter "RGB_VSYNC_LEN" "$rgb_v_len" - luckfox_set_pin_parameter "RGB_HSYNC_ACTIVE" "$rgb_h_active" - luckfox_set_pin_parameter "RGB_VSYNC_ACTIVE" "$rgb_v_active" - luckfox_set_pin_parameter "RGB_DE_ACTIVE" "$rgb_de_active" - luckfox_set_pin_parameter "RGB_PCLK_ACTIVE" "$rgb_pclk_active" - fi - - luckfox_set_pin_parameter "RGB_ENABLE" "$action" - - # set pins mark - luckfox_set_pin_mark "GPIO1_D0" "$action" - luckfox_set_pin_mark "GPIO1_D1" "$action" - luckfox_set_pin_mark "GPIO1_C2" "$action" - luckfox_set_pin_mark "GPIO1_C3" "$action" - luckfox_set_pin_mark "GPIO1_C1" "$action" - - luckfox_set_pin_mark "GPIO1_C6" "$action" - luckfox_set_pin_mark "GPIO2_A7" "$action" - luckfox_set_pin_mark "GPIO2_A6" "$action" - luckfox_set_pin_mark "GPIO1_D3" "$action" - luckfox_set_pin_mark "GPIO1_C0" "$action" - luckfox_set_pin_mark "GPIO1_D2" "$action" - - luckfox_set_pin_mark "GPIO1_C7" "$action" - luckfox_set_pin_mark "GPIO2_B0" "$action" - luckfox_set_pin_mark "GPIO2_B1" "$action" - - luckfox_set_pin_mark "GPIO1_C4" "$action" - luckfox_set_pin_mark "GPIO1_C5" "$action" - luckfox_set_pin_mark "GPIO2_A1" "$action" - luckfox_set_pin_mark "GPIO2_A0" "$action" - luckfox_set_pin_mark "GPIO2_A5" "$action" - luckfox_set_pin_mark "GPIO2_A4" "$action" - luckfox_set_pin_mark "GPIO2_A2" "$action" - luckfox_set_pin_mark "GPIO2_A3" "$action" - #endregion -} - -function luckfox_ts_app() { - #region - local action="$1" - local ts_reg_hex="$2" - - luckfox_check_i2c 1 3 - - # update fdt - luckfox_update_fdt - - #ts_reg_hex=$(printf '0x%x\n' "$ts_reg") - - local i2c_pinctrl_addr tp_action tp_rst_pinctrl_addr tp_irq_pinctrl_addr - # create fdt overlay content - if [ "$action" == 1 ]; then - i2c_pinctrl_addr=$(luckfox_get_pinctrl_addr "i2c3m2-xfer") - tp_rst_pinctrl_addr=$(luckfox_get_pinctrl_addr "tp-rst") - tp_irq_pinctrl_addr=$(luckfox_get_pinctrl_addr "tp-irq") - local ts_action=okay - else - local ts_action=disbaled - fi - - # TouchScreen device tree overlay - # Just support GT911 now - - # I2C device tree overlay - if [ "$action" == 1 ]; then - local fdt_content=" -/dts-v1/; -/plugin/; -&{/i2c@ff460000}{ - status=\"$ts_action\"; - pinctrl-0 = <$i2c_pinctrl_addr $tp_irq_pinctrl_addr $tp_rst_pinctrl_addr>; -}; - -&{/i2c@ff460000/touchscreen}{ - status=\"$ts_action\"; - reg=<$ts_reg_hex>; -}; -" - elif [ "$action" == 0 ]; then - local fdt_content=" -/dts-v1/; -/plugin/; -&{/i2c@ff460000}{ - status=\"$ts_action\"; -}; - -&{/i2c@ff460000/touchscreen}{ - status=\"$ts_action\"; -}; -" - fi - - # fdt overlay - luckfox_fdt_overlay "$fdt_content" - - # update cfg - luckfox_set_pin_cfg "TS_ENABLE" "$action" - luckfox_set_pin_parameter "TS_ENABLE" "$action" - - #endregion -} - -function luckfox_fbtft_app() { - #region - local action="$1" - local fbtft_compatible="$2" - local spi_device_name - - local spi_main=0 - local spi_sub=0 - local pre_action pre_cs_action pre_miso_action - - # check - luckfox_check_spi 1 0 - - pre_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-clk")") - pre_miso_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-miso")") - pre_cs_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-cs0")") - - #ts_reg_hex=$(printf '0x%x\n' "$ts_reg") - if [ "$action" == 1 ]; then - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico" ]; then - luckfox_check_pin_diagram "GPIO1_A2" "GPIO1_C0" "GPIO1_C1" "GPIO1_C2" "GPIO1_C3" "GPIO0_A4" - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Pro" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Max" ]; then - luckfox_check_pin_diagram "GPIO2_B1" "GPIO1_C0" "GPIO1_C1" "GPIO1_C2" "GPIO1_C3" "GPIO2_B0" - else - luckfox_result_handle "$LF_ERR" "This Luckfox-Pico Model does not support FBTFT setting!" - return - fi - - spi_pinctrl_addr+=$(luckfox_get_pinctrl_addr "spi0m0-clk") - spi_pinctrl_addr+=" " - spi_pinctrl_addr+=$(luckfox_get_pinctrl_addr "spi0m0-mosi") - spi_pinctrl_addr+=" " - spi_pinctrl_addr+=$(luckfox_get_pinctrl_addr "spi0m0-cs0") - - local fbtft_action=okay - elif [ "$action" == 0 ]; then - local fbtft_action=disabled - fi - - spi_device_name=$(luckfox_get_device_name "spi0") - - if [ "$action" == 1 ]; then - local fdt_content=" -/dts-v1/; -/plugin/; - -&{$spi_device_name}{ - status=\"$fbtft_action\"; - pinctrl-0 = <$spi_pinctrl_addr>; -}; - -&{$spi_device_name/fbtft@0}{ - status=\"$fbtft_action\"; - compatible=\"$fbtft_compatible\"; -}; - -&{$spi_device_name/spidev@0}{ - status=\"disabled\"; -}; -" - elif [ "$action" == 0 ]; then - local fdt_content=" -/dts-v1/; -/plugin/; - -&{$spi_device_name}{ - status=\"$fbtft_action\"; -}; - -&{$spi_device_name/fbtft@0}{ - status=\"$fbtft_action\"; -}; -" - fi - - # fdt overlay - # luckfox_fdt_overlay "$fdt_content - luckfox_dtbo_overlay "FBTFT" "$fdt_content" - - # update pin fun fbtft: miso_action = 0 cs_action = 1 - if [ "$action" == 1 ]; then - if [ "$pre_miso_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-miso")" 1 - fi - - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-cs0")" 0 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-clk")" 0 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-mosi")" 0 - elif [ "$action" == 0 ]; then - if [ "$pre_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-clk")" 1 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-mosi")" 1 - fi - - if [ "$pre_miso_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-miso")" 1 - fi - - if [ "$pre_cs_action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "spi${spi_main}m${spi_sub}-cs0")" 1 - fi - fi - - # update cfg - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico" ]; then - luckfox_set_pin_mark "GPIO1_A2" "$action" - luckfox_set_pin_mark "GPIO1_C0" "$action" - luckfox_set_pin_mark "GPIO1_C1" "$action" - luckfox_set_pin_mark "GPIO1_C2" "$action" - luckfox_set_pin_mark "GPIO1_C3" "$action" - luckfox_set_pin_mark "GPIO0_A4" "$action" - elif [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Pro" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Max" ]; then - luckfox_set_pin_mark "GPIO2_B1" "$action" - luckfox_set_pin_mark "GPIO1_C0" "$action" - luckfox_set_pin_mark "GPIO1_C1" "$action" - luckfox_set_pin_mark "GPIO1_C2" "$action" - luckfox_set_pin_mark "GPIO1_C3" "$action" - luckfox_set_pin_mark "GPIO2_B0" "$action" - fi - - luckfox_set_pin_cfg "FBTFT_ENABLE" "$action" - luckfox_set_pin_parameter "FBTFT_ENABLE" "$action" - #endregion -} - -function luckfox_sdmmc_app() { - #region - local action="$1" - local emmc_device_name - - local pre_action - pre_action=$(luckfox_get_pin_mode "$(luckfox_get_pinctrl_addr "sdmmc0-clk")") - - if [ "$action" == 1 ]; then - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ] && [ "$LUCKFOX_CHIP_MEDIA_CLASS" == "spi_nand" ]; then - luckfox_check_pin_diagram "GPIO3_A6" "GPIO3_A7" "GPIO3_A5" "GPIO3_A4" "GPIO3_A2" "GPIO3_A3" "GPIO3_A1" - fi - local emmc_action=okay - elif [ "$action" == 0 ]; then - local emmc_action=disabled - fi - - # device addr - emmc_device_name=$(luckfox_get_device_name "mmc1") - - local dtbo_content=" -/dts-v1/; -/plugin/; - -&{$emmc_device_name}{ - status=\"$emmc_action\"; -}; -" - # dtb overlay - luckfox_dtbo_overlay "sdmmc" "$dtbo_content" - if [ "$action" == 1 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "sdmmc0-clk")" 0 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "sdmmc0-cmd")" 0 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "sdmmc0-bus4")" 0 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "sdmmc0-det")" 0 - #elif [ "$action" == 0 ] && [ "$pre_action" == 1 ]; then - elif [ "$action" == 0 ]; then - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "sdmmc0-clk")" 1 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "sdmmc0-cmd")" 1 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "sdmmc0-bus4")" 1 - luckfox_set_pin_mode "$(luckfox_get_pinctrl_addr "sdmmc0-det")" 1 - fi - - # update cfg - luckfox_set_pin_cfg "SDMMC_ENABLE" "$action" - luckfox_set_pin_parameter "SDMMC_ENABLE" "$action" - - #mark - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Plus" ] && [ "$LUCKFOX_CHIP_MEDIA_CLASS" == "spi_nand" ]; then - luckfox_set_pin_mark "GPIO3_A6" "$action" - luckfox_set_pin_mark "GPIO3_A7" "$action" - luckfox_set_pin_mark "GPIO3_A5" "$action" - luckfox_set_pin_mark "GPIO3_A4" "$action" - luckfox_set_pin_mark "GPIO3_A2" "$action" - luckfox_set_pin_mark "GPIO3_A3" "$action" - luckfox_set_pin_mark "GPIO3_A1" "$action" - fi - #endregion -} - -# ---------------------- GUI Handler ---------------------- -function luckfox_result_handle() { - local status="$1" - local log="$2" - - if [ "$status" == $LF_OK ]; then - return - elif [ "$status" == $LF_ERR ]; then - if [ -n "$log" ]; then - if [ "$LF_GUI_ENABLE" == 1 ]; then - dialog --msgbox "$log" 10 30 - else - echo "[luckfox-config] error:${log}" - fi - else - if [ "$LF_GUI_ENABLE" == 1 ]; then - dialog --msgbox "error" 10 30 - else - echo "[luckfox-config] error" - fi - fi - exit - elif [ "$status" == $LF_NONE ]; then - if [ -n "$log" ]; then - if [ "$LF_GUI_ENABLE" == 1 ]; then - dialog --msgbox "Could not find $log" 10 30 - else - echo "[luckfox-config] error:Could not find ${log}" - fi - fi - exit - fi -} - -function luckfox_get_option_str() { - local search_param="$1" - local group=() - local right_group=() - local option_group=() - local option_str="" - - while IFS= read -r line; do - if [[ "$line" == *"| |"* && "$line" == *"$search_param"* ]]; then - group=() - right_group=() - - IFS='-' read -r -a group <<<"$(echo "$line" | cut -d'|' -f1)" - IFS='-' read -r -a right_group <<<"$(echo "$line" | cut -d'|' -f3)" - group+=("${right_group[@]}") - for pin in "${group[@]}"; do - if [ "$search_param" == "UART" ]; then - if [[ "$pin" == *"$search_param"*"_RX"* ]]; then - option_group+=$(echo "$pin" | sed -E 's/(UART[0-9]+_M[0-9]+)_.*$/\1 x /g') - fi - elif [ "$search_param" == "PWM" ]; then - if [[ "$pin" == *"$search_param"* ]]; then - option_group+=$(echo "$pin" | sed -E 's/(PWM[0-9]+_M[0-9]+).*$/\1 x /g') - fi - elif [ "$search_param" == "I2C" ]; then - if [[ "$pin" == *"$search_param"*"_SCL"* ]]; then - option_group+=$(echo "$pin" | sed -E 's/(I2C[0-9]+_M[0-9]+)_.*$/\1 x /g') - fi - elif [ "$search_param" == "SPI" ]; then - if [[ "$pin" == *"$search_param"*"_CLK"* ]]; then - option_group+=$(echo "$pin" | sed -E 's/(SPI[0-9]+_M[0-9]+)_.*$/\1 x /g') - fi - fi - done - fi - done <"$LUCKFOX_PIN_DIAGRAM_FILE" - - for element in "${option_group[@]}"; do - option_str+="$element" - done - - echo "$option_str" -} - -function luckfox_pico_show_pin_diagram() { - if [ -f $LUCKFOX_PIN_DIAGRAM_FILE ]; then - dialog --title "Luckfox Pin Diagram" --no-collapse --textbox $LUCKFOX_PIN_DIAGRAM_FILE 100 100 - else - luckfox_result_handle "$LF_NONE" "$LUCKFOX_PIN_DIAGRAM_FILE" - fi -} - -# ---------------------- Main GUI ------------------------- -function luckfox_show_menu() { - # Only support Luckfox Pico Ultra /Luckfox Pico Ultra W - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra W" ]; then - while true; do - option=$(dialog --title "$LUCKFOX_CHIP_MODEL Config" \ - --menu "Choose an option" 80 50 6 \ - 1 "Advanced Options" \ - 2 "About Luckfox" \ - 2>&1 >/dev/tty) - - case $option in - 1) luckfox_advanced_options ;; - 2) luckfox_about ;; - *) luckfox_exit ;; - esac - done - else - while true; do - option=$(dialog --title "$LUCKFOX_CHIP_MODEL Config" \ - --menu "Choose an option" 80 50 6 \ - 1 "Compatible Devices" \ - 2 "Advanced Options" \ - 3 "About Luckfox" \ - 2>&1 >/dev/tty) - - case $option in - 1) luckfox_compatible_devices ;; - 2) luckfox_advanced_options ;; - 3) luckfox_about ;; - *) luckfox_exit ;; - esac - done - fi -} - -function luckfox_compatible_devices() { - local action - - option=$(dialog --title "Compatible Devices" \ - --menu "Choose an option" 80 50 6 \ - 1 "Pico_LCD" \ - 2 "Pico_ePaper" \ - 3 "Pico_UPS_B" \ - 4 "Pico_ResTouch_LCD" \ - 5 "OLED_Module" \ - 6 "Pico_OLED" \ - 7 "DHT11" \ - 2>&1 >/dev/tty) - - case $option in - 1) device="Pico_LCD" ;; - 2) device="Pico_ePaper" ;; - 3) device="Pico_UPS_B" ;; - 4) device="Pico_ResTouch_LCD" ;; - 5) device="OLED_Module" ;; - 6) device="Pico_OLED" ;; - 7) device="DHT11" ;; - *) luckfox_show_menu ;; - esac - - action=$(dialog --menu "$device Startup Confirmation" 10 40 2 1 "Yes" \ - 0 "No" \ - 2>&1 >/dev/tty) - if [ -z "$action" ] || [ "$action" == 0 ]; then - luckfox_compatible_devices - fi - luckfox_compatible_app "$device" "$action" - echo "Change the compatible status of $device to $action." >>"$LUCKFOX_CHANGE_TXT" - -} - -function luckfox_advanced_options() { - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra W" ]; then - while true; do - option=$(dialog --title "Advanced Options" \ - --menu "Choose an option" 80 50 6 \ - 1 "PWM" \ - 2 "UART" \ - 3 "I2C" \ - 4 "SPI" \ - 5 "USB" \ - 6 "CSI" \ - 7 "RGB" \ - 8 "TouchScreen" \ - 2>&1 >/dev/tty) - - case $option in - 1) luckfox_PWM ;; - 2) luckfox_UART ;; - 3) luckfox_I2C ;; - 4) luckfox_SPI ;; - 5) luckfox_USB ;; - 6) luckfox_CSI ;; - 7) luckfox_RGB ;; - 8) luckfox_TS ;; - *) luckfox_show_menu ;; - esac - done - else - while true; do - option=$(dialog --title "Advanced Options" \ - --menu "Choose an option" 80 50 6 1 "PWM" \ - 2 "UART" \ - 3 "I2C" \ - 4 "SPI" \ - 5 "USB" \ - 6 "CSI" \ - 7 "FBTFT" \ - 8 "SDMMC" \ - 2>&1 >/dev/tty) - - case $option in - 1) luckfox_PWM ;; - 2) luckfox_UART ;; - 3) luckfox_I2C ;; - 4) luckfox_SPI ;; - 5) luckfox_USB ;; - 6) luckfox_CSI ;; - 7) luckfox_FBTFT ;; - 8) luckfox_SDMMC ;; - *) luckfox_show_menu ;; - esac - done - fi -} - -function luckfox_about() { - luckfox_pico_show_pin_diagram -} - -function luckfox_exit() { - luckfox_fdt_clear - - # echo Setting change - - clear - exit -} - -# ---------------------- Sub GUI ------------------------- -# Advanced Options -function luckfox_PWM() { - local pwm_enable pwm_main pwm_sub - local option pattern - - local pwm_option_str - pwm_option_str=$(luckfox_get_option_str "PWM") - - if [ -z "$pwm_option_str" ]; then - dialog --msgbox "No PWM Pins" 10 30 - fi - - option=$(dialog --title "PWM Config" \ - --menu "Choose an option" 100 30 10 $pwm_option_str 2>&1 >/dev/tty) - if [ -z "$option" ]; then - luckfox_advanced_options - fi - - pattern=".*PWM([0-9]+)_M([0-9]+).*" - if [[ $option =~ $pattern ]]; then - pwm_main="${BASH_REMATCH[1]}" - pwm_sub="${BASH_REMATCH[2]}" - fi - - pwm_enable=$(dialog --menu "PWM${pwm_main}_M${pwm_sub} Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$pwm_enable" ]; then - luckfox_advanced_options - else - luckfox_pwm_app "$pwm_enable" "$pwm_main" "$pwm_sub" - echo "Set PWM${pwm_main}_M${pwm_sub} enable status : $pwm_enable." >>"$LUCKFOX_CHANGE_TXT" - fi - luckfox_advanced_options -} - -function luckfox_UART() { - local uart_enable uart_main uart_sub - local option pattern - - local uart_option_str - uart_option_str=$(luckfox_get_option_str "UART") - - if [ -z "$uart_option_str" ]; then - dialog --msgbox "No UART Pins" 10 30 - fi - - option=$(dialog --title "UART Config" \ - --menu "Choose an option" 10 30 4 $uart_option_str 2>&1 >/dev/tty) - if [ -z "$option" ]; then - luckfox_advanced_options - fi - - pattern=".*UART([0-9]+)_M([0-9]+).*" - if [[ $option =~ $pattern ]]; then - uart_main="${BASH_REMATCH[1]}" - uart_sub="${BASH_REMATCH[2]}" - fi - - uart_enable=$(dialog --menu "UART${uart_main}_M${uart_sub} Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$uart_enable" ]; then - luckfox_advanced_options - else - luckfox_uart_app "$uart_enable" "$uart_main" "$uart_sub" - echo "Set UART${uart_main}_M${uart_sub} enable status : $uart_enable." >>"$LUCKFOX_CHANGE_TXT" - fi - luckfox_advanced_options -} - -function luckfox_I2C() { - local i2c_enable i2c_speed i2c_main i2c_sub - local option pattern - - local i2c_option_str - i2c_option_str=$(luckfox_get_option_str "I2C") - - if [ -z "$i2c_option_str" ]; then - dialog --msgbox "No I2C Pins" 10 30 - fi - - option=$(dialog --title "I2C Config" \ - --menu "Choose an option" 10 30 4 $i2c_option_str 2>&1 >/dev/tty) - if [ -z "$option" ]; then - luckfox_advanced_options - fi - - pattern=".*I2C([0-9]+)_M([0-9]+).*" - if [[ $option =~ $pattern ]]; then - i2c_main="${BASH_REMATCH[1]}" - i2c_sub="${BASH_REMATCH[2]}" - fi - - i2c_enable=$(dialog --menu "I2C${i2c_main}_M${i2c_sub} Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$i2c_enable" ]; then - luckfox_advanced_options - fi - - if [ "$i2c_enable" == 1 ]; then - i2c_speed=$(dialog --inputbox "I2C${i2c_main}_M${i2c_sub} Speed:" 10 30 2>&1 >/dev/tty) - if [ -z "$i2c_speed" ]; then - luckfox_advanced_options - fi - elif [ "$i2c_enable" == 0 ]; then - i2c_speed=0 # default - fi - - luckfox_i2c_app "$i2c_enable" "$i2c_main" "$i2c_sub" "$i2c_speed" - echo "Set I2C${i2c_main}_M${i2c_sub} enable status : $i2c_enable." >>"$LUCKFOX_CHANGE_TXT" - echo "Set I2C${i2c_main}_M${i2c_sub} speed : $i2c_speed." >>"$LUCKFOX_CHANGE_TXT" - luckfox_advanced_options -} - -function luckfox_SPI() { - local spi_enable spi_speed spi_main spi_sub spi_cs_enable spi_miso_enable - local option - - local spi_option_str - spi_option_str=$(luckfox_get_option_str "SPI") - - if [ -z "$spi_option_str" ]; then - dialog --msgbox "No SPI Pins" 10 30 - luckfox_advanced_options - fi - - option=$(dialog --title "SPI Config" \ - --menu "Choose an option" 10 30 4 $spi_option_str 2>&1 >/dev/tty) - if [ -z "$option" ]; then - luckfox_advanced_options - fi - - pattern=".*SPI([0-9]+)_M([0-9]+).*" - if [[ $option =~ $pattern ]]; then - spi_main="${BASH_REMATCH[1]}" - spi_sub="${BASH_REMATCH[2]}" - fi - - spi_enable=$(dialog --menu "SPI${spi_main}_M${spi_sub} Enable Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$spi_enable" ]; then - luckfox_advanced_options - fi - - if [ "$spi_enable" == 1 ]; then - spi_speed=$(dialog --inputbox "SPI${spi_main}_M${spi_sub} Speed:" 10 30 2>&1 >/dev/tty) - if [ -z "$spi_speed" ]; then - luckfox_advanced_options - fi - - spi_cs_enable=$(dialog --menu "SPI${spi_main}_M${spi_sub} CS0 Enable Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$spi_cs_enable" ]; then - luckfox_advanced_options - fi - - spi_miso_enable=$(dialog --menu "SPI${spi_main}_M${spi_sub} MISO Enable Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$spi_miso_enable" ]; then - luckfox_advanced_options - fi - elif [ "$spi_enable" == 0 ]; then - spi_speed=10000000 - spi_cs_enable=1 - spi_miso_enable=1 - fi - luckfox_spi_app "$spi_enable" "$spi_main" "$spi_sub" "$spi_cs_enable" "$spi_miso_enable" "$spi_speed" - echo "Set SPI${spi_main}_M${spi_sub} enable status : $spi_enable." >>"$LUCKFOX_CHANGE_TXT" - echo "Set SPI${spi_main}_M${spi_sub} cs-pin enable status : $spi_cs_enable." >>"$LUCKFOX_CHANGE_TXT" - echo "Set SPI${spi_main}_M${spi_sub} miso-pin enable status : $spi_miso_enable." >>"$LUCKFOX_CHANGE_TXT" - echo "Set SPI${spi_main}_M${spi_sub} speed : $spi_speed." >>"$LUCKFOX_CHANGE_TXT" - luckfox_advanced_options -} - -function luckfox_USB() { - while true; do - option=$(dialog --title "USB Mode Config" \ - --menu "Choose an option" 10 30 3 \ - 1 "device" \ - 2 "host" \ - 2>&1 >/dev/tty) - case $option in - 1) - luckfox_usb_app peripheral - echo "Set USB Mode : peripheral." >>"$LUCKFOX_CHANGE_TXT" - dialog --msgbox "USB Effective after restart" 10 30 - luckfox_advanced_options - ;; - 2) - luckfox_usb_app host - echo "Set USB Mode: host." >>"$LUCKFOX_CHANGE_TXT" - dialog --msgbox "USB Effective after restart" 10 30 - luckfox_advanced_options - ;; - *) luckfox_advanced_options ;; - esac - done - - luckfox_advanced_options -} - -function luckfox_CSI() { - local csi_enable - csi_enable=$(dialog --menu "CSI Enable Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$csi_enable" ]; then - luckfox_advanced_options - fi - luckfox_csi_app "$csi_enable" - dialog --msgbox "CSI Effective after restart" 10 30 - echo "Set CSI enable status : $csi_enable." >>"$LUCKFOX_CHANGE_TXT" - luckfox_advanced_options -} - -function luckfox_RGB() { - local rgb_enable rgb_mode_str - - rgb_enable=$(dialog --menu "RGB Enable Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$rgb_enable" ]; then - luckfox_advanced_options - fi - - if [ "$rgb_enable" == 1 ]; then - rgb_mode_str="reset" - - if [ -f "$LUCKFOX_RGB_PARAMS" ]; then - touch "$LUCKFOX_RGB_PARAMS" - fi - - # init params - init_rgb_clk=$(luckfox_get_pin_cfg "RGB_CLK") - init_rgb_h=$(luckfox_get_pin_cfg "RGB_HACTIVE") - init_rgb_v=$(luckfox_get_pin_cfg "RGB_VACTIVE") - init_rgb_hb=$(luckfox_get_pin_cfg "RGB_HBACKPORCH") - init_rgb_hf=$(luckfox_get_pin_cfg "RGB_HFRONTPORCH") - init_rgb_vb=$(luckfox_get_pin_cfg "RGB_VBACKPORCH") - init_rgb_vf=$(luckfox_get_pin_cfg "RGB_VFRONTPORCH") - init_rgb_h_len=$(luckfox_get_pin_cfg "RGB_HSYNC_LEN") - init_rgb_v_len=$(luckfox_get_pin_cfg "RGB_VSYNC_LEN") - init_rgb_h_active=$(luckfox_get_pin_cfg "RGB_HSYNC_ACTIVE") - init_rgb_v_active=$(luckfox_get_pin_cfg "RGB_VSYNC_ACTIVE") - init_rgb_de_active=$(luckfox_get_pin_cfg "RGB_DE_ACTIVE") - init_rgb_pclk_active=$(luckfox_get_pin_cfg "RGB_PCLK_ACTIVE") - - LUCKFOX_RGB_PARAMS=$(mktemp) - dialog --no-cancel --form "Enter RGB Parameters" 15 50 0 \ - "Clock :" 1 1 "$init_rgb_clk" 1 15 10 0 \ - "Hsync-Active:" 2 1 "$init_rgb_h_active" 2 15 10 0 \ - "Vsync-Active:" 3 1 "$init_rgb_v_active" 3 15 10 0 \ - "DE-Active :" 4 1 "$init_rgb_de_active" 4 15 10 0 \ - "PCLK-Active :" 5 1 "$init_rgb_pclk_active" 5 15 10 0 \ - 2>"$LUCKFOX_RGB_PARAMS" - IFS=$'\n' read -d '' -r rgb_clk rgb_h_active rgb_v_active rgb_de_active rgb_pclk_active <"$LUCKFOX_RGB_PARAMS" - rm -f "$LUCKFOX_RGB_PARAMS" - - LUCKFOX_RGB_PARAMS=$(mktemp) - dialog --no-cancel --form "Enter RGB Parameters" 15 50 0 \ - "Hactive :" 1 1 "$init_rgb_h" 1 15 10 0 \ - "Vactive :" 2 1 "$init_rgb_v" 2 15 10 0 \ - "HBack-Porch :" 3 1 "$init_rgb_hb" 3 15 10 0 \ - "HFont-Porch :" 4 1 "$init_rgb_hf" 4 15 10 0 \ - "VBack-Porch :" 5 1 "$init_rgb_vb" 5 15 10 0 \ - "VFont-Porch :" 6 1 "$init_rgb_vf" 6 15 10 0 \ - "Hsync-Len :" 7 1 "$init_rgb_h_len" 7 15 10 0 \ - "Vsync-Len :" 8 1 "$init_rgb_v_len" 8 15 10 0 \ - 2>"$LUCKFOX_RGB_PARAMS" - IFS=$'\n' read -d '' -r rgb_h rgb_v rgb_hb rgb_hf rgb_vb rgb_vf rgb_h_len rgb_v_len <"$LUCKFOX_RGB_PARAMS" - rm -f "$LUCKFOX_RGB_PARAMS" - - dialog --msgbox "All parameters are valid." 15 50 - - luckfox_rgb_app 1 "$rgb_mode_str" "$rgb_clk" \ - "$rgb_h" "$rgb_v" \ - "$rgb_hb" "$rgb_hf" \ - "$rgb_vb" "$rgb_vf" \ - "$rgb_h_len" "$rgb_v_len" \ - "$rgb_h_active" "$rgb_v_active" \ - "$rgb_de_active" "$rgb_pclk_active" - echo "Set RGB enable status : $rgb_enable." >>"$LUCKFOX_CHANGE_TXT" - else - luckfox_rgb_app 0 - echo "Set RGB enable status : $rgb_enable." >>"$LUCKFOX_CHANGE_TXT" - fi - - dialog --msgbox "RGB Effective after restart" 10 30 - luckfox_advanced_options -} - -function luckfox_TS() { - local ts_enable ts_mode ts_reg_hex - - ts_enable=$(dialog --menu "TouchScreen Enable Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$ts_enable" ]; then - luckfox_advanced_options - fi - - if [ "$ts_enable" == 1 ]; then - ts_mode=$(dialog --menu "Touch GT911 Enable Config" 10 40 2 \ - 0 "i2c_addr: 0x14" \ - 1 "i2c_addr: 0x5d" \ - 2>&1 >/dev/tty) - if [ -z "$ts_mode" ]; then - luckfox_advanced_options - elif [ "$ts_mode" == 0 ]; then - ts_reg_hex="0x14" - elif [ "$ts_mode" == 1 ]; then - ts_reg_hex="0x5d" - fi - fi - - luckfox_ts_app "$ts_enable" "$ts_reg_hex" - echo "Set TouchScreen enable status : $ts_enable." >>"$LUCKFOX_CHANGE_TXT" - echo "Set TouchScreen Reg : $ts_reg_hex." >>"$LUCKFOX_CHANGE_TXT" - luckfox_advanced_options -} - -function luckfox_FBTFT() { - local fbtft_enable - fbtft_enable=$(dialog --menu "FBTFT Enable Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$fbtft_enable" ]; then - luckfox_advanced_options - fi - - if [ "$fbtft_enable" == 1 ]; then - fbtft_mode=$(dialog --menu "FBTFT MODE Config" 10 40 2 \ - 0 "st7789v/st7789vm" \ - 2>&1 >/dev/tty) - if [ -z "$fbtft_mode" ]; then - luckfox_advanced_options - elif [ "$fbtft_mode" == 0 ]; then - fbtft_compatible="sitronix,st7789v" - fi - fi - - luckfox_fbtft_app "$fbtft_enable" "$fbtft_compatible" - dialog --msgbox "FBTFT Effective after restart" 10 30 - - echo "Set FBTFT enable status : $fbtft_enable." >>"$LUCKFOX_CHANGE_TXT" - echo "Set FBTFT compatible : $fbtft_compatible." >>"$LUCKFOX_CHANGE_TXT" - luckfox_advanced_options -} - -function luckfox_SDMMC() { - local sdmmc_enable - if [ "$LUCKFOX_CHIP_MEDIA_CLASS" != "spi_nand" ]; then - dialog --title "SDMMC Config" --msgbox "Only spi_nand storage media support SDMMC Config" 10 30 - luckfox_advanced_options - fi - - sdmmc_enable=$(dialog --menu "SDMMC Enable Config" 10 40 2 \ - 0 "disable" \ - 1 "enable" \ - 2>&1 >/dev/tty) - if [ -z "$sdmmc_enable" ]; then - luckfox_advanced_options - fi - luckfox_sdmmc_app "$sdmmc_enable" - echo "Set SDMMC enable status : $sdmmc_enable." >>"$LUCKFOX_CHANGE_TXT" - luckfox_advanced_options -} - -# ---------------------- RUN ------------------------- -if [ "$1" == "load" ]; then - LF_GUI_ENABLE=0 - if [ -f $LUCKFOX_PIN_DIAGRAM_FILE ]; then - rm $LUCKFOX_PIN_DIAGRAM_FILE - fi - luckfox_config_init - luckfox_load_cfg - echo "Complete configuration loading" -elif [ "$1" == "show" ]; then - luckfox_config_init - cat $LUCKFOX_PIN_DIAGRAM_FILE -elif [ "$1" == "update" ]; then - luckfox_update_fdt -elif [ "$1" == "rgb_switch" ]; then - # for Luckfox Pico Ultra Boot Key - luckfox_config_init - LF_GUI_ENABLE=0 - if [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra" ] || [ "$LUCKFOX_CHIP_MODEL" == "Luckfox Pico Ultra W" ]; then - if [ "$(luckfox_get_pin_cfg "RGB_HACTIVE")" == "480" ]; then - # 480 -> 720 - echo "****************************************************" - echo "***Switch the RGB screen resolution to 720 x 720.***" - echo "****************************************************" - luckfox_csi_app 1 - luckfox_rgb_app 1 "reset" "30000000" \ - "720" "720" \ - "44" "46" \ - "18" "16" \ - "2" "2" \ - "0" "0" \ - "0" "1" - elif [ "$(luckfox_get_pin_cfg "RGB_HACTIVE")" == "720" ]; then - # 720 -> 480 - echo "****************************************************" - echo "***Switch the RGB screen resolution to 480 x 480.***" - echo "****************************************************" - luckfox_csi_app 1 - luckfox_rgb_app 1 "reset" "16500000" \ - "480" "480" \ - "10" "50" \ - "8" "8" \ - "4" "10" \ - "0" "0" \ - "0" "1" - elif [ -z "$(luckfox_get_pin_cfg "RGB_HACTIVE")" ]; then - echo "****************************************************" - echo "***Switch the RGB screen resolution to 480 x 480.***" - echo "****************************************************" - luckfox_csi_app 1 - luckfox_rgb_app 1 "reset" "16500000" \ - "480" "480" \ - "10" "50" \ - "8" "8" \ - "4" "10" \ - "0" "0" \ - "0" "1" - fi - else - luckfox_result_handle "$RK_ERR" "This Luckchip Pico Model does not support RGB switch." - fi -elif [ -z "$1" ]; then - LF_GUI_ENABLE=1 - luckfox_config_init - luckfox_show_menu -fi diff --git a/sysdrv/tools/board/luckfox_config/luckfox_switch_rgb_resolution b/sysdrv/tools/board/luckfox_config/luckfox_switch_rgb_resolution deleted file mode 100755 index e546bec13..000000000 Binary files a/sysdrv/tools/board/luckfox_config/luckfox_switch_rgb_resolution and /dev/null differ diff --git a/sysdrv/tools/board/luckfox_config/luckfox_switch_rgb_resolution.c b/sysdrv/tools/board/luckfox_config/luckfox_switch_rgb_resolution.c deleted file mode 100644 index 243b54f59..000000000 --- a/sysdrv/tools/board/luckfox_config/luckfox_switch_rgb_resolution.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#define INPUT_DIR "/dev/input" -#define EVENT_PREFIX "event" - -void check_adc_keys_event(const char *device_path) { - int fd; - char name[256] = "Unknown"; - struct input_event ev; - - fd = open(device_path, O_RDONLY); - if (fd < 0) { - perror("Unable to open device"); - return; - } - - if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0) { - perror("Unable to get device name"); - close(fd); - return; - } - - if (strstr(name, "adc-keys") != NULL) { - printf("Found ADC keys device: %s\n", device_path); - - while (read(fd, &ev, sizeof(struct input_event)) > 0) { - if (ev.type == EV_KEY) { - if (ev.value == 0) { - printf("Key released: code %d\n", ev.code); - system("luckfox-config rgb_switch"); - system("reboot"); - } - } - } - } - - close(fd); -} - -int main() { - struct dirent *entry; - DIR *dp; - - - dp = opendir(INPUT_DIR); - if (dp == NULL) { - perror("Unable to open /dev/input directory"); - return EXIT_FAILURE; - } - - while ((entry = readdir(dp))) { - if (strncmp(entry->d_name, EVENT_PREFIX, strlen(EVENT_PREFIX)) == 0) { - char device_path[256]; - snprintf(device_path, sizeof(device_path), "%s/%s", INPUT_DIR, entry->d_name); - check_adc_keys_event(device_path); - } - } - - closedir(dp); - return EXIT_SUCCESS; -} - diff --git a/sysdrv/tools/board/luckfox_config/ubuntu/etc/rc.local b/sysdrv/tools/board/luckfox_config/ubuntu/etc/rc.local deleted file mode 100644 index bfe81100c..000000000 --- a/sysdrv/tools/board/luckfox_config/ubuntu/etc/rc.local +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -/usr/bin/filesystem_resize.sh -/etc/init.d/S50usbdevice start -luckfox-config load -if [ -n "$(hwclock | grep "invalid")" ]; then - date -s 2024-01-01 - hwclock -w -fi diff --git a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/dtc b/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/dtc deleted file mode 100755 index 644924741..000000000 Binary files a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/dtc and /dev/null differ diff --git a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtdump b/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtdump deleted file mode 100755 index dd7141557..000000000 Binary files a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtdump and /dev/null differ diff --git a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtget b/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtget deleted file mode 100755 index 3dadd7618..000000000 Binary files a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtget and /dev/null differ diff --git a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtoverlay b/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtoverlay deleted file mode 100755 index 7ffda3733..000000000 Binary files a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtoverlay and /dev/null differ diff --git a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtput b/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtput deleted file mode 100755 index 63f0d1e42..000000000 Binary files a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/fdtput and /dev/null differ diff --git a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/iomux b/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/iomux deleted file mode 100755 index c41e4883c..000000000 Binary files a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/iomux and /dev/null differ diff --git a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/luckfox_switch_rgb_resolution b/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/luckfox_switch_rgb_resolution deleted file mode 100755 index cc8577b96..000000000 Binary files a/sysdrv/tools/board/luckfox_config/ubuntu/usr/bin/luckfox_switch_rgb_resolution and /dev/null differ diff --git a/sysdrv/tools/board/luckfox_config/ubuntu/usr/lib/libfdt.so.1 b/sysdrv/tools/board/luckfox_config/ubuntu/usr/lib/libfdt.so.1 deleted file mode 120000 index a96f5be58..000000000 --- a/sysdrv/tools/board/luckfox_config/ubuntu/usr/lib/libfdt.so.1 +++ /dev/null @@ -1 +0,0 @@ -libfdt.so.1.7.0 \ No newline at end of file diff --git a/sysdrv/tools/board/luckfox_config/ubuntu/usr/lib/libfdt.so.1.7.0 b/sysdrv/tools/board/luckfox_config/ubuntu/usr/lib/libfdt.so.1.7.0 deleted file mode 100755 index bdbcc2d01..000000000 Binary files a/sysdrv/tools/board/luckfox_config/ubuntu/usr/lib/libfdt.so.1.7.0 and /dev/null differ diff --git a/sysdrv/tools/board/uboot/0001-uboot-compatible-luckfox.patch b/sysdrv/tools/board/uboot/0001-uboot-compatible-luckfox.patch deleted file mode 100644 index 9b2ee7ce3..000000000 --- a/sysdrv/tools/board/uboot/0001-uboot-compatible-luckfox.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 816477167f7fec38674690a576a9f17100707441 Mon Sep 17 00:00:00 2001 -From: luckfox-eng29 -Date: Wed, 21 Aug 2024 14:35:48 +0800 -Subject: [PATCH] uboot compatible luckfox - ---- - .../arm/include/asm/arch-rockchip/boot_mode.h | 2 ++ - .../u-boot/arch/arm/mach-rockchip/boot_mode.c | 19 +++++++++++++++---- - sysdrv/source/uboot/u-boot/common/autoboot.c | 3 ++- - sysdrv/source/uboot/u-boot/common/image-fit.c | 14 +++++++++++--- - sysdrv/source/uboot/u-boot/drivers/mmc/mmc.c | 5 +++++ - .../source/uboot/u-boot/include/boot_rkimg.h | 3 ++- - 6 files changed, 37 insertions(+), 9 deletions(-) - -diff --git a/sysdrv/source/uboot/u-boot/arch/arm/include/asm/arch-rockchip/boot_mode.h b/sysdrv/source/uboot/u-boot/arch/arm/include/asm/arch-rockchip/boot_mode.h -index 063fd6b47..a34ec828f 100644 ---- a/sysdrv/source/uboot/u-boot/arch/arm/include/asm/arch-rockchip/boot_mode.h -+++ b/sysdrv/source/uboot/u-boot/arch/arm/include/asm/arch-rockchip/boot_mode.h -@@ -28,6 +28,8 @@ - /* enter bootrom download mode */ - #define BOOT_BROM_DOWNLOAD 0xEF08A53C - -+#define BOOT_TO_UBOOT (REBOOT_FLAG + 16) -+ - #ifndef __ASSEMBLY__ - int setup_boot_mode(void); - #endif -diff --git a/sysdrv/source/uboot/u-boot/arch/arm/mach-rockchip/boot_mode.c b/sysdrv/source/uboot/u-boot/arch/arm/mach-rockchip/boot_mode.c -index 6f4858bba..cd8b65f25 100644 ---- a/sysdrv/source/uboot/u-boot/arch/arm/mach-rockchip/boot_mode.c -+++ b/sysdrv/source/uboot/u-boot/arch/arm/mach-rockchip/boot_mode.c -@@ -194,7 +194,7 @@ int rockchip_get_boot_mode(void) - boot_mode[PL] = BOOT_MODE_CHARGING; - clear_boot_reg = 1; - break; -- case BOOT_PANIC: -+ case BOOT_PANIC: - printf("boot mode: panic\n"); - boot_mode[PL] = BOOT_MODE_PANIC; - break; -@@ -203,9 +203,14 @@ int rockchip_get_boot_mode(void) - boot_mode[PL] = BOOT_MODE_WATCHDOG; - break; - case BOOT_QUIESCENT: -- printf("boot mode: quiescent\n"); -- boot_mode[PL] = BOOT_MODE_QUIESCENT; -- break; -+ printf("boot mode: quiescent\n"); -+ boot_mode[PL] = BOOT_MODE_QUIESCENT; -+ break; -+ case BOOT_TO_UBOOT: -+ printf("boot mode: uboot\n"); -+ boot_mode[PL] = BOOT_MODE_UBOOT_TERMINAL; -+ clear_boot_reg = 1; -+ break; - default: - printf("boot mode: None\n"); - boot_mode[PL] = BOOT_MODE_UNDEFINE; -@@ -231,6 +236,8 @@ int setup_boot_mode(void) - { - char env_preboot[256] = {0}; - -+ env_set("cli", NULL); /* removed by default */ -+ - switch (rockchip_get_boot_mode()) { - case BOOT_MODE_BOOTLOADER: - printf("enter fastboot!\n"); -@@ -263,6 +270,10 @@ int setup_boot_mode(void) - printf("enter charging!\n"); - env_set("preboot", "setenv preboot; charge"); - break; -+ case BOOT_MODE_UBOOT_TERMINAL: -+ printf("enter uboot!\n"); -+ env_set("cli", "yes"); -+ break; - } - - return 0; -diff --git a/sysdrv/source/uboot/u-boot/common/autoboot.c b/sysdrv/source/uboot/u-boot/common/autoboot.c -index c64d566d1..9cf947b98 100644 ---- a/sysdrv/source/uboot/u-boot/common/autoboot.c -+++ b/sysdrv/source/uboot/u-boot/common/autoboot.c -@@ -220,7 +220,8 @@ static int __abortboot(int bootdelay) - #endif - - #ifdef CONFIG_ARCH_ROCKCHIP -- if (!IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI) && ctrlc()) { /* we press ctrl+c ? */ -+// if (!IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI) && ctrlc()) { /* we press ctrl+c ? */ -+ if ((!IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI) && ctrlc()) || env_get("cli")) { /* we press ctrl+c ? */ - #else - /* - * Check if key already pressed -diff --git a/sysdrv/source/uboot/u-boot/common/image-fit.c b/sysdrv/source/uboot/u-boot/common/image-fit.c -index 0ee9eab69..632551b88 100644 ---- a/sysdrv/source/uboot/u-boot/common/image-fit.c -+++ b/sysdrv/source/uboot/u-boot/common/image-fit.c -@@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR; - #include - #include - -+#define FDT_DEFAULT_LOAD_ADDR 0x00c00000 - #define __round_mask(x, y) ((__typeof__(x))((y)-1)) - #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) - -@@ -2140,7 +2141,13 @@ int fit_image_load_index(bootm_headers_t *images, ulong addr, - ret = fit_image_select(fit, noffset, images->verify); - if (ret) { - bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH); -- return ret; -+ /* Use the memory fdt directly */ -+ printf(" Use the memory fdt directly\n"); -+ *datap = FDT_DEFAULT_LOAD_ADDR; -+ fit_image_get_data_size(fit, noffset, (int *)&size); -+ *lenp = (ulong)size; -+ return noffset; -+ //return ret; - } - - bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH); -@@ -2175,7 +2182,6 @@ int fit_image_load_index(bootm_headers_t *images, ulong addr, - fit_image_check_os(fit, noffset, IH_OS_ARM_TRUSTED_FIRMWARE) || - fit_image_check_os(fit, noffset, IH_OS_OP_TEE) || - fit_image_check_os(fit, noffset, IH_OS_U_BOOT) || -- fit_image_check_os(fit, noffset, IH_OS_QNX) || - fit_image_check_os(fit, noffset, IH_OS_OPENRTOS); - - /* -@@ -2261,8 +2267,10 @@ int fit_image_load_index(bootm_headers_t *images, ulong addr, - return -EXDEV; - } - -+ //printf(" Loading %s from 0x%08lx to 0x%08lx\n", -+ // prop_name, data, load); - printf(" Loading %s from 0x%08lx to 0x%08lx\n", -- prop_name, data, load); -+ prop_name, image_start, load); - - dst = map_sysmem(load, len); - memmove(dst, buf, len); -diff --git a/sysdrv/source/uboot/u-boot/drivers/mmc/mmc.c b/sysdrv/source/uboot/u-boot/drivers/mmc/mmc.c -index 59805d33a..d352b00a3 100644 ---- a/sysdrv/source/uboot/u-boot/drivers/mmc/mmc.c -+++ b/sysdrv/source/uboot/u-boot/drivers/mmc/mmc.c -@@ -2288,6 +2288,11 @@ int mmc_start_init(struct mmc *mmc) - - /* Test for SD version 2 */ - err = mmc_send_if_cond(mmc); -+ if (err) { -+ mmc_go_idle(mmc); -+ mmc_get_blk_desc(mmc)->hwpart = 0; -+ mmc_send_if_cond(mmc); -+ } - - /* Now try to get the SD card's operating condition */ - err = sd_send_op_cond(mmc); -diff --git a/sysdrv/source/uboot/u-boot/include/boot_rkimg.h b/sysdrv/source/uboot/u-boot/include/boot_rkimg.h -index 9cb709703..fc8356704 100644 ---- a/sysdrv/source/uboot/u-boot/include/boot_rkimg.h -+++ b/sysdrv/source/uboot/u-boot/include/boot_rkimg.h -@@ -20,7 +20,8 @@ enum _boot_mode { - BOOT_MODE_WATCHDOG, - BOOT_MODE_DFU, - BOOT_MODE_QUIESCENT, -- BOOT_MODE_UNDEFINE, -+ BOOT_MODE_UBOOT_TERMINAL, -+ BOOT_MODE_UNDEFINE, - }; - - struct bootloader_message { --- -2.34.1 - diff --git a/sysdrv/tools/board/uboot/0002-add-115200baudrate-rkbin.patch b/sysdrv/tools/board/uboot/0002-add-115200baudrate-rkbin.patch deleted file mode 100644 index 227b2e17f..000000000 --- a/sysdrv/tools/board/uboot/0002-add-115200baudrate-rkbin.patch +++ /dev/null @@ -1,622 +0,0 @@ -From 8a7f8dcc33ffb580540df5e1dd02b3d3572cb6ee Mon Sep 17 00:00:00 2001 -From: luckfox-eng29 -Date: Wed, 25 Sep 2024 18:49:11 +0800 -Subject: [PATCH] patch for 115200 bin - -Signed-off-by: luckfox-eng29 ---- - ...rv1106_ddr_924MHz_1500000Baud_tb_v1.15.bin | Bin 0 -> 22632 bytes - .../rv1106_ddr_924MHz_1500000Baud_v1.15.bin | Bin 0 -> 22632 bytes - .../bin/rv11/rv1106_ddr_924MHz_tb_v1.15.bin | Bin 22632 -> 22632 bytes - 3 files changed, 0 insertions(+), 0 deletions(-) - create mode 100644 sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_tb_v1.15.bin - create mode 100644 sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_v1.15.bin - -diff --git a/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_tb_v1.15.bin b/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_tb_v1.15.bin -new file mode 100644 -index 0000000000000000000000000000000000000000..95767c2f7a73114dae8356f9ebbca6a10689ecee -GIT binary patch -literal 22632 -zcmd743w%>WzBoQ}&Pj5TrfvEF`T%;8w9qy@(gu|0k|yD_G+?0hfvDG%7B~THD@8^0 -zZc~c8y0||cMa9-f1>NiFRVk0VRu_XjTwi-{BH*?@tEiDw*ONZTXFtDH_J$7`LMV+2D}I>DY+nr8pnpH^Dlo@W2TpVA&zswA8zV@AYLUA`_XbJ&27CF=9;fAdWp2qu-pPmY$@|%4G(jMZuhN^dS@C49+>n@B-S4Ia>T`DCj43 -z<{U#FhF%z%enE89=k7k3$g_J;&qcR85B2oAt!Zup>iNNq`kl2!0VEqIVwqX=yHP$8 -zzj9ky++=5|CM165#w}EHitTVesz*J4ao@32FVIcEZL8j?7Z{SNBq>=F^h8fma*|3R -zDFvk5wBCtZ93qo+`*i>>G}tIE4r<}FTkW4q2ir27=}y&dT6}2e=2E~melE2>qj6H) -z=h71Z{pHXNrD5&{d!bXg=RFA--<1$T+&l1mOG55Q=-!Cxab6*UIs};9lG0373e=C)a7L8P=EFdrYv>lb*$U&Z1}GQ{)54HkWh^Iaku_Uk -zJh7a-MNV=lv7Dks0Xa7v%NhBkgU7xVcNW-5|IB*QL(;z#=k(GPC#9QiPjjwvx^>OY -z2Hi)_SRW=wQ0_6`RC{h|rjRVq-IQMaf=(J|%#60tO4=}98KWX1=TYu+zDf2>;bd<^ -zGM)dlw?+Qs*^E*=8)m(eP*n*r)$*dHzHiAZ?7n%t`u9k@R{AZO2iLshM;`X=`4J8+ -zjHIuk%-eSTb` -zfw}$7zq|!&L}A}&VZ0@6ayxB%#eh2ytP`dLW=gBFh=FPd?K7iy=j7Md+fyp>KFtc%oHHc73vNh}0L -zJ=JcqsSICqOesBcD>8iQeH#5se*{K%2zoTHW36)v|1UwcvWVv;c77>u4$2*N6*btz?$WeiG7gvSyeoqcqzBG$1>U%noDGSYRxS&(UY!gtUow?*NN3WOdF0$X_H5Am=6B2K{={)^vdVS>iU(Vy8sXf0CR~enwiop)y*Y1F&O~ -z6UyI_ra<}+5+~5&Ny#Ko^FbPS>HzkVq<6(e_Xnv^NYs*fD~nXR2(?~pqtc4HF`b-d -zFM5>a1C4h-&5nmUO_DL*98ef(@kuGA1Xf%TNRC(0bkRFqUe7uL*U0Z+?@licB8A^S -z9p=!56&oWzKD=bO?F~xey8<%z;pQRL#ry@jUEJiN_B`LOX|L@Ya=5 -zA+P0g`D5SKnj@hc5ArMkT%0EzRq*ns#_M+x%wob8*cPfNDeE(z|j8ovCGU1QrSymim<*CkMLAgi~ -zP8hx}z%Z%KUkmi2G!LGt2+J=*YY9~L2?=%mNw9?#7ZcOpF!O-~IS$Gbpgq@uB6{k> -z&<@nTm>rNavatGMs`IW%69sixCS?a$W}&GhaW^NvKstKYM7F -zH5Jm6g(`{x_$=#0=R;6J<>it+WI7H;3Lf-O3;6&hw8Z0`HWzt2&MvS5Mde4#q!(zq -zS$x*5?L!qw&U8WB=PpWjVj&e;fmI4nq$OBbm?$t&h`WeD(w#-13uDzZtendPm1-u) -zDj1+94y%WfgrxzDlbpX2=wAQ_rpUvJP;mgODJ^i|_*+6zSRPuN_6Kt@&}D*C?s5bc -zs|$+MK^gmud9Ib7stU8P!V@lP19E5u`V>&&bZ3Jre(qc|2KpxnMS%n;X>d&z;^)5E -z>&7_D1`D81Z@PkQNdhzLU(DJl{nbH6kuIo!JGxmE7#U>(jw`Xt*4A=8;;!#WE1s3=uAl>*T+GC|IzdMG`u -zZzOe!DSg;a>YWsDf#xXErQ5Jxv6O~7$xb!YdB#G+TUs)JJ9@eTaYWA`_&X+JgYl@W -z1Nv*=eWb*AOp#aQmCc1+0HBm%zHhq==U9XWA$dWnO>L6_CAn!S9m@P!9x8hpFB9-| -zL+2@1k}Y|z)`qjmeB<(xp*+{4=g;|%^t7rAvgKu=_O5NXMXA -zPuqp2B3S*4h(5ZD65ks(3HHUt<}FBv~Imrz)9G|9HjrCge1 -zqoZ_2IzqJ+kUnujW+tJTHA*uKRF2UN`s85vlR`XiYTxEM?b^Q@abK^7mUk)y6;Ct? -z^$<0aNclXUoX_WRR0>c-1oF95)rxYkUKYekGk-Hrhm}1@Pl+t*(8=QXB -z>O7|73mCU_3>RMTuSz=(YgrMddd4qLUb)GfZ=rmYFwXM57tg)mN7@U~`6nLD;v3hG -z=TEF3XSm)+=TGoiHXQ1IyS}>9+%qnFzhxuD%@9|29_lZtzXNj5&Dw9-0CB!;zh$2% -zRUhYsytZE;>3;1uYg -zAAnOpSL;Pg(`)JKMv;QJwwRnhWPAdT4A=Sg_di@-)boF|sq=RL-@KBhsOaL-6~D1K -z#3FpEm$q&9?C*cQOf&D3--6xp?h0Ie`Sl*43n10n}s=F~oc5{v> -z-LN=-EAWctk{%sDRC^2|@u+0fErU~qK8sg({rjyagIQ{9no`6W;$Q9Vz -zY!N>(OYHsJ6g2gaMg8fH+ujN;QsZm%MdleanMYxDZ*hQDh(6FT?>CRZazwF~{|Ji~ -z@GN#39gu;gLqVG*_55Q#5#%AU8N@Nx0IpO~aaQAz6l;>zt5YreHb36umA*A^U)i{P -znwj;etyGYqSkG~QiTOYHFlYQDB|h>xsSkKuw2g{AhmwHO-)hKg`}OP6Q5k=o{Z~Ts -zR=Rr|{gKf4Tf$X^;U=FWue$T@yqeCZ@@hN3htSslRDBIR|5{&t#@zF7rpIC4W9E)d -zJ)i56_q(rg^qH>(4sLRY99LV#41!*6P2<`I#o)Ci<^XLkV*nzgyg -z+!L5pS5>$17FpprgG*m}QgZ90V^8Ichkj0o_LDsST0b88d9VKQ=)Oq$n+*G7kM(hj -z2I7r%Px+Z_IqZx~Hlu&iPk{}B${z6JY_N7@gN)Cn^?P8~+y(RJ4L@EW_o+(EJ^!3U -zP85`Ad5uu-+wdR#nj7HEjw1Cp6TJvUk}#r?0BI_h@xe*tKGfZaz+RI}`IwT%`$B$A -zJ5@s8-y7A)NL}`5By=I7X+y&C-Z;b_Gq+997f31GHVg9shLfA*+jpq8IMML7hc&_K -zM#Q$b)J+tU-c)wJ!Ckb|xHzJB=<*pK*q+f+J*`3&ENn3<% -zR_x-UB`-#lE!%lC4T(23;O3^qNGxw4r+6eTZD6`f7%lZIoYmU~`+}tPk_I#biHjTL -z-HWN&wq)wiV1JKnAHm=Ctr0l_O7l7C?Jjdb>4cer62z`wK&-b066n*?+s5COoRi)+ -zE(s{}=m4UZ1ZaT1Z#*ZRG9tjHT1Xw5JUKp}XKLuppr -zf()erm7d6Iq_zg$EI%hP$>xAsy|V<1T?It}H9ifHa}r9%u!Eh37%)=Cl%+sf%19Zc -zpEbhX2)%h0dh;yoKe4pDMPcB4uLb3alYDebmLbDOwVZ5cS{!|iMW0Kb?9SzHw&Fdz -z2M2<02HiLkN*X3*(^e2Tfw~JKp{c{TIqUVa(svq5kEU*wRV&tGkT&IIDvoa^5{KRq -zl{O%gK;op%+vh0~&G^t@Z;#4~^rv9YJSBa{MMAe-{&^Lj&A`9 -za%ZJajAn7WTQBl-CX=at75IU@R*-y?+X`pYc34FljdUCjt?2=mOI9Z{Db`a^D~?DU -zMjwO{^Wlqwa)vSq(t{Eu9LmW?32B2 -z`^nzpR^0U1H`LypIe4!_^eE?YSLS+dbgrkB?*1mNbmuo(%4R$I4bbDxBjma1*f;hW -zdp%Z>p^1!s$WPDI`t*J2b*~0>iF%*{%pPuvF?=xGrk0U -z+kE53NLN<`LOs%uG^}T{B@yZSx+-4{8lesOPqcC4E4mp}hZS&^`*WiybDiC9jHX&E -zdH;fF%3W9F-$HuVhw7|-?#g-oD9v{g{eByt^!9^by8_A&P7xaUvl7|^q42F-T$N5X7@3m> -zmN*4?I4H4BIxB6ybAo70?D19#H}fBXyz9Mh{U}(S -zlcG3{k?;I3wf89Kb1D^{N9V_N)Uxs3jA)we#5%SFX|Y%v>Ga3J2`2=5Ejj-n&rH~t -zuZ6G(f*rzbcCwo`@V5#N9Gtv?*qG=0A~}ve`Br&w7LA+EN)H<`2h@l41SwIB7$}FB -zknj=c7_v%~^RboMLpODT@8CsCP6rwFoxZcuL8wD!&nZX|YH~oO^BZArC_i5nr9H%0 -zd^a)*laaNwQyygL`Wy`Y8`ahme&WADYE}2*WV(B?LT5`Dl+`5(b9m}0eC=bB;-ET+ -z)dl810)L7EaatPcCON5o_okcgZIYOSjsPwK_=e7V>8I>q|7eor2ML}<8k%_X)+UL) -zg0VGLt{N$qChn5ZL1{~w)Hl%)K%6-Mryj6YB~QvHPY(%Is9^YT_}(BXmg9tkhmy!aWrno -zwVoOK)@h!TI%qN4T2arh3pQ9uJ3B0^I-$)wiN=q#>#gM_kh|-1X=wx1<1h4rt#45Q -zk$7Gy_xK{yLrPqDqIU^}3tE)3`9ubrlycC7=+7l?x1w)YfyLpXZ)*;M?q294b{xCz -zPkxu~wBM~e>5uho{7BzYuj*Uk2V?0m4J>BcHj$A(?_Z_+oxfW5tiM&a-@l4$)ot-t -z6S{2L45wq6{&)U^VC%^B(j8T~sa|&WamYVde~tHG|E~Iw@0{dD;0s1+)@R!}aoEiD -z4Wl_$)*9ahC9UuF#+g+CR&{W2NGuIdDrEqHutQSe1L^o0c1BuVukQ++ -zofQf75Bx@Aky4ME=JAFR?Ct@TgyRhSpJ5fmTEMd-p)SA#J!87h7d>h1WM`d@_9>w> -zMJN+iwtXNytO08!*c2buATg0j-vBn$%G%)>3y*h}d#m(WD^(3dZP4+XH3@t-fGLOgzPUP;35 -zarSV?6kf2ms7Ic%uxUL{X>+;Z&~`}%TEI-NuH*rz**2stS@8Q`>>UnG4iAUEi|}NZ -zYmn{vo!S!<&?rtSp(vXE?FAXy~n|F1{RW41~625dRVUX*WT<`S`-f -zLa_T&_U5fXW6;Nuhv?p#qlrtI?jkx>N;1bUxn;`=DO=;{dw=t)$#8l}InckaZlbW= -z!gK(v77bDw@Knw_(EolN%J2CE>3aRiAVbXXjz;2Ba!lZB#37xWhxP7$;9#>8_NrvK -zEx|uj?GQ`T;Z!s(5-J%mxf~*!OmQbA)Z8n;bJaoXx~t)5rH#Ap5`GW1 -zCTz&%pYR;F!^$!~Q@wu+ut{XUCy&q;Z5%5`6JdeS*$a`e;6J%*Vv}13 -zzSUF@&Y^M~OR{xmrL7?OMTev-#l&J0iKWd>BIQurllReQKST{&65o{j2 -z7gIr0ejo^XTi_&3tky2y`Rej^@WdKZ`pmbJ8fX^mHg#`9Oh#4UqRD{J>!(UW`^$GUem%=F5EY5AfaJqZ}#79iS$#H!ytvo(LFAdIB5qcrDahpZf -zL8$aw@HePT8~oVB8oGT;{3xf!4}N9}&%@x6psipdFWd$v;D!bjDn<8$Z}CA`(~m>^ -z0<6I!5DvJ$bTwIadA|@~thzW`g}~0&!QK{Udq#+}8Eh$5w;y_~y*<25dNmkHWPHug -z_YCO!s_?$jSA*un1F%-B;7SBSaFXgRy125CoTwr~gPWG2nKI{S8 -zUN4dOM0RITmH=HT>yO{06&fsA9pp54MMJuBK4f5K$IgmGLn3J`o({*(jt=T^Ya`$<3GX5AhuM0xpFvfj@W~ -zxdQ;aZglGfIPdDPfk+4{sGt;`6Y^!9Ahlr)w1(YK%Mn;r$pjZ*Yv8>UM_}dZOrXR& -z$t{O!T^}4uv7U5ljOU@RdnKDO)x+q(LfcEzX}ax@zZ80U_>gPC5|gk3EbCkD%q`gM -z+_WC$SNJkE=!kW;vJi6r6wQInwlZUbMPwoV@S88H=SA1{y#pwBQQ!TqOe-;8JOVws -zXMmg?{`AcT7;xbRvO{ffo|D+ZB!LzseVp|)q#t?AX-AXzcVk^Xsz#f)LD+x4iaRi!_qh51>s!9WmTLBig+E02* -zQBOo;Og-&C0`ru6MuFakcmm2oe}R}tjYkf?blpq#mrLuM2l|o81kZ=*!%n(iH1)#M -zU2dv)-d0#Wy6ZZ*}|%R_c9l -zUyL%O`3ASLhH<_@7;Qv{4t~A40S84^{ghQm0NsL9q -zz+s`Lv}VaD7Si2ehZ4gM%b;%~+;ThH@VRvB?$0IfGa1fa*BRhDna|rA$UcS)3%yk^ -zPE)~e{AKxxz8ekkz9*$$7?Xe|PfBJZ1$+LJk_B!&3{%7Tly_ChMs2e{lX_CJay0Cy -zDb}fmCk~~1i>E2Q>!vBZ+G#RxS&5F{q+OSd#n}>!iKFv(d*%5%y~|4O0U8)2x&F7( -zBIB?96Zs$fpGym#*$2M1IlEU$x#lmbsXUpFg>@Ld6bb#?Aj1!Whc*`|`l-U=A@b4+ -zr~gwBM?&unu53SFO&gMY$O%5LT{QR*92Y -zdB46wrCSa6>-Ia7^xsAGUxc)H{ZkXYM|lqRV4_#O1bWe15dIwk(ZS9@Jkzl; -z!XO6jyVWBEmp3`&go~WJB4!98+8vn<<(~rH0EARXJ0P?}xE_KF*2+4FeGrJgMf{`A -z3atC0`VS?;p}S$fz9q!SmIWf%a)(bdk_$>BSPP -z(?V*>po}kRdmcvi70~0Bh@$IjXiw+-EV{GCcc7ec!MMaleb>K&rX%rF_tQY*gs5dg -z@x>R_g~EB^ES$4j1#P?5^|l380Y`Bkz)lGk@dWT#j_A`5dhq-fTSAx`Lb{cxvVuuUE$} -z`~YU~2a-BjFB;Vb{1T!;ZfivimWdjfHK3;BttSBEgrqL}(nanbJ>`v!^H7-ZaG&>1 -z7-_%uAwQn`y5Gzr@%iECsyK88YP{ELDOj%}mUoqv%4edop6E-Dx-~E(UKt{G;PqjK -z-w^j+?{OUsyK0IR>)z`Hv#(j_e6P1irz~6zG18p~($s#KAr|nof8mUS+YPEBUB!F7 -z?oF#J0xZ->qC^JXf(t28L8%M(SL|P1-u5Dt;7l6ip*0XkV-qbZXtn8l#rf4}n$tTd -zX!$RzJK#pg{pjlTFdTX)Ot?!$dz{%ucsv|B6CoofC%;)l3-Q4zDk}djh2FhHq~vR$ -zG0*coQ#~Cxdi(HH`zoPHnzj6@6WnyOc-sT%8#w+0>A^zKT*31TDX^qTdOO&=vInwC -zIXhR9;Y1=coXd}k+HdH5f3MaB>DY3$Qw2IX_#VnubFk4j%q3vn%Gsk^2tzudAo|T(AbLt7Dq<0)pEJOB+GM -zQL36Ep{FFO`oM!2FRi;YOM2j@dLZ4<2dquHW4wgRk_xuXhu8rJvFm3aL -z79{#Fo$`Yr)K7uE&dgHH$0Q?2ZSGF0f7iyO7gYk>5=cN(+4<0_`GZ65%srVM?o|!1 -zFQ$VGE%V`i_nme8!;1sHQvcxrio@3mB^GOI^`1eoXV0M2v&ww|^i{N)ZvI?)_D#8% -zCGVYtr+^nSOkae1DLQ&jDfqd8mv9r|S{_YRchiXI*SjR#RTRM7T;3c=0DDXVxvh`@ -zH(2Aks&m`*Kr6X{^(cbbxQ^!x3&2N#3!5#SJ_M)uMC8Q2cn`d04Y^9V_|wB(+iR -zf?L|o_au#RI3yc>>{}UG~MxrZHke%a63?9Z{{B8Q1_C -zor0zfVedKc#k>%tD4Z{Af_o?6ohA^R|M;PmzRwlTbB1bS%{QzyR5!xD4KZlN9Brs1 -zEnG|M4Pl?WC6_NO{n!P&neH_BdCtLUkgU?v5D$mU5`h^6G{fe#_93gmnahKPt^oWc -zpgp?*W2U6D!;IjFJ+5WMcWi-M%bmqHStpe~HrNyTQ_!u5%$(YpSu&3|_tX?2@xb5= -z|7*Y(#wTm}%u0Of2mENtGf~)cz7EBKbEF5vBL(vqQecg1h1ssnOw=CS)8-d%iM@p<tg5!zY+_uE?8 -z7~D&tIZ-@DH(wp2zY%b{jMNBDrkcEC%J6HTc`Cuq+hr^xw$s)XBX3V1J|?9a@d!4- -z)eOs8vef_7POyqWn=a&I?J~m@?5B$crveOJ#z#{xg+iAM(OWrJX7R_MA3Y5ofL}LI -z@D0fsX=P#A7LW|YzGbDFOG{1wr2GG -z7PFZ(L~UmO?ESi$2Kmo5%&|9pYi5kl9K03pZnAPx+^!{=P#?!s* -zV*RLRRop|ob*6U#{t?Kz<+|J@%Yovk?p?@zBpor*qT2c{#Fs+v4-*VDGu30(xpjIN -zcMRts%!}ioV~ysBY`c=iW71SKZSJ{X`bb)-O_rO3AG)I{F@Zwj=WcRi;n>>l{A -zi>#JQp`l^7cHK8bNB5fR8sU2vx@nu8-gldDDRj#v*)D?s{?B}s -zNXuh7fZt6t2V$=v{dRyihInA$Zc!a62Rg&PLF^kV3t?rD@-n?RY_)=|@if2y4qDXZ -zyot19CHcPLk$RAaHqtz9*o&Suf`0&HZUFFBCM8)6VBJKCOJUDjSpc{3Y4GKHSC*8* -zs+@5r?Dy9oIR9seI8g~0|5}(LPNNy`3Xs}!K_aY&5-Kr+l$c1#IBzMO1W3tk1BqSA -zCd?`JfPW#ZgfETo{I`5IpqzH3)ujWZpXA+YPYv82tASC;9#1io9@6_Rg+3c1p5gN^ -zpZW@JBovs;hy0WI*ZgSuqP|aGo(tbN42PZ@gg1e79}cw+GA)#eX?pS-l=IhbXm~G3 -z)B%vc^XvO2y)qTvdI+6By#k0bZ-9gl6pk{JOT402;q4M!w}$RNkTEql|E#IbKknC%%fr6WVWqxmC1+B -zr8#ShTZv3Ox^%LPe-@!U^vRrKIblX*77$;EGIy`XXuK9qvtLE<+#md^eDUZ52gmzR -zZt6#73(iUIItVg@8k|7mS#x-$;jG7Ky2->yc!8n|zDb&nBy5Q9LOC1xYF-bk*zY@H -z`Pw_FZMqH@U%1i`Qj1Y50l^g9g8kqYsjsjLeeXSm4VT9oC6JBhuc%JL3@M -z*`sk==yvv)%0T(zLAT!=fiJA$$oE4%er0Yg+-g*Gs-_$qyx5=1%Lm8VBB8zr6Ewn| -zv)ES-w|W#uqhHbNW8s$W?GY4>Z;8a-N?O*j?M>)dnLp0UbmZjs -z`c$>JK=fBazAFDa-=s+@ovN!YKiP{rYTz#PUHSdqE%{vl*XYvV>!zs@4BoO1e}=%A -zRJC9D(O4EgL_T83D -zVS-O(80U2xQaWJf8`)z+p}ax19b~N(0Ua(L#^i_$g=T{NV*cLBdv@}ujr;R(Rr}< -zUHH7+cov?6-FO!^Q|bg`)&kXgYEAaiWfkjOm7J@N -ztFGD1)!kKFTeE4i3SD2Zj=*Z}UbAWK#+rLnC_BF(rF6ymJAbo#w(*ALchx?!YjIiG -zJZ@=D)jZB|{c>(o6~`AXS*k(+Rw0|Mj58UpSv_~|wb!nl&E2!6ZsVGJXWUy+!xfrl -z78K4bESPSbJFjrgJkzz)*4_gznaAB-Fr#3$3Q;oXJVvsrs!h|Qpy^lIL7UcXuF0uV -zLA+*dEUv6uom0i-Y$32s6(kwUEw1Kl%a<+s^6;*3C-CkR?)VZO0LzGZe6`L!5s;su6azk_=|G8SF;Hr%lKdSWwv-SG5ahaiv*O&stu<{Ujn+ -zXe}R$OvXjnz4_kSH7dmacxaAtu58UZu3~j{&89mlpf5R9%SyJ6ZNLiT<1F`XUIWoR -z8^>T?>Cigp5ER`Vt3Ul0WBMAcy*gHVbJd-7b=*QS2R7H#a2qRNo@mG5R#x0zw_(ja -zT&@x5nD^tJj+90VZ^@~;EpN>1ztWX5XnRvNcXFX-(CdwbA$IaU*!q$;GYR -zSg~$iY?iLs3^NxN&5s%Rw_3evQ?%sA?GTEuc2#p^7J~!vt~+XB$lUT}H{4!cR#SGpOU6l7vw0bN(a!E&ptsb0(F!Uzig6KQO)k}i+<>iJ2Ej9b>OjlR+f -zO^}6frRnH2TBkyswPxcΘwM=?CC&0fIuY2%gbjR#p~5GV)6#KZF)R5y4^E%Q%SO$jR?N;jkmkpeT-F -z^f%HDR6|Oo@-hy%&!FAdZ|u9qjT?U%hrEj+Ke<9N7AG||^*`Z|*Nw#)GcM|KpQD|= -zGA^hx+73-{E_ZpP&vGdJ@z`THSLj1pfKiOL6CL|cjZ3LqM7H?oZ|u7i@GcBRgw86} -z)i`6@!SD)#GhxEjI8lDd$l$NEla}^VI4n!(gMqx4c^d1^RbwC9&X_(kq|aCN2L?{Y -zJ_ZMm#bHPKLn!m(alt%@{-XT>ge^DDN~Qo08e@}`8A|<_X)Uo?Hg3-ALF1o9+% -zfeHd44@r;yG^2^X5fhRpDiZRsjE)~Ae^L^xS%61=q7LB^!5jOI7#dSl1&N!G8F?X| -z4OnNR1sHXZ7%F@M5ryg!x=0>=pzWcV6q#fQsgo0w48-GMey|WL7=~6u%xE-7Lt+{+ -zsStyW6>}sH)5r}m`E4JGcR`F1rPxPejFhbq)5v_>3>{__SYd-0Ls(8?sJ9CSN#e-J -zkF@pw=TCv;(f0qld{N5d@-Tcz1l^7PevU7;=vZUp89N4y7%Sn+JeakFFJ+hcqPvPO -z2yrQ0BNe}j#>%Vsqli-~2!E6mHNqb{${#t$#rQ)}bc{bV&5^#q`gcRjA@`5?gMX4g -zj2y}TQT&m^9D}a?x7SOODtRU)hyS^0gkC?#m%V^Ac1@D^lHVv_?n29>e0laVUo2Pg -z#f+SpUC|mE^izC^AD^fqd`TMN3oDZ`WZjJNMNU()C|}^e8Q=ge`x|_r5dD*UQU3$^ -zq5^3|==0xQFDdGAMoK|n79&5$mo#9?&+%mkaz^=b@-kl>KjKU6q!?e)ev&VV85%X= -zODauA*Najn|1n?WgfH|6U*vz2FU#dN~VyJ^`hWn`FWeBwsZD!1WT3l>Z~Xq-!$EX}C`JU)jev=I8m+4*NXe3k?D`Cih)G;!Ac? -zj4!z(d{JM;m(=VO_yhx?bcTtpm$(tWup@k7nHXQ-AR!;i7X$kJ|8smvfE^5m65YoL -zZAqF0@&ncCXMbexV^v8NSOyXX(uMH&xqZww((q{eqm66aOk)*f{=VF2P}fMMn0!eB -zOB_Ok-`^29#AEd|d7M0|r;X|XDp)6E{ix06s2(7v=$O2L&-OWh({VJN4KWMy$qlg? -zNU*#+&A5e{1FNC(F8zWu$FYzTcetZ=rqrj;LbcIdo=lDY83;B(< -zKN@RLj4yvrzF;Pm?uxd6M%K&E^Ccl8;VO9(CzD^r7w}F;R7JtA-76bix@<=^DXKThuaPxrC(q9Q(UO#r_7tQBD3rZ0xVz9sBc`V}GA>vA-WQu|N2)R-%6+QRM#vdgy2c - -literal 0 -HcmV?d00001 - -diff --git a/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_v1.15.bin b/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_1500000Baud_v1.15.bin -new file mode 100644 -index 0000000000000000000000000000000000000000..95767c2f7a73114dae8356f9ebbca6a10689ecee -GIT binary patch -literal 22632 -zcmd743w%>WzBoQ}&Pj5TrfvEF`T%;8w9qy@(gu|0k|yD_G+?0hfvDG%7B~THD@8^0 -zZc~c8y0||cMa9-f1>NiFRVk0VRu_XjTwi-{BH*?@tEiDw*ONZTXFtDH_J$7`LMV+2D}I>DY+nr8pnpH^Dlo@W2TpVA&zswA8zV@AYLUA`_XbJ&27CF=9;fAdWp2qu-pPmY$@|%4G(jMZuhN^dS@C49+>n@B-S4Ia>T`DCj43 -z<{U#FhF%z%enE89=k7k3$g_J;&qcR85B2oAt!Zup>iNNq`kl2!0VEqIVwqX=yHP$8 -zzj9ky++=5|CM165#w}EHitTVesz*J4ao@32FVIcEZL8j?7Z{SNBq>=F^h8fma*|3R -zDFvk5wBCtZ93qo+`*i>>G}tIE4r<}FTkW4q2ir27=}y&dT6}2e=2E~melE2>qj6H) -z=h71Z{pHXNrD5&{d!bXg=RFA--<1$T+&l1mOG55Q=-!Cxab6*UIs};9lG0373e=C)a7L8P=EFdrYv>lb*$U&Z1}GQ{)54HkWh^Iaku_Uk -zJh7a-MNV=lv7Dks0Xa7v%NhBkgU7xVcNW-5|IB*QL(;z#=k(GPC#9QiPjjwvx^>OY -z2Hi)_SRW=wQ0_6`RC{h|rjRVq-IQMaf=(J|%#60tO4=}98KWX1=TYu+zDf2>;bd<^ -zGM)dlw?+Qs*^E*=8)m(eP*n*r)$*dHzHiAZ?7n%t`u9k@R{AZO2iLshM;`X=`4J8+ -zjHIuk%-eSTb` -zfw}$7zq|!&L}A}&VZ0@6ayxB%#eh2ytP`dLW=gBFh=FPd?K7iy=j7Md+fyp>KFtc%oHHc73vNh}0L -zJ=JcqsSICqOesBcD>8iQeH#5se*{K%2zoTHW36)v|1UwcvWVv;c77>u4$2*N6*btz?$WeiG7gvSyeoqcqzBG$1>U%noDGSYRxS&(UY!gtUow?*NN3WOdF0$X_H5Am=6B2K{={)^vdVS>iU(Vy8sXf0CR~enwiop)y*Y1F&O~ -z6UyI_ra<}+5+~5&Ny#Ko^FbPS>HzkVq<6(e_Xnv^NYs*fD~nXR2(?~pqtc4HF`b-d -zFM5>a1C4h-&5nmUO_DL*98ef(@kuGA1Xf%TNRC(0bkRFqUe7uL*U0Z+?@licB8A^S -z9p=!56&oWzKD=bO?F~xey8<%z;pQRL#ry@jUEJiN_B`LOX|L@Ya=5 -zA+P0g`D5SKnj@hc5ArMkT%0EzRq*ns#_M+x%wob8*cPfNDeE(z|j8ovCGU1QrSymim<*CkMLAgi~ -zP8hx}z%Z%KUkmi2G!LGt2+J=*YY9~L2?=%mNw9?#7ZcOpF!O-~IS$Gbpgq@uB6{k> -z&<@nTm>rNavatGMs`IW%69sixCS?a$W}&GhaW^NvKstKYM7F -zH5Jm6g(`{x_$=#0=R;6J<>it+WI7H;3Lf-O3;6&hw8Z0`HWzt2&MvS5Mde4#q!(zq -zS$x*5?L!qw&U8WB=PpWjVj&e;fmI4nq$OBbm?$t&h`WeD(w#-13uDzZtendPm1-u) -zDj1+94y%WfgrxzDlbpX2=wAQ_rpUvJP;mgODJ^i|_*+6zSRPuN_6Kt@&}D*C?s5bc -zs|$+MK^gmud9Ib7stU8P!V@lP19E5u`V>&&bZ3Jre(qc|2KpxnMS%n;X>d&z;^)5E -z>&7_D1`D81Z@PkQNdhzLU(DJl{nbH6kuIo!JGxmE7#U>(jw`Xt*4A=8;;!#WE1s3=uAl>*T+GC|IzdMG`u -zZzOe!DSg;a>YWsDf#xXErQ5Jxv6O~7$xb!YdB#G+TUs)JJ9@eTaYWA`_&X+JgYl@W -z1Nv*=eWb*AOp#aQmCc1+0HBm%zHhq==U9XWA$dWnO>L6_CAn!S9m@P!9x8hpFB9-| -zL+2@1k}Y|z)`qjmeB<(xp*+{4=g;|%^t7rAvgKu=_O5NXMXA -zPuqp2B3S*4h(5ZD65ks(3HHUt<}FBv~Imrz)9G|9HjrCge1 -zqoZ_2IzqJ+kUnujW+tJTHA*uKRF2UN`s85vlR`XiYTxEM?b^Q@abK^7mUk)y6;Ct? -z^$<0aNclXUoX_WRR0>c-1oF95)rxYkUKYekGk-Hrhm}1@Pl+t*(8=QXB -z>O7|73mCU_3>RMTuSz=(YgrMddd4qLUb)GfZ=rmYFwXM57tg)mN7@U~`6nLD;v3hG -z=TEF3XSm)+=TGoiHXQ1IyS}>9+%qnFzhxuD%@9|29_lZtzXNj5&Dw9-0CB!;zh$2% -zRUhYsytZE;>3;1uYg -zAAnOpSL;Pg(`)JKMv;QJwwRnhWPAdT4A=Sg_di@-)boF|sq=RL-@KBhsOaL-6~D1K -z#3FpEm$q&9?C*cQOf&D3--6xp?h0Ie`Sl*43n10n}s=F~oc5{v> -z-LN=-EAWctk{%sDRC^2|@u+0fErU~qK8sg({rjyagIQ{9no`6W;$Q9Vz -zY!N>(OYHsJ6g2gaMg8fH+ujN;QsZm%MdleanMYxDZ*hQDh(6FT?>CRZazwF~{|Ji~ -z@GN#39gu;gLqVG*_55Q#5#%AU8N@Nx0IpO~aaQAz6l;>zt5YreHb36umA*A^U)i{P -znwj;etyGYqSkG~QiTOYHFlYQDB|h>xsSkKuw2g{AhmwHO-)hKg`}OP6Q5k=o{Z~Ts -zR=Rr|{gKf4Tf$X^;U=FWue$T@yqeCZ@@hN3htSslRDBIR|5{&t#@zF7rpIC4W9E)d -zJ)i56_q(rg^qH>(4sLRY99LV#41!*6P2<`I#o)Ci<^XLkV*nzgyg -z+!L5pS5>$17FpprgG*m}QgZ90V^8Ichkj0o_LDsST0b88d9VKQ=)Oq$n+*G7kM(hj -z2I7r%Px+Z_IqZx~Hlu&iPk{}B${z6JY_N7@gN)Cn^?P8~+y(RJ4L@EW_o+(EJ^!3U -zP85`Ad5uu-+wdR#nj7HEjw1Cp6TJvUk}#r?0BI_h@xe*tKGfZaz+RI}`IwT%`$B$A -zJ5@s8-y7A)NL}`5By=I7X+y&C-Z;b_Gq+997f31GHVg9shLfA*+jpq8IMML7hc&_K -zM#Q$b)J+tU-c)wJ!Ckb|xHzJB=<*pK*q+f+J*`3&ENn3<% -zR_x-UB`-#lE!%lC4T(23;O3^qNGxw4r+6eTZD6`f7%lZIoYmU~`+}tPk_I#biHjTL -z-HWN&wq)wiV1JKnAHm=Ctr0l_O7l7C?Jjdb>4cer62z`wK&-b066n*?+s5COoRi)+ -zE(s{}=m4UZ1ZaT1Z#*ZRG9tjHT1Xw5JUKp}XKLuppr -zf()erm7d6Iq_zg$EI%hP$>xAsy|V<1T?It}H9ifHa}r9%u!Eh37%)=Cl%+sf%19Zc -zpEbhX2)%h0dh;yoKe4pDMPcB4uLb3alYDebmLbDOwVZ5cS{!|iMW0Kb?9SzHw&Fdz -z2M2<02HiLkN*X3*(^e2Tfw~JKp{c{TIqUVa(svq5kEU*wRV&tGkT&IIDvoa^5{KRq -zl{O%gK;op%+vh0~&G^t@Z;#4~^rv9YJSBa{MMAe-{&^Lj&A`9 -za%ZJajAn7WTQBl-CX=at75IU@R*-y?+X`pYc34FljdUCjt?2=mOI9Z{Db`a^D~?DU -zMjwO{^Wlqwa)vSq(t{Eu9LmW?32B2 -z`^nzpR^0U1H`LypIe4!_^eE?YSLS+dbgrkB?*1mNbmuo(%4R$I4bbDxBjma1*f;hW -zdp%Z>p^1!s$WPDI`t*J2b*~0>iF%*{%pPuvF?=xGrk0U -z+kE53NLN<`LOs%uG^}T{B@yZSx+-4{8lesOPqcC4E4mp}hZS&^`*WiybDiC9jHX&E -zdH;fF%3W9F-$HuVhw7|-?#g-oD9v{g{eByt^!9^by8_A&P7xaUvl7|^q42F-T$N5X7@3m> -zmN*4?I4H4BIxB6ybAo70?D19#H}fBXyz9Mh{U}(S -zlcG3{k?;I3wf89Kb1D^{N9V_N)Uxs3jA)we#5%SFX|Y%v>Ga3J2`2=5Ejj-n&rH~t -zuZ6G(f*rzbcCwo`@V5#N9Gtv?*qG=0A~}ve`Br&w7LA+EN)H<`2h@l41SwIB7$}FB -zknj=c7_v%~^RboMLpODT@8CsCP6rwFoxZcuL8wD!&nZX|YH~oO^BZArC_i5nr9H%0 -zd^a)*laaNwQyygL`Wy`Y8`ahme&WADYE}2*WV(B?LT5`Dl+`5(b9m}0eC=bB;-ET+ -z)dl810)L7EaatPcCON5o_okcgZIYOSjsPwK_=e7V>8I>q|7eor2ML}<8k%_X)+UL) -zg0VGLt{N$qChn5ZL1{~w)Hl%)K%6-Mryj6YB~QvHPY(%Is9^YT_}(BXmg9tkhmy!aWrno -zwVoOK)@h!TI%qN4T2arh3pQ9uJ3B0^I-$)wiN=q#>#gM_kh|-1X=wx1<1h4rt#45Q -zk$7Gy_xK{yLrPqDqIU^}3tE)3`9ubrlycC7=+7l?x1w)YfyLpXZ)*;M?q294b{xCz -zPkxu~wBM~e>5uho{7BzYuj*Uk2V?0m4J>BcHj$A(?_Z_+oxfW5tiM&a-@l4$)ot-t -z6S{2L45wq6{&)U^VC%^B(j8T~sa|&WamYVde~tHG|E~Iw@0{dD;0s1+)@R!}aoEiD -z4Wl_$)*9ahC9UuF#+g+CR&{W2NGuIdDrEqHutQSe1L^o0c1BuVukQ++ -zofQf75Bx@Aky4ME=JAFR?Ct@TgyRhSpJ5fmTEMd-p)SA#J!87h7d>h1WM`d@_9>w> -zMJN+iwtXNytO08!*c2buATg0j-vBn$%G%)>3y*h}d#m(WD^(3dZP4+XH3@t-fGLOgzPUP;35 -zarSV?6kf2ms7Ic%uxUL{X>+;Z&~`}%TEI-NuH*rz**2stS@8Q`>>UnG4iAUEi|}NZ -zYmn{vo!S!<&?rtSp(vXE?FAXy~n|F1{RW41~625dRVUX*WT<`S`-f -zLa_T&_U5fXW6;Nuhv?p#qlrtI?jkx>N;1bUxn;`=DO=;{dw=t)$#8l}InckaZlbW= -z!gK(v77bDw@Knw_(EolN%J2CE>3aRiAVbXXjz;2Ba!lZB#37xWhxP7$;9#>8_NrvK -zEx|uj?GQ`T;Z!s(5-J%mxf~*!OmQbA)Z8n;bJaoXx~t)5rH#Ap5`GW1 -zCTz&%pYR;F!^$!~Q@wu+ut{XUCy&q;Z5%5`6JdeS*$a`e;6J%*Vv}13 -zzSUF@&Y^M~OR{xmrL7?OMTev-#l&J0iKWd>BIQurllReQKST{&65o{j2 -z7gIr0ejo^XTi_&3tky2y`Rej^@WdKZ`pmbJ8fX^mHg#`9Oh#4UqRD{J>!(UW`^$GUem%=F5EY5AfaJqZ}#79iS$#H!ytvo(LFAdIB5qcrDahpZf -zL8$aw@HePT8~oVB8oGT;{3xf!4}N9}&%@x6psipdFWd$v;D!bjDn<8$Z}CA`(~m>^ -z0<6I!5DvJ$bTwIadA|@~thzW`g}~0&!QK{Udq#+}8Eh$5w;y_~y*<25dNmkHWPHug -z_YCO!s_?$jSA*un1F%-B;7SBSaFXgRy125CoTwr~gPWG2nKI{S8 -zUN4dOM0RITmH=HT>yO{06&fsA9pp54MMJuBK4f5K$IgmGLn3J`o({*(jt=T^Ya`$<3GX5AhuM0xpFvfj@W~ -zxdQ;aZglGfIPdDPfk+4{sGt;`6Y^!9Ahlr)w1(YK%Mn;r$pjZ*Yv8>UM_}dZOrXR& -z$t{O!T^}4uv7U5ljOU@RdnKDO)x+q(LfcEzX}ax@zZ80U_>gPC5|gk3EbCkD%q`gM -z+_WC$SNJkE=!kW;vJi6r6wQInwlZUbMPwoV@S88H=SA1{y#pwBQQ!TqOe-;8JOVws -zXMmg?{`AcT7;xbRvO{ffo|D+ZB!LzseVp|)q#t?AX-AXzcVk^Xsz#f)LD+x4iaRi!_qh51>s!9WmTLBig+E02* -zQBOo;Og-&C0`ru6MuFakcmm2oe}R}tjYkf?blpq#mrLuM2l|o81kZ=*!%n(iH1)#M -zU2dv)-d0#Wy6ZZ*}|%R_c9l -zUyL%O`3ASLhH<_@7;Qv{4t~A40S84^{ghQm0NsL9q -zz+s`Lv}VaD7Si2ehZ4gM%b;%~+;ThH@VRvB?$0IfGa1fa*BRhDna|rA$UcS)3%yk^ -zPE)~e{AKxxz8ekkz9*$$7?Xe|PfBJZ1$+LJk_B!&3{%7Tly_ChMs2e{lX_CJay0Cy -zDb}fmCk~~1i>E2Q>!vBZ+G#RxS&5F{q+OSd#n}>!iKFv(d*%5%y~|4O0U8)2x&F7( -zBIB?96Zs$fpGym#*$2M1IlEU$x#lmbsXUpFg>@Ld6bb#?Aj1!Whc*`|`l-U=A@b4+ -zr~gwBM?&unu53SFO&gMY$O%5LT{QR*92Y -zdB46wrCSa6>-Ia7^xsAGUxc)H{ZkXYM|lqRV4_#O1bWe15dIwk(ZS9@Jkzl; -z!XO6jyVWBEmp3`&go~WJB4!98+8vn<<(~rH0EARXJ0P?}xE_KF*2+4FeGrJgMf{`A -z3atC0`VS?;p}S$fz9q!SmIWf%a)(bdk_$>BSPP -z(?V*>po}kRdmcvi70~0Bh@$IjXiw+-EV{GCcc7ec!MMaleb>K&rX%rF_tQY*gs5dg -z@x>R_g~EB^ES$4j1#P?5^|l380Y`Bkz)lGk@dWT#j_A`5dhq-fTSAx`Lb{cxvVuuUE$} -z`~YU~2a-BjFB;Vb{1T!;ZfivimWdjfHK3;BttSBEgrqL}(nanbJ>`v!^H7-ZaG&>1 -z7-_%uAwQn`y5Gzr@%iECsyK88YP{ELDOj%}mUoqv%4edop6E-Dx-~E(UKt{G;PqjK -z-w^j+?{OUsyK0IR>)z`Hv#(j_e6P1irz~6zG18p~($s#KAr|nof8mUS+YPEBUB!F7 -z?oF#J0xZ->qC^JXf(t28L8%M(SL|P1-u5Dt;7l6ip*0XkV-qbZXtn8l#rf4}n$tTd -zX!$RzJK#pg{pjlTFdTX)Ot?!$dz{%ucsv|B6CoofC%;)l3-Q4zDk}djh2FhHq~vR$ -zG0*coQ#~Cxdi(HH`zoPHnzj6@6WnyOc-sT%8#w+0>A^zKT*31TDX^qTdOO&=vInwC -zIXhR9;Y1=coXd}k+HdH5f3MaB>DY3$Qw2IX_#VnubFk4j%q3vn%Gsk^2tzudAo|T(AbLt7Dq<0)pEJOB+GM -zQL36Ep{FFO`oM!2FRi;YOM2j@dLZ4<2dquHW4wgRk_xuXhu8rJvFm3aL -z79{#Fo$`Yr)K7uE&dgHH$0Q?2ZSGF0f7iyO7gYk>5=cN(+4<0_`GZ65%srVM?o|!1 -zFQ$VGE%V`i_nme8!;1sHQvcxrio@3mB^GOI^`1eoXV0M2v&ww|^i{N)ZvI?)_D#8% -zCGVYtr+^nSOkae1DLQ&jDfqd8mv9r|S{_YRchiXI*SjR#RTRM7T;3c=0DDXVxvh`@ -zH(2Aks&m`*Kr6X{^(cbbxQ^!x3&2N#3!5#SJ_M)uMC8Q2cn`d04Y^9V_|wB(+iR -zf?L|o_au#RI3yc>>{}UG~MxrZHke%a63?9Z{{B8Q1_C -zor0zfVedKc#k>%tD4Z{Af_o?6ohA^R|M;PmzRwlTbB1bS%{QzyR5!xD4KZlN9Brs1 -zEnG|M4Pl?WC6_NO{n!P&neH_BdCtLUkgU?v5D$mU5`h^6G{fe#_93gmnahKPt^oWc -zpgp?*W2U6D!;IjFJ+5WMcWi-M%bmqHStpe~HrNyTQ_!u5%$(YpSu&3|_tX?2@xb5= -z|7*Y(#wTm}%u0Of2mENtGf~)cz7EBKbEF5vBL(vqQecg1h1ssnOw=CS)8-d%iM@p<tg5!zY+_uE?8 -z7~D&tIZ-@DH(wp2zY%b{jMNBDrkcEC%J6HTc`Cuq+hr^xw$s)XBX3V1J|?9a@d!4- -z)eOs8vef_7POyqWn=a&I?J~m@?5B$crveOJ#z#{xg+iAM(OWrJX7R_MA3Y5ofL}LI -z@D0fsX=P#A7LW|YzGbDFOG{1wr2GG -z7PFZ(L~UmO?ESi$2Kmo5%&|9pYi5kl9K03pZnAPx+^!{=P#?!s* -zV*RLRRop|ob*6U#{t?Kz<+|J@%Yovk?p?@zBpor*qT2c{#Fs+v4-*VDGu30(xpjIN -zcMRts%!}ioV~ysBY`c=iW71SKZSJ{X`bb)-O_rO3AG)I{F@Zwj=WcRi;n>>l{A -zi>#JQp`l^7cHK8bNB5fR8sU2vx@nu8-gldDDRj#v*)D?s{?B}s -zNXuh7fZt6t2V$=v{dRyihInA$Zc!a62Rg&PLF^kV3t?rD@-n?RY_)=|@if2y4qDXZ -zyot19CHcPLk$RAaHqtz9*o&Suf`0&HZUFFBCM8)6VBJKCOJUDjSpc{3Y4GKHSC*8* -zs+@5r?Dy9oIR9seI8g~0|5}(LPNNy`3Xs}!K_aY&5-Kr+l$c1#IBzMO1W3tk1BqSA -zCd?`JfPW#ZgfETo{I`5IpqzH3)ujWZpXA+YPYv82tASC;9#1io9@6_Rg+3c1p5gN^ -zpZW@JBovs;hy0WI*ZgSuqP|aGo(tbN42PZ@gg1e79}cw+GA)#eX?pS-l=IhbXm~G3 -z)B%vc^XvO2y)qTvdI+6By#k0bZ-9gl6pk{JOT402;q4M!w}$RNkTEql|E#IbKknC%%fr6WVWqxmC1+B -zr8#ShTZv3Ox^%LPe-@!U^vRrKIblX*77$;EGIy`XXuK9qvtLE<+#md^eDUZ52gmzR -zZt6#73(iUIItVg@8k|7mS#x-$;jG7Ky2->yc!8n|zDb&nBy5Q9LOC1xYF-bk*zY@H -z`Pw_FZMqH@U%1i`Qj1Y50l^g9g8kqYsjsjLeeXSm4VT9oC6JBhuc%JL3@M -z*`sk==yvv)%0T(zLAT!=fiJA$$oE4%er0Yg+-g*Gs-_$qyx5=1%Lm8VBB8zr6Ewn| -zv)ES-w|W#uqhHbNW8s$W?GY4>Z;8a-N?O*j?M>)dnLp0UbmZjs -z`c$>JK=fBazAFDa-=s+@ovN!YKiP{rYTz#PUHSdqE%{vl*XYvV>!zs@4BoO1e}=%A -zRJC9D(O4EgL_T83D -zVS-O(80U2xQaWJf8`)z+p}ax19b~N(0Ua(L#^i_$g=T{NV*cLBdv@}ujr;R(Rr}< -zUHH7+cov?6-FO!^Q|bg`)&kXgYEAaiWfkjOm7J@N -ztFGD1)!kKFTeE4i3SD2Zj=*Z}UbAWK#+rLnC_BF(rF6ymJAbo#w(*ALchx?!YjIiG -zJZ@=D)jZB|{c>(o6~`AXS*k(+Rw0|Mj58UpSv_~|wb!nl&E2!6ZsVGJXWUy+!xfrl -z78K4bESPSbJFjrgJkzz)*4_gznaAB-Fr#3$3Q;oXJVvsrs!h|Qpy^lIL7UcXuF0uV -zLA+*dEUv6uom0i-Y$32s6(kwUEw1Kl%a<+s^6;*3C-CkR?)VZO0LzGZe6`L!5s;su6azk_=|G8SF;Hr%lKdSWwv-SG5ahaiv*O&stu<{Ujn+ -zXe}R$OvXjnz4_kSH7dmacxaAtu58UZu3~j{&89mlpf5R9%SyJ6ZNLiT<1F`XUIWoR -z8^>T?>Cigp5ER`Vt3Ul0WBMAcy*gHVbJd-7b=*QS2R7H#a2qRNo@mG5R#x0zw_(ja -zT&@x5nD^tJj+90VZ^@~;EpN>1ztWX5XnRvNcXFX-(CdwbA$IaU*!q$;GYR -zSg~$iY?iLs3^NxN&5s%Rw_3evQ?%sA?GTEuc2#p^7J~!vt~+XB$lUT}H{4!cR#SGpOU6l7vw0bN(a!E&ptsb0(F!Uzig6KQO)k}i+<>iJ2Ej9b>OjlR+f -zO^}6frRnH2TBkyswPxcΘwM=?CC&0fIuY2%gbjR#p~5GV)6#KZF)R5y4^E%Q%SO$jR?N;jkmkpeT-F -z^f%HDR6|Oo@-hy%&!FAdZ|u9qjT?U%hrEj+Ke<9N7AG||^*`Z|*Nw#)GcM|KpQD|= -zGA^hx+73-{E_ZpP&vGdJ@z`THSLj1pfKiOL6CL|cjZ3LqM7H?oZ|u7i@GcBRgw86} -z)i`6@!SD)#GhxEjI8lDd$l$NEla}^VI4n!(gMqx4c^d1^RbwC9&X_(kq|aCN2L?{Y -zJ_ZMm#bHPKLn!m(alt%@{-XT>ge^DDN~Qo08e@}`8A|<_X)Uo?Hg3-ALF1o9+% -zfeHd44@r;yG^2^X5fhRpDiZRsjE)~Ae^L^xS%61=q7LB^!5jOI7#dSl1&N!G8F?X| -z4OnNR1sHXZ7%F@M5ryg!x=0>=pzWcV6q#fQsgo0w48-GMey|WL7=~6u%xE-7Lt+{+ -zsStyW6>}sH)5r}m`E4JGcR`F1rPxPejFhbq)5v_>3>{__SYd-0Ls(8?sJ9CSN#e-J -zkF@pw=TCv;(f0qld{N5d@-Tcz1l^7PevU7;=vZUp89N4y7%Sn+JeakFFJ+hcqPvPO -z2yrQ0BNe}j#>%Vsqli-~2!E6mHNqb{${#t$#rQ)}bc{bV&5^#q`gcRjA@`5?gMX4g -zj2y}TQT&m^9D}a?x7SOODtRU)hyS^0gkC?#m%V^Ac1@D^lHVv_?n29>e0laVUo2Pg -z#f+SpUC|mE^izC^AD^fqd`TMN3oDZ`WZjJNMNU()C|}^e8Q=ge`x|_r5dD*UQU3$^ -zq5^3|==0xQFDdGAMoK|n79&5$mo#9?&+%mkaz^=b@-kl>KjKU6q!?e)ev&VV85%X= -zODauA*Najn|1n?WgfH|6U*vz2FU#dN~VyJ^`hWn`FWeBwsZD!1WT3l>Z~Xq-!$EX}C`JU)jev=I8m+4*NXe3k?D`Cih)G;!Ac? -zj4!z(d{JM;m(=VO_yhx?bcTtpm$(tWup@k7nHXQ-AR!;i7X$kJ|8smvfE^5m65YoL -zZAqF0@&ncCXMbexV^v8NSOyXX(uMH&xqZww((q{eqm66aOk)*f{=VF2P}fMMn0!eB -zOB_Ok-`^29#AEd|d7M0|r;X|XDp)6E{ix06s2(7v=$O2L&-OWh({VJN4KWMy$qlg? -zNU*#+&A5e{1FNC(F8zWu$FYzTcetZ=rqrj;LbcIdo=lDY83;B(< -zKN@RLj4yvrzF;Pm?uxd6M%K&E^Ccl8;VO9(CzD^r7w}F;R7JtA-76bix@<=^DXKThuaPxrC(q9Q(UO#r_7tQBD3rZ0xVz9sBc`V}GA>vA-WQu|N2)R-%6+QRM#vdgy2c - -literal 0 -HcmV?d00001 - -diff --git a/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_tb_v1.15.bin b/sysdrv/source/uboot/rkbin/bin/rv11/rv1106_ddr_924MHz_tb_v1.15.bin -index 95767c2f7a73114dae8356f9ebbca6a10689ecee..561ee68249c2d41d8d300baad7d0aff8b2728ee2 100644 -GIT binary patch -delta 18 -acmaE{f$_x##tkN}%nXMZH=DZ}3IhO3qXv}# - -delta 18 -acmaE{f$_x##tkN}%n6UhHk-Q|3IhO82nQ; - clocks = <&cru HCLK_SDMMC>, <&cru CCLK_SRC_SDMMC>; - clock-names = "biu", "ciu"; - memory-region-src = <&ramdisk_c>; - memory-region-dst = <&ramdisk_r>; - }; -}; \ No newline at end of file