From dcec8aaccae0299dec2bc1b63cd4e81414a011a5 Mon Sep 17 00:00:00 2001 From: someoneWasTaken94 <121205769+someoneWasTaken94@users.noreply.github.com> Date: Thu, 22 Dec 2022 13:31:25 +0000 Subject: [PATCH 1/5] most of multi-size code implemented --- src/data/layers/factory.tsx | 172 ++++++++++++++++++++++++++---------- 1 file changed, 123 insertions(+), 49 deletions(-) diff --git a/src/data/layers/factory.tsx b/src/data/layers/factory.tsx index 324704b..321fa90 100644 --- a/src/data/layers/factory.tsx +++ b/src/data/layers/factory.tsx @@ -394,6 +394,10 @@ const factory = createLayer(id, () => { type: "command" | "conveyor" | "processor"; description: string; energyCost?: number; + size?: { + width: number; + height: number; + }; /** amount it consumes */ inputs?: Record< @@ -433,7 +437,20 @@ const factory = createLayer(id, () => { interface FactoryInternalProcessor extends FactoryInternalBase { type: Exclude; } - type FactoryInternal = FactoryInternalConveyor | FactoryInternalProcessor; + + /** + * Fragment is just a hint that this spot is occupied by another component + * Does not actually do anything, but stores the string that the actual + * component is stored under + */ + interface FactoryInternalFragment { + type: "fragment"; + initalLocation: string; + } + type FactoryInternal = + | FactoryInternalConveyor + | FactoryInternalProcessor + | FactoryInternalFragment; interface Block { sprite: Sprite; @@ -538,6 +555,7 @@ const factory = createLayer(id, () => { const _data = components.value[id]; const _compData = compInternalData[id]; if (_data === undefined || _compData === undefined) continue; + if (_compData.type === "fragment") continue; const factoryData = FACTORY_COMPONENTS[_data.type]; // debugger; if (_data.type === "conveyor") { @@ -555,7 +573,7 @@ const factory = createLayer(id, () => { const dirAmt = directionToNum(inputDirection); if (dirType === "h") { if ((block.x - x) * dirAmt >= 1 + block.turbulance) { - const compBehind = compInternalData[x + dirAmt + "x" + y]; + let compBehind = compInternalData[x + dirAmt + "x" + y]; const storedComp = components.value[x + dirAmt + "x" + y]; // empty spot @@ -568,6 +586,12 @@ const factory = createLayer(id, () => { block.turbulance = Math.random() * 0.4 - 0.2; (compBehind as FactoryInternalConveyor).nextPackages.push(block); } else { + if (compBehind.type === "fragment") { + // this should be a factory processor, if it isn't something went wrong + compBehind = compInternalData[ + compBehind.initalLocation + ] as FactoryInternalProcessor; + } // send it to the factory // destory its sprite and data const factoryData = storedComp as FactoryComponentProcessor; @@ -591,7 +615,7 @@ const factory = createLayer(id, () => { } } else { if ((block.y - y) * dirAmt >= 1 + block.turbulance) { - const compBehind = compInternalData[x + "x" + (y + dirAmt)]; + let compBehind = compInternalData[x + "x" + (y + dirAmt)]; const storedComp = components.value[x + "x" + (y + dirAmt)]; // empty spot @@ -606,6 +630,12 @@ const factory = createLayer(id, () => { } else { // send it to the factory // destory its sprite and data + if (compBehind.type === "fragment") { + // this should be a factory processor, if it isn't something went wrong + compBehind = compInternalData[ + compBehind.initalLocation + ] as FactoryInternalProcessor; + } const data = storedComp as FactoryComponentProcessor; if (factoryData.inputs?.[block.type] !== undefined) { if (data.inputStock === undefined) data.inputStock = {}; @@ -747,6 +777,10 @@ const factory = createLayer(id, () => { const factoryBaseData = FACTORY_COMPONENTS[data.type]; if (factoryBaseData == undefined) return; + const size = factoryBaseData.size ?? { width: 1, height: 1 }; + + // this is too big + if (x + size.width >= factorySize.width || y + size.height >= factorySize.height) return; const sheet = Assets.get(factoryBaseData.imageSrc); const sprite = new Sprite(sheet); @@ -805,18 +839,43 @@ const factory = createLayer(id, () => { }), sprite } as FactoryInternalProcessor; + for (let _x = 0; _x < size.width; _x++) { + for (let _y = 0; _y < size.height; _y++) { + compInternalData[_x + "x" + _y] = { + type: "fragment", + initalLocation: x + "x" + y + }; + } + } spriteContainer.addChild(sprite); } - + function removeFactoryComp(x: number, y: number) { const data = compInternalData[x + "x" + y]; if (data === undefined) return; + if (data.type === "fragment") { + const [x, y] = data.initalLocation.split("x").map(i => +i); + removeFactoryComp(x, y); + return; + } + if (data.type === "conveyor") { const cData = data as FactoryInternalConveyor; for (const p of cData.packages) { p.sprite.destroy(); } + } else { + const size = FACTORY_COMPONENTS[data.type].size ?? { width: 1, height: 1 }; + + // delete all components + for (let x = 0; x < size.width; x++) { + for (let y = 0; y < size.height; y++) { + // this will be handled below + if (x === 0 && y === 0) continue; + delete compInternalData[x + "x" + y]; + } + } } delete components.value[x + "x" + y]; @@ -917,7 +976,8 @@ const factory = createLayer(id, () => { if (compSelected.value === "rotateLeft") { if ( components.value[x + "x" + y] != null && - components.value[x + "x" + y].direction != null + components.value[x + "x" + y].direction != null && + compInternalData[x + "x" + y].type !== "fragment" ) { components.value[x + "x" + y] = { ...components.value[x + "x" + y], @@ -927,12 +987,15 @@ const factory = createLayer(id, () => { Direction.Left ) }; - compInternalData[x + "x" + y].sprite.rotation -= Math.PI / 2; + ( + compInternalData[x + "x" + y] as FactoryInternalProcessor + ).sprite.rotation -= Math.PI / 2; } } else if (compSelected.value === "rotateRight") { if ( components.value[x + "x" + y] != null && - components.value[x + "x" + y].direction != null + components.value[x + "x" + y].direction != null && + compInternalData[x + "x" + y]?.type !== "fragment" ) { components.value[x + "x" + y] = { ...components.value[x + "x" + y], @@ -942,9 +1005,18 @@ const factory = createLayer(id, () => { Direction.Right ) }; - compInternalData[x + "x" + y].sprite.rotation += Math.PI / 2; + ( + compInternalData[x + "x" + y] as FactoryInternalProcessor + ).sprite.rotation += Math.PI / 2; } } else if (compSelected.value === "delete") { + if (compInternalData[x + "x" + y]?.type === "fragment") { + [x, y] = ( + compInternalData[x + "x" + y] as FactoryInternalFragment + ).initalLocation + .split("x") + .map(i => +i); + } removeFactoryComp(x, y); } else if (compSelected.value !== "cursor") { if (components.value[x + "x" + y] == null) { @@ -976,10 +1048,11 @@ const factory = createLayer(id, () => { function onCompClick(name: FactoryCompNames) { compSelected.value = name; } - + function setTracks() { for (const [key, comp] of Object.entries(compInternalData)) { if (comp == null) continue; + if (comp.type === "fragment") continue; if (comp.type === "conveyor") { for (const pkg of [...comp.nextPackages, ...comp.packages]) { pkg.sprite.destroy(); @@ -988,7 +1061,7 @@ const factory = createLayer(id, () => { comp.nextPackages = []; comp.packages = []; } else { - const producerComp = components.value[key] as FactoryComponentProducer; + const producerComp = components.value[key] as FactoryComponentProcessor; if (producerComp.outputStock !== undefined) { for (const key in producerComp.outputStock) { delete producerComp.outputStock[key]; @@ -1003,9 +1076,10 @@ const factory = createLayer(id, () => { } } } - + function clearFactory() { for (const key of Object.keys(compInternalData)) { + if (compInternalData[key].type === "fragment") continue; const [x, y] = key.split("x").map(i => +i); removeFactoryComp(x, y); } @@ -1059,44 +1133,44 @@ const factory = createLayer(id, () => { onContextmenu={(e: MouseEvent) => e.preventDefault()} />
- - - - -
- + + + + + +
Date: Fri, 23 Dec 2022 01:08:46 +0000 Subject: [PATCH 2/5] do changes --- src/data/layers/factory.tsx | 179 +++++++++++++++++------------------- 1 file changed, 85 insertions(+), 94 deletions(-) diff --git a/src/data/layers/factory.tsx b/src/data/layers/factory.tsx index 0f426df..388d6de 100644 --- a/src/data/layers/factory.tsx +++ b/src/data/layers/factory.tsx @@ -29,8 +29,8 @@ import { noPersist, Persistent, persistent, State } from "game/persistence"; import Decimal, { DecimalSource, format, formatWhole } from "util/bignum"; import { Direction } from "util/common"; import { ProcessedComputable } from "util/computed"; -import { render, renderRow } from "util/vue"; -import { computed, ComputedRef, reactive, ref, unref, watchEffect } from "vue"; +import { render, renderRow, VueFeature } from "util/vue"; +import { computed, ComputedRef, reactive, ref, shallowRef, unref, watchEffect } from "vue"; import coal from "./coal"; import _block from "./factory-components/block.svg"; import _blockMaker from "./factory-components/blockmaker.svg"; @@ -249,7 +249,7 @@ const factory = createLayer(id, () => { key: "0", name: "Conveyor", type: "conveyor", - description: "Moves items at 1 block per second.", + description: "Moves items at 1 block per tick.", energyCost: 1, tick: 1, ports: { @@ -267,7 +267,7 @@ const factory = createLayer(id, () => { key: "1", name: "Wood Machine", type: "processor", - description: "Produces 1 wood every 1 second.", + description: "Produces 1 wood per tick.", energyCost: 10, tick: 1, outputs: { @@ -282,7 +282,7 @@ const factory = createLayer(id, () => { key: "2", name: "Cloth Machine", type: "processor", - description: "Produces 1 cloth every 1 second.", + description: "Produces 1 cloth per tick.", energyCost: 10, tick: 1, outputs: { @@ -297,7 +297,7 @@ const factory = createLayer(id, () => { key: "3", name: "Dye Machine", type: "processor", - description: "Produces 1 dye every 1 second.", + description: "Produces 1 dye per tick.", energyCost: 10, tick: 1, outputs: { @@ -312,7 +312,7 @@ const factory = createLayer(id, () => { key: "4", name: "Metal Machine", type: "processor", - description: "Produces 1 metal every 1 second.", + description: "Produces 1 metal per tick.", energyCost: 10, tick: 1, outputs: { @@ -327,7 +327,7 @@ const factory = createLayer(id, () => { key: "5", name: "Plastic Machine", type: "processor", - description: "Produces 1 plastic every 1 second.", + description: "Produces 1 plastic per tick.", energyCost: 10, tick: 1, outputs: { @@ -341,7 +341,7 @@ const factory = createLayer(id, () => { key: "shift+1", name: "Sawmill", type: "processor", - description: "Turns 1 wood into 1 plank every second.", + description: "Turns 1 wood into 1 plank per tick.", energyCost: 2, tick: 1, inputs: { @@ -360,7 +360,7 @@ const factory = createLayer(id, () => { key: "shift+2", name: "Thread Spinner", type: "processor", - description: "Turns 1 cloth into 1 thread every second.", + description: "Turns 1 cloth into 1 thread per tick.", energyCost: 2, tick: 1, inputs: { @@ -384,7 +384,7 @@ const factory = createLayer(id, () => { () => `Turns 1 plastic into ${ toys.milestones.milestone5.earned.value ? "2 wheels" : "1 wheel" - } every second.` + } per tick.` ), energyCost: 2, tick: 1, @@ -404,7 +404,7 @@ const factory = createLayer(id, () => { key: "ctrl+shift+1", name: "Wooden Block Maker", type: "processor", - description: "Turns 1 plank into 1 wooden block every second.", + description: "Turns 1 plank into 1 wooden block per tick.", energyCost: 20, tick: 1, inputs: { @@ -424,7 +424,7 @@ const factory = createLayer(id, () => { key: "ctrl+shift+2", name: "Clothes Maker", type: "processor", - description: "Turns 2 threads, 3 cloth, and 1 dye into 1 clothes every second.", + description: "Turns 2 threads, 3 cloth, and 1 dye into 1 clothes per tick.", energyCost: 20, tick: 1, inputs: { @@ -450,7 +450,7 @@ const factory = createLayer(id, () => { key: "ctrl+shift+3", name: "Trucks Maker", type: "processor", - description: "Turns 2 metal and 4 wheels into 1 truck every second.", + description: "Turns 2 metal and 4 wheels into 1 truck per tick.", energyCost: 20, tick: 1, inputs: { @@ -575,10 +575,6 @@ const factory = createLayer(id, () => { type: "command" | "conveyor" | "processor"; description: ProcessedComputable; energyCost?: number; - size?: { - width: number; - height: number; - }; /** amount it consumes */ inputs?: Stock; @@ -605,21 +601,12 @@ const factory = createLayer(id, () => { } interface FactoryInternalProcessor extends FactoryInternalBase { type: Exclude; - } + lastProdTimes: number[]; - /** - * Fragment is just a hint that this spot is occupied by another component - * Does not actually do anything, but stores the string that the actual - * component is stored under - */ - interface FactoryInternalFragment { - type: "fragment"; - initalLocation: string; + lastFactoryProd: number; + average: ComputedRef; } - type FactoryInternal = - | FactoryInternalConveyor - | FactoryInternalProcessor - | FactoryInternalFragment; + type FactoryInternal = FactoryInternalConveyor | FactoryInternalProcessor; interface Block { sprite: Sprite; @@ -760,9 +747,6 @@ const factory = createLayer(id, () => { loaded = true; watchEffect(updateGraphics); }); - (window as any).internal = compInternalData; - (window as any).comp = components; - (window as any).blocks = movingBlocks; function moveBlock(block: Block, newBlock: FactoryInternal, blockData: FactoryComponent) { // empty spot @@ -800,7 +784,6 @@ const factory = createLayer(id, () => { const _data = components.value[id]; const _compData = compInternalData[id]; if (_data === undefined || _compData === undefined) continue; - if (_compData.type === "fragment") continue; const factoryData = FACTORY_COMPONENTS[_data.type]; // debugger; if (_data.type === "conveyor") { @@ -818,7 +801,7 @@ const factory = createLayer(id, () => { const dirAmt = directionToNum(inputDirection); if (dirType === "h") { if ((block.x - x) * dirAmt >= 1 + block.turbulance) { - let compBehind = compInternalData[x + dirAmt + "x" + y]; + const compBehind = compInternalData[x + dirAmt + "x" + y]; const storedComp = components.value[x + dirAmt + "x" + y]; moveBlock(block, compBehind, storedComp); @@ -834,7 +817,7 @@ const factory = createLayer(id, () => { } } else { if ((block.y - y) * dirAmt >= 1 + block.turbulance) { - let compBehind = compInternalData[x + "x" + (y + dirAmt)]; + const compBehind = compInternalData[x + "x" + (y + dirAmt)]; const storedComp = components.value[x + "x" + (y + dirAmt)]; moveBlock(block, compBehind, storedComp); @@ -883,6 +866,12 @@ const factory = createLayer(id, () => { } } data.ticksDone -= cyclesDone * factoryData.tick; + const now = Date.now(); + const diff = (now - compData.lastFactoryProd) / 1000; + compData.lastProdTimes.push(diff); + console.log(compData.lastProdTimes); + if (compData.lastProdTimes.length > 10) compData.lastProdTimes.shift(); + compData.lastFactoryProd = now; } } else { data.ticksDone += factoryTicks; @@ -982,10 +971,6 @@ const factory = createLayer(id, () => { const factoryBaseData = FACTORY_COMPONENTS[data.type]; if (factoryBaseData == undefined) return; - const size = factoryBaseData.size ?? { width: 1, height: 1 }; - - // this is too big - if (x + size.width >= factorySize.width || y + size.height >= factorySize.height) return; const sheet = Assets.get(factoryBaseData.imageSrc); const sprite = new Sprite(sheet); @@ -1031,6 +1016,26 @@ const factory = createLayer(id, () => { type: data.type, packages: isConveyor ? [] : undefined, nextPackages: isConveyor ? [] : undefined, + lastProdTimes: !isConveyor ? (reactive([]) as number[]) : undefined, + lastFactoryProd: !isConveyor + ? Date.now() - + 1000 * Decimal.div(data.ticksDone ?? 0, computedTickRate.value).toNumber() + : undefined, + average: !isConveyor + ? computed(() => { + const times = (compInternalData[x + "x" + y] as FactoryInternalProcessor) + .lastProdTimes; + if (times.length === 0) return undefined; + + // times is in SECONDS, not ticks + // seconds * Ticks per second -> ticks taken + + return Decimal.mul(times.length, factoryBaseData.tick) + .div(times.reduce((x, n) => x + n, 0)) + .div(computedTickRate.value) + .toNumber(); + }) + : undefined, canProduce: computed(() => { if (data.type === "conveyor") return true; if (!(factoryBaseData.canProduce?.value ?? true)) return false; @@ -1054,14 +1059,6 @@ const factory = createLayer(id, () => { }), sprite } as FactoryInternalProcessor; - for (let _x = 0; _x < size.width; _x++) { - for (let _y = 0; _y < size.height; _y++) { - compInternalData[_x + "x" + _y] = { - type: "fragment", - initalLocation: x + "x" + y - }; - } - } spriteContainer.addChild(sprite); } @@ -1069,28 +1066,11 @@ const factory = createLayer(id, () => { const data = compInternalData[x + "x" + y]; if (data === undefined) return; - if (data.type === "fragment") { - const [x, y] = data.initalLocation.split("x").map(i => +i); - removeFactoryComp(x, y); - return; - } - if (data.type === "conveyor") { const cData = data as FactoryInternalConveyor; for (const p of cData.packages) { p.sprite.destroy(); } - } else { - const size = FACTORY_COMPONENTS[data.type].size ?? { width: 1, height: 1 }; - - // delete all components - for (let x = 0; x < size.width; x++) { - for (let y = 0; y < size.height; y++) { - // this will be handled below - if (x === 0 && y === 0) continue; - delete compInternalData[x + "x" + y]; - } - } } delete components.value[x + "x" + y]; @@ -1135,6 +1115,7 @@ const factory = createLayer(id, () => { const pointerDown = ref(false), pointerDrag = ref(false), compHovered = ref(undefined), + compInternalHovered = shallowRef(undefined), paused = ref(false); function onFactoryPointerMove(e: PointerEvent) { @@ -1164,12 +1145,12 @@ const factory = createLayer(id, () => { } if (!pointerDown.value && !pointerDrag.value) { const { tx, ty } = spriteContainer.localTransform; - compHovered.value = - components.value[ - Math.round(roundDownTo(x - tx, blockSize) / blockSize) + - "x" + - Math.round(roundDownTo(y - ty, blockSize) / blockSize) - ]; + const xyPos = + Math.round(roundDownTo(x - tx, blockSize) / blockSize) + + "x" + + Math.round(roundDownTo(y - ty, blockSize) / blockSize); + compHovered.value = components.value[xyPos]; + compInternalHovered.value = compInternalData[xyPos]; } } function onFactoryPointerDown(e: PointerEvent) { @@ -1191,8 +1172,7 @@ const factory = createLayer(id, () => { if (compSelected.value === "rotateLeft") { if ( components.value[x + "x" + y] != null && - components.value[x + "x" + y].direction != null && - compInternalData[x + "x" + y].type !== "fragment" + components.value[x + "x" + y].direction != null ) { components.value[x + "x" + y] = { ...components.value[x + "x" + y], @@ -1202,15 +1182,12 @@ const factory = createLayer(id, () => { Direction.Left ) }; - ( - compInternalData[x + "x" + y] as FactoryInternalProcessor - ).sprite.rotation -= Math.PI / 2; + compInternalData[x + "x" + y].sprite.rotation -= Math.PI / 2; } } else if (compSelected.value === "rotateRight") { if ( components.value[x + "x" + y] != null && - components.value[x + "x" + y].direction != null && - compInternalData[x + "x" + y]?.type !== "fragment" + components.value[x + "x" + y].direction != null ) { components.value[x + "x" + y] = { ...components.value[x + "x" + y], @@ -1220,18 +1197,9 @@ const factory = createLayer(id, () => { Direction.Right ) }; - ( - compInternalData[x + "x" + y] as FactoryInternalProcessor - ).sprite.rotation += Math.PI / 2; + compInternalData[x + "x" + y].sprite.rotation += Math.PI / 2; } } else if (compSelected.value === "delete") { - if (compInternalData[x + "x" + y]?.type === "fragment") { - [x, y] = ( - compInternalData[x + "x" + y] as FactoryInternalFragment - ).initalLocation - .split("x") - .map(i => +i); - } removeFactoryComp(x, y); } else if (compSelected.value !== "cursor") { if (components.value[x + "x" + y] == null) { @@ -1267,7 +1235,6 @@ const factory = createLayer(id, () => { function setTracks() { for (const [key, comp] of Object.entries(compInternalData)) { if (comp == null) continue; - if (comp.type === "fragment") continue; if (comp.type === "conveyor") { const cComp = comp as FactoryInternalConveyor; for (const pkg of [...cComp.nextPackages, ...cComp.packages]) { @@ -1278,6 +1245,7 @@ const factory = createLayer(id, () => { cComp.packages = []; } else { const producerComp = components.value[key] as FactoryComponentProcessor; + const cComp = comp as FactoryInternalProcessor; if (producerComp.outputStock !== undefined) { for (const key in producerComp.outputStock) { delete producerComp.outputStock[key as ResourceNames]; @@ -1289,13 +1257,14 @@ const factory = createLayer(id, () => { } } producerComp.ticksDone = 0; + cComp.lastFactoryProd = Date.now(); + cComp.lastProdTimes.splice(0, Infinity); } } } function clearFactory() { for (const key of Object.keys(compInternalData)) { - if (compInternalData[key].type === "fragment") continue; const [x, y] = key.split("x").map(i => +i); removeFactoryComp(x, y); } @@ -1401,7 +1370,7 @@ const factory = createLayer(id, () => { } const hoveredComponent = jsx(() => - compHovered.value !== undefined ? ( + compHovered.value !== undefined && compInternalHovered.value !== undefined ? (
{
{unref(FACTORY_COMPONENTS[compHovered.value.type].description)}
- {compHovered.value.type !== "conveyor" ? ( + {compHovered.value.type !== "conveyor" && + compInternalHovered.value.type !== "conveyor" ? ( <> {showStockAmount( compHovered.value.inputStock, @@ -1435,6 +1405,27 @@ const factory = createLayer(id, () => { "Outputs:", false )} +
+ Efficency:{" "} + {compInternalHovered.value.average.value !== undefined ? ( + 1 + ? "purple" + : compInternalHovered.value.average.value >= 0.9 + ? "green" + : compInternalHovered.value.average.value >= 0.5 + ? "yellow" + : "red" + }} + > + {formatWhole(compInternalHovered.value.average.value * 100)} + + ) : ( + "--" + )} + % ) : undefined}
@@ -1595,7 +1586,7 @@ const factory = createLayer(id, () => { display: jsx(() => ( <> {render(modifiersModal)} - {render(tabs)} + {render(tabs as VueFeature)} )) }; From 529eabbcd05c880f6ee086d218a824056fa05f19 Mon Sep 17 00:00:00 2001 From: someoneWasTaken94 <121205769+someoneWasTaken94@users.noreply.github.com> Date: Fri, 23 Dec 2022 16:36:13 +0000 Subject: [PATCH 3/5] stuff --- src/data/layers/factory.tsx | 437 ++++++++---------------------------- 1 file changed, 90 insertions(+), 347 deletions(-) diff --git a/src/data/layers/factory.tsx b/src/data/layers/factory.tsx index e50955f..db463b3 100644 --- a/src/data/layers/factory.tsx +++ b/src/data/layers/factory.tsx @@ -33,51 +33,29 @@ import { Direction, WithRequired } from "util/common"; import { ProcessedComputable } from "util/computed"; import { render, renderGrid, renderRow, VueFeature } from "util/vue"; import { computed, ComputedRef, reactive, ref, shallowRef, unref, watchEffect } from "vue"; -import boxes from "./boxes"; -import coal from "./coal"; -import dyes from "./dyes"; -import Factory from "./Factory.vue"; -import metal from "./metal"; -import oil from "./oil"; -import paper from "./paper"; -import plastic from "./plastic"; -import "./styles/factory.css"; -import Toy from "./Toy.vue"; -import toys from "./toys"; -import trees from "./trees"; -import workshop from "./workshop"; - import _cloth from "../symbols/cloth.png"; import _dye from "../symbols/dyes.png"; import _metal from "../symbols/metal.png"; import _plastic from "../symbols/plastic.png"; -import _boxes from "../symbols/cardboardBox.png"; -import _wrappingPaper from "../symbols/wrappingPaper.png"; -import _ribbon from "../symbols/ribbons.png"; - +import boxes from "./boxes"; +import coal from "./coal"; +import dyes from "./dyes"; import _bear from "./factory-components/bear.svg"; import _bearMaker from "./factory-components/bearmaker.svg"; -import _bearWrapper from "./factory-components/__placeholder.png"; import _block from "./factory-components/block.svg"; import _blockMaker from "./factory-components/blockmaker.svg"; -import _blockWrapper from "./factory-components/__placeholder.png"; -import _bow from "./factory-components/__placeholder.png"; -import _bowMaker from "./factory-components/__placeholder.png"; import _bucket from "./factory-components/bucket.svg"; import _bucketMaker from "./factory-components/bucketmaker.svg"; import _bucketShovel from "./factory-components/bucketshovel.svg"; import _bucketShovelMaker from "./factory-components/bucketshovelmaker.svg"; -import _bucketShovelWrapper from "./factory-components/__placeholder.png"; import _button from "./factory-components/button.svg"; import _buttonMaker from "./factory-components/buttonmaker.svg"; import _circuitBoard from "./factory-components/circuit.svg"; import _circuitBoardMaker from "./factory-components/circuitmaker.svg"; import _clothes from "./factory-components/clothes.svg"; import _clothesMaker from "./factory-components/clothesmaker.svg"; -import _clothesWrapper from "./factory-components/__placeholder.png"; import _console from "./factory-components/console.svg"; import _consoleMaker from "./factory-components/consolemaker.svg"; -import _consoleWrapper from "./factory-components/__placeholder.png"; import _conveyor from "./factory-components/conveyor.png"; import _cursor from "./factory-components/cursor.svg"; import _delete from "./factory-components/delete.svg"; @@ -95,11 +73,18 @@ import _thread from "./factory-components/thread.svg"; import _threadMaker from "./factory-components/threadmaker.svg"; import _truck from "./factory-components/truck.svg"; import _truckMaker from "./factory-components/truckmaker.svg"; -import _truckWrapper from "./factory-components/__placeholder.png"; import _wheel from "./factory-components/wheel.svg"; import _wheelMaker from "./factory-components/wheelmaker.svg"; -import _wrappedBox from "./factory-components/__placeholder.png"; -import _wrappedBoxMaker from "./factory-components/__placeholder.png"; +import Factory from "./Factory.vue"; +import metal from "./metal"; +import oil from "./oil"; +import paper from "./paper"; +import plastic from "./plastic"; +import "./styles/factory.css"; +import Toy from "./Toy.vue"; +import toys from "./toys"; +import trees from "./trees"; +import workshop from "./workshop"; const id = "factory"; @@ -221,7 +206,10 @@ const factory = createLayer(id, () => { createMultiplicativeModifier(() => ({ multiplier: Decimal.lt(energyEfficiency.value, 1) ? 1 - : Decimal.sub(2, Decimal.div(energyConsumption.value, Decimal.max(computedEnergy.value, 1))), + : Decimal.sub( + 2, + Decimal.div(energyConsumption.value, Decimal.max(computedEnergy.value, 1)) + ), description: "Brighter work rooms", enabled: () => upgrades[2][0].bought.value })), @@ -302,17 +290,29 @@ const factory = createLayer(id, () => { // ---------------------------------------------- Components - function generateComponentDescription(declaration: FactoryComponentDeclaration) { - let str = declaration.inputs === undefined ? "Produces " : "Turns "; if (declaration.inputs !== undefined) { - str += formatList(Object.entries(declaration.inputs) - .map(x => formatWhole(unref(x[1].amount)) + " " + RESOURCES[x[0] as ResourceNames].name)) + " into "; + str += + formatList( + Object.entries(declaration.inputs).map( + x => + formatWhole(unref(x[1].amount)) + + " " + + RESOURCES[x[0] as ResourceNames].name + ) + ) + " into "; } if (declaration.outputs !== undefined) { - str += formatList(Object.entries(declaration.outputs) - .map(x => formatWhole(unref(x[1].amount)) + " " + RESOURCES[x[0] as ResourceNames].name)) + " per tick."; + str += + formatList( + Object.entries(declaration.outputs).map( + x => + formatWhole(unref(x[1].amount)) + + " " + + RESOURCES[x[0] as ResourceNames].name + ) + ) + " per tick."; } return str; } @@ -371,7 +371,7 @@ const factory = createLayer(id, () => { imageSrc: _shed, extraImage: _wood, key: "1", - name: "Wood Warehouse", + name: "Wood Machine", type: "processor", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wood)), energyCost: 10, @@ -386,7 +386,7 @@ const factory = createLayer(id, () => { imageSrc: _shed, extraImage: _cloth, key: "2", - name: "Cloth Warehouse", + name: "Cloth Machine", type: "processor", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.cloth)), energyCost: 10, @@ -401,7 +401,7 @@ const factory = createLayer(id, () => { imageSrc: _shed, extraImage: _dye, key: "3", - name: "Dye Warehouse", + name: "Dye Machine", type: "processor", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.dye)), energyCost: 10, @@ -416,7 +416,7 @@ const factory = createLayer(id, () => { imageSrc: _shed, extraImage: _metal, key: "4", - name: "Metal Warehouse", + name: "Metal Machine", type: "processor", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.metal)), energyCost: 10, @@ -431,7 +431,7 @@ const factory = createLayer(id, () => { imageSrc: _shed, extraImage: _plastic, key: "5", - name: "Plastic Warehouse", + name: "Plastic Machine", type: "processor", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.plastic)), energyCost: 10, @@ -442,54 +442,6 @@ const factory = createLayer(id, () => { } } } as FactoryComponentDeclaration, - boxes: { - imageSrc: _shed, - extraImage: _boxes, - key: "6", - name: "Box Warehouse", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.boxes)), - energyCost: 10, - tick: 1, - outputs: { - boxes: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened - } as FactoryComponentDeclaration, - wrappingPaper: { - imageSrc: _shed, - extraImage: _wrappingPaper, - key: "7", - name: "Wrapping Paper Warehouse", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wrappingPaper)), - energyCost: 10, - tick: 1, - outputs: { - wrappingPaper: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened - } as FactoryComponentDeclaration, - ribbon: { - imageSrc: _shed, - extraImage: _ribbon, - key: "8", - name: "Ribbon Warehouse", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.ribbon)), - energyCost: 10, - tick: 1, - outputs: { - ribbon: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened - } as FactoryComponentDeclaration, plank: { imageSrc: _plankMaker, key: "shift+1", @@ -632,7 +584,9 @@ const factory = createLayer(id, () => { key: "shift+8", name: "Circuit Board Manufacturer", type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.circuitBoard)), + description: computed(() => + generateComponentDescription(FACTORY_COMPONENTS.circuitBoard) + ), energyCost: 2, tick: 1, inputs: { @@ -650,55 +604,6 @@ const factory = createLayer(id, () => { }, visible: main.days[advancedDay - 1].opened } as FactoryComponentDeclaration, - bow: { - imageSrc: _bowMaker, - key: "shift+9", - name: "Bow Maker", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.bow)), - energyCost: 2, - tick: 1, - inputs: { - ribbon: { - amount: 1 - } - }, - outputs: { - bow: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened - } as FactoryComponentDeclaration, - wrappedBox: { - imageSrc: _wrappedBoxMaker, - key: "shift+0", - name: "Box Wrapper", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wrappedBox)), - energyCost: 2, - tick: 1, - inputs: { - boxes: { - amount: 1 - }, - wrappingPaper: { - amount: 1 - }, - bow: { - amount: 1 - }, - ribbon: { - amount: 1 - } - }, - outputs: { - wrappedBox: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened - } as FactoryComponentDeclaration, blocks: { imageSrc: _blockMaker, key: "ctrl+1", @@ -803,7 +708,9 @@ const factory = createLayer(id, () => { key: "ctrl+5", name: "Shovel and Pail Maker", type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.bucketShovel)), + description: computed(() => + generateComponentDescription(FACTORY_COMPONENTS.bucketShovel) + ), energyCost: 20, tick: 1, inputs: { @@ -848,144 +755,6 @@ const factory = createLayer(id, () => { } }, visible: main.days[advancedDay - 1].opened - } as FactoryComponentDeclaration, - wrappedBlocks: { - imageSrc: _blockWrapper, - key: "ctrl+shift+1", - name: "Wooden Block Wrapper", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wrappedBlocks)), - energyCost: 20, - tick: 1, - inputs: { - block: { - amount: 1 - }, - wrappedBox: { - amount: 1 - } - }, - outputs: { - wrappedBlock: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened - } as FactoryComponentDeclaration, - wrappedClothes: { - imageSrc: _clothesWrapper, - key: "ctrl+shift+2", - name: "Clothes Wrapper", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wrappedClothes)), - energyCost: 20, - tick: 1, - inputs: { - clothes: { - amount: 1 - }, - wrappedBox: { - amount: 1 - } - }, - outputs: { - wrappedClothes: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened - } as FactoryComponentDeclaration, - wrappedTrucks: { - imageSrc: _truckWrapper, - key: "ctrl+shift+3", - name: "Trucks Wrapper", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wrappedTrucks)), - energyCost: 20, - tick: 1, - inputs: { - trucks: { - amount: 1 - }, - wrappedBox: { - amount: 1 - } - }, - outputs: { - wrappedTrucks: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened - } as FactoryComponentDeclaration, - wrappedBear: { - imageSrc: _bearWrapper, - key: "ctrl+shift+4", - name: "Teddy Bear Wrapper", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wrappedBear)), - energyCost: 20, - tick: 1, - inputs: { - bear: { - amount: 1 - }, - wrappedBox: { - amount: 1 - } - }, - outputs: { - wrappedBear: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened - } as FactoryComponentDeclaration, - wrappedBucketShovel: { - imageSrc: _bucketShovelWrapper, - key: "ctrl+shift+5", - name: "Shovel and Pail Wrapper", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wrappedBucketShovel)), - energyCost: 20, - tick: 1, - inputs: { - shovelBucket: { - amount: 1 - }, - wrappedBox: { - amount: 1 - } - }, - outputs: { - wrappedShovelBucket: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened - } as FactoryComponentDeclaration, - wrappedConsole: { - imageSrc: _consoleWrapper, - key: "ctrl+shift+6", - name: "Game Console Wrapper", - type: "processor", - description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wrappedConsole)), - energyCost: 20, - tick: 1, - inputs: { - console: { - amount: 1 - }, - wrappedBox: { - amount: 1 - } - }, - outputs: { - wrappedConsole: { - amount: 1 - } - }, - visible: main.days[presentsDay - 1].opened } as FactoryComponentDeclaration } as Record; const RESOURCES = { @@ -1010,18 +779,6 @@ const factory = createLayer(id, () => { name: "Metal", imageSrc: _metal }, - boxes: { - name: "Boxes", - imageSrc: _boxes - }, - wrappingPaper: { - name: "Wrapping Paper", - imageSrc: _wrappingPaper - }, - ribbon: { - name: "Ribbon", - imageSrc: _ribbon - }, // Processed resources plank: { name: "Planks", @@ -1055,14 +812,6 @@ const factory = createLayer(id, () => { name: "Circuit Board", imageSrc: _circuitBoard }, - bow: { - name: "Bow", - imageSrc: _bow - }, - wrappedBox: { - name: "Wrapped Box", - imageSrc: _wrappedBox - }, // Toys block: { name: "Wooden Blocks", @@ -1087,31 +836,6 @@ const factory = createLayer(id, () => { console: { name: "Game Console", imageSrc: _console - }, - // Wrapped toys - wrappedBlock: { - name: "Wrapped Wooden Blocks", - imageSrc: _block - }, - wrappedClothes: { - name: "Wrapped Clothes", - imageSrc: _clothes - }, - wrappedTrucks: { - name: "Wrapped Trucks", - imageSrc: _truck - }, - wrappedBear: { - name: "Wrapped Teddy Bear", - imageSrc: _bear - }, - wrappedShovelBucket: { - name: "Wrapped Shovel and Pail", - imageSrc: _bucketShovel - }, - wrappedConsole: { - name: "Wrapped Game Console", - imageSrc: _console } } as const; @@ -1333,7 +1057,7 @@ const factory = createLayer(id, () => { showAmount: false }, style: "width: 200px", - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })) as GenericBuyable; const oilFuel = createBuyable(() => ({ resource: oil.oil, @@ -1347,7 +1071,7 @@ const factory = createLayer(id, () => { showAmount: false }, style: "width: 200px", - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })) as GenericBuyable; const carryToys = createBuyable(() => ({ resource: boxes.boxes, @@ -1363,7 +1087,7 @@ const factory = createLayer(id, () => { showAmount: false }, style: "width: 200px", - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })) as GenericBuyable; const factoryBuyables = { expandFactory, oilFuel, carryToys }; const upgrades = [ @@ -1376,7 +1100,7 @@ const factory = createLayer(id, () => { description: "Double sawmill consumption and production and metal supplier efficiency" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })), createUpgrade(() => ({ resource: paper.paper, @@ -1385,7 +1109,7 @@ const factory = createLayer(id, () => { title: "News Ticker", description: "Paper boosts tick speed" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })), createUpgrade(() => ({ resource: toys.trucks, @@ -1394,7 +1118,7 @@ const factory = createLayer(id, () => { title: "Haul wood in trucks", description: "Trucks multiply wood gain" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })), createUpgrade(() => ({ resource: metal.metal, @@ -1403,7 +1127,7 @@ const factory = createLayer(id, () => { title: "Diamond-tipped drills", description: "Drill power ^1.2" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })) ], [ @@ -1414,7 +1138,7 @@ const factory = createLayer(id, () => { title: "Larger wood pieces", description: "Wooden block producers produce 3x as much" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })), createUpgrade(() => ({ resource: dyes.dyes.red.amount, @@ -1423,7 +1147,7 @@ const factory = createLayer(id, () => { title: "Colorful clothes", description: "Dye producers produce 4x as much" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })), createUpgrade(() => ({ resource: plastic.plastic, @@ -1432,7 +1156,7 @@ const factory = createLayer(id, () => { title: "Improved plastic producers", description: "Plastic producers produce 4x as much" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })), createUpgrade(() => ({ resource: oil.oil, @@ -1441,7 +1165,7 @@ const factory = createLayer(id, () => { title: "Capitalism", description: "Console production is tripled" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })) ], [ @@ -1452,7 +1176,7 @@ const factory = createLayer(id, () => { title: "Brighter work rooms", description: "Unused electricity makes ticks faster" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })), createUpgrade(() => ({ resource: dyes.dyes.blue.amount, @@ -1461,7 +1185,7 @@ const factory = createLayer(id, () => { title: "Colorful teddy bears", description: "Teddy bears produce 2x as much" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })), createUpgrade(() => ({ resource: dyes.dyes.black.amount, @@ -1470,7 +1194,7 @@ const factory = createLayer(id, () => { title: "New Colors", description: "Unlock white dye" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })), createUpgrade(() => ({ resource: boxes.boxes, @@ -1479,7 +1203,7 @@ const factory = createLayer(id, () => { title: "Carry ticks in boxes", description: "Tick speed x1.5" }, - visible: () => showIf(main.days[advancedDay - 1].opened.value) + visibility: () => showIf(main.days[advancedDay - 1].opened.value) })) ] ]; @@ -1515,6 +1239,9 @@ const factory = createLayer(id, () => { let loaded = false; globalBus.on("onLoad", async () => { + if (loaded) { + return; + } loaded = false; spriteContainer.destroy({ @@ -1843,7 +1570,11 @@ const factory = createLayer(id, () => { lastProdTimes: !isConveyor ? (reactive([]) as number[]) : undefined, lastFactoryProd: !isConveyor ? Date.now() - - 1000 * Decimal.div(data.ticksDone ?? 0, computedActualTickRate.value).toNumber() + 1000 * + Decimal.div( + (data as FactoryComponentProcessor).ticksDone ?? 0, + computedActualTickRate.value + ).toNumber() : undefined, average: !isConveyor ? computed(() => { @@ -1867,7 +1598,7 @@ const factory = createLayer(id, () => { const compData = components.value[x + "x" + y] as FactoryComponentProcessor; if (factoryBaseData.inputs !== undefined) { for (const [res, val] of Object.entries(factoryBaseData.inputs)) - if ((compData.inputStock?.[res as ResourceNames] ?? 0) < val.amount) + if ((compData.inputStock?.[res as ResourceNames] ?? 0) < unref(val.amount)) return false; } if (factoryBaseData.outputs !== undefined) { @@ -2110,6 +1841,9 @@ const factory = createLayer(id, () => { {Object.entries(FACTORY_COMPONENTS).map(value => { const key = value[0] as FactoryCompNames; const item = value[1]; + if (unref(item.visible) === false) { + return null; + } return (
{ compInternalHovered.value.type !== "conveyor" ? ( <> {showStockAmount( - compHovered.value.inputStock, + (compHovered.value as FactoryComponentProcessor).inputStock, FACTORY_COMPONENTS[compHovered.value.type].inputs, "Inputs:" )} {showStockAmount( - compHovered.value.outputStock, + (compHovered.value as FactoryComponentProcessor).outputStock, FACTORY_COMPONENTS[compHovered.value.type].outputs, "Outputs:", false )}
Efficency:{" "} - {compInternalHovered.value.average.value !== undefined ? ( + {(compInternalHovered.value as FactoryInternalProcessor).average.value !== + undefined ? ( 1 + (compInternalHovered.value as FactoryInternalProcessor) + .average.value! > 1 ? "purple" - : compInternalHovered.value.average.value >= 0.9 + : ( + compInternalHovered.value as FactoryInternalProcessor + ).average.value! >= 0.9 ? "green" - : compInternalHovered.value.average.value >= 0.5 + : ( + compInternalHovered.value as FactoryInternalProcessor + ).average.value! >= 0.5 ? "yellow" : "red" }} > - {formatWhole(compInternalHovered.value.average.value * 100)} + {formatWhole( + (compInternalHovered.value as FactoryInternalProcessor).average + .value! * 100 + )} ) : ( "--" @@ -2476,4 +2219,4 @@ const factory = createLayer(id, () => { )) }; }); -export default factory; +export default factory; \ No newline at end of file From b9f304b656a1a622d4dd38a4bc34fe6596e8fc72 Mon Sep 17 00:00:00 2001 From: someoneWasTaken94 <121205769+someoneWasTaken94@users.noreply.github.com> Date: Sat, 24 Dec 2022 02:12:28 +0000 Subject: [PATCH 4/5] some new content --- saves/Day 19 Complete.txt | 1 + src/data/layers/boxes.tsx | 37 ++- src/data/layers/elves.tsx | 6 +- .../layers/factory-components/boxmaker.svg | 123 ++++++++ src/data/layers/factory.tsx | 264 +++++++++++++++++- src/data/projEntry.tsx | 4 +- 6 files changed, 418 insertions(+), 17 deletions(-) create mode 100644 saves/Day 19 Complete.txt create mode 100644 src/data/layers/factory-components/boxmaker.svg diff --git a/saves/Day 19 Complete.txt b/saves/Day 19 Complete.txt new file mode 100644 index 0000000..5681eba --- /dev/null +++ b/saves/Day 19 Complete.txt @@ -0,0 +1 @@ +eyJpZCI6ImFkdmVudC1pbmNyZW1lbnRhbC0yIiwiZGV2U3BlZWQiOjAsIm5hbWUiOiJEZWZhdWx0IFNhdmUiLCJ0YWJzIjpbIm1haW4iLCJmYWN0b3J5Il0sInRpbWUiOjE2NzE3NzI2MTQ4MDgsImF1dG9zYXZlIjp0cnVlLCJvZmZsaW5lUHJvZCI6ZmFsc2UsIm9mZmxpbmVUaW1lIjpudWxsLCJ0aW1lUGxheWVkIjo5MzYxNC42NDg1MTkzNzQ1OCwia2VlcEdvaW5nIjpmYWxzZSwibW9kSUQiOiJhZHZlbnQtaW5jcmVtZW50YWwiLCJtb2RWZXJzaW9uIjoiMC41IiwibGF5ZXJzIjp7Im1haW4iOnsibWluaW1pemVkIjpmYWxzZSwiZGF5cyI6eyIwIjp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjEiOnsib3BlbmVkIjp0cnVlLCJyZWNlbnRseVVwZGF0ZWQiOmZhbHNlfSwiMiI6eyJvcGVuZWQiOnRydWUsInJlY2VudGx5VXBkYXRlZCI6ZmFsc2V9LCIzIjp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjQiOnsib3BlbmVkIjp0cnVlLCJyZWNlbnRseVVwZGF0ZWQiOmZhbHNlfSwiNSI6eyJvcGVuZWQiOnRydWUsInJlY2VudGx5VXBkYXRlZCI6ZmFsc2V9LCI2Ijp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjciOnsib3BlbmVkIjp0cnVlLCJyZWNlbnRseVVwZGF0ZWQiOmZhbHNlfSwiOCI6eyJvcGVuZWQiOnRydWUsInJlY2VudGx5VXBkYXRlZCI6ZmFsc2V9LCI5Ijp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjEwIjp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjExIjp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjEyIjp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjEzIjp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjE0Ijp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjE1Ijp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjE2Ijp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjE3Ijp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjE4Ijp7Im9wZW5lZCI6dHJ1ZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjE5Ijp7Im9wZW5lZCI6ZmFsc2UsInJlY2VudGx5VXBkYXRlZCI6ZmFsc2V9LCIyMCI6eyJvcGVuZWQiOmZhbHNlLCJyZWNlbnRseVVwZGF0ZWQiOmZhbHNlfSwiMjEiOnsib3BlbmVkIjpmYWxzZSwicmVjZW50bHlVcGRhdGVkIjpmYWxzZX0sIjIyIjp7Im9wZW5lZCI6ZmFsc2UsInJlY2VudGx5VXBkYXRlZCI6ZmFsc2V9LCIyMyI6eyJvcGVuZWQiOmZhbHNlLCJyZWNlbnRseVVwZGF0ZWQiOmZhbHNlfX0sImRheSI6MjAsImlzTWFzdGVyeSI6ZmFsc2V9LCJ0cmVlcyI6eyJtaW5pbWl6ZWQiOmZhbHNlLCJsb2dzIjoiMi4xMzYyMzY5NzYxMzI2MjNlODIiLCJ0b3RhbExvZ3MiOiIxLjAzMTIyODMwODc2Njc5ZTg0IiwidHJlZXMiOiIxMCIsInNhcGxpbmdzIjoiMy42MzUzNzU0MDA4NDAxNzNlMjkiLCJyb3cxVXBncmFkZXMiOnsiMCI6eyJyZXNvdXJjZSI6IjEwMjg0MzYwNjYxMDguNjU5NCIsImJvdWdodCI6dHJ1ZX0sIjEiOnsicmVzb3VyY2UiOiIxMDI4NDM2MDY2MTA4LjY1OTQiLCJib3VnaHQiOnRydWV9LCIyIjp7InJlc291cmNlIjoiMTAyODQzNjA2NjEwOC42NTk0IiwiYm91Z2h0Ijp0cnVlfSwiMyI6eyJyZXNvdXJjZSI6IjEwMjg0MzYwNjYxMDguNjU5NCIsImJvdWdodCI6dHJ1ZX0sIjQiOnsicmVzb3VyY2UiOiIxMDI4NDM2MDY2MTA4LjY1OTQiLCJib3VnaHQiOnRydWV9fSwicm93MlVwZ3JhZGVzIjp7IjAiOnsicmVzb3VyY2UiOiIxMDI4NDM2MDY2MTA4LjY1OTQiLCJib3VnaHQiOnRydWV9LCIxIjp7InJlc291cmNlIjoiMTAyODQzNjA2NjEwOC42NTk0IiwiYm91Z2h0Ijp0cnVlfSwiMiI6eyJyZXNvdXJjZSI6IjEwMjg0MzYwNjYxMDguNjU5NCIsImJvdWdodCI6dHJ1ZX0sIjMiOnsicmVzb3VyY2UiOiIxMDI4NDM2MDY2MTA4LjY1OTQiLCJib3VnaHQiOnRydWV9LCI0Ijp7InJlc291cmNlIjoiMTAyODQzNjA2NjEwOC42NTk0IiwiYm91Z2h0Ijp0cnVlfX0sInJvdzFCdXlhYmxlcyI6eyIwIjp7InJlc291cmNlIjoiMTAyODQzNjA2NjEwOC42NTk0IiwiYW1vdW50IjoiNDk4NzI5MyJ9LCIxIjp7InJlc291cmNlIjoiMTAyODQzNjA2NjEwOC42NTk0IiwiYW1vdW50IjoiNTEzMjkyNSJ9LCIyIjp7InJlc291cmNlIjoiMTAyODQzNjA2NjEwOC42NTk0IiwiYW1vdW50IjoiMTIxMTE0NzMifX0sIm1hbnVhbEN1dFByb2dyZXNzIjoiMC4wMDAwMDE5MDczNDg2MzI4MTI0OTk0IiwibWFudWFsUGxhbnRQcm9ncmVzcyI6IjAuMDAwMDAxOTA3MzQ4NjMyODEyNDk5NCIsImdlbmVyYWxUYWJDb2xsYXBzZWQiOnt9LCJjcmVhdGVkU2FwbGluZ3MiOiIzLjgyOTExMTMxNzQ5MjUxMmUyOSIsIm1hc3RlcnkiOnsibG9ncyI6IjQuODcyMTUyNjU1NTIxNDA4ZTIzIiwidG90YWxMb2dzIjoiNC45MjgzMzg4NDA0MDEzMmUyMyIsInNhcGxpbmdzIjoiNjUzNzUwNTI3NDgzNjguODMiLCJyb3cxVXBncmFkZXMiOnsiMCI6eyJib3VnaHQiOnRydWV9LCIxIjp7ImJvdWdodCI6dHJ1ZX0sIjIiOnsiYm91Z2h0Ijp0cnVlfSwiMyI6eyJib3VnaHQiOnRydWV9LCI0Ijp7ImJvdWdodCI6dHJ1ZX19LCJyb3cyVXBncmFkZXMiOnsiMCI6eyJib3VnaHQiOnRydWV9LCIxIjp7ImJvdWdodCI6dHJ1ZX0sIjIiOnsiYm91Z2h0Ijp0cnVlfSwiMyI6eyJib3VnaHQiOnRydWV9LCI0Ijp7ImJvdWdodCI6dHJ1ZX19LCJyb3cxQnV5YWJsZXMiOnsiMCI6eyJhbW91bnQiOiIxMTMyOTUifSwiMSI6eyJhbW91bnQiOiIxMTMyOTUifSwiMiI6eyJhbW91bnQiOiIzMzU4MjcifX0sImNyZWF0ZWRTYXBsaW5ncyI6IjY1Mzc1ODM1MDc3MjAxLjUxNiJ9LCJtYXN0ZXJlZCI6dHJ1ZX0sIndvcmtzaG9wIjp7Im1pbmltaXplZCI6ZmFsc2UsImZvdW5kYXRpb25Qcm9ncmVzcyI6IjEzNTQiLCJmb3VuZGF0aW9uQ29udmVyc2lvbiI6eyJiYXNlUmVzb3VyY2UiOiIxMDI4NDM2MDY2MTA4LjY1OTQiLCJnYWluUmVzb3VyY2UiOiIxMDAifSwibWlsZXN0b25lcyI6eyJsb2dHYWluTWlsZXN0b25lMSI6eyJlYXJuZWQiOnRydWV9LCJhdXRvQ3V0TWlsZXN0b25lMSI6eyJlYXJuZWQiOnRydWV9LCJhdXRvUGxhbnRNaWxlc3RvbmUxIjp7ImVhcm5lZCI6dHJ1ZX0sImF1dG9DdXRNaWxlc3RvbmUyIjp7ImVhcm5lZCI6dHJ1ZX0sImF1dG9QbGFudE1pbGVzdG9uZTIiOnsiZWFybmVkIjp0cnVlfSwibG9nR2Fpbk1pbGVzdG9uZTIiOnsiZWFybmVkIjp0cnVlfSwibW9yZVBsYW50c01pbGVzdG9uZTEiOnsiZWFybmVkIjp0cnVlfSwibG9nR2Fpbk1pbGVzdG9uZTMiOnsiZWFybmVkIjp0cnVlfSwiZXh0cmFFeHBhbnNpb25NaWxlc3RvbmUxIjp7ImVhcm5lZCI6dHJ1ZX0sImV4dHJhRXhwYW5zaW9uTWlsZXN0b25lMiI6eyJlYXJuZWQiOnRydWV9LCJleHRyYUV4cGFuc2lvbk1pbGVzdG9uZTMiOnsiZWFybmVkIjp0cnVlfSwiZXh0cmFFeHBhbnNpb25NaWxlc3RvbmU0Ijp7ImVhcm5lZCI6dHJ1ZX0sImV4dHJhRXhwYW5zaW9uTWlsZXN0b25lNSI6eyJlYXJuZWQiOnRydWV9LCJleHRyYUV4cGFuc2lvbk1pbGVzdG9uZTYiOnsiZWFybmVkIjp0cnVlfSwiZXh0cmFFeHBhbnNpb25NaWxlc3RvbmU3Ijp7ImVhcm5lZCI6ZmFsc2V9fSwiY29sbGFwc2VNaWxlc3RvbmVzIjp0cnVlLCJtYXN0ZXJ5Ijp7ImZvdW5kYXRpb25Qcm9ncmVzcyI6IjEwMCIsIm1pbGVzdG9uZXMiOnsibG9nR2Fpbk1pbGVzdG9uZTEiOnsiZWFybmVkIjp0cnVlfSwiYXV0b0N1dE1pbGVzdG9uZTEiOnsiZWFybmVkIjp0cnVlfSwiYXV0b1BsYW50TWlsZXN0b25lMSI6eyJlYXJuZWQiOnRydWV9LCJhdXRvQ3V0TWlsZXN0b25lMiI6eyJlYXJuZWQiOnRydWV9LCJhdXRvUGxhbnRNaWxlc3RvbmUyIjp7ImVhcm5lZCI6dHJ1ZX0sImxvZ0dhaW5NaWxlc3RvbmUyIjp7ImVhcm5lZCI6dHJ1ZX0sIm1vcmVQbGFudHNNaWxlc3RvbmUxIjp7ImVhcm5lZCI6dHJ1ZX0sImxvZ0dhaW5NaWxlc3RvbmUzIjp7ImVhcm5lZCI6dHJ1ZX0sImV4dHJhRXhwYW5zaW9uTWlsZXN0b25lMSI6eyJlYXJuZWQiOmZhbHNlfSwiZXh0cmFFeHBhbnNpb25NaWxlc3RvbmUyIjp7ImVhcm5lZCI6ZmFsc2V9LCJleHRyYUV4cGFuc2lvbk1pbGVzdG9uZTMiOnsiZWFybmVkIjpmYWxzZX0sImV4dHJhRXhwYW5zaW9uTWlsZXN0b25lNCI6eyJlYXJuZWQiOmZhbHNlfSwiZXh0cmFFeHBhbnNpb25NaWxlc3RvbmU1Ijp7ImVhcm5lZCI6ZmFsc2V9fX0sIm1hc3RlcmVkIjp0cnVlLCJnZW5lcmFsVGFiQ29sbGFwc2VkIjp7fX0sImNvYWwiOnsibWluaW1pemVkIjpmYWxzZSwiY29hbCI6IjIuMzkxMTMyNzQwMjI2MTE3ZTE0NiIsInRvdGFsQ29hbCI6IjIuMzkxMTMyNzQwMjU0NzUzM2UxNDYiLCJhc2giOiIyLjQ0NTc4NzkwNTg1NjY1MzRlMTEyIiwiYWN0aXZlRmlyZXMiOiIwIiwiYnVpbGRGaXJlIjp7InJlc291cmNlIjoiMTAyODQzNjA2NjEwOC42NTk0IiwiYW1vdW50IjoiMCJ9LCJhY3RpdmVCb25maXJlcyI6IjIuMTY0MjExODE5NTY3MTQ2NWUyNCIsImJ1aWxkQm9uZmlyZSI6eyJyZXNvdXJjZSI6MCwiYW1vdW50IjoiMi4xNjQyMTE4MTk1NjcxNDY1ZTI0In0sImFjdGl2ZUtpbG5zIjoiNzA5NCIsImJ1aWxkS2lsbiI6eyJyZXNvdXJjZSI6IjEwMjg0MzYwNjYxMDguNjU5NCIsImFtb3VudCI6IjcwOTQifSwid2FybWVyQ3V0dGVycyI6eyJyZXNvdXJjZSI6Ijc3NzQ3ODk5NzY1LjQ4Mzc4IiwiYm91Z2h0Ijp0cnVlfSwid2FybWVyUGxhbnRlcnMiOnsicmVzb3VyY2UiOiI3Nzc0Nzg5OTc2NS40ODM3OCIsImJvdWdodCI6dHJ1ZX0sImJhc2ljRmVydGlsaXplciI6eyJyZXNvdXJjZSI6IjE0NTY4ODI2IiwiYm91Z2h0Ijp0cnVlfSwidW5sb2NrQm9uZmlyZSI6eyJyZXNvdXJjZSI6MCwiYm91Z2h0Ijp0cnVlfSwiZGVkaWNhdGVkQ3V0dGVycyI6eyJyZXNvdXJjZSI6Ijc3NzQ3ODk5NzY1LjQ4Mzc4IiwiYm91Z2h0Ijp0cnVlfSwiZGVkaWNhdGVkUGxhbnRlcnMiOnsicmVzb3VyY2UiOiI3Nzc0Nzg5OTc2NS40ODM3OCIsImJvdWdodCI6dHJ1ZX0sImJldHRlckZlcnRpbGl6ZXIiOnsiYm91Z2h0Ijp0cnVlfSwidW5sb2NrS2lsbiI6eyJyZXNvdXJjZSI6IjEwMjg0MzYwNjYxMDguNjU5NCIsImJvdWdodCI6dHJ1ZX0sImhlYXRlZEN1dHRlcnMiOnsicmVzb3VyY2UiOiI3Nzc0Nzg5OTc2NS40ODM3OCIsImFtb3VudCI6IjIxMDUzOTU4NTE2NjgifSwiaGVhdGVkUGxhbnRlcnMiOnsicmVzb3VyY2UiOiI3Nzc0Nzg5OTc2NS40ODM3OCIsImFtb3VudCI6IjIxMDUzOTU4NTE2NjgifSwibW9yZUZlcnRpbGl6ZXIiOnsicmVzb3VyY2UiOiIxNDU2ODgyNiIsImFtb3VudCI6IjEwNjc4ODQ1NjkwNDk2MSJ9LCJnZW5lcmFsVGFiQ29sbGFwc2VkIjp7fSwiYWN0aXZlRHJpbGxzIjoiMzkzOSIsImJ1aWxkRHJpbGwiOnsiYW1vdW50IjoiMzkzOSJ9LCJlZmZpY2llbnRTbWVsdGhlciI6eyJyZXNvdXJjZSI6IjEuMzM2NDc3NzkxMzI4MjUyZTE3IiwiYm91Z2h0Ijp0cnVlfSwiYXJzb25pc3RBc3Npc3RhbmNlIjp7ImJvdWdodCI6dHJ1ZX0sInJlZmluZWRDb2FsIjp7ImJvdWdodCI6dHJ1ZX0sImNvbG9yZWRGaXJlIjp7ImJvdWdodCI6dHJ1ZX0sIm1hc3RlcnkiOnsiY29hbCI6IjkuMDYyODExNzY3MjA3NTQ1ZTMzIiwidG90YWxDb2FsIjoiOS4wNjg5MjI4NzgzMTg1MzVlMzMiLCJhc2giOiIyLjY3NTI0MzQ3ODczMjE4OGUxNyIsImFjdGl2ZUZpcmVzIjoiMTA2MS44ODUzODU0NzU1Mjk4IiwiYnVpbGRGaXJlIjp7ImFtb3VudCI6IjEwNjEuODg1Mzg1NDc1NTI5OCJ9LCJhY3RpdmVCb25maXJlcyI6IjIwMDUwMyIsImJ1aWxkQm9uZmlyZSI6eyJhbW91bnQiOiIyMDA1MDMifSwiYWN0aXZlS2lsbnMiOiI2NzEiLCJidWlsZEtpbG4iOnsiYW1vdW50IjoiNjcxIn0sImFjdGl2ZURyaWxscyI6IjE2NSIsImJ1aWxkRHJpbGwiOnsiYW1vdW50IjoiMTY1In0sIndhcm1lckN1dHRlcnMiOnsiYm91Z2h0Ijp0cnVlfSwid2FybWVyUGxhbnRlcnMiOnsiYm91Z2h0Ijp0cnVlfSwiYmFzaWNGZXJ0aWxpemVyIjp7ImJvdWdodCI6dHJ1ZX0sInVubG9ja0JvbmZpcmUiOnsiYm91Z2h0Ijp0cnVlfSwiZGVkaWNhdGVkQ3V0dGVycyI6eyJib3VnaHQiOnRydWV9LCJkZWRpY2F0ZWRQbGFudGVycyI6eyJib3VnaHQiOnRydWV9LCJiZXR0ZXJGZXJ0aWxpemVyIjp7ImJvdWdodCI6dHJ1ZX0sInVubG9ja0tpbG4iOnsiYm91Z2h0Ijp0cnVlfSwiZWZmaWNpZW50U21lbHRoZXIiOnsiYm91Z2h0Ijp0cnVlfSwiYXJzb25pc3RBc3Npc3RhbmNlIjp7ImJvdWdodCI6ZmFsc2V9LCJyZWZpbmVkQ29hbCI6eyJib3VnaHQiOmZhbHNlfSwiY29sb3JlZEZpcmUiOnsiYm91Z2h0IjpmYWxzZX0sImhlYXRlZEN1dHRlcnMiOnsiYW1vdW50IjoiOTc5OCJ9LCJoZWF0ZWRQbGFudGVycyI6eyJhbW91bnQiOiI5Nzk4In0sIm1vcmVGZXJ0aWxpemVyIjp7ImFtb3VudCI6IjI1MzUifX0sIm1hc3RlcmVkIjp0cnVlfSwiZWx2ZXMiOnsibWluaW1pemVkIjpmYWxzZSwiZWx2ZXMiOnsiY3V0dGVyc0VsZiI6eyJidXlQcm9ncmVzcyI6IjAuMDAwODU0NTMxODcwODkxNjAwNSIsInJlc291cmNlIjoiNzc3NDc4OTk3NjUuNDgzNzgiLCJib3VnaHQiOnRydWUsImJ1eWFibGUiOnsicmVzb3VyY2UiOiIxMDI4NDM2MDY2MTA4LjY1OTQiLCJhbW91bnQiOiIzMTk4In0sImFtb3VudE9mVGltZXNEb25lIjowLjc5MjAwMDAwMDU3OTc5NzR9LCJwbGFudGVyc0VsZiI6eyJidXlQcm9ncmVzcyI6IjAuMDAwMjI2NjQyNTE5MzA0MzIwOSIsInJlc291cmNlIjoiNzc3NDc4OTk3NjUuNDgzNzgiLCJib3VnaHQiOnRydWUsImJ1eWFibGUiOnsicmVzb3VyY2UiOiIxMDI4NDM2MDY2MTA4LjY1OTQiLCJhbW91bnQiOiIzMTk4In0sImFtb3VudE9mVGltZXNEb25lIjowLjYyNDAwMDAwMDU4MTk1MX0sImV4cGFuZGVyc0VsZiI6eyJidXlQcm9ncmVzcyI6IjAuMDAxMTgzMzY4MDk4MTI3NjA3MyIsInJlc291cmNlIjoiNzc3NDc4OTk3NjUuNDgzNzgiLCJib3VnaHQiOnRydWUsImJ1eWFibGUiOnsicmVzb3VyY2UiOiIxMDI4NDM2MDY2MTA4LjY1OTQiLCJhbW91bnQiOiI3Mzc5In0sImFtb3VudE9mVGltZXNEb25lIjowLjYxMjAwMDAwMDU3OTUwNjN9LCJoZWF0ZWRDdXR0ZXJzRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDAyMDcwNDIzOTgwMTM0NDYxNSIsInJlc291cmNlIjoiNzc3NDc4OTk3NjUuNDgzNzgiLCJib3VnaHQiOnRydWUsImJ1eWFibGUiOnsicmVzb3VyY2UiOiI3Nzc0Nzg5OTc2NS40ODM3OCIsImFtb3VudCI6IjI3MCJ9LCJhbW91bnRPZlRpbWVzRG9uZSI6MC4xODgwMDAwMDA1ODAwNzUyN30sImhlYXRlZFBsYW50ZXJzRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDA3ODExMjk3NDg2MTkyNTUzIiwicmVzb3VyY2UiOiI3Nzc0Nzg5OTc2NS40ODM3OCIsImJvdWdodCI6dHJ1ZSwiYnV5YWJsZSI6eyJyZXNvdXJjZSI6Ijc3NzQ3ODk5NzY1LjQ4Mzc4IiwiYW1vdW50IjoiMjcwIn0sImFtb3VudE9mVGltZXNEb25lIjowLjk0ODAwMDAwMDU3OTUxOX0sImZlcnRpbGl6ZXJFbGYiOnsiYnV5UHJvZ3Jlc3MiOiIwLjAwMDc3NDM4MDUwODI5NjI4NTEiLCJyZXNvdXJjZSI6Ijc3NzQ3ODk5NzY1LjQ4Mzc4IiwiYm91Z2h0Ijp0cnVlLCJidXlhYmxlIjp7InJlc291cmNlIjoiMTQ1Njg4MjYiLCJhbW91bnQiOiIxMzkifSwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuNzcyMDAwMDAwNTgwNjExNH0sInNtYWxsRmlyZUVsZiI6eyJidXlhYmxlIjp7InJlc291cmNlIjoiMTAyODQzNjA2NjEwOC42NTk0IiwiYW1vdW50IjowfSwidG9nZ2xlIjp0cnVlLCJidXlQcm9ncmVzcyI6IjAuMDAwOTE2MDE3MzQyMjk1MjExMSIsInJlc291cmNlIjoiNzc3NDc4OTk3NjUuNDgzNzgiLCJib3VnaHQiOnRydWUsImFtb3VudE9mVGltZXNEb25lIjowLjA1MjAwMDAwMDU4MDI1MDExNn0sImJvbmZpcmVFbGYiOnsiYnV5YWJsZSI6eyJyZXNvdXJjZSI6MCwiYW1vdW50IjowfSwidG9nZ2xlIjp0cnVlLCJidXlQcm9ncmVzcyI6IjAuMDAwNzM5MTM2MjY0NzI0MjQzOSIsInJlc291cmNlIjoiNzc3NDc4OTk3NjUuNDgzNzgiLCJib3VnaHQiOnRydWUsImFtb3VudE9mVGltZXNEb25lIjowLjU3NjAwMDAwMDU3NzUxNTR9LCJraWxuRWxmIjp7ImJ1eWFibGUiOnsicmVzb3VyY2UiOiIxMDI4NDM2MDY2MTA4LjY1OTQiLCJhbW91bnQiOiIxMDIifSwidG9nZ2xlIjp0cnVlLCJidXlQcm9ncmVzcyI6IjAuMDAwNDgyMDY5NzA3MjQ1NTQxNTUiLCJyZXNvdXJjZSI6Ijc3NzQ3ODk5NzY1LjQ4Mzc4IiwiYm91Z2h0Ijp0cnVlLCJhbW91bnRPZlRpbWVzRG9uZSI6MC4xNTIwMDAwMDA1Nzk1OTA3M30sInBhcGVyRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDg2MDM4OTYxMDQxMjI2NzYiLCJib3VnaHQiOnRydWUsImFtb3VudE9mVGltZXNEb25lIjowLjYxMjAwMDAwMDAxMzU3MDZ9LCJib3hFbGYiOnsiYnV5UHJvZ3Jlc3MiOiIwLjAxMDAxMTk5ODg3MTU3MjczMiIsImJvdWdodCI6dHJ1ZSwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuODU2MDAwMDAwMDkwNzE1OH0sImNsb3RoRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDAyOTQ3NDY0NzQwMDAxNTcxIiwiYm91Z2h0Ijp0cnVlLCJhbW91bnRPZlRpbWVzRG9uZSI6MC40ODgwMDAwMDA2MTM0Mzk1fSwibWluaW5nRHJpbGxFbGYiOnsidG9nZ2xlIjpmYWxzZSwiYnV5UHJvZ3Jlc3MiOjAsImFtb3VudE9mVGltZXNEb25lIjowLCJib3VnaHQiOmZhbHNlfSwiaGVhdnlEcmlsbEVsZiI6eyJ0b2dnbGUiOnRydWUsImJ1eVByb2dyZXNzIjoiMC4wMDE0MDMyNzMzOTA4OTE2MDA0IiwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuOTQwMDAwMDAwMzYwMzI4MiwiYm91Z2h0Ijp0cnVlfSwib2lsRWxmIjp7InRvZ2dsZSI6dHJ1ZSwiYnV5UHJvZ3Jlc3MiOiIwLjAwMDE4MzA4MTg1MjYxODc1NDk4IiwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuMjA0MDAwMDAwMzU1NDYzODQsImJvdWdodCI6dHJ1ZX0sIm1ldGFsRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDAxMzMxNTU5MjQ0MzM3NjE1NiIsImFtb3VudE9mVGltZXNEb25lIjowLjE5MjAwMDAwMDM1MzEzMjgsImJvdWdodCI6dHJ1ZX0sImNvYWxEcmlsbEVsZiI6eyJ0b2dnbGUiOnRydWUsImJ1eVByb2dyZXNzIjoiMC4wMDE0MDM1Mjg2Njk1NjI2OTExIiwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuODQwMDAwMDAwMzY5MDg3NywiYm91Z2h0Ijp0cnVlfSwiZHllRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDAwMTgzMjY3NTMzMDUzMTk5NjUiLCJhbW91bnRPZlRpbWVzRG9uZSI6MC41NDAwMDAwMDAzODQ4NzE3LCJib3VnaHQiOnRydWV9LCJwbGFzdGljRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDA3MzExMjU4NDU5NjY2MDE1IiwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuNTc2MDAwMDAwMzcyODc5MSwiYm91Z2h0Ijp0cnVlfX0sIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX0sIjUiOnsiZWFybmVkIjp0cnVlfSwiNiI6eyJlYXJuZWQiOnRydWV9LCI3Ijp7ImVhcm5lZCI6dHJ1ZX0sIjgiOnsiZWFybmVkIjp0cnVlfSwiOSI6eyJlYXJuZWQiOnRydWV9LCIxMCI6eyJlYXJuZWQiOnRydWV9LCIxMSI6eyJlYXJuZWQiOnRydWV9fSwiZ2VuZXJhbFRhYkNvbGxhcHNlZCI6e30sImNvbGxhcHNlTWlsZXN0b25lcyI6ZmFsc2UsIm1hc3RlcnkiOnsiZWx2ZXMiOnsiY3V0dGVyc0VsZiI6eyJidXlQcm9ncmVzcyI6IjAuMDAwNDEzMTY1NDQyMTQxNzMzIiwiYW1vdW50T2ZUaW1lc0RvbmUiOjEuMDQ1OTE4OTA3MDM4ODY3NWUtMTEsImJvdWdodCI6dHJ1ZX0sInBsYW50ZXJzRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDQxNzg1NTI0MDQ0NzY4NzEiLCJhbW91bnRPZlRpbWVzRG9uZSI6MC40MDgwMDAwMDAwMTI1MjEsImJvdWdodCI6dHJ1ZX0sImV4cGFuZGVyc0VsZiI6eyJidXlQcm9ncmVzcyI6IjAuMDA0MjE1MDIxNzM5Mzc4MTU1IiwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuNzk0MDAwMDAwMDA3NTM1OCwiYm91Z2h0Ijp0cnVlfSwiaGVhdGVkQ3V0dGVyc0VsZiI6eyJidXlQcm9ncmVzcyI6IjAuMDAxNTAzODI5ODkyODI3NDM1MiIsImFtb3VudE9mVGltZXNEb25lIjowLjMwMjAwMDAwMDA0NjQ2MiwiYm91Z2h0Ijp0cnVlfSwiaGVhdGVkUGxhbnRlcnNFbGYiOnsiYnV5UHJvZ3Jlc3MiOiIwLjAwMjU5OTc3NjUwOTM1ODYwOSIsImFtb3VudE9mVGltZXNEb25lIjowLjcyNjAwMDAwMDA0OTc5MzksImJvdWdodCI6dHJ1ZX0sImZlcnRpbGl6ZXJFbGYiOnsiYnV5UHJvZ3Jlc3MiOiIwLjAwMjIzMzY2NzA0MzEyMDI4IiwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuNTkyMDAwMDAwMDQ3Nzg5OSwiYm91Z2h0Ijp0cnVlfSwic21hbGxGaXJlRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDI4NzMwNjA4NjYwMzAzNDE0IiwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuODc2MDAwMDAwMDQ5MjAyOCwidG9nZ2xlIjp0cnVlLCJib3VnaHQiOnRydWV9LCJib25maXJlRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDE3MjczNjIwMzk4MTEyMiIsImFtb3VudE9mVGltZXNEb25lIjowLjI1ODAwMDAwMDA0OTg4OTksInRvZ2dsZSI6dHJ1ZSwiYm91Z2h0Ijp0cnVlfSwia2lsbkVsZiI6eyJidXlQcm9ncmVzcyI6IjAuMDAxNTMzODU1Mjk4NTQwOTk4MSIsImFtb3VudE9mVGltZXNEb25lIjowLjY5NDAwMDAwMDA1MDAzOSwidG9nZ2xlIjp0cnVlLCJib3VnaHQiOnRydWV9LCJwYXBlckVsZiI6eyJidXlQcm9ncmVzcyI6IjAuMDAwODQyMDg2ODM0NzQ2MjA4NSIsImFtb3VudE9mVGltZXNEb25lIjowLjg4MDAwMDAwMDAwMDg4NTQsImJvdWdodCI6dHJ1ZX0sImJveEVsZiI6eyJidXlQcm9ncmVzcyI6IjAuMDA1Mjk0MTE3NjQ3MDcyNTc3IiwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuMzA0MDAwMDAwMDAwOTMyODYsImJvdWdodCI6dHJ1ZX0sImNsb3RoRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMDM4NjI1MDk4MTkwNzU0MDUiLCJhbW91bnRPZlRpbWVzRG9uZSI6MC40MzIwMDAwMDAwMDIyMzMyNiwiYm91Z2h0Ijp0cnVlfSwiY29hbERyaWxsRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMTE0NTQ1NDU0NTQ1NDUyNzMiLCJhbW91bnRPZlRpbWVzRG9uZSI6MC41MDM5OTk5OTk5OTk4ODc2LCJ0b2dnbGUiOnRydWUsImJvdWdodCI6dHJ1ZX0sImhlYXZ5RHJpbGxFbGYiOnsiYnV5UHJvZ3Jlc3MiOiIwLjAxMTQ1NDU0NTQ1NDU0NTI3MyIsImFtb3VudE9mVGltZXNEb25lIjowLjUwMzk5OTk5OTk5OTg4NzYsInRvZ2dsZSI6dHJ1ZSwiYm91Z2h0Ijp0cnVlfSwib2lsRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMTE0NTQ1NDU0NTQ1NDUyNzMiLCJhbW91bnRPZlRpbWVzRG9uZSI6MC41MDM5OTk5OTk5OTk4ODc2LCJ0b2dnbGUiOnRydWUsImJvdWdodCI6dHJ1ZX0sIm1ldGFsRWxmIjp7ImJ1eVByb2dyZXNzIjoiMC4wMTE0NTQ1NDU0NTQ1NDUyNzMiLCJhbW91bnRPZlRpbWVzRG9uZSI6MC41MDM5OTk5OTk5OTk4ODc2LCJib3VnaHQiOnRydWV9LCJkeWVFbGYiOnsiYnV5UHJvZ3Jlc3MiOjAsImFtb3VudE9mVGltZXNEb25lIjowLCJib3VnaHQiOmZhbHNlfSwicGxhc3RpY0VsZiI6eyJidXlQcm9ncmVzcyI6IjAuMDAzNTMzNzA0NDcxMDYxNjA1IiwiYW1vdW50T2ZUaW1lc0RvbmUiOjAuOTQwMDAwMDAwMDAwNzkzNSwiYm91Z2h0Ijp0cnVlfX0sIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX0sIjUiOnsiZWFybmVkIjp0cnVlfSwiNiI6eyJlYXJuZWQiOnRydWV9LCI3Ijp7ImVhcm5lZCI6dHJ1ZX0sIjgiOnsiZWFybmVkIjp0cnVlfSwiOSI6eyJlYXJuZWQiOnRydWV9LCIxMCI6eyJlYXJuZWQiOnRydWV9LCIxMSI6eyJlYXJuZWQiOnRydWV9fX19LCJwYXBlciI6eyJtaW5pbWl6ZWQiOmZhbHNlLCJwYXBlciI6IjguNTc5NDkxNjcwODU4MjQ2ZTEwMSIsInRvdGFsUGFwZXIiOiI4LjU3OTQ5MTk0MTY4MzAxM2UxMDEiLCJwYXBlckNvbnZlcnNpb24iOnsiZ2FpblJlc291cmNlIjoiNDA2OS45OTk5OTk5OTk5OTkifSwiYm9va3MiOnsiY3V0dGVyc0Jvb2siOnsicmVzb3VyY2UiOiI0MDY5Ljk5OTk5OTk5OTk5OSIsImFtb3VudCI6IjE4MSJ9LCJwbGFudGVyc0Jvb2siOnsicmVzb3VyY2UiOiI0MDY5Ljk5OTk5OTk5OTk5OSIsImFtb3VudCI6IjE4MSJ9LCJleHBhbmRlcnNCb29rIjp7InJlc291cmNlIjoiNDA2OS45OTk5OTk5OTk5OTkiLCJhbW91bnQiOiIxODEifSwiaGVhdGVkQ3V0dGVyc0Jvb2siOnsicmVzb3VyY2UiOiI0MDY5Ljk5OTk5OTk5OTk5OSIsImFtb3VudCI6IjE4MSJ9LCJoZWF0ZWRQbGFudGVyc0Jvb2siOnsicmVzb3VyY2UiOiI0MDY5Ljk5OTk5OTk5OTk5OSIsImFtb3VudCI6IjE4MSJ9LCJmZXJ0aWxpemVyQm9vayI6eyJyZXNvdXJjZSI6IjQwNjkuOTk5OTk5OTk5OTk5IiwiYW1vdW50IjoiMTgxIn0sInNtYWxsRmlyZUJvb2siOnsicmVzb3VyY2UiOiI0MDY5Ljk5OTk5OTk5OTk5OSIsImFtb3VudCI6IjE4MSJ9LCJib25maXJlQm9vayI6eyJyZXNvdXJjZSI6IjQwNjkuOTk5OTk5OTk5OTk5IiwiYW1vdW50IjoiMTgxIn0sImtpbG5Cb29rIjp7InJlc291cmNlIjoiNDA2OS45OTk5OTk5OTk5OTkiLCJhbW91bnQiOiIxODEifSwicGFwZXJCb29rIjp7ImFtb3VudCI6IjEyIn0sImJveEJvb2siOnsiYW1vdW50IjoiMTQifSwiY2xvdGhCb29rIjp7ImFtb3VudCI6IjE4MSJ9LCJtaW5pbmdEcmlsbEJvb2siOnsiYW1vdW50IjowfSwiaGVhdnlEcmlsbEJvb2siOnsiYW1vdW50IjoiMTUyIn0sIm9pbEJvb2siOnsiYW1vdW50IjoiMTUyIn0sIm1ldGFsQm9vayI6eyJhbW91bnQiOiIxNTIifSwiY29hbERyaWxsQm9vayI6eyJhbW91bnQiOiIxNTIifSwiZHllQm9vayI6eyJhbW91bnQiOjB9LCJwcmltYXJ5RHllQm9vayI6eyJhbW91bnQiOiIxODEifSwic2Vjb25kYXJ5RHllQm9vayI6eyJhbW91bnQiOiIxODEifSwicGxhc3RpY0Jvb2siOnsiYW1vdW50IjoiMTgxIn19LCJnZW5lcmFsVGFiQ29sbGFwc2VkIjp7fSwidXBncmFkZXMiOnsiY2xvdGhVcGdyYWRlIjp7ImJvdWdodCI6dHJ1ZX0sImRyaWxsaW5nVXBncmFkZSI6eyJib3VnaHQiOnRydWV9LCJvaWxVcGdyYWRlIjp7ImJvdWdodCI6dHJ1ZX19LCJ1cGdyYWRlczIiOnsiYXNoVXBncmFkZSI6eyJib3VnaHQiOnRydWV9LCJib29rVXBncmFkZSI6eyJib3VnaHQiOnRydWV9LCJjbGFzc3Jvb21VcGdyYWRlIjp7ImJvdWdodCI6ZmFsc2V9LCJ0cmVlVXBncmFkZSI6eyJib3VnaHQiOnRydWV9fSwibWFzdGVyeSI6eyJwYXBlciI6IjMuMjM0ODcyNDA0NzQyMDQ5ZTIzIiwidG90YWxQYXBlciI6IjMuMjM0ODc1MzAxNTIyMjY3OGUyMyIsImJvb2tzIjp7ImN1dHRlcnNCb29rIjp7ImFtb3VudCI6IjQ3In0sInBsYW50ZXJzQm9vayI6eyJhbW91bnQiOiI0NyJ9LCJleHBhbmRlcnNCb29rIjp7ImFtb3VudCI6IjQ3In0sImhlYXRlZEN1dHRlcnNCb29rIjp7ImFtb3VudCI6IjQ3In0sImhlYXRlZFBsYW50ZXJzQm9vayI6eyJhbW91bnQiOiI0NyJ9LCJmZXJ0aWxpemVyQm9vayI6eyJhbW91bnQiOiI0NyJ9LCJzbWFsbEZpcmVCb29rIjp7ImFtb3VudCI6IjQ3In0sImJvbmZpcmVCb29rIjp7ImFtb3VudCI6IjQ3In0sImtpbG5Cb29rIjp7ImFtb3VudCI6IjQ3In0sInBhcGVyQm9vayI6eyJhbW91bnQiOiI3In0sImJveEJvb2siOnsiYW1vdW50IjoiNyJ9LCJjbG90aEJvb2siOnsiYW1vdW50IjoiNDcifSwiY29hbERyaWxsQm9vayI6eyJhbW91bnQiOiIxIn0sImhlYXZ5RHJpbGxCb29rIjp7ImFtb3VudCI6IjEifSwib2lsQm9vayI6eyJhbW91bnQiOiIxIn0sIm1ldGFsQm9vayI6eyJhbW91bnQiOiIxIn0sInByaW1hcnlEeWVCb29rIjp7ImFtb3VudCI6MH0sInNlY29uZGFyeUR5ZUJvb2siOnsiYW1vdW50IjowfSwicGxhc3RpY0Jvb2siOnsiYW1vdW50IjoiNDcifX0sInVwZ3JhZGVzIjp7ImNsb3RoVXBncmFkZSI6eyJib3VnaHQiOnRydWV9LCJkcmlsbGluZ1VwZ3JhZGUiOnsiYm91Z2h0Ijp0cnVlfSwib2lsVXBncmFkZSI6eyJib3VnaHQiOnRydWV9fSwidXBncmFkZXMyIjp7ImFzaFVwZ3JhZGUiOnsiYm91Z2h0IjpmYWxzZX0sImJvb2tVcGdyYWRlIjp7ImJvdWdodCI6ZmFsc2V9LCJ0cmVlVXBncmFkZSI6eyJib3VnaHQiOmZhbHNlfX19LCJtYXN0ZXJlZCI6dHJ1ZX0sImJveGVzIjp7Im1pbmltaXplZCI6ZmFsc2UsImJveGVzIjoiMS4wMDI5MjExMzg4Nzk1NTMxZTg4IiwidG90YWxCb3hlcyI6IjEuMDEzMDg3ODAzNTIyNTc4OGU4OCIsImJveGVzQ29udmVyc2lvbiI6eyJiYXNlUmVzb3VyY2UiOiIxMDI4NDM2MDY2MTA4LjY1OTQiLCJnYWluUmVzb3VyY2UiOjB9LCJ1cGdyYWRlcyI6eyJsb2dzVXBncmFkZSI6eyJyZXNvdXJjZSI6MCwiYm91Z2h0Ijp0cnVlfSwiYXNoVXBncmFkZSI6eyJyZXNvdXJjZSI6MCwiYm91Z2h0Ijp0cnVlfSwiY29hbFVwZ3JhZGUiOnsicmVzb3VyY2UiOjAsImJvdWdodCI6dHJ1ZX19LCJidXlhYmxlcyI6eyJsb2dCb3hlc0J1eWFibGUiOnsicmVzb3VyY2UiOjAsImFtb3VudCI6IjY3NCJ9LCJhc2hCb3hlc0J1eWFibGUiOnsicmVzb3VyY2UiOjAsImFtb3VudCI6IjMwMyJ9LCJjb2FsQm94ZXNCdXlhYmxlIjp7InJlc291cmNlIjowLCJhbW91bnQiOiIyMzQifX0sInJvdzJVcGdyYWRlcyI6eyJvcmVVcGdyYWRlIjp7ImJvdWdodCI6dHJ1ZX0sIm1ldGFsVXBncmFkZSI6eyJib3VnaHQiOnRydWV9LCJwbGFzdGljVXBncmFkZSI6eyJib3VnaHQiOnRydWV9fSwicm93M1VwZ3JhZGVzIjp7ImNsb3RoVXBncmFkZSI6eyJib3VnaHQiOnRydWV9LCJkeWVVcGdyYWRlIjp7ImJvdWdodCI6dHJ1ZX0sInhwVXBncmFkZSI6eyJib3VnaHQiOnRydWV9fSwiZ2VuZXJhbFRhYkNvbGxhcHNlZCI6e30sImJ1eWFibGVzMiI6eyJvcmVCb3hlc0J1eWFibGUiOnsiYW1vdW50IjoiMTY0In0sIm1ldGFsQm94ZXNCdXlhYmxlIjp7ImFtb3VudCI6IjExNSJ9LCJwbGFzdGljQm94ZXNCdXlhYmxlIjp7ImFtb3VudCI6Ijk4In19LCJtYXN0ZXJ5Ijp7ImJveGVzIjoiNi4wMTQ5MDk4Nzg1NzU0MjllMTYiLCJ0b3RhbEJveGVzIjoiNi4wMTQ5MTM1Mjc1NDAxMzFlMTYiLCJ1cGdyYWRlcyI6eyJsb2dzVXBncmFkZSI6eyJib3VnaHQiOnRydWV9LCJhc2hVcGdyYWRlIjp7ImJvdWdodCI6dHJ1ZX0sImNvYWxVcGdyYWRlIjp7ImJvdWdodCI6dHJ1ZX19LCJyb3cyVXBncmFkZXMiOnsib3JlVXBncmFkZSI6eyJib3VnaHQiOnRydWV9LCJtZXRhbFVwZ3JhZGUiOnsiYm91Z2h0Ijp0cnVlfSwicGxhc3RpY1VwZ3JhZGUiOnsiYm91Z2h0Ijp0cnVlfX0sInJvdzNVcGdyYWRlcyI6eyJjbG90aFVwZ3JhZGUiOnsiYm91Z2h0IjpmYWxzZX0sImR5ZVVwZ3JhZGUiOnsiYm91Z2h0IjpmYWxzZX0sInhwVXBncmFkZSI6eyJib3VnaHQiOmZhbHNlfX0sImJ1eWFibGVzIjp7ImxvZ0JveGVzQnV5YWJsZSI6eyJhbW91bnQiOiI0NyJ9LCJhc2hCb3hlc0J1eWFibGUiOnsiYW1vdW50IjoiMzAifSwiY29hbEJveGVzQnV5YWJsZSI6eyJhbW91bnQiOiIyNSJ9fSwiYnV5YWJsZXMyIjp7Im9yZUJveGVzQnV5YWJsZSI6eyJhbW91bnQiOjB9LCJtZXRhbEJveGVzQnV5YWJsZSI6eyJhbW91bnQiOjB9LCJwbGFzdGljQm94ZXNCdXlhYmxlIjp7ImFtb3VudCI6MH19fSwibWFzdGVyZWQiOnRydWV9LCJtZXRhbCI6eyJtaW5pbWl6ZWQiOmZhbHNlLCJvcmUiOiIxLjY5NzYwNDY2ODE1MTE2NWUzMCIsImJlc3RPcmUiOiIxLjkwNjY4ODY5NjE2NDc1MjdlMzAiLCJvcmVQcm9ncmVzcyI6IjAuMTM3Nzk3NDE3NjgwNjc2NjYiLCJtZXRhbCI6IjYuMTY1NjU5NTU4ODMyMTYyNWU1NyIsImJlc3RNZXRhbCI6IjYuMTY1NjU5NTU4ODMyMTYyNWU1NyIsInRvdGFsTWV0YWwiOiI2LjE4OTkzNDIwNjYyMDg3NGU1NyIsInNpbXBsZVBpY2theGUiOnsiYm91Z2h0Ijp0cnVlfSwiZG91YmxlUGlja2F4ZSI6eyJib3VnaHQiOmZhbHNlfSwiY3J1Y2libGUiOnsiYm91Z2h0Ijp0cnVlfSwiY29hbERyaWxsIjp7ImJvdWdodCI6dHJ1ZX0sImluZHVzdHJpYWxGdXJuYWNlIjp7ImJvdWdodCI6dHJ1ZX0sIm9yZURyaWxsIjp7ImFtb3VudCI6IjI0MTYyNzAifSwiaW5kdXN0cmlhbENydWNpYmxlIjp7ImFtb3VudCI6IjI0MTYyNyJ9LCJhdXRvU21lbHRFbmFibGVkIjp0cnVlLCJob3R0ZXJGb3JnZSI6eyJhbW91bnQiOiIzMzUzNzkifSwiZ2VuZXJhbFRhYkNvbGxhcHNlZCI6e30sImVmZmljaWVudERyaWxsIjp7ImJvdWdodCI6dHJ1ZX0sIm1hc3RlcnkiOnsib3JlIjoiOTI3NTcyMTIwLjQ0MjYzNjUiLCJiZXN0T3JlIjoiMTk1MzMwOTAwNy4wNDQwOTgiLCJvcmVQcm9ncmVzcyI6IjAuNTMxMDMxMjY2MTM4MjM0NiIsIm1ldGFsIjoiMy42NTMyMjkxOTUxMTEwNGUxNiIsImJlc3RNZXRhbCI6IjMuNjUzMjI5MTk1MTExMDRlMTYiLCJ0b3RhbE1ldGFsIjoiMy42NTMyNTcwMzA2MzI0MDVlMTYiLCJzaW1wbGVQaWNrYXhlIjp7ImJvdWdodCI6dHJ1ZX0sImRvdWJsZVBpY2theGUiOnsiYm91Z2h0IjpmYWxzZX0sImNydWNpYmxlIjp7ImJvdWdodCI6dHJ1ZX0sImNvYWxEcmlsbCI6eyJib3VnaHQiOnRydWV9LCJpbmR1c3RyaWFsRnVybmFjZSI6eyJib3VnaHQiOnRydWV9LCJlZmZpY2llbnREcmlsbCI6eyJib3VnaHQiOnRydWV9LCJvcmVEcmlsbCI6eyJhbW91bnQiOiIyNzAifSwiaW5kdXN0cmlhbENydWNpYmxlIjp7ImFtb3VudCI6IjI3In0sImhvdHRlckZvcmdlIjp7ImFtb3VudCI6IjI0In19LCJtYXN0ZXJlZCI6dHJ1ZX0sImNsb3RoIjp7Im1pbmltaXplZCI6ZmFsc2UsImNsb3RoIjoiMi40MDQ3MTIyOTgzNTczMjY0ZTE3IiwidG90YWxDbG90aCI6IjcuNTU0ODk3MDI4MDQzODYxZTE3Iiwid29vbCI6IjEuOTg1MTYxNjY5NDM2MzA1ZTE3Iiwic2hlZXAiOiIyLjAzMTY1MTU3ODUyMzYxN2UxNyIsImJ1aWxkUGVucyI6eyJhbW91bnQiOiIyMDQzOSJ9LCJiZXR0ZXJTaGVhcnMiOnsiYW1vdW50IjoiMTk5MDcifSwiZmFzdGVyU3Bpbm5pbmciOnsiYW1vdW50IjoiMjk5NzAifSwidHJlZXNVcGdyYWRlcyI6eyJ0cmVlc1VwZ3JhZGUzIjp7ImJvdWdodCI6dHJ1ZX0sInRyZWVzVXBncmFkZTIiOnsiYm91Z2h0Ijp0cnVlfSwidHJlZXNVcGdyYWRlMSI6eyJib3VnaHQiOnRydWV9LCJ0cmVlc1VwZ3JhZGU0Ijp7ImJvdWdodCI6dHJ1ZX19LCJtZXRhbFVwZ3JhZGVzIjp7Im1ldGFsVXBncmFkZTMiOnsiYm91Z2h0Ijp0cnVlfSwibWV0YWxVcGdyYWRlMiI6eyJib3VnaHQiOnRydWV9LCJtZXRhbFVwZ3JhZGUxIjp7ImJvdWdodCI6dHJ1ZX0sIm1ldGFsVXBncmFkZTQiOnsiYm91Z2h0Ijp0cnVlfX0sInBhcGVyVXBncmFkZXMiOnsicGFwZXJVcGdyYWRlMyI6eyJib3VnaHQiOnRydWV9LCJwYXBlclVwZ3JhZGUyIjp7ImJvdWdodCI6dHJ1ZX0sInBhcGVyVXBncmFkZTEiOnsiYm91Z2h0Ijp0cnVlfSwicGFwZXJVcGdyYWRlNCI6eyJib3VnaHQiOnRydWV9fSwiZ2VuZXJhbFRhYkNvbGxhcHNlZCI6e30sImJyZWVkaW5nUHJvZ3Jlc3MiOjEsInNoZWFyaW5nUHJvZ3Jlc3MiOjEsInNwaW5uaW5nUHJvZ3Jlc3MiOjEsIm1hc3RlcnkiOnsiY2xvdGgiOiIxMTE0NTEiLCJ0b3RhbENsb3RoIjoiMTE4OTAxIiwid29vbCI6IjYyMzIwIiwic2hlZXAiOiI3NjQwMyIsImJ1aWxkUGVucyI6eyJhbW91bnQiOiIyNDgifSwiYmV0dGVyU2hlYXJzIjp7ImFtb3VudCI6IjMxMCJ9LCJmYXN0ZXJTcGlubmluZyI6eyJhbW91bnQiOiI0MTQifSwidHJlZXNVcGdyYWRlcyI6eyJ0cmVlc1VwZ3JhZGUxIjp7ImJvdWdodCI6dHJ1ZX0sInRyZWVzVXBncmFkZTIiOnsiYm91Z2h0Ijp0cnVlfSwidHJlZXNVcGdyYWRlMyI6eyJib3VnaHQiOnRydWV9LCJ0cmVlc1VwZ3JhZGU0Ijp7ImJvdWdodCI6dHJ1ZX19LCJtZXRhbFVwZ3JhZGVzIjp7Im1ldGFsVXBncmFkZTEiOnsiYm91Z2h0Ijp0cnVlfSwibWV0YWxVcGdyYWRlMiI6eyJib3VnaHQiOnRydWV9LCJtZXRhbFVwZ3JhZGUzIjp7ImJvdWdodCI6dHJ1ZX0sIm1ldGFsVXBncmFkZTQiOnsiYm91Z2h0Ijp0cnVlfX0sInBhcGVyVXBncmFkZXMiOnsicGFwZXJVcGdyYWRlMSI6eyJib3VnaHQiOnRydWV9LCJwYXBlclVwZ3JhZGUyIjp7ImJvdWdodCI6dHJ1ZX0sInBhcGVyVXBncmFkZTMiOnsiYm91Z2h0Ijp0cnVlfSwicGFwZXJVcGdyYWRlNCI6eyJib3VnaHQiOnRydWV9fX0sIm1hc3RlcmVkIjp0cnVlfSwib2lsIjp7Im1pbmltaXplZCI6ZmFsc2UsIm9pbCI6IjEuODk0NzU3NTQ1MDA4MzQ0N2UyNCIsInRvdGFsT2lsIjoiNS4yNzk0NzA5ODE3NDc4MThlMjQiLCJkZXB0aCI6IjEwNDAxMyIsImRyaWxsUHJvZ3Jlc3MiOiIxLjc0NTc1NDgwOTE5NjIwNGU0NyIsImFjdGl2ZUhlYXZ5IjoiMTAzNCIsImJ1aWxkSGVhdnkiOnsiYW1vdW50IjoiMTAzNCJ9LCJhY3RpdmVIZWF2eTIiOiI0ODEiLCJidWlsZEhlYXZ5MiI6eyJhbW91bnQiOiI0ODEifSwiYWN0aXZlRXh0cmFjdG9yIjoiMTEwIiwiYnVpbGRFeHRyYWN0b3IiOnsiYW1vdW50IjoiMTEwIn0sImFjdGl2ZVB1bXAiOiIxMDQiLCJidWlsZFB1bXAiOnsiYW1vdW50IjoiMTA0In0sImFjdGl2ZUJ1cm5lciI6IjY1NCIsImJ1aWxkQnVybmVyIjp7ImFtb3VudCI6IjY1NCJ9LCJhY3RpdmVTbWVsdGVyIjoiMzY4IiwiYnVpbGRTbWVsdGVyIjp7ImFtb3VudCI6IjM2OCJ9LCJkZXB0aE1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX0sIjUiOnsiZWFybmVkIjp0cnVlfSwiNiI6eyJlYXJuZWQiOnRydWV9LCI3Ijp7ImVhcm5lZCI6dHJ1ZX19LCJjb2xsYXBzZWREZXB0aE1pbGVzdG9uZXMiOnRydWUsInJvdzFVcGdyYWRlcyI6eyIwIjp7ImJvdWdodCI6dHJ1ZX0sIjEiOnsiYm91Z2h0Ijp0cnVlfSwiMiI6eyJib3VnaHQiOnRydWV9LCIzIjp7ImJvdWdodCI6dHJ1ZX0sIjQiOnsiYm91Z2h0Ijp0cnVlfX0sInJvdzJVcGdyYWRlcyI6eyIwIjp7ImJvdWdodCI6dHJ1ZX0sIjEiOnsiYm91Z2h0Ijp0cnVlfSwiMiI6eyJib3VnaHQiOnRydWV9LCIzIjp7ImJvdWdodCI6dHJ1ZX0sIjQiOnsiYm91Z2h0Ijp0cnVlfX0sImdlbmVyYWxUYWJDb2xsYXBzZWQiOnt9LCJvaWxNaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjp0cnVlfSwiMSI6eyJlYXJuZWQiOnRydWV9LCIyIjp7ImVhcm5lZCI6dHJ1ZX19LCJjb2xsYXBzZWRPaWxNaWxlc3RvbmVzIjp0cnVlLCJyb3czVXBncmFkZXMiOnsiMCI6eyJib3VnaHQiOnRydWV9LCIxIjp7ImJvdWdodCI6dHJ1ZX0sIjIiOnsiYm91Z2h0Ijp0cnVlfSwiMyI6eyJib3VnaHQiOnRydWV9LCI0Ijp7ImJvdWdodCI6dHJ1ZX19LCJtYXN0ZXJ5Ijp7Im9pbCI6IjUwODA2MDY5MS44MzU4MzA2IiwidG90YWxPaWwiOiI1MTE0MTQ2NDEuODM1ODMwNiIsImRlcHRoIjoiMjMwOTMiLCJkcmlsbFByb2dyZXNzIjoiMTM1NTcyNTUyMzE2NC43ODEyIiwiYWN0aXZlSGVhdnkiOiIxMDMiLCJidWlsZEhlYXZ5Ijp7ImFtb3VudCI6IjEwMyJ9LCJhY3RpdmVIZWF2eTIiOiI0MSIsImJ1aWxkSGVhdnkyIjp7ImFtb3VudCI6IjQxIn0sImFjdGl2ZUV4dHJhY3RvciI6IjExIiwiYnVpbGRFeHRyYWN0b3IiOnsiYW1vdW50IjoiMTEifSwiYWN0aXZlUHVtcCI6IjExIiwiYnVpbGRQdW1wIjp7ImFtb3VudCI6IjExIn0sImFjdGl2ZUJ1cm5lciI6IjI1IiwiYnVpbGRCdXJuZXIiOnsiYW1vdW50IjoiMjUifSwiYWN0aXZlU21lbHRlciI6IjEyIiwiYnVpbGRTbWVsdGVyIjp7ImFtb3VudCI6IjEyIn0sImRlcHRoTWlsZXN0b25lcyI6eyIwIjp7ImVhcm5lZCI6dHJ1ZX0sIjEiOnsiZWFybmVkIjp0cnVlfSwiMiI6eyJlYXJuZWQiOnRydWV9LCIzIjp7ImVhcm5lZCI6dHJ1ZX0sIjQiOnsiZWFybmVkIjp0cnVlfSwiNSI6eyJlYXJuZWQiOnRydWV9LCI2Ijp7ImVhcm5lZCI6dHJ1ZX0sIjciOnsiZWFybmVkIjp0cnVlfX0sIm9pbE1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfX0sInJvdzFVcGdyYWRlcyI6eyIwIjp7ImJvdWdodCI6dHJ1ZX0sIjEiOnsiYm91Z2h0Ijp0cnVlfSwiMiI6eyJib3VnaHQiOnRydWV9LCIzIjp7ImJvdWdodCI6dHJ1ZX0sIjQiOnsiYm91Z2h0Ijp0cnVlfX0sInJvdzJVcGdyYWRlcyI6eyIwIjp7ImJvdWdodCI6dHJ1ZX0sIjEiOnsiYm91Z2h0Ijp0cnVlfSwiMiI6eyJib3VnaHQiOnRydWV9LCIzIjp7ImJvdWdodCI6dHJ1ZX0sIjQiOnsiYm91Z2h0Ijp0cnVlfX0sInJvdzNVcGdyYWRlcyI6eyIwIjp7ImJvdWdodCI6ZmFsc2V9LCIxIjp7ImJvdWdodCI6ZmFsc2V9LCIyIjp7ImJvdWdodCI6ZmFsc2V9LCIzIjp7ImJvdWdodCI6ZmFsc2V9LCI0Ijp7ImJvdWdodCI6ZmFsc2V9fX0sIm1hc3RlcmVkIjp0cnVlfSwicGxhc3RpYyI6eyJtaW5pbWl6ZWQiOmZhbHNlLCJwbGFzdGljIjoiMy41NzAzNTU0NzkyOTMyNTNlMjEiLCJ0b3RhbFBsYXN0aWMiOiI0LjQ3NTgxODg1NDM1Njk1N2UyMSIsImJ1aWxkUmVmaW5lcnkiOnsiYW1vdW50IjoiNTQ0In0sImFjdGl2ZVJlZmluZXJ5IjoiNTQ0IiwidXBncmFkZXMiOnsicGFwZXJUb29scyI6eyJib3VnaHQiOnRydWV9LCJib3hUb29scyI6eyJib3VnaHQiOnRydWV9LCJjbG90aFRvb2xzIjp7ImJvdWdodCI6dHJ1ZX19LCJlbGZVcGdyYWRlcyI6eyJwYXBlckVsZiI6eyJib3VnaHQiOnRydWV9LCJib3hFbGYiOnsiYm91Z2h0Ijp0cnVlfSwiY2xvdGhFbGYiOnsiYm91Z2h0Ijp0cnVlfX0sImJ1eWFibGVzIjp7InBhc3NpdmVQYXBlciI6eyJhbW91bnQiOiIyODEwOTE2In0sInBhc3NpdmVCb3hlcyI6eyJhbW91bnQiOiIyODEwOTE2In0sImNsb3RoR2FpbnMiOnsiYW1vdW50IjoiMjgxMDkxNiJ9fSwiZ2VuZXJhbFRhYkNvbGxhcHNlZCI6e30sIm1hc3RlcnkiOnsicGxhc3RpYyI6IjE2NDAwNzAuNDUyMjMyOTEyIiwidG90YWxQbGFzdGljIjoiMTY2MTkxMC40NTIyMzI5MTIiLCJhY3RpdmVSZWZpbmVyeSI6IjQ2IiwiYnVpbGRSZWZpbmVyeSI6eyJhbW91bnQiOiI0NiJ9LCJ1cGdyYWRlcyI6eyJwYXBlclRvb2xzIjp7ImJvdWdodCI6dHJ1ZX0sImJveFRvb2xzIjp7ImJvdWdodCI6dHJ1ZX0sImNsb3RoVG9vbHMiOnsiYm91Z2h0Ijp0cnVlfX0sImVsZlVwZ3JhZGVzIjp7InBhcGVyRWxmIjp7ImJvdWdodCI6dHJ1ZX0sImJveEVsZiI6eyJib3VnaHQiOnRydWV9LCJjbG90aEVsZiI6eyJib3VnaHQiOnRydWV9fSwiYnV5YWJsZXMiOnsicGFzc2l2ZVBhcGVyIjp7ImFtb3VudCI6IjY2MSJ9LCJwYXNzaXZlQm94ZXMiOnsiYW1vdW50IjoiNjYxIn0sImNsb3RoR2FpbnMiOnsiYW1vdW50IjoiNjYxIn19fSwibWFzdGVyZWQiOnRydWV9LCJkeWVzIjp7Im1pbmltaXplZCI6ZmFsc2UsImR5ZXMiOnsicmVkIjp7ImFtb3VudCI6Ijc2Mjc5ODMyNzU3Ljg5OTE5IiwiYnV5YWJsZSI6eyJhbW91bnQiOiIxMjE3In19LCJ5ZWxsb3ciOnsiYW1vdW50IjoiMTg4OTIyNDg3Mzg2LjcwOTc1IiwiYnV5YWJsZSI6eyJhbW91bnQiOiIxMTY1In19LCJibHVlIjp7ImFtb3VudCI6IjI1NzI2MjcyNTg4LjYxNjM5IiwiYnV5YWJsZSI6eyJhbW91bnQiOiIxMTE2In19LCJvcmFuZ2UiOnsiYW1vdW50IjoiNDE1NzYiLCJidXlhYmxlIjp7ImFtb3VudCI6IjgxMCJ9fSwiZ3JlZW4iOnsiYW1vdW50IjoiMzIxOTYiLCJidXlhYmxlIjp7ImFtb3VudCI6IjY5OSJ9fSwicHVycGxlIjp7ImFtb3VudCI6IjMwMzIwIiwiYnV5YWJsZSI6eyJhbW91bnQiOiI2ODEifX0sImJsYWNrIjp7ImJ1eWFibGUiOnsiYW1vdW50IjoiMjMwIn19LCJ3aGl0ZSI6eyJidXlhYmxlIjp7ImFtb3VudCI6IjIzMCJ9fX0sImdlbmVyYWxUYWJDb2xsYXBzZWQiOnt9LCJ1cGdyYWRlcyI6eyJibHVlRHllVXBnIjp7ImJvdWdodCI6dHJ1ZX0sInJlZER5ZVVwZyI6eyJib3VnaHQiOnRydWV9LCJ5ZWxsb3dEeWVVcGciOnsiYm91Z2h0Ijp0cnVlfSwieWVsbG93RHllVXBnMiI6eyJib3VnaHQiOnRydWV9LCJyZWREeWVVcGcyIjp7ImJvdWdodCI6dHJ1ZX0sImJsdWVEeWVVcGcyIjp7ImJvdWdodCI6dHJ1ZX0sImNvYWxVcGciOnsiYm91Z2h0Ijp0cnVlfX0sIm1hc3RlcnkiOnsiZHllcyI6eyJyZWQiOnsiYW1vdW50IjowLCJidXlhYmxlIjp7ImFtb3VudCI6IjE1In19LCJncmVlbiI6eyJhbW91bnQiOjAsImJ1eWFibGUiOnsiYW1vdW50IjoiNSJ9fSwiYmx1ZSI6eyJhbW91bnQiOjAsImJ1eWFibGUiOnsiYW1vdW50IjoiMTQifX0sInllbGxvdyI6eyJhbW91bnQiOjAsImJ1eWFibGUiOnsiYW1vdW50IjoiMTIifX0sInB1cnBsZSI6eyJhbW91bnQiOjAsImJ1eWFibGUiOnsiYW1vdW50IjoiNCJ9fSwib3JhbmdlIjp7ImFtb3VudCI6MCwiYnV5YWJsZSI6eyJhbW91bnQiOiI0In19fSwidXBncmFkZXMiOnsiYmx1ZUR5ZVVwZyI6eyJib3VnaHQiOnRydWV9LCJyZWREeWVVcGciOnsiYm91Z2h0Ijp0cnVlfSwieWVsbG93RHllVXBnIjp7ImJvdWdodCI6dHJ1ZX0sInllbGxvd0R5ZVVwZzIiOnsiYm91Z2h0Ijp0cnVlfSwicmVkRHllVXBnMiI6eyJib3VnaHQiOnRydWV9LCJibHVlRHllVXBnMiI6eyJib3VnaHQiOnRydWV9LCJjb2FsVXBnIjp7ImJvdWdodCI6dHJ1ZX19fSwibWFzdGVyZWQiOnRydWV9LCJtYW5hZ2VtZW50Ijp7Im1pbmltaXplZCI6ZmFsc2UsImVsZlRyYWluaW5nIjp7ImN1dHRlckVsZlRyYWluaW5nIjp7InN0YXRlIjp0cnVlLCJleHAiOiIzMTI3NDY4LjIyOTc1OTUwMTgiLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjp0cnVlfSwiMSI6eyJlYXJuZWQiOnRydWV9LCIyIjp7ImVhcm5lZCI6dHJ1ZX0sIjMiOnsiZWFybmVkIjp0cnVlfSwiNCI6eyJlYXJuZWQiOnRydWV9fX0sInBsYW50ZXJFbGZUcmFpbmluZyI6eyJzdGF0ZSI6dHJ1ZSwiZXhwIjoiNjI0ODQ1Ni4yMTU2NjA1NCIsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX19fSwiZXhwYW5kZXJzRWxmVHJhaW5pbmciOnsic3RhdGUiOmZhbHNlLCJleHAiOiI5Mzc2NDUxLjQzODk2MTQ0MyIsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX19fSwiaGVhdGVkQ3V0dGVyRWxmVHJhaW5pbmciOnsic3RhdGUiOnRydWUsImV4cCI6IjEyNDk2MzI3LjM5NTk2NDYxNSIsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX19fSwiaGVhdGVkUGxhbnRlckVsZlRyYWluaW5nIjp7InN0YXRlIjp0cnVlLCJleHAiOiIxNTYyMzk4My4yMDc5NDI2MyIsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX19fSwiZmVydGlsaXplckVsZlRyYWluaW5nIjp7InN0YXRlIjp0cnVlLCJleHAiOiIxODc4MDg4Mi45MTMyNTQxMiIsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX19fSwic21hbGxmaXJlRWxmVHJhaW5pbmciOnsic3RhdGUiOnRydWUsImV4cCI6IjIxOTA3NDkzLjM5MDE1MzU0NiIsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX19fSwiYm9uZmlyZUVsZlRyYWluaW5nIjp7InN0YXRlIjp0cnVlLCJleHAiOiIyNTAwNjQzNi4wMzM4ODIzMjciLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjp0cnVlfSwiMSI6eyJlYXJuZWQiOnRydWV9LCIyIjp7ImVhcm5lZCI6dHJ1ZX0sIjMiOnsiZWFybmVkIjp0cnVlfSwiNCI6eyJlYXJuZWQiOnRydWV9fX0sImZpcmVFbGZUcmFpbmluZyI6eyIyIjp7InN0YXRlIjp0cnVlLCJleHAiOjB9fSwia2lsbkVsZlRyYWluaW5nIjp7InN0YXRlIjp0cnVlLCJleHAiOiIyODE5MzUwNy43OTA3MTA5ODIiLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjp0cnVlfSwiMSI6eyJlYXJuZWQiOnRydWV9LCIyIjp7ImVhcm5lZCI6dHJ1ZX0sIjMiOnsiZWFybmVkIjp0cnVlfSwiNCI6eyJlYXJuZWQiOnRydWV9fX0sInBhcGVyRWxmVHJhaW5pbmciOnsic3RhdGUiOnRydWUsImV4cCI6IjEwNDMwOTA0LjQ2MzY2NDMwNiIsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX19fSwiYm94RWxmVHJhaW5pbmciOnsic3RhdGUiOmZhbHNlLCJleHAiOiIxMTQ3MDIyNC41MDQ5ODIzNDUiLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjp0cnVlfSwiMSI6eyJlYXJuZWQiOnRydWV9LCIyIjp7ImVhcm5lZCI6dHJ1ZX0sIjMiOnsiZWFybmVkIjp0cnVlfSwiNCI6eyJlYXJuZWQiOnRydWV9fX0sImNsb3RoRWxmVHJhaW5pbmciOnsic3RhdGUiOmZhbHNlLCJleHAiOiIzNzQ4OTM1NS4wNDcwMTA3NSIsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX19fSwiY29hbERyaWxsRWxmVHJhaW5pbmciOnsic3RhdGUiOmZhbHNlLCJleHAiOiI0MDYyMzY4NS4wNDA5MTI3NCIsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX19fSwibWV0YWxFbGZUcmFpbmluZyI6eyJzdGF0ZSI6ZmFsc2UsImV4cCI6IjUwMDQ2MDI3Ljk5OTYwOTU4IiwibWlsZXN0b25lcyI6eyIwIjp7ImVhcm5lZCI6dHJ1ZX0sIjEiOnsiZWFybmVkIjp0cnVlfSwiMiI6eyJlYXJuZWQiOnRydWV9LCIzIjp7ImVhcm5lZCI6dHJ1ZX0sIjQiOnsiZWFybmVkIjp0cnVlfX19LCJvaWxFbGZUcmFpbmluZyI6eyJzdGF0ZSI6ZmFsc2UsImV4cCI6IjQ2ODYwMzcxLjU0ODQxMTg3NiIsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOnRydWV9LCIxIjp7ImVhcm5lZCI6dHJ1ZX0sIjIiOnsiZWFybmVkIjp0cnVlfSwiMyI6eyJlYXJuZWQiOnRydWV9LCI0Ijp7ImVhcm5lZCI6dHJ1ZX19fSwiaGVhdnlEcmlsbEVsZlRyYWluaW5nIjp7InN0YXRlIjpmYWxzZSwiZXhwIjoiNDM3Mzk3MzUuNjE1MTU0MzkiLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjp0cnVlfSwiMSI6eyJlYXJuZWQiOnRydWV9LCIyIjp7ImVhcm5lZCI6dHJ1ZX0sIjMiOnsiZWFybmVkIjp0cnVlfSwiNCI6eyJlYXJuZWQiOnRydWV9fX0sImR5ZUVsZlRyYWluaW5nIjp7InN0YXRlIjpmYWxzZSwiZXhwIjoiNTMxMjc0MDAuNjQ3NjM2MTUiLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjp0cnVlfSwiMSI6eyJlYXJuZWQiOnRydWV9LCIyIjp7ImVhcm5lZCI6dHJ1ZX0sIjMiOnsiZWFybmVkIjp0cnVlfSwiNCI6eyJlYXJuZWQiOnRydWV9fX0sInBsYXN0aWNFbGZUcmFpbmluZyI6eyJzdGF0ZSI6ZmFsc2UsImV4cCI6IjU2MzQyNzcwLjQ1NjgxNTUyIiwibWlsZXN0b25lcyI6eyIwIjp7ImVhcm5lZCI6dHJ1ZX0sIjEiOnsiZWFybmVkIjp0cnVlfSwiMiI6eyJlYXJuZWQiOnRydWV9LCIzIjp7ImVhcm5lZCI6dHJ1ZX0sIjQiOnsiZWFybmVkIjp0cnVlfX19fSwiY3VycmVudFNob3duIjoiVGluc2VsIiwiZ2VuZXJhbFRhYkNvbGxhcHNlZCI6e30sInRlYWNoaW5nIjp7ImJvdWdodCI6dHJ1ZX0sInNjaG9vbHMiOnsiYW1vdW50IjoiNSJ9LCJjbGFzc3Jvb21zIjp7ImFtb3VudCI6IjEwNDYifSwiY2xhc3Nyb29tVXBncmFkZSI6eyJib3VnaHQiOnRydWV9LCJmb2N1c011bHRpcGxpZXIiOiIxLjAwNjE1NzgzMjc4NzQ5ODciLCJ1cGdyYWRlcyI6eyIwIjp7ImJvdWdodCI6dHJ1ZX0sIjEiOnsiYm91Z2h0Ijp0cnVlfSwiMiI6eyJib3VnaHQiOnRydWV9fSwiZm9jdXNUYXJnZXRzIjp7fSwiZm9jdXNDb29sZG93biI6MCwiZm9jdXNUaW1lIjowLCJhZHZhbmNlZFVwZ3JhZGUiOnsiYm91Z2h0Ijp0cnVlfSwidXBncmFkZXMyIjp7IjAiOnsiYm91Z2h0Ijp0cnVlfSwiMSI6eyJib3VnaHQiOnRydWV9LCIyIjp7ImJvdWdodCI6dHJ1ZX19LCJmb2N1c011bHRpIjoiMS4xNDM1OTc3ODM1MjYyODk2IiwibWFzdGVyeSI6eyJlbGZUcmFpbmluZyI6eyJib25maXJlRWxmVHJhaW5pbmciOnsiZXhwIjowLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjpmYWxzZX0sIjEiOnsiZWFybmVkIjpmYWxzZX0sIjIiOnsiZWFybmVkIjpmYWxzZX0sIjMiOnsiZWFybmVkIjpmYWxzZX0sIjQiOnsiZWFybmVkIjpmYWxzZX19fSwiYm94RWxmVHJhaW5pbmciOnsiZXhwIjowLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjpmYWxzZX0sIjEiOnsiZWFybmVkIjpmYWxzZX0sIjIiOnsiZWFybmVkIjpmYWxzZX0sIjMiOnsiZWFybmVkIjpmYWxzZX0sIjQiOnsiZWFybmVkIjpmYWxzZX19fSwiY2xvdGhFbGZUcmFpbmluZyI6eyJleHAiOjAsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOmZhbHNlfSwiMSI6eyJlYXJuZWQiOmZhbHNlfSwiMiI6eyJlYXJuZWQiOmZhbHNlfSwiMyI6eyJlYXJuZWQiOmZhbHNlfSwiNCI6eyJlYXJuZWQiOmZhbHNlfX19LCJjb2FsRHJpbGxFbGZUcmFpbmluZyI6eyJleHAiOjAsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOmZhbHNlfSwiMSI6eyJlYXJuZWQiOmZhbHNlfSwiMiI6eyJlYXJuZWQiOmZhbHNlfSwiMyI6eyJlYXJuZWQiOmZhbHNlfSwiNCI6eyJlYXJuZWQiOmZhbHNlfX19LCJjdXR0ZXJFbGZUcmFpbmluZyI6eyJleHAiOjAsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOmZhbHNlfSwiMSI6eyJlYXJuZWQiOmZhbHNlfSwiMiI6eyJlYXJuZWQiOmZhbHNlfSwiMyI6eyJlYXJuZWQiOmZhbHNlfSwiNCI6eyJlYXJuZWQiOmZhbHNlfX19LCJleHBhbmRlcnNFbGZUcmFpbmluZyI6eyJleHAiOjAsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOmZhbHNlfSwiMSI6eyJlYXJuZWQiOmZhbHNlfSwiMiI6eyJlYXJuZWQiOmZhbHNlfSwiMyI6eyJlYXJuZWQiOmZhbHNlfSwiNCI6eyJlYXJuZWQiOmZhbHNlfX19LCJmZXJ0aWxpemVyRWxmVHJhaW5pbmciOnsiZXhwIjowLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjpmYWxzZX0sIjEiOnsiZWFybmVkIjpmYWxzZX0sIjIiOnsiZWFybmVkIjpmYWxzZX0sIjMiOnsiZWFybmVkIjpmYWxzZX0sIjQiOnsiZWFybmVkIjpmYWxzZX19fSwiaGVhdGVkQ3V0dGVyRWxmVHJhaW5pbmciOnsiZXhwIjowLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjpmYWxzZX0sIjEiOnsiZWFybmVkIjpmYWxzZX0sIjIiOnsiZWFybmVkIjpmYWxzZX0sIjMiOnsiZWFybmVkIjpmYWxzZX0sIjQiOnsiZWFybmVkIjpmYWxzZX19fSwiaGVhdGVkUGxhbnRlckVsZlRyYWluaW5nIjp7ImV4cCI6MCwibWlsZXN0b25lcyI6eyIwIjp7ImVhcm5lZCI6ZmFsc2V9LCIxIjp7ImVhcm5lZCI6ZmFsc2V9LCIyIjp7ImVhcm5lZCI6ZmFsc2V9LCIzIjp7ImVhcm5lZCI6ZmFsc2V9LCI0Ijp7ImVhcm5lZCI6ZmFsc2V9fX0sImhlYXZ5RHJpbGxFbGZUcmFpbmluZyI6eyJleHAiOjAsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOmZhbHNlfSwiMSI6eyJlYXJuZWQiOmZhbHNlfSwiMiI6eyJlYXJuZWQiOmZhbHNlfSwiMyI6eyJlYXJuZWQiOmZhbHNlfSwiNCI6eyJlYXJuZWQiOmZhbHNlfX19LCJraWxuRWxmVHJhaW5pbmciOnsiZXhwIjowLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjpmYWxzZX0sIjEiOnsiZWFybmVkIjpmYWxzZX0sIjIiOnsiZWFybmVkIjpmYWxzZX0sIjMiOnsiZWFybmVkIjpmYWxzZX0sIjQiOnsiZWFybmVkIjpmYWxzZX19fSwibWV0YWxFbGZUcmFpbmluZyI6eyJleHAiOjAsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOmZhbHNlfSwiMSI6eyJlYXJuZWQiOmZhbHNlfSwiMiI6eyJlYXJuZWQiOmZhbHNlfSwiMyI6eyJlYXJuZWQiOmZhbHNlfSwiNCI6eyJlYXJuZWQiOmZhbHNlfX19LCJvaWxFbGZUcmFpbmluZyI6eyJleHAiOjAsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOmZhbHNlfSwiMSI6eyJlYXJuZWQiOmZhbHNlfSwiMiI6eyJlYXJuZWQiOmZhbHNlfSwiMyI6eyJlYXJuZWQiOmZhbHNlfSwiNCI6eyJlYXJuZWQiOmZhbHNlfX19LCJwYXBlckVsZlRyYWluaW5nIjp7ImV4cCI6MCwibWlsZXN0b25lcyI6eyIwIjp7ImVhcm5lZCI6ZmFsc2V9LCIxIjp7ImVhcm5lZCI6ZmFsc2V9LCIyIjp7ImVhcm5lZCI6ZmFsc2V9LCIzIjp7ImVhcm5lZCI6ZmFsc2V9LCI0Ijp7ImVhcm5lZCI6ZmFsc2V9fX0sInBsYW50ZXJFbGZUcmFpbmluZyI6eyJleHAiOjAsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOmZhbHNlfSwiMSI6eyJlYXJuZWQiOmZhbHNlfSwiMiI6eyJlYXJuZWQiOmZhbHNlfSwiMyI6eyJlYXJuZWQiOmZhbHNlfSwiNCI6eyJlYXJuZWQiOmZhbHNlfX19LCJzbWFsbGZpcmVFbGZUcmFpbmluZyI6eyJleHAiOjAsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOmZhbHNlfSwiMSI6eyJlYXJuZWQiOmZhbHNlfSwiMiI6eyJlYXJuZWQiOmZhbHNlfSwiMyI6eyJlYXJuZWQiOmZhbHNlfSwiNCI6eyJlYXJuZWQiOmZhbHNlfX19LCJkeWVFbGZUcmFpbmluZyI6eyJleHAiOjAsIm1pbGVzdG9uZXMiOnsiMCI6eyJlYXJuZWQiOmZhbHNlfSwiMSI6eyJlYXJuZWQiOmZhbHNlfSwiMiI6eyJlYXJuZWQiOmZhbHNlfSwiMyI6eyJlYXJuZWQiOmZhbHNlfSwiNCI6eyJlYXJuZWQiOmZhbHNlfX19LCJwbGFzdGljRWxmVHJhaW5pbmciOnsiZXhwIjowLCJtaWxlc3RvbmVzIjp7IjAiOnsiZWFybmVkIjpmYWxzZX0sIjEiOnsiZWFybmVkIjpmYWxzZX0sIjIiOnsiZWFybmVkIjpmYWxzZX0sIjMiOnsiZWFybmVkIjpmYWxzZX0sIjQiOnsiZWFybmVkIjpmYWxzZX19fX0sInRlYWNoaW5nIjp7ImJvdWdodCI6ZmFsc2V9LCJzY2hvb2xzIjp7ImFtb3VudCI6MH0sImNsYXNzcm9vbXMiOnsiYW1vdW50IjowfSwiY2xhc3Nyb29tVXBncmFkZSI6eyJib3VnaHQiOmZhbHNlfSwiYWR2YW5jZWRVcGdyYWRlIjp7ImJvdWdodCI6ZmFsc2V9LCJ1cGdyYWRlcyI6eyIwIjp7ImJvdWdodCI6ZmFsc2V9LCIxIjp7ImJvdWdodCI6ZmFsc2V9LCIyIjp7ImJvdWdodCI6ZmFsc2V9fSwidXBncmFkZXMyIjp7IjAiOnsiYm91Z2h0IjpmYWxzZX0sIjEiOnsiYm91Z2h0IjpmYWxzZX0sIjIiOnsiYm91Z2h0IjpmYWxzZX19LCJmb2N1c011bHRpIjoiMS4wMTI2OTg0NzU0MjAxMTg3IiwiZm9jdXNUYXJnZXRzIjp7fSwiZm9jdXNDb29sZG93biI6MCwiZm9jdXNUaW1lIjowfX0sIndyYXBwaW5nUGFwZXIiOnsibWluaW1pemVkIjpmYWxzZSwid3JhcHBpbmdQYXBlciI6eyJjaHJpc3RtYXMiOnsiYnV5YWJsZSI6eyJhbW91bnQiOiI2NyJ9fSwicmFpbmJvdyI6eyJidXlhYmxlIjp7ImFtb3VudCI6IjQ4In19LCJqYXp6eSI6eyJidXlhYmxlIjp7ImFtb3VudCI6IjgzIn19LCJzdW5zaGluZSI6eyJidXlhYmxlIjp7ImFtb3VudCI6IjU3In19LCJvY2VhbiI6eyJidXlhYmxlIjp7ImFtb3VudCI6IjUyIn19LCJiZWFjaCI6eyJidXlhYmxlIjp7ImFtb3VudCI6IjU5In19fSwiZ2VuZXJhbFRhYkNvbGxhcHNlZCI6e30sIm1pbGVzdG9uZXMiOnsicHJpbWFyeUJvb3N0Ijp7ImVhcm5lZCI6ZmFsc2V9LCJzZWNvbmRhcnlCb29zdCI6eyJlYXJuZWQiOmZhbHNlfSwiYnV5TWF4UHJpbWFyeSI6eyJlYXJuZWQiOmZhbHNlfSwic2Vjb25kYXJ5Tm9SZXNldCI6eyJlYXJuZWQiOmZhbHNlfSwiYnV5TWF4U2Vjb25kYXJ5Ijp7ImVhcm5lZCI6ZmFsc2V9LCJ1bmxvY2tEeWVFbGYiOnsiZWFybmVkIjpmYWxzZX19LCJjb2xsYXBzZU1pbGVzdG9uZXMiOnRydWUsInVubG9ja0R5ZUVsZk1pbGVzdG9uZSI6eyJlYXJuZWQiOnRydWV9fSwibGV0dGVycyI6eyJtaW5pbWl6ZWQiOmZhbHNlLCJsZXR0ZXJzIjoiMS4zMDk0ODU0MTMwNTI2MzI2ZTU0IiwidG90YWxMZXR0ZXJzIjoiNi41NDc0MjcwNjUyNjMxNjNlNTQiLCJwcm9jZXNzaW5nUHJvZ3Jlc3MiOiIyLjc5MTQ5MzU1NjEwNTI3NTZlLTI4IiwiYnV5YWJsZXMiOnsibWV0YWxCdXlhYmxlIjp7ImFtb3VudCI6IjEyIn0sInBsYXN0aWNCdXlhYmxlIjp7ImFtb3VudCI6IjIzIn0sInBhcGVyQnV5YWJsZSI6eyJhbW91bnQiOiI0MyJ9fSwibWlsZXN0b25lcyI6eyJhdXRvU21lbHRpbmdNaWxlc3RvbmUiOnsiZWFybmVkIjp0cnVlfSwibWluaW5nTWlsZXN0b25lIjp7ImVhcm5lZCI6dHJ1ZX0sInN5bmVyZ3lNaWxlc3RvbmUiOnsiZWFybmVkIjp0cnVlfSwiaW5kdXN0cmlhbENydWNpYmxlTWlsZXN0b25lIjp7ImVhcm5lZCI6dHJ1ZX19LCJnZW5lcmFsVGFiQ29sbGFwc2VkIjp7fSwiY29sbGFwc2VNaWxlc3RvbmVzIjp0cnVlLCJtYXN0ZXJ5Ijp7ImxldHRlcnMiOiIxMjU1ODAwNS41NzE1MTA4NSIsInRvdGFsTGV0dGVycyI6IjEyNTU4MDA1LjU3MTUxMDg1IiwiYnV5YWJsZXMiOnsibWV0YWxCdXlhYmxlIjp7ImFtb3VudCI6MH0sInBsYXN0aWNCdXlhYmxlIjp7ImFtb3VudCI6MH0sInBhcGVyQnV5YWJsZSI6eyJhbW91bnQiOjB9fSwibWlsZXN0b25lcyI6eyJhdXRvU21lbHRpbmdNaWxlc3RvbmUiOnsiZWFybmVkIjp0cnVlfSwibWluaW5nTWlsZXN0b25lIjp7ImVhcm5lZCI6dHJ1ZX0sInN5bmVyZ3lNaWxlc3RvbmUiOnsiZWFybmVkIjp0cnVlfSwiaW5kdXN0cmlhbENydWNpYmxlTWlsZXN0b25lIjp7ImVhcm5lZCI6dHJ1ZX19fSwibWFzdGVyZWQiOnRydWV9LCJyaWJib24iOnsibWluaW1pemVkIjpmYWxzZSwicmliYm9uIjoiMTYiLCJtaWxlc3RvbmVzIjp7InNlY29uZGFyeUR5ZUVsZiI6eyJlYXJuZWQiOnRydWV9LCJkeWVCb29rIjp7ImVhcm5lZCI6dHJ1ZX19LCJyaWJib25Qcm9ncmVzcyI6MTAsImNvbGxhcHNlTWlsZXN0b25lcyI6dHJ1ZSwiZ2VuZXJhbFRhYkNvbGxhcHNlZCI6e319LCJ0b3lzIjp7Im1pbmltaXplZCI6ZmFsc2UsImNsb3RoZXMiOiIxNTAwIiwid29vZGVuQmxvY2tzIjoiMjYzMS4wMDAwMDAwMDAwMDEiLCJ0cnVja3MiOiIyMTcwLjgxOTIiLCJ0b3RhbFRveXMiOiIyOTExNyIsImJ1eWFibGVzIjp7IjAiOnsiYW1vdW50IjoiMzQxIn0sIjEiOnsiYW1vdW50IjoiMS4wMDAwMDAwMDAwMDAwMTQyIn0sIjIiOnsiYW1vdW50IjoiMzc3In19LCJyb3cxVXBncmFkZXMiOnsiMCI6eyJib3VnaHQiOnRydWV9LCIxIjp7ImJvdWdodCI6dHJ1ZX0sIjIiOnsiYm91Z2h0Ijp0cnVlfX0sIm1pbGVzdG9uZXMiOnsibWlsZXN0b25lMSI6eyJlYXJuZWQiOnRydWV9LCJtaWxlc3RvbmUyIjp7ImVhcm5lZCI6dHJ1ZX0sIm1pbGVzdG9uZTMiOnsiZWFybmVkIjp0cnVlfSwibWlsZXN0b25lNCI6eyJlYXJuZWQiOnRydWV9LCJtaWxlc3RvbmU1Ijp7ImVhcm5lZCI6dHJ1ZX0sIm1pbGVzdG9uZTYiOnsiZWFybmVkIjp0cnVlfSwibWlsZXN0b25lNyI6eyJlYXJuZWQiOnRydWV9LCJtaWxlc3RvbmU4Ijp7ImVhcm5lZCI6dHJ1ZX19LCJnZW5lcmFsVGFiQ29sbGFwc2VkIjp7fSwiY29sbGFwc2VNaWxlc3RvbmVzIjpmYWxzZX0sImZhY3RvcnkiOnsibWluaW1pemVkIjpmYWxzZSwiY29tcG9uZW50cyI6eyItNXgtNSI6eyJ0aWNrc0RvbmUiOjEuMzE5NzY0MjYwNTU2NzA3NSwiZGlyZWN0aW9uIjoiTEVGVCIsIm91dHB1dFN0b2NrIjp7ImNsb3RoIjowfSwidHlwZSI6ImNsb3RoIn0sIi01eC00Ijp7InRpY2tzRG9uZSI6MC43ODE0OTg5MDEyNDU2NTUyLCJkaXJlY3Rpb24iOiJVUCIsIm91dHB1dFN0b2NrIjp7ImNsb3RoIjowfSwidHlwZSI6ImNsb3RoIn0sIi0zeC01Ijp7InRpY2tzRG9uZSI6MS4zMTk0MzA0ODkwNTkxNDg4LCJkaXJlY3Rpb24iOiJVUCIsImlucHV0U3RvY2siOnsiY2xvdGgiOjUwfSwib3V0cHV0U3RvY2siOnsidGhyZWFkIjowfSwidHlwZSI6InRocmVhZCJ9LCItM3gtNCI6eyJ0aWNrc0RvbmUiOjAuNzgwNTM5OTQxODM2OCwiZGlyZWN0aW9uIjoiTEVGVCIsImlucHV0U3RvY2siOnsiY2xvdGgiOjUwLCJwbGFzdGljIjoxNX0sIm91dHB1dFN0b2NrIjp7InN0dWZmaW5nIjowfSwidHlwZSI6InN0dWZmaW5nIn0sIi00eC01Ijp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiUklHSFQiLCJ0eXBlIjoiY29udmV5b3IifSwiLTR4LTQiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJSSUdIVCIsInR5cGUiOiJjb252ZXlvciJ9LCIxeC01Ijp7InRpY2tzRG9uZSI6Mi40NTExMTA2MzU3NTEzNTIsImRpcmVjdGlvbiI6IlVQIiwiaW5wdXRTdG9jayI6eyJwbGFzdGljIjowLCJ0aHJlYWQiOjQ4fSwib3V0cHV0U3RvY2siOnsiYnV0dG9ucyI6MH0sInR5cGUiOiJidXR0b24ifSwiMXgtNCI6eyJ0aWNrc0RvbmUiOjAuODUwMTIwMjk2ODc1ODA3NywiZGlyZWN0aW9uIjoiUklHSFQiLCJpbnB1dFN0b2NrIjp7InBsYXN0aWMiOjF9LCJvdXRwdXRTdG9jayI6eyJidXR0b25zIjoxfSwidHlwZSI6ImJ1dHRvbiJ9LCIzeC01Ijp7InRpY2tzRG9uZSI6MC40NDEyNTY1ODg1MDk4NzU4LCJkaXJlY3Rpb24iOiJVUCIsIm91dHB1dFN0b2NrIjp7InBsYXN0aWMiOjEwMzM1fSwidHlwZSI6InBsYXN0aWMifSwiMngtNSI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IkxFRlQiLCJ0eXBlIjoiY29udmV5b3IifSwiM3gtNCI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IkRPV04iLCJ0eXBlIjoiY29udmV5b3IifSwiM3gtMyI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IkxFRlQiLCJ0eXBlIjoiY29udmV5b3IifSwiMngtMyI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IkxFRlQiLCJ0eXBlIjoiY29udmV5b3IifSwiMXgtMyI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IlVQIiwidHlwZSI6ImNvbnZleW9yIn0sIi0xeC00Ijp7InRpY2tzRG9uZSI6MC43ODIxNzk3NTc0MTMyMTc5LCJkaXJlY3Rpb24iOiJMRUZUIiwiaW5wdXRTdG9jayI6eyJ0aHJlYWQiOjQ5NCwic3R1ZmZpbmciOjU3OSwiZHllIjo0ODIyLCJidXR0b25zIjo0MTR9LCJvdXRwdXRTdG9jayI6eyJiZWFyIjowfSwidHlwZSI6ImJlYXIifSwiLTJ4LTQiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJSSUdIVCIsInR5cGUiOiJjb252ZXlvciJ9LCItMngtNSI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IlJJR0hUIiwidHlwZSI6ImNvbnZleW9yIn0sIjB4LTUiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJMRUZUIiwidHlwZSI6ImNvbnZleW9yIn0sIjB4LTQiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJMRUZUIiwidHlwZSI6ImNvbnZleW9yIn0sIi0xeC01Ijp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiRE9XTiIsInR5cGUiOiJjb252ZXlvciJ9LCItMXgtMiI6eyJ0aWNrc0RvbmUiOjAuNDM5NjY0Mjg5MTk3MTM5ODUsImRpcmVjdGlvbiI6IkRPV04iLCJvdXRwdXRTdG9jayI6eyJkeWUiOjk2Mzh9LCJ0eXBlIjoiZHllIn0sIi0xeC0zIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiVVAiLCJ0eXBlIjoiY29udmV5b3IifSwiNHgtNSI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IlJJR0hUIiwidHlwZSI6ImNvbnZleW9yIn0sIjV4LTIiOnsidGlja3NEb25lIjoxLjgwMjYwODk3MTg5ODg4MzEsImRpcmVjdGlvbiI6IkRPV04iLCJpbnB1dFN0b2NrIjp7InBsYXN0aWMiOjF9LCJvdXRwdXRTdG9jayI6eyJidWNrZXQiOjB9LCJ0eXBlIjoiYnVja2V0In0sIjV4LTUiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJET1dOIiwidHlwZSI6ImNvbnZleW9yIn0sIjV4LTQiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJET1dOIiwidHlwZSI6ImNvbnZleW9yIn0sIjV4LTMiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJET1dOIiwidHlwZSI6ImNvbnZleW9yIn0sIjV4MCI6eyJ0aWNrc0RvbmUiOjAuNzQzMzU1NzU0MjEyODU5NywiZGlyZWN0aW9uIjoiRE9XTiIsIm91dHB1dFN0b2NrIjp7InBsYXN0aWMiOjc5MDF9LCJ0eXBlIjoicGxhc3RpYyJ9LCIzeDAiOnsidGlja3NEb25lIjowLjA4ODY4ODI2ODIwOTA5MjE1LCJkaXJlY3Rpb24iOiJMRUZUIiwiaW5wdXRTdG9jayI6eyJwbGFzdGljIjowfSwib3V0cHV0U3RvY2siOnsic2hvdmVsIjowfSwidHlwZSI6InNob3ZlbCJ9LCI0eDAiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJMRUZUIiwidHlwZSI6ImNvbnZleW9yIn0sIjV4LTEiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJVUCIsInR5cGUiOiJjb252ZXlvciJ9LCI0eC0yIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiTEVGVCIsInR5cGUiOiJjb252ZXlvciJ9LCIzeC0xIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiVVAiLCJ0eXBlIjoiY29udmV5b3IifSwiM3gtMiI6eyJ0aWNrc0RvbmUiOjIuMTAyNjIzMzI0MTA3NjA3LCJkaXJlY3Rpb24iOiJMRUZUIiwiaW5wdXRTdG9jayI6eyJidWNrZXQiOjI0Nywic2hvdmVsIjowfSwib3V0cHV0U3RvY2siOnsic2hvdmVsQnVja2V0IjowfSwidHlwZSI6ImJ1Y2tldFNob3ZlbCJ9LCItM3gtMSI6eyJ0aWNrc0RvbmUiOjAuNDY5NTI0MDc2NTcwODY2MTQsImRpcmVjdGlvbiI6IlJJR0hUIiwib3V0cHV0U3RvY2siOnsicGxhc3RpYyI6NzI2Nn0sInR5cGUiOiJwbGFzdGljIn0sIi0xeC0xIjp7InRpY2tzRG9uZSI6MS43NzA3Mzg1NTA2NTcwNTYzLCJkaXJlY3Rpb24iOiJSSUdIVCIsImlucHV0U3RvY2siOnsibWV0YWwiOjE0NzgsInBsYXN0aWMiOjB9LCJvdXRwdXRTdG9jayI6eyJjaXJjdWl0Qm9hcmQiOjB9LCJ0eXBlIjoiY2lyY3VpdEJvYXJkIn0sIjF4LTEiOnsidGlja3NEb25lIjoxLjMxMDI0NjQzMDM4NDcyMDYsImRpcmVjdGlvbiI6IlJJR0hUIiwib3V0cHV0U3RvY2siOnsibWV0YWwiOjB9LCJ0eXBlIjoibWV0YWwifSwiLTF4MSI6eyJ0aWNrc0RvbmUiOjEuMTgyODg1MDk1NTg2MjM1LCJkaXJlY3Rpb24iOiJSSUdIVCIsImlucHV0U3RvY2siOnsibWV0YWwiOjEwNTEsInBsYXN0aWMiOjIsImNpcmN1aXRCb2FyZCI6MTI2MH0sIm91dHB1dFN0b2NrIjp7ImNvbnNvbGUiOjB9LCJ0eXBlIjoiY29uc29sZSJ9LCItMngtMSI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IlJJR0hUIiwidHlwZSI6ImNvbnZleW9yIn0sIi0zeC0yIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiVVAiLCJ0eXBlIjoiY29udmV5b3IifSwiLTN4LTMiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJMRUZUIiwidHlwZSI6ImNvbnZleW9yIn0sIi00eC0zIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiRE9XTiIsInR5cGUiOiJjb252ZXlvciJ9LCItNHgtMiI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IkRPV04iLCJ0eXBlIjoiY29udmV5b3IifSwiLTR4LTEiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJMRUZUIiwidHlwZSI6ImNvbnZleW9yIn0sIi01eC0xIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiRE9XTiIsInR5cGUiOiJjb252ZXlvciJ9LCItNXgwIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiUklHSFQiLCJ0eXBlIjoiY29udmV5b3IifSwiLTR4MCI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IlJJR0hUIiwidHlwZSI6ImNvbnZleW9yIn0sIi0zeDAiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJSSUdIVCIsInR5cGUiOiJjb252ZXlvciJ9LCItMngwIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiUklHSFQiLCJ0eXBlIjoiY29udmV5b3IifSwiLTF4MCI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IkRPV04iLCJ0eXBlIjoiY29udmV5b3IifSwiMHgtMSI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IkxFRlQiLCJ0eXBlIjoiY29udmV5b3IifSwiMHgwIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiTEVGVCIsInR5cGUiOiJjb252ZXlvciJ9LCIxeDAiOnsidGlja3NEb25lIjowLjc0NTMzODg0NzA1NDcyMTEsImRpcmVjdGlvbiI6IlVQIiwib3V0cHV0U3RvY2siOnsibWV0YWwiOjB9LCJ0eXBlIjoibWV0YWwifSwiLTV4MyI6eyJ0aWNrc0RvbmUiOjAuNzc5NzI4MDkzNTA3NjkyOSwiZGlyZWN0aW9uIjoiVVAiLCJvdXRwdXRTdG9jayI6eyJjbG90aCI6MH0sInR5cGUiOiJjbG90aCJ9LCItNXg0Ijp7InRpY2tzRG9uZSI6MS4zMTc0NjMwNDY3Mjc0NzY2LCJkaXJlY3Rpb24iOiJMRUZUIiwib3V0cHV0U3RvY2siOnsiY2xvdGgiOjB9LCJ0eXBlIjoiY2xvdGgifSwiLTV4NSI6eyJ0aWNrc0RvbmUiOjAuNzc4NjQzNzU2NDc5ODY2MywiZGlyZWN0aW9uIjoiRE9XTiIsIm91dHB1dFN0b2NrIjp7ImNsb3RoIjowfSwidHlwZSI6ImNsb3RoIn0sIi01eDIiOnsidGlja3NEb25lIjoxLjMxNzEzMTc3MTM5MTEzMzUsImRpcmVjdGlvbiI6IkRPV04iLCJvdXRwdXRTdG9jayI6eyJjbG90aCI6MH0sInR5cGUiOiJjbG90aCJ9LCItNXgxIjp7InRpY2tzRG9uZSI6MS4zMDg3MTIyNjM5MjQ2MzEsImRpcmVjdGlvbiI6IlJJR0hUIiwib3V0cHV0U3RvY2siOnsiY2xvdGgiOjB9LCJ0eXBlIjoiY2xvdGgifSwiLTN4NCI6eyJ0aWNrc0RvbmUiOjAuNzQ0NzkwMDg2NzQ4NTg5LCJkaXJlY3Rpb24iOiJMRUZUIiwiaW5wdXRTdG9jayI6eyJjbG90aCI6MzI3fSwib3V0cHV0U3RvY2siOnsidGhyZWFkIjoxNTg0fSwidHlwZSI6InRocmVhZCJ9LCItM3g1Ijp7InRpY2tzRG9uZSI6MC40NzAyNzA0NjE5MDUxOTAwNiwiZGlyZWN0aW9uIjoiRE9XTiIsImlucHV0U3RvY2siOnsiY2xvdGgiOjE3MH0sIm91dHB1dFN0b2NrIjp7InRocmVhZCI6MH0sInR5cGUiOiJ0aHJlYWQifSwiLTF4NSI6eyJ0aWNrc0RvbmUiOjAuNzg2OTUwMDAxOTgzMTIwNiwiZGlyZWN0aW9uIjoiVVAiLCJpbnB1dFN0b2NrIjp7InRocmVhZCI6MywiY2xvdGgiOjE4NzIsImR5ZSI6MjI2OH0sIm91dHB1dFN0b2NrIjp7ImNsb3RoZXMiOjB9LCJ0eXBlIjoiY2xvdGhlcyJ9LCItMngxIjp7InRpY2tzRG9uZSI6MC43ODM0MjQyNzcyNjk3MzQ2LCJkaXJlY3Rpb24iOiJMRUZUIiwib3V0cHV0U3RvY2siOnsiZHllIjozODA2fSwidHlwZSI6ImR5ZSJ9LCItNHg1Ijp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiUklHSFQiLCJ0eXBlIjoiY29udmV5b3IifSwiLTJ4NSI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IlJJR0hUIiwidHlwZSI6ImNvbnZleW9yIn0sIi00eDQiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJSSUdIVCIsInR5cGUiOiJjb252ZXlvciJ9LCItMng0Ijp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiRE9XTiIsInR5cGUiOiJjb252ZXlvciJ9LCItNHgzIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiUklHSFQiLCJ0eXBlIjoiY29udmV5b3IifSwiLTR4MiI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IlJJR0hUIiwidHlwZSI6ImNvbnZleW9yIn0sIi00eDEiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJSSUdIVCIsInR5cGUiOiJjb252ZXlvciJ9LCItM3gxIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiRE9XTiIsInR5cGUiOiJjb252ZXlvciJ9LCItM3gyIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiRE9XTiIsInR5cGUiOiJjb252ZXlvciJ9LCItM3gzIjp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiUklHSFQiLCJ0eXBlIjoiY29udmV5b3IifSwiLTJ4MiI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IkRPV04iLCJ0eXBlIjoiY29udmV5b3IifSwiLTJ4MyI6eyJ0aWNrc0RvbmUiOjAsImRpcmVjdGlvbiI6IkRPV04iLCJ0eXBlIjoiY29udmV5b3IifSwiM3g1Ijp7InRpY2tzRG9uZSI6MC41NTEwNjI5ODU4Mzk5MTQ4LCJkaXJlY3Rpb24iOiJSSUdIVCIsIm91dHB1dFN0b2NrIjp7ImNsb3RoIjowfSwidHlwZSI6ImNsb3RoIn0sIjF4NSI6eyJ0aWNrc0RvbmUiOjAuNTQyMTYwMDA3OTM5NjQ5MSwiZGlyZWN0aW9uIjoiUklHSFQiLCJpbnB1dFN0b2NrIjp7ImNsb3RoIjo2NX0sIm91dHB1dFN0b2NrIjp7InRocmVhZCI6MH0sInR5cGUiOiJ0aHJlYWQifSwiMHg1Ijp7InRpY2tzRG9uZSI6MCwiZGlyZWN0aW9uIjoiTEVGVCIsInR5cGUiOiJjb252ZXlvciJ9LCIyeDUiOnsidGlja3NEb25lIjowLCJkaXJlY3Rpb24iOiJMRUZUIiwidHlwZSI6ImNvbnZleW9yIn19LCJlbGZCdXlhYmxlcyI6eyJjbG90aGVzQnV5YWJsZSI6eyJhbW91bnQiOiI1In0sImJsb2Nrc0J1eWFibGUiOnsiYW1vdW50IjoiOCJ9LCJ0cnVja3NCdXlhYmxlIjp7ImFtb3VudCI6IjYifSwiYmVhcnNCdXlhYmxlIjp7InJlc291cmNlIjoiODU1OCIsImFtb3VudCI6IjUifSwiYnVja2V0QnV5YWJsZSI6eyJyZXNvdXJjZSI6IjMxMjAiLCJhbW91bnQiOiI0In0sImNvbnNvbGVzQnV5YWJsZSI6eyJyZXNvdXJjZSI6IjI3ODEiLCJhbW91bnQiOiI0In19LCJ0YWJzIjp7InNlbGVjdGVkIjoiZGFzaGJvYXJkIn0sImdlbmVyYWxUYWJDb2xsYXBzZWQiOnt9LCJiZWFycyI6Ijg1NTgiLCJidWNrZXRBbmRTaG92ZWxzIjoiMzEyMCIsImNvbnNvbGVzIjoiMjc4MSIsImZhY3RvcnlCdXlhYmxlcyI6eyJleHBhbmRGYWN0b3J5Ijp7ImFtb3VudCI6IjQifSwib2lsRnVlbCI6eyJhbW91bnQiOiIyIn0sImNhcnJ5VG95cyI6eyJhbW91bnQiOiI0In19LCJ1cGdyYWRlcyI6eyIwIjp7IjAiOnsiYm91Z2h0Ijp0cnVlfSwiMSI6eyJib3VnaHQiOnRydWV9LCIyIjp7ImJvdWdodCI6dHJ1ZX0sIjMiOnsiYm91Z2h0Ijp0cnVlfX0sIjEiOnsiMCI6eyJib3VnaHQiOnRydWV9LCIxIjp7ImJvdWdodCI6dHJ1ZX0sIjIiOnsiYm91Z2h0Ijp0cnVlfSwiMyI6eyJib3VnaHQiOnRydWV9fSwiMiI6eyIwIjp7ImJvdWdodCI6dHJ1ZX0sIjEiOnsiYm91Z2h0Ijp0cnVlfSwiMiI6eyJib3VnaHQiOnRydWV9LCIzIjp7ImJvdWdodCI6dHJ1ZX19fX19LCJhdXRvUGF1c2UiOnRydWUsInVzaW5nTG9nIjpmYWxzZX0= \ No newline at end of file diff --git a/src/data/layers/boxes.tsx b/src/data/layers/boxes.tsx index 98b8b8b..2abf605 100644 --- a/src/data/layers/boxes.tsx +++ b/src/data/layers/boxes.tsx @@ -28,6 +28,7 @@ import { render, renderGrid } from "util/vue"; import { computed, ComputedRef, ref, unref } from "vue"; import dyes from "./dyes"; import elves, { ElfBuyable } from "./elves"; +import factory from "./factory"; import management from "./management"; import paper from "./paper"; import plastic from "./plastic"; @@ -587,7 +588,36 @@ const layer = createLayer(id, function (this: BaseLayer) { Decimal.add(plasticBoxesBuyable.amount.value, plasticBoxesBuyable.freeLevels.value) ) })) as BoxesBuyable; + const presentBuyable = createBuyable(() => ({ + display: { + title: "Carry presents in boxes", + description: jsx(() => ( + <> + Use boxes to carry presents, boosting its gain +
+
+
Amount: {formatWhole(presentBuyable.amount.value)} boxes
+ + )), + effectDisplay: jsx(() => ( + <>{format(Decimal.div(presentBuyable.amount.value, 10).add(1).pow(2))}x + )), + showAmount: false + }, + resource: noPersist(boxes), + cost() { + return Decimal.pow(2, presentBuyable.amount.value).mul(1e87); + }, + inverseCost(x: DecimalSource) { + const amt = Decimal.div(x, 1e87).log2(); + return Decimal.isNaN(amt) ? Decimal.dZero : amt.floor().max(0); + }, + freeLevels: computed(() => 0), + totalAmount: computed(() => presentBuyable.amount.value), + visibility: () => showIf(factory.upgrades[3][3].bought.value) + })) as BoxesBuyable; const buyables2 = { oreBoxesBuyable, metalBoxesBuyable, plasticBoxesBuyable }; + const buyables3 = { presentBuyable }; globalBus.on("update", diff => { if (Decimal.lt(main.day.value, day)) { return; @@ -677,6 +707,7 @@ const layer = createLayer(id, function (this: BaseLayer) { row3Upgrades, buyables, buyables2, + buyables3, minWidth: 700, generalTabCollapsed, display: jsx(() => ( @@ -703,7 +734,11 @@ const layer = createLayer(id, function (this: BaseLayer) { Object.values(row3Upgrades) )} - {renderGrid(Object.values(buyables), Object.values(buyables2))} + {renderGrid( + Object.values(buyables), + Object.values(buyables2), + Object.values(buyables3) + )} )), minimizedDisplay: jsx(() => ( diff --git a/src/data/layers/elves.tsx b/src/data/layers/elves.tsx index e2ad2d9..47378a4 100644 --- a/src/data/layers/elves.tsx +++ b/src/data/layers/elves.tsx @@ -876,7 +876,11 @@ const layer = createLayer(id, function (this: BaseLayer) { name: "Bell", description: "Bell will automatically purchase all box buyables you can afford, without actually spending any boxes.", - buyable: [...Object.values(boxes.buyables), ...Object.values(boxes.buyables2)], + buyable: [ + ...Object.values(boxes.buyables), + ...Object.values(boxes.buyables2), + ...Object.values(boxes.buyables3) + ], cooldownModifier: boxCooldown, visibility: () => showIf(plastic.elfUpgrades.boxElf.bought.value) }); diff --git a/src/data/layers/factory-components/boxmaker.svg b/src/data/layers/factory-components/boxmaker.svg new file mode 100644 index 0000000..70da472 --- /dev/null +++ b/src/data/layers/factory-components/boxmaker.svg @@ -0,0 +1,123 @@ + + + + \ No newline at end of file diff --git a/src/data/layers/factory.tsx b/src/data/layers/factory.tsx index db463b3..85c0ff9 100644 --- a/src/data/layers/factory.tsx +++ b/src/data/layers/factory.tsx @@ -40,9 +40,11 @@ import _plastic from "../symbols/plastic.png"; import boxes from "./boxes"; import coal from "./coal"; import dyes from "./dyes"; +import _box from "../symbols/cardboardBox.png"; import _bear from "./factory-components/bear.svg"; import _bearMaker from "./factory-components/bearmaker.svg"; import _block from "./factory-components/block.svg"; +import _boxMaker from "./factory-components/boxmaker.svg"; import _blockMaker from "./factory-components/blockmaker.svg"; import _bucket from "./factory-components/bucket.svg"; import _bucketMaker from "./factory-components/bucketmaker.svg"; @@ -75,6 +77,7 @@ import _truck from "./factory-components/truck.svg"; import _truckMaker from "./factory-components/truckmaker.svg"; import _wheel from "./factory-components/wheel.svg"; import _wheelMaker from "./factory-components/wheelmaker.svg"; +import _present from "./factory-components/presentmaker.svg"; import Factory from "./Factory.vue"; import metal from "./metal"; import oil from "./oil"; @@ -94,6 +97,7 @@ const presentsDay = 20; const toyGoal = 750; const advancedToyGoal = 1500; +const presentsGoal = 8e9; // 20x20 block size // TODO: unhardcode stuff @@ -138,6 +142,16 @@ const factory = createLayer(id, () => { const bears = createResource(0, "teddy bears"); const bucketAndShovels = createResource(0, "shovel and pails"); const consoles = createResource(0, "consoles"); + const presents = createResource(0, "presents"); + + const allToys = { + clothes: toys.clothes, + woodenBlocks: toys.woodenBlocks, + trucks: toys.trucks, + bears, + bucketAndShovels, + consoles + }; function getRelativeCoords(e: MouseEvent) { const rect = (e.target as HTMLElement).getBoundingClientRect(); @@ -172,6 +186,11 @@ const factory = createLayer(id, () => { multiplier: 1.4, description: "6000 toys", enabled: toys.milestones.milestone6.earned + })), + createMultiplicativeModifier(() => ({ + multiplier: () => Decimal.log10(trees.logs.value).div(100).add(1), + description: "Burn some logs", + enabled: betterLighting.bought })) ]) as WithRequired; const computedEnergy = computed(() => energy.apply(0)); @@ -227,9 +246,27 @@ const factory = createLayer(id, () => { addend: expandFactory.amount, description: "Expand Factory", enabled: () => Decimal.gt(expandFactory.amount.value, 0) + })), + createAdditiveModifier(() => ({ + addend: 5, + description: "Factory eXPerience", + enabled: betterFactory.bought })) ]); const computedFactorySize = computed(() => new Decimal(factorySize.apply(7)).toNumber()); + const presentMultipliers = createSequentialModifier(() => [ + createMultiplicativeModifier(() => ({ + multiplier: computedToyMultiplier, + description: "Tickspeed overflow", + enabled: () => computedToyMultiplier.value.gt(1) + })), + createMultiplicativeModifier(() => ({ + multiplier: Decimal.div(boxes.buyables3.presentBuyable.amount.value, 10).add(1).pow(2), + description: "Carry boxes in... presents?", + enabled: carryPresents.bought + })) + ]); + const computedPresentMultipliers = computed(() => presentMultipliers.apply(1)); const energyBar = createBar(() => ({ width: 680, @@ -317,6 +354,10 @@ const factory = createLayer(id, () => { return str; } + // this keeps track of which toy the present factory has consumed + // it cycles around, so each toy is used evenly + let toysIndex = 0; + const FACTORY_COMPONENTS = { cursor: { imageSrc: _cursor, @@ -459,6 +500,26 @@ const factory = createLayer(id, () => { plank: { amount: computed(() => (upgrades[0][0].bought.value ? 2 : 1)) } + }, + visible: main.days[presentsDay - 1].opened + } as FactoryComponentDeclaration, + boxMaker: { + imageSrc: _boxMaker, + key: "ctrl+8", + name: "Box Maker", + type: "processor", + description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.boxMaker)), + energyCost: 3, + tick: 1, + inputs: { + plank: { + amount: 2 + } + }, + outputs: { + box: { + amount: 2 + } } } as FactoryComponentDeclaration, thread: { @@ -755,6 +816,57 @@ const factory = createLayer(id, () => { } }, visible: main.days[advancedDay - 1].opened + } as FactoryComponentDeclaration, + present: { + imageSrc: _present, + type: "processor", + // idk about this + key: "ctrl+7", + name: "Present Wrapper", + description: computed( + () => + `Takes in 4 dye, 4 plastic, 1 cloth, 2 boxes, and ${formatWhole( + computedToyMultiplier.value + )} toys of any type (from storage) to produce ${formatWhole( + computedPresentMultipliers.value + )} presents every tick.` + ), + tick: 1, + energyCost: 20, + inputs: { + dye: { + amount: 4 + }, + plastic: { + amount: 4 + }, + cloth: { + amount: 1 + }, + box: { + amount: 2 + } + }, + canProduce: computed(() => { + return Object.values(allToys).some(i => + Decimal.gte(i.value, computedToyMultiplier.value) + ); + }), + onProduce(times, stock) { + const value = Object.values(allToys); + + while (times > 0) { + while (Decimal.lt(value[toysIndex].value, computedToyMultiplier.value)) { + toysIndex = (toysIndex + 1) % value.length; + } + const toyToPick = Object.values(allToys)[toysIndex]; + toysIndex = (toysIndex + 1) % value.length; + toyToPick.value = Decimal.sub(toyToPick.value, computedToyMultiplier.value); + times--; + presents.value = Decimal.add(presents.value, computedPresentMultipliers.value); + } + }, + visible: main.days[presentsDay - 1].opened } as FactoryComponentDeclaration } as Record; const RESOURCES = { @@ -784,6 +896,10 @@ const factory = createLayer(id, () => { name: "Planks", imageSrc: _plank }, + box: { + name: "Boxes", + imageSrc: _box + }, thread: { name: "Thread", imageSrc: _thread @@ -903,7 +1019,7 @@ const factory = createLayer(id, () => { outputs?: Stock; /** on produce, do something */ - onProduce?: (times: number) => void; + onProduce?: (times: number, stock: Stock | undefined) => void; /** can it produce? (in addtion to the stock check) */ canProduce?: ComputedRef; } @@ -956,10 +1072,21 @@ const factory = createLayer(id, () => { // trained elves + const costCheapener = createSequentialModifier(() => [ + createMultiplicativeModifier(() => ({ + multiplier: () => Decimal.add(presents.value, 1).log10().add(1), + description: "Excitment Upgrade", + enabled: excitmentUpgrade.bought + })) + ]); + const computedCostCheapeners = computed(() => costCheapener.apply(1)); + const clothesBuyable = createBuyable(() => ({ resource: toys.clothes, cost() { - return Decimal.pow(2, Decimal.add(this.amount.value, 5)); + return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div( + computedCostCheapeners.value + ); }, display: { title: "Train elves to make clothes", @@ -970,7 +1097,9 @@ const factory = createLayer(id, () => { const blocksBuyable = createBuyable(() => ({ resource: toys.woodenBlocks, cost() { - return Decimal.pow(2, Decimal.add(this.amount.value, 5)); + return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div( + computedCostCheapeners.value + ); }, display: { title: "Train elves to make wooden blocks", @@ -981,7 +1110,9 @@ const factory = createLayer(id, () => { const trucksBuyable = createBuyable(() => ({ resource: toys.trucks, cost() { - return Decimal.pow(2, Decimal.add(this.amount.value, 5)); + return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div( + computedCostCheapeners.value + ); }, display: { title: "Train elves to make toy trucks", @@ -992,7 +1123,9 @@ const factory = createLayer(id, () => { const bearsBuyable = createBuyable(() => ({ resource: noPersist(bears), cost() { - return Decimal.pow(2, Decimal.add(this.amount.value, 5)); + return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div( + computedCostCheapeners.value + ); }, display: { title: "Train elves to make bears", @@ -1004,7 +1137,9 @@ const factory = createLayer(id, () => { const bucketBuyable = createBuyable(() => ({ resource: noPersist(bucketAndShovels), cost() { - return Decimal.pow(2, Decimal.add(this.amount.value, 5)); + return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div( + computedCostCheapeners.value + ); }, display: { title: "Train elves to make shovel and pails", @@ -1016,7 +1151,9 @@ const factory = createLayer(id, () => { const consolesBuyable = createBuyable(() => ({ resource: noPersist(consoles), cost() { - return Decimal.pow(2, Decimal.add(this.amount.value, 5)); + return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div( + computedCostCheapeners.value + ); }, display: { title: "Train elves to make consoles", @@ -1089,7 +1226,63 @@ const factory = createLayer(id, () => { style: "width: 200px", visibility: () => showIf(main.days[advancedDay - 1].opened.value) })) as GenericBuyable; - const factoryBuyables = { expandFactory, oilFuel, carryToys }; + + const betterFactory = createUpgrade(() => ({ + resource: noPersist(presents), + cost: 100, + display: { + title: "Factory eXPerience", + description: "Factory size is increased by 5." + }, + visibility: () => showIf(main.days[presentsDay - 1].opened.value) + })); + const betterLighting = createUpgrade(() => ({ + resource: noPersist(presents), + cost: 300, + display: { + title: "Burn some logs", + description: "More energy needed? Let's burn some logs! Logs boosts maximum energy.", + effectDisplay: jsx(() => ( + <>x{format(Decimal.log10(trees.logs.value).div(100).add(1))} + )) + }, + visibility: () => showIf(betterFactory.bought.value) + })); + const excitmentUpgrade = createUpgrade(() => ({ + resource: noPersist(presents), + cost: 1000, + display: { + title: "Faster Elf Training", + description: + "Apparently elves like presents. Let's use it to train them to work on the factory faster! Presents divides the requirement for factory elf training.", + effectDisplay: jsx(() => <>/{format(Decimal.add(presents.value, 1).log10().add(1))}) + }, + visibility: () => showIf(betterLighting.bought.value) + })); + const carryPresents = createUpgrade(() => ({ + resource: noPersist(presents), + cost: 5000, + display: { + title: "Carrying more stuff in boxes", + description: + "Boxes seem really useful for carrying stuff. Why don't we use them to carry presents as well? Unlocks 2 new rebuyables (one of them is in the boxes layer)." + } + })); + const carryBoxes = createBuyable(() => ({ + resource: noPersist(presents), + cost() { + return Decimal.add(carryBoxes.amount.value, 1).pow(1.5) + .mul(Decimal.pow(2, carryBoxes.amount.value)) + .mul(1000); + }, + display: { + title: "Carry boxes in... presents?", + description: + "Presents are made out of boxes, so shouldn't they be able to hold boxes as well? Apparently it makes the boxes more durable. Each level multiplies boxes gain by 1.5.", + effectDisplay: jsx(() => <>x{format(Decimal.pow(1.5, carryBoxes.amount.value))}) + } + })) as GenericBuyable; + const factoryBuyables = { expandFactory, oilFuel, carryToys, carryBoxes }; const upgrades = [ [ createUpgrade(() => ({ @@ -1205,7 +1398,8 @@ const factory = createLayer(id, () => { }, visibility: () => showIf(main.days[advancedDay - 1].opened.value) })) - ] + ], + [betterFactory, betterLighting, excitmentUpgrade, carryPresents] ]; // pixi @@ -1378,7 +1572,7 @@ const factory = createLayer(id, () => { if (data.ticksDone >= factoryData.tick) { if (compData.canProduce.value) { const cyclesDone = Math.floor(data.ticksDone / factoryData.tick); - factoryData.onProduce?.(cyclesDone); + factoryData.onProduce?.(cyclesDone, factoryData.inputs); if (factoryData.inputs !== undefined) { if (data.inputStock === undefined) data.inputStock = {}; for (const [key, val] of Object.entries(factoryData.inputs)) { @@ -1825,6 +2019,20 @@ const factory = createLayer(id, () => { function togglePaused() { paused.value = !paused.value; } + function handleDrag(drag: DragEvent, name: FactoryCompNames) { + drag.dataTransfer!.setData("name", name); + } + function handleDrop(drag: DragEvent) { + drag.preventDefault(); + const { tx, ty } = spriteContainer.localTransform; + let { x, y } = getRelativeCoords(drag); + x = roundDownTo(x - tx, blockSize) / blockSize; + y = roundDownTo(y - ty, blockSize) / blockSize; + const name = drag.dataTransfer!.getData("name"); + if (components.value[x + "x" + y] == null) { + addFactoryComp(x, y, { type: name }); + } + } // ------------------------------------------------------------------------------- Tabs @@ -1850,6 +2058,8 @@ const factory = createLayer(id, () => { src={item.imageSrc} class={{ selected: compSelected.value === key }} onClick={() => onCompClick(key)} + draggable="true" + onDragstart={drag => handleDrag(drag, key)} /> {item.extraImage == null ? null : ( @@ -2002,6 +2212,8 @@ const factory = createLayer(id, () => { ? `Reach ${format( advancedToyGoal )} for each toy to complete the day` + : main.day.value === presentsDay + ? `Reach ${format(presentsGoal)} presents` : `${name} Complete!`}{" "} -{" "}