From bb47c5575483ee09874fbacf139d37dac084e714 Mon Sep 17 00:00:00 2001 From: Yoshiki Ohshima Date: Wed, 30 Aug 2023 14:14:20 -0700 Subject: [PATCH] use library versio 0.7.5 --- assets/css/joystick.css | 2 +- assets/css/microverse.css | 12 +- behaviors/PrototypeBehavior.d.ts | 1803 +++++++++++++++++ behaviors/croquet/avatarEvents.js | 23 +- behaviors/croquet/avatarVoiceLevel.js | 43 + behaviors/croquet/billboard.js | 11 +- behaviors/croquet/dragAndDrop.js | 11 +- behaviors/croquet/elected.js | 13 +- behaviors/croquet/fullBodyAvatar.js | 11 +- behaviors/croquet/gizmo.js | 29 +- behaviors/croquet/halfBodyAvatar.js | 13 +- behaviors/croquet/menu.js | 24 +- behaviors/croquet/pdfview.js | 19 +- behaviors/croquet/pedestal.js | 21 +- behaviors/croquet/physics.js | 12 +- behaviors/croquet/propertySheet.js | 34 +- behaviors/croquet/rapier.js | 12 +- behaviors/croquet/scrollableArea.js | 17 +- behaviors/croquet/singleUser.js | 12 +- behaviors/croquet/stickyNote.js | 12 +- behaviors/croquet/video.js | 19 +- .../{bitcoinTracker.js => bitcoinTracker.ts} | 76 +- index.html | 2 +- lib/{index-8d2ac4f0.js => index-aef48027.js} | 1071 +++++----- meta/version.txt | 2 +- package-lock.json | 185 +- package.json | 4 +- prelude.js | 14 +- worlds/default.js | 2 +- 29 files changed, 2819 insertions(+), 690 deletions(-) create mode 100644 behaviors/PrototypeBehavior.d.ts create mode 100644 behaviors/croquet/avatarVoiceLevel.js rename behaviors/default/{bitcoinTracker.js => bitcoinTracker.ts} (80%) rename lib/{index-8d2ac4f0.js => index-aef48027.js} (92%) diff --git a/assets/css/joystick.css b/assets/css/joystick.css index f9fdc29..8b5a21c 100644 --- a/assets/css/joystick.css +++ b/assets/css/joystick.css @@ -1,5 +1,5 @@ #joystick { - position: fixed; + position: absolute; left: 50%; bottom: 50px; -ms-transform: translate(-50%, 0%); diff --git a/assets/css/microverse.css b/assets/css/microverse.css index 76d7c79..420b984 100644 --- a/assets/css/microverse.css +++ b/assets/css/microverse.css @@ -76,6 +76,14 @@ body.tilt > iframe { /* TODO Solve this in HTML */ } +#microverse { + position: relative; + /* position" relative is important as it makes the control buttons inside laid out accordingly. */ + width: 100%; + height: 100%; + touch-action: none; +} + .info-text { color: #fff; z-index: 200; @@ -348,7 +356,7 @@ body.tilt > iframe { } .btn-ui { - position: fixed; + position: absolute; background-color: rgba(0, 0, 0, 0.5); z-index: 200; border-radius: 50%; @@ -385,7 +393,7 @@ body.tilt > iframe { align-items: center; flex-direction: column; - position: fixed; + position: absolute; width: 0px; height: 50px; diff --git a/behaviors/PrototypeBehavior.d.ts b/behaviors/PrototypeBehavior.d.ts new file mode 100644 index 0000000..66c7703 --- /dev/null +++ b/behaviors/PrototypeBehavior.d.ts @@ -0,0 +1,1803 @@ +export type Quaternion = [number, number, number, number]; +export type Vector3 = [number, number, number]; +export type Vector2 = [number, number]; +export type Matrix2 = [number, number, number, number]; +export type Matrix3 = [number, number, number, number, number, number, number, number, number]; + +export type EventName = "pointerDown"|"pointerUp"|"pointerMove"|"pointerTap"|"pointerLeave"|"pointerEnter"|"pointerWheel"|"pointerDoubleDown"|"click"|"keyUp"|"keyDown"; + +export type EventMask = {altKey?: boolean, shiftKey?: boolean, ctrlKey?: boolean, metaKey?: boolean}; + +export type VQ = {v: Vector3, q: Quaternion}; + +export type Matrix4 = [ + number, number, number, number, + number, number, number, number, + number, number, number, number, + number, number, number, number +]; + +export type WorldcoreExports = { + slerp(a: number, b: number, t: number): number, + + /** + * Null 2-vector [0, 0] + * @public + * @returns {Vector2} + */ + v2_zero(): Vector2, + /** + * Random point on a unit circle. + * @public + * @returns {Vector2} + */ + v2_random(): Vector2, + + /** + * Magnitude of vector. + * @public + * @param {Vector2} v + * @returns {number} + */ + v2_magnitude(v: Vector2): number, + + /** + * Squared magnitude of vector. + * @public + * @param {Vector2} v + * @returns {number} + */ + v2_sqrMag(v: Vector2): number, + + /** + * Normalized vector. (Error on magnitude 0) + * @public + * @param {Vector2} v + * @returns {number[]} + */ + v2_normalize(v: Vector2): Vector2, + + /** + * Absolute value of all elements. + * @public + * @param {Vector2} v + * @returns {Vector2} + */ + v2_abs(v: Vector2): Vector2, + + /** + * Ceiling of all elements. + * @public + * @param {Vector2} v + * @returns {Vector2} + */ + v2_ceil(v: Vector2): Vector2, + + /** + * Floor of all elements. + * @public + * @param {Vector2} v + * @returns {Vector2} + */ + v2_floor(v: Vector2): Vector2, + + /** + * Reciprocal of all elements. + * @public + * @param {Vector2} v + * @returns {Vector2} + */ + v2_inverse(v: Vector2): Vector2, + + /** + * Multiply all elements by a constant scale factor. + * @public + * @param {Vector2} v + * @param {number} s + * @returns {Vector2} + */ + v2_scale(v: Vector2, s: number): Vector2, + + /** + * Multiply individual elements of two vectors + * @public + * @param {Vector2} a + * @param {Vector2} b + * @returns {Vector2} + */ + v2_multiply(a: Vector2, b: Vector2), + + /** + * Divide individual elements of two vectors + * @public + * @param {Vector2} a + * @param {Vector2} b + * @returns {Vector2} + */ + v2_divide(a: Vector2, b: Vector2); + + /** + * Rotate clockwise. Angle in radians. + * @public + * @param {Vector2} v + * @param {number} a + * @returns {Vector2} + */ + v2_rotate(v: Vector2, a: number): Vector2, + + /** + * Add two vectors + * @public + * @param {Vector2} a + * @param {Vector2} b + * @returns {Vector2} + */ + v2_add(a: Vector2, b: Vector2): Vector2, + + /** + * Subtract two vectors + * @public + * @param {Vector2} a + * @param {Vector2} b + * @returns {Vector2} + */ + v2_sub(a: Vector2, b: Vector2): Vector2, + + /** + * Dot product of two vectors + * @public + * @param {Vector2} a + * @param {Vector2} b + * @returns {number} + */ + v2_dot(a: Vector2, b: Vector2): number, + + /** + * Minimum of two vectors, compared element by element. + * @public + * @param {Vector2} a + * @param {Vector2} b + * @returns {Vector2} + */ + v2_min(a: Vector2, b: Vector2): Vector2, + + /** + * Maximum of two vectors, compared element by element. + * @public + * @param {Vector2} a + * @param {Vector2} b + * @returns {Vector2} + */ + v2_max(a: Vector2, b: Vector2): Vector2, + + /** + * Angle in radian between two vectors. + * @public + * @param {Vector2} a + * @param {Vector2} b + * @returns {number} + */ + v2_angle(a: Vector2, b: Vector2): number, + + v2_signedAngle(a: Vector2, b: Vector2): number, + + /** + * Linear interpolation between two vectors + * @public + * @param {Vector2} a + * @param {Vector2} b + * @param {number} t - interpolation value between 0 and 1 + * @returns {Vector2} + */ + v2_lerp(a: Vector2, b: Vector2, t: number): Vector2, + + /** + * Checks for vector equality within an epsilon. + * @public + * @param {Vector2} a + * @param {Vector2} b + * @param {number} e - epsilon 0 by default + * @returns {boolean} + */ + v2_equals(a: Vector2, b: Vector2, e?: number): boolean, + + /** + * Checks if vector is [0, 0] + * @public + * @param {Vector2} v + * @returns {boolean} + */ + v2_isZero(v: Vector2): boolean, + + v2_distance(a: Vector2, b: Vector2): number, + v2_distanceSqr(a: Vector2, b: Vector2): number, + + /** + * Manhattan distance of vector + * @public + * @param {Vector2} v + * @returns {number} + */ + v2_manhattan(a: Vector2, b: Vector2): number, + + /** + * Multiplies vector by a 2x2 matrix + * @public + * @param {Vector2} v + * @param {Matrix2} m + * @returns {Vector2} + */ + v2_transform(v: Vector2, m: Matrix2): Vector2, + v2_perpendicular(v: Vector2) : Vector2, + v2_closest(v: Vector2, p: Vector2): Vector2, + + /** + * Null 3-vector [0, 0, 0] + * @public + * @returns {Vector3} + */ + v3_zero(): Vector3, + + /** + * Random point on a unit sphere. + * @public + * @returns {Vector3} + */ + v3_random(): Vector3, + + /** + * Magnitude of vector. + * @public + * @param {Vector3} v + * @returns {number} + */ + v3_magnitude(v: Vector3): number, + + /** + * Squared magnitude of vector. + * @public + * @param {Vector3} v + * @returns {number} + */ + v3_sqrMag(v: Vector3): number, + + /** + * Normalized vector. (Error on magnitude 0) + * @public + * @param {Vector3} v + * @returns {Vector3} + */ + v3_normalize(v: Vector3): Vector3, + + /** + * Reciprocal of all elements. + * @public + * @param {Vector3} v + * @returns {Vector3} + */ + v3_inverse(v: Vector3): Vector3, + + /** + * Absolute value of all elements. + * @public + * @param {Vector3} v + * @returns {Vector3} + */ + v3_abs(v: Vector3): Vector3, + + /** + * Ceiling of all elements. + * @public + * @param {Vector3} v + * @returns {Vector3} + */ + v3_ceil(v: Vector3): Vector3, + + /** + * Floor of all elements. + * @public + * @param {Vector3} v + * @returns {Vector3} + */ + v3_floor(v: Vector3): Vector3, + + /** + * Multiply all elements by a constant scale factor. + * @public + * @param {Vector3} v + * @param {number} s - scale + * @returns {Vector3} + */ + v3_scale(v: Vector3, s: number): number, + + /** + * Multiply individual elements of two vectors + * @public + * @param {Vector3} a + * @param {Vector3} b + * @returns {Vector3} + */ + v3_multiply(a: Vector3, b: Vector3): Vector3, + + /** + * Divide individual elements of two vectors + * @public + * @param {Vector3} a + * @param {Vector3} b + * @returns {Vector3} + */ + v3_divide(a: Vector3, b: Vector3): Vector3, + + /** + * Rotate around x axis. Angle in radians. Clockwise looking along axis + * @public + * @param {Vector3} v + * @param {number} a + * @returns {Vector3} + */ + v3_rotateX(v: Vector3, a: number): Vector3, + + /** + * Rotate around y axis. Angle in radians. Clockwise looking along axis + * @public + * @param {Vector3} v + * @param {number} a + * @returns {Vector3} + */ + v3_rotateY(v: Vectnlor3, a: number): Vector3, + + /** + * Rotate around z axis. Angle in radians. Clockwise looking along axis + * @public + * @param {Vector3} v + * @param {number} a + * @returns {Vector3} + */ + v3_rotateZ(v: Vector3, a: number): Vector3, + + /** + * Add two vectors + * @public + * @param {Vector3} a + * @param {Vector3} b + * @returns {Vector3} + */ + v3_add(a: Vector3, b: Vector3): Vector3, + + /** + * Subtract two vectors + * @public + * @param {Vector3} a + * @param {Vector3} b + * @returns {Vector3} + */ + v3_sub(a: Vector3, b: Vector3): Vector3, + + /** + * Dot product of two vectors + * @public + * @param {Vector3} a + * @param {Vector3} b + * @returns {number} + */ + v3_dot(a: Vector3, b: Vector3): number, + + /** + * Cross product of two vectors + * @public + * @param {Vector3} a + * @param {Vector3} b + * @returns {number} + */ + v3_cross(a: Vector3, b: Vector3): Vector3, + + /** + * Minimum of two vectors, compared element by element. + * @public + * @param {Vector3} a + * @param {Vector3} b + * @returns {number} + */ + v3_min(a: Vector3, b: Vector3): Vector3, + + /** + * Maximum of two vectors, compared element by element. + * @public + * @param {Vector3} a + * @param {Vector3} b + * @returns {Vector3} + */ + v3_max(a: Vector3, b: Vector3): Vector3, + + /** + * Manhattan distance of vector + * @public + * @param {Vector3} a + * @param {Vector3} b + * @returns {number} + */ + v3_manhattan(a: Vector3, b: Vector3): number, + + /** + * Angle in radian between two vectors. + * @public + * @param {Vector3} a + * @param {Vector3} b + * @returns {number} + */ + v3_angle(a: Vector3, b: Vector3): number, + + /** + * Linear interpolation between two vectors + * @public + * @param {Vector3} a + * @param {Vector3} b + * @param {number} t - value between 0 and 1 + * @returns {Vector3} + */ + v3_lerp(a: Vector3, b: Vector3, t: number): Vector3, + + /** + * Multiplies vector by a 4x4 matrix (Treats the vector as [x,y,z,1] in homogenous coordinates) + * @public + * @param {Vector3} a + * @param {Matrix4} m + * @returns {Vector3} + */ + v3_transform(a: Vector3, m: Matrix4): Vector3, + + /** + * Rotate by a quaternion + * @public + * @param {Vector3} v + * @param {Quaternion} q + * @returns {Vector3} + */ + v3_rotate(v: Vector3, q: Quaternion): Vector3, + + /** + * Checks for vector equality within an epsilon. + * @public + * @param {Vector3} a + * @param {Vector3} b + * @param {number=} e - epsilon defaults to zero + * @returns {boolean} + */ + v3_equals(a: Vector3, b: Vector3, e?: number): boolean, + + /** + * Checks if vector is [0, 0, 0] + * @public + * @param {Vector3} v + * @returns {boolean} + */ + v3_isZero(v: Vector3): boolean, + + v3_distance(a: Vector3, b: Vector3): number, + v3_distanceSqr(a: Vector3, b: Vector3): number, + + /** + * Returns a 2x2 zero Matrix + * @public + * @returns {Matrix2} 2x2 Matrix + */ + m2_zero(): Matrix2 + + /** + * Returns a 2x2 identity matrix + * @public + * @returns {Matrix2} 2x2 Matrix + */ + m2_identity(): Matrix2, + + /** + * Returns a 2x2 matrix that will rotate a 2-vector clockwise. Angle is in radians. + * @public + * @param {number} angle + * @returns {Matrix2} 2x2 Matrix + */ + m2_rotation(angle: number): Matrix2, + + /** + * Returns a 4x4 zero matrix + * @public + * @returns {Matrix4} 4x4 Matrix + */ + m4_zero(): Matrix4, + + /** + * Returns a 4x4 identity matrix + * @public + * @returns {Matrix4} 4x4 Matrix + */ + m4_identity(): Matrix4 + + /** + * Creates a 4x4 transform matrix from a 3-vector translation. + * @public + * @param {Vector3} v + * @returns {Matrix4} 4x4 Matrix + */ + m4_translation(v: Vector3): Matrix4, + + /** + * Extracts the translation from a 4x4 transform matrix. + * @public + * @param {Matrix4} m + * @returns {Vector3} extracted translation + */ + m4_getTranslation(m: Matrix4): Vector3, + + /** + * Creates a 4x4 transform matrix from a 3-vector scale, or a scale constant. + * @public + * @param {Vector3|number} s + * @returns {Matrix4} 4x4 Matrix + */ + m4_scale(s: Vector3|number): Matrix4, + + /** + * Extracts the scale from a 4x4 transform matrix. + * @public + * @param {Matrix4} m + * @returns {Vector3} extracted scale + */ + m4_getScale(m: Matrix4): Vector3, + + /** + * Creates a 4x4 rotation matrix around the given axis. Angle is in radians, and rotation is clockwise looking along axis. + * @public + * @param {Vector3} axis + * @param {number} angle + * @returns {Matrix4} 4x4 Matrix + */ + m4_rotation(axis: Vector3, angle: number): Matrix4, + + /** + * Creates a 4x4 rotation matrix around the x axis. Angle is in radians, and rotation is clockwise looking along axis. + * @public + * @param {number} angle + * @returns {Matrix4} 4x4 Matrix + */ + m4_rotationX(a: number): Matrix4, + + /** + * Creates a 4x4 rotation matrix around the y axis. Angle is in radians, and rotation is clockwise looking along axis. + * @public + * @param {number} angle + * @returns {Matrix4} 4x4 Matrix + */ + m4_rotationY(a: number): Matrix4, + + /** + * Creates a 4x4 rotation matrix around the z axis. Angle is in radians, and rotation is clockwise looking along axis. + * @public + * @param {number} angle + * @returns {Matrix4} 4x4 Matrix + */ + m4_rotationZ(a: number): Matrix4, + + /** + * Creates a 4x4 rotation matrix from a quaternion. + * @public + * @param {Quaternion} rotation + * @returns {Matrix4} 4x4 Matrix + */ + m4_rotationQ(q: Quaternion): Matrix4, + + /** + * Extracts the rotation quaternion from a 4x4 transform matrix. + * @public + * @param {Matrix4} matrix + * @returns {Quaternion} Quaternion + */ + m4_getRotation(m: Matrix4): Quaternion, + + /** + * Creates a 4x4 transform matrix from a scale, a rotation, and a translation. The scale can be either a 3-vector or a scalar. The rotation is a quaternion. + * @public + * @param {Vector3|number} scale + * @param {Quaternion} rotation + * @param {Vector3} translation + * @returns {Matrix4} 4x4 Matrix + */ + m4_scaleRotationTranslation(s: Vector3|number, q: Quaternion, v: Vector3) : Matrix4, + m4_getScaleRotationTranslation(m: Matrix4): [Vector3, Quaternion, Vector3], + + /** + * Creates a 4x4 perspective matrix from a field of view, an aspect ratio, and the near and far clip planes. The FOV is in radians. + * @public + * @param {number} fov + * @param {number} aspect + * @param {number} near + * @param {number} far + * @returns {Matrix4} 4x4 Matrix + */ + m4_perspective(fov: number, aspect: number, near: number, far: number): Matrix4, + + /** + * Returns the transpose of a 4x4 matrix + * @public + * @param {Matrix4} m + * @returns {Matrix4} 4x4 Matrix + */ + m4_transpose(m: Matrix4): Matrix4, + + /** + * Returns the determinant of a 4x4 matrix + * @public + * @param {Matrix4} matrix + * @returns {number} Determinant + */ + m4_determinant(m: Matrix4): number, + + /** + * Returns the inverse of a 4x4 matrix + * @public + * @param {Matrix4} matrix + * @returns {Matrix4} 4x4 Matrix + */ + m4_invert(m: Matrix4): Matrix4, + + /** + * Multiply two 4x4 matrices + * @public + * @param {Matrix4} a + * @param {Matrix4} b + * @returns {Matrix4} 4x4 Matrix + */ + m4_multiply(a: Matrix4, b: Matrix4): Matrix4, + + /** + * Extracts the scaling/rotation components of a 4x4 transform matrix and performs an inverse/transpose operation on them. + * This is the transform that should be applied to the surface normals of an object in a 3d rendered scene instead of the object's + * regular 4x4 transform. + * @public + * @param {Matrix4} m + * @returns {number[]} 4x4 Matrix + */ + m4_toNormal4(m: Matrix4): Matrix4, + + /** + * Identity quaternion + * @public + * @returns {Quaternion} + */ + q_identity(): Quaternion, + q_magnitude(q: Quaternion): number, + + /** + * Normalize quaternion. (If you do a long series of quaternion operations, periodically renormalize to prevent drift.) + * @public + * @param {Quaternion} q + * @returns {Quaternion} + */ + q_normalize(q: Quaternion): number, + + /** + * Reverse the rotation. + * @public + * @param {Quaternion} q + * @returns {Quaternion} + */ + q_conjugate(q: Quaternion): Quaternion, + + /** + * Reverse the rotation. + * @public + * @param {Quaternion} q + * @returns {Quaternion} + */ + q_invert(q: Quaternion): Quaternion, + + /** + * Creates a quaternion for a rotation around an axis. The angle is clockwise in radians looking along the axis. The axis should be normalized. + * @public + * @param {Vector3} axis + * @param {number} angle + * @returns {Quaternion} + */ + q_axisAngle(axis: Vector3, angle: number): Quaternion, + + q_toAxisAngle(quat: Quaternion): [Vector3, number], + + /** + * Given a forward vector, an up vector, and a target vector, generates a quaternion that will rotate the forward vector to look at the target vector. + * All vectors should be normalized. + * @public + * @param {Vector3} f - forward + * @param {Vector3} u - up + * @param {Vector3} t - target + * @returns {Quaternion} + */ + q_lookAt(f: Vector3, u: Vector3, t: Vector3): Quaternion, + + /** + * Creates a quaternion from the given Euler angles. All angles are in radians. + * @public + * @param {number} x + * @param {number} y + * @param {number} z + * @returns {Quaternion} + */ + q_euler(x: number, y: number, z: number): Quaternion, + + q_eulerXYZ(x: number, y: number, z: number): Quaternion, + + /** + * Extracts the Euler angle around the x axis from a quaternion. + * @public + * @param {Quaternion} + * @returns {number} + */ + q_pitch(q: Quaternion): number, + + /** + * Extracts the Euler angle around the y axis from a quaternion. + * @public + * @param {Quaternion} + * @returns {number} + */ + q_yaw(q: Quaternion): number, + + /** + * Extracts the Euler angle around the z axis from a quaternion. + * @public + * @param {Quaternion} + * @returns {number} + */ + q_roll(q: Quaternion): number, + + q_dot(q: Quaternion): number, + + /** + * Combines two rotations. QuaternionA is applied before quaternionB. + * @public + * @param {Quaternion} a + * @param {Quaternion} b + * @returns {Quaternion} + */ + q_multiply(a: Quaternion, b: Quaternion): Quaternion, + + /** + * Interpolates between two rotations. + * @public + * @param {Quaternion} a + * @param {Quaternion} b + * @param {number} t - value between 0 and 1 + * @returns {Quaternion} + */ + q_slerp(a: Quaternion, b: Quaternion, t: number): Quaternion, + + /** + * Checks for quaternion equality within an epsilon. + * @public + * @param {Quaternion} a + * @param {Quaternion} b + * @param {number=} e - epsilon that defaults to 0.0001 + * @returns {boolean} + */ + q_equals(a: Quaternion, b: Quaternion, e?: number): boolean, + + /** + * Checks if quaternion is [0, 0, 0, 1] + * @public + * @param {Quaternion} quaternion + * @returns {boolean} + */ + q_isZero(q: Quaternion): boolean, + + /** + * Returns the CardPawn for given Actor Id. To be used only from pawn side behaviors. + * @public + * @param {string} id - actor's id + * @returns {CardPawn} + */ + GetPawn(id: string): CardPawn, +}; + +export type PhysicsExports = { + PhysicsVersion(): string, + Physics: any +}; + +export type FrameExports = { + sendToShell(command: string, ...args: Array) +} + +export type THREE = typeof import("three"); +export type MicroverseModule = {THREE: THREE} & WorldcoreExports & PhysicsExports & FrameExports & {getViewRoot(): any}; + +export type BehaviorMethod = Array; +export type PlaneMaterial = THREE.MeshStandardMaterial|Array; +export type Rotation = Quaternion|Vector3; + +export type CardActor = ActorBehavior; +export type CardPawn = PawnBehavior; + +export type P3DEvent = { + targetId: string, avatarId: string, + xyz: Vector3, uv: Vector2, + normal: Vector3, distance: number, + ctrlKey: boolean, altKey: boolean, shiftKey: boolean, metaKey: boolean, + xy: Vector2, id: number, + button: number, buttons, number, instanceId: number, + ray: {origin: Vector3, direction: Vector3}, + deltaY: number +} + +declare global { + const Microverse: MicroverseModule +} + +export class ActorBehavior { + /** +The id of the CardActor. + + @public + @type string + */ + id: string + + /** +The id of the session. + + @public + @type string + */ + sessionId: string + + /** +The [x, y, z] translation of the card. + + @public + @type Vector3 + */ + translation: Vector3 + + /** +The rotation of the card in quaternion. + @public + @type Quaternion + */ + rotation: Quaternion + + /** +The scale of the card in three axes. + @public + @type Vector3 + */ + scale: Vector3 + + /** + The layers property specifies how the card is treated when a special action is taken. Typical value are as follows: + +- "walk": The avatar stays on the geometry of the card. +- "pointer": The pointer action is enabled. +- "portal": the avatar tests if the card it is going through needs to take the avatar to a connected world. + + @public + @type Array + + */ + layers: Array + + /** + The cards in the world are organized in a hierarchical parent-children structure. The `parent` specifies its parent. Note that this is a "logical" structure. All cards are held as a direct child of the Three.JS scene, with automatic matrix composition for nested cards. + + @public + @type CardActor + */ + parent: CardActor + + /** + The list of behavior modules installed to the card. + + @public + @type Array + + */ + behaviorModules: Array + + /** + An informative string for the card. + + @public + @type string + */ + name: string + + /** + The visibility of the card, and whether it responds to pointer events or not. + + @public + @type boolean + */ + + hidden: boolean|undefined + + /** + Any other values that the CardActor holds are stored in an object stored in the `_cardData` property. This is needed to mark the values to be stored in the persistent data. + + @public + @type Object + */ + _cardData: any + + /** + The behavior object. + */ + + _behavior: any + + /** + The unproxified base object of this behavior. + */ + + _target: CardActor + + /** + This method creates a new card (a CardActor on the model side and a CardPawn on the view side), based on the `cardSpec`. + + @public + @param {object} data - the spec for a card to be created. + @returns {CardActor} the CardActor created. + */ + createCard(data:any): CardActor + + /** + This method removes the card from the world. All `teardown()` method of installed pawn behaviors and actor behaviors are called before the CardActor is removed from the system. + + @public + */ + destroy(): void + + /** + This method invokes a method of another behavior. The `behaviorName` has to be in one of the form of: + +- "*ModuleName*$*BehaviorName*" +- "*BehaviorName*" + +When the first form is used, it specifies the globally known module name and the behavior with the name on the actor side of the module. When the second form is used, it specified the behavior in the same module as the calling behavior. + + * The `methodName` is the name of the method, and `values` are variable-length arguments for the method. + + @public + @param {string} behaviorName - name of the behavior + @param {string} methodName - name of the method + @param {any} ...arguments - arguments for the method + @returns {any} the return value from the method + */ + call(behaviorName: string, methodName: string, ...args:Array): any + + /** + This method schedules a future call in the specified logical time in milliseconds. If it is used in this form: + +`this.future(20).mth();` + +`mth` of the same behavior will be invoked 20 milliseconds from logical `now`. If you would like to call a method of another module or behavior, you can use `call()`: + +`this.future(20).call("Module$Behavior", "mth");` + + @public + @param {number} time - the delay in logical millisecond + @returns A proxy to invoke a method on + */ + future(time: number): ThisType + + /** + This method updates some elements in the `_cardData` object. The current value and the new values are merged to create the new `_cardData` object. As a side effect, it publishes `cardDataSet` Croquet event that can be handled by the pawn or any other subscribers. + + @public + @param {object} options - keys and values to specify new values + + */ + setCardData(options:any): void + + /** + This method updates the intrinsic properties of the object. + @public + @param {object} options - keys and values to specify new values + + */ + set(options:any): void + + /** +This method adds a "listener" to be invoked when an event occurs on the card. When `listener` is a function, it has to have a form of `this.mthName` where `mthName` is an existing method name of CardActor or the behavior itself. When listener is a string, it has to be the name of a method at CardActor or the behavior itself. The listener added by this Actor-side `addEventListener()` is invoked when any user in the world causes the corresponding user pointer or key event. + +Calling this method with the same arguments removes the previous listener before adding the new one. This semantics ensures that dynamically-modified method will be used. + + @public + @param {EventName} eventType - the event type + @param {string|function} listener - the name of the handler in the calling behavior, or a function specified in the form of `this.mth` + */ + addEventListener(eventName: string, listener: string|((evt: P3DEvent) => void)): void + + /** +This method removes the event listener that was added. You can call it when there is no matching event listener. + + @public + @param {EventType} eventName - the event type + @param {string|function} listener + */ + removeEventListener(eventName: string, listener: string|((evt: P3DEvent) => void)): void + + /** + This method adds a Croquet event subscription. Unlike the version in the Croquet Library, this version removes the subscription with the same `scope` and `eventName` if it exists before adding the new one. This semantics ensures that it is safe to call this from the `setup()` of a behavior. + + @public + @param {string} scope - the scope of Croquet event + @param {string} eventName - the event name of Croquet event + @param {string|function} listener - the name of the handler in the calling behavior, or a function specified in the form of `this.mth` + */ + subscribe(scope: string, eventName: string, listener: string|((data: T) => void)): void + + /** + This method removes a Croquet event subscription. + @public + @param {string} scope - the scope name of Croquet event + @param {string} eventName - the event name of Croquet event + @param {string|function} listener - the name of the handler in the calling behavior, or a function specified in the form of `this.mth` + */ + + unsubscribe(scope: string, eventName: string, listener?: string|((data: T) => void)): void + + /** + This method publishes a Croquet event. + + @public + @param {string} scope - the scope of Croquet event + @param {string} eventName - the event name of Croquet event + @param {any} data - serializable data to be published + */ + publish(scope: string, eventName: string, data?: T): void + + /** + This method adds a Croquet event subscription by calling the `subscribe()` method with `this.id` as the `scope`. + + @public + @param {string} eventName - the event name of Croquet event + @param {string|function} listener - the name of the handler in the calling behavior, or a function specified in the form of `this.mth` + */ + listen(eventName: string, listener: string|((arg: T) => void)): void + + /** + This method publishes a Croquet event with `this.id` as the `scope`. It is usually used to publish an event whose expect recipient is the corresponding CardPawn. + + @public + @param {string} eventName - the event name of Croquet event + @param {any} data - serializable data to be published + */ + say(eventName: string, data?: T): void + + /** + This method adds a new element to the `layers` array. If `newLayerName` is already in the `layers` array, the call does not have any effects. + + @public + @param {string} newLayerName - the name of a later to be added + */ + addLayer(newLayerName: string): void + + /** + This method removes an element from the `layers` array. If `layerName` is not in the `layers` array, the call does not have any effects. + + @public + @param {string} layerName - the name of a later to be removed + */ + removeLayer(layerName: string): void + + /** +This method moves the translation of the card to the specified `[x, y, z]` coordinates. + @public + @param {Vector3} v - the translation for the card + */ + translateTo(v: Vector3): void + + /** +When rot is a 4 element array, it is interpreted as a quaternion. +When rot is a 3 element array, it is interpreted as an Euler angle. +When rot is a number, it is interpreted as [0, rot, 0]. + +This method sets the rotation of the card to the specified by the argument. + @public + @param {Rotation|number} rot - the rotation for the card + */ + rotateTo(rot: Rotation|number): void + + /** +When s is a number, it is interpreted as `[s, s, s]`. +This method sets the scale of the card to the specified by scale factors in [x, y, z] axis. + + @public + @param {Vector3|number} s - the scale for the card + */ + scaleTo(s: Vector3|number): void + + /** +This method sets the translation and rotation of the card, making sure that those two values are used in the same logical time and used for the rendering. + + @public + @param {Vector3} v - the translation for the card + @param {Quaternion} q - the rotation for the card + */ + positionTo(v: Vector3, q: Quaternion): void + + + /** +This method moves the translation of the card by the specified `[x, y, z]` vector. + @public + @param {Vector3} v - the translation offset + */ + translateBy(v: Vector3): void + + /** +When rot is a 4 element array, it is interpreted as a quaternion. +When rot is a 3 element array, it is interpreted as an Euler angle. +When rot is a number, it is interpreted as [0, rot, 0]. + +This method combines the rotation of the card by the specified rotation. + @public + @param {Rotation|number} rot - the additional rotation for the card + */ + rotateBy(rot: Rotation|number): void + + /** +When s is a number, it is interpreted as [s, s, s]. +This method multiplies the scale of the card by the specified by scale factors in [x, y, z] axis. + + @public + @param {Vector3} s - the scale offset + */ + scaleBy(s: Vector3): void + + /** +When v is a number, it is interpreted as [0, 0, v]. + +This method translates the object by `the specified offset, in the reference frame of the object. + @public + @param {Vector3|number} v - the offset + */ + forwardBy(v: Vector3): void + + /** + The physics simulation world for this card. It looks up the value in the parent chain, starting from itself, or the "global" one if the world has a single global simulation world. + @public + @type any + */ + physicsWorld: any + + /** + set the physics simulation world to the card. + @public + @param {any} v - the physics world + */ + + setPhysicsWorld(v: any) + + /** +A Three.js keyframe based animation is supported. The animation clip can contain multiple tracks. The index specified here dictates which track to play. A cardData called animationStartTime specifiy the base for time offset. + +@public +@param {number} animationClipIndex - the index into animation tracks array + */ + + setAnimationClipIndex(animationClipIndex: number): void + + /** + This method is empty. It is used to have a way to get the tap to focus keyboard events but you don't need to take any particular action on tap. + + @public + */ + nop(): void + + /** + This method returns the Actor-side Worldcore service with the given name. + + @public + @param {string} name - the name of the Actor-side Service. + */ + service(name: string): any + + /** + This method returns the current Croquet logical time. + @public + @type number + */ + + now(): number +} + +export class PawnBehavior { + /** +The id of the CardPawn. + + @public + @type string + */ + id: string + + /** +The viewId of the session. + + @public + @type string + */ + viewId: string + + /** +The id of the session. + + @public + @type string + */ + sessionId: string + + /** +The corresponding actor of this pawn: + + @public + @type CardActor + */ + actor: CardActor + + /** + The cards in the world are organized in a hierarchical parent-children structure. The `parent` property specifies its parent. The pawn side implementation here returns a pawn if the card has a parent. + + @public + @type CardActor + */ + parent: CardPawn + + /** + the shape property is the root of the visual appearance of the card. It is a THREE.Object3D. + + @public + @type THREE.Object3D + */ + shape: THREE.Object3D + + /** +The [x, y, z] translation of the card. + + @public + @type Vector3 + */ + translation: Vector3 + + /** +The rotation of the card in quaternion. + @public + @type Quaternion + */ + rotation: Quaternion + + /** +The scale of the card in three axes. + @public + @type Vector3 + */ + scale: Vector3 + + /** + This method updates the intrinsic properties of the object. The values are sent to the actor. + @public + @param {object} options - keys and values to specify new values + + */ + set(options:any): void + + + /** + The behavior object. + */ + + _behavior: any + + /** + The unproxified base object of this behavior. + */ + + _target: CardPawn + + /** + The global transformation matrix for the object. + @public + @type Matrix4 + */ + + global: Matrix4 + + /** + The local transformation matrix for the object. + @public + @type Matrix4 + */ + + local: Matrix4 + + /** + This method invokes a method of another behavior. The `behaviorName` has to be in one of the form of: + +- "*ModuleName*$*BehaviorName*" +- "*BehaviorName*" + +When the first form is used, it specifies the globally known module name and the behavior with the name on the actor side of the module. When the second form is used, it specified the behavior in the same module as the calling behavior. + +The `methodName` is the name of the method, and `values` are variable-length arguments for the method. + + @public + @param {string} behaviorName - the name of the behavior that has the metho + @param {string} methodName - the name of the method + @param {any} values - arguments for the method + @returns any + */ + call(behaviorName: string, methodName: string, ...values: Array): any + + /** + This method invokes a method on the corresponding actor. It is expected that the method to be invoked does not alter the state of the actor, but only reads a property or synthesizes a value from properties. + + * The `behaviorName` has to be a name of an actor behavior in the same module. + + * `actorCall()` is used as you cannot invoke an intended method by a simple invocation syntax: + +`let foo = aPawn.actor.getFoo();` + +because the behavior that has `getFoo()` is not specified. If `getFoo()` is defined by an actor behavior with the name `FooActor`, you can call it by + +`let foo = aPawn.actorCall("FooActor", "getFoo");` + +Make sure that the actor's method called from the pawn does not modify the state of the model in any way. + + @public + @param {string} behaviorName - the name of the behavior that has the method + @param {string} methodName- the name of the method + @param {any} values - arguments for the method + */ + + actorCall(behaviorName: string, methodName: string, ...values: Array): any + + /** + This method schedules a future call in roughly the specified wall time in milliseconds. If it is used in this form: + +`this.future(20).mth();` + +mth` of the same behavior will be invoked. If you would like to call a method of another module or behavior, you can use `call()`: + + @example this.future(20).call("Module$Behavior", "mth"); + + @public + @returns a proxy to call a method on + @param {number} time - the wall clock time to delay the method invocatino. + */ + future(time: number): ThisType + + /** +This method adds a "listener" to be invoked when an event occurs on the pawn of a card. When `listener` is a string, it has to have the name of an existing method of CardPawn or the behavior itself. (Internally the function object is stored in the event listener data structure.) + +Calling this with the same arguments (thus the string form) removes the previous listener and then add the new one. This semantics ensures that dynamically-modified method will be used. + + @public + @param {EventName} eventName - the event name of Croquet event + @param {string|function} listener - the name of the handler in the calling behavior, or a function specified in the form of `this.mth` + */ + + addEventListener(eventName: string, listener: string|((evt: P3DEvent) => void)): void + + /** +This method removes the event listener that was added. You can call it even when there is no matching event listener. + + @public + @param {EventName} eventName - the event name of Croquet event + @param {string|function} listener - the name of the handler in the calling behavior, or a function specified in the form of `this.mth` + */ + + removeEventListener(eventName: string, listener: string|((evt: P3DEvent) => void)): void + + /** + This method adds a Croquet event subscription. Unlike the version in the Croquet Library, this version removes the subscription with the same `scope` and `eventName` if it exists before adding a new one; so that it is safe to call this from the `setup()` of a behavior. + + * The `listener` can be either a function or a string in the form of: + +- "*ModuleName*$*BehaviorName*.*methodName*" +- "*BehaviorName*.*methodName*" +- "*methodName*" + + @public + @param {string} scope - the scope name of Croquet event + @param {string} eventName - the event name of Croquet event + @param {string|function} listener - the name of the handler in the calling behavior, or a function specified in the form of `this.mth` + */ + + subscribe(scope: string, eventName: string, listener: string|((evt: T) => void)): void + + /** + This method removes a Croquet event subscription. + @public + @param {string} scope - the scope name of Croquet event + @param {string} eventName - the event name of Croquet event + @param {string|function} listener - the name of the handler in the calling behavior, or a function specified in the form of `this.mth` + */ + + unsubscribe(scope: string, eventName: string, listener?: string|((evt: T) => void)): void + + /** + This method publishes a Croquet event. + + @public + @param {string} scope - the scope of Croquet event + @param {string} eventName - the eventName of Croquet event + @param {anyf} data - serializable data to be published + */ + + publish(scope: string, eventName: string, data?: T): void + + /** + This method add a Croquet event subscription by calling the `subscribe()` method with `this.actor.id` as the `scope`. + + @public + @param {string} eventName - the eventName of Croquet event + @param {string|function} listener - the name of the handler in the calling behavior, or a function specified in the form of `this.mth` + */ + + listen(eventName: string, listener: string|((evt: T) => void)): void + + /** + This method publishes a Croquet event with `this.actor.id` as its `scope`. + + @public + @param {string} eventName - the eventName of Croquet event + @param {any} data - serializable data to be published + */ + + say(eventName: string, data?: T): void + + /** + This method returns the AvatarPawn of the local client. Recall that the notion of "my" avatar only exists on the view side. The model side treats all avatars equally, even the one that is associated with the local computer. This is why this method is on the pawn side, and returns the AvatarPawn. + + @public + @returns {AvatarPawn} The local AvatarPawn + */ + + getMyAvatar(): AvatarPawn + + /** + A pawn behavior may request a method callback when CardPawn's `update()` method is invoked. behaviorName and methodName will be "registered in the pawn, and for each `update()` call, the behavior method is invoked. + + *the argument is an array of the behavior name and the method to be called: `type BehaviorMethod = Array`. + + @public + @param {BehaviorMethod} array - a two element array with behavior name and method name + */ + + addUpdateRequest(array: BehaviorMethod): void + + /** + This method creates a flat card like Three.JS geometry in specified in `width`, `height`, `depth`, and `cornerRadius`. + + @public + @param {number} width - width of the geometry (in meters) + @param {number} height - height of the geometry (in meters) + @param {number} depth - depth of the geometry (in meters) + @param {number} cornerRadius - radius of the corners of the geometry (in meters) + @returns {Geometry} THREE.Geometry created + */ + + roundedCornerGeometry(width: number, height: number, depth: number, cornerRadius: number): THREE.BufferGeometry + + /** +`type PlaneMaterial = Material|Array` + +This method creates a Three.JS material that can be used with the geometry created by `roundedCornerGeometry()`. When the depth is non-zero, thus it is expected that the geometry from `roundedCornerGeometry()` has "sides", this method returns an array of materials with `color` and `frameColor`. Otherwise, it return a material with `color`. + + @public + @param {number} depth - depth of the geometry (in meters) + @param {number} color - the surface color for the material + @param {number} frameColor - the frame color for the material if depth is non-zero + @param {boolean} fullBright - if the material should ignore shaadows. + @returns {PlaneMaterial} + */ + + makePlaneMaterial(depth: number, color: number, frameColor: number, fullBright: boolean): PlaneMaterial + + /** +This method publishes an event to set the corresponding actor's translation. + + @public + @param {Vector3} v - the translation to be used by corresponding actor + */ + + translateTo(v: Vector3): void + + /** +This method publishes an event to set the corresponding actors's rotation. + + @public + @param {Quaternion} q - the rotation to be ued by corresponding actor + */ + + rotateTo(q: Quaternion): void + + /** +This method publishes an event to set the corresponding actors's rotation. + + @public + @param {Vector3} s the scale to be used by the corresponding actor + */ + + scaleTo(s: Vector3): void + + /** +This method publishes an event to set the corresponding actors's translation and rotation. It guarantees that two values are sent in one message, thus causes both to be updated at the same time. + + @public + @param {Vector3} v - the translation to be used by corresponding actor + @param {Quaternion} q - the rotation to be ued by corresponding actor + */ + + positionTo(v: Vector3, q: Quaternion): void + + /** + In order for the avatar to walk on a three-dimensional model, the 3D model needs to have the bounded volume hierarchy structure attached. This method has to be called to make a 3D object that is created in the pawn-side behavior. + + @public + @param {Object3D} obj + */ + + constructCollider(obj: THREE.Object3D): void + + /** + If the card has an associated collider object, it will be removed. If there is no collider object, this method does not take any effects. + + * A typical use case of `constructCollider()` and `cleanupColliderObject()` in a pawn-side behavior is as follows in its `setup()` method: + + @public + @example +this.cleanupColliderObject() +if (this.actor.layers && this.actor.layers.includes("walk")) { + this.constructCollider(this.floor); + // where this.floor is a Three.js Mesh with geometry. + } + */ + + cleanupColliderObject(): void + + /** + This method is empty. It is used to have a way to get the tap to focus keyboard events but you don't need to take any particular action on tap. + + @public + */ + + nop(): void + + /** + This method returns the Pawn-side Worldcore service with the given name. + + @public + @param {string} name - the name of the Pawn-side Service. + */ + service(name: string): any + + /** + This method returns the data of the specified asset as ArrayBuffer. The parameter is a string in the form of a full URL, relative path, or a Croquet dataId. + + @public + @param {string} name - the string that specifies the asset location. + */ + getBuffer(name: string): Promise + + /** + Add an additional method to invoke at each display frame, typically modify the visual appearance of the object. + */ + + addUpdateRequest(spec: Array): void + + /** + Remove an additional method to invoke at each display frame, typically modify the visual appearance of the object. + */ + + removeUpdateRequest(spec: Array): void + /** + recompute matrices + */ + + onLocalChanged() + + /** + This method returns the current Croquet logical time. + @public + @type number + */ + + now(): number +} + +export class AvatarActor extends ActorBehavior { + /** +The avatar's camera rotation around the X axis (the axis going from left to right; thus a positive value indicates to look "up", and a negative value indicates to look "down".) + +To get desired effects, use the set method: + +```JavaScript +this.set({lookPitch: n}); +``` + +Typically you would set lookPitch and lookYaw at the same time: + +```JavaScript +this.set({lookPitch: m, lookYaw: n}); +``` + @public + @type number + */ + get lookPitch(): number + /** +The avatar's camera rotation around the Y axis in the scene (the axis going from bottom to top; thus a positive value indicates to look east, and a negative value indicates to look west. + + @public + @type number + */ + get lookYaw(): number + + /** + The offset in 3D coordinates between avatar's position and the camera's position. A typical third person view behind the avatar has [0, p, p], where p is a positive number. + + While those three variables are used in the default `walkLook()` implementation, you can override the method to have a totally custom camera position. (see below.) + + @public + @type Vector3 + */ + + get lookOffset(): Vector3 + + /** +Equivalent to call: + +```JavaScript +this.goTo([0, 0, 0], [0, 0, 0, 1]) +``` + +and + +```JavaScript + this.set({lookPitch: 0, lookYaw: 0}); +``` + +as well as to notify the pawn by: + +```JavaScript + this.say("setLookAngles", {pitch: 0, yaw: 0, lookOffset: [0, 0, 0]}); +``` + @public + */ + + goHome() +} + +export class AvatarPawn extends PawnBehavior { + /** + isMyPlayerPawn flag indicates that this pawn is the local avatar. + @public + @type boolean + */ + + isMyPlayerPawn: boolean + + /** + fallDistance governs the amount of fall per frame when the avatar is not on a walkable floor and isFalling is set + @public + @type number + */ + + fallDistance: number + + /** + maxFall is the lower bound for the avatar to fall. + @public + @type number + */ + + maxFall: number + + get lookPitch(): number + + get lookYaw(): number + + get lookOffset(): Vector3 + + /** + Sets the coressponding actor's look configurations by publishing an event to the actor. + @public + @param {number} pitch + @param {number} yaw + @param {Vector3} lookOffset + */ + lookTo(pitch:number, yaw:number, lookOffset:Vector3) + + /** + This method sets the opacity of the 3D model by assigning a different opacity value into the Three.js material. + + @public + @param {number} opacity + */ + setOpacity(opacity:number) + + /** + This call initiates tells the actor to move back to [0, 0, 0], and resets rotation. + */ + + goHome() + + /** + This method add the pawn as the first responder so that the event of the specified type will be routed to the object first. + + @public + @param {EventName} eventName - the name of the input event + @param {EventMask} eventMask - whether the modifier keys should be checked + @param {CardPawn} pawn - the first responder for the event + */ + + addFirstResponder(eventName: EventName, eventMask: EventMask, pawn: CardPawn) + + /** + This method removes the pawn as the first responder so that the event of the specified type will no longer be routed to the object first. + + @public + @param {EventName} eventName - the name of the input event + @param {EventMask} eventMask - whether the modifier keys should be checked + @param {CardPawn} pawn - the first responder for the event + */ + + removeFirstResponder(eventName: EventName, eventMask: EventMask, pawn: CardPawn) + + /** + This method adds the pawn as the last responder so that the event of the specified type will be routed to the object when no other pawn handled it. + + @public + @param {EventName} eventName - the name of the input event + @param {EventMask} eventMask - whether the modifier keys should be checked + @param {CardPawn} pawn - the first responder for the event + */ + + addLastResponder(eventName: EventName, eventMask: EventMask, pawn: CardPawn) + + /** + This method removes the pawn as the last responder so that the event of the specified type will be routed to the object. + + @public + @param {EventName} eventName - the name of the input event + @param {EventMask} eventMask - whether the modifier keys should be checked + @param {CardPawn} pawn - the first responder for the event + */ + + removeLastResponder(eventName: EventName, eventMask: EventMask, pawn: CardPawn) + + /** + This method checks if given position (v) and rotation (q) collides with a portal in the world. + + @public + @param {VQ} vq - the pose of the avatar + returns {boolean} + */ + + collidePortal(vq: VQ): boolean + + /** + This method checks if given position (v) and rotation (q) collides with an object with the walk layer. + + @public + @param {Array} collideList - array of Meshes that have the walk layer. + @param {VQ} vq - the pose of the avatar + returns {boolean} + */ + + collideBVH(collideList: Array, vq: VQ): boolean + + /** + This method checks if there is a mesh with walk layer toward the negative y direction from the position (v). + @public + @param {VQ} vq - the pose of the avatar + returns {boolean} + */ + + checkFloor(vq: VQ): boolean +} diff --git a/behaviors/croquet/avatarEvents.js b/behaviors/croquet/avatarEvents.js index 0b8ee9c..8ee747f 100644 --- a/behaviors/croquet/avatarEvents.js +++ b/behaviors/croquet/avatarEvents.js @@ -1,4 +1,13 @@ -class AvatarPawn { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {PawnBehavior} from "../PrototypeBehavior"; + +class AvatarPawn extends PawnBehavior { setup() { if (!this.isMyPlayerPawn) {return;} @@ -20,8 +29,14 @@ class AvatarPawn { this.addEventListener("pointerWheel", this.pointerWheel); this.removeEventListener("pointerDoubleDown", "onPointerDoubleDown"); - this.addFirstResponder("pointerDoubleDown", {shiftKey: true}, this); - this.addEventListener("pointerDoubleDown", this.addSticky); + let doubleDownAction = "doubleDown"; + let eventMask = {shiftKey: true}; + if (Microverse.Constants.PointerDoubleDownAction) { + doubleDownAction = Microverse.Constants.PointerDoubleDownAction; + eventMask = {}; + } + this.addFirstResponder("pointerDoubleDown", eventMask, this); + this.addEventListener("pointerDoubleDown", doubleDownAction); this.addLastResponder("keyDown", {ctrlKey: true}, this); this.addEventListener("keyDown", this.keyDown); @@ -62,7 +77,7 @@ class AvatarPawn { } } -export class WalkerPawn { +class WalkerPawn extends PawnBehavior { walkTerrain(vq) { let walkLayer = this.service("ThreeRenderManager").threeLayer("walk"); if (!walkLayer) return vq; diff --git a/behaviors/croquet/avatarVoiceLevel.js b/behaviors/croquet/avatarVoiceLevel.js new file mode 100644 index 0000000..42575f9 --- /dev/null +++ b/behaviors/croquet/avatarVoiceLevel.js @@ -0,0 +1,43 @@ +// Copyright 2022 by Croquet Corporation, Inc. All Rights Reserved. +// https://croquet.io +// info@croquet.io + +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; + +class AvatarVoiceLevelActor extends ActorBehavior { + setup() { + this.subscribe(this.parent.id, "voiceLevelChanged", "voiceLevelChanged"); + } + + voiceLevelChanged(audioLevel) { + this.publish(this.id, "voiceLevelChanged", audioLevel); + } +} + +class AvatarVoiceLevelPawn extends PawnBehavior { + setup() { + this.subscribe(this.actor.id, "voiceLevelChanged", "voiceLevelChanged"); + } + + voiceLevelChanged(audioLevel) { + const s = 1 + audioLevel; + this.shape.children[0].scale.set(s, s, s); + } +} + +export default { + modules: [ + { + name: "AvatarVoiceLevel", + actorBehaviors: [AvatarVoiceLevelActor], + pawnBehaviors: [AvatarVoiceLevelPawn], + }, + ] +} diff --git a/behaviors/croquet/billboard.js b/behaviors/croquet/billboard.js index 7fe3670..caee8b9 100644 --- a/behaviors/croquet/billboard.js +++ b/behaviors/croquet/billboard.js @@ -12,7 +12,16 @@ reference vector to use. */ -class BillboardingPawn { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {PawnBehavior} from "../PrototypeBehavior"; + +class BillboardingPawn extends PawnBehavior { setup() { let moduleName = this._behavior.module.externalName; this.addUpdateRequest([`${moduleName}$BillboardingPawn`, "update"]); diff --git a/behaviors/croquet/dragAndDrop.js b/behaviors/croquet/dragAndDrop.js index 1872529..4e52f2a 100644 --- a/behaviors/croquet/dragAndDrop.js +++ b/behaviors/croquet/dragAndDrop.js @@ -1,4 +1,13 @@ -class FileDragAndDropActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior} from "../PrototypeBehavior"; + +class FileDragAndDropActor extends ActorBehavior { fileUploaded(data) { let {dataId, fileName, type, translation, rotation, animationClipIndex, dataScale} = data; diff --git a/behaviors/croquet/elected.js b/behaviors/croquet/elected.js index 0aad93f..59bad08 100644 --- a/behaviors/croquet/elected.js +++ b/behaviors/croquet/elected.js @@ -26,7 +26,16 @@ firstEligibleView prefers the currently elected view, it is safe to call again. */ -class ElectedActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; + +class ElectedActor extends ActorBehavior { setup() { this.subscribe("playerManager", "create", "updateElectedView"); this.subscribe("playerManager", "destroy", "updateElectedView"); @@ -79,7 +88,7 @@ to handle the event. */ -class ElectedPawn { +class ElectedPawn extends PawnBehavior { setup() { if (this.electedViewId === undefined) { this.electedViewId = ""; diff --git a/behaviors/croquet/fullBodyAvatar.js b/behaviors/croquet/fullBodyAvatar.js index 31b5867..09a6d78 100644 --- a/behaviors/croquet/fullBodyAvatar.js +++ b/behaviors/croquet/fullBodyAvatar.js @@ -1,4 +1,13 @@ -class AvatarPawn { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {PawnBehavior} from "../PrototypeBehavior"; + +class AvatarPawn extends PawnBehavior { setup() { this.speedManager = {snapshots: [], speed: 0, sign: 1, lastTime: Date.now()}; this.teardown(); diff --git a/behaviors/croquet/gizmo.js b/behaviors/croquet/gizmo.js index 0d2dce8..6ded970 100644 --- a/behaviors/croquet/gizmo.js +++ b/behaviors/croquet/gizmo.js @@ -1,4 +1,13 @@ -class GizmoActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; + +class GizmoActor extends ActorBehavior { setup() { this.target = this._cardData.target; let targetParent = this._cardData.targetParent; @@ -324,7 +333,7 @@ class GizmoActor { } } -class GizmoPawn { +class GizmoPawn extends PawnBehavior { setup() { this.lastTime = this.now(); this.isMine = this.actor.creatorId === this.viewId; @@ -377,7 +386,7 @@ class GizmoPawn { } } -class GizmoAxisActor { +class GizmoAxisActor extends ActorBehavior { setup() { this.isGizmoManipulator = true; this.subscribe(this.parent.id, "translateTarget", "translateTarget"); @@ -388,7 +397,7 @@ class GizmoAxisActor { } } -class GizmoAxisPawn { +class GizmoAxisPawn extends PawnBehavior { setup() { this.originalColor = this.actor._cardData.color; @@ -505,7 +514,7 @@ class GizmoAxisPawn { } } -class GizmoRotorActor { +class GizmoRotorActor extends ActorBehavior { setup() { this.isGizmoManipulator = true; this.subscribe(this.parent.id, "rotateTarget", "rotateTarget"); @@ -516,7 +525,7 @@ class GizmoRotorActor { } } -class GizmoRotorPawn { +class GizmoRotorPawn extends PawnBehavior { setup() { this.originalColor = this.actor._cardData.color; @@ -686,7 +695,7 @@ class GizmoRotorPawn { } } -class GizmoScalerActor { +class GizmoScalerActor extends ActorBehavior { setup() { this.isGizmoManipulator = true; this.subscribe(this.parent.id, "scaleTarget", "scaleTarget"); @@ -697,7 +706,7 @@ class GizmoScalerActor { } } -class GizmoScalerPawn { +class GizmoScalerPawn extends PawnBehavior { setup() { this.originalColor = this.actor._cardData.color; let isMine = this.parent?.actor.creatorId === this.viewId; @@ -859,13 +868,13 @@ class GizmoScalerPawn { } } -class GizmoPropertySheetButtonActor { +class GizmoPropertySheetButtonActor extends ActorBehavior { setup() { this.isGizmoManipulator = true; } } -class GizmoPropertySheetButtonPawn { +class GizmoPropertySheetButtonPawn extends PawnBehavior { setup() { let isMine = this.parent?.actor.creatorId === this.viewId; this.isMine = isMine; diff --git a/behaviors/croquet/halfBodyAvatar.js b/behaviors/croquet/halfBodyAvatar.js index 8a549bf..9041022 100644 --- a/behaviors/croquet/halfBodyAvatar.js +++ b/behaviors/croquet/halfBodyAvatar.js @@ -1,4 +1,13 @@ -class AvatarActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; + +class AvatarActor extends ActorBehavior { setup() { this._cardData.animationClipIndex = 9; this.say("animationStateChanged"); @@ -17,7 +26,7 @@ class AvatarActor { } } -class AvatarPawn { +class AvatarPawn extends PawnBehavior { setup() { this.subscribe(this.id, "3dModelLoaded", "modelLoaded"); this.listen("avatarPosed", "avatarPosed"); diff --git a/behaviors/croquet/menu.js b/behaviors/croquet/menu.js index 3542173..1277300 100644 --- a/behaviors/croquet/menu.js +++ b/behaviors/croquet/menu.js @@ -22,7 +22,17 @@ created. */ -class MenuActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; + + +class MenuActor extends ActorBehavior { setItems(list) { if (this.items) { @@ -156,7 +166,7 @@ class MenuActor { i.selected = !i.selected; this.selectionChanged(i); } else { - this.publish(this._parent.id, "fire", { + this.publish(this.parent.id, "fire", { action: item.label, id: this.id, viewId: data.viewId @@ -176,7 +186,7 @@ class MenuActor { this.selectionChanged(item); let selection = this.items.map((i) => ({label: i.label, selected: i.selected})); - this.publish(this._parent.id, "fire", {selection, id: this.id}); + this.publish(this.parent.id, "fire", {selection, id: this.id}); } } @@ -185,7 +195,7 @@ class MenuActor { } } -class MenuPawn { +class MenuPawn extends PawnBehavior { setup() { this.listen("cardDataSet", "cardDataUpdated"); this.initializeClipping(); @@ -236,13 +246,13 @@ behavior when the user tries to select an item. */ -class MenuItemActor { +class MenuItemActor extends ActorBehavior { setup() { } } -class MenuItemPawn { +class MenuItemPawn extends PawnBehavior { setup() { this.removeEventListener("pointerDoubleDown", "onPointerDoubleDown"); this.addEventListener("pointerDoubleDown", "nop"); @@ -274,3 +284,5 @@ export default { } ] } + +/* globals Microverse */ diff --git a/behaviors/croquet/pdfview.js b/behaviors/croquet/pdfview.js index 90ec49d..046fa96 100644 --- a/behaviors/croquet/pdfview.js +++ b/behaviors/croquet/pdfview.js @@ -1,4 +1,13 @@ -class PDFActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; + +class PDFActor extends ActorBehavior { setup() { // these will be initialised by the first client to load the doc and figure out // a suitable aspect ratio. pageGapPercent is needed for calculating overall @@ -176,7 +185,7 @@ class PDFActor { } } -class PDFPawn { +class PDFPawn extends PawnBehavior { setup() { if (!window.pdfjsPromise) { window.pdfjsPromise = new Promise(resolve => { @@ -403,7 +412,7 @@ class PDFPawn { uv.needsUpdate = true; if (!pageEntry.texture) pageEntry.texture = new Microverse.THREE.Texture(renderResult); - pageEntry.texture.colorSpace = THREE.SRGBColorSpace; + pageEntry.texture.colorSpace = Microverse.THREE.SRGBColorSpace; if (pageMesh.material.map !== pageEntry.texture) { pageMesh.material.map = pageEntry.texture; pageEntry.texture.needsUpdate = true; @@ -787,7 +796,7 @@ class PDFPawn { } } -class PDFButtonActor { +class PDFButtonActor extends ActorBehavior { // setup() { // } @@ -798,7 +807,7 @@ class PDFButtonActor { } } -class PDFButtonPawn { +class PDFButtonPawn extends PawnBehavior { setup() { this.subscribe(this.id, "2dModelLoaded", "svgLoaded"); diff --git a/behaviors/croquet/pedestal.js b/behaviors/croquet/pedestal.js index 41450b2..7185e39 100644 --- a/behaviors/croquet/pedestal.js +++ b/behaviors/croquet/pedestal.js @@ -1,4 +1,13 @@ -class GizmoActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; + +class GizmoActor extends ActorBehavior { setup() { this.target = this._cardData.target; this.creatorId = this._cardData.creatorId; @@ -223,11 +232,11 @@ class GizmoActor { } } -class GizmoPawn { +class GizmoPawn extends PawnBehavior { setup() { this.lastTime = this.now(); this.isMine = this.actor.creatorId === this.viewId; - + if (this.isMine && !this.interval) { this.interval = setInterval(() => this.checkInteraction(), 1000); } @@ -275,7 +284,7 @@ class GizmoPawn { } } -class GizmoPropertySheetButtonPawn { +class GizmoPropertySheetButtonPawn extends PawnBehavior { setup() { let isMine = this.parent?.actor.creatorId === this.viewId; this.isMine = isMine; @@ -330,7 +339,7 @@ class GizmoPropertySheetButtonPawn { } } -class PoseGizmoActor { +class PoseGizmoActor extends ActorBehavior { setup() { console.log("PoseGizmo", this.id); this.isGizmoManipulator = true; @@ -396,7 +405,7 @@ class PoseGizmoActor { } } -class PoseGizmoPawn { +class PoseGizmoPawn extends PawnBehavior { setup() { this.originalColor = this.actor._cardData.color; this.action = this.actor._cardData.action; diff --git a/behaviors/croquet/physics.js b/behaviors/croquet/physics.js index 2fbc4b1..0b41c72 100644 --- a/behaviors/croquet/physics.js +++ b/behaviors/croquet/physics.js @@ -10,7 +10,17 @@ example.) */ -class PhysicsActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior} from "../PrototypeBehavior"; + + +class PhysicsActor extends ActorBehavior { teardown() { this.removeImpulseJoint(); this.removeCollider(); diff --git a/behaviors/croquet/propertySheet.js b/behaviors/croquet/propertySheet.js index 29a6fdb..e3f3e92 100644 --- a/behaviors/croquet/propertySheet.js +++ b/behaviors/croquet/propertySheet.js @@ -20,7 +20,17 @@ contain a rotation are special cased so that if the value is an array of */ -class PropertySheetActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; + + +class PropertySheetActor extends ActorBehavior { setup() { if (this.windows) { this.windows.forEach((w) => w.destroy()); @@ -282,7 +292,7 @@ class PropertySheetActor { } } -class PropertySheetPawn { +class PropertySheetPawn extends PawnBehavior { setup() { if (this.frame) { this.shape.remove(this.frame); @@ -411,7 +421,7 @@ pointerMove. */ -class PropertySheetWindowActor { +class PropertySheetWindowActor extends ActorBehavior { setup() { if (this.dismiss) { this.dismiss.destroy(); @@ -439,7 +449,7 @@ class PropertySheetWindowActor { setObject() {console.log("set object");} } -class PropertySheetWindowPawn { +class PropertySheetWindowPawn extends PawnBehavior { setup() { if (this.frame) { this.shape.remove(this.frame); @@ -526,12 +536,12 @@ expected to subscribe to it to destroy itself. */ -class PropertySheetDismissActor { +class PropertySheetDismissActor extends ActorBehavior { setup() { } } -class PropertySheetDismissPawn { +class PropertySheetDismissPawn extends PawnBehavior { setup() { this.addEventListener("pointerTap", "tap"); @@ -574,7 +584,7 @@ class PropertySheetDismissPawn { } } -class PropertySheetEditActor { +class PropertySheetEditActor extends ActorBehavior { setup() { this.listen("launchCodeEditor", "launchCodeEditor"); } @@ -600,7 +610,7 @@ class PropertySheetEditActor { } } -class PropertySheetEditPawn { +class PropertySheetEditPawn extends PawnBehavior { setup() { this.addEventListener("pointerTap", "tap"); } @@ -639,12 +649,12 @@ class PropertySheetEditPawn { } } -class PropertySheetWindowBarActor { +class PropertySheetWindowBarActor extends ActorBehavior { setup() { } } -class PropertySheetWindowBarPawn { +class PropertySheetWindowBarPawn extends PawnBehavior { setup() { this.addEventListener("pointerDown", "pointerDown"); this.addEventListener("pointerMove", "pointerMove"); @@ -681,7 +691,7 @@ class PropertySheetWindowBarPawn { } } -class BehaviorMenuActor { +class BehaviorMenuActor extends ActorBehavior { show() { if (this.menu) { this.menu.destroy(); @@ -755,7 +765,7 @@ class BehaviorMenuActor { } } -class ActionMenuActor { +class ActionMenuActor extends ActorBehavior { show() { if (this.menu) { this.menu.destroy(); diff --git a/behaviors/croquet/rapier.js b/behaviors/croquet/rapier.js index 68b4dbd..1dff929 100644 --- a/behaviors/croquet/rapier.js +++ b/behaviors/croquet/rapier.js @@ -10,7 +10,17 @@ example.) */ -class RapierActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior} from "../PrototypeBehavior"; + + +class RapierActor extends ActorBehavior { setup() { this._oldRapier07 = true; } diff --git a/behaviors/croquet/scrollableArea.js b/behaviors/croquet/scrollableArea.js index cbd2660..2d035db 100644 --- a/behaviors/croquet/scrollableArea.js +++ b/behaviors/croquet/scrollableArea.js @@ -1,4 +1,13 @@ -class ScrollAreaActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; + +class ScrollAreaActor extends ActorBehavior { setup() { this.noSave = true; console.log("setup.scrollTop", this.scrollTop); @@ -56,7 +65,7 @@ class ScrollAreaActor { } } -class ScrollAreaPawn { +class ScrollAreaPawn extends PawnBehavior { setup() { this.listen("targetSet", "targetSet"); this.listen("updateDisplay", "updateDisplay"); @@ -154,10 +163,10 @@ class ScrollAreaPawn { } } -class ScrollBarActor { +class ScrollBarActor extends ActorBehavior { setup() {} } -class ScrollBarPawn { +class ScrollBarPawn extends PawnBehavior { setup() { this.addEventListener("pointerDown", "pointerDown"); this.addEventListener("pointerUp", "pointerUp"); diff --git a/behaviors/croquet/singleUser.js b/behaviors/croquet/singleUser.js index 6979dea..adc1b1c 100644 --- a/behaviors/croquet/singleUser.js +++ b/behaviors/croquet/singleUser.js @@ -2,7 +2,17 @@ // https://croquet.io // info@croquet.io -class SingleUserInteractionActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior} from "../PrototypeBehavior"; + + +class SingleUserInteractionActor extends ActorBehavior { setup() { if (this.occupier === undefined) this.occupier = null; if (this.lastOccupierAction === undefined) this.lastOccupierAction = -1; // this.now(); diff --git a/behaviors/croquet/stickyNote.js b/behaviors/croquet/stickyNote.js index 43624a1..551eed8 100644 --- a/behaviors/croquet/stickyNote.js +++ b/behaviors/croquet/stickyNote.js @@ -15,7 +15,17 @@ contain a rotation are special cased so that if the value is an array of */ -class StickyNoteActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior} from "../PrototypeBehavior"; + + +class StickyNoteActor extends ActorBehavior { setup() { this.subscribe(this.id, "text", "cardSpecAccept"); } diff --git a/behaviors/croquet/video.js b/behaviors/croquet/video.js index 287f990..de834e5 100644 --- a/behaviors/croquet/video.js +++ b/behaviors/croquet/video.js @@ -12,7 +12,16 @@ There is a case that the session comes back from dormant. so care is taken that the video element recreated won't start playing. */ -class VideoActor { +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; + +class VideoActor extends ActorBehavior { setup() { this.listen("setSize", "setSize"); this.listen("ended", "ended"); @@ -152,7 +161,7 @@ class VideoActor { } } -class VideoPawn { +class VideoPawn extends PawnBehavior { setup() { this.addEventListener("pointerTap", "tapped"); this.listen("cardDataSet", "videoChanged"); @@ -466,7 +475,7 @@ class VideoPawn { } -class VideoButtonActor { +class VideoButtonActor extends ActorBehavior { // setup() { // } @@ -480,10 +489,10 @@ class VideoButtonActor { } } -class VideoButtonPawn { +class VideoButtonPawn extends PawnBehavior { setup() { if (this.actor._cardData.isPrototype) {return;} - + this.subscribe(this.id, "2dModelLoaded", "svgLoaded"); this.addEventListener("pointerMove", "nop"); diff --git a/behaviors/default/bitcoinTracker.js b/behaviors/default/bitcoinTracker.ts similarity index 80% rename from behaviors/default/bitcoinTracker.js rename to behaviors/default/bitcoinTracker.ts index d098055..1fed8a4 100644 --- a/behaviors/default/bitcoinTracker.js +++ b/behaviors/default/bitcoinTracker.ts @@ -2,27 +2,34 @@ // https://croquet.io // info@croquet.io -/* +// the following import statement is solely for the type checking and +// autocompletion features in IDE. A Behavior cannot inherit from +// another behavior or a base class but can use the methods and +// properties of the card to which it is installed. +// The prototype classes ActorBehavior and PawnBehavior provide +// the features defined at the card object. + +import {ActorBehavior, PawnBehavior} from "../PrototypeBehavior"; +/* This module manages a list of recent values from a bitcoin position server. It is used with the Elected module, so that one of participants is chosen to fetch values. -*/ - -/* - BitcoinTrackerActor's history is a list of {date, and amount} - */ -class BitcoinTrackerActor { +type History = {date: number, amount: number}; +type BarMesh = THREE.Mesh; + +class BitcoinTrackerActor extends ActorBehavior { + history: Array; setup() { if (!this.history) { this.history = [{ date: 0, amount: 0 }]; } - this.listen("BTC-USD", "onBitcoinData"); - this.listen("BTC-USD-history", "onBitcoinHistory"); + this.listen("BTC-USD", this.onBitcoinData); + this.listen>("BTC-USD-history", this.onBitcoinHistory); } latest() { @@ -34,26 +41,32 @@ class BitcoinTrackerActor { // the last data point, and publishes value-change event. if (date - this.latest().date < 1000) return; this.addEntries({date, amount}); - this.say("value-changed", amount); + this.say("value-changed", amount); } - onBitcoinHistory(prices) { + onBitcoinHistory(prices: Array) { const newer = prices.filter(p => p.date - this.latest().date > 25000); this.addEntries(...newer); - this.publish(this.id, "value-init", newer.map(v=>v.amount)); + this.publish>(this.id, "value-init", newer.map(v=>v.amount)); } - addEntries(...data) { + addEntries(...data: Array) { + if (data.length === 0) {return;} this.history.push(...data); if (this.history[0].date === 0) {this.history.shift();} if (this.history.length > 300) {this.history.shift();} } } -class BitcoinTrackerPawn { +class BitcoinTrackerPawn extends PawnBehavior { + lastAmount: number; + socket: WebSocket; + canvas: HTMLCanvasElement; + texture: THREE.CanvasTexture; + setup() { this.lastAmount = 0; - this.listen("value-changed", "onBTCUSDChanged"); + this.listen("value-changed", "onBTCUSDChanged"); this.onBTCUSDChanged(); @@ -157,6 +170,8 @@ class BitcoinTrackerPawn { this.clear("#050505"); let ctx = this.canvas.getContext("2d"); + if (!ctx) return; + if (!this.texture) return; ctx.textAlign = "right"; ctx.fillStyle = color; @@ -172,6 +187,7 @@ class BitcoinTrackerPawn { clear(fill) { let ctx = this.canvas.getContext("2d"); + if (!ctx) return; ctx.fillStyle = fill; ctx.fillRect( 0, 0, this.canvas.width, this.canvas.height ); } @@ -181,7 +197,8 @@ class BitcoinTrackerPawn { } } -class BitLogoPawn { +class BitLogoPawn extends PawnBehavior { + lastColor: string setup() { // this is a case where a method of the base object is called. this.subscribe(this.parent.id, "setColor", "setColor"); @@ -191,23 +208,23 @@ class BitLogoPawn { setColor(color) { if (color === this.lastColor) {return;} let material = this.makePlaneMaterial(this.actor._cardData.depth, color, this.actor._cardData.frameColor, false); - let obj = this.shape.children.find((o) => o.name === "2d"); + let obj = this.shape.children.find((o) => o.name === "2d") as BarMesh; if (!obj || !obj.children || obj.children.length === 0) {return;} - obj = obj.children[0]; - obj.material = material; + obj = obj.children[0] as BarMesh; + obj.material = (material as THREE.MeshStandardMaterial); this.lastColor = color; } } -class BarGraphActor { +class BarGraphActor extends ActorBehavior { setup() { if (this._cardData.values === undefined) { this._cardData.values = []; this._cardData.length = 20; this._cardData.height = 0.5; } - this.subscribe(this.parent.id, "value-changed", this.updateBars); - this.subscribe(this.parent.id, "value-init", this.initBars); + this.subscribe(this.parent.id, "value-changed", "updateBars"); + this.subscribe>(this.parent.id, "value-init", "initBars"); } length() { @@ -222,7 +239,7 @@ class BarGraphActor { return this._cardData.values; } - updateBars(value, notSay) { + updateBars(value: number, notSay: boolean) { let values = this._cardData.values; values.push(value); if (values.length > this.length()) { @@ -234,13 +251,16 @@ class BarGraphActor { } } - initBars(values) { + initBars(values: Array) { values.forEach((value) => this.updateBars(value, true)); this.say("updateGraph"); } } -class BarGraphPawn { +class BarGraphPawn extends PawnBehavior { + bars: Array; + bar: BarMesh; + base: BarMesh; setup() { this.constructBars(); this.listen("updateGraph", "updateGraph"); @@ -251,7 +271,7 @@ class BarGraphPawn { constructBars() { [...this.shape.children].forEach((c) => { - c.material.dispose(); + ((c as BarMesh).material as {dispose}).dispose(); this.shape.remove(c); }); this.bars = []; @@ -269,7 +289,7 @@ class BarGraphPawn { new THREE.MeshStandardMaterial({color: color, emissive: color})); for(let i = 0; i < len; i++) { let bar = this.bar.clone(); - bar.material = bar.material.clone(); + bar.material = (bar.material as THREE.MeshStandardMaterial).clone(); bar.position.set((0.5 + i - len / 2) * size, 0,0); this.shape.add(bar); this.bars.push(bar); @@ -282,7 +302,7 @@ class BarGraphPawn { this.base.material.emissive = c; } - updateGraph(){ + updateGraph() { let values = this.actor._cardData.values; let height = this.actor._cardData.height; let mn = Math.min(...values); diff --git a/index.html b/index.html index 400530b..c90cd16 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ Microverse - + diff --git a/lib/index-8d2ac4f0.js b/lib/index-aef48027.js similarity index 92% rename from lib/index-8d2ac4f0.js rename to lib/index-aef48027.js index eca014b..f3d6b9c 100644 --- a/lib/index-8d2ac4f0.js +++ b/lib/index-aef48027.js @@ -11,11 +11,11 @@ /** * Copyright Croquet Corporation 2023 * Bundle of @croquet/croquet - * Date: 2023-08-01 - * Version: 1.1.0-34 + * Date: 2023-08-24 + * Version: 1.1.0-38 */ -if(Object.defineProperty(exports,"__esModule",{value:!0}),void 0===globalThis.TextEncoder){globalThis.TextEncoder=function(){},TextEncoder.prototype.encode=function(t){for(var e=t.length,s=-1,i="undefined"==typeof Uint8Array?new Array(1.5*e):new Uint8Array(3*e),n=0,o=0,r=0;r!==e;){if(n=t.charCodeAt(r),r+=1,n>=55296&&n<=56319){if(r===e){i[s+=1]=239,i[s+=1]=191,i[s+=1]=189;break}if(!((o=t.charCodeAt(r))>=56320&&o<=57343)){i[s+=1]=239,i[s+=1]=191,i[s+=1]=189;continue}if(r+=1,(n=1024*(n-55296)+o-56320+65536)>65535){i[s+=1]=240|n>>>18,i[s+=1]=128|n>>>12&63,i[s+=1]=128|n>>>6&63,i[s+=1]=128|63&n;continue}}n<=127?i[s+=1]=0|n:n<=2047?(i[s+=1]=192|n>>>6,i[s+=1]=128|63&n):(i[s+=1]=224|n>>>12,i[s+=1]=128|n>>>6&63,i[s+=1]=128|63&n)}return"undefined"!=typeof Uint8Array?i.subarray(0,s+1):(i.length=s+1,i)},TextEncoder.prototype.toString=function(){return"[object TextEncoder]"};try{Object.defineProperty(TextEncoder.prototype,"encoding",{get:function(){if(TextEncoder.prototype.isPrototypeOf(this))return"utf-8";throw TypeError("Illegal invocation")}})}catch(t){TextEncoder.prototype.encoding="utf-8"}"undefined"!=typeof Symbol&&(TextEncoder.prototype[Symbol.toStringTag]="TextEncoder")}var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof __webpack_require__.g?__webpack_require__.g:"undefined"!=typeof self?self:{};!function(t){var e=function(t){var e,s=Object.prototype,i=s.hasOwnProperty,n="function"==typeof Symbol?Symbol:{},o=n.iterator||"@@iterator",r=n.asyncIterator||"@@asyncIterator",a=n.toStringTag||"@@toStringTag";function l(t,e,s){return Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{l({},"")}catch(t){l=function(t,e,s){return t[e]=s}}function c(t,e,s,i){var n=e&&e.prototype instanceof b?e:b,o=Object.create(n.prototype),r=new W(i||[]);return o._invoke=function(t,e,s){var i=h;return function(n,o){if(i===m)throw new Error("Generator is already running");if(i===p){if("throw"===n)throw o;return C()}for(s.method=n,s.arg=o;;){var r=s.delegate;if(r){var a=G(r,s);if(a){if(a===f)continue;return a}}if("next"===s.method)s.sent=s._sent=s.arg;else if("throw"===s.method){if(i===h)throw i=p,s.arg;s.dispatchException(s.arg)}else"return"===s.method&&s.abrupt("return",s.arg);i=m;var l=d(t,e,s);if("normal"===l.type){if(i=s.done?p:u,l.arg===f)continue;return{value:l.arg,done:s.done}}"throw"===l.type&&(i=p,s.method="throw",s.arg=l.arg)}}}(t,s,r),o}function d(t,e,s){try{return{type:"normal",arg:t.call(e,s)}}catch(t){return{type:"throw",arg:t}}}t.wrap=c;var h="suspendedStart",u="suspendedYield",m="executing",p="completed",f={};function b(){}function y(){}function g(){}var w={};l(w,o,(function(){return this}));var Z=Object.getPrototypeOf,X=Z&&Z(Z(T([])));X&&X!==s&&i.call(X,o)&&(w=X);var v=g.prototype=b.prototype=Object.create(w);function L(t){["next","throw","return"].forEach((function(e){l(t,e,(function(t){return this._invoke(e,t)}))}))}function x(t,e){function s(n,o,r,a){var l=d(t[n],t,o);if("throw"!==l.type){var c=l.arg,h=c.value;return h&&"object"==typeof h&&i.call(h,"__await")?e.resolve(h.__await).then((function(t){s("next",t,r,a)}),(function(t){s("throw",t,r,a)})):e.resolve(h).then((function(t){c.value=t,r(c)}),(function(t){return s("throw",t,r,a)}))}a(l.arg)}var n;this._invoke=function(t,i){function o(){return new e((function(e,n){s(t,i,e,n)}))}return n=n?n.then(o,o):o()}}function G(t,s){var i=t.iterator[s.method];if(i===e){if(s.delegate=null,"throw"===s.method){if(t.iterator.return&&(s.method="return",s.arg=e,G(t,s),"throw"===s.method))return f;s.method="throw",s.arg=new TypeError("The iterator does not provide a 'throw' method")}return f}var n=d(i,t.iterator,s.arg);if("throw"===n.type)return s.method="throw",s.arg=n.arg,s.delegate=null,f;var o=n.arg;return o?o.done?(s[t.resultName]=o.value,s.next=t.nextLoc,"return"!==s.method&&(s.method="next",s.arg=e),s.delegate=null,f):o:(s.method="throw",s.arg=new TypeError("iterator result is not an object"),s.delegate=null,f)}function S(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function k(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function W(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(S,this),this.reset(!0)}function T(t){if(t){var s=t[o];if(s)return s.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,r=function s(){for(;++n=0;--o){var r=this.tryEntries[o],a=r.completion;if("root"===r.tryLoc)return n("end");if(r.tryLoc<=this.prev){var l=i.call(r,"catchLoc"),c=i.call(r,"finallyLoc");if(l&&c){if(this.prev=0;--s){var n=this.tryEntries[s];if(n.tryLoc<=this.prev&&i.call(n,"finallyLoc")&&this.prev=0;--e){var s=this.tryEntries[e];if(s.finallyLoc===t)return this.complete(s.completion,s.afterLoc),k(s),f}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var s=this.tryEntries[e];if(s.tryLoc===t){var i=s.completion;if("throw"===i.type){var n=i.arg;k(s)}return n}}throw new Error("illegal catch attempt")},delegateYield:function(t,s,i){return this.delegate={iterator:T(t),resultName:s,nextLoc:i},"next"===this.method&&(this.arg=e),f}},t}(t.exports);try{globalThis.regeneratorRuntime=e}catch(t){"object"==typeof globalThis?globalThis.regeneratorRuntime=e:Function("r","regeneratorRuntime = r")(e)}}({exports:{}});const e={CROQUET_VERSION:"1.1.0-34"},s=window.location.hostname.endsWith("croquet.studio");let i="",n="";function o(t,e){if(e)for(const s of e.split("&")){const e=s.split("="),i=e[0];let n=!0;if(e.length>1&&(n=decodeURIComponent(e.slice(1).join("=")),n.match(/^(true|false|null|[0-9.]*|["[{].*)$/)))try{n=JSON.parse(n)}catch(t){"["===n[0]&&(n=n.slice(1,-1).split(","))}t[i]=n}}const r=new class{constructor(){this.getSession(),o(this,window.location.search.slice(1)),o(this,s?window.location.hash.slice(1):n),window.location.pathname.indexOf("/ar.html")>=0&&(this.ar=!0)}has(t,e,s){"boolean"!=typeof s&&(s=this.isHost(s));const i=this[t];if("string"!=typeof i)return s;const n=i.split(",");return!0===s&&(e=`no${e}`),e.endsWith("s")&&(e=e.slice(0,-1)),n.includes(e)||n.includes(`${e}s`)?!s:s}getSession(){if(s){const t=/^\/([^/]+)\/(.*)$/,e=window.location.pathname.match(t);if(e)return i=e[1],e[2]}else{const t=/^#([^&]+)&?(.*)$/,e=window.location.hash.match(t);if(e)return e[1].includes("=")?(n=`${e[1]}&${e[2]}`,""):(n=e[2],e[1])}return"string"==typeof this.session?(n=window.location.hash.slice(1),this.session):""}setSession(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];null==s&&this.getSession();const{search:o,hash:r}=window.location,a=s?`/${i}/${t}${o}${r}`:`#${t}${n?"&"+n:""}`;e?window.history.replaceState({},"",a):window.history.pushState({},"",a)}isHost(t){const e=window.location.hostname;if(e===t)return!0;if("localhost"!==t)return!1;if(e.endsWith(".ngrok.io"))return!0;if(e.endsWith("croquet.dev"))return!0;if("croquet.io"===e){if(window.location.pathname.match(/^\/(dev|files)\//))return!0}return"file:"===window.location.protocol||["127.0.0.1","[::1]"].includes(e)}isLocalhost(){return this.isHost("localhost")}};var a,l,c,d={exports:{}};l=t,c=function(t){var e=function(t){return new e.lib.init(t)};function s(t,e){return e.offset[t]?isNaN(e.offset[t])?e.offset[t]:e.offset[t]+"px":"0px"}function i(t,e){return!(!t||"string"!=typeof e||!(t.className&&t.className.trim().split(/\s+/gi).indexOf(e)>-1))}return e.defaults={oldestFirst:!0,text:"Toastify is awesome!",node:void 0,duration:3e3,selector:void 0,callback:function(){},destination:void 0,newWindow:!1,close:!1,gravity:"toastify-top",positionLeft:!1,position:"",backgroundColor:"",avatar:"",className:"",stopOnFocus:!0,onClick:function(){},offset:{x:0,y:0},escapeMarkup:!0,style:{background:""}},e.lib=e.prototype={toastify:"1.11.2",constructor:e,init:function(t){return t||(t={}),this.options={},this.toastElement=null,this.options.text=t.text||e.defaults.text,this.options.node=t.node||e.defaults.node,this.options.duration=0===t.duration?0:t.duration||e.defaults.duration,this.options.selector=t.selector||e.defaults.selector,this.options.callback=t.callback||e.defaults.callback,this.options.destination=t.destination||e.defaults.destination,this.options.newWindow=t.newWindow||e.defaults.newWindow,this.options.close=t.close||e.defaults.close,this.options.gravity="bottom"===t.gravity?"toastify-bottom":e.defaults.gravity,this.options.positionLeft=t.positionLeft||e.defaults.positionLeft,this.options.position=t.position||e.defaults.position,this.options.backgroundColor=t.backgroundColor||e.defaults.backgroundColor,this.options.avatar=t.avatar||e.defaults.avatar,this.options.className=t.className||e.defaults.className,this.options.stopOnFocus=void 0===t.stopOnFocus?e.defaults.stopOnFocus:t.stopOnFocus,this.options.onClick=t.onClick||e.defaults.onClick,this.options.offset=t.offset||e.defaults.offset,this.options.escapeMarkup=void 0!==t.escapeMarkup?t.escapeMarkup:e.defaults.escapeMarkup,this.options.style=t.style||e.defaults.style,t.backgroundColor&&(this.options.style.background=t.backgroundColor),this},buildToast:function(){if(!this.options)throw"Toastify is not initialized";var t=document.createElement("div");for(var e in t.className="toastify on "+this.options.className,this.options.position?t.className+=" toastify-"+this.options.position:!0===this.options.positionLeft?(t.className+=" toastify-left",console.warn("Property `positionLeft` will be depreciated in further versions. Please use `position` instead.")):t.className+=" toastify-right",t.className+=" "+this.options.gravity,this.options.backgroundColor&&console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.'),this.options.style)t.style[e]=this.options.style[e];if(this.options.node&&this.options.node.nodeType===Node.ELEMENT_NODE)t.appendChild(this.options.node);else if(this.options.escapeMarkup?t.innerText=this.options.text:t.innerHTML=this.options.text,""!==this.options.avatar){var i=document.createElement("img");i.src=this.options.avatar,i.className="toastify-avatar","left"==this.options.position||!0===this.options.positionLeft?t.appendChild(i):t.insertAdjacentElement("afterbegin",i)}if(!0===this.options.close){var n=document.createElement("span");n.innerHTML="✖",n.className="toast-close",n.addEventListener("click",function(t){t.stopPropagation(),this.removeElement(this.toastElement),window.clearTimeout(this.toastElement.timeOutValue)}.bind(this));var o=window.innerWidth>0?window.innerWidth:screen.width;("left"==this.options.position||!0===this.options.positionLeft)&&o>360?t.insertAdjacentElement("afterbegin",n):t.appendChild(n)}if(this.options.stopOnFocus&&this.options.duration>0){var r=this;t.addEventListener("mouseover",(function(e){window.clearTimeout(t.timeOutValue)})),t.addEventListener("mouseleave",(function(){t.timeOutValue=window.setTimeout((function(){r.removeElement(t)}),r.options.duration)}))}if(void 0!==this.options.destination&&t.addEventListener("click",function(t){t.stopPropagation(),!0===this.options.newWindow?window.open(this.options.destination,"_blank"):window.location=this.options.destination}.bind(this)),"function"==typeof this.options.onClick&&void 0===this.options.destination&&t.addEventListener("click",function(t){t.stopPropagation(),this.options.onClick()}.bind(this)),"object"==typeof this.options.offset){var a=s("x",this.options),l=s("y",this.options),c="left"==this.options.position?a:"-"+a,d="toastify-top"==this.options.gravity?l:"-"+l;t.style.transform="translate("+c+","+d+")"}return t},showToast:function(){var t;if(this.toastElement=this.buildToast(),!(t="string"==typeof this.options.selector?document.getElementById(this.options.selector):this.options.selector instanceof HTMLElement||"undefined"!=typeof ShadowRoot&&this.options.selector instanceof ShadowRoot?this.options.selector:document.body))throw"Root element is not defined";var s=e.defaults.oldestFirst?t.firstChild:t.lastChild;return t.insertBefore(this.toastElement,s),e.reposition(),this.options.duration>0&&(this.toastElement.timeOutValue=window.setTimeout(function(){this.removeElement(this.toastElement)}.bind(this),this.options.duration)),this},hideToast:function(){this.toastElement.timeOutValue&&clearTimeout(this.toastElement.timeOutValue),this.removeElement(this.toastElement)},removeElement:function(t){t.className=t.className.replace(" on",""),window.setTimeout(function(){this.options.node&&this.options.node.parentNode&&this.options.node.parentNode.removeChild(this.options.node),t.parentNode&&t.parentNode.removeChild(t),this.options.callback.call(t),e.reposition()}.bind(this),400)}},e.reposition=function(){for(var t,e={top:15,bottom:15},s={top:15,bottom:15},n={top:15,bottom:15},o=document.getElementsByClassName("toastify"),r=0;r0?window.innerWidth:screen.width)<=360?(o[r].style[t]=n[t]+"px",n[t]+=a+15):!0===i(o[r],"toastify-left")?(o[r].style[t]=e[t]+"px",e[t]+=a+15):(o[r].style[t]=s[t]+"px",s[t]+=a+15)}return this},e.lib.init.prototype=e.lib,e},(a=d).exports?a.exports=c():l.Toastify=c();var h=d.exports,u={exports:{}};!function(e){!function(t,s,i){var n,o=256,r=i.pow(o,6),a=i.pow(2,52),l=2*a,c=255;function d(e,c,d){var b=[],y=p(m((c=1==c?{entropy:!0}:c||{}).entropy?[e,f(s)]:null==e?function(){try{var e;return n&&(e=n.randomBytes)?e=e(o):(e=new Uint8Array(o),(t.crypto||t.msCrypto).getRandomValues(e)),f(e)}catch(e){var i=t.navigator,r=i&&i.plugins;return[+new Date,t,r,t.screen,f(s)]}}():e,3),b),g=new h(b),w=function(){for(var t=g.g(6),e=r,s=0;t=l;)t/=2,e/=2,s>>>=1;return(t+s)/e};return w.int32=function(){return 0|g.g(4)},w.quick=function(){return g.g(4)/4294967296},w.double=w,p(f(g.S),s),(c.pass||d||function(t,e,s,n){return n&&(n.S&&u(n,g),t.state=function(){return u(g,{})}),s?(i.random=t,e):t})(w,y,"global"in c?c.global:this==i,c.state)}function h(t){var e,s=t.length,i=this,n=0,r=i.i=i.j=0,a=i.S=[];for(s||(t=[s++]);n65536?(n[0]=240|(1835008&o)>>>18,n[1]=128|(258048&o)>>>12,n[2]=128|(4032&o)>>>6,n[3]=128|63&o):o>2048?(n[0]=224|(61440&o)>>>12,n[1]=128|(4032&o)>>>6,n[2]=128|63&o):o>128?(n[0]=192|(1984&o)>>>6,n[1]=128|63&o):n[0]=o,this.parsedData.push(n)}this.parsedData=Array.prototype.concat.apply([],this.parsedData),this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function e(t,e){this.typeNumber=t,this.errorCorrectLevel=e,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}t.prototype={getLength:function(t){return this.parsedData.length},write:function(t){for(var e=0,s=this.parsedData.length;e=7&&this.setupTypeNumber(t),null==this.dataCache&&(this.dataCache=e.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,s)},setupPositionProbePattern:function(t,e){for(var s=-1;s<=7;s++)if(!(t+s<=-1||this.moduleCount<=t+s))for(var i=-1;i<=7;i++)e+i<=-1||this.moduleCount<=e+i||(this.modules[t+s][e+i]=0<=s&&s<=6&&(0==i||6==i)||0<=i&&i<=6&&(0==s||6==s)||2<=s&&s<=4&&2<=i&&i<=4)},getBestMaskPattern:function(){for(var t=0,e=0,s=0;s<8;s++){this.makeImpl(!0,s);var i=u.getLostPoint(this);(0==s||t>i)&&(t=i,e=s)}return e},createMovieClip:function(t,e,s){var i=t.createEmptyMovieClip(e,s);this.make();for(var n=0;n>s&1);this.modules[Math.floor(s/3)][s%3+this.moduleCount-8-3]=i}for(s=0;s<18;s++){i=!t&&1==(e>>s&1);this.modules[s%3+this.moduleCount-8-3][Math.floor(s/3)]=i}},setupTypeInfo:function(t,e){for(var s=this.errorCorrectLevel<<3|e,i=u.getBCHTypeInfo(s),n=0;n<15;n++){var o=!t&&1==(i>>n&1);n<6?this.modules[n][8]=o:n<8?this.modules[n+1][8]=o:this.modules[this.moduleCount-15+n][8]=o}for(n=0;n<15;n++){o=!t&&1==(i>>n&1);n<8?this.modules[8][this.moduleCount-n-1]=o:n<9?this.modules[8][15-n-1+1]=o:this.modules[8][15-n-1]=o}this.modules[this.moduleCount-8][8]=!t},mapData:function(t,e){for(var s=-1,i=this.moduleCount-1,n=7,o=0,r=this.moduleCount-1;r>0;r-=2)for(6==r&&r--;;){for(var a=0;a<2;a++)if(null==this.modules[i][r-a]){var l=!1;o>>n&1)),u.getMask(e,i,r-a)&&(l=!l),this.modules[i][r-a]=l,-1==--n&&(o++,n=7)}if((i+=s)<0||this.moduleCount<=i){i-=s,s=-s;break}}}},e.PAD0=236,e.PAD1=17,e.createData=function(t,s,i){for(var n=y.getRSBlocks(t,s),o=new g,r=0;r8*l)throw new Error("code length overflow. ("+o.getLengthInBits()+">"+8*l+")");for(o.getLengthInBits()+4<=8*l&&o.put(0,4);o.getLengthInBits()%8!=0;)o.putBit(!1);for(;!(o.getLengthInBits()>=8*l||(o.put(e.PAD0,8),o.getLengthInBits()>=8*l));)o.put(e.PAD1,8);return e.createBytes(o,n)},e.createBytes=function(t,e){for(var s=0,i=0,n=0,o=new Array(e.length),r=new Array(e.length),a=0;a=0?m.get(p):0}}var f=0;for(d=0;d=0;)e^=u.G15<=0;)e^=u.G18<>>=1;return e},getPatternPosition:function(t){return u.PATTERN_POSITION_TABLE[t-1]},getMask:function(t,e,s){switch(t){case n:return(e+s)%2==0;case o:return e%2==0;case r:return s%3==0;case a:return(e+s)%3==0;case l:return(Math.floor(e/2)+Math.floor(s/3))%2==0;case c:return e*s%2+e*s%3==0;case d:return(e*s%2+e*s%3)%2==0;case h:return(e*s%3+(e+s)%2)%2==0;default:throw new Error("bad maskPattern:"+t)}},getErrorCorrectPolynomial:function(t){for(var e=new b([1],0),s=0;s5&&(s+=3+o-5)}for(i=0;i=256;)t-=255;return p.EXP_TABLE[t]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},f=0;f<8;f++)p.EXP_TABLE[f]=1<>>7-t%8&1)},put:function(t,e){for(var s=0;s>>e-s-1&1))},getLengthInBits:function(){return this.length},putBit:function(t){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),t&&(this.buffer[e]|=128>>>this.length%8),this.length++}};var w=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],Z=function(){var t=function(t,e){this._bIsPainted=!1,this._htOption=e,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=e.width,this._elCanvas.height=e.height,t.appendChild(this._elCanvas),this._el=t,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._bSupportDataURI=null};return t.prototype.draw=function(t){var e=this._oContext,s=this._htOption,i=t.getModuleCount(),n=s.width/i,o=s.height/i,r=Math.round(n),a=Math.round(o);this.clear();for(var l=0;lw.length)throw new Error("Too long data");return s}m=function(t,e){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:i.H},"string"==typeof e&&(e={text:e}),e)for(var s in e)this._htOption[s]=e[s];"string"==typeof t&&(t=document.getElementById(t)),this._htOption.useSVG&&(Z=svgDrawer),this._el=t,this._oQRCode=null,this._oDrawing=new Z(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},m.prototype.makeCode=function(t){this._oQRCode=new e(X(t,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(t),this._oQRCode.make(),this._oDrawing.draw(this._oQRCode)},m.prototype.clear=function(){this._oDrawing.clear()},m.prototype.getCanvas=function(){for(let t=0;t>>2]>>>24-o%4*8&255;e[i+o>>>2]|=r<<24-(i+o)%4*8}else for(var a=0;a>>2]=s[a>>>2];return this.sigBytes+=n,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var t=l.clone.call(this);return t.words=this.words.slice(0),t},random:function(t){for(var e=[],s=0;s>>2]>>>24-n%4*8&255;i.push((o>>>4).toString(16)),i.push((15&o).toString(16))}return i.join("")},parse:function(t){for(var e=t.length,s=[],i=0;i>>3]|=parseInt(t.substr(i,2),16)<<24-i%8*4;return new c.init(s,e/2)}},u=d.Latin1={stringify:function(t){for(var e=t.words,s=t.sigBytes,i=[],n=0;n>>2]>>>24-n%4*8&255;i.push(String.fromCharCode(o))}return i.join("")},parse:function(t){for(var e=t.length,s=[],i=0;i>>2]|=(255&t.charCodeAt(i))<<24-i%4*8;return new c.init(s,e)}},m=d.Utf8={stringify:function(t){try{return decodeURIComponent(escape(u.stringify(t)))}catch(t){throw new Error("Malformed UTF-8 data")}},parse:function(t){return u.parse(unescape(encodeURIComponent(t)))}},p=a.BufferedBlockAlgorithm=l.extend({reset:function(){this._data=new c.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=m.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(t){var s,i=this._data,n=i.words,o=i.sigBytes,r=this.blockSize,a=o/(4*r),l=(a=t?e.ceil(a):e.max((0|a)-this._minBufferSize,0))*r,d=e.min(4*l,o);if(l){for(var h=0;h>>2]|=t[n]<<24-n%4*8;s.call(this,i,e)}else s.apply(this,arguments)};i.prototype=e}}(),t.lib.WordArray}(w.exports),X={exports:{}},v=X.exports=function(t){return function(e){var s=t,i=s.lib,n=i.WordArray,o=i.Hasher,r=s.algo,a=[],l=[];!function(){function t(t){for(var s=e.sqrt(t),i=2;i<=s;i++)if(!(t%i))return!1;return!0}function s(t){return 4294967296*(t-(0|t))|0}for(var i=2,n=0;n<64;)t(i)&&(n<8&&(a[n]=s(e.pow(i,.5))),l[n]=s(e.pow(i,1/3)),n++),i++}();var c=[],d=r.SHA256=o.extend({_doReset:function(){this._hash=new n.init(a.slice(0))},_doProcessBlock:function(t,e){for(var s=this._hash.words,i=s[0],n=s[1],o=s[2],r=s[3],a=s[4],d=s[5],h=s[6],u=s[7],m=0;m<64;m++){if(m<16)c[m]=0|t[e+m];else{var p=c[m-15],f=(p<<25|p>>>7)^(p<<14|p>>>18)^p>>>3,b=c[m-2],y=(b<<15|b>>>17)^(b<<13|b>>>19)^b>>>10;c[m]=f+c[m-7]+y+c[m-16]}var g=i&n^i&o^n&o,w=(i<<30|i>>>2)^(i<<19|i>>>13)^(i<<10|i>>>22),Z=u+((a<<26|a>>>6)^(a<<21|a>>>11)^(a<<7|a>>>25))+(a&d^~a&h)+l[m]+c[m];u=h,h=d,d=a,a=r+Z|0,r=o,o=n,n=i,i=Z+(w+g)|0}s[0]=s[0]+i|0,s[1]=s[1]+n|0,s[2]=s[2]+o|0,s[3]=s[3]+r|0,s[4]=s[4]+a|0,s[5]=s[5]+d|0,s[6]=s[6]+h|0,s[7]=s[7]+u|0},_doFinalize:function(){var t=this._data,s=t.words,i=8*this._nDataBytes,n=8*t.sigBytes;return s[n>>>5]|=128<<24-n%32,s[14+(n+64>>>9<<4)]=e.floor(i/4294967296),s[15+(n+64>>>9<<4)]=i,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var t=o.clone.call(this);return t._hash=this._hash.clone(),t}});s.SHA256=o._createHelper(d),s.HmacSHA256=o._createHmacHelper(d)}(Math),t.SHA256}(w.exports);const L="node"===e.CROQUET_PLATFORM;let x;function G(t){const e=t.sigBytes,s=t.words,i=new Uint8Array(e);let n=0,o=0;for(;n>>24,n===e)break;if(i[n++]=(16711680&t)>>>16,n===e)break;if(i[n++]=(65280&t)>>>8,n===e)break;i[n++]=255&t}return i}function S(t){function e(t){const e=t.indexOf("{"),s=t.lastIndexOf("}");if(-1===e||-1===s||s`${t}:${e(""+i[t])}`)).join(""))}return s}function k(t){return btoa(String.fromCharCode(...new Uint8Array(t))).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function W(){return r.has("debug","hashing",!1)}x=globalThis.crypto&&globalThis.crypto.subtle&&"function"==typeof globalThis.crypto.subtle.digest?globalThis.crypto.subtle.digest.bind(globalThis.crypto.subtle):(t,e)=>{if("SHA-256"!==t)throw Error("Croquet: only SHA-256 available");const s=Z.create(e);return G(v(s)).buffer};const T={},C=new TextEncoder;async function V(t){const e=C.encode(t),s=await async function(t){return 0===t.length?"47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU":k(await x("SHA-256",t))}(e);return W()&&(T[s]={string:t,buffer:e}),s}const P=[],R={};const Y=new Set;const M=Date.now();"undefined"==typeof performance&&(window.performance={now:()=>Date.now()-M});const I=["simulate","update","render","snapshot"],K={total:"black",update:"blue",render:"magenta",simulate:"yellow",snapshot:"green",backlog:"red",network:"lightgray"};let H,z,N=null,F=null,_=null,j=0,Q=null,E=null;function J(t){for(N=t;t.firstChild;)t.removeChild(t.firstChild);t.style.background="#faf0dc",Q=document.createElement("canvas"),E=Q.getContext("2d"),Q.id="text_stats",Q.width=Math.min(140,window.innerWidth),Q.height=36,Q.style.width=Q.width,Q.style.height=Q.height,E.font="9.5pt sans-serif",t.appendChild(Q),t.title=Object.entries(K).map((t=>{let[e,s]=t;return`${s}: ${e}`})).join("\n"),F=document.createElement("canvas"),F.width=Math.min(125,window.innerWidth),F.height=125,F.style.width="100%";const e=document.createElement("div");e.id="innerDiv",t.appendChild(e),e.appendChild(F),_=F.getContext("2d")}const U=[];let D=0,O=!1,B=tt(0);const A=1e3/60;function $(t){return 20*(1-t/A)+60}function q(t){H=function(t){const e=document.createElement("canvas");return e.width=t.width,e.height=t.height,e.style.width="100%",e.style.position="absolute",e.style.left="0px",N.querySelector("#innerDiv").appendChild(e),e}(t),z=H.getContext("2d"),z.strokeStyle="rgba(255, 255, 255, 0.5)";for(let t=0;t<60;t+=A){const e=$(t);z.moveTo(0,e),z.lineTo(H.width,e),z.stroke()}}function tt(t){return{start:t,total:0,items:{},users:0,backlog:0,network:0,latency:0,activity:1e3,connected:O}}function et(t){B.total=t-B.start;const e=Math.min(120,window.innerWidth);if(U.length>=e&&U.splice(0,U.length-e+1),U.push(B),U.length<=1)return;if(!N)return;if(0===N.offsetHeight)return;const s=U.slice(1).filter((t=>t.total)),i=s.map((t=>t.total)).reduce(((t,e)=>t+e),0)/s.length,n=Math.max(...s.map((t=>t.total)));Math.max(...s.map((t=>Math.max(t.backlog,t.network)))),D=1e3,function(t,e){E.globalCompositeOperation="copy",E.fillStyle="rgb(255, 255, 255, 0)",E.fillRect(0,0,Q.width,Q.height),E.fillStyle="rgb(0, 0, 0, 1)",E.globalCompositeOperation="source-over";let s=`${B.users} users, ${Math.round(1e3/t)} fps`;e>70&&(s+=` ${Math.ceil(e).toLocaleString()}ms`),E.fillText(s,2,15),s=B.backlog<100&&B.activity<1e3?`latency: ${B.latency} ms`:`backlog: ${B.backlog<100?"0.0":(B.backlog/1e3).toFixed(1)} s`,E.fillText(s,2,33)}(i,n),H||q(F),j===F.width?(_.globalCompositeOperation="copy",_.drawImage(F,1,0,F.width-1,F.height,0,0,F.width-1,F.height),_.globalCompositeOperation="source-over",_.fillStyle="transparent",_.fillRect(F.width-1,0,1,F.height)):j++;const o=t=>$(t/D*-2*A)+5;{const t=U[U.length-1],e=j-.5;let s=$(0);_.beginPath(),_.moveTo(e,s),_.lineTo(e,$(t.total)),_.strokeStyle=K[t.connected?"total":"network"],_.stroke(),_.beginPath(),_.moveTo(e,s),s=$(t.total);let i=0;for(const n of I)t.items[n]&&(i+=t.items[n],s=$(i),_.lineTo(e,s),_.strokeStyle=K[n],_.stroke(),_.beginPath(),_.moveTo(e,s));t.network&&(_.beginPath(),_.moveTo(e,o(0)),_.lineTo(e,o(t.network)),_.strokeStyle=K.network,_.stroke())}}const st=[],it={};let nt={};const ot={frames:U,animationFrame(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};et(t),B=tt(t);for(const[t,s]of Object.entries(e))this[t](s)},begin(t){const e=performance.now();B.items[t]=(B.items[t]||0)-e;const s=st[st.length-1];return s&&(B.items[s]+=e),st.push(t),e},end(t){const e=performance.now();B.items[t]+=e;const s=st.pop();if(s!==t)throw Error(`Unmatched stats calls: expected end("${s}"), got end("${t}")`);const i=st[st.length-1];return i&&(B.items[i]-=e),e},backlog(t){B.backlog=Math.max(t,B.backlog)},network(t){B.network=t},starvation(t){B.network=t},latency(t){B.latency=t},activity(t){B.activity=t},users(t){B.users=t},connected(t){const e=O;B.connected=O=t,e&&!O&&H&&(H.remove(),z=null)},networkTraffic:it,addNetworkTraffic(t,e){it[t]=(it[t]||0)+e},perSecondTally(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(window.logMessageStats)for(const[e,s]of Object.entries(t))nt[e]=(nt[e]||0)+s},stepSession(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const s=Math.floor(Date.now()/1e3);if(!window.logMessageStats)return nt={second:s},null;let i=null;if(s!==nt.second){if(nt.second&&e&&(nt.requestedMessages||nt.sentMessagesTotal)){i={...nt};const t=s-nt.second;1!==t&&(i.sampleSeconds=t),i.sentBundles&&(i.averageDelay=Math.round(10*i.sendDelay/i.sentMessagesTotal)/10,i.averageBundlePayload=Math.round(i.sentBundlePayload/i.sentBundles)),delete i.second,delete i.sendDelay,delete i.sentBundlePayload}nt={second:s}}return i}};globalThis.CROQUETSTATS=ot;const rt="ontouchstart"in document.documentElement,at=window.parent!==window,lt=rt?20:12,ct=rt?0:15;let dt=!1;function ht(){if(dt)return;dt=!0;const t=`\n #croquet_dock { position: fixed; z-index: 2; border: 3px solid white; bottom: 6px; left: 6px; width: 36px; height: 36px; box-sizing: border-box; background: white; opacity: 0.4; transition: all 0.3s ease; }\n #croquet_dock.active { opacity: 0.95; border-radius: 12px; }\n #croquet_dock.debug { width: 84px; }\n #croquet_dock_bar { position: absolute; border: 3px solid white; width: 100%; height: 30px; box-sizing: border-box; background: white; }\n\n #croquet_badge { position: absolute; width: 72px; height: 24px; top: 50%; transform: translate(0px, -50%); cursor: none; }\n #croquet_dock.active #croquet_badge { left: 2%; }\n #croquet_dock:not(.debug) #croquet_badge { display: none; }\n\n .croquet_dock_button { position: absolute; width: ${lt}%; height: 90%; top: 50%; transform: translate(0px, -50%); border-radius: 20%; }\n .croquet_dock_button:focus { outline: 0; }\n .croquet_dock_button canvas { position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; }\n #croquet_dock:not(.active) .croquet_dock_button { display: none; }\n #croquet_dock_left { right: ${2+ct+lt+2}% }\n #croquet_dock:not(.debug) #croquet_dock_left { display: none; }\n #croquet_dock_right { right: ${2+ct}%; }\n #croquet_dock:not(.debug) #croquet_dock_right { display: none; }\n #croquet_dock_pin { right: 2%; }\n #croquet_dock_pin.pinned { background: #cce6ff; }\n\n #croquet_dock_content { position: absolute; left: 2px; top: 2px; right: 2px; bottom: 2px; background: white; overflow: hidden; }\n #croquet_dock.debug:not(.active) #croquet_dock_content { display: none; }\n #croquet_dock.debug:not(.active) #croquet_dock_content div { display: none; }\n\n #croquet_qrcode { position: absolute; width: 100%; height: 100%;box-sizing: border-box; cursor: crosshair; }\n #croquet_dock.active #croquet_qrcode { border: 6px solid white; }\n #croquet_dock.debug #croquet_qrcode:not(.active) { display: none; }\n #croquet_qrcode canvas { image-rendering: pixelated; }\n\n #croquet_stats { position: absolute; width: 70%; height: 90%; left: 15%; top: 5%; opacity: 0.8; font-family: sans-serif; }\n #croquet_stats:not(.active) { display: none; }\n`,e=document.createElement("style");e.innerHTML=t,document.head.insertBefore(e,document.head.getElementsByTagName("style")[0])}let ut=!1;let mt,pt=!1;function ft(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return t&&Pt.showMessage(t,{...e,level:"warning"})}function bt(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return t&&Pt.showMessage(t,{...e,level:"status"})}function yt(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"error";console.error(`Error during ${t}`,e);const i=(e.stack||"").split("\n").filter((t=>!t.match(/croquet-.*\.min.js/))).join("\n");Pt.showMessage(`Error during ${t}: ${e.message}\n\n${i}`,{level:s,duration:"error"===s?1e4:void 0,stopOnFocus:!0})}function gt(t,e){const s=Tt(Pt.root,(()=>document.body));if(!1===s)return null;!function(){if(pt)return;pt=!0;let t="/*!\n * Toastify js 1.5.0\n * https://github.com/apvarun/toastify-js\n * @license MIT licensed\n *\n * Copyright (C) 2018 Varun A P\n */\n .toastify {\n padding: 12px 20px;\n color: #ffffff;\n display: inline-block;\n box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);\n background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);\n background: linear-gradient(135deg, #73a5ff, #5477f5);\n position: fixed;\n opacity: 0;\n transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);\n border-radius: 2px;\n cursor: pointer;\n text-decoration: none;\n max-width: calc(50% - 20px);\n z-index: 2147483647;\n }\n .toastify.on {\n opacity: 1;\n }\n .toast-close {\n opacity: 0.4;\n padding: 0 5px;\n }\n .toastify-right {\n right: 15px;\n }\n .toastify-left {\n left: 15px;\n }\n .toastify-top {\n top: -150px;\n }\n .toastify-bottom {\n bottom: -150px;\n }\n .toastify-rounded {\n border-radius: 25px;\n }\n .toastify-avatar {\n width: 1.5em;\n height: 1.5em;\n margin: 0 5px;\n border-radius: 2px;\n }\n @media only screen and (max-width: 360px) {\n .toastify-right, .toastify-left {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n }\n }\n";t+="\n .toastify {\n font-family: sans-serif;\n border-radius: 8px;\n }\n\n .toastify-center {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n max-width: -moz-fit-content;\n }\n";const e=document.createElement("style");e.innerHTML="/*!\n * Toastify js 1.5.0\n * https://github.com/apvarun/toastify-js\n * @license MIT licensed\n *\n * Copyright (C) 2018 Varun A P\n */\n .toastify {\n padding: 12px 20px;\n color: #ffffff;\n display: inline-block;\n box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);\n background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);\n background: linear-gradient(135deg, #73a5ff, #5477f5);\n position: fixed;\n opacity: 0;\n transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);\n border-radius: 2px;\n cursor: pointer;\n text-decoration: none;\n max-width: calc(50% - 20px);\n z-index: 2147483647;\n }\n .toastify.on {\n opacity: 1;\n }\n .toast-close {\n opacity: 0.4;\n padding: 0 5px;\n }\n .toastify-right {\n right: 15px;\n }\n .toastify-left {\n left: 15px;\n }\n .toastify-top {\n top: -150px;\n }\n .toastify-bottom {\n bottom: -150px;\n }\n .toastify-rounded {\n border-radius: 25px;\n }\n .toastify-avatar {\n width: 1.5em;\n height: 1.5em;\n margin: 0 5px;\n border-radius: 2px;\n }\n @media only screen and (max-width: 360px) {\n .toastify-right, .toastify-left {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n }\n }\n\n .toastify {\n font-family: sans-serif;\n border-radius: 8px;\n }\n\n .toastify-center {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n max-width: -moz-fit-content;\n }\n",document.head.insertBefore(e,document.head.getElementsByTagName("style")[0])}();const i={text:t,duration:3e3,gravity:"bottom",position:"right",stopOnFocus:!0,...e};let n;return s instanceof Element&&s!==document.body?(n=s.id,n||(s.id=n="_croquetToastParent")):"string"==typeof s&&(n=s),n&&(i.selector=n),h(i).showToast()}try{if(mt=window.localStorage,mt["croquet-debug-persist-allowed"]="true","true"!==mt["croquet-debug-persist-allowed"])throw Error("localStorage not persisted");delete mt["croquet-debug-persist-allowed"]}catch(Mo){console.warn("localStorage not allowed"),mt={}}const wt={get pinned(){return"true"===mt[window.location.pathname+"/croquet-debug-ui-pinned"]},set pinned(t){mt[window.location.pathname+"/croquet-debug-ui-pinned"]=!!t},get activePage(){return mt[window.location.pathname+"/croquet-debug-ui-activePage"]},set activePage(t){mt[window.location.pathname+"/croquet-debug-ui-activePage"]=t}},Zt=t=>{t.preventDefault(),t.stopPropagation()};function Xt(t,e,s){const i=document.createElement("canvas"),n=i.width=40*lt/12,o=i.height=60,r=i.getContext("2d");r.font="36px Arial",r.textAlign="center",r.textBaseline="middle",r.fillStyle="black",r.fillText(t,n/2,.55*o);const a=document.createElement("button");a.id=e,a.className="croquet_dock_button";const l=t=>{t.preventDefault(),t.stopPropagation(),s()};return rt?(a.ontouchstart=l,a.ontouchend=Zt,a.onpointerdown=Zt,a.onpointerup=Zt):(a.onclick=l,a.onpointerdown=Zt,a.onpointerup=Zt),a.appendChild(i),a}function vt(t,e){if(!1===Pt.badge)return;const s=function(t){const e=new p(t),s=["bcdfghjklmnpqrstvwxyz","aeiou"];let i="";for(let t=0;t<5;t++)i+=s[t%2][e.quick()*s[t%2].length|0];return i}(e);for(document.title=document.title.replace(/:.*/,""),document.title+=":"+s;t.firstChild;)t.removeChild(t.firstChild);const i=document.createElement("canvas"),n=i.width=120,o=i.height=40;i.style.width="100%",t.appendChild(i);const r=i.getContext("2d"),a=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;const s=new p(t),i=[];for(let t=0;t2&&void 0!==arguments[2]?arguments[2]:{};for(;t.firstChild;)t.removeChild(t.firstChild);return new b(t,{text:e,width:128,height:128,colorDark:"#000000",colorLight:"#ffffff",correctLevel:b.CorrectLevel.L,...s})}function xt(){if(!1===Pt.root||!1===Pt.qrcode)return;if(r.noqr)return;const t=Pt.sessionURL;if(!t)return void console.warn("App.sessionURL is not set");const e=Tt(Pt.qrcode);if(!e)return;rt||(e.onclick=e=>{e.preventDefault(),e.stopPropagation(),e.shiftKey?function(){const t=document.getElementById("croquet_dock");t&&t.classList.toggle("debug")}():window.open(t)});Lt(e,t).getCanvas().style.width="100%"}let Gt,St,kt=0;function Wt(){!function(){if(ut)return;ut=!0;const t=`\n ${at?"body { min-height: 100vh }":""}\n #croquet_spinnerOverlay {\n z-index: 1000;\n position: fixed;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n background-color:#333;\n opacity:0.9;\n display:flex;\n align-items:center;\n justify-content:center;\n transition: opacity 1.0s ease-out;\n }\n /* https://github.com/lukehaas/css-loaders */\n @keyframes croquet_dots {\n 0%, 80%, 100% { box-shadow: 0 2.5em 0 -1.3em; }\n 40% { box-shadow: 0 2.5em 0 0; }\n }\n #croquet_loader,\n #croquet_loader::before,\n #croquet_loader::after {\n border-radius: 50%;\n width: 2.5em;\n height: 2.5em;\n animation: croquet_dots 1.8s infinite ease-in-out;\n }\n #croquet_loader {\n color: #fff;\n font-size: 10px;\n margin: 80px auto;\n position: relative;\n text-indent: -9999em;\n animation-delay: -0.16s;\n }\n #croquet_loader::before,\n #croquet_loader::after {\n content: '';\n position: absolute;\n top: 0;\n }\n #croquet_loader::before { left: -3.5em; animation-delay: -0.32s; }\n #croquet_loader::after { left: 3.5em; }\n #croquet_spinnerOverlay.croquet_error>*,\n #croquet_spinnerOverlay.croquet_error>*::before,\n #croquet_spinnerOverlay.croquet_error>*::after {\n color: #f00;\n }\n #croquet_spinnerOverlay.croquet_fatal>*,\n #croquet_spinnerOverlay.croquet_fatal>*::before,\n #croquet_spinnerOverlay.croquet_fatal>*::after {\n color: #f00;\n box-shadow: 0 2.5em 0 0 !important;\n animation: none !important;\n }\n`,e=document.createElement("style");e.innerHTML=t,document.head.insertBefore(e,document.head.getElementsByTagName("style")[0])}();const t=document.createElement("div");t.id="croquet_spinnerOverlay";const e=document.createElement("div");return e.id="croquet_loader",e.innerText="Catching up...",t.appendChild(e),t}function Tt(t,e){if(!1===t)return!1;if(t instanceof Element)return t;if("string"==typeof t){const e=document.getElementById(t);if(e)return e}return e?e():null}const Ct=new Set;let Vt=function(){let t=null;const e=document.getElementsByTagName("link");for(const s of e)if("canonical"===s.getAttribute("rel")){t=s.getAttribute("href");break}return t||window.location.href}();const Pt={get sessionURL(){return Vt},set sessionURL(t){Vt=t,xt()},root:null,sync:!0,messages:!1,badge:!1,stats:!1,qrcode:!1,makeWidgetDock:function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(r.nodock)return;const e=t.debug||r.debug,s=document.getElementById("croquet_dock");s&&s.parentElement.removeChild(s);const i=Tt(Pt.root,(()=>document.body));if(!i)return;ht();const n=document.createElement("div");n.id="croquet_dock",e&&n.classList.add("debug"),at&&!t.iframe&&(n.style.display="none"),i.appendChild(n);const o=document.createElement("div");let a;o.id="croquet_dock_bar",n.appendChild(o),!1!==t.badge&&(a=document.createElement("div"),a.id="croquet_badge",o.appendChild(a),Pt.badge=a);const l=document.createElement("div");l.id="croquet_dock_content",n.appendChild(l);const c=[];let d,h;if(!1!==t.qrcode){Pt.sessionURL&&(d=document.createElement("div"),d.id="croquet_qrcode",l.appendChild(d),c.push(d.id),Pt.qrcode=d,e||(wt.activePage=d.id))}if(!1!==t.stats&&(h=document.createElement("div"),h.id="croquet_stats",l.appendChild(h),c.push(h.id),Pt.stats=h),c.length){function X(t){const e=c.length;let s,i=0;if(wt.activePage){const t=c.indexOf(wt.activePage);t>=0?(i=t,s=document.getElementById(wt.activePage)):wt.activePage=null}const n=c[(i+e+t)%e];let o;n===wt.activePage?o=s:(s&&s.classList.remove("active"),o=document.getElementById(n)),o&&o.classList.add("active"),wt.activePage=n}c.length>1&&(o.appendChild(Xt("<","croquet_dock_left",(()=>X(-1)))),o.appendChild(Xt(">","croquet_dock_right",(()=>X(1))))),X(0)}if(!rt&&!t.alwaysPinned){const v=Xt("📌","croquet_dock_pin",(()=>{wt.pinned=!wt.pinned,L()})),L=()=>{wt.pinned?v.classList.add("pinned"):v.classList.remove("pinned")};L(),o.appendChild(v)}const u=200,m=166,p=8,f=t=>{n.style.width=`${t}px`;const e=1.18*t;n.style.height=`${e}px`;const s=18*t/100;o.style.height=`${s}px`,l.style.top=`${s+2}px`,a&&(a.style.height=.9*s+"px",a.style.width=.9*s*3+"px"),d&&(d.style.border=p*t/u+"px solid white")},b=()=>{n.style.width=n.style.height="",o.style.height="",l.style.top="",a&&(a.style.height=a.style.width=""),d&&(d.style.border="")};let y=t.fixedSize||u;const g=()=>n.classList.contains("active"),w=()=>{n.classList.add("active"),f(y),setTimeout((()=>n.style.transition="none"),300)},Z=()=>{n.style.transition="",n.classList.remove("active"),b()};if(rt)Z(),n.ontouchstart=t=>{t.preventDefault(),t.stopPropagation(),g()?Z():w()},n.ontouchend=Zt,n.onpointerdown=Zt,n.onpointerup=Zt;else if(t.alwaysPinned?w():(wt.pinned?w():Z(),n.onmouseenter=w,n.onmouseleave=()=>{wt.pinned||Z()}),!t.fixedSize){let x=0;n.addEventListener("wheel",(t=>{t.stopPropagation();const e=Date.now();if(e-x<100)return;x=e;let{deltaY:s}=t;s=Math.sign(s)*Math.min(5,Math.abs(s));const i=.8*Math.min(window.innerWidth,window.innerHeight);y=Math.max(m,Math.min(i,n.offsetWidth/1.05**s)),f(y)}),{passive:!0})}},makeSessionWidgets:function(t){!function(t){if(!t||!1===Pt.root)return;const e=Tt(Pt.badge);e&&vt(e,t)}(t),xt(),function(){if(!1===Pt.root)return;if(r.nostats)return;const t=Tt(Pt.stats);t&&J(t)}()},makeQRCanvas(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!Pt.sessionURL)return null;const e=Lt(document.createElement("div"),Pt.sessionURL,t);return e&&e.getCanvas()},clearSessionMoniker:function(){!1!==Pt.badge&&(document.title=document.title.replace(/:.*/,""))},showSyncWait(t){!1===Pt.root?t=!1:Gt||(Gt=Wt()),function(t){if(St!==t&&("string"!=typeof St||!0!==t))if(!1===Pt.sync&&(t=!1),St=t,t)clearTimeout(kt),kt=setTimeout((()=>{St&&(Tt(Pt.root,(()=>document.body)).appendChild(Gt),Gt.style.opacity=.9,Gt.className="error"===St?"croquet_error":"fatal"===St?"croquet_fatal":"")}),500);else{if(!Gt)return;clearTimeout(kt),Gt.style.opacity=0,Gt.className="",kt=setTimeout((()=>{St||Gt.parentElement&&Gt.parentElement.removeChild(Gt)}),500)}}(t)},messageFunction:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=e.level;let i;return"error"===s?(i="orangered,red",console.error(t)):"warning"===s?(i="gold,orange",console.warn(t)):i="silver,gray",gt(t,{style:{background:`linear-gradient(90deg,${i})`},...e})},showMessage(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("once"===e.only){if(Ct.has(t))return null;Ct.add(t)}return"fatal"===e.level&&(e.level="error",e.showSyncWait="fatal"),e.showSyncWait&&("fatal"!==e.showSyncWait||e.duration||(e.duration=-1),Pt.showSyncWait(e.showSyncWait)),r.nomessages||!1===Pt.root||!1===Pt.messages||!Pt.messageFunction?("warning"===e.level&&console.warn(t),"error"===e.level&&console.error(t),null):Pt.messageFunction(t,e)},isCroquetHost:t=>t.endsWith("croquet.io")||["localhost","127.0.0.1","[::1]"].includes(t)||t.endsWith("ngrok.io"),referrerURL(){const t=new URL(Pt.sessionURL),e=this.isCroquetHost(t.hostname);return`${t.protocol}//${t.host}${t.pathname}${e?t.search:""}`},autoSession(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{key:"q"};"string"==typeof t&&(t={key:t}),t||(t={});const e=t.key||"q",s=new URL(Pt.sessionURL);let i="";const n=s.search.slice(1).split("&"),o=n.find((t=>t.split("=")[0]===e));if(o?i=o.replace(/[^=]*=/,""):(i=n.find((t=>!t.includes("="))),i||(i=s.hash.slice(1),i&&(s.hash="",s.search?s.searchParams.set(e,i):s.search=i))),i)try{i=decodeURIComponent(i)}catch(t){}else i=Math.floor(Math.random()*36**10).toString(36),s.searchParams.set(e,i);const a=s.toString("");window.location.href!==a&&(window.history.replaceState({},"",a),Pt.sessionURL=a),r.has("debug","session")&&console.log(`Croquet.App.autoSession: "${i}"`);const l=Promise.resolve(i);return l[Symbol.toPrimitive]=()=>(console.warn("Deprecated: Croquet.App.autoSession() return value used directly. It returns a promise now!"),i),l},autoPassword(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{key:"pw",scrub:!1,keyless:!1};const e=t.key||"pw",s=t.scrub&&!r.has("debug","password"),i=t.keyless,n=new URL(Pt.sessionURL);let o="";const a=n.hash.slice(1);if(a){const t=a.split("&"),r=t.find((t=>t.split("=")[0]===e));r?(o=r.replace(/[^=]*=/,""),o&&s&&(n.hash=t.filter((t=>t.split("=")[0]!==e)).join("&"))):i&&(o=t.find((t=>!t.includes("="))),o&&s&&(n.hash=t.filter((t=>t!==o)).join("&")))}if(!o){const t=new Uint8Array(16);window.crypto.getRandomValues(t),o=k(t.buffer),n.hash=a?`${a}&${e}=${o}`:i?o:`${e}=${o}`,Pt.sessionURL=n.href,s&&(n.hash=a)}if(r.has("debug","session")&&console.log(`Croquet.App.sessionUrl: ${Pt.sessionURL}`),window.location.href!==n.href&&window.history.replaceState({},"",n.href),o)try{o=decodeURIComponent(o)}catch(t){}r.has("debug","session")&&console.log(`Croquet.App.autoPassword: "${o}"`);const l=Promise.resolve(o);return l[Symbol.toPrimitive]=()=>(console.warn("Deprecated: Croquet.App.autoPassword() return value used directly. It returns a promise now!"),o),l}};function Rt(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,i="none";for(const n of["immediate","queued","oncePerFrame","oncePerFrameWhileSynced"])for(const o of t[n])o.for===e?null===s||o.unbound===s?t[n].delete(o):i="subscriber":"none"===i&&(i="others");return i}const Yt=new class{constructor(){this.subscriptions={},this.subscribers=new Map,this.queuedEvents=[],this.perFrameEvents=new Map,this.perSyncedFrameEvents=new Map,this.subscriberIds=0}register(t){return"V"+ ++this.subscriberIds}deregister(t){}addSubscription(t,e,s,i,n){if("vote"===n)return void this.addSubscription(t,e+"#__vote",s,i,"immediate");const o=t+":"+e,r=i;r.for=s;let a=this.subscriptions[o];if(a||(a=this.subscriptions[o]={immediate:new Set,queued:new Set,oncePerFrame:new Set,oncePerFrameWhileSynced:new Set}),!a[n])throw Error(`Unknown subscribe() option: handling="${n}"`);a[n].add(r);let l=this.subscribers.get(s);l||this.subscribers.set(s,l=new Set),l.add(o)}removeSubscription(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;const n=t+":"+e,o=this.subscriptions[n];if(o){const t=Rt(o,s,i);if(t||delete this.subscriptions[n],"subscriber"!==t){const t=this.subscribers.get(s);t.delete(n),0===t.size&&this.subscribers.delete(s)}}e.endsWith("#__vote")||this.removeSubscription(t,e+"#__vote",s)}removeAllSubscriptionsFor(t){const e=this.subscribers.get(t);if(e){for(const s of e){const e=this.subscriptions[s];if(e){"none"===Rt(e,t)&&delete this.subscriptions[s]}else console.error(`Croquet: topic ${s} not found in subscriptions table for ${t} during removeAllSubscriptionsFor()`)}this.subscribers.delete(t)}}handleEvent(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t=>t();const i=this.subscriptions[t];i&&(i.queued.size>0&&this.queuedEvents.push({topic:t,data:e}),i.oncePerFrame.size>0&&this.perFrameEvents.set(t,e),i.oncePerFrameWhileSynced.size>0&&this.perSyncedFrameEvents.set(t,e),i.immediate.size>0&&s((()=>{for(const s of i.immediate)try{s(e)}catch(e){console.error(e),console.warn(`Croquet: error "${e.message}" in "immediate" subscription ${t}`)}})))}processFrameEvents(t,e){let s=0;const i=(t,e,i)=>{const n=this.subscriptions[e];if(n)for(const o of n[t]){try{o(i)}catch(s){console.error(s),console.warn(`Croquet: error "${s.message}" in "${t}" subscription ${e}`)}s++}};for(const{topic:t,data:e}of this.queuedEvents)i("queued",t,e);if(this.queuedEvents.length=0,t){for(const[t,e]of this.perFrameEvents)i("oncePerFrame",t,e);if(this.perFrameEvents.clear(),e){for(const[t,e]of this.perSyncedFrameEvents)i("oncePerFrameWhileSynced",t,e);this.perSyncedFrameEvents.clear()}for(const{topic:t,data:e}of this.queuedEvents)i("queued",t,e);this.queuedEvents.length=0}return s}};let Mt={get subscribe(){return Mt={subscribe:r.has("debug","subscribe",!1)},Mt.subscribe}};class It{constructor(t){this.vm=t}register(t){return this.vm.registerModel(t)}deregister(t){this.vm.deregisterModel(t.id)}publish(t,e,s){this.vm.publishFromModel(s,t,e)}subscribe(t,e,s,i){return Mt.subscribe&&console.log(`Model.subscribe("${e}:${s}", ${t} ${(""+i).replace(/\([\s\S]*/,"")})`),this.vm.addSubscription(t,e,s,i)}unsubscribe(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"*";Mt.subscribe&&console.log(`Model.unsubscribe(${e}:${s}", ${t} ${(""+i).replace(/\([\s\S]*/,"")})`),this.vm.removeSubscription(t,e,s,i)}unsubscribeAll(t){Mt.subscribe&&console.log(`Model.unsubscribeAll(${t} ${t.id})`),this.vm.removeAllSubscriptionsFor(t)}future(t,e,s,i){if(Ht&&Ht.equal(this))return this.vm.future(t,e,s,i);throw Error(`Model.future() called from outside: ${t}`)}cancelFuture(t,e){if(Ht&&Ht.equal(this))return this.vm.cancelFuture(t,e);throw Error(`Model.cancelFuture() called from outside: ${t}`)}random(){return this.vm.random()}now(){return this.vm.time}equal(t){return t instanceof It&&t.vm===this.vm}isViewRealm(){return!1}}class Kt{constructor(t){this.vm=t}register(t){return Yt.register(t)}deregister(t){Yt.deregister(t)}publish(t,e,s){this.vm.publishFromView(s,t,e)}subscribe(t,e,s,i){let n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"queued";Mt.subscribe&&console.log(`View.subscribe("${i}:${t}", ${e} ${s?s.name||(""+s).replace(/\([\s\S]*/,""):""+s} [${n}])`),Yt.addSubscription(i,t,e,s,n)}unsubscribe(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,i=arguments.length>3?arguments[3]:void 0;Mt.subscribe&&console.log(`View.unsubscribe("${i}:${t}", ${e} ${s?s.name||(""+s).replace(/\([\s\S]*/,""):"*"})`),Yt.removeSubscription(i,t,e,s)}unsubscribeAll(t){Mt.subscribe&&console.log(`View.unsubscribeAll(${t})`),Yt.removeAllSubscriptionsFor(t)}future(t,e){const s=this.vm;return new Proxy(t,{get(i,n){if("function"==typeof t[n]){return new Proxy(t[n],{apply(i,o,r){setTimeout((()=>{t.id&&Ft(s,(()=>t[n](...r)),!0)}),e)}})}throw Error("Tried to call "+n+"() on future of "+Object.getPrototypeOf(t).constructor.name+" which is not a function")}})}random(){return Math.random()}now(){return this.vm.time}externalNow(){return this.vm.controller.reflectorTime}extrapolatedNow(){return this.vm.controller.extrapolatedTime}isSynced(){return!!this.vm.controller.synced}equal(t){return t instanceof Kt&&t.vm===this.vm}isViewRealm(){return!0}}let Ht=null;function zt(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"Tried to execute code that requires realm outside of realm.";if(!Ht&&t)throw Error(t);return Ht}function Nt(t,e){if(null!==Ht)throw Error("Can't switch realms from inside realm");try{return Ht=new It(t),e()}finally{Ht=null}}function Ft(t,e){let s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(null!==Ht&&!s)throw Error("Can't switch realms from inside realm");const i=Ht;try{return Ht=new Kt(t),e()}finally{Ht=i}}var _t=function(t){return t!=t},jt=Math.sqrt,Qt=.7853981633974483;var Et=function(t){var e,s;return 0===t?.16666666666666713:((t<0?-t:t)<=1?(e=t*(19.562619833175948+t*(t*(5.444622390564711+t*(.004253011369004428*t-.6019598008014124))-16.262479672107002))-8.198089802484825,s=t*(139.51056146574857+t*(t*(70.49610280856842+t*(1*t-14.740913729888538))-147.1791292232726))-49.18853881490881):(e=.004253011369004428+(t=1/t)*(t*(5.444622390564711+t*(t*(19.562619833175948+-8.198089802484825*t)-16.262479672107002))-.6019598008014124),s=1+t*(t*(70.49610280856842+t*(t*(139.51056146574857+-49.18853881490881*t)-147.1791292232726))-14.740913729888538)),e/s)};var Jt=function(t){var e,s;return 0===t?.08333333333333809:((t<0?-t:t)<=1?(e=28.536655482610616+t*(t*(6.968710824104713+t*(.002967721961301243*t-.5634242780008963))-25.56901049652825),s=342.43986579130785+t*(t*(147.0656354026815+t*(1*t-21.947795316429207))-383.8770957603691)):(e=.002967721961301243+(t=1/t)*(t*(6.968710824104713+t*(28.536655482610616*t-25.56901049652825))-.5634242780008963),s=1+t*(t*(147.0656354026815+t*(342.43986579130785*t-383.8770957603691))-21.947795316429207)),e/s)};var Ut=function(t){var e,s,i,n,o;if(_t(t))return NaN;if(t>0?i=t:(e=!0,i=-t),i>1)return NaN;if(i>.625)n=(s=1-i)*Jt(s),s=jt(s+s),o=Qt-s,o-=s=s*n-6123233995736766e-32,o+=Qt;else{if(i<1e-8)return t;o=i*(o=(s=i*i)*Et(s))+i}return e?-o:o};var Dt=function(t){var e;return _t(t)||t<-1||t>1?NaN:t>.5?2*Ut(jt(.5-.5*t)):(e=Qt-Ut(t),e+=6123233995736766e-32,e+=Qt)};var Ot=function(){return"function"==typeof Symbol&&"symbol"==typeof Symbol("foo")}();var Bt=function(){return Ot&&"symbol"==typeof Symbol.toStringTag},At=Object.prototype.toString;var $t=function(t){return At.call(t)},qt=Object.prototype.hasOwnProperty;var te=function(t,e){return null!=t&&qt.call(t,e)},ee="function"==typeof Symbol?Symbol.toStringTag:"";var se=function(t){var e,s,i;if(null==t)return At.call(t);s=t[ee],e=te(t,ee);try{t[ee]=void 0}catch(e){return At.call(t)}return i=At.call(t),e?t[ee]=s:delete t[ee],i},ie=Bt()?se:$t,ne="function"==typeof Uint32Array;var oe=function(t){return ne&&t instanceof Uint32Array||"[object Uint32Array]"===ie(t)},re="function"==typeof Uint32Array?Uint32Array:null;var ae=function(){var t,e;if("function"!=typeof re)return!1;try{e=new re(e=[1,3.14,-3.14,4294967296,4294967297]),t=oe(e)&&1===e[0]&&3===e[1]&&4294967293===e[2]&&0===e[3]&&1===e[4]}catch(e){t=!1}return t},le="function"==typeof Uint32Array?Uint32Array:null;var ce=function(){throw new Error("not implemented")},de=ae()?le:ce,he="function"==typeof Float64Array;var ue=function(t){return he&&t instanceof Float64Array||"[object Float64Array]"===ie(t)},me="function"==typeof Float64Array?Float64Array:null;var pe=function(){var t,e;if("function"!=typeof me)return!1;try{e=new me([1,3.14,-3.14,NaN]),t=ue(e)&&1===e[0]&&3.14===e[1]&&-3.14===e[2]&&e[3]!=e[3]}catch(e){t=!1}return t},fe="function"==typeof Float64Array?Float64Array:null;var be=function(){throw new Error("not implemented")},ye=pe()?fe:be,ge="function"==typeof Uint8Array;var we=function(t){return ge&&t instanceof Uint8Array||"[object Uint8Array]"===ie(t)},Ze="function"==typeof Uint8Array?Uint8Array:null;var Xe=function(){var t,e;if("function"!=typeof Ze)return!1;try{e=new Ze(e=[1,3.14,-3.14,256,257]),t=we(e)&&1===e[0]&&3===e[1]&&253===e[2]&&0===e[3]&&1===e[4]}catch(e){t=!1}return t},ve="function"==typeof Uint8Array?Uint8Array:null;var Le=function(){throw new Error("not implemented")},xe=Xe()?ve:Le,Ge="function"==typeof Uint16Array;var Se=function(t){return Ge&&t instanceof Uint16Array||"[object Uint16Array]"===ie(t)},ke="function"==typeof Uint16Array?Uint16Array:null;var We=function(){var t,e;if("function"!=typeof ke)return!1;try{e=new ke(e=[1,3.14,-3.14,65536,65537]),t=Se(e)&&1===e[0]&&3===e[1]&&65533===e[2]&&0===e[3]&&1===e[4]}catch(e){t=!1}return t},Te="function"==typeof Uint16Array?Uint16Array:null;var Ce,Ve=function(){throw new Error("not implemented")},Pe={uint16:We()?Te:Ve,uint8:xe};(Ce=new Pe.uint16(1))[0]=4660;var Re=52===new Pe.uint8(Ce.buffer)[0],Ye=!0===Re?1:0,Me=new ye(1),Ie=new de(Me.buffer);var Ke=function(t){return Me[0]=t,Ie[Ye]},He=!0===Re?1:0,ze=new ye(1),Ne=new de(ze.buffer);var Fe=function(t,e){return ze[0]=t,Ne[He]=e>>>0,ze[0]},_e=Fe,je=Number.POSITIVE_INFINITY,Qe=Number.NEGATIVE_INFINITY;var Ee=function(t){return 0===t?.6666666666666735:.6666666666666735+t*(.3999999999940942+t*(.2857142874366239+t*(.22222198432149784+t*(.1818357216161805+t*(.15313837699209373+.14798198605116586*t)))))},Je=.6931471803691238,Ue=1.9082149292705877e-10;var De=function(t){var e,s,i,n,o,r,a,l,c,d;if(t<-1||_t(t))return NaN;if(-1===t)return Qe;if(t===je)return t;if(0===t)return t;if(d=1,(i=t<0?-t:t)<.41421356237309503){if(i<1.862645149230957e-9)return i<5551115123125783e-32?t:t-t*t*.5;t>-.2928932188134525&&(d=0,n=t,s=1)}return 0!==d&&(i<9007199254740992?(o=(d=((s=Ke(c=1+t))>>20)-1023)>0?1-(c-t):t-(c-1),o/=c):(d=((s=Ke(c=t))>>20)-1023,o=0),(s&=1048575)<434334?c=_e(c,1072693248|s):(d+=1,c=_e(c,1071644672|s),s=1048576-s>>2),n=c-1),e=.5*n*n,0===s?0===n?d*Je+(o+=d*Ue):d*Je-((l=e*(1-.6666666666666666*n))-(d*Ue+o)-n):(l=(a=(r=n/(2+n))*r)*Ee(a),0===d?n-(e-r*(e+l)):d*Je-(e-(r*(e+l)+(d*Ue+o))-n))},Oe=.6931471805599453;var Be=function(t){return 0===t?.3999999999940942:.3999999999940942+t*(.22222198432149784+.15313837699209373*t)};var Ae=function(t){return 0===t?.6666666666666735:.6666666666666735+t*(.2857142874366239+t*(.1818357216161805+.14798198605116586*t))},$e=.6931471803691238,qe=1.9082149292705877e-10;var ts=function(t){var e,s,i,n,o,r,a,l,c,d,h;return 0===t?Qe:_t(t)||t<0?NaN:(n=0,(s=Ke(t))<1048576&&(n-=54,s=Ke(t*=0x40000000000000)),s>=2146435072?t+t:(n+=(s>>20)-1023|0,n+=(a=(s&=1048575)+614244&1048576|0)>>20|0,r=(t=_e(t,s|1072693248^a))-1,(1048575&2+s)<3?0===r?0===n?0:n*$e+n*qe:(o=r*r*(.5-.3333333333333333*r),0===n?r-o:n*$e-(o-n*qe-r)):(a=s-398458|0,l=440401-s|0,i=(d=(h=(c=r/(2+r))*c)*h)*Be(d),o=h*Ae(d)+i,(a|=l)>0?(e=.5*r*r,0===n?r-(e-c*(e+o)):n*$e-(e-(c*(e+o)+n*qe)-r)):0===n?r-c*(r-o):n*$e-(c*(r-o)-n*qe-r))))};var es=function(t){var e;return _t(t)||t<1?NaN:1===t?0:t>=268435456?ts(t)+Oe:t>2?ts(2*t-1/(t+jt(t*t-1))):De((e=t-1)+jt(2*e+e*e))};var ss=function(t){return t===je||t===Qe};var is=function(t){var e,s,i;return _t(t)||ss(t)?t:(t<0&&(t=-t,e=!0),i=t<3.725290298461914e-9?t:t>268435456?ts(t)+Oe:t>2?ts(2*t+1/(jt(t*t+1)+t)):De(t+(s=t*t)/(1+jt(1+s))),e?-i:i)},ns=1.5707963267948966;var os=function(t){return 0===t?-64.85021904942025:t*(t*(t*(-.8750608600031904*t-16.157537187333652)-75.00855792314705)-122.88666844901361)-64.85021904942025};var rs=function(t){return 0===t?194.5506571482614:194.5506571482614+t*(485.3903996359137+t*(432.88106049129027+t*(165.02700983169885+t*(24.858464901423062+1*t))))};var as=function(t){var e,s,i,n;return _t(t)||0===t?t:t===je?ns:t===Qe?-ns:(t<0&&(s=!0,t=-t),e=0,t>2.414213562373095?(i=ns,e=1,t=-1/t):t<=.66?i=0:(i=Qt,e=2,t=(t-1)/(t+1)),n=t*(n=(n=t*t)*os(n)/rs(n))+t,2===e?n+=3061616997868383e-32:1===e&&(n+=6123233995736766e-32),i+=n,s?-i:i)};var ls,cs,ds=function(t){var e,s;return _t(t)||t<-1||t>1?NaN:1===t?je:-1===t?Qe:(t<0&&(e=!0,t=-t),t<3.725290298461914e-9?e?-t:t:(s=t<.5?.5*De((s=t+t)+s*t/(1-t)):.5*De((t+t)/(1-t)),e?-s:s))};!0===Re?(ls=1,cs=0):(ls=0,cs=1);var hs={HIGH:ls,LOW:cs},us=new ye(1),ms=new de(us.buffer),ps=hs.HIGH,fs=hs.LOW;var bs=function(t,e){return us[0]=e,t[0]=ms[ps],t[1]=ms[fs],t};var ys,gs,ws=function(t,e){return 1===arguments.length?bs([0,0],t):bs(t,e)};!0===Re?(ys=1,gs=0):(ys=0,gs=1);var Zs={HIGH:ys,LOW:gs},Xs=new ye(1),vs=new de(Xs.buffer),Ls=Zs.HIGH,xs=Zs.LOW;var Gs=function(t,e){return vs[Ls]=t,vs[xs]=e,Xs[0]},Ss=Gs,ks=[0,0];var Ws=function(t,e){var s,i;return ws(ks,t),s=ks[0],s&=2147483647,i=Ke(e),Ss(s|=i&=2147483648,ks[1])};var Ts=function(t){return!!(Ke(t)>>>31)},Cs=3.141592653589793;var Vs=function(t,e){var s;return _t(e)||_t(t)?NaN:ss(e)?e===je?ss(t)?Ws(Cs/4,t):Ws(0,t):ss(t)?Ws(3*Cs/4,t):Ws(Cs,t):ss(t)?Ws(Cs/2,t):0===t?e>=0&&!Ts(e)?Ws(0,t):Ws(Cs,t):0===e?Ws(Cs/2,t):(s=as(t/e),e<0?s<=0?s+Cs:s-Cs:s)},Ps=22250738585072014e-324;var Rs=function(t){return 0===t?1.87595182427177:1.87595182427177+t*(t*(1.6214297201053545+t*(.14599619288661245*t-.758397934778766))-1.8849797954337717)};var Ys=function(t){var e,s,i,n,o;return _t(t)||ss(t)||0===t?t:(s=-2147483648&(i=Ke(t)),i&=2147483647,o=0,t>>20)-1023|0},Bs=Os,As=[0,0],$s=[0,0];var qs=function(t,e){var s,i;return 0===t||_t(t)||ss(t)?t:(Ds(As,t),e+=As[1],(e+=Bs(t=As[0]))<-1074?Ws(0,t):e>1023?t<0?Qe:je:(e<=-1023?(e+=52,i=2220446049250313e-31):i=1,ws($s,t),s=$s[0],s&=2148532223,i*Ss(s|=e+1023<<20,$s[1])))},ti=qs,ei=[10680707,7228996,1387004,2578385,16069853,12639074,9804092,4427841,16666979,11263675,12935607,2387514,4345298,14681673,3074569,13734428,16653803,1880361,10960616,8533493,3062596,8710556,7349940,6258241,3772886,3769171,3798172,8675211,12450088,3874808,9961438,366607,15675153,9132554,7151469,3571407,2607881,12013382,4155038,6285869,7677882,13102053,15825725,473591,9065106,15363067,6271263,9264392,5636912,4652155,7056368,13614112,10155062,1944035,9527646,15080200,6658437,6231200,6832269,16767104,5075751,3212806,1398474,7579849,6349435,12618859],si=[1.570796251296997,7.549789415861596e-8,5390302529957765e-30,3282003415807913e-37,1270655753080676e-44,12293330898111133e-52,27337005381646456e-60,21674168387780482e-67],ii=5.960464477539063e-8,ni=li(new Array(20)),oi=li(new Array(20)),ri=li(new Array(20)),ai=li(new Array(20));function li(t){var e,s=t.length;for(e=0;e0;m++)d=ii*y|0,ai[m]=y-16777216*d|0,y=i[b-1]+d,b-=1;if(y=ti(y,n),y-=8*Es(.125*y),y-=f=0|y,h=0,n>0?(f+=m=ai[s-1]>>24-n,ai[s-1]-=m<<24-n,h=ai[s-1]>>23-n):0===n?h=ai[s-1]>>23:y>=.5&&(h=2),h>0){for(f+=1,c=0,m=0;m0)switch(n){case 1:ai[s-1]&=8388607;break;case 2:ai[s-1]&=4194303}2===h&&(y=1-y,0!==c&&(y-=ti(1,n)))}if(0===y){for(b=0,m=s-1;m>=o;m--)b|=ai[m];if(0===b){for(p=1;0===ai[o-p];p++);for(m=s+1;m<=s+p;m++){for(l[a+m]=ei[r+m],d=0,b=0;b<=a;b++)d+=t[b]*l[a+(m-b)];i[m]=d}return ci(t,e,s+=p,i,n,o,r,a,l)}}if(0===y)for(s-=1,n-=24;0===ai[s];)s-=1,n-=24;else(y=ti(y,-n))>=16777216?(d=ii*y|0,ai[s]=y-16777216*d|0,n+=24,ai[s+=1]=d):ai[s]=0|y;for(d=ti(1,n),m=s;m>=0;m--)i[m]=d*ai[m],d*=ii;for(m=s;m>=0;m--){for(d=0,p=0;p<=u&&p<=s-m;p++)d+=si[p]*i[m+p];ri[s-m]=d}for(d=0,m=s;m>=0;m--)d+=ri[m];for(e[0]=0===h?d:-d,d=ri[0]-d,m=1;m<=s;m++)d+=ri[m];return e[1]=0===h?d:-d,7&f}var di=function(t,e,s,i){var n,o,r,a,l,c,d;for(4,(o=(s-3)/24|0)<0&&(o=0),a=s-24*(o+1),c=o-(r=i-1),d=r+4,l=0;l<=d;l++)ni[l]=c<0?0:ei[c],c+=1;for(l=0;l<=4;l++){for(n=0,c=0;c<=r;c++)n+=t[c]*ni[r+(l-c)];oi[l]=n}return 4,ci(t,e,4,oi,a,4,o,r,ni)},hi=Math.round;var ui=function(t,e,s){var i,n,o,r,a;return o=t-1.5707963267341256*(i=hi(.6366197723675814*t)),r=6077100506506192e-26*i,a=e>>20|0,s[0]=o-r,a-(Ke(s[0])>>20&2047)>16&&(r=20222662487959506e-37*i-((n=o)-(o=n-(r=6077100506303966e-26*i))-r),s[0]=o-r,a-(Ke(s[0])>>20&2047)>49&&(r=84784276603689e-45*i-((n=o)-(o=n-(r=20222662487111665e-37*i))-r),s[0]=o-r)),s[1]=o-s[0]-r,i},mi=1.5707963267341256,pi=6077100506506192e-26,fi=2*pi,bi=4*pi,yi=new Array(3),gi=new Array(2);var wi=function(t,e){var s,i,n,o,r,a,l;if((n=2147483647&Ke(t)|0)<=1072243195)return e[0]=t,e[1]=0,0;if(n<=1074752122)return 598523==(1048575&n)?ui(t,n,e):n<=1073928572?t>0?(l=t-mi,e[0]=l-pi,e[1]=l-e[0]-pi,1):(l=t+mi,e[0]=l+pi,e[1]=l-e[0]+pi,-1):t>0?(l=t-2*mi,e[0]=l-fi,e[1]=l-e[0]-fi,2):(l=t+2*mi,e[0]=l+fi,e[1]=l-e[0]+fi,-2);if(n<=1075594811)return n<=1075183036?1074977148===n?ui(t,n,e):t>0?(l=t-3*mi,e[0]=l-1.8231301519518578e-10,e[1]=l-e[0]-1.8231301519518578e-10,3):(l=t+3*mi,e[0]=l+1.8231301519518578e-10,e[1]=l-e[0]+1.8231301519518578e-10,-3):1075388923===n?ui(t,n,e):t>0?(l=t-4*mi,e[0]=l-bi,e[1]=l-e[0]-bi,4):(l=t+4*mi,e[0]=l+bi,e[1]=l-e[0]+bi,-4);if(n<1094263291)return ui(t,n,e);if(n>=2146435072)return e[0]=NaN,e[1]=NaN,0;for(s=Qs(t),l=Ss(n-((i=(n>>20)-1046)<<20|0),s),r=0;r<2;r++)yi[r]=0|l,l=16777216*(l-yi[r]);for(yi[2]=l,o=3;0===yi[o-1];)o-=1;return a=di(yi,gi,i,o),t<0?(e[0]=-gi[0],e[1]=-gi[1],-a):(e[0]=gi[0],e[1]=gi[1],a)},Zi=wi,Xi=[0,0];var vi=function(t){var e;if(e=Ke(t),(e&=2147483647)<=1072243195)return e<1044381696?1:Hs(t,0);if(e>=2146435072)return NaN;switch(3&Zi(t,Xi)){case 0:return Hs(Xi[0],Xi[1]);case 1:return-Ns(Xi[0],Xi[1]);case 2:return-Hs(Xi[0],Xi[1]);default:return Ns(Xi[0],Xi[1])}},Li=Math.ceil;var xi=function(t){return t<0?Li(t):Es(t)};var Gi=function(t){return 0===t?.16666666666666602:.16666666666666602+t*(t*(6613756321437934e-20+t*(4.1381367970572385e-8*t-16533902205465252e-22))-.0027777777777015593)};var Si=function(t,e,s){var i,n,o;return o=(i=t-e)-(n=i*i)*Gi(n),ti(1-(e-i*o/(2-o)-t),s)};var ki=function(t){var e;return _t(t)||t===je?t:t===Qe?0:t>709.782712893384?je:t<-745.1332191019411?0:t>-3.725290298461914e-9&&t<3.725290298461914e-9?1+t:(e=xi(t<0?1.4426950408889634*t-.5:1.4426950408889634*t+.5),Si(t-.6931471803691238*e,1.9082149292705877e-10*e,e))};var Wi=function(t){return _t(t)?t:(t<0&&(t=-t),t>21?ki(t)/2:(ki(t)+ki(-t))/2)};var Ti=function(t){return 0===t?-.03333333333333313:t*(.0015873015872548146+t*(t*(4008217827329362e-21+-2.0109921818362437e-7*t)-793650757867488e-19))-.03333333333333313},Ci=.6931471803691238,Vi=1.9082149292705877e-10;var Pi=function(t){var e,s,i,n,o,r,a,l,c,d,h,u;if(t===je||_t(t))return t;if(t===Qe)return-1;if(0===t)return t;if(t<0?(s=!0,a=-t):(s=!1,a=t),a>=38.816242111356935){if(s)return-1;if(a>=709.782712893384)return je}if(o=0|Ke(a),a>.34657359027997264)a<1.0397207708399179?s?(i=t+Ci,n=-Vi,u=-1):(i=t-Ci,n=Vi,u=1):(u=s?1.4426950408889634*t-.5:1.4426950408889634*t+.5,i=t-(d=u|=0)*Ci,n=d*Vi),c=i-(t=i-n)-n;else{if(o<1016070144)return t;u=0}return h=(l=t*(e=.5*t))*(((r=1+l*Ti(l))-(d=3-r*e))/(6-t*d)),0===u?t-(t*h-l):(h=t*(h-c)-c,h-=l,-1===u?.5*(t-h)-.5:1===u?t<-.25?-2*(h-(t+.5)):1+2*(t-h):u<=-2||u>56?(i=Ke(a=1-(h-t))+(u<<20)|0,(a=_e(a,i))-1):(d=1,u<20?a=(d=_e(d,i=1072693248-(2097152>>u)|0))-(h-t):(a=t-(h+(d=_e(d,i=1023-u<<20|0))),a+=1),i=Ke(a)+(u<<20)|0,_e(a,i)))},Ri=!0===Re?0:1,Yi=new ye(1),Mi=new de(Yi.buffer);var Ii=function(t,e){return Yi[0]=t,Mi[Ri]=e>>>0,Yi[0]},Ki=Ii;var Hi=function(t){return 0===t?.3999999999940942:.3999999999940942+t*(.22222198432149784+.15313837699209373*t)};var zi=function(t){return 0===t?.6666666666666735:.6666666666666735+t*(.2857142874366239+t*(.1818357216161805+.14798198605116586*t))};var Ni=function(t){var e,s,i,n,o,r,a,l,c,d;return n=t-1,(1048575&2+(i=Ke(t)))<3?0===n?0:n*n*(.3333333333333333*n-.5):(c=(i&=1048575)-398458|0,d=440401-i|0,s=(l=(r=(o=n/(2+n))*o)*r)*Hi(l),a=r*zi(l)+s,(c|=d)>0?o*((e=.5*n*n)+a)-e:o*(a-n))};var Fi=function(t){var e,s,i,n,o,r,a;return _t(t)||t<0?NaN:0===t?Qe:(o=0,(s=Ke(t))<1048576&&(o-=54,s=Ke(t*=0x40000000000000)),s>=2146435072?t+t:(o+=(s>>20)-1023|0,t=_e(t,(s&=1048575)|1072693248^(n=s+614244&1048576|0)),r=o+=n>>20|0,i=Ni(t),a=3694239077158931e-28*r+25082946711645275e-27*((t-=1)+i),(a+=.4342944818781689*(t-(e=Ki(t,0))+i)+.4342944818781689*e)+.30102999566361177*r))};var _i=function(t){return 0===t?.3999999999940942:.3999999999940942+t*(.22222198432149784+.15313837699209373*t)};var ji=function(t){return 0===t?.6666666666666735:.6666666666666735+t*(.2857142874366239+t*(.1818357216161805+.14798198605116586*t))};var Qi=function(t){var e,s,i,n,o,r,a,l,c,d;return n=t-1,(1048575&2+(i=Ke(t)))<3?0===n?0:n*n*(.3333333333333333*n-.5):(c=(i&=1048575)-398458|0,d=440401-i|0,s=(l=(r=(o=n/(2+n))*o)*r)*_i(l),a=r*ji(l)+s,(c|=d)>0?o*((e=.5*n*n)+a)-e:o*(a-n))},Ei=[0,0];var Ji=function(t){var e,s,i,n,o;if(_t(t)||t<0)return NaN;if(ws(Ei,t),o=0,(s=Ei[0])<1048576){if(0==(2147483647&s|Ei[1]))return Qe;o-=54,s=Ke(t*=0x40000000000000)}return s>=2146435072?t+t:(o+=(s>>20)-1023|0,t=_e(t,(s&=1048575)|1072693248^(n=s+614244&1048576|0)),o+=n>>20|0,i=Qi(t),1.6751713164886512e-10*((t-=1)+i)+1.4426950407214463*(t-(e=Ki(t,0))+i)+1.4426950407214463*e+o)},Ui=[0,0];var Di=function(t){var e;if(e=Ke(t),(e&=2147483647)<=1072243195)return e<1045430272?t:Ns(t,0);if(e>=2146435072)return NaN;switch(3&Zi(t,Ui)){case 0:return Ns(Ui[0],Ui[1]);case 1:return Hs(Ui[0],Ui[1]);case 2:return-Ns(Ui[0],Ui[1]);default:return-Hs(Ui[0],Ui[1])}};var Oi=function(t){var e,s;return 0===t?.16666666666666666:((t<0?-t:t)<=1?(e=t*(t*(-.789474443963537*t-163.72585752598383)-11561.443576500522)-351754.9648081514,s=t*(36157.827983443196+t*(1*t-277.7110814206028))-2110529.7888489086):(e=(t=1/t)*(t*(-351754.9648081514*t-11561.443576500522)-163.72585752598383)-.789474443963537,s=1+t*(t*(36157.827983443196+-2110529.7888489086*t)-277.7110814206028)),e/s)};var Bi=function(t){var e;return 0===t?t:(e=Js(t),t>710.4758600739439||t<-709.089565712824?t>0?je:Qe:e>1?e>=709.0895657128241?(e=ki(.5*e),e*=.5*e,t<0&&(e=-e),e):(e=.5*(e=ki(e))-.5/e,t<0&&(e=-e),e):t+t*(e*=e)*Oi(e))};var Ai=function(t){return 0===t?.13333333333320124:.13333333333320124+t*(.021869488294859542+t*(.0035920791075913124+t*(.0005880412408202641+t*(7817944429395571e-20+-18558637485527546e-21*t))))};var $i=function(t){return 0===t?.05396825397622605:.05396825397622605+t*(.0088632398235993+t*(.0014562094543252903+t*(.0002464631348184699+t*(7140724913826082e-20+2590730518636337e-20*t))))};var qi=function(t,e,s){var i,n,o,r,a,l,c,d,h;return(n=2147483647&(i=Ke(t))|0)>=1072010280&&(t<0&&(t=-t,e=-e),t=(h=.7853981633974483-t)+(d=3061616997868383e-32-e),e=0),r=e+(h=t*t)*((a=h*t)*((r=Ai(d=h*h))+(c=h*$i(d)))+e),d=t+(r+=.3333333333333341*a),n>=1072010280?(1-(i>>30&2))*((c=s)-2*(t-(d*d/(d+c)-r))):1===s?d:(Ki(h=d,0),c=r-(h-t),Ki(l=o=-1/d,0),l+o*((a=1+l*h)+l*c))},tn=[0,0];var en=function(t){var e,s;return e=Ke(t),(e&=2147483647)<=1072243195?e<1044381696?t:qi(t,0,1):e>=2146435072?NaN:(s=Zi(t,tn),qi(tn[0],tn[1],1-((1&s)<<1)))};var sn=function(t){var e,s;return 0===t?-.3333333333333332:((t<0?-t:t)<=1?(e=t*(t*(0*t-.9643991794250523)-99.28772310019185)-1614.6876844170845,s=4844.063053251255+t*(2235.4883906010045+t*(112.81167849163293+1*t))):(e=0+(t=1/t)*(t*(-1614.6876844170845*t-99.28772310019185)-.9643991794250523),s=1+t*(112.81167849163293+t*(2235.4883906010045+4844.063053251255*t))),e/s)};var nn=function(t){var e,s;if((s=Js(t))>44.014845965556525)return t<0?-1:1;if(s>=.625)s=1-2/((e=ki(2*s))+1),t<0&&(s=-s);else{if(0===t)return t;s=t+t*(e=t*t)*sn(e)}return s};void 0===globalThis.CroquetMath&&(globalThis.CroquetMath={}),Object.assign(globalThis.CroquetMath,{acos:Dt,acosh:es,asin:Ut,asinh:is,atan:as,atanh:ds,atan2:Vs,cbrt:Ms,cos:vi,cosh:Wi,exp:ki,expm1:Pi,log:ts,log1p:De,log10:Fi,log2:Ji,sin:Di,sinh:Bi,tan:en,tanh:nn});const on=Math.pow;function rn(t){return t===1/0||t===-1/0}globalThis.CroquetMath.pow=(t,e)=>{if(isNaN(t)||isNaN(e))return NaN;if(rn(t)||rn(e))return on(t,e);if(0===t||0===e)return on(t,e);if(t<0&&!function(t){return Number.isInteger(t)}(e))return NaN;if(1===e)return t;if(2===e)return t*t;if(3===e)return t*t*t;if(4===e)return t*t*t*t;let s=1;t<0&&(t*=-1,s=on(-1,e));return globalThis.CroquetMath.exp(globalThis.CroquetMath.log(t)*e)*s};var an=function(t,e){return t0&&(e=i-1>>1,s=this.array[e],this.compare(t,s));)this.array[i]=s,i=e;this.array[i]=t},ln.prototype.heapify=function(t){var e;for(this.array=t,this.size=t.length,e=this.size>>1;e>=0;e--)this._percolateDown(e)},ln.prototype._percolateUp=function(t,e){for(var s,i,n=this.array[t];t>0&&(s=t-1>>1,i=this.array[s],e||this.compare(n,i));)this.array[t]=i,t=s;this.array[t]=n},ln.prototype._percolateDown=function(t){for(var e,s,i,n=this.size,o=this.size>>>1,r=this.array[t];tthis.size-1||t<0))return this._percolateUp(t,!0),this.poll()},ln.prototype.remove=function(t){for(var e=0;e1?(this.array[0]=this.array[--this.size],this._percolateDown(0)):this.size-=1,t}},ln.prototype.replaceTop=function(t){if(0!=this.size){var e=this.array[0];return this.array[0]=t,this._percolateDown(0),e}},ln.prototype.trim=function(){this.array=this.array.slice(0,this.size)},ln.prototype.isEmpty=function(){return 0===this.size},ln.prototype.forEach=function(t){if(!this.isEmpty()&&"function"==typeof t)for(var e=0,s=this.clone();!s.isEmpty();)t(s.poll(),e++)},ln.prototype.kSmallest=function(t){if(0==this.size)return[];t=Math.min(this.size,t);var e=new ln(this.compare);const s=Math.min((t>0?Math.pow(2,t-1):0)+1,this.size);e.size=s,e.array=this.array.slice(0,s);for(var i=new Array(t),n=0;nt.push(e))),t}asUnsortedArray(){return this.array.slice(0,this.size)}}var hn={exports:{}},un=hn.exports=function(t){return function(){var e=t,s=e.lib.WordArray;function i(t,e,i){for(var n=[],o=0,r=0;r>>6-r%4*2;n[o>>>2]|=a<<24-o%4*8,o++}return s.create(n,o)}e.enc.Base64={stringify:function(t){var e=t.words,s=t.sigBytes,i=this._map;t.clamp();for(var n=[],o=0;o>>2]>>>24-o%4*8&255)<<16|(e[o+1>>>2]>>>24-(o+1)%4*8&255)<<8|e[o+2>>>2]>>>24-(o+2)%4*8&255,a=0;a<4&&o+.75*a>>6*(3-a)&63));var l=i.charAt(64);if(l)for(;n.length%4;)n.push(l);return n.join("")},parse:function(t){var e=t.length,s=this._map,n=this._reverseMap;if(!n){n=this._reverseMap=[];for(var o=0;o>>31}var h=(i<<5|i>>>27)+l+r[c];h+=c<20?1518500249+(n&o|~n&a):c<40?1859775393+(n^o^a):c<60?(n&o|n&a|o&a)-1894007588:(n^o^a)-899497514,l=a,a=o,o=n<<30|n>>>2,n=i,i=h}s[0]=s[0]+i|0,s[1]=s[1]+n|0,s[2]=s[2]+o|0,s[3]=s[3]+a|0,s[4]=s[4]+l|0},_doFinalize:function(){var t=this._data,e=t.words,s=8*this._nDataBytes,i=8*t.sigBytes;return e[i>>>5]|=128<<24-i%32,e[14+(i+64>>>9<<4)]=Math.floor(s/4294967296),e[15+(i+64>>>9<<4)]=s,t.sigBytes=4*e.length,this._process(),this._hash},clone:function(){var t=n.clone.call(this);return t._hash=this._hash.clone(),t}});e.SHA1=n._createHelper(a),e.HmacSHA1=n._createHmacHelper(a)}(),t.SHA1}(w.exports);var yn={exports:{}};yn.exports=function(t){!function(){var e=t,s=e.lib.Base,i=e.enc.Utf8;e.algo.HMAC=s.extend({init:function(t,e){t=this._hasher=new t.init,"string"==typeof e&&(e=i.parse(e));var s=t.blockSize,n=4*s;e.sigBytes>n&&(e=t.finalize(e)),e.clamp();for(var o=this._oKey=e.clone(),r=this._iKey=e.clone(),a=o.words,l=r.words,c=0;c>>24)|4278255360&(n<<24|n>>>8)}var o=this._hash.words,r=t[e+0],l=t[e+1],m=t[e+2],p=t[e+3],f=t[e+4],b=t[e+5],y=t[e+6],g=t[e+7],w=t[e+8],Z=t[e+9],X=t[e+10],v=t[e+11],L=t[e+12],x=t[e+13],G=t[e+14],S=t[e+15],k=o[0],W=o[1],T=o[2],C=o[3];k=c(k,W,T,C,r,7,a[0]),C=c(C,k,W,T,l,12,a[1]),T=c(T,C,k,W,m,17,a[2]),W=c(W,T,C,k,p,22,a[3]),k=c(k,W,T,C,f,7,a[4]),C=c(C,k,W,T,b,12,a[5]),T=c(T,C,k,W,y,17,a[6]),W=c(W,T,C,k,g,22,a[7]),k=c(k,W,T,C,w,7,a[8]),C=c(C,k,W,T,Z,12,a[9]),T=c(T,C,k,W,X,17,a[10]),W=c(W,T,C,k,v,22,a[11]),k=c(k,W,T,C,L,7,a[12]),C=c(C,k,W,T,x,12,a[13]),T=c(T,C,k,W,G,17,a[14]),k=d(k,W=c(W,T,C,k,S,22,a[15]),T,C,l,5,a[16]),C=d(C,k,W,T,y,9,a[17]),T=d(T,C,k,W,v,14,a[18]),W=d(W,T,C,k,r,20,a[19]),k=d(k,W,T,C,b,5,a[20]),C=d(C,k,W,T,X,9,a[21]),T=d(T,C,k,W,S,14,a[22]),W=d(W,T,C,k,f,20,a[23]),k=d(k,W,T,C,Z,5,a[24]),C=d(C,k,W,T,G,9,a[25]),T=d(T,C,k,W,p,14,a[26]),W=d(W,T,C,k,w,20,a[27]),k=d(k,W,T,C,x,5,a[28]),C=d(C,k,W,T,m,9,a[29]),T=d(T,C,k,W,g,14,a[30]),k=h(k,W=d(W,T,C,k,L,20,a[31]),T,C,b,4,a[32]),C=h(C,k,W,T,w,11,a[33]),T=h(T,C,k,W,v,16,a[34]),W=h(W,T,C,k,G,23,a[35]),k=h(k,W,T,C,l,4,a[36]),C=h(C,k,W,T,f,11,a[37]),T=h(T,C,k,W,g,16,a[38]),W=h(W,T,C,k,X,23,a[39]),k=h(k,W,T,C,x,4,a[40]),C=h(C,k,W,T,r,11,a[41]),T=h(T,C,k,W,p,16,a[42]),W=h(W,T,C,k,y,23,a[43]),k=h(k,W,T,C,Z,4,a[44]),C=h(C,k,W,T,L,11,a[45]),T=h(T,C,k,W,S,16,a[46]),k=u(k,W=h(W,T,C,k,m,23,a[47]),T,C,r,6,a[48]),C=u(C,k,W,T,g,10,a[49]),T=u(T,C,k,W,G,15,a[50]),W=u(W,T,C,k,b,21,a[51]),k=u(k,W,T,C,L,6,a[52]),C=u(C,k,W,T,p,10,a[53]),T=u(T,C,k,W,X,15,a[54]),W=u(W,T,C,k,l,21,a[55]),k=u(k,W,T,C,w,6,a[56]),C=u(C,k,W,T,S,10,a[57]),T=u(T,C,k,W,y,15,a[58]),W=u(W,T,C,k,x,21,a[59]),k=u(k,W,T,C,f,6,a[60]),C=u(C,k,W,T,v,10,a[61]),T=u(T,C,k,W,m,15,a[62]),W=u(W,T,C,k,Z,21,a[63]),o[0]=o[0]+k|0,o[1]=o[1]+W|0,o[2]=o[2]+T|0,o[3]=o[3]+C|0},_doFinalize:function(){var t=this._data,s=t.words,i=8*this._nDataBytes,n=8*t.sigBytes;s[n>>>5]|=128<<24-n%32;var o=e.floor(i/4294967296),r=i;s[15+(n+64>>>9<<4)]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8),s[14+(n+64>>>9<<4)]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8),t.sigBytes=4*(s.length+1),this._process();for(var a=this._hash,l=a.words,c=0;c<4;c++){var d=l[c];l[c]=16711935&(d<<8|d>>>24)|4278255360&(d<<24|d>>>8)}return a},clone:function(){var t=o.clone.call(this);return t._hash=this._hash.clone(),t}});function c(t,e,s,i,n,o,r){var a=t+(e&s|~e&i)+n+r;return(a<>>32-o)+e}function d(t,e,s,i,n,o,r){var a=t+(e&i|s&~i)+n+r;return(a<>>32-o)+e}function h(t,e,s,i,n,o,r){var a=t+(e^s^i)+n+r;return(a<>>32-o)+e}function u(t,e,s,i,n,o,r){var a=t+(s^(e|~i))+n+r;return(a<>>32-o)+e}s.MD5=o._createHelper(l),s.HmacMD5=o._createHmacHelper(l)}(Math),t.MD5}(w.exports);var Xn={exports:{}};Xn.exports=function(t){return function(){var e=t,s=e.lib,i=s.Base,n=s.WordArray,o=e.algo,r=o.MD5,a=o.EvpKDF=i.extend({cfg:i.extend({keySize:4,hasher:r,iterations:1}),init:function(t){this.cfg=this.cfg.extend(t)},compute:function(t,e){for(var s,i=this.cfg,o=i.hasher.create(),r=n.create(),a=r.words,l=i.keySize,c=i.iterations;a.length>>2];t.sigBytes-=e}};i.BlockCipher=d.extend({cfg:d.cfg.extend({mode:m,padding:p}),reset:function(){var t;d.reset.call(this);var e=this.cfg,s=e.iv,i=e.mode;this._xformMode==this._ENC_XFORM_MODE?t=i.createEncryptor:(t=i.createDecryptor,this._minBufferSize=1),this._mode&&this._mode.__creator==t?this._mode.init(this,s&&s.words):(this._mode=t.call(i,this,s&&s.words),this._mode.__creator=t)},_doProcessBlock:function(t,e){this._mode.processBlock(t,e)},_doFinalize:function(){var t,e=this.cfg.padding;return this._xformMode==this._ENC_XFORM_MODE?(e.pad(this._data,this.blockSize),t=this._process(!0)):(t=this._process(!0),e.unpad(t)),t},blockSize:4});var f=i.CipherParams=n.extend({init:function(t){this.mixIn(t)},toString:function(t){return(t||this.formatter).stringify(this)}}),b=(s.format={}).OpenSSL={stringify:function(t){var e=t.ciphertext,s=t.salt;return(s?o.create([1398893684,1701076831]).concat(s).concat(e):e).toString(l)},parse:function(t){var e,s=l.parse(t),i=s.words;return 1398893684==i[0]&&1701076831==i[1]&&(e=o.create(i.slice(2,4)),i.splice(0,4),s.sigBytes-=16),f.create({ciphertext:s,salt:e})}},y=i.SerializableCipher=n.extend({cfg:n.extend({format:b}),encrypt:function(t,e,s,i){i=this.cfg.extend(i);var n=t.createEncryptor(s,i),o=n.finalize(e),r=n.cfg;return f.create({ciphertext:o,key:s,iv:r.iv,algorithm:t,mode:r.mode,padding:r.padding,blockSize:t.blockSize,formatter:i.format})},decrypt:function(t,e,s,i){return i=this.cfg.extend(i),e=this._parse(e,i.format),t.createDecryptor(s,i).finalize(e.ciphertext)},_parse:function(t,e){return"string"==typeof t?e.parse(t,this):t}}),g=(s.kdf={}).OpenSSL={execute:function(t,e,s,i){i||(i=o.random(8));var n=c.create({keySize:e+s}).compute(t,i),r=o.create(n.words.slice(e),4*s);return n.sigBytes=4*e,f.create({key:n,iv:r,salt:i})}},w=i.PasswordBasedCipher=y.extend({cfg:y.cfg.extend({kdf:g}),encrypt:function(t,e,s,i){var n=(i=this.cfg.extend(i)).kdf.execute(s,t.keySize,t.ivSize);i.iv=n.iv;var o=y.encrypt.call(this,t,e,n.key,i);return o.mixIn(n),o},decrypt:function(t,e,s,i){i=this.cfg.extend(i),e=this._parse(e,i.format);var n=i.kdf.execute(s,t.keySize,t.ivSize,e.salt);return i.iv=n.iv,y.decrypt.call(this,t,e,n.key,i)}})}()}(w.exports);var Ln=wn.exports=function(t){return function(){var e=t,s=e.lib.BlockCipher,i=e.algo,n=[],o=[],r=[],a=[],l=[],c=[],d=[],h=[],u=[],m=[];!function(){for(var t=[],e=0;e<256;e++)t[e]=e<128?e<<1:e<<1^283;var s=0,i=0;for(e=0;e<256;e++){var p=i^i<<1^i<<2^i<<3^i<<4;p=p>>>8^255&p^99,n[s]=p,o[p]=s;var f=t[s],b=t[f],y=t[b],g=257*t[p]^16843008*p;r[s]=g<<24|g>>>8,a[s]=g<<16|g>>>16,l[s]=g<<8|g>>>24,c[s]=g,g=16843009*y^65537*b^257*f^16843008*s,d[p]=g<<24|g>>>8,h[p]=g<<16|g>>>16,u[p]=g<<8|g>>>24,m[p]=g,s?(s=f^t[t[t[y^f]]],i^=t[t[i]]):s=i=1}}();var p=[0,1,2,4,8,16,32,64,128,27,54],f=i.AES=s.extend({_doReset:function(){if(!this._nRounds||this._keyPriorReset!==this._key){for(var t=this._keyPriorReset=this._key,e=t.words,s=t.sigBytes/4,i=4*((this._nRounds=s+6)+1),o=this._keySchedule=[],r=0;r6&&r%s==4&&(c=n[c>>>24]<<24|n[c>>>16&255]<<16|n[c>>>8&255]<<8|n[255&c]):(c=n[(c=c<<8|c>>>24)>>>24]<<24|n[c>>>16&255]<<16|n[c>>>8&255]<<8|n[255&c],c^=p[r/s|0]<<24),o[r]=o[r-s]^c);for(var a=this._invKeySchedule=[],l=0;l>>24]]^h[n[c>>>16&255]]^u[n[c>>>8&255]]^m[n[255&c]]}}},encryptBlock:function(t,e){this._doCryptBlock(t,e,this._keySchedule,r,a,l,c,n)},decryptBlock:function(t,e){var s=t[e+1];t[e+1]=t[e+3],t[e+3]=s,this._doCryptBlock(t,e,this._invKeySchedule,d,h,u,m,o),s=t[e+1],t[e+1]=t[e+3],t[e+3]=s},_doCryptBlock:function(t,e,s,i,n,o,r,a){for(var l=this._nRounds,c=t[e]^s[0],d=t[e+1]^s[1],h=t[e+2]^s[2],u=t[e+3]^s[3],m=4,p=1;p>>24]^n[d>>>16&255]^o[h>>>8&255]^r[255&u]^s[m++],b=i[d>>>24]^n[h>>>16&255]^o[u>>>8&255]^r[255&c]^s[m++],y=i[h>>>24]^n[u>>>16&255]^o[c>>>8&255]^r[255&d]^s[m++],g=i[u>>>24]^n[c>>>16&255]^o[d>>>8&255]^r[255&h]^s[m++];c=f,d=b,h=y,u=g}f=(a[c>>>24]<<24|a[d>>>16&255]<<16|a[h>>>8&255]<<8|a[255&u])^s[m++],b=(a[d>>>24]<<24|a[h>>>16&255]<<16|a[u>>>8&255]<<8|a[255&c])^s[m++],y=(a[h>>>24]<<24|a[u>>>16&255]<<16|a[c>>>8&255]<<8|a[255&d])^s[m++],g=(a[u>>>24]<<24|a[c>>>16&255]<<16|a[d>>>8&255]<<8|a[255&h])^s[m++],t[e]=f,t[e+1]=b,t[e+2]=y,t[e+3]=g},keySize:8});e.AES=s._createHelper(f)}(),t.AES}(w.exports),xn={exports:{}},Gn=xn.exports=function(t){return t.HmacSHA256}(w.exports);function Sn(t){let e=t.length;for(;--e>=0;)t[e]=0}const kn=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]),Wn=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),Tn=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]),Cn=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Vn=new Array(576);Sn(Vn);const Pn=new Array(60);Sn(Pn);const Rn=new Array(512);Sn(Rn);const Yn=new Array(256);Sn(Yn);const Mn=new Array(29);Sn(Mn);const In=new Array(30);function Kn(t,e,s,i,n){this.static_tree=t,this.extra_bits=e,this.extra_base=s,this.elems=i,this.max_length=n,this.has_stree=t&&t.length}let Hn,zn,Nn;function Fn(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e}Sn(In);const _n=t=>t<256?Rn[t]:Rn[256+(t>>>7)],jn=(t,e)=>{t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255},Qn=(t,e,s)=>{t.bi_valid>16-s?(t.bi_buf|=e<>16-t.bi_valid,t.bi_valid+=s-16):(t.bi_buf|=e<{Qn(t,s[2*e],s[2*e+1])},Jn=(t,e)=>{let s=0;do{s|=1&t,t>>>=1,s<<=1}while(--e>0);return s>>>1},Un=(t,e,s)=>{const i=new Array(16);let n,o,r=0;for(n=1;n<=15;n++)i[n]=r=r+s[n-1]<<1;for(o=0;o<=e;o++){let e=t[2*o+1];0!==e&&(t[2*o]=Jn(i[e]++,e))}},Dn=t=>{let e;for(e=0;e<286;e++)t.dyn_ltree[2*e]=0;for(e=0;e<30;e++)t.dyn_dtree[2*e]=0;for(e=0;e<19;e++)t.bl_tree[2*e]=0;t.dyn_ltree[512]=1,t.opt_len=t.static_len=0,t.last_lit=t.matches=0},On=t=>{t.bi_valid>8?jn(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0},Bn=(t,e,s,i)=>{const n=2*e,o=2*s;return t[n]{const i=t.heap[s];let n=s<<1;for(;n<=t.heap_len&&(n{let i,n,o,r,a=0;if(0!==t.last_lit)do{i=t.pending_buf[t.d_buf+2*a]<<8|t.pending_buf[t.d_buf+2*a+1],n=t.pending_buf[t.l_buf+a],a++,0===i?En(t,n,e):(o=Yn[n],En(t,o+256+1,e),r=kn[o],0!==r&&(n-=Mn[o],Qn(t,n,r)),i--,o=_n(i),En(t,o,s),r=Wn[o],0!==r&&(i-=In[o],Qn(t,i,r)))}while(a{const s=e.dyn_tree,i=e.stat_desc.static_tree,n=e.stat_desc.has_stree,o=e.stat_desc.elems;let r,a,l,c=-1;for(t.heap_len=0,t.heap_max=573,r=0;r>1;r>=1;r--)An(t,s,r);l=o;do{r=t.heap[1],t.heap[1]=t.heap[t.heap_len--],An(t,s,1),a=t.heap[1],t.heap[--t.heap_max]=r,t.heap[--t.heap_max]=a,s[2*l]=s[2*r]+s[2*a],t.depth[l]=(t.depth[r]>=t.depth[a]?t.depth[r]:t.depth[a])+1,s[2*r+1]=s[2*a+1]=l,t.heap[1]=l++,An(t,s,1)}while(t.heap_len>=2);t.heap[--t.heap_max]=t.heap[1],((t,e)=>{const s=e.dyn_tree,i=e.max_code,n=e.stat_desc.static_tree,o=e.stat_desc.has_stree,r=e.stat_desc.extra_bits,a=e.stat_desc.extra_base,l=e.stat_desc.max_length;let c,d,h,u,m,p,f=0;for(u=0;u<=15;u++)t.bl_count[u]=0;for(s[2*t.heap[t.heap_max]+1]=0,c=t.heap_max+1;c<573;c++)d=t.heap[c],u=s[2*s[2*d+1]+1]+1,u>l&&(u=l,f++),s[2*d+1]=u,d>i||(t.bl_count[u]++,m=0,d>=a&&(m=r[d-a]),p=s[2*d],t.opt_len+=p*(u+m),o&&(t.static_len+=p*(n[2*d+1]+m)));if(0!==f){do{for(u=l-1;0===t.bl_count[u];)u--;t.bl_count[u]--,t.bl_count[u+1]+=2,t.bl_count[l]--,f-=2}while(f>0);for(u=l;0!==u;u--)for(d=t.bl_count[u];0!==d;)h=t.heap[--c],h>i||(s[2*h+1]!==u&&(t.opt_len+=(u-s[2*h+1])*s[2*h],s[2*h+1]=u),d--)}})(t,e),Un(s,c,t.bl_count)},to=(t,e,s)=>{let i,n,o=-1,r=e[1],a=0,l=7,c=4;for(0===r&&(l=138,c=3),e[2*(s+1)+1]=65535,i=0;i<=s;i++)n=r,r=e[2*(i+1)+1],++a{let i,n,o=-1,r=e[1],a=0,l=7,c=4;for(0===r&&(l=138,c=3),i=0;i<=s;i++)if(n=r,r=e[2*(i+1)+1],!(++a{Qn(t,0+(i?1:0),3),((t,e,s,i)=>{On(t),i&&(jn(t,s),jn(t,~s)),t.pending_buf.set(t.window.subarray(e,e+s),t.pending),t.pending+=s})(t,e,s,!0)};var no=(t,e,s,i)=>{let n,o,r=0;t.level>0?(2===t.strm.data_type&&(t.strm.data_type=(t=>{let e,s=4093624447;for(e=0;e<=31;e++,s>>>=1)if(1&s&&0!==t.dyn_ltree[2*e])return 0;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return 1;for(e=32;e<256;e++)if(0!==t.dyn_ltree[2*e])return 1;return 0})(t)),qn(t,t.l_desc),qn(t,t.d_desc),r=(t=>{let e;for(to(t,t.dyn_ltree,t.l_desc.max_code),to(t,t.dyn_dtree,t.d_desc.max_code),qn(t,t.bl_desc),e=18;e>=3&&0===t.bl_tree[2*Cn[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e})(t),n=t.opt_len+3+7>>>3,o=t.static_len+3+7>>>3,o<=n&&(n=o)):n=o=s+5,s+4<=n&&-1!==e?io(t,e,s,i):4===t.strategy||o===n?(Qn(t,2+(i?1:0),3),$n(t,Vn,Pn)):(Qn(t,4+(i?1:0),3),((t,e,s,i)=>{let n;for(Qn(t,e-257,5),Qn(t,s-1,5),Qn(t,i-4,4),n=0;n{so||((()=>{let t,e,s,i,n;const o=new Array(16);for(s=0,i=0;i<28;i++)for(Mn[i]=s,t=0;t<1<>=7;i<30;i++)for(In[i]=n<<7,t=0;t<1<(t.pending_buf[t.d_buf+2*t.last_lit]=e>>>8&255,t.pending_buf[t.d_buf+2*t.last_lit+1]=255&e,t.pending_buf[t.l_buf+t.last_lit]=255&s,t.last_lit++,0===e?t.dyn_ltree[2*s]++:(t.matches++,e--,t.dyn_ltree[2*(Yn[s]+256+1)]++,t.dyn_dtree[2*_n(e)]++),t.last_lit===t.lit_bufsize-1),_tr_align:t=>{Qn(t,2,3),En(t,256,Vn),(t=>{16===t.bi_valid?(jn(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):t.bi_valid>=8&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)})(t)}};var ro=(t,e,s,i)=>{let n=65535&t|0,o=t>>>16&65535|0,r=0;for(;0!==s;){r=s>2e3?2e3:s,s-=r;do{n=n+e[i++]|0,o=o+n|0}while(--r);n%=65521,o%=65521}return n|o<<16|0};const ao=new Uint32Array((()=>{let t,e=[];for(var s=0;s<256;s++){t=s;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[s]=t}return e})());var lo=(t,e,s,i)=>{const n=ao,o=i+s;t^=-1;for(let s=i;s>>8^n[255&(t^e[s])];return-1^t},co={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},ho={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};const{_tr_init:uo,_tr_stored_block:mo,_tr_flush_block:po,_tr_tally:fo,_tr_align:bo}=oo,{Z_NO_FLUSH:yo,Z_PARTIAL_FLUSH:go,Z_FULL_FLUSH:wo,Z_FINISH:Zo,Z_BLOCK:Xo,Z_OK:vo,Z_STREAM_END:Lo,Z_STREAM_ERROR:xo,Z_DATA_ERROR:Go,Z_BUF_ERROR:So,Z_DEFAULT_COMPRESSION:ko,Z_FILTERED:Wo,Z_HUFFMAN_ONLY:To,Z_RLE:Co,Z_FIXED:Vo,Z_DEFAULT_STRATEGY:Po,Z_UNKNOWN:Ro,Z_DEFLATED:Yo}=ho,Mo=(t,e)=>(t.msg=co[e],e),Io=t=>(t<<1)-(t>4?9:0),Ko=t=>{let e=t.length;for(;--e>=0;)t[e]=0};let Ho=(t,e,s)=>(e<{const e=t.state;let s=e.pending;s>t.avail_out&&(s=t.avail_out),0!==s&&(t.output.set(e.pending_buf.subarray(e.pending_out,e.pending_out+s),t.next_out),t.next_out+=s,e.pending_out+=s,t.total_out+=s,t.avail_out-=s,e.pending-=s,0===e.pending&&(e.pending_out=0))},No=(t,e)=>{po(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,zo(t.strm)},Fo=(t,e)=>{t.pending_buf[t.pending++]=e},_o=(t,e)=>{t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e},jo=(t,e,s,i)=>{let n=t.avail_in;return n>i&&(n=i),0===n?0:(t.avail_in-=n,e.set(t.input.subarray(t.next_in,t.next_in+n),s),1===t.state.wrap?t.adler=ro(t.adler,e,n,s):2===t.state.wrap&&(t.adler=lo(t.adler,e,n,s)),t.next_in+=n,t.total_in+=n,n)},Qo=(t,e)=>{let s,i,n=t.max_chain_length,o=t.strstart,r=t.prev_length,a=t.nice_match;const l=t.strstart>t.w_size-262?t.strstart-(t.w_size-262):0,c=t.window,d=t.w_mask,h=t.prev,u=t.strstart+258;let m=c[o+r-1],p=c[o+r];t.prev_length>=t.good_match&&(n>>=2),a>t.lookahead&&(a=t.lookahead);do{if(s=e,c[s+r]===p&&c[s+r-1]===m&&c[s]===c[o]&&c[++s]===c[o+1]){o+=2,s++;do{}while(c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&or){if(t.match_start=e,r=i,i>=a)break;m=c[o+r-1],p=c[o+r]}}}while((e=h[e&d])>l&&0!=--n);return r<=t.lookahead?r:t.lookahead},Eo=t=>{const e=t.w_size;let s,i,n,o,r;do{if(o=t.window_size-t.lookahead-t.strstart,t.strstart>=e+(e-262)){t.window.set(t.window.subarray(e,e+e),0),t.match_start-=e,t.strstart-=e,t.block_start-=e,i=t.hash_size,s=i;do{n=t.head[--s],t.head[s]=n>=e?n-e:0}while(--i);i=e,s=i;do{n=t.prev[--s],t.prev[s]=n>=e?n-e:0}while(--i);o+=e}if(0===t.strm.avail_in)break;if(i=jo(t.strm,t.window,t.strstart+t.lookahead,o),t.lookahead+=i,t.lookahead+t.insert>=3)for(r=t.strstart-t.insert,t.ins_h=t.window[r],t.ins_h=Ho(t,t.ins_h,t.window[r+1]);t.insert&&(t.ins_h=Ho(t,t.ins_h,t.window[r+3-1]),t.prev[r&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=r,r++,t.insert--,!(t.lookahead+t.insert<3)););}while(t.lookahead<262&&0!==t.strm.avail_in)},Jo=(t,e)=>{let s,i;for(;;){if(t.lookahead<262){if(Eo(t),t.lookahead<262&&e===yo)return 1;if(0===t.lookahead)break}if(s=0,t.lookahead>=3&&(t.ins_h=Ho(t,t.ins_h,t.window[t.strstart+3-1]),s=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==s&&t.strstart-s<=t.w_size-262&&(t.match_length=Qo(t,s)),t.match_length>=3)if(i=fo(t,t.strstart-t.match_start,t.match_length-3),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=3){t.match_length--;do{t.strstart++,t.ins_h=Ho(t,t.ins_h,t.window[t.strstart+3-1]),s=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart}while(0!=--t.match_length);t.strstart++}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=Ho(t,t.ins_h,t.window[t.strstart+1]);else i=fo(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(i&&(No(t,!1),0===t.strm.avail_out))return 1}return t.insert=t.strstart<2?t.strstart:2,e===Zo?(No(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(No(t,!1),0===t.strm.avail_out)?1:2},Uo=(t,e)=>{let s,i,n;for(;;){if(t.lookahead<262){if(Eo(t),t.lookahead<262&&e===yo)return 1;if(0===t.lookahead)break}if(s=0,t.lookahead>=3&&(t.ins_h=Ho(t,t.ins_h,t.window[t.strstart+3-1]),s=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=2,0!==s&&t.prev_length4096)&&(t.match_length=2)),t.prev_length>=3&&t.match_length<=t.prev_length){n=t.strstart+t.lookahead-3,i=fo(t,t.strstart-1-t.prev_match,t.prev_length-3),t.lookahead-=t.prev_length-1,t.prev_length-=2;do{++t.strstart<=n&&(t.ins_h=Ho(t,t.ins_h,t.window[t.strstart+3-1]),s=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart)}while(0!=--t.prev_length);if(t.match_available=0,t.match_length=2,t.strstart++,i&&(No(t,!1),0===t.strm.avail_out))return 1}else if(t.match_available){if(i=fo(t,0,t.window[t.strstart-1]),i&&No(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return 1}else t.match_available=1,t.strstart++,t.lookahead--}return t.match_available&&(i=fo(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<2?t.strstart:2,e===Zo?(No(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(No(t,!1),0===t.strm.avail_out)?1:2};function Do(t,e,s,i,n){this.good_length=t,this.max_lazy=e,this.nice_length=s,this.max_chain=i,this.func=n}const Oo=[new Do(0,0,0,0,((t,e)=>{let s=65535;for(s>t.pending_buf_size-5&&(s=t.pending_buf_size-5);;){if(t.lookahead<=1){if(Eo(t),0===t.lookahead&&e===yo)return 1;if(0===t.lookahead)break}t.strstart+=t.lookahead,t.lookahead=0;const i=t.block_start+s;if((0===t.strstart||t.strstart>=i)&&(t.lookahead=t.strstart-i,t.strstart=i,No(t,!1),0===t.strm.avail_out))return 1;if(t.strstart-t.block_start>=t.w_size-262&&(No(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===Zo?(No(t,!0),0===t.strm.avail_out?3:4):(t.strstart>t.block_start&&(No(t,!1),t.strm.avail_out),1)})),new Do(4,4,8,4,Jo),new Do(4,5,16,8,Jo),new Do(4,6,32,32,Jo),new Do(4,4,16,16,Uo),new Do(8,16,32,32,Uo),new Do(8,16,128,128,Uo),new Do(8,32,128,256,Uo),new Do(32,128,258,1024,Uo),new Do(32,258,258,4096,Uo)];function Bo(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Yo,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Uint16Array(1146),this.dyn_dtree=new Uint16Array(122),this.bl_tree=new Uint16Array(78),Ko(this.dyn_ltree),Ko(this.dyn_dtree),Ko(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Uint16Array(16),this.heap=new Uint16Array(573),Ko(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Uint16Array(573),Ko(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}const Ao=t=>{if(!t||!t.state)return Mo(t,xo);t.total_in=t.total_out=0,t.data_type=Ro;const e=t.state;return e.pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=e.wrap?42:113,t.adler=2===e.wrap?0:1,e.last_flush=yo,uo(e),vo},$o=t=>{const e=Ao(t);var s;return e===vo&&((s=t.state).window_size=2*s.w_size,Ko(s.head),s.max_lazy_match=Oo[s.level].max_lazy,s.good_match=Oo[s.level].good_length,s.nice_match=Oo[s.level].nice_length,s.max_chain_length=Oo[s.level].max_chain,s.strstart=0,s.block_start=0,s.lookahead=0,s.insert=0,s.match_length=s.prev_length=2,s.match_available=0,s.ins_h=0),e},qo=(t,e,s,i,n,o)=>{if(!t)return xo;let r=1;if(e===ko&&(e=6),i<0?(r=0,i=-i):i>15&&(r=2,i-=16),n<1||n>9||s!==Yo||i<8||i>15||e<0||e>9||o<0||o>Vo)return Mo(t,xo);8===i&&(i=9);const a=new Bo;return t.state=a,a.strm=t,a.wrap=r,a.gzhead=null,a.w_bits=i,a.w_size=1<qo(t,e,Yo,15,8,Po),deflateInit2:qo,deflateReset:$o,deflateResetKeep:Ao,deflateSetHeader:(t,e)=>t&&t.state?2!==t.state.wrap?xo:(t.state.gzhead=e,vo):xo,deflate:(t,e)=>{let s,i;if(!t||!t.state||e>Xo||e<0)return t?Mo(t,xo):xo;const n=t.state;if(!t.output||!t.input&&0!==t.avail_in||666===n.status&&e!==Zo)return Mo(t,0===t.avail_out?So:xo);n.strm=t;const o=n.last_flush;if(n.last_flush=e,42===n.status)if(2===n.wrap)t.adler=0,Fo(n,31),Fo(n,139),Fo(n,8),n.gzhead?(Fo(n,(n.gzhead.text?1:0)+(n.gzhead.hcrc?2:0)+(n.gzhead.extra?4:0)+(n.gzhead.name?8:0)+(n.gzhead.comment?16:0)),Fo(n,255&n.gzhead.time),Fo(n,n.gzhead.time>>8&255),Fo(n,n.gzhead.time>>16&255),Fo(n,n.gzhead.time>>24&255),Fo(n,9===n.level?2:n.strategy>=To||n.level<2?4:0),Fo(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(Fo(n,255&n.gzhead.extra.length),Fo(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(t.adler=lo(t.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(Fo(n,0),Fo(n,0),Fo(n,0),Fo(n,0),Fo(n,0),Fo(n,9===n.level?2:n.strategy>=To||n.level<2?4:0),Fo(n,3),n.status=113);else{let e=Yo+(n.w_bits-8<<4)<<8,s=-1;s=n.strategy>=To||n.level<2?0:n.level<6?1:6===n.level?2:3,e|=s<<6,0!==n.strstart&&(e|=32),e+=31-e%31,n.status=113,_o(n,e),0!==n.strstart&&(_o(n,t.adler>>>16),_o(n,65535&t.adler)),t.adler=1}if(69===n.status)if(n.gzhead.extra){for(s=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>s&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),zo(t),s=n.pending,n.pending!==n.pending_buf_size));)Fo(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>s&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){s=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>s&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),zo(t),s=n.pending,n.pending===n.pending_buf_size)){i=1;break}i=n.gzindexs&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),0===i&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){s=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>s&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),zo(t),s=n.pending,n.pending===n.pending_buf_size)){i=1;break}i=n.gzindexs&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),0===i&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&zo(t),n.pending+2<=n.pending_buf_size&&(Fo(n,255&t.adler),Fo(n,t.adler>>8&255),t.adler=0,n.status=113)):n.status=113),0!==n.pending){if(zo(t),0===t.avail_out)return n.last_flush=-1,vo}else if(0===t.avail_in&&Io(e)<=Io(o)&&e!==Zo)return Mo(t,So);if(666===n.status&&0!==t.avail_in)return Mo(t,So);if(0!==t.avail_in||0!==n.lookahead||e!==yo&&666!==n.status){let s=n.strategy===To?((t,e)=>{let s;for(;;){if(0===t.lookahead&&(Eo(t),0===t.lookahead)){if(e===yo)return 1;break}if(t.match_length=0,s=fo(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,s&&(No(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===Zo?(No(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(No(t,!1),0===t.strm.avail_out)?1:2})(n,e):n.strategy===Co?((t,e)=>{let s,i,n,o;const r=t.window;for(;;){if(t.lookahead<=258){if(Eo(t),t.lookahead<=258&&e===yo)return 1;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=3&&t.strstart>0&&(n=t.strstart-1,i=r[n],i===r[++n]&&i===r[++n]&&i===r[++n])){o=t.strstart+258;do{}while(i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&nt.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=3?(s=fo(t,1,t.match_length-3),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(s=fo(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),s&&(No(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===Zo?(No(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(No(t,!1),0===t.strm.avail_out)?1:2})(n,e):Oo[n.level].func(n,e);if(3!==s&&4!==s||(n.status=666),1===s||3===s)return 0===t.avail_out&&(n.last_flush=-1),vo;if(2===s&&(e===go?bo(n):e!==Xo&&(mo(n,0,0,!1),e===wo&&(Ko(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),zo(t),0===t.avail_out))return n.last_flush=-1,vo}return e!==Zo?vo:n.wrap<=0?Lo:(2===n.wrap?(Fo(n,255&t.adler),Fo(n,t.adler>>8&255),Fo(n,t.adler>>16&255),Fo(n,t.adler>>24&255),Fo(n,255&t.total_in),Fo(n,t.total_in>>8&255),Fo(n,t.total_in>>16&255),Fo(n,t.total_in>>24&255)):(_o(n,t.adler>>>16),_o(n,65535&t.adler)),zo(t),n.wrap>0&&(n.wrap=-n.wrap),0!==n.pending?vo:Lo)},deflateEnd:t=>{if(!t||!t.state)return xo;const e=t.state.status;return 42!==e&&69!==e&&73!==e&&91!==e&&103!==e&&113!==e&&666!==e?Mo(t,xo):(t.state=null,113===e?Mo(t,Go):vo)},deflateSetDictionary:(t,e)=>{let s=e.length;if(!t||!t.state)return xo;const i=t.state,n=i.wrap;if(2===n||1===n&&42!==i.status||i.lookahead)return xo;if(1===n&&(t.adler=ro(t.adler,e,s,0)),i.wrap=0,s>=i.w_size){0===n&&(Ko(i.head),i.strstart=0,i.block_start=0,i.insert=0);let t=new Uint8Array(i.w_size);t.set(e.subarray(s-i.w_size,s),0),e=t,s=i.w_size}const o=t.avail_in,r=t.next_in,a=t.input;for(t.avail_in=s,t.next_in=0,t.input=e,Eo(i);i.lookahead>=3;){let t=i.strstart,e=i.lookahead-2;do{i.ins_h=Ho(i,i.ins_h,i.window[t+3-1]),i.prev[t&i.w_mask]=i.head[i.ins_h],i.head[i.ins_h]=t,t++}while(--e);i.strstart=t,i.lookahead=2,Eo(i)}return i.strstart+=i.lookahead,i.block_start=i.strstart,i.insert=i.lookahead,i.lookahead=0,i.match_length=i.prev_length=2,i.match_available=0,t.next_in=r,t.input=a,t.avail_in=o,i.wrap=n,vo},deflateInfo:"pako deflate (from Nodeca project)"};const er=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var sr=function(t){const e=Array.prototype.slice.call(arguments,1);for(;e.length;){const s=e.shift();if(s){if("object"!=typeof s)throw new TypeError(s+"must be non-object");for(const e in s)er(s,e)&&(t[e]=s[e])}}return t},ir=t=>{let e=0;for(let s=0,i=t.length;s=252?6:t>=248?5:t>=240?4:t>=224?3:t>=192?2:1;or[254]=or[254]=1;var rr=t=>{if("function"==typeof TextEncoder&&TextEncoder.prototype.encode)return(new TextEncoder).encode(t);let e,s,i,n,o,r=t.length,a=0;for(n=0;n>>6,e[o++]=128|63&s):s<65536?(e[o++]=224|s>>>12,e[o++]=128|s>>>6&63,e[o++]=128|63&s):(e[o++]=240|s>>>18,e[o++]=128|s>>>12&63,e[o++]=128|s>>>6&63,e[o++]=128|63&s);return e},ar=(t,e)=>{const s=e||t.length;if("function"==typeof TextDecoder&&TextDecoder.prototype.decode)return(new TextDecoder).decode(t.subarray(0,e));let i,n;const o=new Array(2*s);for(n=0,i=0;i4)o[n++]=65533,i+=r-1;else{for(e&=2===r?31:3===r?15:7;r>1&&i1?o[n++]=65533:e<65536?o[n++]=e:(e-=65536,o[n++]=55296|e>>10&1023,o[n++]=56320|1023&e)}}return((t,e)=>{if(e<65534&&t.subarray&&nr)return String.fromCharCode.apply(null,t.length===e?t:t.subarray(0,e));let s="";for(let i=0;i{(e=e||t.length)>t.length&&(e=t.length);let s=e-1;for(;s>=0&&128==(192&t[s]);)s--;return s<0||0===s?e:s+or[t[s]]>e?s:e};var cr=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0};const dr=Object.prototype.toString,{Z_NO_FLUSH:hr,Z_SYNC_FLUSH:ur,Z_FULL_FLUSH:mr,Z_FINISH:pr,Z_OK:fr,Z_STREAM_END:br,Z_DEFAULT_COMPRESSION:yr,Z_DEFAULT_STRATEGY:gr,Z_DEFLATED:wr}=ho;function Zr(t){this.options=sr({level:yr,method:wr,chunkSize:16384,windowBits:15,memLevel:8,strategy:gr},t||{});let e=this.options;e.raw&&e.windowBits>0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new cr,this.strm.avail_out=0;let s=tr.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(s!==fr)throw new Error(co[s]);if(e.header&&tr.deflateSetHeader(this.strm,e.header),e.dictionary){let t;if(t="string"==typeof e.dictionary?rr(e.dictionary):"[object ArrayBuffer]"===dr.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,s=tr.deflateSetDictionary(this.strm,t),s!==fr)throw new Error(co[s]);this._dict_set=!0}}function Xr(t,e){const s=new Zr(e);if(s.push(t,!0),s.err)throw s.msg||co[s.err];return s.result}Zr.prototype.push=function(t,e){const s=this.strm,i=this.options.chunkSize;let n,o;if(this.ended)return!1;for(o=e===~~e?e:!0===e?pr:hr,"string"==typeof t?s.input=rr(t):"[object ArrayBuffer]"===dr.call(t)?s.input=new Uint8Array(t):s.input=t,s.next_in=0,s.avail_in=s.input.length;;)if(0===s.avail_out&&(s.output=new Uint8Array(i),s.next_out=0,s.avail_out=i),(o===ur||o===mr)&&s.avail_out<=6)this.onData(s.output.subarray(0,s.next_out)),s.avail_out=0;else{if(n=tr.deflate(s,o),n===br)return s.next_out>0&&this.onData(s.output.subarray(0,s.next_out)),n=tr.deflateEnd(this.strm),this.onEnd(n),this.ended=!0,n===fr;if(0!==s.avail_out){if(o>0&&s.next_out>0)this.onData(s.output.subarray(0,s.next_out)),s.avail_out=0;else if(0===s.avail_in)break}else this.onData(s.output)}return!0},Zr.prototype.onData=function(t){this.chunks.push(t)},Zr.prototype.onEnd=function(t){t===fr&&(this.result=ir(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg};var vr={Deflate:Zr,deflate:Xr,deflateRaw:function(t,e){return(e=e||{}).raw=!0,Xr(t,e)},gzip:function(t,e){return(e=e||{}).gzip=!0,Xr(t,e)},constants:ho};var Lr=function(t,e){let s,i,n,o,r,a,l,c,d,h,u,m,p,f,b,y,g,w,Z,X,v,L,x,G;const S=t.state;s=t.next_in,x=t.input,i=s+(t.avail_in-5),n=t.next_out,G=t.output,o=n-(e-t.avail_out),r=n+(t.avail_out-257),a=S.dmax,l=S.wsize,c=S.whave,d=S.wnext,h=S.window,u=S.hold,m=S.bits,p=S.lencode,f=S.distcode,b=(1<>>24,u>>>=w,m-=w,w=g>>>16&255,0===w)G[n++]=65535&g;else{if(!(16&w)){if(0==(64&w)){g=p[(65535&g)+(u&(1<>>=w,m-=w),m<15&&(u+=x[s++]<>>24,u>>>=w,m-=w,w=g>>>16&255,!(16&w)){if(0==(64&w)){g=f[(65535&g)+(u&(1<a){t.msg="invalid distance too far back",S.mode=30;break t}if(u>>>=w,m-=w,w=n-o,X>w){if(w=X-w,w>c&&S.sane){t.msg="invalid distance too far back",S.mode=30;break t}if(v=0,L=h,0===d){if(v+=l-w,w2;)G[n++]=L[v++],G[n++]=L[v++],G[n++]=L[v++],Z-=3;Z&&(G[n++]=L[v++],Z>1&&(G[n++]=L[v++]))}else{v=n-X;do{G[n++]=G[v++],G[n++]=G[v++],G[n++]=G[v++],Z-=3}while(Z>2);Z&&(G[n++]=G[v++],Z>1&&(G[n++]=G[v++]))}break}}break}}while(s>3,s-=Z,m-=Z<<3,u&=(1<{const l=a.bits;let c,d,h,u,m,p,f=0,b=0,y=0,g=0,w=0,Z=0,X=0,v=0,L=0,x=0,G=null,S=0;const k=new Uint16Array(16),W=new Uint16Array(16);let T,C,V,P=null,R=0;for(f=0;f<=15;f++)k[f]=0;for(b=0;b=1&&0===k[g];g--);if(w>g&&(w=g),0===g)return n[o++]=20971520,n[o++]=20971520,a.bits=1,0;for(y=1;y0&&(0===t||1!==g))return-1;for(W[1]=0,f=1;f<15;f++)W[f+1]=W[f]+k[f];for(b=0;b852||2===t&&L>592)return 1;for(;;){T=f-X,r[b]p?(C=P[R+r[b]],V=G[S+r[b]]):(C=96,V=0),c=1<>X)+d]=T<<24|C<<16|V|0}while(0!==d);for(c=1<>=1;if(0!==c?(x&=c-1,x+=c):x=0,b++,0==--k[f]){if(f===g)break;f=e[s+r[b]]}if(f>w&&(x&u)!==h){for(0===X&&(X=w),m+=y,Z=f-X,v=1<852||2===t&&L>592)return 1;h=x&u,n[h]=w<<24|Z<<16|m-o|0}}return 0!==x&&(n[m+x]=f-X<<24|64<<16|0),a.bits=w,0};const{Z_FINISH:Tr,Z_BLOCK:Cr,Z_TREES:Vr,Z_OK:Pr,Z_STREAM_END:Rr,Z_NEED_DICT:Yr,Z_STREAM_ERROR:Mr,Z_DATA_ERROR:Ir,Z_MEM_ERROR:Kr,Z_BUF_ERROR:Hr,Z_DEFLATED:zr}=ho,Nr=t=>(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24);function Fr(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}const _r=t=>{if(!t||!t.state)return Mr;const e=t.state;return t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=1,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new Int32Array(852),e.distcode=e.distdyn=new Int32Array(592),e.sane=1,e.back=-1,Pr},jr=t=>{if(!t||!t.state)return Mr;const e=t.state;return e.wsize=0,e.whave=0,e.wnext=0,_r(t)},Qr=(t,e)=>{let s;if(!t||!t.state)return Mr;const i=t.state;return e<0?(s=0,e=-e):(s=1+(e>>4),e<48&&(e&=15)),e&&(e<8||e>15)?Mr:(null!==i.window&&i.wbits!==e&&(i.window=null),i.wrap=s,i.wbits=e,jr(t))},Er=(t,e)=>{if(!t)return Mr;const s=new Fr;t.state=s,s.window=null;const i=Qr(t,e);return i!==Pr&&(t.state=null),i};let Jr,Ur,Dr=!0;const Or=t=>{if(Dr){Jr=new Int32Array(512),Ur=new Int32Array(32);let e=0;for(;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(Wr(1,t.lens,0,288,Jr,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;Wr(2,t.lens,0,32,Ur,0,t.work,{bits:5}),Dr=!1}t.lencode=Jr,t.lenbits=9,t.distcode=Ur,t.distbits=5},Br=(t,e,s,i)=>{let n;const o=t.state;return null===o.window&&(o.wsize=1<=o.wsize?(o.window.set(e.subarray(s-o.wsize,s),0),o.wnext=0,o.whave=o.wsize):(n=o.wsize-o.wnext,n>i&&(n=i),o.window.set(e.subarray(s-i,s-i+n),o.wnext),(i-=n)?(o.window.set(e.subarray(s-i,s),0),o.wnext=i,o.whave=o.wsize):(o.wnext+=n,o.wnext===o.wsize&&(o.wnext=0),o.whave{let s,i,n,o,r,a,l,c,d,h,u,m,p,f,b,y,g,w,Z,X,v,L,x=0;const G=new Uint8Array(4);let S,k;const W=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(!t||!t.state||!t.output||!t.input&&0!==t.avail_in)return Mr;s=t.state,12===s.mode&&(s.mode=13),r=t.next_out,n=t.output,l=t.avail_out,o=t.next_in,i=t.input,a=t.avail_in,c=s.hold,d=s.bits,h=a,u=l,L=Pr;t:for(;;)switch(s.mode){case 1:if(0===s.wrap){s.mode=13;break}for(;d<16;){if(0===a)break t;a--,c+=i[o++]<>>8&255,s.check=lo(s.check,G,2,0),c=0,d=0,s.mode=2;break}if(s.flags=0,s.head&&(s.head.done=!1),!(1&s.wrap)||(((255&c)<<8)+(c>>8))%31){t.msg="incorrect header check",s.mode=30;break}if((15&c)!==zr){t.msg="unknown compression method",s.mode=30;break}if(c>>>=4,d-=4,v=8+(15&c),0===s.wbits)s.wbits=v;else if(v>s.wbits){t.msg="invalid window size",s.mode=30;break}s.dmax=1<>8&1),512&s.flags&&(G[0]=255&c,G[1]=c>>>8&255,s.check=lo(s.check,G,2,0)),c=0,d=0,s.mode=3;case 3:for(;d<32;){if(0===a)break t;a--,c+=i[o++]<>>8&255,G[2]=c>>>16&255,G[3]=c>>>24&255,s.check=lo(s.check,G,4,0)),c=0,d=0,s.mode=4;case 4:for(;d<16;){if(0===a)break t;a--,c+=i[o++]<>8),512&s.flags&&(G[0]=255&c,G[1]=c>>>8&255,s.check=lo(s.check,G,2,0)),c=0,d=0,s.mode=5;case 5:if(1024&s.flags){for(;d<16;){if(0===a)break t;a--,c+=i[o++]<>>8&255,s.check=lo(s.check,G,2,0)),c=0,d=0}else s.head&&(s.head.extra=null);s.mode=6;case 6:if(1024&s.flags&&(m=s.length,m>a&&(m=a),m&&(s.head&&(v=s.head.extra_len-s.length,s.head.extra||(s.head.extra=new Uint8Array(s.head.extra_len)),s.head.extra.set(i.subarray(o,o+m),v)),512&s.flags&&(s.check=lo(s.check,i,m,o)),a-=m,o+=m,s.length-=m),s.length))break t;s.length=0,s.mode=7;case 7:if(2048&s.flags){if(0===a)break t;m=0;do{v=i[o+m++],s.head&&v&&s.length<65536&&(s.head.name+=String.fromCharCode(v))}while(v&&m>9&1,s.head.done=!0),t.adler=s.check=0,s.mode=12;break;case 10:for(;d<32;){if(0===a)break t;a--,c+=i[o++]<>>=7&d,d-=7&d,s.mode=27;break}for(;d<3;){if(0===a)break t;a--,c+=i[o++]<>>=1,d-=1,3&c){case 0:s.mode=14;break;case 1:if(Or(s),s.mode=20,e===Vr){c>>>=2,d-=2;break t}break;case 2:s.mode=17;break;case 3:t.msg="invalid block type",s.mode=30}c>>>=2,d-=2;break;case 14:for(c>>>=7&d,d-=7&d;d<32;){if(0===a)break t;a--,c+=i[o++]<>>16^65535)){t.msg="invalid stored block lengths",s.mode=30;break}if(s.length=65535&c,c=0,d=0,s.mode=15,e===Vr)break t;case 15:s.mode=16;case 16:if(m=s.length,m){if(m>a&&(m=a),m>l&&(m=l),0===m)break t;n.set(i.subarray(o,o+m),r),a-=m,o+=m,l-=m,r+=m,s.length-=m;break}s.mode=12;break;case 17:for(;d<14;){if(0===a)break t;a--,c+=i[o++]<>>=5,d-=5,s.ndist=1+(31&c),c>>>=5,d-=5,s.ncode=4+(15&c),c>>>=4,d-=4,s.nlen>286||s.ndist>30){t.msg="too many length or distance symbols",s.mode=30;break}s.have=0,s.mode=18;case 18:for(;s.have>>=3,d-=3}for(;s.have<19;)s.lens[W[s.have++]]=0;if(s.lencode=s.lendyn,s.lenbits=7,S={bits:s.lenbits},L=Wr(0,s.lens,0,19,s.lencode,0,s.work,S),s.lenbits=S.bits,L){t.msg="invalid code lengths set",s.mode=30;break}s.have=0,s.mode=19;case 19:for(;s.have>>24,y=x>>>16&255,g=65535&x,!(b<=d);){if(0===a)break t;a--,c+=i[o++]<>>=b,d-=b,s.lens[s.have++]=g;else{if(16===g){for(k=b+2;d>>=b,d-=b,0===s.have){t.msg="invalid bit length repeat",s.mode=30;break}v=s.lens[s.have-1],m=3+(3&c),c>>>=2,d-=2}else if(17===g){for(k=b+3;d>>=b,d-=b,v=0,m=3+(7&c),c>>>=3,d-=3}else{for(k=b+7;d>>=b,d-=b,v=0,m=11+(127&c),c>>>=7,d-=7}if(s.have+m>s.nlen+s.ndist){t.msg="invalid bit length repeat",s.mode=30;break}for(;m--;)s.lens[s.have++]=v}}if(30===s.mode)break;if(0===s.lens[256]){t.msg="invalid code -- missing end-of-block",s.mode=30;break}if(s.lenbits=9,S={bits:s.lenbits},L=Wr(1,s.lens,0,s.nlen,s.lencode,0,s.work,S),s.lenbits=S.bits,L){t.msg="invalid literal/lengths set",s.mode=30;break}if(s.distbits=6,s.distcode=s.distdyn,S={bits:s.distbits},L=Wr(2,s.lens,s.nlen,s.ndist,s.distcode,0,s.work,S),s.distbits=S.bits,L){t.msg="invalid distances set",s.mode=30;break}if(s.mode=20,e===Vr)break t;case 20:s.mode=21;case 21:if(a>=6&&l>=258){t.next_out=r,t.avail_out=l,t.next_in=o,t.avail_in=a,s.hold=c,s.bits=d,Lr(t,u),r=t.next_out,n=t.output,l=t.avail_out,o=t.next_in,i=t.input,a=t.avail_in,c=s.hold,d=s.bits,12===s.mode&&(s.back=-1);break}for(s.back=0;x=s.lencode[c&(1<>>24,y=x>>>16&255,g=65535&x,!(b<=d);){if(0===a)break t;a--,c+=i[o++]<>w)],b=x>>>24,y=x>>>16&255,g=65535&x,!(w+b<=d);){if(0===a)break t;a--,c+=i[o++]<>>=w,d-=w,s.back+=w}if(c>>>=b,d-=b,s.back+=b,s.length=g,0===y){s.mode=26;break}if(32&y){s.back=-1,s.mode=12;break}if(64&y){t.msg="invalid literal/length code",s.mode=30;break}s.extra=15&y,s.mode=22;case 22:if(s.extra){for(k=s.extra;d>>=s.extra,d-=s.extra,s.back+=s.extra}s.was=s.length,s.mode=23;case 23:for(;x=s.distcode[c&(1<>>24,y=x>>>16&255,g=65535&x,!(b<=d);){if(0===a)break t;a--,c+=i[o++]<>w)],b=x>>>24,y=x>>>16&255,g=65535&x,!(w+b<=d);){if(0===a)break t;a--,c+=i[o++]<>>=w,d-=w,s.back+=w}if(c>>>=b,d-=b,s.back+=b,64&y){t.msg="invalid distance code",s.mode=30;break}s.offset=g,s.extra=15&y,s.mode=24;case 24:if(s.extra){for(k=s.extra;d>>=s.extra,d-=s.extra,s.back+=s.extra}if(s.offset>s.dmax){t.msg="invalid distance too far back",s.mode=30;break}s.mode=25;case 25:if(0===l)break t;if(m=u-l,s.offset>m){if(m=s.offset-m,m>s.whave&&s.sane){t.msg="invalid distance too far back",s.mode=30;break}m>s.wnext?(m-=s.wnext,p=s.wsize-m):p=s.wnext-m,m>s.length&&(m=s.length),f=s.window}else f=n,p=r-s.offset,m=s.length;m>l&&(m=l),l-=m,s.length-=m;do{n[r++]=f[p++]}while(--m);0===s.length&&(s.mode=21);break;case 26:if(0===l)break t;n[r++]=s.length,l--,s.mode=21;break;case 27:if(s.wrap){for(;d<32;){if(0===a)break t;a--,c|=i[o++]<Er(t,15),inflateInit2:Er,inflate:Ar,inflateEnd:t=>{if(!t||!t.state)return Mr;let e=t.state;return e.window&&(e.window=null),t.state=null,Pr},inflateGetHeader:(t,e)=>{if(!t||!t.state)return Mr;const s=t.state;return 0==(2&s.wrap)?Mr:(s.head=e,e.done=!1,Pr)},inflateSetDictionary:(t,e)=>{const s=e.length;let i,n,o;return t&&t.state?(i=t.state,0!==i.wrap&&11!==i.mode?Mr:11===i.mode&&(n=1,n=ro(n,e,s,0),n!==i.check)?Ir:(o=Br(t,e,s,s),o?(i.mode=31,Kr):(i.havedict=1,Pr))):Mr},inflateInfo:"pako inflate (from Nodeca project)"};var qr=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1};const ta=Object.prototype.toString,{Z_NO_FLUSH:ea,Z_FINISH:sa,Z_OK:ia,Z_STREAM_END:na,Z_NEED_DICT:oa,Z_STREAM_ERROR:ra,Z_DATA_ERROR:aa,Z_MEM_ERROR:la}=ho;function ca(t){this.options=sr({chunkSize:65536,windowBits:15,to:""},t||{});const e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(e.windowBits>=0&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new cr,this.strm.avail_out=0;let s=$r.inflateInit2(this.strm,e.windowBits);if(s!==ia)throw new Error(co[s]);if(this.header=new qr,$r.inflateGetHeader(this.strm,this.header),e.dictionary&&("string"==typeof e.dictionary?e.dictionary=rr(e.dictionary):"[object ArrayBuffer]"===ta.call(e.dictionary)&&(e.dictionary=new Uint8Array(e.dictionary)),e.raw&&(s=$r.inflateSetDictionary(this.strm,e.dictionary),s!==ia)))throw new Error(co[s])}function da(t,e){const s=new ca(e);if(s.push(t),s.err)throw s.msg||co[s.err];return s.result}ca.prototype.push=function(t,e){const s=this.strm,i=this.options.chunkSize,n=this.options.dictionary;let o,r,a;if(this.ended)return!1;for(r=e===~~e?e:!0===e?sa:ea,"[object ArrayBuffer]"===ta.call(t)?s.input=new Uint8Array(t):s.input=t,s.next_in=0,s.avail_in=s.input.length;;){for(0===s.avail_out&&(s.output=new Uint8Array(i),s.next_out=0,s.avail_out=i),o=$r.inflate(s,r),o===oa&&n&&(o=$r.inflateSetDictionary(s,n),o===ia?o=$r.inflate(s,r):o===aa&&(o=oa));s.avail_in>0&&o===na&&s.state.wrap>0&&0!==t[s.next_in];)$r.inflateReset(s),o=$r.inflate(s,r);switch(o){case ra:case aa:case oa:case la:return this.onEnd(o),this.ended=!0,!1}if(a=s.avail_out,s.next_out&&(0===s.avail_out||o===na))if("string"===this.options.to){let t=lr(s.output,s.next_out),e=s.next_out-t,n=ar(s.output,t);s.next_out=e,s.avail_out=i-e,e&&s.output.set(s.output.subarray(t,t+e),0),this.onData(n)}else this.onData(s.output.length===s.next_out?s.output:s.output.subarray(0,s.next_out));if(o!==ia||0!==a){if(o===na)return o=$r.inflateEnd(this.strm),this.onEnd(o),this.ended=!0,!0;if(0===s.avail_in)break}}return!0},ca.prototype.onData=function(t){this.chunks.push(t)},ca.prototype.onEnd=function(t){t===ia&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=ir(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg};var ha={Inflate:ca,inflate:da,inflateRaw:function(t,e){return(e=e||{}).raw=!0,da(t,e)},ungzip:da,constants:ho};const{Deflate:ua,deflate:ma,deflateRaw:pa,gzip:fa}=vr,{Inflate:ba,inflate:ya,inflateRaw:ga,ungzip:wa}=ha;var Za={Deflate:ua,deflate:ma,deflateRaw:pa,gzip:fa,Inflate:ba,inflate:ya,inflateRaw:ga,ungzip:wa,constants:ho};class Xa{constructor(){this.url="(offline)",this.readyState=WebSocket.CONNECTING,this.bufferedAmount=0,setTimeout((()=>{this.readyState=WebSocket.OPEN,this.onopen&&this.onopen()}),50),this.start=Date.now()}send(t){const{id:e,action:s,args:i}=JSON.parse(t);switch(s){case"JOIN":return this.id=e,this.ticks=i.ticks.tick,this.seq=-16>>>0,this.reply("SYNC",{messages:[],time:this.time,seq:this.seq,tove:i.tove,reflector:"offline"}),this.reply("RECV",[this.time,++this.seq,{what:"users",joined:[i.user],active:1,total:1}]),void this.tick();case"SEND":{const t=[...i];return t[0]=this.time,t[1]=++this.seq,void this.reply("RECV",t)}case"PULSE":return;default:throw Error("Offline unhandled "+s)}}close(t,e){this.readyState=WebSocket.CLOSING,setTimeout((()=>{this.readyState=WebSocket.CLOSED,this.onclose&&this.onclose({code:t,reason:e})}),50)}get time(){return Date.now()-this.start}tick(){clearInterval(this.ticker),this.ticker=setInterval((()=>{this.reply("TICK",{time:this.time})}),this.ticks)}reply(t,e){setTimeout((()=>{this.onmessage&&this.onmessage({data:JSON.stringify({id:this.id,action:t,args:e})})}),50)}}function va(t,e,s){var i=void 0===e?null:e,n=function(t,e){var s=atob(t);if(e){for(var i=new Uint8Array(s.length),n=0,o=s.length;nconsole.error(`UploadWorker error: ${t.message}`);let Ha=0;const za=new Set;function Na(t){for(const e of za)if(e.id===t){const{appId:t,persistentId:s}=e.sessionSpec;return{appId:t,persistentId:s,uploadEncrypted:t=>e.uploadEncrypted(t),downloadEncrypted:t=>e.downloadEncrypted(t)}}return{}}class Fa{constructor(){!function(){const t=r.dev||!1!==r.dev&&"localhost",e=r.dev||!1!==r.dev&&(Ca||Va);Pa={messages:r.has("debug","messages",!1),sends:r.has("debug","sends",!1),ticks:r.has("debug","ticks",!1),pong:r.has("debug","pong",!1),snapshot:r.has("debug","snapshot",!1),session:r.has("debug","session",!1),initsnapshot:r.has("debug","initsnapshot",t),reflector:r.has("debug","reflector",e),offline:r.has("debug","offline",r.offline)},Pa.offline&&Pt.showMessage("Croquet: offline mode enabled, no multiuser",{level:"warning"})}(),this.reset()}reset(){globalThis.CROQUETVM===this.vm&&delete globalThis.CROQUETVM,this.vm=null,this.session=null,this.connection=this.connection||new _a(this),this.networkQueue=[],this.reflectorTime=0,this.msPerTick=this.msPerTick||0,this.tickMultiplier=this.tickMultiplier||1,this.extrapolatedTimeBase=Date.now(),this.key=this.key||null,this.tove=this.tove||null,this.viewId=this.viewId||Math.floor(Math.random()*36**10).toString(36),this.timeline="",this.rejoinTimeout&&clearTimeout(this.rejoinTimeout),this.rejoinTimeout=0,this.sendBuffer=[],this.users=0,this.usersTotal=0,this.cpuTime=0,this.triggeringCpuTime=null,this.synced=null,this.latency=0,this.latencyHistory&&(this.latencyHistory=[]),this.localTicker&&(globalThis.clearInterval(this.localTicker),delete this.localTicker),this.syncTimer&&(globalThis.clearTimeout(this.syncTimer),delete this.syncTimer),this.tuttiHistory=[],this.lastAnimationEnd=0,this.animationGapCheck=[],this.rateLimitedSendTimes=[],this.rateLimitBuffer=[],this.rateLimitSoftWarned=!1,this.rateLimitBufferWarned=!1,this.rateLimitLastLogged=0,this.payloadSizeWarned=!1,Yt.removeAllSubscriptionsFor(this.viewId),Yt.addSubscription(this.viewId,"__peers__",this.viewId,(t=>bt(`users now ${t.count}`)),"oncePerFrameWhileSynced"),this.leaving||Pt.showSyncWait(!0)}get id(){return this.vm?this.vm.id:this.sessionSpec.id}get persistentId(){return this.sessionSpec.persistentId}get versionId(){return this.sessionSpec.codeHash}get extrapolatedTime(){return Date.now()-this.extrapolatedTimeBase}get viewOnly(){return this.sessionSpec.viewOnly}get backlog(){return this.vm?this.reflectorTime-this.vm.time:0}get starvation(){return Date.now()-this.lastReceived}get lag(){return this.vm?Math.max(0,this.extrapolatedTime-this.vm.time-this.msPerTick):0}get activity(){return Date.now()-this.lastSent}get viewed(){return!(!this.session||!this.session.view)}get connected(){return this.connection.connected}get shouldLeaveWhenDisconnected(){return this.leaving||!this.canRejoinSeamlessly||0===this.sessionSpec.rejoinLimit}get canRejoinSeamlessly(){return!!this.timeline}checkForConnection(t){this.connection.checkForConnection(t)}dormantDisconnect(){this.connected&&this.connection.dormantDisconnect()}async initFromSessionSpec(t){const{name:e,optionsFromUrl:s,password:i,appId:n,apiKey:o,viewIdDebugSuffix:a}=t,l=n?`${n}/${e}`:e;a&&(this.viewId=this.viewId.replace(/_.*$/,"")+"_"+encodeURIComponent((""+a).slice(0,16)).replace(/[^a-z0-9]/gi,(t=>`_${"%"===t?"":t.charCodeAt(0).toString(16).toUpperCase()}`)));const c={...t.options};if(s)for(const t of s)t in r&&(c[t]=r[t]);const d={};for(const e of["hashOverride"])e in r?d[e]=r[e]:e in t&&(d[e]=t[e]);this.key=gn(i,"",{keySize:8});const h=await async function(t,e){return V(t+y(e))}(l,c),{developerId:u,token:m}=await this.verifyApiKey(o,n,h),{id:p,codeHash:f,computedCodeHash:b}=await async function(t,e,s,i){let n,o;const r=R[t];let a="";r?(n=r.codeHashes,o=r.computedCodeHash,a=" (code hashing from cache)"):(n=await Promise.all(P),o=await V([i,...n].join("|")),R[t]={codeHashes:n,computedCodeHash:o});const{hashOverride:l,...c}=s,d=l||o,h=await V(t+"|"+e+y(c)+d);if(W()&&!Y.has(h)){(L?"utf-8":[...document.getElementsByTagName("meta")].find((t=>t.getAttribute("charset"))))||console.warn('Croquet: Missing declaration. Croquet model code hashing might differ between browsers.'),T[o].what="Version ID",T[t].what="Persistent ID",T[h].what="Session ID",d!==o&&(n.push(o),T[o].what="Computed Version ID (replaced by overrideHash)",T[d]={what:"Version ID (as specified by overrideHash)"});const e=[...n,d,t,h].map((t=>({hash:t,...T[t]})));console.log(`Croquet: Debug Hashing for session ${h}${a}`,e),Y.add(h)}return{id:h,persistentId:t,codeHash:d,computedCodeHash:o}}(h,u,d,Wa);this.tove=await this.encrypt(p),Pa.session&&console.log(`Croquet session "${l}":\n sessionId=${p}${n?`\n persistentId=${h}`:""}\n versionId=${f===b?f:`${f} (specified in hashOverride)\n versionId=${b} (computed)`}\n viewId=${this.viewId}`),this.eventRateLimit=t.eventRateLimit,this.eventHistoryLimit=this.eventRateLimit,this.eventMaxBundles=this.eventRateLimit,this.sessionSpec={...t,options:c,name:l,id:p,persistentId:h,developerId:u,token:m,codeHash:f,computedCodeHash:b};const{msPerTick:g,multiplier:w}=this.getTickAndMultiplier();this.msPerTick=g,this.tickMultiplier=w,this.setUpActivityChecks()}async establishSession(){const{id:t,persistentId:e,codeHash:s}=this.sessionSpec;this.sessionSpec.snapshot={id:t,time:0,meta:{id:t,persistentId:e,codeHash:s,created:(new Date).toISOString()}};const i=new Promise((t=>this.sessionSpec.sessionJoined=t));this.checkForConnection(!1),Pa.session&&console.log(t,"waiting for SYNC"),await i}async verifyApiKey(t,e,s){const{signServer:i,apiKey:n}=Ra(t);if("none"===i)return{developerId:"unknown_dev_id"};try{const t=await fetch(`${i}/join?meta=login`,{method:"GET",mode:"cors",headers:{"X-Croquet-Auth":n,"X-Croquet-App":e,"X-Croquet-Id":s,"X-Croquet-Version":Wa,"X-Croquet-Path":new URL(Pt.referrerURL()).pathname},referrer:Pt.referrerURL(),referrerPolicy:"no-referrer-when-downgrade"}),{error:o,developerId:r,token:a}=await t.json();if(o)throw Error(o);return Pa.session&&console.log("Croquet: verified API key"),{developerId:r,token:a}}catch(e){throw Error(`Croquet API key validation failed for "${t}": ${e.message}`)}}lastKnownTime(t){return Math.max(t.time,t.externalTime)}takeSnapshot(){const t=this.vm.snapshot(),e=this.lastKnownTime(t),s=t.externalSeq;return t.meta={...this.sessionSpec.snapshot.meta,options:this.sessionSpec.options,time:e,seq:s,date:(new globalThis.CroquetViewDate).toISOString(),host:Ta?"localhost":window.location.hostname,sdk:Wa},delete t.meta.hash,t}takeSnapshotHandleErrors(){let t,e,s;try{t=ot.begin("snapshot"),s=this.takeSnapshot()}catch(t){return yt("snapshot",t),null}finally{e=ot.end("snapshot")-t}return Pa.snapshot&&console.log(this.id,`snapshot taken in ${Math.ceil(e)} ms`),s}scheduleSnapshot(){if(!this.connected||!this.vm||this.viewOnly)return;const t=this.vm.time,e=t-this.vm.lastSnapshotPoll;if(e<5e3)return void(Pa.snapshot&&console.log(`not requesting snapshot poll (${e}ms since poll scheduled)`));const s=new pl(t,0,"_","handlePollForSnapshot",[]);this.sendTagged(s,{debounce:5e3,msgID:"pollForSnapshot"}),Pa.snapshot&&console.log(this.id,"requesting snapshot poll via reflector")}handlePollForSnapshot(t){if(!0!==this.synced||this.viewOnly)return void(this.triggeringCpuTime=null);const e=this.triggeringCpuTime||this.cpuTime;let s,i,n;this.triggeringCpuTime=null,this.cpuTime=0;try{s=ot.begin("snapshot"),i={cpuTime:e,hash:this.vm.getSummaryHash(),viewId:this.viewId}}catch(t){return void yt("snapshot",t)}finally{n=ot.end("snapshot")-s,this.cpuTime-=n}Pa.snapshot&&console.log(this.id,`Summary hashing took ${Math.ceil(n)}ms`),Promise.resolve().then((()=>this.pollForSnapshot(t,i)))}pollForSnapshot(t,e){e.cpuTime+=Math.random(),Pa.snapshot&&console.log(this.id,"sending snapshot vote",e),this.sendTutti({time:t,topic:"snapshot",data:e,tallyTarget:["handleSnapshotVote"]})}handleSnapshotVote(t){if(!0!==this.synced)return void(Pa.snapshot&&console.log(this.id,"Ignoring snapshot vote during sync"));const{tally:e}=t;Pa.snapshot&&console.log(this.id,"received snapshot votes",e);const{numberOfGroups:s,shouldUpload:i,dissidentFlag:n}=this.analyzeTally(e,"cpuTime");if(s>1&&console.error(this.id,`Session diverged! Snapshots fall into ${s} groups`),i){const t=this.takeSnapshotHandleErrors();t&&Promise.resolve().then((()=>this.uploadSnapshot(t,n)))}}analyzeTally(t,e){let s=!1,i=null;const n=[],o={};let r=null;Object.keys(t).forEach(((t,e)=>{const s=JSON.parse(t);n.push(s);const{hash:i,viewId:a}=s;a===this.viewId&&(r=e),o[i]||(o[i]=[]),o[i].push(e)}));const a=Object.keys(o),l=a.length;let c=0;l>1&&(a.sort(((t,e)=>o[e].length-o[t].length)),o[a[0]].length===o[a[1]].length&&(Pa.snapshot&&console.log(this.id,"Deciding consensus by tie-break"),a[1]1&&a.sort(((t,s)=>n[t][e]-n[s][e])),a[0]===r&&(s=!0,t!==d&&(i={groupVotes:a.length,allVotes:n.length}))}return{numberOfGroups:l,shouldUpload:s,dissidentFlag:i}}snapshotPath(t,e,s){const i=Math.ceil(t).toString().padStart(10,"0"),{appId:n,persistentId:o,codeHash:r,apiKey:a}=this.sessionSpec;return a?`apps/${n}/snap/${r}/${o}.${this.id}/${i}_${e}.${s}`:`snapshots/${this.id}/${i}_${e}-${s}.snap`}hashSnapshot(t){return t.meta.hash?t.meta.hash:(t.meta.hashPromise||(t.meta.hashPromise=new Promise((e=>{const s={...t};delete s.meta,V(JSON.stringify(s)).then((s=>{t.meta.hash=s,delete t.meta.hashPromise,e(s)}))}))),t.meta.hashPromise)}uploadServer(t){if("string"==typeof r.files){let t=new URL(r.files,window.location).href;return t.endsWith("/")&&(t=t.slice(0,-1)),{url:t,apiKey:null}}const{apiKey:e,signServer:s}=Ra(t);if("none"===s&&!Pa.offline)throw Error("no file server configured");return{url:s,apiKey:e}}async uploadSnapshot(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;await this.hashSnapshot(t);const s=ot.begin("snapshot"),i=JSON.stringify(t),n=ot.end("snapshot")-s;Pa.snapshot&&console.log(this.id,`snapshot stringified (${i.length} bytes) in ${Math.ceil(n)}ms`);const{time:o,seq:r,hash:a}=t.meta,l=this.connection.socket;try{const t=await this.uploadEncrypted({content:i,path:this.snapshotPath(o,r,a),key:this.key,gzip:!0,debug:Pa.snapshot,what:"snapshot"});return this.connection.socket!==l?(console.warn(this.id,"Controller was reset while trying to upload snapshot"),!1):(this.announceSnapshotUrl(o,r,a,t,e),!0)}catch(t){return console.error(this.id,"Failed to upload snapshot"),!1}}announceSnapshotUrl(t,e,s,i,n){if(Pa.snapshot){let o=`time: ${t}, seq: ${e}, hash: ${s}`;n&&(o+=", as dissident; "+JSON.stringify(n)),console.log(this.id,`sending snapshot url to reflector (${o}): ${i}`)}try{this.connection.send(JSON.stringify({id:this.id,action:"SNAP",args:{time:t,seq:e,hash:s,url:i,dissident:n}}))}catch(t){console.error("ERROR while sending",t)}}async downloadEncrypted(t){let{url:e,gzip:s,key:i,debug:n,json:o,what:r}=t;e.startsWith("https://croquet.io/files/v1")&&(e=e.replace("https://croquet.io/files/v1","https://files.croquet.io"));const a=e.startsWith("offline:");let l=Date.now();const c=await(a?this.fetchOffline(e,r,n):fetch(e,{method:"GET",mode:"cors",headers:{"X-Croquet-App":this.sessionSpec.appId,"X-Croquet-Id":this.sessionSpec.persistentId,"X-Croquet-Session":this.sessionSpec.id,"X-Croquet-Version":Wa},referrer:Pt.referrerURL()})),d=await c.arrayBuffer();n&&console.log(this.id,`${r} fetched (${d.byteLength} bytes) in ${-l+(l=Date.now())}ms`),ot.addNetworkTraffic(`${r}_in`,d.byteLength);const h=this.decryptBinary(d,i);n&&console.log(this.id,`${r} decrypted (${h.length} bytes) in ${-l+(l=Date.now())}ms`);const u=s?Za.inflate(h):h;return n&&s&&console.log(this.id,`${r} inflated (${u.length} bytes) in ${-l+(l=Date.now())}ms`),o?JSON.parse((new TextDecoder).decode(u)):u}async fetchOffline(t,e,s){const i=++Ha;return new Promise(((n,o)=>{const r=Ta?"addListener":"addEventListener",a=Ta?"removeListener":"removeEventListener";Ka.postMessage({job:i,cmd:"getOfflineFile",url:t,id:this.id,what:e,debug:s,offline:Pa.offline});const l=t=>{if(i!==t.data.job)return;const{ok:s,status:r,statusText:c,body:d,bytes:h}=t.data;ot.addNetworkTraffic(`${e}_out`,h),Ka[a]("message",l),s?n({arrayBuffer:()=>d}):o(Error(`${r}: ${c}`))};try{Ka[r]("message",l)}catch(t){console.log("failed to add listener",t)}}))}async uploadEncrypted(t){let{content:e,path:s,key:i,gzip:n,keep:o,debug:r,what:a}=t;const l="string"==typeof e?(new TextEncoder).encode(e).buffer:e,c=o?void 0:[l],d="string"==typeof i?i:un.stringify(i),{apiKey:h,appId:u,persistentId:m}=this.sessionSpec,p=++Ha;return new Promise(((t,e)=>{const i=Ta?"addListener":"addEventListener",o=Ta?"removeListener":"removeEventListener";Ka.postMessage({job:p,cmd:"uploadEncrypted",server:this.uploadServer(h),path:s,buffer:l,keyBase64:d,gzip:n,referrer:Pt.referrerURL(),id:this.id,appId:u,persistentId:m,CROQUET_VERSION:Wa,debug:r,what:a,offline:Pa.offline},c);const f=s=>{if(p!==s.data.job)return;const{url:i,ok:n,status:r,statusText:l,bytes:c}=s.data;ot.addNetworkTraffic(`${a}_out`,c),Ka[o]("message",f),n?t(i):e(Error(`${r}: ${l}`))};try{Ka[i]("message",f)}catch(t){console.log("failed to add listener",t)}}))}persistentPath(t){const{appId:e,persistentId:s}=this.sessionSpec;return`apps/${e}/${s}/save/${t}`}pollForPersist(t,e,s,i,n){if(!this.synced)return;if(!this.sessionSpec.appId)throw Error("Persistence API requires appId");if(Pa.offline)return;const o={viewId:this.viewId,hash:i,ms:n+.001*Math.random()},r={persistTime:e,persistentHash:i,persistentString:s};Pa.snapshot&&console.log(this.id,`sending persistence vote for time @${e}`,o),this.sendTutti({time:t,topic:"persist",data:o,localContext:r,tallyTarget:["handlePersistVote"]})}async handlePersistVote(t){const{tally:e,localContext:s}=t;if(Pa.snapshot){const t=!!s?`for time @${s.persistTime}`:"that we didn't participate in";console.log(this.id,`received persistence vote ${t}`,e)}const{numberOfGroups:i,shouldUpload:n,dissidentFlag:o}=this.analyzeTally(e,"ms");if(i>1&&console.warn(this.id,`Persistence records fall into ${i} groups`),!n||!s)return;const{persistTime:r,persistentHash:a,persistentString:l}=s,c=await this.uploadEncrypted({path:this.persistentPath(a),content:l,key:this.key,gzip:!0,debug:Pa.snapshot,what:"persistence"});if(Pa.snapshot){const t=o?` (as dissident; ${JSON.stringify(o)})`:"";console.log(this.id,`sending persistent data url to reflector${t}: ${c}`)}try{this.connection.send(JSON.stringify({id:this.id,action:"SAVE",args:{persistTime:r,url:c,dissident:o}}))}catch(t){console.error("ERROR while sending",t)}}convertReflectorMessage(t){let e="noop",s=[];switch(t[2].what){case"users":{const{joined:i,left:n,active:o,total:r}=t[2];this.users=o,this.usersTotal=r;const a="__peers__",l={entered:i||[],exited:n||[],count:o};e="publishFromModelOnly",s=["__VM__",a,l],Yt.handleEvent(this.viewId+":"+a,l);break}case"tally":{const{tuttiSeq:i,tuttiKey:n,tally:o,tallyTarget:r,missingClients:a}=t[2];(Pa.messages||Pa.snapshot)&&a&&console.log(`${a} ${1===a?"client":"clients"} failed to participate in tally ${n||i}`),e="handleTuttiResult",s=[{tuttiSeq:i,tuttiKey:n,tally:o,tallyTarget:r}];break}}const i=new pl(0,0,"_",e,s);t[2]=i.asState()[2]}handleTuttiResult(t){const{tuttiSeq:e,tuttiKey:s,tally:i,tallyTarget:n}=t,o=s?t=>t.tuttiKey===s:t=>t.dummyTuttiSeq===e,r=this.tuttiHistory.findIndex(o),a=-1!==r&&this.tuttiHistory.splice(r,1)[0];let l=null,c=null;if(a&&(l=a.payload,c=a.localContext),n){const[t,...e]=n,s=[...e,{tally:i,localPayload:l,localContext:c}],o=new pl(0,0,"_",t,s);this.vm.verifyExternal(o),o.executeOn(this.vm,!0)}}async receive(t,e){const s=this.lastReceived;switch(this.lastReceived=this.connection.lastReceived,t){case"SYNC":{this.syncReceived=!0,this.clearSyncReceiptTimeout(),za.add(this);const{progressReporter:t}=this.sessionSpec,s=t||(()=>{}),{messages:i,url:n,persisted:o,time:r,seq:a,snapshotSeq:l,tove:c,reflector:d,flags:h}=e;if(c&&c!==this.tove)try{if(this.decrypt(c)!==this.id)throw Error("wrong sessionId in tove?!")}catch(t){return this.connection.closeConnectionWithError("SYNC",Error(`session password check: ${t.message}`),4200),void s(-1)}const u=e.timeline||e.reflectorSession;this.flags=h||{};const m=o?"persistence":"snapshot";Pa.session&&console.log(this.id,`received SYNC from ${d} reflector: time ${r}, ${i.length} messages, ${m} ${n||""}`);let p=!!this.vm;if(p){this.networkQueue.length=0;const t=!!u&&u===this.timeline,e=i[0],s=a,n=void 0!==l?l:e?e[1]:s;Pa.messages&&console.log(this.id,`rejoin: we have #${this.vm.seq} SYNC has #${n}-#${s}`);let o=t&&ml(n,this.vm.seq)&&ml(this.vm.seq,s)&&r>=this.reflectorTime;if(o){let t=0;e&&ml(e[1],this.vm.seq)&&(t=this.vm.seq-e[1]+1>>>0);for(let e=t;o&&e0){const t=this.sendBuffer;this.sendBuffer=[],Pa.session&&console.log(this.id,`rejoin: sending ${t.length} messages buffered while disconnected`);for(const e of t)e()}}else Pa.session&&console.log(this.id,"cannot rejoin seamlessly; rebooting model/view"),this.leave(!0),p=!1}const f=this.networkQueue;this.networkQueue=[];for(const t of i){if("string"!=typeof t[2])this.convertReflectorMessage(t);else try{t[2]=this.decryptPayload(t[2])[0]}catch(t){return this.connection.closeConnectionWithError("SYNC",Error(`session password decrypt: ${t.message}`),4200),void s(-1)}Pa.messages&&console.log(this.id,"received in SYNC "+JSON.stringify(t)),this.networkQueue.push(t)}if(this.networkQueue.push(...f),r>this.reflectorTime&&this.timeFromReflector(r,"reflector"),p)return Pa.session&&console.log(this.id,"seamless rejoin successful"),void this.sessionSpec.sessionJoined();let b;if(this.timeline=u||"",Pa.snapshot&&n&&console.log(`${this.id} fetching ${m} ${n}`),n)try{b=await this.downloadEncrypted({url:n,gzip:!0,key:this.key,debug:Pa.snapshot,json:!0,what:m})}catch(t){return this.connection.closeConnectionWithError("SYNC",Error(`failed to fetch ${m}: ${t.message}`),4200),void s(-1)}if(!this.connected)return console.log(this.id,"disconnected during SYNC"),void s(-1);o?this.install(b):(b&&(this.sessionSpec.snapshot=b),this.install()),Pa.session&&console.log(`${this.id} fast-forwarding from ${Math.round(this.vm.time)} to at least ${r}`);const y=this.vm.time,g=await new Promise((t=>{const{port1:e,port2:i}=new MessageChannel;e.onmessage=()=>{let e=!0;if(this.vm.time===this.reflectorTime)this.viewId in this.vm.views&&(s(1),t(!0),e=!1);else{const t=(this.vm.time-y)/(this.reflectorTime-y);s(t)}e&&this.stepSession("fastForward",{budget:200})};this.fastForwardHandler=e=>{this.connected&&this.vm?"error"===e?(s(-1),t(!1)):i.postMessage("tick"):(console.log(this.id,"disconnected during SYNC fast-forwarding"),s(-1),t(!1))},Promise.resolve().then((()=>this.stepSession("fastForward",{budget:200})))}));return delete this.fastForwardHandler,g&&Pa.session&&console.log(`${this.id} fast-forwarded to ${Math.round(this.vm.time)}`),void(g&&this.sessionSpec.sessionJoined())}case"RECV":{const t=e;if(t[1]>>>=0,"string"!=typeof t[2])Pa.messages&&console.log(this.id,"received META "+JSON.stringify(t)),this.convertReflectorMessage(t),Pa.messages&&console.log(this.id,"converted to "+JSON.stringify(t));else try{const[e,s,i]=this.decryptPayload(t[2]);t[2]=e,s===this.viewId&&this.addToStatistics(i,this.lastReceived),Pa.messages&&console.log(this.id,"received "+JSON.stringify(t))}catch(t){return void this.connection.closeConnectionWithError("RECV",Error(`session password decrypt: ${t.message}`),4200)}let s;return this.networkQueue.push(t),this.flags.rawtime&&(s=t[t.length-1]),this.timeFromReflector(t[0],"reflector",s),void(this.simulateIfNeeded&&Promise.resolve().then((()=>this.simulateIfNeeded())))}case"TICK":{if(!this.vm)return;const t="number"==typeof e?e:e.time;if(Pa.ticks){const e=s&&this.lastReceived-s-this.msPerTick*this.tickMultiplier|0;console.log(this.id,`Controller received TICK ${t} ${Math.abs(e)<5?"on time":e<0?"early":"late"} (${e} ms)`)}return this.timeFromReflector(t,"reflector"),this.tickMultiplier>1&&this.multiplyTick(t),void(this.simulateIfNeeded&&Promise.resolve().then((()=>this.simulateIfNeeded())))}case"INFO":{const{msg:t,options:s}=e;return void Pt.showMessage(t,s)}case"REQU":return Pa.snapshot&&console.log("received REQU (snapshot request) from reflector"),void(this.cpuTime=12345);default:console.warn("Unknown action:",t,e)}}install(t){const e=Date.now(),{snapshot:s,initFn:i,options:n}=this.sessionSpec,[o,r]=s.modelsById?["deserializ","snapshot"]:["initializ","root model"];Pa.session&&console.log(`${this.id} ${o}ing ${r}`);let a=new hl(s,(()=>{try{return i(n,t)}catch(t){throw yt("init",t,"fatal"),t}}));if((Pa.session||Pa.snapshot&&s.modelsById)&&console.log(`${this.id} ${r} ${o}ed in ${Date.now()-e}ms`),Pa.initsnapshot&&!s.modelsById){Pa.snapshot&&console.log(`${this.id} exercising snapshot and restore after init()`);let t=null;try{t=JSON.stringify(a.snapshot())}catch(t){throw yt("initial snapshot",t,"fatal"),t}try{a=new hl(JSON.parse(t),(()=>i(n)))}catch(t){throw yt("initial snapshot resume",t,"fatal"),t}}const l=this.lastKnownTime(a);this.reflectorTime=Math.max(this.reflectorTime,l),this.setVM(a)}setVM(t){this.vm=t,this.vm.controller=this}sendJoin(){this.syncReceived=!1,delete this.fastForwardHandler,this.rejoinTimeout&&(clearTimeout(this.rejoinTimeout),this.rejoinTimeout=0),Pa.session&&console.log(this.id,"Controller sending JOIN");const{tick:t,delay:e}=this.getTickAndMultiplier(),{name:s,codeHash:i,appId:n,apiKey:o,persistentId:r,developerId:a,heraldUrl:l,rejoinLimit:c,autoSleep:d,computedCodeHash:h,location:u,flags:m}=this.sessionSpec,{apiKey:p}=Ra(o),f=u?[this.viewId]:this.viewId,b={name:s,apiKey:p,appId:n,persistentId:r,url:Pt.referrerURL(),sdk:Wa,developerId:a,version:1,user:f,location:u,ticks:{tick:t,delay:e},dormantDelay:d,tove:this.tove,codeHash:i};l&&Object.assign(b,{heraldUrl:l}),c&&Object.assign(b,{leaveDelay:c+250}),h!==i&&Object.assign(b,{computedCodeHash:h}),m&&Object.assign(b,{flags:m}),this.connection.send(JSON.stringify({id:this.id,action:"JOIN",args:b})),this.syncReceiptTimeout=setTimeout((()=>{delete this.syncReceiptTimeout,this.syncReceived||this.connection.closeConnectionWithError("JOIN",Error("Initial reflector connection timed out"))}),5e3)}clearSyncReceiptTimeout(){this.syncReceiptTimeout&&(clearTimeout(this.syncReceiptTimeout),delete this.syncReceiptTimeout)}connectionInterrupted(){this.syncReceived&&(this.shouldLeaveWhenDisconnected?this.leave():this.rejoinTimeout||(this.rejoinTimeout=setTimeout((()=>{Pa.session&&console.log(this.id,"rejoin timed out"),this.rejoinTimeout=0,this.leave()}),this.sessionSpec.rejoinLimit)))}leave(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const{rebootModelView:e}=this.sessionSpec;if(this.reset(),Pa.session&&console.log(this.id,`resetting ${t?"(but keeping)":"and discarding"} controller`),t||za.delete(this),!this.sessionSpec)throw Error("do not discard sessionSpec!");e()}async encrypt(t){const e=Z.random(16),s=Ln.encrypt(t,this.key,{iv:e}),i=Gn(t,this.key);return`${un.stringify(e)}${un.stringify(i)}${s}`}get deprecatedDefaultKey(){return Ia||(Ia=gn("THIS SHOULDN'T BE IN LOGS","",{keySize:8})),Ia}decrypt(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.key;const s=un.parse(t.slice(0,24)),i=un.parse(t.slice(24,68)),n=t.slice(68),o=Ln.decrypt(n,e,{iv:s});let r="";try{r=pn.stringify(o)}catch(t){}const a=Gn(r,this.key);if(this.compareHmacs(i.words,a.words))return r;if(e!==this.deprecatedDefaultKey)return this.decrypt(t,this.deprecatedDefaultKey);throw Error("Decryption error")}decryptBinary(t,e){const s=(new TextDecoder).decode(new Uint8Array(t,0,4));let i,n,o,r,a;switch("string"==typeof e&&(e=un.parse(e)),s){case"CRQ0":i=(new TextDecoder).decode(t),n=un.parse(i.slice(4,28)),o=un.parse(i.slice(28,72)),r=i.slice(72),a=Ln.decrypt(r,e,{iv:n});break;case"CRQ1":i=new Uint8Array(t),n=Z.create(i.subarray(4,20)),o=Z.create(i.subarray(20,52)),r=Z.create(i.subarray(52)),a=Ln.decrypt({ciphertext:r},e,{iv:n});break;default:throw Error(`${this.id} unknown encryption version ${s}`)}a.clamp();const l=Gn(a,e);if(this.compareHmacs(o.words,l.words))return G(a);if(e!==this.deprecatedDefaultKey)return this.decryptBinary(t,this.deprecatedDefaultKey);throw Error("Decryption error")}async encryptMessage(t,e,s){const[i,n,o]=t.asState();return[i,n,await this.encryptPayload([o,e,s])]}async encryptPayload(t){return this.encrypt(JSON.stringify(t))}decryptPayload(t){return JSON.parse(this.decrypt(t))}compareHmacs(t,e){let s=t.length===e.length;for(let i=0;i16384)return void console.warn(`${this.id} Message with payload of ${e} bytes exceeds maximum 16384 and will not be sent to reflector.`);!this.payloadSizeWarned&&e>4096&&(console.log(`${this.id} Message with payload of ${e} bytes being sent to reflector. Maximum recommended is 4096.`),this.payloadSizeWarned=!0);const s=Date.now(),i=this.rateLimitedSendTimes,n=this.rateLimitBuffer;if(ot.perSecondTally({requestedMessages:1}),n.length)return void this.addToRateLimitBuffer(t);let o=0;if(i.length&&this.synced){const t=i[i.length-1],e=1e3/this.eventRateLimit-(s-t);e>1&&(o=Math.ceil(e))}o?(this.addToRateLimitBuffer(t),setTimeout((()=>this.serviceRateLimitBuffer()),o)):(this.recordRateLimitedSend(s),this.socketSendMessage(t),ot.perSecondTally({sentSingleMessages:1,sentMessagesTotal:1,sentPayloadTotal:e}))}recordRateLimitedSend(t){const e=this.rateLimitedSendTimes;!this.synced&&e.length&&e[e.length-1]===t||(e.push(t),e.length>this.eventHistoryLimit&&e.shift()),!this.rateLimitSoftWarned&&e.length===this.eventHistoryLimit&&t-e[0]<1010&&(console.warn(`${this.id} Sends to reflector are at or above recommended limit of ${this.eventHistoryLimit} within one second. Events will be bundled as necessary to keep to the limit.`),this.rateLimitSoftWarned=!0)}addToRateLimitBuffer(t){ot.perSecondTally({bundledMessages:1});const e=Date.now(),s=t.asState(),i=s[2].length,n=this.rateLimitBuffer;if(n.length){const t=n[n.length-1],{msgStates:o,totalPayload:r}=t;if(r<4096)return o.push({msgState:s,bufferTime:e}),void(t.totalPayload+=i)}ot.perSecondTally({newBundles:1}),n.push({msgStates:[{msgState:s,bufferTime:e}],totalPayload:i});const o=n.length;Pa.session&&o%5==0&&o!==this.rateLimitLastLogged&&(console.log(`${this.id} SEND rate-limit buffer grew to ${o} event bundles (max ${this.eventMaxBundles})`),this.rateLimitLastLogged=o),o>this.eventMaxBundles?(console.error(`${this.id} Disconnecting after overflow of SEND rate-limit buffer.`),this.connection.closeConnectionWithError("SEND",Error("Send rate exceeded"),4200)):!this.rateLimitBufferWarned&&o>this.eventMaxBundles/2&&(console.warn(`${this.id} SEND rate-limit buffer is 50% full. If send rate does not drop, the app will be disconnected.`),this.rateLimitBufferWarned=!0)}serviceRateLimitBuffer(){if(!this.connected)return;const t=this.rateLimitBuffer;if(!t.length)return;const e=Date.now(),s=1e3/this.eventRateLimit,i=this.rateLimitedSendTimes;if(i.length){const t=i[i.length-1];if(s-(e-t)>0)return}const n=t.shift(),{msgStates:o,totalPayload:r}=n,a=[];let l=0;if(o.forEach((t=>{a.push(t.msgState),l+=e-t.bufferTime})),1===a.length){const t=pl.fromState(a[0],this.vm);this.socketSendMessage(t)}else{const t=new pl(this.vm.time,0,"_","handleBundledEvents",[a]);this.socketSendMessage(t)}if(this.recordRateLimitedSend(e),ot.perSecondTally({sentBundles:1,sentMessagesTotal:o.length,sendDelay:l,sentBundlePayload:r,sentPayloadTotal:r}),Pa.session&&this.connected){const e=t.length;e&&e%5==0&&e!==this.rateLimitLastLogged&&(console.log(`${this.id} SEND rate-limit buffer dropped to ${e} event bundles`),this.rateLimitLastLogged=e)}t.length&&setTimeout((()=>this.serviceRateLimitBuffer()),s)}async socketSendMessage(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;const s=await this.encryptMessage(t,this.viewId,Date.now()),i=e?`tagged SEND ${t.asState()} with tags ${JSON.stringify(e)}`:`SEND ${t.asState()}`;if(!this.connected)return void(this.vm&&(Pa.sends&&console.log(this.id,`buffering ${i}`),this.sendBuffer.push((()=>this.socketSendMessage(t,e)))));Pa.sends&&console.log(this.id,`sending ${i}`);const n={id:this.id,action:"SEND",args:[...s,this.latency]};e&&(n.tags=e),this.lastSent=Date.now(),this.connection.send(JSON.stringify(n))}async sendTagged(t,e){this.viewOnly||this.socketSendMessage(t,e)}async sendTutti(t){let{time:e,topic:s,data:i,localContext:n=null,firstMessage:o=null,wantsVote:r=!0,tallyTarget:a=null}=t;if(this.viewOnly)return;const l=o&&await this.encryptMessage(o,this.viewId,Date.now()),c=y(i);if(!this.connected)return void(this.vm&&(Pa.sends&&console.log(this.id,`buffering "${s}" TUTTI ${c} ${o&&o.asState()}`),this.sendBuffer.push((()=>this.sendTutti({time:e,topic:s,data:i,localContext:n,firstMessage:o,wantsVote:r,tallyTarget:a})))));Pa.sends&&console.log(this.id,`sending "${s}" TUTTI ${c} ${o&&o.asState()}`),this.lastSent=Date.now();const d=`${s}@${e}`;this.connection.send(JSON.stringify({id:this.id,action:"TUTTI",args:[e,0,c,l,r,a,d]})),this.tuttiHistory.length>100&&this.tuttiHistory.shift(),this.tuttiHistory.push({time:e,tuttiKey:d,dummyTuttiSeq:0,payload:c,localContext:n})}sendLog(){for(var t=arguments.length,e=new Array(t),s=0;sthis.sendLog(...e))))}addToStatistics(t,e){this.latency=e-t,this.latencyHistory&&(this.latencyHistory.length>=100&&this.latencyHistory.shift(),this.latencyHistory.push({time:e,ms:this.latency}))}get latencies(){return this.latencyHistory||(this.latencyHistory=[]),this.latencyHistory}getTickAndMultiplier(){const t=this.sessionSpec.options,e=["number","string"].includes(typeof t.tps)?t.tps:["number","string"].includes(typeof this.sessionSpec.tps)?this.sessionSpec.tps:20,[s,i]=(e+"x").split("x").map((t=>Number.parseFloat("0"+t))),n=1e3/Math.max(1/30,Math.min(60,s)),o=Math.max(1,i);let r=n,a=0;return o>1&&!Ya&&(r=n/o,a=Math.ceil(r*(o-1))),{msPerTick:r,multiplier:o,tick:n,delay:a}}simulate(t){if(!this.vm)return!0;try{let e=!0;if(this.networkQueue.length+this.vm.messages.size===0)e=this.vm.advanceTo(this.reflectorTime,t);else{const s=ot.begin("simulate");for(;e;){const s=this.networkQueue[0];if(!s)break;if(e=this.vm.advanceTo(s[0],t),!e)break;this.networkQueue.shift();const i=this.vm.scheduleExternalMessage(s);e=this.vm.advanceTo(i.time,t),this.cpuTime+=5}e&&(e=this.vm.advanceTo(this.reflectorTime,t)),this.cpuTime+=Math.max(.01,ot.end("simulate")-s)}ot.backlog(this.backlog);const s=this.lag,i=Math.max(200,.1*this.msPerTick),n=Math.max(2e3,.2*this.msPerTick);if("boolean"==typeof this.synced&&this.viewed&&(this.synced&&s>n||!this.synced&&s{delete this.syncTimer,this.connected&&this.lag5e3&&!Pa.offline&&(this.triggeringCpuTime=this.cpuTime,this.cpuTime=0,this.isBeingAnimated()?setTimeout((()=>this.scheduleSnapshot()),Math.floor(2e3*Math.random())):this.scheduleSnapshot()),e}catch(t){return yt("simulate",t),this.connection.closeConnectionWithError("simulate",t),"error"}}stepSession(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=ot.stepSession(e.frameTime,!0);s&&console.log(s);const{backlog:i,latency:n,starvation:o,activity:r}=this;if("animation"===t){ot.animationFrame(e.frameTime,{backlog:i,starvation:o,latency:n,activity:r,users:this.users});const t=Date.now();if(this.lastAnimationEnd){const e=t-this.lastAnimationEnd;if(!0===this.animationGapCheck&&e>200&&(this.animationGapCheck=[],Pa.session&&console.log(`${this.id} animation has stopped (too long between steps)`)),!0!==this.animationGapCheck){const t=this.animationGapCheck;t.push(e),t.length>4&&t.shift(),4===t.length&&t.reduce(((t,e)=>t+e),0)<=400&&(this.animationGapCheck=!0,Pa.session&&console.log(`${this.id} animation has started`))}}this.lastAnimationEnd=t}if(!this.connected)return void(this.isInBackground()||this.checkForConnection(!0));if(!this.vm)return;let a;switch(t){case"animation":{const t=e.expectedSimFPS,s=Date.now(),i=Ma.reduce(((t,e)=>t+e),0)/Ma.length;if(a=this.simulate(s+Math.min(i,200)),!1===a){const e=0===t?0:1e3/t*4;this.backlog>e&&(a=this.simulate(s+200-i))}"error"!==a&&(Ma.push(Date.now()-s),Ma.length>4&&Ma.shift());break}case"fastForward":case"background":a=this.simulate(Date.now()+e.budget);break;default:console.warn(t)}this.fastForwardHandler&&this.fastForwardHandler(a),"error"!==a&&(ot.begin("update"),this.processModelViewEvents("animation"===t),ot.end("update"),this.serviceRateLimitBuffer(),"animation"===t&&(e.view&&(ot.begin("render"),this.inViewRealm((()=>e.view.update(e.frameTime))),ot.end("render")),this.lastAnimationEnd=Date.now()))}applySyncChange(t){Pa.session&&console.log(this.id,`synced=${t}`),this.synced=t,Pt.showSyncWait(!t),this.vm.publishFromView(this.viewId,"synced",t)}inViewRealm(t){return Ft(this.vm,(()=>t(this.vm)))}processModelViewEvents(t){return this.vm?this.vm.processModelViewEvents(t):0}timeFromReflector(t,e,s){t{this.timeFromReflector(Math.round(t+i*e),"controller"),Pa.ticks&&console.log(this.id,"Controller generate TICK "+this.reflectorTime,i),++i>=s&&(globalThis.clearInterval(this.localTicker),this.localTicker=0)}),e)}startStepping(t){const e=s=>{this.leaving||(this.isOutOfSight()||t(s),window.requestAnimationFrame(e))};window.requestAnimationFrame(e)}setUpActivityChecks(){let t=null;if(this.isOutOfSight=()=>!(Ta||"hidden"!==document.visibilityState&&t),this.isBeingAnimated=()=>{const t=!0===this.animationGapCheck,e=Date.now()-this.lastAnimationEnd<200;return t&&!e&&(this.animationGapCheck=[],Pa.session&&console.log(`${this.id} animation has stopped (too long since last step)`)),t&&e},this.isInBackground=()=>this.isOutOfSight()||!this.isBeingAnimated(),!Ta){new IntersectionObserver(((e,s)=>t=e[0].isIntersecting)).observe(document.body)}const e=this.sessionSpec.autoSleep;let s;if(e){const t=1e3*e;let i=0,n=0;s=()=>{const e=Date.now();e-i<980||(i=e,this.isOutOfSight()?n?e-n>t&&(this.dormantDisconnect(),n=0):n=e:n=0)}}const i=()=>{this.leaving?n&&(clearInterval(n),n=null):this.connected&&this.vm&&(s&&s(),this.isBeingAnimated()||this.connection.keepAlive(Date.now()))};let n=setInterval(i,1e3);this.simulateIfNeeded=()=>{if(!this.isBeingAnimated()&&(i(),!this.fastForwardHandler&&this.connected)){let t=.9*this.msPerTick;e&&(t=Math.min(t,200));const s=this.synced?"background":"fastForward";this.stepSession(s,{budget:t})}}}toString(){return`Controller[${this.id}]`}[Symbol.toPrimitive](){return this.toString()}}class _a{constructor(t){this.controller=t,this.socketLastSent=0,this.connectBlocked=!1,this.connectRestricted=!1,this.connectHasBeenCalled=!1,this.reconnectDelay=0,this.missingTickThreshold=1/0}get id(){return this.controller.id}setTick(t){this.missingTickThreshold=Math.min(3*t,45e3)}get connected(){return!(!this.socket||this.socket.readyState!==WebSocket.OPEN)}checkForConnection(t){this.socket||this.connectHasBeenCalled||this.connectBlocked||this.connectRestricted&&!t||this.connectToReflector()}connectToReflector(){if(this.socket||this.connectHasBeenCalled)return;let t;if(this.connectHasBeenCalled=!0,this.connectBlocked=!1,this.connectRestricted=!1,Pa.offline)t=new Xa;else{let e=Ra(this.controller.sessionSpec.apiKey).reflector;const s=Ta?void 0:window.location.href,i={},n=this.controller.sessionSpec.token;if(n&&(i.token=n),r.reflector){const t=r.reflector.toUpperCase();"CF"===t||t.match(/^[A-Z]{3}$/)?(e=Pa.reflector?"wss://croquet.network/reflector/dev/":"wss://croquet.network/reflector/",3===t.length&&(i.colo=t)):r.reflector.match(/^[-a-z0-9]+$/i)?i.region=r.reflector:e=new URL(r.reflector,s).href.replace(/^http/,"ws")}if(!e.match(/^wss?:/))throw Error("Cannot interpret reflector address "+e);e.endsWith("/")||(e+="/");const o=new URL(e+this.id,s);for(const[t,e]of Object.entries(i))o.searchParams.append(t,e);t=new WebSocket(o)}t.onopen=e=>{const s=this.socket;s&&(s.onopen=s.onmessage=s.onerror=s.onclose=null),this.socket=t,this.connectHasBeenCalled=!1,Pa.session&&console.log(this.id,this.socket.constructor.name,"connected to",this.socket.url),this.reconnectDelay=0,ot.connected(!0),this.controller.sendJoin()},t.onmessage=e=>{ot.addNetworkTraffic("reflector_in",e.data.length),t===this.socket&&this.receive(e.data)},t.onerror=e=>{Pa.session&&console.log(this.id,t.constructor.name,"connection error"),this.connectHasBeenCalled=!1,this.controller.clearSyncReceiptTimeout()},t.onclose=t=>{this.socketClosed(t.code,t.reason)}}socketClosed(t,e){this.controller.clearSyncReceiptTimeout();const s=1e3!==t&&t<4100,i=4110===t;i||1e3===t||this.reconnectDelay||setTimeout((()=>{this.connected||Pt.showMessage(`Connection closed: ${t} ${e}`,{level:s?"error":"fatal"})}),500),Pa.session&&console.log(this.id,`${this.socket?this.socket.constructor.name+" closed":"closed before opening,"} with code: ${t} ${e}`),ot.connected(!1),i?this.connectRestricted=!0:this.connectBlocked=!0,this.disconnected(),s&&(Pa.session&&console.log(this.id,`reconnecting in ${this.reconnectDelay} ms`),this.reconnectTimeout=globalThis.setTimeout((()=>{delete this.reconnectTimeout,this.connectToReflector()}),this.reconnectDelay),this.reconnectDelay=Math.min(3e4,Math.round((this.reconnectDelay+100)*(1+Math.random()))))}disconnected(){this.socket&&(this.socket=null,this.lastReceived=0,this.socketLastSent=0,this.stalledSince=0,this.connectHasBeenCalled=!1,this.controller.connectionInterrupted())}send(t){this.socketLastSent=Date.now(),this.socket.send(t),ot.addNetworkTraffic("reflector_out",t.length)}receive(t){this.lastReceived=Date.now();const{id:e,action:s,args:i}=JSON.parse(t);if(e)try{this.controller.receive(s,i)}catch(t){this.closeConnectionWithError("receive",t)}else if("PONG"===s){if(Pa.pong&&console.log("PONG after",Date.now()-i,"ms"),this.pongHook)try{this.pongHook(i)}catch(t){console.error(t)}}else console.warn("Unknown action",s)}dormantDisconnect(){this.connected&&(Pa.session&&console.log(this.id,"dormant; disconnecting from reflector"),this.closeConnection(4110,"Going dormant"))}closeConnectionWithError(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:4e3;console.error(e),console.warn("closing socket"),s>=4100&&4110!==s&&(this.controller.leaving=()=>{}),this.closeConnection(s,`Error in ${t}: ${e.message||e}`)}closeConnection(t,e){this.socket&&(this.socket.onclose=null,this.socket.close(t,e),this.socketClosed(t,e))}PULSE(t){this.connected&&(0===this.socket.bufferedAmount?(this.send(JSON.stringify({action:"PULSE"})),this.stalledSince=0):this.stalledSince&&t-this.stalledSince>500?console.log(`${this.id} Reflector connection stalled: ${this.socket.bufferedAmount} bytes unsent for ${t-this.stalledSince} ms`):this.stalledSince=Date.now())}keepAlive(t){0!==this.lastReceived&&(t-this.socketLastSent>25e3?this.PULSE(t):t-this.lastReceived>5e4?this.closeConnectionWithError("connection",Error("Reflector has gone away")):t-this.lastReceived>this.missingTickThreshold&&this.PULSE(t))}PING(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Date.now();this.connected&&this.send(JSON.stringify({action:"PING",args:t}))}}globalThis.setInterval((()=>{for(const t of za)t.connected&&t.vm&&t.connection.keepAlive(Date.now())}),100);const ja=Symbol("hash"),Qa=Symbol("key"),Ea=Symbol("url"),Ja=new Map;function Ua(t){return r.has("debug",t,!1)}function Da(t){return t.replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function Oa(t){return t.replace(/-/g,"+").replace(/_/g,"/").padEnd(t.length+3&-4,"=")}function Ba(t,e){return e.replace(/[\s\S]/g,(e=>String.fromCharCode(e.charCodeAt(0)^t.charCodeAt(0))))}class Aa{static async store(t,e){let s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if("object"==typeof t&&(console.warn("Deprecated: Croquet.Data.store(sessionId, data) called without sessionId"),e=t),hl.hasCurrent())throw Error("Croquet.Data.store() called from Model code");const{appId:i,persistentId:n,uploadEncrypted:o}=Na(t),r=Z.random(32).toString(un),a=`apps/${i}/${n}/data/%HASH%`,l=await o({path:a,content:e,key:r,keep:s,debug:Ua("data"),what:"data"}),c=function(t){return t.replace(/.*\//,"")}(l);return new Aa(c,r,l)}static async fetch(t,e){if("object"==typeof t&&(console.warn("Deprecated: Croquet.Data.fetch(sessionId, handle) called without sessionId"),e=t),hl.hasCurrent())throw Error("Croquet.Data.fetch() called from Model code");const{downloadEncrypted:s}=Na(t),i=e&&e[ja],n=e&&e[Qa],o=e&&e[Ea];if("string"!=typeof i||"string"!=typeof n||"string"!=typeof o)throw Error("Croquet.Data.fetch() called with invalid handle");return s({url:o,key:n,debug:Ua("data"),what:"data"})}static hash(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"base64url";"function"==typeof t&&(t=Function.prototype.toString.call(t)),"string"==typeof t?t=(new TextEncoder).encode(t):t&&t.constructor===DataView?t=new Uint8Array(t.buffer,t.byteOffset,t.byteLength):t&&t.constructor===ArrayBuffer?t=new Uint8Array(t):ArrayBuffer.isView(t)||(t=(new TextEncoder).encode(y(t)));const s=v(Z.create(t));switch(e){case"hex":return s.toString();case"base64":return s.toString(un);case"base64url":return Da(s.toString(un));default:throw Error(`Croquet.Data: unknown hash output "${e}", expected "hex"/"base64"/"base64url"`)}}static fromId(t){const e=t.slice(0,1);let s,i,n,o;switch(e){case"0":s=t.slice(1,44),i=t.slice(44),n=`https://files.croquet.io/sessiondata/${s}`;break;case"1":s=t.slice(1,44),i=t.slice(44,87)+"=",o=t.slice(87),n=`https://files.croquet.io/apps/${o}/data/${s}`;break;case"2":s=t.slice(1,44),i=Oa(t.slice(44,87)),o=Ba(i,atob(Oa(t.slice(87)))),n=`https://files.croquet.io/apps/${o}/data/${s}`;break;case"3":i=Oa(t.slice(1,44)),n=Ba(i,atob(Oa(t.slice(44)))),s=n.slice(-43);break;default:throw Error(`Croquet.Data expected handle v0-v3 got v${e}`)}return new this(s,i,n)}static toId(t){if(!t)return"";const e=t[ja],s=t[Qa],i=t[Ea];if(i.slice(-43)!==e)throw Error("Croquet Data: malformed URL");return`3${Da(s)}${Da(btoa(Ba(s,i)))}`}constructor(t,e,s){const i=Ja.get(t);if(i)return Ua("data")&&console.log(`Croquet.Data: using cached handle for ${t}`),i;if(s.slice(-43)!==t)throw Error("Croquet Data: malformed URL");Object.defineProperty(this,ja,{value:t}),Object.defineProperty(this,Qa,{value:e}),Object.defineProperty(this,Ea,{value:s}),Ja.set(t,this),Ua("data")&&console.log(`Croquet.Data: created new handle for ${t}`)}}const $a={cls:Aa,write:t=>Aa.toId(t),read:t=>Aa.fromId(t)};let qa=null,tl=null;class el extends Error{}function sl(){if(!globalThis.CroquetViewMath){globalThis.CroquetMath.random=()=>qa.random(),globalThis.CroquetViewMath={...Math};for(const[t,e]of Object.entries(globalThis.CroquetMath)){const s=Math[t];Math[t]=1===e.length?t=>qa?e(t):s(t):(t,i)=>qa?e(t,i):s(t,i)}}if(!globalThis.CroquetViewDate){const i=globalThis.Date;let n=!1;function o(t,e){return n||(n=!0,console.warn(new el(`${t} used in Model code`))),e}function r(t,e,s,n,a,l,c){const d=this instanceof r,h=[t,e,s,n,a,l,c];if(h.length=arguments.length,qa)switch(o(d?"new Date()":"Date()"),arguments.length){case 0:h.push(qa.time);break;case 1:break;default:h[0]=i.UTC(...h),h.length=1}const u=new i(...h);return d?u:""+u}r.prototype=i.prototype,r.UTC=i.UTC,r.now=()=>qa?o("Date.now()",qa.time):i.now(),r.parse=function(){return qa?o("Date.parse()",0):i.parse(...arguments)},globalThis.CroquetViewDate=i,globalThis.Date=r}}Object.defineProperty(el.prototype,"name",{value:"CroquetWarning"});const il={};function nl(t,e){const{qPara:s,qArgs:i,qFn:n}=JSON.parse(atob(t.slice(1,-1))),o=JSON.stringify(s),r=il[o]||(il[o]=new Function(...s));return"number"==typeof n&&(i[n]=r),r.call(e,...i).bind(e)}function ol(t,e){if(qa)throw Error("VirtualMachine confusion");if(!(t instanceof hl))throw Error("not a VM: "+t);const s=qa;try{qa=t,globalThis.CROQUETVM=t,e()}finally{qa=s}}const rl=["handleModelEventInModel","handleBundledEvents","publishFromModelOnly","handlePollForSnapshot","handleTuttiResult","handleTuttiDivergence","handleSnapshotVote","handlePersistVote","handleModelEventInView","noop"],al={};for(let t=0;t{Nt(this,(()=>{if(this.modelsById={},this.modelsByName={},this.messages=new dn(((t,e)=>t.before(e))),this.subscriptions={},this.subscribers=new Map,this.views={},this._random=()=>{throw Error("You must not use random when applying state!")},this.id=t.id,this.time=0,this.seq=4294967280,this.externalTime=0,this.externalSeq=this.seq,this.futureSeq=0,this.lastSnapshotPoll=0,this.lastPersistencePoll=0,this.inPersistenceCoolOff=!1,this.persisted="",this.modelsId=0,this.controller=null,t.modelsById){const e=wl.newOrRecycled(this).readVM(t,"vm");let s=[];for(const t of Object.keys(e))t in this||"meta"===t?"_random"===t?this[t]=new p(null,{state:e[t]}):"messages"===t?s=e.messages:this[t]=e[t]:console.warn(`Ignoring property snapshot.${t}`);for(const t of s)this.messages.add(t);for(const[t,e]of Object.entries(this.subscriptions))for(const s of e){const[e]=s.split(".");let i=this.subscribers.get(e);i||this.subscribers.set(e,i=new Set),i.add(t)}}else this._random=new p(t.id,{state:!0}),this.addSubscription(this,"__VM__","__peers__",this.generateJoinExit),e(this)}))}))}registerModel(t,e){if(qa!==this)throw Error("You can only create models from model code!");return e||(e="M"+ ++this.modelsId),this.modelsById[e]=t,e}deregisterModel(t){if(qa!==this)throw Error("You can only destroy models from model code!");const e=this.modelsById;delete this.modelsById[t];for(const[t,s]of Object.entries(this.modelsByName))e===s&&delete this.modelsByName[t];this.messages.removeMany((e=>e.hasReceiver(t)))}lookUpModel(t){if("_"===t)return this;let e=this.modelsById[t];if(e)return e;const[s,i,n]=t.match(/^([^#]+)#(.*)$/)||[];return e=this.modelsById[i],e&&e.lookUp(n)}get(t){return this.modelsByName[t]}set(t,e){if(qa!==this)throw Error("You can only make a model well-known from model code!");this.modelsByName[t]=e}noop(){}generateJoinExit(t){let{entered:e,exited:s,count:i}=t;const n={};for(const t of e){if(!Array.isArray(t))continue;const e=t[1]||{};e.region&&(e.country=e.region.slice(0,2),e.region=e.region.slice(2)),n[t[0]]={loc:e}}if(e=e.map((t=>Array.isArray(t)?t[0]:t)),s=s.map((t=>Array.isArray(t)?t[0]:t)),e.length===i){s=Object.keys(this.views);for(const t of s)this.views[t].extraConnections=0}if(0!==e.length&&0!==s.length){const t=e.filter((t=>s.includes(t)));if(0!==t.length&&(e=e.filter((e=>!t.includes(e))),s=s.filter((e=>!t.includes(e))),0===e.length&&0===s.length))return}for(const t of s)if(this.views[t]){if(this.views[t].extraConnections){this.views[t].extraConnections--,tl.session&&console.log(`${this.id} @${this.time}#${this.seq} view ${t} closed extra connection`);continue}delete this.views[t],this.publishFromModelOnly(this.id,"view-exit",t)}else{const{time:e,seq:s}=this;console.error(`${this.id} @${e}#${s} view ${t} exited without being present - this should not happen`),Promise.resolve().then((()=>{this.controller.sendLog(`view-exit-mismatch @${e}#${s} ${t} left without being present`)}))}for(const t of e)this.views[t]?(tl.session&&console.log(`${this.id} @${this.time}#${this.seq} view ${t} opened another connection`),this.views[t].extraConnections=(this.views[t].extraConnections||0)+1):(this.views[t]=n[t]||{},this.publishFromModelOnly(this.id,"view-join",t));const o=Object.values(this.views).reduce(((t,e)=>t+1+(e.extraConnections||0)),0);if(i!==o){const{time:t,seq:e}=this;console.error(`@${t}#${e} view count mismatch (model: ${o}, reflector: ${i}) - this should not happen`),Promise.resolve().then((()=>{this.controller.sendLog(`view-exit-mismatch @${t}#${e} connections model: ${o} reflector: ${i}`)}))}}scheduleExternalMessage(t){const e=pl.fromState(t,this);if(e.time>>0;if(e.seq!==s)throw Error(`External message error. Expected message #${s} got #${e.seq}`);return this.externalTime=e.time,this.externalSeq=e.seq,e.seq=2*e.seq+1,this.verifyExternal(e),this.messages.add(e),e}verifyExternal(t){if("_"!==t.receiver)throw Error(`invalid receiver in external message: ${t}`);if(!(t.selector in al))throw Error(`unexpected external message: ${t.selector}`)}futureSend(t,e,s,i){if(t.every)return this.futureRepeat(t.every,e,s,i);if(t<0)throw Error("attempt to send future message into the past");this.futureSeq=this.futureSeq+1>>>0;const n=new pl(this.time+t,2*this.futureSeq,e,s,i);return this.messages.add(n),{time:n.time,seq:n.seq}}cancelFuture(t,e){const s=this.messages;let i;if("number"==typeof e.time){const{time:t,seq:n}=e;i=s.removeOne((e=>e.time===t&&e.seq===n))}else{if("*"===e)return i=s.removeMany((e=>e.receiver===t.id)),i.length>0;{const n=this.asQFunc(t,e,"cancelFuture message"),o=t.id;i=s.removeOne((t=>t.receiver===o&&t.selector===n||"_"===t.receiver&&"futureExecAndRepeat"===t.selector&&t.args[1]===o&&t.args[2]===n))}}return void 0!==i}futureRepeat(t,e,s,i){this.futureSend(t,"_","futureExecAndRepeat",[t,e,s,i])}futureExecAndRepeat(t,e,s,i){const n=this.lookUpModel(e);if(n){if("function"==typeof n[s])try{n[s](...i)}catch(t){yt(`future message ${n}.${s}`,t)}else{const t=nl(s,n);try{t(...i)}catch(e){yt(`future message ${n} ${t}`,e)}}this.futureRepeat(t,e,s,i)}}future(t,e,s,i){if(!this.lookUpModel(t.id))throw Error(`future send to unregistered model ${t}`);if(void 0===s){const s=this;return new Proxy(t,{get:(i,n)=>function(){for(var i=arguments.length,o=new Array(i),r=0;r>>0,i/2>>>0!==this.seq))throw Error(`Sequence error: expected ${this.seq} got ${i/2>>>0} in ${s}`);if(this.messages.poll(),this.time=s.time,s.executeOn(this),globalThis.CroquetViewDate.now()>=e)return!1}return this.time=t,!0}asQFunc(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"subscription handler";if("string"==typeof e)return e;if("function"==typeof e){if(t[e.name]===e)return e.name;let i=t;for(;null!==i;){for(const[t,s]of Object.entries(Object.getOwnPropertyDescriptors(i)))if(s.value===e)return t;i=Object.getPrototypeOf(i)}ft(`${s} is not a method of ${t}: ${e}\n`,{only:"once"});const n=/^\(?([a-z][a-z0-9]*)?\)? *=> *this\.([a-z][a-z0-9]*) *\( *([a-z][a-z0-9]*)? *\) *$/i,o=e.toString().match(n);return!o||o[3]&&o[3]!==o[1]?function(t,e){"function"==typeof t&&(e=t,t={});const s=Object.keys(t).concat(["return "+e]),i=Object.values(t),n={qPara:s,qArgs:i},o=i.indexOf(e);return o>=0&&(i[o]=s[o],n.qFn=o),`{${btoa(JSON.stringify(n))}}`}(e):o[2]}return null}addSubscription(t,e,s,i){if(qa!==this)throw Error("Cannot add a model subscription from outside model code");const n=this.asQFunc(t,i);if("string"!=typeof n)throw Error(`Subscription handler for "${s}" must be a method name`);if(n.indexOf(".")<0&&"function"!=typeof t[n]&&"{"!==n[0])throw Error(`Subscriber method for "${s}" not found: ${t}.${n}()`);const o=e+":"+s,r=t===this?"_":t.id,a=r+"."+n;if(this.subscriptions[o]){if(-1!==this.subscriptions[o].indexOf(a))throw Error(`${t}.${n} already subscribed to ${s}`)}else this.subscriptions[o]=[];this.subscriptions[o].push(a);let l=this.subscribers.get(r);l||this.subscribers.set(r,l=new Set),l.add(o)}removeSubscription(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"*";if(qa!==this)throw Error("Cannot remove a model subscription from outside model code");const n=e+":"+s,o=this.subscriptions[n];if(o){const e=t.id+".";if("*"===i){for(let t=o.length-1;t>=0;t--)o[t].startsWith(e)&&o.splice(t,1);0===o.length&&delete this.subscriptions[n]}else{const r=this.asQFunc(t,i);if("string"!=typeof r)throw Error(`Invalid unsubscribe args for "${s}" in ${t}: ${i}`);const a=e+r,l=o.indexOf(a);if(-1!==l&&(o.splice(l,1),0===o.length&&delete this.subscriptions[n]),o.find((t=>t.startsWith(e))))return}const r=this.subscribers.get(t.id);r.delete(n),0===r.size&&this.subscribers.delete(t.id)}}removeAllSubscriptionsFor(t){const e=this.subscribers.get(t.id);if(e){const s=t.id+".";for(const t of e){const e=this.subscriptions[t];for(let t=e.length-1;t>=0;t--)e[t].startsWith(s)&&e.splice(t,1);0===e.length&&delete this.subscriptions[t]}this.subscribers.delete(t.id)}}publishFromModel(t,e,s){if(qa!==this)throw Error("Cannot publish a model event from outside model code");const i=e.endsWith("#reflected");i&&(e=e.slice(0,e.length-"#reflected".length));const n=t+":"+e;this.handleModelEventInModel(n,s,i),this.handleModelEventInView(n,s)}publishFromModelOnly(t,e,s){if(qa!==this)throw Error("Cannot publish a model event from outside model code");const i=t+":"+e;this.handleModelEventInModel(i,s)}publishFromView(t,e,s){if(qa)throw Error("Cannot publish a view event from model code");const i=t+":"+e;this.handleViewEventInModel(i,s),this.handleViewEventInView(i,s)}handleBundledEvents(t){for(const e of t){const t=pl.fromState(e,this);this.verifyExternal(t),t.executeOn(this,!0)}}handleModelEventInModel(t,e){let s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(qa!==this)throw Error("handleModelEventInModel called from outside model code");if(s){if(!0!==this.controller.synced)return;const s=t+"#__vote",i=t+"#divergence",n=!!Yt.subscriptions[s],o=!!this.subscriptions[t],r=!!this.subscriptions[i];n&&r&&console.log(`divergence subscription for ${t} overridden by vote subscription`);const a=o?new pl(this.time,0,"_","handleModelEventInModel",[t,e]):null;let l;l=n?["handleModelEventInView",s]:["handleTuttiDivergence",i],Promise.resolve().then((()=>this.controller.sendTutti({time:this.time,topic:t,data:e,firstMessage:a,wantsVote:n,tallyTarget:l})))}else if(this.subscriptions[t]){const s=this.subscriptions[t],i=s.slice();for(let n=0;n=0){const s=l.indexOf("."),i=l.slice(0,s),n=l.slice(s+1);try{c.call(i,n,e)}catch(e){yt(`event ${t} ${c}.call(${JSON.stringify(i)}, ${JSON.stringify(n)})`,e)}}else if("function"==typeof c[l])try{c[l](e)}catch(e){yt(`event ${t} ${c}.${l}()`,e)}else yt(`event ${t} ${c}.${l}(): method not found`);else{const s=nl(l,c);try{s(e)}catch(e){yt(`event ${t} ${c} ${s}`,e)}}else ft(`event ${t} .${l}(): subscriber not found`)}}}handleViewEventInModel(t,e){if(this.subscriptions[t]){const s=[t];void 0!==e&&s.push(e);const i=new pl(this.time,0,"_","handleModelEventInModel",s);this.controller.sendMessage(i)}}handleModelEventInView(t,e){Yt.handleEvent(t,e,(t=>function(t){if(!qa)throw Error("VirtualMachine confusion");const e=qa;try{qa=null,t()}finally{qa=e}}((()=>Ft(this,t,!0)))))}handleViewEventInView(t,e){Yt.handleEvent(t,e)}handleTuttiDivergence(t,e){if(this.subscriptions[t])this.handleModelEventInModel(t,e);else{const s=t.split(":").slice(-1)[0];console.warn(`uncaptured divergence in ${s}:`,e)}}processModelViewEvents(t){if(qa)throw Error("cannot process view events in model code");return Ft(this,(()=>Yt.processFrameEvents(t,!!this.controller.synced)))}handlePollForSnapshot(){const t=this.time,e=t-this.lastSnapshotPoll;e<5e3?console.log(`rejecting snapshot poll ${e}ms after previous`):(this.lastSnapshotPoll=t,this.controller.handlePollForSnapshot(t))}handleTuttiResult(t){this.controller.handleTuttiResult(t)}handleSnapshotVote(t){this.controller.handleSnapshotVote(t)}handlePersistVote(t){this.controller.handlePersistVote(t)}snapshot(){return yl.newOrRecycled(this).snapshot(this,"_")}getSummaryHash(){return y((new bl).getHash(this))}persist(t,e){this.controller&&"no.appId"===this.controller.sessionSpec.appId&&console.warn("Croquet: appId should be provided in Session.join() to not overwrite another apps's persistent data");const s=ot.begin("snapshot"),i="function"==typeof e?e.call(t):e;if("object"!=typeof i)throw Error(`Croquet: persistSession() can only persist objects (got ${typeof i})`);const n=y(i),o=Aa.hash(n),r=ot.end("snapshot")-s,a=this.persisted===o,l=this.time;var c,d;if(tl.snapshot&&console.log(`${this.id} persistent data @${l} collected, stringified and hashed in ${Math.ceil(r)}ms${a?" (unchanged, ignoring)":""}`),!a)if(c=this,d={persistTime:l,persistentString:n,persistentHash:o,ms:r},ll.set(c,d),this.persisted=o,this.inPersistenceCoolOff)tl.snapshot&&console.log(`${this.id} persistence poll postponed by cooloff`);else{const t=this.lastPersistencePoll?this.lastPersistencePoll+25e3-this.time:0;t>0?(tl.snapshot&&console.log(`${this.id} postponing persistence poll by ${t}ms`),this.futureSend(t,"_","triggerPersistencePoll",[]),this.inPersistenceCoolOff=!0):this.triggerPersistencePoll()}}triggerPersistencePoll(){this.inPersistenceCoolOff=!1,this.lastPersistencePoll=this.controller?this.time:0;const t=(e=this,ll.get(e));var e;if(!t)return;const{persistTime:s,persistentString:i,persistentHash:n,ms:o}=t;if(cl(this),this.controller&&this.controller.synced){tl.snapshot&&console.log(`${this.id} asking controller to poll for persistence @${s}`);const t=this.time;Promise.resolve().then((()=>this.controller.pollForPersist(t,s,i,n,o)))}}random(){if(qa!==this)throw Error("synchronized random accessed from outside the model");return this._random()}randomID(){if(qa!==this)throw Error("synchronized random accessed from outside the model");let t="";for(let e=0;e<4;e++)t+=(this._random.int32()>>>0).toString(16).padStart(8,"0");return t}toString(){return`VirtualMachine[${this.id}]`}[Symbol.toPrimitive](){return this.toString()}}function ul(t,e,s){let i;if("_"===t){const t=al[e];"number"==typeof t&&(i=t.toString(36))}if(void 0===i&&(i=`${t}>${e}`),s.length>0){const t=Zl.newOrRecycled();i+=JSON.stringify(t.encode(s))}return i}function ml(t,e){return(e-t|0)>=0}class pl{constructor(t,e,s,i,n){this.time=t,this.seq=e,this.receiver=s,this.selector=i,this.args=n}before(t){return this.time!==t.time?this.time>>0}set externalSeq(t){this.seq=2*t+1}get internalSeq(){return this.seq/2>>>0}set internalSeq(t){this.seq=2*t}asState(){return[this.time,this.seq,ul(this.receiver,this.selector,this.args)]}static fromState(t,e){const[s,i,n]=t,{receiver:o,selector:r,args:a}=function(t,e){let s,i,n;if(1===t.length||"["===t[1]){const e=parseInt(t[0],36);s="_",i=rl[e],n=t.slice(1)}else{const e=t.indexOf(">");let o=t.indexOf("[");-1===o&&(o=t.length),s=t.slice(0,e),i=t.slice(e+1,o),n=t.slice(o)}let o=[];n&&(o=Xl.newOrRecycled(e).decode(JSON.parse(n)));return{receiver:s,selector:i,args:o}}(n,e);return new pl(s,i,o,r,a)}executeOn(t){const e=arguments.length>1&&void 0!==arguments[1]&&arguments[1]?t=>t():e=>ol(t,(()=>Nt(t,e))),{receiver:s,selector:i,args:n}=this,o=t.lookUpModel(s);if(o)if("{"===i[0]){const t=nl(i,o);e((()=>{try{t(...n)}catch(e){yt(`${this.shortString()} ${t}`,e)}}))}else i.indexOf(".")>=0?e((()=>{const t=i.indexOf("."),e=i.slice(0,t),s=i.slice(t+1);try{o.call(e,s,...n)}catch(t){yt(`${this.shortString()} ${o}.call(${JSON.stringify(e)}, ${JSON.stringify(s)})`,t)}})):"function"!=typeof o[i]?ft(`${this.shortString()} ${o}.${i}(): method not found`):e((()=>{try{o[i](...n)}catch(t){yt(`${this.shortString()} ${o}.${i}()`,t)}}));else ft(`${this.shortString()} ${i}(): receiver not found`)}shortString(){return(this.isExternal()?"External":"Future")+"Message"}toString(){const{receiver:t,selector:e,args:s}=this,i=this.isExternal(),n=i?this.externalSeq:this.internalSeq;return`${i?"External":"Future"}Message[${this.time}${":#"[+i]}${n} ${t}.${e}(${s.map(JSON.stringify).join(", ")})]`}[Symbol.toPrimitive](){return this.toString()}}const fl=(()=>{const t=new ArrayBuffer(8),e=new DataView(t);return t=>(e.setFloat64(0,t,!0),e.getInt32(0,!0)+e.getInt32(4,!0))})();class bl{constructor(){this.done=new Set,this.todo=[],this.hashers=new Map,this.addHasher("Teatime:Message",pl),this.addHasher("Teatime:Data",$a);for(const[t,e]of kl.allClassTypes())this.addHasher(t,e)}addHasher(t,e){const{cls:s,write:i}=Object.getPrototypeOf(e)===Object.prototype?e:{cls:e,write:t=>({...t})};this.hashers.set(s,(t=>this.hashStructure(t,i(t))))}getHash(t){this.hashState={oC:0,mC:0,nanC:0,infC:0,zC:0,nC:0,nH:0,sC:0,sL:0,fC:0};for(const[e,s]of Object.entries(t))if("controller"!==e&&"meta"!==e)if("_random"===e)this.hash(s.state(),!1);else if("messages"===e){const t=s.asArray();(this.hashState.fC=t.length)&&this.hash(t,!1)}else this.hashEntry(e,s);return this.hashDeferred(),this.hashState}hashDeferred(){let t=0;for(;t1&&void 0!==arguments[1])||arguments[1];switch(typeof t){case"number":return void(Number.isNaN(t)?this.hashState.nanC++:Number.isFinite(t)?0===t?this.hashState.zC++:(this.hashState.nC++,this.hashState.nH+=fl(t)):this.hashState.infC++);case"string":return this.hashState.sC++,void(this.hashState.sL+=t.length);case"boolean":case"undefined":return;case"bigint":if(0n===t)this.hashState.zC++;else{this.hashState.nC++;const e=t<0?-1n:0n;for(;t!==e;)this.hashState.nH+=Number(0xFFFFFFFFn&t),t>>=32n}return;default:{if(this.done.has(t))return;if(null===t)return;if(this.hashers.has(t.constructor))return void this.hashers.get(t.constructor)(t);const s=Object.prototype.toString.call(t).slice(8,-1);if(this.hashers.has(s))return void this.hashers.get(s)(t);switch(s){case"Array":return void this.hashArray(t,e);case"ArrayBuffer":return void this.hashIntArray(new Uint8Array(t));case"Set":return void this.hashStructure(t,[...t]);case"Map":return void this.hashStructure(t,[...t],!1);case"DataView":return void this.hashIntArray(new Uint8Array(t.buffer,t.byteOffset,t.byteLength));case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":return void this.hashIntArray(t);case"Float32Array":case"Float64Array":return void this.hashArray(t,!1);case"Object":t instanceof kl?this.hashModel(t):t.constructor===Object&&this.hashObject(t,e)}}}}hashModel(t){this.hashState.mC++,this.done.add(t);for(const[e,s]of Object.entries(t))"__realm"!==e&&void 0!==s&&this.hashEntry(e,s)}hashObject(t){let e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];this.hashState.oC++,this.done.add(t);for(const[s,i]of Object.entries(t))void 0!==i&&this.hashEntry(s,i,e)}hashArray(t){let e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];this.done.add(t);for(let s=0;s2&&void 0!==arguments[2])||arguments[2];void 0!==e&&(this.done.add(t),this.hash(e,s))}hashEntry(t,e){let s=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];"$"!==t[0]&&(s&&"object"==typeof e?this.todo.push({key:t,value:e}):this.hash(e,s))}}class yl{static newOrRecycled(t){let e=this.reusableInstance;return e?(e.vm=t,e.nextRef=1,e.refs=new Map,e.todo=[]):e=this.reusableInstance=new this(t),e}static get reusableInstance(){return this[this.name+"-instance"]}static set reusableInstance(t){this[this.name+"-instance"]=t}static resetInstance(){this.reusableInstance=null}constructor(t){this.vm=t,this.nextRef=1,this.refs=new Map,this.todo=[],this.writers=new Map,this.addWriter("Teatime:Message",pl),this.addWriter("Teatime:Data",$a);for(const[t,e]of kl.allClassTypes())this.addWriter(t,e);this.okayToIgnore={};for(const t of kl.allClasses())if(Object.prototype.hasOwnProperty.call(t,"okayToIgnore")){const e=t.okayToIgnore();if(!Array.isArray(e))throw new Error("okayToIgnore() must return an array");for(const t of e){if("$"!==t[0])throw Error(`okayToIgnore: ignored prop "${t}" must start with '$'`);this.okayToIgnore[t]=!0}}}addWriter(t,e){const{cls:s,write:i}=Object.getPrototypeOf(e)===Object.prototype?e:{cls:e,write:t=>({...t})};this.writers.set(s,((e,s)=>this.writeAs(t,e,i(e),s)))}snapshot(t){const e={_random:t._random.state(),messages:this.write(t.messages.asArray(),"vm.messages"),subscribers:void 0,controller:void 0};for(const[s,i]of Object.entries(t))s in e||this.writeInto(e,s,i,`vm.${s}`);return this.writeDeferred(),e}writeDeferred(){let t=0;for(;t2&&void 0!==arguments[2])||arguments[2];switch(typeof t){case"number":return Object.is(t,-0)?{$class:"NegZero"}:Number.isFinite(t)?t:Number.isNaN(t)?{$class:"NaN"}:{$class:"Infinity",$value:Math.sign(t)};case"string":case"boolean":return t;case"undefined":return{$class:"Undefined"};case"bigint":return{$class:"BigInt",$value:t.toString()};default:{if(this.refs.has(t))return this.writeRef(t);if(null===t)return t;if(this.writers.has(t.constructor))return this.writers.get(t.constructor)(t,e);const i=Object.prototype.toString.call(t).slice(8,-1);if(this.writers.has(i))return this.writers.get(i)(t,e);switch(i){case"Array":return this.writeArray(t,e,s);case"ArrayBuffer":return this.writeArrayBuffer(t);case"Set":return this.writeAs(i,t,[...t],e);case"Map":return this.writeAs(i,t,[...t].flat(),e);case"DataView":case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":return this.writeTypedArray(i,t);case"Object":if(t instanceof kl)return this.writeModel(t,e);if(t.constructor===Object||"function"!=typeof t.constructor)return this.writeObject(t,e,s);throw console.error(`Croquet: unknown class at ${e}:`,t),Error(`Croquet: class not registered in Model.types(): ${t.constructor.name}`);default:throw console.error(`Croquet: unsupported property at ${e}:`,t),Error(`Croquet: serialization of ${i}s is not supported`)}}}}writeModel(t,e){const s={};this.refs.set(t,s);try{s.$model=kl.classToID(t.constructor)}catch(s){throw console.error(`unregistered model class at ${e}:`,t),s}for(const i of Object.keys(t).sort()){if("__realm"===i)continue;const n=t[i];("number"==typeof n&&Number.isFinite(n)&&!Object.is(n,-0)||"string"==typeof n||"boolean"==typeof n)&&"$"!==i[0]?s[i]=n:this.writeInto(s,i,n,e)}return s}writeObject(t,e){let s=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];const i={};this.refs.set(t,i);for(const n of Object.keys(t).sort()){const o=t[n];("number"==typeof o&&Number.isFinite(o)&&!Object.is(o,-0)||"string"==typeof o||"boolean"==typeof o)&&"$"!==n[0]?i[n]=o:this.writeInto(i,n,o,e,s)}return i}writeArray(t,e){let s=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];const i=[];this.refs.set(t,i);for(let n=0;n4&&void 0!==arguments[4])||arguments[4];if("$"===e[0])return void(this.okayToIgnore[e]||(ft(`snapshot: ignoring property ${e} (declare as okayToIgnore to suppress warning)`,{only:"once"}),this.okayToIgnore[e]=!0));if(n&&"object"==typeof s)return void this.todo.push({state:t,key:e,value:s,path:i});const o=i+("string"==typeof e&&e.match(/^[_a-z][_a-z0-9]*$/i)?`.${e}`:`[${JSON.stringify(e)}]`),r=this.write(s,o);t[e]=r}}const gl=Symbol("croquet:unresolved");class wl{static newOrRecycled(t){let e=this.reusableInstance;return e?(e.vm=t,e.refs=new Map,e.todo=[],e.unresolved=[],e.postprocess=[]):e=this.reusableInstance=new this(t),e}static get reusableInstance(){return this[this.name+"-instance"]}static set reusableInstance(t){this[this.name+"-instance"]=t}static resetInstance(){this.reusableInstance=null}constructor(t){this.vm=t,this.refs=new Map,this.todo=[],this.unresolved=[],this.postprocess=[],this.readers=new Map,this.addReader("Teatime:Message",pl),this.addReader("Teatime:Data",$a),this.readers.set("Undefined",(()=>{})),this.readers.set("NaN",(()=>NaN)),this.readers.set("Infinity",(t=>t*(1/0))),this.readers.set("NegZero",(()=>-0)),this.readers.set("BigInt",(t=>BigInt(t))),this.readers.set("ArrayBuffer",(t=>function(t){const e=globalThis.atob(t),s=e.length,i=new Uint8Array(s);for(let t=0;tnew DataView(...t))),this.readers.set("Int8Array",(t=>new Int8Array(...t))),this.readers.set("Uint8Array",(t=>new Uint8Array(...t))),this.readers.set("Uint8ClampedArray",(t=>new Uint8ClampedArray(...t))),this.readers.set("Int16Array",(t=>new Int16Array(...t))),this.readers.set("Uint16Array",(t=>new Uint16Array(...t))),this.readers.set("Int32Array",(t=>new Int32Array(...t))),this.readers.set("Uint32Array",(t=>new Uint32Array(...t))),this.readers.set("Float32Array",(t=>new Float32Array(...t))),this.readers.set("Float64Array",(t=>new Float64Array(...t)));for(const[t,e]of kl.allClassTypes())this.addReader(t,e)}addReader(t,e){const s="object"==typeof e?e.read:t=>Object.assign(Object.create(e.prototype),t);this.readers.set(t,s)}readVM(t,e){if("vm"!==e)throw Error("VirtualMachine must be root object");const s=this.read(t,e,!1);return this.readDeferred(),this.resolveRefs(),this.doPostprocess(),s}readDeferred(){let t=0;for(;t2&&void 0!==arguments[2])||arguments[2];switch(typeof t){case"number":case"string":case"boolean":return t;default:{const i=Object.prototype.toString.call(t).slice(8,-1);switch(i){case"Array":return this.readArray(t,e,s);case"Null":return null;case"Object":{const{$class:i,$model:n,$ref:o}=t;if(o)throw Error("refs should have been handled in readInto()");return n?this.readModel(t,e):i?this.readAs(i,t,e):this.readObject(Object,t,e,s)}default:throw Error(`Don't know how to deserialize ${i} at ${e}`)}}}}readModel(t,e){const s=kl.instantiateClassID(t.$model,t.id);t.$id&&this.refs.set(t.$id,s);for(const[i,n]of Object.entries(t))"id"!==i&&"$"!==i[0]&&this.readInto(s,i,n,e);return s}readObject(t,e,s){let i=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];const n=new t;e.$id&&this.refs.set(e.$id,n);for(const[t,o]of Object.entries(e))"$"!==t[0]&&this.readInto(n,t,o,s,i);return n}readArray(t,e){let s=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];const i=[];t.$id&&this.refs.set(t.$id,i);for(let n=0;n2&&void 0!==arguments[2])||arguments[2];const i=t.$value;return t.$id&&(i.$id=t.$id),this.readArray(i,e,s)}readAsSet(t,e){const s=new Set;t.$id&&this.refs.set(t.$id,s);const i=this.unresolved.length,n=this.read(t.$value,e,!1),o=()=>{for(const t of n)s.add(t)};return this.unresolved.length===i?o():this.postprocess.push(o),s}readAsMap(t,e){const s=new Map;t.$id&&this.refs.set(t.$id,s);const i=this.unresolved.length,n=this.read(t.$value,e,!1),o=()=>{for(let t=0;t4&&void 0!==arguments[4])||arguments[4];if(this.readRef(t,e,s,i))return;if(n&&"object"==typeof s)return void this.todo.push({object:t,key:e,value:s,path:i});const o=i+("string"==typeof e&&e.match(/^[_a-z][_a-z0-9]*$/i)?`.${e}`:`[${JSON.stringify(e)}]`);t[e]=this.read(s,o)}}class Zl extends yl{encode(t){const e=this.writeArray(t,"args");return this.writeDeferred(),e}writeModel(t){return{$ref:t.id}}}class Xl extends wl{decode(t){const e=this.readArray(t,"args");return this.readDeferred(),this.resolveRefs(),this.doPostprocess(),e}resolveRefs(){for(const{object:t,key:e,ref:s,path:i}of this.unresolved)if(this.refs.has(s))t[e]=this.refs.get(s);else{const n=this.vm.lookUpModel(s);if(!n)throw Error(`Unresolved ref: ${s} at ${i}[${JSON.stringify(e)}]`);t[e]=n}}}function vl(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:new Set;const n=Object.values(t).filter((t=>{const e=Object.prototype.toString.call(t).slice(8,-1);return("Object"===e||"Array"===e)&&!i.has(t)}));for(const t of n){i.add(t);const n=e+"."+t.constructor.name;if(s[n]){if(s[n]!==t.constructor)throw new Error("Class with name "+n+" already gathered, but new one has different identity")}else s[n]=t.constructor}for(const t of n)vl(t,e,s,i)}function Ll(t){const e=new Uint8Array(t),s=[];for(let t=0;t{T[t].what=`Class ${e}`}))}(this,t),function(t,e){const s=Wl[e];if(s&&s!==t)throw Error(`Registering model class ${t.name} failed, id "${e}" already used by ${s.name}`);Vl(t)?xl&&!s&&console.warn(`ignoring re-exported model class ${e}`):(xl&&console.log(`registering model class ${e}`),t[Tl]=e);Wl[e]=t}(this,t),kl.lastRegistered=this,this}static wellKnownModel(t){if(!hl.hasCurrent())throw Error("static Model.wellKnownModel() called from outside model");return hl.current().get(t)}static evaluate(t){return hl.evaluate(t)}static types(){return{}}static okayToIgnore(){return[]}static classToID(t){return function(t){if(Vl(t))return t[Tl];const e=t.name||"ClassName";throw Error(`Model class not registered, did you call ${e}.register("${e}")?`)}(t)}static classFromID(t){return Pl(t)}static allClasses(){return Cl()}static allClassTypes(){return function(){const t={};for(const e of Cl())Object.assign(t,e.types());return Object.entries(t)}()}static instantiateClassID(t,e){return Pl(t).createNoInit(e)}constructor(t){if(t!==Gl)throw Error('You must create Croquet Models using create() not "new"!')}init(t,e){Sl.delete(this)}destroy(){zt().unsubscribeAll(this),zt().deregister(this)}publish(t,e,s){this.__realm||this.__realmError(),this.__realm.publish(e,s,t)}subscribe(t,e,s){return this.__realm||this.__realmError(),this.__realm.subscribe(this,t,e,s)}unsubscribe(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"*";this.__realm||this.__realmError(),this.__realm.unsubscribe(this,t,e,s)}unsubscribeAll(){this.__realm||this.__realmError(),this.__realm.unsubscribeAll(this)}__realmError(){if(!this.id)throw Error(`${this} has no ID, did you call super.init(options)?`)}future(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1?arguments[1]:void 0;this.__realm||this.__realmError();for(var s=arguments.length,i=new Array(s>2?s-2:0),n=2;n1&&void 0!==arguments[1]?arguments[1]:{};return t&&Pt.showMessage(t,{...e,level:"error"})}(t,e)}constructor(t){"object"==typeof t&&"__realm"in t||console.warn("Croquet: argument to View constructor needs to be a Model");let e=zt("");e&&e.isViewRealm()||(e=Ft(t.__realm.vm,(()=>zt()),!0)),Object.defineProperty(this,"realm",{value:e}),Object.defineProperty(this,"id",{value:e.register(this),configurable:!0});const s=e.vm.controller.session;s.view||(s.view=this)}detach(){this.unsubscribeAll(),this.realm.deregister(this),Object.defineProperty(this,"id",{value:""})}reattach(){Object.defineProperty(this,"id",{value:this.realm.register(this)})}publish(t,e,s){this.realm.publish(e,s,t)}subscribe(t,e,s){"string"==typeof s&&(s=this[s]);const i=s;(s=i.bind(this)).unbound=i;const{event:n,handling:o}=e.event?e:{event:e};this.realm.subscribe(n,this.id,s,t,o)}unsubscribe(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;"string"==typeof s&&(s=this[s]),this.realm.unsubscribe(e,this.id,s,t)}unsubscribeAll(){this.realm.unsubscribeAll(this.id)}future(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return this.realm.future(this,t)}random(){return zt().random()}now(){return this.realm.now()}externalNow(){return this.realm.externalNow()}extrapolatedNow(){return this.realm.extrapolatedNow()}update(t){}wellKnownModel(t){return this.realm.vm.get(t)}get sessionId(){return this.realm.vm.id}get session(){return this.realm.vm.controller.session}get viewId(){return this.realm.vm.controller.viewId}[Symbol.toPrimitive](){const t=this.constructor.name;return t.includes("View")?t:`${t}[View]`}}const Yl=new class{constructor(){this.ready=!1,this.isInIframe=window.top!==window,this.subscriptions={},this.enumerator=null}setReceiver(t){this.receiver=t,this.ready=!0}setIframeEnumerator(t){this.enumerator=t}on(t,e){if(!this.receiver)throw Error("setReceiver() has not been called");if("string"==typeof e&&(e=this.receiver[e]),!e)throw Error("Messenger.on: the second argument must be a method name or a function");if(this.subscriptions[t]){if(this.findIndex(this.subscriptions[t],e)>=0)throw Error(`${e} is already subscribed`)}else this.subscriptions[t]=[];this.subscriptions[t].push(e),this.listener||(this.listener=t=>this.receive(t),window.addEventListener("message",this.listener))}detach(){this.listener&&(window.removeEventListener("message",this.listener),this.listener=null),this.stopPublishingPointerMove(),this.receiver=null,this.subscriptions={},this.enumerator=null,this.ready=!1}removeSubscription(t,e){"string"==typeof e&&(e=this.receiver[e]);const s=this.subscriptions[t];if(s){const i=this.findIndex(s,e);s.splice(i,1),0===s.length&&delete this.subscriptions[t]}}removeAllSubscriptions(){this.subscriptions={}}receive(t){const{event:e,data:s}=t.data,i=t.source;this.handleEvent(e,s,i)}handleEvent(t,e,s){const i=this.subscriptions[t];i&&i.forEach((t=>{t.call(this.receiver,e,s)}))}send(t,e,s){if(this.isInIframe)return void window.top.postMessage({event:t,data:e},"*");if(s)return void s.postMessage({event:t,data:e},"*");if(!this.enumerator)return;this.enumerator().forEach((s=>{s.contentWindow.postMessage({event:t,data:e},"*")}))}findIndex(t,e){const s=e.name;return t.findIndex((t=>{const i=t.name;return s||i?s===i:e===t}))}startPublishingPointerMove(){this._moveHandler||(this._moveHandler=t=>this.send("pointerPosition",{x:t.clientX,y:t.clientY,type:t.type}),window.document.addEventListener("pointermove",this._moveHandler,!0))}stopPublishingPointerMove(){this._moveHandler&&(window.document.removeEventListener("pointermove",this._moveHandler,!0),this._moveHandler=null)}},Ml="node"===e.CROQUET_PLATFORM;let Il=60;class Kl{static async join(t){try{return await this.join_impl(t)}catch(t){throw Pt.showMessage(t.message||t,{level:"fatal"}),t}}static async join_impl(t){if("object"!=typeof t)throw Error("Croquet: please use new Session.join( {apiKey, ...} ) API. See https://croquet.io/docs/croquet/Session.html#.join");t.appId||(t.appId="no.appId"),t.name||(t.name=Pt.autoSession(),t.password||(t.password=Pt.autoPassword())),t.model||(t.model=kl.lastRegistered),t.view||(t.view=Rl);for(const[f,b]of Object.entries(t))b instanceof Promise&&(t[f]=await b);function e(t,e){return t===e||t.prototype instanceof e}if("string"!=typeof t.apiKey)throw Error("Croquet: no apiKey provided in Session.join()!");if(t.apiKey.length>128)throw Error("Croquet: apiKey > 128 characters in Session.join()!");if("string"!=typeof t.name)throw Error("Croquet: no session name provided in Session.join()!");if(t.name.length>128)throw Error("Croquet: session name > 128 characters in Session.join()!");const s=t.model;if("function"!=typeof s||!e(s,kl))throw Error("Croquet: bad model class in Session.join()");const i=t.view||Rl;if("function"!=typeof i||!e(i,Rl))throw Error("Croquet: bad view class in Session.join()");if("string"!=typeof t.appId)throw Error("Croquet: no appId provided in Session.join()");if(!t.appId.length>128)throw Error("Croquet: appId > 128 characters in Session.join()");if(!t.appId.match(/^[a-z](-?[a-z0-9_])*(\.[a-z0-9_](-?[a-z0-9_])*)+$/i))throw Error("Croquet: malformed appId in Session.join()");if("string"!=typeof t.password||!t.password)throw Error("Croquet: no password provided in Session.join()");const n=r.reflector||t.reflector;n&&(r.reflector=n);const o=r.files||t.files;o&&(r.files=o);const a=r.backend||t.backend;if(a&&(r.backend=a),Ml&&"manual"!==t.step)throw Error("stepping must be manual in a Node.js app");if("rejoinLimit"in t){if("number"!=typeof t.rejoinLimit||t.rejoinLimit<0||t.rejoinLimit>6e4)throw Error("rejoinLimit range: 0-60000")}else t.rejoinLimit=1e3;if("eventRateLimit"in t){if("number"!=typeof t.eventRateLimit||t.eventRateLimit<1||t.eventRateLimit>60)throw Error("eventRateLimit range: 1-60")}else t.eventRateLimit=20;if(t.heraldUrl){if(t.heraldUrl.length>256)throw Error("heraldUrl can only be 256 characters");if(!t.heraldUrl.startsWith("https://"))throw Error("heraldUrl needs to be https")}if(t.hashOverride){if(43!==t.hashOverride.length)throw Error("hashOverride must be 43 characters");if(-1!==t.hashOverride.search(/[^-_a-zA-Z0-9]/))throw Error("hashOverride must be base64url encoded")}if(t.debug){function g(t){return"string"==typeof t&&(t=t.split(",")),t?Array.isArray(t)?t:[t]:[]}r.debug=[...g(t.debug),...g(r.debug)].join(",")}if("autoSleep"in t){const w=t.autoSleep,Z=typeof w;if("number"===Z){if(w<0)throw Error("an autoSleep value must be >= 0")}else{if("boolean"!==Z)throw Error("autoSleep must be numeric or boolean");t.autoSleep=w?10:0}}else t.autoSleep=10;if(t.flags){let X=t.flags;"string"==typeof X&&(X=X.split(",")),X=X?Array.isArray(X)?X:[X]:[],X=X.filter((t=>"object"!=typeof t)),X.length?(t.flags={},X.forEach((e=>t.flags[e]=!0))):t.flags=null}"expectedSimFPS"in t&&(Il=Math.min(t.expectedSimFPS,120));const l=["name","password","apiKey","appId","tps","autoSleep","heraldUrl","rejoinLimit","eventRateLimit","optionsFromUrl","viewOptions","viewIdDebugSuffix","hashOverride","location","flags","progressReporter"];!function(){if(Object.isFrozen(Hl))return;zl(Hl),function(t){const e=JSON.stringify(t,((t,e)=>"function"==typeof e?S(e):e));if("{}"===e)return;const s=JSON.parse(e),i=V(y(s));P.push(i),W()&&i.then((t=>{T[t].what="Croquet Constants"}))}(Hl)}();const c=new Fa,d=JSON.parse(JSON.stringify({...t.options})),h={id:"",persistentId:"",versionId:"",name:t.name,model:null,view:null,step(t){c.stepSession("animation",{frameTime:t,view:h.view,expectedSimFPS:Il})},leave:()=>Kl.leave(h.id),get latency(){return c.latency},get latencies(){return c.latencies}},u={options:d,initFn:(t,e)=>s.create(t,e,"modelRoot"),rebootModelView:p};for(const[v,L]of Object.entries(t))l.includes(v)&&(u[v]=L);await c.initFromSessionSpec(u);let m=!1;return await p(),"manual"!==t.step&&c.startStepping(h.step),h;async function p(){!function(){h.model=null,h.view&&(r.has("debug","session",!1)&&console.log(h.id,"detaching root view"),h.view.detach(),""!==h.view.id&&console.warn(`Croquet: ${h.view} did not call super.detach()`),h.view=null);Pt.clearSessionMoniker(),Yl.ready&&Yl.detach()}(),c.leaving?c.leaving(!0):m||(m=!0,await c.establishSession(u),m=!1,h.model=c.vm.get("modelRoot"),h.id=c.id,h.persistentId=c.persistentId,h.versionId=c.versionId,c.session=h,Pt.makeSessionWidgets(h.id),c.inViewRealm((()=>{r.has("debug","session",!1)&&console.log(h.id,"creating root view"),new i(h.model,u.viewOptions)})))}}static async leave(t){const e=function(t){for(const e of za)if(e.id===t)return e;return null}(t);if(!e)return!1;e.reconnectTimeout&&(clearTimeout(e.reconnectTimeout),delete e.reconnectTimeout);const s=new Promise((t=>e.leaving=t)),i=e.connection;return!!i.connected&&(i.closeConnection(1e3),s)}static thisSession(){const t=hl.current();return t?t.id:""}}const Hl={};function zl(t){if(!Object.isFrozen(t)){Object.freeze(t);for(const e of Object.values(t))!e||"object"!=typeof e&&"function"!=typeof e||zl(e)}}exports.App=Pt,exports.Constants=Hl,exports.Data=Aa,exports.Messenger=Yl,exports.Model=kl,exports.Session=Kl,exports.View=Rl,exports.gatherInternalClassTypes=function(t,e){const s={};return vl({root:t},e,s,new Set),s},exports.startSession=function(){return Pt.showMessage("Croquet.startSession() is deprecated, please use Croquet.Session.join()",{level:"warning",only:"once"}),Kl.join(...arguments)}; +if(Object.defineProperty(exports,"__esModule",{value:!0}),void 0===globalThis.TextEncoder){globalThis.TextEncoder=function(){},TextEncoder.prototype.encode=function(t){for(var e=t.length,s=-1,i="undefined"==typeof Uint8Array?new Array(1.5*e):new Uint8Array(3*e),n=0,o=0,r=0;r!==e;){if(n=t.charCodeAt(r),r+=1,n>=55296&&n<=56319){if(r===e){i[s+=1]=239,i[s+=1]=191,i[s+=1]=189;break}if(!((o=t.charCodeAt(r))>=56320&&o<=57343)){i[s+=1]=239,i[s+=1]=191,i[s+=1]=189;continue}if(r+=1,(n=1024*(n-55296)+o-56320+65536)>65535){i[s+=1]=240|n>>>18,i[s+=1]=128|n>>>12&63,i[s+=1]=128|n>>>6&63,i[s+=1]=128|63&n;continue}}n<=127?i[s+=1]=0|n:n<=2047?(i[s+=1]=192|n>>>6,i[s+=1]=128|63&n):(i[s+=1]=224|n>>>12,i[s+=1]=128|n>>>6&63,i[s+=1]=128|63&n)}return"undefined"!=typeof Uint8Array?i.subarray(0,s+1):(i.length=s+1,i)},TextEncoder.prototype.toString=function(){return"[object TextEncoder]"};try{Object.defineProperty(TextEncoder.prototype,"encoding",{get:function(){if(TextEncoder.prototype.isPrototypeOf(this))return"utf-8";throw TypeError("Illegal invocation")}})}catch(t){TextEncoder.prototype.encoding="utf-8"}"undefined"!=typeof Symbol&&(TextEncoder.prototype[Symbol.toStringTag]="TextEncoder")}var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof __webpack_require__.g?__webpack_require__.g:"undefined"!=typeof self?self:{};!function(t){var e=function(t){var e,s=Object.prototype,i=s.hasOwnProperty,n="function"==typeof Symbol?Symbol:{},o=n.iterator||"@@iterator",r=n.asyncIterator||"@@asyncIterator",a=n.toStringTag||"@@toStringTag";function l(t,e,s){return Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{l({},"")}catch(t){l=function(t,e,s){return t[e]=s}}function c(t,e,s,i){var n=e&&e.prototype instanceof b?e:b,o=Object.create(n.prototype),r=new W(i||[]);return o._invoke=function(t,e,s){var i=h;return function(n,o){if(i===m)throw new Error("Generator is already running");if(i===p){if("throw"===n)throw o;return C()}for(s.method=n,s.arg=o;;){var r=s.delegate;if(r){var a=S(r,s);if(a){if(a===f)continue;return a}}if("next"===s.method)s.sent=s._sent=s.arg;else if("throw"===s.method){if(i===h)throw i=p,s.arg;s.dispatchException(s.arg)}else"return"===s.method&&s.abrupt("return",s.arg);i=m;var l=d(t,e,s);if("normal"===l.type){if(i=s.done?p:u,l.arg===f)continue;return{value:l.arg,done:s.done}}"throw"===l.type&&(i=p,s.method="throw",s.arg=l.arg)}}}(t,s,r),o}function d(t,e,s){try{return{type:"normal",arg:t.call(e,s)}}catch(t){return{type:"throw",arg:t}}}t.wrap=c;var h="suspendedStart",u="suspendedYield",m="executing",p="completed",f={};function b(){}function y(){}function g(){}var w={};l(w,o,(function(){return this}));var Z=Object.getPrototypeOf,v=Z&&Z(Z(T([])));v&&v!==s&&i.call(v,o)&&(w=v);var X=g.prototype=b.prototype=Object.create(w);function L(t){["next","throw","return"].forEach((function(e){l(t,e,(function(t){return this._invoke(e,t)}))}))}function x(t,e){function s(n,o,r,a){var l=d(t[n],t,o);if("throw"!==l.type){var c=l.arg,h=c.value;return h&&"object"==typeof h&&i.call(h,"__await")?e.resolve(h.__await).then((function(t){s("next",t,r,a)}),(function(t){s("throw",t,r,a)})):e.resolve(h).then((function(t){c.value=t,r(c)}),(function(t){return s("throw",t,r,a)}))}a(l.arg)}var n;this._invoke=function(t,i){function o(){return new e((function(e,n){s(t,i,e,n)}))}return n=n?n.then(o,o):o()}}function S(t,s){var i=t.iterator[s.method];if(i===e){if(s.delegate=null,"throw"===s.method){if(t.iterator.return&&(s.method="return",s.arg=e,S(t,s),"throw"===s.method))return f;s.method="throw",s.arg=new TypeError("The iterator does not provide a 'throw' method")}return f}var n=d(i,t.iterator,s.arg);if("throw"===n.type)return s.method="throw",s.arg=n.arg,s.delegate=null,f;var o=n.arg;return o?o.done?(s[t.resultName]=o.value,s.next=t.nextLoc,"return"!==s.method&&(s.method="next",s.arg=e),s.delegate=null,f):o:(s.method="throw",s.arg=new TypeError("iterator result is not an object"),s.delegate=null,f)}function G(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function k(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function W(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(G,this),this.reset(!0)}function T(t){if(t){var s=t[o];if(s)return s.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,r=function s(){for(;++n=0;--o){var r=this.tryEntries[o],a=r.completion;if("root"===r.tryLoc)return n("end");if(r.tryLoc<=this.prev){var l=i.call(r,"catchLoc"),c=i.call(r,"finallyLoc");if(l&&c){if(this.prev=0;--s){var n=this.tryEntries[s];if(n.tryLoc<=this.prev&&i.call(n,"finallyLoc")&&this.prev=0;--e){var s=this.tryEntries[e];if(s.finallyLoc===t)return this.complete(s.completion,s.afterLoc),k(s),f}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var s=this.tryEntries[e];if(s.tryLoc===t){var i=s.completion;if("throw"===i.type){var n=i.arg;k(s)}return n}}throw new Error("illegal catch attempt")},delegateYield:function(t,s,i){return this.delegate={iterator:T(t),resultName:s,nextLoc:i},"next"===this.method&&(this.arg=e),f}},t}(t.exports);try{globalThis.regeneratorRuntime=e}catch(t){"object"==typeof globalThis?globalThis.regeneratorRuntime=e:Function("r","regeneratorRuntime = r")(e)}}({exports:{}});const e={CROQUET_VERSION:"1.1.0-38"},s=window.location.hostname.endsWith("croquet.studio");let i="",n="";function o(t,e){if(e)for(const s of e.split("&")){const e=s.split("="),i=e[0];let n=!0;if(e.length>1&&(n=decodeURIComponent(e.slice(1).join("=")),n.match(/^(true|false|null|[0-9.]*|["[{].*)$/)))try{n=JSON.parse(n)}catch(t){"["===n[0]&&(n=n.slice(1,-1).split(","))}t[i]=n}}const r=new class{constructor(){this.getSession(),o(this,window.location.search.slice(1)),o(this,s?window.location.hash.slice(1):n),window.location.pathname.indexOf("/ar.html")>=0&&(this.ar=!0)}has(t,e,s){"boolean"!=typeof s&&(s=this.isHost(s));const i=this[t];if("string"!=typeof i)return s;const n=i.split(",");return!0===s&&(e=`no${e}`),e.endsWith("s")&&(e=e.slice(0,-1)),n.includes(e)||n.includes(`${e}s`)?!s:s}getSession(){if(s){const t=/^\/([^/]+)\/(.*)$/,e=window.location.pathname.match(t);if(e)return i=e[1],e[2]}else{const t=/^#([^&]+)&?(.*)$/,e=window.location.hash.match(t);if(e)return e[1].includes("=")?(n=`${e[1]}&${e[2]}`,""):(n=e[2],e[1])}return"string"==typeof this.session?(n=window.location.hash.slice(1),this.session):""}setSession(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];null==s&&this.getSession();const{search:o,hash:r}=window.location,a=s?`/${i}/${t}${o}${r}`:`#${t}${n?"&"+n:""}`;e?window.history.replaceState({},"",a):window.history.pushState({},"",a)}isHost(t){const e=window.location.hostname;if(e===t)return!0;if("localhost"!==t)return!1;if(e.endsWith(".ngrok.io"))return!0;if(e.endsWith("croquet.dev"))return!0;if("croquet.io"===e){if(window.location.pathname.match(/^\/(dev|files)\//))return!0}return"file:"===window.location.protocol||["127.0.0.1","[::1]"].includes(e)}isLocalhost(){return this.isHost("localhost")}};var a,l,c,d={exports:{}};l=t,c=function(t){var e=function(t){return new e.lib.init(t)};function s(t,e){return e.offset[t]?isNaN(e.offset[t])?e.offset[t]:e.offset[t]+"px":"0px"}function i(t,e){return!(!t||"string"!=typeof e||!(t.className&&t.className.trim().split(/\s+/gi).indexOf(e)>-1))}return e.defaults={oldestFirst:!0,text:"Toastify is awesome!",node:void 0,duration:3e3,selector:void 0,callback:function(){},destination:void 0,newWindow:!1,close:!1,gravity:"toastify-top",positionLeft:!1,position:"",backgroundColor:"",avatar:"",className:"",stopOnFocus:!0,onClick:function(){},offset:{x:0,y:0},escapeMarkup:!0,style:{background:""}},e.lib=e.prototype={toastify:"1.11.2",constructor:e,init:function(t){return t||(t={}),this.options={},this.toastElement=null,this.options.text=t.text||e.defaults.text,this.options.node=t.node||e.defaults.node,this.options.duration=0===t.duration?0:t.duration||e.defaults.duration,this.options.selector=t.selector||e.defaults.selector,this.options.callback=t.callback||e.defaults.callback,this.options.destination=t.destination||e.defaults.destination,this.options.newWindow=t.newWindow||e.defaults.newWindow,this.options.close=t.close||e.defaults.close,this.options.gravity="bottom"===t.gravity?"toastify-bottom":e.defaults.gravity,this.options.positionLeft=t.positionLeft||e.defaults.positionLeft,this.options.position=t.position||e.defaults.position,this.options.backgroundColor=t.backgroundColor||e.defaults.backgroundColor,this.options.avatar=t.avatar||e.defaults.avatar,this.options.className=t.className||e.defaults.className,this.options.stopOnFocus=void 0===t.stopOnFocus?e.defaults.stopOnFocus:t.stopOnFocus,this.options.onClick=t.onClick||e.defaults.onClick,this.options.offset=t.offset||e.defaults.offset,this.options.escapeMarkup=void 0!==t.escapeMarkup?t.escapeMarkup:e.defaults.escapeMarkup,this.options.style=t.style||e.defaults.style,t.backgroundColor&&(this.options.style.background=t.backgroundColor),this},buildToast:function(){if(!this.options)throw"Toastify is not initialized";var t=document.createElement("div");for(var e in t.className="toastify on "+this.options.className,this.options.position?t.className+=" toastify-"+this.options.position:!0===this.options.positionLeft?(t.className+=" toastify-left",console.warn("Property `positionLeft` will be depreciated in further versions. Please use `position` instead.")):t.className+=" toastify-right",t.className+=" "+this.options.gravity,this.options.backgroundColor&&console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.'),this.options.style)t.style[e]=this.options.style[e];if(this.options.node&&this.options.node.nodeType===Node.ELEMENT_NODE)t.appendChild(this.options.node);else if(this.options.escapeMarkup?t.innerText=this.options.text:t.innerHTML=this.options.text,""!==this.options.avatar){var i=document.createElement("img");i.src=this.options.avatar,i.className="toastify-avatar","left"==this.options.position||!0===this.options.positionLeft?t.appendChild(i):t.insertAdjacentElement("afterbegin",i)}if(!0===this.options.close){var n=document.createElement("span");n.innerHTML="✖",n.className="toast-close",n.addEventListener("click",function(t){t.stopPropagation(),this.removeElement(this.toastElement),window.clearTimeout(this.toastElement.timeOutValue)}.bind(this));var o=window.innerWidth>0?window.innerWidth:screen.width;("left"==this.options.position||!0===this.options.positionLeft)&&o>360?t.insertAdjacentElement("afterbegin",n):t.appendChild(n)}if(this.options.stopOnFocus&&this.options.duration>0){var r=this;t.addEventListener("mouseover",(function(e){window.clearTimeout(t.timeOutValue)})),t.addEventListener("mouseleave",(function(){t.timeOutValue=window.setTimeout((function(){r.removeElement(t)}),r.options.duration)}))}if(void 0!==this.options.destination&&t.addEventListener("click",function(t){t.stopPropagation(),!0===this.options.newWindow?window.open(this.options.destination,"_blank"):window.location=this.options.destination}.bind(this)),"function"==typeof this.options.onClick&&void 0===this.options.destination&&t.addEventListener("click",function(t){t.stopPropagation(),this.options.onClick()}.bind(this)),"object"==typeof this.options.offset){var a=s("x",this.options),l=s("y",this.options),c="left"==this.options.position?a:"-"+a,d="toastify-top"==this.options.gravity?l:"-"+l;t.style.transform="translate("+c+","+d+")"}return t},showToast:function(){var t;if(this.toastElement=this.buildToast(),!(t="string"==typeof this.options.selector?document.getElementById(this.options.selector):this.options.selector instanceof HTMLElement||"undefined"!=typeof ShadowRoot&&this.options.selector instanceof ShadowRoot?this.options.selector:document.body))throw"Root element is not defined";var s=e.defaults.oldestFirst?t.firstChild:t.lastChild;return t.insertBefore(this.toastElement,s),e.reposition(),this.options.duration>0&&(this.toastElement.timeOutValue=window.setTimeout(function(){this.removeElement(this.toastElement)}.bind(this),this.options.duration)),this},hideToast:function(){this.toastElement.timeOutValue&&clearTimeout(this.toastElement.timeOutValue),this.removeElement(this.toastElement)},removeElement:function(t){t.className=t.className.replace(" on",""),window.setTimeout(function(){this.options.node&&this.options.node.parentNode&&this.options.node.parentNode.removeChild(this.options.node),t.parentNode&&t.parentNode.removeChild(t),this.options.callback.call(t),e.reposition()}.bind(this),400)}},e.reposition=function(){for(var t,e={top:15,bottom:15},s={top:15,bottom:15},n={top:15,bottom:15},o=document.getElementsByClassName("toastify"),r=0;r0?window.innerWidth:screen.width)<=360?(o[r].style[t]=n[t]+"px",n[t]+=a+15):!0===i(o[r],"toastify-left")?(o[r].style[t]=e[t]+"px",e[t]+=a+15):(o[r].style[t]=s[t]+"px",s[t]+=a+15)}return this},e.lib.init.prototype=e.lib,e},(a=d).exports?a.exports=c():l.Toastify=c();var h=d.exports,u={exports:{}};!function(e){!function(t,s,i){var n,o=256,r=i.pow(o,6),a=i.pow(2,52),l=2*a,c=255;function d(e,c,d){var b=[],y=p(m((c=1==c?{entropy:!0}:c||{}).entropy?[e,f(s)]:null==e?function(){try{var e;return n&&(e=n.randomBytes)?e=e(o):(e=new Uint8Array(o),(t.crypto||t.msCrypto).getRandomValues(e)),f(e)}catch(e){var i=t.navigator,r=i&&i.plugins;return[+new Date,t,r,t.screen,f(s)]}}():e,3),b),g=new h(b),w=function(){for(var t=g.g(6),e=r,s=0;t=l;)t/=2,e/=2,s>>>=1;return(t+s)/e};return w.int32=function(){return 0|g.g(4)},w.quick=function(){return g.g(4)/4294967296},w.double=w,p(f(g.S),s),(c.pass||d||function(t,e,s,n){return n&&(n.S&&u(n,g),t.state=function(){return u(g,{})}),s?(i.random=t,e):t})(w,y,"global"in c?c.global:this==i,c.state)}function h(t){var e,s=t.length,i=this,n=0,r=i.i=i.j=0,a=i.S=[];for(s||(t=[s++]);n65536?(n[0]=240|(1835008&o)>>>18,n[1]=128|(258048&o)>>>12,n[2]=128|(4032&o)>>>6,n[3]=128|63&o):o>2048?(n[0]=224|(61440&o)>>>12,n[1]=128|(4032&o)>>>6,n[2]=128|63&o):o>128?(n[0]=192|(1984&o)>>>6,n[1]=128|63&o):n[0]=o,this.parsedData.push(n)}this.parsedData=Array.prototype.concat.apply([],this.parsedData),this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function e(t,e){this.typeNumber=t,this.errorCorrectLevel=e,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}t.prototype={getLength:function(t){return this.parsedData.length},write:function(t){for(var e=0,s=this.parsedData.length;e=7&&this.setupTypeNumber(t),null==this.dataCache&&(this.dataCache=e.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,s)},setupPositionProbePattern:function(t,e){for(var s=-1;s<=7;s++)if(!(t+s<=-1||this.moduleCount<=t+s))for(var i=-1;i<=7;i++)e+i<=-1||this.moduleCount<=e+i||(this.modules[t+s][e+i]=0<=s&&s<=6&&(0==i||6==i)||0<=i&&i<=6&&(0==s||6==s)||2<=s&&s<=4&&2<=i&&i<=4)},getBestMaskPattern:function(){for(var t=0,e=0,s=0;s<8;s++){this.makeImpl(!0,s);var i=u.getLostPoint(this);(0==s||t>i)&&(t=i,e=s)}return e},createMovieClip:function(t,e,s){var i=t.createEmptyMovieClip(e,s);this.make();for(var n=0;n>s&1);this.modules[Math.floor(s/3)][s%3+this.moduleCount-8-3]=i}for(s=0;s<18;s++){i=!t&&1==(e>>s&1);this.modules[s%3+this.moduleCount-8-3][Math.floor(s/3)]=i}},setupTypeInfo:function(t,e){for(var s=this.errorCorrectLevel<<3|e,i=u.getBCHTypeInfo(s),n=0;n<15;n++){var o=!t&&1==(i>>n&1);n<6?this.modules[n][8]=o:n<8?this.modules[n+1][8]=o:this.modules[this.moduleCount-15+n][8]=o}for(n=0;n<15;n++){o=!t&&1==(i>>n&1);n<8?this.modules[8][this.moduleCount-n-1]=o:n<9?this.modules[8][15-n-1+1]=o:this.modules[8][15-n-1]=o}this.modules[this.moduleCount-8][8]=!t},mapData:function(t,e){for(var s=-1,i=this.moduleCount-1,n=7,o=0,r=this.moduleCount-1;r>0;r-=2)for(6==r&&r--;;){for(var a=0;a<2;a++)if(null==this.modules[i][r-a]){var l=!1;o>>n&1)),u.getMask(e,i,r-a)&&(l=!l),this.modules[i][r-a]=l,-1==--n&&(o++,n=7)}if((i+=s)<0||this.moduleCount<=i){i-=s,s=-s;break}}}},e.PAD0=236,e.PAD1=17,e.createData=function(t,s,i){for(var n=y.getRSBlocks(t,s),o=new g,r=0;r8*l)throw new Error("code length overflow. ("+o.getLengthInBits()+">"+8*l+")");for(o.getLengthInBits()+4<=8*l&&o.put(0,4);o.getLengthInBits()%8!=0;)o.putBit(!1);for(;!(o.getLengthInBits()>=8*l||(o.put(e.PAD0,8),o.getLengthInBits()>=8*l));)o.put(e.PAD1,8);return e.createBytes(o,n)},e.createBytes=function(t,e){for(var s=0,i=0,n=0,o=new Array(e.length),r=new Array(e.length),a=0;a=0?m.get(p):0}}var f=0;for(d=0;d=0;)e^=u.G15<=0;)e^=u.G18<>>=1;return e},getPatternPosition:function(t){return u.PATTERN_POSITION_TABLE[t-1]},getMask:function(t,e,s){switch(t){case n:return(e+s)%2==0;case o:return e%2==0;case r:return s%3==0;case a:return(e+s)%3==0;case l:return(Math.floor(e/2)+Math.floor(s/3))%2==0;case c:return e*s%2+e*s%3==0;case d:return(e*s%2+e*s%3)%2==0;case h:return(e*s%3+(e+s)%2)%2==0;default:throw new Error("bad maskPattern:"+t)}},getErrorCorrectPolynomial:function(t){for(var e=new b([1],0),s=0;s5&&(s+=3+o-5)}for(i=0;i=256;)t-=255;return p.EXP_TABLE[t]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},f=0;f<8;f++)p.EXP_TABLE[f]=1<>>7-t%8&1)},put:function(t,e){for(var s=0;s>>e-s-1&1))},getLengthInBits:function(){return this.length},putBit:function(t){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),t&&(this.buffer[e]|=128>>>this.length%8),this.length++}};var w=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],Z=function(){var t=function(t,e){this._bIsPainted=!1,this._htOption=e,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=e.width,this._elCanvas.height=e.height,t.appendChild(this._elCanvas),this._el=t,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._bSupportDataURI=null};return t.prototype.draw=function(t){var e=this._oContext,s=this._htOption,i=t.getModuleCount(),n=s.width/i,o=s.height/i,r=Math.round(n),a=Math.round(o);this.clear();for(var l=0;lw.length)throw new Error("Too long data");return s}m=function(t,e){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:i.H},"string"==typeof e&&(e={text:e}),e)for(var s in e)this._htOption[s]=e[s];"string"==typeof t&&(t=document.getElementById(t)),this._htOption.useSVG&&(Z=svgDrawer),this._el=t,this._oQRCode=null,this._oDrawing=new Z(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},m.prototype.makeCode=function(t){this._oQRCode=new e(v(t,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(t),this._oQRCode.make(),this._oDrawing.draw(this._oQRCode)},m.prototype.clear=function(){this._oDrawing.clear()},m.prototype.getCanvas=function(){for(let t=0;t>>2]>>>24-o%4*8&255;e[i+o>>>2]|=r<<24-(i+o)%4*8}else for(var a=0;a>>2]=s[a>>>2];return this.sigBytes+=n,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var t=l.clone.call(this);return t.words=this.words.slice(0),t},random:function(t){for(var e=[],s=0;s>>2]>>>24-n%4*8&255;i.push((o>>>4).toString(16)),i.push((15&o).toString(16))}return i.join("")},parse:function(t){for(var e=t.length,s=[],i=0;i>>3]|=parseInt(t.substr(i,2),16)<<24-i%8*4;return new c.init(s,e/2)}},u=d.Latin1={stringify:function(t){for(var e=t.words,s=t.sigBytes,i=[],n=0;n>>2]>>>24-n%4*8&255;i.push(String.fromCharCode(o))}return i.join("")},parse:function(t){for(var e=t.length,s=[],i=0;i>>2]|=(255&t.charCodeAt(i))<<24-i%4*8;return new c.init(s,e)}},m=d.Utf8={stringify:function(t){try{return decodeURIComponent(escape(u.stringify(t)))}catch(t){throw new Error("Malformed UTF-8 data")}},parse:function(t){return u.parse(unescape(encodeURIComponent(t)))}},p=a.BufferedBlockAlgorithm=l.extend({reset:function(){this._data=new c.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=m.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(t){var s,i=this._data,n=i.words,o=i.sigBytes,r=this.blockSize,a=o/(4*r),l=(a=t?e.ceil(a):e.max((0|a)-this._minBufferSize,0))*r,d=e.min(4*l,o);if(l){for(var h=0;h>>2]|=t[n]<<24-n%4*8;s.call(this,i,e)}else s.apply(this,arguments)};i.prototype=e}}(),t.lib.WordArray}(w.exports),v={exports:{}},X=v.exports=function(t){return function(e){var s=t,i=s.lib,n=i.WordArray,o=i.Hasher,r=s.algo,a=[],l=[];!function(){function t(t){for(var s=e.sqrt(t),i=2;i<=s;i++)if(!(t%i))return!1;return!0}function s(t){return 4294967296*(t-(0|t))|0}for(var i=2,n=0;n<64;)t(i)&&(n<8&&(a[n]=s(e.pow(i,.5))),l[n]=s(e.pow(i,1/3)),n++),i++}();var c=[],d=r.SHA256=o.extend({_doReset:function(){this._hash=new n.init(a.slice(0))},_doProcessBlock:function(t,e){for(var s=this._hash.words,i=s[0],n=s[1],o=s[2],r=s[3],a=s[4],d=s[5],h=s[6],u=s[7],m=0;m<64;m++){if(m<16)c[m]=0|t[e+m];else{var p=c[m-15],f=(p<<25|p>>>7)^(p<<14|p>>>18)^p>>>3,b=c[m-2],y=(b<<15|b>>>17)^(b<<13|b>>>19)^b>>>10;c[m]=f+c[m-7]+y+c[m-16]}var g=i&n^i&o^n&o,w=(i<<30|i>>>2)^(i<<19|i>>>13)^(i<<10|i>>>22),Z=u+((a<<26|a>>>6)^(a<<21|a>>>11)^(a<<7|a>>>25))+(a&d^~a&h)+l[m]+c[m];u=h,h=d,d=a,a=r+Z|0,r=o,o=n,n=i,i=Z+(w+g)|0}s[0]=s[0]+i|0,s[1]=s[1]+n|0,s[2]=s[2]+o|0,s[3]=s[3]+r|0,s[4]=s[4]+a|0,s[5]=s[5]+d|0,s[6]=s[6]+h|0,s[7]=s[7]+u|0},_doFinalize:function(){var t=this._data,s=t.words,i=8*this._nDataBytes,n=8*t.sigBytes;return s[n>>>5]|=128<<24-n%32,s[14+(n+64>>>9<<4)]=e.floor(i/4294967296),s[15+(n+64>>>9<<4)]=i,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var t=o.clone.call(this);return t._hash=this._hash.clone(),t}});s.SHA256=o._createHelper(d),s.HmacSHA256=o._createHmacHelper(d)}(Math),t.SHA256}(w.exports);const L="node"===e.CROQUET_PLATFORM;let x;function S(t){const e=t.sigBytes,s=t.words,i=new Uint8Array(e);let n=0,o=0;for(;n>>24,n===e)break;if(i[n++]=(16711680&t)>>>16,n===e)break;if(i[n++]=(65280&t)>>>8,n===e)break;i[n++]=255&t}return i}function G(t){function e(t){const e=t.indexOf("{"),s=t.lastIndexOf("}");if(-1===e||-1===s||s`${t}:${e(""+i[t])}`)).join(""))}return s}function k(t){return btoa(String.fromCharCode(...new Uint8Array(t))).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function W(){return r.has("debug","hashing",!1)}x=globalThis.crypto&&globalThis.crypto.subtle&&"function"==typeof globalThis.crypto.subtle.digest?globalThis.crypto.subtle.digest.bind(globalThis.crypto.subtle):(t,e)=>{if("SHA-256"!==t)throw Error("Croquet: only SHA-256 available");const s=Z.create(e);return S(X(s)).buffer};let T={};const C=new TextEncoder;async function V(t){const e=C.encode(t),s=await async function(t){return 0===t.length?"47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU":k(await x("SHA-256",t))}(e);return T[s]={string:t,buffer:e},s}const P=[],R={};const Y=new Set;const M=Date.now();"undefined"==typeof performance&&(window.performance={now:()=>Date.now()-M});const I=["simulate","update","render","snapshot"],H={total:"black",update:"blue",render:"magenta",simulate:"yellow",snapshot:"green",backlog:"red",network:"lightgray"};let K,z,N=null,F=null,_=null,j=0,E=null,Q=null;function J(t){for(N=t;t.firstChild;)t.removeChild(t.firstChild);t.style.background="#faf0dc",E=document.createElement("canvas"),Q=E.getContext("2d"),E.id="text_stats",E.width=Math.min(140,window.innerWidth),E.height=36,E.style.width=E.width,E.style.height=E.height,Q.font="9.5pt sans-serif",t.appendChild(E),t.title=Object.entries(H).map((t=>{let[e,s]=t;return`${s}: ${e}`})).join("\n"),F=document.createElement("canvas"),F.width=Math.min(125,window.innerWidth),F.height=125,F.style.width="100%";const e=document.createElement("div");e.id="innerDiv",t.appendChild(e),e.appendChild(F),_=F.getContext("2d")}const U=[];let D=0,O=!1,B=tt(0);const A=1e3/60;function $(t){return 20*(1-t/A)+60}function q(t){K=function(t){const e=document.createElement("canvas");return e.width=t.width,e.height=t.height,e.style.width="100%",e.style.position="absolute",e.style.left="0px",N.querySelector("#innerDiv").appendChild(e),e}(t),z=K.getContext("2d"),z.strokeStyle="rgba(255, 255, 255, 0.5)";for(let t=0;t<60;t+=A){const e=$(t);z.moveTo(0,e),z.lineTo(K.width,e),z.stroke()}}function tt(t){return{start:t,total:0,items:{},users:0,backlog:0,network:0,latency:0,activity:1e3,connected:O}}function et(t){B.total=t-B.start;const e=Math.min(120,window.innerWidth);if(U.length>=e&&U.splice(0,U.length-e+1),U.push(B),U.length<=1)return;if(!N)return;if(0===N.offsetHeight)return;const s=U.slice(1).filter((t=>t.total)),i=s.map((t=>t.total)).reduce(((t,e)=>t+e),0)/s.length,n=Math.max(...s.map((t=>t.total)));Math.max(...s.map((t=>Math.max(t.backlog,t.network)))),D=1e3,function(t,e){Q.globalCompositeOperation="copy",Q.fillStyle="rgb(255, 255, 255, 0)",Q.fillRect(0,0,E.width,E.height),Q.fillStyle="rgb(0, 0, 0, 1)",Q.globalCompositeOperation="source-over";let s=`${B.users} users, ${Math.round(1e3/t)} fps`;e>70&&(s+=` ${Math.ceil(e).toLocaleString()}ms`),Q.fillText(s,2,15),s=B.backlog<100&&B.activity<1e3?`latency: ${B.latency} ms`:`backlog: ${B.backlog<100?"0.0":(B.backlog/1e3).toFixed(1)} s`,Q.fillText(s,2,33)}(i,n),K||q(F),j===F.width?(_.globalCompositeOperation="copy",_.drawImage(F,1,0,F.width-1,F.height,0,0,F.width-1,F.height),_.globalCompositeOperation="source-over",_.fillStyle="transparent",_.fillRect(F.width-1,0,1,F.height)):j++;const o=t=>$(t/D*-2*A)+5;{const t=U[U.length-1],e=j-.5;let s=$(0);_.beginPath(),_.moveTo(e,s),_.lineTo(e,$(t.total)),_.strokeStyle=H[t.connected?"total":"network"],_.stroke(),_.beginPath(),_.moveTo(e,s),s=$(t.total);let i=0;for(const n of I)t.items[n]&&(i+=t.items[n],s=$(i),_.lineTo(e,s),_.strokeStyle=H[n],_.stroke(),_.beginPath(),_.moveTo(e,s));t.network&&(_.beginPath(),_.moveTo(e,o(0)),_.lineTo(e,o(t.network)),_.strokeStyle=H.network,_.stroke())}}const st=[],it={};let nt={};const ot={frames:U,animationFrame(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};et(t),B=tt(t);for(const[t,s]of Object.entries(e))this[t](s)},begin(t){const e=performance.now();B.items[t]=(B.items[t]||0)-e;const s=st[st.length-1];return s&&(B.items[s]+=e),st.push(t),e},end(t){const e=performance.now();B.items[t]+=e;const s=st.pop();if(s!==t)throw Error(`Unmatched stats calls: expected end("${s}"), got end("${t}")`);const i=st[st.length-1];return i&&(B.items[i]-=e),e},backlog(t){B.backlog=Math.max(t,B.backlog)},network(t){B.network=t},starvation(t){B.network=t},latency(t){B.latency=t},activity(t){B.activity=t},users(t){B.users=t},connected(t){const e=O;B.connected=O=t,e&&!O&&K&&(K.remove(),z=null)},networkTraffic:it,addNetworkTraffic(t,e){it[t]=(it[t]||0)+e},perSecondTally(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(window.logMessageStats)for(const[e,s]of Object.entries(t))nt[e]=(nt[e]||0)+s},stepSession(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const s=Math.floor(Date.now()/1e3);if(!window.logMessageStats)return nt={second:s},null;let i=null;if(s!==nt.second){if(nt.second&&e&&(nt.requestedMessages||nt.sentMessagesTotal)){i={...nt};const t=s-nt.second;1!==t&&(i.sampleSeconds=t),i.sentBundles&&(i.averageDelay=Math.round(10*i.sendDelay/i.sentMessagesTotal)/10,i.averageBundlePayload=Math.round(i.sentBundlePayload/i.sentBundles)),delete i.second,delete i.sendDelay,delete i.sentBundlePayload}nt={second:s}}return i}};globalThis.CROQUETSTATS=ot;const rt="ontouchstart"in document.documentElement,at=window.parent!==window,lt=rt?20:12,ct=rt?0:15;let dt=!1;function ht(){if(dt)return;dt=!0;const t=`\n #croquet_dock { position: fixed; z-index: 2; border: 3px solid white; bottom: 6px; left: 6px; width: 36px; height: 36px; box-sizing: border-box; background: white; opacity: 0.4; transition: all 0.3s ease; }\n #croquet_dock.active { opacity: 0.95; border-radius: 12px; }\n #croquet_dock.debug { width: 84px; }\n #croquet_dock_bar { position: absolute; border: 3px solid white; width: 100%; height: 30px; box-sizing: border-box; background: white; }\n\n #croquet_badge { position: absolute; width: 72px; height: 24px; top: 50%; transform: translate(0px, -50%); cursor: none; }\n #croquet_dock.active #croquet_badge { left: 2%; }\n #croquet_dock:not(.debug) #croquet_badge { display: none; }\n\n .croquet_dock_button { position: absolute; width: ${lt}%; height: 90%; top: 50%; transform: translate(0px, -50%); border-radius: 20%; }\n .croquet_dock_button:focus { outline: 0; }\n .croquet_dock_button canvas { position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; }\n #croquet_dock:not(.active) .croquet_dock_button { display: none; }\n #croquet_dock_left { right: ${2+ct+lt+2}% }\n #croquet_dock:not(.debug) #croquet_dock_left { display: none; }\n #croquet_dock_right { right: ${2+ct}%; }\n #croquet_dock:not(.debug) #croquet_dock_right { display: none; }\n #croquet_dock_pin { right: 2%; }\n #croquet_dock_pin.pinned { background: #cce6ff; }\n\n #croquet_dock_content { position: absolute; left: 2px; top: 2px; right: 2px; bottom: 2px; background: white; overflow: hidden; }\n #croquet_dock.debug:not(.active) #croquet_dock_content { display: none; }\n #croquet_dock.debug:not(.active) #croquet_dock_content div { display: none; }\n\n #croquet_qrcode { position: absolute; width: 100%; height: 100%;box-sizing: border-box; cursor: crosshair; }\n #croquet_dock.active #croquet_qrcode { border: 6px solid white; }\n #croquet_dock.debug #croquet_qrcode:not(.active) { display: none; }\n #croquet_qrcode canvas { image-rendering: pixelated; }\n\n #croquet_stats { position: absolute; width: 70%; height: 90%; left: 15%; top: 5%; opacity: 0.8; font-family: sans-serif; }\n #croquet_stats:not(.active) { display: none; }\n`,e=document.createElement("style");e.innerHTML=t,document.head.insertBefore(e,document.head.getElementsByTagName("style")[0])}let ut=!1;let mt,pt=!1;function ft(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return t&&Pt.showMessage(t,{...e,level:"warning"})}function bt(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return t&&Pt.showMessage(t,{...e,level:"status"})}function yt(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"error";console.error(`Error during ${t}`,e);const i=(e.stack||"").split("\n").filter((t=>!t.match(/croquet-.*\.min.js/))).join("\n");Pt.showMessage(`Error during ${t}: ${e.message}\n\n${i}`,{level:s,duration:"error"===s?1e4:void 0,stopOnFocus:!0})}function gt(t,e){const s=Tt(Pt.root,(()=>document.body));if(!1===s)return null;!function(){if(pt)return;pt=!0;let t="/*!\n * Toastify js 1.5.0\n * https://github.com/apvarun/toastify-js\n * @license MIT licensed\n *\n * Copyright (C) 2018 Varun A P\n */\n .toastify {\n padding: 12px 20px;\n color: #ffffff;\n display: inline-block;\n box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);\n background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);\n background: linear-gradient(135deg, #73a5ff, #5477f5);\n position: fixed;\n opacity: 0;\n transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);\n border-radius: 2px;\n cursor: pointer;\n text-decoration: none;\n max-width: calc(50% - 20px);\n z-index: 2147483647;\n }\n .toastify.on {\n opacity: 1;\n }\n .toast-close {\n opacity: 0.4;\n padding: 0 5px;\n }\n .toastify-right {\n right: 15px;\n }\n .toastify-left {\n left: 15px;\n }\n .toastify-top {\n top: -150px;\n }\n .toastify-bottom {\n bottom: -150px;\n }\n .toastify-rounded {\n border-radius: 25px;\n }\n .toastify-avatar {\n width: 1.5em;\n height: 1.5em;\n margin: 0 5px;\n border-radius: 2px;\n }\n @media only screen and (max-width: 360px) {\n .toastify-right, .toastify-left {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n }\n }\n";t+="\n .toastify {\n font-family: sans-serif;\n border-radius: 8px;\n }\n\n .toastify-center {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n max-width: -moz-fit-content;\n }\n";const e=document.createElement("style");e.innerHTML="/*!\n * Toastify js 1.5.0\n * https://github.com/apvarun/toastify-js\n * @license MIT licensed\n *\n * Copyright (C) 2018 Varun A P\n */\n .toastify {\n padding: 12px 20px;\n color: #ffffff;\n display: inline-block;\n box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);\n background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);\n background: linear-gradient(135deg, #73a5ff, #5477f5);\n position: fixed;\n opacity: 0;\n transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);\n border-radius: 2px;\n cursor: pointer;\n text-decoration: none;\n max-width: calc(50% - 20px);\n z-index: 2147483647;\n }\n .toastify.on {\n opacity: 1;\n }\n .toast-close {\n opacity: 0.4;\n padding: 0 5px;\n }\n .toastify-right {\n right: 15px;\n }\n .toastify-left {\n left: 15px;\n }\n .toastify-top {\n top: -150px;\n }\n .toastify-bottom {\n bottom: -150px;\n }\n .toastify-rounded {\n border-radius: 25px;\n }\n .toastify-avatar {\n width: 1.5em;\n height: 1.5em;\n margin: 0 5px;\n border-radius: 2px;\n }\n @media only screen and (max-width: 360px) {\n .toastify-right, .toastify-left {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n }\n }\n\n .toastify {\n font-family: sans-serif;\n border-radius: 8px;\n }\n\n .toastify-center {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n max-width: -moz-fit-content;\n }\n",document.head.insertBefore(e,document.head.getElementsByTagName("style")[0])}();const i={text:t,duration:3e3,gravity:"bottom",position:"right",stopOnFocus:!0,...e};let n;return s instanceof Element&&s!==document.body?(n=s.id,n||(s.id=n="_croquetToastParent")):"string"==typeof s&&(n=s),n&&(i.selector=n),h(i).showToast()}try{if(mt=window.localStorage,mt["croquet-debug-persist-allowed"]="true","true"!==mt["croquet-debug-persist-allowed"])throw Error("localStorage not persisted");delete mt["croquet-debug-persist-allowed"]}catch(Mo){console.warn("localStorage not allowed"),mt={}}const wt={get pinned(){return"true"===mt[window.location.pathname+"/croquet-debug-ui-pinned"]},set pinned(t){mt[window.location.pathname+"/croquet-debug-ui-pinned"]=!!t},get activePage(){return mt[window.location.pathname+"/croquet-debug-ui-activePage"]},set activePage(t){mt[window.location.pathname+"/croquet-debug-ui-activePage"]=t}},Zt=t=>{t.preventDefault(),t.stopPropagation()};function vt(t,e,s){const i=document.createElement("canvas"),n=i.width=40*lt/12,o=i.height=60,r=i.getContext("2d");r.font="36px Arial",r.textAlign="center",r.textBaseline="middle",r.fillStyle="black",r.fillText(t,n/2,.55*o);const a=document.createElement("button");a.id=e,a.className="croquet_dock_button";const l=t=>{t.preventDefault(),t.stopPropagation(),s()};return rt?(a.ontouchstart=l,a.ontouchend=Zt,a.onpointerdown=Zt,a.onpointerup=Zt):(a.onclick=l,a.onpointerdown=Zt,a.onpointerup=Zt),a.appendChild(i),a}function Xt(t,e){if(!1===Pt.badge)return;const s=function(t){const e=new p(t),s=["bcdfghjklmnpqrstvwxyz","aeiou"];let i="";for(let t=0;t<5;t++)i+=s[t%2][e.quick()*s[t%2].length|0];return i}(e);for(document.title=document.title.replace(/:.*/,""),document.title+=":"+s;t.firstChild;)t.removeChild(t.firstChild);const i=document.createElement("canvas"),n=i.width=120,o=i.height=40;i.style.width="100%",t.appendChild(i);const r=i.getContext("2d"),a=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;const s=new p(t),i=[];for(let t=0;t2&&void 0!==arguments[2]?arguments[2]:{};for(;t.firstChild;)t.removeChild(t.firstChild);return new b(t,{text:e,width:128,height:128,colorDark:"#000000",colorLight:"#ffffff",correctLevel:b.CorrectLevel.L,...s})}function xt(){if(!1===Pt.root||!1===Pt.qrcode)return;if(r.noqr)return;const t=Pt.sessionURL;if(!t)return void console.warn("App.sessionURL is not set");const e=Tt(Pt.qrcode);if(!e)return;rt||(e.onclick=e=>{e.preventDefault(),e.stopPropagation(),e.shiftKey?function(){const t=document.getElementById("croquet_dock");t&&t.classList.toggle("debug")}():window.open(t)});Lt(e,t).getCanvas().style.width="100%"}let St,Gt,kt=0;function Wt(){!function(){if(ut)return;ut=!0;const t=`\n ${at?"body { min-height: 100vh }":""}\n #croquet_spinnerOverlay {\n z-index: 1000;\n position: fixed;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n background-color:#333;\n opacity:0.9;\n display:flex;\n align-items:center;\n justify-content:center;\n transition: opacity 1.0s ease-out;\n }\n /* https://github.com/lukehaas/css-loaders */\n @keyframes croquet_dots {\n 0%, 80%, 100% { box-shadow: 0 2.5em 0 -1.3em; }\n 40% { box-shadow: 0 2.5em 0 0; }\n }\n #croquet_loader,\n #croquet_loader::before,\n #croquet_loader::after {\n border-radius: 50%;\n width: 2.5em;\n height: 2.5em;\n animation: croquet_dots 1.8s infinite ease-in-out;\n }\n #croquet_loader {\n color: #fff;\n font-size: 10px;\n margin: 80px auto;\n position: relative;\n text-indent: -9999em;\n animation-delay: -0.16s;\n }\n #croquet_loader::before,\n #croquet_loader::after {\n content: '';\n position: absolute;\n top: 0;\n }\n #croquet_loader::before { left: -3.5em; animation-delay: -0.32s; }\n #croquet_loader::after { left: 3.5em; }\n #croquet_spinnerOverlay.croquet_error>*,\n #croquet_spinnerOverlay.croquet_error>*::before,\n #croquet_spinnerOverlay.croquet_error>*::after {\n color: #f00;\n }\n #croquet_spinnerOverlay.croquet_fatal>*,\n #croquet_spinnerOverlay.croquet_fatal>*::before,\n #croquet_spinnerOverlay.croquet_fatal>*::after {\n color: #f00;\n box-shadow: 0 2.5em 0 0 !important;\n animation: none !important;\n }\n`,e=document.createElement("style");e.innerHTML=t,document.head.insertBefore(e,document.head.getElementsByTagName("style")[0])}();const t=document.createElement("div");t.id="croquet_spinnerOverlay";const e=document.createElement("div");return e.id="croquet_loader",e.innerText="Catching up...",t.appendChild(e),t}function Tt(t,e){if(!1===t)return!1;if(t instanceof Element)return t;if("string"==typeof t){const e=document.getElementById(t);if(e)return e}return e?e():null}const Ct=new Set;let Vt=function(){let t=null;const e=document.getElementsByTagName("link");for(const s of e)if("canonical"===s.getAttribute("rel")){t=s.getAttribute("href");break}return t||window.location.href}();const Pt={get sessionURL(){return Vt},set sessionURL(t){Vt=t,xt()},root:null,sync:!0,messages:!1,badge:!1,stats:!1,qrcode:!1,makeWidgetDock:function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(r.nodock)return;const e=t.debug||r.debug,s=document.getElementById("croquet_dock");s&&s.parentElement.removeChild(s);const i=Tt(Pt.root,(()=>document.body));if(!i)return;ht();const n=document.createElement("div");n.id="croquet_dock",e&&n.classList.add("debug"),at&&!t.iframe&&(n.style.display="none"),i.appendChild(n);const o=document.createElement("div");let a;o.id="croquet_dock_bar",n.appendChild(o),!1!==t.badge&&(a=document.createElement("div"),a.id="croquet_badge",o.appendChild(a),Pt.badge=a);const l=document.createElement("div");l.id="croquet_dock_content",n.appendChild(l);const c=[];let d,h;if(!1!==t.qrcode){Pt.sessionURL&&(d=document.createElement("div"),d.id="croquet_qrcode",l.appendChild(d),c.push(d.id),Pt.qrcode=d,e||(wt.activePage=d.id))}if(!1!==t.stats&&(h=document.createElement("div"),h.id="croquet_stats",l.appendChild(h),c.push(h.id),Pt.stats=h),c.length){function v(t){const e=c.length;let s,i=0;if(wt.activePage){const t=c.indexOf(wt.activePage);t>=0?(i=t,s=document.getElementById(wt.activePage)):wt.activePage=null}const n=c[(i+e+t)%e];let o;n===wt.activePage?o=s:(s&&s.classList.remove("active"),o=document.getElementById(n)),o&&o.classList.add("active"),wt.activePage=n}c.length>1&&(o.appendChild(vt("<","croquet_dock_left",(()=>v(-1)))),o.appendChild(vt(">","croquet_dock_right",(()=>v(1))))),v(0)}if(!rt&&!t.alwaysPinned){const X=vt("📌","croquet_dock_pin",(()=>{wt.pinned=!wt.pinned,L()})),L=()=>{wt.pinned?X.classList.add("pinned"):X.classList.remove("pinned")};L(),o.appendChild(X)}const u=200,m=166,p=8,f=t=>{n.style.width=`${t}px`;const e=1.18*t;n.style.height=`${e}px`;const s=18*t/100;o.style.height=`${s}px`,l.style.top=`${s+2}px`,a&&(a.style.height=.9*s+"px",a.style.width=.9*s*3+"px"),d&&(d.style.border=p*t/u+"px solid white")},b=()=>{n.style.width=n.style.height="",o.style.height="",l.style.top="",a&&(a.style.height=a.style.width=""),d&&(d.style.border="")};let y=t.fixedSize||u;const g=()=>n.classList.contains("active"),w=()=>{n.classList.add("active"),f(y),setTimeout((()=>n.style.transition="none"),300)},Z=()=>{n.style.transition="",n.classList.remove("active"),b()};if(rt)Z(),n.ontouchstart=t=>{t.preventDefault(),t.stopPropagation(),g()?Z():w()},n.ontouchend=Zt,n.onpointerdown=Zt,n.onpointerup=Zt;else if(t.alwaysPinned?w():(wt.pinned?w():Z(),n.onmouseenter=w,n.onmouseleave=()=>{wt.pinned||Z()}),!t.fixedSize){let x=0;n.addEventListener("wheel",(t=>{t.stopPropagation();const e=Date.now();if(e-x<100)return;x=e;let{deltaY:s}=t;s=Math.sign(s)*Math.min(5,Math.abs(s));const i=.8*Math.min(window.innerWidth,window.innerHeight);y=Math.max(m,Math.min(i,n.offsetWidth/1.05**s)),f(y)}),{passive:!0})}},makeSessionWidgets:function(t){!function(t){if(!t||!1===Pt.root)return;const e=Tt(Pt.badge);e&&Xt(e,t)}(t),xt(),function(){if(!1===Pt.root)return;if(r.nostats)return;const t=Tt(Pt.stats);t&&J(t)}()},makeQRCanvas(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!Pt.sessionURL)return null;const e=Lt(document.createElement("div"),Pt.sessionURL,t);return e&&e.getCanvas()},clearSessionMoniker:function(){!1!==Pt.badge&&(document.title=document.title.replace(/:.*/,""))},showSyncWait(t){!1===Pt.root?t=!1:St||(St=Wt()),function(t){if(Gt!==t&&("string"!=typeof Gt||!0!==t))if(!1===Pt.sync&&(t=!1),Gt=t,t)clearTimeout(kt),kt=setTimeout((()=>{Gt&&(Tt(Pt.root,(()=>document.body)).appendChild(St),St.style.opacity=.9,St.className="error"===Gt?"croquet_error":"fatal"===Gt?"croquet_fatal":"")}),500);else{if(!St)return;clearTimeout(kt),St.style.opacity=0,St.className="",kt=setTimeout((()=>{Gt||St.parentElement&&St.parentElement.removeChild(St)}),500)}}(t)},messageFunction:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=e.level;let i;return"error"===s?(i="orangered,red",console.error(t)):"warning"===s?(i="gold,orange",console.warn(t)):i="silver,gray",gt(t,{style:{background:`linear-gradient(90deg,${i})`},...e})},showMessage(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("once"===e.only){if(Ct.has(t))return null;Ct.add(t)}return"fatal"===e.level&&(e.level="error",e.showSyncWait="fatal"),e.showSyncWait&&("fatal"!==e.showSyncWait||e.duration||(e.duration=-1),Pt.showSyncWait(e.showSyncWait)),r.nomessages||!1===Pt.root||!1===Pt.messages||!Pt.messageFunction?("warning"===e.level&&console.warn(t),"error"===e.level&&console.error(t),null):Pt.messageFunction(t,e)},isCroquetHost:t=>t.endsWith("croquet.io")||["localhost","127.0.0.1","[::1]"].includes(t)||t.endsWith("ngrok.io"),referrerURL(){const t=new URL(Pt.sessionURL),e=this.isCroquetHost(t.hostname);return`${t.protocol}//${t.host}${t.pathname}${e?t.search:""}`},autoSession(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{key:"q"};"string"==typeof t&&(t={key:t}),t||(t={});const e=t.key||"q",s=new URL(Pt.sessionURL);let i="";const n=s.search.slice(1).split("&"),o=n.find((t=>t.split("=")[0]===e));if(o?i=o.replace(/[^=]*=/,""):(i=n.find((t=>!t.includes("="))),i||(i=s.hash.slice(1),i&&(s.hash="",s.search?s.searchParams.set(e,i):s.search=i))),i)try{i=decodeURIComponent(i)}catch(t){}else i=Math.floor(Math.random()*36**10).toString(36),s.searchParams.set(e,i);const a=s.toString("");window.location.href!==a&&(window.history.replaceState({},"",a),Pt.sessionURL=a),r.has("debug","session")&&console.log(`Croquet.App.autoSession: "${i}"`);const l=Promise.resolve(i);return l[Symbol.toPrimitive]=()=>(console.warn("Deprecated: Croquet.App.autoSession() return value used directly. It returns a promise now!"),i),l},autoPassword(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{key:"pw",scrub:!1,keyless:!1};const e=t.key||"pw",s=t.scrub&&!r.has("debug","password"),i=t.keyless,n=new URL(Pt.sessionURL);let o="";const a=n.hash.slice(1);if(a){const t=a.split("&"),r=t.find((t=>t.split("=")[0]===e));r?(o=r.replace(/[^=]*=/,""),o&&s&&(n.hash=t.filter((t=>t.split("=")[0]!==e)).join("&"))):i&&(o=t.find((t=>!t.includes("="))),o&&s&&(n.hash=t.filter((t=>t!==o)).join("&")))}if(!o){const t=new Uint8Array(16);window.crypto.getRandomValues(t),o=k(t.buffer),n.hash=a?`${a}&${e}=${o}`:i?o:`${e}=${o}`,Pt.sessionURL=n.href,s&&(n.hash=a)}if(r.has("debug","session")&&console.log(`Croquet.App.sessionUrl: ${Pt.sessionURL}`),window.location.href!==n.href&&window.history.replaceState({},"",n.href),o)try{o=decodeURIComponent(o)}catch(t){}r.has("debug","session")&&console.log(`Croquet.App.autoPassword: "${o}"`);const l=Promise.resolve(o);return l[Symbol.toPrimitive]=()=>(console.warn("Deprecated: Croquet.App.autoPassword() return value used directly. It returns a promise now!"),o),l}};function Rt(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,i="none";for(const n of["immediate","queued","oncePerFrame","oncePerFrameWhileSynced"])for(const o of t[n])o.for===e?null===s||o.unbound===s?t[n].delete(o):i="subscriber":"none"===i&&(i="others");return i}const Yt=new class{constructor(){this.subscriptions={},this.subscribers=new Map,this.queuedEvents=[],this.perFrameEvents=new Map,this.perSyncedFrameEvents=new Map,this.subscriberIds=0}register(t){return"V"+ ++this.subscriberIds}deregister(t){}addSubscription(t,e,s,i,n){if("vote"===n)return void this.addSubscription(t,e+"#__vote",s,i,"immediate");const o=t+":"+e,r=i;r.for=s;let a=this.subscriptions[o];if(a||(a=this.subscriptions[o]={immediate:new Set,queued:new Set,oncePerFrame:new Set,oncePerFrameWhileSynced:new Set}),!a[n])throw Error(`Unknown subscribe() option: handling="${n}"`);a[n].add(r);let l=this.subscribers.get(s);l||this.subscribers.set(s,l=new Set),l.add(o)}removeSubscription(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;const n=t+":"+e,o=this.subscriptions[n];if(o){const t=Rt(o,s,i);if(t||delete this.subscriptions[n],"subscriber"!==t){const t=this.subscribers.get(s);t.delete(n),0===t.size&&this.subscribers.delete(s)}}e.endsWith("#__vote")||this.removeSubscription(t,e+"#__vote",s)}removeAllSubscriptionsFor(t){const e=this.subscribers.get(t);if(e){for(const s of e){const e=this.subscriptions[s];if(e){"none"===Rt(e,t)&&delete this.subscriptions[s]}else console.error(`Croquet: topic ${s} not found in subscriptions table for ${t} during removeAllSubscriptionsFor()`)}this.subscribers.delete(t)}}handleEvent(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t=>t();const i=this.subscriptions[t];i&&(i.queued.size>0&&this.queuedEvents.push({topic:t,data:e}),i.oncePerFrame.size>0&&this.perFrameEvents.set(t,e),i.oncePerFrameWhileSynced.size>0&&this.perSyncedFrameEvents.set(t,e),i.immediate.size>0&&s((()=>{for(const s of i.immediate)try{s(e)}catch(e){console.error(e),console.warn(`Croquet: error "${e.message}" in "immediate" subscription ${t}`)}})))}processFrameEvents(t,e){let s=0;const i=(t,e,i)=>{const n=this.subscriptions[e];if(n)for(const o of n[t]){try{o(i)}catch(s){console.error(s),console.warn(`Croquet: error "${s.message}" in "${t}" subscription ${e}`)}s++}};for(const{topic:t,data:e}of this.queuedEvents)i("queued",t,e);if(this.queuedEvents.length=0,t){for(const[t,e]of this.perFrameEvents)i("oncePerFrame",t,e);if(this.perFrameEvents.clear(),e){for(const[t,e]of this.perSyncedFrameEvents)i("oncePerFrameWhileSynced",t,e);this.perSyncedFrameEvents.clear()}for(const{topic:t,data:e}of this.queuedEvents)i("queued",t,e);this.queuedEvents.length=0}return s}};let Mt={get subscribe(){return Mt={subscribe:r.has("debug","subscribe",!1)},Mt.subscribe}};class It{constructor(t){this.vm=t}register(t){return this.vm.registerModel(t)}deregister(t){this.vm.deregisterModel(t.id)}publish(t,e,s){this.vm.publishFromModel(s,t,e)}subscribe(t,e,s,i){return Mt.subscribe&&console.log(`Model.subscribe("${e}:${s}", ${t} ${(""+i).replace(/\([\s\S]*/,"")})`),this.vm.addSubscription(t,e,s,i)}unsubscribe(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"*";Mt.subscribe&&console.log(`Model.unsubscribe(${e}:${s}", ${t} ${(""+i).replace(/\([\s\S]*/,"")})`),this.vm.removeSubscription(t,e,s,i)}unsubscribeAll(t){Mt.subscribe&&console.log(`Model.unsubscribeAll(${t} ${t.id})`),this.vm.removeAllSubscriptionsFor(t)}future(t,e,s,i){if(Kt&&Kt.equal(this))return this.vm.future(t,e,s,i);throw Error(`Model.future() called from outside: ${t}`)}cancelFuture(t,e){if(Kt&&Kt.equal(this))return this.vm.cancelFuture(t,e);throw Error(`Model.cancelFuture() called from outside: ${t}`)}random(){return this.vm.random()}now(){return this.vm.time}equal(t){return t instanceof It&&t.vm===this.vm}isViewRealm(){return!1}}class Ht{constructor(t){this.vm=t}register(t){return Yt.register(t)}deregister(t){Yt.deregister(t)}publish(t,e,s){this.vm.publishFromView(s,t,e)}subscribe(t,e,s,i){let n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"queued";Mt.subscribe&&console.log(`View.subscribe("${i}:${t}", ${e} ${s?s.name||(""+s).replace(/\([\s\S]*/,""):""+s} [${n}])`),Yt.addSubscription(i,t,e,s,n)}unsubscribe(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,i=arguments.length>3?arguments[3]:void 0;Mt.subscribe&&console.log(`View.unsubscribe("${i}:${t}", ${e} ${s?s.name||(""+s).replace(/\([\s\S]*/,""):"*"})`),Yt.removeSubscription(i,t,e,s)}unsubscribeAll(t){Mt.subscribe&&console.log(`View.unsubscribeAll(${t})`),Yt.removeAllSubscriptionsFor(t)}future(t,e){const s=this.vm;return new Proxy(t,{get(i,n){if("function"==typeof t[n]){return new Proxy(t[n],{apply(i,o,r){setTimeout((()=>{t.id&&Ft(s,(()=>t[n](...r)),!0)}),e)}})}throw Error("Tried to call "+n+"() on future of "+Object.getPrototypeOf(t).constructor.name+" which is not a function")}})}random(){return Math.random()}now(){return this.vm.time}externalNow(){return this.vm.controller.reflectorTime}extrapolatedNow(){return this.vm.controller.extrapolatedTime}isSynced(){return!!this.vm.controller.synced}equal(t){return t instanceof Ht&&t.vm===this.vm}isViewRealm(){return!0}}let Kt=null;function zt(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"Tried to execute code that requires realm outside of realm.";if(!Kt&&t)throw Error(t);return Kt}function Nt(t,e){if(null!==Kt)throw Error("Can't switch realms from inside realm");try{return Kt=new It(t),e()}finally{Kt=null}}function Ft(t,e){let s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(null!==Kt&&!s)throw Error("Can't switch realms from inside realm");const i=Kt;try{return Kt=new Ht(t),e()}finally{Kt=i}}var _t=function(t){return t!=t},jt=Math.sqrt,Et=.7853981633974483;var Qt=function(t){var e,s;return 0===t?.16666666666666713:((t<0?-t:t)<=1?(e=t*(19.562619833175948+t*(t*(5.444622390564711+t*(.004253011369004428*t-.6019598008014124))-16.262479672107002))-8.198089802484825,s=t*(139.51056146574857+t*(t*(70.49610280856842+t*(1*t-14.740913729888538))-147.1791292232726))-49.18853881490881):(e=.004253011369004428+(t=1/t)*(t*(5.444622390564711+t*(t*(19.562619833175948+-8.198089802484825*t)-16.262479672107002))-.6019598008014124),s=1+t*(t*(70.49610280856842+t*(t*(139.51056146574857+-49.18853881490881*t)-147.1791292232726))-14.740913729888538)),e/s)};var Jt=function(t){var e,s;return 0===t?.08333333333333809:((t<0?-t:t)<=1?(e=28.536655482610616+t*(t*(6.968710824104713+t*(.002967721961301243*t-.5634242780008963))-25.56901049652825),s=342.43986579130785+t*(t*(147.0656354026815+t*(1*t-21.947795316429207))-383.8770957603691)):(e=.002967721961301243+(t=1/t)*(t*(6.968710824104713+t*(28.536655482610616*t-25.56901049652825))-.5634242780008963),s=1+t*(t*(147.0656354026815+t*(342.43986579130785*t-383.8770957603691))-21.947795316429207)),e/s)};var Ut=function(t){var e,s,i,n,o;if(_t(t))return NaN;if(t>0?i=t:(e=!0,i=-t),i>1)return NaN;if(i>.625)n=(s=1-i)*Jt(s),s=jt(s+s),o=Et-s,o-=s=s*n-6123233995736766e-32,o+=Et;else{if(i<1e-8)return t;o=i*(o=(s=i*i)*Qt(s))+i}return e?-o:o};var Dt=function(t){var e;return _t(t)||t<-1||t>1?NaN:t>.5?2*Ut(jt(.5-.5*t)):(e=Et-Ut(t),e+=6123233995736766e-32,e+=Et)};var Ot=function(){return"function"==typeof Symbol&&"symbol"==typeof Symbol("foo")}();var Bt=function(){return Ot&&"symbol"==typeof Symbol.toStringTag},At=Object.prototype.toString;var $t=function(t){return At.call(t)},qt=Object.prototype.hasOwnProperty;var te=function(t,e){return null!=t&&qt.call(t,e)},ee="function"==typeof Symbol?Symbol.toStringTag:"";var se=function(t){var e,s,i;if(null==t)return At.call(t);s=t[ee],e=te(t,ee);try{t[ee]=void 0}catch(e){return At.call(t)}return i=At.call(t),e?t[ee]=s:delete t[ee],i},ie=Bt()?se:$t,ne="function"==typeof Uint32Array;var oe=function(t){return ne&&t instanceof Uint32Array||"[object Uint32Array]"===ie(t)},re="function"==typeof Uint32Array?Uint32Array:null;var ae=function(){var t,e;if("function"!=typeof re)return!1;try{e=new re(e=[1,3.14,-3.14,4294967296,4294967297]),t=oe(e)&&1===e[0]&&3===e[1]&&4294967293===e[2]&&0===e[3]&&1===e[4]}catch(e){t=!1}return t},le="function"==typeof Uint32Array?Uint32Array:null;var ce=function(){throw new Error("not implemented")},de=ae()?le:ce,he="function"==typeof Float64Array;var ue=function(t){return he&&t instanceof Float64Array||"[object Float64Array]"===ie(t)},me="function"==typeof Float64Array?Float64Array:null;var pe=function(){var t,e;if("function"!=typeof me)return!1;try{e=new me([1,3.14,-3.14,NaN]),t=ue(e)&&1===e[0]&&3.14===e[1]&&-3.14===e[2]&&e[3]!=e[3]}catch(e){t=!1}return t},fe="function"==typeof Float64Array?Float64Array:null;var be=function(){throw new Error("not implemented")},ye=pe()?fe:be,ge="function"==typeof Uint8Array;var we=function(t){return ge&&t instanceof Uint8Array||"[object Uint8Array]"===ie(t)},Ze="function"==typeof Uint8Array?Uint8Array:null;var ve=function(){var t,e;if("function"!=typeof Ze)return!1;try{e=new Ze(e=[1,3.14,-3.14,256,257]),t=we(e)&&1===e[0]&&3===e[1]&&253===e[2]&&0===e[3]&&1===e[4]}catch(e){t=!1}return t},Xe="function"==typeof Uint8Array?Uint8Array:null;var Le=function(){throw new Error("not implemented")},xe=ve()?Xe:Le,Se="function"==typeof Uint16Array;var Ge=function(t){return Se&&t instanceof Uint16Array||"[object Uint16Array]"===ie(t)},ke="function"==typeof Uint16Array?Uint16Array:null;var We=function(){var t,e;if("function"!=typeof ke)return!1;try{e=new ke(e=[1,3.14,-3.14,65536,65537]),t=Ge(e)&&1===e[0]&&3===e[1]&&65533===e[2]&&0===e[3]&&1===e[4]}catch(e){t=!1}return t},Te="function"==typeof Uint16Array?Uint16Array:null;var Ce,Ve=function(){throw new Error("not implemented")},Pe={uint16:We()?Te:Ve,uint8:xe};(Ce=new Pe.uint16(1))[0]=4660;var Re=52===new Pe.uint8(Ce.buffer)[0],Ye=!0===Re?1:0,Me=new ye(1),Ie=new de(Me.buffer);var He=function(t){return Me[0]=t,Ie[Ye]},Ke=!0===Re?1:0,ze=new ye(1),Ne=new de(ze.buffer);var Fe=function(t,e){return ze[0]=t,Ne[Ke]=e>>>0,ze[0]},_e=Fe,je=Number.POSITIVE_INFINITY,Ee=Number.NEGATIVE_INFINITY;var Qe=function(t){return 0===t?.6666666666666735:.6666666666666735+t*(.3999999999940942+t*(.2857142874366239+t*(.22222198432149784+t*(.1818357216161805+t*(.15313837699209373+.14798198605116586*t)))))},Je=.6931471803691238,Ue=1.9082149292705877e-10;var De=function(t){var e,s,i,n,o,r,a,l,c,d;if(t<-1||_t(t))return NaN;if(-1===t)return Ee;if(t===je)return t;if(0===t)return t;if(d=1,(i=t<0?-t:t)<.41421356237309503){if(i<1.862645149230957e-9)return i<5551115123125783e-32?t:t-t*t*.5;t>-.2928932188134525&&(d=0,n=t,s=1)}return 0!==d&&(i<9007199254740992?(o=(d=((s=He(c=1+t))>>20)-1023)>0?1-(c-t):t-(c-1),o/=c):(d=((s=He(c=t))>>20)-1023,o=0),(s&=1048575)<434334?c=_e(c,1072693248|s):(d+=1,c=_e(c,1071644672|s),s=1048576-s>>2),n=c-1),e=.5*n*n,0===s?0===n?d*Je+(o+=d*Ue):d*Je-((l=e*(1-.6666666666666666*n))-(d*Ue+o)-n):(l=(a=(r=n/(2+n))*r)*Qe(a),0===d?n-(e-r*(e+l)):d*Je-(e-(r*(e+l)+(d*Ue+o))-n))},Oe=.6931471805599453;var Be=function(t){return 0===t?.3999999999940942:.3999999999940942+t*(.22222198432149784+.15313837699209373*t)};var Ae=function(t){return 0===t?.6666666666666735:.6666666666666735+t*(.2857142874366239+t*(.1818357216161805+.14798198605116586*t))},$e=.6931471803691238,qe=1.9082149292705877e-10;var ts=function(t){var e,s,i,n,o,r,a,l,c,d,h;return 0===t?Ee:_t(t)||t<0?NaN:(n=0,(s=He(t))<1048576&&(n-=54,s=He(t*=0x40000000000000)),s>=2146435072?t+t:(n+=(s>>20)-1023|0,n+=(a=(s&=1048575)+614244&1048576|0)>>20|0,r=(t=_e(t,s|1072693248^a))-1,(1048575&2+s)<3?0===r?0===n?0:n*$e+n*qe:(o=r*r*(.5-.3333333333333333*r),0===n?r-o:n*$e-(o-n*qe-r)):(a=s-398458|0,l=440401-s|0,i=(d=(h=(c=r/(2+r))*c)*h)*Be(d),o=h*Ae(d)+i,(a|=l)>0?(e=.5*r*r,0===n?r-(e-c*(e+o)):n*$e-(e-(c*(e+o)+n*qe)-r)):0===n?r-c*(r-o):n*$e-(c*(r-o)-n*qe-r))))};var es=function(t){var e;return _t(t)||t<1?NaN:1===t?0:t>=268435456?ts(t)+Oe:t>2?ts(2*t-1/(t+jt(t*t-1))):De((e=t-1)+jt(2*e+e*e))};var ss=function(t){return t===je||t===Ee};var is=function(t){var e,s,i;return _t(t)||ss(t)?t:(t<0&&(t=-t,e=!0),i=t<3.725290298461914e-9?t:t>268435456?ts(t)+Oe:t>2?ts(2*t+1/(jt(t*t+1)+t)):De(t+(s=t*t)/(1+jt(1+s))),e?-i:i)},ns=1.5707963267948966;var os=function(t){return 0===t?-64.85021904942025:t*(t*(t*(-.8750608600031904*t-16.157537187333652)-75.00855792314705)-122.88666844901361)-64.85021904942025};var rs=function(t){return 0===t?194.5506571482614:194.5506571482614+t*(485.3903996359137+t*(432.88106049129027+t*(165.02700983169885+t*(24.858464901423062+1*t))))};var as=function(t){var e,s,i,n;return _t(t)||0===t?t:t===je?ns:t===Ee?-ns:(t<0&&(s=!0,t=-t),e=0,t>2.414213562373095?(i=ns,e=1,t=-1/t):t<=.66?i=0:(i=Et,e=2,t=(t-1)/(t+1)),n=t*(n=(n=t*t)*os(n)/rs(n))+t,2===e?n+=3061616997868383e-32:1===e&&(n+=6123233995736766e-32),i+=n,s?-i:i)};var ls,cs,ds=function(t){var e,s;return _t(t)||t<-1||t>1?NaN:1===t?je:-1===t?Ee:(t<0&&(e=!0,t=-t),t<3.725290298461914e-9?e?-t:t:(s=t<.5?.5*De((s=t+t)+s*t/(1-t)):.5*De((t+t)/(1-t)),e?-s:s))};!0===Re?(ls=1,cs=0):(ls=0,cs=1);var hs={HIGH:ls,LOW:cs},us=new ye(1),ms=new de(us.buffer),ps=hs.HIGH,fs=hs.LOW;var bs=function(t,e){return us[0]=e,t[0]=ms[ps],t[1]=ms[fs],t};var ys,gs,ws=function(t,e){return 1===arguments.length?bs([0,0],t):bs(t,e)};!0===Re?(ys=1,gs=0):(ys=0,gs=1);var Zs={HIGH:ys,LOW:gs},vs=new ye(1),Xs=new de(vs.buffer),Ls=Zs.HIGH,xs=Zs.LOW;var Ss=function(t,e){return Xs[Ls]=t,Xs[xs]=e,vs[0]},Gs=Ss,ks=[0,0];var Ws=function(t,e){var s,i;return ws(ks,t),s=ks[0],s&=2147483647,i=He(e),Gs(s|=i&=2147483648,ks[1])};var Ts=function(t){return!!(He(t)>>>31)},Cs=3.141592653589793;var Vs=function(t,e){var s;return _t(e)||_t(t)?NaN:ss(e)?e===je?ss(t)?Ws(Cs/4,t):Ws(0,t):ss(t)?Ws(3*Cs/4,t):Ws(Cs,t):ss(t)?Ws(Cs/2,t):0===t?e>=0&&!Ts(e)?Ws(0,t):Ws(Cs,t):0===e?Ws(Cs/2,t):(s=as(t/e),e<0?s<=0?s+Cs:s-Cs:s)},Ps=22250738585072014e-324;var Rs=function(t){return 0===t?1.87595182427177:1.87595182427177+t*(t*(1.6214297201053545+t*(.14599619288661245*t-.758397934778766))-1.8849797954337717)};var Ys=function(t){var e,s,i,n,o;return _t(t)||ss(t)||0===t?t:(s=-2147483648&(i=He(t)),i&=2147483647,o=0,t>>20)-1023|0},Bs=Os,As=[0,0],$s=[0,0];var qs=function(t,e){var s,i;return 0===t||_t(t)||ss(t)?t:(Ds(As,t),e+=As[1],(e+=Bs(t=As[0]))<-1074?Ws(0,t):e>1023?t<0?Ee:je:(e<=-1023?(e+=52,i=2220446049250313e-31):i=1,ws($s,t),s=$s[0],s&=2148532223,i*Gs(s|=e+1023<<20,$s[1])))},ti=qs,ei=[10680707,7228996,1387004,2578385,16069853,12639074,9804092,4427841,16666979,11263675,12935607,2387514,4345298,14681673,3074569,13734428,16653803,1880361,10960616,8533493,3062596,8710556,7349940,6258241,3772886,3769171,3798172,8675211,12450088,3874808,9961438,366607,15675153,9132554,7151469,3571407,2607881,12013382,4155038,6285869,7677882,13102053,15825725,473591,9065106,15363067,6271263,9264392,5636912,4652155,7056368,13614112,10155062,1944035,9527646,15080200,6658437,6231200,6832269,16767104,5075751,3212806,1398474,7579849,6349435,12618859],si=[1.570796251296997,7.549789415861596e-8,5390302529957765e-30,3282003415807913e-37,1270655753080676e-44,12293330898111133e-52,27337005381646456e-60,21674168387780482e-67],ii=5.960464477539063e-8,ni=li(new Array(20)),oi=li(new Array(20)),ri=li(new Array(20)),ai=li(new Array(20));function li(t){var e,s=t.length;for(e=0;e0;m++)d=ii*y|0,ai[m]=y-16777216*d|0,y=i[b-1]+d,b-=1;if(y=ti(y,n),y-=8*Qs(.125*y),y-=f=0|y,h=0,n>0?(f+=m=ai[s-1]>>24-n,ai[s-1]-=m<<24-n,h=ai[s-1]>>23-n):0===n?h=ai[s-1]>>23:y>=.5&&(h=2),h>0){for(f+=1,c=0,m=0;m0)switch(n){case 1:ai[s-1]&=8388607;break;case 2:ai[s-1]&=4194303}2===h&&(y=1-y,0!==c&&(y-=ti(1,n)))}if(0===y){for(b=0,m=s-1;m>=o;m--)b|=ai[m];if(0===b){for(p=1;0===ai[o-p];p++);for(m=s+1;m<=s+p;m++){for(l[a+m]=ei[r+m],d=0,b=0;b<=a;b++)d+=t[b]*l[a+(m-b)];i[m]=d}return ci(t,e,s+=p,i,n,o,r,a,l)}}if(0===y)for(s-=1,n-=24;0===ai[s];)s-=1,n-=24;else(y=ti(y,-n))>=16777216?(d=ii*y|0,ai[s]=y-16777216*d|0,n+=24,ai[s+=1]=d):ai[s]=0|y;for(d=ti(1,n),m=s;m>=0;m--)i[m]=d*ai[m],d*=ii;for(m=s;m>=0;m--){for(d=0,p=0;p<=u&&p<=s-m;p++)d+=si[p]*i[m+p];ri[s-m]=d}for(d=0,m=s;m>=0;m--)d+=ri[m];for(e[0]=0===h?d:-d,d=ri[0]-d,m=1;m<=s;m++)d+=ri[m];return e[1]=0===h?d:-d,7&f}var di=function(t,e,s,i){var n,o,r,a,l,c,d;for(4,(o=(s-3)/24|0)<0&&(o=0),a=s-24*(o+1),c=o-(r=i-1),d=r+4,l=0;l<=d;l++)ni[l]=c<0?0:ei[c],c+=1;for(l=0;l<=4;l++){for(n=0,c=0;c<=r;c++)n+=t[c]*ni[r+(l-c)];oi[l]=n}return 4,ci(t,e,4,oi,a,4,o,r,ni)},hi=Math.round;var ui=function(t,e,s){var i,n,o,r,a;return o=t-1.5707963267341256*(i=hi(.6366197723675814*t)),r=6077100506506192e-26*i,a=e>>20|0,s[0]=o-r,a-(He(s[0])>>20&2047)>16&&(r=20222662487959506e-37*i-((n=o)-(o=n-(r=6077100506303966e-26*i))-r),s[0]=o-r,a-(He(s[0])>>20&2047)>49&&(r=84784276603689e-45*i-((n=o)-(o=n-(r=20222662487111665e-37*i))-r),s[0]=o-r)),s[1]=o-s[0]-r,i},mi=1.5707963267341256,pi=6077100506506192e-26,fi=2*pi,bi=4*pi,yi=new Array(3),gi=new Array(2);var wi=function(t,e){var s,i,n,o,r,a,l;if((n=2147483647&He(t)|0)<=1072243195)return e[0]=t,e[1]=0,0;if(n<=1074752122)return 598523==(1048575&n)?ui(t,n,e):n<=1073928572?t>0?(l=t-mi,e[0]=l-pi,e[1]=l-e[0]-pi,1):(l=t+mi,e[0]=l+pi,e[1]=l-e[0]+pi,-1):t>0?(l=t-2*mi,e[0]=l-fi,e[1]=l-e[0]-fi,2):(l=t+2*mi,e[0]=l+fi,e[1]=l-e[0]+fi,-2);if(n<=1075594811)return n<=1075183036?1074977148===n?ui(t,n,e):t>0?(l=t-3*mi,e[0]=l-1.8231301519518578e-10,e[1]=l-e[0]-1.8231301519518578e-10,3):(l=t+3*mi,e[0]=l+1.8231301519518578e-10,e[1]=l-e[0]+1.8231301519518578e-10,-3):1075388923===n?ui(t,n,e):t>0?(l=t-4*mi,e[0]=l-bi,e[1]=l-e[0]-bi,4):(l=t+4*mi,e[0]=l+bi,e[1]=l-e[0]+bi,-4);if(n<1094263291)return ui(t,n,e);if(n>=2146435072)return e[0]=NaN,e[1]=NaN,0;for(s=Es(t),l=Gs(n-((i=(n>>20)-1046)<<20|0),s),r=0;r<2;r++)yi[r]=0|l,l=16777216*(l-yi[r]);for(yi[2]=l,o=3;0===yi[o-1];)o-=1;return a=di(yi,gi,i,o),t<0?(e[0]=-gi[0],e[1]=-gi[1],-a):(e[0]=gi[0],e[1]=gi[1],a)},Zi=wi,vi=[0,0];var Xi=function(t){var e;if(e=He(t),(e&=2147483647)<=1072243195)return e<1044381696?1:Ks(t,0);if(e>=2146435072)return NaN;switch(3&Zi(t,vi)){case 0:return Ks(vi[0],vi[1]);case 1:return-Ns(vi[0],vi[1]);case 2:return-Ks(vi[0],vi[1]);default:return Ns(vi[0],vi[1])}},Li=Math.ceil;var xi=function(t){return t<0?Li(t):Qs(t)};var Si=function(t){return 0===t?.16666666666666602:.16666666666666602+t*(t*(6613756321437934e-20+t*(4.1381367970572385e-8*t-16533902205465252e-22))-.0027777777777015593)};var Gi=function(t,e,s){var i,n,o;return o=(i=t-e)-(n=i*i)*Si(n),ti(1-(e-i*o/(2-o)-t),s)};var ki=function(t){var e;return _t(t)||t===je?t:t===Ee?0:t>709.782712893384?je:t<-745.1332191019411?0:t>-3.725290298461914e-9&&t<3.725290298461914e-9?1+t:(e=xi(t<0?1.4426950408889634*t-.5:1.4426950408889634*t+.5),Gi(t-.6931471803691238*e,1.9082149292705877e-10*e,e))};var Wi=function(t){return _t(t)?t:(t<0&&(t=-t),t>21?ki(t)/2:(ki(t)+ki(-t))/2)};var Ti=function(t){return 0===t?-.03333333333333313:t*(.0015873015872548146+t*(t*(4008217827329362e-21+-2.0109921818362437e-7*t)-793650757867488e-19))-.03333333333333313},Ci=.6931471803691238,Vi=1.9082149292705877e-10;var Pi=function(t){var e,s,i,n,o,r,a,l,c,d,h,u;if(t===je||_t(t))return t;if(t===Ee)return-1;if(0===t)return t;if(t<0?(s=!0,a=-t):(s=!1,a=t),a>=38.816242111356935){if(s)return-1;if(a>=709.782712893384)return je}if(o=0|He(a),a>.34657359027997264)a<1.0397207708399179?s?(i=t+Ci,n=-Vi,u=-1):(i=t-Ci,n=Vi,u=1):(u=s?1.4426950408889634*t-.5:1.4426950408889634*t+.5,i=t-(d=u|=0)*Ci,n=d*Vi),c=i-(t=i-n)-n;else{if(o<1016070144)return t;u=0}return h=(l=t*(e=.5*t))*(((r=1+l*Ti(l))-(d=3-r*e))/(6-t*d)),0===u?t-(t*h-l):(h=t*(h-c)-c,h-=l,-1===u?.5*(t-h)-.5:1===u?t<-.25?-2*(h-(t+.5)):1+2*(t-h):u<=-2||u>56?(i=He(a=1-(h-t))+(u<<20)|0,(a=_e(a,i))-1):(d=1,u<20?a=(d=_e(d,i=1072693248-(2097152>>u)|0))-(h-t):(a=t-(h+(d=_e(d,i=1023-u<<20|0))),a+=1),i=He(a)+(u<<20)|0,_e(a,i)))},Ri=!0===Re?0:1,Yi=new ye(1),Mi=new de(Yi.buffer);var Ii=function(t,e){return Yi[0]=t,Mi[Ri]=e>>>0,Yi[0]},Hi=Ii;var Ki=function(t){return 0===t?.3999999999940942:.3999999999940942+t*(.22222198432149784+.15313837699209373*t)};var zi=function(t){return 0===t?.6666666666666735:.6666666666666735+t*(.2857142874366239+t*(.1818357216161805+.14798198605116586*t))};var Ni=function(t){var e,s,i,n,o,r,a,l,c,d;return n=t-1,(1048575&2+(i=He(t)))<3?0===n?0:n*n*(.3333333333333333*n-.5):(c=(i&=1048575)-398458|0,d=440401-i|0,s=(l=(r=(o=n/(2+n))*o)*r)*Ki(l),a=r*zi(l)+s,(c|=d)>0?o*((e=.5*n*n)+a)-e:o*(a-n))};var Fi=function(t){var e,s,i,n,o,r,a;return _t(t)||t<0?NaN:0===t?Ee:(o=0,(s=He(t))<1048576&&(o-=54,s=He(t*=0x40000000000000)),s>=2146435072?t+t:(o+=(s>>20)-1023|0,t=_e(t,(s&=1048575)|1072693248^(n=s+614244&1048576|0)),r=o+=n>>20|0,i=Ni(t),a=3694239077158931e-28*r+25082946711645275e-27*((t-=1)+i),(a+=.4342944818781689*(t-(e=Hi(t,0))+i)+.4342944818781689*e)+.30102999566361177*r))};var _i=function(t){return 0===t?.3999999999940942:.3999999999940942+t*(.22222198432149784+.15313837699209373*t)};var ji=function(t){return 0===t?.6666666666666735:.6666666666666735+t*(.2857142874366239+t*(.1818357216161805+.14798198605116586*t))};var Ei=function(t){var e,s,i,n,o,r,a,l,c,d;return n=t-1,(1048575&2+(i=He(t)))<3?0===n?0:n*n*(.3333333333333333*n-.5):(c=(i&=1048575)-398458|0,d=440401-i|0,s=(l=(r=(o=n/(2+n))*o)*r)*_i(l),a=r*ji(l)+s,(c|=d)>0?o*((e=.5*n*n)+a)-e:o*(a-n))},Qi=[0,0];var Ji=function(t){var e,s,i,n,o;if(_t(t)||t<0)return NaN;if(ws(Qi,t),o=0,(s=Qi[0])<1048576){if(0==(2147483647&s|Qi[1]))return Ee;o-=54,s=He(t*=0x40000000000000)}return s>=2146435072?t+t:(o+=(s>>20)-1023|0,t=_e(t,(s&=1048575)|1072693248^(n=s+614244&1048576|0)),o+=n>>20|0,i=Ei(t),1.6751713164886512e-10*((t-=1)+i)+1.4426950407214463*(t-(e=Hi(t,0))+i)+1.4426950407214463*e+o)},Ui=[0,0];var Di=function(t){var e;if(e=He(t),(e&=2147483647)<=1072243195)return e<1045430272?t:Ns(t,0);if(e>=2146435072)return NaN;switch(3&Zi(t,Ui)){case 0:return Ns(Ui[0],Ui[1]);case 1:return Ks(Ui[0],Ui[1]);case 2:return-Ns(Ui[0],Ui[1]);default:return-Ks(Ui[0],Ui[1])}};var Oi=function(t){var e,s;return 0===t?.16666666666666666:((t<0?-t:t)<=1?(e=t*(t*(-.789474443963537*t-163.72585752598383)-11561.443576500522)-351754.9648081514,s=t*(36157.827983443196+t*(1*t-277.7110814206028))-2110529.7888489086):(e=(t=1/t)*(t*(-351754.9648081514*t-11561.443576500522)-163.72585752598383)-.789474443963537,s=1+t*(t*(36157.827983443196+-2110529.7888489086*t)-277.7110814206028)),e/s)};var Bi=function(t){var e;return 0===t?t:(e=Js(t),t>710.4758600739439||t<-709.089565712824?t>0?je:Ee:e>1?e>=709.0895657128241?(e=ki(.5*e),e*=.5*e,t<0&&(e=-e),e):(e=.5*(e=ki(e))-.5/e,t<0&&(e=-e),e):t+t*(e*=e)*Oi(e))};var Ai=function(t){return 0===t?.13333333333320124:.13333333333320124+t*(.021869488294859542+t*(.0035920791075913124+t*(.0005880412408202641+t*(7817944429395571e-20+-18558637485527546e-21*t))))};var $i=function(t){return 0===t?.05396825397622605:.05396825397622605+t*(.0088632398235993+t*(.0014562094543252903+t*(.0002464631348184699+t*(7140724913826082e-20+2590730518636337e-20*t))))};var qi=function(t,e,s){var i,n,o,r,a,l,c,d,h;return(n=2147483647&(i=He(t))|0)>=1072010280&&(t<0&&(t=-t,e=-e),t=(h=.7853981633974483-t)+(d=3061616997868383e-32-e),e=0),r=e+(h=t*t)*((a=h*t)*((r=Ai(d=h*h))+(c=h*$i(d)))+e),d=t+(r+=.3333333333333341*a),n>=1072010280?(1-(i>>30&2))*((c=s)-2*(t-(d*d/(d+c)-r))):1===s?d:(Hi(h=d,0),c=r-(h-t),Hi(l=o=-1/d,0),l+o*((a=1+l*h)+l*c))},tn=[0,0];var en=function(t){var e,s;return e=He(t),(e&=2147483647)<=1072243195?e<1044381696?t:qi(t,0,1):e>=2146435072?NaN:(s=Zi(t,tn),qi(tn[0],tn[1],1-((1&s)<<1)))};var sn=function(t){var e,s;return 0===t?-.3333333333333332:((t<0?-t:t)<=1?(e=t*(t*(0*t-.9643991794250523)-99.28772310019185)-1614.6876844170845,s=4844.063053251255+t*(2235.4883906010045+t*(112.81167849163293+1*t))):(e=0+(t=1/t)*(t*(-1614.6876844170845*t-99.28772310019185)-.9643991794250523),s=1+t*(112.81167849163293+t*(2235.4883906010045+4844.063053251255*t))),e/s)};var nn=function(t){var e,s;if((s=Js(t))>44.014845965556525)return t<0?-1:1;if(s>=.625)s=1-2/((e=ki(2*s))+1),t<0&&(s=-s);else{if(0===t)return t;s=t+t*(e=t*t)*sn(e)}return s};void 0===globalThis.CroquetMath&&(globalThis.CroquetMath={}),Object.assign(globalThis.CroquetMath,{acos:Dt,acosh:es,asin:Ut,asinh:is,atan:as,atanh:ds,atan2:Vs,cbrt:Ms,cos:Xi,cosh:Wi,exp:ki,expm1:Pi,log:ts,log1p:De,log10:Fi,log2:Ji,sin:Di,sinh:Bi,tan:en,tanh:nn});const on=Math.pow;function rn(t){return t===1/0||t===-1/0}globalThis.CroquetMath.pow=(t,e)=>{if(isNaN(t)||isNaN(e))return NaN;if(rn(t)||rn(e))return on(t,e);if(0===t||0===e)return on(t,e);if(t<0&&!function(t){return Number.isInteger(t)}(e))return NaN;if(1===e)return t;if(2===e)return t*t;if(3===e)return t*t*t;if(4===e)return t*t*t*t;let s=1;t<0&&(t*=-1,s=on(-1,e));return globalThis.CroquetMath.exp(globalThis.CroquetMath.log(t)*e)*s};var an=function(t,e){return t0&&(e=i-1>>1,s=this.array[e],this.compare(t,s));)this.array[i]=s,i=e;this.array[i]=t},ln.prototype.heapify=function(t){var e;for(this.array=t,this.size=t.length,e=this.size>>1;e>=0;e--)this._percolateDown(e)},ln.prototype._percolateUp=function(t,e){for(var s,i,n=this.array[t];t>0&&(s=t-1>>1,i=this.array[s],e||this.compare(n,i));)this.array[t]=i,t=s;this.array[t]=n},ln.prototype._percolateDown=function(t){for(var e,s,i,n=this.size,o=this.size>>>1,r=this.array[t];tthis.size-1||t<0))return this._percolateUp(t,!0),this.poll()},ln.prototype.remove=function(t){for(var e=0;e1?(this.array[0]=this.array[--this.size],this._percolateDown(0)):this.size-=1,t}},ln.prototype.replaceTop=function(t){if(0!=this.size){var e=this.array[0];return this.array[0]=t,this._percolateDown(0),e}},ln.prototype.trim=function(){this.array=this.array.slice(0,this.size)},ln.prototype.isEmpty=function(){return 0===this.size},ln.prototype.forEach=function(t){if(!this.isEmpty()&&"function"==typeof t)for(var e=0,s=this.clone();!s.isEmpty();)t(s.poll(),e++)},ln.prototype.kSmallest=function(t){if(0==this.size)return[];t=Math.min(this.size,t);var e=new ln(this.compare);const s=Math.min((t>0?Math.pow(2,t-1):0)+1,this.size);e.size=s,e.array=this.array.slice(0,s);for(var i=new Array(t),n=0;nt.push(e))),t}asUnsortedArray(){return this.array.slice(0,this.size)}}var hn={exports:{}},un=hn.exports=function(t){return function(){var e=t,s=e.lib.WordArray;function i(t,e,i){for(var n=[],o=0,r=0;r>>6-r%4*2;n[o>>>2]|=a<<24-o%4*8,o++}return s.create(n,o)}e.enc.Base64={stringify:function(t){var e=t.words,s=t.sigBytes,i=this._map;t.clamp();for(var n=[],o=0;o>>2]>>>24-o%4*8&255)<<16|(e[o+1>>>2]>>>24-(o+1)%4*8&255)<<8|e[o+2>>>2]>>>24-(o+2)%4*8&255,a=0;a<4&&o+.75*a>>6*(3-a)&63));var l=i.charAt(64);if(l)for(;n.length%4;)n.push(l);return n.join("")},parse:function(t){var e=t.length,s=this._map,n=this._reverseMap;if(!n){n=this._reverseMap=[];for(var o=0;o>>31}var h=(i<<5|i>>>27)+l+r[c];h+=c<20?1518500249+(n&o|~n&a):c<40?1859775393+(n^o^a):c<60?(n&o|n&a|o&a)-1894007588:(n^o^a)-899497514,l=a,a=o,o=n<<30|n>>>2,n=i,i=h}s[0]=s[0]+i|0,s[1]=s[1]+n|0,s[2]=s[2]+o|0,s[3]=s[3]+a|0,s[4]=s[4]+l|0},_doFinalize:function(){var t=this._data,e=t.words,s=8*this._nDataBytes,i=8*t.sigBytes;return e[i>>>5]|=128<<24-i%32,e[14+(i+64>>>9<<4)]=Math.floor(s/4294967296),e[15+(i+64>>>9<<4)]=s,t.sigBytes=4*e.length,this._process(),this._hash},clone:function(){var t=n.clone.call(this);return t._hash=this._hash.clone(),t}});e.SHA1=n._createHelper(a),e.HmacSHA1=n._createHmacHelper(a)}(),t.SHA1}(w.exports);var yn={exports:{}};yn.exports=function(t){!function(){var e=t,s=e.lib.Base,i=e.enc.Utf8;e.algo.HMAC=s.extend({init:function(t,e){t=this._hasher=new t.init,"string"==typeof e&&(e=i.parse(e));var s=t.blockSize,n=4*s;e.sigBytes>n&&(e=t.finalize(e)),e.clamp();for(var o=this._oKey=e.clone(),r=this._iKey=e.clone(),a=o.words,l=r.words,c=0;c>>24)|4278255360&(n<<24|n>>>8)}var o=this._hash.words,r=t[e+0],l=t[e+1],m=t[e+2],p=t[e+3],f=t[e+4],b=t[e+5],y=t[e+6],g=t[e+7],w=t[e+8],Z=t[e+9],v=t[e+10],X=t[e+11],L=t[e+12],x=t[e+13],S=t[e+14],G=t[e+15],k=o[0],W=o[1],T=o[2],C=o[3];k=c(k,W,T,C,r,7,a[0]),C=c(C,k,W,T,l,12,a[1]),T=c(T,C,k,W,m,17,a[2]),W=c(W,T,C,k,p,22,a[3]),k=c(k,W,T,C,f,7,a[4]),C=c(C,k,W,T,b,12,a[5]),T=c(T,C,k,W,y,17,a[6]),W=c(W,T,C,k,g,22,a[7]),k=c(k,W,T,C,w,7,a[8]),C=c(C,k,W,T,Z,12,a[9]),T=c(T,C,k,W,v,17,a[10]),W=c(W,T,C,k,X,22,a[11]),k=c(k,W,T,C,L,7,a[12]),C=c(C,k,W,T,x,12,a[13]),T=c(T,C,k,W,S,17,a[14]),k=d(k,W=c(W,T,C,k,G,22,a[15]),T,C,l,5,a[16]),C=d(C,k,W,T,y,9,a[17]),T=d(T,C,k,W,X,14,a[18]),W=d(W,T,C,k,r,20,a[19]),k=d(k,W,T,C,b,5,a[20]),C=d(C,k,W,T,v,9,a[21]),T=d(T,C,k,W,G,14,a[22]),W=d(W,T,C,k,f,20,a[23]),k=d(k,W,T,C,Z,5,a[24]),C=d(C,k,W,T,S,9,a[25]),T=d(T,C,k,W,p,14,a[26]),W=d(W,T,C,k,w,20,a[27]),k=d(k,W,T,C,x,5,a[28]),C=d(C,k,W,T,m,9,a[29]),T=d(T,C,k,W,g,14,a[30]),k=h(k,W=d(W,T,C,k,L,20,a[31]),T,C,b,4,a[32]),C=h(C,k,W,T,w,11,a[33]),T=h(T,C,k,W,X,16,a[34]),W=h(W,T,C,k,S,23,a[35]),k=h(k,W,T,C,l,4,a[36]),C=h(C,k,W,T,f,11,a[37]),T=h(T,C,k,W,g,16,a[38]),W=h(W,T,C,k,v,23,a[39]),k=h(k,W,T,C,x,4,a[40]),C=h(C,k,W,T,r,11,a[41]),T=h(T,C,k,W,p,16,a[42]),W=h(W,T,C,k,y,23,a[43]),k=h(k,W,T,C,Z,4,a[44]),C=h(C,k,W,T,L,11,a[45]),T=h(T,C,k,W,G,16,a[46]),k=u(k,W=h(W,T,C,k,m,23,a[47]),T,C,r,6,a[48]),C=u(C,k,W,T,g,10,a[49]),T=u(T,C,k,W,S,15,a[50]),W=u(W,T,C,k,b,21,a[51]),k=u(k,W,T,C,L,6,a[52]),C=u(C,k,W,T,p,10,a[53]),T=u(T,C,k,W,v,15,a[54]),W=u(W,T,C,k,l,21,a[55]),k=u(k,W,T,C,w,6,a[56]),C=u(C,k,W,T,G,10,a[57]),T=u(T,C,k,W,y,15,a[58]),W=u(W,T,C,k,x,21,a[59]),k=u(k,W,T,C,f,6,a[60]),C=u(C,k,W,T,X,10,a[61]),T=u(T,C,k,W,m,15,a[62]),W=u(W,T,C,k,Z,21,a[63]),o[0]=o[0]+k|0,o[1]=o[1]+W|0,o[2]=o[2]+T|0,o[3]=o[3]+C|0},_doFinalize:function(){var t=this._data,s=t.words,i=8*this._nDataBytes,n=8*t.sigBytes;s[n>>>5]|=128<<24-n%32;var o=e.floor(i/4294967296),r=i;s[15+(n+64>>>9<<4)]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8),s[14+(n+64>>>9<<4)]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8),t.sigBytes=4*(s.length+1),this._process();for(var a=this._hash,l=a.words,c=0;c<4;c++){var d=l[c];l[c]=16711935&(d<<8|d>>>24)|4278255360&(d<<24|d>>>8)}return a},clone:function(){var t=o.clone.call(this);return t._hash=this._hash.clone(),t}});function c(t,e,s,i,n,o,r){var a=t+(e&s|~e&i)+n+r;return(a<>>32-o)+e}function d(t,e,s,i,n,o,r){var a=t+(e&i|s&~i)+n+r;return(a<>>32-o)+e}function h(t,e,s,i,n,o,r){var a=t+(e^s^i)+n+r;return(a<>>32-o)+e}function u(t,e,s,i,n,o,r){var a=t+(s^(e|~i))+n+r;return(a<>>32-o)+e}s.MD5=o._createHelper(l),s.HmacMD5=o._createHmacHelper(l)}(Math),t.MD5}(w.exports);var vn={exports:{}};vn.exports=function(t){return function(){var e=t,s=e.lib,i=s.Base,n=s.WordArray,o=e.algo,r=o.MD5,a=o.EvpKDF=i.extend({cfg:i.extend({keySize:4,hasher:r,iterations:1}),init:function(t){this.cfg=this.cfg.extend(t)},compute:function(t,e){for(var s,i=this.cfg,o=i.hasher.create(),r=n.create(),a=r.words,l=i.keySize,c=i.iterations;a.length>>2];t.sigBytes-=e}};i.BlockCipher=d.extend({cfg:d.cfg.extend({mode:m,padding:p}),reset:function(){var t;d.reset.call(this);var e=this.cfg,s=e.iv,i=e.mode;this._xformMode==this._ENC_XFORM_MODE?t=i.createEncryptor:(t=i.createDecryptor,this._minBufferSize=1),this._mode&&this._mode.__creator==t?this._mode.init(this,s&&s.words):(this._mode=t.call(i,this,s&&s.words),this._mode.__creator=t)},_doProcessBlock:function(t,e){this._mode.processBlock(t,e)},_doFinalize:function(){var t,e=this.cfg.padding;return this._xformMode==this._ENC_XFORM_MODE?(e.pad(this._data,this.blockSize),t=this._process(!0)):(t=this._process(!0),e.unpad(t)),t},blockSize:4});var f=i.CipherParams=n.extend({init:function(t){this.mixIn(t)},toString:function(t){return(t||this.formatter).stringify(this)}}),b=(s.format={}).OpenSSL={stringify:function(t){var e=t.ciphertext,s=t.salt;return(s?o.create([1398893684,1701076831]).concat(s).concat(e):e).toString(l)},parse:function(t){var e,s=l.parse(t),i=s.words;return 1398893684==i[0]&&1701076831==i[1]&&(e=o.create(i.slice(2,4)),i.splice(0,4),s.sigBytes-=16),f.create({ciphertext:s,salt:e})}},y=i.SerializableCipher=n.extend({cfg:n.extend({format:b}),encrypt:function(t,e,s,i){i=this.cfg.extend(i);var n=t.createEncryptor(s,i),o=n.finalize(e),r=n.cfg;return f.create({ciphertext:o,key:s,iv:r.iv,algorithm:t,mode:r.mode,padding:r.padding,blockSize:t.blockSize,formatter:i.format})},decrypt:function(t,e,s,i){return i=this.cfg.extend(i),e=this._parse(e,i.format),t.createDecryptor(s,i).finalize(e.ciphertext)},_parse:function(t,e){return"string"==typeof t?e.parse(t,this):t}}),g=(s.kdf={}).OpenSSL={execute:function(t,e,s,i){i||(i=o.random(8));var n=c.create({keySize:e+s}).compute(t,i),r=o.create(n.words.slice(e),4*s);return n.sigBytes=4*e,f.create({key:n,iv:r,salt:i})}},w=i.PasswordBasedCipher=y.extend({cfg:y.cfg.extend({kdf:g}),encrypt:function(t,e,s,i){var n=(i=this.cfg.extend(i)).kdf.execute(s,t.keySize,t.ivSize);i.iv=n.iv;var o=y.encrypt.call(this,t,e,n.key,i);return o.mixIn(n),o},decrypt:function(t,e,s,i){i=this.cfg.extend(i),e=this._parse(e,i.format);var n=i.kdf.execute(s,t.keySize,t.ivSize,e.salt);return i.iv=n.iv,y.decrypt.call(this,t,e,n.key,i)}})}()}(w.exports);var Ln=wn.exports=function(t){return function(){var e=t,s=e.lib.BlockCipher,i=e.algo,n=[],o=[],r=[],a=[],l=[],c=[],d=[],h=[],u=[],m=[];!function(){for(var t=[],e=0;e<256;e++)t[e]=e<128?e<<1:e<<1^283;var s=0,i=0;for(e=0;e<256;e++){var p=i^i<<1^i<<2^i<<3^i<<4;p=p>>>8^255&p^99,n[s]=p,o[p]=s;var f=t[s],b=t[f],y=t[b],g=257*t[p]^16843008*p;r[s]=g<<24|g>>>8,a[s]=g<<16|g>>>16,l[s]=g<<8|g>>>24,c[s]=g,g=16843009*y^65537*b^257*f^16843008*s,d[p]=g<<24|g>>>8,h[p]=g<<16|g>>>16,u[p]=g<<8|g>>>24,m[p]=g,s?(s=f^t[t[t[y^f]]],i^=t[t[i]]):s=i=1}}();var p=[0,1,2,4,8,16,32,64,128,27,54],f=i.AES=s.extend({_doReset:function(){if(!this._nRounds||this._keyPriorReset!==this._key){for(var t=this._keyPriorReset=this._key,e=t.words,s=t.sigBytes/4,i=4*((this._nRounds=s+6)+1),o=this._keySchedule=[],r=0;r6&&r%s==4&&(c=n[c>>>24]<<24|n[c>>>16&255]<<16|n[c>>>8&255]<<8|n[255&c]):(c=n[(c=c<<8|c>>>24)>>>24]<<24|n[c>>>16&255]<<16|n[c>>>8&255]<<8|n[255&c],c^=p[r/s|0]<<24),o[r]=o[r-s]^c);for(var a=this._invKeySchedule=[],l=0;l>>24]]^h[n[c>>>16&255]]^u[n[c>>>8&255]]^m[n[255&c]]}}},encryptBlock:function(t,e){this._doCryptBlock(t,e,this._keySchedule,r,a,l,c,n)},decryptBlock:function(t,e){var s=t[e+1];t[e+1]=t[e+3],t[e+3]=s,this._doCryptBlock(t,e,this._invKeySchedule,d,h,u,m,o),s=t[e+1],t[e+1]=t[e+3],t[e+3]=s},_doCryptBlock:function(t,e,s,i,n,o,r,a){for(var l=this._nRounds,c=t[e]^s[0],d=t[e+1]^s[1],h=t[e+2]^s[2],u=t[e+3]^s[3],m=4,p=1;p>>24]^n[d>>>16&255]^o[h>>>8&255]^r[255&u]^s[m++],b=i[d>>>24]^n[h>>>16&255]^o[u>>>8&255]^r[255&c]^s[m++],y=i[h>>>24]^n[u>>>16&255]^o[c>>>8&255]^r[255&d]^s[m++],g=i[u>>>24]^n[c>>>16&255]^o[d>>>8&255]^r[255&h]^s[m++];c=f,d=b,h=y,u=g}f=(a[c>>>24]<<24|a[d>>>16&255]<<16|a[h>>>8&255]<<8|a[255&u])^s[m++],b=(a[d>>>24]<<24|a[h>>>16&255]<<16|a[u>>>8&255]<<8|a[255&c])^s[m++],y=(a[h>>>24]<<24|a[u>>>16&255]<<16|a[c>>>8&255]<<8|a[255&d])^s[m++],g=(a[u>>>24]<<24|a[c>>>16&255]<<16|a[d>>>8&255]<<8|a[255&h])^s[m++],t[e]=f,t[e+1]=b,t[e+2]=y,t[e+3]=g},keySize:8});e.AES=s._createHelper(f)}(),t.AES}(w.exports),xn={exports:{}},Sn=xn.exports=function(t){return t.HmacSHA256}(w.exports);function Gn(t){let e=t.length;for(;--e>=0;)t[e]=0}const kn=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]),Wn=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),Tn=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]),Cn=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Vn=new Array(576);Gn(Vn);const Pn=new Array(60);Gn(Pn);const Rn=new Array(512);Gn(Rn);const Yn=new Array(256);Gn(Yn);const Mn=new Array(29);Gn(Mn);const In=new Array(30);function Hn(t,e,s,i,n){this.static_tree=t,this.extra_bits=e,this.extra_base=s,this.elems=i,this.max_length=n,this.has_stree=t&&t.length}let Kn,zn,Nn;function Fn(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e}Gn(In);const _n=t=>t<256?Rn[t]:Rn[256+(t>>>7)],jn=(t,e)=>{t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255},En=(t,e,s)=>{t.bi_valid>16-s?(t.bi_buf|=e<>16-t.bi_valid,t.bi_valid+=s-16):(t.bi_buf|=e<{En(t,s[2*e],s[2*e+1])},Jn=(t,e)=>{let s=0;do{s|=1&t,t>>>=1,s<<=1}while(--e>0);return s>>>1},Un=(t,e,s)=>{const i=new Array(16);let n,o,r=0;for(n=1;n<=15;n++)i[n]=r=r+s[n-1]<<1;for(o=0;o<=e;o++){let e=t[2*o+1];0!==e&&(t[2*o]=Jn(i[e]++,e))}},Dn=t=>{let e;for(e=0;e<286;e++)t.dyn_ltree[2*e]=0;for(e=0;e<30;e++)t.dyn_dtree[2*e]=0;for(e=0;e<19;e++)t.bl_tree[2*e]=0;t.dyn_ltree[512]=1,t.opt_len=t.static_len=0,t.last_lit=t.matches=0},On=t=>{t.bi_valid>8?jn(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0},Bn=(t,e,s,i)=>{const n=2*e,o=2*s;return t[n]{const i=t.heap[s];let n=s<<1;for(;n<=t.heap_len&&(n{let i,n,o,r,a=0;if(0!==t.last_lit)do{i=t.pending_buf[t.d_buf+2*a]<<8|t.pending_buf[t.d_buf+2*a+1],n=t.pending_buf[t.l_buf+a],a++,0===i?Qn(t,n,e):(o=Yn[n],Qn(t,o+256+1,e),r=kn[o],0!==r&&(n-=Mn[o],En(t,n,r)),i--,o=_n(i),Qn(t,o,s),r=Wn[o],0!==r&&(i-=In[o],En(t,i,r)))}while(a{const s=e.dyn_tree,i=e.stat_desc.static_tree,n=e.stat_desc.has_stree,o=e.stat_desc.elems;let r,a,l,c=-1;for(t.heap_len=0,t.heap_max=573,r=0;r>1;r>=1;r--)An(t,s,r);l=o;do{r=t.heap[1],t.heap[1]=t.heap[t.heap_len--],An(t,s,1),a=t.heap[1],t.heap[--t.heap_max]=r,t.heap[--t.heap_max]=a,s[2*l]=s[2*r]+s[2*a],t.depth[l]=(t.depth[r]>=t.depth[a]?t.depth[r]:t.depth[a])+1,s[2*r+1]=s[2*a+1]=l,t.heap[1]=l++,An(t,s,1)}while(t.heap_len>=2);t.heap[--t.heap_max]=t.heap[1],((t,e)=>{const s=e.dyn_tree,i=e.max_code,n=e.stat_desc.static_tree,o=e.stat_desc.has_stree,r=e.stat_desc.extra_bits,a=e.stat_desc.extra_base,l=e.stat_desc.max_length;let c,d,h,u,m,p,f=0;for(u=0;u<=15;u++)t.bl_count[u]=0;for(s[2*t.heap[t.heap_max]+1]=0,c=t.heap_max+1;c<573;c++)d=t.heap[c],u=s[2*s[2*d+1]+1]+1,u>l&&(u=l,f++),s[2*d+1]=u,d>i||(t.bl_count[u]++,m=0,d>=a&&(m=r[d-a]),p=s[2*d],t.opt_len+=p*(u+m),o&&(t.static_len+=p*(n[2*d+1]+m)));if(0!==f){do{for(u=l-1;0===t.bl_count[u];)u--;t.bl_count[u]--,t.bl_count[u+1]+=2,t.bl_count[l]--,f-=2}while(f>0);for(u=l;0!==u;u--)for(d=t.bl_count[u];0!==d;)h=t.heap[--c],h>i||(s[2*h+1]!==u&&(t.opt_len+=(u-s[2*h+1])*s[2*h],s[2*h+1]=u),d--)}})(t,e),Un(s,c,t.bl_count)},to=(t,e,s)=>{let i,n,o=-1,r=e[1],a=0,l=7,c=4;for(0===r&&(l=138,c=3),e[2*(s+1)+1]=65535,i=0;i<=s;i++)n=r,r=e[2*(i+1)+1],++a{let i,n,o=-1,r=e[1],a=0,l=7,c=4;for(0===r&&(l=138,c=3),i=0;i<=s;i++)if(n=r,r=e[2*(i+1)+1],!(++a{En(t,0+(i?1:0),3),((t,e,s,i)=>{On(t),i&&(jn(t,s),jn(t,~s)),t.pending_buf.set(t.window.subarray(e,e+s),t.pending),t.pending+=s})(t,e,s,!0)};var no=(t,e,s,i)=>{let n,o,r=0;t.level>0?(2===t.strm.data_type&&(t.strm.data_type=(t=>{let e,s=4093624447;for(e=0;e<=31;e++,s>>>=1)if(1&s&&0!==t.dyn_ltree[2*e])return 0;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return 1;for(e=32;e<256;e++)if(0!==t.dyn_ltree[2*e])return 1;return 0})(t)),qn(t,t.l_desc),qn(t,t.d_desc),r=(t=>{let e;for(to(t,t.dyn_ltree,t.l_desc.max_code),to(t,t.dyn_dtree,t.d_desc.max_code),qn(t,t.bl_desc),e=18;e>=3&&0===t.bl_tree[2*Cn[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e})(t),n=t.opt_len+3+7>>>3,o=t.static_len+3+7>>>3,o<=n&&(n=o)):n=o=s+5,s+4<=n&&-1!==e?io(t,e,s,i):4===t.strategy||o===n?(En(t,2+(i?1:0),3),$n(t,Vn,Pn)):(En(t,4+(i?1:0),3),((t,e,s,i)=>{let n;for(En(t,e-257,5),En(t,s-1,5),En(t,i-4,4),n=0;n{so||((()=>{let t,e,s,i,n;const o=new Array(16);for(s=0,i=0;i<28;i++)for(Mn[i]=s,t=0;t<1<>=7;i<30;i++)for(In[i]=n<<7,t=0;t<1<(t.pending_buf[t.d_buf+2*t.last_lit]=e>>>8&255,t.pending_buf[t.d_buf+2*t.last_lit+1]=255&e,t.pending_buf[t.l_buf+t.last_lit]=255&s,t.last_lit++,0===e?t.dyn_ltree[2*s]++:(t.matches++,e--,t.dyn_ltree[2*(Yn[s]+256+1)]++,t.dyn_dtree[2*_n(e)]++),t.last_lit===t.lit_bufsize-1),_tr_align:t=>{En(t,2,3),Qn(t,256,Vn),(t=>{16===t.bi_valid?(jn(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):t.bi_valid>=8&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)})(t)}};var ro=(t,e,s,i)=>{let n=65535&t|0,o=t>>>16&65535|0,r=0;for(;0!==s;){r=s>2e3?2e3:s,s-=r;do{n=n+e[i++]|0,o=o+n|0}while(--r);n%=65521,o%=65521}return n|o<<16|0};const ao=new Uint32Array((()=>{let t,e=[];for(var s=0;s<256;s++){t=s;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[s]=t}return e})());var lo=(t,e,s,i)=>{const n=ao,o=i+s;t^=-1;for(let s=i;s>>8^n[255&(t^e[s])];return-1^t},co={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},ho={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};const{_tr_init:uo,_tr_stored_block:mo,_tr_flush_block:po,_tr_tally:fo,_tr_align:bo}=oo,{Z_NO_FLUSH:yo,Z_PARTIAL_FLUSH:go,Z_FULL_FLUSH:wo,Z_FINISH:Zo,Z_BLOCK:vo,Z_OK:Xo,Z_STREAM_END:Lo,Z_STREAM_ERROR:xo,Z_DATA_ERROR:So,Z_BUF_ERROR:Go,Z_DEFAULT_COMPRESSION:ko,Z_FILTERED:Wo,Z_HUFFMAN_ONLY:To,Z_RLE:Co,Z_FIXED:Vo,Z_DEFAULT_STRATEGY:Po,Z_UNKNOWN:Ro,Z_DEFLATED:Yo}=ho,Mo=(t,e)=>(t.msg=co[e],e),Io=t=>(t<<1)-(t>4?9:0),Ho=t=>{let e=t.length;for(;--e>=0;)t[e]=0};let Ko=(t,e,s)=>(e<{const e=t.state;let s=e.pending;s>t.avail_out&&(s=t.avail_out),0!==s&&(t.output.set(e.pending_buf.subarray(e.pending_out,e.pending_out+s),t.next_out),t.next_out+=s,e.pending_out+=s,t.total_out+=s,t.avail_out-=s,e.pending-=s,0===e.pending&&(e.pending_out=0))},No=(t,e)=>{po(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,zo(t.strm)},Fo=(t,e)=>{t.pending_buf[t.pending++]=e},_o=(t,e)=>{t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e},jo=(t,e,s,i)=>{let n=t.avail_in;return n>i&&(n=i),0===n?0:(t.avail_in-=n,e.set(t.input.subarray(t.next_in,t.next_in+n),s),1===t.state.wrap?t.adler=ro(t.adler,e,n,s):2===t.state.wrap&&(t.adler=lo(t.adler,e,n,s)),t.next_in+=n,t.total_in+=n,n)},Eo=(t,e)=>{let s,i,n=t.max_chain_length,o=t.strstart,r=t.prev_length,a=t.nice_match;const l=t.strstart>t.w_size-262?t.strstart-(t.w_size-262):0,c=t.window,d=t.w_mask,h=t.prev,u=t.strstart+258;let m=c[o+r-1],p=c[o+r];t.prev_length>=t.good_match&&(n>>=2),a>t.lookahead&&(a=t.lookahead);do{if(s=e,c[s+r]===p&&c[s+r-1]===m&&c[s]===c[o]&&c[++s]===c[o+1]){o+=2,s++;do{}while(c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&c[++o]===c[++s]&&or){if(t.match_start=e,r=i,i>=a)break;m=c[o+r-1],p=c[o+r]}}}while((e=h[e&d])>l&&0!=--n);return r<=t.lookahead?r:t.lookahead},Qo=t=>{const e=t.w_size;let s,i,n,o,r;do{if(o=t.window_size-t.lookahead-t.strstart,t.strstart>=e+(e-262)){t.window.set(t.window.subarray(e,e+e),0),t.match_start-=e,t.strstart-=e,t.block_start-=e,i=t.hash_size,s=i;do{n=t.head[--s],t.head[s]=n>=e?n-e:0}while(--i);i=e,s=i;do{n=t.prev[--s],t.prev[s]=n>=e?n-e:0}while(--i);o+=e}if(0===t.strm.avail_in)break;if(i=jo(t.strm,t.window,t.strstart+t.lookahead,o),t.lookahead+=i,t.lookahead+t.insert>=3)for(r=t.strstart-t.insert,t.ins_h=t.window[r],t.ins_h=Ko(t,t.ins_h,t.window[r+1]);t.insert&&(t.ins_h=Ko(t,t.ins_h,t.window[r+3-1]),t.prev[r&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=r,r++,t.insert--,!(t.lookahead+t.insert<3)););}while(t.lookahead<262&&0!==t.strm.avail_in)},Jo=(t,e)=>{let s,i;for(;;){if(t.lookahead<262){if(Qo(t),t.lookahead<262&&e===yo)return 1;if(0===t.lookahead)break}if(s=0,t.lookahead>=3&&(t.ins_h=Ko(t,t.ins_h,t.window[t.strstart+3-1]),s=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==s&&t.strstart-s<=t.w_size-262&&(t.match_length=Eo(t,s)),t.match_length>=3)if(i=fo(t,t.strstart-t.match_start,t.match_length-3),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=3){t.match_length--;do{t.strstart++,t.ins_h=Ko(t,t.ins_h,t.window[t.strstart+3-1]),s=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart}while(0!=--t.match_length);t.strstart++}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=Ko(t,t.ins_h,t.window[t.strstart+1]);else i=fo(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(i&&(No(t,!1),0===t.strm.avail_out))return 1}return t.insert=t.strstart<2?t.strstart:2,e===Zo?(No(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(No(t,!1),0===t.strm.avail_out)?1:2},Uo=(t,e)=>{let s,i,n;for(;;){if(t.lookahead<262){if(Qo(t),t.lookahead<262&&e===yo)return 1;if(0===t.lookahead)break}if(s=0,t.lookahead>=3&&(t.ins_h=Ko(t,t.ins_h,t.window[t.strstart+3-1]),s=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=2,0!==s&&t.prev_length4096)&&(t.match_length=2)),t.prev_length>=3&&t.match_length<=t.prev_length){n=t.strstart+t.lookahead-3,i=fo(t,t.strstart-1-t.prev_match,t.prev_length-3),t.lookahead-=t.prev_length-1,t.prev_length-=2;do{++t.strstart<=n&&(t.ins_h=Ko(t,t.ins_h,t.window[t.strstart+3-1]),s=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart)}while(0!=--t.prev_length);if(t.match_available=0,t.match_length=2,t.strstart++,i&&(No(t,!1),0===t.strm.avail_out))return 1}else if(t.match_available){if(i=fo(t,0,t.window[t.strstart-1]),i&&No(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return 1}else t.match_available=1,t.strstart++,t.lookahead--}return t.match_available&&(i=fo(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<2?t.strstart:2,e===Zo?(No(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(No(t,!1),0===t.strm.avail_out)?1:2};function Do(t,e,s,i,n){this.good_length=t,this.max_lazy=e,this.nice_length=s,this.max_chain=i,this.func=n}const Oo=[new Do(0,0,0,0,((t,e)=>{let s=65535;for(s>t.pending_buf_size-5&&(s=t.pending_buf_size-5);;){if(t.lookahead<=1){if(Qo(t),0===t.lookahead&&e===yo)return 1;if(0===t.lookahead)break}t.strstart+=t.lookahead,t.lookahead=0;const i=t.block_start+s;if((0===t.strstart||t.strstart>=i)&&(t.lookahead=t.strstart-i,t.strstart=i,No(t,!1),0===t.strm.avail_out))return 1;if(t.strstart-t.block_start>=t.w_size-262&&(No(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===Zo?(No(t,!0),0===t.strm.avail_out?3:4):(t.strstart>t.block_start&&(No(t,!1),t.strm.avail_out),1)})),new Do(4,4,8,4,Jo),new Do(4,5,16,8,Jo),new Do(4,6,32,32,Jo),new Do(4,4,16,16,Uo),new Do(8,16,32,32,Uo),new Do(8,16,128,128,Uo),new Do(8,32,128,256,Uo),new Do(32,128,258,1024,Uo),new Do(32,258,258,4096,Uo)];function Bo(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Yo,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Uint16Array(1146),this.dyn_dtree=new Uint16Array(122),this.bl_tree=new Uint16Array(78),Ho(this.dyn_ltree),Ho(this.dyn_dtree),Ho(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Uint16Array(16),this.heap=new Uint16Array(573),Ho(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Uint16Array(573),Ho(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}const Ao=t=>{if(!t||!t.state)return Mo(t,xo);t.total_in=t.total_out=0,t.data_type=Ro;const e=t.state;return e.pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=e.wrap?42:113,t.adler=2===e.wrap?0:1,e.last_flush=yo,uo(e),Xo},$o=t=>{const e=Ao(t);var s;return e===Xo&&((s=t.state).window_size=2*s.w_size,Ho(s.head),s.max_lazy_match=Oo[s.level].max_lazy,s.good_match=Oo[s.level].good_length,s.nice_match=Oo[s.level].nice_length,s.max_chain_length=Oo[s.level].max_chain,s.strstart=0,s.block_start=0,s.lookahead=0,s.insert=0,s.match_length=s.prev_length=2,s.match_available=0,s.ins_h=0),e},qo=(t,e,s,i,n,o)=>{if(!t)return xo;let r=1;if(e===ko&&(e=6),i<0?(r=0,i=-i):i>15&&(r=2,i-=16),n<1||n>9||s!==Yo||i<8||i>15||e<0||e>9||o<0||o>Vo)return Mo(t,xo);8===i&&(i=9);const a=new Bo;return t.state=a,a.strm=t,a.wrap=r,a.gzhead=null,a.w_bits=i,a.w_size=1<qo(t,e,Yo,15,8,Po),deflateInit2:qo,deflateReset:$o,deflateResetKeep:Ao,deflateSetHeader:(t,e)=>t&&t.state?2!==t.state.wrap?xo:(t.state.gzhead=e,Xo):xo,deflate:(t,e)=>{let s,i;if(!t||!t.state||e>vo||e<0)return t?Mo(t,xo):xo;const n=t.state;if(!t.output||!t.input&&0!==t.avail_in||666===n.status&&e!==Zo)return Mo(t,0===t.avail_out?Go:xo);n.strm=t;const o=n.last_flush;if(n.last_flush=e,42===n.status)if(2===n.wrap)t.adler=0,Fo(n,31),Fo(n,139),Fo(n,8),n.gzhead?(Fo(n,(n.gzhead.text?1:0)+(n.gzhead.hcrc?2:0)+(n.gzhead.extra?4:0)+(n.gzhead.name?8:0)+(n.gzhead.comment?16:0)),Fo(n,255&n.gzhead.time),Fo(n,n.gzhead.time>>8&255),Fo(n,n.gzhead.time>>16&255),Fo(n,n.gzhead.time>>24&255),Fo(n,9===n.level?2:n.strategy>=To||n.level<2?4:0),Fo(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(Fo(n,255&n.gzhead.extra.length),Fo(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(t.adler=lo(t.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(Fo(n,0),Fo(n,0),Fo(n,0),Fo(n,0),Fo(n,0),Fo(n,9===n.level?2:n.strategy>=To||n.level<2?4:0),Fo(n,3),n.status=113);else{let e=Yo+(n.w_bits-8<<4)<<8,s=-1;s=n.strategy>=To||n.level<2?0:n.level<6?1:6===n.level?2:3,e|=s<<6,0!==n.strstart&&(e|=32),e+=31-e%31,n.status=113,_o(n,e),0!==n.strstart&&(_o(n,t.adler>>>16),_o(n,65535&t.adler)),t.adler=1}if(69===n.status)if(n.gzhead.extra){for(s=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>s&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),zo(t),s=n.pending,n.pending!==n.pending_buf_size));)Fo(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>s&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){s=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>s&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),zo(t),s=n.pending,n.pending===n.pending_buf_size)){i=1;break}i=n.gzindexs&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),0===i&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){s=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>s&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),zo(t),s=n.pending,n.pending===n.pending_buf_size)){i=1;break}i=n.gzindexs&&(t.adler=lo(t.adler,n.pending_buf,n.pending-s,s)),0===i&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&zo(t),n.pending+2<=n.pending_buf_size&&(Fo(n,255&t.adler),Fo(n,t.adler>>8&255),t.adler=0,n.status=113)):n.status=113),0!==n.pending){if(zo(t),0===t.avail_out)return n.last_flush=-1,Xo}else if(0===t.avail_in&&Io(e)<=Io(o)&&e!==Zo)return Mo(t,Go);if(666===n.status&&0!==t.avail_in)return Mo(t,Go);if(0!==t.avail_in||0!==n.lookahead||e!==yo&&666!==n.status){let s=n.strategy===To?((t,e)=>{let s;for(;;){if(0===t.lookahead&&(Qo(t),0===t.lookahead)){if(e===yo)return 1;break}if(t.match_length=0,s=fo(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,s&&(No(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===Zo?(No(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(No(t,!1),0===t.strm.avail_out)?1:2})(n,e):n.strategy===Co?((t,e)=>{let s,i,n,o;const r=t.window;for(;;){if(t.lookahead<=258){if(Qo(t),t.lookahead<=258&&e===yo)return 1;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=3&&t.strstart>0&&(n=t.strstart-1,i=r[n],i===r[++n]&&i===r[++n]&&i===r[++n])){o=t.strstart+258;do{}while(i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&nt.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=3?(s=fo(t,1,t.match_length-3),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(s=fo(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),s&&(No(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===Zo?(No(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(No(t,!1),0===t.strm.avail_out)?1:2})(n,e):Oo[n.level].func(n,e);if(3!==s&&4!==s||(n.status=666),1===s||3===s)return 0===t.avail_out&&(n.last_flush=-1),Xo;if(2===s&&(e===go?bo(n):e!==vo&&(mo(n,0,0,!1),e===wo&&(Ho(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),zo(t),0===t.avail_out))return n.last_flush=-1,Xo}return e!==Zo?Xo:n.wrap<=0?Lo:(2===n.wrap?(Fo(n,255&t.adler),Fo(n,t.adler>>8&255),Fo(n,t.adler>>16&255),Fo(n,t.adler>>24&255),Fo(n,255&t.total_in),Fo(n,t.total_in>>8&255),Fo(n,t.total_in>>16&255),Fo(n,t.total_in>>24&255)):(_o(n,t.adler>>>16),_o(n,65535&t.adler)),zo(t),n.wrap>0&&(n.wrap=-n.wrap),0!==n.pending?Xo:Lo)},deflateEnd:t=>{if(!t||!t.state)return xo;const e=t.state.status;return 42!==e&&69!==e&&73!==e&&91!==e&&103!==e&&113!==e&&666!==e?Mo(t,xo):(t.state=null,113===e?Mo(t,So):Xo)},deflateSetDictionary:(t,e)=>{let s=e.length;if(!t||!t.state)return xo;const i=t.state,n=i.wrap;if(2===n||1===n&&42!==i.status||i.lookahead)return xo;if(1===n&&(t.adler=ro(t.adler,e,s,0)),i.wrap=0,s>=i.w_size){0===n&&(Ho(i.head),i.strstart=0,i.block_start=0,i.insert=0);let t=new Uint8Array(i.w_size);t.set(e.subarray(s-i.w_size,s),0),e=t,s=i.w_size}const o=t.avail_in,r=t.next_in,a=t.input;for(t.avail_in=s,t.next_in=0,t.input=e,Qo(i);i.lookahead>=3;){let t=i.strstart,e=i.lookahead-2;do{i.ins_h=Ko(i,i.ins_h,i.window[t+3-1]),i.prev[t&i.w_mask]=i.head[i.ins_h],i.head[i.ins_h]=t,t++}while(--e);i.strstart=t,i.lookahead=2,Qo(i)}return i.strstart+=i.lookahead,i.block_start=i.strstart,i.insert=i.lookahead,i.lookahead=0,i.match_length=i.prev_length=2,i.match_available=0,t.next_in=r,t.input=a,t.avail_in=o,i.wrap=n,Xo},deflateInfo:"pako deflate (from Nodeca project)"};const er=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var sr=function(t){const e=Array.prototype.slice.call(arguments,1);for(;e.length;){const s=e.shift();if(s){if("object"!=typeof s)throw new TypeError(s+"must be non-object");for(const e in s)er(s,e)&&(t[e]=s[e])}}return t},ir=t=>{let e=0;for(let s=0,i=t.length;s=252?6:t>=248?5:t>=240?4:t>=224?3:t>=192?2:1;or[254]=or[254]=1;var rr=t=>{if("function"==typeof TextEncoder&&TextEncoder.prototype.encode)return(new TextEncoder).encode(t);let e,s,i,n,o,r=t.length,a=0;for(n=0;n>>6,e[o++]=128|63&s):s<65536?(e[o++]=224|s>>>12,e[o++]=128|s>>>6&63,e[o++]=128|63&s):(e[o++]=240|s>>>18,e[o++]=128|s>>>12&63,e[o++]=128|s>>>6&63,e[o++]=128|63&s);return e},ar=(t,e)=>{const s=e||t.length;if("function"==typeof TextDecoder&&TextDecoder.prototype.decode)return(new TextDecoder).decode(t.subarray(0,e));let i,n;const o=new Array(2*s);for(n=0,i=0;i4)o[n++]=65533,i+=r-1;else{for(e&=2===r?31:3===r?15:7;r>1&&i1?o[n++]=65533:e<65536?o[n++]=e:(e-=65536,o[n++]=55296|e>>10&1023,o[n++]=56320|1023&e)}}return((t,e)=>{if(e<65534&&t.subarray&&nr)return String.fromCharCode.apply(null,t.length===e?t:t.subarray(0,e));let s="";for(let i=0;i{(e=e||t.length)>t.length&&(e=t.length);let s=e-1;for(;s>=0&&128==(192&t[s]);)s--;return s<0||0===s?e:s+or[t[s]]>e?s:e};var cr=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0};const dr=Object.prototype.toString,{Z_NO_FLUSH:hr,Z_SYNC_FLUSH:ur,Z_FULL_FLUSH:mr,Z_FINISH:pr,Z_OK:fr,Z_STREAM_END:br,Z_DEFAULT_COMPRESSION:yr,Z_DEFAULT_STRATEGY:gr,Z_DEFLATED:wr}=ho;function Zr(t){this.options=sr({level:yr,method:wr,chunkSize:16384,windowBits:15,memLevel:8,strategy:gr},t||{});let e=this.options;e.raw&&e.windowBits>0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new cr,this.strm.avail_out=0;let s=tr.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(s!==fr)throw new Error(co[s]);if(e.header&&tr.deflateSetHeader(this.strm,e.header),e.dictionary){let t;if(t="string"==typeof e.dictionary?rr(e.dictionary):"[object ArrayBuffer]"===dr.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,s=tr.deflateSetDictionary(this.strm,t),s!==fr)throw new Error(co[s]);this._dict_set=!0}}function vr(t,e){const s=new Zr(e);if(s.push(t,!0),s.err)throw s.msg||co[s.err];return s.result}Zr.prototype.push=function(t,e){const s=this.strm,i=this.options.chunkSize;let n,o;if(this.ended)return!1;for(o=e===~~e?e:!0===e?pr:hr,"string"==typeof t?s.input=rr(t):"[object ArrayBuffer]"===dr.call(t)?s.input=new Uint8Array(t):s.input=t,s.next_in=0,s.avail_in=s.input.length;;)if(0===s.avail_out&&(s.output=new Uint8Array(i),s.next_out=0,s.avail_out=i),(o===ur||o===mr)&&s.avail_out<=6)this.onData(s.output.subarray(0,s.next_out)),s.avail_out=0;else{if(n=tr.deflate(s,o),n===br)return s.next_out>0&&this.onData(s.output.subarray(0,s.next_out)),n=tr.deflateEnd(this.strm),this.onEnd(n),this.ended=!0,n===fr;if(0!==s.avail_out){if(o>0&&s.next_out>0)this.onData(s.output.subarray(0,s.next_out)),s.avail_out=0;else if(0===s.avail_in)break}else this.onData(s.output)}return!0},Zr.prototype.onData=function(t){this.chunks.push(t)},Zr.prototype.onEnd=function(t){t===fr&&(this.result=ir(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg};var Xr={Deflate:Zr,deflate:vr,deflateRaw:function(t,e){return(e=e||{}).raw=!0,vr(t,e)},gzip:function(t,e){return(e=e||{}).gzip=!0,vr(t,e)},constants:ho};var Lr=function(t,e){let s,i,n,o,r,a,l,c,d,h,u,m,p,f,b,y,g,w,Z,v,X,L,x,S;const G=t.state;s=t.next_in,x=t.input,i=s+(t.avail_in-5),n=t.next_out,S=t.output,o=n-(e-t.avail_out),r=n+(t.avail_out-257),a=G.dmax,l=G.wsize,c=G.whave,d=G.wnext,h=G.window,u=G.hold,m=G.bits,p=G.lencode,f=G.distcode,b=(1<>>24,u>>>=w,m-=w,w=g>>>16&255,0===w)S[n++]=65535&g;else{if(!(16&w)){if(0==(64&w)){g=p[(65535&g)+(u&(1<>>=w,m-=w),m<15&&(u+=x[s++]<>>24,u>>>=w,m-=w,w=g>>>16&255,!(16&w)){if(0==(64&w)){g=f[(65535&g)+(u&(1<a){t.msg="invalid distance too far back",G.mode=30;break t}if(u>>>=w,m-=w,w=n-o,v>w){if(w=v-w,w>c&&G.sane){t.msg="invalid distance too far back",G.mode=30;break t}if(X=0,L=h,0===d){if(X+=l-w,w2;)S[n++]=L[X++],S[n++]=L[X++],S[n++]=L[X++],Z-=3;Z&&(S[n++]=L[X++],Z>1&&(S[n++]=L[X++]))}else{X=n-v;do{S[n++]=S[X++],S[n++]=S[X++],S[n++]=S[X++],Z-=3}while(Z>2);Z&&(S[n++]=S[X++],Z>1&&(S[n++]=S[X++]))}break}}break}}while(s>3,s-=Z,m-=Z<<3,u&=(1<{const l=a.bits;let c,d,h,u,m,p,f=0,b=0,y=0,g=0,w=0,Z=0,v=0,X=0,L=0,x=0,S=null,G=0;const k=new Uint16Array(16),W=new Uint16Array(16);let T,C,V,P=null,R=0;for(f=0;f<=15;f++)k[f]=0;for(b=0;b=1&&0===k[g];g--);if(w>g&&(w=g),0===g)return n[o++]=20971520,n[o++]=20971520,a.bits=1,0;for(y=1;y0&&(0===t||1!==g))return-1;for(W[1]=0,f=1;f<15;f++)W[f+1]=W[f]+k[f];for(b=0;b852||2===t&&L>592)return 1;for(;;){T=f-v,r[b]p?(C=P[R+r[b]],V=S[G+r[b]]):(C=96,V=0),c=1<>v)+d]=T<<24|C<<16|V|0}while(0!==d);for(c=1<>=1;if(0!==c?(x&=c-1,x+=c):x=0,b++,0==--k[f]){if(f===g)break;f=e[s+r[b]]}if(f>w&&(x&u)!==h){for(0===v&&(v=w),m+=y,Z=f-v,X=1<852||2===t&&L>592)return 1;h=x&u,n[h]=w<<24|Z<<16|m-o|0}}return 0!==x&&(n[m+x]=f-v<<24|64<<16|0),a.bits=w,0};const{Z_FINISH:Tr,Z_BLOCK:Cr,Z_TREES:Vr,Z_OK:Pr,Z_STREAM_END:Rr,Z_NEED_DICT:Yr,Z_STREAM_ERROR:Mr,Z_DATA_ERROR:Ir,Z_MEM_ERROR:Hr,Z_BUF_ERROR:Kr,Z_DEFLATED:zr}=ho,Nr=t=>(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24);function Fr(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}const _r=t=>{if(!t||!t.state)return Mr;const e=t.state;return t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=1,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new Int32Array(852),e.distcode=e.distdyn=new Int32Array(592),e.sane=1,e.back=-1,Pr},jr=t=>{if(!t||!t.state)return Mr;const e=t.state;return e.wsize=0,e.whave=0,e.wnext=0,_r(t)},Er=(t,e)=>{let s;if(!t||!t.state)return Mr;const i=t.state;return e<0?(s=0,e=-e):(s=1+(e>>4),e<48&&(e&=15)),e&&(e<8||e>15)?Mr:(null!==i.window&&i.wbits!==e&&(i.window=null),i.wrap=s,i.wbits=e,jr(t))},Qr=(t,e)=>{if(!t)return Mr;const s=new Fr;t.state=s,s.window=null;const i=Er(t,e);return i!==Pr&&(t.state=null),i};let Jr,Ur,Dr=!0;const Or=t=>{if(Dr){Jr=new Int32Array(512),Ur=new Int32Array(32);let e=0;for(;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(Wr(1,t.lens,0,288,Jr,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;Wr(2,t.lens,0,32,Ur,0,t.work,{bits:5}),Dr=!1}t.lencode=Jr,t.lenbits=9,t.distcode=Ur,t.distbits=5},Br=(t,e,s,i)=>{let n;const o=t.state;return null===o.window&&(o.wsize=1<=o.wsize?(o.window.set(e.subarray(s-o.wsize,s),0),o.wnext=0,o.whave=o.wsize):(n=o.wsize-o.wnext,n>i&&(n=i),o.window.set(e.subarray(s-i,s-i+n),o.wnext),(i-=n)?(o.window.set(e.subarray(s-i,s),0),o.wnext=i,o.whave=o.wsize):(o.wnext+=n,o.wnext===o.wsize&&(o.wnext=0),o.whave{let s,i,n,o,r,a,l,c,d,h,u,m,p,f,b,y,g,w,Z,v,X,L,x=0;const S=new Uint8Array(4);let G,k;const W=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(!t||!t.state||!t.output||!t.input&&0!==t.avail_in)return Mr;s=t.state,12===s.mode&&(s.mode=13),r=t.next_out,n=t.output,l=t.avail_out,o=t.next_in,i=t.input,a=t.avail_in,c=s.hold,d=s.bits,h=a,u=l,L=Pr;t:for(;;)switch(s.mode){case 1:if(0===s.wrap){s.mode=13;break}for(;d<16;){if(0===a)break t;a--,c+=i[o++]<>>8&255,s.check=lo(s.check,S,2,0),c=0,d=0,s.mode=2;break}if(s.flags=0,s.head&&(s.head.done=!1),!(1&s.wrap)||(((255&c)<<8)+(c>>8))%31){t.msg="incorrect header check",s.mode=30;break}if((15&c)!==zr){t.msg="unknown compression method",s.mode=30;break}if(c>>>=4,d-=4,X=8+(15&c),0===s.wbits)s.wbits=X;else if(X>s.wbits){t.msg="invalid window size",s.mode=30;break}s.dmax=1<>8&1),512&s.flags&&(S[0]=255&c,S[1]=c>>>8&255,s.check=lo(s.check,S,2,0)),c=0,d=0,s.mode=3;case 3:for(;d<32;){if(0===a)break t;a--,c+=i[o++]<>>8&255,S[2]=c>>>16&255,S[3]=c>>>24&255,s.check=lo(s.check,S,4,0)),c=0,d=0,s.mode=4;case 4:for(;d<16;){if(0===a)break t;a--,c+=i[o++]<>8),512&s.flags&&(S[0]=255&c,S[1]=c>>>8&255,s.check=lo(s.check,S,2,0)),c=0,d=0,s.mode=5;case 5:if(1024&s.flags){for(;d<16;){if(0===a)break t;a--,c+=i[o++]<>>8&255,s.check=lo(s.check,S,2,0)),c=0,d=0}else s.head&&(s.head.extra=null);s.mode=6;case 6:if(1024&s.flags&&(m=s.length,m>a&&(m=a),m&&(s.head&&(X=s.head.extra_len-s.length,s.head.extra||(s.head.extra=new Uint8Array(s.head.extra_len)),s.head.extra.set(i.subarray(o,o+m),X)),512&s.flags&&(s.check=lo(s.check,i,m,o)),a-=m,o+=m,s.length-=m),s.length))break t;s.length=0,s.mode=7;case 7:if(2048&s.flags){if(0===a)break t;m=0;do{X=i[o+m++],s.head&&X&&s.length<65536&&(s.head.name+=String.fromCharCode(X))}while(X&&m>9&1,s.head.done=!0),t.adler=s.check=0,s.mode=12;break;case 10:for(;d<32;){if(0===a)break t;a--,c+=i[o++]<>>=7&d,d-=7&d,s.mode=27;break}for(;d<3;){if(0===a)break t;a--,c+=i[o++]<>>=1,d-=1,3&c){case 0:s.mode=14;break;case 1:if(Or(s),s.mode=20,e===Vr){c>>>=2,d-=2;break t}break;case 2:s.mode=17;break;case 3:t.msg="invalid block type",s.mode=30}c>>>=2,d-=2;break;case 14:for(c>>>=7&d,d-=7&d;d<32;){if(0===a)break t;a--,c+=i[o++]<>>16^65535)){t.msg="invalid stored block lengths",s.mode=30;break}if(s.length=65535&c,c=0,d=0,s.mode=15,e===Vr)break t;case 15:s.mode=16;case 16:if(m=s.length,m){if(m>a&&(m=a),m>l&&(m=l),0===m)break t;n.set(i.subarray(o,o+m),r),a-=m,o+=m,l-=m,r+=m,s.length-=m;break}s.mode=12;break;case 17:for(;d<14;){if(0===a)break t;a--,c+=i[o++]<>>=5,d-=5,s.ndist=1+(31&c),c>>>=5,d-=5,s.ncode=4+(15&c),c>>>=4,d-=4,s.nlen>286||s.ndist>30){t.msg="too many length or distance symbols",s.mode=30;break}s.have=0,s.mode=18;case 18:for(;s.have>>=3,d-=3}for(;s.have<19;)s.lens[W[s.have++]]=0;if(s.lencode=s.lendyn,s.lenbits=7,G={bits:s.lenbits},L=Wr(0,s.lens,0,19,s.lencode,0,s.work,G),s.lenbits=G.bits,L){t.msg="invalid code lengths set",s.mode=30;break}s.have=0,s.mode=19;case 19:for(;s.have>>24,y=x>>>16&255,g=65535&x,!(b<=d);){if(0===a)break t;a--,c+=i[o++]<>>=b,d-=b,s.lens[s.have++]=g;else{if(16===g){for(k=b+2;d>>=b,d-=b,0===s.have){t.msg="invalid bit length repeat",s.mode=30;break}X=s.lens[s.have-1],m=3+(3&c),c>>>=2,d-=2}else if(17===g){for(k=b+3;d>>=b,d-=b,X=0,m=3+(7&c),c>>>=3,d-=3}else{for(k=b+7;d>>=b,d-=b,X=0,m=11+(127&c),c>>>=7,d-=7}if(s.have+m>s.nlen+s.ndist){t.msg="invalid bit length repeat",s.mode=30;break}for(;m--;)s.lens[s.have++]=X}}if(30===s.mode)break;if(0===s.lens[256]){t.msg="invalid code -- missing end-of-block",s.mode=30;break}if(s.lenbits=9,G={bits:s.lenbits},L=Wr(1,s.lens,0,s.nlen,s.lencode,0,s.work,G),s.lenbits=G.bits,L){t.msg="invalid literal/lengths set",s.mode=30;break}if(s.distbits=6,s.distcode=s.distdyn,G={bits:s.distbits},L=Wr(2,s.lens,s.nlen,s.ndist,s.distcode,0,s.work,G),s.distbits=G.bits,L){t.msg="invalid distances set",s.mode=30;break}if(s.mode=20,e===Vr)break t;case 20:s.mode=21;case 21:if(a>=6&&l>=258){t.next_out=r,t.avail_out=l,t.next_in=o,t.avail_in=a,s.hold=c,s.bits=d,Lr(t,u),r=t.next_out,n=t.output,l=t.avail_out,o=t.next_in,i=t.input,a=t.avail_in,c=s.hold,d=s.bits,12===s.mode&&(s.back=-1);break}for(s.back=0;x=s.lencode[c&(1<>>24,y=x>>>16&255,g=65535&x,!(b<=d);){if(0===a)break t;a--,c+=i[o++]<>w)],b=x>>>24,y=x>>>16&255,g=65535&x,!(w+b<=d);){if(0===a)break t;a--,c+=i[o++]<>>=w,d-=w,s.back+=w}if(c>>>=b,d-=b,s.back+=b,s.length=g,0===y){s.mode=26;break}if(32&y){s.back=-1,s.mode=12;break}if(64&y){t.msg="invalid literal/length code",s.mode=30;break}s.extra=15&y,s.mode=22;case 22:if(s.extra){for(k=s.extra;d>>=s.extra,d-=s.extra,s.back+=s.extra}s.was=s.length,s.mode=23;case 23:for(;x=s.distcode[c&(1<>>24,y=x>>>16&255,g=65535&x,!(b<=d);){if(0===a)break t;a--,c+=i[o++]<>w)],b=x>>>24,y=x>>>16&255,g=65535&x,!(w+b<=d);){if(0===a)break t;a--,c+=i[o++]<>>=w,d-=w,s.back+=w}if(c>>>=b,d-=b,s.back+=b,64&y){t.msg="invalid distance code",s.mode=30;break}s.offset=g,s.extra=15&y,s.mode=24;case 24:if(s.extra){for(k=s.extra;d>>=s.extra,d-=s.extra,s.back+=s.extra}if(s.offset>s.dmax){t.msg="invalid distance too far back",s.mode=30;break}s.mode=25;case 25:if(0===l)break t;if(m=u-l,s.offset>m){if(m=s.offset-m,m>s.whave&&s.sane){t.msg="invalid distance too far back",s.mode=30;break}m>s.wnext?(m-=s.wnext,p=s.wsize-m):p=s.wnext-m,m>s.length&&(m=s.length),f=s.window}else f=n,p=r-s.offset,m=s.length;m>l&&(m=l),l-=m,s.length-=m;do{n[r++]=f[p++]}while(--m);0===s.length&&(s.mode=21);break;case 26:if(0===l)break t;n[r++]=s.length,l--,s.mode=21;break;case 27:if(s.wrap){for(;d<32;){if(0===a)break t;a--,c|=i[o++]<Qr(t,15),inflateInit2:Qr,inflate:Ar,inflateEnd:t=>{if(!t||!t.state)return Mr;let e=t.state;return e.window&&(e.window=null),t.state=null,Pr},inflateGetHeader:(t,e)=>{if(!t||!t.state)return Mr;const s=t.state;return 0==(2&s.wrap)?Mr:(s.head=e,e.done=!1,Pr)},inflateSetDictionary:(t,e)=>{const s=e.length;let i,n,o;return t&&t.state?(i=t.state,0!==i.wrap&&11!==i.mode?Mr:11===i.mode&&(n=1,n=ro(n,e,s,0),n!==i.check)?Ir:(o=Br(t,e,s,s),o?(i.mode=31,Hr):(i.havedict=1,Pr))):Mr},inflateInfo:"pako inflate (from Nodeca project)"};var qr=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1};const ta=Object.prototype.toString,{Z_NO_FLUSH:ea,Z_FINISH:sa,Z_OK:ia,Z_STREAM_END:na,Z_NEED_DICT:oa,Z_STREAM_ERROR:ra,Z_DATA_ERROR:aa,Z_MEM_ERROR:la}=ho;function ca(t){this.options=sr({chunkSize:65536,windowBits:15,to:""},t||{});const e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(e.windowBits>=0&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new cr,this.strm.avail_out=0;let s=$r.inflateInit2(this.strm,e.windowBits);if(s!==ia)throw new Error(co[s]);if(this.header=new qr,$r.inflateGetHeader(this.strm,this.header),e.dictionary&&("string"==typeof e.dictionary?e.dictionary=rr(e.dictionary):"[object ArrayBuffer]"===ta.call(e.dictionary)&&(e.dictionary=new Uint8Array(e.dictionary)),e.raw&&(s=$r.inflateSetDictionary(this.strm,e.dictionary),s!==ia)))throw new Error(co[s])}function da(t,e){const s=new ca(e);if(s.push(t),s.err)throw s.msg||co[s.err];return s.result}ca.prototype.push=function(t,e){const s=this.strm,i=this.options.chunkSize,n=this.options.dictionary;let o,r,a;if(this.ended)return!1;for(r=e===~~e?e:!0===e?sa:ea,"[object ArrayBuffer]"===ta.call(t)?s.input=new Uint8Array(t):s.input=t,s.next_in=0,s.avail_in=s.input.length;;){for(0===s.avail_out&&(s.output=new Uint8Array(i),s.next_out=0,s.avail_out=i),o=$r.inflate(s,r),o===oa&&n&&(o=$r.inflateSetDictionary(s,n),o===ia?o=$r.inflate(s,r):o===aa&&(o=oa));s.avail_in>0&&o===na&&s.state.wrap>0&&0!==t[s.next_in];)$r.inflateReset(s),o=$r.inflate(s,r);switch(o){case ra:case aa:case oa:case la:return this.onEnd(o),this.ended=!0,!1}if(a=s.avail_out,s.next_out&&(0===s.avail_out||o===na))if("string"===this.options.to){let t=lr(s.output,s.next_out),e=s.next_out-t,n=ar(s.output,t);s.next_out=e,s.avail_out=i-e,e&&s.output.set(s.output.subarray(t,t+e),0),this.onData(n)}else this.onData(s.output.length===s.next_out?s.output:s.output.subarray(0,s.next_out));if(o!==ia||0!==a){if(o===na)return o=$r.inflateEnd(this.strm),this.onEnd(o),this.ended=!0,!0;if(0===s.avail_in)break}}return!0},ca.prototype.onData=function(t){this.chunks.push(t)},ca.prototype.onEnd=function(t){t===ia&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=ir(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg};var ha={Inflate:ca,inflate:da,inflateRaw:function(t,e){return(e=e||{}).raw=!0,da(t,e)},ungzip:da,constants:ho};const{Deflate:ua,deflate:ma,deflateRaw:pa,gzip:fa}=Xr,{Inflate:ba,inflate:ya,inflateRaw:ga,ungzip:wa}=ha;var Za={Deflate:ua,deflate:ma,deflateRaw:pa,gzip:fa,Inflate:ba,inflate:ya,inflateRaw:ga,ungzip:wa,constants:ho};class va{constructor(){this.url="(offline)",this.readyState=WebSocket.CONNECTING,this.bufferedAmount=0,setTimeout((()=>{this.readyState=WebSocket.OPEN,this.onopen&&this.onopen()}),50),this.start=Date.now()}send(t){const{id:e,action:s,args:i}=JSON.parse(t);switch(s){case"JOIN":return this.id=e,this.ticks=i.ticks.tick,this.seq=-16>>>0,this.reply("SYNC",{messages:[],time:this.time,seq:this.seq,tove:i.tove,reflector:"offline"}),this.reply("RECV",[this.time,++this.seq,{what:"users",joined:[i.user],active:1,total:1}]),void this.tick();case"SEND":{const t=[...i];return t[0]=this.time,t[1]=++this.seq,void this.reply("RECV",t)}case"PULSE":return;default:throw Error("Offline unhandled "+s)}}close(t,e){this.readyState=WebSocket.CLOSING,setTimeout((()=>{this.readyState=WebSocket.CLOSED,this.onclose&&this.onclose({code:t,reason:e})}),50)}get time(){return Date.now()-this.start}tick(){clearInterval(this.ticker),this.ticker=setInterval((()=>{this.reply("TICK",{time:this.time})}),this.ticks)}reply(t,e){setTimeout((()=>{this.onmessage&&this.onmessage({data:JSON.stringify({id:this.id,action:t,args:e})})}),50)}}function Xa(t,e,s){var i=void 0===e?null:e,n=function(t,e){var s=atob(t);if(e){for(var i=new Uint8Array(s.length),n=0,o=s.length;nconsole.error(`UploadWorker error: ${t.message}`);let Ka=0;const za=new Set;function Na(t){for(const e of za)if(e.id===t){const{appId:t,persistentId:s}=e.sessionSpec;return{appId:t,persistentId:s,uploadEncrypted:t=>e.uploadEncrypted(t),downloadEncrypted:t=>e.downloadEncrypted(t)}}return{}}class Fa{constructor(){!function(){const t=r.dev||!1!==r.dev&&"localhost",e=r.dev||!1!==r.dev&&(Ca||Va);Pa={messages:r.has("debug","messages",!1),sends:r.has("debug","sends",!1),ticks:r.has("debug","ticks",!1),pong:r.has("debug","pong",!1),snapshot:r.has("debug","snapshot",!1),session:r.has("debug","session",!1),initsnapshot:r.has("debug","initsnapshot",t),reflector:r.has("debug","reflector",e),offline:r.has("debug","offline",r.offline)},Pa.offline&&Pt.showMessage("Croquet: offline mode enabled, no multiuser",{level:"warning"})}(),this.reset()}reset(){globalThis.CROQUETVM===this.vm&&delete globalThis.CROQUETVM,this.vm=null,this.session=null,this.connection=this.connection||new _a(this),this.networkQueue=[],this.reflectorTime=0,this.msPerTick=this.msPerTick||0,this.tickMultiplier=this.tickMultiplier||1,this.extrapolatedTimeBase=Date.now(),this.key=this.key||null,this.tove=this.tove||null,this.viewId=this.viewId||Math.floor(Math.random()*36**10).toString(36),this.timeline="",this.rejoinTimeout&&clearTimeout(this.rejoinTimeout),this.rejoinTimeout=0,this.sendBuffer=[],this.users=0,this.usersTotal=0,this.cpuTime=0,this.triggeringCpuTime=null,this.synced=null,this.latency=0,this.latencyHistory&&(this.latencyHistory=[]),this.localTicker&&(globalThis.clearInterval(this.localTicker),delete this.localTicker),this.syncTimer&&(globalThis.clearTimeout(this.syncTimer),delete this.syncTimer),this.tuttiHistory=[],this.lastAnimationEnd=0,this.animationGapCheck=[],this.rateLimitedSendTimes=[],this.rateLimitBuffer=[],this.rateLimitSoftWarned=!1,this.rateLimitBufferWarned=!1,this.rateLimitLastLogged=0,this.payloadSizeWarned=!1,Yt.removeAllSubscriptionsFor(this.viewId),Yt.addSubscription(this.viewId,"__peers__",this.viewId,(t=>bt(`users now ${t.count}`)),"oncePerFrameWhileSynced"),this.leaving||Pt.showSyncWait(!0)}get id(){return this.vm?this.vm.id:this.sessionSpec.id}get persistentId(){return this.sessionSpec.persistentId}get versionId(){return this.sessionSpec.codeHash}get extrapolatedTime(){return Date.now()-this.extrapolatedTimeBase}get viewOnly(){return this.sessionSpec.viewOnly}get backlog(){return this.vm?this.reflectorTime-this.vm.time:0}get starvation(){return Date.now()-this.lastReceived}get lag(){return this.vm?Math.max(0,this.extrapolatedTime-this.vm.time-this.msPerTick):0}get activity(){return Date.now()-this.lastSent}get viewed(){return!(!this.session||!this.session.view)}get connected(){return this.connection.connected}get shouldLeaveWhenDisconnected(){return this.leaving||!this.canRejoinSeamlessly||0===this.sessionSpec.rejoinLimit}get canRejoinSeamlessly(){return!!this.timeline}checkForConnection(t){this.connection.checkForConnection(t)}dormantDisconnect(){this.connected&&this.connection.dormantDisconnect()}async initFromSessionSpec(t){const{name:e,optionsFromUrl:s,password:i,appId:n,apiKey:o,viewIdDebugSuffix:a}=t,l=n?`${n}/${e}`:e;a&&(this.viewId=this.viewId.replace(/_.*$/,"")+"_"+encodeURIComponent((""+a).slice(0,16)).replace(/[^a-z0-9]/gi,(t=>`_${"%"===t?"":t.charCodeAt(0).toString(16).toUpperCase()}`)));const c={...t.options};if(s)for(const t of s)t in r&&(c[t]=r[t]);const d={};for(const e of["hashOverride"])e in r?d[e]=r[e]:e in t&&(d[e]=t[e]);this.key=gn(i,"",{keySize:8});const h=await async function(t,e){return V(t+y(e))}(l,c),{developerId:u,token:m}=await this.verifyApiKey(o,n,h),{id:p,codeHash:f,computedCodeHash:b}=await async function(t,e,s,i){let n,o;const r=R[t];let a="";r?(n=r.codeHashes,o=r.computedCodeHash,a=" (code hashing from cache)"):(n=await Promise.all(P),o=await V([i,...n].join("|")),R[t]={codeHashes:n,computedCodeHash:o});const{hashOverride:l,...c}=s,d=l||o,h=await V(t+"|"+e+y(c)+d);if(W()&&!Y.has(h)){(L?"utf-8":[...document.getElementsByTagName("meta")].find((t=>t.getAttribute("charset"))))||console.warn('Croquet: Missing declaration. Croquet model code hashing might differ between browsers.'),T[o].what="Version ID",T[t].what="Persistent ID",T[h].what="Session ID",d!==o&&(n.push(o),T[o].what="Computed Version ID (replaced by overrideHash)",T[d]={what:"Version ID (as specified by overrideHash)"});const e=[...n,d,t,h].map((t=>({hash:t,...T[t]})));console.log(`Croquet: Debug Hashing for session ${h}${a}`,e),Y.add(h)}return W()||(T={}),{id:h,persistentId:t,codeHash:d,computedCodeHash:o}}(h,u,d,Wa);this.tove=await this.encrypt(p),Pa.session&&console.log(`Croquet session "${l}":\n sessionId=${p}${n?`\n persistentId=${h}`:""}\n versionId=${f===b?f:`${f} (specified in hashOverride)\n versionId=${b} (computed)`}\n viewId=${this.viewId}`),this.eventRateLimit=t.eventRateLimit,this.eventHistoryLimit=this.eventRateLimit,this.eventMaxBundles=this.eventRateLimit,this.sessionSpec={...t,options:c,name:l,id:p,persistentId:h,developerId:u,token:m,codeHash:f,computedCodeHash:b};const{msPerTick:g,multiplier:w}=this.getTickAndMultiplier();this.msPerTick=g,this.tickMultiplier=w,this.setUpActivityChecks()}async establishSession(){const{id:t,persistentId:e,codeHash:s}=this.sessionSpec;this.sessionSpec.snapshot={id:t,time:0,meta:{id:t,persistentId:e,codeHash:s,created:(new Date).toISOString()}};const i=new Promise((t=>this.sessionSpec.sessionJoined=t));this.checkForConnection(!1),Pa.session&&console.log(t,"waiting for SYNC"),await i}async verifyApiKey(t,e,s){const{signServer:i,apiKey:n}=Ra(t);if("none"===i)return{developerId:"unknown_dev_id"};try{const t=await fetch(`${i}/join?meta=login`,{method:"GET",mode:"cors",headers:{"X-Croquet-Auth":n,"X-Croquet-App":e,"X-Croquet-Id":s,"X-Croquet-Version":Wa,"X-Croquet-Path":new URL(Pt.referrerURL()).pathname},referrer:Pt.referrerURL(),referrerPolicy:"no-referrer-when-downgrade"}),{error:o,developerId:r,token:a}=await t.json();if(o)throw Error(o);return Pa.session&&console.log("Croquet: verified API key"),{developerId:r,token:a}}catch(e){throw Error(`Croquet API key validation failed for "${t}": ${e.message}`)}}lastKnownTime(t){return Math.max(t.time,t.externalTime)}takeSnapshot(){const t=this.vm.snapshot(),e=this.lastKnownTime(t),s=t.externalSeq;return t.meta={...this.sessionSpec.snapshot.meta,options:this.sessionSpec.options,time:e,seq:s,date:(new globalThis.CroquetViewDate).toISOString(),host:Ta?"localhost":window.location.hostname,sdk:Wa},delete t.meta.hash,t}takeSnapshotHandleErrors(){let t,e,s;try{t=ot.begin("snapshot"),s=this.takeSnapshot()}catch(t){return yt("snapshot",t),null}finally{e=ot.end("snapshot")-t}return Pa.snapshot&&console.log(this.id,`snapshot taken in ${Math.ceil(e)} ms`),s}scheduleSnapshot(){if(!this.connected||!this.vm||this.viewOnly)return;const t=this.vm.time,e=t-this.vm.lastSnapshotPoll;if(e<5e3)return void(Pa.snapshot&&console.log(`not requesting snapshot poll (${e}ms since poll scheduled)`));const s=new bl(t,0,"_","handlePollForSnapshot",[]);this.sendTagged(s,{debounce:5e3,msgID:"pollForSnapshot"}),Pa.snapshot&&console.log(this.id,"requesting snapshot poll via reflector")}handlePollForSnapshot(t){if(!0!==this.synced||this.viewOnly)return void(this.triggeringCpuTime=null);const e=this.triggeringCpuTime||this.cpuTime;let s,i,n;this.triggeringCpuTime=null,this.cpuTime=0;try{s=ot.begin("snapshot"),i={cpuTime:e,hash:this.vm.getSummaryHash(),viewId:this.viewId}}catch(t){return void yt("snapshot",t)}finally{n=ot.end("snapshot")-s,this.cpuTime-=n}Pa.snapshot&&console.log(this.id,`Summary hashing took ${Math.ceil(n)}ms`),Promise.resolve().then((()=>this.pollForSnapshot(t,i)))}pollForSnapshot(t,e){e.cpuTime+=Math.random(),Pa.snapshot&&console.log(this.id,"sending snapshot vote",e),this.sendTutti({time:t,topic:"snapshot",data:e,tallyTarget:["handleSnapshotVote"]})}handleSnapshotVote(t){const{tally:e}=t;Pa.snapshot&&console.log(this.id,"received snapshot votes",e);const{numberOfGroups:s,shouldUpload:i,dissidentFlag:n}=this.analyzeTally(e,"cpuTime");if(s>1){this.diverged=!0;const t=this.vm.diverged?this.vm.diverged.size:0;console.error(this.id,`Session diverged (#${t})! Snapshots fall into ${s} groups`)}if(!0===this.synced){if(i){const t=this.takeSnapshotHandleErrors();t&&Promise.resolve().then((()=>this.uploadSnapshot(t,n)))}}else Pa.snapshot&&console.log(this.id,"Ignoring snapshot vote during sync")}analyzeTally(t,e){let s=!1,i=null;const n=[],o={};let r=null;Object.keys(t).forEach(((t,e)=>{const s=JSON.parse(t);n.push(s);const{hash:i,viewId:a}=s;a===this.viewId&&(r=e),o[i]||(o[i]=[]),o[i].push(e)}));const a=Object.keys(o),l=a.length;let c=0;l>1&&(a.sort(((t,e)=>o[e].length-o[t].length)),o[a[0]].length===o[a[1]].length&&(Pa.snapshot&&console.log(this.id,"Deciding consensus by tie-break"),a[1]1&&a.sort(((t,s)=>n[t][e]-n[s][e])),a[0]===r&&(s=!0,t!==d&&(i={groupVotes:a.length,allVotes:n.length}))}return{numberOfGroups:l,shouldUpload:s,dissidentFlag:i}}snapshotPath(t,e,s){const i=Math.ceil(t).toString().padStart(10,"0"),{appId:n,persistentId:o,codeHash:r,apiKey:a}=this.sessionSpec;return a?`apps/${n}/snap/${r}/${o}.${this.id}/${i}_${e}.${s}`:`snapshots/${this.id}/${i}_${e}-${s}.snap`}hashSnapshot(t){return t.meta.hash?t.meta.hash:(t.meta.hashPromise||(t.meta.hashPromise=new Promise((e=>{const s={...t};delete s.meta,V(JSON.stringify(s)).then((s=>{t.meta.hash=s,delete t.meta.hashPromise,e(s)}))}))),t.meta.hashPromise)}uploadServer(t){if("string"==typeof r.files){let t=new URL(r.files,window.location).href;return t.endsWith("/")&&(t=t.slice(0,-1)),{url:t,apiKey:null}}const{apiKey:e,signServer:s}=Ra(t);if("none"===s&&!Pa.offline)throw Error("no file server configured");return{url:s,apiKey:e}}async uploadSnapshot(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;await this.hashSnapshot(t);const s=ot.begin("snapshot"),i=JSON.stringify(t),n=ot.end("snapshot")-s;Pa.snapshot&&console.log(this.id,`snapshot stringified (${i.length} bytes) in ${Math.ceil(n)}ms`);const{time:o,seq:r,hash:a}=t.meta,l=this.connection.socket;try{const t=await this.uploadEncrypted({content:i,path:this.snapshotPath(o,r,a),key:this.key,gzip:!0,debug:Pa.snapshot,what:"snapshot"});return this.connection.socket!==l?(console.warn(this.id,"Controller was reset while trying to upload snapshot"),!1):(this.announceSnapshotUrl(o,r,a,t,e),!0)}catch(t){return console.error(this.id,"Failed to upload snapshot"),!1}}announceSnapshotUrl(t,e,s,i,n){if(Pa.snapshot){let o=`time: ${t}, seq: ${e}, hash: ${s}`;n&&(o+=", as dissident; "+JSON.stringify(n)),console.log(this.id,`sending snapshot url to reflector (${o}): ${i}`)}try{this.connection.send(JSON.stringify({id:this.id,action:"SNAP",args:{time:t,seq:e,hash:s,url:i,dissident:n}}))}catch(t){console.error("ERROR while sending",t)}this.diverged&&this.vm.publishFromView("__VM__","__diverged__",{key:`@${t}#${e}`,url:i,dissident:n})}async diffDivergedSnapshots(t){const e=await Promise.all(t.map((t=>this.downloadEncrypted({url:t,gzip:!0,key:this.key,debug:Pa.snapshot,json:!0,what:"diverged snapshot"}))));for(const t of e)delete t.meta;let s=0;!function t(e,i,n){if(typeof e!=typeof i)console.log(`${n} diverged (${typeof e} vs ${typeof i}):`,e,i),s++;else if(Array.isArray(e)!==Array.isArray(i))console.log(`${n} diverged (array vs object):`,e,i),s++;else if("object"==typeof e){const o=e?Object.keys(e):[],r=i?Object.keys(i):[],a=o.filter((t=>!r.includes(t))),l=r.filter((t=>!o.includes(t)));(a.length||l.length)&&(console.log(`${n} diverged (keys mismatch):`,a,l),s++);for(const s of o)if(r.includes(s)){const o=Array.isArray(e)?`[${s}]`:s.match(/^[a-z_$][a-z0-9_$]*$/i)?`.${s}`:`["${s}"]`;t(e[s],i[s],`${n}${o}`)}}else e!==i&&(console.log(`${n} diverged (value mismatch):`,e,i),s++)}(e[0],e[1],"CROQUETVM"),s?console.log(`Total ${s} differences between diverged snapshots:`,e.slice(0,2)):console.log("... but diverged snapshots are identical?!")}async downloadEncrypted(t){let{url:e,gzip:s,key:i,debug:n,json:o,what:r}=t;e.startsWith("https://croquet.io/files/v1")&&(e=e.replace("https://croquet.io/files/v1","https://files.croquet.io"));const a=e.startsWith("offline:");let l=Date.now();const c=await(a?this.fetchOffline(e,r,n):fetch(e,{method:"GET",mode:"cors",headers:{"X-Croquet-App":this.sessionSpec.appId,"X-Croquet-Id":this.sessionSpec.persistentId,"X-Croquet-Session":this.sessionSpec.id,"X-Croquet-Version":Wa},referrer:Pt.referrerURL()})),d=await c.arrayBuffer();n&&console.log(this.id,`${r} fetched (${d.byteLength} bytes) in ${-l+(l=Date.now())}ms`),ot.addNetworkTraffic(`${r}_in`,d.byteLength);const h=this.decryptBinary(d,i);n&&console.log(this.id,`${r} decrypted (${h.length} bytes) in ${-l+(l=Date.now())}ms`);const u=s?Za.inflate(h):h;return n&&s&&console.log(this.id,`${r} inflated (${u.length} bytes) in ${-l+(l=Date.now())}ms`),o?JSON.parse((new TextDecoder).decode(u)):u}async fetchOffline(t,e,s){const i=++Ka;return new Promise(((n,o)=>{const r=Ta?"addListener":"addEventListener",a=Ta?"removeListener":"removeEventListener";Ha.postMessage({job:i,cmd:"getOfflineFile",url:t,id:this.id,what:e,debug:s,offline:Pa.offline});const l=t=>{if(i!==t.data.job)return;const{ok:s,status:r,statusText:c,body:d,bytes:h}=t.data;ot.addNetworkTraffic(`${e}_out`,h),Ha[a]("message",l),s?n({arrayBuffer:()=>d}):o(Error(`${r}: ${c}`))};try{Ha[r]("message",l)}catch(t){console.log("failed to add listener",t)}}))}async uploadEncrypted(t){let{content:e,path:s,key:i,gzip:n,keep:o,debug:r,what:a}=t;const l="string"==typeof e?(new TextEncoder).encode(e).buffer:e,c=o?void 0:[l],d="string"==typeof i?i:un.stringify(i),{apiKey:h,appId:u,persistentId:m}=this.sessionSpec,p=++Ka;return new Promise(((t,e)=>{const i=Ta?"addListener":"addEventListener",o=Ta?"removeListener":"removeEventListener";Ha.postMessage({job:p,cmd:"uploadEncrypted",server:this.uploadServer(h),path:s,buffer:l,keyBase64:d,gzip:n,referrer:Pt.referrerURL(),id:this.id,appId:u,persistentId:m,CROQUET_VERSION:Wa,debug:r,what:a,offline:Pa.offline},c);const f=s=>{if(p!==s.data.job)return;const{url:i,ok:n,status:r,statusText:l,bytes:c}=s.data;ot.addNetworkTraffic(`${a}_out`,c),Ha[o]("message",f),n?t(i):e(Error(`${r}: ${l}`))};try{Ha[i]("message",f)}catch(t){console.log("failed to add listener",t)}}))}persistentPath(t){const{appId:e,persistentId:s}=this.sessionSpec;return`apps/${e}/${s}/save/${t}`}pollForPersist(t,e,s,i,n){if(!this.synced)return;if(!this.sessionSpec.appId)throw Error("Persistence API requires appId");if(Pa.offline)return;const o={viewId:this.viewId,hash:i,ms:n+.001*Math.random()},r={persistTime:e,persistentHash:i,persistentString:s};Pa.snapshot&&console.log(this.id,`sending persistence vote for time @${e}`,o),this.sendTutti({time:t,topic:"persist",data:o,localContext:r,tallyTarget:["handlePersistVote"]})}async handlePersistVote(t){const{tally:e,localContext:s}=t;if(Pa.snapshot){const t=!!s?`for time @${s.persistTime}`:"that we didn't participate in";console.log(this.id,`received persistence vote ${t}`,e)}const{numberOfGroups:i,shouldUpload:n,dissidentFlag:o}=this.analyzeTally(e,"ms");if(i>1&&console.warn(this.id,`Persistence records fall into ${i} groups`),!n||!s)return;const{persistTime:r,persistentHash:a,persistentString:l}=s,c=await this.uploadEncrypted({path:this.persistentPath(a),content:l,key:this.key,gzip:!0,debug:Pa.snapshot,what:"persistence"});if(Pa.snapshot){const t=o?` (as dissident; ${JSON.stringify(o)})`:"";console.log(this.id,`sending persistent data url to reflector${t}: ${c}`)}try{this.connection.send(JSON.stringify({id:this.id,action:"SAVE",args:{persistTime:r,url:c,dissident:o}}))}catch(t){console.error("ERROR while sending",t)}}convertReflectorMessage(t){let e="noop",s=[];switch(t[2].what){case"users":{const{joined:i,left:n,active:o,total:r}=t[2];this.users=o,this.usersTotal=r;const a="__peers__",l={entered:i||[],exited:n||[],count:o};e="publishFromModelOnly",s=["__VM__",a,l],Yt.handleEvent(this.viewId+":"+a,l);break}case"tally":{const{tuttiSeq:i,tuttiKey:n,tally:o,tallyTarget:r,missingClients:a}=t[2];(Pa.messages||Pa.snapshot)&&a&&console.log(`${a} ${1===a?"client":"clients"} failed to participate in tally ${n||i}`),e="handleTuttiResult",s=[{tuttiSeq:i,tuttiKey:n,tally:o,tallyTarget:r}];break}}const i=new bl(0,0,"_",e,s);t[2]=i.asState()[2]}handleTuttiResult(t){const{tuttiSeq:e,tuttiKey:s,tally:i,tallyTarget:n}=t,o=s?t=>t.tuttiKey===s:t=>t.dummyTuttiSeq===e,r=this.tuttiHistory.findIndex(o),a=-1!==r&&this.tuttiHistory.splice(r,1)[0];let l=null,c=null;if(a&&(l=a.payload,c=a.localContext),n){const[t,...e]=n,s=[...e,{tally:i,localPayload:l,localContext:c}],o=new bl(0,0,"_",t,s);this.vm.verifyExternal(o),o.executeOn(this.vm,!0)}}async receive(t,e){const s=this.lastReceived;switch(this.lastReceived=this.connection.lastReceived,t){case"SYNC":{this.syncReceived=!0,this.clearSyncReceiptTimeout(),za.add(this);const{progressReporter:t}=this.sessionSpec,s=t||(()=>{}),{messages:i,url:n,persisted:o,time:r,seq:a,snapshotSeq:l,tove:c,reflector:d,flags:h}=e;if(c&&c!==this.tove)try{if(this.decrypt(c)!==this.id)throw Error("wrong sessionId in tove?!")}catch(t){return this.connection.closeConnectionWithError("SYNC",Error(`session password check: ${t.message}`),4200),void s(-1)}const u=e.timeline||e.reflectorSession;this.flags=h||{};const m=o?"persistence":"snapshot";Pa.session&&console.log(this.id,`received SYNC from ${d} reflector: time ${r}, ${i.length} messages, ${m} ${n||""}`);let p=!!this.vm;if(p){this.networkQueue.length=0;const t=!!u&&u===this.timeline,e=i[0],s=a,n=void 0!==l?l:e?e[1]:s;Pa.messages&&console.log(this.id,`rejoin: we have #${this.vm.seq} SYNC has #${n}-#${s}`);let o=t&&fl(n,this.vm.seq)&&fl(this.vm.seq,s)&&r>=this.reflectorTime;if(o){let t=0;e&&fl(e[1],this.vm.seq)&&(t=this.vm.seq-e[1]+1>>>0);for(let e=t;o&&e0){const t=this.sendBuffer;this.sendBuffer=[],Pa.session&&console.log(this.id,`rejoin: sending ${t.length} messages buffered while disconnected`);for(const e of t)e()}}else Pa.session&&console.log(this.id,"cannot rejoin seamlessly; rebooting model/view"),this.leave(!0),p=!1}const f=this.networkQueue;this.networkQueue=[];for(const t of i){if("string"!=typeof t[2])this.convertReflectorMessage(t);else try{t[2]=this.decryptPayload(t[2])[0]}catch(t){return this.connection.closeConnectionWithError("SYNC",Error(`session password decrypt: ${t.message}`),4200),void s(-1)}Pa.messages&&console.log(this.id,"received in SYNC "+JSON.stringify(t)),this.networkQueue.push(t)}if(this.networkQueue.push(...f),r>this.reflectorTime&&this.timeFromReflector(r,"reflector"),p)return Pa.session&&console.log(this.id,"seamless rejoin successful"),void this.sessionSpec.sessionJoined();let b;if(this.timeline=u||"",Pa.snapshot&&n&&console.log(`${this.id} fetching ${m} ${n}`),n)try{b=await this.downloadEncrypted({url:n,gzip:!0,key:this.key,debug:Pa.snapshot,json:!0,what:m})}catch(t){return this.connection.closeConnectionWithError("SYNC",Error(`failed to fetch ${m}: ${t.message}`),4200),void s(-1)}if(!this.connected)return console.log(this.id,"disconnected during SYNC"),void s(-1);o?this.install(b):(b&&(this.sessionSpec.snapshot=b),this.install()),Pa.session&&console.log(`${this.id} fast-forwarding from ${Math.round(this.vm.time)} to at least ${r}`);const y=this.vm.time,g=await new Promise((t=>{const{port1:e,port2:i}=new MessageChannel;e.onmessage=()=>{let e=!0;if(this.vm.time===this.reflectorTime)this.viewId in this.vm.views&&(s(1),t(!0),e=!1);else{const t=(this.vm.time-y)/(this.reflectorTime-y);s(t)}e&&this.stepSession("fastForward",{budget:200})};this.fastForwardHandler=e=>{this.connected&&this.vm?"error"===e?(s(-1),t(!1)):i.postMessage("tick"):(console.log(this.id,"disconnected during SYNC fast-forwarding"),s(-1),t(!1))},Promise.resolve().then((()=>this.stepSession("fastForward",{budget:200})))}));return delete this.fastForwardHandler,g&&Pa.session&&console.log(`${this.id} fast-forwarded to ${Math.round(this.vm.time)}`),g&&this.vm.diverged&&Pt.showMessage("Croquet: session had diverged",{level:"warning",only:"once"}),void(g&&this.sessionSpec.sessionJoined())}case"RECV":{const t=e;if(t[1]>>>=0,"string"!=typeof t[2])Pa.messages&&console.log(this.id,"received META "+JSON.stringify(t)),this.convertReflectorMessage(t),Pa.messages&&console.log(this.id,"converted to "+JSON.stringify(t));else try{const[e,s,i]=this.decryptPayload(t[2]);t[2]=e,s===this.viewId&&this.addToStatistics(i,this.lastReceived),Pa.messages&&console.log(this.id,"received "+JSON.stringify(t))}catch(t){return void this.connection.closeConnectionWithError("RECV",Error(`session password decrypt: ${t.message}`),4200)}let s;return this.networkQueue.push(t),this.flags.rawtime&&(s=t[t.length-1]),this.timeFromReflector(t[0],"reflector",s),void(this.simulateIfNeeded&&Promise.resolve().then((()=>this.simulateIfNeeded())))}case"TICK":{if(!this.vm)return;const t="number"==typeof e?e:e.time;if(Pa.ticks){const e=s&&this.lastReceived-s-this.msPerTick*this.tickMultiplier|0;console.log(this.id,`Controller received TICK ${t} ${Math.abs(e)<5?"on time":e<0?"early":"late"} (${e} ms)`)}return this.timeFromReflector(t,"reflector"),this.tickMultiplier>1&&this.multiplyTick(t),void(this.simulateIfNeeded&&Promise.resolve().then((()=>this.simulateIfNeeded())))}case"INFO":{const{msg:t,options:s}=e;return void Pt.showMessage(t,s)}case"REQU":return Pa.snapshot&&console.log("received REQU (snapshot request) from reflector"),void(this.cpuTime=12345);default:console.warn("Unknown action:",t,e)}}install(t){const e=Date.now(),{snapshot:s,initFn:i,options:n}=this.sessionSpec,[o,r]=s.modelsById?["deserializ","snapshot"]:["initializ","root model"];Pa.session&&console.log(`${this.id} ${o}ing ${r}`);let a=new ml(s,(()=>{try{return i(n,t)}catch(t){throw yt("init",t,"fatal"),t}}));if((Pa.session||Pa.snapshot&&s.modelsById)&&console.log(`${this.id} ${r} ${o}ed in ${Date.now()-e}ms`),Pa.initsnapshot&&!s.modelsById){Pa.snapshot&&console.log(`${this.id} exercising snapshot and restore after init()`);let t=null;try{t=JSON.stringify(a.snapshot())}catch(t){throw yt("initial snapshot",t,"fatal"),t}try{a=new ml(JSON.parse(t),(()=>i(n)))}catch(t){throw yt("initial snapshot resume",t,"fatal"),t}}const l=this.lastKnownTime(a);this.reflectorTime=Math.max(this.reflectorTime,l),this.setVM(a)}setVM(t){this.vm=t,this.vm.controller=this}sendJoin(){this.syncReceived=!1,delete this.fastForwardHandler,this.rejoinTimeout&&(clearTimeout(this.rejoinTimeout),this.rejoinTimeout=0),Pa.session&&console.log(this.id,"Controller sending JOIN");const{tick:t,delay:e}=this.getTickAndMultiplier(),{name:s,codeHash:i,appId:n,apiKey:o,persistentId:r,developerId:a,heraldUrl:l,rejoinLimit:c,autoSleep:d,computedCodeHash:h,location:u,flags:m}=this.sessionSpec,{apiKey:p}=Ra(o),f=u?[this.viewId]:this.viewId,b={name:s,apiKey:p,appId:n,persistentId:r,url:Pt.referrerURL(),sdk:Wa,developerId:a,version:1,user:f,location:u,ticks:{tick:t,delay:e},dormantDelay:d,tove:this.tove,codeHash:i};l&&Object.assign(b,{heraldUrl:l}),c&&Object.assign(b,{leaveDelay:c+250}),h!==i&&Object.assign(b,{computedCodeHash:h}),m&&Object.assign(b,{flags:m}),this.connection.send(JSON.stringify({id:this.id,action:"JOIN",args:b})),this.syncReceiptTimeout=setTimeout((()=>{delete this.syncReceiptTimeout,this.syncReceived||this.connection.closeConnectionWithError("JOIN",Error("Initial reflector connection timed out"))}),5e3)}clearSyncReceiptTimeout(){this.syncReceiptTimeout&&(clearTimeout(this.syncReceiptTimeout),delete this.syncReceiptTimeout)}connectionInterrupted(){this.syncReceived&&(this.shouldLeaveWhenDisconnected?this.leave():this.rejoinTimeout||(this.rejoinTimeout=setTimeout((()=>{Pa.session&&console.log(this.id,"rejoin timed out"),this.rejoinTimeout=0,this.leave()}),this.sessionSpec.rejoinLimit)))}leave(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const{rebootModelView:e}=this.sessionSpec;if(this.reset(),Pa.session&&console.log(this.id,`resetting ${t?"(but keeping)":"and discarding"} controller`),t||za.delete(this),!this.sessionSpec)throw Error("do not discard sessionSpec!");e()}async encrypt(t){const e=Z.random(16),s=Ln.encrypt(t,this.key,{iv:e}),i=Sn(t,this.key);return`${un.stringify(e)}${un.stringify(i)}${s}`}get deprecatedDefaultKey(){return Ia||(Ia=gn("THIS SHOULDN'T BE IN LOGS","",{keySize:8})),Ia}decrypt(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.key;const s=un.parse(t.slice(0,24)),i=un.parse(t.slice(24,68)),n=t.slice(68),o=Ln.decrypt(n,e,{iv:s});let r="";try{r=pn.stringify(o)}catch(t){}const a=Sn(r,this.key);if(this.compareHmacs(i.words,a.words))return r;if(e!==this.deprecatedDefaultKey)return this.decrypt(t,this.deprecatedDefaultKey);throw Error("Decryption error")}decryptBinary(t,e){const s=(new TextDecoder).decode(new Uint8Array(t,0,4));let i,n,o,r,a;switch("string"==typeof e&&(e=un.parse(e)),s){case"CRQ0":i=(new TextDecoder).decode(t),n=un.parse(i.slice(4,28)),o=un.parse(i.slice(28,72)),r=i.slice(72),a=Ln.decrypt(r,e,{iv:n});break;case"CRQ1":i=new Uint8Array(t),n=Z.create(i.subarray(4,20)),o=Z.create(i.subarray(20,52)),r=Z.create(i.subarray(52)),a=Ln.decrypt({ciphertext:r},e,{iv:n});break;default:throw Error(`${this.id} unknown encryption version ${s}`)}a.clamp();const l=Sn(a,e);if(this.compareHmacs(o.words,l.words))return S(a);if(e!==this.deprecatedDefaultKey)return this.decryptBinary(t,this.deprecatedDefaultKey);throw Error("Decryption error")}async encryptMessage(t,e,s){const[i,n,o]=t.asState();return[i,n,await this.encryptPayload([o,e,s])]}async encryptPayload(t){return this.encrypt(JSON.stringify(t))}decryptPayload(t){return JSON.parse(this.decrypt(t))}compareHmacs(t,e){let s=t.length===e.length;for(let i=0;i16384)return void console.warn(`${this.id} Message with payload of ${e} bytes exceeds maximum 16384 and will not be sent to reflector.`);!this.payloadSizeWarned&&e>4096&&(console.log(`${this.id} Message with payload of ${e} bytes being sent to reflector. Maximum recommended is 4096.`),this.payloadSizeWarned=!0);const s=Date.now(),i=this.rateLimitedSendTimes,n=this.rateLimitBuffer;if(ot.perSecondTally({requestedMessages:1}),n.length)return void this.addToRateLimitBuffer(t);let o=0;if(i.length&&this.synced){const t=i[i.length-1],e=1e3/this.eventRateLimit-(s-t);e>1&&(o=Math.ceil(e))}o?(this.addToRateLimitBuffer(t),setTimeout((()=>this.serviceRateLimitBuffer()),o)):(this.recordRateLimitedSend(s),this.socketSendMessage(t),ot.perSecondTally({sentSingleMessages:1,sentMessagesTotal:1,sentPayloadTotal:e}))}recordRateLimitedSend(t){const e=this.rateLimitedSendTimes;!this.synced&&e.length&&e[e.length-1]===t||(e.push(t),e.length>this.eventHistoryLimit&&e.shift()),!this.rateLimitSoftWarned&&e.length===this.eventHistoryLimit&&t-e[0]<1010&&(console.warn(`${this.id} Sends to reflector are at or above recommended limit of ${this.eventHistoryLimit} within one second. Events will be bundled as necessary to keep to the limit.`),this.rateLimitSoftWarned=!0)}addToRateLimitBuffer(t){ot.perSecondTally({bundledMessages:1});const e=Date.now(),s=t.asState(),i=s[2].length,n=this.rateLimitBuffer;if(n.length){const t=n[n.length-1],{msgStates:o,totalPayload:r}=t;if(r<4096)return o.push({msgState:s,bufferTime:e}),void(t.totalPayload+=i)}ot.perSecondTally({newBundles:1}),n.push({msgStates:[{msgState:s,bufferTime:e}],totalPayload:i});const o=n.length;Pa.session&&o%5==0&&o!==this.rateLimitLastLogged&&(console.log(`${this.id} SEND rate-limit buffer grew to ${o} event bundles (max ${this.eventMaxBundles})`),this.rateLimitLastLogged=o),o>this.eventMaxBundles?(console.error(`${this.id} Disconnecting after overflow of SEND rate-limit buffer.`),this.connection.closeConnectionWithError("SEND",Error("Send rate exceeded"),4200)):!this.rateLimitBufferWarned&&o>this.eventMaxBundles/2&&(console.warn(`${this.id} SEND rate-limit buffer is 50% full. If send rate does not drop, the app will be disconnected.`),this.rateLimitBufferWarned=!0)}serviceRateLimitBuffer(){if(!this.connected)return;const t=this.rateLimitBuffer;if(!t.length)return;const e=Date.now(),s=1e3/this.eventRateLimit,i=this.rateLimitedSendTimes;if(i.length){const t=i[i.length-1];if(s-(e-t)>0)return}const n=t.shift(),{msgStates:o,totalPayload:r}=n,a=[];let l=0;if(o.forEach((t=>{a.push(t.msgState),l+=e-t.bufferTime})),1===a.length){const t=bl.fromState(a[0],this.vm);this.socketSendMessage(t)}else{const t=new bl(this.vm.time,0,"_","handleBundledEvents",[a]);this.socketSendMessage(t)}if(this.recordRateLimitedSend(e),ot.perSecondTally({sentBundles:1,sentMessagesTotal:o.length,sendDelay:l,sentBundlePayload:r,sentPayloadTotal:r}),Pa.session&&this.connected){const e=t.length;e&&e%5==0&&e!==this.rateLimitLastLogged&&(console.log(`${this.id} SEND rate-limit buffer dropped to ${e} event bundles`),this.rateLimitLastLogged=e)}t.length&&setTimeout((()=>this.serviceRateLimitBuffer()),s)}async socketSendMessage(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;const s=await this.encryptMessage(t,this.viewId,Date.now()),i=e?`tagged SEND ${t.asState()} with tags ${JSON.stringify(e)}`:`SEND ${t.asState()}`;if(!this.connected)return void(this.vm&&(Pa.sends&&console.log(this.id,`buffering ${i}`),this.sendBuffer.push((()=>this.socketSendMessage(t,e)))));Pa.sends&&console.log(this.id,`sending ${i}`);const n={id:this.id,action:"SEND",args:[...s,this.latency]};e&&(n.tags=e),this.lastSent=Date.now(),this.connection.send(JSON.stringify(n))}async sendTagged(t,e){this.viewOnly||this.socketSendMessage(t,e)}async sendTutti(t){let{time:e,topic:s,data:i,localContext:n=null,firstMessage:o=null,wantsVote:r=!0,tallyTarget:a=null}=t;if(this.viewOnly)return;const l=o&&await this.encryptMessage(o,this.viewId,Date.now()),c=y(i);if(!this.connected)return void(this.vm&&(Pa.sends&&console.log(this.id,`buffering "${s}" TUTTI ${c} ${o&&o.asState()}`),this.sendBuffer.push((()=>this.sendTutti({time:e,topic:s,data:i,localContext:n,firstMessage:o,wantsVote:r,tallyTarget:a})))));Pa.sends&&console.log(this.id,`sending "${s}" TUTTI ${c} ${o&&o.asState()}`),this.lastSent=Date.now();const d=`${s}@${e}`;this.connection.send(JSON.stringify({id:this.id,action:"TUTTI",args:[e,0,c,l,r,a,d]})),this.tuttiHistory.length>100&&this.tuttiHistory.shift(),this.tuttiHistory.push({time:e,tuttiKey:d,dummyTuttiSeq:0,payload:c,localContext:n})}sendLog(){for(var t=arguments.length,e=new Array(t),s=0;sthis.sendLog(...e))))}addToStatistics(t,e){this.latency=e-t,this.latencyHistory&&(this.latencyHistory.length>=100&&this.latencyHistory.shift(),this.latencyHistory.push({time:e,ms:this.latency}))}get latencies(){return this.latencyHistory||(this.latencyHistory=[]),this.latencyHistory}getTickAndMultiplier(){const t=this.sessionSpec.options,e=["number","string"].includes(typeof t.tps)?t.tps:["number","string"].includes(typeof this.sessionSpec.tps)?this.sessionSpec.tps:20,[s,i]=(e+"x").split("x").map((t=>Number.parseFloat("0"+t))),n=1e3/Math.max(1/30,Math.min(60,s)),o=Math.max(1,i);let r=n,a=0;return o>1&&!Ya&&(r=n/o,a=Math.ceil(r*(o-1))),{msPerTick:r,multiplier:o,tick:n,delay:a}}simulate(t){if(!this.vm)return!0;try{let e=!0;if(this.networkQueue.length+this.vm.messages.size===0)e=this.vm.advanceTo(this.reflectorTime,t);else{const s=ot.begin("simulate");for(;e;){const s=this.networkQueue[0];if(!s)break;if(e=this.vm.advanceTo(s[0],t),!e)break;this.networkQueue.shift();const i=this.vm.scheduleExternalMessage(s);e=this.vm.advanceTo(i.time,t),this.cpuTime+=5}e&&(e=this.vm.advanceTo(this.reflectorTime,t)),this.cpuTime+=Math.max(.01,ot.end("simulate")-s)}ot.backlog(this.backlog);const s=this.lag,i=Math.max(200,.1*this.msPerTick),n=Math.max(2e3,.2*this.msPerTick);if("boolean"==typeof this.synced&&this.viewed&&(this.synced&&s>n||!this.synced&&s{delete this.syncTimer,this.connected&&this.lag5e3&&!Pa.offline&&(this.triggeringCpuTime=this.cpuTime,this.cpuTime=0,this.isBeingAnimated()?setTimeout((()=>this.scheduleSnapshot()),Math.floor(2e3*Math.random())):this.scheduleSnapshot()),e}catch(t){return yt("simulate",t),this.connection.closeConnectionWithError("simulate",t),"error"}}stepSession(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=ot.stepSession(e.frameTime,!0);s&&console.log(s);const{backlog:i,latency:n,starvation:o,activity:r}=this;if("animation"===t){ot.animationFrame(e.frameTime,{backlog:i,starvation:o,latency:n,activity:r,users:this.users});const t=Date.now();if(this.lastAnimationEnd){const e=t-this.lastAnimationEnd;if(!0===this.animationGapCheck&&e>200&&(this.animationGapCheck=[],Pa.session&&console.log(`${this.id} animation has stopped (too long between steps)`)),!0!==this.animationGapCheck){const t=this.animationGapCheck;t.push(e),t.length>4&&t.shift(),4===t.length&&t.reduce(((t,e)=>t+e),0)<=400&&(this.animationGapCheck=!0,Pa.session&&console.log(`${this.id} animation has started`))}}this.lastAnimationEnd=t}if(!this.connected)return void(this.isInBackground()||this.checkForConnection(!0));if(!this.vm)return;let a;switch(t){case"animation":{const t=e.expectedSimFPS,s=Date.now(),i=Ma.reduce(((t,e)=>t+e),0)/Ma.length;if(a=this.simulate(s+Math.min(i,200)),!1===a){const e=0===t?0:1e3/t*4;this.backlog>e&&(a=this.simulate(s+200-i))}"error"!==a&&(Ma.push(Date.now()-s),Ma.length>4&&Ma.shift());break}case"fastForward":case"background":a=this.simulate(Date.now()+e.budget);break;default:console.warn(t)}this.fastForwardHandler&&this.fastForwardHandler(a),"error"!==a&&(ot.begin("update"),this.processModelViewEvents("animation"===t),ot.end("update"),this.serviceRateLimitBuffer(),"animation"===t&&(e.view&&(ot.begin("render"),this.inViewRealm((()=>e.view.update(e.frameTime))),ot.end("render")),this.lastAnimationEnd=Date.now()))}applySyncChange(t){Pa.session&&console.log(this.id,`synced=${t}`),this.synced=t,Pt.showSyncWait(!t),this.vm.publishFromView(this.viewId,"synced",t)}inViewRealm(t){return Ft(this.vm,(()=>t(this.vm)))}processModelViewEvents(t){return this.vm?this.vm.processModelViewEvents(t):0}timeFromReflector(t,e,s){t{this.timeFromReflector(Math.round(t+i*e),"controller"),Pa.ticks&&console.log(this.id,"Controller generate TICK "+this.reflectorTime,i),++i>=s&&(globalThis.clearInterval(this.localTicker),this.localTicker=0)}),e)}startStepping(t){const e=s=>{this.leaving||(this.isOutOfSight()||t(s),window.requestAnimationFrame(e))};window.requestAnimationFrame(e)}setUpActivityChecks(){let t=null;if(this.isOutOfSight=()=>!(Ta||"hidden"!==document.visibilityState&&t),this.isBeingAnimated=()=>{const t=!0===this.animationGapCheck,e=Date.now()-this.lastAnimationEnd<200;return t&&!e&&(this.animationGapCheck=[],Pa.session&&console.log(`${this.id} animation has stopped (too long since last step)`)),t&&e},this.isInBackground=()=>this.isOutOfSight()||!this.isBeingAnimated(),!Ta){new IntersectionObserver(((e,s)=>t=e[0].isIntersecting)).observe(document.body)}const e=this.sessionSpec.autoSleep;let s;if(e){const t=1e3*e;let i=0,n=0;s=()=>{const e=Date.now();e-i<980||(i=e,this.isOutOfSight()?n?e-n>t&&(this.dormantDisconnect(),n=0):n=e:n=0)}}const i=()=>{this.leaving?n&&(clearInterval(n),n=null):this.connected&&this.vm&&(s&&s(),this.isBeingAnimated()||this.connection.keepAlive(Date.now()))};let n=setInterval(i,1e3);this.simulateIfNeeded=()=>{if(!this.isBeingAnimated()&&(i(),!this.fastForwardHandler&&this.connected)){let t=.9*this.msPerTick;e&&(t=Math.min(t,200));const s=this.synced?"background":"fastForward";this.stepSession(s,{budget:t})}}}toString(){return`Controller[${this.id}]`}[Symbol.toPrimitive](){return this.toString()}}class _a{constructor(t){this.controller=t,this.socketLastSent=0,this.connectBlocked=!1,this.connectRestricted=!1,this.connectHasBeenCalled=!1,this.reconnectDelay=0,this.missingTickThreshold=1/0}get id(){return this.controller.id}setTick(t){this.missingTickThreshold=Math.min(3*t,45e3)}get connected(){return!(!this.socket||this.socket.readyState!==WebSocket.OPEN)}checkForConnection(t){this.socket||this.connectHasBeenCalled||this.connectBlocked||this.connectRestricted&&!t||this.connectToReflector()}connectToReflector(){if(this.socket||this.connectHasBeenCalled)return;let t;if(this.connectHasBeenCalled=!0,this.connectBlocked=!1,this.connectRestricted=!1,Pa.offline)t=new va;else{let e=Ra(this.controller.sessionSpec.apiKey).reflector;const s=Ta?void 0:window.location.href,i={},n=this.controller.sessionSpec.token;if(n&&(i.token=n),r.reflector){const t=r.reflector.toUpperCase();"CF"===t||t.match(/^[A-Z]{3}$/)?(e=Pa.reflector?"wss://croquet.network/reflector/dev/":"wss://croquet.network/reflector/",3===t.length&&(i.colo=t)):r.reflector.match(/^[-a-z0-9]+$/i)?i.region=r.reflector:e=new URL(r.reflector,s).href.replace(/^http/,"ws")}if(!e.match(/^wss?:/))throw Error("Cannot interpret reflector address "+e);e.endsWith("/")||(e+="/");const o=new URL(e+this.id,s);for(const[t,e]of Object.entries(i))o.searchParams.append(t,e);t=new WebSocket(o)}t.onopen=e=>{const s=this.socket;s&&(s.onopen=s.onmessage=s.onerror=s.onclose=null),this.socket=t,this.connectHasBeenCalled=!1,Pa.session&&console.log(this.id,this.socket.constructor.name,"connected to",this.socket.url),this.reconnectDelay=0,ot.connected(!0),this.controller.sendJoin()},t.onmessage=e=>{ot.addNetworkTraffic("reflector_in",e.data.length),t===this.socket&&this.receive(e.data)},t.onerror=e=>{Pa.session&&console.log(this.id,t.constructor.name,"connection error"),this.connectHasBeenCalled=!1,this.controller.clearSyncReceiptTimeout()},t.onclose=t=>{this.socketClosed(t.code,t.reason)}}socketClosed(t,e){this.controller.clearSyncReceiptTimeout();const s=1e3!==t&&t<4100,i=4110===t;i||1e3===t||this.reconnectDelay||setTimeout((()=>{this.connected||Pt.showMessage(`Connection closed: ${t} ${e}`,{level:s?"error":"fatal"})}),500),Pa.session&&console.log(this.id,`${this.socket?this.socket.constructor.name+" closed":"closed before opening,"} with code: ${t} ${e}`),ot.connected(!1),i?this.connectRestricted=!0:this.connectBlocked=!0,this.disconnected(),s&&(Pa.session&&console.log(this.id,`reconnecting in ${this.reconnectDelay} ms`),this.reconnectTimeout=globalThis.setTimeout((()=>{delete this.reconnectTimeout,this.connectToReflector()}),this.reconnectDelay),this.reconnectDelay=Math.min(3e4,Math.round((this.reconnectDelay+100)*(1+Math.random()))))}disconnected(){this.socket&&(this.socket=null,this.lastReceived=0,this.socketLastSent=0,this.stalledSince=0,this.connectHasBeenCalled=!1,this.controller.connectionInterrupted())}send(t){this.socketLastSent=Date.now(),this.socket.send(t),ot.addNetworkTraffic("reflector_out",t.length)}receive(t){this.lastReceived=Date.now();const{id:e,action:s,args:i}=JSON.parse(t);if(e)try{this.controller.receive(s,i)}catch(t){this.closeConnectionWithError("receive",t)}else if("PONG"===s){if(Pa.pong&&console.log("PONG after",Date.now()-i,"ms"),this.pongHook)try{this.pongHook(i)}catch(t){console.error(t)}}else console.warn("Unknown action",s)}dormantDisconnect(){this.connected&&(Pa.session&&console.log(this.id,"dormant; disconnecting from reflector"),this.closeConnection(4110,"Going dormant"))}closeConnectionWithError(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:4e3;console.error(e),console.warn("closing socket"),s>=4100&&4110!==s&&(this.controller.leaving=()=>{}),this.closeConnection(s,`Error in ${t}: ${e.message||e}`)}closeConnection(t,e){this.socket&&(this.socket.onclose=null,this.socket.close(t,e),this.socketClosed(t,e))}PULSE(t){this.connected&&(0===this.socket.bufferedAmount?(this.send(JSON.stringify({action:"PULSE"})),this.stalledSince=0):this.stalledSince&&t-this.stalledSince>500?console.log(`${this.id} Reflector connection stalled: ${this.socket.bufferedAmount} bytes unsent for ${t-this.stalledSince} ms`):this.stalledSince=Date.now())}keepAlive(t){0!==this.lastReceived&&(t-this.socketLastSent>25e3?this.PULSE(t):t-this.lastReceived>5e4?this.closeConnectionWithError("connection",Error("Reflector has gone away")):t-this.lastReceived>this.missingTickThreshold&&this.PULSE(t))}PING(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Date.now();this.connected&&this.send(JSON.stringify({action:"PING",args:t}))}}globalThis.setInterval((()=>{for(const t of za)t.connected&&t.vm&&t.connection.keepAlive(Date.now())}),100);const ja=Symbol("hash"),Ea=Symbol("key"),Qa=Symbol("url"),Ja=new Map;function Ua(t){return r.has("debug",t,!1)}function Da(t){return t.replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function Oa(t){return t.replace(/-/g,"+").replace(/_/g,"/").padEnd(t.length+3&-4,"=")}function Ba(t,e){return e.replace(/[\s\S]/g,(e=>String.fromCharCode(e.charCodeAt(0)^t.charCodeAt(0))))}class Aa{static async store(t,e){let s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if("object"==typeof t&&(console.warn("Deprecated: Croquet.Data.store(sessionId, data) called without sessionId"),e=t),ml.hasCurrent())throw Error("Croquet.Data.store() called from Model code");const{appId:i,persistentId:n,uploadEncrypted:o}=Na(t),r=Z.random(32).toString(un),a=`apps/${i}/${n}/data/%HASH%`,l=await o({path:a,content:e,key:r,keep:s,debug:Ua("data"),what:"data"}),c=function(t){return t.replace(/.*\//,"")}(l);return new Aa(c,r,l)}static async fetch(t,e){if("object"==typeof t&&(console.warn("Deprecated: Croquet.Data.fetch(sessionId, handle) called without sessionId"),e=t),ml.hasCurrent())throw Error("Croquet.Data.fetch() called from Model code");const{downloadEncrypted:s}=Na(t),i=e&&e[ja],n=e&&e[Ea],o=e&&e[Qa];if("string"!=typeof i||"string"!=typeof n||"string"!=typeof o)throw Error("Croquet.Data.fetch() called with invalid handle");return s({url:o,key:n,debug:Ua("data"),what:"data"})}static hash(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"base64url";"function"==typeof t&&(t=Function.prototype.toString.call(t)),"string"==typeof t?t=(new TextEncoder).encode(t):t&&t.constructor===DataView?t=new Uint8Array(t.buffer,t.byteOffset,t.byteLength):t&&t.constructor===ArrayBuffer?t=new Uint8Array(t):ArrayBuffer.isView(t)||(t=(new TextEncoder).encode(y(t)));const s=X(Z.create(t));switch(e){case"hex":return s.toString();case"base64":return s.toString(un);case"base64url":return Da(s.toString(un));default:throw Error(`Croquet.Data: unknown hash output "${e}", expected "hex"/"base64"/"base64url"`)}}static fromId(t){const e=t.slice(0,1);let s,i,n,o;switch(e){case"0":s=t.slice(1,44),i=t.slice(44),n=`https://files.croquet.io/sessiondata/${s}`;break;case"1":s=t.slice(1,44),i=t.slice(44,87)+"=",o=t.slice(87),n=`https://files.croquet.io/apps/${o}/data/${s}`;break;case"2":s=t.slice(1,44),i=Oa(t.slice(44,87)),o=Ba(i,atob(Oa(t.slice(87)))),n=`https://files.croquet.io/apps/${o}/data/${s}`;break;case"3":i=Oa(t.slice(1,44)),n=Ba(i,atob(Oa(t.slice(44)))),s=n.slice(-43);break;default:throw Error(`Croquet.Data expected handle v0-v3 got v${e}`)}return new this(s,i,n)}static toId(t){if(!t)return"";const e=t[ja],s=t[Ea],i=t[Qa];if(i.slice(-43)!==e)throw Error("Croquet Data: malformed URL");return`3${Da(s)}${Da(btoa(Ba(s,i)))}`}constructor(t,e,s){const i=Ja.get(t);if(i)return Ua("data")&&console.log(`Croquet.Data: using cached handle for ${t}`),i;if(s.slice(-43)!==t)throw Error("Croquet Data: malformed URL");Object.defineProperty(this,ja,{value:t}),Object.defineProperty(this,Ea,{value:e}),Object.defineProperty(this,Qa,{value:s}),Ja.set(t,this),Ua("data")&&console.log(`Croquet.Data: created new handle for ${t}`)}}const $a={cls:Aa,write:t=>Aa.toId(t),read:t=>Aa.fromId(t)};let qa=null,tl=null;const el=Symbol("DEBUG_WRITES_TARGET");let sl=null;class il extends Error{}function nl(){if(!globalThis.CroquetViewMath){globalThis.CroquetMath.random=()=>qa.random(),globalThis.CroquetViewMath={};for(const[t,e]of Object.entries(Object.getOwnPropertyDescriptors(Math)))globalThis.CroquetViewMath[t]=e.value;for(const[s,i]of Object.entries(globalThis.CroquetMath)){const n=Math[s];Math[s]=1===i.length?t=>qa?i(t):n(t):(t,e)=>qa?i(t,e):n(t,e)}}if(!globalThis.CroquetViewDate){const o=globalThis.Date;let r=!1;function a(t,e){return r||(r=!0,console.warn(new il(`${t} used in Model code`))),e}function l(t,e,s,i,n,r,c){const d=this instanceof l,h=[t,e,s,i,n,r,c];if(h.length=arguments.length,qa)switch(a(d?"new Date()":"Date()"),arguments.length){case 0:h.push(qa.time);break;case 1:break;default:h[0]=o.UTC(...h),h.length=1}const u=new o(...h);return d?u:""+u}l.prototype=o.prototype,l.UTC=o.UTC,l.now=()=>qa?a("Date.now()",qa.time):o.now(),l.parse=function(){return qa?a("Date.parse()",0):o.parse(...arguments)},globalThis.CroquetViewDate=o,globalThis.Date=l}}Object.defineProperty(il.prototype,"name",{value:"CroquetWarning"});const ol={};function rl(t,e){const{qPara:s,qArgs:i,qFn:n}=JSON.parse(atob(t.slice(1,-1))),o=JSON.stringify(s),r=ol[o]||(ol[o]=new Function(...s));return"number"==typeof n&&(i[n]=r),r.call(e,...i).bind(e)}function al(t,e){if(qa)throw Error("VirtualMachine confusion");if(!(t instanceof ml))throw Error("not a VM: "+t);const s=qa;try{qa=t,globalThis.CROQUETVM=t,e()}finally{qa=s}}const ll=["handleModelEventInModel","handleBundledEvents","publishFromModelOnly","handlePollForSnapshot","handleTuttiResult","handleTuttiDivergence","handleSnapshotVote","handlePersistVote","handleModelEventInView","noop"],cl={};for(let t=0;t{Nt(this,(()=>{if(this.modelsById={},this.modelsByName={},this.messages=new dn(((t,e)=>t.before(e))),this.subscriptions={},this.subscribers=new Map,this.views={},this._random=()=>{throw Error("You must not use random when applying state!")},this.id=t.id,this.time=0,this.seq=4294967280,this.externalTime=0,this.externalSeq=this.seq,this.futureSeq=0,this.lastSnapshotPoll=0,this.lastPersistencePoll=0,this.inPersistenceCoolOff=!1,this.persisted="",this.modelsId=0,this.diverged=null,this.controller=null,t.modelsById){const e=vl.newOrRecycled(this).readVM(t,"vm");let s=[];for(const t of Object.keys(e))t in this||"meta"===t?"_random"===t?this[t]=new p(null,{state:e[t]}):"messages"===t?s=e.messages:this[t]=e[t]:console.warn(`Ignoring property snapshot.${t}`);for(const t of s)this.messages.add(t);for(const[t,e]of Object.entries(this.subscriptions))for(const s of e){const[e]=s.split(".");let i=this.subscribers.get(e);i||this.subscribers.set(e,i=new Set),i.add(t)}}else this._random=new p(t.id,{state:!0}),this.addSubscription(this,"__VM__","__peers__",this.generateJoinExit),this.addSubscription(this,"__VM__","__diverged__",this.handleSessionDiverged),e(this)}))}))}registerModel(t,e){if(qa!==this)throw Error("You can only create models from model code!");return e||(e="M"+ ++this.modelsId),this.modelsById[e]=t,e}deregisterModel(t){if(qa!==this)throw Error("You can only destroy models from model code!");const e=this.modelsById;delete this.modelsById[t];for(const[t,s]of Object.entries(this.modelsByName))e===s&&delete this.modelsByName[t];this.messages.removeMany((e=>e.hasReceiver(t)))}lookUpModel(t){if("_"===t)return this;let e=this.modelsById[t];if(e)return e;const[s,i,n]=t.match(/^([^#]+)#(.*)$/)||[];return e=this.modelsById[i],e&&e.lookUp(n)}get(t){const e=this.modelsByName[t];return qa!==this&&tl.write?this.debugWriteProxy(this,e):e}set(t,e){if(qa!==this)throw Error("You can only make a model well-known from model code!");this.modelsByName[t]=e}debugWriteProxy(t,e){if("object"!=typeof e||null===e)return e;if(!this.$debugWriteProxyHandler){function i(){throw Error("Attempt to modify Croquet model state from outside!")}sl||(sl=new WeakMap),this.$debugWriteProxyHandler={set(e,s,n){qa!==t&&i(),e[s]=n},deleteProperty(e,s){qa!==t&&i(),delete e[s]},get(e,s){if(s===el)return e;const n=e[s];if(n&&n[el])return n;if(qa!==t&&"object"==typeof n&&null!==n){if(n instanceof Map){const e=new Map([...n.entries()].map((e=>{let[s,i]=e;return[t.debugWriteProxy(t,s),t.debugWriteProxy(t,i)]})));return e[el]=n,e.set=i,e.delete=i,e}if(n instanceof Set){const e=new Set([...n.entries()].map((e=>t.debugWriteProxy(t,e))));return e[el]=n,e.set=i,e.delete=i,e}return t.debugWriteProxy(t,n)}return n}}}let s=sl.get(e);return s||(s=new Proxy(e,this.$debugWriteProxyHandler),sl.set(e,s)),s}noop(){}generateJoinExit(t){let{entered:e,exited:s,count:i}=t;const n={};for(const t of e){if(!Array.isArray(t))continue;const e=t[1]||{};e.region&&(e.country=e.region.slice(0,2),e.region=e.region.slice(2)),n[t[0]]={loc:e}}if(e=e.map((t=>Array.isArray(t)?t[0]:t)),s=s.map((t=>Array.isArray(t)?t[0]:t)),e.length===i){s=Object.keys(this.views);for(const t of s)this.views[t].extraConnections=0}if(0!==e.length&&0!==s.length){const t=e.filter((t=>s.includes(t)));if(0!==t.length&&(e=e.filter((e=>!t.includes(e))),s=s.filter((e=>!t.includes(e))),0===e.length&&0===s.length))return}for(const t of s)if(this.views[t]){if(this.views[t].extraConnections){this.views[t].extraConnections--,tl.session&&console.log(`${this.id} @${this.time}#${this.seq} view ${t} closed extra connection`);continue}delete this.views[t],this.publishFromModelOnly(this.id,"view-exit",t)}else{const{time:e,seq:s}=this;console.error(`${this.id} @${e}#${s} view ${t} exited without being present - this should not happen`),Promise.resolve().then((()=>{this.controller.sendLog(`view-exit-mismatch @${e}#${s} ${t} left without being present`)}))}for(const t of e)this.views[t]?(tl.session&&console.log(`${this.id} @${this.time}#${this.seq} view ${t} opened another connection`),this.views[t].extraConnections=(this.views[t].extraConnections||0)+1):(this.views[t]=n[t]||{},this.publishFromModelOnly(this.id,"view-join",t));const o=Object.values(this.views).reduce(((t,e)=>t+1+(e.extraConnections||0)),0);if(i!==o){const{time:t,seq:e}=this;console.error(`@${t}#${e} view count mismatch (model: ${o}, reflector: ${i}) - this should not happen`),Promise.resolve().then((()=>{this.controller.sendLog(`view-exit-mismatch @${t}#${e} connections model: ${o} reflector: ${i}`)}))}}scheduleExternalMessage(t){const e=bl.fromState(t,this);if(e.time>>0;if(e.seq!==s)throw Error(`External message error. Expected message #${s} got #${e.seq}`);return this.externalTime=e.time,this.externalSeq=e.seq,e.seq=2*e.seq+1,this.verifyExternal(e),this.messages.add(e),e}verifyExternal(t){if("_"!==t.receiver)throw Error(`invalid receiver in external message: ${t}`);if(!(t.selector in cl))throw Error(`unexpected external message: ${t.selector}`)}futureSend(t,e,s,i){if(t.every)return this.futureRepeat(t.every,e,s,i);if(t<0)throw Error("attempt to send future message into the past");this.futureSeq=this.futureSeq+1>>>0;const n=new bl(this.time+t,2*this.futureSeq,e,s,i);return this.messages.add(n),{time:n.time,seq:n.seq}}cancelFuture(t,e){const s=this.messages;let i;if("number"==typeof e.time){const{time:t,seq:n}=e;i=s.removeOne((e=>e.time===t&&e.seq===n))}else{if("*"===e)return i=s.removeMany((e=>e.receiver===t.id)),i.length>0;{const n=this.asQFunc(t,e,"cancelFuture message"),o=t.id;i=s.removeOne((t=>t.receiver===o&&t.selector===n||"_"===t.receiver&&"futureExecAndRepeat"===t.selector&&t.args[1]===o&&t.args[2]===n))}}return void 0!==i}futureRepeat(t,e,s,i){this.futureSend(t,"_","futureExecAndRepeat",[t,e,s,i])}futureExecAndRepeat(t,e,s,i){const n=this.lookUpModel(e);if(n){if("function"==typeof n[s])try{n[s](...i)}catch(t){yt(`future message ${n}.${s}`,t)}else{const t=rl(s,n);try{t(...i)}catch(e){yt(`future message ${n} ${t}`,e)}}this.futureRepeat(t,e,s,i)}}future(t,e,s,i){if(!this.lookUpModel(t.id))throw Error(`future send to unregistered model ${t}`);if(void 0===s){const s=this;return new Proxy(t,{get:(i,n)=>function(){for(var i=arguments.length,o=new Array(i),r=0;r>>0,i/2>>>0!==this.seq))throw Error(`Sequence error: expected ${this.seq} got ${i/2>>>0} in ${s}`);if(this.messages.poll(),this.time=s.time,s.executeOn(this),globalThis.CroquetViewDate.now()>=e)return!1}return this.time=t,!0}asQFunc(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"subscription handler";if("string"==typeof e)return e;if("function"==typeof e){if(t[e.name]===e)return e.name;let i=t;for(;null!==i;){for(const[t,s]of Object.entries(Object.getOwnPropertyDescriptors(i)))if(s.value===e)return t;i=Object.getPrototypeOf(i)}ft(`${s} is not a method of ${t}: ${e}\n`,{only:"once"});const n=/^\(?([a-z][a-z0-9]*)?\)? *=> *this\.([a-z][a-z0-9]*) *\( *([a-z][a-z0-9]*)? *\) *$/i,o=e.toString().match(n);return!o||o[3]&&o[3]!==o[1]?function(t,e){"function"==typeof t&&(e=t,t={});const s=Object.keys(t).concat(["return "+e]),i=Object.values(t),n={qPara:s,qArgs:i},o=i.indexOf(e);return o>=0&&(i[o]=s[o],n.qFn=o),`{${btoa(JSON.stringify(n))}}`}(e):o[2]}return null}addSubscription(t,e,s,i){if(qa!==this)throw Error("Cannot add a model subscription from outside model code");const n=this.asQFunc(t,i);if("string"!=typeof n)throw Error(`Subscription handler for "${s}" must be a method name`);if(n.indexOf(".")<0&&"function"!=typeof t[n]&&"{"!==n[0])throw Error(`Subscriber method for "${s}" not found: ${t}.${n}()`);const o=e+":"+s,r=t===this?"_":t.id,a=r+"."+n;if(this.subscriptions[o]){if(-1!==this.subscriptions[o].indexOf(a))throw Error(`${t}.${n} already subscribed to ${s}`)}else this.subscriptions[o]=[];this.subscriptions[o].push(a);let l=this.subscribers.get(r);l||this.subscribers.set(r,l=new Set),l.add(o)}removeSubscription(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"*";if(qa!==this)throw Error("Cannot remove a model subscription from outside model code");const n=e+":"+s,o=this.subscriptions[n];if(o){const e=t.id+".";if("*"===i){for(let t=o.length-1;t>=0;t--)o[t].startsWith(e)&&o.splice(t,1);0===o.length&&delete this.subscriptions[n]}else{const r=this.asQFunc(t,i);if("string"!=typeof r)throw Error(`Invalid unsubscribe args for "${s}" in ${t}: ${i}`);const a=e+r,l=o.indexOf(a);if(-1!==l&&(o.splice(l,1),0===o.length&&delete this.subscriptions[n]),o.find((t=>t.startsWith(e))))return}const r=this.subscribers.get(t.id);r.delete(n),0===r.size&&this.subscribers.delete(t.id)}}removeAllSubscriptionsFor(t){const e=this.subscribers.get(t.id);if(e){const s=t.id+".";for(const t of e){const e=this.subscriptions[t];for(let t=e.length-1;t>=0;t--)e[t].startsWith(s)&&e.splice(t,1);0===e.length&&delete this.subscriptions[t]}this.subscribers.delete(t.id)}}publishFromModel(t,e,s){if(qa!==this)throw Error("Cannot publish a model event from outside model code");const i=e.endsWith("#reflected");i&&(e=e.slice(0,e.length-"#reflected".length));const n=t+":"+e;this.handleModelEventInModel(n,s,i),this.handleModelEventInView(n,s)}publishFromModelOnly(t,e,s){if(qa!==this)throw Error("Cannot publish a model event from outside model code");const i=t+":"+e;this.handleModelEventInModel(i,s)}publishFromView(t,e,s){if(qa)throw Error("Cannot publish a view event from model code");const i=t+":"+e;this.handleViewEventInModel(i,s),this.handleViewEventInView(i,s)}handleBundledEvents(t){for(const e of t){const t=bl.fromState(e,this);this.verifyExternal(t),t.executeOn(this,!0)}}handleModelEventInModel(t,e){let s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(qa!==this)throw Error("handleModelEventInModel called from outside model code");if(s){if(!0!==this.controller.synced)return;const s=t+"#__vote",i=t+"#divergence",n=!!Yt.subscriptions[s],o=!!this.subscriptions[t],r=!!this.subscriptions[i];n&&r&&console.log(`divergence subscription for ${t} overridden by vote subscription`);const a=o?new bl(this.time,0,"_","handleModelEventInModel",[t,e]):null;let l;l=n?["handleModelEventInView",s]:["handleTuttiDivergence",i],Promise.resolve().then((()=>this.controller.sendTutti({time:this.time,topic:t,data:e,firstMessage:a,wantsVote:n,tallyTarget:l})))}else if(this.subscriptions[t]){const s=this.subscriptions[t],i=s.slice();for(let n=0;n=0){const s=l.indexOf("."),i=l.slice(0,s),n=l.slice(s+1);try{c.call(i,n,e)}catch(e){yt(`event ${t} ${c}.call(${JSON.stringify(i)}, ${JSON.stringify(n)})`,e)}}else if("function"==typeof c[l])try{c[l](e)}catch(e){yt(`event ${t} ${c}.${l}()`,e)}else yt(`event ${t} ${c}.${l}(): method not found`);else{const s=rl(l,c);try{s(e)}catch(e){yt(`event ${t} ${c} ${s}`,e)}}else ft(`event ${t} .${l}(): subscriber not found`)}}}handleViewEventInModel(t,e){if(this.subscriptions[t]){const s=[t];void 0!==e&&s.push(e);const i=new bl(this.time,0,"_","handleModelEventInModel",s);this.controller.sendMessage(i)}}handleModelEventInView(t,e){tl.write&&(e=this.debugWriteProxy(this,e)),Yt.handleEvent(t,e,(t=>function(t){if(!qa)throw Error("VirtualMachine confusion");const e=qa;try{qa=null,t()}finally{qa=e}}((()=>Ft(this,t,!0)))))}handleViewEventInView(t,e){Yt.handleEvent(t,e)}handleTuttiDivergence(t,e){if(this.subscriptions[t])this.handleModelEventInModel(t,e);else{const s=t.split(":").slice(-1)[0];console.warn(`uncaptured divergence in ${s}:`,e)}}handleSessionDiverged(t){const{key:e,url:s}=t;this.diverged||(this.diverged=new Map);let i=this.diverged.get(e);i||this.diverged.set(e,i=[]),i.push(s),2===i.length&&this.controller&&!this.controller.fastForwardHandler&&this.debugDiverged(e)}debugDiverged(t){t||(t=this.diverged.keys().next().value);const e=this.diverged.get(t);if(!e||e.length<2)throw Error(`no diverged urls for snapshot ${t}`);Promise.resolve().then((()=>this.controller.diffDivergedSnapshots(e)))}processModelViewEvents(t){if(qa)throw Error("cannot process view events in model code");return Ft(this,(()=>Yt.processFrameEvents(t,!!this.controller.synced)))}handlePollForSnapshot(){const t=this.time,e=t-this.lastSnapshotPoll;e<5e3?console.log(`rejecting snapshot poll ${e}ms after previous`):(this.lastSnapshotPoll=t,this.controller.handlePollForSnapshot(t))}handleTuttiResult(t){this.controller.handleTuttiResult(t)}handleSnapshotVote(t){this.controller.handleSnapshotVote(t)}handlePersistVote(t){this.controller.handlePersistVote(t)}snapshot(){return wl.newOrRecycled(this).snapshot(this,"_")}getSummaryHash(){return y((new gl).getHash(this))}persist(t,e){this.controller&&"no.appId"===this.controller.sessionSpec.appId&&console.warn("Croquet: appId should be provided in Session.join() to not overwrite another apps's persistent data");const s=ot.begin("snapshot"),i="function"==typeof e?e.call(t):e;if("object"!=typeof i)throw Error(`Croquet: persistSession() can only persist objects (got ${typeof i})`);const n=y(i),o=Aa.hash(n),r=ot.end("snapshot")-s,a=this.persisted===o,l=this.time;var c,d;if(tl.snapshot&&console.log(`${this.id} persistent data @${l} collected, stringified and hashed in ${Math.ceil(r)}ms${a?" (unchanged, ignoring)":""}`),!a)if(c=this,d={persistTime:l,persistentString:n,persistentHash:o,ms:r},dl.set(c,d),this.persisted=o,this.inPersistenceCoolOff)tl.snapshot&&console.log(`${this.id} persistence poll postponed by cooloff`);else{const t=this.lastPersistencePoll?this.lastPersistencePoll+25e3-this.time:0;t>0?(tl.snapshot&&console.log(`${this.id} postponing persistence poll by ${t}ms`),this.futureSend(t,"_","triggerPersistencePoll",[]),this.inPersistenceCoolOff=!0):this.triggerPersistencePoll()}}triggerPersistencePoll(){this.inPersistenceCoolOff=!1,this.lastPersistencePoll=this.controller?this.time:0;const t=(e=this,dl.get(e));var e;if(!t)return;const{persistTime:s,persistentString:i,persistentHash:n,ms:o}=t;if(hl(this),this.controller&&this.controller.synced){tl.snapshot&&console.log(`${this.id} asking controller to poll for persistence @${s}`);const t=this.time;Promise.resolve().then((()=>this.controller.pollForPersist(t,s,i,n,o)))}}random(){if(qa!==this)throw Error("synchronized random accessed from outside the model");return this._random()}randomID(){if(qa!==this)throw Error("synchronized random accessed from outside the model");let t="";for(let e=0;e<4;e++)t+=(this._random.int32()>>>0).toString(16).padStart(8,"0");return t}toString(){return`VirtualMachine[${this.id}]`}[Symbol.toPrimitive](){return this.toString()}}function pl(t,e,s){let i;if("_"===t){const t=cl[e];"number"==typeof t&&(i=t.toString(36))}if(void 0===i&&(i=`${t}>${e}`),s.length>0){const t=Xl.newOrRecycled();i+=JSON.stringify(t.encode(s))}return i}function fl(t,e){return(e-t|0)>=0}class bl{constructor(t,e,s,i,n){this.time=t,this.seq=e,this.receiver=s,this.selector=i,this.args=n}before(t){return this.time!==t.time?this.time>>0}set externalSeq(t){this.seq=2*t+1}get internalSeq(){return this.seq/2>>>0}set internalSeq(t){this.seq=2*t}asState(){return[this.time,this.seq,pl(this.receiver,this.selector,this.args)]}static fromState(t,e){const[s,i,n]=t,{receiver:o,selector:r,args:a}=function(t,e){let s,i,n;if(1===t.length||"["===t[1]){const e=parseInt(t[0],36);s="_",i=ll[e],n=t.slice(1)}else{const e=t.indexOf(">");let o=t.indexOf("[");-1===o&&(o=t.length),s=t.slice(0,e),i=t.slice(e+1,o),n=t.slice(o)}let o=[];n&&(o=Ll.newOrRecycled(e).decode(JSON.parse(n)));return{receiver:s,selector:i,args:o}}(n,e);return new bl(s,i,o,r,a)}executeOn(t){const e=arguments.length>1&&void 0!==arguments[1]&&arguments[1]?t=>t():e=>al(t,(()=>Nt(t,e))),{receiver:s,selector:i,args:n}=this,o=t.lookUpModel(s);if(o)if("{"===i[0]){const t=rl(i,o);e((()=>{try{t(...n)}catch(e){yt(`${this.shortString()} ${t}`,e)}}))}else i.indexOf(".")>=0?e((()=>{const t=i.indexOf("."),e=i.slice(0,t),s=i.slice(t+1);try{o.call(e,s,...n)}catch(t){yt(`${this.shortString()} ${o}.call(${JSON.stringify(e)}, ${JSON.stringify(s)})`,t)}})):"function"!=typeof o[i]?ft(`${this.shortString()} ${o}.${i}(): method not found`):e((()=>{try{o[i](...n)}catch(t){yt(`${this.shortString()} ${o}.${i}()`,t)}}));else ft(`${this.shortString()} ${i}(): receiver not found`)}shortString(){return(this.isExternal()?"External":"Future")+"Message"}toString(){const{receiver:t,selector:e,args:s}=this,i=this.isExternal(),n=i?this.externalSeq:this.internalSeq;return`${i?"External":"Future"}Message[${this.time}${":#"[+i]}${n} ${t}.${e}(${s.map(JSON.stringify).join(", ")})]`}[Symbol.toPrimitive](){return this.toString()}}const yl=(()=>{const t=new ArrayBuffer(8),e=new DataView(t);return t=>(e.setFloat64(0,t,!0),e.getInt32(0,!0)+e.getInt32(4,!0))})();class gl{constructor(){this.done=new Set,this.todo=[],this.hashers=new Map,this.addHasher("Teatime:Message",bl),this.addHasher("Teatime:Data",$a);for(const[t,e]of Tl.allClassTypes())this.addHasher(t,e)}addHasher(t,e){const{cls:s,write:i}=Object.getPrototypeOf(e)===Object.prototype?e:{cls:e,write:t=>({...t})};this.hashers.set(s,(t=>this.hashStructure(t,i(t))))}getHash(t){this.hashState={oC:0,mC:0,nanC:0,infC:0,zC:0,nC:0,nH:0,sC:0,sL:0,fC:0};for(const[e,s]of Object.entries(t))if("controller"!==e&&"meta"!==e)if("_random"===e)this.hash(s.state(),!1);else if("messages"===e){const t=s.asArray();(this.hashState.fC=t.length)&&this.hash(t,!1)}else this.hashEntry(e,s);return this.hashDeferred(),this.hashState}hashDeferred(){let t=0;for(;t1&&void 0!==arguments[1])||arguments[1];switch(typeof t){case"number":return void(Number.isNaN(t)?this.hashState.nanC++:Number.isFinite(t)?0===t?this.hashState.zC++:(this.hashState.nC++,this.hashState.nH+=yl(t)):this.hashState.infC++);case"string":return this.hashState.sC++,void(this.hashState.sL+=t.length);case"boolean":case"undefined":return;case"bigint":if(0n===t)this.hashState.zC++;else{this.hashState.nC++;const e=t<0?-1n:0n;for(;t!==e;)this.hashState.nH+=Number(0xFFFFFFFFn&t),t>>=32n}return;default:{if(this.done.has(t))return;if(null===t)return;if(this.hashers.has(t.constructor))return void this.hashers.get(t.constructor)(t);const s=Object.prototype.toString.call(t).slice(8,-1);if(this.hashers.has(s))return void this.hashers.get(s)(t);switch(s){case"Array":return void this.hashArray(t,e);case"ArrayBuffer":return void this.hashIntArray(new Uint8Array(t));case"Set":return void this.hashStructure(t,[...t]);case"Map":return void this.hashStructure(t,[...t],!1);case"DataView":return void this.hashIntArray(new Uint8Array(t.buffer,t.byteOffset,t.byteLength));case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":return void this.hashIntArray(t);case"Float32Array":case"Float64Array":return void this.hashArray(t,!1);case"Object":t instanceof Tl?this.hashModel(t):t.constructor===Object&&this.hashObject(t,e)}}}}hashModel(t){this.hashState.mC++,this.done.add(t);for(const[e,s]of Object.entries(t))"__realm"!==e&&void 0!==s&&this.hashEntry(e,s)}hashObject(t){let e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];this.hashState.oC++,this.done.add(t);for(const[s,i]of Object.entries(t))void 0!==i&&this.hashEntry(s,i,e)}hashArray(t){let e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];this.done.add(t);for(let s=0;s2&&void 0!==arguments[2])||arguments[2];void 0!==e&&(this.done.add(t),this.hash(e,s))}hashEntry(t,e){let s=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];"$"!==t[0]&&(s&&"object"==typeof e?this.todo.push({key:t,value:e}):this.hash(e,s))}}class wl{static newOrRecycled(t){let e=this.reusableInstance;return e?(e.vm=t,e.nextRef=1,e.refs=new Map,e.todo=[]):e=this.reusableInstance=new this(t),e}static get reusableInstance(){return this[this.name+"-instance"]}static set reusableInstance(t){this[this.name+"-instance"]=t}static resetInstance(){this.reusableInstance=null}constructor(t){this.vm=t,this.nextRef=1,this.refs=new Map,this.todo=[],this.writers=new Map,this.addWriter("Teatime:Message",bl),this.addWriter("Teatime:Data",$a);for(const[t,e]of Tl.allClassTypes())this.addWriter(t,e);this.okayToIgnore={$debugWriteProxyHandler:!0};for(const t of Tl.allClasses())if(Object.prototype.hasOwnProperty.call(t,"okayToIgnore")){const e=t.okayToIgnore();if(!Array.isArray(e))throw new Error("okayToIgnore() must return an array");for(const t of e){if("$"!==t[0])throw Error(`okayToIgnore: ignored prop "${t}" must start with '$'`);this.okayToIgnore[t]=!0}}}addWriter(t,e){const{cls:s,write:i}=Object.getPrototypeOf(e)===Object.prototype?e:{cls:e,write:t=>({...t})};this.writers.set(s,((e,s)=>this.writeAs(t,e,i(e),s)))}snapshot(t){const e={_random:t._random.state(),messages:this.write(t.messages.asArray(),"vm.messages"),subscribers:void 0,controller:void 0};for(const[s,i]of Object.entries(t))s in e||this.writeInto(e,s,i,`vm.${s}`);return this.writeDeferred(),e}writeDeferred(){let t=0;for(;t2&&void 0!==arguments[2])||arguments[2];switch(typeof t){case"number":return Object.is(t,-0)?{$class:"NegZero"}:Number.isFinite(t)?t:Number.isNaN(t)?{$class:"NaN"}:{$class:"Infinity",$value:Math.sign(t)};case"string":case"boolean":return t;case"undefined":return{$class:"Undefined"};case"bigint":return{$class:"BigInt",$value:t.toString()};default:{if(this.refs.has(t))return this.writeRef(t);if(null===t)return t;if(this.writers.has(t.constructor))return this.writers.get(t.constructor)(t,e);const i=Object.prototype.toString.call(t).slice(8,-1);if(this.writers.has(i))return this.writers.get(i)(t,e);switch(i){case"Array":return this.writeArray(t,e,s);case"ArrayBuffer":return this.writeArrayBuffer(t);case"Set":return this.writeAs(i,t,[...t],e);case"Map":return this.writeAs(i,t,[...t].flat(),e);case"DataView":case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":return this.writeTypedArray(i,t);case"Object":if(t instanceof Tl)return this.writeModel(t,e);if(t.constructor===Object||"function"!=typeof t.constructor)return this.writeObject(t,e,s);throw console.error(`Croquet: unknown class at ${e}:`,t),Error(`Croquet: class not registered in Model.types(): ${t.constructor.name}`);default:throw console.error(`Croquet: unsupported property at ${e}:`,t),Error(`Croquet: serialization of ${i}s is not supported`)}}}}writeModel(t,e){const s={};this.refs.set(t,s);try{s.$model=Tl.classToID(t.constructor)}catch(s){throw console.error(`unregistered model class at ${e}:`,t),s}for(const i of Object.keys(t).sort()){if("__realm"===i)continue;const n=t[i];("number"==typeof n&&Number.isFinite(n)&&!Object.is(n,-0)||"string"==typeof n||"boolean"==typeof n)&&"$"!==i[0]?s[i]=n:this.writeInto(s,i,n,e)}return s}writeObject(t,e){let s=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];const i={};this.refs.set(t,i);for(const n of Object.keys(t).sort()){const o=t[n];("number"==typeof o&&Number.isFinite(o)&&!Object.is(o,-0)||"string"==typeof o||"boolean"==typeof o)&&"$"!==n[0]?i[n]=o:this.writeInto(i,n,o,e,s)}return i}writeArray(t,e){let s=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];const i=[];this.refs.set(t,i);for(let n=0;n4&&void 0!==arguments[4])||arguments[4];if("$"===e[0])return void(this.okayToIgnore[e]||(ft(`snapshot: ignoring property ${e} (declare as okayToIgnore to suppress warning)`,{only:"once"}),this.okayToIgnore[e]=!0));if(n&&"object"==typeof s)return void this.todo.push({state:t,key:e,value:s,path:i});const o=i+("string"==typeof e&&e.match(/^[_a-z][_a-z0-9]*$/i)?`.${e}`:`[${JSON.stringify(e)}]`),r=this.write(s,o);t[e]=r}}const Zl=Symbol("croquet:unresolved");class vl{static newOrRecycled(t){let e=this.reusableInstance;return e?(e.vm=t,e.refs=new Map,e.todo=[],e.unresolved=[],e.postprocess=[]):e=this.reusableInstance=new this(t),e}static get reusableInstance(){return this[this.name+"-instance"]}static set reusableInstance(t){this[this.name+"-instance"]=t}static resetInstance(){this.reusableInstance=null}constructor(t){this.vm=t,this.refs=new Map,this.todo=[],this.unresolved=[],this.postprocess=[],this.readers=new Map,this.addReader("Teatime:Message",bl),this.addReader("Teatime:Data",$a),this.readers.set("Undefined",(()=>{})),this.readers.set("NaN",(()=>NaN)),this.readers.set("Infinity",(t=>t*(1/0))),this.readers.set("NegZero",(()=>-0)),this.readers.set("BigInt",(t=>BigInt(t))),this.readers.set("ArrayBuffer",(t=>function(t){const e=globalThis.atob(t),s=e.length,i=new Uint8Array(s);for(let t=0;tnew DataView(...t))),this.readers.set("Int8Array",(t=>new Int8Array(...t))),this.readers.set("Uint8Array",(t=>new Uint8Array(...t))),this.readers.set("Uint8ClampedArray",(t=>new Uint8ClampedArray(...t))),this.readers.set("Int16Array",(t=>new Int16Array(...t))),this.readers.set("Uint16Array",(t=>new Uint16Array(...t))),this.readers.set("Int32Array",(t=>new Int32Array(...t))),this.readers.set("Uint32Array",(t=>new Uint32Array(...t))),this.readers.set("Float32Array",(t=>new Float32Array(...t))),this.readers.set("Float64Array",(t=>new Float64Array(...t)));for(const[t,e]of Tl.allClassTypes())this.addReader(t,e)}addReader(t,e){const s="object"==typeof e?e.read:t=>Object.assign(Object.create(e.prototype),t);this.readers.set(t,s)}readVM(t,e){if("vm"!==e)throw Error("VirtualMachine must be root object");const s=this.read(t,e,!1);return this.readDeferred(),this.resolveRefs(),this.doPostprocess(),s}readDeferred(){let t=0;for(;t2&&void 0!==arguments[2])||arguments[2];switch(typeof t){case"number":case"string":case"boolean":return t;default:{const i=Object.prototype.toString.call(t).slice(8,-1);switch(i){case"Array":return this.readArray(t,e,s);case"Null":return null;case"Object":{const{$class:i,$model:n,$ref:o}=t;if(o)throw Error("refs should have been handled in readInto()");return n?this.readModel(t,e):i?this.readAs(i,t,e):this.readObject(Object,t,e,s)}default:throw Error(`Don't know how to deserialize ${i} at ${e}`)}}}}readModel(t,e){const s=Tl.instantiateClassID(t.$model,t.id);t.$id&&this.refs.set(t.$id,s);for(const[i,n]of Object.entries(t))"id"!==i&&"$"!==i[0]&&this.readInto(s,i,n,e);return s}readObject(t,e,s){let i=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];const n=new t;e.$id&&this.refs.set(e.$id,n);for(const[t,o]of Object.entries(e))"$"!==t[0]&&this.readInto(n,t,o,s,i);return n}readArray(t,e){let s=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];const i=[];t.$id&&this.refs.set(t.$id,i);for(let n=0;n2&&void 0!==arguments[2])||arguments[2];const i=t.$value;return t.$id&&(i.$id=t.$id),this.readArray(i,e,s)}readAsSet(t,e){const s=new Set;t.$id&&this.refs.set(t.$id,s);const i=this.unresolved.length,n=this.read(t.$value,e,!1),o=()=>{for(const t of n)s.add(t)};return this.unresolved.length===i?o():this.postprocess.push(o),s}readAsMap(t,e){const s=new Map;t.$id&&this.refs.set(t.$id,s);const i=this.unresolved.length,n=this.read(t.$value,e,!1),o=()=>{for(let t=0;t4&&void 0!==arguments[4])||arguments[4];if(this.readRef(t,e,s,i))return;if(n&&"object"==typeof s)return void this.todo.push({object:t,key:e,value:s,path:i});const o=i+("string"==typeof e&&e.match(/^[_a-z][_a-z0-9]*$/i)?`.${e}`:`[${JSON.stringify(e)}]`);t[e]=this.read(s,o)}}class Xl extends wl{encode(t){const e=this.writeArray(t,"args");return this.writeDeferred(),e}writeModel(t){return{$ref:t.id}}}class Ll extends vl{decode(t){const e=this.readArray(t,"args");return this.readDeferred(),this.resolveRefs(),this.doPostprocess(),e}resolveRefs(){for(const{object:t,key:e,ref:s,path:i}of this.unresolved)if(this.refs.has(s))t[e]=this.refs.get(s);else{const n=this.vm.lookUpModel(s);if(!n)throw Error(`Unresolved ref: ${s} at ${i}[${JSON.stringify(e)}]`);t[e]=n}}}function xl(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:new Set;const n=Object.values(t).filter((t=>{const e=Object.prototype.toString.call(t).slice(8,-1);return("Object"===e||"Array"===e)&&!i.has(t)}));for(const t of n){i.add(t);const n=e+"."+t.constructor.name;if(s[n]){if(s[n]!==t.constructor)throw new Error("Class with name "+n+" already gathered, but new one has different identity")}else s[n]=t.constructor}for(const t of n)xl(t,e,s,i)}function Sl(t){const e=new Uint8Array(t),s=[];for(let t=0;tT[t].what=`Class ${e}`))}(this,t),function(t,e){const s=Cl[e];if(s&&s!==t)throw Error(`Registering model class ${t.name} failed, id "${e}" already used by ${s.name}`);Rl(t)?Gl.classes&&!s&&console.warn(`ignoring re-exported model class ${e}`):(Gl.classes&&console.log(`registering model class ${e}`),t[Vl]=e);Cl[e]=t}(this,t),Tl.lastRegistered=this,this}static wellKnownModel(t){if(!ml.hasCurrent())throw Error("static Model.wellKnownModel() called from outside model");return ml.current().get(t)}static evaluate(t){return ml.evaluate(t)}static types(){return{}}static okayToIgnore(){return[]}static classToID(t){return function(t){if(Rl(t))return t[Vl];const e=t.name||"ClassName";throw Error(`Model class not registered, did you call ${e}.register("${e}")?`)}(t)}static classFromID(t){return Yl(t)}static allClasses(){return Pl()}static allClassTypes(){return function(){const t={};for(const e of Pl())Object.assign(t,e.types());return Object.entries(t)}()}static instantiateClassID(t,e){return Yl(t).createNoInit(e)}constructor(t){if(t!==kl)throw Error('You must create Croquet Models using create() not "new"!')}init(t,e){Wl.delete(this)}destroy(){zt().unsubscribeAll(this),zt().deregister(this)}publish(t,e,s){this.__realm||this.__realmError(),this.__realm.publish(e,s,t)}subscribe(t,e,s){return this.__realm||this.__realmError(),this.__realm.subscribe(this,t,e,s)}unsubscribe(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"*";this.__realm||this.__realmError(),this.__realm.unsubscribe(this,t,e,s)}unsubscribeAll(){this.__realm||this.__realmError(),this.__realm.unsubscribeAll(this)}__realmError(){if(!this.id)throw Error(`${this} has no ID, did you call super.init(options)?`)}future(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1?arguments[1]:void 0;this.__realm||this.__realmError();for(var s=arguments.length,i=new Array(s>2?s-2:0),n=2;n1&&void 0!==arguments[1]?arguments[1]:{};return t&&Pt.showMessage(t,{...e,level:"error"})}(t,e)}constructor(t){"object"==typeof t&&"__realm"in t||console.warn("Croquet: argument to View constructor needs to be a Model");let e=zt("");e&&e.isViewRealm()||(e=Ft(t.__realm.vm,(()=>zt()),!0)),Object.defineProperty(this,"realm",{value:e}),Object.defineProperty(this,"id",{value:e.register(this),configurable:!0});const s=e.vm.controller.session;s.view||(s.view=this)}detach(){this.unsubscribeAll(),this.realm.deregister(this),Object.defineProperty(this,"id",{value:""})}reattach(){Object.defineProperty(this,"id",{value:this.realm.register(this)})}publish(t,e,s){this.realm.publish(e,s,t)}subscribe(t,e,s){"string"==typeof s&&(s=this[s]);const i=s;(s=i.bind(this)).unbound=i;const{event:n,handling:o}=e.event?e:{event:e};this.realm.subscribe(n,this.id,s,t,o)}unsubscribe(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;"string"==typeof s&&(s=this[s]),this.realm.unsubscribe(e,this.id,s,t)}unsubscribeAll(){this.realm.unsubscribeAll(this.id)}future(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return this.realm.future(this,t)}random(){return zt().random()}now(){return this.realm.now()}externalNow(){return this.realm.externalNow()}extrapolatedNow(){return this.realm.extrapolatedNow()}update(t){}wellKnownModel(t){return this.realm.vm.get(t)}get sessionId(){return this.realm.vm.id}get session(){return this.realm.vm.controller.session}get viewId(){return this.realm.vm.controller.viewId}[Symbol.toPrimitive](){const t=this.constructor.name;return t.includes("View")?t:`${t}[View]`}}const Il=new class{constructor(){this.ready=!1,this.isInIframe=window.top!==window,this.subscriptions={},this.enumerator=null}setReceiver(t){this.receiver=t,this.ready=!0}setIframeEnumerator(t){this.enumerator=t}on(t,e){if(!this.receiver)throw Error("setReceiver() has not been called");if("string"==typeof e&&(e=this.receiver[e]),!e)throw Error("Messenger.on: the second argument must be a method name or a function");if(this.subscriptions[t]){if(this.findIndex(this.subscriptions[t],e)>=0)throw Error(`${e} is already subscribed`)}else this.subscriptions[t]=[];this.subscriptions[t].push(e),this.listener||(this.listener=t=>this.receive(t),window.addEventListener("message",this.listener))}detach(){this.listener&&(window.removeEventListener("message",this.listener),this.listener=null),this.stopPublishingPointerMove(),this.receiver=null,this.subscriptions={},this.enumerator=null,this.ready=!1}removeSubscription(t,e){"string"==typeof e&&(e=this.receiver[e]);const s=this.subscriptions[t];if(s){const i=this.findIndex(s,e);s.splice(i,1),0===s.length&&delete this.subscriptions[t]}}removeAllSubscriptions(){this.subscriptions={}}receive(t){const{event:e,data:s}=t.data,i=t.source;this.handleEvent(e,s,i)}handleEvent(t,e,s){const i=this.subscriptions[t];i&&i.forEach((t=>{t.call(this.receiver,e,s)}))}send(t,e,s){if(this.isInIframe)return void window.top.postMessage({event:t,data:e},"*");if(s)return void s.postMessage({event:t,data:e},"*");if(!this.enumerator)return;this.enumerator().forEach((s=>{s.contentWindow.postMessage({event:t,data:e},"*")}))}findIndex(t,e){const s=e.name;return t.findIndex((t=>{const i=t.name;return s||i?s===i:e===t}))}startPublishingPointerMove(){this._moveHandler||(this._moveHandler=t=>this.send("pointerPosition",{x:t.clientX,y:t.clientY,type:t.type}),window.document.addEventListener("pointermove",this._moveHandler,!0))}stopPublishingPointerMove(){this._moveHandler&&(window.document.removeEventListener("pointermove",this._moveHandler,!0),this._moveHandler=null)}},Hl="node"===e.CROQUET_PLATFORM;let Kl=60;class zl{static async join(t){try{return await this.join_impl(t)}catch(t){throw Pt.showMessage(t.message||t,{level:"fatal"}),t}}static async join_impl(t){if("object"!=typeof t)throw Error("Croquet: please use new Session.join( {apiKey, ...} ) API. See https://croquet.io/docs/croquet/Session.html#.join");t.appId||(t.appId="no.appId"),t.name||(t.name=Pt.autoSession(),t.password||(t.password=Pt.autoPassword())),t.model||(t.model=Tl.lastRegistered),t.view||(t.view=Ml);for(const[f,b]of Object.entries(t))b instanceof Promise&&(t[f]=await b);function e(t,e){return t===e||t.prototype instanceof e}if("string"!=typeof t.apiKey)throw Error("Croquet: no apiKey provided in Session.join()!");if(t.apiKey.length>128)throw Error("Croquet: apiKey > 128 characters in Session.join()!");if("string"!=typeof t.name)throw Error("Croquet: no session name provided in Session.join()!");if(t.name.length>128)throw Error("Croquet: session name > 128 characters in Session.join()!");const s=t.model;if("function"!=typeof s||!e(s,Tl))throw Error("Croquet: bad model class in Session.join()");const i=t.view||Ml;if("function"!=typeof i||!e(i,Ml))throw Error("Croquet: bad view class in Session.join()");if("string"!=typeof t.appId)throw Error("Croquet: no appId provided in Session.join()");if(!t.appId.length>128)throw Error("Croquet: appId > 128 characters in Session.join()");if(!t.appId.match(/^[a-z](-?[a-z0-9_])*(\.[a-z0-9_](-?[a-z0-9_])*)+$/i))throw Error("Croquet: malformed appId in Session.join()");if("string"!=typeof t.password||!t.password)throw Error("Croquet: no password provided in Session.join()");const n=r.reflector||t.reflector;n&&(r.reflector=n);const o=r.files||t.files;o&&(r.files=o);const a=r.backend||t.backend;if(a&&(r.backend=a),Hl&&"manual"!==t.step)throw Error("stepping must be manual in a Node.js app");if("rejoinLimit"in t){if("number"!=typeof t.rejoinLimit||t.rejoinLimit<0||t.rejoinLimit>6e4)throw Error("rejoinLimit range: 0-60000")}else t.rejoinLimit=1e3;if("eventRateLimit"in t){if("number"!=typeof t.eventRateLimit||t.eventRateLimit<1||t.eventRateLimit>60)throw Error("eventRateLimit range: 1-60")}else t.eventRateLimit=20;if(t.heraldUrl){if(t.heraldUrl.length>256)throw Error("heraldUrl can only be 256 characters");if(!t.heraldUrl.startsWith("https://"))throw Error("heraldUrl needs to be https")}if(t.hashOverride){if(43!==t.hashOverride.length)throw Error("hashOverride must be 43 characters");if(-1!==t.hashOverride.search(/[^-_a-zA-Z0-9]/))throw Error("hashOverride must be base64url encoded")}if(t.debug){function g(t){return"string"==typeof t&&(t=t.split(",")),t?Array.isArray(t)?t:[t]:[]}r.debug=[...g(t.debug),...g(r.debug)].join(",")}if("autoSleep"in t){const w=t.autoSleep,Z=typeof w;if("number"===Z){if(w<0)throw Error("an autoSleep value must be >= 0")}else{if("boolean"!==Z)throw Error("autoSleep must be numeric or boolean");t.autoSleep=w?10:0}}else t.autoSleep=10;if(t.flags){let v=t.flags;"string"==typeof v&&(v=v.split(",")),v=v?Array.isArray(v)?v:[v]:[],v=v.filter((t=>"object"!=typeof t)),v.length?(t.flags={},v.forEach((e=>t.flags[e]=!0))):t.flags=null}"expectedSimFPS"in t&&(Kl=Math.min(t.expectedSimFPS,120));const l=["name","password","apiKey","appId","tps","autoSleep","heraldUrl","rejoinLimit","eventRateLimit","optionsFromUrl","viewOptions","viewIdDebugSuffix","hashOverride","location","flags","progressReporter"];!function(){if(Object.isFrozen(Nl))return;Fl(Nl),function(t){const e=JSON.stringify(t,((t,e)=>"function"==typeof e?G(e):e));if("{}"===e)return;const s=JSON.parse(e),i=V(y(s));P.push(i),i.then((t=>T[t].what="Croquet Constants"))}(Nl)}();const c=new Fa,d=JSON.parse(JSON.stringify({...t.options})),h={id:"",persistentId:"",versionId:"",name:t.name,model:null,view:null,step(t){c.stepSession("animation",{frameTime:t,view:h.view,expectedSimFPS:Kl})},leave:()=>zl.leave(h.id),get latency(){return c.latency},get latencies(){return c.latencies}},u={options:d,initFn:(t,e)=>s.create(t,e,"modelRoot"),rebootModelView:p};for(const[X,L]of Object.entries(t))l.includes(X)&&(u[X]=L);await c.initFromSessionSpec(u);let m=!1;return await p(),"manual"!==t.step&&c.startStepping(h.step),h;async function p(){!function(){h.model=null,h.view&&(r.has("debug","session",!1)&&console.log(h.id,"detaching root view"),h.view.detach(),""!==h.view.id&&console.warn(`Croquet: ${h.view} did not call super.detach()`),h.view=null);Pt.clearSessionMoniker(),Il.ready&&Il.detach()}(),c.leaving?c.leaving(!0):m||(m=!0,await c.establishSession(u),m=!1,h.model=c.vm.get("modelRoot"),h.id=c.id,h.persistentId=c.persistentId,h.versionId=c.versionId,c.session=h,Pt.makeSessionWidgets(h.id),c.inViewRealm((()=>{r.has("debug","session",!1)&&console.log(h.id,"creating root view"),new i(h.model,u.viewOptions)})))}}static async leave(t){const e=function(t){for(const e of za)if(e.id===t)return e;return null}(t);if(!e)return!1;e.reconnectTimeout&&(clearTimeout(e.reconnectTimeout),delete e.reconnectTimeout);const s=new Promise((t=>e.leaving=t)),i=e.connection;return!!i.connected&&(i.closeConnection(1e3),s)}static thisSession(){const t=ml.current();return t?t.id:""}}const Nl={};function Fl(t){if(!Object.isFrozen(t)){Object.freeze(t);for(const e of Object.values(t))!e||"object"!=typeof e&&"function"!=typeof e||Fl(e)}}exports.App=Pt,exports.Constants=Nl,exports.Data=Aa,exports.Messenger=Il,exports.Model=Tl,exports.Session=zl,exports.View=Ml,exports.gatherInternalClassTypes=function(t,e){const s={};return xl({root:t},e,s,new Set),s},exports.startSession=function(){return Pt.showMessage("Croquet.startSession() is deprecated, please use Croquet.Session.join()",{level:"warning",only:"once"}),zl.join(...arguments)}; @@ -7015,11 +7015,12 @@ function setupController(fullScreenFlag) { function setupFullScreenButton() { let fullScreenBtn = document.querySelector("#fullScreenBtn"); + let microverse = document.querySelector("#microverse"); if (!fullScreenBtn) { let div = document.createElement("div"); div.innerHTML = _src_hud_js__WEBPACK_IMPORTED_MODULE_2__.fullScreenHTML; fullScreenBtn = div.children[0]; - document.body.appendChild(fullScreenBtn); + (microverse || document.body).appendChild(fullScreenBtn); fullScreenBtn.onclick = (e) => { e.stopPropagation(); @@ -7047,158 +7048,15 @@ function setupFullScreenButton() { class HudController { constructor() { this.hud = document.querySelector("#hud"); + let microverse = document.querySelector("#microverse"); if (!this.hud) { let div = document.createElement("div"); div.innerHTML = _src_hud_js__WEBPACK_IMPORTED_MODULE_2__.innerHTML; this.hud = div.children[0]; - document.body.appendChild(this.hud); + (microverse || document.body).appendChild(this.hud); } - - /* - // joystick sends events into primary frame - this.capturedPointers = {}; - - this.joystick = this.hud.querySelector("#joystick"); - this.knob = this.joystick.querySelector("#knob"); - this.trackingknob = this.joystick.querySelector("#trackingknob"); - - window.onresize = () => this.adjustJoystickKnob(); - - if (!document.head.querySelector("#joystick-css")) { - let css = document.createElement("link"); - css.rel = "stylesheet"; - css.type = "text/css"; - css.id = "joystick-css"; - css.onload = () => { - this.adjustJoystickKnob(); - if (this._hudFlags) { - this.setButtonsVisibility(this._hudFlags); - delete this._hudFlags; - } - }; - let root = window.microverseDir ? window.microverseDir : "./"; - css.href = root + "assets/css/joystick.css"; - document.head.appendChild(css); - } else { - this.adjustJoystickKnob(); - } - - this.releaseHandler = (e) => { - for (let k in this.capturedPointers) { - this.joystick.releasePointerCapture(k); - } - this.capturedPointers = {}; - this.endMMotion(e); - }; - this.joystick.onpointerdown = (e) => { - if (e.pointerId !== undefined) { - this.capturedPointers[e.pointerId] = "hiddenKnob"; - this.joystick.setPointerCapture(e.pointerId); - } - this.startMMotion(e); // use the knob to start - }; - //this.joystick.onpointerenter = (e) => console.log("shell: pointerEnter") - // this.joystick.onpointerleave = (e) => this.releaseHandler(e); - this.joystick.onpointermove = (e) => this.updateMMotion(e); - this.joystick.onpointerup = (e) => this.releaseHandler(e); - this.joystick.onpointercancel = (e) => this.releaseHandler(e); - this.joystick.onlostpointercapture = (e) => this.releaseHandler(e); - */ } - - /* - - adjustJoystickKnob() { - let joystickStyle = window.getComputedStyle(this.joystick); - let knobStyle = window.getComputedStyle(this.knob); - let center = (parseFloat(joystickStyle.width) || 120) / 2; - let size = (parseFloat(knobStyle.width) || 60) / 2; - let radius = center - size; - this.joystickLayout = { center, radius }; - this.trackingknob.style.transform = "translate(0px, 0px)"; // top-left - this.knob.style.transform = `translate(${center-size}px, ${center-size}px)`; // eslint-disable-line - } - - // mouse motion via joystick element - - startMMotion(e) { - this.activeMMotion = {}; - this.updateMMotion(e, "motion-start"); - } - - endMMotion(e) { - e.preventDefault(); - e.stopPropagation(); - this.activeMMotion = null; - let { radius } = this.joystickLayout; - this.trackingknob.style.transform = "translate(0px, 0px)"; - this.knob.style.transform = `translate(${radius}px, ${radius}px)`; - sendToSelf("motion-end"); - } - - updateMMotion(e, cmd = "motion-update") { - e.preventDefault(); - e.stopPropagation(); - - if (this.activeMMotion) { - let { center, radius } = this.joystickLayout; - - let dx = e.offsetX - center; - let dy = e.offsetY - center; - - sendToSelf(cmd, {dx, dy}); - this.activeMMotion.dx = dx; - this.activeMMotion.dy = dy; - - this.trackingknob.style.transform = `translate(${dx}px, ${dy}px)`; - - let squaredDist = dx ** 2 + dy ** 2; - if (squaredDist > radius ** 2) { - let dist = Math.sqrt(squaredDist); - dx = radius * dx / dist; - dy = radius * dy / dist; - } - - this.knob.style.transform = `translate(${radius + dx}px, ${radius + dy}px)`; - } - } - - */ - - /* - setupFullScreenButton() { - let div = document.createElement("div"); - div.innerHTML = fullScreenHTML; - let fullscreenBtn = div.children[0]; - - this.hud.appendChild(fullscreenBtn); - this.fullscreenBtn = this.hud.querySelector("#fullscreenBtn"); - - if (this.fullscreenBtn) { - this.fullscreenBtn.onclick = (e) => { - e.stopPropagation(); - e.preventDefault(); - - if (e.shiftKey) { - document.body.classList.toggle("tilt"); - return; - } - - if (!document.fullscreenElement) { - // If the document is not in full screen mode - // make the document full screen - document.body.requestFullscreen(); - } else { - // Otherwise exit the full screen - if (document.exitFullscreen) { - document.exitFullscreen(); - } - } - }; - } - } - */ } class Shell { @@ -7322,7 +7180,8 @@ class Shell { }; if (owningFrameId) this.frameEntry(owningFrameId)?.ownedFrames.add(portalId); this.frames.set(portalId, frameEntry); - document.body.appendChild(frame); + let microverse = document.querySelector("#microverse"); + (microverse || document.body).appendChild(frame); this.sendFrameType(portalId); // console.log("shell: added frame", portalId, portalURL); return portalId; @@ -8334,7 +8193,8 @@ const AM_PointerTarget = superclass => class extends superclass { } if (!behaviorName && behavior) { - behaviorName = behavior.$behaviorName; + let compiled = behavior.ensureBehavior(); + behaviorName = compiled.$behaviorName; } let array = this.eventListeners.get(eventName); @@ -8372,7 +8232,7 @@ const AM_PointerTarget = superclass => class extends superclass { */ - let behaviorName = this._behavior.$behaviorName; + let behaviorName = this._behavior.ensureBehavior().$behaviorName; let moduleName = this._behavior.module.externalName; let array = this.eventListeners.get(eventName); @@ -8531,15 +8391,15 @@ const PM_Pointer = superclass => class extends superclass { // immediate handling so handler runs inside of the DOM event handler invocation // and can open links, toggle audio, etc. - this.subscribe("input", {event: "pointerDown", handling: "immediate"}, this.doPointerDown); - this.subscribe("input", {event: "pointerUp", handling: "immediate"}, this.doPointerUp); - this.subscribe("input", {event: "pointerMove", handling: "immediate"}, this.doPointerMove); - this.subscribe("input", {event: "click", handling: "immediate"}, this.doPointerClick); - this.subscribe("input", {event: "wheel", handling: "immediate"}, this.doPointerWheel); - this.subscribe("input", {event: "doubleDown", handling: "immediate"}, this.doPointerDoubleDown); - this.subscribe("input", {event: "tap", handling: "immediate"}, this.doPointerTap); - this.subscribe("input", {event: "keyDown", handling: "immediate"}, this.doKeyDown); - this.subscribe("input", {event: "keyUp", handling: "immediate"}, this.doKeyUp); + this.subscribe("_input", {event: "pointerDown", handling: "immediate"}, this.doPointerDown); + this.subscribe("_input", {event: "pointerUp", handling: "immediate"}, this.doPointerUp); + this.subscribe("_input", {event: "pointerMove", handling: "immediate"}, this.doPointerMove); + this.subscribe("_input", {event: "click", handling: "immediate"}, this.doPointerClick); + this.subscribe("_input", {event: "wheel", handling: "immediate"}, this.doPointerWheel); + this.subscribe("_input", {event: "doubleDown", handling: "immediate"}, this.doPointerDoubleDown); + this.subscribe("_input", {event: "tap", handling: "immediate"}, this.doPointerTap); + this.subscribe("_input", {event: "keyDown", handling: "immediate"}, this.doKeyDown); + this.subscribe("_input", {event: "keyUp", handling: "immediate"}, this.doKeyUp); this.firstResponders = new Map(); this.lastResponders = new Map(); @@ -8899,10 +8759,11 @@ const PM_Pointer = superclass => class extends superclass { pe.shiftKey = wcEvent.shiftKey; pe.metaKey = wcEvent.metaKey; pe.xy = wcEvent.xy; - pe.id = wcEvent.id; + pe.pointerId = wcEvent.pointerId; pe.button = wcEvent.button; pe.buttons = wcEvent.buttons; pe.instanceId = rc.instanceId; + pe.pressure = wcEvent.pressure; if (rc.ray) { pe.ray = {origin: rc.ray.origin.toArray(), direction: rc.ray.direction.toArray()}; } @@ -9070,9 +8931,9 @@ const PM_ThreeCamera = superclass => class extends (0,_worldcore__WEBPACK_IMPORT } setRaycastFrom2D(xy) { - const x = ( xy[0] / window.innerWidth ) * 2 - 1; - const y = - ( xy[1] / window.innerHeight ) * 2 + 1; const render = this.service("ThreeRenderManager"); + const x = ( xy[0] / render.canvas.width ) * 2 - 1; + const y = - ( xy[1] / render.canvas.height) * 2 + 1; if (!this.raycaster) this.raycaster = new THREE.Raycaster(); this.raycaster.setFromCamera({x: x, y: y}, render.camera); this.raycaster.params.Line = {threshold: 0.2}; @@ -9383,10 +9244,11 @@ class ThreeRenderManager extends _worldcore__WEBPACK_IMPORTED_MODULE_0__.RenderM this.camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 10000); if (!options.canvas) { + let microverse = document.querySelector("#microverse"); this.canvas = document.createElement("canvas"); this.canvas.id = "ThreeCanvas"; - this.canvas.style.cssText = "position: absolute; left: 0; top: 0; z-index: 0"; - document.body.insertBefore(this.canvas, null); + this.canvas.style.zIindex = 0; + (microverse || document.body).appendChild(this.canvas); options.canvas = this.canvas; } @@ -9406,6 +9268,8 @@ class ThreeRenderManager extends _worldcore__WEBPACK_IMPORTED_MODULE_0__.RenderM options.canvas = this.canvas; } + this.publish("_input", "setMicroverseDiv", {divQuery: "#microverse", canvasQuery: "#ThreeCanvas"}); + this.renderer = new THREE.WebGLRenderer(options); this.renderer.shadowMap.enabled = true; // this.renderer.outputColorSpace = THREE.LinearSRGBColorSpace; @@ -9454,7 +9318,8 @@ class ThreeRenderManager extends _worldcore__WEBPACK_IMPORTED_MODULE_0__.RenderM this.observer = new MutationObserver(styleCallback); this.observer.observe(this.vrButton, {attributes: true, attributeFilter: ["style"]}); - document.body.appendChild(this.vrButton); + let microverse = document.querySelector("#microverse"); + (microverse || document.body).appendChild(this.vrButton); this.renderer.xr.enabled = true; this.xrController = new XRController(this); } else { @@ -9463,15 +9328,16 @@ class ThreeRenderManager extends _worldcore__WEBPACK_IMPORTED_MODULE_0__.RenderM this.renderPass = new three_examples_jsm_postprocessing_RenderPass_js__WEBPACK_IMPORTED_MODULE_4__.RenderPass( this.scene, this.camera ); this.composer.addPass( this.renderPass ); } - this.resize(); - this.subscribe("input", "resize", () => this.resize()); + + // this.resize(); + this.subscribe("_input", "resize", this.resize); this.setRender(true); }); } installOutlinePass() { if(!this.outlinePass){ - this.outlinePass = new three_examples_jsm_postprocessing_OutlinePass_js__WEBPACK_IMPORTED_MODULE_5__.OutlinePass( new THREE.Vector2( window.innerWidth, window.innerHeight ), this.scene, this.camera ); + this.outlinePass = new three_examples_jsm_postprocessing_OutlinePass_js__WEBPACK_IMPORTED_MODULE_5__.OutlinePass( new THREE.Vector2(this.canvas.width, this.canvas.height), this.scene, this.camera ); this.outlinePass.edgeStrength = 3.0; this.outlinePass.edgeGlow = 0.1; this.outlinePass.edgeThickness = 1.5; @@ -9522,12 +9388,13 @@ class ThreeRenderManager extends _worldcore__WEBPACK_IMPORTED_MODULE_0__.RenderM if (this.observer) this.observer.disconnect(); } - resize() { - this.camera.aspect = window.innerWidth / window.innerHeight; + resize(obj) { + // console.log("three resize", obj); + this.camera.aspect = obj.width / obj.height; this.camera.updateProjectionMatrix(); - this.renderer.setSize(window.innerWidth, window.innerHeight); + this.renderer.setSize(obj.width, obj.height); if (this.composer) { - this.composer.setSize(window.innerWidth, window.innerHeight) + this.composer.setSize(obj.width, obj.height) } } @@ -10871,12 +10738,13 @@ class AvatarActor extends (0,_worldcore__WEBPACK_IMPORTED_MODULE_0__.mix)(_card_ const TEXT_SCALE = 0.005; // 100px of text scales to 0.5 world units const PADDING = 0.1; // horizontal and vertical const MARGIN_FUDGE = 0.02; // compensate for text widget's small gap at the left + const voiceLevelBehavior = this.behaviorManager.hasBehavior("AvatarVoiceLevel") ? ["AvatarVoiceLevel"] : []; if (!this.nicknameCard) { const marginLeft = (PADDING - MARGIN_FUDGE) / TEXT_SCALE; const marginTop = PADDING * 1.1 / TEXT_SCALE; const options = { name: 'nickname', - behaviorModules: ["Billboard"], + behaviorModules: ["Billboard", ...voiceLevelBehavior], translation: [0, 1, -0.1], // above and slightly in front type: "text", depth: 0.02, @@ -11230,8 +11098,9 @@ class AvatarActor extends (0,_worldcore__WEBPACK_IMPORTED_MODULE_0__.mix)(_card_ type: "text", depth: 0.05, margins: {left: 20, top: 20, right: 20, bottom: 20}, - backgroundColor: 0xf4e056, + backgroundColor: 0xc4a836, frameColor: 0xfad912, + fullBright: true, runs, width: 1, height: 1, @@ -11976,7 +11845,8 @@ class AvatarPawn extends (0,_worldcore__WEBPACK_IMPORTED_MODULE_0__.mix)(_card_j let c = document.createElement("div"); c.innerHTML = `
0
`; userCountDisplay = c.firstChild; - document.body.appendChild(userCountDisplay); + let microverse = document.querySelector("#microverse"); + (microverse || document.body).appendChild(userCountDisplay); if (this.service("DolbyChatManager") && window.innerWidth >= 600) { userCountDisplay.style.left = "40%"; @@ -12782,6 +12652,12 @@ class AvatarPawn extends (0,_worldcore__WEBPACK_IMPORTED_MODULE_0__.mix)(_card_j } } + doubleDown(e) { + if (e.shiftKey) { + this.addSticky(e); + } + } + stopFalling() { this.isFalling = false; } @@ -12993,6 +12869,9 @@ class AvatarPawn extends (0,_worldcore__WEBPACK_IMPORTED_MODULE_0__.mix)(_card_j let behaviorModules = actor._behaviorModules || []; let avatarType = configuration.avatarType; let maybeDataLocation = oldCardData.dataLocation; + let type = oldCardData.type; + + if (type === "object") {return oldCardData;} [ "dataLocation", "dataTranslation", "dataScale", "dataRotation", "handedness", @@ -14594,6 +14473,7 @@ class CardPawn extends (0,_worldcore__WEBPACK_IMPORTED_MODULE_0__.mix)(_worldcor onPointerDoubleDown(pe) { if (!pe.targetId) {return;} + if (pe.shiftKey || pe.ctrlKey || pe.altKey) {return;} let pose = this.getJumpToPose ? this.getJumpToPose() : null; if (pose) { pe.xyz = pose[0]; // world coordinates @@ -14979,12 +14859,14 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ BehaviorViewManager: () => (/* binding */ BehaviorViewManager), /* harmony export */ CodeLibrary: () => (/* binding */ CodeLibrary), /* harmony export */ PM_Code: () => (/* binding */ PM_Code), -/* harmony export */ checkModule: () => (/* binding */ checkModule) +/* harmony export */ checkModule: () => (/* binding */ checkModule), +/* harmony export */ compileToModule: () => (/* binding */ compileToModule) /* harmony export */ }); /* harmony import */ var _worldcore__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./worldcore */ "./src/worldcore.js"); /* harmony import */ var _ThreeRender_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ThreeRender.js */ "./src/ThreeRender.js"); /* harmony import */ var _physics_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./physics.js */ "./src/physics.js"); /* harmony import */ var _frame_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./frame.js */ "./src/frame.js"); +/* harmony import */ var _compiler_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./compiler.js */ "./src/compiler.js"); // Copyright 2022 by Croquet Corporation, Inc. All Rights Reserved. // https://croquet.io // info@croquet.io @@ -14996,7 +14878,9 @@ const {ViewService, ModelService, GetPawn, Model, Constants, App} = _worldcore__ -//console.log(WorldcoreRapierExports); + + +let compiledBehaviors = new Map(); // class extends superclass { future(time) { if (!this[isProxy]) {return super.future(time);} - let behaviorName = this._behavior.$behaviorName; + let compiled = this._behavior.getCompiledBehavior(); + let behaviorName = compiled.$behaviorName; let moduleName = this._behavior.module.externalName; return this.futureWithBehavior(time, moduleName, behaviorName); } @@ -15123,7 +15008,9 @@ const AM_Code = superclass => class extends superclass { get(_target, property) { let behavior = behaviorManager.lookup(moduleName, behaviorName); - let func = property === "call" ? basicCall : behavior.$behavior[property]; + let compiled = behavior.getCompiledBehavior(); + + let func = property === "call" ? basicCall : compiled.$behavior[property]; let fullName = property === "call" ? "call" : `${moduleName}$${behaviorName}.${property}`; if (typeof func === "function") { const methodProxy = new Proxy(func, { @@ -15213,8 +15100,15 @@ const AM_Code = superclass => class extends superclass { let behavior = behaviorManager.lookup(module, behaviorName); if (!behavior) {return false;} + + let $behavior; + if (isActor) { + $behavior = behavior.ensureBehavior().$behavior + } else { + $behavior = behavior.ensureBehavior().$behavior; + } if (!maybeMethod) {return true;} - return !!behavior.$behavior[maybeMethod]; + return !!$behavior[maybeMethod]; } // setup() of a behavior, and typically a subscribe call in it, gets called multiple times @@ -15262,7 +15156,7 @@ const AM_Code = superclass => class extends superclass { } if (!behaviorName && behavior) { - behaviorName = behavior.$behaviorName; + behaviorName = behavior.getCompiledBehavior().$behaviorName; } let fullMethodName; @@ -15381,14 +15275,14 @@ const PM_Code = superclass => class extends superclass { if (pawnBehaviors) { for (let behavior of pawnBehaviors.values()) { if (behavior) { - behavior.ensureBehavior(); - } - // future(0) is used so that setup() is called after - // all behaviors specified are installed. - if (behavior.$behavior.setup) { - this.future(0).callSetup(`${module.externalName}$${behavior.$behaviorName}`); + let {$behavior, $behaviorName} = behavior.ensureBehavior(); + // future(0) is used so that setup() is called after + // all behaviors specified are installed. + if ($behavior.setup) { + this.future(0).callSetup(`${module.externalName}$${$behaviorName}`); + } } - }; + } } }); } @@ -15436,8 +15330,9 @@ const PM_Code = superclass => class extends superclass { let {pawnBehaviors} = module; if (pawnBehaviors) { for (let behavior of pawnBehaviors.values()) { - if (behavior.$behavior.teardown) { - this.call(`${behavior.module.externalName}$${behavior.$behaviorName}`, "teardown"); + let {$behavior, $behaviorName} = behavior.ensureBehavior(); + if ($behavior.teardown) { + this.call(`${behavior.module.externalName}$${$behaviorName}`, "teardown"); } }; } @@ -15524,7 +15419,7 @@ const PM_Code = superclass => class extends superclass { } if (!behaviorName && behavior) { - behaviorName = behavior.$behaviorName; + behaviorName = behavior.getCompiledBehavior().$behaviorName; } let fullMethodName; @@ -15589,7 +15484,7 @@ const PM_Code = superclass => class extends superclass { // so there is one instance of ScriptBehavior for each defined behavior. class ScriptingBehavior extends Model { - static okayToIgnore() { return [ "$behavior", "$behaviorName" ]; } + // static okayToIgnore() { return [ "$behavior", "$behaviorName" ]; } init(options) { this.systemBehavior = !!options.systemBehavior; @@ -15599,16 +15494,10 @@ class ScriptingBehavior extends Model { this.location = options.location; } - setCode(string) { + compileBehavior(string) { if (!string) { - console.log("code is empty for ", this); - return; + string = this.code; } - - let theSame = this.code === string; - - this.code = string; - let trimmed = string.trim(); let source; if (trimmed.length === 0) {return;} @@ -15620,7 +15509,7 @@ class ScriptingBehavior extends Model { let cls; try { const Microverse = {..._worldcore__WEBPACK_IMPORTED_MODULE_0__, ..._ThreeRender_js__WEBPACK_IMPORTED_MODULE_1__, ..._physics_js__WEBPACK_IMPORTED_MODULE_2__, ..._frame_js__WEBPACK_IMPORTED_MODULE_3__, RAPIER: _physics_js__WEBPACK_IMPORTED_MODULE_2__.Physics, getViewRoot}; - cls = new Function("Worldcore", "Microverse", code)(Microverse, Microverse); + cls = new Function("Microverse", code)(Microverse); } catch(error) { console.log("error occured while compiling:", source, error); try { @@ -15633,34 +15522,57 @@ class ScriptingBehavior extends Model { return; } - this.$behavior = cls.prototype; - this.$behaviorName = cls.name; + return cls; + } - if (!theSame) { - this.publish(this.id, "setCode", string); + getCompiledBehavior() { + return compiledBehaviors.get(this); + } + + setCode(string, forView) { + if (!string) { + console.log("code is empty for ", this); + return; + } + + let theSame = this.code === string; + let cls = this.compileBehavior(string); + let result = {$behavior: cls.prototype, $behaviorName: cls.name}; + compiledBehaviors.set(this, result); + + if (forView) { + if (!theSame) { + throw Error("view cannot specify new code"); + } + } else { + if (!theSame) { + this.code = string; + this.publish(this.id, "setCode", string); + } } + return result; } ensureBehavior() { - if (!this.$behavior) { - let maybeCode = this.code; - this.setCode(maybeCode); + let entry = compiledBehaviors.get(this); + if (!entry) { + let cls = this.compileBehavior(); + entry = {$behavior: cls.prototype, $behaviorName: cls.name}; + compiledBehaviors.set(this, entry); } - return this.$behavior; + return entry; } invoke(receiver, name, ...values) { - this.ensureBehavior(); - let myHandler = this.$behavior; - let behaviorName = this.$behaviorName; + let {$behavior, $behaviorName} = this.ensureBehavior(); let module = this.module; let result; - let proxy = newProxy(receiver, myHandler, module, this); + let proxy = newProxy(receiver, $behavior, module, this); try { let prop = proxy[name]; if (typeof prop === "undefined") { - throw new Error(`a method named ${name} not found in ${behaviorName || this}`); + throw new Error(`a method named ${name} not found in ${$behaviorName || this}`); } if (typeof prop === "function") { result = prop.apply(proxy, values); @@ -15668,8 +15580,8 @@ class ScriptingBehavior extends Model { result = prop; } } catch (e) { - console.error(`an error occured in ${behaviorName}.${name}() on`, receiver, e); - App.messages && App.showMessage(`Error in ${behaviorName}.${name}()`, { level: "error" }); + console.error(`an error occured in ${$behaviorName}.${name}() on`, receiver, e); + App.messages && App.showMessage(`Error in ${$behaviorName}.${name}()`, { level: "error" }); } return result; } @@ -15765,12 +15677,10 @@ class BehaviorModelManager extends ModelService { if (!module) {return null;} let b = module.actorBehaviors.get(behaviorName); if (b) { - b.ensureBehavior(); return b; } b = module.pawnBehaviors.get(behaviorName); if (b) { - b.ensureBehavior(); return b; } return null; @@ -15944,7 +15854,7 @@ class BehaviorModelManager extends ModelService { let toPublish = []; changed.forEach((behavior) => { - if (!behavior.$behavior.setup) {return;} + if (!behavior.getCompiledBehavior().$behavior.setup) {return;} if (behavior.type === "actorBehavior") { let modelUsers = this.modelUses.get(behavior); let actorManager = this.service("ActorManager"); @@ -15957,7 +15867,7 @@ class BehaviorModelManager extends ModelService { }); } } else if (behavior.type === "pawnBehavior") { - toPublish.push([behavior.module.externalName, behavior.$behaviorName]); + toPublish.push([behavior.module.externalName, behavior.getCompiledBehavior().$behaviorName]); } }); this.publish(this.id, "callViewSetupAll", toPublish); @@ -15992,7 +15902,7 @@ class BehaviorModelManager extends ModelService { if (array.indexOf(modelId) < 0) { array.push(modelId); behavior.ensureBehavior(); - if (behavior.$behavior.setup) { + if (behavior.getCompiledBehavior().$behavior.setup) { behavior.invoke(model[isProxy] ? model._target : model, "setup"); } } @@ -16005,7 +15915,8 @@ class BehaviorModelManager extends ModelService { let ind = array.indexOf(modelId); if (ind < 0) {return;} array.splice(ind, 1); - if (behavior.$behavior && behavior.$behavior.teardown) { + let compiled = behavior.getCompiledBehavior(); + if (compiled && compiled.$behavior.teardown) { behavior.future(0).invoke(model[isProxy] ? model._target : model, "teardown"); } } @@ -16021,9 +15932,9 @@ class BehaviorModelManager extends ModelService { array.push(modelId); } - behavior.ensureBehavior(); - if (behavior.$behavior.setup) { - model.say("callSetup", `${behavior.module.externalName}$${behavior.$behaviorName}`); + let {$behavior, $behaviorName} = behavior.ensureBehavior(); + if ($behavior.setup) { + model.say("callSetup", `${behavior.module.externalName}$${$behaviorName}`); } } @@ -16034,8 +15945,9 @@ class BehaviorModelManager extends ModelService { let ind = array.indexOf(modelId); if (ind < 0) {return;} array.splice(ind, 1); - if (behavior.$behavior && behavior.$behavior.teardown) { - model.say("callTeardown", `${behavior.module.externalName}$${behavior.$behaviorName}`); + let compiled = behavior.getCompiledBehavior(); + if (compiled && compiled.$behavior.teardown) { + model.say("callTeardown", `${behavior.module.externalName}$${compiled.$behaviorName}`); } } } @@ -16061,6 +15973,7 @@ class BehaviorViewManager extends ViewService { this.callback(false); } this.setURL(null); + compiledBehaviors = new Map(); super.destroy(); } @@ -16136,9 +16049,7 @@ class BehaviorViewManager extends ViewService { let systemModuleMap = new Map(); - let dataURLs = []; let promises = []; - let scripts = []; if (!window._allResolvers) { window._allResolvers = new Map(); @@ -16153,86 +16064,64 @@ class BehaviorViewManager extends ViewService { array.forEach((obj) => { // {action, name, content, systemModule} = obj; if (obj.action === "add") { + delete obj.action; systemModuleMap.set(obj.name, obj.systemModule); - let id = Math.random().toString(); - let promise = new Promise((resolve, _reject) => { - current.set(id, resolve); - let script = document.createElement("script"); - scripts.push(script); - script.type = "module"; - let dataURL = URL.createObjectURL(new Blob([obj.content], {type: "application/javascript"})); - script.innerHTML = ` -import * as data from "${dataURL}"; -let map = window._allResolvers.get("${key}"); -if (map) {map.get("${id}")({data, key: ${key}, name: "${obj.name}"});} -`; - document.body.appendChild(script); - dataURLs.push(dataURL); - }).catch((e) => {console.log(e); return null}); - promises.push(promise); + let modPromise = compileToModule(obj.content, obj.name) + .catch((e) => {console.log(e); return null;}); + promises.push(modPromise); } }); Promise.all(promises).then(async (allData) => { - dataURLs.forEach((url) => URL.revokeObjectURL(url)); - scripts.forEach((s) => s.remove()); allData = allData.filter((o) => o); if (allData.length === 0) {return;} - let keys = [...window._allResolvers.keys()]; + // probably it needs to check if another loop is underway - let index = keys.indexOf(key); - window._allResolvers.delete(key); + let library = new CodeLibrary(); + allData.forEach((obj) => { + let dot = obj.name.lastIndexOf("."); + let location = obj.name.slice(0, dot); + let isSystem = obj.name.startsWith("croquet"); - if (index !== keys.length - 1) { - // if it is not the last element, - // there was already another call so discard it - } else { - let library = new CodeLibrary(); - allData.forEach((obj) => { - let dot = obj.name.lastIndexOf("."); - let location = obj.name.slice(0, dot); - let isSystem = obj.name.startsWith("croquet"); - - if (!obj || checkModule(obj.data)) { - throw new Error("a behavior file does not export an array of modules"); - } + if (!obj || checkModule(obj.data)) { + throw new Error("a behavior file does not export an array of modules"); + } - library.add(obj.data.default, location, isSystem); - }); + library.add(obj.data.default, location, isSystem); + }); - let sendBuffer = []; - let key = Math.random(); + let sendBuffer = []; + let key = Math.random(); - for (let [_k, m] of library.modules) { - let {actorBehaviors, pawnBehaviors, name, location, systemModule} = m; - sendBuffer.push({ - name, systemModule, location, - actorBehaviors: [...actorBehaviors], - pawnBehaviors: [...pawnBehaviors] - }); - }; + for (let [_k, m] of library.modules) { + let {actorBehaviors, pawnBehaviors, name, location, systemModule} = m; + sendBuffer.push({ + name, systemModule, location, + actorBehaviors: [...actorBehaviors], + pawnBehaviors: [...pawnBehaviors] + }); + }; - let string = JSON.stringify(sendBuffer); - let array = new TextEncoder().encode(string); - let ind = 0; + let string = JSON.stringify(sendBuffer); + let array = new TextEncoder().encode(string); + let ind = 0; - this.publish(this.model.id, "loadStart", key); - let throttle = array.length > 80000; + this.publish(this.model.id, "loadStart", key); + let throttle = array.length > 80000; - while (ind < array.length) { - let buf = array.slice(ind, ind + 2880); - this.publish(this.model.id, "loadOne", {key, buf}); - ind += 2880; - if (throttle) { - await new Promise((resolve) => { - setTimeout(resolve, 5); - }); - } + while (ind < array.length) { + let buf = array.slice(ind, ind + 2880); + this.publish(this.model.id, "loadOne", {key, buf}); + ind += 2880; + if (throttle) { + await new Promise((resolve) => { + setTimeout(resolve, 16); + }); } - - this.publish(this.model.id, "loadDone", key); } + + this.publish(this.model.id, "loadDone", key); }); } } @@ -16246,7 +16135,7 @@ class CodeLibrary { this.classes = new Map(); } - add(library, location, isSystem) { + add(library, location, isSystem, language) { if (library.modules) { library.modules.forEach(module => { let {name, actorBehaviors, pawnBehaviors} = module; @@ -16272,7 +16161,8 @@ class CodeLibrary { location, actorBehaviors: actors, pawnBehaviors: pawns, - systemModule: isSystem + systemModule: isSystem, + language: language }); }); } @@ -16336,6 +16226,140 @@ function checkModule(module) { }); } +function compileToModule(text, path) { + let language = path.endsWith(".ts") ? "ts" : "js"; + + let jsCompiler; + let tsCompiler; + + if (!jsCompiler) { + jsCompiler = new _compiler_js__WEBPACK_IMPORTED_MODULE_4__.JSCompiler(); + } + + let js = jsCompiler.compile(text, path); + + if (language === "ts") { + if (!tsCompiler) { + tsCompiler = new _compiler_js__WEBPACK_IMPORTED_MODULE_4__.TSCompiler(); + } + js = tsCompiler.compile(js, path); + } + + let dataURL = URL.createObjectURL(new Blob([js], {type: "application/javascript"})); + return eval(`import("${dataURL}")`).then((mod) => { + return {name: path, data: mod}; + }).finally(() => { + URL.revokeObjectURL(dataURL); + }); +} + + +/***/ }), + +/***/ "./src/compiler.js": +/*!*************************!*\ + !*** ./src/compiler.js ***! + \*************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ JSCompiler: () => (/* binding */ JSCompiler), +/* harmony export */ TSCompiler: () => (/* binding */ TSCompiler) +/* harmony export */ }); +class TSCompiler { + constructor() { + if (!window.ts) {return;} + this.options = { + module: ts.ModuleKind.ESNext, + target: ts.ScriptTarget.ESNext, + noResolve: true, + }; + this.compilerHost = this.createCompilerHost(); + } + + compile(tsCode, location) { + if (!window.ts) {return tsCode;} + this.sources = new Map([[location, tsCode]]); + this.results = new Map(); + + let program = ts.createProgram([location], this.options, this.compilerHost); + let result = program.emit(); + + let compiledName = location.replace(/\.ts$/, ".js"); + + let compiled = this.results.get(compiledName); + + delete this.sources; + delete this.results; + return compiled; + } + + getSourceFile(fileName, languageVersion, _onError) { + const sourceText = this.readFile(fileName); + return sourceText !== undefined + ? ts.createSourceFile(fileName, sourceText, languageVersion) + : undefined; + } + + readFile(fileName) { + return this.sources.get(fileName); + } + + writeFile(fileName, content) { + this.results.set(fileName, content); + } + + knownDirectories() { + return []; + // return ["croquet", "default"]; + } + + createCompilerHost() { + return { + getSourceFile: this.getSourceFile, + getDefaultLibFileName: (defaultLibOptions) => "/" + ts.getDefaultLibFileName(defaultLibOptions), + writeFile: (fileName, content) => this.writeFile(fileName, content), + getCurrentDirectory: () => "/", + getDirectories: (_path) => [], + fileExists: () => true, + readFile: (fileName) => this.readFile(fileName), + getCanonicalFileName: (fileName) => fileName, + useCaseSensitiveFileNames: () => true, + getNewLine: () => "\n", + getEnvironmentVariable: () => "", // do nothing + resolveModuleNames: () => [], + }; + } +} + +class JSCompiler { + compile(jsCode, _location) { + console.log(_location); + let result = []; + + let codeArray = jsCode.split("\n"); + + for (let i = 0; i < codeArray.length; i++) { + let line = codeArray[i]; + if (/^import/.test(line)) { + result.push(""); + continue; + } + let test = /^class(\s+)(\S+)\s+extends\s(ActorBehavior|PawnBehavior)(.*)\r?$/.exec(line) + if (test) { + let newLine = `class${test[1]}${test[2]}${test[4]}`; + result.push(newLine); + continue; + } + result.push(line); + } + return result.join("\n"); + } +} + +/* globals ts*/ /***/ }), @@ -16470,7 +16494,8 @@ console.log(`DolbyChatManager (local actor ${alreadyHere ? "already" : "not yet" `; chatHolder = div.firstChild; - document.body.appendChild(chatHolder); + let microverse = document.body.querySelector("#microverse"); + (microverse || document.body).appendChild(chatHolder); ['toggleConnection', 'toggleAudio', 'toggleSettings', 'toggleMicrophoneTest'].forEach(buttonName => { const elem = document.getElementById(buttonName); @@ -16966,6 +16991,7 @@ console.log(`DolbyChatManager (local actor ${alreadyHere ? "already" : "not yet" async muteChatAudio() { console.log("muting local audio"); await this.ensureAudioMuteState(true); + this.audioLevelChanged(0); } async unmuteChatAudio() { @@ -16989,9 +17015,17 @@ console.log("unmuting local audio"); this._testAudioLevelIntervalId = window.setInterval(this.testAudioLevel.bind(this), this._testAudioInterval); } + audioLevelChanged(level) { + this.publish(this.localPlayer.id, "voiceLevelChanged", level); + } + testAudioLevel() { const audioLevel = this.getLocalAudioLevel(); + if (!chatAudioMuted) { + this.audioLevelChanged(audioLevel); + } + // no need to display audio level if the meter isn't on view. if (this.elements.chatHolder.classList.contains('hide-settings') || !this.measurableAudioStreamSource) return; @@ -17349,7 +17383,8 @@ function createHelpMenu() { }); } - document.body.appendChild(helpMenu); + let microverse = document.body.querySelector("#microverse"); + (microverse || document.body).appendChild(helpMenu); } @@ -17388,9 +17423,9 @@ const fullScreenHTML = ` `.trim(); -const container = ` -
-
+const hudContainer = ` +
+
@@ -17406,15 +17441,18 @@ const container = ` `.trim(); const microverseHTML = ` +
-${container} +${hudContainer} +
`.trim(); const innerHTML = ` +
-${container} +${hudContainer} ${joystickHTML} -
`.trim(); +
`.trim(); let avatar; let joystick; @@ -17575,9 +17613,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _settingsMenu_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./settingsMenu.js */ "./src/settingsMenu.js"); /* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! jszip */ "./node_modules/jszip/dist/jszip.min.js"); /* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(jszip__WEBPACK_IMPORTED_MODULE_13__); -/* harmony import */ var fflate__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! fflate */ "./node_modules/fflate/esm/browser.js"); +/* harmony import */ var fflate__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! fflate */ "./node_modules/fflate/esm/browser.js"); /* harmony import */ var _wcAssetManager_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./wcAssetManager.js */ "./src/wcAssetManager.js"); -/* harmony import */ var _hud_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./hud.js */ "./src/hud.js"); // Copyright 2022 by Croquet Corporation, Inc. All Rights Reserved. // https://croquet.io // info@croquet.io @@ -17603,15 +17640,13 @@ __webpack_require__.r(__webpack_exports__); - - const defaultAvatarNames = [ "newwhite", "madhatter", "marchhare", "queenofhearts", "cheshirecat", "alice" ]; const defaultSystemBehaviorDirectory = "behaviors/croquet"; const defaultSystemBehaviorModules = [ - "avatarEvents.js", "billboard.js", "elected.js", "menu.js", "pdfview.js", "physics.js", "rapier.js", "scrollableArea.js", "singleUser.js", "stickyNote.js", "halfBodyAvatar.js", "fullBodyAvatar.js", "propertySheet.js", "dragAndDrop.js", "gizmo.js", "video.js" + "avatarEvents.js", "billboard.js", "elected.js", "menu.js", "pdfview.js", "physics.js", "rapier.js", "scrollableArea.js", "singleUser.js", "stickyNote.js", "halfBodyAvatar.js", "fullBodyAvatar.js", "propertySheet.js", "dragAndDrop.js", "gizmo.js", "video.js", "avatarVoiceLevel.js" ]; let AA = true; @@ -17718,7 +17753,7 @@ async function getDisplayOptions() { function loadLoaders() { window.JSZip = (jszip__WEBPACK_IMPORTED_MODULE_13___default()); - window.fflate = fflate__WEBPACK_IMPORTED_MODULE_16__; + window.fflate = fflate__WEBPACK_IMPORTED_MODULE_15__; window.THREE = _ThreeRender_js__WEBPACK_IMPORTED_MODULE_1__.THREE; return Promise.resolve(_ThreeRender_js__WEBPACK_IMPORTED_MODULE_1__.THREE); } @@ -17757,29 +17792,28 @@ function loadInitialBehaviors(paths, directory) { let promises = paths.map((path) => { if (!isSystem) { - let code = `import('${root}${directory}/${path}')`; - return eval(code).then((module) => { - let rest = directory.slice("behaviors".length); - if (rest[0] === "/") {rest = rest.slice(1);} - return [`${rest === "" ? "" : (rest + "/")}${path}`, module]; - }) + let match = /\/?behaviors\/(.*)/.exec(directory); + let dir = match ? match[1] : directory; + return fetch(`${root}${directory}/${path}`) + .then((res) => res.text()) + .then((text) => (0,_code_js__WEBPACK_IMPORTED_MODULE_9__.compileToModule)(text, `${dir}/${path}`)); } else { let modulePath = `${directory.split("/")[1]}/${path}`; - let code = `import('${root}behaviors/${modulePath}')`; - return eval(code).then((module) => { - return [modulePath, module]; - }) + return fetch(`${root}behaviors/${modulePath}`) + .then((res) => res.text()) + .then((text) => (0,_code_js__WEBPACK_IMPORTED_MODULE_9__.compileToModule)(text, modulePath)); } }); return Promise.all(promises).then((array) => { - array.forEach((pair) => { - let [path, module] = pair; - let dot = path.lastIndexOf("."); - let fileName = path.slice(0, dot); + array.forEach((obj) => { + let {name, data} = obj; + let dot = name.lastIndexOf("."); + let fileName = name.slice(0, dot); + let language = name.slice(dot + 1); - (0,_code_js__WEBPACK_IMPORTED_MODULE_9__.checkModule)(module); // may throw an error - library.add(module.default, fileName, isSystem); + (0,_code_js__WEBPACK_IMPORTED_MODULE_9__.checkModule)(data); // may throw an error + library.add(data.default, fileName, isSystem, language); }); return true; }); @@ -18578,16 +18612,6 @@ const shellListener = (command, data) => { (0,_frame_js__WEBPACK_IMPORTED_MODULE_8__.addShellListener)(shellListener); function startMicroverse() { - /* - let hud = document.querySelector("#hud"); - if (!hud) { - let div = document.createElement("div"); - div.innerHTML = innerHTML || microverseHTML; - hud = div.querySelector("#hud"); - document.body.appendChild(hud); - } - */ - let setButtons = (display) => { ["homeBtn", "worldMenuBtn"].forEach((n) => { let btn = document.querySelector("#" + n); @@ -19611,6 +19635,7 @@ function avatarSelected(entry) { avatarIsValid = false; let holder = settingsMenu.querySelector("#avatarList"); + let avatarURLField = settingsMenu.querySelector('#avatarURLField'); for (let i = 0; i < holder.childNodes.length; i++) { let child = holder.childNodes[i]; if (child.getAttribute("avatarURL") === value) { @@ -19723,7 +19748,8 @@ function createShareMenu(avatar) { saveVrseRow.style.display = "none"; } - document.body.appendChild(shareDialog); + let microverse = document.body.querySelector("#microverse"); + (microverse || document.body).appendChild(shareDialog); } function savePressed(myAvatar) { @@ -20240,7 +20266,9 @@ class KeyFocusManager extends _worldcore__WEBPACK_IMPORTED_MODULE_0__.ViewServic this.hiddenInput.style.setProperty("width", "100px"); this.hiddenInput.style.setProperty("height", "100px"); - document.body.appendChild(this.hiddenInput); + + let microverse = document.body.querySelector("#microverse"); + (microverse || document.body).appendChild(this.hiddenInput); this.hiddenInput.addEventListener("input", evt => { evt.stopPropagation(); @@ -20276,7 +20304,8 @@ class KeyFocusManager extends _worldcore__WEBPACK_IMPORTED_MODULE_0__.ViewServic this.copyElement.style.setProperty("width", "100px"); this.copyElement.style.setProperty("height", "100px"); - document.body.appendChild(this.copyElement); + let microverse = document.body.querySelector("#microverse"); + (microverse || document.body).appendChild(this.copyElement); } } @@ -23518,6 +23547,8 @@ function qrPressed(_myAvatar, url) { } function loadPressed(myAvatar) { + let handler = myAvatar?.actor.behaviorManager.lookup("FileDragAndDropHandler", "FileDragAndDropActor"); + if (!handler) {return;} if (!imageInput) { let input = document.createElement("div"); input.innerHTML = ``; @@ -24457,31 +24488,13 @@ const TRIPLE_DURATION = 600; // milliseconds const TAP_DURATION = 300; // milliseconds const TAP_DISTANCE = 10; // pixels -const SWIPE_DURATION = 300; // milliseconds -const SWIPE_DISTANCE = 50; // pixels - const keys = new Set(); -const chordNames = new Map(); -const upChordKeys = new Map(); -const downChordKeys = new Map(); // Returns true if the key is pressed. Includes entries for mouse buttons. function KeyDown(key) { return keys.has(key); } -//Returns true if the combination of keys is pressed/unpressed. -// export function ChordDown(name) { -// const chord = chordNames.get(name); -// if (!chord) return false; -// const down = chord.down; -// const up = chord.up; -// let all = true; -// down.forEach(d => {all &= KeyDown(d);}); -// up.forEach(u => {all &= !KeyDown(u);}); -// return all; -// } - //---------------------------------------------------------------------------------------------------- // Input // @@ -24500,16 +24513,51 @@ class InputManager extends _Root__WEBPACK_IMPORTED_MODULE_1__.ViewService { this.lastDown = {}; this.penultimateDown = {}; - document.body.style.touchAction = "none"; + this.synthesizedModifierKeys = new Map(); + this.subscribe("_input", "setMicroverseDiv", this.setMicroverseDiv); + } + + setMicroverseDiv({divQuery, canvasQuery}) { + this.microverseDiv = document.body.querySelector(divQuery); + this.canvas = document.body.querySelector(canvasQuery); + + let handleChange = (entries) => { + for (const entry of entries) { + let rect = entry.contentRect; + if (rect.width && rect.height) { + this.scheduleResize({width: rect.width, height: rect.height}); + } + } + }; + this.observer = new ResizeObserver(handleChange); + this.observer.observe(this.microverseDiv); this.addAllListeners(); + } - this.synthesizedModifierKeys = new Map(); + scheduleResize(obj) { + this.resizeObj = obj; + if (!this.resizeTimeout) { + this.publishResize(); + } + } + + publishResize() { + if (this.resizeObj) { + let obj = this.resizeObj + delete this.resizeObj; + this.publish("_input", "resize", obj); + this.resizeTimeout = setTimeout(() => { + this.publishResize(); + delete this.resizeTimeout; + }, 500); + } } destroy() { super.destroy(); if (this.inPointerLock) document.exitPointerLock(); if (this.inFullscreen) document.exitFullscreen(); + if (this.observer) {this.observer.disconnect();} this.removeAllListeners(); } @@ -24533,104 +24581,19 @@ class InputManager extends _Root__WEBPACK_IMPORTED_MODULE_1__.ViewService { // adds all the default input manager listeners addAllListeners() { - this.addListener(document, 'contextmenu', e => e.preventDefault()); - this.addListener(window, 'resize', e => this.onResize(e)); + this.addListener(this.canvas, 'contextmenu', e => e.preventDefault()); this.addListener(window, 'focus', e => this.onFocus(e)); this.addListener(window, 'blur', e => this.onBlur(e)); this.addListener(window, 'deviceorientation', e => this.onOrientation(e)); - this.addListener(document, 'click', e => this.onClick(e)); + this.addListener(this.canvas, 'click', e => this.onClick(e)); this.addListener(document, 'pointerlockchange', e => this.onPointerLock(e)); - this.addListener(document, 'pointerdown', e => this.onPointerDown(e)); - this.addListener(document, 'pointerup', e => this.onPointerUp(e)); - this.addListener(document, 'pointercancel', e => this.onPointerUp(e)); - this.addListener(document, 'pointermove', e => this.onPointerMove(e)); - this.addListener(document, 'wheel', e => this.onWheel(e)); - this.addListener(document,'keydown', e => this.onKeyDown(e)); - this.addListener(document,'keyup', e => this.onKeyUp(e)); - } - - // If you want the input handler to report a chord event, you need to add the chord and give it an event name. - addChord(name, down = [], up = []) { - chordNames.set(name, {down, up}); - down.forEach(d => { - if (!downChordKeys.has(d)) downChordKeys.set(d, new Set()); - downChordKeys.get(d).add(name); - }); - up.forEach(u => { - if (!upChordKeys.has(u)) upChordKeys.set(u, new Set()); - upChordKeys.get(u).add(name); - }); - } - - onChordDown(key) { - const downs = []; - const ups = []; - - if (downChordKeys.has(key)) { - downChordKeys.get(key).forEach( name => { - if (this.chordTest(name)) downs.push(name); - }); - } - - if (upChordKeys.has(key)) { - upChordKeys.get(key).forEach( name => { - if (!this.chordTest(name)) ups.push(name); - }); - } - - ups.forEach(name => { - if (!KeyDown(name)) return; - keys.delete(name); - this.publish("input", name + "Up"); - }); - - downs.forEach(name => { - if (KeyDown(name)) return; - keys.add(name); - this.publish("input", name + "Down"); - }); - - } - - onChordUp(key) { - const downs = []; - const ups = []; - - if (downChordKeys.has(key)) { - downChordKeys.get(key).forEach( name => { - if (!this.chordTest(name)) ups.push(name); - }); - } - - if (upChordKeys.has(key)) { - upChordKeys.get(key).forEach( name => { - if (this.chordTest(name)) downs.push(name); - }); - } - - ups.forEach(name => { - if (!KeyDown(name)) return; - keys.delete(name); - this.publish("input", name + "Up"); - }); - - downs.forEach(name => { - if (KeyDown(name)) return; - keys.add(name); - this.publish("input", name + "Down"); - }); - - } - - chordTest(name) { - const chord = chordNames.get(name); - if (!chord) return false; - const down = chord.down; - const up = chord.up; - let all = true; - down.forEach(d => {all &= KeyDown(d);}); - up.forEach(u => {all &= !KeyDown(u);}); - return all; + this.addListener(this.canvas, 'pointerdown', e => this.onPointerDown(e)); + this.addListener(this.canvas, 'pointerup', e => this.onPointerUp(e)); + this.addListener(this.canvas, 'pointercancel', e => this.onPointerUp(e)); + this.addListener(this.canvas, 'pointermove', e => this.onPointerMove(e)); + this.addListener(this.canvas, 'wheel', e => this.onWheel(e)); + this.addListener(window, 'keydown', e => this.onKeyDown(e)); + this.addListener(window, 'keyup', e => this.onKeyUp(e)); } get inFullscreen() { @@ -24691,27 +24654,27 @@ class InputManager extends _Root__WEBPACK_IMPORTED_MODULE_1__.ViewService { document.exitPointerLock(); } - onPointerLock(event) { - this.publish("input", "pointerLock", this.inPointerLock); + onPointerLock(_event) { + this.publish("_input", "pointerLock", this.inPointerLock); } - onResize(event) { + onResize(_event) { // Delay actual resize event to address iOS posting of resize before page layout finishes. // (Also it kind of looks better .... ) - this.publish("input", "beforeResize"); + this.publish("_input", "beforeResize"); this.future(500).futureResize(); } futureResize() { - this.publish("input", "resize", [window.innerWidth, window.innerHeight]); + this.publish("_input", "resize", [window.innerWidth / 2, window.innerHeight]); } - onFocus(event) { - this.publish("input", "focus"); + onFocus(_event) { + this.publish("_input", "focus"); } - onBlur(event) { - this.publish("input", "blur"); + onBlur(_event) { + this.publish("_input", "blur"); } // publishes both keyDown + arg and "xDown" where "x" is the key @@ -24721,13 +24684,10 @@ class InputManager extends _Root__WEBPACK_IMPORTED_MODULE_1__.ViewService { let modKeys = this.modifierKeysFrom(event); keys.add(key); if (event.repeat) { - this.publish("input", key + "Repeat", {key, shift: modKeys.shiftKey, alt: modKeys.altKey, ctrl: modKeys.ctrlKey, meta: modKeys.metaKey, ...modKeys}); - this.publish("input", "keyRepeat", {key, shift: modKeys.shiftKey, alt: modKeys.altKey, ctrl: modKeys.ctrlKey, meta: modKeys.metaKey, ...modKeys}); + this.publish("_input", "keyRepeat", {key, ...modKeys}); // This can generate a lot of events! Don't subscribe to in model. } else { - this.publish("input", key + "Down", {key, shift: modKeys.shiftKey, alt: modKeys.altKey, ctrl: modKeys.ctrlKey, meta: modKeys.metaKey, ...modKeys}); - this.publish("input", "keyDown", {key, shift: modKeys.shiftKey, alt: modKeys.altKey, ctrl: modKeys.ctrlKey, meta: modKeys.metaKey, ...modKeys}); - this.onChordDown(key); + this.publish("_input", "keyDown", {key, ...modKeys}); } } @@ -24736,141 +24696,157 @@ class InputManager extends _Root__WEBPACK_IMPORTED_MODULE_1__.ViewService { const key = event.key; let modKeys = this.modifierKeysFrom(event); if (!KeyDown(key)) return; - this.publish("input", key + "Up", {key, shift: modKeys.shiftKey, alt: modKeys.altKey, ctrl: modKeys.ctrlKey, meta: modKeys.metaKey, ...modKeys}); - this.publish("input", "keyUp", {key, shift: modKeys.shiftKey, alt: modKeys.altKey, ctrl: modKeys.ctrlKey, meta: modKeys.metaKey, modKeys}); + this.publish("_input", "keyUp", {key, ...modKeys}); keys.delete(key); - this.onChordUp(key); } onClick(event) { let modKeys = this.modifierKeysFrom(event); window.focus(); - this.publish("input", "click", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, ...modKeys, xy: [event.clientX, event.clientY]}); + this.publish("_input", "click", { + pointerId: event.pointerId, pointerType: event.pointerType, + button: event.button, buttons: event.buttons, ...modKeys, + xy: [event.offsetX, event.offsetY]}); } onPointerDown(event) { let modKeys = this.modifierKeysFrom(event); - this.presses.set(event.pointerId, {id: event.pointerId, time: event.timeStamp, start: [event.clientX, event.clientY], ...modKeys, xy: [event.clientX, event.clientY]}); - this.publish("input", "pointerDown", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, ...modKeys, xy: [event.clientX, event.clientY]}); - if (event.button === this.lastDown.button && event.timeStamp - this.lastDown.time < DOUBLE_DURATION && this.modifierEqual(event, this.lastDown)) { - if (event.button === this.penultimateDown.button && event.timeStamp - this.penultimateDown.time < TRIPLE_DURATION) { - this.publish("input", "tripleDown", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, ...modKeys, xy: [event.clientX, event.clientY]}); + let pressure = this.getPressure(event); + this.presses.set(event.pointerId, { + pointerId: event.pointerId, time: event.timeStamp, + start: [event.offsetX, event.offsetY], ...modKeys, + xy: [event.offsetX, event.offsetY] + }); + this.publish("_input", "pointerDown", { + pointerId: event.pointerId, pointerType: event.pointerType, + button: event.button, buttons: event.buttons, ...modKeys, + xy: [event.offsetX, event.offsetY], pressure + }); + if (event.pointerId === this.lastDown.pointerId && + event.button === this.lastDown.button && + event.timeStamp - this.lastDown.time < DOUBLE_DURATION && + this.modifierEqual(event, this.lastDown)) { + if (event.pointerId === this.penultimateDown.pointerId && + event.button === this.penultimateDown.button && + event.timeStamp - this.penultimateDown.time < TRIPLE_DURATION) { + this.publish("_input", "tripleDown", { + pointerId: event.pointerId, pointerType: event.pointerType, + button: event.button, buttons: event.buttons, ...modKeys, + xy: [event.offsetX, event.offsetY], pressure + }); } else { - this.publish("input", "doubleDown", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, ...modKeys, xy: [event.clientX, event.clientY]}); + this.publish("_input", "doubleDown", { + pointerId: event.pointerId, pointerType: event.pointerType, + button: event.button, buttons: event.buttons, ...modKeys, + xy: [event.offsetX, event.offsetY], pressure + }); } } this.penultimateDown = this.lastDown; - this.lastDown = {id: event.pointerId, button: event.button, buttons: event.buttons, ...modKeys, time: event.timeStamp}; - this.zoomStart(); + this.lastDown = { + pointerId: event.pointerId, button: event.button, buttons: event.buttons, + ...modKeys, time: event.timeStamp + }; } onPointerUp(event) { const press = this.presses.get(event.pointerId); + let pressure = this.getPressure(event); let modKeys = this.modifierKeysFrom(event); if (press) { - press.xy = [event.clientX, event.clientY]; + press.xy = [event.offsetX, event.offsetY]; const duration = event.timeStamp - press.time; - const dx = event.clientX - press.start[0]; - const dy = event.clientY - press.start[1]; + const dx = event.offsetX - press.start[0]; + const dy = event.offsetY - press.start[1]; const ax = Math.abs(dx); const ay = Math.abs(dy); if (duration < TAP_DURATION && ax < TAP_DISTANCE && ay < TAP_DISTANCE) { - this.publish("input", "tap", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, ...modKeys, xy: [event.clientX, event.clientY]}); - } - if (duration < SWIPE_DURATION && ax > SWIPE_DISTANCE) { - this.publish("input", "swipeX", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, distance: dx, ...modKeys}); - } - if (duration < SWIPE_DURATION && ay > SWIPE_DISTANCE) { - this.publish("input", "swipeY", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, distance: dy, ...modKeys}); + this.publish("_input", "tap", { + pointerId: event.pointerId, pointerType: event.pointerType, + button: event.button, buttons: event.buttons, ...modKeys, + xy: [event.offsetX, event.offsetY], pressure + }); } } this.presses.delete(event.pointerId); - this.publish("input", "pointerUp", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, ...modKeys, xy: [event.clientX, event.clientY]}); - this.zoomEnd(); + this.publish("_input", "pointerUp", { + pointerIdd: event.pointerId, pointerType: event.pointerType, + button: event.button, buttons: event.buttons, ...modKeys, + xy: [event.offsetX, event.offsetY], pressure + }); } onPointerMove(event) { const press = this.presses.get(event.pointerId); + let pressure = this.getPressure(event); let modKeys = this.modifierKeysFrom(event); if (press) { - press.xy = [event.clientX, event.clientY]; + press.xy = [event.offsetX, event.offsetY]; const duration = event.timeStamp - press.time; - const dx = event.clientX - press.start[0]; - const dy = event.clientY - press.start[1]; + const dx = event.offsetX - press.start[0]; + const dy = event.offsetY - press.start[1]; const ax = Math.abs(dx); const ay = Math.abs(dy); if (duration > TAP_DURATION || ax > TAP_DISTANCE || ay > TAP_DISTANCE) { // Only publish pressed move events that aren't taps - this.publish("input", "pointerMove", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, ...modKeys, xy: [event.clientX, event.clientY]}); - this.publish("input", "pointerDelta", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, ...modKeys, xy: [event.movementX, event.movementY]}); + this.publish("_input", "pointerMove", { + pointerId: event.pointerId, pointerType: event.pointerType, + button: event.button, buttons: event.buttons, ...modKeys, + xy: [event.offsetX, event.offsetY], pressure + }); + this.publish("_input", "pointerDelta", { + pointerId: event.pointerId, pointerType: event.pointerType, + button: event.button, buttons: event.buttons, ...modKeys, + xy: [event.movementX, event.movementY], pressure + }); } } else { - this.publish("input", "pointerMove", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, ...modKeys, xy: [event.clientX, event.clientY]}); - this.publish("input", "pointerDelta", {id: event.pointerId, type: event.pointerType, button: event.button, buttons: event.buttons, ...modKeys, xy: [event.movementX, event.movementY]}); + this.publish("_input", "pointerMove", { + pointerId: event.pointerId, pointerType: event.pointerType, + button: event.button, buttons: event.buttons, ...modKeys, + xy: [event.offsetX, event.offsetY] + }); + this.publish("_input", "pointerDelta", { + pointerId: event.pointerId, type: event.pointerType, + button: event.button, buttons: event.buttons, ...modKeys, + xy: [event.movementX, event.movementY] + }); } - this.zoomUpdate(); - } - - zoomStart() { - if (this.presses.size !== 2) return; - - const values = Array.from(this.presses.values()); - const press0 = values[0]; - const press1 = values[1]; - const mid = (0,_Vector__WEBPACK_IMPORTED_MODULE_0__.v2_scale)((0,_Vector__WEBPACK_IMPORTED_MODULE_0__.v2_add)(press0.xy, press1.xy), 0.5); - - this.publish("input", "zoomStart", {mid, zoom: 1, dial: 0}); - } - - zoomEnd() { - if (this.presses.size !== 1) return; - this.publish("input", "zoomEnd"); - } - - zoomUpdate() { - if (this.presses.size < 2) return; - - const values = Array.from(this.presses.values()); - const press0 = values[0]; - const press1 = values[1]; - const mid = (0,_Vector__WEBPACK_IMPORTED_MODULE_0__.v2_scale)((0,_Vector__WEBPACK_IMPORTED_MODULE_0__.v2_add)(press0.xy, press1.xy), 0.5); - - const delta0 = (0,_Vector__WEBPACK_IMPORTED_MODULE_0__.v2_sub)(press1.start, press0.start); - const delta1 = (0,_Vector__WEBPACK_IMPORTED_MODULE_0__.v2_sub)(press1.xy, press0.xy); - const gap0 = (0,_Vector__WEBPACK_IMPORTED_MODULE_0__.v2_magnitude)(delta0); - const gap1 = (0,_Vector__WEBPACK_IMPORTED_MODULE_0__.v2_magnitude)(delta1); - - let zoom = 1; - if (gap0 > 0) zoom = gap1 / gap0; - - const angle0 = Math.atan2(delta0[0], delta0[1]); - const angle1 = Math.atan2(delta1[0], delta1[1]); - let dial = (angle1 - angle0 + _Vector__WEBPACK_IMPORTED_MODULE_0__.TAU) % _Vector__WEBPACK_IMPORTED_MODULE_0__.TAU; - if (dial > Math.PI) dial -= _Vector__WEBPACK_IMPORTED_MODULE_0__.TAU; - - this.publish("input", "zoomUpdate", {mid, zoom, dial}); } onWheel(event) { let modKeys = this.modifierKeysFrom(event); event.preventDefault(); const y = event.deltaY; - this.publish("input", "wheel", {deltaY: y, ...modKeys, xy: [event.clientX, event.clientY]}); + this.publish("_input", "wheel", { + deltaY: y, ...modKeys, xy: [event.offsetX, event.offsetY] + }); } onOrientation(event) { const alpha = event.alpha; // yaw const beta = event.beta; // Pitch if in portrait, - const gamma = event.gamma; + // const gamma = event.gamma; const pitch = (0,_Vector__WEBPACK_IMPORTED_MODULE_0__.toRad)(beta); const yaw = (0,_Vector__WEBPACK_IMPORTED_MODULE_0__.toRad)(alpha); // For landscape mode depends on phone orientation ... // const pitch = gamma; // const yaw = alpha; // 90 off - this.publish("input", "orientation", {pitch, yaw}); + this.publish("_input", "orientation", {pitch, yaw}); } + getPressure(evt) { + if (evt.pressure !== undefined) { + return evt.pressure; + } else if (evt.touchType === "stylus") { + return evt.force / Math.sin(evt.altitudeAngle); + } else if (evt.force !== undefined) { + return evt.force; + } else { + return 1; + } + } } @@ -25119,9 +25095,14 @@ const AM_Smoothed = superclass => class extends AM_Spatial(superclass) { this.say("translateTo", v); } - positionTo(data) { - this._translation = data.v; - this._rotation = data.q; + positionTo(data, data1) { + if (Array.isArray(data1)) { + this._translation = data; + this._rotation = data1; + } else { + this._translation = data.v; + this._rotation = data.q; + } this.$local = null; this.$global = null; this.say("rotateTo", data.q); @@ -117024,4 +117005,4 @@ start(); })(); /******/ })() -; \ No newline at end of file +; diff --git a/meta/version.txt b/meta/version.txt index b6b7ee9..7f53a2f 100644 --- a/meta/version.txt +++ b/meta/version.txt @@ -1 +1 @@ -commit: 394128068f54edf93bebed83eb02821822ca8c87 Date: Fri Aug 4 10:25:46 2023 -0700 +commit: 9e5d9a864611fc44571357e957a1dc3e58fc25fb Date: Tue Aug 29 16:59:08 2023 -0700 diff --git a/package-lock.json b/package-lock.json index 375a89c..7513719 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,11 @@ "name": "croquet-microverse-gallery-world", "version": "1.0.0", "dependencies": { - "@croquet/microverse-library": "^0.6.1" + "@croquet/microverse-library": "^0.7.5" }, "devDependencies": { "@croquet/microverse-file-server": "^1.0.7", - "@croquet/microverse-watch-server": "^1.0.6", + "@croquet/microverse-watch-server": "^1.0.7", "npm-run-all": "^4.1.5" } }, @@ -26,19 +26,19 @@ } }, "node_modules/@croquet/microverse-library": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@croquet/microverse-library/-/microverse-library-0.6.1.tgz", - "integrity": "sha512-3zOEhKIfq2++JSa94EvNcyGdlpE4TncAy/bJyts2EZHFtfTkBq2q/1AJZdX9ms/uWEgFFz9AwLH29mBslHamwA==", + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@croquet/microverse-library/-/microverse-library-0.7.5.tgz", + "integrity": "sha512-6G/ahD1ri2QtW9E+g5xRJDN1WIqBmKpy1XAuoXoE9CFnF3ysdBqVwroWh4sTtfNVe7YhY1LbN4pw7OsVSztn5A==", "hasInstallScript": true }, "node_modules/@croquet/microverse-watch-server": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@croquet/microverse-watch-server/-/microverse-watch-server-1.0.6.tgz", - "integrity": "sha512-kYVzaHm//Dx9YvEy2wKqPF0qel01EjRfdHIhlxGIvT0FU171fCJTfS4w1yJBIU3RPUcdvSiTEBgz9xcg477/Ag==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@croquet/microverse-watch-server/-/microverse-watch-server-1.0.7.tgz", + "integrity": "sha512-8OUJEv75Z08GECHx/+IFVHplpVO82sbRA19BV/TNs0010duGCisUPnvSjbFn/t+zAqhtMdA6f3Tf5bzDuH1kqw==", "dev": true, "dependencies": { - "chokidar": "^3.5.3", - "ws": "^8.5.0" + "chokidar": "3.5.3", + "ws": "8.13.0" }, "bin": { "watch-server": "watch-server.js" @@ -82,6 +82,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", + "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -248,18 +268,19 @@ } }, "node_modules/es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", + "get-intrinsic": "^1.2.1", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", @@ -279,14 +300,18 @@ "object-inspect": "^1.12.3", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", "safe-regex-test": "^1.0.0", "string.prototype.trim": "^1.2.7", "string.prototype.trimend": "^1.0.6", "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" + "which-typed-array": "^1.1.10" }, "engines": { "node": ">= 0.4" @@ -357,9 +382,9 @@ } }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -377,15 +402,15 @@ "dev": true }, "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -653,9 +678,9 @@ } }, "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -795,16 +820,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.11" }, "engines": { "node": ">= 0.4" @@ -825,6 +846,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1078,12 +1105,12 @@ } }, "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", "dev": true, "dependencies": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -1094,6 +1121,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-array-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", + "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -1300,6 +1345,57 @@ "node": ">=8.0" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", @@ -1368,17 +1464,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.10.tgz", - "integrity": "sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" diff --git a/package.json b/package.json index e79ac48..9a6d4f1 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,11 @@ "watch-server": "watch-server" }, "dependencies": { - "@croquet/microverse-library": "^0.6.1" + "@croquet/microverse-library": "^0.7.5" }, "devDependencies": { "@croquet/microverse-file-server": "^1.0.7", - "@croquet/microverse-watch-server": "^1.0.6", + "@croquet/microverse-watch-server": "^1.0.7", "npm-run-all": "^4.1.5" } } diff --git a/prelude.js b/prelude.js index 5c1b9d4..9bbc1fe 100644 --- a/prelude.js +++ b/prelude.js @@ -44,9 +44,13 @@ export async function prelude() { let css = document.createElement("link"); css.rel = "stylesheet"; css.type = "text/css"; + css. css.id = "joystick-css"; css.onload = resolve; - }) + css.href = "/assets/css/joystick.css"; + document.head.appendChild(css); + }); + */ /* @@ -56,5 +60,13 @@ export async function prelude() { Promise like the one above. */ + await new Promise((resolve, reject) => { + let script = document.createElement("script"); + script.src = "https://cdn.jsdelivr.net/npm/typescript@5.1.6/lib/typescript.min.js"; + script.onload = resolve; + script.type = "text/javascript"; + document.head.appendChild(script); + }); + return null; } diff --git a/worlds/default.js b/worlds/default.js index c1116e8..3516a08 100644 --- a/worlds/default.js +++ b/worlds/default.js @@ -9,7 +9,7 @@ export function init(Constants) { Constants.UserBehaviorDirectory = "behaviors/default"; Constants.UserBehaviorModules = [ - "demo.js", "lights.js", "bouncingBall.js", "bitcoinTracker.js", "spin.js", "replaceWorld.js", "openPortal.js", "urlLink.js", "text3D.js", "pool.js", "video.js" + "demo.js", "lights.js", "bouncingBall.js", "bitcoinTracker.ts", "spin.js", "replaceWorld.js", "openPortal.js", "urlLink.js", "text3D.js", "pool.js", "video.js" ]; Constants.ExcludedSystemBehaviorModules = ["gizmo.js"];