From 5a9e41351cc7aabcdbb8fdd52c2ac298e53b45fa Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 27 Jun 2024 09:53:42 -0700 Subject: [PATCH 01/54] quick button entrance animation --- src/buttons.js | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/buttons.js b/src/buttons.js index b604220c..2551d48f 100644 --- a/src/buttons.js +++ b/src/buttons.js @@ -24,6 +24,22 @@ export const Buttons = { button = this.buttons[key] } button.visible = true + const justEntered = button.lastVisibleFrame !== this.p5Frames - 1 + if (justEntered) { + button.visibleForFrames = 0 + } + button.visibleForFrames++ + button.lastVisibleFrame = this.p5Frames + + const entranceTime = 0.2 // seconds + + // animate in button when it is visible + const scale = Math.min( + 1, + button.visibleForFrames / (entranceTime * this.P5_FPS) + ) + const scaledWidth = width * scale + const scaledHeight = height * scale p.push() p.noStroke() @@ -31,15 +47,23 @@ export const Buttons = { p.strokeWeight(button.active ? 1 : 4) p.fill(bg) - p.rect(x, y, width, height, height / 2) + p.rect( + x + width / 2 - scaledWidth / 2, + y + height / 2 - scaledHeight / 2, + scaledWidth, + scaledHeight, + height / 2 + ) if (button.hover) { p.fill(fgHover) p.rect(x, y, width, height, height / 2) } - p.fill(fg) - p.textAlign(p.CENTER, p.CENTER) - p.text(text, x + width / 2, y + height / 2 + textSize * 0.05) + if (scale === 1) { + p.fill(fg) + p.textAlign(p.CENTER, p.CENTER) + p.text(text, x + width / 2, y + height / 2 + textSize * 0.05) + } p.pop() }, From a4d8f921981f596a9315c101b8afb86abdee195f Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 27 Jun 2024 11:38:48 -0700 Subject: [PATCH 02/54] make bodies dance with gravity on game end --- src/anybody.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/anybody.js b/src/anybody.js index 8f2f6924..016cbb0c 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -12,6 +12,7 @@ import { Buttons } from './buttons.js' // const GAME_LENGTH = 60 // seconds const GAME_LENGTH_BY_LEVEL_INDEX = [10, 20, 30, 40, 50] +const NORMAL_GRAVITY = 100 const proverTickIndex = { 2: 250, 3: 250, @@ -65,7 +66,7 @@ export class Anybody extends EventEmitter { pixelDensity: 4, //4, // Math.min(4, 4 * (window.devicePixelRatio ?? 1)), scalingFactor: 10n ** 3n, minDistanceSquared: 200 * 200, - G: 100, // Gravitational constant + G: NORMAL_GRAVITY, // Gravitational constant mode: 'game', // game or nft admin: false, solved: false, @@ -118,6 +119,7 @@ export class Anybody extends EventEmitter { this.lastMissileCantBeUndone = false this.speedFactor = 2 this.speedLimit = 10 + this.G = NORMAL_GRAVITY this.vectorLimit = this.speedLimit * this.speedFactor this.FPS = 25 this.P5_FPS_MULTIPLIER = 3 @@ -376,6 +378,7 @@ export class Anybody extends EventEmitter { // this.sound?.playGameOver({ won }) this.gameOver = true this.won = won + this.G = 2000 // make the badies dance var dust = 0 var timeTook = 0 From c9a155e8170d88329102fc08521d7e784c4d55bb Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 27 Jun 2024 12:17:54 -0700 Subject: [PATCH 03/54] close --- src/anybody.js | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/visuals.js | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/src/anybody.js b/src/anybody.js index 016cbb0c..437080d4 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -29,6 +29,65 @@ function intersectsButton(button, x, y) { ) } +const PAUSE_BODY_DATA = [ + { + bodyIndex: 0, + seed: '0x34f645e62a9fb47226675e36c76e717bee1cc4688cdbd2ce1a2343e0fb210afa', + radius: 36000, + px: 149311, + py: 901865 + }, + { + bodyIndex: 1, + seed: '0x34f645e62a9fb47276675e36c76e717bee1cc4688cdbx2ce1a2343e0fb210afa', + radius: 30000, + px: 309311, + py: 201865 + }, + { + bodyIndex: 2, + seed: '0x34f645e62a9fb47426675e36c76e717bee1cc4688cdbd2te1a2343e0fb210afa', + radius: 36000, + px: 949311, + py: 901865 + }, + { + bodyIndex: 3, + seed: '0xfc7bf9b39ccf2426bd93629ff94dff5e6e9347098494ac42ea7c7d7339b09f2a', + radius: 7000, + px: 833406, + py: 103029 + }, + { + bodyIndex: 4, + seed: '0xd85fb8fd2d7ea126a9c3f53553f987bb4a52c0beea472672edeb4d39dcfcdd19', + radius: 20000, + px: 705620, + py: 178711 + }, + { + bodyIndex: 5, + seed: '0xd4528b05a80492ac1160e49f070b2f77b2e2b4180b360be799a920f35926aa5d', + radius: 17000, + px: 139878, + py: 454946 + }, + { + bodyIndex: 6, + seed: '0xd4528b05a80492ac1160e49f070b2f77b2e2b4180b360be799a920f35926aa5d', + radius: 9000, + px: 289878, + py: 694946 + }, + { + bodyIndex: 7, + seed: '0xd4528b05a80492ac1160e49f070b2f77b2e2b4180b360be799a920f35926aa5d', + radius: 14000, + px: 589878, + py: 694946 + } +] + export class Anybody extends EventEmitter { constructor(p, options = {}) { super() @@ -459,6 +518,10 @@ export class Anybody extends EventEmitter { } setPause(newPauseState = !this.paused, mute = false) { + if (newPauseState) { + this.pauseBodies = PAUSE_BODY_DATA.map(this.bodyDataToBodies.bind(this)) + } + if (typeof newPauseState !== 'boolean') { newPauseState = !this.paused } @@ -698,6 +761,7 @@ export class Anybody extends EventEmitter { generateBodies() { this.bodyData = this.bodyData || this.generateLevelData(this.day, this.level) + console.log(JSON.stringify(this.bodyData)) this.bodies = this.bodyData.map(this.bodyDataToBodies.bind(this)) this.startingBodies = this.bodies.length } diff --git a/src/visuals.js b/src/visuals.js index 4ef7c2ce..ba6a7945 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -191,6 +191,8 @@ export const Visuals = { if (!this.firstFrame && !this.paused) { this.drawBodies() + } else { + this.drawPauseBodies() } if ( @@ -1224,6 +1226,47 @@ export const Visuals = { this.bodiesGraphic.clear() }, + drawPauseBodies() { + this.bodiesGraphic ||= this.p.createGraphics( + this.windowWidth, + this.windowHeight + ) + this.bodiesGraphic.noStroke() + + for (const body of this.pauseBodies) { + body.position.x + // after final proof is sent, don't draw upgradable bodies + if (body.radius == 0) continue + const bodyRadius = this.bodyCopies.filter( + (b) => b.bodyIndex == body.bodyIndex + )[0]?.radius + const radius = this.getBodyRadius(bodyRadius) + + // calculate x and y wobble factors based on this.p5Frames to make the pause bodies look like they're bobbing around + const xWobble = + this.p.sin(this.p.frameCount / this.P5_FPS) * (10 + body.bodyIndex) + const yWobble = + this.p.cos(this.p.frameCount / this.P5_FPS + body.bodyIndex * 3) * + (10 + body.bodyIndex) + + const bodyCopy = JSON.parse( + JSON.stringify( + body, + (key, value) => (typeof value === 'bigint' ? value.toString() : value) // return everything else unchanged + ) + ) + bodyCopy.position = this.p.createVector( + body.position.x + xWobble, + body.position.y + yWobble + ) + bodyCopy.velocity = this.p.createVector(body.velocity.x, body.velocity.y) + this.drawBodiesLooped(bodyCopy, radius, this.drawBody) + } + + this.p.image(this.bodiesGraphic, 0, 0) + this.bodiesGraphic.clear() + }, + drawBorder() { // drawClock const clockCenter = this.windowWidth / 2 From 384b0ca9eca4259655a37a634adb0995fcfbf5fa Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 27 Jun 2024 14:24:02 -0700 Subject: [PATCH 04/54] mostly match figma, heros --- src/anybody.js | 12 +++--- src/buttons.js | 2 +- src/visuals.js | 110 ++++++++++++++++++++++++++----------------------- 3 files changed, 67 insertions(+), 57 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 437080d4..a068eab5 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -40,16 +40,16 @@ const PAUSE_BODY_DATA = [ { bodyIndex: 1, seed: '0x34f645e62a9fb47276675e36c76e717bee1cc4688cdbx2ce1a2343e0fb210afa', - radius: 30000, + radius: 32000, px: 309311, - py: 201865 + py: 121865 }, { bodyIndex: 2, seed: '0x34f645e62a9fb47426675e36c76e717bee1cc4688cdbd2te1a2343e0fb210afa', - radius: 36000, - px: 949311, - py: 901865 + radius: 30000, + px: 850311, + py: 811865 }, { bodyIndex: 3, @@ -520,6 +520,8 @@ export class Anybody extends EventEmitter { setPause(newPauseState = !this.paused, mute = false) { if (newPauseState) { this.pauseBodies = PAUSE_BODY_DATA.map(this.bodyDataToBodies.bind(this)) + this.pauseBodies[1].c = this.getBodyColor(0) + this.pauseBodies[2].c = this.getBodyColor(0) } if (typeof newPauseState !== 'boolean') { diff --git a/src/buttons.js b/src/buttons.js index 2551d48f..25901e34 100644 --- a/src/buttons.js +++ b/src/buttons.js @@ -31,7 +31,7 @@ export const Buttons = { button.visibleForFrames++ button.lastVisibleFrame = this.p5Frames - const entranceTime = 0.2 // seconds + const entranceTime = 0.4 // seconds // animate in button when it is visible const scale = Math.min( diff --git a/src/visuals.js b/src/visuals.js index ba6a7945..4f84bbe3 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -445,13 +445,13 @@ export const Visuals = { // } }, - tintImage(img, color) { - const g = this.p.createGraphics(img.width, img.height) - const cc = this.getTintFromColor(color) - g.tint(cc[0], cc[1], cc[2], cc[3] * 255) - g.image(img, 0, 0) - return g - }, + // tintImage(img, color) { + // const g = this.p.createGraphics(img.width, img.height) + // const cc = this.getTintFromColor(color) + // g.tint(cc[0], cc[1], cc[2], cc[3] * 255) + // g.image(img, 0, 0) + // return g + // }, drawStaticBg() { const bw = true @@ -931,7 +931,9 @@ export const Visuals = { }, drawFaceSvg(body, width) { - this.fIndex ||= Math.floor(Math.random() * 14) + const maxIndex = Math.min(FACE_BLINK_SVGS.length, FACE_SVGS.length) + this.fIndex ||= Math.floor(Math.random() * maxIndex) + const fIndex = (this.fIndex + body.bodyIndex) % maxIndex const baddiesNear = this.closeTo(body) if (baddiesNear) { @@ -948,9 +950,9 @@ export const Visuals = { Math.floor(this.frames / x) % m == 0 || Math.floor(this.frames / x) % m == 2 ) { - this.drawImageAsset(FACE_BLINK_SVGS[this.fIndex], width) + this.drawImageAsset(FACE_BLINK_SVGS[fIndex], width) } else { - this.drawImageAsset(FACE_SVGS[this.fIndex], width) + this.drawImageAsset(FACE_SVGS[fIndex], width) } // this.bodiesGraphic.pop() }, @@ -958,14 +960,15 @@ export const Visuals = { drawStarForegroundSvg(width, body) { const fill = body.c.fg this.bodiesGraphic.push() - this.fgIndex ||= Math.floor(Math.random() * 10) + this.fgIndex ||= Math.floor(Math.random() * FG_SVGS.length) + const fgIndex = (this.bgIndex + body.bodyIndex) % FG_SVGS.length const r = { ...rot.fg, - ...(rotOverride?.fg?.[this.fgIndex] ?? {}) + ...(rotOverride?.fg?.[fgIndex] ?? {}) } const rotateBy = r.speed == 0 ? 0 : (this.frames / r.speed) % 360 this.bodiesGraphic.rotate(r.direction * rotateBy) - this.drawImageAsset(FG_SVGS[this.fgIndex], width, fill) + this.drawImageAsset(FG_SVGS[fgIndex], width, fill) this.bodiesGraphic.pop() }, @@ -985,51 +988,52 @@ export const Visuals = { drawStarBackgroundSvg(width, body) { const fill = body.c.bg this.bodiesGraphic.push() - this.bgIndex ||= Math.floor(Math.random() * 10) + this.bgIndex ||= Math.floor(Math.random() * BG_SVGS.length) + const bgIndex = (this.bgIndex + body.bodyIndex) % BG_SVGS.length const r = { ...rot.bg, - ...(rotOverride?.bg?.[this.bgIndex] ?? {}) + ...(rotOverride?.bg?.[bgIndex] ?? {}) } const rotateBy = r.speed == 0 ? 0 : (this.frames / r.speed) % 360 this.bodiesGraphic.rotate(r.direction * rotateBy) - this.drawImageAsset(BG_SVGS[this.bgIndex], width, fill) + this.drawImageAsset(BG_SVGS[bgIndex], width, fill) this.bodiesGraphic.pop() }, - getTintFromColor(c) { - const cc = c - .split(',') - .map((c) => parseFloat(c.replace(')', '').replace('hsla(', ''))) - return [cc[0], cc[1], cc[2], cc[2]] - }, - - drawBodyStyle1(radius, body, offset) { - this.bodiesGraphic.noStroke() - let c = - body.radius !== 0 ? body.c : this.replaceOpacity(body.c, this.deadOpacity) - // if (body.bodyIndex == 0) { - // c = 'white' - // } - this.bodiesGraphic.fill(c) - // const scale = 1 - // const foo = this.p.createGraphics(radius / scale, radius / scale) - // foo.noStroke() - // foo.fill(c) - // foo.ellipse( - // radius / scale / 2, - // radius / scale / 2, - // radius / scale, - // radius / scale - // ) - // this.bodiesGraphic.image( - // foo, - // -radius / 2, - // -radius / 2 - offset, - // radius, - // radius - // ) - this.bodiesGraphic.ellipse(0, offset, radius) - }, + // getTintFromColor(c) { + // const cc = c + // .split(',') + // .map((c) => parseFloat(c.replace(')', '').replace('hsla(', ''))) + // return [cc[0], cc[1], cc[2], cc[2]] + // }, + + // drawBodyStyle1(radius, body, offset) { + // this.bodiesGraphic.noStroke() + // let c = + // body.radius !== 0 ? body.c : this.replaceOpacity(body.c, this.deadOpacity) + // // if (body.bodyIndex == 0) { + // // c = 'white' + // // } + // this.bodiesGraphic.fill(c) + // // const scale = 1 + // // const foo = this.p.createGraphics(radius / scale, radius / scale) + // // foo.noStroke() + // // foo.fill(c) + // // foo.ellipse( + // // radius / scale / 2, + // // radius / scale / 2, + // // radius / scale, + // // radius / scale + // // ) + // // this.bodiesGraphic.image( + // // foo, + // // -radius / 2, + // // -radius / 2 - offset, + // // radius, + // // radius + // // ) + // this.bodiesGraphic.ellipse(0, offset, radius) + // }, moveAndRotate_PopAfter(graphic, x, y /*v*/) { graphic.push() @@ -1053,7 +1057,8 @@ export const Visuals = { // y-offset of face relative to center // const offset = this.getOffset(radius) - if (body.bodyIndex === 0) { + if (body.bodyIndex === 0 || (this.paused && body.bodyIndex < 3)) { + // draw hero const size = Math.floor(body.radius * BODY_SCALE * 2.66) this.drawStarBackgroundSvg(size, body) @@ -1234,6 +1239,7 @@ export const Visuals = { this.bodiesGraphic.noStroke() for (const body of this.pauseBodies) { + this.bodiesGraphic.push() body.position.x // after final proof is sent, don't draw upgradable bodies if (body.radius == 0) continue @@ -1261,9 +1267,11 @@ export const Visuals = { ) bodyCopy.velocity = this.p.createVector(body.velocity.x, body.velocity.y) this.drawBodiesLooped(bodyCopy, radius, this.drawBody) + this.bodiesGraphic.pop() } this.p.image(this.bodiesGraphic, 0, 0) + this.bodiesGraphic.clear() }, From d4b0681cc832dbaaff1570d31870353093168d5b Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 27 Jun 2024 14:30:58 -0700 Subject: [PATCH 05/54] bob, rotation --- src/anybody.js | 32 ++++++++++++++++++++++++-------- src/visuals.js | 2 +- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index a068eab5..0bca2f7b 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -35,56 +35,72 @@ const PAUSE_BODY_DATA = [ seed: '0x34f645e62a9fb47226675e36c76e717bee1cc4688cdbd2ce1a2343e0fb210afa', radius: 36000, px: 149311, - py: 901865 + py: 901865, + vx: 0, + vy: 0 }, { bodyIndex: 1, seed: '0x34f645e62a9fb47276675e36c76e717bee1cc4688cdbx2ce1a2343e0fb210afa', radius: 32000, px: 309311, - py: 121865 + py: 121865, + vx: 0, + vy: 0 }, { bodyIndex: 2, seed: '0x34f645e62a9fb47426675e36c76e717bee1cc4688cdbd2te1a2343e0fb210afa', radius: 30000, px: 850311, - py: 811865 + py: 811865, + vx: 0, + vy: 0 }, { bodyIndex: 3, seed: '0xfc7bf9b39ccf2426bd93629ff94dff5e6e9347098494ac42ea7c7d7339b09f2a', radius: 7000, px: 833406, - py: 103029 + py: 103029, + vx: 0, + vy: 0 }, { bodyIndex: 4, seed: '0xd85fb8fd2d7ea126a9c3f53553f987bb4a52c0beea472672edeb4d39dcfcdd19', radius: 20000, px: 705620, - py: 178711 + py: 178711, + vx: -100000, + vy: -1111000 }, { bodyIndex: 5, seed: '0xd4528b05a80492ac1160e49f070b2f77b2e2b4180b360be799a920f35926aa5d', radius: 17000, px: 139878, - py: 454946 + py: 454946, + vx: 0, + vy: 0 }, { bodyIndex: 6, seed: '0xd4528b05a80492ac1160e49f070b2f77b2e2b4180b360be799a920f35926aa5d', radius: 9000, px: 289878, - py: 694946 + py: 694946, + vx: 0, + vy: 0 }, { bodyIndex: 7, seed: '0xd4528b05a80492ac1160e49f070b2f77b2e2b4180b360be799a920f35926aa5d', radius: 14000, px: 589878, - py: 694946 + py: 694946, + vx: -100000, + vy: -1111000 } ] diff --git a/src/visuals.js b/src/visuals.js index 4f84bbe3..6dad4a50 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1253,7 +1253,7 @@ export const Visuals = { this.p.sin(this.p.frameCount / this.P5_FPS) * (10 + body.bodyIndex) const yWobble = this.p.cos(this.p.frameCount / this.P5_FPS + body.bodyIndex * 3) * - (10 + body.bodyIndex) + (16 + body.bodyIndex) const bodyCopy = JSON.parse( JSON.stringify( From fd365722965b557a979db279258cf49f006b66fa Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 27 Jun 2024 14:42:24 -0700 Subject: [PATCH 06/54] comment unused code for sanity --- src/visuals.js | 514 ++++++++++++++++++++++++------------------------- 1 file changed, 257 insertions(+), 257 deletions(-) diff --git a/src/visuals.js b/src/visuals.js index 6dad4a50..0b858572 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1275,99 +1275,99 @@ export const Visuals = { this.bodiesGraphic.clear() }, - drawBorder() { - // drawClock - const clockCenter = this.windowWidth / 2 - - // const radialStep1 = (this.frames / (this.chunk * 1) / 255) * 180 + 270 % 360 - // const clockRadius = this.windowWidth - // const clockX = clockCenter + clockRadius * Math.cos(radialStep1 * Math.PI / 180) - // const clockY = clockCenter + clockRadius * Math.sin(radialStep1 * Math.PI / 180) - // this.bodiesGraphic.stroke(this.getBW()) - // this.bodiesGraphic.noStroke() - // this.bodiesGraphic.fill(this.getNotGrey()) - // this.bodiesGraphic.ellipse(clockX, clockY, 100, 100) - - let size = this.windowWidth / Math.PI - const radialStep2 = - (this.frames / (this.chunk * 1) / 255) * 360 + (270 % 360) - const clockRadius2 = this.windowWidth / 2 + size / 4 - - const clockX2 = - clockCenter + clockRadius2 * Math.cos((radialStep2 * Math.PI) / 180) - const clockY2 = - clockCenter + clockRadius2 * Math.sin((radialStep2 * Math.PI) / 180) - // this.bodiesGraphic.stroke(this.getBW()) - this.bodiesGraphic.noStroke() - // this.bodiesGraphic.stroke('white') - this.bodiesGraphic.fill(this.getGrey()) - // if (size < 0) { - // size = 0 - // } - this.bodiesGraphic.ellipse(clockX2, clockY2, size, size) - }, - - getAngledImage(body) { - const graphic = this.p.createGraphics(this.windowWidth, this.windowHeight) - graphic.push() - graphic.translate(body.position.x, body.position.y) - var angle = body.velocity.heading() + graphic.PI / 2 - graphic.rotate(angle) - - if (!this.eyes) { - this.eyes = this.p.loadImage('/eyes-3.png') - } - const size = 6 - graphic.image( - this.eyes, - -body.radius * (size / 2), - -body.radius * (size / 2), - body.radius * size, - body.radius * size - ) - - graphic.pop() - graphic.push() - graphic.translate(body.position.x, body.position.y) - var angle2 = body.velocity.heading() + graphic.PI / 2 - graphic.rotate(angle2) - graphic.pop() - return graphic - }, + // drawBorder() { + // // drawClock + // const clockCenter = this.windowWidth / 2 + + // // const radialStep1 = (this.frames / (this.chunk * 1) / 255) * 180 + 270 % 360 + // // const clockRadius = this.windowWidth + // // const clockX = clockCenter + clockRadius * Math.cos(radialStep1 * Math.PI / 180) + // // const clockY = clockCenter + clockRadius * Math.sin(radialStep1 * Math.PI / 180) + // // this.bodiesGraphic.stroke(this.getBW()) + // // this.bodiesGraphic.noStroke() + // // this.bodiesGraphic.fill(this.getNotGrey()) + // // this.bodiesGraphic.ellipse(clockX, clockY, 100, 100) + + // let size = this.windowWidth / Math.PI + // const radialStep2 = + // (this.frames / (this.chunk * 1) / 255) * 360 + (270 % 360) + // const clockRadius2 = this.windowWidth / 2 + size / 4 + + // const clockX2 = + // clockCenter + clockRadius2 * Math.cos((radialStep2 * Math.PI) / 180) + // const clockY2 = + // clockCenter + clockRadius2 * Math.sin((radialStep2 * Math.PI) / 180) + // // this.bodiesGraphic.stroke(this.getBW()) + // this.bodiesGraphic.noStroke() + // // this.bodiesGraphic.stroke('white') + // this.bodiesGraphic.fill(this.getGrey()) + // // if (size < 0) { + // // size = 0 + // // } + // this.bodiesGraphic.ellipse(clockX2, clockY2, size, size) + // }, - getAngledBody(body, finalColor) { - // rotate by velocity - this.p.push() - this.p.translate(body.position.x, body.position.y) - var angle = body.velocity.heading() + this.p.PI / 2 - this.p.rotate(angle) + // getAngledImage(body) { + // const graphic = this.p.createGraphics(this.windowWidth, this.windowHeight) + // graphic.push() + // graphic.translate(body.position.x, body.position.y) + // var angle = body.velocity.heading() + graphic.PI / 2 + // graphic.rotate(angle) + + // if (!this.eyes) { + // this.eyes = this.p.loadImage('/eyes-3.png') + // } + // const size = 6 + // graphic.image( + // this.eyes, + // -body.radius * (size / 2), + // -body.radius * (size / 2), + // body.radius * size, + // body.radius * size + // ) + + // graphic.pop() + // graphic.push() + // graphic.translate(body.position.x, body.position.y) + // var angle2 = body.velocity.heading() + graphic.PI / 2 + // graphic.rotate(angle2) + // graphic.pop() + // return graphic + // }, - this.p.strokeWeight(0) - // stroke("white") - this.p.fill(finalColor) - // Calculate the vertices of the equilateral triangle - let x1 = body.radius * 4 * this.p.cos(this.p.PI / 6) - let y1 = body.radius * 4 * this.p.sin(this.p.PI / 6) - - let x2 = body.radius * 4 * this.p.cos(this.p.PI / 6 + this.p.TWO_PI / 3) - let y2 = body.radius * 4 * this.p.sin(this.p.PI / 6 + this.p.TWO_PI / 3) - - let x3 = - body.radius * 4 * this.p.cos(this.p.PI / 6 + (2 * this.p.TWO_PI) / 3) - let y3 = - body.radius * 4 * this.p.sin(this.p.PI / 6 + (2 * this.p.TWO_PI) / 3) - - this.p.triangle(x1, y1, x2, y2, x3, y3) - this.p.pop() - - this.p.stroke('white') - this.p.strokeWeight(1) - this.p.push() - this.p.translate(body.position.x, body.position.y) - var angle2 = body.velocity.heading() + this.p.PI / 2 - this.p.rotate(angle2) - this.p.pop() - }, + // getAngledBody(body, finalColor) { + // // rotate by velocity + // this.p.push() + // this.p.translate(body.position.x, body.position.y) + // var angle = body.velocity.heading() + this.p.PI / 2 + // this.p.rotate(angle) + + // this.p.strokeWeight(0) + // // stroke("white") + // this.p.fill(finalColor) + // // Calculate the vertices of the equilateral triangle + // let x1 = body.radius * 4 * this.p.cos(this.p.PI / 6) + // let y1 = body.radius * 4 * this.p.sin(this.p.PI / 6) + + // let x2 = body.radius * 4 * this.p.cos(this.p.PI / 6 + this.p.TWO_PI / 3) + // let y2 = body.radius * 4 * this.p.sin(this.p.PI / 6 + this.p.TWO_PI / 3) + + // let x3 = + // body.radius * 4 * this.p.cos(this.p.PI / 6 + (2 * this.p.TWO_PI) / 3) + // let y3 = + // body.radius * 4 * this.p.sin(this.p.PI / 6 + (2 * this.p.TWO_PI) / 3) + + // this.p.triangle(x1, y1, x2, y2, x3, y3) + // this.p.pop() + + // this.p.stroke('white') + // this.p.strokeWeight(1) + // this.p.push() + // this.p.translate(body.position.x, body.position.y) + // var angle2 = body.velocity.heading() + this.p.PI / 2 + // this.p.rotate(angle2) + // this.p.pop() + // }, drawTailStyle1(/*x, y, v, radius, finalColor, offset*/) { return @@ -1387,174 +1387,174 @@ export const Visuals = { // this.p.pop() }, - drawTailStyleGhost(x, y, v, radius, finalColor) { - // ghost version - - const id = radius + '-' + finalColor - if (!this.tailGraphics) { - this.tailGraphics = {} - } - if (!this.tailGraphics || this.tailGraphics[id] == undefined) { - this.tailGraphics[id] = this.p.createGraphics( - this.windowWidth, - this.windowHeight - ) - this.tailGraphics[id].noStroke() - this.tailGraphics[id].fill(finalColor) - - this.tailGraphics[id].beginShape() - // this.tailGraphics[id].vertex(radius, 0) - // this.tailGraphics[id].vertex(0, 0) - - // this.p.arc(0, 0, radius, radius, this.p.PI, 2 * this.p.PI) - const arcResolution = 20 - - for (let j = 0; j < arcResolution; j++) { - const ang = this.p.map(j, 0, arcResolution, 0, this.p.PI) - const ax = radius / 2 + (this.p.cos(ang) * radius) / 2 - const ay = (2 * radius) / 2 + (-1 * this.p.sin(ang) * radius) / 2 - this.tailGraphics[id].vertex(ax, ay) - } - - // this.tailGraphics[id].fill('red') - // this.tailGraphics[id].rect(0, 0, radius, radius / 2) - - const bumps = 7 - let bumpHeight = radius / 6 - // let heightChanger = radius / 10 - // const bumpHeightMax = radius / 5 - // const bumpHeightMin = radius / 8 - const startY = radius * 1 - // this.tailGraphics[id].push() - let remaindingWidth = radius - for (let i = 0; i < bumps; i++) { - let bumpWidth = radius / bumps - // bumpHeight += heightChanger - // if (bumpHeight > bumpHeightMax || bumpHeight < bumpHeightMin) { - // heightChanger *= -1 - // } - let x = radius - remaindingWidth - if (i % 2 == 1) { - // this.tailGraphics[id].arc(x + bumpWidth / 2, startY, bumpWidth, bumpHeight, this.tailGraphics[id].PI, 0, this.tailGraphics[id].OPEN) - for (let j = 0; j < arcResolution; j++) { - const ang = this.p.map(j, 0, arcResolution, this.p.PI, 0) - const ax = x + bumpWidth / 2 + (this.p.cos(ang) * bumpWidth) / 2 - const ay = - startY + bumpHeight + (-1 * this.p.sin(ang) * bumpHeight) / 2 - this.tailGraphics[id].vertex(ax, ay) - } - } else { - for (let j = 0; j < arcResolution; j++) { - const ang = this.p.map(j, 0, arcResolution, this.p.PI, 0) - const ax = x + bumpWidth / 2 + (this.p.cos(ang) * bumpWidth) / 2 - const ay = startY + bumpHeight + (this.p.sin(ang) * bumpHeight) / 2 - this.tailGraphics[id].vertex(ax, ay) - } - // this.tailGraphics[id].arc(x + bumpWidth / 2, startY + bumpWidth, bumpWidth, bumpHeight, 0, this.tailGraphics[id].PI, this.tailGraphics[id].OPEN) - } - remaindingWidth -= bumpWidth - } - this.tailGraphics[id].endShape(this.tailGraphics[id].CLOSE) - // this.tailGraphics[id].pop() - } - - // this.tailGraphics[id].push() - // this.tailGraphics[id].translate(x, y) - var angle = v.heading() + this.p.PI / 2 - // this.tailGraphics[id].rotate(angle) - // this.tailGraphics[id].fill(finalColor) - // this.tailGraphics[id].fill('rgba(255,0,0,1)') - // this.tailGraphics[id].rect(0, 0, radius, radius / 4) - // this.tailGraphics[id].pop() - this.p.push() - this.p.translate(x, y) - this.p.rotate(angle) - this.p.image(this.tailGraphics[id], -radius / 2, -radius) - this.p.pop() - }, + // drawTailStyleGhost(x, y, v, radius, finalColor) { + // // ghost version + + // const id = radius + '-' + finalColor + // if (!this.tailGraphics) { + // this.tailGraphics = {} + // } + // if (!this.tailGraphics || this.tailGraphics[id] == undefined) { + // this.tailGraphics[id] = this.p.createGraphics( + // this.windowWidth, + // this.windowHeight + // ) + // this.tailGraphics[id].noStroke() + // this.tailGraphics[id].fill(finalColor) + + // this.tailGraphics[id].beginShape() + // // this.tailGraphics[id].vertex(radius, 0) + // // this.tailGraphics[id].vertex(0, 0) + + // // this.p.arc(0, 0, radius, radius, this.p.PI, 2 * this.p.PI) + // const arcResolution = 20 + + // for (let j = 0; j < arcResolution; j++) { + // const ang = this.p.map(j, 0, arcResolution, 0, this.p.PI) + // const ax = radius / 2 + (this.p.cos(ang) * radius) / 2 + // const ay = (2 * radius) / 2 + (-1 * this.p.sin(ang) * radius) / 2 + // this.tailGraphics[id].vertex(ax, ay) + // } + + // // this.tailGraphics[id].fill('red') + // // this.tailGraphics[id].rect(0, 0, radius, radius / 2) + + // const bumps = 7 + // let bumpHeight = radius / 6 + // // let heightChanger = radius / 10 + // // const bumpHeightMax = radius / 5 + // // const bumpHeightMin = radius / 8 + // const startY = radius * 1 + // // this.tailGraphics[id].push() + // let remaindingWidth = radius + // for (let i = 0; i < bumps; i++) { + // let bumpWidth = radius / bumps + // // bumpHeight += heightChanger + // // if (bumpHeight > bumpHeightMax || bumpHeight < bumpHeightMin) { + // // heightChanger *= -1 + // // } + // let x = radius - remaindingWidth + // if (i % 2 == 1) { + // // this.tailGraphics[id].arc(x + bumpWidth / 2, startY, bumpWidth, bumpHeight, this.tailGraphics[id].PI, 0, this.tailGraphics[id].OPEN) + // for (let j = 0; j < arcResolution; j++) { + // const ang = this.p.map(j, 0, arcResolution, this.p.PI, 0) + // const ax = x + bumpWidth / 2 + (this.p.cos(ang) * bumpWidth) / 2 + // const ay = + // startY + bumpHeight + (-1 * this.p.sin(ang) * bumpHeight) / 2 + // this.tailGraphics[id].vertex(ax, ay) + // } + // } else { + // for (let j = 0; j < arcResolution; j++) { + // const ang = this.p.map(j, 0, arcResolution, this.p.PI, 0) + // const ax = x + bumpWidth / 2 + (this.p.cos(ang) * bumpWidth) / 2 + // const ay = startY + bumpHeight + (this.p.sin(ang) * bumpHeight) / 2 + // this.tailGraphics[id].vertex(ax, ay) + // } + // // this.tailGraphics[id].arc(x + bumpWidth / 2, startY + bumpWidth, bumpWidth, bumpHeight, 0, this.tailGraphics[id].PI, this.tailGraphics[id].OPEN) + // } + // remaindingWidth -= bumpWidth + // } + // this.tailGraphics[id].endShape(this.tailGraphics[id].CLOSE) + // // this.tailGraphics[id].pop() + // } + + // // this.tailGraphics[id].push() + // // this.tailGraphics[id].translate(x, y) + // var angle = v.heading() + this.p.PI / 2 + // // this.tailGraphics[id].rotate(angle) + // // this.tailGraphics[id].fill(finalColor) + // // this.tailGraphics[id].fill('rgba(255,0,0,1)') + // // this.tailGraphics[id].rect(0, 0, radius, radius / 4) + // // this.tailGraphics[id].pop() + // this.p.push() + // this.p.translate(x, y) + // this.p.rotate(angle) + // this.p.image(this.tailGraphics[id], -radius / 2, -radius) + // this.p.pop() + // }, - getOffset(radius) { - return this.target == 'inside' ? 0 : radius / 1.5 - }, + // getOffset(radius) { + // return this.target == 'inside' ? 0 : radius / 1.5 + // }, - drawTails() { - // if (this.allCopiesOfBodies && this.allCopiesOfBodies.length > 0) { - // const allCopiesOfBodies = - // this.allCopiesOfBodies[this.allCopiesOfBodies.length - 1] - // const body = allCopiesOfBodies[0] - // if (body.bodyIndex == 0) { - // this.p.noFill() - // this.p.stroke('white') - // this.p.strokeWeight(10) - // this.p.ellipse(body.position.x, body.position.y, body.radius * 10) - // } - // } - for (let i = 0; i < this.allCopiesOfBodies.length; i++) { - const copyOfBodies = this.allCopiesOfBodies[i] - for (let j = 0; j < copyOfBodies.length; j++) { - const body = copyOfBodies[j] - if (body.bodyIndex == 0) continue - if (this.gameOver || this.won) { - if ( - this.witheringBodies.filter((b) => b.bodyIndex == body.bodyIndex) - .length > 0 - ) - continue - } - if (body.radius == 0) continue - let c = - body.radius !== 0 - ? this.replaceOpacity(body.c, this.deadOpacity) - : this.replaceOpacity(body.c, this.deadOpacity) - this.p.fill(c) - // if (this.mode == 'nft') { - const bodyCopy = this.bodyCopies.filter( - (b) => b.bodyIndex == body.bodyIndex - )[0] - const radius = this.getBodyRadius(bodyCopy.radius) * 1.1 - - // this.p.ellipse(body.position.x, body.position.y, radius, radius) - this.p.push() - this.p.translate(body.position.x, body.position.y) - this.p.rotate(body.velocity.heading() + this.p.PI / 2) - // this.p.arc(0, 0, radius, radius, this.p.PI, 2 * this.p.PI) - this.p.pop() - const offset = this.getOffset(radius) - - switch (body.tailStyle) { - case 1: - this.drawTailStyle1( - body.position.x, - body.position.y, - body.velocity, - radius, - c, - offset - ) - break - case 'ghost': - this.drawTailStyleGhost( - body.position.x, - body.position.y, - body.velocity, - radius, - c, - offset - ) - break - default: - this.drawTailStyle1( - body.position.x, - body.position.y, - body.velocity, - radius, - c, - offset - ) - } - } - } - }, + // drawTails() { + // // if (this.allCopiesOfBodies && this.allCopiesOfBodies.length > 0) { + // // const allCopiesOfBodies = + // // this.allCopiesOfBodies[this.allCopiesOfBodies.length - 1] + // // const body = allCopiesOfBodies[0] + // // if (body.bodyIndex == 0) { + // // this.p.noFill() + // // this.p.stroke('white') + // // this.p.strokeWeight(10) + // // this.p.ellipse(body.position.x, body.position.y, body.radius * 10) + // // } + // // } + // for (let i = 0; i < this.allCopiesOfBodies.length; i++) { + // const copyOfBodies = this.allCopiesOfBodies[i] + // for (let j = 0; j < copyOfBodies.length; j++) { + // const body = copyOfBodies[j] + // if (body.bodyIndex == 0) continue + // if (this.gameOver || this.won) { + // if ( + // this.witheringBodies.filter((b) => b.bodyIndex == body.bodyIndex) + // .length > 0 + // ) + // continue + // } + // if (body.radius == 0) continue + // let c = + // body.radius !== 0 + // ? this.replaceOpacity(body.c, this.deadOpacity) + // : this.replaceOpacity(body.c, this.deadOpacity) + // this.p.fill(c) + // // if (this.mode == 'nft') { + // const bodyCopy = this.bodyCopies.filter( + // (b) => b.bodyIndex == body.bodyIndex + // )[0] + // const radius = this.getBodyRadius(bodyCopy.radius) * 1.1 + + // // this.p.ellipse(body.position.x, body.position.y, radius, radius) + // this.p.push() + // this.p.translate(body.position.x, body.position.y) + // this.p.rotate(body.velocity.heading() + this.p.PI / 2) + // // this.p.arc(0, 0, radius, radius, this.p.PI, 2 * this.p.PI) + // this.p.pop() + // const offset = this.getOffset(radius) + + // switch (body.tailStyle) { + // case 1: + // this.drawTailStyle1( + // body.position.x, + // body.position.y, + // body.velocity, + // radius, + // c, + // offset + // ) + // break + // case 'ghost': + // this.drawTailStyleGhost( + // body.position.x, + // body.position.y, + // body.velocity, + // radius, + // c, + // offset + // ) + // break + // default: + // this.drawTailStyle1( + // body.position.x, + // body.position.y, + // body.velocity, + // radius, + // c, + // offset + // ) + // } + // } + // } + // }, replaceOpacity(c, opacity) { const isHSLA = c.includes('hsla') From 21a0e92e3328f044c3fcc473e1867c81b34f4316 Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 27 Jun 2024 14:44:10 -0700 Subject: [PATCH 07/54] dont log body data --- src/anybody.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/anybody.js b/src/anybody.js index 0bca2f7b..235c1c15 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -779,7 +779,6 @@ export class Anybody extends EventEmitter { generateBodies() { this.bodyData = this.bodyData || this.generateLevelData(this.day, this.level) - console.log(JSON.stringify(this.bodyData)) this.bodies = this.bodyData.map(this.bodyDataToBodies.bind(this)) this.startingBodies = this.bodies.length } From 459a914bdcfba3e3df10cc847f4e9f18c1dc9762 Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 27 Jun 2024 15:13:42 -0700 Subject: [PATCH 08/54] fix this binding issues, just make paused bodies once --- src/anybody.js | 30 ++++++++-------- src/visuals.js | 96 +++++++++++++++++++++++++++++--------------------- 2 files changed, 70 insertions(+), 56 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 235c1c15..9c3b5612 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -533,12 +533,8 @@ export class Anybody extends EventEmitter { this.showPlayAgain = true } - setPause(newPauseState = !this.paused, mute = false) { - if (newPauseState) { - this.pauseBodies = PAUSE_BODY_DATA.map(this.bodyDataToBodies.bind(this)) - this.pauseBodies[1].c = this.getBodyColor(0) - this.pauseBodies[2].c = this.getBodyColor(0) - } + setPause = (newPauseState = !this.paused, mute = false) => { + console.log(this.pauseBodies.map((b) => b.c)) if (typeof newPauseState !== 'boolean') { newPauseState = !this.paused @@ -779,8 +775,12 @@ export class Anybody extends EventEmitter { generateBodies() { this.bodyData = this.bodyData || this.generateLevelData(this.day, this.level) - this.bodies = this.bodyData.map(this.bodyDataToBodies.bind(this)) + this.bodies = this.bodyData.map(this.bodyDataToBodies) this.startingBodies = this.bodies.length + + this.pauseBodies = PAUSE_BODY_DATA.map(this.bodyDataToBodies) + this.pauseBodies[1].c = this.getBodyColor(0) + this.pauseBodies[2].c = this.getBodyColor(0) } getFaceIdx(seed) { @@ -796,8 +796,8 @@ export class Anybody extends EventEmitter { return faceIndex } - bodyDataToBodies(b) { - const bodyIndex = b.bodyIndex + bodyDataToBodies = (b) => { + const { bodyIndex } = b const px = b.px / parseInt(this.scalingFactor) const py = b.py / parseInt(this.scalingFactor) const vx = @@ -811,7 +811,7 @@ export class Anybody extends EventEmitter { return { seed: b.seed, // faceIndex, - bodyIndex: bodyIndex, + bodyIndex, position: this.createVector(px, py), velocity: this.createVector(vx, vy), radius: radius, @@ -826,12 +826,12 @@ export class Anybody extends EventEmitter { const theme = themes[this.random(0, themes.length - 1)] return { - bg: hslToRgb(randHSL(bodyThemes[theme].bg, this.random.bind(this))), - core: hslToRgb(randHSL(bodyThemes[theme].cr, this.random.bind(this))), - fg: hslToRgb(randHSL(bodyThemes[theme].fg, this.random.bind(this))) + bg: hslToRgb(randHSL(bodyThemes[theme].bg, this.random)), + core: hslToRgb(randHSL(bodyThemes[theme].cr, this.random)), + fg: hslToRgb(randHSL(bodyThemes[theme].fg, this.random)) } } else { - return randHSL([undefined, '90-100', '55-60'], this.random.bind(this)) + return randHSL([undefined, '90-100', '55-60'], this.random) } // const seedtype = typeof seed // if (seedtype !== 'string' && seedtype !== 'number') { @@ -848,7 +848,7 @@ export class Anybody extends EventEmitter { // return result } - random(min, max, rng = this.rng) { + random = (min, max, rng = this.rng) => { return rng.nextInt(min, max) // return Math.floor(Math.random() * (upper - lower + 1)) + lower; } diff --git a/src/visuals.js b/src/visuals.js index 0b858572..f95ae43e 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1051,13 +1051,13 @@ export const Visuals = { // } }, - drawBody(x, y, v, radius, body) { + drawBody(x, y, v, radius, body, hero = false) { this.moveAndRotate_PopAfter(this.bodiesGraphic, x, y, v) // y-offset of face relative to center // const offset = this.getOffset(radius) - if (body.bodyIndex === 0 || (this.paused && body.bodyIndex < 3)) { + if (body.bodyIndex === 0 || hero) { // draw hero const size = Math.floor(body.radius * BODY_SCALE * 2.66) @@ -1080,45 +1080,45 @@ export const Visuals = { return actualRadius * 4 + this.radiusMultiplyer }, - drawBodiesLooped(body, radius, drawFunction) { - drawFunction = drawFunction.bind(this) - drawFunction(body.position.x, body.position.y, body.velocity, radius, body) - - // let loopedX = false, - // loopedY = false, - // loopX = body.position.x, - // loopY = body.position.y - // const loopGap = radius / 2 - - // // crosses right, draw on left - // if (body.position.x > this.windowWidth - loopGap) { - // loopedX = true - // loopX = body.position.x - this.windowWidth - // drawFunction(loopX, body.position.y, body.velocity, radius, body, true) - // // crosses left, draw on right - // } else if (body.position.x < loopGap) { - // loopedX = true - // loopX = body.position.x + this.windowWidth - // drawFunction(loopX, body.position.y, body.velocity, radius, body, true) - // } + // drawBodiesLooped(body, radius, drawFunction) { + // drawFunction = drawFunction.bind(this) + // drawFunction(body.position.x, body.position.y, body.velocity, radius, body) + + // // let loopedX = false, + // // loopedY = false, + // // loopX = body.position.x, + // // loopY = body.position.y + // // const loopGap = radius / 2 + + // // // crosses right, draw on left + // // if (body.position.x > this.windowWidth - loopGap) { + // // loopedX = true + // // loopX = body.position.x - this.windowWidth + // // drawFunction(loopX, body.position.y, body.velocity, radius, body, true) + // // // crosses left, draw on right + // // } else if (body.position.x < loopGap) { + // // loopedX = true + // // loopX = body.position.x + this.windowWidth + // // drawFunction(loopX, body.position.y, body.velocity, radius, body, true) + // // } - // // crosses bottom, draw on top - // if (body.position.y > this.windowHeight - loopGap) { - // loopedY = true - // loopY = body.position.y - this.windowHeight - // drawFunction(body.position.x, loopY, body.velocity, radius, body, true) - // // crosses top, draw on bottom - // } else if (body.position.y < loopGap) { - // loopedY = true - // loopY = body.position.y + this.windowHeight - // drawFunction(body.position.x, loopY, body.velocity, radius, body, true) - // } + // // // crosses bottom, draw on top + // // if (body.position.y > this.windowHeight - loopGap) { + // // loopedY = true + // // loopY = body.position.y - this.windowHeight + // // drawFunction(body.position.x, loopY, body.velocity, radius, body, true) + // // // crosses top, draw on bottom + // // } else if (body.position.y < loopGap) { + // // loopedY = true + // // loopY = body.position.y + this.windowHeight + // // drawFunction(body.position.x, loopY, body.velocity, radius, body, true) + // // } - // // crosses corner, draw opposite corner - // if (loopedX && loopedY) { - // drawFunction(loopX, loopY, body.velocity, radius, body, true) - // } - }, + // // // crosses corner, draw opposite corner + // // if (loopedX && loopedY) { + // // drawFunction(loopX, loopY, body.velocity, radius, body, true) + // // } + // }, // TODO: add this back as part of a end game animation drawWitheringBodies() { @@ -1209,7 +1209,13 @@ export const Visuals = { (b) => b.bodyIndex == body.bodyIndex )[0]?.radius const radius = this.getBodyRadius(bodyRadius) - this.drawBodiesLooped(body, radius, this.drawBody) + this.drawBody( + body.position.x, + body.position.y, + body.velocity, + radius, + body + ) const bodyCopy = JSON.parse( JSON.stringify( @@ -1266,7 +1272,15 @@ export const Visuals = { body.position.y + yWobble ) bodyCopy.velocity = this.p.createVector(body.velocity.x, body.velocity.y) - this.drawBodiesLooped(bodyCopy, radius, this.drawBody) + this.drawBody( + body.position.x, + body.position.y, + body.velocity, + radius, + body, + body.bodyIndex < 3 + ) + this.bodiesGraphic.pop() } From 4a4834add5ba0d17cfb55cd2c3d4e905517986ae Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 27 Jun 2024 21:59:46 -0700 Subject: [PATCH 09/54] Revert "fix this binding issues, just make paused bodies once" This reverts commit 459a914bdcfba3e3df10cc847f4e9f18c1dc9762. --- src/anybody.js | 30 ++++++++-------- src/visuals.js | 96 +++++++++++++++++++++----------------------------- 2 files changed, 56 insertions(+), 70 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 9c3b5612..235c1c15 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -533,8 +533,12 @@ export class Anybody extends EventEmitter { this.showPlayAgain = true } - setPause = (newPauseState = !this.paused, mute = false) => { - console.log(this.pauseBodies.map((b) => b.c)) + setPause(newPauseState = !this.paused, mute = false) { + if (newPauseState) { + this.pauseBodies = PAUSE_BODY_DATA.map(this.bodyDataToBodies.bind(this)) + this.pauseBodies[1].c = this.getBodyColor(0) + this.pauseBodies[2].c = this.getBodyColor(0) + } if (typeof newPauseState !== 'boolean') { newPauseState = !this.paused @@ -775,12 +779,8 @@ export class Anybody extends EventEmitter { generateBodies() { this.bodyData = this.bodyData || this.generateLevelData(this.day, this.level) - this.bodies = this.bodyData.map(this.bodyDataToBodies) + this.bodies = this.bodyData.map(this.bodyDataToBodies.bind(this)) this.startingBodies = this.bodies.length - - this.pauseBodies = PAUSE_BODY_DATA.map(this.bodyDataToBodies) - this.pauseBodies[1].c = this.getBodyColor(0) - this.pauseBodies[2].c = this.getBodyColor(0) } getFaceIdx(seed) { @@ -796,8 +796,8 @@ export class Anybody extends EventEmitter { return faceIndex } - bodyDataToBodies = (b) => { - const { bodyIndex } = b + bodyDataToBodies(b) { + const bodyIndex = b.bodyIndex const px = b.px / parseInt(this.scalingFactor) const py = b.py / parseInt(this.scalingFactor) const vx = @@ -811,7 +811,7 @@ export class Anybody extends EventEmitter { return { seed: b.seed, // faceIndex, - bodyIndex, + bodyIndex: bodyIndex, position: this.createVector(px, py), velocity: this.createVector(vx, vy), radius: radius, @@ -826,12 +826,12 @@ export class Anybody extends EventEmitter { const theme = themes[this.random(0, themes.length - 1)] return { - bg: hslToRgb(randHSL(bodyThemes[theme].bg, this.random)), - core: hslToRgb(randHSL(bodyThemes[theme].cr, this.random)), - fg: hslToRgb(randHSL(bodyThemes[theme].fg, this.random)) + bg: hslToRgb(randHSL(bodyThemes[theme].bg, this.random.bind(this))), + core: hslToRgb(randHSL(bodyThemes[theme].cr, this.random.bind(this))), + fg: hslToRgb(randHSL(bodyThemes[theme].fg, this.random.bind(this))) } } else { - return randHSL([undefined, '90-100', '55-60'], this.random) + return randHSL([undefined, '90-100', '55-60'], this.random.bind(this)) } // const seedtype = typeof seed // if (seedtype !== 'string' && seedtype !== 'number') { @@ -848,7 +848,7 @@ export class Anybody extends EventEmitter { // return result } - random = (min, max, rng = this.rng) => { + random(min, max, rng = this.rng) { return rng.nextInt(min, max) // return Math.floor(Math.random() * (upper - lower + 1)) + lower; } diff --git a/src/visuals.js b/src/visuals.js index f95ae43e..0b858572 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1051,13 +1051,13 @@ export const Visuals = { // } }, - drawBody(x, y, v, radius, body, hero = false) { + drawBody(x, y, v, radius, body) { this.moveAndRotate_PopAfter(this.bodiesGraphic, x, y, v) // y-offset of face relative to center // const offset = this.getOffset(radius) - if (body.bodyIndex === 0 || hero) { + if (body.bodyIndex === 0 || (this.paused && body.bodyIndex < 3)) { // draw hero const size = Math.floor(body.radius * BODY_SCALE * 2.66) @@ -1080,45 +1080,45 @@ export const Visuals = { return actualRadius * 4 + this.radiusMultiplyer }, - // drawBodiesLooped(body, radius, drawFunction) { - // drawFunction = drawFunction.bind(this) - // drawFunction(body.position.x, body.position.y, body.velocity, radius, body) - - // // let loopedX = false, - // // loopedY = false, - // // loopX = body.position.x, - // // loopY = body.position.y - // // const loopGap = radius / 2 - - // // // crosses right, draw on left - // // if (body.position.x > this.windowWidth - loopGap) { - // // loopedX = true - // // loopX = body.position.x - this.windowWidth - // // drawFunction(loopX, body.position.y, body.velocity, radius, body, true) - // // // crosses left, draw on right - // // } else if (body.position.x < loopGap) { - // // loopedX = true - // // loopX = body.position.x + this.windowWidth - // // drawFunction(loopX, body.position.y, body.velocity, radius, body, true) - // // } + drawBodiesLooped(body, radius, drawFunction) { + drawFunction = drawFunction.bind(this) + drawFunction(body.position.x, body.position.y, body.velocity, radius, body) + + // let loopedX = false, + // loopedY = false, + // loopX = body.position.x, + // loopY = body.position.y + // const loopGap = radius / 2 + + // // crosses right, draw on left + // if (body.position.x > this.windowWidth - loopGap) { + // loopedX = true + // loopX = body.position.x - this.windowWidth + // drawFunction(loopX, body.position.y, body.velocity, radius, body, true) + // // crosses left, draw on right + // } else if (body.position.x < loopGap) { + // loopedX = true + // loopX = body.position.x + this.windowWidth + // drawFunction(loopX, body.position.y, body.velocity, radius, body, true) + // } - // // // crosses bottom, draw on top - // // if (body.position.y > this.windowHeight - loopGap) { - // // loopedY = true - // // loopY = body.position.y - this.windowHeight - // // drawFunction(body.position.x, loopY, body.velocity, radius, body, true) - // // // crosses top, draw on bottom - // // } else if (body.position.y < loopGap) { - // // loopedY = true - // // loopY = body.position.y + this.windowHeight - // // drawFunction(body.position.x, loopY, body.velocity, radius, body, true) - // // } + // // crosses bottom, draw on top + // if (body.position.y > this.windowHeight - loopGap) { + // loopedY = true + // loopY = body.position.y - this.windowHeight + // drawFunction(body.position.x, loopY, body.velocity, radius, body, true) + // // crosses top, draw on bottom + // } else if (body.position.y < loopGap) { + // loopedY = true + // loopY = body.position.y + this.windowHeight + // drawFunction(body.position.x, loopY, body.velocity, radius, body, true) + // } - // // // crosses corner, draw opposite corner - // // if (loopedX && loopedY) { - // // drawFunction(loopX, loopY, body.velocity, radius, body, true) - // // } - // }, + // // crosses corner, draw opposite corner + // if (loopedX && loopedY) { + // drawFunction(loopX, loopY, body.velocity, radius, body, true) + // } + }, // TODO: add this back as part of a end game animation drawWitheringBodies() { @@ -1209,13 +1209,7 @@ export const Visuals = { (b) => b.bodyIndex == body.bodyIndex )[0]?.radius const radius = this.getBodyRadius(bodyRadius) - this.drawBody( - body.position.x, - body.position.y, - body.velocity, - radius, - body - ) + this.drawBodiesLooped(body, radius, this.drawBody) const bodyCopy = JSON.parse( JSON.stringify( @@ -1272,15 +1266,7 @@ export const Visuals = { body.position.y + yWobble ) bodyCopy.velocity = this.p.createVector(body.velocity.x, body.velocity.y) - this.drawBody( - body.position.x, - body.position.y, - body.velocity, - radius, - body, - body.bodyIndex < 3 - ) - + this.drawBodiesLooped(bodyCopy, radius, this.drawBody) this.bodiesGraphic.pop() } From 52ff9b0fa5014707f70de40528666e5c1fe693d2 Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 27 Jun 2024 22:23:54 -0700 Subject: [PATCH 10/54] fix --- src/calculations.js | 1 + src/visuals.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/calculations.js b/src/calculations.js index 3dcf67f7..4f60bd2f 100644 --- a/src/calculations.js +++ b/src/calculations.js @@ -419,6 +419,7 @@ export const Calculations = { newBody.c = body.c newBody.bodyIndex = body.bodyIndex newBody.seed = body.seed + // newBody.faceIndex = body.faceIndex bigBodies.push(newBody) diff --git a/src/visuals.js b/src/visuals.js index 0b858572..8ff1a442 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -189,7 +189,7 @@ export const Visuals = { // } // } - if (!this.firstFrame && !this.paused) { + if (!this.paused) { this.drawBodies() } else { this.drawPauseBodies() From 3dcb66ac05041a5b07700ccf2d51f0190d451179 Mon Sep 17 00:00:00 2001 From: psugihara Date: Fri, 28 Jun 2024 09:03:46 -0700 Subject: [PATCH 11/54] generalize body copying to make adding / removing keys a little simpler --- src/calculations.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/calculations.js b/src/calculations.js index 4f60bd2f..2cd51890 100644 --- a/src/calculations.js +++ b/src/calculations.js @@ -402,10 +402,11 @@ export const Calculations = { convertBodiesToBigInts(bodies) { const bigBodies = [] - // const maxVectorScaled = this.convertFloatToScaledBigInt(this.vectorLimit) + + const skipCopying = ['px', 'py', 'vx', 'vy'] for (let i = 0; i < bodies.length; i++) { const body = bodies[i] - const newBody = { position: {}, velocity: {}, radius: null } + const newBody = {} newBody.position.x = body.px || this.convertFloatToScaledBigInt(body.position.x) @@ -416,11 +417,14 @@ export const Calculations = { newBody.velocity.y = body.vy || this.convertFloatToScaledBigInt(body.velocity.y) newBody.radius = this.convertFloatToScaledBigInt(body.radius) - newBody.c = body.c - newBody.bodyIndex = body.bodyIndex - newBody.seed = body.seed - // newBody.faceIndex = body.faceIndex + // copy over any other properties on body + for (const key in body) { + if (typeof newBody[key] !== 'undefined' || skipCopying.includes(key)) + continue + const value = body[key] + newBody[key] = value + } bigBodies.push(newBody) } From ebc247fab37df81176944ec1fdd01a3c34c2535b Mon Sep 17 00:00:00 2001 From: psugihara Date: Fri, 28 Jun 2024 09:08:38 -0700 Subject: [PATCH 12/54] fix --- src/calculations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calculations.js b/src/calculations.js index 2cd51890..c910bb21 100644 --- a/src/calculations.js +++ b/src/calculations.js @@ -406,7 +406,7 @@ export const Calculations = { const skipCopying = ['px', 'py', 'vx', 'vy'] for (let i = 0; i < bodies.length; i++) { const body = bodies[i] - const newBody = {} + const newBody = { position: {}, velocity: {} } newBody.position.x = body.px || this.convertFloatToScaledBigInt(body.position.x) From b07f9f093bf52c43ddce04b8e1405eced29b801d Mon Sep 17 00:00:00 2001 From: psugihara Date: Fri, 28 Jun 2024 09:08:43 -0700 Subject: [PATCH 13/54] delete unused --- src/anybody.js | 40 +----- src/visuals.js | 324 ------------------------------------------------- 2 files changed, 2 insertions(+), 362 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 235c1c15..f2b8655f 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -487,7 +487,7 @@ export class Anybody extends EventEmitter { this.setOptions(options) } this.clearValues() - // this.sound?.stop() + this.sound?.stop() this.sound?.playStart() this.init() this.draw() @@ -503,7 +503,6 @@ export class Anybody extends EventEmitter { setStatsText = async (stats) => { const statLines = [ - // `total bodies: ${stats.bodiesIncluded}`, this.doubleTextInverted(`¸♩·¯·♬¸¸♬·¯·♩¸¸♪¯`), `${stats.bodiesIncluded - 1} bodies cleared`, `in ${stats.timeTook} sec 🐎`, @@ -512,16 +511,6 @@ export class Anybody extends EventEmitter { ] const toShow = statLines.join('\n') this.statsText = toShow - // for (let i = 0; i < toShow.length; i++) { - // await new Promise((resolve) => setTimeout(resolve, 50)) - // this.statsText = toShow.slice(0, i + 1) - // this.sound?.playStat() - // // play a sound on new line - // if (toShow[i] == '\n') { - // await new Promise((resolve) => setTimeout(resolve, 800)) - // this.sound?.playStat() - // } - // } await this.setShowPlayAgain(1000) this.sound?.playSuccess() @@ -617,31 +606,20 @@ export class Anybody extends EventEmitter { const missileInits = [] // TODO: what about when the game begins with a missileInit that isn't in corner? - // console.log('finish') - // console.dir( - // { - // alreadyRun: this.alreadyRun, - // stopEvery: this.stopEvery, - // missileInits: this.missileInits - // }, - // { depth: null } - // ) if (this.mode == 'game') { let missileIndex = 0 for (let i = this.alreadyRun; i < this.alreadyRun + this.stopEvery; i++) { if (this.missileInits[missileIndex]?.step == i) { - // console.log('step == i', i) const missile = this.missileInits[missileIndex] missileInits.push([missile.vx, missile.vy, missile.radius]) missileIndex++ } else { - // console.log('else it starts from corner') missileInits.push([maxVectorScaled, maxVectorScaled, '0']) } } missileInits.push([maxVectorScaled, maxVectorScaled, '0']) } - // console.log('first missile: ', this.missileInits[0], this.alreadyRun) + let inflightMissile = this.missileInits[0]?.step == this.alreadyRun ? this.missileInits[0] @@ -833,24 +811,10 @@ export class Anybody extends EventEmitter { } else { return randHSL([undefined, '90-100', '55-60'], this.random.bind(this)) } - // const seedtype = typeof seed - // if (seedtype !== 'string' && seedtype !== 'number') { - // seed = seed.toHexString() - // } else if (seedtype == 'number') { - // seed = seed.toString(16) - // } - // const blocker = 0xffff - // const color = (BigInt(seed) & BigInt(blocker)) % 360n - // const saturation = ((BigInt(seed) >> 16n) & BigInt(blocker)) % 100n - // const lightness = (((BigInt(seed) >> 32n) & BigInt(blocker)) % 40n) + 40n - // const result = `hsla(${color.toString()}, ${saturation.toString()}%, ${lightness.toString()}%,${replaceOpacity ? '1' : this.opac})` - - // return result } random(min, max, rng = this.rng) { return rng.nextInt(min, max) - // return Math.floor(Math.random() * (upper - lower + 1)) + lower; } randomColor(min = 0, max = 359, rng = this.rng) { diff --git a/src/visuals.js b/src/visuals.js index 8ff1a442..29bb9a2f 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -445,14 +445,6 @@ export const Visuals = { // } }, - // tintImage(img, color) { - // const g = this.p.createGraphics(img.width, img.height) - // const cc = this.getTintFromColor(color) - // g.tint(cc[0], cc[1], cc[2], cc[3] * 255) - // g.image(img, 0, 0) - // return g - // }, - drawStaticBg() { const bw = true @@ -1000,41 +992,6 @@ export const Visuals = { this.bodiesGraphic.pop() }, - // getTintFromColor(c) { - // const cc = c - // .split(',') - // .map((c) => parseFloat(c.replace(')', '').replace('hsla(', ''))) - // return [cc[0], cc[1], cc[2], cc[2]] - // }, - - // drawBodyStyle1(radius, body, offset) { - // this.bodiesGraphic.noStroke() - // let c = - // body.radius !== 0 ? body.c : this.replaceOpacity(body.c, this.deadOpacity) - // // if (body.bodyIndex == 0) { - // // c = 'white' - // // } - // this.bodiesGraphic.fill(c) - // // const scale = 1 - // // const foo = this.p.createGraphics(radius / scale, radius / scale) - // // foo.noStroke() - // // foo.fill(c) - // // foo.ellipse( - // // radius / scale / 2, - // // radius / scale / 2, - // // radius / scale, - // // radius / scale - // // ) - // // this.bodiesGraphic.image( - // // foo, - // // -radius / 2, - // // -radius / 2 - offset, - // // radius, - // // radius - // // ) - // this.bodiesGraphic.ellipse(0, offset, radius) - // }, - moveAndRotate_PopAfter(graphic, x, y /*v*/) { graphic.push() graphic.translate(x, y) @@ -1275,287 +1232,6 @@ export const Visuals = { this.bodiesGraphic.clear() }, - // drawBorder() { - // // drawClock - // const clockCenter = this.windowWidth / 2 - - // // const radialStep1 = (this.frames / (this.chunk * 1) / 255) * 180 + 270 % 360 - // // const clockRadius = this.windowWidth - // // const clockX = clockCenter + clockRadius * Math.cos(radialStep1 * Math.PI / 180) - // // const clockY = clockCenter + clockRadius * Math.sin(radialStep1 * Math.PI / 180) - // // this.bodiesGraphic.stroke(this.getBW()) - // // this.bodiesGraphic.noStroke() - // // this.bodiesGraphic.fill(this.getNotGrey()) - // // this.bodiesGraphic.ellipse(clockX, clockY, 100, 100) - - // let size = this.windowWidth / Math.PI - // const radialStep2 = - // (this.frames / (this.chunk * 1) / 255) * 360 + (270 % 360) - // const clockRadius2 = this.windowWidth / 2 + size / 4 - - // const clockX2 = - // clockCenter + clockRadius2 * Math.cos((radialStep2 * Math.PI) / 180) - // const clockY2 = - // clockCenter + clockRadius2 * Math.sin((radialStep2 * Math.PI) / 180) - // // this.bodiesGraphic.stroke(this.getBW()) - // this.bodiesGraphic.noStroke() - // // this.bodiesGraphic.stroke('white') - // this.bodiesGraphic.fill(this.getGrey()) - // // if (size < 0) { - // // size = 0 - // // } - // this.bodiesGraphic.ellipse(clockX2, clockY2, size, size) - // }, - - // getAngledImage(body) { - // const graphic = this.p.createGraphics(this.windowWidth, this.windowHeight) - // graphic.push() - // graphic.translate(body.position.x, body.position.y) - // var angle = body.velocity.heading() + graphic.PI / 2 - // graphic.rotate(angle) - - // if (!this.eyes) { - // this.eyes = this.p.loadImage('/eyes-3.png') - // } - // const size = 6 - // graphic.image( - // this.eyes, - // -body.radius * (size / 2), - // -body.radius * (size / 2), - // body.radius * size, - // body.radius * size - // ) - - // graphic.pop() - // graphic.push() - // graphic.translate(body.position.x, body.position.y) - // var angle2 = body.velocity.heading() + graphic.PI / 2 - // graphic.rotate(angle2) - // graphic.pop() - // return graphic - // }, - - // getAngledBody(body, finalColor) { - // // rotate by velocity - // this.p.push() - // this.p.translate(body.position.x, body.position.y) - // var angle = body.velocity.heading() + this.p.PI / 2 - // this.p.rotate(angle) - - // this.p.strokeWeight(0) - // // stroke("white") - // this.p.fill(finalColor) - // // Calculate the vertices of the equilateral triangle - // let x1 = body.radius * 4 * this.p.cos(this.p.PI / 6) - // let y1 = body.radius * 4 * this.p.sin(this.p.PI / 6) - - // let x2 = body.radius * 4 * this.p.cos(this.p.PI / 6 + this.p.TWO_PI / 3) - // let y2 = body.radius * 4 * this.p.sin(this.p.PI / 6 + this.p.TWO_PI / 3) - - // let x3 = - // body.radius * 4 * this.p.cos(this.p.PI / 6 + (2 * this.p.TWO_PI) / 3) - // let y3 = - // body.radius * 4 * this.p.sin(this.p.PI / 6 + (2 * this.p.TWO_PI) / 3) - - // this.p.triangle(x1, y1, x2, y2, x3, y3) - // this.p.pop() - - // this.p.stroke('white') - // this.p.strokeWeight(1) - // this.p.push() - // this.p.translate(body.position.x, body.position.y) - // var angle2 = body.velocity.heading() + this.p.PI / 2 - // this.p.rotate(angle2) - // this.p.pop() - // }, - - drawTailStyle1(/*x, y, v, radius, finalColor, offset*/) { - return - // finalColor = finalColor.replace(this.opac, '1') - // this.p.push() - // this.p.translate(x, y) - // this.p.rotate(v.heading() + this.p.PI / 2) - - // // this.p.rotate(angle) - // this.p.fill(finalColor) - // this.p.stroke(finalColor) - // // this.p.strokeWeight(10) - // // this.p.noFill() - // this.p.ellipse(0, offset, radius * 1.2) - - // // this.p.image(this.drawTails[id], -radius / 2, -radius) - // this.p.pop() - }, - - // drawTailStyleGhost(x, y, v, radius, finalColor) { - // // ghost version - - // const id = radius + '-' + finalColor - // if (!this.tailGraphics) { - // this.tailGraphics = {} - // } - // if (!this.tailGraphics || this.tailGraphics[id] == undefined) { - // this.tailGraphics[id] = this.p.createGraphics( - // this.windowWidth, - // this.windowHeight - // ) - // this.tailGraphics[id].noStroke() - // this.tailGraphics[id].fill(finalColor) - - // this.tailGraphics[id].beginShape() - // // this.tailGraphics[id].vertex(radius, 0) - // // this.tailGraphics[id].vertex(0, 0) - - // // this.p.arc(0, 0, radius, radius, this.p.PI, 2 * this.p.PI) - // const arcResolution = 20 - - // for (let j = 0; j < arcResolution; j++) { - // const ang = this.p.map(j, 0, arcResolution, 0, this.p.PI) - // const ax = radius / 2 + (this.p.cos(ang) * radius) / 2 - // const ay = (2 * radius) / 2 + (-1 * this.p.sin(ang) * radius) / 2 - // this.tailGraphics[id].vertex(ax, ay) - // } - - // // this.tailGraphics[id].fill('red') - // // this.tailGraphics[id].rect(0, 0, radius, radius / 2) - - // const bumps = 7 - // let bumpHeight = radius / 6 - // // let heightChanger = radius / 10 - // // const bumpHeightMax = radius / 5 - // // const bumpHeightMin = radius / 8 - // const startY = radius * 1 - // // this.tailGraphics[id].push() - // let remaindingWidth = radius - // for (let i = 0; i < bumps; i++) { - // let bumpWidth = radius / bumps - // // bumpHeight += heightChanger - // // if (bumpHeight > bumpHeightMax || bumpHeight < bumpHeightMin) { - // // heightChanger *= -1 - // // } - // let x = radius - remaindingWidth - // if (i % 2 == 1) { - // // this.tailGraphics[id].arc(x + bumpWidth / 2, startY, bumpWidth, bumpHeight, this.tailGraphics[id].PI, 0, this.tailGraphics[id].OPEN) - // for (let j = 0; j < arcResolution; j++) { - // const ang = this.p.map(j, 0, arcResolution, this.p.PI, 0) - // const ax = x + bumpWidth / 2 + (this.p.cos(ang) * bumpWidth) / 2 - // const ay = - // startY + bumpHeight + (-1 * this.p.sin(ang) * bumpHeight) / 2 - // this.tailGraphics[id].vertex(ax, ay) - // } - // } else { - // for (let j = 0; j < arcResolution; j++) { - // const ang = this.p.map(j, 0, arcResolution, this.p.PI, 0) - // const ax = x + bumpWidth / 2 + (this.p.cos(ang) * bumpWidth) / 2 - // const ay = startY + bumpHeight + (this.p.sin(ang) * bumpHeight) / 2 - // this.tailGraphics[id].vertex(ax, ay) - // } - // // this.tailGraphics[id].arc(x + bumpWidth / 2, startY + bumpWidth, bumpWidth, bumpHeight, 0, this.tailGraphics[id].PI, this.tailGraphics[id].OPEN) - // } - // remaindingWidth -= bumpWidth - // } - // this.tailGraphics[id].endShape(this.tailGraphics[id].CLOSE) - // // this.tailGraphics[id].pop() - // } - - // // this.tailGraphics[id].push() - // // this.tailGraphics[id].translate(x, y) - // var angle = v.heading() + this.p.PI / 2 - // // this.tailGraphics[id].rotate(angle) - // // this.tailGraphics[id].fill(finalColor) - // // this.tailGraphics[id].fill('rgba(255,0,0,1)') - // // this.tailGraphics[id].rect(0, 0, radius, radius / 4) - // // this.tailGraphics[id].pop() - // this.p.push() - // this.p.translate(x, y) - // this.p.rotate(angle) - // this.p.image(this.tailGraphics[id], -radius / 2, -radius) - // this.p.pop() - // }, - - // getOffset(radius) { - // return this.target == 'inside' ? 0 : radius / 1.5 - // }, - - // drawTails() { - // // if (this.allCopiesOfBodies && this.allCopiesOfBodies.length > 0) { - // // const allCopiesOfBodies = - // // this.allCopiesOfBodies[this.allCopiesOfBodies.length - 1] - // // const body = allCopiesOfBodies[0] - // // if (body.bodyIndex == 0) { - // // this.p.noFill() - // // this.p.stroke('white') - // // this.p.strokeWeight(10) - // // this.p.ellipse(body.position.x, body.position.y, body.radius * 10) - // // } - // // } - // for (let i = 0; i < this.allCopiesOfBodies.length; i++) { - // const copyOfBodies = this.allCopiesOfBodies[i] - // for (let j = 0; j < copyOfBodies.length; j++) { - // const body = copyOfBodies[j] - // if (body.bodyIndex == 0) continue - // if (this.gameOver || this.won) { - // if ( - // this.witheringBodies.filter((b) => b.bodyIndex == body.bodyIndex) - // .length > 0 - // ) - // continue - // } - // if (body.radius == 0) continue - // let c = - // body.radius !== 0 - // ? this.replaceOpacity(body.c, this.deadOpacity) - // : this.replaceOpacity(body.c, this.deadOpacity) - // this.p.fill(c) - // // if (this.mode == 'nft') { - // const bodyCopy = this.bodyCopies.filter( - // (b) => b.bodyIndex == body.bodyIndex - // )[0] - // const radius = this.getBodyRadius(bodyCopy.radius) * 1.1 - - // // this.p.ellipse(body.position.x, body.position.y, radius, radius) - // this.p.push() - // this.p.translate(body.position.x, body.position.y) - // this.p.rotate(body.velocity.heading() + this.p.PI / 2) - // // this.p.arc(0, 0, radius, radius, this.p.PI, 2 * this.p.PI) - // this.p.pop() - // const offset = this.getOffset(radius) - - // switch (body.tailStyle) { - // case 1: - // this.drawTailStyle1( - // body.position.x, - // body.position.y, - // body.velocity, - // radius, - // c, - // offset - // ) - // break - // case 'ghost': - // this.drawTailStyleGhost( - // body.position.x, - // body.position.y, - // body.velocity, - // radius, - // c, - // offset - // ) - // break - // default: - // this.drawTailStyle1( - // body.position.x, - // body.position.y, - // body.velocity, - // radius, - // c, - // offset - // ) - // } - // } - // } - // }, - replaceOpacity(c, opacity) { const isHSLA = c.includes('hsla') const prefix = isHSLA ? 'hsla' : 'rgba' From 1959c97a760b9cf99d7b5ffcd41d81bbffcf59ba Mon Sep 17 00:00:00 2001 From: psugihara Date: Fri, 28 Jun 2024 09:32:58 -0700 Subject: [PATCH 14/54] delete unused code --- src/anybody.js | 52 +----------- src/calculations.js | 156 ++-------------------------------- src/nft.js | 1 - src/visuals.js | 199 +------------------------------------------- 4 files changed, 13 insertions(+), 395 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index f2b8655f..fd35c719 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -10,7 +10,6 @@ import { loadFonts } from './fonts.js' import { Buttons } from './buttons.js' // import wc from './witness_calculator.js' -// const GAME_LENGTH = 60 // seconds const GAME_LENGTH_BY_LEVEL_INDEX = [10, 20, 30, 40, 50] const NORMAL_GRAVITY = 100 const proverTickIndex = { @@ -159,7 +158,6 @@ export class Anybody extends EventEmitter { globalStyle: 'default', // 'default', 'psycho' aimHelper: false, target: 'inside', // 'outside' or 'inside' - showLevels: false, // true or false faceRotation: 'mania', // 'time' or 'hitcycle' or 'mania' sfx: 'bubble', // 'space' or 'bubble' ownerPresent: false @@ -243,34 +241,11 @@ export class Anybody extends EventEmitter { this.startingFrame = this.alreadyRun this.stopEvery = this.test ? 20 : this.proverTickIndex(this.level + 1) // const vectorLimitScaled = this.convertFloatToScaledBigInt(this.vectorLimit) - this.loadImages() this.setPause(this.paused, true) this.storeInits() // this.prepareWitness() } - // async prepareWitness() { - // // const wasmFile = `/public/game_10_1.wasm` - // const wasmFile = new URL('./game_10_1.wasm', import.meta.url).href - // console.log({ wasmFile }) - // const response = await fetch(wasmFile) - // console.log({ response }) - // const buffer = await response.arrayBuffer() - // console.log({ buffer }) - // // let wasm = await fetch(new URL('./game_10_1.wasm', import.meta.url).href) - // // console.log({ wasm }) - // this.witnessCalculator = await wc(buffer) - // console.log({ witnessCalculator: this.witnessCalculator }) - // // const w = await witnessCalculator.calculateWitness(input, 0); - // // for (let i = 0; i < w.length; i++) { - // // console.log(w[i]); - // // } - // // const buff = await witnessCalculator.calculateWTNSBin(input, 0) - // // writeFile(process.argv[4], buff, function (err) { - // // if (err) throw err - // // }) - // } - async start() { loadFonts(this.p) this.addCSS() @@ -292,16 +267,8 @@ export class Anybody extends EventEmitter { } storeInits() { - // console.dir( - // { - // frames: this.frames, - // bodies: this.bodies.map((b) => (b.position.x, b.position.y)) - // }, - // { depth: null } - // ) this.bodyCopies = JSON.parse(JSON.stringify(this.bodies)) this.bodyInits = this.processInits(this.bodies) - // console.dir({ bodyInits: this.bodyInits }, { depth: null }) } processInits(bodies) { @@ -434,11 +401,7 @@ export class Anybody extends EventEmitter { } break case 'KeyR': - // confirm('Are you sure you want to restart?') && this.restart() - if (!this.gameOver) { - // this.startingBodies = 2 - } - this.restart() + this.restart(null, false) break case 'KeyP': this.setPause() @@ -450,7 +413,7 @@ export class Anybody extends EventEmitter { if (this.handledGameOver) return this.handledGameOver = true - // this.sound?.playGameOver({ won }) + this.sound?.playGameOver({ won }) this.gameOver = true this.won = won this.G = 2000 // make the badies dance @@ -487,7 +450,7 @@ export class Anybody extends EventEmitter { this.setOptions(options) } this.clearValues() - this.sound?.stop() + // this.sound?.stop() this.sound?.playStart() this.init() this.draw() @@ -546,12 +509,6 @@ export class Anybody extends EventEmitter { if (this.missiles.length == 0 && this.lastMissileCantBeUndone) { this.lastMissileCantBeUndone = false } - // const { bodies, missiles } = await this.circomStep( - // this.bodies, - // this.missiles - // ) - // this.bodies = bodies - // this.missiles = missiles || [] this.bodies = this.forceAccumulator(this.bodies) var results = this.detectCollision(this.bodies, this.missiles) this.bodies = results.bodies @@ -943,9 +900,6 @@ if (typeof window !== 'undefined') { window.Anybody = Anybody } -// function _smolr(a, b) { -// return a < b ? a : b -// } BigInt.prototype.toJSON = function () { return this.toString() } diff --git a/src/calculations.js b/src/calculations.js index c910bb21..48697872 100644 --- a/src/calculations.js +++ b/src/calculations.js @@ -1,6 +1,3 @@ -// these still use this: -// scalingFactor, vectorLimit, windowWidth, G, minDistanceSquared, bodies, bodyFinal, explosions, missiles - export const Calculations = { forceAccumulator(bodies = this.bodies) { bodies = this.convertBodiesToBigInts(bodies) @@ -9,85 +6,6 @@ export const Calculations = { return bodies }, - // async circomStep(bodies, missiles) { - // // console.log('incoming', { bodies, missiles }) - // // this.witnessCalculator = false - - // // const vectorLimitScaled = this.convertFloatToScaledBigInt(this.vectorLimit) - - // if (this.witnessCalculator) { - // bodies = this.convertBodiesToBigInts(bodies) - // missiles = this.convertBodiesToBigInts(missiles) - // // console.log({ bodies, missiles }) - // const witnessBodies = bodies.map((b) => { - // b = this.convertScaledBigIntBodyToArray(b) - // b[2] = BigInt(b[2]).toString() - // b[3] = BigInt(b[3]).toString() - // return b - // }) - // const empty = ['0', '0', '0', '0', '0'] - // const witnessMissiles = missiles.map((b) => { - // b = this.convertScaledBigIntBodyToArray(b) - // b[2] = BigInt(b[2]).toString() - // b[3] = BigInt(b[3]).toString() - // return b - // }) - // const startingMissileLength = witnessMissiles.length - // for (let i = 0; i < 2 - startingMissileLength; i++) { - // witnessMissiles.push(empty) - // } - // const startingLength = witnessBodies.length - // if (witnessBodies.length < 10) { - // for (let i = 0; i < 10 - startingLength; i++) { - // witnessBodies.push(empty) - // } - // } - - // // console.log({ - // // witnessBodies, - // // witnessMissiles: JSON.parse(JSON.stringify(witnessMissiles)) - // // }) - // const results = await this.witnessCalculator.calculateWitness( - // { bodies: witnessBodies, missiles: witnessMissiles }, - // 0 - // ) - // // console.log({ results }) - - // witnessMissiles[0][0] = results[results.length - 3].toString() - // witnessMissiles[0][1] = results[results.length - 4].toString() - // // console.log({ witnessMissilesUpdated: witnessMissiles }) - // const convertedMissile = this.convertScaledStringArrayToBody( - // witnessMissiles[0] - // ) - // // console.log({ convertedMissile }) - - // // console.log({ missilesConvertedBackToBodies: missiles }) - // if (missiles.length > 0) { - // missiles[0].position.x = convertedMissile.position.x - // missiles[0].position.y = convertedMissile.position.y - // missiles[0].radius = convertedMissile.radius - // missiles = this.convertBigIntsToBodies(missiles) - // } - - // // console.log({ results, missiles }) - // for (let i = 0; i < startingLength; i++) { - // const body = [] - // for (let j = 0; j < 5; j++) { - // body.push(results[1 + i * 5 + j]) - // } - // const convertedBody = this.convertScaledStringArrayToBody(body) - // bodies[i].position.x = convertedBody.position.x - // bodies[i].position.y = convertedBody.position.y - // bodies[i].velocity.x = convertedBody.velocity.x - // bodies[i].velocity.y = convertedBody.velocity.y - // bodies[i].radius = convertedBody.radius - // } - // bodies = this.convertBigIntsToBodies(bodies) - // } - // // console.log({ bodies, missiles }) - // return { bodies, missiles } - // }, - forceAccumulatorBigInts(bodies) { const vectorLimitScaled = this.convertFloatToScaledBigInt(this.vectorLimit) let accumulativeForces = [] @@ -100,22 +18,6 @@ export const Calculations = { for (let j = i + 1; j < bodies.length; j++) { const otherBody = bodies[j] const force = this.calculateForceBigInt(body, otherBody) - // const bodyVelocity = [ - // body.radius == 0n - // ? 0n - // : time * (force[0] / (body.radius / this.scalingFactor)), - // body.radius == 0n - // ? 0n - // : time * (force[1] / (body.radius / this.scalingFactor)) - // ] - // const otherBodyVelocity = [ - // otherBody.radius == 0n - // ? 0n - // : time * (-force[0] / (otherBody.radius / this.scalingFactor)), - // otherBody.radius == 0n - // ? 0n - // : time * (-force[1] / (otherBody.radius / this.scalingFactor)) - // ] const bodyVelocity = [time * force[0], time * force[1]] const otherBodyVelocity = [time * -force[0], time * -force[1]] @@ -126,16 +28,13 @@ export const Calculations = { ) } } - // console.log({ vectorLimitScaled }) + for (let i = 0; i < bodies.length; i++) { const body = bodies[i] const body_velocity = _addVectors( [body.velocity.x, body.velocity.y], accumulativeForces[i] - ) //.mult(friction); - // console.log('body.velocity.x', body.velocity.x) - // console.log('accumulativeForces[i][0]', accumulativeForces[i][0]) - // console.log('body_velocity[0]', body_velocity[0]) + ) body.velocity.x = body_velocity[0] body.velocity.y = body_velocity[1] const body_velocity_x_abs = @@ -150,30 +49,20 @@ export const Calculations = { body.velocity.y = (body_velocity_y_abs / body.velocity.y) * vectorLimitScaled } - // body.velocity.limit(speedLimit); + const body_position = _addVectors( [body.position.x, body.position.y], [body.velocity.x, body.velocity.y] ) - // console.log('unlimited new position of x = ', body.position.x) - // console.log('body.position.x', body.position.x) - // console.log('body.velocity.x', body.velocity.x) - // console.log('body_position[0]', body_position[0]) + body.position.x = body_position[0] body.position.y = body_position[1] } - // console.log('before limiter') - // console.dir({ bodies_0: this.convertScaledBigIntBodyToArray(bodies[0]) }, { depth: null }) - - // const xOffset = bodies[bodies.length - 1].position.x - // const yOffset = bodies[bodies.length - 1].position.y const scaledWindowWidth = this.convertFloatToScaledBigInt(this.windowWidth) for (let i = 0; i < bodies.length; i++) { const body = bodies[i] - // if (position == "static") { - // body.position = [body.position.x - xOffset + scaledWindowWidth / 2, body.position.y - yOffset + scaledWindowWidth / 2] - // } + if (body.position.x > scaledWindowWidth) { body.position.x = 0n } else if (body.position.x < 0n) { @@ -189,10 +78,7 @@ export const Calculations = { }, calculateBodyFinal() { - // const maxVectorScaled = this.convertFloatToScaledBigInt(this.vectorLimit) - // console.log(this.bodies.map((b) => b.bodyIndex.toString())) this.bodies.sort((a, b) => a.bodyIndex - b.bodyIndex) - // console.log(this.bodies.map((b) => b.bodyIndex.toString())) const bodiesAsBigInts = this.convertBodiesToBigInts(this.bodies) this.bodyFinal = bodiesAsBigInts.map((b) => { b = this.convertScaledBigIntBodyToArray(b) @@ -204,27 +90,20 @@ export const Calculations = { // Calculate the gravitational force between two bodies calculateForceBigInt(body1, body2) { - // console.log({ p }) const GScaled = BigInt(Math.floor(this.G * parseInt(this.scalingFactor))) - // console.log({ GScaled }) let minDistanceScaled = BigInt(this.minDistanceSquared) * this.scalingFactor ** 2n // when the original gets squared, the scaling factor gets squared - // console.log({ minDistanceScaled }) const position1 = body1.position const body1_position_x = position1.x - // console.log({ body1_position_x }) const body1_position_y = position1.y - // console.log({ body1_position_y }) const body1_radius = body1.radius const position2 = body2.position const body2_position_x = position2.x - // console.log({ body2_position_x }) const body2_position_y = position2.y - // console.log({ body2_position_y }) const body2_radius = body2.radius let dx = body2_position_x - body1_position_x @@ -232,52 +111,35 @@ export const Calculations = { const dxAbs = dx > 0n ? dx : -1n * dx const dyAbs = dy > 0n ? dy : -1n * dy - // console.log({ dx, dy }) - // console.log({ dxAbs, dyAbs }) - const dxs = dx * dx const dys = dy * dy - // console.log({ dxs, dys }) let distanceSquared const unboundDistanceSquared = dxs + dys - // console.log({ unboundDistanceSquared }) if (unboundDistanceSquared < minDistanceScaled) { distanceSquared = minDistanceScaled } else { distanceSquared = unboundDistanceSquared } let distance = _approxSqrt(distanceSquared) - // console.log({ distance }) - // console.log({ distanceSquared }) const bodies_sum = body1_radius == 0n || body2_radius == 0n ? 0n : (body1_radius + body2_radius) * 4n // NOTE: this could be tweaked as a variable for "liveliness" of bodies - // console.log({ bodies_sum }) const distanceSquared_with_avg_denom = distanceSquared * 2n // NOTE: this is a result of moving division to the end of the calculation - // console.log({ distanceSquared_with_avg_denom }) - const forceMag_numerator = GScaled * bodies_sum * this.scalingFactor // distancec should be divided by scaling factor but this preserves rounding with integer error - // console.log({ forceMag_numerator }) + const forceMag_numerator = GScaled * bodies_sum * this.scalingFactor // distance should be divided by scaling factor but this preserves rounding with integer error const forceDenom = distanceSquared_with_avg_denom * distance - // console.log({ forceDenom }) const forceXnum = dxAbs * forceMag_numerator - // console.log({ forceXnum }) const forceXunsigned = _approxDiv(forceXnum, forceDenom) - // console.log({ forceXunsigned }) const forceX = dx < 0n ? -forceXunsigned : forceXunsigned - // console.log({ forceX }) const forceYnum = dyAbs * forceMag_numerator - // console.log({ forceYnum }) const forceYunsigned = _approxDiv(forceYnum, forceDenom) - // console.log({ forceYunsigned }) const forceY = dy < 0n ? -forceYunsigned : forceYunsigned - // console.log({ forceY }) return [forceX, forceY] }, @@ -523,21 +385,19 @@ function _approxDist(x1, y1, x2, y2) { return distance } function _approxSqrt(n) { - // console.log({ n }) if (n == 0n) { return 0n } var lo = 0n var hi = n >> 1n var mid, midSquared - // console.log({ lo, hi }) + while (lo <= hi) { mid = (lo + hi) >> 1n // multiplication by multiplicative inverse is not what we want so we use >> - // console.log({ lo, mid, hi }) + // TODO: Make more accurate by checking if lo + hi is odd or even before bit shifting midSquared = mid * mid if (midSquared == n) { - // console.log(`final perfect`, { lo, mid, hi }) return mid // Exact square root found } else if (midSquared < n) { lo = mid + 1n // Adjust lower bound diff --git a/src/nft.js b/src/nft.js index fb297839..f5a1749f 100644 --- a/src/nft.js +++ b/src/nft.js @@ -13,7 +13,6 @@ q5.preload = () => { q5.setup = () => { window.anybody = new Anybody(q5, { mode: 'game', - // showLevels: true, // target: 'inside', // globalStyle: 'psycho', day: Math.floor(Math.random() * 10000000), diff --git a/src/visuals.js b/src/visuals.js index 29bb9a2f..6067c944 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -77,18 +77,6 @@ const FACE_SVGS = [ new URL('/public/bodies/faces/face14.svg', import.meta.url).href ] -// const FACE_DISTRESS_SVGS = [ -// new URL('/public/bodies/faces_distress/1.svg', import.meta.url).href, -// new URL('/public/bodies/faces_distress/2.svg', import.meta.url).href, -// new URL('/public/bodies/faces_distress/3.svg', import.meta.url).href -// ] - -// const FACE_CRY_SVGS = [ -// new URL('/public/bodies/faces_cry/1.svg', import.meta.url).href, -// new URL('/public/bodies/faces_cry/2.svg', import.meta.url).href, -// new URL('/public/bodies/faces_cry/3.svg', import.meta.url).href -// ] - const FACE_BLINK_SVGS = [ new URL('/public/bodies/faces_blink/1.svg', import.meta.url).href, new URL('/public/bodies/faces_blink/2.svg', import.meta.url).href, @@ -166,12 +154,10 @@ export const Visuals = { this.p5Frames++ this.p.noFill() - // this.p.textFont('Instrument Serif, serif') this.drawBg() if (this.globalStyle == 'psycho') { this.p.blendMode(this.p.DIFFERENCE) } - // this.drawTails() if (this.globalStyle == 'psycho') { this.p.blendMode(this.p.BLEND) @@ -223,7 +209,6 @@ export const Visuals = { this.drawMissiles() } this.drawExplosions() - // this.drawBodyOutlines() this.drawScore() @@ -231,13 +216,6 @@ export const Visuals = { const framesIsAtStopEveryInterval = (this.frames - this.startingFrame) % this.stopEvery == 0 const didNotJustPause = !this.justPaused - // console.log({ - // stopEvery: this.stopEvery, - // alreadyRun: this.alreadyRun, - // frames: this.frames, - // framesIsAtStopEveryInterval, - // frames_lt_timer: this.frames < this.timer - // }) const ranOutOfTime = this.frames - this.startingFrame + this.FPS >= this.timer @@ -247,7 +225,6 @@ export const Visuals = { this.handleGameOver({ won: false, ranOutOfTime, hitHeroBody }) } - // const timeHasntRunOut = this.frames - this.startingFrame <= this.timer if ( !this.firstFrame && notPaused && @@ -419,7 +396,7 @@ export const Visuals = { // this.windowHeight // ) - // // Grid lines + // // Grid lines, uncomment for visual debugging and alignment // const boxCount = 6 // // this.p.stroke('black') // this.p.stroke('white') @@ -445,64 +422,10 @@ export const Visuals = { // } }, - drawStaticBg() { - const bw = true - - // Fill the background with static noise - if (!this.staticBg) { - this.staticBg = this.p.createGraphics(this.windowWidth, this.windowHeight) - this.staticBg.loadPixels() - for (let x = 0; x < this.staticBg.width; x++) { - for (let y = 0; y < this.staticBg.height; y++) { - let colorValue - if (bw) { - const noiseValue = this.staticBg.noise(x * 0.01, y * 0.01) - colorValue = this.staticBg.map(noiseValue, 0, 1, 0, 255) - colorValue = this.staticBg.color(colorValue) - } else { - // const noiseValue = this.staticBg.noise(x * 0.01, y * 0.01) - const rNoise = this.staticBg.noise(x * 0.01, y * 0.01) // * 255 - const gNoise = this.staticBg.noise(x * 0.02, y * 0.02) // * 255 // Different scale for variation - const bNoise = this.staticBg.noise(x * 0.03, y * 0.03) // * 255 // Different scale for variation - const rColorValue = this.staticBg.map(rNoise, 0, 1.01, 0, 255) - const gColorValue = this.staticBg.map(gNoise, 0, 1.02, 0, 255) - const bColorValue = this.staticBg.map(bNoise, 0, 1.03, 0, 255) - colorValue = this.staticBg.color( - rColorValue, - gColorValue, - bColorValue - ) - } - this.staticBg.set(x, y, this.staticBg.color(colorValue)) - } - } - this.staticBg.updatePixels() - } - this.p.image(this.staticBg, 0, 0) - }, - drawSolidBg() { - this.p.background(255) - }, - getColorDir(chunk) { return Math.floor(this.frames / (255 * chunk)) % 2 == 0 }, - getBW() { - const dir = this.getColorDir(this.chunk) - const lowerHalf = Math.floor(this.frames / this.chunk) % 255 < 255 / 2 - if (dir && lowerHalf) { - return 'white' - } else if (!dir && !lowerHalf) { - return 'white' - } else if (!dir && lowerHalf) { - return 'black' - } else if (dir && !lowerHalf) { - return 'black' - } - // return ? 'white' : 'black' - }, - getGrey() { if (this.getColorDir(this.chunk)) { return 255 - (Math.floor(this.frames / this.chunk) % 255) @@ -511,14 +434,6 @@ export const Visuals = { } }, - getNotGrey() { - if (!this.getColorDir(this.chunk)) { - return 255 - (Math.floor(this.frames / this.chunk) % 255) - } else { - return Math.floor(this.frames / this.chunk) % 255 - } - }, - drawScore() { const { p } = this p.push() @@ -580,13 +495,7 @@ export const Visuals = { const xLeft = this.windowWidth / 2 - 300 const xRight = this.windowWidth / 2 + 300 const y = 374 + leading * i - // if (i === 3) { - // p.stroke('black') - // p.strokeWeight(4) - // p.line(xLeft, y, xRight, y) - // p.noStroke() - // barPadding = 20 - // } + for (const [j, stat] of line.split(':').entries()) { if (j === 0) { p.textAlign(p.LEFT, p.TOP) @@ -691,19 +600,10 @@ export const Visuals = { this.scaleX(this.p.mouseX), this.scaleX(this.p.mouseY) + crossHairSize ) - // // Calculate the length of the direction - // let len = this.p.sqrt(dirX * dirX + dirY * dirY) - - // // If the length is not zero, scale the direction to have a length of 100 - // if (len != 0) { - // dirX = (dirX / len) * 100 - // dirY = (dirY / len) * 100 - // } if (this.paused) return // Draw the line - // this.p.setLineDash([5, 15]) const drawingContext = this.p.canvas.getContext('2d') const chunk = this.windowWidth / 100 drawingContext.setLineDash([chunk]) @@ -773,78 +673,6 @@ export const Visuals = { } }, - paintAtOnce(n = this.paintSteps) { - this.bodiesGraphic ||= this.p.createGraphics( - this.windowWidth, - this.windowHeight - ) - - for (let i = 0; i < n; i++) { - const results = this.step(this.bodies, this.missiles) - this.bodies = results.bodies - this.missiles = results.missiles || [] - this.drawBodies(false) - this.drawWitheringBodies() - this.frames++ - } - - this.p.image(this.bodiesGraphic, 0, 0) - this.bodiesGraphic.clear() - }, - componentToHex(c) { - var hex = parseInt(c).toString(16) - return hex.length == 1 ? '0' + hex : hex - }, - - rgbToHex(r, g, b) { - return ( - '0x' + - this.componentToHex(r) + - this.componentToHex(g) + - this.componentToHex(b) - ) - }, - hexToRgb(hex) { - var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) - return result - ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16) - } - : null - }, - - invertColorRGB(c) { - throw new Error(`invert color is not meant for HSL colors (${c})`) - // let [r, g, b] = c.replace('rgba(', '').split(',').slice(0, 3) - // const hexColor = this.rgbToHex(r, g, b) - // const invert = (parseInt(hexColor) ^ 0xffffff).toString(16).padStart(6, '0') - // const invertRGB = this.hexToRgb(invert) - // // r = r - 255 - // // g = g - 255 - // // b = b - 255 - // const newColor = this.p.color(invertRGB.r, invertRGB.g, invertRGB.b) - // return newColor - }, - - // Function to apply mask color to the image - maskImage(img, maskColor) { - img.loadPixels() // Load the image's pixel data - - for (let i = 0; i < img.pixels.length; i += 4) { - if (img.pixels[i + 3] == 0) continue // Skip transparent pixels (alpha = 0 - // Replace RGB values with the mask color's RGB, preserve the original alpha - img.pixels[i] = maskColor[0] // R - img.pixels[i + 1] = maskColor[1] // G - img.pixels[i + 2] = maskColor[2] // B - img.pixels[i + 3] = 255 // TODO: could be 100% or 1 - // Alpha remains unchanged to preserve transparency - } - - img.updatePixels() // Update the image with the new pixel values - }, - isMissileClose(body) { const minDistance = 300 let closeEnough = false @@ -1027,10 +855,6 @@ export const Visuals = { } this.bodiesGraphic.pop() - - // if (this.showLevels) { - // this.drawLevels(radius, body, offset) - // } }, getBodyRadius(actualRadius) { @@ -1084,11 +908,6 @@ export const Visuals = { } const { p } = this - // draw a fake withering body for development - // if (this.witheringBodies.length === 0) { - // this.witheringBodies = [{ position: p.createVector(100, 100) }] - // } - this.bodiesGraphic ||= p.createGraphics(this.windowWidth, this.windowHeight) this.bodiesGraphic.drawingContext.msImageSmoothingEnabled = false @@ -1444,19 +1263,5 @@ export const Visuals = { } return this.lastFrameRate - }, - async loadImages() { - return - // this.starSVG ||= {} - // for (let i = 0; i < STAR_SVGS.length; i++) { - // const svg = STAR_SVGS[i] - // await new Promise((resolve) => { - // this.p.loadImage(svg, (img) => { - // this.starSVG[i + 1] = img - // resolve() - // }) - // }) - // } - // this.loaded = true } } From fdaa9248e24610e165647b1a6d7b4bc4c4144e3a Mon Sep 17 00:00:00 2001 From: psugihara Date: Fri, 28 Jun 2024 09:44:49 -0700 Subject: [PATCH 15/54] reverse ticker --- src/visuals.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/visuals.js b/src/visuals.js index c42b2c32..d26f87ac 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -530,10 +530,13 @@ export const Visuals = { p.textSize(200) p.textAlign(p.LEFT, p.TOP) p.textFont(fonts.dot) - const tickerSpeed = 120 / this.P5_FPS + const tickerSpeed = -120 / this.P5_FPS const textWidth = p.textWidth(doubleText) - if (!this.gameoverTickerX || this.gameoverTickerX + tickerSpeed >= 0) { - this.gameoverTickerX = -textWidth / 2 + if ( + !this.gameoverTickerX || + this.gameoverTickerX + tickerSpeed < -textWidth / 2 + ) { + this.gameoverTickerX = 0 } this.gameoverTickerX += tickerSpeed p.text( From 050cddbf6ce3dd34bcedef2fa972824aa1994c3d Mon Sep 17 00:00:00 2001 From: psugihara Date: Fri, 28 Jun 2024 09:50:07 -0700 Subject: [PATCH 16/54] pump framerate on gameover --- src/anybody.js | 3 +++ src/visuals.js | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/anybody.js b/src/anybody.js index 693b8fa9..41697220 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -198,6 +198,7 @@ export class Anybody extends EventEmitter { this.FPS = 25 this.P5_FPS_MULTIPLIER = 3 this.P5_FPS = this.FPS * this.P5_FPS_MULTIPLIER + this.p.frameRate(this.P5_FPS) this.timer = (this.level > 5 ? 60 : GAME_LENGTH_BY_LEVEL_INDEX[this.level - 1]) * this.FPS @@ -417,6 +418,8 @@ export class Anybody extends EventEmitter { this.gameOver = true this.won = won this.G = 2000 // make the badies dance + this.P5_FPS *= 3 + this.p.frameRate(this.P5_FPS) var dust = 0 var timeTook = 0 diff --git a/src/visuals.js b/src/visuals.js index d26f87ac..3546c1a2 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -530,7 +530,7 @@ export const Visuals = { p.textSize(200) p.textAlign(p.LEFT, p.TOP) p.textFont(fonts.dot) - const tickerSpeed = -120 / this.P5_FPS + const tickerSpeed = -200 / this.P5_FPS const textWidth = p.textWidth(doubleText) if ( !this.gameoverTickerX || From 90986f79c17eb1eb0edb65ceda3ccd05e7ca1022 Mon Sep 17 00:00:00 2001 From: psugihara Date: Tue, 2 Jul 2024 22:23:45 -0700 Subject: [PATCH 17/54] some rectangles --- src/anybody.js | 4 ++-- src/colors.js | 8 +++++++- src/visuals.js | 31 +++++++++++++++++++------------ 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 41697220..79e2a090 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -221,7 +221,7 @@ export class Anybody extends EventEmitter { this.p5Frames = 0 this.showIt = true this.justStopped = false - this.gameOver = false + this.gameOver = true this.firstFrame = true this.loaded = false this.showPlayAgain = false @@ -229,7 +229,7 @@ export class Anybody extends EventEmitter { this.statsText = '' this.hasStarted = false this.buttons = {} - this.won = false + this.won = true this.finalBatchSent = false this.solved = false } diff --git a/src/colors.js b/src/colors.js index ed04c02e..b098c5f5 100644 --- a/src/colors.js +++ b/src/colors.js @@ -1,3 +1,6 @@ +const iris_60 = 'rgba(88, 59, 209, 1)' +const iris_30 = 'rgba(146, 118, 255, 1)' + export const THEME = { bg: 'rgb(20,20,20)', fg: 'white', @@ -5,7 +8,10 @@ export const THEME = { pink: 'rgba(236, 205, 255, 1)', fuschia: 'rgba(160, 67, 232, 1)', red: 'rgba(255, 88, 88, 1)', - maroon: 'rgba(53, 20, 20, 1)' + maroon: 'rgba(53, 20, 20, 1)', + border: iris_60, + foreground: iris_60, + mutedForeground: iris_30 } // [hue, saturation, lightness] diff --git a/src/visuals.js b/src/visuals.js index 3546c1a2..dabcc877 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -178,7 +178,7 @@ export const Visuals = { if (!this.paused) { this.drawBodies() - } else { + } else if (!this.gameOver) { this.drawPauseBodies() } @@ -249,13 +249,13 @@ export const Visuals = { } }, drawPause() { - if (!(this.paused && fonts.dot)) return + if (!(this.paused && fonts.dot && !this.gameOver)) return + + // draw logo this.p.textFont(fonts.dot) this.p.fill(THEME.pink) this.p.textSize(200) this.p.textAlign(this.p.LEFT, this.p.TOP) - - // draw logo const titleY = this.windowHeight / 2 - 270 drawKernedText(this.p, 'Anybody', 46, titleY, 0.8) drawKernedText(this.p, 'Problem', 46, titleY + 240, 2) @@ -469,18 +469,25 @@ export const Visuals = { p.noStroke() p.fill('white') - p.textSize(128) - p.textAlign(p.CENTER, p.TOP) - p.text('SUCCESS', this.windowWidth / 2 - 8, 190) // adjust by 8 to center SF Pro weirdness + // logo at top + this.p.textFont(fonts.dot) + this.p.fill(THEME.pink) + this.p.textSize(60) + this.p.textAlign(this.p.LEFT, this.p.TOP) + drawKernedText(this.p, 'Anybody', 334, 22, 0.8) + drawKernedText(this.p, 'Problem', 640, 22, 2) - // draw a white box behind the stats, with border radius - p.fill('white') - p.rect(this.windowWidth / 2 - 320, 340, 640, 350, 20, 20, 20, 20) + // bordered boxes + p.fill('black') + p.stroke(THEME.border) + const gutter = 24 + p.rect(gutter, 104, this.windowWidth - gutter * 2, 144, 24) + p.rect(this.windowWidth / 2 - 320, 340, 640, 350, 24) // draw stats p.textSize(48) - p.textStyle(p.BOLD) - p.fill('black') + p.textFont(fonts.body) + p.fill(THEME.mutedForeground) for (const [i, line] of this.statsText.split('\n').entries()) { // print each stat line with left aligned label, right aligned stat if (line.match(/1x/)) { From 7cd9b1020b7ed8aeeff10c18eeb7a3ace0d0356c Mon Sep 17 00:00:00 2001 From: psugihara Date: Tue, 2 Jul 2024 23:06:08 -0700 Subject: [PATCH 18/54] bottom buttons --- src/buttons.js | 25 ++++++++++++++++++++++++- src/visuals.js | 44 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/buttons.js b/src/buttons.js index 5d87a84c..d14325ad 100644 --- a/src/buttons.js +++ b/src/buttons.js @@ -62,11 +62,17 @@ export const Buttons = { if (scale === 1) { p.fill(fg) p.textAlign(p.CENTER, p.CENTER) - p.text(text, x + width / 2, y + height / 2 + textSize * 0.05) + p.text( + text, + // tweak to center, somethign about the font + x + width / 2 + textSize * 0.13, + y + height / 2 + textSize * 0.05 + ) } p.pop() }, + // single button with a fat appearance (retry, start) drawFatButton(buttonOptions) { const { bottom } = buttonOptions const bottomPadding = bottom || 80 @@ -78,5 +84,22 @@ export const Buttons = { x: this.windowWidth / 2 - 275 / 2, ...buttonOptions }) + }, + + // buttons that are drawn at the bottom of the screen (win screen) + drawBottomButton(buttonOptions) { + const { columns, column } = buttonOptions + const gutter = 24 + const interButtonGutter = 6 + const frameWidth = this.windowWidth - 2 * gutter + const width = (frameWidth - (columns - 1) * interButtonGutter) / columns + this.drawButton({ + height: 84, + textSize: 44, + width, + y: this.windowHeight - gutter - 84, + x: gutter + column * (width + interButtonGutter), + ...buttonOptions + }) } } diff --git a/src/visuals.js b/src/visuals.js index dabcc877..45c9245f 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -482,7 +482,7 @@ export const Visuals = { p.stroke(THEME.border) const gutter = 24 p.rect(gutter, 104, this.windowWidth - gutter * 2, 144, 24) - p.rect(this.windowWidth / 2 - 320, 340, 640, 350, 24) + p.rect(gutter, 320, this.windowWidth - gutter * 2, 524, 24) // draw stats p.textSize(48) @@ -516,14 +516,40 @@ export const Visuals = { } // play again button - if (this.showPlayAgain) { - this.drawFatButton({ - text: 'RETRY', - onClick: () => this.restart(null, false), - fg: 'black', - bg: 'white' - }) - } + // if (this.showPlayAgain) { + this.drawBottomButton({ + text: 'RETRY', + onClick: () => this.restart(null, false), + fg: 'black', + bg: 'white', + columns: 4, + column: 0 + }) + this.drawBottomButton({ + text: 'RESTART', + onClick: () => this.restart(null, false), + fg: 'black', + bg: 'white', + columns: 4, + column: 1 + }) + this.drawBottomButton({ + text: 'RESTART', + onClick: () => this.restart(null, false), + fg: 'black', + bg: 'white', + columns: 4, + column: 2 + }) + this.drawBottomButton({ + text: 'RESTART', + onClick: () => this.restart(null, false), + fg: 'black', + bg: 'white', + columns: 4, + column: 3 + }) + // } p.pop() }, From 23a9fc7e100225b47660c1ff3fe27de9f075a9c1 Mon Sep 17 00:00:00 2001 From: psugihara Date: Wed, 3 Jul 2024 09:33:11 -0700 Subject: [PATCH 19/54] no stroke --- src/visuals.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/visuals.js b/src/visuals.js index 3546c1a2..e8da2ae1 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -256,6 +256,7 @@ export const Visuals = { this.p.textAlign(this.p.LEFT, this.p.TOP) // draw logo + this.p.noStroke() const titleY = this.windowHeight / 2 - 270 drawKernedText(this.p, 'Anybody', 46, titleY, 0.8) drawKernedText(this.p, 'Problem', 46, titleY + 240, 2) From 2a38084eece5935ba8425bbcc5ad007101b46529 Mon Sep 17 00:00:00 2001 From: evvvritt Date: Wed, 3 Jul 2024 13:25:54 -0400 Subject: [PATCH 20/54] global pixel density: devicePixelRatio, stroke = 2 --- src/anybody.js | 4 ++-- src/visuals.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 41697220..2265dc9e 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -138,7 +138,7 @@ export class Anybody extends EventEmitter { startingBodies: 1, windowWidth: 1000, windowHeight: 1000, - pixelDensity: 4, //4, // Math.min(4, 4 * (window.devicePixelRatio ?? 1)), + pixelDensity: window.devicePixelRatio, //4, // Math.min(4, 4 * (window.devicePixelRatio ?? 1)), scalingFactor: 10n ** 3n, minDistanceSquared: 200 * 200, G: NORMAL_GRAVITY, // Gravitational constant @@ -798,7 +798,7 @@ export class Anybody extends EventEmitter { prepareP5() { this.p.frameRate(this.P5_FPS) this.p.createCanvas(this.windowWidth, this.windowWidth) - // this.p.pixelDensity(this.pixelDensity) + this.p.pixelDensity(this.pixelDensity) this.p.background('white') } diff --git a/src/visuals.js b/src/visuals.js index 3546c1a2..72d153f9 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -708,12 +708,12 @@ export const Visuals = { .then((resp) => resp.text()) .then((svg) => { svg = fill ? replaceAttribute(svg, 'fill', fill) : svg - // svg = replaceAttribute(svg, 'stroke-width', '0') + svg = replaceAttribute(svg, 'stroke-width', '2') svg = 'data:image/svg+xml,' + encodeURIComponent(svg) this.p.loadImage(svg, (img) => { - const width = img.width * this.pixelDensity - const height = img.height * this.pixelDensity + const width = img.width + const height = img.height const foo = this.p.createGraphics(width, height) foo.pixelDensity(this.pixelDensity) From 51feb74040a3fcdc7517d4336f41df130ac6ba8d Mon Sep 17 00:00:00 2001 From: psugihara Date: Wed, 3 Jul 2024 13:40:25 -0700 Subject: [PATCH 21/54] date on start screen --- src/anybody.js | 1 + src/colors.js | 7 ++++++- src/visuals.js | 38 ++++++++++++++++++++++++++++++-------- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 2265dc9e..34999edc 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -232,6 +232,7 @@ export class Anybody extends EventEmitter { this.won = false this.finalBatchSent = false this.solved = false + this.date = new Date().toLocaleDateString() } // run once at initilization diff --git a/src/colors.js b/src/colors.js index ed04c02e..e9034508 100644 --- a/src/colors.js +++ b/src/colors.js @@ -1,3 +1,6 @@ +const iris_50 = 'rgba(121, 88, 255, 1)' +const iris_100 = 'rgba(25, 15, 66, 1)' + export const THEME = { bg: 'rgb(20,20,20)', fg: 'white', @@ -5,7 +8,9 @@ export const THEME = { pink: 'rgba(236, 205, 255, 1)', fuschia: 'rgba(160, 67, 232, 1)', red: 'rgba(255, 88, 88, 1)', - maroon: 'rgba(53, 20, 20, 1)' + maroon: 'rgba(53, 20, 20, 1)', + textFg: iris_50, + textBg: iris_100 } // [hue, saturation, lightness] diff --git a/src/visuals.js b/src/visuals.js index 0e319739..9f4d98c3 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -250,23 +250,45 @@ export const Visuals = { }, drawPause() { if (!(this.paused && fonts.dot)) return - this.p.textFont(fonts.dot) - this.p.fill(THEME.pink) - this.p.textSize(200) - this.p.textAlign(this.p.LEFT, this.p.TOP) + + const { p } = this + p.textFont(fonts.dot) + p.fill(THEME.pink) + p.textSize(200) + p.textAlign(p.LEFT, p.TOP) // draw logo - this.p.noStroke() + p.noStroke() const titleY = this.windowHeight / 2 - 270 - drawKernedText(this.p, 'Anybody', 46, titleY, 0.8) - drawKernedText(this.p, 'Problem', 46, titleY + 240, 2) + drawKernedText(p, 'Anybody', 46, titleY, 0.8) + drawKernedText(p, 'Problem', 46, titleY + 240, 2) this.drawFatButton({ text: 'PLAY', onClick: () => this.setPause(false), fg: THEME.fuschia, - bg: THEME.pink + bg: THEME.pink, + bottom: 120 }) + + // date + p.textFont(fonts.body) + p.textSize(24) + const dateWidth = p.textWidth(this.date) + const dateBgWidth = dateWidth + 48 + const dateBgHeight = 32 + const dateBottomY = this.windowHeight - 58 + p.fill(THEME.textBg) + p.rect( + this.windowWidth / 2 - dateBgWidth / 2, + dateBottomY - dateBgHeight / 2, + dateBgWidth, + dateBgHeight, + 20 + ) + p.textAlign(p.CENTER, p.CENTER) + p.fill(THEME.textFg) + p.text(this.date, this.windowWidth / 2, dateBottomY) }, drawBodyOutlines() { for (let i = 0; i < this.bodies.length; i++) { From 2a59e1180b2bfb6544de4db1cd1809673b1dbd1a Mon Sep 17 00:00:00 2001 From: psugihara Date: Wed, 3 Jul 2024 15:32:19 -0700 Subject: [PATCH 22/54] hero and buttons on win screen --- src/colors.js | 26 ++++++++++++++++++++ src/visuals.js | 67 ++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/src/colors.js b/src/colors.js index b098c5f5..26c1e89d 100644 --- a/src/colors.js +++ b/src/colors.js @@ -1,5 +1,13 @@ const iris_60 = 'rgba(88, 59, 209, 1)' const iris_30 = 'rgba(146, 118, 255, 1)' +const teal_50 = 'rgba(137, 255, 248, 1)' +const teal_75 = 'rgba(13, 61, 58, 1)' +const flame_50 = 'rgba(255, 88, 88, 1)' +const flame_75 = 'rgba(70, 12, 12, 1)' +const pink_50 = 'rgba(255, 105, 177, 1)' +const pink_75 = 'rgba(59, 29, 43, 1)' +const green_50 = 'rgba(125, 241, 115, 1)' +const green_75 = 'rgba(4, 53, 0, 1)' export const THEME = { bg: 'rgb(20,20,20)', @@ -62,6 +70,24 @@ export const themes = { fg: [undefined, '90', '60'] } } + }, + buttons: { + teal: { + fg: teal_50, + bg: teal_75 + }, + flame: { + fg: flame_50, + bg: flame_75 + }, + pink: { + fg: pink_50, + bg: pink_75 + }, + green: { + fg: green_50, + bg: green_75 + } } } diff --git a/src/visuals.js b/src/visuals.js index b25ea292..554ae48f 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1,5 +1,6 @@ import { hslToRgb, THEME } from './colors.js' import { fonts, drawKernedText } from './fonts.js' +import { themes } from './colors.js' const BODY_SCALE = 4 // match to calculations.js !! const WITHERING_STEPS = 3000 @@ -466,6 +467,21 @@ export const Visuals = { drawWinScreen() { const { p } = this + + const justEntered = this.winScreenLastVisibleFrame !== this.p5Frames - 1 + if (justEntered) { + this.winScreenVisibleForFrames = 0 + } + this.winScreenVisibleForFrames++ + this.winScreenLastVisibleFrame = this.p5Frames + + const entranceTime = 0.4 // seconds + + const scale = Math.min( + 1, + this.winScreenVisibleForFrames / (entranceTime * this.P5_FPS) + ) + p.push() p.noStroke() p.fill('white') @@ -475,16 +491,38 @@ export const Visuals = { this.p.fill(THEME.pink) this.p.textSize(60) this.p.textAlign(this.p.LEFT, this.p.TOP) - drawKernedText(this.p, 'Anybody', 334, 22, 0.8) - drawKernedText(this.p, 'Problem', 640, 22, 2) + const logoY = this.p.map(scale, 0, 1, -100, 22) + drawKernedText(this.p, 'Anybody', 334, logoY, 0.8) + drawKernedText(this.p, 'Problem', 640, logoY, 2) // bordered boxes p.fill('black') p.stroke(THEME.border) + p.strokeWeight(1) const gutter = 24 p.rect(gutter, 104, this.windowWidth - gutter * 2, 144, 24) p.rect(gutter, 320, this.windowWidth - gutter * 2, 524, 24) + // draw hero this.bodies[0] + const body = this.getDisplayHero() + const radius = this.getBodyRadius(body.radius) + const xWobble = + this.p.sin(this.p.frameCount / this.P5_FPS) * (5 + body.bodyIndex) + const yWobble = + this.p.cos(this.p.frameCount / this.P5_FPS + body.bodyIndex * 3) * + (6 + body.bodyIndex) + body.position = { + x: this.p.map(scale, 0, 1, -170, 170) + xWobble, + y: 170 + yWobble + } + this.bodiesGraphic ||= this.p.createGraphics( + this.windowWidth, + this.windowHeight + ) + this.drawBodiesLooped(body, radius, this.drawBody) + this.p.image(this.bodiesGraphic, 40, 30, 800, 800) + this.bodiesGraphic.clear() + // draw stats p.textSize(48) p.textFont(fonts.body) @@ -521,32 +559,28 @@ export const Visuals = { this.drawBottomButton({ text: 'RETRY', onClick: () => this.restart(null, false), - fg: 'black', - bg: 'white', + ...themes.buttons.teal, columns: 4, column: 0 }) this.drawBottomButton({ text: 'RESTART', onClick: () => this.restart(null, false), - fg: 'black', - bg: 'white', + ...themes.buttons.flame, columns: 4, column: 1 }) this.drawBottomButton({ text: 'RESTART', onClick: () => this.restart(null, false), - fg: 'black', - bg: 'white', + ...themes.buttons.pink, columns: 4, column: 2 }) this.drawBottomButton({ text: 'RESTART', onClick: () => this.restart(null, false), - fg: 'black', - bg: 'white', + ...themes.buttons.green, columns: 4, column: 3 }) @@ -555,6 +589,19 @@ export const Visuals = { p.pop() }, + getDisplayHero() { + const body = this.bodies[0] + const bodyCopy = JSON.parse( + JSON.stringify( + body, + (key, value) => (typeof value === 'bigint' ? value.toString() : value) // return everything else unchanged + ) + ) + bodyCopy.position = this.p.createVector(body.position.x, body.position.y) + bodyCopy.velocity = this.p.createVector(body.velocity.x, body.velocity.y) + return bodyCopy + }, + drawTicker({ text, bottom = false, fg }) { const doubleText = `${text} ${text} ` From eb3250bcab655fffc5fd0f63b3fda2887bae851c Mon Sep 17 00:00:00 2001 From: psugihara Date: Wed, 3 Jul 2024 15:55:53 -0700 Subject: [PATCH 23/54] show share flag --- src/visuals.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/visuals.js b/src/visuals.js index 554ae48f..46a6e97a 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -554,37 +554,38 @@ export const Visuals = { } } - // play again button - // if (this.showPlayAgain) { + // bottom buttons + const buttonCount = this.showShare ? 4 : 3 this.drawBottomButton({ text: 'RETRY', onClick: () => this.restart(null, false), ...themes.buttons.teal, - columns: 4, + columns: buttonCount, column: 0 }) this.drawBottomButton({ text: 'RESTART', onClick: () => this.restart(null, false), ...themes.buttons.flame, - columns: 4, + columns: buttonCount, column: 1 }) + if (this.showShare) { + this.drawBottomButton({ + text: 'SHARE', + onClick: () => this.restart(null, false), + ...themes.buttons.pink, + columns: buttonCount, + column: 2 + }) + } this.drawBottomButton({ - text: 'RESTART', - onClick: () => this.restart(null, false), - ...themes.buttons.pink, - columns: 4, - column: 2 - }) - this.drawBottomButton({ - text: 'RESTART', + text: 'NEXT', onClick: () => this.restart(null, false), ...themes.buttons.green, - columns: 4, - column: 3 + columns: buttonCount, + column: buttonCount - 1 }) - // } p.pop() }, From 7b6dea36ed09a23bb3b63281970d23feaeeca160 Mon Sep 17 00:00:00 2001 From: psugihara Date: Wed, 3 Jul 2024 15:58:55 -0700 Subject: [PATCH 24/54] science --- src/visuals.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/visuals.js b/src/visuals.js index 46a6e97a..b92b00db 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -512,15 +512,15 @@ export const Visuals = { this.p.cos(this.p.frameCount / this.P5_FPS + body.bodyIndex * 3) * (6 + body.bodyIndex) body.position = { - x: this.p.map(scale, 0, 1, -170, 170) + xWobble, - y: 170 + yWobble + x: this.p.map(scale, 0, 1, -140, 210) + xWobble, + y: 220 + yWobble } this.bodiesGraphic ||= this.p.createGraphics( this.windowWidth, this.windowHeight ) this.drawBodiesLooped(body, radius, this.drawBody) - this.p.image(this.bodiesGraphic, 40, 30, 800, 800) + this.p.image(this.bodiesGraphic, 0, 0, 800, 800) this.bodiesGraphic.clear() // draw stats From 0b4ec0f30f40369d44e997bf64c103f228b30fd5 Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 4 Jul 2024 15:55:19 -0700 Subject: [PATCH 25/54] fix cursor --- src/visuals.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/visuals.js b/src/visuals.js index b92b00db..0199273e 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -201,6 +201,7 @@ export const Visuals = { } this.drawPause() + this.drawScore() if ( this.mode == 'game' && @@ -212,8 +213,6 @@ export const Visuals = { } this.drawExplosions() - this.drawScore() - const notPaused = !this.paused const framesIsAtStopEveryInterval = (this.frames - this.startingFrame) % this.stopEvery == 0 && @@ -687,7 +686,7 @@ export const Visuals = { this.scaleX(this.p.mouseY) + crossHairSize ) - if (this.paused) return + if (this.paused || this.gameOver) return // Draw the line const drawingContext = this.p.canvas.getContext('2d') From a7230cee7345af19dbd61a5e34c6ae17cee942bf Mon Sep 17 00:00:00 2001 From: psugihara Date: Fri, 5 Jul 2024 10:39:18 -0700 Subject: [PATCH 26/54] upper box text --- src/anybody.js | 3 +++ src/colors.js | 16 +++++++++++++--- src/visuals.js | 18 +++++++++++++++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 76d275f7..789f9cde 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -161,6 +161,7 @@ export class Anybody extends EventEmitter { target: 'inside', // 'outside' or 'inside' faceRotation: 'mania', // 'time' or 'hitcycle' or 'mania' sfx: 'bubble', // 'space' or 'bubble' + owner: 'billyrennekamp.eth', ownerPresent: false } // Merge the default options with the provided options @@ -384,6 +385,7 @@ export class Anybody extends EventEmitter { } } + if (this.paused || this.gameOver) return this.missileClick(x, y) } @@ -803,6 +805,7 @@ export class Anybody extends EventEmitter { } missileClick(x, y) { + if (this.gameOver) return if (this.paused) { this.setPause(false) return diff --git a/src/colors.js b/src/colors.js index 26c1e89d..a65bce60 100644 --- a/src/colors.js +++ b/src/colors.js @@ -13,13 +13,23 @@ export const THEME = { bg: 'rgb(20,20,20)', fg: 'white', bodiesTheme: 'default', + border: iris_60, + // colors + lime: 'rgba(125, 241, 115, 1)', pink: 'rgba(236, 205, 255, 1)', fuschia: 'rgba(160, 67, 232, 1)', red: 'rgba(255, 88, 88, 1)', maroon: 'rgba(53, 20, 20, 1)', - border: iris_60, - foreground: iris_60, - mutedForeground: iris_30 + iris_30, + iris_60, + teal_50, + teal_75, + flame_50, + flame_75, + pink_50, + pink_75, + green_50, + green_75 } // [hue, saturation, lightness] diff --git a/src/visuals.js b/src/visuals.js index 0199273e..ff8848f8 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -522,10 +522,22 @@ export const Visuals = { this.p.image(this.bodiesGraphic, 0, 0, 800, 800) this.bodiesGraphic.clear() - // draw stats - p.textSize(48) + // upper box text + p.textSize(32) + p.noStroke() p.textFont(fonts.body) - p.fill(THEME.mutedForeground) + p.fill(THEME.iris_60) + + // upper box text - labels + p.text('problem', 330, 132) + p.text('solver', 330, 192) + + // upper box text - values + p.textSize(54) + p.fill(THEME.iris_30) + p.text('JAN-01-2024', 454, 114) + p.text('okwme.eth', 454, 174) + for (const [i, line] of this.statsText.split('\n').entries()) { // print each stat line with left aligned label, right aligned stat if (line.match(/1x/)) { From 85650b4461e6ddcfbd87d8230eb60d6ab0926b04 Mon Sep 17 00:00:00 2001 From: psugihara Date: Fri, 5 Jul 2024 13:42:20 -0700 Subject: [PATCH 27/54] win screen: draw values in table --- src/anybody.js | 2 +- src/visuals.js | 169 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 130 insertions(+), 41 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 789f9cde..94b73054 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -230,7 +230,7 @@ export class Anybody extends EventEmitter { this.statsText = '' this.hasStarted = false this.buttons = {} - this.won = true + this.won = false this.finalBatchSent = false this.solved = false } diff --git a/src/visuals.js b/src/visuals.js index ff8848f8..c41fd6da 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -5,6 +5,7 @@ import { themes } from './colors.js' const BODY_SCALE = 4 // match to calculations.js !! const WITHERING_STEPS = 3000 const GAME_LENGTH_BY_LEVEL_INDEX = [10, 20, 30, 40, 50] +const LEVELS = GAME_LENGTH_BY_LEVEL_INDEX.length const rot = { fg: { @@ -486,32 +487,38 @@ export const Visuals = { p.fill('white') // logo at top - this.p.textFont(fonts.dot) - this.p.fill(THEME.pink) - this.p.textSize(60) - this.p.textAlign(this.p.LEFT, this.p.TOP) - const logoY = this.p.map(scale, 0, 1, -100, 22) - drawKernedText(this.p, 'Anybody', 334, logoY, 0.8) - drawKernedText(this.p, 'Problem', 640, logoY, 2) + p.textFont(fonts.dot) + p.fill(THEME.pink) + p.textSize(60) + p.textAlign(p.LEFT, p.TOP) + const logoY = p.map(scale, 0, 1, -100, 22) + drawKernedText(p, 'Anybody', 334, logoY, 0.8) + drawKernedText(p, 'Problem', 640, logoY, 2) // bordered boxes p.fill('black') p.stroke(THEME.border) p.strokeWeight(1) const gutter = 24 + const middleBoxY = 320 p.rect(gutter, 104, this.windowWidth - gutter * 2, 144, 24) - p.rect(gutter, 320, this.windowWidth - gutter * 2, 524, 24) + + if (this.showShare) { + p.rect(gutter, 320, this.windowWidth - gutter * 2, 524, 24) + } else { + p.rect(gutter, 320, this.windowWidth - gutter * 2, 444, 24) + p.rect(gutter, 796, this.windowWidth - gutter * 2, 64, 24) + } // draw hero this.bodies[0] const body = this.getDisplayHero() const radius = this.getBodyRadius(body.radius) - const xWobble = - this.p.sin(this.p.frameCount / this.P5_FPS) * (5 + body.bodyIndex) + const xWobble = p.sin(p.frameCount / this.P5_FPS) * (5 + body.bodyIndex) const yWobble = - this.p.cos(this.p.frameCount / this.P5_FPS + body.bodyIndex * 3) * + p.cos(p.frameCount / this.P5_FPS + body.bodyIndex * 3) * (6 + body.bodyIndex) body.position = { - x: this.p.map(scale, 0, 1, -140, 210) + xWobble, + x: p.map(scale, 0, 1, -140, 210) + xWobble, y: 220 + yWobble } this.bodiesGraphic ||= this.p.createGraphics( @@ -519,7 +526,7 @@ export const Visuals = { this.windowHeight ) this.drawBodiesLooped(body, radius, this.drawBody) - this.p.image(this.bodiesGraphic, 0, 0, 800, 800) + p.image(this.bodiesGraphic, 0, 0, 800, 800) this.bodiesGraphic.clear() // upper box text @@ -537,33 +544,115 @@ export const Visuals = { p.fill(THEME.iris_30) p.text('JAN-01-2024', 454, 114) p.text('okwme.eth', 454, 174) + // end upper box text - for (const [i, line] of this.statsText.split('\n').entries()) { - // print each stat line with left aligned label, right aligned stat - if (line.match(/1x/)) { - // gray text if 1x multiplier - p.fill('rgba(0,0,0,0.3)') - p.fill('black') - } else { - p.fill('black') - } - // last line has a bar on top - const leading = 64 - let barPadding = 0 - const xLeft = this.windowWidth / 2 - 300 - const xRight = this.windowWidth / 2 + 300 - const y = 374 + leading * i - - for (const [j, stat] of line.split(':').entries()) { - if (j === 0) { - p.textAlign(p.LEFT, p.TOP) - p.text(stat, xLeft, y + barPadding) - } else { - p.textAlign(p.RIGHT, p.TOP) - p.text(stat, xRight, y + barPadding) - } - } + // middle box text + p.textSize(48) + p.fill(THEME.iris_60) + p.textAlign(p.RIGHT, p.TOP) + const col1X = 580 + const col2X = 770 + const col3X = 960 + + // middle box text - labels + p.text('time', col1X, 264) + p.text('best', col2X, 264) + p.text('+/-', col3X, 264) + + // middle box text - values + const levelTimes = [1.32, 2.5, 13.54] + const bestTimes = [1.45, 2.44, 16.79, 23.45, 36.45] + const plusMinus = bestTimes + .map((best, i) => { + if (i >= levelTimes.length) return '' + const time = levelTimes[i] + const diff = time - best + const sign = diff > 0 ? '+' : '' + return sign + diff.toFixed(2) + }) + .filter(Boolean) + const problemComplete = levelTimes.length >= LEVELS + const rowHeight = 72 + + const bestTime = 20.68 + const levelTimeSum = levelTimes.reduce((a, b) => a + b, 0) + const sumLine = [ + levelTimeSum.toFixed(2), + bestTime.toFixed(2), + (levelTimeSum - bestTime).toFixed(2) + ] + + // middle box text - highlight current + p.fill('rgba(146, 118, 255, 0.2)') + p.rect( + gutter, + middleBoxY + levelTimes.length * rowHeight, + this.windowWidth - gutter * 2, + rowHeight + ) + + // middle box text - value text + p.push() + p.textAlign(p.RIGHT, p.CENTER) + p.textSize(44) + // const middleBoxPadding = 12 + // p.translate(0, middleBoxPadding) + for (let i = 0; i < LEVELS; i++) { + const time = i < levelTimes.length ? levelTimes[i].toFixed(2) : '-' + const light = i % 2 == 0 + p.fill(light ? THEME.iris_30 : THEME.iris_60) + p.text( + time, + col1X, + middleBoxY + rowHeight * i + rowHeight / 2, + 150, + rowHeight + ) + } + for (let i = 0; i < LEVELS; i++) { + const best = i < bestTimes.length ? bestTimes[i] : '-' + const light = i % 2 == 1 && i < levelTimes.length + p.fill(light ? THEME.iris_30 : THEME.iris_60) + p.text( + best.toFixed(2), + col2X, + middleBoxY + rowHeight * i + rowHeight / 2, + 150, + rowHeight + ) } + for (let i = 0; i < LEVELS; i++) { + const diff = plusMinus[i] || '-' + p.text( + diff, + col3X, + middleBoxY + rowHeight * i + rowHeight / 2, + 150, + rowHeight + ) + } + p.textSize(64) + const sumLineY = middleBoxY + rowHeight * bestTimes.length + rowHeight / 2 + const sumLineHeight = 80 + p.textAlign(p.LEFT, p.CENTER) + p.fill(THEME.iris_30) + p.text(problemComplete ? 'solved in' : 'current time', 44, sumLineY) + p.textAlign(p.RIGHT, p.CENTER) + for (const [i, col] of [col1X, col2X, col3X].entries()) { + if (i == 0) p.fill('white') + p.text(sumLine[i], col, sumLineY, 150, sumLineHeight) + } + p.pop() + // end middle box text + + // overlay transparent black box to dim past last levelTimes + p.fill('rgba(0,0,0,0.4)') + p.rect( + gutter, + middleBoxY + rowHeight * levelTimes.length, + this.windowWidth - gutter * 2, + rowHeight * (LEVELS - levelTimes.length) + ) // bottom buttons const buttonCount = this.showShare ? 4 : 3 @@ -614,7 +703,7 @@ export const Visuals = { return bodyCopy }, - drawTicker({ text, bottom = false, fg }) { + drawGameOverTicker({ text, bottom = false, fg }) { const doubleText = `${text} ${text} ` const { p } = this @@ -645,7 +734,7 @@ export const Visuals = { p.noStroke() p.fill(this.randomColor(100)) - this.drawTicker({ text: 'GAME OVER', fg: THEME.red }) + this.drawGameOverTicker({ text: 'GAME OVER', fg: THEME.red }) if (this.showPlayAgain) { this.drawFatButton({ From 5cd727207321498774dd212a29f36c271dce0425 Mon Sep 17 00:00:00 2001 From: psugihara Date: Fri, 5 Jul 2024 15:28:33 -0700 Subject: [PATCH 28/54] lime_40 --- src/colors.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/colors.js b/src/colors.js index a65bce60..80216681 100644 --- a/src/colors.js +++ b/src/colors.js @@ -16,6 +16,7 @@ export const THEME = { border: iris_60, // colors lime: 'rgba(125, 241, 115, 1)', + lime_40: 'rgba(125, 241, 115, 0.4)', pink: 'rgba(236, 205, 255, 1)', fuschia: 'rgba(160, 67, 232, 1)', red: 'rgba(255, 88, 88, 1)', From b090452f50b1476b25841ea86bc33367e8afbe7a Mon Sep 17 00:00:00 2001 From: psugihara Date: Fri, 5 Jul 2024 22:24:03 -0700 Subject: [PATCH 29/54] colors, baddie pyramid --- src/anybody.js | 2 +- src/colors.js | 5 ++ src/visuals.js | 132 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 107 insertions(+), 32 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 94b73054..e0b9ea27 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -222,7 +222,7 @@ export class Anybody extends EventEmitter { this.p5Frames = 0 this.showIt = true this.justStopped = false - this.gameOver = true + this.gameOver = false this.firstFrame = true this.loaded = false this.showPlayAgain = false diff --git a/src/colors.js b/src/colors.js index 80216681..8c41bd53 100644 --- a/src/colors.js +++ b/src/colors.js @@ -180,3 +180,8 @@ export function randHSL(ranges, rand) { return [h, s, l] } + +export function rgbaOpacity(color, opacity) { + const [r, g, b] = color.split(',').map((s) => Number(s.replace(/\D/g, ''))) + return `rgba(${r}, ${g}, ${b}, ${opacity})` +} diff --git a/src/visuals.js b/src/visuals.js index c41fd6da..af1c77b5 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -487,6 +487,7 @@ export const Visuals = { p.fill('white') // logo at top + if (!fonts.dot) return p.textFont(fonts.dot) p.fill(THEME.pink) p.textSize(60) @@ -510,28 +511,10 @@ export const Visuals = { p.rect(gutter, 796, this.windowWidth - gutter * 2, 64, 24) } - // draw hero this.bodies[0] - const body = this.getDisplayHero() - const radius = this.getBodyRadius(body.radius) - const xWobble = p.sin(p.frameCount / this.P5_FPS) * (5 + body.bodyIndex) - const yWobble = - p.cos(p.frameCount / this.P5_FPS + body.bodyIndex * 3) * - (6 + body.bodyIndex) - body.position = { - x: p.map(scale, 0, 1, -140, 210) + xWobble, - y: 220 + yWobble - } - this.bodiesGraphic ||= this.p.createGraphics( - this.windowWidth, - this.windowHeight - ) - this.drawBodiesLooped(body, radius, this.drawBody) - p.image(this.bodiesGraphic, 0, 0, 800, 800) - this.bodiesGraphic.clear() - // upper box text p.textSize(32) p.noStroke() + if (!fonts.body) return p.textFont(fonts.body) p.fill(THEME.iris_60) @@ -574,19 +557,11 @@ export const Visuals = { const problemComplete = levelTimes.length >= LEVELS const rowHeight = 72 - const bestTime = 20.68 - const levelTimeSum = levelTimes.reduce((a, b) => a + b, 0) - const sumLine = [ - levelTimeSum.toFixed(2), - bestTime.toFixed(2), - (levelTimeSum - bestTime).toFixed(2) - ] - - // middle box text - highlight current + // middle box text - highlight current row p.fill('rgba(146, 118, 255, 0.2)') p.rect( gutter, - middleBoxY + levelTimes.length * rowHeight, + middleBoxY + (levelTimes.length - 1) * rowHeight, this.windowWidth - gutter * 2, rowHeight ) @@ -623,6 +598,11 @@ export const Visuals = { } for (let i = 0; i < LEVELS; i++) { const diff = plusMinus[i] || '-' + if (i === levelTimes.length - 1) { + p.fill(/^-/.test(diff) ? THEME.lime : THEME.flame_50) + } else { + p.fill(/^-/.test(diff) ? THEME.green_75 : THEME.flame_75) + } p.text( diff, col3X, @@ -632,6 +612,15 @@ export const Visuals = { ) } p.textSize(64) + + // middle box text - sum line + const bestTime = 20.68 + const levelTimeSum = levelTimes.reduce((a, b) => a + b, 0) + const sumLine = [ + levelTimeSum.toFixed(2), + bestTime.toFixed(2), + (levelTimeSum - bestTime).toFixed(2) + ] const sumLineY = middleBoxY + rowHeight * bestTimes.length + rowHeight / 2 const sumLineHeight = 80 p.textAlign(p.LEFT, p.CENTER) @@ -640,13 +629,53 @@ export const Visuals = { p.textAlign(p.RIGHT, p.CENTER) for (const [i, col] of [col1X, col2X, col3X].entries()) { if (i == 0) p.fill('white') + else if (i == 1) p.fill(THEME.iris_60) + else p.fill(/^-/.test(sumLine[i]) ? THEME.lime : THEME.flame_75) p.text(sumLine[i], col, sumLineY, 150, sumLineHeight) } + p.pop() // end middle box text + // draw hero this.bodies[0] + const body = this.getDisplayHero() + const radius = this.getBodyRadius(body.radius) + const xWobble = p.sin(p.frameCount / this.P5_FPS) * (5 + body.bodyIndex) + const yWobble = + p.cos(p.frameCount / this.P5_FPS + body.bodyIndex * 3) * + (6 + body.bodyIndex) + body.position = { + x: p.map(scale, 0, 1, -140, 170) + xWobble, + y: 180 + yWobble + } + this.bodiesGraphic ||= this.p.createGraphics( + this.windowWidth, + this.windowHeight + ) + this.drawBodiesLooped(body, radius, this.drawBody) + + // begin middle box baddie body pyramid + this.winScreenBadies ||= this.getDisplayBaddies() + const baddies = this.winScreenBadies + for (let i = 0; i < baddies.length; i++) { + const row = baddies[i] + for (let j = 0; j < row.length; j++) { + const body = row[j] + body.position = this.createVector( + 64 + j * 72, + middleBoxY + i * rowHeight + rowHeight / 2 + ) + body.velocity = this.createVector(0, 1) + body.radius = 6.5 + this.drawBodiesLooped(body, 3, this.drawBody) + } + } + + p.image(this.bodiesGraphic, 0, 0) + this.bodiesGraphic.clear() + // overlay transparent black box to dim past last levelTimes - p.fill('rgba(0,0,0,0.4)') + p.fill('rgba(0,0,0,0.6)') p.rect( gutter, middleBoxY + rowHeight * levelTimes.length, @@ -654,6 +683,20 @@ export const Visuals = { rowHeight * (LEVELS - levelTimes.length) ) + // bottom box ticker text + this.winTickerGraphic ||= this.p.createGraphics( + this.windowWidth, + this.windowHeight + ) + p.textAlign(p.LEFT, p.TOP) + p.textSize(32) + p.fill(THEME.iris_30) + p.text( + 'NICE JOB!!!! Keep going!!! Solve this problem and climb the leaderboard.', + 44, + 811 + ) + // bottom buttons const buttonCount = this.showShare ? 4 : 3 this.drawBottomButton({ @@ -700,9 +743,33 @@ export const Visuals = { ) bodyCopy.position = this.p.createVector(body.position.x, body.position.y) bodyCopy.velocity = this.p.createVector(body.velocity.x, body.velocity.y) + bodyCopy.radius = 30 return bodyCopy }, + getDisplayBaddies() { + const baddies = [] + const body = this.bodies[this.bodies.length - 1] + if (!body) return [] + const str = JSON.stringify(body) + for (let i = 0; i < LEVELS; i++) { + baddies.push([]) + for (let j = 0; j < i + 1; j++) { + const bodyCopy = JSON.parse(str) + bodyCopy.position = this.p.createVector( + body.position.x, + body.position.y + ) + bodyCopy.velocity = this.p.createVector( + body.velocity.x, + body.velocity.y + ) + baddies[i].push(body) + } + } + return baddies + }, + drawGameOverTicker({ text, bottom = false, fg }) { const doubleText = `${text} ${text} ` @@ -1028,7 +1095,10 @@ export const Visuals = { // y-offset of face relative to center // const offset = this.getOffset(radius) - if (body.bodyIndex === 0 || (this.paused && body.bodyIndex < 3)) { + if ( + body.bodyIndex === 0 || + (!this.gameOver && this.paused && body.bodyIndex < 3) + ) { // draw hero const size = Math.floor(body.radius * BODY_SCALE * 2.66) From d6b240bc10642f0430df4ce60823de207951162c Mon Sep 17 00:00:00 2001 From: psugihara Date: Sat, 6 Jul 2024 21:02:06 -0700 Subject: [PATCH 30/54] add celebration YAYYYY ticker sequence --- src/anybody.js | 5 +++++ src/visuals.js | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index e0b9ea27..3f97e6e0 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -233,6 +233,11 @@ export class Anybody extends EventEmitter { this.won = false this.finalBatchSent = false this.solved = false + + // uncomment to work on the game over screen + // setTimeout(() => { + // this.handleGameOver({ won: true }) + // }, 500) } // run once at initilization diff --git a/src/visuals.js b/src/visuals.js index af1c77b5..ee29a19e 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -453,7 +453,13 @@ export const Visuals = { this.scoreSize = this.initialScoreSize p.pop() this.won ? this.drawWinScreen() : this.drawLoseScreen() - return + if (!this.celebrating) return + } + + // flash the score red and white + if (this.won) { + const flash = Math.floor(this.frames / 10) % 2 == 0 + p.fill(flash ? THEME.red : 'white') } p.textFont(fonts.body) @@ -466,8 +472,6 @@ export const Visuals = { }, drawWinScreen() { - const { p } = this - const justEntered = this.winScreenLastVisibleFrame !== this.p5Frames - 1 if (justEntered) { this.winScreenVisibleForFrames = 0 @@ -475,11 +479,38 @@ export const Visuals = { this.winScreenVisibleForFrames++ this.winScreenLastVisibleFrame = this.p5Frames + const celebrationTime = 6 // seconds + this.celebrating = + this.winScreenVisibleForFrames / this.P5_FPS < celebrationTime + + if (this.celebrating) { + this.drawGameOverTicker({ + text: ' YAYYYYYYYYYYY', + bottom: true, + fg: THEME.iris_30 + }) + } else { + this.drawStatsScreen() + } + }, + + drawStatsScreen() { + const { p } = this + + const justEntered = this.statsScreenLastVisibleFrame !== this.p5Frames - 1 + if (justEntered) { + this.statsScreenVisibleForFrames = 0 + this.P5_FPS = this.FPS * this.P5_FPS_MULTIPLIER + this.p.frameRate(this.P5_FPS) + } + this.statsScreenVisibleForFrames++ + this.statsScreenLastVisibleFrame = this.p5Frames + const entranceTime = 0.4 // seconds const scale = Math.min( 1, - this.winScreenVisibleForFrames / (entranceTime * this.P5_FPS) + this.statsScreenVisibleForFrames / (entranceTime * this.P5_FPS) ) p.push() From 1644d3fa4c05e5fc086593205183fcd6fe81ce45 Mon Sep 17 00:00:00 2001 From: psugihara Date: Sat, 6 Jul 2024 21:17:51 -0700 Subject: [PATCH 31/54] flash framesToook --- src/anybody.js | 1 + src/visuals.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/anybody.js b/src/anybody.js index 62b8093d..4ad7629e 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -234,6 +234,7 @@ export class Anybody extends EventEmitter { this.finalBatchSent = false this.solved = false this.date = new Date().toLocaleDateString() + // this.framesTook = false // uncomment to work on the game over screen // setTimeout(() => { diff --git a/src/visuals.js b/src/visuals.js index b1b95389..04296096 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -467,7 +467,7 @@ export const Visuals = { p.textAlign(p.LEFT, p.TOP) const runningFrames = this.frames - this.startingFrame - const seconds = runningFrames / this.FPS + const seconds = (this.framesTook || runningFrames) / this.FPS const secondsLeft = (this.level > 5 ? 60 : GAME_LENGTH_BY_LEVEL_INDEX[this.level - 1]) - seconds From 274b220e80e84b24bb40abdbc41f24001de1711e Mon Sep 17 00:00:00 2001 From: psugihara Date: Sat, 6 Jul 2024 21:22:39 -0700 Subject: [PATCH 32/54] fix --- src/anybody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anybody.js b/src/anybody.js index 4ad7629e..56832902 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -234,7 +234,7 @@ export class Anybody extends EventEmitter { this.finalBatchSent = false this.solved = false this.date = new Date().toLocaleDateString() - // this.framesTook = false + this.framesTook = false // uncomment to work on the game over screen // setTimeout(() => { From e75a3f20849f9800fc6484e22248bfc3e5b092d2 Mon Sep 17 00:00:00 2001 From: psugihara Date: Sun, 7 Jul 2024 10:50:36 -0700 Subject: [PATCH 33/54] button finesse --- src/buttons.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/buttons.js b/src/buttons.js index d14325ad..10973239 100644 --- a/src/buttons.js +++ b/src/buttons.js @@ -14,7 +14,6 @@ export const Buttons = { fgHover = 'rgba(160, 67, 232, 0.3)' }) { const { p } = this - this.p.textFont(fonts.dot) // register the button if it's not registered const key = `${text}-${x}-${y}-${height}-${width}` @@ -43,7 +42,7 @@ export const Buttons = { p.push() p.noStroke() - p.textSize(textSize) + p.textSize(textSize * scale) p.strokeWeight(button.active ? 1 : 4) p.fill(bg) @@ -59,7 +58,8 @@ export const Buttons = { p.rect(x, y, width, height, height / 2) } - if (scale === 1) { + if (scale >= 0.3 && fonts.dot) { + p.textFont(fonts.dot) p.fill(fg) p.textAlign(p.CENTER, p.CENTER) p.text( From 1f81e280544277556651f3e45b2701f0cbc6210c Mon Sep 17 00:00:00 2001 From: psugihara Date: Sun, 7 Jul 2024 10:52:10 -0700 Subject: [PATCH 34/54] active state --- src/buttons.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/buttons.js b/src/buttons.js index 10973239..f35e51b0 100644 --- a/src/buttons.js +++ b/src/buttons.js @@ -1,3 +1,4 @@ +import { rgbaOpacity } from './colors.js' import { fonts } from './fonts.js' export const Buttons = { @@ -58,6 +59,11 @@ export const Buttons = { p.rect(x, y, width, height, height / 2) } + if (button.active) { + p.fill(rgbaOpacity(bg, 0.3)) + p.rect(x, y, width, height, height / 2) + } + if (scale >= 0.3 && fonts.dot) { p.textFont(fonts.dot) p.fill(fg) From feaf83cd02315686cf6c0ca8103baea944dd5e5f Mon Sep 17 00:00:00 2001 From: psugihara Date: Sun, 7 Jul 2024 13:51:39 -0700 Subject: [PATCH 35/54] unpause animation? --- src/anybody.js | 17 ++-- src/buttons.js | 5 +- src/visuals.js | 237 ++++++++++++++++++++++++++++++------------------- 3 files changed, 157 insertions(+), 102 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 56832902..ab106fa0 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -498,18 +498,23 @@ export class Anybody extends EventEmitter { } setPause(newPauseState = !this.paused, mute = false) { + if (typeof newPauseState !== 'boolean') { + newPauseState = !this.paused + } + if (newPauseState) { this.pauseBodies = PAUSE_BODY_DATA.map(this.bodyDataToBodies.bind(this)) this.pauseBodies[1].c = this.getBodyColor(0) this.pauseBodies[2].c = this.getBodyColor(0) + this.paused = newPauseState + this.willUnpause = false + delete this.beganUnpauseAt + } else { + this.justPaused = true + this.willUnpause = true } - if (typeof newPauseState !== 'boolean') { - newPauseState = !this.paused - } - this.paused = newPauseState - this.justPaused = true - this.emit('paused', this.paused) + this.emit('paused', newPauseState) if (newPauseState) { if (!mute) this.sound?.pause() } else { diff --git a/src/buttons.js b/src/buttons.js index f35e51b0..04b6eb34 100644 --- a/src/buttons.js +++ b/src/buttons.js @@ -12,10 +12,9 @@ export const Buttons = { onClick, fg = 'black', bg = 'white', - fgHover = 'rgba(160, 67, 232, 0.3)' + fgHover = 'rgba(160, 67, 232, 0.3)', + p = this.p }) { - const { p } = this - // register the button if it's not registered const key = `${text}-${x}-${y}-${height}-${width}` let button = this.buttons[key] diff --git a/src/visuals.js b/src/visuals.js index 04296096..57b8ba81 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1,4 +1,4 @@ -import { hslToRgb, THEME } from './colors.js' +import { hslToRgb, rgbaOpacity, THEME } from './colors.js' import { fonts, drawKernedText } from './fonts.js' import { themes } from './colors.js' @@ -180,8 +180,6 @@ export const Visuals = { if (!this.paused) { this.drawBodies() - } else if (!this.gameOver) { - this.drawPauseBodies() } if ( @@ -250,13 +248,43 @@ export const Visuals = { } }, drawPause() { - if (!(this.paused && fonts.dot)) return + if (!fonts.dot || !this.paused) return - const { p } = this + this.pauseGraphic ||= this.p.createGraphics( + this.windowWidth, + this.windowHeight + ) + this.pauseGraphic.clear() + + const p = this.pauseGraphic + + const unpauseDuration = 2 + const unpauseFrames = unpauseDuration * this.P5_FPS + if (this.willUnpause && !this.beganUnpauseAt) { + this.willUnpause = true + this.beganUnpauseAt = this.p5Frames + } + + // pause and return when unpause finished + if (this.beganUnpauseAt + unpauseFrames < this.p5Frames) { + this.paused = false + this.willUnpause = false + return + } else if (this.willUnpause) { + // fade text out + const fadeOutFrames = (unpauseFrames / 4) * 3 + const fadeOutStart = this.beganUnpauseAt + unpauseFrames - fadeOutFrames + const fadeOutProgress = this.p5Frames - fadeOutStart + const fadeOut = this.p.map(fadeOutProgress, 0, fadeOutFrames, 1, 0) + p.fill(rgbaOpacity(THEME.pink, fadeOut)) + } else { + p.fill(THEME.pink) + } + + this.drawPauseBodies() // draw logo p.textFont(fonts.dot) - p.fill(THEME.pink) p.textSize(200) p.textAlign(p.LEFT, p.TOP) p.noStroke() @@ -264,32 +292,37 @@ export const Visuals = { drawKernedText(p, 'Anybody', 46, titleY, 0.8) drawKernedText(p, 'Problem', 46, titleY + 240, 2) - this.drawFatButton({ - text: 'PLAY', - onClick: () => this.setPause(false), - fg: THEME.fuschia, - bg: THEME.pink, - bottom: 120 - }) + if (!this.willUnpause) { + this.drawFatButton({ + text: 'PLAY', + onClick: () => this.setPause(false), + fg: THEME.fuschia, + bg: THEME.pink, + bottom: 120, + p + }) - // date - p.textFont(fonts.body) - p.textSize(24) - const dateWidth = p.textWidth(this.date) - const dateBgWidth = dateWidth + 48 - const dateBgHeight = 32 - const dateBottomY = this.windowHeight - 58 - p.fill(THEME.textBg) - p.rect( - this.windowWidth / 2 - dateBgWidth / 2, - dateBottomY - dateBgHeight / 2, - dateBgWidth, - dateBgHeight, - 20 - ) - p.textAlign(p.CENTER, p.CENTER) - p.fill(THEME.textFg) - p.text(this.date, this.windowWidth / 2, dateBottomY) + // date + p.textFont(fonts.body) + p.textSize(24) + const dateWidth = p.textWidth(this.date) + const dateBgWidth = dateWidth + 48 + const dateBgHeight = 32 + const dateBottomY = this.windowHeight - 58 + p.fill(THEME.textBg) + p.rect( + this.windowWidth / 2 - dateBgWidth / 2, + dateBottomY - dateBgHeight / 2, + dateBgWidth, + dateBgHeight, + 20 + ) + p.textAlign(p.CENTER, p.CENTER) + p.fill(THEME.textFg) + p.text(this.date, this.windowWidth / 2, dateBottomY) + } + + this.p.image(this.pauseGraphic, 0, 0) }, drawBodyOutlines() { for (let i = 0; i < this.bodies.length; i++) { @@ -697,6 +730,7 @@ export const Visuals = { const yWobble = p.cos(p.frameCount / this.P5_FPS + body.bodyIndex * 3) * (6 + body.bodyIndex) + body.position = { x: p.map(scale, 0, 1, -140, 170) + xWobble, y: 180 + yWobble @@ -1060,10 +1094,11 @@ export const Visuals = { const maxIndex = Math.min(FACE_BLINK_SVGS.length, FACE_SVGS.length) this.fIndex ||= Math.floor(Math.random() * maxIndex) const fIndex = (this.fIndex + body.bodyIndex) % maxIndex + const graphic = body.graphic || this.bodiesGraphic const baddiesNear = this.closeTo(body) if (baddiesNear) { - this.drawImageAsset(FACE_SHOT_SVGS[this.fIndex], width) + this.drawImageAsset(FACE_SHOT_SVGS[this.fIndex], width, null, graphic) return } @@ -1076,16 +1111,17 @@ export const Visuals = { Math.floor(this.frames / x) % m == 0 || Math.floor(this.frames / x) % m == 2 ) { - this.drawImageAsset(FACE_BLINK_SVGS[fIndex], width) + this.drawImageAsset(FACE_BLINK_SVGS[fIndex], width, null, graphic) } else { - this.drawImageAsset(FACE_SVGS[fIndex], width) + this.drawImageAsset(FACE_SVGS[fIndex], width, null, graphic) } // this.bodiesGraphic.pop() }, drawStarForegroundSvg(width, body) { const fill = body.c.fg - this.bodiesGraphic.push() + const graphic = body.graphic || this.bodiesGraphic + graphic.push() this.fgIndex ||= Math.floor(Math.random() * FG_SVGS.length) const fgIndex = (this.bgIndex + body.bodyIndex) % FG_SVGS.length const r = { @@ -1093,27 +1129,29 @@ export const Visuals = { ...(rotOverride?.fg?.[fgIndex] ?? {}) } const rotateBy = r.speed == 0 ? 0 : (this.frames / r.speed) % 360 - this.bodiesGraphic.rotate(r.direction * rotateBy) - this.drawImageAsset(FG_SVGS[fgIndex], width, fill) - this.bodiesGraphic.pop() + graphic.rotate(r.direction * rotateBy) + this.drawImageAsset(FG_SVGS[fgIndex], width, fill, graphic) + graphic.pop() }, drawCoreSvg(width, body) { const fill = body.c.core - this.bodiesGraphic.push() + const graphic = body.graphic || this.bodiesGraphic + graphic.push() const r = { ...rot.core, ...(rotOverride?.core?.[0] ?? {}) } const rotateBy = r.speed == 0 ? 0 : (this.frames / r.speed) % 360 - this.bodiesGraphic.rotate(r.direction * rotateBy) - this.drawImageAsset(CORE_SVGS[0], width, fill) - this.bodiesGraphic.pop() + graphic.rotate(r.direction * rotateBy) + this.drawImageAsset(CORE_SVGS[0], width, fill, graphic) + graphic.pop() }, drawStarBackgroundSvg(width, body) { const fill = body.c.bg - this.bodiesGraphic.push() + const graphic = body.graphic || this.bodiesGraphic + graphic.push() this.bgIndex ||= Math.floor(Math.random() * BG_SVGS.length) const bgIndex = (this.bgIndex + body.bodyIndex) % BG_SVGS.length const r = { @@ -1121,9 +1159,9 @@ export const Visuals = { ...(rotOverride?.bg?.[bgIndex] ?? {}) } const rotateBy = r.speed == 0 ? 0 : (this.frames / r.speed) % 360 - this.bodiesGraphic.rotate(r.direction * rotateBy) - this.drawImageAsset(BG_SVGS[bgIndex], width, fill) - this.bodiesGraphic.pop() + graphic.rotate(r.direction * rotateBy) + this.drawImageAsset(BG_SVGS[bgIndex], width, fill, graphic) + graphic.pop() }, moveAndRotate_PopAfter(graphic, x, y /*v*/) { @@ -1143,15 +1181,13 @@ export const Visuals = { }, drawBody(x, y, v, radius, body) { - this.moveAndRotate_PopAfter(this.bodiesGraphic, x, y, v) + const graphic = body.graphic || this.bodiesGraphic + this.moveAndRotate_PopAfter(graphic, x, y, v) // y-offset of face relative to center // const offset = this.getOffset(radius) - if ( - body.bodyIndex === 0 || - (!this.gameOver && this.paused && body.bodyIndex < 3) - ) { + if (body.bodyIndex === 0 || body.hero) { // draw hero const size = Math.floor(body.radius * BODY_SCALE * 2.66) @@ -1163,7 +1199,7 @@ export const Visuals = { this.drawBaddie(body) } - this.bodiesGraphic.pop() + graphic.pop() }, getBodyRadius(actualRadius) { @@ -1317,14 +1353,10 @@ export const Visuals = { }, drawPauseBodies() { - this.bodiesGraphic ||= this.p.createGraphics( - this.windowWidth, - this.windowHeight - ) - this.bodiesGraphic.noStroke() + this.pauseGraphic.noStroke() - for (const body of this.pauseBodies) { - this.bodiesGraphic.push() + for (const [i, body] of this.pauseBodies.entries()) { + this.pauseGraphic.push() body.position.x // after final proof is sent, don't draw upgradable bodies if (body.radius == 0) continue @@ -1340,6 +1372,33 @@ export const Visuals = { this.p.cos(this.p.frameCount / this.P5_FPS + body.bodyIndex * 3) * (16 + body.bodyIndex) + // if not paused, bodies should flee to the nearest side of the screen + const fleeDuration = 1.5 // seconds + const xFlee = + this.willUnpause && this.beganUnpauseAt + ? this.p.map( + this.p5Frames - this.beganUnpauseAt, + 0, + this.P5_FPS * fleeDuration, + 0, + body.position.x > this.windowWidth / 2 + ? this.windowWidth + 300 + : -300 + ) + : 0 + const yFlee = + this.willUnpause && this.beganUnpauseAt + ? this.p.map( + this.p5Frames - this.beganUnpauseAt, + 0, + this.P5_FPS * fleeDuration, + 0, + body.position.y > this.windowHeight / 2 + ? this.windowHeight + 300 + : -300 + ) + : 0 + const bodyCopy = JSON.parse( JSON.stringify( body, @@ -1347,17 +1406,15 @@ export const Visuals = { ) ) bodyCopy.position = this.p.createVector( - body.position.x + xWobble, - body.position.y + yWobble + body.position.x + xWobble + xFlee, + body.position.y + yWobble + yFlee ) bodyCopy.velocity = this.p.createVector(body.velocity.x, body.velocity.y) + bodyCopy.graphic = this.pauseGraphic + bodyCopy.hero = i < 3 this.drawBodiesLooped(bodyCopy, radius, this.drawBody) - this.bodiesGraphic.pop() + this.pauseGraphic.pop() } - - this.p.image(this.bodiesGraphic, 0, 0) - - this.bodiesGraphic.clear() }, replaceOpacity(c, opacity) { @@ -1388,22 +1445,24 @@ export const Visuals = { }, drawBaddie(body) { + const graphic = body.graphic || this.bodiesGraphic const colorHSL = body.c const coreWidth = body.radius * BODY_SCALE - const bgColor = hslToRgb(colorHSL, 0.5) + let bgColor = hslToRgb(colorHSL, 0.5) const coreColor = hslToRgb(colorHSL) - this.bodiesGraphic.push() + graphic.push() const rotate = (this.frames / 30) % 360 - this.bodiesGraphic.rotate(rotate) + graphic.rotate(rotate) this.drawImageAsset( BADDIE_SVG.bg, Math.floor(coreWidth * (310 / 111.2)), - bgColor + bgColor, + graphic ) - this.bodiesGraphic.push() - this.bodiesGraphic.rotate(-rotate + body.velocity.heading() + this.p.PI / 2) - this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor) - this.drawImageAsset(BADDIE_SVG.face, coreWidth, undefined) + graphic.push() + graphic.rotate(-rotate + body.velocity.heading() + this.p.PI / 2) + this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor, graphic) + this.drawImageAsset(BADDIE_SVG.face, coreWidth, undefined, graphic) // pupils always looking at missile, if no missile, look at mouse const target = @@ -1417,9 +1476,9 @@ export const Visuals = { const leftEye = [-body.radius * 0.6, -body.radius * 0.15] const rightEye = [body.radius * 0.6, -body.radius * 0.15] - this.bodiesGraphic.fill('white') - this.bodiesGraphic.circle(leftEye[0], leftEye[1], body.radius) - this.bodiesGraphic.circle(rightEye[0], rightEye[1], body.radius) + graphic.fill('white') + graphic.circle(leftEye[0], leftEye[1], body.radius) + graphic.circle(rightEye[0], rightEye[1], body.radius) const angle = Math.atan2(target.y - by, target.x - bx) - @@ -1430,21 +1489,13 @@ export const Visuals = { const leftX = distance * Math.cos(angle) const leftY = distance * Math.sin(angle) - this.bodiesGraphic.fill('black') - this.bodiesGraphic.circle( - leftX + leftEye[0], - leftY + leftEye[1], - body.radius * 0.4 - ) - this.bodiesGraphic.circle( - leftX + rightEye[0], - leftY + rightEye[1], - body.radius * 0.4 - ) + graphic.fill('black') + graphic.circle(leftX + leftEye[0], leftY + leftEye[1], body.radius * 0.4) + graphic.circle(leftX + rightEye[0], leftY + rightEye[1], body.radius * 0.4) const heroBody = this.bodies[0] const minDistance = heroBody.radius * 2 + body.radius * 4 - const currentDistance = this.p.dist( + const currentDistance = graphic.dist( heroBody.position.x, heroBody.position.y, body.position.x, @@ -1453,8 +1504,8 @@ export const Visuals = { const closeToBody = currentDistance <= minDistance if (closeToBody) { - this.bodiesGraphic.fill(coreColor) - this.bodiesGraphic.triangle( + graphic.fill(coreColor) + graphic.triangle( 0, -body.radius * 0.2, leftEye[0] * 2, @@ -1464,8 +1515,8 @@ export const Visuals = { ) } - this.bodiesGraphic.pop() - this.bodiesGraphic.pop() + graphic.pop() + graphic.pop() }, drawCenter(b, p = this.bodiesGraphic, x = 0, y = 0) { From 52322f81c4efc0ae3b14815b07b451bd1884b7c7 Mon Sep 17 00:00:00 2001 From: psugihara Date: Sun, 7 Jul 2024 13:58:39 -0700 Subject: [PATCH 36/54] start fade earlier --- src/visuals.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/visuals.js b/src/visuals.js index 57b8ba81..e3b610f7 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -273,7 +273,7 @@ export const Visuals = { } else if (this.willUnpause) { // fade text out const fadeOutFrames = (unpauseFrames / 4) * 3 - const fadeOutStart = this.beganUnpauseAt + unpauseFrames - fadeOutFrames + const fadeOutStart = this.beganUnpauseAt const fadeOutProgress = this.p5Frames - fadeOutStart const fadeOut = this.p.map(fadeOutProgress, 0, fadeOutFrames, 1, 0) p.fill(rgbaOpacity(THEME.pink, fadeOut)) @@ -1314,6 +1314,7 @@ export const Visuals = { }, async drawBodies(attachToCanvas = true) { + if (this.gameOver && !this.celebrating) return this.bodiesGraphic ||= this.p.createGraphics( this.windowWidth, this.windowHeight From 4f27625387d4cae8fb7f0169c1df6b325ba86e83 Mon Sep 17 00:00:00 2001 From: psugihara Date: Sun, 7 Jul 2024 15:46:16 -0700 Subject: [PATCH 37/54] fix --- src/visuals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/visuals.js b/src/visuals.js index e3b610f7..9b2423cd 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1314,7 +1314,7 @@ export const Visuals = { }, async drawBodies(attachToCanvas = true) { - if (this.gameOver && !this.celebrating) return + if (this.won && !this.celebrating) return this.bodiesGraphic ||= this.p.createGraphics( this.windowWidth, this.windowHeight From ec96900988e2db19f7f3ed6fe11366fafcd4fe9c Mon Sep 17 00:00:00 2001 From: Billy Rennekamp Date: Mon, 8 Jul 2024 20:10:30 +0200 Subject: [PATCH 38/54] pause for merge --- src/anybody.js | 19 ++-- src/nft.js | 3 +- src/visuals.js | 238 +++++++++++++++++++++++++++---------------------- 3 files changed, 147 insertions(+), 113 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 56832902..bbfc803d 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -118,6 +118,7 @@ export class Anybody extends EventEmitter { !this.util && loadFonts(this.p) // this.p.blendMode(this.p.DIFFERENCE) + this.levelSpeeds = new Array(5) this.clearValues() !this.util && this.prepareP5() this.sound = new Sound(this) @@ -162,7 +163,8 @@ export class Anybody extends EventEmitter { faceRotation: 'mania', // 'time' or 'hitcycle' or 'mania' sfx: 'bubble', // 'space' or 'bubble' owner: 'billyrennekamp.eth', - ownerPresent: false + ownerPresent: false, + bestTimes: null } // Merge the default options with the provided options const mergedOptions = { ...defaultOptions, ...options } @@ -244,6 +246,7 @@ export class Anybody extends EventEmitter { // run once at initilization init() { + this.skipAhead = false this.seed = utils.solidityKeccak256(['uint256'], [this.day]) this.rng = new Prando(this.seed.toString(16)) this.generateBodies() @@ -382,6 +385,9 @@ export class Anybody extends EventEmitter { } handleGameClick = (e) => { + if (this.gameOver) { + this.skipAhead = true + } const { x, y } = this.getXY(e) // if mouse is inside of a button, call the button's handler for (const key in this.buttons) { @@ -401,6 +407,9 @@ export class Anybody extends EventEmitter { } handleGameKeyDown = (e) => { + if (this.gameOver) { + this.skipAhead = true + } const modifierKeyActive = e.shiftKey && e.altKey && e.ctrlKey && e.metaKey if (modifierKeyActive) return switch (e.code) { @@ -411,10 +420,10 @@ export class Anybody extends EventEmitter { } break case 'KeyR': - this.restart(null, false) + if (!this.gameOver) this.restart(null, false) break case 'KeyP': - this.setPause() + if (!this.gameOver) this.setPause() break } } @@ -455,9 +464,6 @@ export class Anybody extends EventEmitter { } restart = (options, beginPaused = true) => { - if (this.won) { - this.level++ - } if (options) { this.setOptions(options) } @@ -664,6 +670,7 @@ export class Anybody extends EventEmitter { // maybe should add visuals and turn it into a feature (single shot mode) this.lastMissileCantBeUndone = true } + this.levelSpeeds[level - 1] = results return results } diff --git a/src/nft.js b/src/nft.js index 5a1709bb..2e7198d0 100644 --- a/src/nft.js +++ b/src/nft.js @@ -12,10 +12,11 @@ q5.setup = () => { // target: 'inside', // globalStyle: 'psycho', day: Math.floor(Math.random() * 10000000), - level: Math.floor(Math.random() * 4) + 1, + level: 1, //Math.floor(Math.random() * 4) + 1, alreadyRun: 0, //Math.floor(Math.random() * 20000), seed: seed || null, startingBodies: Math.floor(Math.random() * 8) + 2 + // bestTimes: [1.45, 2.44, 16.79, 23.45, 36.45] }) if (!seed) { window.location.hash = diff --git a/src/visuals.js b/src/visuals.js index 04296096..243e9826 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -294,7 +294,7 @@ export const Visuals = { drawBodyOutlines() { for (let i = 0; i < this.bodies.length; i++) { const body = this.bodies[i] - const radius = body.radius * 4 + this.radiusMultiplyer + const radius = body.radius * 4 this.p.stroke(this.getGrey()) this.p.stroke('black') @@ -501,11 +501,11 @@ export const Visuals = { this.winScreenVisibleForFrames++ this.winScreenLastVisibleFrame = this.p5Frames - const celebrationTime = 6 // seconds + const celebrationTime = 0 // seconds this.celebrating = this.winScreenVisibleForFrames / this.P5_FPS < celebrationTime - if (this.celebrating) { + if (this.celebrating && !this.skipAhead) { this.drawGameOverTicker({ text: ' YAYYYYYYYYYYY', bottom: true, @@ -596,8 +596,12 @@ export const Visuals = { p.text('+/-', col3X, 264) // middle box text - values - const levelTimes = [1.32, 2.5, 13.54] - const bestTimes = [1.45, 2.44, 16.79, 23.45, 36.45] + const levelTimes = this.levelSpeeds + .map((result) => result?.framesTook / this.FPS) + .filter((l) => l !== undefined) + + const bestTimes = + this.bestTimes ?? Array.from({ length: 5 }, (_, i) => levelTimes[i] || 0) const plusMinus = bestTimes .map((best, i) => { if (i >= levelTimes.length) return '' @@ -667,7 +671,7 @@ export const Visuals = { p.textSize(64) // middle box text - sum line - const bestTime = 20.68 + const bestTime = bestTimes.reduce((a, b) => a + b, 0) const levelTimeSum = levelTimes.reduce((a, b) => a + b, 0) const sumLine = [ levelTimeSum.toFixed(2), @@ -754,14 +758,19 @@ export const Visuals = { const buttonCount = this.showShare ? 4 : 3 this.drawBottomButton({ text: 'RETRY', - onClick: () => this.restart(null, false), + onClick: () => { + this.restart(null, false) + }, ...themes.buttons.teal, columns: buttonCount, column: 0 }) this.drawBottomButton({ text: 'RESTART', - onClick: () => this.restart(null, false), + onClick: () => { + this.level = 1 + this.restart(null, false) + }, ...themes.buttons.flame, columns: buttonCount, column: 1 @@ -777,7 +786,10 @@ export const Visuals = { } this.drawBottomButton({ text: 'NEXT', - onClick: () => this.restart(null, false), + onClick: () => { + this.level++ + this.restart(null, false) + }, ...themes.buttons.green, columns: buttonCount, column: buttonCount - 1 @@ -1142,7 +1154,7 @@ export const Visuals = { // } }, - drawBody(x, y, v, radius, body) { + drawBody(x, y, v, radius, body, backgroundOnly = false) { this.moveAndRotate_PopAfter(this.bodiesGraphic, x, y, v) // y-offset of face relative to center @@ -1150,64 +1162,68 @@ export const Visuals = { if ( body.bodyIndex === 0 || - (!this.gameOver && this.paused && body.bodyIndex < 3) + (!this.gameOver && this.paused && body.bodyIndex < 3) // TODO: what does body.bodyIndex < 3 do? ) { // draw hero const size = Math.floor(body.radius * BODY_SCALE * 2.66) this.drawStarBackgroundSvg(size, body) - this.drawCoreSvg(body.radius * BODY_SCALE, body) + if (!backgroundOnly) { + this.drawCoreSvg(body.radius * BODY_SCALE, body) + } this.drawStarForegroundSvg(size, body) - this.drawFaceSvg(body, size) + if (!backgroundOnly) { + this.drawFaceSvg(body, size) + } } else { - this.drawBaddie(body) + this.drawBaddie(body, backgroundOnly) } this.bodiesGraphic.pop() }, getBodyRadius(actualRadius) { - return actualRadius * 4 + this.radiusMultiplyer + return actualRadius * 4 }, drawBodiesLooped(body, radius, drawFunction) { drawFunction = drawFunction.bind(this) drawFunction(body.position.x, body.position.y, body.velocity, radius, body) - // let loopedX = false, - // loopedY = false, - // loopX = body.position.x, - // loopY = body.position.y - // const loopGap = radius / 2 - - // // crosses right, draw on left - // if (body.position.x > this.windowWidth - loopGap) { - // loopedX = true - // loopX = body.position.x - this.windowWidth - // drawFunction(loopX, body.position.y, body.velocity, radius, body, true) - // // crosses left, draw on right - // } else if (body.position.x < loopGap) { - // loopedX = true - // loopX = body.position.x + this.windowWidth - // drawFunction(loopX, body.position.y, body.velocity, radius, body, true) - // } + if (this.paused) return + let loopedX = false, + loopedY = false, + loopX = body.position.x, + loopY = body.position.y + const loopGap = radius * 1.5 + // crosses right, draw on left + if (body.position.x > this.windowWidth - loopGap) { + loopedX = true + loopX = body.position.x - this.windowWidth + drawFunction(loopX, body.position.y, body.velocity, radius, body, true) + // crosses left, draw on right + } else if (body.position.x < loopGap) { + loopedX = true + loopX = body.position.x + this.windowWidth + drawFunction(loopX, body.position.y, body.velocity, radius, body, true) + } - // // crosses bottom, draw on top - // if (body.position.y > this.windowHeight - loopGap) { - // loopedY = true - // loopY = body.position.y - this.windowHeight - // drawFunction(body.position.x, loopY, body.velocity, radius, body, true) - // // crosses top, draw on bottom - // } else if (body.position.y < loopGap) { - // loopedY = true - // loopY = body.position.y + this.windowHeight - // drawFunction(body.position.x, loopY, body.velocity, radius, body, true) - // } + // crosses bottom, draw on top + if (body.position.y > this.windowHeight - loopGap) { + loopedY = true + loopY = body.position.y - this.windowHeight + drawFunction(body.position.x, loopY, body.velocity, radius, body, true) + // crosses top, draw on bottom + } else if (body.position.y < loopGap) { + loopedY = true + loopY = body.position.y + this.windowHeight + drawFunction(body.position.x, loopY, body.velocity, radius, body, true) + } - // // crosses corner, draw opposite corner - // if (loopedX && loopedY) { - // drawFunction(loopX, loopY, body.velocity, radius, body, true) - // } + // crosses corner, draw opposite corner + if (loopedX && loopedY) { + drawFunction(loopX, loopY, body.velocity, radius, body, true) + } }, // TODO: add this back as part of a end game animation @@ -1331,6 +1347,13 @@ export const Visuals = { const bodyRadius = this.bodyCopies.filter( (b) => b.bodyIndex == body.bodyIndex )[0]?.radius + + // TODO: often there is no bodyRadius because bodyIndex doesn't match + // what is going on there? + // if (!bodyRadius) { + // throw new Error('no body matches') + // } + const radius = this.getBodyRadius(bodyRadius) // calculate x and y wobble factors based on this.p5Frames to make the pause bodies look like they're bobbing around @@ -1387,7 +1410,7 @@ export const Visuals = { return `hsla(${cc.join(',')})` }, - drawBaddie(body) { + drawBaddie(body, backgroundOnly) { const colorHSL = body.c const coreWidth = body.radius * BODY_SCALE const bgColor = hslToRgb(colorHSL, 0.5) @@ -1402,66 +1425,69 @@ export const Visuals = { ) this.bodiesGraphic.push() this.bodiesGraphic.rotate(-rotate + body.velocity.heading() + this.p.PI / 2) - this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor) - this.drawImageAsset(BADDIE_SVG.face, coreWidth, undefined) - - // pupils always looking at missile, if no missile, look at mouse - const target = - this.missiles.length > 0 - ? this.missiles[0].position - : { x: this.scaleX(this.p.mouseX), y: this.scaleY(this.p.mouseY) } - - const bx = body.position.x - const by = body.position.y - - const leftEye = [-body.radius * 0.6, -body.radius * 0.15] - const rightEye = [body.radius * 0.6, -body.radius * 0.15] - - this.bodiesGraphic.fill('white') - this.bodiesGraphic.circle(leftEye[0], leftEye[1], body.radius) - this.bodiesGraphic.circle(rightEye[0], rightEye[1], body.radius) - - const angle = - Math.atan2(target.y - by, target.x - bx) - - body.velocity.heading() - - this.p.PI / 2 - - const distance = body.radius * 0.3 - const leftX = distance * Math.cos(angle) - const leftY = distance * Math.sin(angle) - - this.bodiesGraphic.fill('black') - this.bodiesGraphic.circle( - leftX + leftEye[0], - leftY + leftEye[1], - body.radius * 0.4 - ) - this.bodiesGraphic.circle( - leftX + rightEye[0], - leftY + rightEye[1], - body.radius * 0.4 - ) - - const heroBody = this.bodies[0] - const minDistance = heroBody.radius * 2 + body.radius * 4 - const currentDistance = this.p.dist( - heroBody.position.x, - heroBody.position.y, - body.position.x, - body.position.y - ) - const closeToBody = currentDistance <= minDistance + if (!backgroundOnly) { + this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor) + } + if (!backgroundOnly) { + this.drawImageAsset(BADDIE_SVG.face, coreWidth, undefined) + // pupils always looking at missile, if no missile, look at mouse + const target = + this.missiles.length > 0 + ? this.missiles[0].position + : { x: this.scaleX(this.p.mouseX), y: this.scaleY(this.p.mouseY) } + + const bx = body.position.x + const by = body.position.y + + const leftEye = [-body.radius * 0.6, -body.radius * 0.15] + const rightEye = [body.radius * 0.6, -body.radius * 0.15] + + this.bodiesGraphic.fill('white') + this.bodiesGraphic.circle(leftEye[0], leftEye[1], body.radius) + this.bodiesGraphic.circle(rightEye[0], rightEye[1], body.radius) + + const angle = + Math.atan2(target.y - by, target.x - bx) - + body.velocity.heading() - + this.p.PI / 2 + + const distance = body.radius * 0.3 + const leftX = distance * Math.cos(angle) + const leftY = distance * Math.sin(angle) + + this.bodiesGraphic.fill('black') + this.bodiesGraphic.circle( + leftX + leftEye[0], + leftY + leftEye[1], + body.radius * 0.4 + ) + this.bodiesGraphic.circle( + leftX + rightEye[0], + leftY + rightEye[1], + body.radius * 0.4 + ) - if (closeToBody) { - this.bodiesGraphic.fill(coreColor) - this.bodiesGraphic.triangle( - 0, - -body.radius * 0.2, - leftEye[0] * 2, - -body.radius * 0.8, - rightEye[0] * 2, - -body.radius * 0.8 + const heroBody = this.bodies[0] + const minDistance = heroBody.radius * 2 + body.radius * 4 + const currentDistance = this.p.dist( + heroBody.position.x, + heroBody.position.y, + body.position.x, + body.position.y ) + const closeToBody = currentDistance <= minDistance + + if (closeToBody) { + this.bodiesGraphic.fill(coreColor) + this.bodiesGraphic.triangle( + 0, + -body.radius * 0.2, + leftEye[0] * 2, + -body.radius * 0.8, + rightEye[0] * 2, + -body.radius * 0.8 + ) + } } this.bodiesGraphic.pop() From 3df8108eee6e91327b8d5b487be8ad2fa9f6b3e8 Mon Sep 17 00:00:00 2001 From: Billy Rennekamp Date: Mon, 8 Jul 2024 21:04:02 +0200 Subject: [PATCH 39/54] live-ish data, small tweaks --- src/nft.js | 27 ++++++------- src/visuals.js | 100 ++++++++++++++++++++++++++++--------------------- 2 files changed, 69 insertions(+), 58 deletions(-) diff --git a/src/nft.js b/src/nft.js index 2e7198d0..19fa57e3 100644 --- a/src/nft.js +++ b/src/nft.js @@ -2,25 +2,20 @@ import Q5 from './q5.min.js' import { Anybody } from './anybody.js' const q5 = new Q5() -const seed = window.location.hash.slice(1) - +const day = window.location.hash.slice(1) window.anybody q5.setup = () => { - window.anybody = new Anybody(q5, { - mode: 'game', - // target: 'inside', - // globalStyle: 'psycho', - day: Math.floor(Math.random() * 10000000), - level: 1, //Math.floor(Math.random() * 4) + 1, - alreadyRun: 0, //Math.floor(Math.random() * 20000), - seed: seed || null, - startingBodies: Math.floor(Math.random() * 8) + 2 - // bestTimes: [1.45, 2.44, 16.79, 23.45, 36.45] - }) - if (!seed) { - window.location.hash = - '0x' + window.anybody.seed.toString().padStart(64, '0') + const options = { + level: 1, + bestTimes: [1.45, 2.44, 16.79, 23.45, 36.45] + } + if (day && day !== '') { + options.day = parseInt(day) + } + window.anybody = new Anybody(q5, options) + if (!day) { + window.location.hash = window.anybody.day.toString() } } q5.draw = () => { diff --git a/src/visuals.js b/src/visuals.js index 9e686fff..68e85aa3 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -612,10 +612,14 @@ export const Visuals = { p.textSize(54) p.fill(THEME.iris_30) const date = new Date(this.date) - const options = { month: 'short', day: 'numeric', year: 'numeric' } - const formattedDate = date.toLocaleDateString('en-US', options) + const options = { month: 'short', day: '2-digit', year: 'numeric' } + const formattedDate = date + .toLocaleDateString('en-US', options) + .toUpperCase() + .replace(', ', '-') + .replace(' ', '-') p.text(formattedDate, 454, 114) - p.text('okwme.eth', 454, 174) + p.text(this.ens || this.address || 'YOU', 454, 174) // end upper box text // middle box text @@ -786,52 +790,64 @@ export const Visuals = { p.textSize(32) p.fill(THEME.iris_30) p.text( - 'NICE JOB!!!! Keep going!!! Solve this problem and climb the leaderboard.', + this.level == 5 + ? 'CONGRATS!!! SAVE YOUR GAME TO SOLVE THE PROBLEM!!!!' + : 'NICE JOB!!!! Keep going!!! Solve this problem and climb the leaderboard.', 44, 811 ) - - // bottom buttons - const buttonCount = this.showShare ? 4 : 3 - this.drawBottomButton({ - text: 'RETRY', - onClick: () => { - this.restart(null, false) - }, - ...themes.buttons.teal, - columns: buttonCount, - column: 0 - }) - this.drawBottomButton({ - text: 'RESTART', - onClick: () => { - this.level = 1 - this.restart(null, false) - }, - ...themes.buttons.flame, - columns: buttonCount, - column: 1 - }) - if (this.showShare) { + if (this.level < 5) { + // bottom buttons + const buttonCount = this.showShare ? 4 : 3 this.drawBottomButton({ - text: 'SHARE', - onClick: () => this.restart(null, false), - ...themes.buttons.pink, + text: 'RETRY', + onClick: () => { + this.restart(null, false) + }, + ...themes.buttons.teal, + columns: buttonCount, + column: 0 + }) + this.drawBottomButton({ + text: 'RESTART', + onClick: () => { + this.level = 1 + this.restart(null, false) + }, + ...themes.buttons.flame, + columns: buttonCount, + column: 1 + }) + if (this.showShare) { + this.drawBottomButton({ + text: 'SHARE', + onClick: () => this.restart(null, false), + ...themes.buttons.pink, + columns: buttonCount, + column: 2 + }) + } + this.drawBottomButton({ + text: 'NEXT', + onClick: () => { + this.level++ + this.restart(null, false) + }, + ...themes.buttons.green, columns: buttonCount, - column: 2 + column: buttonCount - 1 + }) + } else { + this.drawBottomButton({ + text: this.readyToSave ? 'SAVE' : 'ALMOST READY TO SAVE...', + onClick: () => { + this.emit('save') + }, + ...themes.buttons.green, + columns: 1, + column: 0 }) } - this.drawBottomButton({ - text: 'NEXT', - onClick: () => { - this.level++ - this.restart(null, false) - }, - ...themes.buttons.green, - columns: buttonCount, - column: buttonCount - 1 - }) - p.pop() }, From 58a9a21ca1c00d6a49713f60f01d10c0d7a27bd1 Mon Sep 17 00:00:00 2001 From: Billy Rennekamp Date: Mon, 8 Jul 2024 21:09:36 +0200 Subject: [PATCH 40/54] last tweaks --- src/anybody.js | 2 +- src/visuals.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 3856ca36..1e31e91a 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -162,7 +162,7 @@ export class Anybody extends EventEmitter { target: 'inside', // 'outside' or 'inside' faceRotation: 'mania', // 'time' or 'hitcycle' or 'mania' sfx: 'bubble', // 'space' or 'bubble' - owner: 'billyrennekamp.eth', + owner: 'YOU', ownerPresent: false, bestTimes: null } diff --git a/src/visuals.js b/src/visuals.js index 68e85aa3..1d227287 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -534,7 +534,7 @@ export const Visuals = { this.winScreenVisibleForFrames++ this.winScreenLastVisibleFrame = this.p5Frames - const celebrationTime = 0 // seconds + const celebrationTime = 3 // seconds this.celebrating = this.winScreenVisibleForFrames / this.P5_FPS < celebrationTime @@ -619,7 +619,7 @@ export const Visuals = { .replace(', ', '-') .replace(' ', '-') p.text(formattedDate, 454, 114) - p.text(this.ens || this.address || 'YOU', 454, 174) + p.text(this.owner, 454, 174) // end upper box text // middle box text From b27ce3daf79a5cbaca38a1b22e6f8b3b21a6e335 Mon Sep 17 00:00:00 2001 From: Billy Rennekamp Date: Mon, 8 Jul 2024 21:14:09 +0200 Subject: [PATCH 41/54] bug in clearValues --- src/anybody.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/anybody.js b/src/anybody.js index 1e31e91a..4ef94460 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -201,7 +201,6 @@ export class Anybody extends EventEmitter { this.FPS = 25 this.P5_FPS_MULTIPLIER = 3 this.P5_FPS = this.FPS * this.P5_FPS_MULTIPLIER - this.p.frameRate(this.P5_FPS) this.timer = (this.level > 5 ? 60 : GAME_LENGTH_BY_LEVEL_INDEX[this.level - 1]) * this.FPS From 7cacace3866ca783a15816af712f6be79015540a Mon Sep 17 00:00:00 2001 From: Billy Rennekamp Date: Mon, 8 Jul 2024 21:17:31 +0200 Subject: [PATCH 42/54] actually different bug in clearValues --- src/anybody.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/anybody.js b/src/anybody.js index 4ef94460..6b0d0b9f 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -201,6 +201,7 @@ export class Anybody extends EventEmitter { this.FPS = 25 this.P5_FPS_MULTIPLIER = 3 this.P5_FPS = this.FPS * this.P5_FPS_MULTIPLIER + this.p?.frameRate(this.P5_FPS) this.timer = (this.level > 5 ? 60 : GAME_LENGTH_BY_LEVEL_INDEX[this.level - 1]) * this.FPS From c67a2f41871fef61c707b425ac1b07ff783d6247 Mon Sep 17 00:00:00 2001 From: Billy Rennekamp Date: Mon, 8 Jul 2024 21:31:00 +0200 Subject: [PATCH 43/54] peter suggestion --- src/visuals.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/visuals.js b/src/visuals.js index 1d227287..244471ab 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1211,7 +1211,7 @@ export const Visuals = { // } }, - drawBody(x, y, v, radius, body, backgroundOnly = false) { + drawBody(x, y, v, radius, body) { const graphic = body.graphic || this.bodiesGraphic this.moveAndRotate_PopAfter(graphic, x, y, v) @@ -1223,15 +1223,15 @@ export const Visuals = { const size = Math.floor(body.radius * BODY_SCALE * 2.66) this.drawStarBackgroundSvg(size, body) - if (!backgroundOnly) { + if (!body.backgroundOnly) { this.drawCoreSvg(body.radius * BODY_SCALE, body) } this.drawStarForegroundSvg(size, body) - if (!backgroundOnly) { + if (!body.backgroundOnly) { this.drawFaceSvg(body, size) } } else { - this.drawBaddie(body, backgroundOnly) + this.drawBaddie(body) } graphic.pop() @@ -1242,6 +1242,7 @@ export const Visuals = { }, drawBodiesLooped(body, radius, drawFunction) { + body.backgroundOnly = false drawFunction = drawFunction.bind(this) drawFunction(body.position.x, body.position.y, body.velocity, radius, body) @@ -1251,33 +1252,34 @@ export const Visuals = { loopX = body.position.x, loopY = body.position.y const loopGap = radius * 1.5 + body.backgroundOnly = true // crosses right, draw on left if (body.position.x > this.windowWidth - loopGap) { loopedX = true loopX = body.position.x - this.windowWidth - drawFunction(loopX, body.position.y, body.velocity, radius, body, true) + drawFunction(loopX, body.position.y, body.velocity, radius, body) // crosses left, draw on right } else if (body.position.x < loopGap) { loopedX = true loopX = body.position.x + this.windowWidth - drawFunction(loopX, body.position.y, body.velocity, radius, body, true) + drawFunction(loopX, body.position.y, body.velocity, radius, body) } // crosses bottom, draw on top if (body.position.y > this.windowHeight - loopGap) { loopedY = true loopY = body.position.y - this.windowHeight - drawFunction(body.position.x, loopY, body.velocity, radius, body, true) + drawFunction(body.position.x, loopY, body.velocity, radius, body) // crosses top, draw on bottom } else if (body.position.y < loopGap) { loopedY = true loopY = body.position.y + this.windowHeight - drawFunction(body.position.x, loopY, body.velocity, radius, body, true) + drawFunction(body.position.x, loopY, body.velocity, radius, body) } // crosses corner, draw opposite corner if (loopedX && loopedY) { - drawFunction(loopX, loopY, body.velocity, radius, body, true) + drawFunction(loopX, loopY, body.velocity, radius, body) } }, @@ -1487,7 +1489,7 @@ export const Visuals = { return `hsla(${cc.join(',')})` }, - drawBaddie(body, backgroundOnly) { + drawBaddie(body) { const graphic = body.graphic || this.bodiesGraphic const colorHSL = body.c const coreWidth = body.radius * BODY_SCALE @@ -1505,7 +1507,7 @@ export const Visuals = { graphic.push() graphic.rotate(-rotate + body.velocity.heading() + this.p.PI / 2) this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor, graphic) - if (!backgroundOnly) { + if (!body.backgroundOnly) { this.drawImageAsset(BADDIE_SVG.face, coreWidth, undefined, graphic) // pupils always looking at missile, if no missile, look at mouse From 0e585eaf757811c827cf834c313d8e3d69602d99 Mon Sep 17 00:00:00 2001 From: Billy Rennekamp Date: Mon, 8 Jul 2024 21:40:20 +0200 Subject: [PATCH 44/54] tweak date --- src/anybody.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/anybody.js b/src/anybody.js index 6b0d0b9f..dbdef942 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -235,8 +235,10 @@ export class Anybody extends EventEmitter { this.won = false this.finalBatchSent = false this.solved = false - this.date = new Date().toISOString().split('T')[0].replace(/-/g, '.') - + this.date = new Date(this.day * 1000) + .toISOString() + .split('T')[0] + .replace(/-/g, '.') this.framesTook = false // uncomment to work on the game over screen // setTimeout(() => { From 032d5afef91236e494bda76f6cf6c38fc0fcfd1b Mon Sep 17 00:00:00 2001 From: Billy Rennekamp Date: Wed, 10 Jul 2024 18:48:38 +0200 Subject: [PATCH 45/54] halp --- scripts/utils.js | 5 ++ server/contractData/12345-AnybodyProblem.json | 2 +- .../contractData/12345-ExternalMetadata.json | 2 +- .../12345-Game_2_250Verifier.json | 2 +- .../12345-Game_3_250Verifier.json | 2 +- .../12345-Game_4_250Verifier.json | 2 +- .../12345-Game_5_125Verifier.json | 2 +- .../12345-Game_6_125Verifier.json | 2 +- server/contractData/12345-Speedruns.json | 2 +- .../ABI-12345-AnybodyProblem.json | 58 +------------------ .../ABI-12345-ExternalMetadata.json | 14 ++--- server/contractData/ABI-12345-Speedruns.json | 4 +- server/package.json | 2 +- server/shovel-config.ts | 19 +++++- server/shovel.test.ts | 2 +- server/src/index.ts | 2 +- server/src/leaderboard.ts | 14 ++--- src/anybody.js | 2 +- src/visuals.js | 2 +- test/contracts/anybodyProblem.test.js | 15 ++--- test/contracts/speedruns.test.js | 4 +- 21 files changed, 58 insertions(+), 101 deletions(-) diff --git a/scripts/utils.js b/scripts/utils.js index e105de21..d7a0bc20 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -222,6 +222,11 @@ const deployContracts = async (options) => { ] returnObject.verificationData = verificationData + } else if (networkinfo['chainId'] == 12345) { + await deployer.sendTransaction({ + to: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + value: ethers.utils.parseEther('1.0') + }) } return returnObject diff --git a/server/contractData/12345-AnybodyProblem.json b/server/contractData/12345-AnybodyProblem.json index 6d9e5f8a..76af03c5 100644 --- a/server/contractData/12345-AnybodyProblem.json +++ b/server/contractData/12345-AnybodyProblem.json @@ -1,4 +1,4 @@ { - "address": "0x03025B79e75edE42CD6cfa73aBc7c8473d1583B5", + "address": "0x751DB7255687d9E5dC6DfCA48a9E1ED8A7d10516", "chain": { "chainId": 12345, "name": "unknown" } } diff --git a/server/contractData/12345-ExternalMetadata.json b/server/contractData/12345-ExternalMetadata.json index 142c2e09..f24e8be6 100644 --- a/server/contractData/12345-ExternalMetadata.json +++ b/server/contractData/12345-ExternalMetadata.json @@ -1,4 +1,4 @@ { - "address": "0x2643AA39900b53caeF3fE77faB588CF49C57Ac95", + "address": "0x8a15316f759e54449F36D7ca386e5268Db81FfC9", "chain": { "chainId": 12345, "name": "unknown" } } diff --git a/server/contractData/12345-Game_2_250Verifier.json b/server/contractData/12345-Game_2_250Verifier.json index b4139b1f..83492d51 100644 --- a/server/contractData/12345-Game_2_250Verifier.json +++ b/server/contractData/12345-Game_2_250Verifier.json @@ -1,4 +1,4 @@ { - "address": "0x53e196360c9AAB9c9AE9aD41BFaB76E766083a73", + "address": "0x7496EF7031b76AcD02c6f73A4421AFB4A42Fca4c", "chain": { "chainId": 12345, "name": "unknown" } } diff --git a/server/contractData/12345-Game_3_250Verifier.json b/server/contractData/12345-Game_3_250Verifier.json index 86659f1c..035105b6 100644 --- a/server/contractData/12345-Game_3_250Verifier.json +++ b/server/contractData/12345-Game_3_250Verifier.json @@ -1,4 +1,4 @@ { - "address": "0x6986BF30d9091F73352d7509FC5D796ef68CDd12", + "address": "0xE877CDACBB7827d4232Cde5f8de58371F144a0A4", "chain": { "chainId": 12345, "name": "unknown" } } diff --git a/server/contractData/12345-Game_4_250Verifier.json b/server/contractData/12345-Game_4_250Verifier.json index 679149c9..678af277 100644 --- a/server/contractData/12345-Game_4_250Verifier.json +++ b/server/contractData/12345-Game_4_250Verifier.json @@ -1,4 +1,4 @@ { - "address": "0x941dDe88e163c64DA03bbB3baEb17F4D6d6E1F02", + "address": "0xC8A395E3b82e515F88e0Ef548124c114f16cE9E3", "chain": { "chainId": 12345, "name": "unknown" } } diff --git a/server/contractData/12345-Game_5_125Verifier.json b/server/contractData/12345-Game_5_125Verifier.json index d1e447af..0bbfb133 100644 --- a/server/contractData/12345-Game_5_125Verifier.json +++ b/server/contractData/12345-Game_5_125Verifier.json @@ -1,4 +1,4 @@ { - "address": "0x6E84AB6dCD0B5F4410767ea644778cCbF6Ed77fB", + "address": "0xDCe09254dD3592381b6A5b7a848B29890b656e01", "chain": { "chainId": 12345, "name": "unknown" } } diff --git a/server/contractData/12345-Game_6_125Verifier.json b/server/contractData/12345-Game_6_125Verifier.json index ba063913..6842440e 100644 --- a/server/contractData/12345-Game_6_125Verifier.json +++ b/server/contractData/12345-Game_6_125Verifier.json @@ -1,4 +1,4 @@ { - "address": "0x144Ab3451D4A03DE5b28e41F994060a7AfA27C9e", + "address": "0xd384A4A6F54F61d29b5e656DdadE31C84E2e4EfA", "chain": { "chainId": 12345, "name": "unknown" } } diff --git a/server/contractData/12345-Speedruns.json b/server/contractData/12345-Speedruns.json index 66a4d777..4d42b1e4 100644 --- a/server/contractData/12345-Speedruns.json +++ b/server/contractData/12345-Speedruns.json @@ -1,4 +1,4 @@ { - "address": "0x2524a59da2729fa225B099a802c94C7a8f322571", + "address": "0x55c7d3136cCdd9Adc7CFA576e6B20154CD51b716", "chain": { "chainId": 12345, "name": "unknown" } } diff --git a/server/contractData/ABI-12345-AnybodyProblem.json b/server/contractData/ABI-12345-AnybodyProblem.json index efbab4df..71c748ea 100644 --- a/server/contractData/ABI-12345-AnybodyProblem.json +++ b/server/contractData/ABI-12345-AnybodyProblem.json @@ -542,60 +542,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_fromTokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_toTokenId", - "type": "uint256" - } - ], - "name": "emitBatchMetadataUpdate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "emitMetadataUpdate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_fromTokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_toTokenId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "who", - "type": "address" - } - ], - "name": "exampleEmitMultipleIndexEvent", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [], "name": "externalMetadata", @@ -1752,8 +1698,8 @@ "type": "receive" } ], - "bytecode": "0x610120604052346200071d576200519c803803806200001e816200073d565b928339810160c0828203126200071d57620000398262000763565b90620000486020840162000763565b620000566040850162000763565b60e05260608401516001600160401b0381116200071d5784019382601f860112156200071d57845194620000946200008e8762000778565b6200073d565b9560208088838152019160051b830101918583116200071d57602001905b828210620007225750505060808101516001600160401b0381116200071d5783620000df91830162000790565b60a08201519093906001600160401b0381116200071d5762000102920162000790565b60008054336001600160a01b03198216811783556040519396939290916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09084a36003805460ff191690556608e1bc9bf040006004556001600160401b0360a0820190811190821117620005bd5760a0810160405260fa81526101f460208201526102ee60408201526103e860608201526104e260808201526008906000905b600582106200070257505060408051915081018082116001600160401b0390911117620005bd57604081016040526001815260005b60208110620006a95750805190680100000000000000008211620005bd5760175482601755808310620005d3575b50601760009081526000805160206200517c83398151915292916020015b8282106200039257505050506200024362000911565b60e051600680546001600160a01b0319166001600160a01b03929092169190911790556200027062000911565b600580546001600160a01b0319166001600160a01b03929092169190911790556200029a62000911565b600780546001600160a01b0319166001600160a01b039290921691909117905560005b83518110156200038257620002e0620002d78284620008a6565b511515620008d1565b620003026001600160a01b03620002f88387620008a6565b51161515620008d1565b6001600160a01b03620003168286620008a6565b5116620003248285620008a6565b51600052601860205260406000206200033e8385620008a6565b5160005260205260406000209060018060a01b031982541617905560001981146200036c57600101620002bd565b634e487b7160e01b600052601160045260246000fd5b60405161481190816200096b8239f35b60a08151600180831b0381511686549060ff841b60208401511515851b169160018060a81b031916171786556040810151600187015560608101516002870155608081015160038701550151805190680100000000000000008211620005bd57600486015482600488015580831062000547575b50602001906004860160005260206000206000915b8083106200043b575050505060056020600192019401910190926200022d565b969593949a91989b929990978a518051151560ff80198c54169116178a55602081015160018b0155604081015160028b0155606081015160805260038a0160c05260005b6005811062000526575060800151610100526008890160a05260005b60068110156200050557600190600761010051602081519160c083519360a051948555838101518886015560408101516002860155606081015160038601556080810151600486015560a081015160058601550151600684015501610100520160a052016200049b565b5097929b989099603260206001929d97969899949d0194019101916200041b565b60019081608051602081519160c051928355016080520160c052016200047f565b62000552906200081e565b6200055d836200081e565b906004880160005260206000209182015b81830181106200058057505062000406565b806000603292556000600182015560006002820155620005b660088201620005ac81600385016200084f565b8383019062000868565b016200056e565b634e487b7160e01b600052604160045260246000fd5b620005de90620007ed565b620005e983620007ed565b60176000526000805160206200517c833981519152919082015b8183018110620006155750506200020f565b60008155600060018201556000600282015560006003820155600481015460006004830155806200064b575b5060050162000603565b62000656906200081e565b600482016000526020600020908101905b81811062000676575062000641565b806000603292556000600182015560006002820155620006a260088201620005ac81600385016200084f565b0162000667565b604051906001600160401b0360c0830190811190831117620005bd578160c06020930160405260008152600083820152600060408201526000606082015260006080820152606060a082015282828501015201620001e1565b600160208261ffff83945116865501930191019091620001ac565b600080fd5b60208091620007318462000763565b815201910190620000b2565b6040519190601f01601f191682016001600160401b03811183821017620005bd57604052565b51906001600160a01b03821682036200071d57565b6001600160401b038111620005bd5760051b60200190565b9080601f830112156200071d57815190620007af6200008e8362000778565b9182938184526020808095019260051b8201019283116200071d578301905b828210620007dd575050505090565b81518152908301908301620007ce565b7f333333333333333333333333333333333333333333333333333333333333333381116001166200036c5760050290565b7f051eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851e81116001166200036c5760320290565b8181106200085b575050565b600081556001016200084f565b81811062000874575050565b600790600080825580600183015580600283015580600383015580600483015580600583015560068201550162000868565b8051821015620008bb5760209160051b010190565b634e487b7160e01b600052603260045260246000fd5b15620008d957565b60405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103b32b934b334b2b960811b6044820152606490fd5b6000546001600160a01b031633036200092657565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fdfe6101006040526004361015610098575b361561005c57346100575760405162461bcd60e51b81526020600482015260156024820152746e6f2066616c6c6261636b207468616e6b20796f7560581b6044820152606490fd5b600080fd5b60405162461bcd60e51b81526020600482015260146024820152736e6f2072656365697665207468616e6b20796f7560601b6044820152606490fd5b6000803560e01c8063010520a114612eef578063014a30d214612ea657806301ffc9a714612e50578063041df08214612e3657806306575c8914612e1b57806308cdc2a814612de1578063098b5e9314612d3a5780630b27ce3f14612d1157806310d80a5514612ce6578063132d5ed914612cc8578063158b38b614612c865780632a55205a14612be25780632b057afa14612b965780632e93a49214612b605780633190b9ea14612a93578063355f74071461285057806335d6f0cc14612a715780633bdbdb7114612a525780633ef2570b14612a2d57806343569ffb146129f65780634b9862d9146129da5780634caa028b146129915780634dbe7f73146129615780635103d6ea146128cc5780635120a261146128af578063530ab7dc1461286057806353e52f09146128505780635542437b146128095780635bd6b2ea146127c05780635c9302c91461279e5780635c975abb1461277b5780636498c128146127445780636ef24f2d1461269d57806370180bc11461264c578063715018a6146125ee57806371b8ccb0146125a3578063770c5da11461256c5780637a19b190146124c5578063861f7556146123ab57806387b07780146123825780638cc52cf3146123645780638d6cc56d1461233f5780638da5cb5b14612318578063907311b1146122715780639196b700146122315780639654c1f7146122045780639691f1ab146121dd57806398a6a641146121995780639bc4961714612170578063a035b1fe14612152578063a4830114146120a6578063ac4a60471461205d578063adcbb85b14611fd0578063ae66f57c14611ee7578063b24f67b814611df7578063bd2c955214611d36578063c4b9d59f14611c00578063c8b90ebb14611b4c578063cc80b8ea14611b05578063d8531e6e14611aba578063de89d1c1146105b2578063e2adba8c14610596578063ed3437f814610579578063f2fde38b146104b3578063f6fbc39a14610410578063f81c8ec3146103f2578063f9cfa06f146103d45763ffd73d3b14610391575b5061000f565b346103d15761039f366131cc565b91908152600d602052604081209060038310156103d15760206103c284846133e9565b90549060031b1c604051908152f35b80fd5b50346103d157806003193601126103d1576020604051620151808152f35b50346103d157806003193601126103d1576020604051620f42408152f35b50346103d15760203660031901126103d15760043563ffffffff60e01b81168091036104af576020906301ffc9a760e01b811490811561049e575b811561048d575b811561047c575b811561046b575b506040519015158152f35b632483248360e11b14905082610460565b63152a902d60e11b81149150610459565b6303a24d0760e21b81149150610452565b636cdb3d1360e11b8114915061044b565b5080fd5b50346103d15760203660031901126103d1576104cd61326f565b6104d561358f565b6001600160a01b03908116801561052557600080546001600160a01b03198116831782556040519316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09084a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b50346103d157806003193601126103d15760206040516103e88152f35b50346103d157806003193601126103d157602060405160058152f35b5060c03660031901126103d1576024356001600160401b0381116104af576105de903690600401613142565b6044356001600160401b038111611ab6576105fd903690600401613523565b6064356001600160401b038111611ab25736602382011215611ab2578060040135906106288261312b565b91610636604051938461310a565b80835260208301913660248360071b83010111611a4e5760248101925b60248360071b8301018410611a5657505050506084356001600160401b038111611a5257610685903690600401613523565b916001600160401b0360a43511611a525736602360a435011215611a52576106b260a4356004013561312b565b916106c0604051938461310a565b60a4356004013583526020830136602460a4356004013560051b60a435010111611a4e57602460a43501905b602460a4356004013560051b60a43501018210611a1a5750506004359360ff600354166119e05761072262015180420642613637565b938515611623575b61073386613466565b50546001600160a01b031633036115cf5760ff61074f87613466565b505460a01c1661159557600361076487613466565b500154850361154157875b815181101561153b5786610783828a613623565b5161078e8388613623565b519061079a8488613623565b516107a58588613623565b51906107b18688613623565b519260046107c86107c286516145d7565b97613466565b5001548096036114f657600186106114a65760ff6107f76107e88f613466565b50600019890190600401613a3c565b5054166114ba5760011986116114a6578e9060018701825260186020526040822091526020528d604060018060a01b039120541693841561146e5761083e60018701613212565b80196005116112dd5760011960058201116112dd5733906001600160a01b039061086b9060060187613623565b51160361141b5761089a60036108938f61088490613466565b506000198a0190600401613a3c565b5001613642565b604051906108a782612f6b565b6108bb6108b660018a01613228565b613212565b80196005116114045760021960058201116114045760076108dd910187613623565b5182526108ef6108b660018a01613228565b801960051161140457600219600582011161140457600119600782011161140457600861091d910187613623565b5160208301526109326108b660018a01613228565b8019600511611404576002196005820111611404576002196007820111611404576009610960910187613623565b5160408301526109756108b660018a01613228565b801960051161140457600219600582011161140457600319600782011161140457600a6109a3910187613623565b5160608301526109b86108b660018a01613228565b801960051161140457600219600582011161140457600419600782011161140457600b6109e6910187613623565b518060808401528061131e575b505050604051610a0281612f6b565b610a0b856135f6565b518152610a1785613603565b516020820152610a2685613613565b5160408201528451600310156113085760808501516060820152845160041015611308578f60038f610a64610a739160a08a01516080870152613466565b506000198b0190600401613a3c565b500190915b600583106112f257505050610a8f60018701613212565b80196005116112dd5791610ab79391610aac869460050185613623565b519660018901614156565b610ae9610ade610ad8610ac98d613466565b50600019870190600401613a3c565b50613687565b926020840151613839565b8060208401526005600019850110156112c95760078401541061128e578b828b859383610b146137af565b505b6001860181106111a657505090610b41610b32610b4793613466565b50600019860190600401613a3c565b90613a58565b14610b5d575b5050610b58906135e7565b61076f565b906020600592610b87610b788c9b989d99969c9a979a613466565b50600019850190600401613a3c565b50600160ff19825416179055828a8383015160405190815289858201527f416328325568dd8681e48de39e8d89a80ddf01a688fbcb49c28c621071c9333b60403392a40151610be46001610bda8b613466565b5001918254613839565b90550361118c57610bf486613466565b50805460ff60a01b1916600160a01b1790556004543403611153576005546040518a918291829134906001600160a01b03165af1610c30613c61565b6007548b906001600160a01b0316803b156104af5781809160a48c604051948593849263093ccd3160e41b8452336004850152602484015260016044840152608060648401528160848401525af1801561114857611130575b50507fb08889abce443443404b2caf69aa3ccfb9ebfdf1ad2a634d06e11e24c1067938610ccf60018060a01b0360055416926040519182916040835260408301906134d6565b943460208301521515940390a3856001610ce882613466565b5001546040519081528460208201527f7f05a2f6290fe88fe25ed1665c50706361d709c5003e3067340b9053916fd70760403392a3338952601460205260408920610d3381546135e7565b9055610d47610d4187613466565b50613c9e565b97895b60808a01518b52600d6020528a600382101561111f57610d41610d7a836040610d86948f608001518152206133e9565b90549060031b1c613466565b6040808c0151910151809110908115611116575b50610dad57610da8906135e7565b610d4a565b896080899a94979b9993969998959801518c52600d60205260025b82811161109f5750610e05916080610dec9201518d52600d60205260408d206133e9565b819391549060031b600019811b9283911b169119161790565b90555b6003610e1388613466565b500154338a52601460205260408a209060405191610e3083612f86565b805483526002600182015491826020860152015460408401526201518019811161108b576201518001811461107457600160408301525b6020820152338a52601460205260408a20815181556020820151600182015560026040830151910155895b60038110610fc9575b5050338952601460205260408920600260405191610eb883612f86565b805483526001810154602084015201546040820152895b60038110610ee6575b5050610b58905b9038610b4d565b8151600e8201546001600160a01b03168c52601460205260408c205410610f1557610f10906135e7565b610ecf565b905060025b818111610f3e5750600e0180546001600160a01b03191633179055610b5838610ed8565b60018110610fb557600360001982011015610fa157600d8101546001600160a01b03166003821015610f8d57600e820180546001600160a01b0319169091179055610f8890613c91565b610f1a565b634e487b7160e01b8c52603260045260248cfd5b634e487b7160e01b8b52603260045260248bfd5b634e487b7160e01b8b52601160045260248bfd5b60408281015160118301546001600160a01b03168d526014602052908c206002015410610ffe57610ff9906135e7565b610e92565b905060025b818111611025575060110180546001600160a01b031916331790553880610e9b565b60018110610fb557600360001982011015610fa15760108101546001600160a01b03166003821015610f8d576011820180546001600160a01b031916909117905561106f90613c91565b611003565b61108160408301516135e7565b6040830152610e67565b634e487b7160e01b8c52601160045260248cfd5b9091925060808201518c52600d60205260408c206001821061110257908c6110f2610dec8360406110d86110f9976000198401906133e9565b90549060031b1c9460808901518152600d602052206133e9565b9055613c91565b90899291610dc8565b634e487b7160e01b8d52601160045260248dfd5b90501538610d9a565b505092959690939750939093610e08565b61113990612f3d565b611144578a38610c89565b8a80fd5b6040513d84823e3d90fd5b60405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081c185e5b595b9d607a1b6044820152606490fd5b9296919495610b58906111a188969396613b51565b610edf565b92819495506111d59250906111c084608081940151613819565b516111d08360018b018484613de7565b613cf5565b8115611234575b60a081015115611217575b906112068161120c936080880151906112008383613819565b52613819565b506135e7565b8b8593928592610b16565b92906112068161122961120c946135e7565b9592509250506111e7565b60a08101516111dc5760405162461bcd60e51b8152602060048201526024808201527f596f752073686f742074686520626f647920796f752073686f756c642070726f6044820152631d1958dd60e21b6064820152608490fd5b60405162461bcd60e51b8152602060048201526013602482015272151a5b59481b1a5b5a5d08195e18d959591959606a1b6044820152606490fd5b634e487b7160e01b8d52603260045260248dfd5b50634e487b7160e01b8f52601160045260248ffd5b6001602082829351855501920192019190610a78565b634e487b7160e01b600052603260045260246000fd5b815190835180921492836113f1575b836113de575b836113cb575b836113bd575b50501591826113ac575b5081156113a4575b501561135f573880806109f3565b60405162461bcd60e51b815260206004820152601760248201527f496e76616c696420696e666c696768744d697373696c650000000000000000006044820152606490fd5b905038611351565b60200151620f424014915038611349565b60800151149150388061133f565b9250606083015160608501511492611339565b9250604083015160408501511492611333565b925060208301516020850151149261132d565b50505060248f634e487b7160e01b81526011600452fd5b60405162461bcd60e51b815260206004820152602560248201527f4f776e6572206f6620746869732070726f6f66206973206e6f7420746865207360448201526432b73232b960d91b6064820152608490fd5b60405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103b32b934b334b2b960811b6044820152606490fd5b634e487b7160e01b8f52601160045260248ffd5b60405162461bcd60e51b815260206004820152601460248201527313195d995b08185b1c9958591e481cdbdb1d995960621b6044820152606490fd5b60405162461bcd60e51b815260206004820152601f60248201527f50726576696f7573206c6576656c206e6f742079657420636f6d706c657465006044820152606490fd5b88604051f35b60405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c7920736f6c76652072756e73206f6e207468652063757272656044820152656e742064617960d01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526012602482015271149d5b88185b1c9958591e481cdbdb1d995960721b6044820152606490fd5b60405162461bcd60e51b815260206004820152602660248201527f4f6e6c7920746865206f776e6572206f66207468652072756e2063616e20736f6044820152651b1d99481a5d60d21b6064820152608490fd5b94506017549460405160a05261163a60a051612f50565b87602060a051015287604060a051015287606060a051015287608060a0510152606060a0805101523360a05152600143106119ca57604051866020820152600060408201526000194301406060820152606081528060808101106001600160401b036080830111176119b4576080810160405260208151910120606060a051015284608060a0510152600160401b8610156119a057600186016017556116df86613466565b61198c5760a0805180518354602083015160ff60a01b901515851b166001600160a01b039092166001600160a81b0319909116171783556040810151600184015560608101516002840155608081015160038401550151805190600160401b82116119785760048301548260048501558083106118cb575b5060206004910192018a5260208a208a905b8282106117be57505050507fbe33ae7a5df03243155e17a5896a63473638d0a5042d1504b59ea59ff0f2b0a560608060a0510151604051908982528860208301526040820152a16117b986613b51565b61072a565b95839a939b94959892999b979197516117e681511515899060ff801983541691151516179055565b60208101516001890155604081015160028901556060810151600389016080526000905b600582106118a45750506080015198600888019660009a5b60068c101561188357600760208260c0600194518d815190558d86858301519101558d600260408301519101558d600360608301519101558d600460808301519101558d600560a0830151910155015160068d01550199019b019a97611822565b50959c9a929893995095509592996032602060019201940192019091611769565b805160c08190526080805160e081905291825560019182019052919091019060200161180a565b6118d4906131e2565b6118dd836131e2565b90600485018d5260208d209182015b81830181106118fc575050611757565b8d81556000600182015560006002820155600381015b60088201811061196c5750600881015b60328201811061193557506032016118ec565b8060006007925560006001820155600060028201556000600382015560006004820155600060058201556000600682015501611922565b60008155600101611912565b634e487b7160e01b8b52604160045260248bfd5b634e487b7160e01b89526004899052602489fd5b634e487b7160e01b88526041600452602488fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60405162461bcd60e51b815260206004820152601260248201527110dbdb9d1c9858dd081a5cc81c185d5cd95960721b6044820152606490fd5b6001600160401b03823511611a4a5760208091611a3f366024863560a4350101613142565b8152019101906106ec565b8780fd5b8680fd5b8480fd5b36601f8501121561005757604051611a6d81612fa1565b803660808701116100575785905b608087018210611a98575050815260809390930192602001610653565b6020604091611aa736856133f9565b815201910190611a7b565b8380fd5b8280fd5b50346103d15760203660031901126103d157600435906001600160401b0382116103d157610680611af6611af13660048601613142565b614693565b611b0360405180926134fb565bf35b50346103d15760203660031901126103d1576004356001600160a01b038116908190036104af57611b3461358f565b6001600160601b0360a01b6005541617600555604051f35b50346103d157602090816003193601126103d1576004356001600160401b0381116104af57611b7f903690600401613142565b9060405192611b8d84613062565b610a40809436903760405192611ba284613062565b84368537825b60528110611bda5750506040519291835b60528210611bc5578585f35b82806001928651815201940191019092611bb9565b80611beb611bf89284979697613623565b518160051b8601526135e7565b939293611ba8565b50346103d15760603660031901126103d1576001600160a01b0360443581811690819003610057578291611c3261358f565b60405190611c5460209260043584820152838152611c4f81612fa1565b6147b8565b611c6d60405160243585820152848152611c4f81612fa1565b906040519484860152838552611c8285612fa1565b606060405194611c9186613047565b6003865236908601377f04d76c509b8f988dc8955b929b113410ea0e0897373914a00b48ea522da64173611cc4856135f6565b52611cce84613603565b52611cd883613613565b526007541691823b15611d3157611d089284928360405180968195829463b46f007160e01b84526004840161476b565b03925af1801561114857611d1d575b50604051f35b611d2690612f3d565b6103d1578038611d17565b505050fd5b50346103d1576020806003193601126104af57611d5f6004611d588135613466565b5001613759565b6040519180830181845282518091528160408501930191855b828110611d855785850386f35b90919293828551805115158352818101518284015260408101516040840152606080820151908401908a915b60058310611de157505050600192611dd560806106409301516101008301906132f4565b01950193929101611d78565b8151815287946001909301929182019101611db1565b50346103d1576020806003193601126104af5760065460405163295d33a960e21b81526004803590820152908390829060249082906001600160a01b03165afa928315611edb578093611e5f575b5050611e5b6040519282849384528301906134d6565b0390f35b909192503d8082843e611e72818461310a565b82019183818403126104af578051906001600160401b038211611ab6570182601f820112156104af57805191611ea783613c46565b93611eb5604051958661310a565b8385528584840101116103d1575090611ed3918480850191016134a1565b903880611e45565b604051903d90823e3d90fd5b50346103d15760203660031901126103d157600435906017548210156103d15760a0600583601760005202807fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150154907fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c16810154907fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c187fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c178201549101549160ff60405194600180881b0381168652861c1615156020850152604084015260608301526080820152f35b50346103d15760203660031901126103d1576004356001600160a01b038116908190036104af57611fff61358f565b47907fb08889abce443443404b2caf69aa3ccfb9ebfdf1ad2a634d06e11e24c106793861204c84808060405187875af1612037613c61565b906040519283926040845260408401906134d6565b9560208301521515940390a3604051f35b50346103d15760203660031901126103d157600435906001600160401b0382116103d1576107c06120996120943660048601613142565b6146db565b611b03604051809261343e565b50346103d157806120b6366131cc565b6120be61358f565b6040519160208301526040820152604081526120d981612f86565b6040516120e581612fa1565b60018152602036818301377f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c61211a826135f6565b526007546001600160a01b031691823b15611d3157611d089284928360405180968195829463b46f007160e01b84526004840161476b565b50346103d157806003193601126103d1576020600454604051908152f35b50346103d157806003193601126103d1576006546040516001600160a01b039091168152602090f35b50346103d1576121a836613285565b9160018060a01b03168352601560205260408320908352602052604082206007821015611ab657602092500154604051908152f35b50346103d15760203660031901126103d15760206121fc60043561398d565b604051908152f35b50346103d15760203660031901126103d15760043560058110156104af5760209060080154604051908152f35b50346103d157806003193601126103d157601754906001821061225d5760405160001983018152602090f35b634e487b7160e01b81526011600452602490fd5b50346103d157602090816003193601126103d1576004356001600160401b0381116104af576122a4903690600401613142565b90604051926122b28461302b565b610b808094369037604051926122c78461302b565b84368537825b605c81106122ff5750506040519291835b605c82106122ea578585f35b828060019286518152019401910190926122de565b80611beb6123109284979697613623565b9392936122cd565b50346103d157806003193601126103d157546040516001600160a01b039091168152602090f35b50346103d15760203660031901126103d15761235961358f565b600435600455604051f35b50346103d157806003193601126103d15760206040516204f1a08152f35b50346103d157806003193601126103d1576007546040516001600160a01b039091168152602090f35b50346103d1576101603660031901126103d1576024356001600160a01b038116810361005757366063121561005757604051906123e782612fa1565b608482368211610057576044905b8282106124b55750503660a312156100575760405161241381612fa1565b806101049236841161005757905b83821061249b575050366101231215610057576040519161244183612fa1565b826101449136831161005757905b82821061248b57505035936001600160401b03851161248757612479612482953690600401613142565b93600435614156565b604051f35b8580fd5b813581526020918201910161244f565b60206040916124aa36856133f9565b815201910190612421565b81358152602091820191016123f5565b50346103d157602090816003193601126103d1576004356001600160401b0381116104af576124f8903690600401613142565b90604051926125068461300f565b6102c080943690376040519261251b8461300f565b84368537825b601681106125535750506040519291835b6016821061253e578585f35b82806001928651815201940191019092612532565b80611beb6125649284979697613623565b939293612521565b50346103d15760203660031901126103d15760043560038110156104af57600e01546040516001600160a01b039091168152602090f35b50346103d1576125b2366131cc565b919081526016602052604081209060038310156103d15760206125d584846133e9565b905460405160039290921b1c6001600160a01b03168152f35b50346103d157806003193601126103d15761260761358f565b600080546001600160a01b03198116825560405191906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b50346103d15760203660031901126103d1576060906040906001600160a01b0361267461326f565b168152601460205220805490600260018201549101549060405192835260208301526040820152f35b50346103d157602090816003193601126103d1576004356001600160401b0381116104af576126d0903690600401613142565b90604051926126de84612ff3565b610cc08094369037604051926126f384612ff3565b84368537825b6066811061272b5750506040519291835b60668210612716578585f35b8280600192865181520194019101909261270a565b80611beb61273c9284979697613623565b9392936126f9565b50346103d15760203660031901126103d15760043560038110156104af57601101546040516001600160a01b039091168152602090f35b50346103d157806003193601126103d157602060ff600354166040519015158152f35b50346103d157806003193601126103d15760206121fc62015180420642613637565b50346103d15760203660031901126103d157600435906001600160401b0382116103d1576109006127fc6127f73660048601613142565b614723565b611b0360405180926133c1565b50346103d15760203660031901126103d1576004356001600160a01b038116908190036104af5761283861358f565b6001600160601b0360a01b6007541617600755604051f35b505061285a6132af565b3861038b565b50346103d1576101403660031901126103d15761287c36613360565b60e435906001600160401b038211611ab65761289f612482923690600401613142565b9061012435916101043591613de7565b50346103d157806003193601126103d1576020604051614e208152f35b50346103d1576101203660031901126103d1576128e836613360565b9060e435906001600160401b0382116103d15760e06129188461290e3660048701613142565b6101043591613cf5565b611b03604051809260c08091805184526020810151602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b50346103d15761056061297c612976366131cc565b90613845565b61298960405180936132f4565b610540820152f35b50346103d15760203660031901126103d157600435906001600160401b0382116103d1576105406129cd6129c83660048601613142565b61464b565b611b0360405180926132cc565b50346103d157806003193601126103d157602060405160148152f35b50346103d157602090612a08366131cc565b90825260188352604082209082528252604060018060a01b0391205416604051908152f35b50346103d15760603660031901126103d15760206121fc60443560243560043561389e565b50346103d15760203660031901126103d15760206121fc6004356145d7565b50346103d15760403660031901126103d15760e06129186024356004356138c7565b50346103d15760203660031901126103d157612aad61358f565b604051600435602082015260208152612ac581612fa1565b8160405191612ad383612fa1565b60018352602036818501377ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7612b08846135f6565b526007546001600160a01b0316803b15611ab657612b3d938360405180968195829463b46f007160e01b84526004840161476b565b03925af1801561114857612b515750604051f35b612b5a90612f3d565b38611d17565b50346103d157806003193601126103d157612b79613a1a565b9062093a8019821161225d5760206121fc4262093a808501613637565b50346103d157612ba536613285565b90612bae61358f565b8352601860205260408320908352602052604082209060018060a01b03166001600160601b0360a01b825416179055604051f35b50346103d157612bf1366131cc565b90825260026020526040822060405190612c0a82612fa1565b546001600160a01b0380821680845260a09290921c6020840152919015612c64575b6001600160601b0360208201511693836000190485118415151661225d57509261271091604094511692845193845202046020820152f35b50604051612c7181612fa1565b600154828116825260a01c6020820152612c2c565b50346103d15760203660031901126103d157612ca061326f565b612ca861358f565b60018060a01b03166001600160601b0360a01b6006541617600655604051f35b50346103d157806003193601126103d157602060405162093a808152f35b50346103d15760203660031901126103d15760206004612d068135613466565b500154604051908152f35b50346103d157806003193601126103d1576005546040516001600160a01b039091168152602090f35b50346103d157602090816003193601126103d1576004356001600160401b0381116104af57612d6d903690600401613142565b9060405192612d7b84612fd7565b610e00809436903760405192612d9084612fd7565b84368537825b60708110612dc85750506040519291835b60708210612db3578585f35b82806001928651815201940191019092612da7565b80611beb612dd99284979697613623565b939293612d96565b50346103d15760203660031901126103d1576004358015158091036104af57612e0861358f565b60ff801960035416911617600355604051f35b50346103d157806003193601126103d15760206121fc613a1a565b50346103d15760206121fc612e4a366131cc565b906139e9565b50346103d15760203660031901126103d15760043563ffffffff60e01b81168091036104af5760209063152a902d60e11b8114908115612e9557506040519015158152f35b6301ffc9a760e01b14905082610460565b50346103d15760203660031901126103d157600435906001600160401b0382116103d157610400612ee2612edd3660048601613142565b6145f6565b611b0360405180926131a0565b50346103d15760603660031901126103d15760043590612f1182602435613637565b908115612f295760206121fc84846044350690613839565b634e487b7160e01b81526012600452602490fd5b6001600160401b0381116119b457604052565b60c081019081106001600160401b038211176119b457604052565b60a081019081106001600160401b038211176119b457604052565b606081019081106001600160401b038211176119b457604052565b604081019081106001600160401b038211176119b457604052565b60e081019081106001600160401b038211176119b457604052565b610e0081019081106001600160401b038211176119b457604052565b610cc081019081106001600160401b038211176119b457604052565b6102c081019081106001600160401b038211176119b457604052565b610b8081019081106001600160401b038211176119b457604052565b608081019081106001600160401b038211176119b457604052565b610a4081019081106001600160401b038211176119b457604052565b61040081019081106001600160401b038211176119b457604052565b61054081019081106001600160401b038211176119b457604052565b61068081019081106001600160401b038211176119b457604052565b6107c081019081106001600160401b038211176119b457604052565b61090081019081106001600160401b038211176119b457604052565b90601f801991011681019081106001600160401b038211176119b457604052565b6001600160401b0381116119b45760051b60200190565b81601f82011215610057578035916131598361312b565b92613167604051948561310a565b808452602092838086019260051b820101928311610057578301905b828210613191575050505090565b81358152908301908301613183565b916000915b602090818410156131c557908060019286518152019401920191926131a5565b5050915050565b6040906003190112610057576004359060243590565b7f051eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851e81116001166119ca5760320290565b8060001904600511811515166119ca5760050290565b6001600160ff1b0381116001166119ca5760011b90565b7f333333333333333333333333333333333333333333333333333333333333333381116001166119ca5760050290565b600435906001600160a01b038216820361005757565b6060906003190112610057576004356001600160a01b038116810361005757906024359060443590565b503461005757600036600319011261005757602060405160028152f35b6000915b602a83106132dd57505050565b6001908251815260208091019201920191906132d0565b906000905b6006821061330657505050565b602060e082613354600194875160c08091805184526020810151602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b019301910190916132f9565b60e0906003190112610057576040519060e082018281106001600160401b038211176119b457604052816004358152602435602082015260443560408201526064356060820152608435608082015260a43560a082015260c060c435910152565b6000915b604883106133d257505050565b6001908251815260208091019201920191906133c5565b6003821015611308570190600090565b9080601f83011215610057576040519161341283612fa1565b82906040810192831161005757905b82821061342e5750505090565b8135815260209182019101613421565b6000915b603e831061344f57505050565b600190825181526020809101920192019190613442565b601754811015611308576005906017600052027fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150190600090565b918091926000905b8282106134c15750116134ba575050565b6000910152565b915080602091830151818601520182916134a9565b906020916134ef815180928185528580860191016134a1565b601f01601f1916010190565b6000915b6034831061350c57505050565b6001908251815260208091019201920191906134ff565b81601f820112156100575780359061353a8261312b565b9260409261354a8451958661310a565b808552602091828087019260061b85010193818511610057578301915b8483106135775750505050505090565b83869161358484866133f9565b815201920191613567565b6000546001600160a01b031633036135a357565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60001981146119ca5760010190565b8051156113085760200190565b8051600110156113085760400190565b8051600210156113085760600190565b80518210156113085760209160051b010190565b8181106119ca570390565b60405191906000835b600582106136715750505060a082018281106001600160401b038211176119b457604052565b600160208192855481520193019101909161364b565b90604080519261369684612f6b565b8360ff82541615158152600193848301549160209283820152600290818501548682015260036136c7818701613642565b90606091828401528751976136db89612f50565b60009760080195895b6006808b101561374657898d9260079286519061370082612fbc565b8c548252858d0154848301528b8d015488830152888d01548a83015260048d0154608083015260058d015460a08301528c015460c08201528152019801990198966136e4565b5050995050505092505050608091500152565b9081546137658161312b565b92613773604051948561310a565b818452600090815260208082208186015b848410613792575050505050565b6032836001926137a185613687565b815201920193019290613784565b604051906137bc82612fbc565b8160c06000918281528260208201528260408201528260608201528260808201528260a08201520152565b604051906137f482612f50565b8160005b60c08110613804575050565b60209061380f6137af565b81840152016137f8565b9060068110156113085760051b0190565b612710811981116119ca570190565b811981116119ca570190565b919061384f6137e7565b9260005b8281111561386c57505060011981116119ca5760010190565b806138848161387f61389994878761389e565b6138c7565b61388e8288613819565b526112068187613819565b613853565b91604051916020830193845260408301526060820152606081526138c181613047565b51902090565b613985906138d36137af565b506138ee6138df6137af565b938085528260c086015261398d565b60a08401526040519060209182810191825282815261390c81612fa1565b519020620f4240908181068386015260405183810191825283815261393081612fa1565b519020908106604085015260405182810191825282815261395081612fa1565b519020614e209161396283830661382a565b606086015260405190808201928352815261397c81612fa1565b5190200661382a565b608082015290565b6139d060ff916006604051916139a283612f50565b60248352601b60208401526016604084015260116060840152600c6080840152600760a08401520690613819565b51166103e89080600019048211811515166119ca570290565b90600143106119ca57604051906020820192835260408201526000194301406060820152606081526138c181613047565b6204f1a042106119ca57613a3962093a806204f19f1942010642613637565b90565b8054821015611308576000526032602060002091020190600090565b9290613b3b57613a79829392511515839060ff801983541691151516179055565b6020918284015192600193848301556040948581015193600294858501556060918281015160039081870190896000915b60058310613b27575050505060086080809301519601936000965b600680891015613b1957815180518855888101518c8901558c8101518b890155838101518589015585810151600489015560a0810151600589015560c0015190870155968901966007909501948601613ac5565b505050505095505050505050565b80518455928101929101908a908801613aaa565b634e487b7160e01b600052600060045260246000fd5b6003613b5c82613466565b500154906004613b6b82613466565b50015460011981116119ca576001019060405192613b8884612f6b565b6000845260006020850152604084019260008452604051613ba881612f6b565b60a0368237606086015260808501613bbe6137e7565b8152613bca82856139e9565b8552613bd68284613845565b5090526004613be484613466565b5001938454600160401b8110156119b4577f70f3b6a85b7a5047df9e61440f8b6480a7cd8a96f849a4092d0a22303a5dbb0f96610b41826080986001613c2c95018155613a3c565b5190604051938452602084015260408301526060820152a1565b6001600160401b0381116119b457601f01601f191660200190565b3d15613c8c573d90613c7282613c46565b91613c80604051938461310a565b82523d6000602084013e565b606090565b80156119ca576000190190565b90604051613cab81612f50565b60a0613cf06004839560ff8154600180871b0381168752851c161515602086015260018101546040860152600281015460608601526003810154608086015201613759565b910152565b9190613cff6137af565b50613d0982613212565b91600592801984116119ca57613d2190840183613623565b516020850152613d3081613212565b801984116119ca57600119848201116119ca576006613d50910183613623565b516040850152613d5f81613212565b801984116119ca57600219848201116119ca576007613d7f910183613623565b516060850152613d8e81613212565b90811984116119ca57600319848301116119ca57613db26008613dbd930184613623565b516080860152613212565b91821981116119ca57600419908301116119ca576009613dde920190613623565b5160a082015290565b9291906020928385015190613dfb8461323f565b90600591801983116119ca57613e1c90613e1483613212565b908401613839565b60021993908481116119ca576002613e35910186613623565b51036140ac576040870151613e498661323f565b801984116119ca57613e6690613e5e84613212565b908501613839565b60011981116119ca578460018201116119ca576003613e86910186613623565b510361407257606087015196613e9b8661323f565b801984116119ca57613eb090613e5e84613212565b978489116119ca578460028a01116119ca57613ed06004809a0187613623565b510361403b576080810151613ee48761323f565b8019851161402657613f0190613ef985613212565b908601613839565b6003198111614026578560038201116140265784613f20910187613623565b5103613fef5760a0613f349101519561323f565b9081198311613fda5790613f4b613f529392613212565b9101613839565b906004198211613fc55785820111613fb057906006613f72920190613623565b5103613f7c575050565b60405162461bcd60e51b815291820152600e60248201526d496e76616c69642072616469757360901b604482015260649150fd5b601185634e487b7160e01b6000525260246000fd5b601186634e487b7160e01b6000525260246000fd5b601188634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808901889052601060248201526f496e76616c696420766563746f72207960801b6044820152606490fd5b60118a634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808901889052601060248201526f092dcecc2d8d2c840eccac6e8dee440f60831b6044820152606490fd5b60405162461bcd60e51b8152600481018790526012602482015271496e76616c696420706f736974696f6e207960701b6044820152606490fd5b60405162461bcd60e51b8152600481018790526012602482015271092dcecc2d8d2c840e0dee6d2e8d2dedc40f60731b6044820152606490fd5b90816020910312610057575180151581036100575790565b6000915b6002831061410f57505050565b600190825181526020809101920192019190614102565b906000905b6002821061413857505050565b602060408261414a60019487516140fe565b0193019101909161412b565b939091929360028114600014614259575091610504916141c16141a2946141b6614182602098996145f6565b916141ac6040519a8b998a98630f3022c960e21b8a5260048a01906140fe565b6044880190614126565b60c48601906140fe565b6101048401906131a0565b6001600160a01b03165afa90811561424d5760009161421f575b50156141e357565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21019103137b23c90383937b7b360611b6044820152606490fd5b614240915060203d8111614246575b614238818361310a565b8101906140e6565b386141db565b503d61422e565b6040513d6000823e3d90fd5b60038103614324575091610644916142a86141a29461429d61427d6020989961464b565b916141ac6040519a8b998a986371dd4db160e11b8a5260048a01906140fe565b6101048401906132cc565b6001600160a01b03165afa90811561424d57600091614306575b50156142ca57565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21019903137b23c90383937b7b360611b6044820152606490fd5b61431e915060203d811161424657614238818361310a565b386142c2565b92939060049584878096146000146143f857509261437c61078493614371602097946141ac6143566141a29b99614693565b936040519b8c9a8b99632a6d5ed560e01b8b528a01906140fe565b6101048401906134fb565b6001600160a01b03165afa90811561424d576000916143da575b501561439f5750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101a103137b23c90383937b7b360611b6044820152fd5b6143f2915060203d811161424657614238818361310a565b38614396565b600581036144c25750926144466108c49361443b602097946141ac6144206141a29b996146db565b936040519b8c9a8b9963ea59061d60e01b8b528a01906140fe565b61010484019061343e565b6001600160a01b03165afa90811561424d576000916144a4575b50156144695750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101a903137b23c90383937b7b360611b6044820152fd5b6144bc915060203d811161424657614238818361310a565b38614460565b600691929394955014600014614593576020936145176141a2969461450c610a04956141ac6144f18c97614723565b936040519b8c9a8b996311b5352360e01b8b528a01906140fe565b6101048401906133c1565b6001600160a01b03165afa90811561424d57600091614575575b501561453a5750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101b103137b23c90383937b7b360611b6044820152fd5b61458d915060203d811161424657614238818361310a565b38614531565b60405162461bcd60e51b8152602081880152601860248201527f496e76616c6964206e756d626572206f6620626f6469657300000000000000006044820152606490fd5b600c81106119ca57600a90600b190104600181106119ca576000190190565b906040516146038161307e565b6104008091369037604051906146188261307e565b36823760005b6020811061462b57509150565b806146396146469286613623565b518160051b8401526135e7565b61461e565b906040516146588161309a565b61054080913690376040519061466d8261309a565b36823760005b602a811061468057509150565b8061463961468e9286613623565b614673565b906040516146a0816130b6565b6106808091369037604051906146b5826130b6565b36823760005b603481106146c857509150565b806146396146d69286613623565b6146bb565b906040516146e8816130d2565b6107c08091369037604051906146fd826130d2565b36823760005b603e811061471057509150565b8061463961471e9286613623565b614703565b90604051614730816130ee565b610900809136903760405190614745826130ee565b36823760005b6048811061475857509150565b806146396147669286613623565b61474b565b9092916040820191604081528451809352606081019260208096019060005b8181106147a457505050613a3993948184039101526134d6565b82518652948701949187019160010161478a565b6020815191015190602081106147cc575090565b6000199060200360031b1b169056fea2646970667358221220ac7db03f69e75e5055d3b93a6033230c77338e458ad1269192a44eeb31a024e964736f6c634300080f0033c624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15", - "deployedBytecode": "0x6101006040526004361015610098575b361561005c57346100575760405162461bcd60e51b81526020600482015260156024820152746e6f2066616c6c6261636b207468616e6b20796f7560581b6044820152606490fd5b600080fd5b60405162461bcd60e51b81526020600482015260146024820152736e6f2072656365697665207468616e6b20796f7560601b6044820152606490fd5b6000803560e01c8063010520a114612eef578063014a30d214612ea657806301ffc9a714612e50578063041df08214612e3657806306575c8914612e1b57806308cdc2a814612de1578063098b5e9314612d3a5780630b27ce3f14612d1157806310d80a5514612ce6578063132d5ed914612cc8578063158b38b614612c865780632a55205a14612be25780632b057afa14612b965780632e93a49214612b605780633190b9ea14612a93578063355f74071461285057806335d6f0cc14612a715780633bdbdb7114612a525780633ef2570b14612a2d57806343569ffb146129f65780634b9862d9146129da5780634caa028b146129915780634dbe7f73146129615780635103d6ea146128cc5780635120a261146128af578063530ab7dc1461286057806353e52f09146128505780635542437b146128095780635bd6b2ea146127c05780635c9302c91461279e5780635c975abb1461277b5780636498c128146127445780636ef24f2d1461269d57806370180bc11461264c578063715018a6146125ee57806371b8ccb0146125a3578063770c5da11461256c5780637a19b190146124c5578063861f7556146123ab57806387b07780146123825780638cc52cf3146123645780638d6cc56d1461233f5780638da5cb5b14612318578063907311b1146122715780639196b700146122315780639654c1f7146122045780639691f1ab146121dd57806398a6a641146121995780639bc4961714612170578063a035b1fe14612152578063a4830114146120a6578063ac4a60471461205d578063adcbb85b14611fd0578063ae66f57c14611ee7578063b24f67b814611df7578063bd2c955214611d36578063c4b9d59f14611c00578063c8b90ebb14611b4c578063cc80b8ea14611b05578063d8531e6e14611aba578063de89d1c1146105b2578063e2adba8c14610596578063ed3437f814610579578063f2fde38b146104b3578063f6fbc39a14610410578063f81c8ec3146103f2578063f9cfa06f146103d45763ffd73d3b14610391575b5061000f565b346103d15761039f366131cc565b91908152600d602052604081209060038310156103d15760206103c284846133e9565b90549060031b1c604051908152f35b80fd5b50346103d157806003193601126103d1576020604051620151808152f35b50346103d157806003193601126103d1576020604051620f42408152f35b50346103d15760203660031901126103d15760043563ffffffff60e01b81168091036104af576020906301ffc9a760e01b811490811561049e575b811561048d575b811561047c575b811561046b575b506040519015158152f35b632483248360e11b14905082610460565b63152a902d60e11b81149150610459565b6303a24d0760e21b81149150610452565b636cdb3d1360e11b8114915061044b565b5080fd5b50346103d15760203660031901126103d1576104cd61326f565b6104d561358f565b6001600160a01b03908116801561052557600080546001600160a01b03198116831782556040519316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09084a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b50346103d157806003193601126103d15760206040516103e88152f35b50346103d157806003193601126103d157602060405160058152f35b5060c03660031901126103d1576024356001600160401b0381116104af576105de903690600401613142565b6044356001600160401b038111611ab6576105fd903690600401613523565b6064356001600160401b038111611ab25736602382011215611ab2578060040135906106288261312b565b91610636604051938461310a565b80835260208301913660248360071b83010111611a4e5760248101925b60248360071b8301018410611a5657505050506084356001600160401b038111611a5257610685903690600401613523565b916001600160401b0360a43511611a525736602360a435011215611a52576106b260a4356004013561312b565b916106c0604051938461310a565b60a4356004013583526020830136602460a4356004013560051b60a435010111611a4e57602460a43501905b602460a4356004013560051b60a43501018210611a1a5750506004359360ff600354166119e05761072262015180420642613637565b938515611623575b61073386613466565b50546001600160a01b031633036115cf5760ff61074f87613466565b505460a01c1661159557600361076487613466565b500154850361154157875b815181101561153b5786610783828a613623565b5161078e8388613623565b519061079a8488613623565b516107a58588613623565b51906107b18688613623565b519260046107c86107c286516145d7565b97613466565b5001548096036114f657600186106114a65760ff6107f76107e88f613466565b50600019890190600401613a3c565b5054166114ba5760011986116114a6578e9060018701825260186020526040822091526020528d604060018060a01b039120541693841561146e5761083e60018701613212565b80196005116112dd5760011960058201116112dd5733906001600160a01b039061086b9060060187613623565b51160361141b5761089a60036108938f61088490613466565b506000198a0190600401613a3c565b5001613642565b604051906108a782612f6b565b6108bb6108b660018a01613228565b613212565b80196005116114045760021960058201116114045760076108dd910187613623565b5182526108ef6108b660018a01613228565b801960051161140457600219600582011161140457600119600782011161140457600861091d910187613623565b5160208301526109326108b660018a01613228565b8019600511611404576002196005820111611404576002196007820111611404576009610960910187613623565b5160408301526109756108b660018a01613228565b801960051161140457600219600582011161140457600319600782011161140457600a6109a3910187613623565b5160608301526109b86108b660018a01613228565b801960051161140457600219600582011161140457600419600782011161140457600b6109e6910187613623565b518060808401528061131e575b505050604051610a0281612f6b565b610a0b856135f6565b518152610a1785613603565b516020820152610a2685613613565b5160408201528451600310156113085760808501516060820152845160041015611308578f60038f610a64610a739160a08a01516080870152613466565b506000198b0190600401613a3c565b500190915b600583106112f257505050610a8f60018701613212565b80196005116112dd5791610ab79391610aac869460050185613623565b519660018901614156565b610ae9610ade610ad8610ac98d613466565b50600019870190600401613a3c565b50613687565b926020840151613839565b8060208401526005600019850110156112c95760078401541061128e578b828b859383610b146137af565b505b6001860181106111a657505090610b41610b32610b4793613466565b50600019860190600401613a3c565b90613a58565b14610b5d575b5050610b58906135e7565b61076f565b906020600592610b87610b788c9b989d99969c9a979a613466565b50600019850190600401613a3c565b50600160ff19825416179055828a8383015160405190815289858201527f416328325568dd8681e48de39e8d89a80ddf01a688fbcb49c28c621071c9333b60403392a40151610be46001610bda8b613466565b5001918254613839565b90550361118c57610bf486613466565b50805460ff60a01b1916600160a01b1790556004543403611153576005546040518a918291829134906001600160a01b03165af1610c30613c61565b6007548b906001600160a01b0316803b156104af5781809160a48c604051948593849263093ccd3160e41b8452336004850152602484015260016044840152608060648401528160848401525af1801561114857611130575b50507fb08889abce443443404b2caf69aa3ccfb9ebfdf1ad2a634d06e11e24c1067938610ccf60018060a01b0360055416926040519182916040835260408301906134d6565b943460208301521515940390a3856001610ce882613466565b5001546040519081528460208201527f7f05a2f6290fe88fe25ed1665c50706361d709c5003e3067340b9053916fd70760403392a3338952601460205260408920610d3381546135e7565b9055610d47610d4187613466565b50613c9e565b97895b60808a01518b52600d6020528a600382101561111f57610d41610d7a836040610d86948f608001518152206133e9565b90549060031b1c613466565b6040808c0151910151809110908115611116575b50610dad57610da8906135e7565b610d4a565b896080899a94979b9993969998959801518c52600d60205260025b82811161109f5750610e05916080610dec9201518d52600d60205260408d206133e9565b819391549060031b600019811b9283911b169119161790565b90555b6003610e1388613466565b500154338a52601460205260408a209060405191610e3083612f86565b805483526002600182015491826020860152015460408401526201518019811161108b576201518001811461107457600160408301525b6020820152338a52601460205260408a20815181556020820151600182015560026040830151910155895b60038110610fc9575b5050338952601460205260408920600260405191610eb883612f86565b805483526001810154602084015201546040820152895b60038110610ee6575b5050610b58905b9038610b4d565b8151600e8201546001600160a01b03168c52601460205260408c205410610f1557610f10906135e7565b610ecf565b905060025b818111610f3e5750600e0180546001600160a01b03191633179055610b5838610ed8565b60018110610fb557600360001982011015610fa157600d8101546001600160a01b03166003821015610f8d57600e820180546001600160a01b0319169091179055610f8890613c91565b610f1a565b634e487b7160e01b8c52603260045260248cfd5b634e487b7160e01b8b52603260045260248bfd5b634e487b7160e01b8b52601160045260248bfd5b60408281015160118301546001600160a01b03168d526014602052908c206002015410610ffe57610ff9906135e7565b610e92565b905060025b818111611025575060110180546001600160a01b031916331790553880610e9b565b60018110610fb557600360001982011015610fa15760108101546001600160a01b03166003821015610f8d576011820180546001600160a01b031916909117905561106f90613c91565b611003565b61108160408301516135e7565b6040830152610e67565b634e487b7160e01b8c52601160045260248cfd5b9091925060808201518c52600d60205260408c206001821061110257908c6110f2610dec8360406110d86110f9976000198401906133e9565b90549060031b1c9460808901518152600d602052206133e9565b9055613c91565b90899291610dc8565b634e487b7160e01b8d52601160045260248dfd5b90501538610d9a565b505092959690939750939093610e08565b61113990612f3d565b611144578a38610c89565b8a80fd5b6040513d84823e3d90fd5b60405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081c185e5b595b9d607a1b6044820152606490fd5b9296919495610b58906111a188969396613b51565b610edf565b92819495506111d59250906111c084608081940151613819565b516111d08360018b018484613de7565b613cf5565b8115611234575b60a081015115611217575b906112068161120c936080880151906112008383613819565b52613819565b506135e7565b8b8593928592610b16565b92906112068161122961120c946135e7565b9592509250506111e7565b60a08101516111dc5760405162461bcd60e51b8152602060048201526024808201527f596f752073686f742074686520626f647920796f752073686f756c642070726f6044820152631d1958dd60e21b6064820152608490fd5b60405162461bcd60e51b8152602060048201526013602482015272151a5b59481b1a5b5a5d08195e18d959591959606a1b6044820152606490fd5b634e487b7160e01b8d52603260045260248dfd5b50634e487b7160e01b8f52601160045260248ffd5b6001602082829351855501920192019190610a78565b634e487b7160e01b600052603260045260246000fd5b815190835180921492836113f1575b836113de575b836113cb575b836113bd575b50501591826113ac575b5081156113a4575b501561135f573880806109f3565b60405162461bcd60e51b815260206004820152601760248201527f496e76616c696420696e666c696768744d697373696c650000000000000000006044820152606490fd5b905038611351565b60200151620f424014915038611349565b60800151149150388061133f565b9250606083015160608501511492611339565b9250604083015160408501511492611333565b925060208301516020850151149261132d565b50505060248f634e487b7160e01b81526011600452fd5b60405162461bcd60e51b815260206004820152602560248201527f4f776e6572206f6620746869732070726f6f66206973206e6f7420746865207360448201526432b73232b960d91b6064820152608490fd5b60405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103b32b934b334b2b960811b6044820152606490fd5b634e487b7160e01b8f52601160045260248ffd5b60405162461bcd60e51b815260206004820152601460248201527313195d995b08185b1c9958591e481cdbdb1d995960621b6044820152606490fd5b60405162461bcd60e51b815260206004820152601f60248201527f50726576696f7573206c6576656c206e6f742079657420636f6d706c657465006044820152606490fd5b88604051f35b60405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c7920736f6c76652072756e73206f6e207468652063757272656044820152656e742064617960d01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526012602482015271149d5b88185b1c9958591e481cdbdb1d995960721b6044820152606490fd5b60405162461bcd60e51b815260206004820152602660248201527f4f6e6c7920746865206f776e6572206f66207468652072756e2063616e20736f6044820152651b1d99481a5d60d21b6064820152608490fd5b94506017549460405160a05261163a60a051612f50565b87602060a051015287604060a051015287606060a051015287608060a0510152606060a0805101523360a05152600143106119ca57604051866020820152600060408201526000194301406060820152606081528060808101106001600160401b036080830111176119b4576080810160405260208151910120606060a051015284608060a0510152600160401b8610156119a057600186016017556116df86613466565b61198c5760a0805180518354602083015160ff60a01b901515851b166001600160a01b039092166001600160a81b0319909116171783556040810151600184015560608101516002840155608081015160038401550151805190600160401b82116119785760048301548260048501558083106118cb575b5060206004910192018a5260208a208a905b8282106117be57505050507fbe33ae7a5df03243155e17a5896a63473638d0a5042d1504b59ea59ff0f2b0a560608060a0510151604051908982528860208301526040820152a16117b986613b51565b61072a565b95839a939b94959892999b979197516117e681511515899060ff801983541691151516179055565b60208101516001890155604081015160028901556060810151600389016080526000905b600582106118a45750506080015198600888019660009a5b60068c101561188357600760208260c0600194518d815190558d86858301519101558d600260408301519101558d600360608301519101558d600460808301519101558d600560a0830151910155015160068d01550199019b019a97611822565b50959c9a929893995095509592996032602060019201940192019091611769565b805160c08190526080805160e081905291825560019182019052919091019060200161180a565b6118d4906131e2565b6118dd836131e2565b90600485018d5260208d209182015b81830181106118fc575050611757565b8d81556000600182015560006002820155600381015b60088201811061196c5750600881015b60328201811061193557506032016118ec565b8060006007925560006001820155600060028201556000600382015560006004820155600060058201556000600682015501611922565b60008155600101611912565b634e487b7160e01b8b52604160045260248bfd5b634e487b7160e01b89526004899052602489fd5b634e487b7160e01b88526041600452602488fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60405162461bcd60e51b815260206004820152601260248201527110dbdb9d1c9858dd081a5cc81c185d5cd95960721b6044820152606490fd5b6001600160401b03823511611a4a5760208091611a3f366024863560a4350101613142565b8152019101906106ec565b8780fd5b8680fd5b8480fd5b36601f8501121561005757604051611a6d81612fa1565b803660808701116100575785905b608087018210611a98575050815260809390930192602001610653565b6020604091611aa736856133f9565b815201910190611a7b565b8380fd5b8280fd5b50346103d15760203660031901126103d157600435906001600160401b0382116103d157610680611af6611af13660048601613142565b614693565b611b0360405180926134fb565bf35b50346103d15760203660031901126103d1576004356001600160a01b038116908190036104af57611b3461358f565b6001600160601b0360a01b6005541617600555604051f35b50346103d157602090816003193601126103d1576004356001600160401b0381116104af57611b7f903690600401613142565b9060405192611b8d84613062565b610a40809436903760405192611ba284613062565b84368537825b60528110611bda5750506040519291835b60528210611bc5578585f35b82806001928651815201940191019092611bb9565b80611beb611bf89284979697613623565b518160051b8601526135e7565b939293611ba8565b50346103d15760603660031901126103d1576001600160a01b0360443581811690819003610057578291611c3261358f565b60405190611c5460209260043584820152838152611c4f81612fa1565b6147b8565b611c6d60405160243585820152848152611c4f81612fa1565b906040519484860152838552611c8285612fa1565b606060405194611c9186613047565b6003865236908601377f04d76c509b8f988dc8955b929b113410ea0e0897373914a00b48ea522da64173611cc4856135f6565b52611cce84613603565b52611cd883613613565b526007541691823b15611d3157611d089284928360405180968195829463b46f007160e01b84526004840161476b565b03925af1801561114857611d1d575b50604051f35b611d2690612f3d565b6103d1578038611d17565b505050fd5b50346103d1576020806003193601126104af57611d5f6004611d588135613466565b5001613759565b6040519180830181845282518091528160408501930191855b828110611d855785850386f35b90919293828551805115158352818101518284015260408101516040840152606080820151908401908a915b60058310611de157505050600192611dd560806106409301516101008301906132f4565b01950193929101611d78565b8151815287946001909301929182019101611db1565b50346103d1576020806003193601126104af5760065460405163295d33a960e21b81526004803590820152908390829060249082906001600160a01b03165afa928315611edb578093611e5f575b5050611e5b6040519282849384528301906134d6565b0390f35b909192503d8082843e611e72818461310a565b82019183818403126104af578051906001600160401b038211611ab6570182601f820112156104af57805191611ea783613c46565b93611eb5604051958661310a565b8385528584840101116103d1575090611ed3918480850191016134a1565b903880611e45565b604051903d90823e3d90fd5b50346103d15760203660031901126103d157600435906017548210156103d15760a0600583601760005202807fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150154907fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c16810154907fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c187fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c178201549101549160ff60405194600180881b0381168652861c1615156020850152604084015260608301526080820152f35b50346103d15760203660031901126103d1576004356001600160a01b038116908190036104af57611fff61358f565b47907fb08889abce443443404b2caf69aa3ccfb9ebfdf1ad2a634d06e11e24c106793861204c84808060405187875af1612037613c61565b906040519283926040845260408401906134d6565b9560208301521515940390a3604051f35b50346103d15760203660031901126103d157600435906001600160401b0382116103d1576107c06120996120943660048601613142565b6146db565b611b03604051809261343e565b50346103d157806120b6366131cc565b6120be61358f565b6040519160208301526040820152604081526120d981612f86565b6040516120e581612fa1565b60018152602036818301377f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c61211a826135f6565b526007546001600160a01b031691823b15611d3157611d089284928360405180968195829463b46f007160e01b84526004840161476b565b50346103d157806003193601126103d1576020600454604051908152f35b50346103d157806003193601126103d1576006546040516001600160a01b039091168152602090f35b50346103d1576121a836613285565b9160018060a01b03168352601560205260408320908352602052604082206007821015611ab657602092500154604051908152f35b50346103d15760203660031901126103d15760206121fc60043561398d565b604051908152f35b50346103d15760203660031901126103d15760043560058110156104af5760209060080154604051908152f35b50346103d157806003193601126103d157601754906001821061225d5760405160001983018152602090f35b634e487b7160e01b81526011600452602490fd5b50346103d157602090816003193601126103d1576004356001600160401b0381116104af576122a4903690600401613142565b90604051926122b28461302b565b610b808094369037604051926122c78461302b565b84368537825b605c81106122ff5750506040519291835b605c82106122ea578585f35b828060019286518152019401910190926122de565b80611beb6123109284979697613623565b9392936122cd565b50346103d157806003193601126103d157546040516001600160a01b039091168152602090f35b50346103d15760203660031901126103d15761235961358f565b600435600455604051f35b50346103d157806003193601126103d15760206040516204f1a08152f35b50346103d157806003193601126103d1576007546040516001600160a01b039091168152602090f35b50346103d1576101603660031901126103d1576024356001600160a01b038116810361005757366063121561005757604051906123e782612fa1565b608482368211610057576044905b8282106124b55750503660a312156100575760405161241381612fa1565b806101049236841161005757905b83821061249b575050366101231215610057576040519161244183612fa1565b826101449136831161005757905b82821061248b57505035936001600160401b03851161248757612479612482953690600401613142565b93600435614156565b604051f35b8580fd5b813581526020918201910161244f565b60206040916124aa36856133f9565b815201910190612421565b81358152602091820191016123f5565b50346103d157602090816003193601126103d1576004356001600160401b0381116104af576124f8903690600401613142565b90604051926125068461300f565b6102c080943690376040519261251b8461300f565b84368537825b601681106125535750506040519291835b6016821061253e578585f35b82806001928651815201940191019092612532565b80611beb6125649284979697613623565b939293612521565b50346103d15760203660031901126103d15760043560038110156104af57600e01546040516001600160a01b039091168152602090f35b50346103d1576125b2366131cc565b919081526016602052604081209060038310156103d15760206125d584846133e9565b905460405160039290921b1c6001600160a01b03168152f35b50346103d157806003193601126103d15761260761358f565b600080546001600160a01b03198116825560405191906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b50346103d15760203660031901126103d1576060906040906001600160a01b0361267461326f565b168152601460205220805490600260018201549101549060405192835260208301526040820152f35b50346103d157602090816003193601126103d1576004356001600160401b0381116104af576126d0903690600401613142565b90604051926126de84612ff3565b610cc08094369037604051926126f384612ff3565b84368537825b6066811061272b5750506040519291835b60668210612716578585f35b8280600192865181520194019101909261270a565b80611beb61273c9284979697613623565b9392936126f9565b50346103d15760203660031901126103d15760043560038110156104af57601101546040516001600160a01b039091168152602090f35b50346103d157806003193601126103d157602060ff600354166040519015158152f35b50346103d157806003193601126103d15760206121fc62015180420642613637565b50346103d15760203660031901126103d157600435906001600160401b0382116103d1576109006127fc6127f73660048601613142565b614723565b611b0360405180926133c1565b50346103d15760203660031901126103d1576004356001600160a01b038116908190036104af5761283861358f565b6001600160601b0360a01b6007541617600755604051f35b505061285a6132af565b3861038b565b50346103d1576101403660031901126103d15761287c36613360565b60e435906001600160401b038211611ab65761289f612482923690600401613142565b9061012435916101043591613de7565b50346103d157806003193601126103d1576020604051614e208152f35b50346103d1576101203660031901126103d1576128e836613360565b9060e435906001600160401b0382116103d15760e06129188461290e3660048701613142565b6101043591613cf5565b611b03604051809260c08091805184526020810151602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b50346103d15761056061297c612976366131cc565b90613845565b61298960405180936132f4565b610540820152f35b50346103d15760203660031901126103d157600435906001600160401b0382116103d1576105406129cd6129c83660048601613142565b61464b565b611b0360405180926132cc565b50346103d157806003193601126103d157602060405160148152f35b50346103d157602090612a08366131cc565b90825260188352604082209082528252604060018060a01b0391205416604051908152f35b50346103d15760603660031901126103d15760206121fc60443560243560043561389e565b50346103d15760203660031901126103d15760206121fc6004356145d7565b50346103d15760403660031901126103d15760e06129186024356004356138c7565b50346103d15760203660031901126103d157612aad61358f565b604051600435602082015260208152612ac581612fa1565b8160405191612ad383612fa1565b60018352602036818501377ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7612b08846135f6565b526007546001600160a01b0316803b15611ab657612b3d938360405180968195829463b46f007160e01b84526004840161476b565b03925af1801561114857612b515750604051f35b612b5a90612f3d565b38611d17565b50346103d157806003193601126103d157612b79613a1a565b9062093a8019821161225d5760206121fc4262093a808501613637565b50346103d157612ba536613285565b90612bae61358f565b8352601860205260408320908352602052604082209060018060a01b03166001600160601b0360a01b825416179055604051f35b50346103d157612bf1366131cc565b90825260026020526040822060405190612c0a82612fa1565b546001600160a01b0380821680845260a09290921c6020840152919015612c64575b6001600160601b0360208201511693836000190485118415151661225d57509261271091604094511692845193845202046020820152f35b50604051612c7181612fa1565b600154828116825260a01c6020820152612c2c565b50346103d15760203660031901126103d157612ca061326f565b612ca861358f565b60018060a01b03166001600160601b0360a01b6006541617600655604051f35b50346103d157806003193601126103d157602060405162093a808152f35b50346103d15760203660031901126103d15760206004612d068135613466565b500154604051908152f35b50346103d157806003193601126103d1576005546040516001600160a01b039091168152602090f35b50346103d157602090816003193601126103d1576004356001600160401b0381116104af57612d6d903690600401613142565b9060405192612d7b84612fd7565b610e00809436903760405192612d9084612fd7565b84368537825b60708110612dc85750506040519291835b60708210612db3578585f35b82806001928651815201940191019092612da7565b80611beb612dd99284979697613623565b939293612d96565b50346103d15760203660031901126103d1576004358015158091036104af57612e0861358f565b60ff801960035416911617600355604051f35b50346103d157806003193601126103d15760206121fc613a1a565b50346103d15760206121fc612e4a366131cc565b906139e9565b50346103d15760203660031901126103d15760043563ffffffff60e01b81168091036104af5760209063152a902d60e11b8114908115612e9557506040519015158152f35b6301ffc9a760e01b14905082610460565b50346103d15760203660031901126103d157600435906001600160401b0382116103d157610400612ee2612edd3660048601613142565b6145f6565b611b0360405180926131a0565b50346103d15760603660031901126103d15760043590612f1182602435613637565b908115612f295760206121fc84846044350690613839565b634e487b7160e01b81526012600452602490fd5b6001600160401b0381116119b457604052565b60c081019081106001600160401b038211176119b457604052565b60a081019081106001600160401b038211176119b457604052565b606081019081106001600160401b038211176119b457604052565b604081019081106001600160401b038211176119b457604052565b60e081019081106001600160401b038211176119b457604052565b610e0081019081106001600160401b038211176119b457604052565b610cc081019081106001600160401b038211176119b457604052565b6102c081019081106001600160401b038211176119b457604052565b610b8081019081106001600160401b038211176119b457604052565b608081019081106001600160401b038211176119b457604052565b610a4081019081106001600160401b038211176119b457604052565b61040081019081106001600160401b038211176119b457604052565b61054081019081106001600160401b038211176119b457604052565b61068081019081106001600160401b038211176119b457604052565b6107c081019081106001600160401b038211176119b457604052565b61090081019081106001600160401b038211176119b457604052565b90601f801991011681019081106001600160401b038211176119b457604052565b6001600160401b0381116119b45760051b60200190565b81601f82011215610057578035916131598361312b565b92613167604051948561310a565b808452602092838086019260051b820101928311610057578301905b828210613191575050505090565b81358152908301908301613183565b916000915b602090818410156131c557908060019286518152019401920191926131a5565b5050915050565b6040906003190112610057576004359060243590565b7f051eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851e81116001166119ca5760320290565b8060001904600511811515166119ca5760050290565b6001600160ff1b0381116001166119ca5760011b90565b7f333333333333333333333333333333333333333333333333333333333333333381116001166119ca5760050290565b600435906001600160a01b038216820361005757565b6060906003190112610057576004356001600160a01b038116810361005757906024359060443590565b503461005757600036600319011261005757602060405160028152f35b6000915b602a83106132dd57505050565b6001908251815260208091019201920191906132d0565b906000905b6006821061330657505050565b602060e082613354600194875160c08091805184526020810151602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b019301910190916132f9565b60e0906003190112610057576040519060e082018281106001600160401b038211176119b457604052816004358152602435602082015260443560408201526064356060820152608435608082015260a43560a082015260c060c435910152565b6000915b604883106133d257505050565b6001908251815260208091019201920191906133c5565b6003821015611308570190600090565b9080601f83011215610057576040519161341283612fa1565b82906040810192831161005757905b82821061342e5750505090565b8135815260209182019101613421565b6000915b603e831061344f57505050565b600190825181526020809101920192019190613442565b601754811015611308576005906017600052027fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150190600090565b918091926000905b8282106134c15750116134ba575050565b6000910152565b915080602091830151818601520182916134a9565b906020916134ef815180928185528580860191016134a1565b601f01601f1916010190565b6000915b6034831061350c57505050565b6001908251815260208091019201920191906134ff565b81601f820112156100575780359061353a8261312b565b9260409261354a8451958661310a565b808552602091828087019260061b85010193818511610057578301915b8483106135775750505050505090565b83869161358484866133f9565b815201920191613567565b6000546001600160a01b031633036135a357565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60001981146119ca5760010190565b8051156113085760200190565b8051600110156113085760400190565b8051600210156113085760600190565b80518210156113085760209160051b010190565b8181106119ca570390565b60405191906000835b600582106136715750505060a082018281106001600160401b038211176119b457604052565b600160208192855481520193019101909161364b565b90604080519261369684612f6b565b8360ff82541615158152600193848301549160209283820152600290818501548682015260036136c7818701613642565b90606091828401528751976136db89612f50565b60009760080195895b6006808b101561374657898d9260079286519061370082612fbc565b8c548252858d0154848301528b8d015488830152888d01548a83015260048d0154608083015260058d015460a08301528c015460c08201528152019801990198966136e4565b5050995050505092505050608091500152565b9081546137658161312b565b92613773604051948561310a565b818452600090815260208082208186015b848410613792575050505050565b6032836001926137a185613687565b815201920193019290613784565b604051906137bc82612fbc565b8160c06000918281528260208201528260408201528260608201528260808201528260a08201520152565b604051906137f482612f50565b8160005b60c08110613804575050565b60209061380f6137af565b81840152016137f8565b9060068110156113085760051b0190565b612710811981116119ca570190565b811981116119ca570190565b919061384f6137e7565b9260005b8281111561386c57505060011981116119ca5760010190565b806138848161387f61389994878761389e565b6138c7565b61388e8288613819565b526112068187613819565b613853565b91604051916020830193845260408301526060820152606081526138c181613047565b51902090565b613985906138d36137af565b506138ee6138df6137af565b938085528260c086015261398d565b60a08401526040519060209182810191825282815261390c81612fa1565b519020620f4240908181068386015260405183810191825283815261393081612fa1565b519020908106604085015260405182810191825282815261395081612fa1565b519020614e209161396283830661382a565b606086015260405190808201928352815261397c81612fa1565b5190200661382a565b608082015290565b6139d060ff916006604051916139a283612f50565b60248352601b60208401526016604084015260116060840152600c6080840152600760a08401520690613819565b51166103e89080600019048211811515166119ca570290565b90600143106119ca57604051906020820192835260408201526000194301406060820152606081526138c181613047565b6204f1a042106119ca57613a3962093a806204f19f1942010642613637565b90565b8054821015611308576000526032602060002091020190600090565b9290613b3b57613a79829392511515839060ff801983541691151516179055565b6020918284015192600193848301556040948581015193600294858501556060918281015160039081870190896000915b60058310613b27575050505060086080809301519601936000965b600680891015613b1957815180518855888101518c8901558c8101518b890155838101518589015585810151600489015560a0810151600589015560c0015190870155968901966007909501948601613ac5565b505050505095505050505050565b80518455928101929101908a908801613aaa565b634e487b7160e01b600052600060045260246000fd5b6003613b5c82613466565b500154906004613b6b82613466565b50015460011981116119ca576001019060405192613b8884612f6b565b6000845260006020850152604084019260008452604051613ba881612f6b565b60a0368237606086015260808501613bbe6137e7565b8152613bca82856139e9565b8552613bd68284613845565b5090526004613be484613466565b5001938454600160401b8110156119b4577f70f3b6a85b7a5047df9e61440f8b6480a7cd8a96f849a4092d0a22303a5dbb0f96610b41826080986001613c2c95018155613a3c565b5190604051938452602084015260408301526060820152a1565b6001600160401b0381116119b457601f01601f191660200190565b3d15613c8c573d90613c7282613c46565b91613c80604051938461310a565b82523d6000602084013e565b606090565b80156119ca576000190190565b90604051613cab81612f50565b60a0613cf06004839560ff8154600180871b0381168752851c161515602086015260018101546040860152600281015460608601526003810154608086015201613759565b910152565b9190613cff6137af565b50613d0982613212565b91600592801984116119ca57613d2190840183613623565b516020850152613d3081613212565b801984116119ca57600119848201116119ca576006613d50910183613623565b516040850152613d5f81613212565b801984116119ca57600219848201116119ca576007613d7f910183613623565b516060850152613d8e81613212565b90811984116119ca57600319848301116119ca57613db26008613dbd930184613623565b516080860152613212565b91821981116119ca57600419908301116119ca576009613dde920190613623565b5160a082015290565b9291906020928385015190613dfb8461323f565b90600591801983116119ca57613e1c90613e1483613212565b908401613839565b60021993908481116119ca576002613e35910186613623565b51036140ac576040870151613e498661323f565b801984116119ca57613e6690613e5e84613212565b908501613839565b60011981116119ca578460018201116119ca576003613e86910186613623565b510361407257606087015196613e9b8661323f565b801984116119ca57613eb090613e5e84613212565b978489116119ca578460028a01116119ca57613ed06004809a0187613623565b510361403b576080810151613ee48761323f565b8019851161402657613f0190613ef985613212565b908601613839565b6003198111614026578560038201116140265784613f20910187613623565b5103613fef5760a0613f349101519561323f565b9081198311613fda5790613f4b613f529392613212565b9101613839565b906004198211613fc55785820111613fb057906006613f72920190613623565b5103613f7c575050565b60405162461bcd60e51b815291820152600e60248201526d496e76616c69642072616469757360901b604482015260649150fd5b601185634e487b7160e01b6000525260246000fd5b601186634e487b7160e01b6000525260246000fd5b601188634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808901889052601060248201526f496e76616c696420766563746f72207960801b6044820152606490fd5b60118a634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808901889052601060248201526f092dcecc2d8d2c840eccac6e8dee440f60831b6044820152606490fd5b60405162461bcd60e51b8152600481018790526012602482015271496e76616c696420706f736974696f6e207960701b6044820152606490fd5b60405162461bcd60e51b8152600481018790526012602482015271092dcecc2d8d2c840e0dee6d2e8d2dedc40f60731b6044820152606490fd5b90816020910312610057575180151581036100575790565b6000915b6002831061410f57505050565b600190825181526020809101920192019190614102565b906000905b6002821061413857505050565b602060408261414a60019487516140fe565b0193019101909161412b565b939091929360028114600014614259575091610504916141c16141a2946141b6614182602098996145f6565b916141ac6040519a8b998a98630f3022c960e21b8a5260048a01906140fe565b6044880190614126565b60c48601906140fe565b6101048401906131a0565b6001600160a01b03165afa90811561424d5760009161421f575b50156141e357565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21019103137b23c90383937b7b360611b6044820152606490fd5b614240915060203d8111614246575b614238818361310a565b8101906140e6565b386141db565b503d61422e565b6040513d6000823e3d90fd5b60038103614324575091610644916142a86141a29461429d61427d6020989961464b565b916141ac6040519a8b998a986371dd4db160e11b8a5260048a01906140fe565b6101048401906132cc565b6001600160a01b03165afa90811561424d57600091614306575b50156142ca57565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21019903137b23c90383937b7b360611b6044820152606490fd5b61431e915060203d811161424657614238818361310a565b386142c2565b92939060049584878096146000146143f857509261437c61078493614371602097946141ac6143566141a29b99614693565b936040519b8c9a8b99632a6d5ed560e01b8b528a01906140fe565b6101048401906134fb565b6001600160a01b03165afa90811561424d576000916143da575b501561439f5750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101a103137b23c90383937b7b360611b6044820152fd5b6143f2915060203d811161424657614238818361310a565b38614396565b600581036144c25750926144466108c49361443b602097946141ac6144206141a29b996146db565b936040519b8c9a8b9963ea59061d60e01b8b528a01906140fe565b61010484019061343e565b6001600160a01b03165afa90811561424d576000916144a4575b50156144695750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101a903137b23c90383937b7b360611b6044820152fd5b6144bc915060203d811161424657614238818361310a565b38614460565b600691929394955014600014614593576020936145176141a2969461450c610a04956141ac6144f18c97614723565b936040519b8c9a8b996311b5352360e01b8b528a01906140fe565b6101048401906133c1565b6001600160a01b03165afa90811561424d57600091614575575b501561453a5750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101b103137b23c90383937b7b360611b6044820152fd5b61458d915060203d811161424657614238818361310a565b38614531565b60405162461bcd60e51b8152602081880152601860248201527f496e76616c6964206e756d626572206f6620626f6469657300000000000000006044820152606490fd5b600c81106119ca57600a90600b190104600181106119ca576000190190565b906040516146038161307e565b6104008091369037604051906146188261307e565b36823760005b6020811061462b57509150565b806146396146469286613623565b518160051b8401526135e7565b61461e565b906040516146588161309a565b61054080913690376040519061466d8261309a565b36823760005b602a811061468057509150565b8061463961468e9286613623565b614673565b906040516146a0816130b6565b6106808091369037604051906146b5826130b6565b36823760005b603481106146c857509150565b806146396146d69286613623565b6146bb565b906040516146e8816130d2565b6107c08091369037604051906146fd826130d2565b36823760005b603e811061471057509150565b8061463961471e9286613623565b614703565b90604051614730816130ee565b610900809136903760405190614745826130ee565b36823760005b6048811061475857509150565b806146396147669286613623565b61474b565b9092916040820191604081528451809352606081019260208096019060005b8181106147a457505050613a3993948184039101526134d6565b82518652948701949187019160010161478a565b6020815191015190602081106147cc575090565b6000199060200360031b1b169056fea2646970667358221220ac7db03f69e75e5055d3b93a6033230c77338e458ad1269192a44eeb31a024e964736f6c634300080f0033", + "bytecode": "0x610120604052346200071d5762004db2803803806200001e816200073d565b928339810160c0828203126200071d57620000398262000763565b90620000486020840162000763565b620000566040850162000763565b60e05260608401516001600160401b0381116200071d5784019382601f860112156200071d57845194620000946200008e8762000778565b6200073d565b9560208088838152019160051b830101918583116200071d57602001905b828210620007225750505060808101516001600160401b0381116200071d5783620000df91830162000790565b60a08201519093906001600160401b0381116200071d5762000102920162000790565b60008054336001600160a01b03198216811783556040519396939290916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09084a36003805460ff191690556608e1bc9bf040006004556001600160401b0360a0820190811190821117620005bd5760a0810160405260fa81526101f460208201526102ee60408201526103e860608201526104e260808201526008906000905b600582106200070257505060408051915081018082116001600160401b0390911117620005bd57604081016040526001815260005b60208110620006a95750805190680100000000000000008211620005bd5760175482601755808310620005d3575b506017600090815260008051602062004d9283398151915292916020015b8282106200039257505050506200024362000911565b60e051600680546001600160a01b0319166001600160a01b03929092169190911790556200027062000911565b600580546001600160a01b0319166001600160a01b03929092169190911790556200029a62000911565b600780546001600160a01b0319166001600160a01b039290921691909117905560005b83518110156200038257620002e0620002d78284620008a6565b511515620008d1565b620003026001600160a01b03620002f88387620008a6565b51161515620008d1565b6001600160a01b03620003168286620008a6565b5116620003248285620008a6565b51600052601860205260406000206200033e8385620008a6565b5160005260205260406000209060018060a01b031982541617905560001981146200036c57600101620002bd565b634e487b7160e01b600052601160045260246000fd5b60405161442790816200096b8239f35b60a08151600180831b0381511686549060ff841b60208401511515851b169160018060a81b031916171786556040810151600187015560608101516002870155608081015160038701550151805190680100000000000000008211620005bd57600486015482600488015580831062000547575b50602001906004860160005260206000206000915b8083106200043b575050505060056020600192019401910190926200022d565b969593949a91989b929990978a518051151560ff80198c54169116178a55602081015160018b0155604081015160028b0155606081015160805260038a0160c05260005b6005811062000526575060800151610100526008890160a05260005b60068110156200050557600190600761010051602081519160c083519360a051948555838101518886015560408101516002860155606081015160038601556080810151600486015560a081015160058601550151600684015501610100520160a052016200049b565b5097929b989099603260206001929d97969899949d0194019101916200041b565b60019081608051602081519160c051928355016080520160c052016200047f565b62000552906200081e565b6200055d836200081e565b906004880160005260206000209182015b81830181106200058057505062000406565b806000603292556000600182015560006002820155620005b660088201620005ac81600385016200084f565b8383019062000868565b016200056e565b634e487b7160e01b600052604160045260246000fd5b620005de90620007ed565b620005e983620007ed565b601760005260008051602062004d92833981519152919082015b8183018110620006155750506200020f565b60008155600060018201556000600282015560006003820155600481015460006004830155806200064b575b5060050162000603565b62000656906200081e565b600482016000526020600020908101905b81811062000676575062000641565b806000603292556000600182015560006002820155620006a260088201620005ac81600385016200084f565b0162000667565b604051906001600160401b0360c0830190811190831117620005bd578160c06020930160405260008152600083820152600060408201526000606082015260006080820152606060a082015282828501015201620001e1565b600160208261ffff83945116865501930191019091620001ac565b600080fd5b60208091620007318462000763565b815201910190620000b2565b6040519190601f01601f191682016001600160401b03811183821017620005bd57604052565b51906001600160a01b03821682036200071d57565b6001600160401b038111620005bd5760051b60200190565b9080601f830112156200071d57815190620007af6200008e8362000778565b9182938184526020808095019260051b8201019283116200071d578301905b828210620007dd575050505090565b81518152908301908301620007ce565b7f333333333333333333333333333333333333333333333333333333333333333381116001166200036c5760050290565b7f051eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851e81116001166200036c5760320290565b8181106200085b575050565b600081556001016200084f565b81811062000874575050565b600790600080825580600183015580600283015580600383015580600483015580600583015560068201550162000868565b8051821015620008bb5760209160051b010190565b634e487b7160e01b600052603260045260246000fd5b15620008d957565b60405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103b32b934b334b2b960811b6044820152606490fd5b6000546001600160a01b031633036200092657565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fdfe60806040526004361015610097575b361561005b57346100565760405162461bcd60e51b81526020600482015260156024820152746e6f2066616c6c6261636b207468616e6b20796f7560581b6044820152606490fd5b600080fd5b60405162461bcd60e51b81526020600482015260146024820152736e6f2072656365697665207468616e6b20796f7560601b6044820152606490fd5b60003560e01c8063010520a114612bb8578063014a30d214612b7057806301ffc9a714612b1b578063041df08214612b0257806306575c8914612ae757806308cdc2a814612aac578063098b5e9314612a0b5780630b27ce3f146129e257806310d80a55146129b8578063132d5ed91461299a578063158b38b6146129575780632a55205a146128b45780632b057afa146128665780632e93a49214612830578063355f7407146125f357806335d6f0cc1461280f5780633bdbdb71146127f15780633ef2570b146127cd57806343569ffb146127925780634b9862d9146127765780634caa028b1461272e5780634dbe7f73146126ff5780635103d6ea1461266c5780635120a2611461264f578063530ab7dc1461260157806353e52f09146125f35780635542437b146125af5780635bd6b2ea146125675780635c9302c9146125455780635c975abb146125225780636498c128146124ec5780636ef24f2d1461244b57806370180bc1146123fa578063715018a61461239b57806371b8ccb014612351578063770c5da11461231b5780637a19b1901461227a578063861f75561461216a57806387b07780146121415780638cc52cf3146121235780638d6cc56d146121025780638da5cb5b146120d9578063907311b1146120385780639196b7001461200d5780639654c1f714611fe15780639691f1ab14611fbb57806398a6a64114611f745780639bc4961714611f4b578063a035b1fe14611f2d578063ac4a604714611ee5578063adcbb85b14611e5b578063ae66f57c14611d74578063b24f67b814611c93578063bd2c955214611bc6578063c8b90ebb14611b18578063cc80b8ea14611ad4578063d8531e6e14611a8a578063de89d1c114610582578063e2adba8c14610566578063ed3437f814610549578063f2fde38b14610481578063f6fbc39a146103e3578063f81c8ec3146103c5578063f9cfa06f146103a75763ffd73d3b0361000e57346100565761037536612e94565b90600052600d6020526040600020600382101561005657602091610398916130b1565b90549060031b1c604051908152f35b34610056576000366003190112610056576020604051620151808152f35b34610056576000366003190112610056576020604051620f42408152f35b346100565760203660031901126100565760043563ffffffff60e01b8116809103610056576020906301ffc9a760e01b8114908115610470575b811561045f575b811561044e575b811561043d575b506040519015158152f35b632483248360e11b14905082610432565b63152a902d60e11b8114915061042b565b6303a24d0760e21b81149150610424565b636cdb3d1360e11b8114915061041d565b346100565760203660031901126100565761049a612f37565b6104a2613257565b6001600160a01b039081169081156104f557600080546001600160a01b031981168417825560405191939192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08484a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b346100565760003660031901126100565760206040516103e88152f35b3461005657600036600319011261005657602060405160058152f35b60c0366003190112610056576024356001600160401b038111610056576105ad903690600401612e0a565b6044356001600160401b038111610056576105cc9036906004016131eb565b6064356001600160401b0381116100565736602382011215610056578060040135906105f782612df3565b916106056040519384612dd2565b80835260208301913660248360071b830101116100565760248101925b60248360071b8301018410611a2e57505050506084356001600160401b038111610056576106549036906004016131eb565b916001600160401b0360a435116100565736602360a4350112156100565761068160a43560040135612df3565b61068e6040519182612dd2565b60a4356004013581526020810136602460a4356004013560051b60a43501011161005657602460a43501905b602460a4356004013560051b60a435010182106119fe5750506004359360ff600354166119c4576106f0620151804206426132df565b93851561165b575b6107018661312e565b50546001600160a01b031633036116075760ff61071d8761312e565b505460a01c166115cd5760036107328761312e565b50015485036115795760005b83518110156115775786610752828a6132cb565b5161075d83886132cb565b519061076984866132cb565b519161077585886132cb565b5192610781868a6132cb565b51926004610798610792865161425d565b9761312e565b500154809603611532576001861061105c5760ff6107c76107b88f61312e565b506000198901906004016136e4565b5054166114f657600119861161105c5760018601600052601860205260406000209060005260205260018060a01b03604060002054169384156114be5761081060018701612eda565b801960051161105c57600119600582011161105c5733906001600160a01b039061083d90600601876132cb565b51160361146b5761086c60036108658f6108569061312e565b506000198a01906004016136e4565b50016132ea565b6040519061087982612c20565b61088d61088860018a01612ef0565b612eda565b801960051161105c57600219600582011161105c5760076108af9101876132cb565b5182526108c161088860018a01612ef0565b801960051161105c57600219600582011161105c57600119600782011161105c5760086108ef9101876132cb565b51602083015261090461088860018a01612ef0565b801960051161105c57600219600582011161105c57600219600782011161105c5760096109329101876132cb565b51604083015261094761088860018a01612ef0565b801960051161105c57600219600582011161105c57600319600782011161105c57600a6109759101876132cb565b51606083015261098a61088860018a01612ef0565b801960051161105c57600219600582011161105c57600419600782011161105c57600b6109b89101876132cb565b5180608084015280611385575b5050506040516109d481612c20565b6109dd856132be565b518152845160011015611046576040850151602082015284516002101561104657606085015160408201528451600310156110465760808501516060820152845160041015611046576003610a3f8f6108569060a0890151608086015261312e565b50016000915b6005831061136f57505050610a5c60018701612eda565b91821960051161105c57610a8393610a788694600501856132cb565b519660018901613de8565b610ab5610aaa610aa4610a958d61312e565b506000198701906004016136e4565b5061332f565b9260208401516134e1565b80602084015260056000198501101561104657600784015410611334578290828b600092610ae1613457565b5060005b60018601811061124c57505090610b10610b01610b169361312e565b506000198601906004016136e4565b90613700565b14610b2c575b5050610b27906132af565b61073e565b906020600592610b57610b488c9b989c9d99969d9a979a61312e565b506000198501906004016136e4565b50600160ff19825416179055828a8383015160405190815289858201527f416328325568dd8681e48de39e8d89a80ddf01a688fbcb49c28c621071c9333b60403392a40151610bb46001610baa8b61312e565b50019182546134e1565b90550361123257610bc48661312e565b50805460ff60a01b1916600160a01b17905560045434036111f9576005546040516000918291829134906001600160a01b03165af1610c016138f3565b6007546001600160a01b0316803b15610056576000809160a46040518094819363093ccd3160e41b83523360048401528b602484015260016044840152608060648401528160848401525af18015611146576111ea575b507fb08889abce443443404b2caf69aa3ccfb9ebfdf1ad2a634d06e11e24c1067938610c9d60018060a01b03600554169260405191829160408352604083019061319e565b943460208301521515940390a3856001610cb68261312e565b5001546040519081528460208201527f7f05a2f6290fe88fe25ed1665c50706361d709c5003e3067340b9053916fd70760403392a33360005260146020526040600020610d0381546132af565b9055610d17610d118761312e565b50613930565b9660005b6080890151600052600d60205260038110156111db576080890151600052610d59610d11610d4d8360406000206130b1565b90549060031b1c61312e565b6040808b01519101518091109081156111d2575b50610d8057610d7b906132af565b610d1b565b96889194976080829a9b94979b9895980151600052600d60205260025b81811161116e575090610ddf610dc68493608080960151600052600d60205260406000206130b1565b819391549060031b600019811b9283911b169119161790565b9055015160405190602082015260208152610df981612c69565b604051610e0581612c69565b60018152602036818301377ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7610e3a826132be565b526007546001600160a01b031690813b15610056579160405192839163b46f007160e01b8352604483016040600485015282518091526020606485019301906000905b80821061115257505050600083610ea3829694829460031984830301602485015261319e565b03925af1801561114657611137575b505b6003610ebf8861312e565b50015433600052601460205260406000209060405191610ede83612c4e565b805483526002600182015491826020860152015460408401526201518019811161105c576201518001811461112057600160408301525b6020820152336000526014602052604060002081518155602082015160018201556002604083015191015560005b60038110611072575b50503360005260146020526040600020600260405191610f6b83612c4e565b80548352600181015460208401520154604082015260005b60038110610f9a575b5050610b27905b9089610b1c565b8151600e8201546001600160a01b031660009081526014602052604090205410610fcc57610fc7906132af565b610f83565b905060025b818111610ff55750600e0180546001600160a01b03191633179055610b2789610f8c565b6001811061105c5760036000198201101561104657600d8101546001600160a01b0316906003811015611046576110419181600e01906001600160601b0360a01b825416179055613923565b610fd1565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b604082015160018060a01b038260110154166000526014602052600260406000200154106110a8576110a3906132af565b610f43565b905060025b8181116110cf575060110180546001600160a01b031916331790558880610f4c565b6001811061105c576003600019820110156110465760108101546001600160a01b03169060038110156110465761111b9181601101906001600160601b0360a01b825416179055613923565b6110ad565b61112d60408301516132af565b6040830152610f15565b61114090612c3b565b88610eb2565b6040513d6000823e3d90fd5b8251855287955060209485019490920191600190910190610e7d565b9091506080830151600052600d6020526040600020906001811061105c5761119e6111ca926000198301906130b1565b90549060031b1c6080850151600052600d6020526111c3610dc68360406000206130b1565b9055613923565b908991610d9d565b9050158b610d6d565b50929596509296939093610eb4565b6111f390612c3b565b8a610c58565b60405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081c185e5b595b9d607a1b6044820152606490fd5b9296610b2790611247879894979693966137e3565b610f93565b928194955061127b925090611266846080819401516134c1565b516112768360018b018484613a79565b613987565b81156112da575b60a0810151156112bd575b906112ac816112b2936080880151906112a683836134c1565b526134c1565b506132af565b8b8593928592610ae5565b92906112ac816112cf6112b2946132af565b95925092505061128d565b60a08101516112825760405162461bcd60e51b8152602060048201526024808201527f596f752073686f742074686520626f647920796f752073686f756c642070726f6044820152631d1958dd60e21b6064820152608490fd5b60405162461bcd60e51b8152602060048201526013602482015272151a5b59481b1a5b5a5d08195e18d959591959606a1b6044820152606490fd5b6001602082829351855501920192019190610a45565b81519083518092149283611458575b83611445575b83611432575b83611424575b5050159182611413575b50811561140b575b50156113c6578e80806109c5565b60405162461bcd60e51b815260206004820152601760248201527f496e76616c696420696e666c696768744d697373696c650000000000000000006044820152606490fd5b90508f6113b8565b60200151620f4240149150386113b0565b6080015114915038806113a6565b92506060830151606085015114926113a0565b925060408301516040850151149261139a565b9250602083015160208501511492611394565b60405162461bcd60e51b815260206004820152602560248201527f4f776e6572206f6620746869732070726f6f66206973206e6f7420746865207360448201526432b73232b960d91b6064820152608490fd5b60405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103b32b934b334b2b960811b6044820152606490fd5b60405162461bcd60e51b815260206004820152601460248201527313195d995b08185b1c9958591e481cdbdb1d995960621b6044820152606490fd5b60405162461bcd60e51b815260206004820152601f60248201527f50726576696f7573206c6576656c206e6f742079657420636f6d706c657465006044820152606490fd5b005b60405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c7920736f6c76652072756e73206f6e207468652063757272656044820152656e742064617960d01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526012602482015271149d5b88185b1c9958591e481cdbdb1d995960721b6044820152606490fd5b60405162461bcd60e51b815260206004820152602660248201527f4f6e6c7920746865206f776e6572206f66207468652072756e2063616e20736f6044820152651b1d99481a5d60d21b6064820152608490fd5b94506017549460405161166d81612c05565b60006020820152600060408201526000606082015260006080820152606060a08201523381526001431061105c57604051876020820152600060408201526000194301406060820152606081528060808101106001600160401b036080830111176119985760808101604052602081519101206060820152856080820152600160401b87101561199857600187016017556117078761312e565b6119ae578151815460208401516001600160a81b03199091166001600160a01b03929092169190911790151560a090811b60ff60a01b16919091178255604083015160018301556060830151600283015560808301516003830155820151805190600160401b82116119985760048301548260048501558083106118e8575b50602060049101920160005260206000206000905b8282106117ee57505050506060807fbe33ae7a5df03243155e17a5896a63473638d0a5042d1504b59ea59ff0f2b0a5920151604051908982528860208301526040820152a16117e9866137e3565b6106f8565b95839a939b94959892999b9791975161181681511515899060ff801983541691151516179055565b60208101516001890155604081015160028901556060810151600389016000915b600583106118d2575050506080015198600888019660009a5b60068c10156118b157600760208260c0600194518d815190558d86858301519101558d600260408301519101558d600360608301519101558d600460808301519101558d600560a0830151910155015160068d01550199019b019a97611850565b50959c9a92989399509550959299603260206001920194019201909161179b565b8051825560019283019290910190602001611837565b6118f190612eaa565b6118fa83612eaa565b906004850160005260206000209182015b818301811061191b575050611786565b600081556000600182015560006002820155600381015b60088201811061198c5750600881015b603282018110611955575060320161190b565b8060006007925560006001820155600060028201556000600382015560006004820155600060058201556000600682015501611942565b60008155600101611932565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052600060045260246000fd5b60405162461bcd60e51b815260206004820152601260248201527110dbdb9d1c9858dd081a5cc81c185d5cd95960721b6044820152606490fd5b6001600160401b038235116100565760208091611a23366024863560a4350101612e0a565b8152019101906106ba565b36601f8501121561005657604051611a4581612c69565b803660808701116100565785905b608087018210611a70575050815260809390930192602001610622565b6020604091611a7f36856130c1565b815201910190611a53565b34610056576020366003190112610056576004356001600160401b03811161005657611ac5611ac0610680923690600401612e0a565b614319565b611ad260405180926131c3565bf35b34610056576020366003190112610056576004356001600160a01b0381169081900361005657611b02613257565b600580546001600160a01b031916919091179055005b3461005657602080600319360112610056576004356001600160401b03811161005657611b49903690600401612e0a565b9060405191611b5783612d0f565b610a40809336903760405190611b6c82612d0f565b8336833760005b60528110611ba6575050604051916000835b60528210611b91578585f35b82806001928651815201940191019092611b85565b80611bb4611bc192846132cb565b518160051b8501526132af565b611b73565b346100565760208060031936011261005657611bee6004611be7813561312e565b5001613401565b906040519181839283018184528251809152816040850193019160005b828110611c1a57505050500390f35b919390838194965051805115158352818101518284015260408101516040840152606080820151908401906000915b60058310611c7d57505050600192611c6d6080610640930151610100830190612fbc565b0195019101918594939192611c0b565b8151815287946001909301929182019101611c49565b34610056576020806003193601126100565760065460405163295d33a960e21b815260048035908201529190600090839060249082906001600160a01b03165afa91821561114657600092611cfc575b50611cf860405192828493845283019061319e565b0390f35b9091503d806000833e611d0f8183612dd2565b8101908281830312610056578051906001600160401b038211610056570181601f82011215610056578051611d43816138d8565b92611d516040519485612dd2565b81845284828401011161005657611d6d91848085019101613169565b9082611ce3565b346100565760203660031901126100565760043560175481101561005657600560a091601760005202807fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150154907fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c16810154907fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c187fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c178201549101549160ff60405194600180881b0381168652861c1615156020850152604084015260608301526080820152f35b34610056576020366003190112610056576004356001600160a01b0381169081900361005657611e89613257565b47907fb08889abce443443404b2caf69aa3ccfb9ebfdf1ad2a634d06e11e24c1067938611ed76000808060405187875af1611ec26138f3565b9060405192839260408452604084019061319e565b9560208301521515940390a3005b34610056576020366003190112610056576004356001600160401b03811161005657611f20611f1b6107c0923690600401612e0a565b614361565b611ad26040518092613106565b34610056576000366003190112610056576020600454604051908152f35b34610056576000366003190112610056576006546040516001600160a01b039091168152602090f35b3461005657611f8236612f4d565b9160018060a01b031660005260156020526040600020906000526020526040600020906007811015610056576020910154604051908152f35b34610056576020366003190112610056576020611fd9600435613635565b604051908152f35b346100565760203660031901126100565760043560058110156100565760209060080154604051908152f35b34610056576000366003190112610056576017546001811061105c5760209060405190600019018152f35b3461005657602080600319360112610056576004356001600160401b03811161005657612069903690600401612e0a565b906040519161207783612cf3565b610b8080933690376040519061208c82612cf3565b8336833760005b605c81106120c6575050604051916000835b605c82106120b1578585f35b828060019286518152019401910190926120a5565b80611bb46120d492846132cb565b612093565b34610056576000366003190112610056576000546040516001600160a01b039091168152602090f35b346100565760203660031901126100565761211b613257565b600480359055005b346100565760003660031901126100565760206040516204f1a08152f35b34610056576000366003190112610056576007546040516001600160a01b039091168152602090f35b3461005657610160366003190112610056576024356001600160a01b038116810361005657366063121561005657604051906121a582612c69565b608482368211610056576044905b82821061226a5750503660a31215610056576040516121d181612c69565b806101049236841161005657905b83821061225057505036610123121561005657604051916121ff83612c69565b826101449136831161005657905b82821061224057505035936001600160401b03851161005657612237611577953690600401612e0a565b93600435613de8565b813581526020918201910161220d565b602060409161225f36856130c1565b8152019101906121df565b81358152602091820191016121b3565b3461005657602080600319360112610056576004356001600160401b038111610056576122ab903690600401612e0a565b90604051916122b983612cd7565b6102c08093369037604051906122ce82612cd7565b8336833760005b60168110612308575050604051916000835b601682106122f3578585f35b828060019286518152019401910190926122e7565b80611bb461231692846132cb565b6122d5565b3461005657602036600319011261005657600435600381101561005657600e01546040516001600160a01b039091168152602090f35b346100565761235f36612e94565b9060005260166020526040600020600382101561005657602091612382916130b1565b905460405160039290921b1c6001600160a01b03168152f35b34610056576000366003190112610056576123b4613257565b600080546001600160a01b0319811682556040519082906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b34610056576020366003190112610056576001600160a01b0361241b612f37565b16600052601460205260606040600020805490600260018201549101549060405192835260208301526040820152f35b3461005657602080600319360112610056576004356001600160401b0381116100565761247c903690600401612e0a565b906040519161248a83612cbb565b610cc080933690376040519061249f82612cbb565b8336833760005b606681106124d9575050604051916000835b606682106124c4578585f35b828060019286518152019401910190926124b8565b80611bb46124e792846132cb565b6124a6565b3461005657602036600319011261005657600435600381101561005657601101546040516001600160a01b039091168152602090f35b3461005657600036600319011261005657602060ff600354166040519015158152f35b34610056576000366003190112610056576020611fd9620151804206426132df565b34610056576020366003190112610056576004356001600160401b038111610056576125a261259d610900923690600401612e0a565b6143a9565b611ad26040518092613089565b34610056576020366003190112610056576004356001600160a01b03811690819003610056576125dd613257565b600780546001600160a01b031916919091179055005b506125fc612f77565b61000e565b34610056576101403660031901126100565761261c36613028565b60e435906001600160401b0382116100565761263f611577923690600401612e0a565b9061012435916101043591613a79565b34610056576000366003190112610056576020604051614e208152f35b34610056576101203660031901126100565761268736613028565b60e4356001600160401b0381116100565760e0916126ac6126b6923690600401612e0a565b6101043591613987565b611ad2604051809260c08091805184526020810151602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b346100565761056061271961271336612e94565b906134ed565b6127266040518093612fbc565b610540820152f35b34610056576020366003190112610056576004356001600160401b03811161005657612769612764610540923690600401612e0a565b6142d1565b611ad26040518092612f94565b3461005657600036600319011261005657602060405160148152f35b34610056576127a036612e94565b906000526018602052604060002090600052602052602060018060a01b0360406000205416604051908152f35b34610056576060366003190112610056576020611fd9604435602435600435613546565b34610056576020366003190112610056576020611fd960043561425d565b346100565760403660031901126100565760e06126b660243560043561356f565b34610056576000366003190112610056576128496136c2565b62093a8019811161105c57611fd960209162093a804291016132df565b346100565761287436612f4d565b9061287d613257565b60009081526018602090815260408083209383529290522080546001600160a01b0319166001600160a01b03909216919091179055005b34610056576128c236612e94565b906000526002602052604060002090604051916128de83612c69565b546001600160a01b0380821680855260a09290921c6020850152929015612935575b6001600160601b03602082015116826000190481118315151661105c5760409361271092511692845193845202046020820152f35b5060405161294281612c69565b600154838116825260a01c6020820152612900565b3461005657602036600319011261005657612970612f37565b612978613257565b600680546001600160a01b0319166001600160a01b0392909216919091179055005b3461005657600036600319011261005657602060405162093a808152f35b3461005657602036600319011261005657602060046129d7813561312e565b500154604051908152f35b34610056576000366003190112610056576005546040516001600160a01b039091168152602090f35b3461005657602080600319360112610056576004356001600160401b03811161005657612a3c903690600401612e0a565b9060405191612a4a83612c9f565b610e00809336903760405190612a5f82612c9f565b8336833760005b60708110612a99575050604051916000835b60708210612a84578585f35b82806001928651815201940191019092612a78565b80611bb4612aa792846132cb565b612a66565b346100565760203660031901126100565760043580151580910361005657612ad2613257565b60ff8019600354169116176003556000604051f35b34610056576000366003190112610056576020611fd96136c2565b34610056576020611fd9612b1536612e94565b90613691565b346100565760203660031901126100565760043563ffffffff60e01b81168091036100565760209063152a902d60e11b8114908115612b5f57506040519015158152f35b6301ffc9a760e01b14905082610432565b34610056576020366003190112610056576004356001600160401b03811161005657612bab612ba6610400923690600401612e0a565b61427c565b611ad26040518092612e68565b3461005657606036600319011261005657600435612bd8816024356132df565b8015612bef57602091611fd99160443506906134e1565b634e487b7160e01b600052601260045260246000fd5b60c081019081106001600160401b0382111761199857604052565b60a081019081106001600160401b0382111761199857604052565b6001600160401b03811161199857604052565b606081019081106001600160401b0382111761199857604052565b604081019081106001600160401b0382111761199857604052565b60e081019081106001600160401b0382111761199857604052565b610e0081019081106001600160401b0382111761199857604052565b610cc081019081106001600160401b0382111761199857604052565b6102c081019081106001600160401b0382111761199857604052565b610b8081019081106001600160401b0382111761199857604052565b610a4081019081106001600160401b0382111761199857604052565b608081019081106001600160401b0382111761199857604052565b61040081019081106001600160401b0382111761199857604052565b61054081019081106001600160401b0382111761199857604052565b61068081019081106001600160401b0382111761199857604052565b6107c081019081106001600160401b0382111761199857604052565b61090081019081106001600160401b0382111761199857604052565b90601f801991011681019081106001600160401b0382111761199857604052565b6001600160401b0381116119985760051b60200190565b81601f8201121561005657803591612e2183612df3565b92612e2f6040519485612dd2565b808452602092838086019260051b820101928311610056578301905b828210612e59575050505090565b81358152908301908301612e4b565b916000915b60209081841015612e8d5790806001928651815201940192019192612e6d565b5050915050565b6040906003190112610056576004359060243590565b7f051eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851e811160011661105c5760320290565b80600019046005118115151661105c5760050290565b6001600160ff1b03811160011661105c5760011b90565b7f3333333333333333333333333333333333333333333333333333333333333333811160011661105c5760050290565b600435906001600160a01b038216820361005657565b6060906003190112610056576004356001600160a01b038116810361005657906024359060443590565b503461005657600036600319011261005657602060405160028152f35b6000915b602a8310612fa557505050565b600190825181526020809101920192019190612f98565b906000905b60068210612fce57505050565b602060e08261301c600194875160c08091805184526020810151602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b01930191019091612fc1565b60e0906003190112610056576040519060e082018281106001600160401b0382111761199857604052816004358152602435602082015260443560408201526064356060820152608435608082015260a43560a082015260c060c435910152565b6000915b6048831061309a57505050565b60019082518152602080910192019201919061308d565b6003821015611046570190600090565b9080601f8301121561005657604051916130da83612c69565b82906040810192831161005657905b8282106130f65750505090565b81358152602091820191016130e9565b6000915b603e831061311757505050565b60019082518152602080910192019201919061310a565b601754811015611046576005906017600052027fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150190600090565b918091926000905b828210613189575011613182575050565b6000910152565b91508060209183015181860152018291613171565b906020916131b781518092818552858086019101613169565b601f01601f1916010190565b6000915b603483106131d457505050565b6001908251815260208091019201920191906131c7565b81601f820112156100565780359061320282612df3565b9260409261321284519586612dd2565b808552602091828087019260061b85010193818511610056578301915b84831061323f5750505050505090565b83869161324c84866130c1565b81520192019161322f565b6000546001600160a01b0316330361326b57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b600019811461105c5760010190565b8051156110465760200190565b80518210156110465760209160051b010190565b81811061105c570390565b60405191906000835b600582106133195750505060a082018281106001600160401b0382111761199857604052565b60016020819285548152019301910190916132f3565b90604080519261333e84612c20565b8360ff825416151581526001938483015491602092838201526002908185015486820152600361336f8187016132ea565b906060918284015287519761338389612c05565b60009760080195895b6006808b10156133ee57898d926007928651906133a882612c84565b8c548252858d0154848301528b8d015488830152888d01548a83015260048d0154608083015260058d015460a08301528c015460c082015281520198019901989661338c565b5050995050505092505050608091500152565b90815461340d81612df3565b9261341b6040519485612dd2565b818452600090815260208082208186015b84841061343a575050505050565b6032836001926134498561332f565b81520192019301929061342c565b6040519061346482612c84565b8160c06000918281528260208201528260408201528260608201528260808201528260a08201520152565b6040519061349c82612c05565b8160005b60c081106134ac575050565b6020906134b7613457565b81840152016134a0565b9060068110156110465760051b0190565b6127108119811161105c570190565b8119811161105c570190565b91906134f761348f565b9260005b82811115613514575050600119811161105c5760010190565b8061352c81613527613541948787613546565b61356f565b61353682886134c1565b526112ac81876134c1565b6134fb565b916040519160208301938452604083015260608201526060815261356981612d2b565b51902090565b61362d9061357b613457565b50613596613587613457565b938085528260c0860152613635565b60a0840152604051906020918281019182528281526135b481612c69565b519020620f424090818106838601526040518381019182528381526135d881612c69565b51902090810660408501526040518281019182528281526135f881612c69565b519020614e209161360a8383066134d2565b606086015260405190808201928352815261362481612c69565b519020066134d2565b608082015290565b61367860ff9160066040519161364a83612c05565b60248352601b60208401526016604084015260116060840152600c6080840152600760a084015206906134c1565b51166103e890806000190482118115151661105c570290565b906001431061105c576040519060208201928352604082015260001943014060608201526060815261356981612d2b565b6204f1a0421061105c576136e162093a806204f19f19420106426132df565b90565b8054821015611046576000526032602060002091020190600090565b92906119ae57613721829392511515839060ff801983541691151516179055565b6020918284015192600193848301556040948581015193600294858501556060918281015160039081870190896000915b600583106137cf575050505060086080809301519601936000965b6006808910156137c157815180518855888101518c8901558c8101518b890155838101518589015585810151600489015560a0810151600589015560c001519087015596890196600790950194860161376d565b505050505095505050505050565b80518455928101929101908a908801613752565b60036137ee8261312e565b5001549060046137fd8261312e565b500154600119811161105c57600101906040519261381a84612c20565b600084526000602085015260408401926000845260405161383a81612c20565b60a036823760608601526080850161385061348f565b815261385c8285613691565b855261386882846134ed565b50905260046138768461312e565b5001938454600160401b811015611998577f70f3b6a85b7a5047df9e61440f8b6480a7cd8a96f849a4092d0a22303a5dbb0f96610b108260809860016138be950181556136e4565b5190604051938452602084015260408301526060820152a1565b6001600160401b03811161199857601f01601f191660200190565b3d1561391e573d90613904826138d8565b916139126040519384612dd2565b82523d6000602084013e565b606090565b801561105c576000190190565b9060405161393d81612c05565b60a06139826004839560ff8154600180871b0381168752851c161515602086015260018101546040860152600281015460608601526003810154608086015201613401565b910152565b9190613991613457565b5061399b82612eda565b916005928019841161105c576139b3908401836132cb565b5160208501526139c281612eda565b8019841161105c576001198482011161105c5760066139e29101836132cb565b5160408501526139f181612eda565b8019841161105c576002198482011161105c576007613a119101836132cb565b516060850152613a2081612eda565b908119841161105c576003198483011161105c57613a446008613a4f9301846132cb565b516080860152612eda565b918219811161105c576004199083011161105c576009613a709201906132cb565b5160a082015290565b9291906020928385015190613a8d84612f07565b906005918019831161105c57613aae90613aa683612eda565b9084016134e1565b600219939084811161105c576002613ac79101866132cb565b5103613d3e576040870151613adb86612f07565b8019841161105c57613af890613af084612eda565b9085016134e1565b600119811161105c5784600182011161105c576003613b189101866132cb565b5103613d0457606087015196613b2d86612f07565b8019841161105c57613b4290613af084612eda565b9784891161105c578460028a011161105c57613b626004809a01876132cb565b5103613ccd576080810151613b7687612f07565b80198511613cb857613b9390613b8b85612eda565b9086016134e1565b6003198111613cb857856003820111613cb85784613bb29101876132cb565b5103613c815760a0613bc691015195612f07565b9081198311613c6c5790613bdd613be49392612eda565b91016134e1565b906004198211613c575785820111613c4257906006613c049201906132cb565b5103613c0e575050565b60405162461bcd60e51b815291820152600e60248201526d496e76616c69642072616469757360901b604482015260649150fd5b601185634e487b7160e01b6000525260246000fd5b601186634e487b7160e01b6000525260246000fd5b601188634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808901889052601060248201526f496e76616c696420766563746f72207960801b6044820152606490fd5b60118a634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808901889052601060248201526f092dcecc2d8d2c840eccac6e8dee440f60831b6044820152606490fd5b60405162461bcd60e51b8152600481018790526012602482015271496e76616c696420706f736974696f6e207960701b6044820152606490fd5b60405162461bcd60e51b8152600481018790526012602482015271092dcecc2d8d2c840e0dee6d2e8d2dedc40f60731b6044820152606490fd5b90816020910312610056575180151581036100565790565b6000915b60028310613da157505050565b600190825181526020809101920192019190613d94565b906000905b60028210613dca57505050565b6020604082613ddc6001948751613d90565b01930191019091613dbd565b939091929360028114600014613edf57509161050491613e53613e3494613e48613e146020989961427c565b91613e3e6040519a8b998a98630f3022c960e21b8a5260048a0190613d90565b6044880190613db8565b60c4860190613d90565b610104840190612e68565b6001600160a01b03165afa90811561114657600091613eb1575b5015613e7557565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21019103137b23c90383937b7b360611b6044820152606490fd5b613ed2915060203d8111613ed8575b613eca8183612dd2565b810190613d78565b38613e6d565b503d613ec0565b60038103613faa57509161064491613f2e613e3494613f23613f03602098996142d1565b91613e3e6040519a8b998a986371dd4db160e11b8a5260048a0190613d90565b610104840190612f94565b6001600160a01b03165afa90811561114657600091613f8c575b5015613f5057565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21019903137b23c90383937b7b360611b6044820152606490fd5b613fa4915060203d8111613ed857613eca8183612dd2565b38613f48565b929390600495848780961460001461407e57509261400261078493613ff760209794613e3e613fdc613e349b99614319565b936040519b8c9a8b99632a6d5ed560e01b8b528a0190613d90565b6101048401906131c3565b6001600160a01b03165afa90811561114657600091614060575b50156140255750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101a103137b23c90383937b7b360611b6044820152fd5b614078915060203d8111613ed857613eca8183612dd2565b3861401c565b600581036141485750926140cc6108c4936140c160209794613e3e6140a6613e349b99614361565b936040519b8c9a8b9963ea59061d60e01b8b528a0190613d90565b610104840190613106565b6001600160a01b03165afa9081156111465760009161412a575b50156140ef5750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101a903137b23c90383937b7b360611b6044820152fd5b614142915060203d8111613ed857613eca8183612dd2565b386140e6565b6006919293949550146000146142195760209361419d613e349694614192610a0495613e3e6141778c976143a9565b936040519b8c9a8b996311b5352360e01b8b528a0190613d90565b610104840190613089565b6001600160a01b03165afa908115611146576000916141fb575b50156141c05750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101b103137b23c90383937b7b360611b6044820152fd5b614213915060203d8111613ed857613eca8183612dd2565b386141b7565b60405162461bcd60e51b8152602081880152601860248201527f496e76616c6964206e756d626572206f6620626f6469657300000000000000006044820152606490fd5b600c811061105c57600a90600b1901046001811061105c576000190190565b9060405161428981612d46565b61040080913690376040519061429e82612d46565b36823760005b602081106142b157509150565b806142bf6142cc92866132cb565b518160051b8401526132af565b6142a4565b906040516142de81612d62565b6105408091369037604051906142f382612d62565b36823760005b602a811061430657509150565b806142bf61431492866132cb565b6142f9565b9060405161432681612d7e565b61068080913690376040519061433b82612d7e565b36823760005b6034811061434e57509150565b806142bf61435c92866132cb565b614341565b9060405161436e81612d9a565b6107c080913690376040519061438382612d9a565b36823760005b603e811061439657509150565b806142bf6143a492866132cb565b614389565b906040516143b681612db6565b6109008091369037604051906143cb82612db6565b36823760005b604881106143de57509150565b806142bf6143ec92866132cb565b6143d156fea26469706673582212204001863979e4f4694fa1b36381823478399113603bc7a804f72698f9616d617964736f6c634300080f0033c624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15", + "deployedBytecode": "0x60806040526004361015610097575b361561005b57346100565760405162461bcd60e51b81526020600482015260156024820152746e6f2066616c6c6261636b207468616e6b20796f7560581b6044820152606490fd5b600080fd5b60405162461bcd60e51b81526020600482015260146024820152736e6f2072656365697665207468616e6b20796f7560601b6044820152606490fd5b60003560e01c8063010520a114612bb8578063014a30d214612b7057806301ffc9a714612b1b578063041df08214612b0257806306575c8914612ae757806308cdc2a814612aac578063098b5e9314612a0b5780630b27ce3f146129e257806310d80a55146129b8578063132d5ed91461299a578063158b38b6146129575780632a55205a146128b45780632b057afa146128665780632e93a49214612830578063355f7407146125f357806335d6f0cc1461280f5780633bdbdb71146127f15780633ef2570b146127cd57806343569ffb146127925780634b9862d9146127765780634caa028b1461272e5780634dbe7f73146126ff5780635103d6ea1461266c5780635120a2611461264f578063530ab7dc1461260157806353e52f09146125f35780635542437b146125af5780635bd6b2ea146125675780635c9302c9146125455780635c975abb146125225780636498c128146124ec5780636ef24f2d1461244b57806370180bc1146123fa578063715018a61461239b57806371b8ccb014612351578063770c5da11461231b5780637a19b1901461227a578063861f75561461216a57806387b07780146121415780638cc52cf3146121235780638d6cc56d146121025780638da5cb5b146120d9578063907311b1146120385780639196b7001461200d5780639654c1f714611fe15780639691f1ab14611fbb57806398a6a64114611f745780639bc4961714611f4b578063a035b1fe14611f2d578063ac4a604714611ee5578063adcbb85b14611e5b578063ae66f57c14611d74578063b24f67b814611c93578063bd2c955214611bc6578063c8b90ebb14611b18578063cc80b8ea14611ad4578063d8531e6e14611a8a578063de89d1c114610582578063e2adba8c14610566578063ed3437f814610549578063f2fde38b14610481578063f6fbc39a146103e3578063f81c8ec3146103c5578063f9cfa06f146103a75763ffd73d3b0361000e57346100565761037536612e94565b90600052600d6020526040600020600382101561005657602091610398916130b1565b90549060031b1c604051908152f35b34610056576000366003190112610056576020604051620151808152f35b34610056576000366003190112610056576020604051620f42408152f35b346100565760203660031901126100565760043563ffffffff60e01b8116809103610056576020906301ffc9a760e01b8114908115610470575b811561045f575b811561044e575b811561043d575b506040519015158152f35b632483248360e11b14905082610432565b63152a902d60e11b8114915061042b565b6303a24d0760e21b81149150610424565b636cdb3d1360e11b8114915061041d565b346100565760203660031901126100565761049a612f37565b6104a2613257565b6001600160a01b039081169081156104f557600080546001600160a01b031981168417825560405191939192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08484a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b346100565760003660031901126100565760206040516103e88152f35b3461005657600036600319011261005657602060405160058152f35b60c0366003190112610056576024356001600160401b038111610056576105ad903690600401612e0a565b6044356001600160401b038111610056576105cc9036906004016131eb565b6064356001600160401b0381116100565736602382011215610056578060040135906105f782612df3565b916106056040519384612dd2565b80835260208301913660248360071b830101116100565760248101925b60248360071b8301018410611a2e57505050506084356001600160401b038111610056576106549036906004016131eb565b916001600160401b0360a435116100565736602360a4350112156100565761068160a43560040135612df3565b61068e6040519182612dd2565b60a4356004013581526020810136602460a4356004013560051b60a43501011161005657602460a43501905b602460a4356004013560051b60a435010182106119fe5750506004359360ff600354166119c4576106f0620151804206426132df565b93851561165b575b6107018661312e565b50546001600160a01b031633036116075760ff61071d8761312e565b505460a01c166115cd5760036107328761312e565b50015485036115795760005b83518110156115775786610752828a6132cb565b5161075d83886132cb565b519061076984866132cb565b519161077585886132cb565b5192610781868a6132cb565b51926004610798610792865161425d565b9761312e565b500154809603611532576001861061105c5760ff6107c76107b88f61312e565b506000198901906004016136e4565b5054166114f657600119861161105c5760018601600052601860205260406000209060005260205260018060a01b03604060002054169384156114be5761081060018701612eda565b801960051161105c57600119600582011161105c5733906001600160a01b039061083d90600601876132cb565b51160361146b5761086c60036108658f6108569061312e565b506000198a01906004016136e4565b50016132ea565b6040519061087982612c20565b61088d61088860018a01612ef0565b612eda565b801960051161105c57600219600582011161105c5760076108af9101876132cb565b5182526108c161088860018a01612ef0565b801960051161105c57600219600582011161105c57600119600782011161105c5760086108ef9101876132cb565b51602083015261090461088860018a01612ef0565b801960051161105c57600219600582011161105c57600219600782011161105c5760096109329101876132cb565b51604083015261094761088860018a01612ef0565b801960051161105c57600219600582011161105c57600319600782011161105c57600a6109759101876132cb565b51606083015261098a61088860018a01612ef0565b801960051161105c57600219600582011161105c57600419600782011161105c57600b6109b89101876132cb565b5180608084015280611385575b5050506040516109d481612c20565b6109dd856132be565b518152845160011015611046576040850151602082015284516002101561104657606085015160408201528451600310156110465760808501516060820152845160041015611046576003610a3f8f6108569060a0890151608086015261312e565b50016000915b6005831061136f57505050610a5c60018701612eda565b91821960051161105c57610a8393610a788694600501856132cb565b519660018901613de8565b610ab5610aaa610aa4610a958d61312e565b506000198701906004016136e4565b5061332f565b9260208401516134e1565b80602084015260056000198501101561104657600784015410611334578290828b600092610ae1613457565b5060005b60018601811061124c57505090610b10610b01610b169361312e565b506000198601906004016136e4565b90613700565b14610b2c575b5050610b27906132af565b61073e565b906020600592610b57610b488c9b989c9d99969d9a979a61312e565b506000198501906004016136e4565b50600160ff19825416179055828a8383015160405190815289858201527f416328325568dd8681e48de39e8d89a80ddf01a688fbcb49c28c621071c9333b60403392a40151610bb46001610baa8b61312e565b50019182546134e1565b90550361123257610bc48661312e565b50805460ff60a01b1916600160a01b17905560045434036111f9576005546040516000918291829134906001600160a01b03165af1610c016138f3565b6007546001600160a01b0316803b15610056576000809160a46040518094819363093ccd3160e41b83523360048401528b602484015260016044840152608060648401528160848401525af18015611146576111ea575b507fb08889abce443443404b2caf69aa3ccfb9ebfdf1ad2a634d06e11e24c1067938610c9d60018060a01b03600554169260405191829160408352604083019061319e565b943460208301521515940390a3856001610cb68261312e565b5001546040519081528460208201527f7f05a2f6290fe88fe25ed1665c50706361d709c5003e3067340b9053916fd70760403392a33360005260146020526040600020610d0381546132af565b9055610d17610d118761312e565b50613930565b9660005b6080890151600052600d60205260038110156111db576080890151600052610d59610d11610d4d8360406000206130b1565b90549060031b1c61312e565b6040808b01519101518091109081156111d2575b50610d8057610d7b906132af565b610d1b565b96889194976080829a9b94979b9895980151600052600d60205260025b81811161116e575090610ddf610dc68493608080960151600052600d60205260406000206130b1565b819391549060031b600019811b9283911b169119161790565b9055015160405190602082015260208152610df981612c69565b604051610e0581612c69565b60018152602036818301377ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7610e3a826132be565b526007546001600160a01b031690813b15610056579160405192839163b46f007160e01b8352604483016040600485015282518091526020606485019301906000905b80821061115257505050600083610ea3829694829460031984830301602485015261319e565b03925af1801561114657611137575b505b6003610ebf8861312e565b50015433600052601460205260406000209060405191610ede83612c4e565b805483526002600182015491826020860152015460408401526201518019811161105c576201518001811461112057600160408301525b6020820152336000526014602052604060002081518155602082015160018201556002604083015191015560005b60038110611072575b50503360005260146020526040600020600260405191610f6b83612c4e565b80548352600181015460208401520154604082015260005b60038110610f9a575b5050610b27905b9089610b1c565b8151600e8201546001600160a01b031660009081526014602052604090205410610fcc57610fc7906132af565b610f83565b905060025b818111610ff55750600e0180546001600160a01b03191633179055610b2789610f8c565b6001811061105c5760036000198201101561104657600d8101546001600160a01b0316906003811015611046576110419181600e01906001600160601b0360a01b825416179055613923565b610fd1565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b604082015160018060a01b038260110154166000526014602052600260406000200154106110a8576110a3906132af565b610f43565b905060025b8181116110cf575060110180546001600160a01b031916331790558880610f4c565b6001811061105c576003600019820110156110465760108101546001600160a01b03169060038110156110465761111b9181601101906001600160601b0360a01b825416179055613923565b6110ad565b61112d60408301516132af565b6040830152610f15565b61114090612c3b565b88610eb2565b6040513d6000823e3d90fd5b8251855287955060209485019490920191600190910190610e7d565b9091506080830151600052600d6020526040600020906001811061105c5761119e6111ca926000198301906130b1565b90549060031b1c6080850151600052600d6020526111c3610dc68360406000206130b1565b9055613923565b908991610d9d565b9050158b610d6d565b50929596509296939093610eb4565b6111f390612c3b565b8a610c58565b60405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081c185e5b595b9d607a1b6044820152606490fd5b9296610b2790611247879894979693966137e3565b610f93565b928194955061127b925090611266846080819401516134c1565b516112768360018b018484613a79565b613987565b81156112da575b60a0810151156112bd575b906112ac816112b2936080880151906112a683836134c1565b526134c1565b506132af565b8b8593928592610ae5565b92906112ac816112cf6112b2946132af565b95925092505061128d565b60a08101516112825760405162461bcd60e51b8152602060048201526024808201527f596f752073686f742074686520626f647920796f752073686f756c642070726f6044820152631d1958dd60e21b6064820152608490fd5b60405162461bcd60e51b8152602060048201526013602482015272151a5b59481b1a5b5a5d08195e18d959591959606a1b6044820152606490fd5b6001602082829351855501920192019190610a45565b81519083518092149283611458575b83611445575b83611432575b83611424575b5050159182611413575b50811561140b575b50156113c6578e80806109c5565b60405162461bcd60e51b815260206004820152601760248201527f496e76616c696420696e666c696768744d697373696c650000000000000000006044820152606490fd5b90508f6113b8565b60200151620f4240149150386113b0565b6080015114915038806113a6565b92506060830151606085015114926113a0565b925060408301516040850151149261139a565b9250602083015160208501511492611394565b60405162461bcd60e51b815260206004820152602560248201527f4f776e6572206f6620746869732070726f6f66206973206e6f7420746865207360448201526432b73232b960d91b6064820152608490fd5b60405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103b32b934b334b2b960811b6044820152606490fd5b60405162461bcd60e51b815260206004820152601460248201527313195d995b08185b1c9958591e481cdbdb1d995960621b6044820152606490fd5b60405162461bcd60e51b815260206004820152601f60248201527f50726576696f7573206c6576656c206e6f742079657420636f6d706c657465006044820152606490fd5b005b60405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c7920736f6c76652072756e73206f6e207468652063757272656044820152656e742064617960d01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526012602482015271149d5b88185b1c9958591e481cdbdb1d995960721b6044820152606490fd5b60405162461bcd60e51b815260206004820152602660248201527f4f6e6c7920746865206f776e6572206f66207468652072756e2063616e20736f6044820152651b1d99481a5d60d21b6064820152608490fd5b94506017549460405161166d81612c05565b60006020820152600060408201526000606082015260006080820152606060a08201523381526001431061105c57604051876020820152600060408201526000194301406060820152606081528060808101106001600160401b036080830111176119985760808101604052602081519101206060820152856080820152600160401b87101561199857600187016017556117078761312e565b6119ae578151815460208401516001600160a81b03199091166001600160a01b03929092169190911790151560a090811b60ff60a01b16919091178255604083015160018301556060830151600283015560808301516003830155820151805190600160401b82116119985760048301548260048501558083106118e8575b50602060049101920160005260206000206000905b8282106117ee57505050506060807fbe33ae7a5df03243155e17a5896a63473638d0a5042d1504b59ea59ff0f2b0a5920151604051908982528860208301526040820152a16117e9866137e3565b6106f8565b95839a939b94959892999b9791975161181681511515899060ff801983541691151516179055565b60208101516001890155604081015160028901556060810151600389016000915b600583106118d2575050506080015198600888019660009a5b60068c10156118b157600760208260c0600194518d815190558d86858301519101558d600260408301519101558d600360608301519101558d600460808301519101558d600560a0830151910155015160068d01550199019b019a97611850565b50959c9a92989399509550959299603260206001920194019201909161179b565b8051825560019283019290910190602001611837565b6118f190612eaa565b6118fa83612eaa565b906004850160005260206000209182015b818301811061191b575050611786565b600081556000600182015560006002820155600381015b60088201811061198c5750600881015b603282018110611955575060320161190b565b8060006007925560006001820155600060028201556000600382015560006004820155600060058201556000600682015501611942565b60008155600101611932565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052600060045260246000fd5b60405162461bcd60e51b815260206004820152601260248201527110dbdb9d1c9858dd081a5cc81c185d5cd95960721b6044820152606490fd5b6001600160401b038235116100565760208091611a23366024863560a4350101612e0a565b8152019101906106ba565b36601f8501121561005657604051611a4581612c69565b803660808701116100565785905b608087018210611a70575050815260809390930192602001610622565b6020604091611a7f36856130c1565b815201910190611a53565b34610056576020366003190112610056576004356001600160401b03811161005657611ac5611ac0610680923690600401612e0a565b614319565b611ad260405180926131c3565bf35b34610056576020366003190112610056576004356001600160a01b0381169081900361005657611b02613257565b600580546001600160a01b031916919091179055005b3461005657602080600319360112610056576004356001600160401b03811161005657611b49903690600401612e0a565b9060405191611b5783612d0f565b610a40809336903760405190611b6c82612d0f565b8336833760005b60528110611ba6575050604051916000835b60528210611b91578585f35b82806001928651815201940191019092611b85565b80611bb4611bc192846132cb565b518160051b8501526132af565b611b73565b346100565760208060031936011261005657611bee6004611be7813561312e565b5001613401565b906040519181839283018184528251809152816040850193019160005b828110611c1a57505050500390f35b919390838194965051805115158352818101518284015260408101516040840152606080820151908401906000915b60058310611c7d57505050600192611c6d6080610640930151610100830190612fbc565b0195019101918594939192611c0b565b8151815287946001909301929182019101611c49565b34610056576020806003193601126100565760065460405163295d33a960e21b815260048035908201529190600090839060249082906001600160a01b03165afa91821561114657600092611cfc575b50611cf860405192828493845283019061319e565b0390f35b9091503d806000833e611d0f8183612dd2565b8101908281830312610056578051906001600160401b038211610056570181601f82011215610056578051611d43816138d8565b92611d516040519485612dd2565b81845284828401011161005657611d6d91848085019101613169565b9082611ce3565b346100565760203660031901126100565760043560175481101561005657600560a091601760005202807fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150154907fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c16810154907fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c187fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c178201549101549160ff60405194600180881b0381168652861c1615156020850152604084015260608301526080820152f35b34610056576020366003190112610056576004356001600160a01b0381169081900361005657611e89613257565b47907fb08889abce443443404b2caf69aa3ccfb9ebfdf1ad2a634d06e11e24c1067938611ed76000808060405187875af1611ec26138f3565b9060405192839260408452604084019061319e565b9560208301521515940390a3005b34610056576020366003190112610056576004356001600160401b03811161005657611f20611f1b6107c0923690600401612e0a565b614361565b611ad26040518092613106565b34610056576000366003190112610056576020600454604051908152f35b34610056576000366003190112610056576006546040516001600160a01b039091168152602090f35b3461005657611f8236612f4d565b9160018060a01b031660005260156020526040600020906000526020526040600020906007811015610056576020910154604051908152f35b34610056576020366003190112610056576020611fd9600435613635565b604051908152f35b346100565760203660031901126100565760043560058110156100565760209060080154604051908152f35b34610056576000366003190112610056576017546001811061105c5760209060405190600019018152f35b3461005657602080600319360112610056576004356001600160401b03811161005657612069903690600401612e0a565b906040519161207783612cf3565b610b8080933690376040519061208c82612cf3565b8336833760005b605c81106120c6575050604051916000835b605c82106120b1578585f35b828060019286518152019401910190926120a5565b80611bb46120d492846132cb565b612093565b34610056576000366003190112610056576000546040516001600160a01b039091168152602090f35b346100565760203660031901126100565761211b613257565b600480359055005b346100565760003660031901126100565760206040516204f1a08152f35b34610056576000366003190112610056576007546040516001600160a01b039091168152602090f35b3461005657610160366003190112610056576024356001600160a01b038116810361005657366063121561005657604051906121a582612c69565b608482368211610056576044905b82821061226a5750503660a31215610056576040516121d181612c69565b806101049236841161005657905b83821061225057505036610123121561005657604051916121ff83612c69565b826101449136831161005657905b82821061224057505035936001600160401b03851161005657612237611577953690600401612e0a565b93600435613de8565b813581526020918201910161220d565b602060409161225f36856130c1565b8152019101906121df565b81358152602091820191016121b3565b3461005657602080600319360112610056576004356001600160401b038111610056576122ab903690600401612e0a565b90604051916122b983612cd7565b6102c08093369037604051906122ce82612cd7565b8336833760005b60168110612308575050604051916000835b601682106122f3578585f35b828060019286518152019401910190926122e7565b80611bb461231692846132cb565b6122d5565b3461005657602036600319011261005657600435600381101561005657600e01546040516001600160a01b039091168152602090f35b346100565761235f36612e94565b9060005260166020526040600020600382101561005657602091612382916130b1565b905460405160039290921b1c6001600160a01b03168152f35b34610056576000366003190112610056576123b4613257565b600080546001600160a01b0319811682556040519082906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b34610056576020366003190112610056576001600160a01b0361241b612f37565b16600052601460205260606040600020805490600260018201549101549060405192835260208301526040820152f35b3461005657602080600319360112610056576004356001600160401b0381116100565761247c903690600401612e0a565b906040519161248a83612cbb565b610cc080933690376040519061249f82612cbb565b8336833760005b606681106124d9575050604051916000835b606682106124c4578585f35b828060019286518152019401910190926124b8565b80611bb46124e792846132cb565b6124a6565b3461005657602036600319011261005657600435600381101561005657601101546040516001600160a01b039091168152602090f35b3461005657600036600319011261005657602060ff600354166040519015158152f35b34610056576000366003190112610056576020611fd9620151804206426132df565b34610056576020366003190112610056576004356001600160401b038111610056576125a261259d610900923690600401612e0a565b6143a9565b611ad26040518092613089565b34610056576020366003190112610056576004356001600160a01b03811690819003610056576125dd613257565b600780546001600160a01b031916919091179055005b506125fc612f77565b61000e565b34610056576101403660031901126100565761261c36613028565b60e435906001600160401b0382116100565761263f611577923690600401612e0a565b9061012435916101043591613a79565b34610056576000366003190112610056576020604051614e208152f35b34610056576101203660031901126100565761268736613028565b60e4356001600160401b0381116100565760e0916126ac6126b6923690600401612e0a565b6101043591613987565b611ad2604051809260c08091805184526020810151602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b346100565761056061271961271336612e94565b906134ed565b6127266040518093612fbc565b610540820152f35b34610056576020366003190112610056576004356001600160401b03811161005657612769612764610540923690600401612e0a565b6142d1565b611ad26040518092612f94565b3461005657600036600319011261005657602060405160148152f35b34610056576127a036612e94565b906000526018602052604060002090600052602052602060018060a01b0360406000205416604051908152f35b34610056576060366003190112610056576020611fd9604435602435600435613546565b34610056576020366003190112610056576020611fd960043561425d565b346100565760403660031901126100565760e06126b660243560043561356f565b34610056576000366003190112610056576128496136c2565b62093a8019811161105c57611fd960209162093a804291016132df565b346100565761287436612f4d565b9061287d613257565b60009081526018602090815260408083209383529290522080546001600160a01b0319166001600160a01b03909216919091179055005b34610056576128c236612e94565b906000526002602052604060002090604051916128de83612c69565b546001600160a01b0380821680855260a09290921c6020850152929015612935575b6001600160601b03602082015116826000190481118315151661105c5760409361271092511692845193845202046020820152f35b5060405161294281612c69565b600154838116825260a01c6020820152612900565b3461005657602036600319011261005657612970612f37565b612978613257565b600680546001600160a01b0319166001600160a01b0392909216919091179055005b3461005657600036600319011261005657602060405162093a808152f35b3461005657602036600319011261005657602060046129d7813561312e565b500154604051908152f35b34610056576000366003190112610056576005546040516001600160a01b039091168152602090f35b3461005657602080600319360112610056576004356001600160401b03811161005657612a3c903690600401612e0a565b9060405191612a4a83612c9f565b610e00809336903760405190612a5f82612c9f565b8336833760005b60708110612a99575050604051916000835b60708210612a84578585f35b82806001928651815201940191019092612a78565b80611bb4612aa792846132cb565b612a66565b346100565760203660031901126100565760043580151580910361005657612ad2613257565b60ff8019600354169116176003556000604051f35b34610056576000366003190112610056576020611fd96136c2565b34610056576020611fd9612b1536612e94565b90613691565b346100565760203660031901126100565760043563ffffffff60e01b81168091036100565760209063152a902d60e11b8114908115612b5f57506040519015158152f35b6301ffc9a760e01b14905082610432565b34610056576020366003190112610056576004356001600160401b03811161005657612bab612ba6610400923690600401612e0a565b61427c565b611ad26040518092612e68565b3461005657606036600319011261005657600435612bd8816024356132df565b8015612bef57602091611fd99160443506906134e1565b634e487b7160e01b600052601260045260246000fd5b60c081019081106001600160401b0382111761199857604052565b60a081019081106001600160401b0382111761199857604052565b6001600160401b03811161199857604052565b606081019081106001600160401b0382111761199857604052565b604081019081106001600160401b0382111761199857604052565b60e081019081106001600160401b0382111761199857604052565b610e0081019081106001600160401b0382111761199857604052565b610cc081019081106001600160401b0382111761199857604052565b6102c081019081106001600160401b0382111761199857604052565b610b8081019081106001600160401b0382111761199857604052565b610a4081019081106001600160401b0382111761199857604052565b608081019081106001600160401b0382111761199857604052565b61040081019081106001600160401b0382111761199857604052565b61054081019081106001600160401b0382111761199857604052565b61068081019081106001600160401b0382111761199857604052565b6107c081019081106001600160401b0382111761199857604052565b61090081019081106001600160401b0382111761199857604052565b90601f801991011681019081106001600160401b0382111761199857604052565b6001600160401b0381116119985760051b60200190565b81601f8201121561005657803591612e2183612df3565b92612e2f6040519485612dd2565b808452602092838086019260051b820101928311610056578301905b828210612e59575050505090565b81358152908301908301612e4b565b916000915b60209081841015612e8d5790806001928651815201940192019192612e6d565b5050915050565b6040906003190112610056576004359060243590565b7f051eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851e811160011661105c5760320290565b80600019046005118115151661105c5760050290565b6001600160ff1b03811160011661105c5760011b90565b7f3333333333333333333333333333333333333333333333333333333333333333811160011661105c5760050290565b600435906001600160a01b038216820361005657565b6060906003190112610056576004356001600160a01b038116810361005657906024359060443590565b503461005657600036600319011261005657602060405160028152f35b6000915b602a8310612fa557505050565b600190825181526020809101920192019190612f98565b906000905b60068210612fce57505050565b602060e08261301c600194875160c08091805184526020810151602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b01930191019091612fc1565b60e0906003190112610056576040519060e082018281106001600160401b0382111761199857604052816004358152602435602082015260443560408201526064356060820152608435608082015260a43560a082015260c060c435910152565b6000915b6048831061309a57505050565b60019082518152602080910192019201919061308d565b6003821015611046570190600090565b9080601f8301121561005657604051916130da83612c69565b82906040810192831161005657905b8282106130f65750505090565b81358152602091820191016130e9565b6000915b603e831061311757505050565b60019082518152602080910192019201919061310a565b601754811015611046576005906017600052027fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150190600090565b918091926000905b828210613189575011613182575050565b6000910152565b91508060209183015181860152018291613171565b906020916131b781518092818552858086019101613169565b601f01601f1916010190565b6000915b603483106131d457505050565b6001908251815260208091019201920191906131c7565b81601f820112156100565780359061320282612df3565b9260409261321284519586612dd2565b808552602091828087019260061b85010193818511610056578301915b84831061323f5750505050505090565b83869161324c84866130c1565b81520192019161322f565b6000546001600160a01b0316330361326b57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b600019811461105c5760010190565b8051156110465760200190565b80518210156110465760209160051b010190565b81811061105c570390565b60405191906000835b600582106133195750505060a082018281106001600160401b0382111761199857604052565b60016020819285548152019301910190916132f3565b90604080519261333e84612c20565b8360ff825416151581526001938483015491602092838201526002908185015486820152600361336f8187016132ea565b906060918284015287519761338389612c05565b60009760080195895b6006808b10156133ee57898d926007928651906133a882612c84565b8c548252858d0154848301528b8d015488830152888d01548a83015260048d0154608083015260058d015460a08301528c015460c082015281520198019901989661338c565b5050995050505092505050608091500152565b90815461340d81612df3565b9261341b6040519485612dd2565b818452600090815260208082208186015b84841061343a575050505050565b6032836001926134498561332f565b81520192019301929061342c565b6040519061346482612c84565b8160c06000918281528260208201528260408201528260608201528260808201528260a08201520152565b6040519061349c82612c05565b8160005b60c081106134ac575050565b6020906134b7613457565b81840152016134a0565b9060068110156110465760051b0190565b6127108119811161105c570190565b8119811161105c570190565b91906134f761348f565b9260005b82811115613514575050600119811161105c5760010190565b8061352c81613527613541948787613546565b61356f565b61353682886134c1565b526112ac81876134c1565b6134fb565b916040519160208301938452604083015260608201526060815261356981612d2b565b51902090565b61362d9061357b613457565b50613596613587613457565b938085528260c0860152613635565b60a0840152604051906020918281019182528281526135b481612c69565b519020620f424090818106838601526040518381019182528381526135d881612c69565b51902090810660408501526040518281019182528281526135f881612c69565b519020614e209161360a8383066134d2565b606086015260405190808201928352815261362481612c69565b519020066134d2565b608082015290565b61367860ff9160066040519161364a83612c05565b60248352601b60208401526016604084015260116060840152600c6080840152600760a084015206906134c1565b51166103e890806000190482118115151661105c570290565b906001431061105c576040519060208201928352604082015260001943014060608201526060815261356981612d2b565b6204f1a0421061105c576136e162093a806204f19f19420106426132df565b90565b8054821015611046576000526032602060002091020190600090565b92906119ae57613721829392511515839060ff801983541691151516179055565b6020918284015192600193848301556040948581015193600294858501556060918281015160039081870190896000915b600583106137cf575050505060086080809301519601936000965b6006808910156137c157815180518855888101518c8901558c8101518b890155838101518589015585810151600489015560a0810151600589015560c001519087015596890196600790950194860161376d565b505050505095505050505050565b80518455928101929101908a908801613752565b60036137ee8261312e565b5001549060046137fd8261312e565b500154600119811161105c57600101906040519261381a84612c20565b600084526000602085015260408401926000845260405161383a81612c20565b60a036823760608601526080850161385061348f565b815261385c8285613691565b855261386882846134ed565b50905260046138768461312e565b5001938454600160401b811015611998577f70f3b6a85b7a5047df9e61440f8b6480a7cd8a96f849a4092d0a22303a5dbb0f96610b108260809860016138be950181556136e4565b5190604051938452602084015260408301526060820152a1565b6001600160401b03811161199857601f01601f191660200190565b3d1561391e573d90613904826138d8565b916139126040519384612dd2565b82523d6000602084013e565b606090565b801561105c576000190190565b9060405161393d81612c05565b60a06139826004839560ff8154600180871b0381168752851c161515602086015260018101546040860152600281015460608601526003810154608086015201613401565b910152565b9190613991613457565b5061399b82612eda565b916005928019841161105c576139b3908401836132cb565b5160208501526139c281612eda565b8019841161105c576001198482011161105c5760066139e29101836132cb565b5160408501526139f181612eda565b8019841161105c576002198482011161105c576007613a119101836132cb565b516060850152613a2081612eda565b908119841161105c576003198483011161105c57613a446008613a4f9301846132cb565b516080860152612eda565b918219811161105c576004199083011161105c576009613a709201906132cb565b5160a082015290565b9291906020928385015190613a8d84612f07565b906005918019831161105c57613aae90613aa683612eda565b9084016134e1565b600219939084811161105c576002613ac79101866132cb565b5103613d3e576040870151613adb86612f07565b8019841161105c57613af890613af084612eda565b9085016134e1565b600119811161105c5784600182011161105c576003613b189101866132cb565b5103613d0457606087015196613b2d86612f07565b8019841161105c57613b4290613af084612eda565b9784891161105c578460028a011161105c57613b626004809a01876132cb565b5103613ccd576080810151613b7687612f07565b80198511613cb857613b9390613b8b85612eda565b9086016134e1565b6003198111613cb857856003820111613cb85784613bb29101876132cb565b5103613c815760a0613bc691015195612f07565b9081198311613c6c5790613bdd613be49392612eda565b91016134e1565b906004198211613c575785820111613c4257906006613c049201906132cb565b5103613c0e575050565b60405162461bcd60e51b815291820152600e60248201526d496e76616c69642072616469757360901b604482015260649150fd5b601185634e487b7160e01b6000525260246000fd5b601186634e487b7160e01b6000525260246000fd5b601188634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808901889052601060248201526f496e76616c696420766563746f72207960801b6044820152606490fd5b60118a634e487b7160e01b6000525260246000fd5b60405162461bcd60e51b8152808901889052601060248201526f092dcecc2d8d2c840eccac6e8dee440f60831b6044820152606490fd5b60405162461bcd60e51b8152600481018790526012602482015271496e76616c696420706f736974696f6e207960701b6044820152606490fd5b60405162461bcd60e51b8152600481018790526012602482015271092dcecc2d8d2c840e0dee6d2e8d2dedc40f60731b6044820152606490fd5b90816020910312610056575180151581036100565790565b6000915b60028310613da157505050565b600190825181526020809101920192019190613d94565b906000905b60028210613dca57505050565b6020604082613ddc6001948751613d90565b01930191019091613dbd565b939091929360028114600014613edf57509161050491613e53613e3494613e48613e146020989961427c565b91613e3e6040519a8b998a98630f3022c960e21b8a5260048a0190613d90565b6044880190613db8565b60c4860190613d90565b610104840190612e68565b6001600160a01b03165afa90811561114657600091613eb1575b5015613e7557565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21019103137b23c90383937b7b360611b6044820152606490fd5b613ed2915060203d8111613ed8575b613eca8183612dd2565b810190613d78565b38613e6d565b503d613ec0565b60038103613faa57509161064491613f2e613e3494613f23613f03602098996142d1565b91613e3e6040519a8b998a986371dd4db160e11b8a5260048a0190613d90565b610104840190612f94565b6001600160a01b03165afa90811561114657600091613f8c575b5015613f5057565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21019903137b23c90383937b7b360611b6044820152606490fd5b613fa4915060203d8111613ed857613eca8183612dd2565b38613f48565b929390600495848780961460001461407e57509261400261078493613ff760209794613e3e613fdc613e349b99614319565b936040519b8c9a8b99632a6d5ed560e01b8b528a0190613d90565b6101048401906131c3565b6001600160a01b03165afa90811561114657600091614060575b50156140255750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101a103137b23c90383937b7b360611b6044820152fd5b614078915060203d8111613ed857613eca8183612dd2565b3861401c565b600581036141485750926140cc6108c4936140c160209794613e3e6140a6613e349b99614361565b936040519b8c9a8b9963ea59061d60e01b8b528a0190613d90565b610104840190613106565b6001600160a01b03165afa9081156111465760009161412a575b50156140ef5750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101a903137b23c90383937b7b360611b6044820152fd5b614142915060203d8111613ed857613eca8183612dd2565b386140e6565b6006919293949550146000146142195760209361419d613e349694614192610a0495613e3e6141778c976143a9565b936040519b8c9a8b996311b5352360e01b8b528a0190613d90565b610104840190613089565b6001600160a01b03165afa908115611146576000916141fb575b50156141c05750565b60649060206040519162461bcd60e51b8352820152601460248201527324b73b30b634b2101b103137b23c90383937b7b360611b6044820152fd5b614213915060203d8111613ed857613eca8183612dd2565b386141b7565b60405162461bcd60e51b8152602081880152601860248201527f496e76616c6964206e756d626572206f6620626f6469657300000000000000006044820152606490fd5b600c811061105c57600a90600b1901046001811061105c576000190190565b9060405161428981612d46565b61040080913690376040519061429e82612d46565b36823760005b602081106142b157509150565b806142bf6142cc92866132cb565b518160051b8401526132af565b6142a4565b906040516142de81612d62565b6105408091369037604051906142f382612d62565b36823760005b602a811061430657509150565b806142bf61431492866132cb565b6142f9565b9060405161432681612d7e565b61068080913690376040519061433b82612d7e565b36823760005b6034811061434e57509150565b806142bf61435c92866132cb565b614341565b9060405161436e81612d9a565b6107c080913690376040519061438382612d9a565b36823760005b603e811061439657509150565b806142bf6143a492866132cb565b614389565b906040516143b681612db6565b6109008091369037604051906143cb82612db6565b36823760005b604881106143de57509150565b806142bf6143ec92866132cb565b6143d156fea26469706673582212204001863979e4f4694fa1b36381823478399113603bc7a804f72698f9616d617964736f6c634300080f0033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/server/contractData/ABI-12345-ExternalMetadata.json b/server/contractData/ABI-12345-ExternalMetadata.json index 71d124e0..47ad9efb 100644 --- a/server/contractData/ABI-12345-ExternalMetadata.json +++ b/server/contractData/ABI-12345-ExternalMetadata.json @@ -44,7 +44,7 @@ "inputs": [ { "internalType": "uint256", - "name": "tokenId", + "name": "date", "type": "uint256" } ], @@ -63,7 +63,7 @@ "inputs": [ { "internalType": "uint256", - "name": "tokenId", + "name": "date", "type": "uint256" } ], @@ -82,7 +82,7 @@ "inputs": [ { "internalType": "uint256", - "name": "tokenId", + "name": "date", "type": "uint256" } ], @@ -101,7 +101,7 @@ "inputs": [ { "internalType": "uint256", - "name": "tokenId", + "name": "date", "type": "uint256" } ], @@ -120,7 +120,7 @@ "inputs": [ { "internalType": "uint256", - "name": "tokenId", + "name": "date", "type": "uint256" } ], @@ -227,8 +227,8 @@ "type": "function" } ], - "bytecode": "0x6080806040523461005b5760008054336001600160a01b0319821681178355916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09084a3611d3090816100618239f35b600080fdfe60806040526004361015610013575b600080fd5b60003560e01c8063102581d21461011757806319d4c3f91461010e5780635542437b146101055780636b8ff574146100fc578063715018a6146100f357806387b07780146100ea5780638da5cb5b146100e1578063a574cea4146100d8578063be985ac9146100cf578063e1765073146100c6578063e2ce81a5146100bd578063e82fedd7146100b45763f2fde38b146100ac57600080fd5b61000e610966565b5061000e610946565b5061000e6108fe565b5061000e6108e4565b5061000e6108cf565b5061000e6103ca565b5061000e6103a0565b5061000e610376565b5061000e610314565b5061000e6102fa565b5061000e6102b2565b5061000e610277565b5061000e610193565b602090600319011261000e5760043590565b918091926000905b82821061015257501161014b575050565b6000910152565b9150806020918301518186015201829161013a565b604091602082526101878151809281602086015260208686019101610132565b601f01601f1916010190565b503461000e5761027361021b6101b06101ab36610120565b610ee3565b61021660466040518093753c68746d6c3e3c626f64793e3c696d67207372633d2760501b60208301526101ed815180926020603686019101610132565b81016f139f1e17b137b23c9f1e17b43a36b61f60811b6036820152036026810184520182610b52565b610daf565b610267603660405180937519185d184e9d195e1d0bda1d1b5b0ed8985cd94d8d0b60521b60208301526102578151809260208686019101610132565b8101036016810184520182610b52565b60405191829182610167565b0390f35b503461000e57600036600319011261000e576001546040516001600160a01b039091168152602090f35b6001600160a01b0381160361000e57565b503461000e57602036600319011261000e576004356102d0816102a1565b6102d8610a33565b600280546001600160a01b0319166001600160a01b0392909216919091179055005b503461000e5761027361026761030f36610120565b610e9b565b503461000e576000806003193601126103735761032f610a33565b80546001600160a01b0319811682556040519082906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b80fd5b503461000e57600036600319011261000e576002546040516001600160a01b039091168152602090f35b503461000e57600036600319011261000e576000546040516001600160a01b039091168152602090f35b503461000e576103d936610120565b6103e281610e9b565b906103ec81610ee3565b6103f582610ee3565b60015490939061041b9061040f906001600160a01b031681565b6001600160a01b031690565b60408051632b99bd5f60e21b815260048101869052909460a082602481865afa9283156108c2575b60009182918394849661087c575b508851635e964aa960e11b8152600481019290925260009082908180602481015b03915afa90811561086f575b60009161084e575b505161049181610c47565b9215610843576104a86104a2611a63565b94611c4b565b946104b290611a83565b926104bc90611a83565b906104c690611a83565b916104d090611a83565b8851605b60f81b6020820152958695919491602187017f7b2274726169745f74797065223a22736f6c766564222c2276616c7565223a008152601f0161051591610a8b565b7f7d2c207b2274726169745f74797065223a2273656564222c2276616c7565223a8152601160f91b602082015260210161054e91610a8b565b7f227d2c207b2274726169745f74797065223a22646179222c2276616c7565223a8152601160f91b602082015260210161058791610a8b565b7f227d2c207b2274726169745f74797065223a22626f6479436f756e74222c227681526630b63ab2911d1160c91b60208201526027016105c691610a8b565b7f227d2c207b2274726169745f74797065223a226c6576656c222c2276616c7565815262111d1160e91b602082015260230161060191610a8b565b7f227d2c207b2274726169745f74797065223a22616363756d756c61746976655481526d34b6b29116113b30b63ab2911d1160911b6020820152602e0161064791610a8b565b62227d5d60e81b81526003010394601f199586810183526106689083610b52565b8451683d913730b6b2911d1160b91b60208201529384936029850161068c91610a8b565b61088b60f21b81526002017f226465736372697074696f6e223a2022416e79626f64792050726f626c656d2081527f2868747470733a2f2f616e79626f64792e747269666c652e6c69666529222c006020820152603f01691134b6b0b3b2911d101160b11b8152600a016106ff91610a8b565b61088b60f21b81526002016d1134b6b0b3b2afbab936111d101160911b8152600e0161072a91610a8b565b61088b60f21b81526002017f22686f6d655f75726c223a202268747470733a2f2f616e79626f64792e747269815269199b194b9b1a5999488b60b21b6020820152602a017f2265787465726e616c5f75726c223a202268747470733a2f2f616e79626f647981526d0b9d1c9a599b194b9b1a5999488b60921b6020820152602e016d01130ba3a3934b13aba32b9911d160951b8152600e016107cb91610a8b565b607d60f81b81526001010383810182526107e59082610b52565b6107ee90610daf565b81517f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000602082015292908390603d820161082791610a8b565b0390810183526108379083610b52565b51610273819282610167565b6104a86104a2611a42565b610869913d8091833e6108618183610b52565b810190611188565b38610486565b6108776110de565b61047e565b90955061047294506108aa9193506000925060a03d81116108bb575b6108a28183610b52565b8101906110a7565b979096929591945090925090610451565b503d610898565b6108ca6110de565b610443565b503461000e576102736102676101ab36610120565b503461000e576102736102676108f936610120565b611338565b503461000e57602036600319011261000e5760043561091c816102a1565b610924610a33565b600180546001600160a01b0319166001600160a01b0392909216919091179055005b503461000e57602036600319011261000e5761027361026760043561197e565b503461000e57602036600319011261000e57600435610984816102a1565b61098c610a33565b6001600160a01b039081169081156109df57600080546001600160a01b031981168417825560405191939192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08484a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6000546001600160a01b03163303610a4757565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b90610a9e60209282815194859201610132565b0190565b50634e487b7160e01b600052604160045260246000fd5b60e0810190811067ffffffffffffffff821117610ad557604052565b610add610aa2565b604052565b60a0810190811067ffffffffffffffff821117610ad557604052565b6020810190811067ffffffffffffffff821117610ad557604052565b60c0810190811067ffffffffffffffff821117610ad557604052565b6040810190811067ffffffffffffffff821117610ad557604052565b90601f8019910116810190811067ffffffffffffffff821117610ad557604052565b60209067ffffffffffffffff8111610b92575b601f01601f19160190565b610b9a610aa2565b610b87565b60405190610bac82610afe565b60008252565b604051906060820182811067ffffffffffffffff821117610c23575b604052604082527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f6040837f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201520152565b610c2b610aa2565b610bce565b50634e487b7160e01b600052601160045260246000fd5b6001906001198111610c57570190565b610a9e610c30565b6002906002198111610c57570190565b6020906020198111610c57570190565b81198111610c57570190565b8115610c95570490565b634e487b7160e01b600052601260045260246000fd5b6001600160fe1b038111600116610cc3575b60021b90565b610ccb610c30565b610cbd565b806000190460041181151516610cc35760021b90565b7f028f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f8111600116610d17575b60640290565b610d1f610c30565b610d11565b8060001904821181151516610d37570290565b610d3f610c30565b0290565b604051906080820182811067ffffffffffffffff821117610d70575b604052604282526060366020840137565b610d78610aa2565b610d5f565b90610d8782610b74565b610d946040519182610b52565b8281528092610da5601f1991610b74565b0190602036910137565b805115610e8f57610dbe610bb2565b610dda610dd5610dce8451610c5f565b6003900490565b610cab565b91610dec610de784610c6f565b610d7d565b92835280815182019060208501935b828210610e3d57505050600390510680600114610e2c57600214610e1d575090565b603d60f81b6000199091015290565b50613d3d60f01b6001199091015290565b9091936004906003809401938451600190603f9082828260121c16880101518553828282600c1c16880101518386015382828260061c1688010151600286015316850101519082015301939190610dfb565b50610e98610b9f565b90565b610ea490611a83565b610e98602960405180936850726f626c656d202360b81b6020830152610ed38151809260208686019101610132565b8101036009810184520182610b52565b610e98610ff261105961108e9361104561102c610f08610f0284611338565b93610e9b565b6110266040519687957f3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d22757460208801527f662d38223f3e3c73766720786d6c6e733d22687474703a2f2f7777772e77332e60408801527f6f72672f323030302f7376672220206865696768743d2231303025222077696460608801527f74683d2231303025222076696577426f783d223020302031303030203130303060808801527f22207374796c653d226261636b67726f756e642d636f6c6f723a677265793b2260a08801526f1f1e39ba3cb6329f1e17b9ba3cb6329f60811b60c088015260d0870190610a8b565b7f3c7465787420783d2235302220793d223535302220636c6173733d226e616d65815261111f60f11b602082015260220190565b90610a8b565b6c1e17ba32bc3a1f1e17b9bb339f60991b8152600d0190565b0391610216601f1993848101835282610b52565b6040517f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000006020820152938491603a8301611026565b03908101835282610b52565b5190811515820361000e57565b908160a091031261000e5780516110bd816102a1565b916110ca6020830161109a565b916040810151916080606083015192015190565b506040513d6000823e3d90fd5b9080601f8301121561000e5760409182519261110684610b1a565b839261054083019281841161000e57935b83851061112657505050505090565b60e08583031261000e57825160e09161113e82610ab9565b8651825260209182880151838201528588015186820152606080890151908201526080808901519082015260a0808901519082015260c08089015190820152815201940193611117565b6020808284031261000e57815167ffffffffffffffff9283821161000e57019083601f8301121561000e57815192831161129f575b6040938451946111d2838660051b0187610b52565b84865282860191836106408097028601019481861161000e578401925b858410611200575050505050505090565b868483031261000e57825161121481610ae2565b61121d8561109a565b81528585015186820152838501518482015282607f8601121561000e57835161124581610ae2565b8061010087019185831161000e578a94928994928792606090818c01905b84821061128957505084015261127991906110eb565b60808201528152019301926111ef565b815181528f99508d988b96509182019101611263565b6112a7610aa2565b6111bd565b9081602091031261000e575190565b91906105608382031261000e576112d561054091846110eb565b92015190565b6001906000198114610c57570190565b50634e487b7160e01b600052603260045260246000fd5b906006811015611314575b60051b0190565b61131c6112eb565b61130d565b81811061132c570390565b611334610c30565b0390565b611340610b9f565b60015490919061135a9061040f906001600160a01b031681565b60408051632b99bd5f60e21b815260048101849052919260a09291908383602481885afa928315611971575b600093611946575b508151635e964aa960e11b8152600481019190915260008180602481015b0381885afa908115611939575b600091611920575b5051815190631da686ff60e31b825260209384836004818a5afa928315611913575b6000936118e4575b508351634dbe7f7360e01b81526004810191909152602481019190915294610560908190879060449082905afa9586156118d7575b60009182976118a3575b505094939291906000955b858710611446575050505050505090565b9091929394959682858961145a8186611302565b518981015161146890610cd0565b61147185610ce6565b61147a91610c7f565b6114848582610c8b565b61148d81611a83565b9561149791610d24565b6114a091611321565b6114a990611a83565b9083810191888351906114bb91610c8b565b92516114c78a85610d24565b6114d091611321565b926114da90611a83565b926114e490611a83565b928a519384918783016114f691610a8b565b601760f91b815260010161150991610a8b565b0395601f1996878101855261151e9085610b52565b8a8301928a84519061152f91610c8b565b935161153b8c86610d24565b61154491611321565b9361154e90611a83565b9361155890611a83565b938c5194859189830161156a91610a8b565b601760f91b815260010161157d91610a8b565b03888101855261158d9085610b52565b805161159890611a83565b908c5196878981016115c3906012907103a3930b739b337b93696b7b934b3b4b71d160751b81520190565b6115cd9089610a8b565b620383c160ed1b81526003016115e39088610a8b565b630383c1d960e51b8152600401038a810189526116009089610b52565b61160990611a83565b9060c001516116179061197e565b968d519a8b998a0161162891610a8b565b7f3c7374796c653e20406b65796672616d6573206d6f7665456c6c6970736500008152601e016116589084610a8b565b670103d901812903d960c51b81526008016116739082610a8b565b7f207472616e73666f726d3a20726f74617465283064656729207472616e736c6181527f7465283070782c2031307078293b207d2031303025207b20000000000000000060208201526038016116c891610a8b565b7f207472616e73666f726d3a20726f746174652833363064656729207472616e738152736c617465283070782c2031307078293b207d207d60601b60208201526034016a656c6c697073652369642d60a81b8152600b016117299083610a8b565b7f207b20616e696d6174696f6e3a206d6f7665456c6c697073650000000000000081526019016117599083610a8b565b7f20347320696e66696e697465206c696e6561723b20616e696d6174696f6e2d64815266656c61793a202d60c81b602082015260270161179891610a8b565b6b399d903e9e17b9ba3cb6329f60a11b8152600c016f3c656c6c697073652069643d2269642d60801b81526010016117cf91610a8b565b651110393c9e9160d11b81526006016117e89082610a8b565b601760f91b81526001016117fc9083610a8b565b651110393c1e9160d11b815260060161181491610a8b565b601760f91b815260010161182791610a8b565b65111031bc9e9160d11b815260060161183f91610a8b565b65111031bc1e9160d11b815260060161185791610a8b565b6711103334b6361e9160c11b815260080161187191610a8b565b631110179f60e11b815260040103908101825261188e9082610b52565b96611898906112db565b959493929190611435565b6118c793975080919250903d106118d0575b6118bf8183610b52565b8101906112bb565b9490388061142a565b503d6118b5565b6118df6110de565b611420565b611905919350853d871161190c575b6118fd8183610b52565b8101906112ac565b91386113eb565b503d6118f3565b61191b6110de565b6113e3565b611933913d8091833e6108618183610b52565b386113c1565b6119416110de565b6113b9565b6113ac919350611964600091863d88116108bb576108a28183610b52565b935050505093915061138e565b6119796110de565b611386565b610e98602591611a27611a1961ffff611026611a0b6119d060286119c9606482878b60201c16069683198811611a35575b6119be610168828d1606611a83565b9a60101c1606611a83565b9401611a83565b92604051988997630d0e6d8560e31b60208a01526119f881518092602060248d019101610132565b8801600b60fa1b60248201520190610a8b565b61094b60f21b815260020190565b61252960f01b815260020190565b03601f198101835282610b52565b611a3d610c30565b6119af565b60405190611a4f82610b36565b600582526466616c736560d81b6020830152565b60405190611a7082610b36565b60048252637472756560e01b6020830152565b806000917a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000080821015611bb8575b506d04ee2d6d415b85acef810000000080831015611ba9575b50662386f26fc1000080831015611b9a575b506305f5e10080831015611b8b575b5061271080831015611b7c575b506064821015611b6c575b600a80921015611b62575b600190816021611b1a828701610d7d565b95860101905b611b2c575b5050505090565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a835304918215611b5d57919082611b20565b611b25565b9160010191611b09565b9190606460029104910191611afe565b60049193920491019138611af3565b60089193920491019138611ae6565b60109193920491019138611ad7565b60209193920491019138611ac5565b604093508104915038611aac565b906020918051821015611bd857010190565b611be06112eb565b010190565b8015611bf3575b6000190190565b611bfb610c30565b611bec565b15611c0757565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b611c53610d43565b90815115611ced575b603060208301538151600190811015611ce0575b90607860218401536041915b808311611c8f5750610e98915015611c00565b9080600f611ccc92166010811015611cd3575b6f181899199a1a9b1b9c1cb0b131b232b360811b901a611cc28587611bc6565b5360041c92611be5565b9190611c7c565b611cdb6112eb565b611ca2565b611ce86112eb565b611c70565b611cf56112eb565b611c5c56fea2646970667358221220fe16a9ce4280f38425cd7bc130ceb940f6da0c75bc1abee450401af712731cdb64736f6c634300080f0033", - "deployedBytecode": "0x60806040526004361015610013575b600080fd5b60003560e01c8063102581d21461011757806319d4c3f91461010e5780635542437b146101055780636b8ff574146100fc578063715018a6146100f357806387b07780146100ea5780638da5cb5b146100e1578063a574cea4146100d8578063be985ac9146100cf578063e1765073146100c6578063e2ce81a5146100bd578063e82fedd7146100b45763f2fde38b146100ac57600080fd5b61000e610966565b5061000e610946565b5061000e6108fe565b5061000e6108e4565b5061000e6108cf565b5061000e6103ca565b5061000e6103a0565b5061000e610376565b5061000e610314565b5061000e6102fa565b5061000e6102b2565b5061000e610277565b5061000e610193565b602090600319011261000e5760043590565b918091926000905b82821061015257501161014b575050565b6000910152565b9150806020918301518186015201829161013a565b604091602082526101878151809281602086015260208686019101610132565b601f01601f1916010190565b503461000e5761027361021b6101b06101ab36610120565b610ee3565b61021660466040518093753c68746d6c3e3c626f64793e3c696d67207372633d2760501b60208301526101ed815180926020603686019101610132565b81016f139f1e17b137b23c9f1e17b43a36b61f60811b6036820152036026810184520182610b52565b610daf565b610267603660405180937519185d184e9d195e1d0bda1d1b5b0ed8985cd94d8d0b60521b60208301526102578151809260208686019101610132565b8101036016810184520182610b52565b60405191829182610167565b0390f35b503461000e57600036600319011261000e576001546040516001600160a01b039091168152602090f35b6001600160a01b0381160361000e57565b503461000e57602036600319011261000e576004356102d0816102a1565b6102d8610a33565b600280546001600160a01b0319166001600160a01b0392909216919091179055005b503461000e5761027361026761030f36610120565b610e9b565b503461000e576000806003193601126103735761032f610a33565b80546001600160a01b0319811682556040519082906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b80fd5b503461000e57600036600319011261000e576002546040516001600160a01b039091168152602090f35b503461000e57600036600319011261000e576000546040516001600160a01b039091168152602090f35b503461000e576103d936610120565b6103e281610e9b565b906103ec81610ee3565b6103f582610ee3565b60015490939061041b9061040f906001600160a01b031681565b6001600160a01b031690565b60408051632b99bd5f60e21b815260048101869052909460a082602481865afa9283156108c2575b60009182918394849661087c575b508851635e964aa960e11b8152600481019290925260009082908180602481015b03915afa90811561086f575b60009161084e575b505161049181610c47565b9215610843576104a86104a2611a63565b94611c4b565b946104b290611a83565b926104bc90611a83565b906104c690611a83565b916104d090611a83565b8851605b60f81b6020820152958695919491602187017f7b2274726169745f74797065223a22736f6c766564222c2276616c7565223a008152601f0161051591610a8b565b7f7d2c207b2274726169745f74797065223a2273656564222c2276616c7565223a8152601160f91b602082015260210161054e91610a8b565b7f227d2c207b2274726169745f74797065223a22646179222c2276616c7565223a8152601160f91b602082015260210161058791610a8b565b7f227d2c207b2274726169745f74797065223a22626f6479436f756e74222c227681526630b63ab2911d1160c91b60208201526027016105c691610a8b565b7f227d2c207b2274726169745f74797065223a226c6576656c222c2276616c7565815262111d1160e91b602082015260230161060191610a8b565b7f227d2c207b2274726169745f74797065223a22616363756d756c61746976655481526d34b6b29116113b30b63ab2911d1160911b6020820152602e0161064791610a8b565b62227d5d60e81b81526003010394601f199586810183526106689083610b52565b8451683d913730b6b2911d1160b91b60208201529384936029850161068c91610a8b565b61088b60f21b81526002017f226465736372697074696f6e223a2022416e79626f64792050726f626c656d2081527f2868747470733a2f2f616e79626f64792e747269666c652e6c69666529222c006020820152603f01691134b6b0b3b2911d101160b11b8152600a016106ff91610a8b565b61088b60f21b81526002016d1134b6b0b3b2afbab936111d101160911b8152600e0161072a91610a8b565b61088b60f21b81526002017f22686f6d655f75726c223a202268747470733a2f2f616e79626f64792e747269815269199b194b9b1a5999488b60b21b6020820152602a017f2265787465726e616c5f75726c223a202268747470733a2f2f616e79626f647981526d0b9d1c9a599b194b9b1a5999488b60921b6020820152602e016d01130ba3a3934b13aba32b9911d160951b8152600e016107cb91610a8b565b607d60f81b81526001010383810182526107e59082610b52565b6107ee90610daf565b81517f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000602082015292908390603d820161082791610a8b565b0390810183526108379083610b52565b51610273819282610167565b6104a86104a2611a42565b610869913d8091833e6108618183610b52565b810190611188565b38610486565b6108776110de565b61047e565b90955061047294506108aa9193506000925060a03d81116108bb575b6108a28183610b52565b8101906110a7565b979096929591945090925090610451565b503d610898565b6108ca6110de565b610443565b503461000e576102736102676101ab36610120565b503461000e576102736102676108f936610120565b611338565b503461000e57602036600319011261000e5760043561091c816102a1565b610924610a33565b600180546001600160a01b0319166001600160a01b0392909216919091179055005b503461000e57602036600319011261000e5761027361026760043561197e565b503461000e57602036600319011261000e57600435610984816102a1565b61098c610a33565b6001600160a01b039081169081156109df57600080546001600160a01b031981168417825560405191939192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08484a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6000546001600160a01b03163303610a4757565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b90610a9e60209282815194859201610132565b0190565b50634e487b7160e01b600052604160045260246000fd5b60e0810190811067ffffffffffffffff821117610ad557604052565b610add610aa2565b604052565b60a0810190811067ffffffffffffffff821117610ad557604052565b6020810190811067ffffffffffffffff821117610ad557604052565b60c0810190811067ffffffffffffffff821117610ad557604052565b6040810190811067ffffffffffffffff821117610ad557604052565b90601f8019910116810190811067ffffffffffffffff821117610ad557604052565b60209067ffffffffffffffff8111610b92575b601f01601f19160190565b610b9a610aa2565b610b87565b60405190610bac82610afe565b60008252565b604051906060820182811067ffffffffffffffff821117610c23575b604052604082527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f6040837f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201520152565b610c2b610aa2565b610bce565b50634e487b7160e01b600052601160045260246000fd5b6001906001198111610c57570190565b610a9e610c30565b6002906002198111610c57570190565b6020906020198111610c57570190565b81198111610c57570190565b8115610c95570490565b634e487b7160e01b600052601260045260246000fd5b6001600160fe1b038111600116610cc3575b60021b90565b610ccb610c30565b610cbd565b806000190460041181151516610cc35760021b90565b7f028f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f8111600116610d17575b60640290565b610d1f610c30565b610d11565b8060001904821181151516610d37570290565b610d3f610c30565b0290565b604051906080820182811067ffffffffffffffff821117610d70575b604052604282526060366020840137565b610d78610aa2565b610d5f565b90610d8782610b74565b610d946040519182610b52565b8281528092610da5601f1991610b74565b0190602036910137565b805115610e8f57610dbe610bb2565b610dda610dd5610dce8451610c5f565b6003900490565b610cab565b91610dec610de784610c6f565b610d7d565b92835280815182019060208501935b828210610e3d57505050600390510680600114610e2c57600214610e1d575090565b603d60f81b6000199091015290565b50613d3d60f01b6001199091015290565b9091936004906003809401938451600190603f9082828260121c16880101518553828282600c1c16880101518386015382828260061c1688010151600286015316850101519082015301939190610dfb565b50610e98610b9f565b90565b610ea490611a83565b610e98602960405180936850726f626c656d202360b81b6020830152610ed38151809260208686019101610132565b8101036009810184520182610b52565b610e98610ff261105961108e9361104561102c610f08610f0284611338565b93610e9b565b6110266040519687957f3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d22757460208801527f662d38223f3e3c73766720786d6c6e733d22687474703a2f2f7777772e77332e60408801527f6f72672f323030302f7376672220206865696768743d2231303025222077696460608801527f74683d2231303025222076696577426f783d223020302031303030203130303060808801527f22207374796c653d226261636b67726f756e642d636f6c6f723a677265793b2260a08801526f1f1e39ba3cb6329f1e17b9ba3cb6329f60811b60c088015260d0870190610a8b565b7f3c7465787420783d2235302220793d223535302220636c6173733d226e616d65815261111f60f11b602082015260220190565b90610a8b565b6c1e17ba32bc3a1f1e17b9bb339f60991b8152600d0190565b0391610216601f1993848101835282610b52565b6040517f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000006020820152938491603a8301611026565b03908101835282610b52565b5190811515820361000e57565b908160a091031261000e5780516110bd816102a1565b916110ca6020830161109a565b916040810151916080606083015192015190565b506040513d6000823e3d90fd5b9080601f8301121561000e5760409182519261110684610b1a565b839261054083019281841161000e57935b83851061112657505050505090565b60e08583031261000e57825160e09161113e82610ab9565b8651825260209182880151838201528588015186820152606080890151908201526080808901519082015260a0808901519082015260c08089015190820152815201940193611117565b6020808284031261000e57815167ffffffffffffffff9283821161000e57019083601f8301121561000e57815192831161129f575b6040938451946111d2838660051b0187610b52565b84865282860191836106408097028601019481861161000e578401925b858410611200575050505050505090565b868483031261000e57825161121481610ae2565b61121d8561109a565b81528585015186820152838501518482015282607f8601121561000e57835161124581610ae2565b8061010087019185831161000e578a94928994928792606090818c01905b84821061128957505084015261127991906110eb565b60808201528152019301926111ef565b815181528f99508d988b96509182019101611263565b6112a7610aa2565b6111bd565b9081602091031261000e575190565b91906105608382031261000e576112d561054091846110eb565b92015190565b6001906000198114610c57570190565b50634e487b7160e01b600052603260045260246000fd5b906006811015611314575b60051b0190565b61131c6112eb565b61130d565b81811061132c570390565b611334610c30565b0390565b611340610b9f565b60015490919061135a9061040f906001600160a01b031681565b60408051632b99bd5f60e21b815260048101849052919260a09291908383602481885afa928315611971575b600093611946575b508151635e964aa960e11b8152600481019190915260008180602481015b0381885afa908115611939575b600091611920575b5051815190631da686ff60e31b825260209384836004818a5afa928315611913575b6000936118e4575b508351634dbe7f7360e01b81526004810191909152602481019190915294610560908190879060449082905afa9586156118d7575b60009182976118a3575b505094939291906000955b858710611446575050505050505090565b9091929394959682858961145a8186611302565b518981015161146890610cd0565b61147185610ce6565b61147a91610c7f565b6114848582610c8b565b61148d81611a83565b9561149791610d24565b6114a091611321565b6114a990611a83565b9083810191888351906114bb91610c8b565b92516114c78a85610d24565b6114d091611321565b926114da90611a83565b926114e490611a83565b928a519384918783016114f691610a8b565b601760f91b815260010161150991610a8b565b0395601f1996878101855261151e9085610b52565b8a8301928a84519061152f91610c8b565b935161153b8c86610d24565b61154491611321565b9361154e90611a83565b9361155890611a83565b938c5194859189830161156a91610a8b565b601760f91b815260010161157d91610a8b565b03888101855261158d9085610b52565b805161159890611a83565b908c5196878981016115c3906012907103a3930b739b337b93696b7b934b3b4b71d160751b81520190565b6115cd9089610a8b565b620383c160ed1b81526003016115e39088610a8b565b630383c1d960e51b8152600401038a810189526116009089610b52565b61160990611a83565b9060c001516116179061197e565b968d519a8b998a0161162891610a8b565b7f3c7374796c653e20406b65796672616d6573206d6f7665456c6c6970736500008152601e016116589084610a8b565b670103d901812903d960c51b81526008016116739082610a8b565b7f207472616e73666f726d3a20726f74617465283064656729207472616e736c6181527f7465283070782c2031307078293b207d2031303025207b20000000000000000060208201526038016116c891610a8b565b7f207472616e73666f726d3a20726f746174652833363064656729207472616e738152736c617465283070782c2031307078293b207d207d60601b60208201526034016a656c6c697073652369642d60a81b8152600b016117299083610a8b565b7f207b20616e696d6174696f6e3a206d6f7665456c6c697073650000000000000081526019016117599083610a8b565b7f20347320696e66696e697465206c696e6561723b20616e696d6174696f6e2d64815266656c61793a202d60c81b602082015260270161179891610a8b565b6b399d903e9e17b9ba3cb6329f60a11b8152600c016f3c656c6c697073652069643d2269642d60801b81526010016117cf91610a8b565b651110393c9e9160d11b81526006016117e89082610a8b565b601760f91b81526001016117fc9083610a8b565b651110393c1e9160d11b815260060161181491610a8b565b601760f91b815260010161182791610a8b565b65111031bc9e9160d11b815260060161183f91610a8b565b65111031bc1e9160d11b815260060161185791610a8b565b6711103334b6361e9160c11b815260080161187191610a8b565b631110179f60e11b815260040103908101825261188e9082610b52565b96611898906112db565b959493929190611435565b6118c793975080919250903d106118d0575b6118bf8183610b52565b8101906112bb565b9490388061142a565b503d6118b5565b6118df6110de565b611420565b611905919350853d871161190c575b6118fd8183610b52565b8101906112ac565b91386113eb565b503d6118f3565b61191b6110de565b6113e3565b611933913d8091833e6108618183610b52565b386113c1565b6119416110de565b6113b9565b6113ac919350611964600091863d88116108bb576108a28183610b52565b935050505093915061138e565b6119796110de565b611386565b610e98602591611a27611a1961ffff611026611a0b6119d060286119c9606482878b60201c16069683198811611a35575b6119be610168828d1606611a83565b9a60101c1606611a83565b9401611a83565b92604051988997630d0e6d8560e31b60208a01526119f881518092602060248d019101610132565b8801600b60fa1b60248201520190610a8b565b61094b60f21b815260020190565b61252960f01b815260020190565b03601f198101835282610b52565b611a3d610c30565b6119af565b60405190611a4f82610b36565b600582526466616c736560d81b6020830152565b60405190611a7082610b36565b60048252637472756560e01b6020830152565b806000917a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000080821015611bb8575b506d04ee2d6d415b85acef810000000080831015611ba9575b50662386f26fc1000080831015611b9a575b506305f5e10080831015611b8b575b5061271080831015611b7c575b506064821015611b6c575b600a80921015611b62575b600190816021611b1a828701610d7d565b95860101905b611b2c575b5050505090565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a835304918215611b5d57919082611b20565b611b25565b9160010191611b09565b9190606460029104910191611afe565b60049193920491019138611af3565b60089193920491019138611ae6565b60109193920491019138611ad7565b60209193920491019138611ac5565b604093508104915038611aac565b906020918051821015611bd857010190565b611be06112eb565b010190565b8015611bf3575b6000190190565b611bfb610c30565b611bec565b15611c0757565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b611c53610d43565b90815115611ced575b603060208301538151600190811015611ce0575b90607860218401536041915b808311611c8f5750610e98915015611c00565b9080600f611ccc92166010811015611cd3575b6f181899199a1a9b1b9c1cb0b131b232b360811b901a611cc28587611bc6565b5360041c92611be5565b9190611c7c565b611cdb6112eb565b611ca2565b611ce86112eb565b611c70565b611cf56112eb565b611c5c56fea2646970667358221220fe16a9ce4280f38425cd7bc130ceb940f6da0c75bc1abee450401af712731cdb64736f6c634300080f0033", + "bytecode": "0x6080806040523461005b5760008054336001600160a01b0319821681178355916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09084a361233990816100618239f35b600080fdfe60806040526004361015610013575b600080fd5b60003560e01c8063102581d21461011757806319d4c3f91461010e5780635542437b146101055780636b8ff574146100fc578063715018a6146100f357806387b07780146100ea5780638da5cb5b146100e1578063a574cea4146100d8578063be985ac9146100cf578063e1765073146100c6578063e2ce81a5146100bd578063e82fedd7146100b45763f2fde38b146100ac57600080fd5b61000e610c39565b5061000e610c19565b5061000e610bd1565b5061000e610bb7565b5061000e610ba2565b5061000e6103ca565b5061000e6103a0565b5061000e610376565b5061000e610314565b5061000e6102fa565b5061000e6102b2565b5061000e610277565b5061000e610193565b602090600319011261000e5760043590565b918091926000905b82821061015257501161014b575050565b6000910152565b9150806020918301518186015201829161013a565b604091602082526101878151809281602086015260208686019101610132565b601f01601f1916010190565b503461000e5761027361021b6101b06101ab36610120565b611729565b61021660466040518093753c68746d6c3e3c626f64793e3c696d67207372633d2760501b60208301526101ed815180926020603686019101610132565b81016f139f1e17b137b23c9f1e17b43a36b61f60811b6036820152036026810184520182610e09565b610ffd565b610267603660405180937519185d184e9d195e1d0bda1d1b5b0ed8985cd94d8d0b60521b60208301526102578151809260208686019101610132565b8101036016810184520182610e09565b60405191829182610167565b0390f35b503461000e57600036600319011261000e576001546040516001600160a01b039091168152602090f35b6001600160a01b0381160361000e57565b503461000e57602036600319011261000e576004356102d0816102a1565b6102d8610d06565b600280546001600160a01b0319166001600160a01b0392909216919091179055005b503461000e5761027361026761030f36610120565b6110e9565b503461000e576000806003193601126103735761032f610d06565b80546001600160a01b0319811682556040519082906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b80fd5b503461000e57600036600319011261000e576002546040516001600160a01b039091168152602090f35b503461000e57600036600319011261000e576000546040516001600160a01b039091168152602090f35b503461000e576103d936610120565b6103e2816110e9565b6103eb82611729565b6103f483611729565b906103fe8461117b565b6001546040805160016228c2c560e01b031980825260048083018c90526000602484015260209b939a9795968c968c966001600160a01b031695929487949093909290919089856044818b5afa928a8415996105309761055e9b610b95575b600096610b76575b50898951978089528a848a8061048b898783016020600191939293604081019481520152565b0381875afa998a15610b69575b60009a610b35575b505190815290810184815260026020820152610500939291908390829081906040015b0381855afa928315610b28575b600093610af9575b50508951632b99bd5f60e21b8082528c820198895260a09c91988d9586918b91829160200190565b0381865afa998a15610aec575b6000998a9b610ac3575b5085908d51809d81928583528683019190602083019252565b0381865afa9b8c15610ab6575b60009b8c9d610a8d575b50519d8e9485938493845283019190602083019252565b03915afa988915610a80575b600098899a610a45575b505061057f906120c3565b9a610589906120c3565b90610593906120c3565b9161059d906120c3565b926105a790612206565b936105b1906120c3565b946105bb90612206565b956105c5906120c3565b966105cf90612206565b976105d9906120c3565b9851605b60f81b9a81019a8b529a8b9a6001017f7b2274726169745f74797065223a2264617465222c2276616c7565223a2200008152601e0161061b91610d5e565b7f227d2c207b2274726169745f74797065223a22646179222c2276616c7565223a8152601160f91b602082015260210161065491610d5e565b7f227d2c207b2274726169745f74797065223a226d6f6e7468222c2276616c7565815262111d1160e91b602082015260230161068f91610d5e565b7f227d2c207b2274726169745f74797065223a2279656172222c2276616c7565228152611d1160f11b60208201526022016106c991610d5e565b7f227d2c207b2274726169745f74797065223a223173742d61646472657373222c815268113b30b63ab2911d1160b91b602082015260290161070a91610d5e565b7f227d2c207b2274726169745f74797065223a223173742d74696d65222c227661815265363ab2911d1160d11b602082015260260161074891610d5e565b7f227d2c207b2274726169745f74797065223a22326e642d61646472657373222c815268113b30b63ab2911d1160b91b602082015260290161078991610d5e565b7f227d2c207b2274726169745f74797065223a22326e642d74696d65222c227661815265363ab2911d1160d11b60208201526026016107c791610d5e565b7f227d2c207b2274726169745f74797065223a223372642d61646472657373222c815268113b30b63ab2911d1160b91b602082015260290161080891610d5e565b7f227d2c207b2274726169745f74797065223a223372642d74696d65222c227661815265363ab2911d1160d11b602082015260260161084691610d5e565b62227d5d60e81b81526003010393601f199485810183526108679083610e09565b8551683d913730b6b2911d1160b91b88820190815290948594909160090161088e91610d5e565b61088b60f21b81526002017f226465736372697074696f6e223a2022416e79626f64792050726f626c656d2081527f2868747470733a2f2f616e79626f64792e747269666c652e6c69666529222c006020820152603f01691134b6b0b3b2911d101160b11b8152600a0161090191610d5e565b61088b60f21b81526002016d1134b6b0b3b2afbab936111d101160911b8152600e0161092c91610d5e565b61088b60f21b81526002017f22686f6d655f75726c223a202268747470733a2f2f616e79626f64792e747269815269199b194b9b1a5999488b60b21b6020820152602a017f2265787465726e616c5f75726c223a202268747470733a2f2f616e79626f647981526d0b9d1c9a599b194b9b1a5999488b60921b6020820152602e016d01130ba3a3934b13aba32b9911d160951b8152600e016109cd91610d5e565b607d60f81b81526001010382810182526109e79082610e09565b6109f090610ffd565b82517f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000094810194855293849190601d01610a2991610d5e565b039081018352610a399083610e09565b51610273819282610167565b610a6a929a5061057f9950803d10610a79575b610a628183610e09565b81019061208a565b50509891905097989038610574565b503d610a58565b610a886118ef565b61056a565b909c50610aa8919b50853d8711610a7957610a628183610e09565b50509b9190509a9b38610547565b610abe6118ef565b61053d565b610ade919b5086809b503d8811610a7957610a628183610e09565b50509a919050999a90610517565b610af46118ef565b61050d565b610b19929350803d10610b21575b610b118183610e09565b8101906118e0565b90388e6104d8565b503d610b07565b610b306118ef565b6104d0565b8594939085929b50926104c3610b5b8995610500993d8711610b2157610b118183610e09565b9c93505092509293946104a0565b610b716118ef565b610498565b610b8e919650823d8411610b2157610b118183610e09565b9438610465565b610b9d6118ef565b61045d565b503461000e576102736102676101ab36610120565b503461000e57610273610267610bcc36610120565b6119f6565b503461000e57602036600319011261000e57600435610bef816102a1565b610bf7610d06565b600180546001600160a01b0319166001600160a01b0392909216919091179055005b503461000e57602036600319011261000e57610273610267600435611fc6565b503461000e57602036600319011261000e57600435610c57816102a1565b610c5f610d06565b6001600160a01b03908116908115610cb257600080546001600160a01b031981168417825560405191939192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08484a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6000546001600160a01b03163303610d1a57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b90610d7160209282815194859201610132565b0190565b50634e487b7160e01b600052604160045260246000fd5b60c0810190811067ffffffffffffffff821117610da857604052565b610db0610d75565b604052565b60e0810190811067ffffffffffffffff821117610da857604052565b6020810190811067ffffffffffffffff821117610da857604052565b6060810190811067ffffffffffffffff821117610da857604052565b90601f8019910116810190811067ffffffffffffffff821117610da857604052565b60209067ffffffffffffffff8111610e49575b601f01601f19160190565b610e51610d75565b610e3e565b60405190610e6382610dd1565b60008252565b60405190610e7682610ded565b604082527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f6040837f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201520152565b50634e487b7160e01b600052601160045260246000fd5b6002906002198111610eef570190565b610d71610ec8565b6020906020198111610eef570190565b81198111610eef570190565b8115610f1d570490565b634e487b7160e01b600052601260045260246000fd5b6001600160fe1b038111600116610f4b575b60021b90565b610f53610ec8565b610f45565b806000190460041181151516610f4b5760021b90565b7f028f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f8111600116610f9f575b60640290565b610fa7610ec8565b610f99565b8060001904821181151516610fbf570290565b610fc7610ec8565b0290565b90610fd582610e2b565b610fe26040519182610e09565b8281528092610ff3601f1991610e2b565b0190602036910137565b8051156110dd5761100c610e69565b61102861102361101c8451610edf565b6003900490565b610f33565b9161103a61103584610ef7565b610fcb565b92835280815182019060208501935b82821061108b5750505060039051068060011461107a5760021461106b575090565b603d60f81b6000199091015290565b50613d3d60f01b6001199091015290565b9091936004906003809401938451600190603f9082828260121c16880101518553828282600c1c16880101518386015382828260061c1688010151600286015316850101519082015301939190611049565b506110e6610e56565b90565b6110e6602261110a6111166111006111109561117b565b96919390936120c3565b926120c3565b946120c3565b604051948261112f879451809260208088019101610132565b830190602d60f81b91826020820152611152825180936020602185019101610132565b0190602182015261116c8251809360208785019101610132565b01036002810184520182610e09565b6111b99062010bd9906201518090046000811280156001600160ff1b0383900384131661129d575b600160ff1b829003831216611290575b016112aa565b6111f36111d16111c8836113d7565b62023ab1900590565b916111ed6111e66111e185611418565b6112e8565b6004900590565b906116e6565b9061128a61122c61122761121a61121161120c87611316565b611476565b62164b09900590565b946111ed6111e6876114d3565b611350565b61128561125a61124661123e84611530565b61098f900590565b926111ed6112538561159b565b6050900590565b9461128561128061127a611271600b87059661137e565b6111ed876115f8565b966116c0565b611663565b6113ac565b91909192565b611298610ec8565b6111b3565b6112a5610ec8565b6111a3565b62253d8c906000811280156001600160ff1b038390038413166112db575b600160ff1b829003831216610eef570190565b6112e3610ec8565b6112c8565b6003906000811280156001600160ff1b038390038413166112db57600160ff1b829003831216610eef570190565b6001906000811280156001600160ff1b03839003841316611343575b818360ff1b03831216610eef570190565b61134b610ec8565b611332565b601f906000811280156001600160ff1b038390038413166112db57600160ff1b829003831216610eef570190565b6002906000811280156001600160ff1b038390038413166112db57600160ff1b829003831216610eef570190565b6000811280156001600160ff1b038390038413166112db57600160ff1b829003831216610eef570190565b600081136001600160ff1b038290046004111660011661140b575b60008112600760fd1b821216600116610f4b5760021b90565b611413610ec8565b6113f2565b62023ab1600082136001600160ff1b03839004821116600116611469575b60017fffffc694f94337079d130ab45dff8e0f9ea161331bb1c93dea871de6fec83ce28312600084121616610fbf570290565b611471610ec8565b611436565b610fa0600082136001600160ff1b038390048211166001166114c6575b60017ffff7ced916872b020c49ba5e353f7ced916872b020c49ba5e353f7ced916872c8312600084121616610fbf570290565b6114ce610ec8565b611493565b6105b5600082136001600160ff1b03839004821116600116611523575b60017fffe9924f8d0dd7b2e6f174df9576f9de01c091c8faeb2605f522de8852b47aa88312600084121616610fbf570290565b61152b610ec8565b6114f0565b600081136001600160ff1b038290046050111660011661158e575b60017ffe666666666666666666666666666666666666666666666666666666666666678212600083121616611581575b60500290565b611589610ec8565b61157b565b611596610ec8565b61154b565b61098f600082136001600160ff1b038390048211166001166115eb575b60017ffff29be1739a4fb805dbcd5d6c7d1f7d6fd627208942391f124ee1c3f30702688312600084121616610fbf570290565b6115f3610ec8565b6115b8565b600081136001600160ff1b03829004600c1116600116611656575b60017ff5555555555555555555555555555555555555555555555555555555555555568212600083121616611649575b600c0290565b611651610ec8565b611643565b61165e610ec8565b611613565b600081136001600160ff1b03829004606411166001166116b3575b60017ffeb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb98212600083121616610f9f5760640290565b6116bb610ec8565b61167e565b6031600160ff1b0181126001166116d9575b6030190190565b6116e1610ec8565b6116d2565b600082128015600160ff1b840183121661171c575b6001600160ff1b038301821316611710570390565b611718610ec8565b0390565b611724610ec8565b6116fb565b6110e661183861189f6118d49361188b61187261174e611748846119f6565b936110e9565b61186c6040519687957f3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d22757460208801527f662d38223f3e3c73766720786d6c6e733d22687474703a2f2f7777772e77332e60408801527f6f72672f323030302f7376672220206865696768743d2231303025222077696460608801527f74683d2231303025222076696577426f783d223020302031303030203130303060808801527f22207374796c653d226261636b67726f756e642d636f6c6f723a677265793b2260a08801526f1f1e39ba3cb6329f1e17b9ba3cb6329f60811b60c088015260d0870190610d5e565b7f3c7465787420783d2235302220793d223535302220636c6173733d226e616d65815261111f60f11b602082015260220190565b90610d5e565b6c1e17ba32bc3a1f1e17b9bb339f60991b8152600d0190565b0391610216601f1993848101835282610e09565b6040517f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000006020820152938491603a830161186c565b03908101835282610e09565b9081602091031261000e575190565b506040513d6000823e3d90fd5b91906105608382031261000e5780601f8401121561000e57604080519161192283610d8c565b829161054086019582871161000e57925b8684106119435750505050915190565b60e08484031261000e57815160e09161195b82610db5565b8551825260209182870151838201528487015185820152606080880151908201526080808801519082015260a0808801519082015260c08088015190820152815201930192611933565b6001906000198114610eef570190565b50634e487b7160e01b600052603260045260246000fd5b9060068110156119de575b60051b0190565b6119e66119b5565b6119d7565b818110611710570390565b6119fe610e56565b600154909190611a2490611a18906001600160a01b031681565b6001600160a01b031690565b60408051631da686ff60e31b81529192602091908284600481885afa938415611fb9575b600094611f9a575b5081516338ab6ea360e21b8152908382600481895afa918215611f8d575b600092611f6e575b508251634dbe7f7360e01b81526004810191909152602481019190915293610560908190869060449082905afa948515611f61575b6000918296611f2d575b5050939291906000945b848610611acf5750505050505090565b909192939495848488611ae281866119cc565b5160a0810151611af190610f58565b611afa85610f6e565b611b0391610f07565b611b0d8582610f13565b611b16816120c3565b95611b2091610fac565b611b29916119eb565b611b32906120c3565b90838101918a835190611b4491610f13565b9251611b508c85610fac565b611b59916119eb565b92611b63906120c3565b92611b6d906120c3565b928951938491878301611b7f91610d5e565b601760f91b8152600101611b9291610d5e565b0395601f19968781018552611ba79085610e09565b898301928c80855190611bb991610f13565b945190611bc69086610fac565b611bcf916119eb565b93611bd9906120c3565b93611be3906120c3565b938b51948591898301611bf591610d5e565b601760f91b8152600101611c0891610d5e565b038881018552611c189085610e09565b8051611c23906120c3565b908b519687898101611c4e906012907103a3930b739b337b93696b7b934b3b4b71d160751b81520190565b611c589089610d5e565b620383c160ed1b8152600301611c6e9088610d5e565b630383c1d960e51b8152600401038a81018952611c8b9089610e09565b611c94906120c3565b9060c00151611ca290611fc6565b968c519a8b998a01611cb391610d5e565b7f3c7374796c653e20406b65796672616d6573206d6f7665456c6c6970736500008152601e01611ce39084610d5e565b670103d901812903d960c51b8152600801611cfe9082610d5e565b7f207472616e73666f726d3a20726f74617465283064656729207472616e736c6181527f7465283070782c2031307078293b207d2031303025207b2000000000000000006020820152603801611d5391610d5e565b7f207472616e73666f726d3a20726f746174652833363064656729207472616e738152736c617465283070782c2031307078293b207d207d60601b60208201526034016a656c6c697073652369642d60a81b8152600b01611db49083610d5e565b7f207b20616e696d6174696f6e3a206d6f7665456c6c69707365000000000000008152601901611de49083610d5e565b7f20347320696e66696e697465206c696e6561723b20616e696d6174696f6e2d64815266656c61793a202d60c81b6020820152602701611e2391610d5e565b6b399d903e9e17b9ba3cb6329f60a11b8152600c016f3c656c6c697073652069643d2269642d60801b8152601001611e5a91610d5e565b651110393c9e9160d11b8152600601611e739082610d5e565b601760f91b8152600101611e879083610d5e565b651110393c1e9160d11b8152600601611e9f91610d5e565b601760f91b8152600101611eb291610d5e565b65111031bc9e9160d11b8152600601611eca91610d5e565b65111031bc1e9160d11b8152600601611ee291610d5e565b6711103334b6361e9160c11b8152600801611efc91610d5e565b631110179f60e11b8152600401039081018252611f199082610e09565b95611f23906119a5565b9493929190611abf565b611f5193965080919250903d10611f5a575b611f498183610e09565b8101906118fc565b93903880611ab5565b503d611f3f565b611f696118ef565b611aab565b611f86919250843d8611610b2157610b118183610e09565b9038611a76565b611f956118ef565b611a6e565b611fb2919450833d8511610b2157610b118183610e09565b9238611a50565b611fc16118ef565b611a48565b6110e660259161206f61206161ffff61186c6120536120186028612011606482878b60201c1606968319881161207d575b612006610168828d16066120c3565b9a60101c16066120c3565b94016120c3565b92604051988997630d0e6d8560e31b60208a015261204081518092602060248d019101610132565b8801600b60fa1b60248201520190610d5e565b61094b60f21b815260020190565b61252960f01b815260020190565b03601f198101835282610e09565b612085610ec8565b611ff7565b908160a091031261000e5780516120a0816102a1565b916020820151801515810361000e57916040810151916080606083015192015190565b806000917a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000808210156121f8575b506d04ee2d6d415b85acef8100000000808310156121e9575b50662386f26fc10000808310156121da575b506305f5e100808310156121cb575b50612710808310156121bc575b5060648210156121ac575b600a809210156121a2575b60019081602161215a828701610fcb565b95860101905b61216c575b5050505090565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a83530491821561219d57919082612160565b612165565b9160010191612149565b919060646002910491019161213e565b60049193920491019138612133565b60089193920491019138612126565b60109193920491019138612117565b60209193920491019138612105565b6040935081049150386120ec565b60018060a01b03169060405161221b81610ded565b602881526020926040368584013760275b600081121561224357506110e691929350156122b8565b90600f811660108110156122ab575b835183101561229e575b6f181899199a1a9b1b9c1cb0b131b232b360811b901a83830186015360041c90600160ff1b8114612291575b6000190161222c565b612299610ec8565b612288565b6122a66119b5565b61225c565b6122b36119b5565b612252565b156122bf57565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fdfea2646970667358221220444443809fab30a64ba32a238e763f1615be64c3bd7e571579a2c8ad704a04d164736f6c634300080f0033", + "deployedBytecode": "0x60806040526004361015610013575b600080fd5b60003560e01c8063102581d21461011757806319d4c3f91461010e5780635542437b146101055780636b8ff574146100fc578063715018a6146100f357806387b07780146100ea5780638da5cb5b146100e1578063a574cea4146100d8578063be985ac9146100cf578063e1765073146100c6578063e2ce81a5146100bd578063e82fedd7146100b45763f2fde38b146100ac57600080fd5b61000e610c39565b5061000e610c19565b5061000e610bd1565b5061000e610bb7565b5061000e610ba2565b5061000e6103ca565b5061000e6103a0565b5061000e610376565b5061000e610314565b5061000e6102fa565b5061000e6102b2565b5061000e610277565b5061000e610193565b602090600319011261000e5760043590565b918091926000905b82821061015257501161014b575050565b6000910152565b9150806020918301518186015201829161013a565b604091602082526101878151809281602086015260208686019101610132565b601f01601f1916010190565b503461000e5761027361021b6101b06101ab36610120565b611729565b61021660466040518093753c68746d6c3e3c626f64793e3c696d67207372633d2760501b60208301526101ed815180926020603686019101610132565b81016f139f1e17b137b23c9f1e17b43a36b61f60811b6036820152036026810184520182610e09565b610ffd565b610267603660405180937519185d184e9d195e1d0bda1d1b5b0ed8985cd94d8d0b60521b60208301526102578151809260208686019101610132565b8101036016810184520182610e09565b60405191829182610167565b0390f35b503461000e57600036600319011261000e576001546040516001600160a01b039091168152602090f35b6001600160a01b0381160361000e57565b503461000e57602036600319011261000e576004356102d0816102a1565b6102d8610d06565b600280546001600160a01b0319166001600160a01b0392909216919091179055005b503461000e5761027361026761030f36610120565b6110e9565b503461000e576000806003193601126103735761032f610d06565b80546001600160a01b0319811682556040519082906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b80fd5b503461000e57600036600319011261000e576002546040516001600160a01b039091168152602090f35b503461000e57600036600319011261000e576000546040516001600160a01b039091168152602090f35b503461000e576103d936610120565b6103e2816110e9565b6103eb82611729565b6103f483611729565b906103fe8461117b565b6001546040805160016228c2c560e01b031980825260048083018c90526000602484015260209b939a9795968c968c966001600160a01b031695929487949093909290919089856044818b5afa928a8415996105309761055e9b610b95575b600096610b76575b50898951978089528a848a8061048b898783016020600191939293604081019481520152565b0381875afa998a15610b69575b60009a610b35575b505190815290810184815260026020820152610500939291908390829081906040015b0381855afa928315610b28575b600093610af9575b50508951632b99bd5f60e21b8082528c820198895260a09c91988d9586918b91829160200190565b0381865afa998a15610aec575b6000998a9b610ac3575b5085908d51809d81928583528683019190602083019252565b0381865afa9b8c15610ab6575b60009b8c9d610a8d575b50519d8e9485938493845283019190602083019252565b03915afa988915610a80575b600098899a610a45575b505061057f906120c3565b9a610589906120c3565b90610593906120c3565b9161059d906120c3565b926105a790612206565b936105b1906120c3565b946105bb90612206565b956105c5906120c3565b966105cf90612206565b976105d9906120c3565b9851605b60f81b9a81019a8b529a8b9a6001017f7b2274726169745f74797065223a2264617465222c2276616c7565223a2200008152601e0161061b91610d5e565b7f227d2c207b2274726169745f74797065223a22646179222c2276616c7565223a8152601160f91b602082015260210161065491610d5e565b7f227d2c207b2274726169745f74797065223a226d6f6e7468222c2276616c7565815262111d1160e91b602082015260230161068f91610d5e565b7f227d2c207b2274726169745f74797065223a2279656172222c2276616c7565228152611d1160f11b60208201526022016106c991610d5e565b7f227d2c207b2274726169745f74797065223a223173742d61646472657373222c815268113b30b63ab2911d1160b91b602082015260290161070a91610d5e565b7f227d2c207b2274726169745f74797065223a223173742d74696d65222c227661815265363ab2911d1160d11b602082015260260161074891610d5e565b7f227d2c207b2274726169745f74797065223a22326e642d61646472657373222c815268113b30b63ab2911d1160b91b602082015260290161078991610d5e565b7f227d2c207b2274726169745f74797065223a22326e642d74696d65222c227661815265363ab2911d1160d11b60208201526026016107c791610d5e565b7f227d2c207b2274726169745f74797065223a223372642d61646472657373222c815268113b30b63ab2911d1160b91b602082015260290161080891610d5e565b7f227d2c207b2274726169745f74797065223a223372642d74696d65222c227661815265363ab2911d1160d11b602082015260260161084691610d5e565b62227d5d60e81b81526003010393601f199485810183526108679083610e09565b8551683d913730b6b2911d1160b91b88820190815290948594909160090161088e91610d5e565b61088b60f21b81526002017f226465736372697074696f6e223a2022416e79626f64792050726f626c656d2081527f2868747470733a2f2f616e79626f64792e747269666c652e6c69666529222c006020820152603f01691134b6b0b3b2911d101160b11b8152600a0161090191610d5e565b61088b60f21b81526002016d1134b6b0b3b2afbab936111d101160911b8152600e0161092c91610d5e565b61088b60f21b81526002017f22686f6d655f75726c223a202268747470733a2f2f616e79626f64792e747269815269199b194b9b1a5999488b60b21b6020820152602a017f2265787465726e616c5f75726c223a202268747470733a2f2f616e79626f647981526d0b9d1c9a599b194b9b1a5999488b60921b6020820152602e016d01130ba3a3934b13aba32b9911d160951b8152600e016109cd91610d5e565b607d60f81b81526001010382810182526109e79082610e09565b6109f090610ffd565b82517f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000094810194855293849190601d01610a2991610d5e565b039081018352610a399083610e09565b51610273819282610167565b610a6a929a5061057f9950803d10610a79575b610a628183610e09565b81019061208a565b50509891905097989038610574565b503d610a58565b610a886118ef565b61056a565b909c50610aa8919b50853d8711610a7957610a628183610e09565b50509b9190509a9b38610547565b610abe6118ef565b61053d565b610ade919b5086809b503d8811610a7957610a628183610e09565b50509a919050999a90610517565b610af46118ef565b61050d565b610b19929350803d10610b21575b610b118183610e09565b8101906118e0565b90388e6104d8565b503d610b07565b610b306118ef565b6104d0565b8594939085929b50926104c3610b5b8995610500993d8711610b2157610b118183610e09565b9c93505092509293946104a0565b610b716118ef565b610498565b610b8e919650823d8411610b2157610b118183610e09565b9438610465565b610b9d6118ef565b61045d565b503461000e576102736102676101ab36610120565b503461000e57610273610267610bcc36610120565b6119f6565b503461000e57602036600319011261000e57600435610bef816102a1565b610bf7610d06565b600180546001600160a01b0319166001600160a01b0392909216919091179055005b503461000e57602036600319011261000e57610273610267600435611fc6565b503461000e57602036600319011261000e57600435610c57816102a1565b610c5f610d06565b6001600160a01b03908116908115610cb257600080546001600160a01b031981168417825560405191939192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08484a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6000546001600160a01b03163303610d1a57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b90610d7160209282815194859201610132565b0190565b50634e487b7160e01b600052604160045260246000fd5b60c0810190811067ffffffffffffffff821117610da857604052565b610db0610d75565b604052565b60e0810190811067ffffffffffffffff821117610da857604052565b6020810190811067ffffffffffffffff821117610da857604052565b6060810190811067ffffffffffffffff821117610da857604052565b90601f8019910116810190811067ffffffffffffffff821117610da857604052565b60209067ffffffffffffffff8111610e49575b601f01601f19160190565b610e51610d75565b610e3e565b60405190610e6382610dd1565b60008252565b60405190610e7682610ded565b604082527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f6040837f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201520152565b50634e487b7160e01b600052601160045260246000fd5b6002906002198111610eef570190565b610d71610ec8565b6020906020198111610eef570190565b81198111610eef570190565b8115610f1d570490565b634e487b7160e01b600052601260045260246000fd5b6001600160fe1b038111600116610f4b575b60021b90565b610f53610ec8565b610f45565b806000190460041181151516610f4b5760021b90565b7f028f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f8111600116610f9f575b60640290565b610fa7610ec8565b610f99565b8060001904821181151516610fbf570290565b610fc7610ec8565b0290565b90610fd582610e2b565b610fe26040519182610e09565b8281528092610ff3601f1991610e2b565b0190602036910137565b8051156110dd5761100c610e69565b61102861102361101c8451610edf565b6003900490565b610f33565b9161103a61103584610ef7565b610fcb565b92835280815182019060208501935b82821061108b5750505060039051068060011461107a5760021461106b575090565b603d60f81b6000199091015290565b50613d3d60f01b6001199091015290565b9091936004906003809401938451600190603f9082828260121c16880101518553828282600c1c16880101518386015382828260061c1688010151600286015316850101519082015301939190611049565b506110e6610e56565b90565b6110e6602261110a6111166111006111109561117b565b96919390936120c3565b926120c3565b946120c3565b604051948261112f879451809260208088019101610132565b830190602d60f81b91826020820152611152825180936020602185019101610132565b0190602182015261116c8251809360208785019101610132565b01036002810184520182610e09565b6111b99062010bd9906201518090046000811280156001600160ff1b0383900384131661129d575b600160ff1b829003831216611290575b016112aa565b6111f36111d16111c8836113d7565b62023ab1900590565b916111ed6111e66111e185611418565b6112e8565b6004900590565b906116e6565b9061128a61122c61122761121a61121161120c87611316565b611476565b62164b09900590565b946111ed6111e6876114d3565b611350565b61128561125a61124661123e84611530565b61098f900590565b926111ed6112538561159b565b6050900590565b9461128561128061127a611271600b87059661137e565b6111ed876115f8565b966116c0565b611663565b6113ac565b91909192565b611298610ec8565b6111b3565b6112a5610ec8565b6111a3565b62253d8c906000811280156001600160ff1b038390038413166112db575b600160ff1b829003831216610eef570190565b6112e3610ec8565b6112c8565b6003906000811280156001600160ff1b038390038413166112db57600160ff1b829003831216610eef570190565b6001906000811280156001600160ff1b03839003841316611343575b818360ff1b03831216610eef570190565b61134b610ec8565b611332565b601f906000811280156001600160ff1b038390038413166112db57600160ff1b829003831216610eef570190565b6002906000811280156001600160ff1b038390038413166112db57600160ff1b829003831216610eef570190565b6000811280156001600160ff1b038390038413166112db57600160ff1b829003831216610eef570190565b600081136001600160ff1b038290046004111660011661140b575b60008112600760fd1b821216600116610f4b5760021b90565b611413610ec8565b6113f2565b62023ab1600082136001600160ff1b03839004821116600116611469575b60017fffffc694f94337079d130ab45dff8e0f9ea161331bb1c93dea871de6fec83ce28312600084121616610fbf570290565b611471610ec8565b611436565b610fa0600082136001600160ff1b038390048211166001166114c6575b60017ffff7ced916872b020c49ba5e353f7ced916872b020c49ba5e353f7ced916872c8312600084121616610fbf570290565b6114ce610ec8565b611493565b6105b5600082136001600160ff1b03839004821116600116611523575b60017fffe9924f8d0dd7b2e6f174df9576f9de01c091c8faeb2605f522de8852b47aa88312600084121616610fbf570290565b61152b610ec8565b6114f0565b600081136001600160ff1b038290046050111660011661158e575b60017ffe666666666666666666666666666666666666666666666666666666666666678212600083121616611581575b60500290565b611589610ec8565b61157b565b611596610ec8565b61154b565b61098f600082136001600160ff1b038390048211166001166115eb575b60017ffff29be1739a4fb805dbcd5d6c7d1f7d6fd627208942391f124ee1c3f30702688312600084121616610fbf570290565b6115f3610ec8565b6115b8565b600081136001600160ff1b03829004600c1116600116611656575b60017ff5555555555555555555555555555555555555555555555555555555555555568212600083121616611649575b600c0290565b611651610ec8565b611643565b61165e610ec8565b611613565b600081136001600160ff1b03829004606411166001166116b3575b60017ffeb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb851eb98212600083121616610f9f5760640290565b6116bb610ec8565b61167e565b6031600160ff1b0181126001166116d9575b6030190190565b6116e1610ec8565b6116d2565b600082128015600160ff1b840183121661171c575b6001600160ff1b038301821316611710570390565b611718610ec8565b0390565b611724610ec8565b6116fb565b6110e661183861189f6118d49361188b61187261174e611748846119f6565b936110e9565b61186c6040519687957f3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d22757460208801527f662d38223f3e3c73766720786d6c6e733d22687474703a2f2f7777772e77332e60408801527f6f72672f323030302f7376672220206865696768743d2231303025222077696460608801527f74683d2231303025222076696577426f783d223020302031303030203130303060808801527f22207374796c653d226261636b67726f756e642d636f6c6f723a677265793b2260a08801526f1f1e39ba3cb6329f1e17b9ba3cb6329f60811b60c088015260d0870190610d5e565b7f3c7465787420783d2235302220793d223535302220636c6173733d226e616d65815261111f60f11b602082015260220190565b90610d5e565b6c1e17ba32bc3a1f1e17b9bb339f60991b8152600d0190565b0391610216601f1993848101835282610e09565b6040517f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000006020820152938491603a830161186c565b03908101835282610e09565b9081602091031261000e575190565b506040513d6000823e3d90fd5b91906105608382031261000e5780601f8401121561000e57604080519161192283610d8c565b829161054086019582871161000e57925b8684106119435750505050915190565b60e08484031261000e57815160e09161195b82610db5565b8551825260209182870151838201528487015185820152606080880151908201526080808801519082015260a0808801519082015260c08088015190820152815201930192611933565b6001906000198114610eef570190565b50634e487b7160e01b600052603260045260246000fd5b9060068110156119de575b60051b0190565b6119e66119b5565b6119d7565b818110611710570390565b6119fe610e56565b600154909190611a2490611a18906001600160a01b031681565b6001600160a01b031690565b60408051631da686ff60e31b81529192602091908284600481885afa938415611fb9575b600094611f9a575b5081516338ab6ea360e21b8152908382600481895afa918215611f8d575b600092611f6e575b508251634dbe7f7360e01b81526004810191909152602481019190915293610560908190869060449082905afa948515611f61575b6000918296611f2d575b5050939291906000945b848610611acf5750505050505090565b909192939495848488611ae281866119cc565b5160a0810151611af190610f58565b611afa85610f6e565b611b0391610f07565b611b0d8582610f13565b611b16816120c3565b95611b2091610fac565b611b29916119eb565b611b32906120c3565b90838101918a835190611b4491610f13565b9251611b508c85610fac565b611b59916119eb565b92611b63906120c3565b92611b6d906120c3565b928951938491878301611b7f91610d5e565b601760f91b8152600101611b9291610d5e565b0395601f19968781018552611ba79085610e09565b898301928c80855190611bb991610f13565b945190611bc69086610fac565b611bcf916119eb565b93611bd9906120c3565b93611be3906120c3565b938b51948591898301611bf591610d5e565b601760f91b8152600101611c0891610d5e565b038881018552611c189085610e09565b8051611c23906120c3565b908b519687898101611c4e906012907103a3930b739b337b93696b7b934b3b4b71d160751b81520190565b611c589089610d5e565b620383c160ed1b8152600301611c6e9088610d5e565b630383c1d960e51b8152600401038a81018952611c8b9089610e09565b611c94906120c3565b9060c00151611ca290611fc6565b968c519a8b998a01611cb391610d5e565b7f3c7374796c653e20406b65796672616d6573206d6f7665456c6c6970736500008152601e01611ce39084610d5e565b670103d901812903d960c51b8152600801611cfe9082610d5e565b7f207472616e73666f726d3a20726f74617465283064656729207472616e736c6181527f7465283070782c2031307078293b207d2031303025207b2000000000000000006020820152603801611d5391610d5e565b7f207472616e73666f726d3a20726f746174652833363064656729207472616e738152736c617465283070782c2031307078293b207d207d60601b60208201526034016a656c6c697073652369642d60a81b8152600b01611db49083610d5e565b7f207b20616e696d6174696f6e3a206d6f7665456c6c69707365000000000000008152601901611de49083610d5e565b7f20347320696e66696e697465206c696e6561723b20616e696d6174696f6e2d64815266656c61793a202d60c81b6020820152602701611e2391610d5e565b6b399d903e9e17b9ba3cb6329f60a11b8152600c016f3c656c6c697073652069643d2269642d60801b8152601001611e5a91610d5e565b651110393c9e9160d11b8152600601611e739082610d5e565b601760f91b8152600101611e879083610d5e565b651110393c1e9160d11b8152600601611e9f91610d5e565b601760f91b8152600101611eb291610d5e565b65111031bc9e9160d11b8152600601611eca91610d5e565b65111031bc1e9160d11b8152600601611ee291610d5e565b6711103334b6361e9160c11b8152600801611efc91610d5e565b631110179f60e11b8152600401039081018252611f199082610e09565b95611f23906119a5565b9493929190611abf565b611f5193965080919250903d10611f5a575b611f498183610e09565b8101906118fc565b93903880611ab5565b503d611f3f565b611f696118ef565b611aab565b611f86919250843d8611610b2157610b118183610e09565b9038611a76565b611f956118ef565b611a6e565b611fb2919450833d8511610b2157610b118183610e09565b9238611a50565b611fc16118ef565b611a48565b6110e660259161206f61206161ffff61186c6120536120186028612011606482878b60201c1606968319881161207d575b612006610168828d16066120c3565b9a60101c16066120c3565b94016120c3565b92604051988997630d0e6d8560e31b60208a015261204081518092602060248d019101610132565b8801600b60fa1b60248201520190610d5e565b61094b60f21b815260020190565b61252960f01b815260020190565b03601f198101835282610e09565b612085610ec8565b611ff7565b908160a091031261000e5780516120a0816102a1565b916020820151801515810361000e57916040810151916080606083015192015190565b806000917a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000808210156121f8575b506d04ee2d6d415b85acef8100000000808310156121e9575b50662386f26fc10000808310156121da575b506305f5e100808310156121cb575b50612710808310156121bc575b5060648210156121ac575b600a809210156121a2575b60019081602161215a828701610fcb565b95860101905b61216c575b5050505090565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a83530491821561219d57919082612160565b612165565b9160010191612149565b919060646002910491019161213e565b60049193920491019138612133565b60089193920491019138612126565b60109193920491019138612117565b60209193920491019138612105565b6040935081049150386120ec565b60018060a01b03169060405161221b81610ded565b602881526020926040368584013760275b600081121561224357506110e691929350156122b8565b90600f811660108110156122ab575b835183101561229e575b6f181899199a1a9b1b9c1cb0b131b232b360811b901a83830186015360041c90600160ff1b8114612291575b6000190161222c565b612299610ec8565b612288565b6122a66119b5565b61225c565b6122b36119b5565b612252565b156122bf57565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fdfea2646970667358221220444443809fab30a64ba32a238e763f1615be64c3bd7e571579a2c8ad704a04d164736f6c634300080f0033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/server/contractData/ABI-12345-Speedruns.json b/server/contractData/ABI-12345-Speedruns.json index 7da975de..74c9e56c 100644 --- a/server/contractData/ABI-12345-Speedruns.json +++ b/server/contractData/ABI-12345-Speedruns.json @@ -519,8 +519,8 @@ "type": "receive" } ], - "bytecode": "0x6080346200012657602081016001600160401b03811182821017620001105760405260008091526002546001908181811c9116801562000105575b6020821014620000f157601f8111620000a7575b600283905560038054336001600160a01b03198216811790925560405191906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08684a3611ea190816200012c8239f35b60028352601f0160051c7f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace908101905b818110620000e657506200004e565b8381558201620000d7565b634e487b7160e01b83526022600452602483fd5b90607f16906200003a565b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610030575b3615610028573461002357610021611980565b005b600080fd5b610021611958565b60003560e01c8062fdd58e1461018357806301ffc9a71461017a5780630e89341c146101715780632eb2c2d6146101685780634e1273f41461015f57806356d5f24b146101565780635abc08191461014d578063715018a6146101445780638da5cb5b1461013b57806393ccd31014610132578063a22cb46514610129578063b46f007114610120578063c12e5c6814610117578063e2ce81a51461010e578063e985e9c514610105578063f242432a146100fc5763f2fde38b0361000e576100f7610b06565b61000e565b506100f7610aeb565b506100f7610ab6565b506100f7610a6e565b506100f7610930565b506100f76108be565b506100f761085e565b506100f761071b565b506100f76106f1565b506100f761068c565b506100f761065c565b506100f76105bc565b506100f76104f6565b506100f761042b565b506100f7610283565b506100f76101e3565b506100f761019d565b6001600160a01b0381160361002357565b50346100235760403660031901126100235760206101c96004356101c08161018c565b60243590610c33565b604051908152f35b6001600160e01b031981160361002357565b503461002357602036600319011261002357602061020b600435610206816101d1565b611b75565b6040519015158152f35b918091926000905b82821061023557501161022e575050565b6000910152565b9150806020918301518186015201829161021d565b9060209161026381518092818552858086019101610215565b601f01601f1916010190565b90602061028092818152019061024a565b90565b5034610023576020366003190112610023576102b76102a3600435611a0a565b60405191829160208352602083019061024a565b0390f35b50634e487b7160e01b600052604160045260246000fd5b606081019081106001600160401b038211176102ed57604052565b6102f56102bb565b604052565b608081019081106001600160401b038211176102ed57604052565b90601f801991011681019081106001600160401b038211176102ed57604052565b6020906001600160401b03811161034f575b60051b0190565b6103576102bb565b610348565b81601f820112156100235780359161037383610336565b926103816040519485610315565b808452602092838086019260051b820101928311610023578301905b8282106103ab575050505090565b8135815290830190830161039d565b6020906001600160401b0381116103d7575b601f01601f19160190565b6103df6102bb565b6103cc565b81601f82011215610023578035906103fb826103ba565b926104096040519485610315565b8284526020838301011161002357816000926020809301838601378301015290565b50346100235760a0366003190112610023576004356104498161018c565b602435906104568261018c565b6001600160401b03916044358381116100235761047790369060040161035c565b6064358481116100235761048f90369060040161035c565b91608435948511610023576104ab6100219536906004016103e4565b93610e88565b90815180825260208080930193019160005b8281106104d1575050505090565b8351855293810193928101926001016104c3565b9060206102809281815201906104b1565b5034610023576040366003190112610023576004356001600160401b03808211610023573660238301121561002357816004013561053381610336565b926105416040519485610315565b81845260209160248386019160051b8301019136831161002357602401905b8282106105995785602435868111610023576102b79161058761058d92369060040161035c565b90610d5d565b604051918291826104e5565b83809183356105a78161018c565b815201910190610560565b8015150361002357565b5034610023576060366003190112610023576100216004356105dd8161018c565b6024356105e98161018c565b604435916105f6836105b2565b61060b60018060a01b036004541633146113af565b611810565b60a0600319820112610023576004356106288161018c565b916024356106358161018c565b916044359160643591608435906001600160401b03821161002357610280916004016103e4565b50346100235761002161066e36610610565b9361068760018060a09694961b036004541633146113af565b61160b565b5034610023576000806003193601126106ee576106a7610bdb565b600380546001600160a01b031981169091556040519082906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b80fd5b5034610023576000366003190112610023576003546040516001600160a01b039091168152602090f35b5034610023576080366003190112610023576004356107398161018c565b6024356044356064356001600160401b0381116100235761075e9036906004016103e4565b9160018060a01b03610775816004541633146113af565b841693841561080f576100219461078b83611533565b5061079584611533565b506107c5826107ae856000526000602052604060002090565b9060018060a01b0316600052602052604060002090565b6107d08582546110d0565b9055604080518481526020810186905260009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f629190a43361145f565b60405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b50346100235760403660031901126100235761002160043561087f8161018c565b6024359061088c826105b2565b611ca4565b9181601f84011215610023578235916001600160401b038311610023576020838186019501011161002357565b5034610023576040366003190112610023576004356001600160401b03808211610023573660238301121561002357816004013591818311610023573660248460051b830101116100235760243591821161002357610021926109276024933690600401610891565b93909201611d97565b50346100235760603660031901126100235760043561094e8161018c565b6024356044359060018060a01b0361096b816004541633146113af565b8316918215610a1d57610a127fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62916000956109a585611533565b506109af82611533565b506109b8611582565b506109f8826109d5836107ae896000526000602052604060002090565b546109e2828210156115b3565b03916107ae876000526000602052604060002090565b556040805194855260208501919091523393918291820190565b0390a4610021611582565b60405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b503461002357602036600319011261002357600435610a8c8161018c565b610a94610bdb565b600480546001600160a01b0319166001600160a01b0392909216919091179055005b503461002357604036600319011261002357602061020b600435610ad98161018c565b60243590610ae68261018c565b611c15565b503461002357610021610afd36610610565b93929092611d04565b503461002357602036600319011261002357600435610b248161018c565b610b2c610bdb565b6001600160a01b03908116908115610b875760009160035491816bffffffffffffffffffffffff60a01b84161760035560405192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08484a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6003546001600160a01b03163303610bef57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b6001600160a01b03811615610c67576000918252602082815260408084206001600160a01b03909316845291905290205490565b60405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b6064820152608490fd5b90610cc982610336565b610cd66040519182610315565b8281528092610ce7601f1991610336565b0190602036910137565b50634e487b7160e01b600052601160045260246000fd5b6001906000198114610d18570190565b610d20610cf1565b0190565b50634e487b7160e01b600052603260045260246000fd5b6020918151811015610d50575b60051b010190565b610d58610d24565b610d48565b9190918051835103610dce57610d738151610cbf565b9060005b8151811015610dc75780610db2610da1610d94610dc29486610d3b565b516001600160a01b031690565b610dab8389610d3b565b5190610c33565b610dbc8286610d3b565b52610d08565b610d77565b5090925050565b60405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b6064820152608490fd5b15610e2c57565b60405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201526d195c881bdc88185c1c1c9bdd995960921b6064820152608490fd5b6001600160a01b0380821696919592949392903388148015610fa5575b610eae90610e25565b610ebb8451865114610fba565b8516610ec8811515611017565b60005b8451811015610f5f578088610f53610f4b8a6107ae8b610ef987610ef2610f5a9a8f610d3b565b5192610d3b565b5195610f3a87610f17836107ae866000526000602052604060002090565b54610f2482821015611071565b03916107ae846000526000602052604060002090565b556000526000602052604060002090565b9182546110d0565b9055610d08565b610ecb565b50610fa396919592976040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb339180610f9a8a8a836110dc565b0390a43361128e565b565b50610eae610fb33389611c15565b9050610ea5565b15610fc157565b60405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608490fd5b1561101e57565b60405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b1561107857565b60405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608490fd5b81198111610d18570190565b90916110f3610280936040845260408401906104b1565b9160208184039101526104b1565b908160209103126100235751610280816101d1565b93906102809593611148916111569460018060a01b03809216885216602087015260a0604087015260a08601906104b1565b9084820360608601526104b1565b91608081840391015261024a565b60809060208152602860208201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b60608201520190565b60009060033d116111ba57565b905060046000803e60005160e01c90565b600060443d1061028057604051600319913d83016004833e81516001600160401b03918282113d60248401111761122857818401948551938411611230573d85010160208487010111611228575061028092910160200190610315565b949350505050565b50949350505050565b60809060208152603460208201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356040820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60608201520190565b9493919092813b6112a2575b505050505050565b60006020946112c96040519788968795869463bc197c8160e01b9c8d875260048701611116565b03926001600160a01b03165af16000918161137f575b5061135757505060016112f06111ad565b6308c379a014611328575b61130b575b38808080808061129a565b60405162461bcd60e51b81528061132460048201611239565b0390fd5b6113306111cb565b8061133b57506112fb565b60405162461bcd60e51b8152908190611324906004830161026f565b6001600160e01b031916146113005760405162461bcd60e51b81528061132460048201611164565b6113a191925060203d81116113a8575b6113998183610315565b810190611101565b90386112df565b503d61138f565b156113b657565b60405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920416e79626f64792050726f626c656d2063616e2063616c6c0000006044820152606490fd5b909260a0926102809594600180861b031683526000602084015260408301526060820152816080820152019061024a565b919261028095949160a094600180871b03809216855216602084015260408301526060820152816080820152019061024a565b9390803b61146f575b5050505050565b6114979360006020946040519687958694859363f23a6e6160e01b9b8c8652600486016113fb565b03926001600160a01b03165af160009181611513575b506114eb57505060016114be6111ad565b6308c379a0146114d8575b61130b575b3880808080611468565b6114e06111cb565b8061133b57506114c9565b6001600160e01b031916146114ce5760405162461bcd60e51b81528061132460048201611164565b61152c91925060203d81116113a8576113998183610315565b90386114ad565b60405190604082018281106001600160401b03821117611575575b60405260018252602082016020368237825115611569575290565b611571610d24565b5290565b61157d6102bb565b61154e565b60405190602082018281106001600160401b038211176115a6575b60405260008252565b6115ae6102bb565b61159d565b156115ba57565b60405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608490fd5b6001600160a01b039485831694919391929190611629861515611017565b61163282611533565b5061163c84611533565b50600095828752602093878552816040998761166c8a8d8d209060018060a01b0316600052602052604060002090565b5461167982821015611071565b878c528b89520361169e8a8d8d209060018060a01b0316600052602052604060002090565b55858a528987528a8a206001600160a01b0384166000908152602091909152604090206116cc8982546110d0565b90558a51868152602081018990529089169033907fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6290604090a43b611716575b5050505050505050565b61173c948785948a519788958694859363f23a6e6160e01b9c8d8652336004870161142c565b03925af191829185936117f1575b50506117c357505060019061175d6111ad565b6308c379a014611793575b5061177c57505b388080808080808061170c565b5162461bcd60e51b81528061132460048201611239565b61179b6111cb565b90816117a75750611768565b50825162461bcd60e51b8152908190611324906004830161026f565b6001600160e01b0319160390506117da575061176f565b5162461bcd60e51b81528061132460048201611164565b611808929350803d106113a8576113998183610315565b90388061174a565b6001600160a01b038083169390821692908385146118855761186b6020926107ae7f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319560018060a01b03166000526001602052604060002090565b9015159060ff1981541660ff8316179055604051908152a3565b60405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608490fd5b3d15611907573d906118ed826103ba565b916118fb6040519384610315565b82523d6000602084013e565b606090565b1561191357565b60405162461bcd60e51b815260206004820152601d60248201527f43616c6c20746f20616e79626f647950726f626c656d206661696c65640000006044820152606490fd5b610fa36000808060018060a01b03600454166040519034905af161197a6118dc565b5061190c565b610fa360008060018060a01b036004541660405136838237828136810182815203925af161197a6118dc565b602081830312610023578051906001600160401b038211610023570181601f820112156100235780516119de816103ba565b926119ec6040519485610315565b81845260208284010111610023576102809160208085019101610215565b9060018060a01b0360045416916040519060209182810191631649ecf760e31b8352602482015260248152611a3e816102d2565b6000948592839251915afa90611a526118dc565b9115611a6b5761028092935080825183010191016119ac565b9050604051908360025460019281841c93808316928315611b56575b8286108414611b425797869798611aa48789989960209181520190565b94908115611b215750600114611ac5575b5050505061028092500382610315565b60026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace9690945091905b828510611b0b5750505061028093500138808080611ab5565b8654858501529586019587955093810193611af2565b93505050506102809491925060ff19168252151560051b0138808080611ab5565b634e487b7160e01b89526022600452602489fd5b94607f1694611a87565b908160209103126100235751610280816105b2565b60008060018060a01b0360045416604051936020850190637b7de1cd60e11b825263ffffffff60e01b169485602482015260248152611bb3816102d2565b51915afa611bbf6118dc565b9015611bd957610280915060208082518301019101611b60565b50636cdb3d1360e11b8114908115611c04575b8115611bf6575090565b6301ffc9a760e01b14919050565b6303a24d0760e21b81149150611bec565b9060008060018060a01b038060045416906040516020810191630bd1274f60e31b835280881660248301528616604482015260448152611c54816102fa565b51915afa90611c616118dc565b9115611c7c5750610280915060208082518301019101611b60565b611c9f91506107ae60ff9360018060a01b03166000526001602052604060002090565b541690565b9060008060018060a01b0380600454169082604051602081019263ceab69ff60e01b845288166024820152861515604482015260448152611ce4816102fa565b51925af1611cf06118dc565b5015611cfa575050565b610fa39133611810565b92919060008060018060a01b03968682611d41611d4f8b60045416946040519283918c8c8c6020860199634a940b5f60e11b8b526024870161142c565b03601f198101835282610315565b51925af193611d5c6118dc565b9415611d6a57505050505050565b610fa395811633148015611d82575b61068790610e25565b50610687611d903383611c15565b9050611d79565b90929192611db060018060a01b036004541633146113af565b60048111611e3457826040519485378383016040528015611e2e5780600114611e285780600214611e1a5780600314611e0657600414611def57505050565b6060810135926040820135926020830135923591a4565b5090916040820135926020830135923591a3565b5091906020830135923591a2565b503591a1565b505090a0565b60405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e7920746f7069637360881b6044820152606490fdfea2646970667358221220cbfc973bff832847dbbd3585a22aa0df549b5af66c0bfa7a5cbb73143d3aa78464736f6c634300080f0033", - "deployedBytecode": "0x60806040526004361015610030575b3615610028573461002357610021611980565b005b600080fd5b610021611958565b60003560e01c8062fdd58e1461018357806301ffc9a71461017a5780630e89341c146101715780632eb2c2d6146101685780634e1273f41461015f57806356d5f24b146101565780635abc08191461014d578063715018a6146101445780638da5cb5b1461013b57806393ccd31014610132578063a22cb46514610129578063b46f007114610120578063c12e5c6814610117578063e2ce81a51461010e578063e985e9c514610105578063f242432a146100fc5763f2fde38b0361000e576100f7610b06565b61000e565b506100f7610aeb565b506100f7610ab6565b506100f7610a6e565b506100f7610930565b506100f76108be565b506100f761085e565b506100f761071b565b506100f76106f1565b506100f761068c565b506100f761065c565b506100f76105bc565b506100f76104f6565b506100f761042b565b506100f7610283565b506100f76101e3565b506100f761019d565b6001600160a01b0381160361002357565b50346100235760403660031901126100235760206101c96004356101c08161018c565b60243590610c33565b604051908152f35b6001600160e01b031981160361002357565b503461002357602036600319011261002357602061020b600435610206816101d1565b611b75565b6040519015158152f35b918091926000905b82821061023557501161022e575050565b6000910152565b9150806020918301518186015201829161021d565b9060209161026381518092818552858086019101610215565b601f01601f1916010190565b90602061028092818152019061024a565b90565b5034610023576020366003190112610023576102b76102a3600435611a0a565b60405191829160208352602083019061024a565b0390f35b50634e487b7160e01b600052604160045260246000fd5b606081019081106001600160401b038211176102ed57604052565b6102f56102bb565b604052565b608081019081106001600160401b038211176102ed57604052565b90601f801991011681019081106001600160401b038211176102ed57604052565b6020906001600160401b03811161034f575b60051b0190565b6103576102bb565b610348565b81601f820112156100235780359161037383610336565b926103816040519485610315565b808452602092838086019260051b820101928311610023578301905b8282106103ab575050505090565b8135815290830190830161039d565b6020906001600160401b0381116103d7575b601f01601f19160190565b6103df6102bb565b6103cc565b81601f82011215610023578035906103fb826103ba565b926104096040519485610315565b8284526020838301011161002357816000926020809301838601378301015290565b50346100235760a0366003190112610023576004356104498161018c565b602435906104568261018c565b6001600160401b03916044358381116100235761047790369060040161035c565b6064358481116100235761048f90369060040161035c565b91608435948511610023576104ab6100219536906004016103e4565b93610e88565b90815180825260208080930193019160005b8281106104d1575050505090565b8351855293810193928101926001016104c3565b9060206102809281815201906104b1565b5034610023576040366003190112610023576004356001600160401b03808211610023573660238301121561002357816004013561053381610336565b926105416040519485610315565b81845260209160248386019160051b8301019136831161002357602401905b8282106105995785602435868111610023576102b79161058761058d92369060040161035c565b90610d5d565b604051918291826104e5565b83809183356105a78161018c565b815201910190610560565b8015150361002357565b5034610023576060366003190112610023576100216004356105dd8161018c565b6024356105e98161018c565b604435916105f6836105b2565b61060b60018060a01b036004541633146113af565b611810565b60a0600319820112610023576004356106288161018c565b916024356106358161018c565b916044359160643591608435906001600160401b03821161002357610280916004016103e4565b50346100235761002161066e36610610565b9361068760018060a09694961b036004541633146113af565b61160b565b5034610023576000806003193601126106ee576106a7610bdb565b600380546001600160a01b031981169091556040519082906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b80fd5b5034610023576000366003190112610023576003546040516001600160a01b039091168152602090f35b5034610023576080366003190112610023576004356107398161018c565b6024356044356064356001600160401b0381116100235761075e9036906004016103e4565b9160018060a01b03610775816004541633146113af565b841693841561080f576100219461078b83611533565b5061079584611533565b506107c5826107ae856000526000602052604060002090565b9060018060a01b0316600052602052604060002090565b6107d08582546110d0565b9055604080518481526020810186905260009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f629190a43361145f565b60405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b50346100235760403660031901126100235761002160043561087f8161018c565b6024359061088c826105b2565b611ca4565b9181601f84011215610023578235916001600160401b038311610023576020838186019501011161002357565b5034610023576040366003190112610023576004356001600160401b03808211610023573660238301121561002357816004013591818311610023573660248460051b830101116100235760243591821161002357610021926109276024933690600401610891565b93909201611d97565b50346100235760603660031901126100235760043561094e8161018c565b6024356044359060018060a01b0361096b816004541633146113af565b8316918215610a1d57610a127fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62916000956109a585611533565b506109af82611533565b506109b8611582565b506109f8826109d5836107ae896000526000602052604060002090565b546109e2828210156115b3565b03916107ae876000526000602052604060002090565b556040805194855260208501919091523393918291820190565b0390a4610021611582565b60405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b503461002357602036600319011261002357600435610a8c8161018c565b610a94610bdb565b600480546001600160a01b0319166001600160a01b0392909216919091179055005b503461002357604036600319011261002357602061020b600435610ad98161018c565b60243590610ae68261018c565b611c15565b503461002357610021610afd36610610565b93929092611d04565b503461002357602036600319011261002357600435610b248161018c565b610b2c610bdb565b6001600160a01b03908116908115610b875760009160035491816bffffffffffffffffffffffff60a01b84161760035560405192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08484a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6003546001600160a01b03163303610bef57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b6001600160a01b03811615610c67576000918252602082815260408084206001600160a01b03909316845291905290205490565b60405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b6064820152608490fd5b90610cc982610336565b610cd66040519182610315565b8281528092610ce7601f1991610336565b0190602036910137565b50634e487b7160e01b600052601160045260246000fd5b6001906000198114610d18570190565b610d20610cf1565b0190565b50634e487b7160e01b600052603260045260246000fd5b6020918151811015610d50575b60051b010190565b610d58610d24565b610d48565b9190918051835103610dce57610d738151610cbf565b9060005b8151811015610dc75780610db2610da1610d94610dc29486610d3b565b516001600160a01b031690565b610dab8389610d3b565b5190610c33565b610dbc8286610d3b565b52610d08565b610d77565b5090925050565b60405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b6064820152608490fd5b15610e2c57565b60405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201526d195c881bdc88185c1c1c9bdd995960921b6064820152608490fd5b6001600160a01b0380821696919592949392903388148015610fa5575b610eae90610e25565b610ebb8451865114610fba565b8516610ec8811515611017565b60005b8451811015610f5f578088610f53610f4b8a6107ae8b610ef987610ef2610f5a9a8f610d3b565b5192610d3b565b5195610f3a87610f17836107ae866000526000602052604060002090565b54610f2482821015611071565b03916107ae846000526000602052604060002090565b556000526000602052604060002090565b9182546110d0565b9055610d08565b610ecb565b50610fa396919592976040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb339180610f9a8a8a836110dc565b0390a43361128e565b565b50610eae610fb33389611c15565b9050610ea5565b15610fc157565b60405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608490fd5b1561101e57565b60405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b1561107857565b60405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608490fd5b81198111610d18570190565b90916110f3610280936040845260408401906104b1565b9160208184039101526104b1565b908160209103126100235751610280816101d1565b93906102809593611148916111569460018060a01b03809216885216602087015260a0604087015260a08601906104b1565b9084820360608601526104b1565b91608081840391015261024a565b60809060208152602860208201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b60608201520190565b60009060033d116111ba57565b905060046000803e60005160e01c90565b600060443d1061028057604051600319913d83016004833e81516001600160401b03918282113d60248401111761122857818401948551938411611230573d85010160208487010111611228575061028092910160200190610315565b949350505050565b50949350505050565b60809060208152603460208201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356040820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60608201520190565b9493919092813b6112a2575b505050505050565b60006020946112c96040519788968795869463bc197c8160e01b9c8d875260048701611116565b03926001600160a01b03165af16000918161137f575b5061135757505060016112f06111ad565b6308c379a014611328575b61130b575b38808080808061129a565b60405162461bcd60e51b81528061132460048201611239565b0390fd5b6113306111cb565b8061133b57506112fb565b60405162461bcd60e51b8152908190611324906004830161026f565b6001600160e01b031916146113005760405162461bcd60e51b81528061132460048201611164565b6113a191925060203d81116113a8575b6113998183610315565b810190611101565b90386112df565b503d61138f565b156113b657565b60405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920416e79626f64792050726f626c656d2063616e2063616c6c0000006044820152606490fd5b909260a0926102809594600180861b031683526000602084015260408301526060820152816080820152019061024a565b919261028095949160a094600180871b03809216855216602084015260408301526060820152816080820152019061024a565b9390803b61146f575b5050505050565b6114979360006020946040519687958694859363f23a6e6160e01b9b8c8652600486016113fb565b03926001600160a01b03165af160009181611513575b506114eb57505060016114be6111ad565b6308c379a0146114d8575b61130b575b3880808080611468565b6114e06111cb565b8061133b57506114c9565b6001600160e01b031916146114ce5760405162461bcd60e51b81528061132460048201611164565b61152c91925060203d81116113a8576113998183610315565b90386114ad565b60405190604082018281106001600160401b03821117611575575b60405260018252602082016020368237825115611569575290565b611571610d24565b5290565b61157d6102bb565b61154e565b60405190602082018281106001600160401b038211176115a6575b60405260008252565b6115ae6102bb565b61159d565b156115ba57565b60405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608490fd5b6001600160a01b039485831694919391929190611629861515611017565b61163282611533565b5061163c84611533565b50600095828752602093878552816040998761166c8a8d8d209060018060a01b0316600052602052604060002090565b5461167982821015611071565b878c528b89520361169e8a8d8d209060018060a01b0316600052602052604060002090565b55858a528987528a8a206001600160a01b0384166000908152602091909152604090206116cc8982546110d0565b90558a51868152602081018990529089169033907fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6290604090a43b611716575b5050505050505050565b61173c948785948a519788958694859363f23a6e6160e01b9c8d8652336004870161142c565b03925af191829185936117f1575b50506117c357505060019061175d6111ad565b6308c379a014611793575b5061177c57505b388080808080808061170c565b5162461bcd60e51b81528061132460048201611239565b61179b6111cb565b90816117a75750611768565b50825162461bcd60e51b8152908190611324906004830161026f565b6001600160e01b0319160390506117da575061176f565b5162461bcd60e51b81528061132460048201611164565b611808929350803d106113a8576113998183610315565b90388061174a565b6001600160a01b038083169390821692908385146118855761186b6020926107ae7f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319560018060a01b03166000526001602052604060002090565b9015159060ff1981541660ff8316179055604051908152a3565b60405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608490fd5b3d15611907573d906118ed826103ba565b916118fb6040519384610315565b82523d6000602084013e565b606090565b1561191357565b60405162461bcd60e51b815260206004820152601d60248201527f43616c6c20746f20616e79626f647950726f626c656d206661696c65640000006044820152606490fd5b610fa36000808060018060a01b03600454166040519034905af161197a6118dc565b5061190c565b610fa360008060018060a01b036004541660405136838237828136810182815203925af161197a6118dc565b602081830312610023578051906001600160401b038211610023570181601f820112156100235780516119de816103ba565b926119ec6040519485610315565b81845260208284010111610023576102809160208085019101610215565b9060018060a01b0360045416916040519060209182810191631649ecf760e31b8352602482015260248152611a3e816102d2565b6000948592839251915afa90611a526118dc565b9115611a6b5761028092935080825183010191016119ac565b9050604051908360025460019281841c93808316928315611b56575b8286108414611b425797869798611aa48789989960209181520190565b94908115611b215750600114611ac5575b5050505061028092500382610315565b60026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace9690945091905b828510611b0b5750505061028093500138808080611ab5565b8654858501529586019587955093810193611af2565b93505050506102809491925060ff19168252151560051b0138808080611ab5565b634e487b7160e01b89526022600452602489fd5b94607f1694611a87565b908160209103126100235751610280816105b2565b60008060018060a01b0360045416604051936020850190637b7de1cd60e11b825263ffffffff60e01b169485602482015260248152611bb3816102d2565b51915afa611bbf6118dc565b9015611bd957610280915060208082518301019101611b60565b50636cdb3d1360e11b8114908115611c04575b8115611bf6575090565b6301ffc9a760e01b14919050565b6303a24d0760e21b81149150611bec565b9060008060018060a01b038060045416906040516020810191630bd1274f60e31b835280881660248301528616604482015260448152611c54816102fa565b51915afa90611c616118dc565b9115611c7c5750610280915060208082518301019101611b60565b611c9f91506107ae60ff9360018060a01b03166000526001602052604060002090565b541690565b9060008060018060a01b0380600454169082604051602081019263ceab69ff60e01b845288166024820152861515604482015260448152611ce4816102fa565b51925af1611cf06118dc565b5015611cfa575050565b610fa39133611810565b92919060008060018060a01b03968682611d41611d4f8b60045416946040519283918c8c8c6020860199634a940b5f60e11b8b526024870161142c565b03601f198101835282610315565b51925af193611d5c6118dc565b9415611d6a57505050505050565b610fa395811633148015611d82575b61068790610e25565b50610687611d903383611c15565b9050611d79565b90929192611db060018060a01b036004541633146113af565b60048111611e3457826040519485378383016040528015611e2e5780600114611e285780600214611e1a5780600314611e0657600414611def57505050565b6060810135926040820135926020830135923591a4565b5090916040820135926020830135923591a3565b5091906020830135923591a2565b503591a1565b505090a0565b60405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e7920746f7069637360881b6044820152606490fdfea2646970667358221220cbfc973bff832847dbbd3585a22aa0df549b5af66c0bfa7a5cbb73143d3aa78464736f6c634300080f0033", + "bytecode": "0x6080346200012657602081016001600160401b03811182821017620001105760405260008091526002546001908181811c9116801562000105575b6020821014620000f157601f8111620000a7575b600283905560038054336001600160a01b03198216811790925560405191906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08684a3611ea190816200012c8239f35b60028352601f0160051c7f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace908101905b818110620000e657506200004e565b8381558201620000d7565b634e487b7160e01b83526022600452602483fd5b90607f16906200003a565b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610030575b3615610028573461002357610021611980565b005b600080fd5b610021611958565b60003560e01c8062fdd58e1461018357806301ffc9a71461017a5780630e89341c146101715780632eb2c2d6146101685780634e1273f41461015f57806356d5f24b146101565780635abc08191461014d578063715018a6146101445780638da5cb5b1461013b57806393ccd31014610132578063a22cb46514610129578063b46f007114610120578063c12e5c6814610117578063e2ce81a51461010e578063e985e9c514610105578063f242432a146100fc5763f2fde38b0361000e576100f7610b06565b61000e565b506100f7610aeb565b506100f7610ab6565b506100f7610a6e565b506100f7610930565b506100f76108be565b506100f761085e565b506100f761071b565b506100f76106f1565b506100f761068c565b506100f761065c565b506100f76105bc565b506100f76104f6565b506100f761042b565b506100f7610283565b506100f76101e3565b506100f761019d565b6001600160a01b0381160361002357565b50346100235760403660031901126100235760206101c96004356101c08161018c565b60243590610c33565b604051908152f35b6001600160e01b031981160361002357565b503461002357602036600319011261002357602061020b600435610206816101d1565b611b75565b6040519015158152f35b918091926000905b82821061023557501161022e575050565b6000910152565b9150806020918301518186015201829161021d565b9060209161026381518092818552858086019101610215565b601f01601f1916010190565b90602061028092818152019061024a565b90565b5034610023576020366003190112610023576102b76102a3600435611a0a565b60405191829160208352602083019061024a565b0390f35b50634e487b7160e01b600052604160045260246000fd5b606081019081106001600160401b038211176102ed57604052565b6102f56102bb565b604052565b608081019081106001600160401b038211176102ed57604052565b90601f801991011681019081106001600160401b038211176102ed57604052565b6020906001600160401b03811161034f575b60051b0190565b6103576102bb565b610348565b81601f820112156100235780359161037383610336565b926103816040519485610315565b808452602092838086019260051b820101928311610023578301905b8282106103ab575050505090565b8135815290830190830161039d565b6020906001600160401b0381116103d7575b601f01601f19160190565b6103df6102bb565b6103cc565b81601f82011215610023578035906103fb826103ba565b926104096040519485610315565b8284526020838301011161002357816000926020809301838601378301015290565b50346100235760a0366003190112610023576004356104498161018c565b602435906104568261018c565b6001600160401b03916044358381116100235761047790369060040161035c565b6064358481116100235761048f90369060040161035c565b91608435948511610023576104ab6100219536906004016103e4565b93610e88565b90815180825260208080930193019160005b8281106104d1575050505090565b8351855293810193928101926001016104c3565b9060206102809281815201906104b1565b5034610023576040366003190112610023576004356001600160401b03808211610023573660238301121561002357816004013561053381610336565b926105416040519485610315565b81845260209160248386019160051b8301019136831161002357602401905b8282106105995785602435868111610023576102b79161058761058d92369060040161035c565b90610d5d565b604051918291826104e5565b83809183356105a78161018c565b815201910190610560565b8015150361002357565b5034610023576060366003190112610023576100216004356105dd8161018c565b6024356105e98161018c565b604435916105f6836105b2565b61060b60018060a01b036004541633146113af565b611810565b60a0600319820112610023576004356106288161018c565b916024356106358161018c565b916044359160643591608435906001600160401b03821161002357610280916004016103e4565b50346100235761002161066e36610610565b9361068760018060a09694961b036004541633146113af565b61160b565b5034610023576000806003193601126106ee576106a7610bdb565b600380546001600160a01b031981169091556040519082906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b80fd5b5034610023576000366003190112610023576003546040516001600160a01b039091168152602090f35b5034610023576080366003190112610023576004356107398161018c565b6024356044356064356001600160401b0381116100235761075e9036906004016103e4565b9160018060a01b03610775816004541633146113af565b841693841561080f576100219461078b83611533565b5061079584611533565b506107c5826107ae856000526000602052604060002090565b9060018060a01b0316600052602052604060002090565b6107d08582546110d0565b9055604080518481526020810186905260009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f629190a43361145f565b60405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b50346100235760403660031901126100235761002160043561087f8161018c565b6024359061088c826105b2565b611ca4565b9181601f84011215610023578235916001600160401b038311610023576020838186019501011161002357565b5034610023576040366003190112610023576004356001600160401b03808211610023573660238301121561002357816004013591818311610023573660248460051b830101116100235760243591821161002357610021926109276024933690600401610891565b93909201611d97565b50346100235760603660031901126100235760043561094e8161018c565b6024356044359060018060a01b0361096b816004541633146113af565b8316918215610a1d57610a127fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62916000956109a585611533565b506109af82611533565b506109b8611582565b506109f8826109d5836107ae896000526000602052604060002090565b546109e2828210156115b3565b03916107ae876000526000602052604060002090565b556040805194855260208501919091523393918291820190565b0390a4610021611582565b60405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b503461002357602036600319011261002357600435610a8c8161018c565b610a94610bdb565b600480546001600160a01b0319166001600160a01b0392909216919091179055005b503461002357604036600319011261002357602061020b600435610ad98161018c565b60243590610ae68261018c565b611c15565b503461002357610021610afd36610610565b93929092611d04565b503461002357602036600319011261002357600435610b248161018c565b610b2c610bdb565b6001600160a01b03908116908115610b875760009160035491816bffffffffffffffffffffffff60a01b84161760035560405192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08484a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6003546001600160a01b03163303610bef57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b6001600160a01b03811615610c67576000918252602082815260408084206001600160a01b03909316845291905290205490565b60405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b6064820152608490fd5b90610cc982610336565b610cd66040519182610315565b8281528092610ce7601f1991610336565b0190602036910137565b50634e487b7160e01b600052601160045260246000fd5b6001906000198114610d18570190565b610d20610cf1565b0190565b50634e487b7160e01b600052603260045260246000fd5b6020918151811015610d50575b60051b010190565b610d58610d24565b610d48565b9190918051835103610dce57610d738151610cbf565b9060005b8151811015610dc75780610db2610da1610d94610dc29486610d3b565b516001600160a01b031690565b610dab8389610d3b565b5190610c33565b610dbc8286610d3b565b52610d08565b610d77565b5090925050565b60405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b6064820152608490fd5b15610e2c57565b60405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201526d195c881bdc88185c1c1c9bdd995960921b6064820152608490fd5b6001600160a01b0380821696919592949392903388148015610fa5575b610eae90610e25565b610ebb8451865114610fba565b8516610ec8811515611017565b60005b8451811015610f5f578088610f53610f4b8a6107ae8b610ef987610ef2610f5a9a8f610d3b565b5192610d3b565b5195610f3a87610f17836107ae866000526000602052604060002090565b54610f2482821015611071565b03916107ae846000526000602052604060002090565b556000526000602052604060002090565b9182546110d0565b9055610d08565b610ecb565b50610fa396919592976040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb339180610f9a8a8a836110dc565b0390a43361128e565b565b50610eae610fb33389611c15565b9050610ea5565b15610fc157565b60405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608490fd5b1561101e57565b60405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b1561107857565b60405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608490fd5b81198111610d18570190565b90916110f3610280936040845260408401906104b1565b9160208184039101526104b1565b908160209103126100235751610280816101d1565b93906102809593611148916111569460018060a01b03809216885216602087015260a0604087015260a08601906104b1565b9084820360608601526104b1565b91608081840391015261024a565b60809060208152602860208201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b60608201520190565b60009060033d116111ba57565b905060046000803e60005160e01c90565b600060443d1061028057604051600319913d83016004833e81516001600160401b03918282113d60248401111761122857818401948551938411611230573d85010160208487010111611228575061028092910160200190610315565b949350505050565b50949350505050565b60809060208152603460208201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356040820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60608201520190565b9493919092813b6112a2575b505050505050565b60006020946112c96040519788968795869463bc197c8160e01b9c8d875260048701611116565b03926001600160a01b03165af16000918161137f575b5061135757505060016112f06111ad565b6308c379a014611328575b61130b575b38808080808061129a565b60405162461bcd60e51b81528061132460048201611239565b0390fd5b6113306111cb565b8061133b57506112fb565b60405162461bcd60e51b8152908190611324906004830161026f565b6001600160e01b031916146113005760405162461bcd60e51b81528061132460048201611164565b6113a191925060203d81116113a8575b6113998183610315565b810190611101565b90386112df565b503d61138f565b156113b657565b60405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920416e79626f64792050726f626c656d2063616e2063616c6c0000006044820152606490fd5b909260a0926102809594600180861b031683526000602084015260408301526060820152816080820152019061024a565b919261028095949160a094600180871b03809216855216602084015260408301526060820152816080820152019061024a565b9390803b61146f575b5050505050565b6114979360006020946040519687958694859363f23a6e6160e01b9b8c8652600486016113fb565b03926001600160a01b03165af160009181611513575b506114eb57505060016114be6111ad565b6308c379a0146114d8575b61130b575b3880808080611468565b6114e06111cb565b8061133b57506114c9565b6001600160e01b031916146114ce5760405162461bcd60e51b81528061132460048201611164565b61152c91925060203d81116113a8576113998183610315565b90386114ad565b60405190604082018281106001600160401b03821117611575575b60405260018252602082016020368237825115611569575290565b611571610d24565b5290565b61157d6102bb565b61154e565b60405190602082018281106001600160401b038211176115a6575b60405260008252565b6115ae6102bb565b61159d565b156115ba57565b60405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608490fd5b6001600160a01b039485831694919391929190611629861515611017565b61163282611533565b5061163c84611533565b50600095828752602093878552816040998761166c8a8d8d209060018060a01b0316600052602052604060002090565b5461167982821015611071565b878c528b89520361169e8a8d8d209060018060a01b0316600052602052604060002090565b55858a528987528a8a206001600160a01b0384166000908152602091909152604090206116cc8982546110d0565b90558a51868152602081018990529089169033907fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6290604090a43b611716575b5050505050505050565b61173c948785948a519788958694859363f23a6e6160e01b9c8d8652336004870161142c565b03925af191829185936117f1575b50506117c357505060019061175d6111ad565b6308c379a014611793575b5061177c57505b388080808080808061170c565b5162461bcd60e51b81528061132460048201611239565b61179b6111cb565b90816117a75750611768565b50825162461bcd60e51b8152908190611324906004830161026f565b6001600160e01b0319160390506117da575061176f565b5162461bcd60e51b81528061132460048201611164565b611808929350803d106113a8576113998183610315565b90388061174a565b6001600160a01b038083169390821692908385146118855761186b6020926107ae7f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319560018060a01b03166000526001602052604060002090565b9015159060ff1981541660ff8316179055604051908152a3565b60405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608490fd5b3d15611907573d906118ed826103ba565b916118fb6040519384610315565b82523d6000602084013e565b606090565b1561191357565b60405162461bcd60e51b815260206004820152601d60248201527f43616c6c20746f20616e79626f647950726f626c656d206661696c65640000006044820152606490fd5b610fa36000808060018060a01b03600454166040519034905af161197a6118dc565b5061190c565b610fa360008060018060a01b036004541660405136838237828136810182815203925af161197a6118dc565b602081830312610023578051906001600160401b038211610023570181601f820112156100235780516119de816103ba565b926119ec6040519485610315565b81845260208284010111610023576102809160208085019101610215565b9060018060a01b0360045416916040519060209182810191631649ecf760e31b8352602482015260248152611a3e816102d2565b6000948592839251915afa90611a526118dc565b9115611a6b5761028092935080825183010191016119ac565b9050604051908360025460019281841c93808316928315611b56575b8286108414611b425797869798611aa48789989960209181520190565b94908115611b215750600114611ac5575b5050505061028092500382610315565b60026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace9690945091905b828510611b0b5750505061028093500138808080611ab5565b8654858501529586019587955093810193611af2565b93505050506102809491925060ff19168252151560051b0138808080611ab5565b634e487b7160e01b89526022600452602489fd5b94607f1694611a87565b908160209103126100235751610280816105b2565b60008060018060a01b0360045416604051936020850190637b7de1cd60e11b825263ffffffff60e01b169485602482015260248152611bb3816102d2565b51915afa611bbf6118dc565b9015611bd957610280915060208082518301019101611b60565b50636cdb3d1360e11b8114908115611c04575b8115611bf6575090565b6301ffc9a760e01b14919050565b6303a24d0760e21b81149150611bec565b9060008060018060a01b038060045416906040516020810191630bd1274f60e31b835280881660248301528616604482015260448152611c54816102fa565b51915afa90611c616118dc565b9115611c7c5750610280915060208082518301019101611b60565b611c9f91506107ae60ff9360018060a01b03166000526001602052604060002090565b541690565b9060008060018060a01b0380600454169082604051602081019263ceab69ff60e01b845288166024820152861515604482015260448152611ce4816102fa565b51925af1611cf06118dc565b5015611cfa575050565b610fa39133611810565b92919060008060018060a01b03968682611d41611d4f8b60045416946040519283918c8c8c6020860199634a940b5f60e11b8b526024870161142c565b03601f198101835282610315565b51925af193611d5c6118dc565b9415611d6a57505050505050565b610fa395811633148015611d82575b61068790610e25565b50610687611d903383611c15565b9050611d79565b90929192611db060018060a01b036004541633146113af565b60048111611e3457826040519485378383016040528015611e2e5780600114611e285780600214611e1a5780600314611e0657600414611def57505050565b6060810135926040820135926020830135923591a4565b5090916040820135926020830135923591a3565b5091906020830135923591a2565b503591a1565b505090a0565b60405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e7920746f7069637360881b6044820152606490fdfea264697066735822122004004b455c451428b713c251104538019468f77321b9a77cc2cbd21f849b44ce64736f6c634300080f0033", + "deployedBytecode": "0x60806040526004361015610030575b3615610028573461002357610021611980565b005b600080fd5b610021611958565b60003560e01c8062fdd58e1461018357806301ffc9a71461017a5780630e89341c146101715780632eb2c2d6146101685780634e1273f41461015f57806356d5f24b146101565780635abc08191461014d578063715018a6146101445780638da5cb5b1461013b57806393ccd31014610132578063a22cb46514610129578063b46f007114610120578063c12e5c6814610117578063e2ce81a51461010e578063e985e9c514610105578063f242432a146100fc5763f2fde38b0361000e576100f7610b06565b61000e565b506100f7610aeb565b506100f7610ab6565b506100f7610a6e565b506100f7610930565b506100f76108be565b506100f761085e565b506100f761071b565b506100f76106f1565b506100f761068c565b506100f761065c565b506100f76105bc565b506100f76104f6565b506100f761042b565b506100f7610283565b506100f76101e3565b506100f761019d565b6001600160a01b0381160361002357565b50346100235760403660031901126100235760206101c96004356101c08161018c565b60243590610c33565b604051908152f35b6001600160e01b031981160361002357565b503461002357602036600319011261002357602061020b600435610206816101d1565b611b75565b6040519015158152f35b918091926000905b82821061023557501161022e575050565b6000910152565b9150806020918301518186015201829161021d565b9060209161026381518092818552858086019101610215565b601f01601f1916010190565b90602061028092818152019061024a565b90565b5034610023576020366003190112610023576102b76102a3600435611a0a565b60405191829160208352602083019061024a565b0390f35b50634e487b7160e01b600052604160045260246000fd5b606081019081106001600160401b038211176102ed57604052565b6102f56102bb565b604052565b608081019081106001600160401b038211176102ed57604052565b90601f801991011681019081106001600160401b038211176102ed57604052565b6020906001600160401b03811161034f575b60051b0190565b6103576102bb565b610348565b81601f820112156100235780359161037383610336565b926103816040519485610315565b808452602092838086019260051b820101928311610023578301905b8282106103ab575050505090565b8135815290830190830161039d565b6020906001600160401b0381116103d7575b601f01601f19160190565b6103df6102bb565b6103cc565b81601f82011215610023578035906103fb826103ba565b926104096040519485610315565b8284526020838301011161002357816000926020809301838601378301015290565b50346100235760a0366003190112610023576004356104498161018c565b602435906104568261018c565b6001600160401b03916044358381116100235761047790369060040161035c565b6064358481116100235761048f90369060040161035c565b91608435948511610023576104ab6100219536906004016103e4565b93610e88565b90815180825260208080930193019160005b8281106104d1575050505090565b8351855293810193928101926001016104c3565b9060206102809281815201906104b1565b5034610023576040366003190112610023576004356001600160401b03808211610023573660238301121561002357816004013561053381610336565b926105416040519485610315565b81845260209160248386019160051b8301019136831161002357602401905b8282106105995785602435868111610023576102b79161058761058d92369060040161035c565b90610d5d565b604051918291826104e5565b83809183356105a78161018c565b815201910190610560565b8015150361002357565b5034610023576060366003190112610023576100216004356105dd8161018c565b6024356105e98161018c565b604435916105f6836105b2565b61060b60018060a01b036004541633146113af565b611810565b60a0600319820112610023576004356106288161018c565b916024356106358161018c565b916044359160643591608435906001600160401b03821161002357610280916004016103e4565b50346100235761002161066e36610610565b9361068760018060a09694961b036004541633146113af565b61160b565b5034610023576000806003193601126106ee576106a7610bdb565b600380546001600160a01b031981169091556040519082906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08284a3f35b80fd5b5034610023576000366003190112610023576003546040516001600160a01b039091168152602090f35b5034610023576080366003190112610023576004356107398161018c565b6024356044356064356001600160401b0381116100235761075e9036906004016103e4565b9160018060a01b03610775816004541633146113af565b841693841561080f576100219461078b83611533565b5061079584611533565b506107c5826107ae856000526000602052604060002090565b9060018060a01b0316600052602052604060002090565b6107d08582546110d0565b9055604080518481526020810186905260009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f629190a43361145f565b60405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b50346100235760403660031901126100235761002160043561087f8161018c565b6024359061088c826105b2565b611ca4565b9181601f84011215610023578235916001600160401b038311610023576020838186019501011161002357565b5034610023576040366003190112610023576004356001600160401b03808211610023573660238301121561002357816004013591818311610023573660248460051b830101116100235760243591821161002357610021926109276024933690600401610891565b93909201611d97565b50346100235760603660031901126100235760043561094e8161018c565b6024356044359060018060a01b0361096b816004541633146113af565b8316918215610a1d57610a127fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62916000956109a585611533565b506109af82611533565b506109b8611582565b506109f8826109d5836107ae896000526000602052604060002090565b546109e2828210156115b3565b03916107ae876000526000602052604060002090565b556040805194855260208501919091523393918291820190565b0390a4610021611582565b60405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b503461002357602036600319011261002357600435610a8c8161018c565b610a94610bdb565b600480546001600160a01b0319166001600160a01b0392909216919091179055005b503461002357604036600319011261002357602061020b600435610ad98161018c565b60243590610ae68261018c565b611c15565b503461002357610021610afd36610610565b93929092611d04565b503461002357602036600319011261002357600435610b248161018c565b610b2c610bdb565b6001600160a01b03908116908115610b875760009160035491816bffffffffffffffffffffffff60a01b84161760035560405192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08484a3f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6003546001600160a01b03163303610bef57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b6001600160a01b03811615610c67576000918252602082815260408084206001600160a01b03909316845291905290205490565b60405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b6064820152608490fd5b90610cc982610336565b610cd66040519182610315565b8281528092610ce7601f1991610336565b0190602036910137565b50634e487b7160e01b600052601160045260246000fd5b6001906000198114610d18570190565b610d20610cf1565b0190565b50634e487b7160e01b600052603260045260246000fd5b6020918151811015610d50575b60051b010190565b610d58610d24565b610d48565b9190918051835103610dce57610d738151610cbf565b9060005b8151811015610dc75780610db2610da1610d94610dc29486610d3b565b516001600160a01b031690565b610dab8389610d3b565b5190610c33565b610dbc8286610d3b565b52610d08565b610d77565b5090925050565b60405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b6064820152608490fd5b15610e2c57565b60405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201526d195c881bdc88185c1c1c9bdd995960921b6064820152608490fd5b6001600160a01b0380821696919592949392903388148015610fa5575b610eae90610e25565b610ebb8451865114610fba565b8516610ec8811515611017565b60005b8451811015610f5f578088610f53610f4b8a6107ae8b610ef987610ef2610f5a9a8f610d3b565b5192610d3b565b5195610f3a87610f17836107ae866000526000602052604060002090565b54610f2482821015611071565b03916107ae846000526000602052604060002090565b556000526000602052604060002090565b9182546110d0565b9055610d08565b610ecb565b50610fa396919592976040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb339180610f9a8a8a836110dc565b0390a43361128e565b565b50610eae610fb33389611c15565b9050610ea5565b15610fc157565b60405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608490fd5b1561101e57565b60405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b1561107857565b60405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608490fd5b81198111610d18570190565b90916110f3610280936040845260408401906104b1565b9160208184039101526104b1565b908160209103126100235751610280816101d1565b93906102809593611148916111569460018060a01b03809216885216602087015260a0604087015260a08601906104b1565b9084820360608601526104b1565b91608081840391015261024a565b60809060208152602860208201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b60608201520190565b60009060033d116111ba57565b905060046000803e60005160e01c90565b600060443d1061028057604051600319913d83016004833e81516001600160401b03918282113d60248401111761122857818401948551938411611230573d85010160208487010111611228575061028092910160200190610315565b949350505050565b50949350505050565b60809060208152603460208201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356040820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60608201520190565b9493919092813b6112a2575b505050505050565b60006020946112c96040519788968795869463bc197c8160e01b9c8d875260048701611116565b03926001600160a01b03165af16000918161137f575b5061135757505060016112f06111ad565b6308c379a014611328575b61130b575b38808080808061129a565b60405162461bcd60e51b81528061132460048201611239565b0390fd5b6113306111cb565b8061133b57506112fb565b60405162461bcd60e51b8152908190611324906004830161026f565b6001600160e01b031916146113005760405162461bcd60e51b81528061132460048201611164565b6113a191925060203d81116113a8575b6113998183610315565b810190611101565b90386112df565b503d61138f565b156113b657565b60405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920416e79626f64792050726f626c656d2063616e2063616c6c0000006044820152606490fd5b909260a0926102809594600180861b031683526000602084015260408301526060820152816080820152019061024a565b919261028095949160a094600180871b03809216855216602084015260408301526060820152816080820152019061024a565b9390803b61146f575b5050505050565b6114979360006020946040519687958694859363f23a6e6160e01b9b8c8652600486016113fb565b03926001600160a01b03165af160009181611513575b506114eb57505060016114be6111ad565b6308c379a0146114d8575b61130b575b3880808080611468565b6114e06111cb565b8061133b57506114c9565b6001600160e01b031916146114ce5760405162461bcd60e51b81528061132460048201611164565b61152c91925060203d81116113a8576113998183610315565b90386114ad565b60405190604082018281106001600160401b03821117611575575b60405260018252602082016020368237825115611569575290565b611571610d24565b5290565b61157d6102bb565b61154e565b60405190602082018281106001600160401b038211176115a6575b60405260008252565b6115ae6102bb565b61159d565b156115ba57565b60405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608490fd5b6001600160a01b039485831694919391929190611629861515611017565b61163282611533565b5061163c84611533565b50600095828752602093878552816040998761166c8a8d8d209060018060a01b0316600052602052604060002090565b5461167982821015611071565b878c528b89520361169e8a8d8d209060018060a01b0316600052602052604060002090565b55858a528987528a8a206001600160a01b0384166000908152602091909152604090206116cc8982546110d0565b90558a51868152602081018990529089169033907fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6290604090a43b611716575b5050505050505050565b61173c948785948a519788958694859363f23a6e6160e01b9c8d8652336004870161142c565b03925af191829185936117f1575b50506117c357505060019061175d6111ad565b6308c379a014611793575b5061177c57505b388080808080808061170c565b5162461bcd60e51b81528061132460048201611239565b61179b6111cb565b90816117a75750611768565b50825162461bcd60e51b8152908190611324906004830161026f565b6001600160e01b0319160390506117da575061176f565b5162461bcd60e51b81528061132460048201611164565b611808929350803d106113a8576113998183610315565b90388061174a565b6001600160a01b038083169390821692908385146118855761186b6020926107ae7f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319560018060a01b03166000526001602052604060002090565b9015159060ff1981541660ff8316179055604051908152a3565b60405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608490fd5b3d15611907573d906118ed826103ba565b916118fb6040519384610315565b82523d6000602084013e565b606090565b1561191357565b60405162461bcd60e51b815260206004820152601d60248201527f43616c6c20746f20616e79626f647950726f626c656d206661696c65640000006044820152606490fd5b610fa36000808060018060a01b03600454166040519034905af161197a6118dc565b5061190c565b610fa360008060018060a01b036004541660405136838237828136810182815203925af161197a6118dc565b602081830312610023578051906001600160401b038211610023570181601f820112156100235780516119de816103ba565b926119ec6040519485610315565b81845260208284010111610023576102809160208085019101610215565b9060018060a01b0360045416916040519060209182810191631649ecf760e31b8352602482015260248152611a3e816102d2565b6000948592839251915afa90611a526118dc565b9115611a6b5761028092935080825183010191016119ac565b9050604051908360025460019281841c93808316928315611b56575b8286108414611b425797869798611aa48789989960209181520190565b94908115611b215750600114611ac5575b5050505061028092500382610315565b60026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace9690945091905b828510611b0b5750505061028093500138808080611ab5565b8654858501529586019587955093810193611af2565b93505050506102809491925060ff19168252151560051b0138808080611ab5565b634e487b7160e01b89526022600452602489fd5b94607f1694611a87565b908160209103126100235751610280816105b2565b60008060018060a01b0360045416604051936020850190637b7de1cd60e11b825263ffffffff60e01b169485602482015260248152611bb3816102d2565b51915afa611bbf6118dc565b9015611bd957610280915060208082518301019101611b60565b50636cdb3d1360e11b8114908115611c04575b8115611bf6575090565b6301ffc9a760e01b14919050565b6303a24d0760e21b81149150611bec565b9060008060018060a01b038060045416906040516020810191630bd1274f60e31b835280881660248301528616604482015260448152611c54816102fa565b51915afa90611c616118dc565b9115611c7c5750610280915060208082518301019101611b60565b611c9f91506107ae60ff9360018060a01b03166000526001602052604060002090565b541690565b9060008060018060a01b0380600454169082604051602081019263ceab69ff60e01b845288166024820152861515604482015260448152611ce4816102fa565b51925af1611cf06118dc565b5015611cfa575050565b610fa39133611810565b92919060008060018060a01b03968682611d41611d4f8b60045416946040519283918c8c8c6020860199634a940b5f60e11b8b526024870161142c565b03601f198101835282610315565b51925af193611d5c6118dc565b9415611d6a57505050505050565b610fa395811633148015611d82575b61068790610e25565b50610687611d903383611c15565b9050611d79565b90929192611db060018060a01b036004541633146113af565b60048111611e3457826040519485378383016040528015611e2e5780600114611e285780600214611e1a5780600314611e0657600414611def57505050565b6060810135926040820135926020830135923591a4565b5090916040820135926020830135923591a3565b5091906020830135923591a2565b503591a1565b505090a0565b60405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e7920746f7069637360881b6044820152606490fdfea264697066735822122004004b455c451428b713c251104538019468f77321b9a77cc2cbd21f849b44ce64736f6c634300080f0033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/server/package.json b/server/package.json index 694a4102..5f2cf7e2 100644 --- a/server/package.json +++ b/server/package.json @@ -5,7 +5,7 @@ "license": "MIT", "type": "module", "scripts": { - "shovel": "OUTPUT=1 bun run shovel-config.ts > config.json && ./shovel --config config.json", + "shovel": "OUTPUT=1 bun run shovel-config.ts > config.json && DATABASE_URL=postgresql://billy@localhost:5432/shovel ./shovel --config config.json", "dev": "bun run --hot src/index.ts", "start": "./shovel --config config.json & bun run src/index.ts", "smoke": "bun run tsc && bun test" diff --git a/server/shovel-config.ts b/server/shovel-config.ts index de9e41f3..adf2459b 100644 --- a/server/shovel-config.ts +++ b/server/shovel-config.ts @@ -10,7 +10,12 @@ import { AnybodyProblem, Speedruns } from './contracts' import { ethers } from 'ethers' import { camelToSnakeCase } from './src/util' -export type Chain = 'mainnet' | 'sepolia' | 'garnet' | 'base_sepolia' +export type Chain = + | 'mainnet' + | 'sepolia' + | 'garnet' + | 'base_sepolia' + | 'localhost' type KnownSource = Source & { name: Chain } const mainnet: KnownSource = { @@ -27,6 +32,14 @@ const sepolia: KnownSource = { concurrency: 1 } +const localhost: KnownSource = { + name: 'localhost', + chain_id: 12345, + url: 'http://localhost:8545', + batch_size: 1000, + concurrency: 1 +} + const garnet: KnownSource = { name: 'garnet', chain_id: 17069, @@ -59,7 +72,7 @@ const STARTING_BLOCK = { } // n.b. sources must match ABI in contracts to correctly sync -export const sources: KnownSource[] = [baseSepolia] +export const sources: KnownSource[] = [localhost] const contracts = Object.fromEntries( [AnybodyProblem, Speedruns].map((contract) => { @@ -153,7 +166,7 @@ async function integrationFor( if (process.env.OUTPUT) { ;(async function main() { let integrations = await Promise.all([ - integrationFor('Speedruns', 'Transfer', [ + integrationFor('Speedruns', 'TransferSingle', [ ['block_num DESC', 'tx_idx DESC', 'log_idx DESC'] ]), integrationFor('AnybodyProblem', 'RunCreated'), diff --git a/server/shovel.test.ts b/server/shovel.test.ts index 5a1591a4..4c7d1bd3 100644 --- a/server/shovel.test.ts +++ b/server/shovel.test.ts @@ -33,7 +33,7 @@ describe('shovel sanity test', () => { // public | problems_body_removed | 0 expect(rows).toBeDefined() - expect(rowCount).toBeGreaterThanOrEqual(7) + expect(rowCount).toBeGreaterThanOrEqual(4) // TODO: uncomment when there's data // const tablesWithRows = rows.filter((row) => row.rows_n > 0) diff --git a/server/src/index.ts b/server/src/index.ts index d4b792b2..7432de43 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -35,7 +35,7 @@ async function setupListener() { db.query(`LISTEN "${source.name}-anybody_problem_level_solved"`) db.query(`LISTEN "${source.name}-anybody_problem_run_created"`) db.query(`LISTEN "${source.name}-anybody_problem_run_solved"`) - db.query(`LISTEN "${source.name}-speedruns_transfer"`) + db.query(`LISTEN "${source.name}-speedruns_transfer_single"`) } await Promise.all( diff --git a/server/src/leaderboard.ts b/server/src/leaderboard.ts index a4318702..2b1f03ab 100644 --- a/server/src/leaderboard.ts +++ b/server/src/leaderboard.ts @@ -112,18 +112,18 @@ async function calculateDailyLeaderboard(day: number, chain: Chain) { ), latest_transactions AS ( SELECT - token_id, + id, "to", - ROW_NUMBER() OVER (PARTITION BY token_id ORDER BY block_num DESC, tx_idx DESC, log_idx DESC) AS rn + ROW_NUMBER() OVER (PARTITION BY id ORDER BY block_num DESC, tx_idx DESC, log_idx DESC) AS rn FROM - speedruns_transfer + speedruns_transfer_single WHERE - token_id IN (SELECT run_id FROM leaderboard) + id IN (SELECT run_id FROM leaderboard) AND src_name = $1 ), current_players AS ( SELECT - token_id, + id, concat('0x', encode("to", 'hex')) as player FROM latest_transactions @@ -137,13 +137,13 @@ async function calculateDailyLeaderboard(day: number, chain: Chain) { current_players.player FROM leaderboard - LEFT JOIN current_players ON leaderboard.run_id = current_players.token_id + LEFT JOIN current_players ON leaderboard.run_id = current_players.id ORDER BY COALESCE(leaderboard.level, 0), leaderboard.time; ` const result = await db.query(q, [chain]) - + console.dir(result, { depth: null }) function scores(rows: any[]): SpeedScore[] { return rows.map((r: any) => ({ problemId: r.problem_id, diff --git a/src/anybody.js b/src/anybody.js index dbdef942..e1a06b7a 100644 --- a/src/anybody.js +++ b/src/anybody.js @@ -139,7 +139,7 @@ export class Anybody extends EventEmitter { startingBodies: 1, windowWidth: 1000, windowHeight: 1000, - pixelDensity: window.devicePixelRatio, //4, // Math.min(4, 4 * (window.devicePixelRatio ?? 1)), + pixelDensity: typeof window !== 'undefined' ? window.devicePixelRatio : 4, //4, // Math.min(4, 4 * (window.devicePixelRatio ?? 1)), scalingFactor: 10n ** 3n, minDistanceSquared: 200 * 200, G: NORMAL_GRAVITY, // Gravitational constant diff --git a/src/visuals.js b/src/visuals.js index 244471ab..d77e81c2 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1506,8 +1506,8 @@ export const Visuals = { ) graphic.push() graphic.rotate(-rotate + body.velocity.heading() + this.p.PI / 2) - this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor, graphic) if (!body.backgroundOnly) { + this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor, graphic) this.drawImageAsset(BADDIE_SVG.face, coreWidth, undefined, graphic) // pupils always looking at missile, if no missile, look at mouse diff --git a/test/contracts/anybodyProblem.test.js b/test/contracts/anybodyProblem.test.js index d810178e..e12d5e79 100644 --- a/test/contracts/anybodyProblem.test.js +++ b/test/contracts/anybodyProblem.test.js @@ -90,9 +90,6 @@ describe('AnybodyProblem Tests', function () { const { AnybodyProblem: anybodyProblem } = await deployContracts() const functions = [ - { name: 'emitMetadataUpdate', args: [0] }, - { name: 'emitBatchMetadataUpdate', args: [0, 0] }, - { name: 'exampleEmitMultipleIndexEvent', args: [0, 0, addr1.address] }, { name: 'updateProceedRecipient', args: [addr1.address] }, { name: 'updateSpeedrunsAddress', args: [addr1.address] }, { name: 'updateVerifier', args: [addr1.address, 0, 0] }, @@ -236,7 +233,6 @@ describe('AnybodyProblem Tests', function () { const [owner, acct1] = await ethers.getSigners() const { AnybodyProblem: anybodyProblem, Speedruns: speedruns } = await deployContracts({ mock: true }) - await anybodyProblem.updateProceedRecipient(acct1.address) const proceedRecipient = await anybodyProblem.proceedRecipient() @@ -245,6 +241,7 @@ describe('AnybodyProblem Tests', function () { let runId = 0, tx const day = await anybodyProblem.currentDay() + let accumulativeTime = 0 for (let i = 0; i < 5; i++) { const level = i + 1 @@ -259,6 +256,7 @@ describe('AnybodyProblem Tests', function () { tx = solvedReturn.tx accumulativeTime += parseInt(solvedReturn.time) } + await expect(tx) .to.emit(anybodyProblem, 'RunSolved') .withArgs(owner.address, runId, accumulativeTime, day) @@ -271,19 +269,14 @@ describe('AnybodyProblem Tests', function () { const balanceAfter = await ethers.provider.getBalance(proceedRecipient) expect(balanceAfter.sub(balanceBefore)).to.equal(price) - const speedrunBalance = await speedruns.balanceOf(owner.address) + const speedrunBalance = await speedruns.balanceOf(owner.address, day) expect(speedrunBalance).to.equal(1) - const expectedTokenId = runId - const ownerOfToken = await speedruns.ownerOf(expectedTokenId) - expect(ownerOfToken).to.equal(owner.address) - const fastestRun = await anybodyProblem.fastestByDay(day, 0) expect(fastestRun).to.equal(runId) const mostGames = await anybodyProblem.mostGames(0) expect(mostGames).to.equal(owner.address) - const gamesPlayed = await anybodyProblem.gamesPlayed(owner.address) expect(gamesPlayed.total).to.equal(1) expect(gamesPlayed.lastPlayed).to.equal(day) @@ -331,7 +324,7 @@ describe('AnybodyProblem Tests', function () { .to.emit(anybodyProblem, 'EthMoved') .withArgs(owner.address, true, '0x', price) - const speedrunBalance = await speedruns.balanceOf(owner.address) + const speedrunBalance = await speedruns.balanceOf(owner.address, day) expect(speedrunBalance).to.equal(1) const fastestRun = await anybodyProblem.fastestByDay(day, 0) diff --git a/test/contracts/speedruns.test.js b/test/contracts/speedruns.test.js index 450d4f29..8277d683 100644 --- a/test/contracts/speedruns.test.js +++ b/test/contracts/speedruns.test.js @@ -34,8 +34,8 @@ describe('Speedruns Tests', function () { args: [owner.address, 1] }, { - name: '__transfer', - args: [acct1.address, acct2.address, 1] + name: '__transfer_single', + args: [acct1.address, acct2.address, 1, 1, ''] }, { name: 'emitGenericEvent', From 799697972ed8909b0870e6acae9a57721c37ba6a Mon Sep 17 00:00:00 2001 From: psugihara Date: Wed, 10 Jul 2024 15:57:30 -0700 Subject: [PATCH 46/54] yarn shovel:clean, bump starting_block, base_sepolia seems to work --- server/package.json | 3 ++- server/shovel-config.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/package.json b/server/package.json index 5f2cf7e2..abaf9d3e 100644 --- a/server/package.json +++ b/server/package.json @@ -5,7 +5,8 @@ "license": "MIT", "type": "module", "scripts": { - "shovel": "OUTPUT=1 bun run shovel-config.ts > config.json && DATABASE_URL=postgresql://billy@localhost:5432/shovel ./shovel --config config.json", + "shovel": "OUTPUT=1 bun run shovel-config.ts > config.json && ./shovel --config config.json", + "shovel:clean": "dropdb shovel && createdb shovel && rm config.json", "dev": "bun run --hot src/index.ts", "start": "./shovel --config config.json & bun run src/index.ts", "smoke": "bun run tsc && bun test" diff --git a/server/shovel-config.ts b/server/shovel-config.ts index adf2459b..7844098d 100644 --- a/server/shovel-config.ts +++ b/server/shovel-config.ts @@ -68,11 +68,11 @@ const STARTING_BLOCK = { // mainnet: BigInt('2067803') sepolia: BigInt('5716600'), garnet: BigInt('2067803'), - base_sepolia: BigInt('11476234') + base_sepolia: BigInt('11912350') } // n.b. sources must match ABI in contracts to correctly sync -export const sources: KnownSource[] = [localhost] +export const sources: KnownSource[] = [baseSepolia] const contracts = Object.fromEntries( [AnybodyProblem, Speedruns].map((contract) => { From 0f8e67ce4b2b364fa38e2ae6d0eb53930638773d Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 11 Jul 2024 09:25:12 -0700 Subject: [PATCH 47/54] fix: calculateDailyLeaderboard uses player not owner --- server/src/leaderboard.ts | 49 +++++++++++++-------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/server/src/leaderboard.ts b/server/src/leaderboard.ts index 2b1f03ab..8b42b14a 100644 --- a/server/src/leaderboard.ts +++ b/server/src/leaderboard.ts @@ -51,26 +51,28 @@ async function calculateDailyLeaderboard(day: number, chain: Chain) { SELECT run_id, level, - MIN(time) AS fastest_time - FROM + MIN(time) AS fastest_time, + player + FROM anybody_problem_level_solved WHERE day = ${day} AND src_name = $1 GROUP BY - run_id, level + run_id, level, player ), cumulative_times AS ( SELECT run_id, - SUM(time) AS total_time + SUM(time) AS total_time, + player FROM anybody_problem_level_solved WHERE day = ${day} AND src_name = $1 GROUP BY - run_id + run_id, player HAVING COUNT(level) = ${MAX_BODY_COUNT - 1} ), @@ -79,7 +81,8 @@ async function calculateDailyLeaderboard(day: number, chain: Chain) { run_id, level, fastest_time, - ROW_NUMBER() OVER (PARTITION BY level ORDER BY fastest_time) AS rank + ROW_NUMBER() OVER (PARTITION BY level ORDER BY fastest_time) AS rank, + player FROM fastest_times ), @@ -87,7 +90,8 @@ async function calculateDailyLeaderboard(day: number, chain: Chain) { SELECT run_id, total_time, - ROW_NUMBER() OVER (ORDER BY total_time) AS rank + ROW_NUMBER() OVER (ORDER BY total_time) AS rank, + player FROM cumulative_times ), @@ -95,7 +99,8 @@ async function calculateDailyLeaderboard(day: number, chain: Chain) { SELECT level, run_id, - fastest_time AS time + fastest_time AS time, + player FROM ranked_fastest_times WHERE @@ -104,46 +109,24 @@ async function calculateDailyLeaderboard(day: number, chain: Chain) { SELECT NULL AS level, run_id, - total_time AS time + total_time AS time, + player FROM ranked_cumulative_times WHERE rank <= ${DAILY_CATEGORY_LIMIT} - ), - latest_transactions AS ( - SELECT - id, - "to", - ROW_NUMBER() OVER (PARTITION BY id ORDER BY block_num DESC, tx_idx DESC, log_idx DESC) AS rn - FROM - speedruns_transfer_single - WHERE - id IN (SELECT run_id FROM leaderboard) - AND src_name = $1 - ), - current_players AS ( - SELECT - id, - concat('0x', encode("to", 'hex')) as player - FROM - latest_transactions - WHERE - rn = 1 ) SELECT leaderboard.level, leaderboard.run_id, leaderboard.time, - current_players.player + concat('0x', encode(player, 'hex')) as player FROM leaderboard - LEFT JOIN current_players ON leaderboard.run_id = current_players.id ORDER BY COALESCE(leaderboard.level, 0), leaderboard.time; ` - const result = await db.query(q, [chain]) - console.dir(result, { depth: null }) function scores(rows: any[]): SpeedScore[] { return rows.map((r: any) => ({ problemId: r.problem_id, From 300db00739e40212ff919e2a733f155bd4c1a153 Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 11 Jul 2024 09:26:59 -0700 Subject: [PATCH 48/54] fix: format player as string in calculateAllTimeLeaderboard --- server/src/leaderboard.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/leaderboard.ts b/server/src/leaderboard.ts index 8b42b14a..69ab52d2 100644 --- a/server/src/leaderboard.ts +++ b/server/src/leaderboard.ts @@ -242,21 +242,21 @@ players_with_most_levels_solved AS ( ) SELECT category, - player, + concat('0x', encode(player, 'hex')) as player, metric FROM leaderboard UNION ALL SELECT 'Most Days Played' AS category, - player, + concat('0x', encode(player, 'hex')) as player, days_played AS metric FROM players_with_most_days_played UNION ALL SELECT 'Most Solved' AS category, - player, + concat('0x', encode(player, 'hex')) as player, solve_count AS metric FROM players_with_most_levels_solved; From 0fb31e1cb665b10959f6a6191090e4976058162b Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 11 Jul 2024 09:29:10 -0700 Subject: [PATCH 49/54] bump season start --- server/src/leaderboard.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/leaderboard.ts b/server/src/leaderboard.ts index 69ab52d2..51c25d98 100644 --- a/server/src/leaderboard.ts +++ b/server/src/leaderboard.ts @@ -296,7 +296,7 @@ FROM export async function updateLeaderboard(chain: Chain) { const start = Date.now() - const seasonStart = 1717632000 + const seasonStart = 1719532800 // calculate daily leaderboards const today = currentDayInUnixTime() From d737ce4bc5d24ac24c3ce32df6c98a2b9d91737c Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 11 Jul 2024 09:38:18 -0700 Subject: [PATCH 50/54] fix bad merge --- src/visuals.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/visuals.js b/src/visuals.js index fffbae3f..4deb26a3 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1507,8 +1507,9 @@ export const Visuals = { ) graphic.push() graphic.rotate(-rotate + body.velocity.heading() + this.p.PI / 2) + this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor, graphic) if (!body.backgroundOnly) { - this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor, graphic) + this.drawImageAsset(BADDIE_SVG.face, coreWidth, undefined, graphic) // pupils always looking at missile, if no missile, look at mouse const target = From b0117534ddea27effc52ce18c194ecd73dbb1cd2 Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 11 Jul 2024 09:39:00 -0700 Subject: [PATCH 51/54] fix merge --- src/visuals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/visuals.js b/src/visuals.js index 4deb26a3..a8ad8910 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1509,7 +1509,7 @@ export const Visuals = { graphic.rotate(-rotate + body.velocity.heading() + this.p.PI / 2) this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor, graphic) if (!body.backgroundOnly) { - this.drawImageAsset(BADDIE_SVG.face, coreWidth, undefined, graphic) + this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor, graphic) // pupils always looking at missile, if no missile, look at mouse const target = From 18be52b3a754f090a3749ed66223360f027a7a36 Mon Sep 17 00:00:00 2001 From: psugihara Date: Thu, 11 Jul 2024 09:41:12 -0700 Subject: [PATCH 52/54] fix merge lol --- src/visuals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/visuals.js b/src/visuals.js index a8ad8910..91a1dbf3 100644 --- a/src/visuals.js +++ b/src/visuals.js @@ -1509,7 +1509,7 @@ export const Visuals = { graphic.rotate(-rotate + body.velocity.heading() + this.p.PI / 2) this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor, graphic) if (!body.backgroundOnly) { - this.drawImageAsset(BADDIE_SVG.core, coreWidth, coreColor, graphic) + this.drawImageAsset(BADDIE_SVG.face, coreWidth, coreColor, graphic) // pupils always looking at missile, if no missile, look at mouse const target = From 9134db0f98037d28523a7636428c46d6cb2c0c04 Mon Sep 17 00:00:00 2001 From: Billy Rennekamp Date: Mon, 15 Jul 2024 21:03:00 +0200 Subject: [PATCH 53/54] tweaks --- contracts/ExternalMetadata.sol | 23 +++++++++++------------ scripts/utils.js | 4 ++++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/contracts/ExternalMetadata.sol b/contracts/ExternalMetadata.sol index f1f94495..db9e723a 100644 --- a/contracts/ExternalMetadata.sol +++ b/contracts/ExternalMetadata.sol @@ -240,25 +240,24 @@ contract ExternalMetadata is Ownable { string( abi.encodePacked( "[", - '{"trait_type":"date","value":"', + '{"trait_type":"Day","value":"', StringsExtended.toString(date), - '"}, {"trait_type":"day","value":"', - StringsExtended.toString(day), - '"}, {"trait_type":"month","value":"', - StringsExtended.toString(month), - '"}, {"trait_type":"year","value":"', + '"}, {"trait_type":"Month","value":"', StringsExtended.toString(year), - '"}, {"trait_type":"1st-address","value":"', + '-', + Math.log10(month) + 1 == 1 ? "0" : "", + StringsExtended.toString(month), + '"}, {"trait_type":"1st Place","value":"', StringsExtended.toHexString(fastestAddress), - '"}, {"trait_type":"1st-time","value":"', + '"}, {"trait_type":"1st Place Time","value":"', StringsExtended.toString(fastestTime), - '"}, {"trait_type":"2nd-address","value":"', + '"}, {"trait_type":"2nd Place","value":"', StringsExtended.toHexString(secondFastestAddress), - '"}, {"trait_type":"2nd-time","value":"', + '"}, {"trait_type":"2nd Place Time","value":"', StringsExtended.toString(secondFastestTime), - '"}, {"trait_type":"3rd-address","value":"', + '"}, {"trait_type":"3rd Place","value":"', StringsExtended.toHexString(thirdFastestAddress), - '"}, {"trait_type":"3rd-time","value":"', + '"}, {"trait_type":"3rd Place Time","value":"', StringsExtended.toString(thirdFastestTime), '"}]' ) diff --git a/scripts/utils.js b/scripts/utils.js index d7a0bc20..7733a0e0 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -227,6 +227,10 @@ const deployContracts = async (options) => { to: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', value: ethers.utils.parseEther('1.0') }) + await deployer.sendTransaction({ + to: '0xc795344b1b30E3CfEE1AFA1D5204B141940CF445', + value: ethers.utils.parseEther('1.0') + }) } return returnObject From e7d35122d5c7892a0d8d056a56e93e74b446b66f Mon Sep 17 00:00:00 2001 From: Billy Rennekamp Date: Mon, 15 Jul 2024 22:36:26 +0200 Subject: [PATCH 54/54] tweaks --- server/.env.template | 4 ++++ server/package.json | 2 +- server/src/demo.html | 9 ++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/server/.env.template b/server/.env.template index 05c8febc..9bfa391c 100644 --- a/server/.env.template +++ b/server/.env.template @@ -5,3 +5,7 @@ PGPASSWORD="" PGDATABASE=shovel PGPORT=5432 +MAINNET_RPC= +SEPOLIA_RPC= +GARNET_RPC= +BASE_SEPOLIA_RPC= \ No newline at end of file diff --git a/server/package.json b/server/package.json index abaf9d3e..744254c2 100644 --- a/server/package.json +++ b/server/package.json @@ -5,7 +5,7 @@ "license": "MIT", "type": "module", "scripts": { - "shovel": "OUTPUT=1 bun run shovel-config.ts > config.json && ./shovel --config config.json", + "shovel": "OUTPUT=1 bun run shovel-config.ts > config.json && DATABASE_URL=postgresql://${USER}@localhost:5432/shovel ./shovel --config config.json", "shovel:clean": "dropdb shovel && createdb shovel && rm config.json", "dev": "bun run --hot src/index.ts", "start": "./shovel --config config.json & bun run src/index.ts", diff --git a/server/src/demo.html b/server/src/demo.html index 9335495e..9d866c0e 100644 --- a/server/src/demo.html +++ b/server/src/demo.html @@ -31,7 +31,14 @@

Anybody API /sse/base_sepolia

while (true) { const { value, done } = await reader.read() if (done) break - sseData.innerHTML += value + '


' + const prettyValue = JSON.stringify( + JSON.parse( + value.substring(value.indexOf('data:') + 5, value.indexOf('id:')) + ), + null, + 2 + ) + sseData.innerHTML += prettyValue + '


' window.scrollTo(0, document.body.scrollHeight) }