{"version":3,"file":"31e58a38230817439e0a.chunk.js","mappings":"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","sources":["webpack://ch.enlightware.gamecreator/./src/imgui/text-layout.ts","webpack://ch.enlightware.gamecreator/./src/math/collision-distance.ts","webpack://ch.enlightware.gamecreator/./src/math/euclidean-division.ts","webpack://ch.enlightware.gamecreator/./src/runtime/gl-state.ts","webpack://ch.enlightware.gamecreator/./src/runtime/input-sources.ts","webpack://ch.enlightware.gamecreator/./src/runtime/mat3.ts","webpack://ch.enlightware.gamecreator/./src/runtime/planck-conversion.ts","webpack://ch.enlightware.gamecreator/./src/runtime/runtime-canvas.ts","webpack://ch.enlightware.gamecreator/./src/runtime/runtime-llm.ts","webpack://ch.enlightware.gamecreator/./src/runtime/runtime-script.ts","webpack://ch.enlightware.gamecreator/./src/runtime/runtime-speech.ts","webpack://ch.enlightware.gamecreator/./src/runtime/runtime.ts","webpack://ch.enlightware.gamecreator/./src/utils/canvas.ts","webpack://ch.enlightware.gamecreator/./src/utils/debug.ts"],"sourcesContent":["/**\n * @module imgui\n */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { Parameters } from 'apps/common/parameters';\nimport { Font } from './render-context';\n\n/** a vector of tuples (line, line length) */\nexport type TextLayout = [string, number][];\n\nexport type TextSizer = (text: string) => number;\n\n/**\n * Multi-line layout algorithm\n * @param text the text to layout\n * @param textSizer a, to estimate text width\n * @param maxWidth maximum width after which a wrap-around shall occur\n * @param splitOn the character to split on, by default ' ' meaning word boundary, unicode-aware if possible\n * @returns a vector of lines\n */\nexport function layoutTextWithSizer(text: string, textSizer: TextSizer, maxWidth: number, splitOn = ' '): TextLayout {\n\tconst hasSegmenter = typeof Intl.Segmenter === 'function';\n\tconst splitLength = textSizer(splitOn);\n\tconst textLayout: TextLayout = [];\n\tconst pushLine = (line: string, length: number) => {\n\t\tif (splitOn === ' ') {\n\t\t\t// trim end of line spacing\n\t\t\twhile (line.endsWith(' ')) {\n\t\t\t\tline = line.slice(0, -1);\n\t\t\t\tlength -= splitLength;\n\t\t\t}\n\t\t}\n\t\ttextLayout.push([line, length]);\n\t};\n\tconst endSymbol = splitOn === ' ' ? '' : splitOn;\n\tconst endSymbolLength = splitOn === ' ' ? 0 : splitLength;\n\tfor (const inputLine of text.split('\\n')) {\n\t\tif (inputLine === '') {\n\t\t\tpushLine('', 0);\n\t\t\tcontinue;\n\t\t}\n\t\tlet line = '';\n\t\tlet currentLength = 0;\n\t\tif (hasSegmenter && splitOn === ' ') {\n\t\t\t// Unicode-aware segmenter\n\t\t\tconst segmenter = new Intl.Segmenter(Parameters.language, { granularity: 'word' });\n\t\t\tconst segments = segmenter.segment(inputLine);\n\t\t\tconst nonWordLength = splitLength * 2;\n\t\t\tfor (const { segment, isWordLike } of segments) {\n\t\t\t\tconst length = textSizer(segment);\n\t\t\t\tif (line !== '') {\n\t\t\t\t\tif (isWordLike && currentLength + nonWordLength + length > maxWidth) {\n\t\t\t\t\t\tpushLine(line, currentLength);\n\t\t\t\t\t\tline = segment;\n\t\t\t\t\t\tcurrentLength = length;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tline += segment;\n\t\t\t\t\t\tcurrentLength += length;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tline = segment;\n\t\t\t\t\tcurrentLength = length;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// fallback to simple space-based layout\n\t\t\tfor (const word of inputLine.split(splitOn)) {\n\t\t\t\tconst length = textSizer(word);\n\t\t\t\tif (line !== '') {\n\t\t\t\t\tif (currentLength + splitLength + length > maxWidth) {\n\t\t\t\t\t\tpushLine(line + endSymbol, currentLength + endSymbolLength);\n\t\t\t\t\t\tline = word;\n\t\t\t\t\t\tcurrentLength = length;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tline += splitOn + word;\n\t\t\t\t\t\tcurrentLength += splitLength + length;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tline = word;\n\t\t\t\t\tcurrentLength = length;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (line !== '') {\n\t\t\tpushLine(line, currentLength);\n\t\t}\n\t}\n\treturn textLayout;\n}\n\nexport function layoutText(text: string, font: Font, maxWidth: number, splitOn = ' '): TextLayout {\n\tconst sizer = (text: string) => font.size(text).size.x;\n\treturn layoutTextWithSizer(text, sizer, maxWidth, splitOn);\n}","/**\n * @module math\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { Vector2, ScalingRotation, transformVectors2, SimilarityTransform } from './linalg';\nimport { assert } from 'utils/assert';\n\nexport function collisionDistance(parentShape: Vector2[], childShape: Vector2[], collisionAngle: number, parentScale: number, childToParentTransformation: ScalingRotation): number {\n\tconst parentTransformation = SimilarityTransform.scalingRotation(parentScale, -collisionAngle);\n\treturn collisionDistanceOnXAxis(\n\t\ttransformVectors2(parentShape, parentTransformation),\n\t\ttransformVectors2(childShape, childToParentTransformation.toSimilarityTransform().after(parentTransformation))\n\t);\n}\n\nexport const enum Side {\n\tLeft,\n\tRight\n}\n\nexport function getPolygonSideIndices(polygon: Vector2[], side: Side) {\n\tconst a = new Array();\n\tlet indices = a;\n\tconst sideSignum = side === Side.Right ? 1 : -1;\n\tif (polygon.length > 0) {\n\t\tlet lastAdded = false;\n\t\tfor (let i = 0; i < polygon.length; i++) {\n\t\t\tconst iInc = (i + 1) % polygon.length;\n\t\t\tconst p1 = polygon[i]!;\n\t\t\tconst p2 = polygon[iInc]!;\n\t\t\tconst displacement = p2.sub(p1);\n\t\t\tif (sideSignum * displacement.y > 0) { // = sideSignum * (displacement.rotate(PI/4)).x > 0\n\t\t\t\tif (!lastAdded) {\n\t\t\t\t\tif (a.length > 0) { // we already found a segment but it is disconnected (last not added)\n\t\t\t\t\t\t// Therefore we create a new array to collected the second segment\n\t\t\t\t\t\tindices = new Array();\n\t\t\t\t\t}\n\t\t\t\t\tindices.push(i);\n\t\t\t\t}\n\t\t\t\tindices.push(iInc);\n\t\t\t\tlastAdded = true;\n\t\t\t} else {\n\t\t\t\tlastAdded = false;\n\t\t\t}\n\t\t}\n\t\tif (a !== indices) { // do we have two segments?\n\t\t\t// Connect the two segments such that they are in positive order and connected:\n\t\t\tfor (const i of a) {\n\t\t\t\tif (indices[indices.length - 1] !== i) {\n\t\t\t\t\tindices.push(i);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn indices;\n}\n\nexport function collisionDistanceOnXAxis(a: Vector2[], b: Vector2[]): number {\n\tassert(a.length > 0, 'Got empty shape!');\n\tassert(b.length > 0, 'Got empty shape!');\n\n\t// We'd like to touch a's right with b's left side.\n\t// So, we start with getting the relevant points from the shapes while keeping track which shape they belong to(labels):\n\tconst enum Label { A, B }\n\ttype LabelledPoint = [Label, Vector2];\n\tconst labelledPoints = [\n\t\t...getPolygonSideIndices(a, Side.Right).map((i) => [Label.A, a[i]] as LabelledPoint),\n\t\t...getPolygonSideIndices(b, Side.Left).map((i) => [Label.B, b[i]] as LabelledPoint)\n\t];\n\n\t// Then, we sort them by their y-coordinate\n\tlabelledPoints.sort((p1: LabelledPoint, p2: LabelledPoint) => {\n\t\treturn p1[1].y - p2[1].y;\n\t});\n\n\t/*\n\tNext, we go through all elements with increasing y coordinates and compute the maximal touch\n\tdistance of all points of one label with the segment between the surrounding points of the other label:\n\tFor example for: A1, B0, B1, B2, A2, B3, A3\n\tWe have to consider the distances of B0, B1, B3 to the segment A1-A2 and of A2 to B2-B3 and B3 to A2-A3.\n\tWe do that by going through the points and for each search the next with the same label.\n\tFor the points in between compute the point to segment distances.\n\t*/\n\n\tlet maxD = -Infinity;\n\tfor (let i = 0; i < labelledPoints.length - 1; i++) {\n\t\tconst labelAtI = labelledPoints[i]![0];\n\t\tconst pi = labelledPoints[i]![1];\n\t\tlet j = i + 1;\n\t\t// Find the first point after v with the same label;\n\t\tfor (; j < labelledPoints.length; j++) {\n\t\t\tif (labelAtI === labelledPoints[j]![0]) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (j - i > 1) { // if there were points of the other label in between\n\t\t\tif (j === labelledPoints.length) {\n\t\t\t\t// All remaining were of the other label. Nothing left to do.\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tconst pj = labelledPoints[j]![1];\n\t\t\t// Compute the distance of all pints between i and j to the segment pi-pj.\n\t\t\tconst xOverY = pj.sub(pi).aspectRatio;\n\t\t\tconst labelSignum = labelAtI === Label.A ? 1 : -1;\n\t\t\tfor (let k = i + 1; k < j; k++) {\n\t\t\t\tconst w = labelledPoints[k]![1];\n\t\t\t\t// The signed distance is the right side of A minus the left side of B because that is how much B\n\t\t\t\t// would need to move to the right for its left side to touch A's right side\n\t\t\t\t// We first compute edge point minus vertex and then correct the sign depending on which belonged to A or B.\n\t\t\t\tconst d = labelSignum * (pi.x + xOverY * (w.y - pi.y) - w.x);\n\t\t\t\tmaxD = Math.max(maxD, d);\n\t\t\t}\n\t\t\ti = j - 2; // next i to consider for the outer loop should be the last before the label changes back. Another -1 is necessary to compensate for the inc of i from the for-loop.\n\t\t}\n\t}\n\treturn maxD;\n}\n","/**\n * @module math\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\n// Function to calculate the Euclidean quotient\nexport function euclideanQuotient(dividend: number, divisor: number) {\n\t// Floor for positive divisors, ceil for negative divisors to always round towards negative infinity\n\tif (divisor > 0) {\n\t\treturn Math.floor(dividend / divisor);\n\t} else {\n\t\treturn Math.ceil(dividend / divisor);\n\t}\n}\n\n// Function to calculate the Euclidean remainder\nexport function euclideanRemainder(dividend: number, divisor: number) {\n\tlet remainder = dividend % divisor;\n\t// If the remainder is negative, adjust it by adding the absolute value of the divisor\n\tif (remainder < 0) {\n\t\tremainder += Math.abs(divisor);\n\t}\n\treturn remainder;\n}","/**\n * @module runtime\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { dynamicCast, nonnull, unsigned } from '../utils/types';\nimport { Rect } from 'math/geometry';\nimport { Features } from 'apps/common/parameters';\nimport { reportLog } from 'apps/common/analytics';\nimport { notifyErrorToUser } from 'error/error-screen';\n\n// WebGL stuff\n\nconst objectVertexShader = `attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 uWorldToViewport;\nuniform mat3 uPoseToWorld;\n\nvarying lowp vec2 vTextureCoord;\n\nvoid main() {\n\tgl_Position = vec4(uWorldToViewport * uPoseToWorld * vec3(aVertexPosition, 1.0), 1.0);\n\tvTextureCoord = aTextureCoord;\n}`;\n\nconst objectFragmentShader = `varying lowp vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nprecision lowp float;\nuniform float uAlpha;\n\nvoid main(void) {\n\tvec4 col = texture2D(uSampler, vTextureCoord);\n\tcol.rgba *= uAlpha;\n\tgl_FragColor = col;\n}`;\n\nconst objectVertexShader2 = `#version 300 es\nin vec2 aVertexPosition;\nin vec2 aTextureCoord;\nin mat3 poseToWorld;\nin float alpha;\n\nuniform mat3 uWorldToViewport;\n\nout lowp vec2 vTextureCoord;\nout float vAlpha;\n\nvoid main() {\n\tgl_Position = vec4(uWorldToViewport * poseToWorld * vec3(aVertexPosition, 1.0), 1.0);\n\tvTextureCoord = aTextureCoord;\n\tvAlpha = alpha;\n}`;\n\nconst objectFragmentShader2 = `#version 300 es\nprecision lowp float;\n\nin lowp vec2 vTextureCoord;\nin float vAlpha;\n\nuniform sampler2D uSampler;\n\nout vec4 outColor;\n\nvoid main(void) {\n\tvec4 col = texture(uSampler, vTextureCoord);\n\tcol.rgba *= vAlpha;\n\toutColor = col;\n}`;\n\nconst crossVertexShader = `attribute vec2 aVertexPosition;\n\nuniform mat3 uWorldToViewport;\nuniform vec2 uPosition;\nuniform float uWorldSize;\nuniform vec4 uColor;\n\nvarying lowp vec4 vColor;\n\nvoid main() {\n\tgl_Position = vec4(uWorldToViewport * vec3(uPosition + aVertexPosition * uWorldSize, 1.0), 1.0);\n\tvColor = uColor;\n}`;\n\nconst colorFragmentShader = `varying lowp vec4 vColor;\n\nvoid main(void) {\n\tlowp vec4 col = vColor;\n\tcol.rgb *= col.a;\n\tgl_FragColor = col;\n}`;\n\nconst simpleVertexShare = `attribute vec2 aVertexPosition;\n\nuniform mat3 uWorldToViewport;\nuniform vec4 uColor;\n\nvarying lowp vec4 vColor;\n\nvoid main() {\n\tgl_Position = vec4(uWorldToViewport * vec3(aVertexPosition, 1.0), 1.0);\n\tvColor = uColor;\n}`;\n\nconst objectTextureCoordArrayOrig = [\n\t0, 1, 0, 0,\n\t1, 1, 1, 0\n];\n\ntype ArrayIsh = Float32Array | number[];\ntype TextureMapKey = object | symbol;\ntype TextureMap = Map;\n\ntype NonWebGLBufferNames = {\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n\t[K in keyof T]: T[K] extends Float32Array | number | Function ? K : never;\n}[keyof T];\ntype EmptyInterfaceNames = Exclude>;\n\nclass ObjectGL1State {\n\tconstructor(\n\t\tpublic objectUPoseToWorld: WebGLUniformLocation,\n\t\tpublic objectUAlpha: WebGLUniformLocation\n\t) {}\n}\nclass ObjectGL2State {\n\tposeToWorldBuffer: WebGLBuffer | null = null;\n\tposeToWorldData: Float32Array = new Float32Array(32 * 9);\n\talphaBuffer: WebGLBuffer | null = null;\n\talphaData: Float32Array = new Float32Array(32);\n\tinstanceCount = 0;\n\n\tconstructor(public poseToWorldLoc: number, public alphaLoc: number) {}\n\n\tpushInstance(poseToWorld: ArrayIsh, alpha: number) {\n\t\tif (this.instanceCount >= this.alphaData.length) {\n\t\t\t// array is full, double size and copy elements\n\t\t\tconst newPoseToWorldData = new Float32Array(this.poseToWorldData.length * 2);\n\t\t\tnewPoseToWorldData.set(this.poseToWorldData);\n\t\t\tthis.poseToWorldData = newPoseToWorldData;\n\t\t\tconst newAlphaData = new Float32Array(this.alphaData.length * 2);\n\t\t\tnewAlphaData.set(this.alphaData);\n\t\t\tthis.alphaData = newAlphaData\n\t\t}\n\t\tthis.poseToWorldData.set(poseToWorld, this.instanceCount * 9)\n\t\tthis.alphaData[this.instanceCount] = alpha;\n\t\tthis.instanceCount += 1;\n\t}\n\n\tclearInstances() {\n\t\tthis.instanceCount = 0;\n\t}\n\n\tsetupPoseToWorldBuffer(gl: WebGL2RenderingContext) {\n\t\tthis.setupBufferForInstances(gl, this.poseToWorldLoc, this.poseToWorldData, 'poseToWorldBuffer', 9, 3);\n\t}\n\n\tsetupAlphaBuffer(gl: WebGL2RenderingContext) {\n\t\tthis.setupBufferForInstances(gl, this.alphaLoc, this.alphaData, 'alphaBuffer', 1, 1);\n\t}\n\n\tprivate setupBufferForInstances>(\n\t\tgl: WebGL2RenderingContext,\n\t\tbaseLoc: number,\n\t\tinternalBuffer: Float32Array,\n\t\tglBufferName: BK,\n\t\tfloatCount: number,\n\t\tattribCount: number\n\t) {\n\t\tif (this[glBufferName] === null) {\n\t\t\tthis[glBufferName] = nonnull(gl.createBuffer(), 'Cannot create WebGL buffer');\n\t\t}\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, this[glBufferName]);\n\t\tconst bufferView = new Float32Array(internalBuffer.buffer, 0, this.instanceCount * floatCount)\n\t\tgl.bufferData(gl.ARRAY_BUFFER,\n\t\t\tbufferView,\n\t\t\tgl.DYNAMIC_DRAW\n\t\t);\n\t\tconst stride = floatCount * 4;\n\t\tconst shift = floatCount / attribCount;\n\t\tfor (let i = 0; i < attribCount; ++i) {\n\t\t\tconst loc = baseLoc + i;\n\t\t\tgl.enableVertexAttribArray(loc);\n\t\t\tconst offset = i * shift * 4; // shift floats per row, 4 bytes per float\n\t\t\tgl.vertexAttribPointer(\n\t\t\t\tloc, // location\n\t\t\t\tshift, // size (num values to pull from buffer per iteration)\n\t\t\t\tgl.FLOAT, // type of data in buffer\n\t\t\t\tfalse, // normalize\n\t\t\t\tstride, // stride, num bytes to advance to get to next set of values\n\t\t\t\toffset // offset in buffer\n\t\t\t);\n\t\t\t// this line says this attribute only changes for each 1 instance\n\t\t\tgl.vertexAttribDivisor(loc, 1);\n\t\t}\n\t}\n}\n\nexport class GLState {\n\t// main GL state\n\treadonly gl: WebGLRenderingContext;\n\t// object and UI rendering\n\tprivate objectProgram!: WebGLProgram;\n\tprivate objectUWorldToViewport!: WebGLUniformLocation;\n\tprivate objectUSampler!: WebGLUniformLocation;\n\tprivate objectStateVer!: ObjectGL1State | ObjectGL2State;\n\tprivate objectVertexBuffer!: WebGLBuffer;\n\tprivate objectAVertexPosition!: number;\n\tprivate objectTextureCoordBuffer!: WebGLBuffer;\n\tprivate objectATextureCoord!: number;\n\tprivate objectTextureCoordArray = objectTextureCoordArrayOrig;\n\t// cross rendering\n\tprivate crossProgram!: WebGLProgram;\n\tprivate crossUWorldToViewport!: WebGLUniformLocation;\n\tprivate crossUPosition!: WebGLUniformLocation;\n\tprivate crossUWorldSize!: WebGLUniformLocation;\n\tprivate crossUColor!: WebGLUniformLocation;\n\tprivate crossVertexBuffer!: WebGLBuffer;\n\tprivate crossAVertexPosition!: number;\n\t// world bounds\n\tprivate boundsProgram!: WebGLProgram;\n\tprivate boundsUWorldToViewport!: WebGLUniformLocation;\n\tprivate boundsUColor!: WebGLUniformLocation;\n\tprivate boundsVertexBuffer!: WebGLBuffer;\n\tprivate boundsAVertexPosition!: number;\n\t// texture data cache for re-creation upon context restoration\n\tprivate textures: TextureMap = new Map();\n\t// other caches to reduce API calls for renderObject\n\tprivate lastBoundTexture: WebGLTexture | null = null;\n\tprivate lastPushedAlpha: number | null = null;\n\n\tconstructor(canvas: HTMLCanvasElement) {\n\t\tconst gl2 = Features.forceGL1 ? null : canvas.getContext('webgl2', { alpha: false });\n\t\tthis.gl = gl2 || notifyErrorToUser('Getting WebGL context failed (consider restarting your browser)', nonnull, canvas.getContext('webgl', { alpha: false }));\n\t\tconst webGL2 = gl2 !== null;\n\t\tconsole.debug(`Initialising WebGL${webGL2 ? '2' : ''} context`);\n\t\tconst dpr = window.devicePixelRatio || 1;\n\t\tconst gl = this.gl;\n\t\tconst debugInfo = gl.getExtension('WEBGL_debug_renderer_info');\n\t\treportLog('initWebGL', {\n\t\t\tver: webGL2 ? 2 : 1,\n\t\t\tdpr,\n\t\t\tMAX_VERTEX_ATTRIBS: gl.getParameter(gl.MAX_VERTEX_ATTRIBS),\n\t\t\tMAX_VARYING_VECTORS: gl.getParameter(gl.MAX_VARYING_VECTORS),\n\t\t\tMAX_TEXTURE_SIZE: gl.getParameter(gl.MAX_TEXTURE_SIZE),\n\t\t\t...(gl2 !== null && {\n\t\t\t\tMAX_ARRAY_TEXTURE_LAYERS: gl2.getParameter(gl2.MAX_ARRAY_TEXTURE_LAYERS)\n\t\t\t}),\n\t\t\t...(debugInfo !== null ? {\n\t\t\t\tVENDOR: gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL),\n\t\t\t\tRENDERER: gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)\n\t\t\t} : {\n\t\t\t\tVENDOR: gl.getParameter(gl.VENDOR),\n\t\t\t\tRENDERER: gl.getParameter(gl.RENDERER)\n\t\t\t})\n\t\t});\n\t\tthis.init(webGL2);\n\t\t/* // Torture test code that forces a context lost every 5 seconds\n\t\twindow.setInterval(() => {\n\t\t\tconst ext = nonnull(this.gl.getExtension('WEBGL_lose_context'));\n\t\t\text.loseContext();\n\t\t\twindow.setTimeout(() => ext.restoreContext(), 1000);\n\t\t}, 5000);*/\n\t}\n\n\tprivate init(isGl2: boolean) {\n\t\tconst gl = this.gl;\n\t\tconst dpr = window.devicePixelRatio || 1;\n\t\tgl.lineWidth(2 * dpr);\n\n\t\t// object program and data\n\t\tconst objectProgram = isGl2 ?\n\t\t\tthis.compileProgram(objectVertexShader2, objectFragmentShader2) :\n\t\t\tthis.compileProgram(objectVertexShader, objectFragmentShader)\n\t\t;\n\t\tthis.objectProgram = objectProgram;\n\t\tthis.objectUWorldToViewport = nonnull(gl.getUniformLocation(objectProgram, 'uWorldToViewport'));\n\t\tthis.objectUSampler = nonnull(gl.getUniformLocation(objectProgram, 'uSampler'));\n\t\tif (isGl2) {\n\t\t\tthis.objectStateVer = new ObjectGL2State(\n\t\t\t\tunsigned(gl.getAttribLocation(objectProgram, 'poseToWorld')),\n\t\t\t\tunsigned(gl.getAttribLocation(objectProgram, 'alpha'))\n\t\t\t);\n\t\t} else {\n\t\t\tthis.objectStateVer = new ObjectGL1State(\n\t\t\t\tnonnull(gl.getUniformLocation(objectProgram, 'uPoseToWorld')),\n\t\t\t\tnonnull(gl.getUniformLocation(objectProgram, 'uAlpha'))\n\t\t\t);\n\t\t}\n\t\tthis.objectVertexBuffer = this.createBuffer([\n\t\t\t0, 1, 0, 0,\n\t\t\t1, 1, 1, 0\n\t\t]);\n\t\tthis.objectAVertexPosition = unsigned(gl.getAttribLocation(objectProgram, 'aVertexPosition'));\n\t\tthis.objectTextureCoordBuffer = this.createBuffer(this.objectTextureCoordArray);\n\t\tthis.objectATextureCoord = unsigned(gl.getAttribLocation(objectProgram, 'aTextureCoord'));\n\n\t\t// cross program and data\n\t\tconst crossProgram = this.compileProgram(crossVertexShader, colorFragmentShader);\n\t\tthis.crossProgram = crossProgram;\n\t\tthis.crossUWorldToViewport = nonnull(gl.getUniformLocation(crossProgram, 'uWorldToViewport'));\n\t\tthis.crossUPosition = nonnull(gl.getUniformLocation(crossProgram, 'uPosition'));\n\t\tthis.crossUWorldSize = nonnull(gl.getUniformLocation(crossProgram, 'uWorldSize'));\n\t\tthis.crossUColor = nonnull(gl.getUniformLocation(crossProgram, 'uColor'));\n\t\tthis.crossVertexBuffer = this.createBuffer([\n\t\t\t-1, 0, 1, 0,\n\t\t\t0, -1, 0, 1\n\t\t]);\n\t\tthis.crossAVertexPosition = unsigned(gl.getAttribLocation(crossProgram, 'aVertexPosition'));\n\n\t\t// world bounds\n\t\tconst boundsProgram = this.compileProgram(simpleVertexShare, colorFragmentShader);\n\t\tthis.boundsProgram = boundsProgram;\n\t\tthis.boundsUWorldToViewport = nonnull(gl.getUniformLocation(boundsProgram, 'uWorldToViewport'));\n\t\tthis.boundsUColor = nonnull(gl.getUniformLocation(boundsProgram, 'uColor'));\n\t\tthis.boundsVertexBuffer = this.createBuffer([\n\t\t\t-1, -1, 1, -1,\n\t\t\t1, 1, -1, 1\n\t\t]);\n\t\tthis.boundsAVertexPosition = unsigned(gl.getAttribLocation(crossProgram, 'aVertexPosition'));\n\t\tgl.useProgram(boundsProgram);\n\t\tgl.uniform4fv(this.boundsUColor, [0, 0, 0.38, 1]);\n\n\t\t// blending\n\t\tgl.enable(gl.BLEND);\n\t\tgl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\t\t// restore textures\n\t\tthis.restoreTextures();\n\t}\n\n\treInit() {\n\t\tthis.init(this.isWebGL2);\n\t}\n\n\tprivate get isWebGL2() {\n\t\treturn this.objectStateVer instanceof ObjectGL2State;\n\t}\n\n\tprivate restoreTextures() {\n\t\tconst newTextures: TextureMap = new Map();\n\t\tfor (const [key, [_texture, data]] of this.textures) {\n\t\t\tnewTextures.set(key, [this.createTexture(data), data]);\n\t\t}\n\t\tthis.textures = newTextures;\n\t}\n\n\tprivate createTexture(data: ImageData) {\n\t\tconst gl = this.gl;\n\t\tconst texture = nonnull(gl.createTexture());\n\t\tgl.bindTexture(gl.TEXTURE_2D, texture);\n\t\tgl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, data);\n\t\tif (this.isWebGL2) {\n\t\t\t// Mipmaps for NPOT textures are only available in WebGL2\n\t\t\tgl.generateMipmap(gl.TEXTURE_2D);\n\t\t}\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\t\tif (this.isWebGL2) {\n\t\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);\n\t\t} else {\n\t\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n\t\t}\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\t\treturn texture;\n\t}\n\n\tloadTexture(key: TextureMapKey, data: ImageData) {\n\t\tconst texture = this.createTexture(data);\n\t\tthis.textures.set(key, [texture, data]);\n\t}\n\n\thasTexture(key: TextureMapKey) {\n\t\treturn this.textures.has(key);\n\t}\n\n\tgetTexture(key: TextureMapKey) {\n\t\treturn this.textures.get(key)?.[0];\n\t}\n\n\tdeleteTexture(key: TextureMapKey) {\n\t\tconst texture = this.textures.get(key);\n\t\tif (texture !== undefined) {\n\t\t\tthis.textures.delete(key);\n\t\t\tthis.gl.deleteTexture(texture[0]);\n\t\t} else {\n\t\t\tconsole.log('Deleting non-existant texture with key', key);\n\t\t}\n\t}\n\n\tdeleteTexturesButKeep(keyToKeep: TextureMapKey) {\n\t\tconst newTextures: TextureMap = new Map();\n\t\tfor (const [key, [texture, imageData]] of this.textures) {\n\t\t\tif (key !== keyToKeep) {\n\t\t\t\tthis.gl.deleteTexture(texture);\n\t\t\t} else {\n\t\t\t\tnewTextures.set(key, [texture, imageData]);\n\t\t\t}\n\t\t}\n\t\tthis.textures = newTextures;\n\t}\n\n\tget textureCount() {\n\t\treturn this.textures.size;\n\t}\n\n\tsetupUITexCoords(coords: number[]) {\n\t\tthis.objectTextureCoordArray = objectTextureCoordArrayOrig.concat(coords);\n\t\tthis.updateBuffer(this.objectTextureCoordBuffer, this.objectTextureCoordArray);\n\t}\n\n\tsetupRenderUI(screenToViewport: ArrayIsh, texture: WebGLTexture) {\n\t\t// assuming this comes after setupRenderObjects\n\t\tconst gl = this.gl;\n\t\t// setup alpha\n\t\tif (this.objectStateVer instanceof ObjectGL1State) {\n\t\t\tgl.uniform1f(this.objectStateVer.objectUAlpha, 1.0);\n\t\t}\n\t\t// setup world matrix\n\t\tgl.uniformMatrix3fv(this.objectUWorldToViewport, false, screenToViewport);\n\t\t// setup texture\n\t\tgl.bindTexture(gl.TEXTURE_2D, texture);\n\t}\n\n\trenderUIElement(normalizedToScreen: ArrayIsh, elementId: number) {\n\t\tconst gl = this.gl;\n\t\t// prepare texture coordinate buffer\n\t\tthis.setupBuffer(this.objectTextureCoordBuffer, this.objectATextureCoord, 32 * (elementId + 1));\n\t\t// draw\n\t\tif (this.objectStateVer instanceof ObjectGL2State) {\n\t\t\tthis.objectStateVer.pushInstance(normalizedToScreen, 1.0);\n\t\t\tthis.setupObjectGL2State(this.objectStateVer);\n\t\t\tconst gl2 = (this.gl as WebGL2RenderingContext);\n\t\t\tgl2.drawArraysInstanced(gl2.TRIANGLE_STRIP, 0, 4, this.objectStateVer.instanceCount);\n\t\t\tthis.objectStateVer.clearInstances();\n\t\t} else {\n\t\t\tgl.uniformMatrix3fv(this.objectStateVer.objectUPoseToWorld, false, normalizedToScreen);\n\t\t\tgl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n\t\t}\n\t}\n\n\tfinishRenderUI() {\n\t\tthis.renderObjectInstances();\n\t}\n\n\tsetupRenderObjects(worldToViewport: ArrayIsh) {\n\t\t// setup program and world matrix\n\t\tconst gl = this.gl;\n\t\tgl.useProgram(this.objectProgram);\n\t\tgl.uniformMatrix3fv(this.objectUWorldToViewport, false, worldToViewport);\n\t\t// prepare vertex position buffer\n\t\tthis.setupBuffer(this.objectVertexBuffer, this.objectAVertexPosition);\n\t\t// prepare texture coordinate buffer\n\t\tthis.setupBuffer(this.objectTextureCoordBuffer, this.objectATextureCoord);\n\t\t// setup texture\n\t\tgl.activeTexture(gl.TEXTURE0);\n\t\tgl.uniform1i(this.objectUSampler, 0);\n\t\t// reset caches\n\t\tthis.lastBoundTexture = null;\n\t\tthis.lastPushedAlpha = null;\n\t}\n\n\trenderObject(spriteToWorld: ArrayIsh, texture: WebGLTexture, alpha: number) {\n\t\t// bind pose and texture, and draw\n\t\tconst gl = this.gl;\n\t\tif (this.objectStateVer instanceof ObjectGL2State) {\n\t\t\tif (texture !== this.lastBoundTexture) {\n\t\t\t\t// Look at: https://webgl2fundamentals.org/webgl/lessons/webgl-instanced-drawing.html\n\t\t\t\tthis.renderObjectInstances();\n\t\t\t\tthis.lastBoundTexture = texture;\n\t\t\t}\n\t\t\tthis.objectStateVer.pushInstance(spriteToWorld, alpha);\n\t\t} else {\n\t\t\tgl.uniformMatrix3fv(this.objectStateVer.objectUPoseToWorld, false, spriteToWorld);\n\t\t\tif (alpha !== this.lastPushedAlpha) {\n\t\t\t\tgl.uniform1f(this.objectStateVer.objectUAlpha, alpha);\n\t\t\t\tthis.lastPushedAlpha = alpha;\n\t\t\t}\n\t\t\tif (texture !== this.lastBoundTexture) {\n\t\t\t\tgl.bindTexture(gl.TEXTURE_2D, texture);\n\t\t\t\tthis.lastBoundTexture = texture;\n\t\t\t}\n\t\t\tgl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n\t\t}\n\t}\n\n\tfinishRenderObjects() {\n\t\tthis.renderObjectInstances();\n\t}\n\n\tprivate setupObjectGL2State(objectState: ObjectGL2State) {\n\t\tconst gl2 = (this.gl as WebGL2RenderingContext);\n\t\t// upload the new matrix data\n\t\tobjectState.setupPoseToWorldBuffer(gl2);\n\t\t// upload the alpha data\n\t\tobjectState.setupAlphaBuffer(gl2);\n\t}\n\n\tprivate renderObjectInstances() {\n\t\t// get relevant state and make sure we are in GL2\n\t\tconst objectState = dynamicCast(ObjectGL2State, this.objectStateVer);\n\t\tif (objectState === null || objectState.instanceCount === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst gl2 = (this.gl as WebGL2RenderingContext);\n\t\tthis.setupObjectGL2State(objectState);\n\t\t// bind texture\n\t\tgl2.bindTexture(gl2.TEXTURE_2D, this.lastBoundTexture);\n\t\t// render instances\n\t\tgl2.drawArraysInstanced(gl2.TRIANGLE_STRIP, 0, 4, objectState.instanceCount);\n\t\t// clear the in-memory array\n\t\tobjectState.clearInstances();\n\t}\n\n\tsetupRenderCross(worldToViewport: ArrayIsh, worldSize: number) {\n\t\t// setup program, world matrix and world size\n\t\tconst gl = this.gl;\n\t\tgl.useProgram(this.crossProgram);\n\t\tgl.uniformMatrix3fv(this.crossUWorldToViewport, false, worldToViewport);\n\t\tgl.uniform1f(this.crossUWorldSize, worldSize);\n\t\t// prepare vertex position buffer\n\t\tthis.setupBuffer(this.crossVertexBuffer, this.crossAVertexPosition);\n\t}\n\n\trenderCross(position: ArrayIsh, color: ArrayIsh) {\n\t\t// bind pose and color, and draw\n\t\tconst gl = this.gl;\n\t\tgl.uniform2fv(this.crossUPosition, position);\n\t\tgl.uniform4fv(this.crossUColor, color);\n\t\tgl.drawArrays(gl.LINES, 0, 4);\n\t}\n\n\tupdateWorldBounds(worldBounds: Rect) {\n\t\tthis.updateBuffer(this.boundsVertexBuffer, [\n\t\t\tworldBounds.topLeft.x, worldBounds.topLeft.y,\n\t\t\tworldBounds.topRight.x, worldBounds.topRight.y,\n\t\t\tworldBounds.bottomRight.x, worldBounds.bottomRight.y,\n\t\t\tworldBounds.bottomLeft.x, worldBounds.bottomLeft.y\n\t\t]);\n\t}\n\n\tsetupRenderWorldBounds(worldToViewport: ArrayIsh) {\n\t\t// setup program, world matrix and world size\n\t\tconst gl = this.gl;\n\t\tgl.useProgram(this.boundsProgram);\n\t\tgl.uniformMatrix3fv(this.boundsUWorldToViewport, false, worldToViewport);\n\t\t// prepare vertex position buffer\n\t\tthis.setupBuffer(this.boundsVertexBuffer, this.boundsAVertexPosition);\n\t}\n\n\trenderWorldBounds() {\n\t\t// draw\n\t\tconst gl = this.gl;\n\t\tgl.drawArrays(gl.LINE_LOOP, 0, 4);\n\t}\n\n\n\tprivate compileShader(source: string, type: number) {\n\t\tconst gl = this.gl;\n\t\tconst shader = nonnull(gl.createShader(type), 'Cannot create WebGL shader');\n\t\tgl.shaderSource(shader, source);\n\t\tgl.compileShader(shader);\n\t\tif (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n\t\t\tconsole.error(\n\t\t\t\t`Error compiling ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader:`,\n\t\t\t\tgl.getShaderInfoLog(shader)\n\t\t\t);\n\t\t\tconsole.warn('source:\\n', source);\n\t\t}\n\t\treturn shader;\n\t}\n\n\n\tprivate compileProgram(vertexShader: string, fragmentShader: string) {\n\t\tconst gl = this.gl;\n\t\tconst program = nonnull(gl.createProgram(), 'Cannot create WebGL program');\n\t\tgl.attachShader(program, this.compileShader(vertexShader, gl.VERTEX_SHADER));\n\t\tgl.attachShader(program, this.compileShader(fragmentShader, gl.FRAGMENT_SHADER));\n\t\tgl.linkProgram(program);\n\t\tif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n\t\t\tconst errorMessage = `Error linking shader program: ${gl.getProgramInfoLog(program)}`;\n\t\t\tconsole.error(errorMessage);\n\t\t\tthrow new Error(errorMessage);\n\t\t}\n\t\treturn program;\n\t}\n\n\n\tprivate createBuffer(data: number[]) {\n\t\tconst gl = this.gl;\n\t\tconst buffer = nonnull(gl.createBuffer(), 'Cannot create WebGL buffer');\n\t\tthis.updateBuffer(buffer, data);\n\t\treturn buffer;\n\t}\n\n\n\tprivate updateBuffer(buffer: WebGLBuffer, data: number[]) {\n\t\tconst gl = this.gl;\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n\t\tgl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);\n\t}\n\n\n\tprivate setupBuffer(buffer: WebGLBuffer, attribute: number, offset = 0) {\n\t\tconst gl = this.gl;\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n\t\tgl.enableVertexAttribArray(attribute);\n\t\tgl.vertexAttribPointer(attribute, 2, gl.FLOAT, false, 0, offset);\n\t}\n}\n","/**\n * @module runtime\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { dynamicCast } from 'utils/types';\nimport { isBitSet, setBitValue } from 'utils/flags';\nimport { ButtonIndex, keyCodeToInputNumber, numpadCodeToInputNumber } from 'blocks/conditions/input/input-block';\nimport { applyToConstArrayIfLargeEnough } from 'utils/array-types';\n\nexport const GamepadAngleThreshold = 0.4;\n\nexport class InputSource {\n\tlastState = 0;\n\tcurState = 0;\n\tretryGame = false;\n\tstopGame = false;\n\n\tconstructor(public readonly name: string) {\n\t}\n\n\tinit() {\n\t\tthis.lastState = 0;\n\t\tthis.curState = 0;\n\t\tthis.retryGame = false;\n\t\tthis.stopGame = false;\n\t}\n\n\tcheck() { }\n\n\tstoreCurAsLast() {\n\t\tthis.lastState = this.curState;\n\t}\n\n\tisButtonActive(button: ButtonIndex) {\n\t\treturn isBitSet(this.curState, button);\n\t}\n\n\tsetButtonActive(button: ButtonIndex, active: boolean) {\n\t\tthis.curState = setBitValue(this.curState, button, active);\n\t}\n\n\tisButtonActivated(button: ButtonIndex) {\n\t\tconst last = isBitSet(this.lastState, button);\n\t\tconst cur = isBitSet(this.curState, button);\n\t\treturn cur && !last;\n\t}\n\n\tisButtonDeactivated(button: ButtonIndex) {\n\t\tconst last = isBitSet(this.lastState, button);\n\t\tconst cur = isBitSet(this.curState, button);\n\t\treturn !cur && last;\n\t}\n\n\tisAnyButtonActive() {\n\t\treturn this.curState !== 0;\n\t}\n\n\ttoString() {\n\t\treturn `(${this.curState}, ${this.lastState}, ${this.retryGame}, ${this.stopGame})`;\n\t}\n}\n\nexport class Inputs {\n\tsources: InputSource[] = [];\n\tgamepads = navigator.getGamepads ? navigator.getGamepads() : [];\n\tprivate gamepadConnectedListener?: (event: GamepadEvent) => void;\n\tprivate gamepadDisconnectedListener?: (event: GamepadEvent) => void;\n\n\tinit() {\n\t\tthis.sources.map((inputSource) => inputSource.init());\n\t}\n\n\tcheck() {\n\t\t// We have to scan gamepads at each step because chrome only provides\n\t\t// an instant snapshot to the user.\n\t\tthis.scanGamepads();\n\t\tthis.sources.map((inputSource) => inputSource.check());\n\t}\n\n\tstoreCurAsLast() {\n\t\tthis.sources.map((inputSource) => inputSource.storeCurAsLast());\n\t}\n\n\tmerge() {\n\t\tconst merged = new InputSource('merged');\n\t\t[merged.lastState, merged.curState, merged.retryGame, merged.stopGame] = this.sources.reduce(\n\t\t\t(states, inputSource) => [\n\t\t\t\tinputSource.lastState | states[0],\n\t\t\t\tinputSource.curState | states[1],\n\t\t\t\tinputSource.retryGame || states[2],\n\t\t\t\tinputSource.stopGame || states[3]\n\t\t\t],\n\t\t\t[0, 0, false, false] as [number, number, boolean, boolean]\n\t\t);\n\t\treturn merged;\n\t}\n\n\tscanGamepads() {\n\t\tthis.gamepads = navigator.getGamepads ? navigator.getGamepads() : [];\n\t}\n\n\tmonitorGamepads() {\n\t\t// setup callbacks\n\t\tthis.gamepadConnectedListener = this.gamepadConnected.bind(this);\n\t\twindow.addEventListener('gamepadconnected', this.gamepadConnectedListener);\n\t\tthis.gamepadDisconnectedListener = this.gamepadDisconnected.bind(this);\n\t\twindow.addEventListener('gamepaddisconnected', this.gamepadDisconnectedListener);\n\t\t// scan existing ones\n\t\tconst gamepads = navigator.getGamepads ? navigator.getGamepads() : [];\n\t\tfor (const gamepad of gamepads) {\n\t\t\tif (gamepad !== null) {\n\t\t\t\tthis.addGamepad(gamepad);\n\t\t\t}\n\t\t}\n\t}\n\n\tignoreGamepads() {\n\t\t// disable callbacks\n\t\tif (this.gamepadConnectedListener) {\n\t\t\twindow.removeEventListener('gamepadconnected', this.gamepadConnectedListener);\n\t\t}\n\t\tif (this.gamepadDisconnectedListener) {\n\t\t\twindow.removeEventListener('gamepaddisconnected', this.gamepadDisconnectedListener);\n\t\t}\n\t\t// no need to remove gamepads, because the input array will be re-created on show() in setupInputs()\n\t}\n\n\ttoString() {\n\t\tconst sourcesText = this.sources.map((source) => source.toString()).join(', ');\n\t\treturn `Inputs: ${this.sources.length} sources: ${sourcesText}`;\n\t}\n\n\tprivate gamepadConnected(event: GamepadEvent) {\n\t\t// console.log('gamepad connected', event.gamepad);\n\t\tthis.addGamepad(event.gamepad);\n\t}\n\n\n\tprivate gamepadDisconnected(event: GamepadEvent) {\n\t\t// console.log('gamepad disconnected', event.gamepad);\n\t\tthis.removeGamepads(event.gamepad);\n\t}\n\n\n\tprivate addGamepad(gamepad: Gamepad) {\n\t\t// check if it already exists, if so ignore\n\t\tfor (const input of this.sources) {\n\t\t\tconst gamepadInput = dynamicCast(GamepadInputSource, input);\n\t\t\tif (gamepadInput !== null) {\n\t\t\t\tif (gamepad.index === gamepadInput.index) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// add\n\t\tthis.sources.push(new GamepadInputSource(gamepad));\n\t\tconsole.info('Created gamepad input', gamepad.id);\n\t}\n\n\n\tprivate removeGamepads(gamepad?: Gamepad) {\n\t\tthis.sources = this.sources.filter(\n\t\t\t(input: InputSource) => {\n\t\t\t\tconst gamepadInput = dynamicCast(GamepadInputSource, input);\n\t\t\t\tif (gamepadInput !== null && (gamepad === undefined || gamepadInput.index === gamepad.index)) {\n\t\t\t\t\tconsole.info('Removed gamepad input', gamepadInput.name);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n}\n\nclass GamepadInputSource extends InputSource {\n\tpublic readonly index: number;\n\n\tconstructor(gamepad: Gamepad) {\n\t\tsuper(gamepad.id);\n\t\tthis.index = gamepad.index;\n\t}\n\n\tcheck() {\n\t\tsuper.check();\n\t\tconst gamepads = navigator.getGamepads ? navigator.getGamepads() : [];\n\t\tfor (const gp of gamepads) {\n\t\t\tif (gp === null || gp.index !== this.index) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// see https://w3c.github.io/gamepad/ for button mapping\n\t\t\t// game buttons\n\t\t\tapplyToConstArrayIfLargeEnough(gp.axes, 2, (axes) => {\n\t\t\t\tconst y = axes[1];\n\t\t\t\tthis.setButtonActive(0, y < -GamepadAngleThreshold);\n\t\t\t\tthis.setButtonActive(1, y > GamepadAngleThreshold);\n\t\t\t\tconst x = axes[0];\n\t\t\t\tthis.setButtonActive(2, x < -GamepadAngleThreshold);\n\t\t\t\tthis.setButtonActive(3, x > GamepadAngleThreshold);\n\t\t\t});\n\t\t\tapplyToConstArrayIfLargeEnough(gp.buttons, 2, (buttons) => {\n\t\t\t\tthis.setButtonActive(4, buttons[0].pressed);\n\t\t\t\tthis.setButtonActive(5, buttons[1].pressed);\n\t\t\t});\n\t\t\tapplyToConstArrayIfLargeEnough(gp.buttons, 4, (buttons) => {\n\t\t\t\tthis.setButtonActive(6, buttons[2].pressed);\n\t\t\t\tthis.setButtonActive(7, buttons[3].pressed);\n\t\t\t});\n\t\t\t// game over actions\n\t\t\tthis.stopGame = gp.buttons[8]?.pressed ?? false;\n\t\t\tthis.retryGame = gp.buttons[9]?.pressed ?? false;\n\t\t\t// const value = gp.buttons.reduce((p, v, i) => p | ((v.pressed ? 1 : 0) << i), 0);\n\t\t\t// console.log('gp check', this.index, value);\n\t\t}\n\t}\n}\n\nexport class KeyboardInputSource extends InputSource {\n\tconstructor() {\n\t\tsuper('keyboard');\n\t}\n\n\tprocessKeyDown(event: KeyboardEvent) {\n\t\t// We filter out numpad entries because their `which` values overlap with main keys\n\t\tif (event.code.startsWith('Numpad')) {\n\t\t\treturn;\n\t\t}\n\t\tconst index = keyCodeToInputNumber(event.which);\n\t\tif (index !== null) {\n\t\t\tthis.setButtonActive(index, true);\n\t\t} else if (event.which === 27) {\n\t\t\tthis.stopGame = true;\n\t\t} else if (event.which === 13) {\n\t\t\tthis.retryGame = true;\n\t\t}\n\t}\n\n\tprocessKeyUp(event: KeyboardEvent) {\n\t\t// We filter out numpad entries because their `which` values overlap with main keys\n\t\tif (event.code.startsWith('Numpad')) {\n\t\t\treturn;\n\t\t}\n\t\tconst index = keyCodeToInputNumber(event.which);\n\t\tif (index !== null) {\n\t\t\tthis.setButtonActive(index, false);\n\t\t} else if (event.which === 27) {\n\t\t\tthis.stopGame = false;\n\t\t} else if (event.which === 13) {\n\t\t\tthis.retryGame = false;\n\t\t}\n\t}\n}\n\nexport class NumpadInputSource extends InputSource {\n\tconstructor() {\n\t\tsuper('numpad');\n\t}\n\n\tprocessKeyDown(event: KeyboardEvent) {\n\t\tconst index = numpadCodeToInputNumber(event.code);\n\t\tif (index !== null) {\n\t\t\tthis.setButtonActive(index, true);\n\t\t}\n\t}\n\n\tprocessKeyUp(event: KeyboardEvent) {\n\t\tconst index = numpadCodeToInputNumber(event.code);\n\t\tif (index !== null) {\n\t\t\tthis.setButtonActive(index, false);\n\t\t}\n\t}\n}\n\nexport const enum Button {\n\tRetry = -2,\n\tStop = -1,\n\tUp = 0,\n\tDown,\n\tLeft,\n\tRight,\n\tA,\n\tB,\n\tX,\n\tY\n}\n","/**\n * @module runtime\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { Vector2 } from 'math/linalg';\nimport { createFixedSizeFloat32Array, FixedSizeArray, FixedSizeFloat32Array } from 'utils/array-types';\n\n// simple helper matrix function for WebGL, column major\n\nexport type Vec3 = FixedSizeFloat32Array<3>;\nexport type Vec3Like = Readonly>;\nexport type Mat3 = FixedSizeFloat32Array<9>;\nexport type Mat3Like = Readonly>;\n\nexport function createVec3() {\n\treturn createFixedSizeFloat32Array(3);\n}\n\nexport function createMat3() {\n\treturn createFixedSizeFloat32Array(9);\n}\n\nexport function scalarToVec3Homo(x: number, y: number): Vec3 {\n\tconst input = createFixedSizeFloat32Array(3);\n\tinput[0] = x;\n\tinput[1] = y;\n\tinput[2] = 1;\n\treturn input;\n}\n\nexport function vector2ToVec3Homo(vector2: Vector2) {\n\treturn scalarToVec3Homo(vector2.x, vector2.y);\n}\n\nexport function vec3HomoToVector2(vec3: Vec3Like): Vector2 {\n\treturn new Vector2(vec3[0] / vec3[2], vec3[1] / vec3[2]);\n}\n\nexport function multMat3Vec3(mat3: Mat3Like, vec3: Vec3Like): Vec3 {\n\tconst output = createFixedSizeFloat32Array(3);\n\tfor (let i = 0; i < 3; ++i) {\n\t\tlet v = 0;\n\t\tfor (let j = 0; j < 3; ++j) {\n\t\t\tconst index = j * 3 + i;\n\t\t\tv += vec3[j]! * mat3[index]!;\n\t\t}\n\t\toutput[i] = v;\n\t}\n\treturn output;\n}\n\nexport function multMat3Mat3(a: Mat3Like, b: Mat3Like): Mat3 {\n\tconst output = createFixedSizeFloat32Array(9);\n\tfor (let col = 0; col < 3; ++col) {\n\t\tfor (let row = 0; row < 3; ++row) {\n\t\t\tlet v = 0;\n\t\t\tfor (let i = 0; i < 3; ++i) {\n\t\t\t\tv += a[i * 3 + row]! * b[col * 3 + i]!;\n\t\t\t}\n\t\t\toutput[col * 3 + row] = v;\n\t\t}\n\t}\n\treturn output;\n}\n\nexport function invertMat3(mat3: Mat3Like): Mat3 {\n\t// from: https://en.wikipedia.org/wiki/Invertible_matrix#Inversion_of_3_%C3%97_3_matrices\n\tconst a = mat3[0];\n\tconst d = mat3[1];\n\tconst g = mat3[2];\n\tconst b = mat3[3];\n\tconst e = mat3[4];\n\tconst h = mat3[5];\n\tconst c = mat3[6];\n\tconst f = mat3[7];\n\tconst i = mat3[8];\n\tconst det = a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g);\n\tconst div = 1 / det;\n\tconst output = createFixedSizeFloat32Array(9);\n\toutput[0] = div * (e * i - f * h);\n\toutput[1] = div * (f * g - d * i);\n\toutput[2] = div * (d * h - e * g);\n\toutput[3] = div * (c * h - b * i);\n\toutput[4] = div * (a * i - c * g);\n\toutput[5] = div * (b * g - a * h);\n\toutput[6] = div * (b * f - c * e);\n\toutput[7] = div * (c * d - a * f);\n\toutput[8] = div * (a * e - b * d);\n\treturn output;\n}\n\nexport function identMat3(): Mat3 {\n\tconst output = createFixedSizeFloat32Array(9);\n\toutput[0] = 1;\n\toutput[4] = 1;\n\toutput[8] = 1;\n\treturn output;\n}\n","/**\n * @module runtime\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { Vec2 } from 'planck-js';\nimport { MinSizeArray } from 'utils/array-types';\n\nexport function vecToVec2(vec: MinSizeArray) {\n\treturn new Vec2(vec[0], vec[1]);\n}\n","/**\n * @module runtime\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { FixedSizeFloat32Array } from 'utils/array-types';\nimport { SimilarityTransform } from 'math/linalg';\nimport { createOffscreenCanvasAnd2DContext } from 'utils/canvas';\nimport { Rect } from 'math/geometry';\nimport { AnyCanvasRenderingContext2D } from 'imgui/imgui-types';\nimport { layoutTextWithSizer } from 'imgui/text-layout';\n\nexport const enum HorizontalTextAlignment {\n\tLeft,\n\tCenter,\n\tRight,\n}\n\nexport const enum VerticalTextAlignment {\n\tTop,\n\tMiddle,\n\tBottom,\n}\n\nexport const DEFAULT_CANVAS_RESOLUTION = 100;\n\nexport class CanvasAttributes {\n\ttextColor = '#000000';\n\ttextHorizontalAlignment = HorizontalTextAlignment.Center;\n\ttextVerticalAlignment = VerticalTextAlignment.Middle;\n\tstrokeColor = '#000000';\n\tfillColor = '#ffffff';\n\tfontSize = 20;\n\tresolution = 100;\n}\n\nexport class CanvasOverlay {\n\tpublic readonly textureKey: symbol;\n\tpublic readonly pixelToPose: FixedSizeFloat32Array<9>;\n\tpublic readonly ctx: AnyCanvasRenderingContext2D;\n\n\tconstructor(resolution: number, boundingRect: Rect) {\n\t\tthis.textureKey = Symbol('text-overlay');\n\n\t\t// Honour the resolution of parent and centering in its AABB.\n\t\tconst w = boundingRect.width * resolution | 0;\n\t\tconst h = boundingRect.height * resolution | 0;\n\t\tif (w <= 0 || h <= 0) {\n\t\t\tconsole.error('CanvasOverlay: renderText called with invalid sizes', w, h);\n\t\t\tthrow new Error('CanvasOverlay: renderText called with invalid sizes');\n\t\t}\n\t\tif (w > 2048 || h > 2048) {\n\t\t\tconsole.error('CanvasOverlay: renderText called with too large sizes', w, h);\n\t\t\tthrow new Error('CanvasOverlay: renderText called with too large sizes');\n\t\t}\n\n\t\t// Compute pose matrix, similary as for main sprite in RuntimeScreen::render.\n\t\tconst scaling = 1 / resolution;\n\t\tconst translation = boundingRect.topLeft.multScalar(1);\n\t\tconst pixelToPose = SimilarityTransform.scalingTranslation(scaling, translation).toGLMat3();\n\n\t\t// Our vertex buffer uses unit square, so we need to scale it.\n\t\tpixelToPose[0] *= w;\n\t\tpixelToPose[1] *= w;\n\t\tpixelToPose[2] *= w;\n\t\tpixelToPose[3] *= h;\n\t\tpixelToPose[4] *= h;\n\t\tpixelToPose[5] *= h;\n\n\t\tthis.pixelToPose = pixelToPose;\n\n\t\tthis.ctx = createOffscreenCanvasAnd2DContext(w, h).ctx;\n\t}\n\n\tget width() {\n\t\treturn this.ctx.canvas.width;\n\t}\n\n\tget height() {\n\t\treturn this.ctx.canvas.height;\n\t}\n\n\tgetImageData() {\n\t\treturn this.ctx.getImageData(0, 0, this.width, this.height);\n\t}\n}\n\nexport abstract class CanvasRenderAction {\n\tpublic abstract render(overlay: CanvasOverlay, attr: CanvasAttributes): void;\n};\n\nexport class ClearCanvas extends CanvasRenderAction {\n\tpublic render(overlay: CanvasOverlay, attr: CanvasAttributes) {\n\t\t// do nothing\n\t}\n}\n\nexport class DrawText extends CanvasRenderAction {\n\tconstructor(public text: string) {\n\t\tsuper();\n\t}\n\n\tpublic render(overlay: CanvasOverlay, attr: CanvasAttributes) {\n\t\tconst size = attr.fontSize;\n\t\tconst ctx = overlay.ctx;\n\t\tctx.font = `${size}px \"Roboto\"`;\n\t\tctx.textAlign = 'center';\n\t\tctx.textBaseline = 'middle';\n\t\tctx.fillStyle = attr.textColor;\n\t\tconst sizer = (text: string) => ctx.measureText(text).width;\n\t\tconst layout = layoutTextWithSizer(this.text, sizer, overlay.width);\n\t\tconst lineHeight = size * 1.2;\n\t\tlet y: number;\n\t\tswitch (attr.textVerticalAlignment) {\n\t\t\tcase VerticalTextAlignment.Top:\n\t\t\t\ty = 0;\n\t\t\t\tctx.textBaseline = 'top';\n\t\t\t\tbreak;\n\t\t\tcase VerticalTextAlignment.Middle:\n\t\t\t\ty = (overlay.height - (layout.length - 1) * lineHeight) / 2;\n\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\tbreak;\n\t\t\tcase VerticalTextAlignment.Bottom:\n\t\t\t\ty = overlay.height - (layout.length - 1) * lineHeight;\n\t\t\t\tctx.textBaseline = 'bottom';\n\t\t\t\tbreak;\n\t\t}\n\t\tlayout.forEach(([line, _], i) => {\n\t\t\tlet x;\n\t\t\tswitch (attr.textHorizontalAlignment) {\n\t\t\t\tcase HorizontalTextAlignment.Left:\n\t\t\t\t\tx = 0;\n\t\t\t\t\tctx.textAlign = 'left';\n\t\t\t\t\tbreak;\n\t\t\t\tcase HorizontalTextAlignment.Center:\n\t\t\t\t\tx = overlay.width / 2;\n\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\tbreak;\n\t\t\t\tcase HorizontalTextAlignment.Right:\n\t\t\t\t\tx = overlay.width;\n\t\t\t\t\tctx.textAlign = 'right';\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tctx.fillText(line, x, y + i * lineHeight);\n\t\t});\n\t}\n}\n\nexport class DrawLine extends CanvasRenderAction {\n\tconstructor(public x1: number, public y1: number, public x2: number, public y2: number) {\n\t\tsuper();\n\t}\n\n\tpublic render(overlay: CanvasOverlay, attr: CanvasAttributes) {\n\t\tconst ctx = overlay.ctx;\n\t\tctx.strokeStyle = attr.strokeColor;\n\t\tctx.lineWidth = 1;\n\t\tctx.beginPath();\n\t\tctx.moveTo(this.x1, this.y1);\n\t\tctx.lineTo(this.x2, this.y2);\n\t\tctx.stroke();\n\t}\n}\n\nexport class DrawRect extends CanvasRenderAction {\n\tconstructor(public x: number, public y: number, public width: number, public height: number) {\n\t\tsuper();\n\t}\n\n\tpublic render(overlay: CanvasOverlay, attr: CanvasAttributes) {\n\t\tconst ctx = overlay.ctx;\n\t\tctx.strokeStyle = attr.strokeColor;\n\t\tctx.lineWidth = 1;\n\t\tctx.strokeRect(this.x, this.y, this.width, this.height);\n\t}\n}\n\nexport class FillRect extends CanvasRenderAction {\n\tconstructor(public x: number, public y: number, public width: number, public height: number) {\n\t\tsuper();\n\t}\n\n\tpublic render(overlay: CanvasOverlay, attr: CanvasAttributes) {\n\t\tconst ctx = overlay.ctx;\n\t\tctx.fillStyle = attr.fillColor;\n\t\tctx.fillRect(this.x, this.y, this.width, this.height);\n\t}\n}\n\nexport class DrawEllipse extends CanvasRenderAction {\n\tconstructor(public x: number, public y: number, public rx: number, public ry: number) {\n\t\tsuper();\n\t}\n\n\tpublic render(overlay: CanvasOverlay, attr: CanvasAttributes) {\n\t\tconst ctx = overlay.ctx;\n\t\tctx.strokeStyle = attr.strokeColor;\n\t\tctx.lineWidth = 1;\n\t\tctx.beginPath();\n\t\tctx.ellipse(this.x, this.y, this.rx, this.ry, 0, 0, 2 * Math.PI);\n\t\tctx.stroke();\n\t}\n}\n\nexport class FillEllipse extends CanvasRenderAction {\n\tconstructor(public x: number, public y: number, public rx: number, public ry: number) {\n\t\tsuper();\n\t}\n\n\tpublic render(overlay: CanvasOverlay, attr: CanvasAttributes) {\n\t\tconst ctx = overlay.ctx;\n\t\tctx.fillStyle = attr.fillColor;\n\t\tctx.beginPath();\n\t\tctx.ellipse(this.x, this.y, this.rx, this.ry, 0, 0, 2 * Math.PI);\n\t\tctx.fill();\n\t}\n}\n\nexport class SetFontSize extends CanvasRenderAction {\n\tconstructor(public size: number) {\n\t\tsuper();\n\t}\n\n\tpublic render(_: CanvasOverlay, attr: CanvasAttributes) {\n\t\tattr.fontSize = this.size;\n\t}\n}\n\nexport class SetTextAlignment extends CanvasRenderAction {\n\tconstructor(\n\t\tpublic horizontalAlignment: HorizontalTextAlignment,\n\t\tpublic verticalAlignment: VerticalTextAlignment\n\t) {\n\t\tsuper();\n\t}\n\n\tpublic render(_: CanvasOverlay, attr: CanvasAttributes) {\n\t\tattr.textHorizontalAlignment = this.horizontalAlignment;\n\t\tattr.textVerticalAlignment = this.verticalAlignment;\n\t}\n}\n\nexport class SetTextColor extends CanvasRenderAction {\n\tconstructor(public color: string) {\n\t\tsuper();\n\t}\n\n\tpublic render(_: CanvasOverlay, attr: CanvasAttributes) {\n\t\tattr.textColor = this.color;\n\t}\n}\n\nexport class SetStrokeColor extends CanvasRenderAction {\n\tconstructor(public color: string) {\n\t\tsuper();\n\t}\n\n\tpublic render(_: CanvasOverlay, attr: CanvasAttributes) {\n\t\tattr.strokeColor = this.color;\n\t}\n}\n\nexport class SetFillColor extends CanvasRenderAction {\n\tconstructor(public color: string) {\n\t\tsuper();\n\t}\n\n\tpublic render(_: CanvasOverlay, attr: CanvasAttributes) {\n\t\tattr.fillColor = this.color;\n\t}\n}","/**\n * @module runtime\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { reportWarning } from 'apps/common/analytics';\nimport { Parameters } from 'apps/common/parameters';\n\ninterface LLM {\n\tnewConversation(systemMessage: string): boolean;\n\task(prompt: string): boolean;\n\thasResponse(): boolean;\n\tgetResponse(): [string, boolean] | null;\n\tclearReadStates(): void;\n}\n\nclass FakeLLM implements LLM {\n\tnewConversation() {\n\t\t// do nothing\n\t\treturn false;\n\t}\n\n\task(_prompt: string) {\n\t\t// do nothing\n\t\treturn false;\n\t}\n\n\thasResponse(): boolean {\n\t\treturn false;\n\t}\n\n\tgetResponse() {\n\t\treturn null;\n\t}\n\n\tclearReadStates() {\n\t\t// do nothing\n\t}\n}\n\ntype MessageRole = 'user' | 'assistant' | 'system';\n\ninterface Message {\n\trole: MessageRole;\n\tcontent: string;\n}\n\nclass CloudflareLLM implements LLM {\n\tmessages: Message[] = [];\n\tresponse: [string, boolean] | null = null;\n\tresponseRead = false;\n\tinProgress = false;\n\n\tconstructor(\n\t\t// readonly model: string,\n\t\t// readonly accountId: string,\n\t\treadonly authKey: string\n\t) {}\n\n\tnewConversation(systemMessage: string) {\n\t\tif (this.inProgress) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.messages = [{\n\t\t\trole: 'system',\n\t\t\tcontent: systemMessage\n\t\t}];\n\t\treturn true;\n\t}\n\n\task(prompt: string) {\n\t\tif (this.inProgress) {\n\t\t\treturn false;\n\t\t}\n\t\tvoid this.askAsync(prompt);\n\t\treturn true;\n\t}\n\n\tasync askAsync(prompt: string) {\n\t\tif (this.inProgress) {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tthis.inProgress = true;\n\t\t\tconsole.debug('LLM request:', prompt);\n\t\t\t// const url = `https://api.cloudflare.com/client/v4/accounts/${this.accountId}/ai/run/${this.model}`;\n\t\t\tconst url = '/proxy/llm';\n\t\t\tconst messages = [...this.messages];\n\t\t\tmessages.push({\n\t\t\t\trole: 'user',\n\t\t\t\tcontent: prompt\n\t\t\t});\n\t\t\tconst request = new Request(url, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Authorization': `Bearer ${this.authKey}`,\n\t\t\t\t\t'Content-Type': 'text/event-stream',\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tmessages,\n\t\t\t\t\tstream: true,\n\t\t\t\t}),\n\t\t\t});\n\t\t\tconst response = await fetch(request);\n\t\t\tif (!response.ok) {\n\t\t\t\treportWarning('llmRequestFailed', { status: response.status });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet responseText = '';\n\t\t\tawait readServerSideEventStream(response, (data) => {\n\t\t\t\tresponseText += data;\n\t\t\t\tconsole.debug('LLM response (partial):', responseText);\n\t\t\t\tthis.response = [responseText, false];\n\t\t\t\tthis.responseRead = false;\n\t\t\t});\n\t\t\tconsole.debug('LLM response:', responseText);\n\t\t\tthis.response = [responseText, true];\n\t\t\tthis.responseRead = false;\n\t\t\tthis.messages = messages;\n\t\t\tthis.messages.push({\n\t\t\t\trole: 'assistant',\n\t\t\t\tcontent: responseText\n\t\t\t});\n\t\t} finally {\n\t\t\tthis.inProgress = false;\n\t\t}\n\t}\n\n\thasResponse() {\n\t\treturn this.response !== null;\n\t}\n\n\tgetResponse() {\n\t\tthis.responseRead = true;\n\t\treturn this.response;\n\t}\n\n\tclearReadStates() {\n\t\tif (this.responseRead) {\n\t\t\tthis.response = null;\n\t\t\tthis.responseRead = false;\n\t\t}\n\t}\n}\n\n// eslint-disable-next-line no-underscore-dangle\nlet _llm: LLM | null = null;\n\nfunction llm() {\n\tif (_llm === null) {\n\t\tif (Parameters.llmAuth === null ) {\n\t\t\t_llm = new FakeLLM();\n\t\t\treportWarning('llmAuthNotSet');\n\t\t} else {\n\t\t\t_llm = new CloudflareLLM(\n\t\t\t\t// '@cf/meta/llama-3.1-8b-instruct-awq',\n\t\t\t\tParameters.llmAuth\n\t\t\t);\n\t\t\tconsole.info('Starting LLM interface.');\n\t\t}\n\t}\n\treturn _llm;\n}\n\nexport function newLlmConversation(systemMessage: string) {\n\treturn llm().newConversation(systemMessage);\n}\n\nexport function askLlm(prompt: string) {\n\treturn llm().ask(prompt);\n}\n\nexport function hasLlmResponse() {\n\treturn _llm?.hasResponse() ?? false;\n}\n\nexport function getLlmResponse() {\n\treturn _llm?.getResponse() ?? null;\n}\n\nexport function clearLlmReadStates() {\n\t_llm?.clearReadStates();\n}\n\nasync function readServerSideEventStream(response: Response, onResponse: (data: string) => void) {\n\tconst EVENTSTREAM_PREFIX = 'data: ';\n\tconst EVENTSTREAM_ENDED = '[DONE]';\n\n\t// Use a ReadableStream to handle the response\n\tconst body = response.body;\n\tif (body === null) {\n\t\treturn;\n\t}\n\tconst reader = body\n\t\t.pipeThrough(new TextDecoderStream())\n\t\t.getReader();\n\n\tlet data = '';\n\twhile (true) {\n\t\t// Handle each chunk, note that this is a robust implementation that doesn't\n\t\t// require each chunk to be on a single line.\n\t\t// eslint-disable-next-line prefer-const\n\t\tlet { value, done } = await reader.read();\n\n\t\tif (done) {\n\t\t\tbreak;\n\t\t}\n\t\tif (value === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst lines = value.split('\\n');\n\t\tif (lines[lines.length - 1] !== '') {\n\t\t\tdata += lines.pop() ?? '';\n\t\t}\n\t\tfor (let line of lines) {\n\t\t\tif (data !== '') {\n\t\t\t\tline = data + line;\n\t\t\t\tdata = '';\n\t\t\t}\n\t\t\tif (!line) {\n\t\t\t\tcontinue; // Skip empty lines\n\t\t\t}\n\t\t\tif (line.indexOf(EVENTSTREAM_PREFIX) >= 0) {\n\t\t\t\tconst msgChunk = line.substring(EVENTSTREAM_PREFIX.length);\n\n\t\t\t\tif (msgChunk === EVENTSTREAM_ENDED) {\n\t\t\t\t\tdone = true;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.debug('LLM to parse: ', msgChunk);\n\t\t\t\t\tconst { response } = JSON.parse(msgChunk);\n\t\t\t\t\tif (typeof response === 'string') {\n\t\t\t\t\t\tonResponse(response);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (done) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Close the stream from the client-side\n\tawait reader.cancel();\n}","/**\n * @module runtime\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { defined, nonnull } from 'utils/types';\nimport { BodyData, Body, Runtime } from './runtime-core';\nimport { ScriptValue, set_log_ctx as setLogCtx } from 'app-core-web/pkg';\nimport { getPilaReportFunctions } from './runtime-pila';\nimport { ClearCanvas, DrawText, FillRect, DrawLine, DrawRect, DrawEllipse, SetFillColor, SetFontSize, SetStrokeColor, SetTextColor, HorizontalTextAlignment, SetTextAlignment, VerticalTextAlignment, FillEllipse } from './runtime-canvas';\nimport { assertRecoverable } from 'utils/assert';\nimport { SimilarityTransform, Vector2 } from 'math/linalg';\nimport { postGameEvent } from 'network/api';\n\nlet runtimeData: [Runtime, Body, BodyData, string] | null = null;\n\nexport function setScriptRuntimeData(runtime: Runtime, body: Body, bodyData: BodyData, logCtx: string) {\n\tsetLogCtx(logCtx)\n\truntimeData = [runtime, body, bodyData, logCtx];\n}\n\n// read\n\nexport function getCandliVariable(scope: number, index: number) {\n\tconst data = nonnull(runtimeData);\n\tconst runtime = data[0];\n\tconst value = runtime.getVariableByScopeAndIndex(scope, index, data[2]);\n\tif (value === null) {\n\t\treturn 0;\n\t} else if (typeof value !== 'number') {\n\t\tif (!runtime.invalidVarReadExceptionFired) {\n\t\t\tassertRecoverable(false, `Expected number, found Script game variable at ${index}.`);\n\t\t\truntime.invalidVarReadExceptionFired = true;\n\t\t}\n\t\treturn 0;\n\t}\n\treturn value;\n}\n\nexport function getScriptVariable(scope: number, index: number) {\n\tconst data = nonnull(runtimeData);\n\tconst runtime = data[0];\n\tconst value = runtime.getVariableByScopeAndIndex(scope, index, data[2]);\n\tconst type = defined(\n\t\truntime.game.variables[index - 1]?.name?.type ?? undefined,\n\t\t'Variable type not found'\n\t);\n\tif (value === null) {\n\t\treturn type.default_value();\n\t} else if (typeof value === 'number') {\n\t\tif (!runtime.invalidVarReadExceptionFired) {\n\t\t\tassertRecoverable(false, `Expected Script game variable, found number at ${index}.`);\n\t\t\truntime.invalidVarReadExceptionFired = true;\n\t\t}\n\t\treturn type.default_value();\n\t}\n\treturn value;\n}\n\nexport function gameSessionId() {\n\tconst data = nonnull(runtimeData);\n\treturn data[0].gameSessionId;\n}\n\nexport function textInputActive() {\n\tconst data = nonnull(runtimeData);\n\treturn data[0].textInputActive();\n}\n\nexport function getTextInput() {\n\tconst data = nonnull(runtimeData);\n\treturn data[0].textInputContent();\n}\n\n// write\n\nexport function log(message: string) {\n\tconst data = nonnull(runtimeData);\n\tconst logCtx = data[3];\n\tconsole.log(`Script: ${logCtx}${message}`);\n}\n\nexport function setCandliVariable(scope: number, index: number, value: number) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].setVariableByScopeAndIndex(scope, index, value, data[2]);\n}\n\nexport function setScriptVariable(scope: number, index: number, value: ScriptValue) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].setVariableByScopeAndIndex(scope, index, value, data[2]);\n}\n\nexport function logGameEvent(name: string, data: string) {\n\tconst runtime = nonnull(runtimeData)[0];\n\tvoid postGameEvent(runtime.gameId, {\n\t\ttype: 'log',\n\t\tsession: runtime.gameSessionId,\n\t\tname,\n\t\tdata,\n\t});\n}\n\nexport function startTextInput(initial: string) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].startTextInput(initial, data[1]);\n}\n\nexport function stopTextInput() {\n\tconst data = nonnull(runtimeData);\n\tdata[0].stopTextInput();\n}\n\nexport function checkPoint(point: string) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].checkPoints.add(point);\n}\n\nexport function openURL(url: string) {\n\ttry {\n\t\twindow.open(url, '_blank');\n\t} catch (e) {\n\t\tconsole.error(`Opening url \"${url}\" failed: ${e}`);\n\t}\n}\n\nexport function clearCanvas() {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new ClearCanvas());\n}\n\nexport function drawText(text: string) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new DrawText(text));\n}\n\nexport function drawLine(x1: number, y1: number, x2: number, y2: number) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new DrawLine(x1, y1, x2, y2));\n}\n\nexport function drawRect(x: number, y: number, width: number, height: number) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new DrawRect(x, y, width, height));\n}\n\nexport function fillRect(x: number, y: number, width: number, height: number) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new FillRect(x, y, width, height));\n}\n\nexport function drawEllipse(x: number, y: number, rx: number, ry: number) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new DrawEllipse(x, y, rx, ry));\n}\n\nexport function fillEllipse(x: number, y: number, rx: number, ry: number) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new FillEllipse(x, y, rx, ry));\n}\n\nexport function setFontSize(size: number) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new SetFontSize(size));\n}\n\nexport function setTextAlignment(horizontalAlignment: HorizontalTextAlignment, verticalAlignment: VerticalTextAlignment) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new SetTextAlignment(horizontalAlignment, verticalAlignment));\n}\n\nexport function setTextColor(color: string) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new SetTextColor(color));\n\t// We also set the text color directly because if we start the text input box,\n\t// we want the correct text color.\n\tdata[2].canvasAttributes.textColor = color;\n}\n\nexport function setStrokeColor(color: string) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new SetStrokeColor(color));\n}\n\nexport function setFillColor(color: string) {\n\tconst data = nonnull(runtimeData);\n\tdata[0].addCanvasRenderAction(data[2], new SetFillColor(color));\n}\n\nexport function attachCamera() {\n\tconst data = nonnull(runtimeData);\n\tdata[0].attachCamera(data[1]);\n}\n\nexport function spawnObject(object: string, x: number, y: number, angle: number, scale: number) {\n\tconst data = nonnull(runtimeData);\n\tif (scale <= 0) {\n\t\tconsole.error(`Script attempted to spawn object type ${object} with zero or negative scale ${scale}`);\n\t\treturn;\n\t}\n\tconst pose = new SimilarityTransform(new Vector2(x, y), angle, scale);\n\tconst objectType = data[0].game.objectTypeByName(object);\n\tif (objectType === null) {\n\t\tconsole.error(`Script attempted to spawn object type ${object} that does not exists.`);\n\t\treturn;\n\t}\n\tdata[0].createObject(objectType, pose);\n}\n\n// pila\n\nexport function getPilaCompetency(name: string, latest: boolean): [number, number] | null {\n\treturn getPilaReportFunctions().getCompetency(name, latest);\n}\n\nexport function setPilaCompetency(name: string, latest: boolean, v0: number, v1: number) {\n\tgetPilaReportFunctions().setCompetency(name, latest, v0, v1);\n}\n","/// \n/**\n * @module runtime\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { reportWarning } from 'apps/common/analytics';\nimport { Parameters } from 'apps/common/parameters';\nimport { defined } from 'utils/types';\nimport Bowser from 'bowser';\n\nconst SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;\n\ninterface RecognitionState {\n\tstart(): void;\n\tstop(): void;\n\tisRecording(): boolean;\n\thasResult(): boolean;\n\tgetResult(): [string, boolean] | null;\n\thasError(): boolean;\n\tgetError(): string | null;\n\tclearReadStates(): void;\n}\n\nclass RealRecognitionState implements RecognitionState {\n\t// recognition has been requested to start, but might be awaiting user permission\n\trequested: boolean = false;\n\t// recognition is currently active\n\trecording: boolean = false;\n\tresult: [string, boolean] | null = null;\n\tresultRead: boolean = false;\n\terror: string | null = null;\n\terrorRead: boolean = false;\n\tspeechRecognition: SpeechRecognition;\n\n\tconstructor() {\n\t\tthis.speechRecognition = new SpeechRecognition();\n\t\tthis.speechRecognition.continuous = true;\n\t\t// Cannot enabling interim results on Android, because of bug\n\t\t// https://issues.chromium.org/issues/40272768\n\t\tif (Bowser.getParser(window.navigator.userAgent).getOSName() !== 'Android') {\n\t\t\tthis.speechRecognition.interimResults = true;\n\t\t}\n\t\tthis.speechRecognition.lang = Parameters.language;\n\t\tthis.speechRecognition.onstart = () => {\n\t\t\tthis.recording = true;\n\t\t}\n\t\tthis.speechRecognition.onresult = (event) => {\n\t\t\tlet isFinal = true;\n\t\t\tlet transcript = '';\n\t\t\tfor (const resultAlternatives of event.results) {\n\t\t\t\tconst result = defined(resultAlternatives[0]);\n\t\t\t\tisFinal = isFinal && resultAlternatives.isFinal;\n\t\t\t\tif (transcript.length > 0 && result.transcript[0] !== ' ') {\n\t\t\t\t\ttranscript += ' ';\n\t\t\t\t}\n\t\t\t\ttranscript += result.transcript;\n\t\t\t\tif (resultAlternatives.isFinal && transcript[transcript.length - 1] !== '.') {\n\t\t\t\t\ttranscript += '.';\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.result = [transcript, isFinal];\n\t\t\tthis.resultRead = false;\n\t\t};\n\t\tthis.speechRecognition.onerror = (event) => {\n\t\t\tthis.error = event.error;\n\t\t\tthis.errorRead = false;\n\t\t\tthis.recording = false;\n\t\t\tthis.requested = false;\n\t\t};\n\t\tthis.speechRecognition.onend = () => {\n\t\t\tthis.recording = false;\n\t\t\tthis.requested = false;\n\t\t}\n\t}\n\n\tstart() {\n\t\tif (this.requested) {\n\t\t\treturn;\n\t\t}\n\t\tthis.speechRecognition.start();\n\t\tthis.requested = true;\n\t\tthis.result = null;\n\t}\n\n\tstop() {\n\t\tif (!this.recording) {\n\t\t\treturn;\n\t\t}\n\t\tthis.speechRecognition.stop();\n\t}\n\n\tisRecording() {\n\t\treturn this.recording;\n\t}\n\n\thasResult(): boolean {\n\t\treturn this.result !== null;\n\t}\n\n\tgetResult() {\n\t\tthis.resultRead = true;\n\t\treturn this.result;\n\t}\n\n\thasError(): boolean {\n\t\treturn this.error !== null;\n\t}\n\n\tgetError() {\n\t\tthis.errorRead = true;\n\t\treturn this.error;\n\t}\n\n\tclearReadStates() {\n\t\tif (this.resultRead) {\n\t\t\tthis.result = null;\n\t\t\tthis.resultRead = false;\n\t\t}\n\t\tif (this.errorRead) {\n\t\t\tthis.error = null;\n\t\t\tthis.errorRead = false;\n\t\t};\n\t}\n}\n\nclass FakeRecognitionState implements RecognitionState {\n\tstart() {\n\t\t// do nothing\n\t}\n\n\tstop() {\n\t\t// do nothing\n\t}\n\n\tisRecording() {\n\t\treturn false;\n\t}\n\n\thasResult() {\n\t\treturn false;\n\t}\n\n\tgetResult() {\n\t\treturn null;\n\t}\n\n\thasError() {\n\t\treturn false;\n\t}\n\n\tgetError() {\n\t\treturn null;\n\t}\n\n\tclearReadStates() {\n\t\t// do nothing\n\t}\n}\n\n// eslint-disable-next-line no-underscore-dangle\nlet _speechRecognition: RecognitionState | null = null;\n\nconst isSupported = SpeechRecognition !== undefined && (\n\tBowser.getParser(window.navigator.userAgent).getBrowserName() !== 'Chrome' ||\n\t// Only real Chrome supports the SpeechRecognition API, not Chromium for example\n\t(window.navigator.userAgentData?.brands?.filter(e => e.brand === 'Google Chrome').length ?? 0) > 0\n);\n\nfunction speechRecognition() {\n\tif (_speechRecognition === null) {\n\t\tif (isSpeechRecognitionSupported()) {\n\t\t\t_speechRecognition = new RealRecognitionState();\n\t\t\tconsole.info('Starting speech recognition.');\n\t\t} else {\n\t\t\t_speechRecognition = new FakeRecognitionState();\n\t\t\treportWarning('speechRecognitionNotSupported');\n\t\t}\n\t}\n\treturn _speechRecognition;\n}\n\nexport function isSpeechRecognitionSupported() {\n\treturn isSupported;\n}\n\nexport function startSpeechRecognition() {\n\tspeechRecognition().start();\n}\n\nexport function stopSpeechRecognition() {\n\tspeechRecognition().stop();\n}\n\nexport function hasSpeechRecognitionResult() {\n\treturn _speechRecognition?.hasResult() ?? false;\n}\n\nexport function getSpeechRecognitionResult() {\n\treturn _speechRecognition?.getResult() ?? null;\n}\n\nexport function hasSpeechRecognitionError() {\n\treturn _speechRecognition?.hasError() ?? false;\n}\n\nexport function getSpeechRecognitionError() {\n\treturn _speechRecognition?.getError() ?? null;\n}\n\nexport function clearSpeechRecognitionReadStates() {\n\t_speechRecognition?.clearReadStates();\n}","/**\n * @module runtime\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { nonnull, downcast, cast, defined, getPropByNameOrNull } from '../utils/types';\nimport { resizeCanvas, getChildElementsByTag } from '../utils/html';\nimport { Screen } from '../screen/screen';\nimport { Body, AABB } from 'planck-js';\nimport { Game, CanvasWithKey } from '../game/game';\nimport { Vector2 } from 'math/linalg';\nimport { screenManager } from '../screen/screen-manager';\nimport { Runtime, BodyData, toVector2, RuntimeContactCallback, TouchingPoint, getContactPoints } from './runtime-core';\nimport { isBitSet } from 'utils/flags';\nimport { Analytics, reportLog } from 'apps/common/analytics';\nimport { Features } from 'apps/common/parameters';\nimport { Color } from 'color/color';\nimport { assert, assertFalse, assertRecoverable } from 'utils/assert';\nimport { boundingRectOfShape, Dialog } from 'game/game-core';\nimport { GLState } from './gl-state';\nimport { createCanvasAnd2DContext, createCanvasAnd2DContextHiDPI, createOffscreenCanvasAnd2DContext } from 'utils/canvas';\nimport { scalarToVec3Homo, multMat3Vec3, invertMat3, multMat3Mat3, identMat3, vector2ToVec3Homo, Mat3, createMat3, vec3HomoToVector2 } from './mat3';\nimport { vecToVec2 } from './planck-conversion';\nimport { MDCDialog, MDCDialogCloseEvent } from '@material/dialog';\nimport { Button, InputSource, Inputs, KeyboardInputSource, NumpadInputSource } from './input-sources';\nimport { qsT } from 'translator/translator';\nimport { drawCanvasInBox } from 'utils/render';\nimport { FixedSizeArray, genIndex } from 'utils/array-types';\nimport { ButtonIndex } from 'blocks/conditions/input/input-block';\nimport { drawScoreIcon, getVariableMiniature } from 'blocks/common/variable/variable-render';\nimport { CanvasOverlay, ClearCanvas } from './runtime-canvas';\nimport { clearSpeechRecognitionReadStates } from './runtime-speech';\nimport { clearLlmReadStates } from './runtime-llm';\nimport { preMultiplyAlpha } from 'utils/image';\nimport { getBrowserNameLowercase } from 'apps/common/browser-check';\n\nexport { RuntimeContactCallback as RuntimeCollisionCallback } from './runtime-core';\n\nlet debugCamera = Features.devMode;\nlet debugContacts = Features.devMode;\nlet debugTouches = Features.devMode;\n\nconst ButtonCount = 8;\nconst ButtonNormalizedCenter = 0.5;\nconst ButtonNormalizedRadius2 = 2 * 0.5 * 0.5 * 0.9;\n\n\nfunction pushTexCoord(array: number[], left: number, top: number, w: number, h: number) {\n\tconst right = left + w;\n\tconst bottom = top + h;\n\tarray.push(left);\n\tarray.push(bottom);\n\tarray.push(left);\n\tarray.push(top);\n\tarray.push(right);\n\tarray.push(bottom);\n\tarray.push(right);\n\tarray.push(top);\n}\n\ntype MatrixPair = [Mat3, Mat3];\n\nexport type ButtonCallback = (button: Button) => void;\ntype PlayerId = 0 | 1;\ntype ButtonWidget = [PlayerId, ButtonIndex, MatrixPair];\ntype ButtonStates = FixedSizeArray;\n\n// Extra spacings for textareas in different browsers\n// [variable in ratio font size, fixed in pixels]\nconst BrowserTextAreaExtraSpacings = {\n\tchrome: [0.1, -1],\n\tedge: [0.1, -1],\n\tfirefox: [0.1, 1],\n\tsafari: [-0.1, 0],\n\t// eslint-disable-next-line camelcase\n\tsamsung_internet: [0.1, -1],\n} as const;\n\nexport function uiTextureFontLoadPromise() {\n\tconst fontSize = 72;\n\tconst dpr = window.devicePixelRatio || 1;\n\tconst realFontSize = Math.ceil(fontSize * dpr);\n\tconst iconFont = `normal ${realFontSize}px \"Material Icons\"`;\n\tconst scaledSize = realFontSize * 7 / 9;\n\tconst buttonFont = `bold ${scaledSize}px \"Roboto\"`;\n\treturn Promise.all([\n\t\tdocument.fonts.load(iconFont),\n\t\tdocument.fonts.load(buttonFont),\n\t]);\n}\n\nexport class RuntimeScreen extends Screen {\n\tprivate runtime: Runtime;\n\tprivate dialogOverlay = downcast(HTMLCanvasElement, nonnull(document.getElementById('runtime-dialog')));\n\tprivate activeDialog: Dialog | null = null;\n\tprivate returnLayer = nonnull(document.getElementById('runtime-return-layer'));\n\tprivate variablesDisplay = downcast(HTMLElement, nonnull(document.getElementById('runtime-variables')));\n\tprivate retryButton = downcast(HTMLElement, nonnull(document.getElementById('runtime-retry')));\n\tprivate runtimeStats = nonnull(document.getElementById('runtime-stats'));\n\tprivate gameOver = false;\n\tprivate gamePaused = false;\n\tprivate _forceHideControls = false;\n\tprivate controlsForcedHiddenBeforeOverlay = false;\n\tprivate lastVariableCount = NaN;\n\tprivate backgroundColor = new Color('#ffffff');\n\tprivate touches: TouchList | null = null;\n\tprivate newTouches: Set = new Set();\n\tprivate mouseTouch: Vector2 | null = null;\n\tprivate newMouseTouch = false;\n\tprivate animRequestId: number | null = null;\n\n\tprivate readonly canvas = downcast(HTMLCanvasElement, nonnull(document.getElementById('runtime-canvas')));\n\tprivate glState: GLState;\n\tprivate readonly uiTextureKey = Symbol('UI');\n\tprivate buttonWidgets: ButtonWidget[] = [];\n\tprivate activeInputButtons = 0;\n\tprivate readonly keyboardInput = new KeyboardInputSource();\n\tprivate readonly numpadInput = new NumpadInputSource();\n\tprivate screenInputs = [new InputSource('screen P1'), new InputSource('screen P2')] as const;\n\tprivate defaultInputs = [this.keyboardInput, this.screenInputs[0]] as const;\n\tprivate inputs = new Inputs();\n\tprivate assignedInputs: InputSource[] = [...this.defaultInputs];\n\tprivate assignInputDialogueElement = nonnull(document.getElementById('runtime-assignInput'));\n\tprivate assignInputDialogue = new MDCDialog(this.assignInputDialogueElement);\n\tprivate assignInputDialogueSourceTrigger: InputSource | null = null;\n\tprivate uiTouches: Vector2[] = [];\n\tprivate frameCounter = 0;\n\tprivate computationDuration = 0;\n\tprivate computationStatWindow = new Float32Array(64);\n\tprivate computationStatIndex = 0;\n\tprivate canvasCreationStat = 0;\n\tprivate worldBoundTopLeft = scalarToVec3Homo(0, 0);\n\tprivate worldBoundBottomRight = scalarToVec3Homo(0, 0);\n\n\tprivate readonly textInput = downcast(HTMLTextAreaElement, nonnull(document.getElementById('runtime-textInput')));\n\tprivate textAreaVerticalOffset: readonly [number, number] = [0, 0];\n\n\t// re-fetched on resized():\n\tprivate canvasRect = this.canvas.getBoundingClientRect();\n\n\t/** called when a button is pressed (for controller) or clicked (for UI) */\n\tpublic buttonActivatedCallback: ButtonCallback | null = null;\n\t/** called when a button is released (for controller) */\n\tpublic buttonDeactivatedCallback: ButtonCallback | null = null;\n\n\tconstructor(game: Game) {\n\t\tsuper(downcast(HTMLElement, document.getElementById('runtime')));\n\t\t// eslint-disable-next-line no-loss-of-precision\n\t\tthis.computationStatWindow.fill(1/60.);\n\n\t\t// Measure textarea properties\n\t\tconst browserName = getBrowserNameLowercase();\n\t\tif (browserName !== null) {\n\t\t\tconst textAreaOffsets = getPropByNameOrNull(BrowserTextAreaExtraSpacings, browserName);\n\t\t\tif (textAreaOffsets !== null) {\n\t\t\t\tconsole.log(`Using textarea offsets for ${browserName}: ${textAreaOffsets}`);\n\t\t\t\tthis.textAreaVerticalOffset = textAreaOffsets;\n\t\t\t}\n\t\t}\n\n\t\t// WebGL\n\t\tthis.canvas.addEventListener('webglcontextlost', (event) => {\n\t\t\tconsole.warn('WebGL context lost!');\n\t\t\tevent.preventDefault();\n\t\t\tif (this.animRequestId !== null) {\n\t\t\t\twindow.cancelAnimationFrame(this.animRequestId);\n\t\t\t\tthis.animRequestId = null;\n\t\t\t}\n\t\t}, false);\n\t\tthis.canvas.addEventListener('webglcontextrestored', (_event) => {\n\t\t\tconsole.warn('WebGL context restored!');\n\t\t\tthis.glState.reInit();\n\t\t\tthis.scheduleStep();\n\t\t}, false);\n\t\tthis.glState = new GLState(this.canvas);\n\t\tthis.generateUITexture(72);\n\n\t\t// Runtime Core\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tconst textInput = {\n\t\t\tget active() {\n\t\t\t\treturn self.isTextInputVisible;\n\t\t\t},\n\t\t\tset active(active: boolean) {\n\t\t\t\tif (active && !self.isTextInputVisible) {\n\t\t\t\t\tself.showTextInput();\n\t\t\t\t} else if (!active && self.isTextInputVisible){\n\t\t\t\t\tself.hideTextInput();\n\t\t\t\t}\n\t\t\t},\n\t\t\tget text() {\n\t\t\t\treturn self.textInput.value;\n\t\t\t},\n\t\t\tset text(text: string) {\n\t\t\t\tself.textInput.value = text;\n\t\t\t},\n\t\t\tinitiator: null,\n\t\t}\n\t\tthis.runtime = new Runtime(game, game.id, this.showDialog.bind(this), textInput);\n\n\t\t// Setup events\n\n\t\t// game UI\n\t\tthis.dialogOverlay.addEventListener('click', this.dialogClicked.bind(this));\n\t\tnonnull(document.getElementById('runtime-return')).onclick = () => this.returnButtonClicked();\n\n\t\tconst retryGameCallback = this.retryGame.bind(this);\n\t\tnonnull(document.getElementById('runtime-retry__icon')).onclick = retryGameCallback;\n\t\tnonnull(document.getElementById('runtime-retry__text')).onclick = retryGameCallback;\n\t\tthis.assignInputDialogue.listen('MDCDialog:closed', this.assignInput.bind(this));\n\t\tif (!Features.devMode) {\n\t\t\tthis.runtimeStats.style.display = 'none';\n\t\t}\n\n\t\t// Record list of touches, and then cancel touch events' default behaviours\n\t\t// on canvas, to prevent undesired gestures on iOS\n\t\tconst touchEvents = [\n\t\t\t'touchStart',\n\t\t\t'touchMove',\n\t\t\t'touchEnd',\n\t\t\t'touchCancel',\n\t\t];\n\t\tconst handleTouchEvent = (event: Event) => {\n\t\t\tconst touchEvent = downcast(TouchEvent, event);\n\t\t\tthis.touches = touchEvent.touches;\n\t\t\tif (event.type === 'touchstart') {\n\t\t\t\tfor (const touch of touchEvent.changedTouches) {\n\t\t\t\t\tthis.newTouches.add(touch.identifier);\n\t\t\t\t}\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t};\n\t\tfor (const touchEvent of touchEvents) {\n\t\t\tthis.canvas.addEventListener(touchEvent.toLowerCase(), handleTouchEvent, { passive: false });\n\t\t}\n\n\t\t// Touch emulation by mouse\n\t\tconst setMouseTouch = (event: Event) => {\n\t\t\tconst mouseEvent = downcast(MouseEvent, event);\n\t\t\tthis.mouseTouch = new Vector2(mouseEvent.clientX, mouseEvent.clientY);\n\t\t\tthis.newMouseTouch = true;\n\t\t\tif (this.isTextInputVisible) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t};\n\t\tthis.canvas.addEventListener('mousedown', setMouseTouch);\n\t\tconst updateMouseTouch = (event: Event) => {\n\t\t\tif (this.mouseTouch) {\n\t\t\t\tconst mouseEvent = downcast(MouseEvent, event);\n\t\t\t\tthis.mouseTouch = new Vector2(mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t}\n\t\t};\n\t\tthis.canvas.addEventListener('mousemove', updateMouseTouch);\n\t\tconst clearMouseTouch = (_event: Event) => this.mouseTouch = null;\n\t\tthis.canvas.addEventListener('mouseup', clearMouseTouch);\n\t\tthis.canvas.addEventListener('mouseleave', clearMouseTouch);\n\t}\n\n\tprivate get twoPlayers() {\n\t\treturn this.runtime.game.twoPlayers;\n\t}\n\n\tget retryButtonVisible() {\n\t\treturn this.retryButton.style.display !== 'none';\n\t}\n\tset retryButtonVisible(visible: boolean) {\n\t\tif (visible) {\n\t\t\tthis.retryButton.style.display = '';\n\t\t} else {\n\t\t\tthis.retryButton.style.display = 'none';\n\t\t}\n\t}\n\n\tget retryButtonActive() {\n\t\treturn this.assignedInputs.reduce((retry, inputSource) => retry || inputSource.retryGame, false) ||\n\t\t\tthis.keyboardInput.retryGame;\n\t}\n\n\tget contactCallback() {\n\t\treturn this.runtime.contactCallback;\n\t}\n\tset contactCallback(callback: RuntimeContactCallback | null) {\n\t\tthis.runtime.contactCallback = callback;\n\t}\n\n\tget forceHideReturnButton() {\n\t\treturn this.returnLayer.style.display === 'none';\n\t}\n\tset forceHideReturnButton(hidden: boolean) {\n\t\tthis.returnLayer.style.display = hidden ? 'none' : '';\n\t}\n\n\tget forceHideControls() {\n\t\treturn this._forceHideControls;\n\t}\n\tset forceHideControls(hidden: boolean) {\n\t\tthis._forceHideControls = hidden;\n\t\tthis.controlsForcedHiddenBeforeOverlay = hidden;\n\t}\n\n\toverlayForceHideControls() {\n\t\tconst wasHidden = this.forceHideControls;\n\t\tthis.forceHideControls = true;\n\t\tthis.controlsForcedHiddenBeforeOverlay = wasHidden;\n\t}\n\n\toverlayUnForceHideControls() {\n\t\tthis.forceHideControls = this.controlsForcedHiddenBeforeOverlay;\n\t}\n\n\tforceHideWidgets(hidden = true) {\n\t\tthis.forceHideReturnButton = hidden;\n\t\tthis.forceHideControls = hidden;\n\t}\n\n\tresetDefaultSettings() {\n\t\tthis.forceHideWidgets(false);\n\t}\n\n\tprivate get dialogVisible() {\n\t\treturn this.dialogOverlay.style.display !== 'none';\n\t}\n\n\tassertNoCallbacks() {\n\t\tassertRecoverable(this.contactCallback === null, 'contactCallback is not null');\n\t\tassertRecoverable(this.buttonActivatedCallback === null, 'buttonActivatedCallback is not null');\n\t\tassertRecoverable(this.buttonDeactivatedCallback === null, 'buttonDeactivatedCallback is not null');\n\t}\n\n\tinspectGameVariables() {\n\t\treturn this.runtime.gameVariables;\n\t}\n\n\tpause() {\n\t\tthis.gamePaused = true;\n\n\t\t// if block game screen is already visible, do not update the text\n\t\tif (this.dialogVisible) {\n\t\t\treturn;\n\t\t}\n\n\t\t// hide controls\n\t\tthis.overlayForceHideControls();\n\n\t\t// show screen\n\t\tthis.dialogOverlay.style.display = '';\n\t\tthis.resizeAndRenderBlockGameOverlay();\n\t}\n\n\tunpause() {\n\t\tthis.gamePaused = false;\n\t\tif (!this.gameOver) {\n\t\t\tthis.hideDialog();\n\t\t}\n\t\tthis.runtime.lastStepTime = null;\n\t\tthis.scheduleStep();\n\t}\n\n\tsetGame(game: Game) {\n\t\tthis.runtime.game = game;\n\t\tthis.runtime.gameId = game.id;\n\t}\n\n\tgetGameId() {\n\t\treturn this.runtime.gameId;\n\t}\n\n\tgetTimeStats() {\n\t\treturn {\n\t\t\twallTime: this.runtime.worldTime,\n\t\t\tcpuTime: this.computationDuration * 0.001,\n\t\t\tframeCtr: this.frameCounter\n\t\t};\n\t}\n\n\tgetCheckPoints() {\n\t\treturn this.runtime.checkPoints;\n\t}\n\n\tprotected get isTextInputVisible() {\n\t\treturn this.textInput.style.display !== 'none';\n\t}\n\n\tprotected hideTextInput() {\n\t\tthis.textInput.style.display = 'none';\n\t\tthis.textInput.blur();\n\t}\n\n\tprotected showTextInput() {\n\t\tthis.updateTextInputStyle();\n\t\tthis.textInput.style.display = '';\n\t\tthis.textInput.focus();\n\t}\n\n\tprotected updateTextInputStyle() {\n\t\tconst initiator = nonnull(this.runtime.textInputInitiator());\n\t\tconst worldToScreen = invertMat3(this.computeScreenToWorldTransformGL());\n\t\tconst screenCenterPos = vec3HomoToVector2(multMat3Vec3(worldToScreen, vector2ToVec3Homo(initiator.pos)));\n\t\t// TODO: Handle rotation and flipX/flipY.\n\t\tconst boundingRect = boundingRectOfShape(initiator.bodyData.objectType.shape);\n\t\tconst screenSize = boundingRect.size.multScalar(initiator.scale / this.worldUnitPerPixel());\n\t\tconst topLeft = screenCenterPos.sub(screenSize.multScalar(0.5));\n\t\tconst canvasAttributes = initiator.bodyData.canvasAttributes;\n\t\tconst canvasResolution = canvasAttributes.resolution;\n\t\tconst canvasFontSize = canvasAttributes.fontSize;\n\t\tconst canvasWidth = boundingRect.width * canvasResolution;\n\t\tconst fontSizeRatioWidth = canvasFontSize / canvasWidth;\n\t\tconst fontSizeScreen = screenSize.x * fontSizeRatioWidth;\n\t\tthis.textInput.style.color = canvasAttributes.textColor;\n\t\tthis.textInput.style.fontSize = `${fontSizeScreen}px`;\n\t\tthis.textInput.style.left = `${topLeft.x}px`;\n\t\t// Note: 0.1 to compensate for half line-height\n\t\tconst top = topLeft.y - fontSizeScreen * (0.1 + this.textAreaVerticalOffset[0]) - this.textAreaVerticalOffset[1];\n\t\tthis.textInput.style.top = `${top}px`;\n\t\tthis.textInput.style.width = `${screenSize.x}px`;\n\t\tthis.textInput.style.height = `${screenSize.y}px`;\n\t}\n\n\tprotected resized() {\n\t\tresizeCanvas(this.canvas, null, false);\n\t\tthis.canvasRect = this.canvas.getBoundingClientRect();\n\t\tthis.updateButtonWidgets();\n\t\tif (this.dialogVisible) {\n\t\t\tthis.resizeAndRenderBlockGameOverlay();\n\t\t}\n\t\tif (this.isTextInputVisible) {\n\t\t\tthis.updateTextInputStyle();\n\t\t}\n\t}\n\n\tprotected keyDown(event: KeyboardEvent) {\n\t\tif (this.isTextInputVisible) {\n\t\t\treturn;\n\t\t}\n\t\tif (event.which === 68) {\n\t\t\tdebugCamera = !debugCamera;\n\t\t\tdebugContacts = !debugContacts;\n\t\t\tdebugTouches = !debugTouches;\n\t\t} else {\n\t\t\tthis.keyboardInput.processKeyDown(event);\n\t\t\tthis.numpadInput.processKeyDown(event);\n\t\t}\n\t}\n\n\tprotected keyUp(event: KeyboardEvent) {\n\t\tthis.keyboardInput.processKeyUp(event);\n\t\tthis.numpadInput.processKeyUp(event);\n\t}\n\n\tprotected appHidden() {\n\t\tthis.pause();\n\t}\n\n\tprotected appVisible() {\n\t\tthis.unpause();\n\t}\n\n\tprivate buttonActivated(index: number) {\n\t\tif (this.buttonActivatedCallback) {\n\t\t\tthis.buttonActivatedCallback(index);\n\t\t}\n\t}\n\n\tprivate buttonDeactivated(index: number) {\n\t\tif (this.buttonDeactivatedCallback) {\n\t\t\tthis.buttonDeactivatedCallback(index);\n\t\t}\n\t}\n\n\tprivate scheduleStep() {\n\t\tif (this.animRequestId === null) {\n\t\t\tthis.animRequestId = window.requestAnimationFrame(this.step.bind(this));\n\t\t}\n\t}\n\n\tprivate step(timestamp: DOMHighResTimeStamp) {\n\t\tthis.animRequestId = null;\n\n\t\t// not visible, do not do anything\n\t\tif (!this.visible) {\n\t\t\treturn;\n\t\t}\n\n\t\t// update screen button state\n\t\tfor (const buttonWidget of this.buttonWidgets) {\n\t\t\tconst [player, button, transforms] = buttonWidget;\n\t\t\tif (!this.isScreenInputActive(player)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isBitSet(this.activeInputButtons, button)) {\n\t\t\t\tthis.screenInputs[player].setButtonActive(button, this.glButtonCheck(transforms));\n\t\t\t}\n\t\t}\n\n\t\t// check all input sources, excepted on frame 0 because on Chrome the gamepad have invalid states\n\t\tif (this.frameCounter !== 0) {\n\t\t\tthis.inputs.check();\n\t\t} else {\n\t\t\tthis.inputs.scanGamepads();\n\t\t}\n\t\tthis.processInputAssignmentDialogueShortcuts();\n\t\tthis.frameCounter += 1;\n\t\t// handle inputs, depending whether we are two players or one\n\t\tlet lastButtonStates: ButtonStates;\n\t\tlet buttonStates: ButtonStates;\n\t\tif (this.twoPlayers) {\n\t\t\t// two players, consider assigned inputs\n\t\t\tlastButtonStates = [this.assignedInputs[0]!.lastState, this.assignedInputs[1]!.lastState];\n\t\t\tbuttonStates = [this.assignedInputs[0]!.curState, this.assignedInputs[1]!.curState];\n\t\t\t// check for activity on unassigned input\n\t\t\tif (!this.assignInputDialogue.isOpen) {\n\t\t\t\tfor (const input of this.inputs.sources) {\n\t\t\t\t\tif (this.assignedInputs.includes(input)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tlet buttonPressed = false;\n\t\t\t\t\tfor (const button of genIndex(ButtonCount)) {\n\t\t\t\t\t\tif (input.isButtonActivated(button)) {\n\t\t\t\t\t\t\tbuttonPressed = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (buttonPressed) {\n\t\t\t\t\t\tthis.showInputAssignmentDialogue(input);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// single player, merge all button sources state\n\t\t\tconst merged = this.inputs.merge();\n\t\t\tlastButtonStates = [merged.lastState, merged.lastState];\n\t\t\tbuttonStates = [merged.curState, merged.curState];\n\t\t}\n\t\t// trigger callbacks, on any valid input\n\t\tfor (const player of [0, 1] as const) {\n\t\t\tif (!this.twoPlayers && player > 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tfor (let button = 0; button < ButtonCount; button += 1) {\n\t\t\t\tconst last = isBitSet(lastButtonStates[player], button);\n\t\t\t\tconst cur = isBitSet(buttonStates[player], button);\n\t\t\t\tif (cur && !last) {\n\t\t\t\t\tthis.buttonActivated(button);\n\t\t\t\t}\n\t\t\t\tif (!cur && last) {\n\t\t\t\t\tthis.buttonDeactivated(button);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// override button state if controls are forcibly hidden\n\t\tif (this.forceHideControls) {\n\t\t\tbuttonStates = [0, 0];\n\t\t}\n\t\t// store cur as new last for inputs\n\t\tthis.inputs.storeCurAsLast();\n\n\t\t// handle stop and retry, from any assigned input\n\t\tconst stopGame =\n\t\t\tthis.assignedInputs.reduce((stop, inputSource) => stop || inputSource.stopGame, false) ||\n\t\t\tthis.keyboardInput.stopGame\n\t\t;\n\t\tif (stopGame && !this.forceHideReturnButton) {\n\t\t\tthis.stopGame();\n\t\t\treturn;\n\t\t}\n\t\tif (this.retryButtonActive) {\n\t\t\tif (this.retryButtonVisible) {\n\t\t\t\tthis.retryGame();\n\t\t\t} else {\n\t\t\t\tthis.dialogClicked();\n\t\t\t}\n\t\t}\n\n\t\t// collect world touches\n\t\tconst viewportToWorldPreStep = this.computeViewportToWorldTransformGL();\n\t\tconst [cx, cy] = [this.screenCenter.x, this.screenCenter.y];\n\t\tconst screenToWorld = (x: number, y: number) => {\n\t\t\t// transform screen to viewport in input\n\t\t\tconst input = scalarToVec3Homo(x / cx - 1, 1 - y / cy);\n\t\t\tconst output = multMat3Vec3(viewportToWorldPreStep, input);\n\t\t\treturn new Vector2(output[0], output[1]);\n\t\t};\n\t\tconst touchingPoints: TouchingPoint[] = [];\n\t\tthis.uiTouches = [];\n\t\tif (this.touches !== null) {\n\t\t\tfor (const touch of this.touches) {\n\t\t\t\ttouchingPoints.push([\n\t\t\t\t\tscreenToWorld(touch.clientX, touch.clientY),\n\t\t\t\t\ttouch.identifier,\n\t\t\t\t\tthis.newTouches.has(touch.identifier)\n\t\t\t\t]);\n\t\t\t\tthis.uiTouches.push(new Vector2(touch.clientX, touch.clientY));\n\t\t\t}\n\t\t}\n\t\tif (this.mouseTouch !== null) {\n\t\t\ttouchingPoints.push([\n\t\t\t\tscreenToWorld(this.mouseTouch.x, this.mouseTouch.y),\n\t\t\t\t-1,\n\t\t\t\tthis.newMouseTouch\n\t\t\t]);\n\t\t\tthis.uiTouches.push(new Vector2(this.mouseTouch.x, this.mouseTouch.y));\n\t\t}\n\t\tthis.newTouches.clear();\n\t\tthis.newMouseTouch = false;\n\n\t\t// step runtime\n\t\tconst miniStepCb = () => {\n\t\t\t// clear per-step state\n\t\t\tclearSpeechRecognitionReadStates();\n\t\t\tclearLlmReadStates();\n\t\t};\n\t\tthis.runtime.step(timestamp, buttonStates, touchingPoints, miniStepCb);\n\n\t\t// do the rendering\n\t\tconst viewportToWorldPostStep = this.computeViewportToWorldTransformGL();\n\t\tthis.render(viewportToWorldPostStep, buttonStates);\n\n\t\t// update score if changed\n\t\tthis.updateVariableDisplay();\n\n\t\t// if dev mode, update stats\n\t\tif ((this.frameCounter % 32 === 0) && Features.devMode) {\n\t\t\tconst [totalTime, length] = this.runtime.perfStats;\n\t\t\tassert(length === this.computationStatWindow.length);\n\t\t\tconst fps = length / totalTime;\n\t\t\tconst computationTime = this.computationStatWindow.reduce((acc, cur) => acc + cur, 0);\n\t\t\tconst load = computationTime * 0.1 / totalTime;\n\t\t\tconst canvasCreationPerFrame = (this.canvasCreationStat / 32).toFixed(2);\n\t\t\tthis.canvasCreationStat = 0;\n\t\t\tthis.runtimeStats.innerText = `${fps.toFixed(2)} FPS - ${canvasCreationPerFrame} CPF - load ${load.toFixed(1)} %`;\n\t\t}\n\n\t\t// reschedule step, if not paused\n\t\tif (!this.gamePaused) {\n\t\t\tthis.scheduleStep();\n\t\t}\n\n\t\t// store computation duration\n\t\tconst computationDuration = performance.now() - timestamp;\n\t\tthis.computationDuration += computationDuration;\n\t\tthis.computationStatWindow[this.computationStatIndex] = computationDuration;\n\t\tthis.computationStatIndex = (this.computationStatIndex + 1) % this.computationStatWindow.length;\n\t}\n\n\tprivate render(viewportToWorld: Mat3, buttonStates: ButtonStates) {\n\t\t// first render canvas overlay for all object instances\n\t\tthis.renderCanvasOverlay();\n\n\t\t// compute transforms\n\t\tconst worldToViewport = invertMat3(viewportToWorld);\n\n\t\t// compute AABB of visible objects\n\t\t// we add some margin to consider sprites who are a bit outside their colliders\n\t\tconst renderAABB = new AABB(\n\t\t\tvecToVec2(multMat3Vec3(viewportToWorld, [-1.02, 1.02, 1])),\n\t\t\tvecToVec2(multMat3Vec3(viewportToWorld, [1.02, -1.02, 1]))\n\t\t);\n\n\t\t// draw background\n\t\tconst gl = this.glState.gl;\n\t\tgl.viewport(0, 0, this.canvas.width, this.canvas.height);\n\t\tconst bg = this.backgroundColor;\n\t\tgl.clearColor(bg.components[0] / 255, bg.components[1] / 255, bg.components[2] / 255, 1);\n\t\tgl.clear(gl.COLOR_BUFFER_BIT);\n\n\t\t// draw world bounds, with some rough clipping to avoid excessive GL state change\n\t\tconst viewportTopLeftWorldBound = multMat3Vec3(worldToViewport, this.worldBoundTopLeft);\n\t\tconst viewportBottomRightWorldBound = multMat3Vec3(worldToViewport, this.worldBoundBottomRight);\n\t\tif (viewportTopLeftWorldBound[0] >= -1.01 ||\n\t\t\tviewportTopLeftWorldBound[1] <= 1.01 ||\n\t\t\tviewportBottomRightWorldBound[0] <= 1.01 ||\n\t\t\tviewportBottomRightWorldBound[1] >= -1.01\n\t\t) {\n\t\t\tthis.glState.setupRenderWorldBounds(worldToViewport);\n\t\t\tthis.glState.renderWorldBounds();\n\t\t}\n\n\t\t// setup world-to-viewport transformation\n\t\tthis.glState.setupRenderObjects(worldToViewport);\n\n\t\t// display all objects in view\n\t\t// first split by layer\n\t\tconst layers: FixedSizeArray = [[], [], [], []];\n\t\tthis.runtime.world.queryAABB(renderAABB, (fixture) => {\n\t\t\tconst body = fixture.getBody();\n\t\t\tconst bodyData = cast(BodyData, body.getUserData());\n\t\t\tlayers[bodyData.objectType.kind].push(body);\n\t\t\treturn true;\n\t\t});\n\t\t// then render all layers\n\t\tfor (const layer of layers) {\n\t\t\tlayer.sort((a, b) => cast(BodyData, a.getUserData()).zOrder - cast(BodyData, b.getUserData()).zOrder);\n\t\t\tfor (const body of layer) {\n\t\t\t\tconst fixture = nonnull(body.getFixtureList());\n\t\t\t\tconst bodyData = cast(BodyData, body.getUserData());\n\t\t\t\tconst objectType = bodyData.objectType;\n\t\t\t\t// compute pose matrix\n\t\t\t\t// TODO: lookup the \"current\" frame, not always the first one\n\t\t\t\tconst animation = defined(objectType.animations[bodyData.animation?.index ?? 0]);\n\t\t\t\tconst frame = defined(animation.frames[bodyData.animation?.frameIndex ?? 0]);\n\t\t\t\tconst w = frame.sprite.size.x;\n\t\t\t\tconst h = frame.sprite.size.y;\n\t\t\t\t// we have a single part, so the part frame is equal to the pose frame\n\t\t\t\tconst spriteToPose = frame.partFromPixelTransform.toGLMat3();\n\t\t\t\t// our vertex buffer uses unit square, so we need to scale it\n\t\t\t\tspriteToPose[0] *= w;\n\t\t\t\tspriteToPose[1] *= w;\n\t\t\t\tspriteToPose[2] *= w;\n\t\t\t\tspriteToPose[3] *= h;\n\t\t\t\tspriteToPose[4] *= h;\n\t\t\t\tspriteToPose[5] *= h;\n\t\t\t\t// matrix to transform pose-centered coordinates to world coordinates\n\t\t\t\tconst scale = fixture.getUserData() as number;\n\t\t\t\tconst xInputScale = bodyData.flippingFactors.x * scale;\n\t\t\t\tconst yInputScale = bodyData.flippingFactors.y * scale;\n\t\t\t\tconst angle = body.getAngle();\n\t\t\t\tconst cosA = Math.cos(angle);\n\t\t\t\tconst sinA = Math.sin(angle);\n\t\t\t\tconst pos = body.getPosition();\n\t\t\t\tconst poseToWorld = createMat3();\n\t\t\t\tposeToWorld[0] = cosA * xInputScale;\n\t\t\t\tposeToWorld[1] = sinA * xInputScale;\n\t\t\t\tposeToWorld[3] = -sinA * yInputScale;\n\t\t\t\tposeToWorld[4] = cosA * yInputScale;\n\t\t\t\tposeToWorld[6] = pos.x;\n\t\t\t\tposeToWorld[7] = pos.y;\n\t\t\t\tposeToWorld[8] = 1;\n\t\t\t\tconst texture = defined(this.glState.getTexture(frame.sprite));\n\t\t\t\tthis.glState.renderObject(multMat3Mat3(poseToWorld, spriteToPose), texture, objectType.alpha);\n\t\t\t\tconst textOverlay = bodyData.canvasOverlay;\n\t\t\t\tif (textOverlay !== null) {\n\t\t\t\t\tconst textTexture = defined(this.glState.getTexture(textOverlay.textureKey));\n\t\t\t\t\tthis.glState.renderObject(multMat3Mat3(poseToWorld, textOverlay.pixelToPose), textTexture, objectType.alpha);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.glState.finishRenderObjects();\n\n\t\t// draw and process UI\n\t\tif (!this.forceHideControls)\n\t\t{\n\t\t\tconst uiTexture = defined(this.glState.getTexture(this.uiTextureKey));\n\t\t\tthis.glState.setupRenderUI(this.computeScreenToViewportTransformGL(), uiTexture);\n\t\t\tfor (const buttonWidget of this.buttonWidgets) {\n\t\t\t\tconst [player, button, transforms] = buttonWidget;\n\t\t\t\tif (!this.isScreenInputActive(player)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (isBitSet(this.activeInputButtons, button)) {\n\t\t\t\t\tconst state = isBitSet(buttonStates[player], button);\n\t\t\t\t\tthis.glButtonRender(button, transforms, state);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.glState.finishRenderUI();\n\t\t}\n\n\t\t// display debug informations if enabled\n\t\tconst debugCrosses = this.collectDebugCrosses();\n\t\tif (debugCrosses.length > 0) {\n\t\t\tconst crossPixelSize = 16;\n\t\t\tconst crossWorldSize = viewportToWorld[0] * crossPixelSize / this.canvasRect.width;\n\t\t\tthis.glState.setupRenderCross(worldToViewport, crossWorldSize);\n\t\t\tfor (const [worldPos, color] of debugCrosses) {\n\t\t\t\tthis.glState.renderCross(worldPos.dataRowMajor, color);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate renderCanvasOverlay() {\n\t\t// process all canvas render actions\n\t\tfor (const [target, actions] of this.runtime.canvasRenderActions) {\n\t\t\t// Helper functions to clear and create overlay\n\t\t\tconst clearCanvas = () => {\n\t\t\t\tif (target.canvasOverlay !== null) {\n\t\t\t\t\tthis.glState.deleteTexture(target.canvasOverlay.textureKey);\n\t\t\t\t\ttarget.canvasOverlay = null;\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst createOverlayIfNeeded = () => {\n\t\t\t\tif (target.canvasOverlay === null) {\n\t\t\t\t\tthis.canvasCreationStat += 1;\n\t\t\t\t\tconst boundingRect = boundingRectOfShape(target.objectType.shape);\n\t\t\t\t\tconst resolution = target.canvasAttributes.resolution;\n\t\t\t\t\ttarget.canvasOverlay = new CanvasOverlay(resolution, boundingRect);\n\t\t\t\t}\n\t\t\t\treturn target.canvasOverlay;\n\t\t\t};\n\t\t\t// First clear the canvas\n\t\t\tclearCanvas();\n\t\t\t// Process all actions\n\t\t\ttry {\n\t\t\t\tfor (const action of actions) {\n\t\t\t\t\tif (action instanceof ClearCanvas) {\n\t\t\t\t\t\tclearCanvas();\n\t\t\t\t\t} else {\n\t\t\t\t\t\taction.render(createOverlayIfNeeded(), target.canvasAttributes);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('Error while processing canvas render actions', e);\n\t\t\t}\n\t\t\t// Upload overlay to texture after all operations\n\t\t\tconst overlay = target.canvasOverlay;\n\t\t\tif (overlay !== null) {\n\t\t\t\tthis.glState.loadTexture(overlay.textureKey, preMultiplyAlpha(overlay.getImageData()));\n\t\t\t}\n\t\t}\n\t\tthis.runtime.canvasRenderActions.clear();\n\t}\n\n\t// GL button\n\tprivate glButtonCheck([_normalizedToScreen, screenToNormalized]: MatrixPair) {\n\t\treturn this.uiTouches.some((touchPoint) => {\n\t\t\tconst vec3 = [touchPoint.x, touchPoint.y, 1] as const;\n\t\t\tconst [x, y] = multMat3Vec3(screenToNormalized, vec3);\n\t\t\tconst dx = x - ButtonNormalizedCenter;\n\t\t\tconst dy = y - ButtonNormalizedCenter;\n\t\t\treturn dx * dx + dy * dy < ButtonNormalizedRadius2;\n\t\t});\n\t}\n\n\tprivate glButtonRender(button: number, [normalizedToScreen, _screenToNormalized]: MatrixPair, pressed: boolean) {\n\t\tconst elementId = pressed ? button * 2 + 1 : button * 2;\n\t\tthis.glState.renderUIElement(normalizedToScreen, elementId);\n\t}\n\n\tprivate updateButtonWidgets() {\n\t\t// parameters in function of window size\n\t\tlet bottomMargin = 8;\n\t\tlet sideMargin = 8;\n\t\tlet size = 256;\n\t\tconst width = this.canvasRect.width;\n\t\tconst height = this.canvasRect.height\n\t\tconst landscape = width >= height;\n\t\tif (landscape) {\n\t\t\tif (height <= 512) {\n\t\t\t\tsize = 192;\n\t\t\t\tbottomMargin = 0;\n\t\t\t}\n\t\t} else {\n\t\t\tif (width < 360) {\n\t\t\t\tsize = 160;\n\t\t\t\tbottomMargin = 0;\n\t\t\t\tsideMargin = 0;\n\t\t\t} else if (width < 416) {\n\t\t\t\tsize = 180;\n\t\t\t\tbottomMargin = 0;\n\t\t\t\tsideMargin = 0;\n\t\t\t} else if (width < 600) {\n\t\t\t\tsize = 192;\n\t\t\t}\n\t\t}\n\t\tconst reduction = size / 256;\n\t\t// helper functions\n\t\tconst buildButton = (transform: Mat3, x: number, y: number, player: PlayerId, button: ButtonIndex) => {\n\t\t\tconst localLoc = this.buttonLocation(x, y, 72 * reduction);\n\t\t\tconst loc = multMat3Mat3(transform, localLoc);\n\t\t\tconst locInv = invertMat3(loc);\n\t\t\tthis.buttonWidgets.push([player, button, [loc, locInv]]);\n\t\t};\n\t\tconst buildCross = (transform: Mat3, x: number, y: number, player: PlayerId, buttons: FixedSizeArray) => {\n\t\t\tbuildButton(transform, x + 92 * reduction, y + 24 * reduction, player, buttons[0]);\n\t\t\tbuildButton(transform, x + 92 * reduction, y + 160 * reduction, player, buttons[1]);\n\t\t\tbuildButton(transform, x + 24 * reduction, y + 92 * reduction, player, buttons[2]);\n\t\t\tbuildButton(transform, x + 160 * reduction, y + 92 * reduction, player, buttons[3]);\n\t\t};\n\t\t// rebuild the widget layout\n\t\tthis.buttonWidgets = [];\n\t\tconst y = height - bottomMargin - size;\n\t\t// player 1\n\t\tconst player1Transform = identMat3();\n\t\tbuildCross(player1Transform, sideMargin, y, 0, [0, 1, 2, 3]);\n\t\tbuildCross(player1Transform, width - sideMargin - size, y, 0, [7, 4, 6, 5]);\n\t\t// player 2\n\t\tconst player2Transform = createMat3();\n\t\tplayer2Transform[0] = -1;\n\t\tplayer2Transform[6] = width;\n\t\tplayer2Transform[4] = -1;\n\t\tplayer2Transform[7] = height;\n\t\tplayer2Transform[8] = 1;\n\t\tbuildCross(player2Transform, sideMargin, y, 1, [0, 1, 2, 3]);\n\t\tbuildCross(player2Transform, width - sideMargin - size, y, 1, [7, 4, 6, 5]);\n\t}\n\n\tprivate generateUITexture(fontSize: number) {\n\t\tconst texts = [\n\t\t\t'keyboard_arrow_up',\n\t\t\t'keyboard_arrow_down',\n\t\t\t'keyboard_arrow_left',\n\t\t\t'keyboard_arrow_right',\n\t\t\t'A',\n\t\t\t'B',\n\t\t\t'X',\n\t\t\t'Y'\n\t\t] as const;\n\t\tconst dpr = window.devicePixelRatio || 1;\n\t\tconst realFontSize = Math.ceil(fontSize * dpr);\n\t\tconst width = realFontSize * 8;\n\t\tconst height = realFontSize * 2;\n\t\tconst canvasAndContext = createOffscreenCanvasAnd2DContext(width, height);\n\t\tconst ctx = canvasAndContext.ctx;\n\t\t// ctx.clearRect(0, 0, width, height);\n\t\tctx.font = `normal ${realFontSize}px \"Material Icons\"`;\n\t\tctx.lineJoin = 'round';\n\t\tctx.shadowOffsetY = 2 * dpr;\n\t\tctx.shadowBlur = 6 * dpr;\n\t\tctx.lineWidth = dpr;\n\t\tctx.strokeStyle = 'white';\n\t\tconst uiTexCoords: number[] = [];\n\t\ttexts.forEach((text, i) => {\n\t\t\tif (i === 4) {\n\t\t\t\tconst scaledSize = realFontSize * 7 / 9;\n\t\t\t\tctx.font = `bold ${scaledSize}px \"Roboto\"`;\n\t\t\t}\n\t\t\tconst metrics = ctx.measureText(text);\n\t\t\tconst dx = i < 4 ? 0 : (realFontSize - metrics.width) / 2;\n\t\t\tconst dy = i < 4 ? 0 : -(realFontSize - metrics.actualBoundingBoxAscent - metrics.actualBoundingBoxDescent) / 2 - 1;\n\t\t\tconst bx = i * realFontSize;\n\t\t\tconst half = realFontSize / 2;\n\t\t\t// normal\n\t\t\tlet by = realFontSize;\n\t\t\tctx.fillStyle = 'black';\n\t\t\tctx.shadowColor = 'rgba(255, 255, 255, 0.7)';\n\t\t\tctx.fillText(text, bx + dx, by + dy - 2 * dpr);\n\t\t\tctx.strokeText(text, bx + dx, by + dy - 2 * dpr);\n\t\t\t// ctx.fillText(text, bx + dx, by + dy - 2 * dpr);\n\t\t\t// pressed\n\t\t\tctx.shadowColor = 'transparent';\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(bx + half, by + half, half - 1 * dpr, 0, 2 * Math.PI);\n\t\t\tctx.fill();\n\t\t\tctx.fillStyle = 'white';\n\t\t\tby += realFontSize;\n\t\t\tctx.fillText(text, bx + dx, by + dy);\n\t\t\t// update texture coordinates\n\t\t\t// normal\n\t\t\tpushTexCoord(uiTexCoords, i / 8, 0, 1 / 8, 1 / 2);\n\t\t\t// pressed\n\t\t\tpushTexCoord(uiTexCoords, i / 8, 1 / 2, 1 / 8, 1 / 2);\n\t\t});\n\t\tthis.glState.setupUITexCoords(uiTexCoords);\n\t\tthis.glState.loadTexture(this.uiTextureKey, preMultiplyAlpha(ctx.getImageData(0, 0, width, height)));\n\t}\n\n\tprivate collectDebugCrosses() {\n\t\tconst debugCrosses: [Vector2, number[]][] = [];\n\t\tif (debugCamera) {\n\t\t\tconst trackedPos = this.runtime.targetCamera instanceof Vector2 ?\n\t\t\t\tthis.runtime.targetCamera :\n\t\t\t\ttoVector2(this.runtime.targetCamera.getPosition())\n\t\t\t;\n\t\t\tdebugCrosses.push([trackedPos, [1, 0, 0, 1]]);\n\t\t\tif (this.runtime.targetCameraPos !== null) {\n\t\t\t\tdebugCrosses.push([this.runtime.targetCameraPos, [0, 1, 0, 1]]);\n\t\t\t}\n\t\t}\n\t\tif (debugContacts) {\n\t\t\tfor (let contact = this.runtime.world.getContactList(); contact; contact = contact.getNext()) {\n\t\t\t\tconst points = getContactPoints(contact);\n\t\t\t\tif (points.length > 1) {\n\t\t\t\t\tfor (const point of points) {\n\t\t\t\t\t\tdebugCrosses.push([point, [0.5, 0.5, 0.5, .7]]);\n\t\t\t\t\t}\n\t\t\t\t\tconst midPoint = points.reduce(\n\t\t\t\t\t\t(accP: Vector2, curP: Vector2) => accP.add(curP),\n\t\t\t\t\t\tVector2.zeros()\n\t\t\t\t\t).multScalar(1 / points.length);\n\t\t\t\t\tdebugCrosses.push([midPoint, [0, 0, 0, 1]]);\n\t\t\t\t} else if (points.length > 0) {\n\t\t\t\t\tdebugCrosses.push([defined(points[0]), [0, 0, 0, 1]]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (debugTouches) {\n\t\t\tfor (const touchPoint of this.runtime.touchingPoints) {\n\t\t\t\tdebugCrosses.push([touchPoint[0], [0, 0, 1, 1]]);\n\t\t\t}\n\t\t}\n\t\treturn debugCrosses;\n\t}\n\n\tprivate updateVariableDisplay() {\n\t\tif (!this.runtime.gameVariablesChanged || this.retryButtonVisible) {\n\t\t\treturn;\n\t\t}\n\t\tthis.runtime.eatGameVariablesChanged();\n\n\t\tif (this.lastVariableCount !== this.runtime.gameVariables.size) {\n\t\t\tthis.lastVariableCount = this.runtime.gameVariables.size;\n\n\t\t\t// Clear display content\n\t\t\tconst grid = this.variablesDisplay;\n\t\t\tgrid.innerText = '';\n\n\t\t\t// Re-create variable grid with latest values\n\t\t\tthis.runtime.gameVariables.forEach((value, id) => {\n\t\t\t\tconst { canvas, ctx } = createCanvasAnd2DContextHiDPI(32, 32);\n\t\t\t\tif (id === 0) {\n\t\t\t\t\tdrawScoreIcon(ctx, 16, 16);\n\t\t\t\t} else {\n\t\t\t\t\tconst variable = defined(this.runtime.game.variables[id - 1]);\n\t\t\t\t\tif (!variable.visible) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// TODO: render variable text\n\t\t\t\t\tdrawCanvasInBox(ctx, getVariableMiniature(variable.name, true), 32);\n\t\t\t\t}\n\t\t\t\tgrid.appendChild(canvas);\n\t\t\t\tconst valueText = document.createElement('SPAN');\n\t\t\t\tvalueText.innerText = value.toString();\n\t\t\t\tgrid.appendChild(valueText);\n\t\t\t});\n\n\t\t\t// Display if there are any variables to show\n\t\t\tif (grid.children.length > 0 && !Features.hideVariablesInPlay) {\n\t\t\t\tgrid.style.visibility = 'visible';\n\t\t\t}\n\t\t} else {\n\t\t\t// Change values\n\t\t\tconst grid = this.variablesDisplay;\n\t\t\tlet variableIndex = 0;\n\t\t\tthis.runtime.gameVariables.forEach((value, id) => {\n\t\t\t\tif (id === 0 || defined(this.runtime.game.variables[id - 1]).visible) {\n\t\t\t\t\tdowncast(HTMLSpanElement, grid.children[variableIndex * 2 + 1]).innerText = value.toString();\n\t\t\t\t\tvariableIndex++;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate dialogClicked() {\n\t\tif (!this.gameOver && !this.gamePaused) {\n\t\t\tthis.hideDialog();\n\t\t}\n\t}\n\n\tprotected showDialog(gameOver: boolean, screen: number | null) {\n\t\t// if block game screen is already visible and in game over, do not do anything\n\t\tif (this.dialogVisible && this.gameOver) {\n\t\t\treturn;\n\t\t}\n\t\tif (gameOver) {\n\t\t\tthis.gameOver = true;\n\t\t\t// first update score\n\t\t\tthis.updateVariableDisplay();\n\t\t} else {\n\t\t\t// if not game over and no screen selected, do nothing\n\t\t\tif (screen === null) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// hide controls if no screen was shown\n\t\tif (this.activeDialog === null) {\n\t\t\tthis.overlayForceHideControls();\n\t\t}\n\n\t\t// show screen\n\t\tthis.dialogOverlay.style.display = '';\n\t\tthis.activeDialog = screen !== null ? this.runtime.game.dialogs[screen] ?? null : null;\n\t\tthis.resizeAndRenderBlockGameOverlay();\n\n\t\t// show retry button when game over\n\t\tif (gameOver) {\n\t\t\tthis.retryButtonVisible = true;\n\t\t}\n\t}\n\n\tprivate hideDialog() {\n\t\tthis.dialogOverlay.style.display = 'none';\n\t\tthis.overlayUnForceHideControls();\n\t\tthis.retryButtonVisible = false;\n\t\tthis.activeDialog = null;\n\t}\n\n\tprivate unsetGameOver() {\n\t\tthis.gameOver = false;\n\t\tthis.hideDialog();\n\t}\n\n\tprotected returnButtonClicked() {\n\t\tthis.stopGame();\n\t}\n\n\tprivate stopGame() {\n\t\tif (this.buttonActivatedCallback) {\n\t\t\tthis.buttonActivatedCallback(Button.Stop);\n\t\t}\n\t\tif (window.getComputedStyle(this.returnLayer).display !== 'none') {\n\t\t\tthis.stopGameCallback();\n\t\t\tthis.unsetGameOver();\n\t\t}\n\t}\n\n\tprotected stopGameCallback() {\n\t\tscreenManager.pop();\n\t}\n\n\tprivate resizeAndRenderBlockGameOverlay() {\n\t\tresizeCanvas(this.dialogOverlay, null);\n\t\tconst endGameCtx = nonnull(this.dialogOverlay.getContext('2d'));\n\t\tconst clientRect = this.dialogOverlay.getBoundingClientRect();\n\t\tconst w = clientRect.width;\n\t\tconst h = clientRect.height;\n\n\t\tassert(this.gamePaused || this.gameOver || this.activeDialog !== null, 'Game is neither paused nor over yet the dialog overlay is redrawn');\n\n\t\tconst fillShadedBlackAndWriteText = (text: string) => {\n\t\t\t// shaded black\n\t\t\tendGameCtx.fillStyle = 'rgba(0, 0, 0, 0.6)';\n\t\t\tendGameCtx.fillRect(0, 0, this.dialogOverlay.width, this.dialogOverlay.height);\n\t\t\t// write text\n\t\t\tendGameCtx.fillStyle = 'white';\n\t\t\tconst fontSize = w >= 380 ? 60 : 45;\n\t\t\tendGameCtx.font = `bold ${fontSize}px \"Roboto\"`;\n\t\t\tendGameCtx.textAlign = 'center';\n\t\t\tendGameCtx.fillText(text, w / 2, h / 2);\n\t\t};\n\n\t\tif (this.gameOver || this.activeDialog !== null) {\n\t\t\tif (this.activeDialog !== null) {\n\t\t\t\tif (this.activeDialog.backgroundColor.alpha !== 0) {\n\t\t\t\t\tendGameCtx.fillStyle = this.activeDialog.backgroundColor.rgbaHexString;\n\t\t\t\t\tendGameCtx.fillRect(0, 0, w, h);\n\t\t\t\t} else {\n\t\t\t\t\tendGameCtx.clearRect(0, 0, w, h);\n\t\t\t\t}\n\t\t\t\tconst screenSize = new Vector2(w, h);\n\t\t\t\tconst size = screenSize.multScalar(this.activeDialog.scaleFactor);\n\t\t\t\tconst emptyScale = 1 - this.activeDialog.scaleFactor;\n\t\t\t\tconst topLeft = screenSize.multScalar(emptyScale * 0.5);\n\t\t\t\tdrawCanvasInBox(endGameCtx, this.activeDialog.image, size, topLeft);\n\t\t\t} else {\n\t\t\t\tfillShadedBlackAndWriteText(qsT('Game over'));\n\t\t\t}\n\t\t} else {\n\t\t\tfillShadedBlackAndWriteText(qsT('Paused'));\n\t\t}\n\t}\n\n\tprivate retryGame() {\n\t\tthis.stopWorld();\n\t\tif (this.buttonActivatedCallback) {\n\t\t\tthis.buttonActivatedCallback(Button.Retry);\n\t\t}\n\t\tthis.initWorld();\n\t\tthis.unsetGameOver();\n\t}\n\n\tpublic show(from: Screen | null) {\n\t\t// load textures from the game\n\t\tthis.loadObjectTextures();\n\n\t\t// clear all previous checkpoints\n\t\tthis.runtime.checkPoints.clear();\n\n\t\t// init the world from the level\n\t\tthis.initWorld();\n\n\t\t// setup the CSS given the player configuration\n\t\tthis.setupCSS();\n\n\t\t// show the runtime screen\n\t\tsuper.show(from);\n\n\t\t// recreate input vector, scan existing gamepads and setup callbacks\n\t\tthis.setupInputs();\n\n\t\t// do a first render\n\t\tthis.frameCounter = 0;\n\t\tthis.computationDuration = 0;\n\t\tthis.scheduleStep();\n\n\t\t// report to analytics\n\t\treportLog('startGame', this.runtime.gameId);\n\t}\n\n\tpublic hide(to: Screen | null) {\n\t\t// report to analytics\n\t\treportLog('stopGame', this.getTimeStats());\n\n\t\t// hides the runtime screen\n\t\tsuper.hide(to);\n\n\t\t// reset members as upon construction\n\t\tthis.stopWorld();\n\n\t\t// delete textures\n\t\tthis.glState.deleteTexturesButKeep(this.uiTextureKey);\n\n\t\t// remove gamepad callbacks\n\t\tthis.inputs.ignoreGamepads();\n\n\t\t// hide the text input\n\t\tthis.hideTextInput();\n\t}\n\n\tprivate setupCSS() {\n\t\tif (this.twoPlayers) {\n\t\t\tthis.variablesDisplay.classList.add('runtime-variables__twoPlayers');\n\t\t\tnonnull(document.getElementById('runtime-return')).classList.add('runtime-return__twoPlayers');\n\t\t\tthis.returnLayer.classList.add('runtime-return-layer__twoPlayers');\n\t\t\tnonnull(document.getElementById('runtime-more')).classList.add('runtime-more__twoPlayers');\n\t\t} else {\n\t\t\tthis.variablesDisplay.classList.remove('runtime-variables__twoPlayers');\n\t\t\tnonnull(document.getElementById('runtime-return')).classList.remove('runtime-return__twoPlayers');\n\t\t\tthis.returnLayer.classList.remove('runtime-return-layer__twoPlayers');\n\t\t\tnonnull(document.getElementById('runtime-more')).classList.remove('runtime-more__twoPlayers');\n\t\t}\n\t}\n\n\tprivate setupInputs() {\n\t\t// recreate input vector and set initial assigned inputs\n\t\tthis.inputs.sources = [...this.defaultInputs, this.numpadInput];\n\t\tif (this.twoPlayers) {\n\t\t\tthis.inputs.sources.push(this.screenInputs[1]);\n\t\t\tthis.assignedInputs = [this.screenInputs[0], this.screenInputs[1]];\n\t\t} else {\n\t\t\tthis.assignedInputs = this.inputs.sources;\n\t\t}\n\t\tthis.inputs.monitorGamepads();\n\t}\n\n\tprivate showInputAssignmentDialogue(input: InputSource) {\n\t\tconst name = input.name;\n\t\tif (this.assignInputDialogue.isOpen || this.assignInputDialogueSourceTrigger !== null) {\n\t\t\treturn;\n\t\t}\n\t\tconst contentElement = nonnull(document.getElementById('runtime-assignInput__content'));\n\t\tcontentElement.innerText = name;\n\t\tthis.assignInputDialogueSourceTrigger = input;\n\t\tthis.assignInputDialogue.open();\n\t}\n\n\tprivate processInputAssignmentDialogueShortcuts() {\n\t\tconst input = this.assignInputDialogueSourceTrigger;\n\t\tif (input === null || !this.assignInputDialogue.isOpen) {\n\t\t\treturn;\n\t\t}\n\t\tconst buttons = getChildElementsByTag(this.assignInputDialogueElement, 'button')\n\t\tfor (let index = 0; index < buttons.length; index += 1) {\n\t\t\tconst button = buttons[index];\n\t\t\tif (document.activeElement === button) {\n\t\t\t\tif (input.isButtonActivated(Button.Right)) {\n\t\t\t\t\tbuttons[(index + 1) % buttons.length]!.focus();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (input.isButtonActivated(Button.Left)) {\n\t\t\t\t\tbuttons[(index + buttons.length - 1) % buttons.length]!.focus();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (input.isButtonActivated(Button.A)) {\n\t\t\t\t\tbutton.click();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate assignInput(event: MDCDialogCloseEvent) {\n\t\tconst input = this.assignInputDialogueSourceTrigger;\n\t\tassert(input !== null);\n\t\tthis.assignInputDialogueSourceTrigger = null;\n\t\tconst action = event.detail.action;\n\t\tif (!action || action === 'close') {\n\t\t\treturn;\n\t\t}\n\t\t// if input not in input list, it was disconnected since the dialogue was triggered, so return\n\t\tconst index = parseInt(action, 10);\n\t\tif (this.inputs.sources.indexOf(input) < 0) {\n\t\t\treturn;\n\t\t}\n\t\tconsole.info(`Reassigned input ${index} to ${input.name}`);\n\t\tthis.assignedInputs[index] = input;\n\t}\n\n\tprivate isScreenInputActive(player: PlayerId) {\n\t\tif (this.twoPlayers) {\n\t\t\tconst screenInput = this.screenInputs[player];\n\t\t\treturn this.assignedInputs.includes(screenInput);\n\t\t} else {\n\t\t\treturn player === 0;\n\t\t}\n\t}\n\n\tprivate loadObjectTextures() {\n\t\tassert(this.glState.textureCount === 1);\n\t\tfor (const objectType of this.runtime.game.objects) {\n\t\t\tfor (const animation of objectType.animations) {\n\t\t\t\tfor (const frame of animation.frames) {\n\t\t\t\t\tconst sprite = frame.sprite;\n\t\t\t\t\tif (this.glState.hasTexture(sprite)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst canvasWithKey = cast(CanvasWithKey, sprite);\n\t\t\t\t\tthis.glState.loadTexture(sprite, preMultiplyAlpha(canvasWithKey.imageData));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate initWorld() {\n\t\tthis.runtime.initWorld();\n\t\tthis.backgroundColor = this.runtime.game.level.camera.backgroundColor.toSpace('rgb');\n\t\tthis.glState.updateWorldBounds(this.runtime.worldBounds);\n\t\tthis.worldBoundTopLeft = vector2ToVec3Homo(this.runtime.worldBounds.topLeft);\n\t\tthis.worldBoundBottomRight = vector2ToVec3Homo(this.runtime.worldBounds.bottomRight);\n\t\tthis.lastVariableCount = NaN;\n\t\tthis.variablesDisplay.style.visibility = 'hidden';\n\t\tthis.activeInputButtons = this.runtime.game.getActiveInputButtons();\n\t\tthis.inputs.init();\n\t}\n\n\tprivate stopWorld() {\n\t\tthis.runtime.stopWorld();\n\t}\n\n\tprivate worldUnitPerPixel() {\n\t\tconst screenRatio = this.canvasRect.width / this.canvasRect.height;\n\t\tconst extentRatio = this.runtime.cameraExtent.aspectRatio;\n\t\tconst spaceOnX = screenRatio >= extentRatio;\n\t\tconst cameraExtent = spaceOnX ? this.runtime.cameraExtent.y : this.runtime.cameraExtent.x;\n\t\tif (spaceOnX) {\n\t\t\treturn cameraExtent / this.canvasRect.height;\n\t\t} else {\n\t\t\treturn cameraExtent / this.canvasRect.width;\n\t\t}\n\t}\n\n\tprivate computeViewportToWorldTransformGL() {\n\t\tconst viewportToWorldGL = createMat3();\n\t\tconst screenRatio = this.canvasRect.width / this.canvasRect.height;\n\t\tconst extentRatio = this.runtime.cameraExtent.aspectRatio;\n\t\tconst spaceOnX = screenRatio >= extentRatio;\n\t\tconst scaleX = spaceOnX ? screenRatio : 1;\n\t\tconst scaleY = spaceOnX ? 1 : 1 / screenRatio;\n\t\tconst halfCameraExtent = (spaceOnX ? this.runtime.cameraExtent.y : this.runtime.cameraExtent.x) * 0.5;\n\t\tviewportToWorldGL[0] = halfCameraExtent * scaleX;\n\t\tviewportToWorldGL[4] = halfCameraExtent * scaleY * -1;\n\t\tconst currentCamera = this.runtime.displacedCurrentCamera;\n\t\tviewportToWorldGL[6] = currentCamera.x;\n\t\tviewportToWorldGL[7] = currentCamera.y;\n\t\tviewportToWorldGL[8] = 1;\n\t\treturn viewportToWorldGL;\n\t}\n\n\tprivate computeScreenToViewportTransformGL() {\n\t\tconst screenToViewport = createMat3();\n\t\tscreenToViewport[0] = 2 / this.canvasRect.width;\n\t\tscreenToViewport[4] = -2 / this.canvasRect.height;\n\t\tscreenToViewport[6] = -1;\n\t\tscreenToViewport[7] = 1;\n\t\tscreenToViewport[8] = 1;\n\t\treturn screenToViewport;\n\t}\n\n\tprivate computeScreenToWorldTransformGL() {\n\t\treturn multMat3Mat3(this.computeViewportToWorldTransformGL(), this.computeScreenToViewportTransformGL());\n\t}\n\n\tprivate buttonLocation(x: number, y: number, size = 72) {\n\t\tconst normalizedToScreen = createMat3();\n\t\tnormalizedToScreen[0] = size;\n\t\tnormalizedToScreen[4] = size;\n\t\tnormalizedToScreen[6] = x;\n\t\tnormalizedToScreen[7] = y;\n\t\tnormalizedToScreen[8] = 1;\n\t\treturn normalizedToScreen;\n\t}\n\n\tprivate get screenCenter() {\n\t\treturn new Vector2(this.canvasRect.width / 2, this.canvasRect.height / 2);\n\t}\n}\n","/**\n * @module utils\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nimport { nonnull } from './types';\n\nexport function createCanvasAnd2DContext(width: number, height: number) {\n\tconst canvas = document.createElement('canvas');\n\tcanvas.width = width;\n\tcanvas.height = height;\n\tconst ctx = nonnull(canvas.getContext('2d'));\n\treturn { canvas, ctx };\n}\n\nexport function createCanvasAnd2DContextHiDPI(width: number, height: number) {\n\tconst dpr = window.devicePixelRatio || 1;\n\tconst { canvas, ctx } = createCanvasAnd2DContext(width * dpr, height * dpr);\n\tctx.scale(dpr, dpr);\n\treturn { canvas, ctx };\n}\n\nexport function createOffscreenCanvasAnd2DContext(width: number, height: number) {\n\tif (typeof OffscreenCanvas !== 'undefined') {\n\t\tconst offscreen = new OffscreenCanvas(width, height);\n\t\tconst ctx = nonnull(offscreen.getContext('2d'));\n\t\treturn { canvas: offscreen, ctx };\n\t} else {\n\t\treturn createCanvasAnd2DContext(width, height);\n\t}\n}\n\nexport function createOffscreenCanvasAnd2DContextHiDPI(width: number, height: number) {\n\tconst dpr = window.devicePixelRatio || 1;\n\tconst { canvas, ctx } = createOffscreenCanvasAnd2DContext(width * dpr, height * dpr);\n\tctx.scale(dpr, dpr);\n\treturn { canvas, ctx };\n}","/**\n * @module utils\n */\n/** comment to work-around limitation of typedoc module plugin */\n\n// Copyright 2018-2024 Enlightware GmbH, Switzerland\n\nconst uniqueIdMap: Map = new Map();\n\nexport function uniqueId(value: any) {\n\tconst id = uniqueIdMap.get(value);\n\tif (id !== undefined) {\n\t\treturn id;\n\t} else {\n\t\tconst newId = uniqueIdMap.size;\n\t\tuniqueIdMap.set(value, newId);\n\t\treturn newId;\n\t}\n}"],"names":["layoutTextWithSizer","text","textSizer","maxWidth","splitOn","hasSegmenter","Intl","Segmenter","splitLength","textLayout","pushLine","line","length","endsWith","slice","push","endSymbol","endSymbolLength","inputLine","split","currentLength","segments","language","granularity","segment","nonWordLength","isWordLike","word","layoutText","font","size","x","collisionDistance","parentShape","childShape","collisionAngle","parentScale","childToParentTransformation","parentTransformation","scalingRotation","a","b","labelledPoints","getPolygonSideIndices","map","i","sort","p1","p2","y","maxD","Infinity","labelAtI","pi","j","xOverY","sub","aspectRatio","labelSignum","k","w","d","Math","max","collisionDistanceOnXAxis","toSimilarityTransform","after","polygon","side","Array","indices","sideSignum","lastAdded","iInc","euclideanQuotient","dividend","divisor","floor","ceil","euclideanRemainder","remainder","abs","colorFragmentShader","objectTextureCoordArrayOrig","ObjectGL1State","objectUPoseToWorld","objectUAlpha","constructor","ObjectGL2State","poseToWorldLoc","alphaLoc","poseToWorldBuffer","poseToWorldData","Float32Array","alphaBuffer","alphaData","instanceCount","pushInstance","poseToWorld","alpha","this","newPoseToWorldData","set","newAlphaData","clearInstances","setupPoseToWorldBuffer","gl","setupBufferForInstances","setupAlphaBuffer","baseLoc","internalBuffer","glBufferName","floatCount","attribCount","createBuffer","bindBuffer","ARRAY_BUFFER","bufferView","buffer","bufferData","DYNAMIC_DRAW","stride","shift","loc","enableVertexAttribArray","offset","vertexAttribPointer","FLOAT","vertexAttribDivisor","GLState","objectProgram","objectUWorldToViewport","objectUSampler","objectStateVer","objectVertexBuffer","objectAVertexPosition","objectTextureCoordBuffer","objectATextureCoord","objectTextureCoordArray","crossProgram","crossUWorldToViewport","crossUPosition","crossUWorldSize","crossUColor","crossVertexBuffer","crossAVertexPosition","boundsProgram","boundsUWorldToViewport","boundsUColor","boundsVertexBuffer","boundsAVertexPosition","textures","Map","lastBoundTexture","lastPushedAlpha","canvas","gl2","forceGL1","getContext","webGL2","console","debug","dpr","window","devicePixelRatio","debugInfo","getExtension","ver","MAX_VERTEX_ATTRIBS","getParameter","MAX_VARYING_VECTORS","MAX_TEXTURE_SIZE","MAX_ARRAY_TEXTURE_LAYERS","VENDOR","UNMASKED_VENDOR_WEBGL","RENDERER","UNMASKED_RENDERER_WEBGL","init","isGl2","lineWidth","compileProgram","getUniformLocation","getAttribLocation","useProgram","uniform4fv","enable","BLEND","blendFunc","ONE","ONE_MINUS_SRC_ALPHA","restoreTextures","reInit","isWebGL2","newTextures","key","_texture","data","createTexture","texture","bindTexture","TEXTURE_2D","texImage2D","RGBA","UNSIGNED_BYTE","generateMipmap","texParameteri","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","TEXTURE_MIN_FILTER","LINEAR_MIPMAP_LINEAR","LINEAR","TEXTURE_MAG_FILTER","loadTexture","hasTexture","has","getTexture","get","deleteTexture","undefined","delete","log","deleteTexturesButKeep","keyToKeep","imageData","textureCount","setupUITexCoords","coords","concat","updateBuffer","setupRenderUI","screenToViewport","uniform1f","uniformMatrix3fv","renderUIElement","normalizedToScreen","elementId","setupBuffer","setupObjectGL2State","drawArraysInstanced","TRIANGLE_STRIP","drawArrays","finishRenderUI","renderObjectInstances","setupRenderObjects","worldToViewport","activeTexture","TEXTURE0","uniform1i","renderObject","spriteToWorld","finishRenderObjects","objectState","setupRenderCross","worldSize","renderCross","position","color","uniform2fv","LINES","updateWorldBounds","worldBounds","topLeft","topRight","bottomRight","bottomLeft","setupRenderWorldBounds","renderWorldBounds","LINE_LOOP","compileShader","source","type","shader","createShader","shaderSource","getShaderParameter","COMPILE_STATUS","error","VERTEX_SHADER","getShaderInfoLog","warn","vertexShader","fragmentShader","program","createProgram","attachShader","FRAGMENT_SHADER","linkProgram","getProgramParameter","LINK_STATUS","errorMessage","getProgramInfoLog","Error","STATIC_DRAW","attribute","GamepadAngleThreshold","InputSource","name","lastState","curState","retryGame","stopGame","check","storeCurAsLast","isButtonActive","button","setButtonActive","active","isButtonActivated","last","isButtonDeactivated","isAnyButtonActive","toString","Inputs","sources","gamepads","navigator","getGamepads","gamepadConnectedListener","gamepadDisconnectedListener","inputSource","scanGamepads","merge","merged","reduce","states","monitorGamepads","gamepadConnected","bind","addEventListener","gamepadDisconnected","gamepad","addGamepad","ignoreGamepads","removeEventListener","sourcesText","join","event","removeGamepads","input","gamepadInput","GamepadInputSource","index","info","id","filter","super","gp","axes","buttons","pressed","KeyboardInputSource","processKeyDown","code","startsWith","which","processKeyUp","NumpadInputSource","createMat3","scalarToVec3Homo","vector2ToVec3Homo","vector2","vec3HomoToVector2","vec3","multMat3Vec3","mat3","output","v","multMat3Mat3","col","row","invertMat3","g","e","h","c","f","div","identMat3","vecToVec2","vec","Vec2","CanvasAttributes","textColor","textHorizontalAlignment","textVerticalAlignment","strokeColor","fillColor","fontSize","resolution","CanvasOverlay","textureKey","pixelToPose","ctx","boundingRect","Symbol","width","height","scaling","translation","multScalar","scalingTranslation","toGLMat3","getImageData","CanvasRenderAction","ClearCanvas","render","overlay","attr","DrawText","textAlign","textBaseline","fillStyle","layout","measureText","lineHeight","forEach","_","fillText","DrawLine","x1","y1","x2","y2","strokeStyle","beginPath","moveTo","lineTo","stroke","DrawRect","strokeRect","FillRect","fillRect","DrawEllipse","rx","ry","ellipse","PI","FillEllipse","fill","SetFontSize","SetTextAlignment","horizontalAlignment","verticalAlignment","SetTextColor","SetStrokeColor","SetFillColor","FakeLLM","newConversation","ask","_prompt","hasResponse","getResponse","clearReadStates","CloudflareLLM","authKey","messages","response","responseRead","inProgress","systemMessage","role","content","prompt","askAsync","url","request","Request","method","headers","body","JSON","stringify","stream","fetch","ok","status","responseText","async","onResponse","EVENTSTREAM_PREFIX","EVENTSTREAM_ENDED","reader","pipeThrough","TextDecoderStream","getReader","value","done","read","lines","pop","indexOf","msgChunk","substring","parse","cancel","readServerSideEventStream","_llm","llm","llmAuth","newLlmConversation","askLlm","hasLlmResponse","getLlmResponse","clearLlmReadStates","runtimeData","setScriptRuntimeData","runtime","bodyData","logCtx","getCandliVariable","scope","getVariableByScopeAndIndex","invalidVarReadExceptionFired","getScriptVariable","game","variables","default_value","gameSessionId","textInputActive","getTextInput","textInputContent","message","setCandliVariable","setVariableByScopeAndIndex","setScriptVariable","logGameEvent","gameId","session","startTextInput","initial","stopTextInput","checkPoint","point","checkPoints","add","openURL","open","clearCanvas","addCanvasRenderAction","drawText","drawLine","drawRect","drawEllipse","fillEllipse","setFontSize","setTextAlignment","setTextColor","canvasAttributes","setStrokeColor","setFillColor","attachCamera","spawnObject","object","angle","scale","pose","objectType","objectTypeByName","createObject","getPilaCompetency","latest","getCompetency","setPilaCompetency","v0","v1","setCompetency","SpeechRecognition","webkitSpeechRecognition","RealRecognitionState","requested","recording","result","resultRead","errorRead","speechRecognition","continuous","userAgent","getOSName","interimResults","lang","onstart","onresult","isFinal","transcript","resultAlternatives","results","onerror","onend","start","stop","isRecording","hasResult","getResult","hasError","getError","FakeRecognitionState","_speechRecognition","isSupported","getBrowserName","userAgentData","brands","brand","isSpeechRecognitionSupported","startSpeechRecognition","stopSpeechRecognition","hasSpeechRecognitionResult","getSpeechRecognitionResult","hasSpeechRecognitionError","getSpeechRecognitionError","clearSpeechRecognitionReadStates","debugCamera","devMode","debugContacts","debugTouches","ButtonCount","ButtonNormalizedCenter","ButtonNormalizedRadius2","pushTexCoord","array","left","top","right","bottom","BrowserTextAreaExtraSpacings","chrome","edge","firefox","safari","samsung_internet","uiTextureFontLoadPromise","realFontSize","iconFont","buttonFont","Promise","all","document","fonts","load","RuntimeScreen","dialogOverlay","HTMLCanvasElement","getElementById","activeDialog","returnLayer","variablesDisplay","HTMLElement","retryButton","runtimeStats","gameOver","gamePaused","_forceHideControls","controlsForcedHiddenBeforeOverlay","lastVariableCount","NaN","backgroundColor","touches","newTouches","Set","mouseTouch","newMouseTouch","animRequestId","glState","uiTextureKey","buttonWidgets","activeInputButtons","keyboardInput","numpadInput","screenInputs","defaultInputs","inputs","assignedInputs","assignInputDialogueElement","assignInputDialogue","assignInputDialogueSourceTrigger","uiTouches","frameCounter","computationDuration","computationStatWindow","computationStatIndex","canvasCreationStat","worldBoundTopLeft","worldBoundBottomRight","textInput","HTMLTextAreaElement","textAreaVerticalOffset","canvasRect","getBoundingClientRect","buttonActivatedCallback","buttonDeactivatedCallback","browserName","textAreaOffsets","preventDefault","cancelAnimationFrame","_event","scheduleStep","generateUITexture","self","isTextInputVisible","showTextInput","hideTextInput","initiator","showDialog","dialogClicked","onclick","returnButtonClicked","retryGameCallback","listen","assignInput","style","display","touchEvents","handleTouchEvent","touchEvent","TouchEvent","touch","changedTouches","identifier","toLowerCase","passive","mouseEvent","MouseEvent","clientX","clientY","clearMouseTouch","twoPlayers","retryButtonVisible","visible","retryButtonActive","retry","contactCallback","callback","forceHideReturnButton","hidden","forceHideControls","overlayForceHideControls","wasHidden","overlayUnForceHideControls","forceHideWidgets","resetDefaultSettings","dialogVisible","assertNoCallbacks","inspectGameVariables","gameVariables","pause","resizeAndRenderBlockGameOverlay","unpause","hideDialog","lastStepTime","setGame","getGameId","getTimeStats","wallTime","worldTime","cpuTime","frameCtr","getCheckPoints","blur","updateTextInputStyle","focus","textInputInitiator","worldToScreen","computeScreenToWorldTransformGL","screenCenterPos","pos","shape","screenSize","worldUnitPerPixel","canvasResolution","fontSizeRatioWidth","fontSizeScreen","resized","updateButtonWidgets","keyDown","keyUp","appHidden","appVisible","buttonActivated","buttonDeactivated","requestAnimationFrame","step","timestamp","buttonWidget","player","transforms","isScreenInputActive","glButtonCheck","lastButtonStates","buttonStates","processInputAssignmentDialogueShortcuts","isOpen","includes","buttonPressed","showInputAssignmentDialogue","cur","viewportToWorldPreStep","computeViewportToWorldTransformGL","cx","cy","screenCenter","screenToWorld","touchingPoints","clear","viewportToWorldPostStep","updateVariableDisplay","totalTime","perfStats","fps","acc","canvasCreationPerFrame","toFixed","innerText","performance","now","viewportToWorld","renderCanvasOverlay","renderAABB","AABB","viewport","bg","clearColor","components","COLOR_BUFFER_BIT","viewportTopLeftWorldBound","viewportBottomRightWorldBound","layers","world","queryAABB","fixture","getBody","getUserData","kind","layer","zOrder","getFixtureList","animation","animations","frame","frames","frameIndex","sprite","spriteToPose","partFromPixelTransform","xInputScale","flippingFactors","yInputScale","getAngle","cosA","cos","sinA","sin","getPosition","textOverlay","canvasOverlay","textTexture","uiTexture","computeScreenToViewportTransformGL","state","glButtonRender","debugCrosses","collectDebugCrosses","crossPixelSize","crossWorldSize","worldPos","dataRowMajor","target","actions","canvasRenderActions","createOverlayIfNeeded","action","_normalizedToScreen","screenToNormalized","some","touchPoint","dx","dy","_screenToNormalized","bottomMargin","sideMargin","reduction","buildButton","transform","localLoc","buttonLocation","locInv","buildCross","player1Transform","player2Transform","lineJoin","shadowOffsetY","shadowBlur","uiTexCoords","scaledSize","metrics","actualBoundingBoxAscent","actualBoundingBoxDescent","bx","half","by","shadowColor","strokeText","arc","trackedPos","targetCamera","targetCameraPos","contact","getContactList","getNext","points","midPoint","accP","curP","zeros","gameVariablesChanged","eatGameVariablesChanged","grid","variable","appendChild","valueText","createElement","children","hideVariablesInPlay","visibility","variableIndex","HTMLSpanElement","screen","dialogs","unsetGameOver","getComputedStyle","stopGameCallback","endGameCtx","clientRect","fillShadedBlackAndWriteText","rgbaHexString","clearRect","scaleFactor","emptyScale","image","stopWorld","initWorld","show","from","loadObjectTextures","setupCSS","setupInputs","hide","to","classList","remove","activeElement","click","detail","parseInt","screenInput","objects","canvasWithKey","level","camera","toSpace","getActiveInputButtons","spaceOnX","cameraExtent","viewportToWorldGL","screenRatio","scaleX","scaleY","halfCameraExtent","currentCamera","displacedCurrentCamera","createCanvasAnd2DContext","createCanvasAnd2DContextHiDPI","createOffscreenCanvasAnd2DContext","OffscreenCanvas","offscreen","createOffscreenCanvasAnd2DContextHiDPI","uniqueIdMap","uniqueId","newId"],"sourceRoot":""}