diff --git a/.github/workflows/pio.yml b/.github/workflows/pio.yml index 1dfb5eaf..1c4c6091 100644 --- a/.github/workflows/pio.yml +++ b/.github/workflows/pio.yml @@ -3,9 +3,39 @@ name: PlatformIO CI on: [push] jobs: - build: + get_default_envs: + name: Gather Environments runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Cache pip + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + - uses: actions/setup-python@v4 + with: + python-version: '3.9' + - name: Install PlatformIO Core + run: pip install --upgrade platformio + - name: Get default environments + id: envs + run: | + echo -n "environments=" >> $GITHUB_OUTPUT + jq -c -n '$ARGS.positional' --args $(pio project config --json-output | jq -cr '.[][0]' | grep 'env:'| awk -F: '{ print $2" "}' | tr -d '\n') >> $GITHUB_OUTPUT + cat $GITHUB_OUTPUT + outputs: + environments: ${{ steps.envs.outputs.environments }} + build: + runs-on: ubuntu-latest + needs: get_default_envs + strategy: + fail-fast: false + matrix: + environment: ${{ fromJSON(needs.get_default_envs.outputs.environments) }} steps: - uses: actions/checkout@v3 with: @@ -15,7 +45,7 @@ jobs: path: | ~/.cache/pip ~/.platformio/.cache - key: ${{ runner.os }}-pio + key: ${{ runner.os }}-${{ matrix.environment}}-${{ hashFiles('platformio.ini') }} - uses: actions/setup-python@v4 with: python-version: '3.9' @@ -27,12 +57,12 @@ jobs: git_hash=$(git rev-parse --short "$GITHUB_SHA") echo "git_hash=${git_hash}" >> $GITHUB_ENV - name: Build PlatformIO Project - run: pio run + run: pio run -e ${{ matrix.environment }} - name: 'Upload Artifact' uses: actions/upload-artifact@v3 with: - name: StarMod-esp32-${{env.GITHUB_REF_NAME}}-${{env.git_hash}}.bin - path: .pio/build/esp32dev/firmware.bin + name: StarMod-${{ matrix.environment }}-${{env.GITHUB_REF_NAME}}-${{env.git_hash}}.bin + path: .pio/build/${{ matrix.environment }}/firmware.bin retention-days: 30 release: @@ -51,5 +81,4 @@ jobs: files: | *.bin env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index 1950b79a..f7d80978 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,10 @@ # StarMod -Headstart for building ESP32 applications: printing, file management, persistent data, Wifi, Web, UI and system management works out of the box. -StarMod will integrate with major IOT/network devices and applications. +See [StarDocs](https://ewowi.github.io/StarDocs/) -Everything is a module. +image -System modules: +Forks: -* Print: Print to different targets (Serial, file, net) -* Files: File Manager -* Model: Datamodel in json, stored to file, used in ui and network comms -* Network: Wifi -* Web: Web server -* UI: UI Server -* System: Show and manage ESP32 system +* [MoonModules/StarModLeds](https://github.com/MoonModules/StarModLeds) -User Modules - -* E131/DMX support -* Home Assistant (planned) -* LEDs -* ... - -Build apps on top of this - -* Led apps -* IO control apps -* IOT apps -* Any app - -By [MoonModules](https://github.com/MoonModules) -LED module inspired by [WLED MM](https://github.com/MoonModules/WLED) - -Disclaimer: - -Using this software is the users responsibility as it is not bug free. Therefore contributors of this repo can not be held reliable for anything including but not limited to spontaneous combustion of the entire led strip, the house and the inevitable heat death of the universe - -GPL V3 License: - -You may copy, distribute and modify the software as long as you track changes/dates in source files. Any modifications to or software including (via compiler) GPL-licensed code must also be made available under the GPL along with build & install instructions ([tldrlegal](https://www.tldrlegal.com/license/gnu-general-public-license-v3-gpl-3)) \ No newline at end of file diff --git a/data/app.js b/data/app.js index 3e568713..e38629c0 100644 --- a/data/app.js +++ b/data/app.js @@ -1,6 +1,6 @@ // @title StarMod // @file app.js -// @date 20240114 +// @date 20240411 // @repo https://github.com/ewowi/StarMod // @Authors https://github.com/ewowi/StarMod/commits/main // @Copyright © 2024 Github StarMod Commit Authors @@ -8,321 +8,14 @@ // @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com function appName() { - return "Led"; + return "Demo"; } function userFun(buffer) { if (buffer[0]==1 && jsonValues.pview) { let pviewNode = gId("pview"); - //replace the canvas: in case we switch from 2D to 3D as they cannot be reused between them - //not needed anymore as we do only three.js - // if (jsonValues.pview.new) - // { - // console.log("replace the canvas!", jsonValues.pview); - // let canvasNode = cE("canvas"); - // canvasNode.width = pviewNode.width; - // canvasNode.height = pviewNode.height; - // canvasNode.className = pviewNode.className; - // canvasNode.draggable = true; - // canvasNode.addEventListener('dragstart', (event) => {event.preventDefault(); event.stopPropagation();}); - - // pviewNode.parentNode.replaceChild(canvasNode, pviewNode); - // pviewNode = canvasNode; - // pviewNode.id = "pview"; - // pviewNode.addEventListener('dblclick', (event) => {toggleModal(event.target);}); - // } - - // console.log("userFun", buffer); - - // if (jsonValues.pview.depth == 1) - // preview2D(pviewNode, buffer); - // else - preview3D(pviewNode, buffer); - return true; } return false; -} - -function preview2D(canvasNode, buffer) { - let ctx = canvasNode.getContext('2d'); - let i = 5; - let factor = 10;//fixed value: from mm to cm - ctx.clearRect(0, 0, canvasNode.width, canvasNode.height); - if (jsonValues.pview) { - let pPL = Math.min(canvasNode.width / jsonValues.pview.width, canvasNode.height / jsonValues.pview.height); // pixels per LED (width of circle) - let lOf = Math.floor((canvasNode.width - pPL*jsonValues.pview.width)/2); //left offeset (to center matrix) - if (jsonValues.pview.outputs) { - // console.log("preview2D jsonValues", jsonValues.pview); - for (var output of jsonValues.pview.outputs) { - if (output.buffer) { - for (var led of output.buffer) { - if (buffer[i] + buffer[i+1] + buffer[i+2] > 20) { //do not show nearly blacks - ctx.fillStyle = `rgb(${buffer[i]},${buffer[i+1]},${buffer[i+2]})`; - ctx.beginPath(); - ctx.arc(led[0]*pPL/factor + lOf, led[1]*pPL/factor, pPL*0.4, 0, 2 * Math.PI); - ctx.fill(); - } - i+=3; - } - } - else { - console.log("preview2D jsonValues no leds", jsonValues.pview); - jsonValues.pview = null; - } - } - } - else { - console.log("preview2D jsonValues no outputs", jsonValues.pview); - jsonValues.pview = null; - } - jsonValues.pview.new = null; - } -} - -let renderer = null; -let scene = null; -let camera = null; -var controls = null; -let raycaster = null; -let intersect = null; -let mousePointer = null; - -//https://stackoverflow.com/questions/8426822/rotate-camera-in-three-js-with-mouse - -//inspiration: https://discoverthreejs.com/book/first-steps/transformations/ -function preview3D(canvasNode, buffer) { - //3D vars - import ('three').then((THREE) => { - - function onMouseMove( event ) { - - let canvasRect = canvasNode.getBoundingClientRect(); - - if (!mousePointer) mousePointer = new THREE.Vector2(); - mousePointer.x = ((event.clientX - canvasRect.left) / canvasRect.width) * 2 - 1; - mousePointer.y = -((event.clientY - canvasRect.top) / canvasRect.height) * 2 + 1; - - let canvasMenuRect = gId("canvasMenu").getBoundingClientRect(); - - // console.log(event.clientX, event.clientY, canvasMenuRect); - - //if mousePointer out of menu bounds then hide menu - if (event.clientX < canvasMenuRect.left || event.clientX > canvasMenuRect.right || event.clientY < canvasMenuRect.top || event.clientY > canvasMenuRect.bottom) - gId("canvasMenu").style.display = "none"; - } - - function onMouseDown(event) { - event.preventDefault(); - // var rightclick; - // if (!event) var event = window.event; - // if (event.which) rightclick = (event.which == 3); - // else if (event.button) rightclick = (event.button == 2); - // if (!rightclick) return; - - // var intersects = raycaster.intersectObjects(scene.children); - console.log("onMouseDown", event, intersect); - - if (intersect) { - // intersect = intersects[0].object; - gId("canvasMenu").style.left = (event.clientX) + "px"; // - rect.left - gId("canvasMenu").style.top = (event.clientY) + "px"; //- rect.top - gId("canvasMenu").style.display = ""; //not none -> show - let sp = intersect.name.split(" - "); //output and led index is encoded in the name - gId("canvasData").innerText = jsonValues.pview.outputs[sp[0]].leds[sp[1]];// event.clientY; - } - // else{ - // intersect = undefined; - // } - } - - import ('three/addons/controls/OrbitControls.js').then((OCModule) => { - - let factor = 10;//fixed value: from mm to cm - let d = 5 / factor; //distanceLED; - - //init three - done once - if (!renderer || (jsonValues.pview && jsonValues.pview.new)) { //init 3D - - console.log("preview3D create new renderer"); - - renderer = new THREE.WebGLRenderer({canvas: canvasNode, antialias: true, alpha: true }); - // THREE.Object3D.DefaultUp = new THREE.Vector3(0,1,1); - renderer.setClearAlpha(0) - renderer.setClearColor( 0x000000, 0 ); - - camera = new THREE.PerspectiveCamera( 45, canvasNode.width/canvasNode.width, 1, 500); //aspectRatio is 1 for the time being - camera.position.set( 0, 0, d*Math.sqrt(jsonValues.pview.width*jsonValues.pview.width + jsonValues.pview.height*jsonValues.pview.height + jsonValues.pview.depth*jsonValues.pview.depth) ); - camera.lookAt( 0, 0, 0 ); - - scene = new THREE.Scene(); - scene.background = null; //new THREE.Color( 0xff0000 ); - - controls = new OCModule.OrbitControls( camera, renderer.domElement ); - controls.target.set( 0, 0.5, 0 ); - controls.update(); - controls.enablePan = false; - controls.enableDamping = true; - - raycaster = new THREE.Raycaster(); - - canvasNode.addEventListener( 'mousemove', onMouseMove ); - canvasNode.addEventListener('mousedown', onMouseDown, false); - //prevent default behavior - // if (gId("canvasMenu").addEventListener) { - // gId("canvasMenu").addEventListener('contextmenu', function (e) { - // console.log("canvasMenu contextmenu", e); - // e.preventDefault(); - // }, false); - // } else { - // gId("canvasMenu").attachEvent('oncontextmenu', function () { - // console.log("canvasMenu oncontextmenu", window); - // window.event.returnValue = false; - // }); - // } - - gId("canvasButton1").innerText = "Set Start position"; - gId("canvasButton2").innerText = "Set End position"; - gId("canvasButton3").innerText = "Set Mid position"; - - //process canvas button click - gId("canvasButton1").addEventListener("click", function(){ - var command = {}; - command["canvasData"] = "start:" + gId("canvasData").innerText; - requestJson(command); - - gId("canvasMenu").style.display = "none"; - }, false); - gId("canvasButton2").addEventListener("click", function(){ - var command = {}; - command["canvasData"] = "end:" + gId("canvasData").innerText; - requestJson(command); - gId("canvasMenu").style.display = "none"; - }, false); - gId("canvasButton3").addEventListener("click", function(){ - var command = {}; - command["canvasData"] = "mid:" + gId("canvasData").innerText; - requestJson(command); - gId("canvasMenu").style.display = "none"; - }, false); - - } //new - - //init fixture - anytime a new fixture - if (jsonValues.pview && jsonValues.pview.new) { //set the new coordinates - var offset_x = -d*(jsonValues.pview.width-1)/2; - var offset_y = -d*(jsonValues.pview.height-1)/2; - var offset_z = -d*(jsonValues.pview.depth-1)/2; - - console.log("preview3D new jsonValues", jsonValues.pview); - - if (jsonValues.pview.outputs) { - // console.log("preview3D jsonValues", jsonValues.pview); - let outputsIndex = 0; - for (var output of jsonValues.pview.outputs) { - if (output.leds) { - let ledsIndex = 0; - for (var led of output.leds) { - if (led.length == 1) //1D: make 2D - led.push(0); - if (led.length <= 2) //1D and 2D: maak 3D - led.push(0); - const geometry = new THREE.SphereGeometry( 0.2); //was 1/factor - const material = new THREE.MeshBasicMaterial({transparent: true, opacity: 0.7}); - // material.color = new THREE.Color(`${x/mW}`, `${y/mH}`, `${z/mD}`); - const sphere = new THREE.Mesh( geometry, material ); - sphere.position.set(offset_x + d*led[0]/factor, -offset_y - d*led[1]/factor, - offset_z - d*led[2]/factor); - sphere.name = outputsIndex + " - " + ledsIndex++; - scene.add( sphere ); - } - } - else { - console.log("preview3D jsonValues no leds", jsonValues.pview); - jsonValues.pview = null; - } - outputsIndex++; - } //outputs - } - else { - console.log("preview3D jsonValues no outputs", jsonValues.pview); - jsonValues.pview = null; - } - jsonValues.pview.new = null; - } - - //animate / render - if (jsonValues.pview) { - //https://stackoverflow.com/questions/29884485/threejs-canvas-size-based-on-container - if (canvasNode.width != canvasNode.clientWidth) { //} || canvasNode.height != canvasNode.clientHeight) { - console.log("3D pview update size", canvasNode.width, canvasNode.clientWidth, canvasNode.height, canvasNode.clientHeight); - renderer.setSize(canvasNode.clientWidth, canvasNode.clientWidth, false); //Setting updateStyle to false prevents any style changes to the output canvas. - } - - //light up the cube - let firstLed = 5; - var i = 1; - if (jsonValues.pview.outputs) { - // console.log("preview3D jsonValues", jsonValues.pview); - for (var output of jsonValues.pview.outputs) { - if (output.leds) { - for (var led of output.leds) { - if (i < scene.children.length) { - scene.children[i].visible = buffer[i*3 + firstLed] + buffer[i*3 + firstLed + 1] + buffer[i*3 + firstLed+2] > 10; //do not show blacks - if (scene.children[i].visible) - scene.children[i].material.color = new THREE.Color(`${buffer[i*3 + firstLed]/255}`, `${buffer[i*3 + firstLed + 1]/255}`, `${buffer[i*3 + firstLed + 2]/255}`); - } - i++; - } - } - else { - console.log("preview3D jsonValues no leds", jsonValues.pview); - jsonValues.pview = null; - } - } - } - else { - console.log("preview3D jsonValues no outputs", jsonValues.pview); - jsonValues.pview = null; - } - } - - // controls.rotateSpeed = 0.4; - //moving heads rotation - scene.rotation.x = buffer[1] / 255 * Math.PI * 2; - scene.rotation.y = buffer[2] / 255 * Math.PI * 2; - scene.rotation.z = buffer[3] / 255 * Math.PI * 2; - - controls.update(); // apply orbit controls - - if (mousePointer) { - raycaster.setFromCamera( mousePointer, camera ); - - const intersects = raycaster.intersectObjects( scene.children, true ); //recursive - - if ( intersects.length > 0 ) { - // console.log(raycaster, intersects, mousePointer, scene.children); - - if ( intersect != intersects[ 0 ].object ) { - - if ( intersect ) intersect.material.color.setHex( intersect.currentHex ); - - intersect = intersects[ 0 ].object; - intersect.currentHex = intersect.material.color.getHex(); - intersect.material.color.setHex( 0xff0000 ); //red - - } - - } else { - - if ( intersect ) intersect.material.color.setHex( intersect.currentHex ); - - intersect = null; - - } - } //if mousePointer - - renderer.render( scene, camera); - }); //import OrbitControl - }); //import Three -} //preview3D \ No newline at end of file +} \ No newline at end of file diff --git a/data/index.css b/data/index.css index 8ca2ca98..45843879 100644 --- a/data/index.css +++ b/data/index.css @@ -1,8 +1,8 @@ /* @title StarMod @file index.css - @date 20240226 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 diff --git a/data/index.htm b/data/index.htm index bf19aef0..53c78519 100644 --- a/data/index.htm +++ b/data/index.htm @@ -1,8 +1,8 @@ don't use for LEDS when serial-to-USB is needed - case 20: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 21: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - #endif //CONFIG_IDF_TARGET_ESP32S2 - - #if CONFIG_IDF_TARGET_ESP32S3 - case 0: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 1: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 2: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 3: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 4: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 5: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 6: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 7: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 8: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 9: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 10: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 11: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 12: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 13: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 14: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 15: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 16: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 17: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 18: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - #if !ARDUINO_USB_CDC_ON_BOOT - // 19 + 20 = USB-JTAG. Not recommended for other uses. - case 19: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 20: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - #endif - case 21: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // // 22 to 32: not connected, or SPI FLASH - // case 22: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // case 23: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // case 24: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // case 25: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // case 26: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // case 27: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // case 28: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // case 29: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // case 30: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // case 31: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // case 32: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - #if !defined(BOARD_HAS_PSRAM) - // 33 to 37: reserved if using _octal_ SPI Flash or _octal_ PSRAM - case 33: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 34: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 35: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 36: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 37: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - #endif - case 38: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 39: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 40: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 41: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 42: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - // 43+44 = Serial RX+TX --> don't use for LEDS when serial-to-USB is needed - case 43: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 44: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 45: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 46: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 47: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - case 48: FastLED.addLeds(fixture.ledsP, startLed, nrOfLeds).setCorrection(TypicalLEDStrip); break; - #endif //CONFIG_IDF_TARGET_ESP32S3 - - default: USER_PRINTF("FastLedPin assignment: pin not supported %d\n", pinNr); - } //switch pinNr - } //if led range in details (- in details e.g. 0-1023) - } //if pin owned by leds - pinNr++; - } // for pins - fixture.doAllocPins = false; - } - } - } //loop - - void loop1s() { - mdl->setUIValueV("realFps", "%lu /s", frameCounter); - frameCounter = 0; - } - - void loop10s() { - // USER_PRINTF("caching %u %u\n", trigoCached, trigoUnCached); //not working for some reason!! - // trigoCached = 0; - // trigoUnCached = 0; - } - -private: - unsigned long frameMillis = 0; - unsigned long frameCounter = 0; - -}; - -extern LedModEffects *eff; \ No newline at end of file diff --git a/src/App/LedModFixture.h b/src/App/LedModFixture.h deleted file mode 100644 index 66461a17..00000000 --- a/src/App/LedModFixture.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - @title StarMod - @file LedModFixture.h - @date 20240228 - @repo https://github.com/ewowi/StarMod - @Authors https://github.com/ewowi/StarMod/commits/main - @Copyright © 2024 Github StarMod Commit Authors - @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com -*/ - -class LedModFixture:public SysModule { - -public: - - uint8_t viewRotation = 0; - - LedModFixture() :SysModule("Fixture") {}; - - void setup() { - SysModule::setup(); - - parentVar = ui->initAppMod(parentVar, name, 1100); - - JsonObject currentVar = ui->initCheckBox(parentVar, "on", true, false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "On"); - return true; - case f_ChangeFun: - ui->callVarFun("bri", UINT8_MAX, f_ChangeFun); //set FastLed brightness - return true; - default: return false; - }}); - currentVar["dash"] = true; - - //logarithmic slider (10) - currentVar = ui->initSlider(parentVar, "bri", 10, 0, 255, false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Brightness"); - return true; - case f_ChangeFun: { - stackUnsigned8 bri = var["value"]; - - stackUnsigned8 result = mdl->getValue("on").as()?mdl->varLinearToLogarithm(var, bri):0; - - FastLED.setBrightness(result); - - USER_PRINTF("Set Brightness to %d -> b:%d r:%d\n", var["value"].as(), bri, result); - return true; } - default: return false; - }}); - currentVar["log"] = true; //logarithmic - currentVar["dash"] = true; //these values override model.json??? - - currentVar = ui->initCanvas(parentVar, "pview", UINT16_MAX, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Preview"); - // ui->setComment(var, "Shows the fixture"); - // ui->setComment(var, "Click to enlarge"); - return true; - case f_LoopFun: { - var["interval"] = max(eff->fixture.nrOfLeds * web->ws.count()/200, 16U)*10; //interval in ms * 10, not too fast //from cs to ms - - web->sendDataWs([this](AsyncWebSocketMessageBuffer * wsBuf) { - byte* buffer; - - buffer = wsBuf->get(); - - // send leds preview to clients - for (size_t i = 0; i < eff->fixture.nrOfLeds; i++) - { - buffer[i*3+5] = eff->fixture.ledsP[i].red; - buffer[i*3+5+1] = eff->fixture.ledsP[i].green; - buffer[i*3+5+2] = eff->fixture.ledsP[i].blue; - } - //new values - buffer[0] = 1; //userFun id - //rotations - if (viewRotation == 0) { - buffer[1] = 0; - buffer[2] = 0; - buffer[3] = 0; - } else if (viewRotation == 1) { - buffer[1] = 0;//beatsin8(4, 250, 5); //tilt - buffer[2] = beat8(1);//, 0, 255); //pan - buffer[3] = 0;//beatsin8(6, 255, 5); //roll - } else if (viewRotation == 2) { - buffer[1] = eff->fixture.head.x; - buffer[2] = eff->fixture.head.y; - buffer[3] = eff->fixture.head.y; - } - - }, eff->fixture.nrOfLeds * 3 + 5, true); - return true; - } - default: return false; - }}); - - ui->initSelect(currentVar, "viewRot", viewRotation, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: { - ui->setLabel(var, "Rotation"); - // ui->setComment(var, "View rotation"); - JsonArray options = ui->setOptions(var); - options.add("None"); - options.add("Pan"); - #ifdef STARMOD_USERMOD_WLEDAUDIO - options.add("Moving heads GEQ"); - #endif - return true; } - case f_ChangeFun: - this->viewRotation = var["value"]; - // if (!var["value"]) - // eff->fixture.head = {0,0,0}; - return true; - default: return false; - }}); - - currentVar = ui->initSelect(parentVar, "fixture", eff->fixture.fixtureNr, false ,[](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - { - // ui->setComment(var, "Fixture to display effect on"); - JsonArray options = ui->setOptions(var); - files->dirToJson(options, true, "F_"); //only files containing F(ixture), alphabetically - - // ui needs to load the file also initially - char fileName[32] = ""; - if (files->seqNrToName(fileName, var["value"])) { - web->addResponse("pview", "file", JsonString(fileName, JsonString::Copied)); - } - return true; - } - case f_ChangeFun: - { - eff->fixture.fixtureNr = var["value"]; - eff->fixture.doMap = true; - eff->fixture.doAllocPins = true; - - //remap all leds - // for (std::vector::iterator leds=eff->fixture.projections.begin(); leds!=eff->fixture.projections.end(); ++leds) { - for (Leds *leds: eff->fixture.projections) { - leds->doMap = true; - } - - char fileName[32] = ""; - if (files->seqNrToName(fileName, eff->fixture.fixtureNr)) { - //send to pview a message to get file filename - web->addResponse("pview", "file", JsonString(fileName, JsonString::Copied)); - } - return true; - } - default: return false; - }}); //fixture - - ui->initCoord3D(currentVar, "fixSize", eff->fixture.size, 0, NUM_LEDS_Max, true, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_ValueFun: - mdl->setValue(var, eff->fixture.size); - return true; - case f_UIFun: - ui->setLabel(var, "Size"); - return true; - default: return false; - }}); - - ui->initNumber(currentVar, "fixCount", eff->fixture.nrOfLeds, 0, UINT16_MAX, true, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_ValueFun: - mdl->setValue(var, eff->fixture.nrOfLeds); - return true; - case f_UIFun: - ui->setLabel(var, "Count"); - web->addResponseV(var["id"], "comment", "Max %d", NUM_LEDS_Max); - return true; - default: return false; - }}); - - ui->initNumber(parentVar, "fps", eff->fps, 1, 999, false , [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setComment(var, "Frames per second"); - return true; - case f_ChangeFun: - eff->fps = var["value"]; - return true; - default: return false; - }}); - - ui->initText(parentVar, "realFps", nullptr, 10, true, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - web->addResponseV(var["id"], "comment", "f(%d leds)", eff->fixture.nrOfLeds); - return true; - default: return false; - }}); - - ui->initCheckBox(parentVar, "fShow", eff->fShow, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "FastLed show"); - ui->setComment(var, "dev performance tuning"); - return true; - case f_ChangeFun: - eff->fShow = var["value"]; - return true; - default: return false; - }}); - - } -}; - -extern LedModFixture *fix; \ No newline at end of file diff --git a/src/App/LedModFixtureGen.h b/src/App/LedModFixtureGen.h deleted file mode 100644 index c21367a0..00000000 --- a/src/App/LedModFixtureGen.h +++ /dev/null @@ -1,1081 +0,0 @@ -/* - @title StarMod - @file LedModFixtureGen.h - @date 20240228 - @repo https://github.com/ewowi/StarMod - @Authors https://github.com/ewowi/StarMod/commits/main - @Copyright © 2024 Github StarMod Commit Authors - @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com -*/ - -#include "SysModule.h" - -//GenFix: class to provide fixture write functions and save to json file -// { -// "name": "F_Hexagon", -// "nrOfLeds": 216, -// "width": 6554, -// "height": 6554, -// "depth": 1, -// "outputs": [{"pin": 2,"leds": [[720,360,0],[1073,1066,0]]}], {"pin": 3,"leds": [[720,360,0],[1073,1066,0]]}] -// } -class GenFix { - -public: - char name[32] = ""; - - // unsigned16 distance = 1; //cm, not used yet (to display multiple fixture, also from other devices) - - char pinSep[2]=""; - char pixelSep[2]=""; - - Coord3D fixSize = {0,0,0}; - unsigned16 nrOfLeds=0; - - File f; - - GenFix() { - USER_PRINTF("GenFix constructor\n"); - } - - ~GenFix() { - USER_PRINTF("GenFix destructor\n"); - } - - void openHeader(const char * format, ...) { - va_list args; - va_start(args, format); - - vsnprintf(name, sizeof(name)-1, format, args); - - va_end(args); - - f = files->open("/temp.json", "w"); - if (!f) - USER_PRINTF("GenFix could not open temp file for writing\n"); - - f.print(",\"outputs\":["); - strcpy(pinSep, ""); - } - - void closeHeader() { - f.print("]"); //outputs - - USER_PRINTF("closeHeader %d-%d-%d %d\n", fixSize.x, fixSize.y, fixSize.z, nrOfLeds); - f.close(); - f = files->open("/temp.json", "r"); - - File g; - - char fileName[32] = "/"; - strncat(fileName, name, sizeof(fileName)-1); - strncat(fileName, ".json", sizeof(fileName)-1); - - - //create g by merging in f (better solution?) - g = files->open(fileName, "w"); - - g.print("{"); - g.printf("\"name\":\"%s\"", name); - g.printf(",\"nrOfLeds\":%d", nrOfLeds); - g.printf(",\"width\":%d", (fixSize.x+9)/10+1); //effects run on 1 led is 1 cm mode. - g.printf(",\"height\":%d", (fixSize.y+9)/10+1); //e.g. (110+9)/10 +1 = 11+1 = 12, (111+9)/10 +1 = 12+1 = 13 - g.printf(",\"depth\":%d", (fixSize.z+9)/10+1); - - byte character; - f.read(&character, sizeof(byte)); - while (f.available()) { - g.write(character); - f.read(&character, sizeof(byte)); - } - g.write(character); - - g.print("}"); - g.close(); - f.close(); - - files->remove("/temp.json"); - } - - void openPin(unsigned8 pin) { - f.printf("%s{\"pin\":%d,\"leds\":[", pinSep, pin); - strcpy(pinSep, ","); - strcpy(pixelSep, ""); - } - void closePin() { - f.printf("]}"); - } - - void write3D(Coord3D pixel) { - write3D(pixel.x, pixel.y, pixel.z); - } - - void write3D(unsigned16 x, unsigned16 y, unsigned16 z) { - // if (x>UINT16_MAX/2 || y>UINT16_MAX/2 || z>UINT16_MAX/2) - if (x>1000 || y>1000 || z>1000) - USER_PRINTF("write3D coord too high %d,%d,%d\n", x, y, z); - else - { - f.printf("%s[%d,%d,%d]", pixelSep, x, y, z); - strcpy(pixelSep, ","); - fixSize.x = max((unsigned16)fixSize.x, x); - fixSize.y = max((unsigned16)fixSize.y, y); - fixSize.z = max((unsigned16)fixSize.z, z); - nrOfLeds++; - } - - } - - //utility - unsigned u_abs(int x) { - if (x <0) return -x; - else return x; - } - - void matrix(Coord3D first, Coord3D rowEnd, Coord3D colEnd, unsigned8 ip, unsigned8 pin) { - - openPin(pin); - - //advance from pixel to rowEnd - //if rowEnd: is it serpentine or not? - // no: set advancing dimension back to first - // yes: set non advancing dimension 1 step closer to colEnd - //determine new rowEnd - //if rowEnd > colEnd - // yes: done - // no: go back to first step - - // Coord3D pixel = first; - - stackUnsigned8 rowDimension; //in what dimension the row will advance (x=0, y=1, z=2), now only one should differ - if (first.x != rowEnd.x) rowDimension = 0; - if (first.y != rowEnd.y) rowDimension = 1; // - if (first.z != rowEnd.z) rowDimension = 2; - - stackUnsigned8 colDimension; //in what dimension the col will advance, not the rowDimension - if (first.x != colEnd.x && rowDimension != 0) colDimension = 0; // - if (first.y != colEnd.y && rowDimension != 1) colDimension = 1; - if (first.z != colEnd.z && rowDimension != 2) colDimension = 2; - - bool rowValueSame = (rowDimension == 0)? first.x == colEnd.x : (rowDimension == 1)? first.y == colEnd.y : first.z == colEnd.z; - bool serpentine = rowValueSame; - - unsigned16 nrOfColumns = (colDimension == 0)? u_abs(colEnd.x - first.x) + 1 : (colDimension == 1)? u_abs(colEnd.y - first.y) + 1 : u_abs(colEnd.z - first.z) + 1; - if (nrOfColumns % 2 == 1 && rowValueSame) //if odd nrOfCols and rowValueSame then adjust the endpoint col value to the rowEnd col value - { - if (rowDimension == 0) - colEnd.x = rowEnd.x; - else if (rowDimension == 1) - colEnd.y = rowEnd.y; - else if (rowDimension == 2) - colEnd.z = rowEnd.z; - } - - Coord3D colPixel = Coord3D{(rowDimension==0)?colEnd.x:first.x, (rowDimension==1)?colEnd.y:first.y, (rowDimension==2)?colEnd.z:first.z}; - stackUnsigned8 colNr = 0; - while (true) { - // colPixel is not advancing over the dimension of the row but advances over it's own dimension towards the colEnd - - Coord3D cRowStart = Coord3D{(colDimension==0)?colPixel.x:first.x, (colDimension==1)?colPixel.y:first.y, (colDimension==2)?colPixel.z:first.z}; - Coord3D cRowEnd = Coord3D{(colDimension==0)?colPixel.x:rowEnd.x, (colDimension==1)?colPixel.y:rowEnd.y, (colDimension==2)?colPixel.z:rowEnd.z}; - - if (serpentine && colNr%2 != 0) { - Coord3D temp = cRowStart; - cRowStart = cRowEnd; - cRowEnd = temp; - } - - Coord3D rowPixel = cRowStart; - while (true) { - USER_PRINTF(" %d,%d,%d", rowPixel.x, rowPixel.y, rowPixel.z); - write3D(rowPixel.x*10, rowPixel.y*10, rowPixel.z*10); - - if (rowPixel == cRowEnd) break; //end condition row - rowPixel.advance(cRowEnd); - } - - USER_PRINTF("\n"); - - if (colPixel == colEnd) break; //end condition columns - colPixel.advance(colEnd); - colNr++; - } - - closePin(); - } - - void ring(Coord3D middle, unsigned16 ledCount, unsigned8 ip, unsigned8 pin, uint16_t pan = 0, uint16_t tilt = 0, uint16_t roll = 0, bool preDiam = false) { - - openPin(pin); - - uint8_t ringDiam = 10 * ledCount / 2 / M_PI; //in mm; - if (preDiam) { - //check for rings241 rings which have a specific diameter - switch (ledCount) { - case 1: ringDiam = 0; break; - case 8: ringDiam = 13; break; - case 12: ringDiam = 23; break; - case 16: ringDiam = 33; break; - case 24: ringDiam = 43; break; - case 32: ringDiam = 53; break; - case 40: ringDiam = 63; break; - case 48: ringDiam = 73; break; - case 60: ringDiam = 83; break; - default: ringDiam = 10 * ledCount / 2 / M_PI; //in mm - } - } - - Trigo trigo; - - for (int i=0; i 1 - // {1, 8}, //1 -> 8 - // {9, 20}, //2 -> 12 - // {21, 36}, //3 -> 16 - // {37, 60}, //4 -> 24 - // {61, 92}, //5 -> 32 - // {93, 132}, //6 -> 40 - // {133, 180}, //7 -> 48 - // {181, 240}, //8 Outer Ring -> 60 -> 241 - - // stackUnsigned16 size = ringDiams[nrOfRings-1]; //size if the biggest ring - for (int j=0; j= 0; x-=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 110; for (int x = 90; x <= 510; x+=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 70; for (int x = 400; x >= 110; x-=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - closePin(); - //second pin (green) - openPin(pin); - y = 140; for (int x = 530; x >= 0; x-=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 100; for (int x = 90; x <= 510; x+=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 60; for (int x = 390; x >= 120; x-=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - closePin(); - //third pin (blue) - openPin(pin); - y = 130; for (int x = 520; x >= 10; x-=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 90; for (int x = 100; x <= 500; x+=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 50; for (int x = 390; x >= 140; x-=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - closePin(); - //fourth pin (yellow) - openPin(pin); - y = 120; for (int x = 520; x >= 30; x-=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 80; for (int x = 100; x <= 480; x+=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 40; for (int x = 380; x >= 240; x-=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 30; for (int x = 250; x <= 370; x+=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 20; for (int x = 360; x >= 260; x-=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 10; for (int x = 270; x <= 350; x+=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - y = 00; for (int x = 330; x >= 290; x-=10) write3D(x+first.x*10, y+first.y*10, first.z*10); - closePin(); - } - - void globe(Coord3D first, unsigned8 width, unsigned8 ip, unsigned8 pin) { - - Coord3D middle; - middle.x = first.x*10 + width*10 / 2; - middle.z = first.z*10 + width*10 / 2; - - // loop over latitudes -> sin 0 to pi - for (uint8_t lat = 0; lat <= width; lat++) { - float factor = 128.0f / width; //16 => 8 - float ringDiam = (sin8(lat * factor)-128) / factor / 2.0f; // 0 .. 128 => 0 .. 128 .. 0 => 0 .. 16 .. 0 in cm - - uint8_t ledCount = ringDiam * 2 * M_PI; - - middle.y = first.y*10 + lat*10; - - // Coord3D start = first; - // start.y = first.y + lat; - USER_PRINTF("Globe %d %f %d %d,%d,%d\n", lat, ringDiam, ledCount, middle.x, middle.y, middle.z); - ring(middle, ledCount, ip, pin, 0, 90, 0); //tilt 90 - } - } - - // https://stackoverflow.com/questions/17705621/algorithm-for-a-geodesic-sphere - //https://opengl.org.ru/docs/pg/0208.html - void geodesicDome(Coord3D first, unsigned8 width, unsigned8 ip, unsigned8 pin) { - - stackUnsigned8 tindices[20][3] = { {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1}, {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3}, {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} }; - - openPin(pin); - - for (int i=0; i<20; i++) { - write3D(tindices[i][0]*10 + first.x*10, tindices[i][1]*10 + first.y*10, tindices[i][2]*10 + first.z*10); - } - - closePin(); - } - -}; - -enum Fixtures -{ - f_Matrix, - f_Ring, - f_Rings241, - f_Spiral, - f_Wheel, - f_Hexagon, - f_Cone, - f_Cloud, - f_Wall, - f_6Rings, - f_SpaceStation, - f_Human, - f_Globe, - f_GeodesicDome, - fixtureCount -}; - -class LedModFixtureGen:public SysModule { - -public: - - LedModFixtureGen() :SysModule("Fixture Generator") {}; - - void setup() { - SysModule::setup(); - - parentVar = ui->initAppMod(parentVar, name, 6302); //created as a usermod, not an appmod to have it in the usermods tab - parentVar["s"] = true; //setup - - ui->initSelect(parentVar, "fixtureGen", 0, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: { - ui->setLabel(var, "Fixture"); - ui->setComment(var, "Type of fixture"); - JsonArray options = ui->setOptions(var); //See enum Fixtures for order of options - options.add("Matrix"); - options.add("Ring"); - options.add("Rings241"); - options.add("Spiral"); - options.add("Wheel"); - options.add("Hexagon"); - options.add("Cone"); - options.add("Cloud"); - options.add("Wall"); - options.add("6Rings"); - options.add("SpaceStation"); - options.add("Human"); - options.add("Globe"); - options.add("GeodesicDome WIP"); - return true; - } - case f_ChangeFun: - this->fixtureGenChFun(); - return true; - default: return false; - }}); //fixtureGen - - ui->initCheckBox(parentVar, "panels", false, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setComment(var, "Show panels"); - return true; - case f_ChangeFun: { - this->fixtureGenChFun(); - return true; } - default: return false; - }}); - - // gpio2 seems to be a safe choice on all esp32 variants -// ui->initText(parentVar, "pinList", "2", 32, false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun -// case f_UIFun: -// ui->setComment(var, "One or more e.g. 12,13,14"); -// return true; -// #if 0 // @ewowi did not get this to work -// case f_ValueFun: -// #if CONFIG_IDF_TARGET_ESP32 && (defined(BOARD_HAS_PSRAM) || defined(ARDUINO_ESP32_PICO)) // -// ui->setValue(var, "2"); // gpio16 is reserved on pico and on esp32 with PSRAM -// #elif CONFIG_IDF_TARGET_ESP32S3 -// ui->setValue(var, "21"); // gpio21 = builtin neopixel on some -S3 boards -// #elif CONFIG_IDF_TARGET_ESP32C3 -// ui->setValue(var, "10"); // gpio10 = builtin neopixel on some -C3 boards -// #else -// ui->setValue(var, "16"); // default on universal shield (classic esp32, or esp32-S2) -// #endif -// return true; -// #endif -// default: return false; -// }}); - - ui->initButton(parentVar, "generate", false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_ChangeFun: { - - char fileName[32]; - generateChFun(var, fileName); - ui->callVarFun("fixture", UINT8_MAX, f_UIFun); //reload fixture select - - uint8_t value = ui->selectOptionToValue("fixture", fileName); - if (value != UINT8_MAX) - mdl->setValue("fixture", value); - - return true; } - default: return false; - }}); - - } //setup - - void loop() { - // SysModule::loop(); - } - - //generate dynamic html for fixture controls - void fixtureGenChFun() { - - JsonObject fixtureGenVar = mdl->findVar("fixtureGen"); - JsonObject panelVar = mdl->findVar("panels"); - - // JsonObject parentVar = mdl->findVar(var["id"]); //local parentVar - stackUnsigned8 fgValue = fixtureGenVar["value"]; - - fixtureGenVar.remove("n"); //tbd: we should also remove the varFun !! - - // mdl->varPreDetails(fixtureGenVar); - - JsonObject parentVar = fixtureGenVar; - if (panelVar["value"].as()) { - - parentVar = ui->initTable(fixtureGenVar, "pnlTbl", nullptr, false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Panels"); - ui->setComment(var, "List of fixtures"); - return true; - case f_AddRow: - web->getResponseObject()["addRow"]["rowNr"] = rowNr; - return true; - case f_DelRow: - // web->getResponseObject()["addRow"]["rowNr"] = rowNr; - return true; - default: return false; - }}); - - ui->initCoord3D(parentVar, "pnlFirst", {0,0,0}, 0, NUM_LEDS_Max, false, [fgValue](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - //show Top Left for all fixture except Matrix as it has its own - if (fgValue == f_Matrix) - ui->setLabel(var, "First LED"); - else - ui->setLabel(var, "Top left"); - return true; - default: return false; - }}); - - } //if panels - - - if (fgValue == f_Matrix) { - - ui->initCoord3D(parentVar, "mrxRowEnd", {7,0,0}, 0, NUM_LEDS_Max, false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Row end"); - ui->setComment(var, "-> Orientation"); - return true; - default: return false; - }}); - - ui->initCoord3D(parentVar, "mrxColEnd", {7,7,0}, 0, NUM_LEDS_Max, false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Column end"); - ui->setComment(var, "Last LED -> nrOfLeds, Serpentine"); - return true; - default: return false; - }}); - - if (panelVar["value"].as()) { - - ui->initSelect(fixtureGenVar, "fixPreset", 0, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: { - ui->setLabel(var, "Preset"); - JsonArray options = ui->setOptions(var); - options.add("None"); - options.add("16x16"); - options.add("4x16x16"); - options.add("4x32x8"); - options.add("Human Sized Cube"); - options.add("CubeBox"); - options.add("Cube3D"); - options.add("Sticks"); - return true; } - case f_ChangeFun: { - stackUnsigned8 optionNr = 1; // 0 is none, maintain the same order here as the options - stackUnsigned8 panel = 0; - if (var["value"] == optionNr++) { //16x16 - stackUnsigned8 lengthMinOne = 15; - panel = 0; mdl->setValue("pnlFirst", Coord3D{0,0,0}, panel++); - panel = 0; mdl->setValue("mrxRowEnd", Coord3D{0,lengthMinOne,0}, panel++); - panel = 0; mdl->setValue("mrxColEnd", Coord3D{lengthMinOne,lengthMinOne,0}, panel++); - panel = 0; mdl->setValue("fixPin", 2, panel++); // default per board... - } - if (var["value"] == optionNr++) { //4x16x16 - stackUnsigned8 lengthMinOne = 15; stackUnsigned8 size = lengthMinOne + 1; - panel = 0; mdl->setValue("pnlFirst", Coord3D{0,0,0}, panel++); mdl->setValue("pnlFirst", Coord3D{16,0,0}, panel++); mdl->setValue("pnlFirst", Coord3D{0,16,0}, panel++); mdl->setValue("pnlFirst", Coord3D{16,16,0}, panel++); - panel = 0; mdl->setValue("mrxRowEnd", Coord3D{0,lengthMinOne,0}, panel++); mdl->setValue("mrxRowEnd", Coord3D{16,lengthMinOne,0}, panel++); mdl->setValue("mrxRowEnd", Coord3D{0,31,0}, panel++); mdl->setValue("mrxRowEnd", Coord3D{16,31,0}, panel++); - panel = 0; mdl->setValue("mrxColEnd", Coord3D{lengthMinOne,lengthMinOne,0}, panel++); mdl->setValue("mrxColEnd", Coord3D{31,lengthMinOne,0}, panel++); mdl->setValue("mrxColEnd", Coord3D{lengthMinOne,31,0}, panel++); mdl->setValue("mrxColEnd", Coord3D{31,31,0}, panel++); - panel = 0; mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); - } - if (var["value"] == optionNr++) { //4x32x8 - stackUnsigned8 lengthMinOne = 31; - panel = 0; mdl->setValue("pnlFirst", Coord3D{lengthMinOne,lengthMinOne,0}, panel++); mdl->setValue("pnlFirst", Coord3D{lengthMinOne,23,0}, panel++); mdl->setValue("pnlFirst", Coord3D{lengthMinOne,15,0}, panel++); mdl->setValue("pnlFirst", Coord3D{lengthMinOne,7,0}, panel++); - panel = 0; mdl->setValue("mrxRowEnd", Coord3D{lengthMinOne,24,0}, panel++); mdl->setValue("mrxRowEnd", Coord3D{lengthMinOne,16,0}, panel++); mdl->setValue("mrxRowEnd", Coord3D{lengthMinOne,8,0}, panel++); mdl->setValue("mrxRowEnd", Coord3D{lengthMinOne,0,0}, panel++); - panel = 0; mdl->setValue("mrxColEnd", Coord3D{0,lengthMinOne,0}, panel++); mdl->setValue("mrxColEnd", Coord3D{0,23,0}, panel++); mdl->setValue("mrxColEnd", Coord3D{0,15,0}, panel++); mdl->setValue("mrxColEnd", Coord3D{0,7,0}, panel++); - panel = 0; mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); - } - else if (var["value"] == optionNr++) { //Human Sized Cube - stackUnsigned8 length = 20; stackUnsigned8 size = length + 1; - panel = 0; mdl->setValue("pnlFirst", Coord3D{1,1,size}, panel++); mdl->setValue("pnlFirst", Coord3D{0,1,1}, panel++); mdl->setValue("pnlFirst", Coord3D{1,1,0}, panel++); mdl->setValue("pnlFirst", Coord3D{size,1,1}, panel++); mdl->setValue("pnlFirst", Coord3D{1,0,1}, panel++); - panel = 0; mdl->setValue("mrxRowEnd", Coord3D{1,length,size}, panel++); mdl->setValue("mrxRowEnd", Coord3D{0,length,1}, panel++); mdl->setValue("mrxRowEnd", Coord3D{1,length,0}, panel++); mdl->setValue("mrxRowEnd", Coord3D{size,length,1}, panel++); mdl->setValue("mrxRowEnd", Coord3D{1,0,length}, panel++); - panel = 0; mdl->setValue("mrxColEnd", Coord3D{length,length,size}, panel++); mdl->setValue("mrxColEnd", Coord3D{0,length,length}, panel++); mdl->setValue("mrxColEnd", Coord3D{length,length,0}, panel++); mdl->setValue("mrxColEnd", Coord3D{size,length,length}, panel++); mdl->setValue("mrxColEnd", Coord3D{length,0,length}, panel++); - panel = 0; mdl->setValue("fixPin", 16, panel++); mdl->setValue("fixPin", 14, panel++); mdl->setValue("fixPin", 32, panel++); mdl->setValue("fixPin", 3, panel++); mdl->setValue("fixPin", 15, panel++); - } - else if (var["value"] == optionNr++) { //Cube 6 x 8 x 8 - stackUnsigned8 length = 8; stackUnsigned8 size = length + 1; - panel = 0; mdl->setValue("pnlFirst", Coord3D{1,1,0}, panel++); mdl->setValue("pnlFirst", Coord3D{length, size, length}, panel++); mdl->setValue("pnlFirst", Coord3D{size, 1, 1}, panel++); mdl->setValue("pnlFirst", Coord3D{0, length, length}, panel++); mdl->setValue("pnlFirst", Coord3D{length, 1, size}, panel++); mdl->setValue("pnlFirst", Coord3D{1, 0, length}, panel++); - panel = 0; mdl->setValue("mrxRowEnd", Coord3D{1,length,0}, panel++); mdl->setValue("mrxRowEnd", Coord3D{1, size, length}, panel++); mdl->setValue("mrxRowEnd", Coord3D{size, 1, length}, panel++); mdl->setValue("mrxRowEnd", Coord3D{0, 1, length}, panel++); mdl->setValue("mrxRowEnd", Coord3D{1, 1, size}, panel++); mdl->setValue("mrxRowEnd", Coord3D{length, 0, length}, panel++); - panel = 0; mdl->setValue("mrxColEnd", Coord3D{length,length,0}, panel++); mdl->setValue("mrxColEnd", Coord3D{1, size, 1}, panel++); mdl->setValue("mrxColEnd", Coord3D{size, length, length}, panel++); mdl->setValue("mrxColEnd", Coord3D{0, 1, 1}, panel++); mdl->setValue("mrxColEnd", Coord3D{1, length, size}, panel++); mdl->setValue("mrxColEnd", Coord3D{length, 0, 1}, panel++); - panel = 0; mdl->setValue("fixPin", 12, panel++); mdl->setValue("fixPin", 12, panel++); mdl->setValue("fixPin", 13, panel++); mdl->setValue("fixPin", 13, panel++); mdl->setValue("fixPin", 14, panel++); mdl->setValue("fixPin", 14, panel++); - } - else if (var["value"] == optionNr++) { //Cube 3D - stackUnsigned8 length = 8; stackUnsigned8 size = length -1; - for (forUnsigned8 panel=0; panel < length; panel++) { - mdl->setValue("pnlFirst", Coord3D{0,0,(unsigned16)panel}, panel); - mdl->setValue("mrxRowEnd", Coord3D{0,size,(unsigned16)panel}, panel); - mdl->setValue("mrxColEnd", Coord3D{size,size,(unsigned16)panel}, panel); - mdl->setValue("fixPin", 12, panel); - } - } - else if (var["value"] == optionNr++) { //Sticks - stackUnsigned8 length = 16; - stackUnsigned8 height = 54; - for (forUnsigned8 panel=0; panel < length; panel++) { - mdl->setValue("pnlFirst", Coord3D{(unsigned16)(panel*5), height, 0}, panel); - mdl->setValue("mrxRowEnd", Coord3D{(unsigned16)(panel*5), height, 0}, panel); - mdl->setValue("mrxColEnd", Coord3D{(unsigned16)(panel*5), 0, 0}, panel); - mdl->setValue("fixPin", 12, panel); - } - } - return true; } - default: return false; - }}); - } - } - else if (fgValue == f_Ring) { - ui->initNumber(parentVar, "fixLeds", 24, 1, NUM_LEDS_Max, false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Leds"); - return true; - default: return false; - }}); - - if (panelVar["value"].as()) { - - ui->initSelect(fixtureGenVar, "fixPreset", 0, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: { - ui->setLabel(var, "Preset"); - JsonArray options = ui->setOptions(var); - options.add("None"); - options.add("Olympic"); - options.add("Audi"); - return true; } - case f_ChangeFun: { - stackUnsigned8 optionNr = 1; // 0 is none, maintain the same order here as the options - stackUnsigned8 panel = 0; - if (var["value"] == optionNr++) { //Olympic - panel = 0; mdl->setValue("pnlFirst", Coord3D{0,0,0}, panel++); mdl->setValue("pnlFirst", Coord3D{10,0,0}, panel++); mdl->setValue("pnlFirst", Coord3D{20,0,0}, panel++); mdl->setValue("pnlFirst", Coord3D{5,3,0}, panel++); mdl->setValue("pnlFirst", Coord3D{15,3,0}, panel++); - panel = 0; mdl->setValue("fixLeds", 24, panel++); mdl->setValue("fixLeds", 24, panel++); mdl->setValue("fixLeds", 24, panel++); mdl->setValue("fixLeds", 24, panel++); mdl->setValue("fixLeds", 24, panel++); - panel = 0; mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); // default per board... - } - if (var["value"] == optionNr++) { //Audi - panel = 0; mdl->setValue("pnlFirst", Coord3D{0,0,0}, panel++); mdl->setValue("pnlFirst", Coord3D{6,0,0}, panel++); mdl->setValue("pnlFirst", Coord3D{12,0,0}, panel++); mdl->setValue("pnlFirst", Coord3D{18 ,0,0}, panel++); - panel = 0; mdl->setValue("fixLeds", 24, panel++); mdl->setValue("fixLeds", 24, panel++); mdl->setValue("fixLeds", 24, panel++); mdl->setValue("fixLeds", 24, panel++); - panel = 0; mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); mdl->setValue("fixPin", 2, panel++); // default per board... - } - return true; } - default: return false; - }}); - } - } - else if (fgValue == f_Rings241) { - ui->initNumber(parentVar, "nrOfRings", 9, 1, 9); - ui->initCheckBox(parentVar, "in2out", true); - } - else if (fgValue == f_Spiral) { - ui->initNumber(parentVar, "fixLeds", 64, 1, NUM_LEDS_Max, false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Leds"); - return true; - default: return false; - }}); - } - else if (fgValue == f_Wheel) { - ui->initNumber(parentVar, "nrOfSpokes", 36, 1, 360); - ui->initNumber(parentVar, "ledsPerSpoke", 24, 1, 360); - } - else if (fgValue == f_Hexagon) { - ui->initNumber(parentVar, "ledsPerSide", 12, 1, 255); - - if (panelVar["value"].as()) { - - ui->initSelect(fixtureGenVar, "fixPreset", 0, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: { - ui->setLabel(var, "Preset"); - JsonArray options = ui->setOptions(var); - options.add("None"); - options.add("HexaWall"); - return true; } - case f_ChangeFun: { - stackUnsigned8 optionNr = 1; // 0 is none, maintain the same order here as the options - stackUnsigned8 panel = 0; - if (var["value"] == optionNr++) { //HexaWall - panel = 0; - mdl->setValue("pnlFirst", Coord3D{0,0,0}, panel++); - mdl->setValue("pnlFirst", Coord3D{10,6,0}, panel++); - mdl->setValue("pnlFirst", Coord3D{10,18,0}, panel++); - mdl->setValue("pnlFirst", Coord3D{20,0,0}, panel++); - mdl->setValue("pnlFirst", Coord3D{30,6,0}, panel++); - mdl->setValue("pnlFirst", Coord3D{40,12,0}, panel++); - mdl->setValue("pnlFirst", Coord3D{40,24,0}, panel++); - mdl->setValue("pnlFirst", Coord3D{50,6,0}, panel++); - mdl->setValue("pnlFirst", Coord3D{60,0,0}, panel++); - - for (forUnsigned8 panel = 0; panel < 9; panel++) { - mdl->setValue("ledsPerSide", 6, panel); - mdl->setValue("fixPin", 2, panel); - } - } - return true; } - default: return false; - }}); - } - } - else if (fgValue == f_Human) { - - if (panelVar["value"].as()) { - - ui->initSelect(fixtureGenVar, "fixPreset", 0, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: { - ui->setLabel(var, "Preset"); - JsonArray options = ui->setOptions(var); - options.add("Body1"); - options.add("Body2"); - return true; } - default: return false; - }}); - } - - } - else if (fgValue == f_Cone) { - ui->initNumber(parentVar, "nrOfRings", 24, 1, 360); - } - else if (fgValue == f_Globe) { - ui->initNumber(parentVar, "width", 24, 1, 48); - } - - - - ui->initNumber(parentVar, "fixIP", WiFi.localIP()[3], 1, 256, false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "IP"); - ui->setComment(var, "Super-Sync WIP"); - return true; - default: return false; - }}); - - ui->initPin(parentVar, "fixPin", 2, false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: { - ui->setLabel(var, "Pin"); - - //tbd: move logic to pinMgr and create initPin - JsonArray options = ui->setOptions(var); - - for (forUnsigned8 pinNr = 0; pinNr < NUM_DIGITAL_PINS; pinNr++) { - char text[32]; - itoa(pinNr, text, 10); - if (digitalPinIsValid(pinNr)) { - - #if defined(CONFIG_IDF_TARGET_ESP32S2) - if ((pinNr > 18 && pinNr < 21) || (pinNr > 21 && pinNr < 33)) strcat(text, " 🟣"); else - #elif defined(CONFIG_IDF_TARGET_ESP32S3) - if ((pinNr > 18 && pinNr < 21) || (pinNr > 21 && pinNr < 33)) strcat(text, " 🟣"); else - #elif defined(CONFIG_IDF_TARGET_ESP32C3) - if ((pinNr > 11 && pinNr < 18) || (pinNr > 17 && pinNr < 20)) strcat(text, " 🟣"); else - #elif defined(ESP32) - if (pinNr > 5 && pinNr < 12) strcat(text, " 🟣"); else - #else //??? - #endif - - if (!digitalPinCanOutput(pinNr)) - strcat(text, " 🟠"); //read only - else - strcat(text, " 🟢"); //io - - //results in crashes - // if (digitalPinToRtcPin(pinNr)) strcat(text, " 🟢"); else strcat(text, " 🔴"); //error: 'RTC_GPIO_IS_VALID_GPIO' was not declared in this scope - // if (digitalPinToDacChannel(pinNr)) strcat(text, " 🟢"); else strcat(text, " 🔴"); //error: 'DAC_CHANNEL_1_GPIO_NUM' was not declared in this scope - - //not so relevant - // if (digitalPinToAnalogChannel(pinNr)) strcat(text, " 🟣"); - // if (digitalPinToTouchChannel(pinNr)) strcat(text, " 🟤"); - } - else - strcat(text, " 🔴"); //not valid - options.add(JsonString(text, JsonString::Copied)); - } - return true; } - case f_ChangeFun: { - //set remaining rows to same pin - JsonArray valArray = mdl->varValArray(var); - - stackUnsigned8 thisVal = var["value"]; - stackUnsigned8 rowNrL = 0; - for (JsonVariant val: valArray) { - if (rowNrL > rowNr) - mdl->setValue(var, valArray[rowNr].as(), rowNrL); - rowNrL++; - } - return true; } - default: return false; - }}); - - mdl->varPostDetails(fixtureGenVar, UINT8_MAX); - - } - - //tbd: move to utility functions - char *removeSpaces(char *str) - { - int i = 0, j = 0; - while (str[i]) - { - if (str[i] != ' ') - str[j++] = str[i]; - i++; - } - str[j] = '\0'; - return str; - } - - void getPanels(const char * fileName, std::function genFun) { - GenFix genFix; - - JsonObject presetsVar = mdl->findVar("fixPreset"); - stackUnsigned8 presets = mdl->getValue(presetsVar); - - //set header and file name - if (presets != 0) { - JsonArray options = ui->getOptions(presetsVar); - - char text[32] = "F_"; - strncat(text, options[presets], 31); - removeSpaces(text); - - genFix.openHeader(text); - - ui->clearOptions(presetsVar); - } - else { - // stackUnsigned16 ledCount = mdl->getValue("fixLeds"); - genFix.openHeader(fileName); - } - - JsonVariant pnlFirstValue = mdl->findVar("pnlFirst")["value"]; - - if (pnlFirstValue.is()) { - stackUnsigned8 rowNr = 0; - for (JsonVariant firstValueRow: pnlFirstValue.as()) { - genFun(&genFix, rowNr); - rowNr++; - } - } else { - genFun(&genFix, UINT8_MAX); - } - - genFix.closeHeader(); - } - - void generateChFun(JsonObject var, char * fileName) { - - stackUnsigned8 fgValue = mdl->getValue("fixtureGen"); - - if (fgValue == f_Matrix) { - - Coord3D size = (mdl->getValue("mrxColEnd").as() - mdl->getValue("pnlFirst").as()) + Coord3D{1,1,1}; - print->fFormat(fileName, 31, "F_Matrix%d%d%d", size.x, size.y, size.z); - - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - genFix->matrix(mdl->getValue("pnlFirst", rowNr), mdl->getValue("mrxRowEnd", rowNr), mdl->getValue("mrxColEnd", rowNr), mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - }); - - } else if (fgValue == f_Ring) { - - print->fFormat(fileName, 31, "F_Ring%d", mdl->getValue("fixLeds").as()); - - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - Coord3D middle = mdl->getValue("pnlFirst", rowNr); - uint16_t ledCount = mdl->getValue("fixLeds", rowNr); - uint8_t ringDiam = 10 * ledCount / 2 / M_PI + 10; //in mm - middle.x = middle.x*10 + ringDiam; - middle.y = middle.y*10 + ringDiam; - - genFix->ring(middle, ledCount, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - }); - - } else if (fgValue == f_Rings241) { - - print->fFormat(fileName, 31, "F_Rings241-%d", mdl->getValue("nrOfRings").as()); - - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - Coord3D middle = mdl->getValue("pnlFirst", rowNr); - uint16_t nrOfLeds = mdl->getValue("fixLeds", rowNr); - uint8_t ringDiam = 10 * 60 / 2 / M_PI; //in mm - middle.x = middle.x*10 + ringDiam; - middle.y = middle.y*10 + ringDiam; - genFix->rings241(middle, mdl->getValue("nrOfRings", rowNr), mdl->getValue("in2out", rowNr), mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - }); - - } else if (fgValue == f_Spiral) { - - print->fFormat(fileName, 31, "F_Spiral%d", mdl->getValue("fixLeds").as()); - - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - genFix->spiral(mdl->getValue("pnlFirst", rowNr), mdl->getValue("fixLeds", rowNr), mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - }); - - } else if (fgValue == f_Wheel) { - - print->fFormat(fileName, 31, "F_Wheel%d%d", mdl->getValue("nrOfSpokes").as(), mdl->getValue("ledsPerSpoke").as()); - - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - genFix->wheel(mdl->getValue("pnlFirst", rowNr), mdl->getValue("nrOfSpokes", rowNr), mdl->getValue("ledsPerSpoke", rowNr), mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - }); - - } else if (fgValue == f_Hexagon) { - - strcpy(fileName, "F_Hexagon"); - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - genFix->hexagon(mdl->getValue("pnlFirst", rowNr), mdl->getValue("ledsPerSide", rowNr), mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - }); - - } else if (fgValue == f_Cone) { - - print->fFormat(fileName, 31, "F_Cone%d", mdl->getValue("nrOfRings").as()); - - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - genFix->cone(mdl->getValue("pnlFirst", rowNr), mdl->getValue("nrOfRings", rowNr), mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - }); - - } else if (fgValue == f_Cloud) { - - strcpy(fileName, "F_Cloud5416"); - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - genFix->cloud(mdl->getValue("pnlFirst", rowNr), mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - }); - - } else if (fgValue == f_Wall) { - - strcpy(fileName, "F_Wall"); - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - genFix->rings241(Coord3D{110,110,0}, 9, true, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - - genFix->matrix(Coord3D{19,0,0}, Coord3D{19,8,0}, Coord3D{27,0,0}, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - genFix->matrix(Coord3D{0,19,0}, Coord3D{0,25,0}, Coord3D{50,19,0}, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - - genFix->ring(Coord3D{190+80,80+80,0}, 48, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - - // genFix.spiral(240, 0, 0, 48); - }); - - } else if (fgValue == f_6Rings) { - - strcpy(fileName, "F_6Rings"); - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - genFix->rings241(Coord3D{110,110,0}, 9, true, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - genFix->rings241(Coord3D{0,110,110}, 9, true, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr), 90); //pan 90 - genFix->rings241(Coord3D{110,110,220}, 9, true, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - genFix->rings241(Coord3D{220,110,110}, 9, true, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr), 90); // pan 90 - genFix->rings241(Coord3D{110,0,110}, 9, true, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr), 0, 90); // tilt 90 - genFix->rings241(Coord3D{110,220,110}, 9, true, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr), 0, 90); // tilt 90 - }); - - } else if (fgValue == f_SpaceStation) { - - strcpy(fileName, "F_SpaceStation"); - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - Trigo trigo; - for (int i=0; i<360; i+=20) { - uint8_t ringDiam = 50; - uint8_t issDiam = 150; - Coord3D middle = Coord3D{ringDiam + issDiam + trigo.sin(issDiam, i), ringDiam + issDiam + trigo.cos(issDiam, i), ringDiam}; - genFix->ring(middle, 12, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr), 0, 90, 360-i); // tilt 90 then roll a bit - } - }); - - } else if (fgValue == f_Human) { - - strcpy(fileName, "F_Human"); - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - - //total dimensions width: 10 + 18 + 10 - // height 18 + 5 + - Coord3D headSize = {18, 18, 1}; - Coord3D armSize = {12, 5, 1}; - Coord3D legSize = {5, 20, 1}; - - // head - genFix->rings241({190,110,0}, 9, true, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - - //arms - genFix->matrix(Coord3D{0,headSize.y + 2,0}, Coord3D{0,headSize.y + 2 + armSize.y,0}, Coord3D{armSize.x,headSize.y + 2,0}, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - genFix->matrix(Coord3D{armSize.x + 14,headSize.y + 2,0}, Coord3D{armSize.x + 14,headSize.y + 2 + armSize.y,0}, Coord3D{38,headSize.y + 2,0}, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - - //legs - genFix->matrix(Coord3D{10, 28, 0}, Coord3D{10, 50, 0}, Coord3D{15,28,0}, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - genFix->matrix(Coord3D{23, 28, 0}, Coord3D{23, 50, 0}, Coord3D{28,28,0}, mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - - - }); - - } else if (fgValue == f_Globe) { - - print->fFormat(fileName, 31, "F_Globe%d", mdl->getValue("width").as()); - - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - genFix->globe(mdl->getValue("pnlFirst", rowNr), mdl->getValue("width", rowNr), mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - }); - - } else if (fgValue == f_GeodesicDome) { - - strcpy(fileName, "F_GeodesicDome"); - getPanels(fileName, [](GenFix * genFix, unsigned8 rowNr) { - genFix->geodesicDome(mdl->getValue("pnlFirst", rowNr), mdl->getValue("width", rowNr), mdl->getValue("fixIP", rowNr), mdl->getValue("fixPin", rowNr)); - }); - - } - - files->filesChanged = true; - } - - // File openFile(const char * name) { - // char fileName[30] = "/"; - // strncat(fileName, name, sizeof(fileName)-1); - // strncat(fileName, ".json", sizeof(fileName)-1); - - // File f = files->open(fileName, "w"); - // if (!f) - // USER_PRINTF("fixtureGen Could not open file %s for writing\n", fileName); - - // return f; - // } - -}; - -extern LedModFixtureGen *lfg; \ No newline at end of file diff --git a/src/Sys/SysModFiles.cpp b/src/Sys/SysModFiles.cpp index d97d2622..fe66b229 100644 --- a/src/Sys/SysModFiles.cpp +++ b/src/Sys/SysModFiles.cpp @@ -1,8 +1,8 @@ /* @title StarMod @file SysModFiles.cpp - @date 20240228 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -19,8 +19,8 @@ SysModFiles::SysModFiles() :SysModule("Files") { if (!LittleFS.begin(true)) { //true: formatOnFail - USER_PRINTF(" An Error has occurred while mounting File system"); - USER_PRINTF(" fail\n"); + ppf(" An Error has occurred while mounting File system"); + ppf(" fail\n"); success = false; } }; @@ -37,14 +37,13 @@ void SysModFiles::setup() { return true; case f_AddRow: rowNr = fileList.size(); - USER_PRINTF("chFun addRow %s[%d] = %s\n", mdl->varID(var), rowNr, var["value"].as().c_str()); web->getResponseObject()["addRow"]["rowNr"] = rowNr; //add a row with all defaults return true; case f_DelRow: if (rowNr != UINT8_MAX && rowNr < fileList.size()) { const char * fileName = fileList[rowNr].name; - USER_PRINTF("chFun delRow %s[%d] = %s %s\n", mdl->varID(var), rowNr, var["value"].as().c_str(), fileName); + ppf("chFun delRow %s[%d] = %s %s\n", mdl->varID(var), rowNr, var["value"].as().c_str(), fileName); this->removeFiles(fileName, false); } print->printJson(" ", var); @@ -143,7 +142,7 @@ void SysModFiles::loop10s() { } bool SysModFiles::remove(const char * path) { - USER_PRINTF("File remove %s\n", path); + ppf("File remove %s\n", path); return LittleFS.remove(path); filesChanged = true; } @@ -179,7 +178,7 @@ void SysModFiles::dirToJson(JsonArray array, bool nameOnly, const char * filter) strncat(urlString, file.name(), sizeof(urlString)-1); row.add(JsonString(urlString, JsonString::Copied)); } - // USER_PRINTF("FILE: %s %d\n", file.name(), file.size()); + // ppf("FILE: %s %d\n", file.name(), file.size()); } file.close(); @@ -197,7 +196,7 @@ bool SysModFiles::seqNrToName(char * fileName, size_t seqNr) { size_t counter = 0; while (file) { if (counter == seqNr) { - USER_PRINTF("seqNrToName: %s %d\n", file.name(), file.size()); + // ppf("seqNrToName: %d %s %d\n", seqNr, file.name(), file.size()); root.close(); strncat(fileName, "/", 31); //add root prefix, fileName is 32 bytes but sizeof doesn't know so cheating strncat(fileName, file.name(), 31); @@ -218,15 +217,15 @@ bool SysModFiles::readObjectFromFile(const char* path, JsonDocument* dest) { // if (doCloseFile) closeFile(); File f = open(path, "r"); if (!f) { - USER_PRINTF("File %s open not successful\n", path); + ppf("File %s open not successful\n", path); return false; } else { - USER_PRINTF(PSTR("File %s open to read, size %d bytes\n"), path, (int)f.size()); + ppf("File %s open to read, size %d bytes\n", path, (int)f.size()); DeserializationError error = deserializeJson(*dest, f, DeserializationOption::NestingLimit(20)); //StarMod requires more then 10 if (error) { print->printJDocInfo("readObjectFromFile", *dest); - USER_PRINTF("readObjectFromFile deserializeJson failed with code %s\n", error.c_str()); + ppf("readObjectFromFile deserializeJson failed with code %s\n", error.c_str()); f.close(); return false; } else { @@ -269,20 +268,4 @@ void SysModFiles::removeFiles(const char * filter, bool reverse) { } root.close(); -} - -bool SysModFiles::readFile(const char * path) { - File f = open(path, "r"); - if (f) { - - while(f.available()) { - Serial.print((char)f.read()); - } - Serial.println(); - - f.close(); - return true; - } - else - return false; -} +} \ No newline at end of file diff --git a/src/Sys/SysModFiles.h b/src/Sys/SysModFiles.h index 5cbc24b0..4885cf5a 100644 --- a/src/Sys/SysModFiles.h +++ b/src/Sys/SysModFiles.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysModFiles.h - @date 20240228 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -57,8 +57,6 @@ class SysModFiles: public SysModule { //remove files meeting filter condition, if no filter, all, if reverse then all but filter void removeFiles(const char * filter = nullptr, bool reverse = false); - bool readFile(const char * path); - }; extern SysModFiles *files; \ No newline at end of file diff --git a/src/Sys/SysModModel.cpp b/src/Sys/SysModModel.cpp index f1b7e6f6..e93604da 100644 --- a/src/Sys/SysModModel.cpp +++ b/src/Sys/SysModModel.cpp @@ -1,8 +1,8 @@ /* @title StarMod @file SysModModel.cpp - @date 20240228 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -20,7 +20,7 @@ SysModModel::SysModModel() :SysModule("Model") { JsonArray root = model->to(); //create - USER_PRINTF("Reading model from /model.json... (deserializeConfigFromFS)\n"); + ppf("Reading model from /model.json... (deserializeConfigFromFS)\n"); if (files->readObjectFromFile("/model.json", model)) {//not part of success... // print->printJson("Read model", *model); // web->sendDataWs(*model); @@ -60,7 +60,7 @@ void SysModModel::setup() { ui->initButton(parentVar, "deleteObsolete", false, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun case f_UIFun: ui->setLabel(var, "Delete obsolete variables"); - ui->setComment(var, "WIP"); + ui->setComment(var, "🚧"); return true; // case f_ChangeFun: // model->to(); //create @@ -82,7 +82,7 @@ void SysModModel::setup() { } if (doWriteModel) { - USER_PRINTF("Writing model to /model.json... (serializeConfig)\n"); + ppf("Writing model to /model.json... (serializeConfig)\n"); // files->writeObjectToFile("/model.json", model); @@ -118,7 +118,7 @@ void SysModModel::cleanUpModel(JsonObject parent, bool oPos, bool ro) { if (oPos) { if (var["o"].isNull() || varOrder(var) >= 0) { //not set negative in initVar if (!doShowObsolete) { - USER_PRINTF("cleanUpModel remove var %s (""o"">=0)\n", varID(var)); + ppf("cleanUpModel remove var %s (""o"">=0)\n", varID(var)); vars.remove(varV); //remove the obsolete var (no o or ) } } @@ -127,7 +127,7 @@ void SysModModel::cleanUpModel(JsonObject parent, bool oPos, bool ro) { } } else { //!oPos if (var["o"].isNull() || varOrder(var) < 0) { - USER_PRINTF("cleanUpModel remove var %s (""o""<0)\n", varID(var)); + ppf("cleanUpModel remove var %s (""o""<0)\n", varID(var)); vars.remove(varV); //remove the obsolete var (no o or o is negative - not cleanedUp) } } @@ -136,7 +136,7 @@ void SysModModel::cleanUpModel(JsonObject parent, bool oPos, bool ro) { //remove ro values (ro vars cannot be deleted as SM uses these vars) // remove if var is ro or table is instance table (exception here, values don't need to be saved) if (ro && (parent["id"] == "insTbl" || varRO(var))) {// && !var["value"].isNull()) - USER_PRINTF("remove ro value %s\n", varID(var)); + ppf("remove ro value %s\n", varID(var)); var.remove("value"); } @@ -165,7 +165,7 @@ JsonObject SysModModel::findVar(const char * id, JsonArray parent) { JsonObject foundVar = findVar(id, var["n"]); if (!foundVar.isNull()) { if (modelParentVar.isNull()) modelParentVar = var; //only recursive lowest assigns parentVar - // USER_PRINTF("findvar parent of %s is %s\n", id, varID(modelParentVar)); + // ppf("findvar parent of %s is %s\n", id, varID(modelParentVar)); return foundVar; } } diff --git a/src/Sys/SysModModel.h b/src/Sys/SysModModel.h index 3c92b90f..0b16e1ab 100644 --- a/src/Sys/SysModModel.h +++ b/src/Sys/SysModModel.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysModModel.h - @date 20240228 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -36,7 +36,7 @@ struct Coord3D { //comparisons bool operator!=(Coord3D rhs) { - // USER_PRINTF("Coord3D compare%d %d %d %d %d %d\n", x, y, z, rhs.x, rhs.y, rhs.z); + // ppf("Coord3D compare%d %d %d %d %d %d\n", x, y, z, rhs.x, rhs.y, rhs.z); // return x != rhs.x || y != rhs.y || z != rhs.z; return !(*this==rhs); } @@ -58,7 +58,7 @@ struct Coord3D { //assignments Coord3D operator=(Coord3D rhs) { - // USER_PRINTF("Coord3D assign %d,%d,%d\n", rhs.x, rhs.y, rhs.z); + // ppf("Coord3D assign %d,%d,%d\n", rhs.x, rhs.y, rhs.z); x = rhs.x; y = rhs.y; z = rhs.z; @@ -136,12 +136,12 @@ namespace ArduinoJson { dst["x"] = src.x; dst["y"] = src.y; dst["z"] = src.z; - // USER_PRINTF("Coord3D toJson %d,%d,%d -> %s\n", src.x, src.y, src.z, dst.as().c_str()); + // ppf("Coord3D toJson %d,%d,%d -> %s\n", src.x, src.y, src.z, dst.as().c_str()); return true; } static Coord3D fromJson(JsonVariantConst src) { - // USER_PRINTF("Coord3D fromJson %s\n", src.as().c_str()); + // ppf("Coord3D fromJson %s\n", src.as().c_str()); return Coord3D{src["x"], src["y"], src["z"]}; } @@ -200,7 +200,7 @@ class SysModModel:public SysModule { return setValue(var, value, rowNr); } else { - USER_PRINTF("setValue Var %s not found\n", id); + ppf("setValue Var %s not found\n", id); return JsonObject(); } } @@ -212,16 +212,19 @@ class SysModModel:public SysModule { if (rowNr == UINT8_MAX) { //normal situation if (var["value"].isNull() || var["value"].as() != value) { //const char * will be JsonString so comparison works - JsonString oldValue = JsonString(var["value"], JsonString::Copied); + if (!var["value"].isNull() && !varRO(var)) var["oldValue"] = var["value"]; var["value"] = value; //trick to remove null values if (var["value"].isNull() || var["value"].as() == UINT16_MAX) { var.remove("value"); - if (oldValue.size()>0) - USER_PRINTF("dev setValue value removed %s %s\n", varID(var), oldValue.c_str()); //old value + ppf("dev setValue value removed %s %s\n", varID(var), var["oldValue"].as().c_str()); } else { - USER_PRINTF("setValue changed %s %s -> %s\n", varID(var), oldValue.c_str(), var["value"].as().c_str()); //old value + //only print if ! read only + if (!varRO(var)) + ppf("setValue changed %s %s -> %s\n", varID(var), var["oldValue"].as().c_str(), var["value"].as().c_str()); + // else + // ppf("setValue changed %s %s\n", varID(var), var["value"].as().c_str()); web->addResponse(var["id"], "value", var["value"]); changed = true; } @@ -231,8 +234,7 @@ class SysModModel:public SysModule { //if we deal with multiple rows, value should be an array, if not we create one if (var["value"].isNull() || !var["value"].is()) { - USER_PRINTF("setValue var %s[%d] value %s not array, creating\n", varID(var), rowNr, var["value"].as().c_str()); - // print->printJson("setValueB var %s value %s not array, creating", id, var["value"].as().c_str()); + // ppf("setValue var %s[%d] value %s not array, creating\n", varID(var), rowNr, var["value"].as().c_str()); var["value"].to(); } @@ -246,15 +248,15 @@ class SysModModel:public SysModule { if (notSame) { // if (rowNr >= valueArray.size()) - // USER_PRINTF("notSame %d %d\n", rowNr, valueArray.size()); + // ppf("notSame %d %d\n", rowNr, valueArray.size()); valueArray[rowNr] = value; //if valueArray[().c_str()); + // ppf(" assigned %d %d %s\n", rowNr, valueArray.size(), valueArray[rowNr].as().c_str()); web->addResponse(var["id"], "value", var["value"]); //send the whole array to UI as response is in format value: !! changed = true; } } else { - USER_PRINTF("setValue %s could not create value array\n", varID(var)); + ppf("setValue %s could not create value array\n", varID(var)); } } @@ -273,7 +275,7 @@ class SysModModel:public SysModule { va_end(args); - USER_PRINTF("setValueV %s[%d] = %s\n", id, rowNr, value); + ppf("setValueV %s[%d] = %s\n", id, rowNr, value); return setValue(id, JsonString(value, JsonString::Copied), rowNr); } @@ -296,7 +298,7 @@ class SysModModel:public SysModule { return getValue(var, rowNr); } else { - // USER_PRINTF("getValue: Var %s does not exist!!\n", id); + // ppf("getValue: Var %s does not exist!!\n", id); return JsonVariant(); } } @@ -307,10 +309,10 @@ class SysModModel:public SysModule { if (rowNr != UINT8_MAX && rowNr < valueArray.size()) return valueArray[rowNr]; else if (valueArray.size()) - return valueArray[0]; + return valueArray[0]; //return the first element else { - USER_PRINTF("dev getValue no array or rownr wrong %s %s %d\n", varID(var), var["value"].as().c_str(), rowNr); - return JsonVariant(); + ppf("dev getValue no array or rownr wrong %s %s %d\n", varID(var), var["value"].as().c_str(), rowNr); + return JsonVariant(); // return null } } else @@ -373,7 +375,9 @@ class SysModModel:public SysModule { } } setValueRowNr = rowNr; - print->printJson("varPreDetails post", var); + ppf("varPreDetails post "); + print->printVar(var); + ppf("\n"); } void varPostDetails(JsonObject var, unsigned8 rowNr) { @@ -381,21 +385,23 @@ class SysModModel:public SysModule { setValueRowNr = UINT8_MAX; if (rowNr != UINT8_MAX) { - print->printJson("varPostDetails pre", var); + ppf("varPostDetails pre "); + print->printVar(var); + ppf("\n"); //check if post init added: parent is already >=0 if (varOrder(var) >= 0) { - for (JsonArray::iterator childVar=varChildren(var).begin(); childVar!=varChildren(var).end(); ++childVar) { //use iterator to make .remove work!!! - JsonArray valArray = varValArray(*childVar); + // for (JsonArray::iterator childVar=varChildren(var).begin(); childVar!=varChildren(var).end(); ++childVar) { //use iterator to make .remove work!!! + for (JsonObject childVar: varChildren(var)) { //use iterator to make .remove work!!! + JsonArray valArray = varValArray(childVar); if (!valArray.isNull()) { - - if (varOrder(*childVar) < 0) { //if not updated + if (varOrder(childVar) < 0) { //if not updated valArray[rowNr] = (char*)0; // set element in valArray to 0 - USER_PRINTF("varPostDetails %s[%d] to null\n", varID(var), rowNr); + ppf("varPostDetails %s.%s[%d] <- null\n", varID(var), varID(childVar), rowNr); // setValue(var, -99, rowNr); //set value -99 - varOrder(*childVar, -varOrder(*childVar)); //make positive again + varOrder(childVar, -varOrder(childVar)); //make positive again //if some values in array are not -99 } @@ -406,18 +412,20 @@ class SysModModel:public SysModule { allNull = false; } if (allNull) { - print->printJson("remove allnulls", *childVar); + print->printJson("remove allnulls", childVar); varChildren(var).remove(childVar); } } else { - print->printJson("remove non valArray", *childVar); + print->printJson("remove non valArray", childVar); varChildren(var).remove(childVar); } } } //if new added - print->printJson("varPostDetails post", var); + ppf("varPostDetails post "); + print->printVar(var); + ppf("\n"); web->addResponse("details", "rowNr", rowNr); } diff --git a/src/Sys/SysModNetwork.cpp b/src/Sys/SysModNetwork.cpp index f2370812..41b599eb 100644 --- a/src/Sys/SysModNetwork.cpp +++ b/src/Sys/SysModNetwork.cpp @@ -1,8 +1,8 @@ /* @title StarMod @file SysModNetwork.cpp - @date 20240228 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -73,7 +73,7 @@ void SysModNetwork::loop1s() { void SysModNetwork::handleConnection() { if (lastReconnectAttempt == 0) { // do this only once - USER_PRINTF("lastReconnectAttempt == 0\n"); + ppf("lastReconnectAttempt == 0\n"); initConnection(); return; } @@ -85,18 +85,18 @@ void SysModNetwork::handleConnection() { //if not connected to Wifi if (!(WiFi.localIP()[0] != 0 && WiFi.status() == WL_CONNECTED)) { //!Network.isConfirmedConnection() if (isConfirmedConnection) { //should not be confirmed as not connected -> lost connection -> retry - USER_PRINTF("Disconnected!\n"); + ppf("Disconnected!\n"); initConnection(); } //if no connection for more then 6 seconds (was 12) if (!apActive && millis() - lastReconnectAttempt > 6000 ) { //&& (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN) - USER_PRINTF("Not connected AP.\n"); + ppf("Not connected AP.\n"); initAP(); } } else if (!isConfirmedConnection) { //newly connected mdl->setUIValueV("nwstatus", "Connected %d.%d.%d.%d", WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], WiFi.localIP()[3]); - USER_PRINTF("Connected %s\n", WiFi.localIP().toString().c_str()); + ppf("Connected %s\n", WiFi.localIP().toString().c_str()); isConfirmedConnection = true; @@ -126,26 +126,23 @@ void SysModNetwork::initConnection() { if (ssid && strlen(ssid)>0) { char passXXX [32] = ""; for (int i = 0; i < strlen(password); i++) strncat(passXXX, "*", sizeof(passXXX)-1); - USER_PRINTF("Connecting to WiFi %s / %s\n", ssid, passXXX); + ppf("Connecting to WiFi %s / %s\n", ssid, passXXX); WiFi.begin(ssid, password); #if defined(STARMOD_LOLIN_WIFI_FIX ) WiFi.setTxPower(WIFI_POWER_8_5dBm ); #endif WiFi.setSleep(false); - char hostname[25]; - prepareHostname(hostname, mdl->getValue("instanceName")); - USER_PRINTF("hostname %s\n", hostname); - WiFi.setHostname(hostname); + WiFi.setHostname(mdns->cmDNS); //use the mdns name (instance name or star-mac) } else - USER_PRINTF("No SSID"); + ppf("No SSID"); - isConfirmedConnection = false; //neet to test if really connected in handleConnection + isConfirmedConnection = false; //need to test if really connected in handleConnection } void SysModNetwork::initAP() { const char * apSSID = mdl->getValue("instanceName"); - USER_PRINTF("Opening access point %s\n", apSSID); + ppf("Opening access point %s\n", apSSID); WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0)); WiFi.softAP(apSSID, NULL, apChannel, false); //no password!!! #if defined(STARMOD_LOLIN_WIFI_FIX ) @@ -168,7 +165,7 @@ void SysModNetwork::stopAP() { dnsServer.stop(); WiFi.softAPdisconnect(true); apActive = false; - USER_PRINTF("Access point disabled (handle).\n"); + ppf("Access point disabled (handle).\n"); } void SysModNetwork::handleAP() { @@ -179,7 +176,7 @@ void SysModNetwork::handleAP() { if (stac != stacO) { stacO = stac; if (WiFi.status() != WL_CONNECTED) { - USER_PRINTF("Connected AP clients: %d %d\n", stac, WiFi.status()); + ppf("Connected AP clients: %d %d\n", stac, WiFi.status()); if (stac) WiFi.disconnect(); // disable search so that AP can work else diff --git a/src/Sys/SysModNetwork.h b/src/Sys/SysModNetwork.h index 2f7784d2..aca4e172 100644 --- a/src/Sys/SysModNetwork.h +++ b/src/Sys/SysModNetwork.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysModNetwork.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -24,29 +24,6 @@ class SysModNetwork:public SysModule { void loop1s(); - //tbd: utility function ... - void prepareHostname(char* hostname, const char *in) - { - const char *pC = in; - uint8_t pos = 0; - while (*pC && pos < 24) { // while !null and not over length - if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname - hostname[pos] = *pC; - pos++; - } else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') { - hostname[pos] = '-'; - pos++; - } - // else do nothing - no leading hyphens and do not include hyphens for all other characters. - pC++; - } - //last character must not be hyphen - if (pos > 5) { - while (pos > 4 && hostname[pos -1] == '-') pos--; - hostname[pos] = '\0'; // terminate string (leave at least "wled") - } - } - void handleConnection(); void initConnection(); diff --git a/src/Sys/SysModPins.cpp b/src/Sys/SysModPins.cpp index f998e223..39b16d03 100644 --- a/src/Sys/SysModPins.cpp +++ b/src/Sys/SysModPins.cpp @@ -1,8 +1,8 @@ /* @title StarMod @file SysModPins.cpp - @date 20240226 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -15,14 +15,6 @@ #include "SysModWeb.h" SysModPins::SysModPins() :SysModule("Pins") { -#if CONFIG_IDF_TARGET_ESP32 - // softhack007: configuring these pins on S3/C3/S2 may cause major problems (crashes included) - // pinMode(2, OUTPUT); // softhack007 default LED pin on some boards, so don't play around with gpio2 - pinMode(4, OUTPUT); - pinMode(19, OUTPUT); - pinMode(33, OUTPUT); -#endif - //start with no pins allocated for (int i=0; iinitText(tableVar, "pinDetails", nullptr, 256, true, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun case f_ValueFun: - for (forUnsigned8 rowNr = 0; rowNr < getNrOfAllocatedPins(); rowNr++) - USER_PRINTF("pinDetails[%d] d1:%s d2:%s\n", rowNr, getNthAllocatedPinObject(rowNr).details, pinObjects[0].details); + for (forUnsigned8 rowNr = 0; rowNr < getNrOfAllocatedPins(); rowNr++) { + // ppf("pinDetails[%d] d:%s\n", rowNr, getNthAllocatedPinObject(rowNr).details); mdl->setValue(var, JsonString(getNthAllocatedPinObject(rowNr).details, JsonString::Copied), rowNr); + } return true; case f_UIFun: ui->setLabel(var, "Details"); @@ -75,47 +68,59 @@ void SysModPins::setup() { default: return false; }}); - #ifdef STARMOD_DEVMODE - ui->initCanvas(parentVar, "board", UINT16_MAX, true, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun case f_UIFun: - ui->setLabel(var, "Board layout"); - ui->setComment(var, "WIP"); + ui->setLabel(var, "Pin viewer"); + ui->setComment(var, "🚧"); return true; case f_LoopFun: - var["interval"] = 10*10*10; //every 10 sec from cs to ms + var["interval"] = 100; //every 100 ms web->sendDataWs([](AsyncWebSocketMessageBuffer * wsBuf) { byte* buffer; buffer = wsBuf->get(); - // send leds preview to clients - for (size_t i = 0; i < 20; i++) + // send pins to clients + for (size_t pinNr = 0; pinNr < NUM_DIGITAL_PINS; pinNr++) { - buffer[i*3+5] = random(256);// (digitalRead(i)+1) * 50; - buffer[i*3+5+1] = random(256); - buffer[i*3+5+2] = random(256); + buffer[pinNr+5] = random(8);// digitalRead(pinNr) * 255; // is only 0 or 1 } + // ppf("\n"); //new values buffer[0] = 0; //userFun id - }, 20 * 3 + 5, true); + }, NUM_DIGITAL_PINS + 5, true); return true; default: return false; }}); - #endif //STARMOD_DEVMODE - // ui->initCheckBox(parentVar, "pin2", true, UINT8_MAX, false, nullptr, updateGPIO); - // ui->initCheckBox(parentVar, "pin4"); #if CONFIG_IDF_TARGET_ESP32 - ui->initCheckBox(parentVar, "pin19", true, false, updateGPIO); + // softhack007: configuring these pins on S3/C3/S2 may cause major problems (crashes included) + // pinMode(2, OUTPUT); // softhack007 default LED pin on some boards, so don't play around with gpio2 + allocatePin(19, "Pins", "Relais"); + pinMode(19, OUTPUT); //tbd: part of allocatePin? + + ui->initCheckBox(parentVar, "pin19", true, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun + case f_UIFun: + ui->setComment(var, "🚧 used for relais on Serg shields"); + return true; + case f_ChangeFun: { + bool pinValue = var["value"]; + + ppf("chFun pin19 %s:=%d\n", mdl->varID(var), pinValue); + + // softhack007: writing these pins on S3/C3/S2 may cause major problems (crashes included) + digitalWrite(19, pinValue?HIGH:LOW); + return true; } + default: return false; + }}); #endif - // ui->initCheckBox(parentVar, "pin33", true); } -void SysModPins::loop1s() { +void SysModPins::loop() { + if (pinsChanged) { pinsChanged = false; @@ -124,31 +129,11 @@ void SysModPins::loop1s() { } } -bool SysModPins::updateGPIO(JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_ChangeFun: - if (var["value"].is()) { - bool pinValue = var["value"]; - JsonString id = var["id"]; - - USER_PRINTF("updateGPIO %s:=%d\n", id.c_str(), pinValue); - -#if CONFIG_IDF_TARGET_ESP32 - // softhack007: writing these pins on S3/C3/S2 may cause major problems (crashes included) - // if (id == "pin2") digitalWrite(2, pinValue?HIGH:LOW); // softhack007 default LED pin on some boards, so don't play around with gpio2 - if (id == "pin4") digitalWrite(4, pinValue?HIGH:LOW); - if (id == "pin19") digitalWrite(19, pinValue?HIGH:LOW); - if (id == "pin33") digitalWrite(33, pinValue?HIGH:LOW); -#endif - } - return true; - default: return false; - }}; - void SysModPins::allocatePin(unsigned8 pinNr, const char * owner, const char * details) { - USER_PRINTF("allocatePin %d %s %s\n", pinNr, owner, details); + ppf("allocatePin %d %s %s\n", pinNr, owner, details); if ((pinNr < NUM_DIGITAL_PINS) && (digitalPinIsValid(pinNr))) { if (strcmp(pinObjects[pinNr].owner, "") != 0 && strcmp(pinObjects[pinNr].owner, owner) != 0) - USER_PRINTF("allocatePin %d: not owner %s!=%s", pinNr, owner, pinObjects[pinNr].owner); + ppf("allocatePin %d: not owner %s!=%s", pinNr, owner, pinObjects[pinNr].owner); else { strncpy(pinObjects[pinNr].owner, owner, sizeof(PinObject::owner)-1); strncpy(pinObjects[pinNr].details, details, sizeof(PinObject::details)-1); @@ -158,10 +143,10 @@ void SysModPins::allocatePin(unsigned8 pinNr, const char * owner, const char * d } void SysModPins::deallocatePin(unsigned8 pinNr, const char * owner) { - // USER_PRINTF("deallocatePin %d %s\n", pinNr, owner); + ppf("deallocatePin %d %s\n", pinNr, owner); if (pinNr < NUM_DIGITAL_PINS) { if (strcmp(pinObjects[pinNr].owner, owner) != 0) - USER_PRINTF("deallocatePin %d: not owner %s!=%s", pinNr, owner, pinObjects[pinNr].owner); + ppf("deallocatePin %d: not owner %s!=%s", pinNr, owner, pinObjects[pinNr].owner); else { strcpy(pinObjects[pinNr].owner, ""); strcpy(pinObjects[pinNr].details, ""); diff --git a/src/Sys/SysModPins.h b/src/Sys/SysModPins.h index 000fe399..78e81528 100644 --- a/src/Sys/SysModPins.h +++ b/src/Sys/SysModPins.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysModPins.h - @date 20240226 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -12,6 +12,12 @@ #pragma once #include "SysModule.h" +#define pinTypeIO 0 +#define pinTypeReadOnly 1 +#define pinTypeReserved 2 +#define pinTypeSpi 3 +#define pinTypeInvalid UINT8_MAX + //info stored per pin struct PinObject { char owner[32]; //if not "" then allocated (tbd: no use char) @@ -26,7 +32,7 @@ class SysModPins:public SysModule { SysModPins(); void setup(); - void loop1s(); + void loop(); void allocatePin(unsigned8 pinNr, const char * owner, const char * details); void deallocatePin(unsigned8 pinNr, const char * owner); @@ -69,9 +75,42 @@ class SysModPins:public SysModule { return UINT8_MAX; } - static bool updateGPIO(JsonObject var, unsigned8 rowNr, unsigned8 funType); - bool pinsChanged = false; //update pins table if pins changed + + uint8_t getPinType(uint8_t pinNr) { + uint8_t pinType; + if (digitalPinIsValid(pinNr)) { + + #if defined(CONFIG_IDF_TARGET_ESP32S2) + if ((pinNr > 18 && pinNr < 21) || (pinNr > 21 && pinNr < 33)) pinType = pinTypeReserved; else + #elif defined(CONFIG_IDF_TARGET_ESP32S3) + if ((pinNr > 18 && pinNr < 21) || (pinNr > 21 && pinNr < 33)) pinType = pinTypeReserved; else + #elif defined(CONFIG_IDF_TARGET_ESP32C3) + if ((pinNr > 11 && pinNr < 18) || (pinNr > 17 && pinNr < 20)) pinType = pinTypeReserved; else + #elif defined(ESP32) + if (pinNr > 5 && pinNr < 12) pinType = pinTypeReserved; else + #else //??? + pinType = pinTypeInvalid; return pinType; + #endif + + if (!digitalPinCanOutput(pinNr)) + pinType = pinTypeReadOnly; + else + pinType = pinTypeIO; + + //results in crashes + // if (digitalPinToRtcPin(pinNr)) pinType = pinTypeIO; else pinType = pinTypeInvalid; //error: 'RTC_GPIO_IS_VALID_GPIO' was not declared in this scope + // if (digitalPinToDacChannel(pinNr)) pinType = pinTypeIO; else pinType = pinTypeInvalid; //error: 'DAC_CHANNEL_1_GPIO_NUM' was not declared in this scope + + //not so relevant + // if (digitalPinToAnalogChannel(pinNr)) pinType = pinTypeInvalid; + // if (digitalPinToTouchChannel(pinNr)) pinType = pinTypeInvalid; + } + else + pinType = pinTypeInvalid; + + return pinType; + } }; extern SysModPins *pins; \ No newline at end of file diff --git a/src/Sys/SysModPrint.cpp b/src/Sys/SysModPrint.cpp index 296f344b..373fc529 100644 --- a/src/Sys/SysModPrint.cpp +++ b/src/Sys/SysModPrint.cpp @@ -1,8 +1,8 @@ /* @title StarMod @file SysModPrint.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -60,7 +60,6 @@ void SysModPrint::setup() { case f_UIFun: { ui->setLabel(var, "Output"); - ui->setComment(var, "System log to Serial or Net print (WIP)"); JsonArray options = ui->setOptions(var); options.add("No"); @@ -73,12 +72,7 @@ void SysModPrint::setup() { default: return false; }}); - ui->initTextArea(parentVar, "log", "WIP", true, [](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setComment(var, "Show the printed log"); - return true; - default: return false; - }}); + ui->initTextArea(parentVar, "log"); } void SysModPrint::loop() { @@ -86,84 +80,70 @@ void SysModPrint::loop() { if (!setupsDone) setupsDone = true; } -size_t SysModPrint::print(const char * format, ...) { +void SysModPrint::printf(const char * format, ...) { va_list args; va_start(args, format); - - //tbd: print to UI (crashes because of recursive calls to print in setUIValueV... - // unsigned8 pOut = mdl->getValue("pOut"); - // if (pOut == 2) { - // Serial.println(format); - // char value[1024]; - // vsnprintf(value, sizeof(value)-1, format, args); - // mdl->setUIValueV("log", "%s", format); - // va_end(args); - // return 1; - // } - - Serial.print(strncmp(pcTaskGetTaskName(NULL), "loopTask", 8) == 0?"":"α"); //looptask λ/ asyncTCP task α - - for (size_t i = 0; i < strlen(format); i++) - { - if (format[i] == '%') - { - switch (format[i+1]) - { - case 's': - Serial.print(va_arg(args, const char *)); - break; - case 'u': - Serial.print(va_arg(args, unsigned int)); - break; - case 'c': - Serial.print(va_arg(args, int)); - break; - case 'd': - Serial.print(va_arg(args, int)); - break; - case 'f': - Serial.print(va_arg(args, double)); - break; - case '%': - Serial.print("%"); // in case of %% - break; - default: - va_arg(args, int); - // logFile.print(x); - Serial.print(format[i]); - Serial.print(format[i+1]); - } - i++; - } - else - { - Serial.print(format[i]); + // Serial.print(strncmp(pcTaskGetTaskName(NULL), "loopTask", 8) == 0?"":"α"); //looptask λ/ asyncTCP task α + + unsigned8 pOut = 1; //default serial + char value[1024]; + vsnprintf(value, sizeof(value)-1, format, args); + if (mdls->isConnected) { + if (mdl->model) + pOut = mdl->getValue("pOut"); + + if (pOut == 1) + Serial.print(value); + else if (pOut == 2) { + JsonObject responseObject = web->getResponseObject(); + if (responseObject["log"]["value"].isNull()) + responseObject["log"]["value"] = value; + else + responseObject["log"]["value"] = responseObject["log"]["value"].as() + String(value); + // web->addResponse("log", "value", JsonString(value, JsonString::Copied)); //setValue not necessary + // mdl->setUIValueV("log", "%s", value); + } + else if (pOut == 3) { + //tbd } } + else + Serial.print(value); va_end(args); - return 1; } -size_t SysModPrint::println(const __FlashStringHelper * x) { - return Serial.println(x); +void SysModPrint::println(const __FlashStringHelper * x) { + printf("%s\n", x); } void SysModPrint::printVar(JsonObject var) { - char sep[3] = ""; + char sep[3] = " "; for (JsonPair pair: var) { - print("%s%s: %s", sep, pair.key(), pair.value().as().c_str()); - strcpy(sep, ", "); + if (pair.key() == "id") { + printf("%s%s", sep, pair.value().as().c_str()); + strcpy(sep, ", "); + } + else if (pair.key() == "value") { + printf(":%s", pair.value().as().c_str()); + } + else if (pair.key() == "n") { + printf("["); + for (JsonObject childVar: mdl->varChildren(var)) { + printVar(childVar); + } + printf("]"); + } } } -size_t SysModPrint::printJson(const char * text, JsonVariantConst source) { - print("%s ", text); - size_t size = serializeJson(source, Serial); //for the time being - Serial.println(); - return size; +void SysModPrint::printJson(const char * text, JsonVariantConst source) { + char resStr[1024]; + serializeJson(source, resStr, sizeof(resStr)); + + printf("%s %s\n", text, resStr); } size_t SysModPrint::fFormat(char * buf, size_t size, const char * format, ...) { @@ -180,5 +160,5 @@ size_t SysModPrint::fFormat(char * buf, size_t size, const char * format, ...) { } void SysModPrint::printJDocInfo(const char * text, JsonDocument source) { - print("%s (s:%u o:%u n:%u)\n", text, source.size(), source.overflowed(), source.nesting()); + printf("%s (s:%u o:%u n:%u)\n", text, source.size(), source.overflowed(), source.nesting()); } \ No newline at end of file diff --git a/src/Sys/SysModPrint.h b/src/Sys/SysModPrint.h index 9d7727f5..9abecc3a 100644 --- a/src/Sys/SysModPrint.h +++ b/src/Sys/SysModPrint.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysModPrint.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -12,10 +12,10 @@ #pragma once #include "SysModule.h" -#define USER_PRINTF(x...) print->print(x) -#define USER_PRINT_FUNCTION(x...) //print->print(x) -#define USER_PRINT_NOT(x...) //print->print(x) -#define USER_PRINT_Async(x...) print->print(x) +#define ppf(x...) print->printf(x) +// #define ppf(x...) //to have no print code compiled, difference is only 6308 bytes +// Flash: [====== ] 62.8% (used 1194250 bytes from 1900544 bytes) +// Flash: [====== ] 63.2% (used 1200558 bytes from 1900544 bytes) class SysModPrint:public SysModule { @@ -25,14 +25,16 @@ class SysModPrint:public SysModule { void setup(); void loop(); - //generic print function (based on printf) - size_t print(const char * format, ...); + //generic print function + void printf(const char * format, ...); - size_t println(const __FlashStringHelper * x); + //not used yet + void println(const __FlashStringHelper * x); + //print var as id:value + [childVars recursively] void printVar(JsonObject var); - size_t printJson(const char * text, JsonVariantConst source); + void printJson(const char * text, JsonVariantConst source); size_t fFormat(char * buf, size_t size, const char * format, ...); diff --git a/src/Sys/SysModSystem.cpp b/src/Sys/SysModSystem.cpp index d79b8af5..b82d8d8e 100644 --- a/src/Sys/SysModSystem.cpp +++ b/src/Sys/SysModSystem.cpp @@ -1,8 +1,8 @@ /* @title StarMod @file SysModSystem.cpp - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -14,6 +14,8 @@ #include "SysModUI.h" #include "SysModWeb.h" #include "SysModModel.h" +#include "SysModNetwork.h" +#include "User/UserModMDNS.h" // #include @@ -39,11 +41,18 @@ void SysModSystem::setup() { parentVar = ui->initSysMod(parentVar, name, 2000); parentVar["s"] = true; //setup - ui->initText(parentVar, "instanceName", "StarMod", 32, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun + ui->initText(parentVar, "instanceName", _INIT(TOSTRING(APP)), 32, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun case f_UIFun: ui->setLabel(var, "Name"); ui->setComment(var, "Instance name"); return true; + case f_ChangeFun: + char instanceName[25]; + removeInvalidCharacters(instanceName, var["value"]); + ppf("instanceName stripped %s\n", instanceName); + mdl->setValue(mdl->varID(var), JsonString(instanceName, JsonString::Copied)); + mdns->resetMDNS(); // set the new name for mdns + return true; default: return false; }}); @@ -154,16 +163,22 @@ void SysModSystem::setup() { //calculate version in format YYMMDDHH //https://forum.arduino.cc/t/can-you-format-__date__/200818/10 - int month, day, year, hour, minute, second; - const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; - sscanf(__DATE__, "%s %d %d", version, &day, &year); // Mon dd yyyy - month = (strstr(month_names, version)-month_names)/3+1; - sscanf(__TIME__, "%d:%d:%d", &hour, &minute, &second); //hh:mm:ss - print->fFormat(version, sizeof(version)-1, "%02d%02d%02d%02d", year-2000, month, day, hour); - - USER_PRINTF("version %s %s %s %d:%d:%d\n", version, __DATE__, __TIME__, hour, minute, second); - - ui->initText(parentVar, "version", version, 16, true); + // int month, day, year, hour, minute, second; + // const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; + // sscanf(__DATE__, "%s %d %d", version, &day, &year); // Mon dd yyyy + // month = (strstr(month_names, version)-month_names)/3+1; + // sscanf(__TIME__, "%d:%d:%d", &hour, &minute, &second); //hh:mm:ss + // print->fFormat(version, sizeof(version)-1, "%02d%02d%02d%02d", year-2000, month, day, hour); + + // ppf("version %s %s %s %d:%d:%d\n", version, __DATE__, __TIME__, hour, minute, second); + + strcat(build, _INIT(TOSTRING(APP))); + strcat(build, "_"); + strcat(build, _INIT(TOSTRING(VERSION))); + strcat(build, "_"); + strcat(build, _INIT(TOSTRING(PIOENV))); + + ui->initText(parentVar, "build", build, 32, true); // ui->initText(parentVar, "date", __DATE__, 16, true); // ui->initText(parentVar, "time", __TIME__, 16, true); @@ -211,7 +226,7 @@ void SysModSystem::loop10s() { if (psramFound()) { ui->callVarFun(mdl->findVar("psram")); } - USER_PRINTF("❤️"); //heartbeat + ppf("❤️"); //heartbeat } //replace code by sentence as soon it occurs, so we know what will happen and what not diff --git a/src/Sys/SysModSystem.h b/src/Sys/SysModSystem.h index 3d452fb9..ad250c9e 100644 --- a/src/Sys/SysModSystem.h +++ b/src/Sys/SysModSystem.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysModSystem.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -16,7 +16,7 @@ class SysModSystem:public SysModule { public: - char version[16] = ""; + char build[64] = ""; char chipInfo[64] = ""; SysModSystem(); @@ -33,6 +33,29 @@ class SysModSystem:public SysModule { int sysTools_get_arduino_maxStackUsage(void); // to query max used stack of the arduino task. returns "-1" if unknown int sysTools_get_webserver_maxStackUsage(void); // to query max used stack of the webserver task. returns "-1" if unknown + //tbd: utility function ... (pka prepareHostname) + void removeInvalidCharacters(char* hostname, const char *in) + { + const char *pC = in; + uint8_t pos = 0; + while (*pC && pos < 24) { // while !null and not over length + if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname + hostname[pos] = *pC; + pos++; + } else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') { + hostname[pos] = '-'; + pos++; + } + // else do nothing - no leading hyphens and do not include hyphens for all other characters. + pC++; + } + //last character must not be hyphen + if (pos > 5) { + while (pos > 4 && hostname[pos -1] == '-') pos--; + hostname[pos] = '\0'; // terminate string (leave at least "wled") + } + } + private: unsigned long loopCounter = 0; diff --git a/src/Sys/SysModUI.cpp b/src/Sys/SysModUI.cpp index 720aa8ec..c969b17f 100644 --- a/src/Sys/SysModUI.cpp +++ b/src/Sys/SysModUI.cpp @@ -1,8 +1,8 @@ /* @title StarMod @file SysModUI.cpp - @date 20240228 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -63,14 +63,14 @@ void SysModUI::loop() { varLoop.loopFun(varLoop.var, 1, f_LoopFun); //rowNr.. varLoop.counter++; - // USER_PRINTF("%s %u %u %d %d\n", varLoop->mdl->varID(var), varLoop->lastMillis, millis(), varLoop->interval, varLoop->counter); + // ppf("%s %u %u %d %d\n", varLoop->mdl->varID(var), varLoop->lastMillis, millis(), varLoop->interval, varLoop->counter); } } } void SysModUI::loop1s() { //if something changed in vloops - ui->callVarFun("vlLoopps", UINT8_MAX, f_ValueFun); + callVarFun("vlLoopps", UINT8_MAX, f_ValueFun); for (VarLoop &varLoop : loopFunctions) varLoop.counter = 0; } @@ -83,12 +83,12 @@ JsonObject SysModUI::initVar(JsonObject parent, const char * id, const char * ty bool differentParents = modelParentId != nullptr && parentId != nullptr && strcmp(modelParentId, parentId) != 0; //!mdl->modelParentVar.isNull() && !parent.isNull() && mdl->modelParentVar["id"] != parent["id"]; if (differentParents) { - USER_PRINTF("initVar parents not equal %s: %s != %s\n", id, modelParentId, parentId); + ppf("initVar parents not equal %s: %s != %s\n", id, modelParentId, parentId); } //create new var if (differentParents || var.isNull()) { - USER_PRINTF("initVar create new %s var: %s->%s\n", type, parentId, id); + ppf("initVar new %s var: %s->%s\n", type, parentId?parentId:"", id); //parentId not null otherwise crash if (parent.isNull()) { JsonArray vars = mdl->model->as(); var = vars.add(); @@ -100,13 +100,13 @@ JsonObject SysModUI::initVar(JsonObject parent, const char * id, const char * ty var["id"] = JsonString(id, JsonString::Copied); } // else { - // USER_PRINTF("initVar Var %s->%s already defined\n", modelParentId, id); + // ppf("initVar Var %s->%s already defined\n", modelParentId, id); // } if (!var.isNull()) { if (var["type"].isNull() || var["type"] != type) { var["type"] = JsonString(type, JsonString::Copied); - print->printJson("initVar set type", var); + // print->printJson("initVar set type", var); } if (var["ro"].isNull() || mdl->varRO(var) != readOnly) mdl->varRO(var, readOnly); @@ -135,12 +135,12 @@ JsonObject SysModUI::initVar(JsonObject parent, const char * id, const char * ty loopFunctions.push_back(loop); var["loopFun"] = loopFunctions.size()-1; - // USER_PRINTF("iObject loopFun %s %u %u %d %d\n", mdl->varID(var)); + // ppf("iObject loopFun %s %u %u %d %d\n", mdl->varID(var)); } } } else - USER_PRINTF("initVar could not find or create var %s with %s\n", id, type); + ppf("initVar could not find or create var %s with %s\n", id, type); return var; } @@ -161,11 +161,11 @@ void SysModUI::processJson(JsonVariant json) { // commands if (pair.key() == "v") { //when called from jsonHandler // do nothing as it is no real var but the verbose command of WLED - USER_PRINTF("processJson v type %s\n", pair.value().as().c_str()); + ppf("processJson v type %s\n", pair.value().as().c_str()); } else if (pair.key() == "view" || pair.key() == "canvasData" || pair.key() == "theme") { //save the chosen view in System (see index.js) JsonObject var = mdl->findVar("System"); - USER_PRINTF("processJson %s v:%s n: %d s:%s\n", pair.key().c_str(), pair.value().as().c_str(), var.isNull(), mdl->varID(var)); + ppf("processJson %s v:%s n: %d s:%s\n", pair.key().c_str(), pair.value().as().c_str(), var.isNull(), mdl->varID(var)); var[JsonString(key, JsonString::Copied)] = JsonString(value, JsonString::Copied); //this is needed as key can become a dangling pointer // json.remove(key); //key should stay as all clients use this to perform the changeHTML action } @@ -174,7 +174,7 @@ void SysModUI::processJson(JsonVariant json) { JsonObject command = value; JsonObject var = mdl->findVar(command["id"]); stackUnsigned8 rowNr = command["rowNr"]; - USER_PRINTF("processJson %s - %s [%d]\n", key, value.as().c_str(), rowNr); + ppf("processJson %s - %s [%d]\n", key, value.as().c_str(), rowNr); //first remove the deleted row both on server and on client(s) if (pair.key() == "delRow") { @@ -199,10 +199,10 @@ void SysModUI::processJson(JsonVariant json) { //sendDataWs done in caller of processJson } else - USER_PRINTF("dev processJson Command %s var %s not found\n", key, varInArray.as().c_str()); + ppf("dev processJson Command %s var %s not found\n", key, varInArray.as().c_str()); } } else - USER_PRINTF("dev processJson value not array? %s %s\n", key, value.as().c_str()); + ppf("dev processJson value not array? %s %s\n", key, value.as().c_str()); json.remove(key); //key processed we don't need the key in the response } else if (!value.isNull()) { // {"varid": {"value":value}} or {"varid": value} @@ -223,13 +223,13 @@ void SysModUI::processJson(JsonVariant json) { JsonObject var = mdl->findVar(key); - USER_PRINTF("processJson var %s[%d] %s -> %s\n", key, rowNr, var["value"].as().c_str(), newValue.as().c_str()); + ppf("processJson var %s[%d] %s -> %s\n", key, rowNr, var["value"].as().c_str(), newValue.as().c_str()); if (!var.isNull()) { //a button never sets the value if (var["type"] == "button") { //button always - ui->callVarFun(var, rowNr, f_ChangeFun); + callVarFun(var, rowNr, f_ChangeFun); if (rowNr != UINT8_MAX) web->getResponseObject()[mdl->varID(var)]["rowNr"] = rowNr; } else { @@ -243,10 +243,10 @@ void SysModUI::processJson(JsonVariant json) { // json.remove(key); //key / var["id"] processed we don't need the key in the response } else - USER_PRINTF("dev Object %s[%d] not found\n", key, rowNr); + ppf("dev Object %s[%d] not found\n", key, rowNr); } else { - USER_PRINTF("dev processJson command not recognized k:%s v:%s\n", key, value.as().c_str()); + ppf("dev processJson command not recognized k:%s v:%s\n", key, value.as().c_str()); } } //for json pairs } diff --git a/src/Sys/SysModUI.h b/src/Sys/SysModUI.h index afdd678f..f3aed0ef 100644 --- a/src/Sys/SysModUI.h +++ b/src/Sys/SysModUI.h @@ -2,7 +2,7 @@ @title StarMod @file SysModUI.h @date 20240227 - @repo https://github.com/ewowi/StarMod + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -193,7 +193,7 @@ class SysModUI: public SysModule { } if (changeFunExists) - USER_PRINTF("initVarAndUpdate chFun init %s[x] <- %s\n", mdl->varID(var), var["value"].as().c_str()); + ppf("initVarAndUpdate chFun init %s[x] <- %s\n", mdl->varID(var), var["value"].as().c_str()); } } @@ -214,20 +214,20 @@ class SysModUI: public SysModule { size_t funNr = var["fun"]; if (funNr < varFunctions.size()) { result = varFunctions[funNr](var, rowNr, funType); - // if (result) { //send rowNr = 0 if no rowNr - // //only print vars with a value - // if (!var["value"].isNull() && funType != f_ValueFun) { - // if (var["id"] == "fixFirst") { - // USER_PRINTF("%sFun %s", funType==f_ValueFun?"val":funType==f_UIFun?"ui":funType==f_ChangeFun?"ch":funType==f_AddRow?"add":funType==f_DelRow?"del":"other", mdl->varID(var)); - // if (rowNr != UINT8_MAX) - // USER_PRINTF("[%d] = %s\n", rowNr, var["value"][rowNr].as().c_str()); - // else - // USER_PRINTF(" = %s\n", var["value"].as().c_str()); - // } - // } + if (result && !mdl->varRO(var)) { //send rowNr = 0 if no rowNr + //only print vars with a value and not valuefun as that changes a lot due to insTbl clTbl etc (tbd) + // if (!var["value"].isNull() && + if (funType != f_ValueFun) { + ppf("%sFun %s", funType==f_ValueFun?"val":funType==f_UIFun?"ui":funType==f_ChangeFun?"ch":funType==f_AddRow?"add":funType==f_DelRow?"del":"other", mdl->varID(var)); + if (rowNr != UINT8_MAX) + ppf("[%d] = %s\n", rowNr, var["value"][rowNr].as().c_str()); + else + ppf(" = %s\n", var["value"].as().c_str()); + } + } } else - USER_PRINTF("dev callVarFun function nr %s outside bounds %d >= %d\n", mdl->varID(var), funNr, varFunctions.size()); + ppf("dev callVarFun function nr %s outside bounds %d >= %d\n", mdl->varID(var), funNr, varFunctions.size()); } //for ro variables, call valueFun to add also the value in responseDoc (as it is not stored in the model) @@ -238,13 +238,13 @@ class SysModUI: public SysModule { return result; } - // assuming ui->callVarFun(varID, UINT8_MAX, f_UIFun); has been called before + // assuming callVarFun(varID, UINT8_MAX, f_UIFun); has been called before uint8_t selectOptionToValue(const char *varID, const char *label) { JsonArray options = web->getResponseObject()[varID]["options"]; - // USER_PRINTF("selectOptionToValue fileName %s %s\n", label, options[0].as().c_str()); + // ppf("selectOptionToValue fileName %s %s\n", label, options[0].as().c_str()); uint8_t value = 0; for (JsonVariant option: options) { - // USER_PRINTF("selectOptionToValue fileName2 %s %s\n", label, option.as().c_str()); + // ppf("selectOptionToValue fileName2 %s %s\n", label, option.as().c_str()); if (strstr(option, label) != nullptr) //if label part of value return value; value++; diff --git a/src/Sys/SysModWeb.cpp b/src/Sys/SysModWeb.cpp index bb92a2ad..77071207 100644 --- a/src/Sys/SysModWeb.cpp +++ b/src/Sys/SysModWeb.cpp @@ -1,8 +1,8 @@ /* @title StarMod @file SysModWeb.cpp - @date 20240228 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -14,6 +14,7 @@ #include "SysModUI.h" #include "SysModFiles.h" #include "SysModules.h" +#include "SysModPins.h" #include "User/UserModMDNS.h" @@ -157,7 +158,7 @@ void SysModWeb::loop() { if (clientsChanged) { clientsChanged = false; - USER_PRINTF("SysModWeb clientsChanged\n"); + // ppf("SysModWeb clientsChanged\n"); for (JsonObject childVar: mdl->varChildren("clTbl")) ui->callVarFun(childVar, UINT8_MAX, f_ValueFun); } @@ -187,7 +188,7 @@ void SysModWeb::loop1s() { } void SysModWeb::reboot() { - USER_PRINTF("SysModWeb reboot\n"); + ppf("SysModWeb reboot\n"); ws.closeAll(1012); } @@ -221,13 +222,13 @@ void SysModWeb::connectedChanged() { server.on("/upload", HTTP_POST, [](WebRequest *) {}, [this](WebRequest *request, const String& filename, size_t index, byte *data, size_t len, bool final) {serveUpload(request, filename, index, data, len, final);}); server.onNotFound([this](AsyncWebServerRequest *request) { - USER_PRINTF("Not-Found HTTP call: URI: %s\n", request->url().c_str()); ///hotspot-detect.html + ppf("Not-Found HTTP call: URI: %s\n", request->url().c_str()); ///hotspot-detect.html if (this->captivePortal(request)) return; }); - // USER_PRINTF("%s server (re)started\n", name); //causes crash for some reason... - USER_PRINTF("server (re)started\n"); + // ppf("%s server (re)started\n", name); //causes crash for some reason... + ppf("server (re)started\n"); } //else remove handlers... } @@ -240,13 +241,21 @@ void SysModWeb::connectedChanged() { // https://github.com/me-no-dev/ESPAsyncWebServer/blob/master/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino void SysModWeb::wsEvent(WebSocket * ws, WebClient * client, AwsEventType type, void * arg, byte *data, size_t len){ - // if (!ws.count()) { - // USER_PRINT_Async("wsEvent no clients\n"); - // return; - // } + if (type == WS_EVT_CONNECT) { printClient("WS client connected", client); + //send system constants + getResponseObject()["sysInfo"]["board"] = CONFIG_IDF_TARGET; + getResponseObject()["sysInfo"]["nrOfPins"] = NUM_DIGITAL_PINS; + getResponseObject()["sysInfo"]["pinTypes"].to(); + JsonArray pinTypes = getResponseObject()["sysInfo"]["pinTypes"]; + for (int i=0; igetPinType(i)); + } + + sendResponseObject(client); + JsonArray model = mdl->model->as(); //inspired by https://github.com/bblanchon/ArduinoJson/issues/1280 @@ -274,7 +283,7 @@ void SysModWeb::wsEvent(WebSocket * ws, WebClient * client, AwsEventType type, v } else if (type == WS_EVT_DATA) { AwsFrameInfo * info = (AwsFrameInfo*)arg; String msg = ""; - // USER_PRINT_Async(" info %d %d %d=%d? %d %d\n", info->final, info->index, info->len, len, info->opcode, data[0]); + // ppf(" info %d %d %d=%d? %d %d\n", info->final, info->index, info->len, len, info->opcode, data[0]); if (info->final && info->index == 0 && info->len == len) { //not multipart recvWsCounter++; recvWsBytes+=len; @@ -286,26 +295,26 @@ void SysModWeb::wsEvent(WebSocket * ws, WebClient * client, AwsEventType type, v // application layer ping/pong heartbeat. // client-side socket layer ping packets are unresponded (investigate) // printClient("WS client pong", client); //crash? - USER_PRINT_Async("pong\n"); + ppf("pong\n"); client->text("pong"); } else { - JsonDocument *responseDoc = web->getResponseDoc(); //we need the doc for deserializeJson - JsonObject responseObject = web->getResponseObject(); + JsonDocument *responseDoc = getResponseDoc(); //we need the doc for deserializeJson + JsonObject responseObject = getResponseObject(); DeserializationError error = deserializeJson(*responseDoc, data, len); //data to responseDoc if (error || responseObject.isNull()) { - USER_PRINT_Async("wsEvent deserializeJson failed with code %s\n", error.c_str()); + ppf("wsEvent deserializeJson failed with code %s\n", error.c_str()); client->text("{\"success\":true}"); // we have to send something back otherwise WS connection closes } else { bool isUiFun = !responseObject["uiFun"].isNull(); ui->processJson(responseObject); //adds to responseDoc / responseObject if (responseObject.size()) { - web->sendResponseObject(isUiFun?client:nullptr); //uiFun only send to requesting client async response + sendResponseObject(isUiFun?client:nullptr); //uiFun only send to requesting client async response } else { - USER_PRINT_Async("WS_EVT_DATA no responseDoc\n"); + ppf("WS_EVT_DATA no responseDoc\n"); client->text("{\"success\":true}"); // we have to send something back otherwise WS connection closes } } @@ -315,13 +324,13 @@ void SysModWeb::wsEvent(WebSocket * ws, WebClient * client, AwsEventType type, v //message is comprised of multiple frames or the frame is split into multiple packets if(info->index == 0){ // if(info->num == 0) - // USER_PRINT_Async("ws[%s][%u] %s-message start\n", ws.url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - // USER_PRINT_Async("ws[%s][%u] frame[%u] start[%llu]\n", ws.url(), client->id(), info->num, info->len); - USER_PRINTF("💀"); + // ppf("ws[%s][%u] %s-message start\n", ws.url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + // ppf("ws[%s][%u] frame[%u] start[%llu]\n", ws.url(), client->id(), info->num, info->len); + ppf("💀"); } - // USER_PRINT_Async("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", ws.url(), client->id(), info->num, (info->message_opcode == WS_TEXT)?"text":"binary", info->index, info->index + len); - USER_PRINTF("💀"); + // ppf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", ws.url(), client->id(), info->num, (info->message_opcode == WS_TEXT)?"text":"binary", info->index, info->index + len); + ppf("💀"); if(info->opcode == WS_TEXT){ for (size_t i=0; i < len; i++) { @@ -335,14 +344,14 @@ void SysModWeb::wsEvent(WebSocket * ws, WebClient * client, AwsEventType type, v // msg += buff ; // } // } - USER_PRINT_Async("%s\n",msg.c_str()); + ppf("%s\n",msg.c_str()); if ((info->index + len) == info->len) { - // USER_PRINT_Async("ws[%s][%u] frame[%u] end[%llu]\n", ws.url(), client->id(), info->num, info->len); - USER_PRINTF("👻"); + // ppf("ws[%s][%u] frame[%u] end[%llu]\n", ws.url(), client->id(), info->num, info->len); + ppf("👻"); if(info->final){ - // USER_PRINT_Async("ws[%s][%u] %s-message end\n", ws.url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - USER_PRINTF("☠️"); + // ppf("ws[%s][%u] %s-message end\n", ws.url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + ppf("☠️"); if(info->message_opcode == WS_TEXT) client->text("I got your text message"); else @@ -364,23 +373,23 @@ void SysModWeb::wsEvent(WebSocket * ws, WebClient * client, AwsEventType type, v // if(info->final){ // if(info->message_opcode == WS_TEXT) { // client->text("{\"error\":9}"); //we do not handle split packets right now - // USER_PRINT_Async("WS multipart message: we do not handle split packets right now\n"); + // ppf("WS multipart message: we do not handle split packets right now\n"); // } // } // } - // USER_PRINT_Async("WS multipart message f:%d i:%d len:%d == %d\n", info->final, info->index, info->len, len); + // ppf("WS multipart message f:%d i:%d len:%d == %d\n", info->final, info->index, info->len, len); } } else if (type == WS_EVT_ERROR){ //error was received from the other end // printClient("WS error", client); //crashes - // USER_PRINT_Async("WS error\n"); - USER_PRINT_Async("ws[%s][%u] error(): \n", ws->url(), client->id());//, *((unsigned16*)arg));//, (char*)data); + // ppf("WS error\n"); + ppf("ws[%s][%u] error(): \n", ws->url(), client->id());//, *((unsigned16*)arg));//, (char*)data); } else if (type == WS_EVT_PONG){ //pong message was received (in response to a ping request maybe) // printClient("WS pong", client); //crashes! - // USER_PRINT_Async("WS pong\n"); - // USER_PRINT_Async("ws[%s][%u] pong[%u]: %s\n", ws.url(), client->id(), len, (len)?(char*)data:""); - USER_PRINT_Async("ws[%s][%u] pong[%u]: \n", ws->url(), client->id(), len);//, (len)?(char*)data:""); + // ppf("WS pong\n"); + // ppf("ws[%s][%u] pong[%u]: %s\n", ws.url(), client->id(), len, (len)?(char*)data:""); + ppf("ws[%s][%u] pong[%u]: \n", ws->url(), client->id(), len);//, (len)?(char*)data:""); } } @@ -401,7 +410,7 @@ void SysModWeb::sendDataWs(std::function fi if (ws.count()) { if (len > 8192) - USER_PRINTF("program error: sendDataWs BufferLen too high !!!%d\n", len); + ppf("program error: sendDataWs BufferLen too high !!!%d\n", len); AsyncWebSocketMessageBuffer * wsBuf = ws.makeBuffer(len); //assert failed: block_trim_free heap_tlsf.c:371 (block_is_free(block) && "block must be free"), AsyncWebSocket::makeBuffer(unsigned int) if (wsBuf) { @@ -423,7 +432,7 @@ void SysModWeb::sendDataWs(std::function fi } else { printClient("sendDataWs client full or not connected", loopClient); - // USER_PRINTF("sendDataWs client full or not connected\n"); + // ppf("sendDataWs client full or not connected\n"); ws.cleanupClients(); //only if above threshold ws._cleanBuffers(); } @@ -433,7 +442,7 @@ void SysModWeb::sendDataWs(std::function fi ws._cleanBuffers(); } else { - USER_PRINT_Async("sendDataWs WS buffer allocation failed\n"); + ppf("sendDataWs WS buffer allocation failed\n"); ws.closeAll(1013); //code 1013 = temporary overload, try again later ws.cleanupClients(0); //disconnect ALL clients to release memory ws._cleanBuffers(); @@ -446,7 +455,7 @@ void SysModWeb::sendDataWs(std::function fi //add an url to the webserver to listen to void SysModWeb::serveIndex(WebRequest *request) { - USER_PRINT_Async("Webserver: server.on serveIndex csdata %d-%d (%s)", PAGE_index, PAGE_index_L, request->url().c_str()); + ppf("Webserver: server.on serveIndex csdata %d-%d (%s)", PAGE_index, PAGE_index_L, request->url().c_str()); if (captivePortal(request)) return; @@ -454,20 +463,20 @@ void SysModWeb::serveIndex(WebRequest *request) { WebResponse *response; response = request->beginResponse_P(200, "text/html", PAGE_index, PAGE_index_L); - response->addHeader(FPSTR("Content-Encoding"),"gzip"); + response->addHeader("Content-Encoding","gzip"); // setStaticContentCacheHeaders(response); request->send(response); - USER_PRINT_Async("!\n"); + ppf("!\n"); } void SysModWeb::serveUpload(WebRequest *request, const String& filename, size_t index, byte *data, size_t len, bool final) { // curl -F 'data=@fixture1.json' 192.168.8.213/upload - USER_PRINT_Async("serveUpload r:%s f:%s i:%d l:%d f:%d\n", request->url().c_str(), filename.c_str(), index, len, final); + ppf("serveUpload r:%s f:%s i:%d l:%d f:%d\n", request->url().c_str(), filename.c_str(), index, len, final); mdl->setValue("upload", index/10000); - web->sendResponseObject(); //otherwise not send in asyn_tcp thread + sendResponseObject(); //otherwise not send in asyn_tcp thread if (!index) { String finalname = filename; @@ -487,7 +496,7 @@ void SysModWeb::serveUpload(WebRequest *request, const String& filename, size_t request->_tempFile.close(); mdl->setValue("upload", UINT16_MAX - 10); //success - web->sendResponseObject(); //otherwise not send in asyn_tcp thread + sendResponseObject(); //otherwise not send in asyn_tcp thread request->send(200, "text/plain", F("File Uploaded!")); @@ -498,13 +507,13 @@ void SysModWeb::serveUpload(WebRequest *request, const String& filename, size_t void SysModWeb::serveUpdate(WebRequest *request, const String& filename, size_t index, byte *data, size_t len, bool final) { // curl -F 'data=@fixture1.json' 192.168.8.213/upload - // USER_PRINT_Async("serveUpdate r:%s f:%s i:%d l:%d f:%d\n", request->url().c_str(), filename.c_str(), index, len, final); + // ppf("serveUpdate r:%s f:%s i:%d l:%d f:%d\n", request->url().c_str(), filename.c_str(), index, len, final); mdl->setValue("update", index/10000); - web->sendResponseObject(); //otherwise not send in asyn_tcp thread + sendResponseObject(); //otherwise not send in asyn_tcp thread if (!index) { - USER_PRINTF("OTA Update Start\n"); + ppf("OTA Update Start\n"); // WLED::instance().disableWatchdog(); // usermods.onUpdateBegin(true); // notify usermods that update is about to begin (some may require task de-init) // lastEditTime = millis(); // make sure PIN does not lock during update @@ -515,20 +524,20 @@ void SysModWeb::serveUpdate(WebRequest *request, const String& filename, size_t Update.write(data, len); else { mdl->setValue("update", UINT16_MAX - 20); //fail - web->sendResponseObject(); //otherwise not send in asyn_tcp thread + sendResponseObject(); //otherwise not send in asyn_tcp thread } if (final) { bool success = Update.end(true); mdl->setValue("update", success?UINT16_MAX - 10:UINT16_MAX - 20); - web->sendResponseObject(); //otherwise not send in asyn_tcp thread + sendResponseObject(); //otherwise not send in asyn_tcp thread char message[64]; const char * instanceName = mdl->getValue("instanceName"); print->fFormat(message, sizeof(message)-1, "Update of %s (...%d) %s", instanceName, WiFi.localIP()[3], success?"Successful":"Failed"); - USER_PRINTF("%s\n", message); + ppf("%s\n", message); request->send(200, "text/plain", message); // usermods.onUpdateBegin(false); // notify usermods that update has failed (some may require task init) @@ -540,7 +549,7 @@ void SysModWeb::serveFiles(WebRequest *request) { const char * urlString = request->url().c_str(); const char * path = urlString + strlen("/file"); //remove the uri from the path (skip their positions) - USER_PRINT_Async("fileServer request %s\n", path); + ppf("fileServer request %s\n", path); if(LittleFS.exists(path)) { request->send(LittleFS, path, "text/plain");//"application/json"); } @@ -550,7 +559,7 @@ void SysModWeb::jsonHandler(WebRequest *request, JsonVariant json) { print->printJson("jsonHandler", json); - JsonObject responseObject = web->getResponseObject(); + JsonObject responseObject = getResponseObject(); ui->processJson(json); @@ -564,7 +573,7 @@ void SysModWeb::jsonHandler(WebRequest *request, JsonVariant json) { char resStr[200]; serializeJson(responseObject, resStr, 200); - USER_PRINT_Async("processJsonUrl response %s\n", resStr); + ppf("processJsonUrl response %s\n", resStr); request->send(200, "application/json", resStr); } @@ -573,7 +582,7 @@ void SysModWeb::jsonHandler(WebRequest *request, JsonVariant json) { request->send(200, "application/json", F("{\"success\":true}")); } - web->sendResponseObject(); + sendResponseObject(); } void SysModWeb::clientsToJson(JsonArray array, bool nameOnly, const char * filter) { @@ -581,7 +590,7 @@ void SysModWeb::clientsToJson(JsonArray array, bool nameOnly, const char * filte if (nameOnly) { array.add(JsonString(client->remoteIP().toString().c_str(), JsonString::Copied)); } else { - // USER_PRINTF("Client %d %d ...%d\n", client->id(), client->queueIsFull(), client->remoteIP()[3]); + // ppf("Client %d %d ...%d\n", client->id(), client->queueIsFull(), client->remoteIP()[3]); JsonArray row = array.add(); row.add(client->id()); array.add(JsonString(client->remoteIP().toString().c_str(), JsonString::Copied)); @@ -594,7 +603,7 @@ void SysModWeb::clientsToJson(JsonArray array, bool nameOnly, const char * filte bool SysModWeb::captivePortal(WebRequest *request) { - USER_PRINTF("captivePortal %d %d\n", WiFi.localIP()[3], request->client()->localIP()[3]); + ppf("captivePortal %d %d\n", WiFi.localIP()[3], request->client()->localIP()[3]); if (ON_STA_FILTER(request)) return false; //only serve captive in AP mode String hostH; @@ -602,7 +611,7 @@ bool SysModWeb::captivePortal(WebRequest *request) hostH = request->getHeader("Host")->value(); if (!isIp(hostH) && hostH.indexOf(mdns->cmDNS) < 0) { //&& hostH.indexOf("wled.me") < 0 - USER_PRINTF("Captive portal\n"); + ppf("Captive portal\n"); WebResponse *response = request->beginResponse(302); response->addHeader(F("Location"), F("http://4.3.2.1")); request->send(response); @@ -612,9 +621,9 @@ bool SysModWeb::captivePortal(WebRequest *request) } JsonDocument * SysModWeb::getResponseDoc() { - // USER_PRINTF("response wsevent core %d %s\n", xPortGetCoreID(), pcTaskGetTaskName(NULL)); + // ppf("response wsevent core %d %s\n", xPortGetCoreID(), pcTaskGetTaskName(NULL)); - return strncmp(pcTaskGetTaskName(NULL), "loopTask", 8) == 0?web->responseDocLoopTask:web->responseDocAsyncTCP; + return strncmp(pcTaskGetTaskName(NULL), "loopTask", 8) == 0?responseDocLoopTask:responseDocAsyncTCP; } JsonObject SysModWeb::getResponseObject() { @@ -625,10 +634,24 @@ void SysModWeb::sendResponseObject(WebClient * client) { JsonObject responseObject = getResponseObject(); if (responseObject.size()) { if (strncmp(pcTaskGetTaskName(NULL), "loopTask", 8) != 0) { - print->printJson("sendResponseObject", responseObject); - print->printJDocInfo(" info", responseObject); + ppf("send "); + char sep[3] = ""; + for (JsonPair pair: responseObject) { + ppf("%s%s", sep, pair.key().c_str()); + strcpy(sep, ", "); + if (pair.value().is()) { + char sep[3] = ""; + ppf("{"); + for (JsonPair pair: pair.value().as()) { + ppf("%s%s", sep, pair.key().c_str()); + strcpy(sep, ", "); + } + ppf("}"); + } + } + ppf("\n"); } - web->sendDataWs(responseObject, client); + sendDataWs(responseObject, client); getResponseDoc()->to(); //recreate! } } @@ -640,14 +663,14 @@ void SysModWeb::serveJson(WebRequest *request) { // return model.json if (request->url().indexOf("mdl") > 0) { JsonArray model = mdl->model->as(); - USER_PRINTF("serveJson model ...%d, %s %d %d\n", request->client()->remoteIP()[3], request->url().c_str(), model.size(), measureJson(model)); + ppf("serveJson model ...%d, %s %d %d\n", request->client()->remoteIP()[3], request->url().c_str(), model.size(), measureJson(model)); response = new AsyncJsonResponse(true); //array, removed size as ArduinoJson v7 doesnt care (tbd: here copy is mode, see WLED for using reference) JsonArray root = response->getRoot(); root.set(model); } else { //WLED compatible - USER_PRINTF("serveJson ...%d, %s\n", request->client()->remoteIP()[3], request->url().c_str()); + ppf("serveJson ...%d, %s\n", request->client()->remoteIP()[3], request->url().c_str()); response = new AsyncJsonResponse(false); //object. removed size as ArduinoJson v7 doesnt care JsonObject root = response->getRoot(); @@ -662,9 +685,9 @@ void SysModWeb::serveJson(WebRequest *request) { root["info"]["name"] = mdl->getValue("instanceName"); root["info"]["arch"] = "esp32"; //platformName - root["info"]["rel"] = "StarMod"; + root["info"]["rel"] = _INIT(TOSTRING(APP)); root["info"]["ver"] = "0.0.1"; - root["info"]["vid"] = mdl->getValue("version").as(); //WLED-native needs int otherwise status offline!!! + root["info"]["vid"] = VERSION; //WLED-native needs int otherwise status offline!!! root["info"]["leds"]["count"] = 999; root["info"]["leds"]["countP"] = 998; root["info"]["leds"]["fps"] = mdl->getValue("fps"); //tbd: should be realFps but is ro var diff --git a/src/Sys/SysModWeb.h b/src/Sys/SysModWeb.h index ea9c8ac0..44dec7de 100644 --- a/src/Sys/SysModWeb.h +++ b/src/Sys/SysModWeb.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysModWeb.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -151,7 +151,7 @@ class SysModWeb:public SysModule { void sendResponseObject(WebClient * client = nullptr); void printClient(const char * text, WebClient * client) { - USER_PRINTF("%s client: %d ...%d q:%d l:%d s:%d (#:%d)\n", text, client?client->id():-1, client?client->remoteIP()[3]:-1, client->queueIsFull(), client->queueLength(), client->status(), client->server()->count()); + ppf("%s client: %d ...%d q:%d l:%d s:%d (#:%d)\n", text, client?client->id():-1, client?client->remoteIP()[3]:-1, client->queueIsFull(), client->queueLength(), client->status(), client->server()->count()); //status: { WS_DISCONNECTED, WS_CONNECTED, WS_DISCONNECTING } } diff --git a/src/Sys/SysModWorkFlow.h b/src/Sys/SysModWorkFlow.h index 93bf2e39..ac62a2d1 100644 --- a/src/Sys/SysModWorkFlow.h +++ b/src/Sys/SysModWorkFlow.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysModWorkFlow.h - @date 20240228 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -86,7 +86,7 @@ class SysModWorkFlow: public SysModule { Action action; strcpy(action.description, description); strcpy(action.module, module); - USER_PRINTF("addAction %s %s %d\n", description, module, actions.size()); + ppf("addAction %s %s %d\n", description, module, actions.size()); actions.push_back(action); rebuildTable = true; diff --git a/src/Sys/SysStarModJson.h b/src/Sys/SysStarModJson.h index 7c57fbb7..446f39b6 100644 --- a/src/Sys/SysStarModJson.h +++ b/src/Sys/SysStarModJson.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysStarModJson.h - @date 20240228 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -17,14 +17,14 @@ class StarModJson { public: StarModJson(const char * path, const char * mode = "r") { - USER_PRINTF("StarModJson constructing %s %s\n", path, mode); + // ppf("StarModJson constructing %s %s\n", path, mode); f = files->open(path, mode); if (!f) - USER_PRINTF("StarModJson open %s for %s failed", path, mode); + ppf("StarModJson open %s for %s failed", path, mode); } ~StarModJson() { - USER_PRINTF("StarModJson destructing\n"); + // ppf("StarModJson destructing\n"); f.close(); } @@ -71,9 +71,9 @@ class StarModJson { while (f.available() && (!foundAll || !lazy)) next(); if (foundAll) - USER_PRINTF("StarModJson found all what it was looking for %d >= %d\n", foundCounter, varDetails.size()); + ppf("StarModJson found all what it was looking for %d >= %d\n", foundCounter, varDetails.size()); else - USER_PRINTF("StarModJson Not all vars looked for where found %d < %d\n", foundCounter, varDetails.size()); + ppf("StarModJson Not all vars looked for where found %d < %d\n", foundCounter, varDetails.size()); f.close(); return foundAll; } @@ -111,23 +111,23 @@ class StarModJson { void next() { if (character=='{') { //object begin - // USER_PRINTF("Object %c\n", character); + // ppf("Object %c\n", character); varStack.push_back(lastVarId); //copy!! - // USER_PRINTF("Object push %s %d\n", lastVarId, varStack.size()); + // ppf("Object push %s %d\n", lastVarId, varStack.size()); strcpy(lastVarId, ""); f.read(&character, sizeof(byte)); } else if (character=='}') { //object end strncpy(lastVarId, varStack[varStack.size()-1].c_str(), sizeof(lastVarId)-1); - // USER_PRINTF("Object pop %s %d\n", lastVarId, varStack.size()); + // ppf("Object pop %s %d\n", lastVarId, varStack.size()); check(lastVarId); varStack.pop_back(); f.read(&character, sizeof(byte)); } else if (character=='[') { //array begin - // USER_PRINTF("Array %c\n", character); + // ppf("Array %c\n", character); varStack.push_back(lastVarId); //copy!! - // USER_PRINTF("Array push %s %d\n", lastVarId, varStack.size()); + // ppf("Array push %s %d\n", lastVarId, varStack.size()); strcpy(lastVarId, ""); f.read(&character, sizeof(byte)); @@ -138,12 +138,12 @@ class StarModJson { else if (character==']') { //array end //assign back the popped var id from [ strncpy(lastVarId, varStack[varStack.size()-1].c_str(), sizeof(lastVarId)-1); - // USER_PRINTF("Array pop %s %d %d\n", lastVarId, varStack.size(), uint16CollectList.size()); + // ppf("Array pop %s %d %d\n", lastVarId, varStack.size(), uint16CollectList.size()); check(lastVarId); //check the parent array, if exists if (varStack.size()-2 >=0) { - // USER_PRINTF(" Parent check %s\n", varStack[varStack.size()-2].c_str()); + // ppf(" Parent check %s\n", varStack[varStack.size()-2].c_str()); strncpy(beforeLastVarId, varStack[varStack.size()-2].c_str(), sizeof(beforeLastVarId)-1); check(beforeLastVarId); } @@ -158,11 +158,11 @@ class StarModJson { //if no lastVar then var found if (strcmp(lastVarId, "") == 0) { - // USER_PRINTF("Element [%s]\n", value); + // ppf("Element [%s]\n", value); strncpy(lastVarId, value, sizeof(lastVarId)-1); } else { // if lastvar then string value found - // USER_PRINTF("String var %s: [%s]\n", lastVarId, value); + // ppf("String var %s: [%s]\n", lastVarId, value); check(lastVarId, value); strcpy(lastVarId, ""); } @@ -175,14 +175,14 @@ class StarModJson { size_t len = 0; //readuntil not number while (isDigit(character)) { - // USER_PRINTF("%c", character); + // ppf("%c", character); value[len++] = character; f.read(&character, sizeof(byte)); } value[len++] = '\0'; //number value found - // USER_PRINTF("Number var %s: [%s]\n", lastVarId, value); + // ppf("Number var %s: [%s]\n", lastVarId, value); if (collectNumbers) uint16CollectList.push_back(atoi(value)); @@ -191,27 +191,27 @@ class StarModJson { strcpy(lastVarId, ""); } else if (character==':') { - // USER_PRINTF("semicolon %c\n", character); + // ppf("semicolon %c\n", character); f.read(&character, sizeof(byte)); } else if (character==',') { - // USER_PRINTF("sep %c\n", character); + // ppf("sep %c\n", character); f.read(&character, sizeof(byte)); } else if (character==']') { - // USER_PRINTF("close %c\n", character); + // ppf("close %c\n", character); f.read(&character, sizeof(byte)); } else if (character=='}') { - // USER_PRINTF("close %c\n", character); + // ppf("close %c\n", character); f.read(&character, sizeof(byte)); } else if (character=='\n') { //skip new lines - // USER_PRINTF("skip newline \n"); + // ppf("skip newline \n"); f.read(&character, sizeof(byte)); } else { - // USER_PRINTF("%c", character); + // ppf("%c", character); f.read(&character, sizeof(byte)); } } //next @@ -219,9 +219,9 @@ class StarModJson { void check(char * varId, char * value = nullptr) { //check if var is in lookFor list for (std::vector::iterator vd=varDetails.begin(); vd!=varDetails.end(); ++vd) { - // USER_PRINTF("check %s %s %s\n", vd->id, varId, value); + // ppf("check %s %s %s\n", vd->id, varId, value); if (strcmp(vd->id, varId)==0) { - // USER_PRINTF("StarModJson found %s:%s %d %s %d %d\n", varId, vd->type, vd->index, value?value:"", uint16CollectList.size(), funList.size()); + // ppf("StarModJson found %s:%s %d %s %d %d\n", varId, vd->type, vd->index, value?value:"", uint16CollectList.size(), funList.size()); // if (strcmp(vd->type, "uint8") ==0 && value) *uint8List[vd->index] = atoi(value); if (strcmp(vd->type, "uint16") ==0 && value) *uint16List[vd->index] = atoi(value); if (strcmp(vd->type, "char") ==0 && value) strncpy(charList[vd->index], value, 31); //assuming size 32-1 here @@ -278,7 +278,7 @@ class StarModJson { f.print("null"); } else - USER_PRINTF("dev StarModJson write %s not supported\n", variant.as().c_str()); + ppf("dev StarModJson write %s not supported\n", variant.as().c_str()); } }; \ No newline at end of file diff --git a/src/SysModule.h b/src/SysModule.h index bb44a865..53b28224 100644 --- a/src/SysModule.h +++ b/src/SysModule.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysModule.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -11,6 +11,11 @@ #pragma once +//make a string from pio variables (_INIT and STRINGIFY needed to make TOSTRING work) +#define _INIT(x) x +#define STRINGIFY(X) #X +#define TOSTRING(X) STRINGIFY(X) + //conventional (works) // #define unsigned8 uint8_t // #define unsigned16 uint16_t diff --git a/src/SysModules.cpp b/src/SysModules.cpp index ce58c6b1..799fd77a 100644 --- a/src/SysModules.cpp +++ b/src/SysModules.cpp @@ -1,8 +1,8 @@ /* @title StarMod @file SysModules.cpp - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -23,6 +23,14 @@ void SysModules::setup() { module->setup(); } + //delete mdlTbl values if nr of modules has changed (new values created using module defaults) + for (JsonObject childVar: mdl->varChildren("mdlTbl")) { + if (!childVar["value"].isNull() && mdl->varValArray(childVar).size() != modules.size()) { + ppf("mdlTbl clear (%s %s) %d %d\n", childVar["id"].as().c_str(), childVar["value"].as().c_str(), modules.size(), mdl->varValArray(childVar).size()); + childVar.remove("value"); + } + } + //do its own setup: will be shown as last module JsonObject parentVar = ui->initSysMod(parentVar, "Modules", 4203); @@ -60,6 +68,7 @@ void SysModules::setup() { ui->initCheckBox(tableVar, "mdlEnabled", UINT16_MAX, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun not readonly! (tbd) case f_ValueFun: //never a rowNr as parameter, set all + //execute only if var has not been set for (forUnsigned8 rowNr = 0; rowNr < modules.size(); rowNr++) mdl->setValue(var, modules[rowNr]->isEnabled, rowNr); return true; @@ -73,7 +82,7 @@ void SysModules::setup() { modules[rowNr]->enabledChanged(); } else { - USER_PRINTF(" no rowNr or > modules.size!!", rowNr); + ppf(" no rowNr or %d > modules.size %d!!\n", rowNr, modules.size()); } // print->printJson(" ", var); return true; diff --git a/src/SysModules.h b/src/SysModules.h index 2b8b5be8..490c6d8f 100644 --- a/src/SysModules.h +++ b/src/SysModules.h @@ -1,8 +1,8 @@ /* @title StarMod @file SysModules.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 diff --git a/src/User/UserModArtNet.h b/src/User/UserModArtNet.h deleted file mode 100644 index 3e026a95..00000000 --- a/src/User/UserModArtNet.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - @title StarMod - @file UserModArtNet.h - @date 20240114 - @repo https://github.com/ewowi/StarMod - @Authors https://github.com/ewowi/StarMod/commits/main - @Copyright © 2024 Github StarMod Commit Authors - @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com -*/ - -#define ARTNET_DEFAULT_PORT 6454 - -const size_t ART_NET_HEADER_SIZE = 12; -const byte ART_NET_HEADER[] PROGMEM = {0x41,0x72,0x74,0x2d,0x4e,0x65,0x74,0x00,0x00,0x50,0x00,0x0e}; - -class UserModArtNet:public SysModule { - -public: - - IPAddress targetIp; //tbd: targetip also configurable from fixtures and artnet instead of pin output - - UserModArtNet() :SysModule("ArtNet") { - isEnabled = false; //default off - }; - - //setup filesystem - void setup() { - SysModule::setup(); - - parentVar = ui->initUserMod(parentVar, name, 6100); - - ui->initIP(parentVar, "artInst", UINT16_MAX, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - - case f_UIFun: { - ui->setLabel(var, "Instance"); - ui->setComment(var, "Instance to send data"); - JsonArray options = ui->setOptions(var); - JsonArray instanceObject = options.add(); - instanceObject.add(0); - instanceObject.add("no sync"); - for (InstanceInfo &instance : instances->instances) { - if (instance.ip != WiFi.localIP()) { - char option[64] = { 0 }; - strncpy(option, instance.name, sizeof(option)-1); - strncat(option, " ", sizeof(option)-1); - strncat(option, instance.ip.toString().c_str(), sizeof(option)-1); - instanceObject = options.add(); - instanceObject.add(instance.ip[3]); - instanceObject.add(option); - } - } - return true; - } - case f_ChangeFun: { - size_t ddpInst = var["value"]; - if (ddpInst >=0 && ddpInst < instances->instances.size()) { - targetIp = instances->instances[ddpInst].ip; - USER_PRINTF("Start ArtNet to %s\n", targetIp.toString().c_str()); - } - return true; - } - default: return false; - }}); //ddpInst - } - - void loop() { - // SysModule::loop(); - - if(!mdls->isConnected) return; - - if(!targetIp) return; - - if(!eff->newFrame) return; - - // calculate the number of UDP packets we need to send - bool isRGBW = false; - - const size_t channelCount = eff->fixture.nrOfLeds * (isRGBW?4:3); // 1 channel for every R,G,B,(W?) value - const size_t ARTNET_CHANNELS_PER_PACKET = isRGBW?512:510; // 512/4=128 RGBW LEDs, 510/3=170 RGB LEDs - const size_t packetCount = ((channelCount-1)/ARTNET_CHANNELS_PER_PACKET)+1; - - stackUnsigned32 channel = 0; - size_t bufferOffset = 0; - - sequenceNumber++; - - WiFiUDP ddpUdp; - - int bri = mdl->getValue("bri"); - - for (size_t currentPacket = 0; currentPacket < packetCount; currentPacket++) { - - if (sequenceNumber > 255) sequenceNumber = 0; - - if (!ddpUdp.beginPacket(targetIp, ARTNET_DEFAULT_PORT)) { - USER_PRINTF("Art-Net WiFiUDP.beginPacket returned an error\n"); - return; // borked - } - - size_t packetSize = ARTNET_CHANNELS_PER_PACKET; - - if (currentPacket == (packetCount - 1U)) { - // last packet - if (channelCount % ARTNET_CHANNELS_PER_PACKET) { - packetSize = channelCount % ARTNET_CHANNELS_PER_PACKET; - } - } - - byte header_buffer[ART_NET_HEADER_SIZE]; - memcpy_P(header_buffer, ART_NET_HEADER, ART_NET_HEADER_SIZE); - ddpUdp.write(header_buffer, ART_NET_HEADER_SIZE); // This doesn't change. Hard coded ID, OpCode, and protocol version. - ddpUdp.write(sequenceNumber & 0xFF); // sequence number. 1..255 - ddpUdp.write(0x00); // physical - more an FYI, not really used for anything. 0..3 - ddpUdp.write((currentPacket) & 0xFF); // Universe LSB. 1 full packet == 1 full universe, so just use current packet number. - ddpUdp.write(0x00); // Universe MSB, unused. - ddpUdp.write(0xFF & (packetSize >> 8)); // 16-bit length of channel data, MSB - ddpUdp.write(0xFF & (packetSize )); // 16-bit length of channel data, LSB - - for (size_t i = 0; i < eff->fixture.nrOfLeds; i++) { - CRGB pixel = eff->fixture.ledsP[i]; - ddpUdp.write(scale8(pixel.r, bri)); // R - ddpUdp.write(scale8(pixel.g, bri)); // G - ddpUdp.write(scale8(pixel.b, bri)); // B - // if (isRGBW) ddpUdp.write(scale8(buffer[bufferOffset++], bri)); // W - } - - if (!ddpUdp.endPacket()) { - USER_PRINTF("Art-Net WiFiUDP.endPacket returned an error\n"); - return; // borked - } - channel += packetSize; - } - - } - - private: - size_t sequenceNumber = 0; - -}; - -extern UserModArtNet *artnetmod; \ No newline at end of file diff --git a/src/User/UserModDDP.h b/src/User/UserModDDP.h deleted file mode 100644 index ef8d6cab..00000000 --- a/src/User/UserModDDP.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - @title StarMod - @file UserModDDP.h - @date 20240114 - @repo https://github.com/ewowi/StarMod - @Authors https://github.com/ewowi/StarMod/commits/main - @Copyright © 2024 Github StarMod Commit Authors - @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com -*/ - -#define DDP_DEFAULT_PORT 4048 -#define DDP_HEADER_LEN 10 -#define DDP_SYNCPACKET_LEN 10 - -#define DDP_FLAGS1_VER 0xc0 // version mask -#define DDP_FLAGS1_VER1 0x40 // version=1 -#define DDP_FLAGS1_PUSH 0x01 -#define DDP_FLAGS1_QUERY 0x02 -#define DDP_FLAGS1_REPLY 0x04 -#define DDP_FLAGS1_STORAGE 0x08 -#define DDP_FLAGS1_TIME 0x10 - -#define DDP_ID_DISPLAY 1 -#define DDP_ID_CONFIG 250 -#define DDP_ID_STATUS 251 - -// 1440 channels per packet -#define DDP_CHANNELS_PER_PACKET 1440 // 480 leds - -#define DDP_TYPE_RGB24 0x0B // 00 001 011 (RGB , 8 bits per channel, 3 channels) -#define DDP_TYPE_RGBW32 0x1B // 00 011 011 (RGBW, 8 bits per channel, 4 channels) - -class UserModDDP:public SysModule { - -public: - - IPAddress targetIp; //tbd: targetip also configurable from fixtures, and ddp instead of pin output - - UserModDDP() :SysModule("DDP") { - isEnabled = false; //default off - }; - - //setup filesystem - void setup() { - SysModule::setup(); - - parentVar = ui->initUserMod(parentVar, name, 6000); - - ui->initIP(parentVar, "ddpInst", UINT16_MAX, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - - case f_UIFun: { - ui->setLabel(var, "Instance"); - ui->setComment(var, "Instance to send data"); - JsonArray options = ui->setOptions(var); - JsonArray instanceObject = options.add(); - instanceObject.add(0); - instanceObject.add("no sync"); - for (InstanceInfo &instance : instances->instances) { - if (instance.ip != WiFi.localIP()) { - char option[64] = { 0 }; - strncpy(option, instance.name, sizeof(option)-1); - strncat(option, " ", sizeof(option)-1); - strncat(option, instance.ip.toString().c_str(), sizeof(option)-1); - instanceObject = options.add(); - instanceObject.add(instance.ip[3]); - instanceObject.add(option); - } - } - return true; - } - case f_ChangeFun: { - size_t ddpInst = var["value"]; - if (ddpInst >=0 && ddpInst < instances->instances.size()) { - targetIp = instances->instances[ddpInst].ip; - USER_PRINTF("Start DDP to %s\n", targetIp.toString().c_str()); - } - return true; - } - default: return false; - }}); //ddpInst - } - - void loop() { - // SysModule::loop(); - - if(!mdls->isConnected) return; - - if(!targetIp) return; - - if(!eff->newFrame) return; - - // calculate the number of UDP packets we need to send - bool isRGBW = false; - - const size_t channelCount = eff->fixture.nrOfLeds * (isRGBW? 4:3); // 1 channel for every R,G,B,(W?) value - const size_t packetCount = ((channelCount-1) / DDP_CHANNELS_PER_PACKET) +1; - - stackUnsigned32 channel = 0; - size_t bufferOffset = 0; - - sequenceNumber++; - - WiFiUDP ddpUdp; - - int bri = mdl->getValue("bri"); - - for (size_t currentPacket = 0; currentPacket < packetCount; currentPacket++) { - - if (sequenceNumber > 15) sequenceNumber = 0; - - if (!ddpUdp.beginPacket(targetIp, DDP_DEFAULT_PORT)) { // port defined in ESPAsyncE131.h - USER_PRINTF("DDP WiFiUDP.beginPacket returned an error\n"); - return; // borked - } - - // the amount of data is AFTER the header in the current packet - size_t packetSize = DDP_CHANNELS_PER_PACKET; - - byte flags = DDP_FLAGS1_VER1; - if (currentPacket == (packetCount - 1U)) { - // last packet, set the push flag - // TODO: determine if we want to send an empty push packet to each destination after sending the pixel data - flags = DDP_FLAGS1_VER1 | DDP_FLAGS1_PUSH; - if (channelCount % DDP_CHANNELS_PER_PACKET) { - packetSize = channelCount % DDP_CHANNELS_PER_PACKET; - } - } - - // write the header - /*0*/ddpUdp.write(flags); - /*1*/ddpUdp.write(sequenceNumber++ & 0x0F); // sequence may be unnecessary unless we are sending twice (as requested in Sync settings) - /*2*/ddpUdp.write(isRGBW ? DDP_TYPE_RGBW32 : DDP_TYPE_RGB24); - /*3*/ddpUdp.write(DDP_ID_DISPLAY); - // data offset in bytes, 32-bit number, MSB first - /*4*/ddpUdp.write(0xFF & (channel >> 24)); - /*5*/ddpUdp.write(0xFF & (channel >> 16)); - /*6*/ddpUdp.write(0xFF & (channel >> 8)); - /*7*/ddpUdp.write(0xFF & (channel )); - // data length in bytes, 16-bit number, MSB first - /*8*/ddpUdp.write(0xFF & (packetSize >> 8)); - /*9*/ddpUdp.write(0xFF & (packetSize )); - - for (size_t i = 0; i < eff->fixture.nrOfLeds; i++) { - CRGB pixel = eff->fixture.ledsP[i]; - ddpUdp.write(scale8(pixel.r, bri)); // R - ddpUdp.write(scale8(pixel.g, bri)); // G - ddpUdp.write(scale8(pixel.b, bri)); // B - // if (isRGBW) ddpUdp.write(scale8(buffer[bufferOffset++], bri)); // W - } - - if (!ddpUdp.endPacket()) { - USER_PRINTF("DDP WiFiUDP.endPacket returned an error\n"); - return; // problem - } - channel += packetSize; - } - } - - private: - size_t sequenceNumber = 0; - -}; - -extern UserModDDP *ddpmod; \ No newline at end of file diff --git a/src/User/UserModE131.h b/src/User/UserModE131.h index f0fe18f0..5abfa83e 100644 --- a/src/User/UserModE131.h +++ b/src/User/UserModE131.h @@ -1,8 +1,8 @@ /* @title StarMod @file UserModE131.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -19,6 +19,7 @@ class UserModE131:public SysModule { public: UserModE131() :SysModule("E131") { + isEnabled = false; //default not enabled }; //setup filesystem @@ -114,21 +115,21 @@ class UserModE131:public SysModule { void onOffChanged() { if (mdls->isConnected && isEnabled) { - USER_PRINTF("UserModE131::connected && enabled\n"); + ppf("UserModE131::connected && enabled\n"); if (e131Created) { // TODO: crashes here - no idea why! - USER_PRINTF("UserModE131 - ESPAsyncE131 created already\n"); + ppf("UserModE131 - ESPAsyncE131 created already\n"); return; } - USER_PRINTF("UserModE131 - Create ESPAsyncE131\n"); + ppf("UserModE131 - Create ESPAsyncE131\n"); e131 = ESPAsyncE131(universeCount); if (this->e131.begin(E131_MULTICAST, universe, universeCount)) { // TODO: multicast igmp failing, so only works with unicast currently - USER_PRINTF("Network exists, begin e131.begin ok\n"); + ppf("Network exists, begin e131.begin ok\n"); success = true; } else { - USER_PRINTF("Network exists, begin e131.begin FAILED\n"); + ppf("Network exists, begin e131.begin FAILED\n"); } e131Created = true; } @@ -152,7 +153,7 @@ class UserModE131:public SysModule { if (i == varToWatch.channel) { if (packet.property_values[i] != varToWatch.savedValue) { - USER_PRINTF("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH%d: %u -> %u", + ppf("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH%d: %u -> %u", htons(packet.universe), // The Universe for this packet htons(packet.property_value_count) - 1, // Start code is ignored, we're interested in dimmer data e131.stats.num_packets, // Packet counter @@ -164,11 +165,11 @@ class UserModE131:public SysModule { varToWatch.savedValue = packet.property_values[i]; if (varToWatch.id != nullptr && varToWatch.max != 0) { - USER_PRINTF(" varsToWatch: %s\n", varToWatch.id); + ppf(" varsToWatch: %s\n", varToWatch.id); mdl->setValue(varToWatch.id, varToWatch.savedValue%(varToWatch.max+1)); // TODO: ugly to have magic string } else - USER_PRINTF("\n"); + ppf("\n"); }//!= savedValue }//if channel }//maxChannels @@ -191,7 +192,7 @@ class UserModE131:public SysModule { // return varsToWatch[i].savedValue; // } // } - // USER_PRINTF("ERROR: failed to find param %s\n", id); + // ppf("ERROR: failed to find param %s\n", id); // return 0; // } diff --git a/src/User/UserModExample.h b/src/User/UserModExample.h index 68db486d..02e46284 100644 --- a/src/User/UserModExample.h +++ b/src/User/UserModExample.h @@ -1,19 +1,19 @@ /* @title StarMod @file UserModExample.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com */ -class UserModExample:public SysModuleule { +class UserModExample: public SysModule { public: - UserModExample() :SysModule(le("Usermod example") { + UserModExample() :SysModule("Usermod example") { }; //setup filesystem diff --git a/src/User/UserModHA.h b/src/User/UserModHA.h index 8a7bd680..60d94394 100644 --- a/src/User/UserModHA.h +++ b/src/User/UserModHA.h @@ -1,8 +1,8 @@ /* @title StarMod @file UserModHA.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -22,26 +22,19 @@ class UserModHA:public SysModule { }; void onStateCommand(bool state, HALight* sender) { - Serial.print("State: "); - Serial.println(state); + ppf("State: %s\n", state?"true":"false"); sender->setState(state); // report state back to the Home Assistant } void onBrightnessCommand(unsigned8 brightness, HALight* sender) { - Serial.print("Brightness: "); - Serial.println(brightness); + ppf("Brightness: %s\n", brightness); sender->setBrightness(brightness); // report brightness back to the Home Assistant } void onRGBColorCommand(HALight::RGBColor color, HALight* sender) { - Serial.print("Red: "); - Serial.println(color.red); - Serial.print("Green: "); - Serial.println(color.green); - Serial.print("Blue: "); - Serial.println(color.blue); + ppf("Red: %d Green: %d blue: %d\n", color.red, color.green, color.blue); sender->setRGBColor(color); // report color back to the Home Assistant } @@ -49,8 +42,8 @@ class UserModHA:public SysModule { void connectedChanged() { if (mdls->isConnected) { // set device's details (optional) - device.setName("StarMod"); - device.setSoftwareVersion("0.0.1"); + device.setName(_INIT(TOSTRING(APP))); + device.setSoftwareVersion(_INIT(TOSTRING(VERSION))); } // configure light (optional) @@ -83,7 +76,7 @@ class UserModHA:public SysModule { WiFiClient client; HADevice device; HAMqtt* mqtt = new HAMqtt(client, device); - HALight* light = new HALight("starmod", HALight::BrightnessFeature | HALight::RGBFeature); + HALight* light = new HALight(_INIT(TOSTRING(APP)), HALight::BrightnessFeature | HALight::RGBFeature); }; extern UserModHA *hamod; \ No newline at end of file diff --git a/src/User/UserModInstances.h b/src/User/UserModInstances.h index f799365a..47591cf2 100644 --- a/src/User/UserModInstances.h +++ b/src/User/UserModInstances.h @@ -1,8 +1,8 @@ /* @title StarMod @file UserModInstances.h - @date 20240114 - @repo https://github.com/ewoudwijma/StarMod + @date 20240411 + @repo https://github.com/ewoudwijma/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewoudwijma/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -64,12 +64,12 @@ struct AppData { int getVar(const char * varID) { //int to support -1 for (int i=0; i < nrOfAppVars; i++) { - // USER_PRINTF("getVar %d %s %s %d\n", i, varID, vars[i].id, vars[i].value); + // ppf("getVar %d %s %s %d\n", i, varID, vars[i].id, vars[i].value); if (varID && !str3cmp(vars[i].id, "-") && str3cmp(vars[i].id, varID)) { return vars[i].value; } } - // USER_PRINTF("getVar %s not found\n", varID); + // ppf("getVar %s not found\n", varID); return -1; } @@ -88,7 +88,7 @@ struct AppData { size_t i = foundAppVar; if (str3cmp(vars[i].id, "-")) str3cpy(vars[i].id, varID); //assign empty slot to var vars[i].value = value; - // USER_PRINTF("setVar %d %s %d\n", i, varID, vars[i].value); + // ppf("setVar %d %s %d\n", i, varID, vars[i].value); } void initVars() { @@ -186,7 +186,7 @@ class UserModInstances:public SysModule { // mdl->findVars("dash", true, [instance, row](JsonObject var) { //findFun // //look for value in instance // int value = instance->app.getVar(var["id"]); - // // USER_PRINTF("insTbl %s %s: %d\n", instance->name, varID, value); + // // ppf("insTbl %s %s: %d\n", instance->name, varID, value); // row.add(value); // }); // } @@ -303,7 +303,7 @@ class UserModInstances:public SysModule { //find dash variables and add them to the table mdl->findVars("dash", true, [tableVar, this](JsonObject var) { //findFun - USER_PRINTF("dash %s %s found\n", mdl->varID(var), var["value"].as().c_str()); + ppf("dash %s %s found\n", mdl->varID(var), var["value"].as().c_str()); char columnVarID[32] = "ins"; strcat(columnVarID, var["id"]); @@ -314,7 +314,7 @@ class UserModInstances:public SysModule { case f_ValueFun: //should not trigger chFun for (forUnsigned8 rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) { - // USER_PRINTF("initVar dash %s[%d]\n", mdl->varID(insVar), rowNrL); + // ppf("initVar dash %s[%d]\n", mdl->varID(insVar), rowNrL); //do what setValue is doing except calling changeFun // insVar["value"][rowNrL] = instances[rowNrL].app.getVar(mdl->varID(var)); //only int values... web->addResponse(insVar["id"], "value", instances[rowNrL].app.getVar(mdl->varID(var)), rowNrL); //only int values...); @@ -335,6 +335,8 @@ class UserModInstances:public SysModule { mdl->setValue(var, mdl->getValue(insVar, rowNr).as()); //this will call sendDataWS (tbd...), do not set for rowNr } else { // https://randomnerdtutorials.com/esp32-http-get-post-arduino/ + + //this takes 10% of flash size!!! tbd: move to udp calls HTTPClient http; char serverPath[32]; print->fFormat(serverPath, sizeof(serverPath)-1, "http://%s/json", instances[rowNr].ip.toString().c_str()); @@ -343,19 +345,16 @@ class UserModInstances:public SysModule { char postMessage[32]; print->fFormat(postMessage, sizeof(postMessage)-1, "{\"%s\":%d}", mdl->varID(var), mdl->getValue(insVar, rowNr).as()); - USER_PRINTF("json post %s %s\n", serverPath, postMessage); + ppf("json post %s %s\n", serverPath, postMessage); int httpResponseCode = http.POST(postMessage); if (httpResponseCode>0) { - Serial.print("HTTP Response code: "); - Serial.println(httpResponseCode); String payload = http.getString(); - Serial.println(payload); + ppf("HTTP Response code: %d %s\n", httpResponseCode, payload); } else { - Serial.print("Error code: "); - Serial.println(httpResponseCode); + ppf("Error code: %d\n", httpResponseCode); } // Free resources http.end(); @@ -377,18 +376,18 @@ class UserModInstances:public SysModule { }); if (sizeof(UDPWLEDMessage) != 44) { - USER_PRINTF("Program error: Size of UDP message is not 44: %d\n", sizeof(UDPWLEDMessage)); - // USER_PRINTF("udpMessage size %d = %d + %d + %d + ...\n", sizeof(UDPWLEDMessage), sizeof(udpMessage.ip0), sizeof(udpMessage.version), sizeof(udpMessage.name)); + ppf("Program error: Size of UDP message is not 44: %d\n", sizeof(UDPWLEDMessage)); + // ppf("udpMessage size %d = %d + %d + %d + ...\n", sizeof(UDPWLEDMessage), sizeof(udpMessage.ip0), sizeof(udpMessage.version), sizeof(udpMessage.name)); success = false; } if (sizeof(UDPStarModMessage) != 1460) { //size of UDP Packet // one udp frame should be 1460, not 1472 (then split by network in 1460 and 12) - USER_PRINTF("Program error: Size of UDP message is not 44: %d\n", sizeof(UDPStarModMessage)); - // USER_PRINTF("udpMessage size %d = %d + %d + %d + ...\n", sizeof(UDPWLEDMessage), sizeof(udpMessage.ip0), sizeof(udpMessage.version), sizeof(udpMessage.name)); + ppf("Program error: Size of UDP message is not 44: %d\n", sizeof(UDPStarModMessage)); + // ppf("udpMessage size %d = %d + %d + %d + ...\n", sizeof(UDPWLEDMessage), sizeof(udpMessage.ip0), sizeof(udpMessage.version), sizeof(udpMessage.name)); success = false; } - USER_PRINTF("UDPWLEDSyncMessage %d %d %d\n", sizeof(UDPWLEDMessage), sizeof(UDPStarModMessage), sizeof(UDPWLEDSyncMessage)); + ppf("UDPWLEDSyncMessage %d %d %d\n", sizeof(UDPWLEDMessage), sizeof(UDPStarModMessage), sizeof(UDPWLEDSyncMessage)); } void onOffChanged() { @@ -437,7 +436,7 @@ class UserModInstances:public SysModule { if (packetSize > 0) { IPAddress remoteIp = notifierUdp.remoteIP(); - // USER_PRINTF("handleNotifications sync ...%d %d\n", remoteIp[3], packetSize); + // ppf("handleNotifications sync ...%d %d\n", remoteIp[3], packetSize); UDPWLEDSyncMessage wledSyncMessage; byte *udpIn = (byte *)&wledSyncMessage; @@ -447,7 +446,7 @@ class UserModInstances:public SysModule { // Serial.printf("%d: %d\n", i, udpIn[i]); // } - USER_PRINTF(" %d %d p:%d\n", wledSyncMessage.bri, wledSyncMessage.mainsegMode, packetSize); + ppf(" %d %d p:%d\n", wledSyncMessage.bri, wledSyncMessage.mainsegMode, packetSize); InstanceInfo *instance = findInstance(remoteIp); //if not exist, created @@ -470,7 +469,7 @@ class UserModInstances:public SysModule { // } // Serial.println(); - USER_PRINTF("insTbl handleNotifications %d\n", remoteIp[3]); + ppf("insTbl handleNotifications %d\n", remoteIp[3]); for (JsonObject childVar: mdl->varChildren("insTbl")) ui->callVarFun(childVar, UINT8_MAX, f_ValueFun); //rowNr //instance - instances.begin() @@ -487,7 +486,7 @@ class UserModInstances:public SysModule { if (packetSize > 0) { IPAddress remoteIp = instanceUDP.remoteIP(); - // USER_PRINTF("handleNotifications instances ...%d %d check %d or %d\n", remoteIp[3], packetSize, sizeof(UDPWLEDMessage), sizeof(UDPStarModMessage)); + // ppf("handleNotifications instances ...%d %d check %d or %d\n", remoteIp[3], packetSize, sizeof(UDPWLEDMessage), sizeof(UDPStarModMessage)); if (packetSize == sizeof(UDPWLEDMessage)) { //WLED instance UDPStarModMessage starModMessage; @@ -511,7 +510,7 @@ class UserModInstances:public SysModule { byte udpIn[1472+1]; notifierUdp.read(udpIn, packetSize); - USER_PRINTF("packetSize %d not equal to %d or %d\n", packetSize, sizeof(UDPWLEDMessage), sizeof(UDPStarModMessage)); + ppf("packetSize %d not equal to %d or %d\n", packetSize, sizeof(UDPWLEDMessage), sizeof(UDPStarModMessage)); } web->recvUDPCounter++; web->recvUDPBytes+=packetSize; @@ -525,7 +524,7 @@ class UserModInstances:public SysModule { for (std::vector::iterator instance=instances.begin(); instance!=instances.end(); ) { if (millis() - instance->timeStamp > 32000) { //assuming a ping each 30 seconds instance = instances.erase(instance); - USER_PRINTF("insTbl remove inactive instances %d\n", instance->ip[3]); + // ppf("insTbl remove inactive instances %d\n", instance->ip[3]); for (JsonObject childVar: mdl->varChildren("insTbl")) ui->callVarFun(childVar, UINT8_MAX, f_ValueFun); //no rowNr so all rows updated @@ -555,10 +554,10 @@ class UserModInstances:public SysModule { starModMessage.header.ip2 = localIP[2]; starModMessage.header.ip3 = localIP[3]; const char * instanceName = mdl->getValue("instanceName"); - strncpy(starModMessage.header.name, instanceName?instanceName:"StarMod", sizeof(starModMessage.header.name)-1); + strncpy(starModMessage.header.name, instanceName?instanceName:_INIT(TOSTRING(APP)), sizeof(starModMessage.header.name)-1); starModMessage.header.type = 32; //esp32 tbd: CONFIG_IDF_TARGET_ESP32S3 etc starModMessage.header.insId = localIP[3]; //WLED: used in map of instances as index! - starModMessage.header.version = atoi(sys->version); + starModMessage.header.version = VERSION; starModMessage.sys.type = 1; //StarMod starModMessage.sys.upTime = millis()/1000; starModMessage.sys.syncMaster = mdl->getValue("sma"); @@ -590,7 +589,7 @@ class UserModInstances:public SysModule { IPAddress broadcastIP(255, 255, 255, 255); if (0 != instanceUDP.beginPacket(broadcastIP, instanceUDPPort)) { // WLEDMM beginPacket == 0 --> error - // USER_PRINTF("sendSysInfoUDP %s s:%d p:%d i:...%d\n", starModMessage.header.name, sizeof(UDPStarModMessage), instanceUDPPort, localIP[3]); + // ppf("sendSysInfoUDP %s s:%d p:%d i:...%d\n", starModMessage.header.name, sizeof(UDPStarModMessage), instanceUDPPort, localIP[3]); // for (size_t x = 0; x < sizeof(UDPWLEDMessage) + sizeof(SysData) + sizeof(AppData); x++) { // char * xx = (char *)&starModMessage; // Serial.printf("%d: %d - %c\n", x, xx[x], xx[x]); @@ -602,7 +601,7 @@ class UserModInstances:public SysModule { instanceUDP.endPacket(); } else { - USER_PRINTF("sendSysInfoUDP error\n"); + ppf("sendSysInfoUDP error\n"); } } @@ -615,7 +614,7 @@ class UserModInstances:public SysModule { instanceFound = true; } - // USER_PRINTF("updateInstance Instance: ...%d n:%s found:%d\n", messageIP[3], udpStarMessage.header.name, instanceFound); + // ppf("updateInstance Instance: ...%d n:%s found:%d\n", messageIP[3], udpStarMessage.header.name, instanceFound); if (!instanceFound) { //new instance InstanceInfo instance; @@ -666,7 +665,7 @@ class UserModInstances:public SysModule { instance.app.str3cpy(varID, newVar.id); varID[3]='\0'; - USER_PRINTF("AppData3 %s %s %d\n", instance.name, varID, newVar.value); + ppf("AppData3 %s %s %d\n", instance.name, varID, newVar.value); mdl->setValue(varID, newVar.value); } } @@ -693,7 +692,7 @@ class UserModInstances:public SysModule { // web->sendResponseObject(); - // USER_PRINTF("updateInstance updRow[%d] %s\n", instance - instances.begin(), instances[instance - instances.begin()].name); + // ppf("updateInstance updRow[%d] %s\n", instance - instances.begin(), instances[instance - instances.begin()].name); for (JsonObject childVar: mdl->varChildren("insTbl")) ui->callVarFun(childVar, UINT8_MAX, f_ValueFun); //rowNr instance - instances.begin() @@ -706,7 +705,7 @@ class UserModInstances:public SysModule { } // for instances if (!instanceFound) { - USER_PRINTF("insTbl new instance %s\n", messageIP.toString().c_str()); + // ppf("insTbl new instance %s\n", messageIP.toString().c_str()); ui->callVarFun("ddpInst", UINT8_MAX, f_UIFun); //UiFun as select changes ui->callVarFun("artInst", UINT8_MAX, f_UIFun); diff --git a/src/User/UserModMDNS.h b/src/User/UserModMDNS.h index 49433ebe..931ca55d 100644 --- a/src/User/UserModMDNS.h +++ b/src/User/UserModMDNS.h @@ -1,8 +1,8 @@ /* @title StarMod @file UserModMDNS.h - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -28,8 +28,6 @@ class UserModMDNS:public SysModule { escapedMac.replace(":", ""); escapedMac.toLowerCase(); - sprintf(cmDNS, PSTR("star-%*s"), 6, escapedMac.c_str() + 6); - // strncpy(cmDNS, "wled-98765", sizeof(cmDNS) -1); } void loop() { @@ -39,20 +37,33 @@ class UserModMDNS:public SysModule { void onOffChanged() { if (mdls->isConnected && isEnabled) { - // print->fFormat(cmDNS, sizeof(cmDNS)-1, "wled-%*s", WiFi.macAddress().c_str() + 6); + resetMDNS(); - MDNS.end(); - MDNS.begin(cmDNS); - - USER_PRINTF("mDNS started %s -> %s -> %s\n", WiFi.macAddress().c_str(), escapedMac.c_str(), cmDNS); - MDNS.addService("http", "tcp", 80); - MDNS.addService("star", "tcp", 80); - MDNS.addServiceTxt("star", "tcp", "mac", escapedMac.c_str()); } else { MDNS.end(); } } + void resetMDNS() { + + if (!mdls->isConnected) return; + + //reset cmDNS + const char * instanceName = mdl->getValue("instanceName"); + if (strcmp(instanceName, _INIT(TOSTRING(APP))) == 0 ) + sprintf(cmDNS, "star-%*s", 6, escapedMac.c_str() + 6); + else + strcpy(cmDNS, instanceName); + + MDNS.end(); + MDNS.begin(cmDNS); + + ppf("mDNS started %s -> %s\n", WiFi.macAddress().c_str(), cmDNS); + MDNS.addService("http", "tcp", 80); + MDNS.addService("star", "tcp", 80); + MDNS.addServiceTxt("star", "tcp", "mac", escapedMac.c_str()); + } + }; extern UserModMDNS *mdns; \ No newline at end of file diff --git a/src/User/UserModWLEDAudio.h b/src/User/UserModWLEDAudio.h deleted file mode 100644 index 2b436947..00000000 --- a/src/User/UserModWLEDAudio.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - @title StarMod - @file UserModWLEDAudio.h - @date 20240114 - @repo https://github.com/ewowi/StarMod - @Authors https://github.com/ewowi/StarMod/commits/main - @Copyright © 2024 Github StarMod Commit Authors - @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com -*/ - -#pragma once - -#include // https://github.com/netmindz/WLED-sync - -#define MAX_FREQUENCY 11025 // sample frequency / 2 (as per Nyquist criterion) - -enum UM_SoundSimulations { - UMS_BeatSin = 0, - UMS_WeWillRockYou -}; - - -class UserModWLEDAudio:public SysModule { - -public: - - WLEDSync sync; - byte fftResults[NUM_GEQ_CHANNELS]= {0}; - float volumeSmth; - - UserModWLEDAudio() :SysModule("WLED Audio Sync Receiver") { - }; - - //setup filesystem - void setup() { - SysModule::setup(); - parentVar = ui->initUserMod(parentVar, name, 6300); - - ui->initText(parentVar, "wledAudioStatus", nullptr, 16, true, [](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Status:"); - return true; - default: return false; - }}); - - } - - void onOffChanged() { - if (mdls->isConnected && isEnabled) { - sync.begin(); - } else { - // sync.end();??? - } - } - - bool isTimeout() { - return ((millis() - lastData) > 10000); - } - - void loop() { - // SysModule::loop(); - if (mdls->isConnected && sync.read()) { - lastData = millis(); - if(debug) USER_PRINTF("WLED-Sync: "); - for (int b = 0; b < NUM_GEQ_CHANNELS; b++) { - byte val = sync.fftResult[b]; - fftResults[b] = val; - if(debug) USER_PRINTF("%u ", val); - } - volumeSmth = sync.volumeSmth; - if(debug) USER_PRINTF("\n"); - } - else if((lastData == 0) || isTimeout()) { // Could also check for non-silent - simulateSound(UMS_BeatSin); - } - } - - void loop10s() { - // USER_PRINTF("%d, %s, %d\n", sync.receivedFormat, sync.sourceIP.toString().c_str(), sync.lastPacketTime); - String msg = ""; - if((lastData != 0) && isTimeout()) { - msg = sync.sourceIP.toString() + " Timeout " + ((millis() - lastData) / 1000) +"s"; - } - else { - switch(sync.receivedFormat) { - case -1: msg = "Not connected"; - break; - case 1: msg = "V1 from " + sync.sourceIP.toString(); - break; - case 2: msg = "V2 from " + sync.sourceIP.toString(); - break; - default: msg = "Unknown"; - break; - } - } - mdl->setUIValueV("wledAudioStatus", "%s", msg.c_str()); - } - - private: - boolean debug = false; - unsigned long lastData = 0; - - void simulateSound(uint8_t simulationId) - { - uint8_t samplePeak; - float FFT_MajorPeak; - uint8_t maxVol; - uint8_t binNum; - - uint16_t volumeRaw; - float my_magnitude; - - uint32_t ms = millis(); - - switch (simulationId) { - default: - case UMS_BeatSin: - for (int i = 0; i<16; i++) - fftResults[i] = beatsin8(120 / (i+1), 0, 255); - // fftResults[i] = (beatsin8(120, 0, 255) + (256/16 * i)) % 256; - volumeSmth = fftResults[8]; - break; - case UMS_WeWillRockYou: - if (ms%2000 < 200) { - volumeSmth = random8(255); - for (int i = 0; i<5; i++) - fftResults[i] = random8(255); - } - else if (ms%2000 < 400) { - volumeSmth = 0; - for (int i = 0; i<16; i++) - fftResults[i] = 0; - } - else if (ms%2000 < 600) { - volumeSmth = random8(255); - for (int i = 5; i<11; i++) - fftResults[i] = random8(255); - } - else if (ms%2000 < 800) { - volumeSmth = 0; - for (int i = 0; i<16; i++) - fftResults[i] = 0; - } - else if (ms%2000 < 1000) { - volumeSmth = random8(255); - for (int i = 11; i<16; i++) - fftResults[i] = random8(255); - } - else { - volumeSmth = 0; - for (int i = 0; i<16; i++) - fftResults[i] = 0; - } - break; - } - - // samplePeak = random8() > 250; - // FFT_MajorPeak = 21 + (volumeSmth*volumeSmth) / 8.0f; // WLEDMM 21hz...8200hz - // maxVol = 31; // this gets feedback fro UI - // binNum = 8; // this gets feedback fro UI - // volumeRaw = volumeSmth; - // my_magnitude = 10000.0f / 8.0f; //no idea if 10000 is a good value for FFT_Magnitude ??? - // if (volumeSmth < 1 ) my_magnitude = 0.001f; // noise gate closed - mute - - } - - -}; - -extern UserModWLEDAudio *wledAudioMod; \ No newline at end of file diff --git a/src/html_ui.h b/src/html_ui.h index b3a9868b..1bd1b20e 100644 --- a/src/html_ui.h +++ b/src/html_ui.h @@ -7,1385 +7,595 @@ */ // Autogenerated from data/index.htm, do not edit!! -const uint16_t PAGE_index_L = 22049; +const uint16_t PAGE_index_L = 9412; const uint8_t PAGE_index[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xd5, 0xbd, 0xcb, 0x76, 0xe3, 0x48, - 0xb2, 0x20, 0xb8, 0x8f, 0xaf, 0x00, 0x91, 0x51, 0x0c, 0x20, 0x08, 0x52, 0x7c, 0x89, 0x92, 0x40, - 0x41, 0xbc, 0xf1, 0xca, 0xcc, 0xc8, 0x8a, 0x57, 0xa5, 0x22, 0x32, 0x2b, 0x53, 0xa1, 0x4a, 0x81, - 0xa4, 0x53, 0x42, 0x06, 0x04, 0x30, 0x01, 0x50, 0x8f, 0x24, 0xf9, 0x07, 0xdd, 0xbd, 0xe8, 0xbe, - 0x8b, 0xbb, 0xab, 0xd3, 0xb3, 0xea, 0x39, 0xbd, 0x9d, 0xf5, 0x2c, 0xe6, 0x53, 0xee, 0x17, 0xd4, - 0x27, 0x8c, 0x99, 0xf9, 0x03, 0x0e, 0x10, 0x94, 0x22, 0xaa, 0xea, 0xf6, 0xf4, 0x54, 0x56, 0x88, - 0x80, 0xc3, 0x1f, 0xe6, 0xe6, 0x66, 0xe6, 0x66, 0xe6, 0xee, 0xe6, 0xc6, 0x61, 0xed, 0xf9, 0xdb, - 0x67, 0xef, 0x7f, 0x7a, 0xf7, 0xc2, 0xb8, 0xc8, 0x2e, 0xc3, 0x23, 0xe3, 0x50, 0xfe, 0x30, 0x7f, - 0x0a, 0x3f, 0x97, 0x2c, 0xf3, 0x8d, 0xc9, 0x85, 0x9f, 0xa4, 0x2c, 0xf3, 0xcc, 0x45, 0x36, 0x6b, - 0xee, 0x9b, 0x90, 0x9c, 0x05, 0x59, 0xc8, 0x8e, 0x1e, 0x1c, 0x67, 0x7e, 0xf2, 0x3a, 0x9e, 0xfe, - 0xed, 0xaf, 0xff, 0xf5, 0x7f, 0x1a, 0xaf, 0x5e, 0x3c, 0x4f, 0x8d, 0xbf, 0xfd, 0xf5, 0xbf, 0xfc, - 0x0f, 0x63, 0x7c, 0x6b, 0xbc, 0x8e, 0xe3, 0x08, 0x3e, 0x2c, 0x42, 0x86, 0x69, 0xff, 0xe9, 0x5f, - 0x0f, 0x77, 0x78, 0x09, 0xe3, 0x30, 0xcd, 0x6e, 0xb1, 0xa4, 0x9b, 0xc4, 0x71, 0xe6, 0xd0, 0xdf, - 0x56, 0x0a, 0xb5, 0x5c, 0xc6, 0xd3, 0x65, 0xb3, 0x39, 0x3e, 0x6f, 0x4e, 0xe2, 0x30, 0x4e, 0xdc, - 0x30, 0x88, 0x98, 0x9f, 0x34, 0xcf, 0x13, 0x7f, 0x1a, 0xb0, 0x28, 0xb3, 0xb2, 0xd8, 0x18, 0xc7, - 0x59, 0x16, 0x5f, 0x3a, 0xc6, 0x57, 0xb3, 0xd9, 0x98, 0xf5, 0x7a, 0x46, 0xfb, 0x0f, 0xf0, 0x3c, - 0x1e, 0xb4, 0x67, 0x83, 0xae, 0xd1, 0x69, 0xb7, 0xff, 0x60, 0x0f, 0x9b, 0xcd, 0x8c, 0xdd, 0x64, - 0xa2, 0x86, 0xaf, 0xda, 0x3d, 0xfc, 0x0f, 0x13, 0x2f, 0x64, 0x12, 0xcf, 0xbd, 0xdf, 0x81, 0xc4, - 0x52, 0x1a, 0xa4, 0x8c, 0xe3, 0x64, 0xca, 0x12, 0x99, 0x3c, 0x18, 0x0c, 0x20, 0x2d, 0x65, 0x21, - 0x9b, 0xa8, 0x1a, 0xbf, 0xa6, 0xff, 0x41, 0xf2, 0x2c, 0x8e, 0xb2, 0x66, 0x1a, 0xfc, 0xce, 0xdc, - 0x4e, 0x7b, 0x7e, 0xb3, 0xe6, 0xbd, 0xb8, 0x0e, 0x59, 0xa1, 0x0b, 0x5f, 0x75, 0xba, 0xf8, 0x5f, - 0x09, 0xaa, 0xd9, 0x6c, 0xa6, 0x83, 0x94, 0x9c, 0x8f, 0xad, 0xee, 0xee, 0xae, 0x63, 0x74, 0x06, - 0x6d, 0xc7, 0x68, 0xdb, 0x1a, 0x64, 0x15, 0x9f, 0x0a, 0x20, 0x56, 0x7c, 0x2f, 0x80, 0x5b, 0xf1, - 0xbd, 0x12, 0x6e, 0xc0, 0xf1, 0x2d, 0x63, 0xd1, 0xe7, 0x62, 0xff, 0x60, 0xef, 0xa0, 0x7b, 0xd0, - 0xe7, 0xd8, 0xef, 0xef, 0xf5, 0x77, 0xfb, 0xd5, 0xd8, 0x9f, 0x8d, 0x67, 0xfd, 0x59, 0xbf, 0x80, - 0xfd, 0x6e, 0xa7, 0xbf, 0xdf, 0x1d, 0xeb, 0xb8, 0x57, 0x29, 0x45, 0xdc, 0xab, 0xe4, 0x22, 0xfa, - 0x55, 0x72, 0xb1, 0x1b, 0x7a, 0x42, 0x33, 0x75, 0xf7, 0x55, 0xc7, 0xa6, 0xec, 0xea, 0xfe, 0xf1, - 0x98, 0xcc, 0xa6, 0xed, 0x83, 0x41, 0x01, 0xce, 0x49, 0x77, 0x8f, 0xd1, 0xe8, 0x6f, 0xa6, 0x14, - 0xe1, 0x9c, 0x4c, 0xfd, 0xe9, 0xc0, 0xdf, 0x80, 0xb3, 0xe3, 0xef, 0xfb, 0x34, 0xca, 0xa1, 0x3f, - 0x66, 0xa1, 0x4c, 0xdd, 0xef, 0x4d, 0x76, 0x19, 0x42, 0x3f, 0x89, 0x2f, 0x2f, 0x01, 0xa9, 0x32, - 0x7d, 0xf7, 0x60, 0xdf, 0xef, 0xf7, 0xb6, 0x0d, 0x4e, 0x18, 0x9c, 0x5f, 0x64, 0x85, 0x5e, 0x08, - 0x02, 0xd2, 0xba, 0xd0, 0xe9, 0xf6, 0x74, 0x60, 0xdb, 0xf4, 0xbf, 0x42, 0x8f, 0x06, 0xd3, 0xc1, - 0xfe, 0xc0, 0x27, 0xba, 0x2f, 0x82, 0x2a, 0x3f, 0x48, 0x8c, 0xf9, 0xc9, 0xa7, 0xfb, 0x51, 0x36, - 0x38, 0x18, 0x4c, 0xf7, 0xa6, 0xa2, 0xc8, 0x38, 0x5c, 0xb0, 0x42, 0x91, 0xf6, 0x6e, 0xef, 0x60, - 0xf0, 0xb4, 0x54, 0xe4, 0xc5, 0xde, 0xd7, 0x9d, 0xaf, 0x5f, 0x7c, 0x3e, 0x2f, 0x16, 0xa1, 0x94, - 0x59, 0x45, 0x93, 0xf3, 0x20, 0xfa, 0x54, 0x42, 0xc9, 0xc4, 0x9f, 0xf6, 0x4b, 0x4d, 0xb2, 0xbd, - 0xdd, 0xfe, 0x7e, 0x7b, 0xa3, 0x2e, 0x9e, 0x2c, 0x6a, 0x4a, 0xe7, 0xfe, 0xa4, 0x04, 0x3d, 0xc7, - 0x9c, 0x4e, 0xc8, 0xdd, 0xf1, 0xb4, 0x43, 0x63, 0x7f, 0xde, 0x5c, 0x24, 0xa1, 0x0b, 0xff, 0xac, - 0x47, 0x53, 0x3f, 0xf3, 0x5d, 0x7f, 0x3e, 0x0f, 0x83, 0x89, 0x9f, 0x05, 0x71, 0xb4, 0x13, 0x4f, - 0x32, 0x06, 0xa3, 0x97, 0x25, 0xcc, 0xbf, 0x1c, 0x8e, 0xfd, 0x94, 0x0d, 0xfa, 0xce, 0x23, 0xc5, - 0x72, 0x33, 0xff, 0x32, 0x08, 0x6f, 0xdd, 0x47, 0xef, 0x12, 0x96, 0xa6, 0x06, 0x0a, 0xcd, 0xcc, - 0xe8, 0xbe, 0x7b, 0xe4, 0x4c, 0x16, 0x49, 0x1a, 0x5c, 0x31, 0x01, 0x4d, 0x74, 0xeb, 0x47, 0x45, - 0x60, 0x3a, 0xbd, 0xde, 0x60, 0xaf, 0x52, 0x80, 0xfc, 0x13, 0x80, 0x79, 0x16, 0x5f, 0x06, 0x13, - 0xe3, 0x0d, 0x5b, 0xb0, 0x12, 0x20, 0x00, 0xc3, 0xa4, 0xd9, 0x81, 0xc1, 0xef, 0xe0, 0xe0, 0x4c, - 0x9a, 0x33, 0xd9, 0xe8, 0xa4, 0xd9, 0x05, 0x2e, 0xec, 0x76, 0xe9, 0xb1, 0xe7, 0x7e, 0xd5, 0xeb, - 0xf5, 0xe8, 0xb1, 0xef, 0x7e, 0xd5, 0xef, 0xf7, 0xe9, 0x71, 0x17, 0x08, 0x7a, 0x77, 0x97, 0x1e, - 0x07, 0x52, 0x88, 0x4e, 0x9a, 0xfb, 0x40, 0xfe, 0xfb, 0xfb, 0xf4, 0x38, 0x86, 0xe1, 0x1c, 0x13, - 0x1b, 0x34, 0x27, 0xc0, 0x41, 0x93, 0x09, 0x3d, 0x32, 0x18, 0x18, 0xc6, 0xe8, 0x71, 0xea, 0x7e, - 0x35, 0x9d, 0x4e, 0xe9, 0x11, 0x59, 0xac, 0xc7, 0x5b, 0x3b, 0x87, 0x86, 0x27, 0x1c, 0x9c, 0x10, - 0x5a, 0xdb, 0xf7, 0xe9, 0xf1, 0xd6, 0xfd, 0xca, 0x3f, 0xa0, 0x01, 0x83, 0x7a, 0xdb, 0x2d, 0xde, - 0x6e, 0x8c, 0x92, 0xcf, 0xb7, 0x7a, 0x7d, 0xc7, 0x90, 0xff, 0xda, 0xad, 0x03, 0x9b, 0xbe, 0x65, - 0xe3, 0xcd, 0x8f, 0x57, 0x7e, 0x62, 0x51, 0x0d, 0xb6, 0xcc, 0xe3, 0xf3, 0x4c, 0x9d, 0x76, 0x17, - 0x84, 0xa7, 0xfa, 0xb3, 0x99, 0xef, 0x82, 0xe7, 0xdb, 0xed, 0x38, 0x86, 0xfc, 0x57, 0xcc, 0x94, - 0x5d, 0xb8, 0x7b, 0x5c, 0x42, 0x65, 0x73, 0xf9, 0x04, 0xa5, 0x06, 0x3d, 0x9e, 0x36, 0x9e, 0xbb, - 0x9d, 0xfe, 0xfc, 0xc6, 0xe0, 0x7f, 0xda, 0xe2, 0x09, 0xf3, 0xc0, 0x97, 0x03, 0x78, 0x6d, 0x1b, - 0x7b, 0xf8, 0x97, 0x4a, 0x4d, 0xdd, 0x28, 0x8e, 0x10, 0x45, 0xe9, 0xf9, 0xdc, 0x35, 0xc7, 0x61, - 0x3c, 0xf9, 0x64, 0xe2, 0x87, 0xcb, 0xcc, 0x45, 0x71, 0x31, 0x8e, 0xa7, 0xb7, 0x4b, 0x7d, 0x7c, - 0x9f, 0x24, 0x81, 0x1f, 0x3a, 0xdf, 0xb2, 0xf0, 0x8a, 0x65, 0x40, 0x18, 0x4e, 0xea, 0x47, 0x29, - 0xf0, 0x42, 0x12, 0xcc, 0x80, 0x24, 0x26, 0x9f, 0xce, 0x93, 0x78, 0x11, 0x4d, 0x39, 0xc1, 0x73, - 0xca, 0x12, 0xa0, 0x2b, 0x52, 0xb3, 0x87, 0xb9, 0x44, 0xe2, 0xdf, 0xd4, 0xbb, 0xbd, 0xbe, 0xe8, - 0x38, 0x17, 0xdd, 0xa5, 0x5e, 0xf0, 0x42, 0x96, 0xc2, 0xc9, 0xa3, 0x79, 0xc1, 0x50, 0x70, 0xb9, - 0xbb, 0x00, 0xd9, 0x34, 0xb8, 0x5a, 0xea, 0x69, 0xdd, 0x35, 0xc9, 0xc5, 0xe5, 0xa5, 0x9f, 0x9c, - 0x07, 0x51, 0x33, 0xa1, 0xc4, 0x01, 0xf4, 0x5b, 0xaf, 0x4d, 0x13, 0x9d, 0xf6, 0x5a, 0x48, 0x4c, - 0xde, 0x3d, 0xd2, 0x1f, 0xdc, 0x20, 0xf3, 0x81, 0xdc, 0x87, 0xa2, 0x8e, 0x90, 0xcd, 0x36, 0xab, - 0x28, 0xc8, 0x59, 0x7b, 0x1d, 0x44, 0xf3, 0x45, 0xb6, 0xd4, 0xba, 0xde, 0x36, 0x3e, 0xa7, 0xe7, - 0x38, 0x9d, 0x70, 0x09, 0xf2, 0xf7, 0x95, 0x8d, 0xe7, 0xc8, 0x92, 0xcb, 0x6d, 0x99, 0xb5, 0x3a, - 0xf9, 0x47, 0xc9, 0xfd, 0xf6, 0xda, 0xaf, 0x46, 0x2f, 0x95, 0x9e, 0xb2, 0x49, 0x9c, 0x10, 0xb3, - 0x13, 0x55, 0xac, 0x31, 0xd1, 0x07, 0x76, 0x5f, 0x5e, 0x07, 0x53, 0x20, 0x3a, 0x9c, 0x90, 0x87, - 0x02, 0xdd, 0xf4, 0x2c, 0xe6, 0x2d, 0x9c, 0xcf, 0x17, 0xa9, 0xdb, 0xe9, 0x02, 0xaa, 0x3e, 0xaf, - 0x37, 0xeb, 0x89, 0x1f, 0x5d, 0xf9, 0xe9, 0x97, 0xd4, 0x4b, 0x49, 0x6e, 0x07, 0x08, 0x37, 0x8d, - 0xc3, 0x60, 0x6a, 0x10, 0x89, 0x95, 0x5b, 0x03, 0x79, 0x03, 0xcd, 0x4d, 0xd9, 0xcc, 0x5f, 0x84, - 0xd9, 0xba, 0x05, 0xda, 0x9f, 0x1f, 0x2e, 0xe7, 0x71, 0x1a, 0x50, 0x9f, 0x66, 0xc1, 0x0d, 0x9b, - 0x0e, 0x69, 0x54, 0xa1, 0x28, 0x69, 0x1e, 0xf0, 0xc0, 0x29, 0xa5, 0x3d, 0xcc, 0xe2, 0xb9, 0xab, - 0xd7, 0xd8, 0x2c, 0x8c, 0x7a, 0x33, 0x06, 0x1c, 0x25, 0x40, 0xec, 0xb3, 0x38, 0xb9, 0x74, 0xe9, - 0x29, 0xf4, 0x33, 0xf6, 0x93, 0xc5, 0xb5, 0x14, 0x4a, 0xe0, 0xad, 0xa8, 0x5c, 0x46, 0xab, 0x9f, - 0x0e, 0xe7, 0xfe, 0x74, 0x1a, 0x44, 0xe7, 0x38, 0x68, 0xc3, 0xf8, 0x8a, 0x25, 0xb3, 0x30, 0xbe, - 0x76, 0xfd, 0x45, 0x16, 0x97, 0x3a, 0xd9, 0x87, 0x4e, 0xae, 0x5b, 0x11, 0x52, 0xb5, 0x4e, 0x7d, - 0x34, 0x67, 0xb7, 0x32, 0x7f, 0x1c, 0xb2, 0xcf, 0x66, 0x43, 0xa5, 0x4c, 0x84, 0xfe, 0x3c, 0x65, - 0xae, 0x7c, 0x18, 0x6a, 0xc8, 0x2e, 0x21, 0xb8, 0xad, 0x10, 0x2c, 0xf8, 0xe0, 0x22, 0x98, 0x4e, - 0x59, 0x04, 0x69, 0x37, 0xcd, 0xf4, 0xc2, 0x9f, 0x02, 0xc8, 0x80, 0x5e, 0xf8, 0x0f, 0xd1, 0x8f, - 0xe2, 0x57, 0x80, 0x64, 0x64, 0x53, 0x47, 0x3e, 0x5d, 0x2c, 0xab, 0x87, 0x48, 0x22, 0x00, 0xf9, - 0x08, 0xfa, 0x8f, 0xd0, 0x86, 0x4d, 0xe0, 0xb2, 0x73, 0xc0, 0x54, 0x3c, 0x5f, 0xe7, 0xc5, 0x89, - 0x3c, 0xf8, 0x07, 0xec, 0xfa, 0xb6, 0x91, 0xc8, 0x14, 0xc9, 0x6e, 0x65, 0xec, 0xd6, 0xe5, 0x34, - 0x7c, 0x06, 0xc8, 0xf2, 0x41, 0x3c, 0x24, 0xdd, 0xe5, 0x34, 0x48, 0xe7, 0xa1, 0x7f, 0xeb, 0x9e, - 0x27, 0xc1, 0x74, 0x88, 0x7f, 0x80, 0x12, 0x2f, 0xe7, 0x38, 0x7a, 0x58, 0x60, 0x71, 0x19, 0xa5, - 0x6e, 0xc2, 0xe6, 0xcc, 0xcf, 0xac, 0xae, 0xd3, 0x99, 0x95, 0xcb, 0xf7, 0xbe, 0xa0, 0x7c, 0xaf, - 0xa2, 0x7c, 0xff, 0x0b, 0xca, 0xf7, 0x45, 0x79, 0x98, 0x75, 0x81, 0x74, 0x1d, 0xa4, 0x5f, 0x30, - 0x75, 0x9c, 0x56, 0x7a, 0x9b, 0xd2, 0xfb, 0x02, 0x46, 0x18, 0x2d, 0x1a, 0x81, 0xe9, 0xae, 0xc2, - 0xb4, 0x60, 0x72, 0x4d, 0x8d, 0xbc, 0x4b, 0x06, 0x54, 0x0d, 0xbf, 0x1c, 0x26, 0x10, 0xad, 0x42, - 0xfc, 0xd1, 0xa3, 0xe0, 0xa8, 0x4b, 0x20, 0x5d, 0x09, 0x56, 0x0b, 0xc9, 0xd8, 0xe1, 0x7d, 0x44, - 0xe8, 0xe5, 0x3b, 0xc1, 0x2a, 0x5e, 0x38, 0xc0, 0xe2, 0x45, 0x40, 0x4d, 0x6f, 0x3a, 0xe8, 0x53, - 0xe0, 0x40, 0x56, 0x09, 0xfb, 0xfa, 0xab, 0x49, 0x1c, 0x45, 0x41, 0x34, 0x2d, 0xf3, 0xae, 0x60, - 0x5a, 0x20, 0xa1, 0x89, 0x25, 0xca, 0x5d, 0xd8, 0x46, 0xc3, 0x00, 0x50, 0x6d, 0xce, 0xd8, 0xfd, - 0x52, 0x5f, 0x8a, 0x5d, 0xdd, 0x2d, 0x48, 0x28, 0xa9, 0xfb, 0xe0, 0x64, 0xff, 0x7b, 0x13, 0x9a, - 0x63, 0x37, 0x6e, 0xb3, 0x0b, 0x24, 0x19, 0xc7, 0x61, 0x16, 0xcc, 0xf3, 0xc6, 0x13, 0x06, 0xa3, - 0x05, 0x8a, 0xcc, 0x50, 0x0e, 0x65, 0x10, 0xd1, 0xd4, 0x43, 0xd3, 0xa5, 0x6c, 0x42, 0xc0, 0xd6, - 0xc9, 0x7b, 0x86, 0xf4, 0xaf, 0x6a, 0x33, 0xe4, 0x03, 0xd2, 0xf9, 0xf2, 0x2a, 0x48, 0x83, 0x71, - 0x10, 0x06, 0xd9, 0xad, 0xe4, 0x35, 0xc1, 0x9d, 0xdd, 0x76, 0x15, 0x88, 0xe5, 0x01, 0xdc, 0x9c, - 0xb2, 0xb6, 0x4f, 0x51, 0x43, 0x8d, 0xb1, 0x26, 0x90, 0xcc, 0x12, 0x1d, 0x41, 0x46, 0xbb, 0x84, - 0x22, 0xe4, 0x53, 0xd5, 0x71, 0x7f, 0x0c, 0xf4, 0xb5, 0xc8, 0x98, 0x42, 0x4f, 0x47, 0x0e, 0x41, - 0xa7, 0xbb, 0xfb, 0x07, 0x8e, 0xf1, 0x5d, 0x90, 0x27, 0xba, 0xc8, 0x6a, 0x0e, 0xb0, 0x0b, 0x31, - 0xe8, 0xc0, 0xd8, 0xbb, 0xb6, 0x2e, 0x1a, 0x45, 0xa2, 0xd1, 0xea, 0xa5, 0xd5, 0x78, 0x71, 0x5d, - 0x7f, 0x06, 0x00, 0xc2, 0x14, 0x05, 0x70, 0x46, 0x99, 0x6b, 0x9a, 0x15, 0xb0, 0xa0, 0xa0, 0x26, - 0x29, 0x56, 0xdd, 0xbc, 0x36, 0xea, 0x1c, 0xa7, 0xbb, 0x65, 0xe9, 0x46, 0x3c, 0x33, 0x2c, 0x1a, - 0x5d, 0xa0, 0x5e, 0x1a, 0x04, 0xe9, 0x1c, 0x26, 0xbc, 0x28, 0xdb, 0xf6, 0xac, 0xc0, 0x76, 0x2f, - 0x90, 0x9c, 0xb7, 0x0e, 0x2a, 0x3d, 0x86, 0x4c, 0xa1, 0xa1, 0xb3, 0x6e, 0xf1, 0xe9, 0x1e, 0x8c, - 0xf9, 0x0d, 0xc6, 0xd4, 0x4d, 0x09, 0x7b, 0xfd, 0xe0, 0x70, 0x87, 0x3b, 0x33, 0x8c, 0xc3, 0x74, - 0x92, 0x40, 0xd5, 0x47, 0x0f, 0x76, 0x76, 0x8c, 0x7f, 0x81, 0x41, 0x66, 0x51, 0xca, 0x0c, 0xc3, - 0xf8, 0xe6, 0xcd, 0x07, 0xe3, 0x9b, 0x17, 0x6f, 0x5e, 0x7c, 0xff, 0xe4, 0x95, 0xf1, 0xee, 0xc3, - 0xd3, 0x57, 0x2f, 0x9f, 0x19, 0xf0, 0xef, 0xc5, 0x9b, 0xe3, 0x17, 0xc6, 0x0f, 0x0c, 0x14, 0xee, - 0x38, 0x32, 0x7a, 0x8e, 0xd1, 0x3d, 0x30, 0xbe, 0x5b, 0x44, 0xcc, 0xe8, 0xb6, 0xdb, 0x7b, 0xa5, - 0x0a, 0xbe, 0x8e, 0x13, 0x03, 0xe6, 0x77, 0xe3, 0x9b, 0x77, 0xaf, 0x9a, 0x57, 0x3d, 0x63, 0x91, - 0xfa, 0xe7, 0xcc, 0x31, 0x88, 0x6a, 0x92, 0x09, 0xcc, 0x2b, 0x86, 0xc8, 0x9a, 0x1a, 0x97, 0x8b, - 0x34, 0x33, 0xc6, 0xcc, 0x98, 0x2f, 0x92, 0xc9, 0x05, 0x68, 0xfc, 0xd3, 0x96, 0x41, 0x82, 0x6d, - 0x92, 0x19, 0x97, 0x71, 0x1c, 0x71, 0x9e, 0x4f, 0xff, 0x25, 0x98, 0x84, 0xf1, 0x62, 0xda, 0x82, - 0x1a, 0x1e, 0xcc, 0x16, 0xd1, 0x04, 0x87, 0xcb, 0x00, 0x61, 0xf1, 0xc6, 0xbf, 0x64, 0x96, 0xbd, - 0x4c, 0x58, 0xb6, 0x48, 0x22, 0xf3, 0x15, 0x9b, 0x9a, 0x6b, 0xf5, 0x19, 0x85, 0xc2, 0xd7, 0x8b, - 0xc8, 0x62, 0xf6, 0x32, 0x98, 0x59, 0x1d, 0xcf, 0x63, 0x27, 0xed, 0xd3, 0x7a, 0xfd, 0xd7, 0x34, - 0x8e, 0x7e, 0xf0, 0xc1, 0xf8, 0x4b, 0x5b, 0xf3, 0xab, 0x80, 0x5d, 0xcb, 0xd2, 0xc6, 0x3c, 0x61, - 0xf8, 0xde, 0x7b, 0x6e, 0x9d, 0xbf, 0x9c, 0x5a, 0x26, 0x7d, 0x34, 0x6d, 0x87, 0xd9, 0x4e, 0xad, - 0xbd, 0xe6, 0x79, 0x6a, 0x9d, 0xbc, 0x7a, 0x91, 0xbd, 0xfb, 0xdc, 0x62, 0x4e, 0x64, 0x2f, 0x43, - 0x06, 0xa3, 0xe8, 0xb1, 0xd6, 0x39, 0xcb, 0x10, 0x7e, 0x18, 0x2c, 0xcb, 0xec, 0x4e, 0xa1, 0x7c, - 0xea, 0xed, 0x0e, 0xa1, 0xfd, 0xac, 0x35, 0x09, 0x99, 0x9f, 0x7c, 0x0f, 0xc3, 0x60, 0xb5, 0x9d, - 0xb6, 0xc3, 0x5a, 0x44, 0x3a, 0xf0, 0xcb, 0xd5, 0x12, 0xdb, 0xd9, 0x04, 0x0c, 0xeb, 0x0c, 0xbd, - 0xd7, 0x7e, 0x76, 0xd1, 0xba, 0x0c, 0xa0, 0x23, 0xbc, 0xc8, 0x4e, 0x39, 0x63, 0xa9, 0xa6, 0xcd, - 0xef, 0xb2, 0x85, 0x80, 0xd7, 0x05, 0x0a, 0x42, 0x9c, 0x58, 0xb2, 0xba, 0x66, 0xf8, 0xb8, 0xba, - 0x42, 0x7b, 0xa7, 0x6b, 0x23, 0xe4, 0x1b, 0x5f, 0xe3, 0x45, 0x06, 0x1a, 0x69, 0x6a, 0x83, 0x06, - 0x82, 0x22, 0xd2, 0x88, 0x8d, 0x78, 0x66, 0x6c, 0xcd, 0x05, 0x35, 0xc4, 0xad, 0xf1, 0x62, 0x36, - 0x63, 0x89, 0x2a, 0xe1, 0x63, 0x09, 0x95, 0x1a, 0x9d, 0xa4, 0xa7, 0x0d, 0xf8, 0xd3, 0xe8, 0xf0, - 0x9f, 0xee, 0xe9, 0x51, 0xb7, 0x5d, 0xaf, 0x03, 0xca, 0x66, 0x41, 0x18, 0x1e, 0x23, 0xa5, 0x7a, - 0x67, 0xe8, 0x14, 0x7a, 0xb8, 0xc4, 0xac, 0x6b, 0x87, 0x7e, 0x21, 0xb7, 0x7c, 0xea, 0x9e, 0xae, - 0xed, 0x33, 0x07, 0x4c, 0x7a, 0x06, 0x3c, 0xfa, 0x0e, 0xba, 0x68, 0xd9, 0xf0, 0xe6, 0x27, 0x13, - 0xcb, 0x87, 0x21, 0x7f, 0x1c, 0xee, 0x74, 0xda, 0x8d, 0xc0, 0xf1, 0x4f, 0x3a, 0xfc, 0xd9, 0x69, - 0xf5, 0x1f, 0x87, 0x30, 0x04, 0xdd, 0xc7, 0x84, 0x8e, 0x77, 0x2f, 0x31, 0x37, 0x36, 0x65, 0xd9, - 0x30, 0x5c, 0x0d, 0xaf, 0x37, 0x64, 0x21, 0x50, 0x31, 0x48, 0x08, 0x60, 0x63, 0xd6, 0x0a, 0xe3, - 0x73, 0xa0, 0x06, 0x39, 0xda, 0x5a, 0x47, 0x81, 0xc2, 0x8d, 0x90, 0x4d, 0x53, 0x73, 0x73, 0xe8, - 0x36, 0x52, 0xbc, 0x68, 0x11, 0x86, 0x5f, 0x50, 0xaf, 0xc0, 0xde, 0xe7, 0x57, 0xbd, 0x81, 0xff, - 0x48, 0x7c, 0x59, 0xaf, 0x91, 0x8c, 0x40, 0xb2, 0x80, 0x28, 0x62, 0x09, 0x25, 0x39, 0x29, 0x30, - 0x1f, 0xe3, 0x8f, 0x13, 0xe0, 0xa0, 0xc4, 0xe7, 0x75, 0xe0, 0xd0, 0xa0, 0x5c, 0x4c, 0xe2, 0x30, - 0xe5, 0x29, 0x54, 0xd4, 0xbf, 0x9d, 0xf8, 0x69, 0x26, 0xcb, 0x06, 0x28, 0xdf, 0x53, 0x20, 0x63, - 0xfe, 0x7a, 0x19, 0x03, 0x9f, 0xbd, 0x8b, 0x29, 0x95, 0x97, 0x29, 0x73, 0x48, 0x4f, 0x70, 0x48, - 0x70, 0x39, 0x8f, 0x13, 0xe0, 0x8a, 0xec, 0x22, 0x61, 0xcc, 0xb4, 0x5b, 0xd9, 0x05, 0x8b, 0xac, - 0xcc, 0x3b, 0x5a, 0xaa, 0x02, 0xa9, 0x25, 0x18, 0x29, 0xe5, 0x8c, 0xf4, 0x14, 0x25, 0x18, 0xcc, - 0x22, 0xcf, 0x42, 0x74, 0xe6, 0x11, 0xeb, 0xd8, 0x43, 0xbd, 0xc1, 0xd5, 0xca, 0x2a, 0xb6, 0xcf, - 0xae, 0x8d, 0xac, 0xf5, 0x03, 0x64, 0x8c, 0x93, 0xae, 0x5d, 0x80, 0xad, 0x75, 0xe3, 0x59, 0x11, - 0xf0, 0x20, 0xd6, 0xf4, 0xe7, 0x66, 0xda, 0x42, 0x49, 0x6e, 0xef, 0xa4, 0x9c, 0xd4, 0x1f, 0x77, - 0x9b, 0x9d, 0x62, 0xee, 0x5b, 0xaf, 0xa9, 0xb2, 0xff, 0x04, 0xd9, 0x61, 0x46, 0xc0, 0xdc, 0x9c, - 0x93, 0x1e, 0x77, 0x1b, 0x1d, 0x42, 0x4d, 0xec, 0x91, 0xa8, 0xe0, 0xa6, 0xc6, 0x6b, 0x16, 0x2d, - 0xa0, 0x5b, 0xdb, 0xe0, 0xce, 0x5b, 0x3f, 0x8c, 0xa9, 0xf5, 0xd5, 0x4a, 0xa5, 0x1c, 0xc5, 0x2d, - 0xb2, 0x11, 0xf2, 0xa4, 0x9f, 0x20, 0x13, 0xb4, 0xa9, 0x25, 0x40, 0x1e, 0x3e, 0x31, 0xda, 0xc0, - 0x1a, 0x9b, 0xcd, 0x92, 0x40, 0x6f, 0x09, 0xed, 0xc1, 0x33, 0xd1, 0xb8, 0x32, 0xed, 0x5c, 0x5a, - 0xc5, 0x42, 0x0c, 0xb2, 0x16, 0x8e, 0x0a, 0xd4, 0xf7, 0x9c, 0x5b, 0x30, 0xc0, 0x29, 0x05, 0x7a, - 0x44, 0xe7, 0x37, 0xa0, 0xe1, 0x79, 0x7c, 0x1d, 0x99, 0x0e, 0xcb, 0x07, 0xdb, 0xd6, 0x1e, 0x97, - 0xdb, 0x5a, 0xc7, 0x5e, 0xc1, 0xc8, 0x89, 0x4e, 0x35, 0xcc, 0xf9, 0x8d, 0xe9, 0x6c, 0xcb, 0x0b, - 0x9d, 0x53, 0x59, 0x7f, 0xba, 0x3b, 0xab, 0xea, 0x94, 0x49, 0x48, 0x8f, 0x3c, 0x05, 0x4a, 0x2b, - 0x02, 0xea, 0x6d, 0xc1, 0xd7, 0x00, 0xe8, 0xca, 0x68, 0x1a, 0xa6, 0x3d, 0xd4, 0x2a, 0x79, 0xee, - 0x67, 0x3e, 0x54, 0x12, 0x44, 0xa0, 0x23, 0xbf, 0x07, 0x81, 0xec, 0x6d, 0x93, 0x51, 0x27, 0x11, - 0x88, 0x89, 0xd3, 0x16, 0xf2, 0x32, 0x3c, 0x76, 0x4e, 0x4f, 0xd7, 0xeb, 0x02, 0xb1, 0xee, 0x80, - 0x32, 0x03, 0x48, 0xda, 0x91, 0xbc, 0xb1, 0xf3, 0x36, 0x19, 0x07, 0x24, 0xe6, 0xf1, 0xad, 0xf5, - 0x6b, 0x2a, 0xa9, 0xd9, 0x07, 0x6a, 0xe6, 0x42, 0xbb, 0x45, 0x42, 0xdf, 0xaa, 0x49, 0xbe, 0x5b, - 0xad, 0xca, 0x8d, 0x6f, 0xce, 0x44, 0xc8, 0xb2, 0x38, 0xb8, 0x55, 0x02, 0xa2, 0xf7, 0xdc, 0x98, - 0x80, 0x99, 0x9c, 0x31, 0x03, 0x69, 0x5c, 0xd6, 0x0a, 0xd3, 0x4b, 0xce, 0xd8, 0x44, 0xfb, 0x3f, - 0xb2, 0xf1, 0x37, 0xaf, 0xbe, 0x17, 0x69, 0xd6, 0x92, 0x23, 0xc2, 0x65, 0x8e, 0x1f, 0x65, 0x30, - 0xed, 0x06, 0xf0, 0x5c, 0x6b, 0x3b, 0x7e, 0x38, 0xbf, 0xf0, 0xe1, 0x61, 0x9d, 0x17, 0x07, 0xdd, - 0x21, 0x7b, 0x86, 0x13, 0xd4, 0x13, 0xfc, 0x66, 0xb5, 0x2b, 0xbe, 0x3c, 0x43, 0xe5, 0x01, 0xe7, - 0x2e, 0x5b, 0x09, 0x0d, 0x6a, 0xf2, 0x1d, 0x8c, 0xc5, 0x1c, 0x06, 0x03, 0xb4, 0xd7, 0x67, 0x94, - 0x6e, 0xf5, 0x77, 0xe5, 0xf4, 0xb6, 0x23, 0xa7, 0xb9, 0x8e, 0xb3, 0xdb, 0x56, 0x05, 0x5b, 0x52, - 0xe3, 0xc2, 0xba, 0x69, 0x36, 0x0c, 0xb9, 0x28, 0x4e, 0x7f, 0x03, 0x9c, 0x57, 0xcf, 0x46, 0x5b, - 0x26, 0xa9, 0xc6, 0x96, 0xc9, 0xee, 0xf1, 0x96, 0xf4, 0xcd, 0xfc, 0x53, 0x36, 0xaf, 0xaa, 0x9d, - 0x92, 0x6d, 0x05, 0x31, 0x4c, 0x99, 0x9f, 0x9e, 0x70, 0x58, 0xa1, 0x1b, 0x42, 0x7e, 0x52, 0xf7, - 0x8f, 0xf1, 0x99, 0xa7, 0xb4, 0x72, 0xbd, 0x8b, 0x0b, 0x47, 0x2b, 0x97, 0xa6, 0x90, 0xd7, 0x6f, - 0x15, 0xe8, 0xc6, 0xe2, 0x55, 0xe7, 0x88, 0x9e, 0xc6, 0x97, 0x2f, 0x42, 0x86, 0x7a, 0xb5, 0x0d, - 0xf4, 0x04, 0x0a, 0x27, 0xcb, 0x04, 0x82, 0x5a, 0xbb, 0x84, 0x75, 0x49, 0x70, 0x8b, 0xf9, 0x14, - 0x28, 0xc1, 0xd2, 0x52, 0x58, 0x84, 0x36, 0xee, 0x3b, 0x3f, 0xf2, 0x6a, 0x9d, 0x72, 0xea, 0x73, - 0xff, 0x72, 0x0e, 0xc2, 0xc8, 0x83, 0x81, 0xd7, 0x44, 0x39, 0xc1, 0xfe, 0xbd, 0x7c, 0x87, 0xf1, - 0x02, 0x1a, 0x7f, 0x81, 0x82, 0xe1, 0x55, 0x00, 0x09, 0xc0, 0x31, 0x96, 0x49, 0x02, 0x11, 0xed, - 0x32, 0xd3, 0x49, 0xed, 0xed, 0x39, 0xa6, 0x24, 0x2b, 0x62, 0xa7, 0xd6, 0xb1, 0x75, 0x16, 0x7e, - 0xba, 0x00, 0x61, 0x15, 0x75, 0x0a, 0x0c, 0x68, 0x1e, 0x03, 0x73, 0x70, 0x2f, 0xb2, 0x24, 0x01, - 0x73, 0xb3, 0x4c, 0x77, 0xb3, 0xcc, 0x8b, 0x68, 0x7a, 0x57, 0x89, 0xde, 0x66, 0x89, 0xd7, 0xc1, - 0x9d, 0x25, 0x10, 0xae, 0xcd, 0xfe, 0x80, 0x38, 0x9a, 0x7c, 0x32, 0x1d, 0x4b, 0x8a, 0x4d, 0x50, - 0x2d, 0x71, 0x4e, 0x64, 0xde, 0x72, 0x3d, 0x04, 0x61, 0xa5, 0xa4, 0x8a, 0x67, 0xe2, 0xca, 0x1f, - 0x18, 0x0f, 0x8d, 0x3b, 0xc4, 0x0d, 0x0c, 0xec, 0x6f, 0x40, 0x4f, 0xd9, 0x77, 0x40, 0x5a, 0x20, - 0x7d, 0x9d, 0xcf, 0x93, 0xd9, 0xc0, 0x93, 0x95, 0x88, 0xec, 0xfe, 0x83, 0x00, 0x03, 0x91, 0xfd, - 0xaf, 0x04, 0xb7, 0xf7, 0x0f, 0x82, 0x7b, 0x19, 0xfc, 0x07, 0x82, 0xbb, 0xa9, 0x43, 0x6d, 0x11, - 0xc6, 0x04, 0x5d, 0xe0, 0x81, 0x8a, 0xbc, 0x45, 0x2a, 0x35, 0x3b, 0xa0, 0x25, 0x3b, 0x49, 0x75, - 0x0e, 0x2e, 0x71, 0x78, 0x96, 0x45, 0x75, 0x16, 0x92, 0x32, 0x94, 0x03, 0xa7, 0x8b, 0x2d, 0x82, - 0x1f, 0x79, 0x35, 0x2f, 0xf9, 0x39, 0x2a, 0xa1, 0x52, 0xbe, 0x69, 0x36, 0x62, 0x5e, 0x7b, 0x28, - 0x35, 0xef, 0xc9, 0x9d, 0xba, 0x3a, 0x6a, 0x08, 0x13, 0x9a, 0x07, 0x79, 0xc9, 0x48, 0x2b, 0x39, - 0xc7, 0x92, 0xf2, 0x23, 0x58, 0x53, 0x73, 0x78, 0x8c, 0xce, 0xb3, 0x8b, 0x7a, 0x7d, 0xde, 0x9a, - 0x2f, 0xd2, 0x0b, 0x9c, 0x33, 0x64, 0xda, 0xa1, 0xd7, 0xd5, 0x92, 0x87, 0xd8, 0x2f, 0x54, 0xea, - 0x84, 0xc0, 0x9c, 0x5f, 0x80, 0xb8, 0xfb, 0x86, 0xc5, 0x97, 0x2c, 0x4b, 0x6e, 0xad, 0x16, 0x28, - 0x6a, 0xb1, 0xf8, 0xf4, 0x9a, 0xa5, 0x17, 0x4f, 0xfd, 0x34, 0x98, 0xc0, 0x6c, 0xc0, 0xd0, 0xff, - 0x68, 0x2d, 0x35, 0xcb, 0x18, 0xa7, 0x2e, 0x69, 0xed, 0xb6, 0xf6, 0x60, 0x28, 0x7d, 0xad, 0x98, - 0x95, 0x3a, 0xb1, 0x3d, 0x2c, 0x4d, 0x2d, 0x41, 0x23, 0x7c, 0x3c, 0x87, 0xb9, 0x1d, 0x95, 0xfe, - 0x66, 0xd2, 0xc4, 0x97, 0x0e, 0x7f, 0x59, 0xd0, 0x4b, 0x17, 0x5f, 0xa0, 0x1e, 0xd2, 0x23, 0x3c, - 0xd6, 0x20, 0x1d, 0xa2, 0x11, 0x35, 0x1a, 0x42, 0x9e, 0x03, 0x05, 0x5b, 0xbe, 0xbd, 0x5e, 0x6f, - 0xd5, 0xdb, 0x7b, 0xff, 0xa0, 0x3d, 0xd0, 0x68, 0x7c, 0x49, 0xe5, 0xff, 0x44, 0xa3, 0xa0, 0xc2, - 0xae, 0xb3, 0x97, 0x62, 0xb2, 0xae, 0x29, 0xc5, 0xec, 0x47, 0x7c, 0x2d, 0x6b, 0x24, 0x00, 0x16, - 0xe5, 0x37, 0xf8, 0x34, 0x64, 0xe0, 0x8a, 0x81, 0xa9, 0xd9, 0xb3, 0x5a, 0x51, 0x65, 0x93, 0xaa, - 0xe4, 0x6f, 0x85, 0x29, 0xaa, 0x6b, 0x17, 0xc7, 0x50, 0x81, 0x55, 0x2e, 0xa7, 0xbf, 0x21, 0xcb, - 0x0e, 0xb9, 0x5d, 0xb0, 0x4b, 0x46, 0xca, 0x95, 0xd7, 0xf9, 0x2c, 0xcb, 0x74, 0x72, 0x9f, 0x65, - 0x2a, 0xe8, 0xb9, 0x8a, 0xc6, 0xaf, 0x0e, 0x39, 0x0d, 0x4c, 0x2e, 0x82, 0x70, 0x0a, 0xe0, 0x2a, - 0x72, 0xb7, 0x8a, 0xe9, 0x27, 0x57, 0xa7, 0x2d, 0xe1, 0x8b, 0xf1, 0xa2, 0x93, 0xde, 0xe3, 0xab, - 0x06, 0x59, 0xb3, 0xf4, 0xc0, 0x2d, 0x5a, 0xfe, 0x08, 0x56, 0x2d, 0x10, 0xde, 0xd6, 0xb2, 0x95, - 0xf5, 0x5e, 0x0a, 0x36, 0x68, 0x91, 0xe3, 0x46, 0x50, 0x3b, 0xd7, 0xc3, 0x4c, 0x53, 0xd6, 0x7c, - 0xba, 0x83, 0x9b, 0x25, 0xf2, 0x77, 0x68, 0xb4, 0x9c, 0xd2, 0xa5, 0x14, 0x1b, 0x04, 0xdf, 0x55, - 0xa3, 0x31, 0xfc, 0x0f, 0xa3, 0xe6, 0xff, 0x30, 0x42, 0x46, 0x72, 0xe5, 0xd8, 0x49, 0xe2, 0x8c, - 0x56, 0x8f, 0xc0, 0x9c, 0x43, 0x4d, 0x1d, 0xbb, 0x25, 0xad, 0xf8, 0xc7, 0x5d, 0xa7, 0x94, 0xe7, - 0x16, 0xf2, 0x74, 0xef, 0xc9, 0xf3, 0x3b, 0x0e, 0x5a, 0x39, 0xcf, 0xa6, 0xa6, 0xa5, 0x1b, 0x87, - 0xf6, 0x52, 0xe9, 0x51, 0x48, 0xbe, 0x5f, 0x27, 0xf1, 0xa5, 0x50, 0x7c, 0xf5, 0x5c, 0x42, 0x73, - 0x94, 0xd2, 0x8f, 0x79, 0x79, 0x21, 0x65, 0xbf, 0xbc, 0x1d, 0xff, 0x0a, 0x7f, 0xd3, 0xd2, 0xc8, - 0x3b, 0x35, 0x90, 0x99, 0x4c, 0xd0, 0xdb, 0x51, 0x7b, 0xa4, 0xb2, 0xd7, 0xc8, 0x85, 0xd5, 0x8a, - 0xa9, 0x14, 0x10, 0x8c, 0xfa, 0x50, 0xaf, 0xe7, 0x26, 0x51, 0x91, 0x66, 0x10, 0xc0, 0x6f, 0xd9, - 0x4d, 0x9e, 0xb5, 0x35, 0x59, 0x24, 0x09, 0x31, 0xe2, 0x8d, 0x66, 0xd3, 0xe9, 0x15, 0x3b, 0x55, - 0x79, 0xbd, 0xad, 0x0d, 0x9c, 0xf3, 0x06, 0xb4, 0xca, 0xb6, 0x80, 0xd0, 0x19, 0xec, 0x75, 0x3a, - 0x83, 0xfd, 0xb6, 0x6d, 0xbb, 0xff, 0x4c, 0xc8, 0x91, 0x3e, 0xec, 0xb5, 0x92, 0x27, 0xfc, 0x81, - 0x63, 0x54, 0x0e, 0xc1, 0x1a, 0xff, 0x43, 0xa7, 0x27, 0x77, 0x76, 0xfe, 0xff, 0xd2, 0xeb, 0x89, - 0xe2, 0x6f, 0xea, 0x4d, 0xe3, 0xc9, 0x02, 0x0d, 0x04, 0xe7, 0x9a, 0x3b, 0x68, 0x9c, 0x28, 0x79, - 0x3b, 0x7b, 0x2d, 0xd7, 0x49, 0x52, 0xaf, 0xaf, 0xf1, 0x0f, 0x28, 0x55, 0xce, 0x22, 0xf8, 0x7a, - 0x11, 0x3d, 0x03, 0x00, 0xfc, 0x68, 0x9a, 0x7a, 0x27, 0xa7, 0x40, 0xc7, 0x53, 0x16, 0xe2, 0x43, - 0xea, 0x5f, 0xb1, 0xe9, 0x0f, 0x8a, 0x77, 0x39, 0x91, 0x7e, 0x78, 0xf9, 0xe6, 0xfd, 0xfe, 0x2f, - 0xaf, 0x9f, 0xfc, 0xd9, 0x43, 0x01, 0x82, 0x6f, 0x9d, 0x01, 0xbd, 0x0e, 0x76, 0x77, 0x7b, 0xbb, - 0xb9, 0x67, 0x07, 0x95, 0x2d, 0xa6, 0x1c, 0xa7, 0x53, 0xa4, 0x01, 0x61, 0xb9, 0x3c, 0xbd, 0xa5, - 0x4f, 0xb9, 0xe3, 0x61, 0xf2, 0xa2, 0x90, 0x93, 0x1b, 0xb1, 0x22, 0x73, 0x21, 0xe3, 0x05, 0x80, - 0x18, 0xb2, 0x1f, 0x94, 0x83, 0xfb, 0x19, 0x24, 0x9c, 0xa3, 0x73, 0xb7, 0x20, 0x51, 0xaa, 0x73, - 0x15, 0x3c, 0x1d, 0xd1, 0xab, 0xd8, 0x9f, 0x42, 0x39, 0x00, 0xea, 0xfd, 0x05, 0xbb, 0x24, 0xee, - 0xf5, 0x3f, 0xb1, 0x1f, 0x8f, 0x89, 0x46, 0x83, 0x2c, 0x47, 0x17, 0x24, 0x4c, 0x2b, 0xb4, 0xd4, - 0xdc, 0xc9, 0x3e, 0xe1, 0xb5, 0x3b, 0xd5, 0xad, 0xe2, 0xbc, 0x94, 0xb7, 0x2b, 0xdb, 0x40, 0x1d, - 0xea, 0x3a, 0xb5, 0x79, 0x8f, 0x87, 0x5c, 0xff, 0x02, 0xb8, 0xb3, 0x6c, 0x9e, 0xba, 0xa6, 0xe7, - 0x5d, 0x07, 0x11, 0x18, 0x4c, 0xd0, 0x19, 0xbe, 0xe5, 0xa5, 0x35, 0x07, 0x49, 0x14, 0x03, 0xc1, - 0x8f, 0xcc, 0xeb, 0x34, 0x35, 0x5d, 0xf8, 0x6b, 0xda, 0x0d, 0xd3, 0xdd, 0xd9, 0x31, 0x1b, 0xe5, - 0xac, 0x17, 0x71, 0x9a, 0xa1, 0xa2, 0xd2, 0x30, 0x77, 0x20, 0xd7, 0xb0, 0x80, 0x17, 0xde, 0xba, - 0xb1, 0x48, 0x42, 0x13, 0x3d, 0xd6, 0xd7, 0x5c, 0xd9, 0xfa, 0x91, 0x8d, 0x8f, 0xe3, 0xc9, 0x27, - 0x86, 0x98, 0x86, 0xb4, 0xd6, 0x38, 0x88, 0xfc, 0xe4, 0xf6, 0xfd, 0xed, 0x9c, 0x79, 0xa6, 0x9f, - 0x80, 0x40, 0xe2, 0x1e, 0x58, 0x13, 0xbf, 0x01, 0xd5, 0xb1, 0x14, 0x29, 0xd6, 0x63, 0xde, 0x11, - 0x77, 0x15, 0xe1, 0xfe, 0x1c, 0x23, 0x00, 0xc2, 0xf0, 0xa3, 0x09, 0x83, 0x99, 0xf1, 0x09, 0x16, - 0x79, 0xca, 0x9d, 0xb6, 0xc2, 0xcf, 0x81, 0xad, 0x7c, 0x00, 0x66, 0xdc, 0xa7, 0x6f, 0xa2, 0x0c, - 0xb9, 0x8d, 0xdb, 0x9e, 0x17, 0x82, 0x50, 0xb1, 0x97, 0x62, 0x12, 0x78, 0x1a, 0xfb, 0xc9, 0x94, - 0x3b, 0xae, 0xc6, 0xf8, 0x68, 0xda, 0x0e, 0xf0, 0x2d, 0xcd, 0x19, 0xd2, 0x53, 0x2f, 0xde, 0x97, - 0xe4, 0x29, 0x7f, 0x1f, 0x5c, 0x32, 0x98, 0x27, 0x68, 0x92, 0x17, 0xcf, 0x7c, 0x76, 0x10, 0x2f, - 0x9c, 0xfe, 0xb9, 0xda, 0xcf, 0x97, 0xf2, 0x94, 0xce, 0x9f, 0x9b, 0xe1, 0x34, 0x57, 0x7a, 0xa6, - 0x5c, 0x61, 0x0f, 0x6d, 0xee, 0x42, 0x0a, 0x39, 0xd1, 0x83, 0xfa, 0xb9, 0x0c, 0xbd, 0xef, 0x8e, - 0xdf, 0xbe, 0x69, 0xcd, 0x71, 0x9f, 0xa8, 0x04, 0x7f, 0x0d, 0x08, 0x9f, 0x5c, 0x80, 0xe6, 0xb7, - 0x0c, 0x85, 0x93, 0x54, 0xa0, 0x9a, 0x25, 0x09, 0x4e, 0xbd, 0x02, 0xd9, 0x08, 0x8c, 0x41, 0x49, - 0xa6, 0xe3, 0x3b, 0xb2, 0x2c, 0x74, 0x3d, 0x44, 0xd5, 0x22, 0x6c, 0x65, 0x80, 0xe7, 0x7a, 0xfd, - 0xc4, 0xe4, 0x8b, 0x9a, 0xa6, 0x63, 0x8a, 0x65, 0x4a, 0x78, 0xe2, 0xab, 0x97, 0xe6, 0x29, 0x4c, - 0x05, 0x93, 0x70, 0x31, 0x65, 0xa9, 0xc8, 0x6e, 0x4b, 0x8d, 0xbd, 0xd6, 0x21, 0xc5, 0x1b, 0x5f, - 0xc8, 0x59, 0x4e, 0x7c, 0x6b, 0xfb, 0xad, 0x60, 0x0a, 0x68, 0x85, 0xbf, 0x20, 0xfd, 0x21, 0x53, - 0x9b, 0x30, 0xcd, 0xec, 0x22, 0x8b, 0x64, 0x97, 0xa1, 0x28, 0x02, 0x42, 0xc4, 0xf0, 0x43, 0x60, - 0xb9, 0xe9, 0xad, 0x71, 0x8e, 0xc4, 0x0d, 0xbc, 0x07, 0xcd, 0x87, 0x36, 0xcd, 0xd5, 0xa2, 0xa9, - 0x70, 0x48, 0x95, 0x73, 0x6d, 0x9d, 0x95, 0xfc, 0x81, 0xd0, 0xcd, 0x84, 0x4d, 0x58, 0x70, 0xc5, - 0x84, 0xff, 0xe9, 0xdb, 0xf7, 0xaf, 0x5f, 0x11, 0x89, 0xe5, 0xaf, 0x58, 0xc8, 0x3c, 0xbe, 0x05, - 0xf6, 0xb9, 0x04, 0x02, 0x67, 0x1c, 0xba, 0x42, 0x2d, 0x29, 0x7d, 0x34, 0x38, 0x3b, 0xa5, 0x54, - 0x9c, 0xb5, 0xb8, 0xdd, 0x65, 0xe5, 0x82, 0x88, 0x27, 0xe1, 0xa7, 0x0c, 0xf9, 0xb6, 0x5e, 0xe7, - 0xf9, 0xb1, 0x09, 0xce, 0xc8, 0xe2, 0x03, 0xa8, 0x31, 0x1b, 0xac, 0x91, 0xb0, 0x59, 0x8e, 0x4b, - 0xb3, 0xdf, 0xea, 0xb5, 0xba, 0x2d, 0xb0, 0xf1, 0x47, 0x79, 0x15, 0xd8, 0x04, 0xf0, 0xf6, 0x31, - 0xf0, 0xe5, 0xdc, 0xb4, 0xdd, 0xd2, 0x07, 0x05, 0xc5, 0x6a, 0x65, 0x5e, 0x3d, 0x99, 0x43, 0x0e, - 0x4e, 0x5a, 0xfc, 0xb9, 0x75, 0x85, 0x12, 0xd5, 0x53, 0x0b, 0x4e, 0xce, 0x2c, 0x04, 0x64, 0x7d, - 0x78, 0xa9, 0x09, 0x57, 0x4b, 0x9a, 0x09, 0xc4, 0x08, 0xad, 0x20, 0xe5, 0x0c, 0x11, 0x02, 0x08, - 0x3a, 0x26, 0xa6, 0xec, 0xca, 0x20, 0xce, 0x83, 0x89, 0x02, 0x90, 0x7f, 0x33, 0xa7, 0x05, 0x3b, - 0x1c, 0x12, 0x57, 0xe0, 0x19, 0x0d, 0x5d, 0xe4, 0x84, 0x35, 0x67, 0x4a, 0x98, 0x01, 0x52, 0xce, - 0x92, 0xe5, 0x71, 0xa1, 0x2f, 0x06, 0xb4, 0x0d, 0x23, 0x04, 0x94, 0x4c, 0x58, 0xfd, 0x32, 0x76, - 0x48, 0x6c, 0xd3, 0x81, 0x59, 0x56, 0x72, 0x1a, 0x27, 0x6b, 0xa7, 0x43, 0x9e, 0x3a, 0x31, 0xc1, - 0x08, 0x28, 0xe2, 0x39, 0x8b, 0x2a, 0x81, 0xc0, 0x0f, 0xd4, 0x32, 0x98, 0xe3, 0xe9, 0x2b, 0x76, - 0xee, 0x87, 0x40, 0x95, 0xa2, 0x10, 0xb1, 0x46, 0x65, 0x29, 0xc1, 0x34, 0x20, 0xfe, 0x73, 0xf9, - 0xc9, 0xb7, 0xee, 0xbe, 0x8f, 0x5f, 0xc5, 0xe7, 0x7e, 0x12, 0x64, 0x17, 0x97, 0x16, 0x03, 0xac, - 0x2c, 0x85, 0x24, 0x11, 0xf2, 0xd4, 0x68, 0x93, 0xfe, 0xef, 0x03, 0xad, 0x5c, 0x06, 0xd1, 0x88, - 0xfe, 0xba, 0x6d, 0x07, 0xbd, 0xce, 0x97, 0xfe, 0xcd, 0x88, 0xfe, 0xba, 0x38, 0x77, 0x45, 0x9e, - 0x3f, 0x22, 0x7d, 0x0e, 0x9b, 0xf4, 0x6d, 0xc8, 0x13, 0x7b, 0x96, 0x4a, 0xc8, 0xec, 0x66, 0x64, - 0xef, 0x58, 0x59, 0xd3, 0xe7, 0x76, 0x45, 0xc2, 0x17, 0xc6, 0x60, 0x38, 0xac, 0xa8, 0x11, 0x3f, - 0xb6, 0x42, 0xf8, 0x60, 0x0f, 0x45, 0x93, 0xf4, 0x89, 0xd0, 0x67, 0x25, 0xfa, 0xc4, 0xa6, 0xd1, - 0xbf, 0x23, 0xe4, 0x84, 0x8f, 0xf3, 0x26, 0xc1, 0x5c, 0x2b, 0x92, 0x81, 0x64, 0x6c, 0x00, 0x14, - 0x39, 0xb6, 0xf8, 0x31, 0xe3, 0xe4, 0x65, 0xd7, 0xeb, 0x50, 0xba, 0xe6, 0xf9, 0x54, 0x81, 0x7f, - 0x28, 0x92, 0x95, 0xdd, 0x81, 0x2d, 0x78, 0x9e, 0x48, 0x3d, 0xf1, 0x4f, 0xe5, 0x14, 0x03, 0x99, - 0x4d, 0xdc, 0xd5, 0x63, 0xa2, 0x64, 0x98, 0x84, 0x7e, 0x9a, 0x22, 0x91, 0xd6, 0xeb, 0xfe, 0x91, - 0x57, 0xac, 0x42, 0xe2, 0xf0, 0x2a, 0x0e, 0xa6, 0x45, 0x3d, 0x3d, 0xef, 0x8b, 0x81, 0x35, 0x19, - 0x62, 0x55, 0x1a, 0x34, 0x75, 0xfe, 0x05, 0xe8, 0xd3, 0xc9, 0x40, 0xc6, 0x95, 0xea, 0x5b, 0x73, - 0x90, 0x42, 0xe0, 0xe2, 0x90, 0xaf, 0x84, 0xa8, 0x2d, 0x1b, 0x66, 0x23, 0x6b, 0xc5, 0x7f, 0x28, - 0x6a, 0x27, 0xc2, 0x88, 0x8b, 0x00, 0xcc, 0x08, 0x24, 0x0e, 0x42, 0xd9, 0xca, 0x60, 0xbc, 0x27, - 0x7e, 0xc8, 0x5e, 0xc5, 0xd7, 0x2c, 0x79, 0x06, 0x9a, 0x90, 0x45, 0xde, 0x00, 0x44, 0xa6, 0x5c, - 0x6f, 0xe2, 0x3f, 0x53, 0xf4, 0x5f, 0xa6, 0x1e, 0xa8, 0x13, 0x26, 0xed, 0xc4, 0x01, 0x06, 0x9d, - 0x78, 0x33, 0x20, 0xf3, 0x77, 0x04, 0xeb, 0x0f, 0x40, 0xd2, 0x19, 0x48, 0x1e, 0x12, 0x88, 0x93, - 0x7a, 0x1d, 0x9f, 0x6b, 0xde, 0x84, 0x64, 0x11, 0xff, 0x8b, 0x29, 0xad, 0x74, 0x31, 0x4e, 0xb3, - 0x24, 0x88, 0xce, 0xad, 0xb6, 0x83, 0xc9, 0xb2, 0x27, 0x1e, 0x65, 0x1d, 0xa5, 0x9a, 0x17, 0x11, - 0x55, 0x85, 0x67, 0xfe, 0xdc, 0x2a, 0x95, 0xd3, 0x4b, 0xd9, 0xee, 0xb6, 0x02, 0xd8, 0x09, 0x04, - 0x15, 0x87, 0x05, 0x9e, 0x51, 0x6c, 0x63, 0x72, 0xc3, 0xe2, 0x23, 0x3c, 0x32, 0xbf, 0x32, 0x1b, - 0xbe, 0x6b, 0xe2, 0x54, 0xff, 0x0b, 0xce, 0x07, 0xd9, 0xd4, 0xac, 0x79, 0x51, 0xbd, 0x6e, 0x4e, - 0x2e, 0xd8, 0xe4, 0xd3, 0x38, 0xbe, 0x81, 0xd7, 0x4c, 0x4c, 0x20, 0x30, 0x5f, 0x92, 0x4b, 0xcd, - 0xf4, 0x44, 0xd2, 0x6a, 0xf5, 0x99, 0x73, 0x0a, 0xcf, 0x6e, 0xaf, 0x56, 0x31, 0x6e, 0xac, 0x01, - 0xc5, 0xf8, 0x19, 0x5a, 0x18, 0x16, 0x0c, 0x84, 0xf3, 0x65, 0x35, 0xd8, 0xcb, 0x29, 0x3a, 0x96, - 0x93, 0xbc, 0x4f, 0x42, 0xb1, 0xc1, 0xf7, 0x0b, 0x94, 0x2d, 0x28, 0x30, 0x43, 0xfe, 0xda, 0xc5, - 0xaf, 0x5c, 0xf4, 0x78, 0xe6, 0x2c, 0x8c, 0xfd, 0xcc, 0x35, 0x68, 0xbb, 0x15, 0x50, 0xd1, 0x56, - 0x74, 0xb1, 0x02, 0x84, 0x21, 0xaf, 0xdf, 0xa7, 0x0a, 0xd3, 0xb9, 0x1f, 0x99, 0xe8, 0xda, 0xd1, - 0x3c, 0xbc, 0x7f, 0xfb, 0xeb, 0x5f, 0xff, 0x3b, 0x4c, 0xba, 0xa5, 0x56, 0x68, 0x0d, 0x6d, 0x88, - 0xe9, 0x5b, 0x5d, 0x8f, 0x1b, 0xd2, 0x08, 0x04, 0xc8, 0x22, 0x35, 0xe4, 0x57, 0xe1, 0x76, 0xb7, - 0xd5, 0x53, 0x8b, 0xb3, 0xc2, 0x1b, 0xa0, 0xd7, 0x2d, 0x8f, 0x7c, 0x73, 0x8d, 0x47, 0xab, 0x29, - 0xc5, 0x5e, 0xf8, 0x92, 0xde, 0xb1, 0x17, 0x3e, 0x74, 0x21, 0xd2, 0xbb, 0xf0, 0xef, 0xff, 0xed, - 0xdf, 0x4c, 0x27, 0xaa, 0xee, 0x81, 0x58, 0x5c, 0x34, 0x7f, 0x8c, 0x93, 0x4f, 0xb8, 0x9d, 0x8f, - 0x86, 0x1e, 0xe8, 0x13, 0x67, 0xd9, 0xd7, 0x30, 0x42, 0xae, 0x1c, 0x3d, 0x49, 0x12, 0x23, 0x35, - 0x35, 0x35, 0x4c, 0x9e, 0x41, 0x8e, 0xaa, 0xca, 0x61, 0x7e, 0x80, 0x14, 0xfe, 0x4d, 0xd4, 0x32, - 0x24, 0x27, 0xd9, 0x93, 0x0c, 0x08, 0x1b, 0x28, 0x8c, 0xc1, 0xd0, 0xc1, 0x2c, 0x0a, 0x64, 0xc0, - 0x75, 0xd5, 0x9d, 0x1d, 0x76, 0x1d, 0x5f, 0x07, 0xad, 0x73, 0x90, 0xc5, 0x8b, 0x71, 0x2b, 0x88, - 0x77, 0xd0, 0x71, 0xff, 0x3c, 0x9e, 0xa4, 0xa0, 0x9a, 0xc6, 0xa0, 0x83, 0xe2, 0xdf, 0xc2, 0x20, - 0x96, 0xfb, 0x1f, 0xc1, 0xac, 0x50, 0x48, 0x60, 0xe5, 0x04, 0x44, 0xcc, 0x38, 0x31, 0xed, 0xad, - 0xe9, 0x7c, 0x4a, 0x45, 0x09, 0x47, 0x9b, 0xf8, 0x54, 0x6f, 0x0a, 0x04, 0xc9, 0x3f, 0xe9, 0x24, - 0x99, 0xe1, 0x19, 0x20, 0x13, 0x8d, 0xe8, 0x72, 0xad, 0x59, 0x45, 0x6b, 0xcc, 0x16, 0x4a, 0x21, - 0x65, 0xc0, 0xfd, 0xc8, 0x26, 0x89, 0x91, 0xa4, 0x44, 0x93, 0x4e, 0x2d, 0x83, 0x79, 0x00, 0x98, - 0x74, 0x16, 0x84, 0xec, 0xfd, 0x38, 0x24, 0x1e, 0x85, 0x7e, 0x2f, 0xf3, 0x86, 0x69, 0xaf, 0x2e, - 0x35, 0x9c, 0x91, 0x92, 0x2d, 0x38, 0x17, 0xb5, 0x1d, 0xd2, 0x20, 0xcc, 0x86, 0x59, 0xb9, 0x90, - 0xb2, 0x8d, 0x3a, 0xdf, 0xd3, 0xd6, 0xc5, 0x86, 0x46, 0x99, 0x34, 0xff, 0x85, 0xde, 0x12, 0xea, - 0xf8, 0x3e, 0xbe, 0x76, 0x97, 0xeb, 0x35, 0x30, 0x1b, 0x7f, 0x91, 0x52, 0xa6, 0xe0, 0x1a, 0x07, - 0x4d, 0x02, 0x05, 0x50, 0xb1, 0xbf, 0xeb, 0x4d, 0xbc, 0x46, 0xb6, 0x40, 0xe6, 0x05, 0x2e, 0x2a, - 0x6e, 0xe3, 0xd3, 0xa1, 0x2a, 0xc7, 0x77, 0x14, 0x69, 0x32, 0xc9, 0x9c, 0x07, 0xba, 0x88, 0x32, - 0x83, 0x79, 0x3e, 0x5a, 0x88, 0xb7, 0x51, 0xa2, 0x71, 0xb3, 0x6b, 0x89, 0x37, 0x5e, 0x0b, 0x8d, - 0xc8, 0x26, 0x52, 0x84, 0xf5, 0xb5, 0x81, 0x15, 0x5e, 0xca, 0x50, 0xdf, 0x6d, 0xd0, 0x62, 0xa2, - 0x29, 0x59, 0xbd, 0x96, 0x42, 0xd4, 0xda, 0xd6, 0xa0, 0xe5, 0x0b, 0x03, 0x1a, 0xf9, 0xe4, 0x43, - 0x26, 0xc4, 0x0b, 0x2b, 0x8a, 0x97, 0x7f, 0xfd, 0xcf, 0xe6, 0x06, 0xd6, 0x4a, 0x09, 0x1a, 0xf1, - 0x52, 0x45, 0xa2, 0x8d, 0xea, 0xbe, 0x4c, 0xc7, 0xa1, 0x36, 0xc6, 0x59, 0x7c, 0x7e, 0x1e, 0xb2, - 0xd7, 0xb8, 0x77, 0x58, 0x07, 0x58, 0x1b, 0x15, 0xb1, 0x2d, 0xfa, 0x3f, 0x16, 0x62, 0xd5, 0x0a, - 0xc2, 0x8c, 0x56, 0xc2, 0xdb, 0x28, 0xbc, 0xf5, 0x70, 0xb0, 0xfe, 0x19, 0x7d, 0x40, 0x5b, 0x54, - 0x81, 0x9f, 0x28, 0x21, 0x98, 0x8f, 0x89, 0x9c, 0xea, 0xf2, 0x3e, 0x22, 0xd3, 0x15, 0xa6, 0x78, - 0x31, 0x31, 0xde, 0xd3, 0xfb, 0x02, 0x89, 0x36, 0x4c, 0xc3, 0xdc, 0x60, 0xf0, 0xf5, 0x56, 0x16, - 0xe5, 0x4d, 0x3b, 0xb4, 0x50, 0x84, 0xac, 0x30, 0xe5, 0xfd, 0xc7, 0xea, 0xa7, 0x2c, 0x03, 0x19, - 0x0a, 0x26, 0x73, 0x86, 0xa6, 0x56, 0x35, 0xdf, 0x6e, 0x21, 0x51, 0x5e, 0x2b, 0x80, 0xa2, 0x32, - 0x6c, 0xce, 0x27, 0x55, 0x54, 0xab, 0x7f, 0x5e, 0xdf, 0x29, 0xa7, 0x04, 0x1a, 0x34, 0x8d, 0xcf, - 0xe3, 0x18, 0xbd, 0xf4, 0x93, 0x4f, 0x65, 0x04, 0x84, 0xda, 0xb0, 0x94, 0x94, 0x09, 0x31, 0x32, - 0x02, 0x2b, 0x50, 0x4e, 0xc7, 0x4a, 0x52, 0xc2, 0x4a, 0x22, 0xc4, 0x58, 0x71, 0xee, 0x4e, 0x3e, - 0x5f, 0xa0, 0xe5, 0x78, 0x29, 0x4f, 0xb8, 0x95, 0x1c, 0x9c, 0x13, 0x4b, 0x42, 0x68, 0xcc, 0x29, - 0xe5, 0x6e, 0xa8, 0x61, 0xd0, 0xe0, 0x05, 0x2d, 0x84, 0x4c, 0x58, 0x08, 0x09, 0x5a, 0x06, 0x98, - 0x06, 0x56, 0x42, 0xa6, 0xac, 0x84, 0x52, 0xff, 0xc4, 0x0c, 0xb2, 0x55, 0x53, 0x4b, 0xae, 0xcc, - 0x61, 0x55, 0x67, 0x39, 0x18, 0xa0, 0xff, 0x1c, 0x2d, 0xb9, 0x67, 0x4c, 0xec, 0xd0, 0x61, 0xfa, - 0xaa, 0x74, 0x86, 0x08, 0x18, 0x6d, 0x5a, 0x39, 0x19, 0x68, 0x45, 0x62, 0xf0, 0xb9, 0x19, 0xe0, - 0x96, 0xde, 0xd7, 0xf7, 0x4b, 0xc7, 0x4a, 0xe4, 0x81, 0xe6, 0x9c, 0x13, 0x8a, 0x13, 0xe0, 0xec, - 0xc0, 0x72, 0x32, 0x98, 0xc4, 0x71, 0x32, 0xed, 0x3d, 0xaf, 0x62, 0x3e, 0x51, 0x82, 0x66, 0xbb, - 0xbb, 0x26, 0xb7, 0x68, 0x71, 0x39, 0x46, 0xe7, 0x11, 0xab, 0xc0, 0x37, 0xe1, 0x18, 0x9d, 0x14, - 0x39, 0xde, 0x51, 0x3d, 0x98, 0x87, 0xfe, 0x84, 0x5d, 0xc4, 0xe1, 0x94, 0x81, 0x19, 0x7a, 0xf3, - 0x45, 0x45, 0xff, 0x77, 0x61, 0x3e, 0x5c, 0x9a, 0x02, 0xdb, 0x16, 0x73, 0x59, 0xc8, 0x7f, 0x85, - 0x2e, 0xdd, 0xa2, 0x8e, 0xfb, 0xff, 0x31, 0xa4, 0x4a, 0x79, 0x2e, 0x42, 0xea, 0x17, 0x21, 0xfd, - 0x7d, 0x8b, 0x9a, 0xfc, 0xbf, 0x12, 0x52, 0x5f, 0x57, 0x44, 0xe6, 0x49, 0x7c, 0x8e, 0xa7, 0x0c, - 0xcb, 0x92, 0x49, 0xa5, 0xdb, 0x95, 0x8c, 0x2d, 0xa9, 0x45, 0x63, 0x70, 0x4d, 0x6c, 0xa0, 0xa6, - 0xb6, 0x21, 0x35, 0x24, 0x47, 0x20, 0x39, 0x23, 0x60, 0x05, 0x51, 0xa2, 0x52, 0x0b, 0x22, 0x25, - 0x4f, 0xbd, 0x1b, 0x65, 0x92, 0x44, 0x78, 0xe7, 0x1d, 0x1f, 0x4c, 0x5d, 0x04, 0x21, 0x3d, 0x69, - 0x9f, 0x3a, 0x11, 0x39, 0x4b, 0xbf, 0x8e, 0x93, 0x4b, 0x74, 0xf1, 0x14, 0xdd, 0xb7, 0x98, 0xc9, - 0x40, 0x9b, 0x19, 0xb4, 0x37, 0xdf, 0x89, 0xd0, 0xb2, 0xc1, 0xd3, 0x6a, 0x40, 0x4c, 0x9a, 0xa5, - 0x01, 0x4a, 0x5d, 0x72, 0x7b, 0x4c, 0xba, 0x0f, 0x7a, 0x21, 0x73, 0xc4, 0x50, 0xd7, 0x35, 0x37, - 0x05, 0x2f, 0xbd, 0xd3, 0x61, 0x7d, 0x1b, 0x2c, 0x0c, 0x8e, 0x71, 0x81, 0x0b, 0xc7, 0xb7, 0x9d, - 0x19, 0x43, 0xef, 0x26, 0x2a, 0xf0, 0xd4, 0xde, 0xf2, 0x92, 0x65, 0x17, 0xf1, 0xd4, 0x35, 0xdf, - 0xbd, 0x3d, 0x7e, 0x6f, 0x3a, 0xa8, 0xff, 0xba, 0xd1, 0x7a, 0x73, 0xb4, 0x14, 0x0e, 0x74, 0x4d, - 0x3b, 0x07, 0x62, 0xa8, 0x99, 0x42, 0x9f, 0x31, 0x71, 0x55, 0x4f, 0x50, 0x42, 0xc1, 0x16, 0x73, - 0x94, 0xb4, 0x81, 0x2b, 0x55, 0xc7, 0x6d, 0xb2, 0xff, 0x1f, 0xa1, 0xe9, 0x2d, 0xd3, 0x90, 0x23, - 0x45, 0x9d, 0x32, 0xa6, 0xac, 0xcf, 0x25, 0x45, 0xdb, 0x15, 0xa9, 0x49, 0xc9, 0xd6, 0x82, 0x44, - 0xee, 0x45, 0x30, 0x1d, 0x91, 0x73, 0x58, 0x50, 0xc7, 0x47, 0x61, 0x79, 0xbc, 0x85, 0x51, 0xb3, - 0x91, 0x9c, 0xe0, 0x56, 0x1b, 0x0d, 0x97, 0x09, 0xa0, 0x28, 0x2e, 0xa5, 0xa0, 0x54, 0xd2, 0x12, - 0x62, 0xb2, 0x81, 0xb6, 0x3a, 0x25, 0xe0, 0x5b, 0xae, 0x55, 0x48, 0x0e, 0xa8, 0xd7, 0x8b, 0x95, - 0x06, 0x5f, 0xea, 0x44, 0x40, 0x5f, 0x2f, 0x3a, 0x5f, 0x79, 0x74, 0x05, 0xc0, 0x92, 0x2e, 0x39, - 0xf4, 0xb7, 0xd6, 0x34, 0xf1, 0xcf, 0xcf, 0x11, 0x11, 0xe8, 0xe1, 0x06, 0xf4, 0xa0, 0x63, 0x84, - 0x23, 0x06, 0x75, 0x41, 0x40, 0x53, 0xc1, 0xe6, 0xe2, 0xfe, 0x08, 0x76, 0xa7, 0x8f, 0x85, 0x4c, - 0x30, 0x4d, 0x53, 0x22, 0x7f, 0xd9, 0xa6, 0xba, 0xac, 0xf9, 0xf4, 0xa0, 0x55, 0x87, 0x01, 0xb7, - 0x88, 0xed, 0x19, 0xc5, 0x0f, 0x09, 0x7c, 0x90, 0xee, 0x41, 0xe9, 0x96, 0x9b, 0x2d, 0xa2, 0xd5, - 0xaa, 0xd9, 0x15, 0x8f, 0x23, 0xdc, 0xf0, 0x7f, 0xf1, 0xc9, 0x33, 0xcf, 0x59, 0xd4, 0x35, 0x9d, - 0xdc, 0xdb, 0x0c, 0xf3, 0x3d, 0xc8, 0x05, 0x5c, 0x03, 0x15, 0xf3, 0xbb, 0xee, 0xe6, 0x86, 0x8f, - 0x4b, 0x4a, 0x74, 0xc5, 0x47, 0x28, 0xf8, 0xc9, 0xc5, 0x3a, 0x3a, 0xe6, 0x1a, 0x59, 0x97, 0xea, - 0x3e, 0xf2, 0x70, 0x77, 0x7c, 0x61, 0x69, 0x8f, 0x3b, 0xef, 0xb9, 0x3a, 0x56, 0xfc, 0x20, 0x56, - 0x91, 0xfb, 0xf5, 0x7a, 0x95, 0xcf, 0x9a, 0x57, 0xe8, 0x35, 0x71, 0x4f, 0x54, 0xb2, 0x66, 0xad, - 0x14, 0x37, 0xbd, 0xe6, 0xdb, 0xb3, 0xc8, 0x03, 0xab, 0xbb, 0x41, 0xfd, 0x71, 0x0a, 0x8c, 0x11, - 0xdb, 0x4d, 0xf5, 0x16, 0xc2, 0x1b, 0x9a, 0x5a, 0x72, 0xb5, 0x22, 0xc3, 0xa5, 0x07, 0x66, 0xeb, - 0x08, 0x73, 0x42, 0xc4, 0x63, 0xbe, 0x78, 0xc8, 0x22, 0x32, 0x6b, 0xc1, 0x62, 0xad, 0xf4, 0x9e, - 0x0a, 0x3f, 0xa9, 0x83, 0x7e, 0xc2, 0x32, 0xad, 0x73, 0xe3, 0x5c, 0x38, 0xd7, 0x90, 0xf2, 0x87, - 0x51, 0x89, 0xb0, 0x15, 0x20, 0x0c, 0x01, 0x81, 0xc1, 0x92, 0x2b, 0x55, 0x54, 0x02, 0x9d, 0x02, - 0x71, 0xd9, 0xac, 0x2f, 0x7a, 0x72, 0x1d, 0xbe, 0x86, 0xb3, 0xa1, 0xfd, 0x64, 0x53, 0xe5, 0xe2, - 0x92, 0x8a, 0x50, 0xa8, 0x68, 0x8e, 0x68, 0x0d, 0x7d, 0x79, 0x60, 0xb5, 0x38, 0x61, 0xc9, 0xf8, - 0x0f, 0xa5, 0xf1, 0xdf, 0xdc, 0xa2, 0x1d, 0xdc, 0x69, 0xfc, 0x37, 0x2b, 0x8c, 0x7f, 0x68, 0x26, - 0x37, 0xfe, 0xf9, 0x8b, 0x32, 0xfe, 0x55, 0x42, 0x12, 0x5f, 0xbf, 0x49, 0x3c, 0x7f, 0xd3, 0x1b, - 0x50, 0xf6, 0xb5, 0x6d, 0xba, 0x07, 0x2a, 0x49, 0x05, 0xba, 0x9d, 0xa2, 0xd7, 0x83, 0xfb, 0xa2, - 0xea, 0x75, 0x60, 0xe6, 0x97, 0x62, 0x6d, 0x90, 0x20, 0x55, 0x8b, 0xaa, 0xf9, 0x50, 0x5f, 0xe1, - 0x81, 0x17, 0xdc, 0x41, 0xca, 0x57, 0xa4, 0x61, 0xee, 0x03, 0xc0, 0x94, 0x5f, 0x9f, 0xc1, 0xe0, - 0x14, 0x16, 0xb9, 0x30, 0xa1, 0xe8, 0x1a, 0xf7, 0x95, 0x6b, 0x5c, 0x3c, 0xd1, 0x66, 0xef, 0x09, - 0x43, 0xa8, 0xab, 0x2b, 0xf7, 0x71, 0x55, 0x51, 0x01, 0xa0, 0xaf, 0xa9, 0x70, 0x15, 0x97, 0x6f, - 0xb9, 0x68, 0x7d, 0x62, 0xb7, 0x29, 0x7a, 0xe5, 0x65, 0xfb, 0xb4, 0x62, 0x56, 0xfa, 0xb6, 0x14, - 0x6a, 0xd4, 0x49, 0x78, 0x4a, 0xb2, 0x99, 0x18, 0x0b, 0xbd, 0xec, 0xc5, 0xf5, 0x36, 0xad, 0x0d, - 0xf4, 0x98, 0xfb, 0x13, 0xbe, 0xe5, 0x14, 0x09, 0x29, 0x57, 0x44, 0xfc, 0xe0, 0xa9, 0xb4, 0xbb, - 0xb6, 0x17, 0x2f, 0x17, 0xa2, 0x13, 0x48, 0xf7, 0x17, 0x70, 0x4a, 0x6b, 0x59, 0x7a, 0x15, 0xb4, - 0x60, 0xf6, 0x65, 0x75, 0xf0, 0xb5, 0x36, 0x7f, 0xc3, 0x7b, 0x42, 0x99, 0xff, 0xbe, 0xde, 0x83, - 0x25, 0xed, 0x07, 0x61, 0x4a, 0xa5, 0x05, 0x4b, 0xe1, 0x78, 0x26, 0x0e, 0x5f, 0xc5, 0xf5, 0xe0, - 0x8d, 0xa8, 0x75, 0x04, 0x02, 0xc0, 0x15, 0xcf, 0xc0, 0xff, 0x2c, 0x17, 0xe7, 0x19, 0x89, 0x73, - 0x3c, 0xae, 0x67, 0x0f, 0xb7, 0xb6, 0x2f, 0x9b, 0x81, 0xd6, 0x41, 0x7c, 0x38, 0x19, 0x5f, 0x0f, - 0x8b, 0x48, 0xfe, 0x03, 0x09, 0x69, 0x2f, 0xad, 0x84, 0x28, 0xc7, 0xb2, 0x85, 0xa7, 0x15, 0x17, - 0x12, 0x70, 0x09, 0x81, 0xc9, 0x25, 0x84, 0xb8, 0x85, 0xcd, 0x47, 0xc0, 0x1a, 0xd1, 0x96, 0xb9, - 0x26, 0xda, 0x3a, 0xad, 0x50, 0x3b, 0xb6, 0x3e, 0xa1, 0x6d, 0x9f, 0x66, 0x62, 0x9a, 0x66, 0xb2, - 0x6a, 0x96, 0xcb, 0x95, 0x63, 0xee, 0xe0, 0x23, 0xfc, 0x95, 0xf7, 0x89, 0x6e, 0x0e, 0xa5, 0x4f, - 0xec, 0x89, 0x88, 0xad, 0x49, 0xc4, 0xe6, 0x58, 0x47, 0x09, 0x21, 0x53, 0x01, 0xfd, 0xaa, 0xe3, - 0xa0, 0x29, 0x7a, 0xdc, 0x66, 0xc5, 0xf5, 0x97, 0x2d, 0x82, 0xb7, 0x88, 0x7a, 0x0e, 0x94, 0x01, - 0x0a, 0x0c, 0x20, 0x1b, 0x18, 0xb2, 0x2c, 0xd8, 0x31, 0x39, 0x2e, 0xd6, 0xf4, 0x24, 0x0c, 0x85, - 0xc6, 0x22, 0x97, 0x90, 0x36, 0x37, 0x8d, 0xe1, 0x12, 0xa9, 0x3e, 0xaa, 0xa2, 0x19, 0x20, 0xae, - 0x60, 0x8a, 0xcb, 0x9d, 0x3b, 0x71, 0x62, 0x10, 0xf8, 0x06, 0x1e, 0x3b, 0x08, 0x66, 0x01, 0xad, - 0x9f, 0x96, 0xe8, 0x2d, 0x94, 0xe8, 0x5a, 0xde, 0xc3, 0x6c, 0x1a, 0x5e, 0x4a, 0xd8, 0x90, 0x48, - 0x8a, 0x05, 0x5e, 0x60, 0xe2, 0x80, 0x7a, 0x59, 0x86, 0xfd, 0x03, 0x3a, 0xea, 0x6c, 0x93, 0x40, - 0xd0, 0xed, 0xd2, 0x22, 0x3a, 0x07, 0x87, 0x10, 0x15, 0xc3, 0x47, 0xcd, 0x45, 0x36, 0x57, 0xc3, - 0x2a, 0x06, 0x48, 0x42, 0xe0, 0xd3, 0x54, 0xae, 0x8f, 0x94, 0x10, 0x80, 0x8e, 0xdc, 0x93, 0x5b, - 0x90, 0x9a, 0x4b, 0x4d, 0x87, 0xf0, 0x95, 0x0e, 0x71, 0x12, 0x9d, 0x72, 0x05, 0x42, 0xb4, 0xb3, - 0xc6, 0x51, 0x8a, 0xe4, 0x9e, 0xd3, 0x52, 0x8b, 0xa1, 0xd8, 0x4b, 0xb0, 0xcc, 0x37, 0x48, 0x54, - 0xf2, 0x25, 0x50, 0x3f, 0xa9, 0x0c, 0x5d, 0xa0, 0x33, 0xd2, 0x70, 0xb8, 0x58, 0xd4, 0x55, 0x1c, - 0xd0, 0x9b, 0xd4, 0xde, 0x8e, 0xad, 0xcc, 0x0a, 0x52, 0xd6, 0x08, 0x68, 0x37, 0x20, 0xa0, 0x31, - 0x20, 0xed, 0x8e, 0x4f, 0xbe, 0xf7, 0x94, 0x83, 0x02, 0x5c, 0x4e, 0x83, 0xfe, 0x46, 0xbf, 0xfa, - 0x9a, 0xac, 0x0e, 0x43, 0x49, 0xa1, 0xa0, 0x1d, 0x1f, 0x78, 0x10, 0x93, 0x86, 0x53, 0xe8, 0x88, - 0x4c, 0x4d, 0xde, 0x2e, 0xb1, 0xbe, 0x53, 0xcb, 0xa4, 0xd8, 0x97, 0x5b, 0xad, 0x36, 0x09, 0xf8, - 0xec, 0xe1, 0x92, 0x5b, 0x87, 0xeb, 0x93, 0x60, 0xfa, 0x17, 0xcf, 0xc4, 0xd7, 0x60, 0xba, 0xfe, - 0xca, 0x3c, 0x3d, 0x2b, 0xe9, 0x41, 0x7e, 0x61, 0x60, 0x10, 0x24, 0xda, 0x67, 0xf2, 0x12, 0x23, - 0x53, 0x15, 0x97, 0x15, 0x59, 0xbe, 0xac, 0x08, 0x94, 0x65, 0xdb, 0xe2, 0xc0, 0xe9, 0x9a, 0x2f, - 0x20, 0x65, 0x77, 0x2e, 0x98, 0x0e, 0x69, 0xb7, 0xc9, 0x85, 0x9f, 0xbe, 0xbd, 0x8e, 0xde, 0x25, - 0xf1, 0x9c, 0x25, 0xd9, 0xad, 0x72, 0xa1, 0xd2, 0xa4, 0x87, 0x5e, 0x7d, 0x74, 0xf1, 0x67, 0x15, - 0x4e, 0xd3, 0xb0, 0x45, 0x39, 0x35, 0xee, 0xd1, 0x3c, 0x84, 0x4a, 0xb6, 0xd9, 0x59, 0xc9, 0xf5, - 0xb7, 0x59, 0xac, 0xe0, 0xcf, 0xd5, 0x0b, 0x96, 0x64, 0x09, 0x37, 0xe3, 0xee, 0x80, 0x04, 0x3d, - 0xb8, 0xfa, 0x06, 0x95, 0xec, 0x0e, 0x23, 0x58, 0xf4, 0x72, 0xc8, 0xc8, 0x61, 0xb4, 0xbd, 0x4e, - 0xa0, 0x46, 0xfe, 0xe4, 0x89, 0x94, 0x75, 0x25, 0xd2, 0xc4, 0xb9, 0x76, 0x0d, 0x6d, 0xe4, 0x7d, - 0xa6, 0xe7, 0x29, 0xd9, 0xa3, 0xd5, 0x8b, 0x80, 0x77, 0x0d, 0x8f, 0x60, 0xed, 0x61, 0x41, 0xd5, - 0x28, 0x54, 0x44, 0x1b, 0x3f, 0xf1, 0x89, 0xf6, 0x24, 0x2b, 0x20, 0xbc, 0x7b, 0x16, 0xca, 0xed, - 0x25, 0x6e, 0xde, 0x19, 0xc3, 0x64, 0xf2, 0x69, 0xcd, 0x56, 0x2b, 0x8b, 0x4f, 0x51, 0xaa, 0x0b, - 0x4e, 0xb6, 0x7d, 0x0a, 0xb2, 0x1d, 0x1d, 0x59, 0xb8, 0xe3, 0x92, 0x0a, 0x15, 0x04, 0x43, 0x61, - 0xbe, 0xd3, 0xdc, 0x98, 0xf9, 0x11, 0x0c, 0x9d, 0x9c, 0x4c, 0x35, 0x15, 0xa2, 0x62, 0x4b, 0x3b, - 0xe7, 0x4d, 0x71, 0x72, 0xdd, 0xdc, 0xbe, 0x9a, 0x8b, 0x7c, 0x91, 0x37, 0x8f, 0x12, 0xa5, 0xb2, - 0x06, 0x5c, 0xa8, 0x30, 0x37, 0x97, 0x57, 0xf1, 0x90, 0x6f, 0x51, 0x71, 0x65, 0xb2, 0x2a, 0xad, - 0x4f, 0x95, 0x03, 0xcd, 0xa3, 0xdb, 0xa4, 0xa6, 0x18, 0x9d, 0xc0, 0x3b, 0xe1, 0x3a, 0x9e, 0x60, - 0x94, 0x65, 0xe0, 0x7d, 0xc6, 0xd2, 0x6f, 0xf5, 0x24, 0x59, 0x21, 0x30, 0xf8, 0x82, 0x15, 0x48, - 0x8b, 0xc7, 0x4a, 0x5a, 0xa0, 0xb0, 0x20, 0x6c, 0xe7, 0x2b, 0x69, 0x60, 0xe6, 0x06, 0xc2, 0x90, - 0x2b, 0x99, 0x31, 0x81, 0xbd, 0x54, 0x87, 0xad, 0x41, 0xfc, 0x83, 0x05, 0xc6, 0xc1, 0xaf, 0xd7, - 0xd5, 0xa3, 0xda, 0x2e, 0x3c, 0xb4, 0x99, 0xd4, 0x6e, 0xda, 0xb6, 0x3a, 0xbd, 0x91, 0x60, 0x35, - 0xa1, 0xcc, 0xac, 0xdb, 0x44, 0x3c, 0x09, 0x86, 0xa4, 0xa8, 0x79, 0x27, 0xf6, 0xc8, 0x92, 0x86, - 0x4b, 0x82, 0xee, 0x2b, 0xb0, 0x6a, 0x70, 0x9c, 0x93, 0x93, 0xce, 0x29, 0x18, 0xaf, 0xf2, 0x53, - 0xac, 0xd2, 0xab, 0xec, 0x0a, 0x9a, 0x6a, 0x64, 0xa3, 0x9e, 0x6a, 0xde, 0x11, 0xfb, 0x46, 0x2a, - 0x0c, 0x60, 0x26, 0x27, 0x2f, 0xa6, 0x1b, 0xc0, 0x72, 0xb4, 0xd6, 0xc2, 0x38, 0xdb, 0x1c, 0x4f, - 0xca, 0xac, 0xd8, 0x56, 0xad, 0x69, 0x6e, 0xec, 0xb5, 0x11, 0x6d, 0xda, 0x25, 0xbd, 0x20, 0x87, - 0xc0, 0xa0, 0xef, 0x06, 0xaf, 0x02, 0x55, 0xb3, 0x5c, 0x4d, 0x88, 0x0a, 0x0b, 0xc4, 0x60, 0x1f, - 0x32, 0xf2, 0xa8, 0x8a, 0xc5, 0x6e, 0x27, 0xdb, 0x42, 0x0f, 0x52, 0xc7, 0xcc, 0x8f, 0xd2, 0x04, - 0x7c, 0x30, 0x38, 0x24, 0x08, 0x71, 0x80, 0xbb, 0x55, 0xcb, 0x56, 0x71, 0x86, 0x07, 0x5a, 0xf8, - 0x38, 0x55, 0xcc, 0xf8, 0x55, 0x13, 0x7e, 0x00, 0x96, 0x0a, 0x47, 0x18, 0x07, 0x7f, 0x0d, 0x35, - 0x38, 0x21, 0x0c, 0x02, 0x0e, 0xc4, 0x3d, 0x36, 0x1d, 0xbb, 0xc7, 0xa6, 0xdb, 0x9c, 0x94, 0xab, - 0x71, 0x46, 0x46, 0x00, 0xa2, 0x5a, 0x43, 0x9e, 0x66, 0x8d, 0x70, 0xee, 0xe2, 0xe2, 0xe0, 0x7e, - 0x0e, 0x23, 0x2d, 0xec, 0x73, 0xb9, 0x8c, 0xf4, 0x4a, 0x27, 0x2e, 0xa9, 0x50, 0x89, 0x57, 0x4d, - 0x00, 0xa3, 0xb0, 0xb0, 0x97, 0xc9, 0xed, 0xc8, 0xe8, 0x08, 0x97, 0xfe, 0x8d, 0x05, 0xc6, 0x87, - 0x54, 0x50, 0xf3, 0x09, 0x1d, 0x46, 0x21, 0x3b, 0x0c, 0x86, 0x59, 0xa3, 0x21, 0x64, 0xc6, 0xf0, - 0x0e, 0xea, 0xc2, 0x41, 0x95, 0x04, 0x7e, 0x92, 0x9d, 0x3a, 0xb8, 0x33, 0xea, 0x05, 0x1d, 0xc7, - 0x9c, 0x0a, 0x64, 0x4b, 0x8d, 0x0f, 0xb5, 0x11, 0x09, 0x32, 0xe6, 0x42, 0x69, 0x2f, 0x77, 0x1c, - 0x42, 0x49, 0x39, 0xb5, 0x71, 0xdf, 0x2a, 0x48, 0x08, 0xed, 0xcd, 0xc3, 0xa3, 0x77, 0xf2, 0x65, - 0xb5, 0x0a, 0x70, 0x0e, 0xc8, 0x9d, 0xb0, 0xb6, 0xf2, 0xae, 0x4b, 0x40, 0x86, 0xd9, 0x91, 0xec, - 0x57, 0xb3, 0x03, 0xf6, 0x50, 0x89, 0xe4, 0x62, 0xdc, 0xe1, 0x65, 0x17, 0x15, 0xb9, 0xec, 0x30, - 0x19, 0x49, 0xea, 0xe2, 0xa4, 0xc5, 0x03, 0x0a, 0x99, 0x6b, 0x57, 0x24, 0xf3, 0x0d, 0xb2, 0xfa, - 0x97, 0xfb, 0xcd, 0x99, 0x8c, 0xef, 0x4b, 0xf9, 0xf2, 0xb9, 0xb4, 0x5e, 0xdf, 0x82, 0x70, 0xa8, - 0x15, 0x54, 0x3a, 0x0f, 0x37, 0xcf, 0xdd, 0x4d, 0xa4, 0x7c, 0xf3, 0x65, 0x7a, 0x11, 0x2f, 0xc2, - 0x29, 0xed, 0xc1, 0xbc, 0x20, 0xa1, 0x65, 0x5c, 0x5f, 0xc0, 0x1f, 0xa0, 0x5d, 0xd2, 0x71, 0x37, - 0x18, 0xbf, 0xc4, 0x80, 0xb2, 0xd9, 0x2a, 0xc1, 0xe5, 0x73, 0x64, 0x10, 0x7c, 0xe8, 0xb5, 0x8b, - 0xb8, 0xca, 0xcd, 0xf9, 0xa7, 0x22, 0x7f, 0xa8, 0x36, 0xf4, 0x69, 0x05, 0xbb, 0x24, 0xea, 0x86, - 0x1b, 0x6b, 0xe9, 0xba, 0x5a, 0xb5, 0xb1, 0xfa, 0x9f, 0x55, 0x6e, 0xe7, 0x91, 0xb0, 0x56, 0x6e, - 0x86, 0xc8, 0xeb, 0x2b, 0x60, 0x0d, 0xf1, 0x02, 0x98, 0x07, 0x62, 0x05, 0x83, 0xeb, 0xf6, 0x32, - 0x4e, 0x98, 0x79, 0xbf, 0xa2, 0x27, 0xb7, 0x13, 0x0b, 0x5a, 0xab, 0x1e, 0x28, 0xb9, 0xc7, 0x91, - 0xf6, 0x2f, 0xe7, 0x5d, 0xb7, 0x37, 0xa5, 0xa7, 0x70, 0xb2, 0xb5, 0xa8, 0x35, 0x36, 0xf5, 0xd8, - 0xf6, 0x2c, 0xc5, 0xa5, 0x7a, 0x3e, 0xb9, 0xb0, 0xf5, 0xdd, 0xfa, 0xec, 0x3f, 0x06, 0x2d, 0xa3, - 0xf0, 0x24, 0x7c, 0x0a, 0x64, 0x76, 0xf5, 0xaa, 0xaa, 0xd6, 0x16, 0x4d, 0x59, 0x42, 0xdc, 0xcb, - 0x2d, 0x90, 0xbc, 0xdd, 0xad, 0x22, 0x44, 0x6b, 0x3a, 0x2a, 0x34, 0xad, 0x3b, 0xa9, 0x22, 0x22, - 0x7c, 0xa6, 0x79, 0x2a, 0x4d, 0x13, 0x26, 0x26, 0x9c, 0x90, 0x9f, 0xf1, 0xf8, 0x46, 0x98, 0xb0, - 0xd5, 0xc7, 0x05, 0xc5, 0x0b, 0x99, 0x1b, 0x1e, 0x6b, 0x44, 0x38, 0x87, 0x40, 0x3d, 0x8e, 0xa9, - 0xeb, 0x82, 0xed, 0x3b, 0x2b, 0x51, 0xf2, 0x3c, 0x57, 0x64, 0x4f, 0x58, 0xa3, 0x71, 0x3a, 0x14, - 0x36, 0xab, 0x47, 0x95, 0xfa, 0x74, 0x16, 0x17, 0x77, 0xd6, 0x93, 0xff, 0xd3, 0xc2, 0xd5, 0x30, - 0xfe, 0x24, 0x07, 0xb2, 0xd2, 0xf6, 0x33, 0x0c, 0x03, 0x3d, 0x02, 0x9c, 0x7b, 0x05, 0x7e, 0xc5, - 0x1b, 0x92, 0x29, 0xb7, 0x01, 0x4f, 0x6e, 0x9c, 0x5b, 0xe7, 0xf7, 0x53, 0xd4, 0x41, 0xd1, 0x90, - 0xe7, 0x7e, 0x50, 0xb1, 0x7c, 0xbe, 0xae, 0xda, 0xb3, 0xa4, 0x06, 0x47, 0xdb, 0xb8, 0xa4, 0xa7, - 0x89, 0xdd, 0x4b, 0xf9, 0x18, 0x2a, 0x3c, 0xe3, 0x44, 0x4e, 0x2f, 0x4a, 0x07, 0xe3, 0x9e, 0x16, - 0xd9, 0x5e, 0x41, 0xe3, 0x52, 0xb9, 0x6c, 0x65, 0xf8, 0xc9, 0x7c, 0x9e, 0x17, 0x13, 0x11, 0xe9, - 0x83, 0x95, 0x90, 0xce, 0x34, 0x14, 0x4b, 0x61, 0xfa, 0x17, 0x51, 0xaa, 0x72, 0x8b, 0x79, 0x89, - 0x62, 0x46, 0x92, 0x30, 0x73, 0xaa, 0x71, 0x4b, 0x49, 0x15, 0x0b, 0xa4, 0x9b, 0x3d, 0x2d, 0x9a, - 0x60, 0xd5, 0xac, 0xe7, 0xf8, 0x9b, 0x9f, 0xb4, 0x05, 0xdb, 0xc8, 0xdb, 0x62, 0xfd, 0x0d, 0x07, - 0xbb, 0xbb, 0xdd, 0x5d, 0xa5, 0x02, 0x8e, 0x60, 0xb2, 0xce, 0x17, 0x0f, 0xa3, 0xd2, 0x4e, 0xcf, - 0xff, 0x23, 0xdf, 0x3f, 0x57, 0x38, 0x8d, 0xc1, 0xf7, 0x82, 0x2d, 0x26, 0x13, 0x86, 0x7a, 0xbc, - 0x0b, 0x55, 0x76, 0x3e, 0xb3, 0xca, 0x7f, 0xfd, 0xbf, 0xee, 0xaa, 0x72, 0xe6, 0x07, 0x68, 0x38, - 0xbb, 0x56, 0x54, 0xb4, 0x6f, 0xf2, 0x0a, 0x3b, 0x8e, 0x5f, 0x44, 0xa8, 0x10, 0x01, 0x8c, 0x2f, - 0x5f, 0x52, 0x1f, 0x71, 0x0d, 0xaf, 0x72, 0x0c, 0x5d, 0xeb, 0x1f, 0x1e, 0x3f, 0xa0, 0xf0, 0x7b, - 0x79, 0x89, 0x2b, 0x77, 0xa4, 0xca, 0x91, 0x4a, 0xa1, 0x4e, 0x66, 0xd0, 0x46, 0xed, 0x94, 0x25, - 0x57, 0x2c, 0x11, 0xba, 0x86, 0x6e, 0x09, 0xf2, 0xfa, 0x95, 0xf3, 0x83, 0x82, 0x9f, 0xab, 0x5e, - 0x0e, 0x39, 0xa9, 0x33, 0xa9, 0xb8, 0x97, 0x36, 0xb9, 0x8b, 0x5c, 0xab, 0x55, 0x75, 0x07, 0x57, - 0x2b, 0xd1, 0x41, 0x4b, 0x88, 0x68, 0x9e, 0x5e, 0xce, 0x2e, 0xab, 0xd9, 0x3a, 0xd9, 0x8f, 0x48, - 0x28, 0xea, 0x55, 0x90, 0x4e, 0xc4, 0x31, 0x74, 0x72, 0x6a, 0xcb, 0xa1, 0x05, 0xc4, 0xd5, 0x34, - 0x24, 0x8e, 0xf2, 0x64, 0x1d, 0xb5, 0x22, 0xb5, 0x96, 0x9b, 0x23, 0xaa, 0x2e, 0xa5, 0x5d, 0xb8, - 0xa5, 0x7e, 0xd7, 0xbe, 0xac, 0xe3, 0xa3, 0xbf, 0x03, 0x4f, 0xa0, 0xca, 0x8c, 0xb6, 0x34, 0xb3, - 0x0d, 0x2f, 0x44, 0x40, 0x1e, 0x79, 0xb5, 0x0a, 0xf0, 0xbb, 0x25, 0x8d, 0x48, 0xd3, 0x86, 0x16, - 0xd1, 0xa7, 0x88, 0x87, 0xfa, 0x51, 0x72, 0x53, 0x1a, 0x5e, 0x92, 0x14, 0x7c, 0xbb, 0x0a, 0x45, - 0x55, 0x55, 0x72, 0xfd, 0xcf, 0xb8, 0x0e, 0xb2, 0x0b, 0x23, 0x8e, 0x98, 0x68, 0x02, 0xe4, 0xa1, - 0x01, 0xaa, 0x04, 0x2a, 0x56, 0xe9, 0xdd, 0xed, 0x38, 0x65, 0xbc, 0xbb, 0x77, 0x8e, 0x72, 0xb1, - 0xb3, 0x77, 0x8d, 0x9f, 0x5b, 0x41, 0x10, 0x79, 0x36, 0x8d, 0x1e, 0x6c, 0xfb, 0x73, 0xc8, 0xa1, - 0xda, 0x02, 0xc5, 0xd3, 0x60, 0xa6, 0xbd, 0x89, 0x1a, 0xa5, 0x7f, 0x52, 0x06, 0xa5, 0x58, 0x6a, - 0x07, 0x35, 0x4f, 0x10, 0x1f, 0x08, 0x03, 0x26, 0xe1, 0x52, 0x7d, 0xb9, 0x6a, 0x12, 0xd2, 0x77, - 0x98, 0xac, 0xb4, 0x7b, 0x44, 0x2c, 0xf3, 0xa1, 0x33, 0x9c, 0xf1, 0x6d, 0x24, 0xa1, 0xd8, 0xea, - 0xf1, 0x24, 0x9a, 0xbe, 0xb8, 0x61, 0x13, 0xd4, 0x09, 0xcf, 0x70, 0x6f, 0xb7, 0xbb, 0xb3, 0xf3, - 0x70, 0xb9, 0xed, 0x70, 0xe1, 0x7a, 0x07, 0x6b, 0x3b, 0x73, 0xf8, 0xc6, 0x15, 0x3e, 0x54, 0xa5, - 0x05, 0x61, 0x7e, 0x02, 0x47, 0x3b, 0x36, 0x17, 0xda, 0x5a, 0xa4, 0x81, 0x13, 0x76, 0xea, 0xf9, - 0x4e, 0xe1, 0x9d, 0xc2, 0x0e, 0x80, 0x14, 0xbe, 0x13, 0x7e, 0x02, 0x95, 0xa0, 0x47, 0x23, 0xdf, - 0xd6, 0x8f, 0x06, 0x55, 0x19, 0x13, 0xa8, 0x53, 0x55, 0xae, 0x74, 0xb7, 0x0b, 0x31, 0x45, 0x28, - 0x8b, 0x57, 0xc8, 0x58, 0x8e, 0x1c, 0x52, 0x3e, 0x23, 0xab, 0x37, 0x2c, 0xd7, 0x03, 0x9c, 0xd0, - 0xe3, 0x27, 0xf0, 0x84, 0xaa, 0xc3, 0x03, 0x9d, 0x89, 0x99, 0x9e, 0x5c, 0xbd, 0xa1, 0x2d, 0x3c, - 0xe6, 0x34, 0xa9, 0xe3, 0x31, 0x3d, 0x36, 0x82, 0xc9, 0xd1, 0xa5, 0xdd, 0x0b, 0x96, 0x9f, 0x2f, - 0x2d, 0xe0, 0x7e, 0x06, 0x3b, 0x3f, 0x5d, 0xe4, 0x17, 0x5b, 0xcb, 0x4f, 0xb3, 0x94, 0xdb, 0x1c, - 0x6e, 0x1c, 0x2c, 0xf3, 0xbd, 0x10, 0xac, 0x07, 0x5e, 0x3d, 0xfc, 0x72, 0x5b, 0x25, 0x77, 0x74, - 0xfb, 0x4a, 0x15, 0x89, 0xb8, 0x2f, 0x5a, 0xec, 0x54, 0x40, 0xe1, 0x29, 0x00, 0x04, 0x81, 0xef, - 0x46, 0x54, 0x43, 0xe6, 0x95, 0x5b, 0xd7, 0x81, 0xcc, 0xd6, 0x58, 0x8d, 0x76, 0xf8, 0x52, 0x3f, - 0xee, 0xd5, 0x19, 0x6a, 0xcb, 0xad, 0x3a, 0x66, 0x71, 0x88, 0xbe, 0xec, 0x40, 0xda, 0xad, 0x6d, - 0xa2, 0x6a, 0x5d, 0x53, 0xb5, 0xcb, 0x33, 0x4e, 0x5a, 0xd3, 0x60, 0xe4, 0xea, 0xa7, 0x40, 0xb5, - 0xf3, 0x6b, 0x96, 0xed, 0x1d, 0x2d, 0xaf, 0x41, 0x21, 0xbb, 0x4e, 0x5b, 0x74, 0x38, 0xce, 0x52, - 0xc7, 0xd8, 0x4a, 0xa4, 0x07, 0xf0, 0x30, 0x81, 0x73, 0x98, 0xeb, 0x81, 0xe8, 0xec, 0xb5, 0xd3, - 0x63, 0x3d, 0x5b, 0xfa, 0x5b, 0x88, 0xb6, 0xb9, 0x67, 0x3e, 0x98, 0xe1, 0xe9, 0xad, 0xf2, 0x9a, - 0xa3, 0xea, 0x26, 0x6d, 0x1a, 0x0a, 0x25, 0xed, 0x75, 0x7a, 0xfd, 0x76, 0xbd, 0x5e, 0xc8, 0x9b, - 0xc5, 0xb1, 0x31, 0x0e, 0xce, 0x47, 0xa3, 0x91, 0x49, 0x47, 0x70, 0x71, 0x83, 0x91, 0x15, 0xae, - 0x56, 0x8f, 0x96, 0xe6, 0x95, 0xe9, 0x66, 0x09, 0xe8, 0x74, 0x8f, 0xb4, 0x15, 0x0c, 0x6d, 0xff, - 0x91, 0x70, 0xd2, 0x0d, 0x4d, 0x3c, 0x9b, 0xf8, 0x1a, 0x29, 0x41, 0xcc, 0xe1, 0xa0, 0x9e, 0x8e, - 0x8f, 0x21, 0x4d, 0xbc, 0x8e, 0xac, 0xd0, 0xd3, 0xf2, 0xf0, 0x33, 0x80, 0x3c, 0x83, 0x3c, 0xb8, - 0x68, 0xd2, 0x5b, 0xf1, 0x8b, 0xda, 0xf9, 0x5a, 0x6b, 0xa3, 0x3f, 0x8f, 0xaa, 0xda, 0x5a, 0xf6, - 0xf1, 0xd6, 0xc2, 0x1d, 0x5b, 0x9c, 0xc8, 0x03, 0x76, 0x43, 0xa2, 0x03, 0x4d, 0x1f, 0x0f, 0x9e, - 0xeb, 0x46, 0xa2, 0xb6, 0x44, 0x6a, 0xe3, 0x77, 0x69, 0x37, 0xdd, 0x63, 0xf1, 0x55, 0x2c, 0x48, - 0xe8, 0x35, 0x0d, 0x2b, 0x8c, 0x2e, 0x56, 0x36, 0xf0, 0x32, 0x04, 0x2b, 0x6b, 0xdd, 0x78, 0x4a, - 0xfd, 0xd6, 0xbd, 0xed, 0x18, 0xf3, 0x80, 0x8b, 0x74, 0x60, 0xca, 0xdb, 0x2d, 0x79, 0x3a, 0x5a, - 0x9e, 0xdf, 0xb7, 0xe4, 0xe9, 0xaa, 0x3c, 0x25, 0x3a, 0x03, 0xc0, 0x4c, 0xf4, 0xa9, 0x68, 0xdd, - 0xce, 0x84, 0xd7, 0x97, 0xeb, 0x88, 0x77, 0xbb, 0x3b, 0x46, 0x05, 0x74, 0x29, 0x35, 0xcd, 0xd5, - 0x92, 0x03, 0xe8, 0xed, 0x1b, 0xa5, 0x1a, 0xc8, 0xd9, 0xd0, 0x25, 0x38, 0xbf, 0xc6, 0x43, 0x45, - 0xea, 0xdb, 0xb0, 0x74, 0x86, 0x42, 0x10, 0x1a, 0x6d, 0x09, 0xd4, 0x19, 0xd7, 0xe7, 0xbb, 0xe5, - 0x29, 0xb2, 0xf9, 0x3b, 0x74, 0x70, 0x7e, 0x4b, 0x5b, 0x46, 0x9d, 0x20, 0xa5, 0xcd, 0xfe, 0x05, - 0x86, 0x2f, 0x1c, 0x02, 0x00, 0x86, 0x97, 0x59, 0xc4, 0x83, 0x2c, 0x33, 0xb2, 0xca, 0xb5, 0xa1, - 0x2b, 0xf5, 0x9e, 0x65, 0x13, 0xa7, 0x5c, 0x86, 0x47, 0x98, 0xf1, 0x64, 0xa4, 0x99, 0x8d, 0xcf, - 0x3c, 0xd4, 0x8c, 0xa7, 0xc5, 0x9c, 0xd1, 0xbc, 0x4a, 0x05, 0x67, 0xed, 0x46, 0xdf, 0xe4, 0xd1, - 0x59, 0xfa, 0xf0, 0x03, 0x05, 0x7e, 0x2d, 0x2f, 0xda, 0x8b, 0x66, 0xe5, 0x01, 0x7e, 0x1a, 0x8c, - 0x62, 0x90, 0x9b, 0xc2, 0x27, 0x11, 0xe8, 0xc6, 0x95, 0x61, 0x56, 0xbd, 0x0d, 0x70, 0xb7, 0x04, - 0x8a, 0x2c, 0x45, 0x73, 0xfd, 0xfc, 0x72, 0xa2, 0xd7, 0x1b, 0xf9, 0xb7, 0x21, 0x81, 0x6d, 0x64, - 0xb5, 0x2b, 0xb0, 0x20, 0xa2, 0x35, 0xca, 0x88, 0xf3, 0x9e, 0x1c, 0x51, 0x53, 0x0b, 0x50, 0xdf, - 0x9e, 0xdf, 0xd8, 0xa6, 0x6b, 0x96, 0x43, 0xd6, 0x6b, 0xb1, 0x78, 0xe5, 0x72, 0x9c, 0x0a, 0x05, - 0x61, 0x72, 0xe9, 0x8a, 0x4b, 0x6a, 0xb7, 0x73, 0x8c, 0x2d, 0xc0, 0x46, 0xa6, 0xe9, 0x2a, 0x08, - 0xad, 0x9d, 0x93, 0x8f, 0x3f, 0xfe, 0x72, 0xba, 0x73, 0xee, 0x98, 0x06, 0xed, 0xd6, 0x10, 0xa9, - 0xd6, 0x5f, 0x3e, 0x5e, 0x2f, 0x3b, 0x6b, 0x7b, 0x65, 0x7d, 0x4c, 0x1b, 0xfc, 0x11, 0xf2, 0x30, - 0xef, 0x08, 0x49, 0xe8, 0x03, 0x0c, 0x98, 0x24, 0x1e, 0x9a, 0xb0, 0x70, 0x1f, 0xe1, 0x71, 0x32, - 0x79, 0xa1, 0xc5, 0x24, 0x2d, 0x07, 0x80, 0x58, 0xe6, 0xc7, 0x56, 0x45, 0x34, 0x75, 0x12, 0x40, - 0x92, 0xb3, 0x5b, 0xd0, 0xe7, 0x17, 0xfe, 0xe4, 0x42, 0xdf, 0x13, 0x87, 0x71, 0x92, 0x2a, 0x0e, - 0xc7, 0x40, 0x5b, 0x18, 0xaf, 0x59, 0x06, 0x8b, 0x78, 0x0e, 0xef, 0x6f, 0xe1, 0xbd, 0x7a, 0xeb, - 0x3a, 0xe6, 0xa6, 0x40, 0xd9, 0x7a, 0xf6, 0x17, 0x14, 0x5c, 0x66, 0x6b, 0xfe, 0x90, 0x91, 0x10, - 0xcf, 0xf3, 0xbf, 0xc2, 0x84, 0x6d, 0xf9, 0xe3, 0x79, 0x9e, 0x35, 0x9e, 0xa3, 0x42, 0xe5, 0x68, - 0xbb, 0x2f, 0x0b, 0xbb, 0xb4, 0x8a, 0xe9, 0x7f, 0x27, 0x46, 0xee, 0xcb, 0xa1, 0x6f, 0xfd, 0x64, - 0xa4, 0xdf, 0xd9, 0xd5, 0x20, 0xdc, 0x85, 0x60, 0x8a, 0xba, 0xa7, 0xa3, 0x80, 0x62, 0x09, 0x6e, - 0x47, 0xd9, 0xff, 0x4e, 0x03, 0x82, 0xf5, 0x4f, 0x8b, 0xb5, 0x4f, 0x3f, 0x77, 0xf0, 0x4a, 0x41, - 0x52, 0x54, 0xcf, 0x11, 0x57, 0xd9, 0x45, 0x90, 0x0a, 0x2e, 0x15, 0xc1, 0xd1, 0x3c, 0xb3, 0xdd, - 0xea, 0x9b, 0x8e, 0xa2, 0x7e, 0x0f, 0xb3, 0x88, 0xf8, 0x14, 0xef, 0x89, 0x91, 0x41, 0x2a, 0xb0, - 0xd9, 0x0c, 0xc4, 0xc6, 0x93, 0x30, 0x04, 0x89, 0x3b, 0xf5, 0x4c, 0x1e, 0xe6, 0xb1, 0x94, 0x07, - 0x46, 0x85, 0x76, 0xce, 0xd1, 0x41, 0xb1, 0x1d, 0x8c, 0x2b, 0x01, 0x93, 0x19, 0x36, 0xa7, 0x66, - 0xa2, 0xd2, 0x84, 0x57, 0x02, 0x8f, 0xe7, 0x76, 0x58, 0xa9, 0x5e, 0xfb, 0xee, 0x76, 0x80, 0xd5, - 0x83, 0x48, 0x36, 0x34, 0x2d, 0x6c, 0xe6, 0x43, 0x28, 0x79, 0xed, 0xb7, 0x92, 0x50, 0x4a, 0x3d, - 0xef, 0x08, 0x45, 0xe5, 0x9f, 0x4e, 0xbf, 0xda, 0xe2, 0x36, 0xae, 0xba, 0xe6, 0xeb, 0xd4, 0x62, - 0xad, 0xd5, 0x24, 0x5a, 0x23, 0x3e, 0xfb, 0xfc, 0xac, 0x55, 0x03, 0x0b, 0x64, 0x81, 0xed, 0x6d, - 0xc1, 0xeb, 0x0b, 0xa4, 0x21, 0x8e, 0x55, 0x9c, 0xb5, 0x8b, 0x08, 0xc1, 0xf4, 0xca, 0x3a, 0x91, - 0xee, 0xb5, 0x30, 0x3c, 0x15, 0x41, 0x80, 0xf5, 0xc8, 0xe6, 0x25, 0x06, 0x50, 0x44, 0x56, 0x5a, - 0x9b, 0x17, 0xbd, 0xa8, 0x28, 0x46, 0x7c, 0x50, 0x51, 0xac, 0xd4, 0xff, 0x8d, 0x92, 0xf1, 0x5c, - 0x45, 0x29, 0x4e, 0xb3, 0x78, 0x8e, 0x06, 0xb0, 0x7f, 0xee, 0xf3, 0x40, 0x91, 0x39, 0x39, 0xd7, - 0x3c, 0x22, 0xe8, 0x2d, 0x28, 0x42, 0xd6, 0x51, 0x59, 0xb7, 0xd0, 0x9f, 0x88, 0x76, 0x14, 0x7a, - 0x2a, 0xa3, 0x76, 0x52, 0x06, 0x83, 0xaa, 0xe8, 0xe2, 0x28, 0xdc, 0xc4, 0x33, 0x24, 0x09, 0xea, - 0xd4, 0x62, 0x8e, 0xe4, 0xa1, 0x0f, 0xec, 0x51, 0xc9, 0x07, 0x10, 0x87, 0x80, 0x30, 0x53, 0x14, - 0x2a, 0xae, 0x91, 0xdb, 0x2e, 0x25, 0x6a, 0x73, 0x74, 0x10, 0xa5, 0x60, 0xf5, 0x3f, 0x65, 0x40, - 0x85, 0xd0, 0x12, 0x2f, 0x13, 0x01, 0x5f, 0x1c, 0x07, 0xe3, 0x10, 0x66, 0x4c, 0x0d, 0x11, 0x6a, - 0x13, 0x63, 0x45, 0x74, 0xfa, 0xb2, 0xe1, 0x4f, 0xdb, 0xa1, 0x70, 0xa3, 0x1e, 0x8f, 0x97, 0xb5, - 0xe4, 0x67, 0x40, 0x58, 0x23, 0xcc, 0x8f, 0x7f, 0x80, 0x5e, 0x61, 0xae, 0x45, 0x20, 0x63, 0x9a, - 0x51, 0xe3, 0x4f, 0xa0, 0x4e, 0x52, 0x24, 0x7b, 0xf4, 0xc4, 0x58, 0xe6, 0xd7, 0xfc, 0x90, 0x4a, - 0xd8, 0x30, 0xc9, 0xf3, 0x3e, 0x43, 0x25, 0x04, 0xcf, 0x68, 0x9a, 0x76, 0x5e, 0x6a, 0x99, 0x59, - 0x3e, 0xc6, 0xf5, 0x00, 0x96, 0xa3, 0x18, 0x3a, 0x05, 0x1e, 0x02, 0x43, 0x13, 0xd4, 0x4b, 0xc7, - 0x7c, 0x81, 0xe1, 0x3f, 0x0c, 0x68, 0x2f, 0x83, 0x0e, 0x61, 0x8d, 0x45, 0x31, 0x42, 0xd3, 0x43, - 0x0b, 0xec, 0x51, 0x3f, 0x0c, 0x6f, 0xb9, 0x55, 0xb7, 0x2e, 0xce, 0x15, 0xd5, 0x6b, 0xd4, 0xda, - 0x82, 0xaa, 0x5c, 0xd7, 0xa6, 0xbd, 0x51, 0x35, 0xa6, 0x47, 0x63, 0x12, 0x91, 0x2a, 0xae, 0x9e, - 0xfb, 0xe9, 0x05, 0x4a, 0x06, 0x45, 0x9d, 0x13, 0x2e, 0x2f, 0x52, 0xb9, 0x4e, 0x80, 0x66, 0xa1, - 0xe3, 0x6f, 0x9a, 0x29, 0xe2, 0x1c, 0x06, 0x05, 0x1d, 0xd9, 0xb2, 0x4d, 0x52, 0xc1, 0x2a, 0x3c, - 0x26, 0xec, 0xd0, 0xaf, 0x3c, 0xb6, 0xa1, 0x09, 0x1d, 0x15, 0x5d, 0xf0, 0xbe, 0x9c, 0xe8, 0x4f, - 0x11, 0x7e, 0xe8, 0xd0, 0x2e, 0x2e, 0x4b, 0x66, 0x5b, 0x16, 0xc5, 0x6d, 0x6c, 0xbf, 0xba, 0xad, - 0x2d, 0xf5, 0xae, 0xb1, 0x5e, 0xee, 0xcf, 0x7b, 0x93, 0x78, 0xdd, 0xa1, 0x7c, 0x3c, 0x1c, 0xa8, - 0xc7, 0x46, 0xc3, 0x8e, 0x54, 0x16, 0x47, 0x80, 0x92, 0x67, 0xfc, 0xcc, 0x0e, 0x6f, 0xa9, 0xae, - 0x16, 0x8a, 0x48, 0xde, 0xe9, 0xa5, 0x6f, 0xaa, 0x80, 0xe7, 0xf4, 0x52, 0x11, 0x7b, 0x21, 0xac, - 0xdc, 0x02, 0x48, 0x7b, 0xa1, 0x99, 0xd0, 0x67, 0x64, 0xdc, 0x9f, 0x0a, 0x69, 0xa4, 0x8d, 0xb6, - 0x1e, 0xf2, 0xe7, 0x33, 0x32, 0x6e, 0x90, 0xd0, 0xd6, 0x9c, 0x18, 0x7b, 0xe1, 0xf3, 0x72, 0x1e, - 0xdf, 0xa6, 0x9f, 0x09, 0x65, 0x18, 0x7e, 0x4e, 0x46, 0x66, 0x97, 0xe5, 0x76, 0x9e, 0x41, 0xe7, - 0x87, 0xe2, 0x84, 0x09, 0x74, 0xdf, 0x2e, 0x6e, 0x65, 0x0c, 0xf5, 0x5d, 0x6a, 0x62, 0xfb, 0x50, - 0x39, 0x48, 0x55, 0xb6, 0x91, 0x27, 0xc3, 0x3c, 0xb4, 0x95, 0x1d, 0xc1, 0x05, 0x73, 0xd7, 0x86, - 0x94, 0x36, 0x37, 0xdd, 0x0b, 0x2b, 0x8a, 0x3a, 0x25, 0xda, 0x85, 0x30, 0x36, 0x6a, 0xec, 0xa0, - 0x74, 0xbd, 0xae, 0x76, 0xab, 0xa2, 0x6a, 0xd0, 0x4a, 0xc9, 0x73, 0x85, 0x87, 0x84, 0xf8, 0xa8, - 0x51, 0x96, 0x3c, 0x36, 0x46, 0xb1, 0x1e, 0x99, 0x11, 0x31, 0xcc, 0x33, 0x8a, 0xa3, 0x4a, 0xdb, - 0x32, 0xd2, 0xa0, 0xf1, 0x9c, 0x79, 0x34, 0x8d, 0xea, 0xac, 0x44, 0x09, 0x3c, 0xab, 0x94, 0x4d, - 0xb4, 0xdb, 0x9d, 0xaf, 0xb8, 0x50, 0x2e, 0xdc, 0xf3, 0x26, 0xd7, 0x8f, 0x32, 0x27, 0xa3, 0x98, - 0x39, 0x90, 0xbc, 0xce, 0x54, 0x6a, 0xe8, 0x84, 0xf5, 0xba, 0xdf, 0x68, 0xac, 0x0b, 0x87, 0xba, - 0x0b, 0x03, 0xd3, 0xf0, 0x9d, 0xcf, 0x38, 0x76, 0xb1, 0x11, 0x37, 0x0b, 0x06, 0x03, 0xcd, 0xeb, - 0x63, 0x60, 0x44, 0x50, 0x43, 0x51, 0xdf, 0x7a, 0x99, 0xb1, 0x4b, 0x79, 0x3a, 0x00, 0x55, 0x09, - 0xb5, 0xe0, 0x23, 0x1f, 0x44, 0x88, 0x3e, 0x0d, 0x12, 0xc6, 0x09, 0x8f, 0xca, 0x34, 0x65, 0xe0, - 0x06, 0xe9, 0x2d, 0x67, 0x92, 0x47, 0xab, 0x3e, 0x7b, 0x7a, 0x9c, 0x3f, 0xe5, 0xa9, 0xda, 0xd0, - 0x72, 0x34, 0x1f, 0x56, 0xf1, 0x24, 0x5e, 0x51, 0xf8, 0x4b, 0xbe, 0x16, 0x67, 0x61, 0xf0, 0x08, - 0xcc, 0x15, 0x0f, 0x1f, 0xb6, 0x19, 0xfa, 0x42, 0x2f, 0xa7, 0x70, 0xa1, 0x15, 0x24, 0x68, 0xe5, - 0xfa, 0xc2, 0xd6, 0xc2, 0x79, 0x24, 0x41, 0xb9, 0x6b, 0x40, 0xc7, 0xe6, 0x79, 0x11, 0x9b, 0xb4, - 0x61, 0xc7, 0xc4, 0x59, 0xd6, 0x24, 0xb4, 0x6c, 0x0e, 0xc6, 0xc6, 0x1d, 0x32, 0x3c, 0x34, 0x1e, - 0xcd, 0x14, 0xf2, 0xe4, 0xee, 0xc6, 0x35, 0x32, 0xd9, 0xe6, 0x3d, 0x30, 0x9d, 0x76, 0x7e, 0xe7, - 0x4b, 0x17, 0x17, 0x5b, 0xab, 0x6e, 0x77, 0xe9, 0xb4, 0x1f, 0x67, 0x78, 0x93, 0x8b, 0x13, 0x7b, - 0xbb, 0x43, 0xff, 0xbe, 0x4b, 0x68, 0xf2, 0x6d, 0x87, 0x78, 0x83, 0x01, 0x3b, 0xec, 0x62, 0x88, - 0x62, 0x75, 0x48, 0x26, 0xc1, 0xc4, 0xe4, 0xb0, 0xd3, 0x1e, 0xa2, 0xb8, 0x0e, 0x4f, 0xe2, 0xd3, - 0x06, 0xfc, 0xc1, 0x20, 0xb7, 0xf8, 0x23, 0xaf, 0x6d, 0xf1, 0x37, 0xaf, 0x6d, 0xc1, 0xac, 0x78, - 0x59, 0x0b, 0xcf, 0x2d, 0x9f, 0xf8, 0xb5, 0x2d, 0x7e, 0xe1, 0xda, 0x16, 0x9f, 0xae, 0x6d, 0x49, - 0x1e, 0x67, 0x8d, 0xc8, 0x61, 0x8f, 0x33, 0xbc, 0xaa, 0x25, 0x2b, 0x5e, 0xd5, 0xe2, 0xab, 0xab, - 0x5a, 0xe2, 0x86, 0xd7, 0xab, 0x08, 0xeb, 0x69, 0xf8, 0xe9, 0x6d, 0x34, 0x39, 0x7a, 0x50, 0xd3, - 0xa2, 0x8c, 0xcb, 0x18, 0xac, 0x26, 0xa8, 0x2c, 0x0c, 0x64, 0x08, 0x9b, 0xe6, 0x9e, 0x07, 0xee, - 0xb5, 0x71, 0xb2, 0xca, 0x8f, 0x2a, 0xe0, 0x66, 0xe2, 0x71, 0x45, 0x04, 0xd7, 0xb4, 0x47, 0xd5, - 0x7b, 0xc3, 0x81, 0x82, 0x09, 0x80, 0x13, 0x3a, 0xfe, 0xc5, 0xd2, 0xcb, 0xb4, 0x29, 0x56, 0xff, - 0x4f, 0x4d, 0xdb, 0xa5, 0xa8, 0x5b, 0x18, 0xc2, 0x2a, 0x1a, 0x69, 0x4b, 0x27, 0x51, 0xbe, 0x0f, - 0xd6, 0x76, 0x81, 0x24, 0xc5, 0xce, 0x0a, 0xe0, 0xb9, 0xe0, 0x3c, 0xb2, 0x52, 0xe0, 0x82, 0x70, - 0xd6, 0xc2, 0xaa, 0x5e, 0x46, 0x41, 0xf6, 0x96, 0xd7, 0xb6, 0x5a, 0x81, 0x3e, 0x34, 0xe4, 0xdb, - 0x56, 0x6b, 0xd9, 0x6a, 0x55, 0xab, 0x81, 0x01, 0x78, 0x11, 0x5c, 0x22, 0xef, 0x08, 0xd5, 0xd6, - 0xf7, 0x3e, 0x59, 0x41, 0xbd, 0x8e, 0x51, 0xd8, 0xf8, 0x4d, 0x16, 0x18, 0x2d, 0x4b, 0x24, 0x25, - 0x0c, 0x58, 0xee, 0x8a, 0xc9, 0x6d, 0x89, 0x60, 0xef, 0xa0, 0x2e, 0x38, 0xfa, 0x64, 0x89, 0x27, - 0xdb, 0xa5, 0x1f, 0xa5, 0x24, 0xa7, 0x2d, 0xbc, 0x4a, 0x7b, 0x24, 0x4a, 0xe3, 0xb3, 0xed, 0x26, - 0xce, 0x0c, 0xd3, 0xfd, 0x39, 0x5a, 0x16, 0x49, 0x00, 0x42, 0x9b, 0x6a, 0x5b, 0x40, 0x62, 0x14, - 0x83, 0x64, 0x22, 0xb5, 0x6b, 0x51, 0xaf, 0x67, 0x39, 0xea, 0xef, 0xc1, 0x19, 0x15, 0x3b, 0x15, - 0x3b, 0xb9, 0x17, 0xe4, 0x17, 0x85, 0x84, 0xd5, 0x8a, 0x58, 0x41, 0xdb, 0xd4, 0x44, 0xc9, 0xb8, - 0x55, 0x84, 0xd7, 0x3b, 0xf5, 0x10, 0x6e, 0x11, 0x6b, 0x6e, 0xb5, 0x02, 0xdb, 0x72, 0xec, 0xe1, - 0xfb, 0x3c, 0x0e, 0x6f, 0x91, 0x4e, 0x46, 0xfc, 0xb3, 0x7c, 0x05, 0x45, 0xd6, 0x2e, 0x1f, 0xb3, - 0xfb, 0xc3, 0xe4, 0x2f, 0x7f, 0x31, 0xb8, 0xb2, 0x6f, 0x60, 0x68, 0x4c, 0xae, 0x9d, 0xfa, 0x63, - 0x98, 0x4d, 0xf1, 0x80, 0x82, 0x2c, 0x4a, 0x7b, 0xa1, 0xa6, 0xc6, 0xc4, 0x8f, 0x30, 0x70, 0x2b, - 0x8c, 0x0e, 0xe8, 0xe7, 0x53, 0xe3, 0x2f, 0x7f, 0x31, 0x1d, 0x93, 0xee, 0x4a, 0xbb, 0xe6, 0xb7, - 0x4b, 0x1e, 0xa8, 0x6b, 0x49, 0xbf, 0xea, 0x1d, 0x74, 0x70, 0x61, 0x01, 0xac, 0xae, 0xab, 0xf8, - 0x13, 0x7b, 0x1a, 0xc6, 0xe3, 0x0f, 0xdf, 0xbf, 0x4a, 0xdd, 0xb9, 0x13, 0xc5, 0x18, 0xa2, 0x94, - 0xac, 0xfe, 0xef, 0x19, 0xf4, 0xec, 0xfc, 0x9c, 0x25, 0xa9, 0x0b, 0x6c, 0x18, 0x01, 0xa7, 0x4d, - 0xd0, 0xbd, 0xcc, 0xce, 0x13, 0x8c, 0x72, 0x7e, 0xb9, 0xf6, 0xd2, 0x5c, 0x99, 0xfc, 0xb4, 0xe9, - 0x3e, 0xf3, 0x72, 0xf7, 0x19, 0x52, 0x0a, 0xe8, 0x70, 0x2e, 0x13, 0x98, 0xb9, 0x2e, 0x6d, 0x7c, - 0x04, 0x23, 0x43, 0xf4, 0x84, 0xef, 0x43, 0xb4, 0x47, 0xe5, 0x14, 0xf7, 0xe4, 0xd4, 0xb9, 0xf5, - 0xae, 0x35, 0x9b, 0x66, 0x92, 0xa6, 0x4d, 0x11, 0x8b, 0x16, 0xd5, 0x89, 0xc2, 0x37, 0x5c, 0x84, - 0xd1, 0x3e, 0x5e, 0x79, 0xb5, 0xc8, 0xbf, 0x0a, 0xc0, 0x5c, 0x8b, 0x13, 0xba, 0x8f, 0xef, 0x09, - 0xfa, 0x53, 0xd0, 0xac, 0xaf, 0xd7, 0x6b, 0x55, 0x9f, 0x30, 0xdc, 0x2f, 0x18, 0x08, 0x3b, 0x2f, - 0xa6, 0xe7, 0xec, 0xe3, 0xce, 0xc7, 0x69, 0xe3, 0x63, 0x0b, 0xfe, 0xec, 0xd8, 0xce, 0x43, 0x9d, - 0xc1, 0xf0, 0x12, 0xe0, 0x0f, 0xdf, 0xbf, 0x74, 0xcf, 0x1e, 0x2e, 0x37, 0x42, 0xa6, 0xae, 0x71, - 0x1d, 0xb3, 0xb0, 0x80, 0xb9, 0xd6, 0x73, 0x81, 0xc0, 0xa0, 0xeb, 0x61, 0x72, 0x90, 0x77, 0xc0, - 0x34, 0xdb, 0xfc, 0x9e, 0xd2, 0x81, 0xc2, 0xb6, 0xb3, 0xf9, 0x05, 0xa6, 0x3e, 0x98, 0x6b, 0xa7, - 0xec, 0xe6, 0xed, 0x8c, 0x0a, 0x37, 0x3a, 0xb6, 0xbb, 0x91, 0x6b, 0x7d, 0xe6, 0xdc, 0x78, 0xb8, - 0xac, 0xe7, 0x71, 0xf7, 0xc5, 0xaf, 0xfe, 0x95, 0xcf, 0x69, 0xda, 0x04, 0x52, 0x83, 0x11, 0x17, - 0x31, 0x6f, 0x39, 0x67, 0xc3, 0x3b, 0x6d, 0xd6, 0x40, 0x6a, 0xb0, 0x60, 0xb8, 0x9c, 0x25, 0x0e, - 0xa0, 0x9b, 0xad, 0xf9, 0xda, 0xd3, 0x32, 0xfd, 0x14, 0xcc, 0xdd, 0x27, 0x38, 0xec, 0x1b, 0x3b, - 0xc3, 0x9e, 0xd8, 0x39, 0x33, 0x3d, 0x41, 0xde, 0x43, 0x7b, 0x8b, 0xe2, 0xaf, 0x7e, 0x8f, 0xdb, - 0x09, 0x1f, 0xda, 0x14, 0x05, 0xd3, 0x1e, 0x3e, 0xf1, 0x32, 0xb4, 0xde, 0xd2, 0x18, 0x27, 0x1b, - 0xef, 0x08, 0x00, 0xf7, 0xf0, 0xee, 0x33, 0xa6, 0x76, 0x7e, 0x9e, 0x62, 0x30, 0x3c, 0x72, 0xa5, - 0xa5, 0x3f, 0x06, 0x19, 0xc6, 0xfc, 0x5c, 0xad, 0x32, 0xcc, 0xa3, 0x6d, 0x64, 0x2b, 0xd3, 0xd7, - 0x93, 0xbc, 0x6d, 0x6c, 0xf2, 0x7b, 0x76, 0xfe, 0xe2, 0x66, 0x0e, 0x20, 0xc9, 0xd6, 0x32, 0x98, - 0x37, 0xad, 0x4c, 0x72, 0xe5, 0x0b, 0x8c, 0xfa, 0x58, 0x5e, 0x99, 0xcb, 0x2e, 0x92, 0xf8, 0xda, - 0x60, 0x6b, 0xdb, 0x39, 0xc6, 0x32, 0x4b, 0x8b, 0x64, 0x5b, 0xc2, 0x50, 0x3c, 0xbd, 0xe0, 0xec, - 0x0b, 0xbc, 0x2f, 0x7c, 0xe8, 0xa9, 0x3f, 0xf3, 0x93, 0x20, 0x5f, 0x4b, 0x13, 0xfc, 0xfd, 0xc2, - 0x86, 0x46, 0x9c, 0x29, 0xb6, 0x94, 0xf3, 0xc5, 0x5b, 0xdd, 0xb5, 0x31, 0x32, 0x0d, 0x2e, 0xf1, - 0x80, 0x39, 0x67, 0x49, 0x7c, 0x09, 0xe6, 0x25, 0x73, 0x4d, 0x93, 0x96, 0x34, 0x5e, 0x09, 0x6d, - 0xb4, 0x16, 0xd0, 0x21, 0xf2, 0xad, 0x07, 0x7c, 0x0a, 0x72, 0x9c, 0x93, 0x78, 0x13, 0x05, 0xec, - 0xa9, 0xa3, 0x7f, 0xe0, 0xcd, 0xc0, 0x38, 0x88, 0x6f, 0x60, 0x9d, 0x7f, 0x3a, 0x49, 0x58, 0x28, - 0x4a, 0xc0, 0xdc, 0x1e, 0x02, 0x97, 0xf3, 0x8f, 0xf9, 0x81, 0xb7, 0x40, 0xea, 0xbf, 0xc5, 0x40, - 0xaf, 0x1c, 0x6f, 0xa4, 0x69, 0x7f, 0x11, 0x5c, 0x5b, 0x40, 0x82, 0x06, 0x6d, 0x7e, 0x9a, 0x0b, - 0x07, 0x53, 0x25, 0x23, 0x25, 0xc8, 0xb0, 0x82, 0xf0, 0xed, 0x15, 0xc2, 0xc2, 0xcf, 0x8f, 0xf0, - 0x45, 0x29, 0x5e, 0xa7, 0x59, 0xcb, 0xc3, 0x78, 0x65, 0x2d, 0x36, 0xa7, 0xa3, 0x25, 0xa8, 0xaa, - 0x72, 0x20, 0x9f, 0x79, 0x3b, 0x1f, 0x3f, 0xee, 0x9c, 0xe7, 0xf8, 0xff, 0x55, 0xb4, 0xd3, 0xec, - 0x78, 0xb4, 0x22, 0x29, 0x39, 0xc6, 0x05, 0x20, 0xa4, 0x67, 0x82, 0x62, 0xed, 0xca, 0x13, 0xf3, - 0x92, 0x66, 0xe9, 0x66, 0x3d, 0xee, 0x27, 0x50, 0x23, 0x58, 0xeb, 0x68, 0xeb, 0xef, 0x1f, 0x90, - 0xaf, 0xf2, 0x13, 0xe8, 0xf4, 0x86, 0xeb, 0xbf, 0x16, 0xae, 0x74, 0xb9, 0xaf, 0x2d, 0xb3, 0xb5, - 0x03, 0xc3, 0x0b, 0x89, 0x9a, 0x4e, 0xc5, 0x73, 0x09, 0x6a, 0x4d, 0xe8, 0xbc, 0x8a, 0x80, 0xe7, - 0x2b, 0xb1, 0x23, 0x4d, 0x25, 0x8c, 0x44, 0x9c, 0xb7, 0x46, 0x74, 0xd4, 0xec, 0x92, 0x9e, 0x9e, - 0x29, 0x69, 0x40, 0x9d, 0x49, 0x46, 0x91, 0x4b, 0x0f, 0xd1, 0x6a, 0x15, 0x1d, 0x25, 0xa3, 0xc4, - 0x8d, 0x40, 0xef, 0x68, 0x76, 0x6a, 0x85, 0x7e, 0x7e, 0xfc, 0x48, 0x26, 0x2a, 0xea, 0x91, 0x72, - 0xa1, 0xe2, 0x99, 0x83, 0xf2, 0xc2, 0x76, 0x24, 0xf3, 0xe1, 0xc5, 0x83, 0xf2, 0xb9, 0x23, 0x23, - 0x77, 0x1a, 0x79, 0x6b, 0x59, 0x01, 0x6b, 0x20, 0x67, 0x1a, 0x34, 0x85, 0x9a, 0xad, 0xbc, 0xb8, - 0x95, 0x97, 0x5f, 0xad, 0xe4, 0x87, 0x8e, 0xfe, 0xa1, 0x0b, 0x1f, 0xba, 0x34, 0x04, 0xca, 0xc0, - 0x67, 0x0d, 0x8f, 0x00, 0x59, 0xad, 0x3a, 0xdb, 0x3e, 0xe4, 0x20, 0xea, 0x48, 0xdb, 0x0a, 0x18, - 0xdf, 0x10, 0x4d, 0xc0, 0x51, 0xc1, 0xec, 0x24, 0x51, 0xe7, 0xd6, 0x4e, 0x47, 0xb4, 0x55, 0xc5, - 0x45, 0x02, 0x4a, 0x46, 0x56, 0xa4, 0xea, 0x51, 0x59, 0x48, 0x4d, 0x8d, 0x44, 0x6a, 0x94, 0xd7, - 0xcd, 0x85, 0xab, 0xed, 0xe6, 0x45, 0xf6, 0xf5, 0x17, 0x55, 0x7e, 0xa3, 0xd1, 0xd3, 0x02, 0x92, - 0xab, 0x10, 0x2b, 0xa4, 0x5e, 0xbe, 0xf1, 0x1d, 0x71, 0xab, 0x6e, 0x24, 0x51, 0x19, 0xa3, 0x2a, - 0x69, 0x0f, 0xb4, 0x45, 0x27, 0x83, 0xb8, 0x56, 0xde, 0xec, 0x68, 0xea, 0x31, 0x30, 0xf1, 0xa1, - 0x72, 0x62, 0xa0, 0x92, 0x2c, 0x19, 0x80, 0x87, 0x6f, 0xe5, 0x03, 0x84, 0x4e, 0x95, 0xe2, 0x6b, - 0x43, 0x1b, 0x31, 0x7c, 0xc5, 0x31, 0x83, 0xbf, 0xf8, 0xa6, 0xa2, 0x8a, 0x2e, 0x03, 0x98, 0x98, - 0xe7, 0xa0, 0x0c, 0xc3, 0x20, 0xa1, 0xeb, 0x25, 0xca, 0x82, 0x68, 0xc1, 0xd6, 0x0a, 0xe5, 0xbc, - 0x1a, 0x2c, 0xd7, 0xd1, 0xcb, 0x2d, 0x21, 0x7b, 0x27, 0xcf, 0x4e, 0x2e, 0x9c, 0xa1, 0x2a, 0x71, - 0x3a, 0xb4, 0x01, 0xca, 0xa1, 0x2f, 0x36, 0x46, 0xe7, 0xe9, 0x78, 0x8f, 0x00, 0x3f, 0x75, 0x94, - 0x0a, 0x64, 0xf8, 0xd0, 0x30, 0x06, 0x84, 0xc0, 0x1e, 0xcb, 0x2d, 0x20, 0x44, 0xf3, 0xbe, 0x3a, - 0xa0, 0xa4, 0xb2, 0xda, 0xb8, 0x2c, 0xbe, 0x15, 0xd9, 0x76, 0x23, 0x68, 0xfd, 0x1a, 0x83, 0xc9, - 0x62, 0x9a, 0xfa, 0x7e, 0x9e, 0x5f, 0xe8, 0x74, 0x4b, 0x22, 0xe9, 0x2d, 0xf2, 0xc4, 0xdd, 0x80, - 0xa9, 0x5b, 0x54, 0x7f, 0x41, 0xdb, 0x4e, 0x5a, 0xe2, 0x13, 0x5e, 0xba, 0x15, 0xcf, 0x59, 0x65, - 0x16, 0xfe, 0xc5, 0x5e, 0xf3, 0x7d, 0xb9, 0xa2, 0x40, 0xbd, 0xfe, 0x3e, 0x7f, 0xc1, 0x0d, 0xa0, - 0xe2, 0x09, 0x1b, 0x06, 0x83, 0x47, 0x94, 0x91, 0x03, 0x9a, 0x1a, 0x01, 0xfa, 0xc5, 0x45, 0xaa, - 0x00, 0x2c, 0xf0, 0x3e, 0x80, 0x0a, 0x0e, 0x56, 0x11, 0xd6, 0xc4, 0x3f, 0x9d, 0xa4, 0xa7, 0x18, - 0xb4, 0x93, 0x3f, 0x07, 0x30, 0x08, 0x96, 0xf6, 0x06, 0x36, 0xa5, 0x4d, 0xf5, 0xaf, 0xa5, 0xa4, - 0xcb, 0xfb, 0xfc, 0x92, 0x8b, 0x25, 0x3c, 0x80, 0x8a, 0x44, 0x21, 0xa7, 0x2b, 0x11, 0x7e, 0x58, - 0x72, 0xe6, 0x70, 0x1a, 0x2b, 0xa4, 0xe4, 0x9a, 0x49, 0x82, 0x7c, 0x07, 0x25, 0x71, 0xf9, 0xd2, - 0xc8, 0x6c, 0x55, 0xf9, 0xf5, 0x05, 0x70, 0x9b, 0x45, 0x43, 0x63, 0x51, 0x1d, 0x45, 0x0a, 0x76, - 0x92, 0x26, 0x1d, 0x25, 0x55, 0x30, 0x7c, 0x5f, 0x14, 0x8d, 0x1c, 0x24, 0x92, 0x80, 0xf9, 0x50, - 0x00, 0x6b, 0xd1, 0x49, 0x38, 0xbe, 0x59, 0x08, 0xc3, 0x42, 0x72, 0xd7, 0xa9, 0x6c, 0xb4, 0xc1, - 0x4a, 0x3c, 0xa9, 0x0f, 0xec, 0x3b, 0x39, 0xb0, 0x7c, 0x93, 0x7b, 0x52, 0xaf, 0xbf, 0xb4, 0x92, - 0x1c, 0xd9, 0xdc, 0x45, 0x18, 0x0d, 0x73, 0x10, 0xbe, 0xb7, 0x32, 0xf5, 0xf9, 0x24, 0x3a, 0x15, - 0xc0, 0x88, 0xb6, 0x92, 0x61, 0x04, 0x30, 0xde, 0xc5, 0xa2, 0xda, 0x40, 0x4a, 0x94, 0xf3, 0x1a, - 0x25, 0xd1, 0xac, 0x56, 0x84, 0x9d, 0xa2, 0x14, 0x03, 0xf5, 0x27, 0x07, 0xf9, 0x3d, 0x07, 0x19, - 0x2f, 0xa8, 0x2c, 0xd2, 0x82, 0x04, 0xd2, 0xf7, 0x5e, 0x03, 0x11, 0x24, 0x50, 0x55, 0xca, 0xaf, - 0xf4, 0x0b, 0xc0, 0xe2, 0x9a, 0x61, 0x25, 0x27, 0xfe, 0x29, 0xff, 0x8b, 0xd3, 0x01, 0xee, 0xcd, - 0xe7, 0x1a, 0x0e, 0xe9, 0x32, 0xd6, 0xd9, 0xf7, 0xec, 0x57, 0x72, 0xb3, 0x19, 0x30, 0xef, 0x1a, - 0xb1, 0x30, 0x93, 0x0c, 0xf3, 0xe1, 0xd2, 0x5f, 0x9b, 0x5c, 0x33, 0x79, 0xb8, 0xc4, 0xc2, 0x6b, - 0x23, 0x8b, 0xe1, 0x11, 0x2b, 0x58, 0xb7, 0xce, 0xb8, 0x7c, 0x9d, 0x40, 0x7d, 0x29, 0x3f, 0x90, - 0x58, 0x5e, 0x27, 0x9f, 0xd8, 0x92, 0xc3, 0x85, 0x10, 0x8b, 0xbd, 0x77, 0x56, 0xe4, 0xbc, 0xb6, - 0x26, 0x04, 0x23, 0xfe, 0x1d, 0xc6, 0x23, 0xac, 0xd8, 0x8b, 0xd5, 0xc6, 0xcf, 0x6b, 0x3f, 0x89, - 0xac, 0xb3, 0xd7, 0xfe, 0x7c, 0x4e, 0x0e, 0xf7, 0x87, 0xcb, 0x14, 0x60, 0x68, 0x1e, 0xe1, 0x13, - 0x36, 0x04, 0x2f, 0xd3, 0x98, 0x6e, 0x66, 0xc1, 0x8b, 0x42, 0xc9, 0x3a, 0x3c, 0xb3, 0xf9, 0xbd, - 0xa1, 0x6f, 0x9c, 0xdf, 0xc0, 0xc6, 0x04, 0x19, 0xd1, 0x76, 0xd8, 0x95, 0x1f, 0xda, 0x96, 0xb9, - 0xf0, 0x8e, 0xc4, 0xe5, 0x88, 0x0b, 0xdb, 0x94, 0x4b, 0x29, 0xdf, 0xe2, 0xb6, 0x32, 0x9c, 0xd7, - 0xdf, 0x41, 0xc7, 0x82, 0x94, 0x14, 0x4f, 0x81, 0xbf, 0xcc, 0x2b, 0x72, 0xac, 0x52, 0x6f, 0x8a, - 0x57, 0x41, 0x98, 0x52, 0x67, 0x76, 0x96, 0x69, 0x32, 0x71, 0x6f, 0xc8, 0x4f, 0x39, 0x6b, 0xfd, - 0x32, 0xf5, 0x8a, 0x0d, 0x3a, 0x6c, 0x4e, 0x37, 0x17, 0x0e, 0xcb, 0xa7, 0x5d, 0xb8, 0x61, 0xe8, - 0x2c, 0xe8, 0x54, 0xe8, 0xc6, 0x9a, 0x2a, 0xaa, 0x62, 0xa6, 0x43, 0x7a, 0x28, 0x2a, 0x80, 0xd6, - 0x1b, 0xaf, 0x56, 0xb3, 0x7e, 0xf3, 0x44, 0x1b, 0xb6, 0x3a, 0xa4, 0x2b, 0xd4, 0xcf, 0xcd, 0x0a, - 0x44, 0xc8, 0x72, 0x54, 0x76, 0x3d, 0x50, 0x41, 0x7f, 0xf3, 0x2c, 0x24, 0x74, 0xae, 0x80, 0xcb, - 0x4e, 0xc3, 0x38, 0xa4, 0xb6, 0xea, 0x78, 0xf0, 0xc5, 0x1d, 0x27, 0x53, 0x40, 0x2a, 0x61, 0x0e, - 0x47, 0xc3, 0x19, 0xef, 0xfb, 0x63, 0x3f, 0x35, 0x2e, 0x89, 0x6c, 0x1e, 0x01, 0xd9, 0xac, 0x1f, - 0x0d, 0x39, 0xe4, 0xe8, 0x19, 0x08, 0xbc, 0xcb, 0x33, 0x8c, 0x95, 0x98, 0xdf, 0x8b, 0x8c, 0x37, - 0x17, 0xa8, 0xd6, 0x70, 0xb5, 0x42, 0x38, 0x87, 0x55, 0xe0, 0x26, 0xad, 0x30, 0x4c, 0xd3, 0x96, - 0xf6, 0x0a, 0x66, 0x84, 0xfe, 0xd5, 0xe3, 0x5e, 0x0b, 0x30, 0x9b, 0x53, 0x40, 0x5a, 0xe1, 0x32, - 0x08, 0xc2, 0x0f, 0x06, 0x66, 0x21, 0xb5, 0x5d, 0x69, 0xe8, 0xb4, 0x13, 0x9d, 0x73, 0x00, 0x37, - 0xa4, 0x11, 0xf3, 0x48, 0x75, 0x0f, 0x97, 0x09, 0x46, 0xc1, 0x82, 0x6c, 0x1f, 0x92, 0x10, 0x14, - 0xcb, 0xb5, 0x61, 0x3d, 0x84, 0x99, 0x0e, 0x7a, 0xb9, 0xb6, 0x81, 0xee, 0x61, 0x60, 0x65, 0x63, - 0x6b, 0xf9, 0xe4, 0x04, 0xa0, 0x7d, 0xe2, 0xc6, 0xd1, 0x05, 0x4e, 0x3c, 0xdb, 0x86, 0x3b, 0xd8, - 0x3e, 0x5a, 0x7e, 0xf5, 0x57, 0x4e, 0x0c, 0xbe, 0xe6, 0xf5, 0x24, 0x24, 0x15, 0xa3, 0x5b, 0xad, - 0xed, 0xf5, 0x76, 0x1c, 0xa2, 0x11, 0x42, 0xb1, 0x20, 0x0c, 0x41, 0x41, 0x0e, 0x2e, 0xc3, 0xdd, - 0x55, 0x21, 0x85, 0xb3, 0x44, 0x1a, 0x7b, 0x8e, 0xc7, 0x07, 0xbe, 0x43, 0xbd, 0x9f, 0x93, 0xc9, - 0x8f, 0xc8, 0x3a, 0xe8, 0xff, 0x39, 0x26, 0x3a, 0x90, 0x7e, 0xd7, 0x74, 0x31, 0x27, 0x11, 0x46, - 0x65, 0x9e, 0x7a, 0x3f, 0xa2, 0xbb, 0x5a, 0x24, 0xe1, 0xcc, 0xfd, 0x23, 0x5d, 0x59, 0x56, 0xaf, - 0xff, 0xa8, 0x6b, 0xf7, 0xb6, 0xf3, 0xb5, 0xf7, 0x46, 0x54, 0xfb, 0x47, 0xef, 0x11, 0xff, 0x60, - 0xde, 0x98, 0x40, 0x80, 0x2c, 0xc9, 0x04, 0x79, 0x81, 0x4d, 0x6f, 0x02, 0xfd, 0x60, 0xb5, 0xbf, - 0x3b, 0xdf, 0x38, 0x7f, 0x72, 0x7e, 0xf0, 0x04, 0xfd, 0x4a, 0xcf, 0x90, 0xf5, 0xad, 0x58, 0xcf, - 0x93, 0xec, 0xf2, 0x46, 0xe9, 0x55, 0xa3, 0x6d, 0x3c, 0xbe, 0x8d, 0xb8, 0x83, 0x59, 0x42, 0x67, - 0x0c, 0x90, 0x5d, 0x2b, 0xee, 0xe3, 0x73, 0xb6, 0x73, 0xf1, 0x56, 0x4e, 0x14, 0xd7, 0x94, 0x68, - 0xd7, 0x08, 0x1a, 0x89, 0xb5, 0xc4, 0x05, 0x5e, 0x0c, 0x5b, 0xb7, 0x2c, 0x1a, 0xcd, 0x11, 0x50, - 0xa8, 0x89, 0xa4, 0x8c, 0x48, 0x8b, 0xb8, 0x22, 0xfd, 0x94, 0xae, 0x8e, 0x02, 0x5c, 0xe1, 0xed, - 0x50, 0x30, 0x14, 0x78, 0x01, 0x94, 0xf3, 0x1c, 0x7e, 0xfa, 0xa7, 0x38, 0x8c, 0xce, 0x9d, 0xc3, - 0x2e, 0xc0, 0xe2, 0xa9, 0xdb, 0x20, 0x4b, 0xe8, 0xca, 0x32, 0x7e, 0xd9, 0xe0, 0x50, 0xce, 0x75, - 0x67, 0xd2, 0x3f, 0x49, 0x7d, 0xf4, 0x1e, 0x2e, 0x17, 0xa0, 0x7c, 0x9b, 0xeb, 0xa3, 0xb1, 0x87, - 0x4a, 0x06, 0x9a, 0x6f, 0x8f, 0x4a, 0x0e, 0x84, 0x47, 0xf7, 0x3a, 0x10, 0x52, 0xe1, 0x40, 0x40, - 0xf7, 0xc1, 0x76, 0xda, 0xfb, 0x2c, 0x39, 0xf4, 0x48, 0xb6, 0x29, 0xe4, 0xd0, 0x23, 0x45, 0x57, - 0x8f, 0x1c, 0x82, 0xd8, 0x85, 0xd9, 0x62, 0xb1, 0x36, 0x9d, 0x7c, 0x1b, 0xe2, 0xc7, 0xb3, 0xa5, - 0xa0, 0xbe, 0xd4, 0x74, 0x97, 0x40, 0x68, 0xae, 0xf9, 0xf1, 0xe1, 0x72, 0x6c, 0x3d, 0x7a, 0x64, - 0xaf, 0xcd, 0xf5, 0xfa, 0xe3, 0x19, 0x82, 0x25, 0x89, 0xcb, 0x07, 0x03, 0xf6, 0xe4, 0xe1, 0xf2, - 0x29, 0xee, 0x1c, 0xc3, 0x13, 0x2c, 0xf0, 0x07, 0xf2, 0x3f, 0xba, 0x79, 0xe4, 0x40, 0x01, 0x5e, - 0x0b, 0x39, 0x17, 0x1f, 0xd9, 0xe6, 0xda, 0x01, 0x69, 0x71, 0x3b, 0x3a, 0x83, 0x0f, 0x0f, 0x97, - 0x7f, 0x5c, 0x3f, 0x52, 0x66, 0x95, 0xc8, 0xfd, 0xc8, 0xe1, 0x98, 0x02, 0x52, 0x7e, 0x04, 0xa2, - 0xfb, 0xcc, 0x35, 0x67, 0x3e, 0xea, 0xb4, 0x54, 0xee, 0x7c, 0x64, 0xaa, 0x0a, 0x3f, 0x9a, 0x37, - 0x1f, 0x0b, 0xd4, 0xff, 0x91, 0xdc, 0x56, 0x1f, 0xcd, 0xcd, 0x3a, 0x97, 0x6b, 0x59, 0x2b, 0xe6, - 0xc0, 0x6a, 0x4d, 0x55, 0xed, 0x29, 0x79, 0x5b, 0x6e, 0x0c, 0xef, 0x48, 0x4c, 0xc2, 0x37, 0x40, - 0x4c, 0x8f, 0xf8, 0xcc, 0xfc, 0x68, 0x24, 0x26, 0xa7, 0x1b, 0xc1, 0x34, 0x98, 0xad, 0x56, 0xbb, - 0xa1, 0xb9, 0x86, 0xca, 0xdb, 0xee, 0x8d, 0x9d, 0xdf, 0x0f, 0xcc, 0x57, 0x2f, 0xf1, 0x9a, 0xc2, - 0xec, 0x35, 0x27, 0x17, 0xeb, 0xe4, 0x11, 0x12, 0xe8, 0xa3, 0x53, 0x5c, 0x81, 0x06, 0x6b, 0x18, - 0x03, 0x1b, 0x3c, 0x7a, 0x0c, 0x10, 0x1c, 0x7e, 0x94, 0xae, 0xed, 0x33, 0x71, 0x0c, 0x15, 0x24, - 0x47, 0x5a, 0xd8, 0x7f, 0x19, 0xf0, 0x8d, 0xf0, 0xb5, 0x48, 0xbf, 0xdb, 0xc1, 0x4a, 0xe9, 0x66, - 0x18, 0xe9, 0xaf, 0xe1, 0x2b, 0xdb, 0xe8, 0x8c, 0x13, 0x03, 0x4f, 0x6a, 0x72, 0xbd, 0xde, 0x26, - 0x8b, 0x90, 0x88, 0x65, 0x63, 0x59, 0xd6, 0x56, 0x8c, 0xcd, 0xb6, 0x4d, 0x57, 0xc3, 0x05, 0xb9, - 0x91, 0xb6, 0xce, 0xc1, 0x79, 0x7c, 0x87, 0x44, 0x68, 0x70, 0x9d, 0xdd, 0x86, 0xb5, 0x18, 0x2d, - 0xe4, 0x89, 0xeb, 0x36, 0x58, 0xd2, 0x07, 0x74, 0x7e, 0xb9, 0x42, 0x56, 0xae, 0xb3, 0x56, 0x1c, - 0xa1, 0x9c, 0xf6, 0x82, 0x3b, 0x85, 0xaa, 0x43, 0xc7, 0xbb, 0x4c, 0x98, 0x45, 0x20, 0x97, 0x89, - 0xea, 0xf1, 0x28, 0x6b, 0xf1, 0x37, 0x2f, 0x71, 0x37, 0xba, 0xde, 0xba, 0x4e, 0x02, 0x00, 0x14, - 0x2c, 0x00, 0xb0, 0x0f, 0x02, 0x14, 0xd9, 0x6e, 0x81, 0x3e, 0x9f, 0xae, 0x56, 0xbf, 0x59, 0x37, - 0x52, 0xa6, 0x12, 0x3d, 0xaa, 0xdd, 0x0d, 0x38, 0xa0, 0x5f, 0x53, 0x70, 0x4b, 0xdb, 0xb9, 0xad, - 0xd7, 0x31, 0xdf, 0x1f, 0x15, 0x15, 0x61, 0x30, 0x5b, 0x28, 0x87, 0x57, 0x39, 0x08, 0xca, 0xc4, - 0x23, 0x58, 0x5a, 0xc9, 0xef, 0x44, 0xc9, 0x73, 0x5e, 0x12, 0x89, 0x4c, 0x6c, 0xb9, 0xa3, 0xed, - 0xce, 0xe5, 0x8a, 0x96, 0x6b, 0x59, 0x15, 0x3f, 0x57, 0x52, 0xa8, 0xeb, 0x39, 0xaf, 0xeb, 0x14, - 0x25, 0xcc, 0x9f, 0xbd, 0xee, 0xe1, 0x61, 0xe7, 0x40, 0x8c, 0xf6, 0x4f, 0x1e, 0x79, 0x2b, 0x8a, - 0x97, 0x32, 0xc9, 0xd7, 0xce, 0x80, 0xbf, 0xa3, 0x07, 0xa2, 0xc5, 0x6f, 0x7e, 0xb2, 0x41, 0x22, - 0x8e, 0xb4, 0xd3, 0x1d, 0x9a, 0x75, 0xa0, 0x4c, 0x12, 0xfd, 0x04, 0xf4, 0x30, 0x3a, 0x4c, 0x86, - 0x36, 0x06, 0x16, 0x42, 0xc2, 0xb8, 0xc0, 0x4b, 0xa1, 0xa7, 0xec, 0x49, 0x66, 0x45, 0x60, 0x00, - 0xaf, 0xdd, 0x2f, 0xae, 0x48, 0xcb, 0xa3, 0x57, 0x06, 0xb3, 0xc5, 0x09, 0xd4, 0x78, 0xea, 0xe1, - 0x99, 0xee, 0x7a, 0x62, 0x1f, 0x1e, 0xee, 0xaf, 0x92, 0xa3, 0xa3, 0xa3, 0x7d, 0x8c, 0x77, 0x07, - 0x95, 0xfc, 0xec, 0x30, 0x68, 0x81, 0xe9, 0xe7, 0x0e, 0x78, 0x93, 0x19, 0xf3, 0xa4, 0x45, 0x05, - 0x43, 0x01, 0xc6, 0x0c, 0x8f, 0xba, 0x32, 0x1c, 0xe2, 0xa7, 0x23, 0xef, 0x67, 0xe5, 0xff, 0xf0, - 0x31, 0x6c, 0x8e, 0x64, 0x90, 0x9f, 0xf5, 0xc6, 0x33, 0xc6, 0xe3, 0x20, 0xa1, 0x97, 0xc1, 0x26, - 0xdf, 0xd8, 0xf0, 0x80, 0x9c, 0x2a, 0x23, 0x2b, 0x69, 0x40, 0x56, 0xe1, 0xba, 0x80, 0xe6, 0x6d, - 0xb0, 0xcb, 0x00, 0xd5, 0x16, 0x39, 0x95, 0xf0, 0xb0, 0xd2, 0x7e, 0xb7, 0x47, 0x39, 0x57, 0x2b, - 0x78, 0xea, 0xf1, 0xa7, 0x80, 0x51, 0x38, 0x68, 0x6c, 0xcf, 0x69, 0x34, 0x20, 0x9b, 0xb4, 0x53, - 0x4a, 0x95, 0x01, 0xfe, 0x9c, 0x24, 0xb7, 0x4a, 0xa2, 0x7c, 0xad, 0xb1, 0x00, 0x1d, 0x55, 0x31, - 0x4c, 0xaf, 0x03, 0xf4, 0x99, 0xe1, 0x8b, 0x83, 0x76, 0x8a, 0x9f, 0x32, 0xa3, 0xd3, 0x69, 0xbb, - 0x62, 0x6d, 0xe0, 0x63, 0x64, 0x0e, 0x45, 0x5a, 0x5f, 0xa5, 0x25, 0x32, 0xad, 0x2b, 0xf3, 0x19, - 0xc7, 0x24, 0xc0, 0x5a, 0xa8, 0x54, 0x3e, 0x13, 0x4d, 0x80, 0x2a, 0x68, 0x75, 0x41, 0x68, 0x8b, - 0xe2, 0x7b, 0x32, 0xab, 0xb6, 0x94, 0xc6, 0xf5, 0x64, 0x91, 0xde, 0xe9, 0x62, 0x3f, 0xcb, 0x08, - 0x1c, 0x09, 0xd0, 0x40, 0xbd, 0xb6, 0x7e, 0xce, 0x4d, 0x2f, 0x20, 0x69, 0xf8, 0xd8, 0x44, 0xcc, - 0xf1, 0xef, 0x47, 0x1d, 0x80, 0x10, 0xfe, 0x71, 0xfc, 0xd8, 0x2e, 0x15, 0xe8, 0x83, 0x48, 0x38, - 0xe4, 0x17, 0xce, 0x8d, 0xaa, 0x20, 0x44, 0x4c, 0xb3, 0x26, 0x65, 0x18, 0x38, 0x55, 0x19, 0x76, - 0x77, 0xbb, 0x07, 0x83, 0x86, 0xc5, 0x8e, 0x8e, 0xf0, 0x6e, 0xd7, 0xdd, 0x41, 0xaf, 0xdb, 0x6e, - 0x58, 0x9d, 0x76, 0xb7, 0x57, 0x67, 0x68, 0x0d, 0x5b, 0xaa, 0x77, 0x03, 0x85, 0x9c, 0x4c, 0x20, - 0xe7, 0x60, 0x5f, 0x25, 0x8d, 0x15, 0x0e, 0xf3, 0xb4, 0x2b, 0x99, 0xd6, 0xee, 0xaa, 0xb4, 0x99, - 0x4c, 0xeb, 0xb9, 0x9d, 0x76, 0x05, 0x2e, 0xea, 0x75, 0xec, 0xab, 0x2c, 0x27, 0x8b, 0x89, 0x42, - 0xbb, 0x03, 0x97, 0xff, 0xee, 0xb9, 0x44, 0x91, 0x53, 0xbe, 0x1f, 0xcf, 0x45, 0x02, 0x3c, 0xf2, - 0xfa, 0xfb, 0xa0, 0x57, 0x1f, 0x7a, 0x79, 0x08, 0xab, 0x9f, 0x45, 0xc0, 0x28, 0xa8, 0xb7, 0xd9, - 0x71, 0x7a, 0xb6, 0x5c, 0x42, 0xf9, 0xcb, 0x49, 0xbb, 0xb9, 0x77, 0xda, 0xd8, 0x41, 0x6e, 0x76, - 0x92, 0xfc, 0x8c, 0x42, 0xe6, 0xec, 0xab, 0x23, 0x3c, 0xc9, 0x11, 0xf2, 0x52, 0xd9, 0xc7, 0x69, - 0x97, 0xb3, 0xdb, 0x48, 0x8b, 0x9e, 0x72, 0xe4, 0x74, 0x9c, 0x4d, 0xf6, 0x70, 0xcc, 0x36, 0xf9, - 0xe0, 0xea, 0xf5, 0xdd, 0x41, 0x8d, 0xf6, 0x3c, 0xec, 0xee, 0xd5, 0x88, 0xd8, 0x89, 0xca, 0xab, - 0x86, 0x24, 0xf7, 0x88, 0x10, 0x3f, 0xe0, 0x56, 0xef, 0xea, 0xa1, 0x5d, 0xeb, 0x2b, 0xf6, 0x16, - 0xcb, 0xa7, 0xa1, 0x4c, 0xf2, 0x75, 0xbb, 0x10, 0x00, 0x8d, 0x07, 0xe5, 0x60, 0x43, 0xc0, 0x31, - 0x67, 0x2f, 0x4e, 0x9e, 0x30, 0x4b, 0x56, 0x31, 0xf5, 0xc1, 0x2e, 0xc0, 0xc9, 0x6f, 0x39, 0x4e, - 0x8f, 0xbc, 0x83, 0x3d, 0x1b, 0x08, 0xae, 0x79, 0xb0, 0xd7, 0xe8, 0xb4, 0xd5, 0x61, 0x12, 0x48, - 0x1f, 0xec, 0x52, 0xfa, 0x60, 0x57, 0xa6, 0x73, 0x8b, 0x31, 0xe5, 0x03, 0x92, 0xc2, 0x80, 0xec, - 0xd9, 0x42, 0x32, 0x60, 0xbe, 0xfe, 0xfe, 0x9a, 0x0f, 0x57, 0x67, 0x20, 0x52, 0x23, 0x2f, 0x05, - 0xb4, 0x76, 0x06, 0x8f, 0x93, 0x86, 0x38, 0xb0, 0x4d, 0x0d, 0x47, 0x30, 0xe5, 0xa2, 0x2f, 0x42, - 0xe0, 0x09, 0x72, 0x49, 0xa4, 0xc8, 0xcf, 0x30, 0xac, 0x99, 0x97, 0x63, 0x52, 0x93, 0x07, 0x84, - 0x36, 0xe9, 0x07, 0xef, 0x08, 0xd9, 0x42, 0xf4, 0xc6, 0xf2, 0x4c, 0x58, 0x48, 0xac, 0xb2, 0x14, - 0x35, 0x3e, 0x61, 0x8f, 0xbd, 0xc3, 0x81, 0xe6, 0x77, 0x6f, 0xa1, 0xc3, 0x81, 0xad, 0xdd, 0x87, - 0xcb, 0x9f, 0x73, 0xe7, 0x1d, 0xb3, 0x29, 0xb8, 0x26, 0x4c, 0xf1, 0x1f, 0x23, 0xb5, 0x5e, 0x81, - 0x79, 0x00, 0xac, 0x9f, 0x8b, 0xae, 0x97, 0x8f, 0xb8, 0x3f, 0x17, 0x68, 0xd0, 0x5e, 0x9f, 0x81, - 0xba, 0x18, 0x4c, 0x6f, 0xdc, 0x0c, 0x54, 0xd0, 0x35, 0x2d, 0xbc, 0x1b, 0xf9, 0x36, 0x14, 0x56, - 0x9c, 0x08, 0xb8, 0x67, 0x5e, 0x10, 0xe4, 0x32, 0x71, 0xdf, 0x59, 0x97, 0xcc, 0xc1, 0x55, 0x1f, - 0xf2, 0xea, 0x2f, 0x78, 0x6e, 0x67, 0xec, 0xd6, 0xc0, 0x50, 0xac, 0xfd, 0x4a, 0xd4, 0x20, 0x5c, - 0x1c, 0xcc, 0x9b, 0x8c, 0xa8, 0x72, 0xca, 0x22, 0xe2, 0x6c, 0x27, 0x1e, 0xbd, 0x3a, 0x33, 0x96, - 0x13, 0x39, 0x5a, 0x98, 0x38, 0x4d, 0x62, 0x14, 0x66, 0xcf, 0xbf, 0xf6, 0x03, 0xc8, 0x06, 0x88, - 0x1c, 0x41, 0x6b, 0x09, 0xd6, 0xcc, 0x41, 0x90, 0xd5, 0xbb, 0x02, 0x42, 0x7c, 0x18, 0x96, 0x80, - 0xc7, 0xfd, 0xc5, 0x4e, 0xab, 0xd5, 0xca, 0x9d, 0x59, 0xca, 0xe7, 0xdc, 0xec, 0x9c, 0x0e, 0xb7, - 0x9c, 0x62, 0x88, 0x28, 0x5c, 0x03, 0xd8, 0xd0, 0xbc, 0xed, 0x4f, 0xcc, 0xf1, 0x41, 0xb8, 0xd1, - 0xb3, 0x0f, 0xf5, 0x6d, 0xe4, 0xc7, 0x68, 0x4a, 0x23, 0xfc, 0xe3, 0x2e, 0x29, 0x52, 0x88, 0x75, - 0xc5, 0x28, 0x8e, 0x4b, 0xed, 0x82, 0xe2, 0x25, 0x03, 0x8f, 0xbd, 0xa3, 0x1d, 0xa9, 0x0e, 0xc6, - 0x76, 0xb9, 0xc2, 0xd5, 0x22, 0x5b, 0xd6, 0x7d, 0xcb, 0x9c, 0x87, 0xcc, 0xb2, 0xf8, 0x4b, 0xcc, - 0xf8, 0x89, 0xbd, 0x56, 0xe2, 0x2c, 0x41, 0x5f, 0x9b, 0x82, 0xaa, 0x13, 0x80, 0xee, 0xe9, 0x9a, - 0x29, 0x58, 0x5f, 0xcd, 0x38, 0x09, 0xce, 0x83, 0xc8, 0xd4, 0x37, 0x51, 0xce, 0x58, 0x61, 0x69, - 0x85, 0x86, 0x42, 0xae, 0xaf, 0x14, 0xc6, 0x23, 0x2f, 0xb2, 0x90, 0x93, 0xac, 0xee, 0xe5, 0xfa, - 0x40, 0x2b, 0xc7, 0xe8, 0xc2, 0x12, 0xc6, 0xa3, 0x0a, 0xca, 0x98, 0x18, 0xa0, 0xbc, 0xb3, 0x35, - 0xfc, 0x79, 0x8b, 0x0a, 0xdd, 0x99, 0xbd, 0x26, 0x53, 0x99, 0x6b, 0x56, 0xc7, 0x17, 0xc1, 0xa5, - 0x17, 0x4a, 0x17, 0xd6, 0x94, 0xf1, 0x05, 0xd4, 0x87, 0xb4, 0x4c, 0x08, 0x53, 0x77, 0x23, 0x53, - 0x56, 0xd3, 0xa4, 0x5e, 0xaf, 0x1a, 0xe6, 0x1a, 0x1f, 0xe7, 0x51, 0xe2, 0x8a, 0x9e, 0x68, 0xeb, - 0x81, 0x63, 0x4a, 0xa1, 0x4d, 0xc2, 0xad, 0x45, 0x92, 0x47, 0x30, 0x9e, 0x8a, 0x9c, 0xa1, 0xb2, - 0x74, 0xbd, 0x29, 0x73, 0x42, 0xbe, 0x83, 0x87, 0xc0, 0x7a, 0xed, 0xcf, 0x69, 0x9b, 0x87, 0xb6, - 0x41, 0xa3, 0x74, 0x14, 0x90, 0x6e, 0x1f, 0x0c, 0x69, 0xd7, 0x7e, 0x5e, 0x44, 0x5c, 0x98, 0x59, - 0x0b, 0x84, 0x07, 0x30, 0xf7, 0x81, 0x98, 0x1f, 0x22, 0x61, 0xb5, 0xb3, 0x29, 0x7a, 0x15, 0xe5, - 0x82, 0x3b, 0xdd, 0xe7, 0xd8, 0x02, 0x25, 0xfa, 0x92, 0x79, 0xe8, 0x0d, 0x7f, 0xe8, 0x40, 0xc5, - 0x6b, 0xd1, 0x69, 0xb0, 0x04, 0xa1, 0x85, 0x5f, 0x12, 0xda, 0xa2, 0x04, 0x0f, 0xd7, 0xfc, 0x21, - 0x33, 0x2e, 0x18, 0x64, 0xcb, 0x9d, 0xe5, 0x40, 0x32, 0xc2, 0x27, 0x8e, 0x81, 0x80, 0x79, 0xd9, - 0x4f, 0xcc, 0xfb, 0xa1, 0x68, 0xbc, 0x5f, 0xe0, 0xda, 0x1d, 0xca, 0xbd, 0xd2, 0x6a, 0x7f, 0xbd, - 0xfe, 0xa6, 0x5e, 0xff, 0xba, 0x5e, 0x7f, 0x0a, 0x74, 0x56, 0x3b, 0x5f, 0xad, 0x9e, 0x23, 0xc1, - 0xd5, 0x6e, 0x57, 0xab, 0xef, 0x90, 0x3f, 0x5e, 0x09, 0x67, 0x75, 0xed, 0x69, 0xbe, 0xf0, 0xbb, - 0xdd, 0x49, 0x41, 0x2b, 0x84, 0x47, 0x26, 0xed, 0x15, 0x0b, 0x26, 0x26, 0x17, 0x4f, 0xd2, 0x91, - 0x45, 0x2b, 0xcb, 0xc3, 0xed, 0x85, 0x71, 0x31, 0xb8, 0xb4, 0x44, 0x09, 0x34, 0x88, 0x34, 0x83, - 0x41, 0x94, 0x38, 0x2f, 0xa0, 0x43, 0x1a, 0x90, 0xfa, 0x7a, 0xc1, 0x6f, 0x6d, 0x7e, 0x3b, 0xe6, - 0xf1, 0x0b, 0xc8, 0x05, 0x51, 0x5a, 0x3e, 0x65, 0x3c, 0x86, 0x1e, 0xda, 0x07, 0x68, 0x99, 0xe7, - 0x4b, 0x9e, 0x76, 0x9e, 0x51, 0xc4, 0x86, 0x86, 0x41, 0x64, 0x62, 0xcb, 0xa1, 0x79, 0xfc, 0xec, - 0xfb, 0x97, 0xef, 0xde, 0x13, 0xb0, 0xad, 0xcc, 0x3f, 0xc7, 0x1d, 0x6f, 0x23, 0x4b, 0x5c, 0x02, - 0xe0, 0x79, 0x56, 0x30, 0x32, 0xb5, 0x85, 0x60, 0x53, 0x79, 0xe9, 0x00, 0x57, 0x7f, 0x44, 0xb2, - 0x42, 0x1e, 0x2d, 0xe4, 0x2e, 0xae, 0x0e, 0x43, 0x01, 0xcd, 0x4d, 0x03, 0x78, 0x17, 0x65, 0x6c, - 0xd7, 0x7c, 0xf5, 0xf2, 0xcd, 0x1f, 0x0b, 0xcd, 0xa2, 0x33, 0x0d, 0x97, 0x91, 0xf5, 0x56, 0xf5, - 0xc5, 0x64, 0xd5, 0xb8, 0x48, 0xc4, 0xfa, 0xbe, 0xe1, 0x87, 0x6a, 0x5a, 0x31, 0x47, 0x8c, 0xb2, - 0xf1, 0x41, 0x1a, 0x48, 0x44, 0xb8, 0x78, 0x7f, 0xde, 0x62, 0x9c, 0x25, 0x8c, 0x91, 0x03, 0xd5, - 0x79, 0x87, 0x73, 0x0c, 0x86, 0x0b, 0x9c, 0xa3, 0x23, 0x0b, 0x41, 0x50, 0x86, 0x16, 0xdd, 0x18, - 0x7a, 0x0c, 0xb8, 0x66, 0xf6, 0x77, 0xa8, 0x97, 0xd0, 0x2c, 0xa8, 0xbe, 0x6e, 0xba, 0x64, 0x28, - 0x7f, 0x8a, 0xf9, 0x65, 0x28, 0x7d, 0xab, 0x24, 0x4e, 0x71, 0x6a, 0x52, 0x32, 0xf1, 0xb3, 0x5a, - 0x06, 0x6a, 0xfc, 0xae, 0xe0, 0x8d, 0xa9, 0x74, 0xb9, 0x6c, 0xb6, 0xcc, 0xf8, 0xd1, 0xa2, 0xb5, - 0x70, 0xb7, 0x5d, 0x33, 0xe7, 0x96, 0x79, 0xd0, 0xe8, 0x39, 0x5d, 0xe2, 0x83, 0x32, 0xb4, 0x5d, - 0x96, 0xf5, 0x0f, 0x99, 0x5c, 0x04, 0x70, 0xb8, 0x76, 0x90, 0x4b, 0x5b, 0x4d, 0x90, 0x4b, 0xa9, - 0x7b, 0xb7, 0x44, 0x07, 0xfb, 0x13, 0x19, 0x13, 0xa3, 0xe8, 0xd7, 0x82, 0x7a, 0xfd, 0x82, 0xa9, - 0xe5, 0x9a, 0x11, 0x2e, 0xa9, 0xb8, 0x42, 0x60, 0xa7, 0xce, 0x6f, 0x56, 0x32, 0xba, 0xc1, 0x60, - 0xfd, 0xcc, 0x59, 0x72, 0xa7, 0xa8, 0x0b, 0x4c, 0x93, 0xa0, 0xcb, 0x84, 0x13, 0xe9, 0xc4, 0xd3, - 0xb0, 0xa7, 0xa0, 0xe3, 0x4b, 0x91, 0x73, 0x0c, 0x0d, 0x46, 0xe7, 0x6d, 0x81, 0x57, 0xe5, 0x65, - 0xc3, 0x86, 0x4f, 0x29, 0xde, 0x72, 0xe1, 0x42, 0x76, 0x37, 0x05, 0x48, 0x84, 0x1f, 0x75, 0x26, - 0x1f, 0x8e, 0xe5, 0xc3, 0x2b, 0xf9, 0xe0, 0xcb, 0x87, 0xa9, 0x7c, 0x18, 0xab, 0xad, 0x6a, 0xf2, - 0x21, 0x72, 0x6b, 0x1d, 0x27, 0xe3, 0x91, 0xbe, 0x2e, 0x5d, 0x7e, 0x2d, 0x28, 0x41, 0x60, 0x17, - 0xc2, 0x03, 0x0d, 0x21, 0xcd, 0x6f, 0x2d, 0x1a, 0x46, 0xa3, 0x81, 0xcb, 0x8d, 0x43, 0x7c, 0x06, - 0xfd, 0x44, 0x00, 0xc7, 0x3f, 0x62, 0x6c, 0x00, 0xbf, 0x35, 0xf3, 0x38, 0x7d, 0x28, 0x7f, 0x7c, - 0x2a, 0xed, 0x0a, 0x5c, 0x61, 0x81, 0xc9, 0xda, 0x87, 0x89, 0x2c, 0x75, 0x53, 0x68, 0x94, 0xad, - 0xf9, 0x3c, 0x6e, 0xfd, 0x8e, 0x0d, 0xae, 0x56, 0xdf, 0x0b, 0x5c, 0x60, 0x80, 0x13, 0x3c, 0x2a, - 0x1e, 0xf0, 0xf5, 0xd5, 0x09, 0x5d, 0x1c, 0x82, 0xca, 0x28, 0x8a, 0x30, 0x1e, 0x8c, 0x41, 0xbc, - 0x9f, 0x17, 0xd7, 0x65, 0x70, 0x52, 0x92, 0xfb, 0x96, 0xe8, 0xc0, 0x7a, 0x90, 0x30, 0xb5, 0x75, - 0x90, 0x07, 0x6e, 0xd7, 0xb7, 0xee, 0x99, 0x47, 0x4b, 0xc3, 0x2c, 0x4a, 0x4e, 0xd3, 0x35, 0x4e, - 0x4c, 0xbd, 0x1a, 0xf3, 0xd4, 0x58, 0x6b, 0xce, 0x1a, 0x7b, 0x58, 0x80, 0xe7, 0xbb, 0x12, 0x3c, - 0x24, 0x68, 0xfd, 0x16, 0x85, 0x68, 0x5b, 0xaf, 0x71, 0x5f, 0x84, 0xdf, 0xf2, 0x3d, 0xdd, 0x76, - 0xf6, 0xcc, 0x7f, 0x31, 0xed, 0xe5, 0xcf, 0x1e, 0x98, 0x48, 0xcc, 0xcb, 0xa7, 0xc2, 0xee, 0xe3, - 0x9f, 0xd5, 0x3a, 0x38, 0x1a, 0xfd, 0xfb, 0x7c, 0xb9, 0xec, 0xe8, 0xcf, 0x20, 0x23, 0x7f, 0xe7, - 0xcb, 0x57, 0x43, 0x78, 0x1b, 0xda, 0x7f, 0x7e, 0xec, 0x75, 0x87, 0xdf, 0x90, 0x1b, 0x40, 0xbb, - 0xb2, 0xd9, 0xfa, 0xb3, 0xed, 0xfc, 0x64, 0x99, 0x37, 0x24, 0x86, 0xf0, 0x0f, 0x4a, 0x6b, 0x96, - 0xf9, 0xa0, 0x81, 0xe3, 0x58, 0x88, 0xf6, 0xc9, 0x59, 0x76, 0x15, 0xdf, 0x06, 0x0c, 0x1d, 0xdc, - 0x7c, 0xad, 0x89, 0x7b, 0xfd, 0xb3, 0x5b, 0x54, 0x6f, 0x69, 0x34, 0xa7, 0x6c, 0xbc, 0x38, 0x3f, - 0x67, 0x34, 0x30, 0x17, 0x09, 0x2d, 0x43, 0x42, 0xeb, 0xc1, 0x0c, 0xf7, 0x72, 0xf0, 0x73, 0x1b, - 0x0c, 0xc3, 0x70, 0x97, 0x1d, 0x0f, 0xdf, 0x38, 0x9d, 0x81, 0xd3, 0x69, 0xef, 0xc2, 0xd0, 0xfd, - 0x5e, 0xe8, 0x30, 0x2e, 0x19, 0xe2, 0x1e, 0x6b, 0xc3, 0x4f, 0x2f, 0x4d, 0x3a, 0x4f, 0xce, 0x2f, - 0x4b, 0x61, 0xad, 0x97, 0xca, 0x8b, 0x81, 0x3e, 0x9b, 0x3c, 0x51, 0x56, 0x99, 0xe0, 0x35, 0x47, - 0x2a, 0xb5, 0xd7, 0x55, 0xa9, 0xbe, 0x48, 0xd5, 0xfc, 0x20, 0x09, 0x6e, 0x82, 0xcc, 0x53, 0xb5, - 0x2a, 0x62, 0x0f, 0x4c, 0xba, 0x7e, 0xae, 0x41, 0x84, 0x96, 0x0c, 0x22, 0x81, 0x77, 0xcb, 0xb6, - 0x1d, 0x34, 0x3b, 0x7c, 0xf8, 0x17, 0xc2, 0xbf, 0x29, 0xfc, 0xbb, 0x00, 0x8a, 0xbf, 0xf0, 0xe2, - 0x61, 0xec, 0xc5, 0x0d, 0x2c, 0xd9, 0x5e, 0xb5, 0x87, 0xd1, 0xc9, 0xde, 0xc1, 0xee, 0xa9, 0xd7, - 0x19, 0xa6, 0x27, 0x3d, 0x7c, 0x68, 0xd3, 0xc3, 0x00, 0x1f, 0x82, 0x93, 0xc1, 0xde, 0xa9, 0x17, - 0x9c, 0x74, 0x4f, 0x29, 0x97, 0x4c, 0xa3, 0x5f, 0x4c, 0xe8, 0x8b, 0x84, 0xfd, 0x53, 0xef, 0xa2, - 0xd1, 0x6d, 0xf7, 0xf7, 0xf1, 0xe5, 0x00, 0x5e, 0xe8, 0xeb, 0x1e, 0x7e, 0x05, 0x0d, 0x29, 0x38, - 0xe9, 0x9d, 0xae, 0xda, 0x76, 0xa3, 0xd9, 0x5d, 0x61, 0xee, 0xbd, 0xf6, 0xa9, 0xc7, 0x86, 0x99, - 0xc7, 0x1a, 0xf0, 0x65, 0xd0, 0x3f, 0x05, 0x82, 0xb0, 0xf9, 0x87, 0xce, 0x29, 0x10, 0x0d, 0x73, - 0xf9, 0xea, 0x70, 0x07, 0x6f, 0xbd, 0x61, 0x8d, 0xbc, 0x4c, 0x42, 0xee, 0x8d, 0xa3, 0xa3, 0xa3, - 0xf6, 0x91, 0x97, 0xe1, 0x0f, 0xde, 0x72, 0xdd, 0xd9, 0x17, 0xfb, 0x80, 0x32, 0x77, 0x1a, 0x2f, - 0x85, 0x7f, 0x21, 0x3d, 0x49, 0xc0, 0x86, 0xc6, 0x36, 0xb9, 0x8b, 0xe1, 0xc0, 0x95, 0x56, 0xac, - 0xb0, 0x8c, 0xc5, 0x6f, 0xd7, 0x95, 0x16, 0x30, 0xfd, 0xf6, 0xba, 0x2e, 0xb7, 0x83, 0x44, 0xee, - 0x8e, 0x8b, 0x1c, 0x0a, 0xff, 0xe3, 0xf8, 0x80, 0xea, 0x3c, 0xaf, 0x3d, 0x02, 0xf1, 0x07, 0xe0, - 0xba, 0x6d, 0x7b, 0x64, 0xdd, 0x58, 0xac, 0xd1, 0x5f, 0xb5, 0x39, 0x71, 0xd8, 0xfc, 0x3b, 0x7d, - 0x98, 0x81, 0xf8, 0xb7, 0x38, 0x5e, 0x79, 0xaa, 0xed, 0x12, 0xb4, 0x07, 0x1c, 0x58, 0x43, 0x58, - 0x57, 0x00, 0xfe, 0x9e, 0x00, 0x5f, 0x34, 0xb9, 0x4b, 0x4d, 0xf2, 0x26, 0xf2, 0xfa, 0xbb, 0xc5, - 0xfa, 0x97, 0x0b, 0x0c, 0xff, 0x0e, 0x65, 0xab, 0x6b, 0xd9, 0x3d, 0x70, 0x97, 0xe5, 0xb4, 0xfe, - 0x9e, 0xab, 0x70, 0x03, 0x75, 0x16, 0xb0, 0x03, 0xdf, 0x96, 0xbf, 0x40, 0x8d, 0x1c, 0xb4, 0x4c, - 0x14, 0xe8, 0xba, 0xcb, 0x87, 0x30, 0x06, 0x2a, 0x55, 0x5a, 0xf8, 0x58, 0xf5, 0x40, 0x75, 0x63, - 0x5b, 0xb2, 0x58, 0xe1, 0xe7, 0xd7, 0x7c, 0x5b, 0x21, 0x81, 0xde, 0xd9, 0x43, 0x14, 0xe4, 0x44, - 0x05, 0x63, 0xba, 0x66, 0xfc, 0x17, 0xc6, 0x38, 0xf3, 0x88, 0x00, 0x56, 0xed, 0x75, 0x5e, 0xe2, - 0x00, 0x03, 0x05, 0xcb, 0x0c, 0xbc, 0x18, 0xc3, 0x8e, 0x1f, 0xa8, 0xed, 0x7e, 0xb2, 0xea, 0x81, - 0xbd, 0x14, 0x64, 0x9c, 0x53, 0x58, 0x65, 0xc6, 0x7d, 0x9b, 0x6c, 0x62, 0x4e, 0xbc, 0x90, 0x84, - 0x2d, 0x24, 0x5a, 0x56, 0x9c, 0x12, 0x80, 0x90, 0xb4, 0x12, 0x08, 0x44, 0x4e, 0x92, 0x59, 0x81, - 0x24, 0xb3, 0xa1, 0xef, 0x65, 0x1a, 0x59, 0x5a, 0xa2, 0x0f, 0xb6, 0x24, 0xcf, 0xfd, 0x6e, 0x25, - 0x79, 0x66, 0xff, 0x4c, 0xf2, 0x2c, 0x51, 0x67, 0x76, 0x0f, 0x75, 0x2e, 0x67, 0x44, 0x3d, 0xfb, - 0x1d, 0x49, 0x3d, 0xfb, 0x9d, 0x6a, 0x1a, 0xcc, 0x3e, 0x83, 0x06, 0xb7, 0xd5, 0x72, 0x70, 0xc0, - 0x81, 0x2b, 0xd7, 0xd2, 0x1b, 0x38, 0xfb, 0x1a, 0xa3, 0x7c, 0x43, 0xe4, 0xd8, 0xe9, 0x0a, 0x74, - 0x10, 0xe0, 0x4b, 0x21, 0x3a, 0x3a, 0x77, 0x54, 0xdf, 0x6f, 0xbb, 0x4b, 0xdf, 0x23, 0xc1, 0x43, - 0xa4, 0x23, 0x51, 0x00, 0x45, 0xb2, 0x3a, 0x79, 0xe0, 0x60, 0x80, 0xfc, 0x86, 0x15, 0x1e, 0x1e, - 0xf6, 0x60, 0x2c, 0xba, 0x58, 0x5b, 0xe2, 0x11, 0x05, 0xad, 0x94, 0x78, 0xcb, 0x1a, 0x1d, 0x10, - 0x3d, 0x03, 0x68, 0x7b, 0xa0, 0xe5, 0x46, 0xe6, 0xe8, 0x9e, 0x12, 0x4d, 0x94, 0xda, 0x04, 0x7c, - 0x6b, 0x2d, 0x11, 0x19, 0x65, 0xb2, 0x02, 0x5c, 0x86, 0xf7, 0x7a, 0x39, 0x03, 0x80, 0x11, 0xd7, - 0x68, 0xe6, 0xd5, 0xcb, 0x16, 0x01, 0x08, 0x2e, 0x64, 0x79, 0x05, 0x89, 0xcc, 0x50, 0x83, 0x91, - 0xb3, 0xa6, 0x00, 0xa0, 0x45, 0xf2, 0x13, 0x85, 0xa5, 0x65, 0x25, 0xbc, 0x27, 0x36, 0x55, 0xd4, - 0xa5, 0x6e, 0x00, 0x06, 0x21, 0xc7, 0x14, 0x44, 0x2d, 0x7f, 0xb3, 0x51, 0xd5, 0xa6, 0x42, 0xfb, - 0xa2, 0x90, 0xe8, 0xbe, 0x9d, 0x77, 0x05, 0x89, 0x1c, 0xd1, 0x9a, 0x79, 0x53, 0x1c, 0x02, 0x0e, - 0x78, 0x80, 0x24, 0xc8, 0xbf, 0x89, 0x47, 0x0f, 0x74, 0x30, 0xa8, 0x19, 0xc7, 0x02, 0x5e, 0x60, - 0xb4, 0xe4, 0x74, 0x90, 0xe8, 0x1d, 0xb9, 0x83, 0x6e, 0xba, 0x3d, 0x14, 0x02, 0x12, 0xc7, 0x34, - 0x3a, 0x38, 0xa8, 0x43, 0x0c, 0xf5, 0x2d, 0x38, 0x2a, 0x3d, 0x09, 0xc5, 0x48, 0x7b, 0x5e, 0xbf, - 0x03, 0xba, 0x04, 0x3c, 0x51, 0xd7, 0x11, 0xfd, 0xfd, 0xbc, 0x4b, 0xc8, 0x79, 0x1c, 0x64, 0xa8, - 0xa4, 0x2b, 0x98, 0x9f, 0x26, 0x07, 0xba, 0xdf, 0x06, 0x14, 0xa7, 0x93, 0x5d, 0x9a, 0x5c, 0x44, - 0x08, 0x71, 0x72, 0x75, 0x9d, 0x64, 0x8d, 0xee, 0x3e, 0x01, 0xaf, 0xb6, 0x86, 0xe6, 0x52, 0x28, - 0x27, 0x96, 0x44, 0x27, 0x96, 0xa4, 0x9a, 0x58, 0x2c, 0x4e, 0x82, 0x82, 0xa5, 0xba, 0xae, 0x1a, - 0xc0, 0xe4, 0x2e, 0x92, 0x61, 0xf9, 0xa4, 0xb7, 0x89, 0x1c, 0x60, 0x2a, 0x56, 0x22, 0x1e, 0x56, - 0x20, 0x9e, 0x7e, 0x3e, 0x37, 0xe4, 0xc0, 0x86, 0x30, 0x10, 0x9b, 0x64, 0x44, 0x41, 0x92, 0x08, - 0x67, 0x20, 0xa4, 0xb4, 0xf1, 0x56, 0x08, 0xec, 0xdb, 0xcb, 0xf9, 0x9d, 0xec, 0xd9, 0x03, 0xf6, - 0xbc, 0xb4, 0x7a, 0x07, 0xf6, 0x06, 0xa4, 0xbd, 0x3e, 0x7d, 0xe9, 0x6f, 0x7e, 0xf9, 0x27, 0x4e, - 0x21, 0x4c, 0x23, 0x13, 0xa8, 0x8c, 0x57, 0x35, 0x4c, 0x5c, 0x4e, 0x26, 0x35, 0xeb, 0x85, 0xe5, - 0xdb, 0x24, 0x9b, 0x45, 0x83, 0xbe, 0xc2, 0xd4, 0x52, 0xb2, 0x22, 0xe4, 0x7b, 0x57, 0x24, 0xfd, - 0x09, 0x21, 0xa7, 0x40, 0xf7, 0x2b, 0x92, 0xc1, 0x03, 0x89, 0xd9, 0x44, 0x04, 0x06, 0xf5, 0x06, - 0x03, 0x95, 0xa2, 0x86, 0x87, 0x8b, 0x56, 0x6d, 0x3a, 0xd3, 0x32, 0xad, 0x33, 0x8d, 0x7c, 0x26, - 0x85, 0x41, 0xbc, 0x42, 0x56, 0x6a, 0x20, 0x27, 0x17, 0xdb, 0x1d, 0x69, 0xe9, 0x22, 0xb5, 0xe6, - 0x0d, 0x80, 0xa8, 0xa9, 0x62, 0x31, 0x28, 0x03, 0x31, 0xe9, 0x6c, 0xeb, 0xe6, 0xc0, 0x15, 0x02, - 0x1e, 0xa8, 0x40, 0xca, 0xc8, 0x46, 0xb3, 0xbf, 0x2f, 0xc7, 0xbc, 0xc3, 0xfb, 0x37, 0xd8, 0xe8, - 0xdf, 0x41, 0xb1, 0x7f, 0xfd, 0x9e, 0xcb, 0xd9, 0x4f, 0xab, 0x07, 0xa8, 0xa4, 0xf7, 0x99, 0xa5, - 0x77, 0x2b, 0x4b, 0xef, 0xde, 0x5b, 0x5a, 0x47, 0x66, 0x9e, 0xaa, 0x71, 0xa5, 0x1c, 0x71, 0x31, - 0xd5, 0x0e, 0x06, 0x42, 0x41, 0x40, 0xc4, 0x8e, 0x71, 0x77, 0xff, 0x1d, 0x34, 0xd0, 0x76, 0xab, - 0x40, 0xdd, 0xa3, 0x69, 0x87, 0xeb, 0xaa, 0x1b, 0xa3, 0xcf, 0x89, 0x59, 0x41, 0xb5, 0x5e, 0xe3, - 0x94, 0xd0, 0xe3, 0x33, 0x88, 0x2f, 0x64, 0x14, 0x4d, 0xe4, 0x87, 0x5e, 0x42, 0x13, 0xb8, 0xf4, - 0x95, 0x33, 0xa9, 0xba, 0x72, 0x0d, 0x24, 0xcb, 0x89, 0x56, 0xf4, 0xa5, 0x66, 0xbd, 0xa6, 0x89, - 0x8e, 0xdf, 0x85, 0xf7, 0x9e, 0x3f, 0x2f, 0x3f, 0xbb, 0x46, 0x51, 0xcb, 0x7b, 0x4b, 0xd5, 0x8b, - 0xe5, 0xb1, 0xaa, 0x5f, 0x39, 0x16, 0x96, 0xe7, 0xc0, 0x5c, 0x4a, 0x03, 0xcf, 0x39, 0xd3, 0xc8, - 0xa4, 0xd6, 0xd2, 0x29, 0x3d, 0x10, 0x71, 0x55, 0x69, 0x61, 0x83, 0x03, 0x5e, 0x1b, 0x28, 0x3a, - 0x6b, 0x51, 0x23, 0x2b, 0xd6, 0x28, 0x66, 0xf0, 0x81, 0x3e, 0xc5, 0xde, 0x23, 0x35, 0x85, 0x04, - 0xa4, 0xee, 0xdc, 0x2d, 0x2b, 0x29, 0x5f, 0x6f, 0x28, 0xc5, 0xd3, 0xb0, 0x38, 0x26, 0x24, 0xb1, - 0xaa, 0xa0, 0xde, 0xef, 0xdc, 0xa1, 0x3b, 0x6a, 0x1a, 0x63, 0x0f, 0xc8, 0xe3, 0x77, 0xde, 0x3b, - 0x6d, 0x72, 0xd0, 0x14, 0xc0, 0xfe, 0xc1, 0x3d, 0x19, 0xf6, 0xbb, 0xa8, 0x12, 0xe6, 0x0a, 0x22, - 0xce, 0x00, 0x96, 0x98, 0xb4, 0x79, 0xcf, 0x6c, 0xd9, 0x2d, 0x52, 0x62, 0x36, 0xe7, 0x9a, 0x18, - 0xcc, 0x1f, 0xb9, 0x4b, 0x16, 0x80, 0xcb, 0x3d, 0xd7, 0x5b, 0x6c, 0xb3, 0x09, 0xfc, 0x8b, 0x85, - 0x8d, 0x36, 0x83, 0x7f, 0x0b, 0xf8, 0x37, 0x86, 0x7f, 0x73, 0xf8, 0x77, 0x0d, 0xff, 0x6e, 0xe1, - 0xdf, 0x39, 0x7a, 0x2a, 0x94, 0x2a, 0xbc, 0x40, 0x4c, 0x13, 0xe1, 0x9e, 0x7b, 0x33, 0x98, 0xb2, - 0x95, 0x3e, 0x7a, 0x0e, 0x03, 0x75, 0x61, 0x91, 0x39, 0xa5, 0x29, 0xce, 0xc8, 0x4e, 0x16, 0xe3, - 0x53, 0xeb, 0x39, 0xca, 0xa6, 0x9a, 0xf5, 0x84, 0x2c, 0x0c, 0x9c, 0x64, 0xed, 0x5b, 0x18, 0x0e, - 0x26, 0x19, 0xf1, 0x96, 0x63, 0x11, 0xa6, 0x5e, 0x4d, 0x5f, 0x4d, 0x4a, 0xac, 0x47, 0x53, 0xbd, - 0xd0, 0xb2, 0x1b, 0x5d, 0x68, 0x49, 0x34, 0x99, 0xa8, 0x26, 0x95, 0xba, 0x0c, 0x75, 0xfe, 0x49, - 0x90, 0xf0, 0x25, 0x46, 0xa3, 0x23, 0x6b, 0x90, 0xf2, 0xd8, 0x9a, 0x1a, 0xcd, 0xcd, 0xa1, 0xe5, - 0x4b, 0xca, 0x99, 0x43, 0xbe, 0x56, 0x5d, 0xf9, 0x84, 0x9b, 0x71, 0x6d, 0xde, 0x17, 0x96, 0xa3, - 0xbf, 0xdf, 0xb7, 0x05, 0x1c, 0x5a, 0xad, 0x0a, 0x1e, 0x90, 0xda, 0x89, 0x06, 0x53, 0xb1, 0x28, - 0x88, 0x7c, 0x7b, 0x79, 0xeb, 0x75, 0x76, 0xc5, 0xf8, 0x61, 0xe7, 0x13, 0x8e, 0xa2, 0x8c, 0xc4, - 0x0e, 0x7c, 0xeb, 0xe6, 0xdf, 0x88, 0x7b, 0x8f, 0x4a, 0xea, 0x3d, 0x64, 0xe9, 0xcb, 0xe1, 0xcf, - 0x91, 0xd7, 0xe9, 0x72, 0x0a, 0x2b, 0x58, 0x7a, 0xda, 0xe7, 0xfe, 0xdd, 0x9f, 0x77, 0x65, 0x97, - 0x92, 0x46, 0x57, 0xb1, 0xa4, 0x3e, 0x0d, 0x77, 0x75, 0xdc, 0x0b, 0x0c, 0x9d, 0xab, 0x5e, 0x7e, - 0xb2, 0xce, 0x9d, 0x73, 0x4c, 0x2a, 0x09, 0x3b, 0x65, 0x1d, 0x6d, 0x1b, 0xd3, 0x36, 0x08, 0xd4, - 0x19, 0xd4, 0xd9, 0xe9, 0xab, 0x61, 0x99, 0xc9, 0xcc, 0x16, 0x6f, 0xc6, 0x2e, 0x95, 0x39, 0xd8, - 0x73, 0x49, 0x45, 0x53, 0xf8, 0x05, 0x35, 0x3f, 0xc3, 0x61, 0x75, 0x76, 0x73, 0x35, 0x7f, 0x64, - 0x4d, 0x50, 0xd3, 0x6e, 0x43, 0x2a, 0xca, 0xb7, 0x49, 0x2e, 0xdf, 0x50, 0xc3, 0xe3, 0x0d, 0x4d, - 0xa0, 0x1f, 0x98, 0x34, 0xbc, 0xf5, 0xba, 0xdd, 0x75, 0xc1, 0x18, 0x81, 0xde, 0x62, 0x62, 0xd9, - 0xb6, 0x28, 0x36, 0xab, 0xda, 0xed, 0xe9, 0xed, 0xfa, 0xb2, 0xdd, 0x73, 0x10, 0x5e, 0x3e, 0x6f, - 0xd7, 0xf9, 0xc6, 0x42, 0xec, 0xac, 0xce, 0x75, 0x4a, 0xe8, 0xd9, 0x2e, 0x9f, 0xb0, 0x11, 0x16, - 0x1f, 0x78, 0x91, 0x77, 0xd7, 0x89, 0x73, 0xf5, 0x5c, 0x64, 0x5a, 0x5e, 0x7b, 0x31, 0x00, 0xd9, - 0xeb, 0x54, 0xcc, 0x25, 0x45, 0x16, 0xea, 0x76, 0x31, 0xba, 0xa1, 0x00, 0xd2, 0x01, 0x00, 0x43, - 0x02, 0x70, 0xd0, 0x77, 0x80, 0x00, 0x34, 0x9f, 0x40, 0xe2, 0x85, 0x8d, 0xce, 0x40, 0x18, 0x31, - 0xc2, 0x6b, 0xc1, 0x39, 0xf6, 0x1b, 0x31, 0xa3, 0x88, 0x31, 0xc8, 0xca, 0xca, 0x81, 0xb0, 0x16, - 0xfb, 0xdd, 0x92, 0xea, 0x22, 0x67, 0x3b, 0xe9, 0x34, 0xc9, 0x24, 0x7b, 0xe2, 0x0e, 0x7e, 0x8d, - 0x77, 0xba, 0x55, 0xbc, 0x23, 0x33, 0xaf, 0xf5, 0xcc, 0x35, 0xaf, 0x4f, 0x5d, 0xcf, 0x78, 0xd7, - 0x4b, 0x02, 0x5a, 0x88, 0x8c, 0xce, 0xc8, 0x1a, 0xab, 0xfe, 0xbe, 0xb4, 0xae, 0x11, 0x81, 0x73, - 0x95, 0x30, 0x27, 0xfe, 0x19, 0x13, 0xdf, 0x60, 0xb7, 0x9f, 0x59, 0xcc, 0x99, 0x39, 0x63, 0x67, - 0x6e, 0x0f, 0xcb, 0x40, 0x34, 0xbb, 0x8a, 0x37, 0x78, 0xae, 0xb6, 0xd3, 0x96, 0xb9, 0xd0, 0x56, - 0x54, 0x5f, 0x15, 0x0d, 0xaa, 0x6f, 0x6d, 0x49, 0x47, 0xb9, 0xf0, 0x03, 0x88, 0x77, 0x87, 0x9b, - 0x14, 0x55, 0x4c, 0x94, 0xd6, 0x2a, 0x5a, 0xa9, 0x1b, 0x64, 0x94, 0x51, 0xcd, 0x90, 0xfa, 0x5a, - 0x33, 0xdc, 0x0b, 0xe4, 0x9b, 0x01, 0xff, 0x09, 0x1c, 0xdf, 0xaa, 0x86, 0x5f, 0x12, 0xa1, 0x69, - 0x9c, 0xf9, 0xcc, 0xba, 0x75, 0xce, 0x1d, 0xf8, 0x77, 0x67, 0x97, 0x51, 0x35, 0xe8, 0x6b, 0x6e, - 0xb2, 0x02, 0xe8, 0xfb, 0xae, 0xda, 0xd9, 0x51, 0x35, 0xe6, 0x4c, 0x93, 0x42, 0x3d, 0x25, 0x47, - 0x00, 0xfa, 0x41, 0x2e, 0xa3, 0x4b, 0x02, 0xb4, 0x7b, 0xa7, 0x00, 0xd5, 0x7b, 0xc3, 0xfe, 0x19, - 0xbd, 0x51, 0x52, 0x28, 0xc9, 0x3d, 0x2a, 0xb9, 0x30, 0x3b, 0xdf, 0x9c, 0xbb, 0xa4, 0x00, 0xe2, - 0xd8, 0xdc, 0x10, 0x40, 0xca, 0x53, 0xd2, 0x93, 0x64, 0x3f, 0xd4, 0x58, 0xb2, 0x28, 0x24, 0x32, - 0x2e, 0xdd, 0x71, 0x1e, 0xb4, 0x05, 0x7c, 0xc3, 0x67, 0xe4, 0xc3, 0x95, 0x87, 0x49, 0xca, 0x62, - 0xae, 0x86, 0x13, 0x8c, 0xd4, 0xd8, 0x94, 0xae, 0xb1, 0xbd, 0xb7, 0x1a, 0x63, 0x9c, 0x7b, 0xe5, - 0xca, 0x3c, 0xf4, 0xd4, 0x16, 0x67, 0xe5, 0xf3, 0x91, 0xa2, 0xb8, 0x5d, 0x10, 0x0d, 0x9a, 0x73, - 0x45, 0xe2, 0x64, 0x7f, 0x38, 0xb5, 0x66, 0x8e, 0xa8, 0x09, 0x27, 0xcf, 0x85, 0xb4, 0x49, 0x7b, - 0x5d, 0x77, 0xc1, 0x05, 0x87, 0x42, 0x24, 0xd6, 0xcd, 0xb8, 0xad, 0x21, 0x82, 0x07, 0xc9, 0x6e, - 0x06, 0xc2, 0xc9, 0xd2, 0xe5, 0xee, 0x31, 0xa8, 0x57, 0x3c, 0x33, 0xa2, 0x0e, 0xe8, 0xd5, 0x5a, - 0xb6, 0xd8, 0xec, 0xea, 0xfa, 0x39, 0xbf, 0xca, 0x2d, 0x5f, 0x48, 0xbf, 0x5b, 0x83, 0x19, 0x4e, - 0x54, 0xef, 0x98, 0x37, 0xd1, 0xf5, 0x12, 0xc6, 0x35, 0x8c, 0xbb, 0xa7, 0x13, 0x74, 0xea, 0xe4, - 0x86, 0x56, 0x9c, 0x6b, 0x9c, 0x89, 0x17, 0x2b, 0x8d, 0x53, 0xb7, 0xa9, 0xbc, 0x5d, 0x9d, 0x52, - 0xb8, 0xd6, 0x19, 0x17, 0xb4, 0xce, 0xa2, 0x65, 0xe6, 0xf1, 0x55, 0x9a, 0xf4, 0x84, 0xb4, 0x48, - 0xc1, 0xc9, 0x30, 0xc8, 0x03, 0x9d, 0x08, 0xa5, 0xf4, 0x1f, 0x5e, 0x5b, 0x13, 0x47, 0x8a, 0xaf, - 0x36, 0x68, 0x1f, 0xe4, 0xa1, 0xe4, 0x2e, 0x0d, 0x72, 0x25, 0xa1, 0x9b, 0x06, 0x7a, 0xac, 0xfc, - 0x39, 0xc2, 0x5d, 0x32, 0x29, 0x00, 0x90, 0x80, 0x89, 0x3e, 0x51, 0x26, 0x3a, 0x77, 0xe2, 0x80, - 0xbc, 0x10, 0x88, 0x88, 0x4b, 0x18, 0xc8, 0xcd, 0xf2, 0x4a, 0x8b, 0xbc, 0x34, 0xe7, 0xdc, 0x45, - 0x89, 0x5b, 0xf4, 0xac, 0x7b, 0x26, 0xf4, 0x7e, 0xdf, 0xad, 0x10, 0x07, 0x02, 0x1f, 0x13, 0xd5, - 0xfd, 0xe0, 0x64, 0xa2, 0x10, 0x1a, 0x6b, 0xfe, 0x59, 0xe8, 0xfa, 0x80, 0x92, 0x63, 0x60, 0xf4, - 0x49, 0xa3, 0x0b, 0x79, 0xda, 0xe8, 0x79, 0xe3, 0x55, 0xc6, 0x3a, 0x80, 0xca, 0xa3, 0x26, 0x86, - 0x2d, 0x77, 0x62, 0xea, 0xfe, 0x8e, 0x58, 0x6b, 0x32, 0xce, 0xc7, 0x10, 0x63, 0x71, 0x70, 0x6a, - 0xd6, 0xc1, 0x8c, 0x30, 0x30, 0x87, 0x6c, 0x52, 0x0c, 0x86, 0x54, 0xdc, 0x8b, 0xd5, 0x4a, 0x20, - 0x3e, 0x0b, 0x93, 0x05, 0xdd, 0x6b, 0x50, 0x85, 0x9f, 0x0a, 0xc9, 0x81, 0xcc, 0x7e, 0x80, 0x53, - 0x87, 0xa6, 0x00, 0x70, 0x0d, 0xa5, 0xdf, 0x57, 0x8c, 0x4e, 0x33, 0x48, 0xee, 0x0a, 0xe1, 0xa7, - 0x7b, 0xb8, 0xb2, 0x3c, 0xd2, 0x2c, 0x41, 0x90, 0xd2, 0xe8, 0x37, 0x90, 0xbc, 0x8c, 0x64, 0x39, - 0x71, 0xb2, 0xc6, 0x3e, 0xfa, 0x64, 0xed, 0x92, 0x66, 0x28, 0xa9, 0x48, 0x11, 0x8e, 0x9f, 0x2f, - 0x90, 0xe4, 0xaa, 0x7b, 0x41, 0x08, 0x29, 0xc4, 0x2f, 0x73, 0x11, 0xa0, 0x7a, 0xaf, 0xeb, 0xf1, - 0x95, 0x2e, 0x6e, 0x29, 0x1d, 0xf3, 0xd9, 0xa5, 0x26, 0x15, 0x7e, 0x5e, 0xa8, 0xa4, 0x71, 0xfb, - 0x5e, 0xaf, 0xa7, 0x1f, 0xdc, 0x36, 0xee, 0xb4, 0x0a, 0x10, 0xb3, 0x3e, 0x9f, 0xce, 0x7a, 0xf6, - 0x26, 0xe2, 0xe3, 0xcf, 0x11, 0xb2, 0xf1, 0xa8, 0x24, 0x63, 0x11, 0xeb, 0xba, 0x02, 0x9e, 0xcb, - 0x5a, 0xbd, 0x1b, 0xd2, 0x6a, 0x99, 0x02, 0xba, 0x59, 0x51, 0x5b, 0x2f, 0x94, 0x5e, 0x6b, 0x3b, - 0x1f, 0x15, 0x6c, 0x72, 0x9a, 0x11, 0xda, 0xad, 0xda, 0xa6, 0x87, 0xa3, 0xa1, 0x89, 0x57, 0xa1, - 0x30, 0xfa, 0x72, 0x65, 0x62, 0x59, 0x31, 0x1c, 0x9b, 0x44, 0xc9, 0xed, 0xde, 0x8e, 0x5a, 0x33, - 0xd9, 0x30, 0xb8, 0x32, 0x3e, 0x50, 0x8c, 0x1b, 0x29, 0x78, 0x95, 0xa8, 0x28, 0x88, 0x46, 0x7c, - 0x96, 0xab, 0x98, 0x7f, 0xe2, 0x36, 0x20, 0xe6, 0x90, 0x63, 0x12, 0x7b, 0x99, 0x36, 0x00, 0x31, - 0x34, 0x10, 0x6b, 0x83, 0x00, 0x3a, 0x30, 0xe1, 0x23, 0xb1, 0xcb, 0xa6, 0xb3, 0xf8, 0xbe, 0xab, - 0x61, 0x76, 0x7d, 0xc7, 0x3c, 0x32, 0xe5, 0xfb, 0xb1, 0x60, 0xf6, 0xa1, 0x4e, 0xc0, 0xcc, 0x4c, - 0x4b, 0xa7, 0x72, 0x8f, 0x64, 0x52, 0x22, 0x87, 0x2d, 0x1a, 0x70, 0x2e, 0x2d, 0x23, 0x6f, 0xb7, - 0x5a, 0x62, 0xe6, 0x1f, 0xe4, 0x30, 0x01, 0x7c, 0x6b, 0x81, 0xf7, 0x88, 0x80, 0x06, 0x98, 0xf1, - 0x62, 0xef, 0x44, 0xc9, 0xfa, 0xce, 0xa6, 0x46, 0xc3, 0xf5, 0x62, 0xa1, 0x59, 0x6a, 0x3a, 0xf4, - 0xc1, 0x9e, 0xb8, 0x79, 0xb6, 0x60, 0x65, 0xde, 0x58, 0x09, 0xd1, 0xdb, 0xde, 0xbe, 0x58, 0x31, - 0x89, 0xbc, 0x0e, 0xf7, 0xca, 0x14, 0xf3, 0x81, 0x51, 0xae, 0x2b, 0xe4, 0x9d, 0xce, 0x01, 0xb2, - 0x3d, 0x94, 0x55, 0x8c, 0x8f, 0x6b, 0x31, 0x5c, 0x18, 0x24, 0xca, 0xe1, 0x8a, 0x19, 0x07, 0x2a, - 0x75, 0xa0, 0xe5, 0xed, 0xa3, 0x35, 0x4f, 0x6d, 0xe5, 0xbd, 0xeb, 0x74, 0x72, 0x73, 0x52, 0x11, - 0x90, 0x4c, 0xb0, 0x2c, 0x36, 0x1a, 0xb8, 0x7d, 0xe4, 0x9e, 0x2d, 0xfa, 0x0f, 0x9a, 0x3d, 0xb2, - 0xbc, 0x4e, 0x7d, 0x62, 0xc5, 0x8e, 0xe9, 0x8b, 0xb5, 0x42, 0x17, 0xd6, 0x8c, 0x88, 0xfb, 0x07, - 0x6e, 0xbb, 0x01, 0x52, 0x3d, 0x9e, 0xf7, 0xe6, 0x97, 0xc3, 0x9c, 0x79, 0x2f, 0xc9, 0x7c, 0x2a, - 0xd9, 0x31, 0xbb, 0xc0, 0x64, 0x91, 0xd7, 0x6d, 0x17, 0x10, 0xa1, 0x57, 0x77, 0xf7, 0xfc, 0xf8, - 0x65, 0xf3, 0x33, 0x34, 0xd4, 0xcf, 0xe5, 0xc4, 0x97, 0xb6, 0x45, 0x4b, 0x06, 0x50, 0xc5, 0x41, - 0x69, 0xce, 0xec, 0x97, 0x3d, 0xd5, 0x90, 0x67, 0xff, 0xae, 0x66, 0xaa, 0xa7, 0x27, 0xe4, 0xd5, - 0xbc, 0xf6, 0x5c, 0x55, 0xd6, 0x68, 0xa7, 0xdb, 0xde, 0x18, 0x7b, 0xc9, 0xef, 0x22, 0x43, 0xff, - 0xbe, 0x0c, 0xfb, 0xf7, 0x65, 0x38, 0x40, 0x28, 0xf2, 0x49, 0x3e, 0x92, 0x1a, 0x04, 0xe3, 0x2f, - 0x9b, 0xb3, 0xfc, 0xbd, 0xb2, 0x65, 0x4c, 0x31, 0x6f, 0x49, 0xb2, 0xb0, 0xc2, 0x9a, 0x2b, 0x2b, - 0xac, 0x58, 0xa0, 0xbf, 0x43, 0x5b, 0xce, 0x50, 0x8e, 0xed, 0x65, 0xbe, 0x08, 0xca, 0xbc, 0x57, - 0x30, 0x73, 0x34, 0x71, 0xd9, 0x72, 0x7f, 0x1f, 0xe6, 0x5a, 0x49, 0x64, 0x72, 0x28, 0xd0, 0x1e, - 0xd3, 0x33, 0x1d, 0x74, 0x9d, 0x9e, 0x9e, 0x49, 0x5b, 0xee, 0xc8, 0x13, 0xd7, 0x6a, 0xf1, 0xf6, - 0x8e, 0xd6, 0x3b, 0xbb, 0x85, 0xaf, 0xfd, 0x12, 0x6c, 0xd4, 0xec, 0x07, 0x6c, 0x76, 0x80, 0xf2, - 0xaa, 0xdd, 0xd9, 0x00, 0x0d, 0xad, 0x62, 0x2d, 0xcb, 0xc1, 0xc1, 0xe7, 0xc2, 0x05, 0xa2, 0xa5, - 0xd0, 0xa5, 0x7d, 0xa7, 0xbf, 0xd9, 0xef, 0xce, 0x5e, 0x21, 0x53, 0xa7, 0x3d, 0xa0, 0x89, 0xf5, - 0xf3, 0x3a, 0xde, 0x75, 0x97, 0x15, 0xab, 0x09, 0x9d, 0x4e, 0x67, 0x54, 0xec, 0x2c, 0x4a, 0xb4, - 0x0e, 0x48, 0x34, 0x1d, 0x11, 0x83, 0xe2, 0xb2, 0xf9, 0x81, 0x02, 0x03, 0x95, 0x21, 0xb0, 0x8a, - 0x8b, 0x60, 0x08, 0x60, 0xbb, 0xc5, 0x5c, 0xbd, 0x76, 0x71, 0x28, 0xab, 0x81, 0x55, 0x7b, 0x01, - 0x0a, 0xf6, 0x77, 0xde, 0xef, 0x2e, 0x55, 0xd5, 0xd7, 0xb0, 0xb3, 0x56, 0x87, 0x59, 0x96, 0xb9, - 0x7b, 0x7f, 0x66, 0x61, 0x20, 0x18, 0xdc, 0x38, 0x04, 0x50, 0x33, 0xd0, 0x4b, 0x45, 0xbd, 0x18, - 0xf6, 0xa8, 0xd3, 0xef, 0x3a, 0xbb, 0x1b, 0xc5, 0x3b, 0x6a, 0xe0, 0xa8, 0x89, 0x76, 0x7b, 0x23, - 0x47, 0xbf, 0x08, 0xc4, 0x6e, 0xd7, 0xd9, 0xdb, 0xc8, 0x33, 0x28, 0xe6, 0x19, 0x0c, 0x2a, 0x00, - 0x3d, 0xb8, 0x93, 0xfe, 0x73, 0x38, 0x68, 0x88, 0x3b, 0xed, 0x0a, 0xcc, 0x76, 0x8a, 0x64, 0xb0, - 0xd7, 0xff, 0x1c, 0xfa, 0x97, 0xa9, 0xb8, 0xfe, 0x50, 0xe6, 0xe2, 0xa2, 0xbf, 0x7c, 0x5e, 0x61, - 0x6d, 0xa2, 0x7a, 0xa0, 0x76, 0x8a, 0x68, 0xce, 0x5d, 0x6d, 0x1e, 0x62, 0x5e, 0xd2, 0x10, 0xc8, - 0x4f, 0x0a, 0x9b, 0x85, 0x32, 0xa0, 0x28, 0x81, 0x82, 0x2d, 0x42, 0x01, 0xd7, 0x3c, 0x32, 0x6f, - 0xaf, 0xd8, 0xcf, 0xde, 0x40, 0x52, 0x6c, 0x61, 0x12, 0xc6, 0x99, 0x31, 0xf3, 0x72, 0x63, 0x42, - 0x77, 0x27, 0x11, 0xc9, 0x25, 0xe4, 0xf9, 0xa8, 0x58, 0x73, 0xe2, 0x7a, 0x2d, 0x77, 0x47, 0x0c, - 0x6c, 0x95, 0x33, 0xdf, 0x18, 0x25, 0x4d, 0xe0, 0x48, 0x37, 0x81, 0xa3, 0x6a, 0x13, 0xb8, 0x2f, - 0x0d, 0xdf, 0xe8, 0x4e, 0xc3, 0x37, 0x17, 0xbc, 0xbc, 0xdd, 0x3d, 0xa5, 0xee, 0x73, 0x63, 0x56, - 0xb4, 0x57, 0x6d, 0x86, 0xc9, 0x16, 0xc4, 0xb2, 0x33, 0x2a, 0x0e, 0xd1, 0xe6, 0xb2, 0x73, 0xcd, - 0xeb, 0xd9, 0xbf, 0x6b, 0x77, 0xa5, 0x8a, 0x96, 0x3a, 0xb9, 0x65, 0x31, 0xfc, 0x5d, 0x45, 0x7c, - 0xd6, 0x42, 0x68, 0xe7, 0xf2, 0x9a, 0xae, 0x24, 0xd2, 0x06, 0x5a, 0x1f, 0x5e, 0x90, 0xe4, 0xba, - 0x87, 0x34, 0x13, 0xde, 0x56, 0xdd, 0x47, 0xb9, 0xc7, 0x03, 0x47, 0xc1, 0x1f, 0xe1, 0x3a, 0x15, - 0xc6, 0x09, 0xc2, 0x23, 0xad, 0x27, 0x09, 0xdc, 0xfb, 0xbb, 0x73, 0xe4, 0xfb, 0xc8, 0x1a, 0xdd, - 0xcf, 0x5d, 0xe8, 0x66, 0x15, 0x0b, 0xdd, 0x19, 0x40, 0x55, 0xe5, 0x1e, 0x8a, 0x54, 0xcf, 0x60, - 0x60, 0xf5, 0x2d, 0x6e, 0x22, 0x4b, 0x44, 0x6b, 0x86, 0x45, 0x53, 0x4b, 0x5d, 0x69, 0xa4, 0xf3, - 0xc8, 0xe5, 0x56, 0xec, 0x51, 0x20, 0x5c, 0xff, 0x2e, 0x53, 0x21, 0x92, 0xca, 0xbe, 0x32, 0x19, - 0x7c, 0xc9, 0x28, 0x07, 0x9a, 0xc5, 0x10, 0xe5, 0x16, 0x43, 0x92, 0x2b, 0x10, 0xf9, 0xe6, 0x05, - 0x9d, 0xaf, 0x8a, 0x79, 0x0e, 0xba, 0xa8, 0x19, 0x67, 0x72, 0xd7, 0x89, 0xb6, 0x2d, 0x0f, 0xc8, - 0x82, 0xd8, 0x27, 0x6b, 0x70, 0xd7, 0xb7, 0xe6, 0x59, 0x45, 0x8a, 0x19, 0x65, 0x2e, 0x5f, 0x4f, - 0x86, 0x0e, 0x25, 0x8a, 0xa0, 0x7e, 0x12, 0xf6, 0x4a, 0x0e, 0x9e, 0xc8, 0x12, 0x69, 0x0c, 0x75, - 0x20, 0xa9, 0x2d, 0x1a, 0x56, 0x13, 0xa3, 0xfc, 0x5a, 0xa6, 0xc3, 0x4f, 0x77, 0xda, 0x24, 0xd2, - 0xcd, 0xa5, 0xd1, 0x64, 0xa4, 0x91, 0xe3, 0xc4, 0x93, 0xeb, 0x6b, 0xd8, 0x0e, 0xa0, 0x7d, 0x32, - 0x6a, 0xbb, 0x0c, 0x92, 0xf1, 0x97, 0x76, 0xad, 0x44, 0xba, 0xd5, 0x90, 0xeb, 0xe4, 0xfd, 0x2d, - 0x0b, 0x76, 0xd2, 0x36, 0xbb, 0x84, 0x5f, 0xc4, 0x4f, 0x85, 0x79, 0x9c, 0xc9, 0x45, 0x33, 0xcc, - 0x99, 0x8f, 0xef, 0x3a, 0xda, 0x58, 0x8e, 0x53, 0x8b, 0x5b, 0x35, 0x61, 0x97, 0x72, 0xb7, 0xa7, - 0xef, 0x4c, 0x14, 0x51, 0x45, 0x3a, 0x51, 0x5d, 0x8b, 0x4d, 0xe5, 0x69, 0x11, 0x1d, 0x89, 0x97, - 0xa0, 0x4e, 0xef, 0xa5, 0x02, 0x35, 0x12, 0x25, 0xb4, 0x4a, 0xbc, 0x2b, 0x76, 0xe9, 0xec, 0x9e, - 0x7a, 0x7e, 0xa3, 0xd7, 0x2d, 0x78, 0x8b, 0x2c, 0x6b, 0x22, 0xdd, 0x96, 0xdd, 0x7d, 0x77, 0xd2, - 0xe8, 0xee, 0x13, 0x4d, 0x8b, 0x3d, 0x47, 0x83, 0x2e, 0x2e, 0x00, 0xf1, 0x0d, 0x3e, 0x3e, 0xad, - 0x14, 0xef, 0xe7, 0xce, 0xba, 0x2e, 0xa0, 0x34, 0x45, 0x90, 0x71, 0x97, 0x9e, 0x5c, 0xe1, 0x16, - 0x69, 0x23, 0x92, 0xf3, 0x6e, 0x9b, 0xca, 0xc8, 0x7d, 0x4b, 0xf8, 0x22, 0x9c, 0x6c, 0x6a, 0x53, - 0x11, 0xee, 0x1c, 0xc5, 0x2c, 0x03, 0xe5, 0x01, 0xf5, 0xc5, 0x0e, 0x2a, 0x2f, 0x1d, 0x46, 0xf8, - 0x22, 0xdc, 0x46, 0xa2, 0xe2, 0x7a, 0x87, 0x67, 0x91, 0x5e, 0xd2, 0x32, 0xa9, 0xdc, 0x6e, 0x4e, - 0x4c, 0x1c, 0xd9, 0x25, 0x4e, 0x2b, 0x4c, 0x4a, 0x65, 0x5e, 0x4b, 0x24, 0xaf, 0x0d, 0xee, 0x9e, - 0x93, 0xe4, 0xee, 0xbf, 0x0e, 0x79, 0x47, 0x07, 0x25, 0x3d, 0xaf, 0x57, 0x31, 0x61, 0xf1, 0xe9, - 0x27, 0xab, 0x9e, 0x7e, 0xb2, 0xf2, 0xf4, 0xa3, 0xc9, 0x66, 0xda, 0x13, 0xb0, 0x7d, 0xa2, 0x60, - 0xde, 0x41, 0x6f, 0x5d, 0x35, 0x51, 0x9f, 0x57, 0xe0, 0xa3, 0xd0, 0x77, 0xcd, 0x62, 0x2c, 0x6c, - 0x9e, 0xdc, 0xba, 0x71, 0x32, 0x91, 0x7d, 0x5a, 0x6f, 0xd9, 0x32, 0xa9, 0x63, 0x25, 0x29, 0x23, - 0x00, 0x84, 0xb4, 0x94, 0xe6, 0x72, 0x99, 0x60, 0x09, 0x63, 0x56, 0x54, 0x80, 0x0e, 0xb4, 0x75, - 0xd4, 0xfe, 0x26, 0x9e, 0xb4, 0x05, 0xe1, 0x3d, 0x9c, 0xd6, 0x36, 0x88, 0xe0, 0x2a, 0x97, 0xbc, - 0x5b, 0x46, 0x6e, 0x40, 0xe3, 0x50, 0xd6, 0x74, 0x07, 0xe5, 0x4d, 0x85, 0x6a, 0xcf, 0x2e, 0xea, - 0x87, 0x05, 0x75, 0xb3, 0xa8, 0xe9, 0x75, 0xdb, 0xed, 0x4d, 0x2d, 0xae, 0xdb, 0x29, 0xe5, 0xd1, - 0x75, 0xe0, 0xb5, 0xae, 0xcb, 0xe5, 0x79, 0xba, 0x6d, 0x4d, 0x4f, 0x2b, 0xe8, 0x63, 0x55, 0x83, - 0xfb, 0xf0, 0xce, 0x19, 0x46, 0x08, 0x80, 0x2a, 0xf9, 0xe4, 0x6b, 0x3c, 0xa1, 0x6d, 0x9f, 0xf5, - 0x25, 0x1f, 0xf8, 0x3a, 0x1f, 0xa8, 0xf3, 0xa7, 0xba, 0x83, 0xaa, 0xc6, 0x46, 0x3f, 0x59, 0x11, - 0x77, 0xd9, 0xf1, 0x0c, 0x45, 0x41, 0xda, 0xef, 0xa2, 0xcd, 0xe0, 0x6b, 0x5a, 0x19, 0x8c, 0x3c, - 0x62, 0xdf, 0x93, 0x3e, 0x4f, 0x1f, 0xa4, 0x24, 0x0e, 0x24, 0x97, 0x3f, 0xfb, 0xf9, 0x82, 0x1d, - 0xc2, 0xd1, 0x57, 0xab, 0x39, 0xd9, 0xc6, 0xe8, 0xde, 0xc8, 0xcd, 0xfd, 0x9b, 0x02, 0x10, 0xb1, - 0x90, 0x42, 0xcf, 0x03, 0xaf, 0xad, 0xf6, 0x4d, 0xd4, 0x12, 0x9b, 0x02, 0xeb, 0xa1, 0x40, 0x56, - 0x7d, 0x4d, 0xbd, 0x08, 0x29, 0x82, 0x8b, 0x74, 0x78, 0xce, 0xe4, 0xf3, 0xcc, 0x4a, 0x0f, 0x0f, - 0x51, 0xe6, 0x74, 0xfb, 0x35, 0x2f, 0x90, 0x8f, 0xa2, 0x8b, 0x09, 0x6d, 0xb8, 0x14, 0x08, 0x20, - 0x00, 0xda, 0x45, 0xef, 0x23, 0xad, 0xd9, 0x70, 0x98, 0xf0, 0x97, 0x7c, 0xfd, 0x29, 0x5e, 0xa0, - 0x6a, 0x37, 0xad, 0x80, 0x7e, 0x57, 0xf7, 0x69, 0xd6, 0x4f, 0xaa, 0x6d, 0x64, 0x56, 0x76, 0x77, - 0x88, 0xf5, 0xc6, 0xde, 0x9e, 0xf8, 0xed, 0xe9, 0x44, 0xaa, 0x3b, 0x3e, 0x59, 0xbd, 0xb9, 0xaf, - 0x79, 0x17, 0xfa, 0xed, 0x15, 0x52, 0xdb, 0xae, 0xda, 0xa8, 0x36, 0x50, 0xc6, 0xcf, 0xb6, 0xb6, - 0xe4, 0x52, 0xde, 0x81, 0x60, 0xec, 0x83, 0xbe, 0xd6, 0x96, 0x6e, 0x4c, 0x50, 0x7f, 0x71, 0x57, - 0x64, 0xb7, 0x27, 0x6b, 0xef, 0xaf, 0xef, 0xe9, 0xef, 0x8b, 0xbf, 0xbb, 0xbf, 0x45, 0x5f, 0x8b, - 0xd8, 0x49, 0x53, 0xe8, 0x19, 0xf5, 0xb4, 0xdf, 0x96, 0xef, 0x7b, 0x75, 0xa6, 0xa9, 0xa4, 0x9d, - 0x7c, 0xff, 0xda, 0xd6, 0x0e, 0xf7, 0x95, 0xb0, 0xd2, 0xad, 0x04, 0xd1, 0x0b, 0xdd, 0x15, 0xb7, - 0x5b, 0x2f, 0xf7, 0x1b, 0x07, 0x7a, 0xa3, 0xe7, 0xda, 0x5d, 0x2a, 0xc7, 0x1b, 0xbc, 0xab, 0xef, - 0x5d, 0xcb, 0x77, 0xfd, 0x64, 0x8d, 0xe6, 0x81, 0xa8, 0xf4, 0x08, 0x1d, 0xa2, 0x5b, 0xfc, 0x76, - 0x9d, 0x41, 0x5b, 0xed, 0x44, 0x47, 0xad, 0xaf, 0x6a, 0x70, 0x30, 0xf8, 0x2f, 0xd7, 0xad, 0xa5, - 0xba, 0xaa, 0xa1, 0x03, 0x90, 0x25, 0x16, 0x38, 0x56, 0xc2, 0x23, 0x9e, 0xc9, 0x19, 0x07, 0xaa, - 0xdb, 0xe8, 0x49, 0x41, 0xd3, 0x7d, 0x7b, 0xb7, 0xa6, 0x9b, 0xc8, 0x43, 0x2d, 0x03, 0x52, 0xcd, - 0x70, 0xc6, 0x8f, 0xd4, 0x74, 0x3f, 0xe8, 0x4b, 0xc3, 0xaa, 0xc7, 0x37, 0x9d, 0x82, 0x79, 0xc4, - 0xc4, 0xb1, 0x13, 0x26, 0x24, 0x92, 0xd8, 0x22, 0x42, 0xf9, 0x23, 0xa5, 0x4b, 0xa0, 0x3e, 0x83, - 0xbf, 0x7c, 0xbb, 0x31, 0x57, 0x52, 0xf0, 0x77, 0xf7, 0x40, 0xfc, 0xee, 0x8b, 0xf4, 0x9e, 0xf8, - 0x6d, 0xe3, 0x6f, 0x8c, 0x1b, 0x8f, 0x2a, 0xfa, 0xf0, 0xea, 0x6e, 0xa9, 0x82, 0x7d, 0x49, 0xf1, - 0x64, 0x0d, 0x1e, 0x8d, 0x69, 0x37, 0x13, 0x01, 0x61, 0x2a, 0x4c, 0x04, 0x26, 0xe1, 0xa7, 0xd3, - 0xfe, 0xb9, 0x8f, 0x1f, 0x57, 0x91, 0x29, 0x3a, 0x24, 0xcf, 0x2f, 0xd6, 0x90, 0x49, 0xe1, 0xd6, - 0xd6, 0x22, 0x34, 0xef, 0xc3, 0x31, 0x09, 0xd5, 0xa1, 0xf2, 0x71, 0x54, 0xb1, 0xcc, 0xb3, 0x3c, - 0xba, 0xe0, 0x26, 0xb0, 0x91, 0x17, 0x69, 0x82, 0x10, 0xd1, 0x9f, 0x96, 0x74, 0xc0, 0x14, 0x14, - 0x2c, 0xae, 0x18, 0xf6, 0xa4, 0x0e, 0xe8, 0x6b, 0x4b, 0xd7, 0x3e, 0x8d, 0x93, 0x2d, 0x54, 0x30, - 0x8e, 0x3e, 0xfc, 0x4d, 0x15, 0xe2, 0x53, 0xa1, 0xba, 0x65, 0xf4, 0xbc, 0xaf, 0xd4, 0xb8, 0x54, - 0x6a, 0x7a, 0x11, 0x7f, 0x19, 0x6c, 0xd1, 0xd1, 0x7e, 0xbd, 0x77, 0x7a, 0xfe, 0x2c, 0x77, 0x8e, - 0x3c, 0x64, 0xb1, 0xe1, 0xae, 0xc2, 0x10, 0x0c, 0x9b, 0x1e, 0xb0, 0x92, 0xdb, 0xe8, 0xbe, 0xb9, - 0xf5, 0xc3, 0x56, 0x9b, 0x63, 0x98, 0x68, 0x83, 0x9d, 0xf0, 0x1d, 0xa4, 0x62, 0xb0, 0xf5, 0x95, - 0x41, 0xc5, 0x5c, 0x62, 0xc0, 0x13, 0x6d, 0xc0, 0x13, 0x39, 0xe0, 0x18, 0xbf, 0xa0, 0x00, 0xbf, - 0x04, 0x34, 0xc9, 0xc7, 0x3e, 0xd1, 0xc1, 0x7a, 0x5d, 0x12, 0x97, 0x24, 0xe1, 0x73, 0x11, 0x71, - 0xb8, 0x7b, 0xaf, 0x34, 0xef, 0xc9, 0xa3, 0x2b, 0x83, 0xf6, 0x1d, 0x62, 0x5c, 0x97, 0x94, 0x83, - 0xba, 0xf5, 0x84, 0x8b, 0x86, 0x7b, 0x64, 0xf9, 0x2f, 0x55, 0xca, 0xe6, 0xdd, 0x1e, 0xa1, 0x6c, - 0xc3, 0x23, 0xc4, 0x34, 0xa5, 0xe3, 0x7e, 0x0d, 0xb3, 0x2c, 0x9f, 0xc1, 0xa6, 0x5d, 0x6f, 0xd5, - 0x1c, 0x5e, 0xe6, 0xc8, 0xd3, 0x17, 0xe5, 0xbe, 0xe1, 0x9d, 0x53, 0x6a, 0xcc, 0x13, 0xfd, 0x7d, - 0xdb, 0x6a, 0x3d, 0xd3, 0x84, 0xf5, 0xc6, 0x91, 0x81, 0x9c, 0xcc, 0x2a, 0x69, 0xeb, 0xfb, 0x1c, - 0x4f, 0x84, 0x1f, 0x8b, 0x84, 0x16, 0xb5, 0x20, 0x0e, 0x8f, 0xc8, 0x9e, 0xb3, 0xbc, 0xcf, 0x38, - 0x58, 0xcd, 0x82, 0x16, 0x4a, 0x3a, 0xac, 0x5a, 0x39, 0xca, 0x09, 0x9a, 0x35, 0xe5, 0xb1, 0x3e, - 0x00, 0xa7, 0x12, 0x80, 0x77, 0x39, 0x22, 0x08, 0x76, 0xf2, 0x79, 0xee, 0xb7, 0xc9, 0xe7, 0x89, - 0x5b, 0x50, 0xe9, 0xfd, 0x80, 0xeb, 0xa2, 0xb8, 0x14, 0x2e, 0xbc, 0xa2, 0x07, 0x03, 0xee, 0x9f, - 0x95, 0xc6, 0x5e, 0x25, 0x11, 0xbc, 0xdf, 0xe0, 0x6e, 0x76, 0xc7, 0x5c, 0x55, 0x3c, 0x4d, 0x25, - 0xe7, 0xdd, 0x2a, 0x5d, 0x66, 0x1b, 0xa3, 0xbe, 0x29, 0xf4, 0xa5, 0xb4, 0x38, 0x3f, 0xda, 0xd8, - 0x1a, 0x3f, 0xa0, 0xee, 0x94, 0xfd, 0xd9, 0xfd, 0xc1, 0xdd, 0x22, 0xf7, 0xb7, 0x62, 0x23, 0x02, - 0xbd, 0x95, 0xf2, 0x9b, 0x8b, 0x2c, 0x32, 0xf2, 0x2b, 0x2a, 0xfa, 0x76, 0x73, 0xe8, 0x07, 0x9c, - 0xb8, 0xb8, 0xec, 0x54, 0xfb, 0x83, 0x68, 0xb0, 0x45, 0xa5, 0x85, 0x01, 0xad, 0xac, 0xf6, 0xf9, - 0x56, 0x8a, 0xfa, 0x87, 0xaa, 0xfd, 0x6e, 0x2b, 0xb4, 0xfb, 0xff, 0x40, 0xad, 0x3f, 0x6e, 0x07, - 0x76, 0xf0, 0x0f, 0x54, 0xfb, 0x74, 0x6b, 0xb5, 0xfd, 0x7f, 0xa0, 0xd6, 0xaf, 0x4b, 0xb5, 0x52, - 0x95, 0xbc, 0x7e, 0xe1, 0x57, 0xe2, 0xae, 0x13, 0x96, 0xbb, 0x4e, 0x56, 0x52, 0x0b, 0x91, 0x11, - 0xad, 0x28, 0x63, 0xcd, 0x6b, 0xeb, 0xf5, 0xfe, 0xb1, 0x54, 0xef, 0xa0, 0x5d, 0x51, 0x2f, 0x30, - 0x08, 0xcb, 0xa7, 0xe3, 0x95, 0xd4, 0x62, 0xee, 0xaa, 0x17, 0xec, 0xe1, 0xa5, 0x38, 0xfe, 0xdb, - 0x11, 0xe7, 0x81, 0x95, 0x00, 0x2b, 0x74, 0x36, 0x5f, 0x8d, 0xec, 0x88, 0xf5, 0xbb, 0xb2, 0xb8, - 0xfc, 0x26, 0x27, 0x7a, 0xd5, 0x5e, 0xa7, 0xab, 0x1b, 0x13, 0xc0, 0xc9, 0xab, 0xe2, 0xf4, 0xa3, - 0x83, 0xf2, 0xa7, 0x72, 0x79, 0x43, 0xdb, 0x72, 0xd2, 0x3b, 0x58, 0xe9, 0x6f, 0x7d, 0xbd, 0xe0, - 0x0f, 0x96, 0x0c, 0xaf, 0x62, 0xe9, 0xc3, 0x28, 0x68, 0xae, 0xd0, 0x0d, 0xbd, 0xd8, 0x9f, 0x4b, - 0xc5, 0x04, 0xa9, 0xf6, 0xef, 0x29, 0xf6, 0xd3, 0x5d, 0x60, 0x76, 0x7a, 0x3a, 0x98, 0x9d, 0x02, - 0xaa, 0x7f, 0xd6, 0xdb, 0x23, 0x28, 0xef, 0x69, 0x89, 0xb1, 0x62, 0x09, 0x00, 0xf0, 0x9e, 0x12, - 0x59, 0x5e, 0xc2, 0xf0, 0xf5, 0x79, 0xa2, 0xcf, 0x0d, 0x56, 0x3d, 0x6f, 0xc2, 0x34, 0x21, 0x05, - 0xb5, 0x29, 0x32, 0x29, 0x45, 0x80, 0x13, 0x00, 0xa8, 0x23, 0xd0, 0x25, 0x02, 0x4a, 0xb5, 0x26, - 0x89, 0x7e, 0xf4, 0x8f, 0x81, 0xd6, 0x46, 0x0c, 0xaa, 0xf0, 0xc1, 0x41, 0xb7, 0xd1, 0xd9, 0xad, - 0x37, 0x3b, 0x03, 0x89, 0x3b, 0x48, 0x11, 0x62, 0x7a, 0x99, 0x2e, 0xdc, 0x80, 0x39, 0x7e, 0xe0, - 0xfe, 0xe8, 0x30, 0x37, 0xc5, 0xb8, 0x03, 0xee, 0x9f, 0x1d, 0x16, 0x32, 0xf7, 0x5b, 0xf8, 0x9b, - 0xba, 0xdf, 0x39, 0x2c, 0x75, 0x19, 0x73, 0x66, 0x6e, 0xc4, 0x9c, 0x60, 0xea, 0x7e, 0xef, 0x04, - 0xcc, 0x7d, 0xea, 0x04, 0x73, 0x37, 0x83, 0xf7, 0xd4, 0xfd, 0xd9, 0x99, 0xbb, 0xa1, 0x93, 0x30, - 0xf7, 0x8f, 0x4e, 0x12, 0xb8, 0x5f, 0x3b, 0xa9, 0xef, 0xbe, 0x75, 0x52, 0xe6, 0x3e, 0x87, 0x3f, - 0xa9, 0x9b, 0x30, 0x27, 0x4d, 0xdd, 0x1f, 0xd6, 0x6b, 0xab, 0xea, 0x86, 0x25, 0x8c, 0x0a, 0x44, - 0x97, 0xd7, 0xb8, 0xe7, 0x61, 0x3c, 0xf6, 0x43, 0x67, 0xb9, 0x76, 0xbe, 0xb1, 0x9d, 0x3f, 0x79, - 0xbf, 0xb7, 0xd2, 0x85, 0xf5, 0xe7, 0x26, 0x85, 0x3a, 0xd8, 0x53, 0x17, 0xfe, 0x44, 0x2a, 0x8a, - 0x5f, 0xa3, 0x33, 0x84, 0x2c, 0x2c, 0xb5, 0xfe, 0x64, 0x3b, 0xf0, 0xe0, 0x5b, 0x11, 0xc6, 0x33, - 0xfb, 0xc9, 0xfa, 0xb9, 0x22, 0xee, 0xc0, 0x9f, 0x30, 0x60, 0x04, 0xe4, 0x9a, 0x5b, 0x78, 0x7f, - 0x44, 0xc6, 0xa0, 0x72, 0x8c, 0x2d, 0x42, 0x61, 0xe7, 0xd4, 0x65, 0x00, 0x27, 0xa7, 0x3c, 0xda, - 0x3f, 0x05, 0x52, 0xf8, 0xbd, 0x95, 0x04, 0x96, 0x3d, 0xcc, 0xa3, 0xdf, 0xfc, 0xde, 0x0a, 0x52, - 0x0b, 0xef, 0xe1, 0x82, 0x07, 0x8a, 0xce, 0x05, 0x0f, 0x7e, 0x40, 0x81, 0xbc, 0x20, 0x65, 0x6a, - 0x61, 0x20, 0x02, 0x00, 0x03, 0xf3, 0xf8, 0xf8, 0x80, 0x71, 0x53, 0x28, 0x96, 0x37, 0x54, 0x15, - 0x40, 0xbb, 0xf5, 0xba, 0x35, 0xf1, 0x12, 0xc6, 0x2f, 0x09, 0x88, 0x46, 0x0c, 0xc5, 0x85, 0x53, - 0x88, 0x52, 0x26, 0xbf, 0x34, 0x3b, 0x2e, 0x46, 0xaa, 0x73, 0x52, 0x1e, 0x6b, 0x7f, 0x19, 0xb9, - 0x13, 0x07, 0xd0, 0x0f, 0x23, 0x93, 0x21, 0x22, 0x03, 0xc4, 0xac, 0xef, 0x4c, 0xdd, 0xc8, 0xf1, - 0xdd, 0x64, 0xcd, 0xef, 0x6a, 0x44, 0x78, 0x59, 0x09, 0x5e, 0x26, 0xe1, 0x65, 0x12, 0x5e, 0x18, - 0x4b, 0x01, 0x30, 0x8c, 0xad, 0x65, 0x97, 0xc3, 0xa4, 0x31, 0x04, 0x3d, 0x39, 0x02, 0x71, 0x56, - 0x48, 0x4e, 0x6c, 0x17, 0xc4, 0xb0, 0x88, 0xfc, 0xbf, 0x94, 0x90, 0x00, 0x59, 0x24, 0x0e, 0x50, - 0x48, 0xe4, 0x44, 0x6e, 0xaf, 0x8f, 0x97, 0x09, 0xac, 0x56, 0xbd, 0x03, 0xfc, 0x1d, 0x21, 0x79, - 0x43, 0xe7, 0x52, 0xdb, 0x95, 0xe1, 0xc5, 0x28, 0xb2, 0x57, 0x18, 0xb9, 0xc9, 0x61, 0x7b, 0xc4, - 0x83, 0x8a, 0xf0, 0x32, 0xbe, 0x28, 0xe3, 0x63, 0x99, 0x04, 0xca, 0xf8, 0x79, 0x19, 0xb4, 0x9a, - 0xd6, 0x72, 0xa5, 0xeb, 0x24, 0x75, 0x02, 0xa7, 0x56, 0xfb, 0xbd, 0x35, 0xb3, 0xec, 0xd3, 0x35, - 0x18, 0x6a, 0x7e, 0x6b, 0x61, 0xe7, 0x77, 0x87, 0x1c, 0x13, 0xec, 0x2d, 0xdf, 0x3b, 0x81, 0x41, - 0x84, 0xff, 0xd7, 0x3a, 0xa7, 0x52, 0x03, 0xf1, 0x5b, 0xc7, 0x1e, 0x64, 0x5f, 0xdb, 0x74, 0xbb, - 0xd8, 0x2b, 0xcf, 0x6f, 0xcd, 0x44, 0x30, 0x56, 0x15, 0x81, 0x84, 0x47, 0x92, 0x4b, 0x86, 0x7e, - 0x6b, 0xea, 0x89, 0xf8, 0x2c, 0x7a, 0x54, 0x50, 0xa8, 0xf7, 0xa4, 0xcd, 0x63, 0xc0, 0xf2, 0x32, - 0x30, 0x22, 0x09, 0xe2, 0x7f, 0x2d, 0xc2, 0x97, 0x58, 0x11, 0xe0, 0xac, 0x5e, 0xaf, 0xbd, 0x59, - 0xad, 0x9a, 0x18, 0x01, 0x32, 0x82, 0xe7, 0xaf, 0xb5, 0x28, 0x1f, 0xfc, 0xc6, 0x90, 0x68, 0xb5, - 0xaa, 0xc9, 0xd8, 0xf6, 0x9c, 0xe6, 0x96, 0x89, 0x9b, 0x3a, 0x63, 0x37, 0x10, 0x21, 0x4e, 0x30, - 0x8a, 0x57, 0x02, 0x30, 0x26, 0xab, 0x15, 0xf6, 0x4e, 0xb0, 0x29, 0xc6, 0x9b, 0x7f, 0x8a, 0x11, - 0x99, 0x80, 0x70, 0xf3, 0xfa, 0x88, 0x52, 0x9e, 0xd4, 0xeb, 0x4f, 0xac, 0xd4, 0x1e, 0x2d, 0xc7, - 0x6e, 0xba, 0x76, 0x2d, 0x8c, 0xb9, 0x2a, 0x6e, 0x8e, 0xa2, 0x40, 0x7f, 0x1b, 0x37, 0x25, 0x64, - 0xce, 0x52, 0xe5, 0x10, 0xb1, 0x5d, 0xe8, 0xbe, 0x62, 0xb2, 0x7b, 0xa1, 0x5d, 0xbb, 0x35, 0xb3, - 0xf3, 0x74, 0xbc, 0x82, 0x35, 0xcc, 0x78, 0x90, 0x25, 0x0c, 0x2e, 0x04, 0x38, 0x24, 0x6b, 0x96, - 0xc2, 0xc0, 0x50, 0xd0, 0x8c, 0x25, 0xdd, 0xb8, 0x20, 0x82, 0xe1, 0x94, 0xe3, 0xfd, 0x90, 0x85, - 0x9e, 0xb5, 0xc6, 0xab, 0x55, 0x72, 0x92, 0xb5, 0x16, 0x78, 0x55, 0x02, 0x7f, 0xf0, 0x3a, 0x22, - 0x96, 0x4e, 0xd6, 0x7a, 0xe5, 0x6c, 0x62, 0x3b, 0x6b, 0x4d, 0x09, 0xd5, 0x18, 0x69, 0x9d, 0x2a, - 0xa1, 0x2b, 0x26, 0x22, 0x64, 0xdb, 0x16, 0xde, 0x08, 0x32, 0x55, 0x37, 0x1b, 0xb1, 0x56, 0x44, - 0x01, 0x1d, 0x27, 0x4e, 0x6c, 0x3b, 0xd7, 0x2a, 0x68, 0x78, 0x19, 0x06, 0x5c, 0x2c, 0x40, 0x30, - 0x6a, 0xbc, 0x79, 0x75, 0xa1, 0x01, 0x07, 0xa6, 0xad, 0x5d, 0xbf, 0x13, 0xf1, 0xb0, 0x50, 0x53, - 0x1b, 0x63, 0x72, 0xca, 0x6b, 0x82, 0x4f, 0x22, 0x27, 0x05, 0x0b, 0xa5, 0xe5, 0x03, 0x7f, 0x67, - 0xad, 0x63, 0x71, 0x17, 0xc8, 0x55, 0xbd, 0x7e, 0xcd, 0x46, 0x22, 0x38, 0x3b, 0x46, 0x3a, 0xbb, - 0x66, 0xeb, 0x47, 0xc3, 0x33, 0xd7, 0x34, 0xd5, 0x41, 0xb4, 0x19, 0xc9, 0x92, 0x7c, 0xd3, 0x37, - 0x13, 0x21, 0x5a, 0x66, 0x27, 0xb3, 0x3c, 0x90, 0xdc, 0x21, 0xd3, 0x58, 0x76, 0xc6, 0xef, 0xfd, - 0x18, 0xfa, 0x0d, 0xef, 0x8c, 0x62, 0xa3, 0x13, 0x1f, 0xe0, 0xce, 0x49, 0x8a, 0x6c, 0xfc, 0x04, - 0x3a, 0x04, 0x83, 0xb4, 0x3e, 0x83, 0x26, 0xd8, 0x1a, 0x32, 0xe9, 0x39, 0x28, 0x4d, 0x75, 0x85, - 0xb8, 0x34, 0x45, 0x0e, 0x05, 0x59, 0x91, 0x02, 0xad, 0x4e, 0xd7, 0x18, 0x9d, 0x4e, 0x5d, 0x52, - 0x32, 0xb5, 0x45, 0x08, 0x3d, 0xe8, 0xed, 0x49, 0xdc, 0x68, 0x9c, 0x82, 0x50, 0x48, 0x5a, 0x63, - 0x27, 0xf4, 0x6a, 0xd1, 0x30, 0x04, 0xea, 0xb1, 0xf0, 0x1d, 0xef, 0x4f, 0xe0, 0x0f, 0xde, 0x8d, - 0x75, 0xc6, 0x28, 0x72, 0x4c, 0x3e, 0xc4, 0x8b, 0x87, 0xbf, 0x58, 0x97, 0xf6, 0xf2, 0xe1, 0x32, - 0x01, 0xfe, 0xe8, 0x70, 0xfe, 0x50, 0xe2, 0x01, 0xa3, 0xd9, 0xa9, 0xf0, 0xe0, 0xa9, 0xf7, 0xc8, - 0x7c, 0x84, 0xd7, 0xe9, 0xb4, 0x8e, 0x4f, 0x18, 0xde, 0x5e, 0xf3, 0xc8, 0x54, 0x6f, 0x82, 0xca, - 0xcf, 0xd8, 0xc3, 0x5f, 0x1e, 0x2e, 0xa3, 0xb5, 0x77, 0xf9, 0x70, 0x99, 0x8e, 0xcc, 0x13, 0xd3, - 0x35, 0x5b, 0xe6, 0x1a, 0xeb, 0x3e, 0xd6, 0x44, 0xc8, 0x9a, 0x3e, 0x9e, 0x9a, 0x78, 0xa1, 0xd3, - 0xd9, 0xda, 0x16, 0x77, 0x8b, 0x38, 0x78, 0xb9, 0x88, 0x02, 0x83, 0xa3, 0x76, 0x74, 0x86, 0xfd, - 0x2b, 0xc2, 0xc6, 0x63, 0x07, 0x9a, 0xd0, 0x92, 0xd9, 0xc8, 0xf4, 0xc2, 0x34, 0x6e, 0x6b, 0xd1, - 0xbf, 0x3b, 0x3b, 0x24, 0xc1, 0x04, 0x72, 0x37, 0x36, 0x80, 0x3b, 0x2b, 0x00, 0xf4, 0x31, 0xda, - 0xd9, 0xf9, 0xca, 0x48, 0xe3, 0x45, 0x32, 0x61, 0x1f, 0xbe, 0x7f, 0xe5, 0x61, 0xf6, 0x64, 0x3d, - 0x9a, 0xdc, 0x4e, 0x42, 0x76, 0x86, 0x44, 0x0d, 0x14, 0x81, 0x13, 0x16, 0x0e, 0xf6, 0xce, 0xe3, - 0x7c, 0xb8, 0x31, 0xb4, 0x67, 0x6a, 0xaf, 0x1f, 0xef, 0xd0, 0x80, 0x47, 0x38, 0xdc, 0xb5, 0x10, - 0xe3, 0x1a, 0xe2, 0x65, 0xa7, 0x98, 0x79, 0xa8, 0xdd, 0x08, 0x80, 0xd0, 0xc4, 0x6b, 0x79, 0x2f, - 0x00, 0x8c, 0x20, 0x10, 0x21, 0xff, 0xbc, 0x84, 0xe1, 0x41, 0x28, 0x17, 0x3c, 0xcb, 0x5a, 0x65, - 0x49, 0x21, 0x8b, 0x48, 0xb4, 0x44, 0x79, 0xfb, 0x0c, 0x2f, 0x51, 0x91, 0xe1, 0xf7, 0x81, 0x92, - 0x52, 0xf2, 0x26, 0x92, 0x2c, 0x9b, 0x8e, 0x80, 0xe8, 0x2e, 0xbd, 0xe5, 0x22, 0x09, 0x5d, 0xa0, - 0x3e, 0x47, 0x44, 0xce, 0x73, 0xc7, 0x6c, 0xed, 0x20, 0xb3, 0x5e, 0x02, 0x73, 0x2e, 0xa8, 0x33, - 0xbc, 0x2b, 0x79, 0x7c, 0xbf, 0xd6, 0x2f, 0xc9, 0x89, 0x20, 0x5a, 0x10, 0xd5, 0x80, 0x4e, 0xa4, - 0x5b, 0x98, 0x13, 0xac, 0x05, 0x48, 0xfa, 0x01, 0xe5, 0x36, 0x31, 0x1f, 0xe0, 0x6b, 0x26, 0x6e, - 0x95, 0x41, 0x7c, 0x4c, 0x30, 0x5a, 0x5c, 0xa6, 0x7a, 0xfb, 0x31, 0xd2, 0x3a, 0x24, 0x7b, 0x91, - 0x51, 0x2f, 0x30, 0x74, 0x12, 0x12, 0x21, 0x8c, 0x58, 0xaa, 0xcb, 0xaa, 0x56, 0x18, 0xd9, 0xc5, - 0xc1, 0xa3, 0xa9, 0x07, 0xa5, 0xb5, 0xc6, 0x56, 0x3c, 0xf0, 0x23, 0x60, 0xa4, 0x34, 0x6e, 0x72, - 0x56, 0xf9, 0xc5, 0x06, 0xf1, 0xf6, 0x31, 0x3a, 0xd3, 0x2e, 0x56, 0xc0, 0x0d, 0xb7, 0xda, 0x55, - 0x29, 0x49, 0x43, 0x86, 0x36, 0x86, 0x89, 0x34, 0xd0, 0xee, 0x83, 0x8a, 0x4c, 0x8c, 0xe5, 0x18, - 0x7b, 0x24, 0xf6, 0xd3, 0x11, 0x4c, 0xd9, 0x32, 0x04, 0xf2, 0x02, 0x06, 0x14, 0x3b, 0x2e, 0xaf, - 0xc0, 0x0a, 0x54, 0x08, 0xe0, 0x18, 0xa5, 0x5c, 0xc2, 0xef, 0x70, 0x03, 0x1c, 0xc4, 0x74, 0xfb, - 0xc6, 0x18, 0xaa, 0xd5, 0x03, 0x6f, 0xbe, 0x00, 0x24, 0xcf, 0x4b, 0x69, 0xc7, 0xb8, 0x63, 0xe2, - 0x70, 0x02, 0xe8, 0x1a, 0xd3, 0x7d, 0x3d, 0x73, 0x7a, 0x9e, 0xd3, 0x33, 0x01, 0x30, 0x86, 0x57, - 0x62, 0xfa, 0xf9, 0x6a, 0x35, 0x3f, 0x1a, 0xc3, 0xbc, 0x34, 0x85, 0x8a, 0x9c, 0xb1, 0xf8, 0x3c, - 0x87, 0xcf, 0x53, 0xa8, 0xc5, 0x99, 0x8b, 0x79, 0x0a, 0xf2, 0x8f, 0x8f, 0xe6, 0x2a, 0x97, 0x0d, - 0x40, 0x4b, 0xf8, 0xc5, 0xcc, 0x33, 0xe6, 0x63, 0xf3, 0x82, 0x35, 0x10, 0x64, 0x18, 0xac, 0xb1, - 0x07, 0xe2, 0xf7, 0x06, 0x03, 0x97, 0x83, 0x84, 0x14, 0x74, 0x24, 0xe4, 0xb2, 0x0c, 0x77, 0x86, - 0x31, 0x1b, 0x03, 0xf8, 0x37, 0x01, 0xa1, 0x4d, 0x87, 0xcb, 0x4b, 0x17, 0xcb, 0x40, 0x83, 0x37, - 0x4c, 0x46, 0xaa, 0xff, 0xc4, 0x6e, 0x53, 0x2b, 0x56, 0xa1, 0x2e, 0x31, 0x60, 0x36, 0x4c, 0x38, - 0x32, 0x4c, 0x1a, 0xea, 0x3c, 0xe7, 0x8c, 0xd7, 0x07, 0xd5, 0xd5, 0xeb, 0x18, 0x75, 0x73, 0x0c, - 0xd3, 0xfb, 0x39, 0x85, 0x6c, 0x13, 0xfa, 0xdc, 0xcc, 0x93, 0x85, 0x61, 0x02, 0x9d, 0xe0, 0x04, - 0x52, 0x8b, 0x46, 0x93, 0xd6, 0xd8, 0x9d, 0xb4, 0x16, 0xaa, 0x2a, 0x78, 0x5e, 0x2b, 0x07, 0xd9, - 0x84, 0x13, 0x9d, 0x28, 0x05, 0x6f, 0x30, 0x05, 0x22, 0x7d, 0xcd, 0x00, 0xe9, 0x95, 0xd0, 0xcd, - 0xb4, 0x95, 0x2e, 0x7e, 0xcb, 0xae, 0x08, 0x49, 0x5b, 0x0e, 0x7d, 0x8d, 0xc1, 0x5e, 0xf9, 0x65, - 0x77, 0x74, 0xc1, 0xec, 0xcb, 0x69, 0xc8, 0x9e, 0xc1, 0x5c, 0x37, 0xf6, 0x27, 0x9f, 0x46, 0xdb, - 0x3e, 0xb8, 0xfa, 0x87, 0x27, 0x51, 0x70, 0x49, 0x91, 0x0f, 0xbf, 0xc6, 0xeb, 0x14, 0x86, 0x51, - 0x7e, 0xaf, 0xba, 0x91, 0x5a, 0xf9, 0x75, 0x45, 0x9d, 0x76, 0xfb, 0x31, 0xad, 0x07, 0x07, 0x47, - 0x4a, 0xd3, 0x28, 0x87, 0x47, 0x14, 0x14, 0x17, 0x38, 0x41, 0x03, 0xf7, 0xc5, 0xe5, 0xb3, 0x0f, - 0x8f, 0x29, 0x07, 0x78, 0xc5, 0x2b, 0x07, 0xf8, 0x9d, 0x95, 0xf9, 0x95, 0x03, 0xac, 0x35, 0xb6, - 0xd7, 0x59, 0xa3, 0xe1, 0x44, 0xa0, 0x70, 0xac, 0xf5, 0x4b, 0x85, 0x9e, 0x68, 0xa1, 0x69, 0xcf, - 0x30, 0xe4, 0xa7, 0x0a, 0x65, 0xbe, 0xf3, 0x68, 0xe7, 0xdc, 0x31, 0x3f, 0x7e, 0x7c, 0x04, 0x6c, - 0xf5, 0xe8, 0x4c, 0x5e, 0x0d, 0xc8, 0x3c, 0xb3, 0x2c, 0x1a, 0x4d, 0xe7, 0xb8, 0x94, 0x2a, 0xae, - 0xaa, 0xe1, 0x1f, 0xdf, 0x32, 0x6f, 0xe7, 0x2f, 0x16, 0x06, 0x43, 0x5f, 0x41, 0x32, 0x40, 0x4f, - 0x98, 0xb0, 0x3f, 0xee, 0x58, 0x37, 0x4d, 0x7b, 0x94, 0x5f, 0x97, 0x60, 0x0d, 0x57, 0x0f, 0xed, - 0x1d, 0xe7, 0x15, 0x65, 0x2f, 0xe6, 0xbc, 0xf6, 0xd3, 0x4b, 0xf1, 0xf9, 0xd9, 0xb6, 0xda, 0x30, - 0x46, 0x9b, 0xc8, 0xf3, 0xeb, 0xb6, 0x3c, 0x13, 0xd0, 0xef, 0x79, 0x96, 0x0f, 0x90, 0x05, 0x64, - 0xe2, 0x47, 0xeb, 0x63, 0xfa, 0xd8, 0x1a, 0xb9, 0xd6, 0x89, 0xf9, 0xe8, 0xd4, 0xb6, 0xe0, 0xe9, - 0xe3, 0xc7, 0xd6, 0xea, 0xe4, 0x2f, 0x1f, 0xa3, 0x8f, 0x1f, 0x31, 0xa5, 0x61, 0x7f, 0xec, 0xac, - 0xb4, 0xe4, 0xd4, 0x31, 0x1f, 0x59, 0xf6, 0xc7, 0x8f, 0xf8, 0xc5, 0x86, 0xa2, 0x1f, 0xed, 0x9d, - 0x73, 0x52, 0x29, 0x5e, 0x33, 0xb4, 0x3f, 0x7e, 0x41, 0x1f, 0x43, 0x49, 0x95, 0x7a, 0xc9, 0xe4, - 0x7a, 0x07, 0x0c, 0xec, 0x25, 0x90, 0xbd, 0xa6, 0xe7, 0x15, 0x43, 0xdb, 0xbd, 0x89, 0x0d, 0xf5, - 0x05, 0xaf, 0xd7, 0xc6, 0x28, 0xbf, 0x6b, 0x8c, 0xbf, 0x0a, 0x4a, 0x03, 0x5e, 0x2d, 0x24, 0x05, - 0x97, 0x16, 0xcd, 0x1b, 0xaa, 0x6c, 0x34, 0x7e, 0x61, 0x47, 0x48, 0x0a, 0xda, 0xf5, 0x7c, 0xda, - 0x15, 0x1f, 0xaf, 0x19, 0x17, 0xce, 0x8c, 0xc7, 0xce, 0x8e, 0x64, 0xf4, 0xc3, 0x88, 0xe4, 0x2f, - 0x5f, 0xbd, 0x10, 0xea, 0x2b, 0x97, 0xa9, 0x5c, 0x7c, 0xaa, 0x40, 0xb1, 0x18, 0x45, 0x9f, 0xee, - 0x39, 0xf0, 0xb4, 0x60, 0xb1, 0x74, 0xc3, 0xac, 0x0e, 0x9e, 0xd1, 0x04, 0x43, 0x90, 0x41, 0xdb, - 0xd9, 0x75, 0x9c, 0x7c, 0x32, 0xc2, 0xf8, 0x9c, 0x3a, 0x30, 0x65, 0x99, 0x1f, 0x84, 0x69, 0x0b, - 0xe4, 0x70, 0x43, 0x55, 0xe4, 0x64, 0x6b, 0x1e, 0x64, 0xee, 0x76, 0xf9, 0x0b, 0x6b, 0x36, 0x9d, - 0xd7, 0xf9, 0xbd, 0x76, 0xf0, 0x98, 0x5e, 0x04, 0xb3, 0xcc, 0x02, 0x6d, 0x7f, 0x4d, 0x81, 0x05, - 0x5b, 0xf1, 0xa7, 0x72, 0xfc, 0xbf, 0x14, 0x2f, 0xbf, 0xcc, 0x16, 0xe9, 0xda, 0xc8, 0x9f, 0xf1, - 0x3e, 0x0b, 0xfe, 0x0e, 0x83, 0x2a, 0x81, 0x3a, 0x53, 0xa2, 0x21, 0x2d, 0xc7, 0x36, 0xfe, 0x9e, - 0x95, 0xef, 0x30, 0xe3, 0x38, 0x50, 0x83, 0x85, 0xc1, 0xea, 0xe8, 0xc2, 0x02, 0x96, 0xa4, 0x18, - 0x60, 0xd6, 0x32, 0xc5, 0x55, 0x04, 0x4d, 0xb4, 0x7b, 0xf9, 0xc5, 0x83, 0x6f, 0xc5, 0xbd, 0x99, - 0xa9, 0xbc, 0x27, 0x11, 0x0c, 0x82, 0x08, 0x01, 0x00, 0x73, 0x4f, 0x20, 0xb9, 0x45, 0x57, 0x40, - 0x83, 0x5c, 0x75, 0xcd, 0x5f, 0x53, 0x93, 0xf4, 0xed, 0x57, 0x79, 0x29, 0x15, 0x1e, 0x9b, 0xc2, - 0xc4, 0x82, 0x36, 0x25, 0xa0, 0xf8, 0x91, 0x8d, 0x9f, 0xa4, 0x29, 0xbb, 0x1c, 0x87, 0xb7, 0x2d, - 0x0c, 0xb3, 0x19, 0x84, 0xec, 0x38, 0x4b, 0x98, 0x7f, 0x09, 0x3c, 0x85, 0xe1, 0xf5, 0x55, 0x88, - 0x7c, 0xbe, 0x02, 0x6f, 0x9a, 0xc3, 0x52, 0x6c, 0x54, 0xbd, 0x02, 0x7e, 0x4d, 0x81, 0xbc, 0x52, - 0x0b, 0x06, 0xd6, 0x4e, 0xd4, 0x3c, 0x6f, 0x3c, 0x46, 0x1d, 0x03, 0x9e, 0x33, 0xbc, 0x53, 0x8a, - 0x5f, 0x6b, 0x45, 0x32, 0x80, 0x47, 0x46, 0x84, 0x49, 0x1a, 0x46, 0x0e, 0x24, 0x8d, 0x77, 0x56, - 0x48, 0x75, 0x45, 0x89, 0x46, 0x63, 0xed, 0x9c, 0x0d, 0x11, 0x08, 0xac, 0x52, 0x48, 0x31, 0x71, - 0xc5, 0x90, 0xe1, 0x19, 0x9b, 0x9d, 0x11, 0x91, 0x08, 0x03, 0x3f, 0x03, 0x09, 0xa6, 0x69, 0x1a, - 0xd7, 0x27, 0x3c, 0xd8, 0xf0, 0xa9, 0x83, 0xfa, 0x5b, 0x80, 0xc1, 0x3f, 0xa1, 0xe1, 0xcf, 0xe8, - 0x15, 0x57, 0xfa, 0x54, 0xaf, 0x44, 0xe6, 0x1b, 0xd1, 0x1f, 0x4f, 0x41, 0x43, 0xf5, 0xd3, 0x9d, - 0x3b, 0xd0, 0x08, 0x75, 0x0a, 0xb3, 0x4b, 0x95, 0x51, 0x96, 0x80, 0xfe, 0x20, 0x3e, 0x4c, 0x95, - 0xd7, 0x34, 0x48, 0x87, 0x18, 0x6e, 0x0c, 0x6f, 0x82, 0x23, 0x8a, 0x52, 0xc9, 0xa4, 0xc5, 0xde, - 0x67, 0x77, 0x50, 0x82, 0x29, 0x5a, 0x11, 0xde, 0x75, 0xc3, 0x6c, 0x54, 0xd1, 0x46, 0x1c, 0x71, - 0xea, 0xf8, 0xf5, 0x8e, 0x9a, 0xce, 0x38, 0xb7, 0x22, 0x83, 0x3f, 0x3b, 0x3e, 0xa6, 0x1b, 0xba, - 0x8f, 0x2f, 0x18, 0xd0, 0xa6, 0x3d, 0x4c, 0xa5, 0xd4, 0x3e, 0x46, 0x03, 0xf7, 0xe1, 0xb2, 0x14, - 0xf6, 0xd8, 0x2a, 0x36, 0x69, 0x2b, 0x19, 0xff, 0x81, 0x39, 0x68, 0x65, 0xd1, 0x75, 0x0b, 0x74, - 0xf9, 0xd5, 0x19, 0x34, 0x65, 0xa1, 0x56, 0xf5, 0x70, 0xf9, 0xc1, 0x82, 0x49, 0x37, 0x45, 0xeb, - 0x05, 0xdf, 0xed, 0x33, 0x0c, 0xcc, 0x3a, 0x2c, 0x75, 0x26, 0x1d, 0x9e, 0x21, 0xfc, 0x74, 0x29, - 0xd1, 0xb0, 0x14, 0x59, 0x3a, 0x8f, 0x9c, 0xfc, 0x4c, 0xb0, 0x0e, 0x5e, 0xcf, 0x2c, 0xaf, 0x2f, - 0xcb, 0xef, 0x95, 0xca, 0x65, 0x9c, 0xb8, 0xc6, 0x19, 0x14, 0xe3, 0x05, 0x0c, 0xe3, 0x18, 0x6f, - 0x67, 0x4a, 0xae, 0xa0, 0xfc, 0x75, 0x90, 0x5d, 0x18, 0xbe, 0x71, 0xe5, 0x87, 0xa0, 0x99, 0xbc, - 0x7e, 0xf9, 0xfa, 0x05, 0x05, 0xfa, 0x34, 0xc2, 0xe0, 0x13, 0x33, 0x34, 0x01, 0xaf, 0x5d, 0xbd, - 0x03, 0xe2, 0x52, 0x5b, 0x83, 0x41, 0x41, 0x58, 0xe3, 0x2b, 0x50, 0xb5, 0x8d, 0x38, 0xc2, 0xdb, - 0xef, 0x6b, 0x0d, 0x46, 0xe6, 0x9d, 0x97, 0xc2, 0xba, 0x5b, 0x3e, 0xe3, 0xed, 0xad, 0x14, 0xd1, - 0x77, 0xf8, 0x25, 0x4d, 0xdd, 0x71, 0x37, 0x2d, 0xb4, 0xb4, 0xf5, 0x9a, 0xd8, 0xaf, 0xa9, 0xa1, - 0x2f, 0xef, 0xd9, 0xb6, 0x3b, 0x72, 0x4b, 0x6d, 0x89, 0x6b, 0x6a, 0xa1, 0xa1, 0x3f, 0x52, 0x8c, - 0xe2, 0x7c, 0xf1, 0xa9, 0x10, 0xdf, 0x1f, 0x74, 0x6d, 0xe9, 0xd1, 0x2d, 0x7a, 0x31, 0xf2, 0x37, - 0x4f, 0xfb, 0x82, 0xc1, 0x96, 0x41, 0x51, 0x06, 0x2d, 0x8e, 0x25, 0xef, 0x62, 0x18, 0x3f, 0x9e, - 0xb7, 0x98, 0xe4, 0x95, 0xf3, 0xd8, 0x0e, 0x06, 0x19, 0x6d, 0x6a, 0x01, 0xd2, 0x79, 0xe0, 0xe5, - 0x49, 0x12, 0xa7, 0xe9, 0x5b, 0x0a, 0x92, 0x3e, 0xa2, 0x6b, 0x91, 0xe4, 0x67, 0xcf, 0x14, 0x97, - 0x47, 0x43, 0xa7, 0xfc, 0x28, 0x8e, 0x6e, 0x2f, 0xe3, 0xc5, 0xfd, 0x65, 0x60, 0xea, 0xcc, 0x4c, - 0xb7, 0x94, 0xa8, 0x07, 0x62, 0x87, 0x09, 0x8c, 0xee, 0xd6, 0x63, 0x1b, 0x37, 0x6f, 0xd9, 0xce, - 0x6f, 0xb8, 0x42, 0x95, 0xaf, 0x41, 0xa1, 0x87, 0xb7, 0x5d, 0xf3, 0x9a, 0xcd, 0xdf, 0xd8, 0x6a, - 0x75, 0x01, 0x3a, 0x2c, 0xc5, 0x14, 0x5e, 0xad, 0xd4, 0xd0, 0xe0, 0x7d, 0x5a, 0x38, 0xe1, 0x52, - 0x5c, 0x64, 0x0a, 0x92, 0xcd, 0x9f, 0xcc, 0xe7, 0x6f, 0x5f, 0x0b, 0xb6, 0xc1, 0xcb, 0xc6, 0xd9, - 0x14, 0xef, 0x4c, 0xcf, 0x40, 0xab, 0xdf, 0x1e, 0xc5, 0x79, 0xa3, 0x84, 0x93, 0xbb, 0xc8, 0x54, - 0x18, 0xe4, 0x6f, 0xe9, 0xa2, 0x33, 0x7e, 0x93, 0x59, 0x01, 0xd4, 0xef, 0x14, 0xa8, 0xcf, 0xbf, - 0x14, 0xd4, 0x8d, 0x20, 0xce, 0xca, 0xdb, 0xfb, 0x23, 0xf3, 0xb8, 0xa3, 0x07, 0xc4, 0xce, 0x71, - 0x30, 0x06, 0x76, 0x39, 0xc7, 0x2b, 0xe1, 0xf9, 0x25, 0x4a, 0x18, 0xb9, 0xbb, 0x5e, 0xff, 0x11, - 0xe8, 0x48, 0x4b, 0xb0, 0x9d, 0xa7, 0x3c, 0x9a, 0xbc, 0x8d, 0xe5, 0xf0, 0xf2, 0x62, 0xba, 0xbe, - 0xb0, 0xc6, 0xf0, 0x56, 0x20, 0x50, 0x9e, 0x58, 0x7e, 0x31, 0x11, 0x7c, 0xc2, 0xc2, 0x78, 0x09, - 0x2e, 0xfa, 0xb4, 0xe8, 0x52, 0xdf, 0xf2, 0x65, 0xf3, 0x14, 0x70, 0x1b, 0x32, 0xd4, 0x2c, 0xc6, - 0xef, 0xa2, 0xd3, 0xcc, 0xc1, 0xaf, 0x79, 0x9c, 0xf9, 0xe7, 0x0c, 0xf7, 0x5a, 0x52, 0xac, 0x74, - 0x6e, 0x55, 0xf2, 0x23, 0xbb, 0xd8, 0x9e, 0x2d, 0xc2, 0xc2, 0x0b, 0x55, 0x1c, 0xef, 0x5b, 0x5e, - 0x5f, 0x61, 0x64, 0xeb, 0x5b, 0xe6, 0xdd, 0xb2, 0xb2, 0x1b, 0x92, 0xc7, 0x82, 0xc7, 0x72, 0x23, - 0x1e, 0xf2, 0x38, 0x57, 0x29, 0x30, 0xd1, 0x21, 0x8e, 0x01, 0xd9, 0x4b, 0x8a, 0xaa, 0xed, 0x6a, - 0x41, 0xea, 0xb5, 0x4e, 0xd1, 0x95, 0x98, 0xc9, 0x64, 0xb5, 0xe2, 0x21, 0xe5, 0xed, 0x96, 0x50, - 0xc7, 0x4a, 0xb7, 0xde, 0x67, 0x30, 0x6d, 0xe8, 0xb7, 0xf9, 0x81, 0xd8, 0xcf, 0xfc, 0x1b, 0x12, - 0xbd, 0xe4, 0x3b, 0xd4, 0xae, 0xf1, 0xcb, 0xb5, 0x36, 0x6a, 0x4c, 0x5c, 0xaf, 0x4d, 0xd7, 0x5a, - 0xa2, 0x25, 0x2e, 0x94, 0xb2, 0x35, 0xd4, 0xe6, 0xa2, 0x30, 0xe6, 0xad, 0x6b, 0x10, 0xad, 0xf1, - 0x72, 0xbf, 0x63, 0xba, 0x00, 0x4f, 0xbf, 0xc6, 0x40, 0xbb, 0xea, 0xe3, 0x8f, 0x25, 0x44, 0x4a, - 0x3c, 0xea, 0xbe, 0x52, 0xd0, 0x57, 0xc4, 0x95, 0xa4, 0xe5, 0x41, 0x22, 0x04, 0x62, 0x10, 0x74, - 0x2c, 0x0f, 0x96, 0xd6, 0x6f, 0xf0, 0x33, 0x4c, 0xf0, 0x15, 0xcd, 0x95, 0x7a, 0xfd, 0x37, 0xbc, - 0xf7, 0x56, 0x3a, 0xa2, 0x1e, 0x0a, 0x64, 0x22, 0x7e, 0x08, 0x9f, 0x8e, 0xa4, 0x0c, 0x0d, 0x62, - 0xa7, 0x16, 0xa0, 0xbd, 0xfa, 0x86, 0x15, 0xee, 0xc1, 0xc3, 0x2c, 0x5b, 0x49, 0x98, 0x07, 0x62, - 0xcf, 0xf1, 0x7d, 0x6c, 0x23, 0x08, 0x16, 0xb0, 0x78, 0xca, 0xeb, 0xf8, 0x0e, 0x2f, 0x0e, 0x00, - 0x68, 0xc4, 0xeb, 0xb7, 0x4c, 0x92, 0xf8, 0xef, 0x0c, 0x85, 0x5f, 0xbe, 0x92, 0xc7, 0x97, 0x6d, - 0xc4, 0xb5, 0xdb, 0xe2, 0xfe, 0xc3, 0xdf, 0xf1, 0xfa, 0x76, 0xf4, 0x0c, 0xa0, 0x17, 0x35, 0x7f, - 0xf1, 0x50, 0x0b, 0xe5, 0x1e, 0x03, 0x41, 0x1b, 0x80, 0x55, 0xcb, 0x7e, 0x70, 0x28, 0x43, 0x51, - 0x97, 0xe2, 0x5a, 0xe7, 0x21, 0xe8, 0x8f, 0x8c, 0xe5, 0x03, 0x83, 0xfe, 0x97, 0x5f, 0xe0, 0xa6, - 0x92, 0x20, 0x11, 0x66, 0x62, 0x86, 0x71, 0xae, 0xcd, 0x8b, 0x2c, 0x9b, 0xa7, 0xee, 0xce, 0xce, - 0x22, 0x9a, 0x7f, 0x3a, 0x47, 0x5d, 0x72, 0x87, 0x3e, 0xfd, 0x4b, 0xbb, 0xd5, 0xd9, 0x1d, 0xb4, - 0x3a, 0x3b, 0xe3, 0x45, 0x10, 0x4e, 0x79, 0x9a, 0xd0, 0xee, 0x80, 0x3c, 0x4d, 0xa7, 0x54, 0xd3, - 0x0e, 0x08, 0x1b, 0xe8, 0xec, 0xce, 0xe7, 0xd4, 0xc8, 0x6e, 0x7c, 0x8c, 0x0b, 0x9f, 0x82, 0x3d, - 0x76, 0xb9, 0x63, 0x8a, 0x8a, 0xd6, 0xf4, 0xbb, 0x36, 0xb4, 0x9e, 0xed, 0xa0, 0x72, 0x0d, 0xbf, - 0xe3, 0x78, 0x7a, 0x6b, 0x88, 0xbb, 0xc2, 0xcc, 0x38, 0x42, 0xd1, 0x65, 0xd9, 0xd0, 0xc1, 0xc3, - 0x69, 0x70, 0x65, 0xd0, 0x8d, 0x04, 0x9e, 0x0c, 0xd6, 0x0f, 0x89, 0x17, 0xe7, 0x49, 0xbc, 0x98, - 0x1f, 0x19, 0x0f, 0x0e, 0x2f, 0x3a, 0x06, 0xdd, 0x48, 0xe8, 0x99, 0x33, 0x28, 0x9b, 0xb9, 0x21, - 0x9b, 0x65, 0xe6, 0xd1, 0x71, 0xe6, 0x27, 0xa0, 0x44, 0xfc, 0xed, 0xaf, 0xff, 0xf5, 0x7f, 0x1a, - 0xaf, 0x5e, 0x3c, 0x4f, 0x8d, 0xbf, 0xfd, 0xf5, 0xbf, 0xfc, 0x0f, 0x63, 0x7c, 0x0b, 0x9a, 0x85, - 0xba, 0xb0, 0x0b, 0xd2, 0xfe, 0xd3, 0xbf, 0x42, 0xfb, 0x1d, 0xa8, 0xcf, 0x37, 0x1e, 0x20, 0xfe, - 0x3d, 0xd5, 0x2d, 0x76, 0x1d, 0x5f, 0x07, 0xad, 0x73, 0x50, 0x38, 0x16, 0xe3, 0x56, 0x10, 0xef, - 0x60, 0x85, 0xcf, 0xe3, 0x49, 0x6a, 0x16, 0x5b, 0x83, 0x89, 0xe0, 0x02, 0x9a, 0xfb, 0xf7, 0xff, - 0xf6, 0x6f, 0x87, 0x3b, 0x3e, 0xf5, 0x46, 0x00, 0x76, 0x38, 0x4e, 0x8e, 0x1e, 0x00, 0x9c, 0xdd, - 0x23, 0xea, 0x40, 0x00, 0x9d, 0xe2, 0x77, 0x1d, 0xe0, 0xd5, 0x00, 0xe6, 0xd1, 0xe1, 0x0e, 0xa4, - 0xc2, 0x5f, 0xf8, 0x6e, 0x1c, 0x06, 0xd1, 0x7c, 0x21, 0xc7, 0x16, 0x78, 0x21, 0x03, 0x1d, 0x10, - 0x75, 0x9c, 0x05, 0xbc, 0x3e, 0x99, 0xcf, 0x4d, 0xe3, 0x01, 0x96, 0xbe, 0xa2, 0xc7, 0x18, 0xe6, - 0xb1, 0x60, 0xf2, 0x09, 0x2b, 0xcb, 0x7e, 0x08, 0xd8, 0xb5, 0x85, 0xb7, 0x63, 0x10, 0x9a, 0xee, - 0xa8, 0xe4, 0xb9, 0x9f, 0x5e, 0x3c, 0x8d, 0xfd, 0x64, 0x2a, 0xab, 0xc2, 0x84, 0xbf, 0xb3, 0xae, - 0x0f, 0xd0, 0x0b, 0x59, 0x0d, 0x7f, 0xfe, 0xbb, 0xaa, 0x39, 0x86, 0x79, 0x82, 0x5d, 0xca, 0x8a, - 0xe0, 0xed, 0xef, 0xac, 0x07, 0x94, 0x18, 0xd3, 0xe0, 0xe8, 0xc1, 0xa7, 0x07, 0x7f, 0x1f, 0x30, - 0x20, 0x9f, 0xe6, 0xa2, 0x1a, 0xf1, 0x7c, 0x47, 0x45, 0x20, 0x39, 0xa2, 0x23, 0x63, 0x85, 0x34, - 0x4c, 0x4f, 0x77, 0xd6, 0xec, 0x5f, 0x31, 0xd1, 0xc9, 0x31, 0x7f, 0xce, 0xeb, 0x85, 0x57, 0x20, - 0x44, 0x16, 0xde, 0x51, 0x73, 0xe8, 0x8f, 0x59, 0x78, 0xf4, 0xfe, 0x82, 0x5d, 0xb2, 0xc3, 0x1d, - 0xfe, 0x02, 0x14, 0x9f, 0x92, 0x02, 0x67, 0xa0, 0x61, 0xe2, 0x01, 0x5f, 0xc2, 0xc7, 0x26, 0x4f, - 0xe2, 0x5d, 0x28, 0xa6, 0x40, 0x7b, 0x34, 0x17, 0x53, 0x47, 0xa8, 0xa6, 0xbc, 0x3d, 0x1e, 0x1a, - 0xff, 0x81, 0x04, 0x16, 0x26, 0x91, 0x04, 0x38, 0x4c, 0x31, 0xcf, 0xe1, 0x0e, 0xcf, 0xa0, 0x72, - 0xca, 0x8c, 0xd7, 0x21, 0x28, 0x15, 0x47, 0x3f, 0x02, 0x5f, 0x6d, 0x66, 0x79, 0x20, 0xf2, 0x9c, - 0x27, 0xfe, 0x2d, 0x63, 0x91, 0x79, 0xf4, 0x0d, 0x7f, 0xd8, 0x5a, 0xd9, 0x94, 0x5d, 0x99, 0x47, - 0xcf, 0xd9, 0xd5, 0xf6, 0xaa, 0x42, 0xce, 0x63, 0xaf, 0xf0, 0x67, 0x7b, 0x35, 0x7e, 0xf2, 0x09, - 0xea, 0x81, 0xbf, 0xdb, 0x2b, 0x1a, 0xc3, 0x5f, 0xf3, 0xe8, 0x29, 0xfc, 0xdd, 0x5a, 0xcd, 0x1c, - 0x14, 0x79, 0xf3, 0xe8, 0x1d, 0xfc, 0xdd, 0x5e, 0x0d, 0x0c, 0xce, 0x04, 0xea, 0x39, 0xc6, 0x9f, - 0xad, 0x15, 0x45, 0xb7, 0x3e, 0x74, 0xfe, 0x0d, 0xfc, 0xd5, 0xb2, 0xec, 0xf0, 0x51, 0xc1, 0x27, - 0x64, 0xff, 0x07, 0x86, 0x92, 0x0d, 0x97, 0xd3, 0x10, 0x75, 0x36, 0x3f, 0x80, 0xa9, 0x4b, 0x0a, - 0x3d, 0x95, 0x1e, 0x2e, 0x2e, 0xa3, 0xb6, 0xa9, 0x84, 0xa0, 0x4c, 0x32, 0x65, 0x3d, 0x3c, 0xfb, - 0x83, 0x42, 0xfe, 0xce, 0xbd, 0xf9, 0x0b, 0xd9, 0xbb, 0x40, 0xa5, 0x5f, 0x92, 0xbf, 0x77, 0x67, - 0xf5, 0xfc, 0xe7, 0x81, 0x2a, 0x06, 0x33, 0x64, 0x14, 0x44, 0x40, 0x33, 0xf5, 0xaf, 0x0e, 0xf6, - 0x0e, 0xda, 0xc3, 0x8d, 0x6a, 0xe3, 0xa9, 0x1f, 0x22, 0x97, 0x99, 0x9a, 0xa4, 0xf7, 0x43, 0x29, - 0x26, 0x8d, 0xc3, 0xb9, 0xf1, 0x40, 0x88, 0xdd, 0x49, 0x1c, 0xc6, 0x89, 0x7b, 0x9e, 0xb0, 0x5b, - 0x68, 0xef, 0xff, 0xf9, 0x3f, 0x8d, 0x6e, 0xbb, 0xdb, 0x2f, 0x08, 0xf5, 0x7f, 0xff, 0xb7, 0xff, - 0xdb, 0x68, 0x1a, 0xaf, 0x82, 0x09, 0x8b, 0x52, 0x30, 0x19, 0x71, 0xa7, 0x42, 0x62, 0x7c, 0xf3, - 0xee, 0x55, 0xf3, 0xaa, 0x77, 0xb8, 0x33, 0xd7, 0x71, 0x35, 0xf1, 0x23, 0x30, 0x13, 0x5f, 0xb3, - 0x68, 0xa1, 0x84, 0xfa, 0x3c, 0x4e, 0x03, 0x1c, 0x2b, 0xd7, 0x1f, 0x83, 0x8a, 0x05, 0x6a, 0xc9, - 0x50, 0xdc, 0x73, 0xeb, 0xd2, 0x35, 0xb7, 0x08, 0xc9, 0xd1, 0x21, 0xe7, 0x71, 0xbd, 0x8e, 0xa7, - 0x94, 0xd2, 0x41, 0x78, 0xf9, 0xc7, 0x23, 0xde, 0x54, 0x9e, 0xb9, 0x9c, 0xb7, 0x5b, 0x91, 0xf7, - 0xc1, 0xb6, 0xcc, 0xbd, 0x8d, 0xcc, 0x28, 0x1f, 0xb4, 0x6c, 0xcf, 0xfd, 0xcc, 0x37, 0x8d, 0x8b, - 0x60, 0x0a, 0x76, 0x8a, 0x47, 0xf7, 0xb2, 0x9a, 0x47, 0x0f, 0x94, 0x14, 0x91, 0x83, 0x82, 0x33, - 0x2c, 0x4d, 0x51, 0xd9, 0x65, 0x78, 0xf4, 0xff, 0x02, 0x9e, 0x45, 0xb1, 0xe9, 0x77, 0x05, 0x01, - 0x00 + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xd5, 0x7d, 0xdb, 0x76, 0xe3, 0xc8, + 0x91, 0xe0, 0xbb, 0xbe, 0x02, 0x42, 0xd9, 0x6c, 0xa2, 0x09, 0xde, 0x29, 0x95, 0x0a, 0x14, 0x44, + 0xd7, 0x45, 0x6d, 0x97, 0x4f, 0xdd, 0x4e, 0x57, 0x75, 0xf7, 0xce, 0x91, 0x35, 0xee, 0x24, 0x91, + 0x24, 0x61, 0x81, 0x00, 0x17, 0x00, 0xa5, 0x52, 0x53, 0xfc, 0x83, 0x99, 0x97, 0x1d, 0x3f, 0xf8, + 0xcd, 0xbb, 0xb3, 0x4f, 0x7b, 0xf6, 0x75, 0x9e, 0xf7, 0x61, 0x3f, 0xc5, 0x5f, 0xe0, 0x4f, 0xd8, + 0x88, 0xc8, 0x4c, 0x20, 0x01, 0x02, 0x92, 0xaa, 0xed, 0x39, 0x33, 0x5b, 0x75, 0x44, 0x02, 0x79, + 0x89, 0x8c, 0x8c, 0x8c, 0x88, 0x8c, 0x88, 0xbc, 0xd0, 0x38, 0x3d, 0x7c, 0xf5, 0xfe, 0xe5, 0xa7, + 0x7f, 0xf8, 0x70, 0x6e, 0x2c, 0xd3, 0x55, 0x70, 0x66, 0x9c, 0xaa, 0x2f, 0xce, 0x3c, 0xf8, 0x5a, + 0xf1, 0x94, 0x19, 0xb3, 0x25, 0x8b, 0x13, 0x9e, 0xba, 0xe6, 0x26, 0x9d, 0xb7, 0x4f, 0x4c, 0x48, + 0x4e, 0xfd, 0x34, 0xe0, 0x67, 0x07, 0x1f, 0x53, 0x16, 0xbf, 0x8d, 0xbc, 0xbf, 0xfe, 0xf9, 0xbf, + 0xfd, 0x6f, 0x63, 0x7a, 0x6b, 0xbc, 0x8d, 0xa2, 0x10, 0x5e, 0x37, 0x01, 0x4f, 0x8c, 0xbf, 0xfe, + 0xf9, 0x9f, 0xfe, 0x78, 0xda, 0x15, 0xe5, 0x8c, 0xd3, 0x24, 0xbd, 0xc5, 0xf2, 0x4e, 0x1c, 0x45, + 0xa9, 0x4d, 0x9f, 0x9d, 0x04, 0xea, 0xae, 0x22, 0x6f, 0xdb, 0x6e, 0x4f, 0x17, 0xed, 0x59, 0x14, + 0x44, 0xb1, 0x13, 0xf8, 0x21, 0x67, 0x71, 0x7b, 0x11, 0x33, 0xcf, 0xe7, 0x61, 0xda, 0x4c, 0x23, + 0x63, 0x1a, 0xa5, 0x69, 0xb4, 0xb2, 0x8d, 0x27, 0xf3, 0xf9, 0x94, 0x0f, 0x87, 0x46, 0xef, 0x97, + 0xf0, 0x3c, 0x3d, 0xee, 0xcd, 0x8f, 0x07, 0x46, 0xbf, 0xd7, 0xfb, 0xa5, 0x35, 0x6e, 0xb7, 0x53, + 0xfe, 0x39, 0x95, 0x10, 0x9e, 0xf4, 0x86, 0xf8, 0x1f, 0x13, 0x97, 0x2a, 0x49, 0x94, 0x3e, 0xe9, + 0x43, 0x62, 0x29, 0x0d, 0x52, 0xa6, 0x51, 0xec, 0xf1, 0x58, 0x25, 0x1f, 0x1f, 0x1f, 0x43, 0x5a, + 0xc2, 0x03, 0x3e, 0xcb, 0x20, 0x7e, 0x43, 0xff, 0x20, 0x79, 0x1e, 0x85, 0x69, 0x3b, 0xf1, 0x7f, + 0xe2, 0x4e, 0xbf, 0xb7, 0xfe, 0xbc, 0x13, 0xbd, 0xb8, 0x09, 0x78, 0xa1, 0x0b, 0x4f, 0xfa, 0x03, + 0xfc, 0x5f, 0xc2, 0x6a, 0x3e, 0x9f, 0xeb, 0x28, 0xc5, 0x8b, 0x69, 0x73, 0x70, 0x74, 0x64, 0x1b, + 0xfd, 0xe3, 0x9e, 0x6d, 0xf4, 0x2c, 0x0d, 0xb3, 0x8a, 0xac, 0x02, 0x8a, 0x15, 0xf9, 0x05, 0x74, + 0x2b, 0xf2, 0x2b, 0xf1, 0x06, 0x1a, 0xdf, 0x72, 0x1e, 0x3e, 0x96, 0xfa, 0xcf, 0x9e, 0x3e, 0x1b, + 0x3c, 0x1b, 0x09, 0xea, 0x8f, 0x9e, 0x8e, 0x8e, 0x46, 0xd5, 0xd4, 0x9f, 0x4f, 0xe7, 0xa3, 0xf9, + 0xa8, 0x40, 0xfd, 0x41, 0x7f, 0x74, 0x32, 0x98, 0xea, 0xb4, 0xcf, 0x52, 0x8a, 0xb4, 0xcf, 0x92, + 0x8b, 0xe4, 0xcf, 0x92, 0x8b, 0xdd, 0xd0, 0x13, 0xda, 0x89, 0x73, 0x92, 0x75, 0xcc, 0xe3, 0xd7, + 0x0f, 0x8f, 0xc7, 0x6c, 0xee, 0xf5, 0x9e, 0x1d, 0x17, 0xf0, 0x9c, 0x0d, 0x9e, 0x72, 0x1a, 0xfd, + 0xfd, 0x94, 0x22, 0x9e, 0x33, 0x8f, 0x79, 0xc7, 0x6c, 0x0f, 0xcf, 0x3e, 0x3b, 0x61, 0x34, 0xca, + 0x01, 0x9b, 0xf2, 0x40, 0xa5, 0x9e, 0x0c, 0x67, 0x47, 0x1c, 0xb1, 0x9f, 0x45, 0xab, 0x15, 0x10, + 0x55, 0xa5, 0x1f, 0x3d, 0x3b, 0x61, 0xa3, 0x61, 0xdd, 0xe0, 0x04, 0xfe, 0x62, 0x99, 0x16, 0x7a, + 0x21, 0x19, 0x48, 0xeb, 0x42, 0x7f, 0x30, 0xd4, 0x91, 0xed, 0xd1, 0xbf, 0x42, 0x8f, 0x8e, 0xbd, + 0xe3, 0x93, 0x63, 0x46, 0x7c, 0x5f, 0x44, 0x55, 0x65, 0x28, 0x8a, 0xb1, 0xf8, 0xea, 0x61, 0x92, + 0x1d, 0x3f, 0x3b, 0xf6, 0x9e, 0x7a, 0xb2, 0xca, 0x34, 0xd8, 0xf0, 0x42, 0x95, 0xde, 0xd1, 0xf0, + 0xd9, 0xf1, 0x8b, 0x52, 0x95, 0xf3, 0xa7, 0xdf, 0xf4, 0xbf, 0x39, 0x7f, 0xbc, 0x2c, 0x16, 0xb1, + 0x54, 0x45, 0x65, 0x93, 0x6b, 0x3f, 0xbc, 0x2a, 0x91, 0x64, 0xc6, 0xbc, 0x51, 0xa9, 0x49, 0xfe, + 0xf4, 0x68, 0x74, 0xd2, 0xdb, 0x83, 0x25, 0x92, 0x25, 0xa4, 0x64, 0xcd, 0x66, 0x25, 0xec, 0x05, + 0xe5, 0x74, 0x46, 0x1e, 0x4c, 0xbd, 0x3e, 0x8d, 0xfd, 0xa2, 0xbd, 0x89, 0x03, 0x07, 0xfe, 0x9a, + 0x5f, 0x79, 0x2c, 0x65, 0x0e, 0x5b, 0xaf, 0x03, 0x7f, 0xc6, 0x52, 0x3f, 0x0a, 0xbb, 0xd1, 0x2c, + 0xe5, 0x30, 0x7a, 0x69, 0xcc, 0xd9, 0x6a, 0x3c, 0x65, 0x09, 0x3f, 0x1e, 0xd9, 0x5f, 0x65, 0x22, + 0x37, 0x67, 0x2b, 0x3f, 0xb8, 0x75, 0xbe, 0xfa, 0x10, 0xf3, 0x24, 0x31, 0x50, 0x55, 0xa6, 0xc6, + 0xe0, 0xc3, 0x57, 0xf6, 0x6c, 0x13, 0x27, 0xfe, 0x35, 0x97, 0xd8, 0x84, 0xb7, 0x2c, 0x2c, 0x22, + 0xd3, 0x1f, 0x0e, 0x8f, 0x9f, 0x56, 0x2a, 0x90, 0xbf, 0x03, 0x32, 0x2f, 0xa3, 0x95, 0x3f, 0x33, + 0xde, 0xf1, 0x0d, 0x2f, 0x21, 0x02, 0x38, 0xcc, 0xda, 0x7d, 0x18, 0xfc, 0x3e, 0x0e, 0xce, 0xac, + 0x3d, 0x57, 0x8d, 0xce, 0xda, 0x03, 0x90, 0xc2, 0xc1, 0x80, 0x1e, 0x87, 0xce, 0x93, 0xe1, 0x70, + 0x48, 0x8f, 0x23, 0xe7, 0xc9, 0x68, 0x34, 0xa2, 0xc7, 0x23, 0x60, 0xe8, 0xa3, 0x23, 0x7a, 0x3c, + 0x56, 0x4a, 0x74, 0xd6, 0x3e, 0x01, 0xf6, 0x3f, 0x39, 0xa1, 0xc7, 0x29, 0x0c, 0xe7, 0x94, 0xc4, + 0xa0, 0x3d, 0x03, 0x09, 0x9a, 0xcd, 0xe8, 0x91, 0xc3, 0xc0, 0x70, 0x4e, 0x8f, 0x9e, 0xf3, 0xc4, + 0xf3, 0x3c, 0x7a, 0x44, 0x11, 0x1b, 0x8a, 0xd6, 0x16, 0xd0, 0xf0, 0x4c, 0xa0, 0x13, 0x40, 0x6b, + 0x27, 0x8c, 0x1e, 0x6f, 0x9d, 0x27, 0xec, 0x19, 0x0d, 0x18, 0xc0, 0xed, 0x75, 0x44, 0xbb, 0x11, + 0x6a, 0x3e, 0xd6, 0x1c, 0x8e, 0x6c, 0x43, 0xfd, 0xf5, 0x3a, 0xcf, 0x2c, 0xca, 0x4b, 0xa7, 0xfb, + 0x99, 0xd7, 0x2c, 0x6e, 0x12, 0x04, 0x4b, 0x95, 0x61, 0xa2, 0x50, 0xbf, 0x37, 0x00, 0xe5, 0x99, + 0x7d, 0xec, 0x97, 0x5b, 0x8a, 0x72, 0x47, 0x7d, 0xdb, 0x50, 0x7f, 0xc5, 0x42, 0xe9, 0xd2, 0x79, + 0x2a, 0x34, 0x54, 0xba, 0x56, 0x4f, 0x50, 0xeb, 0x78, 0x28, 0xd2, 0xa6, 0x6b, 0xa7, 0x3f, 0x5a, + 0x7f, 0x36, 0xc4, 0x47, 0x4f, 0x3e, 0x61, 0x19, 0xc8, 0x79, 0x06, 0xaf, 0x3d, 0xe3, 0x29, 0x7e, + 0x52, 0x2d, 0xcf, 0x09, 0xa3, 0x10, 0x49, 0x94, 0x2c, 0xd6, 0x8e, 0x39, 0x0d, 0xa2, 0xd9, 0x95, + 0x89, 0x19, 0xab, 0xd4, 0x41, 0x75, 0x31, 0x8d, 0xbc, 0xdb, 0xad, 0x3e, 0xbe, 0xcf, 0x63, 0x9f, + 0x05, 0xf6, 0x6f, 0x78, 0x70, 0xcd, 0x53, 0x60, 0x0c, 0x3b, 0x61, 0x61, 0x02, 0xb2, 0x10, 0xfb, + 0x73, 0x60, 0x89, 0xd9, 0xd5, 0x22, 0x8e, 0x36, 0xa1, 0x27, 0x18, 0x5e, 0x70, 0x96, 0x44, 0x3d, + 0x63, 0x35, 0x6b, 0x9c, 0x6b, 0x24, 0x91, 0x97, 0xbd, 0x5b, 0xbb, 0x65, 0xdf, 0x5e, 0x0e, 0xb6, + 0x7a, 0xc5, 0xa5, 0xaa, 0x85, 0x93, 0x47, 0x7b, 0xc9, 0x51, 0x71, 0x39, 0x47, 0x80, 0x99, 0xe7, + 0x5f, 0x6f, 0xf5, 0xb4, 0xc1, 0x8e, 0xf4, 0xe2, 0x76, 0xc5, 0xe2, 0x85, 0x1f, 0xb6, 0x63, 0x4a, + 0x3c, 0x86, 0x7e, 0xeb, 0xd0, 0x34, 0xd5, 0x69, 0xed, 0xa4, 0xc6, 0x14, 0xdd, 0x23, 0xfb, 0xc1, + 0xf1, 0x53, 0x06, 0xec, 0x3e, 0x96, 0x30, 0x02, 0x3e, 0xdf, 0x07, 0x51, 0xd0, 0xb3, 0xd6, 0xce, + 0x0f, 0xd7, 0x9b, 0x74, 0xab, 0x75, 0xbd, 0x67, 0x3c, 0xa6, 0xe7, 0x38, 0x9d, 0x08, 0x0d, 0xf2, + 0xf3, 0xea, 0x46, 0x6b, 0x14, 0xc9, 0x6d, 0x5d, 0x61, 0x0d, 0xa6, 0xc8, 0x54, 0xd2, 0x6f, 0xed, + 0x58, 0x35, 0x79, 0xa9, 0xb6, 0xc7, 0x67, 0x51, 0x4c, 0xc2, 0x4e, 0x5c, 0xb1, 0xc3, 0x44, 0x06, + 0xe2, 0xbe, 0xbd, 0xf1, 0x3d, 0x60, 0x3a, 0x9c, 0x90, 0xc7, 0x92, 0xdc, 0xf4, 0x2c, 0xe7, 0x2d, + 0x9c, 0xcf, 0x37, 0x89, 0xd3, 0x1f, 0x00, 0xa9, 0x1e, 0xd7, 0x9b, 0xdd, 0x8c, 0x85, 0xd7, 0x2c, + 0xf9, 0x12, 0xb8, 0x94, 0xe4, 0xf4, 0x81, 0x71, 0x93, 0x28, 0xf0, 0x3d, 0x83, 0x58, 0xac, 0xdc, + 0x1a, 0xe8, 0x1b, 0x68, 0xce, 0xe3, 0x73, 0xb6, 0x09, 0xd2, 0x5d, 0x07, 0xac, 0x3f, 0x16, 0x6c, + 0xd7, 0x51, 0xe2, 0x53, 0x9f, 0xe6, 0xfe, 0x67, 0xee, 0x8d, 0x69, 0x54, 0xa1, 0x2a, 0x59, 0x1e, + 0xf0, 0x20, 0x38, 0xa5, 0x37, 0x4e, 0xa3, 0xb5, 0xa3, 0x43, 0x6c, 0x17, 0x46, 0xbd, 0x1d, 0x01, + 0x8d, 0x62, 0x60, 0xf6, 0x79, 0x14, 0xaf, 0x1c, 0x7a, 0x0a, 0x58, 0xca, 0xff, 0xa1, 0x29, 0xac, + 0x14, 0x4a, 0x10, 0xad, 0x64, 0xa5, 0x8c, 0xce, 0x28, 0x19, 0xaf, 0x99, 0xe7, 0xf9, 0xe1, 0x02, + 0x07, 0x6d, 0x1c, 0x5d, 0xf3, 0x78, 0x1e, 0x44, 0x37, 0x0e, 0xdb, 0xa4, 0x51, 0xa9, 0x93, 0x23, + 0xe8, 0xe4, 0xae, 0x13, 0x22, 0x57, 0xeb, 0xdc, 0x47, 0x73, 0x76, 0x27, 0x65, 0xd3, 0x80, 0x3f, + 0x5a, 0x0c, 0x33, 0x63, 0x22, 0x60, 0xeb, 0x84, 0x3b, 0xea, 0x61, 0xac, 0x11, 0xbb, 0x44, 0xe0, + 0x5e, 0x46, 0x60, 0x29, 0x07, 0x4b, 0xdf, 0xf3, 0x78, 0x08, 0x69, 0x9f, 0xdb, 0xc9, 0x92, 0x79, + 0x80, 0x32, 0x90, 0x17, 0xfe, 0x23, 0xf9, 0x51, 0xfd, 0x4a, 0x94, 0x8c, 0xd4, 0xb3, 0xd5, 0xd3, + 0x72, 0x5b, 0x3d, 0x44, 0x8a, 0x00, 0x28, 0x47, 0xd0, 0x7f, 0xc4, 0x36, 0x68, 0x83, 0x94, 0x2d, + 0x80, 0x52, 0xd1, 0x7a, 0x97, 0x57, 0x27, 0xf6, 0x10, 0x19, 0xd8, 0xf5, 0xba, 0x91, 0x48, 0x33, + 0x96, 0xad, 0x15, 0xec, 0xce, 0xca, 0x0b, 0x5e, 0x02, 0xb1, 0x18, 0xa8, 0x87, 0x78, 0xb0, 0xf5, + 0xfc, 0x64, 0x1d, 0xb0, 0x5b, 0x67, 0x11, 0xfb, 0xde, 0x18, 0x3f, 0x80, 0x13, 0x57, 0x6b, 0x1c, + 0x3d, 0xac, 0xb0, 0x59, 0x85, 0x89, 0x13, 0xf3, 0x35, 0x67, 0x69, 0x73, 0x60, 0xf7, 0xe7, 0xe5, + 0xfa, 0xc3, 0x2f, 0xa8, 0x3f, 0xac, 0xa8, 0x3f, 0xfa, 0x82, 0xfa, 0x23, 0x59, 0x1f, 0x66, 0x5d, + 0x60, 0x5d, 0x1b, 0xf9, 0x17, 0x5c, 0x1d, 0xbb, 0x93, 0xdc, 0x26, 0xf4, 0xbe, 0x81, 0x11, 0x46, + 0x8f, 0x46, 0x52, 0x7a, 0x90, 0x51, 0x5a, 0x0a, 0xb9, 0x66, 0x46, 0xde, 0xa7, 0x03, 0xaa, 0x86, + 0x5f, 0x0d, 0x13, 0xa8, 0x56, 0xa9, 0xfe, 0xe8, 0x51, 0x4a, 0xd4, 0x0a, 0x58, 0x57, 0xa1, 0xd5, + 0x41, 0x36, 0xb6, 0x45, 0x1f, 0x11, 0x7b, 0xf5, 0x4e, 0xb8, 0xca, 0x17, 0x81, 0xb0, 0x7c, 0x91, + 0x58, 0xd3, 0x9b, 0x8e, 0xba, 0x07, 0x12, 0xc8, 0x2b, 0x71, 0xdf, 0x3d, 0x99, 0x45, 0x61, 0xe8, + 0x87, 0x5e, 0x59, 0x76, 0xa5, 0xd0, 0x02, 0x0b, 0xcd, 0x9a, 0xb2, 0xde, 0xd2, 0x32, 0x5a, 0x06, + 0xa0, 0x6a, 0x09, 0xc1, 0x1e, 0x95, 0xfa, 0x52, 0xec, 0xea, 0x51, 0x41, 0x43, 0x29, 0xdb, 0x07, + 0x27, 0xfb, 0x9f, 0xda, 0xd0, 0x1c, 0xff, 0xec, 0xb4, 0x07, 0xc0, 0x92, 0x51, 0x14, 0xa4, 0xfe, + 0x3a, 0x6f, 0x3c, 0xe6, 0x30, 0x5a, 0x60, 0xc8, 0x8c, 0xd5, 0x50, 0xfa, 0x21, 0x4d, 0x3d, 0x34, + 0x5d, 0xaa, 0x26, 0x24, 0x6e, 0xfd, 0xbc, 0x67, 0xc8, 0xff, 0x19, 0x34, 0x43, 0x3d, 0x20, 0x9f, + 0x6f, 0xaf, 0xfd, 0xc4, 0x9f, 0xfa, 0x81, 0x9f, 0xde, 0x2a, 0x59, 0x93, 0xd2, 0x39, 0xe8, 0x55, + 0xa1, 0x58, 0x1e, 0xc0, 0xfd, 0x29, 0xab, 0x7e, 0x8a, 0x1a, 0x6b, 0x82, 0x35, 0x83, 0x64, 0x1e, + 0xeb, 0x04, 0x32, 0x7a, 0x25, 0x12, 0xa1, 0x9c, 0x66, 0x1d, 0x67, 0x53, 0xe0, 0xaf, 0x4d, 0xca, + 0x33, 0xf2, 0xf4, 0xd5, 0x10, 0xf4, 0x07, 0x47, 0xbf, 0x14, 0x14, 0x3f, 0x02, 0x7d, 0xa2, 0xab, + 0xac, 0xf6, 0x31, 0x76, 0x21, 0x02, 0x1b, 0x18, 0x7b, 0xd7, 0xd3, 0x55, 0xa3, 0x4c, 0x34, 0x3a, + 0xc3, 0xa4, 0x9a, 0x2e, 0x8e, 0xc3, 0xe6, 0x80, 0x20, 0x4c, 0x51, 0x80, 0x67, 0x98, 0x3a, 0xa6, + 0x59, 0x81, 0x0b, 0x2a, 0x6a, 0xd2, 0x62, 0xd5, 0xcd, 0x6b, 0xa3, 0x2e, 0x68, 0x7a, 0x54, 0xd6, + 0x6e, 0x24, 0x33, 0xe3, 0xa2, 0xd3, 0x05, 0xe6, 0xa5, 0x41, 0x98, 0xae, 0x61, 0xc2, 0x0b, 0xd3, + 0xba, 0xe7, 0x0c, 0x6d, 0x67, 0x89, 0xec, 0x5c, 0x3b, 0xa8, 0xf4, 0x18, 0xf0, 0x8c, 0x0c, 0xfd, + 0x5d, 0x47, 0x4c, 0xf7, 0xe0, 0xcc, 0xef, 0x09, 0xa6, 0xee, 0x4a, 0x58, 0xbb, 0x83, 0xd3, 0xae, + 0x08, 0x66, 0x18, 0xa7, 0xc9, 0x2c, 0x06, 0xd0, 0x67, 0x07, 0xdd, 0xae, 0xf1, 0x2b, 0x18, 0x64, + 0x1e, 0x26, 0xdc, 0x30, 0x8c, 0x5f, 0xbf, 0xfb, 0xce, 0xf8, 0xf5, 0xf9, 0xbb, 0xf3, 0x6f, 0x9f, + 0xbf, 0x31, 0x3e, 0x7c, 0xf7, 0xe2, 0xcd, 0xeb, 0x97, 0x06, 0xfc, 0x9d, 0xbf, 0xfb, 0x78, 0x6e, + 0x7c, 0xcf, 0xc1, 0xe0, 0x8e, 0x42, 0x63, 0x68, 0x1b, 0x83, 0x67, 0xc6, 0x6f, 0x37, 0x21, 0x37, + 0x06, 0xbd, 0xde, 0xd3, 0x12, 0x80, 0x6f, 0xa2, 0xd8, 0x80, 0xf9, 0xdd, 0xf8, 0xf5, 0x87, 0x37, + 0xed, 0xeb, 0xa1, 0xb1, 0x49, 0xd8, 0x82, 0xdb, 0x06, 0x71, 0x4d, 0x3c, 0x83, 0x79, 0xc5, 0x90, + 0x45, 0x13, 0x63, 0xb5, 0x49, 0x52, 0x63, 0xca, 0x8d, 0xf5, 0x26, 0x9e, 0x2d, 0xc1, 0xe2, 0xf7, + 0x3a, 0x06, 0x29, 0xb6, 0x59, 0x6a, 0xac, 0xa2, 0x28, 0x14, 0x32, 0x9f, 0xfc, 0xca, 0x9f, 0x05, + 0xd1, 0xc6, 0xeb, 0x00, 0x84, 0x83, 0xf9, 0x26, 0x9c, 0xe1, 0x70, 0x19, 0xa0, 0x2c, 0xde, 0xb1, + 0x15, 0x6f, 0x5a, 0xdb, 0x98, 0xa7, 0x9b, 0x38, 0x34, 0x5f, 0xf1, 0x55, 0x64, 0xee, 0xb2, 0x7c, + 0xd4, 0x0a, 0xdf, 0x6c, 0xc2, 0x26, 0xb7, 0xb6, 0xfe, 0xbc, 0xd9, 0x77, 0x5d, 0x7e, 0xd1, 0xbb, + 0x6c, 0x34, 0xfe, 0x90, 0x44, 0xe1, 0xf7, 0x0c, 0xbc, 0xbf, 0xa4, 0xb3, 0xbe, 0xf6, 0xf9, 0x8d, + 0xb5, 0x5d, 0xbc, 0xf6, 0x9a, 0x26, 0x3d, 0x9b, 0xd6, 0x58, 0xc0, 0x3a, 0xec, 0xed, 0xe4, 0x43, + 0x9f, 0xc8, 0x25, 0xc8, 0xf4, 0xff, 0x25, 0xbd, 0x02, 0x9e, 0x1a, 0x9e, 0xeb, 0x45, 0xb3, 0x0d, + 0x8a, 0xac, 0x7d, 0x93, 0xb8, 0xe1, 0x26, 0x08, 0xec, 0x30, 0x7e, 0x3f, 0x7f, 0xab, 0x34, 0x6c, + 0xe2, 0x8e, 0xec, 0x9c, 0x2e, 0xee, 0x76, 0x67, 0x6f, 0x7c, 0x20, 0x1d, 0x78, 0x5a, 0x2b, 0x16, + 0x7a, 0x89, 0x7b, 0x71, 0x69, 0x03, 0x64, 0x1e, 0xe0, 0x43, 0xc2, 0xae, 0xb9, 0xf7, 0x3d, 0x10, + 0x8b, 0xe0, 0x80, 0x5a, 0x08, 0x01, 0xa3, 0xef, 0x5e, 0xbf, 0xfb, 0x74, 0xf2, 0xfb, 0xb7, 0xcf, + 0xff, 0x8b, 0x8b, 0x91, 0x1b, 0x7c, 0xeb, 0x1f, 0xd3, 0xeb, 0xf1, 0xd1, 0xd1, 0xf0, 0xc8, 0x06, + 0xcf, 0xf7, 0xd3, 0xed, 0x9a, 0xbf, 0x7e, 0xef, 0xf6, 0xd4, 0xf3, 0xb7, 0x9c, 0x79, 0xef, 0xc3, + 0xe0, 0xd6, 0xed, 0xe7, 0x29, 0x30, 0x60, 0x00, 0xdb, 0x1d, 0xa8, 0x94, 0x8f, 0x6b, 0xdf, 0x1d, + 0x66, 0x95, 0xc1, 0x9e, 0x03, 0xa9, 0xc2, 0x06, 0xc6, 0xd8, 0x27, 0x98, 0x01, 0x5e, 0x87, 0xf3, + 0x08, 0x90, 0x1d, 0x67, 0x43, 0xbe, 0xe0, 0xe9, 0x07, 0x51, 0x1a, 0x47, 0x5d, 0x8c, 0xa0, 0xd1, + 0x73, 0x5d, 0x59, 0xb6, 0x23, 0x41, 0x25, 0x17, 0xfc, 0x72, 0x62, 0xfe, 0xf5, 0xcf, 0x7f, 0xfe, + 0x57, 0xd3, 0xe9, 0xd7, 0xe7, 0xfe, 0x77, 0xd3, 0x19, 0xd4, 0xe7, 0xfe, 0x4f, 0xd3, 0x81, 0xaf, + 0x3f, 0xfe, 0x9b, 0xc6, 0x71, 0xc8, 0x48, 0x79, 0xbb, 0x5e, 0x07, 0xd0, 0x39, 0x0f, 0x38, 0x92, + 0xfd, 0xc5, 0x2d, 0x65, 0xe5, 0x45, 0x67, 0xe7, 0x85, 0x92, 0x33, 0xb0, 0x81, 0x53, 0x2e, 0x0b, + 0x17, 0x0a, 0x2e, 0x61, 0x00, 0x02, 0xfe, 0x7d, 0x26, 0xf8, 0x2f, 0x21, 0x61, 0x81, 0x4c, 0x8f, + 0x84, 0x8f, 0x60, 0x3e, 0x0c, 0xa2, 0x45, 0xd3, 0xac, 0x2e, 0x65, 0x6a, 0x70, 0xa2, 0xf0, 0x4d, + 0xc4, 0x3c, 0xa8, 0x07, 0x48, 0x7d, 0x5a, 0x72, 0x94, 0x1b, 0x7b, 0xc5, 0xae, 0xf8, 0x0f, 0x1f, + 0xe1, 0xc1, 0x0f, 0xfd, 0x34, 0x67, 0x06, 0x48, 0xf0, 0x3a, 0xa0, 0xc0, 0xcf, 0xaf, 0x01, 0x99, + 0x37, 0x7e, 0x02, 0x8a, 0x92, 0xc7, 0x4d, 0x33, 0x57, 0x3e, 0x33, 0x01, 0xdd, 0xae, 0x6e, 0xd5, + 0x3e, 0xec, 0x6b, 0xed, 0xaa, 0x36, 0x50, 0x06, 0x6f, 0x12, 0x4b, 0xf4, 0x98, 0x06, 0x90, 0xbb, + 0x80, 0x77, 0x9a, 0xae, 0x13, 0xc7, 0x74, 0xdd, 0x1b, 0xd0, 0xfe, 0xd1, 0x0d, 0x74, 0x46, 0x84, + 0x02, 0x3a, 0xeb, 0x38, 0x4a, 0x23, 0xd0, 0x57, 0x13, 0xf3, 0x26, 0x49, 0x80, 0xd2, 0x37, 0x89, + 0x69, 0xb5, 0x4c, 0xa7, 0xdb, 0x35, 0x5b, 0xe5, 0xa2, 0xcb, 0x28, 0x49, 0x43, 0x50, 0x04, 0x2d, + 0xb3, 0x0b, 0xa5, 0xc6, 0x05, 0xba, 0x88, 0xd6, 0x8d, 0x4d, 0x1c, 0x98, 0x36, 0xb7, 0x88, 0xf9, + 0xf9, 0x8d, 0xf1, 0x03, 0x9f, 0x7e, 0x84, 0x79, 0x95, 0x23, 0xa5, 0x21, 0xad, 0x33, 0xf5, 0x43, + 0x16, 0xdf, 0xe2, 0xe8, 0xba, 0x26, 0x8b, 0x63, 0x76, 0x3b, 0xdd, 0xcc, 0xe7, 0x3c, 0x36, 0x31, + 0x0f, 0x64, 0x8a, 0x27, 0x28, 0x8f, 0x2e, 0x77, 0xcf, 0xb0, 0x13, 0xbc, 0x83, 0x71, 0x0b, 0xc3, + 0x07, 0xb6, 0x67, 0xe1, 0x8c, 0x47, 0x73, 0xe3, 0x39, 0x56, 0x79, 0x41, 0x55, 0xac, 0x2d, 0xf6, + 0x2c, 0xa0, 0x56, 0xbe, 0xf3, 0xc3, 0xf4, 0x84, 0xf2, 0x64, 0x1d, 0x6b, 0x0c, 0xd5, 0x81, 0x1b, + 0x03, 0xd0, 0x43, 0xd6, 0x76, 0x1d, 0x73, 0x54, 0x39, 0x2f, 0x22, 0x16, 0x7b, 0x4d, 0x52, 0x41, + 0x53, 0x7c, 0x34, 0x2d, 0x3b, 0xb0, 0x76, 0x3c, 0x00, 0xbd, 0xa0, 0x14, 0x98, 0x7c, 0xdf, 0xce, + 0x02, 0xce, 0xe2, 0x4f, 0xfe, 0x8a, 0x47, 0x9b, 0xb4, 0x89, 0xe2, 0x2a, 0x9f, 0x2d, 0x5b, 0x7b, + 0x11, 0xd2, 0x4d, 0xf0, 0xa4, 0x89, 0x63, 0x5a, 0x1d, 0x52, 0xf7, 0x9d, 0x7c, 0x5a, 0x78, 0x89, + 0x13, 0x81, 0x6b, 0x2a, 0xcf, 0x23, 0xb0, 0xcc, 0xb1, 0xc4, 0x1b, 0x45, 0x3a, 0x8d, 0x6f, 0xb7, + 0x81, 0xfb, 0xdb, 0x8f, 0xef, 0xdf, 0x75, 0xd6, 0x18, 0x35, 0x57, 0xe8, 0x83, 0x4f, 0x95, 0xce, + 0x96, 0x4d, 0x06, 0x9d, 0x14, 0xad, 0x28, 0x52, 0xf3, 0x38, 0x8e, 0xe2, 0x8c, 0xd8, 0x88, 0x8c, + 0x41, 0x49, 0xa6, 0xcd, 0x6c, 0x55, 0x17, 0xba, 0x1e, 0x58, 0xf8, 0xd1, 0x49, 0x81, 0xce, 0x8d, + 0xc6, 0x85, 0x29, 0x8c, 0x3d, 0xd3, 0x36, 0xa5, 0xf9, 0x06, 0x4f, 0xc2, 0xaa, 0x33, 0x2f, 0x3b, + 0x7e, 0x38, 0x0b, 0x36, 0x1e, 0x4f, 0x64, 0x71, 0x4b, 0xd0, 0x95, 0xbb, 0x87, 0x7d, 0xb0, 0x4c, + 0xe2, 0x26, 0xbe, 0x30, 0x03, 0x48, 0x4f, 0x5a, 0xc9, 0x62, 0x1d, 0xd0, 0x0b, 0x6e, 0x00, 0x9f, + 0x8d, 0x46, 0x13, 0x0a, 0xf5, 0x88, 0xd2, 0xdc, 0x2a, 0x8a, 0x48, 0xba, 0x0a, 0x64, 0x15, 0x50, + 0x91, 0x06, 0x0b, 0x40, 0xe4, 0xbc, 0x5b, 0x50, 0x19, 0xc0, 0xdc, 0x20, 0x7b, 0xd0, 0x7c, 0x60, + 0x8d, 0x89, 0xce, 0xa2, 0xa9, 0x60, 0x4c, 0xc0, 0x3b, 0xeb, 0x4d, 0xb2, 0x44, 0x3e, 0x29, 0x00, + 0x83, 0x6e, 0xc6, 0x7c, 0xc6, 0xc1, 0x62, 0x33, 0x84, 0xe8, 0xfe, 0xe6, 0xd3, 0xdb, 0x37, 0xc4, + 0x62, 0xf9, 0x2b, 0x56, 0x32, 0x3f, 0xde, 0x82, 0xf8, 0xac, 0x80, 0xc1, 0xb9, 0xc0, 0xae, 0x00, + 0x25, 0xa1, 0x4c, 0x43, 0x88, 0x53, 0x42, 0xd5, 0x79, 0x07, 0x99, 0x02, 0x0a, 0xe6, 0x6a, 0x56, + 0x24, 0x61, 0x56, 0x8a, 0x72, 0xdb, 0x68, 0x88, 0xf2, 0xd8, 0x84, 0x10, 0x64, 0x99, 0x61, 0x01, + 0x2f, 0x97, 0x45, 0x23, 0xe6, 0xf3, 0x9c, 0x96, 0xe6, 0xa8, 0x33, 0xec, 0x0c, 0x3a, 0x7d, 0xd3, + 0x9a, 0xe4, 0x20, 0xb0, 0x09, 0x90, 0xed, 0x8f, 0x20, 0x97, 0x6b, 0xd3, 0x72, 0x4a, 0x19, 0x19, + 0x16, 0x77, 0x77, 0xe6, 0xf5, 0xf3, 0x35, 0x94, 0x10, 0xac, 0x25, 0x9e, 0x3b, 0xd7, 0x38, 0x5f, + 0xb8, 0xd9, 0x44, 0x6c, 0xcf, 0x03, 0x20, 0xd6, 0x77, 0xaf, 0xb5, 0xa9, 0xa3, 0x69, 0xed, 0x04, + 0x33, 0x93, 0x20, 0x74, 0xfc, 0x44, 0x08, 0x44, 0x00, 0x28, 0xe8, 0x94, 0xf0, 0xf8, 0xb5, 0x41, + 0x92, 0x07, 0xd3, 0x20, 0x10, 0xff, 0xf3, 0x9a, 0x0c, 0x19, 0x1c, 0x12, 0x47, 0xd2, 0xf9, 0x15, + 0x70, 0x11, 0x4a, 0xc2, 0x4e, 0x08, 0x25, 0xcc, 0x6f, 0x89, 0x10, 0xc9, 0xf2, 0xb8, 0x50, 0x8e, + 0x01, 0x6d, 0xc3, 0x08, 0x01, 0x27, 0x13, 0x55, 0xbf, 0x4c, 0x1c, 0x62, 0xcb, 0xb4, 0x13, 0xd0, + 0x92, 0x52, 0xd2, 0x04, 0x5b, 0xdb, 0xfd, 0xa3, 0x5e, 0xcf, 0x52, 0xd3, 0xa7, 0xc4, 0x22, 0x5a, + 0xf3, 0xb0, 0x12, 0x09, 0xcc, 0xa0, 0x96, 0x63, 0xfe, 0x5f, 0x93, 0x37, 0x7c, 0xc1, 0x02, 0xe0, + 0x4a, 0x59, 0x89, 0x44, 0xa3, 0xb2, 0x96, 0x14, 0x1a, 0x50, 0xff, 0xb9, 0xfe, 0x14, 0x4b, 0x1a, + 0x9f, 0xa2, 0x37, 0xd1, 0x82, 0xc5, 0x7e, 0xba, 0x5c, 0x35, 0x39, 0x50, 0x65, 0x2b, 0x35, 0x89, + 0xa5, 0xe6, 0xb8, 0x31, 0x20, 0x6f, 0x30, 0xe0, 0x95, 0x95, 0x1f, 0x4e, 0xe8, 0xd3, 0xe9, 0xd9, + 0x21, 0xbe, 0xb3, 0xcf, 0x13, 0xfa, 0x74, 0x70, 0x66, 0x4e, 0x5d, 0x36, 0x79, 0xcb, 0xd2, 0x25, + 0x35, 0xc9, 0x2c, 0x28, 0x13, 0xb9, 0xcd, 0x2c, 0x21, 0xb4, 0xda, 0xa9, 0xd5, 0x6d, 0x86, 0x6d, + 0x66, 0x91, 0x3e, 0x88, 0x5d, 0xca, 0x82, 0xe1, 0x68, 0xa6, 0xad, 0xe8, 0xeb, 0x26, 0xb8, 0xd5, + 0x96, 0xb2, 0x90, 0x0c, 0xca, 0x22, 0xf2, 0x35, 0x63, 0x7d, 0x62, 0xd3, 0xf8, 0xdf, 0x96, 0x7a, + 0x82, 0xe1, 0xa4, 0x4d, 0x38, 0x1f, 0x16, 0xd9, 0x40, 0x09, 0x36, 0x20, 0x8a, 0x12, 0x5b, 0xcc, + 0x0c, 0x05, 0x7b, 0x59, 0x8d, 0x06, 0xd4, 0x3e, 0x74, 0x19, 0x01, 0x60, 0xa7, 0x32, 0xb9, 0x13, + 0xf0, 0x70, 0x91, 0x2e, 0x1b, 0x0d, 0x6c, 0xc1, 0x75, 0x65, 0xea, 0x05, 0xbb, 0x54, 0x53, 0x0c, + 0x14, 0x36, 0x31, 0xda, 0x61, 0xa2, 0x66, 0x98, 0x05, 0x2c, 0x49, 0x90, 0x49, 0x1b, 0x0d, 0x76, + 0xe6, 0x16, 0x41, 0x28, 0x1a, 0x5e, 0x47, 0xe0, 0xe7, 0x16, 0x86, 0x24, 0xef, 0x8b, 0x81, 0x90, + 0x0c, 0x69, 0xad, 0x87, 0x91, 0xec, 0x25, 0xf0, 0xa7, 0x1d, 0x82, 0x8e, 0x2b, 0xc1, 0xdb, 0x09, + 0x94, 0x02, 0x90, 0xe2, 0xc0, 0x25, 0xd6, 0xcb, 0x5c, 0x59, 0xb3, 0x05, 0xde, 0xec, 0x2f, 0x8b, + 0xb6, 0x97, 0x25, 0x88, 0x9d, 0x02, 0x9a, 0x21, 0x68, 0x1c, 0xc4, 0x12, 0x8c, 0xfe, 0x37, 0x20, + 0xc3, 0x01, 0x7f, 0x13, 0xdd, 0xf0, 0xf8, 0x25, 0xd8, 0x79, 0x20, 0x5c, 0x91, 0x20, 0x66, 0x2c, + 0xbe, 0x7c, 0xf1, 0xe5, 0x01, 0x5f, 0xd9, 0x89, 0x0b, 0xe6, 0x84, 0x49, 0x11, 0x0a, 0x10, 0xd0, + 0x99, 0x3b, 0x07, 0x36, 0xff, 0x40, 0xb8, 0x7e, 0x0f, 0x2c, 0x1d, 0x82, 0xe6, 0x21, 0x85, 0x38, + 0x03, 0x62, 0xc1, 0xf3, 0xa1, 0x3b, 0x23, 0x5d, 0x24, 0x3e, 0x31, 0xa5, 0x93, 0x6c, 0xa6, 0x49, + 0x1a, 0x83, 0xc3, 0xd6, 0xec, 0xd9, 0x98, 0xac, 0x7a, 0xe2, 0x52, 0xd1, 0x49, 0x02, 0x3a, 0x04, + 0xd8, 0xf6, 0x13, 0xb8, 0x20, 0x2e, 0x9a, 0x0a, 0x2f, 0xd9, 0xba, 0x59, 0xaa, 0xa7, 0xd7, 0xb2, + 0x9c, 0xba, 0x0a, 0xd8, 0x09, 0x44, 0x15, 0x87, 0x05, 0x9e, 0x51, 0x6d, 0x63, 0x72, 0xab, 0x29, + 0x46, 0x78, 0x62, 0x3e, 0x31, 0x5b, 0x0c, 0x7c, 0x32, 0x98, 0xea, 0x7f, 0x8f, 0xf3, 0x41, 0xea, + 0x99, 0x87, 0x6e, 0xda, 0x68, 0x98, 0xb3, 0x25, 0x9f, 0x5d, 0x4d, 0xa3, 0xcf, 0xf0, 0x1a, 0xca, + 0x09, 0x04, 0xe6, 0xcb, 0x0d, 0x38, 0x8a, 0xa1, 0xe9, 0xca, 0xa4, 0xbb, 0xbb, 0x47, 0xce, 0x29, + 0xa2, 0xb8, 0x75, 0x77, 0x17, 0x61, 0xc0, 0x81, 0x83, 0xfc, 0x2f, 0xfd, 0xc0, 0x6b, 0xc2, 0x40, + 0xd8, 0x5f, 0x06, 0xc1, 0xda, 0x02, 0xf9, 0xfb, 0x30, 0x22, 0x59, 0x9f, 0xa4, 0x61, 0x83, 0x03, + 0x80, 0xa4, 0xc7, 0x81, 0xc7, 0xf1, 0x34, 0xe5, 0x84, 0x24, 0xad, 0x03, 0x2e, 0xf9, 0x85, 0x3c, + 0xde, 0xf7, 0xf3, 0x7c, 0x84, 0xda, 0xfd, 0x43, 0x90, 0xe9, 0xed, 0x3e, 0x90, 0xf3, 0x10, 0x83, + 0x58, 0xa0, 0xbb, 0xc6, 0xd8, 0xf3, 0xb8, 0x23, 0x5c, 0x7a, 0xf7, 0x50, 0x42, 0xba, 0x08, 0x2e, + 0x41, 0x67, 0x08, 0xe0, 0x88, 0xcb, 0x12, 0xf5, 0x1a, 0x2a, 0x6b, 0x26, 0x5e, 0x07, 0x50, 0x91, + 0x09, 0xb5, 0xe7, 0x9a, 0xf3, 0x20, 0x62, 0xa9, 0x63, 0x50, 0x08, 0x0c, 0x66, 0xe8, 0xda, 0xa1, + 0x0a, 0x0a, 0xd4, 0x61, 0x8a, 0x4b, 0x11, 0x20, 0xf8, 0xaa, 0x21, 0x80, 0x4c, 0xb5, 0xba, 0x68, + 0x12, 0xff, 0x0f, 0xd3, 0x4e, 0x4b, 0xad, 0x50, 0xec, 0x73, 0x8c, 0xe9, 0xfb, 0x06, 0xe5, 0x0c, + 0xbc, 0x9a, 0x2b, 0x50, 0x77, 0x65, 0x4d, 0x08, 0xca, 0x6b, 0x93, 0x18, 0x2a, 0xb7, 0x93, 0x82, + 0xef, 0xcd, 0x53, 0x2b, 0x7b, 0xea, 0x08, 0x31, 0x7c, 0x07, 0xb2, 0x52, 0xf3, 0xa8, 0xa8, 0xd3, + 0xdb, 0x95, 0x7b, 0x91, 0x8a, 0x5e, 0x08, 0x2e, 0x64, 0xd0, 0x85, 0x48, 0xef, 0xc2, 0x5f, 0xfe, + 0xe5, 0x4f, 0x26, 0x70, 0x65, 0x65, 0x0f, 0xa8, 0x9e, 0xef, 0x9a, 0x3f, 0x44, 0xf1, 0x15, 0x86, + 0x58, 0x89, 0xed, 0x40, 0x36, 0x70, 0x86, 0x7f, 0x0b, 0xdc, 0xe1, 0x28, 0xce, 0x51, 0xec, 0x38, + 0xc9, 0xa6, 0xc5, 0x96, 0x29, 0x0a, 0x28, 0x8e, 0xca, 0x4a, 0x98, 0xdf, 0x41, 0x8a, 0xc8, 0x93, + 0x50, 0x00, 0x1f, 0x98, 0x79, 0x9e, 0xa7, 0x20, 0x54, 0xc0, 0xdd, 0x1c, 0x86, 0x0e, 0x66, 0x70, + 0x60, 0x41, 0x61, 0x27, 0x77, 0xbb, 0xfc, 0x26, 0xba, 0xf1, 0x3b, 0x0b, 0x98, 0x07, 0x36, 0xd3, + 0x8e, 0x1f, 0x75, 0x71, 0x49, 0xee, 0x55, 0x34, 0x4b, 0xc0, 0x2c, 0xf6, 0xc1, 0xfe, 0xc5, 0xcf, + 0xc2, 0x20, 0x96, 0xfb, 0x1f, 0xc1, 0x8c, 0x54, 0x48, 0x08, 0xca, 0x09, 0x48, 0x98, 0x69, 0x6c, + 0x5a, 0xb5, 0xe9, 0x62, 0x3a, 0x47, 0xed, 0x4a, 0x81, 0xd5, 0xac, 0x37, 0x05, 0x61, 0x10, 0x59, + 0x4a, 0x1c, 0x28, 0x05, 0x77, 0x63, 0x20, 0xff, 0xee, 0x41, 0x4d, 0x2b, 0x5a, 0xe3, 0xd6, 0x38, + 0xe7, 0xe6, 0x14, 0xd7, 0x88, 0x84, 0x08, 0xed, 0x21, 0x7f, 0x18, 0xc2, 0x1c, 0x04, 0x0a, 0x62, + 0xee, 0x07, 0xfc, 0xd3, 0x34, 0x20, 0xfd, 0x00, 0xfd, 0xde, 0xe6, 0x0d, 0xd3, 0xfa, 0x09, 0x35, + 0x9c, 0x92, 0x81, 0x2f, 0xb5, 0x86, 0x2d, 0x45, 0xc7, 0x35, 0x5b, 0xf8, 0xfc, 0x78, 0xee, 0xfc, + 0x44, 0xe1, 0xe4, 0x96, 0xc6, 0x99, 0x34, 0xf7, 0x06, 0xee, 0x16, 0x60, 0x7c, 0x1b, 0xdd, 0x38, + 0xdb, 0xdd, 0x6e, 0x1c, 0x74, 0xc4, 0x8b, 0xd2, 0x70, 0x68, 0x07, 0x80, 0x67, 0x9d, 0xfe, 0x16, + 0x6c, 0x63, 0xb4, 0x62, 0x50, 0xf9, 0x15, 0xfb, 0xbb, 0xdb, 0xa7, 0x6b, 0x6a, 0x49, 0x62, 0x2e, + 0x4d, 0xa4, 0x4f, 0x8d, 0x9c, 0x8e, 0xb3, 0x7a, 0x22, 0xca, 0xa3, 0xe9, 0x43, 0x13, 0x7c, 0x56, + 0xfd, 0xd5, 0x5f, 0x6b, 0xa3, 0xe5, 0xa3, 0xde, 0x89, 0xa3, 0x49, 0xac, 0x49, 0xb4, 0xd3, 0x94, + 0x6f, 0x02, 0x12, 0x8d, 0xca, 0x3e, 0x61, 0xa4, 0xf7, 0xb7, 0x47, 0x19, 0x51, 0xcb, 0xc8, 0xf2, + 0x2d, 0xb0, 0xa2, 0x50, 0x85, 0x01, 0x95, 0x9b, 0x19, 0xb1, 0x76, 0x30, 0xd6, 0x05, 0xbc, 0xac, + 0x2d, 0x4c, 0x89, 0xb4, 0xd8, 0x84, 0x71, 0x86, 0xcc, 0xbc, 0xe7, 0x6e, 0x6f, 0xcc, 0x4f, 0x47, + 0xf0, 0xd1, 0x6a, 0x59, 0x59, 0x09, 0x69, 0x8d, 0xb7, 0x4c, 0xc3, 0x6c, 0x15, 0x9c, 0x7d, 0x9d, + 0x7e, 0x62, 0xe9, 0x47, 0x6b, 0x20, 0x67, 0x06, 0xa9, 0xb8, 0x78, 0x51, 0x71, 0xfd, 0xf1, 0x9f, + 0xcd, 0xbd, 0xf1, 0x28, 0x25, 0x68, 0x62, 0x41, 0x80, 0x64, 0x1b, 0xd5, 0x14, 0xf2, 0xa6, 0x81, + 0xc6, 0x3d, 0x69, 0xb4, 0x58, 0x04, 0xfc, 0x2d, 0xae, 0x14, 0xe9, 0x64, 0xd0, 0xc6, 0x5b, 0x2e, + 0x82, 0xfd, 0xfb, 0x62, 0x9c, 0xb5, 0x82, 0x38, 0xc7, 0x11, 0x18, 0xb2, 0xfd, 0x1e, 0x3e, 0xa9, + 0x38, 0x0c, 0x32, 0xc3, 0xdf, 0xa3, 0x37, 0xe8, 0x6b, 0x67, 0x1d, 0x89, 0x33, 0x45, 0x9b, 0x8f, + 0x8e, 0x9a, 0xca, 0x0b, 0xac, 0x18, 0x17, 0x4c, 0x18, 0x39, 0xf1, 0x3f, 0x40, 0x87, 0x82, 0x18, + 0x20, 0x4b, 0xec, 0x29, 0x91, 0x5d, 0xad, 0x1a, 0x10, 0x4d, 0xa3, 0x77, 0xea, 0x27, 0x34, 0xb5, + 0x8a, 0xfe, 0x8b, 0x39, 0x39, 0x05, 0x3d, 0xed, 0x87, 0x60, 0xe0, 0xa1, 0x71, 0xc5, 0xbf, 0x40, + 0x04, 0x04, 0x54, 0x40, 0x25, 0x2b, 0xb0, 0x3f, 0x67, 0x55, 0x49, 0x85, 0x9e, 0xbd, 0xbb, 0x57, + 0x17, 0x4a, 0x32, 0x68, 0x16, 0xad, 0x2b, 0x28, 0xba, 0x62, 0xf1, 0x95, 0xb9, 0xa7, 0xdc, 0xf3, + 0x61, 0x29, 0x19, 0x4b, 0x72, 0x64, 0x24, 0x55, 0xa0, 0x9e, 0x4e, 0x95, 0xb8, 0x44, 0x95, 0x58, + 0xaa, 0xca, 0xa2, 0x7d, 0x10, 0x3f, 0x5e, 0x69, 0xe6, 0x74, 0x29, 0x4f, 0xea, 0x95, 0x1a, 0x22, + 0x67, 0x96, 0x98, 0xc8, 0x98, 0x73, 0xca, 0xfd, 0x58, 0xc3, 0xa0, 0xc1, 0x0b, 0x7a, 0x40, 0xa1, + 0xf4, 0x80, 0x62, 0xf4, 0x7c, 0x30, 0x0d, 0xbc, 0xa0, 0x30, 0xf3, 0x82, 0x4a, 0xfd, 0x93, 0xb3, + 0x54, 0xad, 0x25, 0x1a, 0x5f, 0x9b, 0xe3, 0xaa, 0xce, 0x0a, 0x34, 0xc0, 0xc9, 0x39, 0xdb, 0x8a, + 0xc8, 0x1f, 0x98, 0x66, 0xe2, 0x41, 0x63, 0xd2, 0x10, 0x09, 0x30, 0xd9, 0xf7, 0xe2, 0x42, 0x98, + 0x99, 0xe5, 0xe0, 0x0b, 0x37, 0xc7, 0x29, 0xbd, 0xef, 0x1e, 0xd6, 0xbe, 0x95, 0xc4, 0x03, 0xcf, + 0x20, 0x67, 0x14, 0xdb, 0xc7, 0x19, 0x88, 0x6b, 0xba, 0x31, 0x8a, 0x62, 0x6f, 0xf8, 0xaa, 0x4a, + 0xf8, 0x64, 0x0d, 0x9a, 0x51, 0xef, 0x9b, 0x40, 0xc3, 0xcd, 0x6a, 0x8a, 0xc1, 0x31, 0x5e, 0x41, + 0x6f, 0xa2, 0x31, 0x06, 0x61, 0x72, 0xba, 0xa3, 0xe1, 0xb6, 0x0e, 0xd8, 0x8c, 0x2f, 0xa3, 0xc0, + 0xe3, 0xe0, 0x66, 0x7f, 0xfe, 0xa2, 0xaa, 0xff, 0x59, 0x84, 0x8f, 0x83, 0xc4, 0x81, 0xef, 0x8e, + 0xa5, 0x9a, 0x28, 0x7f, 0x85, 0x2e, 0xdd, 0x9a, 0x76, 0xf0, 0x1f, 0x8d, 0x69, 0x20, 0x30, 0x65, + 0x25, 0x4c, 0x59, 0x11, 0xd3, 0x9f, 0xd0, 0xe2, 0xff, 0x0f, 0xc6, 0x94, 0xe9, 0x93, 0xf5, 0x3a, + 0x8e, 0x16, 0xb8, 0xbb, 0xac, 0xac, 0x99, 0xb2, 0x74, 0xab, 0x52, 0xb0, 0x15, 0xb7, 0x68, 0x02, + 0xae, 0xa9, 0x0d, 0xb4, 0x06, 0xf7, 0xb4, 0x86, 0x92, 0x08, 0x64, 0x67, 0x44, 0xac, 0xa0, 0x4a, + 0xb2, 0xd4, 0x82, 0x4a, 0xc9, 0x53, 0xef, 0x27, 0x99, 0x62, 0x11, 0xd1, 0x79, 0xf0, 0xba, 0x82, + 0x0e, 0xa2, 0x90, 0x5c, 0xf4, 0x2e, 0xed, 0x94, 0x82, 0xc1, 0xdf, 0x44, 0xf1, 0x0a, 0x43, 0x58, + 0xc5, 0xf0, 0x34, 0x16, 0x32, 0x30, 0x26, 0x00, 0x16, 0x22, 0xb3, 0xa1, 0x62, 0x87, 0x76, 0x29, + 0x01, 0x33, 0x69, 0xde, 0x0c, 0x18, 0x8e, 0xf1, 0xed, 0x47, 0xb2, 0xad, 0x30, 0xca, 0x9a, 0x13, + 0x86, 0xba, 0xae, 0x85, 0x61, 0x44, 0xed, 0x6e, 0x9f, 0x8f, 0x2c, 0xf4, 0xb7, 0x88, 0xe2, 0x92, + 0x16, 0x36, 0xb3, 0xec, 0x39, 0xc7, 0xe8, 0x2d, 0x3a, 0x09, 0xd4, 0xde, 0x76, 0xc5, 0xd3, 0x65, + 0xe4, 0x39, 0xe6, 0x87, 0xf7, 0x1f, 0x3f, 0x99, 0x36, 0xda, 0xd8, 0x4e, 0xba, 0xdb, 0x1f, 0xad, + 0x8c, 0x06, 0xba, 0x35, 0x9f, 0x23, 0x31, 0xd6, 0xdc, 0xad, 0x47, 0x4c, 0x5c, 0xd5, 0x13, 0x94, + 0x34, 0xe2, 0xe5, 0x1c, 0xa5, 0x7c, 0xfc, 0x4a, 0xd3, 0xb4, 0x4e, 0xf7, 0xff, 0x2d, 0x3c, 0x5d, + 0x33, 0x0d, 0xd9, 0x4a, 0xd5, 0x65, 0x0e, 0x5b, 0xf3, 0xb1, 0xac, 0x68, 0x39, 0x32, 0x35, 0x2e, + 0xf9, 0x73, 0x90, 0x28, 0xa2, 0x24, 0xa6, 0x2d, 0x4b, 0x8e, 0x0b, 0x26, 0xff, 0x24, 0x28, 0x8f, + 0xb7, 0x74, 0x9c, 0xf6, 0x92, 0xc1, 0xb4, 0x2b, 0xd0, 0x32, 0x06, 0x12, 0x45, 0xa5, 0x94, 0x3d, + 0xef, 0x8f, 0xfc, 0x88, 0xba, 0xa0, 0x0b, 0xe4, 0xe5, 0x56, 0x85, 0x92, 0x80, 0x46, 0xa3, 0x08, + 0xd4, 0xff, 0xd2, 0x20, 0x09, 0xc6, 0xb2, 0x31, 0xb8, 0x2c, 0x76, 0xd5, 0x03, 0x95, 0x74, 0xcd, + 0xa1, 0xbf, 0x75, 0xbc, 0x98, 0x2d, 0x16, 0x48, 0x08, 0x8c, 0xe0, 0x03, 0x79, 0x42, 0x60, 0x09, + 0x41, 0x18, 0xb4, 0x05, 0x81, 0x4c, 0x05, 0xbf, 0x4e, 0xc4, 0x5b, 0xf8, 0xbd, 0x31, 0x24, 0x72, + 0xf3, 0x34, 0x4b, 0x89, 0xe2, 0x81, 0xfb, 0x86, 0xb3, 0x16, 0xb3, 0x84, 0x56, 0x6d, 0x0e, 0xd2, + 0x22, 0xf8, 0xb2, 0x94, 0x11, 0x43, 0x86, 0x0a, 0x7f, 0xaa, 0xb0, 0xe3, 0x7c, 0x13, 0xde, 0xdd, + 0xb5, 0x07, 0xf2, 0x71, 0x02, 0xe5, 0x66, 0xcb, 0x2b, 0xd7, 0x5c, 0xf0, 0x70, 0x60, 0xda, 0x79, + 0x34, 0x1d, 0xe6, 0xfb, 0x10, 0x6a, 0xc3, 0x18, 0xc9, 0x60, 0xa1, 0x1e, 0xc6, 0x87, 0xcc, 0x2d, + 0x25, 0x3a, 0x32, 0x13, 0x2a, 0x5e, 0x39, 0x08, 0xa3, 0x6f, 0xee, 0x50, 0x74, 0x33, 0xff, 0xa7, + 0x5c, 0x4b, 0x26, 0x3b, 0x59, 0x81, 0xfd, 0x9a, 0x80, 0xd5, 0x99, 0xdb, 0x83, 0x51, 0x28, 0x2c, + 0xe9, 0x0a, 0x47, 0x4a, 0x18, 0x72, 0xc5, 0x0c, 0xc1, 0x9e, 0x67, 0xa3, 0x46, 0xa3, 0x2a, 0x9a, + 0x2f, 0x00, 0xba, 0xed, 0x3e, 0xb2, 0xd2, 0x8e, 0x77, 0x92, 0x28, 0x4e, 0x9b, 0x4d, 0x15, 0xfd, + 0x15, 0xb1, 0x69, 0x3d, 0x40, 0xcc, 0xa6, 0x09, 0x88, 0x54, 0x64, 0xb5, 0xb3, 0xb7, 0x00, 0xde, + 0xc0, 0x09, 0xcc, 0x1c, 0xbd, 0x10, 0x17, 0x65, 0xb8, 0xa5, 0x93, 0xda, 0x0e, 0x70, 0x04, 0xb4, + 0x55, 0xdd, 0x90, 0x9c, 0x6e, 0xf0, 0xa7, 0x2b, 0xe3, 0xca, 0x32, 0x82, 0x6c, 0x63, 0x04, 0xb5, + 0x2c, 0x25, 0x22, 0x74, 0x20, 0xc3, 0x8e, 0x28, 0x33, 0xe3, 0xb4, 0x24, 0x12, 0xb9, 0xc7, 0x89, + 0x88, 0xc0, 0x30, 0xab, 0x28, 0x1d, 0xd5, 0xf0, 0x28, 0x46, 0x54, 0x0a, 0x3a, 0x14, 0x63, 0xdc, + 0xb6, 0x58, 0xdd, 0xda, 0xb3, 0x9b, 0x52, 0x5a, 0xcb, 0x2b, 0x98, 0x50, 0x41, 0xc6, 0xad, 0xc4, + 0xa5, 0x18, 0xe5, 0x04, 0x7f, 0xc7, 0x0e, 0x4a, 0xa1, 0x89, 0x40, 0x85, 0x26, 0xda, 0x35, 0x76, + 0xc5, 0xbd, 0xa1, 0x89, 0x76, 0x45, 0x68, 0x02, 0x9a, 0xc9, 0x43, 0x13, 0xe2, 0x25, 0x0b, 0x4d, + 0x64, 0x09, 0xe0, 0x14, 0xbe, 0x8b, 0x5d, 0xb6, 0x1f, 0xab, 0xe0, 0x65, 0x02, 0xec, 0x05, 0x2f, + 0x2a, 0x59, 0x05, 0xba, 0x9d, 0x60, 0x4c, 0x46, 0x44, 0xca, 0x1a, 0x0d, 0x50, 0x03, 0xaf, 0xe5, + 0xaa, 0x29, 0x61, 0x9a, 0x2d, 0x37, 0xe7, 0x43, 0x0d, 0xe8, 0x7e, 0xcb, 0x71, 0x2f, 0x98, 0xd8, + 0x89, 0x00, 0xb3, 0x26, 0x20, 0x96, 0xad, 0x78, 0x70, 0x18, 0x9c, 0xc2, 0xf2, 0x1f, 0x26, 0x14, + 0x17, 0x0d, 0x58, 0xb6, 0x68, 0x20, 0x9f, 0x3a, 0x09, 0xee, 0x2f, 0xe7, 0x88, 0x75, 0x35, 0x70, + 0x86, 0xeb, 0xad, 0x19, 0x02, 0xfa, 0x6a, 0x93, 0x30, 0x8e, 0xdf, 0x4f, 0xff, 0x00, 0xcc, 0xd4, + 0xb9, 0xe2, 0xb7, 0x09, 0xc6, 0x19, 0x54, 0xfb, 0xb4, 0x96, 0x58, 0xca, 0xdb, 0x4a, 0x03, 0xec, + 0x22, 0xb8, 0x24, 0xad, 0x4e, 0x82, 0x85, 0xeb, 0x0f, 0xc5, 0x95, 0x48, 0xad, 0x0d, 0x5c, 0x4b, + 0x60, 0xd4, 0xb2, 0x49, 0x8c, 0x94, 0x9b, 0x30, 0xb4, 0x1d, 0xe5, 0xbe, 0xaa, 0xa2, 0x82, 0x5d, + 0x5a, 0xb0, 0xd3, 0x41, 0xd0, 0xaa, 0xe0, 0x97, 0xc1, 0x10, 0x0b, 0x8a, 0x3a, 0x10, 0x11, 0xe8, + 0xa0, 0xc2, 0x3f, 0xaf, 0x23, 0xe0, 0x4e, 0x33, 0x3f, 0x48, 0xa8, 0xb6, 0x94, 0x0e, 0x1c, 0x9a, + 0xd8, 0x0e, 0x5d, 0xa1, 0x43, 0x99, 0x60, 0xbc, 0x09, 0xc8, 0xb2, 0x23, 0x9f, 0x41, 0x94, 0x79, + 0xae, 0xd3, 0x43, 0xd2, 0xe9, 0x21, 0xea, 0xf4, 0x71, 0x6d, 0xfb, 0xaa, 0x19, 0x68, 0x1d, 0x34, + 0x81, 0x1d, 0x8a, 0x45, 0xbf, 0x94, 0x26, 0x01, 0xe0, 0x06, 0xed, 0xa5, 0x13, 0x13, 0x13, 0x34, + 0x55, 0x28, 0x58, 0xc5, 0xd9, 0xb9, 0x8a, 0xc2, 0x47, 0x1d, 0x5c, 0x38, 0x0b, 0x81, 0xcb, 0xc3, + 0x9a, 0x09, 0x27, 0xad, 0x9d, 0x5b, 0xa8, 0x1d, 0x4b, 0x9f, 0xd5, 0xea, 0xe7, 0x9a, 0x88, 0xe6, + 0x9a, 0xb0, 0x5a, 0x7a, 0x72, 0x0b, 0x59, 0x44, 0x12, 0x89, 0x7e, 0xb8, 0x88, 0x73, 0xff, 0x50, + 0x32, 0xb1, 0xa8, 0x03, 0x84, 0x3d, 0x54, 0x84, 0xcd, 0xa9, 0x8e, 0xc2, 0xae, 0x52, 0x81, 0xfc, + 0x59, 0xc7, 0xc1, 0x5c, 0x74, 0x85, 0xe3, 0x0a, 0x8a, 0x32, 0xad, 0xd1, 0xa1, 0x45, 0xd2, 0x0b, + 0xa4, 0x0c, 0xb0, 0x62, 0x80, 0xd8, 0x20, 0x5b, 0x65, 0x1d, 0x8d, 0xc9, 0x51, 0x11, 0xd2, 0xf3, + 0x20, 0x90, 0x66, 0x8b, 0x5a, 0x27, 0x13, 0x73, 0x6c, 0x79, 0x1d, 0x58, 0x1f, 0x55, 0xd9, 0x0c, + 0x30, 0x97, 0xef, 0xe1, 0x9a, 0x6e, 0x37, 0x8a, 0x0d, 0x42, 0xdf, 0x48, 0xd6, 0x7c, 0xe6, 0xcf, + 0x7d, 0x5a, 0x24, 0x2e, 0xf1, 0x5b, 0xa0, 0xc8, 0xb5, 0xbd, 0x9f, 0x58, 0x63, 0x8d, 0x2e, 0x25, + 0x6a, 0x28, 0x22, 0x45, 0x92, 0x2e, 0x30, 0x07, 0x00, 0x5c, 0x9e, 0x62, 0xff, 0x80, 0x8f, 0xfa, + 0x75, 0xca, 0x04, 0xba, 0x5d, 0xda, 0x29, 0x20, 0xd0, 0x21, 0x42, 0x45, 0x90, 0xa9, 0xc5, 0xc9, + 0xd6, 0xd9, 0xb0, 0x96, 0x16, 0x7c, 0x98, 0x58, 0x7e, 0xd1, 0x46, 0x4a, 0xea, 0x32, 0x40, 0xac, + 0x37, 0xde, 0x53, 0x80, 0x5b, 0xcd, 0x24, 0x60, 0x99, 0x21, 0x71, 0x91, 0x5e, 0x0a, 0x5b, 0x40, + 0xb6, 0xb3, 0xc3, 0x51, 0x4a, 0x5b, 0x2d, 0xcd, 0xf5, 0x92, 0x3b, 0x9b, 0x1e, 0xa3, 0x21, 0xd4, + 0x66, 0x2b, 0xa6, 0xef, 0x90, 0x50, 0xf8, 0x06, 0xc5, 0xd5, 0xad, 0x5a, 0xa9, 0x06, 0xd9, 0x21, + 0xdb, 0x61, 0x00, 0x5c, 0x4a, 0x46, 0x92, 0xd0, 0x8f, 0xba, 0x95, 0x04, 0xa6, 0x57, 0xb6, 0xfd, + 0xa5, 0x56, 0xd4, 0x41, 0xdd, 0x1a, 0x7e, 0x82, 0x4c, 0x01, 0x83, 0xe0, 0x93, 0x81, 0x28, 0x66, + 0xe1, 0x07, 0xea, 0x41, 0x05, 0xa1, 0xb0, 0xc1, 0x04, 0xa4, 0x6f, 0x7d, 0xd9, 0x5a, 0xc7, 0xa1, + 0x64, 0x59, 0xd0, 0xa6, 0x18, 0x0c, 0x97, 0x13, 0x33, 0x48, 0x33, 0x93, 0x67, 0xb3, 0xb8, 0x43, + 0x8a, 0xc3, 0x3e, 0x0c, 0x95, 0xfe, 0x57, 0x7b, 0xed, 0xf6, 0xd9, 0xff, 0xc7, 0x5f, 0x6c, 0x85, + 0x83, 0xb9, 0xbb, 0xf0, 0xbd, 0x7f, 0x74, 0x4d, 0x7c, 0xf5, 0xbd, 0xdd, 0x13, 0xf3, 0xf2, 0xc7, + 0x92, 0x41, 0xc4, 0x0a, 0xc3, 0x8a, 0x28, 0xd1, 0x56, 0x9c, 0xd7, 0x61, 0x5a, 0x5e, 0x79, 0xe5, + 0xf9, 0xca, 0x2b, 0xf0, 0xa5, 0x65, 0xc9, 0x8d, 0x8b, 0x3b, 0xb1, 0x5a, 0x17, 0xde, 0xbb, 0xa6, + 0x3c, 0xa6, 0x0d, 0x39, 0x4b, 0x96, 0xbc, 0xbf, 0x09, 0x3f, 0xc4, 0xd1, 0x9a, 0xc7, 0xe9, 0x6d, + 0x16, 0x85, 0xa5, 0xd9, 0x0f, 0x17, 0x1f, 0x70, 0x25, 0x22, 0xac, 0x88, 0xbb, 0x06, 0x1d, 0x2a, + 0xa9, 0xc9, 0x9e, 0x16, 0x64, 0xcc, 0x34, 0xa3, 0x15, 0x96, 0xa2, 0x87, 0xfb, 0xd5, 0x0a, 0x21, + 0x61, 0xbd, 0x62, 0x49, 0x13, 0x09, 0x4f, 0xf0, 0x1e, 0x4c, 0x30, 0x08, 0xac, 0x73, 0x68, 0x78, + 0x8f, 0x1f, 0x2d, 0x7b, 0x49, 0x0b, 0xaa, 0xfc, 0x1e, 0x98, 0xc0, 0x8d, 0xe2, 0xc9, 0x95, 0x29, + 0xbb, 0x4a, 0xa2, 0xc9, 0x2d, 0xd1, 0x1a, 0xd9, 0x28, 0x80, 0x4d, 0xcf, 0x1e, 0xb9, 0xb4, 0xd5, + 0x6b, 0x95, 0xf7, 0x0d, 0x8f, 0x54, 0x0c, 0xe3, 0x82, 0xcd, 0x51, 0x00, 0x34, 0xc3, 0x69, 0x05, + 0x9f, 0x12, 0x4b, 0x44, 0xf7, 0x04, 0x12, 0xee, 0x03, 0x7b, 0x09, 0xac, 0x2d, 0xee, 0x6f, 0x9a, + 0xc2, 0x54, 0x74, 0xb5, 0xe3, 0x77, 0x77, 0x4d, 0x31, 0xc1, 0x65, 0x5d, 0xb0, 0xc3, 0xfa, 0x09, + 0xcc, 0xb2, 0x75, 0x62, 0x05, 0x1d, 0x59, 0x49, 0xc8, 0x5e, 0xd5, 0x6c, 0xa9, 0x45, 0x42, 0xb3, + 0x67, 0x5b, 0x67, 0x27, 0x33, 0x9b, 0x48, 0xd1, 0xc2, 0x45, 0x73, 0x17, 0x48, 0x26, 0x36, 0x3d, + 0x9b, 0x2a, 0xa6, 0xa5, 0x45, 0x10, 0xe4, 0x82, 0x35, 0xca, 0x45, 0xde, 0x3c, 0x6a, 0x94, 0x4a, + 0x08, 0xb8, 0xea, 0x61, 0x96, 0x2d, 0x58, 0xf2, 0x8b, 0x4a, 0x16, 0x2c, 0x57, 0xa0, 0xb4, 0x3e, + 0x55, 0x0e, 0xb4, 0x74, 0xb4, 0x4c, 0x39, 0x3a, 0x3e, 0x2e, 0x5a, 0x69, 0x82, 0xb2, 0xf5, 0x6b, + 0x87, 0xba, 0x9e, 0x17, 0xe5, 0x14, 0x5b, 0xa1, 0x30, 0xc4, 0x9a, 0x1a, 0x68, 0x8b, 0xaf, 0x33, + 0x6d, 0x81, 0xca, 0x82, 0xa8, 0x9d, 0x2f, 0xf8, 0xa5, 0x8d, 0x86, 0x2f, 0x3d, 0xba, 0x92, 0x3f, + 0xe3, 0x5b, 0x5b, 0x7c, 0x47, 0x37, 0x20, 0xc2, 0x15, 0xb5, 0xdc, 0x91, 0xcc, 0x1e, 0x95, 0xc7, + 0xd7, 0x1b, 0x5b, 0x5c, 0xd9, 0x46, 0x3d, 0x01, 0x06, 0xab, 0xc5, 0x08, 0x26, 0x50, 0x85, 0x75, + 0xe7, 0x48, 0x24, 0xc1, 0x90, 0x14, 0x4d, 0xf0, 0xd8, 0x9a, 0x34, 0x95, 0x07, 0x13, 0x63, 0x04, + 0x0c, 0xdc, 0x1b, 0x1c, 0xe7, 0xf8, 0xa2, 0x7f, 0x09, 0xfe, 0xaf, 0xca, 0x8a, 0xb2, 0xf4, 0x2a, + 0x07, 0x83, 0x26, 0xaa, 0x6c, 0x5d, 0x30, 0x6b, 0xde, 0x96, 0x5b, 0x6b, 0x2a, 0x7c, 0x68, 0xae, + 0xa6, 0x3e, 0xae, 0xfb, 0xd0, 0x6a, 0xb4, 0x76, 0xd2, 0x4b, 0xdb, 0x1f, 0x4f, 0x2a, 0x9c, 0x89, + 0x6d, 0xb6, 0xf4, 0xba, 0xb7, 0x1d, 0x49, 0xb6, 0x69, 0x95, 0xac, 0x8a, 0x1c, 0x03, 0x83, 0xf2, + 0x0d, 0x01, 0x02, 0x0d, 0xbb, 0xdc, 0xc8, 0x48, 0x0b, 0xeb, 0xd8, 0xe0, 0x28, 0x72, 0x0a, 0xca, + 0xca, 0x3d, 0x09, 0x76, 0x58, 0xc3, 0x0f, 0xca, 0x42, 0xed, 0x65, 0x83, 0xe1, 0x8b, 0xc1, 0x10, + 0x98, 0x20, 0xc6, 0x3e, 0x6e, 0xe8, 0x2d, 0xbb, 0xc7, 0x60, 0x6a, 0xa8, 0xd0, 0x5b, 0x85, 0xbd, + 0x50, 0x65, 0x2e, 0xf8, 0xe0, 0xb2, 0x08, 0x82, 0x09, 0xf4, 0x77, 0x00, 0xc1, 0x0e, 0x60, 0x10, + 0x70, 0x20, 0x1e, 0x70, 0xee, 0xf8, 0x03, 0xce, 0xdd, 0xfe, 0xa4, 0x5c, 0x4d, 0x33, 0x72, 0x21, + 0x90, 0xd4, 0x1a, 0xf1, 0x34, 0x5f, 0x46, 0x48, 0x97, 0x50, 0x07, 0x0f, 0x4b, 0x18, 0xd9, 0x70, + 0x8f, 0x95, 0x32, 0xb2, 0x4a, 0xed, 0xa8, 0x64, 0x80, 0xc5, 0x6e, 0x35, 0x03, 0x4c, 0x82, 0xc2, + 0x76, 0x2f, 0xa7, 0x6f, 0xfb, 0x22, 0x0a, 0xbb, 0x62, 0x9f, 0x9b, 0xe0, 0xba, 0x28, 0xf3, 0x36, + 0x9f, 0xd0, 0x61, 0x14, 0xc2, 0x53, 0x7f, 0x1c, 0xb6, 0x5a, 0x52, 0x67, 0x8c, 0xef, 0xe1, 0x2e, + 0x1c, 0x54, 0xc5, 0xe0, 0x17, 0xe1, 0xa5, 0xad, 0x6f, 0xff, 0x11, 0xc4, 0x56, 0xf6, 0x22, 0x5a, + 0x23, 0xfb, 0x3b, 0x8d, 0xb2, 0x9a, 0x6a, 0x6a, 0x13, 0xe1, 0x59, 0xd0, 0x10, 0xda, 0x9b, 0x7b, + 0xd8, 0x47, 0xa9, 0x13, 0x2f, 0x77, 0x77, 0x3e, 0xce, 0x01, 0x79, 0x1c, 0x37, 0x5f, 0x4d, 0x57, + 0x88, 0x8c, 0xc3, 0x33, 0xd5, 0xaf, 0x76, 0x1f, 0xbc, 0xa9, 0x12, 0xcb, 0x45, 0xb8, 0x09, 0xce, + 0x2a, 0x1a, 0x72, 0xe1, 0x69, 0x3c, 0x51, 0xdc, 0x25, 0x58, 0x4b, 0x9c, 0x45, 0x33, 0x77, 0x8e, + 0xb2, 0x51, 0x69, 0x0f, 0xb1, 0x9e, 0xf3, 0xb0, 0x33, 0x94, 0x8a, 0xed, 0x33, 0x5f, 0x3e, 0x97, + 0x36, 0x1a, 0x35, 0x04, 0x07, 0xa8, 0x60, 0xd2, 0xb9, 0xb8, 0xbf, 0xf0, 0x7e, 0x26, 0x15, 0xfb, + 0x53, 0x93, 0x65, 0xb4, 0x09, 0x3c, 0xda, 0xa6, 0xba, 0x24, 0xa5, 0x65, 0xdc, 0x2c, 0xe1, 0x03, + 0x78, 0x97, 0x6c, 0xdc, 0x3d, 0xc1, 0x2f, 0x09, 0xa0, 0x6a, 0xb6, 0x4a, 0x71, 0x31, 0x41, 0x0c, + 0xc2, 0x0f, 0xc3, 0x77, 0xa9, 0x30, 0xd8, 0x85, 0xfc, 0x54, 0x94, 0x0f, 0xb2, 0x3d, 0x8f, 0x5a, + 0xc5, 0x01, 0xa9, 0xba, 0xf1, 0xde, 0x72, 0xbc, 0x6e, 0x56, 0xed, 0x6d, 0x25, 0x08, 0x2b, 0x77, + 0x1d, 0x29, 0x5c, 0xc7, 0x55, 0x3b, 0x2b, 0x72, 0x78, 0x05, 0xaa, 0x21, 0x5d, 0x80, 0xf2, 0xc0, + 0xac, 0xe0, 0xae, 0xdd, 0xae, 0xa2, 0x98, 0x9b, 0x0f, 0x1b, 0x7a, 0x6a, 0xc7, 0xb5, 0xe4, 0xb5, + 0xea, 0x81, 0x52, 0xdb, 0x40, 0x69, 0x8b, 0x77, 0xde, 0x75, 0x6b, 0x5f, 0x7b, 0xca, 0x68, 0x5b, + 0x87, 0x5a, 0xe3, 0x9e, 0xcb, 0xeb, 0x8b, 0x14, 0x57, 0xfb, 0xc5, 0xe4, 0xc2, 0x77, 0xf7, 0xdb, + 0xb3, 0x7f, 0x1b, 0xb6, 0x28, 0x93, 0xca, 0x22, 0xe6, 0x56, 0xf5, 0xc2, 0xac, 0xd6, 0x16, 0x4d, + 0x59, 0x52, 0xdd, 0xab, 0x5d, 0xa2, 0xa2, 0xdd, 0x5a, 0x15, 0xa2, 0x35, 0x9d, 0x16, 0x9a, 0xd6, + 0xa3, 0x55, 0x29, 0x31, 0x3e, 0xd7, 0x42, 0x96, 0xa6, 0x09, 0x13, 0x13, 0x4e, 0xc8, 0x2f, 0xc5, + 0xd1, 0x38, 0x4c, 0xa8, 0x0d, 0x76, 0x41, 0xf5, 0x42, 0xe1, 0x96, 0xcb, 0x5b, 0x29, 0xce, 0x21, + 0x00, 0xc7, 0x36, 0x75, 0x5b, 0xb0, 0x77, 0x2f, 0x90, 0x4c, 0x9f, 0xe7, 0x86, 0xec, 0x05, 0x6f, + 0xb5, 0x2e, 0xc7, 0xd2, 0xe3, 0x75, 0x09, 0x28, 0xc3, 0xf5, 0xfa, 0x35, 0x1e, 0x3e, 0xa0, 0x40, + 0x68, 0x13, 0x17, 0xd4, 0xc4, 0x93, 0x1a, 0xc8, 0x4a, 0xdf, 0xcf, 0x30, 0x0c, 0x8c, 0x27, 0x08, + 0xe9, 0x95, 0xf4, 0x95, 0x6f, 0xc8, 0xa6, 0xc2, 0x07, 0xbc, 0xf8, 0x6c, 0xdf, 0xda, 0x3f, 0x5d, + 0xa2, 0x0d, 0x8a, 0x61, 0x00, 0x11, 0x10, 0x95, 0x2b, 0xf0, 0xbb, 0xaa, 0xad, 0x55, 0xd9, 0xe0, + 0x68, 0xfb, 0xab, 0xf4, 0x34, 0xb9, 0xc9, 0x2a, 0x1f, 0xc3, 0x8c, 0xce, 0x38, 0x91, 0xd3, 0x4b, + 0x66, 0x83, 0x89, 0x38, 0x8d, 0x6a, 0xaf, 0x60, 0x71, 0x65, 0xa5, 0xac, 0xcc, 0xf1, 0x53, 0xe5, + 0x5c, 0x37, 0x22, 0x26, 0xd2, 0x07, 0x2b, 0x26, 0x9b, 0x69, 0x2c, 0x57, 0xd3, 0xf4, 0x1c, 0x59, + 0xab, 0x72, 0x17, 0x7e, 0x89, 0x63, 0x26, 0x8a, 0x31, 0x73, 0xae, 0x71, 0x4a, 0x49, 0x15, 0x6b, + 0xac, 0xfb, 0x3d, 0x2d, 0xba, 0x60, 0xd5, 0xa2, 0x67, 0xb3, 0xfd, 0x2c, 0x6d, 0xcd, 0x37, 0x75, + 0x6b, 0xbc, 0xbf, 0xf1, 0xf1, 0xd1, 0xd1, 0xe0, 0x28, 0x33, 0x01, 0x27, 0x30, 0x59, 0xe7, 0xeb, + 0x8f, 0xe5, 0x0d, 0xa9, 0xff, 0x9a, 0x6f, 0xf3, 0x2b, 0x1c, 0x58, 0x11, 0xdb, 0xd5, 0x36, 0xb3, + 0x19, 0x47, 0x3b, 0xde, 0x01, 0x90, 0xfd, 0x47, 0x82, 0xfc, 0xe3, 0xbf, 0xdd, 0x07, 0x72, 0xce, + 0x7c, 0x74, 0x9c, 0x9d, 0x66, 0x5a, 0xf4, 0x6f, 0x72, 0x80, 0x7d, 0x9b, 0x15, 0x09, 0x2a, 0x4d, + 0xf9, 0xc2, 0x1e, 0xb0, 0x8c, 0xa2, 0x13, 0xa5, 0x2a, 0x5a, 0xaa, 0x38, 0xaa, 0xea, 0x59, 0x1c, + 0x05, 0xc1, 0xa7, 0x68, 0xed, 0xaa, 0xe7, 0xdf, 0xd0, 0xcd, 0x06, 0xd0, 0x2c, 0x17, 0xeb, 0xa8, + 0x44, 0x29, 0x5c, 0x4c, 0xac, 0xe4, 0x04, 0xa7, 0xf9, 0x37, 0x73, 0x01, 0x60, 0xf1, 0xa0, 0x44, + 0x0a, 0x13, 0x91, 0x0c, 0x42, 0x32, 0x4c, 0xb2, 0x23, 0x30, 0xb4, 0x23, 0x9e, 0x8e, 0xfa, 0xc5, + 0xd2, 0x62, 0xd1, 0xfd, 0x49, 0x01, 0x3f, 0x0b, 0xa1, 0xd0, 0xed, 0x5b, 0x19, 0xad, 0xc0, 0x76, + 0x26, 0x89, 0xe1, 0xca, 0xfe, 0x2f, 0x1d, 0x27, 0x90, 0xc5, 0xee, 0xee, 0xaa, 0x7b, 0x78, 0x77, + 0x27, 0x7b, 0xd8, 0x94, 0x9a, 0x5e, 0xa4, 0x97, 0x8b, 0x2b, 0x30, 0xb5, 0x36, 0xc3, 0x04, 0x75, + 0x6b, 0x01, 0x04, 0x99, 0x56, 0x82, 0x44, 0x17, 0x97, 0x96, 0xe2, 0x10, 0xa0, 0xdc, 0xa1, 0x46, + 0xc5, 0x49, 0x9e, 0xac, 0xd3, 0x56, 0xa6, 0x1e, 0xe6, 0x5e, 0x4d, 0x06, 0x2b, 0xeb, 0xb7, 0x53, + 0xea, 0xf7, 0xe1, 0x97, 0x75, 0x7c, 0xf2, 0x33, 0xe8, 0x04, 0x16, 0xd1, 0xa4, 0xa6, 0x99, 0x3a, + 0xba, 0x10, 0x07, 0xb9, 0x14, 0x1c, 0x2b, 0xe0, 0xef, 0x94, 0x0c, 0x2b, 0xcd, 0xa8, 0xda, 0x84, + 0x57, 0x61, 0x74, 0x13, 0xea, 0xea, 0x57, 0xf9, 0x6f, 0x8a, 0x17, 0x98, 0x55, 0x45, 0xa2, 0x2a, + 0x90, 0xc2, 0x8c, 0x34, 0x6e, 0xfc, 0x74, 0x69, 0x44, 0x21, 0x97, 0x4d, 0x80, 0x5a, 0x35, 0xc0, + 0x22, 0x41, 0xfb, 0x2c, 0xb9, 0xbf, 0x1d, 0xbb, 0x4c, 0x77, 0xe7, 0xde, 0x51, 0x2e, 0x76, 0xf6, + 0xbe, 0xf1, 0x73, 0x2a, 0x18, 0x22, 0x2f, 0xa6, 0xf1, 0x83, 0x65, 0x3d, 0x86, 0x1d, 0xaa, 0x1d, + 0x59, 0x3c, 0x77, 0x87, 0x4b, 0x1d, 0xcd, 0x3a, 0x33, 0x96, 0x0a, 0x64, 0xf6, 0xa9, 0x76, 0xe0, + 0xf7, 0x02, 0xe9, 0x81, 0x38, 0x60, 0x12, 0x6e, 0x1a, 0x28, 0x83, 0x26, 0x5d, 0x7f, 0x8f, 0xe7, + 0x4b, 0xfb, 0x58, 0xe4, 0xb2, 0x21, 0x46, 0xe4, 0xb9, 0xd8, 0xd0, 0x12, 0xc8, 0x4d, 0x27, 0xcf, + 0x43, 0xef, 0xfc, 0x33, 0x9f, 0xa1, 0x69, 0xf9, 0x23, 0xee, 0x64, 0x77, 0xba, 0xdd, 0x5f, 0x6c, + 0xeb, 0x8e, 0x71, 0xee, 0xba, 0x08, 0xed, 0x47, 0x5b, 0x6c, 0xa1, 0x11, 0x43, 0x55, 0x5a, 0x60, + 0x16, 0x67, 0x9d, 0xb4, 0x03, 0x8a, 0x81, 0x35, 0xd6, 0x7a, 0xc3, 0x2f, 0x5d, 0x66, 0x17, 0xde, + 0x3b, 0xa0, 0x9f, 0x50, 0x99, 0xdf, 0x8b, 0x3f, 0xa1, 0x4a, 0xd8, 0x63, 0xac, 0xc0, 0xd2, 0x0f, + 0x61, 0x55, 0xf9, 0x24, 0x68, 0x9a, 0x55, 0xae, 0x9c, 0xf7, 0x04, 0x82, 0x1c, 0x4f, 0x26, 0xf3, + 0x0e, 0x15, 0x71, 0x0b, 0x05, 0x0b, 0x0b, 0xac, 0xdc, 0xda, 0x3b, 0x6b, 0xad, 0x37, 0xac, 0x16, + 0x25, 0xec, 0xc0, 0x15, 0x67, 0x1d, 0x95, 0xc5, 0x84, 0x31, 0x69, 0x65, 0x30, 0x50, 0xc4, 0x38, + 0xb0, 0x64, 0xe0, 0x9d, 0x6c, 0x03, 0x3c, 0x10, 0xc9, 0x27, 0x50, 0xce, 0xa1, 0x7d, 0x14, 0x4d, + 0x96, 0xaf, 0x6f, 0xe0, 0xce, 0x0a, 0x2b, 0x3f, 0xc7, 0xc5, 0x8a, 0xad, 0xe5, 0xe7, 0x86, 0xca, + 0x6d, 0x8e, 0xf7, 0x8e, 0xf0, 0x31, 0x37, 0x00, 0x27, 0x44, 0x80, 0x87, 0x6f, 0xe1, 0xf2, 0xe4, + 0xf1, 0x72, 0x96, 0x59, 0x34, 0xa9, 0x08, 0x69, 0xcb, 0x3d, 0x13, 0x68, 0x98, 0x4a, 0x04, 0x43, + 0x80, 0x90, 0x12, 0x84, 0xd0, 0x2d, 0xb7, 0x9e, 0x6a, 0x48, 0x86, 0x3b, 0x04, 0xa3, 0x1d, 0x73, + 0xd5, 0x0f, 0xd6, 0xf5, 0xc7, 0xda, 0xf2, 0xad, 0x4e, 0x59, 0x1c, 0xa2, 0x2f, 0x3b, 0xfa, 0x77, + 0x6b, 0x99, 0x68, 0xa1, 0x1f, 0x66, 0xd0, 0xd5, 0x69, 0x32, 0xad, 0x69, 0xf0, 0x95, 0xf5, 0xf3, + 0xb6, 0xda, 0x49, 0xc1, 0xa6, 0xe5, 0x9e, 0x6d, 0x6f, 0xc0, 0xae, 0xbb, 0x49, 0x3a, 0x74, 0x0c, + 0xb1, 0x99, 0x1d, 0x18, 0x2c, 0xb1, 0x1e, 0xe0, 0xc3, 0x25, 0xcd, 0xc1, 0x64, 0xc0, 0x83, 0x3d, + 0x3b, 0x7b, 0xc8, 0x87, 0x96, 0x0a, 0xdb, 0x10, 0x6f, 0x8b, 0x00, 0xbf, 0x3f, 0xc7, 0x73, 0x72, + 0xe5, 0x85, 0xcf, 0xac, 0x9b, 0xb4, 0x7d, 0x29, 0x50, 0xbc, 0xd7, 0x1f, 0x8e, 0x7a, 0x8d, 0x46, + 0xa1, 0x6c, 0x1a, 0x45, 0xc6, 0xd4, 0x5f, 0x4c, 0x26, 0x13, 0x93, 0x0e, 0x3b, 0xe3, 0x56, 0xa7, + 0x66, 0x70, 0x77, 0xf7, 0xd5, 0xd6, 0xbc, 0x36, 0x9d, 0x34, 0x06, 0xd3, 0xf0, 0x2b, 0x6d, 0x21, + 0x44, 0xdb, 0x09, 0x25, 0x63, 0x7d, 0x63, 0x13, 0x4f, 0x81, 0xbe, 0x45, 0x4e, 0x90, 0x93, 0x38, + 0x58, 0xb9, 0xd3, 0x8f, 0x90, 0x26, 0x5f, 0x27, 0xcd, 0xc0, 0xd5, 0xca, 0x88, 0xd3, 0x96, 0xa2, + 0x80, 0x3a, 0x22, 0x6a, 0xd2, 0x5b, 0x31, 0x27, 0xdb, 0x83, 0x7b, 0xd8, 0xc3, 0xb0, 0x20, 0x81, + 0xaa, 0xad, 0xfb, 0x75, 0x6d, 0xe5, 0xbe, 0x25, 0xcf, 0x3e, 0x82, 0xb8, 0x21, 0xd3, 0x81, 0xc3, + 0x80, 0x17, 0x18, 0xe8, 0xbe, 0xa6, 0xb6, 0x4e, 0x6b, 0x61, 0xbe, 0x72, 0xbf, 0x1e, 0x70, 0x1c, + 0x2b, 0xd6, 0x35, 0x74, 0x48, 0xe3, 0x0a, 0xdf, 0x8d, 0x97, 0xfd, 0xc4, 0x10, 0xd1, 0x0a, 0x3b, + 0x9f, 0xdd, 0xcc, 0x8a, 0xd7, 0x83, 0xf6, 0x17, 0x3d, 0x89, 0x0b, 0x7a, 0xb1, 0xb7, 0x35, 0x65, + 0xfa, 0x5a, 0x99, 0x9f, 0x6a, 0xca, 0x0c, 0xb2, 0x32, 0x25, 0x3e, 0x03, 0xc4, 0x4c, 0x0c, 0xcd, + 0x68, 0xdd, 0x0e, 0x65, 0xf0, 0x58, 0x18, 0x89, 0xf7, 0x47, 0x4d, 0x26, 0x05, 0x72, 0x65, 0x76, + 0x9a, 0xa3, 0x25, 0xfb, 0xd0, 0xdb, 0x77, 0x99, 0x69, 0xa0, 0x66, 0x43, 0x87, 0xf0, 0xfc, 0x06, + 0x8f, 0x50, 0x65, 0x79, 0xe3, 0xd2, 0x69, 0x11, 0xc9, 0x68, 0xb4, 0x39, 0x51, 0x17, 0x5c, 0x26, + 0xf6, 0xed, 0xd3, 0xdd, 0x5a, 0x1f, 0x30, 0x4e, 0xfa, 0x1b, 0xda, 0xbc, 0x6a, 0xfb, 0x09, 0x1d, + 0x3b, 0x28, 0x08, 0x7c, 0xe1, 0x38, 0x02, 0x08, 0xbc, 0x2a, 0x22, 0x1f, 0x54, 0x9d, 0x49, 0xb3, + 0x0c, 0x0d, 0x23, 0xb2, 0x0f, 0xac, 0xbe, 0xd8, 0xe5, 0x3a, 0x1d, 0xba, 0xee, 0x05, 0x08, 0x41, + 0xdf, 0xfb, 0xd9, 0xe2, 0x86, 0x31, 0xc8, 0x17, 0x0f, 0x76, 0x21, 0x38, 0x55, 0x88, 0xf9, 0xee, + 0xf5, 0x4d, 0x1d, 0x52, 0xa6, 0x8c, 0xef, 0xe9, 0x2a, 0x92, 0xf2, 0xce, 0x01, 0xd9, 0xac, 0xba, + 0x2a, 0x81, 0x06, 0xe3, 0x07, 0x42, 0x44, 0x35, 0x58, 0xc8, 0xd2, 0x9c, 0x02, 0x51, 0x6f, 0x0f, + 0xdd, 0x05, 0x4f, 0x5f, 0xa0, 0x0e, 0x04, 0x25, 0xf3, 0x32, 0xc0, 0xfb, 0x52, 0xbf, 0x05, 0x39, + 0x68, 0x5a, 0xb2, 0x77, 0x19, 0xd0, 0x47, 0xd7, 0x93, 0xbd, 0xde, 0x2b, 0x5f, 0x47, 0x04, 0xbe, + 0x57, 0xd4, 0xaa, 0xa0, 0x82, 0xd0, 0xd8, 0xd9, 0x9d, 0x67, 0xae, 0x1a, 0x51, 0x53, 0xbb, 0x22, + 0xad, 0xb7, 0xfe, 0x6c, 0x99, 0x8e, 0x59, 0xbe, 0x34, 0x4d, 0xbb, 0x9a, 0x43, 0xad, 0xea, 0x65, + 0x97, 0x6e, 0x98, 0x42, 0xbb, 0xe2, 0x2a, 0xdd, 0xed, 0x1a, 0x6f, 0x71, 0xe0, 0x13, 0xd3, 0x74, + 0x32, 0x0c, 0x9b, 0xdd, 0x8b, 0xdf, 0xfd, 0xf0, 0xfb, 0xcb, 0xee, 0xc2, 0x36, 0x0d, 0xda, 0x32, + 0x22, 0x53, 0x9b, 0xff, 0xf8, 0xbb, 0x9b, 0x6d, 0x7f, 0x67, 0xdd, 0x35, 0x7f, 0x97, 0xb4, 0xc4, + 0x23, 0x94, 0xe1, 0xee, 0x19, 0xb2, 0xd0, 0x77, 0x30, 0x60, 0x8a, 0x79, 0x68, 0xc2, 0xc2, 0x1d, + 0x8d, 0x1f, 0xe3, 0xd9, 0x79, 0x30, 0x2e, 0x20, 0xa2, 0x5f, 0xb5, 0xb1, 0xcd, 0x0f, 0x08, 0xcb, + 0xfb, 0xbc, 0x48, 0x01, 0x29, 0xc9, 0xee, 0x40, 0x9f, 0xcf, 0xd9, 0x6c, 0xa9, 0xef, 0xb1, 0xb3, + 0xb6, 0x55, 0xfb, 0x91, 0xb1, 0x2d, 0xbc, 0x31, 0x48, 0x5d, 0xcb, 0xf1, 0x0a, 0xde, 0xdf, 0xc3, + 0x7b, 0xf5, 0x26, 0x7a, 0x2c, 0x4d, 0x57, 0x35, 0xe9, 0xc5, 0xcf, 0x31, 0xa1, 0xbe, 0x7c, 0xc0, + 0x49, 0x89, 0xe7, 0xe5, 0xdf, 0x60, 0x42, 0x5d, 0xf9, 0x68, 0x9d, 0x17, 0x8d, 0xd6, 0x74, 0xee, + 0x4b, 0xdb, 0x07, 0x5a, 0xd8, 0xf5, 0x55, 0x4c, 0xff, 0x99, 0x14, 0x79, 0xa8, 0x84, 0xbe, 0x09, + 0x95, 0x93, 0x7d, 0x67, 0x55, 0xa3, 0x70, 0x1f, 0x81, 0xf1, 0xc6, 0xe7, 0x54, 0x27, 0x01, 0xdd, + 0x89, 0x5a, 0x4f, 0xb2, 0xff, 0x4c, 0x03, 0x82, 0xf0, 0xbd, 0x22, 0x74, 0xef, 0xb1, 0x83, 0x57, + 0xba, 0x8e, 0x26, 0xeb, 0x39, 0xd2, 0x2a, 0x5d, 0xfa, 0x89, 0x94, 0x52, 0x79, 0x19, 0x95, 0x6b, + 0xf6, 0x3a, 0x23, 0xd3, 0xce, 0xb8, 0xdf, 0xc5, 0x22, 0xf2, 0x26, 0x90, 0x4f, 0x24, 0xc8, 0xa0, + 0x15, 0xf8, 0x7c, 0x0e, 0x6a, 0xe3, 0x79, 0x10, 0x80, 0xc6, 0xf5, 0x5c, 0x13, 0x97, 0x1d, 0xcd, + 0x72, 0x19, 0x18, 0x15, 0xda, 0x89, 0x47, 0xe1, 0x91, 0x2e, 0xde, 0xe0, 0x61, 0xda, 0xd4, 0x5c, + 0x36, 0x13, 0x95, 0x26, 0xbc, 0x12, 0x7a, 0xa2, 0xb4, 0xcd, 0x4b, 0x70, 0xad, 0xfb, 0xdb, 0x01, + 0x51, 0xf7, 0x43, 0xd5, 0x90, 0x57, 0xd8, 0x1c, 0x88, 0x58, 0x0a, 0xe8, 0xb7, 0x8a, 0x51, 0x4a, + 0x3d, 0xef, 0x4b, 0x43, 0xe5, 0xef, 0xce, 0xbf, 0xda, 0x1a, 0x39, 0x2e, 0xde, 0xe6, 0xcb, 0xdd, + 0x72, 0xc9, 0xd6, 0x24, 0x5e, 0x23, 0x39, 0x7b, 0x7c, 0xd1, 0xaa, 0x81, 0x05, 0xb6, 0xc0, 0xf6, + 0x6a, 0xe8, 0x7a, 0x8e, 0x3c, 0x24, 0xa8, 0x8a, 0xb3, 0x76, 0x91, 0x20, 0x98, 0x5e, 0x09, 0x13, + 0xf9, 0x5e, 0xbb, 0xf0, 0x08, 0x26, 0xc6, 0x98, 0x23, 0xcf, 0xbd, 0x12, 0x17, 0x69, 0x82, 0x9d, + 0x7c, 0xd8, 0xaf, 0xc6, 0x25, 0x15, 0x15, 0x69, 0x30, 0x4a, 0x4b, 0xfc, 0xb2, 0x17, 0x15, 0xd5, + 0x48, 0x0e, 0x2a, 0xaa, 0x95, 0xfa, 0xbf, 0x57, 0x33, 0x5a, 0x4b, 0xaf, 0x01, 0x87, 0x35, 0x5a, + 0xa3, 0x03, 0xcc, 0x16, 0xe4, 0x9e, 0xe2, 0x9d, 0x48, 0x8a, 0x9d, 0x0f, 0x5d, 0x62, 0xe8, 0x1a, + 0x12, 0xa1, 0xe8, 0x64, 0x45, 0x6b, 0xf8, 0x4f, 0xde, 0x9a, 0x15, 0xb8, 0x59, 0x41, 0xed, 0xcc, + 0x0e, 0x5e, 0x5f, 0xa3, 0xab, 0xa3, 0x60, 0x9f, 0xce, 0xb8, 0x95, 0x4b, 0x70, 0xa7, 0x76, 0xbb, + 0x4b, 0x7e, 0xc9, 0x84, 0x35, 0x29, 0xc5, 0x00, 0xa2, 0x00, 0x08, 0x66, 0xca, 0x4a, 0xc5, 0xa5, + 0x76, 0xcb, 0xa1, 0x44, 0x6d, 0x8e, 0xf6, 0xc3, 0x04, 0xbc, 0xfe, 0x17, 0x1c, 0xb8, 0x10, 0x5a, + 0x12, 0x75, 0x42, 0x90, 0x8b, 0x8f, 0xfe, 0x34, 0x80, 0x19, 0x53, 0x23, 0x44, 0xb6, 0x93, 0x32, + 0xbf, 0x2c, 0x2d, 0xf7, 0x25, 0x4b, 0x8e, 0x3f, 0xed, 0xaa, 0xc2, 0xdd, 0x82, 0xe4, 0x0e, 0x59, + 0x5b, 0x71, 0x1a, 0x85, 0xb7, 0x82, 0xfc, 0x20, 0x0a, 0xd8, 0x15, 0xe6, 0xce, 0xc2, 0xcb, 0x6c, + 0x80, 0xe1, 0x71, 0x46, 0x8d, 0xae, 0xc0, 0x9c, 0x44, 0x91, 0x6c, 0x62, 0x48, 0xb5, 0x69, 0x7e, + 0x23, 0x8e, 0xcb, 0x04, 0x2d, 0x93, 0x02, 0xf8, 0x73, 0x34, 0x42, 0xf0, 0xb4, 0xa8, 0x69, 0xe5, + 0xb5, 0xb6, 0x60, 0x3f, 0xe2, 0x0d, 0x2a, 0x20, 0x72, 0x74, 0x5b, 0x51, 0x41, 0x86, 0x40, 0x1c, + 0x52, 0xc8, 0x36, 0xcf, 0xf1, 0xa2, 0x15, 0xbc, 0x2d, 0x2c, 0x85, 0x0e, 0x21, 0xc4, 0xa2, 0x1a, + 0xa1, 0xe9, 0xa1, 0x03, 0xfe, 0x28, 0x0b, 0x82, 0x5b, 0xe1, 0xd5, 0xed, 0x8a, 0x73, 0x45, 0xf5, + 0x52, 0xb7, 0xb6, 0x2e, 0xab, 0x96, 0xc7, 0x69, 0x8b, 0xd5, 0x21, 0xd7, 0xef, 0xbd, 0x92, 0x77, + 0x82, 0x5c, 0xbf, 0x62, 0xc9, 0x12, 0x35, 0x43, 0xc6, 0x9d, 0x33, 0xa1, 0x2f, 0x12, 0xb5, 0xdc, + 0x80, 0x6e, 0xa1, 0xcd, 0xf6, 0xdd, 0x14, 0x79, 0x22, 0x84, 0xae, 0x77, 0xa9, 0xd9, 0xab, 0x99, + 0xdb, 0xc7, 0x22, 0x62, 0xc2, 0x4f, 0x59, 0xe5, 0x01, 0x12, 0x4d, 0xe9, 0xa8, 0xfb, 0x54, 0x9a, + 0x0f, 0x95, 0xc4, 0x78, 0x8a, 0x0c, 0x67, 0x07, 0x56, 0x71, 0x75, 0x33, 0xac, 0x59, 0x5b, 0xb7, + 0xb0, 0xfd, 0xea, 0xb6, 0x6a, 0xe0, 0xee, 0x10, 0xae, 0x88, 0xe7, 0xbd, 0x8b, 0xdd, 0xc1, 0x58, + 0x3d, 0x9e, 0x1e, 0x67, 0x8f, 0xad, 0x96, 0x95, 0x66, 0x45, 0x6c, 0x89, 0x4a, 0x5e, 0xf0, 0x91, + 0x1d, 0xae, 0x01, 0x77, 0x08, 0xf0, 0x44, 0xa0, 0x7a, 0xc5, 0x4c, 0x2b, 0x8b, 0x5a, 0xe3, 0x4b, + 0xc5, 0x4d, 0x13, 0x41, 0xe5, 0x4e, 0x42, 0xda, 0x90, 0xcd, 0xa5, 0x3d, 0xa3, 0x6e, 0x58, 0xaa, + 0xd0, 0x46, 0xda, 0x68, 0xeb, 0x97, 0x2b, 0x3d, 0xa2, 0xe0, 0x1e, 0x0b, 0xd5, 0x96, 0xc4, 0x9b, + 0x26, 0x1e, 0x57, 0xf2, 0xe3, 0x6d, 0xf2, 0x48, 0x2c, 0x83, 0xe0, 0x31, 0x05, 0xb9, 0x55, 0xd6, + 0xdb, 0x79, 0x01, 0x5d, 0x1e, 0x8a, 0x13, 0x26, 0xf0, 0x7d, 0xaf, 0xb8, 0x23, 0x32, 0xd0, 0x37, + 0xbb, 0xc9, 0x5d, 0x48, 0xe5, 0xeb, 0xc0, 0xc2, 0xbd, 0x32, 0xb8, 0xe4, 0x42, 0xdb, 0xb3, 0x08, + 0x5d, 0x70, 0x77, 0x2d, 0x5c, 0xd5, 0x11, 0xae, 0x7b, 0x61, 0x61, 0x52, 0xe7, 0x44, 0xab, 0x70, + 0x61, 0x50, 0x36, 0x76, 0x50, 0xbb, 0xd1, 0xc8, 0x36, 0xbd, 0xa2, 0x69, 0xd0, 0x49, 0x28, 0x72, + 0x85, 0xc7, 0x95, 0xc4, 0xa8, 0x51, 0x91, 0xfc, 0x26, 0x90, 0x22, 0x1c, 0x55, 0x10, 0x29, 0x2c, + 0x0a, 0xca, 0x43, 0x53, 0x75, 0x05, 0x69, 0xd0, 0x44, 0xc9, 0xfc, 0xee, 0x90, 0xea, 0xa2, 0xc4, + 0x09, 0xa2, 0xa8, 0xd2, 0x4d, 0xb4, 0xe5, 0x5e, 0x2c, 0xb9, 0x88, 0x4d, 0x1d, 0xe3, 0x7c, 0x19, + 0x2a, 0xb4, 0x43, 0xba, 0x9d, 0x08, 0x92, 0x77, 0x61, 0x96, 0x1a, 0xd8, 0x41, 0xa3, 0xc1, 0x5a, + 0xad, 0x5d, 0xe1, 0x78, 0x79, 0x61, 0x60, 0x5a, 0xcc, 0x7e, 0xc4, 0x31, 0x8e, 0xbd, 0x1b, 0xca, + 0x60, 0x30, 0xd0, 0xbd, 0xfe, 0x08, 0x82, 0x08, 0x66, 0x28, 0xda, 0x5b, 0xaf, 0x53, 0xbe, 0x52, + 0x47, 0x14, 0xd0, 0x94, 0xc8, 0x56, 0x7c, 0xd4, 0x83, 0xbc, 0x0c, 0x51, 0xc3, 0x84, 0x0b, 0xc6, + 0xa3, 0x3a, 0x6d, 0x75, 0x45, 0x85, 0x8a, 0x96, 0x73, 0x25, 0xa3, 0x55, 0xd9, 0xae, 0x7e, 0xa3, + 0x62, 0x16, 0xa9, 0xda, 0xb3, 0x72, 0xb4, 0x18, 0x56, 0xf1, 0x4c, 0x60, 0x51, 0xf9, 0x2b, 0xb9, + 0x96, 0x67, 0x6b, 0xf0, 0x48, 0xcd, 0xb5, 0xb8, 0xa8, 0x6d, 0xff, 0xa2, 0x0f, 0xbd, 0x5e, 0x46, + 0x0b, 0xad, 0x22, 0x61, 0xab, 0xd6, 0x17, 0x6a, 0x2b, 0xe7, 0x77, 0x36, 0xaa, 0xcd, 0x07, 0x3a, + 0x35, 0x17, 0x45, 0x6a, 0xd2, 0xbe, 0x1f, 0x13, 0x67, 0x59, 0x93, 0xc8, 0xb2, 0x3f, 0x18, 0x39, + 0xe0, 0xc2, 0x25, 0x84, 0x34, 0x53, 0x88, 0x50, 0x2f, 0x73, 0x4d, 0x9e, 0xac, 0x87, 0x83, 0x64, + 0x60, 0xe6, 0x37, 0x60, 0xd2, 0xfd, 0x84, 0x13, 0x73, 0xbd, 0x89, 0xd7, 0x01, 0x07, 0x77, 0x5b, + 0x94, 0x18, 0xee, 0x97, 0xc0, 0xdf, 0xd6, 0x80, 0xfc, 0x45, 0xcc, 0x79, 0x68, 0xca, 0xa0, 0x30, + 0xa1, 0x49, 0x2b, 0x91, 0x30, 0x9d, 0x9b, 0x03, 0xb2, 0x46, 0xb2, 0x7a, 0x78, 0x21, 0xd6, 0x07, + 0x98, 0xf9, 0x4e, 0xdd, 0x51, 0x6f, 0x32, 0x70, 0x46, 0x76, 0xb4, 0x97, 0xd5, 0x4d, 0x6d, 0x79, + 0x1d, 0xd9, 0xca, 0x0f, 0x55, 0x4c, 0xa3, 0x9b, 0x66, 0x61, 0x8a, 0x6e, 0x33, 0x6a, 0x0d, 0x2c, + 0x3c, 0xfd, 0xde, 0xef, 0x7d, 0x1d, 0xdb, 0x9e, 0x1b, 0xc1, 0x67, 0x22, 0x6a, 0xcc, 0x83, 0x08, + 0x44, 0x5d, 0x55, 0x6a, 0xfb, 0x56, 0x77, 0x80, 0xd7, 0x64, 0x51, 0x64, 0x8e, 0x2e, 0x55, 0xa4, + 0x00, 0x46, 0xcf, 0xee, 0xa9, 0x18, 0x4b, 0x06, 0x15, 0x8a, 0x75, 0x3e, 0xbb, 0x09, 0x7c, 0xde, + 0xba, 0xb1, 0x1d, 0x76, 0xa6, 0x7c, 0xe1, 0x87, 0x1f, 0x00, 0xa6, 0x38, 0x09, 0xe7, 0x07, 0x01, + 0x19, 0x64, 0x2e, 0x93, 0x6f, 0x04, 0x08, 0xaa, 0x60, 0x05, 0xdb, 0xb7, 0xbd, 0x62, 0x29, 0x13, + 0x7f, 0xa7, 0xe4, 0x05, 0x85, 0xbc, 0x06, 0x62, 0x79, 0x56, 0xaf, 0xd3, 0xea, 0x77, 0x8e, 0x00, + 0xe7, 0x9e, 0xfd, 0x14, 0x3e, 0x87, 0x5f, 0xc7, 0x78, 0x86, 0xb4, 0x90, 0x3f, 0x90, 0xf9, 0x47, + 0x32, 0xbf, 0x08, 0x7b, 0x41, 0x3b, 0xe7, 0xea, 0xe1, 0x02, 0x46, 0x2d, 0xa8, 0x45, 0xd0, 0x9f, + 0xd6, 0x42, 0x57, 0xa5, 0x8e, 0xc4, 0x9f, 0xb5, 0xdf, 0x67, 0x18, 0x42, 0x97, 0x20, 0xb6, 0x4c, + 0xbc, 0x1d, 0x1c, 0x6f, 0x84, 0x37, 0x8b, 0x98, 0x4c, 0x03, 0x86, 0xc7, 0xd3, 0xc4, 0xe2, 0xf3, + 0x73, 0xbc, 0x16, 0xda, 0x35, 0x67, 0xd2, 0xb7, 0x15, 0x05, 0xd1, 0x73, 0x6b, 0x16, 0x98, 0x06, + 0xe9, 0xdc, 0x52, 0x08, 0x1c, 0x63, 0xc3, 0x03, 0xda, 0xd6, 0xda, 0xac, 0x86, 0x5c, 0xc0, 0xfc, + 0x58, 0x56, 0xeb, 0x0f, 0xe0, 0x61, 0x20, 0x11, 0xdf, 0xa3, 0x0e, 0xbf, 0xdd, 0xab, 0x38, 0xa4, + 0x2e, 0x7b, 0x6d, 0x22, 0x27, 0x91, 0x94, 0x98, 0x75, 0xa3, 0x4d, 0x3d, 0xe2, 0x1a, 0x9a, 0x94, + 0x6e, 0xa1, 0xc9, 0xa6, 0x1a, 0x48, 0x63, 0xa7, 0xd1, 0x98, 0xa9, 0xfd, 0x7c, 0x11, 0xee, 0x01, + 0x4e, 0x6e, 0x7c, 0xb4, 0x37, 0xf7, 0xae, 0x8b, 0xdd, 0x5c, 0x82, 0x96, 0x61, 0x30, 0xdd, 0xf4, + 0x1c, 0x28, 0xf7, 0xf4, 0xc4, 0xee, 0x3f, 0x1d, 0xda, 0x47, 0xbd, 0x4b, 0xb1, 0xfd, 0x7a, 0x4c, + 0x59, 0x7d, 0xcc, 0x1a, 0xf4, 0x21, 0x6f, 0xf8, 0xcc, 0x1e, 0x3d, 0x2b, 0xe4, 0x0d, 0x30, 0xaf, + 0x7f, 0x74, 0x0c, 0x75, 0xec, 0xc1, 0xe8, 0x58, 0xe5, 0xc9, 0x9f, 0x20, 0xa0, 0xcc, 0x67, 0x03, + 0x7b, 0x74, 0x62, 0x0f, 0x4f, 0x2e, 0x77, 0x7a, 0x9f, 0x7f, 0xa4, 0x1f, 0xf9, 0xf8, 0xc5, 0x36, + 0xba, 0xe8, 0x5d, 0xee, 0x6c, 0xfc, 0xee, 0xcb, 0xef, 0x01, 0x7d, 0x07, 0x17, 0x9b, 0xd6, 0xd1, + 0xe5, 0xce, 0xfa, 0x91, 0xb8, 0xbb, 0xc9, 0x5a, 0x9d, 0x23, 0x0b, 0x46, 0xb5, 0xcc, 0xe6, 0x28, + 0x00, 0x3d, 0x9a, 0x59, 0x70, 0x44, 0xee, 0xee, 0xf8, 0xa9, 0xdb, 0x6f, 0x34, 0x46, 0xc8, 0x67, + 0x60, 0xbe, 0x8b, 0x3a, 0x89, 0x33, 0x28, 0xbe, 0xb7, 0x4e, 0xbe, 0x8e, 0x1d, 0xed, 0x15, 0x87, + 0x28, 0xec, 0xb0, 0x78, 0x96, 0x09, 0x47, 0x67, 0x44, 0xbc, 0x3c, 0xf8, 0x9a, 0x24, 0xf4, 0xc3, + 0x6b, 0x35, 0x5e, 0xcd, 0x1a, 0x96, 0xfb, 0x7b, 0x70, 0xdc, 0xc6, 0x96, 0xad, 0xb7, 0xe2, 0xee, + 0xc8, 0xb2, 0x37, 0xb8, 0xc9, 0x78, 0xff, 0x76, 0x67, 0x83, 0x25, 0xb7, 0xe1, 0xec, 0x6c, 0x3f, + 0x5d, 0x1c, 0xd2, 0xf4, 0x57, 0xeb, 0x28, 0x4e, 0x57, 0x6c, 0x6d, 0x9e, 0x19, 0xdb, 0x03, 0x83, + 0xfe, 0xc9, 0xc4, 0xc4, 0x74, 0xb2, 0x24, 0x48, 0x4c, 0x97, 0xa0, 0x00, 0x21, 0x29, 0xbb, 0xbd, + 0x6b, 0x13, 0xae, 0xaf, 0x16, 0xb8, 0xbb, 0xbc, 0x4b, 0x59, 0xbf, 0xea, 0x75, 0x60, 0x5c, 0x3b, + 0xfd, 0xee, 0x74, 0x03, 0x96, 0x87, 0x48, 0x53, 0xb7, 0xdc, 0xff, 0x21, 0x31, 0xed, 0x12, 0xa4, + 0x2e, 0x18, 0x4f, 0x30, 0x5b, 0x75, 0x1f, 0x03, 0x91, 0x7f, 0x66, 0x2b, 0x50, 0xd2, 0x49, 0xf7, + 0x0f, 0xc9, 0xaa, 0x6b, 0x4a, 0x40, 0x3b, 0xfa, 0xde, 0x19, 0x5a, 0xcf, 0xba, 0xf2, 0x37, 0xd2, + 0xd0, 0x6d, 0x30, 0xa2, 0x30, 0x88, 0x98, 0xe7, 0x9a, 0xea, 0xaa, 0x60, 0xfc, 0x95, 0x34, 0xbc, + 0xf6, 0x90, 0x66, 0x60, 0x8c, 0xd0, 0x20, 0x66, 0x98, 0x28, 0xae, 0x97, 0x3b, 0x33, 0x0e, 0x4e, + 0x97, 0x7d, 0xa3, 0x70, 0x5b, 0x1a, 0x5e, 0x2a, 0x67, 0x9e, 0x3d, 0xf8, 0x9b, 0x6a, 0xcb, 0x3e, + 0x40, 0x61, 0xc6, 0x01, 0xee, 0x33, 0x74, 0x1f, 0xbc, 0xdc, 0xcc, 0x2c, 0xb6, 0x41, 0x17, 0xb2, + 0x99, 0x67, 0x7f, 0xf9, 0x97, 0x3f, 0x9d, 0x76, 0x19, 0xf5, 0x41, 0xa2, 0x73, 0x3a, 0x8d, 0xcf, + 0x0e, 0x00, 0xbb, 0xc1, 0x19, 0xa1, 0xed, 0x43, 0x57, 0xb4, 0x6d, 0x26, 0x30, 0xa0, 0x90, 0x0a, + 0x9f, 0x90, 0x6f, 0x9c, 0xd2, 0x52, 0x8f, 0x51, 0x38, 0x76, 0x6b, 0xc8, 0xe5, 0x26, 0xb4, 0xe3, + 0x8c, 0x03, 0xac, 0x4d, 0x26, 0x9d, 0x81, 0x97, 0x8d, 0xfa, 0xb3, 0x2b, 0x04, 0x26, 0xa6, 0x7e, + 0x72, 0xfe, 0xcd, 0xfb, 0x81, 0xa0, 0x3d, 0x46, 0xb3, 0xaa, 0x02, 0x45, 0x06, 0xda, 0xcf, 0x83, + 0x45, 0x66, 0xa0, 0x04, 0x23, 0x9e, 0x7f, 0x16, 0x18, 0x79, 0x15, 0xad, 0x04, 0x84, 0x46, 0xe8, + 0xcf, 0x83, 0x83, 0x86, 0xb4, 0x21, 0xc8, 0x83, 0x4f, 0x07, 0x3f, 0x0f, 0x19, 0xb2, 0xa8, 0x05, + 0x18, 0xf9, 0x7c, 0x0f, 0x20, 0x5c, 0xab, 0x3a, 0x33, 0xee, 0x90, 0x73, 0xe9, 0xe9, 0x5e, 0xc8, + 0x18, 0x13, 0x15, 0x9d, 0x14, 0x8b, 0x85, 0x5a, 0x2f, 0x33, 0xcb, 0xaf, 0x1e, 0x32, 0x1d, 0xf1, + 0x39, 0x23, 0x4b, 0xe9, 0xb4, 0x2b, 0x5e, 0x80, 0xcf, 0xe5, 0xd5, 0x66, 0x21, 0x19, 0xc4, 0x05, + 0x0b, 0x93, 0xba, 0x50, 0x4c, 0x81, 0xf6, 0xc8, 0xe4, 0xa2, 0x8e, 0x08, 0x9b, 0x2b, 0x6b, 0x4f, + 0x6c, 0xea, 0x3b, 0x50, 0xc8, 0xca, 0x5f, 0x10, 0xcc, 0x44, 0xe6, 0xb4, 0x2b, 0x0a, 0x64, 0x25, + 0x55, 0x41, 0xfc, 0x91, 0x3e, 0xf3, 0xec, 0x87, 0x37, 0xe7, 0xaf, 0xf6, 0x8b, 0x1c, 0xc8, 0x32, + 0xf2, 0x07, 0xf1, 0xcc, 0xb3, 0x5f, 0x8b, 0x87, 0x5a, 0x60, 0x1e, 0xbf, 0x36, 0xcf, 0x5e, 0xf1, + 0xeb, 0x7a, 0x50, 0x81, 0x90, 0xb1, 0x37, 0xf8, 0x55, 0x0f, 0x06, 0xaf, 0x9c, 0x3a, 0x7b, 0x05, + 0x9f, 0xf5, 0x80, 0xc8, 0x14, 0x3c, 0x43, 0x9b, 0xa7, 0x16, 0x0c, 0xfe, 0x2c, 0x9a, 0x79, 0x06, + 0x36, 0xde, 0x3d, 0x60, 0xe8, 0x07, 0xcf, 0x80, 0x4a, 0xf8, 0x55, 0x0b, 0x08, 0x7f, 0x87, 0xcc, + 0x3c, 0x7b, 0x07, 0x9f, 0x5a, 0x91, 0xae, 0x18, 0x15, 0x7c, 0x42, 0xf1, 0x3f, 0x30, 0x32, 0xdd, + 0x50, 0xf0, 0x6b, 0xce, 0x4a, 0xe9, 0xe8, 0xd2, 0xf4, 0xcc, 0x4c, 0xf5, 0x65, 0xa1, 0x35, 0x05, + 0x47, 0x14, 0x3f, 0x28, 0x94, 0xef, 0x3f, 0x58, 0xbe, 0x50, 0x7c, 0x00, 0x5c, 0xfa, 0x25, 0xe5, + 0x87, 0xf7, 0x82, 0x17, 0x5f, 0x07, 0x59, 0x35, 0xb5, 0xe5, 0xe1, 0xac, 0x81, 0xbf, 0x7c, 0xd8, + 0x1b, 0xef, 0x81, 0xcd, 0x96, 0xd8, 0x34, 0xfd, 0xce, 0x02, 0xa5, 0x26, 0x8d, 0xd3, 0xb5, 0x71, + 0x20, 0xd5, 0xae, 0xf8, 0x01, 0x0b, 0xb2, 0xa0, 0xce, 0x8c, 0xff, 0xfb, 0xbf, 0x8c, 0x41, 0x6f, + 0x30, 0x2a, 0x28, 0xf5, 0xbf, 0xfc, 0xe9, 0xff, 0x18, 0x6d, 0xe3, 0x8d, 0xf8, 0x8d, 0x02, 0xcf, + 0xd8, 0x84, 0x1e, 0x8f, 0xe5, 0x6f, 0x19, 0x9c, 0x76, 0xd7, 0x3a, 0xad, 0xc4, 0x06, 0xf2, 0xb7, + 0x3c, 0xdc, 0x64, 0x4a, 0x7d, 0xff, 0xe7, 0x37, 0xd4, 0x6f, 0xa0, 0xe0, 0x2f, 0x44, 0x61, 0x0f, + 0xd7, 0x67, 0xa7, 0x42, 0xc6, 0x75, 0x18, 0x2f, 0x28, 0xa5, 0x8f, 0xf8, 0x8a, 0xcc, 0x33, 0xd1, + 0x54, 0x5e, 0xb8, 0x5c, 0x76, 0x50, 0x51, 0xf6, 0xa0, 0xae, 0xf0, 0x70, 0xaf, 0x30, 0xea, 0x07, + 0xad, 0x18, 0x1d, 0x8e, 0x35, 0xa4, 0xe7, 0x6c, 0xe2, 0x36, 0x0a, 0xf3, 0xec, 0x20, 0xd3, 0x22, + 0x6a, 0x50, 0x70, 0x5e, 0xa5, 0x29, 0x0a, 0x7f, 0x91, 0xf4, 0xff, 0x01, 0x6e, 0x8e, 0xbb, 0x44, + 0xa9, 0x74, 0x00, 0x00 }; diff --git a/src/main.cpp b/src/main.cpp index 2f29b73b..fdf1aa74 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,22 +1,14 @@ /* @title StarMod @file main.cpp - @date 20240114 - @repo https://github.com/ewowi/StarMod + @date 20240411 + @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod @Authors https://github.com/ewowi/StarMod/commits/main @Copyright © 2024 Github StarMod Commit Authors @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com */ -// remove latest commit -// git reset --hard HEAD^ -// git push origin -f - -#warning ****************************************************************************************************************************** -#warning ********** STARMOD IS LICENSED UNDER GPL-V3. BY INSTALLING STARMOD YOU IMPLICITLY ACCEPT THE TERMS AND CONDITIONS ******** -#warning ****************************************************************************************************************************** - #include "SysModule.h" #include "SysModules.h" #include "Sys/SysModPrint.h" @@ -40,22 +32,10 @@ SysModNetwork *net; SysModPins *pins; UserModInstances *instances; UserModMDNS *mdns; -#ifdef STARMOD_APPMOD_LEDS - #include "App/LedModEffects.h" - #include "App/LedModFixture.h" - #include "App/LedModFixtureGen.h" - LedModFixture *fix; - LedModFixtureGen *lfg; - LedModEffects *eff; - #ifdef STARMOD_USERMOD_ARTNET - #include "User/UserModArtNet.h" - UserModArtNet *artnetmod; - #endif - #ifdef STARMOD_USERMOD_DDP - #include "User/UserModDDP.h" - UserModDDP *ddpmod; - #endif -#endif + +#include "App/AppModDemo.h" +AppModDemo *appModDemo; + #ifdef STARMOD_USERMOD_E131 #include "User/UserModE131.h" UserModE131 *e131mod; @@ -64,16 +44,9 @@ UserModMDNS *mdns; #include "User/UserModHA.h" UserModHA *hamod; #endif -#ifdef STARMOD_USERMOD_WLEDAUDIO - #include "User/UserModWLEDAudio.h" - UserModWLEDAudio *wledAudioMod; -#endif //setup all modules void setup() { - // pinMode(LED_BUILTIN, OUTPUT); - // digitalWrite(LED_BUILTIN, HIGH); - mdls = new SysModules(); print = new SysModPrint(); @@ -86,49 +59,26 @@ void setup() { pins = new SysModPins(); instances = new UserModInstances(); mdns = new UserModMDNS(); - #ifdef STARMOD_APPMOD_LEDS - eff= new LedModEffects(); - fix = new LedModFixture(); - lfg = new LedModFixtureGen(); - #ifdef STARMOD_USERMOD_ARTNET - artnetmod = new UserModArtNet(); - #endif - #ifdef STARMOD_USERMOD_DDP - ddpmod = new UserModDDP(); - #endif - #endif + appModDemo = new AppModDemo(); #ifdef STARMOD_USERMOD_E131 e131mod = new UserModE131(); #endif #ifdef STARMOD_USERMOD_HA hamod = new UserModHA(); #endif - #ifdef STARMOD_USERMOD_WLEDAUDIO - wledAudioMod = new UserModWLEDAudio(); - #endif //Reorder with care! this is the order in which setup and loop is executed //If changed make sure mdlEnabled.chFun executes var["value"].to(); and saveModel! //Default: add below, not in between - #ifdef STARMOD_APPMOD_LEDS - mdls->add(fix); - mdls->add(eff); - mdls->add(lfg); - #endif + + mdls->add(appModDemo); + mdls->add(files); mdls->add(sys); mdls->add(pins); mdls->add(print); mdls->add(web); mdls->add(net); - #ifdef STARMOD_APPMOD_LEDS - #ifdef STARMOD_USERMOD_DDP - mdls->add(ddpmod); - #endif - #ifdef STARMOD_USERMOD_ARTNET - mdls->add(artnetmod); - #endif - #endif #ifdef STARMOD_USERMOD_E131 mdls->add(e131mod); #endif @@ -137,16 +87,11 @@ void setup() { #endif mdls->add(mdl); mdls->add(ui); - #ifdef STARMOD_USERMOD_WLEDAUDIO - mdls->add(wledAudioMod); //no ui - #endif mdls->add(mdns); //no ui mdls->add(instances); //do not add mdls itself as it does setup and loop for itself!!! (it is the orchestrator) mdls->setup(); - - // digitalWrite(LED_BUILTIN, LOW); } //loop all modules diff --git a/tools/misc.txt b/tools/misc.txt index 91d4dbde..711c1049 100644 --- a/tools/misc.txt +++ b/tools/misc.txt @@ -3,6 +3,11 @@ search range-based for loop =========================== ^(?=.*\bfor\b)(?=.*\b:\b).*$ +remove latest commit +==================== +git reset --hard HEAD^ +git push origin -f + Make video from png and mov =========================== diff --git a/tools/post_build.py b/tools/post_build.py new file mode 100644 index 00000000..f27d886b --- /dev/null +++ b/tools/post_build.py @@ -0,0 +1,64 @@ +# @title StarMod +# @file post_build.py +# @date 20240411 +# @repo https://github.com/ewowi/StarMod, submit changes to this file as PRs to ewowi/StarMod +# @Authors https://github.com/ewowi/StarMod/commits/main +# @Copyright © 2024 Github StarMod Commit Authors +# @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +# @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com + +Import('env') +import os +import shutil +import gzip + +print("") +print("***************************************************************************************************************************") +print("********** STARMOD IS LICENSED UNDER GPL-V3. BY INSTALLING STARMOD YOU IMPLICITLY ACCEPT THE TERMS AND CONDITIONS ********") +print("***************************************************************************************************************************") +print("") + +isGitHub = "runner" in os.path.expanduser("~") #do not copy in github PlatformIO CI (/home/runner/ is output dir in github) + +if isGitHub: + OUTPUT_DIR = "build_output{}".format(os.path.sep) +else: + OUTPUT_DIR = "{}{}Downloads{}".format(os.path.expanduser("~"), os.path.sep, os.path.sep) + + +def _get_cpp_define_value(env, define): + define_list = [item[-1] for item in env["CPPDEFINES"] if item[0] == define] + if define_list: + return define_list[0] + return None + +def _create_dirs(dirs=["firmware", "map"]): + # check if output directories exist and create if necessary + if not os.path.isdir(OUTPUT_DIR): + os.mkdir(OUTPUT_DIR) + for d in dirs: + if not os.path.isdir("{}{}".format(OUTPUT_DIR, d)): + os.mkdir("{}{}".format(OUTPUT_DIR, d)) + +def bin_rename_copy(source, target, env): + app = _get_cpp_define_value(env, "APP") + version = _get_cpp_define_value(env, "VERSION") + pioenv = env["PIOENV"] + + if isGitHub: + _create_dirs(["release"]) + # create string with location and file names based on pioenv + bin_file = "{}release{}{}_{}_{}.bin".format(OUTPUT_DIR, os.path.sep, app, version, pioenv) + else: + bin_file = "{}{}_{}_{}.bin".format(OUTPUT_DIR, app, version, pioenv) + + # check if new target files exist and remove if necessary + for f in [bin_file]: #map_file, + if os.path.isfile(f): + os.remove(f) + + # copy firmware.bin to bin_file + shutil.copy(str(target[0]), bin_file) + print(" created " + bin_file) + +env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_rename_copy])