73686 lines
2.7 MiB
Plaintext
73686 lines
2.7 MiB
Plaintext
"use strict";
|
|
'use strict';
|
|
(function(global, factory) {
|
|
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = global || self,
|
|
factory(global.glMatrix = {}))
|
|
}
|
|
)(this, function(exports) {
|
|
var EPSILON = 1E-6;
|
|
var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array;
|
|
var RANDOM = Math.random;
|
|
function setMatrixArrayType(type) {
|
|
ARRAY_TYPE = type
|
|
}
|
|
var degree = Math.PI / 180;
|
|
function toRadian(a) {
|
|
return a * degree
|
|
}
|
|
function equals(a, b) {
|
|
return Math.abs(a - b) <= EPSILON * Math.max(1, Math.abs(a), Math.abs(b))
|
|
}
|
|
if (!Math.hypot)
|
|
Math.hypot = function() {
|
|
var y = 0
|
|
, i = arguments.length;
|
|
while (i--)
|
|
y += arguments[i] * arguments[i];
|
|
return Math.sqrt(y)
|
|
}
|
|
;
|
|
var common = Object.freeze({
|
|
__proto__: null,
|
|
EPSILON: EPSILON,
|
|
get ARRAY_TYPE() {
|
|
return ARRAY_TYPE
|
|
},
|
|
RANDOM: RANDOM,
|
|
setMatrixArrayType: setMatrixArrayType,
|
|
toRadian: toRadian,
|
|
equals: equals
|
|
});
|
|
function create() {
|
|
var out = new ARRAY_TYPE(4);
|
|
if (ARRAY_TYPE != Float32Array) {
|
|
out[1] = 0;
|
|
out[2] = 0
|
|
}
|
|
out[0] = 1;
|
|
out[3] = 1;
|
|
return out
|
|
}
|
|
function clone(a) {
|
|
var out = new ARRAY_TYPE(4);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
return out
|
|
}
|
|
function copy(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
return out
|
|
}
|
|
function identity(out) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
return out
|
|
}
|
|
function fromValues(m00, m01, m10, m11) {
|
|
var out = new ARRAY_TYPE(4);
|
|
out[0] = m00;
|
|
out[1] = m01;
|
|
out[2] = m10;
|
|
out[3] = m11;
|
|
return out
|
|
}
|
|
function set(out, m00, m01, m10, m11) {
|
|
out[0] = m00;
|
|
out[1] = m01;
|
|
out[2] = m10;
|
|
out[3] = m11;
|
|
return out
|
|
}
|
|
function transpose(out, a) {
|
|
if (out === a) {
|
|
var a1 = a[1];
|
|
out[1] = a[2];
|
|
out[2] = a1
|
|
} else {
|
|
out[0] = a[0];
|
|
out[1] = a[2];
|
|
out[2] = a[1];
|
|
out[3] = a[3]
|
|
}
|
|
return out
|
|
}
|
|
function invert(out, a) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3];
|
|
var det = a0 * a3 - a2 * a1;
|
|
if (!det)
|
|
return null;
|
|
det = 1 / det;
|
|
out[0] = a3 * det;
|
|
out[1] = -a1 * det;
|
|
out[2] = -a2 * det;
|
|
out[3] = a0 * det;
|
|
return out
|
|
}
|
|
function adjoint(out, a) {
|
|
var a0 = a[0];
|
|
out[0] = a[3];
|
|
out[1] = -a[1];
|
|
out[2] = -a[2];
|
|
out[3] = a0;
|
|
return out
|
|
}
|
|
function determinant(a) {
|
|
return a[0] * a[3] - a[2] * a[1]
|
|
}
|
|
function multiply(out, a, b) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3];
|
|
var b0 = b[0]
|
|
, b1 = b[1]
|
|
, b2 = b[2]
|
|
, b3 = b[3];
|
|
out[0] = a0 * b0 + a2 * b1;
|
|
out[1] = a1 * b0 + a3 * b1;
|
|
out[2] = a0 * b2 + a2 * b3;
|
|
out[3] = a1 * b2 + a3 * b3;
|
|
return out
|
|
}
|
|
function rotate(out, a, rad) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3];
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
out[0] = a0 * c + a2 * s;
|
|
out[1] = a1 * c + a3 * s;
|
|
out[2] = a0 * -s + a2 * c;
|
|
out[3] = a1 * -s + a3 * c;
|
|
return out
|
|
}
|
|
function scale(out, a, v) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3];
|
|
var v0 = v[0]
|
|
, v1 = v[1];
|
|
out[0] = a0 * v0;
|
|
out[1] = a1 * v0;
|
|
out[2] = a2 * v1;
|
|
out[3] = a3 * v1;
|
|
return out
|
|
}
|
|
function fromRotation(out, rad) {
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
out[0] = c;
|
|
out[1] = s;
|
|
out[2] = -s;
|
|
out[3] = c;
|
|
return out
|
|
}
|
|
function fromScaling(out, v) {
|
|
out[0] = v[0];
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = v[1];
|
|
return out
|
|
}
|
|
function str(a) {
|
|
return "mat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"
|
|
}
|
|
function frob(a) {
|
|
return Math.hypot(a[0], a[1], a[2], a[3])
|
|
}
|
|
function LDU(L, D, U, a) {
|
|
L[2] = a[2] / a[0];
|
|
U[0] = a[0];
|
|
U[1] = a[1];
|
|
U[3] = a[3] - L[2] * U[1];
|
|
return [L, D, U]
|
|
}
|
|
function add(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
out[2] = a[2] + b[2];
|
|
out[3] = a[3] + b[3];
|
|
return out
|
|
}
|
|
function subtract(out, a, b) {
|
|
out[0] = a[0] - b[0];
|
|
out[1] = a[1] - b[1];
|
|
out[2] = a[2] - b[2];
|
|
out[3] = a[3] - b[3];
|
|
return out
|
|
}
|
|
function exactEquals(a, b) {
|
|
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]
|
|
}
|
|
function equals$1(a, b) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3];
|
|
var b0 = b[0]
|
|
, b1 = b[1]
|
|
, b2 = b[2]
|
|
, b3 = b[3];
|
|
return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1, Math.abs(a3), Math.abs(b3))
|
|
}
|
|
function multiplyScalar(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
out[2] = a[2] * b;
|
|
out[3] = a[3] * b;
|
|
return out
|
|
}
|
|
function multiplyScalarAndAdd(out, a, b, scale) {
|
|
out[0] = a[0] + b[0] * scale;
|
|
out[1] = a[1] + b[1] * scale;
|
|
out[2] = a[2] + b[2] * scale;
|
|
out[3] = a[3] + b[3] * scale;
|
|
return out
|
|
}
|
|
var mul = multiply;
|
|
var sub = subtract;
|
|
var mat2 = Object.freeze({
|
|
__proto__: null,
|
|
create: create,
|
|
clone: clone,
|
|
copy: copy,
|
|
identity: identity,
|
|
fromValues: fromValues,
|
|
set: set,
|
|
transpose: transpose,
|
|
invert: invert,
|
|
adjoint: adjoint,
|
|
determinant: determinant,
|
|
multiply: multiply,
|
|
rotate: rotate,
|
|
scale: scale,
|
|
fromRotation: fromRotation,
|
|
fromScaling: fromScaling,
|
|
str: str,
|
|
frob: frob,
|
|
LDU: LDU,
|
|
add: add,
|
|
subtract: subtract,
|
|
exactEquals: exactEquals,
|
|
equals: equals$1,
|
|
multiplyScalar: multiplyScalar,
|
|
multiplyScalarAndAdd: multiplyScalarAndAdd,
|
|
mul: mul,
|
|
sub: sub
|
|
});
|
|
function create$1() {
|
|
var out = new ARRAY_TYPE(6);
|
|
if (ARRAY_TYPE != Float32Array) {
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[4] = 0;
|
|
out[5] = 0
|
|
}
|
|
out[0] = 1;
|
|
out[3] = 1;
|
|
return out
|
|
}
|
|
function clone$1(a) {
|
|
var out = new ARRAY_TYPE(6);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
return out
|
|
}
|
|
function copy$1(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
return out
|
|
}
|
|
function identity$1(out) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
out[4] = 0;
|
|
out[5] = 0;
|
|
return out
|
|
}
|
|
function fromValues$1(a, b, c, d, tx, ty) {
|
|
var out = new ARRAY_TYPE(6);
|
|
out[0] = a;
|
|
out[1] = b;
|
|
out[2] = c;
|
|
out[3] = d;
|
|
out[4] = tx;
|
|
out[5] = ty;
|
|
return out
|
|
}
|
|
function set$1(out, a, b, c, d, tx, ty) {
|
|
out[0] = a;
|
|
out[1] = b;
|
|
out[2] = c;
|
|
out[3] = d;
|
|
out[4] = tx;
|
|
out[5] = ty;
|
|
return out
|
|
}
|
|
function invert$1(out, a) {
|
|
var aa = a[0]
|
|
, ab = a[1]
|
|
, ac = a[2]
|
|
, ad = a[3];
|
|
var atx = a[4]
|
|
, aty = a[5];
|
|
var det = aa * ad - ab * ac;
|
|
if (!det)
|
|
return null;
|
|
det = 1 / det;
|
|
out[0] = ad * det;
|
|
out[1] = -ab * det;
|
|
out[2] = -ac * det;
|
|
out[3] = aa * det;
|
|
out[4] = (ac * aty - ad * atx) * det;
|
|
out[5] = (ab * atx - aa * aty) * det;
|
|
return out
|
|
}
|
|
function determinant$1(a) {
|
|
return a[0] * a[3] - a[1] * a[2]
|
|
}
|
|
function multiply$1(out, a, b) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3]
|
|
, a4 = a[4]
|
|
, a5 = a[5];
|
|
var b0 = b[0]
|
|
, b1 = b[1]
|
|
, b2 = b[2]
|
|
, b3 = b[3]
|
|
, b4 = b[4]
|
|
, b5 = b[5];
|
|
out[0] = a0 * b0 + a2 * b1;
|
|
out[1] = a1 * b0 + a3 * b1;
|
|
out[2] = a0 * b2 + a2 * b3;
|
|
out[3] = a1 * b2 + a3 * b3;
|
|
out[4] = a0 * b4 + a2 * b5 + a4;
|
|
out[5] = a1 * b4 + a3 * b5 + a5;
|
|
return out
|
|
}
|
|
function rotate$1(out, a, rad) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3]
|
|
, a4 = a[4]
|
|
, a5 = a[5];
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
out[0] = a0 * c + a2 * s;
|
|
out[1] = a1 * c + a3 * s;
|
|
out[2] = a0 * -s + a2 * c;
|
|
out[3] = a1 * -s + a3 * c;
|
|
out[4] = a4;
|
|
out[5] = a5;
|
|
return out
|
|
}
|
|
function scale$1(out, a, v) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3]
|
|
, a4 = a[4]
|
|
, a5 = a[5];
|
|
var v0 = v[0]
|
|
, v1 = v[1];
|
|
out[0] = a0 * v0;
|
|
out[1] = a1 * v0;
|
|
out[2] = a2 * v1;
|
|
out[3] = a3 * v1;
|
|
out[4] = a4;
|
|
out[5] = a5;
|
|
return out
|
|
}
|
|
function translate(out, a, v) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3]
|
|
, a4 = a[4]
|
|
, a5 = a[5];
|
|
var v0 = v[0]
|
|
, v1 = v[1];
|
|
out[0] = a0;
|
|
out[1] = a1;
|
|
out[2] = a2;
|
|
out[3] = a3;
|
|
out[4] = a0 * v0 + a2 * v1 + a4;
|
|
out[5] = a1 * v0 + a3 * v1 + a5;
|
|
return out
|
|
}
|
|
function fromRotation$1(out, rad) {
|
|
var s = Math.sin(rad)
|
|
, c = Math.cos(rad);
|
|
out[0] = c;
|
|
out[1] = s;
|
|
out[2] = -s;
|
|
out[3] = c;
|
|
out[4] = 0;
|
|
out[5] = 0;
|
|
return out
|
|
}
|
|
function fromScaling$1(out, v) {
|
|
out[0] = v[0];
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = v[1];
|
|
out[4] = 0;
|
|
out[5] = 0;
|
|
return out
|
|
}
|
|
function fromTranslation(out, v) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
out[4] = v[0];
|
|
out[5] = v[1];
|
|
return out
|
|
}
|
|
function str$1(a) {
|
|
return "mat2d(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ")"
|
|
}
|
|
function frob$1(a) {
|
|
return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], 1)
|
|
}
|
|
function add$1(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
out[2] = a[2] + b[2];
|
|
out[3] = a[3] + b[3];
|
|
out[4] = a[4] + b[4];
|
|
out[5] = a[5] + b[5];
|
|
return out
|
|
}
|
|
function subtract$1(out, a, b) {
|
|
out[0] = a[0] - b[0];
|
|
out[1] = a[1] - b[1];
|
|
out[2] = a[2] - b[2];
|
|
out[3] = a[3] - b[3];
|
|
out[4] = a[4] - b[4];
|
|
out[5] = a[5] - b[5];
|
|
return out
|
|
}
|
|
function multiplyScalar$1(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
out[2] = a[2] * b;
|
|
out[3] = a[3] * b;
|
|
out[4] = a[4] * b;
|
|
out[5] = a[5] * b;
|
|
return out
|
|
}
|
|
function multiplyScalarAndAdd$1(out, a, b, scale) {
|
|
out[0] = a[0] + b[0] * scale;
|
|
out[1] = a[1] + b[1] * scale;
|
|
out[2] = a[2] + b[2] * scale;
|
|
out[3] = a[3] + b[3] * scale;
|
|
out[4] = a[4] + b[4] * scale;
|
|
out[5] = a[5] + b[5] * scale;
|
|
return out
|
|
}
|
|
function exactEquals$1(a, b) {
|
|
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5]
|
|
}
|
|
function equals$2(a, b) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3]
|
|
, a4 = a[4]
|
|
, a5 = a[5];
|
|
var b0 = b[0]
|
|
, b1 = b[1]
|
|
, b2 = b[2]
|
|
, b3 = b[3]
|
|
, b4 = b[4]
|
|
, b5 = b[5];
|
|
return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1, Math.abs(a5), Math.abs(b5))
|
|
}
|
|
var mul$1 = multiply$1;
|
|
var sub$1 = subtract$1;
|
|
var mat2d = Object.freeze({
|
|
__proto__: null,
|
|
create: create$1,
|
|
clone: clone$1,
|
|
copy: copy$1,
|
|
identity: identity$1,
|
|
fromValues: fromValues$1,
|
|
set: set$1,
|
|
invert: invert$1,
|
|
determinant: determinant$1,
|
|
multiply: multiply$1,
|
|
rotate: rotate$1,
|
|
scale: scale$1,
|
|
translate: translate,
|
|
fromRotation: fromRotation$1,
|
|
fromScaling: fromScaling$1,
|
|
fromTranslation: fromTranslation,
|
|
str: str$1,
|
|
frob: frob$1,
|
|
add: add$1,
|
|
subtract: subtract$1,
|
|
multiplyScalar: multiplyScalar$1,
|
|
multiplyScalarAndAdd: multiplyScalarAndAdd$1,
|
|
exactEquals: exactEquals$1,
|
|
equals: equals$2,
|
|
mul: mul$1,
|
|
sub: sub$1
|
|
});
|
|
function create$2() {
|
|
var out = new ARRAY_TYPE(9);
|
|
if (ARRAY_TYPE != Float32Array) {
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[5] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0
|
|
}
|
|
out[0] = 1;
|
|
out[4] = 1;
|
|
out[8] = 1;
|
|
return out
|
|
}
|
|
function fromMat4(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[4];
|
|
out[4] = a[5];
|
|
out[5] = a[6];
|
|
out[6] = a[8];
|
|
out[7] = a[9];
|
|
out[8] = a[10];
|
|
return out
|
|
}
|
|
function clone$2(a) {
|
|
var out = new ARRAY_TYPE(9);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
return out
|
|
}
|
|
function copy$2(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
return out
|
|
}
|
|
function fromValues$2(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
|
|
var out = new ARRAY_TYPE(9);
|
|
out[0] = m00;
|
|
out[1] = m01;
|
|
out[2] = m02;
|
|
out[3] = m10;
|
|
out[4] = m11;
|
|
out[5] = m12;
|
|
out[6] = m20;
|
|
out[7] = m21;
|
|
out[8] = m22;
|
|
return out
|
|
}
|
|
function set$2(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) {
|
|
out[0] = m00;
|
|
out[1] = m01;
|
|
out[2] = m02;
|
|
out[3] = m10;
|
|
out[4] = m11;
|
|
out[5] = m12;
|
|
out[6] = m20;
|
|
out[7] = m21;
|
|
out[8] = m22;
|
|
return out
|
|
}
|
|
function identity$2(out) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 1;
|
|
out[5] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 1;
|
|
return out
|
|
}
|
|
function transpose$1(out, a) {
|
|
if (out === a) {
|
|
var a01 = a[1]
|
|
, a02 = a[2]
|
|
, a12 = a[5];
|
|
out[1] = a[3];
|
|
out[2] = a[6];
|
|
out[3] = a01;
|
|
out[5] = a[7];
|
|
out[6] = a02;
|
|
out[7] = a12
|
|
} else {
|
|
out[0] = a[0];
|
|
out[1] = a[3];
|
|
out[2] = a[6];
|
|
out[3] = a[1];
|
|
out[4] = a[4];
|
|
out[5] = a[7];
|
|
out[6] = a[2];
|
|
out[7] = a[5];
|
|
out[8] = a[8]
|
|
}
|
|
return out
|
|
}
|
|
function invert$2(out, a) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2];
|
|
var a10 = a[3]
|
|
, a11 = a[4]
|
|
, a12 = a[5];
|
|
var a20 = a[6]
|
|
, a21 = a[7]
|
|
, a22 = a[8];
|
|
var b01 = a22 * a11 - a12 * a21;
|
|
var b11 = -a22 * a10 + a12 * a20;
|
|
var b21 = a21 * a10 - a11 * a20;
|
|
var det = a00 * b01 + a01 * b11 + a02 * b21;
|
|
if (!det)
|
|
return null;
|
|
det = 1 / det;
|
|
out[0] = b01 * det;
|
|
out[1] = (-a22 * a01 + a02 * a21) * det;
|
|
out[2] = (a12 * a01 - a02 * a11) * det;
|
|
out[3] = b11 * det;
|
|
out[4] = (a22 * a00 - a02 * a20) * det;
|
|
out[5] = (-a12 * a00 + a02 * a10) * det;
|
|
out[6] = b21 * det;
|
|
out[7] = (-a21 * a00 + a01 * a20) * det;
|
|
out[8] = (a11 * a00 - a01 * a10) * det;
|
|
return out
|
|
}
|
|
function adjoint$1(out, a) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2];
|
|
var a10 = a[3]
|
|
, a11 = a[4]
|
|
, a12 = a[5];
|
|
var a20 = a[6]
|
|
, a21 = a[7]
|
|
, a22 = a[8];
|
|
out[0] = a11 * a22 - a12 * a21;
|
|
out[1] = a02 * a21 - a01 * a22;
|
|
out[2] = a01 * a12 - a02 * a11;
|
|
out[3] = a12 * a20 - a10 * a22;
|
|
out[4] = a00 * a22 - a02 * a20;
|
|
out[5] = a02 * a10 - a00 * a12;
|
|
out[6] = a10 * a21 - a11 * a20;
|
|
out[7] = a01 * a20 - a00 * a21;
|
|
out[8] = a00 * a11 - a01 * a10;
|
|
return out
|
|
}
|
|
function determinant$2(a) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2];
|
|
var a10 = a[3]
|
|
, a11 = a[4]
|
|
, a12 = a[5];
|
|
var a20 = a[6]
|
|
, a21 = a[7]
|
|
, a22 = a[8];
|
|
return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20)
|
|
}
|
|
function multiply$2(out, a, b) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2];
|
|
var a10 = a[3]
|
|
, a11 = a[4]
|
|
, a12 = a[5];
|
|
var a20 = a[6]
|
|
, a21 = a[7]
|
|
, a22 = a[8];
|
|
var b00 = b[0]
|
|
, b01 = b[1]
|
|
, b02 = b[2];
|
|
var b10 = b[3]
|
|
, b11 = b[4]
|
|
, b12 = b[5];
|
|
var b20 = b[6]
|
|
, b21 = b[7]
|
|
, b22 = b[8];
|
|
out[0] = b00 * a00 + b01 * a10 + b02 * a20;
|
|
out[1] = b00 * a01 + b01 * a11 + b02 * a21;
|
|
out[2] = b00 * a02 + b01 * a12 + b02 * a22;
|
|
out[3] = b10 * a00 + b11 * a10 + b12 * a20;
|
|
out[4] = b10 * a01 + b11 * a11 + b12 * a21;
|
|
out[5] = b10 * a02 + b11 * a12 + b12 * a22;
|
|
out[6] = b20 * a00 + b21 * a10 + b22 * a20;
|
|
out[7] = b20 * a01 + b21 * a11 + b22 * a21;
|
|
out[8] = b20 * a02 + b21 * a12 + b22 * a22;
|
|
return out
|
|
}
|
|
function translate$1(out, a, v) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2]
|
|
, a10 = a[3]
|
|
, a11 = a[4]
|
|
, a12 = a[5]
|
|
, a20 = a[6]
|
|
, a21 = a[7]
|
|
, a22 = a[8]
|
|
, x = v[0]
|
|
, y = v[1];
|
|
out[0] = a00;
|
|
out[1] = a01;
|
|
out[2] = a02;
|
|
out[3] = a10;
|
|
out[4] = a11;
|
|
out[5] = a12;
|
|
out[6] = x * a00 + y * a10 + a20;
|
|
out[7] = x * a01 + y * a11 + a21;
|
|
out[8] = x * a02 + y * a12 + a22;
|
|
return out
|
|
}
|
|
function rotate$2(out, a, rad) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2]
|
|
, a10 = a[3]
|
|
, a11 = a[4]
|
|
, a12 = a[5]
|
|
, a20 = a[6]
|
|
, a21 = a[7]
|
|
, a22 = a[8]
|
|
, s = Math.sin(rad)
|
|
, c = Math.cos(rad);
|
|
out[0] = c * a00 + s * a10;
|
|
out[1] = c * a01 + s * a11;
|
|
out[2] = c * a02 + s * a12;
|
|
out[3] = c * a10 - s * a00;
|
|
out[4] = c * a11 - s * a01;
|
|
out[5] = c * a12 - s * a02;
|
|
out[6] = a20;
|
|
out[7] = a21;
|
|
out[8] = a22;
|
|
return out
|
|
}
|
|
function scale$2(out, a, v) {
|
|
var x = v[0]
|
|
, y = v[1];
|
|
out[0] = x * a[0];
|
|
out[1] = x * a[1];
|
|
out[2] = x * a[2];
|
|
out[3] = y * a[3];
|
|
out[4] = y * a[4];
|
|
out[5] = y * a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
return out
|
|
}
|
|
function fromTranslation$1(out, v) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 1;
|
|
out[5] = 0;
|
|
out[6] = v[0];
|
|
out[7] = v[1];
|
|
out[8] = 1;
|
|
return out
|
|
}
|
|
function fromRotation$2(out, rad) {
|
|
var s = Math.sin(rad)
|
|
, c = Math.cos(rad);
|
|
out[0] = c;
|
|
out[1] = s;
|
|
out[2] = 0;
|
|
out[3] = -s;
|
|
out[4] = c;
|
|
out[5] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 1;
|
|
return out
|
|
}
|
|
function fromScaling$2(out, v) {
|
|
out[0] = v[0];
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = v[1];
|
|
out[5] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 1;
|
|
return out
|
|
}
|
|
function fromMat2d(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = 0;
|
|
out[3] = a[2];
|
|
out[4] = a[3];
|
|
out[5] = 0;
|
|
out[6] = a[4];
|
|
out[7] = a[5];
|
|
out[8] = 1;
|
|
return out
|
|
}
|
|
function fromQuat(out, q) {
|
|
var x = q[0]
|
|
, y = q[1]
|
|
, z = q[2]
|
|
, w = q[3];
|
|
var x2 = x + x;
|
|
var y2 = y + y;
|
|
var z2 = z + z;
|
|
var xx = x * x2;
|
|
var yx = y * x2;
|
|
var yy = y * y2;
|
|
var zx = z * x2;
|
|
var zy = z * y2;
|
|
var zz = z * z2;
|
|
var wx = w * x2;
|
|
var wy = w * y2;
|
|
var wz = w * z2;
|
|
out[0] = 1 - yy - zz;
|
|
out[3] = yx - wz;
|
|
out[6] = zx + wy;
|
|
out[1] = yx + wz;
|
|
out[4] = 1 - xx - zz;
|
|
out[7] = zy - wx;
|
|
out[2] = zx - wy;
|
|
out[5] = zy + wx;
|
|
out[8] = 1 - xx - yy;
|
|
return out
|
|
}
|
|
function normalFromMat4(out, a) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2]
|
|
, a03 = a[3];
|
|
var a10 = a[4]
|
|
, a11 = a[5]
|
|
, a12 = a[6]
|
|
, a13 = a[7];
|
|
var a20 = a[8]
|
|
, a21 = a[9]
|
|
, a22 = a[10]
|
|
, a23 = a[11];
|
|
var a30 = a[12]
|
|
, a31 = a[13]
|
|
, a32 = a[14]
|
|
, a33 = a[15];
|
|
var b00 = a00 * a11 - a01 * a10;
|
|
var b01 = a00 * a12 - a02 * a10;
|
|
var b02 = a00 * a13 - a03 * a10;
|
|
var b03 = a01 * a12 - a02 * a11;
|
|
var b04 = a01 * a13 - a03 * a11;
|
|
var b05 = a02 * a13 - a03 * a12;
|
|
var b06 = a20 * a31 - a21 * a30;
|
|
var b07 = a20 * a32 - a22 * a30;
|
|
var b08 = a20 * a33 - a23 * a30;
|
|
var b09 = a21 * a32 - a22 * a31;
|
|
var b10 = a21 * a33 - a23 * a31;
|
|
var b11 = a22 * a33 - a23 * a32;
|
|
var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
if (!det)
|
|
return null;
|
|
det = 1 / det;
|
|
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
|
|
out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
|
|
out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
|
|
out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
|
|
out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
|
|
out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
|
|
out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
|
|
out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
|
|
out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
|
|
return out
|
|
}
|
|
function projection(out, width, height) {
|
|
out[0] = 2 / width;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = -2 / height;
|
|
out[5] = 0;
|
|
out[6] = -1;
|
|
out[7] = 1;
|
|
out[8] = 1;
|
|
return out
|
|
}
|
|
function str$2(a) {
|
|
return "mat3(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ")"
|
|
}
|
|
function frob$2(a) {
|
|
return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8])
|
|
}
|
|
function add$2(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
out[2] = a[2] + b[2];
|
|
out[3] = a[3] + b[3];
|
|
out[4] = a[4] + b[4];
|
|
out[5] = a[5] + b[5];
|
|
out[6] = a[6] + b[6];
|
|
out[7] = a[7] + b[7];
|
|
out[8] = a[8] + b[8];
|
|
return out
|
|
}
|
|
function subtract$2(out, a, b) {
|
|
out[0] = a[0] - b[0];
|
|
out[1] = a[1] - b[1];
|
|
out[2] = a[2] - b[2];
|
|
out[3] = a[3] - b[3];
|
|
out[4] = a[4] - b[4];
|
|
out[5] = a[5] - b[5];
|
|
out[6] = a[6] - b[6];
|
|
out[7] = a[7] - b[7];
|
|
out[8] = a[8] - b[8];
|
|
return out
|
|
}
|
|
function multiplyScalar$2(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
out[2] = a[2] * b;
|
|
out[3] = a[3] * b;
|
|
out[4] = a[4] * b;
|
|
out[5] = a[5] * b;
|
|
out[6] = a[6] * b;
|
|
out[7] = a[7] * b;
|
|
out[8] = a[8] * b;
|
|
return out
|
|
}
|
|
function multiplyScalarAndAdd$2(out, a, b, scale) {
|
|
out[0] = a[0] + b[0] * scale;
|
|
out[1] = a[1] + b[1] * scale;
|
|
out[2] = a[2] + b[2] * scale;
|
|
out[3] = a[3] + b[3] * scale;
|
|
out[4] = a[4] + b[4] * scale;
|
|
out[5] = a[5] + b[5] * scale;
|
|
out[6] = a[6] + b[6] * scale;
|
|
out[7] = a[7] + b[7] * scale;
|
|
out[8] = a[8] + b[8] * scale;
|
|
return out
|
|
}
|
|
function exactEquals$2(a, b) {
|
|
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8]
|
|
}
|
|
function equals$3(a, b) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3]
|
|
, a4 = a[4]
|
|
, a5 = a[5]
|
|
, a6 = a[6]
|
|
, a7 = a[7]
|
|
, a8 = a[8];
|
|
var b0 = b[0]
|
|
, b1 = b[1]
|
|
, b2 = b[2]
|
|
, b3 = b[3]
|
|
, b4 = b[4]
|
|
, b5 = b[5]
|
|
, b6 = b[6]
|
|
, b7 = b[7]
|
|
, b8 = b[8];
|
|
return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1, Math.abs(a8), Math.abs(b8))
|
|
}
|
|
var mul$2 = multiply$2;
|
|
var sub$2 = subtract$2;
|
|
var mat3 = Object.freeze({
|
|
__proto__: null,
|
|
create: create$2,
|
|
fromMat4: fromMat4,
|
|
clone: clone$2,
|
|
copy: copy$2,
|
|
fromValues: fromValues$2,
|
|
set: set$2,
|
|
identity: identity$2,
|
|
transpose: transpose$1,
|
|
invert: invert$2,
|
|
adjoint: adjoint$1,
|
|
determinant: determinant$2,
|
|
multiply: multiply$2,
|
|
translate: translate$1,
|
|
rotate: rotate$2,
|
|
scale: scale$2,
|
|
fromTranslation: fromTranslation$1,
|
|
fromRotation: fromRotation$2,
|
|
fromScaling: fromScaling$2,
|
|
fromMat2d: fromMat2d,
|
|
fromQuat: fromQuat,
|
|
normalFromMat4: normalFromMat4,
|
|
projection: projection,
|
|
str: str$2,
|
|
frob: frob$2,
|
|
add: add$2,
|
|
subtract: subtract$2,
|
|
multiplyScalar: multiplyScalar$2,
|
|
multiplyScalarAndAdd: multiplyScalarAndAdd$2,
|
|
exactEquals: exactEquals$2,
|
|
equals: equals$3,
|
|
mul: mul$2,
|
|
sub: sub$2
|
|
});
|
|
function create$3() {
|
|
var out = new ARRAY_TYPE(16);
|
|
if (ARRAY_TYPE != Float32Array) {
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0
|
|
}
|
|
out[0] = 1;
|
|
out[5] = 1;
|
|
out[10] = 1;
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function clone$3(a) {
|
|
var out = new ARRAY_TYPE(16);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
out[9] = a[9];
|
|
out[10] = a[10];
|
|
out[11] = a[11];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
return out
|
|
}
|
|
function copy$3(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
out[9] = a[9];
|
|
out[10] = a[10];
|
|
out[11] = a[11];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
return out
|
|
}
|
|
function fromValues$3(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
|
|
var out = new ARRAY_TYPE(16);
|
|
out[0] = m00;
|
|
out[1] = m01;
|
|
out[2] = m02;
|
|
out[3] = m03;
|
|
out[4] = m10;
|
|
out[5] = m11;
|
|
out[6] = m12;
|
|
out[7] = m13;
|
|
out[8] = m20;
|
|
out[9] = m21;
|
|
out[10] = m22;
|
|
out[11] = m23;
|
|
out[12] = m30;
|
|
out[13] = m31;
|
|
out[14] = m32;
|
|
out[15] = m33;
|
|
return out
|
|
}
|
|
function set$3(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
|
|
out[0] = m00;
|
|
out[1] = m01;
|
|
out[2] = m02;
|
|
out[3] = m03;
|
|
out[4] = m10;
|
|
out[5] = m11;
|
|
out[6] = m12;
|
|
out[7] = m13;
|
|
out[8] = m20;
|
|
out[9] = m21;
|
|
out[10] = m22;
|
|
out[11] = m23;
|
|
out[12] = m30;
|
|
out[13] = m31;
|
|
out[14] = m32;
|
|
out[15] = m33;
|
|
return out
|
|
}
|
|
function identity$3(out) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = 1;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 1;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function transpose$2(out, a) {
|
|
if (out === a) {
|
|
var a01 = a[1]
|
|
, a02 = a[2]
|
|
, a03 = a[3];
|
|
var a12 = a[6]
|
|
, a13 = a[7];
|
|
var a23 = a[11];
|
|
out[1] = a[4];
|
|
out[2] = a[8];
|
|
out[3] = a[12];
|
|
out[4] = a01;
|
|
out[6] = a[9];
|
|
out[7] = a[13];
|
|
out[8] = a02;
|
|
out[9] = a12;
|
|
out[11] = a[14];
|
|
out[12] = a03;
|
|
out[13] = a13;
|
|
out[14] = a23
|
|
} else {
|
|
out[0] = a[0];
|
|
out[1] = a[4];
|
|
out[2] = a[8];
|
|
out[3] = a[12];
|
|
out[4] = a[1];
|
|
out[5] = a[5];
|
|
out[6] = a[9];
|
|
out[7] = a[13];
|
|
out[8] = a[2];
|
|
out[9] = a[6];
|
|
out[10] = a[10];
|
|
out[11] = a[14];
|
|
out[12] = a[3];
|
|
out[13] = a[7];
|
|
out[14] = a[11];
|
|
out[15] = a[15]
|
|
}
|
|
return out
|
|
}
|
|
function invert$3(out, a) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2]
|
|
, a03 = a[3];
|
|
var a10 = a[4]
|
|
, a11 = a[5]
|
|
, a12 = a[6]
|
|
, a13 = a[7];
|
|
var a20 = a[8]
|
|
, a21 = a[9]
|
|
, a22 = a[10]
|
|
, a23 = a[11];
|
|
var a30 = a[12]
|
|
, a31 = a[13]
|
|
, a32 = a[14]
|
|
, a33 = a[15];
|
|
var b00 = a00 * a11 - a01 * a10;
|
|
var b01 = a00 * a12 - a02 * a10;
|
|
var b02 = a00 * a13 - a03 * a10;
|
|
var b03 = a01 * a12 - a02 * a11;
|
|
var b04 = a01 * a13 - a03 * a11;
|
|
var b05 = a02 * a13 - a03 * a12;
|
|
var b06 = a20 * a31 - a21 * a30;
|
|
var b07 = a20 * a32 - a22 * a30;
|
|
var b08 = a20 * a33 - a23 * a30;
|
|
var b09 = a21 * a32 - a22 * a31;
|
|
var b10 = a21 * a33 - a23 * a31;
|
|
var b11 = a22 * a33 - a23 * a32;
|
|
var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
if (!det)
|
|
return null;
|
|
det = 1 / det;
|
|
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
|
|
out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
|
|
out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
|
|
out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
|
|
out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
|
|
out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
|
|
out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
|
|
out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
|
|
out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
|
|
out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
|
|
out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
|
|
out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
|
|
out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
|
|
out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
|
|
out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
|
|
out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
|
|
return out
|
|
}
|
|
function adjoint$2(out, a) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2]
|
|
, a03 = a[3];
|
|
var a10 = a[4]
|
|
, a11 = a[5]
|
|
, a12 = a[6]
|
|
, a13 = a[7];
|
|
var a20 = a[8]
|
|
, a21 = a[9]
|
|
, a22 = a[10]
|
|
, a23 = a[11];
|
|
var a30 = a[12]
|
|
, a31 = a[13]
|
|
, a32 = a[14]
|
|
, a33 = a[15];
|
|
out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22);
|
|
out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
|
|
out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12);
|
|
out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
|
|
out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
|
|
out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22);
|
|
out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
|
|
out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12);
|
|
out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21);
|
|
out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
|
|
out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11);
|
|
out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
|
|
out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
|
|
out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21);
|
|
out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
|
|
out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11);
|
|
return out
|
|
}
|
|
function determinant$3(a) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2]
|
|
, a03 = a[3];
|
|
var a10 = a[4]
|
|
, a11 = a[5]
|
|
, a12 = a[6]
|
|
, a13 = a[7];
|
|
var a20 = a[8]
|
|
, a21 = a[9]
|
|
, a22 = a[10]
|
|
, a23 = a[11];
|
|
var a30 = a[12]
|
|
, a31 = a[13]
|
|
, a32 = a[14]
|
|
, a33 = a[15];
|
|
var b00 = a00 * a11 - a01 * a10;
|
|
var b01 = a00 * a12 - a02 * a10;
|
|
var b02 = a00 * a13 - a03 * a10;
|
|
var b03 = a01 * a12 - a02 * a11;
|
|
var b04 = a01 * a13 - a03 * a11;
|
|
var b05 = a02 * a13 - a03 * a12;
|
|
var b06 = a20 * a31 - a21 * a30;
|
|
var b07 = a20 * a32 - a22 * a30;
|
|
var b08 = a20 * a33 - a23 * a30;
|
|
var b09 = a21 * a32 - a22 * a31;
|
|
var b10 = a21 * a33 - a23 * a31;
|
|
var b11 = a22 * a33 - a23 * a32;
|
|
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06
|
|
}
|
|
function multiply$3(out, a, b) {
|
|
var a00 = a[0]
|
|
, a01 = a[1]
|
|
, a02 = a[2]
|
|
, a03 = a[3];
|
|
var a10 = a[4]
|
|
, a11 = a[5]
|
|
, a12 = a[6]
|
|
, a13 = a[7];
|
|
var a20 = a[8]
|
|
, a21 = a[9]
|
|
, a22 = a[10]
|
|
, a23 = a[11];
|
|
var a30 = a[12]
|
|
, a31 = a[13]
|
|
, a32 = a[14]
|
|
, a33 = a[15];
|
|
var b0 = b[0]
|
|
, b1 = b[1]
|
|
, b2 = b[2]
|
|
, b3 = b[3];
|
|
out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
b0 = b[4];
|
|
b1 = b[5];
|
|
b2 = b[6];
|
|
b3 = b[7];
|
|
out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
b0 = b[8];
|
|
b1 = b[9];
|
|
b2 = b[10];
|
|
b3 = b[11];
|
|
out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
b0 = b[12];
|
|
b1 = b[13];
|
|
b2 = b[14];
|
|
b3 = b[15];
|
|
out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
return out
|
|
}
|
|
function translate$2(out, a, v) {
|
|
var x = v[0]
|
|
, y = v[1]
|
|
, z = v[2];
|
|
var a00, a01, a02, a03;
|
|
var a10, a11, a12, a13;
|
|
var a20, a21, a22, a23;
|
|
if (a === out) {
|
|
out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
|
|
out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
|
|
out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
|
|
out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]
|
|
} else {
|
|
a00 = a[0];
|
|
a01 = a[1];
|
|
a02 = a[2];
|
|
a03 = a[3];
|
|
a10 = a[4];
|
|
a11 = a[5];
|
|
a12 = a[6];
|
|
a13 = a[7];
|
|
a20 = a[8];
|
|
a21 = a[9];
|
|
a22 = a[10];
|
|
a23 = a[11];
|
|
out[0] = a00;
|
|
out[1] = a01;
|
|
out[2] = a02;
|
|
out[3] = a03;
|
|
out[4] = a10;
|
|
out[5] = a11;
|
|
out[6] = a12;
|
|
out[7] = a13;
|
|
out[8] = a20;
|
|
out[9] = a21;
|
|
out[10] = a22;
|
|
out[11] = a23;
|
|
out[12] = a00 * x + a10 * y + a20 * z + a[12];
|
|
out[13] = a01 * x + a11 * y + a21 * z + a[13];
|
|
out[14] = a02 * x + a12 * y + a22 * z + a[14];
|
|
out[15] = a03 * x + a13 * y + a23 * z + a[15]
|
|
}
|
|
return out
|
|
}
|
|
function scale$3(out, a, v) {
|
|
var x = v[0]
|
|
, y = v[1]
|
|
, z = v[2];
|
|
out[0] = a[0] * x;
|
|
out[1] = a[1] * x;
|
|
out[2] = a[2] * x;
|
|
out[3] = a[3] * x;
|
|
out[4] = a[4] * y;
|
|
out[5] = a[5] * y;
|
|
out[6] = a[6] * y;
|
|
out[7] = a[7] * y;
|
|
out[8] = a[8] * z;
|
|
out[9] = a[9] * z;
|
|
out[10] = a[10] * z;
|
|
out[11] = a[11] * z;
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
return out
|
|
}
|
|
function rotate$3(out, a, rad, axis) {
|
|
var x = axis[0]
|
|
, y = axis[1]
|
|
, z = axis[2];
|
|
var len = Math.hypot(x, y, z);
|
|
var s, c, t;
|
|
var a00, a01, a02, a03;
|
|
var a10, a11, a12, a13;
|
|
var a20, a21, a22, a23;
|
|
var b00, b01, b02;
|
|
var b10, b11, b12;
|
|
var b20, b21, b22;
|
|
if (len < EPSILON)
|
|
return null;
|
|
len = 1 / len;
|
|
x *= len;
|
|
y *= len;
|
|
z *= len;
|
|
s = Math.sin(rad);
|
|
c = Math.cos(rad);
|
|
t = 1 - c;
|
|
a00 = a[0];
|
|
a01 = a[1];
|
|
a02 = a[2];
|
|
a03 = a[3];
|
|
a10 = a[4];
|
|
a11 = a[5];
|
|
a12 = a[6];
|
|
a13 = a[7];
|
|
a20 = a[8];
|
|
a21 = a[9];
|
|
a22 = a[10];
|
|
a23 = a[11];
|
|
b00 = x * x * t + c;
|
|
b01 = y * x * t + z * s;
|
|
b02 = z * x * t - y * s;
|
|
b10 = x * y * t - z * s;
|
|
b11 = y * y * t + c;
|
|
b12 = z * y * t + x * s;
|
|
b20 = x * z * t + y * s;
|
|
b21 = y * z * t - x * s;
|
|
b22 = z * z * t + c;
|
|
out[0] = a00 * b00 + a10 * b01 + a20 * b02;
|
|
out[1] = a01 * b00 + a11 * b01 + a21 * b02;
|
|
out[2] = a02 * b00 + a12 * b01 + a22 * b02;
|
|
out[3] = a03 * b00 + a13 * b01 + a23 * b02;
|
|
out[4] = a00 * b10 + a10 * b11 + a20 * b12;
|
|
out[5] = a01 * b10 + a11 * b11 + a21 * b12;
|
|
out[6] = a02 * b10 + a12 * b11 + a22 * b12;
|
|
out[7] = a03 * b10 + a13 * b11 + a23 * b12;
|
|
out[8] = a00 * b20 + a10 * b21 + a20 * b22;
|
|
out[9] = a01 * b20 + a11 * b21 + a21 * b22;
|
|
out[10] = a02 * b20 + a12 * b21 + a22 * b22;
|
|
out[11] = a03 * b20 + a13 * b21 + a23 * b22;
|
|
if (a !== out) {
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15]
|
|
}
|
|
return out
|
|
}
|
|
function rotateX(out, a, rad) {
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
var a10 = a[4];
|
|
var a11 = a[5];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
var a20 = a[8];
|
|
var a21 = a[9];
|
|
var a22 = a[10];
|
|
var a23 = a[11];
|
|
if (a !== out) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15]
|
|
}
|
|
out[4] = a10 * c + a20 * s;
|
|
out[5] = a11 * c + a21 * s;
|
|
out[6] = a12 * c + a22 * s;
|
|
out[7] = a13 * c + a23 * s;
|
|
out[8] = a20 * c - a10 * s;
|
|
out[9] = a21 * c - a11 * s;
|
|
out[10] = a22 * c - a12 * s;
|
|
out[11] = a23 * c - a13 * s;
|
|
return out
|
|
}
|
|
function rotateY(out, a, rad) {
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
var a20 = a[8];
|
|
var a21 = a[9];
|
|
var a22 = a[10];
|
|
var a23 = a[11];
|
|
if (a !== out) {
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15]
|
|
}
|
|
out[0] = a00 * c - a20 * s;
|
|
out[1] = a01 * c - a21 * s;
|
|
out[2] = a02 * c - a22 * s;
|
|
out[3] = a03 * c - a23 * s;
|
|
out[8] = a00 * s + a20 * c;
|
|
out[9] = a01 * s + a21 * c;
|
|
out[10] = a02 * s + a22 * c;
|
|
out[11] = a03 * s + a23 * c;
|
|
return out
|
|
}
|
|
function rotateZ(out, a, rad) {
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
var a10 = a[4];
|
|
var a11 = a[5];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
if (a !== out) {
|
|
out[8] = a[8];
|
|
out[9] = a[9];
|
|
out[10] = a[10];
|
|
out[11] = a[11];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15]
|
|
}
|
|
out[0] = a00 * c + a10 * s;
|
|
out[1] = a01 * c + a11 * s;
|
|
out[2] = a02 * c + a12 * s;
|
|
out[3] = a03 * c + a13 * s;
|
|
out[4] = a10 * c - a00 * s;
|
|
out[5] = a11 * c - a01 * s;
|
|
out[6] = a12 * c - a02 * s;
|
|
out[7] = a13 * c - a03 * s;
|
|
return out
|
|
}
|
|
function fromTranslation$2(out, v) {
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = 1;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 1;
|
|
out[11] = 0;
|
|
out[12] = v[0];
|
|
out[13] = v[1];
|
|
out[14] = v[2];
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function fromScaling$3(out, v) {
|
|
out[0] = v[0];
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = v[1];
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = v[2];
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function fromRotation$3(out, rad, axis) {
|
|
var x = axis[0]
|
|
, y = axis[1]
|
|
, z = axis[2];
|
|
var len = Math.hypot(x, y, z);
|
|
var s, c, t;
|
|
if (len < EPSILON)
|
|
return null;
|
|
len = 1 / len;
|
|
x *= len;
|
|
y *= len;
|
|
z *= len;
|
|
s = Math.sin(rad);
|
|
c = Math.cos(rad);
|
|
t = 1 - c;
|
|
out[0] = x * x * t + c;
|
|
out[1] = y * x * t + z * s;
|
|
out[2] = z * x * t - y * s;
|
|
out[3] = 0;
|
|
out[4] = x * y * t - z * s;
|
|
out[5] = y * y * t + c;
|
|
out[6] = z * y * t + x * s;
|
|
out[7] = 0;
|
|
out[8] = x * z * t + y * s;
|
|
out[9] = y * z * t - x * s;
|
|
out[10] = z * z * t + c;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function fromXRotation(out, rad) {
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = c;
|
|
out[6] = s;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = -s;
|
|
out[10] = c;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function fromYRotation(out, rad) {
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
out[0] = c;
|
|
out[1] = 0;
|
|
out[2] = -s;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = 1;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = s;
|
|
out[9] = 0;
|
|
out[10] = c;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function fromZRotation(out, rad) {
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
out[0] = c;
|
|
out[1] = s;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = -s;
|
|
out[5] = c;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 1;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function fromRotationTranslation(out, q, v) {
|
|
var x = q[0]
|
|
, y = q[1]
|
|
, z = q[2]
|
|
, w = q[3];
|
|
var x2 = x + x;
|
|
var y2 = y + y;
|
|
var z2 = z + z;
|
|
var xx = x * x2;
|
|
var xy = x * y2;
|
|
var xz = x * z2;
|
|
var yy = y * y2;
|
|
var yz = y * z2;
|
|
var zz = z * z2;
|
|
var wx = w * x2;
|
|
var wy = w * y2;
|
|
var wz = w * z2;
|
|
out[0] = 1 - (yy + zz);
|
|
out[1] = xy + wz;
|
|
out[2] = xz - wy;
|
|
out[3] = 0;
|
|
out[4] = xy - wz;
|
|
out[5] = 1 - (xx + zz);
|
|
out[6] = yz + wx;
|
|
out[7] = 0;
|
|
out[8] = xz + wy;
|
|
out[9] = yz - wx;
|
|
out[10] = 1 - (xx + yy);
|
|
out[11] = 0;
|
|
out[12] = v[0];
|
|
out[13] = v[1];
|
|
out[14] = v[2];
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function fromQuat2(out, a) {
|
|
var translation = new ARRAY_TYPE(3);
|
|
var bx = -a[0]
|
|
, by = -a[1]
|
|
, bz = -a[2]
|
|
, bw = a[3]
|
|
, ax = a[4]
|
|
, ay = a[5]
|
|
, az = a[6]
|
|
, aw = a[7];
|
|
var magnitude = bx * bx + by * by + bz * bz + bw * bw;
|
|
if (magnitude > 0) {
|
|
translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude;
|
|
translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude;
|
|
translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude
|
|
} else {
|
|
translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;
|
|
translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;
|
|
translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2
|
|
}
|
|
fromRotationTranslation(out, a, translation);
|
|
return out
|
|
}
|
|
function getTranslation(out, mat) {
|
|
out[0] = mat[12];
|
|
out[1] = mat[13];
|
|
out[2] = mat[14];
|
|
return out
|
|
}
|
|
function getScaling(out, mat) {
|
|
var m11 = mat[0];
|
|
var m12 = mat[1];
|
|
var m13 = mat[2];
|
|
var m21 = mat[4];
|
|
var m22 = mat[5];
|
|
var m23 = mat[6];
|
|
var m31 = mat[8];
|
|
var m32 = mat[9];
|
|
var m33 = mat[10];
|
|
out[0] = Math.hypot(m11, m12, m13);
|
|
out[1] = Math.hypot(m21, m22, m23);
|
|
out[2] = Math.hypot(m31, m32, m33);
|
|
return out
|
|
}
|
|
function getRotation(out, mat) {
|
|
var scaling = new ARRAY_TYPE(3);
|
|
getScaling(scaling, mat);
|
|
var is1 = 1 / scaling[0];
|
|
var is2 = 1 / scaling[1];
|
|
var is3 = 1 / scaling[2];
|
|
var sm11 = mat[0] * is1;
|
|
var sm12 = mat[1] * is2;
|
|
var sm13 = mat[2] * is3;
|
|
var sm21 = mat[4] * is1;
|
|
var sm22 = mat[5] * is2;
|
|
var sm23 = mat[6] * is3;
|
|
var sm31 = mat[8] * is1;
|
|
var sm32 = mat[9] * is2;
|
|
var sm33 = mat[10] * is3;
|
|
var trace = sm11 + sm22 + sm33;
|
|
var S = 0;
|
|
if (trace > 0) {
|
|
S = Math.sqrt(trace + 1) * 2;
|
|
out[3] = .25 * S;
|
|
out[0] = (sm23 - sm32) / S;
|
|
out[1] = (sm31 - sm13) / S;
|
|
out[2] = (sm12 - sm21) / S
|
|
} else if (sm11 > sm22 && sm11 > sm33) {
|
|
S = Math.sqrt(1 + sm11 - sm22 - sm33) * 2;
|
|
out[3] = (sm23 - sm32) / S;
|
|
out[0] = .25 * S;
|
|
out[1] = (sm12 + sm21) / S;
|
|
out[2] = (sm31 + sm13) / S
|
|
} else if (sm22 > sm33) {
|
|
S = Math.sqrt(1 + sm22 - sm11 - sm33) * 2;
|
|
out[3] = (sm31 - sm13) / S;
|
|
out[0] = (sm12 + sm21) / S;
|
|
out[1] = .25 * S;
|
|
out[2] = (sm23 + sm32) / S
|
|
} else {
|
|
S = Math.sqrt(1 + sm33 - sm11 - sm22) * 2;
|
|
out[3] = (sm12 - sm21) / S;
|
|
out[0] = (sm31 + sm13) / S;
|
|
out[1] = (sm23 + sm32) / S;
|
|
out[2] = .25 * S
|
|
}
|
|
return out
|
|
}
|
|
function fromRotationTranslationScale(out, q, v, s) {
|
|
var x = q[0]
|
|
, y = q[1]
|
|
, z = q[2]
|
|
, w = q[3];
|
|
var x2 = x + x;
|
|
var y2 = y + y;
|
|
var z2 = z + z;
|
|
var xx = x * x2;
|
|
var xy = x * y2;
|
|
var xz = x * z2;
|
|
var yy = y * y2;
|
|
var yz = y * z2;
|
|
var zz = z * z2;
|
|
var wx = w * x2;
|
|
var wy = w * y2;
|
|
var wz = w * z2;
|
|
var sx = s[0];
|
|
var sy = s[1];
|
|
var sz = s[2];
|
|
out[0] = (1 - (yy + zz)) * sx;
|
|
out[1] = (xy + wz) * sx;
|
|
out[2] = (xz - wy) * sx;
|
|
out[3] = 0;
|
|
out[4] = (xy - wz) * sy;
|
|
out[5] = (1 - (xx + zz)) * sy;
|
|
out[6] = (yz + wx) * sy;
|
|
out[7] = 0;
|
|
out[8] = (xz + wy) * sz;
|
|
out[9] = (yz - wx) * sz;
|
|
out[10] = (1 - (xx + yy)) * sz;
|
|
out[11] = 0;
|
|
out[12] = v[0];
|
|
out[13] = v[1];
|
|
out[14] = v[2];
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function fromRotationTranslationScaleOrigin(out, q, v, s, o) {
|
|
var x = q[0]
|
|
, y = q[1]
|
|
, z = q[2]
|
|
, w = q[3];
|
|
var x2 = x + x;
|
|
var y2 = y + y;
|
|
var z2 = z + z;
|
|
var xx = x * x2;
|
|
var xy = x * y2;
|
|
var xz = x * z2;
|
|
var yy = y * y2;
|
|
var yz = y * z2;
|
|
var zz = z * z2;
|
|
var wx = w * x2;
|
|
var wy = w * y2;
|
|
var wz = w * z2;
|
|
var sx = s[0];
|
|
var sy = s[1];
|
|
var sz = s[2];
|
|
var ox = o[0];
|
|
var oy = o[1];
|
|
var oz = o[2];
|
|
var out0 = (1 - (yy + zz)) * sx;
|
|
var out1 = (xy + wz) * sx;
|
|
var out2 = (xz - wy) * sx;
|
|
var out4 = (xy - wz) * sy;
|
|
var out5 = (1 - (xx + zz)) * sy;
|
|
var out6 = (yz + wx) * sy;
|
|
var out8 = (xz + wy) * sz;
|
|
var out9 = (yz - wx) * sz;
|
|
var out10 = (1 - (xx + yy)) * sz;
|
|
out[0] = out0;
|
|
out[1] = out1;
|
|
out[2] = out2;
|
|
out[3] = 0;
|
|
out[4] = out4;
|
|
out[5] = out5;
|
|
out[6] = out6;
|
|
out[7] = 0;
|
|
out[8] = out8;
|
|
out[9] = out9;
|
|
out[10] = out10;
|
|
out[11] = 0;
|
|
out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz);
|
|
out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz);
|
|
out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz);
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function fromQuat$1(out, q) {
|
|
var x = q[0]
|
|
, y = q[1]
|
|
, z = q[2]
|
|
, w = q[3];
|
|
var x2 = x + x;
|
|
var y2 = y + y;
|
|
var z2 = z + z;
|
|
var xx = x * x2;
|
|
var yx = y * x2;
|
|
var yy = y * y2;
|
|
var zx = z * x2;
|
|
var zy = z * y2;
|
|
var zz = z * z2;
|
|
var wx = w * x2;
|
|
var wy = w * y2;
|
|
var wz = w * z2;
|
|
out[0] = 1 - yy - zz;
|
|
out[1] = yx + wz;
|
|
out[2] = zx - wy;
|
|
out[3] = 0;
|
|
out[4] = yx - wz;
|
|
out[5] = 1 - xx - zz;
|
|
out[6] = zy + wx;
|
|
out[7] = 0;
|
|
out[8] = zx + wy;
|
|
out[9] = zy - wx;
|
|
out[10] = 1 - xx - yy;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function frustum(out, left, right, bottom, top, near, far) {
|
|
var rl = 1 / (right - left);
|
|
var tb = 1 / (top - bottom);
|
|
var nf = 1 / (near - far);
|
|
out[0] = near * 2 * rl;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = near * 2 * tb;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = (right + left) * rl;
|
|
out[9] = (top + bottom) * tb;
|
|
out[10] = (far + near) * nf;
|
|
out[11] = -1;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = far * near * 2 * nf;
|
|
out[15] = 0;
|
|
return out
|
|
}
|
|
function perspective(out, fovy, aspect, near, far) {
|
|
var f = 1 / Math.tan(fovy / 2), nf;
|
|
out[0] = f / aspect;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = f;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[11] = -1;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[15] = 0;
|
|
if (far != null && far !== Infinity) {
|
|
nf = 1 / (near - far);
|
|
out[10] = (far + near) * nf;
|
|
out[14] = 2 * far * near * nf
|
|
} else {
|
|
out[10] = -1;
|
|
out[14] = -2 * near
|
|
}
|
|
return out
|
|
}
|
|
function perspectiveFromFieldOfView(out, fov, near, far) {
|
|
var upTan = Math.tan(fov.upDegrees * Math.PI / 180);
|
|
var downTan = Math.tan(fov.downDegrees * Math.PI / 180);
|
|
var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180);
|
|
var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180);
|
|
var xScale = 2 / (leftTan + rightTan);
|
|
var yScale = 2 / (upTan + downTan);
|
|
out[0] = xScale;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = yScale;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = -((leftTan - rightTan) * xScale * .5);
|
|
out[9] = (upTan - downTan) * yScale * .5;
|
|
out[10] = far / (near - far);
|
|
out[11] = -1;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = far * near / (near - far);
|
|
out[15] = 0;
|
|
return out
|
|
}
|
|
function ortho(out, left, right, bottom, top, near, far) {
|
|
var lr = 1 / (left - right);
|
|
var bt = 1 / (bottom - top);
|
|
var nf = 1 / (near - far);
|
|
out[0] = -2 * lr;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = -2 * bt;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 2 * nf;
|
|
out[11] = 0;
|
|
out[12] = (left + right) * lr;
|
|
out[13] = (top + bottom) * bt;
|
|
out[14] = (far + near) * nf;
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function lookAt(out, eye, center, up) {
|
|
var x0, x1, x2, y0, y1, y2, z0, z1, z2, len;
|
|
var eyex = eye[0];
|
|
var eyey = eye[1];
|
|
var eyez = eye[2];
|
|
var upx = up[0];
|
|
var upy = up[1];
|
|
var upz = up[2];
|
|
var centerx = center[0];
|
|
var centery = center[1];
|
|
var centerz = center[2];
|
|
if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON)
|
|
return identity$3(out);
|
|
z0 = eyex - centerx;
|
|
z1 = eyey - centery;
|
|
z2 = eyez - centerz;
|
|
len = 1 / Math.hypot(z0, z1, z2);
|
|
z0 *= len;
|
|
z1 *= len;
|
|
z2 *= len;
|
|
x0 = upy * z2 - upz * z1;
|
|
x1 = upz * z0 - upx * z2;
|
|
x2 = upx * z1 - upy * z0;
|
|
len = Math.hypot(x0, x1, x2);
|
|
if (!len) {
|
|
x0 = 0;
|
|
x1 = 0;
|
|
x2 = 0
|
|
} else {
|
|
len = 1 / len;
|
|
x0 *= len;
|
|
x1 *= len;
|
|
x2 *= len
|
|
}
|
|
y0 = z1 * x2 - z2 * x1;
|
|
y1 = z2 * x0 - z0 * x2;
|
|
y2 = z0 * x1 - z1 * x0;
|
|
len = Math.hypot(y0, y1, y2);
|
|
if (!len) {
|
|
y0 = 0;
|
|
y1 = 0;
|
|
y2 = 0
|
|
} else {
|
|
len = 1 / len;
|
|
y0 *= len;
|
|
y1 *= len;
|
|
y2 *= len
|
|
}
|
|
out[0] = x0;
|
|
out[1] = y0;
|
|
out[2] = z0;
|
|
out[3] = 0;
|
|
out[4] = x1;
|
|
out[5] = y1;
|
|
out[6] = z1;
|
|
out[7] = 0;
|
|
out[8] = x2;
|
|
out[9] = y2;
|
|
out[10] = z2;
|
|
out[11] = 0;
|
|
out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
|
|
out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
|
|
out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function targetTo(out, eye, target, up) {
|
|
var eyex = eye[0]
|
|
, eyey = eye[1]
|
|
, eyez = eye[2]
|
|
, upx = up[0]
|
|
, upy = up[1]
|
|
, upz = up[2];
|
|
var z0 = eyex - target[0]
|
|
, z1 = eyey - target[1]
|
|
, z2 = eyez - target[2];
|
|
var len = z0 * z0 + z1 * z1 + z2 * z2;
|
|
if (len > 0) {
|
|
len = 1 / Math.sqrt(len);
|
|
z0 *= len;
|
|
z1 *= len;
|
|
z2 *= len
|
|
}
|
|
var x0 = upy * z2 - upz * z1
|
|
, x1 = upz * z0 - upx * z2
|
|
, x2 = upx * z1 - upy * z0;
|
|
len = x0 * x0 + x1 * x1 + x2 * x2;
|
|
if (len > 0) {
|
|
len = 1 / Math.sqrt(len);
|
|
x0 *= len;
|
|
x1 *= len;
|
|
x2 *= len
|
|
}
|
|
out[0] = x0;
|
|
out[1] = x1;
|
|
out[2] = x2;
|
|
out[3] = 0;
|
|
out[4] = z1 * x2 - z2 * x1;
|
|
out[5] = z2 * x0 - z0 * x2;
|
|
out[6] = z0 * x1 - z1 * x0;
|
|
out[7] = 0;
|
|
out[8] = z0;
|
|
out[9] = z1;
|
|
out[10] = z2;
|
|
out[11] = 0;
|
|
out[12] = eyex;
|
|
out[13] = eyey;
|
|
out[14] = eyez;
|
|
out[15] = 1;
|
|
return out
|
|
}
|
|
function str$3(a) {
|
|
return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")"
|
|
}
|
|
function frob$3(a) {
|
|
return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15])
|
|
}
|
|
function add$3(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
out[2] = a[2] + b[2];
|
|
out[3] = a[3] + b[3];
|
|
out[4] = a[4] + b[4];
|
|
out[5] = a[5] + b[5];
|
|
out[6] = a[6] + b[6];
|
|
out[7] = a[7] + b[7];
|
|
out[8] = a[8] + b[8];
|
|
out[9] = a[9] + b[9];
|
|
out[10] = a[10] + b[10];
|
|
out[11] = a[11] + b[11];
|
|
out[12] = a[12] + b[12];
|
|
out[13] = a[13] + b[13];
|
|
out[14] = a[14] + b[14];
|
|
out[15] = a[15] + b[15];
|
|
return out
|
|
}
|
|
function subtract$3(out, a, b) {
|
|
out[0] = a[0] - b[0];
|
|
out[1] = a[1] - b[1];
|
|
out[2] = a[2] - b[2];
|
|
out[3] = a[3] - b[3];
|
|
out[4] = a[4] - b[4];
|
|
out[5] = a[5] - b[5];
|
|
out[6] = a[6] - b[6];
|
|
out[7] = a[7] - b[7];
|
|
out[8] = a[8] - b[8];
|
|
out[9] = a[9] - b[9];
|
|
out[10] = a[10] - b[10];
|
|
out[11] = a[11] - b[11];
|
|
out[12] = a[12] - b[12];
|
|
out[13] = a[13] - b[13];
|
|
out[14] = a[14] - b[14];
|
|
out[15] = a[15] - b[15];
|
|
return out
|
|
}
|
|
function multiplyScalar$3(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
out[2] = a[2] * b;
|
|
out[3] = a[3] * b;
|
|
out[4] = a[4] * b;
|
|
out[5] = a[5] * b;
|
|
out[6] = a[6] * b;
|
|
out[7] = a[7] * b;
|
|
out[8] = a[8] * b;
|
|
out[9] = a[9] * b;
|
|
out[10] = a[10] * b;
|
|
out[11] = a[11] * b;
|
|
out[12] = a[12] * b;
|
|
out[13] = a[13] * b;
|
|
out[14] = a[14] * b;
|
|
out[15] = a[15] * b;
|
|
return out
|
|
}
|
|
function multiplyScalarAndAdd$3(out, a, b, scale) {
|
|
out[0] = a[0] + b[0] * scale;
|
|
out[1] = a[1] + b[1] * scale;
|
|
out[2] = a[2] + b[2] * scale;
|
|
out[3] = a[3] + b[3] * scale;
|
|
out[4] = a[4] + b[4] * scale;
|
|
out[5] = a[5] + b[5] * scale;
|
|
out[6] = a[6] + b[6] * scale;
|
|
out[7] = a[7] + b[7] * scale;
|
|
out[8] = a[8] + b[8] * scale;
|
|
out[9] = a[9] + b[9] * scale;
|
|
out[10] = a[10] + b[10] * scale;
|
|
out[11] = a[11] + b[11] * scale;
|
|
out[12] = a[12] + b[12] * scale;
|
|
out[13] = a[13] + b[13] * scale;
|
|
out[14] = a[14] + b[14] * scale;
|
|
out[15] = a[15] + b[15] * scale;
|
|
return out
|
|
}
|
|
function exactEquals$3(a, b) {
|
|
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15]
|
|
}
|
|
function equals$4(a, b) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3];
|
|
var a4 = a[4]
|
|
, a5 = a[5]
|
|
, a6 = a[6]
|
|
, a7 = a[7];
|
|
var a8 = a[8]
|
|
, a9 = a[9]
|
|
, a10 = a[10]
|
|
, a11 = a[11];
|
|
var a12 = a[12]
|
|
, a13 = a[13]
|
|
, a14 = a[14]
|
|
, a15 = a[15];
|
|
var b0 = b[0]
|
|
, b1 = b[1]
|
|
, b2 = b[2]
|
|
, b3 = b[3];
|
|
var b4 = b[4]
|
|
, b5 = b[5]
|
|
, b6 = b[6]
|
|
, b7 = b[7];
|
|
var b8 = b[8]
|
|
, b9 = b[9]
|
|
, b10 = b[10]
|
|
, b11 = b[11];
|
|
var b12 = b[12]
|
|
, b13 = b[13]
|
|
, b14 = b[14]
|
|
, b15 = b[15];
|
|
return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= EPSILON * Math.max(1, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= EPSILON * Math.max(1, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= EPSILON * Math.max(1, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= EPSILON * Math.max(1, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= EPSILON * Math.max(1, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= EPSILON * Math.max(1, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= EPSILON * Math.max(1, Math.abs(a15), Math.abs(b15))
|
|
}
|
|
var mul$3 = multiply$3;
|
|
var sub$3 = subtract$3;
|
|
var mat4 = Object.freeze({
|
|
__proto__: null,
|
|
create: create$3,
|
|
clone: clone$3,
|
|
copy: copy$3,
|
|
fromValues: fromValues$3,
|
|
set: set$3,
|
|
identity: identity$3,
|
|
transpose: transpose$2,
|
|
invert: invert$3,
|
|
adjoint: adjoint$2,
|
|
determinant: determinant$3,
|
|
multiply: multiply$3,
|
|
translate: translate$2,
|
|
scale: scale$3,
|
|
rotate: rotate$3,
|
|
rotateX: rotateX,
|
|
rotateY: rotateY,
|
|
rotateZ: rotateZ,
|
|
fromTranslation: fromTranslation$2,
|
|
fromScaling: fromScaling$3,
|
|
fromRotation: fromRotation$3,
|
|
fromXRotation: fromXRotation,
|
|
fromYRotation: fromYRotation,
|
|
fromZRotation: fromZRotation,
|
|
fromRotationTranslation: fromRotationTranslation,
|
|
fromQuat2: fromQuat2,
|
|
getTranslation: getTranslation,
|
|
getScaling: getScaling,
|
|
getRotation: getRotation,
|
|
fromRotationTranslationScale: fromRotationTranslationScale,
|
|
fromRotationTranslationScaleOrigin: fromRotationTranslationScaleOrigin,
|
|
fromQuat: fromQuat$1,
|
|
frustum: frustum,
|
|
perspective: perspective,
|
|
perspectiveFromFieldOfView: perspectiveFromFieldOfView,
|
|
ortho: ortho,
|
|
lookAt: lookAt,
|
|
targetTo: targetTo,
|
|
str: str$3,
|
|
frob: frob$3,
|
|
add: add$3,
|
|
subtract: subtract$3,
|
|
multiplyScalar: multiplyScalar$3,
|
|
multiplyScalarAndAdd: multiplyScalarAndAdd$3,
|
|
exactEquals: exactEquals$3,
|
|
equals: equals$4,
|
|
mul: mul$3,
|
|
sub: sub$3
|
|
});
|
|
function create$4() {
|
|
var out = new ARRAY_TYPE(3);
|
|
if (ARRAY_TYPE != Float32Array) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0
|
|
}
|
|
return out
|
|
}
|
|
function clone$4(a) {
|
|
var out = new ARRAY_TYPE(3);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
return out
|
|
}
|
|
function length(a) {
|
|
var x = a[0];
|
|
var y = a[1];
|
|
var z = a[2];
|
|
return Math.hypot(x, y, z)
|
|
}
|
|
function fromValues$4(x, y, z) {
|
|
var out = new ARRAY_TYPE(3);
|
|
out[0] = x;
|
|
out[1] = y;
|
|
out[2] = z;
|
|
return out
|
|
}
|
|
function copy$4(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
return out
|
|
}
|
|
function set$4(out, x, y, z) {
|
|
out[0] = x;
|
|
out[1] = y;
|
|
out[2] = z;
|
|
return out
|
|
}
|
|
function add$4(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
out[2] = a[2] + b[2];
|
|
return out
|
|
}
|
|
function subtract$4(out, a, b) {
|
|
out[0] = a[0] - b[0];
|
|
out[1] = a[1] - b[1];
|
|
out[2] = a[2] - b[2];
|
|
return out
|
|
}
|
|
function multiply$4(out, a, b) {
|
|
out[0] = a[0] * b[0];
|
|
out[1] = a[1] * b[1];
|
|
out[2] = a[2] * b[2];
|
|
return out
|
|
}
|
|
function divide(out, a, b) {
|
|
out[0] = a[0] / b[0];
|
|
out[1] = a[1] / b[1];
|
|
out[2] = a[2] / b[2];
|
|
return out
|
|
}
|
|
function ceil(out, a) {
|
|
out[0] = Math.ceil(a[0]);
|
|
out[1] = Math.ceil(a[1]);
|
|
out[2] = Math.ceil(a[2]);
|
|
return out
|
|
}
|
|
function floor(out, a) {
|
|
out[0] = Math.floor(a[0]);
|
|
out[1] = Math.floor(a[1]);
|
|
out[2] = Math.floor(a[2]);
|
|
return out
|
|
}
|
|
function min(out, a, b) {
|
|
out[0] = Math.min(a[0], b[0]);
|
|
out[1] = Math.min(a[1], b[1]);
|
|
out[2] = Math.min(a[2], b[2]);
|
|
return out
|
|
}
|
|
function max(out, a, b) {
|
|
out[0] = Math.max(a[0], b[0]);
|
|
out[1] = Math.max(a[1], b[1]);
|
|
out[2] = Math.max(a[2], b[2]);
|
|
return out
|
|
}
|
|
function round(out, a) {
|
|
out[0] = Math.round(a[0]);
|
|
out[1] = Math.round(a[1]);
|
|
out[2] = Math.round(a[2]);
|
|
return out
|
|
}
|
|
function scale$4(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
out[2] = a[2] * b;
|
|
return out
|
|
}
|
|
function scaleAndAdd(out, a, b, scale) {
|
|
out[0] = a[0] + b[0] * scale;
|
|
out[1] = a[1] + b[1] * scale;
|
|
out[2] = a[2] + b[2] * scale;
|
|
return out
|
|
}
|
|
function distance(a, b) {
|
|
var x = b[0] - a[0];
|
|
var y = b[1] - a[1];
|
|
var z = b[2] - a[2];
|
|
return Math.hypot(x, y, z)
|
|
}
|
|
function squaredDistance(a, b) {
|
|
var x = b[0] - a[0];
|
|
var y = b[1] - a[1];
|
|
var z = b[2] - a[2];
|
|
return x * x + y * y + z * z
|
|
}
|
|
function squaredLength(a) {
|
|
var x = a[0];
|
|
var y = a[1];
|
|
var z = a[2];
|
|
return x * x + y * y + z * z
|
|
}
|
|
function negate(out, a) {
|
|
out[0] = -a[0];
|
|
out[1] = -a[1];
|
|
out[2] = -a[2];
|
|
return out
|
|
}
|
|
function inverse(out, a) {
|
|
out[0] = 1 / a[0];
|
|
out[1] = 1 / a[1];
|
|
out[2] = 1 / a[2];
|
|
return out
|
|
}
|
|
function normalize(out, a) {
|
|
var x = a[0];
|
|
var y = a[1];
|
|
var z = a[2];
|
|
var len = x * x + y * y + z * z;
|
|
if (len > 0)
|
|
len = 1 / Math.sqrt(len);
|
|
out[0] = a[0] * len;
|
|
out[1] = a[1] * len;
|
|
out[2] = a[2] * len;
|
|
return out
|
|
}
|
|
function dot(a, b) {
|
|
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
|
|
}
|
|
function cross(out, a, b) {
|
|
var ax = a[0]
|
|
, ay = a[1]
|
|
, az = a[2];
|
|
var bx = b[0]
|
|
, by = b[1]
|
|
, bz = b[2];
|
|
out[0] = ay * bz - az * by;
|
|
out[1] = az * bx - ax * bz;
|
|
out[2] = ax * by - ay * bx;
|
|
return out
|
|
}
|
|
function lerp(out, a, b, t) {
|
|
var ax = a[0];
|
|
var ay = a[1];
|
|
var az = a[2];
|
|
out[0] = ax + t * (b[0] - ax);
|
|
out[1] = ay + t * (b[1] - ay);
|
|
out[2] = az + t * (b[2] - az);
|
|
return out
|
|
}
|
|
function hermite(out, a, b, c, d, t) {
|
|
var factorTimes2 = t * t;
|
|
var factor1 = factorTimes2 * (2 * t - 3) + 1;
|
|
var factor2 = factorTimes2 * (t - 2) + t;
|
|
var factor3 = factorTimes2 * (t - 1);
|
|
var factor4 = factorTimes2 * (3 - 2 * t);
|
|
out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
|
|
out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
|
|
out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
|
|
return out
|
|
}
|
|
function bezier(out, a, b, c, d, t) {
|
|
var inverseFactor = 1 - t;
|
|
var inverseFactorTimesTwo = inverseFactor * inverseFactor;
|
|
var factorTimes2 = t * t;
|
|
var factor1 = inverseFactorTimesTwo * inverseFactor;
|
|
var factor2 = 3 * t * inverseFactorTimesTwo;
|
|
var factor3 = 3 * factorTimes2 * inverseFactor;
|
|
var factor4 = factorTimes2 * t;
|
|
out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
|
|
out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
|
|
out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
|
|
return out
|
|
}
|
|
function random(out, scale) {
|
|
scale = scale || 1;
|
|
var r = RANDOM() * 2 * Math.PI;
|
|
var z = RANDOM() * 2 - 1;
|
|
var zScale = Math.sqrt(1 - z * z) * scale;
|
|
out[0] = Math.cos(r) * zScale;
|
|
out[1] = Math.sin(r) * zScale;
|
|
out[2] = z * scale;
|
|
return out
|
|
}
|
|
function transformMat4(out, a, m) {
|
|
var x = a[0]
|
|
, y = a[1]
|
|
, z = a[2];
|
|
var w = m[3] * x + m[7] * y + m[11] * z + m[15];
|
|
w = w || 1;
|
|
out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
|
|
out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
|
|
out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
|
|
return out
|
|
}
|
|
function transformMat3(out, a, m) {
|
|
var x = a[0]
|
|
, y = a[1]
|
|
, z = a[2];
|
|
out[0] = x * m[0] + y * m[3] + z * m[6];
|
|
out[1] = x * m[1] + y * m[4] + z * m[7];
|
|
out[2] = x * m[2] + y * m[5] + z * m[8];
|
|
return out
|
|
}
|
|
function transformQuat(out, a, q) {
|
|
var qx = q[0]
|
|
, qy = q[1]
|
|
, qz = q[2]
|
|
, qw = q[3];
|
|
var x = a[0]
|
|
, y = a[1]
|
|
, z = a[2];
|
|
var uvx = qy * z - qz * y
|
|
, uvy = qz * x - qx * z
|
|
, uvz = qx * y - qy * x;
|
|
var uuvx = qy * uvz - qz * uvy
|
|
, uuvy = qz * uvx - qx * uvz
|
|
, uuvz = qx * uvy - qy * uvx;
|
|
var w2 = qw * 2;
|
|
uvx *= w2;
|
|
uvy *= w2;
|
|
uvz *= w2;
|
|
uuvx *= 2;
|
|
uuvy *= 2;
|
|
uuvz *= 2;
|
|
out[0] = x + uvx + uuvx;
|
|
out[1] = y + uvy + uuvy;
|
|
out[2] = z + uvz + uuvz;
|
|
return out
|
|
}
|
|
function rotateX$1(out, a, b, rad) {
|
|
var p = []
|
|
, r = [];
|
|
p[0] = a[0] - b[0];
|
|
p[1] = a[1] - b[1];
|
|
p[2] = a[2] - b[2];
|
|
r[0] = p[0];
|
|
r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad);
|
|
r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad);
|
|
out[0] = r[0] + b[0];
|
|
out[1] = r[1] + b[1];
|
|
out[2] = r[2] + b[2];
|
|
return out
|
|
}
|
|
function rotateY$1(out, a, b, rad) {
|
|
var p = []
|
|
, r = [];
|
|
p[0] = a[0] - b[0];
|
|
p[1] = a[1] - b[1];
|
|
p[2] = a[2] - b[2];
|
|
r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad);
|
|
r[1] = p[1];
|
|
r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad);
|
|
out[0] = r[0] + b[0];
|
|
out[1] = r[1] + b[1];
|
|
out[2] = r[2] + b[2];
|
|
return out
|
|
}
|
|
function rotateZ$1(out, a, b, rad) {
|
|
var p = []
|
|
, r = [];
|
|
p[0] = a[0] - b[0];
|
|
p[1] = a[1] - b[1];
|
|
p[2] = a[2] - b[2];
|
|
r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad);
|
|
r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad);
|
|
r[2] = p[2];
|
|
out[0] = r[0] + b[0];
|
|
out[1] = r[1] + b[1];
|
|
out[2] = r[2] + b[2];
|
|
return out
|
|
}
|
|
function angle(a, b) {
|
|
var ax = a[0]
|
|
, ay = a[1]
|
|
, az = a[2]
|
|
, bx = b[0]
|
|
, by = b[1]
|
|
, bz = b[2]
|
|
, mag1 = Math.sqrt(ax * ax + ay * ay + az * az)
|
|
, mag2 = Math.sqrt(bx * bx + by * by + bz * bz)
|
|
, mag = mag1 * mag2
|
|
, cosine = mag && dot(a, b) / mag;
|
|
return Math.acos(Math.min(Math.max(cosine, -1), 1))
|
|
}
|
|
function zero(out) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
return out
|
|
}
|
|
function str$4(a) {
|
|
return "vec3(" + a[0] + ", " + a[1] + ", " + a[2] + ")"
|
|
}
|
|
function exactEquals$4(a, b) {
|
|
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2]
|
|
}
|
|
function equals$5(a, b) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2];
|
|
var b0 = b[0]
|
|
, b1 = b[1]
|
|
, b2 = b[2];
|
|
return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2))
|
|
}
|
|
var sub$4 = subtract$4;
|
|
var mul$4 = multiply$4;
|
|
var div = divide;
|
|
var dist = distance;
|
|
var sqrDist = squaredDistance;
|
|
var len = length;
|
|
var sqrLen = squaredLength;
|
|
var forEach = function() {
|
|
var vec = create$4();
|
|
return function(a, stride, offset, count, fn, arg) {
|
|
var i, l;
|
|
if (!stride)
|
|
stride = 3;
|
|
if (!offset)
|
|
offset = 0;
|
|
if (count)
|
|
l = Math.min(count * stride + offset, a.length);
|
|
else
|
|
l = a.length;
|
|
for (i = offset; i < l; i += stride) {
|
|
vec[0] = a[i];
|
|
vec[1] = a[i + 1];
|
|
vec[2] = a[i + 2];
|
|
fn(vec, vec, arg);
|
|
a[i] = vec[0];
|
|
a[i + 1] = vec[1];
|
|
a[i + 2] = vec[2]
|
|
}
|
|
return a
|
|
}
|
|
}();
|
|
var vec3 = Object.freeze({
|
|
__proto__: null,
|
|
create: create$4,
|
|
clone: clone$4,
|
|
length: length,
|
|
fromValues: fromValues$4,
|
|
copy: copy$4,
|
|
set: set$4,
|
|
add: add$4,
|
|
subtract: subtract$4,
|
|
multiply: multiply$4,
|
|
divide: divide,
|
|
ceil: ceil,
|
|
floor: floor,
|
|
min: min,
|
|
max: max,
|
|
round: round,
|
|
scale: scale$4,
|
|
scaleAndAdd: scaleAndAdd,
|
|
distance: distance,
|
|
squaredDistance: squaredDistance,
|
|
squaredLength: squaredLength,
|
|
negate: negate,
|
|
inverse: inverse,
|
|
normalize: normalize,
|
|
dot: dot,
|
|
cross: cross,
|
|
lerp: lerp,
|
|
hermite: hermite,
|
|
bezier: bezier,
|
|
random: random,
|
|
transformMat4: transformMat4,
|
|
transformMat3: transformMat3,
|
|
transformQuat: transformQuat,
|
|
rotateX: rotateX$1,
|
|
rotateY: rotateY$1,
|
|
rotateZ: rotateZ$1,
|
|
angle: angle,
|
|
zero: zero,
|
|
str: str$4,
|
|
exactEquals: exactEquals$4,
|
|
equals: equals$5,
|
|
sub: sub$4,
|
|
mul: mul$4,
|
|
div: div,
|
|
dist: dist,
|
|
sqrDist: sqrDist,
|
|
len: len,
|
|
sqrLen: sqrLen,
|
|
forEach: forEach
|
|
});
|
|
function create$5() {
|
|
var out = new ARRAY_TYPE(4);
|
|
if (ARRAY_TYPE != Float32Array) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0
|
|
}
|
|
return out
|
|
}
|
|
function clone$5(a) {
|
|
var out = new ARRAY_TYPE(4);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
return out
|
|
}
|
|
function fromValues$5(x, y, z, w) {
|
|
var out = new ARRAY_TYPE(4);
|
|
out[0] = x;
|
|
out[1] = y;
|
|
out[2] = z;
|
|
out[3] = w;
|
|
return out
|
|
}
|
|
function copy$5(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
return out
|
|
}
|
|
function set$5(out, x, y, z, w) {
|
|
out[0] = x;
|
|
out[1] = y;
|
|
out[2] = z;
|
|
out[3] = w;
|
|
return out
|
|
}
|
|
function add$5(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
out[2] = a[2] + b[2];
|
|
out[3] = a[3] + b[3];
|
|
return out
|
|
}
|
|
function subtract$5(out, a, b) {
|
|
out[0] = a[0] - b[0];
|
|
out[1] = a[1] - b[1];
|
|
out[2] = a[2] - b[2];
|
|
out[3] = a[3] - b[3];
|
|
return out
|
|
}
|
|
function multiply$5(out, a, b) {
|
|
out[0] = a[0] * b[0];
|
|
out[1] = a[1] * b[1];
|
|
out[2] = a[2] * b[2];
|
|
out[3] = a[3] * b[3];
|
|
return out
|
|
}
|
|
function divide$1(out, a, b) {
|
|
out[0] = a[0] / b[0];
|
|
out[1] = a[1] / b[1];
|
|
out[2] = a[2] / b[2];
|
|
out[3] = a[3] / b[3];
|
|
return out
|
|
}
|
|
function ceil$1(out, a) {
|
|
out[0] = Math.ceil(a[0]);
|
|
out[1] = Math.ceil(a[1]);
|
|
out[2] = Math.ceil(a[2]);
|
|
out[3] = Math.ceil(a[3]);
|
|
return out
|
|
}
|
|
function floor$1(out, a) {
|
|
out[0] = Math.floor(a[0]);
|
|
out[1] = Math.floor(a[1]);
|
|
out[2] = Math.floor(a[2]);
|
|
out[3] = Math.floor(a[3]);
|
|
return out
|
|
}
|
|
function min$1(out, a, b) {
|
|
out[0] = Math.min(a[0], b[0]);
|
|
out[1] = Math.min(a[1], b[1]);
|
|
out[2] = Math.min(a[2], b[2]);
|
|
out[3] = Math.min(a[3], b[3]);
|
|
return out
|
|
}
|
|
function max$1(out, a, b) {
|
|
out[0] = Math.max(a[0], b[0]);
|
|
out[1] = Math.max(a[1], b[1]);
|
|
out[2] = Math.max(a[2], b[2]);
|
|
out[3] = Math.max(a[3], b[3]);
|
|
return out
|
|
}
|
|
function round$1(out, a) {
|
|
out[0] = Math.round(a[0]);
|
|
out[1] = Math.round(a[1]);
|
|
out[2] = Math.round(a[2]);
|
|
out[3] = Math.round(a[3]);
|
|
return out
|
|
}
|
|
function scale$5(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
out[2] = a[2] * b;
|
|
out[3] = a[3] * b;
|
|
return out
|
|
}
|
|
function scaleAndAdd$1(out, a, b, scale) {
|
|
out[0] = a[0] + b[0] * scale;
|
|
out[1] = a[1] + b[1] * scale;
|
|
out[2] = a[2] + b[2] * scale;
|
|
out[3] = a[3] + b[3] * scale;
|
|
return out
|
|
}
|
|
function distance$1(a, b) {
|
|
var x = b[0] - a[0];
|
|
var y = b[1] - a[1];
|
|
var z = b[2] - a[2];
|
|
var w = b[3] - a[3];
|
|
return Math.hypot(x, y, z, w)
|
|
}
|
|
function squaredDistance$1(a, b) {
|
|
var x = b[0] - a[0];
|
|
var y = b[1] - a[1];
|
|
var z = b[2] - a[2];
|
|
var w = b[3] - a[3];
|
|
return x * x + y * y + z * z + w * w
|
|
}
|
|
function length$1(a) {
|
|
var x = a[0];
|
|
var y = a[1];
|
|
var z = a[2];
|
|
var w = a[3];
|
|
return Math.hypot(x, y, z, w)
|
|
}
|
|
function squaredLength$1(a) {
|
|
var x = a[0];
|
|
var y = a[1];
|
|
var z = a[2];
|
|
var w = a[3];
|
|
return x * x + y * y + z * z + w * w
|
|
}
|
|
function negate$1(out, a) {
|
|
out[0] = -a[0];
|
|
out[1] = -a[1];
|
|
out[2] = -a[2];
|
|
out[3] = -a[3];
|
|
return out
|
|
}
|
|
function inverse$1(out, a) {
|
|
out[0] = 1 / a[0];
|
|
out[1] = 1 / a[1];
|
|
out[2] = 1 / a[2];
|
|
out[3] = 1 / a[3];
|
|
return out
|
|
}
|
|
function normalize$1(out, a) {
|
|
var x = a[0];
|
|
var y = a[1];
|
|
var z = a[2];
|
|
var w = a[3];
|
|
var len = x * x + y * y + z * z + w * w;
|
|
if (len > 0)
|
|
len = 1 / Math.sqrt(len);
|
|
out[0] = x * len;
|
|
out[1] = y * len;
|
|
out[2] = z * len;
|
|
out[3] = w * len;
|
|
return out
|
|
}
|
|
function dot$1(a, b) {
|
|
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
|
|
}
|
|
function cross$1(out, u, v, w) {
|
|
var A = v[0] * w[1] - v[1] * w[0]
|
|
, B = v[0] * w[2] - v[2] * w[0]
|
|
, C = v[0] * w[3] - v[3] * w[0]
|
|
, D = v[1] * w[2] - v[2] * w[1]
|
|
, E = v[1] * w[3] - v[3] * w[1]
|
|
, F = v[2] * w[3] - v[3] * w[2];
|
|
var G = u[0];
|
|
var H = u[1];
|
|
var I = u[2];
|
|
var J = u[3];
|
|
out[0] = H * F - I * E + J * D;
|
|
out[1] = -(G * F) + I * C - J * B;
|
|
out[2] = G * E - H * C + J * A;
|
|
out[3] = -(G * D) + H * B - I * A;
|
|
return out
|
|
}
|
|
function lerp$1(out, a, b, t) {
|
|
var ax = a[0];
|
|
var ay = a[1];
|
|
var az = a[2];
|
|
var aw = a[3];
|
|
out[0] = ax + t * (b[0] - ax);
|
|
out[1] = ay + t * (b[1] - ay);
|
|
out[2] = az + t * (b[2] - az);
|
|
out[3] = aw + t * (b[3] - aw);
|
|
return out
|
|
}
|
|
function random$1(out, scale) {
|
|
scale = scale || 1;
|
|
var v1, v2, v3, v4;
|
|
var s1, s2;
|
|
do {
|
|
v1 = RANDOM() * 2 - 1;
|
|
v2 = RANDOM() * 2 - 1;
|
|
s1 = v1 * v1 + v2 * v2
|
|
} while (s1 >= 1);
|
|
do {
|
|
v3 = RANDOM() * 2 - 1;
|
|
v4 = RANDOM() * 2 - 1;
|
|
s2 = v3 * v3 + v4 * v4
|
|
} while (s2 >= 1);
|
|
var d = Math.sqrt((1 - s1) / s2);
|
|
out[0] = scale * v1;
|
|
out[1] = scale * v2;
|
|
out[2] = scale * v3 * d;
|
|
out[3] = scale * v4 * d;
|
|
return out
|
|
}
|
|
function transformMat4$1(out, a, m) {
|
|
var x = a[0]
|
|
, y = a[1]
|
|
, z = a[2]
|
|
, w = a[3];
|
|
out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
|
|
out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
|
|
out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
|
|
out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
|
|
return out
|
|
}
|
|
function transformQuat$1(out, a, q) {
|
|
var x = a[0]
|
|
, y = a[1]
|
|
, z = a[2];
|
|
var qx = q[0]
|
|
, qy = q[1]
|
|
, qz = q[2]
|
|
, qw = q[3];
|
|
var ix = qw * x + qy * z - qz * y;
|
|
var iy = qw * y + qz * x - qx * z;
|
|
var iz = qw * z + qx * y - qy * x;
|
|
var iw = -qx * x - qy * y - qz * z;
|
|
out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
|
|
out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
|
|
out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
|
|
out[3] = a[3];
|
|
return out
|
|
}
|
|
function zero$1(out) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
return out
|
|
}
|
|
function str$5(a) {
|
|
return "vec4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"
|
|
}
|
|
function exactEquals$5(a, b) {
|
|
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]
|
|
}
|
|
function equals$6(a, b) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3];
|
|
var b0 = b[0]
|
|
, b1 = b[1]
|
|
, b2 = b[2]
|
|
, b3 = b[3];
|
|
return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1, Math.abs(a3), Math.abs(b3))
|
|
}
|
|
var sub$5 = subtract$5;
|
|
var mul$5 = multiply$5;
|
|
var div$1 = divide$1;
|
|
var dist$1 = distance$1;
|
|
var sqrDist$1 = squaredDistance$1;
|
|
var len$1 = length$1;
|
|
var sqrLen$1 = squaredLength$1;
|
|
var forEach$1 = function() {
|
|
var vec = create$5();
|
|
return function(a, stride, offset, count, fn, arg) {
|
|
var i, l;
|
|
if (!stride)
|
|
stride = 4;
|
|
if (!offset)
|
|
offset = 0;
|
|
if (count)
|
|
l = Math.min(count * stride + offset, a.length);
|
|
else
|
|
l = a.length;
|
|
for (i = offset; i < l; i += stride) {
|
|
vec[0] = a[i];
|
|
vec[1] = a[i + 1];
|
|
vec[2] = a[i + 2];
|
|
vec[3] = a[i + 3];
|
|
fn(vec, vec, arg);
|
|
a[i] = vec[0];
|
|
a[i + 1] = vec[1];
|
|
a[i + 2] = vec[2];
|
|
a[i + 3] = vec[3]
|
|
}
|
|
return a
|
|
}
|
|
}();
|
|
var vec4 = Object.freeze({
|
|
__proto__: null,
|
|
create: create$5,
|
|
clone: clone$5,
|
|
fromValues: fromValues$5,
|
|
copy: copy$5,
|
|
set: set$5,
|
|
add: add$5,
|
|
subtract: subtract$5,
|
|
multiply: multiply$5,
|
|
divide: divide$1,
|
|
ceil: ceil$1,
|
|
floor: floor$1,
|
|
min: min$1,
|
|
max: max$1,
|
|
round: round$1,
|
|
scale: scale$5,
|
|
scaleAndAdd: scaleAndAdd$1,
|
|
distance: distance$1,
|
|
squaredDistance: squaredDistance$1,
|
|
length: length$1,
|
|
squaredLength: squaredLength$1,
|
|
negate: negate$1,
|
|
inverse: inverse$1,
|
|
normalize: normalize$1,
|
|
dot: dot$1,
|
|
cross: cross$1,
|
|
lerp: lerp$1,
|
|
random: random$1,
|
|
transformMat4: transformMat4$1,
|
|
transformQuat: transformQuat$1,
|
|
zero: zero$1,
|
|
str: str$5,
|
|
exactEquals: exactEquals$5,
|
|
equals: equals$6,
|
|
sub: sub$5,
|
|
mul: mul$5,
|
|
div: div$1,
|
|
dist: dist$1,
|
|
sqrDist: sqrDist$1,
|
|
len: len$1,
|
|
sqrLen: sqrLen$1,
|
|
forEach: forEach$1
|
|
});
|
|
function create$6() {
|
|
var out = new ARRAY_TYPE(4);
|
|
if (ARRAY_TYPE != Float32Array) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0
|
|
}
|
|
out[3] = 1;
|
|
return out
|
|
}
|
|
function identity$4(out) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
return out
|
|
}
|
|
function setAxisAngle(out, axis, rad) {
|
|
rad = rad * .5;
|
|
var s = Math.sin(rad);
|
|
out[0] = s * axis[0];
|
|
out[1] = s * axis[1];
|
|
out[2] = s * axis[2];
|
|
out[3] = Math.cos(rad);
|
|
return out
|
|
}
|
|
function getAxisAngle(out_axis, q) {
|
|
var rad = Math.acos(q[3]) * 2;
|
|
var s = Math.sin(rad / 2);
|
|
if (s > EPSILON) {
|
|
out_axis[0] = q[0] / s;
|
|
out_axis[1] = q[1] / s;
|
|
out_axis[2] = q[2] / s
|
|
} else {
|
|
out_axis[0] = 1;
|
|
out_axis[1] = 0;
|
|
out_axis[2] = 0
|
|
}
|
|
return rad
|
|
}
|
|
function getAngle(a, b) {
|
|
var dotproduct = dot$2(a, b);
|
|
return Math.acos(2 * dotproduct * dotproduct - 1)
|
|
}
|
|
function multiply$6(out, a, b) {
|
|
var ax = a[0]
|
|
, ay = a[1]
|
|
, az = a[2]
|
|
, aw = a[3];
|
|
var bx = b[0]
|
|
, by = b[1]
|
|
, bz = b[2]
|
|
, bw = b[3];
|
|
out[0] = ax * bw + aw * bx + ay * bz - az * by;
|
|
out[1] = ay * bw + aw * by + az * bx - ax * bz;
|
|
out[2] = az * bw + aw * bz + ax * by - ay * bx;
|
|
out[3] = aw * bw - ax * bx - ay * by - az * bz;
|
|
return out
|
|
}
|
|
function rotateX$2(out, a, rad) {
|
|
rad *= .5;
|
|
var ax = a[0]
|
|
, ay = a[1]
|
|
, az = a[2]
|
|
, aw = a[3];
|
|
var bx = Math.sin(rad)
|
|
, bw = Math.cos(rad);
|
|
out[0] = ax * bw + aw * bx;
|
|
out[1] = ay * bw + az * bx;
|
|
out[2] = az * bw - ay * bx;
|
|
out[3] = aw * bw - ax * bx;
|
|
return out
|
|
}
|
|
function rotateY$2(out, a, rad) {
|
|
rad *= .5;
|
|
var ax = a[0]
|
|
, ay = a[1]
|
|
, az = a[2]
|
|
, aw = a[3];
|
|
var by = Math.sin(rad)
|
|
, bw = Math.cos(rad);
|
|
out[0] = ax * bw - az * by;
|
|
out[1] = ay * bw + aw * by;
|
|
out[2] = az * bw + ax * by;
|
|
out[3] = aw * bw - ay * by;
|
|
return out
|
|
}
|
|
function rotateZ$2(out, a, rad) {
|
|
rad *= .5;
|
|
var ax = a[0]
|
|
, ay = a[1]
|
|
, az = a[2]
|
|
, aw = a[3];
|
|
var bz = Math.sin(rad)
|
|
, bw = Math.cos(rad);
|
|
out[0] = ax * bw + ay * bz;
|
|
out[1] = ay * bw - ax * bz;
|
|
out[2] = az * bw + aw * bz;
|
|
out[3] = aw * bw - az * bz;
|
|
return out
|
|
}
|
|
function calculateW(out, a) {
|
|
var x = a[0]
|
|
, y = a[1]
|
|
, z = a[2];
|
|
out[0] = x;
|
|
out[1] = y;
|
|
out[2] = z;
|
|
out[3] = Math.sqrt(Math.abs(1 - x * x - y * y - z * z));
|
|
return out
|
|
}
|
|
function exp(out, a) {
|
|
var x = a[0]
|
|
, y = a[1]
|
|
, z = a[2]
|
|
, w = a[3];
|
|
var r = Math.sqrt(x * x + y * y + z * z);
|
|
var et = Math.exp(w);
|
|
var s = r > 0 ? et * Math.sin(r) / r : 0;
|
|
out[0] = x * s;
|
|
out[1] = y * s;
|
|
out[2] = z * s;
|
|
out[3] = et * Math.cos(r);
|
|
return out
|
|
}
|
|
function ln(out, a) {
|
|
var x = a[0]
|
|
, y = a[1]
|
|
, z = a[2]
|
|
, w = a[3];
|
|
var r = Math.sqrt(x * x + y * y + z * z);
|
|
var t = r > 0 ? Math.atan2(r, w) / r : 0;
|
|
out[0] = x * t;
|
|
out[1] = y * t;
|
|
out[2] = z * t;
|
|
out[3] = .5 * Math.log(x * x + y * y + z * z + w * w);
|
|
return out
|
|
}
|
|
function pow(out, a, b) {
|
|
ln(out, a);
|
|
scale$6(out, out, b);
|
|
exp(out, out);
|
|
return out
|
|
}
|
|
function slerp(out, a, b, t) {
|
|
var ax = a[0]
|
|
, ay = a[1]
|
|
, az = a[2]
|
|
, aw = a[3];
|
|
var bx = b[0]
|
|
, by = b[1]
|
|
, bz = b[2]
|
|
, bw = b[3];
|
|
var omega, cosom, sinom, scale0, scale1;
|
|
cosom = ax * bx + ay * by + az * bz + aw * bw;
|
|
if (cosom < 0) {
|
|
cosom = -cosom;
|
|
bx = -bx;
|
|
by = -by;
|
|
bz = -bz;
|
|
bw = -bw
|
|
}
|
|
if (1 - cosom > EPSILON) {
|
|
omega = Math.acos(cosom);
|
|
sinom = Math.sin(omega);
|
|
scale0 = Math.sin((1 - t) * omega) / sinom;
|
|
scale1 = Math.sin(t * omega) / sinom
|
|
} else {
|
|
scale0 = 1 - t;
|
|
scale1 = t
|
|
}
|
|
out[0] = scale0 * ax + scale1 * bx;
|
|
out[1] = scale0 * ay + scale1 * by;
|
|
out[2] = scale0 * az + scale1 * bz;
|
|
out[3] = scale0 * aw + scale1 * bw;
|
|
return out
|
|
}
|
|
function random$2(out) {
|
|
var u1 = RANDOM();
|
|
var u2 = RANDOM();
|
|
var u3 = RANDOM();
|
|
var sqrt1MinusU1 = Math.sqrt(1 - u1);
|
|
var sqrtU1 = Math.sqrt(u1);
|
|
out[0] = sqrt1MinusU1 * Math.sin(2 * Math.PI * u2);
|
|
out[1] = sqrt1MinusU1 * Math.cos(2 * Math.PI * u2);
|
|
out[2] = sqrtU1 * Math.sin(2 * Math.PI * u3);
|
|
out[3] = sqrtU1 * Math.cos(2 * Math.PI * u3);
|
|
return out
|
|
}
|
|
function invert$4(out, a) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3];
|
|
var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
|
|
var invDot = dot ? 1 / dot : 0;
|
|
out[0] = -a0 * invDot;
|
|
out[1] = -a1 * invDot;
|
|
out[2] = -a2 * invDot;
|
|
out[3] = a3 * invDot;
|
|
return out
|
|
}
|
|
function conjugate(out, a) {
|
|
out[0] = -a[0];
|
|
out[1] = -a[1];
|
|
out[2] = -a[2];
|
|
out[3] = a[3];
|
|
return out
|
|
}
|
|
function fromMat3(out, m) {
|
|
var fTrace = m[0] + m[4] + m[8];
|
|
var fRoot;
|
|
if (fTrace > 0) {
|
|
fRoot = Math.sqrt(fTrace + 1);
|
|
out[3] = .5 * fRoot;
|
|
fRoot = .5 / fRoot;
|
|
out[0] = (m[5] - m[7]) * fRoot;
|
|
out[1] = (m[6] - m[2]) * fRoot;
|
|
out[2] = (m[1] - m[3]) * fRoot
|
|
} else {
|
|
var i = 0;
|
|
if (m[4] > m[0])
|
|
i = 1;
|
|
if (m[8] > m[i * 3 + i])
|
|
i = 2;
|
|
var j = (i + 1) % 3;
|
|
var k = (i + 2) % 3;
|
|
fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1);
|
|
out[i] = .5 * fRoot;
|
|
fRoot = .5 / fRoot;
|
|
out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot;
|
|
out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;
|
|
out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot
|
|
}
|
|
return out
|
|
}
|
|
function fromEuler(out, x, y, z) {
|
|
var halfToRad = .5 * Math.PI / 180;
|
|
x *= halfToRad;
|
|
y *= halfToRad;
|
|
z *= halfToRad;
|
|
var sx = Math.sin(x);
|
|
var cx = Math.cos(x);
|
|
var sy = Math.sin(y);
|
|
var cy = Math.cos(y);
|
|
var sz = Math.sin(z);
|
|
var cz = Math.cos(z);
|
|
out[0] = sx * cy * cz - cx * sy * sz;
|
|
out[1] = cx * sy * cz + sx * cy * sz;
|
|
out[2] = cx * cy * sz - sx * sy * cz;
|
|
out[3] = cx * cy * cz + sx * sy * sz;
|
|
return out
|
|
}
|
|
function str$6(a) {
|
|
return "quat(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"
|
|
}
|
|
var clone$6 = clone$5;
|
|
var fromValues$6 = fromValues$5;
|
|
var copy$6 = copy$5;
|
|
var set$6 = set$5;
|
|
var add$6 = add$5;
|
|
var mul$6 = multiply$6;
|
|
var scale$6 = scale$5;
|
|
var dot$2 = dot$1;
|
|
var lerp$2 = lerp$1;
|
|
var length$2 = length$1;
|
|
var len$2 = length$2;
|
|
var squaredLength$2 = squaredLength$1;
|
|
var sqrLen$2 = squaredLength$2;
|
|
var normalize$2 = normalize$1;
|
|
var exactEquals$6 = exactEquals$5;
|
|
var equals$7 = equals$6;
|
|
var rotationTo = function() {
|
|
var tmpvec3 = create$4();
|
|
var xUnitVec3 = fromValues$4(1, 0, 0);
|
|
var yUnitVec3 = fromValues$4(0, 1, 0);
|
|
return function(out, a, b) {
|
|
var dot$1 = dot(a, b);
|
|
if (dot$1 < -.999999) {
|
|
cross(tmpvec3, xUnitVec3, a);
|
|
if (len(tmpvec3) < 1E-6)
|
|
cross(tmpvec3, yUnitVec3, a);
|
|
normalize(tmpvec3, tmpvec3);
|
|
setAxisAngle(out, tmpvec3, Math.PI);
|
|
return out
|
|
} else if (dot$1 > .999999) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
return out
|
|
} else {
|
|
cross(tmpvec3, a, b);
|
|
out[0] = tmpvec3[0];
|
|
out[1] = tmpvec3[1];
|
|
out[2] = tmpvec3[2];
|
|
out[3] = 1 + dot$1;
|
|
return normalize$2(out, out)
|
|
}
|
|
}
|
|
}();
|
|
var sqlerp = function() {
|
|
var temp1 = create$6();
|
|
var temp2 = create$6();
|
|
return function(out, a, b, c, d, t) {
|
|
slerp(temp1, a, d, t);
|
|
slerp(temp2, b, c, t);
|
|
slerp(out, temp1, temp2, 2 * t * (1 - t));
|
|
return out
|
|
}
|
|
}();
|
|
var setAxes = function() {
|
|
var matr = create$2();
|
|
return function(out, view, right, up) {
|
|
matr[0] = right[0];
|
|
matr[3] = right[1];
|
|
matr[6] = right[2];
|
|
matr[1] = up[0];
|
|
matr[4] = up[1];
|
|
matr[7] = up[2];
|
|
matr[2] = -view[0];
|
|
matr[5] = -view[1];
|
|
matr[8] = -view[2];
|
|
return normalize$2(out, fromMat3(out, matr))
|
|
}
|
|
}();
|
|
var quat = Object.freeze({
|
|
__proto__: null,
|
|
create: create$6,
|
|
identity: identity$4,
|
|
setAxisAngle: setAxisAngle,
|
|
getAxisAngle: getAxisAngle,
|
|
getAngle: getAngle,
|
|
multiply: multiply$6,
|
|
rotateX: rotateX$2,
|
|
rotateY: rotateY$2,
|
|
rotateZ: rotateZ$2,
|
|
calculateW: calculateW,
|
|
exp: exp,
|
|
ln: ln,
|
|
pow: pow,
|
|
slerp: slerp,
|
|
random: random$2,
|
|
invert: invert$4,
|
|
conjugate: conjugate,
|
|
fromMat3: fromMat3,
|
|
fromEuler: fromEuler,
|
|
str: str$6,
|
|
clone: clone$6,
|
|
fromValues: fromValues$6,
|
|
copy: copy$6,
|
|
set: set$6,
|
|
add: add$6,
|
|
mul: mul$6,
|
|
scale: scale$6,
|
|
dot: dot$2,
|
|
lerp: lerp$2,
|
|
length: length$2,
|
|
len: len$2,
|
|
squaredLength: squaredLength$2,
|
|
sqrLen: sqrLen$2,
|
|
normalize: normalize$2,
|
|
exactEquals: exactEquals$6,
|
|
equals: equals$7,
|
|
rotationTo: rotationTo,
|
|
sqlerp: sqlerp,
|
|
setAxes: setAxes
|
|
});
|
|
function create$7() {
|
|
var dq = new ARRAY_TYPE(8);
|
|
if (ARRAY_TYPE != Float32Array) {
|
|
dq[0] = 0;
|
|
dq[1] = 0;
|
|
dq[2] = 0;
|
|
dq[4] = 0;
|
|
dq[5] = 0;
|
|
dq[6] = 0;
|
|
dq[7] = 0
|
|
}
|
|
dq[3] = 1;
|
|
return dq
|
|
}
|
|
function clone$7(a) {
|
|
var dq = new ARRAY_TYPE(8);
|
|
dq[0] = a[0];
|
|
dq[1] = a[1];
|
|
dq[2] = a[2];
|
|
dq[3] = a[3];
|
|
dq[4] = a[4];
|
|
dq[5] = a[5];
|
|
dq[6] = a[6];
|
|
dq[7] = a[7];
|
|
return dq
|
|
}
|
|
function fromValues$7(x1, y1, z1, w1, x2, y2, z2, w2) {
|
|
var dq = new ARRAY_TYPE(8);
|
|
dq[0] = x1;
|
|
dq[1] = y1;
|
|
dq[2] = z1;
|
|
dq[3] = w1;
|
|
dq[4] = x2;
|
|
dq[5] = y2;
|
|
dq[6] = z2;
|
|
dq[7] = w2;
|
|
return dq
|
|
}
|
|
function fromRotationTranslationValues(x1, y1, z1, w1, x2, y2, z2) {
|
|
var dq = new ARRAY_TYPE(8);
|
|
dq[0] = x1;
|
|
dq[1] = y1;
|
|
dq[2] = z1;
|
|
dq[3] = w1;
|
|
var ax = x2 * .5
|
|
, ay = y2 * .5
|
|
, az = z2 * .5;
|
|
dq[4] = ax * w1 + ay * z1 - az * y1;
|
|
dq[5] = ay * w1 + az * x1 - ax * z1;
|
|
dq[6] = az * w1 + ax * y1 - ay * x1;
|
|
dq[7] = -ax * x1 - ay * y1 - az * z1;
|
|
return dq
|
|
}
|
|
function fromRotationTranslation$1(out, q, t) {
|
|
var ax = t[0] * .5
|
|
, ay = t[1] * .5
|
|
, az = t[2] * .5
|
|
, bx = q[0]
|
|
, by = q[1]
|
|
, bz = q[2]
|
|
, bw = q[3];
|
|
out[0] = bx;
|
|
out[1] = by;
|
|
out[2] = bz;
|
|
out[3] = bw;
|
|
out[4] = ax * bw + ay * bz - az * by;
|
|
out[5] = ay * bw + az * bx - ax * bz;
|
|
out[6] = az * bw + ax * by - ay * bx;
|
|
out[7] = -ax * bx - ay * by - az * bz;
|
|
return out
|
|
}
|
|
function fromTranslation$3(out, t) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
out[4] = t[0] * .5;
|
|
out[5] = t[1] * .5;
|
|
out[6] = t[2] * .5;
|
|
out[7] = 0;
|
|
return out
|
|
}
|
|
function fromRotation$4(out, q) {
|
|
out[0] = q[0];
|
|
out[1] = q[1];
|
|
out[2] = q[2];
|
|
out[3] = q[3];
|
|
out[4] = 0;
|
|
out[5] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
return out
|
|
}
|
|
function fromMat4$1(out, a) {
|
|
var outer = create$6();
|
|
getRotation(outer, a);
|
|
var t = new ARRAY_TYPE(3);
|
|
getTranslation(t, a);
|
|
fromRotationTranslation$1(out, outer, t);
|
|
return out
|
|
}
|
|
function copy$7(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
return out
|
|
}
|
|
function identity$5(out) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 1;
|
|
out[4] = 0;
|
|
out[5] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
return out
|
|
}
|
|
function set$7(out, x1, y1, z1, w1, x2, y2, z2, w2) {
|
|
out[0] = x1;
|
|
out[1] = y1;
|
|
out[2] = z1;
|
|
out[3] = w1;
|
|
out[4] = x2;
|
|
out[5] = y2;
|
|
out[6] = z2;
|
|
out[7] = w2;
|
|
return out
|
|
}
|
|
var getReal = copy$6;
|
|
function getDual(out, a) {
|
|
out[0] = a[4];
|
|
out[1] = a[5];
|
|
out[2] = a[6];
|
|
out[3] = a[7];
|
|
return out
|
|
}
|
|
var setReal = copy$6;
|
|
function setDual(out, q) {
|
|
out[4] = q[0];
|
|
out[5] = q[1];
|
|
out[6] = q[2];
|
|
out[7] = q[3];
|
|
return out
|
|
}
|
|
function getTranslation$1(out, a) {
|
|
var ax = a[4]
|
|
, ay = a[5]
|
|
, az = a[6]
|
|
, aw = a[7]
|
|
, bx = -a[0]
|
|
, by = -a[1]
|
|
, bz = -a[2]
|
|
, bw = a[3];
|
|
out[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;
|
|
out[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;
|
|
out[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;
|
|
return out
|
|
}
|
|
function translate$3(out, a, v) {
|
|
var ax1 = a[0]
|
|
, ay1 = a[1]
|
|
, az1 = a[2]
|
|
, aw1 = a[3]
|
|
, bx1 = v[0] * .5
|
|
, by1 = v[1] * .5
|
|
, bz1 = v[2] * .5
|
|
, ax2 = a[4]
|
|
, ay2 = a[5]
|
|
, az2 = a[6]
|
|
, aw2 = a[7];
|
|
out[0] = ax1;
|
|
out[1] = ay1;
|
|
out[2] = az1;
|
|
out[3] = aw1;
|
|
out[4] = aw1 * bx1 + ay1 * bz1 - az1 * by1 + ax2;
|
|
out[5] = aw1 * by1 + az1 * bx1 - ax1 * bz1 + ay2;
|
|
out[6] = aw1 * bz1 + ax1 * by1 - ay1 * bx1 + az2;
|
|
out[7] = -ax1 * bx1 - ay1 * by1 - az1 * bz1 + aw2;
|
|
return out
|
|
}
|
|
function rotateX$3(out, a, rad) {
|
|
var bx = -a[0]
|
|
, by = -a[1]
|
|
, bz = -a[2]
|
|
, bw = a[3]
|
|
, ax = a[4]
|
|
, ay = a[5]
|
|
, az = a[6]
|
|
, aw = a[7]
|
|
, ax1 = ax * bw + aw * bx + ay * bz - az * by
|
|
, ay1 = ay * bw + aw * by + az * bx - ax * bz
|
|
, az1 = az * bw + aw * bz + ax * by - ay * bx
|
|
, aw1 = aw * bw - ax * bx - ay * by - az * bz;
|
|
rotateX$2(out, a, rad);
|
|
bx = out[0];
|
|
by = out[1];
|
|
bz = out[2];
|
|
bw = out[3];
|
|
out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
|
|
out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
|
|
out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
|
|
out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
|
|
return out
|
|
}
|
|
function rotateY$3(out, a, rad) {
|
|
var bx = -a[0]
|
|
, by = -a[1]
|
|
, bz = -a[2]
|
|
, bw = a[3]
|
|
, ax = a[4]
|
|
, ay = a[5]
|
|
, az = a[6]
|
|
, aw = a[7]
|
|
, ax1 = ax * bw + aw * bx + ay * bz - az * by
|
|
, ay1 = ay * bw + aw * by + az * bx - ax * bz
|
|
, az1 = az * bw + aw * bz + ax * by - ay * bx
|
|
, aw1 = aw * bw - ax * bx - ay * by - az * bz;
|
|
rotateY$2(out, a, rad);
|
|
bx = out[0];
|
|
by = out[1];
|
|
bz = out[2];
|
|
bw = out[3];
|
|
out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
|
|
out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
|
|
out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
|
|
out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
|
|
return out
|
|
}
|
|
function rotateZ$3(out, a, rad) {
|
|
var bx = -a[0]
|
|
, by = -a[1]
|
|
, bz = -a[2]
|
|
, bw = a[3]
|
|
, ax = a[4]
|
|
, ay = a[5]
|
|
, az = a[6]
|
|
, aw = a[7]
|
|
, ax1 = ax * bw + aw * bx + ay * bz - az * by
|
|
, ay1 = ay * bw + aw * by + az * bx - ax * bz
|
|
, az1 = az * bw + aw * bz + ax * by - ay * bx
|
|
, aw1 = aw * bw - ax * bx - ay * by - az * bz;
|
|
rotateZ$2(out, a, rad);
|
|
bx = out[0];
|
|
by = out[1];
|
|
bz = out[2];
|
|
bw = out[3];
|
|
out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
|
|
out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
|
|
out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
|
|
out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
|
|
return out
|
|
}
|
|
function rotateByQuatAppend(out, a, q) {
|
|
var qx = q[0]
|
|
, qy = q[1]
|
|
, qz = q[2]
|
|
, qw = q[3]
|
|
, ax = a[0]
|
|
, ay = a[1]
|
|
, az = a[2]
|
|
, aw = a[3];
|
|
out[0] = ax * qw + aw * qx + ay * qz - az * qy;
|
|
out[1] = ay * qw + aw * qy + az * qx - ax * qz;
|
|
out[2] = az * qw + aw * qz + ax * qy - ay * qx;
|
|
out[3] = aw * qw - ax * qx - ay * qy - az * qz;
|
|
ax = a[4];
|
|
ay = a[5];
|
|
az = a[6];
|
|
aw = a[7];
|
|
out[4] = ax * qw + aw * qx + ay * qz - az * qy;
|
|
out[5] = ay * qw + aw * qy + az * qx - ax * qz;
|
|
out[6] = az * qw + aw * qz + ax * qy - ay * qx;
|
|
out[7] = aw * qw - ax * qx - ay * qy - az * qz;
|
|
return out
|
|
}
|
|
function rotateByQuatPrepend(out, q, a) {
|
|
var qx = q[0]
|
|
, qy = q[1]
|
|
, qz = q[2]
|
|
, qw = q[3]
|
|
, bx = a[0]
|
|
, by = a[1]
|
|
, bz = a[2]
|
|
, bw = a[3];
|
|
out[0] = qx * bw + qw * bx + qy * bz - qz * by;
|
|
out[1] = qy * bw + qw * by + qz * bx - qx * bz;
|
|
out[2] = qz * bw + qw * bz + qx * by - qy * bx;
|
|
out[3] = qw * bw - qx * bx - qy * by - qz * bz;
|
|
bx = a[4];
|
|
by = a[5];
|
|
bz = a[6];
|
|
bw = a[7];
|
|
out[4] = qx * bw + qw * bx + qy * bz - qz * by;
|
|
out[5] = qy * bw + qw * by + qz * bx - qx * bz;
|
|
out[6] = qz * bw + qw * bz + qx * by - qy * bx;
|
|
out[7] = qw * bw - qx * bx - qy * by - qz * bz;
|
|
return out
|
|
}
|
|
function rotateAroundAxis(out, a, axis, rad) {
|
|
if (Math.abs(rad) < EPSILON)
|
|
return copy$7(out, a);
|
|
var axisLength = Math.hypot(axis[0], axis[1], axis[2]);
|
|
rad = rad * .5;
|
|
var s = Math.sin(rad);
|
|
var bx = s * axis[0] / axisLength;
|
|
var by = s * axis[1] / axisLength;
|
|
var bz = s * axis[2] / axisLength;
|
|
var bw = Math.cos(rad);
|
|
var ax1 = a[0]
|
|
, ay1 = a[1]
|
|
, az1 = a[2]
|
|
, aw1 = a[3];
|
|
out[0] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
|
|
out[1] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
|
|
out[2] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
|
|
out[3] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
|
|
var ax = a[4]
|
|
, ay = a[5]
|
|
, az = a[6]
|
|
, aw = a[7];
|
|
out[4] = ax * bw + aw * bx + ay * bz - az * by;
|
|
out[5] = ay * bw + aw * by + az * bx - ax * bz;
|
|
out[6] = az * bw + aw * bz + ax * by - ay * bx;
|
|
out[7] = aw * bw - ax * bx - ay * by - az * bz;
|
|
return out
|
|
}
|
|
function add$7(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
out[2] = a[2] + b[2];
|
|
out[3] = a[3] + b[3];
|
|
out[4] = a[4] + b[4];
|
|
out[5] = a[5] + b[5];
|
|
out[6] = a[6] + b[6];
|
|
out[7] = a[7] + b[7];
|
|
return out
|
|
}
|
|
function multiply$7(out, a, b) {
|
|
var ax0 = a[0]
|
|
, ay0 = a[1]
|
|
, az0 = a[2]
|
|
, aw0 = a[3]
|
|
, bx1 = b[4]
|
|
, by1 = b[5]
|
|
, bz1 = b[6]
|
|
, bw1 = b[7]
|
|
, ax1 = a[4]
|
|
, ay1 = a[5]
|
|
, az1 = a[6]
|
|
, aw1 = a[7]
|
|
, bx0 = b[0]
|
|
, by0 = b[1]
|
|
, bz0 = b[2]
|
|
, bw0 = b[3];
|
|
out[0] = ax0 * bw0 + aw0 * bx0 + ay0 * bz0 - az0 * by0;
|
|
out[1] = ay0 * bw0 + aw0 * by0 + az0 * bx0 - ax0 * bz0;
|
|
out[2] = az0 * bw0 + aw0 * bz0 + ax0 * by0 - ay0 * bx0;
|
|
out[3] = aw0 * bw0 - ax0 * bx0 - ay0 * by0 - az0 * bz0;
|
|
out[4] = ax0 * bw1 + aw0 * bx1 + ay0 * bz1 - az0 * by1 + ax1 * bw0 + aw1 * bx0 + ay1 * bz0 - az1 * by0;
|
|
out[5] = ay0 * bw1 + aw0 * by1 + az0 * bx1 - ax0 * bz1 + ay1 * bw0 + aw1 * by0 + az1 * bx0 - ax1 * bz0;
|
|
out[6] = az0 * bw1 + aw0 * bz1 + ax0 * by1 - ay0 * bx1 + az1 * bw0 + aw1 * bz0 + ax1 * by0 - ay1 * bx0;
|
|
out[7] = aw0 * bw1 - ax0 * bx1 - ay0 * by1 - az0 * bz1 + aw1 * bw0 - ax1 * bx0 - ay1 * by0 - az1 * bz0;
|
|
return out
|
|
}
|
|
var mul$7 = multiply$7;
|
|
function scale$7(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
out[2] = a[2] * b;
|
|
out[3] = a[3] * b;
|
|
out[4] = a[4] * b;
|
|
out[5] = a[5] * b;
|
|
out[6] = a[6] * b;
|
|
out[7] = a[7] * b;
|
|
return out
|
|
}
|
|
var dot$3 = dot$2;
|
|
function lerp$3(out, a, b, t) {
|
|
var mt = 1 - t;
|
|
if (dot$3(a, b) < 0)
|
|
t = -t;
|
|
out[0] = a[0] * mt + b[0] * t;
|
|
out[1] = a[1] * mt + b[1] * t;
|
|
out[2] = a[2] * mt + b[2] * t;
|
|
out[3] = a[3] * mt + b[3] * t;
|
|
out[4] = a[4] * mt + b[4] * t;
|
|
out[5] = a[5] * mt + b[5] * t;
|
|
out[6] = a[6] * mt + b[6] * t;
|
|
out[7] = a[7] * mt + b[7] * t;
|
|
return out
|
|
}
|
|
function invert$5(out, a) {
|
|
var sqlen = squaredLength$3(a);
|
|
out[0] = -a[0] / sqlen;
|
|
out[1] = -a[1] / sqlen;
|
|
out[2] = -a[2] / sqlen;
|
|
out[3] = a[3] / sqlen;
|
|
out[4] = -a[4] / sqlen;
|
|
out[5] = -a[5] / sqlen;
|
|
out[6] = -a[6] / sqlen;
|
|
out[7] = a[7] / sqlen;
|
|
return out
|
|
}
|
|
function conjugate$1(out, a) {
|
|
out[0] = -a[0];
|
|
out[1] = -a[1];
|
|
out[2] = -a[2];
|
|
out[3] = a[3];
|
|
out[4] = -a[4];
|
|
out[5] = -a[5];
|
|
out[6] = -a[6];
|
|
out[7] = a[7];
|
|
return out
|
|
}
|
|
var length$3 = length$2;
|
|
var len$3 = length$3;
|
|
var squaredLength$3 = squaredLength$2;
|
|
var sqrLen$3 = squaredLength$3;
|
|
function normalize$3(out, a) {
|
|
var magnitude = squaredLength$3(a);
|
|
if (magnitude > 0) {
|
|
magnitude = Math.sqrt(magnitude);
|
|
var a0 = a[0] / magnitude;
|
|
var a1 = a[1] / magnitude;
|
|
var a2 = a[2] / magnitude;
|
|
var a3 = a[3] / magnitude;
|
|
var b0 = a[4];
|
|
var b1 = a[5];
|
|
var b2 = a[6];
|
|
var b3 = a[7];
|
|
var a_dot_b = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3;
|
|
out[0] = a0;
|
|
out[1] = a1;
|
|
out[2] = a2;
|
|
out[3] = a3;
|
|
out[4] = (b0 - a0 * a_dot_b) / magnitude;
|
|
out[5] = (b1 - a1 * a_dot_b) / magnitude;
|
|
out[6] = (b2 - a2 * a_dot_b) / magnitude;
|
|
out[7] = (b3 - a3 * a_dot_b) / magnitude
|
|
}
|
|
return out
|
|
}
|
|
function str$7(a) {
|
|
return "quat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ")"
|
|
}
|
|
function exactEquals$7(a, b) {
|
|
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7]
|
|
}
|
|
function equals$8(a, b) {
|
|
var a0 = a[0]
|
|
, a1 = a[1]
|
|
, a2 = a[2]
|
|
, a3 = a[3]
|
|
, a4 = a[4]
|
|
, a5 = a[5]
|
|
, a6 = a[6]
|
|
, a7 = a[7];
|
|
var b0 = b[0]
|
|
, b1 = b[1]
|
|
, b2 = b[2]
|
|
, b3 = b[3]
|
|
, b4 = b[4]
|
|
, b5 = b[5]
|
|
, b6 = b[6]
|
|
, b7 = b[7];
|
|
return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1, Math.abs(a7), Math.abs(b7))
|
|
}
|
|
var quat2 = Object.freeze({
|
|
__proto__: null,
|
|
create: create$7,
|
|
clone: clone$7,
|
|
fromValues: fromValues$7,
|
|
fromRotationTranslationValues: fromRotationTranslationValues,
|
|
fromRotationTranslation: fromRotationTranslation$1,
|
|
fromTranslation: fromTranslation$3,
|
|
fromRotation: fromRotation$4,
|
|
fromMat4: fromMat4$1,
|
|
copy: copy$7,
|
|
identity: identity$5,
|
|
set: set$7,
|
|
getReal: getReal,
|
|
getDual: getDual,
|
|
setReal: setReal,
|
|
setDual: setDual,
|
|
getTranslation: getTranslation$1,
|
|
translate: translate$3,
|
|
rotateX: rotateX$3,
|
|
rotateY: rotateY$3,
|
|
rotateZ: rotateZ$3,
|
|
rotateByQuatAppend: rotateByQuatAppend,
|
|
rotateByQuatPrepend: rotateByQuatPrepend,
|
|
rotateAroundAxis: rotateAroundAxis,
|
|
add: add$7,
|
|
multiply: multiply$7,
|
|
mul: mul$7,
|
|
scale: scale$7,
|
|
dot: dot$3,
|
|
lerp: lerp$3,
|
|
invert: invert$5,
|
|
conjugate: conjugate$1,
|
|
length: length$3,
|
|
len: len$3,
|
|
squaredLength: squaredLength$3,
|
|
sqrLen: sqrLen$3,
|
|
normalize: normalize$3,
|
|
str: str$7,
|
|
exactEquals: exactEquals$7,
|
|
equals: equals$8
|
|
});
|
|
function create$8() {
|
|
var out = new ARRAY_TYPE(2);
|
|
if (ARRAY_TYPE != Float32Array) {
|
|
out[0] = 0;
|
|
out[1] = 0
|
|
}
|
|
return out
|
|
}
|
|
function clone$8(a) {
|
|
var out = new ARRAY_TYPE(2);
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
return out
|
|
}
|
|
function fromValues$8(x, y) {
|
|
var out = new ARRAY_TYPE(2);
|
|
out[0] = x;
|
|
out[1] = y;
|
|
return out
|
|
}
|
|
function copy$8(out, a) {
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
return out
|
|
}
|
|
function set$8(out, x, y) {
|
|
out[0] = x;
|
|
out[1] = y;
|
|
return out
|
|
}
|
|
function add$8(out, a, b) {
|
|
out[0] = a[0] + b[0];
|
|
out[1] = a[1] + b[1];
|
|
return out
|
|
}
|
|
function subtract$6(out, a, b) {
|
|
out[0] = a[0] - b[0];
|
|
out[1] = a[1] - b[1];
|
|
return out
|
|
}
|
|
function multiply$8(out, a, b) {
|
|
out[0] = a[0] * b[0];
|
|
out[1] = a[1] * b[1];
|
|
return out
|
|
}
|
|
function divide$2(out, a, b) {
|
|
out[0] = a[0] / b[0];
|
|
out[1] = a[1] / b[1];
|
|
return out
|
|
}
|
|
function ceil$2(out, a) {
|
|
out[0] = Math.ceil(a[0]);
|
|
out[1] = Math.ceil(a[1]);
|
|
return out
|
|
}
|
|
function floor$2(out, a) {
|
|
out[0] = Math.floor(a[0]);
|
|
out[1] = Math.floor(a[1]);
|
|
return out
|
|
}
|
|
function min$2(out, a, b) {
|
|
out[0] = Math.min(a[0], b[0]);
|
|
out[1] = Math.min(a[1], b[1]);
|
|
return out
|
|
}
|
|
function max$2(out, a, b) {
|
|
out[0] = Math.max(a[0], b[0]);
|
|
out[1] = Math.max(a[1], b[1]);
|
|
return out
|
|
}
|
|
function round$2(out, a) {
|
|
out[0] = Math.round(a[0]);
|
|
out[1] = Math.round(a[1]);
|
|
return out
|
|
}
|
|
function scale$8(out, a, b) {
|
|
out[0] = a[0] * b;
|
|
out[1] = a[1] * b;
|
|
return out
|
|
}
|
|
function scaleAndAdd$2(out, a, b, scale) {
|
|
out[0] = a[0] + b[0] * scale;
|
|
out[1] = a[1] + b[1] * scale;
|
|
return out
|
|
}
|
|
function distance$2(a, b) {
|
|
var x = b[0] - a[0]
|
|
, y = b[1] - a[1];
|
|
return Math.hypot(x, y)
|
|
}
|
|
function squaredDistance$2(a, b) {
|
|
var x = b[0] - a[0]
|
|
, y = b[1] - a[1];
|
|
return x * x + y * y
|
|
}
|
|
function length$4(a) {
|
|
var x = a[0]
|
|
, y = a[1];
|
|
return Math.hypot(x, y)
|
|
}
|
|
function squaredLength$4(a) {
|
|
var x = a[0]
|
|
, y = a[1];
|
|
return x * x + y * y
|
|
}
|
|
function negate$2(out, a) {
|
|
out[0] = -a[0];
|
|
out[1] = -a[1];
|
|
return out
|
|
}
|
|
function inverse$2(out, a) {
|
|
out[0] = 1 / a[0];
|
|
out[1] = 1 / a[1];
|
|
return out
|
|
}
|
|
function normalize$4(out, a) {
|
|
var x = a[0]
|
|
, y = a[1];
|
|
var len = x * x + y * y;
|
|
if (len > 0)
|
|
len = 1 / Math.sqrt(len);
|
|
out[0] = a[0] * len;
|
|
out[1] = a[1] * len;
|
|
return out
|
|
}
|
|
function dot$4(a, b) {
|
|
return a[0] * b[0] + a[1] * b[1]
|
|
}
|
|
function cross$2(out, a, b) {
|
|
var z = a[0] * b[1] - a[1] * b[0];
|
|
out[0] = out[1] = 0;
|
|
out[2] = z;
|
|
return out
|
|
}
|
|
function lerp$4(out, a, b, t) {
|
|
var ax = a[0]
|
|
, ay = a[1];
|
|
out[0] = ax + t * (b[0] - ax);
|
|
out[1] = ay + t * (b[1] - ay);
|
|
return out
|
|
}
|
|
function random$3(out, scale) {
|
|
scale = scale || 1;
|
|
var r = RANDOM() * 2 * Math.PI;
|
|
out[0] = Math.cos(r) * scale;
|
|
out[1] = Math.sin(r) * scale;
|
|
return out
|
|
}
|
|
function transformMat2(out, a, m) {
|
|
var x = a[0]
|
|
, y = a[1];
|
|
out[0] = m[0] * x + m[2] * y;
|
|
out[1] = m[1] * x + m[3] * y;
|
|
return out
|
|
}
|
|
function transformMat2d(out, a, m) {
|
|
var x = a[0]
|
|
, y = a[1];
|
|
out[0] = m[0] * x + m[2] * y + m[4];
|
|
out[1] = m[1] * x + m[3] * y + m[5];
|
|
return out
|
|
}
|
|
function transformMat3$1(out, a, m) {
|
|
var x = a[0]
|
|
, y = a[1];
|
|
out[0] = m[0] * x + m[3] * y + m[6];
|
|
out[1] = m[1] * x + m[4] * y + m[7];
|
|
return out
|
|
}
|
|
function transformMat4$2(out, a, m) {
|
|
var x = a[0];
|
|
var y = a[1];
|
|
out[0] = m[0] * x + m[4] * y + m[12];
|
|
out[1] = m[1] * x + m[5] * y + m[13];
|
|
return out
|
|
}
|
|
function rotate$4(out, a, b, rad) {
|
|
var p0 = a[0] - b[0]
|
|
, p1 = a[1] - b[1]
|
|
, sinC = Math.sin(rad)
|
|
, cosC = Math.cos(rad);
|
|
out[0] = p0 * cosC - p1 * sinC + b[0];
|
|
out[1] = p0 * sinC + p1 * cosC + b[1];
|
|
return out
|
|
}
|
|
function angle$1(a, b) {
|
|
var x1 = a[0]
|
|
, y1 = a[1]
|
|
, x2 = b[0]
|
|
, y2 = b[1]
|
|
, mag = Math.sqrt(x1 * x1 + y1 * y1) * Math.sqrt(x2 * x2 + y2 * y2)
|
|
, cosine = mag && (x1 * x2 + y1 * y2) / mag;
|
|
return Math.acos(Math.min(Math.max(cosine, -1), 1))
|
|
}
|
|
function zero$2(out) {
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
return out
|
|
}
|
|
function str$8(a) {
|
|
return "vec2(" + a[0] + ", " + a[1] + ")"
|
|
}
|
|
function exactEquals$8(a, b) {
|
|
return a[0] === b[0] && a[1] === b[1]
|
|
}
|
|
function equals$9(a, b) {
|
|
var a0 = a[0]
|
|
, a1 = a[1];
|
|
var b0 = b[0]
|
|
, b1 = b[1];
|
|
return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1))
|
|
}
|
|
var len$4 = length$4;
|
|
var sub$6 = subtract$6;
|
|
var mul$8 = multiply$8;
|
|
var div$2 = divide$2;
|
|
var dist$2 = distance$2;
|
|
var sqrDist$2 = squaredDistance$2;
|
|
var sqrLen$4 = squaredLength$4;
|
|
var forEach$2 = function() {
|
|
var vec = create$8();
|
|
return function(a, stride, offset, count, fn, arg) {
|
|
var i, l;
|
|
if (!stride)
|
|
stride = 2;
|
|
if (!offset)
|
|
offset = 0;
|
|
if (count)
|
|
l = Math.min(count * stride + offset, a.length);
|
|
else
|
|
l = a.length;
|
|
for (i = offset; i < l; i += stride) {
|
|
vec[0] = a[i];
|
|
vec[1] = a[i + 1];
|
|
fn(vec, vec, arg);
|
|
a[i] = vec[0];
|
|
a[i + 1] = vec[1]
|
|
}
|
|
return a
|
|
}
|
|
}();
|
|
var vec2 = Object.freeze({
|
|
__proto__: null,
|
|
create: create$8,
|
|
clone: clone$8,
|
|
fromValues: fromValues$8,
|
|
copy: copy$8,
|
|
set: set$8,
|
|
add: add$8,
|
|
subtract: subtract$6,
|
|
multiply: multiply$8,
|
|
divide: divide$2,
|
|
ceil: ceil$2,
|
|
floor: floor$2,
|
|
min: min$2,
|
|
max: max$2,
|
|
round: round$2,
|
|
scale: scale$8,
|
|
scaleAndAdd: scaleAndAdd$2,
|
|
distance: distance$2,
|
|
squaredDistance: squaredDistance$2,
|
|
length: length$4,
|
|
squaredLength: squaredLength$4,
|
|
negate: negate$2,
|
|
inverse: inverse$2,
|
|
normalize: normalize$4,
|
|
dot: dot$4,
|
|
cross: cross$2,
|
|
lerp: lerp$4,
|
|
random: random$3,
|
|
transformMat2: transformMat2,
|
|
transformMat2d: transformMat2d,
|
|
transformMat3: transformMat3$1,
|
|
transformMat4: transformMat4$2,
|
|
rotate: rotate$4,
|
|
angle: angle$1,
|
|
zero: zero$2,
|
|
str: str$8,
|
|
exactEquals: exactEquals$8,
|
|
equals: equals$9,
|
|
len: len$4,
|
|
sub: sub$6,
|
|
mul: mul$8,
|
|
div: div$2,
|
|
dist: dist$2,
|
|
sqrDist: sqrDist$2,
|
|
sqrLen: sqrLen$4,
|
|
forEach: forEach$2
|
|
});
|
|
exports.glMatrix = common;
|
|
exports.mat2 = mat2;
|
|
exports.mat2d = mat2d;
|
|
exports.mat3 = mat3;
|
|
exports.mat4 = mat4;
|
|
exports.quat = quat;
|
|
exports.quat2 = quat2;
|
|
exports.vec2 = vec2;
|
|
exports.vec3 = vec3;
|
|
exports.vec4 = vec4;
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
})
|
|
});
|
|
'use strict';
|
|
{
|
|
function lineInt(l1, l2, precision) {
|
|
precision = precision || 0;
|
|
var i = [0, 0];
|
|
var a1, b1, c1, a2, b2, c2, det;
|
|
a1 = l1[1][1] - l1[0][1];
|
|
b1 = l1[0][0] - l1[1][0];
|
|
c1 = a1 * l1[0][0] + b1 * l1[0][1];
|
|
a2 = l2[1][1] - l2[0][1];
|
|
b2 = l2[0][0] - l2[1][0];
|
|
c2 = a2 * l2[0][0] + b2 * l2[0][1];
|
|
det = a1 * b2 - a2 * b1;
|
|
if (!scalar_eq(det, 0, precision)) {
|
|
i[0] = (b2 * c1 - b1 * c2) / det;
|
|
i[1] = (a1 * c2 - a2 * c1) / det
|
|
}
|
|
return i
|
|
}
|
|
function lineSegmentsIntersect(p1, p2, q1, q2) {
|
|
var dx = p2[0] - p1[0];
|
|
var dy = p2[1] - p1[1];
|
|
var da = q2[0] - q1[0];
|
|
var db = q2[1] - q1[1];
|
|
if (da * dy - db * dx === 0)
|
|
return false;
|
|
var s = (dx * (q1[1] - p1[1]) + dy * (p1[0] - q1[0])) / (da * dy - db * dx);
|
|
var t = (da * (p1[1] - q1[1]) + db * (q1[0] - p1[0])) / (db * dx - da * dy);
|
|
return s >= 0 && s <= 1 && t >= 0 && t <= 1
|
|
}
|
|
function triangleArea(a, b, c) {
|
|
return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1])
|
|
}
|
|
function isLeft(a, b, c) {
|
|
return triangleArea(a, b, c) > 0
|
|
}
|
|
function isLeftOn(a, b, c) {
|
|
return triangleArea(a, b, c) >= 0
|
|
}
|
|
function isRight(a, b, c) {
|
|
return triangleArea(a, b, c) < 0
|
|
}
|
|
function isRightOn(a, b, c) {
|
|
return triangleArea(a, b, c) <= 0
|
|
}
|
|
var tmpPoint1 = []
|
|
, tmpPoint2 = [];
|
|
function collinear(a, b, c, thresholdAngle) {
|
|
if (!thresholdAngle)
|
|
return triangleArea(a, b, c) === 0;
|
|
else {
|
|
var ab = tmpPoint1
|
|
, bc = tmpPoint2;
|
|
ab[0] = b[0] - a[0];
|
|
ab[1] = b[1] - a[1];
|
|
bc[0] = c[0] - b[0];
|
|
bc[1] = c[1] - b[1];
|
|
var dot = ab[0] * bc[0] + ab[1] * bc[1]
|
|
, magA = Math.sqrt(ab[0] * ab[0] + ab[1] * ab[1])
|
|
, magB = Math.sqrt(bc[0] * bc[0] + bc[1] * bc[1])
|
|
, angle = Math.acos(dot / (magA * magB));
|
|
return angle < thresholdAngle
|
|
}
|
|
}
|
|
function sqdist(a, b) {
|
|
var dx = b[0] - a[0];
|
|
var dy = b[1] - a[1];
|
|
return dx * dx + dy * dy
|
|
}
|
|
function polygonAt(polygon, i) {
|
|
var s = polygon.length;
|
|
return polygon[i < 0 ? i % s + s : i % s]
|
|
}
|
|
function polygonClear(polygon) {
|
|
polygon.length = 0
|
|
}
|
|
function polygonAppend(polygon, poly, from, to) {
|
|
for (var i = from; i < to; i++)
|
|
polygon.push(poly[i])
|
|
}
|
|
function polygonMakeCCW(polygon) {
|
|
var br = 0
|
|
, v = polygon;
|
|
for (var i = 1; i < polygon.length; ++i)
|
|
if (v[i][1] < v[br][1] || v[i][1] === v[br][1] && v[i][0] > v[br][0])
|
|
br = i;
|
|
if (!isLeft(polygonAt(polygon, br - 1), polygonAt(polygon, br), polygonAt(polygon, br + 1))) {
|
|
polygonReverse(polygon);
|
|
return true
|
|
} else
|
|
return false
|
|
}
|
|
function polygonReverse(polygon) {
|
|
var tmp = [];
|
|
var N = polygon.length;
|
|
for (var i = 0; i !== N; i++)
|
|
tmp.push(polygon.pop());
|
|
for (var i = 0; i !== N; i++)
|
|
polygon[i] = tmp[i]
|
|
}
|
|
function polygonIsReflex(polygon, i) {
|
|
return isRight(polygonAt(polygon, i - 1), polygonAt(polygon, i), polygonAt(polygon, i + 1))
|
|
}
|
|
var tmpLine1 = []
|
|
, tmpLine2 = [];
|
|
function polygonCanSee(polygon, a, b) {
|
|
var p, dist, l1 = tmpLine1, l2 = tmpLine2;
|
|
if (isLeftOn(polygonAt(polygon, a + 1), polygonAt(polygon, a), polygonAt(polygon, b)) && isRightOn(polygonAt(polygon, a - 1), polygonAt(polygon, a), polygonAt(polygon, b)))
|
|
return false;
|
|
dist = sqdist(polygonAt(polygon, a), polygonAt(polygon, b));
|
|
for (var i = 0; i !== polygon.length; ++i) {
|
|
if ((i + 1) % polygon.length === a || i === a)
|
|
continue;
|
|
if (isLeftOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i + 1)) && isRightOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i))) {
|
|
l1[0] = polygonAt(polygon, a);
|
|
l1[1] = polygonAt(polygon, b);
|
|
l2[0] = polygonAt(polygon, i);
|
|
l2[1] = polygonAt(polygon, i + 1);
|
|
p = lineInt(l1, l2);
|
|
if (sqdist(polygonAt(polygon, a), p) < dist)
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
function polygonCanSee2(polygon, a, b) {
|
|
for (var i = 0; i !== polygon.length; ++i) {
|
|
if (i === a || i === b || (i + 1) % polygon.length === a || (i + 1) % polygon.length === b)
|
|
continue;
|
|
if (lineSegmentsIntersect(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i), polygonAt(polygon, i + 1)))
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
function polygonCopy(polygon, i, j, targetPoly) {
|
|
var p = targetPoly || [];
|
|
polygonClear(p);
|
|
if (i < j)
|
|
for (var k = i; k <= j; k++)
|
|
p.push(polygon[k]);
|
|
else {
|
|
for (var k = 0; k <= j; k++)
|
|
p.push(polygon[k]);
|
|
for (var k = i; k < polygon.length; k++)
|
|
p.push(polygon[k])
|
|
}
|
|
return p
|
|
}
|
|
function polygonGetCutEdges(polygon) {
|
|
var min = []
|
|
, tmp1 = []
|
|
, tmp2 = []
|
|
, tmpPoly = [];
|
|
var nDiags = Number.MAX_VALUE;
|
|
for (var i = 0; i < polygon.length; ++i)
|
|
if (polygonIsReflex(polygon, i))
|
|
for (var j = 0; j < polygon.length; ++j)
|
|
if (polygonCanSee(polygon, i, j)) {
|
|
tmp1 = polygonGetCutEdges(polygonCopy(polygon, i, j, tmpPoly));
|
|
tmp2 = polygonGetCutEdges(polygonCopy(polygon, j, i, tmpPoly));
|
|
for (var k = 0; k < tmp2.length; k++)
|
|
tmp1.push(tmp2[k]);
|
|
if (tmp1.length < nDiags) {
|
|
min = tmp1;
|
|
nDiags = tmp1.length;
|
|
min.push([polygonAt(polygon, i), polygonAt(polygon, j)])
|
|
}
|
|
}
|
|
return min
|
|
}
|
|
function polygonDecomp(polygon) {
|
|
var edges = polygonGetCutEdges(polygon);
|
|
if (edges.length > 0)
|
|
return polygonSlice(polygon, edges);
|
|
else
|
|
return [polygon]
|
|
}
|
|
function polygonSlice(polygon, cutEdges) {
|
|
if (cutEdges.length === 0)
|
|
return [polygon];
|
|
if (cutEdges instanceof Array && cutEdges.length && cutEdges[0]instanceof Array && cutEdges[0].length === 2 && cutEdges[0][0]instanceof Array) {
|
|
var polys = [polygon];
|
|
for (var i = 0; i < cutEdges.length; i++) {
|
|
var cutEdge = cutEdges[i];
|
|
for (var j = 0; j < polys.length; j++) {
|
|
var poly = polys[j];
|
|
var result = polygonSlice(poly, cutEdge);
|
|
if (result) {
|
|
polys.splice(j, 1);
|
|
polys.push(result[0], result[1]);
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return polys
|
|
} else {
|
|
var cutEdge = cutEdges;
|
|
var i = polygon.indexOf(cutEdge[0]);
|
|
var j = polygon.indexOf(cutEdge[1]);
|
|
if (i !== -1 && j !== -1)
|
|
return [polygonCopy(polygon, i, j), polygonCopy(polygon, j, i)];
|
|
else
|
|
return false
|
|
}
|
|
}
|
|
function polygonIsSimple(polygon) {
|
|
var path = polygon, i;
|
|
for (i = 0; i < path.length - 1; i++)
|
|
for (var j = 0; j < i - 1; j++)
|
|
if (lineSegmentsIntersect(path[i], path[i + 1], path[j], path[j + 1]))
|
|
return false;
|
|
for (i = 1; i < path.length - 2; i++)
|
|
if (lineSegmentsIntersect(path[0], path[path.length - 1], path[i], path[i + 1]))
|
|
return false;
|
|
return true
|
|
}
|
|
function getIntersectionPoint(p1, p2, q1, q2, delta) {
|
|
delta = delta || 0;
|
|
var a1 = p2[1] - p1[1];
|
|
var b1 = p1[0] - p2[0];
|
|
var c1 = a1 * p1[0] + b1 * p1[1];
|
|
var a2 = q2[1] - q1[1];
|
|
var b2 = q1[0] - q2[0];
|
|
var c2 = a2 * q1[0] + b2 * q1[1];
|
|
var det = a1 * b2 - a2 * b1;
|
|
if (!scalar_eq(det, 0, delta))
|
|
return [(b2 * c1 - b1 * c2) / det, (a1 * c2 - a2 * c1) / det];
|
|
else
|
|
return [0, 0]
|
|
}
|
|
function polygonQuickDecomp(polygon, result, reflexVertices, steinerPoints, delta, maxlevel, level) {
|
|
maxlevel = maxlevel || 100;
|
|
level = level || 0;
|
|
delta = delta || 25;
|
|
result = typeof result !== "undefined" ? result : [];
|
|
reflexVertices = reflexVertices || [];
|
|
steinerPoints = steinerPoints || [];
|
|
var upperInt = [0, 0]
|
|
, lowerInt = [0, 0]
|
|
, p = [0, 0];
|
|
var upperDist = 0
|
|
, lowerDist = 0
|
|
, d = 0
|
|
, closestDist = 0;
|
|
var upperIndex = 0
|
|
, lowerIndex = 0
|
|
, closestIndex = 0;
|
|
var lowerPoly = []
|
|
, upperPoly = [];
|
|
var poly = polygon
|
|
, v = polygon;
|
|
if (v.length < 3)
|
|
return result;
|
|
level++;
|
|
if (level > maxlevel) {
|
|
console.warn("quickDecomp: max level (" + maxlevel + ") reached.");
|
|
return result
|
|
}
|
|
for (var i = 0; i < polygon.length; ++i)
|
|
if (polygonIsReflex(poly, i)) {
|
|
reflexVertices.push(poly[i]);
|
|
upperDist = lowerDist = Number.MAX_VALUE;
|
|
for (var j = 0; j < polygon.length; ++j) {
|
|
if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j - 1))) {
|
|
p = getIntersectionPoint(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j - 1));
|
|
if (isRight(polygonAt(poly, i + 1), polygonAt(poly, i), p)) {
|
|
d = sqdist(poly[i], p);
|
|
if (d < lowerDist) {
|
|
lowerDist = d;
|
|
lowerInt = p;
|
|
lowerIndex = j
|
|
}
|
|
}
|
|
}
|
|
if (isLeft(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j + 1)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) {
|
|
p = getIntersectionPoint(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j + 1));
|
|
if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), p)) {
|
|
d = sqdist(poly[i], p);
|
|
if (d < upperDist) {
|
|
upperDist = d;
|
|
upperInt = p;
|
|
upperIndex = j
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (lowerIndex === (upperIndex + 1) % polygon.length) {
|
|
p[0] = (lowerInt[0] + upperInt[0]) / 2;
|
|
p[1] = (lowerInt[1] + upperInt[1]) / 2;
|
|
steinerPoints.push(p);
|
|
if (i < upperIndex) {
|
|
polygonAppend(lowerPoly, poly, i, upperIndex + 1);
|
|
lowerPoly.push(p);
|
|
upperPoly.push(p);
|
|
if (lowerIndex !== 0)
|
|
polygonAppend(upperPoly, poly, lowerIndex, poly.length);
|
|
polygonAppend(upperPoly, poly, 0, i + 1)
|
|
} else {
|
|
if (i !== 0)
|
|
polygonAppend(lowerPoly, poly, i, poly.length);
|
|
polygonAppend(lowerPoly, poly, 0, upperIndex + 1);
|
|
lowerPoly.push(p);
|
|
upperPoly.push(p);
|
|
polygonAppend(upperPoly, poly, lowerIndex, i + 1)
|
|
}
|
|
} else {
|
|
if (lowerIndex > upperIndex)
|
|
upperIndex += polygon.length;
|
|
closestDist = Number.MAX_VALUE;
|
|
if (upperIndex < lowerIndex)
|
|
return result;
|
|
for (var j = lowerIndex; j <= upperIndex; ++j)
|
|
if (isLeftOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) {
|
|
d = sqdist(polygonAt(poly, i), polygonAt(poly, j));
|
|
if (d < closestDist && polygonCanSee2(poly, i, j)) {
|
|
closestDist = d;
|
|
closestIndex = j % polygon.length
|
|
}
|
|
}
|
|
if (i < closestIndex) {
|
|
polygonAppend(lowerPoly, poly, i, closestIndex + 1);
|
|
if (closestIndex !== 0)
|
|
polygonAppend(upperPoly, poly, closestIndex, v.length);
|
|
polygonAppend(upperPoly, poly, 0, i + 1)
|
|
} else {
|
|
if (i !== 0)
|
|
polygonAppend(lowerPoly, poly, i, v.length);
|
|
polygonAppend(lowerPoly, poly, 0, closestIndex + 1);
|
|
polygonAppend(upperPoly, poly, closestIndex, i + 1)
|
|
}
|
|
}
|
|
if (lowerPoly.length < upperPoly.length) {
|
|
polygonQuickDecomp(lowerPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level);
|
|
polygonQuickDecomp(upperPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level)
|
|
} else {
|
|
polygonQuickDecomp(upperPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level);
|
|
polygonQuickDecomp(lowerPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level)
|
|
}
|
|
return result
|
|
}
|
|
result.push(polygon);
|
|
return result
|
|
}
|
|
function polygonRemoveCollinearPoints(polygon, precision) {
|
|
var num = 0;
|
|
for (var i = polygon.length - 1; polygon.length > 3 && i >= 0; --i)
|
|
if (collinear(polygonAt(polygon, i - 1), polygonAt(polygon, i), polygonAt(polygon, i + 1), precision)) {
|
|
polygon.splice(i % polygon.length, 1);
|
|
num++
|
|
}
|
|
return num
|
|
}
|
|
function polygonRemoveDuplicatePoints(polygon, precision) {
|
|
for (var i = polygon.length - 1; i >= 1; --i) {
|
|
var pi = polygon[i];
|
|
for (var j = i - 1; j >= 0; --j)
|
|
if (points_eq(pi, polygon[j], precision)) {
|
|
polygon.splice(i, 1);
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
function scalar_eq(a, b, precision) {
|
|
precision = precision || 0;
|
|
return Math.abs(a - b) <= precision
|
|
}
|
|
function points_eq(a, b, precision) {
|
|
return scalar_eq(a[0], b[0], precision) && scalar_eq(a[1], b[1], precision)
|
|
}
|
|
self.polyDecomp = {
|
|
decomp: polygonDecomp,
|
|
quickDecomp: polygonQuickDecomp,
|
|
isSimple: polygonIsSimple,
|
|
removeCollinearPoints: polygonRemoveCollinearPoints,
|
|
removeDuplicatePoints: polygonRemoveDuplicatePoints,
|
|
makeCCW: polygonMakeCCW
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
let isReady = false;
|
|
let hasAppStarted = false;
|
|
let buildMode = "dev";
|
|
const C3 = self.C3 = class C3 {
|
|
constructor() {
|
|
throw TypeError("static class can't be instantiated");
|
|
}
|
|
static SetReady() {
|
|
isReady = true
|
|
}
|
|
static IsReady() {
|
|
return isReady
|
|
}
|
|
static SetAppStarted() {
|
|
hasAppStarted = true
|
|
}
|
|
static HasAppStarted() {
|
|
return hasAppStarted
|
|
}
|
|
static SetBuildMode(m) {
|
|
buildMode = m
|
|
}
|
|
static GetBuildMode() {
|
|
return buildMode
|
|
}
|
|
static IsReleaseBuild() {
|
|
return buildMode === "final"
|
|
}
|
|
}
|
|
;
|
|
C3.isDebug = false;
|
|
C3.isDebugDefend = false;
|
|
C3.hardwareConcurrency = navigator.hardwareConcurrency || 2
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.QueryParser = class QueryParser {
|
|
constructor(queryString) {
|
|
this._queryString = queryString;
|
|
this._parameters = new Map;
|
|
this._Parse()
|
|
}
|
|
_Parse() {
|
|
let str = this._queryString;
|
|
if (str.startsWith("?") || str.startsWith("#"))
|
|
str = str.substr(1);
|
|
const arr = str.split("&");
|
|
for (const p of arr)
|
|
this._ParseParameter(p)
|
|
}
|
|
_ParseParameter(p) {
|
|
if (!p)
|
|
return;
|
|
if (!p.includes("=")) {
|
|
this._parameters.set(p, null);
|
|
return
|
|
}
|
|
const i = p.indexOf("=");
|
|
const parameterName = decodeURIComponent(p.substring(0, i));
|
|
const parameterValue = decodeURIComponent(p.substring(i + 1));
|
|
this._parameters.set(parameterName, parameterValue)
|
|
}
|
|
LogAll() {
|
|
for (const e of this._parameters)
|
|
console.log("[QueryParser] Parameter '" + e[0] + "' = " + (e[1] === null ? "null" : "'" + e[1] + "'"))
|
|
}
|
|
Has(name) {
|
|
return this._parameters.has(name)
|
|
}
|
|
Get(name) {
|
|
const ret = this._parameters.get(name);
|
|
if (typeof ret === "undefined")
|
|
return null;
|
|
else
|
|
return ret
|
|
}
|
|
ClearHash() {
|
|
history.replaceState("", document.title, location.pathname + location.search)
|
|
}
|
|
Reparse(str) {
|
|
this._queryString = str;
|
|
this._parameters.clear();
|
|
this._Parse()
|
|
}
|
|
}
|
|
;
|
|
C3.QueryString = new C3.QueryParser(location.search);
|
|
C3.LocationHashString = new C3.QueryParser(location.hash);
|
|
if (C3.QueryString.Get("mode") !== "dev")
|
|
C3.SetBuildMode("final")
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const UNKNOWN = "(unknown)";
|
|
const UA = navigator.userAgent;
|
|
let Flags = {
|
|
linux: /linux|openbsd|freebsd|netbsd/i.test(UA),
|
|
chromeOS: /CrOS/.test(UA),
|
|
windowsTizen: /trident|iemobile|msie|tizen/i.test(UA),
|
|
genericMS: /trident|iemobile|msie|edge\//i.test(UA),
|
|
opera: /OPR\//.test(UA),
|
|
blackberry: /bb10/i.test(UA),
|
|
edge: /edge\//i.test(UA),
|
|
trident: /trident/i.test(UA),
|
|
webkit: /webkit/i.test(UA),
|
|
safari: /safari\//i.test(UA),
|
|
chrome: /chrome\//i.test(UA),
|
|
chromium: /chromium\//i.test(UA),
|
|
crosswalk: /crosswalk|xwalk/i.test(UA),
|
|
nwjs: /nwjs/i.test(UA),
|
|
amazonwebapp: /amazonwebappplatform/i.test(UA),
|
|
webview: /wv\)/.test(UA),
|
|
android: /android/i.test(UA),
|
|
nokia: /nokiabrowser\/[0-9.]+/i.test(UA)
|
|
};
|
|
let Versions = {
|
|
windows: /windows\s+nt\s+\d+\.\d+/i.exec(UA),
|
|
OSX: /mac\s+os\s+x\s+[0-9_]+/i.exec(UA),
|
|
android: /android\s+[0-9.]+/i.exec(UA),
|
|
opera: /OPR\/[0-9.]+/.exec(UA),
|
|
tizen: /tizen\s+[0-9.]+/i.exec(UA),
|
|
iphone: /iphone\s+os\s+[0-9_]+/i.exec(UA),
|
|
ipad: /ipad[^)]*os\s+[0-9_]+/i.exec(UA),
|
|
winPhone: /windows\s+phone\s+[0-9.]+/i.exec(UA),
|
|
winPhoneOS: /windows\s+phone\s+os\s+[0-9.]+/i.exec(UA),
|
|
chrome: /chrome\/[0-9.]+/i.exec(UA),
|
|
chromium: /chromium\/[0-9.]+/i.exec(UA),
|
|
nwjs: /nwjs\/[0-9.]+/i.exec(UA),
|
|
firefox: /firefox\/[0-9.]+/i.exec(UA),
|
|
ie: /msie\s+[0-9.]+/i.exec(UA),
|
|
edge: /edge\/[0-9.]+/i.exec(UA),
|
|
edgeChromium: /edg\/[0-9.]+/i.exec(UA),
|
|
silk: /silk\/[0-9.]+/i.exec(UA)
|
|
};
|
|
let os = UNKNOWN;
|
|
let os_version = UNKNOWN;
|
|
let os_arch = UNKNOWN;
|
|
let browser = UNKNOWN;
|
|
let browser_version = UNKNOWN;
|
|
let browser_arch = UNKNOWN;
|
|
let engine = UNKNOWN;
|
|
let context = "browser";
|
|
let is_desktop = false;
|
|
let is_desktop_app = false;
|
|
let testResults = new Map;
|
|
function runTest(name, value, fn) {
|
|
if (value === true) {
|
|
const result = fn();
|
|
testResults.set(name, true)
|
|
} else if (value && value.length) {
|
|
const result = fn(value[0]);
|
|
testResults.set(name, true)
|
|
} else
|
|
;
|
|
}
|
|
runTest("isWindows", Versions.windows, WIN=>{
|
|
os = "Windows";
|
|
const nt_ver = WIN.split(" ")[2];
|
|
if (nt_ver)
|
|
switch (nt_ver) {
|
|
case "5.0":
|
|
os_version = "2000";
|
|
break;
|
|
case "5.1":
|
|
os_version = "XP";
|
|
break;
|
|
case "5.2":
|
|
os_version = "XP";
|
|
break;
|
|
case "6.0":
|
|
os_version = "Vista";
|
|
break;
|
|
case "6.1":
|
|
os_version = "7";
|
|
break;
|
|
case "6.2":
|
|
os_version = "8";
|
|
break;
|
|
case "6.3":
|
|
os_version = "8.1";
|
|
break;
|
|
case "10.0":
|
|
os_version = "10";
|
|
break
|
|
}
|
|
}
|
|
);
|
|
runTest("isOSX", Versions.OSX, OSX=>{
|
|
os = "Mac OS X";
|
|
const osx_ver = OSX.split(" ")[3];
|
|
if (osx_ver)
|
|
os_version = osx_ver.replace("_", ".")
|
|
}
|
|
);
|
|
runTest("isLinux", Flags.linux, ()=>{
|
|
os = "Linux"
|
|
}
|
|
);
|
|
runTest("isChromeOS", Flags.chromeOS, ()=>{
|
|
os = "Chrome OS"
|
|
}
|
|
);
|
|
runTest("isAndroid", !Flags.windowsTizen && Versions.android, AND=>{
|
|
os = "Android";
|
|
const android_ver = AND.split(" ")[1];
|
|
if (android_ver)
|
|
os_version = android_ver
|
|
}
|
|
);
|
|
runTest("isTizen", Versions.tizen, TIZ=>{
|
|
os = "Tizen";
|
|
const tizen_ver = TIZ.split(" ")[1];
|
|
if (tizen_ver)
|
|
os_version = tizen_ver
|
|
}
|
|
);
|
|
runTest("isIPhone", !Flags.windowsTizen && Versions.iphone, IOS=>{
|
|
os = "iOS";
|
|
const ios_ver = IOS.split(" ")[2];
|
|
if (ios_ver)
|
|
os_version = ios_ver.replace("_", ".")
|
|
}
|
|
);
|
|
runTest("isIPad", !Flags.windowsTizen && Versions.ipad, IOS=>{
|
|
os = "iOS";
|
|
const ios_ver = IOS.split(" ")[3];
|
|
if (ios_ver)
|
|
os_version = ios_ver.replace("_", ".")
|
|
}
|
|
);
|
|
runTest("isWindowsPhone", Versions.winPhone, WIN=>{
|
|
os = "Windows Phone";
|
|
const ver_str = WIN.split(" ")[2];
|
|
if (ver_str)
|
|
os_version = ver_str
|
|
}
|
|
);
|
|
runTest("isWindowsPhoneOS", Versions.winPhoneOS, WIN=>{
|
|
os = "Windows Phone";
|
|
const ver_str = WIN.split(" ")[3];
|
|
if (ver_str)
|
|
os_version = ver_str
|
|
}
|
|
);
|
|
runTest("isBlackberry", Flags.blackberry, ()=>{
|
|
os = "Blackberry";
|
|
os_version = "10";
|
|
browser = "stock";
|
|
engine = "webkit"
|
|
}
|
|
);
|
|
runTest("isChrome", !Flags.edge && !Flags.opera && Versions.chrome, CHR=>{
|
|
browser = "Chrome";
|
|
engine = "Chromium";
|
|
const ver_str = CHR.split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
);
|
|
runTest("isOpera", Versions.opera, OPR=>{
|
|
browser = "Opera";
|
|
engine = "Chromium";
|
|
const ver_str = OPR.split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
);
|
|
runTest("isChromium", Versions.chromium, CHR=>{
|
|
browser = "Chromium";
|
|
engine = "Chromium";
|
|
const ver_str = CHR.split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
);
|
|
runTest("isFirefox", Versions.firefox, FIR=>{
|
|
browser = "Firefox";
|
|
engine = "Gecko";
|
|
const ver_str = FIR.split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
);
|
|
runTest("isInternetExplorer", Versions.ie, IE=>{
|
|
browser = "Internet Explorer";
|
|
engine = "Trident";
|
|
const ver_str = IE.split(" ")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
);
|
|
runTest("isTrident", browser !== "Internet Explorer" && Flags.trident, ()=>{
|
|
engine = "Trident";
|
|
const rRv = /rv:[0-9.]+/i.exec(UA);
|
|
if (rRv && rRv.length) {
|
|
browser = "Internet Explorer";
|
|
const ver_str = rRv[0].split(":")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
}
|
|
);
|
|
runTest("isEdge", Versions.edge, EDGE=>{
|
|
browser = "Edge";
|
|
engine = "Edge";
|
|
const ver_str = EDGE.split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
);
|
|
runTest("isEdgeChromium", Versions.edgeChromium, EDGECHR=>{
|
|
browser = "Edge";
|
|
engine = "Chromium";
|
|
const ver_str = EDGECHR.split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
);
|
|
runTest("isSafari", Flags.safari && !Flags.nokia && !Flags.chrome && !Flags.chromium && !Flags.genericIE && !Flags.blackberry, ()=>{
|
|
browser = "Safari";
|
|
engine = "WebKit";
|
|
const rVersion = /version\/[0-9.]+/i.exec(UA);
|
|
const rChromeiOS = /crios\/[0-9.]+/i.exec(UA);
|
|
const rFirefoxiOS = /fxios\/[0-9.]+/i.exec(UA);
|
|
if (rVersion && rVersion.length) {
|
|
const ver_str = rVersion[0].split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
if (rChromeiOS && rChromeiOS.length) {
|
|
browser = "Chrome for iOS";
|
|
const ver_str = rChromeiOS[0].split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
if (rFirefoxiOS && rFirefoxiOS.length) {
|
|
browser = "Firefox for iOS";
|
|
const ver_str = rFirefoxiOS[0].split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
}
|
|
);
|
|
runTest("isSilk", Versions.silk, SILK=>{
|
|
browser = "Silk";
|
|
const ver_str = SILK.split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
);
|
|
runTest("isCrosswalk", Flags.crosswalk, ()=>context = "crosswalk");
|
|
runTest("isCordova", self["device"] && (self["device"]["cordova"] || self["device"]["phonegap"]), ()=>context = "cordova");
|
|
runTest("isNWJS", Versions.nwjs, NWJS=>{
|
|
context = "nwjs";
|
|
browser = "NW.js";
|
|
engine = "Chromium";
|
|
const ver_str = NWJS.split("/")[1];
|
|
if (ver_str)
|
|
browser_version = ver_str
|
|
}
|
|
);
|
|
runTest("isAmazonWebApp", Flags.amazonwebapp, ()=>context = "webapp");
|
|
runTest("isHomeScreenWebApp", context !== "nwjs" && typeof window !== "undefined" && (window.matchMedia && window.matchMedia("(display-mode: standalone)").matches || navigator["standalone"]), ()=>context = "webapp");
|
|
runTest("isFalseSafari", browser === "Safari" && (os === "Android" || os === "Tizen" || os === "Blackberry"), ()=>browser = "stock");
|
|
runTest("isAndroidWebview", browser === "Chrome" && context === "browser" && Flags.webview, ()=>context = "webview");
|
|
runTest("isFirefoxOS", browser === "Firefox" && os === UNKNOWN, ()=>os = "Firefox OS");
|
|
runTest("isAndroidFallback", os === UNKNOWN && !Flags.windowsTizen && Flags.android, ()=>os = "Android");
|
|
runTest("isTridentFallback", os === UNKNOWN && Flags.trident, ()=>engine = "Trident");
|
|
runTest("isWebkitFallback", os === UNKNOWN && Flags.webkit, ()=>engine = "WebKit");
|
|
runTest("is64Bit", (is64=>{
|
|
return is64.test(UA) || is64.test(navigator.platform) || navigator.cpuClass === "x64"
|
|
}
|
|
)(/x86_64|x86-64|win64|x64;|x64\)|x64_|amd64|wow64|ia64|arm64|arch64|sparc64|ppc64|irix64/i), ()=>os_arch = "64-bit");
|
|
runTest("is32Bit", (is32=>{
|
|
return is32.test(UA) || is32.test(navigator.platform) || navigator.cpuClass === "x86"
|
|
}
|
|
)(/x86;|x86\)|i86|i386|i486|i586|i686|armv1|armv2|armv3|armv4|armv5|armv6|armv7/i), ()=>os_arch = "32-bit");
|
|
runTest("is64BitFallback", os_arch === UNKNOWN && os === "Mac OS X" && parseFloat(os_version) >= 10.7, ()=>os_arch = "64-bit");
|
|
runTest("is32BitFallback", os_arch === UNKNOWN && os === "Windows" || os === "Android" && parseFloat(os_version) < 5, ()=>os_arch = "32-bit");
|
|
runTest("is32BitBrowser", os_arch === "32-bit" || /wow64/i.test(UA), ()=>browser_arch = "32-bit");
|
|
runTest("is64BitBrowser", /win64/i.test(UA), ()=>browser_arch = "64-bit");
|
|
runTest("isDesktop", (()=>{
|
|
return os === "Windows" || os === "Mac OS X" || os === "Linux" || os === "Chrome OS" || context === "nwjs"
|
|
}
|
|
)(), ()=>is_desktop = true);
|
|
if (engine === "Edge" && typeof Windows !== "undefined" && typeof Windows["System"] !== "undefined")
|
|
context = "windows-store";
|
|
is_desktop_app = context === "nwjs";
|
|
const is_ipad_os = os === "Mac OS X" && navigator["maxTouchPoints"] && navigator["maxTouchPoints"] > 2;
|
|
if (is_ipad_os) {
|
|
os = "iOS";
|
|
os_version = browser_version;
|
|
is_desktop = false;
|
|
is_desktop_app = false
|
|
}
|
|
C3.Platform = {
|
|
OS: os,
|
|
OSVersion: os_version,
|
|
OSArchitecture: os_arch,
|
|
Browser: browser,
|
|
BrowserVersion: browser_version,
|
|
BrowserVersionNumber: parseFloat(browser_version),
|
|
BrowserArchitecture: browser_arch,
|
|
BrowserEngine: engine,
|
|
Context: context,
|
|
IsDesktop: is_desktop,
|
|
IsMobile: !is_desktop,
|
|
IsDesktopApp: is_desktop_app,
|
|
IsChromeWebStore: !!(self["chrome"] && self["chrome"]["runtime"] && self["chrome"]["runtime"]["id"]),
|
|
IsAppleOS: os === "Mac OS X" || os === "iOS",
|
|
IsIpadOS: is_ipad_os
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const VERSION = 2;
|
|
const STORE_NAME = "keyvaluepairs";
|
|
const DATABASE_PROMISE_MAP = new Map;
|
|
const SUPPORTS_GETALL = typeof IDBObjectStore !== "undefined" && typeof IDBObjectStore.prototype.getAll === "function";
|
|
const SUPPORTS_GETALLKEYS = typeof IDBObjectStore !== "undefined" && typeof IDBObjectStore.prototype.getAllKeys === "function";
|
|
function asyncifyRequest(request) {
|
|
return new Promise((res,rej)=>{
|
|
request.onsuccess = ()=>res(request.result);
|
|
request.onerror = ()=>rej(request.error)
|
|
}
|
|
)
|
|
}
|
|
function asyncifyTransaction(tx) {
|
|
return new Promise((res,rej)=>{
|
|
tx.oncomplete = ()=>res();
|
|
tx.onerror = ()=>rej(tx.error);
|
|
tx.onabort = ()=>rej(tx.error)
|
|
}
|
|
)
|
|
}
|
|
function openReadOnlyTransaction(name, method) {
|
|
return openTransaction(name, method)
|
|
}
|
|
function openWriteTransaction(name, method) {
|
|
return openTransaction(name, method, true)
|
|
}
|
|
async function openTransaction(name, method, write=false, allowRetry=true) {
|
|
const db = await lazyOpenDatabase(name);
|
|
try {
|
|
const tx = db.transaction([STORE_NAME], write ? "readwrite" : "readonly");
|
|
return method(tx)
|
|
} catch (err) {
|
|
if (allowRetry && err["name"] === "InvalidStateError") {
|
|
DATABASE_PROMISE_MAP.delete(name);
|
|
return openTransaction(name, method, write, false)
|
|
} else
|
|
throw err;
|
|
}
|
|
}
|
|
function lazyOpenDatabase(name) {
|
|
RequireString(name);
|
|
let dbPromise = DATABASE_PROMISE_MAP.get(name);
|
|
if (!(dbPromise instanceof Promise)) {
|
|
dbPromise = openDatabase(name);
|
|
DATABASE_PROMISE_MAP.set(name, dbPromise);
|
|
dbPromise.catch(err=>DATABASE_PROMISE_MAP.delete(name))
|
|
}
|
|
return dbPromise
|
|
}
|
|
async function openDatabase(name) {
|
|
RequireString(name);
|
|
const openRequest = indexedDB.open(name, VERSION);
|
|
openRequest.addEventListener("upgradeneeded", e=>{
|
|
try {
|
|
const db = e.target.result;
|
|
db.createObjectStore(STORE_NAME)
|
|
} catch (err) {
|
|
console.error(`Failed to create objectstore for database ${name}`, err)
|
|
}
|
|
}
|
|
);
|
|
return asyncifyRequest(openRequest)
|
|
}
|
|
function RequireString(x) {
|
|
if (typeof x !== "string")
|
|
throw new TypeError("expected string");
|
|
}
|
|
function getEntriesFromCursor(tx, type) {
|
|
const request = tx.objectStore(STORE_NAME).openCursor();
|
|
return new Promise(resolve=>{
|
|
const results = [];
|
|
request.onsuccess = event=>{
|
|
const cursor = event.target.result;
|
|
if (cursor) {
|
|
switch (type) {
|
|
case "entries":
|
|
results.push([cursor.key, cursor.value]);
|
|
break;
|
|
case "keys":
|
|
results.push(cursor.key);
|
|
break;
|
|
case "values":
|
|
results.push(cursor.value);
|
|
break
|
|
}
|
|
cursor.continue()
|
|
} else
|
|
resolve(results)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
class KVStorageContainer {
|
|
constructor(name) {
|
|
RequireString(name);
|
|
this.name = name
|
|
}
|
|
async ready() {
|
|
await lazyOpenDatabase(this.name)
|
|
}
|
|
set(key, value) {
|
|
RequireString(key);
|
|
return openWriteTransaction(this.name, async tx=>{
|
|
const request = tx.objectStore(STORE_NAME).put(value, key);
|
|
const requestPromise = asyncifyRequest(request);
|
|
const txPromise = asyncifyTransaction(tx);
|
|
await Promise.all([txPromise, requestPromise])
|
|
}
|
|
)
|
|
}
|
|
get(key) {
|
|
RequireString(key);
|
|
return openReadOnlyTransaction(this.name, async tx=>{
|
|
const request = tx.objectStore(STORE_NAME).get(key);
|
|
const requestPromise = asyncifyRequest(request);
|
|
const txPromise = asyncifyTransaction(tx);
|
|
const [_,value] = await Promise.all([txPromise, requestPromise]);
|
|
return value
|
|
}
|
|
)
|
|
}
|
|
delete(key) {
|
|
RequireString(key);
|
|
return openWriteTransaction(this.name, async tx=>{
|
|
const request = tx.objectStore(STORE_NAME).delete(key);
|
|
const requestPromise = asyncifyRequest(request);
|
|
const txPromise = asyncifyTransaction(tx);
|
|
await Promise.all([txPromise, requestPromise])
|
|
}
|
|
)
|
|
}
|
|
clear() {
|
|
return openWriteTransaction(this.name, async tx=>{
|
|
const request = tx.objectStore(STORE_NAME).clear();
|
|
const requestPromise = asyncifyRequest(request);
|
|
const txPromise = asyncifyTransaction(tx);
|
|
await Promise.all([txPromise, requestPromise])
|
|
}
|
|
)
|
|
}
|
|
keys() {
|
|
return openReadOnlyTransaction(this.name, async tx=>{
|
|
let requestPromise;
|
|
if (SUPPORTS_GETALLKEYS) {
|
|
const request = tx.objectStore(STORE_NAME).getAllKeys();
|
|
requestPromise = asyncifyRequest(request)
|
|
} else
|
|
requestPromise = getEntriesFromCursor(tx, "keys");
|
|
const txPromise = asyncifyTransaction(tx);
|
|
const [_,value] = await Promise.all([txPromise, requestPromise]);
|
|
return value
|
|
}
|
|
)
|
|
}
|
|
values() {
|
|
return openReadOnlyTransaction(this.name, async tx=>{
|
|
let requestPromise;
|
|
if (SUPPORTS_GETALL) {
|
|
const request = tx.objectStore(STORE_NAME).getAll();
|
|
requestPromise = asyncifyRequest(request)
|
|
} else
|
|
requestPromise = getEntriesFromCursor(tx, "values");
|
|
const txPromise = asyncifyTransaction(tx);
|
|
const [_,value] = await Promise.all([txPromise, requestPromise]);
|
|
return value
|
|
}
|
|
)
|
|
}
|
|
entries() {
|
|
return openReadOnlyTransaction(this.name, async tx=>{
|
|
const requestPromise = getEntriesFromCursor(tx, "entries");
|
|
const txPromise = asyncifyTransaction(tx);
|
|
const [_,value] = await Promise.all([txPromise, requestPromise]);
|
|
return value
|
|
}
|
|
)
|
|
}
|
|
}
|
|
self.KVStorageContainer = KVStorageContainer
|
|
}
|
|
;'use strict';
|
|
{
|
|
const KVStorageContainer = self.KVStorageContainer;
|
|
const CRITICAL_ERRORS = [/no available storage method found/i, /an attempt was made to break through the security policy of the user agent/i, /the user denied permission to access the database/i, /a mutation operation was attempted on a database that did not allow mutations/i, /idbfactory\.open\(\) called in an invalid security context/i];
|
|
const memoryStorage = new WeakMap;
|
|
let isInMemory = false;
|
|
if (typeof indexedDB === "undefined") {
|
|
isInMemory = true;
|
|
console.warn("Unable to use local storage because indexedDB is not defined")
|
|
}
|
|
function NOT_IMPLEMENTED(name) {
|
|
throw new Error(`"${name}" is not implemented`);
|
|
}
|
|
function DISALLOW_CALLBACK(fn) {
|
|
if (typeof fn === "function")
|
|
throw new Error(`localforage callback API is not implemented; please use the promise API instead`);
|
|
}
|
|
function StructuredClone(value) {
|
|
if (typeof value === "object")
|
|
return new Promise(resolve=>{
|
|
const {port1, port2} = new MessageChannel;
|
|
port2.onmessage = ev=>resolve(ev.data);
|
|
port1.postMessage(value)
|
|
}
|
|
);
|
|
else
|
|
return Promise.resolve(value)
|
|
}
|
|
class ForageAdaptor {
|
|
constructor(inst) {
|
|
this._inst = inst;
|
|
memoryStorage.set(this, new Map)
|
|
}
|
|
_MaybeSwitchToMemoryFallback(err) {
|
|
if (isInMemory)
|
|
return;
|
|
for (const regex of CRITICAL_ERRORS)
|
|
if (err && regex.test(err.message)) {
|
|
console.error("Unable to use local storage, reverting to in-memory store: ", err, err.message);
|
|
isInMemory = true;
|
|
break
|
|
}
|
|
}
|
|
async _getItemFallback(name) {
|
|
const value = memoryStorage.get(this).get(name);
|
|
const ret = await StructuredClone(value);
|
|
return typeof ret === "undefined" ? null : ret
|
|
}
|
|
async _setItemFallback(name, value) {
|
|
value = await StructuredClone(value);
|
|
memoryStorage.get(this).set(name, value)
|
|
}
|
|
_removeItemFallback(name) {
|
|
memoryStorage.get(this).delete(name)
|
|
}
|
|
_clearFallback() {
|
|
memoryStorage.get(this).clear()
|
|
}
|
|
_keysFallback() {
|
|
return Array.from(memoryStorage.get(this).keys())
|
|
}
|
|
IsUsingFallback() {
|
|
return isInMemory
|
|
}
|
|
async getItem(key, successCallback) {
|
|
DISALLOW_CALLBACK(successCallback);
|
|
if (isInMemory)
|
|
return await this._getItemFallback(key);
|
|
let result;
|
|
try {
|
|
result = await this._inst.get(key)
|
|
} catch (err) {
|
|
this._MaybeSwitchToMemoryFallback(err);
|
|
if (isInMemory)
|
|
return await this._getItemFallback(key);
|
|
else {
|
|
console.error(`Error reading '${key}' from storage, returning null: `, err);
|
|
return null
|
|
}
|
|
}
|
|
return typeof result === "undefined" ? null : result
|
|
}
|
|
async setItem(key, value, successCallback) {
|
|
DISALLOW_CALLBACK(successCallback);
|
|
if (typeof value === "undefined")
|
|
value = null;
|
|
if (isInMemory) {
|
|
await this._setItemFallback(key, value);
|
|
return
|
|
}
|
|
try {
|
|
await this._inst.set(key, value)
|
|
} catch (err) {
|
|
this._MaybeSwitchToMemoryFallback(err);
|
|
if (isInMemory)
|
|
await this._setItemFallback(key, value);
|
|
else
|
|
throw err;
|
|
}
|
|
}
|
|
async removeItem(key, successCallback) {
|
|
DISALLOW_CALLBACK(successCallback);
|
|
if (isInMemory) {
|
|
this._removeItemFallback(key);
|
|
return
|
|
}
|
|
try {
|
|
await this._inst.delete(key)
|
|
} catch (err) {
|
|
this._MaybeSwitchToMemoryFallback(err);
|
|
if (isInMemory)
|
|
this._removeItemFallback(key);
|
|
else
|
|
console.error(`Error removing '${key}' from storage: `, err)
|
|
}
|
|
}
|
|
async clear(successCallback) {
|
|
DISALLOW_CALLBACK(successCallback);
|
|
if (isInMemory) {
|
|
this._clearFallback();
|
|
return
|
|
}
|
|
try {
|
|
await this._inst.clear()
|
|
} catch (err) {
|
|
this._MaybeSwitchToMemoryFallback(err);
|
|
if (isInMemory)
|
|
this._clearFallback();
|
|
else
|
|
console.error(`Error clearing storage: `, err)
|
|
}
|
|
}
|
|
async keys(successCallback) {
|
|
DISALLOW_CALLBACK(successCallback);
|
|
if (isInMemory)
|
|
return this._keysFallback();
|
|
let result = [];
|
|
try {
|
|
result = await this._inst.keys()
|
|
} catch (err) {
|
|
this._MaybeSwitchToMemoryFallback(err);
|
|
if (isInMemory)
|
|
return this._keysFallback();
|
|
else
|
|
console.error(`Error getting storage keys: `, err)
|
|
}
|
|
return result
|
|
}
|
|
ready(successCallback) {
|
|
DISALLOW_CALLBACK(successCallback);
|
|
if (isInMemory)
|
|
return Promise.resolve(true);
|
|
else
|
|
return this._inst.ready()
|
|
}
|
|
createInstance(options) {
|
|
if (typeof options !== "object")
|
|
throw new TypeError("invalid options object");
|
|
const name = options["name"];
|
|
if (typeof name !== "string")
|
|
throw new TypeError("invalid store name");
|
|
const inst = new KVStorageContainer(name);
|
|
return new ForageAdaptor(inst)
|
|
}
|
|
length(successCallback) {
|
|
NOT_IMPLEMENTED("localforage.length()")
|
|
}
|
|
key(index, successCallback) {
|
|
NOT_IMPLEMENTED("localforage.key()")
|
|
}
|
|
iterate(iteratorCallback, successCallback) {
|
|
NOT_IMPLEMENTED("localforage.iterate()")
|
|
}
|
|
setDriver(driverName) {
|
|
NOT_IMPLEMENTED("localforage.setDriver()")
|
|
}
|
|
config(options) {
|
|
NOT_IMPLEMENTED("localforage.config()")
|
|
}
|
|
defineDriver(customDriver) {
|
|
NOT_IMPLEMENTED("localforage.defineDriver()")
|
|
}
|
|
driver() {
|
|
NOT_IMPLEMENTED("localforage.driver()")
|
|
}
|
|
supports(driverName) {
|
|
NOT_IMPLEMENTED("localforage.supports()")
|
|
}
|
|
dropInstance() {
|
|
NOT_IMPLEMENTED("localforage.dropInstance()")
|
|
}
|
|
disableMemoryMode() {
|
|
isInMemory = false
|
|
}
|
|
}
|
|
self["localforage"] = new ForageAdaptor(new KVStorageContainer("localforage"))
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Supports = {};
|
|
C3.Supports.WebAnimations = (()=>{
|
|
try {
|
|
if (C3.Platform.Browser === "Safari")
|
|
return false;
|
|
if (typeof document === "undefined")
|
|
return false;
|
|
const e = document.createElement("div");
|
|
if (typeof e.animate === "undefined")
|
|
return false;
|
|
const player = e.animate([{
|
|
opacity: "0"
|
|
}, {
|
|
opacity: "1"
|
|
}], 1E3);
|
|
return typeof player.reverse !== "undefined"
|
|
} catch (e) {
|
|
return false
|
|
}
|
|
}
|
|
)();
|
|
C3.Supports.DialogElement = typeof HTMLDialogElement !== "undefined";
|
|
C3.Supports.RequestIdleCallback = !!self.requestIdleCallback;
|
|
C3.Supports.ImageBitmap = !!self.createImageBitmap;
|
|
C3.Supports.ImageBitmapOptions = false;
|
|
if (C3.Supports.ImageBitmap)
|
|
try {
|
|
self.createImageBitmap(new ImageData(32,32), {
|
|
premultiplyAlpha: "none"
|
|
}).then(imageBitmap=>{
|
|
C3.Supports.ImageBitmapOptions = true
|
|
}
|
|
).catch(err=>{
|
|
C3.Supports.ImageBitmapOptions = false
|
|
}
|
|
)
|
|
} catch (e) {
|
|
C3.Supports.ImageBitmapOptions = false
|
|
}
|
|
C3.Supports.ClipboardReadText = !!(navigator["clipboard"] && navigator["clipboard"]["readText"] && C3.Platform.Browser !== "Firefox");
|
|
C3.Supports.PermissionsQuery = !!(navigator["permissions"] && navigator["permissions"]["query"]);
|
|
C3.Supports.Proxies = typeof Proxy !== "undefined";
|
|
C3.Supports.DownloadAttribute = (()=>{
|
|
if (typeof document === "undefined")
|
|
return false;
|
|
const a = document.createElement("a");
|
|
return typeof a.download !== "undefined"
|
|
}
|
|
)();
|
|
C3.Supports.CanvasToBlob = (()=>{
|
|
return typeof HTMLCanvasElement !== "undefined" && HTMLCanvasElement.prototype.toBlob
|
|
}
|
|
)();
|
|
C3.Supports.Fetch = typeof fetch === "function";
|
|
C3.Supports.PersistentStorage = !!(self.isSecureContext && C3.Platform.Browser !== "Opera" && (navigator["storage"] && navigator["storage"]["persist"]));
|
|
C3.Supports.StorageQuotaEstimate = !!(self.isSecureContext && (navigator["storage"] && navigator["storage"]["estimate"]));
|
|
C3.Supports.Fullscreen = (()=>{
|
|
if (typeof document === "undefined")
|
|
return false;
|
|
if (C3.Platform.OS === "iOS")
|
|
return false;
|
|
const elem = document.documentElement;
|
|
return !!(elem.requestFullscreen || elem.msRequestFullscreen || elem.mozRequestFullScreen || elem.webkitRequestFullscreen)
|
|
}
|
|
)();
|
|
C3.Supports.ImageDecoder = typeof self["ImageDecoder"] !== "undefined";
|
|
C3.Supports.NativeFileSystemAPI = !!self["showOpenFilePicker"];
|
|
C3.Supports.NavigatorFontsQuery = !!(navigator["fonts"] && navigator["fonts"]["query"])
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
if (!String.prototype.trimStart) {
|
|
const startWhitespace = /^[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]*/;
|
|
String.prototype.trimStart = function trimStart() {
|
|
return this.replace(startWhitespace, "")
|
|
}
|
|
}
|
|
if (!String.prototype.trimEnd) {
|
|
const endWhitespace = /[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]*$/;
|
|
String.prototype.trimEnd = function trimEnd() {
|
|
return this.replace(endWhitespace, "")
|
|
}
|
|
}
|
|
if (!String.prototype.replaceAll)
|
|
String.prototype.replaceAll = function replaceAll(find, replace) {
|
|
return this.replace(new RegExp(C3.EscapeRegex(find),"g"), replace)
|
|
}
|
|
;
|
|
if (!Array.prototype.values)
|
|
Array.prototype.values = function*() {
|
|
for (const i of this)
|
|
yield i
|
|
}
|
|
;
|
|
if (!Array.prototype.flat) {
|
|
function arrayFlat(arr, depth) {
|
|
return arr.reduce((acc,val)=>{
|
|
if (depth > 0 && Array.isArray(val)) {
|
|
Array.prototype.push.apply(acc, arrayFlat(val, depth - 1));
|
|
return acc
|
|
} else {
|
|
acc.push(val);
|
|
return acc
|
|
}
|
|
}
|
|
, [])
|
|
}
|
|
Array.prototype.flat = function(depth=1) {
|
|
return arrayFlat(this, depth)
|
|
}
|
|
}
|
|
if (!RegExp.escape)
|
|
RegExp.escape = function(s) {
|
|
return String(s).replace(/[\\^$*+?.()|[\]{}]/g, "\\$&")
|
|
}
|
|
;
|
|
if (navigator["storage"] && !navigator["storage"]["estimate"] && navigator["webkitTemporaryStorage"] && navigator["webkitTemporaryStorage"]["queryUsageAndQuota"])
|
|
navigator["storage"]["estimate"] = function() {
|
|
return new Promise((resolve,reject)=>{
|
|
return navigator["webkitTemporaryStorage"]["queryUsageAndQuota"]((usage,quota)=>resolve({
|
|
"usage": usage,
|
|
"quota": quota
|
|
}), reject)
|
|
}
|
|
)
|
|
}
|
|
;
|
|
if (typeof HTMLCollection !== "undefined" && !HTMLCollection.prototype[Symbol.iterator])
|
|
HTMLCollection.prototype[Symbol.iterator] = function() {
|
|
let i = 0;
|
|
return {
|
|
next: ()=>{
|
|
if (i >= this.length)
|
|
return {
|
|
done: true
|
|
};
|
|
else
|
|
return {
|
|
value: this.item(i++),
|
|
done: false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;
|
|
if (typeof NodeList !== "undefined" && !NodeList.prototype[Symbol.iterator])
|
|
NodeList.prototype[Symbol.iterator] = function() {
|
|
let i = 0;
|
|
return {
|
|
next: ()=>{
|
|
if (i >= this.length)
|
|
return {
|
|
done: true
|
|
};
|
|
else
|
|
return {
|
|
value: this.item(i++),
|
|
done: false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;
|
|
if (typeof DOMTokenList !== "undefined" && !DOMTokenList.prototype[Symbol.iterator])
|
|
DOMTokenList.prototype[Symbol.iterator] = function() {
|
|
let i = 0;
|
|
return {
|
|
next: ()=>{
|
|
if (i >= this.length)
|
|
return {
|
|
done: true
|
|
};
|
|
else
|
|
return {
|
|
value: this.item(i++),
|
|
done: false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;
|
|
if (typeof FileList !== "undefined" && !FileList.prototype[Symbol.iterator])
|
|
FileList.prototype[Symbol.iterator] = function() {
|
|
let i = 0;
|
|
return {
|
|
next: ()=>{
|
|
if (i >= this.length)
|
|
return {
|
|
done: true
|
|
};
|
|
else
|
|
return {
|
|
value: this.item(i++),
|
|
done: false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;
|
|
if (typeof TextEncoder === "undefined") {
|
|
self.TextEncoder = class TextEncoder {
|
|
constructor() {
|
|
Object.defineProperty(this, "encoding", {
|
|
"value": "utf-8",
|
|
"writable": false
|
|
})
|
|
}
|
|
encode(str) {
|
|
var Len = str.length
|
|
, resPos = -1;
|
|
var resArr = new Uint8Array(Len * 3);
|
|
for (var point = 0, nextcode = 0, i = 0; i !== Len; ) {
|
|
point = str.charCodeAt(i),
|
|
i += 1;
|
|
if (point >= 55296 && point <= 56319) {
|
|
if (i === Len) {
|
|
resArr[resPos += 1] = 239;
|
|
resArr[resPos += 1] = 191;
|
|
resArr[resPos += 1] = 189;
|
|
break
|
|
}
|
|
nextcode = str.charCodeAt(i);
|
|
if (nextcode >= 56320 && nextcode <= 57343) {
|
|
point = (point - 55296) * 1024 + nextcode - 56320 + 65536;
|
|
i += 1;
|
|
if (point > 65535) {
|
|
resArr[resPos += 1] = 30 << 3 | point >>> 18;
|
|
resArr[resPos += 1] = 2 << 6 | point >>> 12 & 63;
|
|
resArr[resPos += 1] = 2 << 6 | point >>> 6 & 63;
|
|
resArr[resPos += 1] = 2 << 6 | point & 63;
|
|
continue
|
|
}
|
|
} else {
|
|
resArr[resPos += 1] = 239;
|
|
resArr[resPos += 1] = 191;
|
|
resArr[resPos += 1] = 189;
|
|
continue
|
|
}
|
|
}
|
|
if (point <= 127)
|
|
resArr[resPos += 1] = 0 << 7 | point;
|
|
else if (point <= 2047) {
|
|
resArr[resPos += 1] = 6 << 5 | point >>> 6;
|
|
resArr[resPos += 1] = 2 << 6 | point & 63
|
|
} else {
|
|
resArr[resPos += 1] = 14 << 4 | point >>> 12;
|
|
resArr[resPos += 1] = 2 << 6 | point >>> 6 & 63;
|
|
resArr[resPos += 1] = 2 << 6 | point & 63
|
|
}
|
|
}
|
|
return new Uint8Array(resArr.buffer.slice(0, resPos + 1))
|
|
}
|
|
toString() {
|
|
return "[object TextEncoder]"
|
|
}
|
|
}
|
|
;
|
|
TextEncoder[Symbol.toStringTag] = "TextEncoder"
|
|
}
|
|
if (typeof TextDecoder === "undefined") {
|
|
function persist(iterable) {
|
|
const itr = iterable[Symbol.iterator]();
|
|
return {
|
|
next: _=>itr.next(),
|
|
[Symbol.iterator]() {
|
|
return this
|
|
}
|
|
}
|
|
}
|
|
function readNext(bytes) {
|
|
const n = bytes.next();
|
|
if (n.done)
|
|
throw new Error("unexpected end of input");
|
|
if ((n.value & 192 ^ 128) != 0)
|
|
throw new Error("invalid byte");
|
|
return n.value & 63
|
|
}
|
|
const _decoders = new Map;
|
|
_decoders.set("utf-8", (arr,fatal)=>{
|
|
let view;
|
|
if (arr.buffer)
|
|
view = new Uint8Array(arr.buffer,arr.byteOffset,arr.byteLength);
|
|
else if (view instanceof ArrayBuffer)
|
|
view = new Uint8Array(arr);
|
|
else
|
|
throw new Error("Invalid parameter");
|
|
const bytes = persist(view);
|
|
const result = [];
|
|
try {
|
|
for (const ch of bytes) {
|
|
let val;
|
|
if (ch < 127)
|
|
val = ch & 127;
|
|
else if (ch < 223)
|
|
val = (ch & 31) << 6 | readNext(bytes);
|
|
else if (ch < 239)
|
|
val = (ch & 15) << 12 | readNext(bytes) << 6 | readNext(bytes);
|
|
else if (ch < 247)
|
|
val = (ch & 7) << 18 | readNext(bytes) << 12 | readNext(bytes) << 6 | readNext(bytes);
|
|
else
|
|
throw new Error("Invalid character");
|
|
result.push(String.fromCodePoint(val))
|
|
}
|
|
} catch (e) {
|
|
if (fatal)
|
|
throw e;
|
|
result.push("\ufffd")
|
|
}
|
|
return result.join("")
|
|
}
|
|
);
|
|
_decoders.set("utf8", _decoders.get("utf-8"));
|
|
_decoders.set("utf-16le", (arr,fatal)=>{
|
|
throw new Error("utf-16le decoder not implemented");
|
|
}
|
|
);
|
|
self.TextDecoder = class TextDecoder {
|
|
constructor(label="utf-8", options={}) {
|
|
const decoder = _decoders.get(label);
|
|
if (!decoder)
|
|
throw new Error(`TextDecoder polyfill does not support "${label}"`);
|
|
Object.defineProperty(this, "fatal", {
|
|
"value": options["fatal"] === true,
|
|
"writable": false
|
|
});
|
|
Object.defineProperty(this, "_decoder", {
|
|
"value": decoder,
|
|
"writable": false
|
|
});
|
|
Object.defineProperty(this, "encoding", {
|
|
"value": label,
|
|
"writable": false
|
|
})
|
|
}
|
|
decode(arr) {
|
|
return this["_decoder"](arr, this["fatal"])
|
|
}
|
|
toString() {
|
|
return "[object TextDecoder]"
|
|
}
|
|
}
|
|
;
|
|
TextDecoder[Symbol.toStringTag] = "TextDecoder"
|
|
}
|
|
if (typeof self.isSecureContext === "undefined")
|
|
self.isSecureContext = location.protocol === "https:";
|
|
if (typeof self["globalThis"] === "undefined")
|
|
self["globalThis"] = self
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function assertFail(msg_) {
|
|
let stack = C3.GetCallStack();
|
|
let msg = "Assertion failure: " + msg_ + "\n\nStack trace:\n" + stack;
|
|
console.error(msg)
|
|
}
|
|
self.assert = function assert(cnd_, msg_) {
|
|
if (!cnd_)
|
|
assertFail(msg_)
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.IsNumber = function IsNumber(x) {
|
|
return typeof x === "number"
|
|
}
|
|
;
|
|
C3.IsFiniteNumber = function IsFiniteNumber(x) {
|
|
return C3.IsNumber(x) && isFinite(x)
|
|
}
|
|
;
|
|
C3.RequireNumber = function RequireNumber(x) {
|
|
if (!C3.IsNumber(x))
|
|
throw new TypeError("expected number");
|
|
}
|
|
;
|
|
C3.RequireOptionalNumber = function RequireOptionalNumber(x) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return
|
|
}
|
|
;
|
|
C3.RequireNumberInRange = function RequireNumberInRange(x, low, high) {
|
|
if (!C3.IsNumber(x) || isNaN(x) || low > x || high < x)
|
|
throw new RangeError("number outside of range");
|
|
}
|
|
;
|
|
C3.RequireAllNumber = function RequireAllNumber(...args) {
|
|
for (let a of args)
|
|
;
|
|
}
|
|
;
|
|
C3.RequireFiniteNumber = function RequireFiniteNumber(x) {
|
|
if (!C3.IsFiniteNumber(x))
|
|
throw new TypeError("expected finite number");
|
|
}
|
|
;
|
|
C3.RequireOptionalFiniteNumber = function RequireOptionalFiniteNumber(x) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return
|
|
}
|
|
;
|
|
C3.RequireAllFiniteNumber = function RequireAllFiniteNumber(...args) {
|
|
for (let a of args)
|
|
;
|
|
}
|
|
;
|
|
C3.IsString = function IsString(x) {
|
|
return typeof x === "string"
|
|
}
|
|
;
|
|
C3.RequireString = function RequireString(x) {
|
|
if (!C3.IsString(x))
|
|
throw new TypeError("expected string");
|
|
}
|
|
;
|
|
C3.RequireOptionalString = function RequireOptionalString(x) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return
|
|
}
|
|
;
|
|
C3.RequireAllString = function RequireAllString(...args) {
|
|
for (let a of args)
|
|
;
|
|
}
|
|
;
|
|
C3.IsSimpleObject = function IsSimpleObject(x) {
|
|
if (typeof x !== "object" || x === null)
|
|
return false;
|
|
let proto = Object.getPrototypeOf(x);
|
|
return proto ? proto.constructor === Object : proto === null
|
|
}
|
|
;
|
|
C3.RequireSimpleObject = function RequireSimpleObject(x) {
|
|
if (!C3.IsSimpleObject(x))
|
|
throw new TypeError("expected simple object");
|
|
}
|
|
;
|
|
C3.RequireOptionalSimpleObject = function RequireSimpleObject(x) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return;
|
|
if (!C3.IsSimpleObject(x))
|
|
throw new TypeError("expected simple object");
|
|
}
|
|
;
|
|
C3.IsObject = function IsObject(x) {
|
|
return typeof x === "object" && x !== null && !Array.isArray(x)
|
|
}
|
|
;
|
|
C3.RequireObject = function RequireObject(x) {
|
|
if (!C3.IsObject(x))
|
|
throw new TypeError("expected object");
|
|
}
|
|
;
|
|
C3.RequireOptionalObject = function RequireOptionalObject(x) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return
|
|
}
|
|
;
|
|
C3.RequireAllObject = function RequireAllObject(...args) {
|
|
for (let a of args)
|
|
;
|
|
}
|
|
;
|
|
C3.IsFileLike = function IsFileLike(x) {
|
|
return C3.IsInstanceOf(x, Blob) && typeof x["name"] === "string"
|
|
}
|
|
;
|
|
C3.RequireFileLike = function RequireFileLike(x) {
|
|
if (!C3.IsFileLike(x))
|
|
throw new TypeError("expected file");
|
|
}
|
|
;
|
|
C3.RequireOptionalFileLike = function RequireOptionalFileLike(x) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return
|
|
}
|
|
;
|
|
C3.IsArray = function IsArray(x) {
|
|
return Array.isArray(x)
|
|
}
|
|
;
|
|
C3.RequireArray = function RequireArray(x) {
|
|
if (!C3.IsArray(x))
|
|
throw new TypeError("expected array");
|
|
}
|
|
;
|
|
C3.RequireOptionalArray = function RequireOptionalArray(x) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return
|
|
}
|
|
;
|
|
C3.RequireAllArray = function RequireAllArray(...args) {
|
|
for (let a of args)
|
|
;
|
|
}
|
|
;
|
|
C3.Is2DArray = function(x) {
|
|
if (!C3.IsArray(x))
|
|
return false;
|
|
if (!x.length)
|
|
return true;
|
|
if (!C3.IsArray(x[0]))
|
|
return false;
|
|
return true
|
|
}
|
|
;
|
|
C3.Require2DArray = function Require2DArray(x) {
|
|
if (!C3.Is2DArray(x))
|
|
throw new TypeError("expected 2d array");
|
|
for (let arr of x)
|
|
if (!C3.IsArray(arr))
|
|
throw new TypeError("expected 2d array");
|
|
}
|
|
;
|
|
C3.RequireOptional2DArray = function Require2DArray(x) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return
|
|
}
|
|
;
|
|
C3.IsFunction = function IsFunction(x) {
|
|
return typeof x === "function"
|
|
}
|
|
;
|
|
C3.RequireFunction = function RequireFunction(x, f) {
|
|
if (!C3.IsFunction(x))
|
|
throw new TypeError("expected function");
|
|
if (!C3.IsNullOrUndefined(f))
|
|
if (x !== f)
|
|
throw new TypeError("expected same function reference");
|
|
}
|
|
;
|
|
C3.RequireOptionalFunction = function RequireOptionalFunction(x) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return
|
|
}
|
|
;
|
|
C3.RequireAllFunction = function RequireAllFunction(...args) {
|
|
for (let a of args)
|
|
;
|
|
}
|
|
;
|
|
C3.RequireAnyFunction = function RequireAllFunction(x, ...args) {
|
|
if (!C3.IsFunction(x))
|
|
throw new TypeError("expected function");
|
|
if (!args.length)
|
|
throw new Error("missing comparison functions");
|
|
for (let a of args)
|
|
if (!C3.IsNullOrUndefined(a))
|
|
if (x === a)
|
|
return;
|
|
throw new TypeError("expected same function reference");
|
|
}
|
|
;
|
|
C3.RequireOptionalAllFunction = function RequireAllFunction(...args) {
|
|
if (C3.IsNullOrUndefined(args))
|
|
return;
|
|
for (let a of args)
|
|
;
|
|
}
|
|
;
|
|
C3.IsInstanceOf = function IsInstanceOf(x, t) {
|
|
return x instanceof t
|
|
}
|
|
;
|
|
C3.IsInstanceOfAny = function IsInstanceOfAny(x, ...args) {
|
|
for (let t of args)
|
|
if (C3.IsInstanceOf(x, t))
|
|
return true;
|
|
return false
|
|
}
|
|
;
|
|
C3.RequireInstanceOf = function RequireInstanceOf(x, t) {
|
|
if (!C3.IsInstanceOf(x, t))
|
|
throw new TypeError("unexpected type");
|
|
}
|
|
;
|
|
C3.RequireOptionalInstanceOf = function RequireOptionalInstanceOf(x, t) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return
|
|
}
|
|
;
|
|
C3.RequireAllInstanceOf = function RequireAllInstanceOf(t, ...args) {
|
|
for (let a of args)
|
|
;
|
|
}
|
|
;
|
|
C3.RequireAnyInstanceOf = function RequireAnyInstanceOf(x, ...args) {
|
|
if (!C3.IsInstanceOfAny(x, ...args))
|
|
throw new TypeError("unexpected type");
|
|
}
|
|
;
|
|
C3.RequireAnyOptionalInstanceOf = function RequireAnyOptionalInstanceOf(x, ...args) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return;
|
|
if (!C3.IsInstanceOfAny(x, ...args))
|
|
throw new TypeError("unexpected type");
|
|
}
|
|
;
|
|
C3.IsArrayOf = function IsArrayOf(x, t) {
|
|
for (let i of x)
|
|
if (!C3.IsInstanceOf(i, t))
|
|
return false;
|
|
return true
|
|
}
|
|
;
|
|
C3.IsArrayOfFiniteNumbers = function IsArrayOf(x) {
|
|
for (let i of x)
|
|
if (!C3.IsFiniteNumber(i))
|
|
return false;
|
|
return true
|
|
}
|
|
;
|
|
C3.RequireArrayOf = function RequireArrayOf(x, t) {
|
|
for (let i of x)
|
|
;
|
|
}
|
|
;
|
|
C3.RequireOptionalArrayOf = function RequireOptionalArrayOf(x, t) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return;
|
|
for (let i of x)
|
|
;
|
|
}
|
|
;
|
|
C3.RequireArrayOfAny = function RequireArrayOf(x, ...args) {
|
|
for (let i of x)
|
|
;
|
|
}
|
|
;
|
|
C3.RequireOptionalArrayOfAny = function RequireOptionalArrayOfAny(x, ...args) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return;
|
|
for (let i of x)
|
|
;
|
|
}
|
|
;
|
|
C3.IsDOMNode = function IsDOMNode(d, n) {
|
|
if (C3.IsNullOrUndefined(d) || !C3.IsString(d.nodeName))
|
|
return false;
|
|
return !n || C3.equalsNoCase(d.nodeName, n)
|
|
}
|
|
;
|
|
C3.RequireDOMNode = function RequireDOMNode(d, n) {
|
|
if (C3.IsNullOrUndefined(d) || !C3.IsString(d.nodeName))
|
|
throw new TypeError("expected DOM node");
|
|
if (n && !C3.equalsNoCase(d.nodeName, n))
|
|
throw new TypeError(`expected DOM '${n}' node`);
|
|
}
|
|
;
|
|
C3.RequireOptionalDOMNode = function RequireOptionalDOMNode(d, n) {
|
|
if (C3.IsNullOrUndefined(d))
|
|
return
|
|
}
|
|
;
|
|
C3.IsHTMLElement = function IsHTMLElement(e, t) {
|
|
if (C3.IsNullOrUndefined(e) || !C3.IsString(e.tagName))
|
|
return false;
|
|
return !t || C3.equalsNoCase(e.tagName, t)
|
|
}
|
|
;
|
|
C3.RequireHTMLElement = function RequireHTMLElement(e, t) {
|
|
if (C3.IsNullOrUndefined(e) || !C3.IsString(e.tagName))
|
|
throw new TypeError("expected HTML element");
|
|
if (t && !C3.equalsNoCase(e.tagName, t))
|
|
throw new TypeError(`expected HTML '${t}' element`);
|
|
}
|
|
;
|
|
C3.RequireOptionalHTMLElement = function RequireOptionalHTMLElement(e, t) {
|
|
if (C3.IsNullOrUndefined(e))
|
|
return
|
|
}
|
|
;
|
|
C3.IsDrawable = function IsDrawable(d) {
|
|
return C3.IsHTMLElement(d, "img") || C3.IsHTMLElement(d, "canvas") || C3.IsHTMLElement(d, "video") || typeof OffscreenCanvas !== "undefined" && d instanceof OffscreenCanvas || typeof ImageBitmap !== "undefined" && d instanceof ImageBitmap
|
|
}
|
|
;
|
|
C3.RequireDrawable = function RequireDrawable(d) {
|
|
if (!C3.IsDrawable(d))
|
|
throw new TypeError("expected drawable");
|
|
}
|
|
;
|
|
C3.RequireOptionalDrawable = function RequireOptionalDrawable(d) {
|
|
if (C3.IsNullOrUndefined(d))
|
|
return
|
|
}
|
|
;
|
|
C3.IsDrawableOrImageData = function IsDrawableOrImageData(x) {
|
|
if (x instanceof ImageData)
|
|
return true;
|
|
return C3.IsDrawable(x)
|
|
}
|
|
;
|
|
C3.RequireDrawableOrImageData = function RequireDrawableOrImageData(d) {
|
|
if (!C3.IsDrawableOrImageData(d))
|
|
throw new TypeError("expected drawable or image data");
|
|
}
|
|
;
|
|
C3.RequireOptionalDrawableOrImageData = function RequireOptionalDrawableOrImageData(d) {
|
|
if (C3.IsNullOrUndefined(d))
|
|
return;
|
|
if (!C3.IsDrawableOrImageData(d))
|
|
throw new TypeError("expected drawable or image data");
|
|
}
|
|
;
|
|
C3.IsStringLike = function IsStringLike(x) {
|
|
return typeof x === "string" || x instanceof C3.HtmlString || x instanceof C3.BBString
|
|
}
|
|
;
|
|
C3.RequireStringLike = function RequireStringLike(x) {
|
|
if (!C3.IsStringLike(x))
|
|
throw new TypeError("expected string-like");
|
|
}
|
|
;
|
|
C3.RequireOptionalStringLike = function RequireOptionalStringLike(x) {
|
|
if (C3.IsNullOrUndefined(x))
|
|
return
|
|
}
|
|
;
|
|
C3.RequireAllStringLike = function RequireAllStringLike(...args) {
|
|
for (let a of args)
|
|
;
|
|
}
|
|
;
|
|
C3.RequireOverride = function RequireOverride() {
|
|
throw new Error("must be overridden");
|
|
}
|
|
;
|
|
C3.NotYetImplemented = function NotYetImplemented() {
|
|
throw new Error("not yet implemented");
|
|
}
|
|
;
|
|
C3.IsDefined = function isDefined(obj, ...follow) {
|
|
let currentObject = obj;
|
|
if (typeof currentObject === "undefined")
|
|
return false;
|
|
for (let key of follow) {
|
|
if (typeof currentObject[key] === "undefined")
|
|
return false;
|
|
currentObject = currentObject[key]
|
|
}
|
|
return true
|
|
}
|
|
;
|
|
C3.IsNullOrUndefined = function(x) {
|
|
return typeof x === "undefined" || x === null
|
|
}
|
|
;
|
|
C3.AreArrayElementsOfSameType = function(arr) {
|
|
let type = arr[0].constructor;
|
|
for (let x of arr)
|
|
if (x.constructor !== type)
|
|
return false;
|
|
return type
|
|
}
|
|
;
|
|
C3.AreArrayElementsOfType = function(arr, t) {
|
|
for (let x of arr)
|
|
if (!(x instanceof t))
|
|
return false;
|
|
return true
|
|
}
|
|
;
|
|
const TypedArray = Object.getPrototypeOf(Uint8Array);
|
|
C3.IsTypedArray = function(view) {
|
|
return C3.IsInstanceOf(view, TypedArray)
|
|
}
|
|
;
|
|
C3.RequireTypedArray = function(view) {}
|
|
;
|
|
C3.WeakRequireTypedArray = function WeakRequireTypedArray(inst) {
|
|
C3.WeakRequireInstanceOf(inst, TypedArray)
|
|
}
|
|
;
|
|
C3.WeakRequireAnyInstanceOf = function WeakRequireAnyInstanceOf(inst, ...ctors) {
|
|
if (!C3.WeakIsAnyInstanceOf(inst, ...ctors))
|
|
throw new TypeError("unexpected type");
|
|
}
|
|
;
|
|
C3.WeakIsAnyInstanceOf = function WeakIsAnyInstanceOf(inst, ...ctors) {
|
|
for (const ctor of ctors)
|
|
if (C3.WeakIsInstanceOf(inst, ctor))
|
|
return true;
|
|
return false
|
|
}
|
|
;
|
|
C3.WeakRequireInstanceOf = function WeakRequireInstanceOf(inst, ctor) {
|
|
if (!C3.WeakIsInstanceOf(inst, ctor))
|
|
throw new TypeError("unexpected type");
|
|
}
|
|
;
|
|
C3.WeakIsInstanceOf = function WeakIsInstanceOf(inst, ctor) {
|
|
while (inst = Object.getPrototypeOf(inst))
|
|
if (inst.constructor.name === ctor.name)
|
|
return true;
|
|
return false
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.GetCallStack = function GetCallStack() {
|
|
return (new Error).stack
|
|
}
|
|
;
|
|
C3.Debugger = function Debugger() {
|
|
debugger
|
|
}
|
|
;
|
|
C3.cast = function cast(o, T) {
|
|
if (o && o instanceof T)
|
|
return o;
|
|
else
|
|
return null
|
|
}
|
|
;
|
|
C3.getName = function getName(o) {
|
|
if (typeof o === "undefined")
|
|
return "undefined";
|
|
if (o === null)
|
|
return "null";
|
|
if (typeof o === "boolean")
|
|
return "<boolean>";
|
|
if (C3.IsNumber(o))
|
|
return "<number>";
|
|
if (C3.IsString(o))
|
|
return "<string>";
|
|
if (C3.IsArray(o))
|
|
return "<array>";
|
|
if (typeof o === "symbol")
|
|
return "<" + o.toString() + ">";
|
|
if (C3.IsFunction(o)) {
|
|
if (o.name && o.name !== "Function")
|
|
return o.name;
|
|
return "<anonymous function>"
|
|
}
|
|
if (typeof o === "object") {
|
|
if (o.constructor && o.constructor.name && o.constructor.name !== "Object")
|
|
return o.constructor.name;
|
|
return "<anonymous object>"
|
|
}
|
|
return "<unknown>"
|
|
}
|
|
;
|
|
C3.getType = function getType(o) {
|
|
if (o === null)
|
|
return "null";
|
|
if (Array.isArray(o))
|
|
return "array";
|
|
return typeof o
|
|
}
|
|
;
|
|
C3.range = function *range(a, b) {
|
|
if (!isFinite(Math.abs(a - b)))
|
|
throw new Error("Invalid parameters");
|
|
if (a > b)
|
|
for (let i = a - 1; i >= b; i--)
|
|
yield i;
|
|
else
|
|
for (let i = a; i < b; i++)
|
|
yield i
|
|
}
|
|
;
|
|
function isValidTypeChange(from, to) {
|
|
let fromType = C3.getType(from);
|
|
let toType = C3.getType(to);
|
|
if (fromType === "null" || toType === "null")
|
|
return true;
|
|
if (fromType === "undefined" || toType === "undefined")
|
|
return false;
|
|
return fromType === toType
|
|
}
|
|
let ctorObjectToProxy = new Map;
|
|
let ctorProxyToObject = new Map;
|
|
let proxyToObject = new WeakMap;
|
|
let releasedObjects = new WeakMap;
|
|
C3.DefendHandler = {};
|
|
const VALID_GET_MISSING_KEYS = new Set(["then", "splice"]);
|
|
function logDefendedObjectWarning(msg) {
|
|
console.warn("[Defence] " + msg + " @", C3.GetCallStack())
|
|
}
|
|
C3.DefendHandler.get = function defended_get(target, key) {
|
|
if (!(key in target) && typeof key !== "symbol" && !VALID_GET_MISSING_KEYS.has(key))
|
|
logDefendedObjectWarning(`Accessed missing property '${key}' from defended object '${C3.getName(target)}', returning undefined`);
|
|
if (releasedObjects.has(target) && typeof key !== "symbol" && !VALID_GET_MISSING_KEYS.has(key))
|
|
logDefendedObjectWarning(`Accessed property '${key}' on a released object '${C3.getName(target)}'\nObject was originally released at: ${releasedObjects.get(target)})\nCall stack at access: `);
|
|
return target[key]
|
|
}
|
|
;
|
|
C3.DefendHandler.set = function defended_set(target, key, value) {
|
|
if (!(key in target) && !ctorObjectToProxy.has(target))
|
|
logDefendedObjectWarning(`Set non-existent property '${key}' to '${value}' on defended object '${C3.getName(target)}'`);
|
|
if (!isValidTypeChange(target[key], value) && !ctorObjectToProxy.has(target))
|
|
logDefendedObjectWarning(`Set '${C3.getType(target[key])}' property '${key}' to type '${C3.getType(value)}' on defended object '${C3.getName(target)}'`);
|
|
if (releasedObjects.has(target))
|
|
logDefendedObjectWarning(`Set property '${key}' on a released object '${C3.getName(target)}'\nObject was originally released at: ${releasedObjects.get(target)})\nCall stack at access: `);
|
|
target[key] = value;
|
|
return true
|
|
}
|
|
;
|
|
C3.DefendHandler.deleteProperty = function defended_deleteProperty(target, key) {
|
|
throw new ReferenceError(`Cannot delete property '${key}' from defended object '${C3.getName(target)}'`);
|
|
}
|
|
;
|
|
C3.DefendHandler.defineProperty = function defended_defineProperty(target, key, desc) {
|
|
throw new ReferenceError(`Cannot define property '${key}' on defended object '${C3.getName(target)}'`);
|
|
}
|
|
;
|
|
C3.DefendHandler.enumerate = function defended_enumerate(target) {
|
|
throw new ReferenceError(`Cannot enumerate defended object '${C3.getName(target)}'`);
|
|
}
|
|
;
|
|
let checkRafId = -1;
|
|
function CheckDefendedObjectsUsedCorrectly() {
|
|
checkRafId = -1;
|
|
if (ctorObjectToProxy.size > 0 || ctorProxyToObject.size > 0) {
|
|
let uniqueNames = new Set([...ctorObjectToProxy.keys()].map(o=>C3.getName(o)));
|
|
let leftoverNames = [...uniqueNames].join(",");
|
|
console.warn(`An object derived from DefendedBase was not protected with debugDefend(). This will disable some checks. See the coding guidelines! Possible affected class names: ${leftoverNames}`);
|
|
ctorObjectToProxy.clear();
|
|
ctorProxyToObject.clear()
|
|
}
|
|
}
|
|
C3.DefendedBase = class DefendedBase {
|
|
constructor() {
|
|
if (!C3.isDebugDefend || !C3.Supports.Proxies)
|
|
return;
|
|
let newTarget = new.target;
|
|
let realObject = Object.create(newTarget.prototype);
|
|
let proxy = new Proxy(realObject,C3.DefendHandler);
|
|
ctorObjectToProxy.set(realObject, proxy);
|
|
ctorProxyToObject.set(proxy, realObject);
|
|
proxyToObject.set(proxy, realObject);
|
|
if (checkRafId === -1)
|
|
checkRafId = requestAnimationFrame(CheckDefendedObjectsUsedCorrectly);
|
|
return proxy
|
|
}
|
|
}
|
|
;
|
|
C3.debugDefend = function debugDefend(o) {
|
|
if (C3.isDebugDefend && C3.Supports.Proxies && o instanceof C3.DefendedBase) {
|
|
if (!ctorProxyToObject.has(o))
|
|
return o;
|
|
let realObject = ctorProxyToObject.get(o);
|
|
ctorProxyToObject.delete(o);
|
|
ctorObjectToProxy.delete(realObject);
|
|
return o
|
|
} else if (C3.isDebug)
|
|
return Object.seal(o);
|
|
else
|
|
return o
|
|
}
|
|
;
|
|
C3.New = function New(Type, ...args) {
|
|
let o;
|
|
try {
|
|
o = new Type(...args)
|
|
} catch (e) {
|
|
ctorProxyToObject.clear();
|
|
ctorObjectToProxy.clear();
|
|
throw e;
|
|
}
|
|
if (C3.isDebugDefend)
|
|
VerifyObjectPropertiesConsistent(Type, o);
|
|
return C3.debugDefend(o)
|
|
}
|
|
;
|
|
C3.Release = function Release(o) {
|
|
let realObject = proxyToObject.get(o);
|
|
if (realObject)
|
|
releasedObjects.set(realObject, C3.GetCallStack())
|
|
}
|
|
;
|
|
C3.WasReleased = function(o) {
|
|
let realObject = proxyToObject.get(o);
|
|
if (!realObject)
|
|
return false;
|
|
return !!releasedObjects.get(realObject)
|
|
}
|
|
;
|
|
let typeProperties = new Map;
|
|
function getObjectPropertySet(o) {
|
|
let ret = new Set;
|
|
for (let k in o)
|
|
ret.add(k);
|
|
return ret
|
|
}
|
|
function VerifyObjectPropertiesConsistent(Type, o) {
|
|
let properties = getObjectPropertySet(o);
|
|
let existingProperties = typeProperties.get(Type);
|
|
if (existingProperties) {
|
|
let inconsistentProperties = [];
|
|
for (let k of existingProperties.values())
|
|
if (properties.has(k))
|
|
properties.delete(k);
|
|
else
|
|
inconsistentProperties.push(k);
|
|
C3.appendArray(inconsistentProperties, [...properties]);
|
|
if (inconsistentProperties.length)
|
|
console.warn(`[Defence] '${C3.getName(Type)}' constructor creates inconsistent properties: ${inconsistentProperties.join(", ")}`)
|
|
} else
|
|
typeProperties.set(Type, properties)
|
|
}
|
|
C3.PerfMark = class PerfMark {
|
|
constructor(name) {
|
|
this._name = "";
|
|
if (name)
|
|
this.start(name)
|
|
}
|
|
start(name) {
|
|
this._name = name;
|
|
performance.mark(this._name + "-Start")
|
|
}
|
|
end() {
|
|
performance.mark(this._name + "-End");
|
|
performance.measure(this._name, this._name + "-Start", this._name + "-End")
|
|
}
|
|
next(name) {
|
|
this.end();
|
|
this._name = name;
|
|
performance.mark(this._name + "-Start")
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const TWO_PI = Math.PI * 2;
|
|
const D_TO_R = Math.PI / 180;
|
|
const R_TO_D = 180 / Math.PI;
|
|
C3.wrap = function wrap(x, min, max) {
|
|
x = Math.floor(x);
|
|
min = Math.floor(min);
|
|
max = Math.floor(max);
|
|
if (x < min) {
|
|
let r = max - (min - x) % (max - min);
|
|
return r === max ? 0 : r
|
|
} else
|
|
return min + (x - min) % (max - min)
|
|
}
|
|
;
|
|
C3.mapToRange = function mapToRange(x, inMin, inMax, outMin, outMax) {
|
|
return (x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin
|
|
}
|
|
;
|
|
C3.normalize = function normalize(value, minimum, maximum) {
|
|
return (value - minimum) / (maximum - minimum)
|
|
}
|
|
;
|
|
C3.clamp = function clamp(x, a, b) {
|
|
if (x < a)
|
|
return a;
|
|
else if (x > b)
|
|
return b;
|
|
else
|
|
return x
|
|
}
|
|
;
|
|
C3.clampAngle = function clampAngle(a) {
|
|
a %= TWO_PI;
|
|
if (a < 0)
|
|
a += TWO_PI;
|
|
return a
|
|
}
|
|
;
|
|
C3.toRadians = function toRadians(x) {
|
|
return x * D_TO_R
|
|
}
|
|
;
|
|
C3.toDegrees = function toDegrees(x) {
|
|
return x * R_TO_D
|
|
}
|
|
;
|
|
C3.distanceTo = function distanceTo(x1, y1, x2, y2) {
|
|
return Math.hypot(x2 - x1, y2 - y1)
|
|
}
|
|
;
|
|
C3.distanceSquared = function distanceSquared(x1, y1, x2, y2) {
|
|
const dx = x2 - x1;
|
|
const dy = y2 - y1;
|
|
return dx * dx + dy * dy
|
|
}
|
|
;
|
|
C3.angleTo = function angleTo(x1, y1, x2, y2) {
|
|
return Math.atan2(y2 - y1, x2 - x1)
|
|
}
|
|
;
|
|
C3.angleDiff = function angleDiff(a1, a2) {
|
|
if (a1 === a2)
|
|
return 0;
|
|
let s1 = Math.sin(a1);
|
|
let c1 = Math.cos(a1);
|
|
let s2 = Math.sin(a2);
|
|
let c2 = Math.cos(a2);
|
|
let n = s1 * s2 + c1 * c2;
|
|
if (n >= 1)
|
|
return 0;
|
|
if (n <= -1)
|
|
return Math.PI;
|
|
return Math.acos(n)
|
|
}
|
|
;
|
|
C3.angleRotate = function angleRotate(start, end, step) {
|
|
let ss = Math.sin(start);
|
|
let cs = Math.cos(start);
|
|
let se = Math.sin(end);
|
|
let ce = Math.cos(end);
|
|
if (Math.acos(ss * se + cs * ce) > step)
|
|
if (cs * se - ss * ce > 0)
|
|
return C3.clampAngle(start + step);
|
|
else
|
|
return C3.clampAngle(start - step);
|
|
else
|
|
return C3.clampAngle(end)
|
|
}
|
|
;
|
|
C3.angleClockwise = function angleClockwise(a1, a2) {
|
|
let s1 = Math.sin(a1);
|
|
let c1 = Math.cos(a1);
|
|
let s2 = Math.sin(a2);
|
|
let c2 = Math.cos(a2);
|
|
return c1 * s2 - s1 * c2 <= 0
|
|
}
|
|
;
|
|
C3.angleLerp = function angleLerp(a, b, x, r=0) {
|
|
let diff = C3.angleDiff(a, b);
|
|
const revs = TWO_PI * r;
|
|
if (C3.angleClockwise(b, a))
|
|
return C3.clampAngle(a + (diff + revs) * x);
|
|
else
|
|
return C3.clampAngle(a - (diff + revs) * x)
|
|
}
|
|
;
|
|
C3.angleLerpClockwise = function angleLerpClockwise(a, b, x, r=0) {
|
|
const diff = C3.angleDiff(a, b);
|
|
const revs = TWO_PI * r;
|
|
if (C3.angleClockwise(b, a))
|
|
return C3.clampAngle(a + (diff + revs) * x);
|
|
return C3.clampAngle((TWO_PI - diff + revs) * x)
|
|
}
|
|
;
|
|
C3.angleLerpAntiClockwise = function angleLerpAntiClockwise(a, b, x, r=0) {
|
|
const diff = C3.angleDiff(a, b);
|
|
const revs = TWO_PI * r;
|
|
if (C3.angleClockwise(b, a))
|
|
return C3.clampAngle((-TWO_PI + diff - revs) * x);
|
|
return C3.clampAngle(a - (diff + revs) * x)
|
|
}
|
|
;
|
|
C3.lerp = function lerp(a, b, x) {
|
|
return a + x * (b - a)
|
|
}
|
|
;
|
|
C3.unlerp = function unlerp(a, b, x) {
|
|
if (a === b)
|
|
return 0;
|
|
return (x - a) / (b - a)
|
|
}
|
|
;
|
|
C3.relerp = function relerp(a, b, x, c, d) {
|
|
return C3.lerp(c, d, C3.unlerp(a, b, x))
|
|
}
|
|
;
|
|
C3.qarp = function qarp(a, b, c, x) {
|
|
return C3.lerp(C3.lerp(a, b, x), C3.lerp(b, c, x), x)
|
|
}
|
|
;
|
|
C3.cubic = function cubic(a, b, c, d, x) {
|
|
return C3.lerp(C3.qarp(a, b, c, x), C3.qarp(b, c, d, x), x)
|
|
}
|
|
;
|
|
C3.cosp = function cosp(a, b, x) {
|
|
return (a + b + (a - b) * Math.cos(x * Math.PI)) / 2
|
|
}
|
|
;
|
|
C3.isPOT = function isPOT(x) {
|
|
return x > 0 && (x - 1 & x) === 0
|
|
}
|
|
;
|
|
C3.nextHighestPowerOfTwo = function nextHighestPowerOfTwo(x) {
|
|
--x;
|
|
for (let i = 1; i < 32; i <<= 1)
|
|
x = x | x >> i;
|
|
return x + 1
|
|
}
|
|
;
|
|
C3.roundToNearestFraction = function roundToNearestFraction(x, n) {
|
|
return Math.round(x * n) / n
|
|
}
|
|
;
|
|
C3.floorToNearestFraction = function floorToNearestFraction(x, n) {
|
|
return Math.floor(x * n) / n
|
|
}
|
|
;
|
|
C3.round6dp = function round6dp(x) {
|
|
return Math.round(x * 1E6) / 1E6
|
|
}
|
|
;
|
|
C3.toFixed = function toFixed(n, dp) {
|
|
let ret = n.toFixed(dp);
|
|
let last = ret.length - 1;
|
|
for (; last >= 0 && ret.charAt(last) === "0"; --last)
|
|
;
|
|
if (last >= 0 && ret.charAt(last) === ".")
|
|
--last;
|
|
if (last < 0)
|
|
return ret;
|
|
return ret.substr(0, last + 1)
|
|
}
|
|
;
|
|
C3.PackRGB = function PackRGB(red, green, blue) {
|
|
return C3.clamp(red, 0, 255) | C3.clamp(green, 0, 255) << 8 | C3.clamp(blue, 0, 255) << 16
|
|
}
|
|
;
|
|
const ALPHAEX_SHIFT = 1024;
|
|
const ALPHAEX_MAX = 1023;
|
|
const RGBEX_SHIFT = 16384;
|
|
const RGBEX_MAX = 8191;
|
|
const RGBEX_MIN = -8192;
|
|
C3.PackRGBAEx = function PackRGBAEx(red, green, blue, alpha) {
|
|
red = C3.clamp(Math.floor(red * 1024), RGBEX_MIN, RGBEX_MAX);
|
|
green = C3.clamp(Math.floor(green * 1024), RGBEX_MIN, RGBEX_MAX);
|
|
blue = C3.clamp(Math.floor(blue * 1024), RGBEX_MIN, RGBEX_MAX);
|
|
alpha = C3.clamp(Math.floor(alpha * ALPHAEX_MAX), 0, ALPHAEX_MAX);
|
|
if (red < 0)
|
|
red += RGBEX_SHIFT;
|
|
if (green < 0)
|
|
green += RGBEX_SHIFT;
|
|
if (blue < 0)
|
|
blue += RGBEX_SHIFT;
|
|
return -(red * RGBEX_SHIFT * RGBEX_SHIFT * ALPHAEX_SHIFT + green * RGBEX_SHIFT * ALPHAEX_SHIFT + blue * ALPHAEX_SHIFT + alpha)
|
|
}
|
|
;
|
|
C3.PackRGBEx = function PackRGBEx(red, green, blue) {
|
|
return C3.PackRGBAEx(red, green, blue, 1)
|
|
}
|
|
;
|
|
function isNegativeZero(x) {
|
|
return x === 0 && 1 / x < 0
|
|
}
|
|
C3.GetRValue = function GetRValue(rgb) {
|
|
if (rgb >= 0)
|
|
return (rgb & 255) / 255;
|
|
else {
|
|
let v = Math.floor(-rgb / (RGBEX_SHIFT * RGBEX_SHIFT * ALPHAEX_SHIFT));
|
|
if (v > RGBEX_MAX)
|
|
v -= RGBEX_SHIFT;
|
|
return v / 1024
|
|
}
|
|
}
|
|
;
|
|
C3.GetGValue = function GetGValue(rgb) {
|
|
if (rgb >= 0)
|
|
return ((rgb & 65280) >> 8) / 255;
|
|
else {
|
|
let v = Math.floor(-rgb % (RGBEX_SHIFT * RGBEX_SHIFT * ALPHAEX_SHIFT) / (RGBEX_SHIFT * ALPHAEX_SHIFT));
|
|
if (v > RGBEX_MAX)
|
|
v -= RGBEX_SHIFT;
|
|
return v / 1024
|
|
}
|
|
}
|
|
;
|
|
C3.GetBValue = function GetBValue(rgb) {
|
|
if (rgb >= 0)
|
|
return ((rgb & 16711680) >> 16) / 255;
|
|
else {
|
|
let v = Math.floor(-rgb % (RGBEX_SHIFT * ALPHAEX_SHIFT) / ALPHAEX_SHIFT);
|
|
if (v > RGBEX_MAX)
|
|
v -= RGBEX_SHIFT;
|
|
return v / 1024
|
|
}
|
|
}
|
|
;
|
|
C3.GetAValue = function GetAValue(rgb) {
|
|
if (isNegativeZero(rgb))
|
|
return 0;
|
|
else if (rgb >= 0)
|
|
return 1;
|
|
else {
|
|
const v = Math.floor(-rgb % ALPHAEX_SHIFT);
|
|
return v / ALPHAEX_MAX
|
|
}
|
|
}
|
|
;
|
|
C3.greatestCommonDivisor = function greatestCommonDivisor(a, b) {
|
|
a = Math.floor(a);
|
|
b = Math.floor(b);
|
|
while (b !== 0) {
|
|
let t = b;
|
|
b = a % b;
|
|
a = t
|
|
}
|
|
return a
|
|
}
|
|
;
|
|
const COMMON_ASPECT_RATIOS = [[3, 2], [4, 3], [5, 4], [5, 3], [6, 5], [14, 9], [16, 9], [16, 10], [21, 9]];
|
|
C3.getAspectRatio = function getAspectRatio(w, h) {
|
|
w = Math.floor(w);
|
|
h = Math.floor(h);
|
|
if (w === h)
|
|
return [1, 1];
|
|
for (let aspect of COMMON_ASPECT_RATIOS) {
|
|
let approxH = w / aspect[0] * aspect[1];
|
|
if (Math.abs(h - approxH) < 1)
|
|
return aspect.slice(0);
|
|
approxH = w / aspect[1] * aspect[0];
|
|
if (Math.abs(h - approxH) < 1)
|
|
return [aspect[1], aspect[0]]
|
|
}
|
|
let gcd = C3.greatestCommonDivisor(w, h);
|
|
return [w / gcd, h / gcd]
|
|
}
|
|
;
|
|
C3.segmentsIntersect = function segmentsIntersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) {
|
|
const min_ax = Math.min(a1x, a2x);
|
|
const max_ax = Math.max(a1x, a2x);
|
|
const min_bx = Math.min(b1x, b2x);
|
|
const max_bx = Math.max(b1x, b2x);
|
|
if (max_ax < min_bx || min_ax > max_bx)
|
|
return false;
|
|
const min_ay = Math.min(a1y, a2y);
|
|
const max_ay = Math.max(a1y, a2y);
|
|
const min_by = Math.min(b1y, b2y);
|
|
const max_by = Math.max(b1y, b2y);
|
|
if (max_ay < min_by || min_ay > max_by)
|
|
return false;
|
|
const dpx = b1x - a1x + b2x - a2x;
|
|
const dpy = b1y - a1y + b2y - a2y;
|
|
const qax = a2x - a1x;
|
|
const qay = a2y - a1y;
|
|
const qbx = b2x - b1x;
|
|
const qby = b2y - b1y;
|
|
const d = Math.abs(qay * qbx - qby * qax);
|
|
const la = qbx * dpy - qby * dpx;
|
|
if (Math.abs(la) > d)
|
|
return false;
|
|
const lb = qax * dpy - qay * dpx;
|
|
return Math.abs(lb) <= d
|
|
}
|
|
;
|
|
C3.segmentsIntersectPreCalc = function segmentsIntersectPreCalc(a1x, a1y, a2x, a2y, min_ax, max_ax, min_ay, max_ay, b1x, b1y, b2x, b2y) {
|
|
const min_bx = Math.min(b1x, b2x);
|
|
const max_bx = Math.max(b1x, b2x);
|
|
if (max_ax < min_bx || min_ax > max_bx)
|
|
return false;
|
|
const min_by = Math.min(b1y, b2y);
|
|
const max_by = Math.max(b1y, b2y);
|
|
if (max_ay < min_by || min_ay > max_by)
|
|
return false;
|
|
const dpx = b1x - a1x + b2x - a2x;
|
|
const dpy = b1y - a1y + b2y - a2y;
|
|
const qax = a2x - a1x;
|
|
const qay = a2y - a1y;
|
|
const qbx = b2x - b1x;
|
|
const qby = b2y - b1y;
|
|
const d = Math.abs(qay * qbx - qby * qax);
|
|
const la = qbx * dpy - qby * dpx;
|
|
if (Math.abs(la) > d)
|
|
return false;
|
|
const lb = qax * dpy - qay * dpx;
|
|
return Math.abs(lb) <= d
|
|
}
|
|
;
|
|
C3.segmentIntersectsQuad = function segmentIntersectsQuad(x1, y1, x2, y2, q) {
|
|
const min_x = Math.min(x1, x2);
|
|
const max_x = Math.max(x1, x2);
|
|
const min_y = Math.min(y1, y2);
|
|
const max_y = Math.max(y1, y2);
|
|
const tlx = q.getTlx()
|
|
, tly = q.getTly()
|
|
, trx = q.getTrx()
|
|
, try_ = q.getTry()
|
|
, brx = q.getBrx()
|
|
, bry = q.getBry()
|
|
, blx = q.getBlx()
|
|
, bly = q.getBly();
|
|
return C3.segmentsIntersectPreCalc(x1, y1, x2, y2, min_x, max_x, min_y, max_y, tlx, tly, trx, try_) || C3.segmentsIntersectPreCalc(x1, y1, x2, y2, min_x, max_x, min_y, max_y, trx, try_, brx, bry) || C3.segmentsIntersectPreCalc(x1, y1, x2, y2, min_x, max_x, min_y, max_y, brx, bry, blx, bly) || C3.segmentsIntersectPreCalc(x1, y1, x2, y2, min_x, max_x, min_y, max_y, blx, bly, tlx, tly)
|
|
}
|
|
;
|
|
C3.segmentIntersectsAnyN = function segmentIntersectsAnyN(x1, y1, x2, y2, points) {
|
|
const min_x = Math.min(x1, x2);
|
|
const max_x = Math.max(x1, x2);
|
|
const min_y = Math.min(y1, y2);
|
|
const max_y = Math.max(y1, y2);
|
|
let i = 0;
|
|
for (let last = points.length - 4; i <= last; i += 2)
|
|
if (C3.segmentsIntersectPreCalc(x1, y1, x2, y2, min_x, max_x, min_y, max_y, points[i], points[i + 1], points[i + 2], points[i + 3]))
|
|
return true;
|
|
return C3.segmentsIntersectPreCalc(x1, y1, x2, y2, min_x, max_x, min_y, max_y, points[i], points[i + 1], points[0], points[1])
|
|
}
|
|
;
|
|
const NO_HIT = 2;
|
|
const PADDING = 1E-6;
|
|
C3.rayIntersect = function rayIntersect(rx1, ry1, rx2, ry2, sx1, sy1, sx2, sy2) {
|
|
const rdx = rx2 - rx1;
|
|
const rdy = ry2 - ry1;
|
|
const sdx = sx2 - sx1;
|
|
const sdy = sy2 - sy1;
|
|
const det = rdx * sdy - rdy * sdx;
|
|
if (det === 0)
|
|
return NO_HIT;
|
|
const gamma = ((ry1 - ry2) * (sx2 - rx1) + rdx * (sy2 - ry1)) / det;
|
|
if (0 < gamma && gamma < 1 + PADDING)
|
|
return (sdy * (sx2 - rx1) + (sx1 - sx2) * (sy2 - ry1)) / det;
|
|
return NO_HIT
|
|
}
|
|
;
|
|
C3.rayIntersectExtended = function rayIntersect(rx1, ry1, rx2, ry2, sx1, sy1, sx2, sy2, f) {
|
|
const dx = (sx2 - sx1) * f;
|
|
const dy = (sy2 - sy1) * f;
|
|
return C3.rayIntersect(rx1, ry1, rx2, ry2, sx1 - dx, sy1 - dy, sx2 + dx, sy2 + dy)
|
|
}
|
|
;
|
|
C3.isPointInTriangleInclusive = function isPointInTriangleInclusive(px, py, tx1, ty1, tx2, ty2, tx3, ty3) {
|
|
const v0x = tx2 - tx1;
|
|
const v0y = ty2 - ty1;
|
|
const v1x = tx3 - tx1;
|
|
const v1y = ty3 - ty1;
|
|
const v2x = px - tx1;
|
|
const v2y = py - ty1;
|
|
const dot00 = v0x * v0x + v0y * v0y;
|
|
const dot01 = v0x * v1x + v0y * v1y;
|
|
const dot02 = v0x * v2x + v0y * v2y;
|
|
const dot11 = v1x * v1x + v1y * v1y;
|
|
const dot12 = v1x * v2x + v1y * v2y;
|
|
const invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
|
|
const u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
|
const v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
return u >= 0 && v >= 0 && u + v <= 1
|
|
}
|
|
;
|
|
C3.triangleCartesianToBarycentric = function triangleCartesianToBarycentric(px, py, tx1, ty1, tx2, ty2, tx3, ty3) {
|
|
const v0x = tx2 - tx1;
|
|
const v0y = ty2 - ty1;
|
|
const v1x = tx3 - tx1;
|
|
const v1y = ty3 - ty1;
|
|
const v2x = px - tx1;
|
|
const v2y = py - ty1;
|
|
const dot00 = v0x * v0x + v0y * v0y;
|
|
const dot01 = v0x * v1x + v0y * v1y;
|
|
const dot11 = v1x * v1x + v1y * v1y;
|
|
const dot20 = v2x * v0x + v2y * v0y;
|
|
const dot21 = v2x * v1x + v2y * v1y;
|
|
const denom = dot00 * dot11 - dot01 * dot01;
|
|
const v = (dot11 * dot20 - dot01 * dot21) / denom;
|
|
const w = (dot00 * dot21 - dot01 * dot20) / denom;
|
|
const u = 1 - v - w;
|
|
return [u, v, w]
|
|
}
|
|
;
|
|
C3.triangleBarycentricToCartesian = function triangleBarycentricToCartesian(u, v, w, tx1, ty1, tx2, ty2, tx3, ty3) {
|
|
return [u * tx1 + v * tx2 + w * tx3, u * ty1 + v * ty2 + w * ty3]
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
let mainDocument = null;
|
|
let baseHref = "";
|
|
if (typeof document !== "undefined") {
|
|
mainDocument = document;
|
|
const baseElem = document.querySelector("base");
|
|
baseHref = baseElem && baseElem.hasAttribute("href") ? baseElem.getAttribute("href") : "";
|
|
if (baseHref) {
|
|
if (baseHref.startsWith("/"))
|
|
baseHref = baseHref.substr(1);
|
|
if (!baseHref.endsWith("/"))
|
|
baseHref += "/"
|
|
}
|
|
}
|
|
C3.GetBaseHref = function GetBaseHref() {
|
|
return baseHref
|
|
}
|
|
;
|
|
C3.GetBaseURL = function GetBaseURL() {
|
|
if (!mainDocument)
|
|
return "";
|
|
const loc = mainDocument.location;
|
|
return C3.GetPathFromURL(loc.origin + loc.pathname) + baseHref
|
|
}
|
|
;
|
|
C3.GetPathFromURL = function GetPathFromURL(url) {
|
|
if (!url.length)
|
|
return url;
|
|
if (url.endsWith("/") || url.endsWith("\\"))
|
|
return url;
|
|
const lastSlash = Math.max(url.lastIndexOf("/"), url.lastIndexOf("\\"));
|
|
if (lastSlash === -1)
|
|
return "";
|
|
return url.substr(0, lastSlash + 1)
|
|
}
|
|
;
|
|
C3.GetFilenameFromURL = function GetFilenameFromURL(url) {
|
|
if (!url.length)
|
|
return url;
|
|
if (url.endsWith("/") || url.endsWith("\\"))
|
|
return "";
|
|
const lastSlash = Math.max(url.lastIndexOf("/"), url.lastIndexOf("\\"));
|
|
if (lastSlash === -1)
|
|
return url;
|
|
return url.substr(lastSlash + 1)
|
|
}
|
|
;
|
|
C3.DataTransferHasFiles = function DataTransferHasFiles(dataTransfer) {
|
|
if (dataTransfer.types)
|
|
for (let i = 0; i < dataTransfer.types.length; i++)
|
|
if (dataTransfer.types[i] === "Files" || dataTransfer.types[i] === "application/x-c3-file")
|
|
return true;
|
|
return false
|
|
}
|
|
;
|
|
C3.DataTransferFilterFiles = async function DataTransferHasFiles(dataTransfer, filter) {
|
|
const ret = Array.from(dataTransfer.files).filter(file=>{
|
|
return file.size !== 0
|
|
}
|
|
).filter(file=>{
|
|
return filter(file)
|
|
}
|
|
).map(async file=>{
|
|
try {
|
|
return await C3.CloneFile(file)
|
|
} catch (err) {
|
|
return null
|
|
}
|
|
}
|
|
);
|
|
const files = await Promise.all(ret);
|
|
return files.filter(file=>file)
|
|
}
|
|
;
|
|
C3.IsFileAnImage = function IsFileAnImage(file) {
|
|
if (file.type)
|
|
return file.type.search(/image\/.*/) !== -1;
|
|
else {
|
|
const type = C3.MimeType.GetForFileExtension(C3.GetFileExtension(file.name)).GetString();
|
|
return type.search(/image\/.*/) !== -1
|
|
}
|
|
}
|
|
;
|
|
C3.IsFileAnSVG = function IsFileAnSVG(file) {
|
|
return file.type === "image/svg+xml"
|
|
}
|
|
;
|
|
C3.IsFileAMultiImageContainer = function IsFileAMultiImageContainer(file) {
|
|
if (file.type)
|
|
return C3.MimeType.Get(file.type).IsAnimatedImage();
|
|
else
|
|
return C3.MimeType.GetForFileExtension(C3.GetFileExtension(file.name)).IsAnimatedImage()
|
|
}
|
|
;
|
|
C3.GetFileExtension = function GetFileExtension(filename) {
|
|
let i = filename.lastIndexOf(".");
|
|
if (i < 1)
|
|
return "";
|
|
else
|
|
return filename.substr(i)
|
|
}
|
|
;
|
|
C3.GetFileNamePart = function GetFileNamePart(filename) {
|
|
let i = filename.lastIndexOf(".");
|
|
if (i < 1)
|
|
return filename;
|
|
else
|
|
return filename.substr(0, i)
|
|
}
|
|
;
|
|
C3.NormalizeFileSeparator = function NormalizeFileSeparator(path) {
|
|
return path.replace(/\\/g, "/")
|
|
}
|
|
;
|
|
C3.ParseFilePath = function ParseFilePath(path) {
|
|
path = C3.NormalizeFileSeparator(path);
|
|
let root = /^\w:\//.exec(path);
|
|
if (root) {
|
|
root = root[0];
|
|
path = path.slice(3);
|
|
if (path[0] !== "/")
|
|
path = "/" + path
|
|
} else
|
|
root = "";
|
|
path = path.replace(/\/{2,}/g, "/");
|
|
if (path.length > 1 && path.slice(-1) === "/")
|
|
path = path.slice(0, -1);
|
|
const start = path.lastIndexOf("/") + 1;
|
|
let dir = "", base = path, name, ext = "";
|
|
if (start > 0) {
|
|
dir = path.slice(0, start);
|
|
base = path.slice(start)
|
|
}
|
|
name = base;
|
|
const end = base.lastIndexOf(".");
|
|
if (end > 0) {
|
|
ext = base.slice(end);
|
|
name = base.slice(0, -ext.length)
|
|
}
|
|
const full = root + dir + base;
|
|
return {
|
|
dir,
|
|
base,
|
|
name,
|
|
root,
|
|
ext,
|
|
full
|
|
}
|
|
}
|
|
;
|
|
C3.Wait = function Wait(delay, argument) {
|
|
return new Promise((resolve,reject)=>{
|
|
self.setTimeout(resolve, delay, argument)
|
|
}
|
|
)
|
|
}
|
|
;
|
|
C3.swallowException = function swallowException(f) {
|
|
try {
|
|
f()
|
|
} catch (e) {
|
|
if (C3.isDebug)
|
|
console.warn("Swallowed exception: ", e)
|
|
}
|
|
}
|
|
;
|
|
C3.noop = function noop() {}
|
|
;
|
|
C3.equalsNoCase = function equalsNoCase(a, b) {
|
|
if (typeof a !== "string" || typeof b !== "string")
|
|
return false;
|
|
if (a === b)
|
|
return true;
|
|
a = a.normalize();
|
|
b = b.normalize();
|
|
if (a.length !== b.length)
|
|
return false;
|
|
return a.toLowerCase() === b.toLowerCase()
|
|
}
|
|
;
|
|
C3.equalsCase = function equalsCase(a, b) {
|
|
if (typeof a !== "string" || typeof b !== "string")
|
|
return false;
|
|
if (a === b)
|
|
return true;
|
|
return a.normalize() === b.normalize()
|
|
}
|
|
;
|
|
C3.typedArraySet16 = function typedArraySet16(dest, src, i) {
|
|
dest[i++] = src[0];
|
|
dest[i++] = src[1];
|
|
dest[i++] = src[2];
|
|
dest[i++] = src[3];
|
|
dest[i++] = src[4];
|
|
dest[i++] = src[5];
|
|
dest[i++] = src[6];
|
|
dest[i++] = src[7];
|
|
dest[i++] = src[8];
|
|
dest[i++] = src[9];
|
|
dest[i++] = src[10];
|
|
dest[i++] = src[11];
|
|
dest[i++] = src[12];
|
|
dest[i++] = src[13];
|
|
dest[i++] = src[14];
|
|
dest[i] = src[15]
|
|
}
|
|
;
|
|
C3.truncateArray = function truncateArray(arr, index) {
|
|
arr.length = index
|
|
}
|
|
;
|
|
C3.clearArray = function clearArray(arr) {
|
|
if (!arr)
|
|
return;
|
|
if (arr.length === 0)
|
|
return;
|
|
C3.truncateArray(arr, 0)
|
|
}
|
|
;
|
|
C3.clear2DArray = function clear2DArray(arr) {
|
|
if (!arr)
|
|
return;
|
|
for (let i = 0; i < arr.length; i++) {
|
|
let a = arr[i];
|
|
C3.truncateArray(a, 0)
|
|
}
|
|
C3.truncateArray(arr, 0)
|
|
}
|
|
;
|
|
C3.extendArray = function extendArray(arr, len, filler) {
|
|
len = len | 0;
|
|
const arrayLength = arr.length;
|
|
if (len <= arrayLength)
|
|
return;
|
|
for (let i = arrayLength; i < len; ++i)
|
|
arr.push(filler)
|
|
}
|
|
;
|
|
C3.resizeArray = function resizeArray(arr, len, filler) {
|
|
len = len | 0;
|
|
const arrayLength = arr.length;
|
|
if (len < arrayLength)
|
|
C3.truncateArray(arr, len);
|
|
else if (len > arrayLength)
|
|
C3.extendArray(arr, len, filler)
|
|
}
|
|
;
|
|
C3.shallowAssignArray = function shallowAssignArray(dest, src) {
|
|
C3.clearArray(dest);
|
|
C3.appendArray(dest, src)
|
|
}
|
|
;
|
|
C3.appendArray = function appendArray(a, b) {
|
|
if (b.length < 1E4)
|
|
a.push(...b);
|
|
else
|
|
for (let i = 0, len = b.length; i < len; ++i)
|
|
a.push(b[i])
|
|
}
|
|
;
|
|
C3.arrayRemove = function(arr, index) {
|
|
index = Math.floor(index);
|
|
if (index < 0 || index >= arr.length)
|
|
return;
|
|
let len = arr.length - 1;
|
|
for (let i = index; i < len; ++i)
|
|
arr[i] = arr[i + 1];
|
|
C3.truncateArray(arr, len)
|
|
}
|
|
;
|
|
C3.arrayFindRemove = function arrayFindRemove(a, o) {
|
|
let i = a.indexOf(o);
|
|
if (i >= 0)
|
|
a.splice(i, 1)
|
|
}
|
|
;
|
|
C3.arraysEqual = function arraysEqual(a, b) {
|
|
let len = a.length;
|
|
if (b.length !== len)
|
|
return false;
|
|
for (let i = 0; i < len; ++i)
|
|
if (a[i] !== b[i])
|
|
return false;
|
|
return true
|
|
}
|
|
;
|
|
C3.arrayFilterOut = function arrayFilterOut(arr, callback) {
|
|
let ret = [];
|
|
let j = 0;
|
|
for (let i = 0, len = arr.length; i < len; ++i) {
|
|
let item = arr[i];
|
|
if (callback(item))
|
|
ret.push(item);
|
|
else {
|
|
arr[j] = item;
|
|
++j
|
|
}
|
|
}
|
|
C3.truncateArray(arr, j);
|
|
return ret
|
|
}
|
|
;
|
|
C3.arrayRemoveAllInSet = function arrayRemoveAllInSet(arr, s) {
|
|
const oldLen = arr.length;
|
|
let j = 0;
|
|
for (let i = 0, len = arr.length; i < len; ++i) {
|
|
let item = arr[i];
|
|
if (!s.has(item))
|
|
arr[j++] = item
|
|
}
|
|
C3.truncateArray(arr, j);
|
|
return oldLen - j
|
|
}
|
|
;
|
|
C3.isArrayIndexInBounds = function isArrayIndexInBounds(index, array) {
|
|
if (index !== Math.floor(index))
|
|
return false;
|
|
return index >= 0 && index < array.length
|
|
}
|
|
;
|
|
C3.validateArrayIndex = function validateArrayIndex(index, array) {
|
|
if (!C3.isArrayIndexInBounds(index, array))
|
|
throw new RangeError("array index out of bounds");
|
|
}
|
|
;
|
|
C3.cloneArray = function cloneArray(array) {
|
|
return array.slice()
|
|
}
|
|
;
|
|
C3.deepCloneArray = function deepCloneArray(array, f) {
|
|
let ret = [];
|
|
for (let e of array)
|
|
if (C3.IsObject(e)) {
|
|
let clone = f(e);
|
|
if (!clone)
|
|
throw new Error("missing clone");
|
|
if (clone.constructor !== e.constructor)
|
|
throw new Error("object is not a clone");
|
|
ret.push(clone)
|
|
} else if (C3.IsArray(e))
|
|
ret.push(C3.deepCloneArray(e, f));
|
|
else
|
|
ret.push(e);
|
|
return ret
|
|
}
|
|
;
|
|
C3.clone2DArray = function cloneArray(array) {
|
|
let ret = [];
|
|
for (let arr of array)
|
|
ret.push(arr.slice());
|
|
return ret
|
|
}
|
|
;
|
|
C3.mergeSets = function mergeSets(set1, set2) {
|
|
return new Set([...set1, ...set2])
|
|
}
|
|
;
|
|
C3.mergeSetsInPlace = function mergeSetsInPlace(set1, set2) {
|
|
for (const item of set2)
|
|
set1.add(item);
|
|
return set1
|
|
}
|
|
;
|
|
C3.first = function first(iterable) {
|
|
for (let i of iterable)
|
|
return i;
|
|
return null
|
|
}
|
|
;
|
|
C3.xor = function(x, y) {
|
|
return !x !== !y
|
|
}
|
|
;
|
|
C3.compare = function compare(x, cmp, y) {
|
|
switch (cmp) {
|
|
case 0:
|
|
return x === y;
|
|
case 1:
|
|
return x !== y;
|
|
case 2:
|
|
return x < y;
|
|
case 3:
|
|
return x <= y;
|
|
case 4:
|
|
return x > y;
|
|
case 5:
|
|
return x >= y;
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
;
|
|
C3.hasAnyOwnProperty = function hasAnyOwnProperty(o) {
|
|
for (let p in o)
|
|
if (o.hasOwnProperty(p))
|
|
return true;
|
|
return false
|
|
}
|
|
;
|
|
C3.PromiseAllWithProgress = function PromiseAllWithProgress(arr, progressCallback) {
|
|
if (!arr.length)
|
|
return Promise.resolve([]);
|
|
return new Promise((resolve,reject)=>{
|
|
const results = [];
|
|
let numberCompleted = 0;
|
|
let cancelled = false;
|
|
for (let i = 0, len = arr.length; i < len; ++i) {
|
|
results.push(void 0);
|
|
arr[i].then(result=>{
|
|
if (cancelled)
|
|
return;
|
|
results[i] = result;
|
|
++numberCompleted;
|
|
if (numberCompleted === arr.length)
|
|
resolve(results);
|
|
else
|
|
progressCallback(numberCompleted, arr.length)
|
|
}
|
|
).catch(err=>{
|
|
cancelled = true;
|
|
reject(err)
|
|
}
|
|
)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
;
|
|
let memoryCallbacks = [];
|
|
C3.AddLibraryMemoryCallback = function AddLibraryMemoryCallback(f) {
|
|
memoryCallbacks.push(f)
|
|
}
|
|
;
|
|
C3.GetEstimatedLibraryMemoryUsage = function GetEstimatedLibraryMemoryUsage() {
|
|
let ret = 0;
|
|
for (let f of memoryCallbacks) {
|
|
let m = f();
|
|
ret += m
|
|
}
|
|
return Math.floor(ret)
|
|
}
|
|
;
|
|
let nextTaskId = 1;
|
|
const activeTaskIds = new Map;
|
|
const taskMessageChannel = new MessageChannel;
|
|
taskMessageChannel.port2.onmessage = function OnTask(e) {
|
|
const id = e.data;
|
|
const callback = activeTaskIds.get(id);
|
|
activeTaskIds.delete(id);
|
|
if (callback)
|
|
callback(e.timeStamp)
|
|
}
|
|
;
|
|
C3.RequestUnlimitedAnimationFrame = function RequestUnlimitedAnimationFrame(callback) {
|
|
const id = nextTaskId++;
|
|
activeTaskIds.set(id, callback);
|
|
taskMessageChannel.port1.postMessage(id);
|
|
return id
|
|
}
|
|
;
|
|
C3.CancelUnlimitedAnimationFrame = function CancelUnlimitedAnimationFrame(id) {
|
|
activeTaskIds.delete(id)
|
|
}
|
|
;
|
|
C3.PostTask = C3.RequestUnlimitedAnimationFrame;
|
|
C3.WaitForNextTask = function WaitForNextTask() {
|
|
return new Promise(resolve=>C3.PostTask(resolve))
|
|
}
|
|
;
|
|
const activeRPAFids = new Set;
|
|
C3.RequestPostAnimationFrame = function RequestPostAnimationFrame(callback) {
|
|
const id = self.requestAnimationFrame(async timestamp=>{
|
|
await C3.WaitForNextTask();
|
|
if (!activeRPAFids.has(id))
|
|
return;
|
|
activeRPAFids.delete(id);
|
|
callback(timestamp)
|
|
}
|
|
);
|
|
activeRPAFids.add(id);
|
|
return id
|
|
}
|
|
;
|
|
C3.CancelPostAnimationFrame = function CancelPostAnimationFrame(id) {
|
|
if (!activeRPAFids.has(id))
|
|
return;
|
|
self.cancelAnimationFrame(id);
|
|
activeRPAFids.delete(id)
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.IsAbsoluteURL = function IsAbsoluteURL(url) {
|
|
return /^(?:[a-z]+:)?\/\//.test(url) || url.substr(0, 5) === "data:" || url.substr(0, 5) === "blob:"
|
|
}
|
|
;
|
|
C3.IsRelativeURL = function IsRelativeURL(url) {
|
|
return !C3.IsAbsoluteURL(url)
|
|
}
|
|
;
|
|
C3.ThrowIfNotOk = function ThrowIfNotOk(response) {
|
|
if (!response.ok)
|
|
throw new Error(`fetch '${response.url}' response returned ${response.status} ${response.statusText}`);
|
|
}
|
|
;
|
|
C3.FetchOk = function FetchOk(url, init) {
|
|
return fetch(url, init).then(response=>{
|
|
C3.ThrowIfNotOk(response);
|
|
return response
|
|
}
|
|
)
|
|
}
|
|
;
|
|
C3.FetchText = function FetchText(url) {
|
|
return C3.FetchOk(url).then(response=>response.text())
|
|
}
|
|
;
|
|
C3.FetchJson = function FetchJson(url) {
|
|
return C3.FetchOk(url).then(response=>response.json())
|
|
}
|
|
;
|
|
C3.FetchBlob = function FetchBlob(url) {
|
|
return C3.FetchOk(url).then(response=>response.blob())
|
|
}
|
|
;
|
|
C3.FetchArrayBuffer = function FetchArrayBuffer(url) {
|
|
return C3.FetchOk(url).then(response=>response.arrayBuffer())
|
|
}
|
|
;
|
|
C3.FetchImage = function FetchImage(url) {
|
|
return new Promise((resolve,reject)=>{
|
|
const img = new Image;
|
|
img.onload = ()=>resolve(img);
|
|
img.onerror = err=>reject(err);
|
|
img.src = url
|
|
}
|
|
)
|
|
}
|
|
;
|
|
C3.BlobToArrayBuffer = function BlobToArrayBuffer(blob) {
|
|
if (typeof blob["arrayBuffer"] === "function")
|
|
return blob["arrayBuffer"]();
|
|
else
|
|
return new Promise((resolve,reject)=>{
|
|
const fileReader = new FileReader;
|
|
fileReader.onload = ()=>resolve(fileReader.result);
|
|
fileReader.onerror = ()=>reject(fileReader.error);
|
|
fileReader.readAsArrayBuffer(blob)
|
|
}
|
|
)
|
|
}
|
|
;
|
|
C3.BlobToString = function BlobToString(blob) {
|
|
if (typeof blob["text"] === "function")
|
|
return blob["text"]();
|
|
else
|
|
return new Promise((resolve,reject)=>{
|
|
const fileReader = new FileReader;
|
|
fileReader.onload = ()=>resolve(fileReader.result);
|
|
fileReader.onerror = ()=>reject(fileReader.error);
|
|
fileReader.readAsText(blob)
|
|
}
|
|
)
|
|
}
|
|
;
|
|
C3.BlobToJson = function BlobToJson(blob) {
|
|
return C3.BlobToString(blob).then(text=>JSON.parse(text))
|
|
}
|
|
;
|
|
C3.BlobToImage = async function BlobToImage(blob, decodeImage) {
|
|
let blobUrl = URL.createObjectURL(blob);
|
|
try {
|
|
const img = await C3.FetchImage(blobUrl);
|
|
URL.revokeObjectURL(blobUrl);
|
|
blobUrl = "";
|
|
if (decodeImage && typeof img["decode"] === "function")
|
|
await img["decode"]();
|
|
return img
|
|
} finally {
|
|
if (blobUrl)
|
|
URL.revokeObjectURL(blobUrl)
|
|
}
|
|
}
|
|
;
|
|
C3.CreateCanvas = function CreateCanvas(width, height) {
|
|
if (typeof document !== "undefined" && typeof document.createElement === "function") {
|
|
const canvas = document.createElement("canvas");
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
return canvas
|
|
} else
|
|
return new OffscreenCanvas(width,height)
|
|
}
|
|
;
|
|
C3.CanvasToBlob = function CanvasToBlob(canvas, type, quality) {
|
|
if (typeof quality !== "number")
|
|
quality = 1;
|
|
type = type || "image/png";
|
|
quality = C3.clamp(quality, 0, 1);
|
|
if (canvas.toBlob)
|
|
return new Promise(resolve=>canvas.toBlob(resolve, type, quality));
|
|
else if (canvas["convertToBlob"])
|
|
return canvas["convertToBlob"]({
|
|
"type": type,
|
|
"quality": quality
|
|
});
|
|
else
|
|
return C3.Asyncify(()=>C3.CanvasToBlobSync(canvas, type, quality))
|
|
}
|
|
;
|
|
C3.CanvasToBlobSync = function CanvasToBlobSync(canvas, type, quality) {
|
|
if (typeof quality !== "number")
|
|
quality = 1;
|
|
type = type || "image/png";
|
|
quality = C3.clamp(quality, 0, 1);
|
|
return C3.DataURIToBinaryBlobSync(canvas.toDataURL(type, quality))
|
|
}
|
|
;
|
|
C3.DataURIToBinaryBlobSync = function DataURIToBinaryBlobSync(datauri) {
|
|
const o = C3.ParseDataURI(datauri);
|
|
return C3.BinaryStringToBlob(o.data, o.mime_type)
|
|
}
|
|
;
|
|
C3.ParseDataURI = function ParseDataURI(datauri) {
|
|
if (datauri.substr(0, 5) !== "data:")
|
|
throw new URIError("expected data: uri");
|
|
let comma = datauri.indexOf(",");
|
|
if (comma < 0)
|
|
throw new URIError("expected comma in data: uri");
|
|
let typepart = datauri.substring(5, comma);
|
|
let datapart = datauri.substring(comma + 1);
|
|
let typearr = typepart.split(";");
|
|
let mimetype = typearr[0] || "";
|
|
let encoding1 = typearr[1];
|
|
let encoding2 = typearr[2];
|
|
let decodeddata;
|
|
if (encoding1 === "base64" || encoding2 === "base64")
|
|
decodeddata = atob(datapart);
|
|
else
|
|
decodeddata = decodeURIComponent(datapart);
|
|
return {
|
|
mime_type: mimetype,
|
|
data: decodeddata
|
|
}
|
|
}
|
|
;
|
|
C3.BinaryStringToBlob = function BinaryStringToBlob(binstr, mime_type) {
|
|
let len = binstr.length;
|
|
let len32 = len >> 2;
|
|
let a8 = new Uint8Array(len);
|
|
let a32 = new Uint32Array(a8.buffer,0,len32);
|
|
let i, j;
|
|
for (i = 0,
|
|
j = 0; i < len32; ++i)
|
|
a32[i] = binstr.charCodeAt(j++) | binstr.charCodeAt(j++) << 8 | binstr.charCodeAt(j++) << 16 | binstr.charCodeAt(j++) << 24;
|
|
let tailLength = len & 3;
|
|
while (tailLength--) {
|
|
a8[j] = binstr.charCodeAt(j);
|
|
++j
|
|
}
|
|
if (mime_type)
|
|
return new Blob([a8],{
|
|
"type": mime_type
|
|
});
|
|
else
|
|
return new Blob([a8])
|
|
}
|
|
;
|
|
C3.DrawableToBlob = function DrawableToBlob(drawable, type, quality) {
|
|
const canvas = C3.CreateCanvas(drawable.width, drawable.height);
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.drawImage(drawable, 0, 0);
|
|
return C3.CanvasToBlob(canvas, type, quality)
|
|
}
|
|
;
|
|
C3.ImageDataToBlobSync = function ImageDataToBlobSync(imageData, type, quality) {
|
|
const canvas = C3.CreateCanvas(imageData.width, imageData.height);
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.putImageData(imageData, 0, 0);
|
|
return C3.CanvasToBlobSync(canvas, type, quality)
|
|
}
|
|
;
|
|
C3.ImageDataToBlob = function ImageDataToBlob(imageData, type, quality) {
|
|
if (C3.Supports.ImageBitmapOptions)
|
|
return createImageBitmap(imageData, {
|
|
"premultiplyAlpha": "none"
|
|
}).then(imageBitmap=>C3.DrawableToBlob(imageBitmap, type, quality));
|
|
else if (C3.Supports.ImageBitmap)
|
|
return createImageBitmap(imageData).then(imageBitmap=>C3.DrawableToBlob(imageBitmap, type, quality));
|
|
else {
|
|
const canvas = C3.CreateCanvas(imageData.width, imageData.height);
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.putImageData(imageData, 0, 0);
|
|
return C3.CanvasToBlob(canvas, type, quality)
|
|
}
|
|
}
|
|
;
|
|
C3.CopySet = function CopySet(dest, src) {
|
|
dest.clear();
|
|
for (const x of src)
|
|
dest.add(x)
|
|
}
|
|
;
|
|
C3.MapToObject = function MapToObject(map) {
|
|
const ret = Object.create(null);
|
|
for (const [k,v] of map.entries())
|
|
ret[k] = v;
|
|
return ret
|
|
}
|
|
;
|
|
C3.ObjectToMap = function ObjectToMap(o, map) {
|
|
map.clear();
|
|
for (const [k,v] of Object.entries(o))
|
|
map.set(k, v)
|
|
}
|
|
;
|
|
C3.ToSuperJSON = function ToSuperJSON(v) {
|
|
if (typeof v === "object" && v !== null)
|
|
if (v instanceof Set)
|
|
return {
|
|
"_c3type_": "set",
|
|
"data": [...v].map(o=>ToSuperJSON(o))
|
|
};
|
|
else if (v instanceof Map)
|
|
return {
|
|
"_c3type_": "map",
|
|
"data": [...v].map(pair=>[pair[0], ToSuperJSON(pair[1])])
|
|
};
|
|
else {
|
|
const ret = Object.create(null);
|
|
for (const [key,value] of Object.entries(v))
|
|
ret[key] = ToSuperJSON(value);
|
|
return ret
|
|
}
|
|
return v
|
|
}
|
|
;
|
|
C3.FromSuperJSON = function FromSuperJSON(v) {
|
|
if (typeof v === "object" & v !== null)
|
|
if (v["_c3type_"] === "set")
|
|
return new Set(v["data"].map(o=>FromSuperJSON(o)));
|
|
else if (v["_c3type_"] === "map")
|
|
return new Map(v["data"].map(pair=>[pair[0], FromSuperJSON(pair[1])]));
|
|
else {
|
|
const ret = Object.create(null);
|
|
for (const [key,value] of Object.entries(v))
|
|
ret[key] = FromSuperJSON(value);
|
|
return ret
|
|
}
|
|
return v
|
|
}
|
|
;
|
|
C3.CSSToCamelCase = function(str) {
|
|
let ret = "";
|
|
let isAfterHyphen = false;
|
|
for (const ch of str)
|
|
if (ch === "-")
|
|
isAfterHyphen = true;
|
|
else if (isAfterHyphen) {
|
|
ret += ch.toUpperCase();
|
|
isAfterHyphen = false
|
|
} else
|
|
ret += ch;
|
|
return ret
|
|
}
|
|
;
|
|
C3.IsIterator = function(o) {
|
|
return typeof o === "object" && typeof o.next === "function"
|
|
}
|
|
;
|
|
C3.MakeFilledArray = function MakeFilledArray(len, data) {
|
|
const ret = [];
|
|
if (typeof data === "function")
|
|
for (let i = 0; i < len; ++i)
|
|
ret.push(data());
|
|
else
|
|
for (let i = 0; i < len; ++i)
|
|
ret.push(data);
|
|
return ret
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const HSL_TEST = /([0-9.]+),([0-9.]+)%?,([0-9.]+)%?/i;
|
|
const HSLA_TEST = /([0-9.]+),([0-9.]+)%?,([0-9.]+)%?,([0-9.])/i;
|
|
function padTwoDigits(str) {
|
|
if (str.length === 0)
|
|
return "00";
|
|
else if (str.length === 1)
|
|
return "0" + str;
|
|
else
|
|
return str
|
|
}
|
|
function hueToRGB(p, q, t) {
|
|
if (t < 0)
|
|
t += 1;
|
|
if (t > 1)
|
|
t -= 1;
|
|
if (t < 1 / 6)
|
|
return p + (q - p) * 6 * t;
|
|
if (t < 1 / 2)
|
|
return q;
|
|
if (t < 2 / 3)
|
|
return p + (q - p) * (2 / 3 - t) * 6;
|
|
return p
|
|
}
|
|
C3.Color = class Color {
|
|
constructor(r, g, b, a) {
|
|
this._r = NaN;
|
|
this._g = NaN;
|
|
this._b = NaN;
|
|
this._a = NaN;
|
|
this._r = 0;
|
|
this._g = 0;
|
|
this._b = 0;
|
|
this._a = 0;
|
|
if (r instanceof C3.Color)
|
|
this.set(r);
|
|
else
|
|
this.setRgba(r || 0, g || 0, b || 0, a || 0)
|
|
}
|
|
setRgb(r, g, b) {
|
|
this._r = +r;
|
|
this._g = +g;
|
|
this._b = +b;
|
|
this.clamp();
|
|
return this
|
|
}
|
|
setRgba(r, g, b, a) {
|
|
this._r = +r;
|
|
this._g = +g;
|
|
this._b = +b;
|
|
this._a = +a;
|
|
this.clamp();
|
|
return this
|
|
}
|
|
set(c) {
|
|
this._r = c._r;
|
|
this._g = c._g;
|
|
this._b = c._b;
|
|
this._a = c._a;
|
|
return this
|
|
}
|
|
copy(c) {
|
|
return this.set(c)
|
|
}
|
|
add(c) {
|
|
this._r += c._r;
|
|
this._g += c._g;
|
|
this._b += c._b;
|
|
this._a += c._a;
|
|
this.clamp()
|
|
}
|
|
addRgb(r, g, b, a=0) {
|
|
this._r += +r;
|
|
this._g += +g;
|
|
this._b += +b;
|
|
this._a += +a;
|
|
this.clamp()
|
|
}
|
|
diff(c) {
|
|
this.setR(Math.max(this._r, c._r) - Math.min(this._r, c._r));
|
|
this.setG(Math.max(this._g, c._g) - Math.min(this._g, c._g));
|
|
this.setB(Math.max(this._b, c._b) - Math.min(this._b, c._b));
|
|
this.setA(Math.max(this._a, c._a) - Math.min(this._a, c._a));
|
|
this.clamp()
|
|
}
|
|
copyRgb(c) {
|
|
this._r = c._r;
|
|
this._g = c._g;
|
|
this._b = c._b
|
|
}
|
|
setR(r) {
|
|
this._r = C3.clamp(+r, 0, 1)
|
|
}
|
|
getR() {
|
|
return this._r
|
|
}
|
|
setG(g) {
|
|
this._g = C3.clamp(+g, 0, 1)
|
|
}
|
|
getG() {
|
|
return this._g
|
|
}
|
|
setB(b) {
|
|
this._b = C3.clamp(+b, 0, 1)
|
|
}
|
|
getB() {
|
|
return this._b
|
|
}
|
|
setA(a) {
|
|
this._a = C3.clamp(+a, 0, 1)
|
|
}
|
|
getA() {
|
|
return this._a
|
|
}
|
|
clone() {
|
|
return C3.New(C3.Color, this._r, this._g, this._b, this._a)
|
|
}
|
|
toArray() {
|
|
return [this._r, this._g, this._b, this._a]
|
|
}
|
|
toTypedArray() {
|
|
return new Float64Array(this.toArray())
|
|
}
|
|
writeToTypedArray(ta, i) {
|
|
ta[i++] = this._r;
|
|
ta[i++] = this._g;
|
|
ta[i++] = this._b;
|
|
ta[i] = this._a
|
|
}
|
|
equals(c) {
|
|
return this._r === c._r && this._g === c._g && this._b === c._b && this._a === c._a
|
|
}
|
|
equalsIgnoringAlpha(c) {
|
|
return this._r === c._r && this._g === c._g && this._b === c._b
|
|
}
|
|
equalsRgb(r, g, b) {
|
|
return this._r === r && this._g === g && this._b === b
|
|
}
|
|
equalsRgba(r, g, b, a) {
|
|
return this._r === r && this._g === g && this._b === b && this._a === a
|
|
}
|
|
multiply(c) {
|
|
this._r *= c._r;
|
|
this._g *= c._g;
|
|
this._b *= c._b;
|
|
this._a *= c._a
|
|
}
|
|
multiplyAlpha(a) {
|
|
this._r *= a;
|
|
this._g *= a;
|
|
this._b *= a;
|
|
this._a *= a
|
|
}
|
|
premultiply() {
|
|
this._r *= this._a;
|
|
this._g *= this._a;
|
|
this._b *= this._a;
|
|
return this
|
|
}
|
|
unpremultiply() {
|
|
this._r /= this._a;
|
|
this._g /= this._a;
|
|
this._b /= this._a;
|
|
return this
|
|
}
|
|
clamp() {
|
|
this._r = C3.clamp(this._r, 0, 1);
|
|
this._g = C3.clamp(this._g, 0, 1);
|
|
this._b = C3.clamp(this._b, 0, 1);
|
|
this._a = C3.clamp(this._a, 0, 1);
|
|
return this
|
|
}
|
|
setFromRgbValue(rgb) {
|
|
this._r = C3.GetRValue(rgb);
|
|
this._g = C3.GetGValue(rgb);
|
|
this._b = C3.GetBValue(rgb);
|
|
this._a = C3.GetAValue(rgb)
|
|
}
|
|
getCssRgb(_r, _g, _b) {
|
|
const r = C3.IsFiniteNumber(_r) ? _r : this.getR();
|
|
const g = C3.IsFiniteNumber(_g) ? _g : this.getG();
|
|
const b = C3.IsFiniteNumber(_b) ? _b : this.getB();
|
|
return `rgb(${r * 100}%, ${g * 100}%, ${b * 100}%)`
|
|
}
|
|
getCssRgba(_r, _g, _b, _a) {
|
|
const r = C3.IsFiniteNumber(_r) ? _r : this.getR();
|
|
const g = C3.IsFiniteNumber(_g) ? _g : this.getG();
|
|
const b = C3.IsFiniteNumber(_b) ? _b : this.getB();
|
|
const a = C3.IsFiniteNumber(_a) ? _a : this.getA();
|
|
return `rgba(${r * 100}%, ${g * 100}%, ${b * 100}%, ${a})`
|
|
}
|
|
toHexString() {
|
|
const rh = Math.round(this.getR() * 255);
|
|
const gh = Math.round(this.getG() * 255);
|
|
const bh = Math.round(this.getB() * 255);
|
|
return "#" + padTwoDigits(rh.toString(16)) + padTwoDigits(gh.toString(16)) + padTwoDigits(bh.toString(16))
|
|
}
|
|
parseHexString(str) {
|
|
if (typeof str !== "string")
|
|
return false;
|
|
str = str.trim();
|
|
if (str.charAt(0) === "#")
|
|
str = str.substr(1);
|
|
let rv;
|
|
let gv;
|
|
let bv;
|
|
if (str.length === 3) {
|
|
rv = parseInt(str[0], 16) / 15;
|
|
gv = parseInt(str[1], 16) / 15;
|
|
bv = parseInt(str[2], 16) / 15
|
|
} else if (str.length === 6) {
|
|
rv = parseInt(str.substr(0, 2), 16) / 255;
|
|
gv = parseInt(str.substr(2, 2), 16) / 255;
|
|
bv = parseInt(str.substr(4, 2), 16) / 255
|
|
} else
|
|
return false;
|
|
if (isFinite(rv))
|
|
this.setR(rv);
|
|
if (isFinite(gv))
|
|
this.setG(gv);
|
|
if (isFinite(bv))
|
|
this.setB(bv);
|
|
this.setA(1);
|
|
return true
|
|
}
|
|
toCommaSeparatedRgb() {
|
|
const rv = Math.round(this.getR() * 255);
|
|
const gv = Math.round(this.getG() * 255);
|
|
const bv = Math.round(this.getB() * 255);
|
|
return `${rv}, ${gv}, ${bv}`
|
|
}
|
|
toRgbArray() {
|
|
const rv = Math.round(this.getR() * 255);
|
|
const gv = Math.round(this.getG() * 255);
|
|
const bv = Math.round(this.getB() * 255);
|
|
return [rv, gv, bv]
|
|
}
|
|
parseCommaSeparatedRgb(str) {
|
|
if (typeof str !== "string")
|
|
return false;
|
|
str = str.replace(/^rgb\(|\)|%/, "");
|
|
const arr = str.split(",");
|
|
if (arr.length < 3)
|
|
return false;
|
|
const rv = parseInt(arr[0].trim(), 10) / 255;
|
|
const gv = parseInt(arr[1].trim(), 10) / 255;
|
|
const bv = parseInt(arr[2].trim(), 10) / 255;
|
|
if (isFinite(rv))
|
|
this.setR(rv);
|
|
if (isFinite(gv))
|
|
this.setG(gv);
|
|
if (isFinite(bv))
|
|
this.setB(bv);
|
|
this.setA(1);
|
|
return true
|
|
}
|
|
parseCommaSeparatedPercentageRgb(str) {
|
|
if (typeof str !== "string")
|
|
return false;
|
|
str = str.replace(/^rgb\(|\)|%/, "");
|
|
const arr = str.split(",");
|
|
if (arr.length < 3)
|
|
return false;
|
|
const rv = parseInt(arr[0].trim(), 10) / 100;
|
|
const gv = parseInt(arr[1].trim(), 10) / 100;
|
|
const bv = parseInt(arr[2].trim(), 10) / 100;
|
|
if (isFinite(rv))
|
|
this.setR(rv);
|
|
if (isFinite(gv))
|
|
this.setG(gv);
|
|
if (isFinite(bv))
|
|
this.setB(bv);
|
|
this.setA(1);
|
|
return true
|
|
}
|
|
parseCommaSeparatedRgba(str) {
|
|
if (typeof str !== "string")
|
|
return false;
|
|
str = str.replace(/^rgba\(|\)|%/, "");
|
|
const arr = str.split(",");
|
|
if (arr.length < 4)
|
|
return false;
|
|
const rv = parseInt(arr[0].trim(), 10) / 255;
|
|
const gv = parseInt(arr[1].trim(), 10) / 255;
|
|
const bv = parseInt(arr[2].trim(), 10) / 255;
|
|
const av = parseFloat(arr[3].trim());
|
|
if (isFinite(rv))
|
|
this.setR(rv);
|
|
if (isFinite(gv))
|
|
this.setG(gv);
|
|
if (isFinite(bv))
|
|
this.setB(bv);
|
|
if (isFinite(av))
|
|
this.setA(av);
|
|
return true
|
|
}
|
|
parseCommaSeparatedPercentageRgba(str) {
|
|
if (typeof str !== "string")
|
|
return false;
|
|
str = str.replace(/^rgba\(|\)|%/, "");
|
|
const arr = str.split(",");
|
|
if (arr.length < 4)
|
|
return false;
|
|
const rv = parseInt(arr[0].trim(), 10) / 100;
|
|
const gv = parseInt(arr[1].trim(), 10) / 100;
|
|
const bv = parseInt(arr[2].trim(), 10) / 100;
|
|
const av = parseFloat(arr[3].trim());
|
|
if (isFinite(rv))
|
|
this.setR(rv);
|
|
if (isFinite(gv))
|
|
this.setG(gv);
|
|
if (isFinite(bv))
|
|
this.setB(bv);
|
|
if (isFinite(av))
|
|
this.setA(av);
|
|
return true
|
|
}
|
|
parseString(str) {
|
|
if (typeof str !== "string")
|
|
return false;
|
|
str = str.replace(/\s+/, "");
|
|
if (str.includes(","))
|
|
if (str.startsWith("rgb("))
|
|
if (str.includes("%"))
|
|
return this.parseCommaSeparatedPercentageRgb(str);
|
|
else
|
|
return this.parseCommaSeparatedRgb(str);
|
|
else if (str.startsWith("rgba("))
|
|
if (str.includes("%"))
|
|
return this.parseCommaSeparatedPercentageRgba(str);
|
|
else
|
|
return this.parseCommaSeparatedRgba(str);
|
|
else if (str.startsWith("hsl(") || str.startsWith("hsla("))
|
|
return this.parseHSLString(str);
|
|
else {
|
|
const components = str.split(",");
|
|
if (str.includes("%")) {
|
|
if (components.length === 3)
|
|
return this.parseCommaSeparatedPercentageRgb(str);
|
|
else if (components.length === 4)
|
|
return this.parseCommaSeparatedPercentageRgba(str);
|
|
return false
|
|
} else {
|
|
if (components.length === 3)
|
|
return this.parseCommaSeparatedRgb(str);
|
|
else if (components.length === 4)
|
|
return this.parseCommaSeparatedRgba(str);
|
|
return false
|
|
}
|
|
}
|
|
else
|
|
return this.parseHexString(str)
|
|
}
|
|
toJSON() {
|
|
return [this._r, this._g, this._b, this._a]
|
|
}
|
|
setFromHSLA(h, s, l, a) {
|
|
let r;
|
|
let g;
|
|
let b;
|
|
h %= 360;
|
|
s = C3.clamp(s, 0, 100);
|
|
l = C3.clamp(l, 0, 100);
|
|
a = C3.clamp(a, 0, 1);
|
|
h /= 360;
|
|
s /= 100;
|
|
l /= 100;
|
|
if (s === 0)
|
|
r = g = b = l;
|
|
else {
|
|
const q = l < .5 ? l * (1 + s) : l + s - l * s;
|
|
const p = 2 * l - q;
|
|
r = hueToRGB(p, q, h + 1 / 3);
|
|
g = hueToRGB(p, q, h);
|
|
b = hueToRGB(p, q, h - 1 / 3)
|
|
}
|
|
this.setR(r);
|
|
this.setG(g);
|
|
this.setB(b);
|
|
this.setA(a);
|
|
return this
|
|
}
|
|
parseHSLString(str) {
|
|
const cleanString = str.replace(/ |hsl|hsla|\(|\)|;/gi, "");
|
|
const hsl = HSL_TEST.exec(cleanString);
|
|
const hsla = HSLA_TEST.exec(cleanString);
|
|
if (hsl && hsl.length === 4) {
|
|
this.setFromHSLA(+hsl[1], +hsl[2], +hsl[3], 1);
|
|
return true
|
|
} else if (hsla && hsla.length === 5) {
|
|
this.setFromHSLA(+hsl[1], +hsl[2], +hsl[3], +hsl[4]);
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
toHSLAString() {
|
|
const r = this._r;
|
|
const g = this._g;
|
|
const b = this._b;
|
|
const a = this._a;
|
|
const h = C3.Color.GetHue(r, g, b);
|
|
const s = C3.Color.GetSaturation(r, g, b);
|
|
const l = C3.Color.GetLuminosity(r, g, b);
|
|
return `hsla(${h}, ${s}%, ${l}%, ${a})`
|
|
}
|
|
toHSLAArray() {
|
|
const r = this._r;
|
|
const g = this._g;
|
|
const b = this._b;
|
|
return [C3.Color.GetHue(r, g, b), C3.Color.GetSaturation(r, g, b), C3.Color.GetLuminosity(r, g, b), this._a]
|
|
}
|
|
setFromJSON(arr) {
|
|
if (!Array.isArray(arr))
|
|
return;
|
|
if (arr.length < 3)
|
|
return;
|
|
this._r = arr[0];
|
|
this._g = arr[1];
|
|
this._b = arr[2];
|
|
if (arr.length >= 4)
|
|
this._a = arr[3];
|
|
else
|
|
this._a = 1
|
|
}
|
|
set r(r) {
|
|
this.setR(r)
|
|
}
|
|
get r() {
|
|
return this.getR()
|
|
}
|
|
set g(g) {
|
|
this.setG(g)
|
|
}
|
|
get g() {
|
|
return this.getG()
|
|
}
|
|
set b(b) {
|
|
this.setB(b)
|
|
}
|
|
get b() {
|
|
return this.getB()
|
|
}
|
|
set a(a) {
|
|
this.setA(a)
|
|
}
|
|
get a() {
|
|
return this.getA()
|
|
}
|
|
setAtIndex(i, v) {
|
|
switch (i) {
|
|
case 0:
|
|
this.setR(v);
|
|
break;
|
|
case 1:
|
|
this.setG(v);
|
|
break;
|
|
case 2:
|
|
this.setB(v);
|
|
break;
|
|
case 3:
|
|
this.setA(v);
|
|
break;
|
|
default:
|
|
throw new RangeError("invalid color index");
|
|
}
|
|
}
|
|
getAtIndex(i) {
|
|
switch (i) {
|
|
case 0:
|
|
return this.getR();
|
|
case 1:
|
|
return this.getG();
|
|
case 2:
|
|
return this.getB();
|
|
case 3:
|
|
return this.getA();
|
|
default:
|
|
throw new RangeError("invalid color index");
|
|
}
|
|
}
|
|
static DiffChannel(channel1, channel2) {
|
|
return C3.clamp(Math.max(channel1, channel2) - Math.min(channel1, channel2), 0, 1)
|
|
}
|
|
static Diff(c1, c2) {
|
|
const ret = new C3.Color;
|
|
ret.setR(Math.max(c1._r, c2._r) - Math.min(c1._r, c2._r));
|
|
ret.setG(Math.max(c1._g, c2._g) - Math.min(c1._g, c2._g));
|
|
ret.setB(Math.max(c1._b, c2._b) - Math.min(c1._b, c2._b));
|
|
ret.setA(Math.max(c1._a, c2._a) - Math.min(c1._a, c2._a));
|
|
return ret
|
|
}
|
|
static DiffNoAlpha(c1, c2) {
|
|
const ret = new C3.Color(0,0,0,1);
|
|
ret.setR(Math.max(c1._r, c2._r) - Math.min(c1._r, c2._r));
|
|
ret.setG(Math.max(c1._g, c2._g) - Math.min(c1._g, c2._g));
|
|
ret.setB(Math.max(c1._b, c2._b) - Math.min(c1._b, c2._b));
|
|
return ret
|
|
}
|
|
static GetHue(r, g, b) {
|
|
const max = Math.max(r, g, b);
|
|
const min = Math.min(r, g, b);
|
|
if (max === min)
|
|
return 0;
|
|
let h = 0;
|
|
switch (max) {
|
|
case r:
|
|
h = (g - b) / (max - min) + (g < b ? 6 : 0);
|
|
break;
|
|
case g:
|
|
h = (b - r) / (max - min) + 2;
|
|
break;
|
|
case b:
|
|
h = (r - g) / (max - min) + 4;
|
|
break
|
|
}
|
|
return Math.round(h / 6 * 360)
|
|
}
|
|
static GetSaturation(r, g, b) {
|
|
const max = Math.max(r, g, b);
|
|
const min = Math.min(r, g, b);
|
|
if (max === min)
|
|
return 0;
|
|
const l = (max + min) / 2;
|
|
const d = max - min;
|
|
const s = l > .5 ? d / (2 - max - min) : d / (max + min);
|
|
return Math.round(s * 100)
|
|
}
|
|
static GetLuminosity(r, g, b) {
|
|
const max = Math.max(r, g, b);
|
|
const min = Math.min(r, g, b);
|
|
const l = (max + min) / 2;
|
|
if (!max)
|
|
return 0;
|
|
return Math.round(l * 100)
|
|
}
|
|
}
|
|
;
|
|
C3.Color.White = Object.freeze(C3.New(C3.Color, 1, 1, 1, 1));
|
|
C3.Color.Black = Object.freeze(C3.New(C3.Color, 0, 0, 0, 1));
|
|
C3.Color.TransparentBlack = Object.freeze(C3.New(C3.Color, 0, 0, 0, 0))
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Vector2 = class Vector2 {
|
|
constructor(x, y) {
|
|
this._x = 0;
|
|
this._y = 0;
|
|
if (x instanceof C3.Vector2)
|
|
this.copy(x);
|
|
else
|
|
this.set(x || 0, y || 0)
|
|
}
|
|
set(x, y) {
|
|
this._x = +x;
|
|
this._y = +y
|
|
}
|
|
copy(v) {
|
|
this._x = v._x;
|
|
this._y = v._y
|
|
}
|
|
equals(v) {
|
|
return this._x === v._x && this._y === v._y
|
|
}
|
|
setX(x) {
|
|
this._x = +x
|
|
}
|
|
getX() {
|
|
return this._x
|
|
}
|
|
setY(y) {
|
|
this._y = +y
|
|
}
|
|
getY() {
|
|
return this._y
|
|
}
|
|
toArray() {
|
|
return [this._x, this._y]
|
|
}
|
|
toTypedArray() {
|
|
return new Float64Array(this.toArray())
|
|
}
|
|
writeToTypedArray(ta, i) {
|
|
ta[i++] = this._x;
|
|
ta[i] = this._y
|
|
}
|
|
offset(x, y) {
|
|
this._x += +x;
|
|
this._y += +y
|
|
}
|
|
scale(x, y) {
|
|
this._x *= x;
|
|
this._y *= y
|
|
}
|
|
round() {
|
|
this._x = Math.round(this._x);
|
|
this._y = Math.round(this._y)
|
|
}
|
|
floor() {
|
|
this._x = Math.floor(this._x);
|
|
this._y = Math.floor(this._y)
|
|
}
|
|
ceil() {
|
|
this._x = Math.ceil(this._x);
|
|
this._y = Math.ceil(this._y)
|
|
}
|
|
angle() {
|
|
return C3.angleTo(0, 0, this._x, this._y)
|
|
}
|
|
lengthSquared() {
|
|
return this._x * this._x + this._y * this._y
|
|
}
|
|
length() {
|
|
return Math.sqrt(this.lengthSquared())
|
|
}
|
|
rotatePrecalc(sin_a, cos_a) {
|
|
const temp = this._x * cos_a - this._y * sin_a;
|
|
this._y = this._y * cos_a + this._x * sin_a;
|
|
this._x = temp
|
|
}
|
|
rotate(a) {
|
|
if (a === 0)
|
|
return;
|
|
this.rotatePrecalc(Math.sin(a), Math.cos(a))
|
|
}
|
|
rotateAbout(a, x, y) {
|
|
if (a === 0 || x === this._x && y === this._y)
|
|
return;
|
|
this._x -= x;
|
|
this._y -= y;
|
|
this.rotatePrecalc(Math.sin(a), Math.cos(a));
|
|
this._x += +x;
|
|
this._y += +y
|
|
}
|
|
move(a, dist) {
|
|
if (dist === 0)
|
|
return;
|
|
this._x += Math.cos(a) * dist;
|
|
this._y += Math.sin(a) * dist
|
|
}
|
|
normalize() {
|
|
const m = this.length();
|
|
if (m !== 0 && m !== 1) {
|
|
this._x /= m;
|
|
this._y /= m
|
|
}
|
|
}
|
|
clamp(lower, upper) {
|
|
this._x = C3.clamp(this._x, lower, upper);
|
|
this._y = C3.clamp(this._y, lower, upper)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Rect = class Rect {
|
|
constructor(left, top, right, bottom) {
|
|
this._left = NaN;
|
|
this._top = NaN;
|
|
this._right = NaN;
|
|
this._bottom = NaN;
|
|
this._left = 0;
|
|
this._top = 0;
|
|
this._right = 0;
|
|
this._bottom = 0;
|
|
if (left instanceof C3.Rect)
|
|
this.copy(left);
|
|
else
|
|
this.set(left || 0, top || 0, right || 0, bottom || 0)
|
|
}
|
|
set(left, top, right, bottom) {
|
|
this._left = +left;
|
|
this._top = +top;
|
|
this._right = +right;
|
|
this._bottom = +bottom
|
|
}
|
|
setWH(left, top, width, height) {
|
|
left = +left;
|
|
top = +top;
|
|
this._left = left;
|
|
this._top = top;
|
|
this._right = left + +width;
|
|
this._bottom = top + +height
|
|
}
|
|
copy(rect) {
|
|
this._left = +rect._left;
|
|
this._top = +rect._top;
|
|
this._right = +rect._right;
|
|
this._bottom = +rect._bottom
|
|
}
|
|
clone() {
|
|
return new C3.Rect(this._left,this._top,this._right,this._bottom)
|
|
}
|
|
static Merge(first, second) {
|
|
const ret = new C3.Rect;
|
|
ret.setLeft(Math.min(first._left, second._left));
|
|
ret.setTop(Math.min(first._top, second._top));
|
|
ret.setRight(Math.max(first._right, second._right));
|
|
ret.setBottom(Math.max(first._bottom, second._bottom));
|
|
return ret
|
|
}
|
|
static FromObject(o) {
|
|
return new C3.Rect(o.left,o.top,o.right,o.bottom)
|
|
}
|
|
equals(rect) {
|
|
return this._left === rect._left && this._top === rect._top && this._right === rect._right && this._bottom === rect._bottom
|
|
}
|
|
setLeft(l) {
|
|
this._left = +l
|
|
}
|
|
getLeft() {
|
|
return this._left
|
|
}
|
|
setTop(t) {
|
|
this._top = +t
|
|
}
|
|
getTop() {
|
|
return this._top
|
|
}
|
|
setRight(r) {
|
|
this._right = +r
|
|
}
|
|
getRight() {
|
|
return this._right
|
|
}
|
|
setBottom(b) {
|
|
this._bottom = +b
|
|
}
|
|
getBottom() {
|
|
return this._bottom
|
|
}
|
|
toArray() {
|
|
return [this._left, this._top, this._right, this._bottom]
|
|
}
|
|
toTypedArray() {
|
|
return new Float64Array(this.toArray())
|
|
}
|
|
toDOMRect() {
|
|
return new DOMRect(this._left,this._top,this.width(),this.height())
|
|
}
|
|
writeToTypedArray(ta, i) {
|
|
ta[i++] = this._left;
|
|
ta[i++] = this._top;
|
|
ta[i++] = this._right;
|
|
ta[i] = this._bottom
|
|
}
|
|
writeAsQuadToTypedArray(ta, i) {
|
|
ta[i++] = this._left;
|
|
ta[i++] = this._top;
|
|
ta[i++] = this._right;
|
|
ta[i++] = this._top;
|
|
ta[i++] = this._right;
|
|
ta[i++] = this._bottom;
|
|
ta[i++] = this._left;
|
|
ta[i] = this._bottom
|
|
}
|
|
width() {
|
|
return this._right - this._left
|
|
}
|
|
height() {
|
|
return this._bottom - this._top
|
|
}
|
|
midX() {
|
|
return (this._left + this._right) / 2
|
|
}
|
|
midY() {
|
|
return (this._top + this._bottom) / 2
|
|
}
|
|
offset(x, y) {
|
|
x = +x;
|
|
y = +y;
|
|
this._left += x;
|
|
this._top += y;
|
|
this._right += x;
|
|
this._bottom += y
|
|
}
|
|
offsetLeft(x) {
|
|
this._left += +x
|
|
}
|
|
offsetTop(y) {
|
|
this._top += +y
|
|
}
|
|
offsetRight(x) {
|
|
this._right += +x
|
|
}
|
|
offsetBottom(y) {
|
|
this._bottom += +y
|
|
}
|
|
toSquare(axis) {
|
|
if (axis !== "x")
|
|
throw new Error("invalid axis, only 'x' supported");
|
|
if (this._top < this._bottom)
|
|
if (this._left < this._right)
|
|
this._bottom = this._top + this.width();
|
|
else
|
|
this._bottom = this._top - this.width();
|
|
else if (this._left < this._right)
|
|
this._bottom = this._top - this.width();
|
|
else
|
|
this._bottom = this._top + this.width()
|
|
}
|
|
inflate(x, y) {
|
|
x = +x;
|
|
y = +y;
|
|
this._left -= x;
|
|
this._top -= y;
|
|
this._right += x;
|
|
this._bottom += y
|
|
}
|
|
deflate(x, y) {
|
|
x = +x;
|
|
y = +y;
|
|
this._left += x;
|
|
this._top += y;
|
|
this._right -= x;
|
|
this._bottom -= y
|
|
}
|
|
multiply(x, y) {
|
|
this._left *= x;
|
|
this._top *= y;
|
|
this._right *= x;
|
|
this._bottom *= y
|
|
}
|
|
divide(x, y) {
|
|
this._left /= x;
|
|
this._top /= y;
|
|
this._right /= x;
|
|
this._bottom /= y
|
|
}
|
|
mirrorAround(origin) {
|
|
this._left = +origin - this._left;
|
|
this._right = +origin - this._right
|
|
}
|
|
flipAround(origin) {
|
|
this._top = +origin - this._top;
|
|
this._bottom = +origin - this._bottom
|
|
}
|
|
swapLeftRight() {
|
|
const temp = this._left;
|
|
this._left = this._right;
|
|
this._right = temp
|
|
}
|
|
swapTopBottom() {
|
|
const temp = this._top;
|
|
this._top = this._bottom;
|
|
this._bottom = temp
|
|
}
|
|
shuntY(h) {
|
|
const top = this._top;
|
|
this._top = +h - this._bottom;
|
|
this._bottom = +h - top
|
|
}
|
|
round() {
|
|
this._left = Math.round(this._left);
|
|
this._top = Math.round(this._top);
|
|
this._right = Math.round(this._right);
|
|
this._bottom = Math.round(this._bottom)
|
|
}
|
|
roundInner() {
|
|
this._left = Math.ceil(this._left);
|
|
this._top = Math.ceil(this._top);
|
|
this._right = Math.floor(this._right);
|
|
this._bottom = Math.floor(this._bottom)
|
|
}
|
|
roundOuter() {
|
|
this._left = Math.floor(this._left);
|
|
this._top = Math.floor(this._top);
|
|
this._right = Math.ceil(this._right);
|
|
this._bottom = Math.ceil(this._bottom)
|
|
}
|
|
floor() {
|
|
this._left = Math.floor(this._left);
|
|
this._top = Math.floor(this._top);
|
|
this._right = Math.floor(this._right);
|
|
this._bottom = Math.floor(this._bottom)
|
|
}
|
|
ceil() {
|
|
this._left = Math.ceil(this._left);
|
|
this._top = Math.ceil(this._top);
|
|
this._right = Math.ceil(this._right);
|
|
this._bottom = Math.ceil(this._bottom)
|
|
}
|
|
clamp(l, t, r, b) {
|
|
if (this._left < l)
|
|
this._left = +l;
|
|
if (this._top < t)
|
|
this._top = +t;
|
|
if (this._right > r)
|
|
this._right = +r;
|
|
if (this._bottom > b)
|
|
this._bottom = +b
|
|
}
|
|
clampFlipped(l, t, r, b) {
|
|
if (this._left < l)
|
|
this._left = +l;
|
|
if (this._top > t)
|
|
this._top = +t;
|
|
if (this._right > r)
|
|
this._right = +r;
|
|
if (this._bottom < b)
|
|
this._bottom = +b
|
|
}
|
|
normalize() {
|
|
if (this._left > this._right)
|
|
this.swapLeftRight();
|
|
if (this._top > this._bottom)
|
|
this.swapTopBottom()
|
|
}
|
|
intersectsRect(rect) {
|
|
return !(rect._right < this._left || rect._bottom < this._top || rect._left > this._right || rect._top > this._bottom)
|
|
}
|
|
intersectsRectOffset(rect, x, y) {
|
|
return !(rect._right + x < this._left || rect._bottom + y < this._top || rect._left + x > this._right || rect._top + y > this._bottom)
|
|
}
|
|
containsPoint(x, y) {
|
|
return x >= this._left && x <= this._right && y >= this._top && y <= this._bottom
|
|
}
|
|
containsRect(rect) {
|
|
return rect._left >= this._left && rect._top >= this._top && rect._right <= this._right && rect._bottom <= this._bottom
|
|
}
|
|
expandToContain(rect) {
|
|
if (rect._left < this._left)
|
|
this._left = +rect._left;
|
|
if (rect._top < this._top)
|
|
this._top = +rect._top;
|
|
if (rect._right > this._right)
|
|
this._right = +rect._right;
|
|
if (rect._bottom > this._bottom)
|
|
this._bottom = +rect._bottom
|
|
}
|
|
lerpInto(rect) {
|
|
this._left = C3.lerp(rect._left, rect._right, this._left);
|
|
this._top = C3.lerp(rect._top, rect._bottom, this._top);
|
|
this._right = C3.lerp(rect._left, rect._right, this._right);
|
|
this._bottom = C3.lerp(rect._top, rect._bottom, this._bottom)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Quad = class Quad {
|
|
constructor(tlx, tly, trx, try_, brx, bry, blx, bly) {
|
|
this._tlx = NaN;
|
|
this._tly = NaN;
|
|
this._trx = NaN;
|
|
this._try = NaN;
|
|
this._brx = NaN;
|
|
this._bry = NaN;
|
|
this._blx = NaN;
|
|
this._bly = NaN;
|
|
this._tlx = 0;
|
|
this._tly = 0;
|
|
this._trx = 0;
|
|
this._try = 0;
|
|
this._brx = 0;
|
|
this._bry = 0;
|
|
this._blx = 0;
|
|
this._bly = 0;
|
|
if (tlx instanceof C3.Quad)
|
|
this.copy(tlx);
|
|
else
|
|
this.set(tlx || 0, tly || 0, trx || 0, try_ || 0, brx || 0, bry || 0, blx || 0, bly || 0)
|
|
}
|
|
set(tlx, tly, trx, try_, brx, bry, blx, bly) {
|
|
this._tlx = +tlx;
|
|
this._tly = +tly;
|
|
this._trx = +trx;
|
|
this._try = +try_;
|
|
this._brx = +brx;
|
|
this._bry = +bry;
|
|
this._blx = +blx;
|
|
this._bly = +bly
|
|
}
|
|
setRect(left, top, right, bottom) {
|
|
this.set(left, top, right, top, right, bottom, left, bottom)
|
|
}
|
|
copy(q) {
|
|
this._tlx = q._tlx;
|
|
this._tly = q._tly;
|
|
this._trx = q._trx;
|
|
this._try = q._try;
|
|
this._brx = q._brx;
|
|
this._bry = q._bry;
|
|
this._blx = q._blx;
|
|
this._bly = q._bly
|
|
}
|
|
equals(q) {
|
|
return this._tlx === q._tlx && this._tly === q._tly && this._trx === q._trx && this._try === q._try && this._brx === q._brx && this._bry === q._bry && this._blx === q._blx && this._bly === q._bly
|
|
}
|
|
setTlx(v) {
|
|
this._tlx = +v
|
|
}
|
|
getTlx() {
|
|
return this._tlx
|
|
}
|
|
setTly(v) {
|
|
this._tly = +v
|
|
}
|
|
getTly() {
|
|
return this._tly
|
|
}
|
|
setTrx(v) {
|
|
this._trx = +v
|
|
}
|
|
getTrx() {
|
|
return this._trx
|
|
}
|
|
setTry(v) {
|
|
this._try = +v
|
|
}
|
|
getTry() {
|
|
return this._try
|
|
}
|
|
setBrx(v) {
|
|
this._brx = +v
|
|
}
|
|
getBrx() {
|
|
return this._brx
|
|
}
|
|
setBry(v) {
|
|
this._bry = +v
|
|
}
|
|
getBry() {
|
|
return this._bry
|
|
}
|
|
setBlx(v) {
|
|
this._blx = +v
|
|
}
|
|
getBlx() {
|
|
return this._blx
|
|
}
|
|
setBly(v) {
|
|
this._bly = +v
|
|
}
|
|
getBly() {
|
|
return this._bly
|
|
}
|
|
toDOMQuad() {
|
|
return new DOMQuad(new DOMPoint(this._tlx,this._tly),new DOMPoint(this._trx,this._try),new DOMPoint(this._brx,this._bry),new DOMPoint(this._blx,this._bly))
|
|
}
|
|
toArray() {
|
|
return [this._tlx, this._tly, this._trx, this._try, this._brx, this._bry, this._blx, this._bly]
|
|
}
|
|
toTypedArray() {
|
|
return new Float64Array(this.toArray())
|
|
}
|
|
writeToTypedArray(ta, i) {
|
|
ta[i++] = this._tlx;
|
|
ta[i++] = this._tly;
|
|
ta[i++] = this._trx;
|
|
ta[i++] = this._try;
|
|
ta[i++] = this._brx;
|
|
ta[i++] = this._bry;
|
|
ta[i++] = this._blx;
|
|
ta[i] = this._bly
|
|
}
|
|
writeToTypedArray3D(ta, i, z) {
|
|
ta[i++] = this._tlx;
|
|
ta[i++] = this._tly;
|
|
ta[i++] = z;
|
|
ta[i++] = this._trx;
|
|
ta[i++] = this._try;
|
|
ta[i++] = z;
|
|
ta[i++] = this._brx;
|
|
ta[i++] = this._bry;
|
|
ta[i++] = z;
|
|
ta[i++] = this._blx;
|
|
ta[i++] = this._bly;
|
|
ta[i] = z
|
|
}
|
|
offset(x, y) {
|
|
x = +x;
|
|
y = +y;
|
|
this._tlx += x;
|
|
this._tly += y;
|
|
this._trx += x;
|
|
this._try += y;
|
|
this._brx += x;
|
|
this._bry += y;
|
|
this._blx += x;
|
|
this._bly += y
|
|
}
|
|
round() {
|
|
this._tlx = Math.round(this._tlx);
|
|
this._tly = Math.round(this._tly);
|
|
this._trx = Math.round(this._trx);
|
|
this._try = Math.round(this._try);
|
|
this._brx = Math.round(this._brx);
|
|
this._bry = Math.round(this._bry);
|
|
this._blx = Math.round(this._blx);
|
|
this._bly = Math.round(this._bly)
|
|
}
|
|
floor() {
|
|
this._tlx = Math.floor(this._tlx);
|
|
this._tly = Math.floor(this._tly);
|
|
this._trx = Math.floor(this._trx);
|
|
this._try = Math.floor(this._try);
|
|
this._brx = Math.floor(this._brx);
|
|
this._bry = Math.floor(this._bry);
|
|
this._blx = Math.floor(this._blx);
|
|
this._bly = Math.floor(this._bly)
|
|
}
|
|
ceil() {
|
|
this._tlx = Math.ceil(this._tlx);
|
|
this._tly = Math.ceil(this._tly);
|
|
this._trx = Math.ceil(this._trx);
|
|
this._try = Math.ceil(this._try);
|
|
this._brx = Math.ceil(this._brx);
|
|
this._bry = Math.ceil(this._bry);
|
|
this._blx = Math.ceil(this._blx);
|
|
this._bly = Math.ceil(this._bly)
|
|
}
|
|
setFromRect(rect) {
|
|
this._tlx = rect._left;
|
|
this._tly = rect._top;
|
|
this._trx = rect._right;
|
|
this._try = rect._top;
|
|
this._brx = rect._right;
|
|
this._bry = rect._bottom;
|
|
this._blx = rect._left;
|
|
this._bly = rect._bottom
|
|
}
|
|
setFromRotatedRect(rect, a) {
|
|
if (a === 0)
|
|
this.setFromRect(rect);
|
|
else
|
|
this.setFromRotatedRectPrecalc(rect, Math.sin(a), Math.cos(a))
|
|
}
|
|
setFromRotatedRectPrecalc(rect, sin_a, cos_a) {
|
|
const left_sin_a = rect._left * sin_a;
|
|
const top_sin_a = rect._top * sin_a;
|
|
const right_sin_a = rect._right * sin_a;
|
|
const bottom_sin_a = rect._bottom * sin_a;
|
|
const left_cos_a = rect._left * cos_a;
|
|
const top_cos_a = rect._top * cos_a;
|
|
const right_cos_a = rect._right * cos_a;
|
|
const bottom_cos_a = rect._bottom * cos_a;
|
|
this._tlx = left_cos_a - top_sin_a;
|
|
this._tly = top_cos_a + left_sin_a;
|
|
this._trx = right_cos_a - top_sin_a;
|
|
this._try = top_cos_a + right_sin_a;
|
|
this._brx = right_cos_a - bottom_sin_a;
|
|
this._bry = bottom_cos_a + right_sin_a;
|
|
this._blx = left_cos_a - bottom_sin_a;
|
|
this._bly = bottom_cos_a + left_sin_a
|
|
}
|
|
getBoundingBox(rect) {
|
|
rect.set(Math.min(this._tlx, this._trx, this._brx, this._blx), Math.min(this._tly, this._try, this._bry, this._bly), Math.max(this._tlx, this._trx, this._brx, this._blx), Math.max(this._tly, this._try, this._bry, this._bly))
|
|
}
|
|
containsPoint(x, y) {
|
|
let v0x = this._trx - this._tlx;
|
|
let v0y = this._try - this._tly;
|
|
const v1x = this._brx - this._tlx;
|
|
const v1y = this._bry - this._tly;
|
|
const v2x = x - this._tlx;
|
|
const v2y = y - this._tly;
|
|
let dot00 = v0x * v0x + v0y * v0y;
|
|
let dot01 = v0x * v1x + v0y * v1y;
|
|
let dot02 = v0x * v2x + v0y * v2y;
|
|
const dot11 = v1x * v1x + v1y * v1y;
|
|
const dot12 = v1x * v2x + v1y * v2y;
|
|
let invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
|
|
let u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
|
let v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
if (u >= 0 && v > 0 && u + v < 1)
|
|
return true;
|
|
v0x = this._blx - this._tlx;
|
|
v0y = this._bly - this._tly;
|
|
dot00 = v0x * v0x + v0y * v0y;
|
|
dot01 = v0x * v1x + v0y * v1y;
|
|
dot02 = v0x * v2x + v0y * v2y;
|
|
invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
|
|
u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
|
v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
return u >= 0 && v > 0 && u + v < 1
|
|
}
|
|
midX() {
|
|
return (this._tlx + this._trx + this._brx + this._blx) / 4
|
|
}
|
|
midY() {
|
|
return (this._tly + this._try + this._bry + this._bly) / 4
|
|
}
|
|
intersectsSegment(x1, y1, x2, y2) {
|
|
if (this.containsPoint(x1, y1) || this.containsPoint(x2, y2))
|
|
return true;
|
|
return C3.segmentIntersectsQuad(x1, y1, x2, y2, this)
|
|
}
|
|
intersectsQuad(rhs) {
|
|
let midX = rhs.midX();
|
|
let midY = rhs.midY();
|
|
if (this.containsPoint(midX, midY))
|
|
return true;
|
|
midX = this.midX();
|
|
midY = this.midY();
|
|
if (rhs.containsPoint(midX, midY))
|
|
return true;
|
|
const tlx = this._tlx
|
|
, tly = this._tly
|
|
, trx = this._trx
|
|
, try_ = this._try
|
|
, brx = this._brx
|
|
, bry = this._bry
|
|
, blx = this._blx
|
|
, bly = this._bly;
|
|
return C3.segmentIntersectsQuad(tlx, tly, trx, try_, rhs) || C3.segmentIntersectsQuad(trx, try_, brx, bry, rhs) || C3.segmentIntersectsQuad(brx, bry, blx, bly, rhs) || C3.segmentIntersectsQuad(blx, bly, tlx, tly, rhs)
|
|
}
|
|
mirror() {
|
|
this._swap(0, 2);
|
|
this._swap(1, 3);
|
|
this._swap(6, 4);
|
|
this._swap(7, 5)
|
|
}
|
|
flip() {
|
|
this._swap(0, 6);
|
|
this._swap(1, 7);
|
|
this._swap(2, 4);
|
|
this._swap(3, 5)
|
|
}
|
|
diag() {
|
|
this._swap(2, 6);
|
|
this._swap(3, 7)
|
|
}
|
|
_swap(i, j) {
|
|
const tmp = this._getAtIndex(i);
|
|
this._setAtIndex(i, this._getAtIndex(j));
|
|
this._setAtIndex(j, tmp)
|
|
}
|
|
_getAtIndex(i) {
|
|
switch (i) {
|
|
case 0:
|
|
return this._tlx;
|
|
case 1:
|
|
return this._tly;
|
|
case 2:
|
|
return this._trx;
|
|
case 3:
|
|
return this._try;
|
|
case 4:
|
|
return this._brx;
|
|
case 5:
|
|
return this._bry;
|
|
case 6:
|
|
return this._blx;
|
|
case 7:
|
|
return this._bly;
|
|
default:
|
|
throw new RangeError("invalid quad point index");
|
|
}
|
|
}
|
|
_setAtIndex(i, v) {
|
|
v = +v;
|
|
switch (i) {
|
|
case 0:
|
|
this._tlx = v;
|
|
break;
|
|
case 1:
|
|
this._tly = v;
|
|
break;
|
|
case 2:
|
|
this._trx = v;
|
|
break;
|
|
case 3:
|
|
this._try = v;
|
|
break;
|
|
case 4:
|
|
this._brx = v;
|
|
break;
|
|
case 5:
|
|
this._bry = v;
|
|
break;
|
|
case 6:
|
|
this._blx = v;
|
|
break;
|
|
case 7:
|
|
this._bly = v;
|
|
break;
|
|
default:
|
|
throw new RangeError("invalid quad point index");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
const DEFAULT_POLY_POINTS = [0, 0, 1, 0, 1, 1, 0, 1];
|
|
const tempQuad = C3.New(C3.Quad);
|
|
C3.CollisionPoly = class CollisionPoly extends C3.DefendedBase {
|
|
constructor(pointsArr, enabled=true) {
|
|
super();
|
|
if (!pointsArr)
|
|
pointsArr = DEFAULT_POLY_POINTS;
|
|
this._ptsArr = Float64Array.from(pointsArr);
|
|
this._bbox = new C3.Rect;
|
|
this._isBboxChanged = true;
|
|
this._enabled = enabled
|
|
}
|
|
Release() {}
|
|
pointsArr() {
|
|
return this._ptsArr
|
|
}
|
|
pointCount() {
|
|
return this._ptsArr.length / 2
|
|
}
|
|
setPoints(pointsArr) {
|
|
if (this._ptsArr.length === pointsArr.length)
|
|
this._ptsArr.set(pointsArr);
|
|
else
|
|
this._ptsArr = Float64Array.from(pointsArr);
|
|
this._isBboxChanged = true
|
|
}
|
|
setDefaultPoints() {
|
|
this.setPoints(DEFAULT_POLY_POINTS)
|
|
}
|
|
copy(poly) {
|
|
this.setPoints(poly._ptsArr)
|
|
}
|
|
setBboxChanged() {
|
|
this._isBboxChanged = true
|
|
}
|
|
_updateBbox() {
|
|
if (!this._isBboxChanged)
|
|
return;
|
|
const ptsArr = this._ptsArr;
|
|
let left = ptsArr[0];
|
|
let top = ptsArr[1];
|
|
let right = left;
|
|
let bottom = top;
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2) {
|
|
const x = ptsArr[i];
|
|
const y = ptsArr[i + 1];
|
|
if (x < left)
|
|
left = x;
|
|
if (x > right)
|
|
right = x;
|
|
if (y < top)
|
|
top = y;
|
|
if (y > bottom)
|
|
bottom = y
|
|
}
|
|
this._bbox.set(left, top, right, bottom);
|
|
this._isBboxChanged = false
|
|
}
|
|
setFromRect(rc, offX, offY) {
|
|
let ptsArr = this._ptsArr;
|
|
if (ptsArr.length !== 8) {
|
|
ptsArr = new Float64Array(8);
|
|
this._ptsArr = ptsArr
|
|
}
|
|
ptsArr[0] = rc.getLeft() - offX;
|
|
ptsArr[1] = rc.getTop() - offY;
|
|
ptsArr[2] = rc.getRight() - offX;
|
|
ptsArr[3] = rc.getTop() - offY;
|
|
ptsArr[4] = rc.getRight() - offX;
|
|
ptsArr[5] = rc.getBottom() - offY;
|
|
ptsArr[6] = rc.getLeft() - offX;
|
|
ptsArr[7] = rc.getBottom() - offY;
|
|
this._bbox.copy(rc);
|
|
if (offX !== 0 || offY !== 0)
|
|
this._bbox.offset(-offX, -offY);
|
|
this._isBboxChanged = false
|
|
}
|
|
setFromQuad(q, offX, offY) {
|
|
tempQuad.copy(q);
|
|
tempQuad.offset(offX, offY);
|
|
this.setPoints(tempQuad.toArray());
|
|
this._isBboxChanged = true
|
|
}
|
|
transform(w, h, a) {
|
|
let sina = 0;
|
|
let cosa = 1;
|
|
if (a !== 0) {
|
|
sina = Math.sin(a);
|
|
cosa = Math.cos(a)
|
|
}
|
|
this.transformPrecalc(w, h, sina, cosa)
|
|
}
|
|
transformPrecalc(w, h, sina, cosa) {
|
|
const ptsArr = this._ptsArr;
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2) {
|
|
const j = i + 1;
|
|
const x = ptsArr[i] * w;
|
|
const y = ptsArr[j] * h;
|
|
ptsArr[i] = x * cosa - y * sina;
|
|
ptsArr[j] = y * cosa + x * sina
|
|
}
|
|
this._isBboxChanged = true
|
|
}
|
|
offset(x, y) {
|
|
const ptsArr = this._ptsArr;
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2) {
|
|
ptsArr[i] += x;
|
|
ptsArr[i + 1] += y
|
|
}
|
|
}
|
|
containsPoint(a2x, a2y) {
|
|
const ptsArr = this._ptsArr;
|
|
if (a2x === ptsArr[0] && a2y === ptsArr[1])
|
|
return true;
|
|
this._updateBbox();
|
|
const bbox = this._bbox;
|
|
const a1x = bbox.getLeft() - 110;
|
|
const a1y = bbox.getTop() - 101;
|
|
const a3x = bbox.getRight() + 131;
|
|
const a3y = bbox.getBottom() + 120;
|
|
let minAx12 = 0;
|
|
let minAy12 = 0;
|
|
let maxAx12 = 0;
|
|
let maxAy12 = 0;
|
|
let minAx32 = 0;
|
|
let minAy32 = 0;
|
|
let maxAx32 = 0;
|
|
let maxAy32 = 0;
|
|
if (a1x < a2x) {
|
|
minAx12 = a1x;
|
|
maxAx12 = a2x
|
|
} else {
|
|
minAx12 = a2x;
|
|
maxAx12 = a1x
|
|
}
|
|
if (a1y < a2y) {
|
|
minAy12 = a1y;
|
|
maxAy12 = a2y
|
|
} else {
|
|
minAy12 = a2y;
|
|
maxAy12 = a1y
|
|
}
|
|
if (a3x < a2x) {
|
|
minAx32 = a3x;
|
|
maxAx32 = a2x
|
|
} else {
|
|
minAx32 = a2x;
|
|
maxAx32 = a3x
|
|
}
|
|
if (a3y < a2y) {
|
|
minAy32 = a3y;
|
|
maxAy32 = a2y
|
|
} else {
|
|
minAy32 = a2y;
|
|
maxAy32 = a3y
|
|
}
|
|
let count1 = 0;
|
|
let count2 = 0;
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2) {
|
|
const j = (i + 2) % len;
|
|
const b1x = ptsArr[i];
|
|
const b1y = ptsArr[i + 1];
|
|
const b2x = ptsArr[j];
|
|
const b2y = ptsArr[j + 1];
|
|
if (C3.segmentsIntersectPreCalc(a1x, a1y, a2x, a2y, minAx12, maxAx12, minAy12, maxAy12, b1x, b1y, b2x, b2y))
|
|
++count1;
|
|
if (C3.segmentsIntersectPreCalc(a3x, a3y, a2x, a2y, minAx32, maxAx32, minAy32, maxAy32, b1x, b1y, b2x, b2y))
|
|
++count2
|
|
}
|
|
return count1 % 2 === 1 || count2 % 2 === 1
|
|
}
|
|
intersectsPoly(poly, offX, offY) {
|
|
const rPts = poly._ptsArr;
|
|
const lPts = this._ptsArr;
|
|
if (this.containsPoint(rPts[0] + offX, rPts[1] + offY))
|
|
return true;
|
|
if (poly.containsPoint(lPts[0] - offX, lPts[1] - offY))
|
|
return true;
|
|
for (let i = 0, leni = lPts.length; i < leni; i += 2) {
|
|
const j = (i + 2) % leni;
|
|
const a1x = lPts[i];
|
|
const a1y = lPts[i + 1];
|
|
const a2x = lPts[j];
|
|
const a2y = lPts[j + 1];
|
|
let minAx = 0;
|
|
let minAy = 0;
|
|
let maxAx = 0;
|
|
let maxAy = 0;
|
|
if (a1x < a2x) {
|
|
minAx = a1x;
|
|
maxAx = a2x
|
|
} else {
|
|
minAx = a2x;
|
|
maxAx = a1x
|
|
}
|
|
if (a1y < a2y) {
|
|
minAy = a1y;
|
|
maxAy = a2y
|
|
} else {
|
|
minAy = a2y;
|
|
maxAy = a1y
|
|
}
|
|
for (let k = 0, lenk = rPts.length; k < lenk; k += 2) {
|
|
const l = (k + 2) % lenk;
|
|
const b1x = rPts[k] + offX;
|
|
const b1y = rPts[k + 1] + offY;
|
|
const b2x = rPts[l] + offX;
|
|
const b2y = rPts[l + 1] + offY;
|
|
if (C3.segmentsIntersectPreCalc(a1x, a1y, a2x, a2y, minAx, maxAx, minAy, maxAy, b1x, b1y, b2x, b2y))
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
intersectsSegment(offX, offY, a1x, a1y, a2x, a2y) {
|
|
if (this.containsPoint(a1x - offX, a1y - offY))
|
|
return true;
|
|
if (this.containsPoint(a2x - offX, a2y - offY))
|
|
return true;
|
|
let minAx = 0;
|
|
let minAy = 0;
|
|
let maxAx = 0;
|
|
let maxAy = 0;
|
|
if (a1x < a2x) {
|
|
minAx = a1x;
|
|
maxAx = a2x
|
|
} else {
|
|
minAx = a2x;
|
|
maxAx = a1x
|
|
}
|
|
if (a1y < a2y) {
|
|
minAy = a1y;
|
|
maxAy = a2y
|
|
} else {
|
|
minAy = a2y;
|
|
maxAy = a1y
|
|
}
|
|
const ptsArr = this._ptsArr;
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2) {
|
|
const j = (i + 2) % len;
|
|
const b1x = ptsArr[i] + offX;
|
|
const b1y = ptsArr[i + 1] + offY;
|
|
const b2x = ptsArr[j] + offX;
|
|
const b2y = ptsArr[j + 1] + offY;
|
|
if (C3.segmentsIntersectPreCalc(a1x, a1y, a2x, a2y, minAx, maxAx, minAy, maxAy, b1x, b1y, b2x, b2y))
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
mirror(px) {
|
|
const ptsArr = this._ptsArr;
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2)
|
|
ptsArr[i] = px * 2 - ptsArr[i];
|
|
this._isBboxChanged = true
|
|
}
|
|
flip(py) {
|
|
const ptsArr = this._ptsArr;
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2) {
|
|
const j = i + 1;
|
|
ptsArr[j] = py * 2 - ptsArr[j]
|
|
}
|
|
this._isBboxChanged = true
|
|
}
|
|
diag() {
|
|
const ptsArr = this._ptsArr;
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2) {
|
|
const j = i + 1;
|
|
const temp = ptsArr[i];
|
|
ptsArr[i] = ptsArr[j];
|
|
ptsArr[j] = temp
|
|
}
|
|
this._isBboxChanged = true
|
|
}
|
|
GetMidX() {
|
|
const ptsArr = this._ptsArr;
|
|
let ret = 0;
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2)
|
|
ret += ptsArr[i];
|
|
return ret / this.pointCount()
|
|
}
|
|
GetMidY() {
|
|
const ptsArr = this._ptsArr;
|
|
let ret = 0;
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2)
|
|
ret += ptsArr[i + 1];
|
|
return ret / this.pointCount()
|
|
}
|
|
GetPointsArray() {
|
|
return this._ptsArr
|
|
}
|
|
GetPointCount() {
|
|
return this.pointCount()
|
|
}
|
|
IsEnabled() {
|
|
return this._enabled
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.PairMap = class PairMap extends C3.DefendedBase {
|
|
constructor(iterable) {
|
|
super();
|
|
this._firstMap = new Map;
|
|
if (iterable)
|
|
for (const [x,y,value] of iterable)
|
|
this.Set(x, y, value)
|
|
}
|
|
Release() {
|
|
this.Clear();
|
|
this._firstMap = null
|
|
}
|
|
Clear() {
|
|
const firstMap = this._firstMap;
|
|
for (const secondMap of firstMap.values())
|
|
secondMap.clear();
|
|
firstMap.clear()
|
|
}
|
|
Set(x, y, value) {
|
|
const firstMap = this._firstMap;
|
|
let secondMap = firstMap.get(x);
|
|
if (!secondMap) {
|
|
secondMap = new Map;
|
|
firstMap.set(x, secondMap)
|
|
}
|
|
secondMap.set(y, value)
|
|
}
|
|
Get(x, y) {
|
|
const secondMap = this._firstMap.get(x);
|
|
if (!secondMap)
|
|
return secondMap;
|
|
return secondMap.get(y)
|
|
}
|
|
Has(x, y) {
|
|
const secondMap = this._firstMap.get(x);
|
|
if (!secondMap)
|
|
return false;
|
|
return secondMap.has(y)
|
|
}
|
|
Delete(x, y) {
|
|
const firstMap = this._firstMap;
|
|
const secondMap = firstMap.get(x);
|
|
if (!secondMap)
|
|
return false;
|
|
const ret = secondMap.delete(y);
|
|
if (ret && secondMap.size === 0)
|
|
firstMap.delete(x);
|
|
return ret
|
|
}
|
|
DeleteEither(k) {
|
|
const firstMap = this._firstMap;
|
|
const secondMap = firstMap.get(k);
|
|
if (secondMap) {
|
|
secondMap.clear();
|
|
firstMap.delete(k)
|
|
}
|
|
for (const [x,secondMap] of firstMap.entries())
|
|
if (secondMap.delete(k) && secondMap.size === 0)
|
|
firstMap.delete(x)
|
|
}
|
|
GetSize() {
|
|
let ret = 0;
|
|
for (const secondMap of this._firstMap.values())
|
|
ret += secondMap.size;
|
|
return ret
|
|
}
|
|
*values() {
|
|
for (const secondMap of this._firstMap.values())
|
|
yield*secondMap.values()
|
|
}
|
|
*keyPairs() {
|
|
for (const [x,secondMap] of this._firstMap.entries())
|
|
for (const y of secondMap.keys())
|
|
yield[x, y]
|
|
}
|
|
*entries() {
|
|
for (const [x,secondMap] of this._firstMap.entries())
|
|
for (const [y,value] of secondMap.entries())
|
|
yield[x, y, value]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.ArraySet = class ArraySet extends C3.DefendedBase {
|
|
constructor() {
|
|
super();
|
|
this._set = new Set;
|
|
this._arr = [];
|
|
this._needToRebuildArray = false
|
|
}
|
|
Release() {
|
|
this.Clear()
|
|
}
|
|
Clear() {
|
|
this._set.clear();
|
|
C3.clearArray(this._arr);
|
|
this._needToRebuildArray = false
|
|
}
|
|
Add(v) {
|
|
if (this._set.has(v))
|
|
return;
|
|
this._set.add(v);
|
|
if (!this._needToRebuildArray)
|
|
this._arr.push(v)
|
|
}
|
|
Has(v) {
|
|
return this._set.has(v)
|
|
}
|
|
Delete(v) {
|
|
if (this._set.delete(v))
|
|
this._needToRebuildArray = true
|
|
}
|
|
GetSize() {
|
|
return this._set.size
|
|
}
|
|
IsEmpty() {
|
|
return this._set.size === 0
|
|
}
|
|
GetArray() {
|
|
if (this._needToRebuildArray) {
|
|
this._RebuildArray();
|
|
this._needToRebuildArray = false
|
|
}
|
|
return this._arr
|
|
}
|
|
_RebuildArray() {
|
|
const arr = this._arr;
|
|
C3.clearArray(arr);
|
|
for (const v of this._set)
|
|
arr.push(v)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const EASE_MAP = new Map;
|
|
const PREDEFINED_EASE_MAP = new Map;
|
|
const CUSTOM_EASE_EDITOR_MAP = new Map;
|
|
const CUSTOM_EASE_RUNTIME_MAP = new Map;
|
|
const PRIVATE_EASE_MAP = new Map;
|
|
const ALIAS_MAP = new Map;
|
|
ALIAS_MAP.set("linear", "noease");
|
|
ALIAS_MAP.set("default", "noease");
|
|
self.Ease = class Ease {
|
|
constructor() {}
|
|
static InheritEase() {
|
|
return "default"
|
|
}
|
|
static DefaultEase() {
|
|
return "noease"
|
|
}
|
|
static GetEditorEaseNames(project, ...filter) {
|
|
this._CreateEaseMap();
|
|
if (!CUSTOM_EASE_EDITOR_MAP.has(project))
|
|
CUSTOM_EASE_EDITOR_MAP.set(project, new Map);
|
|
const customEaseMap = CUSTOM_EASE_EDITOR_MAP.get(project);
|
|
return [...PREDEFINED_EASE_MAP.keys()].concat([...customEaseMap.keys()]).filter(ease=>!filter.includes(ease))
|
|
}
|
|
static GetRuntimeEaseNames() {
|
|
this._CreateEaseMap();
|
|
return [...PREDEFINED_EASE_MAP.keys()].concat([...CUSTOM_EASE_RUNTIME_MAP.keys()])
|
|
}
|
|
static IsNamePredefined(easeName) {
|
|
this._CreateEaseMap();
|
|
return [...PREDEFINED_EASE_MAP.keys()].includes(easeName)
|
|
}
|
|
static _GetEase(easeName) {
|
|
const realEaseName = ALIAS_MAP.get(easeName);
|
|
if (realEaseName)
|
|
return EASE_MAP.get(realEaseName);
|
|
if (Ease.IsNamePredefined(easeName))
|
|
return EASE_MAP.get(easeName);
|
|
if (PRIVATE_EASE_MAP.has(easeName))
|
|
return PRIVATE_EASE_MAP.get(easeName)
|
|
}
|
|
static GetEditorEase(easeName, project) {
|
|
this._CreateEaseMap();
|
|
const ease = Ease._GetEase(easeName);
|
|
if (ease)
|
|
return ease;
|
|
return CUSTOM_EASE_EDITOR_MAP.get(project).get(easeName)
|
|
}
|
|
static GetRuntimeEase(easeName) {
|
|
this._CreateEaseMap();
|
|
const ease = Ease._GetEase(easeName);
|
|
if (ease)
|
|
return ease;
|
|
return CUSTOM_EASE_RUNTIME_MAP.get(easeName)
|
|
}
|
|
static GetEaseFromIndex(index) {
|
|
this._CreateEaseMap();
|
|
const names = this.GetRuntimeEaseNames();
|
|
return names[index]
|
|
}
|
|
static GetIndexForEase(name, project) {
|
|
this._CreateEaseMap();
|
|
const names = this.GetEditorEaseNames(project);
|
|
return names.indexOf(name)
|
|
}
|
|
static _CreateEaseMap() {
|
|
if (EASE_MAP.size !== 0)
|
|
return;
|
|
this._AddPredifinedEase("default", ()=>{}
|
|
);
|
|
this._AddPredifinedEase("noease", this.NoEase);
|
|
this._AddPredifinedEase("easeinsine", this.EaseInSine);
|
|
this._AddPredifinedEase("easeoutsine", this.EaseOutSine);
|
|
this._AddPredifinedEase("easeinoutsine", this.EaseInOutSine);
|
|
this._AddPredifinedEase("easeinelastic", this.EaseInElastic);
|
|
this._AddPredifinedEase("easeoutelastic", this.EaseOutElastic);
|
|
this._AddPredifinedEase("easeinoutelastic", this.EaseInOutElastic);
|
|
this._AddPredifinedEase("easeinback", this.EaseInBack);
|
|
this._AddPredifinedEase("easeoutback", this.EaseOutBack);
|
|
this._AddPredifinedEase("easeinoutback", this.EaseInOutBack);
|
|
this._AddPredifinedEase("easeinbounce", this.EaseInBounce);
|
|
this._AddPredifinedEase("easeoutbounce", this.EaseOutBounce);
|
|
this._AddPredifinedEase("easeinoutbounce", this.EaseInOutBounce);
|
|
this._AddPredifinedEase("easeincubic", this.EaseInCubic);
|
|
this._AddPredifinedEase("easeoutcubic", this.EaseOutCubic);
|
|
this._AddPredifinedEase("easeinoutcubic", this.EaseInOutCubic);
|
|
this._AddPredifinedEase("easeinquad", this.EaseInQuad);
|
|
this._AddPredifinedEase("easeoutquad", this.EaseOutQuad);
|
|
this._AddPredifinedEase("easeinoutquad", this.EaseInOutQuad);
|
|
this._AddPredifinedEase("easeinquart", this.EaseInQuart);
|
|
this._AddPredifinedEase("easeoutquart", this.EaseOutQuart);
|
|
this._AddPredifinedEase("easeinoutquart", this.EaseInOutQuart);
|
|
this._AddPredifinedEase("easeinquint", this.EaseInQuint);
|
|
this._AddPredifinedEase("easeoutquint", this.EaseOutQuint);
|
|
this._AddPredifinedEase("easeinoutquint", this.EaseInOutQuint);
|
|
this._AddPredifinedEase("easeincirc", this.EaseInCirc);
|
|
this._AddPredifinedEase("easeoutcirc", this.EaseOutCirc);
|
|
this._AddPredifinedEase("easeinoutcirc", this.EaseInOutCirc);
|
|
this._AddPredifinedEase("easeinexpo", this.EaseInExpo);
|
|
this._AddPredifinedEase("easeoutexpo", this.EaseOutExpo);
|
|
this._AddPredifinedEase("easeinoutexpo", this.EaseInOutExpo);
|
|
this._AddPrivateCustomEase("cubicbezier", this.EaseCubicBezier);
|
|
this._AddPrivateCustomEase("spline", this.EaseSpline)
|
|
}
|
|
static _AddPredifinedEase(name, func) {
|
|
Ease._AddEase(name, func, "predefined")
|
|
}
|
|
static _AddPrivateCustomEase(name, func) {
|
|
Ease._AddEase(name, func, "private")
|
|
}
|
|
static AddCustomEase(name, func, project) {
|
|
this._CreateEaseMap();
|
|
Ease._AddEase(name, func, "custom", project)
|
|
}
|
|
static RemoveCustomEase(name, project) {
|
|
if (this.IsNamePredefined(name))
|
|
return;
|
|
if ([...PRIVATE_EASE_MAP.keys()].includes(name))
|
|
return;
|
|
const customEaseMap = CUSTOM_EASE_EDITOR_MAP.get(project);
|
|
if (customEaseMap)
|
|
customEaseMap.delete(name)
|
|
}
|
|
static _AddEase(name, func, mode, project) {
|
|
switch (mode) {
|
|
case "predefined":
|
|
EASE_MAP.set(name, func);
|
|
PREDEFINED_EASE_MAP.set(name, func);
|
|
break;
|
|
case "custom":
|
|
if (project) {
|
|
if (!CUSTOM_EASE_EDITOR_MAP.has(project))
|
|
CUSTOM_EASE_EDITOR_MAP.set(project, new Map);
|
|
const customEaseMap = CUSTOM_EASE_EDITOR_MAP.get(project);
|
|
customEaseMap.set(name, func)
|
|
} else
|
|
CUSTOM_EASE_RUNTIME_MAP.set(name, func);
|
|
break;
|
|
case "private":
|
|
EASE_MAP.set(name, func);
|
|
PRIVATE_EASE_MAP.set(name, func);
|
|
break;
|
|
default:
|
|
throw new Error("unexpected ease mode");
|
|
}
|
|
}
|
|
static NoEase(t, b, c, d) {
|
|
return c * t / d + b
|
|
}
|
|
static EaseInQuad(t, b, c, d) {
|
|
return c * (t /= d) * t + b
|
|
}
|
|
static EaseOutQuad(t, b, c, d) {
|
|
return -c * (t /= d) * (t - 2) + b
|
|
}
|
|
static EaseInOutQuad(t, b, c, d) {
|
|
if ((t /= d / 2) < 1)
|
|
return c / 2 * t * t + b;
|
|
return -c / 2 * (--t * (t - 2) - 1) + b
|
|
}
|
|
static EaseInCubic(t, b, c, d) {
|
|
return c * (t /= d) * t * t + b
|
|
}
|
|
static EaseOutCubic(t, b, c, d) {
|
|
return c * ((t = t / d - 1) * t * t + 1) + b
|
|
}
|
|
static EaseInOutCubic(t, b, c, d) {
|
|
if ((t /= d / 2) < 1)
|
|
return c / 2 * t * t * t + b;
|
|
return c / 2 * ((t -= 2) * t * t + 2) + b
|
|
}
|
|
static EaseInQuart(t, b, c, d) {
|
|
return c * (t /= d) * t * t * t + b
|
|
}
|
|
static EaseOutQuart(t, b, c, d) {
|
|
return -c * ((t = t / d - 1) * t * t * t - 1) + b
|
|
}
|
|
static EaseInOutQuart(t, b, c, d) {
|
|
if ((t /= d / 2) < 1)
|
|
return c / 2 * t * t * t * t + b;
|
|
return -c / 2 * ((t -= 2) * t * t * t - 2) + b
|
|
}
|
|
static EaseInQuint(t, b, c, d) {
|
|
return c * (t /= d) * t * t * t * t + b
|
|
}
|
|
static EaseOutQuint(t, b, c, d) {
|
|
return c * ((t = t / d - 1) * t * t * t * t + 1) + b
|
|
}
|
|
static EaseInOutQuint(t, b, c, d) {
|
|
if ((t /= d / 2) < 1)
|
|
return c / 2 * t * t * t * t * t + b;
|
|
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b
|
|
}
|
|
static EaseInSine(t, b, c, d) {
|
|
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b
|
|
}
|
|
static EaseOutSine(t, b, c, d) {
|
|
return c * Math.sin(t / d * (Math.PI / 2)) + b
|
|
}
|
|
static EaseInOutSine(t, b, c, d) {
|
|
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b
|
|
}
|
|
static EaseInExpo(t, b, c, d) {
|
|
return t === 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b
|
|
}
|
|
static EaseOutExpo(t, b, c, d) {
|
|
return t === d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b
|
|
}
|
|
static EaseInOutExpo(t, b, c, d) {
|
|
if (t === 0)
|
|
return b;
|
|
if (t === d)
|
|
return b + c;
|
|
if ((t /= d / 2) < 1)
|
|
return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
|
|
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b
|
|
}
|
|
static EaseInCirc(t, b, c, d) {
|
|
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b
|
|
}
|
|
static EaseOutCirc(t, b, c, d) {
|
|
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b
|
|
}
|
|
static EaseInOutCirc(t, b, c, d) {
|
|
if ((t /= d / 2) < 1)
|
|
return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
|
|
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b
|
|
}
|
|
static EaseInElastic(t, b, c, d) {
|
|
let s = 1.70158;
|
|
let p = 0;
|
|
let a = c;
|
|
if (t === 0)
|
|
return b;
|
|
if ((t /= d) === 1)
|
|
return b + c;
|
|
if (!p)
|
|
p = d * .3;
|
|
if (a < Math.abs(c)) {
|
|
a = c;
|
|
s = p / 4
|
|
} else
|
|
s = p / (2 * Math.PI) * Math.asin(c / a);
|
|
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b
|
|
}
|
|
static EaseOutElastic(t, b, c, d) {
|
|
let s = 1.70158;
|
|
let p = 0;
|
|
let a = c;
|
|
if (t === 0)
|
|
return b;
|
|
if ((t /= d) === 1)
|
|
return b + c;
|
|
if (!p)
|
|
p = d * .3;
|
|
if (a < Math.abs(c)) {
|
|
a = c;
|
|
s = p / 4
|
|
} else
|
|
s = p / (2 * Math.PI) * Math.asin(c / a);
|
|
return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b
|
|
}
|
|
static EaseInOutElastic(t, b, c, d) {
|
|
let s = 1.70158;
|
|
let p = 0;
|
|
let a = c;
|
|
if (t === 0)
|
|
return b;
|
|
if ((t /= d / 2) === 2)
|
|
return b + c;
|
|
if (!p)
|
|
p = d * (.3 * 1.5);
|
|
if (a < Math.abs(c)) {
|
|
a = c;
|
|
s = p / 4
|
|
} else
|
|
s = p / (2 * Math.PI) * Math.asin(c / a);
|
|
if (t < 1)
|
|
return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
|
|
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b
|
|
}
|
|
static EaseInBack(t, b, c, d, s) {
|
|
if (s === undefined)
|
|
s = 1.70158;
|
|
return c * (t /= d) * t * ((s + 1) * t - s) + b
|
|
}
|
|
static EaseOutBack(t, b, c, d, s) {
|
|
if (s === undefined)
|
|
s = 1.70158;
|
|
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b
|
|
}
|
|
static EaseInOutBack(t, b, c, d, s) {
|
|
if (s === undefined)
|
|
s = 1.70158;
|
|
if ((t /= d / 2) < 1)
|
|
return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b;
|
|
return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b
|
|
}
|
|
static EaseInBounce(t, b, c, d) {
|
|
return c - Ease.EaseOutBounce(d - t, 0, c, d) + b
|
|
}
|
|
static EaseOutBounce(t, b, c, d) {
|
|
if ((t /= d) < 1 / 2.75)
|
|
return c * (7.5625 * t * t) + b;
|
|
else if (t < 2 / 2.75)
|
|
return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b;
|
|
else if (t < 2.5 / 2.75)
|
|
return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b;
|
|
else
|
|
return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b
|
|
}
|
|
static EaseInOutBounce(t, b, c, d) {
|
|
if (t < d / 2)
|
|
return Ease.EaseInBounce(t * 2, 0, c, d) * .5 + b;
|
|
return Ease.EaseOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b
|
|
}
|
|
static EaseCubicBezier(t, p0, p1, p2, p3) {
|
|
const _0 = p0;
|
|
const _1 = 3 * t * (p1 - p0);
|
|
const _2 = 3 * t ** 2 * (p0 + p2 - 2 * p1);
|
|
const _3 = t ** 3 * (p3 - p0 + 3 * p1 - 3 * p2);
|
|
return _0 + _1 + _2 + _3
|
|
}
|
|
static EaseSpline(t, sx, sy, x1, y1, x2, y2, ex, ey, samples) {
|
|
if (x1 === y1 && x2 === y2)
|
|
return t;
|
|
const tx = get_t_for_x(t, sx, x1, x2, ex, samples);
|
|
const va = a(sy, y1, y2, ey);
|
|
const vb = b(sy, y1, y2, ey);
|
|
const vc = c(sy, y1, y2, ey);
|
|
return calc_bezier(tx, va, vb, vc)
|
|
}
|
|
static GetBezierSamples(startx, a1x, a2x, endx) {
|
|
const ret = [];
|
|
const va = a(startx, a1x, a2x, endx);
|
|
const vb = b(startx, a1x, a2x, endx);
|
|
const vc = c(startx, a1x, a2x, endx);
|
|
for (let i = 0; i < SAMPLE_COUNT; ++i) {
|
|
const sample = calc_bezier(i * SAMPLE_STEP, va, vb, vc);
|
|
ret.push(sample)
|
|
}
|
|
return ret
|
|
}
|
|
}
|
|
;
|
|
const SAMPLE_COUNT = 11;
|
|
const SAMPLE_STEP = 1 / (SAMPLE_COUNT - 1);
|
|
const NEWTON_RAPHSON_ITERATIONS = 4;
|
|
const NEWTON_RAPHSON_MIN_SLOPE = .02;
|
|
const SUBDIVISION_PRECISION = 1E-7;
|
|
const SUBDIVISION_MAX_ITERATIONS = 10;
|
|
const a = (p0,p1,p2,p3)=>{
|
|
return p3 - 3 * p2 + 3 * p1 - p0
|
|
}
|
|
;
|
|
const b = (p0,p1,p2,p3)=>{
|
|
return 3 * p2 - 6 * p1 + 3 * p0
|
|
}
|
|
;
|
|
const c = (p0,p1,p2,p3)=>{
|
|
return 3 * (p1 - p0)
|
|
}
|
|
;
|
|
const calc_bezier = (aT,a,b,c)=>{
|
|
return ((a * aT + b) * aT + c) * aT
|
|
}
|
|
;
|
|
const get_slope = (aT,a,b,c)=>{
|
|
return 3 * a * aT * aT + 2 * b * aT + c
|
|
}
|
|
;
|
|
const get_t_for_x = (aX,p0,p1,p2,p3,samples)=>{
|
|
if (aX == 1)
|
|
return 1;
|
|
let intervalStart = 0;
|
|
let currentSampleIndex = 1;
|
|
let currentSampleValue = samples[currentSampleIndex];
|
|
let lastSampleIndex = SAMPLE_COUNT - 1;
|
|
let lastSampleValue = samples[SAMPLE_COUNT - 1];
|
|
while (currentSampleIndex != lastSampleIndex && currentSampleValue <= aX) {
|
|
currentSampleIndex++;
|
|
currentSampleValue = samples[currentSampleIndex];
|
|
intervalStart += SAMPLE_STEP
|
|
}
|
|
currentSampleIndex--;
|
|
currentSampleValue = samples[currentSampleIndex];
|
|
const dist = (aX - currentSampleValue) / (samples[currentSampleIndex + 1] - currentSampleValue);
|
|
let guess = intervalStart + dist * SAMPLE_STEP;
|
|
const va = a(p0, p1, p2, p3);
|
|
const vb = b(p0, p1, p2, p3);
|
|
const vc = c(p0, p1, p2, p3);
|
|
const initSlope = get_slope(guess, va, vb, vc);
|
|
if (initSlope === 0)
|
|
return guess;
|
|
else if (initSlope >= NEWTON_RAPHSON_MIN_SLOPE) {
|
|
for (let i = 0; i < NEWTON_RAPHSON_ITERATIONS; ++i) {
|
|
const x = calc_bezier(guess, va, vb, vc) - aX;
|
|
const slope = get_slope(guess, va, vb, vc);
|
|
guess -= x / slope
|
|
}
|
|
return guess
|
|
} else {
|
|
let aA = intervalStart;
|
|
let aB = intervalStart + SAMPLE_STEP;
|
|
let i = 0;
|
|
let precissionLimit;
|
|
let maxIterations;
|
|
do {
|
|
guess = aA + (aB - aA) / 2;
|
|
let x = calc_bezier(guess, va, vb, vc) - aX;
|
|
if (x > 0)
|
|
aB = guess;
|
|
else
|
|
aA = guess;
|
|
precissionLimit = Math.abs(x) > SUBDIVISION_PRECISION;
|
|
maxIterations = ++i < SUBDIVISION_MAX_ITERATIONS
|
|
} while (precissionLimit && maxIterations);
|
|
return guess
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function RequireStringOrNumber(value) {
|
|
if (!C3.IsString(value))
|
|
;
|
|
}
|
|
C3.ProbabilityTable = class ProbabilityTable {
|
|
constructor() {
|
|
this._items = [];
|
|
this._totalWeight = 0
|
|
}
|
|
Release() {
|
|
this.Clear();
|
|
this._items = null
|
|
}
|
|
Clear() {
|
|
C3.clear2DArray(this._items);
|
|
this._totalWeight = 0
|
|
}
|
|
GetTotalWeight() {
|
|
return this._totalWeight
|
|
}
|
|
Sample(t=Math.random() * this.GetTotalWeight()) {
|
|
let sumWeight = 0;
|
|
for (const [weight,value] of this._items) {
|
|
sumWeight += weight;
|
|
if (t < sumWeight)
|
|
return value
|
|
}
|
|
return 0
|
|
}
|
|
AddItem(weight, value) {
|
|
RequireStringOrNumber(value);
|
|
this._totalWeight += weight;
|
|
this._items.push([weight, value])
|
|
}
|
|
RemoveItem(weight, value) {
|
|
RequireStringOrNumber(value);
|
|
const ignoreWeight = weight === 0;
|
|
for (let i = 0; i < this._items.length; i++) {
|
|
const item = this._items[i];
|
|
const doesWeightMatch = ignoreWeight || item[0] === weight;
|
|
const doesValueMatch = item[1] === value;
|
|
if (doesWeightMatch && doesValueMatch) {
|
|
this._items.splice(i, 1);
|
|
this._totalWeight -= item[0];
|
|
break
|
|
}
|
|
}
|
|
}
|
|
asJSON() {
|
|
return JSON.stringify(this._items)
|
|
}
|
|
static fromJSON(str) {
|
|
const table = new C3.ProbabilityTable;
|
|
const items = JSON.parse(str);
|
|
for (const item of items) {
|
|
const weight = item[0];
|
|
const value = item[1];
|
|
table.AddItem(weight, value)
|
|
}
|
|
return table
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Event = class Event {
|
|
constructor(type, cancelable) {
|
|
this.type = type;
|
|
this.cancelable = !!cancelable;
|
|
this.defaultPrevented = false;
|
|
this.propagationStopped = false;
|
|
this.isAsync = false
|
|
}
|
|
preventDefault() {
|
|
if (!this.cancelable)
|
|
throw new Error(`event '${this.type}' is not cancelable`);
|
|
this.defaultPrevented = true
|
|
}
|
|
stopPropagation() {
|
|
if (!this.cancelable)
|
|
throw new Error(`event '${this.type}' cannot be stopped`);
|
|
if (this.isAsync)
|
|
throw new Error(`cannot stop async event '${this.type}' propagation`);
|
|
this.propagationStopped = true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
C3.Event.Handler = class EventHandler extends C3.DefendedBase {
|
|
constructor(type) {
|
|
super();
|
|
this._type = type;
|
|
this._captureListeners = [];
|
|
this._captureListenersSet = new Set;
|
|
this._listeners = [];
|
|
this._listenersSet = new Set;
|
|
this._fireDepth = 0;
|
|
this._queueAddListeners = [];
|
|
this._queueRemoveCaptureListeners = [];
|
|
this._queueRemoveListeners = []
|
|
}
|
|
Release() {
|
|
if (this._fireDepth > 0)
|
|
return;
|
|
C3.clearArray(this._captureListeners);
|
|
this._captureListenersSet.clear();
|
|
C3.clearArray(this._listeners);
|
|
this._listenersSet.clear();
|
|
C3.clearArray(this._queueAddListeners);
|
|
C3.clearArray(this._queueRemoveCaptureListeners);
|
|
C3.clearArray(this._queueRemoveListeners);
|
|
C3.Release(this)
|
|
}
|
|
_AddListener(func, capture) {
|
|
if (this._IsFiring()) {
|
|
this._queueAddListeners.push([func, capture]);
|
|
return
|
|
}
|
|
if (capture) {
|
|
if (this._captureListenersSet.has(func))
|
|
return;
|
|
this._captureListeners.push(func);
|
|
this._captureListenersSet.add(func)
|
|
} else {
|
|
if (this._listenersSet.has(func))
|
|
return;
|
|
this._listeners.push(func);
|
|
this._listenersSet.add(func)
|
|
}
|
|
}
|
|
_RemoveListener(func, capture) {
|
|
if (this._IsFiring()) {
|
|
if (capture)
|
|
this._queueRemoveCaptureListeners.push(func);
|
|
else
|
|
this._queueRemoveListeners.push(func);
|
|
return
|
|
}
|
|
if (capture) {
|
|
if (this._captureListenersSet.has(func)) {
|
|
this._captureListenersSet.delete(func);
|
|
C3.arrayFindRemove(this._captureListeners, func)
|
|
}
|
|
} else if (this._listenersSet.has(func)) {
|
|
this._listenersSet.delete(func);
|
|
C3.arrayFindRemove(this._listeners, func)
|
|
}
|
|
}
|
|
_IsEmpty() {
|
|
return !this._captureListeners.length && !this._listeners.length
|
|
}
|
|
_IsFiring() {
|
|
return this._fireDepth > 0
|
|
}
|
|
_ProcessQueuedListeners() {
|
|
for (let q of this._queueAddListeners)
|
|
this._AddListener(...q);
|
|
C3.clearArray(this._queueAddListeners);
|
|
for (const func of this._queueRemoveListeners)
|
|
this._listenersSet.delete(func);
|
|
for (const func of this._queueRemoveCaptureListeners)
|
|
this._captureListenersSet.delete(func);
|
|
const removeListenersSet = new Set(this._queueRemoveListeners);
|
|
const removeCaptureListenersSet = new Set(this._queueRemoveCaptureListeners);
|
|
C3.arrayRemoveAllInSet(this._listeners, removeListenersSet);
|
|
C3.arrayRemoveAllInSet(this._captureListeners, removeCaptureListenersSet);
|
|
C3.clearArray(this._queueRemoveCaptureListeners);
|
|
C3.clearArray(this._queueRemoveListeners)
|
|
}
|
|
_FireCancellable(event) {
|
|
this._IncreaseFireDepth();
|
|
let isStopped = false;
|
|
for (let i = 0, len = this._captureListeners.length; i < len; ++i) {
|
|
this._captureListeners[i](event);
|
|
if (event.propagationStopped) {
|
|
isStopped = true;
|
|
break
|
|
}
|
|
}
|
|
if (!isStopped)
|
|
for (let i = 0, len = this._listeners.length; i < len; ++i) {
|
|
this._listeners[i](event);
|
|
if (event.propagationStopped)
|
|
break
|
|
}
|
|
this._DecreaseFireDepth();
|
|
return !event.defaultPrevented
|
|
}
|
|
_FireNonCancellable(event) {
|
|
this._IncreaseFireDepth();
|
|
for (let i = 0, len = this._captureListeners.length; i < len; ++i)
|
|
this._captureListeners[i](event);
|
|
for (let i = 0, len = this._listeners.length; i < len; ++i)
|
|
this._listeners[i](event);
|
|
this._DecreaseFireDepth();
|
|
return true
|
|
}
|
|
_IncreaseFireDepth() {
|
|
this._fireDepth++
|
|
}
|
|
_DecreaseFireDepth() {
|
|
this._fireDepth--;
|
|
if (this._fireDepth === 0 && (this._queueAddListeners.length || this._queueRemoveCaptureListeners.length || this._queueRemoveListeners.length))
|
|
this._ProcessQueuedListeners()
|
|
}
|
|
SetDelayRemoveEventsEnabled(e) {
|
|
if (e)
|
|
this._IncreaseFireDepth();
|
|
else
|
|
this._DecreaseFireDepth()
|
|
}
|
|
_FireAsync(event) {
|
|
let callbackPromises = [];
|
|
for (let i = 0, len = this._captureListeners.length; i < len; ++i) {
|
|
let func = this._captureListeners[i];
|
|
callbackPromises.push(C3.Asyncify(()=>func(event)))
|
|
}
|
|
for (let i = 0, len = this._listeners.length; i < len; ++i) {
|
|
let func = this._listeners[i];
|
|
callbackPromises.push(C3.Asyncify(()=>func(event)))
|
|
}
|
|
return Promise.all(callbackPromises).then(()=>!event.defaultPrevented)
|
|
}
|
|
_FireAndWait_AsyncOptional(event) {
|
|
const results = [];
|
|
this._IncreaseFireDepth();
|
|
for (let i = 0, len = this._captureListeners.length; i < len; ++i) {
|
|
const ret = this._captureListeners[i](event);
|
|
if (ret instanceof Promise)
|
|
results.push(ret)
|
|
}
|
|
for (let i = 0, len = this._listeners.length; i < len; ++i) {
|
|
const ret = this._listeners[i](event);
|
|
if (ret instanceof Promise)
|
|
results.push(ret)
|
|
}
|
|
this._DecreaseFireDepth();
|
|
if (results.length)
|
|
return Promise.all(results).then(()=>!event.defaultPrevented);
|
|
else
|
|
return !event.defaultPrevented
|
|
}
|
|
async _FireAndWaitAsync(event) {
|
|
return await this._FireAndWait_AsyncOptional(event)
|
|
}
|
|
async _FireAndWaitAsyncSequential(event) {
|
|
this._IncreaseFireDepth();
|
|
for (let i = 0, len = this._captureListeners.length; i < len; ++i) {
|
|
const ret = this._captureListeners[i](event);
|
|
if (ret instanceof Promise)
|
|
await ret
|
|
}
|
|
for (let i = 0, len = this._listeners.length; i < len; ++i) {
|
|
const ret = this._listeners[i](event);
|
|
if (ret instanceof Promise)
|
|
await ret
|
|
}
|
|
this._DecreaseFireDepth();
|
|
return !event.defaultPrevented
|
|
}
|
|
*_FireAsGenerator(event) {
|
|
this._IncreaseFireDepth();
|
|
for (let i = 0, len = this._captureListeners.length; i < len; ++i) {
|
|
const ret = this._captureListeners[i](event);
|
|
if (C3.IsIterator(ret))
|
|
yield*ret
|
|
}
|
|
for (let i = 0, len = this._listeners.length; i < len; ++i) {
|
|
const ret = this._listeners[i](event);
|
|
if (C3.IsIterator(ret))
|
|
yield*ret
|
|
}
|
|
this._DecreaseFireDepth()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Event.Dispatcher = class EventDispatcher extends C3.DefendedBase {
|
|
constructor() {
|
|
super();
|
|
this._eventHandlers = new Map;
|
|
this._dispatcherWasReleased = false
|
|
}
|
|
Release() {
|
|
if (this._dispatcherWasReleased)
|
|
throw new Error("already released");
|
|
this.ClearEvents();
|
|
this._dispatcherWasReleased = true;
|
|
C3.Release(this)
|
|
}
|
|
WasReleased() {
|
|
return this._dispatcherWasReleased
|
|
}
|
|
ClearEvents() {
|
|
for (let handler of this._eventHandlers.values())
|
|
handler.Release();
|
|
this._eventHandlers.clear()
|
|
}
|
|
_GetHandlerByType(type, create_if_missing) {
|
|
let handler = this._eventHandlers.get(type);
|
|
if (handler)
|
|
return handler;
|
|
if (create_if_missing) {
|
|
handler = C3.New(C3.Event.Handler, type);
|
|
this._eventHandlers.set(type, handler);
|
|
return handler
|
|
}
|
|
return null
|
|
}
|
|
HasAnyHandlerFor(type) {
|
|
return this._eventHandlers.has(type)
|
|
}
|
|
addEventListener(type, func, capture) {
|
|
let handler = this._GetHandlerByType(type, true);
|
|
handler._AddListener(func, !!capture)
|
|
}
|
|
removeEventListener(type, func, capture) {
|
|
let handler = this._GetHandlerByType(type, false);
|
|
if (!handler)
|
|
return;
|
|
handler._RemoveListener(func, !!capture);
|
|
if (handler._IsEmpty())
|
|
this._eventHandlers.delete(type)
|
|
}
|
|
dispatchEvent(event) {
|
|
const handler = this._GetHandlerByType(event.type, false);
|
|
if (!handler)
|
|
return true;
|
|
if (event.cancelable)
|
|
return handler._FireCancellable(event);
|
|
else
|
|
return handler._FireNonCancellable(event)
|
|
}
|
|
dispatchEventAsync(event) {
|
|
const handler = this._GetHandlerByType(event.type, false);
|
|
if (!handler)
|
|
return Promise.resolve(true);
|
|
event.isAsync = true;
|
|
return handler._FireAsync(event)
|
|
}
|
|
async dispatchEventAndClearAsync(event) {
|
|
const handler = this._GetHandlerByType(event.type, false);
|
|
if (!handler)
|
|
return true;
|
|
this._eventHandlers.delete(event.type);
|
|
event.isAsync = true;
|
|
const ret = await handler._FireAsync(event);
|
|
handler.Release();
|
|
return ret
|
|
}
|
|
async dispatchEventAndWaitAsync(event) {
|
|
const handler = this._GetHandlerByType(event.type, false);
|
|
if (!handler)
|
|
return true;
|
|
return await handler._FireAndWaitAsync(event)
|
|
}
|
|
dispatchEventAndWait_AsyncOptional(event) {
|
|
const handler = this._GetHandlerByType(event.type, false);
|
|
if (!handler)
|
|
return true;
|
|
return handler._FireAndWait_AsyncOptional(event)
|
|
}
|
|
async dispatchEventAndWaitAsyncSequential(event) {
|
|
const handler = this._GetHandlerByType(event.type, false);
|
|
if (!handler)
|
|
return true;
|
|
return await handler._FireAndWaitAsyncSequential(event)
|
|
}
|
|
dispatchGeneratorEvent(event) {
|
|
const handler = this._GetHandlerByType(event.type, false);
|
|
if (!handler)
|
|
return null;
|
|
if (event.cancelable)
|
|
throw new Error("not supported");
|
|
else
|
|
return handler._FireAsGenerator(event)
|
|
}
|
|
SetDelayRemoveEventsEnabled(e) {
|
|
for (const handler of this._eventHandlers.values())
|
|
handler.SetDelayRemoveEventsEnabled(e)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const SETTIMEOUT_WORK_DURATION = 12;
|
|
const SETTIMEOUT_INTERVAL = 16;
|
|
const IDLECALLBACK_TIMEOUT = 35;
|
|
const SUPPORTS_RIC = typeof requestIdleCallback !== "undefined";
|
|
let workQueue = [];
|
|
let callbackId = -1;
|
|
let highThroughputMode = 0;
|
|
function SetNewCallback(timerTimeout) {
|
|
if (SUPPORTS_RIC && highThroughputMode === 0)
|
|
callbackId = requestIdleCallback(DoAsyncifiedWork, {
|
|
timeout: IDLECALLBACK_TIMEOUT
|
|
});
|
|
else
|
|
callbackId = setTimeout(DoAsyncifiedWork, highThroughputMode > 0 ? 1 : timerTimeout)
|
|
}
|
|
function DoAsyncifiedWork(deadline) {
|
|
callbackId = -1;
|
|
if (!workQueue.length)
|
|
return;
|
|
let startTime = performance.now();
|
|
let curTime = startTime;
|
|
let jobCount = 0;
|
|
let estimatedNextJobDuration = 0;
|
|
do {
|
|
DoNextAsyncifiedJob(workQueue.shift());
|
|
curTime = performance.now();
|
|
++jobCount;
|
|
estimatedNextJobDuration = (curTime - startTime) / jobCount * 1.1
|
|
} while (workQueue.length && (SUPPORTS_RIC && highThroughputMode === 0 && typeof deadline !== "undefined" ? estimatedNextJobDuration < deadline["timeRemaining"]() : curTime - startTime + estimatedNextJobDuration < SETTIMEOUT_WORK_DURATION));
|
|
if (callbackId === -1 && workQueue.length) {
|
|
let workDuration = curTime - startTime;
|
|
let timeout = Math.max(SETTIMEOUT_INTERVAL - workDuration, 4);
|
|
SetNewCallback(timeout)
|
|
}
|
|
}
|
|
function DoNextAsyncifiedJob(w) {
|
|
let ret;
|
|
try {
|
|
ret = w.func()
|
|
} catch (e) {
|
|
w.reject(e);
|
|
return
|
|
}
|
|
w.resolve(ret)
|
|
}
|
|
let asyncifyDisabled = C3.QueryString.Has("disable-asyncify");
|
|
if (asyncifyDisabled)
|
|
console.warn("[Asyncify] Asyncify has been disabled due to disable-asyncify in the query string. Some work will now be done synchronously.");
|
|
C3.Asyncify = function Asyncify(func) {
|
|
let stack = null;
|
|
if (C3.isDebug)
|
|
stack = C3.GetCallStack();
|
|
return new Promise((resolve,reject)=>{
|
|
workQueue.push({
|
|
func: func,
|
|
resolve: resolve,
|
|
reject: reject,
|
|
stack: stack
|
|
});
|
|
if (asyncifyDisabled) {
|
|
DoNextAsyncifiedJob(workQueue.pop());
|
|
return
|
|
}
|
|
if (callbackId === -1)
|
|
SetNewCallback(SETTIMEOUT_INTERVAL)
|
|
}
|
|
)
|
|
}
|
|
;
|
|
C3.Asyncify.SetHighThroughputMode = function SetHighThroughputMode(m) {
|
|
if (m)
|
|
++highThroughputMode;
|
|
else {
|
|
--highThroughputMode;
|
|
if (highThroughputMode < 0)
|
|
throw new Error("already turned off high throughput mode");
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const IDLE_CHECK_MIN_INTERVAL = 1E3;
|
|
const IDLE_CHECK_TIMER_OVERSHOOT = 100;
|
|
let cachedNowTime = -1;
|
|
function ClearTimeCache() {
|
|
cachedNowTime = -1
|
|
}
|
|
C3.FastGetDateNow = function FastGetDateNow() {
|
|
if (cachedNowTime === -1) {
|
|
cachedNowTime = Date.now();
|
|
self.setTimeout(ClearTimeCache, 16)
|
|
}
|
|
return cachedNowTime
|
|
}
|
|
;
|
|
let timerId = -1;
|
|
let nextDeadline = -1;
|
|
let activeIdleTimeouts = new Set;
|
|
function CheckActiveIdleTimeouts() {
|
|
timerId = -1;
|
|
nextDeadline = -1;
|
|
let nowTime = Date.now();
|
|
for (let i of activeIdleTimeouts)
|
|
if (i._CheckTimeout(nowTime)) {
|
|
let deadline = i._GetDeadline();
|
|
if (nextDeadline === -1 || deadline < nextDeadline)
|
|
nextDeadline = deadline
|
|
} else
|
|
activeIdleTimeouts.delete(i);
|
|
if (nextDeadline !== -1) {
|
|
let duration = Math.max(nextDeadline - nowTime + IDLE_CHECK_TIMER_OVERSHOOT, IDLE_CHECK_MIN_INTERVAL);
|
|
timerId = self.setTimeout(CheckActiveIdleTimeouts, duration)
|
|
}
|
|
}
|
|
C3.IdleTimeout = class IdleTimeout {
|
|
constructor(callback, timeoutInSeconds) {
|
|
this._callback = callback;
|
|
this._timeout = timeoutInSeconds * 1E3;
|
|
this._deadline = 0;
|
|
this._isActive = false
|
|
}
|
|
Reset() {
|
|
let nowTime = C3.FastGetDateNow();
|
|
this._deadline = nowTime + this._timeout;
|
|
if (!this._isActive) {
|
|
activeIdleTimeouts.add(this);
|
|
this._isActive = true
|
|
}
|
|
if (timerId === -1) {
|
|
nextDeadline = this._deadline;
|
|
timerId = self.setTimeout(CheckActiveIdleTimeouts, this._timeout + IDLE_CHECK_TIMER_OVERSHOOT)
|
|
} else if (this._deadline < nextDeadline && nextDeadline > nowTime + IDLE_CHECK_MIN_INTERVAL) {
|
|
self.clearTimeout(timerId);
|
|
nextDeadline = this._deadline;
|
|
timerId = self.setTimeout(CheckActiveIdleTimeouts, this._timeout + IDLE_CHECK_TIMER_OVERSHOOT)
|
|
}
|
|
}
|
|
_CheckTimeout(nowTime) {
|
|
if (nowTime >= this._deadline) {
|
|
if (this._callback()) {
|
|
this._deadline = nowTime + this._timeout;
|
|
return true
|
|
}
|
|
this._isActive = false;
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
_GetDeadline() {
|
|
return this._deadline
|
|
}
|
|
Cancel() {
|
|
if (this._isActive) {
|
|
activeIdleTimeouts.delete(this);
|
|
this._isActive = false;
|
|
if (activeIdleTimeouts.size === 0 && timerId !== -1) {
|
|
self.clearTimeout(timerId);
|
|
timerId = -1;
|
|
nextDeadline = -1
|
|
}
|
|
}
|
|
}
|
|
Release() {
|
|
this.Cancel();
|
|
this._callback = null
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Disposable = class Disposable {
|
|
constructor(disposeAction) {
|
|
this._disposed = false;
|
|
this._disposeAction = disposeAction
|
|
}
|
|
Dispose() {
|
|
if (this._disposed)
|
|
return;
|
|
this._disposed = true;
|
|
if (this._disposeAction) {
|
|
this._disposeAction();
|
|
this._disposeAction = null
|
|
}
|
|
}
|
|
IsDisposed() {
|
|
return this._disposed
|
|
}
|
|
Release() {
|
|
this.Dispose()
|
|
}
|
|
static Release(instance) {
|
|
return new Disposable(()=>instance.Release())
|
|
}
|
|
static From(eventDispatcher, eventNames, eventHandler, opts, scope) {
|
|
if (typeof opts === "undefined" || opts === null)
|
|
opts = false;
|
|
else if (typeof opts !== "boolean" && typeof opts !== "object")
|
|
throw new TypeError("invalid event listener options");
|
|
if (scope)
|
|
eventHandler = eventHandler.bind(scope);
|
|
if (eventNames.includes(" ")) {
|
|
eventNames = eventNames.split(" ");
|
|
const disposable = new C3.CompositeDisposable;
|
|
for (let eventName of eventNames) {
|
|
eventDispatcher.addEventListener(eventName, eventHandler, opts);
|
|
disposable.Add(C3.New(C3.Disposable, ()=>eventDispatcher.removeEventListener(eventName, eventHandler, opts)))
|
|
}
|
|
return disposable
|
|
} else {
|
|
eventDispatcher.addEventListener(eventNames, eventHandler, opts);
|
|
return C3.New(C3.Disposable, ()=>eventDispatcher.removeEventListener(eventNames, eventHandler, opts))
|
|
}
|
|
}
|
|
}
|
|
;
|
|
C3.StubDisposable = class StubDisposable extends C3.Disposable {
|
|
SetAction(disposeAction) {
|
|
this._disposeAction = disposeAction
|
|
}
|
|
}
|
|
;
|
|
C3.CompositeDisposable = class CompositeDisposable extends C3.Disposable {
|
|
constructor(...disposables) {
|
|
super();
|
|
this._disposables = new Set;
|
|
for (let disposable of disposables)
|
|
this.Add(disposable)
|
|
}
|
|
Add(...disposables) {
|
|
if (this._disposed)
|
|
throw new Error("already disposed");
|
|
for (let disposable of disposables)
|
|
this._disposables.add(disposable)
|
|
}
|
|
Remove(disposable) {
|
|
if (this._disposed)
|
|
throw new Error("already disposed");
|
|
this._disposables.delete(disposable)
|
|
}
|
|
RemoveAll() {
|
|
if (this._disposed)
|
|
throw new Error("already disposed");
|
|
if (!this._disposables)
|
|
return;
|
|
for (let disposable of this._disposables)
|
|
disposable.Dispose();
|
|
this._disposables.clear()
|
|
}
|
|
IsDisposed() {
|
|
return this._disposed
|
|
}
|
|
Dispose() {
|
|
if (this._disposed)
|
|
throw new Error("already disposed");
|
|
this._disposed = true;
|
|
for (let disposable of this._disposables)
|
|
disposable.Dispose();
|
|
this._disposables.clear();
|
|
this._disposables = null
|
|
}
|
|
Release() {
|
|
this.Dispose()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.KahanSum = class KahanSum extends C3.DefendedBase {
|
|
constructor() {
|
|
super();
|
|
this._c = 0;
|
|
this._y = 0;
|
|
this._t = 0;
|
|
this._sum = 0
|
|
}
|
|
Add(v) {
|
|
v = +v;
|
|
this._y = v - this._c;
|
|
this._t = this._sum + this._y;
|
|
this._c = this._t - this._sum - this._y;
|
|
this._sum = this._t
|
|
}
|
|
Subtract(v) {
|
|
this._sum -= +v
|
|
}
|
|
Get() {
|
|
return this._sum
|
|
}
|
|
Reset() {
|
|
this._c = 0;
|
|
this._y = 0;
|
|
this._t = 0;
|
|
this._sum = 0
|
|
}
|
|
Set(s) {
|
|
this._c = 0;
|
|
this._y = 0;
|
|
this._t = 0;
|
|
this._sum = +s
|
|
}
|
|
Release() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const js_cols = {};
|
|
const RED = true;
|
|
const BLACK = false;
|
|
js_cols.RBnode = function(tree) {
|
|
this.tree = tree;
|
|
this.right = this.tree.sentinel;
|
|
this.left = this.tree.sentinel;
|
|
this.parent = null;
|
|
this.color = false;
|
|
this.key = null
|
|
}
|
|
;
|
|
js_cols.RedBlackSet = function(compare_func) {
|
|
this.size = 0;
|
|
this.sentinel = new js_cols.RBnode(this);
|
|
this.sentinel.color = BLACK;
|
|
this.root = this.sentinel;
|
|
this.root.parent = this.sentinel;
|
|
this.compare = compare_func || this.default_compare
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.default_compare = function(a, b) {
|
|
if (a < b)
|
|
return -1;
|
|
else if (b < a)
|
|
return 1;
|
|
else
|
|
return 0
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.clone = function() {
|
|
var rv = new js_cols.RedBlackSet(this.compare);
|
|
rv.insertAll(this);
|
|
return rv
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.clear = function() {
|
|
this.size = 0;
|
|
this.sentinel = new js_cols.RBnode(this);
|
|
this.sentinel.color = BLACK;
|
|
this.root = this.sentinel;
|
|
this.root.parent = this.sentinel
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.leftRotate = function(x) {
|
|
var y = x.right;
|
|
x.right = y.left;
|
|
if (y.left != this.sentinel)
|
|
y.left.parent = x;
|
|
y.parent = x.parent;
|
|
if (x.parent == this.sentinel)
|
|
this.root = y;
|
|
else if (x == x.parent.left)
|
|
x.parent.left = y;
|
|
else
|
|
x.parent.right = y;
|
|
y.left = x;
|
|
x.parent = y
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.rightRotate = function(x) {
|
|
var y = x.left;
|
|
x.left = y.right;
|
|
if (y.right != this.sentinel)
|
|
y.right.parent = x;
|
|
y.parent = x.parent;
|
|
if (x.parent == this.sentinel)
|
|
this.root = y;
|
|
else if (x == x.parent.right)
|
|
x.parent.right = y;
|
|
else
|
|
x.parent.left = y;
|
|
y.right = x;
|
|
x.parent = y
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.insert = function(key) {
|
|
if (!this.contains(key)) {
|
|
var z = new js_cols.RBnode(this);
|
|
z.key = key;
|
|
var y = this.sentinel;
|
|
var x = this.root;
|
|
while (x != this.sentinel) {
|
|
y = x;
|
|
if (this.compare(z.key, x.key) < 0)
|
|
x = x.left;
|
|
else
|
|
x = x.right
|
|
}
|
|
z.parent = y;
|
|
if (y == this.sentinel)
|
|
this.root = z;
|
|
else if (this.compare(z.key, y.key) < 0)
|
|
y.left = z;
|
|
else
|
|
y.right = z;
|
|
z.left = this.sentinel;
|
|
z.right = this.sentinel;
|
|
z.color = RED;
|
|
this.insertFixup(z);
|
|
this.size++
|
|
} else {
|
|
var node = this.get_(key);
|
|
node.key = key
|
|
}
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.insertFixup = function(z) {
|
|
while (z != this.sentinel && z != this.root && z.parent.color == RED)
|
|
if (z.parent == z.parent.parent.left) {
|
|
var y = z.parent.parent.right;
|
|
if (y.color == RED) {
|
|
z.parent.color = BLACK;
|
|
y.color = BLACK;
|
|
z.parent.parent.color = RED;
|
|
z = z.parent.parent
|
|
} else {
|
|
if (z == z.parent.right) {
|
|
z = z.parent;
|
|
this.leftRotate(z)
|
|
}
|
|
z.parent.color = BLACK;
|
|
z.parent.parent.color = RED;
|
|
if (z.parent.parent != this.sentinel)
|
|
this.rightRotate(z.parent.parent)
|
|
}
|
|
} else {
|
|
var y = z.parent.parent.left;
|
|
if (y.color == RED) {
|
|
z.parent.color = BLACK;
|
|
y.color = BLACK;
|
|
z.parent.parent.color = RED;
|
|
z = z.parent.parent
|
|
} else {
|
|
if (z == z.parent.left) {
|
|
z = z.parent;
|
|
this.rightRotate(z)
|
|
}
|
|
z.parent.color = BLACK;
|
|
z.parent.parent.color = RED;
|
|
if (z.parent.parent != this.sentinel)
|
|
this.leftRotate(z.parent.parent)
|
|
}
|
|
}
|
|
this.root.color = BLACK
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.delete_ = function(z) {
|
|
var y;
|
|
var x;
|
|
if (z.left == this.sentinel || z.right == this.sentinel)
|
|
y = z;
|
|
else
|
|
y = this.successor_(z);
|
|
if (y.left != this.sentinel)
|
|
x = y.left;
|
|
else
|
|
x = y.right;
|
|
x.parent = y.parent;
|
|
if (y.parent == this.sentinel)
|
|
this.root = x;
|
|
else if (y == y.parent.left)
|
|
y.parent.left = x;
|
|
else
|
|
y.parent.right = x;
|
|
if (y != z)
|
|
z.key = y.key;
|
|
if (y.color == BLACK)
|
|
this.deleteFixup(x);
|
|
this.size--
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.deleteFixup = function(x) {
|
|
while (x != this.root && x.color == BLACK)
|
|
if (x == x.parent.left) {
|
|
var w = x.parent.right;
|
|
if (w.color == RED) {
|
|
w.color = BLACK;
|
|
x.parent.color = RED;
|
|
this.leftRotate(x.parent);
|
|
w = x.parent.right
|
|
}
|
|
if (w.left.color == BLACK && w.right.color == BLACK) {
|
|
w.color = RED;
|
|
x = x.parent
|
|
} else {
|
|
if (w.right.color == BLACK) {
|
|
w.left.color = BLACK;
|
|
w.color = RED;
|
|
this.rightRotate(w);
|
|
w = x.parent.right
|
|
}
|
|
w.color = x.parent.color;
|
|
x.parent.color = BLACK;
|
|
w.right.color = BLACK;
|
|
this.leftRotate(x.parent);
|
|
x = this.root
|
|
}
|
|
} else {
|
|
var w = x.parent.left;
|
|
if (w.color == RED) {
|
|
w.color = BLACK;
|
|
x.parent.color = RED;
|
|
this.rightRotate(x.parent);
|
|
w = x.parent.left
|
|
}
|
|
if (w.right.color == BLACK && w.left.color == BLACK) {
|
|
w.color = RED;
|
|
x = x.parent
|
|
} else {
|
|
if (w.left.color == BLACK) {
|
|
w.right.color = BLACK;
|
|
w.color = RED;
|
|
this.leftRotate(w);
|
|
w = x.parent.left
|
|
}
|
|
w.color = x.parent.color;
|
|
x.parent.color = BLACK;
|
|
w.left.color = BLACK;
|
|
this.rightRotate(x.parent);
|
|
x = this.root
|
|
}
|
|
}
|
|
x.color = BLACK
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.remove = function(key) {
|
|
var x = this.get_(key);
|
|
if (x != this.sentinel) {
|
|
var retval = x.key;
|
|
this.delete_(x);
|
|
return retval
|
|
} else
|
|
return null
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.removeSwapped = function(value, key) {
|
|
this.remove(key)
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.min = function(x) {
|
|
while (x.left != this.sentinel)
|
|
x = x.left;
|
|
return x
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.max = function(x) {
|
|
while (x.right != this.sentinel)
|
|
x = x.right;
|
|
return x
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.successor_ = function(x) {
|
|
if (x.right != this.sentinel)
|
|
return this.min(x.right);
|
|
var y = x.parent;
|
|
while (y != this.sentinel && x == y.right) {
|
|
x = y;
|
|
y = y.parent
|
|
}
|
|
return y
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.predeccessor_ = function(x) {
|
|
if (x.left != this.sentinel)
|
|
return this.max(x.left);
|
|
var y = x.parent;
|
|
while (y != this.sentinel && x == y.left) {
|
|
x = y;
|
|
y = y.parent
|
|
}
|
|
return y
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.successor = function(key) {
|
|
if (this.size > 0) {
|
|
var x = this.get_(key);
|
|
if (x == this.sentinel)
|
|
return null;
|
|
if (x.right != this.sentinel)
|
|
return this.min(x.right).key;
|
|
var y = x.parent;
|
|
while (y != this.sentinel && x == y.right) {
|
|
x = y;
|
|
y = y.parent
|
|
}
|
|
if (y != this.sentinel)
|
|
return y.key;
|
|
else
|
|
return null
|
|
} else
|
|
return null
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.predecessor = function(key) {
|
|
if (this.size > 0) {
|
|
var x = this.get_(key);
|
|
if (x == this.sentinel)
|
|
return null;
|
|
if (x.left != this.sentinel)
|
|
return this.max(x.left).key;
|
|
var y = x.parent;
|
|
while (y != this.sentinel && x == y.left) {
|
|
x = y;
|
|
y = y.parent
|
|
}
|
|
if (y != this.sentinel)
|
|
return y.key;
|
|
else
|
|
return null
|
|
} else
|
|
return null
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.getMin = function() {
|
|
return this.min(this.root).key
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.getMax = function() {
|
|
return this.max(this.root).key
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.get_ = function(key) {
|
|
var x = this.root;
|
|
while (x != this.sentinel && this.compare(x.key, key) != 0)
|
|
if (this.compare(key, x.key) < 0)
|
|
x = x.left;
|
|
else
|
|
x = x.right;
|
|
return x
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.contains = function(key) {
|
|
return this.get_(key).key != null
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.getValues = function() {
|
|
var ret = [];
|
|
this.forEach(function(x) {
|
|
ret.push(x)
|
|
});
|
|
return ret
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.insertAll = function(col) {
|
|
if (js_cols.typeOf(col) == "array")
|
|
for (var i = 0; i < col.length; i++)
|
|
this.insert(col[i]);
|
|
else if (js_cols.typeOf(col.forEach) == "function")
|
|
col.forEach(this.insert, this);
|
|
else if (js_cols.typeOf(col.getValues) == "function") {
|
|
var arr = col.getValues();
|
|
for (var i = 0; i < arr.length; i++)
|
|
this.insert(arr[i])
|
|
} else if (js_cols.typeOf(col) == "object")
|
|
for (var key in col)
|
|
this.insert(col[key])
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.removeAll = function(col) {
|
|
if (js_cols.typeOf(col) == "array")
|
|
for (var i = 0; i < col.length; i++)
|
|
this.remove(col[i]);
|
|
else if (js_cols.typeOf(col.forEach) == "function")
|
|
col.forEach(this.removeSwapped, this);
|
|
else if (js_cols.typeOf(col.getValues) == "function") {
|
|
var arr = col.getValues();
|
|
for (var i = 0; i < arr.length; i++)
|
|
this.remove(arr[i])
|
|
} else if (js_cols.typeOf(col) == "object")
|
|
for (var key in col)
|
|
this.remove(col[key])
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.containsAll = function(col) {
|
|
if (js_cols.typeOf(col) == "array") {
|
|
for (var i = 0; i < col.length; i++)
|
|
if (!this.contains(col[i]))
|
|
return false;
|
|
return true
|
|
} else if (js_cols.typeOf(col.forEach) == "function")
|
|
return col.every(this.contains, this);
|
|
else if (js_cols.typeOf(col.getValues) == "function") {
|
|
var arr = col.getValues();
|
|
for (var i = 0; i < arr.length; i++)
|
|
if (!this.contains(arr[i]))
|
|
return false;
|
|
return true
|
|
} else if (js_cols.typeOf(col) == "object") {
|
|
for (var key in col)
|
|
if (!this.contains(col[key]))
|
|
return false;
|
|
return true
|
|
}
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.range = function(from, to) {
|
|
var retArray = [];
|
|
this.traverseFromTo(function(x) {
|
|
retArray.push(x)
|
|
}, from, to);
|
|
return retArray
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.traverse = function(f, opt_obj) {
|
|
if (this.isEmpty())
|
|
return;
|
|
var node = this.min(this.root);
|
|
while (node != this.sentinel) {
|
|
if (f.call(opt_obj, node.key, this))
|
|
return;
|
|
node = this.successor_(node)
|
|
}
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.traverseFrom = function(f, fromKey, opt_obj) {
|
|
if (this.isEmpty())
|
|
return;
|
|
var node = this.get_(fromKey);
|
|
while (node != this.sentinel) {
|
|
if (f.call(opt_obj, node.key, this))
|
|
return;
|
|
node = this.successor_(node)
|
|
}
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.traverseTo = function(f, toKey, opt_obj) {
|
|
if (this.isEmpty())
|
|
return;
|
|
var node = this.min(this.root);
|
|
var toNode = this.get_(toKey);
|
|
while (node != toNode) {
|
|
if (f.call(opt_obj, node.key, this))
|
|
return;
|
|
node = this.successor_(node)
|
|
}
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.traverseFromTo = function(f, fromKey, toKey, opt_obj) {
|
|
if (this.isEmpty())
|
|
return;
|
|
var node = this.get_(fromKey);
|
|
var toNode = this.get_(toKey);
|
|
while (node != toNode) {
|
|
if (f.call(opt_obj, node.key, this))
|
|
return;
|
|
node = this.successor_(node)
|
|
}
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.traverseBackwards = function(f, opt_obj) {
|
|
if (this.isEmpty())
|
|
return;
|
|
var node = this.max(this.root);
|
|
while (node != this.sentinel) {
|
|
if (f.call(opt_obj, node.key, this))
|
|
return;
|
|
node = this.predeccessor_(node)
|
|
}
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.forEach = function(f, opt_obj) {
|
|
if (this.isEmpty())
|
|
return;
|
|
for (var n = this.min(this.root); n != this.sentinel; n = this.successor_(n))
|
|
f.call(opt_obj, n.key, n.key, this)
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.some = function(f, opt_obj) {
|
|
if (this.isEmpty())
|
|
return false;
|
|
for (var n = this.min(this.root); n != this.sentinel; n = this.successor_(n))
|
|
if (f.call(opt_obj, n.key, n.key, this))
|
|
return true;
|
|
return false
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.every = function(f, opt_obj) {
|
|
if (this.isEmpty())
|
|
return false;
|
|
for (var n = this.min(this.root); n != this.sentinel; n = this.successor_(n))
|
|
if (!f.call(opt_obj, n.key, n.key, this))
|
|
return false;
|
|
return true
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.map = function(f, opt_obj) {
|
|
var rv = [];
|
|
if (this.isEmpty())
|
|
return rv;
|
|
for (var n = this.min(this.root); n != this.sentinel; n = this.successor_(n))
|
|
rv.push(f.call(opt_obj, n.key, n.key, this));
|
|
return rv
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.filter = function(f, opt_obj) {
|
|
var rv = [];
|
|
if (this.isEmpty())
|
|
return rv;
|
|
for (var n = this.min(this.root); n != this.sentinel; n = this.successor_(n))
|
|
if (f.call(opt_obj, n.key, n.key, this))
|
|
rv.push(n.key);
|
|
return rv
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.getCount = function() {
|
|
return this.size
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.isEmpty = function() {
|
|
return this.size == 0
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.isSubsetOf = function(col) {
|
|
var colCount = js_cols.getCount(col);
|
|
if (this.getCount() > colCount)
|
|
return false;
|
|
var i = 0;
|
|
if (this.isEmpty())
|
|
return true;
|
|
for (var n = this.min(this.root); n != this.sentinel; n = this.successor_(n))
|
|
if (js_cols.contains.call(col, col, n.key))
|
|
i++;
|
|
return i == this.getCount()
|
|
}
|
|
;
|
|
js_cols.RedBlackSet.prototype.intersection = function(col) {
|
|
var result = new js_cols.RedBlackSet(this.compare);
|
|
if (this.isEmpty())
|
|
return result;
|
|
for (var n = this.min(this.root); n != this.sentinel; n = this.successor_(n))
|
|
if (col.contains.call(col, n.key, n.key, this))
|
|
result.insert(n.key);
|
|
return result
|
|
}
|
|
;
|
|
C3.RedBlackSet = class RedBlackSet extends C3.DefendedBase {
|
|
constructor(sortFunc) {
|
|
super();
|
|
this._rbSet = new js_cols.RedBlackSet(sortFunc);
|
|
this._enableQueue = false;
|
|
this._queueInsert = new Set;
|
|
this._queueRemove = new Set
|
|
}
|
|
Add(item) {
|
|
if (this._enableQueue)
|
|
if (this._rbSet.contains(item))
|
|
this._queueRemove.delete(item);
|
|
else
|
|
this._queueInsert.add(item);
|
|
else
|
|
this._rbSet.insert(item)
|
|
}
|
|
Remove(item) {
|
|
if (this._enableQueue)
|
|
if (this._rbSet.contains(item))
|
|
this._queueRemove.add(item);
|
|
else
|
|
this._queueInsert.delete(item);
|
|
else
|
|
this._rbSet.remove(item)
|
|
}
|
|
Has(item) {
|
|
if (this._enableQueue) {
|
|
if (this._queueInsert.has(item))
|
|
return true;
|
|
return !this._queueRemove.has(item) && this._rbSet.contains(item)
|
|
} else
|
|
return this._rbSet.contains(item)
|
|
}
|
|
Clear() {
|
|
this._rbSet.clear();
|
|
this._queueInsert.clear();
|
|
this._queueRemove.clear()
|
|
}
|
|
toArray() {
|
|
if (this._enableQueue)
|
|
throw new Error("cannot be used in queueing mode");
|
|
return this._rbSet.getValues()
|
|
}
|
|
GetSize() {
|
|
return this._rbSet.getCount() + this._queueInsert.size - this._queueRemove.size
|
|
}
|
|
IsEmpty() {
|
|
return this.GetSize() === 0
|
|
}
|
|
Front() {
|
|
if (this.IsEmpty())
|
|
throw new Error("empty set");
|
|
if (this._enableQueue)
|
|
throw new Error("cannot be used in queueing mode");
|
|
const rbSet = this._rbSet;
|
|
const n = rbSet.min(rbSet.root);
|
|
return n.key
|
|
}
|
|
Shift() {
|
|
if (this.IsEmpty())
|
|
throw new Error("empty set");
|
|
if (this._enableQueue)
|
|
throw new Error("cannot be used in queueing mode");
|
|
const item = this.Front();
|
|
this.Remove(item);
|
|
return item
|
|
}
|
|
SetQueueingEnabled(q) {
|
|
q = !!q;
|
|
if (this._enableQueue === q)
|
|
return;
|
|
this._enableQueue = q;
|
|
if (!q) {
|
|
for (const item of this._queueRemove)
|
|
this._rbSet.remove(item);
|
|
this._queueRemove.clear();
|
|
for (const item of this._queueInsert)
|
|
this._rbSet.insert(item);
|
|
this._queueInsert.clear()
|
|
}
|
|
}
|
|
ForEach(func) {
|
|
this._rbSet.forEach(func)
|
|
}
|
|
*values() {
|
|
if (this.IsEmpty())
|
|
return;
|
|
const rbSet = this._rbSet;
|
|
for (let n = rbSet.min(rbSet.root); n != rbSet.sentinel; n = rbSet.successor_(n))
|
|
yield n.key
|
|
}
|
|
[Symbol.iterator]() {
|
|
return this.values()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.PromiseThrottle = class PromiseThrottle {
|
|
constructor(maxParallel=C3.hardwareConcurrency) {
|
|
this._maxParallel = maxParallel;
|
|
this._queue = [];
|
|
this._activeCount = 0
|
|
}
|
|
Add(func) {
|
|
return new Promise((resolve,reject)=>{
|
|
this._queue.push({
|
|
func,
|
|
resolve,
|
|
reject
|
|
});
|
|
this._MaybeStartNext()
|
|
}
|
|
)
|
|
}
|
|
_FindInQueue(func) {
|
|
for (let i = 0, len = this._queue.length; i < len; ++i)
|
|
if (this._queue[i].func === func)
|
|
return i;
|
|
return -1
|
|
}
|
|
RemoveAndResolve(func, value) {
|
|
const i = this._FindInQueue(func);
|
|
if (i === -1)
|
|
throw new Error("cannot find promise to resolve");
|
|
this._queue[i].resolve(value);
|
|
this._queue.splice(i, 1)
|
|
}
|
|
RemoveAndReject(func, value) {
|
|
const i = this._FindInQueue(func);
|
|
if (i === -1)
|
|
throw new Error("cannot find promise to reject");
|
|
this._queue[i].reject(value);
|
|
this._queue.splice(i, 1)
|
|
}
|
|
async _MaybeStartNext() {
|
|
if (!this._queue.length)
|
|
return;
|
|
if (this._activeCount >= this._maxParallel)
|
|
return;
|
|
this._activeCount++;
|
|
const job = this._queue.shift();
|
|
try {
|
|
const result = await job.func();
|
|
job.resolve(result)
|
|
} catch (err) {
|
|
job.reject(err)
|
|
}
|
|
this._activeCount--;
|
|
this._MaybeStartNext()
|
|
}
|
|
static async Batch(concurrency, methods) {
|
|
const results = [];
|
|
let failed = false;
|
|
const execute = async _=>{
|
|
let fn;
|
|
while (fn = methods.pop()) {
|
|
if (failed)
|
|
return;
|
|
try {
|
|
results.push(await fn())
|
|
} catch (e) {
|
|
failed = true;
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
;
|
|
const promises = [];
|
|
while (concurrency--)
|
|
promises.push(execute());
|
|
await Promise.all(promises);
|
|
return results
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.RateLimiter = class RateLimiter {
|
|
constructor(callback, interval, intervalOnBattery) {
|
|
this._callback = callback;
|
|
this._interval = interval;
|
|
this._intervalOnBattery = intervalOnBattery || interval * 2;
|
|
this._timerId = -1;
|
|
this._lastCallTime = -Infinity;
|
|
this._timerCallFunc = ()=>this._OnTimer();
|
|
this._ignoreReset = false;
|
|
this._canRunImmediate = false;
|
|
this._callbackArguments = null
|
|
}
|
|
SetCanRunImmediate(c) {
|
|
this._canRunImmediate = !!c
|
|
}
|
|
_GetInterval() {
|
|
if (typeof C3.Battery !== "undefined" && C3.Battery.IsOnBatteryPower())
|
|
return this._intervalOnBattery;
|
|
else
|
|
return this._interval
|
|
}
|
|
Call(...args) {
|
|
if (this._timerId !== -1)
|
|
return;
|
|
this._callbackArguments = args;
|
|
let nowTime = C3.FastGetDateNow();
|
|
let timeSinceLastCall = nowTime - this._lastCallTime;
|
|
let interval = this._GetInterval();
|
|
if (timeSinceLastCall >= interval && this._canRunImmediate) {
|
|
this._lastCallTime = nowTime;
|
|
this._RunCallback()
|
|
} else
|
|
this._timerId = self.setTimeout(this._timerCallFunc, Math.max(interval - timeSinceLastCall, 4))
|
|
}
|
|
_RunCallback() {
|
|
this._ignoreReset = true;
|
|
const args = this._callbackArguments;
|
|
this._callbackArguments = null;
|
|
if (args)
|
|
this._callback(...args);
|
|
else
|
|
this._callback();
|
|
this._ignoreReset = false
|
|
}
|
|
Reset() {
|
|
if (this._ignoreReset)
|
|
return;
|
|
this._CancelTimer();
|
|
this._callbackArguments = null;
|
|
this._lastCallTime = C3.FastGetDateNow()
|
|
}
|
|
_OnTimer() {
|
|
this._timerId = -1;
|
|
this._lastCallTime = C3.FastGetDateNow();
|
|
this._RunCallback()
|
|
}
|
|
_CancelTimer() {
|
|
if (this._timerId !== -1) {
|
|
self.clearTimeout(this._timerId);
|
|
this._timerId = -1
|
|
}
|
|
}
|
|
Release() {
|
|
this._CancelTimer();
|
|
this._callback = null;
|
|
this._callbackArguments = null;
|
|
this._timerCallFunc = null
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SVGRasterManager = class SVGRasterManager {
|
|
constructor() {
|
|
this._images = new Map;
|
|
this._allowNpotSurfaces = false;
|
|
this._getBaseSizeCallback = null;
|
|
this._rasterAtSizeCallback = null;
|
|
this._releaseResultCallback = null;
|
|
this._redrawCallback = null
|
|
}
|
|
SetNpotSurfaceAllowed(a) {
|
|
this._allowNpotSurfaces = !!a
|
|
}
|
|
IsNpotSurfaceAllowed() {
|
|
return this._allowNpotSurfaces
|
|
}
|
|
SetGetBaseSizeCallback(f) {
|
|
this._getBaseSizeCallback = f
|
|
}
|
|
GetBaseSize(dataSource) {
|
|
if (!this._getBaseSizeCallback)
|
|
throw new Error("no get base size callback set");
|
|
return this._getBaseSizeCallback(dataSource)
|
|
}
|
|
SetRasterAtSizeCallback(f) {
|
|
this._rasterAtSizeCallback = f
|
|
}
|
|
RasterAtSize(dataSource, context, surfaceWidth, surfaceHeight, imageWidth, imageHeight) {
|
|
if (!this._rasterAtSizeCallback)
|
|
throw new Error("no raster at size callback set");
|
|
return this._rasterAtSizeCallback(dataSource, context, surfaceWidth, surfaceHeight, imageWidth, imageHeight)
|
|
}
|
|
SetReleaseResultCallback(f) {
|
|
this._releaseResultCallback = f
|
|
}
|
|
ReleaseResult(rasterizedResult) {
|
|
if (!this._releaseResultCallback)
|
|
throw new Error("no release result callback set");
|
|
this._releaseResultCallback(rasterizedResult)
|
|
}
|
|
SetRedrawCallback(f) {
|
|
this._redrawCallback = f
|
|
}
|
|
Redraw() {
|
|
if (!this._redrawCallback)
|
|
throw new Error("no redraw callback set");
|
|
this._redrawCallback()
|
|
}
|
|
AddImage(dataSource) {
|
|
let ret = this._images.get(dataSource);
|
|
if (!ret) {
|
|
ret = C3.New(C3.SVGRasterImage, this, dataSource);
|
|
this._images.set(dataSource, ret)
|
|
}
|
|
ret.IncReference();
|
|
return ret
|
|
}
|
|
_RemoveImage(ri) {
|
|
this._images.delete(ri.GetDataSource())
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const MAX_SURFACE_SIZE = 2048;
|
|
C3.SVGRasterImage = class SVGRasterImage {
|
|
constructor(manager, dataSource) {
|
|
this._manager = manager;
|
|
this._dataSource = dataSource;
|
|
this._refCount = 0;
|
|
this._baseWidth = 0;
|
|
this._baseHeight = 0;
|
|
this._getBaseSizePromise = this._manager.GetBaseSize(dataSource).then(baseSize=>{
|
|
this._baseWidth = baseSize[0];
|
|
this._baseHeight = baseSize[1];
|
|
this._manager.Redraw()
|
|
}
|
|
).catch(err=>{
|
|
console.error("[SVG] Error loading SVG: ", err);
|
|
this._hadError = true;
|
|
this._manager.Redraw()
|
|
}
|
|
);
|
|
this._rasterSurfaceWidth = 0;
|
|
this._rasterSurfaceHeight = 0;
|
|
this._rasterImageWidth = 0;
|
|
this._rasterImageHeight = 0;
|
|
this._isRasterizing = false;
|
|
this._rasterizedResult = null;
|
|
this._forceRaster = false;
|
|
this._hadError = false
|
|
}
|
|
Release() {
|
|
if (this._refCount <= 0)
|
|
throw new Error("already released");
|
|
this._refCount--;
|
|
if (this._refCount === 0)
|
|
this._Release()
|
|
}
|
|
_Release() {
|
|
if (this._rasterizedResult) {
|
|
this._manager.ReleaseResult(this._rasterizedResult);
|
|
this._rasterizedResult = null
|
|
}
|
|
this._manager._RemoveImage(this);
|
|
this._manager = null
|
|
}
|
|
GetDataSource() {
|
|
return this._dataSource
|
|
}
|
|
IncReference() {
|
|
this._refCount++
|
|
}
|
|
HasReferences() {
|
|
return this._refCount > 0
|
|
}
|
|
GetRasterizedResult() {
|
|
return this._rasterizedResult
|
|
}
|
|
ForceRasterAgain() {
|
|
this._forceRaster = true
|
|
}
|
|
async StartRasterForSize(context, width, height) {
|
|
if (width === 0 || height === 0 || this._hadError)
|
|
return;
|
|
if (this._isRasterizing)
|
|
return;
|
|
let rasterSurfaceWidth = C3.nextHighestPowerOfTwo(Math.ceil(width));
|
|
let rasterSurfaceHeight = C3.nextHighestPowerOfTwo(Math.ceil(height));
|
|
const maxDim = Math.max(rasterSurfaceWidth, rasterSurfaceHeight);
|
|
if (maxDim > MAX_SURFACE_SIZE) {
|
|
const scale = MAX_SURFACE_SIZE / maxDim;
|
|
width *= scale;
|
|
height *= scale;
|
|
rasterSurfaceWidth = Math.min(Math.ceil(rasterSurfaceWidth * scale), MAX_SURFACE_SIZE);
|
|
rasterSurfaceHeight = Math.min(Math.ceil(rasterSurfaceHeight * scale), MAX_SURFACE_SIZE)
|
|
}
|
|
if (width < rasterSurfaceWidth && height < rasterSurfaceHeight) {
|
|
const imageAspectRatio = width / height;
|
|
const surfaceAspectRatio = rasterSurfaceWidth / rasterSurfaceHeight;
|
|
if (surfaceAspectRatio > imageAspectRatio) {
|
|
width = rasterSurfaceHeight * imageAspectRatio;
|
|
height = rasterSurfaceHeight
|
|
} else {
|
|
width = rasterSurfaceWidth;
|
|
height = rasterSurfaceWidth / imageAspectRatio
|
|
}
|
|
}
|
|
if (this._manager.IsNpotSurfaceAllowed()) {
|
|
rasterSurfaceWidth = Math.ceil(width);
|
|
rasterSurfaceHeight = Math.ceil(height)
|
|
}
|
|
if (rasterSurfaceWidth <= this._rasterSurfaceWidth && rasterSurfaceHeight <= this._rasterSurfaceHeight && !this._forceRaster)
|
|
return;
|
|
this._isRasterizing = true;
|
|
this._rasterSurfaceWidth = rasterSurfaceWidth;
|
|
this._rasterSurfaceHeight = rasterSurfaceHeight;
|
|
const newRasterizedResult = await this._manager.RasterAtSize(this._dataSource, context, this._rasterSurfaceWidth, this._rasterSurfaceHeight, width, height);
|
|
if (this._rasterizedResult)
|
|
this._manager.ReleaseResult(this._rasterizedResult);
|
|
this._rasterizedResult = newRasterizedResult;
|
|
this._rasterImageWidth = width;
|
|
this._rasterImageHeight = height;
|
|
this._isRasterizing = false;
|
|
this._forceRaster = false;
|
|
this._manager.Redraw()
|
|
}
|
|
WhenBaseSizeReady() {
|
|
return this._getBaseSizePromise
|
|
}
|
|
GetBaseWidth() {
|
|
return this._baseWidth
|
|
}
|
|
GetBaseHeight() {
|
|
return this._baseHeight
|
|
}
|
|
GetRasterWidth() {
|
|
return this._rasterImageWidth
|
|
}
|
|
GetRasterHeight() {
|
|
return this._rasterImageHeight
|
|
}
|
|
HadError() {
|
|
return this._hadError
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.UTF8_BOM = "\ufeff";
|
|
const NUMERIC_CHARS = new Set([..."0123456789"]);
|
|
C3.IsNumericChar = function IsNumericChar(c) {
|
|
return NUMERIC_CHARS.has(c)
|
|
}
|
|
;
|
|
const WHITESPACE_CHARS = new Set([..." \t\n\r\u00a0\u0085\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000"]);
|
|
C3.IsWhitespaceChar = function IsWhitespaceChar(c) {
|
|
return WHITESPACE_CHARS.has(c)
|
|
}
|
|
;
|
|
C3.FilterWhitespace = function FilterWhitespace(str) {
|
|
return [...str].filter(ch=>!C3.IsWhitespaceChar(ch)).join("")
|
|
}
|
|
;
|
|
C3.IsStringAllWhitespace = function IsStringAllWhitespace(str) {
|
|
for (const ch of str)
|
|
if (!C3.IsWhitespaceChar(ch))
|
|
return false;
|
|
return true
|
|
}
|
|
;
|
|
C3.IsUnprintableChar = function IsUnprintableChar(c) {
|
|
return c.length === 1 && c.charCodeAt(0) < 32
|
|
}
|
|
;
|
|
C3.FilterUnprintableChars = function FilterUnprintableChars(str) {
|
|
return [...str].filter(ch=>!C3.IsUnprintableChar(ch)).join("")
|
|
}
|
|
;
|
|
const NUMERIC_STRING_CHARS = new Set([..."0123456789.+-e"]);
|
|
C3.IsStringNumber = function IsStringNumber(str) {
|
|
str = str.trim();
|
|
if (!str.length)
|
|
return false;
|
|
let firstChar = str.charAt(0);
|
|
if (firstChar !== "-" && !NUMERIC_CHARS.has(firstChar))
|
|
return false;
|
|
for (let ch of str)
|
|
if (!NUMERIC_STRING_CHARS.has(ch))
|
|
return false;
|
|
return true
|
|
}
|
|
;
|
|
C3.RemoveTrailingDigits = function RemoveTrailingDigits(str) {
|
|
let i = str.length;
|
|
while (i > 0) {
|
|
let prev_ch = str.charAt(i - 1);
|
|
if (!C3.IsNumericChar(prev_ch))
|
|
break;
|
|
--i
|
|
}
|
|
return str.substr(0, i)
|
|
}
|
|
;
|
|
C3.IncrementNumberAtEndOf = function IncrementNumberAtEndOf(str) {
|
|
let baseStr = C3.RemoveTrailingDigits(str);
|
|
let numberStr = str.substr(baseStr.length);
|
|
if (numberStr)
|
|
numberStr = (parseInt(numberStr, 10) + 1).toString();
|
|
else
|
|
numberStr = "2";
|
|
return baseStr + numberStr
|
|
}
|
|
;
|
|
const HTML_ENTITY_MAP = new Map([["&", "&"], ["<", "<"], [">", ">"], ['"', """], ["'", "'"]]);
|
|
function lookupHtmlEntity(s) {
|
|
return HTML_ENTITY_MAP.get(s)
|
|
}
|
|
const HTML_ENTITY_REGEX = /[&<>"']/g;
|
|
C3.EscapeHTML = function EscapeHTML(str) {
|
|
return str.replace(HTML_ENTITY_REGEX, lookupHtmlEntity)
|
|
}
|
|
;
|
|
C3.EscapeJS = function EscapeJS(str) {
|
|
let ret = C3.ReplaceAll(str, "\\", "\\\\");
|
|
ret = C3.ReplaceAll(ret, '"', '\\"');
|
|
ret = C3.ReplaceAll(ret, "\t", "\\t");
|
|
ret = C3.ReplaceAll(ret, "\r", "");
|
|
return C3.ReplaceAll(ret, "\n", "\\n")
|
|
}
|
|
;
|
|
C3.EscapeXML = function EscapeXML(str) {
|
|
let ret = C3.ReplaceAll(str, "&", "&");
|
|
ret = C3.ReplaceAll(ret, "<", "<");
|
|
ret = C3.ReplaceAll(ret, ">", ">");
|
|
return C3.ReplaceAll(ret, '"', """)
|
|
}
|
|
;
|
|
const ESCAPE_REGEX = /[-[\]{}()*+?.,\\^$|#\s]/g;
|
|
C3.EscapeRegex = function EscapeRegex(str) {
|
|
return str.replace(ESCAPE_REGEX, "\\$&")
|
|
}
|
|
;
|
|
C3.FindAll = function FindAll(str, find, matchCase=false) {
|
|
if (!find)
|
|
return [];
|
|
if (!matchCase) {
|
|
str = str.toLowerCase();
|
|
find = find.toLowerCase()
|
|
}
|
|
const findLen = find.length;
|
|
let startIndex = 0;
|
|
let index = 0;
|
|
let ret = [];
|
|
while ((index = str.indexOf(find, startIndex)) > -1) {
|
|
ret.push(index);
|
|
startIndex = index + findLen
|
|
}
|
|
return ret
|
|
}
|
|
;
|
|
C3.ReplaceAll = function ReplaceAll(str, find, replace) {
|
|
return str.replaceAll(find, ()=>replace)
|
|
}
|
|
;
|
|
C3.ReplaceAllCaseInsensitive = function ReplaceAll(str, find, replace) {
|
|
return str.replace(new RegExp(C3.EscapeRegex(find),"gi"), ()=>replace)
|
|
}
|
|
;
|
|
C3.SetElementContent = function SetElementContent(elem, stringlike) {
|
|
if (typeof stringlike === "string")
|
|
elem.textContent = stringlike;
|
|
else if (stringlike.isPlainText())
|
|
elem.textContent = stringlike.toString();
|
|
else {
|
|
elem.innerHTML = stringlike.toHTML();
|
|
if (stringlike instanceof C3.BBString)
|
|
stringlike.attachLinkHandlers(elem)
|
|
}
|
|
}
|
|
;
|
|
C3.StringLikeEquals = function StringLikeEquals(a, b) {
|
|
if (a instanceof C3.HtmlString || a instanceof C3.BBString)
|
|
return a.equals(b);
|
|
else if (b instanceof C3.HtmlString || b instanceof C3.BBString)
|
|
return b.equals(a);
|
|
else
|
|
return a === b
|
|
}
|
|
;
|
|
C3.StringSubstitute = function StringSubstitute(str, ...arr) {
|
|
let ret = str;
|
|
for (let i = 0, len = arr.length; i < len; ++i) {
|
|
const sub = `{${i}}`;
|
|
if (!str.includes(sub))
|
|
throw new Error(`missing placeholder '${sub}' in string substitution`);
|
|
ret = ret.replace(sub, arr[i].toString())
|
|
}
|
|
return ret
|
|
}
|
|
;
|
|
C3.StringSubstituteAllowMissing = function StringSubstituteAllowMissing(str, ...arr) {
|
|
let ret = str;
|
|
let lowestMissingIndex = -1;
|
|
let highestUsedIndex = -1;
|
|
for (let i = 0, len = arr.length; i < len; ++i) {
|
|
const sub = `{${i}}`;
|
|
if (str.includes(sub)) {
|
|
highestUsedIndex = i;
|
|
ret = ret.replace(sub, arr[i].toString())
|
|
} else if (lowestMissingIndex === -1)
|
|
lowestMissingIndex = i
|
|
}
|
|
if (lowestMissingIndex >= 0 && highestUsedIndex >= 0 && lowestMissingIndex < highestUsedIndex)
|
|
throw new Error(`missing placeholder '${lowestMissingIndex}' in string substitution`);
|
|
return ret
|
|
}
|
|
;
|
|
C3.StringSubstituteMap = function StringSubstituteMap(str, o) {
|
|
let ret = str;
|
|
for (let[placeholder,substitution] of Object.entries(o))
|
|
ret = ret.replaceAll(placeholder, substitution.toString());
|
|
return ret
|
|
}
|
|
;
|
|
C3.SortAZCaseInsensitive = function SortAZCaseInsensitive(a, b) {
|
|
let lowerA = a.toLowerCase();
|
|
let lowerB = b.toLowerCase();
|
|
if (lowerA > lowerB)
|
|
return 1;
|
|
else if (lowerA < lowerB)
|
|
return -1;
|
|
else
|
|
return 0
|
|
}
|
|
;
|
|
const KILOBYTE = 1024;
|
|
const MEGABYTE = KILOBYTE * 1024;
|
|
const GIGABYTE = MEGABYTE * 1024;
|
|
const TERABYTE = GIGABYTE * 1024;
|
|
C3.FormatDataSize = function FormatDataSize(sizeInBytes, asRate) {
|
|
let rootKey = "common." + (asRate ? "dataRates" : "dataSizes") + ".";
|
|
const langSub = self.langSub;
|
|
if (sizeInBytes < KILOBYTE)
|
|
return langSub(rootKey + "bytes", sizeInBytes);
|
|
else if (sizeInBytes < MEGABYTE) {
|
|
let kb = sizeInBytes / KILOBYTE;
|
|
if (kb < 10)
|
|
kb = Math.round(kb * 10) / 10;
|
|
else
|
|
kb = Math.round(kb);
|
|
return langSub(rootKey + "kilobytes", kb)
|
|
} else if (sizeInBytes < GIGABYTE) {
|
|
let mb = sizeInBytes / MEGABYTE;
|
|
if (mb < 10)
|
|
mb = Math.round(mb * 10) / 10;
|
|
else
|
|
mb = Math.round(mb);
|
|
return langSub(rootKey + "megabytes", mb)
|
|
} else if (sizeInBytes < TERABYTE) {
|
|
let gb = sizeInBytes / GIGABYTE;
|
|
if (gb < 10)
|
|
gb = Math.round(gb * 10) / 10;
|
|
else
|
|
gb = Math.round(gb);
|
|
return langSub(rootKey + "gigabytes", gb)
|
|
} else {
|
|
let tb = sizeInBytes / TERABYTE;
|
|
if (tb < 10)
|
|
tb = Math.round(tb * 10) / 10;
|
|
else
|
|
tb = Math.round(tb);
|
|
return langSub(rootKey + "terabytes", tb)
|
|
}
|
|
}
|
|
;
|
|
const DEFAULT_FORMATTIME_OPTS = {
|
|
approximate: false,
|
|
days: true,
|
|
hours: true,
|
|
minutes: true,
|
|
seconds: true
|
|
};
|
|
C3.FormatTime = function FormatTime(secondsTotal, opts) {
|
|
opts = Object.assign({}, DEFAULT_FORMATTIME_OPTS, opts);
|
|
C3.Lang.PushContext("common.time");
|
|
const parts = [];
|
|
const lang = self.lang;
|
|
const langPluralSub = self.langPluralSub;
|
|
if (opts.days) {
|
|
const days = Math.floor(secondsTotal / (24 * 3600));
|
|
if (days > 0) {
|
|
secondsTotal -= days * 24 * 3600;
|
|
parts.push(langPluralSub(".days", null, days))
|
|
}
|
|
}
|
|
if (opts.hours) {
|
|
const hours = Math.floor(secondsTotal / 3600);
|
|
if (hours > 0 || parts.length) {
|
|
secondsTotal -= hours * 3600;
|
|
parts.push(langPluralSub(".hours", null, hours))
|
|
}
|
|
}
|
|
if (opts.minutes) {
|
|
const minutes = Math.floor(secondsTotal / 60);
|
|
if (minutes > 0 || parts.length || !opts.seconds) {
|
|
secondsTotal -= minutes * 60;
|
|
parts.push(langPluralSub(".minutes", null, minutes))
|
|
}
|
|
}
|
|
if (opts.seconds) {
|
|
const seconds = Math.floor(secondsTotal % 60);
|
|
parts.push(langPluralSub(".seconds", null, seconds))
|
|
}
|
|
const ret = (opts.approximate ? lang(".approx-prefix") : "") + parts.join(lang(".separator"));
|
|
C3.Lang.PopContext();
|
|
return ret
|
|
}
|
|
;
|
|
C3.ZeroPad = function(n, d) {
|
|
let s = n < 0 ? "-" : "";
|
|
n = Math.abs(n);
|
|
let nStr = n.toString();
|
|
let zeroes = d - nStr.length;
|
|
for (let i = 0; i < zeroes; ++i)
|
|
s += "0";
|
|
return s + nStr
|
|
}
|
|
;
|
|
C3.StringToTitleCase = function StringToTitleCase(str) {
|
|
return str.toLowerCase().replace(/\b\w/g, t=>t.toUpperCase())
|
|
}
|
|
;
|
|
C3.CompareVersionStrings = function CompareVersionStrings(v1, v2) {
|
|
let a1 = v1.split(".").map(s=>s.trim());
|
|
let a2 = v2.split(".").map(s=>s.trim());
|
|
C3.resizeArray(a1, 4, "0");
|
|
C3.resizeArray(a2, 4, "0");
|
|
a1 = a1.map(s=>parseInt(s, 10));
|
|
a2 = a2.map(s=>parseInt(s, 10));
|
|
for (let i = 0; i < 4; ++i) {
|
|
const diff = a1[i] - a2[i];
|
|
if (diff !== 0)
|
|
return diff < 0 ? -1 : 1
|
|
}
|
|
return 0
|
|
}
|
|
;
|
|
C3.CreateGUID = function CreateGUID() {
|
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c=>{
|
|
const r = Math.floor(Math.random() * 16);
|
|
const v = c === "x" ? r : r & 3 | 8;
|
|
return v.toString(16)
|
|
}
|
|
)
|
|
}
|
|
;
|
|
C3.StringHammingDistance = function StringHammingDistance(a, b) {
|
|
if (a.length !== b.length)
|
|
throw new Error("strings must be same length");
|
|
let ret = 0;
|
|
for (let i = 0, len = a.length; i < len; ++i)
|
|
if (a.charAt(i) !== b.charAt(i))
|
|
++ret;
|
|
return ret
|
|
}
|
|
;
|
|
C3.StringLevenshteinDistance = function StringLevenshteinDistance(a, b) {
|
|
if (a.length === 0)
|
|
return b.length;
|
|
if (b.length === 0)
|
|
return a.length;
|
|
let tmp, i, j, prev, val, row;
|
|
if (a.length > b.length) {
|
|
tmp = a;
|
|
a = b;
|
|
b = tmp
|
|
}
|
|
row = Array(a.length + 1);
|
|
for (i = 0; i <= a.length; i++)
|
|
row[i] = i;
|
|
for (i = 1; i <= b.length; i++) {
|
|
prev = i;
|
|
for (j = 1; j <= a.length; j++) {
|
|
if (b[i - 1] === a[j - 1])
|
|
val = row[j - 1];
|
|
else
|
|
val = Math.min(row[j - 1] + 1, Math.min(prev + 1, row[j] + 1));
|
|
row[j - 1] = prev;
|
|
prev = val
|
|
}
|
|
row[a.length] = prev
|
|
}
|
|
return row[a.length]
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
const BB_CODE_MAP = new Map([["b", "strong"], ["i", "em"], ["s", "s"], ["u", "u"], ["sub", "sub"], ["sup", "sup"], ["small", "small"], ["mark", "mark"], ["a1", "a"], ["a2", "a"], ["a3", "a"], ["a4", "a"], ["a5", "a"], ["a6", "a"], ["a7", "a"], ["a8", "a"], ["a9", "a"], ["bad", ["span", "bbCodeBad"]], ["good", ["span", "bbCodeGood"]], ["info", ["span", "bbCodeInfo"]], ["h1", ["span", "bbCodeH1"]], ["h2", ["span", "bbCodeH2"]], ["h3", ["span", "bbCodeH3"]], ["h4", ["span", "bbCodeH4"]], ["item", ["span", "bbCodeItem"]]]);
|
|
const BBREGEX = /\[(\/?)([a-zA-Z0-9]+)\]/g;
|
|
const CUSTOM_BBREGEX = /\[(\/?)([^\[]*?)\]/g;
|
|
let linkActions = null;
|
|
let classIndex = 0;
|
|
function bbToHtmlReplacerFunc(match, closeSlash, tagName) {
|
|
const entry = BB_CODE_MAP.get(tagName);
|
|
if (entry)
|
|
if (typeof entry === "string")
|
|
if (entry === "a" && !closeSlash) {
|
|
const index = parseInt(tagName.substring(1), 10) - 1;
|
|
if (index < 0 || index >= linkActions.length)
|
|
throw new Error("invalid bbcode link substitution");
|
|
const linkAction = linkActions[index];
|
|
if (typeof linkAction === "string")
|
|
return `<a href="${linkActions[index]}">`;
|
|
else if (typeof linkAction === "function")
|
|
return `<a class="bblink${index}">`;
|
|
else
|
|
throw new TypeError("invalid bbcode link action");
|
|
} else
|
|
return "<" + closeSlash + entry + ">";
|
|
else if (Array.isArray(entry)) {
|
|
let tag = entry[0];
|
|
let className = entry[1];
|
|
if (closeSlash)
|
|
return "</" + tag + ">";
|
|
else
|
|
return `<${tag} class="${className}">`
|
|
} else
|
|
;
|
|
else if (tagName === "class")
|
|
if (closeSlash)
|
|
return "</span>";
|
|
else
|
|
return `<span class="bbclass${classIndex++}">`;
|
|
else
|
|
return match
|
|
}
|
|
const LINEBREAK_REGEX = /\n/g;
|
|
C3.BBString = class BBString {
|
|
constructor(str, opts) {
|
|
this._bbstr = opts && opts.noEscape ? str : C3.EscapeHTML(str);
|
|
this._htmlstr = "";
|
|
this._convertLineBreaks = false;
|
|
this._linkActions = [];
|
|
if (opts) {
|
|
this._convertLineBreaks = !!opts.convertLineBreaks;
|
|
if (opts.links) {
|
|
if (opts.links.length > 9)
|
|
throw new Error("too many links");
|
|
this._linkActions = opts.links
|
|
}
|
|
}
|
|
this._hasAnyBBtags = this._bbstr.includes("[");
|
|
this._needsLineBreakConversion = this._convertLineBreaks && this._bbstr.includes("\n");
|
|
this._isPlain = !this._hasAnyBBtags && !this._needsLineBreakConversion && !this._bbstr.includes("&");
|
|
this._hasParsedFragments = false;
|
|
this._fragments = []
|
|
}
|
|
toString() {
|
|
return this._bbstr
|
|
}
|
|
valueOf() {
|
|
return this._bbstr
|
|
}
|
|
isPlainText() {
|
|
return this._isPlain
|
|
}
|
|
toPlainText() {
|
|
if (this._hasAnyBBtags)
|
|
return this._bbstr.replace(BBREGEX, "");
|
|
else
|
|
return this._bbstr
|
|
}
|
|
toHTML() {
|
|
if (this._isPlain)
|
|
return this._bbstr;
|
|
if (!this._htmlstr && this._bbstr) {
|
|
let str = this._bbstr;
|
|
if (this._hasAnyBBtags) {
|
|
classIndex = 0;
|
|
linkActions = this._linkActions;
|
|
str = str.replace(BBREGEX, bbToHtmlReplacerFunc);
|
|
linkActions = null
|
|
}
|
|
if (this._needsLineBreakConversion)
|
|
str = str.replace(LINEBREAK_REGEX, "<br>");
|
|
this._htmlstr = str
|
|
}
|
|
return this._htmlstr
|
|
}
|
|
attachLinkHandlers(parentElem) {
|
|
if (!this._linkActions.length)
|
|
return;
|
|
for (let i = 0, len = this._linkActions.length; i < len; ++i) {
|
|
const linkAction = this._linkActions[i];
|
|
if (typeof linkAction !== "function")
|
|
continue;
|
|
const linkElem = parentElem.querySelector(".bblink" + i);
|
|
if (!linkElem)
|
|
throw new Error("unable to attach BBString link handler");
|
|
linkElem.onclick = linkAction
|
|
}
|
|
}
|
|
equals(s) {
|
|
if (s instanceof C3.HtmlString)
|
|
return this.toHTML() === s.toHTML();
|
|
else if (s instanceof C3.BBString)
|
|
return this._bbstr === s._bbstr;
|
|
else
|
|
return this._bbstr === s
|
|
}
|
|
toFragmentList() {
|
|
if (this._hasParsedFragments)
|
|
return this._fragments;
|
|
const bbStr = this._bbstr;
|
|
const styleStack = [];
|
|
CUSTOM_BBREGEX.lastIndex = 0;
|
|
let prevIndex = 0;
|
|
let result = null;
|
|
while ((result = CUSTOM_BBREGEX.exec(bbStr)) !== null) {
|
|
const index = result.index;
|
|
if (index > 0 && bbStr.charAt(index - 1) === "\\")
|
|
continue;
|
|
const matchStr = result[0];
|
|
const closeSlash = result[1];
|
|
const tagName = result[2];
|
|
const strFrag = bbStr.substring(prevIndex, index);
|
|
prevIndex = index + matchStr.length;
|
|
if (strFrag)
|
|
this._fragments.push({
|
|
text: strFrag,
|
|
styles: styleStack.slice(0)
|
|
});
|
|
if (!tagName)
|
|
continue;
|
|
if (closeSlash) {
|
|
const lowerTagName = tagName.toLowerCase();
|
|
for (let i = styleStack.length - 1; i >= 0; --i)
|
|
if (styleStack[i].tag === lowerTagName) {
|
|
styleStack.splice(i, 1);
|
|
break
|
|
}
|
|
} else {
|
|
let tag = tagName;
|
|
let param = null;
|
|
const eq = tagName.indexOf("=");
|
|
if (eq !== -1) {
|
|
tag = tagName.substring(0, eq).toLowerCase();
|
|
param = tagName.substring(eq + 1)
|
|
} else
|
|
tag = tag.toLowerCase();
|
|
styleStack.push({
|
|
tag,
|
|
param
|
|
})
|
|
}
|
|
}
|
|
if (prevIndex < bbStr.length)
|
|
this._fragments.push({
|
|
text: bbStr.substring(prevIndex),
|
|
styles: styleStack.slice(0)
|
|
});
|
|
for (const frag of this._fragments)
|
|
frag.text = this._ProcessBBCodeEscapeSequences(frag.text);
|
|
this._hasParsedFragments = true;
|
|
return this._fragments
|
|
}
|
|
_ProcessBBCodeEscapeSequences(text) {
|
|
text = C3.ReplaceAll(text, "\\[", "[");
|
|
return C3.ReplaceAll(text, "\\\\", "\\")
|
|
}
|
|
static StripTags(str) {
|
|
return C3.New(C3.BBString, str, {
|
|
noEscape: true
|
|
}).toPlainText()
|
|
}
|
|
static StripAnyTags(str) {
|
|
return str.replace(CUSTOM_BBREGEX, "")
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.WordWrap = class WordWrap {
|
|
constructor() {
|
|
this._lines = []
|
|
}
|
|
GetLines() {
|
|
return this._lines
|
|
}
|
|
GetLineCount() {
|
|
return this._lines.length
|
|
}
|
|
_MeasureLine(line, measureFunc) {
|
|
let width = 0;
|
|
let height = 0;
|
|
for (const frag of line) {
|
|
if (frag.width === -1) {
|
|
const m = measureFunc(frag.text, frag.styles);
|
|
frag.width = m.width;
|
|
frag.height = m.height
|
|
}
|
|
width += frag.width;
|
|
height = Math.max(height, frag.height)
|
|
}
|
|
return {
|
|
width,
|
|
height
|
|
}
|
|
}
|
|
_AddLine(fragments, width, height) {
|
|
this._lines.push({
|
|
fragments,
|
|
width,
|
|
height
|
|
})
|
|
}
|
|
WordWrap(fragmentArr, measureFunc, wrapWidth, wrapMode, endOfLineMargin) {
|
|
if (typeof fragmentArr === "string")
|
|
fragmentArr = [{
|
|
text: fragmentArr,
|
|
styles: []
|
|
}];
|
|
C3.clearArray(this._lines);
|
|
if (!fragmentArr.length || fragmentArr.length === 1 && !fragmentArr[0].text.length || wrapWidth < 2)
|
|
return;
|
|
if (fragmentArr.length === 1) {
|
|
const frag = fragmentArr[0];
|
|
const text = frag.text;
|
|
const styles = frag.styles;
|
|
if (text.length <= 100 && !text.includes("\n")) {
|
|
let {width, height} = measureFunc(text, styles);
|
|
width += endOfLineMargin;
|
|
if (width <= wrapWidth) {
|
|
this._AddLine([{
|
|
text,
|
|
styles,
|
|
width,
|
|
height
|
|
}], width, height);
|
|
return
|
|
}
|
|
}
|
|
}
|
|
let tokenisedFragments;
|
|
if (wrapMode === "word")
|
|
tokenisedFragments = this._TokeniseWords(fragmentArr);
|
|
else {
|
|
tokenisedFragments = [];
|
|
for (const frag of fragmentArr)
|
|
C3.appendArray(tokenisedFragments, [...frag.text].map(ch=>[{
|
|
text: ch,
|
|
styles: frag.styles
|
|
}]))
|
|
}
|
|
this._WrapText(tokenisedFragments, measureFunc, wrapWidth, endOfLineMargin)
|
|
}
|
|
_TokeniseWords(fragmentArr) {
|
|
const ret = [];
|
|
let curWord = [];
|
|
let isCurWhitespace = false;
|
|
for (const frag of fragmentArr) {
|
|
const text = frag.text;
|
|
const styles = frag.styles;
|
|
for (const ch of text)
|
|
if (ch === "\n") {
|
|
if (curWord.length > 0)
|
|
ret.push(curWord);
|
|
ret.push([{
|
|
text: "\n",
|
|
styles
|
|
}]);
|
|
curWord = []
|
|
} else if (curWord.length === 0) {
|
|
curWord.push({
|
|
text: ch,
|
|
styles
|
|
});
|
|
isCurWhitespace = C3.IsWhitespaceChar(ch)
|
|
} else {
|
|
const isWhitespace = C3.IsWhitespaceChar(ch);
|
|
if (isWhitespace === isCurWhitespace) {
|
|
const curFrag = curWord[curWord.length - 1];
|
|
if (curFrag.styles === styles)
|
|
curFrag.text += ch;
|
|
else
|
|
curWord.push({
|
|
text: ch,
|
|
styles
|
|
})
|
|
} else {
|
|
ret.push(curWord);
|
|
curWord = [];
|
|
curWord.push({
|
|
text: ch,
|
|
styles
|
|
});
|
|
isCurWhitespace = isWhitespace
|
|
}
|
|
}
|
|
}
|
|
if (curWord.length > 0)
|
|
ret.push(curWord);
|
|
return ret
|
|
}
|
|
_CopyLine(line) {
|
|
return line.map(f=>({
|
|
text: f.text,
|
|
styles: f.styles,
|
|
width: f.width,
|
|
height: f.height
|
|
}))
|
|
}
|
|
_AddWordToLine(currentLine, curWord) {
|
|
const lastFrag = currentLine.length ? currentLine[currentLine.length - 1] : null;
|
|
let i = 0;
|
|
if (lastFrag && curWord[0].styles === lastFrag.styles) {
|
|
lastFrag.text += curWord[0].text;
|
|
lastFrag.width = -1;
|
|
lastFrag.height = -1;
|
|
i = 1
|
|
}
|
|
for (let len = curWord.length; i < len; ++i) {
|
|
const f = curWord[i];
|
|
currentLine.push({
|
|
text: f.text,
|
|
styles: f.styles,
|
|
width: -1,
|
|
height: -1
|
|
})
|
|
}
|
|
}
|
|
_WrapText(tokenisedFragments, measureFunc, wrapWidth, endOfLineMargin) {
|
|
let currentLine = [];
|
|
let currentLineWidth = 0;
|
|
let currentLineHeight = 0;
|
|
for (const curWord of tokenisedFragments) {
|
|
if (curWord.length === 1 && curWord[0].text === "\n") {
|
|
if (currentLineHeight === 0)
|
|
currentLineHeight = measureFunc(" ", curWord[0].styles).height;
|
|
this._AddLine(currentLine, currentLineWidth, currentLineHeight);
|
|
currentLine = [];
|
|
currentLineWidth = 0;
|
|
currentLineHeight = 0;
|
|
continue
|
|
}
|
|
const tryLine = this._CopyLine(currentLine);
|
|
this._AddWordToLine(tryLine, curWord);
|
|
const tryMetrics = this._MeasureLine(tryLine, measureFunc);
|
|
const tryLineWidth = tryMetrics.width;
|
|
const tryLineHeight = tryMetrics.height;
|
|
if (tryLineWidth >= wrapWidth) {
|
|
if (currentLine.length > 0)
|
|
this._AddLine(currentLine, currentLineWidth, currentLineHeight);
|
|
currentLine = [];
|
|
if (C3.IsStringAllWhitespace(curWord[0].text)) {
|
|
currentLineWidth = 0;
|
|
currentLineHeight = 0
|
|
} else {
|
|
this._AddWordToLine(currentLine, curWord);
|
|
const metrics = this._MeasureLine(currentLine, measureFunc);
|
|
currentLineWidth = metrics.width;
|
|
currentLineHeight = metrics.height
|
|
}
|
|
} else {
|
|
currentLine = tryLine;
|
|
currentLineWidth = tryLineWidth;
|
|
currentLineHeight = tryLineHeight
|
|
}
|
|
}
|
|
if (currentLine.length > 0)
|
|
this._AddLine(currentLine, currentLineWidth, currentLineHeight);
|
|
this._TrimLinesTrailingWhitespace(measureFunc, endOfLineMargin)
|
|
}
|
|
_TrimLinesTrailingWhitespace(measureFunc, endOfLineMargin) {
|
|
for (const line of this._lines) {
|
|
const fragments = line.fragments;
|
|
if (!fragments.length)
|
|
continue;
|
|
let lastFrag = fragments[fragments.length - 1];
|
|
const text = lastFrag.text;
|
|
const trimmedText = text.trimEnd();
|
|
if (!trimmedText) {
|
|
line.width -= lastFrag.width;
|
|
fragments.pop()
|
|
} else if (trimmedText.length < text.length) {
|
|
const trimmedWidth = measureFunc(trimmedText, lastFrag.styles).width;
|
|
const diff = lastFrag.width - trimmedWidth;
|
|
lastFrag.width = trimmedWidth;
|
|
lastFrag.text = trimmedText;
|
|
line.width -= diff
|
|
}
|
|
if (endOfLineMargin !== 0 && fragments.length > 0) {
|
|
lastFrag = fragments[fragments.length - 1];
|
|
lastFrag.width += endOfLineMargin;
|
|
line.width += endOfLineMargin
|
|
}
|
|
}
|
|
}
|
|
Clear() {
|
|
C3.clearArray(this._lines)
|
|
}
|
|
GetMaxLineWidth() {
|
|
return this._lines.reduce((a,v)=>Math.max(a, v.width), 0)
|
|
}
|
|
GetTotalLineHeight() {
|
|
return this._lines.reduce((a,v)=>a + v.height, 0)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
self.C3.Gfx = {};
|
|
'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const PERSPECTIVE_NEAR_Z = 1;
|
|
const PERSPECTIVE_FAR_Z = 1E4;
|
|
const fTempo = [0, 0, 0, 0, 0, 0, 0, 0];
|
|
const glMatrix = self.glMatrix;
|
|
const vec3 = glMatrix.vec3;
|
|
const mat4 = glMatrix.mat4;
|
|
const tmpVec3 = vec3.fromValues(0, 0, 0);
|
|
C3.Gfx.RendererBase = class RendererBase {
|
|
constructor() {
|
|
this._width = 0;
|
|
this._height = 0;
|
|
this._cam = vec3.fromValues(0, 0, 100);
|
|
this._look = vec3.fromValues(0, 0, 0);
|
|
this._up = vec3.fromValues(0, 1, 0);
|
|
this._worldScale = vec3.fromValues(1, 1, 1);
|
|
this._matP = mat4.create();
|
|
this._matMV = mat4.create();
|
|
this._lastMV = mat4.create();
|
|
this._allShaderPrograms = [];
|
|
this._shaderProgramsByName = new Map;
|
|
this._spTextureFill = null;
|
|
this._stateGroups = new Map;
|
|
this._currentStateGroup = null;
|
|
this._blendModeTable = [];
|
|
this._namedBlendModeMap = new Map;
|
|
this._frameNumber = 0;
|
|
this._enableMipmaps = true
|
|
}
|
|
FillIndexBufferData(indexData) {
|
|
let i = 0
|
|
, len = indexData.length
|
|
, fv = 0;
|
|
while (i < len) {
|
|
indexData[i++] = fv;
|
|
indexData[i++] = fv + 1;
|
|
indexData[i++] = fv + 2;
|
|
indexData[i++] = fv;
|
|
indexData[i++] = fv + 2;
|
|
indexData[i++] = fv + 3;
|
|
fv += 4
|
|
}
|
|
}
|
|
Project(x, y, w, h, out) {
|
|
const mv = this._matMV;
|
|
const proj = this._matP;
|
|
for (let i = 0, len = fTempo.length; i < len; ++i)
|
|
fTempo[i] = 0;
|
|
fTempo[0] = mv[0] * x + mv[4] * y + mv[12];
|
|
fTempo[1] = mv[1] * x + mv[5] * y + mv[13];
|
|
fTempo[2] = mv[2] * x + mv[6] * y + mv[14];
|
|
fTempo[3] = mv[3] * x + mv[7] * y + mv[15];
|
|
fTempo[4] = proj[0] * fTempo[0] + proj[4] * fTempo[1] + proj[8] * fTempo[2] + proj[12] * fTempo[3];
|
|
fTempo[5] = proj[1] * fTempo[0] + proj[5] * fTempo[1] + proj[9] * fTempo[2] + proj[13] * fTempo[3];
|
|
fTempo[6] = proj[2] * fTempo[0] + proj[6] * fTempo[1] + proj[10] * fTempo[2] + proj[14] * fTempo[3];
|
|
fTempo[7] = -fTempo[2];
|
|
if (fTempo[7] === 0)
|
|
return;
|
|
fTempo[7] = 1 / fTempo[7];
|
|
fTempo[4] *= fTempo[7];
|
|
fTempo[5] *= fTempo[7];
|
|
fTempo[6] *= fTempo[7];
|
|
out[0] = (fTempo[4] * .5 + .5) * w;
|
|
out[1] = (fTempo[5] * .5 + .5) * h
|
|
}
|
|
GetWidth() {
|
|
return this._width
|
|
}
|
|
GetHeight() {
|
|
return this._height
|
|
}
|
|
GetNearZ() {
|
|
return PERSPECTIVE_NEAR_Z
|
|
}
|
|
GetFarZ() {
|
|
return PERSPECTIVE_FAR_Z
|
|
}
|
|
SetCameraXYZ(x, y, z) {
|
|
this._cam[0] = x * this._worldScale[0];
|
|
this._cam[1] = y * this._worldScale[1];
|
|
this._cam[2] = z
|
|
}
|
|
SetLookXYZ(x, y, z) {
|
|
this._look[0] = x * this._worldScale[0];
|
|
this._look[1] = y * this._worldScale[1];
|
|
this._look[2] = z
|
|
}
|
|
ResetModelView(alternateUpVector) {
|
|
mat4.lookAt(this._matMV, this._cam, this._look, alternateUpVector || this._up);
|
|
mat4.scale(this._matMV, this._matMV, this._worldScale)
|
|
}
|
|
Translate(x, y) {
|
|
if (x === 0 && y === 0)
|
|
return;
|
|
tmpVec3[0] = x;
|
|
tmpVec3[1] = y;
|
|
tmpVec3[2] = 0;
|
|
mat4.translate(this._matMV, this._matMV, tmpVec3)
|
|
}
|
|
Scale(x, y) {
|
|
if (x === 1 && y === 1)
|
|
return;
|
|
tmpVec3[0] = x;
|
|
tmpVec3[1] = y;
|
|
tmpVec3[2] = 1;
|
|
mat4.scale(this._matMV, this._matMV, tmpVec3)
|
|
}
|
|
RotateZ(a) {
|
|
if (a === 0)
|
|
return;
|
|
mat4.rotateZ(this._matMV, this._matMV, a)
|
|
}
|
|
_AddShaderProgram(sp) {
|
|
this._allShaderPrograms.push(sp);
|
|
this._shaderProgramsByName.set(sp.GetName(), sp)
|
|
}
|
|
_RemoveShaderProgram(sp) {
|
|
const i = this._allShaderPrograms.indexOf(sp);
|
|
if (i !== -1)
|
|
this._allShaderPrograms.splice(i, 1);
|
|
this._shaderProgramsByName.delete(sp.GetName())
|
|
}
|
|
_ClearAllShaderPrograms() {
|
|
C3.clearArray(this._allShaderPrograms);
|
|
this._shaderProgramsByName.clear()
|
|
}
|
|
GetShaderProgramByName(name) {
|
|
return this._shaderProgramsByName.get(name) || null
|
|
}
|
|
GetTextureFillShaderProgram() {
|
|
return this._spTextureFill
|
|
}
|
|
_SetCurrentStateGroup(sg) {
|
|
this._currentStateGroup = sg
|
|
}
|
|
GetCurrentStateGroup() {
|
|
return this._currentStateGroup
|
|
}
|
|
AcquireStateGroup(shaderProgram_or_name, blendMode, color, zElevation) {
|
|
const key = C3.Gfx.StateGroup.MakeKey(shaderProgram_or_name, blendMode, color, zElevation);
|
|
let stateGroup = this._stateGroups.get(key);
|
|
if (!stateGroup) {
|
|
stateGroup = C3.New(C3.Gfx.StateGroup, this, shaderProgram_or_name, blendMode, color, zElevation);
|
|
this._stateGroups.set(key, stateGroup)
|
|
}
|
|
stateGroup.AddRef();
|
|
return stateGroup
|
|
}
|
|
ReleaseStateGroup(stateGroup) {
|
|
stateGroup.DecRef();
|
|
if (stateGroup._GetRefCount() === 0) {
|
|
if (this._currentStateGroup === stateGroup)
|
|
this._currentStateGroup = null;
|
|
this._stateGroups.delete(stateGroup.GetKey());
|
|
stateGroup.Release()
|
|
}
|
|
}
|
|
_InitBlendModeData(blendModeData) {
|
|
C3.clearArray(this._blendModeTable);
|
|
this._namedBlendModeMap.clear();
|
|
for (const bmd of blendModeData) {
|
|
const name = bmd[0];
|
|
const srcBlend = bmd[1];
|
|
const destBlend = bmd[2];
|
|
this._blendModeTable.push([srcBlend, destBlend]);
|
|
this._namedBlendModeMap.set(name, {
|
|
srcBlend,
|
|
destBlend
|
|
})
|
|
}
|
|
}
|
|
_GetBlendByIndex(blendIndex) {
|
|
return this._blendModeTable[blendIndex]
|
|
}
|
|
GetSrcBlendByIndex(blendIndex) {
|
|
return this._GetBlendByIndex(blendIndex)[0]
|
|
}
|
|
GetDestBlendByIndex(blendIndex) {
|
|
return this._GetBlendByIndex(blendIndex)[1]
|
|
}
|
|
GetNamedBlend(blendName) {
|
|
const ret = this._namedBlendModeMap.get(blendName);
|
|
if (typeof ret === "undefined")
|
|
throw new Error("invalid blend name");
|
|
return ret
|
|
}
|
|
Finish() {
|
|
this.EndBatch();
|
|
this._frameNumber++
|
|
}
|
|
GetFrameNumber() {
|
|
return this._frameNumber
|
|
}
|
|
IncrementFrameNumber() {
|
|
this._frameNumber++
|
|
}
|
|
SetMipmapsEnabled(e) {
|
|
this._enableMipmaps = !!e
|
|
}
|
|
AreMipmapsEnabled() {
|
|
return this._enableMipmaps
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Gfx.StateGroup = class StateGroup {
|
|
constructor(renderer, shaderProgram_or_name, blendMode, color, zElevation) {
|
|
this._renderer = renderer;
|
|
this._refCount = 0;
|
|
this._shaderProgram = null;
|
|
this._shaderProgramName = "";
|
|
this._blendMode = blendMode;
|
|
this._color = C3.New(C3.Color);
|
|
this._color.set(color);
|
|
this._zElevation = zElevation;
|
|
if (typeof shaderProgram_or_name === "string")
|
|
this._shaderProgramName = shaderProgram_or_name;
|
|
else {
|
|
this._shaderProgram = shaderProgram_or_name;
|
|
this._shaderProgramName = this._shaderProgram.GetName()
|
|
}
|
|
}
|
|
Release() {
|
|
if (this._refCount > 0)
|
|
throw new Error("releasing state group still in use");
|
|
this._renderer = null;
|
|
this._shaderProgram = null;
|
|
this._shaderProgramName = ""
|
|
}
|
|
Apply() {
|
|
const renderer = this._renderer;
|
|
renderer.SetProgram(this._shaderProgram);
|
|
renderer.SetBlendMode(this._blendMode);
|
|
renderer.SetColor(this._color);
|
|
renderer.SetCurrentZ(this._zElevation);
|
|
renderer._SetCurrentStateGroup(this)
|
|
}
|
|
GetKey() {
|
|
return C3.Gfx.StateGroup.MakeKey(this._shaderProgramName, this._blendMode, this._color, this._zElevation)
|
|
}
|
|
AddRef() {
|
|
++this._refCount
|
|
}
|
|
DecRef() {
|
|
--this._refCount
|
|
}
|
|
_GetRefCount() {
|
|
return this._refCount
|
|
}
|
|
OnContextLost() {
|
|
this._shaderProgram = null
|
|
}
|
|
OnContextRestored(renderer) {
|
|
this._shaderProgram = renderer.GetShaderProgramByName(this._shaderProgramName);
|
|
if (!this._shaderProgram)
|
|
throw new Error("failed to restore shader program");
|
|
}
|
|
static MakeKey(shaderProgram_or_name, blendMode, c, zElevation) {
|
|
const shaderProgramName = typeof shaderProgram_or_name === "string" ? shaderProgram_or_name : shaderProgram_or_name.GetName();
|
|
return shaderProgramName + "," + blendMode + "," + c.getR() + "," + c.getG() + "," + c.getB() + "," + c.getA() + "," + zElevation
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tempQuadPos = C3.New(C3.Quad);
|
|
const tempQuadTex = C3.New(C3.Quad);
|
|
function interpolateQuad(srcX, srcY, quad) {
|
|
const qtlx = quad.getTlx();
|
|
const qtly = quad.getTly();
|
|
const qtrx = quad.getTrx() - qtlx;
|
|
const qtry = quad.getTry() - qtly;
|
|
const qblx = quad.getBlx() - qtlx;
|
|
const qbly = quad.getBly() - qtly;
|
|
const xix = qtrx * srcX;
|
|
const xiy = qtry * srcX;
|
|
const yix = qblx * srcY;
|
|
const yiy = qbly * srcY;
|
|
return [qtlx + xix + yix, qtly + xiy + yiy]
|
|
}
|
|
class MeshPoint {
|
|
constructor(mesh) {
|
|
this._mesh = mesh;
|
|
this._x = NaN;
|
|
this._y = NaN;
|
|
this._u = NaN;
|
|
this._v = NaN;
|
|
this._x = 0;
|
|
this._y = 0;
|
|
this._u = 0;
|
|
this._v = 0
|
|
}
|
|
_Init(x, y, u, v) {
|
|
this._x = x;
|
|
this._y = y;
|
|
this._u = u;
|
|
this._v = v
|
|
}
|
|
GetX() {
|
|
return this._x
|
|
}
|
|
SetX(x) {
|
|
if (this._x === x)
|
|
return;
|
|
this._x = x;
|
|
this._mesh._SetPointsChanged()
|
|
}
|
|
GetY() {
|
|
return this._y
|
|
}
|
|
SetY(y) {
|
|
if (this._y === y)
|
|
return;
|
|
this._y = y;
|
|
this._mesh._SetPointsChanged()
|
|
}
|
|
GetU() {
|
|
return this._u
|
|
}
|
|
SetU(u) {
|
|
this._u = u
|
|
}
|
|
GetV() {
|
|
return this._v
|
|
}
|
|
SetV(v) {
|
|
this._v = v
|
|
}
|
|
_Interpolate_TexRect(srcPoint, quadPos, rcTex) {
|
|
[this._x,this._y] = interpolateQuad(srcPoint._x, srcPoint._y, quadPos);
|
|
this._u = C3.lerp(rcTex.getLeft(), rcTex.getRight(), srcPoint._u);
|
|
this._v = C3.lerp(rcTex.getTop(), rcTex.getBottom(), srcPoint._v)
|
|
}
|
|
_Interpolate_TexQuad(srcPoint, quadPos, quadTex) {
|
|
[this._x,this._y] = interpolateQuad(srcPoint._x, srcPoint._y, quadPos);
|
|
[this._u,this._v] = interpolateQuad(srcPoint._u, srcPoint._v, quadTex)
|
|
}
|
|
}
|
|
C3.Gfx.Mesh = class Mesh {
|
|
constructor(hsize, vsize) {
|
|
if (hsize < 2 || vsize < 2)
|
|
throw new Error("invalid mesh size");
|
|
this._hsize = hsize;
|
|
this._vsize = vsize;
|
|
this._pts = [];
|
|
this._minX = 0;
|
|
this._minY = 0;
|
|
this._maxX = 1;
|
|
this._maxY = 1;
|
|
this._pointsChanged = false;
|
|
const lastX = hsize - 1;
|
|
const lastY = vsize - 1;
|
|
for (let y = 0; y < vsize; ++y) {
|
|
const row = [];
|
|
for (let x = 0; x < hsize; ++x) {
|
|
const meshPoint = C3.New(MeshPoint, this);
|
|
const xf = x / lastX;
|
|
const yf = y / lastY;
|
|
meshPoint._Init(xf, yf, xf, yf);
|
|
row.push(meshPoint)
|
|
}
|
|
this._pts.push(row)
|
|
}
|
|
}
|
|
Release() {
|
|
C3.clearArray(this._pts)
|
|
}
|
|
GetHSize() {
|
|
return this._hsize
|
|
}
|
|
GetVSize() {
|
|
return this._vsize
|
|
}
|
|
_SetPointsChanged() {
|
|
this._pointsChanged = true
|
|
}
|
|
_MaybeComputeBounds() {
|
|
if (!this._pointsChanged)
|
|
return;
|
|
let minX = Infinity;
|
|
let minY = Infinity;
|
|
let maxX = -Infinity;
|
|
let maxY = -Infinity;
|
|
for (const row of this._pts)
|
|
for (const meshPoint of row) {
|
|
const x = meshPoint.GetX();
|
|
const y = meshPoint.GetY();
|
|
minX = Math.min(minX, x);
|
|
minY = Math.min(minY, y);
|
|
maxX = Math.max(maxX, x);
|
|
maxY = Math.max(maxY, y)
|
|
}
|
|
this._minX = minX;
|
|
this._minY = minY;
|
|
this._maxX = maxX;
|
|
this._maxY = maxY;
|
|
this._pointsChanged = false
|
|
}
|
|
GetMinX() {
|
|
this._MaybeComputeBounds();
|
|
return this._minX
|
|
}
|
|
GetMinY() {
|
|
this._MaybeComputeBounds();
|
|
return this._minY
|
|
}
|
|
GetMaxX() {
|
|
this._MaybeComputeBounds();
|
|
return this._maxX
|
|
}
|
|
GetMaxY() {
|
|
this._MaybeComputeBounds();
|
|
return this._maxY
|
|
}
|
|
GetMeshPointAt(x, y) {
|
|
x = Math.floor(x);
|
|
y = Math.floor(y);
|
|
if (x < 0 || x >= this._hsize || y < 0 || y >= this._vsize)
|
|
return null;
|
|
return this._pts[y][x]
|
|
}
|
|
CalculateTransformedMesh(srcMesh, quadPos, rcTex_or_quad) {
|
|
const isTexRect = rcTex_or_quad instanceof C3.Rect;
|
|
if (srcMesh.GetHSize() !== this.GetHSize() || srcMesh.GetVSize() !== this.GetVSize())
|
|
throw new Error("source mesh wrong size");
|
|
const srcPts = srcMesh._pts;
|
|
const destPts = this._pts;
|
|
for (let y = 0, lenY = destPts.length; y < lenY; ++y) {
|
|
const srcRow = srcPts[y];
|
|
const destRow = destPts[y];
|
|
for (let x = 0, lenX = destRow.length; x < lenX; ++x) {
|
|
const srcPoint = srcRow[x];
|
|
const destPoint = destRow[x];
|
|
if (isTexRect)
|
|
destPoint._Interpolate_TexRect(srcPoint, quadPos, rcTex_or_quad);
|
|
else
|
|
destPoint._Interpolate_TexQuad(srcPoint, quadPos, rcTex_or_quad)
|
|
}
|
|
}
|
|
}
|
|
Draw(renderer) {
|
|
const pts = this._pts;
|
|
let prevRow = pts[0];
|
|
for (let y = 1, lenY = pts.length; y < lenY; ++y) {
|
|
const row = pts[y];
|
|
let tl = prevRow[0];
|
|
let bl = row[0];
|
|
for (let x = 1, lenX = row.length; x < lenX; ++x) {
|
|
const tr = prevRow[x];
|
|
const br = row[x];
|
|
tempQuadPos.set(tl.GetX(), tl.GetY(), tr.GetX(), tr.GetY(), br.GetX(), br.GetY(), bl.GetX(), bl.GetY());
|
|
tempQuadTex.set(tl.GetU(), tl.GetV(), tr.GetU(), tr.GetV(), br.GetU(), br.GetV(), bl.GetU(), bl.GetV());
|
|
renderer.Quad4(tempQuadPos, tempQuadTex);
|
|
tl = tr;
|
|
bl = br
|
|
}
|
|
prevRow = row
|
|
}
|
|
}
|
|
Outline(renderer) {
|
|
const pts = this._pts;
|
|
let prevRow = pts[0];
|
|
for (let y = 1, lenY = pts.length; y < lenY; ++y) {
|
|
const row = pts[y];
|
|
let tl = prevRow[0];
|
|
let bl = row[0];
|
|
for (let x = 1, lenX = row.length; x < lenX; ++x) {
|
|
const tr = prevRow[x];
|
|
const br = row[x];
|
|
const tlx = tl.GetX();
|
|
const tly = tl.GetY();
|
|
const trx = tr.GetX();
|
|
const try_ = tr.GetY();
|
|
const brx = br.GetX();
|
|
const bry = br.GetY();
|
|
const blx = bl.GetX();
|
|
const bly = bl.GetY();
|
|
renderer.Line(tlx, tly, trx, try_);
|
|
renderer.Line(tlx, tly, brx, bry);
|
|
renderer.Line(tlx, tly, blx, bly);
|
|
if (x === lenX - 1)
|
|
renderer.Line(trx, try_, brx, bry);
|
|
if (y === lenY - 1)
|
|
renderer.Line(blx, bly, brx, bry);
|
|
tl = tr;
|
|
bl = br
|
|
}
|
|
prevRow = row
|
|
}
|
|
}
|
|
InsertPolyMeshVertices(srcPoly) {
|
|
const RAY_EXT_DIST = .001;
|
|
const MIN_RAY_DIST = 0;
|
|
const MAX_RAY_DIST = .99999999;
|
|
const inPts = srcPoly.pointsArr();
|
|
const outPts = [];
|
|
const colCount = this.GetHSize() - 1;
|
|
const rowCount = this.GetVSize() - 1;
|
|
const colWidthNorm = 1 / colCount;
|
|
const rowHeightNorm = 1 / rowCount;
|
|
const lastCol = colCount - 1;
|
|
const lastRow = rowCount - 1;
|
|
let curX = inPts[0];
|
|
let curY = inPts[1];
|
|
let curCol = C3.clamp(Math.floor(curX * colCount), 0, lastCol);
|
|
let curRow = C3.clamp(Math.floor(curY * rowCount), 0, lastRow);
|
|
let isUpper = true;
|
|
let nextX = 0;
|
|
let nextY = 0;
|
|
let rayHit = 0;
|
|
const NOTHING_DISABLED = -1;
|
|
const DISABLE_DIAGONAL = 0;
|
|
const DISABLE_LEFT_EDGE = 1;
|
|
const DISABLE_TOP_EDGE = 2;
|
|
const DISABLE_RIGHT_EDGE = 3;
|
|
const DISABLE_BOTTOM_EDGE = 4;
|
|
let disableCheck = NOTHING_DISABLED;
|
|
const addVertexAtRayHit = ()=>{
|
|
curX = C3.clamp(C3.lerp(curX, nextX, rayHit), 0, 1);
|
|
curY = C3.clamp(C3.lerp(curY, nextY, rayHit), 0, 1);
|
|
outPts.push(curX, curY)
|
|
}
|
|
;
|
|
for (let i = 0, len = inPts.length; i < len; i += 2) {
|
|
curX = inPts[i];
|
|
curY = inPts[i + 1];
|
|
outPts.push(curX, curY);
|
|
curCol = C3.clamp(Math.floor(curX * colCount), 0, lastCol);
|
|
curRow = C3.clamp(Math.floor(curY * rowCount), 0, lastRow);
|
|
const j = (i + 2) % len;
|
|
nextX = inPts[j];
|
|
nextY = inPts[j + 1];
|
|
disableCheck = NOTHING_DISABLED;
|
|
while (true) {
|
|
if (outPts.length > 1E6)
|
|
throw new Error("Too many mesh poly points");
|
|
const srcTlx = curCol * colWidthNorm;
|
|
const srcTly = curRow * rowHeightNorm;
|
|
const srcBrx = (curCol + 1) * colWidthNorm;
|
|
const srcBry = (curRow + 1) * rowHeightNorm;
|
|
isUpper = C3.isPointInTriangleInclusive(curX, curY, srcTlx, srcTly, srcBrx, srcTly, srcBrx, srcBry);
|
|
if (disableCheck !== DISABLE_DIAGONAL) {
|
|
rayHit = C3.rayIntersectExtended(curX, curY, nextX, nextY, srcTlx, srcTly, srcBrx, srcBry, -RAY_EXT_DIST);
|
|
if (rayHit >= MIN_RAY_DIST && rayHit <= MAX_RAY_DIST) {
|
|
addVertexAtRayHit();
|
|
isUpper = !isUpper;
|
|
disableCheck = DISABLE_DIAGONAL;
|
|
continue
|
|
}
|
|
}
|
|
if (curRow > 0 && disableCheck !== DISABLE_TOP_EDGE) {
|
|
rayHit = C3.rayIntersectExtended(curX, curY, nextX, nextY, srcTlx, srcTly, srcBrx, srcTly, RAY_EXT_DIST);
|
|
if (rayHit >= MIN_RAY_DIST && rayHit <= MAX_RAY_DIST) {
|
|
addVertexAtRayHit();
|
|
curRow--;
|
|
isUpper = false;
|
|
disableCheck = DISABLE_BOTTOM_EDGE;
|
|
continue
|
|
}
|
|
}
|
|
if (curCol < lastCol && disableCheck !== DISABLE_RIGHT_EDGE) {
|
|
rayHit = C3.rayIntersectExtended(curX, curY, nextX, nextY, srcBrx, srcTly, srcBrx, srcBry, RAY_EXT_DIST);
|
|
if (rayHit >= MIN_RAY_DIST && rayHit <= MAX_RAY_DIST) {
|
|
addVertexAtRayHit();
|
|
curCol++;
|
|
isUpper = false;
|
|
disableCheck = DISABLE_LEFT_EDGE;
|
|
continue
|
|
}
|
|
}
|
|
if (curCol > 0 && disableCheck !== DISABLE_LEFT_EDGE) {
|
|
rayHit = C3.rayIntersectExtended(curX, curY, nextX, nextY, srcTlx, srcTly, srcTlx, srcBry, RAY_EXT_DIST);
|
|
if (rayHit >= MIN_RAY_DIST && rayHit <= MAX_RAY_DIST) {
|
|
addVertexAtRayHit();
|
|
curCol--;
|
|
isUpper = true;
|
|
disableCheck = DISABLE_RIGHT_EDGE;
|
|
continue
|
|
}
|
|
}
|
|
if (curRow < lastRow && disableCheck !== DISABLE_BOTTOM_EDGE) {
|
|
rayHit = C3.rayIntersectExtended(curX, curY, nextX, nextY, srcTlx, srcBry, srcBrx, srcBry, RAY_EXT_DIST);
|
|
if (rayHit >= MIN_RAY_DIST && rayHit <= MAX_RAY_DIST) {
|
|
addVertexAtRayHit();
|
|
curRow++;
|
|
isUpper = true;
|
|
disableCheck = DISABLE_TOP_EDGE;
|
|
continue
|
|
}
|
|
}
|
|
break
|
|
}
|
|
}
|
|
return C3.New(C3.CollisionPoly, outPts)
|
|
}
|
|
TransformCollisionPoly(srcPoly, destPoly) {
|
|
const ptsArr = this._TransformPolyPoints(srcPoly);
|
|
this._SimplifyPoly(ptsArr);
|
|
destPoly.setPoints(ptsArr)
|
|
}
|
|
_TransformPolyPoints(srcPoly) {
|
|
const outPts = [];
|
|
const ptsArr = srcPoly.pointsArr();
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2) {
|
|
const srcX = ptsArr[i];
|
|
const srcY = ptsArr[i + 1];
|
|
const [destX,destY] = this.TransformPoint(srcX, srcY);
|
|
outPts.push(destX, destY)
|
|
}
|
|
return outPts
|
|
}
|
|
TransformPoint(srcX, srcY) {
|
|
const lastCol = this.GetHSize() - 1;
|
|
const lastRow = this.GetVSize() - 1;
|
|
const colWidthNorm = 1 / lastCol;
|
|
const rowHeightNorm = 1 / lastRow;
|
|
const srcCol = C3.clamp(Math.floor(srcX * lastCol), 0, lastCol - 1);
|
|
const srcRow = C3.clamp(Math.floor(srcY * lastRow), 0, lastRow - 1);
|
|
const srcTlx = srcCol * colWidthNorm;
|
|
const srcTly = srcRow * rowHeightNorm;
|
|
const srcBrx = (srcCol + 1) * colWidthNorm;
|
|
const srcBry = (srcRow + 1) * rowHeightNorm;
|
|
const destTl = this.GetMeshPointAt(srcCol, srcRow);
|
|
const destBr = this.GetMeshPointAt(srcCol + 1, srcRow + 1);
|
|
const isUpper = C3.isPointInTriangleInclusive(srcX, srcY, srcTlx, srcTly, srcBrx, srcTly, srcBrx, srcBry);
|
|
const srcAltX = isUpper ? srcTlx + colWidthNorm : srcTlx;
|
|
const srcAltY = isUpper ? srcTly : srcTly + rowHeightNorm;
|
|
const destAlt = this.GetMeshPointAt(srcCol + (isUpper ? 1 : 0), srcRow + (isUpper ? 0 : 1));
|
|
const [u,v,w] = C3.triangleCartesianToBarycentric(srcX, srcY, srcTlx, srcTly, srcAltX, srcAltY, srcBrx, srcBry);
|
|
return C3.triangleBarycentricToCartesian(u, v, w, destTl.GetX(), destTl.GetY(), destAlt.GetX(), destAlt.GetY(), destBr.GetX(), destBr.GetY())
|
|
}
|
|
_SimplifyPoly(ptsArr) {
|
|
const outPts = [];
|
|
const EPSILON = 1E-7;
|
|
let curX = ptsArr[0];
|
|
let curY = ptsArr[1];
|
|
let lastDx = curX - ptsArr[ptsArr.length - 2];
|
|
let lastDy = curY - ptsArr[ptsArr.length - 1];
|
|
for (let i = 0, len = ptsArr.length; i < len; i += 2) {
|
|
const j = (i + 2) % len;
|
|
const nextX = ptsArr[j];
|
|
const nextY = ptsArr[j + 1];
|
|
const dx = nextX - curX;
|
|
const dy = nextY - curY;
|
|
const bothXNearZero = Math.abs(dx) < EPSILON && Math.abs(lastDx) < EPSILON && Math.sign(dy) === Math.sign(lastDy);
|
|
const bothYNearZero = Math.abs(dy) < EPSILON && Math.abs(lastDy) < EPSILON && Math.sign(dx) === Math.sign(lastDx);
|
|
if (!bothXNearZero && !bothYNearZero && Math.abs(dx / lastDx - dy / lastDy) > EPSILON || dx == 0 && dy === 0)
|
|
outPts.push(curX, curY);
|
|
curX = nextX;
|
|
curY = nextY;
|
|
lastDx = dx;
|
|
lastDy = dy
|
|
}
|
|
if (outPts.length < ptsArr.length)
|
|
C3.shallowAssignArray(ptsArr, outPts)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const VALID_PIXEL_FORMATS = new Set(["rgba8", "rgb8", "rgba4", "rgb5_a1", "rgb565"]);
|
|
const VALID_SAMPLINGS = new Set(["nearest", "bilinear", "trilinear"]);
|
|
const VALID_MIPMAP_QUALITIES = new Set(["default", "low", "high"]);
|
|
const VALID_WRAP_MODES = new Set(["clamp-to-edge", "repeat", "mirror-repeat"]);
|
|
function GetFormatSpecifiers(pixelFormat, gl) {
|
|
let sizedinternalformat;
|
|
let internalformat;
|
|
let format;
|
|
let type;
|
|
switch (pixelFormat) {
|
|
case "rgba8":
|
|
sizedinternalformat = gl.RGBA8;
|
|
internalformat = gl.RGBA;
|
|
format = gl.RGBA;
|
|
type = gl.UNSIGNED_BYTE;
|
|
break;
|
|
case "rgb8":
|
|
sizedinternalformat = gl.RGB8;
|
|
internalformat = gl.RGB;
|
|
format = gl.RGB;
|
|
type = gl.UNSIGNED_BYTE;
|
|
break;
|
|
case "rgba4":
|
|
sizedinternalformat = gl.RGBA4;
|
|
internalformat = gl.RGBA;
|
|
format = gl.RGBA;
|
|
type = gl.UNSIGNED_SHORT_4_4_4_4;
|
|
break;
|
|
case "rgb5_a1":
|
|
sizedinternalformat = gl.RGB5_A1;
|
|
internalformat = gl.RGBA;
|
|
format = gl.RGBA;
|
|
type = gl.UNSIGNED_SHORT_5_5_5_1;
|
|
break;
|
|
case "rgb565":
|
|
sizedinternalformat = gl.RGB565;
|
|
internalformat = gl.RGB;
|
|
format = gl.RGB;
|
|
type = gl.UNSIGNED_SHORT_5_6_5;
|
|
break;
|
|
default:
|
|
throw new Error("invalid pixel format");
|
|
}
|
|
return {
|
|
sizedinternalformat,
|
|
internalformat,
|
|
format,
|
|
type
|
|
}
|
|
}
|
|
const CREATEFROM_DEFAULT_OPTIONS = {
|
|
wrapX: "clamp-to-edge",
|
|
wrapY: "clamp-to-edge",
|
|
sampling: "trilinear",
|
|
pixelFormat: "rgba8",
|
|
mipMap: true,
|
|
mipMapQuality: "default",
|
|
premultiplyAlpha: true,
|
|
isSvg: false,
|
|
width: -1,
|
|
height: -1
|
|
};
|
|
const UPDATE_DEFAULT_OPTIONS = {
|
|
premultiplyAlpha: true,
|
|
flipY: false
|
|
};
|
|
const allTextures = new Set;
|
|
C3.Gfx.WebGLRendererTexture = class WebGLRendererTexture {
|
|
constructor(renderer) {
|
|
this._renderer = renderer;
|
|
this._texture = null;
|
|
this._width = 0;
|
|
this._height = 0;
|
|
this._isStatic = true;
|
|
this._wrapX = "clamp-to-edge";
|
|
this._wrapY = "clamp-to-edge";
|
|
this._sampling = "trilinear";
|
|
this._pixelFormat = "rgba8";
|
|
this._isMipMapped = false;
|
|
this._mipMapQuality = "default";
|
|
this._refCount = 0
|
|
}
|
|
_CreateStatic(data, opts) {
|
|
if ((typeof HTMLImageElement === "undefined" || !(data instanceof HTMLImageElement)) && (typeof HTMLCanvasElement === "undefined" || !(data instanceof HTMLCanvasElement)) && (typeof ImageBitmap === "undefined" || !(data instanceof ImageBitmap)) && (typeof OffscreenCanvas === "undefined" || !(data instanceof OffscreenCanvas)) && !(data instanceof ImageData) && !(data instanceof ArrayBuffer) && data !== null)
|
|
throw new Error("invalid texture source");
|
|
opts = Object.assign({}, CREATEFROM_DEFAULT_OPTIONS, opts);
|
|
if (this._texture)
|
|
throw new Error("already created texture");
|
|
this._wrapX = opts.wrapX;
|
|
this._wrapY = opts.wrapY;
|
|
this._sampling = opts.sampling;
|
|
this._pixelFormat = opts.pixelFormat;
|
|
this._isMipMapped = !!opts.mipMap && this._renderer.AreMipmapsEnabled();
|
|
this._mipMapQuality = opts.mipMapQuality;
|
|
if (!VALID_WRAP_MODES.has(this._wrapX) || !VALID_WRAP_MODES.has(this._wrapY))
|
|
throw new Error("invalid wrap mode");
|
|
if (!VALID_SAMPLINGS.has(this._sampling))
|
|
throw new Error("invalid sampling");
|
|
if (!VALID_PIXEL_FORMATS.has(this._pixelFormat))
|
|
throw new Error("invalid pixel format");
|
|
if (!VALID_MIPMAP_QUALITIES.has(this._mipMapQuality))
|
|
throw new Error("invalid mipmap quality");
|
|
this._isStatic = true;
|
|
if (data instanceof ArrayBuffer || data === null || opts.isSvg) {
|
|
this._width = opts.width;
|
|
this._height = opts.height;
|
|
if (data instanceof ArrayBuffer && data.byteLength !== this._width * this._height * 4)
|
|
throw new Error("ArrayBuffer wrong size");
|
|
} else {
|
|
this._width = data.width;
|
|
this._height = data.height
|
|
}
|
|
if (this._width <= 0 || this._height <= 0)
|
|
throw new Error("invalid texture data size");
|
|
if (opts.isSvg) {
|
|
const canvas = C3.CreateCanvas(this._width, this._height);
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.drawImage(data, 0, 0, this._width, this._height);
|
|
data = canvas
|
|
}
|
|
const isPOT = C3.isPOT(this._width) && C3.isPOT(this._height);
|
|
const maxTextureSize = this._renderer.GetMaxTextureSize();
|
|
if (this._width > maxTextureSize || this._height > maxTextureSize)
|
|
throw new Error("texture data exceeds maximum texture size");
|
|
const gl = this._renderer.GetContext();
|
|
const webglVersion = this._renderer.GetWebGLVersionNumber();
|
|
this._texture = gl.createTexture();
|
|
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], opts.premultiplyAlpha);
|
|
const formatspec = GetFormatSpecifiers(this._pixelFormat, gl);
|
|
if (!this._renderer.SupportsNPOTTextures() && !isPOT && this._IsTiled()) {
|
|
if (data === null)
|
|
throw new Error("cannot pass null data when creating a NPOT tiled texture without NPOT support");
|
|
if (data instanceof ArrayBuffer)
|
|
data = new ImageData(new Uint8ClampedArray(data),this._width,this._height);
|
|
if (data instanceof ImageData) {
|
|
const tmpCanvas = C3.CreateCanvas(this._width, this._height);
|
|
const tmpCtx = tmpCanvas.getContext("2d");
|
|
tmpCtx.putImageData(data, 0, 0);
|
|
data = tmpCanvas
|
|
}
|
|
const canvas = C3.CreateCanvas(C3.nextHighestPowerOfTwo(this._width), C3.nextHighestPowerOfTwo(this._height));
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.imageSmoothingEnabled = this._sampling !== "nearest";
|
|
ctx.drawImage(data, 0, 0, this._width, this._height, 0, 0, canvas.width, canvas.height);
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, formatspec.internalformat, formatspec.format, formatspec.type, canvas)
|
|
} else if (webglVersion >= 2) {
|
|
let levels;
|
|
if (this._isMipMapped)
|
|
levels = Math.floor(Math.log2(Math.max(this._width, this._height)) + 1);
|
|
else
|
|
levels = 1;
|
|
gl.texStorage2D(gl.TEXTURE_2D, levels, formatspec.sizedinternalformat, this._width, this._height);
|
|
if (data instanceof ArrayBuffer)
|
|
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this._width, this._height, formatspec.format, formatspec.type, new Uint8Array(data));
|
|
else if (data !== null)
|
|
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, formatspec.format, formatspec.type, data)
|
|
} else if (data instanceof ArrayBuffer)
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, formatspec.internalformat, this._width, this._height, 0, formatspec.format, formatspec.type, new Uint8Array(data));
|
|
else if (data === null)
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, formatspec.internalformat, this._width, this._height, 0, formatspec.format, formatspec.type, null);
|
|
else
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, formatspec.internalformat, formatspec.format, formatspec.type, data);
|
|
if (data !== null)
|
|
this._SetTextureParameters(gl);
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
this._renderer._ResetLastTexture();
|
|
this._refCount = 1;
|
|
allTextures.add(this)
|
|
}
|
|
_CreateDynamic(width, height, opts) {
|
|
opts = Object.assign({}, CREATEFROM_DEFAULT_OPTIONS, opts);
|
|
if (this._texture)
|
|
throw new Error("already created texture");
|
|
this._wrapX = opts.wrapX;
|
|
this._wrapY = opts.wrapY;
|
|
this._sampling = opts.sampling;
|
|
this._pixelFormat = opts.pixelFormat;
|
|
this._isMipMapped = !!opts.mipMap && this._renderer.AreMipmapsEnabled();
|
|
this._mipMapQuality = opts.mipMapQuality;
|
|
if (!VALID_WRAP_MODES.has(this._wrapX) || !VALID_WRAP_MODES.has(this._wrapY))
|
|
throw new Error("invalid wrap mode");
|
|
if (!VALID_SAMPLINGS.has(this._sampling))
|
|
throw new Error("invalid sampling");
|
|
if (!VALID_PIXEL_FORMATS.has(this._pixelFormat))
|
|
throw new Error("invalid pixel format");
|
|
if (!VALID_MIPMAP_QUALITIES.has(this._mipMapQuality))
|
|
throw new Error("invalid mipmap quality");
|
|
this._isStatic = false;
|
|
this._width = Math.floor(width);
|
|
this._height = Math.floor(height);
|
|
const isPOT = C3.isPOT(this._width) && C3.isPOT(this._height);
|
|
const maxTextureSize = this._renderer.GetMaxTextureSize();
|
|
if (this._width <= 0 || this._height <= 0)
|
|
throw new Error("invalid texture size");
|
|
if (this._width > maxTextureSize || this._height > maxTextureSize)
|
|
throw new Error("texture exceeds maximum texture size");
|
|
if (!this._renderer.SupportsNPOTTextures() && this._IsTiled() && !isPOT)
|
|
throw new Error("non-power-of-two tiled textures not supported");
|
|
const gl = this._renderer.GetContext();
|
|
const webglVersion = this._renderer.GetWebGLVersionNumber();
|
|
this._texture = gl.createTexture();
|
|
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], opts.premultiplyAlpha);
|
|
const formatspec = GetFormatSpecifiers(this._pixelFormat, gl);
|
|
const internalformat = webglVersion >= 2 ? formatspec.sizedinternalformat : formatspec.internalformat;
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, this._width, this._height, 0, formatspec.format, formatspec.type, null);
|
|
this._SetTextureParameters(gl);
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
this._renderer._ResetLastTexture();
|
|
this._refCount = 1;
|
|
allTextures.add(this)
|
|
}
|
|
_GetMipMapHint(gl) {
|
|
if (this._mipMapQuality === "default")
|
|
return this._isStatic ? gl.NICEST : gl.FASTEST;
|
|
else if (this._mipMapQuality === "low")
|
|
return gl.FASTEST;
|
|
else if (this._mipMapQuality === "high")
|
|
return gl.NICEST;
|
|
else
|
|
throw new Error("invalid mipmap quality");
|
|
}
|
|
_IsTiled() {
|
|
return this._wrapX !== "clamp-to-edge" || this._wrapY !== "clamp-to-edge"
|
|
}
|
|
_GetTextureWrapMode(gl, wrapMode) {
|
|
if (wrapMode === "clamp-to-edge")
|
|
return gl.CLAMP_TO_EDGE;
|
|
else if (wrapMode === "repeat")
|
|
return gl.REPEAT;
|
|
else if (wrapMode === "mirror-repeat")
|
|
return gl.MIRRORED_REPEAT;
|
|
else
|
|
throw new Error("invalid wrap mode");
|
|
}
|
|
_SetTextureParameters(gl) {
|
|
const isPOT = C3.isPOT(this._width) && C3.isPOT(this._height);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this._GetTextureWrapMode(gl, this._wrapX));
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this._GetTextureWrapMode(gl, this._wrapY));
|
|
if (this._sampling === "nearest") {
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
this._isMipMapped = false
|
|
} else {
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
if ((isPOT || this._renderer.SupportsNPOTTextures()) && this._isMipMapped) {
|
|
gl.hint(gl.GENERATE_MIPMAP_HINT, this._GetMipMapHint(gl));
|
|
gl.generateMipmap(gl.TEXTURE_2D);
|
|
const useTrilinear = this._sampling === "trilinear" && !this._renderer.HasMajorPerformanceCaveat();
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, useTrilinear ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR_MIPMAP_NEAREST)
|
|
} else {
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
this._isMipMapped = false
|
|
}
|
|
}
|
|
}
|
|
_Update(data, opts) {
|
|
if ((typeof HTMLImageElement === "undefined" || !(data instanceof HTMLImageElement)) && (typeof HTMLVideoElement === "undefined" || !(data instanceof HTMLVideoElement)) && (typeof HTMLCanvasElement === "undefined" || !(data instanceof HTMLCanvasElement)) && (typeof ImageBitmap === "undefined" || !(data instanceof ImageBitmap)) && (typeof OffscreenCanvas === "undefined" || !(data instanceof OffscreenCanvas)) && !(data instanceof ImageData))
|
|
throw new Error("invalid texture source");
|
|
if (!this._texture || this._refCount <= 0)
|
|
throw new Error("texture not created");
|
|
if (this._isStatic)
|
|
throw new Error("cannot update static texture");
|
|
opts = Object.assign({}, UPDATE_DEFAULT_OPTIONS, opts);
|
|
const dataWidth = data.width || data.videoWidth;
|
|
const dataHeight = data.height || data.videoHeight;
|
|
const webglVersion = this._renderer.GetWebGLVersionNumber();
|
|
const gl = this._renderer.GetContext();
|
|
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], opts.premultiplyAlpha);
|
|
gl.pixelStorei(gl["UNPACK_FLIP_Y_WEBGL"], !!opts.flipY);
|
|
const formatspec = GetFormatSpecifiers(this._pixelFormat, gl);
|
|
const internalformat = webglVersion >= 2 ? formatspec.sizedinternalformat : formatspec.internalformat;
|
|
try {
|
|
if (this._width === dataWidth && this._height === dataHeight) {
|
|
const isPOT = C3.isPOT(this._width) && C3.isPOT(this._height);
|
|
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, formatspec.format, formatspec.type, data);
|
|
if ((isPOT || this._renderer.SupportsNPOTTextures()) && this._isMipMapped) {
|
|
gl.hint(gl.GENERATE_MIPMAP_HINT, this._GetMipMapHint(gl));
|
|
gl.generateMipmap(gl.TEXTURE_2D)
|
|
}
|
|
} else {
|
|
this._width = dataWidth;
|
|
this._height = dataHeight;
|
|
const isPOT = C3.isPOT(this._width) && C3.isPOT(this._height);
|
|
if (!this._renderer.SupportsNPOTTextures() && this._IsTiled() && !isPOT)
|
|
throw new Error("non-power-of-two tiled textures not supported");
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, formatspec.format, formatspec.type, data);
|
|
if ((isPOT || this._renderer.SupportsNPOTTextures()) && this._isMipMapped) {
|
|
gl.hint(gl.GENERATE_MIPMAP_HINT, this._GetMipMapHint(gl));
|
|
gl.generateMipmap(gl.TEXTURE_2D)
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error("Error updating WebGL texture: ", e)
|
|
}
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
this._renderer._ResetLastTexture()
|
|
}
|
|
_Delete() {
|
|
if (this._refCount > 0)
|
|
throw new Error("texture still has references");
|
|
if (!this._texture)
|
|
throw new Error("already deleted texture");
|
|
allTextures.delete(this);
|
|
const gl = this._renderer.GetContext();
|
|
gl.deleteTexture(this._texture);
|
|
this._texture = null
|
|
}
|
|
IsValid() {
|
|
return !!this._texture
|
|
}
|
|
_GetTexture() {
|
|
return this._texture
|
|
}
|
|
GetRenderer() {
|
|
return this._renderer
|
|
}
|
|
AddReference() {
|
|
this._refCount++
|
|
}
|
|
SubtractReference() {
|
|
if (this._refCount <= 0)
|
|
throw new Error("no more references");
|
|
this._refCount--
|
|
}
|
|
GetReferenceCount() {
|
|
return this._refCount
|
|
}
|
|
GetWidth() {
|
|
return this._width
|
|
}
|
|
GetHeight() {
|
|
return this._height
|
|
}
|
|
IsStatic() {
|
|
return this._isStatic
|
|
}
|
|
GetEstimatedMemoryUsage() {
|
|
let size = this._width * this._height;
|
|
switch (this._pixelFormat) {
|
|
case "rgba8":
|
|
size *= 4;
|
|
break;
|
|
case "rgb8":
|
|
size *= 3;
|
|
break;
|
|
case "rgba4":
|
|
case "rgb5_a1":
|
|
case "rgb565":
|
|
size *= 2;
|
|
break
|
|
}
|
|
if (this._isMipMapped)
|
|
size += Math.floor(size / 3);
|
|
return size
|
|
}
|
|
static OnContextLost() {
|
|
allTextures.clear()
|
|
}
|
|
static allTextures() {
|
|
return allTextures.values()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
const VALID_SAMPLINGS = new Set(["nearest", "bilinear", "trilinear"]);
|
|
const DEFAULT_RENDERTARGET_OPTIONS = {
|
|
sampling: "trilinear",
|
|
alpha: true,
|
|
readback: true,
|
|
isDefaultSize: true,
|
|
multisampling: 0
|
|
};
|
|
const allRenderTargets = new Set;
|
|
C3.Gfx.WebGLRenderTarget = class WebGLRenderTarget {
|
|
constructor(renderer) {
|
|
this._renderer = renderer;
|
|
this._frameBuffer = null;
|
|
this._texture = null;
|
|
this._renderBuffer = null;
|
|
this._width = 0;
|
|
this._height = 0;
|
|
this._isDefaultSize = true;
|
|
this._sampling = "trilinear";
|
|
this._alpha = true;
|
|
this._readback = true;
|
|
this._multisampling = 0
|
|
}
|
|
_Create(width, height, opts) {
|
|
opts = Object.assign({}, DEFAULT_RENDERTARGET_OPTIONS, opts);
|
|
const webGLVersion = this._renderer.GetWebGLVersionNumber();
|
|
if (this._texture || this._renderBuffer)
|
|
throw new Error("already created render target");
|
|
this._sampling = opts.sampling;
|
|
this._alpha = !!opts.alpha;
|
|
this._readback = !!opts.readback;
|
|
this._isDefaultSize = !!opts.isDefaultSize;
|
|
this._multisampling = opts.multisampling;
|
|
if (!VALID_SAMPLINGS.has(this._sampling))
|
|
throw new Error("invalid sampling");
|
|
if (this._multisampling > 0 && (webGLVersion < 2 || this._readback))
|
|
throw new Error("invalid use of multisampling");
|
|
if (webGLVersion < 2)
|
|
this._readback = true;
|
|
this._width = width;
|
|
this._height = height;
|
|
if (this._width <= 0 || this._height <= 0)
|
|
throw new Error("invalid render target size");
|
|
const gl = this._renderer.GetContext();
|
|
this._frameBuffer = gl.createFramebuffer();
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);
|
|
if (this._readback) {
|
|
this._texture = this._renderer.CreateDynamicTexture(this._width, this._height, {
|
|
sampling: this._sampling,
|
|
pixelFormat: this._alpha ? "rgba8" : "rgb8",
|
|
mipMap: false
|
|
});
|
|
const tex = this._texture._GetTexture();
|
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)
|
|
} else {
|
|
this._renderBuffer = gl.createRenderbuffer();
|
|
gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);
|
|
const internalFormat = this._alpha ? gl.RGBA8 : gl.RGB8;
|
|
if (this._multisampling > 0) {
|
|
const formatSamples = gl.getInternalformatParameter(gl.RENDERBUFFER, internalFormat, gl.SAMPLES);
|
|
if (formatSamples && formatSamples[0]) {
|
|
const maxSamples = formatSamples[0];
|
|
if (this._multisampling > maxSamples)
|
|
this._multisampling = maxSamples
|
|
} else
|
|
this._multisampling = 0
|
|
}
|
|
if (this._multisampling === 0)
|
|
gl.renderbufferStorage(gl.RENDERBUFFER, internalFormat, this._width, this._height);
|
|
else
|
|
gl.renderbufferStorageMultisample(gl.RENDERBUFFER, this._multisampling, internalFormat, this._width, this._height);
|
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this._renderBuffer);
|
|
gl.bindRenderbuffer(gl.RENDERBUFFER, null)
|
|
}
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
allRenderTargets.add(this)
|
|
}
|
|
_Resize(width, height) {
|
|
if (this._width === width && this._height === height)
|
|
return;
|
|
this._width = width;
|
|
this._height = height;
|
|
const gl = this._renderer.GetContext();
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);
|
|
if (this._texture)
|
|
this._texture._Update(new ImageData(this._width,this._height));
|
|
else {
|
|
gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);
|
|
gl.renderbufferStorage(gl.RENDERBUFFER, this._alpha ? gl.RGBA8 : gl.RGB8, this._width, this._height);
|
|
gl.bindRenderbuffer(gl.RENDERBUFFER, null)
|
|
}
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null)
|
|
}
|
|
_Delete() {
|
|
if (!this._texture && !this._renderBuffer)
|
|
throw new Error("already deleted render target");
|
|
allRenderTargets.delete(this);
|
|
const gl = this._renderer.GetContext();
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);
|
|
if (this._texture) {
|
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
|
|
this._renderer.DeleteTexture(this._texture);
|
|
this._texture = null
|
|
} else if (this._renderBuffer) {
|
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
|
|
gl.deleteRenderbuffer(this._renderBuffer);
|
|
this._renderBuffer = null
|
|
}
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
if (this._renderer.GetWebGLVersionNumber() >= 2) {
|
|
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
|
|
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null)
|
|
}
|
|
gl.deleteFramebuffer(this._frameBuffer);
|
|
this._renderer.GetBatchState().currentFramebuffer = null;
|
|
this._frameBuffer = null
|
|
}
|
|
_GetFramebuffer() {
|
|
return this._frameBuffer
|
|
}
|
|
GetWebGLRenderer() {
|
|
return this._renderer
|
|
}
|
|
GetTexture() {
|
|
return this._texture
|
|
}
|
|
IsLinearSampling() {
|
|
return this._sampling !== "nearest"
|
|
}
|
|
HasAlpha() {
|
|
return this._alpha
|
|
}
|
|
IsReadback() {
|
|
return this._readback
|
|
}
|
|
GetWidth() {
|
|
return this._width
|
|
}
|
|
GetHeight() {
|
|
return this._height
|
|
}
|
|
IsDefaultSize() {
|
|
return this._isDefaultSize
|
|
}
|
|
GetMultisampling() {
|
|
return this._multisampling
|
|
}
|
|
GetOptions() {
|
|
const ret = {
|
|
sampling: this._sampling,
|
|
alpha: this._alpha,
|
|
readback: this._readback
|
|
};
|
|
if (!this._isDefaultSize) {
|
|
ret.width = this._width;
|
|
ret.height = this._height
|
|
}
|
|
return ret
|
|
}
|
|
IsCompatibleWithOptions(opts) {
|
|
opts = Object.assign({}, DEFAULT_RENDERTARGET_OPTIONS, opts);
|
|
if (opts.sampling !== "nearest" !== this.IsLinearSampling())
|
|
return false;
|
|
if (!!opts.alpha !== this.HasAlpha())
|
|
return false;
|
|
if (this._renderer.GetWebGLVersionNumber() >= 2)
|
|
if (!!opts.readback !== this.IsReadback())
|
|
return false;
|
|
if (typeof opts.width === "number" || typeof opts.height === "number")
|
|
return !this.IsDefaultSize() && this.GetWidth() === opts.width && this.GetHeight() === opts.height;
|
|
else
|
|
return this.IsDefaultSize()
|
|
}
|
|
_GetWebGLTexture() {
|
|
if (!this._texture)
|
|
return null;
|
|
return this._texture._GetTexture()
|
|
}
|
|
GetEstimatedMemoryUsage() {
|
|
if (this._texture)
|
|
return this._texture.GetEstimatedMemoryUsage();
|
|
return this._width * this._height * (this._alpha ? 4 : 3)
|
|
}
|
|
static async DebugReadPixelsToBlob(renderer, renderTarget) {
|
|
const imageData = await renderer.ReadBackRenderTargetToImageData(renderTarget, true);
|
|
return await C3.ImageDataToBlob(imageData)
|
|
}
|
|
static OnContextLost() {
|
|
allRenderTargets.clear()
|
|
}
|
|
static allRenderTargets() {
|
|
return allRenderTargets.values()
|
|
}
|
|
static ResizeAll(width, height) {
|
|
for (const rt of allRenderTargets)
|
|
if (rt.IsDefaultSize())
|
|
rt._Resize(width, height)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const glMatrix = self.glMatrix;
|
|
const vec3 = glMatrix.vec3;
|
|
const mat4 = glMatrix.mat4;
|
|
const RESERVED_UNIFORM_NAMES = new Set(["aPos", "aTex", "aPoints", "matP", "matMV", "samplerFront", "samplerBack", "destStart", "destEnd", "srcStart", "srcEnd", "srcOriginStart", "srcOriginEnd", "pixelSize", "seconds", "layerScale", "layerAngle", "layoutStart", "layoutEnd", "color", "color2_", "pointTexStart", "pointTexEnd", "zElevation", "tileSize", "tileSpacing", "outlineThickness"]);
|
|
C3.Gfx.WebGLShaderProgram = class WebGLShaderProgram {
|
|
static async Compile(renderer, fragSrc, vsSource, name) {
|
|
const gl = renderer.GetContext();
|
|
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
gl.shaderSource(fragmentShader, fragSrc);
|
|
gl.compileShader(fragmentShader);
|
|
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
gl.shaderSource(vertexShader, vsSource);
|
|
gl.compileShader(vertexShader);
|
|
const shaderProgram = gl.createProgram();
|
|
gl.attachShader(shaderProgram, fragmentShader);
|
|
gl.attachShader(shaderProgram, vertexShader);
|
|
gl.bindAttribLocation(shaderProgram, 0, "aPos");
|
|
gl.bindAttribLocation(shaderProgram, 1, "aTex");
|
|
gl.bindAttribLocation(shaderProgram, 2, "aPoints");
|
|
gl.linkProgram(shaderProgram);
|
|
const parallelShaderCompileExt = renderer._GetParallelShaderCompileExtension();
|
|
if (parallelShaderCompileExt)
|
|
await renderer._WaitForObjectReady(()=>gl.getProgramParameter(shaderProgram, parallelShaderCompileExt["COMPLETION_STATUS_KHR"]));
|
|
else
|
|
await C3.Wait(5);
|
|
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
|
|
const log = gl.getShaderInfoLog(fragmentShader);
|
|
gl.deleteShader(fragmentShader);
|
|
gl.deleteShader(vertexShader);
|
|
gl.deleteProgram(shaderProgram);
|
|
throw new Error("Error compiling fragment shader: " + log);
|
|
}
|
|
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
|
|
const log = gl.getShaderInfoLog(vertexShader);
|
|
gl.deleteShader(fragmentShader);
|
|
gl.deleteShader(vertexShader);
|
|
gl.deleteProgram(shaderProgram);
|
|
throw new Error("Error compiling vertex shader: " + log);
|
|
}
|
|
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
|
|
const log = gl.getProgramInfoLog(shaderProgram);
|
|
gl.deleteShader(fragmentShader);
|
|
gl.deleteShader(vertexShader);
|
|
gl.deleteProgram(shaderProgram);
|
|
throw new Error("Error linking shader program: " + log);
|
|
}
|
|
const infoLog = C3.FilterUnprintableChars(gl.getProgramInfoLog(shaderProgram) || "").trim();
|
|
if (infoLog && !C3.IsStringAllWhitespace(infoLog))
|
|
console.info(`[WebGL] Shader program '${name}' compilation log: `, infoLog);
|
|
gl.deleteShader(fragmentShader);
|
|
gl.deleteShader(vertexShader);
|
|
return shaderProgram
|
|
}
|
|
static async Create(renderer, shaderInfo, vsSource, name) {
|
|
const shaderProgram = await C3.Gfx.WebGLShaderProgram.Compile(renderer, shaderInfo.src, vsSource, name);
|
|
return new C3.Gfx.WebGLShaderProgram(renderer,shaderProgram,shaderInfo,name)
|
|
}
|
|
constructor(renderer, shaderProgram, shaderInfo, name) {
|
|
const gl = renderer.GetContext();
|
|
const batchState = renderer.GetBatchState();
|
|
renderer.EndBatch();
|
|
gl.useProgram(shaderProgram);
|
|
this._gl = gl;
|
|
this._renderer = renderer;
|
|
this._name = name;
|
|
this._shaderProgram = shaderProgram;
|
|
this._isDeviceTransform = name === "<default-device-transform>";
|
|
const locAPos = gl.getAttribLocation(shaderProgram, "aPos");
|
|
const locATex = gl.getAttribLocation(shaderProgram, "aTex");
|
|
const locAPoints = gl.getAttribLocation(shaderProgram, "aPoints");
|
|
if (locAPos !== -1) {
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, renderer._vertexBuffer);
|
|
gl.vertexAttribPointer(locAPos, renderer.GetNumVertexComponents(), gl.FLOAT, false, 0, 0);
|
|
gl.enableVertexAttribArray(locAPos)
|
|
}
|
|
if (locATex !== -1) {
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, renderer._texcoordBuffer);
|
|
gl.vertexAttribPointer(locATex, 2, gl.FLOAT, false, 0, 0);
|
|
gl.enableVertexAttribArray(locATex)
|
|
}
|
|
if (locAPoints !== -1) {
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, renderer._pointBuffer);
|
|
gl.vertexAttribPointer(locAPoints, 4, gl.FLOAT, false, 0, 0);
|
|
gl.enableVertexAttribArray(locAPoints)
|
|
}
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
this._uMatP = new C3.Gfx.WebGLShaderUniform(this,"matP","mat4");
|
|
this._uMatMV = new C3.Gfx.WebGLShaderUniform(this,"matMV","mat4");
|
|
this._uColor = new C3.Gfx.WebGLShaderUniform(this,"color","vec4");
|
|
this._uSamplerFront = new C3.Gfx.WebGLShaderUniform(this,"samplerFront","sampler");
|
|
this._uPointTexStart = new C3.Gfx.WebGLShaderUniform(this,"pointTexStart","vec2");
|
|
this._uPointTexEnd = new C3.Gfx.WebGLShaderUniform(this,"pointTexEnd","vec2");
|
|
this._uZElevation = new C3.Gfx.WebGLShaderUniform(this,"zElevation","float");
|
|
this._uTileSize = new C3.Gfx.WebGLShaderUniform(this,"tileSize","vec2");
|
|
this._uTileSpacing = new C3.Gfx.WebGLShaderUniform(this,"tileSpacing","vec2");
|
|
this._uColor2 = new C3.Gfx.WebGLShaderUniform(this,"color2_","vec4");
|
|
this._uOutlineThickness = new C3.Gfx.WebGLShaderUniform(this,"outlineThickness","float");
|
|
this._uSamplerBack = new C3.Gfx.WebGLShaderUniform(this,"samplerBack","sampler");
|
|
this._uDestStart = new C3.Gfx.WebGLShaderUniform(this,"destStart","vec2");
|
|
this._uDestEnd = new C3.Gfx.WebGLShaderUniform(this,"destEnd","vec2");
|
|
this._uSrcStart = new C3.Gfx.WebGLShaderUniform(this,"srcStart","vec2");
|
|
this._uSrcEnd = new C3.Gfx.WebGLShaderUniform(this,"srcEnd","vec2");
|
|
this._uSrcOriginStart = new C3.Gfx.WebGLShaderUniform(this,"srcOriginStart","vec2");
|
|
this._uSrcOriginEnd = new C3.Gfx.WebGLShaderUniform(this,"srcOriginEnd","vec2");
|
|
this._uPixelSize = new C3.Gfx.WebGLShaderUniform(this,"pixelSize","vec2");
|
|
this._uSeconds = new C3.Gfx.WebGLShaderUniform(this,"seconds","float");
|
|
this._uLayerScale = new C3.Gfx.WebGLShaderUniform(this,"layerScale","float");
|
|
this._uLayerAngle = new C3.Gfx.WebGLShaderUniform(this,"layerAngle","float");
|
|
this._uLayoutStart = new C3.Gfx.WebGLShaderUniform(this,"layoutStart","vec2");
|
|
this._uLayoutEnd = new C3.Gfx.WebGLShaderUniform(this,"layoutEnd","vec2");
|
|
this._hasAnyOptionalUniforms = !!(this._uPixelSize.IsUsed() || this._uSeconds.IsUsed() || this._uSamplerBack.IsUsed() || this._uDestStart.IsUsed() || this._uDestEnd.IsUsed() || this._uSrcStart.IsUsed() || this._uSrcEnd.IsUsed() || this._uSrcOriginStart.IsUsed() || this._uSrcOriginEnd.IsUsed() || this._uLayerScale.IsUsed() || this._uLayerAngle.IsUsed() || this._uLayoutStart.IsUsed() || this._uLayoutEnd.IsUsed());
|
|
this._extendBoxHorizontal = shaderInfo.extendBoxHorizontal || 0;
|
|
this._extendBoxVertical = shaderInfo.extendBoxVertical || 0;
|
|
this._crossSampling = !!shaderInfo.crossSampling;
|
|
this._mustPreDraw = !!shaderInfo.mustPreDraw;
|
|
this._preservesOpaqueness = !!shaderInfo.preservesOpaqueness;
|
|
this._animated = !!shaderInfo.animated;
|
|
const customParameterDefs = shaderInfo.parameters || [];
|
|
this._uCustomParameters = [];
|
|
this._usesDest = this._uDestStart.IsUsed() || this._uDestEnd.IsUsed();
|
|
this._usesAnySrcRectOrPixelSize = this._uPixelSize.IsUsed() || this._uSrcStart.IsUsed() || this._uSrcEnd.IsUsed() || this._uSrcOriginStart.IsUsed() || this._uSrcOriginEnd.IsUsed();
|
|
this._needsPostDrawOrExtendBox = this._crossSampling || this._usesDest || this._extendBoxHorizontal !== 0 || this._extendBoxVertical !== 0;
|
|
this._hasCurrentMatP = false;
|
|
this._hasCurrentMatMV = false;
|
|
this._uColor.Init4f(1, 1, 1, 1);
|
|
this._uColor2.Init4f(1, 1, 1, 1);
|
|
this._uSamplerFront.Init1i(0);
|
|
this._uSamplerBack.Init1i(1);
|
|
this._uPointTexStart.Init2f(0, 0);
|
|
this._uPointTexEnd.Init2f(1, 1);
|
|
this._uZElevation.Init1f(0);
|
|
this._uTileSize.Init2f(0, 0);
|
|
this._uTileSpacing.Init2f(0, 0);
|
|
this._uDestStart.Init2f(0, 0);
|
|
this._uDestEnd.Init2f(1, 1);
|
|
this._uSrcStart.Init2f(0, 0);
|
|
this._uSrcEnd.Init2f(0, 0);
|
|
this._uSrcOriginStart.Init2f(0, 0);
|
|
this._uSrcOriginEnd.Init2f(0, 0);
|
|
this._uPixelSize.Init2f(0, 0);
|
|
this._uLayerScale.Init1f(1);
|
|
this._uLayerAngle.Init1f(0);
|
|
this._uSeconds.Init1f(0);
|
|
this._uLayoutStart.Init2f(0, 0);
|
|
this._uLayoutEnd.Init2f(0, 0);
|
|
this._uOutlineThickness.Init1f(1);
|
|
for (const p of customParameterDefs) {
|
|
const uniformName = p[0];
|
|
const paramType = p[2];
|
|
const shaderUniform = new C3.Gfx.WebGLShaderUniform(this,uniformName,paramType);
|
|
if (paramType === "color")
|
|
shaderUniform.Init3f(0, 0, 0);
|
|
else
|
|
shaderUniform.Init1f(0);
|
|
this._uCustomParameters.push(shaderUniform)
|
|
}
|
|
if (this._isDeviceTransform)
|
|
this._UpdateDeviceTransformUniforms(batchState.currentMatP);
|
|
else {
|
|
this.UpdateMatP(batchState.currentMatP, true);
|
|
this.UpdateMatMV(batchState.currentMV, true)
|
|
}
|
|
const currentShader = batchState.currentShader;
|
|
gl.useProgram(currentShader ? currentShader._shaderProgram : null)
|
|
}
|
|
Release() {
|
|
this._gl.deleteProgram(this._shaderProgram);
|
|
this._shaderProgram = null;
|
|
this._renderer._RemoveShaderProgram(this);
|
|
this._gl = null;
|
|
this._renderer = null
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
GetWebGLContext() {
|
|
return this._gl
|
|
}
|
|
GetShaderProgram() {
|
|
return this._shaderProgram
|
|
}
|
|
UsesDest() {
|
|
return this._usesDest
|
|
}
|
|
UsesCrossSampling() {
|
|
return this._crossSampling
|
|
}
|
|
MustPreDraw() {
|
|
return this._mustPreDraw
|
|
}
|
|
PreservesOpaqueness() {
|
|
return this._preservesOpaqueness
|
|
}
|
|
ExtendsBox() {
|
|
return this._extendBoxHorizontal !== 0 || this._extendBoxVertical !== 0
|
|
}
|
|
GetBoxExtendHorizontal() {
|
|
return this._extendBoxHorizontal
|
|
}
|
|
GetBoxExtendVertical() {
|
|
return this._extendBoxVertical
|
|
}
|
|
UsesAnySrcRectOrPixelSize() {
|
|
return this._usesAnySrcRectOrPixelSize
|
|
}
|
|
NeedsPostDrawOrExtendsBox() {
|
|
return this._needsPostDrawOrExtendBox
|
|
}
|
|
GetParameterCount() {
|
|
return this._uCustomParameters.length
|
|
}
|
|
GetParameterType(paramIndex) {
|
|
return this._uCustomParameters[paramIndex].GetType()
|
|
}
|
|
AreCustomParametersAlreadySetInBatch(params) {
|
|
for (let i = 0, len = params.length; i < len; ++i)
|
|
if (!this._uCustomParameters[i].IsSetToCustomInBatch(params[i]))
|
|
return false;
|
|
return true
|
|
}
|
|
SetCustomParametersInBatch(params) {
|
|
for (let i = 0, len = params.length; i < len; ++i)
|
|
this._uCustomParameters[i].SetBatchValueCustom(params[i])
|
|
}
|
|
AreOptionalUniformsAlreadySetInBatch(destRect, srcRect, srcOriginRect, layoutRect, pixelWidth, pixelHeight, layerScale, layerAngle, time) {
|
|
if (this._uSamplerBack.IsUsed())
|
|
return false;
|
|
if (this._uPixelSize.IsUsed() && !this._uPixelSize.IsSetTo2InBatch(pixelWidth, pixelHeight))
|
|
return false;
|
|
if (this._uDestStart.IsUsed() && !this._uDestStart.IsSetTo2InBatch(destRect.getLeft(), destRect.getTop()))
|
|
return false;
|
|
if (this._uDestEnd.IsUsed() && !this._uDestEnd.IsSetTo2InBatch(destRect.getRight(), destRect.getBottom()))
|
|
return false;
|
|
if (this._uLayerScale.IsUsed() && !this._uLayerScale.IsSetTo1InBatch(layerScale))
|
|
return false;
|
|
if (this._uLayerAngle.IsUsed() && !this._uLayerAngle.IsSetTo1InBatch(layerAngle))
|
|
return false;
|
|
if (this._uSrcStart.IsUsed() && !this._uSrcStart.IsSetTo2InBatch(srcRect.getLeft(), srcRect.getTop()))
|
|
return false;
|
|
if (this._uSrcEnd.IsUsed() && !this._uSrcEnd.IsSetTo2InBatch(srcRect.getRight(), srcRect.getBottom()))
|
|
return false;
|
|
if (this._uSrcOriginStart.IsUsed() && !this._uSrcOriginStart.IsSetTo2InBatch(srcOriginRect.getLeft(), srcOriginRect.getTop()))
|
|
return false;
|
|
if (this._uSrcOriginEnd.IsUsed() && !this._uSrcOriginEnd.IsSetTo2InBatch(srcOriginRect.getRight(), srcOriginRect.getBottom()))
|
|
return false;
|
|
if (this._uLayoutStart.IsUsed() && !this._uLayoutStart.IsSetTo2InBatch(layoutRect.getLeft(), layoutRect.getTop()))
|
|
return false;
|
|
if (this._uLayoutEnd.IsUsed() && !this._uLayoutEnd.IsSetTo2InBatch(layoutRect.getTop(), layoutRect.getBottom()))
|
|
return false;
|
|
if (this._uSeconds.IsUsed() && !this._uSeconds.IsSetTo1InBatch(time))
|
|
return false;
|
|
return true
|
|
}
|
|
SetOptionalUniformsInBatch(destRect, srcRect, srcOriginRect, layoutRect, pixelWidth, pixelHeight, layerScale, layerAngle, time) {
|
|
if (this._uSamplerBack.IsUsed())
|
|
return;
|
|
if (this._uPixelSize.IsUsed())
|
|
this._uPixelSize.SetBatch2(pixelWidth, pixelHeight);
|
|
if (this._uDestStart.IsUsed())
|
|
this._uDestStart.SetBatch2(destRect.getLeft(), destRect.getTop());
|
|
if (this._uDestEnd.IsUsed())
|
|
this._uDestEnd.SetBatch2(destRect.getRight(), destRect.getBottom());
|
|
if (this._uLayerScale.IsUsed())
|
|
this._uLayerScale.SetBatch1(layerScale);
|
|
if (this._uLayerAngle.IsUsed())
|
|
this._uLayerAngle.SetBatch1(layerAngle);
|
|
if (this._uSrcStart.IsUsed())
|
|
this._uSrcStart.SetBatch2(srcRect.getLeft(), srcRect.getTop());
|
|
if (this._uSrcEnd.IsUsed())
|
|
this._uSrcEnd.SetBatch2(srcRect.getRight(), srcRect.getBottom());
|
|
if (this._uSrcOriginStart.IsUsed())
|
|
this._uSrcOriginStart.SetBatch2(srcOriginRect.getLeft(), srcOriginRect.getTop());
|
|
if (this._uSrcOriginEnd.IsUsed())
|
|
this._uSrcOriginEnd.SetBatch2(srcOriginRect.getRight(), srcOriginRect.getBottom());
|
|
if (this._uLayoutStart.IsUsed())
|
|
this._uLayoutStart.SetBatch2(layoutRect.getLeft(), layoutRect.getTop());
|
|
if (this._uLayoutEnd.IsUsed())
|
|
this._uLayoutEnd.SetBatch2(layoutRect.getTop(), layoutRect.getBottom());
|
|
if (this._uSeconds.IsUsed())
|
|
this._uSeconds.SetBatch1(time)
|
|
}
|
|
IsAnimated() {
|
|
return this._animated
|
|
}
|
|
UpdateMatP(matP, force) {
|
|
if (this._hasCurrentMatP && !force)
|
|
return;
|
|
if (this._isDeviceTransform)
|
|
return;
|
|
if (this._uMatP.IsUsed())
|
|
this._uMatP.UpdateMatrix4fv(matP);
|
|
this._hasCurrentMatP = true
|
|
}
|
|
SetMatPStale() {
|
|
this._hasCurrentMatP = false
|
|
}
|
|
UpdateMatMV(matMV, force) {
|
|
if (this._hasCurrentMatMV && !force)
|
|
return;
|
|
if (this._isDeviceTransform)
|
|
return;
|
|
if (this._uMatMV.IsUsed())
|
|
this._uMatMV.UpdateMatrix4fv(matMV);
|
|
this._hasCurrentMatMV = true
|
|
}
|
|
SetMatMVStale() {
|
|
this._hasCurrentMatMV = false
|
|
}
|
|
_UpdateDeviceTransformUniforms(matP) {
|
|
if (!this._isDeviceTransform)
|
|
throw new Error("not device transform shader");
|
|
this._uMatP.UpdateMatrix4fv(matP);
|
|
const renderer = this._renderer;
|
|
const scrollX = renderer.GetWidth() / 2;
|
|
const scrollY = renderer.GetHeight() / 2;
|
|
const worldScale = renderer._worldScale;
|
|
const cam = vec3.fromValues(scrollX * worldScale[0], scrollY * worldScale[1], 100 * self.devicePixelRatio);
|
|
const look = vec3.fromValues(scrollX * worldScale[0], scrollY * worldScale[1], 0);
|
|
const mv = mat4.create();
|
|
mat4.lookAt(mv, cam, look, renderer._up);
|
|
mat4.scale(mv, mv, worldScale);
|
|
this._uMatMV.UpdateMatrix4fv(mv)
|
|
}
|
|
UpdateColor(c) {
|
|
if (this._uColor.IsUsed())
|
|
this._uColor.Update4f(c[0], c[1], c[2], c[3])
|
|
}
|
|
static GetReservedUniformNames() {
|
|
return RESERVED_UNIFORM_NAMES
|
|
}
|
|
static GetDefaultVertexShaderSource(is3d, useHighP) {
|
|
const texPrecision = useHighP ? "highmedp" : "mediump";
|
|
return [`#ifdef GL_FRAGMENT_PRECISION_HIGH`, `#define highmedp highp`, `#else`, `#define highmedp mediump`, `#endif`, `attribute highp ${is3d ? "vec3" : "vec2"} aPos;`, `attribute ${texPrecision} vec2 aTex;`, `varying ${texPrecision} vec2 vTex;`, `uniform highp mat4 matP;`, `uniform highp mat4 matMV;`, `void main(void) {`, ` gl_Position = matP * matMV * vec4(aPos, ${is3d ? "" : "0.0,"} 1.0);`, ` vTex = aTex;`, `}`].join("\n")
|
|
}
|
|
static GetTextureFillFragmentShaderSource() {
|
|
return ["varying mediump vec2 vTex;", "uniform lowp vec4 color;", "uniform lowp sampler2D samplerFront;", "void main(void) {", "\tgl_FragColor = texture2D(samplerFront, vTex) * color;", "}"].join("\n")
|
|
}
|
|
static GetTilemapFragmentShaderSource() {
|
|
return ["#ifdef GL_FRAGMENT_PRECISION_HIGH", "#define highmedp highp", "#else", "#define highmedp mediump", "#endif", "varying highmedp vec2 vTex;", "uniform lowp vec4 color;", "uniform lowp sampler2D samplerFront;", "uniform highmedp vec2 srcStart;", "uniform highmedp vec2 pixelSize;", "uniform highmedp vec2 tileSize;", "uniform highmedp vec2 tileSpacing;", "void main(void) {", "\thighmedp vec2 tile = floor(vTex);", "\thighmedp vec2 tex = fract(vTex);", "\thighmedp vec2 tileOrigin = srcStart + tile * (tileSize + tileSpacing);", "\thighmedp vec2 lowerBound = tileOrigin + pixelSize / 2.0;", "\thighmedp vec2 upperBound = tileOrigin + tileSize - pixelSize / 2.0;", "\tgl_FragColor = texture2D(samplerFront, clamp(tex, lowerBound, upperBound), -16.0) * color;", "}"].join("\n")
|
|
}
|
|
static GetPointVertexShaderSource() {
|
|
return ["attribute vec4 aPoints;", "varying float pointOpacity;", "uniform float zElevation;", "uniform mat4 matP;", "uniform mat4 matMV;", "void main(void) {", "\tgl_Position = matP * matMV * vec4(aPoints.xy, zElevation, 1.0);", "\tgl_PointSize = aPoints.z;", "\tpointOpacity = aPoints.w;", "}"].join("\n")
|
|
}
|
|
static GetPointFragmentShaderSource() {
|
|
return ["uniform lowp sampler2D samplerFront;", "varying lowp float pointOpacity;", "uniform mediump vec2 pointTexStart;", "uniform mediump vec2 pointTexEnd;", "uniform lowp vec4 color;", "void main(void) {", "\tgl_FragColor = texture2D(samplerFront, mix(pointTexStart, pointTexEnd, gl_PointCoord)) * color * pointOpacity;", "}"].join("\n")
|
|
}
|
|
static GetColorFillFragmentShaderSource() {
|
|
return ["uniform lowp vec4 color;", "void main(void) {", "\tgl_FragColor = color;", "}"].join("\n")
|
|
}
|
|
static GetLinearGradientFillFragmentShaderSource() {
|
|
return ["precision lowp float;", "varying mediump vec2 vTex;", "uniform vec4 color;", "uniform vec4 color2_;", "vec3 fromLinear(vec3 linearRGB)", "{", "\tbvec3 cutoff = lessThan(linearRGB, vec3(0.0031308));", "\tvec3 higher = vec3(1.055) * pow(abs(linearRGB), vec3(1.0/2.4)) - vec3(0.055);", "\tvec3 lower = linearRGB * vec3(12.92);", "\treturn mix(higher, lower, vec3(cutoff));", "}", "vec3 toLinear(vec3 sRGB)", "{", "\tbvec3 cutoff = lessThan(sRGB, vec3(0.04045));", "\tvec3 higher = pow(abs((sRGB + vec3(0.055))/vec3(1.055)), vec3(2.4));", "\tvec3 lower = sRGB/vec3(12.92);", "\treturn mix(higher, lower, vec3(cutoff));", "}", "void main(void) {", "\tvec3 linearGrad = mix(toLinear(color.rgb), toLinear(color2_.rgb), vTex.x);", "\tfloat a = mix(color.a, color2_.a, vTex.x);", "\tgl_FragColor = vec4(fromLinear(linearGrad) * a, a);", "}"].join("\n")
|
|
}
|
|
static GetSmoothLineFillFragmentShaderSource() {
|
|
return ["varying mediump vec2 vTex;", "uniform lowp vec4 color;", "void main(void) {", "\tlowp float f = 1.0 - abs(vTex.y - 0.5) * 2.0;", "\tgl_FragColor = color * f;", "}"].join("\n")
|
|
}
|
|
static GetHardEllipseFillFragmentShaderSource() {
|
|
return ["varying mediump vec2 vTex;", "uniform lowp vec4 color;", "void main(void) {", "\tmediump vec2 diff = vTex - vec2(0.5, 0.5);", "\tmediump vec2 diffSq = diff * diff;", "\tmediump float f = step(diffSq.x + diffSq.y, 0.25);", "\tgl_FragColor = color * f;", "}"].join("\n")
|
|
}
|
|
static GetHardEllipseOutlineFragmentShaderSource() {
|
|
return ["varying mediump vec2 vTex;", "uniform lowp vec4 color;", "uniform mediump vec2 pixelSize;", "uniform mediump float outlineThickness;", "void main(void) {", "\tmediump vec2 diff = vTex - vec2(0.5, 0.5);", "\tmediump vec2 diffSq = diff * diff;", "\tmediump float distSq = diffSq.x + diffSq.y;", "\tmediump vec2 norm = normalize(diff);", "\tmediump vec2 halfNorm = norm * 0.5;", "\tmediump float innerF = step(distSq, 0.25);", "\tmediump vec2 innerEdge = halfNorm - pixelSize * norm * outlineThickness;", "\tmediump vec2 innerEdgeSq = innerEdge * innerEdge;", "\tmediump float outerF = step(innerEdgeSq.x + innerEdgeSq.y, distSq);", "\tgl_FragColor = color * innerF * outerF;", "}"].join("\n")
|
|
}
|
|
static GetSmoothEllipseFillFragmentShaderSource() {
|
|
return ["varying mediump vec2 vTex;", "uniform lowp vec4 color;", "uniform mediump vec2 pixelSize;", "void main(void) {", "\tmediump vec2 diff = vTex - vec2(0.5, 0.5);", "\tmediump vec2 diffSq = diff * diff;", "\tmediump vec2 norm = normalize(diff);", "\tmediump vec2 halfNorm = norm * 0.5;", "\tmediump vec2 halfNormSq = halfNorm * halfNorm;", "\tmediump vec2 innerEdge = halfNorm - pixelSize * norm;", "\tmediump vec2 innerEdgeSq = innerEdge * innerEdge;", "\tmediump float f = smoothstep(halfNormSq.x + halfNormSq.y, innerEdgeSq.x + innerEdgeSq.y, diffSq.x + diffSq.y);", "\tgl_FragColor = color * f;", "}"].join("\n")
|
|
}
|
|
static GetSmoothEllipseOutlineFragmentShaderSource() {
|
|
return ["varying mediump vec2 vTex;", "uniform lowp vec4 color;", "uniform mediump vec2 pixelSize;", "uniform mediump float outlineThickness;", "void main(void) {", "\tmediump vec2 diff = vTex - vec2(0.5, 0.5);", "\tmediump vec2 diffSq = diff * diff;", "\tmediump float distSq = diffSq.x + diffSq.y;", "\tmediump vec2 norm = normalize(diff);", "\tmediump vec2 halfNorm = norm * 0.5;", "\tmediump vec2 halfNormSq = halfNorm * halfNorm;", "\tmediump vec2 pxNorm = pixelSize * norm;", "\tmediump vec2 innerEdge1 = halfNorm - pxNorm;", "\tmediump vec2 innerEdge1Sq = innerEdge1 * innerEdge1;", "\tmediump float innerF = smoothstep(halfNormSq.x + halfNormSq.y, innerEdge1Sq.x + innerEdge1Sq.y, distSq);", "\tmediump vec2 innerEdge2 = halfNorm - pxNorm * outlineThickness;", "\tmediump vec2 innerEdge2Sq = innerEdge2 * innerEdge2;", "\tmediump vec2 innerEdge3 = halfNorm - pxNorm * (outlineThickness + 1.0);", "\tmediump vec2 innerEdge3Sq = innerEdge3 * innerEdge3;", "\tmediump float outerF = smoothstep(innerEdge3Sq.x + innerEdge3Sq.y, innerEdge2Sq.x + innerEdge2Sq.y, distSq);", "\tgl_FragColor = color * innerF * outerF;", "}"].join("\n")
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const TYPE_SIZES = new Map([["float", 1], ["percent", 1], ["sampler", 1], ["vec2", 2], ["vec3", 3], ["color", 3], ["vec4", 4], ["mat4", 16]]);
|
|
function areMat4sEqual(a, b) {
|
|
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15]
|
|
}
|
|
C3.Gfx.WebGLShaderUniform = class WebGLShaderUniform {
|
|
constructor(owner, name, type) {
|
|
if (!TYPE_SIZES.has(type))
|
|
throw new Error("invalid uniform type");
|
|
this._owner = owner;
|
|
this._gl = this._owner.GetWebGLContext();
|
|
this._name = name;
|
|
this._type = type;
|
|
this._isColorType = this._type === "color";
|
|
this._location = this._gl.getUniformLocation(this._owner.GetShaderProgram(), name);
|
|
this._isUsed = !!this._location;
|
|
const typeSize = TYPE_SIZES.get(type);
|
|
this._lastValue = new Float32Array(typeSize);
|
|
this._lastBatchValue = new Float32Array(typeSize)
|
|
}
|
|
Release() {
|
|
this._owner = null;
|
|
this._gl = null;
|
|
this._location = null
|
|
}
|
|
IsUsed() {
|
|
return this._isUsed
|
|
}
|
|
GetType() {
|
|
return this._type
|
|
}
|
|
IsColorType() {
|
|
return this._isColorType
|
|
}
|
|
Init1f(v0) {
|
|
if (!this.IsUsed())
|
|
return;
|
|
this._lastValue[0] = v0;
|
|
this._lastBatchValue.set(this._lastValue);
|
|
this._gl.uniform1f(this._location, v0)
|
|
}
|
|
Init1i(v0) {
|
|
if (!this.IsUsed())
|
|
return;
|
|
this._lastValue[0] = v0;
|
|
this._lastBatchValue.set(this._lastValue);
|
|
this._gl.uniform1i(this._location, v0)
|
|
}
|
|
Init2f(v0, v1) {
|
|
if (!this.IsUsed())
|
|
return;
|
|
this._lastValue[0] = v0;
|
|
this._lastValue[1] = v1;
|
|
this._lastBatchValue.set(this._lastValue);
|
|
this._gl.uniform2f(this._location, v0, v1)
|
|
}
|
|
Init3f(v0, v1, v2) {
|
|
if (!this.IsUsed())
|
|
return;
|
|
this._lastValue[0] = v0;
|
|
this._lastValue[1] = v1;
|
|
this._lastValue[2] = v2;
|
|
this._lastBatchValue.set(this._lastValue);
|
|
this._gl.uniform3f(this._location, v0, v1, v2)
|
|
}
|
|
Init4f(v0, v1, v2, v3) {
|
|
if (!this.IsUsed())
|
|
return;
|
|
this._lastValue[0] = v0;
|
|
this._lastValue[1] = v1;
|
|
this._lastValue[2] = v2;
|
|
this._lastValue[3] = v3;
|
|
this._lastBatchValue.set(this._lastValue);
|
|
this._gl.uniform4f(this._location, v0, v1, v2, v3)
|
|
}
|
|
Update1f(v0) {
|
|
v0 = Math.fround(v0);
|
|
const lastValue = this._lastValue;
|
|
if (lastValue[0] === v0)
|
|
return;
|
|
lastValue[0] = v0;
|
|
this._gl.uniform1f(this._location, v0)
|
|
}
|
|
Update1i(v0) {
|
|
const lastValue = this._lastValue;
|
|
if (lastValue[0] === v0)
|
|
return;
|
|
lastValue[0] = v0;
|
|
this._gl.uniform1i(this._location, v0)
|
|
}
|
|
Update2f(v0, v1) {
|
|
v0 = Math.fround(v0);
|
|
v1 = Math.fround(v1);
|
|
const lastValue = this._lastValue;
|
|
if (lastValue[0] === v0 && lastValue[1] === v1)
|
|
return;
|
|
lastValue[0] = v0;
|
|
lastValue[1] = v1;
|
|
this._gl.uniform2f(this._location, v0, v1)
|
|
}
|
|
Update3f(v0, v1, v2) {
|
|
v0 = Math.fround(v0);
|
|
v1 = Math.fround(v1);
|
|
v2 = Math.fround(v2);
|
|
const lastValue = this._lastValue;
|
|
if (lastValue[0] === v0 && lastValue[1] === v1 && lastValue[2] === v2)
|
|
return;
|
|
lastValue[0] = v0;
|
|
lastValue[1] = v1;
|
|
lastValue[2] = v2;
|
|
this._gl.uniform3f(this._location, v0, v1, v2)
|
|
}
|
|
Update4f(v0, v1, v2, v3) {
|
|
v0 = Math.fround(v0);
|
|
v1 = Math.fround(v1);
|
|
v2 = Math.fround(v2);
|
|
v3 = Math.fround(v3);
|
|
const lastValue = this._lastValue;
|
|
if (lastValue[0] === v0 && lastValue[1] === v1 && lastValue[2] === v2 && lastValue[3] === v3)
|
|
return;
|
|
lastValue[0] = v0;
|
|
lastValue[1] = v1;
|
|
lastValue[2] = v2;
|
|
lastValue[3] = v3;
|
|
this._gl.uniform4f(this._location, v0, v1, v2, v3)
|
|
}
|
|
UpdateMatrix4fv(m) {
|
|
const lastValue = this._lastValue;
|
|
if (areMat4sEqual(lastValue, m))
|
|
return;
|
|
C3.typedArraySet16(lastValue, m, 0);
|
|
this._gl.uniformMatrix4fv(this._location, false, m)
|
|
}
|
|
IsSetToCustomInBatch(p) {
|
|
const batchValue = this._lastBatchValue;
|
|
if (this.IsColorType())
|
|
return batchValue[0] === Math.fround(p.getR()) && batchValue[1] === Math.fround(p.getG()) && batchValue[2] === Math.fround(p.getB());
|
|
else
|
|
return batchValue[0] === Math.fround(p)
|
|
}
|
|
SetBatchValueCustom(p) {
|
|
const batchValue = this._lastBatchValue;
|
|
if (this.IsColorType()) {
|
|
batchValue[0] = p.getR();
|
|
batchValue[1] = p.getG();
|
|
batchValue[2] = p.getB()
|
|
} else
|
|
batchValue[0] = p
|
|
}
|
|
IsSetTo1InBatch(x) {
|
|
return this._lastBatchValue[0] === Math.fround(x)
|
|
}
|
|
IsSetTo2InBatch(x, y) {
|
|
const batchValue = this._lastBatchValue;
|
|
return batchValue[0] === Math.fround(x) && batchValue[1] === Math.fround(y)
|
|
}
|
|
SetBatch1(x) {
|
|
this._lastBatchValue[0] = x
|
|
}
|
|
SetBatch2(x, y) {
|
|
const batchValue = this._lastBatchValue;
|
|
batchValue[0] = x;
|
|
batchValue[1] = y
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const glMatrix = self.glMatrix;
|
|
const vec4 = glMatrix.vec4;
|
|
const mat4 = glMatrix.mat4;
|
|
const BATCH_NULL = 0;
|
|
const BATCH_QUAD = 1;
|
|
const BATCH_SETTEXTURE = 2;
|
|
const BATCH_SETCOLOR = 3;
|
|
const BATCH_SETBLEND = 4;
|
|
const BATCH_UPDATEMODELVIEW = 5;
|
|
const BATCH_SETRENDERTARGET = 6;
|
|
const BATCH_CLEARSURFACE = 7;
|
|
const BATCH_CLEARRECT = 8;
|
|
const BATCH_POINTS = 9;
|
|
const BATCH_SETPROGRAM = 10;
|
|
const BATCH_SETPROGRAMPARAMETERS = 11;
|
|
const BATCH_INVALIDATEFRAMEBUFFER = 12;
|
|
const BATCH_SETPOINTTEXCOORDS = 13;
|
|
const BATCH_SETTILEMAPINFO = 14;
|
|
const BATCH_BLITFRAMEBUFFER = 15;
|
|
const BATCH_STARTQUERY = 16;
|
|
const BATCH_ENDQUERY = 17;
|
|
const BATCH_SETELLIPSEPARAMS = 18;
|
|
const BATCH_SETGRADIENTCOLOR = 19;
|
|
C3.Gfx.BatchState = class BatchState {
|
|
constructor(renderer) {
|
|
this.renderer = renderer;
|
|
this.currentMV = mat4.create();
|
|
this.currentMatP = mat4.create();
|
|
this.currentFramebuffer = null;
|
|
this.currentColor = vec4.fromValues(1, 1, 1, 1);
|
|
this.currentShader = null;
|
|
this.pointTexCoords = new C3.Rect;
|
|
this.clearColor = C3.New(C3.Color, 0, 0, 0, 0)
|
|
}
|
|
}
|
|
;
|
|
C3.Gfx.WebGLBatchJob = class WebGLBatchJob {
|
|
constructor(batchState) {
|
|
const arrayBuffer = new ArrayBuffer(96);
|
|
this._type = 0;
|
|
this._batchState = batchState;
|
|
this._gl = batchState.renderer.GetContext();
|
|
this._startIndex = 0;
|
|
this._indexCount = 0;
|
|
this._texParam = null;
|
|
this._mat4param = new Float32Array(arrayBuffer,0,16);
|
|
this._colorParam = new Float32Array(arrayBuffer,64,4);
|
|
this._srcOriginRect = new Float32Array(arrayBuffer,80,4);
|
|
this._shaderParams = []
|
|
}
|
|
InitQuad(startIndex, indexCount) {
|
|
this._type = BATCH_QUAD;
|
|
this._startIndex = startIndex;
|
|
this._indexCount = indexCount
|
|
}
|
|
DoQuad() {
|
|
const gl = this._gl;
|
|
gl.drawElements(gl.TRIANGLES, this._indexCount, gl.UNSIGNED_SHORT, this._startIndex)
|
|
}
|
|
InitSetTexture(rendererTex) {
|
|
this._type = BATCH_SETTEXTURE;
|
|
this._texParam = rendererTex
|
|
}
|
|
DoSetTexture() {
|
|
const gl = this._gl;
|
|
const texParam = this._texParam;
|
|
gl.bindTexture(gl.TEXTURE_2D, texParam ? texParam._GetTexture() : null)
|
|
}
|
|
InitSetColor(c) {
|
|
this._type = BATCH_SETCOLOR;
|
|
c.writeToTypedArray(this._colorParam, 0)
|
|
}
|
|
DoSetColor() {
|
|
const c = this._colorParam;
|
|
const batchState = this._batchState;
|
|
vec4.copy(batchState.currentColor, c);
|
|
batchState.currentShader.UpdateColor(c)
|
|
}
|
|
InitSetGradientColor(c) {
|
|
this._type = BATCH_SETGRADIENTCOLOR;
|
|
c.writeToTypedArray(this._colorParam, 0)
|
|
}
|
|
DoSetGradientColor() {
|
|
const c = this._colorParam;
|
|
const s = this._batchState.currentShader;
|
|
if (s._uColor2.IsUsed())
|
|
s._uColor2.Update4f(c[0], c[1], c[2], c[3])
|
|
}
|
|
InitSetBlend(s, d) {
|
|
this._type = BATCH_SETBLEND;
|
|
this._startIndex = s;
|
|
this._indexCount = d
|
|
}
|
|
DoSetBlend() {
|
|
this._gl.blendFunc(this._startIndex, this._indexCount)
|
|
}
|
|
InitUpdateModelView(m) {
|
|
this._type = BATCH_UPDATEMODELVIEW;
|
|
mat4.copy(this._mat4param, m)
|
|
}
|
|
DoUpdateModelView() {
|
|
const batchState = this._batchState;
|
|
const allShaderPrograms = batchState.renderer._allShaderPrograms;
|
|
const currentShader = batchState.currentShader;
|
|
const mat4param = this._mat4param;
|
|
for (let i = 0, len = allShaderPrograms.length; i < len; ++i) {
|
|
const s = allShaderPrograms[i];
|
|
if (s === currentShader)
|
|
s.UpdateMatMV(mat4param, true);
|
|
else
|
|
s.SetMatMVStale()
|
|
}
|
|
mat4.copy(batchState.currentMV, mat4param)
|
|
}
|
|
InitSetRenderTarget(renderTarget, didSurfaceSizeChange, matP) {
|
|
this._type = BATCH_SETRENDERTARGET;
|
|
this._texParam = renderTarget;
|
|
this._startIndex = didSurfaceSizeChange ? 1 : 0;
|
|
if (didSurfaceSizeChange)
|
|
mat4.copy(this._mat4param, matP)
|
|
}
|
|
DoSetRenderTarget() {
|
|
const gl = this._gl;
|
|
const renderTarget = this._texParam;
|
|
const didSurfaceSizeChange = this._startIndex !== 0;
|
|
const matP = this._mat4param;
|
|
const batchState = this._batchState;
|
|
const renderer = batchState.renderer;
|
|
let newViewportWidth, newViewportHeight;
|
|
if (renderTarget) {
|
|
const fbo = renderTarget._GetFramebuffer();
|
|
batchState.currentFramebuffer = fbo;
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
|
newViewportWidth = renderTarget.GetWidth();
|
|
newViewportHeight = renderTarget.GetHeight()
|
|
} else {
|
|
batchState.currentFramebuffer = null;
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
newViewportWidth = renderer.GetScissoredViewportWidth();
|
|
newViewportHeight = renderer.GetScissoredViewportHeight()
|
|
}
|
|
if (didSurfaceSizeChange)
|
|
renderer._UpdateViewportBatch(newViewportWidth, newViewportHeight, matP)
|
|
}
|
|
InitClearSurface(c) {
|
|
this._type = BATCH_CLEARSURFACE;
|
|
c.writeToTypedArray(this._mat4param, 0)
|
|
}
|
|
InitClearSurface2(r, g, b, a) {
|
|
this._type = BATCH_CLEARSURFACE;
|
|
const c = this._mat4param;
|
|
c[0] = r;
|
|
c[1] = g;
|
|
c[2] = b;
|
|
c[3] = a
|
|
}
|
|
DoClearSurface() {
|
|
const gl = this._gl;
|
|
const mat4param = this._mat4param;
|
|
const batchState = this._batchState;
|
|
const renderer = batchState.renderer;
|
|
const lastClearColor = batchState.clearColor;
|
|
const debugSkipScissor = renderer._isScissorViewport && C3.isDebug;
|
|
if (debugSkipScissor)
|
|
gl.disable(gl.SCISSOR_TEST);
|
|
const r = mat4param[0];
|
|
const g = mat4param[1];
|
|
const b = mat4param[2];
|
|
const a = mat4param[3];
|
|
if (!lastClearColor.equalsRgba(r, g, b, a)) {
|
|
gl.clearColor(r, g, b, a);
|
|
lastClearColor.setRgba(r, g, b, a)
|
|
}
|
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
if (debugSkipScissor)
|
|
gl.enable(gl.SCISSOR_TEST)
|
|
}
|
|
InitClearRect(x, y, w, h, r, g, b, a) {
|
|
this._type = BATCH_CLEARRECT;
|
|
const m = this._mat4param;
|
|
m[0] = x;
|
|
m[1] = y;
|
|
m[2] = w;
|
|
m[3] = h;
|
|
m[4] = r;
|
|
m[5] = g;
|
|
m[6] = b;
|
|
m[7] = a
|
|
}
|
|
DoClearRectangle() {
|
|
const gl = this._gl;
|
|
const mat4param = this._mat4param;
|
|
const batchState = this._batchState;
|
|
const renderer = batchState.renderer;
|
|
const lastClearColor = batchState.clearColor;
|
|
if (!renderer._isScissorViewport)
|
|
gl.enable(gl.SCISSOR_TEST);
|
|
gl.scissor(mat4param[0], mat4param[1], mat4param[2], mat4param[3]);
|
|
const r = mat4param[4];
|
|
const g = mat4param[5];
|
|
const b = mat4param[6];
|
|
const a = mat4param[7];
|
|
if (!lastClearColor.equalsRgba(r, g, b, a)) {
|
|
gl.clearColor(r, g, b, a);
|
|
lastClearColor.setRgba(r, g, b, a)
|
|
}
|
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
if (!renderer._isScissorViewport)
|
|
gl.disable(gl.SCISSOR_TEST);
|
|
else
|
|
gl.scissor(0, 0, renderer._viewportScissorWidth, renderer._viewportScissorHeight)
|
|
}
|
|
InitSetPointTexCoords(rect) {
|
|
this._type = BATCH_SETPOINTTEXCOORDS;
|
|
rect.writeToTypedArray(this._mat4param, 0)
|
|
}
|
|
DoSetPointTextureCoords() {
|
|
const mat4param = this._mat4param;
|
|
this._batchState.pointTexCoords.set(mat4param[0], mat4param[1], mat4param[2], mat4param[3])
|
|
}
|
|
InitPoints(startIndex, z) {
|
|
this._type = BATCH_POINTS;
|
|
this._startIndex = startIndex;
|
|
this._indexCount = 1;
|
|
this._mat4param[0] = z
|
|
}
|
|
DoPoints() {
|
|
const gl = this._gl;
|
|
const batchState = this._batchState;
|
|
const renderer = batchState.renderer;
|
|
const s = renderer._spPoints;
|
|
gl.useProgram(s._shaderProgram);
|
|
s.UpdateMatP(batchState.currentMatP, false);
|
|
s.UpdateMatMV(batchState.currentMV, false);
|
|
const ptc = batchState.pointTexCoords;
|
|
if (s._uPointTexStart.IsUsed())
|
|
s._uPointTexStart.Update2f(ptc.getLeft(), ptc.getTop());
|
|
if (s._uPointTexEnd.IsUsed())
|
|
s._uPointTexEnd.Update2f(ptc.getRight(), ptc.getBottom());
|
|
const z = this._mat4param[0];
|
|
if (s._uZElevation.IsUsed())
|
|
s._uZElevation.Update1f(z);
|
|
if (s._uColor.IsUsed()) {
|
|
const c = batchState.currentColor;
|
|
s._uColor.Update4f(c[0], c[1], c[2], c[3])
|
|
}
|
|
gl.drawArrays(gl.POINTS, this._startIndex / 4, this._indexCount);
|
|
gl.useProgram(batchState.currentShader._shaderProgram)
|
|
}
|
|
InitSetProgram(program) {
|
|
this._type = BATCH_SETPROGRAM;
|
|
this._texParam = program
|
|
}
|
|
DoSetProgram() {
|
|
const gl = this._gl;
|
|
const batchState = this._batchState;
|
|
const s = this._texParam;
|
|
batchState.currentShader = s;
|
|
gl.useProgram(s._shaderProgram);
|
|
s.UpdateMatP(batchState.currentMatP, false);
|
|
s.UpdateMatMV(batchState.currentMV, false);
|
|
if (s._uColor.IsUsed()) {
|
|
const c = batchState.currentColor;
|
|
s._uColor.Update4f(c[0], c[1], c[2], c[3])
|
|
}
|
|
}
|
|
InitSetProgramParameters() {
|
|
this._type = BATCH_SETPROGRAMPARAMETERS
|
|
}
|
|
DoSetProgramParameters() {
|
|
const s = this._batchState.currentShader;
|
|
if (s._hasAnyOptionalUniforms)
|
|
this._DoSetOptionalUniformProgramParameters(s);
|
|
if (s._uCustomParameters.length)
|
|
this._DoUpdateCustomProgramParameters(s)
|
|
}
|
|
_DoSetOptionalUniformProgramParameters(s) {
|
|
const gl = this._gl;
|
|
const mat4param = this._mat4param;
|
|
const colorParam = this._colorParam;
|
|
const srcOriginRect = this._srcOriginRect;
|
|
if (s._uSamplerBack.IsUsed()) {
|
|
const renderer = this._batchState.renderer;
|
|
const texParam = this._texParam;
|
|
if (renderer._lastTexture1 !== texParam) {
|
|
gl.activeTexture(gl.TEXTURE1);
|
|
gl.bindTexture(gl.TEXTURE_2D, texParam ? texParam._GetTexture() : null);
|
|
renderer._lastTexture1 = texParam;
|
|
gl.activeTexture(gl.TEXTURE0)
|
|
}
|
|
}
|
|
if (s._uPixelSize.IsUsed())
|
|
s._uPixelSize.Update2f(mat4param[0], mat4param[1]);
|
|
if (s._uDestStart.IsUsed())
|
|
s._uDestStart.Update2f(mat4param[2], mat4param[3]);
|
|
if (s._uDestEnd.IsUsed())
|
|
s._uDestEnd.Update2f(mat4param[4], mat4param[5]);
|
|
if (s._uLayerScale.IsUsed())
|
|
s._uLayerScale.Update1f(mat4param[6]);
|
|
if (s._uLayerAngle.IsUsed())
|
|
s._uLayerAngle.Update1f(mat4param[7]);
|
|
if (s._uSrcStart.IsUsed())
|
|
s._uSrcStart.Update2f(mat4param[12], mat4param[13]);
|
|
if (s._uSrcEnd.IsUsed())
|
|
s._uSrcEnd.Update2f(mat4param[14], mat4param[15]);
|
|
if (s._uSrcOriginStart.IsUsed())
|
|
s._uSrcOriginStart.Update2f(srcOriginRect[0], srcOriginRect[1]);
|
|
if (s._uSrcOriginEnd.IsUsed())
|
|
s._uSrcOriginEnd.Update2f(srcOriginRect[2], srcOriginRect[3]);
|
|
if (s._uLayoutStart.IsUsed())
|
|
s._uLayoutStart.Update2f(colorParam[0], colorParam[1]);
|
|
if (s._uLayoutEnd.IsUsed())
|
|
s._uLayoutEnd.Update2f(colorParam[2], colorParam[3]);
|
|
if (s._uSeconds.IsUsed())
|
|
s._uSeconds.Update1f(this._startIndex)
|
|
}
|
|
_DoUpdateCustomProgramParameters(s) {
|
|
const uCustomParameters = s._uCustomParameters;
|
|
const shaderParams = this._shaderParams;
|
|
for (let i = 0, len = uCustomParameters.length; i < len; ++i) {
|
|
const shaderUniform = uCustomParameters[i];
|
|
const paramValue = shaderParams[i];
|
|
if (shaderUniform.IsColorType())
|
|
shaderUniform.Update3f(paramValue.getR(), paramValue.getG(), paramValue.getB());
|
|
else
|
|
shaderUniform.Update1f(paramValue)
|
|
}
|
|
}
|
|
InitInvalidateFramebuffer(fbo) {
|
|
this._type = BATCH_INVALIDATEFRAMEBUFFER;
|
|
this._texParam = fbo
|
|
}
|
|
DoInvalidateFramebuffer() {
|
|
const gl = this._gl;
|
|
const fbo = this._texParam;
|
|
const lastBoundFbo = this._batchState.currentFramebuffer;
|
|
if (fbo !== lastBoundFbo)
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
|
gl.invalidateFramebuffer(gl.FRAMEBUFFER, [gl.COLOR_ATTACHMENT0]);
|
|
if (fbo !== lastBoundFbo)
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, lastBoundFbo)
|
|
}
|
|
InitBlitFramebuffer(sourceRenderTarget, destRenderTarget, mode) {
|
|
this._type = BATCH_BLITFRAMEBUFFER;
|
|
const mat4param = this._mat4param;
|
|
const renderer = this._batchState.renderer;
|
|
mat4param[0] = sourceRenderTarget.GetWidth();
|
|
mat4param[1] = sourceRenderTarget.GetHeight();
|
|
mat4param[2] = destRenderTarget ? destRenderTarget.GetWidth() : renderer.GetWidth();
|
|
mat4param[3] = destRenderTarget ? destRenderTarget.GetHeight() : renderer.GetHeight();
|
|
mat4param[4] = sourceRenderTarget.IsLinearSampling() ? 1 : 0;
|
|
mat4param[5] = mode === "stretch";
|
|
const shaderParams = this._shaderParams;
|
|
C3.clearArray(shaderParams);
|
|
shaderParams.push(sourceRenderTarget._GetFramebuffer());
|
|
shaderParams.push(destRenderTarget ? destRenderTarget._GetFramebuffer() : null)
|
|
}
|
|
DoBlitFramebuffer() {
|
|
const mat4param = this._mat4param;
|
|
const shaderParams = this._shaderParams;
|
|
const gl = this._gl;
|
|
const srcWidth = mat4param[0];
|
|
const srcHeight = mat4param[1];
|
|
const destWidth = mat4param[2];
|
|
const destHeight = mat4param[3];
|
|
const isLinearSampling = mat4param[4] !== 0;
|
|
const isStretch = mat4param[5] !== 0;
|
|
const srcFbo = shaderParams[0];
|
|
const destFbo = shaderParams[1];
|
|
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFbo);
|
|
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, destFbo);
|
|
if (isStretch)
|
|
gl.blitFramebuffer(0, 0, srcWidth, srcHeight, 0, 0, destWidth, destHeight, gl.COLOR_BUFFER_BIT, isLinearSampling ? gl.LINEAR : gl.NEAREST);
|
|
else {
|
|
const w = Math.min(srcWidth, destWidth);
|
|
const h = Math.min(srcHeight, destHeight);
|
|
const srcOffY = Math.max(srcHeight - destHeight, 0);
|
|
const destOffY = Math.max(destHeight - srcHeight, 0);
|
|
gl.blitFramebuffer(0, srcOffY, w, h + srcOffY, 0, destOffY, w, h + destOffY, gl.COLOR_BUFFER_BIT, gl.NEAREST)
|
|
}
|
|
}
|
|
InitStartQuery(query) {
|
|
this._type = BATCH_STARTQUERY;
|
|
this._texParam = query
|
|
}
|
|
DoStartQuery() {
|
|
this._texParam.BeginTimeElapsed();
|
|
this._texParam = null
|
|
}
|
|
InitEndQuery(query) {
|
|
this._type = BATCH_ENDQUERY;
|
|
this._texParam = query
|
|
}
|
|
DoEndQuery() {
|
|
this._texParam.EndTimeElapsed();
|
|
this._texParam = null
|
|
}
|
|
InitSetEllipseParams(pixelW, pixelH, outlineThickness) {
|
|
this._type = BATCH_SETELLIPSEPARAMS;
|
|
const mat4param = this._mat4param;
|
|
mat4param[0] = pixelW;
|
|
mat4param[1] = pixelH;
|
|
mat4param[2] = outlineThickness
|
|
}
|
|
DoSetEllipseParams() {
|
|
const s = this._batchState.currentShader;
|
|
const mat4param = this._mat4param;
|
|
if (s._uPixelSize.IsUsed())
|
|
s._uPixelSize.Update2f(mat4param[0], mat4param[1]);
|
|
if (s._uOutlineThickness.IsUsed())
|
|
s._uOutlineThickness.Update1f(mat4param[2])
|
|
}
|
|
InitSetTilemapInfo(srcRect, textureWidth, textureHeight, tileWidth, tileHeight, tileSpacingX, tileSpacingY) {
|
|
this._type = BATCH_SETTILEMAPINFO;
|
|
const mat4param = this._mat4param;
|
|
srcRect.writeToTypedArray(mat4param, 0);
|
|
mat4param[4] = 1 / textureWidth;
|
|
mat4param[5] = 1 / textureHeight;
|
|
mat4param[6] = tileWidth / textureWidth;
|
|
mat4param[7] = tileHeight / textureHeight;
|
|
mat4param[8] = tileSpacingX / textureWidth;
|
|
mat4param[9] = tileSpacingY / textureHeight
|
|
}
|
|
DoSetTilemapInfo() {
|
|
const s = this._batchState.currentShader;
|
|
const mat4param = this._mat4param;
|
|
if (s._uSrcStart.IsUsed())
|
|
s._uSrcStart.Update2f(mat4param[0], mat4param[1]);
|
|
if (s._uPixelSize.IsUsed())
|
|
s._uPixelSize.Update2f(mat4param[4], mat4param[5]);
|
|
if (s._uTileSize.IsUsed())
|
|
s._uTileSize.Update2f(mat4param[6], mat4param[7]);
|
|
if (s._uTileSpacing.IsUsed())
|
|
s._uTileSpacing.Update2f(mat4param[8], mat4param[9])
|
|
}
|
|
Run() {
|
|
switch (this._type) {
|
|
case 1:
|
|
this.DoQuad();
|
|
return;
|
|
case 2:
|
|
this.DoSetTexture();
|
|
return;
|
|
case 3:
|
|
this.DoSetColor();
|
|
return;
|
|
case 4:
|
|
this.DoSetBlend();
|
|
return;
|
|
case 5:
|
|
this.DoUpdateModelView();
|
|
return;
|
|
case 6:
|
|
this.DoSetRenderTarget();
|
|
return;
|
|
case 7:
|
|
this.DoClearSurface();
|
|
return;
|
|
case 8:
|
|
this.DoClearRectangle();
|
|
return;
|
|
case 9:
|
|
this.DoPoints();
|
|
return;
|
|
case 10:
|
|
this.DoSetProgram();
|
|
return;
|
|
case 11:
|
|
this.DoSetProgramParameters();
|
|
return;
|
|
case 12:
|
|
this.DoInvalidateFramebuffer();
|
|
return;
|
|
case 13:
|
|
this.DoSetPointTextureCoords();
|
|
return;
|
|
case 14:
|
|
this.DoSetTilemapInfo();
|
|
return;
|
|
case 15:
|
|
this.DoBlitFramebuffer();
|
|
return;
|
|
case 16:
|
|
this.DoStartQuery();
|
|
return;
|
|
case 17:
|
|
this.DoEndQuery();
|
|
return;
|
|
case 18:
|
|
this.DoSetEllipseParams();
|
|
return;
|
|
case 19:
|
|
this.DoSetGradientColor();
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const MAX_TEXTURE_SIZE = 2048;
|
|
const EXTRA_LINE_HEIGHT = 4;
|
|
const DEFAULT_OPTS = {
|
|
timeout: 60
|
|
};
|
|
const tempColor = new C3.Color(0,0,0,1);
|
|
const VALID_HORIZ_ALIGNMENTS = new Set(["left", "center", "right"]);
|
|
const VALID_VERT_ALIGNMENTS = new Set(["top", "center", "bottom"]);
|
|
const VALID_WORD_WRAP_MODES = new Set(["word", "character"]);
|
|
const allRendererTexts = new Set;
|
|
if (C3.FontManager)
|
|
C3.FontManager.addEventListener("fontload", e=>{
|
|
const fontName = e.font.GetName();
|
|
for (const f of allRendererTexts)
|
|
if (f.IsBBCodeEnabled() || C3.equalsNoCase(f.GetFontName(), fontName))
|
|
f._SetTextChanged()
|
|
}
|
|
);
|
|
function fillOrStrokeText(ctx, isStroke, text, x, y, maxWidth) {
|
|
if (isStroke)
|
|
if (C3.Platform.BrowserEngine === "Gecko")
|
|
ctx.strokeText(text, x, y, maxWidth);
|
|
else
|
|
ctx.strokeText(text, x, y);
|
|
else if (C3.Platform.BrowserEngine === "Gecko")
|
|
ctx.fillText(text, x, y, maxWidth);
|
|
else
|
|
ctx.fillText(text, x, y)
|
|
}
|
|
function fillOrStrokeRect(ctx, isStroke, x, y, w, h) {
|
|
if (isStroke)
|
|
ctx.strokeRect(x, y, w, h);
|
|
else
|
|
ctx.fillRect(x, y, w, h)
|
|
}
|
|
function ptToPx(pt) {
|
|
return pt * (4 / 3)
|
|
}
|
|
C3.Gfx.RendererText = class RendererText {
|
|
constructor(renderer, opts) {
|
|
opts = Object.assign({}, DEFAULT_OPTS, opts);
|
|
this._renderer = renderer;
|
|
this._fontName = "Arial";
|
|
this._fontSize = 16;
|
|
this._lineHeight = 0;
|
|
this._isBold = false;
|
|
this._isItalic = false;
|
|
this._colorStr = "black";
|
|
this._isBBcodeEnabled = false;
|
|
this.onloadfont = null;
|
|
this._alreadyLoadedFonts = new Set;
|
|
this._horizontalAlign = "left";
|
|
this._verticalAlign = "top";
|
|
this._text = "";
|
|
this._bbString = null;
|
|
this._wrappedText = C3.New(C3.WordWrap);
|
|
this._wrapMode = "word";
|
|
this._textChanged = false;
|
|
this._isUpdating = false;
|
|
this._isAsync = true;
|
|
this._drawMaxCharCount = -1;
|
|
this._drawCharCount = 0;
|
|
this._cssWidth = 0;
|
|
this._cssHeight = 0;
|
|
this._width = 0;
|
|
this._height = 0;
|
|
this._zoom = 1;
|
|
this._changed = false;
|
|
this._textCanvas = null;
|
|
this._textContext = null;
|
|
this._measureContext = null;
|
|
this._lastCanvasWidth = -1;
|
|
this._lastCanvasHeight = -1;
|
|
this._lastTextCanvasFont = "";
|
|
this._lastMeasureCanvasFont = "";
|
|
this._lastTextCanvasFillStyle = "";
|
|
this._lastTextCanvasOpacity = 1;
|
|
this._lastTextCanvasLineWidth = 1;
|
|
this._measureTextCallback = (text,styles)=>this._MeasureText(text, styles);
|
|
this._texture = null;
|
|
this._textureWidth = 0;
|
|
this._textureHeight = 0;
|
|
this._rcTex = new C3.Rect;
|
|
this._scaleFactor = 1;
|
|
this._needToRecreateTexture = false;
|
|
this._textureTimeout = new C3.IdleTimeout(()=>{
|
|
this.ReleaseTexture();
|
|
this._SetTextCanvasSize(8, 8)
|
|
}
|
|
,opts.timeout);
|
|
this.ontextureupdate = null;
|
|
this._wasReleased = false;
|
|
allRendererTexts.add(this)
|
|
}
|
|
Release() {
|
|
this.onloadfont = null;
|
|
this._alreadyLoadedFonts.clear();
|
|
this._bbString = null;
|
|
this._textCanvas = null;
|
|
this._textContext = null;
|
|
this._measureContext = null;
|
|
this._measureTextCallback = null;
|
|
this._textureTimeout.Release();
|
|
this.ontextureupdate = null;
|
|
this.ReleaseTexture();
|
|
this._wrappedText.Clear();
|
|
this._wrappedText = null;
|
|
this._renderer = null;
|
|
this._wasReleased = true;
|
|
allRendererTexts.delete(this)
|
|
}
|
|
_SetChanged() {
|
|
this._changed = true
|
|
}
|
|
_SetTextChanged() {
|
|
this._SetChanged();
|
|
this._wrappedText.Clear();
|
|
this._textChanged = true
|
|
}
|
|
SetIsAsync(a) {
|
|
this._isAsync = !!a
|
|
}
|
|
IsAsync() {
|
|
return this._isAsync
|
|
}
|
|
SetBBCodeEnabled(e) {
|
|
e = !!e;
|
|
if (this._isBBcodeEnabled === e)
|
|
return;
|
|
this._isBBcodeEnabled = e;
|
|
if (this._textContext)
|
|
this._textContext.textBaseline = this._isBBcodeEnabled ? "alphabetic" : "top";
|
|
this._SetTextChanged()
|
|
}
|
|
IsBBCodeEnabled() {
|
|
return this._isBBcodeEnabled
|
|
}
|
|
SetFontName(fontName) {
|
|
if (!fontName)
|
|
fontName = "serif";
|
|
if (this._fontName === fontName)
|
|
return;
|
|
this._fontName = fontName;
|
|
this._SetTextChanged()
|
|
}
|
|
GetFontName() {
|
|
return this._fontName
|
|
}
|
|
SetFontSize(fontSize) {
|
|
if (fontSize < .1)
|
|
fontSize = .1;
|
|
if (this._fontSize === fontSize)
|
|
return;
|
|
this._fontSize = fontSize;
|
|
this._SetTextChanged()
|
|
}
|
|
SetLineHeight(h) {
|
|
if (this._lineHeight === h)
|
|
return;
|
|
this._lineHeight = h;
|
|
this._SetChanged()
|
|
}
|
|
SetBold(bold) {
|
|
bold = !!bold;
|
|
if (this._isBold === bold)
|
|
return;
|
|
this._isBold = bold;
|
|
this._SetTextChanged()
|
|
}
|
|
SetItalic(italic) {
|
|
italic = !!italic;
|
|
if (this._isItalic === italic)
|
|
return;
|
|
this._isItalic = italic;
|
|
this._SetTextChanged()
|
|
}
|
|
SetDrawMaxCharacterCount(n) {
|
|
n = Math.floor(n);
|
|
if (this._drawMaxCharCount === n)
|
|
return;
|
|
this._drawMaxCharCount = n;
|
|
this._SetChanged()
|
|
}
|
|
GetDrawMaxCharacterCount() {
|
|
return this._drawMaxCharCount
|
|
}
|
|
_GetStyleTag(styles, tag) {
|
|
for (let i = styles.length - 1; i >= 0; --i) {
|
|
const s = styles[i];
|
|
if (s.tag === tag)
|
|
return s
|
|
}
|
|
return null
|
|
}
|
|
_HasStyleTag(styles, tag) {
|
|
return !!this._GetStyleTag(styles, tag)
|
|
}
|
|
_GetFontString(useCssUnits, styles) {
|
|
let ret = "";
|
|
if (this._isBold || this._HasStyleTag(styles, "b"))
|
|
ret += "bold";
|
|
if (this._isItalic || this._HasStyleTag(styles, "i"))
|
|
ret += " italic";
|
|
const sizeStyle = this._GetStyleTag(styles, "size");
|
|
const fontSize = sizeStyle ? parseFloat(sizeStyle.param) : this._fontSize;
|
|
if (useCssUnits)
|
|
ret += " " + fontSize + "pt";
|
|
else
|
|
ret += " " + fontSize * this._scaleFactor * this._zoom * self.devicePixelRatio + "pt";
|
|
let fontName = this._fontName;
|
|
const fontStyle = this._GetStyleTag(styles, "font");
|
|
if (fontStyle && fontStyle.param) {
|
|
fontName = fontStyle.param;
|
|
if (this.onloadfont && !this._alreadyLoadedFonts.has(fontName)) {
|
|
this.onloadfont(fontName);
|
|
this._alreadyLoadedFonts.add(fontName)
|
|
}
|
|
}
|
|
if (fontName)
|
|
ret += ' "' + fontName + '"';
|
|
return ret
|
|
}
|
|
SetColor(c) {
|
|
if (c instanceof C3.Color)
|
|
c = c.getCssRgb();
|
|
if (this._colorStr === c)
|
|
return;
|
|
this._colorStr = c;
|
|
this._SetChanged()
|
|
}
|
|
SetColorRgb(r, g, b) {
|
|
tempColor.setRgb(r, g, b);
|
|
this.SetColor(tempColor)
|
|
}
|
|
SetHorizontalAlignment(h) {
|
|
if (!VALID_HORIZ_ALIGNMENTS.has(h))
|
|
throw new Error("invalid horizontal alignment");
|
|
if (this._horizontalAlign === h)
|
|
return;
|
|
this._horizontalAlign = h;
|
|
this._SetChanged()
|
|
}
|
|
SetVerticalAlignment(v) {
|
|
if (!VALID_VERT_ALIGNMENTS.has(v))
|
|
throw new Error("invalid vertical alignment");
|
|
if (this._verticalAlign === v)
|
|
return;
|
|
this._verticalAlign = v;
|
|
this._SetChanged()
|
|
}
|
|
SetWordWrapMode(m) {
|
|
if (!VALID_WORD_WRAP_MODES.has(m))
|
|
throw new Error("invalid word wrap mode");
|
|
if (this._wrapMode === m)
|
|
return;
|
|
this._wrapMode = m;
|
|
this._SetTextChanged()
|
|
}
|
|
SetText(text) {
|
|
if (this._text === text)
|
|
return;
|
|
this._text = text;
|
|
this._SetTextChanged()
|
|
}
|
|
SetSize(cssWidth, cssHeight, zoom) {
|
|
if (typeof zoom === "undefined")
|
|
zoom = 1;
|
|
if (cssWidth <= 0 || cssWidth <= 0)
|
|
return;
|
|
if (this._cssWidth === cssWidth && this._cssHeight === cssHeight && this._zoom === zoom)
|
|
return;
|
|
if (this._zoom === 1 !== (zoom === 1))
|
|
this._needToRecreateTexture = true;
|
|
const oldCssWidth = this._cssWidth;
|
|
const oldZoom = this._zoom;
|
|
this._cssWidth = cssWidth;
|
|
this._cssHeight = cssHeight;
|
|
this._zoom = zoom;
|
|
const dpr = self.devicePixelRatio;
|
|
this._width = this._cssWidth * this._zoom * dpr;
|
|
this._height = this._cssHeight * this._zoom * dpr;
|
|
const maxDim = Math.max(this._width, this._height);
|
|
const maxTextureSize = Math.min(this._renderer.GetMaxTextureSize(), MAX_TEXTURE_SIZE);
|
|
let scale = 1;
|
|
if (maxDim > maxTextureSize) {
|
|
scale = maxTextureSize / maxDim;
|
|
this._width = Math.min(this._width * scale, maxTextureSize);
|
|
this._height = Math.min(this._height * scale, maxTextureSize)
|
|
}
|
|
this._scaleFactor = scale;
|
|
if (this._textureWidth > 0 && this._textureHeight > 0 && this._zoom === oldZoom)
|
|
this._rcTex.set(0, 0, this._width / this._textureWidth, this._height / this._textureHeight);
|
|
if (this._cssWidth !== oldCssWidth)
|
|
this._SetTextChanged();
|
|
else
|
|
this._SetChanged()
|
|
}
|
|
GetWidth() {
|
|
return this._width
|
|
}
|
|
GetHeight() {
|
|
return this._height
|
|
}
|
|
GetTextWidth() {
|
|
this._MaybeWrapText();
|
|
return this._wrappedText.GetMaxLineWidth()
|
|
}
|
|
GetTextHeight() {
|
|
this._MaybeWrapText();
|
|
return this._wrappedText.GetTotalLineHeight() + this._wrappedText.GetLineCount() * (this._lineHeight + EXTRA_LINE_HEIGHT) - this._lineHeight
|
|
}
|
|
GetTexture() {
|
|
this._textureTimeout.Reset();
|
|
this._MaybeUpdate();
|
|
return this._texture
|
|
}
|
|
_MaybeUpdate() {
|
|
if (this._texture && !this._changed && !this._textChanged)
|
|
return;
|
|
if (this._isUpdating)
|
|
return;
|
|
if (this._width <= 0 || this._height <= 0)
|
|
return;
|
|
this._changed = false;
|
|
this._isUpdating = true;
|
|
if (this._isAsync)
|
|
C3.Asyncify(()=>this._DoUpdate());
|
|
else
|
|
this._DoUpdate()
|
|
}
|
|
_DoUpdate() {
|
|
if (this._wasReleased)
|
|
return;
|
|
this._SetTextCanvasSize(Math.ceil(this._width), Math.ceil(this._height));
|
|
this._MaybeWrapText();
|
|
this._DrawTextToCanvas();
|
|
this._UpdateTexture();
|
|
this._textureTimeout.Reset();
|
|
this._isUpdating = false
|
|
}
|
|
_SetTextCanvasSize(w, h) {
|
|
if (!this._textCanvas)
|
|
this._textCanvas = C3.CreateCanvas(16, 16);
|
|
let wasReset = false;
|
|
if (this._lastCanvasWidth !== w || this._lastCanvasHeight !== h) {
|
|
this._lastCanvasWidth = w;
|
|
this._lastCanvasHeight = h;
|
|
this._textCanvas.width = w;
|
|
this._textCanvas.height = h;
|
|
wasReset = true
|
|
}
|
|
if (!this._textContext) {
|
|
this._textContext = this._textCanvas.getContext("2d");
|
|
wasReset = true
|
|
}
|
|
if (wasReset) {
|
|
this._textContext.textBaseline = this._isBBcodeEnabled ? "alphabetic" : "top";
|
|
this._textContext.font = this._lastTextCanvasFont;
|
|
this._textContext.fillStyle = this._lastTextCanvasFillStyle;
|
|
this._textContext.strokeStyle = this._lastTextCanvasFillStyle;
|
|
this._textContext.globalAlpha = this._lastTextCanvasOpacity;
|
|
this._textContext.lineWidth = this._lastTextCanvasLineWidth
|
|
} else
|
|
this._textContext.clearRect(0, 0, w, h)
|
|
}
|
|
_MaybeCreateMeasureContext() {
|
|
if (this._measureContext)
|
|
return;
|
|
this._measureContext = C3.CreateCanvas(16, 16).getContext("2d")
|
|
}
|
|
_SetMeasureFontString(fontString) {
|
|
if (this._lastMeasureCanvasFont === fontString)
|
|
return;
|
|
this._lastMeasureCanvasFont = fontString;
|
|
this._measureContext.font = fontString
|
|
}
|
|
_MaybeWrapText() {
|
|
if (!this._textChanged)
|
|
return;
|
|
this._MaybeCreateMeasureContext();
|
|
if (this._isBBcodeEnabled && (!this._bbString || this._bbString.toString() !== this._text))
|
|
this._bbString = new C3.BBString(this._text,{
|
|
noEscape: true
|
|
});
|
|
this._wrappedText.WordWrap(this._isBBcodeEnabled ? this._bbString.toFragmentList() : this._text, this._measureTextCallback, this._cssWidth, this._wrapMode, 0);
|
|
this._textChanged = false
|
|
}
|
|
_MeasureText(text, styles) {
|
|
this._SetMeasureFontString(this._GetFontString(true, styles));
|
|
const sizeStyle = this._GetStyleTag(styles, "size");
|
|
const fontSize = sizeStyle ? parseFloat(sizeStyle.param) : this._fontSize;
|
|
return {
|
|
width: this._measureContext.measureText(text).width,
|
|
height: ptToPx(fontSize)
|
|
}
|
|
}
|
|
_SetDrawFontString(fontString) {
|
|
if (this._lastTextCanvasFont === fontString)
|
|
return;
|
|
this._lastTextCanvasFont = fontString;
|
|
this._textContext.font = fontString
|
|
}
|
|
_SetDrawCanvasColor(styleStr) {
|
|
if (this._lastTextCanvasFillStyle === styleStr)
|
|
return;
|
|
this._lastTextCanvasFillStyle = styleStr;
|
|
this._textContext.fillStyle = styleStr;
|
|
this._textContext.strokeStyle = styleStr
|
|
}
|
|
_SetDrawCanvasOpacity(o) {
|
|
if (this._lastTextCanvasOpacity === o)
|
|
return;
|
|
this._lastTextCanvasOpacity = o;
|
|
this._textContext.globalAlpha = o
|
|
}
|
|
_SetDrawCanvasLineWith(w) {
|
|
if (this._lastTextCanvasLineWidth === w)
|
|
return;
|
|
this._lastTextCanvasLineWidth = w;
|
|
this._textContext.lineWidth = w
|
|
}
|
|
_DrawTextToCanvas() {
|
|
this._drawCharCount = 0;
|
|
const scale = this._scaleFactor * this._zoom * self.devicePixelRatio;
|
|
const lineSpaceHeight = (EXTRA_LINE_HEIGHT + this._lineHeight) * scale;
|
|
let penY = 0;
|
|
const lines = this._wrappedText.GetLines();
|
|
const linesTotalHeight = lines.reduce((a,v)=>a + v.height * scale + lineSpaceHeight, 0) - this._lineHeight * scale;
|
|
if (this._verticalAlign === "center")
|
|
penY = Math.max(this._height / 2 - linesTotalHeight / 2, 0);
|
|
else if (this._verticalAlign === "bottom")
|
|
penY = this._height - linesTotalHeight - 2;
|
|
for (let i = 0, len = lines.length; i < len; ++i) {
|
|
const line = lines[i];
|
|
const curLineTextHeight = line.height * scale;
|
|
const startPenY = penY;
|
|
if (this._isBBcodeEnabled) {
|
|
penY += curLineTextHeight;
|
|
if (i > 0 && penY > this._height - EXTRA_LINE_HEIGHT * scale)
|
|
break
|
|
} else if (i > 0 && penY >= this._height - curLineTextHeight)
|
|
break;
|
|
if (startPenY >= 0)
|
|
this._DrawTextLine(line, penY, scale);
|
|
if (!this._isBBcodeEnabled)
|
|
penY += curLineTextHeight;
|
|
penY += lineSpaceHeight
|
|
}
|
|
}
|
|
_DrawTextLine(line, penY, scale) {
|
|
let penX = 0;
|
|
if (this._horizontalAlign === "center")
|
|
penX = (this._width - line.width * scale) / 2;
|
|
else if (this._horizontalAlign === "right")
|
|
penX = this._width - line.width * scale;
|
|
for (const frag of line.fragments) {
|
|
this._DrawTextFragment(frag, penX, penY, scale, line.height);
|
|
penX += frag.width * scale
|
|
}
|
|
}
|
|
_DrawTextFragment(frag, penX, penY, scale, lineHeight) {
|
|
const textContext = this._textContext;
|
|
const lineFontScale = lineHeight / 16;
|
|
let fragWidth = frag.width * scale;
|
|
const fragHeight = frag.height * scale;
|
|
const fragFontScale = frag.height / 16;
|
|
const lineSpaceHeight = (EXTRA_LINE_HEIGHT + this._lineHeight) * scale;
|
|
const styles = frag.styles;
|
|
let text = frag.text;
|
|
if (this._drawMaxCharCount !== -1) {
|
|
if (this._drawCharCount >= this._drawMaxCharCount)
|
|
return;
|
|
if (this._drawCharCount + text.length > this._drawMaxCharCount) {
|
|
text = text.substr(0, this._drawMaxCharCount - this._drawCharCount);
|
|
fragWidth = this._MeasureText(text, styles).width * scale
|
|
}
|
|
this._drawCharCount += text.length
|
|
}
|
|
const backgroundStyle = this._GetStyleTag(styles, "background");
|
|
const hasUnderline = this._HasStyleTag(styles, "u");
|
|
const hasStrikethrough = this._HasStyleTag(styles, "s");
|
|
if (C3.IsStringAllWhitespace(text) && !backgroundStyle && !hasUnderline && !hasStrikethrough || this._HasStyleTag(styles, "hide"))
|
|
return;
|
|
const offsetXStyle = this._GetStyleTag(styles, "offsetx");
|
|
penX += offsetXStyle ? parseFloat(offsetXStyle.param) * scale : 0;
|
|
const offsetYStyle = this._GetStyleTag(styles, "offsety");
|
|
penY += offsetYStyle ? parseFloat(offsetYStyle.param) * scale : 0;
|
|
if (backgroundStyle) {
|
|
this._SetDrawCanvasColor(backgroundStyle.param);
|
|
textContext.fillRect(penX, penY - fragHeight, fragWidth, fragHeight + lineSpaceHeight)
|
|
}
|
|
const colorStyle = this._GetStyleTag(styles, "color");
|
|
this._SetDrawCanvasColor(colorStyle ? colorStyle.param : this._colorStr);
|
|
const opacityStyle = this._GetStyleTag(styles, "opacity");
|
|
this._SetDrawCanvasOpacity(opacityStyle ? parseFloat(opacityStyle.param) / 100 : 1);
|
|
const isStroke = this._HasStyleTag(styles, "stroke");
|
|
if (isStroke)
|
|
this._SetDrawCanvasLineWith(fragFontScale * this._scaleFactor * this._zoom);
|
|
if (hasUnderline)
|
|
fillOrStrokeRect(textContext, isStroke, penX, penY + scale * lineFontScale, fragWidth, scale * lineFontScale);
|
|
if (hasStrikethrough)
|
|
fillOrStrokeRect(textContext, isStroke, penX, penY - fragHeight / 4, fragWidth, scale * fragFontScale);
|
|
this._SetDrawFontString(this._GetFontString(false, styles));
|
|
fillOrStrokeText(textContext, isStroke, text, penX, penY, fragWidth);
|
|
if (!isStroke) {
|
|
this._SetDrawCanvasLineWith(fragFontScale * this._scaleFactor * this._zoom);
|
|
const outlineStyle = this._GetStyleTag(styles, "outline");
|
|
if (outlineStyle) {
|
|
this._SetDrawCanvasColor(outlineStyle.param);
|
|
fillOrStrokeText(textContext, true, text, penX, penY, fragWidth)
|
|
}
|
|
}
|
|
}
|
|
_UpdateTexture() {
|
|
if (this._renderer.IsContextLost())
|
|
return;
|
|
this._textureWidth = Math.ceil(this._width);
|
|
this._textureHeight = Math.ceil(this._height);
|
|
this._rcTex.set(0, 0, this._width / this._textureWidth, this._height / this._textureHeight);
|
|
if (this._needToRecreateTexture) {
|
|
this.ReleaseTexture();
|
|
this._needToRecreateTexture = false
|
|
}
|
|
if (!this._texture)
|
|
this._texture = this._renderer.CreateDynamicTexture(this._textureWidth, this._textureHeight, {
|
|
mipMap: this._zoom === 1,
|
|
mipMapQuality: "high"
|
|
});
|
|
this._renderer.UpdateTexture(this._textCanvas, this._texture);
|
|
if (this.ontextureupdate)
|
|
this.ontextureupdate()
|
|
}
|
|
GetTexRect() {
|
|
return this._rcTex
|
|
}
|
|
ReleaseTexture() {
|
|
if (this._texture) {
|
|
if (!this._renderer.IsContextLost())
|
|
this._renderer.DeleteTexture(this._texture);
|
|
this._texture = null
|
|
}
|
|
}
|
|
static OnContextLost() {
|
|
for (const rendererText of allRendererTexts)
|
|
rendererText.ReleaseTexture()
|
|
}
|
|
static GetAll() {
|
|
return allRendererTexts.values()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
class WebGLRealTimeElapsedQuery {
|
|
constructor(renderer) {
|
|
this._gl = renderer.GetContext();
|
|
this._version = renderer.GetWebGLVersionNumber();
|
|
this._timerExt = renderer._GetDisjointTimerQueryExtension();
|
|
this._query = null;
|
|
this._isActive = false;
|
|
this._hasResult = false;
|
|
this._result = 0;
|
|
if (this._version === 1)
|
|
this._query = this._timerExt["createQueryEXT"]();
|
|
else
|
|
this._query = this._gl["createQuery"]()
|
|
}
|
|
Release() {
|
|
this._DeleteQueryObject();
|
|
this._gl = null;
|
|
this._timerExt = null;
|
|
this._hasResult = false
|
|
}
|
|
_DeleteQueryObject() {
|
|
if (!this._query)
|
|
return;
|
|
if (this._version === 1)
|
|
this._timerExt["deleteQueryEXT"](this._query);
|
|
else
|
|
this._gl["deleteQuery"](this._query);
|
|
this._query = null
|
|
}
|
|
BeginTimeElapsed() {
|
|
if (this._isActive)
|
|
throw new Error("query already active");
|
|
if (this._version === 1)
|
|
this._timerExt["beginQueryEXT"](this._timerExt["TIME_ELAPSED_EXT"], this._query);
|
|
else
|
|
this._gl["beginQuery"](this._timerExt["TIME_ELAPSED_EXT"], this._query);
|
|
this._isActive = true
|
|
}
|
|
EndTimeElapsed() {
|
|
if (!this._isActive)
|
|
throw new Error("query not active");
|
|
if (this._version === 1)
|
|
this._timerExt["endQueryEXT"](this._timerExt["TIME_ELAPSED_EXT"]);
|
|
else
|
|
this._gl["endQuery"](this._timerExt["TIME_ELAPSED_EXT"]);
|
|
this._isActive = false
|
|
}
|
|
CheckForResult() {
|
|
if (!this._query || this._hasResult || this._isActive)
|
|
return;
|
|
let available = false;
|
|
if (this._version === 1)
|
|
available = this._timerExt["getQueryObjectEXT"](this._query, this._timerExt["QUERY_RESULT_AVAILABLE_EXT"]);
|
|
else
|
|
available = this._gl["getQueryParameter"](this._query, this._gl["QUERY_RESULT_AVAILABLE"]);
|
|
const disjoint = this._gl.getParameter(this._timerExt["GPU_DISJOINT_EXT"]);
|
|
if (available && !disjoint) {
|
|
if (this._version === 1)
|
|
this._result = this._timerExt["getQueryObjectEXT"](this._query, this._timerExt["QUERY_RESULT_EXT"]);
|
|
else
|
|
this._result = this._gl["getQueryParameter"](this._query, this._gl["QUERY_RESULT"]);
|
|
this._result /= 1E9;
|
|
this._hasResult = true
|
|
}
|
|
if (available || disjoint)
|
|
this._DeleteQueryObject()
|
|
}
|
|
HasResult() {
|
|
return this._hasResult
|
|
}
|
|
GetResult() {
|
|
if (!this._hasResult)
|
|
throw new Error("no result available");
|
|
return this._result
|
|
}
|
|
}
|
|
C3.Gfx.WebGLTimeElapsedQuery = class WebGLTimeElapsedQuery {
|
|
constructor(renderer) {
|
|
this._renderer = renderer;
|
|
this._frameNumber = renderer.GetFrameNumber();
|
|
this._isActive = false;
|
|
this._parentQuery = null;
|
|
this._isNested = false;
|
|
this._realQuery = null;
|
|
this._queries = []
|
|
}
|
|
Release() {
|
|
for (const q of this._queries)
|
|
if (q instanceof WebGLRealTimeElapsedQuery)
|
|
q.Release();
|
|
C3.clearArray(this._queries);
|
|
this._parentQuery = null;
|
|
this._realQuery = null;
|
|
this._renderer = null
|
|
}
|
|
BeginTimeElapsed() {
|
|
if (this._isActive)
|
|
throw new Error("query already active");
|
|
const stack = this._renderer._GetTimeQueryStack();
|
|
if (stack.length > 0) {
|
|
this._isNested = true;
|
|
this._parentQuery = stack[stack.length - 1];
|
|
this._parentQuery._EndReal();
|
|
this._parentQuery._queries.push(this)
|
|
} else {
|
|
this._isNested = false;
|
|
this._parentQuery = null
|
|
}
|
|
this._isActive = true;
|
|
stack.push(this);
|
|
this._StartReal()
|
|
}
|
|
EndTimeElapsed() {
|
|
if (!this._isActive)
|
|
throw new Error("query not active");
|
|
const top = this._renderer._GetTimeQueryStack().pop();
|
|
if (top !== this)
|
|
throw new Error("can only end most nested query");
|
|
this._isActive = false;
|
|
this._EndReal();
|
|
if (this._parentQuery) {
|
|
this._parentQuery._StartReal();
|
|
this._parentQuery = null
|
|
}
|
|
}
|
|
_StartReal() {
|
|
this._realQuery = C3.New(WebGLRealTimeElapsedQuery, this._renderer);
|
|
this._queries.push(this._realQuery);
|
|
this._realQuery.BeginTimeElapsed()
|
|
}
|
|
_EndReal() {
|
|
this._realQuery.EndTimeElapsed();
|
|
this._realQuery = null
|
|
}
|
|
CheckForResult() {
|
|
for (const q of this._queries)
|
|
q.CheckForResult()
|
|
}
|
|
IsNested() {
|
|
return this._isNested
|
|
}
|
|
HasResult() {
|
|
return this._queries.every(q=>q.HasResult())
|
|
}
|
|
GetResult() {
|
|
return this._queries.reduce((a,v)=>a + v.GetResult(), 0)
|
|
}
|
|
GetFrameNumber() {
|
|
return this._frameNumber
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Gfx.WebGLQueryResultBuffer = class WebGLQueryResultBuffer {
|
|
constructor(renderer, maxQueries=1E3) {
|
|
this._renderer = renderer;
|
|
this._maxQueries = maxQueries;
|
|
this._buffer = [];
|
|
this._renderer._AddQueryResultBuffer(this)
|
|
}
|
|
Release() {
|
|
this.Clear();
|
|
this._renderer._RemoveQueryResultBuffer(this);
|
|
this._renderer = null
|
|
}
|
|
Clear() {
|
|
for (const q of this._buffer)
|
|
q.Release();
|
|
C3.clearArray(this._buffer)
|
|
}
|
|
AddTimeElapsedQuery() {
|
|
const ret = new C3.Gfx.WebGLTimeElapsedQuery(this._renderer);
|
|
this._buffer.push(ret);
|
|
if (this._buffer.length > this._maxQueries) {
|
|
const oldest = this._buffer.shift();
|
|
oldest.Release()
|
|
}
|
|
return ret
|
|
}
|
|
CheckForResults(toFrameNumber) {
|
|
for (const q of this._buffer) {
|
|
if (q.GetFrameNumber() >= toFrameNumber)
|
|
return;
|
|
if (q.IsNested())
|
|
return;
|
|
q.CheckForResult()
|
|
}
|
|
}
|
|
GetFrameRangeResultSum(startFrame, endFrame) {
|
|
if (endFrame <= startFrame)
|
|
return NaN;
|
|
let sum = 0;
|
|
for (const q of this._buffer) {
|
|
if (q.GetFrameNumber() >= endFrame)
|
|
break;
|
|
if (q.GetFrameNumber() < startFrame)
|
|
continue;
|
|
if (q.HasResult())
|
|
sum += q.GetResult();
|
|
else
|
|
return NaN
|
|
}
|
|
return sum
|
|
}
|
|
DeleteAllBeforeFrameNumber(frameNumber) {
|
|
for (let i = 0, len = this._buffer.length; i < len; ++i) {
|
|
const q = this._buffer[i];
|
|
if (q.GetFrameNumber() < frameNumber)
|
|
q.Release();
|
|
else {
|
|
if (i > 0)
|
|
this._buffer.splice(0, i);
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
const glMatrix = self.glMatrix;
|
|
const vec3 = glMatrix.vec3;
|
|
const vec4 = glMatrix.vec4;
|
|
const mat4 = glMatrix.mat4;
|
|
const DEFAULT_WEBGLRENDERER_OPTS = {
|
|
powerPreference: "default",
|
|
enableGpuProfiling: true,
|
|
alpha: false,
|
|
lowLatency: false,
|
|
maxWebGLVersion: 2
|
|
};
|
|
const VALID_POWER_PREFERENCES = new Set(["default", "low-power", "high-performance"]);
|
|
const MAX_VERTICES = 8E3;
|
|
const MAX_INDICES = MAX_VERTICES / 2 * 3;
|
|
const MAX_POINTS = 8E3;
|
|
const LAST_POINT = MAX_POINTS - 4;
|
|
const PARTIAL_TEXTURE_UPLOAD_CHUNK_SIZE = 256 * 1024;
|
|
function areMat4sEqual(a, b) {
|
|
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15]
|
|
}
|
|
const defaultTexCoordsQuad = new C3.Quad(0,0,1,0,1,1,0,1);
|
|
const tmpVec3 = vec3.fromValues(0, 0, 0);
|
|
const tmpVec3b = vec3.fromValues(0, 0, 0);
|
|
const tmpMat4 = mat4.create();
|
|
const tmpQuad = new C3.Quad;
|
|
const tmpRect = new C3.Rect;
|
|
let loseContextExtension = null;
|
|
if (C3.isDebug) {
|
|
self.debug_lose_context = function() {
|
|
if (!loseContextExtension) {
|
|
console.warn("WEBGL_lose_context not supported");
|
|
return
|
|
}
|
|
loseContextExtension.loseContext()
|
|
}
|
|
;
|
|
self.debug_restore_context = function() {
|
|
if (!loseContextExtension) {
|
|
console.warn("WEBGL_lose_context not supported");
|
|
return
|
|
}
|
|
loseContextExtension.restoreContext()
|
|
}
|
|
}
|
|
const pendingPolls = new Set;
|
|
let pollRafId = -1;
|
|
function CheckPendingPolls() {
|
|
pollRafId = -1;
|
|
for (const info of pendingPolls)
|
|
if (info.checkFunc()) {
|
|
info.resolve();
|
|
pendingPolls.delete(info)
|
|
}
|
|
if (pendingPolls.size > 0)
|
|
pollRafId = self.requestAnimationFrame(CheckPendingPolls)
|
|
}
|
|
function GetWebGLContext(canvas, attribs, maxWebGLVersion) {
|
|
let gl = null;
|
|
if (maxWebGLVersion >= 2) {
|
|
gl = canvas.getContext("webgl2", attribs);
|
|
if (gl)
|
|
return {
|
|
gl,
|
|
version: 2
|
|
}
|
|
}
|
|
gl = canvas.getContext("webgl", attribs);
|
|
if (!gl)
|
|
try {
|
|
gl = canvas.getContext("experimental-webgl", attribs)
|
|
} catch (err) {
|
|
console.warn("Error requesting 'experimental-webgl' context: ", err)
|
|
}
|
|
return {
|
|
gl,
|
|
version: 1
|
|
}
|
|
}
|
|
C3.Gfx.WebGLRenderer = class WebGLRenderer extends C3.Gfx.RendererBase {
|
|
constructor(canvas, opts) {
|
|
super();
|
|
opts = Object.assign({}, DEFAULT_WEBGLRENDERER_OPTS, opts);
|
|
if (!VALID_POWER_PREFERENCES.has(opts.powerPreference))
|
|
throw new Error("invalid power preference");
|
|
let hasMajorPerformanceCaveat = false;
|
|
const attribs = {
|
|
"alpha": !!opts.alpha,
|
|
"depth": false,
|
|
"antialias": false,
|
|
"powerPreference": opts.powerPreference,
|
|
"failIfMajorPerformanceCaveat": true
|
|
};
|
|
if (opts.lowLatency) {
|
|
attribs["desynchronized"] = true;
|
|
attribs["preserveDrawingBuffer"] = true
|
|
}
|
|
let ctxInfo = GetWebGLContext(canvas, attribs, opts.maxWebGLVersion);
|
|
if (!ctxInfo.gl) {
|
|
hasMajorPerformanceCaveat = true;
|
|
attribs["failIfMajorPerformanceCaveat"] = false;
|
|
ctxInfo = GetWebGLContext(canvas, attribs, opts.maxWebGLVersion)
|
|
}
|
|
if (!ctxInfo.gl)
|
|
throw new Error("failed to initialise WebGL context");
|
|
const gl = ctxInfo.gl;
|
|
this._gl = gl;
|
|
this._attribs = gl.getContextAttributes();
|
|
if (opts.lowLatency && !this._attribs["desynchronized"])
|
|
console.info("[WebGLRenderer] Low-latency mode specified but is not supported here");
|
|
this._versionString = gl.getParameter(gl.VERSION);
|
|
this._version = ctxInfo.version;
|
|
this._is3d = true;
|
|
this._lastBackbufferWidth = 0;
|
|
this._lastBackbufferHeight = 0;
|
|
this._vertexBuffer = null;
|
|
this._texcoordBuffer = null;
|
|
this._indexBuffer = null;
|
|
this._pointBuffer = null;
|
|
this._vertexData = new Float32Array(MAX_VERTICES * this.GetNumVertexComponents());
|
|
this._indexData = new Uint16Array(MAX_INDICES);
|
|
this._texcoordData = new Float32Array(MAX_VERTICES * 2);
|
|
this._pointData = new Float32Array(MAX_POINTS * 4);
|
|
this._vertexPtr = 0;
|
|
this._texPtr = 0;
|
|
this._pointPtr = 0;
|
|
this._lastVertexPtr = 0;
|
|
this._lastProgram = null;
|
|
this._spDeviceTransformTextureFill = null;
|
|
this._spColorFill = null;
|
|
this._spLinearGradientFill = null;
|
|
this._spHardEllipseFill = null;
|
|
this._spHardEllipseOutline = null;
|
|
this._spSmoothEllipseFill = null;
|
|
this._spSmoothEllipseOutline = null;
|
|
this._spSmoothLineFill = null;
|
|
this._spPoints = null;
|
|
this._spTilemapFill = null;
|
|
this._batch = [];
|
|
this._batchPtr = 0;
|
|
this._topOfBatch = 0;
|
|
this._currentRenderTarget = null;
|
|
this._baseZ = 0;
|
|
this._currentZ = 0;
|
|
this._lastPointZ = 0;
|
|
this._batchState = C3.New(C3.Gfx.BatchState, this);
|
|
this._lastColor = C3.New(C3.Color, 1, 1, 1, 1);
|
|
this._lastTexture0 = null;
|
|
this._lastTexture1 = null;
|
|
this._lastSrcBlend = 0;
|
|
this._lastDestBlend = 0;
|
|
this._lineWidth = 1;
|
|
this._lineWidthStack = [this._lineWidth];
|
|
this._lineCap = 1;
|
|
this._lineCapStack = [this._lineCap];
|
|
this._lineOffset = .5;
|
|
this._lineOffsetStack = [this._lineOffset];
|
|
this._isScissorViewport = false;
|
|
this._viewportScissorWidth = -1;
|
|
this._viewportScissorHeight = -1;
|
|
this._lastPointTexCoords = new C3.Rect;
|
|
this._maxTextureSize = -1;
|
|
this._minPointSize = 0;
|
|
this._maxPointSize = 0;
|
|
this._highpPrecision = 0;
|
|
this._unmaskedVendor = "(unavailable)";
|
|
this._unmaskedRenderer = "(unavailable)";
|
|
this._extensions = [];
|
|
this._hasMajorPerformanceCaveat = hasMajorPerformanceCaveat;
|
|
this._isInitialisingAfterContextRestored = false;
|
|
this._parallelShaderCompileExt = null;
|
|
this._isGpuProfilingEnabled = !!opts.enableGpuProfiling;
|
|
this._timerExt = null;
|
|
this._allQueryResultBuffers = new Set;
|
|
this._timeQueryStack = [];
|
|
this.FillIndexBufferData(this._indexData)
|
|
}
|
|
async InitState() {
|
|
const gl = this._gl;
|
|
const numVertexComponents = this.GetNumVertexComponents();
|
|
this._lastColor.setRgba(1, 1, 1, 1);
|
|
this._lastTexture0 = null;
|
|
this._lastTexture1 = null;
|
|
this._vertexPtr = 0;
|
|
this._pointPtr = 0;
|
|
this._lastVertexPtr = MAX_VERTICES * numVertexComponents - 4 * numVertexComponents;
|
|
C3.clearArray(this._batch);
|
|
this._batchPtr = 0;
|
|
this._topOfBatch = 0;
|
|
this._lastProgram = null;
|
|
this._currentRenderTarget = null;
|
|
this._lastPointTexCoords.set(0, 0, 1, 1);
|
|
this._baseZ = 0;
|
|
this._currentZ = 0;
|
|
this._lastPointZ = 0;
|
|
const batchState = this._batchState;
|
|
batchState.currentShader = null;
|
|
batchState.currentFramebuffer = null;
|
|
vec4.set(batchState.currentColor, 1, 1, 1, 1);
|
|
batchState.clearColor.setRgba(0, 0, 0, 0);
|
|
batchState.pointTexCoords.set(0, 0, 1, 1);
|
|
gl.clearColor(0, 0, 0, 0);
|
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
gl.enable(gl.BLEND);
|
|
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
this._lastSrcBlend = gl.ONE;
|
|
this._lastDestBlend = gl.ONE_MINUS_SRC_ALPHA;
|
|
this._InitBlendModes(gl);
|
|
gl.disable(gl.CULL_FACE);
|
|
gl.disable(gl.STENCIL_TEST);
|
|
gl.disable(gl.DITHER);
|
|
gl.disable(gl.DEPTH_TEST);
|
|
this._pointBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, this._pointBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, this._pointData.byteLength, gl.DYNAMIC_DRAW);
|
|
this._vertexBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, this._vertexData.byteLength, gl.DYNAMIC_DRAW);
|
|
this._texcoordBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, this._texcoordBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, this._texcoordData.byteLength, gl.DYNAMIC_DRAW);
|
|
this._indexBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer);
|
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indexData, gl.STATIC_DRAW);
|
|
gl.activeTexture(gl.TEXTURE0);
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
|
|
const pointsizes = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
|
|
this._minPointSize = pointsizes[0];
|
|
this._maxPointSize = pointsizes[1];
|
|
const highpVertex = gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT);
|
|
const highpFrag = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT);
|
|
if (highpVertex && highpFrag)
|
|
this._highpPrecision = Math.min(highpVertex["precision"], highpFrag["precision"]);
|
|
else
|
|
this._highpPrecision = 0;
|
|
if (this._maxPointSize > 2048)
|
|
this._maxPointSize = 2048;
|
|
this._extensions = gl.getSupportedExtensions();
|
|
const debug_ext = gl.getExtension("WEBGL_debug_renderer_info");
|
|
if (debug_ext) {
|
|
this._unmaskedVendor = gl.getParameter(debug_ext["UNMASKED_VENDOR_WEBGL"]);
|
|
this._unmaskedRenderer = gl.getParameter(debug_ext["UNMASKED_RENDERER_WEBGL"])
|
|
}
|
|
this._parallelShaderCompileExt = gl.getExtension("KHR_parallel_shader_compile");
|
|
if (C3.isDebug)
|
|
loseContextExtension = gl.getExtension("WEBGL_lose_context");
|
|
if (this._isGpuProfilingEnabled)
|
|
if (this.GetWebGLVersionNumber() === 1) {
|
|
if (C3.Platform.BrowserEngine !== "Chromium" || C3.Platform.BrowserVersionNumber >= 81 || typeof document !== "undefined")
|
|
this._timerExt = gl.getExtension("EXT_disjoint_timer_query")
|
|
} else
|
|
this._timerExt = gl.getExtension("EXT_disjoint_timer_query_webgl2") || gl.getExtension("EXT_disjoint_timer_query");
|
|
this._ClearAllShaderPrograms();
|
|
const WebGLShaderProgram = C3.Gfx.WebGLShaderProgram;
|
|
const vsSource = WebGLShaderProgram.GetDefaultVertexShaderSource(this._is3d, false);
|
|
const DEFAULT_SHADER_PROGRAMS = [[WebGLShaderProgram.GetTextureFillFragmentShaderSource(), vsSource, "<default>"], [WebGLShaderProgram.GetTextureFillFragmentShaderSource(), vsSource, "<default-device-transform>"], [WebGLShaderProgram.GetPointFragmentShaderSource(), WebGLShaderProgram.GetPointVertexShaderSource(), "<point>"], [WebGLShaderProgram.GetColorFillFragmentShaderSource(), vsSource, "<fill>"], [WebGLShaderProgram.GetLinearGradientFillFragmentShaderSource(), vsSource, "<lineargradient>"], [WebGLShaderProgram.GetHardEllipseFillFragmentShaderSource(), vsSource, "<hardellipse>"], [WebGLShaderProgram.GetHardEllipseOutlineFragmentShaderSource(), vsSource, "<hardellipseoutline>"], [WebGLShaderProgram.GetSmoothEllipseFillFragmentShaderSource(), vsSource, "<smoothellipse>"], [WebGLShaderProgram.GetSmoothEllipseOutlineFragmentShaderSource(), vsSource, "<smoothellipseoutline>"], [WebGLShaderProgram.GetSmoothLineFillFragmentShaderSource(), vsSource, "<smoothline>"], [WebGLShaderProgram.GetTilemapFragmentShaderSource(), WebGLShaderProgram.GetDefaultVertexShaderSource(this._is3d, true), "<tilemap>"]];
|
|
const defaultShaders = await Promise.all(DEFAULT_SHADER_PROGRAMS.map(i=>this.CreateShaderProgram({
|
|
src: i[0]
|
|
}, i[1], i[2])));
|
|
this._spTextureFill = defaultShaders[0];
|
|
this._spDeviceTransformTextureFill = defaultShaders[1];
|
|
this._spPoints = defaultShaders[2];
|
|
this._spColorFill = defaultShaders[3];
|
|
this._spLinearGradientFill = defaultShaders[4];
|
|
this._spHardEllipseFill = defaultShaders[5];
|
|
this._spHardEllipseOutline = defaultShaders[6];
|
|
this._spSmoothEllipseFill = defaultShaders[7];
|
|
this._spSmoothEllipseOutline = defaultShaders[8];
|
|
this._spSmoothLineFill = defaultShaders[9];
|
|
this._spTilemapFill = defaultShaders[10];
|
|
this._currentStateGroup = null;
|
|
this.SetTextureFillMode()
|
|
}
|
|
Is3D() {
|
|
return this._is3d
|
|
}
|
|
GetNumVertexComponents() {
|
|
return this._is3d ? 3 : 2
|
|
}
|
|
SetBaseZ(z) {
|
|
this._baseZ = z
|
|
}
|
|
GetBaseZ() {
|
|
return this._baseZ
|
|
}
|
|
SetCurrentZ(z) {
|
|
this._currentZ = z;
|
|
this._currentStateGroup = null
|
|
}
|
|
GetCurrentZ() {
|
|
return this._currentZ
|
|
}
|
|
async CreateShaderProgram(shaderInfo, vsSource, name) {
|
|
const ret = await C3.Gfx.WebGLShaderProgram.Create(this, shaderInfo, vsSource, name);
|
|
this._AddShaderProgram(ret);
|
|
return ret
|
|
}
|
|
ResetLastProgram() {
|
|
this._lastProgram = null
|
|
}
|
|
SetSize(w, h, force) {
|
|
if (this._width === w && this._height === h && !force)
|
|
return;
|
|
this.EndBatch();
|
|
const gl = this._gl;
|
|
const batchState = this._batchState;
|
|
this._width = w;
|
|
this._height = h;
|
|
const viewW = this.GetScissoredViewportWidth();
|
|
const viewH = this.GetScissoredViewportHeight();
|
|
this._UpdateViewportRenderer(viewW, viewH, this._width, this._height);
|
|
this._UpdateViewportBatch(viewW, viewH, this._matP);
|
|
if (this._spDeviceTransformTextureFill) {
|
|
gl.useProgram(this._spDeviceTransformTextureFill.GetShaderProgram());
|
|
this._spDeviceTransformTextureFill._UpdateDeviceTransformUniforms(this._matP);
|
|
this._lastProgram = this._spDeviceTransformTextureFill;
|
|
this._batchState.currentShader = this._spDeviceTransformTextureFill
|
|
}
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
gl.activeTexture(gl.TEXTURE1);
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
gl.activeTexture(gl.TEXTURE0);
|
|
this._lastTexture0 = null;
|
|
this._lastTexture1 = null;
|
|
if (this._currentRenderTarget)
|
|
this._currentRenderTarget._Resize(this._width, this._height);
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
this._currentRenderTarget = null;
|
|
batchState.currentFramebuffer = null
|
|
}
|
|
_UpdateViewportRenderer(viewW, viewH, surfaceW, surfaceH) {
|
|
this._cam[2] = 100;
|
|
mat4.lookAt(this._matMV, this._cam, this._look, this._up);
|
|
mat4.perspective(this._matP, 45, viewW / viewH, this.GetNearZ(), this.GetFarZ());
|
|
const tl = [0, 0];
|
|
const br = [0, 0];
|
|
const dpr = self.devicePixelRatio;
|
|
this.Project(0, 0, viewW, viewH, tl);
|
|
this.Project(1, 1, viewW, viewH, br);
|
|
this._worldScale[0] = dpr / (br[0] - tl[0]);
|
|
this._worldScale[1] = -dpr / (br[1] - tl[1]);
|
|
this._lastBackbufferWidth = surfaceW;
|
|
this._lastBackbufferHeight = surfaceH
|
|
}
|
|
_UpdateViewportBatch(viewW, viewH, matP) {
|
|
const gl = this._gl;
|
|
const batchState = this._batchState;
|
|
gl.viewport(0, 0, viewW, viewH);
|
|
const allShaderPrograms = this._allShaderPrograms;
|
|
const currentShader = batchState.currentShader;
|
|
for (let i = 0, len = allShaderPrograms.length; i < len; ++i) {
|
|
const s = allShaderPrograms[i];
|
|
if (s === currentShader)
|
|
s.UpdateMatP(matP, true);
|
|
else
|
|
s.SetMatPStale()
|
|
}
|
|
mat4.copy(batchState.currentMatP, matP)
|
|
}
|
|
SetViewportScissor(w, h) {
|
|
const gl = this._gl;
|
|
if (this._width === w && this._height === h) {
|
|
if (this._isScissorViewport) {
|
|
this.EndBatch();
|
|
gl.disable(gl.SCISSOR_TEST);
|
|
this._isScissorViewport = false;
|
|
this._viewportScissorWidth = -1;
|
|
this._viewportScissorHeight = -1;
|
|
this.SetSize(this._width, this._height, true)
|
|
}
|
|
return
|
|
}
|
|
if (!this._isScissorViewport) {
|
|
this.EndBatch();
|
|
gl.enable(gl.SCISSOR_TEST);
|
|
this._isScissorViewport = true
|
|
}
|
|
if (this._viewportScissorWidth !== w || this._viewportScissorHeight !== h) {
|
|
this.EndBatch();
|
|
gl.scissor(0, 0, w, h);
|
|
this._viewportScissorWidth = w;
|
|
this._viewportScissorHeight = h;
|
|
this.SetSize(this._width, this._height, true)
|
|
}
|
|
}
|
|
RemoveViewportScissor() {
|
|
const gl = this._gl;
|
|
if (this._isScissorViewport) {
|
|
this.EndBatch();
|
|
gl.disable(gl.SCISSOR_TEST);
|
|
this._isScissorViewport = false
|
|
}
|
|
this._viewportScissorWidth = -1;
|
|
this._viewportScissorHeight = -1
|
|
}
|
|
GetScissoredViewportWidth() {
|
|
if (this._isScissorViewport)
|
|
return this._viewportScissorWidth;
|
|
else
|
|
return this.GetWidth()
|
|
}
|
|
GetScissoredViewportHeight() {
|
|
if (this._isScissorViewport)
|
|
return this._viewportScissorHeight;
|
|
else
|
|
return this.GetHeight()
|
|
}
|
|
UpdateModelView() {
|
|
if (areMat4sEqual(this._lastMV, this._matMV))
|
|
return;
|
|
const b = this.PushBatch();
|
|
b.InitUpdateModelView(this._matMV);
|
|
mat4.copy(this._lastMV, this._matMV);
|
|
this._topOfBatch = 0
|
|
}
|
|
GetBatchState() {
|
|
return this._batchState
|
|
}
|
|
PushBatch() {
|
|
const batch = this._batch;
|
|
if (this._batchPtr === batch.length)
|
|
batch.push(new C3.Gfx.WebGLBatchJob(this._batchState));
|
|
return batch[this._batchPtr++]
|
|
}
|
|
EndBatch() {
|
|
if (this._batchPtr === 0)
|
|
return;
|
|
if (this.IsContextLost())
|
|
return;
|
|
this._WriteBuffers();
|
|
this._ExecuteBatch();
|
|
this._batchPtr = 0;
|
|
this._vertexPtr = 0;
|
|
this._texPtr = 0;
|
|
this._pointPtr = 0;
|
|
this._topOfBatch = 0
|
|
}
|
|
_WriteBuffers() {
|
|
const gl = this._gl;
|
|
if (this._pointPtr > 0) {
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, this._pointBuffer);
|
|
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this._pointData.subarray(0, this._pointPtr))
|
|
}
|
|
if (this._vertexPtr > 0) {
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
|
|
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this._vertexData.subarray(0, this._vertexPtr));
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, this._texcoordBuffer);
|
|
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this._texcoordData.subarray(0, this._texPtr))
|
|
}
|
|
}
|
|
_ExecuteBatch() {
|
|
const batch = this._batch;
|
|
for (let i = 0, len = this._batchPtr; i < len; ++i)
|
|
batch[i].Run()
|
|
}
|
|
GetOpacity() {
|
|
return this._lastColor.getA()
|
|
}
|
|
SetColorRgba(r, g, b, a) {
|
|
const lastColor = this._lastColor;
|
|
if (lastColor.equalsRgba(r, g, b, a))
|
|
return;
|
|
lastColor.setRgba(r, g, b, a);
|
|
const batch = this.PushBatch();
|
|
batch.InitSetColor(lastColor);
|
|
this._topOfBatch = 0;
|
|
this._currentStateGroup = null
|
|
}
|
|
SetOpacity(a) {
|
|
const lastColor = this._lastColor;
|
|
if (lastColor.getA() === a)
|
|
return;
|
|
lastColor.setA(a);
|
|
const batch = this.PushBatch();
|
|
batch.InitSetColor(lastColor);
|
|
this._topOfBatch = 0;
|
|
this._currentStateGroup = null
|
|
}
|
|
SetColor(c) {
|
|
const lastColor = this._lastColor;
|
|
if (lastColor.equals(c))
|
|
return;
|
|
lastColor.set(c);
|
|
const batch = this.PushBatch();
|
|
batch.InitSetColor(lastColor);
|
|
this._topOfBatch = 0;
|
|
this._currentStateGroup = null
|
|
}
|
|
ResetColor() {
|
|
this.SetColorRgba(1, 1, 1, 1)
|
|
}
|
|
GetColor() {
|
|
return this._lastColor
|
|
}
|
|
SetTexture(rendererTex) {
|
|
if (rendererTex === this._lastTexture0)
|
|
return;
|
|
const b = this.PushBatch();
|
|
b.InitSetTexture(rendererTex);
|
|
this._lastTexture0 = rendererTex;
|
|
this._topOfBatch = 0
|
|
}
|
|
_ResetLastTexture() {
|
|
this._lastTexture0 = null
|
|
}
|
|
SetBlendMode(bm) {
|
|
const arr = this._GetBlendByIndex(bm);
|
|
this._SetBlend(arr[0], arr[1])
|
|
}
|
|
SetNamedBlendMode(bm) {
|
|
const o = this.GetNamedBlend(bm);
|
|
this._SetBlend(o.srcBlend, o.destBlend)
|
|
}
|
|
_SetBlend(s, d) {
|
|
if (s === this._lastSrcBlend && d === this._lastDestBlend)
|
|
return;
|
|
const b = this.PushBatch();
|
|
b.InitSetBlend(s, d);
|
|
this._lastSrcBlend = s;
|
|
this._lastDestBlend = d;
|
|
this._topOfBatch = 0;
|
|
this._currentStateGroup = null
|
|
}
|
|
IsPremultipliedAlphaBlend() {
|
|
return this._lastSrcBlend === this._gl.ONE && this._lastDestBlend === this._gl.ONE_MINUS_SRC_ALPHA
|
|
}
|
|
SetAlphaBlend() {
|
|
this._SetBlend(this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA)
|
|
}
|
|
SetNoPremultiplyAlphaBlend() {
|
|
this._SetBlend(this._gl.SRC_ALPHA, this._gl.ONE_MINUS_SRC_ALPHA)
|
|
}
|
|
SetCopyBlend() {
|
|
this._SetBlend(this._gl.ONE, this._gl.ZERO)
|
|
}
|
|
Rect(r) {
|
|
this.Rect2(r.getLeft(), r.getTop(), r.getRight(), r.getBottom())
|
|
}
|
|
Rect2(left, top, right, bottom) {
|
|
this.Quad2(left, top, right, top, right, bottom, left, bottom)
|
|
}
|
|
_ExtendQuadBatch() {
|
|
let v = this._vertexPtr;
|
|
if (v >= this._lastVertexPtr) {
|
|
this.EndBatch();
|
|
v = 0
|
|
}
|
|
if (this._topOfBatch === 1)
|
|
this._batch[this._batchPtr - 1]._indexCount += 6;
|
|
else {
|
|
const b = this.PushBatch();
|
|
b.InitQuad(this._is3d ? v : v / 2 * 3, 6);
|
|
this._topOfBatch = 1
|
|
}
|
|
}
|
|
_WriteQuadToVertexBuffer(quad) {
|
|
quad.writeToTypedArray3D(this._vertexData, this._vertexPtr, this._baseZ + this._currentZ);
|
|
this._vertexPtr += 12
|
|
}
|
|
Quad(quad) {
|
|
this._ExtendQuadBatch();
|
|
this._WriteQuadToVertexBuffer(quad);
|
|
defaultTexCoordsQuad.writeToTypedArray(this._texcoordData, this._texPtr);
|
|
this._texPtr += 8
|
|
}
|
|
Quad2(tlx, tly, trx, try_, brx, bry, blx, bly) {
|
|
this._ExtendQuadBatch();
|
|
const vd = this._vertexData;
|
|
let v = this._vertexPtr;
|
|
const z = this._baseZ + this._currentZ;
|
|
if (this._is3d) {
|
|
vd[v++] = tlx;
|
|
vd[v++] = tly;
|
|
vd[v++] = z;
|
|
vd[v++] = trx;
|
|
vd[v++] = try_;
|
|
vd[v++] = z;
|
|
vd[v++] = brx;
|
|
vd[v++] = bry;
|
|
vd[v++] = z;
|
|
vd[v++] = blx;
|
|
vd[v++] = bly;
|
|
vd[v++] = z
|
|
} else {
|
|
vd[v++] = tlx;
|
|
vd[v++] = tly;
|
|
vd[v++] = trx;
|
|
vd[v++] = try_;
|
|
vd[v++] = brx;
|
|
vd[v++] = bry;
|
|
vd[v++] = blx;
|
|
vd[v++] = bly
|
|
}
|
|
this._vertexPtr = v;
|
|
defaultTexCoordsQuad.writeToTypedArray(this._texcoordData, this._texPtr);
|
|
this._texPtr += 8
|
|
}
|
|
Quad3(quad, rcTex) {
|
|
this._ExtendQuadBatch();
|
|
this._WriteQuadToVertexBuffer(quad);
|
|
rcTex.writeAsQuadToTypedArray(this._texcoordData, this._texPtr);
|
|
this._texPtr += 8
|
|
}
|
|
Quad4(quad, uv) {
|
|
this._ExtendQuadBatch();
|
|
this._WriteQuadToVertexBuffer(quad);
|
|
uv.writeToTypedArray(this._texcoordData, this._texPtr);
|
|
this._texPtr += 8
|
|
}
|
|
FullscreenQuad(mode, curTex) {
|
|
mat4.copy(tmpMat4, this._lastMV);
|
|
vec3.copy(tmpVec3, this._cam);
|
|
vec3.copy(tmpVec3b, this._look);
|
|
this._cam[0] = 0;
|
|
this._cam[1] = 0;
|
|
this._cam[2] = 100 * self.devicePixelRatio;
|
|
this._look[0] = 0;
|
|
this._look[1] = 0;
|
|
this._look[2] = 0;
|
|
this.ResetModelView();
|
|
this.UpdateModelView();
|
|
if (this._isScissorViewport) {
|
|
const left = this._viewportScissorWidth / 2;
|
|
const top = this._viewportScissorHeight / 2;
|
|
tmpRect.set(-left, top, -left + this._viewportScissorWidth, top - this._viewportScissorHeight);
|
|
tmpQuad.setFromRect(tmpRect);
|
|
tmpRect.set(0, 0, this._viewportScissorWidth / this._width, this._viewportScissorHeight / this._height);
|
|
this.Quad3(tmpQuad, tmpRect)
|
|
} else if (mode === "crop" && this._currentRenderTarget && curTex) {
|
|
const left = this._width / 2;
|
|
const top = this._height / 2;
|
|
const srcW = curTex.GetWidth();
|
|
const srcH = curTex.GetHeight();
|
|
const destW = this._currentRenderTarget.GetWidth();
|
|
const destH = this._currentRenderTarget.GetHeight();
|
|
const copyW = Math.min(destW, srcW);
|
|
const copyH = Math.min(destH, srcH);
|
|
const srcOffY = Math.max(srcH - destH, 0);
|
|
const destOffY = Math.max(destH - srcH, 0);
|
|
tmpRect.set(-left, top - destOffY, -left + copyW, top - copyH - destOffY);
|
|
tmpQuad.setFromRect(tmpRect);
|
|
tmpRect.set(0, srcOffY, copyW, copyH + srcOffY);
|
|
tmpRect.divide(srcW, srcH);
|
|
this.Quad3(tmpQuad, tmpRect)
|
|
} else {
|
|
let[width,height] = this.GetRenderTargetSize(this._currentRenderTarget);
|
|
const halfW = width / 2;
|
|
const halfH = height / 2;
|
|
this.Rect2(-halfW, halfH, halfW, -halfH)
|
|
}
|
|
mat4.copy(this._matMV, tmpMat4);
|
|
vec3.copy(this._cam, tmpVec3);
|
|
vec3.copy(this._look, tmpVec3b);
|
|
this.UpdateModelView()
|
|
}
|
|
ConvexPoly(pts) {
|
|
const pts_count = pts.length / 2;
|
|
if (pts_count < 3)
|
|
throw new Error("need at least 3 points");
|
|
const tris = pts_count - 2;
|
|
const last_tri = tris - 1;
|
|
const p0x = pts[0];
|
|
const p0y = pts[1];
|
|
for (let i = 0; i < tris; i += 2) {
|
|
const i2 = i * 2;
|
|
const p1x = pts[i2 + 2];
|
|
const p1y = pts[i2 + 3];
|
|
const p2x = pts[i2 + 4];
|
|
const p2y = pts[i2 + 5];
|
|
if (i === last_tri)
|
|
this.Quad2(p0x, p0y, p1x, p1y, p2x, p2y, p2x, p2y);
|
|
else {
|
|
const p3x = pts[i2 + 6];
|
|
const p3y = pts[i2 + 7];
|
|
this.Quad2(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y)
|
|
}
|
|
}
|
|
}
|
|
Line(x1, y1, x2, y2) {
|
|
const a = C3.angleTo(x1, y1, x2, y2);
|
|
const sin_a = Math.sin(a);
|
|
const cos_a = Math.cos(a);
|
|
const halfLineWidth = this._lineWidth * .5;
|
|
const sin_a_hlw = sin_a * halfLineWidth;
|
|
const cos_a_hlw = cos_a * halfLineWidth;
|
|
const lineCap = this._lineCap;
|
|
if (lineCap === 2)
|
|
this.LinePreCalc_LineCap2(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw);
|
|
else if (lineCap === 1)
|
|
this.LinePreCalc_LineCap1(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw);
|
|
else
|
|
this.LinePreCalc_LineCap0(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw)
|
|
}
|
|
LinePreCalc_LineCap2(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw) {
|
|
const lineOffset = this._lineOffset;
|
|
const startX = x1 + lineOffset - cos_a_hlw;
|
|
const startY = y1 + lineOffset - sin_a_hlw;
|
|
const endX = x2 + lineOffset + cos_a_hlw;
|
|
const endY = y2 + lineOffset + sin_a_hlw;
|
|
const cos_a_lw = cos_a_hlw * 2;
|
|
const sin_a_lw = sin_a_hlw * 2;
|
|
const tlx = startX + sin_a_hlw;
|
|
const tly = startY - cos_a_hlw;
|
|
const blx = startX - sin_a_hlw + cos_a_lw;
|
|
const bly = startY + cos_a_hlw + sin_a_lw;
|
|
const trx = endX + sin_a_hlw;
|
|
const try_ = endY - cos_a_hlw;
|
|
const brx = endX - sin_a_hlw - cos_a_lw;
|
|
const bry = endY + cos_a_hlw - sin_a_lw;
|
|
this.Quad2(tlx, tly, trx, try_, brx, bry, blx, bly)
|
|
}
|
|
LinePreCalc_LineCap1(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw) {
|
|
const lineOffset = this._lineOffset;
|
|
const startX = x1 + lineOffset - cos_a_hlw;
|
|
const startY = y1 + lineOffset - sin_a_hlw;
|
|
const endX = x2 + lineOffset + cos_a_hlw;
|
|
const endY = y2 + lineOffset + sin_a_hlw;
|
|
const tlx = startX + sin_a_hlw;
|
|
const tly = startY - cos_a_hlw;
|
|
const blx = startX - sin_a_hlw;
|
|
const bly = startY + cos_a_hlw;
|
|
const trx = endX + sin_a_hlw;
|
|
const try_ = endY - cos_a_hlw;
|
|
const brx = endX - sin_a_hlw;
|
|
const bry = endY + cos_a_hlw;
|
|
this.Quad2(tlx, tly, trx, try_, brx, bry, blx, bly)
|
|
}
|
|
LinePreCalc_LineCap0(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw) {
|
|
const lineOffset = this._lineOffset;
|
|
const startX = x1 + lineOffset;
|
|
const startY = y1 + lineOffset;
|
|
const endX = x2 + lineOffset;
|
|
const endY = y2 + lineOffset;
|
|
const tlx = startX + sin_a_hlw;
|
|
const tly = startY - cos_a_hlw;
|
|
const blx = startX - sin_a_hlw;
|
|
const bly = startY + cos_a_hlw;
|
|
const trx = endX + sin_a_hlw;
|
|
const try_ = endY - cos_a_hlw;
|
|
const brx = endX - sin_a_hlw;
|
|
const bry = endY + cos_a_hlw;
|
|
this.Quad2(tlx, tly, trx, try_, brx, bry, blx, bly)
|
|
}
|
|
TexturedLine(x1, y1, x2, y2, u, v) {
|
|
const a = C3.angleTo(x1, y1, x2, y2);
|
|
const sin_a = Math.sin(a);
|
|
const cos_a = Math.cos(a);
|
|
const halfLineWidth = this._lineWidth * .5;
|
|
const sin_a_hlw = sin_a * halfLineWidth;
|
|
const cos_a_hlw = cos_a * halfLineWidth;
|
|
const lineCap = this._lineCap;
|
|
if (lineCap === 2)
|
|
this.TexturedLinePreCalc_LineCap2(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw, u, v);
|
|
else if (lineCap === 1)
|
|
this.TexturedLinePreCalc_LineCap1(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw, u, v);
|
|
else
|
|
this.TexturedLinePreCalc_LineCap0(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw, u, v)
|
|
}
|
|
TexturedLinePreCalc_LineCap2(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw, u, v) {
|
|
const lineOffset = this._lineOffset;
|
|
const startX = x1 + lineOffset - cos_a_hlw;
|
|
const startY = y1 + lineOffset - sin_a_hlw;
|
|
const endX = x2 + lineOffset + cos_a_hlw;
|
|
const endY = y2 + lineOffset + sin_a_hlw;
|
|
const cos_a_lw = cos_a_hlw * 2;
|
|
const sin_a_lw = sin_a_hlw * 2;
|
|
const tlx = startX + sin_a_hlw;
|
|
const tly = startY - cos_a_hlw;
|
|
const blx = startX - sin_a_hlw + cos_a_lw;
|
|
const bly = startY + cos_a_hlw + sin_a_lw;
|
|
const trx = endX + sin_a_hlw;
|
|
const try_ = endY - cos_a_hlw;
|
|
const brx = endX - sin_a_hlw - cos_a_lw;
|
|
const bry = endY + cos_a_hlw - sin_a_lw;
|
|
tmpQuad.set(tlx, tly, trx, try_, brx, bry, blx, bly);
|
|
tmpRect.set(u, 0, v, 0);
|
|
this.Quad3(tmpQuad, tmpRect)
|
|
}
|
|
TexturedLinePreCalc_LineCap1(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw, u, v) {
|
|
const lineOffset = this._lineOffset;
|
|
const startX = x1 + lineOffset - cos_a_hlw;
|
|
const startY = y1 + lineOffset - sin_a_hlw;
|
|
const endX = x2 + lineOffset + cos_a_hlw;
|
|
const endY = y2 + lineOffset + sin_a_hlw;
|
|
const tlx = startX + sin_a_hlw;
|
|
const tly = startY - cos_a_hlw;
|
|
const blx = startX - sin_a_hlw;
|
|
const bly = startY + cos_a_hlw;
|
|
const trx = endX + sin_a_hlw;
|
|
const try_ = endY - cos_a_hlw;
|
|
const brx = endX - sin_a_hlw;
|
|
const bry = endY + cos_a_hlw;
|
|
tmpQuad.set(tlx, tly, trx, try_, brx, bry, blx, bly);
|
|
tmpRect.set(u, 0, v, 0);
|
|
this.Quad3(tmpQuad, tmpRect)
|
|
}
|
|
TexturedLinePreCalc_LineCap0(x1, y1, x2, y2, sin_a_hlw, cos_a_hlw, u, v) {
|
|
const lineOffset = this._lineOffset;
|
|
const startX = x1 + lineOffset;
|
|
const startY = y1 + lineOffset;
|
|
const endX = x2 + lineOffset;
|
|
const endY = y2 + lineOffset;
|
|
const tlx = startX + sin_a_hlw;
|
|
const tly = startY - cos_a_hlw;
|
|
const blx = startX - sin_a_hlw;
|
|
const bly = startY + cos_a_hlw;
|
|
const trx = endX + sin_a_hlw;
|
|
const try_ = endY - cos_a_hlw;
|
|
const brx = endX - sin_a_hlw;
|
|
const bry = endY + cos_a_hlw;
|
|
tmpQuad.set(tlx, tly, trx, try_, brx, bry, blx, bly);
|
|
tmpRect.set(u, 0, v, 0);
|
|
this.Quad3(tmpQuad, tmpRect)
|
|
}
|
|
LineRect(left, top, right, bottom) {
|
|
const halfLineWidth = this._lineWidth * .5;
|
|
const lineCap = this._lineCap;
|
|
if (lineCap === 2)
|
|
this._LineRectPreCalc_LineCap2(left, top, right, bottom, halfLineWidth);
|
|
else if (lineCap === 1)
|
|
this._LineRectPreCalc_LineCap1(left, top, right, bottom, halfLineWidth);
|
|
else
|
|
this._LineRectPreCalc_LineCap0(left, top, right, bottom, halfLineWidth)
|
|
}
|
|
_LineRectPreCalc_LineCap2(left, top, right, bottom, halfLineWidth) {
|
|
this.LinePreCalc_LineCap2(left, top, right, top, 0, halfLineWidth);
|
|
this.LinePreCalc_LineCap2(right, top, right, bottom, halfLineWidth, 0);
|
|
this.LinePreCalc_LineCap2(right, bottom, left, bottom, 0, -halfLineWidth);
|
|
this.LinePreCalc_LineCap2(left, bottom, left, top, -halfLineWidth, 0)
|
|
}
|
|
_LineRectPreCalc_LineCap1(left, top, right, bottom, halfLineWidth) {
|
|
this.LinePreCalc_LineCap1(left, top, right, top, 0, halfLineWidth);
|
|
this.LinePreCalc_LineCap1(right, top, right, bottom, halfLineWidth, 0);
|
|
this.LinePreCalc_LineCap1(right, bottom, left, bottom, 0, -halfLineWidth);
|
|
this.LinePreCalc_LineCap1(left, bottom, left, top, -halfLineWidth, 0)
|
|
}
|
|
_LineRectPreCalc_LineCap0(left, top, right, bottom, halfLineWidth) {
|
|
this.LinePreCalc_LineCap0(left, top, right, top, 0, halfLineWidth);
|
|
this.LinePreCalc_LineCap0(right, top, right, bottom, halfLineWidth, 0);
|
|
this.LinePreCalc_LineCap0(right, bottom, left, bottom, 0, -halfLineWidth);
|
|
this.LinePreCalc_LineCap0(left, bottom, left, top, -halfLineWidth, 0)
|
|
}
|
|
LineRect2(r) {
|
|
this.LineRect(r.getLeft(), r.getTop(), r.getRight(), r.getBottom())
|
|
}
|
|
LineQuad(q) {
|
|
const a = C3.angleTo(q.getTlx(), q.getTly(), q.getTrx(), q.getTry());
|
|
const sin_a = Math.sin(a);
|
|
const cos_a = Math.cos(a);
|
|
const halfLineWidth = this._lineWidth * .5;
|
|
const sin_a_hlw = sin_a * halfLineWidth;
|
|
const cos_a_hlw = cos_a * halfLineWidth;
|
|
const lineCap = this._lineCap;
|
|
if (lineCap === 2)
|
|
this._LineQuadPreCalc_LineCap2(q, sin_a_hlw, cos_a_hlw);
|
|
else if (lineCap === 1)
|
|
this._LineQuadPreCalc_LineCap1(q, sin_a_hlw, cos_a_hlw);
|
|
else
|
|
this._LineQuadPreCalc_LineCap0(q, sin_a_hlw, cos_a_hlw)
|
|
}
|
|
_LineQuadPreCalc_LineCap2(q, sin_a_hlw, cos_a_hlw) {
|
|
this.LinePreCalc_LineCap2(q.getTlx(), q.getTly(), q.getTrx(), q.getTry(), sin_a_hlw, cos_a_hlw);
|
|
this.LinePreCalc_LineCap2(q.getTrx(), q.getTry(), q.getBrx(), q.getBry(), cos_a_hlw, -sin_a_hlw);
|
|
this.LinePreCalc_LineCap2(q.getBrx(), q.getBry(), q.getBlx(), q.getBly(), -sin_a_hlw, -cos_a_hlw);
|
|
this.LinePreCalc_LineCap2(q.getBlx(), q.getBly(), q.getTlx(), q.getTly(), -cos_a_hlw, sin_a_hlw)
|
|
}
|
|
_LineQuadPreCalc_LineCap1(q, sin_a_hlw, cos_a_hlw) {
|
|
this.LinePreCalc_LineCap1(q.getTlx(), q.getTly(), q.getTrx(), q.getTry(), sin_a_hlw, cos_a_hlw);
|
|
this.LinePreCalc_LineCap1(q.getTrx(), q.getTry(), q.getBrx(), q.getBry(), cos_a_hlw, -sin_a_hlw);
|
|
this.LinePreCalc_LineCap1(q.getBrx(), q.getBry(), q.getBlx(), q.getBly(), -sin_a_hlw, -cos_a_hlw);
|
|
this.LinePreCalc_LineCap1(q.getBlx(), q.getBly(), q.getTlx(), q.getTly(), -cos_a_hlw, sin_a_hlw)
|
|
}
|
|
_LineQuadPreCalc_LineCap0(q, sin_a_hlw, cos_a_hlw) {
|
|
this.LinePreCalc_LineCap0(q.getTlx(), q.getTly(), q.getTrx(), q.getTry(), sin_a_hlw, cos_a_hlw);
|
|
this.LinePreCalc_LineCap0(q.getTrx(), q.getTry(), q.getBrx(), q.getBry(), cos_a_hlw, -sin_a_hlw);
|
|
this.LinePreCalc_LineCap0(q.getBrx(), q.getBry(), q.getBlx(), q.getBly(), -sin_a_hlw, -cos_a_hlw);
|
|
this.LinePreCalc_LineCap0(q.getBlx(), q.getBly(), q.getTlx(), q.getTly(), -cos_a_hlw, sin_a_hlw)
|
|
}
|
|
SetLineWidth(n) {
|
|
this._lineWidth = n;
|
|
this._lineWidthStack[this._lineWidthStack.length - 1] = n
|
|
}
|
|
GetLineWidth() {
|
|
return this._lineWidth
|
|
}
|
|
PushLineWidth(n) {
|
|
if (this._lineWidthStack.length >= 100)
|
|
throw new Error("pushed too many line widths - check push/pop pairs");
|
|
this._lineWidthStack.push(n);
|
|
this._lineWidth = n
|
|
}
|
|
PopLineWidth() {
|
|
if (this._lineWidthStack.length <= 1)
|
|
throw new Error("cannot pop last line width - check push/pop pairs");
|
|
this._lineWidthStack.pop();
|
|
this._lineWidth = this._lineWidthStack[this._lineWidthStack.length - 1]
|
|
}
|
|
SetLineCapButt() {
|
|
this._lineCap = 0;
|
|
this._lineCapStack[this._lineCapStack.length - 1] = 0
|
|
}
|
|
SetLineCapSquare() {
|
|
this._lineCap = 1;
|
|
this._lineCapStack[this._lineCapStack.length - 1] = 0
|
|
}
|
|
SetLineCapZag() {
|
|
this._lineCap = 2;
|
|
this._lineCapStack[this._lineCapStack.length - 1] = 0
|
|
}
|
|
PushLineCap(type) {
|
|
if (type === "butt")
|
|
this.PushLineCapButt();
|
|
else if (type === "square")
|
|
this.PushLineCapSquare();
|
|
else if (type === "zag")
|
|
this.PushLineCapZag();
|
|
else
|
|
throw new Error("invalid line cap");
|
|
}
|
|
PushLineCapButt() {
|
|
if (this._lineCapStack.length >= 100)
|
|
throw new Error("pushed too many line caps - check push/pop pairs");
|
|
this._lineCapStack.push(0);
|
|
this._lineCap = 0
|
|
}
|
|
PushLineCapSquare() {
|
|
if (this._lineCapStack.length >= 100)
|
|
throw new Error("pushed too many line caps - check push/pop pairs");
|
|
this._lineCapStack.push(1);
|
|
this._lineCap = 1
|
|
}
|
|
PushLineCapZag() {
|
|
if (this._lineCapStack.length >= 100)
|
|
throw new Error("pushed too many line caps - check push/pop pairs");
|
|
this._lineCapStack.push(2);
|
|
this._lineCap = 2
|
|
}
|
|
PopLineCap() {
|
|
if (this._lineCapStack.length <= 1)
|
|
throw new Error("cannot pop last line cap - check push/pop pairs");
|
|
this._lineCapStack.pop();
|
|
this._lineCap = this._lineCapStack[this._lineCapStack.length - 1]
|
|
}
|
|
SetLineOffset(n) {
|
|
this._lineOffset = n;
|
|
this._lineOffsetStack[this._lineOffsetStack.length - 1] = n
|
|
}
|
|
GetLineOffset() {
|
|
return this._lineOffset
|
|
}
|
|
PushLineOffset(n) {
|
|
if (this._lineOffsetStack.length >= 100)
|
|
throw new Error("pushed too many line offsets - check push/pop pairs");
|
|
this._lineOffsetStack.push(n);
|
|
this._lineOffset = n
|
|
}
|
|
PopLineOffset() {
|
|
if (this._lineOffsetStack.length <= 1)
|
|
throw new Error("cannot pop last line offset - check push/pop pairs");
|
|
this._lineOffsetStack.pop();
|
|
this._lineOffset = this._lineOffsetStack[this._lineOffsetStack.length - 1]
|
|
}
|
|
SetPointTextureCoords(rect) {
|
|
if (this._lastPointTexCoords.equals(rect))
|
|
return;
|
|
this._lastPointTexCoords.copy(rect);
|
|
const b = this.PushBatch();
|
|
b.InitSetPointTexCoords(rect);
|
|
this._topOfBatch = 0
|
|
}
|
|
Point(x_, y_, size_, opacity_) {
|
|
if (this._pointPtr >= LAST_POINT)
|
|
this.EndBatch();
|
|
let p = this._pointPtr;
|
|
const z = this._baseZ + this._currentZ;
|
|
if (this._topOfBatch === 2 && this._lastPointZ === z)
|
|
this._batch[this._batchPtr - 1]._indexCount++;
|
|
else {
|
|
const b = this.PushBatch();
|
|
b.InitPoints(p, z);
|
|
this._topOfBatch = 2;
|
|
this._lastPointZ = z
|
|
}
|
|
const pd = this._pointData;
|
|
pd[p++] = x_;
|
|
pd[p++] = y_;
|
|
pd[p++] = size_;
|
|
pd[p++] = opacity_;
|
|
this._pointPtr = p
|
|
}
|
|
SetProgram(program) {
|
|
if (this._lastProgram === program)
|
|
return;
|
|
const b = this.PushBatch();
|
|
b.InitSetProgram(program);
|
|
this._lastProgram = program;
|
|
this._topOfBatch = 0;
|
|
this._currentStateGroup = null
|
|
}
|
|
SetTextureFillMode() {
|
|
this.SetProgram(this._spTextureFill)
|
|
}
|
|
SetDeviceTransformTextureFillMode() {
|
|
this.SetProgram(this._spDeviceTransformTextureFill)
|
|
}
|
|
SetColorFillMode() {
|
|
this.SetProgram(this._spColorFill)
|
|
}
|
|
SetLinearGradientFillMode() {
|
|
this.SetProgram(this._spLinearGradientFill)
|
|
}
|
|
SetGradientColor(c) {
|
|
const b = this.PushBatch();
|
|
b.InitSetGradientColor(c);
|
|
this._topOfBatch = 0
|
|
}
|
|
SetHardEllipseFillMode() {
|
|
this.SetProgram(this._spHardEllipseFill)
|
|
}
|
|
SetHardEllipseOutlineMode() {
|
|
this.SetProgram(this._spHardEllipseOutline)
|
|
}
|
|
SetSmoothEllipseFillMode() {
|
|
this.SetProgram(this._spSmoothEllipseFill)
|
|
}
|
|
SetSmoothEllipseOutlineMode() {
|
|
this.SetProgram(this._spSmoothEllipseOutline)
|
|
}
|
|
SetEllipseParams(pixelW, pixelH, outlineThickness=1) {
|
|
const b = this.PushBatch();
|
|
b.InitSetEllipseParams(pixelW, pixelH, outlineThickness);
|
|
this._topOfBatch = 0
|
|
}
|
|
SetSmoothLineFillMode() {
|
|
this.SetProgram(this._spSmoothLineFill)
|
|
}
|
|
SetTilemapFillMode() {
|
|
this.SetProgram(this._spTilemapFill)
|
|
}
|
|
SetTilemapInfo(srcRect, textureWidth, textureHeight, tileWidth, tileHeight, tileSpacingX, tileSpacingY) {
|
|
if (this._lastProgram !== this._spTilemapFill)
|
|
throw new Error("must set tilemap fill mode first");
|
|
const b = this.PushBatch();
|
|
b.InitSetTilemapInfo(srcRect, textureWidth, textureHeight, tileWidth, tileHeight, tileSpacingX, tileSpacingY);
|
|
this._topOfBatch = 0
|
|
}
|
|
SetProgramParameters(backTex, destRect, srcRect, srcOriginRect, layoutRect, pixelWidth, pixelHeight, layerScale, layerAngle, time, params) {
|
|
const s = this._lastProgram;
|
|
const hasAnyOptionalUniforms = s._hasAnyOptionalUniforms;
|
|
const hasAnyCustomParams = !!params.length;
|
|
if ((!hasAnyOptionalUniforms || s.AreOptionalUniformsAlreadySetInBatch(destRect, srcRect, srcOriginRect, layoutRect, pixelWidth, pixelHeight, layerScale, layerAngle, time)) && (!hasAnyCustomParams || s.AreCustomParametersAlreadySetInBatch(params)))
|
|
return;
|
|
const b = this.PushBatch();
|
|
b.InitSetProgramParameters();
|
|
if (hasAnyOptionalUniforms) {
|
|
s.SetOptionalUniformsInBatch(destRect, srcRect, srcOriginRect, layoutRect, pixelWidth, pixelHeight, layerScale, layerAngle, time);
|
|
const mat4param = b._mat4param;
|
|
mat4param[0] = pixelWidth;
|
|
mat4param[1] = pixelHeight;
|
|
destRect.writeToTypedArray(mat4param, 2);
|
|
mat4param[6] = layerScale;
|
|
mat4param[7] = layerAngle;
|
|
srcRect.writeToTypedArray(mat4param, 12);
|
|
const colorParam = b._colorParam;
|
|
layoutRect.writeToTypedArray(colorParam, 0);
|
|
const tmp = colorParam[1];
|
|
colorParam[1] = colorParam[3];
|
|
colorParam[3] = tmp;
|
|
srcOriginRect.writeToTypedArray(b._srcOriginRect, 0);
|
|
b._startIndex = time;
|
|
if (s._uSamplerBack.IsUsed())
|
|
b._texParam = backTex ? backTex.GetTexture() : null;
|
|
else
|
|
b._texParam = null
|
|
}
|
|
if (hasAnyCustomParams) {
|
|
s.SetCustomParametersInBatch(params);
|
|
C3.shallowAssignArray(b._shaderParams, params)
|
|
}
|
|
this._topOfBatch = 0
|
|
}
|
|
ClearRgba(r, g, b_, a) {
|
|
const b = this.PushBatch();
|
|
b.InitClearSurface2(r, g, b_, a);
|
|
this._topOfBatch = 0
|
|
}
|
|
Clear(c) {
|
|
const b = this.PushBatch();
|
|
b.InitClearSurface(c);
|
|
this._topOfBatch = 0
|
|
}
|
|
ClearRect(x, y, w, h) {
|
|
this.ClearRect4(x, y, w, h, 0, 0, 0, 0)
|
|
}
|
|
ClearRect2(rc) {
|
|
this.ClearRect4(rc.getLeft(), rc.getTop(), rc.width(), rc.height(), 0, 0, 0, 0)
|
|
}
|
|
ClearRect3(rc, c) {
|
|
this.ClearRect4(rc.getLeft(), rc.getTop(), rc.width(), rc.height(), c.getR(), c.getG(), c.getB(), c.getA())
|
|
}
|
|
ClearRect4(x, y, w, h, r, g, b, a) {
|
|
if (w < 0 || h < 0)
|
|
return;
|
|
const batch = this.PushBatch();
|
|
batch.InitClearRect(x, y, w, h, r, g, b, a);
|
|
this._topOfBatch = 0
|
|
}
|
|
Start() {}
|
|
Finish() {
|
|
super.Finish();
|
|
this._gl.flush()
|
|
}
|
|
CheckForQueryResults() {
|
|
for (const qrb of this._allQueryResultBuffers)
|
|
qrb.CheckForResults(this._frameNumber)
|
|
}
|
|
IsContextLost() {
|
|
return !this._gl || this._gl.isContextLost() || this._isInitialisingAfterContextRestored
|
|
}
|
|
OnContextLost() {
|
|
C3.Gfx.WebGLRendererTexture.OnContextLost();
|
|
C3.Gfx.WebGLRenderTarget.OnContextLost();
|
|
C3.Gfx.RendererText.OnContextLost();
|
|
for (const qrb of this._allQueryResultBuffers)
|
|
qrb.Clear();
|
|
this._extensions = [];
|
|
this._timerExt = null;
|
|
this._parallelShaderCompileExt = null;
|
|
this._unmaskedVendor = "(unavailable)";
|
|
this._unmaskedRenderer = "(unavailable)";
|
|
this._lastProgram = null;
|
|
this._spTextureFill = null;
|
|
this._spDeviceTransformTextureFill = null;
|
|
this._spColorFill = null;
|
|
this._spLinearGradientFill = null;
|
|
this._spHardEllipseFill = null;
|
|
this._spHardEllipseOutline = null;
|
|
this._spSmoothEllipseFill = null;
|
|
this._spSmoothEllipseOutline = null;
|
|
this._spSmoothLineFill = null;
|
|
this._spPoints = null;
|
|
this._spTilemapFill = null;
|
|
for (const stateGroup of this._stateGroups.values())
|
|
stateGroup.OnContextLost();
|
|
for (const s of this._allShaderPrograms)
|
|
s.Release();
|
|
this._ClearAllShaderPrograms()
|
|
}
|
|
async OnContextRestored() {
|
|
this._isInitialisingAfterContextRestored = true;
|
|
await this.InitState();
|
|
this._isInitialisingAfterContextRestored = false;
|
|
for (const stateGroup of this._stateGroups.values())
|
|
stateGroup.OnContextRestored(this);
|
|
this.SetSize(this._width, this._height, true)
|
|
}
|
|
CreateStaticTexture(data, opts) {
|
|
if (this.IsContextLost())
|
|
throw new Error("context lost");
|
|
this.EndBatch();
|
|
const rendererTex = C3.New(C3.Gfx.WebGLRendererTexture, this);
|
|
rendererTex._CreateStatic(data, opts);
|
|
return rendererTex
|
|
}
|
|
CreateStaticTextureAsync(data, opts) {
|
|
if (this.IsContextLost())
|
|
return Promise.reject("context lost");
|
|
opts = Object.assign({}, opts);
|
|
const isTiled = opts.wrapX && opts.wrapX !== "clamp-to-edge" || opts.wrapY && opts.wrapY !== "clamp-to-edge";
|
|
if (C3.Supports.ImageBitmapOptions && (this.SupportsNPOTTextures() || !isTiled)) {
|
|
opts.premultiplyAlpha = false;
|
|
return createImageBitmap(data, {
|
|
"premultiplyAlpha": "premultiply"
|
|
}).then(imageBitmap=>C3.Asyncify(()=>this.CreateStaticTexture(imageBitmap, opts)))
|
|
} else if (C3.Supports.ImageBitmap)
|
|
return createImageBitmap(data).then(imageBitmap=>C3.Asyncify(()=>this.CreateStaticTexture(imageBitmap, opts)));
|
|
else if (data instanceof Blob)
|
|
return C3.BlobToImage(data, true).then(img=>this.CreateStaticTextureAsync(img, opts));
|
|
else if (typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement && typeof data["decode"] === "function")
|
|
return data["decode"]().then(()=>C3.Asyncify(()=>this.CreateStaticTexture(data, opts)));
|
|
else
|
|
return C3.Asyncify(()=>this.CreateStaticTexture(data, opts))
|
|
}
|
|
CreateDynamicTexture(width, height, opts) {
|
|
this.EndBatch();
|
|
const rendererTex = C3.New(C3.Gfx.WebGLRendererTexture, this);
|
|
rendererTex._CreateDynamic(width, height, opts);
|
|
return rendererTex
|
|
}
|
|
UpdateTexture(data, rendererTex, opts) {
|
|
this.EndBatch();
|
|
rendererTex._Update(data, opts)
|
|
}
|
|
DeleteTexture(rendererTex) {
|
|
if (!rendererTex)
|
|
return;
|
|
rendererTex.SubtractReference();
|
|
if (rendererTex.GetReferenceCount() > 0)
|
|
return;
|
|
this.EndBatch();
|
|
if (rendererTex === this._lastTexture0) {
|
|
this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
this._lastTexture0 = null
|
|
}
|
|
if (rendererTex === this._lastTexture1) {
|
|
this._gl.activeTexture(this._gl.TEXTURE1);
|
|
this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
this._gl.activeTexture(this._gl.TEXTURE0);
|
|
this._lastTexture1 = null
|
|
}
|
|
rendererTex._Delete()
|
|
}
|
|
CreateRenderTarget(opts) {
|
|
let width = this._width;
|
|
let height = this._height;
|
|
let isDefaultSize = true;
|
|
if (opts) {
|
|
if (typeof opts.width === "number") {
|
|
width = opts.width;
|
|
isDefaultSize = false
|
|
}
|
|
if (typeof opts.height === "number") {
|
|
height = opts.height;
|
|
isDefaultSize = false
|
|
}
|
|
}
|
|
if (width <= 0 || height <= 0)
|
|
throw new Error("invalid size");
|
|
this.EndBatch();
|
|
const renderTarget = C3.New(C3.Gfx.WebGLRenderTarget, this);
|
|
renderTarget._Create(width, height, Object.assign({
|
|
isDefaultSize
|
|
}, opts));
|
|
this._currentRenderTarget = null;
|
|
this._batchState.currentFramebuffer = null;
|
|
return renderTarget
|
|
}
|
|
SetRenderTarget(renderTarget) {
|
|
if (renderTarget === this._currentRenderTarget)
|
|
return;
|
|
let newViewWidth, newViewHeight, newSurfaceWidth, newSurfaceHeight;
|
|
if (renderTarget) {
|
|
if (renderTarget.IsDefaultSize())
|
|
renderTarget._Resize(this._width, this._height);
|
|
newSurfaceWidth = renderTarget.GetWidth();
|
|
newSurfaceHeight = renderTarget.GetHeight();
|
|
newViewWidth = newSurfaceWidth;
|
|
newViewHeight = newSurfaceHeight
|
|
} else {
|
|
newSurfaceWidth = this._width;
|
|
newSurfaceHeight = this._height;
|
|
newViewWidth = this.GetScissoredViewportWidth();
|
|
newViewHeight = this.GetScissoredViewportHeight()
|
|
}
|
|
const didSurfaceSizeChange = this._lastBackbufferWidth !== newSurfaceWidth || this._lastBackbufferHeight !== newSurfaceHeight;
|
|
if (didSurfaceSizeChange)
|
|
this._UpdateViewportRenderer(newViewWidth, newViewHeight, newSurfaceWidth, newSurfaceHeight);
|
|
const b = this.PushBatch();
|
|
b.InitSetRenderTarget(renderTarget, didSurfaceSizeChange, this._matP);
|
|
this._currentRenderTarget = renderTarget;
|
|
this._topOfBatch = 0
|
|
}
|
|
GetRenderTarget() {
|
|
return this._currentRenderTarget
|
|
}
|
|
GetRenderTargetSize(renderTarget) {
|
|
if (renderTarget)
|
|
return [renderTarget.GetWidth(), renderTarget.GetHeight()];
|
|
else
|
|
return [this._width, this._height]
|
|
}
|
|
CopyRenderTarget(renderTarget, mode="stretch") {
|
|
if (this._version < 2 || this._currentRenderTarget && this._currentRenderTarget.GetMultisampling() > 0) {
|
|
this.SetCopyBlend();
|
|
this.ResetColor();
|
|
this.DrawRenderTarget(renderTarget, mode)
|
|
} else {
|
|
const b = this.PushBatch();
|
|
b.InitBlitFramebuffer(renderTarget, this._currentRenderTarget, mode);
|
|
this._topOfBatch = 0
|
|
}
|
|
}
|
|
DrawRenderTarget(renderTarget, mode="stretch") {
|
|
const tex = renderTarget.GetTexture();
|
|
if (!tex)
|
|
throw new Error("not a texture-backed render target");
|
|
this.SetTexture(tex);
|
|
this.FullscreenQuad(mode, tex)
|
|
}
|
|
InvalidateRenderTarget(renderTarget) {
|
|
if (this._version < 2)
|
|
return;
|
|
const b = this.PushBatch();
|
|
b.InitInvalidateFramebuffer(renderTarget._GetFramebuffer());
|
|
this._topOfBatch = 0
|
|
}
|
|
DeleteRenderTarget(renderTarget) {
|
|
this.SetRenderTarget(null);
|
|
this.EndBatch();
|
|
const renderTex = renderTarget.GetTexture();
|
|
if (renderTex === this._lastTexture0) {
|
|
this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
this._lastTexture0 = null
|
|
}
|
|
if (renderTex === this._lastTexture1) {
|
|
this._gl.activeTexture(this._gl.TEXTURE1);
|
|
this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
this._gl.activeTexture(this._gl.TEXTURE0);
|
|
this._lastTexture1 = null
|
|
}
|
|
renderTarget._Delete()
|
|
}
|
|
async ReadBackRenderTargetToImageData(renderTarget, forceSynchronous, areaRect) {
|
|
this.EndBatch();
|
|
const oldRenderTarget = this._currentRenderTarget;
|
|
let width, height, framebuffer;
|
|
if (renderTarget) {
|
|
width = renderTarget.GetWidth();
|
|
height = renderTarget.GetHeight();
|
|
framebuffer = renderTarget._GetFramebuffer()
|
|
} else {
|
|
width = this.GetWidth();
|
|
height = this.GetHeight();
|
|
framebuffer = null
|
|
}
|
|
let x = 0;
|
|
let y = 0;
|
|
let areaWidth = width;
|
|
let areaHeight = height;
|
|
if (areaRect) {
|
|
x = C3.clamp(Math.floor(areaRect.getLeft()), 0, width - 1);
|
|
y = C3.clamp(Math.floor(areaRect.getTop()), 0, height - 1);
|
|
let w = areaRect.width();
|
|
if (w === 0)
|
|
w = width - x;
|
|
else
|
|
w = C3.clamp(Math.floor(w), 0, width - x);
|
|
let h = areaRect.height();
|
|
if (h === 0)
|
|
h = height - y;
|
|
else
|
|
h = C3.clamp(Math.floor(h), 0, height - y);
|
|
areaWidth = w;
|
|
areaHeight = h;
|
|
y = height - (y + areaHeight)
|
|
}
|
|
const gl = this._gl;
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
|
const restorePreviousRenderTarget = ()=>{
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
this._currentRenderTarget = null;
|
|
this._batchState.currentFramebuffer = null;
|
|
this.SetRenderTarget(oldRenderTarget)
|
|
}
|
|
;
|
|
let imageData;
|
|
if (!forceSynchronous && this.GetWebGLVersionNumber() >= 2) {
|
|
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, framebuffer);
|
|
const pixelBuffer = gl.createBuffer();
|
|
const bufferSize = areaWidth * areaHeight * 4;
|
|
const PIXEL_PACK_BUFFER = gl["PIXEL_PACK_BUFFER"];
|
|
gl.bindBuffer(PIXEL_PACK_BUFFER, pixelBuffer);
|
|
gl.bufferData(PIXEL_PACK_BUFFER, bufferSize, gl["STREAM_READ"]);
|
|
gl.readPixels(x, y, areaWidth, areaHeight, gl.RGBA, gl.UNSIGNED_BYTE, 0);
|
|
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
|
|
gl.bindBuffer(PIXEL_PACK_BUFFER, null);
|
|
restorePreviousRenderTarget();
|
|
const sync = gl["fenceSync"](gl["SYNC_GPU_COMMANDS_COMPLETE"], 0);
|
|
await this._WaitForObjectReady(()=>gl["getSyncParameter"](sync, gl["SYNC_STATUS"]) === gl["SIGNALED"]);
|
|
gl["deleteSync"](sync);
|
|
imageData = new ImageData(areaWidth,areaHeight);
|
|
gl.bindBuffer(PIXEL_PACK_BUFFER, pixelBuffer);
|
|
gl["getBufferSubData"](PIXEL_PACK_BUFFER, 0, new Uint8Array(imageData.data.buffer), 0, bufferSize);
|
|
gl.bindBuffer(PIXEL_PACK_BUFFER, null);
|
|
gl.deleteBuffer(pixelBuffer)
|
|
} else {
|
|
imageData = new ImageData(areaWidth,areaHeight);
|
|
gl.readPixels(x, y, areaWidth, areaHeight, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(imageData.data.buffer));
|
|
restorePreviousRenderTarget()
|
|
}
|
|
return imageData
|
|
}
|
|
StartQuery(query) {
|
|
if (!this.SupportsGPUProfiling())
|
|
return;
|
|
const b = this.PushBatch();
|
|
b.InitStartQuery(query);
|
|
this._topOfBatch = 0
|
|
}
|
|
EndQuery(query) {
|
|
if (!this.SupportsGPUProfiling())
|
|
return;
|
|
const b = this.PushBatch();
|
|
b.InitEndQuery(query);
|
|
this._topOfBatch = 0
|
|
}
|
|
_WaitForObjectReady(checkFunc) {
|
|
const ret = new Promise(resolve=>pendingPolls.add({
|
|
resolve,
|
|
checkFunc
|
|
}));
|
|
if (pollRafId === -1)
|
|
pollRafId = self.requestAnimationFrame(CheckPendingPolls);
|
|
return ret
|
|
}
|
|
IsDesynchronized() {
|
|
return !!this._attribs["desynchronized"]
|
|
}
|
|
GetEstimatedBackBufferMemoryUsage() {
|
|
return this._width * this._height * (this._attribs["alpha"] ? 4 : 3)
|
|
}
|
|
GetEstimatedRenderBufferMemoryUsage() {
|
|
let ret = 0;
|
|
for (const t of C3.Gfx.WebGLRenderTarget.allRenderTargets()) {
|
|
if (t.GetTexture())
|
|
continue;
|
|
ret += t.GetEstimatedMemoryUsage()
|
|
}
|
|
return ret
|
|
}
|
|
GetEstimatedTextureMemoryUsage() {
|
|
let ret = 0;
|
|
for (const t of C3.Gfx.WebGLRendererTexture.allTextures())
|
|
ret += t.GetEstimatedMemoryUsage();
|
|
return ret
|
|
}
|
|
GetEstimatedTotalMemoryUsage() {
|
|
return this.GetEstimatedBackBufferMemoryUsage() + this.GetEstimatedRenderBufferMemoryUsage() + this.GetEstimatedTextureMemoryUsage()
|
|
}
|
|
GetWebGLVersionString() {
|
|
return this._versionString
|
|
}
|
|
GetWebGLVersionNumber() {
|
|
return this._version
|
|
}
|
|
SupportsNPOTTextures() {
|
|
return this.GetWebGLVersionNumber() >= 2
|
|
}
|
|
GetMaxTextureSize() {
|
|
return this._maxTextureSize
|
|
}
|
|
GetMinPointSize() {
|
|
return this._minPointSize
|
|
}
|
|
GetMaxPointSize() {
|
|
return this._maxPointSize
|
|
}
|
|
SupportsHighP() {
|
|
return this._highpPrecision !== 0
|
|
}
|
|
GetHighPPrecision() {
|
|
return this._highpPrecision
|
|
}
|
|
GetUnmaskedVendor() {
|
|
return this._unmaskedVendor
|
|
}
|
|
GetUnmaskedRenderer() {
|
|
return this._unmaskedRenderer
|
|
}
|
|
GetExtensions() {
|
|
return this._extensions
|
|
}
|
|
HasMajorPerformanceCaveat() {
|
|
return this._hasMajorPerformanceCaveat
|
|
}
|
|
SupportsGPUProfiling() {
|
|
return !!this._timerExt
|
|
}
|
|
_GetDisjointTimerQueryExtension() {
|
|
return this._timerExt
|
|
}
|
|
_GetParallelShaderCompileExtension() {
|
|
return this._parallelShaderCompileExt
|
|
}
|
|
_AddQueryResultBuffer(qrb) {
|
|
this._allQueryResultBuffers.add(qrb)
|
|
}
|
|
_RemoveQueryResultBuffer(qrb) {
|
|
this._allQueryResultBuffers.delete(qrb)
|
|
}
|
|
_GetTimeQueryStack() {
|
|
return this._timeQueryStack
|
|
}
|
|
GetContext() {
|
|
return this._gl
|
|
}
|
|
_InitBlendModes(gl) {
|
|
this._InitBlendModeData([["normal", gl.ONE, gl.ONE_MINUS_SRC_ALPHA], ["additive", gl.ONE, gl.ONE], ["xor", gl.ONE, gl.ONE_MINUS_SRC_ALPHA], ["copy", gl.ONE, gl.ZERO], ["destination-over", gl.ONE_MINUS_DST_ALPHA, gl.ONE], ["source-in", gl.DST_ALPHA, gl.ZERO], ["destination-in", gl.ZERO, gl.SRC_ALPHA], ["source-out", gl.ONE_MINUS_DST_ALPHA, gl.ZERO], ["destination-out", gl.ZERO, gl.ONE_MINUS_SRC_ALPHA], ["source-atop", gl.DST_ALPHA, gl.ONE_MINUS_SRC_ALPHA], ["destination-atop", gl.ONE_MINUS_DST_ALPHA, gl.SRC_ALPHA]])
|
|
}
|
|
CreateRendererText() {
|
|
return C3.New(C3.Gfx.RendererText, this)
|
|
}
|
|
CreateWebGLText() {
|
|
return this.CreateRendererText()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
let runtime = null;
|
|
const keysDownByKey = new Set;
|
|
function SortZOrderList(a, b) {
|
|
const layerA = a[0];
|
|
const layerB = b[0];
|
|
const diff = layerA - layerB;
|
|
if (diff !== 0)
|
|
return diff;
|
|
const indexA = a[1];
|
|
const indexB = b[1];
|
|
return indexA - indexB
|
|
}
|
|
const tempZOrderList = [];
|
|
const tempInstances = [];
|
|
let didWarnInAlertPolyfill = false;
|
|
self.IRuntime = class IRuntime {
|
|
constructor(runtime_, objects) {
|
|
runtime = runtime_;
|
|
Object.defineProperties(this, {
|
|
assets: {
|
|
value: runtime.GetAssetManager().GetIAssetManager(),
|
|
writable: false
|
|
},
|
|
objects: {
|
|
value: objects,
|
|
writable: false
|
|
},
|
|
globalVars: {
|
|
value: {},
|
|
writable: false
|
|
},
|
|
projectName: {
|
|
value: runtime.GetProjectName(),
|
|
writable: false
|
|
},
|
|
projectVersion: {
|
|
value: runtime.GetProjectVersion(),
|
|
writable: false
|
|
},
|
|
storage: {
|
|
value: new self.IStorage(runtime),
|
|
writable: false
|
|
},
|
|
isInWorker: {
|
|
value: runtime.IsInWorker(),
|
|
writable: false
|
|
}
|
|
});
|
|
runtime.UserScriptDispatcher().addEventListener("keydown", e=>{
|
|
if (keysDownByKey.has(e["key"])) {
|
|
e.stopPropagation();
|
|
return
|
|
}
|
|
keysDownByKey.add(e["key"])
|
|
}
|
|
);
|
|
runtime.UserScriptDispatcher().addEventListener("keyup", e=>keysDownByKey.delete(e["key"]));
|
|
runtime.Dispatcher().addEventListener("window-blur", ()=>keysDownByKey.clear());
|
|
if (runtime.IsInWorker())
|
|
self["alert"] = message=>{
|
|
if (!didWarnInAlertPolyfill) {
|
|
didWarnInAlertPolyfill = true;
|
|
console.warn("[Construct 3] alert() was called from a Web Worker, because the project 'Use worker' setting is enabled. This method is not normally available in a Web Worker. Construct has implemented the alert for you, but note that other features may be missing in worker mode. You may wish to disable 'Use worker', or use a more convenient function like console.log(). For more information please refer to the scripting section of the manual.")
|
|
}
|
|
return this.alert(message)
|
|
}
|
|
}
|
|
_InitGlobalVars(globalVarDescriptors) {
|
|
Object.defineProperties(this.globalVars, globalVarDescriptors)
|
|
}
|
|
addEventListener(name, func) {
|
|
runtime.UserScriptDispatcher().addEventListener(name, func)
|
|
}
|
|
removeEventListener(name, func) {
|
|
runtime.UserScriptDispatcher().removeEventListener(name, func)
|
|
}
|
|
callFunction(name, ...params) {
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const functionBlock = eventSheetManager.GetFunctionBlockByName(name);
|
|
if (!functionBlock)
|
|
throw new Error(`cannot find function name '${name}'`);
|
|
if (!functionBlock.IsEnabled())
|
|
return functionBlock.GetDefaultReturnValue();
|
|
if (params.length < functionBlock.GetFunctionParameterCount())
|
|
throw new Error(`not enough function parameters passed for '${name}' (${params.length} passed, ${functionBlock.GetFunctionParameterCount()} expected)`);
|
|
const callEventBlock = functionBlock.GetEventBlock();
|
|
let solModifiers = null;
|
|
const currentEvent = eventSheetManager.GetCurrentEvent();
|
|
if (currentEvent) {
|
|
const sm = currentEvent.GetSolModifiersIncludingParents();
|
|
if (sm.length > 0) {
|
|
solModifiers = sm;
|
|
eventSheetManager.PushCleanSol(sm)
|
|
}
|
|
}
|
|
const ret = callEventBlock.RunAsExpressionFunctionCall(callEventBlock.GetSolModifiersIncludingParents(), functionBlock.GetReturnType(), functionBlock.GetDefaultReturnValue(), ...params);
|
|
if (solModifiers)
|
|
eventSheetManager.PopSol(solModifiers);
|
|
return ret
|
|
}
|
|
setReturnValue(v) {
|
|
const frame = runtime.GetEventStack().GetCurrentExpFuncStackFrame();
|
|
if (!frame)
|
|
throw new Error("not in a function which returns a value");
|
|
switch (frame.GetFunctionReturnType()) {
|
|
case 1:
|
|
if (typeof v === "number")
|
|
frame.SetFunctionReturnValue(v);
|
|
break;
|
|
case 2:
|
|
if (typeof v === "string")
|
|
frame.SetFunctionReturnValue(v);
|
|
break;
|
|
case 3:
|
|
if (typeof v === "number" || typeof v === "string")
|
|
frame.SetFunctionReturnValue(v);
|
|
break
|
|
}
|
|
}
|
|
get dt() {
|
|
return runtime.GetDt()
|
|
}
|
|
get gameTime() {
|
|
return runtime.GetGameTime()
|
|
}
|
|
get wallTime() {
|
|
return runtime.GetWallTime()
|
|
}
|
|
random() {
|
|
return runtime.Random()
|
|
}
|
|
get layout() {
|
|
return runtime.GetMainRunningLayout().GetILayout()
|
|
}
|
|
getLayout(nameOrIndex) {
|
|
const layoutManager = runtime.GetLayoutManager();
|
|
let layout = null;
|
|
if (typeof nameOrIndex === "number" || typeof nameOrIndex === "string")
|
|
layout = layoutManager.GetLayout(nameOrIndex);
|
|
else
|
|
throw new TypeError("expected string or number");
|
|
if (!layout)
|
|
throw new Error("invalid layout");
|
|
return layout.GetILayout()
|
|
}
|
|
getAllLayouts() {
|
|
return runtime.GetLayoutManager().GetAllLayouts().map(layout=>layout.GetILayout())
|
|
}
|
|
goToLayout(nameOrIndex) {
|
|
const layoutManager = runtime.GetLayoutManager();
|
|
let layout = null;
|
|
if (typeof nameOrIndex === "number" || typeof nameOrIndex === "string")
|
|
layout = layoutManager.GetLayout(nameOrIndex);
|
|
else
|
|
throw new TypeError("expected string or number");
|
|
if (!layout)
|
|
throw new Error("invalid layout");
|
|
if (layoutManager.IsPendingChangeMainLayout())
|
|
return;
|
|
layoutManager.ChangeMainLayout(layout)
|
|
}
|
|
get keyboard() {
|
|
const ret = runtime._GetCommonScriptInterfaces().keyboard;
|
|
if (!ret)
|
|
throw new Error("runtime.keyboard used but Keyboard object missing - add it to your project first");
|
|
return ret
|
|
}
|
|
get mouse() {
|
|
const ret = runtime._GetCommonScriptInterfaces().mouse;
|
|
if (!ret)
|
|
throw new Error("runtime.mouse used but Mouse object missing - add it to your project first");
|
|
return ret
|
|
}
|
|
get touch() {
|
|
const ret = runtime._GetCommonScriptInterfaces().touch;
|
|
if (!ret)
|
|
throw new Error("runtime.touch used but Touch object missing - add it to your project first");
|
|
return ret
|
|
}
|
|
invokeDownload(url, filename) {
|
|
runtime.InvokeDownload(url, filename)
|
|
}
|
|
getInstanceByUid(uid) {
|
|
const ret = runtime.GetInstanceByUID(uid);
|
|
return ret ? ret.GetInterfaceClass() : null
|
|
}
|
|
sortZOrder(iterable, callback) {
|
|
const layout = runtime.GetCurrentLayout();
|
|
for (const iinst of iterable) {
|
|
const inst = runtime._UnwrapScriptInterface(iinst);
|
|
if (!inst || !inst.GetWorldInfo())
|
|
throw new Error("invalid instance");
|
|
const wi = inst.GetWorldInfo();
|
|
tempZOrderList.push([wi.GetLayer().GetIndex(), wi.GetZIndex()]);
|
|
tempInstances.push(inst)
|
|
}
|
|
if (tempZOrderList.length === 0)
|
|
return;
|
|
tempZOrderList.sort(SortZOrderList);
|
|
tempInstances.sort((a,b)=>callback(a.GetInterfaceClass(), b.GetInterfaceClass()));
|
|
let anyChanged = false;
|
|
for (let i = 0, len = tempZOrderList.length; i < len; ++i) {
|
|
const inst = tempInstances[i];
|
|
const layer = layout.GetLayerByIndex(tempZOrderList[i][0]);
|
|
const toZ = tempZOrderList[i][1];
|
|
const layerInstances = layer._GetInstances();
|
|
if (layerInstances[toZ] !== inst) {
|
|
layerInstances[toZ] = inst;
|
|
inst.GetWorldInfo()._SetLayer(layer);
|
|
layer.SetZIndicesChanged();
|
|
anyChanged = true
|
|
}
|
|
}
|
|
if (anyChanged)
|
|
runtime.UpdateRender();
|
|
C3.clearArray(tempZOrderList);
|
|
C3.clearArray(tempInstances)
|
|
}
|
|
alert(message) {
|
|
return runtime.PostComponentMessageToDOMAsync("runtime", "alert", {
|
|
"message": message + (runtime.IsInWorker() ? " [via Web Worker]" : "")
|
|
})
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
let assetManager = null;
|
|
self.IAssetManager = class IAssetManager {
|
|
constructor(assetManager_) {
|
|
assetManager = assetManager_;
|
|
Object.defineProperties(this, {
|
|
isWebMOpusSupported: {
|
|
value: assetManager.IsAudioFormatSupported("audio/webm; codecs=opus"),
|
|
writable: false
|
|
}
|
|
})
|
|
}
|
|
fetchText(url) {
|
|
return assetManager.FetchText(url)
|
|
}
|
|
fetchJson(url) {
|
|
return assetManager.FetchJson(url)
|
|
}
|
|
fetchBlob(url) {
|
|
return assetManager.FetchBlob(url)
|
|
}
|
|
fetchArrayBuffer(url) {
|
|
return assetManager.FetchArrayBuffer(url)
|
|
}
|
|
getProjectFileUrl(url) {
|
|
return assetManager.GetProjectFileUrl(url)
|
|
}
|
|
getMediaFileUrl(url) {
|
|
if (C3.IsRelativeURL(url))
|
|
url = url.toLowerCase();
|
|
return assetManager.GetMediaFileUrl(url, assetManager.GetMediaSubfolder())
|
|
}
|
|
get mediaFolder() {
|
|
return assetManager.GetMediaSubfolder()
|
|
}
|
|
async decodeWebMOpus(audioContext, arrayBuffer) {
|
|
if (this.isWebMOpusSupported)
|
|
throw new Error("decodeWebMOpus(): not supported because WebM Opus is supported by the platform");
|
|
const decodedArrayBuffer = await assetManager.GetRuntime()._WasmDecodeWebMOpus(arrayBuffer);
|
|
const decodedFloats = new Float32Array(decodedArrayBuffer);
|
|
const audioBuffer = audioContext["createBuffer"](1, decodedFloats.length, 48E3);
|
|
const channelBuffer = audioBuffer["getChannelData"](0);
|
|
channelBuffer.set(decodedFloats);
|
|
return audioBuffer
|
|
}
|
|
loadScripts(...urls) {
|
|
return assetManager.LoadScripts(...urls)
|
|
}
|
|
compileWebAssembly(url) {
|
|
return assetManager.CompileWebAssembly(url)
|
|
}
|
|
loadStyleSheet(url) {
|
|
return assetManager.LoadStyleSheet(url)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
self.IStorage = class IStorage {
|
|
constructor(runtime) {
|
|
this._storage = runtime._GetProjectStorage()
|
|
}
|
|
getItem(key) {
|
|
return this._storage.getItem(key)
|
|
}
|
|
setItem(key, value) {
|
|
return this._storage.setItem(key, value)
|
|
}
|
|
removeItem(key) {
|
|
return this._storage.removeItem(key)
|
|
}
|
|
clear() {
|
|
return this._storage.clear()
|
|
}
|
|
keys() {
|
|
return this._storage.keys()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const map = new WeakMap;
|
|
self.IObjectClass = class IObjectClass {
|
|
constructor(objectClass) {
|
|
map.set(this, objectClass);
|
|
Object.defineProperties(this, {
|
|
name: {
|
|
value: objectClass.GetName(),
|
|
writable: false
|
|
}
|
|
});
|
|
objectClass.GetRuntime()._MapScriptInterface(this, objectClass)
|
|
}
|
|
addEventListener(name, func) {
|
|
map.get(this).UserScriptDispatcher().addEventListener(name, func)
|
|
}
|
|
removeEventListener(name, func) {
|
|
map.get(this).UserScriptDispatcher().removeEventListener(name, func)
|
|
}
|
|
getAllInstances() {
|
|
return map.get(this).GetInstances().map(inst=>inst.GetInterfaceClass())
|
|
}
|
|
getFirstInstance() {
|
|
const instances = map.get(this).GetInstances();
|
|
if (instances.length > 0)
|
|
return instances[0].GetInterfaceClass();
|
|
else
|
|
return null
|
|
}
|
|
getPickedInstances() {
|
|
return map.get(this).GetCurrentSol().GetInstances().map(inst=>inst.GetInterfaceClass())
|
|
}
|
|
getFirstPickedInstance() {
|
|
const pickedInstances = map.get(this).GetCurrentSol().GetInstances();
|
|
if (pickedInstances.length > 0)
|
|
return pickedInstances[0].GetInterfaceClass();
|
|
else
|
|
return null
|
|
}
|
|
*instances() {
|
|
for (const inst of map.get(this).GetInstances())
|
|
yield inst.GetInterfaceClass()
|
|
}
|
|
*pickedInstances() {
|
|
for (const inst of map.get(this).GetCurrentSol().GetInstances())
|
|
yield inst.GetInterfaceClass()
|
|
}
|
|
setInstanceClass(Class) {
|
|
const objectClass = map.get(this);
|
|
if (objectClass.GetInstanceCount() > 0)
|
|
throw new Error("setInstanceClass() called too late, because instances have already been created - call in runOnStartup");
|
|
map.get(this)._SetUserScriptInstanceClass(Class)
|
|
}
|
|
createInstance(layerNameOrIndex, x, y) {
|
|
if (typeof layerNameOrIndex !== "number" && typeof layerNameOrIndex !== "string")
|
|
throw new TypeError("invalid layer parameter");
|
|
const objectClass = map.get(this);
|
|
const runtime = objectClass.GetRuntime();
|
|
const layer = runtime.GetMainRunningLayout().GetLayer(layerNameOrIndex);
|
|
if (!layer)
|
|
throw new Error("invalid layer");
|
|
const inst = runtime.CreateInstance(objectClass, layer, x, y);
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
eventSheetManager.BlockFlushingInstances(true);
|
|
inst._TriggerOnCreated();
|
|
if (inst.IsInContainer())
|
|
for (const s of inst.siblings())
|
|
s._TriggerOnCreated();
|
|
eventSheetManager.BlockFlushingInstances(false);
|
|
return inst.GetInterfaceClass()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const map = new WeakMap;
|
|
self.ILayout = class ILayout {
|
|
constructor(layout) {
|
|
map.set(this, layout);
|
|
const effectInstanceArr = [];
|
|
const effectList = layout.GetEffectList();
|
|
const effectCount = effectList.GetAllEffectTypes().length;
|
|
for (let i = 0; i < effectCount; ++i)
|
|
effectInstanceArr.push(new self.IEffectInstance(effectList,i));
|
|
Object.defineProperties(this, {
|
|
name: {
|
|
value: layout.GetName(),
|
|
writable: false
|
|
},
|
|
index: {
|
|
value: layout.GetIndex(),
|
|
writable: false
|
|
},
|
|
effects: {
|
|
value: effectInstanceArr,
|
|
writable: false
|
|
}
|
|
})
|
|
}
|
|
addEventListener(name, func) {
|
|
map.get(this).UserScriptDispatcher().addEventListener(name, func)
|
|
}
|
|
removeEventListener(name, func) {
|
|
map.get(this).UserScriptDispatcher().removeEventListener(name, func)
|
|
}
|
|
get width() {
|
|
return map.get(this).GetWidth()
|
|
}
|
|
set width(w) {
|
|
map.get(this).SetWidth(w)
|
|
}
|
|
get height() {
|
|
return map.get(this).GetHeight()
|
|
}
|
|
set height(h) {
|
|
map.get(this).SetHeight(h)
|
|
}
|
|
scrollTo(x, y) {
|
|
const layout = map.get(this);
|
|
layout.SetScrollX(x);
|
|
layout.SetScrollY(y)
|
|
}
|
|
getLayer(nameOrIndex) {
|
|
const layout = map.get(this);
|
|
let layer = null;
|
|
if (typeof nameOrIndex === "number" || typeof nameOrIndex === "string")
|
|
layer = layout.GetLayer(nameOrIndex);
|
|
else
|
|
throw new TypeError("expected string or number");
|
|
if (!layer)
|
|
throw new Error("invalid layer");
|
|
return layer.GetILayer()
|
|
}
|
|
getAllLayers() {
|
|
return map.get(this).GetLayers().map(layer=>layer.GetILayer())
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const map = new WeakMap;
|
|
self.ILayer = class ILayer {
|
|
constructor(layer) {
|
|
map.set(this, layer);
|
|
const effectInstanceArr = [];
|
|
const effectList = layer.GetEffectList();
|
|
const effectCount = effectList.GetAllEffectTypes().length;
|
|
for (let i = 0; i < effectCount; ++i)
|
|
effectInstanceArr.push(new self.IEffectInstance(effectList,i));
|
|
Object.defineProperties(this, {
|
|
name: {
|
|
value: layer.GetName(),
|
|
writable: false
|
|
},
|
|
index: {
|
|
value: layer.GetIndex(),
|
|
writable: false
|
|
},
|
|
layout: {
|
|
value: layer.GetLayout().GetILayout(),
|
|
writable: false
|
|
},
|
|
effects: {
|
|
value: effectInstanceArr,
|
|
writable: false
|
|
}
|
|
})
|
|
}
|
|
static _Unwrap(ilayer) {
|
|
return map.get(ilayer)
|
|
}
|
|
get isVisible() {
|
|
return map.get(this).IsVisible()
|
|
}
|
|
set isVisible(v) {
|
|
map.get(this).SetVisible(v)
|
|
}
|
|
get opacity() {
|
|
return map.get(this).GetOpacity()
|
|
}
|
|
set opacity(o) {
|
|
o = C3.clamp(+o, 0, 1);
|
|
if (isNaN(o))
|
|
return;
|
|
map.get(this).SetOpacity(o)
|
|
}
|
|
getViewport() {
|
|
return map.get(this).GetViewport().toDOMRect()
|
|
}
|
|
cssPxToLayer(clientX, clientY, z=0) {
|
|
const layer = map.get(this);
|
|
const runtime = layer.GetRuntime();
|
|
return layer.CanvasCssToLayer(clientX - runtime.GetCanvasClientX(), clientY - runtime.GetCanvasClientY(), z)
|
|
}
|
|
layerToCssPx(layerX, layerY, z=0) {
|
|
const layer = map.get(this);
|
|
const runtime = layer.GetRuntime();
|
|
const [clientX,clientY] = layer.LayerToCanvasCss(layerX, layerY, z);
|
|
return [clientX + runtime.GetCanvasClientX(), clientY + runtime.GetCanvasClientY()]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const map = new WeakMap;
|
|
const dispatchers = new WeakMap;
|
|
function GetDispatcher(iinst) {
|
|
let dispatcher = dispatchers.get(iinst);
|
|
if (dispatcher)
|
|
return dispatcher;
|
|
dispatcher = C3.New(C3.Event.Dispatcher);
|
|
dispatchers.set(iinst, dispatcher);
|
|
return dispatcher
|
|
}
|
|
let initInst = null;
|
|
self.IInstance = class IInstance {
|
|
constructor() {
|
|
map.set(this, initInst);
|
|
const descriptors = {
|
|
runtime: {
|
|
value: initInst.GetRuntime().GetIRuntime(),
|
|
writable: false
|
|
},
|
|
objectType: {
|
|
value: initInst.GetObjectClass().GetIObjectClass(),
|
|
writable: false
|
|
},
|
|
uid: {
|
|
value: initInst.GetUID(),
|
|
writable: false
|
|
}
|
|
};
|
|
initInst._GetInstVarsScriptDescriptor(descriptors);
|
|
initInst._GetBehaviorsScriptDescriptor(descriptors);
|
|
Object.defineProperties(this, descriptors);
|
|
initInst.GetRuntime()._MapScriptInterface(this, initInst)
|
|
}
|
|
static _Init(inst) {
|
|
initInst = inst
|
|
}
|
|
static _GetInitInst() {
|
|
return initInst
|
|
}
|
|
_Release() {
|
|
const dispatcher = dispatchers.get(this);
|
|
if (dispatcher) {
|
|
dispatcher.Release();
|
|
dispatchers.delete(this)
|
|
}
|
|
map.delete(this)
|
|
}
|
|
addEventListener(type, func, capture) {
|
|
GetDispatcher(this).addEventListener(type, func, capture)
|
|
}
|
|
removeEventListener(type, func, capture) {
|
|
GetDispatcher(this).removeEventListener(type, func, capture)
|
|
}
|
|
dispatchEvent(e) {
|
|
GetDispatcher(this).dispatchEvent(e)
|
|
}
|
|
destroy() {
|
|
const inst = map.get(this);
|
|
inst.GetRuntime().DestroyInstance(inst)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const IInstance = self.IInstance;
|
|
const ILayer = self.ILayer;
|
|
const map = new WeakMap;
|
|
const BLEND_MODE_TO_INDEX = new Map([["normal", 0], ["additive", 1], ["copy", 3], ["destination-over", 4], ["source-in", 5], ["destination-in", 6], ["source-out", 7], ["destination-out", 8], ["source-atop", 9], ["destination-atop", 10]]);
|
|
const INDEX_TO_BLEND_MODE = new Map([...BLEND_MODE_TO_INDEX.entries()].map(a=>[a[1], a[0]]));
|
|
const tempColor = C3.New(C3.Color);
|
|
self.IWorldInstance = class IWorldInstance extends IInstance {
|
|
constructor() {
|
|
super();
|
|
const inst = IInstance._GetInitInst();
|
|
map.set(this, inst);
|
|
const effectInstanceArr = [];
|
|
const wi = inst.GetWorldInfo();
|
|
const instanceEffectList = wi.GetInstanceEffectList();
|
|
if (instanceEffectList) {
|
|
const effectCount = wi.GetObjectClass().GetEffectList().GetAllEffectTypes().length;
|
|
for (let i = 0; i < effectCount; ++i)
|
|
effectInstanceArr.push(new self.IEffectInstance(instanceEffectList,i))
|
|
}
|
|
const descriptors = {
|
|
effects: {
|
|
value: effectInstanceArr,
|
|
writable: false
|
|
}
|
|
};
|
|
Object.defineProperties(this, descriptors)
|
|
}
|
|
get layout() {
|
|
return map.get(this).GetWorldInfo().GetLayout().GetILayout()
|
|
}
|
|
get layer() {
|
|
return map.get(this).GetWorldInfo().GetLayer().GetILayer()
|
|
}
|
|
get x() {
|
|
return map.get(this).GetWorldInfo().GetX()
|
|
}
|
|
set x(v) {
|
|
v = +v;
|
|
const wi = map.get(this).GetWorldInfo();
|
|
if (isNaN(v) || wi.GetX() === v)
|
|
return;
|
|
wi.SetX(v);
|
|
wi.SetBboxChanged()
|
|
}
|
|
get y() {
|
|
return map.get(this).GetWorldInfo().GetY()
|
|
}
|
|
set y(v) {
|
|
v = +v;
|
|
const wi = map.get(this).GetWorldInfo();
|
|
if (isNaN(v) || wi.GetY() === v)
|
|
return;
|
|
wi.SetY(v);
|
|
wi.SetBboxChanged()
|
|
}
|
|
get zElevation() {
|
|
return map.get(this).GetWorldInfo().GetZElevation()
|
|
}
|
|
set zElevation(z) {
|
|
z = +z;
|
|
const inst = map.get(this);
|
|
const wi = inst.GetWorldInfo();
|
|
if (wi.GetZElevation() === z)
|
|
return;
|
|
wi.SetZElevation(z);
|
|
inst.GetRuntime().UpdateRender()
|
|
}
|
|
get totalZElevation() {
|
|
return map.get(this).GetWorldInfo().GetTotalZElevation()
|
|
}
|
|
get width() {
|
|
return map.get(this).GetWorldInfo().GetWidth()
|
|
}
|
|
set width(w) {
|
|
w = +w;
|
|
const wi = map.get(this).GetWorldInfo();
|
|
if (isNaN(w) || wi.GetWidth() === w)
|
|
return;
|
|
wi.SetWidth(w);
|
|
wi.SetBboxChanged()
|
|
}
|
|
get height() {
|
|
return map.get(this).GetWorldInfo().GetHeight()
|
|
}
|
|
set height(h) {
|
|
h = +h;
|
|
const wi = map.get(this).GetWorldInfo();
|
|
if (isNaN(h) || wi.GetHeight() === h)
|
|
return;
|
|
wi.SetHeight(h);
|
|
wi.SetBboxChanged()
|
|
}
|
|
get angle() {
|
|
return map.get(this).GetWorldInfo().GetAngle()
|
|
}
|
|
set angle(a) {
|
|
a = C3.clampAngle(+a);
|
|
const wi = map.get(this).GetWorldInfo();
|
|
if (isNaN(a) || wi.GetAngle() === a)
|
|
return;
|
|
wi.SetAngle(a);
|
|
wi.SetBboxChanged()
|
|
}
|
|
get angleDegrees() {
|
|
return C3.toDegrees(this.angle)
|
|
}
|
|
set angleDegrees(a) {
|
|
this.angle = C3.toRadians(a)
|
|
}
|
|
getBoundingBox() {
|
|
return map.get(this).GetWorldInfo().GetBoundingBox().toDOMRect()
|
|
}
|
|
getBoundingQuad() {
|
|
return map.get(this).GetWorldInfo().GetBoundingQuad().toDOMQuad()
|
|
}
|
|
get isVisible() {
|
|
return map.get(this).GetWorldInfo().IsVisible()
|
|
}
|
|
set isVisible(v) {
|
|
v = !!v;
|
|
const inst = map.get(this);
|
|
const wi = inst.GetWorldInfo();
|
|
if (wi.IsVisible() === v)
|
|
return;
|
|
wi.SetVisible(v);
|
|
inst.GetRuntime().UpdateRender()
|
|
}
|
|
get opacity() {
|
|
return map.get(this).GetWorldInfo().GetOpacity()
|
|
}
|
|
set opacity(o) {
|
|
o = C3.clamp(+o, 0, 1);
|
|
const inst = map.get(this);
|
|
const wi = inst.GetWorldInfo();
|
|
if (isNaN(o) || wi.GetOpacity() === o)
|
|
return;
|
|
wi.SetOpacity(o);
|
|
inst.GetRuntime().UpdateRender()
|
|
}
|
|
set colorRgb(arr) {
|
|
if (arr.length < 3)
|
|
throw new Error("expected 3 elements");
|
|
tempColor.setRgb(arr[0], arr[1], arr[2]);
|
|
const inst = map.get(this);
|
|
const wi = inst.GetWorldInfo();
|
|
if (wi.GetUnpremultipliedColor().equalsIgnoringAlpha(tempColor))
|
|
return;
|
|
wi.SetUnpremultipliedColor(tempColor);
|
|
inst.GetRuntime().UpdateRender()
|
|
}
|
|
get colorRgb() {
|
|
const c = map.get(this).GetWorldInfo().GetUnpremultipliedColor();
|
|
return [c.getR(), c.getG(), c.getB()]
|
|
}
|
|
set blendMode(bm) {
|
|
const index = BLEND_MODE_TO_INDEX.get(bm);
|
|
if (typeof index !== "number")
|
|
throw new Error("invalid blend mode");
|
|
const inst = map.get(this);
|
|
const wi = inst.GetWorldInfo();
|
|
wi.SetBlendMode(index);
|
|
inst.GetRuntime().UpdateRender()
|
|
}
|
|
get blendMode() {
|
|
return INDEX_TO_BLEND_MODE.get(map.get(this).GetWorldInfo().GetBlendMode())
|
|
}
|
|
moveToTop() {
|
|
map.get(this).GetWorldInfo().ZOrderMoveToTop()
|
|
}
|
|
moveToBottom() {
|
|
map.get(this).GetWorldInfo().ZOrderMoveToBottom()
|
|
}
|
|
moveToLayer(ilayer) {
|
|
const layer = ILayer._Unwrap(ilayer);
|
|
if (!layer)
|
|
throw new Error("invalid layer");
|
|
map.get(this).GetWorldInfo().ZOrderMoveToLayer(layer)
|
|
}
|
|
moveAdjacentToInstance(other, isAfter) {
|
|
map.get(this).GetWorldInfo().ZOrderMoveAdjacentToInstance(map.get(other), isAfter)
|
|
}
|
|
containsPoint(x, y) {
|
|
return map.get(this).GetWorldInfo().ContainsPoint(+x, +y)
|
|
}
|
|
testOverlap(worldInstance) {
|
|
const a = map.get(this);
|
|
const b = map.get(worldInstance);
|
|
return a.GetRuntime().GetCollisionEngine().TestOverlap(a, b)
|
|
}
|
|
testOverlapSolid() {
|
|
const inst = map.get(this);
|
|
const overlapInst = inst.GetRuntime().GetCollisionEngine().TestOverlapSolid(inst);
|
|
return overlapInst ? overlapInst.GetInterfaceClass() : null
|
|
}
|
|
getParent() {
|
|
const parent = map.get(this).GetParent();
|
|
return parent ? parent.GetInterfaceClass() : null
|
|
}
|
|
getTopParent() {
|
|
const parent = map.get(this).GetTopParent();
|
|
return parent ? parent.GetInterfaceClass() : null
|
|
}
|
|
*parents() {
|
|
for (const parent of map.get(this).parents())
|
|
yield parent.GetInterfaceClass()
|
|
}
|
|
getChildCount() {
|
|
return map.get(this).GetChildCount()
|
|
}
|
|
getChildAt(index) {
|
|
const child = map.get(this).GetChildAt(index);
|
|
return child ? child.GetInterfaceClass() : null
|
|
}
|
|
*children() {
|
|
for (const child of map.get(this).children())
|
|
yield child.GetInterfaceClass()
|
|
}
|
|
*allChildren() {
|
|
for (const child of map.get(this).allChildren())
|
|
yield child.GetInterfaceClass()
|
|
}
|
|
addChild(ichild, opts) {
|
|
if (!opts)
|
|
opts = {};
|
|
const inst = map.get(this);
|
|
const child = map.get(ichild);
|
|
inst.AddChild(child, opts)
|
|
}
|
|
removeChild(ichild) {
|
|
const inst = map.get(this);
|
|
const child = map.get(ichild);
|
|
inst.RemoveChild(child)
|
|
}
|
|
removeFromParent() {
|
|
const inst = map.get(this);
|
|
if (!inst.HasParent())
|
|
return;
|
|
const parent = inst.GetParent();
|
|
parent.RemoveChild(inst)
|
|
}
|
|
createMesh(hsize, vsize) {
|
|
map.get(this).GetWorldInfo().CreateMesh(hsize, vsize)
|
|
}
|
|
releaseMesh() {
|
|
const wi = map.get(this).GetWorldInfo();
|
|
wi.ReleaseMesh();
|
|
wi.SetBboxChanged()
|
|
}
|
|
setMeshPoint(col, row, opts) {
|
|
const wi = map.get(this).GetWorldInfo();
|
|
if (wi.SetMeshPoint(col, row, opts))
|
|
wi.SetBboxChanged()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const map = new WeakMap;
|
|
self.IDOMInstance = class IDOMInstance extends self.IWorldInstance {
|
|
constructor() {
|
|
super();
|
|
map.set(this, self.IInstance._GetInitInst())
|
|
}
|
|
getElement() {
|
|
return map.get(this).GetSdkInstance()._GetElementInDOMMode()
|
|
}
|
|
focus() {
|
|
map.get(this).GetSdkInstance().FocusElement()
|
|
}
|
|
blur() {
|
|
map.get(this).GetSdkInstance().BlurElement()
|
|
}
|
|
setCssStyle(prop, val) {
|
|
map.get(this).GetSdkInstance().SetElementCSSStyle(prop, val)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const map = new WeakMap;
|
|
const dispatchers = new WeakMap;
|
|
function GetDispatcher(ibehinst) {
|
|
let dispatcher = dispatchers.get(ibehinst);
|
|
if (dispatcher)
|
|
return dispatcher;
|
|
dispatcher = C3.New(C3.Event.Dispatcher);
|
|
dispatchers.set(ibehinst, dispatcher);
|
|
return dispatcher
|
|
}
|
|
let initBehInst = null;
|
|
self.IBehaviorInstance = class IBehaviorInstance {
|
|
constructor() {
|
|
map.set(this, initBehInst);
|
|
const descriptors = {
|
|
runtime: {
|
|
value: initBehInst.GetRuntime().GetIRuntime(),
|
|
writable: false
|
|
},
|
|
behavior: {
|
|
value: initBehInst.GetBehavior().GetIBehavior(),
|
|
writable: false
|
|
}
|
|
};
|
|
Object.defineProperties(this, descriptors)
|
|
}
|
|
static _Init(behInst) {
|
|
initBehInst = behInst
|
|
}
|
|
static _GetInitInst() {
|
|
return initBehInst
|
|
}
|
|
get instance() {
|
|
return map.get(this).GetObjectInstance().GetInterfaceClass()
|
|
}
|
|
_Release() {
|
|
const dispatcher = dispatchers.get(this);
|
|
if (dispatcher) {
|
|
dispatcher.Release();
|
|
dispatchers.delete(this)
|
|
}
|
|
map.delete(this)
|
|
}
|
|
addEventListener(type, func, capture) {
|
|
GetDispatcher(this).addEventListener(type, func, capture)
|
|
}
|
|
removeEventListener(type, func, capture) {
|
|
GetDispatcher(this).removeEventListener(type, func, capture)
|
|
}
|
|
dispatchEvent(e) {
|
|
GetDispatcher(this).dispatchEvent(e)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const map = new WeakMap;
|
|
self.IBehavior = class IBehavior {
|
|
constructor(behavior) {
|
|
map.set(this, behavior);
|
|
const descriptors = {
|
|
runtime: {
|
|
value: behavior.GetRuntime().GetIRuntime(),
|
|
writable: false
|
|
}
|
|
};
|
|
Object.defineProperties(this, descriptors)
|
|
}
|
|
getAllInstances() {
|
|
return map.get(this).GetInstances().map(inst=>inst.GetInterfaceClass())
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const map = new WeakMap;
|
|
self.IEffectInstance = class IEffectInstance {
|
|
constructor(effectList, index) {
|
|
map.set(this, effectList);
|
|
const descriptors = {
|
|
index: {
|
|
value: index,
|
|
writable: false
|
|
}
|
|
};
|
|
Object.defineProperties(this, descriptors)
|
|
}
|
|
get name() {
|
|
const effectTypes = map.get(this).GetAllEffectTypes();
|
|
return effectTypes[this.index].GetName()
|
|
}
|
|
get isActive() {
|
|
return map.get(this).IsEffectIndexActive(this.index)
|
|
}
|
|
set isActive(a) {
|
|
a = !!a;
|
|
const fxList = map.get(this);
|
|
if (fxList.IsEffectIndexActive(this.index) === a)
|
|
return;
|
|
fxList.SetEffectIndexActive(this.index, a);
|
|
fxList.UpdateActiveEffects();
|
|
fxList.GetRuntime().UpdateRender()
|
|
}
|
|
setParameter(i, v) {
|
|
i = Math.floor(+i);
|
|
const fxList = map.get(this);
|
|
const paramsArr = fxList.GetEffectParametersForIndex(this.index);
|
|
if (i < 0 || i >= paramsArr.length)
|
|
throw new RangeError("invalid effect parameter index");
|
|
const oldValue = paramsArr[i];
|
|
if (oldValue instanceof C3.Color) {
|
|
if (!Array.isArray(v) || v.length < 3)
|
|
throw new TypeError("expected array with 3 elements");
|
|
const r = v[0];
|
|
const g = v[1];
|
|
const b = v[2];
|
|
if (oldValue.equalsRgb(r, g, b))
|
|
return;
|
|
oldValue.setRgb(r, g, b)
|
|
} else {
|
|
if (typeof v !== "number")
|
|
throw new TypeError("expected number");
|
|
if (oldValue === v)
|
|
return;
|
|
paramsArr[i] = v
|
|
}
|
|
if (fxList.IsEffectIndexActive(this.index))
|
|
fxList.GetRuntime().UpdateRender()
|
|
}
|
|
getParameter(i) {
|
|
i = Math.floor(+i);
|
|
const fxList = map.get(this);
|
|
const paramsArr = fxList.GetEffectParametersForIndex(this.index);
|
|
if (i < 0 || i >= paramsArr.length)
|
|
throw new RangeError("invalid effect parameter index");
|
|
const ret = paramsArr[i];
|
|
if (ret instanceof C3.Color)
|
|
return [ret.getR(), ret.getG(), ret.getB()];
|
|
else
|
|
return ret
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const VALID_LOAD_POLICIES = new Set(["local", "remote"]);
|
|
const EXT_TO_TYPE = new Map([["mp4", "video/mp4"], ["webm", "video/webm"], ["m4a", "audio/mp4"], ["mp3", "audio/mpeg"], ["js", "application/javascript"], ["wasm", "application/wasm"], ["svg", "image/svg+xml"], ["html", "text/html"]]);
|
|
function GetTypeFromFileExtension(filename) {
|
|
if (!filename)
|
|
return "";
|
|
const parts = filename.split(".");
|
|
if (parts.length < 2)
|
|
return "";
|
|
const ext = parts[parts.length - 1].toLowerCase();
|
|
return EXT_TO_TYPE.get(ext) || ""
|
|
}
|
|
function AddScript(url) {
|
|
return new Promise((resolve,reject)=>{
|
|
const elem = document.createElement("script");
|
|
elem.onload = resolve;
|
|
elem.onerror = reject;
|
|
elem.async = false;
|
|
elem.src = url;
|
|
document.head.appendChild(elem)
|
|
}
|
|
)
|
|
}
|
|
C3.AssetManager = class AssetManager extends C3.DefendedBase {
|
|
constructor(runtime, opts) {
|
|
super();
|
|
if (!VALID_LOAD_POLICIES.has(opts.defaultLoadPolicy))
|
|
throw new Error("invalid load policy");
|
|
this._runtime = runtime;
|
|
this._localUrlBlobs = new Map;
|
|
this._localBlobUrlCache = new Map;
|
|
this._isCordova = !!opts.isCordova;
|
|
this._isiOSCordova = !!opts.isiOSCordova;
|
|
this._isFileProtocol = location.protocol === "file:";
|
|
this._supportedAudioFormats = opts.supportedAudioFormats || {};
|
|
this._audioFiles = new Map;
|
|
this._preloadSounds = false;
|
|
this._mediaSubfolder = "";
|
|
this._fontsSubfolder = "";
|
|
this._iconsSubfolder = "";
|
|
this._defaultLoadPolicy = opts.defaultLoadPolicy;
|
|
this._allAssets = [];
|
|
this._assetsByUrl = new Map;
|
|
this._webFonts = [];
|
|
this._loadPromises = [];
|
|
this._hasFinishedInitialLoad = false;
|
|
this._totalAssetSizeToLoad = 0;
|
|
this._assetSizeLoaded = 0;
|
|
this._lastLoadProgress = 0;
|
|
this._hasHadErrorLoading = false;
|
|
this._loadingRateLimiter = C3.New(C3.RateLimiter, ()=>this._FireLoadingProgressEvent(), 50);
|
|
this._promiseThrottle = new C3.PromiseThrottle(Math.max(C3.hardwareConcurrency, 8));
|
|
if (opts.localUrlBlobs)
|
|
for (const [url,blob] of Object.entries(opts.localUrlBlobs))
|
|
this._localUrlBlobs.set(url.toLowerCase(), blob);
|
|
this._iAssetManager = new self.IAssetManager(this)
|
|
}
|
|
Release() {
|
|
this._localUrlBlobs.clear();
|
|
for (const url of this._localBlobUrlCache.values())
|
|
URL.revokeObjectURL(url);
|
|
this._localBlobUrlCache.clear();
|
|
for (const asset of this._allAssets)
|
|
asset.Release();
|
|
C3.clearArray(this._allAssets);
|
|
this._assetsByUrl.clear();
|
|
C3.clearArray(this._loadPromises);
|
|
this._runtime = null
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
_SetMediaSubfolder(folder) {
|
|
this._mediaSubfolder = folder
|
|
}
|
|
GetMediaSubfolder() {
|
|
return this._mediaSubfolder
|
|
}
|
|
_SetFontsSubfolder(folder) {
|
|
this._fontsSubfolder = folder
|
|
}
|
|
GetFontsSubfolder() {
|
|
return this._fontsSubfolder
|
|
}
|
|
_SetIconsSubfolder(folder) {
|
|
this._iconsSubfolder = folder
|
|
}
|
|
GetIconsSubfolder() {
|
|
return this._iconsSubfolder
|
|
}
|
|
_HasLocalUrlBlob(url) {
|
|
return this._localUrlBlobs.has(url.toLowerCase())
|
|
}
|
|
_GetLocalUrlBlob(url) {
|
|
return this._localUrlBlobs.get(url.toLowerCase()) || null
|
|
}
|
|
GetLocalUrlAsBlobUrl(url) {
|
|
const blob = this._GetLocalUrlBlob(url);
|
|
if (!blob)
|
|
return url;
|
|
let ret = this._localBlobUrlCache.get(blob);
|
|
if (!ret) {
|
|
ret = URL.createObjectURL(blob);
|
|
this._localBlobUrlCache.set(blob, ret)
|
|
}
|
|
return ret
|
|
}
|
|
FetchBlob(url, loadPolicy) {
|
|
loadPolicy = loadPolicy || this._defaultLoadPolicy;
|
|
const localBlob = this._GetLocalUrlBlob(url);
|
|
if (localBlob)
|
|
return Promise.resolve(localBlob);
|
|
else if (C3.IsRelativeURL(url)) {
|
|
const lowerUrl = url.toLowerCase();
|
|
if (this._isCordova && this._isFileProtocol)
|
|
return this.CordovaFetchLocalFileAsBlob(lowerUrl);
|
|
else if (loadPolicy === "local")
|
|
return this._promiseThrottle.Add(()=>C3.FetchBlob(lowerUrl));
|
|
else
|
|
return C3.FetchBlob(lowerUrl)
|
|
} else
|
|
return C3.FetchBlob(url)
|
|
}
|
|
FetchArrayBuffer(url) {
|
|
const localBlob = this._GetLocalUrlBlob(url);
|
|
if (localBlob)
|
|
return C3.BlobToArrayBuffer(localBlob);
|
|
else if (C3.IsRelativeURL(url)) {
|
|
const lowerUrl = url.toLowerCase();
|
|
if (this._isCordova && this._isFileProtocol)
|
|
return this.CordovaFetchLocalFileAsArrayBuffer(lowerUrl);
|
|
else if (this._defaultLoadPolicy === "local")
|
|
return this._promiseThrottle.Add(()=>C3.FetchArrayBuffer(lowerUrl));
|
|
else
|
|
return C3.FetchArrayBuffer(lowerUrl)
|
|
} else
|
|
return C3.FetchArrayBuffer(url)
|
|
}
|
|
FetchText(url) {
|
|
const localBlob = this._GetLocalUrlBlob(url);
|
|
if (localBlob)
|
|
return C3.BlobToString(localBlob);
|
|
else if (C3.IsRelativeURL(url)) {
|
|
const lowerUrl = url.toLowerCase();
|
|
if (this._isCordova && this._isFileProtocol)
|
|
return this.CordovaFetchLocalFileAsText(lowerUrl);
|
|
else if (this._defaultLoadPolicy === "local")
|
|
return this._promiseThrottle.Add(()=>C3.FetchText(lowerUrl));
|
|
else
|
|
return C3.FetchText(lowerUrl)
|
|
} else
|
|
return C3.FetchText(url)
|
|
}
|
|
async FetchJson(url) {
|
|
const text = await this.FetchText(url);
|
|
return JSON.parse(text)
|
|
}
|
|
_CordovaFetchLocalFileAs(filename, as_) {
|
|
return this._runtime.PostComponentMessageToDOMAsync("runtime", "cordova-fetch-local-file", {
|
|
"filename": filename,
|
|
"as": as_
|
|
})
|
|
}
|
|
CordovaFetchLocalFileAsText(filename) {
|
|
return this._CordovaFetchLocalFileAs(filename, "text")
|
|
}
|
|
async CordovaFetchLocalFileAsBlob(filename) {
|
|
const buffer = await this._CordovaFetchLocalFileAs(filename, "buffer");
|
|
const type = GetTypeFromFileExtension(filename);
|
|
return new Blob([buffer],{
|
|
"type": type
|
|
})
|
|
}
|
|
async CordovaFetchLocalFileAsBlobURL(filename) {
|
|
filename = filename.toLowerCase();
|
|
let blobUrl = this._localBlobUrlCache.get(filename);
|
|
if (blobUrl)
|
|
return blobUrl;
|
|
const blob = await this.CordovaFetchLocalFileAsBlob(filename);
|
|
blobUrl = URL.createObjectURL(blob);
|
|
this._localBlobUrlCache.set(filename, blobUrl);
|
|
return blobUrl
|
|
}
|
|
CordovaFetchLocalFileAsArrayBuffer(filename) {
|
|
return this._CordovaFetchLocalFileAs(filename, "buffer")
|
|
}
|
|
GetMediaFileUrl(filename) {
|
|
if (this._HasLocalUrlBlob(filename))
|
|
return this.GetLocalUrlAsBlobUrl(filename);
|
|
else
|
|
return this._mediaSubfolder + filename.toLowerCase()
|
|
}
|
|
GetProjectFileUrl(url, subfolder="") {
|
|
if (C3.IsAbsoluteURL(url)) {
|
|
if (subfolder)
|
|
throw new Error("cannot specify subfolder with remote URL");
|
|
return Promise.resolve(url)
|
|
} else if (this._HasLocalUrlBlob(url))
|
|
return Promise.resolve(this.GetLocalUrlAsBlobUrl(url));
|
|
else if (this._isCordova && this._isFileProtocol)
|
|
return this.CordovaFetchLocalFileAsBlobURL(subfolder + url);
|
|
else
|
|
return Promise.resolve(subfolder + url.toLowerCase())
|
|
}
|
|
LoadProjectFileUrl(url) {
|
|
return this.GetProjectFileUrl(url)
|
|
}
|
|
LoadImage(opts) {
|
|
if (opts.loadPolicy && !VALID_LOAD_POLICIES.has(opts.loadPolicy))
|
|
throw new Error("invalid load policy");
|
|
let asset = this._assetsByUrl.get(opts.url);
|
|
if (asset)
|
|
return asset;
|
|
asset = C3.New(C3.ImageAsset, this, {
|
|
url: opts.url,
|
|
size: opts.size || 0,
|
|
loadPolicy: opts.loadPolicy || this._defaultLoadPolicy
|
|
});
|
|
this._allAssets.push(asset);
|
|
this._assetsByUrl.set(asset.GetURL(), asset);
|
|
if (!this._hasFinishedInitialLoad) {
|
|
this._totalAssetSizeToLoad += asset.GetSize();
|
|
this._loadPromises.push(asset.Load().then(()=>this._AddLoadedSize(asset.GetSize())))
|
|
}
|
|
return asset
|
|
}
|
|
async WaitForAllToLoad() {
|
|
try {
|
|
await Promise.all(this._loadPromises);
|
|
this._lastLoadProgress = 1
|
|
} catch (err) {
|
|
console.error("Error loading: ", err);
|
|
this._hasHadErrorLoading = true;
|
|
this._FireLoadingProgressEvent()
|
|
}
|
|
}
|
|
SetInitialLoadFinished() {
|
|
this._hasFinishedInitialLoad = true
|
|
}
|
|
HasHadErrorLoading() {
|
|
return this._hasHadErrorLoading
|
|
}
|
|
_AddLoadedSize(s) {
|
|
this._assetSizeLoaded += s;
|
|
this._loadingRateLimiter.Call()
|
|
}
|
|
_FireLoadingProgressEvent() {
|
|
const event = C3.New(C3.Event, "loadingprogress");
|
|
this._lastLoadProgress = C3.clamp(this._assetSizeLoaded / this._totalAssetSizeToLoad, 0, 1);
|
|
event.progress = this._lastLoadProgress;
|
|
this._runtime.Dispatcher().dispatchEvent(event)
|
|
}
|
|
GetLoadProgress() {
|
|
return this._lastLoadProgress
|
|
}
|
|
_SetWebFonts(arr) {
|
|
C3.shallowAssignArray(this._webFonts, arr);
|
|
if (this._webFonts.length)
|
|
this._loadPromises.push(this._LoadWebFonts())
|
|
}
|
|
_LoadWebFonts() {
|
|
if (typeof FontFace === "undefined")
|
|
return Promise.resolve();
|
|
const promises = [];
|
|
for (const [name,filename,size] of this._webFonts) {
|
|
this._totalAssetSizeToLoad += size;
|
|
promises.push(this._LoadWebFont(name, filename).then(()=>this._AddLoadedSize(size)))
|
|
}
|
|
return Promise.all(promises)
|
|
}
|
|
async _LoadWebFont(name, filename) {
|
|
try {
|
|
const url = await this.GetProjectFileUrl(filename, this._fontsSubfolder);
|
|
const fontFace = new FontFace(name,`url('${url}')`);
|
|
if (this._runtime.IsInWorker())
|
|
self.fonts.add(fontFace);
|
|
else
|
|
document.fonts.add(fontFace);
|
|
await fontFace.load()
|
|
} catch (err) {
|
|
console.warn(`[C3 runtime] Failed to load web font '${name}': `, err)
|
|
}
|
|
}
|
|
IsAudioFormatSupported(type) {
|
|
return !!this._supportedAudioFormats[type]
|
|
}
|
|
_SetAudioFiles(arr, preloadSounds) {
|
|
this._preloadSounds = !!preloadSounds;
|
|
for (const [fileName,projectFilesInfo,isMusic] of arr)
|
|
this._audioFiles.set(fileName, {
|
|
fileName,
|
|
formats: projectFilesInfo.map(si=>({
|
|
type: si[0],
|
|
fileExtension: si[1],
|
|
fullName: fileName + si[1],
|
|
fileSize: si[2]
|
|
})),
|
|
isMusic
|
|
})
|
|
}
|
|
GetPreferredAudioFile(namePart) {
|
|
const info = this._audioFiles.get(namePart.toLowerCase());
|
|
if (!info)
|
|
return null;
|
|
let webMOpusFile = null;
|
|
for (const formatInfo of info.formats) {
|
|
if (!webMOpusFile && formatInfo.type === "audio/webm; codecs=opus")
|
|
webMOpusFile = formatInfo;
|
|
if (this.IsAudioFormatSupported(formatInfo.type))
|
|
return formatInfo
|
|
}
|
|
return webMOpusFile
|
|
}
|
|
GetProjectAudioFileUrl(namePart) {
|
|
const formatInfo = this.GetPreferredAudioFile(namePart);
|
|
if (!formatInfo)
|
|
return null;
|
|
return {
|
|
url: this.GetMediaFileUrl(formatInfo.fullName),
|
|
type: formatInfo.type
|
|
}
|
|
}
|
|
GetAudioToPreload() {
|
|
if (this._preloadSounds) {
|
|
const ret = [];
|
|
for (const info of this._audioFiles.values()) {
|
|
if (info.isMusic)
|
|
continue;
|
|
const formatInfo = this.GetPreferredAudioFile(info.fileName);
|
|
if (!formatInfo)
|
|
continue;
|
|
ret.push({
|
|
originalUrl: info.fileName,
|
|
url: this.GetMediaFileUrl(formatInfo.fullName),
|
|
type: formatInfo.type,
|
|
fileSize: formatInfo.fileSize
|
|
})
|
|
}
|
|
return ret
|
|
} else
|
|
return []
|
|
}
|
|
GetIAssetManager() {
|
|
return this._iAssetManager
|
|
}
|
|
async LoadScripts(...urls) {
|
|
const scriptUrls = await Promise.all(urls.map(url=>this.GetProjectFileUrl(url)));
|
|
if (this._runtime.IsInWorker())
|
|
importScripts(...scriptUrls);
|
|
else
|
|
await Promise.all(scriptUrls.map(url=>AddScript(url)))
|
|
}
|
|
async CompileWebAssembly(url) {
|
|
if (WebAssembly.compileStreaming) {
|
|
const fetchUrl = await this.GetProjectFileUrl(url);
|
|
return await WebAssembly.compileStreaming(fetch(fetchUrl))
|
|
} else {
|
|
const arrayBuffer = await C3.FetchArrayBuffer(url);
|
|
return await WebAssembly.compile(arrayBuffer)
|
|
}
|
|
}
|
|
async LoadStyleSheet(url) {
|
|
const fetchUrl = await this.GetProjectFileUrl(url);
|
|
return await this._runtime.PostComponentMessageToDOMAsync("runtime", "add-stylesheet", {
|
|
"url": fetchUrl
|
|
})
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Asset = class Asset extends C3.DefendedBase {
|
|
constructor(assetManager, opts) {
|
|
super();
|
|
this._assetManager = assetManager;
|
|
this._runtime = assetManager.GetRuntime();
|
|
this._url = opts.url;
|
|
this._size = opts.size;
|
|
this._loadPolicy = opts.loadPolicy;
|
|
this._blob = null;
|
|
this._isLoaded = false;
|
|
this._loadPromise = null
|
|
}
|
|
Release() {
|
|
this._loadPromise = null;
|
|
this._assetManager = null;
|
|
this._runtime = null;
|
|
this._blob = null
|
|
}
|
|
GetURL() {
|
|
return this._url
|
|
}
|
|
GetSize() {
|
|
return this._size
|
|
}
|
|
Load() {
|
|
if (this._loadPolicy === "local" || this._blob) {
|
|
this._isLoaded = true;
|
|
return Promise.resolve()
|
|
}
|
|
if (this._loadPromise)
|
|
return this._loadPromise;
|
|
this._loadPromise = this._assetManager.FetchBlob(this._url, this._loadPolicy).then(blob=>{
|
|
this._isLoaded = true;
|
|
this._loadPromise = null;
|
|
this._blob = blob
|
|
}
|
|
).catch(err=>console.error("Error loading resource: ", err));
|
|
return this._loadPromise
|
|
}
|
|
IsLoaded() {
|
|
return this._isLoaded
|
|
}
|
|
GetBlob() {
|
|
if (this._blob)
|
|
return Promise.resolve(this._blob);
|
|
return this._assetManager.FetchBlob(this._url, this._loadPolicy)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const promiseThrottle = new C3.PromiseThrottle;
|
|
const allImageAssets = new Set;
|
|
C3.ImageAsset = class ImageAsset extends C3.Asset {
|
|
constructor(assetManager, opts) {
|
|
super(assetManager, opts);
|
|
this._texturePromise = null;
|
|
this._webglTexture = null;
|
|
this._refCount = 0;
|
|
this._imageWidth = -1;
|
|
this._imageHeight = -1;
|
|
allImageAssets.add(this)
|
|
}
|
|
Release() {
|
|
this.ReleaseTexture();
|
|
if (this._refCount !== 0)
|
|
throw new Error("released image asset which still has texture references");
|
|
this._texturePromise = null;
|
|
allImageAssets.delete(this);
|
|
super.Release()
|
|
}
|
|
static OnWebGLContextLost() {
|
|
for (const imageAsset of allImageAssets) {
|
|
imageAsset._texturePromise = null;
|
|
imageAsset._webglTexture = null;
|
|
imageAsset._refCount = 0
|
|
}
|
|
}
|
|
LoadStaticTexture(renderer, opts) {
|
|
this._refCount++;
|
|
if (this._webglTexture)
|
|
return Promise.resolve(this._webglTexture);
|
|
if (this._texturePromise)
|
|
return this._texturePromise;
|
|
this._texturePromise = this.GetBlob().then(blob=>promiseThrottle.Add(()=>renderer.CreateStaticTextureAsync(blob, opts).then(texture=>{
|
|
this._texturePromise = null;
|
|
if (this._refCount === 0) {
|
|
renderer.DeleteTexture(texture);
|
|
return null
|
|
}
|
|
this._webglTexture = texture;
|
|
this._imageWidth = texture.GetWidth();
|
|
this._imageHeight = texture.GetHeight();
|
|
return this._webglTexture
|
|
}
|
|
))).catch(err=>{
|
|
console.error("Failed to load texture: ", err);
|
|
throw err;
|
|
}
|
|
);
|
|
return this._texturePromise
|
|
}
|
|
ReleaseTexture() {
|
|
if (this._refCount <= 0)
|
|
throw new Error("texture released too many times");
|
|
this._refCount--;
|
|
if (this._refCount === 0 && this._webglTexture) {
|
|
const renderer = this._webglTexture.GetRenderer();
|
|
renderer.DeleteTexture(this._webglTexture);
|
|
this._webglTexture = null
|
|
}
|
|
}
|
|
GetTexture() {
|
|
return this._webglTexture
|
|
}
|
|
GetWidth() {
|
|
return this._imageWidth
|
|
}
|
|
GetHeight() {
|
|
return this._imageHeight
|
|
}
|
|
async LoadToDrawable() {
|
|
const blob = await this.GetBlob();
|
|
if (C3.Supports.ImageBitmapOptions)
|
|
return await createImageBitmap(blob, {
|
|
"premultiplyAlpha": "none"
|
|
});
|
|
else if (C3.Supports.ImageBitmap)
|
|
return await createImageBitmap(blob);
|
|
else
|
|
return await C3.BlobToImage(blob)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
function SortByInstLastCachedZIndex(a, b) {
|
|
return a.GetWorldInfo()._GetLastCachedZIndex() - b.GetWorldInfo()._GetLastCachedZIndex()
|
|
}
|
|
C3.RenderCell = class RenderCell extends C3.DefendedBase {
|
|
constructor(grid, x, y) {
|
|
super();
|
|
this._grid = grid;
|
|
this._x = x;
|
|
this._y = y;
|
|
this._instances = [];
|
|
this._isSorted = true;
|
|
this._pendingRemoval = new Set;
|
|
this._isAnyPendingRemoval = false
|
|
}
|
|
Release() {
|
|
C3.clearArray(this._instances);
|
|
this._pendingRemoval.clear();
|
|
this._grid = null
|
|
}
|
|
Reset() {
|
|
C3.clearArray(this._instances);
|
|
this._isSorted = true;
|
|
this._pendingRemoval.clear();
|
|
this._isAnyPendingRemoval = false
|
|
}
|
|
SetChanged() {
|
|
this._isSorted = false
|
|
}
|
|
IsEmpty() {
|
|
if (!this._instances.length)
|
|
return true;
|
|
if (this._instances.length > this._pendingRemoval.size)
|
|
return false;
|
|
this._FlushPending();
|
|
return true
|
|
}
|
|
Insert(inst) {
|
|
if (this._pendingRemoval.has(inst)) {
|
|
this._pendingRemoval.delete(inst);
|
|
if (this._pendingRemoval.size === 0)
|
|
this._isAnyPendingRemoval = false;
|
|
return
|
|
}
|
|
this._instances.push(inst);
|
|
this._isSorted = this._instances.length === 1
|
|
}
|
|
Remove(inst) {
|
|
this._pendingRemoval.add(inst);
|
|
this._isAnyPendingRemoval = true;
|
|
if (this._pendingRemoval.size >= 50)
|
|
this._FlushPending()
|
|
}
|
|
_FlushPending() {
|
|
if (!this._isAnyPendingRemoval)
|
|
return;
|
|
if (this._instances.length === this._pendingRemoval.size) {
|
|
this.Reset();
|
|
return
|
|
}
|
|
C3.arrayRemoveAllInSet(this._instances, this._pendingRemoval);
|
|
this._pendingRemoval.clear();
|
|
this._isAnyPendingRemoval = false
|
|
}
|
|
_EnsureSorted() {
|
|
if (this._isSorted)
|
|
return;
|
|
this._instances.sort(SortByInstLastCachedZIndex);
|
|
this._isSorted = true
|
|
}
|
|
Dump(result) {
|
|
this._FlushPending();
|
|
this._EnsureSorted();
|
|
if (this._instances.length)
|
|
result.push(this._instances)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.RenderGrid = class RenderGrid extends C3.DefendedBase {
|
|
constructor(cellWidth, cellHeight) {
|
|
super();
|
|
this._cellWidth = cellWidth;
|
|
this._cellHeight = cellHeight;
|
|
this._cells = C3.New(C3.PairMap)
|
|
}
|
|
Release() {
|
|
this._cells.Release();
|
|
this._cells = null
|
|
}
|
|
GetCell(x, y, createIfMissing) {
|
|
let ret = this._cells.Get(x, y);
|
|
if (ret)
|
|
return ret;
|
|
else if (createIfMissing) {
|
|
ret = C3.New(C3.RenderCell, this, x, y);
|
|
this._cells.Set(x, y, ret);
|
|
return ret
|
|
} else
|
|
return null
|
|
}
|
|
XToCell(x) {
|
|
return Math.floor(x / this._cellWidth)
|
|
}
|
|
YToCell(y) {
|
|
return Math.floor(y / this._cellHeight)
|
|
}
|
|
Update(inst, oldRange, newRange) {
|
|
if (oldRange)
|
|
for (let x = oldRange.getLeft(), lenx = oldRange.getRight(); x <= lenx; ++x)
|
|
for (let y = oldRange.getTop(), leny = oldRange.getBottom(); y <= leny; ++y) {
|
|
if (newRange && newRange.containsPoint(x, y))
|
|
continue;
|
|
const cell = this.GetCell(x, y, false);
|
|
if (!cell)
|
|
continue;
|
|
cell.Remove(inst);
|
|
if (cell.IsEmpty())
|
|
this._cells.Delete(x, y)
|
|
}
|
|
if (newRange)
|
|
for (let x = newRange.getLeft(), lenx = newRange.getRight(); x <= lenx; ++x)
|
|
for (let y = newRange.getTop(), leny = newRange.getBottom(); y <= leny; ++y) {
|
|
if (oldRange && oldRange.containsPoint(x, y))
|
|
continue;
|
|
this.GetCell(x, y, true).Insert(inst)
|
|
}
|
|
}
|
|
QueryRange(rc, result) {
|
|
let x = this.XToCell(rc.getLeft());
|
|
const ystart = this.YToCell(rc.getTop());
|
|
const lenx = this.XToCell(rc.getRight());
|
|
const leny = this.YToCell(rc.getBottom());
|
|
for (; x <= lenx; ++x)
|
|
for (let y = ystart; y <= leny; ++y) {
|
|
const cell = this.GetCell(x, y, false);
|
|
if (!cell)
|
|
continue;
|
|
cell.Dump(result)
|
|
}
|
|
}
|
|
MarkRangeChanged(rc) {
|
|
let x = rc.getLeft();
|
|
const ystart = rc.getTop();
|
|
const lenx = rc.getRight();
|
|
const leny = rc.getBottom();
|
|
for (; x <= lenx; ++x)
|
|
for (let y = ystart; y <= leny; ++y) {
|
|
const cell = this.GetCell(x, y, false);
|
|
if (!cell)
|
|
continue;
|
|
cell.SetChanged()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tmpRect = new C3.Rect;
|
|
const tmpQuad = new C3.Quad;
|
|
const renderCellArr = [];
|
|
const tmpDestRect = new C3.Rect;
|
|
const tmpSrcRect = new C3.Rect;
|
|
const glMatrix = self.glMatrix;
|
|
const vec3 = glMatrix.vec3;
|
|
const tempVec3 = vec3.fromValues(0, 1, 0);
|
|
function SortByInstLastCachedZIndex(a, b) {
|
|
return a.GetWorldInfo()._GetLastCachedZIndex() - b.GetWorldInfo()._GetLastCachedZIndex()
|
|
}
|
|
function SortByInstZElevation(a, b) {
|
|
return a.GetWorldInfo().GetZElevation() - b.GetWorldInfo().GetZElevation()
|
|
}
|
|
C3.Layer = class Layer extends C3.DefendedBase {
|
|
constructor(layout, index, data) {
|
|
super();
|
|
this._layout = layout;
|
|
this._runtime = layout.GetRuntime();
|
|
this._name = data[0];
|
|
this._index = index;
|
|
this._sid = data[2];
|
|
this._isVisible = !!data[3];
|
|
this._backgroundColor = C3.New(C3.Color);
|
|
this._backgroundColor.setFromJSON(data[4].map(x=>x / 255));
|
|
this._isTransparent = !!data[5];
|
|
this._parallaxX = data[6];
|
|
this._parallaxY = data[7];
|
|
this._color = C3.New(C3.Color, 1, 1, 1, data[8]);
|
|
this._premultipliedColor = C3.New(C3.Color);
|
|
this._isForceOwnTexture = data[9];
|
|
this._useRenderCells = data[10];
|
|
this._scaleRate = data[11];
|
|
this._blendMode = data[12];
|
|
this._curRenderTarget = null;
|
|
this._scale = 1;
|
|
this._zElevation = data[16];
|
|
this._angle = 0;
|
|
this._isAngleEnabled = true;
|
|
this._viewport = C3.New(C3.Rect);
|
|
this._viewportZ0 = C3.New(C3.Rect);
|
|
this._startupInitialInstances = [];
|
|
this._initialInstances = [];
|
|
this._createdGlobalUids = [];
|
|
this._instances = [];
|
|
this._zIndicesUpToDate = false;
|
|
this._anyInstanceZElevated = false;
|
|
this._effectList = C3.New(C3.EffectList, this, data[15]);
|
|
this._renderGrid = null;
|
|
this._lastRenderList = [];
|
|
this._isRenderListUpToDate = false;
|
|
this._lastRenderCells = C3.New(C3.Rect, 0, 0, -1, -1);
|
|
this._curRenderCells = C3.New(C3.Rect, 0, 0, -1, -1);
|
|
this._iLayer = new self.ILayer(this);
|
|
this._UpdatePremultipliedColor();
|
|
if (this._useRenderCells)
|
|
this._renderGrid = C3.New(C3.RenderGrid, this._runtime.GetOriginalViewportWidth(), this._runtime.GetOriginalViewportHeight());
|
|
for (const instData of data[14]) {
|
|
const objectClass = this._runtime.GetObjectClassByIndex(instData[1]);
|
|
this._layout._AddInitialObjectClass(objectClass);
|
|
if (!objectClass.GetDefaultInstanceData()) {
|
|
objectClass.SetDefaultInstanceData(instData);
|
|
objectClass._SetDefaultLayerIndex(this._index)
|
|
}
|
|
this._initialInstances.push(instData)
|
|
}
|
|
C3.shallowAssignArray(this._startupInitialInstances, this._initialInstances)
|
|
}
|
|
static Create(layout, index, data) {
|
|
return C3.New(C3.Layer, layout, index, data)
|
|
}
|
|
Release() {
|
|
this._layout = null;
|
|
this._runtime = null
|
|
}
|
|
CreateInitialInstances(createdInstances) {
|
|
const isFirstVisit = this._layout.IsFirstVisit();
|
|
let k = 0;
|
|
const initialInstances = this._initialInstances;
|
|
for (let i = 0, len = initialInstances.length; i < len; ++i) {
|
|
const instData = initialInstances[i];
|
|
const objectClass = this._runtime.GetObjectClassByIndex(instData[1]);
|
|
let keep = true;
|
|
if (!objectClass.HasPersistBehavior() || isFirstVisit) {
|
|
const inst = this._runtime.CreateInstanceFromData(instData, this, true);
|
|
createdInstances.push(inst);
|
|
if (objectClass.IsGlobal()) {
|
|
keep = false;
|
|
this._createdGlobalUids.push(inst.GetUID())
|
|
}
|
|
}
|
|
if (keep) {
|
|
initialInstances[k] = initialInstances[i];
|
|
++k
|
|
}
|
|
}
|
|
C3.truncateArray(initialInstances, k);
|
|
this._runtime.FlushPendingInstances();
|
|
this.SetZIndicesChanged()
|
|
}
|
|
_AddInstance(inst, addToGrid) {
|
|
const wi = inst.GetWorldInfo();
|
|
if (wi.GetLayer() !== this)
|
|
throw new Error("instance added to wrong layer");
|
|
this._instances.push(inst);
|
|
if (wi.GetZElevation() !== 0)
|
|
this._anyInstanceZElevated = true;
|
|
if (addToGrid && this._useRenderCells)
|
|
inst.GetWorldInfo().SetBboxChanged();
|
|
this.SetZIndicesChanged()
|
|
}
|
|
_MaybeAddInstance(inst) {
|
|
if (this._instances.includes(inst))
|
|
return;
|
|
this._instances.push(inst);
|
|
if (inst.GetWorldInfo().GetZElevation() !== 0)
|
|
this._anyInstanceZElevated = true;
|
|
this.SetZIndicesChanged()
|
|
}
|
|
_PrependInstance(inst, addToGrid) {
|
|
const wi = inst.GetWorldInfo();
|
|
if (wi.GetLayer() !== this)
|
|
throw new Error("instance added to wrong layer");
|
|
this._instances.unshift(inst);
|
|
if (wi.GetZElevation() !== 0)
|
|
this._anyInstanceZElevated = true;
|
|
this.SetZIndicesChanged();
|
|
if (addToGrid && this._useRenderCells)
|
|
inst.GetWorldInfo().SetBboxChanged()
|
|
}
|
|
_RemoveInstance(inst, removeFromGrid) {
|
|
const index = this._instances.indexOf(inst);
|
|
if (index < 0)
|
|
return;
|
|
if (removeFromGrid && this._useRenderCells)
|
|
inst.GetWorldInfo()._RemoveFromRenderCells();
|
|
this._instances.splice(index, 1);
|
|
this.SetZIndicesChanged();
|
|
this._MaybeResetAnyInstanceZElevatedFlag()
|
|
}
|
|
_SetAnyInstanceZElevated() {
|
|
this._anyInstanceZElevated = true
|
|
}
|
|
_MaybeResetAnyInstanceZElevatedFlag() {
|
|
if (this._instances.length === 0)
|
|
this._anyInstanceZElevated = false
|
|
}
|
|
_SortInstancesByLastCachedZIndex(isPersistMode) {
|
|
if (isPersistMode) {
|
|
const assignedZIndices = new Set;
|
|
for (const inst of this._instances) {
|
|
const cachedZIndex = inst.GetWorldInfo()._GetLastCachedZIndex();
|
|
if (cachedZIndex >= 0)
|
|
assignedZIndices.add(cachedZIndex)
|
|
}
|
|
let index = -1;
|
|
for (const inst of this._instances) {
|
|
const wi = inst.GetWorldInfo();
|
|
if (wi._GetLastCachedZIndex() >= 0)
|
|
continue;
|
|
++index;
|
|
while (assignedZIndices.has(index))
|
|
++index;
|
|
wi._SetZIndex(index)
|
|
}
|
|
}
|
|
this._instances.sort(SortByInstLastCachedZIndex)
|
|
}
|
|
_Start() {}
|
|
_End() {
|
|
for (const inst of this._instances)
|
|
if (!inst.GetObjectClass().IsGlobal())
|
|
this._runtime.DestroyInstance(inst);
|
|
this._runtime.FlushPendingInstances();
|
|
C3.clearArray(this._instances);
|
|
this._anyInstanceZElevated = false;
|
|
this.SetZIndicesChanged()
|
|
}
|
|
RecreateInitialObjects(objectClass, rc, offsetX, offsetY) {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const allObjectClasses = this._runtime.GetAllObjectClasses();
|
|
const isFamily = objectClass.IsFamily();
|
|
const ret = [];
|
|
for (const instData of this._initialInstances) {
|
|
const worldData = instData[0];
|
|
const x = worldData[0];
|
|
const y = worldData[1];
|
|
if (!rc.containsPoint(x, y))
|
|
continue;
|
|
const objectType = allObjectClasses[instData[1]];
|
|
if (objectType !== objectClass)
|
|
if (isFamily) {
|
|
if (!objectClass.FamilyHasMember(objectType))
|
|
continue
|
|
} else
|
|
continue;
|
|
let createOnLayer = this;
|
|
const runningLayout = this._runtime.GetCurrentLayout();
|
|
if (this.GetLayout() !== runningLayout) {
|
|
createOnLayer = runningLayout.GetLayerByName(this.GetName());
|
|
if (!createOnLayer)
|
|
createOnLayer = runningLayout.GetLayerByIndex(this.GetIndex())
|
|
}
|
|
const inst = this._runtime.CreateInstanceFromData(instData, createOnLayer, false);
|
|
const wi = inst.GetWorldInfo();
|
|
wi.OffsetXY(offsetX, offsetY);
|
|
wi.SetBboxChanged();
|
|
eventSheetManager.BlockFlushingInstances(true);
|
|
inst._TriggerOnCreated();
|
|
if (inst.IsInContainer())
|
|
for (const s of inst.siblings())
|
|
s._TriggerOnCreated();
|
|
eventSheetManager.BlockFlushingInstances(false);
|
|
ret.push(inst)
|
|
}
|
|
return ret
|
|
}
|
|
GetInstanceCount() {
|
|
return this._instances.length
|
|
}
|
|
GetLayout() {
|
|
return this._layout
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
GetIndex() {
|
|
return this._index
|
|
}
|
|
GetSID() {
|
|
return this._sid
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetDevicePixelRatio() {
|
|
return this._runtime.GetDevicePixelRatio()
|
|
}
|
|
GetEffectList() {
|
|
return this._effectList
|
|
}
|
|
UsesRenderCells() {
|
|
return this._useRenderCells
|
|
}
|
|
GetRenderGrid() {
|
|
return this._renderGrid
|
|
}
|
|
SetRenderListStale() {
|
|
this._isRenderListUpToDate = false
|
|
}
|
|
IsVisible() {
|
|
return this._isVisible
|
|
}
|
|
SetVisible(v) {
|
|
v = !!v;
|
|
if (this._isVisible === v)
|
|
return;
|
|
this._isVisible = v;
|
|
this._runtime.UpdateRender()
|
|
}
|
|
GetViewport() {
|
|
return this._viewport
|
|
}
|
|
GetViewportForZ(z, outRect) {
|
|
const viewportZ0 = this._viewportZ0;
|
|
if (z === 0)
|
|
outRect.copy(viewportZ0);
|
|
else {
|
|
const scaleFactor = this.Get2DScaleFactorToZ(z);
|
|
const midX = viewportZ0.midX();
|
|
const midY = viewportZ0.midY();
|
|
const halfW = .5 * viewportZ0.width() / scaleFactor;
|
|
const halfH = .5 * viewportZ0.height() / scaleFactor;
|
|
outRect.set(midX - halfW, midY - halfH, midX + halfW, midY + halfH)
|
|
}
|
|
}
|
|
GetOpacity() {
|
|
return this._color.getA()
|
|
}
|
|
SetOpacity(o) {
|
|
o = C3.clamp(o, 0, 1);
|
|
if (this._color.getA() === o)
|
|
return;
|
|
this._color.setA(o);
|
|
this._UpdatePremultipliedColor();
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_UpdatePremultipliedColor() {
|
|
this._premultipliedColor.copy(this._color);
|
|
this._premultipliedColor.premultiply()
|
|
}
|
|
GetPremultipliedColor() {
|
|
return this._premultipliedColor
|
|
}
|
|
HasDefaultColor() {
|
|
return this._color.equalsRgba(1, 1, 1, 1)
|
|
}
|
|
GetScaleRate() {
|
|
return this._scaleRate
|
|
}
|
|
SetScaleRate(r) {
|
|
if (this._scaleRate === r)
|
|
return;
|
|
this._scaleRate = r;
|
|
this._runtime.UpdateRender()
|
|
}
|
|
GetParallaxX() {
|
|
return this._parallaxX
|
|
}
|
|
GetParallaxY() {
|
|
return this._parallaxY
|
|
}
|
|
SetParallax(px, py) {
|
|
if (this._parallaxX === px && this._parallaxY === py)
|
|
return;
|
|
this._parallaxX = px;
|
|
this._parallaxY = py;
|
|
this._runtime.UpdateRender();
|
|
if (this._parallaxX !== 1 || this._parallaxY !== 1)
|
|
for (const inst of this._instances)
|
|
inst.GetObjectClass()._SetAnyInstanceParallaxed(true)
|
|
}
|
|
SetParallaxX(px) {
|
|
this.SetParallax(px, this.GetParallaxY())
|
|
}
|
|
SetParallaxY(py) {
|
|
this.SetParallax(this.GetParallaxX(), py)
|
|
}
|
|
SetZElevation(z) {
|
|
z = +z;
|
|
if (this._zElevation === z)
|
|
return;
|
|
this._zElevation = z;
|
|
this._runtime.UpdateRender()
|
|
}
|
|
GetZElevation() {
|
|
return this._zElevation
|
|
}
|
|
SetAngle(a) {
|
|
this._angle = C3.clampAngle(a)
|
|
}
|
|
GetAngle() {
|
|
if (this._isAngleEnabled)
|
|
return C3.clampAngle(this._layout.GetAngle() + this._angle);
|
|
else
|
|
return 0
|
|
}
|
|
GetOwnAngle() {
|
|
return this._angle
|
|
}
|
|
HasInstances() {
|
|
return this._instances.length > 0
|
|
}
|
|
_GetInstances() {
|
|
return this._instances
|
|
}
|
|
GetBackgroundColor() {
|
|
return this._backgroundColor
|
|
}
|
|
IsTransparent() {
|
|
return this._isTransparent
|
|
}
|
|
SetTransparent(t) {
|
|
this._isTransparent = !!t
|
|
}
|
|
IsForceOwnTexture() {
|
|
return this._isForceOwnTexture
|
|
}
|
|
SetForceOwnTexture(f) {
|
|
this._isForceOwnTexture = !!f
|
|
}
|
|
SetBlendMode(bm) {
|
|
if (this._blendMode === bm)
|
|
return;
|
|
this._blendMode = bm;
|
|
this._runtime.UpdateRender()
|
|
}
|
|
GetBlendMode() {
|
|
return this._blendMode
|
|
}
|
|
IsTransformCompatibleWith(otherLayer) {
|
|
return this === otherLayer || this._parallaxX === otherLayer._parallaxX && this._parallaxY === otherLayer._parallaxY && this._scale === otherLayer._scale && this._scaleRate === otherLayer._scaleRate && this._angle === otherLayer._angle
|
|
}
|
|
_RemoveAllInstancesInSet(s) {
|
|
if (s.size === 0)
|
|
return;
|
|
const numRemoved = C3.arrayRemoveAllInSet(this._instances, s);
|
|
if (numRemoved > 0) {
|
|
this._MaybeResetAnyInstanceZElevatedFlag();
|
|
this.SetZIndicesChanged()
|
|
}
|
|
}
|
|
SetZIndicesChanged() {
|
|
this._zIndicesUpToDate = false;
|
|
this._isRenderListUpToDate = false
|
|
}
|
|
_UpdateZIndices() {
|
|
if (this._zIndicesUpToDate)
|
|
return;
|
|
this._instances.sort(SortByInstZElevation);
|
|
if (this._useRenderCells)
|
|
for (let i = 0, len = this._instances.length; i < len; ++i) {
|
|
const wi = this._instances[i].GetWorldInfo();
|
|
wi._SetZIndex(i);
|
|
this._renderGrid.MarkRangeChanged(wi.GetRenderCellRange())
|
|
}
|
|
else
|
|
for (let i = 0, len = this._instances.length; i < len; ++i)
|
|
this._instances[i].GetWorldInfo()._SetZIndex(i);
|
|
this._zIndicesUpToDate = true
|
|
}
|
|
MoveInstanceAdjacent(inst, other, isAfter) {
|
|
const instWi = inst.GetWorldInfo();
|
|
const otherWi = other.GetWorldInfo();
|
|
if (instWi.GetLayer() !== this || otherWi.GetLayer() !== this)
|
|
throw new Error("can't arrange Z order unless both objects on this layer");
|
|
const myZ = instWi.GetZIndex();
|
|
let insertZ = otherWi.GetZIndex();
|
|
if (myZ === insertZ + (isAfter ? 1 : -1))
|
|
return false;
|
|
C3.arrayRemove(this._instances, myZ);
|
|
if (myZ < insertZ)
|
|
insertZ--;
|
|
if (isAfter)
|
|
insertZ++;
|
|
if (insertZ === this._instances.length)
|
|
this._instances.push(inst);
|
|
else
|
|
this._instances.splice(insertZ, 0, inst);
|
|
this.SetZIndicesChanged();
|
|
return true
|
|
}
|
|
_MergeSortedZArrays(a, b) {
|
|
const ret = [];
|
|
let i = 0
|
|
, j = 0
|
|
, lena = a.length
|
|
, lenb = b.length;
|
|
while (i < lena && j < lenb) {
|
|
const ai = a[i];
|
|
const bj = b[j];
|
|
if (ai.GetWorldInfo()._GetLastCachedZIndex() < bj.GetWorldInfo()._GetLastCachedZIndex()) {
|
|
ret.push(ai);
|
|
++i
|
|
} else {
|
|
ret.push(bj);
|
|
++j
|
|
}
|
|
}
|
|
for (; i < lena; ++i)
|
|
ret.push(a[i]);
|
|
for (; j < lenb; ++j)
|
|
ret.push(b[j]);
|
|
return ret
|
|
}
|
|
_MergeAllSortedZArrays_pass(arr) {
|
|
const ret = [];
|
|
const len = arr.length;
|
|
for (let i = 0; i < len - 1; i += 2) {
|
|
const arr1 = arr[i];
|
|
const arr2 = arr[i + 1];
|
|
ret.push(this._MergeSortedZArrays(arr1, arr2))
|
|
}
|
|
if (len % 2 === 1)
|
|
ret.push(arr[len - 1]);
|
|
return ret
|
|
}
|
|
_MergeAllSortedZArrays(arr) {
|
|
while (arr.length > 1)
|
|
arr = this._MergeAllSortedZArrays_pass(arr);
|
|
return arr[0]
|
|
}
|
|
_GetRenderCellInstancesToDraw() {
|
|
this._UpdateZIndices();
|
|
C3.clearArray(renderCellArr);
|
|
this._renderGrid.QueryRange(this._viewport, renderCellArr);
|
|
if (!renderCellArr.length)
|
|
return [];
|
|
if (renderCellArr.length === 1)
|
|
return renderCellArr[0];
|
|
return this._MergeAllSortedZArrays(renderCellArr)
|
|
}
|
|
_IsOpaque() {
|
|
return !this.UsesOwnTexture() && !this.IsTransparent()
|
|
}
|
|
ShouldDraw() {
|
|
return this.IsVisible() && this.GetOpacity() > 0 && (this.HasInstances() || !this.IsTransparent())
|
|
}
|
|
UsesOwnTexture() {
|
|
return this.IsForceOwnTexture() || !this.HasDefaultColor() || this.GetBlendMode() !== 0 || this._effectList.HasAnyActiveEffect()
|
|
}
|
|
GetRenderTarget() {
|
|
return this._curRenderTarget
|
|
}
|
|
_CanFastPathDrawLayer(activeEffectTypes) {
|
|
if (activeEffectTypes.length === 0)
|
|
return true;
|
|
if (activeEffectTypes.length >= 2)
|
|
return false;
|
|
const effectType = activeEffectTypes[0];
|
|
const shaderProgram = effectType.GetShaderProgram();
|
|
return !shaderProgram.MustPreDraw() && !shaderProgram.UsesDest() && !shaderProgram.UsesCrossSampling() && this.HasDefaultColor()
|
|
}
|
|
Get2DScaleFactorToZ(z) {
|
|
const camZ = this.GetCameraZ();
|
|
return camZ / (camZ - z)
|
|
}
|
|
GetCameraZ() {
|
|
return 100 / this.GetNormalScale()
|
|
}
|
|
_SetTransform(renderer, offX=0, offY=0) {
|
|
const renderScale = this._runtime.GetRenderScale();
|
|
const camX = (this._viewport.midX() + offX) * renderScale;
|
|
const camY = (this._viewport.midY() + offY) * renderScale;
|
|
const camZ = this.GetCameraZ();
|
|
renderer.SetCameraXYZ(camX, camY, camZ);
|
|
renderer.SetLookXYZ(camX, camY, camZ - 100);
|
|
const a = this.GetAngle();
|
|
const upVector = tempVec3;
|
|
if (a === 0)
|
|
vec3.set(upVector, 0, 1, 0);
|
|
else
|
|
vec3.set(upVector, Math.sin(a), Math.cos(a), 0);
|
|
renderer.ResetModelView(upVector);
|
|
renderer.Scale(renderScale, renderScale);
|
|
renderer.UpdateModelView()
|
|
}
|
|
Draw(renderer, destinationRenderTarget, isFirstDrawnLayer) {
|
|
const canvasManager = this._runtime.GetCanvasManager();
|
|
const useOwnTexture = this.UsesOwnTexture();
|
|
let ownRenderTarget = null;
|
|
let layerQuery = null;
|
|
if (this._runtime.IsGPUProfiling() && renderer.SupportsGPUProfiling()) {
|
|
const timingsBuffer = canvasManager.GetLayerTimingsBuffer(this);
|
|
if (timingsBuffer) {
|
|
layerQuery = timingsBuffer.AddTimeElapsedQuery();
|
|
renderer.StartQuery(layerQuery)
|
|
}
|
|
}
|
|
if (useOwnTexture) {
|
|
const rtOpts = {
|
|
sampling: this._runtime.GetSampling()
|
|
};
|
|
if (canvasManager.GetCurrentFullscreenScalingQuality() === "low") {
|
|
rtOpts.width = canvasManager.GetDrawWidth();
|
|
rtOpts.height = canvasManager.GetDrawHeight()
|
|
}
|
|
ownRenderTarget = this._runtime.GetAdditionalRenderTarget(rtOpts);
|
|
renderer.SetRenderTarget(ownRenderTarget);
|
|
if (this.IsTransparent())
|
|
renderer.ClearRgba(0, 0, 0, 0)
|
|
} else
|
|
renderer.SetRenderTarget(destinationRenderTarget);
|
|
if (!this.IsTransparent())
|
|
renderer.Clear(this._backgroundColor);
|
|
this._curRenderTarget = ownRenderTarget || destinationRenderTarget;
|
|
this._SetTransform(renderer);
|
|
renderer.SetBaseZ(this.GetZElevation());
|
|
if (this.GetNormalScale() > Number.EPSILON) {
|
|
this._UpdateZIndices();
|
|
const useRenderCells = this._useRenderCells && this.GetZElevation() === 0 && !this._anyInstanceZElevated;
|
|
if (useRenderCells)
|
|
this._DrawInstances_RenderCells(renderer);
|
|
else
|
|
this._DrawInstances(renderer, this._instances)
|
|
}
|
|
renderer.SetBaseZ(0);
|
|
renderer.SetCurrentZ(0);
|
|
renderer.SetCameraXYZ(0, 0, 100);
|
|
renderer.SetLookXYZ(0, 0, 0);
|
|
if (useOwnTexture)
|
|
this._DrawLayerOwnTextureToRenderTarget(renderer, ownRenderTarget, destinationRenderTarget, isFirstDrawnLayer);
|
|
if (layerQuery)
|
|
renderer.EndQuery(layerQuery);
|
|
this._curRenderTarget = null
|
|
}
|
|
_DrawInstances(renderer, instances) {
|
|
const viewport = this._viewport;
|
|
const renderTarget = this._curRenderTarget;
|
|
let lastInst = null;
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
if (inst === lastInst)
|
|
continue;
|
|
lastInst = inst;
|
|
const wi = inst.GetWorldInfo();
|
|
if (wi.IsVisible() && wi.IsInViewport(viewport))
|
|
if (wi.HasAnyActiveEffect())
|
|
this._DrawInstanceWithEffectsAndRestore(inst, wi, renderer, renderTarget);
|
|
else
|
|
this._DrawInstance(inst, wi, renderer)
|
|
}
|
|
}
|
|
_DrawInstances_RenderCells(renderer) {
|
|
const renderGrid = this._renderGrid;
|
|
const curRenderCells = this._curRenderCells;
|
|
const lastRenderCells = this._lastRenderCells;
|
|
const viewport = this._viewport;
|
|
let instancesToDraw;
|
|
curRenderCells.set(renderGrid.XToCell(viewport.getLeft()), renderGrid.YToCell(viewport.getTop()), renderGrid.XToCell(viewport.getRight()), renderGrid.YToCell(viewport.getBottom()));
|
|
if (!this._isRenderListUpToDate || !curRenderCells.equals(lastRenderCells)) {
|
|
instancesToDraw = this._GetRenderCellInstancesToDraw();
|
|
this._isRenderListUpToDate = true;
|
|
lastRenderCells.copy(curRenderCells)
|
|
} else
|
|
instancesToDraw = this._lastRenderList;
|
|
this._DrawInstances(renderer, instancesToDraw);
|
|
if (instancesToDraw !== this._lastRenderList)
|
|
C3.shallowAssignArray(this._lastRenderList, instancesToDraw)
|
|
}
|
|
_DrawInstance(inst, wi, renderer) {
|
|
const wiStateGroup = wi.GetRendererStateGroup();
|
|
if (renderer.GetCurrentStateGroup() !== wiStateGroup)
|
|
wiStateGroup.Apply();
|
|
inst.Draw(renderer)
|
|
}
|
|
_DrawInstanceWithEffectsAndRestore(inst, wi, renderer, renderTarget) {
|
|
if (this._DrawInstanceWithEffects(inst, wi, renderer, renderTarget, null))
|
|
this._SetTransform(renderer)
|
|
}
|
|
_DrawInstanceWithEffects(inst, wi, renderer, renderTarget, opts) {
|
|
const activeEffectTypes = wi.GetInstanceEffectList().GetActiveEffectTypes();
|
|
if (activeEffectTypes.length === 1) {
|
|
const effectType = activeEffectTypes[0];
|
|
const shaderProgram = effectType.GetShaderProgram();
|
|
if (!shaderProgram.NeedsPostDrawOrExtendsBox() && wi.HasDefaultColor() && !inst.MustPreDraw()) {
|
|
this._DrawInstanceWithEffects_FastPath(inst, wi, effectType, shaderProgram, renderer);
|
|
return false
|
|
}
|
|
}
|
|
const ret = C3.RenderEffectChain(renderer, this._runtime, inst, renderTarget, activeEffectTypes, opts);
|
|
renderer.SetBaseZ(this.GetZElevation());
|
|
return ret
|
|
}
|
|
_DrawInstanceWithEffects_FastPath(inst, wi, effectType, shaderProgram, renderer) {
|
|
renderer.SetProgram(shaderProgram);
|
|
renderer.SetBlendMode(wi.GetBlendMode());
|
|
if (shaderProgram.IsAnimated())
|
|
this._runtime.UpdateRender();
|
|
let pixelWidth = 0
|
|
, pixelHeight = 0;
|
|
if (shaderProgram.UsesAnySrcRectOrPixelSize()) {
|
|
const [sheetWidth,sheetHeight] = inst.GetCurrentSurfaceSize();
|
|
pixelWidth = 1 / sheetWidth;
|
|
pixelHeight = 1 / sheetHeight;
|
|
const instTexRect = inst.GetCurrentTexRect();
|
|
if (instTexRect)
|
|
tmpSrcRect.copy(instTexRect);
|
|
else
|
|
tmpSrcRect.set(0, 0, 0, 0)
|
|
}
|
|
const paramArr = wi.GetInstanceEffectList().GetEffectParametersForIndex(effectType.GetIndex());
|
|
renderer.SetCurrentZ(wi.GetZElevation());
|
|
renderer.SetProgramParameters(null, tmpDestRect, tmpSrcRect, tmpSrcRect, wi.GetBoundingBox(), pixelWidth, pixelHeight, this.GetOwnScale(), this.GetAngle(), this._runtime.GetGameTime(), paramArr);
|
|
inst.Draw(renderer)
|
|
}
|
|
_DrawLayerOwnTextureToRenderTarget(renderer, ownRenderTarget, destinationRenderTarget, isFirstDrawnLayer) {
|
|
const activeEffectTypes = this._effectList.GetActiveEffectTypes();
|
|
const runtime = this._runtime;
|
|
if (this._CanFastPathDrawLayer(activeEffectTypes)) {
|
|
renderer.SetRenderTarget(destinationRenderTarget);
|
|
if (activeEffectTypes.length === 1) {
|
|
const effectType = activeEffectTypes[0];
|
|
const shaderProgram = effectType.GetShaderProgram();
|
|
renderer.SetProgram(shaderProgram);
|
|
tmpSrcRect.set(0, 0, 1, 1);
|
|
const paramArr = this._effectList.GetEffectParametersForIndex(effectType.GetIndex());
|
|
renderer.SetProgramParameters(null, tmpDestRect, tmpSrcRect, tmpSrcRect, this._viewport, 1 / runtime.GetDrawWidth(), 1 / runtime.GetDrawHeight(), this.GetNormalScale(), this.GetAngle(), runtime.GetGameTime(), paramArr);
|
|
if (shaderProgram.IsAnimated())
|
|
runtime.UpdateRender()
|
|
} else
|
|
renderer.SetTextureFillMode();
|
|
if (isFirstDrawnLayer && this._blendMode === 0 && this.HasDefaultColor() && activeEffectTypes.length === 0)
|
|
renderer.CopyRenderTarget(ownRenderTarget);
|
|
else {
|
|
renderer.SetBlendMode(this._blendMode);
|
|
renderer.SetColor(this._premultipliedColor);
|
|
renderer.DrawRenderTarget(ownRenderTarget)
|
|
}
|
|
renderer.InvalidateRenderTarget(ownRenderTarget);
|
|
runtime.ReleaseAdditionalRenderTarget(ownRenderTarget)
|
|
} else
|
|
C3.RenderEffectChain(renderer, runtime, this, destinationRenderTarget, activeEffectTypes)
|
|
}
|
|
GetOwnScale() {
|
|
return this._scale
|
|
}
|
|
SetOwnScale(s) {
|
|
if (this._scale === s)
|
|
return;
|
|
this._scale = s;
|
|
this._layout.BoundScrolling();
|
|
this._runtime.UpdateRender()
|
|
}
|
|
GetRenderScale() {
|
|
return this.GetNormalScale() * this._runtime.GetRenderScale()
|
|
}
|
|
GetDisplayScale() {
|
|
return this.GetNormalScale() * this._runtime.GetDisplayScale()
|
|
}
|
|
GetNormalScale() {
|
|
return (this._scale * this._layout.GetScale() - 1) * this._scaleRate + 1
|
|
}
|
|
UpdateViewport() {
|
|
this._isAngleEnabled = false;
|
|
let[px,py] = this.CanvasCssToLayer(0, 0);
|
|
this._isAngleEnabled = true;
|
|
if (this._runtime.IsPixelRoundingEnabled()) {
|
|
px = Math.round(px);
|
|
py = Math.round(py)
|
|
}
|
|
const invScale = 1 / this.GetNormalScale();
|
|
const viewportZ0 = this._viewportZ0;
|
|
viewportZ0.set(px, py, px + this._runtime.GetViewportWidth() * invScale, py + this._runtime.GetViewportHeight() * invScale);
|
|
const myAngle = this.GetAngle();
|
|
if (myAngle !== 0) {
|
|
tmpRect.copy(viewportZ0);
|
|
tmpRect.offset(-viewportZ0.midX(), -viewportZ0.midY());
|
|
tmpQuad.setFromRotatedRect(tmpRect, myAngle);
|
|
tmpQuad.getBoundingBox(tmpRect);
|
|
tmpRect.offset(viewportZ0.midX(), viewportZ0.midY());
|
|
viewportZ0.copy(tmpRect)
|
|
}
|
|
this.GetViewportForZ(this._zElevation, this._viewport)
|
|
}
|
|
CanvasCssToLayer(ptx, pty, z=0) {
|
|
return this._CanvasToLayer(ptx, pty, z, this.GetDisplayScale())
|
|
}
|
|
DrawSurfaceToLayer(ptx, pty, z=0) {
|
|
return this._CanvasToLayer(ptx, pty, z, this.GetRenderScale() * this.GetDevicePixelRatio())
|
|
}
|
|
_CanvasToLayer(canvasX, canvasY, zElevation, displayScale) {
|
|
const parallaxOriginX = this._runtime.GetParallaxXOrigin();
|
|
const parallaxOriginY = this._runtime.GetParallaxYOrigin();
|
|
const scrollOriginX = (this._layout.GetScrollX() - parallaxOriginX) * this._parallaxX + parallaxOriginX;
|
|
const scrollOriginY = (this._layout.GetScrollY() - parallaxOriginY) * this._parallaxY + parallaxOriginY;
|
|
const normalScale = this.GetNormalScale();
|
|
const scaledViewportWidth = this._runtime.GetViewportWidth() / normalScale;
|
|
const scaledViewportHeight = this._runtime.GetViewportHeight() / normalScale;
|
|
const viewportOriginX = scrollOriginX - scaledViewportWidth / 2;
|
|
const viewportOriginY = scrollOriginY - scaledViewportHeight / 2;
|
|
let layerX = viewportOriginX + canvasX / displayScale;
|
|
let layerY = viewportOriginY + canvasY / displayScale;
|
|
const a = this.GetAngle();
|
|
if (a !== 0) {
|
|
layerX -= scrollOriginX;
|
|
layerY -= scrollOriginY;
|
|
const cosa = Math.cos(a);
|
|
const sina = Math.sin(a);
|
|
const x_temp = layerX * cosa - layerY * sina;
|
|
layerY = layerY * cosa + layerX * sina;
|
|
layerX = x_temp;
|
|
layerX += scrollOriginX;
|
|
layerY += scrollOriginY
|
|
}
|
|
if (zElevation !== 0) {
|
|
const midX = this._viewportZ0.midX();
|
|
const midY = this._viewportZ0.midY();
|
|
const scaleFactor = this.Get2DScaleFactorToZ(zElevation);
|
|
layerX = (layerX - midX) / scaleFactor + midX;
|
|
layerY = (layerY - midY) / scaleFactor + midY
|
|
}
|
|
return [layerX, layerY]
|
|
}
|
|
CanvasCssToLayer_DefaultTransform(ptx, pty) {
|
|
const scale = this._scale;
|
|
const scaleRate = this._scaleRate;
|
|
const parallaxX = this._parallaxX;
|
|
const parallaxY = this._parallaxY;
|
|
const angle = this._angle;
|
|
this._scale = 1;
|
|
this._scaleRate = 1;
|
|
this._parallaxX = 1;
|
|
this._parallaxY = 1;
|
|
this._angle = 0;
|
|
const ret = this.CanvasCssToLayer(ptx, pty);
|
|
this._scale = scale;
|
|
this._scaleRate = scaleRate;
|
|
this._parallaxX = parallaxX;
|
|
this._parallaxY = parallaxY;
|
|
this._angle = angle;
|
|
return ret
|
|
}
|
|
LayerToCanvasCss(ptx, pty, z=0) {
|
|
return this._LayerToCanvas(ptx, pty, z, this.GetDisplayScale())
|
|
}
|
|
LayerToDrawSurface(ptx, pty, z=0) {
|
|
return this._LayerToCanvas(ptx, pty, z, this.GetRenderScale() * this.GetDevicePixelRatio())
|
|
}
|
|
_LayerToCanvas(layerX, layerY, zElevation, displayScale) {
|
|
const runtime = this._runtime;
|
|
const layout = this._layout;
|
|
if (zElevation !== 0) {
|
|
const midX = this._viewportZ0.midX();
|
|
const midY = this._viewportZ0.midY();
|
|
const scaleFactor = this.Get2DScaleFactorToZ(zElevation);
|
|
layerX = (layerX - midX) * scaleFactor + midX;
|
|
layerY = (layerY - midY) * scaleFactor + midY
|
|
}
|
|
const parallaxOriginX = runtime.GetParallaxXOrigin();
|
|
const parallaxOriginY = runtime.GetParallaxYOrigin();
|
|
const scrollOriginX = (layout.GetScrollX() - parallaxOriginX) * this._parallaxX + parallaxOriginX;
|
|
const scrollOriginY = (layout.GetScrollY() - parallaxOriginY) * this._parallaxY + parallaxOriginY;
|
|
const a = this.GetAngle();
|
|
if (a !== 0) {
|
|
layerX -= scrollOriginX;
|
|
layerY -= scrollOriginY;
|
|
const cosa = Math.cos(-a);
|
|
const sina = Math.sin(-a);
|
|
const x_temp = layerX * cosa - layerY * sina;
|
|
layerY = layerY * cosa + layerX * sina;
|
|
layerX = x_temp;
|
|
layerX += scrollOriginX;
|
|
layerY += scrollOriginY
|
|
}
|
|
const normalScale = this.GetNormalScale();
|
|
const scaledViewportWidth = runtime.GetViewportWidth() / normalScale;
|
|
const scaledViewportHeight = runtime.GetViewportHeight() / normalScale;
|
|
const viewportOriginX = scrollOriginX - scaledViewportWidth / 2;
|
|
const viewportOriginY = scrollOriginY - scaledViewportHeight / 2;
|
|
const viewportOffX = layerX - viewportOriginX;
|
|
const viewportOffY = layerY - viewportOriginY;
|
|
const canvasX = viewportOffX * displayScale;
|
|
const canvasY = viewportOffY * displayScale;
|
|
return [canvasX, canvasY]
|
|
}
|
|
_GetLayerToDrawSurfaceScale(size, zElevation) {
|
|
size *= this.GetRenderScale() * this.GetDevicePixelRatio();
|
|
if (zElevation !== 0)
|
|
size *= this.Get2DScaleFactorToZ(zElevation);
|
|
return size
|
|
}
|
|
_SaveToJson() {
|
|
const o = {
|
|
"s": this.GetOwnScale(),
|
|
"a": this.GetOwnAngle(),
|
|
"vl": this._viewport.getLeft(),
|
|
"vt": this._viewport.getTop(),
|
|
"vr": this._viewport.getRight(),
|
|
"vb": this._viewport.getBottom(),
|
|
"v": this.IsVisible(),
|
|
"bc": this._backgroundColor.toJSON(),
|
|
"t": this.IsTransparent(),
|
|
"px": this.GetParallaxX(),
|
|
"py": this.GetParallaxY(),
|
|
"c": this._color.toJSON(),
|
|
"sr": this.GetScaleRate(),
|
|
"fx": this._effectList.SaveToJson(),
|
|
"cg": this._createdGlobalUids
|
|
};
|
|
return o
|
|
}
|
|
_LoadFromJson(o) {
|
|
this._scale = o["s"];
|
|
this._angle = o["a"];
|
|
this._viewport.set(o["vl"], o["vt"], o["vr"], o["vb"]);
|
|
this._isVisible = !!o["v"];
|
|
this._backgroundColor.setFromJSON(o["bc"]);
|
|
this._isTransparent = !!o["t"];
|
|
this._parallaxX = o["px"];
|
|
this._parallaxY = o["py"];
|
|
this._color.setFromJSON(o["c"]);
|
|
this._scaleRate = o["sr"];
|
|
C3.shallowAssignArray(this._createdGlobalUids, o["cg"]);
|
|
C3.shallowAssignArray(this._initialInstances, this._startupInitialInstances);
|
|
const tempSet = new Set(this._createdGlobalUids);
|
|
let j = 0;
|
|
for (let i = 0, len = this._initialInstances.length; i < len; ++i)
|
|
if (!tempSet.has(this._initialInstances[i][2])) {
|
|
this._initialInstances[j] = this._initialInstances[i];
|
|
++j
|
|
}
|
|
C3.truncateArray(this._initialInstances, j);
|
|
this._effectList.LoadFromJson(o["fx"]);
|
|
this._SortInstancesByLastCachedZIndex(false);
|
|
this.SetZIndicesChanged()
|
|
}
|
|
GetILayer() {
|
|
return this._iLayer
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const C3Debugger = self.C3Debugger;
|
|
const assert = self.assert;
|
|
const tempDestRect = C3.New(C3.Rect);
|
|
const tempSrcRect = C3.New(C3.Rect);
|
|
const tempLayoutRect = C3.New(C3.Rect);
|
|
C3.Layout = class Layout extends C3.DefendedBase {
|
|
constructor(layoutManager, index, data) {
|
|
super();
|
|
this._layoutManager = layoutManager;
|
|
this._runtime = layoutManager.GetRuntime();
|
|
this._name = data[0];
|
|
this._originalWidth = data[1];
|
|
this._originalHeight = data[2];
|
|
this._width = data[1];
|
|
this._height = data[2];
|
|
this._isUnboundedScrolling = !!data[3];
|
|
this._eventSheetName = data[4];
|
|
this._eventSheet = null;
|
|
this._sid = data[5];
|
|
this._index = index;
|
|
this._scrollX = 0;
|
|
this._scrollY = 0;
|
|
this._scale = 1;
|
|
this._angle = 0;
|
|
this._initialObjectClasses = new Set;
|
|
this._textureLoadedTypes = new Set;
|
|
this._textureLoadPendingPromises = new Set;
|
|
this._createdInstances = [];
|
|
this._initialNonWorld = [];
|
|
this._layers = [];
|
|
this._layersByName = new Map;
|
|
this._layersBySid = new Map;
|
|
this._effectList = C3.New(C3.EffectList, this, data[8]);
|
|
this._curRenderTarget = null;
|
|
this._persistData = {};
|
|
this._isFirstVisit = true;
|
|
this._iLayout = new self.ILayout(this);
|
|
this._userScriptDispatcher = C3.New(C3.Event.Dispatcher);
|
|
for (const layerData of data[6]) {
|
|
const layer = C3.Layer.Create(this, this._layers.length, layerData);
|
|
this._layers.push(layer);
|
|
this._layersByName.set(layer.GetName().toLowerCase(), layer);
|
|
this._layersBySid.set(layer.GetSID(), layer)
|
|
}
|
|
for (const instData of data[7]) {
|
|
const objectClass = this._runtime.GetObjectClassByIndex(instData[1]);
|
|
if (!objectClass)
|
|
throw new Error("missing nonworld object class");
|
|
if (!objectClass.GetDefaultInstanceData())
|
|
objectClass.SetDefaultInstanceData(instData);
|
|
this._initialNonWorld.push(instData);
|
|
this._AddInitialObjectClass(objectClass)
|
|
}
|
|
}
|
|
Release() {
|
|
for (const l of this._layers)
|
|
l.Release();
|
|
C3.clearArray(this._layers);
|
|
this._textureLoadPendingPromises.clear();
|
|
this._eventSheet = null;
|
|
this._layoutManager = null;
|
|
this._runtime = null
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
GetSID() {
|
|
return this._sid
|
|
}
|
|
GetIndex() {
|
|
return this._index
|
|
}
|
|
GetEffectList() {
|
|
return this._effectList
|
|
}
|
|
GetMinLayerScale() {
|
|
let m = this._layers[0].GetNormalScale();
|
|
for (let i = 1, len = this._layers.length; i < len; ++i) {
|
|
const layer = this._layers[i];
|
|
if (layer.GetParallaxX() === 0 && layer.GetParallaxY() === 0)
|
|
continue;
|
|
m = Math.min(m, layer.GetNormalScale())
|
|
}
|
|
return m
|
|
}
|
|
SetScrollX(x) {
|
|
if (!this._isUnboundedScrolling) {
|
|
const widthBoundary = this._runtime.GetViewportWidth() * (1 / this.GetMinLayerScale()) / 2;
|
|
if (x > this._width - widthBoundary)
|
|
x = this._width - widthBoundary;
|
|
if (x < widthBoundary)
|
|
x = widthBoundary
|
|
}
|
|
if (this._scrollX !== x) {
|
|
this._scrollX = x;
|
|
this._runtime.UpdateRender()
|
|
}
|
|
}
|
|
GetScrollX() {
|
|
return this._scrollX
|
|
}
|
|
SetScrollY(y) {
|
|
if (!this._isUnboundedScrolling) {
|
|
const heightBoundary = this._runtime.GetViewportHeight() * (1 / this.GetMinLayerScale()) / 2;
|
|
if (y > this._height - heightBoundary)
|
|
y = this._height - heightBoundary;
|
|
if (y < heightBoundary)
|
|
y = heightBoundary
|
|
}
|
|
if (this._scrollY !== y) {
|
|
this._scrollY = y;
|
|
this._runtime.UpdateRender()
|
|
}
|
|
}
|
|
GetScrollY() {
|
|
return this._scrollY
|
|
}
|
|
BoundScrolling() {
|
|
this.SetScrollX(this.GetScrollX());
|
|
this.SetScrollY(this.GetScrollY())
|
|
}
|
|
GetScale() {
|
|
return this._scale
|
|
}
|
|
SetScale(s) {
|
|
s = +s;
|
|
if (this._scale === s)
|
|
return;
|
|
this._scale = s;
|
|
this.BoundScrolling()
|
|
}
|
|
SetAngle(a) {
|
|
this._angle = C3.clampAngle(a)
|
|
}
|
|
GetAngle() {
|
|
return this._angle
|
|
}
|
|
GetWidth() {
|
|
return this._width
|
|
}
|
|
SetWidth(w) {
|
|
if (!isFinite(w) || w < 1)
|
|
return;
|
|
this._width = w
|
|
}
|
|
GetHeight() {
|
|
return this._height
|
|
}
|
|
SetHeight(h) {
|
|
if (!isFinite(h) || h < 1)
|
|
return;
|
|
this._height = h
|
|
}
|
|
GetEventSheet() {
|
|
return this._eventSheet
|
|
}
|
|
GetLayers() {
|
|
return this._layers
|
|
}
|
|
GetLayerCount() {
|
|
return this._layers.length
|
|
}
|
|
GetLayer(p) {
|
|
if (typeof p === "number")
|
|
return this.GetLayerByIndex(p);
|
|
else
|
|
return this.GetLayerByName(p.toString())
|
|
}
|
|
GetLayerByIndex(i) {
|
|
i = C3.clamp(Math.floor(i), 0, this._layers.length - 1);
|
|
return this._layers[i]
|
|
}
|
|
GetLayerByName(name) {
|
|
return this._layersByName.get(name.toLowerCase()) || null
|
|
}
|
|
GetLayerBySID(sid) {
|
|
return this._layersBySid.get(sid) || null
|
|
}
|
|
HasOpaqueBottomLayer() {
|
|
for (const layer of this._layers)
|
|
if (layer.ShouldDraw())
|
|
return layer._IsOpaque();
|
|
return false
|
|
}
|
|
IsFirstVisit() {
|
|
return this._isFirstVisit
|
|
}
|
|
_GetInitialObjectClasses() {
|
|
return [...this._initialObjectClasses]
|
|
}
|
|
_AddInitialObjectClass(objectClass) {
|
|
if (objectClass.IsInContainer())
|
|
for (const containerType of objectClass.GetContainer().GetObjectTypes())
|
|
this._initialObjectClasses.add(containerType);
|
|
else
|
|
this._initialObjectClasses.add(objectClass)
|
|
}
|
|
_GetTextureLoadedObjectTypes() {
|
|
return [...this._textureLoadedTypes]
|
|
}
|
|
_Load(previousLayout, renderer) {
|
|
if (previousLayout === this || !renderer)
|
|
return Promise.resolve();
|
|
if (previousLayout) {
|
|
C3.CopySet(this._textureLoadedTypes, previousLayout._textureLoadedTypes);
|
|
previousLayout._textureLoadedTypes.clear()
|
|
}
|
|
const promises = [];
|
|
for (const oc of this._initialObjectClasses)
|
|
if (!this._textureLoadedTypes.has(oc)) {
|
|
promises.push(oc.LoadTextures(renderer));
|
|
this._textureLoadedTypes.add(oc)
|
|
}
|
|
return Promise.all(promises)
|
|
}
|
|
async MaybeLoadTexturesFor(objectClass) {
|
|
if (objectClass.IsFamily())
|
|
throw new Error("cannot load textures for family");
|
|
const renderer = this._runtime.GetWebGLRenderer();
|
|
if (!renderer || renderer.IsContextLost() || this._textureLoadedTypes.has(objectClass))
|
|
return;
|
|
this._textureLoadedTypes.add(objectClass);
|
|
const loadPromise = objectClass.LoadTextures(renderer);
|
|
this._AddPendingTextureLoadPromise(loadPromise);
|
|
await loadPromise;
|
|
objectClass.OnDynamicTextureLoadComplete();
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_AddPendingTextureLoadPromise(promise) {
|
|
this._textureLoadPendingPromises.add(promise);
|
|
promise.then(()=>this._textureLoadPendingPromises.delete(promise)).catch(()=>this._textureLoadPendingPromises.delete(promise))
|
|
}
|
|
WaitForPendingTextureLoadsToComplete() {
|
|
return Promise.all([...this._textureLoadPendingPromises])
|
|
}
|
|
MaybeUnloadTexturesFor(objectClass) {
|
|
if (objectClass.IsFamily() || objectClass.GetInstanceCount() > 0)
|
|
throw new Error("cannot unload textures");
|
|
const renderer = this._runtime.GetWebGLRenderer();
|
|
if (!renderer || !this._textureLoadedTypes.has(objectClass))
|
|
return;
|
|
this._textureLoadedTypes.delete(objectClass);
|
|
objectClass.ReleaseTextures(renderer)
|
|
}
|
|
_Unload(nextLayout, renderer) {
|
|
if (nextLayout === this || !renderer)
|
|
return;
|
|
for (const oc of this._textureLoadedTypes)
|
|
if (!oc.IsGlobal() && !nextLayout._initialObjectClasses.has(oc)) {
|
|
oc.ReleaseTextures();
|
|
this._textureLoadedTypes.delete(oc)
|
|
}
|
|
}
|
|
_OnWebGLContextLost() {
|
|
this._textureLoadedTypes.clear()
|
|
}
|
|
async _StartRunning(isFirstLayout) {
|
|
const runtime = this._runtime;
|
|
const layoutManager = this._layoutManager;
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
if (this._eventSheetName) {
|
|
this._eventSheet = eventSheetManager.GetEventSheetByName(this._eventSheetName);
|
|
this._eventSheet._UpdateDeepIncludes()
|
|
}
|
|
layoutManager._SetMainRunningLayout(this);
|
|
this._width = this._originalWidth;
|
|
this._height = this._originalHeight;
|
|
this._scrollX = runtime.GetOriginalViewportWidth() / 2;
|
|
this._scrollY = runtime.GetOriginalViewportHeight() / 2;
|
|
this.BoundScrolling();
|
|
this._MoveGlobalObjectsToThisLayout(isFirstLayout);
|
|
this._runtime.SetUsingCreatePromises(true);
|
|
this._CreateInitialInstances();
|
|
if (!this._isFirstVisit)
|
|
this._CreatePersistedInstances();
|
|
this._CreateAndLinkContainerInstances(this._createdInstances);
|
|
this._CreateInitialNonWorldInstances();
|
|
layoutManager.ClearPendingChangeLayout();
|
|
runtime.FlushPendingInstances();
|
|
this._runtime.SetUsingCreatePromises(false);
|
|
const createPromises = this._runtime.GetCreatePromises();
|
|
await Promise.all(createPromises);
|
|
C3.clearArray(createPromises);
|
|
if (runtime.IsLoadingState())
|
|
runtime._TriggerOnCreateAfterLoad(this._createdInstances);
|
|
else
|
|
for (const inst of this._createdInstances) {
|
|
inst._TriggerOnCreated();
|
|
inst.SetupInitialSceneGraphConnections()
|
|
}
|
|
C3.clearArray(this._createdInstances);
|
|
await Promise.all([...this._initialObjectClasses].map(oc=>oc.PreloadTexturesWithInstances(this._runtime.GetWebGLRenderer())));
|
|
if (isFirstLayout) {
|
|
runtime.Dispatcher().dispatchEvent(new C3.Event("beforefirstlayoutstart"));
|
|
await runtime.DispatchUserScriptEventAsyncWait(new C3.Event("beforeprojectstart"))
|
|
}
|
|
await this.DispatchUserScriptEventAsyncWait(new C3.Event("beforelayoutstart"));
|
|
if (!runtime.IsLoadingState())
|
|
await runtime.TriggerAsync(C3.Plugins.System.Cnds.OnLayoutStart, null, null);
|
|
await this.DispatchUserScriptEventAsyncWait(new C3.Event("afterlayoutstart"));
|
|
if (isFirstLayout) {
|
|
runtime.Dispatcher().dispatchEvent(new C3.Event("afterfirstlayoutstart"));
|
|
await runtime.DispatchUserScriptEventAsyncWait(new C3.Event("afterprojectstart"))
|
|
}
|
|
eventSheetManager._RunQueuedTriggers(layoutManager);
|
|
await this.WaitForPendingTextureLoadsToComplete();
|
|
this._isFirstVisit = false
|
|
}
|
|
_MoveGlobalObjectsToThisLayout(isFirstLayout) {
|
|
for (const objectClass of this._runtime.GetAllObjectClasses()) {
|
|
if (objectClass.IsFamily() || !objectClass.IsWorldType())
|
|
continue;
|
|
for (const inst of objectClass.GetInstances()) {
|
|
const wi = inst.GetWorldInfo();
|
|
const oldLayer = wi.GetLayer();
|
|
const layerIndex = C3.clamp(oldLayer.GetIndex(), 0, this._layers.length - 1);
|
|
const newLayer = this._layers[layerIndex];
|
|
wi._SetLayer(newLayer);
|
|
newLayer._MaybeAddInstance(inst)
|
|
}
|
|
}
|
|
if (!isFirstLayout)
|
|
for (const layer of this._layers)
|
|
layer._SortInstancesByLastCachedZIndex(false)
|
|
}
|
|
_CreateInitialInstances() {
|
|
for (const layer of this._layers) {
|
|
layer.CreateInitialInstances(this._createdInstances);
|
|
layer.UpdateViewport();
|
|
layer._Start()
|
|
}
|
|
}
|
|
_CreatePersistedInstances() {
|
|
let uidsChanged = false;
|
|
for (const [sidStr,typeData] of Object.entries(this._persistData)) {
|
|
const objectClass = this._runtime.GetObjectClassBySID(parseInt(sidStr, 10));
|
|
if (!objectClass || objectClass.IsFamily() || !objectClass.HasPersistBehavior())
|
|
continue;
|
|
for (const instData of typeData) {
|
|
let layer = null;
|
|
if (objectClass.IsWorldType()) {
|
|
layer = this.GetLayerBySID(instData["w"]["l"]);
|
|
if (!layer)
|
|
continue
|
|
}
|
|
const inst = this._runtime.CreateInstanceFromData(objectClass, layer, false, 0, 0, true);
|
|
inst.LoadFromJson(instData);
|
|
uidsChanged = true;
|
|
this._createdInstances.push(inst)
|
|
}
|
|
C3.clearArray(typeData)
|
|
}
|
|
for (const layer of this._layers) {
|
|
layer._SortInstancesByLastCachedZIndex(true);
|
|
layer.SetZIndicesChanged()
|
|
}
|
|
if (uidsChanged) {
|
|
this._runtime.FlushPendingInstances();
|
|
this._runtime._RefreshUidMap()
|
|
}
|
|
}
|
|
_CreateAndLinkContainerInstances(createdInstances) {
|
|
for (const inst of createdInstances) {
|
|
if (!inst.IsInContainer())
|
|
continue;
|
|
const wi = inst.GetWorldInfo();
|
|
const iid = inst.GetIID();
|
|
for (const containerType of inst.GetObjectClass().GetContainer().objectTypes()) {
|
|
if (containerType === inst.GetObjectClass())
|
|
continue;
|
|
const instances = containerType.GetInstances();
|
|
if (instances.length > iid)
|
|
inst._AddSibling(instances[iid]);
|
|
else {
|
|
let s;
|
|
if (wi)
|
|
s = this._runtime.CreateInstanceFromData(containerType, wi.GetLayer(), true, wi.GetX(), wi.GetY(), true);
|
|
else
|
|
s = this._runtime.CreateInstanceFromData(containerType, null, true, 0, 0, true);
|
|
this._runtime.FlushPendingInstances();
|
|
containerType._UpdateIIDs();
|
|
inst._AddSibling(s);
|
|
createdInstances.push(s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_CreateInitialNonWorldInstances() {
|
|
for (const instData of this._initialNonWorld) {
|
|
const objectClass = this._runtime.GetObjectClassByIndex(instData[1]);
|
|
if (!objectClass.IsInContainer())
|
|
this._runtime.CreateInstanceFromData(instData, null, true)
|
|
}
|
|
}
|
|
_CreateGlobalNonWorlds() {
|
|
const createdInstances = [];
|
|
const initialNonWorld = this._initialNonWorld;
|
|
let k = 0;
|
|
for (let i = 0, len = initialNonWorld.length; i < len; ++i) {
|
|
const instData = initialNonWorld[i];
|
|
const objectClass = this._runtime.GetObjectClassByIndex(instData[1]);
|
|
if (objectClass.IsGlobal()) {
|
|
if (!objectClass.IsInContainer() || !objectClass.GetContainer().HasAnyWorldType())
|
|
createdInstances.push(this._runtime.CreateInstanceFromData(instData, null, true))
|
|
} else {
|
|
initialNonWorld[k] = instData;
|
|
++k
|
|
}
|
|
}
|
|
C3.truncateArray(initialNonWorld, k);
|
|
this._runtime.FlushPendingInstances();
|
|
this._CreateAndLinkContainerInstances(createdInstances)
|
|
}
|
|
RecreateInitialObjects(objectClass, rc, srcLayer, offsetX, offsetY) {
|
|
if (srcLayer)
|
|
return srcLayer.RecreateInitialObjects(objectClass, rc, offsetX, offsetY);
|
|
else {
|
|
const ret = [];
|
|
for (const layer of this._layers)
|
|
ret.push(layer.RecreateInitialObjects(objectClass, rc, offsetX, offsetY));
|
|
return ret.flat()
|
|
}
|
|
}
|
|
async _StopRunning() {
|
|
const layoutManager = this._layoutManager;
|
|
if (!this._runtime.IsLoadingState())
|
|
await this._runtime.TriggerAsync(C3.Plugins.System.Cnds.OnLayoutEnd, null, null);
|
|
layoutManager.SetIsEndingLayout(true);
|
|
this._runtime.GetEventSheetManager().ClearAllScheduledWaits();
|
|
if (!this._isFirstVisit)
|
|
this._SavePersistData();
|
|
for (const layer of this._layers)
|
|
layer._End();
|
|
for (const objectClass of this._runtime.GetAllObjectClasses()) {
|
|
if (objectClass.IsGlobal() || objectClass.IsWorldType() || objectClass.GetPlugin().IsSingleGlobal() || objectClass.IsFamily())
|
|
continue;
|
|
for (const inst of objectClass.GetInstances())
|
|
this._runtime.DestroyInstance(inst);
|
|
this._runtime.FlushPendingInstances()
|
|
}
|
|
layoutManager.SetIsEndingLayout(false);
|
|
if (layoutManager.GetMainRunningLayout() === this)
|
|
layoutManager._SetMainRunningLayout(null)
|
|
}
|
|
_SaveInstanceToPersist(inst) {
|
|
const sidStr = inst.GetObjectClass().GetSID().toString();
|
|
if (!this._persistData.hasOwnProperty(sidStr))
|
|
this._persistData[sidStr] = [];
|
|
const typePersist = this._persistData[sidStr];
|
|
typePersist.push(inst.SaveToJson())
|
|
}
|
|
_SavePersistData() {
|
|
for (const layer of this._layers) {
|
|
layer._UpdateZIndices();
|
|
for (const inst of layer._GetInstances()) {
|
|
const objectClass = inst.GetObjectClass();
|
|
if (!objectClass.IsGlobal() && objectClass.HasPersistBehavior())
|
|
this._SaveInstanceToPersist(inst)
|
|
}
|
|
}
|
|
}
|
|
ResetPersistData() {
|
|
this._persistData = {};
|
|
this._isFirstVisit = true
|
|
}
|
|
GetRenderTarget() {
|
|
return this._curRenderTarget
|
|
}
|
|
UsesOwnTexture() {
|
|
return this._runtime.GetCanvasManager().GetCurrentFullscreenScalingQuality() === "low" || this._runtime.UsesAnyBackgroundBlending() || this._runtime.GetCompositingMode() === "low-latency" || this._effectList.HasAnyActiveEffect()
|
|
}
|
|
_CanFastPathDrawLayout(activeEffectTypes) {
|
|
if (activeEffectTypes.length === 0)
|
|
return true;
|
|
if (activeEffectTypes.length >= 2)
|
|
return false;
|
|
const effectType = activeEffectTypes[0];
|
|
const shaderProgram = effectType.GetShaderProgram();
|
|
return !shaderProgram.MustPreDraw()
|
|
}
|
|
Draw(renderer) {
|
|
const canvasManager = this._runtime.GetCanvasManager();
|
|
const useOwnTexture = this.UsesOwnTexture();
|
|
let ownRenderTarget = null;
|
|
if (useOwnTexture) {
|
|
if (this._runtime.GetCompositingMode() !== "low-latency") {
|
|
renderer.SetRenderTarget(null);
|
|
renderer.ClearRgba(0, 0, 0, 0)
|
|
}
|
|
const rtOpts = {
|
|
sampling: this._runtime.GetSampling(),
|
|
readback: this._runtime.UsesAnyBackgroundBlending() || this._effectList.HasAnyActiveEffect()
|
|
};
|
|
if (canvasManager.GetCurrentFullscreenScalingQuality() === "low") {
|
|
rtOpts.width = canvasManager.GetDrawWidth();
|
|
rtOpts.height = canvasManager.GetDrawHeight()
|
|
}
|
|
ownRenderTarget = this._runtime.GetAdditionalRenderTarget(rtOpts);
|
|
renderer.SetRenderTarget(ownRenderTarget)
|
|
} else
|
|
renderer.SetRenderTarget(null);
|
|
if (!this.HasOpaqueBottomLayer())
|
|
renderer.ClearRgba(0, 0, 0, 0);
|
|
this._curRenderTarget = ownRenderTarget;
|
|
let isFirstDrawnLayer = true;
|
|
for (const layer of this._layers) {
|
|
layer.UpdateViewport();
|
|
if (layer.ShouldDraw()) {
|
|
layer.Draw(renderer, ownRenderTarget, isFirstDrawnLayer);
|
|
isFirstDrawnLayer = false
|
|
}
|
|
}
|
|
if (useOwnTexture)
|
|
this._DrawLayoutOwnTextureToRenderTarget(renderer, ownRenderTarget);
|
|
this._curRenderTarget = null
|
|
}
|
|
_DrawLayoutOwnTextureToRenderTarget(renderer, ownRenderTarget) {
|
|
const activeEffectTypes = this._effectList.GetActiveEffectTypes();
|
|
const runtime = this._runtime;
|
|
if (this._CanFastPathDrawLayout(activeEffectTypes)) {
|
|
renderer.SetRenderTarget(null);
|
|
if (activeEffectTypes.length === 1) {
|
|
const effectType = activeEffectTypes[0];
|
|
const shaderProgram = effectType.GetShaderProgram();
|
|
renderer.SetProgram(shaderProgram);
|
|
tempSrcRect.set(0, 0, 1, 1);
|
|
tempLayoutRect.set(0, 0, runtime.GetViewportWidth(), runtime.GetViewportHeight());
|
|
const paramArr = this._effectList.GetEffectParametersForIndex(effectType.GetIndex());
|
|
renderer.SetProgramParameters(null, tempDestRect, tempSrcRect, tempSrcRect, tempLayoutRect, 1 / runtime.GetDrawWidth(), 1 / runtime.GetDrawHeight(), this.GetScale(), this.GetAngle(), runtime.GetGameTime(), paramArr);
|
|
if (shaderProgram.IsAnimated())
|
|
runtime.UpdateRender()
|
|
} else
|
|
renderer.SetTextureFillMode();
|
|
if (activeEffectTypes.length === 0)
|
|
renderer.CopyRenderTarget(ownRenderTarget);
|
|
else {
|
|
renderer.SetAlphaBlend();
|
|
renderer.ResetColor();
|
|
renderer.DrawRenderTarget(ownRenderTarget)
|
|
}
|
|
renderer.InvalidateRenderTarget(ownRenderTarget);
|
|
runtime.ReleaseAdditionalRenderTarget(ownRenderTarget)
|
|
} else
|
|
C3.RenderEffectChain(renderer, runtime, this, null, activeEffectTypes)
|
|
}
|
|
_SaveToJson() {
|
|
const o = {
|
|
"sx": this.GetScrollX(),
|
|
"sy": this.GetScrollY(),
|
|
"s": this.GetScale(),
|
|
"a": this.GetAngle(),
|
|
"w": this.GetWidth(),
|
|
"h": this.GetHeight(),
|
|
"fv": this._isFirstVisit,
|
|
"persist": this._persistData,
|
|
"fx": this._effectList.SaveToJson(),
|
|
"layers": {}
|
|
};
|
|
for (const layer of this._layers)
|
|
o["layers"][layer.GetSID().toString()] = layer._SaveToJson();
|
|
return o
|
|
}
|
|
_LoadFromJson(o) {
|
|
this._scrollX = o["sx"];
|
|
this._scrollY = o["sy"];
|
|
this._scale = o["s"];
|
|
this._angle = o["a"];
|
|
this._width = o["w"];
|
|
this._height = o["h"];
|
|
this._isFirstVisit = !!o["fv"];
|
|
this._persistData = o["persist"];
|
|
this._effectList.LoadFromJson(o["fx"]);
|
|
for (const [sidStr,data] of Object.entries(o["layers"])) {
|
|
const sid = parseInt(sidStr, 10);
|
|
const layer = this.GetLayerBySID(sid);
|
|
if (!layer)
|
|
continue;
|
|
layer._LoadFromJson(data)
|
|
}
|
|
}
|
|
GetILayout() {
|
|
return this._iLayout
|
|
}
|
|
UserScriptDispatcher() {
|
|
return this._userScriptDispatcher
|
|
}
|
|
DispatchUserScriptEvent(e) {
|
|
e.layout = this.GetILayout();
|
|
const runtime = this._runtime;
|
|
const shouldTime = runtime.IsDebug() && !runtime.GetEventSheetManager().IsInEventEngine();
|
|
if (shouldTime)
|
|
C3Debugger.StartMeasuringScriptTime();
|
|
this._userScriptDispatcher.dispatchEvent(e);
|
|
if (shouldTime)
|
|
C3Debugger.AddScriptTime()
|
|
}
|
|
DispatchUserScriptEventAsyncWait(e) {
|
|
e.layout = this.GetILayout();
|
|
return this._userScriptDispatcher.dispatchEventAndWaitAsync(e)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.LayoutManager = class LayoutManager extends C3.DefendedBase {
|
|
constructor(runtime) {
|
|
super();
|
|
this._runtime = runtime;
|
|
this._allLayouts = [];
|
|
this._layoutsByName = new Map;
|
|
this._layoutsBySid = new Map;
|
|
this._mainRunningLayout = null;
|
|
this._runningSubLayouts = [];
|
|
this._firstLayout = null;
|
|
this._isEndingLayout = 0;
|
|
this._pendingChangeLayout = null
|
|
}
|
|
Release() {
|
|
this._runtime = null;
|
|
this._mainRunningLayout = null;
|
|
this._firstLayout = null;
|
|
this._pendingChangeLayout = null;
|
|
C3.clearArray(this._allLayouts);
|
|
this._layoutsByName.clear();
|
|
this._layoutsBySid.clear();
|
|
C3.clearArray(this._runningSubLayouts)
|
|
}
|
|
Create(layoutData) {
|
|
const layout = C3.New(C3.Layout, this, this._allLayouts.length, layoutData);
|
|
this._allLayouts.push(layout);
|
|
this._layoutsByName.set(layout.GetName().toLowerCase(), layout);
|
|
this._layoutsBySid.set(layout.GetSID(), layout)
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
SetFirstLayout(layout) {
|
|
this._firstLayout = layout
|
|
}
|
|
GetFirstLayout() {
|
|
if (this._firstLayout)
|
|
return this._firstLayout;
|
|
if (this._allLayouts.length)
|
|
return this._allLayouts[0];
|
|
throw new Error("no first layout");
|
|
}
|
|
GetLayoutByName(name) {
|
|
return this._layoutsByName.get(name.toLowerCase()) || null
|
|
}
|
|
GetLayoutBySID(sid) {
|
|
return this._layoutsBySid.get(sid) || null
|
|
}
|
|
GetLayoutByIndex(index) {
|
|
index = C3.clamp(Math.floor(index), 0, this._allLayouts.length - 1);
|
|
return this._allLayouts[index]
|
|
}
|
|
GetLayout(p) {
|
|
if (typeof p === "number")
|
|
return this.GetLayoutByIndex(p);
|
|
else
|
|
return this.GetLayoutByName(p.toString())
|
|
}
|
|
GetAllLayouts() {
|
|
return this._allLayouts
|
|
}
|
|
_SetMainRunningLayout(layout) {
|
|
this._mainRunningLayout = layout
|
|
}
|
|
GetMainRunningLayout() {
|
|
return this._mainRunningLayout
|
|
}
|
|
_AddRunningSubLayout(layout) {
|
|
if (this._runningSubLayouts.includes(layout))
|
|
throw new Error("layout already running");
|
|
this._runningSubLayouts.push(layout)
|
|
}
|
|
_RemoveRunningSubLayout(layout) {
|
|
const i = this._runningSubLayouts.indexOf(layout);
|
|
if (i === -1)
|
|
throw new Error("layout not running");
|
|
this._runningSubLayouts.splice(i, 1)
|
|
}
|
|
*runningLayouts() {
|
|
if (this._mainRunningLayout)
|
|
yield this._mainRunningLayout;
|
|
if (this._runningSubLayouts.length)
|
|
yield*this._runningSubLayouts
|
|
}
|
|
IsLayoutRunning(layout) {
|
|
return this._mainRunningLayout === layout || this._runningSubLayouts.includes(layout)
|
|
}
|
|
SetIsEndingLayout(e) {
|
|
if (e)
|
|
this._isEndingLayout++;
|
|
else {
|
|
if (this._isEndingLayout <= 0)
|
|
throw new Error("already unset");
|
|
this._isEndingLayout--
|
|
}
|
|
}
|
|
IsEndingLayout() {
|
|
return this._isEndingLayout > 0
|
|
}
|
|
ChangeMainLayout(layout) {
|
|
this._pendingChangeLayout = layout
|
|
}
|
|
ClearPendingChangeLayout() {
|
|
this._pendingChangeLayout = null
|
|
}
|
|
IsPendingChangeMainLayout() {
|
|
return !!this._pendingChangeLayout
|
|
}
|
|
GetPendingChangeMainLayout() {
|
|
return this._pendingChangeLayout
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
class RenderEffectChainState {
|
|
constructor() {
|
|
this.renderer = null;
|
|
this.runtime = null;
|
|
this.drawWidth = 0;
|
|
this.drawHeight = 0;
|
|
this.surfaceWidth = 0;
|
|
this.surfaceHeight = 0;
|
|
this.layoutRect = new C3.Rect;
|
|
this.rcTexBounce = new C3.Rect;
|
|
this.rcTexDest = new C3.Rect;
|
|
this.rcTexOrigin = new C3.Rect;
|
|
this.screenRect = new C3.Rect;
|
|
this.clearRect = new C3.Rect;
|
|
this.srcRect = new C3.Rect;
|
|
this.fxTex = [null, null];
|
|
this.fxIndex = 0;
|
|
this.otherFxIndex = 1;
|
|
this.boxExtendHorizontal = 0;
|
|
this.boxExtendVertical = 0;
|
|
this.layerScale = 0;
|
|
this.layerAngle = 0;
|
|
this.layout = null;
|
|
this.layer = null;
|
|
this.inst = null;
|
|
this.wi = null;
|
|
this.renderTarget = null;
|
|
this.preDraw = false;
|
|
this.postDraw = false;
|
|
this.didChangeTransform = false;
|
|
this.opts = null
|
|
}
|
|
Clear() {
|
|
this.renderer = null;
|
|
this.runtime = null;
|
|
this.layout = null;
|
|
this.layer = null;
|
|
this.inst = null;
|
|
this.wi = null;
|
|
this.renderTarget = null;
|
|
this.opts = null
|
|
}
|
|
ShouldPreDraw(firstEffectType) {
|
|
const shaderProgram = firstEffectType.GetShaderProgram();
|
|
if (shaderProgram.MustPreDraw())
|
|
return true;
|
|
if (this.inst)
|
|
return shaderProgram.UsesDest() && (this.wi.GetAngle() !== 0 || this.wi.GetWidth() < 0 || this.wi.GetHeight() < 0) || this.boxExtendHorizontal !== 0 || this.boxExtendVertical !== 0 || !this.wi.HasDefaultColor() || this.inst.MustPreDraw();
|
|
else if (this.layer)
|
|
return !this.layer.HasDefaultColor()
|
|
}
|
|
ShouldPostDraw(lastEffectType) {
|
|
const shaderProgram = lastEffectType.GetShaderProgram();
|
|
return shaderProgram.UsesDest() || shaderProgram.UsesCrossSampling() || this.layout && this.runtime.GetCanvasManager().GetCurrentFullscreenScalingQuality() === "low"
|
|
}
|
|
GetEffectRenderTarget(i) {
|
|
if (i !== 0 && i !== 1)
|
|
throw new Error("invalid effect target");
|
|
const fxTex = this.fxTex;
|
|
if (!fxTex[i]) {
|
|
const runtime = this.runtime;
|
|
const canvasManager = runtime.GetCanvasManager();
|
|
const opts = {
|
|
sampling: runtime.GetSampling()
|
|
};
|
|
if (canvasManager.GetCurrentFullscreenScalingQuality() === "low") {
|
|
opts.width = canvasManager.GetDrawWidth();
|
|
opts.height = canvasManager.GetDrawHeight()
|
|
}
|
|
fxTex[i] = canvasManager.GetAdditionalRenderTarget(opts)
|
|
}
|
|
return fxTex[i]
|
|
}
|
|
ReleaseEffectRenderTargets() {
|
|
const fxTex = this.fxTex;
|
|
const canvasManager = this.runtime.GetCanvasManager();
|
|
if (fxTex[0]) {
|
|
canvasManager.ReleaseAdditionalRenderTarget(fxTex[0]);
|
|
fxTex[0] = null
|
|
}
|
|
if (fxTex[1]) {
|
|
canvasManager.ReleaseAdditionalRenderTarget(fxTex[1]);
|
|
fxTex[1] = null
|
|
}
|
|
}
|
|
}
|
|
const ctxStack = [];
|
|
let ctxPtr = 0;
|
|
function AllocRenderEffectChainState() {
|
|
if (ctxPtr === ctxStack.length)
|
|
ctxStack.push(new RenderEffectChainState);
|
|
return ctxStack[ctxPtr++]
|
|
}
|
|
function ReleaseRenderEffectChainState(ctx) {
|
|
ctx.ReleaseEffectRenderTargets();
|
|
ctx.Clear();
|
|
ctxPtr--
|
|
}
|
|
const tempQuad = new C3.Quad;
|
|
let isDebug = false;
|
|
let isDebugFrame = false;
|
|
async function DebugLogRenderTargetContents(msg, renderer, renderTarget) {
|
|
const blob = await C3.Gfx.WebGLRenderTarget.DebugReadPixelsToBlob(renderer, renderTarget);
|
|
const blobUrl = URL.createObjectURL(blob);
|
|
console.log("[FX] " + msg + " " + (renderTarget ? "" : " [to display]") + ": ", blobUrl)
|
|
}
|
|
C3.RenderEffectChain = function RenderEffectChain(renderer, runtime, effectsObject, renderTarget_, activeEffectTypes, opts_) {
|
|
const ctx = AllocRenderEffectChainState();
|
|
ctx.renderer = renderer;
|
|
ctx.runtime = runtime;
|
|
if (effectsObject instanceof C3.Instance) {
|
|
ctx.inst = effectsObject;
|
|
ctx.wi = ctx.inst.GetWorldInfo()
|
|
} else if (effectsObject instanceof C3.Layer)
|
|
ctx.layer = effectsObject;
|
|
else if (effectsObject instanceof C3.Layout)
|
|
ctx.layout = effectsObject;
|
|
else
|
|
throw new Error("invalid effects object");
|
|
const canvasManager = runtime.GetCanvasManager();
|
|
ctx.renderTarget = renderTarget_;
|
|
ctx.drawWidth = canvasManager.GetDrawWidth();
|
|
ctx.drawHeight = canvasManager.GetDrawHeight();
|
|
ctx.surfaceWidth = ctx.drawWidth;
|
|
ctx.surfaceHeight = ctx.drawHeight;
|
|
ctx.fxIndex = 0;
|
|
ctx.otherFxIndex = 1;
|
|
ctx.boxExtendHorizontal = 0;
|
|
ctx.boxExtendVertical = 0;
|
|
ctx.screenRect.set(0, 0, ctx.drawWidth, ctx.drawHeight);
|
|
ctx.clearRect.set(0, 0, ctx.drawWidth, ctx.drawHeight);
|
|
ctx.didChangeTransform = false;
|
|
ctx.opts = opts_;
|
|
if (ctx.inst) {
|
|
const wi = ctx.wi;
|
|
ctx.layerScale = wi.GetLayer().GetRenderScale();
|
|
ctx.layerAngle = wi.GetLayer().GetAngle();
|
|
ctx.layoutRect.copy(wi.GetBoundingBox())
|
|
} else if (ctx.layer) {
|
|
const layer = ctx.layer;
|
|
ctx.layerScale = layer.GetRenderScale();
|
|
ctx.layerAngle = layer.GetAngle();
|
|
ctx.layoutRect.copy(layer.GetViewport())
|
|
} else {
|
|
const layout = ctx.layout;
|
|
ctx.layerScale = layout.GetScale();
|
|
ctx.layerAngle = layout.GetAngle();
|
|
ctx.layoutRect.set(0, 0, ctx.drawWidth, ctx.drawHeight)
|
|
}
|
|
if (ctx.inst)
|
|
GetInstanceBox(ctx, activeEffectTypes);
|
|
else {
|
|
ctx.rcTexBounce.set(0, 0, ctx.drawWidth / ctx.surfaceWidth, ctx.drawHeight / ctx.surfaceHeight);
|
|
ctx.rcTexDest.copy(ctx.rcTexBounce);
|
|
ctx.rcTexOrigin.copy(ctx.rcTexBounce);
|
|
ctx.rcTexBounce.swapTopBottom();
|
|
ctx.rcTexDest.swapTopBottom();
|
|
ctx.rcTexOrigin.swapTopBottom()
|
|
}
|
|
renderer.SetAlphaBlend();
|
|
renderer.ResetColor();
|
|
renderer.SetBaseZ(0);
|
|
renderer.SetCurrentZ(0);
|
|
ctx.preDraw = ctx.ShouldPreDraw(activeEffectTypes[0]);
|
|
if (ctx.preDraw)
|
|
PreDraw(ctx);
|
|
renderer.ResetColor();
|
|
const lastEffectTypeIndex = activeEffectTypes.length - 1;
|
|
ctx.postDraw = ctx.ShouldPostDraw(activeEffectTypes[lastEffectTypeIndex]);
|
|
for (let i = 0, len = activeEffectTypes.length; i < len; ++i) {
|
|
const effectType = activeEffectTypes[i];
|
|
const shaderProgram = effectType.GetShaderProgram();
|
|
renderer.SetProgram(shaderProgram);
|
|
if (shaderProgram.IsAnimated())
|
|
runtime.UpdateRender();
|
|
if (i === 0 && !ctx.preDraw)
|
|
RenderFirstBounce(ctx, effectType);
|
|
else {
|
|
renderer.SetCopyBlend();
|
|
const isLast = i === lastEffectTypeIndex && !ctx.postDraw;
|
|
RenderBounce(ctx, effectType, isLast, i)
|
|
}
|
|
if (ctx.fxIndex === 0) {
|
|
ctx.fxIndex = 1;
|
|
ctx.otherFxIndex = 0
|
|
} else {
|
|
ctx.fxIndex = 0;
|
|
ctx.otherFxIndex = 1
|
|
}
|
|
}
|
|
if (ctx.postDraw)
|
|
PostDraw(ctx, activeEffectTypes);
|
|
const ret = ctx.didChangeTransform;
|
|
ReleaseRenderEffectChainState(ctx);
|
|
isDebugFrame = false;
|
|
return ret
|
|
}
|
|
;
|
|
function GetInstanceBox(ctx, activeEffectTypes) {
|
|
for (let i = 0, len = activeEffectTypes.length; i < len; ++i) {
|
|
const shaderProgram = activeEffectTypes[i].GetShaderProgram();
|
|
ctx.boxExtendHorizontal += shaderProgram.GetBoxExtendHorizontal();
|
|
ctx.boxExtendVertical += shaderProgram.GetBoxExtendVertical()
|
|
}
|
|
const wi = ctx.wi;
|
|
const layer = wi.GetLayer();
|
|
const layerAngle = layer.GetAngle();
|
|
const bbox = wi.GetBoundingBox();
|
|
const z = wi.GetTotalZElevation();
|
|
let[sl,st] = layer.LayerToDrawSurface(bbox.getLeft(), bbox.getTop(), z);
|
|
let[sr,sb] = layer.LayerToDrawSurface(bbox.getRight(), bbox.getBottom(), z);
|
|
if (layerAngle !== 0) {
|
|
const [strx,stry] = layer.LayerToDrawSurface(bbox.getRight(), bbox.getTop(), z);
|
|
const [sblx,sbly] = layer.LayerToDrawSurface(bbox.getLeft(), bbox.getBottom(), z);
|
|
let temp = Math.min(sl, sr, strx, sblx);
|
|
sr = Math.max(sl, sr, strx, sblx);
|
|
sl = temp;
|
|
temp = Math.min(st, sb, stry, sbly);
|
|
sb = Math.max(st, sb, stry, sbly);
|
|
st = temp
|
|
}
|
|
const screenRect = ctx.screenRect;
|
|
const rcTexOrigin = ctx.rcTexOrigin;
|
|
const rcTexDest = ctx.rcTexDest;
|
|
const clearRect = ctx.clearRect;
|
|
const rcTexBounce = ctx.rcTexBounce;
|
|
screenRect.set(sl, st, sr, sb);
|
|
screenRect.shuntY(ctx.drawHeight);
|
|
rcTexOrigin.copy(screenRect);
|
|
rcTexOrigin.divide(ctx.surfaceWidth, ctx.surfaceHeight);
|
|
rcTexOrigin.swapTopBottom();
|
|
screenRect.inflate(ctx.boxExtendHorizontal, ctx.boxExtendVertical);
|
|
rcTexDest.copy(screenRect);
|
|
rcTexDest.divide(ctx.surfaceWidth, ctx.surfaceHeight);
|
|
rcTexDest.swapTopBottom();
|
|
clearRect.copy(screenRect);
|
|
clearRect.roundOuter();
|
|
clearRect.inflate(ctx.boxExtendHorizontal + 1, ctx.boxExtendVertical + 1);
|
|
screenRect.clamp(0, 0, ctx.drawWidth, ctx.drawHeight);
|
|
clearRect.clamp(0, 0, ctx.drawWidth, ctx.drawHeight);
|
|
rcTexBounce.copy(screenRect);
|
|
rcTexBounce.divide(ctx.surfaceWidth, ctx.surfaceHeight);
|
|
rcTexBounce.swapTopBottom()
|
|
}
|
|
function PreDraw(ctx) {
|
|
const renderer = ctx.renderer;
|
|
renderer.SetTextureFillMode();
|
|
const fxTarget = ctx.GetEffectRenderTarget(ctx.fxIndex);
|
|
renderer.SetRenderTarget(fxTarget);
|
|
const opts = ctx.opts;
|
|
if (opts && opts.preTransform)
|
|
opts.preTransform();
|
|
if (isDebug)
|
|
renderer.ClearRgba(1, 0, 0, 1);
|
|
renderer.ClearRect2(ctx.clearRect);
|
|
if (ctx.inst) {
|
|
renderer.SetColor(ctx.wi.GetPremultipliedColor());
|
|
renderer.SetCurrentZ(ctx.wi.GetTotalZElevation());
|
|
ctx.inst.Draw(renderer);
|
|
renderer.SetCurrentZ(0)
|
|
} else {
|
|
const renderSurface = (ctx.layer || ctx.layout).GetRenderTarget();
|
|
if (ctx.layer)
|
|
renderer.SetColor(ctx.layer.GetPremultipliedColor());
|
|
else
|
|
renderer.ResetColor();
|
|
renderer.DrawRenderTarget(renderSurface);
|
|
renderer.InvalidateRenderTarget(renderSurface);
|
|
ctx.runtime.GetCanvasManager().ReleaseAdditionalRenderTarget(renderSurface)
|
|
}
|
|
ctx.rcTexDest.clampFlipped(0, 1, 1, 0);
|
|
ctx.fxIndex = 1;
|
|
ctx.otherFxIndex = 0;
|
|
if (isDebugFrame)
|
|
DebugLogRenderTargetContents("Pre-draw", renderer, fxTarget)
|
|
}
|
|
function RenderFirstBounce(ctx, effectType) {
|
|
const renderer = ctx.renderer;
|
|
const runtime = ctx.runtime;
|
|
const fxTarget = ctx.GetEffectRenderTarget(ctx.fxIndex);
|
|
renderer.SetRenderTarget(fxTarget);
|
|
const opts = ctx.opts;
|
|
if (opts && opts.preTransform)
|
|
opts.preTransform();
|
|
if (isDebug)
|
|
renderer.ClearRgba(1, 0, 0, 1);
|
|
renderer.ClearRect2(ctx.clearRect);
|
|
if (ctx.inst) {
|
|
const [sheetWidth,sheetHeight] = ctx.inst.GetCurrentSurfaceSize();
|
|
const instTexRect = ctx.inst.GetCurrentTexRect();
|
|
if (instTexRect)
|
|
ctx.srcRect.copy(instTexRect);
|
|
else
|
|
ctx.srcRect.set(0, 0, 0, 0);
|
|
const paramArr = ctx.wi.GetInstanceEffectList().GetEffectParametersForIndex(effectType.GetIndex());
|
|
renderer.SetProgramParameters(ctx.renderTarget, ctx.rcTexDest, ctx.srcRect, ctx.srcRect, ctx.layoutRect, 1 / sheetWidth, 1 / sheetHeight, ctx.layerScale, ctx.layerAngle, runtime.GetGameTime(), paramArr);
|
|
renderer.SetCurrentZ(ctx.wi.GetTotalZElevation());
|
|
ctx.inst.Draw(renderer);
|
|
renderer.SetCurrentZ(0);
|
|
ctx.rcTexDest.clampFlipped(0, 1, 1, 0);
|
|
ctx.screenRect.shuntY(ctx.drawHeight);
|
|
if (isDebugFrame)
|
|
DebugLogRenderTargetContents("First bounce", renderer, fxTarget)
|
|
} else {
|
|
const paramArr = (ctx.layer || ctx.layout).GetEffectList().GetEffectParametersForIndex(effectType.GetIndex());
|
|
renderer.SetProgramParameters(ctx.renderTarget, ctx.rcTexDest, ctx.rcTexBounce, ctx.rcTexOrigin, ctx.layoutRect, 1 / ctx.drawWidth, 1 / ctx.drawHeight, ctx.layerScale, ctx.layerAngle, runtime.GetGameTime(), paramArr);
|
|
const renderSurface = (ctx.layer || ctx.layout).GetRenderTarget();
|
|
if (isDebugFrame)
|
|
DebugLogRenderTargetContents("Layer target", renderer, renderSurface);
|
|
renderer.DrawRenderTarget(renderSurface);
|
|
renderer.InvalidateRenderTarget(renderSurface);
|
|
runtime.GetCanvasManager().ReleaseAdditionalRenderTarget(renderSurface);
|
|
if (isDebugFrame)
|
|
DebugLogRenderTargetContents("First bounce", renderer, fxTarget)
|
|
}
|
|
}
|
|
function RenderBounce(ctx, effectType, isLast, i) {
|
|
const renderer = ctx.renderer;
|
|
const runtime = ctx.runtime;
|
|
let fxTarget;
|
|
let paramArr;
|
|
if (i === 0 && ctx.preDraw && ctx.inst)
|
|
ctx.screenRect.shuntY(ctx.drawHeight);
|
|
if (isLast) {
|
|
if (ctx.inst)
|
|
renderer.SetBlendMode(ctx.wi.GetBlendMode());
|
|
else if (ctx.layer)
|
|
renderer.SetBlendMode(ctx.layer.GetBlendMode());
|
|
fxTarget = ctx.renderTarget;
|
|
renderer.SetRenderTarget(fxTarget)
|
|
} else {
|
|
fxTarget = ctx.GetEffectRenderTarget(ctx.fxIndex);
|
|
renderer.SetRenderTarget(fxTarget);
|
|
if (isDebug)
|
|
renderer.ClearRgba(1, 0, 0, 1);
|
|
renderer.ClearRect2(ctx.clearRect)
|
|
}
|
|
if (ctx.inst)
|
|
paramArr = ctx.wi.GetInstanceEffectList().GetEffectParametersForIndex(effectType.GetIndex());
|
|
else
|
|
paramArr = (ctx.layer || ctx.layout).GetEffectList().GetEffectParametersForIndex(effectType.GetIndex());
|
|
renderer.SetProgramParameters(ctx.renderTarget, ctx.rcTexDest, ctx.rcTexBounce, ctx.rcTexOrigin, ctx.layoutRect, 1 / ctx.surfaceWidth, 1 / ctx.surfaceHeight, ctx.layerScale, ctx.layerAngle, runtime.GetGameTime(), paramArr);
|
|
const srcTarget = ctx.GetEffectRenderTarget(ctx.otherFxIndex);
|
|
renderer.SetTexture(srcTarget.GetTexture());
|
|
runtime.GetCanvasManager().SetDeviceTransform(renderer);
|
|
ctx.didChangeTransform = true;
|
|
tempQuad.setFromRect(ctx.screenRect);
|
|
renderer.Quad3(tempQuad, ctx.rcTexBounce);
|
|
if (!ctx.inst)
|
|
renderer.InvalidateRenderTarget(srcTarget);
|
|
if (isDebugFrame)
|
|
DebugLogRenderTargetContents("Bounce " + i, renderer, fxTarget)
|
|
}
|
|
function PostDraw(ctx, activeEffectTypes) {
|
|
const renderer = ctx.renderer;
|
|
if (ctx.layout) {
|
|
renderer.SetTextureFillMode();
|
|
renderer.SetRenderTarget(ctx.renderTarget);
|
|
const srcTarget = ctx.GetEffectRenderTarget(ctx.otherFxIndex);
|
|
renderer.CopyRenderTarget(srcTarget);
|
|
renderer.InvalidateRenderTarget(srcTarget);
|
|
return
|
|
}
|
|
const canvasManager = ctx.runtime.GetCanvasManager();
|
|
if (canvasManager.GetCurrentFullscreenScalingQuality() === "low") {
|
|
renderer.SetTextureFillMode();
|
|
canvasManager.SetDeviceTransform(renderer, canvasManager.GetDrawWidth(), canvasManager.GetDrawHeight());
|
|
ctx.didChangeTransform = true
|
|
} else
|
|
renderer.SetDeviceTransformTextureFillMode();
|
|
if (ctx.inst)
|
|
renderer.SetBlendMode(ctx.wi.GetBlendMode());
|
|
else if (ctx.layer)
|
|
renderer.SetBlendMode(ctx.layer.GetBlendMode());
|
|
renderer.SetRenderTarget(ctx.renderTarget);
|
|
const srcTarget = ctx.GetEffectRenderTarget(ctx.otherFxIndex);
|
|
renderer.SetTexture(srcTarget.GetTexture());
|
|
tempQuad.setFromRect(ctx.screenRect);
|
|
renderer.Quad3(tempQuad, ctx.rcTexBounce);
|
|
if (!ctx.inst)
|
|
renderer.InvalidateRenderTarget(srcTarget);
|
|
if (isDebugFrame)
|
|
DebugLogRenderTargetContents("Post-draw", renderer, ctx.renderTarget)
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const NAMES_REGEXP = new RegExp("<(.+?)>","g");
|
|
C3.TimelineManager = class TimelineManager extends C3.DefendedBase {
|
|
constructor(runtime) {
|
|
super();
|
|
this._runtime = runtime;
|
|
this._timelineDataManager = C3.New(C3.TimelineDataManager);
|
|
this._pluginInstance = null;
|
|
this._timelines = [];
|
|
this._timelinesByName = new Map;
|
|
this._objectClassToTimelineMap = new Map;
|
|
this._timelinesCreatedByTemplate = new Map;
|
|
this._scheduledTimelines = [];
|
|
this._playingTimelines = [];
|
|
this._hasRuntimeListeners = false;
|
|
this._changingLayout = false;
|
|
this._isTickingTimelines = false;
|
|
this._tickFunc = ()=>this._OnTick();
|
|
this._tick2Func = ()=>this._OnTick2();
|
|
this._beforeLayoutChange = ()=>this._OnBeforeChangeLayout();
|
|
this._layoutChange = ()=>this._OnAfterChangeLayout();
|
|
this._instanceDestroy = e=>this._OnInstanceDestroy(e.instance);
|
|
this._afterLoad = e=>this._OnAfterLoad();
|
|
this._destroyedWhileLoadingState = []
|
|
}
|
|
Release() {
|
|
this.RemoveRuntimeListeners();
|
|
this._tickFunc = null;
|
|
this._tick2Func = null;
|
|
this._beforeLayoutChange = null;
|
|
this._layoutChange = null;
|
|
this._instanceDestroy = null;
|
|
this._afterLoad = null;
|
|
for (const timeline of this._timelines) {
|
|
timeline.Stop();
|
|
timeline.Release()
|
|
}
|
|
C3.clearArray(this._timelines);
|
|
this._timelines = null;
|
|
this._timelineDataManager.Release();
|
|
this._timelineDataManager = null;
|
|
C3.clearArray(this._scheduledTimelines);
|
|
this._scheduledTimelines = null;
|
|
C3.clearArray(this._playingTimelines);
|
|
this._playingTimelines = null;
|
|
this._timelinesByName.clear();
|
|
this._timelinesByName = null;
|
|
this._objectClassToTimelineMap.clear();
|
|
this._objectClassToTimelineMap = null;
|
|
this._timelinesCreatedByTemplate.clear();
|
|
this._timelinesCreatedByTemplate = null;
|
|
C3.clearArray(this._destroyedWhileLoadingState);
|
|
this._destroyedWhileLoadingState = null;
|
|
this._runtime = null
|
|
}
|
|
AddRuntimeListeners() {
|
|
const dispatcher = this._runtime.Dispatcher();
|
|
dispatcher.addEventListener("pretick", this._tickFunc);
|
|
dispatcher.addEventListener("tick2", this._tick2Func);
|
|
dispatcher.addEventListener("beforelayoutchange", this._beforeLayoutChange);
|
|
dispatcher.addEventListener("layoutchange", this._layoutChange);
|
|
dispatcher.addEventListener("instancedestroy", this._instanceDestroy);
|
|
dispatcher.addEventListener("afterload", this._afterLoad)
|
|
}
|
|
RemoveRuntimeListeners() {
|
|
const dispatcher = this._runtime.Dispatcher();
|
|
dispatcher.removeEventListener("pretick", this._tickFunc);
|
|
dispatcher.removeEventListener("tick2", this._tick2Func);
|
|
dispatcher.removeEventListener("beforelayoutchange", this._beforeLayoutChange);
|
|
dispatcher.removeEventListener("layoutchange", this._layoutChange);
|
|
dispatcher.removeEventListener("instancedestroy", this._instanceDestroy);
|
|
dispatcher.removeEventListener("afterload", this._afterLoad)
|
|
}
|
|
Create(timelineData) {
|
|
this._timelineDataManager.Add(timelineData);
|
|
const timeline = C3.TimelineState.CreateInitial(timelineData, this);
|
|
this.Add(timeline);
|
|
this.SetTimelineObjectClassesToMap(timeline);
|
|
this._timelinesCreatedByTemplate.set(timeline.GetName(), 0)
|
|
}
|
|
CreateFromTemplate(template) {
|
|
const timelineDataManager = this.GetTimelineDataManager();
|
|
const templateName = template.GetTemplateName();
|
|
const timelineDataItem = timelineDataManager.Get(templateName);
|
|
const timeline = C3.TimelineState.CreateFromTemplate(`${templateName}:${this._timelinesCreatedByTemplate.get(templateName)}`, timelineDataItem, this);
|
|
this._IncreaseTemplateTimelinesCount(templateName);
|
|
this.Add(timeline);
|
|
return timeline
|
|
}
|
|
_IncreaseTemplateTimelinesCount(templateName) {
|
|
this._timelinesCreatedByTemplate.set(templateName, this._timelinesCreatedByTemplate.get(templateName) + 1)
|
|
}
|
|
_SetCreatedTemplateTimelinesCount() {
|
|
for (const timeline of this._timelines) {
|
|
if (timeline.IsTemplate())
|
|
continue;
|
|
const templateName = timeline.GetTemplateName();
|
|
this._IncreaseTemplateTimelinesCount(templateName)
|
|
}
|
|
}
|
|
_ClearCreatedTemplateTimelinesCount() {
|
|
for (const templateName of this._timelinesCreatedByTemplate.keys())
|
|
this._timelinesCreatedByTemplate.set(templateName, 0)
|
|
}
|
|
Add(timeline) {
|
|
this._timelines.push(timeline);
|
|
this._timelinesByName.set(timeline.GetName().toLowerCase(), timeline)
|
|
}
|
|
Remove(timeline) {
|
|
if (timeline.IsTemplate())
|
|
return;
|
|
C3.arrayFindRemove(this._timelines, timeline);
|
|
C3.arrayFindRemove(this._scheduledTimelines, timeline);
|
|
C3.arrayFindRemove(this._playingTimelines, timeline);
|
|
this._timelinesByName.delete(timeline.GetName().toLowerCase());
|
|
this.RemoveTimelineFromObjectClassMap(timeline);
|
|
if (!timeline.IsReleased())
|
|
timeline.Release()
|
|
}
|
|
Trigger(method) {
|
|
this._runtime.Trigger(method, this._pluginInstance, null)
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetTimelineDataManager() {
|
|
return this._timelineDataManager
|
|
}
|
|
SetPluginInstance(inst) {
|
|
this._pluginInstance = inst
|
|
}
|
|
GetPluginInstance() {
|
|
return this._pluginInstance
|
|
}
|
|
*GetTimelines() {
|
|
for (const timeline of this._timelines)
|
|
yield timeline
|
|
}
|
|
SetTimelineObjectClassToMap(objectClass, timeline) {
|
|
if (!this._objectClassToTimelineMap.has(objectClass))
|
|
this._objectClassToTimelineMap.set(objectClass, new Set);
|
|
this._objectClassToTimelineMap.get(objectClass).add(timeline)
|
|
}
|
|
SetTimelineObjectClassesToMap(timeline) {
|
|
for (const objectClass of timeline.GetObjectClasses())
|
|
this.SetTimelineObjectClassToMap(objectClass, timeline)
|
|
}
|
|
RemoveTimelineFromObjectClassMap(timeline) {
|
|
for (const [objectClass,timelines] of this._objectClassToTimelineMap.entries())
|
|
if (timelines.has(timeline)) {
|
|
timelines.delete(timeline);
|
|
if (timelines.size === 0)
|
|
this._objectClassToTimelineMap.delete(objectClass)
|
|
}
|
|
}
|
|
GetTimelinesForObjectClass(objectClass) {
|
|
if (!this._objectClassToTimelineMap.has(objectClass))
|
|
return;
|
|
return this._objectClassToTimelineMap.get(objectClass)
|
|
}
|
|
GetTimelineOfTemplateForInstances(templateTimeline, instancesObject) {
|
|
if (!instancesObject)
|
|
return;
|
|
for (const timeline of this._timelines) {
|
|
const found = instancesObject.every(io=>{
|
|
return timeline.HasTrackInstance(io.instance, io.trackId)
|
|
}
|
|
);
|
|
if (found)
|
|
if (timeline.GetName().includes(templateTimeline.GetName()))
|
|
return timeline
|
|
}
|
|
}
|
|
GetTimelineByName(name) {
|
|
return this._timelinesByName.get(name.toLowerCase()) || null
|
|
}
|
|
GetScheduledOrPlayingTimelineByName(name) {
|
|
for (const timeline of this._scheduledTimelines)
|
|
if (timeline.GetName() === name)
|
|
return timeline;
|
|
for (const timeline of this._playingTimelines)
|
|
if (timeline.GetName() === name)
|
|
return timeline;
|
|
return null
|
|
}
|
|
*GetTimelinesByName(name) {
|
|
if (NAMES_REGEXP.test(name)) {
|
|
NAMES_REGEXP.lastIndex = 0;
|
|
let match;
|
|
const uniqueNames = new Set;
|
|
do {
|
|
match = NAMES_REGEXP.exec(name);
|
|
if (match) {
|
|
const names = match[1].split(",");
|
|
for (const name of names)
|
|
uniqueNames.add(name)
|
|
}
|
|
} while (match);
|
|
for (const name of uniqueNames.values()) {
|
|
const timeline = this.GetTimelineByName(name);
|
|
if (timeline)
|
|
yield timeline
|
|
}
|
|
uniqueNames.clear()
|
|
} else {
|
|
const timeline = this.GetTimelineByName(name);
|
|
if (timeline)
|
|
yield timeline
|
|
}
|
|
}
|
|
*GetTimelinesByTags(tags) {
|
|
for (const timeline of this._timelines)
|
|
if (timeline.HasTags(tags))
|
|
yield timeline
|
|
}
|
|
AddScheduledTimeline(timeline) {
|
|
if (!this._scheduledTimelines.includes(timeline))
|
|
this._scheduledTimelines.push(timeline);
|
|
this._MaybeEnableRuntimeListeners()
|
|
}
|
|
RemovePlayingTimeline(timeline) {
|
|
C3.arrayFindRemove(this._playingTimelines, timeline);
|
|
this._MaybeDisableRuntimeListeners()
|
|
}
|
|
ScheduleTimeline(timeline) {
|
|
if (this._playingTimelines.includes(timeline)) {
|
|
timeline.SetPlaying(true);
|
|
timeline.SetScheduled(false);
|
|
timeline.SetMarkedForRemoval(false)
|
|
} else {
|
|
timeline.SetPlaying(false);
|
|
timeline.SetScheduled(true);
|
|
timeline.SetMarkedForRemoval(false);
|
|
if (!this._scheduledTimelines.includes(timeline))
|
|
this._scheduledTimelines.push(timeline)
|
|
}
|
|
this._MaybeEnableRuntimeListeners()
|
|
}
|
|
DeScheduleTimeline(timeline) {
|
|
timeline.SetPlaying(false);
|
|
timeline.SetScheduled(false);
|
|
timeline.ResolvePlayPromise();
|
|
C3.arrayFindRemove(this._scheduledTimelines, timeline);
|
|
this._MaybeDisableRuntimeListeners()
|
|
}
|
|
CompleteTimeline(timeline) {
|
|
timeline.SetPlaying(false);
|
|
timeline.SetScheduled(false);
|
|
timeline.SetMarkedForRemoval(true)
|
|
}
|
|
CompleteTimelineAndResolve(timeline) {
|
|
this.CompleteTimeline(timeline);
|
|
timeline.ResolvePlayPromise()
|
|
}
|
|
_OnTick() {
|
|
if (this.GetRuntime().IsLoadingState())
|
|
return;
|
|
if (!this._hasRuntimeListeners)
|
|
return;
|
|
if (this._changingLayout)
|
|
return;
|
|
let renderChange = false;
|
|
this._isTickingTimelines = true;
|
|
while (this._scheduledTimelines.length) {
|
|
const timeline = this._scheduledTimelines.pop();
|
|
timeline.SetInitialState();
|
|
this._playingTimelines.push(timeline)
|
|
}
|
|
const dt = this._runtime.GetDt();
|
|
const ts = this._runtime.GetTimeScale();
|
|
for (const t of this._playingTimelines) {
|
|
if (t.IsMarkedForRemoval())
|
|
continue;
|
|
const change = t.Tick(dt, ts);
|
|
if (!renderChange && change)
|
|
renderChange = true
|
|
}
|
|
this._isTickingTimelines = false;
|
|
if (renderChange)
|
|
this.GetRuntime().UpdateRender()
|
|
}
|
|
_OnTick2() {
|
|
if (this.GetRuntime().IsLoadingState())
|
|
return;
|
|
if (!this._hasRuntimeListeners)
|
|
return;
|
|
if (this._changingLayout)
|
|
return;
|
|
let timelinesToRemove;
|
|
for (const t of this._playingTimelines) {
|
|
if (!t.IsMarkedForRemoval())
|
|
continue;
|
|
if (!timelinesToRemove)
|
|
timelinesToRemove = new Set;
|
|
this._MaybeExecuteTimelineFinishTriggers(t);
|
|
timelinesToRemove.add(t)
|
|
}
|
|
if (timelinesToRemove)
|
|
C3.arrayRemoveAllInSet(this._playingTimelines, timelinesToRemove);
|
|
this._MaybeDisableRuntimeListeners()
|
|
}
|
|
_MaybeExecuteTimelineFinishTriggers(timeline) {
|
|
if (timeline.IsReleased())
|
|
return;
|
|
if (!timeline.HasValidTracks())
|
|
return;
|
|
if (timeline.IsComplete() && timeline.InitialStateSet())
|
|
timeline.FinishTriggers()
|
|
}
|
|
_MaybeEnableRuntimeListeners() {
|
|
if (this._hasRuntimeListeners)
|
|
return;
|
|
this._hasRuntimeListeners = true
|
|
}
|
|
_MaybeDisableRuntimeListeners() {
|
|
if (this._playingTimelines.length)
|
|
return;
|
|
if (this._scheduledTimelines.length)
|
|
return;
|
|
if (this._isTickingTimelines)
|
|
return;
|
|
this._hasRuntimeListeners = false
|
|
}
|
|
_OnBeforeChangeLayout() {
|
|
this._changingLayout = true;
|
|
while (this._scheduledTimelines.length)
|
|
this.DeScheduleTimeline(this._scheduledTimelines.pop());
|
|
const timelinesToRemove = new Set;
|
|
for (const t of this._playingTimelines) {
|
|
const remove = t._OnBeforeChangeLayout();
|
|
if (remove)
|
|
timelinesToRemove.add(t)
|
|
}
|
|
C3.arrayRemoveAllInSet(this._playingTimelines, timelinesToRemove);
|
|
this._MaybeDisableRuntimeListeners();
|
|
for (const timeline of this._timelines)
|
|
timeline.CleanCaches()
|
|
}
|
|
_OnAfterChangeLayout() {
|
|
this._changingLayout = false
|
|
}
|
|
_OnInstanceDestroy(instance) {
|
|
const objectClass = instance.GetObjectClass();
|
|
const timelines = this.GetTimelinesForObjectClass(objectClass);
|
|
if (!timelines)
|
|
return;
|
|
if (this._runtime.IsLoadingState())
|
|
this._destroyedWhileLoadingState.push(instance);
|
|
else
|
|
for (const timeline of timelines) {
|
|
if (timeline.IsTemplate())
|
|
continue;
|
|
if (timeline.IsReleased()) {
|
|
this.Remove(timeline);
|
|
continue
|
|
}
|
|
if (!timeline.HasValidTracks()) {
|
|
this._MaybeExecuteTimelineFinishTriggers(timeline);
|
|
this.Remove(timeline)
|
|
}
|
|
}
|
|
}
|
|
_OnAfterLoad() {
|
|
for (const destroyedInstance of this._destroyedWhileLoadingState)
|
|
this._OnInstanceDestroy(destroyedInstance);
|
|
C3.clearArray(this._destroyedWhileLoadingState)
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"timelinesJson": this._SaveTimelinesToJson(),
|
|
"scheduledTimelinesJson": this._SaveScheduledTimelinesToJson(),
|
|
"playingTimelinesJson": this._SavePlayingTimelinesToJson(),
|
|
"hasRuntimeListeners": this._hasRuntimeListeners,
|
|
"changingLayout": this._changingLayout,
|
|
"isTickingTimelines": this._isTickingTimelines
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this._ClearCreatedTemplateTimelinesCount();
|
|
this._LoadTimelinesFromJson(o["timelinesJson"]);
|
|
this._LoadScheduledTimelinesFromJson(o["scheduledTimelinesJson"]);
|
|
this._LoadPlayingTimelinesFromJson(o["playingTimelinesJson"]);
|
|
this._hasRuntimeListeners = !o["hasRuntimeListeners"];
|
|
this._changingLayout = !!o["changingLayout"];
|
|
this._isTickingTimelines = !!o["isTickingTimelines"];
|
|
this._SetCreatedTemplateTimelinesCount();
|
|
this._MaybeEnableRuntimeListeners();
|
|
this._MaybeDisableRuntimeListeners()
|
|
}
|
|
_SaveTimelinesToJson() {
|
|
return this._timelines.map(timelineState=>timelineState._SaveToJson())
|
|
}
|
|
_LoadTimelinesFromJson(timelinesJson) {
|
|
for (const timelineJson of timelinesJson) {
|
|
let timeline = this.GetTimelineByName(timelineJson["name"]);
|
|
if (timeline)
|
|
timeline._LoadFromJson(timelineJson);
|
|
else {
|
|
const templateName = this._GetTemplateNameFromJson(timelineJson);
|
|
if (!templateName)
|
|
continue;
|
|
const templateTimeline = this.GetTimelineByName(templateName);
|
|
timeline = this.CreateFromTemplate(templateTimeline);
|
|
timeline._LoadFromJson(timelineJson)
|
|
}
|
|
if (!timeline.HasTracks())
|
|
this.Remove(timeline)
|
|
}
|
|
}
|
|
_GetTemplateNameFromJson(timelineJson) {
|
|
const name = timelineJson["name"];
|
|
const nameParts = name.split(":");
|
|
if (!nameParts || nameParts.length !== 2)
|
|
return null;
|
|
return nameParts[0]
|
|
}
|
|
_SaveScheduledTimelinesToJson() {
|
|
return this._SaveTimelines(this._scheduledTimelines)
|
|
}
|
|
_LoadScheduledTimelinesFromJson(scheduledTimelinesJson) {
|
|
this._LoadTimelines(scheduledTimelinesJson, this._scheduledTimelines)
|
|
}
|
|
_SavePlayingTimelinesToJson() {
|
|
return this._SaveTimelines(this._playingTimelines)
|
|
}
|
|
_LoadPlayingTimelinesFromJson(playingTimelinesJson) {
|
|
this._LoadTimelines(playingTimelinesJson, this._playingTimelines)
|
|
}
|
|
_IsTimelineInJson(timeline, json) {
|
|
for (const name of json)
|
|
if (name === timeline.GetName())
|
|
return true;
|
|
return false
|
|
}
|
|
_SaveTimelines(collection) {
|
|
return collection.map(t=>t.GetName())
|
|
}
|
|
_LoadTimelines(timelinesJson, collection) {
|
|
const timelinesToRemove = new Set;
|
|
for (const timeline of collection)
|
|
if (!this._IsTimelineInJson(timeline, timelinesJson))
|
|
timelinesToRemove.add(timeline);
|
|
C3.arrayRemoveAllInSet(collection, timelinesToRemove);
|
|
const ff = tn=>t=>t.GetName() === tn;
|
|
for (const name of timelinesJson) {
|
|
const timeline = this.GetTimelineByName(name);
|
|
if (timeline) {
|
|
const t = collection.find(ff(name));
|
|
if (!t)
|
|
collection.push(timeline)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const PING_PONG_BEGIN = 0;
|
|
const PING_PONG_END = 1;
|
|
C3.TimelineState = class Timeline extends C3.DefendedBase {
|
|
constructor(name, timelineDataItem, timelineManager) {
|
|
super();
|
|
this._runtime = timelineManager.GetRuntime();
|
|
this._timelineManager = timelineManager;
|
|
this._timelineDataItem = timelineDataItem;
|
|
this._name = name;
|
|
this._tracks = [];
|
|
for (const trackDataItem of this._timelineDataItem.GetTrackData().trackDataItems())
|
|
this._tracks.push(C3.TrackState.Create(this, trackDataItem));
|
|
this._playPromise = null;
|
|
this._playResolve = null;
|
|
this._playheadTime = C3.New(C3.KahanSum);
|
|
this._playheadTime.Set(0);
|
|
this._playbackRate = 1;
|
|
this._pingPongState = PING_PONG_BEGIN;
|
|
this._currentRepeatCount = 1;
|
|
this._isPlaying = false;
|
|
this._isScheduled = false;
|
|
this._initialStateSet = false;
|
|
this._complete = true;
|
|
this._released = false;
|
|
this._markedForRemoval = false;
|
|
this._completedTick = -1;
|
|
this._implicitPause = false;
|
|
this._isTemplate = false;
|
|
this._finishedTriggers = false;
|
|
this._firstTick = false;
|
|
this._lastDelta = NaN;
|
|
this._tags = [""];
|
|
this._stringTags = "";
|
|
this._tagsChanged = false
|
|
}
|
|
static CreateInitial(timelineDataJson, timelineManager) {
|
|
const timelineDataManager = timelineManager.GetTimelineDataManager();
|
|
const nameId = timelineDataManager.GetNameId();
|
|
const timelineDataItem = timelineDataManager.Get(timelineDataJson[nameId]);
|
|
const timeline = C3.New(C3.TimelineState, timelineDataJson[nameId], timelineDataItem, timelineManager);
|
|
timeline.SetIsTemplate(true);
|
|
return timeline
|
|
}
|
|
static CreateFromTemplate(name, timelineDataItem, timelineManager) {
|
|
return C3.New(C3.TimelineState, name, timelineDataItem, timelineManager)
|
|
}
|
|
static get WORLD_INSTANCE_BOX_CHANGE() {
|
|
return 1
|
|
}
|
|
static get LAYOUT_RENDER_CHANGE() {
|
|
return C3.nextHighestPowerOfTwo(1)
|
|
}
|
|
Release() {
|
|
if (this.IsReleased())
|
|
return;
|
|
this._timelineManager.DeScheduleTimeline(this);
|
|
this._timelineManager.CompleteTimelineAndResolve(this);
|
|
for (const track of this._tracks)
|
|
track.Release();
|
|
C3.clearArray(this._tracks);
|
|
this._tracks = null;
|
|
this._playheadTime.Release();
|
|
this._playheadTime = null;
|
|
this._runtime = null;
|
|
this._timelineManager = null;
|
|
this._timelineDataItem = null;
|
|
this._released = true;
|
|
this._playPromise = null;
|
|
this._playResolve = null
|
|
}
|
|
GetTimelineManager() {
|
|
return this._timelineManager
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetTracks() {
|
|
return this._tracks
|
|
}
|
|
GetSimilarPropertyTracks(instance, sourceAdapter, propertyName) {
|
|
const ret = [];
|
|
for (const track of this._tracks) {
|
|
if (instance !== track.GetInstance())
|
|
continue;
|
|
const propertyTrack = track.GetPropertyTrack(propertyName);
|
|
if (!propertyTrack)
|
|
continue;
|
|
if (sourceAdapter.constructor !== propertyTrack.GetSourceAdapter().constructor)
|
|
continue;
|
|
ret.push(propertyTrack)
|
|
}
|
|
return ret
|
|
}
|
|
HasTracks() {
|
|
return !!this._tracks.length
|
|
}
|
|
GetTrackById(trackId) {
|
|
for (const track of this._tracks)
|
|
if (C3.equalsNoCase(track.GetId(), trackId))
|
|
return track;
|
|
return null
|
|
}
|
|
SetName(name) {
|
|
this._name = name
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
GetTimelineDataItem() {
|
|
return this._timelineDataItem
|
|
}
|
|
GetTemplateName() {
|
|
return this._timelineDataItem.GetName()
|
|
}
|
|
GetTotalTime() {
|
|
return this._timelineDataItem.GetTotalTime()
|
|
}
|
|
SetTotalTime(tt) {
|
|
this._timelineDataItem.SetTotalTime(tt)
|
|
}
|
|
GetStep() {
|
|
return this._timelineDataItem.GetStep()
|
|
}
|
|
SetStep(s) {
|
|
this._timelineDataItem.SetStep(s)
|
|
}
|
|
GetInterpolationMode() {
|
|
return this._timelineDataItem.GetInterpolationMode()
|
|
}
|
|
SetInterpolationMode(im) {
|
|
this._timelineDataItem.SetInterpolationMode(im)
|
|
}
|
|
GetResultMode() {
|
|
return this._timelineDataItem.GetResultMode()
|
|
}
|
|
SetResultMode(rm) {
|
|
this._timelineDataItem.GetResultMode(rm)
|
|
}
|
|
SetEase(e) {
|
|
for (const track of this.GetTracks())
|
|
track.SetEase(e)
|
|
}
|
|
GetLoop() {
|
|
return this._timelineDataItem.GetLoop()
|
|
}
|
|
SetLoop(l) {
|
|
return this._timelineDataItem.SetLoop(l)
|
|
}
|
|
GetPingPong() {
|
|
return this._timelineDataItem.GetPingPong()
|
|
}
|
|
SetPingPong(p) {
|
|
return this._timelineDataItem.SetPingPong(p)
|
|
}
|
|
GetRepeatCount() {
|
|
return this._timelineDataItem.GetRepeatCount()
|
|
}
|
|
SetPlaybackRate(r) {
|
|
return this._playbackRate = r
|
|
}
|
|
GetPlaybackRate() {
|
|
return this._playbackRate
|
|
}
|
|
IsForwardPlayBack() {
|
|
if (!this.IsPlaying())
|
|
return true;
|
|
return this._playbackRate > 0
|
|
}
|
|
GetPlayPromise() {
|
|
if (this._playPromise)
|
|
return this._playPromise;
|
|
this._playPromise = new Promise(resolve=>{
|
|
this._playResolve = resolve
|
|
}
|
|
);
|
|
return this._playPromise
|
|
}
|
|
ResolvePlayPromise() {
|
|
if (!this._playPromise)
|
|
return;
|
|
this._playResolve();
|
|
this._playPromise = null;
|
|
this._playResolve = null
|
|
}
|
|
SetTags(tags) {
|
|
this._tags = C3.TimelineState._GetTagArray(tags);
|
|
this._tagsChanged = true
|
|
}
|
|
GetTags() {
|
|
return this._tags
|
|
}
|
|
GetStringTags() {
|
|
if (this._tagsChanged)
|
|
this._stringTags = this._tags.join(" ");
|
|
this._tagsChanged = false;
|
|
return this._stringTags
|
|
}
|
|
HasTags(tags) {
|
|
if (!this._tags)
|
|
return false;
|
|
if (!this._tags.length)
|
|
return false;
|
|
const t = C3.TimelineState._GetTagArray(tags);
|
|
if (!t)
|
|
return false;
|
|
if (!t.length)
|
|
return false;
|
|
return t.every(C3.TimelineState._HasTag, this)
|
|
}
|
|
OnStarted() {
|
|
C3.Plugins.Timeline.Cnds.SetTriggerTimeline(this);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnTimelineStarted);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnTimelineStartedByName);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnTimelineStartedByTags);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnAnyTimelineStarted);
|
|
C3.Plugins.Timeline.Cnds.SetTriggerTimeline(null)
|
|
}
|
|
OnCompleted() {
|
|
this._completedTick = this._runtime.GetTickCount()
|
|
}
|
|
FinishTriggers() {
|
|
if (this._finishedTriggers)
|
|
return;
|
|
this._finishedTriggers = true;
|
|
C3.Plugins.Timeline.Cnds.SetTriggerTimeline(this);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnTimelineFinished);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnTimelineFinishedByName);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnTimelineFinishedByTags);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnAnyTimelineFinished);
|
|
C3.Plugins.Timeline.Cnds.SetTriggerTimeline(null)
|
|
}
|
|
SetPlaying(p) {
|
|
this._isPlaying = p
|
|
}
|
|
IsCompletedTick() {
|
|
return this._completedTick === this._runtime.GetTickCount()
|
|
}
|
|
IsPlaying(playingOnly=false) {
|
|
if (this.IsCompletedTick())
|
|
return true;
|
|
if (this.IsScheduled() && !playingOnly)
|
|
return true;
|
|
return this._isPlaying
|
|
}
|
|
_IsPlaying() {
|
|
return this.IsPlaying(true)
|
|
}
|
|
IsPaused() {
|
|
return this._IsPaused()
|
|
}
|
|
_IsPaused() {
|
|
if (this.IsReleased())
|
|
return false;
|
|
if (this.IsScheduled())
|
|
return false;
|
|
if (this._IsPlaying())
|
|
return false;
|
|
if (this.IsComplete())
|
|
return false;
|
|
return true
|
|
}
|
|
SetScheduled(s) {
|
|
this._isScheduled = s
|
|
}
|
|
IsScheduled() {
|
|
return this._isScheduled
|
|
}
|
|
SetComplete(c) {
|
|
this._complete = c;
|
|
const t = this.GetTime();
|
|
if (t <= 0 || t >= this.GetTotalTime())
|
|
this._complete = true
|
|
}
|
|
IsComplete() {
|
|
return this._complete
|
|
}
|
|
IsReleased() {
|
|
return this._released
|
|
}
|
|
SetMarkedForRemoval(mfr) {
|
|
this._markedForRemoval = mfr
|
|
}
|
|
IsMarkedForRemoval() {
|
|
return this._markedForRemoval
|
|
}
|
|
SetImplicitPause(ip) {
|
|
this._implicitPause = ip
|
|
}
|
|
IsImplicitPause() {
|
|
return this._implicitPause
|
|
}
|
|
SetIsTemplate(it) {
|
|
this._isTemplate = !!it
|
|
}
|
|
IsTemplate() {
|
|
return this._isTemplate
|
|
}
|
|
InitialStateSet() {
|
|
return this._initialStateSet
|
|
}
|
|
GetTime() {
|
|
return this._playheadTime.Get()
|
|
}
|
|
SetTime(time) {
|
|
const lastGlobalTime = this.GetTime();
|
|
this._SetTime(time);
|
|
this.SetComplete(false);
|
|
if (!this.IsComplete())
|
|
this.SetImplicitPause(true);
|
|
if (!this._IsPlaying() && !this.IsScheduled() && this._initialStateSet)
|
|
;
|
|
else if (!this._IsPlaying() && !this.IsScheduled() && !this._initialStateSet)
|
|
this.SetInitialStateFromSetTime();
|
|
else if (this._IsPlaying())
|
|
this.Stop();
|
|
else if (this.IsScheduled()) {
|
|
this._timelineManager.DeScheduleTimeline(this);
|
|
this.SetInitialStateFromSetTime()
|
|
}
|
|
const renderChange = this._Interpolate(time, false, true, true, lastGlobalTime);
|
|
if (renderChange)
|
|
this.GetRuntime().UpdateRender();
|
|
this._OnSetTime()
|
|
}
|
|
_SetTime(time) {
|
|
if (time < 0)
|
|
this._playheadTime.Set(0);
|
|
else if (time >= this.GetTotalTime())
|
|
this._playheadTime.Set(this.GetTotalTime());
|
|
else
|
|
this._playheadTime.Set(time)
|
|
}
|
|
_OnSetTime() {
|
|
if (!C3.Plugins.Timeline || this.constructor !== C3.TimelineState)
|
|
return;
|
|
C3.Plugins.Timeline.Cnds.SetTriggerTimeline(this);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnTimeSet);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnTimeSetByName);
|
|
this._timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnTimeSetByTags);
|
|
C3.Plugins.Timeline.Cnds.SetTriggerTimeline(null)
|
|
}
|
|
_CanResume() {
|
|
if (this.GetLoop())
|
|
return true;
|
|
else if (this.GetPingPong() && this._pingPongState === PING_PONG_END)
|
|
if (this.IsForwardPlayBack()) {
|
|
if (this.GetTime() >= this.GetTotalTime())
|
|
return false
|
|
} else {
|
|
if (this.GetTime() <= 0)
|
|
return false
|
|
}
|
|
else if (!this.GetLoop() && !this.GetPingPong())
|
|
if (this.IsForwardPlayBack()) {
|
|
if (this.GetTime() >= this.GetTotalTime())
|
|
return false
|
|
} else if (this.GetTime() <= 0)
|
|
return false;
|
|
return true
|
|
}
|
|
Resume() {
|
|
if (this.IsReleased())
|
|
return;
|
|
if (this._CanResume())
|
|
this.Play(true)
|
|
}
|
|
Play(resume=false) {
|
|
if (this.IsReleased())
|
|
return false;
|
|
if (this.IsScheduled())
|
|
return false;
|
|
if (this._IsPlaying() && this.IsCompletedTick())
|
|
return this._SchedulePlayingTimeline();
|
|
if (this._IsPlaying())
|
|
return false;
|
|
if (!this.IsComplete() && !resume && !this.IsImplicitPause())
|
|
return false;
|
|
return this._ScheduleStoppedTimeline()
|
|
}
|
|
_SchedulePlayingTimeline() {
|
|
this.SetImplicitPause(false);
|
|
this._timelineManager.RemovePlayingTimeline(this);
|
|
this._timelineManager.ScheduleTimeline(this);
|
|
this.GetPlayPromise();
|
|
return true
|
|
}
|
|
_ScheduleStoppedTimeline() {
|
|
this.SetImplicitPause(false);
|
|
this._timelineManager.ScheduleTimeline(this);
|
|
this.GetPlayPromise();
|
|
return true
|
|
}
|
|
Stop(completed=false) {
|
|
if (this.IsReleased())
|
|
return;
|
|
this.SetComplete(completed);
|
|
this._timelineManager.CompleteTimeline(this);
|
|
if (this.IsComplete())
|
|
this.ResolvePlayPromise()
|
|
}
|
|
Reset(render=true, beforeChangeLayout=false) {
|
|
if (this.IsReleased())
|
|
return;
|
|
if (!this._IsPlaying() && this.IsScheduled())
|
|
return this._timelineManager.DeScheduleTimeline(this);
|
|
if (this.IsComplete())
|
|
return;
|
|
this.Stop(true);
|
|
if (this.IsForwardPlayBack())
|
|
this._SetTime(0);
|
|
else
|
|
this._SetTime(this.GetTotalTime());
|
|
let renderChange;
|
|
const time = this.GetTime();
|
|
if (beforeChangeLayout)
|
|
renderChange = this._InterpolateBeforeChangeLayout(time);
|
|
else
|
|
renderChange = this._Interpolate(time, false, false, true);
|
|
if (render)
|
|
this._OnSetTime();
|
|
if (renderChange && render)
|
|
this.GetRuntime().UpdateRender()
|
|
}
|
|
ResetBeforeChangeLayout() {
|
|
this.Reset(false, true)
|
|
}
|
|
_InterpolateBeforeChangeLayout(time) {
|
|
this._Interpolate(time, false, false, true, NaN, false, true)
|
|
}
|
|
_OnBeforeChangeLayout() {
|
|
if (this.IsReleased())
|
|
return true;
|
|
if (this.HasValidGlobalTracks())
|
|
return false;
|
|
this._timelineManager.CompleteTimeline(this);
|
|
this.ResetBeforeChangeLayout();
|
|
return true
|
|
}
|
|
SetInitialStateFromSetTime() {
|
|
this.SetInitialState(true)
|
|
}
|
|
SetInitialState(fromSetTime) {
|
|
if (this.IsMarkedForRemoval())
|
|
return;
|
|
if (fromSetTime) {
|
|
this._initialStateSet = true;
|
|
this._firstTick = true;
|
|
for (const track of this._tracks)
|
|
track.SetInitialState()
|
|
} else {
|
|
this.SetPlaying(true);
|
|
this.SetScheduled(false);
|
|
this.OnStarted();
|
|
if (this.IsComplete()) {
|
|
this._completedTick = -1;
|
|
this._pingPongState = PING_PONG_BEGIN;
|
|
this._currentRepeatCount = 1;
|
|
this._complete = false;
|
|
this._finishedTriggers = false;
|
|
this._initialStateSet = true;
|
|
this._firstTick = true;
|
|
if (this.IsForwardPlayBack())
|
|
this._SetTime(0);
|
|
else
|
|
this._SetTime(this.GetTotalTime());
|
|
for (const track of this._tracks)
|
|
track.SetInitialState()
|
|
} else {
|
|
this._firstTick = true;
|
|
for (const track of this._tracks)
|
|
track.SetResumeState()
|
|
}
|
|
}
|
|
}
|
|
Tick(deltaTime, timeScale) {
|
|
if (deltaTime === 0 && this._lastDelta === 0)
|
|
return;
|
|
this._lastDelta = deltaTime;
|
|
const lastTime = this.GetTime();
|
|
const newDeltaTime = deltaTime * timeScale * this._playbackRate;
|
|
this._SetTime(lastTime + newDeltaTime);
|
|
let complete;
|
|
if (!this.GetLoop() && !this.GetPingPong())
|
|
complete = this._SimpleCompleteCheck();
|
|
else if (this.GetLoop() && !this.GetPingPong())
|
|
complete = this._LoopCompleteCheck();
|
|
else if (!this.GetLoop() && this.GetPingPong())
|
|
complete = this._PingPongCompleteCheck();
|
|
else if (this.GetLoop() && this.GetPingPong())
|
|
complete = this._LoopPingPongCompleteCheck();
|
|
if (complete) {
|
|
for (const track of this._tracks)
|
|
track.SetEndState();
|
|
this.Stop(true);
|
|
this.OnCompleted();
|
|
return true
|
|
} else
|
|
return this._Interpolate(this.GetTime(), true, false, false, lastTime, true)
|
|
}
|
|
_Interpolate(time, isTicking=false, setTime=false, ensureValue=false, lastTime=NaN, onTickCall=false, ignoreGlobals=false) {
|
|
let renderChange = false;
|
|
for (const track of this._tracks)
|
|
track.BeforeInterpolate();
|
|
for (const track of this._tracks) {
|
|
let t = time;
|
|
if (typeof lastTime === "number") {
|
|
const globalTime = this.GetTime();
|
|
const localTime = globalTime - track.GetStartOffset();
|
|
const lastLocalTime = lastTime - track.GetStartOffset();
|
|
if (localTime < 0 && lastLocalTime > 0) {
|
|
t = track.GetStartOffset();
|
|
this._SetTime(t)
|
|
}
|
|
}
|
|
const change = track.Interpolate(t, isTicking, setTime, ensureValue, this._firstTick, ignoreGlobals);
|
|
if (!renderChange && change)
|
|
renderChange = true
|
|
}
|
|
for (const track of this._tracks)
|
|
track.AfterInterpolate();
|
|
if (this._firstTick && onTickCall)
|
|
this._firstTick = false;
|
|
return renderChange
|
|
}
|
|
_SimpleCompleteCheck() {
|
|
if (this.IsForwardPlayBack()) {
|
|
if (this.GetTime() >= this.GetTotalTime())
|
|
if (this._currentRepeatCount < this.GetRepeatCount()) {
|
|
this._currentRepeatCount++;
|
|
this._SetTime(0)
|
|
} else {
|
|
this._SetTime(this.GetTotalTime());
|
|
return true
|
|
}
|
|
} else if (this.GetTime() <= 0)
|
|
if (this._currentRepeatCount < this.GetRepeatCount()) {
|
|
this._currentRepeatCount++;
|
|
this._SetTime(this.GetTotalTime())
|
|
} else {
|
|
this._SetTime(0);
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
_LoopCompleteCheck() {
|
|
if (this.IsForwardPlayBack()) {
|
|
if (this.GetTime() >= this.GetTotalTime())
|
|
this._SetTime(0)
|
|
} else if (this.GetTime() <= 0)
|
|
this._SetTime(this.GetTotalTime());
|
|
return false
|
|
}
|
|
_PingPongCompleteCheck() {
|
|
if (this.IsForwardPlayBack()) {
|
|
if (this.GetTime() >= this.GetTotalTime()) {
|
|
this._SetTime(this.GetTotalTime());
|
|
this.SetPlaybackRate(this.GetPlaybackRate() * -1);
|
|
if (this._pingPongState === PING_PONG_END)
|
|
if (this._currentRepeatCount < this.GetRepeatCount()) {
|
|
this._currentRepeatCount++;
|
|
this._pingPongState = PING_PONG_BEGIN
|
|
} else
|
|
return true;
|
|
else if (this._pingPongState === PING_PONG_BEGIN)
|
|
this._pingPongState = PING_PONG_END
|
|
}
|
|
} else if (this.GetTime() <= 0) {
|
|
this._SetTime(0);
|
|
this.SetPlaybackRate(this.GetPlaybackRate() * -1);
|
|
if (this._pingPongState === PING_PONG_END)
|
|
if (this._currentRepeatCount < this.GetRepeatCount()) {
|
|
this._currentRepeatCount++;
|
|
this._pingPongState = PING_PONG_BEGIN
|
|
} else
|
|
return true;
|
|
else if (this._pingPongState === PING_PONG_BEGIN)
|
|
this._pingPongState = PING_PONG_END
|
|
}
|
|
return false
|
|
}
|
|
_LoopPingPongCompleteCheck() {
|
|
if (this.IsForwardPlayBack()) {
|
|
if (this.GetTime() >= this.GetTotalTime()) {
|
|
this._SetTime(this.GetTotalTime());
|
|
this.SetPlaybackRate(this.GetPlaybackRate() * -1)
|
|
}
|
|
} else if (this.GetTime() <= 0) {
|
|
this._SetTime(0);
|
|
this.SetPlaybackRate(this.GetPlaybackRate() * -1)
|
|
}
|
|
return false
|
|
}
|
|
AddTrack() {
|
|
const trackDataItem = this._timelineDataItem.GetTrackData().AddEmptyTrackDataItem();
|
|
const track = C3.TrackState.Create(this, trackDataItem);
|
|
this._tracks.push(track);
|
|
return track
|
|
}
|
|
CleanCaches() {
|
|
for (const track of this._tracks)
|
|
track.CleanCaches()
|
|
}
|
|
ClearTrackInstances() {
|
|
for (const track of this._tracks)
|
|
track.ClearInstance()
|
|
}
|
|
SetTrackInstance(trackId, instance) {
|
|
if (!instance)
|
|
return;
|
|
for (const track of this._tracks)
|
|
if (trackId) {
|
|
if (track.GetId() !== trackId)
|
|
continue;
|
|
track.SetInstance(instance);
|
|
this._timelineManager.SetTimelineObjectClassToMap(instance.GetObjectClass(), this);
|
|
break
|
|
} else {
|
|
if (track.HasInstance())
|
|
continue;
|
|
track.SetInstance(instance);
|
|
this._timelineManager.SetTimelineObjectClassToMap(instance.GetObjectClass(), this);
|
|
break
|
|
}
|
|
}
|
|
HasTrackInstance(instance, trackId) {
|
|
for (const track of this._tracks)
|
|
if (trackId) {
|
|
if (trackId === track.GetId() && instance === track.GetInstance())
|
|
return true
|
|
} else if (instance === track.GetInstance())
|
|
return true;
|
|
return false
|
|
}
|
|
HasValidTracks() {
|
|
return this._tracks.some(t=>t.CanInstanceBeValid())
|
|
}
|
|
HasValidGlobalTracks() {
|
|
return this._tracks.some(t=>{
|
|
if (!t.CanInstanceBeValid())
|
|
return false;
|
|
const objectClass = t.GetObjectClass();
|
|
if (!objectClass)
|
|
return false;
|
|
return objectClass.IsGlobal()
|
|
}
|
|
)
|
|
}
|
|
GetPropertyTrack(propertyName) {
|
|
for (const track of this.GetTracks())
|
|
for (const propertyTrack of track.GetPropertyTracks())
|
|
if (propertyTrack.GetPropertyName() === propertyName)
|
|
return propertyTrack
|
|
}
|
|
GetKeyframeWithTags(tags) {
|
|
let tagsArray = tags ? tags.split(" ") : [];
|
|
const tagsSet = new Set(tagsArray.map(t=>t.toLowerCase().trim()));
|
|
tagsArray = [...tagsSet.values()];
|
|
for (const track of this.GetTracks())
|
|
for (const keyframeDataItem of track.GetKeyframeDataItems()) {
|
|
const hasAllTags = tagsArray.every(t=>keyframeDataItem.HasTag(t));
|
|
if (hasAllTags)
|
|
return keyframeDataItem
|
|
}
|
|
}
|
|
GetObjectClasses() {
|
|
const ret = [];
|
|
for (const track of this.GetTracks())
|
|
ret.push(track.GetObjectClass());
|
|
return ret.filter(oc=>oc)
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"tracksJson": this._SaveTracksToJson(),
|
|
"name": this._name,
|
|
"playheadTime": this.GetTime(),
|
|
"playbackRate": this._playbackRate,
|
|
"pingPongState": this._pingPongState,
|
|
"currentRepeatCount": this._currentRepeatCount,
|
|
"isPlaying": this._isPlaying,
|
|
"isScheduled": this._isScheduled,
|
|
"initialStateSet": this._initialStateSet,
|
|
"finishedTriggers": this._finishedTriggers,
|
|
"complete": this._complete,
|
|
"released": this._released,
|
|
"markedForRemoval": this._markedForRemoval,
|
|
"completedTick": this._completedTick,
|
|
"implicitPause": this._implicitPause,
|
|
"isTemplate": this._isTemplate,
|
|
"tags": this._tags.join(" "),
|
|
"stringTags": this._stringTags,
|
|
"tagsChanged": this._tagsChanged,
|
|
"firstTick": this._firstTick
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this._LoadTracksFromJson(o["tracksJson"]);
|
|
this._name = o["name"];
|
|
this._playheadTime.Set(o["playheadTime"]);
|
|
this._playbackRate = o["playbackRate"];
|
|
this._pingPongState = o["pingPongState"];
|
|
this._currentRepeatCount = o["currentRepeatCount"];
|
|
this._isPlaying = !!o["isPlaying"];
|
|
this._isScheduled = !!o["isScheduled"];
|
|
this._initialStateSet = !!o["initialStateSet"];
|
|
this._finishedTriggers = o.hasOwnProperty("finishedTriggers") ? !!o["finishedTriggers"] : false;
|
|
this._complete = !!o["complete"];
|
|
this._released = !!o["released"];
|
|
this._markedForRemoval = !!o["markedForRemoval"];
|
|
this._completedTick = o["completedTick"];
|
|
this._implicitPause = !!o["implicitPause"];
|
|
this._isTemplate = !!o["isTemplate"];
|
|
this._tags = o["tags"].split(" ");
|
|
this._stringTags = o["stringTags"];
|
|
this._tagsChanged = !!o["tagsChanged"];
|
|
this._firstTick = !!o["firstTick"]
|
|
}
|
|
_SaveTracksToJson() {
|
|
return this._tracks.map(trackState=>trackState._SaveToJson())
|
|
}
|
|
_LoadTracksFromJson(tracksJson) {
|
|
tracksJson.forEach((trackJson,i)=>{
|
|
const track = this._tracks[i];
|
|
track._LoadFromJson(trackJson)
|
|
}
|
|
);
|
|
this._tracks.filter(track=>track.CanInstanceBeValid())
|
|
}
|
|
static _HasTag(tag) {
|
|
const tags = this.GetTags();
|
|
if (tag === "")
|
|
return tags.length === 1 && tags[0] === "";
|
|
return tags.includes(tag)
|
|
}
|
|
static _GetTagArray(tags) {
|
|
if (C3.IsArray(tags))
|
|
return tags.slice(0);
|
|
if (C3.IsString(tags))
|
|
return tags.split(" ")
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.TrackState = class Track extends C3.DefendedBase {
|
|
constructor(timeline, trackDataItem) {
|
|
super();
|
|
this._timeline = timeline;
|
|
this._trackDataItem = trackDataItem;
|
|
this._trackData = trackDataItem.GetTrackData();
|
|
this._instanceUid = NaN;
|
|
this._objectClassIndex = NaN;
|
|
this._instance = null;
|
|
this._worldInfo = null;
|
|
this._isNested = trackDataItem.GetStartOffset() > 0;
|
|
this._initialStateOfNestedSet = false;
|
|
this._endStateOfNestedSet = false;
|
|
this._lastKeyframeDataItem = null;
|
|
this._keyframeDataItems = this._trackDataItem.GetKeyframeData().GetKeyframeDataItemArray();
|
|
this._propertyTracks = [];
|
|
for (const propertyTrackDataItem of this._trackDataItem.GetPropertyTrackData().propertyTrackDataItems())
|
|
this._propertyTracks.push(C3.PropertyTrackState.Create(this, propertyTrackDataItem))
|
|
}
|
|
static Create(timeline, trackDataItem) {
|
|
return C3.New(C3.TrackState, timeline, trackDataItem)
|
|
}
|
|
Release() {
|
|
this._keyframeDataItems = null;
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.Release();
|
|
C3.clearArray(this._propertyTracks);
|
|
this._propertyTracks = null;
|
|
this._timeline = null;
|
|
this._instance = null;
|
|
this._worldInfo = null;
|
|
this._trackDataItem = null;
|
|
this._lastKeyframeDataItem = null
|
|
}
|
|
CleanCaches() {
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.CleanCaches();
|
|
this._instance = null;
|
|
this._worldInfo = null
|
|
}
|
|
GetTimeline() {
|
|
return this._timeline
|
|
}
|
|
GetRuntime() {
|
|
return this._timeline.GetRuntime()
|
|
}
|
|
GetKeyframeDataItems() {
|
|
if (this._keyframeDataItems)
|
|
return this._keyframeDataItems;
|
|
this._keyframeDataItems = this._trackDataItem.GetKeyframeData().GetKeyframeDataItemArray();
|
|
return this._keyframeDataItems
|
|
}
|
|
GetPropertyTracks() {
|
|
return this._propertyTracks
|
|
}
|
|
GetPropertyTrack(propertyName) {
|
|
for (const propertyTrack of this._propertyTracks)
|
|
if (propertyTrack.GetPropertyName() === propertyName)
|
|
return propertyTrack
|
|
}
|
|
MaybeGetInstance() {
|
|
if (!this._instance)
|
|
this.GetInstance()
|
|
}
|
|
IsInstanceValid() {
|
|
if (!this._instance)
|
|
return false;
|
|
return !this._instance.IsDestroyed()
|
|
}
|
|
CanInstanceBeValid() {
|
|
const uid = this.GetInstanceUID();
|
|
const instance = this.GetRuntime().GetInstanceByUID(uid);
|
|
if (!instance)
|
|
return false;
|
|
return !instance.IsDestroyed()
|
|
}
|
|
GetObjectClass() {
|
|
const index = this.GetObjectClassIndex();
|
|
if (index === -1)
|
|
return;
|
|
return this.GetRuntime().GetObjectClassByIndex(index)
|
|
}
|
|
ClearInstance() {
|
|
this._instance = null;
|
|
this._instanceUid = -1;
|
|
this._worldInfo = null;
|
|
this._objectClassIndex = -1
|
|
}
|
|
HasInstance() {
|
|
return !!this._instance
|
|
}
|
|
GetInstance() {
|
|
if (this._instance && this.IsInstanceValid())
|
|
return this._instance;
|
|
const uid = this.GetInstanceUID();
|
|
this._instance = this.GetRuntime().GetInstanceByUID(uid);
|
|
return this._instance
|
|
}
|
|
SetInstance(instance) {
|
|
if (this._instance === instance)
|
|
return;
|
|
this.CleanCaches();
|
|
this._instance = instance;
|
|
this._objectClassIndex = instance.GetObjectClass().GetIndex();
|
|
this._instanceUid = instance.GetUID();
|
|
this._worldInfo = instance.GetWorldInfo();
|
|
for (const item of this.propertyTrackItems()) {
|
|
const propertyTrack = item.propertyTrack;
|
|
const sourceAdapter = item.sourceAdapter;
|
|
const id = propertyTrack.GetSourceAdapterId();
|
|
switch (id) {
|
|
case "instance-variable":
|
|
{
|
|
const index = sourceAdapter.GetEditorIndex();
|
|
const objectClass = instance.GetObjectClass();
|
|
const i = objectClass.GetInstanceVariableIndexByName(item.name);
|
|
const name = objectClass.GetInstanceVariableName(i);
|
|
const type = objectClass.GetInstanceVariableType(i);
|
|
if (name === item.name && type === item.type)
|
|
sourceAdapter.UpdateInstanceVariableIndex(i);
|
|
break
|
|
}
|
|
case "behavior":
|
|
{
|
|
const timelineBehaviorType = item.behaviorType;
|
|
const trackObjectClass = this.GetObjectClass();
|
|
const objectClass = instance.GetObjectClass();
|
|
const instanceBehaviorType = sourceAdapter.GetBehaviorType(objectClass);
|
|
if (timelineBehaviorType && instanceBehaviorType) {
|
|
const name = timelineBehaviorType.GetName();
|
|
const templateBehaviorIndex = trackObjectClass.GetBehaviorIndexByName(name);
|
|
const instanceBehaviorIndex = objectClass.GetBehaviorIndexByName(name);
|
|
const propertyIndex = sourceAdapter.GetEditorIndex();
|
|
sourceAdapter.UpdateBehaviorTypeSid(instanceBehaviorType.GetSID())
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*propertyTrackItems() {
|
|
for (const propertyTrack of this._propertyTracks) {
|
|
const sourceAdapter = propertyTrack.GetSourceAdapter();
|
|
const objectClass = this.GetObjectClass();
|
|
const ret = {
|
|
propertyTrack: propertyTrack,
|
|
sourceAdapter: sourceAdapter
|
|
};
|
|
switch (propertyTrack.GetSourceAdapterId()) {
|
|
case "world-instance":
|
|
{
|
|
ret.property = propertyTrack.GetPropertyName();
|
|
break
|
|
}
|
|
case "instance-variable":
|
|
{
|
|
const index = sourceAdapter.GetEditorIndex();
|
|
ret.name = objectClass.GetInstanceVariableName(index);
|
|
ret.type = objectClass.GetInstanceVariableType(index);
|
|
break
|
|
}
|
|
case "effect":
|
|
{
|
|
const effectList = objectClass.GetEffectList();
|
|
const effectType = sourceAdapter.GetEffectType(effectList);
|
|
ret.effectType = effectType;
|
|
break
|
|
}
|
|
case "behavior":
|
|
{
|
|
const behaviorType = sourceAdapter.GetBehaviorType(objectClass);
|
|
ret.behaviorType = behaviorType;
|
|
break
|
|
}
|
|
case "plugin":
|
|
{
|
|
ret.plugin = objectClass.GetPlugin();
|
|
break
|
|
}
|
|
}
|
|
yield ret
|
|
}
|
|
}
|
|
GetWorldInfo() {
|
|
if (this._worldInfo && this.IsInstanceValid())
|
|
return this._worldInfo;
|
|
const instance = this.GetInstance();
|
|
if (instance)
|
|
this._worldInfo = instance.GetWorldInfo();
|
|
return this._worldInfo
|
|
}
|
|
GetTrackDataItem() {
|
|
return this._trackDataItem
|
|
}
|
|
GetInstanceUID() {
|
|
if (this._instanceUid)
|
|
return this._instanceUid;
|
|
return this._trackDataItem.GetInstanceUID()
|
|
}
|
|
SetInstanceUID(uid) {
|
|
this._trackDataItem.SetInstanceUID(uid)
|
|
}
|
|
GetInterpolationMode() {
|
|
return this._trackDataItem.GetInterpolationMode()
|
|
}
|
|
SetInterpolationMode(im) {
|
|
this._trackDataItem.SetInterpolationMode(im)
|
|
}
|
|
GetResultMode() {
|
|
return this._trackDataItem.GetResultMode()
|
|
}
|
|
GetId() {
|
|
return this._trackDataItem.GetId()
|
|
}
|
|
GetStartOffset() {
|
|
return this._trackDataItem.GetStartOffset()
|
|
}
|
|
GetLocalTotalTime() {
|
|
return this._trackDataItem.GetLocalTotalTime()
|
|
}
|
|
SetResultMode(rm) {
|
|
this._trackDataItem.SetResultMode(rm)
|
|
}
|
|
SetEase(e) {
|
|
for (const keyframeDataItem of this.GetKeyframeDataItems())
|
|
keyframeDataItem.SetEase(e);
|
|
for (const propertyTrack of this.GetPropertyTracks())
|
|
propertyTrack.SetEase(e)
|
|
}
|
|
GetEnable() {
|
|
return this._trackDataItem.GetEnable()
|
|
}
|
|
SetEnable(e) {
|
|
this._trackDataItem.SetEnable(e)
|
|
}
|
|
GetObjectClassIndex() {
|
|
if (!isNaN(this._objectClassIndex))
|
|
return this._objectClassIndex;
|
|
return this._trackDataItem.GetObjectClassIndex()
|
|
}
|
|
SetObjectClassIndex(objectClassIndex) {
|
|
this._trackDataItem.SetObjectClassIndex(objectClassIndex)
|
|
}
|
|
SetOriginalWidth(w) {
|
|
this._trackDataItem.SetOriginalWidth(w)
|
|
}
|
|
GetOriginalWidth() {
|
|
return this._trackDataItem.GetOriginalWidth()
|
|
}
|
|
SetOriginalHeight(h) {
|
|
this._trackDataItem.SetOriginalHeight(h)
|
|
}
|
|
GetOriginalHeight() {
|
|
return this._trackDataItem.GetOriginalHeight()
|
|
}
|
|
SetInitialState() {
|
|
this.MaybeGetInstance();
|
|
if (!this.IsInstanceValid())
|
|
return;
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.SetInitialState();
|
|
const timeline = this.GetTimeline();
|
|
const isForwardPlayBack = timeline.IsForwardPlayBack();
|
|
const time = isForwardPlayBack ? 0 : this.GetLocalTotalTime();
|
|
this._lastKeyframeDataItem = this.GetLastKeyFrameBeforeTime(time);
|
|
this._initialStateOfNestedSet = false;
|
|
this._endStateOfNestedSet = false;
|
|
this.Interpolate(time)
|
|
}
|
|
SetResumeState() {
|
|
this.MaybeGetInstance();
|
|
if (!this.IsInstanceValid())
|
|
return;
|
|
const playbackDirection = this._timeline.IsForwardPlayBack();
|
|
const time = this._timeline.GetTime() - this.GetStartOffset();
|
|
this._lastKeyframeDataItem = this.GetLastKeyFrameBeforeTime(time);
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.SetResumeState()
|
|
}
|
|
SetEndState() {
|
|
if (this.GetTimeline().IsComplete())
|
|
return;
|
|
this.MaybeGetInstance();
|
|
if (!this.IsInstanceValid())
|
|
return;
|
|
if (!this._isNested) {
|
|
const time = this._timeline.GetTime();
|
|
const totalTime = this.GetStartOffset() + this.GetLocalTotalTime();
|
|
if (time >= totalTime)
|
|
this.Interpolate(this.GetLocalTotalTime(), true, false, true);
|
|
else if (time <= 0)
|
|
this.Interpolate(0, true, false, true)
|
|
}
|
|
}
|
|
BeforeInterpolate() {
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.BeforeInterpolate()
|
|
}
|
|
Interpolate(time, isTicking=false, setTime=false, ensureValue=false, firstTick=false, ignoreGlobals=false) {
|
|
this.MaybeGetInstance();
|
|
if (!this.IsInstanceValid())
|
|
return false;
|
|
if (ignoreGlobals && this.GetObjectClass().IsGlobal())
|
|
return false;
|
|
time = time - this.GetStartOffset();
|
|
if (time < 0)
|
|
return false;
|
|
this.MaybeSetInitialStateOfNestedTrack(time, isTicking);
|
|
this.MaybeTriggerKeyframeReachedConditions(time, isTicking, firstTick);
|
|
let boxChange = false;
|
|
let renderChange = false;
|
|
for (const propertyTrack of this._propertyTracks) {
|
|
const change = propertyTrack.Interpolate(time, setTime, false, ensureValue);
|
|
if (!boxChange && (change & C3.TimelineState.WORLD_INSTANCE_BOX_CHANGE) !== 0)
|
|
boxChange = true;
|
|
if (!renderChange && (change & C3.TimelineState.LAYOUT_RENDER_CHANGE) !== 0)
|
|
renderChange = true
|
|
}
|
|
this.MaybeSetEndStateOfNestedTrack(time, isTicking);
|
|
if (boxChange) {
|
|
const worldInfo = this.GetWorldInfo();
|
|
if (worldInfo)
|
|
worldInfo.SetBboxChanged()
|
|
}
|
|
return renderChange
|
|
}
|
|
AfterInterpolate() {
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.AfterInterpolate()
|
|
}
|
|
MaybeSetInitialStateOfNestedTrack(time, isTicking) {
|
|
if (!isTicking)
|
|
return;
|
|
if (!this._isNested)
|
|
return;
|
|
if (this._initialStateOfNestedSet)
|
|
return;
|
|
const timeline = this.GetTimeline();
|
|
if (timeline.IsForwardPlayBack()) {
|
|
if (time < 0)
|
|
return;
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.Interpolate(0, false, false, true)
|
|
} else {
|
|
if (time > this.GetLocalTotalTime())
|
|
return;
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.Interpolate(this.GetLocalTotalTime(), false, false, true)
|
|
}
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.SetInitialState();
|
|
this._initialStateOfNestedSet = true
|
|
}
|
|
MaybeSetEndStateOfNestedTrack(time, isTicking) {
|
|
if (!isTicking)
|
|
return;
|
|
if (!this._isNested)
|
|
return;
|
|
if (this._endStateOfNestedSet)
|
|
return;
|
|
const timeline = this.GetTimeline();
|
|
if (timeline.IsForwardPlayBack()) {
|
|
if (time >= this.GetLocalTotalTime()) {
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.Interpolate(this.GetLocalTotalTime(), false, false, true);
|
|
this._endStateOfNestedSet = true
|
|
}
|
|
} else if (time <= 0) {
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.Interpolate(0, false, false, true);
|
|
this._endStateOfNestedSet = true
|
|
}
|
|
}
|
|
MaybeTriggerKeyframeReachedConditions(time, isTicking, firstTick) {
|
|
if (firstTick)
|
|
return;
|
|
if (!isTicking)
|
|
return;
|
|
let keyframeDataItem = this.GetLastKeyFrameBeforeTime(time);
|
|
if (keyframeDataItem !== this._lastKeyframeDataItem)
|
|
this.OnKeyframeReached(keyframeDataItem);
|
|
this._lastKeyframeDataItem = keyframeDataItem;
|
|
return keyframeDataItem
|
|
}
|
|
GetLastKeyFrameBeforeTime(time) {
|
|
const timeline = this.GetTimeline();
|
|
let keyframeDataItem = this._trackData.GetKeyFrameDataItemAtTime(time, this._trackDataItem);
|
|
if (keyframeDataItem)
|
|
return keyframeDataItem;
|
|
else if (timeline.IsForwardPlayBack())
|
|
return this._trackData.GetFirstKeyFrameDataItemLowerOrEqualThan(time, this._trackDataItem);
|
|
else
|
|
return this._trackData.GetFirstKeyFrameDataItemHigherOrEqualThan(time, this._trackDataItem)
|
|
}
|
|
OnKeyframeReached(keyframeDataItem) {
|
|
if (!C3.Plugins.Timeline || this.GetTimeline().constructor !== C3.TimelineState)
|
|
return;
|
|
const timeline = this.GetTimeline();
|
|
C3.Plugins.Timeline.Cnds.SetTriggerTimeline(timeline);
|
|
C3.Plugins.Timeline.Cnds.SetTriggerKeyframe(keyframeDataItem);
|
|
const timelineManager = timeline.GetTimelineManager();
|
|
timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnAnyKeyframeReached);
|
|
timelineManager.Trigger(C3.Plugins.Timeline.Cnds.OnKeyframeReached);
|
|
C3.Plugins.Timeline.Cnds.SetTriggerTimeline(null);
|
|
C3.Plugins.Timeline.Cnds.SetTriggerKeyframe(null)
|
|
}
|
|
AddKeyframe() {
|
|
const keyframeData = this._trackDataItem.GetKeyframeData();
|
|
const keyframeDataItem = keyframeData.AddEmptyKeyframeDataItem();
|
|
return keyframeDataItem
|
|
}
|
|
AddPropertyTrack() {
|
|
const propertyTrackData = this._trackDataItem.GetPropertyTrackData();
|
|
const propertyTrackDataItem = propertyTrackData.AddEmptyPropertyTrackDataItem();
|
|
const propertyTrack = C3.PropertyTrackState.Create(this, propertyTrackDataItem);
|
|
this._propertyTracks.push(propertyTrack);
|
|
return propertyTrack
|
|
}
|
|
DeleteKeyframes(match) {
|
|
const keyframeData = this._trackDataItem.GetKeyframeData();
|
|
keyframeData.DeleteKeyframeDataItems(match)
|
|
}
|
|
DeletePropertyKeyframes(match) {
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.DeletePropertyKeyframes(match)
|
|
}
|
|
SaveState() {
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.SaveState()
|
|
}
|
|
CompareInitialStateWithCurrent() {
|
|
this.MaybeGetInstance();
|
|
if (!this.IsInstanceValid())
|
|
return;
|
|
for (const propertyTrack of this._propertyTracks)
|
|
propertyTrack.CompareInitialStateWithCurrent()
|
|
}
|
|
CompareSaveStateWithCurrent() {
|
|
this.MaybeGetInstance();
|
|
if (!this.IsInstanceValid())
|
|
return;
|
|
let difference = false;
|
|
for (const propertyTrack of this._propertyTracks) {
|
|
const diff = propertyTrack.CompareSaveStateWithCurrent();
|
|
if (!difference && diff)
|
|
difference = true
|
|
}
|
|
if (difference) {
|
|
const keyframeDataItem = this.AddKeyframe();
|
|
keyframeDataItem.SetTime(this.GetTimeline().GetTime());
|
|
keyframeDataItem.SetEase("noease");
|
|
keyframeDataItem.SetEnable(true);
|
|
keyframeDataItem.SetTags("")
|
|
}
|
|
}
|
|
_SaveToJson() {
|
|
const instance = this.GetInstance();
|
|
const uid = instance ? instance.GetUID() : this.GetInstanceUID();
|
|
return {
|
|
"propertyTracksJson": this._SavePropertyTracksToJson(),
|
|
"lastKeyframeDataItemJson": this._SaveLastKeyframeDataItemToJson(),
|
|
"initialStateOfNestedSet": this._initialStateOfNestedSet,
|
|
"endStateOfNestedSet": this._endStateOfNestedSet,
|
|
"instanceUid": uid
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this._LoadPropertyTracksFromJson(o["propertyTracksJson"]);
|
|
this._LoadLastKeyframeDataItemFromJson(o["lastKeyframeDataItemJson"]);
|
|
this._LoadInstanceFromJson(o["instanceUid"]);
|
|
this._initialStateOfNestedSet = false;
|
|
if (o.hasOwnProperty["initialStateOfNestedSet"])
|
|
this._initialStateOfNestedSet = o["initialStateOfNestedSet"];
|
|
this._endStateOfNestedSet = false;
|
|
if (o.hasOwnProperty["endStateOfNestedSet"])
|
|
this._endStateOfNestedSet = o["endStateOfNestedSet"]
|
|
}
|
|
_SaveLastKeyframeDataItemToJson() {
|
|
const keyframeData = this._trackDataItem.GetKeyframeData();
|
|
return keyframeData.GetKeyframeDataItemIndex(this._lastKeyframeDataItem)
|
|
}
|
|
_SavePropertyTracksToJson() {
|
|
return this._propertyTracks.map(propertyTrackState=>propertyTrackState._SaveToJson())
|
|
}
|
|
_LoadPropertyTracksFromJson(propertyTracksJson) {
|
|
propertyTracksJson.forEach((propertyTrackJson,i)=>{
|
|
const propertyTrack = this._propertyTracks[i];
|
|
propertyTrack._LoadFromJson(propertyTrackJson)
|
|
}
|
|
)
|
|
}
|
|
_LoadInstanceFromJson(uid) {
|
|
if (!C3.IsFiniteNumber(uid))
|
|
return;
|
|
const instance = this.GetRuntime().GetInstanceByUID(uid);
|
|
if (!instance)
|
|
return;
|
|
const timeline = this.GetTimeline();
|
|
timeline.ClearTrackInstances();
|
|
timeline.SetTrackInstance(this._trackDataItem.GetId(), instance)
|
|
}
|
|
_LoadLastKeyframeDataItemFromJson(lastKeyframeDataItemIndex) {
|
|
const keyframeData = this._trackDataItem.GetKeyframeData();
|
|
this._lastKeyframeDataItem = keyframeData.GetKeyframeDataItemFromIndex(lastKeyframeDataItemIndex)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.PropertyTrackState = class PropertyTrack extends C3.DefendedBase {
|
|
constructor(track, propertyTrackDataItem) {
|
|
super();
|
|
this._track = track;
|
|
this._propertyTrackDataItem = propertyTrackDataItem;
|
|
this._propertyTrackData = propertyTrackDataItem.GetPropertyTrackData();
|
|
this._sourceAdapter = this.GetSourceAdapter();
|
|
this._propertyKeyframeDataItems = this._propertyTrackDataItem.GetPropertyKeyframeData().GetPropertyKeyframeDataItemArray()
|
|
}
|
|
static Create(track, propertyTrackDataItem) {
|
|
return C3.New(C3.PropertyTrackState, track, propertyTrackDataItem)
|
|
}
|
|
Release() {
|
|
this._track = null;
|
|
if (this._sourceAdapter) {
|
|
this._sourceAdapter.Release();
|
|
this._sourceAdapter = null
|
|
}
|
|
this._propertyKeyframeDataItems = null;
|
|
this._propertyTrackDataItem = null;
|
|
this._propertyTrackData = null
|
|
}
|
|
GetTrack() {
|
|
return this._track
|
|
}
|
|
GetPropertyTrackDataItem() {
|
|
return this._propertyTrackDataItem
|
|
}
|
|
GetPropertyTrackData() {
|
|
return this._propertyTrackData
|
|
}
|
|
GetTimeline() {
|
|
return this._track.GetTimeline()
|
|
}
|
|
GetRuntime() {
|
|
return this._track.GetRuntime()
|
|
}
|
|
GetInstance() {
|
|
return this._track.GetInstance()
|
|
}
|
|
GetSourceAdapter() {
|
|
if (this._sourceAdapter)
|
|
return this._sourceAdapter;
|
|
const id = this._propertyTrackDataItem.GetSourceAdapterId();
|
|
let ret;
|
|
switch (id) {
|
|
case "behavior":
|
|
ret = new C3.PropertyTrackState.BehaviorSourceAdapter(this);
|
|
break;
|
|
case "effect":
|
|
ret = new C3.PropertyTrackState.EffectSourceAdapter(this);
|
|
break;
|
|
case "instance-variable":
|
|
ret = new C3.PropertyTrackState.InstanceVariableSourceAdapter(this);
|
|
break;
|
|
case "plugin":
|
|
ret = new C3.PropertyTrackState.PluginSourceAdapter(this);
|
|
break;
|
|
case "world-instance":
|
|
ret = new C3.PropertyTrackState.WorldInstanceSourceAdapter(this);
|
|
break;
|
|
case "value":
|
|
ret = new C3.PropertyTrackState.ValueSourceAdapter(this);
|
|
break
|
|
}
|
|
this._sourceAdapter = ret;
|
|
return this._sourceAdapter
|
|
}
|
|
GetSourceAdapterId() {
|
|
return this._propertyTrackDataItem.GetSourceAdapterId()
|
|
}
|
|
SetSourceAdapterId(said) {
|
|
this._propertyTrackDataItem.SetSourceAdapterId(said)
|
|
}
|
|
GetSourceAdapterArgs() {
|
|
return this._propertyTrackDataItem.GetSourceAdapterArguments()
|
|
}
|
|
SetSourceAdapterArgs(sargs) {
|
|
this._propertyTrackDataItem.SetSourceAdapterArguments(sargs)
|
|
}
|
|
GetSourceAdapterValue() {
|
|
return this.GetSourceAdapter().GetValue()
|
|
}
|
|
GetPropertyName() {
|
|
return this._propertyTrackDataItem.GetProperty()
|
|
}
|
|
SetPropertyName(pn) {
|
|
this._propertyTrackDataItem.SetProperty(pn)
|
|
}
|
|
GetPropertyType() {
|
|
return this._propertyTrackDataItem.GetType()
|
|
}
|
|
SetPropertyType(pt) {
|
|
this._propertyTrackDataItem.SetType(pt)
|
|
}
|
|
GetPropertyKeyframeType() {
|
|
return this.GetPropertyTrackData().GetFirstPropertyKeyframeDataItem(this._propertyTrackDataItem).GetType()
|
|
}
|
|
GetMin() {
|
|
return this._propertyTrackDataItem.GetMin()
|
|
}
|
|
SetMin(min) {
|
|
this._propertyTrackDataItem.SetMin(min)
|
|
}
|
|
GetMax() {
|
|
return this._propertyTrackDataItem.GetMax()
|
|
}
|
|
SetMax(max) {
|
|
this._propertyTrackDataItem.SetMax(max)
|
|
}
|
|
GetEnable() {
|
|
return this._propertyTrackDataItem.GetEnable()
|
|
}
|
|
SetEnable(e) {
|
|
this._propertyTrackDataItem.SetEnable(e)
|
|
}
|
|
GetInterpolationMode() {
|
|
return this._propertyTrackDataItem.GetInterpolationMode()
|
|
}
|
|
SetInterpolationMode(im) {
|
|
this._propertyTrackDataItem.SetInterpolationMode(im)
|
|
}
|
|
GetResultMode() {
|
|
return this._propertyTrackDataItem.GetResultMode()
|
|
}
|
|
SetResultMode(rm) {
|
|
this._propertyTrackDataItem.SetResultMode(rm)
|
|
}
|
|
SetEase(e) {
|
|
for (const propertyKeyframeDataItem of this.GetPropertyKeyframeDataItems())
|
|
propertyKeyframeDataItem.SetEase(e)
|
|
}
|
|
GetPropertyKeyframeDataItems() {
|
|
if (this._propertyKeyframeDataItems)
|
|
return this._propertyKeyframeDataItems;
|
|
this._propertyKeyframeDataItems = this._propertyTrackDataItem.GetPropertyKeyframeData().GetPropertyKeyframeDataItemArray();
|
|
return this._propertyKeyframeDataItems
|
|
}
|
|
*GetPropertyKeyframeValues() {
|
|
for (const propertyKeyframeDataItem of this.GetPropertyKeyframeDataItems())
|
|
yield propertyKeyframeDataItem.GetValueWithResultMode()
|
|
}
|
|
CleanCaches() {
|
|
this.GetSourceAdapter().CleanCaches()
|
|
}
|
|
GetCurrentState() {
|
|
return this.GetSourceAdapter().GetCurrentState()
|
|
}
|
|
SetInitialState() {
|
|
this.GetSourceAdapter().SetInitialState()
|
|
}
|
|
SetResumeState() {
|
|
this.GetSourceAdapter().SetResumeState()
|
|
}
|
|
BeforeInterpolate() {
|
|
this.GetSourceAdapter().BeforeInterpolate()
|
|
}
|
|
Interpolate(time, setTime=false, noChange=false, ensureValue=false) {
|
|
const propertyTrackDataItem = this._propertyTrackDataItem;
|
|
let start = this._propertyTrackData.GetPropertyKeyFrameDataItemAtTime(time, propertyTrackDataItem);
|
|
let end;
|
|
if (start)
|
|
end = this._propertyTrackData.GetFirstPropertyKeyFrameDataItemHigherThan(time, propertyTrackDataItem);
|
|
else {
|
|
start = this._propertyTrackData.GetFirstPropertyKeyFrameDataItemLowerOrEqualThan(time, propertyTrackDataItem);
|
|
end = this._propertyTrackData.GetFirstPropertyKeyFrameDataItemHigherOrEqualThan(time, propertyTrackDataItem)
|
|
}
|
|
return this.GetSourceAdapter().Interpolate(time, start, end, setTime, noChange, ensureValue)
|
|
}
|
|
AfterInterpolate() {
|
|
this.GetSourceAdapter().AfterInterpolate()
|
|
}
|
|
static GetStartPropertyKeyframeForTime(time, propertyTrack) {
|
|
const propertyTrackDataItem = propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = propertyTrack._propertyTrackData;
|
|
let start = propertyTrackData.GetPropertyKeyFrameDataItemAtTime(time, propertyTrackDataItem);
|
|
if (!start)
|
|
start = propertyTrackData.GetFirstPropertyKeyFrameDataItemLowerOrEqualThan(time, propertyTrackDataItem);
|
|
return start
|
|
}
|
|
static GetEndPropertyKeyframeForTime(time, propertyTrack) {
|
|
const propertyTrackDataItem = propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = propertyTrack._propertyTrackData;
|
|
let end = propertyTrackData.GetPropertyKeyFrameDataItemAtTime(time, propertyTrackDataItem);
|
|
if (end)
|
|
return propertyTrackData.GetFirstPropertyKeyFrameDataItemHigherThan(time, propertyTrackDataItem);
|
|
else
|
|
return propertyTrackData.GetFirstPropertyKeyFrameDataItemHigherOrEqualThan(time, propertyTrackDataItem)
|
|
}
|
|
AddPropertyKeyframe() {
|
|
const propertyKeyframeData = this._propertyTrackDataItem.GetPropertyKeyframeData();
|
|
const propertyKeyframeDataItem = propertyKeyframeData.AddEmptyPropertyKeyframeDataItem();
|
|
return propertyKeyframeDataItem
|
|
}
|
|
DeletePropertyKeyframes(match) {
|
|
const propertyKeyframeData = this._propertyTrackDataItem.GetPropertyKeyframeData();
|
|
propertyKeyframeData.DeletePropertyKeyframeDataItems(match)
|
|
}
|
|
SaveState() {
|
|
this.GetSourceAdapter().SaveState()
|
|
}
|
|
CompareInitialStateWithCurrent() {
|
|
const difference = this.GetSourceAdapter().CompareInitialStateWithCurrent();
|
|
if (difference) {
|
|
const propertyKeyframeDataItem = this._propertyTrackData.GetFirstPropertyKeyframeDataItem(this._propertyTrackDataItem);
|
|
const currentState = this.GetSourceAdapter().GetCurrentState();
|
|
propertyKeyframeDataItem.SetAbsoluteValue(currentState)
|
|
}
|
|
}
|
|
CompareSaveStateWithCurrent() {
|
|
const difference = this.GetSourceAdapter().CompareSaveStateWithCurrent();
|
|
if (difference)
|
|
this.AddPropertyKeyframeAtCurrentTime();
|
|
this.GetSourceAdapter().ClearSaveState();
|
|
return difference
|
|
}
|
|
AddPropertyKeyframeAtCurrentTime() {
|
|
const time = this.GetTimeline().GetTime();
|
|
const sourceAdapter = this.GetSourceAdapter();
|
|
const startPropertyKeyframe = C3.PropertyTrackState.GetStartPropertyKeyframeForTime(time, this);
|
|
const propertyKeyframeDataItem = this.AddPropertyKeyframe();
|
|
propertyKeyframeDataItem.SetType(startPropertyKeyframe.GetType());
|
|
propertyKeyframeDataItem.SetTime(time);
|
|
propertyKeyframeDataItem.SetEase(startPropertyKeyframe.GetEase());
|
|
propertyKeyframeDataItem.SetEnable(true);
|
|
propertyKeyframeDataItem.SetValue(sourceAdapter.GetValueAtTime());
|
|
propertyKeyframeDataItem.SetAbsoluteValue(sourceAdapter.GetCurrentState())
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"sourceAdapterJson": this.GetSourceAdapter()._SaveToJson()
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this.GetSourceAdapter()._LoadFromJson(o["sourceAdapterJson"])
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const NS = C3.PropertyTrackState;
|
|
NS.PropertySourceAdapter = class PropertySourceAdapter {
|
|
constructor(propertyTrack) {
|
|
this._propertyTrack = propertyTrack;
|
|
this._propertyAdapter = null
|
|
}
|
|
Release() {
|
|
if (this._propertyAdapter) {
|
|
this._propertyAdapter.Release();
|
|
this._propertyAdapter = null
|
|
}
|
|
this._propertyTrack = null
|
|
}
|
|
GetPropertyTrack() {
|
|
return this._propertyTrack
|
|
}
|
|
CleanCaches() {
|
|
if (this._propertyAdapter)
|
|
this._propertyAdapter.CleanCaches()
|
|
}
|
|
GetPropertyAdapter() {
|
|
if (this._propertyAdapter)
|
|
return this._propertyAdapter;
|
|
this._propertyAdapter = this._CreatePropertyAdapter();
|
|
return this._propertyAdapter
|
|
}
|
|
GetEditorIndex() {}
|
|
GetIndex() {
|
|
return this.GetEditorIndex()
|
|
}
|
|
GetTarget() {}
|
|
SetInitialState() {
|
|
this.GetPropertyAdapter().SetInitialState()
|
|
}
|
|
SetResumeState() {
|
|
this.GetPropertyAdapter().SetResumeState()
|
|
}
|
|
BeforeInterpolate() {
|
|
this.GetPropertyAdapter().BeforeChangeProperty()
|
|
}
|
|
Interpolate(time, start, end, setTime, noChange, ensureValue) {
|
|
const interpolateFunc = NS.PropertySourceAdapter.GetInterpolateFunc(this._propertyTrack);
|
|
const value = interpolateFunc(time, start, end, this._propertyTrack);
|
|
if (noChange)
|
|
return value;
|
|
return this.GetPropertyAdapter().ChangeProperty(time, value, start, end, setTime, ensureValue)
|
|
}
|
|
AfterInterpolate() {
|
|
this.GetPropertyAdapter().AfterChangeProperty()
|
|
}
|
|
SaveState() {
|
|
this.GetPropertyAdapter().SetSaveState()
|
|
}
|
|
ClearSaveState() {
|
|
this.GetPropertyAdapter().ClearSaveState()
|
|
}
|
|
GetCurrentState() {
|
|
return this.GetPropertyAdapter().GetCurrentState()
|
|
}
|
|
CompareInitialStateWithCurrent() {
|
|
return this.GetPropertyAdapter().CompareInitialStateWithCurrent()
|
|
}
|
|
CompareSaveStateWithCurrent() {
|
|
return this.GetPropertyAdapter().CompareSaveStateWithCurrent()
|
|
}
|
|
GetValueAtTime() {
|
|
return NS.PropertySourceAdapter.GetValueAtTime(this._propertyTrack)
|
|
}
|
|
_CreatePropertyAdapter() {
|
|
const propertyType = this._propertyTrack.GetPropertyType();
|
|
const keyframePropertyType = this._propertyTrack.GetPropertyKeyframeType();
|
|
switch (keyframePropertyType) {
|
|
case "combo":
|
|
case "boolean":
|
|
case "text":
|
|
case "string":
|
|
{
|
|
return new NS.PropertyInterpolationAdapter.NoInterpolationAdapter(this)
|
|
}
|
|
case "numeric":
|
|
case "number":
|
|
case "angle":
|
|
{
|
|
if (propertyType === "combo")
|
|
return new NS.PropertyInterpolationAdapter.NoInterpolationAdapter(this);
|
|
return new NS.PropertyInterpolationAdapter.NumericInterpolationAdapter(this)
|
|
}
|
|
case "color":
|
|
case "offsetColor":
|
|
{
|
|
return new NS.PropertyInterpolationAdapter.ColorInterpolationAdapter(this)
|
|
}
|
|
}
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"propertyAdapterJson": this.GetPropertyAdapter()._SaveToJson()
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this.GetPropertyAdapter()._LoadFromJson(o["propertyAdapterJson"])
|
|
}
|
|
static GetValueAtTime(propertyTrack) {
|
|
const track = propertyTrack.GetTrack();
|
|
const time = track.GetTimeline().GetTime();
|
|
const start = NS.GetStartPropertyKeyframeForTime(time, propertyTrack);
|
|
const end = NS.GetEndPropertyKeyframeForTime(time, propertyTrack);
|
|
const interpolateFunc = NS.PropertySourceAdapter.GetInterpolateFunc(propertyTrack);
|
|
return interpolateFunc(time, start, end, propertyTrack)
|
|
}
|
|
static GetValue(propertyTrack, initialValue, value) {
|
|
let resultMode = propertyTrack.GetResultMode();
|
|
if (propertyTrack.GetPropertyType() === "combo")
|
|
resultMode = "absolute";
|
|
switch (resultMode) {
|
|
case "relative":
|
|
return initialValue + value;
|
|
case "absolute":
|
|
return value
|
|
}
|
|
}
|
|
static GetInterpolateFunc(propertyTrack) {
|
|
const type = propertyTrack.GetPropertyKeyframeType();
|
|
switch (type) {
|
|
case "numeric":
|
|
return NS.NumericTypeAdapter.Interpolate;
|
|
case "angle":
|
|
return NS.AngleTypeAdapter.Interpolate;
|
|
case "boolean":
|
|
return NS.BooleanTypeAdapter.Interpolate;
|
|
case "color":
|
|
return NS.ColorTypeAdapter.Interpolate;
|
|
case "text":
|
|
return NS.TextTypeAdapter.Interpolate
|
|
}
|
|
}
|
|
static GetWillChangeFunc(propertyTrack) {
|
|
const type = propertyTrack.GetPropertyKeyframeType();
|
|
switch (type) {
|
|
case "numeric":
|
|
return NS.NumericTypeAdapter.WillChange;
|
|
case "angle":
|
|
return NS.AngleTypeAdapter.WillChange;
|
|
case "boolean":
|
|
return NS.BooleanTypeAdapter.WillChange;
|
|
case "color":
|
|
return NS.ColorTypeAdapter.WillChange;
|
|
case "text":
|
|
return NS.TextTypeAdapter.WillChange
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
class WorldInstanceSourceAdapter extends C3.PropertyTrackState.PropertySourceAdapter {
|
|
constructor(propertyTrack) {
|
|
super(propertyTrack)
|
|
}
|
|
}
|
|
C3.PropertyTrackState.WorldInstanceSourceAdapter = WorldInstanceSourceAdapter
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const INDEX = 0;
|
|
class InstanceVariableSourceAdapter extends C3.PropertyTrackState.PropertySourceAdapter {
|
|
constructor(propertyTrack) {
|
|
super(propertyTrack);
|
|
this._updatedIndex = NaN
|
|
}
|
|
GetEditorIndex() {
|
|
return this._propertyTrack.GetPropertyTrackDataItem().GetSourceAdapterArguments()[INDEX]
|
|
}
|
|
GetIndex() {
|
|
if (this._updatedIndex)
|
|
return this._updatedIndex;
|
|
return super.GetIndex()
|
|
}
|
|
GetTarget() {
|
|
return this._propertyTrack.GetTrack().GetInstance()
|
|
}
|
|
UpdateInstanceVariableIndex(index) {
|
|
const i = this._propertyTrack.GetPropertyTrackDataItem().GetSourceAdapterArguments()[INDEX];
|
|
if (i === index)
|
|
return;
|
|
this._updatedIndex = index
|
|
}
|
|
Interpolate(time, start, end, setTime, noChange, ensureValue) {
|
|
if (!this.GetPropertyAdapter().CanChange(start.GetValue()))
|
|
return;
|
|
return super.Interpolate(time, start, end, setTime, noChange, ensureValue)
|
|
}
|
|
_SaveToJson() {
|
|
return Object.assign(super._SaveToJson(), {
|
|
"index": this._updatedIndex
|
|
})
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
super._LoadFromJson(o);
|
|
this._updatedIndex = o["index"]
|
|
}
|
|
}
|
|
C3.PropertyTrackState.InstanceVariableSourceAdapter = InstanceVariableSourceAdapter
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const SID = 0;
|
|
const INDEX = 1;
|
|
const NAME = 2;
|
|
class BehaviorSourceAdapter extends C3.PropertyTrackState.PropertySourceAdapter {
|
|
constructor(propertyTrack) {
|
|
super(propertyTrack);
|
|
this._sid = NaN
|
|
}
|
|
GetEditorIndex() {
|
|
const dataItem = this._propertyTrack.GetPropertyTrackDataItem();
|
|
return dataItem.GetSourceAdapterArguments()[INDEX]
|
|
}
|
|
GetTarget() {
|
|
const dataItem = this._propertyTrack.GetPropertyTrackDataItem();
|
|
const track = this._propertyTrack.GetTrack();
|
|
const sid = this._sid ? this._sid : dataItem.GetSourceAdapterArguments()[SID];
|
|
const instance = track.GetInstance();
|
|
const index = instance.GetBehaviorIndexBySID(sid);
|
|
const behaviorInstance = instance.GetBehaviorInstances()[index];
|
|
return behaviorInstance.GetSdkInstance()
|
|
}
|
|
GetBehaviorType(objectClass) {
|
|
const dataItem = this._propertyTrack.GetPropertyTrackDataItem();
|
|
const name = dataItem.GetSourceAdapterArguments()[NAME];
|
|
return objectClass.GetBehaviorTypeByName(name)
|
|
}
|
|
UpdateBehaviorTypeSid(sid) {
|
|
const dataItem = this._propertyTrack.GetPropertyTrackDataItem();
|
|
if (dataItem.GetSourceAdapterArguments()[SID] === sid)
|
|
return;
|
|
this._sid = sid
|
|
}
|
|
Interpolate(time, start, end, setTime, noChange, ensureValue) {
|
|
const track = this._propertyTrack.GetTrack();
|
|
const instance = track.GetInstance();
|
|
if (!this.GetBehaviorType(instance.GetObjectClass()))
|
|
return;
|
|
return super.Interpolate(time, start, end, setTime, noChange, ensureValue)
|
|
}
|
|
_SaveToJson() {
|
|
return Object.assign(super._SaveToJson(), {
|
|
"sid": this._sid
|
|
})
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
super._LoadFromJson(o);
|
|
this._sid = o["sid"]
|
|
}
|
|
}
|
|
C3.PropertyTrackState.BehaviorSourceAdapter = BehaviorSourceAdapter
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const NAME = 0;
|
|
const INDEX = 1;
|
|
class EffectSourceAdapter extends C3.PropertyTrackState.PropertySourceAdapter {
|
|
constructor(propertyTrack) {
|
|
super(propertyTrack)
|
|
}
|
|
GetEditorIndex() {
|
|
return this._propertyTrack.GetPropertyTrackDataItem().GetSourceAdapterArguments()[INDEX]
|
|
}
|
|
GetTarget() {
|
|
const pTrack = this._propertyTrack;
|
|
const track = pTrack.GetTrack();
|
|
const worldInfo = track.GetWorldInfo();
|
|
const instanceEffectList = worldInfo.GetInstanceEffectList();
|
|
const effectList = instanceEffectList.GetEffectList();
|
|
const effectType = this.GetEffectType(effectList);
|
|
const effectIndex = effectType.GetIndex();
|
|
if (instanceEffectList.IsEffectIndexActive(effectIndex))
|
|
return instanceEffectList.GetEffectParametersForIndex(effectIndex);
|
|
return null
|
|
}
|
|
GetEffectType(effectList) {
|
|
const pTrack = this._propertyTrack;
|
|
const name = pTrack.GetPropertyTrackDataItem().GetSourceAdapterArguments()[NAME];
|
|
return effectList.GetEffectTypeByName(name)
|
|
}
|
|
Interpolate(time, start, end, setTime, noChange, ensureValue) {
|
|
if (!this._IsEffectActive())
|
|
return;
|
|
return super.Interpolate(time, start, end, setTime, noChange, ensureValue)
|
|
}
|
|
_IsEffectActive() {
|
|
const pTrack = this._propertyTrack;
|
|
const track = pTrack.GetTrack();
|
|
const worldInfo = track.GetWorldInfo();
|
|
const instanceEffectList = worldInfo.GetInstanceEffectList();
|
|
const effectList = instanceEffectList.GetEffectList();
|
|
const effectType = this.GetEffectType(effectList);
|
|
if (!effectType)
|
|
return;
|
|
const effectIndex = effectType.GetIndex();
|
|
return instanceEffectList.IsEffectIndexActive(effectIndex)
|
|
}
|
|
}
|
|
C3.PropertyTrackState.EffectSourceAdapter = EffectSourceAdapter
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const INDEX = 0;
|
|
class PluginSourceAdapter extends C3.PropertyTrackState.PropertySourceAdapter {
|
|
constructor(propertyTrack) {
|
|
super(propertyTrack)
|
|
}
|
|
GetEditorIndex() {
|
|
return this._propertyTrack.GetPropertyTrackDataItem().GetSourceAdapterArguments()[INDEX]
|
|
}
|
|
GetTarget() {
|
|
return this._propertyTrack.GetTrack().GetInstance().GetSdkInstance()
|
|
}
|
|
Interpolate(time, start, end, setTime, noChange, ensureValue) {
|
|
const track = this._propertyTrack.GetTrack();
|
|
const templatePlugin = track.GetObjectClass().GetPlugin();
|
|
const currentPlugin = track.GetInstance().GetObjectClass().GetPlugin();
|
|
if (templatePlugin !== currentPlugin)
|
|
return;
|
|
return super.Interpolate(time, start, end, setTime, noChange, ensureValue)
|
|
}
|
|
}
|
|
C3.PropertyTrackState.PluginSourceAdapter = PluginSourceAdapter
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
class ValueSourceAdapter extends C3.PropertyTrackState.PropertySourceAdapter {
|
|
constructor(propertyTrack) {
|
|
super(propertyTrack);
|
|
this._value = 0;
|
|
this._init = false
|
|
}
|
|
SetInitialState() {
|
|
const propertyTrackData = this._propertyTrack.GetPropertyTrackData();
|
|
let propertyTrackDataItem = this._propertyTrack.GetPropertyTrackDataItem();
|
|
propertyTrackDataItem = propertyTrackData.GetFirstPropertyKeyframeDataItem(propertyTrackDataItem);
|
|
this._value = propertyTrackDataItem.GetValueWithResultMode()
|
|
}
|
|
SetResumeState() {}
|
|
GetValue() {
|
|
if (!this._init)
|
|
this._propertyTrack.Interpolate(0);
|
|
return this._value
|
|
}
|
|
Interpolate(time, start, end, setTime, noChange, ensureValue) {
|
|
const interpolateFunc = C3.PropertyTrackState.NumericTypeAdapter.Interpolate;
|
|
this._value = interpolateFunc(time, start, end, this._propertyTrack);
|
|
this._init = true
|
|
}
|
|
SaveState() {}
|
|
ClearSaveState() {}
|
|
GetCurrentState() {
|
|
return this._value
|
|
}
|
|
CompareInitialStateWithCurrent() {
|
|
return false
|
|
}
|
|
CompareSaveStateWithCurrent() {
|
|
return false
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"value": this._value,
|
|
"init": this._init
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this._value = o["value"];
|
|
this._init = o.hasOwnProperty("init") ? o["init"] : true
|
|
}
|
|
}
|
|
C3.PropertyTrackState.ValueSourceAdapter = ValueSourceAdapter
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.PropertyTrackState.PropertyInterpolationAdapter = class PropertyInterpolationAdapter {
|
|
constructor(sourceAdapter) {
|
|
this._sourceAdapter = sourceAdapter;
|
|
this._propertyTrack = sourceAdapter.GetPropertyTrack();
|
|
this._worldInfo = this._propertyTrack.GetTrack().GetWorldInfo();
|
|
this._property = this._propertyTrack.GetPropertyName();
|
|
this._firstAbsoluteUpdate = false;
|
|
this._saveState = null;
|
|
this._target = null
|
|
}
|
|
Release() {
|
|
this._sourceAdapter = null;
|
|
this._propertyTrack = null;
|
|
this._worldInfo = null;
|
|
this._saveState = null;
|
|
this._target = null
|
|
}
|
|
CleanCaches() {
|
|
this._worldInfo = null;
|
|
this._saveState = null;
|
|
this._target = null
|
|
}
|
|
GetPropertyTrack() {
|
|
return this._propertyTrack
|
|
}
|
|
GetWorldInfo() {
|
|
if (this._worldInfo)
|
|
return this._worldInfo;
|
|
this._worldInfo = this._propertyTrack.GetTrack().GetWorldInfo();
|
|
return this._worldInfo
|
|
}
|
|
SetFirstAbsoluteUpdate(f) {
|
|
this._firstAbsoluteUpdate = !!f
|
|
}
|
|
GetFirstAbsoluteUpdate() {
|
|
return this._firstAbsoluteUpdate
|
|
}
|
|
SetInitialState() {}
|
|
SetResumeState() {}
|
|
SetSaveState() {
|
|
this._saveState = this.GetCurrentState()
|
|
}
|
|
ClearSaveState() {
|
|
this._saveState = null
|
|
}
|
|
GetCurrentState() {}
|
|
CompareInitialStateWithCurrent() {}
|
|
CompareSaveStateWithCurrent() {}
|
|
CanChange(value) {
|
|
const targetType = typeof this._Getter();
|
|
const newType = typeof value;
|
|
return targetType === newType
|
|
}
|
|
BeforeChangeProperty() {}
|
|
ChangeProperty(time, value, start, end, setTime) {}
|
|
AfterChangeProperty() {}
|
|
_FirstKeyframeGetter() {
|
|
const propertyKeyframeDataItem = this._PickTimelinePlaybackMode(()=>{
|
|
const propertyTrackDataItem = this._propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = this._propertyTrack.GetPropertyTrackData();
|
|
return propertyTrackData.GetFirstPropertyKeyframeDataItem(propertyTrackDataItem)
|
|
}
|
|
, ()=>{
|
|
const propertyTrackDataItem = this._propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = this._propertyTrack.GetPropertyTrackData();
|
|
return propertyTrackData.GetLastPropertyKeyframeDataItem(propertyTrackDataItem)
|
|
}
|
|
);
|
|
return propertyKeyframeDataItem.GetAbsoluteValue()
|
|
}
|
|
_CurrentKeyframeGetter() {
|
|
const timeline = this._propertyTrack.GetTimeline();
|
|
const time = timeline.GetTime() - this._propertyTrack.GetTrack().GetStartOffset();
|
|
const propertyKeyframe = this._PickTimelinePlaybackMode(()=>{
|
|
const propertyTrackDataItem = this._propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = this._propertyTrack.GetPropertyTrackData();
|
|
return propertyTrackData.GetFirstPropertyKeyFrameDataItemLowerOrEqualThan(time, propertyTrackDataItem)
|
|
}
|
|
, ()=>{
|
|
const propertyTrackDataItem = this._propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = this._propertyTrack.GetPropertyTrackData();
|
|
const ret = propertyTrackData.GetFirstPropertyKeyFrameDataItemHigherOrEqualThan(time, propertyTrackDataItem);
|
|
if (!ret)
|
|
return propertyTrackData.GetLastPropertyKeyframeDataItem(propertyTrackDataItem);
|
|
return ret
|
|
}
|
|
);
|
|
return propertyKeyframe.GetAbsoluteValue()
|
|
}
|
|
_PickTimelinePlaybackMode(forwardFunc, backwardFunc) {
|
|
const timeline = this._propertyTrack.GetTimeline();
|
|
return timeline.IsForwardPlayBack() ? forwardFunc() : backwardFunc()
|
|
}
|
|
_PickResultMode(relativeFunc, absoluteFunc) {
|
|
const resultMode = this._propertyTrack.GetResultMode();
|
|
return resultMode === "relative" ? relativeFunc() : absoluteFunc()
|
|
}
|
|
_PickFirstAbsoluteUpdate(firstFunc, otherFunc) {
|
|
if (this.GetFirstAbsoluteUpdate()) {
|
|
this.SetFirstAbsoluteUpdate(false);
|
|
return firstFunc()
|
|
} else
|
|
return otherFunc()
|
|
}
|
|
_GetAbsoluteInitialValue(keyframeValue) {}
|
|
_GetIndex() {
|
|
return this._sourceAdapter.GetIndex()
|
|
}
|
|
_GetTarget() {
|
|
if (this._target)
|
|
return this._target;
|
|
this._target = this._sourceAdapter.GetTarget();
|
|
return this._target
|
|
}
|
|
_PickSource(bFunc, eFunc, ivFunc, pFunc, wiFunc) {
|
|
const id = this._propertyTrack.GetSourceAdapterId();
|
|
switch (id) {
|
|
case "behavior":
|
|
return bFunc();
|
|
case "effect":
|
|
return eFunc();
|
|
case "instance-variable":
|
|
return ivFunc();
|
|
case "plugin":
|
|
return pFunc();
|
|
case "world-instance":
|
|
return wiFunc()
|
|
}
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"firstAbsoluteUpdate": this._firstAbsoluteUpdate,
|
|
"saveState": this._saveState
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this._firstAbsoluteUpdate = o["firstAbsoluteUpdate"];
|
|
this._saveState = o["saveState"]
|
|
}
|
|
_GetPropertyKeyframeStubs(propertyTracks, firstOnly=false) {
|
|
const ret = [];
|
|
for (const propertyTrack of propertyTracks) {
|
|
const startOffset = propertyTrack.GetTrack().GetStartOffset();
|
|
for (const propertyKeyframeDataItem of propertyTrack.GetPropertyKeyframeDataItems())
|
|
if (firstOnly && propertyKeyframeDataItem.GetTime() === 0)
|
|
ret.push({
|
|
time: startOffset + propertyKeyframeDataItem.GetTime(),
|
|
value: propertyKeyframeDataItem.GetAbsoluteValue()
|
|
});
|
|
else if (!firstOnly)
|
|
ret.push({
|
|
time: startOffset + propertyKeyframeDataItem.GetTime(),
|
|
value: propertyKeyframeDataItem.GetAbsoluteValue()
|
|
})
|
|
}
|
|
return ret.sort((f,s)=>f.time - s.time)
|
|
}
|
|
_GetLastPropertyKeyframeStub(timeline, time, propertyKeyframeStubs) {
|
|
return this._GetPropertyKeyframeStubLowerThanPlayhead(time, propertyKeyframeStubs)
|
|
}
|
|
_GetPropertyKeyframeStubLowerThanPlayhead(time, propertyKeyframeStubs) {
|
|
for (let i = propertyKeyframeStubs.length - 1; i >= 0; i--) {
|
|
const stubTime = propertyKeyframeStubs[i].time;
|
|
if (stubTime <= time)
|
|
return propertyKeyframeStubs[i]
|
|
}
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const TMP_COLORS_MAP = new Map;
|
|
const TMP_COLOR = [0, 0, 0];
|
|
class ColorInterpolationAdapter extends C3.PropertyTrackState.PropertyInterpolationAdapter {
|
|
constructor(sourceAdapter) {
|
|
super(sourceAdapter)
|
|
}
|
|
SetInitialState() {}
|
|
SetResumeState() {}
|
|
GetCurrentState() {
|
|
const id = this._propertyTrack.GetSourceAdapterId();
|
|
const target = this._GetTarget();
|
|
const index = this._GetIndex();
|
|
switch (id) {
|
|
case "behavior":
|
|
return this._ToColorArray(target.GetPropertyValueByIndex(index));
|
|
case "effect":
|
|
return this._ToColorArray(target[index]);
|
|
case "plugin":
|
|
return this._ToColorArray(target.GetPropertyValueByIndex(index));
|
|
case "world-instance":
|
|
return this._ToColorArray(this._Getter())
|
|
}
|
|
}
|
|
CompareInitialStateWithCurrent() {
|
|
const firstKeyframeColor = this._FirstKeyframeGetter();
|
|
return !this._CompareColors(firstKeyframeColor, this._Getter())
|
|
}
|
|
CompareSaveStateWithCurrent() {
|
|
if (C3.IsNullOrUndefined(this._saveState))
|
|
return false;
|
|
return !this._CompareColors(this._saveState, this._Getter())
|
|
}
|
|
_CompareColors(fColor, sColor) {
|
|
return fColor.equalsIgnoringAlpha(sColor)
|
|
}
|
|
_FirstKeyframeGetter() {
|
|
const color = super._FirstKeyframeGetter();
|
|
return this._GetColorFromArray(color)
|
|
}
|
|
_CurrentKeyframeGetter() {
|
|
const color = super._CurrentKeyframeGetter();
|
|
return this._GetColorFromArray(color)
|
|
}
|
|
_GetAbsoluteInitialValue(value) {}
|
|
_ToColorArray(color) {
|
|
if (C3.IsInstanceOf(color, C3.Color))
|
|
return color.toArray().slice(0, 3);
|
|
return color.slice(0, 3)
|
|
}
|
|
_GetColorFromArray(color) {
|
|
if (C3.IsInstanceOf(color, C3.Color))
|
|
return color;
|
|
return new C3.Color(color[0],color[1],color[2],1)
|
|
}
|
|
CanChange(value) {
|
|
return true
|
|
}
|
|
BeforeChangeProperty() {
|
|
const instance = this._propertyTrack.GetInstance();
|
|
if (!TMP_COLORS_MAP.has(instance))
|
|
TMP_COLORS_MAP.set(instance, new Map);
|
|
const instanceMap = TMP_COLORS_MAP.get(instance);
|
|
const id = this._propertyTrack.GetSourceAdapterId();
|
|
if (!instanceMap.has(id))
|
|
instanceMap.set(id, new Map);
|
|
const sourceMap = instanceMap.get(id);
|
|
if (!sourceMap.has(this._property))
|
|
sourceMap.set(this._property, {
|
|
used: false,
|
|
color: new C3.Color(0,0,0,1)
|
|
})
|
|
}
|
|
_GetTmpColor(instance, sourceId, propertyName) {
|
|
const tmpColorObj = TMP_COLORS_MAP.get(instance).get(sourceId).get(propertyName);
|
|
tmpColorObj.used = true;
|
|
return tmpColorObj.color
|
|
}
|
|
ChangeProperty(time, value, start, end, setTime) {
|
|
const timeline = this._propertyTrack.GetTimeline();
|
|
const track = this._propertyTrack.GetTrack();
|
|
const instance = this._propertyTrack.GetInstance();
|
|
const sourceAdapter = this._propertyTrack.GetSourceAdapter();
|
|
const sourceAdapterId = this._propertyTrack.GetSourceAdapterId();
|
|
const property = this._property;
|
|
const propertyTracks = timeline.GetSimilarPropertyTracks(instance, sourceAdapter, property);
|
|
if (propertyTracks.length > 1) {
|
|
const propertyKeyframeStubs = this._GetPropertyKeyframeStubs(propertyTracks, true);
|
|
const stub = this._GetLastPropertyKeyframeStub(timeline, timeline.GetTime(), propertyKeyframeStubs);
|
|
if (stub) {
|
|
const startOffset = track.GetStartOffset();
|
|
const t = stub.time - startOffset;
|
|
if (t === 0)
|
|
this._GetTmpColor(instance, sourceAdapterId, this._property).addRgb(value[0], value[1], value[2]);
|
|
else {
|
|
if (t < 0)
|
|
return;
|
|
const r = value[0];
|
|
const g = value[1];
|
|
const b = value[2];
|
|
const v = this._propertyTrack.Interpolate(t, false, true);
|
|
const dr = C3.Color.DiffChannel(r, v[0]);
|
|
const dg = C3.Color.DiffChannel(g, v[1]);
|
|
const db = C3.Color.DiffChannel(b, v[2]);
|
|
this._GetTmpColor(instance, sourceAdapterId, this._property).addRgb(dr, dg, db)
|
|
}
|
|
}
|
|
} else
|
|
this._Setter(value[0], value[1], value[2]);
|
|
return C3.TimelineState.LAYOUT_RENDER_CHANGE
|
|
}
|
|
AfterChangeProperty() {
|
|
const instance = this._propertyTrack.GetInstance();
|
|
if (!TMP_COLORS_MAP.has(instance))
|
|
return;
|
|
const instanceMap = TMP_COLORS_MAP.get(instance);
|
|
const id = this._propertyTrack.GetSourceAdapterId();
|
|
if (!instanceMap.has(id))
|
|
return;
|
|
const sourceMap = instanceMap.get(id);
|
|
if (!sourceMap.has(this._property))
|
|
return;
|
|
const tmpColorObj = sourceMap.get(this._property);
|
|
const used = tmpColorObj.used;
|
|
const color = tmpColorObj.color;
|
|
if (used)
|
|
this._Setter(color.getR(), color.getG(), color.getB());
|
|
if (sourceMap.size === 0)
|
|
instanceMap.delete(id);
|
|
if (instanceMap.size === 0)
|
|
TMP_COLORS_MAP.delete(instance)
|
|
}
|
|
_Getter() {
|
|
const id = this._propertyTrack.GetSourceAdapterId();
|
|
const target = this._GetTarget();
|
|
const index = this._GetIndex();
|
|
switch (id) {
|
|
case "behavior":
|
|
return this._GetColorFromArray(target.GetPropertyValueByIndex(index));
|
|
case "effect":
|
|
return target[index].clone();
|
|
case "plugin":
|
|
return this._GetColorFromArray(target.GetPropertyValueByIndex(index));
|
|
case "world-instance":
|
|
return this.GetWorldInfo().GetUnpremultipliedColor().clone()
|
|
}
|
|
}
|
|
_Setter(r, g, b) {
|
|
const id = this._propertyTrack.GetSourceAdapterId();
|
|
const target = this._GetTarget();
|
|
const index = this._GetIndex();
|
|
switch (id) {
|
|
case "behavior":
|
|
TMP_COLOR[0] = r;
|
|
TMP_COLOR[1] = g;
|
|
TMP_COLOR[2] = b;
|
|
target.SetPropertyValueByIndex(index, TMP_COLOR);
|
|
break;
|
|
case "effect":
|
|
target[index].setRgb(r, g, b);
|
|
break;
|
|
case "plugin":
|
|
TMP_COLOR[0] = r;
|
|
TMP_COLOR[1] = g;
|
|
TMP_COLOR[2] = b;
|
|
target.SetPropertyValueByIndex(index, TMP_COLOR);
|
|
break;
|
|
case "world-instance":
|
|
this.GetWorldInfo().SetUnpremultipliedColorRGB(r, g, b);
|
|
break
|
|
}
|
|
}
|
|
_SaveToJson() {}
|
|
_LoadFromJson(o) {}
|
|
}
|
|
C3.PropertyTrackState.PropertyInterpolationAdapter.ColorInterpolationAdapter = ColorInterpolationAdapter
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
class NoInterpolationAdapter extends C3.PropertyTrackState.PropertyInterpolationAdapter {
|
|
constructor(sourceAdapter) {
|
|
super(sourceAdapter)
|
|
}
|
|
SetInitialState() {}
|
|
SetResumeState() {}
|
|
GetCurrentState() {
|
|
return this._Getter()
|
|
}
|
|
CompareInitialStateWithCurrent() {
|
|
const firstKeyframeValue = this._FirstKeyframeGetter();
|
|
return firstKeyframeValue !== this.GetCurrentState()
|
|
}
|
|
CompareSaveStateWithCurrent() {
|
|
if (C3.IsNullOrUndefined(this._saveState))
|
|
return false;
|
|
return this._saveState !== this.GetCurrentState()
|
|
}
|
|
ChangeProperty(time, value, start, end, setTime) {
|
|
const willChangeFunc = C3.PropertyTrackState.PropertySourceAdapter.GetWillChangeFunc(this._propertyTrack);
|
|
const propertyTrack = this._propertyTrack;
|
|
const track = propertyTrack.GetTrack();
|
|
const id = propertyTrack.GetSourceAdapterId();
|
|
const timeline = propertyTrack.GetTimeline();
|
|
const instance = track.GetInstance();
|
|
const sourceAdapter = propertyTrack.GetSourceAdapter();
|
|
const property = this._property;
|
|
const propertyTracks = timeline.GetSimilarPropertyTracks(instance, sourceAdapter, property);
|
|
if (propertyTracks.length > 1) {
|
|
const propertyKeyframeStubs = this._GetPropertyKeyframeStubs(propertyTracks);
|
|
const t = time + track.GetStartOffset();
|
|
const stub = this._GetLastPropertyKeyframeStub(timeline, t, propertyKeyframeStubs);
|
|
if (stub)
|
|
value = stub.value
|
|
}
|
|
const change = willChangeFunc(this._GetIndex(), this._GetTarget(), value, id);
|
|
if (!change)
|
|
return;
|
|
this._Setter(value);
|
|
switch (id) {
|
|
case "behavior":
|
|
return;
|
|
case "effect":
|
|
return;
|
|
case "instance-variable":
|
|
return;
|
|
case "plugin":
|
|
return C3.TimelineState.LAYOUT_RENDER_CHANGE
|
|
}
|
|
}
|
|
_Getter() {
|
|
const id = this._propertyTrack.GetSourceAdapterId();
|
|
const target = this._GetTarget();
|
|
const index = this._GetIndex();
|
|
switch (id) {
|
|
case "behavior":
|
|
return target.GetPropertyValueByIndex(index);
|
|
case "effect":
|
|
return target[index];
|
|
case "instance-variable":
|
|
return target.GetInstanceVariableValue(index);
|
|
case "plugin":
|
|
return target.GetPropertyValueByIndex(index)
|
|
}
|
|
}
|
|
_Setter(value) {
|
|
const id = this._propertyTrack.GetSourceAdapterId();
|
|
const target = this._GetTarget();
|
|
const index = this._GetIndex();
|
|
switch (id) {
|
|
case "behavior":
|
|
target.SetPropertyValueByIndex(index, value);
|
|
break;
|
|
case "effect":
|
|
target[index] = value;
|
|
break;
|
|
case "instance-variable":
|
|
target.SetInstanceVariableValue(index, value);
|
|
break;
|
|
case "plugin":
|
|
target.SetPropertyValueByIndex(index, value);
|
|
break
|
|
}
|
|
}
|
|
}
|
|
C3.PropertyTrackState.PropertyInterpolationAdapter.NoInterpolationAdapter = NoInterpolationAdapter
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const NS = C3.PropertyTrackState.PropertyInterpolationAdapter;
|
|
const INSTANCE_FUNC_MAP = new Map;
|
|
const add = (prop,setter,absolute_setter,getter,round)=>INSTANCE_FUNC_MAP.set(prop, {
|
|
setter,
|
|
absolute_setter,
|
|
getter,
|
|
round
|
|
});
|
|
add("offsetX", (wi,v)=>wi.OffsetX(v), (wi,v)=>wi.SetX(v), wi=>wi.GetX(), true);
|
|
add("offsetY", (wi,v)=>wi.OffsetY(v), (wi,v)=>wi.SetY(v), wi=>wi.GetY(), true);
|
|
add("offsetWidth", (wi,v)=>wi.OffsetWidth(v), (wi,v)=>wi.SetWidth(v), wi=>wi.GetWidth(), true);
|
|
add("offsetHeight", (wi,v)=>wi.OffsetHeight(v), (wi,v)=>wi.SetHeight(v), wi=>wi.GetHeight(), true);
|
|
add("offsetAngle", (wi,v)=>wi.OffsetAngle(v), (wi,v)=>wi.SetAngle(v), wi=>wi.GetAngle(), false);
|
|
add("offsetOpacity", (wi,v)=>wi.OffsetOpacity(v), (wi,v)=>wi.SetOpacity(v), wi=>wi.GetOpacity(), false);
|
|
add("offsetOriginX", (wi,v)=>wi.OffsetOriginX(v), (wi,v)=>wi.SetOriginX(v), wi=>wi.GetOriginX(), false);
|
|
add("offsetOriginY", (wi,v)=>wi.OffsetOriginY(v), (wi,v)=>wi.SetOriginY(v), wi=>wi.GetOriginY(), false);
|
|
add("offsetZElevation", (wi,v)=>wi.OffsetZElevation(v), (wi,v)=>wi.SetZElevation(v), wi=>wi.GetZElevation(), true);
|
|
add("offsetScaleX", (wi,v,t)=>{
|
|
wi.OffsetWidth(t.GetOriginalWidth() * v)
|
|
}
|
|
, (wi,v,t)=>{
|
|
wi.SetWidth(t.GetOriginalWidth() * v)
|
|
}
|
|
, (wi,t)=>{
|
|
return wi.GetWidth() / t.GetOriginalWidth()
|
|
}
|
|
, false);
|
|
add("offsetScaleY", (wi,v,t)=>{
|
|
wi.OffsetHeight(t.GetOriginalHeight() * v)
|
|
}
|
|
, (wi,v,t)=>{
|
|
wi.SetHeight(t.GetOriginalHeight() * v)
|
|
}
|
|
, (wi,t)=>{
|
|
return wi.GetHeight() / t.GetOriginalHeight()
|
|
}
|
|
, false);
|
|
class NumericInterpolationAdapter extends C3.PropertyTrackState.PropertyInterpolationAdapter {
|
|
constructor(sourceAdapter) {
|
|
super(sourceAdapter);
|
|
this._lastValue = 0;
|
|
this._instance_getter = null;
|
|
this._instance_setter = null;
|
|
this._instance_absolute_setter = null;
|
|
this._round = false;
|
|
if (C3.IsInstanceOf(this._propertyTrack.GetTimeline(), C3.Tween))
|
|
this._typeAdapter = new C3.PropertyTrackState.PropertyInterpolationAdapter.NumericInterpolationAdapterForTween(this);
|
|
else
|
|
this._typeAdapter = new C3.PropertyTrackState.PropertyInterpolationAdapter.NumericInterpolationAdapterForTimeline(this);
|
|
const property = this._propertyTrack.GetPropertyName();
|
|
if (this._propertyTrack.GetSourceAdapterId() === "world-instance") {
|
|
const p = INSTANCE_FUNC_MAP.get(property);
|
|
this._instance_getter = p.getter;
|
|
this._instance_setter = p.setter;
|
|
this._instance_absolute_setter = p.absolute_setter;
|
|
this._round = p.round
|
|
}
|
|
}
|
|
Release() {
|
|
this._typeAdapter = null;
|
|
this._instance_getter = null;
|
|
this._instance_setter = null;
|
|
this._instance_absolute_setter = null;
|
|
super.Release()
|
|
}
|
|
GetLastValue() {
|
|
return this._lastValue
|
|
}
|
|
SetLastValue(v) {
|
|
this._lastValue = v
|
|
}
|
|
SetInitialState() {
|
|
const initValue = this._typeAdapter.SetInitialState();
|
|
if (typeof initValue === "number")
|
|
this._lastValue = initValue
|
|
}
|
|
SetResumeState() {
|
|
const resumeValue = this._typeAdapter.SetResumeState();
|
|
if (typeof resumeValue === "number")
|
|
this._lastValue = resumeValue
|
|
}
|
|
GetCurrentState() {
|
|
return this._Getter()
|
|
}
|
|
CompareInitialStateWithCurrent() {
|
|
const firstKeyframeValue = this._FirstKeyframeGetter();
|
|
return firstKeyframeValue !== this.GetCurrentState()
|
|
}
|
|
CompareSaveStateWithCurrent() {
|
|
if (C3.IsNullOrUndefined(this._saveState))
|
|
return false;
|
|
return this._saveState !== this.GetCurrentState()
|
|
}
|
|
BeforeChangeProperty() {
|
|
this._typeAdapter.BeforeChangeProperty()
|
|
}
|
|
ChangeProperty(time, value, start, end, setTime, ensureValue) {
|
|
return this._typeAdapter.ChangeProperty(time, value, start, end, setTime, ensureValue)
|
|
}
|
|
AfterChangeProperty() {
|
|
this._typeAdapter.AfterChangeProperty()
|
|
}
|
|
_Getter() {
|
|
const target = this._GetTarget();
|
|
const index = this._GetIndex();
|
|
const track = this._propertyTrack.GetTrack();
|
|
const wi = this.GetWorldInfo();
|
|
return this._PickSource(()=>target.GetPropertyValueByIndex(index), ()=>target[index], ()=>target.GetInstanceVariableValue(index), ()=>target.GetPropertyValueByIndex(index), ()=>this._instance_getter(wi, track))
|
|
}
|
|
_Setter(value, start, end) {
|
|
const target = this._GetTarget();
|
|
const index = this._GetIndex();
|
|
const track = this._propertyTrack.GetTrack();
|
|
const wi = this.GetWorldInfo();
|
|
this._PickSource(()=>target.OffsetPropertyValueByIndex(index, value), ()=>target[index] += value, ()=>target.SetInstanceVariableOffset(index, value), ()=>target.OffsetPropertyValueByIndex(index, value), ()=>this._instance_setter(wi, value, track))
|
|
}
|
|
_SetterAbsolute(value, start, end) {
|
|
const target = this._GetTarget();
|
|
const index = this._GetIndex();
|
|
const track = this._propertyTrack.GetTrack();
|
|
const wi = this.GetWorldInfo();
|
|
this._PickSource(()=>target.SetPropertyValueByIndex(index, value), ()=>target[index] = value, ()=>target.SetInstanceVariableValue(index, value), ()=>target.SetPropertyValueByIndex(index, value), ()=>this._instance_absolute_setter(wi, value, track))
|
|
}
|
|
_MaybeEnsureValue(time, start, end, setTime, lastValue, currentValue) {
|
|
this._typeAdapter._MaybeEnsureValue(time, start, end, setTime, lastValue, currentValue)
|
|
}
|
|
_AddDelta(value, start, end) {
|
|
const stringValue = value.toString();
|
|
const decimalsString = stringValue.split(".")[1] || "";
|
|
const decimalPlaces = decimalsString.length;
|
|
const v = this._Getter();
|
|
let rv;
|
|
if (decimalPlaces === 0)
|
|
rv = this._round ? Math.round(v) : v;
|
|
else
|
|
rv = C3.toFixed(v, decimalPlaces);
|
|
this._Setter(rv - v, start, end)
|
|
}
|
|
_SaveToJson() {
|
|
return Object.assign(super._SaveToJson(), {
|
|
"v": this._lastValue
|
|
})
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
super._LoadFromJson(o);
|
|
this._lastValue = o["v"]
|
|
}
|
|
}
|
|
C3.PropertyTrackState.PropertyInterpolationAdapter.NumericInterpolationAdapter = NumericInterpolationAdapter
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const TMP_ABSOLUTE_VALUES_MAP = new Map;
|
|
class NumericInterpolationAdapterForTimeline {
|
|
constructor(numericInterpolationAdapter) {
|
|
this._numericInterpolationAdapter = numericInterpolationAdapter
|
|
}
|
|
Release() {
|
|
this._numericInterpolationAdapter = null
|
|
}
|
|
SetInitialState() {
|
|
const adapter = this._numericInterpolationAdapter;
|
|
const propertyTrack = this._numericInterpolationAdapter.GetPropertyTrack();
|
|
return adapter._PickResultMode(()=>{
|
|
return adapter._PickTimelinePlaybackMode(()=>0, ()=>C3.PropertyTrackState.PropertySourceAdapter.GetValueAtTime(propertyTrack))
|
|
}
|
|
, ()=>{}
|
|
)
|
|
}
|
|
SetResumeState() {}
|
|
BeforeChangeProperty() {
|
|
const adapter = this._numericInterpolationAdapter;
|
|
const propertyTrack = this._numericInterpolationAdapter.GetPropertyTrack();
|
|
const property = propertyTrack.GetPropertyName();
|
|
adapter._PickResultMode(()=>{}
|
|
, ()=>{
|
|
const instance = propertyTrack.GetInstance();
|
|
if (!TMP_ABSOLUTE_VALUES_MAP.has(instance))
|
|
TMP_ABSOLUTE_VALUES_MAP.set(instance, new Map);
|
|
const instanceMap = TMP_ABSOLUTE_VALUES_MAP.get(instance);
|
|
const id = propertyTrack.GetSourceAdapterId();
|
|
if (!instanceMap.has(id))
|
|
instanceMap.set(id, new Map);
|
|
const sourceMap = instanceMap.get(id);
|
|
if (!sourceMap.has(property))
|
|
sourceMap.set(property, {
|
|
used: false,
|
|
value: 0
|
|
})
|
|
}
|
|
)
|
|
}
|
|
_GetTmpAbsoluteValueObject(instance, sourceId, propertyName) {
|
|
const tmpAbsoluteValueObj = TMP_ABSOLUTE_VALUES_MAP.get(instance).get(sourceId).get(propertyName);
|
|
tmpAbsoluteValueObj.used = true;
|
|
return tmpAbsoluteValueObj
|
|
}
|
|
ChangeProperty(time, value, start, end, setTime, ensureValue) {
|
|
const adapter = this._numericInterpolationAdapter;
|
|
const propertyTrack = this._numericInterpolationAdapter.GetPropertyTrack();
|
|
const property = propertyTrack.GetPropertyName();
|
|
adapter._PickResultMode(()=>{
|
|
const lastValue = adapter.GetLastValue();
|
|
adapter._Setter(value - lastValue, start, end);
|
|
if (ensureValue)
|
|
this._MaybeEnsureValue(time, start, end, setTime, lastValue, value);
|
|
adapter.SetLastValue(value)
|
|
}
|
|
, ()=>{
|
|
const timeline = propertyTrack.GetTimeline();
|
|
const track = propertyTrack.GetTrack();
|
|
const instance = propertyTrack.GetInstance();
|
|
const sourceAdapter = propertyTrack.GetSourceAdapter();
|
|
const sourceAdapterId = propertyTrack.GetSourceAdapterId();
|
|
const propertyTracks = timeline.GetSimilarPropertyTracks(instance, sourceAdapter, property);
|
|
if (propertyTracks.length > 1) {
|
|
const propertyKeyframeStubs = adapter._GetPropertyKeyframeStubs(propertyTracks, true);
|
|
const stub = adapter._GetLastPropertyKeyframeStub(timeline, timeline.GetTime(), propertyKeyframeStubs);
|
|
if (stub) {
|
|
const startOffset = track.GetStartOffset();
|
|
const t = stub.time - startOffset;
|
|
if (t === 0) {
|
|
const valueObj = this._GetTmpAbsoluteValueObject(instance, sourceAdapterId, property);
|
|
valueObj.value += value
|
|
} else {
|
|
if (t < 0)
|
|
return;
|
|
const v = propertyTrack.Interpolate(t, false, true);
|
|
const valueObj = this._GetTmpAbsoluteValueObject(instance, sourceAdapterId, property);
|
|
valueObj.value += value - v
|
|
}
|
|
}
|
|
} else
|
|
adapter._SetterAbsolute(value)
|
|
}
|
|
);
|
|
return adapter._PickSource(()=>{}
|
|
, ()=>C3.TimelineState.LAYOUT_RENDER_CHANGE, ()=>{}
|
|
, ()=>C3.TimelineState.LAYOUT_RENDER_CHANGE, ()=>C3.TimelineState.LAYOUT_RENDER_CHANGE)
|
|
}
|
|
AfterChangeProperty() {
|
|
const adapter = this._numericInterpolationAdapter;
|
|
const propertyTrack = this._numericInterpolationAdapter.GetPropertyTrack();
|
|
const property = propertyTrack.GetPropertyName();
|
|
adapter._PickResultMode(()=>{}
|
|
, ()=>{
|
|
const instance = propertyTrack.GetInstance();
|
|
if (!TMP_ABSOLUTE_VALUES_MAP.has(instance))
|
|
return;
|
|
const instanceMap = TMP_ABSOLUTE_VALUES_MAP.get(instance);
|
|
const id = propertyTrack.GetSourceAdapterId();
|
|
if (!instanceMap.has(id))
|
|
return;
|
|
const sourceMap = instanceMap.get(id);
|
|
if (!sourceMap.has(property))
|
|
return;
|
|
const tmpValueObj = sourceMap.get(property);
|
|
const used = tmpValueObj.used;
|
|
const value = tmpValueObj.value;
|
|
if (used)
|
|
adapter._SetterAbsolute(value);
|
|
sourceMap.delete(property);
|
|
if (sourceMap.size === 0)
|
|
instanceMap.delete(id);
|
|
if (instanceMap.size === 0)
|
|
TMP_ABSOLUTE_VALUES_MAP.delete(instance)
|
|
}
|
|
)
|
|
}
|
|
_MaybeEnsureValue(time, start, end, setTime, lastValue, currentValue) {
|
|
const adapter = this._numericInterpolationAdapter;
|
|
if (setTime)
|
|
return;
|
|
if (start && time === start.GetTime())
|
|
adapter._AddDelta(start.GetValueWithResultMode(), start, end);
|
|
else if (end && time === end.GetTime())
|
|
adapter._AddDelta(end.GetValueWithResultMode(), start, end);
|
|
else if (currentValue - lastValue === 0)
|
|
adapter._AddDelta(start.GetValueWithResultMode(), start, end)
|
|
}
|
|
}
|
|
C3.PropertyTrackState.PropertyInterpolationAdapter.NumericInterpolationAdapterForTimeline = NumericInterpolationAdapterForTimeline
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const TMP_ABSOLUTE_VALUES_MAP = new Map;
|
|
class NumericInterpolationAdapterForTween {
|
|
constructor(numericInterpolationAdapter) {
|
|
this._numericInterpolationAdapter = numericInterpolationAdapter
|
|
}
|
|
Release() {
|
|
this._numericInterpolationAdapter = null
|
|
}
|
|
SetInitialState() {
|
|
const adapter = this._numericInterpolationAdapter;
|
|
adapter.SetFirstAbsoluteUpdate(true);
|
|
return this._GetAbsoluteInitialValue(adapter._FirstKeyframeGetter())
|
|
}
|
|
SetResumeState() {
|
|
const adapter = this._numericInterpolationAdapter;
|
|
if (adapter._FirstKeyframeGetter() === adapter._CurrentKeyframeGetter())
|
|
return;
|
|
adapter.SetFirstAbsoluteUpdate(true);
|
|
return this._GetAbsoluteInitialValue(adapter._CurrentKeyframeGetter())
|
|
}
|
|
BeforeChangeProperty() {}
|
|
ChangeProperty(time, value, start, end, setTime, ensureValue) {
|
|
const adapter = this._numericInterpolationAdapter;
|
|
const lastValue = adapter.GetLastValue();
|
|
adapter._PickResultMode(()=>{
|
|
adapter._Setter(value - lastValue, start, end);
|
|
if (ensureValue)
|
|
this._MaybeEnsureValue(time, start, end, setTime, lastValue, value)
|
|
}
|
|
, ()=>{
|
|
adapter._PickFirstAbsoluteUpdate(()=>{
|
|
adapter._Setter(lastValue, start, end)
|
|
}
|
|
, ()=>{
|
|
adapter._Setter(value - lastValue, start, end);
|
|
if (ensureValue)
|
|
this._MaybeEnsureValue(time, start, end, setTime, lastValue, value)
|
|
}
|
|
)
|
|
}
|
|
);
|
|
adapter.SetLastValue(value);
|
|
return adapter._PickSource(()=>{}
|
|
, ()=>C3.TimelineState.LAYOUT_RENDER_CHANGE, ()=>{}
|
|
, ()=>C3.TimelineState.LAYOUT_RENDER_CHANGE, ()=>C3.TimelineState.LAYOUT_RENDER_CHANGE)
|
|
}
|
|
AfterChangeProperty() {}
|
|
_GetAbsoluteInitialValue(keyframeValue) {
|
|
const adapter = this._numericInterpolationAdapter;
|
|
return keyframeValue - adapter.GetCurrentState()
|
|
}
|
|
_MaybeEnsureValue(time, start, end, setTime, lastValue, currentValue) {
|
|
const adapter = this._numericInterpolationAdapter;
|
|
if (setTime)
|
|
if (start && time === start.GetTime())
|
|
adapter._AddDelta(start.GetValueWithResultMode(), start, end);
|
|
else if (end && time === end.GetTime())
|
|
adapter._AddDelta(end.GetValueWithResultMode(), start, end);
|
|
else {
|
|
if (!end)
|
|
adapter._AddDelta(start.GetValueWithResultMode(), start, end)
|
|
}
|
|
else if (start && time === start.GetTime())
|
|
adapter._AddDelta(start.GetValueWithResultMode(), start, end);
|
|
else if (end && time === end.GetTime())
|
|
adapter._AddDelta(end.GetValueWithResultMode(), start, end);
|
|
else if (currentValue - lastValue === 0)
|
|
adapter._AddDelta(start.GetValueWithResultMode(), start, end)
|
|
}
|
|
}
|
|
C3.PropertyTrackState.PropertyInterpolationAdapter.NumericInterpolationAdapterForTween = NumericInterpolationAdapterForTween
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const Ease = self.Ease;
|
|
C3.PropertyTrackState.NumericTypeAdapter = class NumericTypeAdapter {
|
|
constructor() {}
|
|
static WillChange(index, source, newValue, type) {
|
|
let oldValue;
|
|
switch (type) {
|
|
case "behavior":
|
|
oldValue = source.GetPropertyValueByIndex(index);
|
|
break;
|
|
case "effect":
|
|
oldValue = source[index];
|
|
break;
|
|
case "instance-variable":
|
|
oldValue = source.GetInstanceVariableValue(index);
|
|
break;
|
|
case "plugin":
|
|
oldValue = source.GetPropertyValueByIndex(index);
|
|
break
|
|
}
|
|
if (oldValue === newValue)
|
|
return false;
|
|
return true
|
|
}
|
|
static Interpolate(time, start, end, propertyTrack) {
|
|
if (!end) {
|
|
let propertyTrackDataItem = propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = propertyTrack.GetPropertyTrackData();
|
|
propertyTrackDataItem = propertyTrackData.GetLastPropertyKeyframeDataItem(propertyTrackDataItem);
|
|
return propertyTrackDataItem.GetValueWithResultMode()
|
|
}
|
|
let mode = propertyTrack.GetInterpolationMode();
|
|
if (mode === "default")
|
|
mode = "continuous";
|
|
if (propertyTrack.GetPropertyType() === "combo")
|
|
mode = "discrete";
|
|
if (mode === "discrete")
|
|
return start.GetValueWithResultMode();
|
|
else if (mode === "continuous" || mode === "step") {
|
|
if (mode === "step") {
|
|
const step = propertyTrack.GetTimeline().GetStep();
|
|
if (step !== 0) {
|
|
const s = 1 / step;
|
|
time = Math.floor(time * s) / s
|
|
}
|
|
}
|
|
const st = start.GetTime();
|
|
const et = end.GetTime();
|
|
const sv = start.GetValueWithResultMode();
|
|
const ev = end.GetValueWithResultMode();
|
|
if (sv === ev)
|
|
return sv;
|
|
const n = C3.normalize(time, st, et);
|
|
const e = start.GetEase();
|
|
let ret;
|
|
const startAddon = start.GetAddOn("cubic-bezier");
|
|
const endAddon = end.GetAddOn("cubic-bezier");
|
|
if (startAddon && startAddon.GetStartEnable() && endAddon && endAddon.GetEndEnable()) {
|
|
const dt = et - st;
|
|
ret = Ease.GetRuntimeEase(e)(dt * n, 0, 1, dt);
|
|
ret = Ease.GetRuntimeEase("cubicbezier")(ret, sv, sv + startAddon.GetStartAnchor(), ev + endAddon.GetEndAnchor(), ev)
|
|
} else
|
|
ret = Ease.GetRuntimeEase(e)((et - st) * n, sv, ev - sv, et - st);
|
|
if (propertyTrack.GetPropertyType() === "integer")
|
|
return Math.floor(ret);
|
|
return ret
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.PropertyTrackState.AngleTypeAdapter = class AngleTypeAdapter {
|
|
constructor() {}
|
|
static WillChange(index, source, newValue, type) {
|
|
let oldValue;
|
|
switch (type) {
|
|
case "behavior":
|
|
oldValue = source.GetPropertyValueByIndex(index);
|
|
break;
|
|
case "effect":
|
|
oldValue = source[index];
|
|
break;
|
|
case "instance-variable":
|
|
oldValue = source.GetInstanceVariableValue(index);
|
|
break;
|
|
case "plugin":
|
|
oldValue = source.GetPropertyValueByIndex(index);
|
|
break
|
|
}
|
|
if (oldValue === newValue)
|
|
return false;
|
|
return true
|
|
}
|
|
static Interpolate(time, start, end, propertyTrack) {
|
|
if (!end) {
|
|
let propertyTrackDataItem = propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = propertyTrack.GetPropertyTrackData();
|
|
propertyTrackDataItem = propertyTrackData.GetLastPropertyKeyframeDataItem(propertyTrackDataItem);
|
|
return propertyTrackDataItem.GetValueWithResultMode()
|
|
}
|
|
let mode = propertyTrack.GetInterpolationMode();
|
|
if (mode === "default")
|
|
mode = "continuous";
|
|
if (propertyTrack.GetPropertyType() === "combo")
|
|
mode = "discrete";
|
|
if (mode === "discrete")
|
|
return start.GetValueWithResultMode();
|
|
else if (mode === "continuous" || mode === "step") {
|
|
if (mode === "step") {
|
|
const step = propertyTrack.GetTimeline().GetStep();
|
|
if (step !== 0) {
|
|
const s = 1 / step;
|
|
time = Math.floor(time * s) / s
|
|
}
|
|
}
|
|
const st = start.GetTime();
|
|
const et = end.GetTime();
|
|
const sv = start.GetValueWithResultMode();
|
|
const ev = end.GetValueWithResultMode();
|
|
const angleAddon = start.GetAddOn("angle");
|
|
if (angleAddon) {
|
|
const revolutions = angleAddon.GetRevolutions();
|
|
if (sv === ev && revolutions === 0)
|
|
return sv;
|
|
const n = C3.normalize(time, st, et);
|
|
const easeFunc = self.Ease.GetRuntimeEase(start.GetEase());
|
|
const easeRes = easeFunc(n, 0, 1, 1);
|
|
switch (angleAddon.GetDirection()) {
|
|
case "closest":
|
|
return C3.angleLerp(sv, ev, easeRes, revolutions);
|
|
case "clockwise":
|
|
return C3.angleLerpClockwise(sv, ev, easeRes, revolutions);
|
|
case "anti-clockwise":
|
|
return C3.angleLerpAntiClockwise(sv, ev, easeRes, revolutions)
|
|
}
|
|
} else {
|
|
if (sv === ev)
|
|
return sv;
|
|
const n = C3.normalize(time, st, et);
|
|
const easeFunc = self.Ease.GetRuntimeEase(start.GetEase());
|
|
return C3.angleLerp(sv, ev, easeFunc(n, 0, 1, 1))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.PropertyTrackState.BooleanTypeAdapter = class BooleanTypeAdapter {
|
|
constructor() {}
|
|
static WillChange(index, source, newValue, type) {
|
|
let oldValue;
|
|
switch (type) {
|
|
case "behavior":
|
|
oldValue = source.GetPropertyValueByIndex(index);
|
|
break;
|
|
case "effect":
|
|
oldValue = source[index];
|
|
break;
|
|
case "instance-variable":
|
|
oldValue = source.GetInstanceVariableValue(index);
|
|
break;
|
|
case "plugin":
|
|
oldValue = source.GetPropertyValueByIndex(index);
|
|
break
|
|
}
|
|
if (!!oldValue === !!newValue)
|
|
return false;
|
|
return true
|
|
}
|
|
static Interpolate(time, start, end, propertyTrack) {
|
|
if (!end) {
|
|
let propertyTrackDataItem = propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = propertyTrack.GetPropertyTrackData();
|
|
propertyTrackDataItem = propertyTrackData.GetLastPropertyKeyframeDataItem(propertyTrackDataItem);
|
|
return propertyTrackDataItem.GetValueWithResultMode() ? 1 : 0
|
|
}
|
|
return start.GetValueWithResultMode() ? 1 : 0
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const TEMP_COLOR_ARRAY = [0, 0, 0];
|
|
const TEMP_COLOR_ARRAY_2 = [0, 0, 0];
|
|
const TEMP_COLOR_ARRAY_3 = [0, 0, 0];
|
|
C3.PropertyTrackState.ColorTypeAdapter = class ColorTypeAdapter {
|
|
constructor() {}
|
|
static WillChange(index, source, newValue, type) {
|
|
let oldValue;
|
|
switch (type) {
|
|
case "behavior":
|
|
oldValue = source.GetPropertyValueByIndex(index);
|
|
break;
|
|
case "effect":
|
|
oldValue = source[index];
|
|
break;
|
|
case "instance-variable":
|
|
oldValue = source.GetInstanceVariableValue(index);
|
|
break;
|
|
case "plugin":
|
|
oldValue = source.GetPropertyValueByIndex(index);
|
|
break
|
|
}
|
|
if (Array.isArray(newValue)) {
|
|
TEMP_COLOR_ARRAY[0] = newValue[0];
|
|
TEMP_COLOR_ARRAY[1] = newValue[1];
|
|
TEMP_COLOR_ARRAY[2] = newValue[2]
|
|
} else {
|
|
TEMP_COLOR_ARRAY_3.parseCommaSeparatedRgb(newValue);
|
|
TEMP_COLOR_ARRAY[0] = Math.floor(TEMP_COLOR_ARRAY_3.getR() * 255);
|
|
TEMP_COLOR_ARRAY[1] = Math.floor(TEMP_COLOR_ARRAY_3.getG() * 255);
|
|
TEMP_COLOR_ARRAY[2] = Math.floor(TEMP_COLOR_ARRAY_3.getB() * 255)
|
|
}
|
|
if (Array.isArray(oldValue)) {
|
|
TEMP_COLOR_ARRAY_2[0] = oldValue[0];
|
|
TEMP_COLOR_ARRAY_2[1] = oldValue[1];
|
|
TEMP_COLOR_ARRAY_2[2] = oldValue[2]
|
|
} else {
|
|
TEMP_COLOR_ARRAY_3.parseCommaSeparatedRgb(oldValue);
|
|
TEMP_COLOR_ARRAY_2[0] = Math.floor(TEMP_COLOR_ARRAY_3.getR() * 255);
|
|
TEMP_COLOR_ARRAY_2[1] = Math.floor(TEMP_COLOR_ARRAY_3.getG() * 255);
|
|
TEMP_COLOR_ARRAY_2[2] = Math.floor(TEMP_COLOR_ARRAY_3.getB() * 255)
|
|
}
|
|
if (TEMP_COLOR_ARRAY[0] !== TEMP_COLOR_ARRAY_2[0])
|
|
return true;
|
|
if (TEMP_COLOR_ARRAY[1] !== TEMP_COLOR_ARRAY_2[1])
|
|
return true;
|
|
if (TEMP_COLOR_ARRAY[2] !== TEMP_COLOR_ARRAY_2[2])
|
|
return true;
|
|
return false
|
|
}
|
|
static Interpolate(time, start, end, propertyTrack) {
|
|
if (!end) {
|
|
let propertyTrackDataItem = propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = propertyTrack.GetPropertyTrackData();
|
|
propertyTrackDataItem = propertyTrackData.GetLastPropertyKeyframeDataItem(propertyTrackDataItem);
|
|
const color = propertyTrackDataItem.GetValueWithResultMode();
|
|
TEMP_COLOR_ARRAY[0] = color[0];
|
|
TEMP_COLOR_ARRAY[1] = color[1];
|
|
TEMP_COLOR_ARRAY[2] = color[2];
|
|
return TEMP_COLOR_ARRAY
|
|
}
|
|
let mode = propertyTrack.GetInterpolationMode();
|
|
if (mode === "default")
|
|
mode = "continuous";
|
|
if (mode === "discrete") {
|
|
const color = start.GetValueWithResultMode();
|
|
TEMP_COLOR_ARRAY[0] = color[0];
|
|
TEMP_COLOR_ARRAY[1] = color[1];
|
|
TEMP_COLOR_ARRAY[2] = color[2];
|
|
return TEMP_COLOR_ARRAY
|
|
} else if (mode === "continuous" || mode === "step") {
|
|
if (mode === "step") {
|
|
const step = propertyTrack.GetTimeline().GetStep();
|
|
if (step !== 0) {
|
|
const s = 1 / step;
|
|
time = Math.floor(time * s) / s
|
|
}
|
|
}
|
|
const st = start.GetTime();
|
|
const et = end.GetTime();
|
|
const sv = start.GetValueWithResultMode();
|
|
const ev = end.GetValueWithResultMode();
|
|
const n = C3.normalize(time, st, et);
|
|
const e = start.GetEase();
|
|
const sr = sv[0];
|
|
const sg = sv[1];
|
|
const sb = sv[2];
|
|
const er = ev[0];
|
|
const eg = ev[1];
|
|
const eb = ev[2];
|
|
const easeFunc = self.Ease.GetRuntimeEase(e);
|
|
const d = et - st;
|
|
const dn = d * n;
|
|
if (sr === er)
|
|
TEMP_COLOR_ARRAY[0] = sr;
|
|
else
|
|
TEMP_COLOR_ARRAY[0] = easeFunc(dn, sr, er - sr, d);
|
|
if (sg === eg)
|
|
TEMP_COLOR_ARRAY[1] = sg;
|
|
else
|
|
TEMP_COLOR_ARRAY[1] = easeFunc(dn, sg, eg - sg, d);
|
|
if (sb === eb)
|
|
TEMP_COLOR_ARRAY[2] = sb;
|
|
else
|
|
TEMP_COLOR_ARRAY[2] = easeFunc(dn, sb, eb - sb, d);
|
|
return TEMP_COLOR_ARRAY
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.PropertyTrackState.TextTypeAdapter = class TextTypeAdapter {
|
|
constructor() {}
|
|
static WillChange(index, source, newValue, type) {
|
|
let oldValue;
|
|
switch (type) {
|
|
case "behavior":
|
|
oldValue = source.GetPropertyValueByIndex(index);
|
|
break;
|
|
case "effect":
|
|
oldValue = source[index];
|
|
break;
|
|
case "instance-variable":
|
|
oldValue = source.GetInstanceVariableValue(index);
|
|
break;
|
|
case "plugin":
|
|
oldValue = source.GetPropertyValueByIndex(index);
|
|
break
|
|
}
|
|
if (oldValue === newValue)
|
|
return false;
|
|
return true
|
|
}
|
|
static Interpolate(time, start, end, propertyTrack) {
|
|
if (!end) {
|
|
let propertyTrackDataItem = propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyTrackData = propertyTrack.GetPropertyTrackData();
|
|
propertyTrackDataItem = propertyTrackData.GetLastPropertyKeyframeDataItem(propertyTrackDataItem);
|
|
return propertyTrackDataItem.GetValueWithResultMode()
|
|
}
|
|
return start.GetValueWithResultMode()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.TimelineDataManager = class TimelineDataManager {
|
|
constructor() {
|
|
this._timelineDataItems = new Map
|
|
}
|
|
Release() {
|
|
for (const timelineDataItem of this._timelineDataItems.values())
|
|
timelineDataItem.Release();
|
|
this._timelineDataItems.clear();
|
|
this._timelineDataItems = null
|
|
}
|
|
Add(data) {
|
|
const timelineDataItem = new C3.TimelineDataItem(data);
|
|
const name = timelineDataItem.GetName();
|
|
this._timelineDataItems.set(name, timelineDataItem)
|
|
}
|
|
Get(name) {
|
|
return this._timelineDataItems.get(name)
|
|
}
|
|
GetNameId() {
|
|
return 0
|
|
}
|
|
static _CreateDataItems(items, jsonItems, dataItemConstructor, dataContainer) {
|
|
if (!jsonItems)
|
|
return;
|
|
for (const jsonItem of jsonItems)
|
|
C3.TimelineDataManager._CreateDataItem("create", jsonItem, items, dataItemConstructor, dataContainer)
|
|
}
|
|
static _LoadDataItemsFromJson(items, jsonItems, dataItemConstructor, dataContainer) {
|
|
if (items.length)
|
|
jsonItems.forEach((jsonItem,index)=>{
|
|
items[index]._LoadFromJson(jsonItem)
|
|
}
|
|
);
|
|
else
|
|
jsonItems.forEach(jsonItem=>{
|
|
C3.TimelineDataManager._CreateDataItem("load", jsonItem, items, dataItemConstructor, dataContainer)
|
|
}
|
|
)
|
|
}
|
|
static _CreateDataItem(mode, json, items, dataItemConstructor, dataContainer) {
|
|
let dataItem;
|
|
if (typeof dataItemConstructor === "function")
|
|
switch (mode) {
|
|
case "load":
|
|
dataItem = new dataItemConstructor(null,dataContainer);
|
|
break;
|
|
case "create":
|
|
dataItem = new dataItemConstructor(json,dataContainer);
|
|
break
|
|
}
|
|
else if (typeof dataItemConstructor === "object") {
|
|
const prop = dataItemConstructor.prop;
|
|
const value = json[prop];
|
|
const cnstrctr = dataItemConstructor.map.get(value);
|
|
switch (mode) {
|
|
case "load":
|
|
dataItem = new cnstrctr(null,dataContainer);
|
|
break;
|
|
case "create":
|
|
dataItem = new cnstrctr(json,dataContainer);
|
|
break
|
|
}
|
|
}
|
|
switch (mode) {
|
|
case "load":
|
|
dataItem._LoadFromJson(json);
|
|
items.push(dataItem);
|
|
break;
|
|
case "create":
|
|
if (typeof dataItem.GetEnable === "function" && !dataItem.GetEnable())
|
|
return dataItem.Release();
|
|
items.push(dataItem);
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const NAME = 0;
|
|
const TOTAL_TIME = 1;
|
|
const STEP = 2;
|
|
const INTERPOLATION_MODE = 3;
|
|
const RESULT_MODE = 4;
|
|
const TRACKS = 5;
|
|
const LOOP = 6;
|
|
const PING_PONG = 7;
|
|
const REPEAT_COUNT = 8;
|
|
C3.TimelineDataItem = class TimelineDataItem {
|
|
constructor(timelineDataJson) {
|
|
this._name = "";
|
|
this._totalTime = NaN;
|
|
this._step = 0;
|
|
this._interpolationMode = "default";
|
|
this._resultMode = "default";
|
|
this._loop = false;
|
|
this._pingPong = false;
|
|
this._repeatCount = 1;
|
|
this._trackData = null;
|
|
if (!timelineDataJson)
|
|
return;
|
|
this._name = timelineDataJson[NAME];
|
|
this._totalTime = timelineDataJson[TOTAL_TIME];
|
|
this._step = timelineDataJson[STEP];
|
|
this._interpolationMode = timelineDataJson[INTERPOLATION_MODE];
|
|
this._resultMode = timelineDataJson[RESULT_MODE];
|
|
this._loop = !!timelineDataJson[LOOP];
|
|
this._pingPong = !!timelineDataJson[PING_PONG];
|
|
this._repeatCount = timelineDataJson[REPEAT_COUNT];
|
|
this._trackData = new C3.TrackData(timelineDataJson[TRACKS],this)
|
|
}
|
|
Release() {
|
|
this._trackData.Release();
|
|
this._trackData = null
|
|
}
|
|
GetTrackData() {
|
|
if (!this._trackData)
|
|
this._trackData = new C3.TrackData(null,this);
|
|
return this._trackData
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
SetName(n) {
|
|
this._name = n
|
|
}
|
|
GetTotalTime() {
|
|
return this._totalTime
|
|
}
|
|
SetTotalTime(tt) {
|
|
this._totalTime = tt
|
|
}
|
|
GetStep() {
|
|
return this._step
|
|
}
|
|
SetStep(s) {
|
|
this._step = s
|
|
}
|
|
GetInterpolationMode() {
|
|
return this._interpolationMode
|
|
}
|
|
SetInterpolationMode(im) {
|
|
this._interpolationMode = im
|
|
}
|
|
GetResultMode() {
|
|
return this._resultMode
|
|
}
|
|
SetResultMode(rm) {
|
|
this._resultMode = rm
|
|
}
|
|
GetLoop() {
|
|
return this._loop
|
|
}
|
|
SetLoop(l) {
|
|
this._loop = l
|
|
}
|
|
GetPingPong() {
|
|
return this._pingPong
|
|
}
|
|
SetPingPong(p) {
|
|
this._pingPong = p
|
|
}
|
|
GetRepeatCount() {
|
|
return this._repeatCount
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"trackDataJson": this._trackData._SaveToJson(),
|
|
"name": this._name,
|
|
"totalTime": this._totalTime,
|
|
"step": this._step,
|
|
"interpolationMode": this._interpolationMode,
|
|
"resultMode": this._resultMode,
|
|
"loop": this._loop,
|
|
"pingPong": this._pingPong,
|
|
"repeatCount": this._repeatCount
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this.GetTrackData()._LoadFromJson(o["trackDataJson"]);
|
|
this._name = o["name"];
|
|
this._totalTime = o["totalTime"];
|
|
this._step = o["step"];
|
|
this._interpolationMode = o["interpolationMode"];
|
|
this._resultMode = o["resultMode"];
|
|
this._loop = o["loop"];
|
|
this._pingPong = o["pingPong"];
|
|
this._repeatCount = o["repeatCount"]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const WI_DATA = 0;
|
|
const OC_INDEX = 1;
|
|
const WI_UID = 2;
|
|
const INTERPOLATION_MODE = 1;
|
|
const RESULT_MODE = 2;
|
|
const ENABLED = 3;
|
|
const KEYFRAMES = 4;
|
|
const PROPERTY_TRACKS = 5;
|
|
const ID = 6;
|
|
const NESTED_DATA = 7;
|
|
const START_OFFSET = 0;
|
|
const LOCAL_TOTAL_TIME = 1;
|
|
const WI_ADDITIONAL_DATA = 8;
|
|
const ORIGINAL_WIDTH = 0;
|
|
const ORIGINAL_HEIGHT = 1;
|
|
class TrackDataItem {
|
|
constructor(trackDataJson, trackData) {
|
|
this._trackData = trackData;
|
|
this._instanceData = null;
|
|
this._additionalInstanceData = null;
|
|
this._instanceUid = NaN;
|
|
this._objectClassIndex = NaN;
|
|
this._interpolationMode = "default";
|
|
this._resultMode = "default";
|
|
this._enabled = false;
|
|
this._keyframeData = null;
|
|
this._propertyTrackData = null;
|
|
this._id = "";
|
|
this._nestedData = null;
|
|
this._startOffset = 0;
|
|
this._localTotalTime = this._trackData.GetTimelineDataItem().GetTotalTime();
|
|
if (!trackDataJson)
|
|
return;
|
|
this._instanceData = trackDataJson[WI_DATA];
|
|
this._instanceUid = trackDataJson[WI_DATA][WI_UID];
|
|
this._objectClassIndex = trackDataJson[WI_DATA][OC_INDEX];
|
|
this._interpolationMode = trackDataJson[INTERPOLATION_MODE];
|
|
this._resultMode = trackDataJson[RESULT_MODE];
|
|
this._enabled = !!trackDataJson[ENABLED];
|
|
if (trackDataJson[ID])
|
|
this._id = trackDataJson[ID];
|
|
if (trackDataJson[NESTED_DATA]) {
|
|
this._nestedData = trackDataJson[NESTED_DATA];
|
|
this._startOffset = trackDataJson[NESTED_DATA][START_OFFSET];
|
|
this._localTotalTime = trackDataJson[NESTED_DATA][LOCAL_TOTAL_TIME]
|
|
}
|
|
if (trackDataJson[WI_ADDITIONAL_DATA])
|
|
this._additionalInstanceData = trackDataJson[WI_ADDITIONAL_DATA];
|
|
this._keyframeData = new C3.KeyframeData(trackDataJson[KEYFRAMES],this);
|
|
this._propertyTrackData = new C3.PropertyTrackData(trackDataJson[PROPERTY_TRACKS],this)
|
|
}
|
|
Release() {
|
|
this._instanceData = null;
|
|
this._trackData = null;
|
|
if (this._keyframeData) {
|
|
this._keyframeData.Release();
|
|
this._keyframeData = null
|
|
}
|
|
if (this._propertyTrackData) {
|
|
this._propertyTrackData.Release();
|
|
this._propertyTrackData = null
|
|
}
|
|
this._nestedData = null
|
|
}
|
|
GetTrackData() {
|
|
return this._trackData
|
|
}
|
|
GetKeyframeData() {
|
|
if (!this._keyframeData)
|
|
this._keyframeData = new C3.KeyframeData(null,this);
|
|
return this._keyframeData
|
|
}
|
|
GetPropertyTrackData() {
|
|
if (!this._propertyTrackData)
|
|
this._propertyTrackData = new C3.PropertyTrackData(null,this);
|
|
return this._propertyTrackData
|
|
}
|
|
GetInstanceData() {
|
|
return this._instanceData
|
|
}
|
|
GetObjectClassIndex() {
|
|
return this._objectClassIndex
|
|
}
|
|
SetObjectClassIndex(index) {
|
|
this._objectClassIndex = index
|
|
}
|
|
GetInstanceUID() {
|
|
return this._instanceUid
|
|
}
|
|
SetInstanceUID(uid) {
|
|
this._instanceUid = uid
|
|
}
|
|
GetInterpolationMode() {
|
|
return this._interpolationMode
|
|
}
|
|
SetInterpolationMode(im) {
|
|
this._interpolationMode = im
|
|
}
|
|
GetResultMode() {
|
|
return this._resultMode
|
|
}
|
|
SetResultMode(rm) {
|
|
this._resultMode = rm
|
|
}
|
|
GetEnable() {
|
|
return this._enabled
|
|
}
|
|
SetEnable(e) {
|
|
this._enabled = !!e
|
|
}
|
|
GetId() {
|
|
return this._id
|
|
}
|
|
GetStartOffset() {
|
|
return this._startOffset
|
|
}
|
|
GetLocalTotalTime() {
|
|
return this._localTotalTime
|
|
}
|
|
GetOriginalWidth() {
|
|
return this._additionalInstanceData[ORIGINAL_WIDTH]
|
|
}
|
|
SetOriginalWidth(w) {
|
|
if (!this._additionalInstanceData)
|
|
this._additionalInstanceData = [];
|
|
this._additionalInstanceData[ORIGINAL_WIDTH] = w
|
|
}
|
|
GetOriginalHeight() {
|
|
if (!this._additionalInstanceData)
|
|
this._additionalInstanceData = [];
|
|
return this._additionalInstanceData[ORIGINAL_HEIGHT]
|
|
}
|
|
SetOriginalHeight(h) {
|
|
if (!this._additionalInstanceData)
|
|
this._additionalInstanceData = [];
|
|
this._additionalInstanceData[ORIGINAL_HEIGHT] = h
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"keyframeDataJson": this._keyframeData._SaveToJson(),
|
|
"propertyTrackDataJson": this._propertyTrackData._SaveToJson(),
|
|
"instanceData": this._instanceData,
|
|
"additionalInstanceData": this._additionalInstanceData,
|
|
"instanceUid": this._instanceUid,
|
|
"objectClassIndex": this._objectClassIndex,
|
|
"interpolationMode": this._interpolationMode,
|
|
"resultMode": this._resultMode,
|
|
"enabled": this._enabled,
|
|
"id": this._id,
|
|
"nestedData": this._nestedData
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this._instanceData = o["instanceData"];
|
|
this._instanceUid = o["instanceUid"];
|
|
this._objectClassIndex = o["objectClassIndex"];
|
|
this._interpolationMode = o["interpolationMode"];
|
|
this._resultMode = o["resultMode"];
|
|
this._enabled = o["enabled"];
|
|
this._id = o["id"];
|
|
this._localTotalTime = this._trackData.GetTimelineDataItem().GetTotalTime();
|
|
if (o["nestedData"]) {
|
|
this._nestedData = o["nestedData"];
|
|
this._startOffset = this._nestedData[START_OFFSET];
|
|
this._localTotalTime = this._nestedData[LOCAL_TOTAL_TIME]
|
|
}
|
|
if (o["additionalInstanceData"])
|
|
this._additionalInstanceData = o["additionalInstanceData"];
|
|
this.GetKeyframeData()._LoadFromJson(o["keyframeDataJson"]);
|
|
this.GetPropertyTrackData()._LoadFromJson(o["propertyTrackDataJson"])
|
|
}
|
|
}
|
|
C3.TrackData = class TrackData {
|
|
constructor(tracksDataJson, timelineDataItem) {
|
|
this._timelineDataItem = timelineDataItem;
|
|
this._trackDataItems = [];
|
|
this._keyframeTimeMap = new Map;
|
|
C3.TimelineDataManager._CreateDataItems(this._trackDataItems, tracksDataJson, TrackDataItem, this)
|
|
}
|
|
Release() {
|
|
this._timelineDataItem = null;
|
|
for (const trackDataItem of this._trackDataItems)
|
|
trackDataItem.Release();
|
|
C3.clearArray(this._trackDataItems);
|
|
this._trackDataItems = null;
|
|
this._keyframeTimeMap.clear();
|
|
this._keyframeTimeMap = null
|
|
}
|
|
GetTimelineDataItem() {
|
|
return this._timelineDataItem
|
|
}
|
|
AddEmptyTrackDataItem() {
|
|
const trackDataItem = new TrackDataItem(null,this);
|
|
this._trackDataItems.push(trackDataItem);
|
|
return trackDataItem
|
|
}
|
|
GetFirstKeyframeDataItem(trackDataItem) {
|
|
return trackDataItem.GetKeyframeData().GetKeyframeDataItemArray()[0]
|
|
}
|
|
GetLastKeyframeDataItem(trackDataItem) {
|
|
const keyframeDataItems = trackDataItem.GetKeyframeData().GetKeyframeDataItemArray();
|
|
return keyframeDataItems[keyframeDataItems.length - 1]
|
|
}
|
|
GetKeyFrameDataItemAtTime(time, trackDataItem) {
|
|
const keyframeDataItemEntry = this._keyframeTimeMap.get(trackDataItem);
|
|
if (!!keyframeDataItemEntry && keyframeDataItemEntry.has(time))
|
|
return keyframeDataItemEntry.get(time);
|
|
for (const keyframeDataItem of trackDataItem.GetKeyframeData().keyframeDataItems())
|
|
if (keyframeDataItem.GetTime() === time) {
|
|
if (!keyframeDataItemEntry)
|
|
this._keyframeTimeMap.set(trackDataItem, new Map);
|
|
this._keyframeTimeMap.get(trackDataItem).set(time, keyframeDataItem);
|
|
return keyframeDataItem
|
|
}
|
|
}
|
|
GetFirstKeyFrameDataItemHigherThan(time, trackDataItem) {
|
|
for (const keyframeDataItem of trackDataItem.GetKeyframeData().keyframeDataItems())
|
|
if (keyframeDataItem.GetTime() > time)
|
|
return keyframeDataItem
|
|
}
|
|
GetFirstKeyFrameDataItemHigherOrEqualThan(time, trackDataItem) {
|
|
for (const keyframeDataItem of trackDataItem.GetKeyframeData().keyframeDataItems())
|
|
if (keyframeDataItem.GetTime() >= time)
|
|
return keyframeDataItem
|
|
}
|
|
GetFirstKeyFrameDataItemLowerOrEqualThan(time, trackDataItem) {
|
|
for (const keyframeDataItem of trackDataItem.GetKeyframeData().keyframeDataItemsReverse())
|
|
if (keyframeDataItem.GetTime() <= time)
|
|
return keyframeDataItem
|
|
}
|
|
*trackDataItems() {
|
|
for (const trackDataItem of this._trackDataItems)
|
|
yield trackDataItem
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"trackDataItemsJson": this._trackDataItems.map(trackDataItem=>trackDataItem._SaveToJson())
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
C3.TimelineDataManager._LoadDataItemsFromJson(this._trackDataItems, o["trackDataItemsJson"], TrackDataItem, this)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const SOURCE_DATA = 0;
|
|
const SOURCE = 0;
|
|
const PROPERTY = 1;
|
|
const TYPE = 2;
|
|
const MIN = 3;
|
|
const MAX = 4;
|
|
const INTERPOLATION_MODE = 5;
|
|
const RESULT_MODE = 6;
|
|
const ENABLED = 7;
|
|
const PROPERTY_KEYFRAMES = 8;
|
|
class PropertyTrackDataItem {
|
|
constructor(propertyTrackDataJson, propertyTrackData) {
|
|
this._propertyTrackData = propertyTrackData;
|
|
this._sourceAdapterId = "";
|
|
this._sourceAdapterArguments = null;
|
|
this._property = null;
|
|
this._type = null;
|
|
this._min = NaN;
|
|
this._max = NaN;
|
|
this._interpolationMode = "default";
|
|
this._resultMode = "default";
|
|
this._enabled = false;
|
|
this._propertyKeyframeData = null;
|
|
if (!propertyTrackDataJson)
|
|
return;
|
|
this._sourceAdapterId = propertyTrackDataJson[SOURCE_DATA][SOURCE];
|
|
this._sourceAdapterArguments = propertyTrackDataJson[SOURCE_DATA].slice(1);
|
|
this._property = propertyTrackDataJson[PROPERTY];
|
|
this._type = propertyTrackDataJson[TYPE];
|
|
this._min = propertyTrackDataJson[MIN];
|
|
this._max = propertyTrackDataJson[MAX];
|
|
this._interpolationMode = propertyTrackDataJson[INTERPOLATION_MODE];
|
|
this._resultMode = propertyTrackDataJson[RESULT_MODE];
|
|
this._enabled = !!propertyTrackDataJson[ENABLED];
|
|
this._propertyKeyframeData = new C3.PropertyKeyframeData(propertyTrackDataJson[PROPERTY_KEYFRAMES],this)
|
|
}
|
|
Release() {
|
|
this._propertyKeyframeData.Release();
|
|
this._propertyKeyframeData = null;
|
|
this._propertyTrackData = null;
|
|
this._sourceAdapterArguments = null
|
|
}
|
|
GetPropertyTrackData() {
|
|
return this._propertyTrackData
|
|
}
|
|
GetPropertyKeyframeData() {
|
|
if (!this._propertyKeyframeData)
|
|
this._propertyKeyframeData = new C3.PropertyKeyframeData(null,this);
|
|
return this._propertyKeyframeData
|
|
}
|
|
GetSourceAdapterId() {
|
|
return this._sourceAdapterId
|
|
}
|
|
SetSourceAdapterId(said) {
|
|
this._sourceAdapterId = said
|
|
}
|
|
GetSourceAdapterArguments() {
|
|
return this._sourceAdapterArguments
|
|
}
|
|
SetSourceAdapterArguments(sargs) {
|
|
this._sourceAdapterArguments = sargs
|
|
}
|
|
GetProperty() {
|
|
return this._property
|
|
}
|
|
SetProperty(p) {
|
|
this._property = p
|
|
}
|
|
GetType() {
|
|
return this._type
|
|
}
|
|
SetType(t) {
|
|
this._type = t
|
|
}
|
|
GetMin() {
|
|
return this._min
|
|
}
|
|
SetMin(min) {
|
|
this._min = min
|
|
}
|
|
GetMax() {
|
|
return this._max
|
|
}
|
|
SetMax(max) {
|
|
this._max = max
|
|
}
|
|
GetInterpolationMode() {
|
|
return this._interpolationMode
|
|
}
|
|
SetInterpolationMode(im) {
|
|
this._interpolationMode = im
|
|
}
|
|
GetResultMode() {
|
|
return this._resultMode
|
|
}
|
|
SetResultMode(rm) {
|
|
this._resultMode = rm
|
|
}
|
|
GetEnable() {
|
|
return this._enabled
|
|
}
|
|
SetEnable(e) {
|
|
this._enabled = !!e
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"propertyKeyframeDataJson": this._propertyKeyframeData._SaveToJson(),
|
|
"sourceAdapterId": this._sourceAdapterId,
|
|
"sourceAdapterArguments": this._sourceAdapterArguments,
|
|
"property": this._property,
|
|
"type": this._type,
|
|
"min": this._min,
|
|
"max": this._max,
|
|
"interpolationMode": this._interpolationMode,
|
|
"resultMode": this._resultMode,
|
|
"enabled": this._enabled
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this._sourceAdapterId = o["sourceAdapterId"];
|
|
this._sourceAdapterArguments = o["sourceAdapterArguments"];
|
|
this._property = o["property"];
|
|
this._type = o["type"];
|
|
this._min = o["min"];
|
|
this._max = o["max"];
|
|
this._interpolationMode = o["interpolationMode"];
|
|
this._resultMode = o["resultMode"];
|
|
this._enabled = o["enabled"];
|
|
this.GetPropertyKeyframeData()._LoadFromJson(o["propertyKeyframeDataJson"])
|
|
}
|
|
}
|
|
C3.PropertyTrackData = class PropertyTrackData {
|
|
constructor(propertyTracksDataJson, trackDataItem) {
|
|
this._trackDataItem = trackDataItem;
|
|
this._propertyTrackDataItems = [];
|
|
this._propertyKeyframeTimeMap = new Map;
|
|
C3.TimelineDataManager._CreateDataItems(this._propertyTrackDataItems, propertyTracksDataJson, PropertyTrackDataItem, this)
|
|
}
|
|
Release() {
|
|
this._trackDataItem = null;
|
|
for (const propertyTrackDataItem of this._propertyTrackDataItems)
|
|
propertyTrackDataItem.Release();
|
|
C3.clearArray(this._propertyTrackDataItems);
|
|
this._propertyTrackDataItems = null;
|
|
this._propertyKeyframeTimeMap.clear();
|
|
this._propertyKeyframeTimeMap = null
|
|
}
|
|
GetTrackDataItem() {
|
|
return this._trackDataItem
|
|
}
|
|
AddEmptyPropertyTrackDataItem() {
|
|
const propertyTrackDataItem = new PropertyTrackDataItem(null,this);
|
|
this._propertyTrackDataItems.push(propertyTrackDataItem);
|
|
return propertyTrackDataItem
|
|
}
|
|
GetFirstPropertyKeyframeDataItem(propertyTrackDataItem) {
|
|
const propertyKeyframeData = propertyTrackDataItem.GetPropertyKeyframeData();
|
|
return propertyKeyframeData.GetPropertyKeyframeDataItemArray()[0]
|
|
}
|
|
GetLastPropertyKeyframeDataItem(propertyTrackDataItem) {
|
|
const propertyKeyframeData = propertyTrackDataItem.GetPropertyKeyframeData();
|
|
const propertyKeyframeDataItems = propertyKeyframeData.GetPropertyKeyframeDataItemArray();
|
|
return propertyKeyframeDataItems[propertyKeyframeDataItems.length - 1]
|
|
}
|
|
GetPropertyKeyFrameDataItemAtTime(time, propertyTrackDataItem) {
|
|
const propertyKeyframeDataItemEntry = this._propertyKeyframeTimeMap.get(propertyTrackDataItem);
|
|
if (!!propertyKeyframeDataItemEntry && propertyKeyframeDataItemEntry.has(time))
|
|
return propertyKeyframeDataItemEntry.get(time);
|
|
const propertyKeyframeData = propertyTrackDataItem.GetPropertyKeyframeData();
|
|
for (const propertyKeyframeDataItem of propertyKeyframeData.propertyKeyframeDataItems())
|
|
if (propertyKeyframeDataItem.GetTime() === time) {
|
|
if (!propertyKeyframeDataItemEntry)
|
|
this._propertyKeyframeTimeMap.set(propertyTrackDataItem, new Map);
|
|
this._propertyKeyframeTimeMap.get(propertyTrackDataItem).set(time, propertyKeyframeDataItem);
|
|
return propertyKeyframeDataItem
|
|
}
|
|
}
|
|
GetFirstPropertyKeyFrameDataItemHigherThan(time, propertyTrackDataItem) {
|
|
const propertyKeyframeData = propertyTrackDataItem.GetPropertyKeyframeData();
|
|
for (const propertyKeyframeDataItem of propertyKeyframeData.propertyKeyframeDataItems())
|
|
if (propertyKeyframeDataItem.GetTime() > time)
|
|
return propertyKeyframeDataItem
|
|
}
|
|
GetFirstPropertyKeyFrameDataItemHigherOrEqualThan(time, propertyTrackDataItem) {
|
|
const propertyKeyframeData = propertyTrackDataItem.GetPropertyKeyframeData();
|
|
for (const propertyKeyframeDataItem of propertyKeyframeData.propertyKeyframeDataItems())
|
|
if (propertyKeyframeDataItem.GetTime() >= time)
|
|
return propertyKeyframeDataItem
|
|
}
|
|
GetFirstPropertyKeyFrameDataItemLowerOrEqualThan(time, propertyTrackDataItem) {
|
|
const propertyKeyframeData = propertyTrackDataItem.GetPropertyKeyframeData();
|
|
for (const propertyKeyframeDataItem of propertyKeyframeData.propertyKeyframeDataItemsReverse())
|
|
if (propertyKeyframeDataItem.GetTime() <= time)
|
|
return propertyKeyframeDataItem
|
|
}
|
|
*propertyTrackDataItems() {
|
|
for (const propertyTrackDataItem of this._propertyTrackDataItems)
|
|
yield propertyTrackDataItem
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"propertyTrackDataItemsJson": this._propertyTrackDataItems.map(propertyTrackDataItem=>propertyTrackDataItem._SaveToJson())
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
C3.TimelineDataManager._LoadDataItemsFromJson(this._propertyTrackDataItems, o["propertyTrackDataItemsJson"], PropertyTrackDataItem, this)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const TIME = 0;
|
|
const EASE = 1;
|
|
const ENABLE = 2;
|
|
const TAGS = 3;
|
|
class KeyframeDataItem {
|
|
constructor(keyframeDataJson, keyframeData) {
|
|
this._keyframeData = keyframeData;
|
|
this._time = -1;
|
|
this._ease = "noease";
|
|
this._enable = false;
|
|
this._tags = null;
|
|
this._lowerTags = null;
|
|
if (!keyframeDataJson)
|
|
return;
|
|
this._time = keyframeDataJson[TIME];
|
|
this._ease = keyframeDataJson[EASE];
|
|
this._enable = !!keyframeDataJson[ENABLE];
|
|
const tagStr = keyframeDataJson[TAGS];
|
|
this._tags = tagStr ? tagStr.split(" ") : [];
|
|
this._lowerTags = new Set(this._tags.map(t=>t.toLowerCase()))
|
|
}
|
|
Release() {
|
|
this._keyframeData = null;
|
|
C3.clearArray(this._tags);
|
|
this._tags = null;
|
|
this._lowerTags.clear();
|
|
this._lowerTags = null
|
|
}
|
|
GetKeyframeData() {
|
|
return this._keyframeData
|
|
}
|
|
GetTime() {
|
|
return this._time
|
|
}
|
|
SetTime(t) {
|
|
this._time = t
|
|
}
|
|
GetEase() {
|
|
return this._ease
|
|
}
|
|
SetEase(e) {
|
|
this._ease = e
|
|
}
|
|
GetEnable() {
|
|
return this._enable
|
|
}
|
|
SetEnable(e) {
|
|
this._enable = !!e
|
|
}
|
|
GetTags() {
|
|
return this._tags
|
|
}
|
|
SetTags(t) {
|
|
this._tags = t ? t.split(" ") : [];
|
|
this._lowerTags = new Set(this._tags.map(t=>t.toLowerCase()))
|
|
}
|
|
GetLowerTags() {
|
|
return this._lowerTags
|
|
}
|
|
HasTag(tag) {
|
|
return this._lowerTags.has(tag.toLowerCase())
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"time": this._time,
|
|
"ease": this._ease,
|
|
"enable": this._enable,
|
|
"tags": this._tags
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this._time = o["time"];
|
|
this._ease = o["ease"];
|
|
this._enable = o["enable"];
|
|
this._tags = o["tags"];
|
|
this._lowerTags = new Set(this._tags.map(t=>t.toLowerCase()))
|
|
}
|
|
}
|
|
C3.KeyframeData = class KeyframeData {
|
|
constructor(keyframesDataJson, trackDataItem) {
|
|
this._trackDataItem = trackDataItem;
|
|
this._keyframeDataItems = [];
|
|
C3.TimelineDataManager._CreateDataItems(this._keyframeDataItems, keyframesDataJson, KeyframeDataItem, this)
|
|
}
|
|
Release() {
|
|
this._trackDataItem = null;
|
|
for (const keyframeDataItem of this._keyframeDataItems)
|
|
keyframeDataItem.Release();
|
|
C3.clearArray(this._keyframeDataItems);
|
|
this._keyframeDataItems = null
|
|
}
|
|
GetTrackDataItem() {
|
|
return this._trackDataItem
|
|
}
|
|
GetKeyframeDataItemCount() {
|
|
return this._keyframeDataItems.length
|
|
}
|
|
GetKeyframeDataItemArray() {
|
|
return this._keyframeDataItems
|
|
}
|
|
AddEmptyKeyframeDataItem() {
|
|
const keyframeDataItem = new KeyframeDataItem(null,this);
|
|
this._keyframeDataItems.push(keyframeDataItem);
|
|
return keyframeDataItem
|
|
}
|
|
DeleteKeyframeDataItems(match) {
|
|
for (const keyframeDataItem of this._keyframeDataItems) {
|
|
if (!match(keyframeDataItem))
|
|
continue;
|
|
const index = this._keyframeDataItems.indexOf(keyframeDataItem);
|
|
if (index === -1)
|
|
continue;
|
|
keyframeDataItem.Release();
|
|
this._keyframeDataItems.splice(index, 1)
|
|
}
|
|
this.SortKeyframeDataItems()
|
|
}
|
|
SortKeyframeDataItems() {
|
|
this._keyframeDataItems.sort((a,b)=>a.GetTime() - b.GetTime())
|
|
}
|
|
GetKeyframeDataItemIndex(keyframeDataItem) {
|
|
return this._keyframeDataItems.indexOf(keyframeDataItem)
|
|
}
|
|
GetKeyframeDataItemFromIndex(index) {
|
|
return this._keyframeDataItems[index]
|
|
}
|
|
*keyframeDataItems() {
|
|
for (const keyframeDataItem of this._keyframeDataItems)
|
|
yield keyframeDataItem
|
|
}
|
|
*keyframeDataItemsReverse() {
|
|
for (let i = this._keyframeDataItems.length - 1; i >= 0; i--)
|
|
yield this._keyframeDataItems[i]
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"keyframeDataItemsJson": this._keyframeDataItems.map(keyframeDataItem=>keyframeDataItem._SaveToJson())
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
C3.TimelineDataManager._LoadDataItemsFromJson(this._keyframeDataItems, o["keyframeDataItemsJson"], KeyframeDataItem, this)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const VALUE_DATA = 0;
|
|
const VALUE_DATA_VALUE = 0;
|
|
const VALUE_DATA_ABSOLUTE_VALUE = 1;
|
|
const VALUE_DATA_TYPE = 2;
|
|
const TIME = 1;
|
|
const EASE = 2;
|
|
const ENABLE = 3;
|
|
const ADDONS = 4;
|
|
class PropertyKeyframeDataItem {
|
|
constructor(propertyKeyframeDataJson, propertyKeyframeData) {
|
|
this._propertyKeyframeData = propertyKeyframeData;
|
|
this._value = null;
|
|
this._aValue = null;
|
|
this._type = "";
|
|
this._time = NaN;
|
|
this._ease = "noease";
|
|
this._enable = false;
|
|
this._addonData = null;
|
|
if (!propertyKeyframeDataJson)
|
|
return;
|
|
this._value = propertyKeyframeDataJson[VALUE_DATA][VALUE_DATA_VALUE];
|
|
this._aValue = propertyKeyframeDataJson[VALUE_DATA][VALUE_DATA_ABSOLUTE_VALUE];
|
|
this._type = propertyKeyframeDataJson[VALUE_DATA][VALUE_DATA_TYPE];
|
|
this._time = propertyKeyframeDataJson[TIME];
|
|
this._ease = propertyKeyframeDataJson[EASE];
|
|
this._enable = !!propertyKeyframeDataJson[ENABLE];
|
|
this._addonData = null;
|
|
if (!!propertyKeyframeDataJson[ADDONS])
|
|
this._addonData = new C3.AddonData(propertyKeyframeDataJson[ADDONS],this)
|
|
}
|
|
Release() {
|
|
this._propertyKeyframeData = null;
|
|
if (this._addonData) {
|
|
this._addonData.Release();
|
|
this._addonData = null
|
|
}
|
|
}
|
|
GetAddonData() {
|
|
return this._addonData
|
|
}
|
|
GetValue() {
|
|
return this._value
|
|
}
|
|
SetValue(value) {
|
|
if (this._type === "color" && C3.IsFiniteNumber(value)) {
|
|
this._value[0] = C3.GetRValue(value);
|
|
this._value[1] = C3.GetGValue(value);
|
|
this._value[2] = C3.GetBValue(value)
|
|
} else
|
|
this._value = value
|
|
}
|
|
GetAbsoluteValue() {
|
|
return this._aValue
|
|
}
|
|
SetAbsoluteValue(aValue) {
|
|
if (this._type === "color" && C3.IsFiniteNumber(aValue)) {
|
|
this._aValue[0] = C3.GetRValue(aValue);
|
|
this._aValue[1] = C3.GetGValue(aValue);
|
|
this._aValue[2] = C3.GetBValue(aValue)
|
|
} else
|
|
this._aValue = aValue
|
|
}
|
|
GetValueWithResultMode() {
|
|
const rm = this._propertyKeyframeData.GetPropertyTrackDataItem().GetResultMode();
|
|
if (rm === "relative")
|
|
return this.GetValue();
|
|
else if (rm === "absolute")
|
|
return this.GetAbsoluteValue()
|
|
}
|
|
GetType() {
|
|
return this._type
|
|
}
|
|
SetType(t) {
|
|
this._type = t
|
|
}
|
|
GetTime() {
|
|
return this._time
|
|
}
|
|
SetTime(t) {
|
|
this._time = t
|
|
}
|
|
GetEase() {
|
|
return this._ease
|
|
}
|
|
SetEase(e) {
|
|
this._ease = e
|
|
}
|
|
GetEnable() {
|
|
return this._enable
|
|
}
|
|
SetEnable(e) {
|
|
this._enable = !!e
|
|
}
|
|
GetAddOn(id) {
|
|
if (!this.GetAddonData())
|
|
return;
|
|
for (const addonDataItem of this.GetAddonData().addonDataItems())
|
|
if (addonDataItem.GetId() === id)
|
|
return addonDataItem
|
|
}
|
|
_SaveToJson() {
|
|
const aData = this._addonData;
|
|
return {
|
|
"addonDataJson": aData ? aData._SaveToJson() : aData,
|
|
"value": this._value,
|
|
"aValue": this._aValue,
|
|
"type": this._type,
|
|
"time": this._time,
|
|
"ease": this._ease,
|
|
"enable": this._enable
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
if (o["addonDataJson"])
|
|
this._addonData._SetFromJson(o["addonDataJson"]);
|
|
this._value = o["value"];
|
|
this._aValue = o["aValue"];
|
|
this._type = o["type"];
|
|
this._time = o["time"];
|
|
this._ease = o["ease"];
|
|
this._enable = o["enable"]
|
|
}
|
|
}
|
|
C3.PropertyKeyframeData = class PropertyKeyframeData {
|
|
constructor(propertyKeyframesDataJson, propertyTrackDataItem) {
|
|
this._propertyTrackDataItem = propertyTrackDataItem;
|
|
this._propertyKeyframeDataItems = [];
|
|
C3.TimelineDataManager._CreateDataItems(this._propertyKeyframeDataItems, propertyKeyframesDataJson, PropertyKeyframeDataItem, this)
|
|
}
|
|
Release() {
|
|
this._propertyTrackDataItem = null;
|
|
for (const propertyKeyframeDataItem of this._propertyKeyframeDataItems)
|
|
propertyKeyframeDataItem.Release();
|
|
C3.clearArray(this._propertyKeyframeDataItems);
|
|
this._propertyKeyframeDataItems = null
|
|
}
|
|
AddEmptyPropertyKeyframeDataItem() {
|
|
const propertyKeyframeDataItem = new PropertyKeyframeDataItem(null,this);
|
|
this._propertyKeyframeDataItems.push(propertyKeyframeDataItem);
|
|
return propertyKeyframeDataItem
|
|
}
|
|
DeletePropertyKeyframeDataItems(match) {
|
|
for (const propertyKeyframeDataItem of this._propertyKeyframeDataItems) {
|
|
if (!match(propertyKeyframeDataItem))
|
|
continue;
|
|
const index = this._propertyKeyframeDataItems.indexOf(propertyKeyframeDataItem);
|
|
if (index === -1)
|
|
continue;
|
|
propertyKeyframeDataItem.Release();
|
|
this._propertyKeyframeDataItems.splice(index, 1)
|
|
}
|
|
this.SortPropertyKeyFrameDataItems()
|
|
}
|
|
SortPropertyKeyFrameDataItems() {
|
|
this._propertyKeyframeDataItems.sort((a,b)=>a.GetTime() - b.GetTime())
|
|
}
|
|
GetPropertyTrackDataItem() {
|
|
return this._propertyTrackDataItem
|
|
}
|
|
GetPropertyKeyframeDataItemCount() {
|
|
return this._propertyKeyframeDataItems.length
|
|
}
|
|
GetPropertyKeyframeDataItemArray() {
|
|
return this._propertyKeyframeDataItems
|
|
}
|
|
*propertyKeyframeDataItems() {
|
|
for (const propertyKeyframeDataItem of this._propertyKeyframeDataItems)
|
|
yield propertyKeyframeDataItem
|
|
}
|
|
*propertyKeyframeDataItemsReverse() {
|
|
for (let i = this._propertyKeyframeDataItems.length - 1; i >= 0; i--)
|
|
yield this._propertyKeyframeDataItems[i]
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"propertyKeyframeDataItemsJson": this._propertyKeyframeDataItems.map(propertyTrackDataItem=>propertyTrackDataItem._SaveToJson())
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
C3.TimelineDataManager._LoadDataItemsFromJson(this._propertyKeyframeDataItems, o["propertyKeyframeDataItemsJson"], PropertyKeyframeDataItem, this)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const ADDON_ID = 0;
|
|
const ADDON_DATA = 1;
|
|
class AddonDataItem {
|
|
constructor(addonDataJson, addonData) {
|
|
this._addonData = addonData;
|
|
this._id = addonDataJson[ADDON_ID];
|
|
this._data = addonDataJson[ADDON_DATA]
|
|
}
|
|
Release() {
|
|
this._addonData = null;
|
|
this._data = null
|
|
}
|
|
GetAddonData() {
|
|
return this._addonData
|
|
}
|
|
GetId() {
|
|
return this._id
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"id": this._id,
|
|
"data": this._data
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
this._id = o["id"];
|
|
this._data = o["data"]
|
|
}
|
|
}
|
|
const START_ANCHOR = 0;
|
|
const START_ENABLE = 1;
|
|
const END_ANCHOR = 2;
|
|
const END_ENABLE = 3;
|
|
class AddonDataCubicBezierItem extends AddonDataItem {
|
|
constructor(addonDataJson, addonData) {
|
|
super(addonDataJson, addonData);
|
|
this._startAnchor = this._data[START_ANCHOR];
|
|
this._startEnable = !!this._data[START_ENABLE];
|
|
this._endAnchor = this._data[END_ANCHOR];
|
|
this._endEnable = !!this._data[END_ENABLE]
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
GetStartAnchor() {
|
|
return this._startAnchor
|
|
}
|
|
GetStartEnable() {
|
|
return this._startEnable
|
|
}
|
|
GetEndAnchor() {
|
|
return this._endAnchor
|
|
}
|
|
GetEndEnable() {
|
|
return this._endEnable
|
|
}
|
|
_SaveToJson() {
|
|
return Object.assign(super._SaveToJson(), {
|
|
"startAnchor": this._startAnchor,
|
|
"startEnable": !!this._startEnable,
|
|
"endAnchor": this._endAnchor,
|
|
"endEnable": !!this._endEnable
|
|
})
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
super._LoadFromJson(o);
|
|
this._startAnchor = o["startAnchor"];
|
|
this._startEnable = !!o["startEnable"];
|
|
this._endAnchor = o["endAnchor"];
|
|
this._endEnable = !!o["endEnable"]
|
|
}
|
|
}
|
|
const DIRECTION = 0;
|
|
const REVOLUTIONS = 1;
|
|
class AddonDataAngleItem extends AddonDataItem {
|
|
constructor(addonDataJson, addonData) {
|
|
super(addonDataJson, addonData);
|
|
this._direction = this._data[DIRECTION];
|
|
this._revolutions = this._data[REVOLUTIONS]
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
GetDirection() {
|
|
return this._direction
|
|
}
|
|
GetRevolutions() {
|
|
return this._revolutions
|
|
}
|
|
_SaveToJson() {
|
|
return Object.assign(super._SaveToJson(), {
|
|
"direction": this._direction,
|
|
"revolutions": this._revolutions
|
|
})
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
super._LoadFromJson(o);
|
|
this._direction = o["direction"];
|
|
this._revolutions = o["revolutions"]
|
|
}
|
|
}
|
|
C3.AddonData = class AddonData {
|
|
constructor(addonsDataJson, propertyKeyframeDataItem) {
|
|
this._propertyKeyframeDataItem = propertyKeyframeDataItem;
|
|
this._addonDataItems = [];
|
|
C3.TimelineDataManager._CreateDataItems(this._addonDataItems, addonsDataJson, {
|
|
prop: 0,
|
|
map: new Map([["cubic-bezier", AddonDataCubicBezierItem], ["angle", AddonDataAngleItem]])
|
|
}, this)
|
|
}
|
|
Release() {
|
|
this._propertyKeyframeDataItem = null;
|
|
for (const addonDataItem of this._addonDataItems)
|
|
addonDataItem.Release();
|
|
C3.clearArray(this._addonDataItems);
|
|
this._addonDataItems = null
|
|
}
|
|
GetPropertyKeyframeDataItem() {
|
|
return this._propertyKeyframeDataItem
|
|
}
|
|
*addonDataItems() {
|
|
for (const addonDataItem of this._addonDataItems)
|
|
yield addonDataItem
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"addonDataItemsJson": this._addonDataItems.map(addonDataItem=>addonDataItem._SaveToJson())
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
C3.TimelineDataManager._LoadDataItemsFromJson(this._addonDataItems, o["addonDataItemsJson"], {
|
|
prop: "id",
|
|
map: new Map([["cubic-bezier", AddonDataCubicBezierItem], ["angle", AddonDataAngleItem]])
|
|
}, this)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const INITIAL_VALUE_MODE_START_VALUE = "start-value";
|
|
const INITIAL_VALUE_MODE_CURRENT_STATE = "current-state";
|
|
let createdTweens = 0;
|
|
C3.Tween = class Tween extends C3.TimelineState {
|
|
constructor(tweenDataItem, timelineManager) {
|
|
super(`tween-${createdTweens++}`, tweenDataItem, timelineManager);
|
|
this._id = "";
|
|
this._destroyInstanceOnComplete = false;
|
|
this._initialValueMode = INITIAL_VALUE_MODE_START_VALUE;
|
|
this._on_completed_callbacks = null;
|
|
this._on_started_callbacks = null
|
|
}
|
|
GetInstance() {
|
|
const tracks = this.GetTracks();
|
|
if (!tracks || !tracks.length)
|
|
return;
|
|
const track = tracks[0];
|
|
if (!track)
|
|
return;
|
|
const instance = track.GetInstance();
|
|
return track.IsInstanceValid() ? instance : null
|
|
}
|
|
AddStartedCallback(c) {
|
|
if (!this._on_started_callbacks)
|
|
this._on_started_callbacks = [];
|
|
this._on_started_callbacks.push(c)
|
|
}
|
|
AddCompletedCallback(c) {
|
|
if (!this._on_completed_callbacks)
|
|
this._on_completed_callbacks = [];
|
|
this._on_completed_callbacks.push(c)
|
|
}
|
|
RemoveStartedCallback(c) {
|
|
if (!this._on_started_callbacks)
|
|
return;
|
|
const index = this._on_started_callbacks.indexOf(c);
|
|
if (index !== -1)
|
|
this._on_started_callbacks.splice(index, 1)
|
|
}
|
|
RemoveCompletedCallback(c) {
|
|
if (!this._on_completed_callbacks)
|
|
return;
|
|
const index = this._on_completed_callbacks.indexOf(c);
|
|
if (index !== -1)
|
|
this._on_completed_callbacks.splice(index, 1)
|
|
}
|
|
SetStartValue(startValue, propertyName) {
|
|
for (const track of this._tracks)
|
|
for (const propertyTrack of track._propertyTracks) {
|
|
if (propertyTrack.GetPropertyName() !== propertyName)
|
|
continue;
|
|
const propertyTrackData = propertyTrack.GetPropertyTrackData();
|
|
const propertyTrackDataItem = propertyTrack.GetPropertyTrackDataItem();
|
|
const propertyKeyframeDataItem = propertyTrackData.GetFirstPropertyKeyframeDataItem(propertyTrackDataItem);
|
|
propertyKeyframeDataItem.SetValue(startValue);
|
|
propertyKeyframeDataItem.SetAbsoluteValue(startValue)
|
|
}
|
|
}
|
|
_GetPropertyTrackState(propertyName) {
|
|
for (const track of this._tracks)
|
|
for (const propertyTrack of track._propertyTracks)
|
|
if (propertyTrack.GetPropertyName() === propertyName)
|
|
return propertyTrack
|
|
}
|
|
BeforeSetEndValues(properties) {
|
|
for (const propertyName of properties) {
|
|
const propertyTrackState = this._GetPropertyTrackState(propertyName);
|
|
this.SetStartValue(propertyTrackState.GetCurrentState(), propertyName)
|
|
}
|
|
if (this.IsForwardPlayBack()) {
|
|
this.SetTotalTime(this.GetTotalTime() - this.GetTime());
|
|
this._SetTime(0)
|
|
} else {
|
|
this.SetTotalTime(this.GetTime());
|
|
this._SetTime(this.GetTotalTime())
|
|
}
|
|
this.SetInitialStateFromSetTime()
|
|
}
|
|
SetEndValue(endValue, propertyName) {
|
|
const propertyTrackState = this._GetPropertyTrackState(propertyName);
|
|
const propertyTrackData = propertyTrackState.GetPropertyTrackData();
|
|
const propertyTrackDataItem = propertyTrackState.GetPropertyTrackDataItem();
|
|
const propertyKeyframeDataItem = propertyTrackData.GetLastPropertyKeyframeDataItem(propertyTrackDataItem);
|
|
propertyKeyframeDataItem.SetTime(this.GetTotalTime());
|
|
propertyKeyframeDataItem.SetValue(endValue);
|
|
propertyKeyframeDataItem.SetAbsoluteValue(endValue)
|
|
}
|
|
SetId(id) {
|
|
this._id = id
|
|
}
|
|
GetId() {
|
|
return this._id
|
|
}
|
|
SetInitialValueMode(initialValueMode) {
|
|
this._initialValueMode = initialValueMode
|
|
}
|
|
GetInitialValueMode() {
|
|
return this._initialValueMode
|
|
}
|
|
SetDestroyInstanceOnComplete(releaseOnComplete) {
|
|
this._destroyInstanceOnComplete = releaseOnComplete
|
|
}
|
|
GetDestroyInstanceOnComplete() {
|
|
return this._destroyInstanceOnComplete
|
|
}
|
|
OnStarted() {
|
|
if (this._on_started_callbacks)
|
|
for (const c of this._on_started_callbacks)
|
|
c(this);
|
|
if (this.IsComplete())
|
|
return;
|
|
for (const track of this._tracks)
|
|
track.CompareSaveStateWithCurrent()
|
|
}
|
|
OnCompleted() {
|
|
this._completedTick = this._runtime.GetTickCount()
|
|
}
|
|
FinishTriggers() {
|
|
if (this._finishedTriggers)
|
|
return;
|
|
this._finishedTriggers = true;
|
|
if (this._on_completed_callbacks)
|
|
for (const c of this._on_completed_callbacks)
|
|
c(this)
|
|
}
|
|
SetTime(time) {
|
|
this._DeleteIntermediateKeyframes();
|
|
super.SetTime(time)
|
|
}
|
|
SetInitialState(fromSetTime) {
|
|
if (!this.InitialStateSet() && this.GetInitialValueMode() === INITIAL_VALUE_MODE_CURRENT_STATE)
|
|
for (const track of this._tracks)
|
|
track.CompareInitialStateWithCurrent();
|
|
super.SetInitialState(fromSetTime)
|
|
}
|
|
Stop(completed=false) {
|
|
super.Stop(completed);
|
|
if (this.IsComplete())
|
|
return;
|
|
for (const track of this._tracks)
|
|
track.SaveState()
|
|
}
|
|
Reset(render=true, beforeChangeLayout=false) {
|
|
this._DeleteIntermediateKeyframes();
|
|
super.Reset(render, beforeChangeLayout)
|
|
}
|
|
_DeleteIntermediateKeyframes() {
|
|
for (const track of this._tracks) {
|
|
const del = kf=>{
|
|
const time = kf.GetTime();
|
|
const totalTime = this.GetTotalTime();
|
|
return time !== 0 && time !== totalTime
|
|
}
|
|
;
|
|
track.DeleteKeyframes(del);
|
|
track.DeletePropertyKeyframes(del)
|
|
}
|
|
}
|
|
_OnBeforeChangeLayout() {
|
|
if (this.IsReleased())
|
|
return true;
|
|
const instance = this.GetInstance();
|
|
if (instance && instance.GetObjectClass().IsGlobal())
|
|
return false;
|
|
this._timelineManager.CompleteTimeline(this);
|
|
this.ResetBeforeChangeLayout();
|
|
return true
|
|
}
|
|
MaybeTriggerKeyframeReachedConditions() {}
|
|
Tick(deltaTime, timeScale) {
|
|
const instance = this.GetInstance();
|
|
const dt = this.GetRuntime().GetDt(instance);
|
|
super.Tick(dt, 1)
|
|
}
|
|
_SaveToJson() {
|
|
const ret = super._SaveToJson();
|
|
const tweenDataItem = this.GetTimelineDataItem();
|
|
return Object.assign(ret, {
|
|
"tweenDataItemJson": tweenDataItem._SaveToJson(),
|
|
"id": this._id,
|
|
"destroyInstanceOnComplete": this._destroyInstanceOnComplete,
|
|
"initialValueMode": this._initialValueMode
|
|
})
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (!o)
|
|
return;
|
|
const tweenDataItem = this.GetTimelineDataItem();
|
|
tweenDataItem._LoadFromJson(o["tweenDataItemJson"]);
|
|
super._LoadFromJson(o);
|
|
this._id = o["id"];
|
|
this._destroyInstanceOnComplete = o["destroyInstanceOnComplete"];
|
|
this._initialValueMode = o["initialValueMode"]
|
|
}
|
|
static IsPlaying(tween) {
|
|
return tween.IsPlaying()
|
|
}
|
|
static IsPaused(tween) {
|
|
return tween.IsPaused()
|
|
}
|
|
static Build(config) {
|
|
const timelineManager = config.runtime.GetTimelineManager();
|
|
const tweenDataItem = new C3.TimelineDataItem;
|
|
if (config.json) {
|
|
tweenDataItem._LoadFromJson(config.json["tweenDataItemJson"]);
|
|
const tween = new C3.Tween(tweenDataItem,timelineManager);
|
|
tween._LoadFromJson(config.json);
|
|
return tween
|
|
} else {
|
|
const tween = new C3.Tween(tweenDataItem,timelineManager);
|
|
if (!C3.IsArray(config.propertyTracksConfig))
|
|
config.propertyTracksConfig = [config.propertyTracksConfig];
|
|
tween.SetId(config.id);
|
|
tween.SetTags(config.tags);
|
|
tween.SetInitialValueMode(config.initialValueMode);
|
|
tween.SetDestroyInstanceOnComplete(config.releaseOnComplete);
|
|
tween.SetLoop(config.loop);
|
|
tween.SetPingPong(config.pingPong);
|
|
tween.SetTotalTime(config.time);
|
|
tween.SetStep(0);
|
|
tween.SetInterpolationMode("default");
|
|
tween.SetResultMode(config.propertyTracksConfig[0].resultMode);
|
|
const track = tween.AddTrack();
|
|
track.SetInstanceUID(config.instance.GetUID());
|
|
track.SetInterpolationMode("default");
|
|
track.SetResultMode(config.propertyTracksConfig[0].resultMode);
|
|
track.SetEnable(true);
|
|
track.SetObjectClassIndex(config.instance.GetObjectClass().GetIndex());
|
|
track.SetOriginalWidth(config.instance.GetWorldInfo().GetWidth());
|
|
track.SetOriginalHeight(config.instance.GetWorldInfo().GetHeight());
|
|
const startKeyframeDataItem = track.AddKeyframe();
|
|
startKeyframeDataItem.SetTime(0);
|
|
startKeyframeDataItem.SetEase("noease");
|
|
startKeyframeDataItem.SetEnable(true);
|
|
startKeyframeDataItem.SetTags("");
|
|
const endKeyframeDataItem = track.AddKeyframe();
|
|
endKeyframeDataItem.SetTime(config.time);
|
|
endKeyframeDataItem.SetEase("noease");
|
|
endKeyframeDataItem.SetEnable(true);
|
|
endKeyframeDataItem.SetTags("");
|
|
for (const propertyTrackConfig of config.propertyTracksConfig) {
|
|
const propertyTrack = track.AddPropertyTrack();
|
|
propertyTrack.SetSourceAdapterId(propertyTrackConfig.sourceId);
|
|
propertyTrack.SetSourceAdapterArgs(propertyTrackConfig.sourceArgs);
|
|
propertyTrack.SetPropertyName(propertyTrackConfig.property);
|
|
propertyTrack.SetPropertyType(propertyTrackConfig.type);
|
|
propertyTrack.SetMin(NaN);
|
|
propertyTrack.SetMax(NaN);
|
|
propertyTrack.SetInterpolationMode("default");
|
|
propertyTrack.SetResultMode(propertyTrackConfig.resultMode);
|
|
propertyTrack.SetEnable(true);
|
|
const startPropertyKeyframeDataItem = propertyTrack.AddPropertyKeyframe();
|
|
startPropertyKeyframeDataItem.SetType(propertyTrackConfig.valueType);
|
|
startPropertyKeyframeDataItem.SetTime(0);
|
|
startPropertyKeyframeDataItem.SetEase(propertyTrackConfig.ease);
|
|
startPropertyKeyframeDataItem.SetEnable(true);
|
|
startPropertyKeyframeDataItem.SetValue(propertyTrackConfig.startValue);
|
|
startPropertyKeyframeDataItem.SetAbsoluteValue(propertyTrackConfig.startValue);
|
|
const endPropertyKeyframeDataItem = propertyTrack.AddPropertyKeyframe();
|
|
endPropertyKeyframeDataItem.SetType(propertyTrackConfig.valueType);
|
|
endPropertyKeyframeDataItem.SetTime(config.time);
|
|
endPropertyKeyframeDataItem.SetEase(propertyTrackConfig.ease);
|
|
endPropertyKeyframeDataItem.SetEnable(true);
|
|
endPropertyKeyframeDataItem.SetValue(propertyTrackConfig.endValue);
|
|
endPropertyKeyframeDataItem.SetAbsoluteValue(propertyTrackConfig.endValue)
|
|
}
|
|
return tween
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const Ease = self.Ease;
|
|
const NAME = 0;
|
|
const TRANSITION_KEYFRAMES = 1;
|
|
C3.Transition = class Transition extends C3.DefendedBase {
|
|
constructor(data) {
|
|
super();
|
|
this._name = data[NAME];
|
|
this._transitionKeyframes = [];
|
|
for (const transitionKeyframeData of data[TRANSITION_KEYFRAMES]) {
|
|
const transitionKeyframe = C3.TransitionKeyframe.Create(this, transitionKeyframeData);
|
|
this._transitionKeyframes.push(transitionKeyframe)
|
|
}
|
|
this._precalculatedSamples = new Map;
|
|
this._transitionKeyframeCache = new Map;
|
|
this._PreCalcSamples();
|
|
Ease.AddCustomEase(this._name, (t,sv,dv,tt)=>this.Interpolate(t, sv, dv, tt))
|
|
}
|
|
static Create(data) {
|
|
return C3.New(C3.Transition, data)
|
|
}
|
|
Release() {
|
|
for (const transitionKeyframe of this._transitionKeyframes)
|
|
transitionKeyframe.Release();
|
|
C3.clearArray(this._transitionKeyframes);
|
|
this._transitionKeyframes = null;
|
|
this._precalculatedSamples.clear();
|
|
this._precalculatedSamples = null;
|
|
this._transitionKeyframeCache.clear();
|
|
this._transitionKeyframeCache = null
|
|
}
|
|
GetTransitionKeyFrameAt(x) {
|
|
const transitionKeyframe = this._transitionKeyframeCache.get(x);
|
|
if (transitionKeyframe)
|
|
return transitionKeyframe;
|
|
for (const transitionKeyframe of this._transitionKeyframes)
|
|
if (transitionKeyframe.GetValueX() === x) {
|
|
this._transitionKeyframeCache.set(x, transitionKeyframe);
|
|
return transitionKeyframe
|
|
}
|
|
}
|
|
GetFirstTransitionKeyFrameHigherThan(x) {
|
|
for (const transitionKeyframe of this._transitionKeyframes)
|
|
if (transitionKeyframe.GetValueX() > x)
|
|
return transitionKeyframe
|
|
}
|
|
GetFirstTransitionKeyFrameHigherOrEqualThan(x) {
|
|
for (const transitionKeyframe of this._transitionKeyframes)
|
|
if (transitionKeyframe.GetValueX() >= x)
|
|
return transitionKeyframe
|
|
}
|
|
GetFirstTransitionKeyFrameLowerOrEqualThan(x) {
|
|
for (let i = this._transitionKeyframes.length - 1; i >= 0; i--) {
|
|
const transitionKeyframe = this._transitionKeyframes[i];
|
|
if (transitionKeyframe.GetValueX() <= x)
|
|
return transitionKeyframe
|
|
}
|
|
}
|
|
Interpolate(time, startValue, deltaValue, totalTime) {
|
|
const n = time / totalTime;
|
|
let start = this.GetTransitionKeyFrameAt(n);
|
|
let end = null;
|
|
if (start)
|
|
end = this.GetFirstTransitionKeyFrameHigherThan(n);
|
|
else {
|
|
start = this.GetFirstTransitionKeyFrameLowerOrEqualThan(n);
|
|
end = this.GetFirstTransitionKeyFrameHigherOrEqualThan(n)
|
|
}
|
|
const delta = end.GetValueX() - start.GetValueX();
|
|
const nn = C3.mapToRange(n, start.GetValueX(), end.GetValueX(), 0, delta);
|
|
const startX = start.GetValueX();
|
|
const startY = start.GetValueY();
|
|
const anchor1X = start.GetValueX() + start.GetStartAnchorX();
|
|
const anchor1Y = start.GetValueY() + start.GetStartAnchorY();
|
|
const anchor2X = end.GetValueX() + end.GetEndAnchorX();
|
|
const anchor2Y = end.GetValueY() + end.GetEndAnchorY();
|
|
const endX = end.GetValueX();
|
|
const endY = end.GetValueY();
|
|
let ret = Ease.GetRuntimeEase("spline")(nn, startX, startY, anchor1X, anchor1Y, anchor2X, anchor2Y, endX, endY, this._precalculatedSamples.get(start));
|
|
ret += start.GetValueY();
|
|
return (1 - ret) * startValue + ret * (startValue + deltaValue)
|
|
}
|
|
_PreCalcSamples() {
|
|
this._precalculatedSamples.clear();
|
|
for (let i = 0; i < this._transitionKeyframes.length - 1; i++) {
|
|
const transitionKeyframe = this._transitionKeyframes[i];
|
|
if (!transitionKeyframe.GetStartEnable())
|
|
continue;
|
|
const start = transitionKeyframe;
|
|
const end = this._transitionKeyframes[i + 1];
|
|
const startValue = start.GetValueX();
|
|
const anchor1Value = start.GetValueX() + start.GetStartAnchorX();
|
|
const anchor2Value = end.GetValueX() + end.GetEndAnchorX();
|
|
const endValue = end.GetValueX();
|
|
this._precalculatedSamples.set(start, Ease.GetBezierSamples(startValue, anchor1Value, anchor2Value, endValue))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const VALUE_X = 0;
|
|
const VALUE_Y = 1;
|
|
const START_ANCHOR_X = 2;
|
|
const START_ANCHOR_Y = 3;
|
|
const END_ANCHOR_X = 4;
|
|
const END_ANCHOR_Y = 5;
|
|
const START_ENABLE = 6;
|
|
const END_ENABLE = 7;
|
|
C3.TransitionKeyframe = class TransitionKeyframe extends C3.DefendedBase {
|
|
constructor(transition, data) {
|
|
super();
|
|
this._transition = transition;
|
|
this._valueX = data[VALUE_X];
|
|
this._valueY = data[VALUE_Y];
|
|
this._startAnchorX = data[START_ANCHOR_X];
|
|
this._startAnchorY = data[START_ANCHOR_Y];
|
|
this._endAnchorX = data[END_ANCHOR_X];
|
|
this._endAnchorY = data[END_ANCHOR_Y];
|
|
this._startEnable = data[START_ENABLE];
|
|
this._endEnable = data[END_ENABLE]
|
|
}
|
|
Release() {
|
|
this._transition = null
|
|
}
|
|
static Create(transition, data) {
|
|
return C3.New(C3.TransitionKeyframe, transition, data)
|
|
}
|
|
GetValueX() {
|
|
return this._valueX
|
|
}
|
|
GetValueY() {
|
|
return this._valueY
|
|
}
|
|
GetStartAnchorX() {
|
|
return this._startAnchorX
|
|
}
|
|
GetStartAnchorY() {
|
|
return this._startAnchorY
|
|
}
|
|
GetEndAnchorX() {
|
|
return this._endAnchorX
|
|
}
|
|
GetEndAnchorY() {
|
|
return this._endAnchorY
|
|
}
|
|
GetStartEnable() {
|
|
return this._startEnable
|
|
}
|
|
GetEndEnable() {
|
|
return this._endEnable
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.TransitionManager = class TransitionManager extends C3.DefendedBase {
|
|
constructor(runtime) {
|
|
super();
|
|
this._runtime = runtime;
|
|
this._transitions = []
|
|
}
|
|
Release() {
|
|
for (const transition of this._transitions)
|
|
transition.Release();
|
|
C3.clearArray(this._transitions);
|
|
this._transitions = null
|
|
}
|
|
Create(transitionData) {
|
|
this._transitions.push(C3.Transition.Create(transitionData))
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SolStack = class SolStack extends C3.DefendedBase {
|
|
constructor(objectClass) {
|
|
super();
|
|
this._objectClass = objectClass;
|
|
this._stack = [];
|
|
this._stack.push(C3.New(C3.Sol, this));
|
|
this._index = 0;
|
|
this._current = this._stack[0]
|
|
}
|
|
Release() {
|
|
for (const s of this._stack)
|
|
s.Release();
|
|
C3.clearArray(this._stack);
|
|
this._current = null;
|
|
this._objectClass = null
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectClass
|
|
}
|
|
GetCurrentSol() {
|
|
return this._current
|
|
}
|
|
Clear() {
|
|
this.GetCurrentSol().Clear()
|
|
}
|
|
PushClean() {
|
|
const stack = this._stack;
|
|
const index = ++this._index;
|
|
if (index === stack.length) {
|
|
const sol = C3.New(C3.Sol, this);
|
|
stack.push(sol);
|
|
this._current = sol
|
|
} else {
|
|
const sol = stack[index];
|
|
sol.Reset();
|
|
this._current = sol
|
|
}
|
|
}
|
|
PushCopy() {
|
|
const stack = this._stack;
|
|
const index = ++this._index;
|
|
if (index === stack.length)
|
|
stack.push(C3.New(C3.Sol, this));
|
|
const sol = stack[index];
|
|
sol.Copy(stack[index - 1]);
|
|
this._current = sol
|
|
}
|
|
Pop() {
|
|
this._current = this._stack[--this._index]
|
|
}
|
|
RemoveInstances(s) {
|
|
const stack = this._stack;
|
|
for (let i = 0, len = stack.length; i < len; ++i)
|
|
stack[i].RemoveInstances(s)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Sol = class Sol extends C3.DefendedBase {
|
|
constructor(stack) {
|
|
super();
|
|
this._stack = stack;
|
|
this._objectClass = this._stack.GetObjectClass();
|
|
this._eventStack = this._objectClass.GetRuntime().GetEventStack();
|
|
this._selectAll = true;
|
|
this._instances = [];
|
|
this._elseInstances = []
|
|
}
|
|
Release() {
|
|
this.ClearArrays();
|
|
this._stack = null;
|
|
this._objectClass = null;
|
|
this._eventStack = null
|
|
}
|
|
ClearArrays() {
|
|
C3.clearArray(this._instances);
|
|
C3.clearArray(this._elseInstances)
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectClass
|
|
}
|
|
IsSelectAll() {
|
|
return this._selectAll
|
|
}
|
|
HasAnyInstances() {
|
|
if (this._selectAll)
|
|
return !!this._objectClass.GetInstanceCount();
|
|
else
|
|
return !!this._instances.length
|
|
}
|
|
GetInstances() {
|
|
if (this._selectAll)
|
|
return this._objectClass.GetInstances();
|
|
else
|
|
return this._instances
|
|
}
|
|
HasAnyElseInstances() {
|
|
return !!this._elseInstances.length
|
|
}
|
|
GetElseInstances() {
|
|
return this._elseInstances
|
|
}
|
|
GetExpressionInstances() {
|
|
const ret = this.GetInstances();
|
|
if (ret.length)
|
|
return ret;
|
|
else
|
|
return this._elseInstances
|
|
}
|
|
Reset() {
|
|
this._selectAll = true;
|
|
C3.clearArray(this._elseInstances)
|
|
}
|
|
Clear() {
|
|
this._selectAll = true
|
|
}
|
|
Copy(sol) {
|
|
if (sol.IsSelectAll())
|
|
this.Reset();
|
|
else {
|
|
this._selectAll = false;
|
|
C3.shallowAssignArray(this._instances, sol._instances);
|
|
C3.clearArray(this._elseInstances)
|
|
}
|
|
}
|
|
_PushInstance(inst) {
|
|
this._instances.push(inst)
|
|
}
|
|
_PushElseInstance(inst) {
|
|
this._elseInstances.push(inst)
|
|
}
|
|
_SetSelectAll(s) {
|
|
this._selectAll = !!s
|
|
}
|
|
_GetOwnInstances() {
|
|
return this._instances
|
|
}
|
|
_GetOwnElseInstances() {
|
|
return this._elseInstances
|
|
}
|
|
SetSinglePicked(inst) {
|
|
this._selectAll = false;
|
|
C3.clearArray(this._instances);
|
|
this._instances.push(inst)
|
|
}
|
|
SetArrayPicked(arr) {
|
|
this._selectAll = false;
|
|
C3.shallowAssignArray(this._instances, arr)
|
|
}
|
|
SetSetPicked(set) {
|
|
this._selectAll = false;
|
|
C3.clearArray(this._instances);
|
|
for (const item of set)
|
|
this._instances.push(item)
|
|
}
|
|
AddElseInstances(setOfPicked, arrayOfAllPicked) {
|
|
for (const inst of arrayOfAllPicked)
|
|
if (!setOfPicked.has(inst))
|
|
this._elseInstances.push(inst)
|
|
}
|
|
TransferElseInstancesToOwn(setOfPicked) {
|
|
for (const inst of setOfPicked)
|
|
this._instances.push(inst);
|
|
C3.arrayRemoveAllInSet(this._elseInstances, setOfPicked)
|
|
}
|
|
PickOne(inst) {
|
|
if (!inst)
|
|
return;
|
|
if (this._eventStack.GetCurrentStackFrame().GetCurrentEvent().IsOrBlock()) {
|
|
if (this.IsSelectAll()) {
|
|
C3.clearArray(this._instances);
|
|
C3.shallowAssignArray(this._elseInstances, inst.GetObjectClass().GetInstances());
|
|
this._selectAll = false
|
|
}
|
|
const i = this._elseInstances.indexOf(inst);
|
|
if (i !== -1) {
|
|
this._instances.push(this._elseInstances[i]);
|
|
this._elseInstances.splice(i, 1)
|
|
}
|
|
} else
|
|
this.SetSinglePicked(inst)
|
|
}
|
|
RemoveInstances(s) {
|
|
C3.arrayRemoveAllInSet(this._instances, s);
|
|
C3.arrayRemoveAllInSet(this._elseInstances, s)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.EventStack = class EventStack extends C3.DefendedBase {
|
|
constructor(eventSheetManager) {
|
|
super();
|
|
this._eventSheetManager = eventSheetManager;
|
|
this._runtime = this._eventSheetManager.GetRuntime();
|
|
this._stack = [];
|
|
this._stack.push(C3.New(C3.EventStackFrame, this, null));
|
|
this._index = 0;
|
|
this._expFuncStack = []
|
|
}
|
|
Release() {
|
|
for (const e of this._stack)
|
|
e.Release();
|
|
C3.clearArray(this._stack);
|
|
C3.clearArray(this._expFuncStack);
|
|
this._eventSheetManager = null;
|
|
this._runtime = null
|
|
}
|
|
GetEventSheetManager() {
|
|
return this._eventSheetManager
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetCurrentStackFrame() {
|
|
return this._stack[this._index]
|
|
}
|
|
Push(currentEvent) {
|
|
const stack = this._stack;
|
|
const index = ++this._index;
|
|
if (index === stack.length) {
|
|
const ret = C3.New(C3.EventStackFrame, this, currentEvent);
|
|
stack.push(ret);
|
|
return ret
|
|
} else {
|
|
const ret = stack[index];
|
|
ret.Reset(currentEvent);
|
|
return ret
|
|
}
|
|
}
|
|
Pop() {
|
|
--this._index
|
|
}
|
|
PushExpFunc(frame) {
|
|
this._expFuncStack.push(frame)
|
|
}
|
|
PopExpFunc() {
|
|
this._expFuncStack.pop()
|
|
}
|
|
GetCurrentExpFuncStackFrame() {
|
|
const expFuncStack = this._expFuncStack;
|
|
if (expFuncStack.length === 0)
|
|
return null;
|
|
else
|
|
return expFuncStack[expFuncStack.length - 1]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.EventStackFrame = class EventStackFrame extends C3.DefendedBase {
|
|
constructor(stack, currentEvent) {
|
|
super();
|
|
this._stack = stack;
|
|
this._runtime = this._stack.GetRuntime();
|
|
this._currentEvent = currentEvent;
|
|
this._cndIndex = 0;
|
|
this._actIndex = 0;
|
|
this._lastEventTrue = false;
|
|
this._elseBranchRan = false;
|
|
this._expressionObjectClass = null;
|
|
this._functionReturnType = 0;
|
|
this._functionReturnValue = 0
|
|
}
|
|
Release() {
|
|
this.Reset(null);
|
|
this._stack = null;
|
|
this._runtime = null
|
|
}
|
|
Reset(currentEvent) {
|
|
this._currentEvent = currentEvent;
|
|
this._cndIndex = 0;
|
|
this._actIndex = 0;
|
|
this._lastEventTrue = false;
|
|
this._elseBranchRan = false
|
|
}
|
|
_Restore(currentEvent, actIndex) {
|
|
this._currentEvent = currentEvent;
|
|
this._cndIndex = 0;
|
|
this._actIndex = actIndex
|
|
}
|
|
ResetQuick() {
|
|
this._cndIndex = 0;
|
|
this._actIndex = 0
|
|
}
|
|
GetCurrentEvent() {
|
|
return this._currentEvent
|
|
}
|
|
SetCurrentEvent(currentEvent) {
|
|
this._currentEvent = currentEvent
|
|
}
|
|
GetConditionIndex() {
|
|
return this._cndIndex
|
|
}
|
|
SetConditionIndex(i) {
|
|
this._cndIndex = i
|
|
}
|
|
GetActionIndex() {
|
|
return this._actIndex
|
|
}
|
|
SetActionIndex(i) {
|
|
this._actIndex = i
|
|
}
|
|
SetLastEventTrue(t) {
|
|
this._lastEventTrue = !!t
|
|
}
|
|
GetLastEventTrue() {
|
|
return this._lastEventTrue
|
|
}
|
|
SetElseBranchRan(r) {
|
|
this._elseBranchRan = !!r
|
|
}
|
|
GetElseBranchRan() {
|
|
return this._elseBranchRan
|
|
}
|
|
SetExpressionObjectClass(objectClass) {
|
|
this._expressionObjectClass = objectClass
|
|
}
|
|
GetExpressionObjectClass() {
|
|
return this._expressionObjectClass
|
|
}
|
|
InitCallFunctionExpression(returnType, defaultReturnValue) {
|
|
this._functionReturnType = returnType;
|
|
this._functionReturnValue = defaultReturnValue
|
|
}
|
|
GetFunctionReturnType() {
|
|
return this._functionReturnType
|
|
}
|
|
SetFunctionReturnValue(v) {
|
|
this._functionReturnValue = v
|
|
}
|
|
GetFunctionReturnValue() {
|
|
return this._functionReturnValue
|
|
}
|
|
IsSolModifierAfterCnds() {
|
|
const currentEvent = this._currentEvent;
|
|
if (currentEvent.IsSolWriterAfterCnds())
|
|
return true;
|
|
if (this._cndIndex < currentEvent.GetConditionCount() - 1)
|
|
return !!currentEvent.GetSolModifiers().length;
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.LocalVarStack = class LocalVarStack extends C3.DefendedBase {
|
|
constructor(eventSheetManager) {
|
|
super();
|
|
this._eventSheetManager = eventSheetManager;
|
|
this._runtime = this._eventSheetManager.GetRuntime();
|
|
this._stack = [];
|
|
this._index = -1;
|
|
this._current = null;
|
|
this._initialValues = []
|
|
}
|
|
Release() {
|
|
C3.clearArray(this._stack);
|
|
this._eventSheetManager = null;
|
|
this._runtime = null
|
|
}
|
|
_SetInitialValues(initialValues) {
|
|
this._initialValues = initialValues;
|
|
const arr = this._initialValues.slice(0);
|
|
this._stack.push(arr);
|
|
this._index = 0;
|
|
this._current = arr
|
|
}
|
|
GetEventSheetManager() {
|
|
return this._eventSheetManager
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetCurrent() {
|
|
return this._current
|
|
}
|
|
Push() {
|
|
const index = ++this._index;
|
|
const stack = this._stack;
|
|
if (index === stack.length)
|
|
stack.push(this._initialValues.slice(0));
|
|
else
|
|
C3.shallowAssignArray(stack[index], this._initialValues);
|
|
this._current = stack[index]
|
|
}
|
|
Pop() {
|
|
this._current = this._stack[--this._index]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.LoopStack = class LoopStack extends C3.DefendedBase {
|
|
constructor(eventSheetManager) {
|
|
super();
|
|
this._eventSheetManager = eventSheetManager;
|
|
this._runtime = this._eventSheetManager.GetRuntime();
|
|
this._stack = [];
|
|
this._index = -1
|
|
}
|
|
Release() {
|
|
C3.clearArray(this._stack);
|
|
this._eventSheetManager = null;
|
|
this._runtime = null
|
|
}
|
|
GetEventSheetManager() {
|
|
return this._eventSheetManager
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
IsInLoop() {
|
|
return this._index >= 0
|
|
}
|
|
GetCurrent() {
|
|
return this._stack[this._index]
|
|
}
|
|
Push() {
|
|
++this._index;
|
|
if (this._index === this._stack.length) {
|
|
const ret = C3.New(C3.Loop, this);
|
|
this._stack.push(ret);
|
|
return ret
|
|
} else {
|
|
const ret = this._stack[this._index];
|
|
ret.Reset();
|
|
return ret
|
|
}
|
|
}
|
|
Pop() {
|
|
--this._index
|
|
}
|
|
FindByName(name) {
|
|
const stack = this._stack;
|
|
for (let i = this._index; i >= 0; --i) {
|
|
const loop = stack[i];
|
|
if (loop.GetName() === name)
|
|
return loop
|
|
}
|
|
return null
|
|
}
|
|
_GetStack() {
|
|
return this._stack.slice(0, this._index + 1)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Loop = class Loop extends C3.DefendedBase {
|
|
constructor(loopStack) {
|
|
super();
|
|
this._loopStack = loopStack;
|
|
this._name = "";
|
|
this._index = 0;
|
|
this._isStopped = false;
|
|
this._end = NaN
|
|
}
|
|
Reset() {
|
|
this._name = "";
|
|
this._index = 0;
|
|
this._isStopped = false;
|
|
this._end = NaN
|
|
}
|
|
SetName(name) {
|
|
this._name = name
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
SetIndex(i) {
|
|
this._index = i
|
|
}
|
|
GetIndex() {
|
|
return this._index
|
|
}
|
|
Stop() {
|
|
this._isStopped = true
|
|
}
|
|
IsStopped() {
|
|
return this._isStopped
|
|
}
|
|
SetEnd(e) {
|
|
this._end = e
|
|
}
|
|
GetEnd() {
|
|
return this._end
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.ArrayStack = class ArrayStack extends C3.DefendedBase {
|
|
constructor() {
|
|
super();
|
|
this._stack = [];
|
|
this._index = -1
|
|
}
|
|
Release() {
|
|
C3.clearArray(this._stack)
|
|
}
|
|
GetCurrent() {
|
|
return this._stack[this._index]
|
|
}
|
|
Push() {
|
|
++this._index;
|
|
if (this._index === this._stack.length) {
|
|
const ret = [];
|
|
this._stack.push(ret);
|
|
return ret
|
|
} else
|
|
return this._stack[this._index]
|
|
}
|
|
Pop() {
|
|
--this._index
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
function SortSolArray(a, b) {
|
|
return a.GetIndex() - b.GetIndex()
|
|
}
|
|
function IsSolArrayIdentical(a, b) {
|
|
for (let i = 0, len = a.length; i < len; ++i)
|
|
if (a[i] !== b[i])
|
|
return false;
|
|
return true
|
|
}
|
|
C3.EventSheetManager = class EventSheetManager extends C3.DefendedBase {
|
|
constructor(runtime) {
|
|
super();
|
|
this._runtime = runtime;
|
|
this._allSheets = [];
|
|
this._sheetsByName = new Map;
|
|
this._allGroups = [];
|
|
this._groupsByName = new Map;
|
|
this._blocksBySid = new Map;
|
|
this._cndsBySid = new Map;
|
|
this._actsBySid = new Map;
|
|
this._allUniqueSolModifiers = new Map;
|
|
this._eventVarsBySid = new Map;
|
|
this._nextLocalVarIndex = 0;
|
|
this._allGlobalVars = [];
|
|
this._allLocalVars = [];
|
|
this._localVarInitialValues = [];
|
|
this._functionBlocksByName = new Map;
|
|
this._eventStack = C3.New(C3.EventStack, this);
|
|
this._localVarStack = C3.New(C3.LocalVarStack, this);
|
|
this._loopStack = C3.New(C3.LoopStack, this);
|
|
this._triggersToPostInit = [];
|
|
this._queuedTriggers = [];
|
|
this._queuedDebugTriggers = [];
|
|
this._runningEventsDepth = 0;
|
|
this._executingTriggerDepth = 0;
|
|
this._blockFlushingDepth = 0;
|
|
this._scheduledWaits = [];
|
|
this._asyncActionPromises = [];
|
|
self["c3_callFunction"] = (name,params)=>this._InvokeFunctionFromJS(name, params)
|
|
}
|
|
Release() {
|
|
this.ClearAllScheduledWaits();
|
|
this._eventStack.Release();
|
|
this._eventStack = null;
|
|
this._localVarStack.Release();
|
|
this._localVarStack = null;
|
|
C3.clearArray(this._queuedTriggers);
|
|
C3.clearArray(this._queuedDebugTriggers);
|
|
this._runtime = null;
|
|
C3.clearArray(this._allSheets);
|
|
this._sheetsByName.clear()
|
|
}
|
|
Create(eventSheetData) {
|
|
const eventSheet = C3.New(C3.EventSheet, this, eventSheetData);
|
|
this._allSheets.push(eventSheet);
|
|
this._sheetsByName.set(eventSheet.GetName().toLowerCase(), eventSheet)
|
|
}
|
|
_AddTriggerToPostInit(trig) {
|
|
this._triggersToPostInit.push(trig)
|
|
}
|
|
_PostInit() {
|
|
for (const functionBlock of this._functionBlocksByName.values())
|
|
functionBlock._PostInit(false);
|
|
for (const sheet of this._allSheets)
|
|
sheet._PostInit();
|
|
for (const sheet of this._allSheets)
|
|
sheet._UpdateDeepIncludes();
|
|
for (const trig of this._triggersToPostInit)
|
|
trig._PostInit(false);
|
|
C3.clearArray(this._triggersToPostInit);
|
|
this._localVarStack._SetInitialValues(this._localVarInitialValues)
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetEventSheetByName(name) {
|
|
return this._sheetsByName.get(name.toLowerCase()) || null
|
|
}
|
|
_RegisterGroup(group) {
|
|
this._allGroups.push(group);
|
|
this._groupsByName.set(group.GetGroupName(), group)
|
|
}
|
|
_RegisterEventBlock(eventBlock) {
|
|
this._blocksBySid.set(eventBlock.GetSID(), eventBlock)
|
|
}
|
|
_RegisterCondition(condition) {
|
|
this._cndsBySid.set(condition.GetSID(), condition)
|
|
}
|
|
_RegisterAction(action) {
|
|
this._actsBySid.set(action.GetSID(), action)
|
|
}
|
|
_RegisterFunctionBlock(functionBlock) {
|
|
this._functionBlocksByName.set(functionBlock.GetFunctionName().toLowerCase(), functionBlock)
|
|
}
|
|
_RegisterEventVariable(ev) {
|
|
this._eventVarsBySid.set(ev.GetSID(), ev);
|
|
if (ev.IsGlobal())
|
|
this._allGlobalVars.push(ev);
|
|
else
|
|
this._allLocalVars.push(ev)
|
|
}
|
|
_DeduplicateSolModifierList(arr) {
|
|
if (arr.length >= 2)
|
|
arr.sort(SortSolArray);
|
|
let candidateList = this._allUniqueSolModifiers.get(arr.length);
|
|
if (!candidateList) {
|
|
candidateList = [];
|
|
this._allUniqueSolModifiers.set(arr.length, candidateList)
|
|
}
|
|
for (let i = 0, len = candidateList.length; i < len; ++i) {
|
|
const candidate = candidateList[i];
|
|
if (IsSolArrayIdentical(arr, candidate))
|
|
return candidate
|
|
}
|
|
candidateList.push(arr);
|
|
return arr
|
|
}
|
|
_GetNextLocalVarIndex(eventVar) {
|
|
this._localVarInitialValues.push(eventVar.GetInitialValue());
|
|
return this._nextLocalVarIndex++
|
|
}
|
|
GetEventStack() {
|
|
return this._eventStack
|
|
}
|
|
GetCurrentEventStackFrame() {
|
|
return this.GetEventStack().GetCurrentStackFrame()
|
|
}
|
|
GetCurrentEvent() {
|
|
return this.GetCurrentEventStackFrame().GetCurrentEvent()
|
|
}
|
|
GetCurrentCondition() {
|
|
const frame = this.GetCurrentEventStackFrame();
|
|
const event = frame.GetCurrentEvent();
|
|
return event.GetConditionAt(frame.GetConditionIndex())
|
|
}
|
|
GetCurrentAction() {
|
|
const frame = this.GetCurrentEventStackFrame();
|
|
const event = frame.GetCurrentEvent();
|
|
return event.GetActionAt(frame.GetActionIndex())
|
|
}
|
|
GetLocalVarStack() {
|
|
return this._localVarStack
|
|
}
|
|
GetLoopStack() {
|
|
return this._loopStack
|
|
}
|
|
GetAllLocalVariablesInScope(fromRow) {
|
|
const ret = [];
|
|
fromRow = fromRow.GetScopeParent();
|
|
while (fromRow) {
|
|
C3.appendArray(ret, fromRow._GetAllLocalVariablesInScope());
|
|
fromRow = fromRow.GetScopeParent()
|
|
}
|
|
return ret
|
|
}
|
|
_GetLocalVariablesScriptInterface(fromRow) {
|
|
const localVarDescriptors = {};
|
|
for (const v of this.GetAllLocalVariablesInScope(fromRow))
|
|
localVarDescriptors[v.GetJsPropName()] = v._GetScriptInterfaceDescriptor();
|
|
return Object.create(Object.prototype, localVarDescriptors)
|
|
}
|
|
GetEventVariableBySID(sid) {
|
|
return this._eventVarsBySid.get(sid) || null
|
|
}
|
|
GetEventBlockBySID(sid) {
|
|
return this._blocksBySid.get(sid) || null
|
|
}
|
|
GetConditionBySID(sid) {
|
|
return this._cndsBySid.get(sid) || null
|
|
}
|
|
GetActionBySID(sid) {
|
|
return this._actsBySid.get(sid) || null
|
|
}
|
|
GetFunctionBlockByName(name) {
|
|
return this._functionBlocksByName.get(name.toLowerCase()) || null
|
|
}
|
|
GetAllGlobalVariables() {
|
|
return this._allGlobalVars
|
|
}
|
|
GetAllLocalVariables() {
|
|
return this._allLocalVars
|
|
}
|
|
ResetAllGlobalsToInitialValue() {
|
|
for (const ev of this._allGlobalVars)
|
|
ev.ResetToInitialValue()
|
|
}
|
|
GetEventGroupByName(name) {
|
|
return this._groupsByName.get(name.toLowerCase()) || null
|
|
}
|
|
GetEventGroupBySID(sid) {
|
|
const group = this._blocksBySid.get(sid);
|
|
if (group && group.IsGroup())
|
|
return group;
|
|
else
|
|
return null
|
|
}
|
|
GetAllGroups() {
|
|
return this._allGroups
|
|
}
|
|
ResetAllGroupsInitialActivation() {
|
|
for (const group of this._allGroups)
|
|
group.ResetInitialActivation()
|
|
}
|
|
_ResetAllHasRunFlags() {
|
|
for (const sheet of this._allSheets)
|
|
sheet._ResetHasRunFlag()
|
|
}
|
|
RunEvents(layoutManager) {
|
|
this._ResetAllHasRunFlags();
|
|
this._runningEventsDepth++;
|
|
for (const layout of layoutManager.runningLayouts()) {
|
|
const eventSheet = layout.GetEventSheet();
|
|
if (!eventSheet)
|
|
continue;
|
|
this._runtime.PushCurrentLayout(layout);
|
|
eventSheet.Run();
|
|
this._runtime.PopCurrentLayout()
|
|
}
|
|
this._runningEventsDepth--
|
|
}
|
|
async DebugRunEvents(layoutManager) {
|
|
this._ResetAllHasRunFlags();
|
|
this._runningEventsDepth++;
|
|
for (const breakEventObject of this._DebugRunEventsGen(layoutManager))
|
|
await this._runtime.DebugBreak(breakEventObject);
|
|
this._runningEventsDepth--
|
|
}
|
|
*_DebugRunEventsGen(layoutManager) {
|
|
for (const layout of layoutManager.runningLayouts()) {
|
|
const eventSheet = layout.GetEventSheet();
|
|
if (!eventSheet)
|
|
continue;
|
|
this._runtime.PushCurrentLayout(layout);
|
|
yield*eventSheet.DebugRun();
|
|
this._runtime.PopCurrentLayout()
|
|
}
|
|
}
|
|
_Trigger(layoutManager, method, inst, behaviorType) {
|
|
let ret = false;
|
|
if (!layoutManager.GetMainRunningLayout())
|
|
return this.QueueTrigger(method, inst, behaviorType);
|
|
this._executingTriggerDepth++;
|
|
for (const layout of layoutManager.runningLayouts()) {
|
|
const eventSheet = layout.GetEventSheet();
|
|
if (!eventSheet)
|
|
continue;
|
|
this._runtime.PushCurrentLayout(layout);
|
|
for (const includeSheet of eventSheet.deepIncludes()) {
|
|
const result = includeSheet._Trigger(method, inst, behaviorType);
|
|
ret = ret || result
|
|
}
|
|
const result2 = eventSheet._Trigger(method, inst, behaviorType);
|
|
ret = ret || result2;
|
|
this._runtime.PopCurrentLayout()
|
|
}
|
|
this._executingTriggerDepth--;
|
|
return ret
|
|
}
|
|
*_DebugTrigger(layoutManager, method, inst, behaviorType) {
|
|
let ret = false;
|
|
if (!layoutManager.GetMainRunningLayout())
|
|
return this.QueueTrigger(method, inst, behaviorType);
|
|
this._executingTriggerDepth++;
|
|
for (const layout of layoutManager.runningLayouts()) {
|
|
const eventSheet = layout.GetEventSheet();
|
|
if (!eventSheet)
|
|
continue;
|
|
this._runtime.PushCurrentLayout(layout);
|
|
for (const includeSheet of eventSheet.deepIncludes()) {
|
|
const result = yield*includeSheet._DebugTrigger(method, inst, behaviorType);
|
|
ret = ret || result
|
|
}
|
|
const result2 = yield*eventSheet._DebugTrigger(method, inst, behaviorType);
|
|
ret = ret || result2;
|
|
this._runtime.PopCurrentLayout()
|
|
}
|
|
this._executingTriggerDepth--;
|
|
return ret
|
|
}
|
|
QueueTrigger(method, inst, behaviorType) {
|
|
this._queuedTriggers.push([method, inst, behaviorType]);
|
|
return false
|
|
}
|
|
QueueDebugTrigger(method, inst, behaviorType) {
|
|
let resolve = null;
|
|
const ret = new Promise(r=>resolve = r);
|
|
this._queuedDebugTriggers.push([method, inst, behaviorType, resolve]);
|
|
return ret
|
|
}
|
|
*_RunQueuedDebugTriggersGen() {
|
|
if (this._runtime.HitBreakpoint())
|
|
throw new Error("should not be in breakpoint");
|
|
const layoutManager = this._runtime.GetLayoutManager();
|
|
while (this._queuedDebugTriggers.length) {
|
|
const [method,inst,behaviorType,resolve] = this._queuedDebugTriggers.shift();
|
|
const ret = yield*this._DebugTrigger(layoutManager, method, inst, behaviorType);
|
|
resolve(ret)
|
|
}
|
|
}
|
|
async RunQueuedDebugTriggersAsync() {
|
|
for (const breakEventObject of this._RunQueuedDebugTriggersGen())
|
|
await this._runtime.DebugBreak(breakEventObject)
|
|
}
|
|
_FastTrigger(layoutManager, method, inst, value) {
|
|
let ret = false;
|
|
const layout = layoutManager.GetMainRunningLayout();
|
|
const eventSheet = layout.GetEventSheet();
|
|
if (!eventSheet)
|
|
return;
|
|
this._executingTriggerDepth++;
|
|
this._runtime.PushCurrentLayout(layout);
|
|
const deepIncludes = eventSheet.deepIncludes();
|
|
for (let i = 0, len = deepIncludes.length; i < len; ++i) {
|
|
const result = deepIncludes[i]._FastTrigger(method, inst, value);
|
|
ret = ret || result
|
|
}
|
|
const result2 = eventSheet._FastTrigger(method, inst, value);
|
|
ret = ret || result2;
|
|
this._runtime.PopCurrentLayout();
|
|
this._executingTriggerDepth--;
|
|
return ret
|
|
}
|
|
*_DebugFastTrigger(layoutManager, method, inst, value) {
|
|
let ret = false;
|
|
const layout = layoutManager.GetMainRunningLayout();
|
|
const eventSheet = layout.GetEventSheet();
|
|
if (!eventSheet)
|
|
return;
|
|
this._executingTriggerDepth++;
|
|
this._runtime.PushCurrentLayout(layout);
|
|
const deepIncludes = eventSheet.deepIncludes();
|
|
for (let i = 0, len = deepIncludes.length; i < len; ++i) {
|
|
const result = yield*deepIncludes[i]._DebugFastTrigger(method, inst, value);
|
|
ret = ret || result
|
|
}
|
|
const result2 = yield*eventSheet._DebugFastTrigger(method, inst, value);
|
|
ret = ret || result2;
|
|
this._runtime.PopCurrentLayout();
|
|
this._executingTriggerDepth--;
|
|
return ret
|
|
}
|
|
GetTriggerDepth() {
|
|
return this._executingTriggerDepth
|
|
}
|
|
IsInTrigger() {
|
|
return this.GetTriggerDepth() > 0
|
|
}
|
|
_IncTriggerDepth() {
|
|
return ++this._executingTriggerDepth
|
|
}
|
|
_DecTriggerDepth() {
|
|
--this._executingTriggerDepth
|
|
}
|
|
IsRunningEvents() {
|
|
return this._runningEventsDepth > 0
|
|
}
|
|
IsInEventEngine() {
|
|
return this.IsRunningEvents() || this.IsInTrigger()
|
|
}
|
|
_RunQueuedTriggers(layoutManager) {
|
|
for (const [method,inst,behaviorType] of this._queuedTriggers)
|
|
this._Trigger(layoutManager, method, inst, behaviorType);
|
|
C3.clearArray(this._queuedTriggers)
|
|
}
|
|
BlockFlushingInstances(e) {
|
|
if (e)
|
|
this._blockFlushingDepth++;
|
|
else
|
|
this._blockFlushingDepth--
|
|
}
|
|
IsFlushingBlocked() {
|
|
return this._blockFlushingDepth > 0
|
|
}
|
|
ClearSol(solModifiers) {
|
|
for (let i = 0, len = solModifiers.length; i < len; ++i)
|
|
solModifiers[i].GetSolStack().Clear()
|
|
}
|
|
PushCleanSol(solModifiers) {
|
|
for (let i = 0, len = solModifiers.length; i < len; ++i)
|
|
solModifiers[i].GetSolStack().PushClean()
|
|
}
|
|
PushCopySol(solModifiers) {
|
|
for (let i = 0, len = solModifiers.length; i < len; ++i)
|
|
solModifiers[i].GetSolStack().PushCopy()
|
|
}
|
|
PopSol(solModifiers) {
|
|
for (let i = 0, len = solModifiers.length; i < len; ++i)
|
|
solModifiers[i].GetSolStack().Pop()
|
|
}
|
|
AddScheduledWait() {
|
|
const w = C3.New(C3.ScheduledWait, this);
|
|
this._scheduledWaits.push(w);
|
|
return w
|
|
}
|
|
scheduledWaits() {
|
|
return this._scheduledWaits
|
|
}
|
|
RunScheduledWaits() {
|
|
if (!this._scheduledWaits.length)
|
|
return;
|
|
const frame = this.GetCurrentEventStackFrame();
|
|
let didAnyRun = false;
|
|
this._runningEventsDepth++;
|
|
for (let i = 0, len = this._scheduledWaits.length; i < len; ++i) {
|
|
const w = this._scheduledWaits[i];
|
|
if (w._ShouldRun())
|
|
w._Run(frame);
|
|
if (w.ShouldRelease())
|
|
didAnyRun = true
|
|
}
|
|
if (didAnyRun)
|
|
this._FilterScheduledWaitsToRelease();
|
|
this._runningEventsDepth--
|
|
}
|
|
async DebugRunScheduledWaits() {
|
|
if (!this._scheduledWaits.length)
|
|
return;
|
|
const frame = this.GetCurrentEventStackFrame();
|
|
let didAnyRun = false;
|
|
this._runningEventsDepth++;
|
|
for (let i = 0, len = this._scheduledWaits.length; i < len; ++i) {
|
|
const w = this._scheduledWaits[i];
|
|
if (w._ShouldRun())
|
|
await w._DebugRun(frame);
|
|
if (w.ShouldRelease())
|
|
didAnyRun = true
|
|
}
|
|
if (didAnyRun)
|
|
this._FilterScheduledWaitsToRelease();
|
|
this._runningEventsDepth--
|
|
}
|
|
_FilterScheduledWaitsToRelease() {
|
|
const toRelease = C3.arrayFilterOut(this._scheduledWaits, w=>w.ShouldRelease());
|
|
for (const w of toRelease)
|
|
w.Release()
|
|
}
|
|
ClearAllScheduledWaits() {
|
|
for (const w of this._scheduledWaits)
|
|
w.Release();
|
|
C3.clearArray(this._scheduledWaits)
|
|
}
|
|
RemoveInstancesFromScheduledWaits(s) {
|
|
for (const w of this._scheduledWaits)
|
|
w.RemoveInstances(s)
|
|
}
|
|
AddAsyncActionPromise(p) {
|
|
this._asyncActionPromises.push(p)
|
|
}
|
|
ClearAsyncActionPromises() {
|
|
C3.clearArray(this._asyncActionPromises)
|
|
}
|
|
GetPromiseForAllAsyncActions() {
|
|
const ret = Promise.all(this._asyncActionPromises);
|
|
this._asyncActionPromises = [];
|
|
return ret
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"groups": this._SaveGroupsToJson(),
|
|
"cnds": this._SaveCndsToJson(),
|
|
"acts": this._SaveActsToJson(),
|
|
"vars": this._SaveVarsToJson(),
|
|
"waits": this._SaveScheduledWaitsToJson()
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
this._LoadGroupsFromJson(o["groups"]);
|
|
this._LoadCndsFromJson(o["cnds"]);
|
|
this._LoadActsFromJson(o["acts"]);
|
|
this._LoadVarsFromJson(o["vars"]);
|
|
this._LoadScheduledWaitsFromJson(o["waits"])
|
|
}
|
|
_SaveGroupsToJson() {
|
|
const o = {};
|
|
for (const group of this.GetAllGroups())
|
|
o[group.GetSID().toString()] = group.IsGroupActive();
|
|
return o
|
|
}
|
|
_LoadGroupsFromJson(o) {
|
|
for (const [sidStr,data] of Object.entries(o)) {
|
|
const sid = parseInt(sidStr, 10);
|
|
const group = this.GetEventGroupBySID(sid);
|
|
if (group)
|
|
group.SetGroupActive(data)
|
|
}
|
|
}
|
|
_SaveCndsToJson() {
|
|
const o = {};
|
|
for (const [sid,cnd] of this._cndsBySid) {
|
|
const data = cnd._SaveToJson();
|
|
if (data)
|
|
o[sid.toString()] = data
|
|
}
|
|
return o
|
|
}
|
|
_LoadCndsFromJson(o) {
|
|
const map = new Map;
|
|
for (const [sidStr,data] of Object.entries(o))
|
|
map.set(parseInt(sidStr, 10), data);
|
|
for (const [sid,cnd] of this._cndsBySid)
|
|
cnd._LoadFromJson(map.get(sid) || null)
|
|
}
|
|
_SaveActsToJson() {
|
|
const o = {};
|
|
for (const [sid,act] of this._actsBySid) {
|
|
const data = act._SaveToJson();
|
|
if (data)
|
|
o[sid.toString()] = data
|
|
}
|
|
return o
|
|
}
|
|
_LoadActsFromJson(o) {
|
|
const map = new Map;
|
|
for (const [sidStr,data] of Object.entries(o))
|
|
map.set(parseInt(sidStr, 10), data);
|
|
for (const [sid,act] of this._actsBySid)
|
|
act._LoadFromJson(map.get(sid) || null)
|
|
}
|
|
_SaveVarsToJson() {
|
|
const o = {};
|
|
for (const [sid,eventVar] of this._eventVarsBySid)
|
|
if (!eventVar.IsConstant() && (eventVar.IsGlobal() || eventVar.IsStatic()))
|
|
o[sid.toString()] = eventVar.GetValue();
|
|
return o
|
|
}
|
|
_LoadVarsFromJson(o) {
|
|
for (const [sidStr,data] of Object.entries(o)) {
|
|
const sid = parseInt(sidStr, 10);
|
|
const eventVar = this.GetEventVariableBySID(sid);
|
|
if (eventVar)
|
|
eventVar.SetValue(data)
|
|
}
|
|
}
|
|
_SaveScheduledWaitsToJson() {
|
|
return this._scheduledWaits.filter(w=>!w.IsPromise()).map(w=>w._SaveToJson())
|
|
}
|
|
_LoadScheduledWaitsFromJson(arr) {
|
|
this.ClearAllScheduledWaits();
|
|
for (const data of arr) {
|
|
const sw = C3.ScheduledWait._CreateFromJson(this, data);
|
|
if (sw)
|
|
this._scheduledWaits.push(sw)
|
|
}
|
|
}
|
|
_GetPerfRecords() {
|
|
return [...this._runtime.GetLayoutManager().runningLayouts()].map(l=>l.GetEventSheet()).filter(eventSheet=>eventSheet).map(e=>e._GetPerfRecord())
|
|
}
|
|
FindFirstFunctionBlockParent(eventRow) {
|
|
while (eventRow) {
|
|
const scopeParent = eventRow.GetScopeParent();
|
|
if (scopeParent instanceof C3.FunctionBlock)
|
|
return scopeParent;
|
|
eventRow = eventRow.GetParent()
|
|
}
|
|
return null
|
|
}
|
|
_InvokeFunctionFromJS(name, params) {
|
|
if (!Array.isArray(params))
|
|
params = [];
|
|
const functionBlock = this.GetFunctionBlockByName(name.toLowerCase());
|
|
if (!functionBlock)
|
|
return null;
|
|
if (!functionBlock.IsEnabled())
|
|
return functionBlock.GetDefaultReturnValue();
|
|
const functionParameters = functionBlock.GetFunctionParameters();
|
|
if (params.length < functionParameters.length) {
|
|
params = params.slice(0);
|
|
do
|
|
params.push(functionParameters[params.length].GetInitialValue());
|
|
while (params.length < functionParameters.length)
|
|
}
|
|
const callEventBlock = functionBlock.GetEventBlock();
|
|
return callEventBlock.RunAsExpressionFunctionCall(callEventBlock.GetSolModifiersIncludingParents(), functionBlock.GetReturnType(), functionBlock.GetDefaultReturnValue(), ...params)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.EventSheet = class EventSheet extends C3.DefendedBase {
|
|
constructor(eventSheetManager, data) {
|
|
super();
|
|
this._eventSheetManager = eventSheetManager;
|
|
this._runtime = eventSheetManager.GetRuntime();
|
|
this._name = data[0];
|
|
this._events = [];
|
|
this._triggers = new Map;
|
|
this._fastTriggers = new Map;
|
|
this._eventsByDisplayNumber = new Map;
|
|
this._hasRun = false;
|
|
this._shallowIncludes = [];
|
|
this._deepIncludes = [];
|
|
this._alreadyIncludedSheets = new Set;
|
|
for (const eventData of data[1])
|
|
this._CreateEvent(eventData, null, this._events);
|
|
this._perfRecord = this._runtime.IsDebug() ? {
|
|
type: "sheet",
|
|
name: this._name,
|
|
totalTimeCounter: 0,
|
|
children: []
|
|
} : null
|
|
}
|
|
Release() {
|
|
this._eventSheetManager = null;
|
|
this._runtime = null
|
|
}
|
|
_CreateEvent(eventData, parent, nontriggers) {
|
|
switch (eventData[0]) {
|
|
case 0:
|
|
case 3:
|
|
this._CreateEventBlock(eventData, parent, nontriggers);
|
|
break;
|
|
case 1:
|
|
this._CreateEventVariable(eventData, parent, nontriggers);
|
|
break;
|
|
case 2:
|
|
this._CreateInclude(eventData, parent, nontriggers);
|
|
break;
|
|
case 4:
|
|
this._CreateFunctionBlock(eventData, parent);
|
|
break;
|
|
case 5:
|
|
this._CreateScriptBlock(eventData, parent, nontriggers);
|
|
break;
|
|
default:
|
|
throw new Error("invalid event type");
|
|
}
|
|
}
|
|
_CreateEventBlock(data, parent, nontriggers) {
|
|
const eventBlock = C3.EventBlock.Create(this, parent, data);
|
|
if (eventBlock.IsOrBlock()) {
|
|
nontriggers.push(eventBlock);
|
|
const conditions = eventBlock.GetConditions();
|
|
for (let i = 0, len = conditions.length; i < len; ++i)
|
|
if (conditions[i].IsTrigger())
|
|
this._InitTrigger(eventBlock, i)
|
|
} else if (eventBlock.IsTrigger())
|
|
this._InitTrigger(eventBlock, 0);
|
|
else
|
|
nontriggers.push(eventBlock)
|
|
}
|
|
_CreateFunctionBlock(data, parent) {
|
|
const functionBlock = C3.FunctionBlock.Create(this, parent, data);
|
|
this._eventSheetManager._RegisterFunctionBlock(functionBlock)
|
|
}
|
|
_CreateEventVariable(data, parent, nontriggers) {
|
|
const v = C3.EventVariable.Create(this, parent, data);
|
|
nontriggers.push(v)
|
|
}
|
|
_CreateInclude(data, parent, nontriggers) {
|
|
const include = C3.EventInclude.Create(this, parent, data);
|
|
nontriggers.push(include)
|
|
}
|
|
_CreateScriptBlock(data, parent, nontriggers) {
|
|
const scriptBlock = C3.EventScript.Create(this, parent, data);
|
|
nontriggers.push(scriptBlock)
|
|
}
|
|
_InitTrigger(eventBlock, i) {
|
|
if (!eventBlock.IsOrBlock())
|
|
this._eventSheetManager._AddTriggerToPostInit(eventBlock);
|
|
const cnd = eventBlock.GetConditionAt(i);
|
|
const func = cnd._GetFunc();
|
|
const objectClass = cnd.GetObjectClass();
|
|
if (cnd.IsFastTrigger()) {
|
|
let methodMap = this._fastTriggers.get(objectClass);
|
|
if (!methodMap) {
|
|
methodMap = new Map;
|
|
this._fastTriggers.set(objectClass, methodMap)
|
|
}
|
|
const value = cnd.GetFastTriggerValue().toLowerCase();
|
|
let valueMap = methodMap.get(func);
|
|
if (!valueMap) {
|
|
valueMap = new Map;
|
|
methodMap.set(func, valueMap)
|
|
}
|
|
let triggerArr = valueMap.get(value);
|
|
if (!triggerArr) {
|
|
triggerArr = [];
|
|
valueMap.set(value, triggerArr)
|
|
}
|
|
triggerArr.push([eventBlock, i])
|
|
} else {
|
|
let ocInfo = this._triggers.get(objectClass);
|
|
if (!ocInfo) {
|
|
ocInfo = {
|
|
methodMap: new Map,
|
|
behaviors: new Map
|
|
};
|
|
this._triggers.set(objectClass, ocInfo)
|
|
}
|
|
const behaviorType = cnd.GetBehaviorType();
|
|
let methodMap;
|
|
if (behaviorType) {
|
|
methodMap = ocInfo.behaviors.get(behaviorType);
|
|
if (!methodMap) {
|
|
methodMap = new Map;
|
|
ocInfo.behaviors.set(behaviorType, methodMap)
|
|
}
|
|
} else
|
|
methodMap = ocInfo.methodMap;
|
|
let triggerArr = methodMap.get(func);
|
|
if (!triggerArr) {
|
|
triggerArr = [];
|
|
methodMap.set(func, triggerArr)
|
|
}
|
|
triggerArr.push([eventBlock, i])
|
|
}
|
|
}
|
|
_PostInit() {
|
|
const events = this._events;
|
|
for (let i = 0, len = events.length; i < len; ++i) {
|
|
const hasElseBlock = i < len - 1 && events[i + 1]instanceof C3.EventBlock && events[i + 1].IsElseBlock();
|
|
events[i]._PostInit(hasElseBlock)
|
|
}
|
|
}
|
|
_AddShallowInclude(include) {
|
|
this._shallowIncludes.push(include)
|
|
}
|
|
_UpdateDeepIncludes() {
|
|
C3.clearArray(this._deepIncludes);
|
|
this._AddDeepIncludes(this);
|
|
this._alreadyIncludedSheets.clear()
|
|
}
|
|
_AddDeepIncludes(rootSheet) {
|
|
const deepIncludes = rootSheet._deepIncludes;
|
|
const alreadyIncludedSheets = rootSheet._alreadyIncludedSheets;
|
|
for (const include of this._shallowIncludes) {
|
|
const sheet = include.GetIncludeSheet();
|
|
if (!include.IsActive() || rootSheet === sheet || alreadyIncludedSheets.has(sheet))
|
|
continue;
|
|
alreadyIncludedSheets.add(sheet);
|
|
sheet._AddDeepIncludes(rootSheet);
|
|
deepIncludes.push(sheet)
|
|
}
|
|
}
|
|
deepIncludes() {
|
|
return this._deepIncludes
|
|
}
|
|
GetEventSheetManager() {
|
|
return this._eventSheetManager
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
_RegisterEventByDisplayNumber(eventBlock, displayNumber) {
|
|
this._eventsByDisplayNumber.set(displayNumber, eventBlock)
|
|
}
|
|
_GetEventByDisplayNumber(displayNumber) {
|
|
return this._eventsByDisplayNumber.get(displayNumber) || null
|
|
}
|
|
_ResetHasRunFlag() {
|
|
this._hasRun = false
|
|
}
|
|
Run() {
|
|
if (this._hasRun)
|
|
return;
|
|
const runtime = this._runtime;
|
|
const profile = runtime.IsCPUProfiling();
|
|
const startTime = profile ? performance.now() : 0;
|
|
this._hasRun = true;
|
|
const eventSheetManager = this.GetEventSheetManager();
|
|
const frame = eventSheetManager.GetCurrentEventStackFrame();
|
|
for (const e of this._events) {
|
|
e.Run(frame);
|
|
eventSheetManager.ClearSol(e.GetSolModifiers());
|
|
eventSheetManager.ClearAsyncActionPromises();
|
|
runtime.FlushPendingInstances()
|
|
}
|
|
frame.Reset(null);
|
|
if (profile)
|
|
this._perfRecord.totalTimeCounter += performance.now() - startTime
|
|
}
|
|
*DebugRun() {
|
|
if (this._hasRun)
|
|
return;
|
|
this._hasRun = true;
|
|
const runtime = this._runtime;
|
|
const eventSheetManager = this.GetEventSheetManager();
|
|
const frame = eventSheetManager.GetCurrentEventStackFrame();
|
|
for (const e of this._events) {
|
|
yield*e.DebugRun(frame);
|
|
eventSheetManager.ClearSol(e.GetSolModifiers());
|
|
eventSheetManager.ClearAsyncActionPromises();
|
|
runtime.FlushPendingInstances()
|
|
}
|
|
frame.Reset(null)
|
|
}
|
|
_Trigger(method, inst, behaviorType) {
|
|
if (inst) {
|
|
const objectClass = inst.GetObjectClass();
|
|
let ret = false;
|
|
let r = this._TriggerForClass(method, inst, objectClass, behaviorType);
|
|
ret = ret || r;
|
|
for (const family of objectClass.GetFamilies()) {
|
|
r = this._TriggerForClass(method, inst, family, behaviorType);
|
|
ret = ret || r
|
|
}
|
|
} else
|
|
return this._TriggerForClass(method, inst, null, null)
|
|
}
|
|
_TriggerForClass(method, inst, objectClass, behaviorType) {
|
|
const ocInfo = this._triggers.get(objectClass);
|
|
if (!ocInfo)
|
|
return false;
|
|
const methodMap = behaviorType ? ocInfo.behaviors.get(behaviorType) : ocInfo.methodMap;
|
|
if (!methodMap)
|
|
return false;
|
|
const triggerList = methodMap.get(method);
|
|
if (!triggerList)
|
|
return false;
|
|
let ret = false;
|
|
for (const [trigger,index] of triggerList) {
|
|
const r = this._ExecuteTrigger(inst, trigger, index);
|
|
ret = ret || r
|
|
}
|
|
return ret
|
|
}
|
|
*_DebugTrigger(method, inst, behaviorType) {
|
|
if (inst) {
|
|
const objectClass = inst.GetObjectClass();
|
|
let ret = false;
|
|
let r = yield*this._DebugTriggerForClass(method, inst, objectClass, behaviorType);
|
|
ret = ret || r;
|
|
for (const family of objectClass.GetFamilies()) {
|
|
r = yield*this._DebugTriggerForClass(method, inst, family, behaviorType);
|
|
ret = ret || r
|
|
}
|
|
} else
|
|
return yield*this._DebugTriggerForClass(method, inst, null, null)
|
|
}
|
|
*_DebugTriggerForClass(method, inst, objectClass, behaviorType) {
|
|
const ocInfo = this._triggers.get(objectClass);
|
|
if (!ocInfo)
|
|
return false;
|
|
const methodMap = behaviorType ? ocInfo.behaviors.get(behaviorType) : ocInfo.methodMap;
|
|
if (!methodMap)
|
|
return false;
|
|
const triggerList = methodMap.get(method);
|
|
if (!triggerList)
|
|
return false;
|
|
let ret = false;
|
|
for (const [trigger,index] of triggerList) {
|
|
let r;
|
|
if (trigger.DebugCanRunFast())
|
|
r = this._ExecuteTrigger(inst, trigger, index);
|
|
else
|
|
r = yield*this._DebugExecuteTrigger(inst, trigger, index);
|
|
ret = ret || r
|
|
}
|
|
return ret
|
|
}
|
|
_FastTrigger(method, inst, value) {
|
|
const objectClass = inst.GetObjectClass();
|
|
const methodMap = this._fastTriggers.get(objectClass);
|
|
if (!methodMap)
|
|
return false;
|
|
const valueMap = methodMap.get(method);
|
|
if (!valueMap)
|
|
return false;
|
|
const triggerList = valueMap.get(value);
|
|
if (!triggerList)
|
|
return false;
|
|
let ret = false;
|
|
for (let i = 0, len = triggerList.length; i < len; ++i) {
|
|
const t = triggerList[i];
|
|
const r = this._ExecuteTrigger(null, t[0], t[1]);
|
|
ret = ret || r
|
|
}
|
|
return ret
|
|
}
|
|
*_DebugFastTrigger(method, inst, value) {
|
|
const objectClass = inst.GetObjectClass();
|
|
const methodMap = this._fastTriggers.get(objectClass);
|
|
if (!methodMap)
|
|
return false;
|
|
const valueMap = methodMap.get(method);
|
|
if (!valueMap)
|
|
return false;
|
|
const triggerList = valueMap.get(value);
|
|
if (!triggerList)
|
|
return false;
|
|
let ret = false;
|
|
for (let i = 0, len = triggerList.length; i < len; ++i) {
|
|
const t = triggerList[i];
|
|
const trigger = t[0];
|
|
const index = t[1];
|
|
let r;
|
|
if (trigger.DebugCanRunFast())
|
|
r = this._ExecuteTrigger(null, trigger, index);
|
|
else
|
|
r = yield*this._DebugExecuteTrigger(null, trigger, index);
|
|
ret = ret || r
|
|
}
|
|
return ret
|
|
}
|
|
_ExecuteTrigger(inst, trigger, index) {
|
|
const runtime = this._runtime;
|
|
const eventSheetManager = this._eventSheetManager;
|
|
const currentEvent = eventSheetManager.GetCurrentEvent();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const triggerDepth = eventSheetManager.GetTriggerDepth();
|
|
let ret = false;
|
|
if (currentEvent)
|
|
eventSheetManager.PushCleanSol(currentEvent.GetSolModifiersIncludingParents());
|
|
eventSheetManager.PushCleanSol(trigger.GetSolModifiersIncludingParents());
|
|
const isRecursive = triggerDepth > 1;
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Push();
|
|
const frame = eventStack.Push(trigger);
|
|
if (inst) {
|
|
const objectClass = trigger.GetConditions()[index].GetObjectClass();
|
|
const sol = objectClass.GetCurrentSol();
|
|
sol.SetSinglePicked(inst);
|
|
if (inst.IsInContainer())
|
|
inst.SetSiblingsSinglePicked()
|
|
}
|
|
let okToRun = true;
|
|
if (trigger.GetParent()) {
|
|
const parents = trigger.GetTriggerParents();
|
|
for (let i = 0, len = parents.length; i < len; ++i)
|
|
if (!parents[i].RunPreTrigger(frame)) {
|
|
okToRun = false;
|
|
break
|
|
}
|
|
}
|
|
if (okToRun) {
|
|
runtime.IncrementExecCount();
|
|
if (trigger.IsOrBlock())
|
|
trigger.RunOrBlockTrigger(frame, index);
|
|
else
|
|
trigger.Run(frame);
|
|
ret = frame.GetLastEventTrue()
|
|
}
|
|
eventStack.Pop();
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Pop();
|
|
eventSheetManager.PopSol(trigger.GetSolModifiersIncludingParents());
|
|
if (currentEvent)
|
|
eventSheetManager.PopSol(currentEvent.GetSolModifiersIncludingParents());
|
|
if (!currentEvent && triggerDepth === 1 && !eventSheetManager.IsFlushingBlocked())
|
|
runtime.FlushPendingInstances();
|
|
return ret
|
|
}
|
|
*_DebugExecuteTrigger(inst, trigger, index) {
|
|
const runtime = this._runtime;
|
|
const eventSheetManager = this._eventSheetManager;
|
|
const currentEvent = eventSheetManager.GetCurrentEvent();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const triggerDepth = eventSheetManager.GetTriggerDepth();
|
|
let ret = false;
|
|
if (currentEvent)
|
|
eventSheetManager.PushCleanSol(currentEvent.GetSolModifiersIncludingParents());
|
|
eventSheetManager.PushCleanSol(trigger.GetSolModifiersIncludingParents());
|
|
const isRecursive = triggerDepth > 1;
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Push();
|
|
const frame = eventStack.Push(trigger);
|
|
if (inst) {
|
|
const objectClass = trigger.GetConditions()[index].GetObjectClass();
|
|
const sol = objectClass.GetCurrentSol();
|
|
sol.SetSinglePicked(inst);
|
|
if (inst.IsInContainer())
|
|
inst.SetSiblingsSinglePicked()
|
|
}
|
|
let okToRun = true;
|
|
if (trigger.GetParent()) {
|
|
const parents = trigger.GetTriggerParents();
|
|
for (let i = 0, len = parents.length; i < len; ++i)
|
|
if (!(yield*parents[i].DebugRunPreTrigger(frame))) {
|
|
okToRun = false;
|
|
break
|
|
}
|
|
}
|
|
if (okToRun) {
|
|
runtime.IncrementExecCount();
|
|
if (trigger.IsOrBlock())
|
|
yield*trigger.DebugRunOrBlockTrigger(frame, index);
|
|
else
|
|
yield*trigger.DebugRun(frame);
|
|
ret = frame.GetLastEventTrue()
|
|
}
|
|
eventStack.Pop();
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Pop();
|
|
eventSheetManager.PopSol(trigger.GetSolModifiersIncludingParents());
|
|
if (currentEvent)
|
|
eventSheetManager.PopSol(currentEvent.GetSolModifiersIncludingParents());
|
|
if (!currentEvent && triggerDepth === 1 && !eventSheetManager.IsFlushingBlocked())
|
|
runtime.FlushPendingInstances();
|
|
return ret
|
|
}
|
|
_GetPerfRecord() {
|
|
return this._perfRecord
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const EMPTY_ARRAY = [];
|
|
function NoActions(frame, index) {
|
|
return true
|
|
}
|
|
function *DebugNoActions(frame, index) {
|
|
return true
|
|
}
|
|
C3.EventBlock = class EventBlock extends C3.DefendedBase {
|
|
constructor(eventSheet, parent, data) {
|
|
super();
|
|
this._eventSheet = eventSheet;
|
|
this._runtime = eventSheet.GetRuntime();
|
|
this._parent = parent;
|
|
this._scopeParent = null;
|
|
this._eventStack = this._runtime.GetEventSheetManager().GetEventStack();
|
|
this._solModifiers = [];
|
|
this._solModifiersIncludingParents = [];
|
|
this._hasGotSolModifiersIncludingParents = false;
|
|
this._isSolWriterAfterCnds = false;
|
|
this._isTopLevelGroup = false;
|
|
this._hasElseBlock = false;
|
|
this._isOrBlock = !!data[2];
|
|
this._isElseBlock = false;
|
|
this._triggerParents = null;
|
|
this._conditions = [];
|
|
this._actions = [];
|
|
this._subEvents = [];
|
|
this._RunActions = NoActions;
|
|
this._DebugRunActions = DebugNoActions;
|
|
this._isGroup = false;
|
|
this._isInitiallyActive = false;
|
|
this._groupName = "";
|
|
this._isGroupActive = false;
|
|
this._containedIncludes = null;
|
|
this._perfRecord = null;
|
|
this._sid = data[4];
|
|
this._displayNumber = data[5];
|
|
this._eventSheet._RegisterEventByDisplayNumber(this, this._displayNumber);
|
|
this._debugData = this._runtime.IsDebug() ? {
|
|
isBreakpoint: data[3][0],
|
|
isBreakable: data[3][1],
|
|
canRunAllConditionsFast: false,
|
|
canRunAllActionsFast: false,
|
|
canRunAllSubEventsFast: false,
|
|
canRunSelfFast: false
|
|
} : null;
|
|
this.GetEventSheetManager()._RegisterEventBlock(this);
|
|
if (data[0] === 3)
|
|
this._InitGroup(data[1]);
|
|
let index = 0;
|
|
for (const cndData of data[6]) {
|
|
const condition = C3.Condition.Create(this, cndData, index++);
|
|
this._conditions.push(condition);
|
|
this._AddSolModifier(condition.GetObjectClass())
|
|
}
|
|
index = 0;
|
|
for (const actData of data[7]) {
|
|
const action = C3.Action.Create(this, actData, index++);
|
|
this._actions.push(action)
|
|
}
|
|
if (data.length === 9) {
|
|
const subEventsData = data[8];
|
|
for (const eventData of subEventsData)
|
|
this._eventSheet._CreateEvent(eventData, this, this._subEvents)
|
|
}
|
|
if (this._conditions.length)
|
|
this._isElseBlock = this._conditions[0].GetObjectClass() === null && this._conditions[0]._GetFunc() === C3.Plugins.System.Cnds.Else;
|
|
if (this._conditions.length === 0)
|
|
this._conditions = EMPTY_ARRAY;
|
|
if (this._actions.length === 0)
|
|
this._actions = EMPTY_ARRAY;
|
|
if (this._subEvents.length === 0)
|
|
this._subEvents = EMPTY_ARRAY
|
|
}
|
|
static Create(eventSheet, parent, data) {
|
|
return C3.New(C3.EventBlock, eventSheet, parent, data)
|
|
}
|
|
_InitGroup(groupData) {
|
|
this._isGroup = true;
|
|
this._isInitiallyActive = !!groupData[0];
|
|
this._isGroupActive = this._isInitiallyActive;
|
|
this._groupName = groupData[1].toLowerCase();
|
|
this._containedIncludes = [];
|
|
this.GetEventSheetManager()._RegisterGroup(this);
|
|
if (this._runtime.IsDebug())
|
|
this._perfRecord = {
|
|
type: "group",
|
|
name: groupData[1],
|
|
totalTimeCounter: 0,
|
|
children: []
|
|
}
|
|
}
|
|
_AddContainedInclude(include) {
|
|
this._containedIncludes.push(include)
|
|
}
|
|
_AddContainerSolModifierToList(objectClass, arr) {
|
|
for (const containerType of objectClass.GetContainer().objectTypes())
|
|
if (!arr.includes(containerType))
|
|
arr.push(containerType)
|
|
}
|
|
_AddSolModifierToList(objectClass, arr) {
|
|
if (!objectClass)
|
|
return;
|
|
if (!arr.includes(objectClass))
|
|
arr.push(objectClass);
|
|
if (objectClass.IsFamily())
|
|
for (const familyMember of objectClass.GetFamilyMembers()) {
|
|
if (familyMember.IsInContainer())
|
|
this._AddContainerSolModifierToList(familyMember, arr)
|
|
}
|
|
else if (objectClass.IsInContainer())
|
|
this._AddContainerSolModifierToList(objectClass, arr)
|
|
}
|
|
_AddSolModifier(objectClass) {
|
|
this._AddSolModifierToList(objectClass, this._solModifiers)
|
|
}
|
|
_AddParentSolModifier(objectClass) {
|
|
this._AddSolModifierToList(objectClass, this._solModifiersIncludingParents)
|
|
}
|
|
SetAllSolModifiers() {
|
|
this._solModifiers = this._runtime.GetAllObjectClasses()
|
|
}
|
|
_PostInit(hasElse) {
|
|
this._hasElseBlock = !!hasElse;
|
|
this._IdentifyTopLevelGroup();
|
|
this._IdentifyTriggerParents();
|
|
for (const c of this._conditions)
|
|
c._PostInit();
|
|
if (this._actions.length > 0) {
|
|
let hasAnyActionWithReturnType = false;
|
|
for (const a of this._actions) {
|
|
a._PostInit();
|
|
if (a.HasReturnType())
|
|
hasAnyActionWithReturnType = true
|
|
}
|
|
if (hasAnyActionWithReturnType) {
|
|
this._RunActions = this._RunActions_ReturnValue;
|
|
this._DebugRunActions = this._DebugRunActions_ReturnValue
|
|
} else {
|
|
this._RunActions = this._RunActions_Fast;
|
|
this._DebugRunActions = this._DebugRunActions_Fast
|
|
}
|
|
}
|
|
const subEvents = this._subEvents;
|
|
for (let i = 0, len = subEvents.length; i < len; ++i) {
|
|
const hasElseBlock = i < len - 1 && subEvents[i + 1]instanceof C3.EventBlock && subEvents[i + 1].IsElseBlock();
|
|
subEvents[i]._PostInit(hasElseBlock)
|
|
}
|
|
if (this._debugData)
|
|
this._UpdateCanRunFast();
|
|
if (this._perfRecord)
|
|
this._GetPerfRecordParent()._GetPerfRecord().children.push(this._perfRecord)
|
|
}
|
|
_GetPerfRecord() {
|
|
return this._perfRecord
|
|
}
|
|
_GetPerfRecordParent() {
|
|
let p = this.GetParent();
|
|
while (p) {
|
|
if (p.IsGroup())
|
|
return p;
|
|
p = p.GetParent()
|
|
}
|
|
return this._eventSheet
|
|
}
|
|
_UpdateCanRunFast() {
|
|
const dd = this._debugData;
|
|
dd.canRunAllConditionsFast = this._conditions.every(c=>c.DebugCanRunFast());
|
|
dd.canRunAllActionsFast = this._actions.every(a=>a.DebugCanRunFast());
|
|
dd.canRunAllSubEventsFast = this._subEvents.every(s=>s.DebugCanRunFast());
|
|
dd.canRunSelfFast = dd.canRunAllConditionsFast && dd.canRunAllActionsFast && dd.canRunAllSubEventsFast
|
|
}
|
|
_UpdateCanRunFastRecursive() {
|
|
let e = this;
|
|
do {
|
|
e._UpdateCanRunFast();
|
|
e = e.GetParent()
|
|
} while (e)
|
|
}
|
|
_IdentifyTopLevelGroup() {
|
|
if (!this.IsGroup())
|
|
return;
|
|
let p = this.GetParent();
|
|
this._isTopLevelGroup = true;
|
|
while (p) {
|
|
if (!p.IsGroup()) {
|
|
this._isTopLevelGroup = false;
|
|
break
|
|
}
|
|
p = p.GetParent()
|
|
}
|
|
}
|
|
_IdentifySolModifiersIncludingParents() {
|
|
const allObjectClasses = this._runtime.GetAllObjectClasses();
|
|
if (this._solModifiers === allObjectClasses)
|
|
this._solModifiersIncludingParents = allObjectClasses;
|
|
else {
|
|
this._solModifiersIncludingParents = C3.cloneArray(this._solModifiers);
|
|
let p = this.GetParent();
|
|
while (p) {
|
|
for (const o of p._solModifiers)
|
|
this._AddParentSolModifier(o);
|
|
p = p.GetParent()
|
|
}
|
|
const eventSheetManager = this.GetEventSheetManager();
|
|
this._solModifiers = eventSheetManager._DeduplicateSolModifierList(this._solModifiers);
|
|
this._solModifiersIncludingParents = eventSheetManager._DeduplicateSolModifierList(this._solModifiersIncludingParents)
|
|
}
|
|
}
|
|
_IdentifyTriggerParents() {
|
|
if (!this.HasAnyTriggeredCondition())
|
|
return;
|
|
this._triggerParents = [];
|
|
let p = this.GetParent();
|
|
while (p) {
|
|
this._triggerParents.push(p);
|
|
p = p.GetParent()
|
|
}
|
|
this._triggerParents.reverse()
|
|
}
|
|
SetSolWriterAfterCnds() {
|
|
this._isSolWriterAfterCnds = true;
|
|
if (this._parent)
|
|
this._parent.SetSolWriterAfterCnds()
|
|
}
|
|
IsSolWriterAfterCnds() {
|
|
return this._isSolWriterAfterCnds
|
|
}
|
|
GetSolModifiers() {
|
|
return this._solModifiers
|
|
}
|
|
GetSolModifiersIncludingParents() {
|
|
if (!this._hasGotSolModifiersIncludingParents) {
|
|
this._hasGotSolModifiersIncludingParents = true;
|
|
this._IdentifySolModifiersIncludingParents()
|
|
}
|
|
return this._solModifiersIncludingParents
|
|
}
|
|
HasSolModifier(objectClass) {
|
|
return this._solModifiers.includes(objectClass)
|
|
}
|
|
GetTriggerParents() {
|
|
return this._triggerParents
|
|
}
|
|
GetEventSheet() {
|
|
return this._eventSheet
|
|
}
|
|
GetEventSheetManager() {
|
|
return this._eventSheet.GetEventSheetManager()
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetParent() {
|
|
return this._parent
|
|
}
|
|
_SetScopeParent(p) {
|
|
this._scopeParent = p
|
|
}
|
|
GetScopeParent() {
|
|
return this._scopeParent || this._parent
|
|
}
|
|
GetDisplayNumber() {
|
|
return this._displayNumber
|
|
}
|
|
IsDebugBreakable() {
|
|
return this._debugData && this._debugData.isBreakable
|
|
}
|
|
IsDebugBreakpoint() {
|
|
return this.IsDebugBreakable() && this._debugData.isBreakpoint
|
|
}
|
|
_SetDebugBreakpoint(b) {
|
|
this._debugData.isBreakpoint = !!b;
|
|
this._UpdateCanRunFastRecursive()
|
|
}
|
|
IsGroup() {
|
|
return this._isGroup
|
|
}
|
|
IsTopLevelGroup() {
|
|
return this._isTopLevelGroup
|
|
}
|
|
IsElseBlock() {
|
|
return this._isElseBlock
|
|
}
|
|
HasElseBlock() {
|
|
return this._hasElseBlock
|
|
}
|
|
GetGroupName() {
|
|
return this._groupName
|
|
}
|
|
IsGroupActive() {
|
|
return this._isGroupActive
|
|
}
|
|
ResetInitialActivation() {
|
|
this.SetGroupActive(this._isInitiallyActive)
|
|
}
|
|
SetGroupActive(a) {
|
|
a = !!a;
|
|
if (!this._isGroup)
|
|
throw new Error("not a group");
|
|
if (this._isGroupActive === a)
|
|
return;
|
|
this._isGroupActive = a;
|
|
for (const include of this._containedIncludes)
|
|
include.UpdateActive();
|
|
if (this._containedIncludes.length) {
|
|
const currentLayout = this._runtime.GetCurrentLayout();
|
|
const mainEventSheet = currentLayout.GetEventSheet();
|
|
if (mainEventSheet)
|
|
mainEventSheet._UpdateDeepIncludes()
|
|
}
|
|
}
|
|
GetSID() {
|
|
return this._sid
|
|
}
|
|
IsOrBlock() {
|
|
return this._isOrBlock
|
|
}
|
|
IsTrigger() {
|
|
return this._conditions.length && this._conditions[0].IsTrigger()
|
|
}
|
|
IsForFunctionBlock() {
|
|
return this._scopeParent && this._scopeParent instanceof C3.FunctionBlock
|
|
}
|
|
HasAnyTriggeredCondition() {
|
|
return this.IsForFunctionBlock() || this._conditions.some(c=>c.IsTrigger())
|
|
}
|
|
GetConditions() {
|
|
return this._conditions
|
|
}
|
|
GetConditionCount() {
|
|
return this._conditions.length
|
|
}
|
|
GetConditionAt(i) {
|
|
i = Math.floor(i);
|
|
if (i < 0 || i >= this._conditions.length)
|
|
throw new RangeError("invalid condition index");
|
|
return this._conditions[i]
|
|
}
|
|
GetConditionByDebugIndex(i) {
|
|
return this.GetConditionAt(i)
|
|
}
|
|
IsFirstConditionOfType(cnd) {
|
|
let i = cnd.GetIndex();
|
|
if (i === 0)
|
|
return true;
|
|
--i;
|
|
for (; i >= 0; --i)
|
|
if (this._conditions[i].GetObjectClass() === cnd.GetObjectClass())
|
|
return false;
|
|
return true
|
|
}
|
|
GetActions() {
|
|
return this._actions
|
|
}
|
|
GetActionCount() {
|
|
return this._actions.length
|
|
}
|
|
GetActionAt(i) {
|
|
i = Math.floor(i);
|
|
if (i < 0 || i >= this._actions.length)
|
|
throw new RangeError("invalid action index");
|
|
return this._actions[i]
|
|
}
|
|
GetActionByDebugIndex(i) {
|
|
i = Math.floor(i);
|
|
const ret = this._actions.find(a=>a.GetDebugIndex() === i);
|
|
if (!ret)
|
|
throw new RangeError("invalid action debug index");
|
|
return ret
|
|
}
|
|
_HasActionIndex(i) {
|
|
i = Math.floor(i);
|
|
return i >= 0 && i < this._actions.length
|
|
}
|
|
GetSubEvents() {
|
|
return this._subEvents
|
|
}
|
|
_GetAllLocalVariablesInScope() {
|
|
return this._subEvents.filter(e=>e instanceof C3.EventVariable)
|
|
}
|
|
RunPreTrigger(frame) {
|
|
frame.SetCurrentEvent(this);
|
|
let isAnyTrue = false;
|
|
const conditions = this._conditions;
|
|
for (let i = 0, len = conditions.length; i < len; ++i) {
|
|
const c = conditions[i];
|
|
frame.SetConditionIndex(i);
|
|
if (c.IsLooping())
|
|
throw new Error("trigger cannot be used as sub-event to a loop");
|
|
if (c.Run())
|
|
isAnyTrue = true;
|
|
else if (!this._isOrBlock)
|
|
return false
|
|
}
|
|
return this._isOrBlock ? isAnyTrue : true
|
|
}
|
|
RunOrBlockTrigger(frame, index) {
|
|
frame.SetCurrentEvent(this);
|
|
if (this._conditions[index].Run()) {
|
|
if (this._RunActions(frame, 0))
|
|
this._RunSubEvents(frame);
|
|
frame.SetLastEventTrue(true)
|
|
}
|
|
}
|
|
*DebugRunPreTrigger(frame) {
|
|
frame.SetCurrentEvent(this);
|
|
let isAnyTrue = false;
|
|
const conditions = this._conditions;
|
|
for (let i = 0, len = conditions.length; i < len; ++i) {
|
|
const c = conditions[i];
|
|
frame.SetConditionIndex(i);
|
|
if (c.IsLooping())
|
|
throw new Error("trigger cannot be used as sub-event to a loop");
|
|
let ret;
|
|
if (c.DebugCanRunFast())
|
|
ret = c.Run();
|
|
else
|
|
ret = yield*c.DebugRun();
|
|
if (ret)
|
|
isAnyTrue = true;
|
|
else if (!this._isOrBlock)
|
|
return false
|
|
}
|
|
return this._isOrBlock ? isAnyTrue : true
|
|
}
|
|
*DebugRunOrBlockTrigger(frame, index) {
|
|
frame.SetCurrentEvent(this);
|
|
const c = this._conditions[index];
|
|
let ret;
|
|
if (c.DebugCanRunFast())
|
|
ret = c.Run();
|
|
else
|
|
ret = yield*c.DebugRun();
|
|
if (ret) {
|
|
let actRet;
|
|
if (this.DebugCanRunActionsFast())
|
|
actRet = this._RunActions(frame, 0);
|
|
else
|
|
actRet = yield*this._DebugRunActions(frame, 0);
|
|
if (actRet)
|
|
if (this.DebugCanRunSubEventsFast())
|
|
this._RunSubEvents();
|
|
else
|
|
yield*this._DebugRunSubEvents();
|
|
frame.SetLastEventTrue(true)
|
|
}
|
|
}
|
|
Run(frame) {
|
|
frame.SetCurrentEvent(this);
|
|
if (!this._isElseBlock)
|
|
frame.SetElseBranchRan(false);
|
|
if (this._isOrBlock)
|
|
this._RunOrBlock(frame);
|
|
else
|
|
this._RunAndBlock(frame)
|
|
}
|
|
*DebugRun(frame) {
|
|
if (this.IsDebugBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
frame.SetCurrentEvent(this);
|
|
if (!this._isElseBlock)
|
|
frame.SetElseBranchRan(false);
|
|
if (this._isOrBlock)
|
|
yield*this._DebugRunOrBlock(frame);
|
|
else
|
|
yield*this._DebugRunAndBlock(frame)
|
|
}
|
|
_RunOrBlock(frame) {
|
|
const conditions = this._conditions;
|
|
let isAnyTrue = conditions.length === 0;
|
|
for (let i = 0, len = conditions.length; i < len; ++i) {
|
|
const c = conditions[i];
|
|
if (c.IsTrigger())
|
|
continue;
|
|
frame.SetConditionIndex(i);
|
|
const result = c.Run();
|
|
isAnyTrue = isAnyTrue || result
|
|
}
|
|
frame.SetLastEventTrue(isAnyTrue);
|
|
if (isAnyTrue) {
|
|
if (this._RunActions(frame, 0))
|
|
this._RunSubEvents(frame);
|
|
if (this._hasElseBlock)
|
|
frame.SetElseBranchRan(true)
|
|
}
|
|
}
|
|
*_DebugRunOrBlock(frame) {
|
|
const conditions = this._conditions;
|
|
let isAnyTrue = conditions.length === 0;
|
|
for (let i = 0, len = conditions.length; i < len; ++i) {
|
|
const c = conditions[i];
|
|
if (c.IsTrigger())
|
|
continue;
|
|
frame.SetConditionIndex(i);
|
|
let ret;
|
|
if (c.DebugCanRunFast())
|
|
ret = c.Run();
|
|
else
|
|
ret = yield*c.DebugRun();
|
|
isAnyTrue = isAnyTrue || ret
|
|
}
|
|
frame.SetLastEventTrue(isAnyTrue);
|
|
if (isAnyTrue) {
|
|
let actRet;
|
|
if (this.DebugCanRunActionsFast())
|
|
actRet = this._RunActions(frame, 0);
|
|
else
|
|
actRet = yield*this._DebugRunActions(frame, 0);
|
|
if (actRet)
|
|
if (this.DebugCanRunSubEventsFast())
|
|
this._RunSubEvents();
|
|
else
|
|
yield*this._DebugRunSubEvents();
|
|
if (this._hasElseBlock)
|
|
frame.SetElseBranchRan(true)
|
|
}
|
|
}
|
|
_RunAndBlock(frame) {
|
|
const conditions = this._conditions;
|
|
for (let i = 0, len = conditions.length; i < len; ++i) {
|
|
const c = conditions[i];
|
|
frame.SetConditionIndex(i);
|
|
const result = c.Run();
|
|
if (!result) {
|
|
frame.SetLastEventTrue(false);
|
|
return
|
|
}
|
|
}
|
|
frame.SetLastEventTrue(true);
|
|
if (this._RunActions(frame, 0))
|
|
this._RunSubEvents(frame);
|
|
if (frame.GetLastEventTrue() && this._hasElseBlock)
|
|
frame.SetElseBranchRan(true)
|
|
}
|
|
*_DebugRunAndBlock(frame) {
|
|
const conditions = this._conditions;
|
|
for (let i = 0, len = conditions.length; i < len; ++i) {
|
|
const c = conditions[i];
|
|
frame.SetConditionIndex(i);
|
|
let ret;
|
|
if (c.DebugCanRunFast())
|
|
ret = c.Run();
|
|
else
|
|
ret = yield*c.DebugRun();
|
|
if (!ret) {
|
|
frame.SetLastEventTrue(false);
|
|
return
|
|
}
|
|
}
|
|
frame.SetLastEventTrue(true);
|
|
let actRet;
|
|
if (this.DebugCanRunActionsFast())
|
|
actRet = this._RunActions(frame, 0);
|
|
else
|
|
actRet = yield*this._DebugRunActions(frame, 0);
|
|
if (actRet)
|
|
if (this.DebugCanRunSubEventsFast())
|
|
this._RunSubEvents();
|
|
else
|
|
yield*this._DebugRunSubEvents();
|
|
if (frame.GetLastEventTrue() && this._hasElseBlock)
|
|
frame.SetElseBranchRan(true)
|
|
}
|
|
_RunActions_Fast(frame, startIndex) {
|
|
const actions = this._actions;
|
|
for (let i = startIndex, len = actions.length; i < len; ++i) {
|
|
const a = actions[i];
|
|
frame.SetActionIndex(i);
|
|
a.Run()
|
|
}
|
|
return true
|
|
}
|
|
*_DebugRunActions_Fast(frame, startIndex) {
|
|
const actions = this._actions;
|
|
for (let i = startIndex, len = actions.length; i < len; ++i) {
|
|
const a = actions[i];
|
|
frame.SetActionIndex(i);
|
|
if (a.DebugCanRunFast())
|
|
a.Run();
|
|
else
|
|
yield*a.DebugRun()
|
|
}
|
|
return true
|
|
}
|
|
_RunActions_ReturnValue(frame, startIndex) {
|
|
const eventSheetManager = this.GetEventSheetManager();
|
|
const actions = this._actions;
|
|
for (let i = startIndex, len = actions.length; i < len; ++i) {
|
|
const a = actions[i];
|
|
frame.SetActionIndex(i);
|
|
const ret = a.Run();
|
|
if (a.CanBailOut() && ret === true)
|
|
return false;
|
|
else if (a.IsAsync() && ret instanceof Promise)
|
|
eventSheetManager.AddAsyncActionPromise(ret)
|
|
}
|
|
return true
|
|
}
|
|
*_DebugRunActions_ReturnValue(frame, startIndex) {
|
|
const eventSheetManager = this.GetEventSheetManager();
|
|
const actions = this._actions;
|
|
for (let i = startIndex, len = actions.length; i < len; ++i) {
|
|
const a = actions[i];
|
|
frame.SetActionIndex(i);
|
|
let ret;
|
|
if (a.DebugCanRunFast())
|
|
ret = a.Run();
|
|
else
|
|
ret = yield*a.DebugRun();
|
|
if (a.CanBailOut() && ret === true)
|
|
return false;
|
|
else if (a.IsAsync() && ret instanceof Promise)
|
|
eventSheetManager.AddAsyncActionPromise(ret)
|
|
}
|
|
return true
|
|
}
|
|
_ResumeActionsAndSubEvents(frame) {
|
|
if (this._RunActions(frame, frame.GetActionIndex()))
|
|
this._RunSubEvents()
|
|
}
|
|
*_DebugResumeActionsAndSubEvents(frame) {
|
|
if (yield*this._DebugRunActions(frame, frame.GetActionIndex()))
|
|
yield*this._DebugRunSubEvents()
|
|
}
|
|
_RunSubEvents() {
|
|
if (!this._subEvents.length)
|
|
return;
|
|
const profile = this.IsGroup() && this._runtime.IsCPUProfiling();
|
|
const startTime = profile ? performance.now() : 0;
|
|
const eventStack = this._eventStack;
|
|
const frame = eventStack.Push(this);
|
|
if (this._isSolWriterAfterCnds)
|
|
this._RunSubEvents_SolWriterAfterCnds(frame);
|
|
else
|
|
this._RunSubEvents_Fast(frame);
|
|
eventStack.Pop();
|
|
if (profile)
|
|
this._perfRecord.totalTimeCounter += performance.now() - startTime
|
|
}
|
|
_RunSubEvents_SolWriterAfterCnds(frame) {
|
|
const isGroup = this._isGroup;
|
|
const isTopLevelGroup = this._isTopLevelGroup;
|
|
const eventSheetManager = this.GetEventSheetManager();
|
|
const subEvents = this._subEvents;
|
|
for (let i = 0, len = subEvents.length, last = len - 1; i < len; ++i) {
|
|
const e = subEvents[i];
|
|
const solModifiers = e.GetSolModifiers();
|
|
const copySol = !isTopLevelGroup || !isGroup && i < last;
|
|
if (copySol)
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
e.Run(frame);
|
|
if (copySol)
|
|
eventSheetManager.PopSol(solModifiers);
|
|
else
|
|
eventSheetManager.ClearSol(solModifiers)
|
|
}
|
|
}
|
|
_RunSubEvents_Fast(frame) {
|
|
const subEvents = this._subEvents;
|
|
for (let i = 0, len = subEvents.length; i < len; ++i)
|
|
subEvents[i].Run(frame)
|
|
}
|
|
*_DebugRunSubEvents() {
|
|
if (!this._subEvents.length)
|
|
return;
|
|
const eventStack = this._eventStack;
|
|
const frame = eventStack.Push(this);
|
|
if (this._isSolWriterAfterCnds)
|
|
yield*this._DebugRunSubEvents_SolWriterAfterCnds(frame);
|
|
else
|
|
yield*this._DebugRunSubEvents_Fast(frame);
|
|
eventStack.Pop()
|
|
}
|
|
*_DebugRunSubEvents_SolWriterAfterCnds(frame) {
|
|
const isGroup = this._isGroup;
|
|
const isTopLevelGroup = this._isTopLevelGroup;
|
|
const eventSheetManager = this.GetEventSheetManager();
|
|
const subEvents = this._subEvents;
|
|
for (let i = 0, len = subEvents.length, last = len - 1; i < len; ++i) {
|
|
const e = subEvents[i];
|
|
const solModifiers = e.GetSolModifiers();
|
|
const copySol = !isTopLevelGroup || !isGroup && i < last;
|
|
if (copySol)
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
yield*e.DebugRun(frame);
|
|
if (copySol)
|
|
eventSheetManager.PopSol(solModifiers);
|
|
else
|
|
eventSheetManager.ClearSol(solModifiers)
|
|
}
|
|
}
|
|
*_DebugRunSubEvents_Fast(frame) {
|
|
const subEvents = this._subEvents;
|
|
for (let i = 0, len = subEvents.length; i < len; ++i)
|
|
yield*subEvents[i].DebugRun(frame)
|
|
}
|
|
Retrigger(oldFrame, newFrame) {
|
|
this._runtime.IncrementExecCount();
|
|
newFrame.ResetQuick();
|
|
const conditions = this._conditions;
|
|
if (!this.IsOrBlock())
|
|
for (let i = oldFrame.GetConditionIndex() + 1, len = conditions.length; i < len; ++i) {
|
|
const c = conditions[i];
|
|
newFrame.SetConditionIndex(i);
|
|
const result = c.Run();
|
|
if (!result)
|
|
return false
|
|
}
|
|
if (this._RunActions(newFrame, 0))
|
|
this._RunSubEvents(newFrame);
|
|
return true
|
|
}
|
|
*DebugRetrigger(oldFrame, newFrame) {
|
|
this._runtime.IncrementExecCount();
|
|
newFrame.ResetQuick();
|
|
const conditions = this._conditions;
|
|
if (!this.IsOrBlock())
|
|
for (let i = oldFrame.GetConditionIndex() + 1, len = conditions.length; i < len; ++i) {
|
|
const c = conditions[i];
|
|
newFrame.SetConditionIndex(i);
|
|
let ret;
|
|
if (c.DebugCanRunFast())
|
|
ret = c.Run();
|
|
else
|
|
ret = yield*c.DebugRun();
|
|
if (!ret)
|
|
return false
|
|
}
|
|
let actRet;
|
|
if (this.DebugCanRunActionsFast())
|
|
actRet = this._RunActions(newFrame, 0);
|
|
else
|
|
actRet = yield*this._DebugRunActions(newFrame, 0);
|
|
if (actRet)
|
|
if (this.DebugCanRunSubEventsFast())
|
|
this._RunSubEvents();
|
|
else
|
|
yield*this._DebugRunSubEvents();
|
|
return true
|
|
}
|
|
DebugCanRunFast() {
|
|
return !this.IsDebugBreakpoint() && !this._runtime.DebugBreakNext() && this._debugData.canRunSelfFast
|
|
}
|
|
DebugCanRunActionsFast() {
|
|
return !this._runtime.DebugBreakNext() && this._debugData.canRunAllActionsFast
|
|
}
|
|
DebugCanRunSubEventsFast() {
|
|
return !this._runtime.DebugBreakNext() && this._debugData.canRunAllSubEventsFast
|
|
}
|
|
_CheckParentsOKToRun(frame) {
|
|
if (this.GetParent()) {
|
|
const parents = this.GetTriggerParents();
|
|
for (let i = 0, len = parents.length; i < len; ++i)
|
|
if (!parents[i].RunPreTrigger(frame))
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
*_DebugCheckParentsOKToRun(frame) {
|
|
if (this.GetParent()) {
|
|
const parents = this.GetTriggerParents();
|
|
for (let i = 0, len = parents.length; i < len; ++i)
|
|
if (!(yield*parents[i].DebugRunPreTrigger(frame)))
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
_EvaluateFunctionCallParameters(eventSheetManager, parameters, isRecursive) {
|
|
if (parameters.length > 0)
|
|
if (isRecursive) {
|
|
const paramResults = parameters.map(p=>p.Get(0));
|
|
eventSheetManager.GetLocalVarStack().Push();
|
|
this._scopeParent.SetFunctionParameters(paramResults)
|
|
} else
|
|
this._scopeParent.EvaluateFunctionParameters(parameters);
|
|
else if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Push()
|
|
}
|
|
RunAsFunctionCall(combinedSolModifiers, parameters) {
|
|
let ret;
|
|
let asyncId;
|
|
const hasAnySolModifiers = combinedSolModifiers.length > 0;
|
|
const runtime = this._runtime;
|
|
const eventStack = this._eventStack;
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const triggerDepth = eventSheetManager._IncTriggerDepth();
|
|
const isRecursive = triggerDepth > 1;
|
|
this._EvaluateFunctionCallParameters(eventSheetManager, parameters, isRecursive);
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PushCleanSol(combinedSolModifiers);
|
|
const frame = eventStack.Push(this);
|
|
if (this._CheckParentsOKToRun(frame)) {
|
|
runtime.IncrementExecCount();
|
|
frame.SetCurrentEvent(this);
|
|
const isAsync = this._scopeParent.IsAsync();
|
|
if (isAsync)
|
|
[asyncId,ret] = this._scopeParent.StartAsyncFunctionCall();
|
|
this._RunAndBlock(frame);
|
|
if (isAsync)
|
|
this._scopeParent.MaybeFinishAsyncFunctionCall(asyncId)
|
|
}
|
|
eventStack.Pop();
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Pop();
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PopSol(combinedSolModifiers);
|
|
eventSheetManager._DecTriggerDepth();
|
|
return ret
|
|
}
|
|
*DebugRunAsFunctionCall(combinedSolModifiers, parameters) {
|
|
let ret;
|
|
let asyncId;
|
|
if (this.IsDebugBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
const hasAnySolModifiers = combinedSolModifiers.length > 0;
|
|
const runtime = this._runtime;
|
|
const eventStack = this._eventStack;
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const triggerDepth = eventSheetManager._IncTriggerDepth();
|
|
const isRecursive = triggerDepth > 1;
|
|
this._EvaluateFunctionCallParameters(eventSheetManager, parameters, isRecursive);
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PushCleanSol(combinedSolModifiers);
|
|
const frame = eventStack.Push(this);
|
|
if (yield*this._DebugCheckParentsOKToRun(frame)) {
|
|
runtime.IncrementExecCount();
|
|
frame.SetCurrentEvent(this);
|
|
const isAsync = this._scopeParent.IsAsync();
|
|
if (isAsync)
|
|
[asyncId,ret] = this._scopeParent.StartAsyncFunctionCall();
|
|
yield*this._DebugRunAndBlock(frame);
|
|
if (isAsync)
|
|
this._scopeParent.MaybeFinishAsyncFunctionCall(asyncId)
|
|
}
|
|
eventStack.Pop();
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Pop();
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PopSol(combinedSolModifiers);
|
|
eventSheetManager._DecTriggerDepth();
|
|
return ret
|
|
}
|
|
RunAsMappedFunctionCall(paramResults) {
|
|
const solModifiers = this.GetSolModifiersIncludingParents();
|
|
const hasAnySolModifiers = solModifiers.length > 0;
|
|
const runtime = this._runtime;
|
|
const eventStack = this._eventStack;
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const triggerDepth = eventSheetManager._IncTriggerDepth();
|
|
const isRecursive = triggerDepth > 1;
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Push();
|
|
this._scopeParent.SetFunctionParameters(paramResults);
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PushCleanSol(solModifiers);
|
|
const frame = eventStack.Push(this);
|
|
if (this._CheckParentsOKToRun(frame)) {
|
|
runtime.IncrementExecCount();
|
|
frame.SetCurrentEvent(this);
|
|
this._RunAndBlock(frame)
|
|
}
|
|
eventStack.Pop();
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Pop();
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PopSol(solModifiers);
|
|
eventSheetManager._DecTriggerDepth()
|
|
}
|
|
*DebugRunAsMappedFunctionCall(paramResults) {
|
|
if (this.IsDebugBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
const solModifiers = this.GetSolModifiersIncludingParents();
|
|
const hasAnySolModifiers = solModifiers.length > 0;
|
|
const runtime = this._runtime;
|
|
const eventStack = this._eventStack;
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const triggerDepth = eventSheetManager._IncTriggerDepth();
|
|
const isRecursive = triggerDepth > 1;
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Push();
|
|
this._scopeParent.SetFunctionParameters(paramResults);
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PushCleanSol(solModifiers);
|
|
const frame = eventStack.Push(this);
|
|
if (yield*this._DebugCheckParentsOKToRun(frame)) {
|
|
runtime.IncrementExecCount();
|
|
frame.SetCurrentEvent(this);
|
|
yield*this._DebugRunAndBlock(frame)
|
|
}
|
|
eventStack.Pop();
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Pop();
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PopSol(solModifiers);
|
|
eventSheetManager._DecTriggerDepth()
|
|
}
|
|
RunAsExpressionFunctionCall(combinedSolModifiers, returnType, defaultReturnValue, ...paramResults) {
|
|
let ret;
|
|
let asyncId;
|
|
const hasAnySolModifiers = combinedSolModifiers.length > 0;
|
|
const runtime = this._runtime;
|
|
const eventStack = this._eventStack;
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const triggerDepth = eventSheetManager._IncTriggerDepth();
|
|
const isRecursive = triggerDepth > 1;
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Push();
|
|
if (paramResults.length > 0)
|
|
this._scopeParent.SetFunctionParameters(paramResults);
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PushCleanSol(combinedSolModifiers);
|
|
const frame = eventStack.Push(this);
|
|
frame.InitCallFunctionExpression(returnType, defaultReturnValue);
|
|
eventStack.PushExpFunc(frame);
|
|
runtime.SetDebuggingEnabled(false);
|
|
if (this._CheckParentsOKToRun(frame)) {
|
|
runtime.IncrementExecCount();
|
|
frame.SetCurrentEvent(this);
|
|
const isAsync = this._scopeParent.IsAsync();
|
|
if (isAsync)
|
|
[asyncId,ret] = this._scopeParent.StartAsyncFunctionCall();
|
|
this._RunAndBlock(frame);
|
|
if (isAsync)
|
|
this._scopeParent.MaybeFinishAsyncFunctionCall(asyncId)
|
|
}
|
|
runtime.SetDebuggingEnabled(true);
|
|
eventStack.Pop();
|
|
eventStack.PopExpFunc();
|
|
if (isRecursive)
|
|
eventSheetManager.GetLocalVarStack().Pop();
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PopSol(combinedSolModifiers);
|
|
eventSheetManager._DecTriggerDepth();
|
|
return ret || frame.GetFunctionReturnValue()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const EMPTY_SOL_MODIFIERS = [];
|
|
let hadUserScriptException = false;
|
|
C3.EventScript = class EventScript extends C3.DefendedBase {
|
|
constructor(eventSheet, parent, data) {
|
|
super();
|
|
const runtime = eventSheet.GetRuntime();
|
|
const eventSheetManager = eventSheet.GetEventSheetManager();
|
|
this._eventSheet = eventSheet;
|
|
this._eventSheetManager = eventSheetManager;
|
|
this._runtime = eventSheet.GetRuntime();
|
|
this._parent = parent;
|
|
const userMethod = runtime.GetObjectReference(data[1]);
|
|
this._func = userMethod;
|
|
this._displayNumber = data[2];
|
|
this._eventSheet._RegisterEventByDisplayNumber(this, this._displayNumber);
|
|
this._debugData = runtime.IsDebug() ? {
|
|
isBreakpoint: data[3][0],
|
|
isBreakable: data[3][1]
|
|
} : null
|
|
}
|
|
static Create(eventSheet, parent, data) {
|
|
return C3.New(C3.EventScript, eventSheet, parent, data)
|
|
}
|
|
_PostInit() {
|
|
const userMethod = this._func;
|
|
const localVars = this._runtime.GetEventSheetManager()._GetLocalVariablesScriptInterface(this);
|
|
this._func = userMethod.bind(null, this._runtime.GetIRuntime(), localVars)
|
|
}
|
|
GetParent() {
|
|
return this._parent
|
|
}
|
|
GetScopeParent() {
|
|
return this._parent
|
|
}
|
|
GetEventSheet() {
|
|
return this._eventSheet
|
|
}
|
|
GetDisplayNumber() {
|
|
return this._displayNumber
|
|
}
|
|
IsDebugBreakable() {
|
|
return this._debugData && this._debugData.isBreakable
|
|
}
|
|
IsDebugBreakpoint() {
|
|
return this.IsDebugBreakable() && this._debugData.isBreakpoint
|
|
}
|
|
_SetDebugBreakpoint(b) {
|
|
this._debugData.isBreakpoint = !!b
|
|
}
|
|
IsElseBlock() {
|
|
return false
|
|
}
|
|
GetSolModifiers() {
|
|
return EMPTY_SOL_MODIFIERS
|
|
}
|
|
GetSolModifiersIncludingParents() {
|
|
if (this._parent)
|
|
return this._parent.GetSolModifiersIncludingParents();
|
|
else
|
|
return EMPTY_SOL_MODIFIERS
|
|
}
|
|
Run(frame) {
|
|
frame.SetCurrentEvent(this);
|
|
this._eventSheetManager.AddAsyncActionPromise(this._RunUserScript())
|
|
}
|
|
async _RunUserScript() {
|
|
try {
|
|
await this._func()
|
|
} catch (err) {
|
|
console.error(`Unhandled exception running script %c${this.GetEventSheet().GetName()}, event ${this.GetDisplayNumber()}:`, "font-size: 1.2em; font-weight: bold;", err);
|
|
if (self.C3Debugger)
|
|
self.C3Debugger._SetLastErrorScript(this);
|
|
if (!hadUserScriptException) {
|
|
console.info(`%cTip:%c run this to highlight in Construct the last script that had an error: %cgoToLastErrorScript()`, "font-weight: bold; text-decoration: underline", "", "font-weight: bold");
|
|
hadUserScriptException = true
|
|
}
|
|
}
|
|
}
|
|
*DebugRun(frame) {
|
|
frame.SetCurrentEvent(this);
|
|
if (this.IsDebugBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
this.Run(frame)
|
|
}
|
|
DebugCanRunFast() {
|
|
return !this.IsDebugBreakpoint() && !this._runtime.DebugBreakNext()
|
|
}
|
|
static HadUserScriptException() {
|
|
return hadUserScriptException
|
|
}
|
|
static SetHadUserScriptException() {
|
|
hadUserScriptException = true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
C3.FunctionBlock = class FunctionBlock extends C3.DefendedBase {
|
|
constructor(eventSheet, parent, data) {
|
|
super();
|
|
this._eventSheet = eventSheet;
|
|
this._runtime = eventSheet.GetRuntime();
|
|
this._parent = parent;
|
|
const funcData = data[1];
|
|
this._functionName = funcData[0];
|
|
this._returnType = funcData[1];
|
|
this._functionParameters = funcData[2].map(paramData=>C3.EventVariable.Create(eventSheet, this, paramData));
|
|
this._isEnabled = funcData[3];
|
|
this._isAsync = funcData[4];
|
|
this._nextAsyncId = 0;
|
|
this._currentAsyncId = -1;
|
|
this._asyncMap = new Map;
|
|
this._eventBlock = C3.EventBlock.Create(eventSheet, parent, data);
|
|
this._eventBlock._SetScopeParent(this)
|
|
}
|
|
static Create(eventSheet, parent, data) {
|
|
return C3.New(C3.FunctionBlock, eventSheet, parent, data)
|
|
}
|
|
_PostInit() {
|
|
for (const fp of this._functionParameters)
|
|
fp._PostInit();
|
|
this._eventBlock._PostInit(false)
|
|
}
|
|
_GetAllLocalVariablesInScope() {
|
|
return this._functionParameters
|
|
}
|
|
GetFunctionParameters() {
|
|
return this._functionParameters
|
|
}
|
|
GetFunctionParameterCount() {
|
|
return this._functionParameters.length
|
|
}
|
|
EvaluateFunctionParameters(parameters) {
|
|
const functionParameters = this._functionParameters;
|
|
for (let i = 0, len = functionParameters.length; i < len; ++i)
|
|
functionParameters[i].SetValue(parameters[i].Get(0))
|
|
}
|
|
SetFunctionParameters(paramResults) {
|
|
const functionParameters = this._functionParameters;
|
|
for (let i = 0, len = functionParameters.length; i < len; ++i)
|
|
functionParameters[i].SetValue(paramResults[i])
|
|
}
|
|
CaptureFunctionParameters() {
|
|
return this._functionParameters.map(p=>p.GetValue())
|
|
}
|
|
GetParent() {
|
|
return this._parent
|
|
}
|
|
GetScopeParent() {
|
|
return this._parent
|
|
}
|
|
GetFunctionName() {
|
|
return this._functionName
|
|
}
|
|
GetReturnType() {
|
|
return this._returnType
|
|
}
|
|
IsEnabled() {
|
|
return this._isEnabled
|
|
}
|
|
GetDefaultReturnValue() {
|
|
switch (this._returnType) {
|
|
case 0:
|
|
return null;
|
|
case 2:
|
|
return "";
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
GetEventBlock() {
|
|
return this._eventBlock
|
|
}
|
|
IsAsync() {
|
|
return this._isAsync
|
|
}
|
|
StartAsyncFunctionCall() {
|
|
const asyncId = this._nextAsyncId++;
|
|
this._currentAsyncId = asyncId;
|
|
let resolve;
|
|
const promise = new Promise(r=>resolve = r);
|
|
this._asyncMap.set(asyncId, {
|
|
resolve,
|
|
pauseCount: 0
|
|
});
|
|
return [asyncId, promise]
|
|
}
|
|
MaybeFinishAsyncFunctionCall(asyncId) {
|
|
const info = this._asyncMap.get(asyncId);
|
|
if (info.pauseCount === 0) {
|
|
info.resolve();
|
|
this._asyncMap.delete(asyncId)
|
|
}
|
|
this._currentAsyncId = -1
|
|
}
|
|
PauseCurrentAsyncFunction() {
|
|
const info = this._asyncMap.get(this._currentAsyncId);
|
|
info.pauseCount++;
|
|
return this._currentAsyncId
|
|
}
|
|
ResumeAsyncFunction(asyncId) {
|
|
this._currentAsyncId = asyncId;
|
|
const info = this._asyncMap.get(asyncId);
|
|
info.pauseCount--
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const EMPTY_SOL_MODIFIERS = [];
|
|
C3.EventVariable = class EventVariable extends C3.DefendedBase {
|
|
constructor(eventSheet, parent, data) {
|
|
super();
|
|
const eventSheetManager = eventSheet.GetEventSheetManager();
|
|
this._eventSheet = eventSheet;
|
|
this._eventSheetManager = eventSheetManager;
|
|
this._runtime = eventSheet.GetRuntime();
|
|
this._parent = parent;
|
|
this._localVarStack = eventSheetManager.GetLocalVarStack();
|
|
this._name = data[1];
|
|
this._type = data[2];
|
|
this._initialValue = data[3];
|
|
this._isStatic = !!data[4];
|
|
this._isConstant = !!data[5];
|
|
this._isFunctionParameter = parent instanceof C3.FunctionBlock;
|
|
this._sid = data[6];
|
|
this._jsPropName = this._runtime.GetJsPropName(data[8]);
|
|
this._scriptSetter = v=>this.SetValue(v);
|
|
this._scriptGetter = ()=>this.GetValue();
|
|
this._hasSingleValue = !this._parent || this._isStatic || this._isConstant;
|
|
this._value = this._initialValue;
|
|
this._localIndex = -1;
|
|
if (this.IsBoolean())
|
|
this._value = this._value ? 1 : 0;
|
|
if (this.IsLocal() && !this.IsStatic() && !this.IsConstant())
|
|
this._localIndex = eventSheetManager._GetNextLocalVarIndex(this);
|
|
eventSheetManager._RegisterEventVariable(this)
|
|
}
|
|
static Create(eventSheet, parent, data) {
|
|
return C3.New(C3.EventVariable, eventSheet, parent, data)
|
|
}
|
|
_PostInit() {}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
GetJsPropName() {
|
|
return this._jsPropName
|
|
}
|
|
GetParent() {
|
|
return this._parent
|
|
}
|
|
IsGlobal() {
|
|
return !this.GetParent()
|
|
}
|
|
IsLocal() {
|
|
return !this.IsGlobal()
|
|
}
|
|
IsFunctionParameter() {
|
|
return this._isFunctionParameter
|
|
}
|
|
IsStatic() {
|
|
return this._isStatic
|
|
}
|
|
IsConstant() {
|
|
return this._isConstant
|
|
}
|
|
IsNumber() {
|
|
return this._type === 0
|
|
}
|
|
IsString() {
|
|
return this._type === 1
|
|
}
|
|
IsBoolean() {
|
|
return this._type === 2
|
|
}
|
|
IsElseBlock() {
|
|
return false
|
|
}
|
|
GetSID() {
|
|
return this._sid
|
|
}
|
|
GetInitialValue() {
|
|
return this._initialValue
|
|
}
|
|
GetSolModifiers() {
|
|
return EMPTY_SOL_MODIFIERS
|
|
}
|
|
Run(frame) {
|
|
if (this.IsLocal() && !this.IsStatic() && !this.IsConstant())
|
|
this.SetValue(this.GetInitialValue())
|
|
}
|
|
DebugCanRunFast() {
|
|
return true
|
|
}
|
|
*DebugRun(frame) {
|
|
this.Run(frame)
|
|
}
|
|
SetValue(v) {
|
|
if (this.IsNumber()) {
|
|
if (typeof v !== "number")
|
|
v = parseFloat(v)
|
|
} else if (this.IsString()) {
|
|
if (typeof v !== "string")
|
|
v = v.toString()
|
|
} else if (this.IsBoolean())
|
|
v = v ? 1 : 0;
|
|
if (this._hasSingleValue)
|
|
this._value = v;
|
|
else
|
|
this._localVarStack.GetCurrent()[this._localIndex] = v
|
|
}
|
|
GetValue() {
|
|
return this._hasSingleValue ? this._value : this._localVarStack.GetCurrent()[this._localIndex]
|
|
}
|
|
GetTypedValue() {
|
|
let ret = this.GetValue();
|
|
if (this.IsBoolean())
|
|
ret = !!ret;
|
|
return ret
|
|
}
|
|
ResetToInitialValue() {
|
|
this._value = this._initialValue
|
|
}
|
|
_GetScriptInterfaceDescriptor() {
|
|
return {
|
|
configurable: false,
|
|
enumerable: true,
|
|
get: this._scriptGetter,
|
|
set: this._scriptSetter
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
const EMPTY_SOL_MODIFIERS = [];
|
|
C3.EventInclude = class EventInclude extends C3.DefendedBase {
|
|
constructor(eventSheet, parent, data) {
|
|
super();
|
|
const eventSheetManager = eventSheet.GetEventSheetManager();
|
|
this._eventSheet = eventSheet;
|
|
this._eventSheetManager = eventSheetManager;
|
|
this._runtime = eventSheet.GetRuntime();
|
|
this._parent = parent;
|
|
this._includeSheet = null;
|
|
this._includeSheetName = data[1];
|
|
this._isActive = true
|
|
}
|
|
static Create(eventSheet, parent, data) {
|
|
return C3.New(C3.EventInclude, eventSheet, parent, data)
|
|
}
|
|
_PostInit() {
|
|
this._includeSheet = this._eventSheetManager.GetEventSheetByName(this._includeSheetName);
|
|
this._eventSheet._AddShallowInclude(this);
|
|
let p = this.GetParent();
|
|
while (p) {
|
|
if (p instanceof C3.EventBlock && p.IsGroup())
|
|
p._AddContainedInclude(this);
|
|
p = p.GetParent()
|
|
}
|
|
this.UpdateActive();
|
|
if (this._runtime.IsDebug())
|
|
this._eventSheet._GetPerfRecord().children.push(this._includeSheet._GetPerfRecord())
|
|
}
|
|
GetParent() {
|
|
return this._parent
|
|
}
|
|
GetSolModifiers() {
|
|
return EMPTY_SOL_MODIFIERS
|
|
}
|
|
GetIncludeSheet() {
|
|
return this._includeSheet
|
|
}
|
|
Run(frame) {
|
|
const pushSol = !!this.GetParent();
|
|
const allObjectClasses = this._runtime.GetAllObjectClasses();
|
|
if (pushSol)
|
|
this._eventSheetManager.PushCleanSol(allObjectClasses);
|
|
this._includeSheet.Run();
|
|
if (pushSol)
|
|
this._eventSheetManager.PopSol(allObjectClasses)
|
|
}
|
|
*DebugRun(frame) {
|
|
const pushSol = !!this.GetParent();
|
|
const allObjectClasses = this._runtime.GetAllObjectClasses();
|
|
if (pushSol)
|
|
this._eventSheetManager.PushCleanSol(allObjectClasses);
|
|
yield*this._includeSheet.DebugRun();
|
|
if (pushSol)
|
|
this._eventSheetManager.PopSol(allObjectClasses)
|
|
}
|
|
DebugCanRunFast() {
|
|
return false
|
|
}
|
|
IsActive() {
|
|
return this._isActive
|
|
}
|
|
UpdateActive() {
|
|
let p = this.GetParent();
|
|
while (p) {
|
|
if (p instanceof C3.EventBlock && p.IsGroup() && !p.IsGroupActive()) {
|
|
this._isActive = false;
|
|
return
|
|
}
|
|
p = p.GetParent()
|
|
}
|
|
this._isActive = true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
C3.ExpNode = class ExpNode extends C3.DefendedBase {
|
|
constructor(owner) {
|
|
super();
|
|
this._owner = owner;
|
|
this._runtime = owner.GetRuntime()
|
|
}
|
|
_PostInit() {}
|
|
static CreateNode(owner, data) {
|
|
const type = data[0];
|
|
const Classes = [BehaviorExpressionNode, ObjectExpressionNode, InstVarExpressionNode, EventVarExpNode, SystemExpressionExpNode, CallFunctionExpressionExpNode];
|
|
return C3.New(Classes[type], owner, data)
|
|
}
|
|
}
|
|
;
|
|
class SystemExpressionExpNode extends C3.ExpNode {
|
|
constructor(owner, data) {
|
|
super(owner);
|
|
this._systemPlugin = this._runtime.GetSystemPlugin();
|
|
this._func = this._runtime.GetObjectReference(data[1]);
|
|
if (this._func === C3.Plugins.System.Exps.random || this._func === C3.Plugins.System.Exps.choose)
|
|
this._owner.SetVariesPerInstance()
|
|
}
|
|
GetBoundMethod() {
|
|
return this._systemPlugin._GetBoundACEMethod(this._func, this._systemPlugin)
|
|
}
|
|
}
|
|
class CallFunctionExpressionExpNode extends C3.ExpNode {
|
|
constructor(owner, data) {
|
|
super(owner);
|
|
this._functionBlock = null;
|
|
this._functionName = data[1];
|
|
this._owner.SetVariesPerInstance()
|
|
}
|
|
_PostInit() {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
this._functionBlock = eventSheetManager.GetFunctionBlockByName(this._functionName);
|
|
this._functionName = null;
|
|
const myEventBlock = this._owner.GetEventBlock();
|
|
const callEventBlock = this._functionBlock.GetEventBlock();
|
|
this._combinedSolModifiers = [...new Set([...myEventBlock.GetSolModifiersIncludingParents(), ...callEventBlock.GetSolModifiersIncludingParents()])];
|
|
this._combinedSolModifiers = eventSheetManager._DeduplicateSolModifierList(this._combinedSolModifiers)
|
|
}
|
|
GetBoundMethod() {
|
|
const functionBlock = this._functionBlock;
|
|
if (functionBlock.IsEnabled()) {
|
|
const callEventBlock = functionBlock.GetEventBlock();
|
|
return C3.EventBlock.prototype.RunAsExpressionFunctionCall.bind(callEventBlock, this._combinedSolModifiers, functionBlock.GetReturnType(), functionBlock.GetDefaultReturnValue())
|
|
} else {
|
|
const defaultReturnValue = functionBlock.GetDefaultReturnValue();
|
|
return ()=>defaultReturnValue
|
|
}
|
|
}
|
|
}
|
|
function WrapIndex(index, len) {
|
|
if (index >= len)
|
|
return index % len;
|
|
else if (index < 0) {
|
|
if (index <= -len)
|
|
index %= len;
|
|
if (index < 0)
|
|
index += len;
|
|
return index
|
|
} else
|
|
return index
|
|
}
|
|
class ObjectExpressionNode extends C3.ExpNode {
|
|
constructor(owner, data) {
|
|
super(owner);
|
|
this._objectClass = this._runtime.GetObjectClassByIndex(data[1]);
|
|
this._func = this._runtime.GetObjectReference(data[2]);
|
|
this._returnsString = !!data[3];
|
|
this._eventStack = this._runtime.GetEventSheetManager().GetEventStack();
|
|
this._owner._MaybeVaryFor(this._objectClass)
|
|
}
|
|
GetBoundMethod() {
|
|
return this._objectClass.GetPlugin()._GetBoundACEMethod(this._func, this._objectClass.GetSingleGlobalInstance().GetSdkInstance())
|
|
}
|
|
ExpObject(...args) {
|
|
const objectClass = this._objectClass;
|
|
const instances = objectClass.GetCurrentSol().GetExpressionInstances();
|
|
const len = instances.length;
|
|
if (len === 0)
|
|
return this._returnsString ? "" : 0;
|
|
const index = WrapIndex(this._owner.GetSolIndex(), len);
|
|
this._eventStack.GetCurrentStackFrame().SetExpressionObjectClass(objectClass);
|
|
return this._func.apply(instances[index].GetSdkInstance(), args)
|
|
}
|
|
ExpObject_InstExpr(instIndex, ...args) {
|
|
const objectClass = this._objectClass;
|
|
const instances = objectClass.GetInstances();
|
|
const len = instances.length;
|
|
if (len === 0)
|
|
return this._returnsString ? "" : 0;
|
|
const index = WrapIndex(instIndex, len);
|
|
this._eventStack.GetCurrentStackFrame().SetExpressionObjectClass(objectClass);
|
|
return this._func.apply(instances[index].GetSdkInstance(), args)
|
|
}
|
|
}
|
|
class InstVarExpressionNode extends C3.ExpNode {
|
|
constructor(owner, data) {
|
|
super(owner);
|
|
this._objectClass = this._runtime.GetObjectClassByIndex(data[1]);
|
|
this._varIndex = data[3];
|
|
this._returnsString = !!data[2];
|
|
this._owner._MaybeVaryFor(this._objectClass)
|
|
}
|
|
ExpInstVar() {
|
|
const instances = this._objectClass.GetCurrentSol().GetExpressionInstances();
|
|
const len = instances.length;
|
|
if (len === 0)
|
|
return this._returnsString ? "" : 0;
|
|
const index = WrapIndex(this._owner.GetSolIndex(), len);
|
|
return instances[index]._GetInstanceVariableValueUnchecked(this._varIndex)
|
|
}
|
|
ExpInstVar_Family() {
|
|
const objectClass = this._objectClass;
|
|
const instances = objectClass.GetCurrentSol().GetExpressionInstances();
|
|
const len = instances.length;
|
|
if (len === 0)
|
|
return this._returnsString ? "" : 0;
|
|
const index = WrapIndex(this._owner.GetSolIndex(), len);
|
|
const inst = instances[index];
|
|
const offset = inst.GetObjectClass().GetFamilyInstanceVariableOffset(objectClass.GetFamilyIndex());
|
|
return inst._GetInstanceVariableValueUnchecked(this._varIndex + offset)
|
|
}
|
|
ExpInstVar_InstExpr(instIndex) {
|
|
const objectClass = this._objectClass;
|
|
const instances = objectClass.GetInstances();
|
|
const len = instances.length;
|
|
if (len === 0)
|
|
return this._returnsString ? "" : 0;
|
|
const index = WrapIndex(instIndex, len);
|
|
const inst = instances[index];
|
|
let offset = 0;
|
|
if (objectClass.IsFamily())
|
|
offset = inst.GetObjectClass().GetFamilyInstanceVariableOffset(objectClass.GetFamilyIndex());
|
|
return inst._GetInstanceVariableValueUnchecked(this._varIndex + offset)
|
|
}
|
|
}
|
|
class BehaviorExpressionNode extends C3.ExpNode {
|
|
constructor(owner, data) {
|
|
super(owner);
|
|
this._objectClass = this._runtime.GetObjectClassByIndex(data[1]);
|
|
this._behaviorType = this._objectClass.GetBehaviorTypeByName(data[2]);
|
|
this._behaviorIndex = this._objectClass.GetBehaviorIndexByName(data[2]);
|
|
this._func = this._runtime.GetObjectReference(data[3]);
|
|
this._returnsString = !!data[4];
|
|
this._eventStack = this._runtime.GetEventSheetManager().GetEventStack();
|
|
this._owner._MaybeVaryFor(this._objectClass)
|
|
}
|
|
ExpBehavior(...args) {
|
|
const objectClass = this._objectClass;
|
|
const instances = objectClass.GetCurrentSol().GetExpressionInstances();
|
|
const len = instances.length;
|
|
if (len === 0)
|
|
return this._returnsString ? "" : 0;
|
|
const index = WrapIndex(this._owner.GetSolIndex(), len);
|
|
this._eventStack.GetCurrentStackFrame().SetExpressionObjectClass(objectClass);
|
|
const inst = instances[index];
|
|
let offset = 0;
|
|
if (objectClass.IsFamily())
|
|
offset = inst.GetObjectClass().GetFamilyBehaviorOffset(objectClass.GetFamilyIndex());
|
|
return this._func.apply(inst.GetBehaviorInstances()[this._behaviorIndex + offset].GetSdkInstance(), args)
|
|
}
|
|
ExpBehavior_InstExpr(instIndex, ...args) {
|
|
const objectClass = this._objectClass;
|
|
const instances = objectClass.GetInstances();
|
|
const len = instances.length;
|
|
if (len === 0)
|
|
return this._returnsString ? "" : 0;
|
|
const index = WrapIndex(instIndex, len);
|
|
this._eventStack.GetCurrentStackFrame().SetExpressionObjectClass(objectClass);
|
|
const inst = instances[index];
|
|
let offset = 0;
|
|
if (objectClass.IsFamily())
|
|
offset = inst.GetObjectClass().GetFamilyBehaviorOffset(objectClass.GetFamilyIndex());
|
|
return this._func.apply(inst.GetBehaviorInstances()[this._behaviorIndex + offset].GetSdkInstance(), args)
|
|
}
|
|
}
|
|
class EventVarExpNode extends C3.ExpNode {
|
|
constructor(owner, data) {
|
|
super(owner);
|
|
this._eventVar = null;
|
|
this._eventVarSid = data[1]
|
|
}
|
|
_PostInit() {
|
|
this._eventVar = this._runtime.GetEventSheetManager().GetEventVariableBySID(this._eventVarSid)
|
|
}
|
|
GetVar() {
|
|
return this._eventVar
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
C3.Parameter = class Parameter extends C3.DefendedBase {
|
|
constructor(owner, type, index) {
|
|
super();
|
|
this._owner = owner;
|
|
this._index = index;
|
|
this._type = type;
|
|
this.Get = null;
|
|
this._variesPerInstance = false;
|
|
this._isConstant = false
|
|
}
|
|
static Create(owner, data, index) {
|
|
const type = data[0];
|
|
const Classes = [ExpressionParameter, StringExpressionParameter, FileParameter, ComboParameter, ObjectParameter, LayerExpressionParameter, LayoutParameter, ExpressionParameter, ComboParameter, ComboParameter, InstVarParameter, EventVarParameter, FileParameter, VariadicParameter, StringExpressionParameter, TimelineParameter, BooleanParameter, FunctionParameter, EaseParameter];
|
|
return C3.New(Classes[type], owner, type, index, data)
|
|
}
|
|
_PostInit() {}
|
|
SetVariesPerInstance() {
|
|
this._variesPerInstance = true
|
|
}
|
|
_MaybeVaryFor(objectClass) {
|
|
if (this._variesPerInstance)
|
|
return;
|
|
if (!objectClass)
|
|
return;
|
|
if (!objectClass.GetPlugin().IsSingleGlobal())
|
|
this._variesPerInstance = true
|
|
}
|
|
VariesPerInstance() {
|
|
return this._variesPerInstance
|
|
}
|
|
GetIndex() {
|
|
return this._index
|
|
}
|
|
GetRuntime() {
|
|
return this._owner.GetRuntime()
|
|
}
|
|
GetEventBlock() {
|
|
return this._owner.GetEventBlock()
|
|
}
|
|
IsConstant() {
|
|
return this._isConstant
|
|
}
|
|
}
|
|
;
|
|
function GetExpressionFunc(number) {
|
|
const ret = self.C3_ExpressionFuncs[number];
|
|
if (!ret)
|
|
throw new Error("invalid expression number");
|
|
return ret
|
|
}
|
|
class ExpressionParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._solIndex = 0;
|
|
const expData = data[1];
|
|
this._expressionNumber = expData[0];
|
|
this._numberedNodes = [];
|
|
this._expressionFunc = null;
|
|
for (let i = 1, len = expData.length; i < len; ++i)
|
|
this._numberedNodes.push(C3.ExpNode.CreateNode(this, expData[i]));
|
|
if (this._numberedNodes.length)
|
|
this.Get = this.GetExpression;
|
|
else {
|
|
this.Get = GetExpressionFunc(this._expressionNumber);
|
|
this._isConstant = true
|
|
}
|
|
}
|
|
_GetNode(i) {
|
|
if (i < 0 || i >= this._numberedNodes.length)
|
|
throw new RangeError("invalid numbered node");
|
|
return this._numberedNodes[i]
|
|
}
|
|
_PostInit() {
|
|
for (const node of this._numberedNodes)
|
|
node._PostInit();
|
|
const func = GetExpressionFunc(this._expressionNumber);
|
|
if (this._numberedNodes.length)
|
|
this._expressionFunc = func(this);
|
|
else
|
|
this._expressionFunc = func
|
|
}
|
|
GetSolIndex() {
|
|
return this._solIndex
|
|
}
|
|
GetExpression(solIndex) {
|
|
this._solIndex = solIndex;
|
|
return this._expressionFunc()
|
|
}
|
|
}
|
|
class StringExpressionParameter extends ExpressionParameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index, data);
|
|
this.Get = this.GetStringExpression;
|
|
if (type === 14) {
|
|
this.GetEventBlock().SetAllSolModifiers();
|
|
if (this._owner instanceof C3.Action)
|
|
this.GetEventBlock().SetSolWriterAfterCnds()
|
|
}
|
|
}
|
|
GetStringExpression(solIndex) {
|
|
this._solIndex = solIndex;
|
|
const ret = this._expressionFunc();
|
|
if (typeof ret === "string")
|
|
return ret;
|
|
else
|
|
return ""
|
|
}
|
|
_GetFastTriggerValue() {
|
|
return GetExpressionFunc(this._expressionNumber)()
|
|
}
|
|
}
|
|
class LayerExpressionParameter extends ExpressionParameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index, data);
|
|
this.Get = this.GetLayer;
|
|
this._isConstant = false
|
|
}
|
|
GetLayer(solIndex) {
|
|
this._solIndex = solIndex;
|
|
const ret = this._expressionFunc();
|
|
const layout = this.GetRuntime().GetCurrentLayout();
|
|
return layout.GetLayer(ret)
|
|
}
|
|
}
|
|
class ComboParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._combo = data[1];
|
|
this.Get = this.GetCombo;
|
|
this._isConstant = true
|
|
}
|
|
GetCombo() {
|
|
return this._combo
|
|
}
|
|
}
|
|
class BooleanParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._bool = data[1];
|
|
this.Get = this.GetBoolean;
|
|
this._isConstant = true
|
|
}
|
|
GetBoolean() {
|
|
return this._bool
|
|
}
|
|
}
|
|
class ObjectParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._objectClass = this.GetRuntime().GetObjectClassByIndex(data[1]);
|
|
this.Get = this.GetObjectClass;
|
|
const eventBlock = this.GetEventBlock();
|
|
eventBlock._AddSolModifier(this._objectClass);
|
|
if (this._owner instanceof C3.Action)
|
|
eventBlock.SetSolWriterAfterCnds();
|
|
else if (eventBlock.GetParent())
|
|
eventBlock.GetParent().SetSolWriterAfterCnds();
|
|
this._isConstant = true
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectClass
|
|
}
|
|
}
|
|
class LayoutParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._layout = this.GetRuntime().GetLayoutManager().GetLayoutByName(data[1]);
|
|
this.Get = this.GetLayout;
|
|
this._isConstant = true
|
|
}
|
|
GetLayout() {
|
|
return this._layout
|
|
}
|
|
}
|
|
class TimelineParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._timeline = this.GetRuntime().GetTimelineManager().GetTimelineByName(data[1]);
|
|
this.Get = this.GetTimeline;
|
|
this._isConstant = true
|
|
}
|
|
GetTimeline() {
|
|
return this._timeline
|
|
}
|
|
}
|
|
class FileParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._fileInfo = data[1];
|
|
this.Get = this.GetFile;
|
|
this._isConstant = true
|
|
}
|
|
GetFile() {
|
|
return this._fileInfo
|
|
}
|
|
}
|
|
class InstVarParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._instVarIndex = data[1];
|
|
const ownerObjectClass = this._owner.GetObjectClass();
|
|
if (ownerObjectClass && ownerObjectClass.IsFamily()) {
|
|
this.Get = this.GetFamilyInstanceVariable;
|
|
this.SetVariesPerInstance()
|
|
} else {
|
|
this.Get = this.GetInstanceVariable;
|
|
this._isConstant = true
|
|
}
|
|
}
|
|
GetInstanceVariable() {
|
|
return this._instVarIndex
|
|
}
|
|
GetFamilyInstanceVariable(solIndex) {
|
|
solIndex = solIndex || 0;
|
|
const familyType = this._owner.GetObjectClass();
|
|
const sol = familyType.GetCurrentSol();
|
|
const instances = sol.GetInstances();
|
|
let realType = null;
|
|
if (instances.length)
|
|
realType = instances[solIndex % instances.length].GetObjectClass();
|
|
else if (sol.HasAnyElseInstances()) {
|
|
const elseInstances = sol.GetElseInstances();
|
|
realType = elseInstances[solIndex % elseInstances.length].GetObjectClass()
|
|
} else if (familyType.GetInstanceCount() > 0) {
|
|
const familyInstances = familyType.GetInstances();
|
|
realType = familyInstances[solIndex % familyInstances.length].GetObjectClass()
|
|
} else
|
|
return 0;
|
|
return this._instVarIndex + realType.GetFamilyInstanceVariableOffset(familyType.GetFamilyIndex())
|
|
}
|
|
}
|
|
class EventVarParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._eventVarSid = data[1];
|
|
this._eventVar = null;
|
|
this.Get = this.GetEventVariable;
|
|
this._isConstant = true
|
|
}
|
|
_PostInit() {
|
|
this._eventVar = this.GetRuntime().GetEventSheetManager().GetEventVariableBySID(this._eventVarSid)
|
|
}
|
|
GetEventVariable() {
|
|
return this._eventVar
|
|
}
|
|
}
|
|
class FunctionParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._functionBlockName = data[1];
|
|
this._functionBlock = null;
|
|
this.Get = this.GetFunction;
|
|
this._isConstant = true
|
|
}
|
|
_PostInit() {
|
|
this._functionBlock = this.GetRuntime().GetEventSheetManager().GetFunctionBlockByName(this._functionBlockName);
|
|
this._functionBlockName = null
|
|
}
|
|
GetFunction() {
|
|
return this._functionBlock
|
|
}
|
|
}
|
|
class VariadicParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._subParams = [];
|
|
this._variadicRet = [];
|
|
this._isConstant = true;
|
|
for (let i = 1, len = data.length; i < len; ++i) {
|
|
const subParam = C3.Parameter.Create(this._owner, data[i], 0);
|
|
this._subParams.push(subParam);
|
|
this._variadicRet.push(0);
|
|
if (!subParam.IsConstant())
|
|
this._isConstant = false
|
|
}
|
|
this.Get = this.GetVariadic
|
|
}
|
|
_PostInit() {
|
|
for (const subParam of this._subParams)
|
|
subParam._PostInit()
|
|
}
|
|
GetVariadic() {
|
|
const subParams = this._subParams;
|
|
const variadicRet = this._variadicRet;
|
|
for (let i = 0, len = subParams.length; i < len; ++i)
|
|
variadicRet[i] = subParams[i].Get(0);
|
|
return variadicRet
|
|
}
|
|
}
|
|
class EaseParameter extends C3.Parameter {
|
|
constructor(owner, type, index, data) {
|
|
super(owner, type, index);
|
|
this._easeIndex = data[1];
|
|
this.Get = this.GetEase;
|
|
this._isConstant = true
|
|
}
|
|
GetEase() {
|
|
return this._easeIndex
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
function EvalParams(parameters, results) {
|
|
for (let i = 0, len = parameters.length; i < len; ++i)
|
|
results[i] = parameters[i].Get(0)
|
|
}
|
|
const EMPTY_PARAMS_ARRAY = [];
|
|
const noop = function() {};
|
|
C3.Condition = class Condition extends C3.DefendedBase {
|
|
constructor(eventBlock, data, index) {
|
|
super();
|
|
this._eventBlock = eventBlock;
|
|
this._runtime = eventBlock.GetRuntime();
|
|
this._index = index;
|
|
this._func = this._runtime.GetObjectReference(data[1]);
|
|
this._isTrigger = data[3] > 0;
|
|
this._isFastTrigger = data[3] === 2;
|
|
this._isLooping = !!data[4];
|
|
this._isInverted = !!data[5];
|
|
this._isStatic = !!data[6];
|
|
this._sid = data[7];
|
|
this._isInOrBlock = this._eventBlock.IsOrBlock();
|
|
this._objectClass = null;
|
|
this._behaviorType = null;
|
|
this._behaviorIndex = -1;
|
|
this._systemPlugin = null;
|
|
this.Run = noop;
|
|
this.DebugRun = noop;
|
|
this._parameters = [];
|
|
this._results = [];
|
|
this._anyParamVariesPerInstance = false;
|
|
this._savedData = null;
|
|
this._unsavedData = null;
|
|
this._debugData = this._runtime.IsDebug() ? {
|
|
isBreakpoint: data[8][0],
|
|
canDebug: data[8][1]
|
|
} : null;
|
|
if (data[0] === -1)
|
|
this._systemPlugin = this._runtime.GetSystemPlugin();
|
|
else {
|
|
this._objectClass = this._runtime.GetObjectClassByIndex(data[0]);
|
|
if (data[2]) {
|
|
this._behaviorType = this._objectClass.GetBehaviorTypeByName(data[2]);
|
|
this._behaviorIndex = this._objectClass.GetBehaviorIndexByName(data[2])
|
|
}
|
|
if (this._eventBlock.GetParent())
|
|
this._eventBlock.GetParent().SetSolWriterAfterCnds()
|
|
}
|
|
if (data.length === 10) {
|
|
let paramData = data[9];
|
|
for (let data of paramData) {
|
|
this._parameters.push(C3.Parameter.Create(this, data, this._parameters.length));
|
|
this._results.push(0)
|
|
}
|
|
}
|
|
if (this._parameters.length === 0) {
|
|
this._parameters = EMPTY_PARAMS_ARRAY;
|
|
this._results = EMPTY_PARAMS_ARRAY
|
|
}
|
|
this._eventBlock.GetEventSheetManager()._RegisterCondition(this)
|
|
}
|
|
static Create(eventBlock, data, index) {
|
|
return C3.New(C3.Condition, eventBlock, data, index)
|
|
}
|
|
_PostInit() {
|
|
for (const param of this._parameters) {
|
|
param._PostInit();
|
|
if (param.VariesPerInstance())
|
|
this._anyParamVariesPerInstance = true
|
|
}
|
|
if (this._isFastTrigger) {
|
|
this.Run = this._RunFastTrigger;
|
|
this.DebugRun = this._DebugRunFastTrigger
|
|
} else if (this._systemPlugin) {
|
|
this._SetSystemRunMethod();
|
|
this.DebugRun = this._DebugRunSystem
|
|
} else if (this._objectClass.GetPlugin().IsSingleGlobal()) {
|
|
this._SetSingleGlobalRunMethod();
|
|
this.DebugRun = this._DebugRunSingleGlobal
|
|
} else if (this._isStatic) {
|
|
this.Run = this._RunStatic;
|
|
this.DebugRun = this._DebugRunStatic
|
|
} else {
|
|
this.Run = this._RunObject;
|
|
this.DebugRun = this._DebugRunObject
|
|
}
|
|
}
|
|
_SetSystemRunMethod() {
|
|
const plugin = this._systemPlugin;
|
|
const bindThis = this._systemPlugin;
|
|
this._SetRunMethodForBoundFunc(plugin, bindThis, this._RunSystem)
|
|
}
|
|
_SetSingleGlobalRunMethod() {
|
|
const plugin = this._objectClass.GetPlugin();
|
|
const bindThis = this._objectClass.GetSingleGlobalInstance().GetSdkInstance();
|
|
this._SetRunMethodForBoundFunc(plugin, bindThis, this._RunSingleGlobal)
|
|
}
|
|
_SetRunMethodForBoundFunc(plugin, bindThis, fallbackMethod) {
|
|
const func = this._func;
|
|
const isInverted = this._isInverted;
|
|
const parameters = this._parameters;
|
|
if (parameters.length === 0) {
|
|
const boundFunc = plugin._GetBoundACEMethod(func, bindThis);
|
|
if (isInverted)
|
|
this.Run = function RunSingleCnd_0param() {
|
|
return C3.xor(boundFunc(), isInverted)
|
|
}
|
|
;
|
|
else
|
|
this.Run = boundFunc
|
|
} else if (parameters.length === 1) {
|
|
const param0 = parameters[0];
|
|
if (!isInverted && param0.IsConstant())
|
|
this.Run = plugin._GetBoundACEMethod_1param(func, bindThis, param0.Get(0));
|
|
else {
|
|
const boundFunc = plugin._GetBoundACEMethod(func, bindThis);
|
|
this.Run = function RunSingleCnd_1param() {
|
|
return C3.xor(boundFunc(param0.Get(0)), isInverted)
|
|
}
|
|
}
|
|
} else if (parameters.length === 2) {
|
|
const param0 = parameters[0];
|
|
const param1 = parameters[1];
|
|
if (!isInverted && param0.IsConstant() && param1.IsConstant())
|
|
this.Run = plugin._GetBoundACEMethod_2params(func, bindThis, param0.Get(0), param1.Get(0));
|
|
else {
|
|
const boundFunc = plugin._GetBoundACEMethod(func, bindThis);
|
|
this.Run = function RunSingleCnd_2params() {
|
|
return C3.xor(boundFunc(param0.Get(0), param1.Get(0)), isInverted)
|
|
}
|
|
}
|
|
} else if (parameters.length === 3) {
|
|
const param0 = parameters[0];
|
|
const param1 = parameters[1];
|
|
const param2 = parameters[2];
|
|
if (!isInverted && param0.IsConstant() && param1.IsConstant() && param2.IsConstant())
|
|
this.Run = plugin._GetBoundACEMethod_3params(func, bindThis, param0.Get(0), param1.Get(0), param2.Get(0));
|
|
else {
|
|
const boundFunc = plugin._GetBoundACEMethod(func, bindThis);
|
|
this.Run = function RunSingleCnd_3params() {
|
|
return C3.xor(boundFunc(param0.Get(0), param1.Get(0), param2.Get(0)), isInverted)
|
|
}
|
|
}
|
|
} else
|
|
this.Run = fallbackMethod
|
|
}
|
|
GetSID() {
|
|
return this._sid
|
|
}
|
|
_GetFunc() {
|
|
return this._func
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectClass
|
|
}
|
|
GetBehaviorType() {
|
|
return this._behaviorType
|
|
}
|
|
GetEventBlock() {
|
|
return this._eventBlock
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetIndex() {
|
|
return this._index
|
|
}
|
|
GetDebugIndex() {
|
|
return this.GetIndex()
|
|
}
|
|
IsTrigger() {
|
|
return this._isTrigger
|
|
}
|
|
IsFastTrigger() {
|
|
return this._isFastTrigger
|
|
}
|
|
IsInverted() {
|
|
return this._isInverted
|
|
}
|
|
IsLooping() {
|
|
return this._isLooping
|
|
}
|
|
IsBreakpoint() {
|
|
return this._debugData.isBreakpoint
|
|
}
|
|
_SetBreakpoint(b) {
|
|
this._debugData.isBreakpoint = !!b;
|
|
this._eventBlock._UpdateCanRunFastRecursive()
|
|
}
|
|
_DebugReturnsGenerator() {
|
|
return this._debugData.canDebug
|
|
}
|
|
DebugCanRunFast() {
|
|
return !this.IsBreakpoint() && !this._runtime.DebugBreakNext() && !this._DebugReturnsGenerator()
|
|
}
|
|
GetSavedDataMap() {
|
|
if (!this._savedData)
|
|
this._savedData = new Map;
|
|
return this._savedData
|
|
}
|
|
GetUnsavedDataMap() {
|
|
if (!this._unsavedData)
|
|
this._unsavedData = new Map;
|
|
return this._unsavedData
|
|
}
|
|
_RunSystem() {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
return C3.xor(this._func.apply(this._systemPlugin, results), this._isInverted)
|
|
}
|
|
*_DebugRunSystem() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
let ret = this._func.apply(this._systemPlugin, results);
|
|
if (C3.IsIterator(ret))
|
|
ret = yield*ret;
|
|
return C3.xor(ret, this._isInverted)
|
|
} else
|
|
return this.Run()
|
|
}
|
|
_RunSingleGlobal() {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
const inst = this._objectClass.GetSingleGlobalInstance().GetSdkInstance();
|
|
return C3.xor(this._func.apply(inst, results), this._isInverted)
|
|
}
|
|
*_DebugRunSingleGlobal() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
const inst = this._objectClass.GetSingleGlobalInstance().GetSdkInstance();
|
|
let ret = this._func.apply(inst, results);
|
|
if (C3.IsIterator(ret))
|
|
ret = yield*ret;
|
|
return C3.xor(ret, this._isInverted)
|
|
} else
|
|
return this.Run()
|
|
}
|
|
_RunFastTrigger() {
|
|
return true
|
|
}
|
|
*_DebugRunFastTrigger() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
return true
|
|
}
|
|
_RunStatic() {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
const ret = this._func.apply(this._behaviorType || this._objectClass, results);
|
|
this._objectClass.ApplySolToContainer();
|
|
return ret
|
|
}
|
|
*_DebugRunStatic() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
let ret = this._func.apply(this._behaviorType || this._objectClass, results);
|
|
if (C3.IsIterator(ret))
|
|
ret = yield*ret;
|
|
this._objectClass.ApplySolToContainer();
|
|
return ret
|
|
} else
|
|
return this.Run()
|
|
}
|
|
_RunObject() {
|
|
const parameters = this._parameters;
|
|
const results = this._results;
|
|
const sol = this._objectClass.GetCurrentSol();
|
|
for (let i = 0, len = parameters.length; i < len; ++i) {
|
|
const p = parameters[i];
|
|
if (!p.VariesPerInstance())
|
|
results[i] = p.Get(0)
|
|
}
|
|
if (sol.IsSelectAll())
|
|
return this._RunObject_FirstFilter(sol);
|
|
else
|
|
return this._RunObject_NextFilter(sol)
|
|
}
|
|
*_DebugRunObject() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
return this._RunObject()
|
|
}
|
|
_EvaluateVaryingParameters(solIndex) {
|
|
const parameters = this._parameters;
|
|
const results = this._results;
|
|
for (let i = 0, len = parameters.length; i < len; ++i) {
|
|
const p = parameters[i];
|
|
if (p.VariesPerInstance())
|
|
results[i] = p.Get(solIndex)
|
|
}
|
|
}
|
|
_RunObject_FirstFilter(sol) {
|
|
const objectClass = this._objectClass;
|
|
const isFamily = objectClass.IsFamily();
|
|
const familyIndex = objectClass.GetFamilyIndex();
|
|
const behaviorIndex = this._behaviorIndex;
|
|
const isBehavior = behaviorIndex >= 0;
|
|
const allInstances = objectClass.GetInstances();
|
|
const paramsVary = this._anyParamVariesPerInstance;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const isInverted = this._isInverted;
|
|
const isInOrBlock = this._isInOrBlock && !this._isTrigger;
|
|
sol.ClearArrays();
|
|
for (let i = 0, len = allInstances.length; i < len; ++i) {
|
|
const inst = allInstances[i];
|
|
if (paramsVary)
|
|
this._EvaluateVaryingParameters(i);
|
|
let ret;
|
|
if (isBehavior) {
|
|
const offset = isFamily ? inst.GetObjectClass().GetFamilyBehaviorOffset(familyIndex) : 0;
|
|
ret = func.apply(inst.GetBehaviorInstances()[behaviorIndex + offset].GetSdkInstance(), results)
|
|
} else
|
|
ret = func.apply(inst.GetSdkInstance(), results);
|
|
if (C3.xor(ret, isInverted))
|
|
sol._PushInstance(inst);
|
|
else if (isInOrBlock)
|
|
sol._PushElseInstance(inst)
|
|
}
|
|
objectClass.FinishCondition(true);
|
|
sol._SetSelectAll(false);
|
|
objectClass.ApplySolToContainer();
|
|
return sol.HasAnyInstances()
|
|
}
|
|
_RunObject_NextFilter(sol) {
|
|
const objectClass = this._objectClass;
|
|
const isFamily = objectClass.IsFamily();
|
|
const familyIndex = objectClass.GetFamilyIndex();
|
|
const isInContainer = objectClass.IsInContainer();
|
|
const behaviorIndex = this._behaviorIndex;
|
|
const isBehavior = behaviorIndex >= 0;
|
|
const paramsVary = this._anyParamVariesPerInstance;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const isInverted = this._isInverted;
|
|
const isInOrBlock = this._isInOrBlock && !this._isTrigger;
|
|
const solInstances = sol._GetOwnInstances();
|
|
const solElseInstances = sol._GetOwnElseInstances();
|
|
const isUsingElseInstances = isInOrBlock && !this._eventBlock.IsFirstConditionOfType(this);
|
|
const arr = isUsingElseInstances ? solElseInstances : solInstances;
|
|
let k = 0;
|
|
let isAnyTrue = false;
|
|
for (let i = 0, len = arr.length; i < len; ++i) {
|
|
const inst = arr[i];
|
|
if (paramsVary)
|
|
this._EvaluateVaryingParameters(i);
|
|
let ret;
|
|
if (isBehavior) {
|
|
const offset = isFamily ? inst.GetObjectClass().GetFamilyBehaviorOffset(familyIndex) : 0;
|
|
ret = func.apply(inst.GetBehaviorInstances()[behaviorIndex + offset].GetSdkInstance(), results)
|
|
} else
|
|
ret = func.apply(inst.GetSdkInstance(), results);
|
|
if (C3.xor(ret, isInverted)) {
|
|
isAnyTrue = true;
|
|
if (isUsingElseInstances) {
|
|
solInstances.push(inst);
|
|
if (isInContainer)
|
|
inst._PushSiblingsToSolInstances()
|
|
} else {
|
|
arr[k] = inst;
|
|
if (isInContainer)
|
|
inst._SetSiblingsToSolInstancesIndex(k);
|
|
++k
|
|
}
|
|
} else if (isUsingElseInstances) {
|
|
arr[k] = inst;
|
|
if (isInContainer)
|
|
inst._SetSiblingsToSolElseInstancesIndex(k);
|
|
++k
|
|
} else if (isInOrBlock) {
|
|
solElseInstances.push(inst);
|
|
if (isInContainer)
|
|
inst._PushSiblingsToSolElseInstances()
|
|
}
|
|
}
|
|
C3.truncateArray(arr, k);
|
|
if (isInContainer)
|
|
objectClass._TruncateContainerSols(isUsingElseInstances, k);
|
|
const pickInFinish = isAnyTrue;
|
|
if (isUsingElseInstances && !isAnyTrue)
|
|
isAnyTrue = this._OrBlockCheckInstances(solInstances);
|
|
objectClass.FinishCondition(pickInFinish || isInOrBlock);
|
|
return isInOrBlock ? isAnyTrue : sol.HasAnyInstances()
|
|
}
|
|
_OrBlockCheckInstances(solInstances) {
|
|
const objectClass = this._objectClass;
|
|
const isFamily = objectClass.IsFamily();
|
|
const familyIndex = objectClass.GetFamilyIndex();
|
|
const paramsVary = this._anyParamVariesPerInstance;
|
|
const behaviorIndex = this._behaviorIndex;
|
|
const isBehavior = behaviorIndex >= 0;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const isInverted = this._isInverted;
|
|
for (let i = 0, len = solInstances.length; i < len; ++i) {
|
|
const inst = solInstances[i];
|
|
if (paramsVary)
|
|
this._EvaluateVaryingParameters(i);
|
|
let ret;
|
|
if (isBehavior) {
|
|
const offset = isFamily ? inst.GetObjectClass().GetFamilyBehaviorOffset(familyIndex) : 0;
|
|
ret = func.apply(inst.GetBehaviorInstances()[behaviorIndex + offset].GetSdkInstance(), results)
|
|
} else
|
|
ret = func.apply(inst.GetSdkInstance(), results);
|
|
if (C3.xor(ret, isInverted))
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
ReevaluateParameter(paramIndex, solIndex) {
|
|
return this._parameters[paramIndex].Get(solIndex)
|
|
}
|
|
GetFastTriggerValue() {
|
|
const parameters = this._parameters;
|
|
if (!parameters.length)
|
|
throw new Error("no parameters");
|
|
return parameters[0]._GetFastTriggerValue()
|
|
}
|
|
_SaveToJson() {
|
|
if (!this._savedData || !this._savedData.size)
|
|
return null;
|
|
const ex = {};
|
|
for (const [k,v] of this._savedData.entries()) {
|
|
let saveVal = v;
|
|
if (k === "collmemory")
|
|
saveVal = [...v.entries()].map(arr=>[arr[0].GetUID(), arr[1].GetUID(), arr[2]]);
|
|
ex[k] = saveVal
|
|
}
|
|
return {
|
|
"ex": ex
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (this._savedData) {
|
|
this._savedData.clear();
|
|
this._savedData = null
|
|
}
|
|
if (!o)
|
|
return;
|
|
const runtime = this._runtime;
|
|
const ex = o["ex"];
|
|
if (ex) {
|
|
const map = this.GetSavedDataMap();
|
|
map.clear();
|
|
for (const [k,v] of Object.entries(ex)) {
|
|
let loadVal = v;
|
|
if (k === "collmemory")
|
|
loadVal = C3.New(C3.PairMap, v.map(arr=>[runtime.GetInstanceByUID(arr[0]), runtime.GetInstanceByUID(arr[1]), arr[2]]).filter(arr=>arr[0] && arr[1]));
|
|
map.set(k, loadVal)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const assert = self.assert;
|
|
function EvalParams(parameters, results) {
|
|
for (let i = 0, len = parameters.length; i < len; ++i)
|
|
results[i] = parameters[i].Get(0)
|
|
}
|
|
const EMPTY_PARAMS_ARRAY = [];
|
|
const noop = function() {};
|
|
const noopGenerator = function*() {};
|
|
C3.Action = class Action extends C3.DefendedBase {
|
|
constructor(eventBlock, data, index) {
|
|
super();
|
|
this._eventBlock = eventBlock;
|
|
const runtime = eventBlock.GetRuntime();
|
|
this._runtime = runtime;
|
|
this._index = index;
|
|
this._sid = data.length >= 4 ? data[3] : -1;
|
|
this._actionReturnType = data.length >= 5 ? data[4] : 0;
|
|
this._func = null;
|
|
this._objectClass = null;
|
|
this._behaviorType = null;
|
|
this._behaviorIndex = -1;
|
|
this._systemPlugin = null;
|
|
this._callFunctionName = "";
|
|
this._callEventBlock = null;
|
|
this._combinedSolModifiers = null;
|
|
this.Run = noop;
|
|
this.DebugRun = noop;
|
|
this._parameters = [];
|
|
this._results = [];
|
|
this._anyParamVariesPerInstance = false;
|
|
this._savedData = null;
|
|
this._unsavedData = null;
|
|
const isScript = data[0] === -3;
|
|
const debugInfo = isScript ? data[2] : data[5];
|
|
this._debugData = runtime.IsDebug() || isScript ? {
|
|
isBreakpoint: debugInfo[0],
|
|
canDebug: debugInfo[1],
|
|
index: debugInfo[2]
|
|
} : null;
|
|
if (data[0] === -1) {
|
|
this._systemPlugin = runtime.GetSystemPlugin();
|
|
this._func = runtime.GetObjectReference(data[1])
|
|
} else if (data[0] === -2)
|
|
this._callFunctionName = data[1];
|
|
else if (isScript) {
|
|
const userMethod = runtime.GetObjectReference(data[1]);
|
|
this._func = userMethod;
|
|
this.Run = this.RunUserScript;
|
|
this.DebugRun = this.DebugRunUserScript;
|
|
this._actionReturnType = 1
|
|
} else {
|
|
this._func = runtime.GetObjectReference(data[1]);
|
|
this._objectClass = runtime.GetObjectClassByIndex(data[0]);
|
|
if (data[2]) {
|
|
this._behaviorType = this._objectClass.GetBehaviorTypeByName(data[2]);
|
|
this._behaviorIndex = this._objectClass.GetBehaviorIndexByName(data[2])
|
|
}
|
|
}
|
|
if (data.length === 7) {
|
|
const paramData = data[6];
|
|
for (const data of paramData) {
|
|
this._parameters.push(C3.Parameter.Create(this, data, this._parameters.length));
|
|
this._results.push(0)
|
|
}
|
|
}
|
|
if (this._parameters.length === 0) {
|
|
this._parameters = EMPTY_PARAMS_ARRAY;
|
|
this._results = EMPTY_PARAMS_ARRAY
|
|
}
|
|
this._eventBlock.GetEventSheetManager()._RegisterAction(this)
|
|
}
|
|
static Create(eventBlock, data, index) {
|
|
return C3.New(C3.Action, eventBlock, data, index)
|
|
}
|
|
_PostInit() {
|
|
for (const param of this._parameters) {
|
|
param._PostInit();
|
|
if (param.VariesPerInstance())
|
|
this._anyParamVariesPerInstance = true
|
|
}
|
|
if (this._systemPlugin) {
|
|
this._SetSystemRunMethod();
|
|
this.DebugRun = this._DebugRunSystem
|
|
} else if (this._callFunctionName) {
|
|
this._SetCallFunctionRunMethod();
|
|
this._callFunctionName = ""
|
|
} else if (this.Run === this.RunUserScript) {
|
|
const userMethod = this._func;
|
|
const localVars = this._runtime.GetEventSheetManager()._GetLocalVariablesScriptInterface(this._eventBlock);
|
|
this._func = userMethod.bind(null, this._runtime.GetIRuntime(), localVars)
|
|
} else if (this._behaviorType)
|
|
if (this.IsAsync()) {
|
|
this.Run = this._RunBehavior_Async;
|
|
this.DebugRun = this._DebugRunBehavior_Async
|
|
} else {
|
|
this.Run = this._RunBehavior;
|
|
this.DebugRun = this._DebugRunBehavior
|
|
}
|
|
else if (this._objectClass.GetPlugin().IsSingleGlobal()) {
|
|
this._SetSingleGlobalRunMethod();
|
|
this.DebugRun = this._DebugRunSingleGlobal
|
|
} else if (this.IsAsync()) {
|
|
this.Run = this._RunObject_Async;
|
|
this.DebugRun = this._DebugRunObject_Async
|
|
} else if (!this._parameters.length) {
|
|
this.Run = this._RunObject_ParamsConst;
|
|
this.DebugRun = this._DebugRunObject_ParamsConst
|
|
} else if (this._parameters.every(p=>p.VariesPerInstance())) {
|
|
this.Run = this._RunObject_AllParamsVary;
|
|
this.DebugRun = this._DebugRunObject_AllParamsVary
|
|
} else if (this._anyParamVariesPerInstance) {
|
|
this.Run = this._RunObject_SomeParamsVary;
|
|
this.DebugRun = this._DebugRunObject_SomeParamsVary
|
|
} else if (this._parameters.every(p=>p.IsConstant())) {
|
|
EvalParams(this._parameters, this._results);
|
|
this.Run = this._RunObject_ParamsConst;
|
|
this.DebugRun = this._DebugRunObject_ParamsConst
|
|
} else {
|
|
this.Run = this._RunObject_ParamsDontVary;
|
|
this.DebugRun = this._DebugRunObject_ParamsDontVary
|
|
}
|
|
}
|
|
_SetSystemRunMethod() {
|
|
const plugin = this._systemPlugin;
|
|
const bindThis = this._systemPlugin;
|
|
this._SetRunMethodForBoundFunc(plugin, bindThis, this._RunSystem)
|
|
}
|
|
_SetSingleGlobalRunMethod() {
|
|
const plugin = this._objectClass.GetPlugin();
|
|
const bindThis = this._objectClass.GetSingleGlobalInstance().GetSdkInstance();
|
|
this._SetRunMethodForBoundFunc(plugin, bindThis, this._RunSingleGlobal)
|
|
}
|
|
_SetCallFunctionRunMethod() {
|
|
const eventSheetManager = this._eventBlock.GetEventSheetManager();
|
|
const functionBlock = eventSheetManager.GetFunctionBlockByName(this._callFunctionName);
|
|
if (functionBlock.IsEnabled()) {
|
|
this._callEventBlock = functionBlock.GetEventBlock();
|
|
this._combinedSolModifiers = [...new Set([...this._eventBlock.GetSolModifiersIncludingParents(), ...this._callEventBlock.GetSolModifiersIncludingParents()])];
|
|
this._combinedSolModifiers = eventSheetManager._DeduplicateSolModifierList(this._combinedSolModifiers);
|
|
this.Run = C3.EventBlock.prototype.RunAsFunctionCall.bind(this._callEventBlock, this._combinedSolModifiers, this._parameters);
|
|
this.DebugRun = this._DebugRunCallFunction
|
|
} else {
|
|
this.Run = noop;
|
|
this.DebugRun = noopGenerator
|
|
}
|
|
}
|
|
_SetRunMethodForBoundFunc(plugin, bindThis, fallbackMethod) {
|
|
const func = this._func;
|
|
const parameters = this._parameters;
|
|
if (parameters.length === 0)
|
|
this.Run = plugin._GetBoundACEMethod(func, bindThis);
|
|
else if (parameters.length === 1) {
|
|
const param0 = parameters[0];
|
|
if (param0.IsConstant())
|
|
this.Run = plugin._GetBoundACEMethod_1param(func, bindThis, param0.Get(0));
|
|
else {
|
|
const boundFunc = plugin._GetBoundACEMethod(func, bindThis);
|
|
this.Run = function RunSingleAct_1param() {
|
|
return boundFunc(param0.Get(0))
|
|
}
|
|
}
|
|
} else if (parameters.length === 2) {
|
|
const param0 = parameters[0];
|
|
const param1 = parameters[1];
|
|
if (param0.IsConstant() && param1.IsConstant())
|
|
this.Run = plugin._GetBoundACEMethod_2params(func, bindThis, param0.Get(0), param1.Get(0));
|
|
else {
|
|
const boundFunc = plugin._GetBoundACEMethod(func, bindThis);
|
|
this.Run = function RunSingleAct_2params() {
|
|
return boundFunc(param0.Get(0), param1.Get(0))
|
|
}
|
|
}
|
|
} else if (parameters.length === 3) {
|
|
const param0 = parameters[0];
|
|
const param1 = parameters[1];
|
|
const param2 = parameters[2];
|
|
if (param0.IsConstant() && param1.IsConstant() && param2.IsConstant())
|
|
this.Run = plugin._GetBoundACEMethod_3params(func, bindThis, param0.Get(0), param1.Get(0), param2.Get(0));
|
|
else {
|
|
const boundFunc = plugin._GetBoundACEMethod(func, bindThis);
|
|
this.Run = function RunSingleAct_3params() {
|
|
return boundFunc(param0.Get(0), param1.Get(0), param2.Get(0))
|
|
}
|
|
}
|
|
} else
|
|
this.Run = fallbackMethod
|
|
}
|
|
GetSID() {
|
|
return this._sid
|
|
}
|
|
IsAsync() {
|
|
return this._actionReturnType === 1
|
|
}
|
|
CanBailOut() {
|
|
return this._actionReturnType === 2
|
|
}
|
|
HasReturnType() {
|
|
return this._actionReturnType !== 0
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectClass
|
|
}
|
|
GetEventBlock() {
|
|
return this._eventBlock
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetIndex() {
|
|
return this._index
|
|
}
|
|
GetDebugIndex() {
|
|
return this._debugData.index
|
|
}
|
|
GetCombinedSolModifiers() {
|
|
return this._combinedSolModifiers
|
|
}
|
|
IsBreakpoint() {
|
|
return this._debugData.isBreakpoint
|
|
}
|
|
_SetBreakpoint(b) {
|
|
this._debugData.isBreakpoint = !!b;
|
|
this._eventBlock._UpdateCanRunFastRecursive()
|
|
}
|
|
_DebugReturnsGenerator() {
|
|
return this._debugData.canDebug
|
|
}
|
|
DebugCanRunFast() {
|
|
return !this.IsBreakpoint() && !this._runtime.DebugBreakNext() && !this._DebugReturnsGenerator()
|
|
}
|
|
GetSavedDataMap() {
|
|
if (!this._savedData)
|
|
this._savedData = new Map;
|
|
return this._savedData
|
|
}
|
|
GetUnsavedDataMap() {
|
|
if (!this._unsavedData)
|
|
this._unsavedData = new Map;
|
|
return this._unsavedData
|
|
}
|
|
_RunSystem() {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
return this._func.apply(this._systemPlugin, results)
|
|
}
|
|
*_DebugRunSystem() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
const ret = yield*this._func.apply(this._systemPlugin, results);
|
|
return ret
|
|
} else
|
|
return this.Run()
|
|
}
|
|
*_DebugRunCallFunction() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
const ret = yield*this._callEventBlock.DebugRunAsFunctionCall(this._combinedSolModifiers, this._parameters);
|
|
return ret
|
|
}
|
|
_RunSingleGlobal() {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
return this._func.apply(this._objectClass.GetSingleGlobalInstance().GetSdkInstance(), results)
|
|
}
|
|
*_DebugRunSingleGlobal() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
const ret = yield*this._func.apply(this._objectClass.GetSingleGlobalInstance().GetSdkInstance(), results);
|
|
return ret
|
|
} else
|
|
return this.Run()
|
|
}
|
|
_RunObject_ParamsConst() {
|
|
const results = this._results;
|
|
const instances = this._objectClass.GetCurrentSol().GetInstances();
|
|
for (let i = 0, len = instances.length; i < len; ++i)
|
|
this._func.apply(instances[i].GetSdkInstance(), results)
|
|
}
|
|
*_DebugRunObject_ParamsConst() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const results = this._results;
|
|
const instances = this._objectClass.GetCurrentSol().GetInstances();
|
|
for (let i = 0, len = instances.length; i < len; ++i)
|
|
yield*this._func.apply(instances[i].GetSdkInstance(), results)
|
|
} else
|
|
this._RunObject_ParamsConst()
|
|
}
|
|
_RunObject_ParamsDontVary() {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
const instances = this._objectClass.GetCurrentSol().GetInstances();
|
|
for (let i = 0, len = instances.length; i < len; ++i)
|
|
this._func.apply(instances[i].GetSdkInstance(), results)
|
|
}
|
|
*_DebugRunObject_ParamsDontVary() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const results = this._results;
|
|
EvalParams(this._parameters, results);
|
|
const instances = this._objectClass.GetCurrentSol().GetInstances();
|
|
for (let i = 0, len = instances.length; i < len; ++i)
|
|
yield*this._func.apply(instances[i].GetSdkInstance(), results)
|
|
} else
|
|
this._RunObject_ParamsDontVary()
|
|
}
|
|
_RunObject_AllParamsVary() {
|
|
const parameters = this._parameters;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const instances = this._objectClass.GetCurrentSol().GetInstances();
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
for (let j = 0, lenj = parameters.length; j < lenj; ++j)
|
|
results[j] = parameters[j].Get(i);
|
|
func.apply(inst.GetSdkInstance(), results)
|
|
}
|
|
}
|
|
*_DebugRunObject_AllParamsVary() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const parameters = this._parameters;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const instances = this._objectClass.GetCurrentSol().GetInstances();
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
for (let j = 0, lenj = parameters.length; j < lenj; ++j)
|
|
results[j] = parameters[j].Get(i);
|
|
yield*func.apply(inst.GetSdkInstance(), results)
|
|
}
|
|
} else
|
|
this._RunObject_AllParamsVary()
|
|
}
|
|
_RunObject_SomeParamsVary() {
|
|
const parameters = this._parameters;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const instances = this._objectClass.GetCurrentSol().GetInstances();
|
|
for (let i = 0, len = parameters.length; i < len; ++i) {
|
|
const p = parameters[i];
|
|
if (!p.VariesPerInstance())
|
|
results[i] = p.Get(0)
|
|
}
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
for (let j = 0, lenj = parameters.length; j < lenj; ++j) {
|
|
const p = parameters[j];
|
|
if (p.VariesPerInstance())
|
|
results[j] = p.Get(i)
|
|
}
|
|
func.apply(inst.GetSdkInstance(), results)
|
|
}
|
|
}
|
|
*_DebugRunObject_SomeParamsVary() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const parameters = this._parameters;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const instances = this._objectClass.GetCurrentSol().GetInstances();
|
|
for (let i = 0, len = parameters.length; i < len; ++i) {
|
|
const p = parameters[i];
|
|
if (!p.VariesPerInstance())
|
|
results[i] = p.Get(0)
|
|
}
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
for (let j = 0, lenj = parameters.length; j < lenj; ++j) {
|
|
const p = parameters[j];
|
|
if (p.VariesPerInstance())
|
|
results[j] = p.Get(i)
|
|
}
|
|
yield*func.apply(inst.GetSdkInstance(), results)
|
|
}
|
|
} else
|
|
this._RunObject_SomeParamsVary()
|
|
}
|
|
_RunBehavior() {
|
|
const objectClass = this._objectClass;
|
|
const isFamily = objectClass.IsFamily();
|
|
const familyIndex = objectClass.GetFamilyIndex();
|
|
const parameters = this._parameters;
|
|
const paramsVary = this._anyParamVariesPerInstance;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const behaviorIndex = this._behaviorIndex;
|
|
const instances = objectClass.GetCurrentSol().GetInstances();
|
|
for (let i = 0, len = parameters.length; i < len; ++i) {
|
|
const p = parameters[i];
|
|
if (!p.VariesPerInstance())
|
|
results[i] = p.Get(0)
|
|
}
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
if (paramsVary)
|
|
for (let j = 0, lenj = parameters.length; j < lenj; ++j) {
|
|
const p = parameters[j];
|
|
if (p.VariesPerInstance())
|
|
results[j] = p.Get(i)
|
|
}
|
|
const offset = isFamily ? inst.GetObjectClass().GetFamilyBehaviorOffset(familyIndex) : 0;
|
|
func.apply(inst.GetBehaviorInstances()[behaviorIndex + offset].GetSdkInstance(), results)
|
|
}
|
|
}
|
|
*_DebugRunBehavior() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const objectClass = this._objectClass;
|
|
const isFamily = objectClass.IsFamily();
|
|
const familyIndex = objectClass.GetFamilyIndex();
|
|
const parameters = this._parameters;
|
|
const paramsVary = this._anyParamVariesPerInstance;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const behaviorIndex = this._behaviorIndex;
|
|
const instances = objectClass.GetCurrentSol().GetInstances();
|
|
for (let i = 0, len = parameters.length; i < len; ++i) {
|
|
const p = parameters[i];
|
|
if (!p.VariesPerInstance())
|
|
results[i] = p.Get(0)
|
|
}
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
if (paramsVary)
|
|
for (let j = 0, lenj = parameters.length; j < lenj; ++j) {
|
|
const p = parameters[j];
|
|
if (p.VariesPerInstance())
|
|
results[j] = p.Get(i)
|
|
}
|
|
const offset = isFamily ? inst.GetObjectClass().GetFamilyBehaviorOffset(familyIndex) : 0;
|
|
yield*func.apply(inst.GetBehaviorInstances()[behaviorIndex + offset].GetSdkInstance(), results)
|
|
}
|
|
} else
|
|
this._RunBehavior()
|
|
}
|
|
_RunObject_Async() {
|
|
const parameters = this._parameters;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const instances = this._objectClass.GetCurrentSol().GetInstances();
|
|
const promises = [];
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
for (let j = 0, lenj = parameters.length; j < lenj; ++j)
|
|
results[j] = parameters[j].Get(i);
|
|
promises.push(func.apply(inst.GetSdkInstance(), results))
|
|
}
|
|
return Promise.all(promises)
|
|
}
|
|
*_DebugRunObject_Async() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const parameters = this._parameters;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const instances = this._objectClass.GetCurrentSol().GetInstances();
|
|
const promises = [];
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
for (let j = 0, lenj = parameters.length; j < lenj; ++j)
|
|
results[j] = parameters[j].Get(i);
|
|
promises.push(yield*func.apply(inst.GetSdkInstance(), results))
|
|
}
|
|
return Promise.all(promises)
|
|
} else
|
|
return this._RunObject_Async()
|
|
}
|
|
_RunBehavior_Async() {
|
|
const objectClass = this._objectClass;
|
|
const isFamily = objectClass.IsFamily();
|
|
const familyIndex = objectClass.GetFamilyIndex();
|
|
const parameters = this._parameters;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const behaviorIndex = this._behaviorIndex;
|
|
const instances = objectClass.GetCurrentSol().GetInstances();
|
|
const promises = [];
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
for (let j = 0, lenj = parameters.length; j < lenj; ++j)
|
|
results[j] = parameters[j].Get(i);
|
|
const offset = isFamily ? inst.GetObjectClass().GetFamilyBehaviorOffset(familyIndex) : 0;
|
|
promises.push(func.apply(inst.GetBehaviorInstances()[behaviorIndex + offset].GetSdkInstance(), results))
|
|
}
|
|
return Promise.all(promises)
|
|
}
|
|
*_DebugRunBehavior_Async() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
if (this._DebugReturnsGenerator()) {
|
|
const objectClass = this._objectClass;
|
|
const isFamily = objectClass.IsFamily();
|
|
const familyIndex = objectClass.GetFamilyIndex();
|
|
const parameters = this._parameters;
|
|
const results = this._results;
|
|
const func = this._func;
|
|
const behaviorIndex = this._behaviorIndex;
|
|
const instances = objectClass.GetCurrentSol().GetInstances();
|
|
const promises = [];
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
for (let j = 0, lenj = parameters.length; j < lenj; ++j)
|
|
results[j] = parameters[j].Get(i);
|
|
const offset = isFamily ? inst.GetObjectClass().GetFamilyBehaviorOffset(familyIndex) : 0;
|
|
promises.push(yield*func.apply(inst.GetBehaviorInstances()[behaviorIndex + offset].GetSdkInstance(), results))
|
|
}
|
|
return Promise.all(promises)
|
|
} else
|
|
return this._RunBehavior_Async()
|
|
}
|
|
async RunUserScript() {
|
|
try {
|
|
await this._func()
|
|
} catch (err) {
|
|
console.error(`Unhandled exception running script %c${this._eventBlock.GetEventSheet().GetName()}, event ${this._eventBlock.GetDisplayNumber()}, action ${this.GetDebugIndex() + 1}:`, "font-size: 1.2em; font-weight: bold;", err);
|
|
if (self.C3Debugger)
|
|
self.C3Debugger._SetLastErrorScript(this);
|
|
if (!C3.EventScript.HadUserScriptException()) {
|
|
console.info(`%cTip:%c run this to highlight in Construct the last script that had an error: %cgoToLastErrorScript()`, "font-weight: bold; text-decoration: underline", "", "font-weight: bold");
|
|
C3.EventScript.SetHadUserScriptException()
|
|
}
|
|
}
|
|
}
|
|
*DebugRunUserScript() {
|
|
if (this.IsBreakpoint() || this._runtime.DebugBreakNext())
|
|
yield this;
|
|
return this.RunUserScript()
|
|
}
|
|
_SaveToJson() {
|
|
if (!this._savedData || !this._savedData.size)
|
|
return null;
|
|
return {
|
|
"ex": C3.ToSuperJSON(this._savedData)
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (this._savedData) {
|
|
this._savedData.clear();
|
|
this._savedData = null
|
|
}
|
|
if (!o)
|
|
return;
|
|
const ex = o["ex"];
|
|
if (ex)
|
|
this._savedData = C3.FromSuperJSON(ex)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tempColor = new C3.Color;
|
|
function CompareX(cmp, x) {
|
|
return C3.compare(this.GetWorldInfo().GetX(), cmp, x)
|
|
}
|
|
function CompareY(cmp, y) {
|
|
return C3.compare(this.GetWorldInfo().GetY(), cmp, y)
|
|
}
|
|
function IsOnScreen() {
|
|
const wi = this.GetWorldInfo();
|
|
return wi.IsInViewport(wi.GetLayer().GetViewport())
|
|
}
|
|
function IsOutsideLayout() {
|
|
const wi = this.GetWorldInfo();
|
|
const layout = wi.GetLayout();
|
|
const bbox = wi.GetBoundingBox();
|
|
return bbox.getRight() < 0 || bbox.getBottom() < 0 || bbox.getLeft() > layout.GetWidth() || bbox.getTop() > layout.GetHeight()
|
|
}
|
|
function PickDistance(which, x, y) {
|
|
const sol = this.GetCurrentSol();
|
|
const instances = sol.GetInstances();
|
|
if (!instances.length)
|
|
return false;
|
|
let inst = instances[0];
|
|
let wi = inst.GetWorldInfo();
|
|
let pickme = inst;
|
|
let dist2 = C3.distanceSquared(wi.GetX(), wi.GetY(), x, y);
|
|
for (let i = 1, len = instances.length; i < len; ++i) {
|
|
inst = instances[i];
|
|
wi = inst.GetWorldInfo();
|
|
const d2 = C3.distanceSquared(wi.GetX(), wi.GetY(), x, y);
|
|
if (which === 0 && d2 < dist2 || which === 1 && d2 > dist2) {
|
|
dist2 = d2;
|
|
pickme = inst
|
|
}
|
|
}
|
|
sol.PickOne(pickme);
|
|
return true
|
|
}
|
|
function SetX(x) {
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.GetX() === x)
|
|
return;
|
|
wi.SetX(x);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function SetY(y) {
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.GetY() === y)
|
|
return;
|
|
wi.SetY(y);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function SetPos(x, y) {
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.EqualsXY(x, y))
|
|
return;
|
|
wi.SetXY(x, y);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function SetPosToObject(objectClass, imgPt) {
|
|
if (!objectClass)
|
|
return;
|
|
const inst = objectClass.GetPairedInstance(this._inst);
|
|
if (!inst)
|
|
return;
|
|
const [x,y] = inst.GetImagePoint(imgPt);
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.GetX() === x && wi.GetY() === y)
|
|
return;
|
|
wi.SetXY(x, y);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function MoveForward(dist) {
|
|
if (dist === 0)
|
|
return;
|
|
const wi = this.GetWorldInfo();
|
|
wi.OffsetXY(wi.GetCosAngle() * dist, wi.GetSinAngle() * dist);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function MoveAtAngle(a, dist) {
|
|
if (dist === 0)
|
|
return;
|
|
const wi = this.GetWorldInfo();
|
|
a = C3.toRadians(a);
|
|
wi.OffsetXY(Math.cos(a) * dist, Math.sin(a) * dist);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function GetX() {
|
|
return this.GetWorldInfo().GetX()
|
|
}
|
|
function GetY() {
|
|
return this.GetWorldInfo().GetY()
|
|
}
|
|
function GetDt() {
|
|
return this._runtime.GetDt(this._inst)
|
|
}
|
|
function CompareWidth(cmp, w) {
|
|
return C3.compare(this.GetWorldInfo().GetWidth(), cmp, w)
|
|
}
|
|
function CompareHeight(cmp, h) {
|
|
return C3.compare(this.GetWorldInfo().GetHeight(), cmp, h)
|
|
}
|
|
function SetWidth(w) {
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.GetWidth() === w)
|
|
return;
|
|
wi.SetWidth(w);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function SetHeight(h) {
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.GetHeight() === h)
|
|
return;
|
|
wi.SetHeight(h);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function SetSize(w, h) {
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.GetWidth() === w && wi.GetHeight() === h)
|
|
return;
|
|
wi.SetSize(w, h);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function GetWidth() {
|
|
return this.GetWorldInfo().GetWidth()
|
|
}
|
|
function GetHeight() {
|
|
return this.GetWorldInfo().GetHeight()
|
|
}
|
|
function GetBboxLeft() {
|
|
return this.GetWorldInfo().GetBoundingBox().getLeft()
|
|
}
|
|
function GetBboxTop() {
|
|
return this.GetWorldInfo().GetBoundingBox().getTop()
|
|
}
|
|
function GetBboxRight() {
|
|
return this.GetWorldInfo().GetBoundingBox().getRight()
|
|
}
|
|
function GetBboxBottom() {
|
|
return this.GetWorldInfo().GetBoundingBox().getBottom()
|
|
}
|
|
function IsAngleWithin(within, a) {
|
|
return C3.angleDiff(this.GetWorldInfo().GetAngle(), C3.toRadians(a)) <= C3.toRadians(within)
|
|
}
|
|
function IsAngleClockwiseFrom(a) {
|
|
return C3.angleClockwise(this.GetWorldInfo().GetAngle(), C3.toRadians(a))
|
|
}
|
|
function IsBetweenAngles(a, b) {
|
|
const lower = C3.toRadians(a);
|
|
const upper = C3.toRadians(b);
|
|
const angle = this.GetWorldInfo().GetAngle();
|
|
const obtuse = !C3.angleClockwise(upper, lower);
|
|
if (obtuse)
|
|
return !(!C3.angleClockwise(angle, lower) && C3.angleClockwise(angle, upper));
|
|
else
|
|
return C3.angleClockwise(angle, lower) && !C3.angleClockwise(angle, upper)
|
|
}
|
|
function SetAngle(a) {
|
|
const wi = this.GetWorldInfo();
|
|
const newAngle = C3.clampAngle(C3.toRadians(a));
|
|
if (isNaN(newAngle) || wi.GetAngle() === newAngle)
|
|
return;
|
|
wi.SetAngle(newAngle);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function RotateClockwise(a) {
|
|
if (isNaN(a) || a === 0)
|
|
return;
|
|
const wi = this.GetWorldInfo();
|
|
wi.SetAngle(wi.GetAngle() + C3.toRadians(a));
|
|
wi.SetBboxChanged()
|
|
}
|
|
function RotateCounterclockwise(a) {
|
|
if (isNaN(a) || a === 0)
|
|
return;
|
|
const wi = this.GetWorldInfo();
|
|
wi.SetAngle(wi.GetAngle() - C3.toRadians(a));
|
|
wi.SetBboxChanged()
|
|
}
|
|
function RotateTowardAngle(amt, target) {
|
|
const wi = this.GetWorldInfo();
|
|
const a = wi.GetAngle();
|
|
const newAngle = C3.angleRotate(a, C3.toRadians(target), C3.toRadians(amt));
|
|
if (isNaN(newAngle) || a === newAngle)
|
|
return;
|
|
wi.SetAngle(newAngle);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function RotateTowardPosition(amt, x, y) {
|
|
const wi = this.GetWorldInfo();
|
|
const a = wi.GetAngle();
|
|
const dx = x - wi.GetX();
|
|
const dy = y - wi.GetY();
|
|
const target = Math.atan2(dy, dx);
|
|
const newAngle = C3.angleRotate(a, target, C3.toRadians(amt));
|
|
if (isNaN(newAngle) || a === newAngle)
|
|
return;
|
|
wi.SetAngle(newAngle);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function SetTowardPosition(x, y) {
|
|
const wi = this.GetWorldInfo();
|
|
const a = wi.GetAngle();
|
|
const dx = x - wi.GetX();
|
|
const dy = y - wi.GetY();
|
|
const newAngle = Math.atan2(dy, dx);
|
|
if (isNaN(newAngle) || a === newAngle)
|
|
return;
|
|
wi.SetAngle(newAngle);
|
|
wi.SetBboxChanged()
|
|
}
|
|
function GetAngle() {
|
|
return C3.toDegrees(this.GetWorldInfo().GetAngle())
|
|
}
|
|
function CompareOpacity(cmp, x) {
|
|
return C3.compare(C3.round6dp(this.GetWorldInfo().GetOpacity() * 100), cmp, x)
|
|
}
|
|
function IsVisible() {
|
|
return this.GetWorldInfo().IsVisible()
|
|
}
|
|
function SetVisible(v) {
|
|
const wi = this.GetWorldInfo();
|
|
if (v === 2)
|
|
v = !wi.IsVisible();
|
|
else
|
|
v = v !== 0;
|
|
if (wi.IsVisible() === v)
|
|
return;
|
|
wi.SetVisible(v);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
function SetOpacity(o) {
|
|
const newOpacity = C3.clamp(o / 100, 0, 1);
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.GetOpacity() === newOpacity)
|
|
return;
|
|
wi.SetOpacity(newOpacity);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
function SetDefaultColor(rgb) {
|
|
tempColor.setFromRgbValue(rgb);
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.GetUnpremultipliedColor().equalsIgnoringAlpha(tempColor))
|
|
return;
|
|
wi.SetUnpremultipliedColor(tempColor);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
function GetColor() {
|
|
const c = this.GetWorldInfo().GetUnpremultipliedColor();
|
|
return C3.PackRGBAEx(c.getR(), c.getG(), c.getB(), c.getA())
|
|
}
|
|
function GetOpacity() {
|
|
return C3.round6dp(this.GetWorldInfo().GetOpacity() * 100)
|
|
}
|
|
function IsOnLayer(layer) {
|
|
if (!layer)
|
|
return false;
|
|
return this.GetWorldInfo().GetLayer() === layer
|
|
}
|
|
function PickTopBottom(which) {
|
|
const sol = this.GetCurrentSol();
|
|
const instances = sol.GetInstances();
|
|
if (!instances.length)
|
|
return false;
|
|
let inst = instances[0];
|
|
let pickme = inst;
|
|
for (let i = 1, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
const instWi = inst.GetWorldInfo();
|
|
const pickmeWi = pickme.GetWorldInfo();
|
|
const instLayerIndex = instWi.GetLayer().GetIndex();
|
|
const pickmeLayerIndex = pickmeWi.GetLayer().GetIndex();
|
|
if (which === 0) {
|
|
if (instLayerIndex > pickmeLayerIndex || instLayerIndex === pickmeLayerIndex && instWi.GetZIndex() > pickmeWi.GetZIndex())
|
|
pickme = inst
|
|
} else if (instLayerIndex < pickmeLayerIndex || instLayerIndex === pickmeLayerIndex && instWi.GetZIndex() < pickmeWi.GetZIndex())
|
|
pickme = inst
|
|
}
|
|
sol.PickOne(pickme);
|
|
return true
|
|
}
|
|
function CompareZElevation(which, cmp, value) {
|
|
const wi = this.GetWorldInfo();
|
|
const z = which === 0 ? wi.GetZElevation() : wi.GetTotalZElevation();
|
|
return C3.compare(z, cmp, value)
|
|
}
|
|
function MoveToTop() {
|
|
this.GetWorldInfo().ZOrderMoveToTop()
|
|
}
|
|
function MoveToBottom() {
|
|
this.GetWorldInfo().ZOrderMoveToBottom()
|
|
}
|
|
function MoveToLayer(layerMove) {
|
|
if (!layerMove)
|
|
return;
|
|
this.GetWorldInfo().ZOrderMoveToLayer(layerMove)
|
|
}
|
|
function ZMoveToObject(where, objectClass) {
|
|
const isAfter = where === 0;
|
|
if (!objectClass)
|
|
return;
|
|
const otherInst = objectClass.GetFirstPicked(this.GetInstance());
|
|
if (!otherInst)
|
|
return;
|
|
this.GetWorldInfo().ZOrderMoveAdjacentToInstance(otherInst, isAfter)
|
|
}
|
|
function SetZElevation(z) {
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.GetZElevation() === z)
|
|
return;
|
|
wi.SetZElevation(z);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
function LayerNumber() {
|
|
return this.GetWorldInfo().GetLayer().GetIndex()
|
|
}
|
|
function LayerName() {
|
|
return this.GetWorldInfo().GetLayer().GetName()
|
|
}
|
|
function ZIndex() {
|
|
return this.GetWorldInfo().GetZIndex()
|
|
}
|
|
function ZElevation() {
|
|
return this.GetWorldInfo().GetZElevation()
|
|
}
|
|
function TotalZElevation() {
|
|
return this.GetWorldInfo().GetTotalZElevation()
|
|
}
|
|
function SetEffectEnabled(enabled, effectName) {
|
|
const effectType = this.GetObjectClass().GetEffectList().GetEffectTypeByName(effectName);
|
|
if (!effectType)
|
|
return;
|
|
const effectTypeIndex = effectType.GetIndex();
|
|
const e = enabled === 1;
|
|
const instFxList = this.GetWorldInfo().GetInstanceEffectList();
|
|
if (instFxList.IsEffectIndexActive(effectTypeIndex) === e)
|
|
return;
|
|
instFxList.SetEffectIndexActive(effectTypeIndex, e);
|
|
instFxList.UpdateActiveEffects();
|
|
this._runtime.UpdateRender()
|
|
}
|
|
function SetEffectParam(effectName, paramIndex, value) {
|
|
const effectType = this.GetObjectClass().GetEffectList().GetEffectTypeByName(effectName);
|
|
if (!effectType)
|
|
return;
|
|
const effectTypeIndex = effectType.GetIndex();
|
|
const instFxList = this.GetWorldInfo().GetInstanceEffectList();
|
|
const paramsArr = instFxList.GetEffectParametersForIndex(effectTypeIndex);
|
|
paramIndex = Math.floor(paramIndex);
|
|
if (paramIndex < 0 || paramIndex >= paramsArr.length)
|
|
return;
|
|
const paramType = effectType.GetShaderProgram().GetParameterType(paramIndex);
|
|
if (paramType === "color") {
|
|
tempColor.setFromRgbValue(value);
|
|
const curColor = paramsArr[paramIndex];
|
|
if (tempColor.equalsIgnoringAlpha(curColor))
|
|
return;
|
|
curColor.copyRgb(tempColor)
|
|
} else {
|
|
if (paramType === "percent")
|
|
value /= 100;
|
|
if (paramsArr[paramIndex] === value)
|
|
return;
|
|
paramsArr[paramIndex] = value
|
|
}
|
|
if (instFxList.IsEffectIndexActive(effectTypeIndex))
|
|
this._runtime.UpdateRender()
|
|
}
|
|
function HasParent() {
|
|
return this.GetWorldInfo().HasParent()
|
|
}
|
|
function HasChildren() {
|
|
return this.GetWorldInfo().HasChildren()
|
|
}
|
|
function PickParent(parentObjectClass, which) {
|
|
const mySol = this.GetCurrentSol();
|
|
const myInstances = mySol.GetInstances();
|
|
if (myInstances.length === 0)
|
|
return false;
|
|
const parentSol = parentObjectClass.GetCurrentSol();
|
|
const parentInstances = parentSol.GetInstances();
|
|
if (parentInstances.length === 0)
|
|
return false;
|
|
const parentInstancesSet = new Set(parentInstances);
|
|
const pickParents = new Set;
|
|
for (let i = 0, len = myInstances.length; i < len; ++i) {
|
|
const myInst = myInstances[i];
|
|
if (which === 1)
|
|
for (const parentInst of myInst.parents()) {
|
|
if (parentInst.BelongsToObjectClass(parentObjectClass) && parentInstancesSet.has(parentInst))
|
|
pickParents.add(parentInst)
|
|
}
|
|
else {
|
|
let parentInst;
|
|
if (which === 0) {
|
|
parentInst = myInst.GetParent();
|
|
if (parentInst === null)
|
|
continue
|
|
} else
|
|
parentInst = myInst.GetTopParent();
|
|
if (parentInst.BelongsToObjectClass(parentObjectClass) && parentInstancesSet.has(parentInst))
|
|
pickParents.add(parentInst)
|
|
}
|
|
}
|
|
if (pickParents.size === 0)
|
|
return false;
|
|
parentSol.SetSetPicked(pickParents);
|
|
parentObjectClass.ApplySolToContainer();
|
|
return true
|
|
}
|
|
function PickChildren(childObjectClass, which) {
|
|
const mySol = this.GetCurrentSol();
|
|
const myInstances = mySol.GetInstances();
|
|
if (myInstances.length === 0)
|
|
return false;
|
|
const childSol = childObjectClass.GetCurrentSol();
|
|
const childInstances = childSol.GetInstances();
|
|
if (childInstances.length === 0)
|
|
return false;
|
|
const childInstancesSet = new Set(childInstances);
|
|
const pickChildren = new Set;
|
|
for (let i = 0, len = myInstances.length; i < len; ++i) {
|
|
const myInst = myInstances[i];
|
|
if (which === 2 && !myInst.HasChildren() && myInst.BelongsToObjectClass(childObjectClass) && childInstancesSet.has(myInst))
|
|
pickChildren.add(myInst);
|
|
for (const childInst of which === 0 ? myInst.children() : myInst.allChildren()) {
|
|
if (which === 2 && childInst.HasChildren())
|
|
continue;
|
|
if (childInst.BelongsToObjectClass(childObjectClass) && childInstancesSet.has(childInst))
|
|
pickChildren.add(childInst)
|
|
}
|
|
}
|
|
if (pickChildren.size === 0)
|
|
return false;
|
|
childSol.SetSetPicked(pickChildren);
|
|
childObjectClass.ApplySolToContainer();
|
|
return true
|
|
}
|
|
function PickNthChild(childObjectClass, index) {
|
|
const mySol = this.GetCurrentSol();
|
|
const myInstances = mySol.GetInstances();
|
|
if (myInstances.length === 0)
|
|
return false;
|
|
const childSol = childObjectClass.GetCurrentSol();
|
|
const childInstances = childSol.GetInstances();
|
|
if (childInstances.length === 0)
|
|
return false;
|
|
const childInstancesSet = new Set(childInstances);
|
|
const pickChildren = [];
|
|
for (let i = 0, len = myInstances.length; i < len; ++i) {
|
|
const myInst = myInstances[i];
|
|
const childInst = myInst.GetChildAt(index);
|
|
if (childInst !== null && childInst.BelongsToObjectClass(childObjectClass) && childInstancesSet.has(childInst))
|
|
pickChildren.push(childInst)
|
|
}
|
|
if (pickChildren.length === 0)
|
|
return false;
|
|
childSol.SetArrayPicked(pickChildren);
|
|
childObjectClass.ApplySolToContainer();
|
|
return true
|
|
}
|
|
function CompareChildCount(cmp, count) {
|
|
return C3.compare(this._inst.GetChildCount(), cmp, count)
|
|
}
|
|
function AddChild(childObjectClass, transformX, transformY, transformWidth, transformHeight, transformAngle, transformZElevation, destroyWithParent) {
|
|
const inst = this._inst;
|
|
const actObjectClass = this._runtime.GetCurrentAction().GetObjectClass();
|
|
for (const child of childObjectClass.allCorrespondingInstances(inst, actObjectClass)) {
|
|
if (!child.GetPlugin().SupportsSceneGraph())
|
|
return;
|
|
inst.AddChild(child, {
|
|
transformX,
|
|
transformY,
|
|
transformWidth,
|
|
transformHeight,
|
|
transformAngle,
|
|
transformZElevation,
|
|
destroyWithParent
|
|
})
|
|
}
|
|
}
|
|
function RemoveChild(childObjectClass) {
|
|
const inst = this._inst;
|
|
const actObjectClass = this._runtime.GetCurrentAction().GetObjectClass();
|
|
for (const child of childObjectClass.allCorrespondingInstances(inst, actObjectClass))
|
|
inst.RemoveChild(child)
|
|
}
|
|
function RemoveFromParent() {
|
|
if (!this._inst.HasParent())
|
|
return;
|
|
const parent = this._inst.GetParent();
|
|
parent.RemoveChild(this._inst)
|
|
}
|
|
function ChildCount() {
|
|
return this._inst.GetChildCount()
|
|
}
|
|
function SetMeshSize(cols, rows) {
|
|
cols = Math.floor(cols);
|
|
rows = Math.floor(rows);
|
|
const wi = this.GetWorldInfo();
|
|
if (cols < 2 || rows < 2 || !isFinite(cols) || !isFinite(rows)) {
|
|
wi.ReleaseMesh();
|
|
wi.SetBboxChanged()
|
|
} else
|
|
wi.CreateMesh(cols, rows)
|
|
}
|
|
function SetMeshPoint(col, row, mode, posx, posy, texu, texv) {
|
|
const wi = this.GetWorldInfo();
|
|
const didBboxChange = wi.SetMeshPoint(col, row, {
|
|
mode: mode === 0 ? "absolute" : "relative",
|
|
x: posx,
|
|
y: posy,
|
|
u: texu,
|
|
v: texv
|
|
});
|
|
if (didBboxChange)
|
|
wi.SetBboxChanged()
|
|
}
|
|
function MeshColumns() {
|
|
const wi = this.GetWorldInfo();
|
|
return wi.HasMesh() ? wi.GetSourceMesh().GetHSize() : 0
|
|
}
|
|
function MeshRows() {
|
|
const wi = this.GetWorldInfo();
|
|
return wi.HasMesh() ? wi.GetSourceMesh().GetVSize() : 0
|
|
}
|
|
function SetElementVisible(v) {
|
|
const wi = this.GetWorldInfo();
|
|
if (v === 2)
|
|
v = !wi.IsVisible();
|
|
else
|
|
v = v !== 0;
|
|
if (wi.IsVisible() === v)
|
|
return;
|
|
wi.SetVisible(v)
|
|
}
|
|
function SetElementCSSStyle(prop, val) {
|
|
this.SetElementCSSStyle(prop, val)
|
|
}
|
|
function SetElementAttribute(attribName, value) {
|
|
this.SetElementAttribute(attribName, "" + value)
|
|
}
|
|
function RemoveElementAttribute(attribName) {
|
|
this.RemoveElementAttribute(attribName)
|
|
}
|
|
function SetElementFocus() {
|
|
this.FocusElement()
|
|
}
|
|
function SetElementBlur() {
|
|
this.BlurElement()
|
|
}
|
|
function IsElementFocused() {
|
|
return this.IsElementFocused()
|
|
}
|
|
function SetElementEnabled(e) {
|
|
this._SetEnabled(e !== 0)
|
|
}
|
|
function IsElementEnabled() {
|
|
return this._IsEnabled()
|
|
}
|
|
function CompareInstanceVar(iv, cmp, val) {
|
|
return C3.compare(this.GetInstance().GetInstanceVariableValue(iv), cmp, val)
|
|
}
|
|
function IsBoolInstanceVarSet(iv) {
|
|
return !!this.GetInstance().GetInstanceVariableValue(iv)
|
|
}
|
|
function PickInstVarHiLow(which, iv) {
|
|
const sol = this.GetCurrentSol();
|
|
const instances = sol.GetInstances();
|
|
if (!instances.length)
|
|
return false;
|
|
let inst = instances[0];
|
|
let pickme = inst;
|
|
let val = inst.GetInstanceVariableValue(iv);
|
|
for (let i = 1, len = instances.length; i < len; ++i) {
|
|
inst = instances[i];
|
|
const v = inst.GetInstanceVariableValue(iv);
|
|
if (which === 0 && v < val || which === 1 && v > val) {
|
|
val = v;
|
|
pickme = inst
|
|
}
|
|
}
|
|
sol.PickOne(pickme);
|
|
return true
|
|
}
|
|
function PickByUID(uid) {
|
|
if (this._runtime.GetCurrentCondition().IsInverted())
|
|
return PickByUID_Inverted(this, uid);
|
|
else
|
|
return PickByUID_Normal(this, uid)
|
|
}
|
|
function PickByUID_Normal(objectClass, uid) {
|
|
const inst = objectClass.GetRuntime().GetInstanceByUID(uid);
|
|
if (!inst)
|
|
return false;
|
|
const sol = objectClass.GetCurrentSol();
|
|
if (!sol.IsSelectAll() && !sol._GetOwnInstances().includes(inst))
|
|
return false;
|
|
if (objectClass.IsFamily()) {
|
|
if (inst.GetObjectClass().BelongsToFamily(objectClass)) {
|
|
sol.PickOne(inst);
|
|
objectClass.ApplySolToContainer();
|
|
return true
|
|
}
|
|
} else if (inst.GetObjectClass() === objectClass) {
|
|
sol.PickOne(inst);
|
|
objectClass.ApplySolToContainer();
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
function PickByUID_Inverted(objectClass, uid) {
|
|
const sol = objectClass.GetCurrentSol();
|
|
if (sol.IsSelectAll()) {
|
|
sol._SetSelectAll(false);
|
|
sol.ClearArrays();
|
|
const instances = objectClass.GetInstances();
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
if (inst.GetUID() === uid)
|
|
sol._PushElseInstance(inst);
|
|
else
|
|
sol._PushInstance(inst)
|
|
}
|
|
objectClass.ApplySolToContainer();
|
|
return !!sol._GetOwnInstances().length
|
|
} else {
|
|
const instances = sol._GetOwnInstances();
|
|
let j = 0;
|
|
for (let i = 0, len = instances.length; i < len; ++i) {
|
|
const inst = instances[i];
|
|
instances[j] = inst;
|
|
if (inst.GetUID() === uid)
|
|
sol._PushElseInstance(inst);
|
|
else
|
|
++j
|
|
}
|
|
C3.truncateArray(instances, j);
|
|
objectClass.ApplySolToContainer();
|
|
return !!instances.length
|
|
}
|
|
}
|
|
function Destroy() {
|
|
this._runtime.DestroyInstance(this._inst)
|
|
}
|
|
function OnCreated() {
|
|
return true
|
|
}
|
|
function OnDestroyed() {
|
|
return true
|
|
}
|
|
function SetInstanceVar(iv, value) {
|
|
this.GetInstance().SetInstanceVariableValue(iv, value)
|
|
}
|
|
function AddInstanceVar(iv, value) {
|
|
const instance = this.GetInstance();
|
|
const lastValue = instance.GetInstanceVariableValue(iv);
|
|
if (typeof lastValue === "number" && typeof value !== "number")
|
|
value = parseFloat(value);
|
|
else if (typeof lastValue === "string" && typeof value !== "string")
|
|
value = value.toString();
|
|
instance.SetInstanceVariableValue(iv, lastValue + value)
|
|
}
|
|
function SubInstanceVar(iv, value) {
|
|
const instance = this.GetInstance();
|
|
const lastValue = instance.GetInstanceVariableValue(iv);
|
|
if (typeof lastValue !== "number")
|
|
return;
|
|
if (typeof value !== "number")
|
|
value = parseFloat(value);
|
|
instance.SetInstanceVariableValue(iv, lastValue - value)
|
|
}
|
|
function SetBoolInstanceVar(iv, value) {
|
|
this.GetInstance().SetInstanceVariableValue(iv, value ? 1 : 0)
|
|
}
|
|
function ToggleBoolInstanceVar(iv) {
|
|
const instance = this.GetInstance();
|
|
instance.SetInstanceVariableValue(iv, instance.GetInstanceVariableValue(iv) === 0 ? 1 : 0)
|
|
}
|
|
function LoadFromJsonString(str) {
|
|
let o;
|
|
try {
|
|
o = JSON.parse(str)
|
|
} catch (err) {
|
|
console.error("Failed to load from JSON string: ", err);
|
|
return
|
|
}
|
|
this.GetInstance().LoadFromJson(o, "state")
|
|
}
|
|
function AsJSON() {
|
|
return JSON.stringify(this.GetInstance().SaveToJson("state"))
|
|
}
|
|
function ObjectTypeName() {
|
|
return this.GetInstance().GetObjectClass().GetName()
|
|
}
|
|
function Count() {
|
|
const expObjectClass = this._runtime.GetCurrentEventStackFrame().GetExpressionObjectClass();
|
|
let count = expObjectClass.GetInstanceCount();
|
|
const instancesPendingCreate = this._runtime._GetInstancesPendingCreate();
|
|
for (const inst of instancesPendingCreate)
|
|
if (expObjectClass.IsFamily()) {
|
|
if (inst.GetObjectClass().BelongsToFamily(expObjectClass))
|
|
++count
|
|
} else if (inst.GetObjectClass() === expObjectClass)
|
|
++count;
|
|
return count
|
|
}
|
|
function PickedCount() {
|
|
return this._runtime.GetCurrentEventStackFrame().GetExpressionObjectClass().GetCurrentSol().GetInstances().length
|
|
}
|
|
function GetIID() {
|
|
return this._inst.GetIID()
|
|
}
|
|
function GetUID() {
|
|
return this._inst.GetUID()
|
|
}
|
|
C3.AddCommonACEs = function AddCommonACEs(pluginData, pluginCtor) {
|
|
const isSingleGlobal = pluginData[1];
|
|
const hasPositionACEs = pluginData[3];
|
|
const hasSizeACEs = pluginData[4];
|
|
const hasAngleACEs = pluginData[5];
|
|
const hasAppearanceACEs = pluginData[6];
|
|
const hasZOrderACEs = pluginData[7];
|
|
const hasEffectsACEs = pluginData[8];
|
|
const hasElementACEs = pluginData[10];
|
|
const hasElementFocusACEs = pluginData[11];
|
|
const hasElementEnabledACEs = pluginData[12];
|
|
const hasSceneGraphACEs = pluginData[13];
|
|
const hasMeshACEs = pluginData[14];
|
|
const Cnds = pluginCtor.Cnds;
|
|
const Acts = pluginCtor.Acts;
|
|
const Exps = pluginCtor.Exps;
|
|
if (hasPositionACEs) {
|
|
Cnds.CompareX = CompareX;
|
|
Cnds.CompareY = CompareY;
|
|
Cnds.IsOnScreen = IsOnScreen;
|
|
Cnds.IsOutsideLayout = IsOutsideLayout;
|
|
Cnds.PickDistance = PickDistance;
|
|
Acts.SetX = SetX;
|
|
Acts.SetY = SetY;
|
|
Acts.SetPos = SetPos;
|
|
Acts.SetPosToObject = SetPosToObject;
|
|
Acts.MoveForward = MoveForward;
|
|
Acts.MoveAtAngle = MoveAtAngle;
|
|
Exps.X = GetX;
|
|
Exps.Y = GetY;
|
|
Exps.dt = GetDt
|
|
}
|
|
if (hasSizeACEs) {
|
|
Cnds.CompareWidth = CompareWidth;
|
|
Cnds.CompareHeight = CompareHeight;
|
|
Acts.SetWidth = SetWidth;
|
|
Acts.SetHeight = SetHeight;
|
|
Acts.SetSize = SetSize;
|
|
Exps.Width = GetWidth;
|
|
Exps.Height = GetHeight;
|
|
Exps.BBoxLeft = GetBboxLeft;
|
|
Exps.BBoxTop = GetBboxTop;
|
|
Exps.BBoxRight = GetBboxRight;
|
|
Exps.BBoxBottom = GetBboxBottom
|
|
}
|
|
if (hasAngleACEs) {
|
|
Cnds.AngleWithin = IsAngleWithin;
|
|
Cnds.IsClockwiseFrom = IsAngleClockwiseFrom;
|
|
Cnds.IsBetweenAngles = IsBetweenAngles;
|
|
Acts.SetAngle = SetAngle;
|
|
Acts.RotateClockwise = RotateClockwise;
|
|
Acts.RotateCounterclockwise = RotateCounterclockwise;
|
|
Acts.RotateTowardAngle = RotateTowardAngle;
|
|
Acts.RotateTowardPosition = RotateTowardPosition;
|
|
Acts.SetTowardPosition = SetTowardPosition;
|
|
Exps.Angle = GetAngle
|
|
}
|
|
if (hasAppearanceACEs) {
|
|
Cnds.IsVisible = IsVisible;
|
|
Cnds.CompareOpacity = CompareOpacity;
|
|
Acts.SetVisible = SetVisible;
|
|
Acts.SetOpacity = SetOpacity;
|
|
Acts.SetDefaultColor = SetDefaultColor;
|
|
Exps.Opacity = GetOpacity;
|
|
Exps.ColorValue = GetColor
|
|
}
|
|
if (hasZOrderACEs) {
|
|
Cnds.IsOnLayer = IsOnLayer;
|
|
Cnds.PickTopBottom = PickTopBottom;
|
|
Cnds.CompareZElevation = CompareZElevation;
|
|
Acts.MoveToTop = MoveToTop;
|
|
Acts.MoveToBottom = MoveToBottom;
|
|
Acts.MoveToLayer = MoveToLayer;
|
|
Acts.ZMoveToObject = ZMoveToObject;
|
|
Acts.SetZElevation = SetZElevation;
|
|
Exps.LayerNumber = LayerNumber;
|
|
Exps.LayerName = LayerName;
|
|
Exps.ZIndex = ZIndex;
|
|
Exps.ZElevation = ZElevation;
|
|
Exps.TotalZElevation = TotalZElevation
|
|
}
|
|
if (hasEffectsACEs) {
|
|
Acts.SetEffectEnabled = SetEffectEnabled;
|
|
Acts.SetEffectParam = SetEffectParam
|
|
}
|
|
if (hasSceneGraphACEs) {
|
|
Cnds.HasParent = HasParent;
|
|
Cnds.HasChildren = HasChildren;
|
|
Cnds.PickParent = PickParent;
|
|
Cnds.PickChildren = PickChildren;
|
|
Cnds.PickNthChild = PickNthChild;
|
|
Cnds.CompareChildCount = CompareChildCount;
|
|
Acts.AddChild = AddChild;
|
|
Acts.RemoveChild = RemoveChild;
|
|
Acts.RemoveFromParent = RemoveFromParent;
|
|
Exps.ChildCount = ChildCount
|
|
}
|
|
if (hasMeshACEs) {
|
|
Acts.SetMeshSize = SetMeshSize;
|
|
Acts.SetMeshPoint = SetMeshPoint;
|
|
Exps.MeshColumns = MeshColumns;
|
|
Exps.MeshRows = MeshRows
|
|
}
|
|
if (hasElementACEs) {
|
|
Cnds.IsVisible = IsVisible;
|
|
Acts.SetVisible = SetElementVisible;
|
|
Acts.SetCSSStyle = SetElementCSSStyle;
|
|
Acts.SetElemAttribute = SetElementAttribute;
|
|
Acts.RemoveElemAttribute = RemoveElementAttribute
|
|
}
|
|
if (hasElementFocusACEs) {
|
|
Cnds.IsFocused = IsElementFocused;
|
|
Acts.SetFocus = SetElementFocus;
|
|
Acts.SetBlur = SetElementBlur
|
|
}
|
|
if (hasElementEnabledACEs) {
|
|
Cnds.IsEnabled = IsElementEnabled;
|
|
Acts.SetEnabled = SetElementEnabled
|
|
}
|
|
if (!isSingleGlobal) {
|
|
Cnds.CompareInstanceVar = CompareInstanceVar;
|
|
Cnds.IsBoolInstanceVarSet = IsBoolInstanceVarSet;
|
|
Cnds.PickInstVarHiLow = PickInstVarHiLow;
|
|
Cnds.PickByUID = PickByUID;
|
|
Acts.SetInstanceVar = SetInstanceVar;
|
|
Acts.AddInstanceVar = AddInstanceVar;
|
|
Acts.SubInstanceVar = SubInstanceVar;
|
|
Acts.SetBoolInstanceVar = SetBoolInstanceVar;
|
|
Acts.ToggleBoolInstanceVar = ToggleBoolInstanceVar;
|
|
Cnds.OnCreated = OnCreated;
|
|
Cnds.OnDestroyed = OnDestroyed;
|
|
Acts.Destroy = Destroy;
|
|
if (!Acts.LoadFromJsonString)
|
|
Acts.LoadFromJsonString = LoadFromJsonString;
|
|
if (!Exps.AsJSON)
|
|
Exps.AsJSON = AsJSON;
|
|
Exps.Count = Count;
|
|
Exps.PickedCount = PickedCount;
|
|
Exps.IID = GetIID;
|
|
Exps.UID = GetUID;
|
|
Exps.ObjectTypeName = ObjectTypeName
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.ScheduledWait = class ScheduledWait extends C3.DefendedBase {
|
|
constructor(eventSheetManager) {
|
|
super();
|
|
this._eventSheetManager = eventSheetManager;
|
|
this._type = "";
|
|
this._time = -1;
|
|
this._signalTag = "";
|
|
this._isSignalled = false;
|
|
this._event = null;
|
|
this._actIndex = 0;
|
|
this._solModifiers = [];
|
|
this._sols = new Map;
|
|
this._callingFunctionBlock = null;
|
|
this._asyncId = -1;
|
|
this._functionParameters = null;
|
|
this._shouldRelease = false
|
|
}
|
|
Release() {
|
|
this._type = "";
|
|
this._time = -1;
|
|
this._signalTag = "";
|
|
this._event = null;
|
|
this._callingFunctionBlock = null;
|
|
this._functionParameters = null;
|
|
this._asyncId = -1;
|
|
C3.clearArray(this._solModifiers);
|
|
for (const s of this._sols.values())
|
|
s.Release();
|
|
this._sols.clear()
|
|
}
|
|
_Init() {
|
|
const eventSheetManager = this._eventSheetManager;
|
|
const allObjectClasses = eventSheetManager.GetRuntime().GetAllObjectClasses();
|
|
const frame = eventSheetManager.GetCurrentEventStackFrame();
|
|
this._event = frame.GetCurrentEvent();
|
|
this._actIndex = frame.GetActionIndex() + 1;
|
|
const functionBlock = eventSheetManager.FindFirstFunctionBlockParent(this._event);
|
|
if (functionBlock) {
|
|
this._callingFunctionBlock = functionBlock;
|
|
this._functionParameters = functionBlock.CaptureFunctionParameters();
|
|
if (functionBlock.IsAsync())
|
|
this._asyncId = functionBlock.PauseCurrentAsyncFunction()
|
|
}
|
|
for (const objectClass of allObjectClasses) {
|
|
const sol = objectClass.GetCurrentSol();
|
|
if (sol.IsSelectAll() && !this._event.HasSolModifier(objectClass))
|
|
continue;
|
|
this._solModifiers.push(objectClass);
|
|
this._sols.set(objectClass, C3.New(C3.SolState, sol))
|
|
}
|
|
}
|
|
InitTimer(seconds) {
|
|
this._type = "timer";
|
|
this._Init();
|
|
this._time = this._eventSheetManager.GetRuntime().GetGameTime() + seconds
|
|
}
|
|
InitSignal(tag) {
|
|
this._type = "signal";
|
|
this._Init();
|
|
this._signalTag = tag.toLowerCase()
|
|
}
|
|
InitPromise(p) {
|
|
this._type = "promise";
|
|
this._Init();
|
|
p.then(()=>this.SetSignalled()).catch(err=>{
|
|
console.warn("[C3 runtime] Promise rejected in 'Wait for previous actions to complete': ", err);
|
|
this.SetSignalled()
|
|
}
|
|
)
|
|
}
|
|
IsTimer() {
|
|
return this._type === "timer"
|
|
}
|
|
IsSignal() {
|
|
return this._type === "signal"
|
|
}
|
|
IsPromise() {
|
|
return this._type === "promise"
|
|
}
|
|
GetSignalTag() {
|
|
return this._signalTag
|
|
}
|
|
IsSignalled() {
|
|
return this._isSignalled
|
|
}
|
|
SetSignalled() {
|
|
this._isSignalled = true
|
|
}
|
|
_ShouldRun() {
|
|
if (this.IsTimer())
|
|
return this._time <= this._eventSheetManager.GetRuntime().GetGameTime();
|
|
else
|
|
return this.IsSignalled()
|
|
}
|
|
_RestoreState(frame) {
|
|
frame._Restore(this._event, this._actIndex);
|
|
for (const [objectClass,solState] of this._sols.entries()) {
|
|
const sol = objectClass.GetCurrentSol();
|
|
solState._Restore(sol)
|
|
}
|
|
const callingFunctionBlock = this._callingFunctionBlock;
|
|
if (callingFunctionBlock) {
|
|
callingFunctionBlock.SetFunctionParameters(this._functionParameters);
|
|
if (callingFunctionBlock.IsAsync())
|
|
callingFunctionBlock.ResumeAsyncFunction(this._asyncId)
|
|
}
|
|
}
|
|
_Run(frame) {
|
|
this._RestoreState(frame);
|
|
this._event._ResumeActionsAndSubEvents(frame);
|
|
if (this._callingFunctionBlock && this._callingFunctionBlock.IsAsync())
|
|
this._callingFunctionBlock.MaybeFinishAsyncFunctionCall(this._asyncId);
|
|
this._eventSheetManager.ClearSol(this._solModifiers);
|
|
this._shouldRelease = true
|
|
}
|
|
async _DebugRun(frame) {
|
|
this._RestoreState(frame);
|
|
for (const breakEventObject of this._event._DebugResumeActionsAndSubEvents(frame))
|
|
await this._eventSheetManager.GetRuntime().DebugBreak(breakEventObject);
|
|
if (this._callingFunctionBlock && this._callingFunctionBlock.IsAsync())
|
|
this._callingFunctionBlock.MaybeFinishAsyncFunctionCall(this._asyncId);
|
|
this._eventSheetManager.ClearSol(this._solModifiers);
|
|
this._shouldRelease = true
|
|
}
|
|
ShouldRelease() {
|
|
return this._shouldRelease
|
|
}
|
|
RemoveInstances(s) {
|
|
for (const solState of this._sols.values())
|
|
solState.RemoveInstances(s)
|
|
}
|
|
_SaveToJson() {
|
|
const sols = {};
|
|
const o = {
|
|
"t": this._time,
|
|
"st": this._signalTag,
|
|
"s": this._isSignalled,
|
|
"ev": this._event.GetSID(),
|
|
"sm": this._solModifiers.map(oc=>oc.GetSID()),
|
|
"sols": sols
|
|
};
|
|
if (this._event._HasActionIndex(this._actIndex))
|
|
o["act"] = this._event.GetActionAt(this._actIndex).GetSID();
|
|
for (const [objectClass,solState] of this._sols)
|
|
sols[objectClass.GetSID().toString()] = solState._SaveToJson();
|
|
return o
|
|
}
|
|
static _CreateFromJson(eventSheetManager, o) {
|
|
const runtime = eventSheetManager.GetRuntime();
|
|
const event = eventSheetManager.GetEventBlockBySID(o["ev"]);
|
|
if (!event)
|
|
return null;
|
|
let actIndex = 0;
|
|
if (o.hasOwnProperty("act")) {
|
|
const act = eventSheetManager.GetActionBySID(o["act"]);
|
|
if (!act)
|
|
return null;
|
|
actIndex = act.GetIndex()
|
|
}
|
|
const sw = C3.New(C3.ScheduledWait, eventSheetManager);
|
|
sw._time = o["t"];
|
|
sw._type = sw._time === -1 ? "signal" : "timer";
|
|
sw._signalTag = o["st"];
|
|
sw._isSignalled = o["s"];
|
|
sw._event = event;
|
|
sw._actIndex = actIndex;
|
|
for (const sid of o["sm"]) {
|
|
const objectClass = runtime.GetObjectClassBySID(sid);
|
|
if (objectClass)
|
|
sw._solModifiers.push(objectClass)
|
|
}
|
|
for (const [sidStr,solData] of Object.entries(o["sols"])) {
|
|
const sid = parseInt(sidStr, 10);
|
|
const objectClass = runtime.GetObjectClassBySID(sid);
|
|
if (!objectClass)
|
|
continue;
|
|
const solState = C3.New(C3.SolState, null);
|
|
solState._LoadFromJson(eventSheetManager, solData);
|
|
sw._sols.set(objectClass, solState)
|
|
}
|
|
return sw
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SolState = class SolState extends C3.DefendedBase {
|
|
constructor(sol) {
|
|
super();
|
|
this._objectClass = null;
|
|
this._isSelectAll = true;
|
|
this._instances = [];
|
|
if (sol) {
|
|
this._objectClass = sol.GetObjectClass();
|
|
this._isSelectAll = sol.IsSelectAll();
|
|
C3.shallowAssignArray(this._instances, sol._GetOwnInstances())
|
|
}
|
|
}
|
|
Release() {
|
|
this._objectClass = null;
|
|
C3.clearArray(this._instances)
|
|
}
|
|
_Restore(sol) {
|
|
sol._SetSelectAll(this._isSelectAll);
|
|
C3.shallowAssignArray(sol._GetOwnInstances(), this._instances)
|
|
}
|
|
RemoveInstances(s) {
|
|
C3.arrayRemoveAllInSet(this._instances, s)
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"sa": this._isSelectAll,
|
|
"insts": this._instances.map(inst=>inst.GetUID())
|
|
}
|
|
}
|
|
_LoadFromJson(eventSheetManager, o) {
|
|
const runtime = eventSheetManager.GetRuntime();
|
|
this._isSelectAll = !!o["sa"];
|
|
C3.clearArray(this._instances);
|
|
for (const uid of o["insts"]) {
|
|
const inst = runtime.GetInstanceByUID(uid);
|
|
if (inst)
|
|
this._instances.push(inst)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function GetNextParamMap(paramMap, param) {
|
|
let nextParamMap = paramMap.get(param);
|
|
if (!nextParamMap) {
|
|
nextParamMap = new Map;
|
|
paramMap.set(param, nextParamMap)
|
|
}
|
|
return nextParamMap
|
|
}
|
|
C3.SDKPluginBase = class SDKPluginBase extends C3.DefendedBase {
|
|
constructor(opts) {
|
|
super();
|
|
this._runtime = opts.runtime;
|
|
this._isSingleGlobal = !!opts.isSingleGlobal;
|
|
this._isWorldType = !!opts.isWorld;
|
|
this._isRotatable = !!opts.isRotatable;
|
|
this._mustPredraw = !!opts.mustPredraw;
|
|
this._hasEffects = !!opts.hasEffects;
|
|
this._supportsSceneGraph = !!opts.supportsSceneGraph;
|
|
this._supportsMesh = !!opts.supportsMesh;
|
|
this._singleGlobalObjectClass = null;
|
|
this._boundACEMethodCache = new Map;
|
|
this._boundACEMethodCache_1param = new Map;
|
|
this._boundACEMethodCache_2params = new Map;
|
|
this._boundACEMethodCache_3params = new Map
|
|
}
|
|
Release() {
|
|
this._runtime = null
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
OnCreate() {}
|
|
IsSingleGlobal() {
|
|
return this._isSingleGlobal
|
|
}
|
|
IsWorldType() {
|
|
return this._isWorldType
|
|
}
|
|
IsRotatable() {
|
|
return this._isRotatable
|
|
}
|
|
MustPreDraw() {
|
|
return this._mustPredraw
|
|
}
|
|
HasEffects() {
|
|
return this._hasEffects
|
|
}
|
|
SupportsSceneGraph() {
|
|
return this._supportsSceneGraph
|
|
}
|
|
SupportsMesh() {
|
|
return this._supportsMesh
|
|
}
|
|
_GetBoundACEMethod(func, bindThis) {
|
|
if (!bindThis)
|
|
throw new Error("missing 'this' binding");
|
|
let ret = this._boundACEMethodCache.get(func);
|
|
if (ret)
|
|
return ret;
|
|
ret = func.bind(bindThis);
|
|
this._boundACEMethodCache.set(func, ret);
|
|
return ret
|
|
}
|
|
_GetBoundACEMethod_1param(func, bindThis, param0) {
|
|
if (!bindThis)
|
|
throw new Error("missing 'this' binding");
|
|
const param0map = GetNextParamMap(this._boundACEMethodCache_1param, func);
|
|
let ret = param0map.get(param0);
|
|
if (ret)
|
|
return ret;
|
|
ret = func.bind(bindThis, param0);
|
|
param0map.set(param0, ret);
|
|
return ret
|
|
}
|
|
_GetBoundACEMethod_2params(func, bindThis, param0, param1) {
|
|
if (!bindThis)
|
|
throw new Error("missing 'this' binding");
|
|
const param0map = GetNextParamMap(this._boundACEMethodCache_2params, func);
|
|
const param1map = GetNextParamMap(param0map, param0);
|
|
let ret = param1map.get(param1);
|
|
if (ret)
|
|
return ret;
|
|
ret = func.bind(bindThis, param0, param1);
|
|
param1map.set(param1, ret);
|
|
return ret
|
|
}
|
|
_GetBoundACEMethod_3params(func, bindThis, param0, param1, param2) {
|
|
if (!bindThis)
|
|
throw new Error("missing 'this' binding");
|
|
const param0map = GetNextParamMap(this._boundACEMethodCache_3params, func);
|
|
const param1map = GetNextParamMap(param0map, param0);
|
|
const param2map = GetNextParamMap(param1map, param1);
|
|
let ret = param2map.get(param2);
|
|
if (ret)
|
|
return ret;
|
|
ret = func.bind(bindThis, param0, param1, param2);
|
|
param2map.set(param2, ret);
|
|
return ret
|
|
}
|
|
_SetSingleGlobalObjectClass(objectClass) {
|
|
if (!this.IsSingleGlobal())
|
|
throw new Error("must be single-global plugin");
|
|
this._singleGlobalObjectClass = objectClass
|
|
}
|
|
GetSingleGlobalObjectClass() {
|
|
if (!this.IsSingleGlobal())
|
|
throw new Error("must be single-global plugin");
|
|
return this._singleGlobalObjectClass
|
|
}
|
|
GetSingleGlobalInstance() {
|
|
if (!this.IsSingleGlobal())
|
|
throw new Error("must be single-global plugin");
|
|
return this._singleGlobalObjectClass.GetSingleGlobalInstance()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SDKDOMPluginBase = class SDKDOMPluginBase extends C3.SDKPluginBase {
|
|
constructor(opts, DOM_COMPONENT_ID) {
|
|
super(opts);
|
|
this._domComponentId = DOM_COMPONENT_ID;
|
|
this._nextElementId = 0;
|
|
this._instMap = new Map;
|
|
this.AddElementMessageHandler("elem-focused", sdkInst=>sdkInst._OnElemFocused());
|
|
this.AddElementMessageHandler("elem-blurred", sdkInst=>{
|
|
if (sdkInst)
|
|
sdkInst._OnElemBlurred()
|
|
}
|
|
)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
_AddElement(sdkInst) {
|
|
const elementId = this._nextElementId++;
|
|
this._instMap.set(elementId, sdkInst);
|
|
return elementId
|
|
}
|
|
_RemoveElement(elementId) {
|
|
this._instMap.delete(elementId)
|
|
}
|
|
AddElementMessageHandler(handler, func) {
|
|
this._runtime.AddDOMComponentMessageHandler(this._domComponentId, handler, e=>{
|
|
const sdkInst = this._instMap.get(e["elementId"]);
|
|
func(sdkInst, e)
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SDKTypeBase = class SDKTypeBase extends C3.DefendedBase {
|
|
constructor(objectClass) {
|
|
super();
|
|
this._objectClass = objectClass;
|
|
this._runtime = objectClass.GetRuntime();
|
|
this._plugin = objectClass.GetPlugin()
|
|
}
|
|
Release() {
|
|
this._objectClass = null;
|
|
this._runtime = null;
|
|
this._plugin = null
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectClass
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetPlugin() {
|
|
return this._plugin
|
|
}
|
|
GetImageInfo() {
|
|
return this._objectClass.GetImageInfo()
|
|
}
|
|
FinishCondition(f) {}
|
|
LoadTextures(renderer) {}
|
|
ReleaseTextures() {}
|
|
OnDynamicTextureLoadComplete() {}
|
|
PreloadTexturesWithInstances(renderer) {}
|
|
LoadTilemapData() {}
|
|
GetScriptInterfaceClass() {
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SDKInstanceBase = class SDKInstanceBase extends C3.DefendedBase {
|
|
constructor(inst, domComponentId) {
|
|
super();
|
|
this._inst = inst;
|
|
this._domComponentId = domComponentId;
|
|
this._runtime = inst.GetRuntime();
|
|
this._objectClass = this._inst.GetObjectClass();
|
|
this._sdkType = this._objectClass.GetSdkType();
|
|
this._tickFunc = null;
|
|
this._tick2Func = null;
|
|
this._isTicking = false;
|
|
this._isTicking2 = false;
|
|
this._disposables = null;
|
|
this._wasReleased = false
|
|
}
|
|
Release() {
|
|
this._wasReleased = true;
|
|
this._StopTicking();
|
|
this._StopTicking2();
|
|
this._tickFunc = null;
|
|
this._tick2Func = null;
|
|
if (this._disposables) {
|
|
this._disposables.Release();
|
|
this._disposables = null
|
|
}
|
|
this._inst = null;
|
|
this._runtime = null;
|
|
this._objectClass = null;
|
|
this._sdkType = null
|
|
}
|
|
WasReleased() {
|
|
return this._wasReleased
|
|
}
|
|
GetInstance() {
|
|
return this._inst
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectClass
|
|
}
|
|
GetPlugin() {
|
|
return this._sdkType.GetPlugin()
|
|
}
|
|
GetSdkType() {
|
|
return this._sdkType
|
|
}
|
|
GetScriptInterface() {
|
|
return this._inst.GetInterfaceClass()
|
|
}
|
|
Trigger(method) {
|
|
return this._runtime.Trigger(method, this._inst, null)
|
|
}
|
|
DebugTrigger(method) {
|
|
return this._runtime.DebugTrigger(method, this._inst, null)
|
|
}
|
|
TriggerAsync(method) {
|
|
return this._runtime.TriggerAsync(method, this._inst, null)
|
|
}
|
|
FastTrigger(method, value) {
|
|
return this._runtime.FastTrigger(method, this._inst, value)
|
|
}
|
|
DebugFastTrigger(method, value) {
|
|
return this._runtime.DebugFastTrigger(method, this._inst, value)
|
|
}
|
|
ScheduleTriggers(f) {
|
|
return this._runtime.ScheduleTriggers(f)
|
|
}
|
|
AddDOMMessageHandler(handler, func) {
|
|
this._runtime.AddDOMComponentMessageHandler(this._domComponentId, handler, func)
|
|
}
|
|
AddDOMMessageHandlers(list) {
|
|
for (const [handler,func] of list)
|
|
this.AddDOMMessageHandler(handler, func)
|
|
}
|
|
PostToDOM(handler, data) {
|
|
this._runtime.PostComponentMessageToDOM(this._domComponentId, handler, data)
|
|
}
|
|
PostToDOMAsync(handler, data) {
|
|
return this._runtime.PostComponentMessageToDOMAsync(this._domComponentId, handler, data)
|
|
}
|
|
_PostToDOMMaybeSync(handler, data) {
|
|
if (this._runtime.IsInWorker())
|
|
this.PostToDOM(handler, data);
|
|
else
|
|
return window["c3_runtimeInterface"]["_OnMessageFromRuntime"]({
|
|
"type": "event",
|
|
"component": this._domComponentId,
|
|
"handler": handler,
|
|
"data": data,
|
|
"responseId": null
|
|
})
|
|
}
|
|
GetCurrentImageInfo() {
|
|
return null
|
|
}
|
|
GetCurrentSurfaceSize() {
|
|
const imageInfo = this.GetCurrentImageInfo();
|
|
if (imageInfo) {
|
|
const texture = imageInfo.GetTexture();
|
|
if (texture)
|
|
return [texture.GetWidth(), texture.GetHeight()]
|
|
}
|
|
return [100, 100]
|
|
}
|
|
GetCurrentTexRect() {
|
|
const imageInfo = this.GetCurrentImageInfo();
|
|
return imageInfo ? imageInfo.GetTexRect() : null
|
|
}
|
|
GetImagePoint(nameOrIndex) {
|
|
const wi = this._inst.GetWorldInfo();
|
|
return [wi.GetX(), wi.GetY()]
|
|
}
|
|
Tick() {}
|
|
Tick2() {}
|
|
_StartTicking() {
|
|
if (this._isTicking)
|
|
return;
|
|
if (!this._tickFunc)
|
|
this._tickFunc = ()=>this.Tick();
|
|
this._runtime.Dispatcher().addEventListener("tick", this._tickFunc);
|
|
this._isTicking = true
|
|
}
|
|
_StopTicking() {
|
|
if (!this._isTicking)
|
|
return;
|
|
this._runtime.Dispatcher().removeEventListener("tick", this._tickFunc);
|
|
this._isTicking = false
|
|
}
|
|
IsTicking() {
|
|
return this._isTicking
|
|
}
|
|
_StartTicking2() {
|
|
if (this._isTicking2)
|
|
return;
|
|
if (!this._tick2Func)
|
|
this._tick2Func = ()=>this.Tick2();
|
|
this._runtime.Dispatcher().addEventListener("tick2", this._tick2Func);
|
|
this._isTicking2 = true
|
|
}
|
|
_StopTicking2() {
|
|
if (!this._isTicking2)
|
|
return;
|
|
this._runtime.Dispatcher().removeEventListener("tick2", this._tick2Func);
|
|
this._isTicking2 = false
|
|
}
|
|
IsTicking2() {
|
|
return this._isTicking2
|
|
}
|
|
GetDebuggerProperties() {
|
|
return []
|
|
}
|
|
SaveToJson() {
|
|
return null
|
|
}
|
|
LoadFromJson(o) {}
|
|
LoadTilemapData(data, mapWidth, mapHeight) {}
|
|
TestPointOverlapTile(x, y) {}
|
|
GetPropertyValueByIndex(index) {}
|
|
SetPropertyValueByIndex(index, value) {}
|
|
OffsetPropertyValueByIndex(index, offset) {
|
|
if (offset === 0)
|
|
return;
|
|
const value = this.GetPropertyValueByIndex(index);
|
|
if (typeof value !== "number")
|
|
throw new Error("expected number");
|
|
this.SetPropertyValueByIndex(index, value + offset)
|
|
}
|
|
SetPropertyColorOffsetValueByIndex(offset, r, g, b) {}
|
|
CallAction(actMethod, ...args) {
|
|
actMethod.call(this, ...args)
|
|
}
|
|
CallExpression(expMethod, ...args) {
|
|
return expMethod.call(this, ...args)
|
|
}
|
|
GetScriptInterfaceClass() {
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SDKWorldInstanceBase = class SDKWorldInstanceBase extends C3.SDKInstanceBase {
|
|
constructor(inst, domComponentId) {
|
|
super(inst, domComponentId);
|
|
this._worldInfo = inst.GetWorldInfo();
|
|
this._webglcontextlost_handler = null;
|
|
this._webglcontextrestored_handler = null
|
|
}
|
|
Release() {
|
|
if (this._webglcontextlost_handler) {
|
|
const dispatcher = this._runtime.Dispatcher();
|
|
dispatcher.removeEventListener("webglcontextlost", this._webglcontextlost_handler);
|
|
dispatcher.removeEventListener("webglcontextrestored", this._webglcontextrestored_handler);
|
|
this._webglcontextlost_handler = null;
|
|
this._webglcontextrestored_handler = null
|
|
}
|
|
this._worldInfo = null;
|
|
super.Release()
|
|
}
|
|
HandleWebGLContextLoss() {
|
|
if (this._webglcontextlost_handler)
|
|
return;
|
|
this._webglcontextlost_handler = ()=>this.OnWebGLContextLost();
|
|
this._webglcontextrestored_handler = ()=>this.OnWebGLContextRestored();
|
|
const dispatcher = this._runtime.Dispatcher();
|
|
dispatcher.addEventListener("webglcontextlost", this._webglcontextlost_handler);
|
|
dispatcher.addEventListener("webglcontextrestored", this._webglcontextrestored_handler)
|
|
}
|
|
OnWebGLContextLost() {}
|
|
OnWebGLContextRestored() {}
|
|
GetWorldInfo() {
|
|
return this._worldInfo
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tempRect = C3.New(C3.Rect);
|
|
C3.SDKDOMInstanceBase = class SDKDOMInstanceBase extends C3.SDKWorldInstanceBase {
|
|
constructor(inst, domComponentId) {
|
|
super(inst, domComponentId);
|
|
this._elementId = this.GetPlugin()._AddElement(this);
|
|
this._isElementShowing = true;
|
|
this._elemHasFocus = false;
|
|
this._autoFontSize = false;
|
|
this._lastRect = C3.New(C3.Rect, 0, 0, -1, -1);
|
|
const canvasManager = this._runtime.GetCanvasManager();
|
|
this._lastWindowWidth = canvasManager.GetLastWidth();
|
|
this._lastWindowHeight = canvasManager.GetLastHeight();
|
|
this._isPendingUpdateState = false;
|
|
this._StartTicking()
|
|
}
|
|
Release() {
|
|
this.GetPlugin()._RemoveElement(this._elementId);
|
|
this.PostToDOMElement("destroy");
|
|
this._elementId = -1;
|
|
super.Release()
|
|
}
|
|
_GetElementInDOMMode() {
|
|
if (this._runtime.IsInWorker())
|
|
throw new Error("not valid in worker mode");
|
|
return this._PostToDOMElementMaybeSync("get-element")
|
|
}
|
|
PostToDOMElement(handler, data) {
|
|
if (!data)
|
|
data = {};
|
|
data["elementId"] = this._elementId;
|
|
this.PostToDOM(handler, data)
|
|
}
|
|
_PostToDOMElementMaybeSync(handler, data) {
|
|
if (!data)
|
|
data = {};
|
|
data["elementId"] = this._elementId;
|
|
return this._PostToDOMMaybeSync(handler, data)
|
|
}
|
|
PostToDOMElementAsync(handler, data) {
|
|
if (!data)
|
|
data = {};
|
|
data["elementId"] = this._elementId;
|
|
return this.PostToDOMAsync(handler, data)
|
|
}
|
|
CreateElement(data) {
|
|
if (!data)
|
|
data = {};
|
|
const isVisible = this.GetWorldInfo().IsVisible();
|
|
data["elementId"] = this._elementId;
|
|
data["isVisible"] = isVisible;
|
|
Object.assign(data, this.GetElementState());
|
|
this._isElementShowing = !!data["isVisible"];
|
|
this._PostToDOMMaybeSync("create", data);
|
|
this._UpdatePosition(true)
|
|
}
|
|
SetElementVisible(v) {
|
|
v = !!v;
|
|
if (this._isElementShowing === v)
|
|
return;
|
|
this._isElementShowing = v;
|
|
this.PostToDOMElement("set-visible", {
|
|
"isVisible": v
|
|
})
|
|
}
|
|
Tick() {
|
|
this._UpdatePosition(false)
|
|
}
|
|
_ShouldPreserveElement() {
|
|
const fullscreenMode = this._runtime.GetCanvasManager().GetFullscreenMode();
|
|
return C3.Platform.OS === "Android" && (fullscreenMode === "scale-inner" || fullscreenMode === "scale-outer" || fullscreenMode === "crop")
|
|
}
|
|
_UpdatePosition(first) {
|
|
const wi = this.GetWorldInfo();
|
|
const layer = wi.GetLayer();
|
|
const x = wi.GetX();
|
|
const y = wi.GetY();
|
|
let[cleft,ctop] = layer.LayerToCanvasCss(x, y);
|
|
let[cright,cbottom] = layer.LayerToCanvasCss(x + wi.GetWidth(), y + wi.GetHeight());
|
|
const canvasManager = this._runtime.GetCanvasManager();
|
|
const rightEdge = canvasManager.GetCssWidth();
|
|
const bottomEdge = canvasManager.GetCssHeight();
|
|
if (!wi.IsVisible() || !layer.IsVisible()) {
|
|
this.SetElementVisible(false);
|
|
return
|
|
}
|
|
if (!this._ShouldPreserveElement()) {
|
|
if (cright <= 0 || cbottom <= 0 || cleft >= rightEdge || ctop >= bottomEdge) {
|
|
this.SetElementVisible(false);
|
|
return
|
|
}
|
|
if (cleft < 1)
|
|
cleft = 1;
|
|
if (ctop < 1)
|
|
ctop = 1;
|
|
if (cright >= rightEdge)
|
|
cright = rightEdge - 1;
|
|
if (cbottom >= bottomEdge)
|
|
cbottom = bottomEdge - 1
|
|
}
|
|
tempRect.set(cleft, ctop, cright, cbottom);
|
|
const curWinWidth = canvasManager.GetLastWidth();
|
|
const curWinHeight = canvasManager.GetLastHeight();
|
|
if (!first && tempRect.equals(this._lastRect) && this._lastWindowWidth === curWinWidth && this._lastWindowHeight === curWinHeight) {
|
|
this.SetElementVisible(true);
|
|
return
|
|
}
|
|
this._lastRect.copy(tempRect);
|
|
this._lastWindowWidth = curWinWidth;
|
|
this._lastWindowHeight = curWinHeight;
|
|
this.SetElementVisible(true);
|
|
let fontSize = null;
|
|
if (this._autoFontSize)
|
|
fontSize = layer.GetDisplayScale() - .2;
|
|
this.PostToDOMElement("update-position", {
|
|
"left": Math.round(this._lastRect.getLeft()) + canvasManager.GetCanvasClientX(),
|
|
"top": Math.round(this._lastRect.getTop()) + canvasManager.GetCanvasClientY(),
|
|
"width": Math.round(this._lastRect.width()),
|
|
"height": Math.round(this._lastRect.height()),
|
|
"fontSize": fontSize
|
|
})
|
|
}
|
|
FocusElement() {
|
|
this._PostToDOMElementMaybeSync("focus", {
|
|
"focus": true
|
|
})
|
|
}
|
|
BlurElement() {
|
|
this._PostToDOMElementMaybeSync("focus", {
|
|
"focus": false
|
|
})
|
|
}
|
|
_OnElemFocused() {
|
|
this._elemHasFocus = true
|
|
}
|
|
_OnElemBlurred() {
|
|
this._elemHasFocus = false
|
|
}
|
|
IsElementFocused() {
|
|
return this._elemHasFocus
|
|
}
|
|
SetElementCSSStyle(prop, val) {
|
|
this.PostToDOMElement("set-css-style", {
|
|
"prop": C3.CSSToCamelCase(prop),
|
|
"val": val
|
|
})
|
|
}
|
|
SetElementAttribute(attribName, value) {
|
|
this.PostToDOMElement("set-attribute", {
|
|
"name": attribName,
|
|
"val": value
|
|
})
|
|
}
|
|
RemoveElementAttribute(attribName) {
|
|
this.PostToDOMElement("remove-attribute", {
|
|
"name": attribName
|
|
})
|
|
}
|
|
UpdateElementState() {
|
|
if (this._isPendingUpdateState)
|
|
return;
|
|
this._isPendingUpdateState = true;
|
|
Promise.resolve().then(()=>{
|
|
this._isPendingUpdateState = false;
|
|
this.PostToDOMElement("update-state", this.GetElementState())
|
|
}
|
|
)
|
|
}
|
|
GetElementState() {}
|
|
GetElementId() {
|
|
return this._elementId
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const IBehavior = self.IBehavior;
|
|
C3.SDKBehaviorBase = class SDKBehaviorBase extends C3.DefendedBase {
|
|
constructor(opts) {
|
|
super();
|
|
this._runtime = opts.runtime;
|
|
this._myObjectClasses = C3.New(C3.ArraySet);
|
|
this._myInstances = C3.New(C3.ArraySet);
|
|
this._iBehavior = null;
|
|
const CustomScriptClass = opts.scriptInterfaceClass;
|
|
if (CustomScriptClass) {
|
|
this._iBehavior = new CustomScriptClass(this);
|
|
if (!(this._iBehavior instanceof IBehavior))
|
|
throw new TypeError("script interface class must derive from IBehavior");
|
|
} else
|
|
this._iBehavior = new IBehavior(this)
|
|
}
|
|
Release() {
|
|
this._myInstances.Release();
|
|
this._myObjectClasses.Release();
|
|
this._runtime = null
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
OnCreate() {}
|
|
_AddObjectClass(objectClass) {
|
|
this._myObjectClasses.Add(objectClass)
|
|
}
|
|
GetObjectClasses() {
|
|
return this._myObjectClasses.GetArray()
|
|
}
|
|
_AddInstance(inst) {
|
|
this._myInstances.Add(inst)
|
|
}
|
|
_RemoveInstance(inst) {
|
|
this._myInstances.Delete(inst)
|
|
}
|
|
GetInstances() {
|
|
return this._myInstances.GetArray()
|
|
}
|
|
GetIBehavior() {
|
|
return this._iBehavior
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SDKBehaviorTypeBase = class SDKBehaviorTypeBase extends C3.DefendedBase {
|
|
constructor(behaviorType) {
|
|
super();
|
|
this._runtime = behaviorType.GetRuntime();
|
|
this._behaviorType = behaviorType;
|
|
this._objectClass = behaviorType.GetObjectClass();
|
|
this._behavior = behaviorType.GetBehavior();
|
|
this._behavior._AddObjectClass(this._objectClass)
|
|
}
|
|
Release() {
|
|
this._runtime = null;
|
|
this._behaviorType = null;
|
|
this._objectClass = null;
|
|
this._behavior = null
|
|
}
|
|
GetBehaviorType() {
|
|
return this._behaviorType
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectClass
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetBehavior() {
|
|
return this._behavior
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SDKBehaviorInstanceBase = class SDKBehaviorInstanceBase extends C3.DefendedBase {
|
|
constructor(behInst, domComponentId) {
|
|
super();
|
|
this._behInst = behInst;
|
|
this._domComponentId = domComponentId;
|
|
this._inst = behInst.GetObjectInstance();
|
|
this._runtime = behInst.GetRuntime();
|
|
this._behaviorType = behInst.GetBehaviorType();
|
|
this._sdkType = this._behaviorType.GetSdkType();
|
|
this._isTicking = false;
|
|
this._isTicking2 = false;
|
|
this._isPostTicking = false;
|
|
this._disposables = null
|
|
}
|
|
Release() {
|
|
this._StopTicking();
|
|
this._StopTicking2();
|
|
this._StopPostTicking();
|
|
if (this._disposables) {
|
|
this._disposables.Release();
|
|
this._disposables = null
|
|
}
|
|
this._behInst = null;
|
|
this._inst = null;
|
|
this._runtime = null;
|
|
this._behaviorType = null;
|
|
this._sdkType = null
|
|
}
|
|
GetBehavior() {
|
|
return this._behaviorType.GetBehavior()
|
|
}
|
|
GetBehaviorInstance() {
|
|
return this._behInst
|
|
}
|
|
GetObjectInstance() {
|
|
return this._inst
|
|
}
|
|
GetObjectClass() {
|
|
return this._inst.GetObjectClass()
|
|
}
|
|
GetWorldInfo() {
|
|
return this._inst.GetWorldInfo()
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetBehaviorType() {
|
|
return this._behaviorType
|
|
}
|
|
GetSdkType() {
|
|
return this._sdkType
|
|
}
|
|
GetScriptInterface() {
|
|
return this._behInst.GetScriptInterface()
|
|
}
|
|
Trigger(method) {
|
|
return this._runtime.Trigger(method, this._inst, this._behaviorType)
|
|
}
|
|
DebugTrigger(method) {
|
|
return this._runtime.DebugTrigger(method, this._inst, this._behaviorType)
|
|
}
|
|
TriggerAsync(method) {
|
|
return this._runtime.TriggerAsync(method, this._inst, this._behaviorType)
|
|
}
|
|
PostCreate() {}
|
|
Tick() {}
|
|
Tick2() {}
|
|
PostTick() {}
|
|
_StartTicking() {
|
|
if (this._isTicking)
|
|
return;
|
|
this._runtime._AddBehInstToTick(this);
|
|
this._isTicking = true
|
|
}
|
|
_StopTicking() {
|
|
if (!this._isTicking)
|
|
return;
|
|
this._runtime._RemoveBehInstToTick(this);
|
|
this._isTicking = false
|
|
}
|
|
IsTicking() {
|
|
return this._isTicking
|
|
}
|
|
_StartTicking2() {
|
|
if (this._isTicking2)
|
|
return;
|
|
this._runtime._AddBehInstToTick2(this);
|
|
this._isTicking2 = true
|
|
}
|
|
_StopTicking2() {
|
|
if (!this._isTicking2)
|
|
return;
|
|
this._runtime._RemoveBehInstToTick2(this);
|
|
this._isTicking2 = false
|
|
}
|
|
IsTicking2() {
|
|
return this._isTicking2
|
|
}
|
|
_StartPostTicking() {
|
|
if (this._isPostTicking)
|
|
return;
|
|
this._runtime._AddBehInstToPostTick(this);
|
|
this._isPostTicking = true
|
|
}
|
|
_StopPostTicking() {
|
|
if (!this._isPostTicking)
|
|
return;
|
|
this._runtime._RemoveBehInstToPostTick(this);
|
|
this._isPostTicking = false
|
|
}
|
|
IsPostTicking() {
|
|
return this._isPostTicking
|
|
}
|
|
GetDebuggerProperties() {
|
|
return []
|
|
}
|
|
AddDOMMessageHandler(handler, func) {
|
|
this._runtime.AddDOMComponentMessageHandler(this._domComponentId, handler, func)
|
|
}
|
|
OnSpriteFrameChanged(prevFrame, nextFrame) {}
|
|
SaveToJson() {
|
|
return null
|
|
}
|
|
LoadFromJson(o) {}
|
|
GetPropertyValueByIndex(index) {}
|
|
SetPropertyValueByIndex(index, value) {}
|
|
OffsetPropertyValueByIndex(index, offset) {
|
|
if (offset === 0)
|
|
return;
|
|
const value = this.GetPropertyValueByIndex(index);
|
|
if (typeof value !== "number")
|
|
throw new Error("expected number");
|
|
this.SetPropertyValueByIndex(index, value + offset)
|
|
}
|
|
SetPropertyColorOffsetValueByIndex(index, offsetR, offsetG, offsetB) {}
|
|
CallAction(actMethod, ...args) {
|
|
actMethod.call(this, ...args)
|
|
}
|
|
CallExpression(expMethod, ...args) {
|
|
return expMethod.call(this, ...args)
|
|
}
|
|
GetScriptInterfaceClass() {
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins = {};
|
|
C3.Behaviors = {};
|
|
C3.PluginManager = class PluginManager extends C3.DefendedBase {
|
|
constructor(runtime) {
|
|
super();
|
|
this._runtime = runtime;
|
|
this._allPlugins = [];
|
|
this._pluginsByCtor = new Map;
|
|
this._systemPlugin = null;
|
|
this._allBehaviors = [];
|
|
this._behaviorsByCtor = new Map;
|
|
this._solidBehavior = null;
|
|
this._jumpthruBehavior = null
|
|
}
|
|
CreatePlugin(pluginData) {
|
|
const Ctor = this._runtime.GetObjectReference(pluginData[0]);
|
|
if (!Ctor)
|
|
throw new Error("missing plugin");
|
|
C3.AddCommonACEs(pluginData, Ctor);
|
|
const plugin = C3.New(Ctor, {
|
|
runtime: this._runtime,
|
|
isSingleGlobal: pluginData[1],
|
|
isWorld: pluginData[2],
|
|
isRotatable: pluginData[5],
|
|
hasEffects: pluginData[8],
|
|
mustPredraw: pluginData[9],
|
|
supportsSceneGraph: pluginData[13],
|
|
supportsMesh: pluginData[14]
|
|
});
|
|
plugin.OnCreate();
|
|
this._allPlugins.push(plugin);
|
|
this._pluginsByCtor.set(Ctor, plugin)
|
|
}
|
|
CreateSystemPlugin() {
|
|
this._systemPlugin = C3.New(C3.Plugins.System, {
|
|
runtime: this._runtime,
|
|
isSingleGlobal: true
|
|
});
|
|
this._systemPlugin.OnCreate()
|
|
}
|
|
CreateBehavior(behaviorData) {
|
|
const Ctor = this._runtime.GetObjectReference(behaviorData[1]);
|
|
if (!Ctor)
|
|
throw new Error("missing behavior");
|
|
const behavior = C3.New(Ctor, {
|
|
runtime: this._runtime
|
|
});
|
|
behavior.OnCreate();
|
|
this._allBehaviors.push(behavior);
|
|
this._behaviorsByCtor.set(Ctor, behavior);
|
|
if (!this._solidBehavior && C3.Behaviors.solid && behavior instanceof C3.Behaviors.solid)
|
|
this._solidBehavior = behavior;
|
|
else if (!this._jumpthruBehavior && C3.Behaviors.jumpthru && behavior instanceof C3.Behaviors.jumpthru)
|
|
this._jumpthruBehavior = behavior
|
|
}
|
|
GetPluginByConstructorFunction(ctor) {
|
|
return this._pluginsByCtor.get(ctor) || null
|
|
}
|
|
HasBehaviorByConstructorFunction(ctor) {
|
|
return this._behaviorsByCtor.has(ctor)
|
|
}
|
|
GetBehaviorByConstructorFunction(ctor) {
|
|
return this._behaviorsByCtor.get(ctor) || null
|
|
}
|
|
GetSystemPlugin() {
|
|
return this._systemPlugin
|
|
}
|
|
GetSolidBehavior() {
|
|
return this._solidBehavior
|
|
}
|
|
GetJumpthruBehavior() {
|
|
return this._jumpthruBehavior
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const allImageInfos = new Set;
|
|
C3.ImageInfo = class ImageInfo extends C3.DefendedBase {
|
|
constructor() {
|
|
super();
|
|
this._url = "";
|
|
this._size = 0;
|
|
this._pixelFormat = 0;
|
|
this._offsetX = 0;
|
|
this._offsetY = 0;
|
|
this._width = 0;
|
|
this._height = 0;
|
|
this._hasMetaData = false;
|
|
this._imageAsset = null;
|
|
this._textureState = "";
|
|
this._rcTex = C3.New(C3.Rect);
|
|
allImageInfos.add(this)
|
|
}
|
|
Release() {
|
|
this.ReleaseTexture();
|
|
this._imageAsset = null;
|
|
allImageInfos.delete(this)
|
|
}
|
|
static OnWebGLContextLost() {
|
|
for (const imageInfo of allImageInfos) {
|
|
imageInfo._textureState = "";
|
|
imageInfo._rcTex.set(0, 0, 0, 0)
|
|
}
|
|
}
|
|
LoadData(imageData) {
|
|
this._url = imageData[0];
|
|
this._size = imageData[1];
|
|
this._pixelFormat = imageData[2];
|
|
this._offsetX = imageData[3];
|
|
this._offsetY = imageData[4];
|
|
this._width = imageData[5];
|
|
this._height = imageData[6];
|
|
this._hasMetaData = true
|
|
}
|
|
LoadAnimationFrameData(frameData) {
|
|
this._url = frameData[0];
|
|
this._size = frameData[1];
|
|
this._offsetX = frameData[2];
|
|
this._offsetY = frameData[3];
|
|
this._width = frameData[4];
|
|
this._height = frameData[5];
|
|
this._pixelFormat = frameData[11];
|
|
this._hasMetaData = true
|
|
}
|
|
LoadDynamicAsset(runtime, url) {
|
|
if (this._imageAsset)
|
|
throw new Error("already loaded asset");
|
|
this._url = url;
|
|
const opts = {};
|
|
if (C3.IsAbsoluteURL(url))
|
|
opts.loadPolicy = "remote";
|
|
this.LoadAsset(runtime, opts);
|
|
return this._imageAsset.Load()
|
|
}
|
|
ReplaceWith(otherImageInfo) {
|
|
if (otherImageInfo === this)
|
|
throw new Error("cannot replace with self");
|
|
this.ReleaseTexture();
|
|
this._url = otherImageInfo._url;
|
|
this._size = otherImageInfo._size;
|
|
this._pixelFormat = otherImageInfo._pixelFormat;
|
|
this._offsetX = otherImageInfo._offsetX;
|
|
this._offsetY = otherImageInfo._offsetY;
|
|
this._width = otherImageInfo._width;
|
|
this._height = otherImageInfo._height;
|
|
this._hasMetaData = otherImageInfo._hasMetaData;
|
|
this._imageAsset = otherImageInfo._imageAsset;
|
|
this._textureState = otherImageInfo._textureState;
|
|
this._rcTex = otherImageInfo._rcTex
|
|
}
|
|
GetURL() {
|
|
return this._url
|
|
}
|
|
GetSize() {
|
|
return this._size
|
|
}
|
|
GetPixelFormat() {
|
|
return this._pixelFormat
|
|
}
|
|
GetOffsetX() {
|
|
return this._offsetX
|
|
}
|
|
GetOffsetY() {
|
|
return this._offsetY
|
|
}
|
|
GetWidth() {
|
|
return this._width
|
|
}
|
|
GetHeight() {
|
|
return this._height
|
|
}
|
|
GetSheetWidth() {
|
|
return this._imageAsset.GetWidth()
|
|
}
|
|
GetSheetHeight() {
|
|
return this._imageAsset.GetHeight()
|
|
}
|
|
LoadAsset(runtime, opts) {
|
|
if (this._imageAsset)
|
|
throw new Error("already got asset");
|
|
opts = Object.assign({}, opts, {
|
|
url: this.GetURL(),
|
|
size: this.GetSize()
|
|
});
|
|
this._imageAsset = runtime.LoadImage(opts)
|
|
}
|
|
IsLoaded() {
|
|
return this._imageAsset && this._imageAsset.IsLoaded()
|
|
}
|
|
async LoadStaticTexture(renderer, opts) {
|
|
if (!this._imageAsset)
|
|
throw new Error("no asset");
|
|
if (this._textureState)
|
|
throw new Error("already loaded texture");
|
|
this._textureState = "loading";
|
|
const texture = await this._imageAsset.LoadStaticTexture(renderer, opts);
|
|
if (!texture) {
|
|
this._textureState = "";
|
|
return null
|
|
}
|
|
this._textureState = "loaded";
|
|
if (!this._hasMetaData) {
|
|
this._width = texture.GetWidth();
|
|
this._height = texture.GetHeight();
|
|
this._hasMetaData = true
|
|
}
|
|
this._rcTex.set(this._offsetX, this._offsetY, this._offsetX + this._width, this._offsetY + this._height);
|
|
this._rcTex.divide(texture.GetWidth(), texture.GetHeight());
|
|
return texture
|
|
}
|
|
ReleaseTexture() {
|
|
if (!this._textureState)
|
|
return;
|
|
if (this._imageAsset)
|
|
this._imageAsset.ReleaseTexture();
|
|
this._textureState = "";
|
|
this._rcTex.set(0, 0, 0, 0)
|
|
}
|
|
GetTexture() {
|
|
return this._imageAsset ? this._imageAsset.GetTexture() : null
|
|
}
|
|
GetTexRect() {
|
|
return this._rcTex
|
|
}
|
|
async ExtractImageToCanvas() {
|
|
const srcDrawable = await this._imageAsset.LoadToDrawable();
|
|
const canvas = C3.CreateCanvas(this._width, this._height);
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.drawImage(srcDrawable, this._offsetX, this._offsetY, this._width, this._height, 0, 0, this._width, this._height);
|
|
return canvas
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.AnimationInfo = class AnimationInfo extends C3.DefendedBase {
|
|
constructor(animData) {
|
|
super();
|
|
this._name = animData[0];
|
|
this._speed = animData[1];
|
|
this._isLooping = !!animData[2];
|
|
this._repeatCount = animData[3];
|
|
this._repeatTo = animData[4];
|
|
this._isPingPong = !!animData[5];
|
|
this._sid = animData[6];
|
|
this._frames = animData[7].map(frameData=>C3.New(C3.AnimationFrameInfo, frameData))
|
|
}
|
|
Release() {
|
|
for (const f of this._frames)
|
|
f.Release();
|
|
C3.clearArray(this._frames)
|
|
}
|
|
LoadAllAssets(runtime) {
|
|
for (const f of this._frames)
|
|
f.GetImageInfo().LoadAsset(runtime)
|
|
}
|
|
LoadAllTextures(renderer, opts) {
|
|
return Promise.all(this._frames.map(f=>f.GetImageInfo().LoadStaticTexture(renderer, opts)))
|
|
}
|
|
ReleaseAllTextures() {
|
|
for (const f of this._frames)
|
|
f.GetImageInfo().ReleaseTexture()
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
GetSID() {
|
|
return this._sid
|
|
}
|
|
GetFrameCount() {
|
|
return this._frames.length
|
|
}
|
|
GetFrames() {
|
|
return this._frames
|
|
}
|
|
GetFrameAt(i) {
|
|
i = Math.floor(i);
|
|
if (i < 0 || i >= this._frames.length)
|
|
throw new RangeError("invalid frame");
|
|
return this._frames[i]
|
|
}
|
|
GetSpeed() {
|
|
return this._speed
|
|
}
|
|
IsLooping() {
|
|
return this._isLooping
|
|
}
|
|
GetRepeatCount() {
|
|
return this._repeatCount
|
|
}
|
|
GetRepeatTo() {
|
|
return this._repeatTo
|
|
}
|
|
IsPingPong() {
|
|
return this._isPingPong
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.AnimationFrameInfo = class AnimationFrameInfo extends C3.DefendedBase {
|
|
constructor(frameData) {
|
|
super();
|
|
this._imageInfo = C3.New(C3.ImageInfo);
|
|
this._imageInfo.LoadAnimationFrameData(frameData);
|
|
this._duration = frameData[6];
|
|
this._origin = C3.New(C3.Vector2, frameData[7], frameData[8]);
|
|
this._imagePoints = frameData[9].map(data=>C3.New(C3.ImagePoint, this, data));
|
|
this._imagePointsByName = new Map;
|
|
for (const ip of this._imagePoints)
|
|
this._imagePointsByName.set(ip.GetName().toLowerCase(), ip);
|
|
this._collisionPoly = null;
|
|
const polyPoints = frameData[10];
|
|
if (polyPoints.length >= 6)
|
|
this._collisionPoly = C3.New(C3.CollisionPoly, polyPoints)
|
|
}
|
|
Release() {
|
|
if (this._collisionPoly) {
|
|
this._collisionPoly.Release();
|
|
this._collisionPoly = null
|
|
}
|
|
this._imageInfo.Release();
|
|
this._imageInfo = null
|
|
}
|
|
GetImageInfo() {
|
|
return this._imageInfo
|
|
}
|
|
GetDuration() {
|
|
return this._duration
|
|
}
|
|
GetOriginX() {
|
|
return this._origin.getX()
|
|
}
|
|
GetOriginY() {
|
|
return this._origin.getY()
|
|
}
|
|
GetCollisionPoly() {
|
|
return this._collisionPoly
|
|
}
|
|
GetImagePointByName(name) {
|
|
return this._imagePointsByName.get(name.toLowerCase()) || null
|
|
}
|
|
GetImagePointByIndex(index) {
|
|
index = Math.floor(index);
|
|
if (index < 0 || index >= this._imagePoints.length)
|
|
return null;
|
|
return this._imagePoints[index]
|
|
}
|
|
GetImagePointCount() {
|
|
return this._imagePoints.length
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.ImagePoint = class ImagePoint extends C3.DefendedBase {
|
|
constructor(afi, data) {
|
|
super();
|
|
this._afi = afi;
|
|
this._name = data[0];
|
|
this._pos = C3.New(C3.Vector2, data[1], data[2])
|
|
}
|
|
Release() {}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
GetX() {
|
|
return this._pos.getX()
|
|
}
|
|
GetY() {
|
|
return this._pos.getY()
|
|
}
|
|
GetVec2() {
|
|
return this._pos
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const C3Debugger = self.C3Debugger;
|
|
const IObjectClass = self.IObjectClass;
|
|
const assert = self.assert;
|
|
C3.ObjectClass = class ObjectClass extends C3.DefendedBase {
|
|
constructor(runtime, index, data) {
|
|
super();
|
|
const PluginCtor = runtime.GetObjectReference(data[1]);
|
|
this._runtime = runtime;
|
|
this._plugin = runtime.GetPluginManager().GetPluginByConstructorFunction(PluginCtor);
|
|
this._sdkType = null;
|
|
this._instSdkCtor = PluginCtor.Instance;
|
|
this._index = index;
|
|
this._sid = data[11];
|
|
this._name = data[0];
|
|
this._jsPropName = this._runtime.GetJsPropName(data[14]);
|
|
this._isGlobal = !!data[9];
|
|
this._isFamily = !!data[2];
|
|
this._isOnLoaderLayout = !!data[10];
|
|
this._instVars = data[3].map(arr=>({
|
|
sid: arr[0],
|
|
type: arr[1],
|
|
name: arr[2],
|
|
jsPropName: runtime.GetJsPropName(arr[3])
|
|
}));
|
|
this._behaviorsCount = data[4];
|
|
this._effectsCount = data[5];
|
|
this._isWorldType = this._plugin.IsWorldType();
|
|
this._effectList = null;
|
|
this._collisionGrid = C3.New(C3.SparseGrid, runtime.GetOriginalViewportWidth(), runtime.GetOriginalViewportHeight());
|
|
this._anyCollisionCellChanged = true;
|
|
this._anyInstanceParallaxed = false;
|
|
this._familyMembers = null;
|
|
this._familyMembersSet = null;
|
|
this._familyIndex = -1;
|
|
this._families = null;
|
|
this._familiesSet = null;
|
|
this._familyInstVarMap = null;
|
|
this._familyBehaviorMap = null;
|
|
this._familyEffectMap = null;
|
|
this._isInContainer = false;
|
|
this._container = null;
|
|
this._behaviorTypes = data[8].map(behaviorTypeData=>C3.BehaviorType.Create(this, behaviorTypeData));
|
|
this._behaviorTypesIncludingInherited = [];
|
|
this._behaviorsByName = new Map;
|
|
this._behaviorNameToIndex = new Map;
|
|
this._usedBehaviorCtors = new Set;
|
|
this._solStack = C3.New(C3.SolStack, this);
|
|
this._defaultInstanceData = null;
|
|
this._defaultLayerIndex = 0;
|
|
this._isContained = false;
|
|
this._container = null;
|
|
this._imageInfo = null;
|
|
this._animations = null;
|
|
this._animationsByName = null;
|
|
this._animationsBySid = null;
|
|
this._textureRefCount = 0;
|
|
this._savedData = new Map;
|
|
this._unsavedData = new Map;
|
|
this._instances = [];
|
|
this._iidsStale = true;
|
|
if (this._plugin.HasEffects())
|
|
this._effectList = C3.New(C3.EffectList, this, data[12]);
|
|
if (data[6]) {
|
|
this._imageInfo = C3.New(C3.ImageInfo);
|
|
this._imageInfo.LoadData(data[6])
|
|
}
|
|
if (data[7]) {
|
|
this._animations = data[7].map(animData=>C3.New(C3.AnimationInfo, animData));
|
|
this._animationsByName = new Map;
|
|
this._animationsBySid = new Map;
|
|
for (const anim of this._animations) {
|
|
this._animationsByName.set(anim.GetName().toLowerCase(), anim);
|
|
this._animationsBySid.set(anim.GetSID(), anim)
|
|
}
|
|
}
|
|
if (this._isFamily) {
|
|
this._familyMembers = [];
|
|
this._familyMembersSet = new Set;
|
|
this._familyIndex = this._runtime._GetNextFamilyIndex()
|
|
} else {
|
|
this._families = [];
|
|
this._familiesSet = new Set;
|
|
this._familyInstVarMap = [];
|
|
this._familyBehaviorMap = [];
|
|
this._familyEffectMap = []
|
|
}
|
|
this._sdkType = C3.New(PluginCtor.Type, this, data[15]);
|
|
this._iObjectClass = null;
|
|
this._instanceUserScriptClass = null;
|
|
this._userScriptDispatcher = C3.New(C3.Event.Dispatcher);
|
|
const CustomScriptClass = this._sdkType.GetScriptInterfaceClass();
|
|
if (CustomScriptClass) {
|
|
this._iObjectClass = new CustomScriptClass(this);
|
|
if (!(this._iObjectClass instanceof IObjectClass))
|
|
throw new TypeError("script interface class must derive from IObjectClass");
|
|
} else
|
|
this._iObjectClass = new IObjectClass(this);
|
|
if (data[13]) {
|
|
const tilemapData = data[13];
|
|
if (tilemapData) {
|
|
const tilePolyData = tilemapData[0];
|
|
const maxTileIndex = tilemapData[1];
|
|
this._sdkType.LoadTilemapData(tilePolyData, maxTileIndex)
|
|
}
|
|
}
|
|
if (!this._runtime.UsesLoaderLayout() || this._isFamily || this._isOnLoaderLayout || !this._isWorldType)
|
|
this.OnCreate();
|
|
if (this._plugin.IsSingleGlobal()) {
|
|
this._plugin._SetSingleGlobalObjectClass(this);
|
|
this._CreateSingleGlobalInstance(data)
|
|
}
|
|
}
|
|
static Create(runtime, index, objectClassData) {
|
|
return C3.New(C3.ObjectClass, runtime, index, objectClassData)
|
|
}
|
|
Release() {
|
|
if (this._imageInfo) {
|
|
this._imageInfo.Release();
|
|
this._imageInfo = null
|
|
}
|
|
if (this._animations) {
|
|
for (const a of this._animations)
|
|
a.Release();
|
|
C3.clearArray(this._animations);
|
|
this._animationsByName.clear();
|
|
this._animationsBySid.clear()
|
|
}
|
|
this._solStack.Release();
|
|
this._solStack = null;
|
|
this._savedData.clear();
|
|
this._unsavedData.clear();
|
|
this._container = null;
|
|
this._runtime = null
|
|
}
|
|
_LoadFamily(familyData) {
|
|
for (let i = 1, len = familyData.length; i < len; ++i) {
|
|
const memberType = this._runtime.GetObjectClassByIndex(familyData[i]);
|
|
this._familyMembers.push(memberType);
|
|
this._familyMembersSet.add(memberType);
|
|
memberType._families.push(this);
|
|
memberType._familiesSet.add(this)
|
|
}
|
|
}
|
|
_SetContainer(container) {
|
|
this._isInContainer = true;
|
|
this._container = container
|
|
}
|
|
IsInContainer() {
|
|
return this._isInContainer
|
|
}
|
|
GetContainer() {
|
|
return this._container
|
|
}
|
|
_OnAfterCreate() {
|
|
let index = 0;
|
|
if (!this._isFamily)
|
|
for (const family of this._families)
|
|
for (const familyBehType of family.GetBehaviorTypes()) {
|
|
const lowerName = familyBehType.GetName().toLowerCase();
|
|
this._behaviorsByName.set(lowerName, familyBehType);
|
|
this._behaviorNameToIndex.set(lowerName, index);
|
|
this._behaviorTypesIncludingInherited.push(familyBehType);
|
|
++index
|
|
}
|
|
for (const behaviorType of this.GetBehaviorTypes()) {
|
|
const lowerName = behaviorType.GetName().toLowerCase();
|
|
this._behaviorsByName.set(lowerName, behaviorType);
|
|
this._behaviorNameToIndex.set(lowerName, index);
|
|
this._behaviorTypesIncludingInherited.push(behaviorType);
|
|
++index
|
|
}
|
|
for (const behaviorType of this._behaviorTypesIncludingInherited)
|
|
this._usedBehaviorCtors.add(behaviorType.GetBehavior().constructor);
|
|
if (!this._isFamily && this._families.length) {
|
|
const familyCount = this._runtime.GetFamilyCount();
|
|
C3.extendArray(this._familyInstVarMap, familyCount, 0);
|
|
C3.extendArray(this._familyBehaviorMap, familyCount, 0);
|
|
C3.extendArray(this._familyEffectMap, familyCount, 0);
|
|
const allFx = [];
|
|
let ivSum = 0;
|
|
let behSum = 0;
|
|
let fxSum = 0;
|
|
for (const family of this._families) {
|
|
const familyIndex = family.GetFamilyIndex();
|
|
this._familyInstVarMap[familyIndex] = ivSum;
|
|
ivSum += family.GetInstanceVariablesCount();
|
|
this._familyBehaviorMap[familyIndex] = behSum;
|
|
behSum += family.GetBehaviorTypesCount();
|
|
this._familyEffectMap[familyIndex] = fxSum;
|
|
fxSum += family.GetEffectTypesCount();
|
|
const familyEffectList = family.GetEffectList();
|
|
if (familyEffectList && this._effectList)
|
|
for (const effectType of familyEffectList.GetAllEffectTypes())
|
|
allFx.push(effectType.Clone(this._effectList))
|
|
}
|
|
if (this._effectList)
|
|
this._effectList.PrependEffectTypes(allFx)
|
|
}
|
|
}
|
|
_CreateSingleGlobalInstance(data) {
|
|
const uid = this._runtime._GetNewUID();
|
|
const inst = C3.New(C3.Instance, {
|
|
runtime: this._runtime,
|
|
objectType: this,
|
|
uid: uid
|
|
});
|
|
inst._CreateSdkInstance(data[16], []);
|
|
this._runtime._MapInstanceByUID(uid, inst);
|
|
this._instances.push(inst)
|
|
}
|
|
GetSdkType() {
|
|
return this._sdkType
|
|
}
|
|
IsOnLoaderLayout() {
|
|
return this._isOnLoaderLayout
|
|
}
|
|
OnCreate() {
|
|
if (!this._isFamily)
|
|
this._sdkType.OnCreate()
|
|
}
|
|
HasLoadedTextures() {
|
|
return this._textureRefCount > 0
|
|
}
|
|
LoadTextures(renderer) {
|
|
if (this._isFamily)
|
|
return Promise.resolve();
|
|
this._textureRefCount++;
|
|
if (this._textureRefCount === 1)
|
|
return this._sdkType.LoadTextures(renderer) || Promise.resolve();
|
|
else
|
|
return Promise.resolve()
|
|
}
|
|
ReleaseTextures() {
|
|
if (this._isFamily)
|
|
return;
|
|
this._textureRefCount--;
|
|
if (this._textureRefCount < 0)
|
|
throw new Error("released textures too many times");
|
|
if (this._textureRefCount === 0)
|
|
this._sdkType.ReleaseTextures()
|
|
}
|
|
OnDynamicTextureLoadComplete() {
|
|
if (this._isFamily)
|
|
throw new Error("not applicable to family");
|
|
this._sdkType.OnDynamicTextureLoadComplete()
|
|
}
|
|
PreloadTexturesWithInstances(renderer) {
|
|
if (this._isFamily)
|
|
return Promise.resolve();
|
|
return this._sdkType.PreloadTexturesWithInstances(renderer)
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetPlugin() {
|
|
return this._plugin
|
|
}
|
|
GetInstanceSdkCtor() {
|
|
return this._instSdkCtor
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
GetJsPropName() {
|
|
return this._jsPropName
|
|
}
|
|
GetIndex() {
|
|
return this._index
|
|
}
|
|
GetSID() {
|
|
return this._sid
|
|
}
|
|
IsFamily() {
|
|
return this._isFamily
|
|
}
|
|
IsGlobal() {
|
|
return this._isGlobal
|
|
}
|
|
IsWorldType() {
|
|
return this._isWorldType
|
|
}
|
|
GetFamilyIndex() {
|
|
return this._familyIndex
|
|
}
|
|
GetBehaviorTypes() {
|
|
return this._behaviorTypes
|
|
}
|
|
GetBehaviorTypesCount() {
|
|
return this._behaviorsCount
|
|
}
|
|
UsesBehaviorByCtor(Ctor) {
|
|
return Ctor && this._usedBehaviorCtors.has(Ctor)
|
|
}
|
|
GetInstanceVariablesCount() {
|
|
return this._instVars.length
|
|
}
|
|
GetInstanceVariableSIDs() {
|
|
return this._instVars.map(iv=>iv.sid)
|
|
}
|
|
GetInstanceVariableIndexBySID(sid) {
|
|
return this._instVars.findIndex(iv=>iv.sid === sid)
|
|
}
|
|
GetInstanceVariableIndexByName(name) {
|
|
return this._instVars.findIndex(iv=>iv.name === name)
|
|
}
|
|
_GetAllInstanceVariableNames() {
|
|
return this._instVars.map(iv=>iv.name)
|
|
}
|
|
_GetAllInstanceVariableJsPropNames() {
|
|
return this._instVars.map(iv=>iv.jsPropName)
|
|
}
|
|
GetInstanceVariableType(i) {
|
|
i = Math.floor(i);
|
|
if (i < 0 || i >= this._instVars.length)
|
|
throw new RangeError("invalid instance variable index");
|
|
return this._instVars[i].type
|
|
}
|
|
GetInstanceVariableName(i) {
|
|
i = Math.floor(i);
|
|
if (i < 0 || i >= this._instVars.length)
|
|
throw new RangeError("invalid instance variable index");
|
|
return this._instVars[i].name
|
|
}
|
|
GetEffectTypesCount() {
|
|
return this._effectsCount
|
|
}
|
|
GetBehaviorTypesIncludingInherited() {
|
|
return this._behaviorTypesIncludingInherited
|
|
}
|
|
GetBehaviorTypeByName(name) {
|
|
return this._behaviorsByName.get(name.toLowerCase()) || null
|
|
}
|
|
GetBehaviorIndexByName(name) {
|
|
const ret = this._behaviorNameToIndex.get(name.toLowerCase());
|
|
if (typeof ret === "undefined")
|
|
return -1;
|
|
else
|
|
return ret
|
|
}
|
|
GetEffectList() {
|
|
return this._effectList
|
|
}
|
|
HasEffects() {
|
|
return this._plugin.HasEffects()
|
|
}
|
|
UsesEffects() {
|
|
return this._effectList && this._effectList.HasAnyEffectType()
|
|
}
|
|
GetSolStack() {
|
|
return this._solStack
|
|
}
|
|
GetCurrentSol() {
|
|
return this._solStack.GetCurrentSol()
|
|
}
|
|
GetImageInfo() {
|
|
return this._imageInfo
|
|
}
|
|
SetDefaultInstanceData(d) {
|
|
this._defaultInstanceData = d
|
|
}
|
|
GetDefaultInstanceData() {
|
|
return this._defaultInstanceData
|
|
}
|
|
_SetDefaultLayerIndex(i) {
|
|
this._defaultLayerIndex = i
|
|
}
|
|
GetDefaultLayerIndex() {
|
|
return this._defaultLayerIndex
|
|
}
|
|
GetAnimations() {
|
|
return this._animations
|
|
}
|
|
GetAnimationCount() {
|
|
return this._animations.length
|
|
}
|
|
GetFamilies() {
|
|
return this._families
|
|
}
|
|
BelongsToFamily(family) {
|
|
return this._familiesSet.has(family)
|
|
}
|
|
GetFamilyMembers() {
|
|
return this._familyMembers
|
|
}
|
|
FamilyHasMember(objectType) {
|
|
return this._familyMembersSet.has(objectType)
|
|
}
|
|
GetFamilyBehaviorOffset(familyIndex) {
|
|
return this._familyBehaviorMap[familyIndex]
|
|
}
|
|
GetFamilyInstanceVariableOffset(familyIndex) {
|
|
return this._familyInstVarMap[familyIndex]
|
|
}
|
|
GetAnimationByName(name) {
|
|
if (!this._animations)
|
|
throw new Error("no animations");
|
|
return this._animationsByName.get(name.toLowerCase()) || null
|
|
}
|
|
GetAnimationBySID(sid) {
|
|
if (!this._animations)
|
|
throw new Error("no animations");
|
|
return this._animationsBySid.get(sid) || null
|
|
}
|
|
GetFirstAnimationFrame() {
|
|
if (!this._animations)
|
|
throw new Error("no animations");
|
|
return this._animations[0].GetFrameAt(0)
|
|
}
|
|
GetDefaultInstanceSize() {
|
|
if (this._animations) {
|
|
const firstFrameInfo = this.GetFirstAnimationFrame().GetImageInfo();
|
|
return [firstFrameInfo.GetWidth(), firstFrameInfo.GetHeight()]
|
|
} else if (this._imageInfo)
|
|
return [this._imageInfo.GetWidth(), this._imageInfo.GetHeight()];
|
|
else
|
|
return [100, 100]
|
|
}
|
|
GetSingleGlobalInstance() {
|
|
if (!this._plugin.IsSingleGlobal())
|
|
throw new Error("not a single-global plugin");
|
|
return this._instances[0]
|
|
}
|
|
GetInstances() {
|
|
return this._instances
|
|
}
|
|
*instances() {
|
|
yield*this._instances
|
|
}
|
|
*instancesIncludingPendingCreate() {
|
|
yield*this._instances;
|
|
for (const inst of this._runtime._GetInstancesPendingCreate())
|
|
if (inst.GetObjectClass() === this)
|
|
yield inst
|
|
}
|
|
GetInstanceCount() {
|
|
return this._instances.length
|
|
}
|
|
_AddInstance(inst) {
|
|
this._instances.push(inst)
|
|
}
|
|
_SetIIDsStale() {
|
|
this._iidsStale = true
|
|
}
|
|
_UpdateIIDs() {
|
|
if (!this._iidsStale || this._isFamily)
|
|
return;
|
|
const instances = this._instances;
|
|
let i = 0;
|
|
for (let len = instances.length; i < len; ++i)
|
|
instances[i]._SetIID(i);
|
|
const instancesPendingCreate = this._runtime._GetInstancesPendingCreate();
|
|
for (const inst of instancesPendingCreate)
|
|
if (inst.GetObjectClass() === this)
|
|
inst._SetIID(i++);
|
|
this._iidsStale = false
|
|
}
|
|
GetInstanceByIID(i) {
|
|
const instances = this._instances;
|
|
if (i < instances.length)
|
|
return instances[i];
|
|
i -= instances.length;
|
|
const instancesPendingCreate = this._runtime._GetInstancesPendingCreate();
|
|
for (const inst of instancesPendingCreate)
|
|
if (inst.GetObjectClass() === this) {
|
|
if (i === 0)
|
|
return inst;
|
|
--i
|
|
}
|
|
return null
|
|
}
|
|
GetFirstPicked(fromInst) {
|
|
if (fromInst && fromInst.IsInContainer() && fromInst.GetObjectClass() !== this)
|
|
for (const s of fromInst.siblings())
|
|
if (s.GetObjectClass() === this)
|
|
return s;
|
|
const instances = this.GetCurrentSol().GetInstances();
|
|
if (instances.length)
|
|
return instances[0];
|
|
else
|
|
return null
|
|
}
|
|
GetPairedInstance(inst) {
|
|
const instances = this.GetCurrentSol().GetInstances();
|
|
if (instances.length)
|
|
return instances[inst.GetIID() % instances.length];
|
|
else
|
|
return null
|
|
}
|
|
*allCorrespondingInstances(inst, objectClass) {
|
|
const myInstances = this.GetCurrentSol().GetInstances();
|
|
const myInstanceCount = myInstances.length;
|
|
const otherSol = objectClass.GetCurrentSol();
|
|
const otherInstances = objectClass.GetCurrentSol().GetInstances();
|
|
const otherInstanceCount = otherInstances.length;
|
|
let index = inst.GetIID();
|
|
if (objectClass.IsFamily() || !otherSol.IsSelectAll())
|
|
index = otherInstances.indexOf(inst);
|
|
const divisor = Math.ceil(myInstanceCount / otherInstanceCount);
|
|
const remainder = myInstanceCount % otherInstanceCount;
|
|
let startIndex = 0;
|
|
let correspondCount = 0;
|
|
if (remainder === 0 || index < remainder) {
|
|
startIndex = index * divisor;
|
|
correspondCount = divisor
|
|
} else {
|
|
startIndex = remainder * divisor + (index - remainder) * (divisor - 1);
|
|
correspondCount = divisor - 1
|
|
}
|
|
for (let i = startIndex, end = startIndex + correspondCount; i < end; ++i)
|
|
yield myInstances[i]
|
|
}
|
|
FinishCondition(f) {
|
|
this._sdkType.FinishCondition(f)
|
|
}
|
|
ApplySolToContainer() {
|
|
if (!this._isInContainer || this._isFamily)
|
|
return;
|
|
this._UpdateIIDs();
|
|
const sol1 = this.GetCurrentSol();
|
|
const sol1instances = sol1._GetOwnInstances();
|
|
const selectAll = sol1.IsSelectAll();
|
|
const es = this._runtime.GetCurrentEventStackFrame();
|
|
const isOrBlock = es && es.GetCurrentEvent() && es.GetCurrentEvent().IsOrBlock();
|
|
for (const containerType of this._container.objectTypes()) {
|
|
if (containerType === this)
|
|
continue;
|
|
containerType._UpdateIIDs();
|
|
const sol2 = containerType.GetCurrentSol();
|
|
sol2._SetSelectAll(selectAll);
|
|
if (!selectAll) {
|
|
const sol2instances = sol2._GetOwnInstances();
|
|
C3.clearArray(sol2instances);
|
|
for (const inst of sol1instances)
|
|
sol2instances.push(containerType.GetInstanceByIID(inst.GetIID()));
|
|
if (isOrBlock) {
|
|
const sol1elseInstances = sol1._GetOwnElseInstances();
|
|
const sol2elseInstances = sol2._GetOwnElseInstances();
|
|
C3.clearArray(sol2elseInstances);
|
|
for (const inst of sol1elseInstances)
|
|
sol2elseInstances.push(containerType.GetInstanceByIID(inst.GetIID()))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_TruncateContainerSols(useElseInstances, i) {
|
|
for (const containerType of this.GetContainer().objectTypes()) {
|
|
const sol = containerType.GetCurrentSol();
|
|
if (useElseInstances)
|
|
C3.truncateArray(sol._GetOwnElseInstances(), i);
|
|
else
|
|
C3.truncateArray(sol._GetOwnInstances(), i)
|
|
}
|
|
}
|
|
_GetCollisionCellGrid() {
|
|
return this._collisionGrid
|
|
}
|
|
_SetAnyCollisionCellChanged(c) {
|
|
this._anyCollisionCellChanged = !!c
|
|
}
|
|
_SetAnyInstanceParallaxed(p) {
|
|
this._anyInstanceParallaxed = !!p
|
|
}
|
|
IsAnyInstanceParallaxed() {
|
|
return this._anyInstanceParallaxed
|
|
}
|
|
_UpdateAllCollisionCells() {
|
|
if (!this._anyCollisionCellChanged || !this._isWorldType)
|
|
return;
|
|
for (const inst of this._instances)
|
|
inst.GetWorldInfo()._UpdateCollisionCell();
|
|
for (const inst of this._runtime._GetInstancesPendingCreate())
|
|
if (inst.GetObjectClass() === this)
|
|
inst.GetWorldInfo()._UpdateCollisionCell();
|
|
this._anyCollisionCellChanged = false
|
|
}
|
|
GetSavedDataMap() {
|
|
if (!this._savedData)
|
|
this._savedData = new Map;
|
|
return this._savedData
|
|
}
|
|
GetUnsavedDataMap() {
|
|
if (!this._unsavedData)
|
|
this._unsavedData = new Map;
|
|
return this._unsavedData
|
|
}
|
|
HasSolidBehavior() {
|
|
return this.UsesBehaviorByCtor(C3.Behaviors.solid)
|
|
}
|
|
HasNoSaveBehavior() {
|
|
return this.UsesBehaviorByCtor(C3.Behaviors.NoSave)
|
|
}
|
|
HasPersistBehavior() {
|
|
return this.UsesBehaviorByCtor(C3.Behaviors.Persist)
|
|
}
|
|
_SaveToJson() {
|
|
const o = {
|
|
"instances": this._instances.map(inst=>inst.SaveToJson())
|
|
};
|
|
if (this._savedData && this._savedData.size)
|
|
o["ex"] = C3.ToSuperJSON(this._savedData);
|
|
return o
|
|
}
|
|
_LoadFromJson(o) {
|
|
if (this._savedData) {
|
|
this._savedData.clear();
|
|
this._savedData = null
|
|
}
|
|
const ex = o["ex"];
|
|
if (ex)
|
|
this._savedData = C3.FromSuperJSON(ex);
|
|
const existingInstances = this._instances;
|
|
const loadInstances = o["instances"];
|
|
for (let i = 0, len = Math.min(existingInstances.length, loadInstances.length); i < len; ++i)
|
|
existingInstances[i].LoadFromJson(loadInstances[i]);
|
|
for (let i = loadInstances.length, len = existingInstances.length; i < len; ++i)
|
|
this._runtime.DestroyInstance(existingInstances[i]);
|
|
for (let i = existingInstances.length, len = loadInstances.length; i < len; ++i) {
|
|
const data = loadInstances[i];
|
|
let layer = null;
|
|
if (this.IsWorldType()) {
|
|
layer = this._runtime.GetMainRunningLayout().GetLayerBySID(data["w"]["l"]);
|
|
if (!layer)
|
|
continue
|
|
}
|
|
const inst = this._runtime.CreateInstanceFromData(this._defaultInstanceData || this, layer, false, 0, 0, true);
|
|
inst.LoadFromJson(data)
|
|
}
|
|
this._SetIIDsStale()
|
|
}
|
|
GetIObjectClass() {
|
|
return this._iObjectClass
|
|
}
|
|
UserScriptDispatcher() {
|
|
return this._userScriptDispatcher
|
|
}
|
|
_GetUserScriptInstanceClass() {
|
|
return this._instanceUserScriptClass
|
|
}
|
|
_SetUserScriptInstanceClass(Class) {
|
|
this._instanceUserScriptClass = Class
|
|
}
|
|
DispatchUserScriptEvent(e) {
|
|
const runtime = this._runtime;
|
|
const shouldTime = runtime.IsDebug() && !runtime.GetEventSheetManager().IsInEventEngine();
|
|
if (shouldTime)
|
|
C3Debugger.StartMeasuringScriptTime();
|
|
this._userScriptDispatcher.dispatchEvent(e);
|
|
if (shouldTime)
|
|
C3Debugger.AddScriptTime()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Container = class Container extends C3.DefendedBase {
|
|
constructor(runtime, objectTypes) {
|
|
super();
|
|
this._runtime = runtime;
|
|
this._objectTypes = objectTypes;
|
|
for (const objectType of this._objectTypes)
|
|
objectType._SetContainer(this)
|
|
}
|
|
Release() {
|
|
this._runtime = null
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetObjectTypes() {
|
|
return this._objectTypes
|
|
}
|
|
objectTypes() {
|
|
return this._objectTypes
|
|
}
|
|
HasAnyWorldType() {
|
|
return this._objectTypes.some(o=>o.IsWorldType())
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const C3Debugger = self.C3Debugger;
|
|
const IInstance = self.IInstance;
|
|
const EMPTY_ARRAY = [];
|
|
let nextPuid = 0;
|
|
const savedDataMaps = new WeakMap;
|
|
const unsavedDataMaps = new WeakMap;
|
|
const FLAG_DESTROYED = 1 << 0;
|
|
const FLAG_TILEMAP = 1 << 1;
|
|
const FLAG_MUST_PREDRAW = 1 << 2;
|
|
const FLAG_SOLID_ENABLED = 1 << 3;
|
|
const FLAG_JUMPTHRU_ENABLED = 1 << 4;
|
|
C3.Instance = class Instance extends C3.DefendedBase {
|
|
constructor(opts) {
|
|
super();
|
|
this._runtime = opts.runtime;
|
|
this._objectType = opts.objectType;
|
|
this._worldInfo = null;
|
|
this._sdkInst = null;
|
|
this._iScriptInterface = null;
|
|
this._iid = 0;
|
|
this._uid = opts.uid;
|
|
this._puid = nextPuid++;
|
|
this._flags = 0;
|
|
this._instVarValues = EMPTY_ARRAY;
|
|
this._behaviorInstances = EMPTY_ARRAY;
|
|
const behaviorTypes = this._objectType.GetBehaviorTypesIncludingInherited();
|
|
if (behaviorTypes.length > 0)
|
|
this._behaviorInstances = behaviorTypes.map((behaviorType,index)=>C3.New(C3.BehaviorInstance, {
|
|
runtime: this._runtime,
|
|
behaviorType: behaviorType,
|
|
instance: this,
|
|
index
|
|
}));
|
|
this._siblings = this._objectType.IsInContainer() ? [] : null;
|
|
this._timeScale = -1;
|
|
this._dispatcher = null;
|
|
const plugin = this.GetPlugin();
|
|
if (plugin.MustPreDraw())
|
|
this._flags |= FLAG_MUST_PREDRAW;
|
|
if (plugin.IsWorldType()) {
|
|
this._worldInfo = C3.New(C3.WorldInfo, this, opts.layer);
|
|
if (opts.worldData)
|
|
this._worldInfo.Init(opts.worldData);
|
|
else {
|
|
this._worldInfo.InitNoData();
|
|
const [width,height] = this._objectType.GetDefaultInstanceSize();
|
|
this._worldInfo.SetSize(width, height);
|
|
if (this.GetObjectClass().UsesEffects())
|
|
this._worldInfo.GetInstanceEffectList().LoadDefaultEffectParameters()
|
|
}
|
|
}
|
|
if (opts.instVarData)
|
|
this._LoadInstanceVariableData(opts.instVarData);
|
|
else
|
|
this._LoadDefaultInstanceVariables()
|
|
}
|
|
Release() {
|
|
if (this._iScriptInterface) {
|
|
this._iScriptInterface._Release();
|
|
this._iScriptInterface = null
|
|
}
|
|
if (this._behaviorInstances.length > 0) {
|
|
for (const behInst of this._behaviorInstances)
|
|
behInst.Release();
|
|
C3.clearArray(this._behaviorInstances)
|
|
}
|
|
this._sdkInst.Release();
|
|
this._sdkInst = null;
|
|
const savedData = savedDataMaps.get(this);
|
|
if (savedData) {
|
|
savedData.clear();
|
|
savedDataMaps.delete(this)
|
|
}
|
|
const unsavedData = unsavedDataMaps.get(this);
|
|
if (unsavedData) {
|
|
unsavedData.clear();
|
|
unsavedDataMaps.delete(this)
|
|
}
|
|
if (this._siblings)
|
|
C3.clearArray(this._siblings);
|
|
if (this._dispatcher) {
|
|
this._dispatcher.Release();
|
|
this._dispatcher = null
|
|
}
|
|
this._runtime = null;
|
|
this._objectType = null;
|
|
if (this._instVarValues.length > 0)
|
|
C3.clearArray(this._instVarValues);
|
|
if (this._worldInfo) {
|
|
this._worldInfo.Release();
|
|
this._worldInfo = null
|
|
}
|
|
}
|
|
_LoadInstanceVariableData(instVarData) {
|
|
if (instVarData.length > 0) {
|
|
this._instVarValues = [];
|
|
C3.shallowAssignArray(this._instVarValues, instVarData)
|
|
}
|
|
}
|
|
_LoadDefaultInstanceVariables() {
|
|
const len = this._objectType.GetInstanceVariablesCount();
|
|
if (len === 0)
|
|
return;
|
|
this._instVarValues = [];
|
|
const typeToInitValue = [0, 0, ""];
|
|
for (let i = 0; i < len; ++i)
|
|
this._instVarValues.push(typeToInitValue[this._objectType.GetInstanceVariableType(i)])
|
|
}
|
|
_CreateSdkInstance(properties, behInstProperties) {
|
|
if (this._sdkInst)
|
|
throw new Error("already got sdk instance");
|
|
for (let i = 0, len = this._behaviorInstances.length; i < len; ++i) {
|
|
const behInst = this._behaviorInstances[i];
|
|
behInst._CreateSdkInstance(behInstProperties ? behInstProperties[i] : null)
|
|
}
|
|
this._sdkInst = C3.New(this._objectType.GetInstanceSdkCtor(), this, properties);
|
|
if (!(this._sdkInst instanceof C3.SDKInstanceBase))
|
|
throw new Error("sdk type must derive from SDKInstanceBase");
|
|
for (let i = 0, len = this._behaviorInstances.length; i < len; ++i)
|
|
this._behaviorInstances[i].PostCreate();
|
|
if (this._objectType._GetUserScriptInstanceClass())
|
|
this._InitUserScriptInterface()
|
|
}
|
|
GetSdkInstance() {
|
|
return this._sdkInst
|
|
}
|
|
GetWorldInfo() {
|
|
return this._worldInfo
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetTimeScale() {
|
|
return this._timeScale
|
|
}
|
|
GetActiveTimeScale() {
|
|
const ts = this._timeScale;
|
|
if (ts === -1)
|
|
return this.GetRuntime().GetTimeScale();
|
|
else
|
|
return ts
|
|
}
|
|
SetTimeScale(ts) {
|
|
ts = +ts;
|
|
if (ts < 0 || !isFinite(ts))
|
|
ts = 0;
|
|
this._timeScale = ts
|
|
}
|
|
RestoreTimeScale() {
|
|
this._timeScale = -1
|
|
}
|
|
Dispatcher() {
|
|
if (!this._dispatcher)
|
|
this._dispatcher = C3.New(C3.Event.Dispatcher);
|
|
return this._dispatcher
|
|
}
|
|
Draw(renderer) {
|
|
this._sdkInst.Draw(renderer)
|
|
}
|
|
OnCreate(properties) {
|
|
this._sdkInst.OnCreate(properties)
|
|
}
|
|
_SetHasTilemap() {
|
|
this._flags |= FLAG_TILEMAP
|
|
}
|
|
HasTilemap() {
|
|
return (this._flags & FLAG_TILEMAP) !== 0
|
|
}
|
|
_MarkDestroyed() {
|
|
this._flags |= FLAG_DESTROYED
|
|
}
|
|
IsDestroyed() {
|
|
return (this._flags & FLAG_DESTROYED) !== 0
|
|
}
|
|
MustPreDraw() {
|
|
return (this._flags & FLAG_MUST_PREDRAW) !== 0
|
|
}
|
|
_IsSolidEnabled() {
|
|
return (this._flags & FLAG_SOLID_ENABLED) !== 0
|
|
}
|
|
_SetSolidEnabled(e) {
|
|
if (e)
|
|
this._flags |= FLAG_SOLID_ENABLED;
|
|
else
|
|
this._flags &= ~FLAG_SOLID_ENABLED
|
|
}
|
|
_IsJumpthruEnabled() {
|
|
return (this._flags & FLAG_JUMPTHRU_ENABLED) !== 0
|
|
}
|
|
_SetJumpthruEnabled(e) {
|
|
if (e)
|
|
this._flags |= FLAG_JUMPTHRU_ENABLED;
|
|
else
|
|
this._flags &= ~FLAG_JUMPTHRU_ENABLED
|
|
}
|
|
SetFlag(bit, enable) {
|
|
bit <<= 16;
|
|
if (enable)
|
|
this._flags |= bit;
|
|
else
|
|
this._flags &= ~bit
|
|
}
|
|
GetFlag(bit) {
|
|
return (this._flags & bit << 16) !== 0
|
|
}
|
|
GetCurrentImageInfo() {
|
|
return this._sdkInst.GetCurrentImageInfo()
|
|
}
|
|
GetCurrentSurfaceSize() {
|
|
return this._sdkInst.GetCurrentSurfaceSize()
|
|
}
|
|
GetCurrentTexRect() {
|
|
return this._sdkInst.GetCurrentTexRect()
|
|
}
|
|
GetImagePoint(nameOrIndex) {
|
|
return this._sdkInst.GetImagePoint(nameOrIndex)
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectType
|
|
}
|
|
BelongsToObjectClass(objectClass) {
|
|
if (objectClass.IsFamily())
|
|
return objectClass.FamilyHasMember(this.GetObjectClass());
|
|
else
|
|
return this.GetObjectClass() === objectClass
|
|
}
|
|
VerifySupportsSceneGraph() {
|
|
if (!this.GetPlugin().SupportsSceneGraph())
|
|
throw new Error("object does not support scene graph");
|
|
}
|
|
HasParent() {
|
|
return this.GetParent() !== null
|
|
}
|
|
GetParent() {
|
|
const wi = this.GetWorldInfo();
|
|
if (!wi)
|
|
return null;
|
|
const parentWi = wi.GetParent();
|
|
return parentWi ? parentWi.GetInstance() : null
|
|
}
|
|
GetTopParent() {
|
|
const wi = this.GetWorldInfo();
|
|
if (!wi)
|
|
return null;
|
|
const parentWi = wi.GetTopParent();
|
|
return parentWi ? parentWi.GetInstance() : null
|
|
}
|
|
*parents() {
|
|
const wi = this.GetWorldInfo();
|
|
if (!wi)
|
|
return;
|
|
for (const parentWi of wi.parents())
|
|
yield parentWi.GetInstance()
|
|
}
|
|
HasChildren() {
|
|
const wi = this.GetWorldInfo();
|
|
return wi ? wi.HasChildren() : false
|
|
}
|
|
GetChildren() {
|
|
const wi = this.GetWorldInfo();
|
|
if (!wi)
|
|
return [];
|
|
return wi.GetChildren().map(wi=>wi.GetInstance())
|
|
}
|
|
*children() {
|
|
const wi = this.GetWorldInfo();
|
|
if (!wi)
|
|
return;
|
|
for (const childWi of wi.children())
|
|
yield childWi.GetInstance()
|
|
}
|
|
*allChildren() {
|
|
const wi = this.GetWorldInfo();
|
|
if (!wi)
|
|
return;
|
|
for (const childWi of wi.allChildren())
|
|
yield childWi.GetInstance()
|
|
}
|
|
GetChildCount() {
|
|
const wi = this.GetWorldInfo();
|
|
return wi ? wi.GetChildCount() : 0
|
|
}
|
|
GetChildAt(index) {
|
|
const wi = this.GetWorldInfo();
|
|
if (!wi)
|
|
return null;
|
|
const childWi = wi.GetChildAt(index);
|
|
return childWi ? childWi.GetInstance() : null
|
|
}
|
|
AddChild(childInst, opts) {
|
|
this.VerifySupportsSceneGraph();
|
|
childInst.VerifySupportsSceneGraph();
|
|
this.GetWorldInfo().AddChild(childInst.GetWorldInfo(), opts || {})
|
|
}
|
|
RemoveChild(childInst) {
|
|
const wi = this.GetWorldInfo();
|
|
if (!wi)
|
|
return;
|
|
wi.RemoveChild(childInst.GetWorldInfo())
|
|
}
|
|
GetDestroyWithParent() {
|
|
const wi = this.GetWorldInfo();
|
|
return wi ? wi.GetDestroyWithParent() : false
|
|
}
|
|
SetupInitialSceneGraphConnections() {
|
|
const wi = this.GetWorldInfo();
|
|
if (!wi)
|
|
return;
|
|
const childrenData = wi.GetSceneGraphChildrenExportData();
|
|
if (!childrenData)
|
|
return;
|
|
for (const childData of childrenData) {
|
|
const child = this._runtime.GetInstanceByUID(childData[0]);
|
|
if (child) {
|
|
const flags = childData[1];
|
|
this.AddChild(child, {
|
|
transformX: !!(flags >> 0 & 1),
|
|
transformY: !!(flags >> 1 & 1),
|
|
transformWidth: !!(flags >> 2 & 1),
|
|
transformHeight: !!(flags >> 3 & 1),
|
|
transformAngle: !!(flags >> 4 & 1),
|
|
destroyWithParent: !!(flags >> 5 & 1),
|
|
transformZElevation: !!(flags >> 6 & 1)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
IsInContainer() {
|
|
return this._siblings !== null
|
|
}
|
|
_AddSibling(inst) {
|
|
this._siblings.push(inst)
|
|
}
|
|
GetSiblings() {
|
|
return this._siblings
|
|
}
|
|
siblings() {
|
|
return this._siblings
|
|
}
|
|
SetSiblingsSinglePicked() {
|
|
for (const s of this.siblings())
|
|
s.GetObjectClass().GetCurrentSol().SetSinglePicked(s)
|
|
}
|
|
_PushSiblingsToSolInstances() {
|
|
for (const s of this.siblings())
|
|
s.GetObjectClass().GetCurrentSol()._PushInstance(s)
|
|
}
|
|
_SetSiblingsToSolInstancesIndex(i) {
|
|
for (const s of this.siblings())
|
|
s.GetObjectClass().GetCurrentSol()._GetOwnInstances()[i] = s
|
|
}
|
|
_PushSiblingsToSolElseInstances() {
|
|
for (const s of this.siblings())
|
|
s.GetObjectClass().GetCurrentSol()._PushElseInstance(s)
|
|
}
|
|
_SetSiblingsToSolElseInstancesIndex(i) {
|
|
for (const s of this.siblings())
|
|
s.GetObjectClass().GetCurrentSol()._GetOwnElseInstances()[i] = s
|
|
}
|
|
GetPlugin() {
|
|
return this._objectType.GetPlugin()
|
|
}
|
|
_SetIID(i) {
|
|
this._iid = i
|
|
}
|
|
GetIID() {
|
|
this._objectType._UpdateIIDs();
|
|
return this._iid
|
|
}
|
|
GetUID() {
|
|
return this._uid
|
|
}
|
|
GetPUID() {
|
|
return this._puid
|
|
}
|
|
GetBehaviorInstances() {
|
|
return this._behaviorInstances
|
|
}
|
|
GetBehaviorInstanceFromCtor(ctor) {
|
|
if (!ctor)
|
|
return null;
|
|
for (const behInst of this._behaviorInstances)
|
|
if (behInst.GetBehavior()instanceof ctor)
|
|
return behInst;
|
|
return null
|
|
}
|
|
GetBehaviorSdkInstanceFromCtor(ctor) {
|
|
if (!ctor)
|
|
return null;
|
|
const behInst = this.GetBehaviorInstanceFromCtor(ctor);
|
|
if (behInst)
|
|
return behInst.GetSdkInstance();
|
|
else
|
|
return null
|
|
}
|
|
GetBehaviorIndexBySID(sid) {
|
|
const behaviorInstances = this._behaviorInstances;
|
|
for (let i = 0, len = behaviorInstances.length; i < len; ++i)
|
|
if (behaviorInstances[i].GetBehaviorType().GetSID() === sid)
|
|
return i;
|
|
return -1
|
|
}
|
|
GetAllInstanceVariableValues() {
|
|
return this._instVarValues
|
|
}
|
|
_GetAllInstanceVariableNames() {
|
|
return this._objectType._GetAllInstanceVariableNames()
|
|
}
|
|
GetInstanceVariableCount() {
|
|
return this._instVarValues.length
|
|
}
|
|
GetInstanceVariableValue(index) {
|
|
index = index | 0;
|
|
const instVarValues = this._instVarValues;
|
|
if (index < 0 || index >= instVarValues.length)
|
|
throw new RangeError("invalid instance variable");
|
|
return instVarValues[index]
|
|
}
|
|
_GetInstanceVariableValueUnchecked(index) {
|
|
return this._instVarValues[index]
|
|
}
|
|
SetInstanceVariableValue(index, value) {
|
|
index = index | 0;
|
|
const instVarValues = this._instVarValues;
|
|
if (index < 0 || index >= instVarValues.length)
|
|
throw new RangeError("invalid instance variable");
|
|
const lastValue = instVarValues[index];
|
|
if (typeof lastValue === "number")
|
|
if (typeof value === "number")
|
|
instVarValues[index] = value;
|
|
else
|
|
instVarValues[index] = parseFloat(value);
|
|
else if (typeof lastValue === "boolean")
|
|
if (typeof value === "boolean")
|
|
instVarValues[index] = value;
|
|
else
|
|
instVarValues[index] = !!value;
|
|
else if (typeof lastValue === "string")
|
|
if (typeof value === "string")
|
|
instVarValues[index] = value;
|
|
else
|
|
instVarValues[index] = value.toString();
|
|
else
|
|
throw new Error("unknown instance variable type");
|
|
}
|
|
SetInstanceVariableOffset(index, offset) {
|
|
if (offset === 0)
|
|
return;
|
|
index = index | 0;
|
|
const instVarValues = this._instVarValues;
|
|
if (index < 0 || index >= instVarValues.length)
|
|
throw new RangeError("invalid instance variable");
|
|
const lastValue = instVarValues[index];
|
|
if (typeof lastValue === "number")
|
|
if (typeof offset === "number")
|
|
instVarValues[index] += offset;
|
|
else
|
|
instVarValues[index] += parseFloat(offset);
|
|
else if (typeof lastValue === "boolean")
|
|
throw new Error("can not set offset of boolean variable");
|
|
else if (typeof lastValue === "string")
|
|
throw new Error("can not set offset of string variable");
|
|
else
|
|
throw new Error("unknown instance variable type");
|
|
}
|
|
GetSavedDataMap() {
|
|
let ret = savedDataMaps.get(this);
|
|
if (ret)
|
|
return ret;
|
|
ret = new Map;
|
|
savedDataMaps.set(this, ret);
|
|
return ret
|
|
}
|
|
GetUnsavedDataMap() {
|
|
let ret = unsavedDataMaps.get(this);
|
|
if (ret)
|
|
return ret;
|
|
ret = new Map;
|
|
unsavedDataMaps.set(this, ret);
|
|
return ret
|
|
}
|
|
_HasAnyCreateDestroyHandler(name) {
|
|
const objectType = this.GetObjectClass();
|
|
if (objectType.UserScriptDispatcher().HasAnyHandlerFor(name))
|
|
return true;
|
|
for (const family of objectType.GetFamilies())
|
|
if (family.UserScriptDispatcher().HasAnyHandlerFor(name))
|
|
return true;
|
|
if (this._runtime.UserScriptDispatcher().HasAnyHandlerFor(name))
|
|
return true;
|
|
return false
|
|
}
|
|
_TriggerOnCreated() {
|
|
if (this._HasAnyCreateDestroyHandler("instancecreate")) {
|
|
const objectType = this.GetObjectClass();
|
|
const instCreateEvent = new C3.Event("instancecreate");
|
|
instCreateEvent.instance = this.GetInterfaceClass();
|
|
objectType.DispatchUserScriptEvent(instCreateEvent);
|
|
for (const family of objectType.GetFamilies())
|
|
family.DispatchUserScriptEvent(instCreateEvent);
|
|
this._runtime.DispatchUserScriptEvent(instCreateEvent)
|
|
}
|
|
this._runtime.Trigger(this.GetPlugin().constructor.Cnds.OnCreated, this, null)
|
|
}
|
|
_TriggerOnDestroyed() {
|
|
this._runtime.Trigger(this.GetPlugin().constructor.Cnds.OnDestroyed, this, null)
|
|
}
|
|
_FireDestroyedScriptEvents(isEndingLayout) {
|
|
if (this._iScriptInterface) {
|
|
const e = new C3.Event("destroy");
|
|
e.isEndingLayout = isEndingLayout;
|
|
this.DispatchUserScriptEvent(e)
|
|
}
|
|
if (!this._HasAnyCreateDestroyHandler("instancedestroy"))
|
|
return;
|
|
const objectType = this.GetObjectClass();
|
|
const instDestroyEvent = new C3.Event("instancedestroy");
|
|
instDestroyEvent.instance = this.GetInterfaceClass();
|
|
instDestroyEvent.isEndingLayout = isEndingLayout;
|
|
objectType.DispatchUserScriptEvent(instDestroyEvent);
|
|
for (const family of objectType.GetFamilies())
|
|
family.DispatchUserScriptEvent(instDestroyEvent);
|
|
this._runtime.DispatchUserScriptEvent(instDestroyEvent)
|
|
}
|
|
_GetDebuggerProperties() {
|
|
return this._sdkInst.GetDebuggerProperties()
|
|
}
|
|
SaveToJson(mode="full") {
|
|
const o = {};
|
|
if (mode === "full")
|
|
o["uid"] = this.GetUID();
|
|
else
|
|
o["c3"] = true;
|
|
if (mode !== "visual-state") {
|
|
const savedData = savedDataMaps.get(this);
|
|
if (savedData && savedData.size)
|
|
o["ex"] = C3.ToSuperJSON(savedData);
|
|
if (this.GetTimeScale() !== -1)
|
|
o["mts"] = this.GetTimeScale();
|
|
if (this._objectType.GetInstanceVariablesCount() > 0) {
|
|
const ivs = {};
|
|
const ivSids = this._objectType.GetInstanceVariableSIDs();
|
|
for (let i = 0, len = this._instVarValues.length; i < len; ++i)
|
|
ivs[ivSids[i].toString()] = this._instVarValues[i];
|
|
o["ivs"] = ivs
|
|
}
|
|
if (this._behaviorInstances.length) {
|
|
const behs = {};
|
|
for (const behInst of this._behaviorInstances) {
|
|
const data = behInst.SaveToJson();
|
|
if (data)
|
|
behs[behInst.GetBehaviorType().GetSID().toString()] = data
|
|
}
|
|
o["behs"] = behs
|
|
}
|
|
}
|
|
if (this._worldInfo)
|
|
o["w"] = this._worldInfo._SaveToJson();
|
|
const ownData = this._sdkInst.SaveToJson();
|
|
if (ownData)
|
|
o["data"] = ownData;
|
|
return o
|
|
}
|
|
LoadFromJson(o, mode="full") {
|
|
if (mode === "full")
|
|
this._uid = o["uid"];
|
|
else if (!o["c3"])
|
|
return;
|
|
if (mode !== "visual-state") {
|
|
let savedData = savedDataMaps.get(this);
|
|
if (savedData) {
|
|
savedData.clear();
|
|
savedDataMaps.delete(this)
|
|
}
|
|
const ex = o["ex"];
|
|
if (ex) {
|
|
savedData = C3.FromSuperJSON(ex);
|
|
savedDataMaps.set(this, savedData)
|
|
}
|
|
this._timeScale = o.hasOwnProperty("mts") ? o["mts"] : -1;
|
|
const ivs = o["ivs"];
|
|
if (ivs)
|
|
for (const [sidStr,value] of Object.entries(ivs)) {
|
|
const sid = parseInt(sidStr, 10);
|
|
const index = this._objectType.GetInstanceVariableIndexBySID(sid);
|
|
if (index < 0 || index >= this._instVarValues.length)
|
|
continue;
|
|
let v = value;
|
|
if (v === null)
|
|
v = NaN;
|
|
this._instVarValues[index] = v
|
|
}
|
|
}
|
|
if (this.GetPlugin().IsWorldType()) {
|
|
const worldData = o["w"];
|
|
const layerSid = worldData["l"];
|
|
if (this._worldInfo.GetLayer().GetSID() !== layerSid) {
|
|
const oldLayer = this._worldInfo.GetLayer();
|
|
const newLayer = oldLayer.GetLayout().GetLayerBySID(layerSid);
|
|
if (newLayer) {
|
|
this._worldInfo._SetLayer(newLayer);
|
|
oldLayer._RemoveInstance(this, true);
|
|
newLayer._AddInstance(this, true);
|
|
newLayer.SetZIndicesChanged();
|
|
this._worldInfo.SetBboxChanged()
|
|
} else if (mode === "full")
|
|
this._runtime.DestroyInstance(this)
|
|
}
|
|
this._worldInfo._LoadFromJson(worldData)
|
|
}
|
|
if (mode !== "visual-state") {
|
|
const behs = o["behs"];
|
|
if (behs)
|
|
for (const [sidStr,data] of Object.entries(behs)) {
|
|
const sid = parseInt(sidStr, 10);
|
|
const index = this.GetBehaviorIndexBySID(sid);
|
|
if (index < 0 || index >= this._behaviorInstances.length)
|
|
continue;
|
|
this._behaviorInstances[index].LoadFromJson(data)
|
|
}
|
|
}
|
|
const ownData = o["data"];
|
|
if (ownData)
|
|
this._sdkInst.LoadFromJson(ownData)
|
|
}
|
|
GetInterfaceClass() {
|
|
return this._iScriptInterface || this._InitUserScriptInterface()
|
|
}
|
|
_InitUserScriptInterface() {
|
|
const DefaultScriptClass = this._worldInfo ? self.IWorldInstance : IInstance;
|
|
const SdkScriptClass = this._sdkInst.GetScriptInterfaceClass();
|
|
const UserScriptClass = this._objectType._GetUserScriptInstanceClass();
|
|
const ScriptInterfaceClass = UserScriptClass || SdkScriptClass || DefaultScriptClass;
|
|
IInstance._Init(this);
|
|
this._iScriptInterface = new ScriptInterfaceClass;
|
|
IInstance._Init(null);
|
|
if (SdkScriptClass && !(this._iScriptInterface instanceof DefaultScriptClass))
|
|
throw new TypeError(`script interface class '${SdkScriptClass.name}' does not extend the right base class '${DefaultScriptClass.name}'`);
|
|
if (UserScriptClass) {
|
|
const ExpectedBaseClass = SdkScriptClass || DefaultScriptClass;
|
|
if (!(this._iScriptInterface instanceof ExpectedBaseClass))
|
|
throw new TypeError(`setInstanceClass(): class '${UserScriptClass.name}' does not extend the right base class '${ExpectedBaseClass.name}'`);
|
|
}
|
|
return this._iScriptInterface
|
|
}
|
|
_GetInstVarsScriptDescriptor(instDescriptors) {
|
|
if (this._instVarValues.length === 0)
|
|
return;
|
|
const varDescriptors = {};
|
|
const instVarJsPropNames = this._objectType._GetAllInstanceVariableJsPropNames();
|
|
for (let i = 0, len = instVarJsPropNames.length; i < len; ++i)
|
|
varDescriptors[instVarJsPropNames[i]] = {
|
|
configurable: false,
|
|
enumerable: true,
|
|
get: C3.Instance.prototype._GetInstanceVariableValueUnchecked.bind(this, i),
|
|
set: C3.Instance.prototype.SetInstanceVariableValue.bind(this, i)
|
|
};
|
|
const instVarsObj = Object.create(Object.prototype, varDescriptors);
|
|
instDescriptors.instVars = {
|
|
value: instVarsObj,
|
|
writable: false
|
|
}
|
|
}
|
|
_GetBehaviorsScriptDescriptor(instDescriptors) {
|
|
const behaviorInstances = this._behaviorInstances;
|
|
if (behaviorInstances.length === 0)
|
|
return;
|
|
const behDescriptors = {};
|
|
for (const behInst of behaviorInstances)
|
|
behDescriptors[behInst.GetBehaviorType().GetJsPropName()] = {
|
|
value: behInst.GetScriptInterface(),
|
|
writable: false
|
|
};
|
|
const behaviorsObj = Object.create(Object.prototype, behDescriptors);
|
|
instDescriptors.behaviors = {
|
|
value: behaviorsObj,
|
|
writable: false
|
|
}
|
|
}
|
|
DispatchUserScriptEvent(e) {
|
|
e.instance = this.GetInterfaceClass();
|
|
const runtime = this._runtime;
|
|
const shouldTime = runtime.IsDebug() && !runtime.GetEventSheetManager().IsInEventEngine();
|
|
if (shouldTime)
|
|
C3Debugger.StartMeasuringScriptTime();
|
|
this.GetInterfaceClass().dispatchEvent(e);
|
|
if (shouldTime)
|
|
C3Debugger.AddScriptTime()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SceneGraphInfo = class SceneGraphInfo extends C3.DefendedBase {
|
|
constructor(owner) {
|
|
super();
|
|
this._owner = owner;
|
|
this._parent = null;
|
|
this._children = [];
|
|
this._myStartWidth = owner.GetWidth();
|
|
this._myStartHeight = owner.GetHeight();
|
|
this._parentStartAngle = 0
|
|
}
|
|
Release() {
|
|
this._parent = null;
|
|
C3.clearArray(this._children)
|
|
}
|
|
SetParent(parent) {
|
|
this._parent = parent;
|
|
this._parentStartAngle = parent ? parent.GetAngle() : 0
|
|
}
|
|
GetParent() {
|
|
return this._parent
|
|
}
|
|
HasChildren() {
|
|
return this._children.length > 0
|
|
}
|
|
GetChildren() {
|
|
return this._children
|
|
}
|
|
_GetStartWidth() {
|
|
return this._myStartWidth
|
|
}
|
|
_GetStartHeight() {
|
|
return this._myStartHeight
|
|
}
|
|
GetParentScaleX() {
|
|
if (this._owner.GetTransformWithParentWidth())
|
|
return this._parent.GetWidth() / this._parent._GetSceneGraphInfo()._GetStartWidth();
|
|
else
|
|
return 1
|
|
}
|
|
GetParentScaleY() {
|
|
if (this._owner.GetTransformWithParentHeight())
|
|
return this._parent.GetHeight() / this._parent._GetSceneGraphInfo()._GetStartHeight();
|
|
else
|
|
return 1
|
|
}
|
|
GetParentStartAngle() {
|
|
return this._parentStartAngle
|
|
}
|
|
_SaveToJson() {
|
|
return {
|
|
"sw": this._myStartWidth,
|
|
"sh": this._myStartHeight,
|
|
"psa": this._parentStartAngle,
|
|
"c": this._children.map(c=>{
|
|
let flagsStr = "";
|
|
if (c.GetTransformWithParentX())
|
|
flagsStr += "x";
|
|
if (c.GetTransformWithParentY())
|
|
flagsStr += "y";
|
|
if (c.GetTransformWithParentWidth())
|
|
flagsStr += "w";
|
|
if (c.GetTransformWithParentHeight())
|
|
flagsStr += "h";
|
|
if (c.GetTransformWithParentAngle())
|
|
flagsStr += "a";
|
|
if (c.GetTransformWithParentZElevation())
|
|
flagsStr += "z";
|
|
if (c.GetDestroyWithParent())
|
|
flagsStr += "d";
|
|
return {
|
|
"uid": c.GetInstance().GetUID(),
|
|
"f": flagsStr
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
_LoadFromJson(o) {
|
|
this._myStartWidth = o["sw"];
|
|
this._myStartHeight = o["sh"];
|
|
this._parentStartAngle = o["psa"]
|
|
}
|
|
_OnAfterLoad(o) {
|
|
const owner = this._owner;
|
|
const runtime = owner.GetRuntime();
|
|
for (const childData of o["c"]) {
|
|
const childUid = childData["uid"];
|
|
const childInst = runtime.GetInstanceByUID(childUid);
|
|
const childWi = childInst.GetWorldInfo();
|
|
const flagsStr = childData["f"];
|
|
const opts = {};
|
|
opts.transformX = flagsStr.includes("x");
|
|
opts.transformY = flagsStr.includes("y");
|
|
opts.transformWidth = flagsStr.includes("w");
|
|
opts.transformHeight = flagsStr.includes("h");
|
|
opts.transformAngle = flagsStr.includes("a");
|
|
opts.transformZElevation = flagsStr.includes("z");
|
|
opts.destroyWithParent = flagsStr.includes("d");
|
|
owner.AddChild(childWi, opts)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tempRect = C3.New(C3.Rect);
|
|
const tempQuad = C3.New(C3.Quad);
|
|
const bboxChangeEvent = C3.New(C3.Event, "bboxchange", false);
|
|
const tempColor = C3.New(C3.Color, 0, 0, 0, 0);
|
|
const tempCollisionPoly = C3.New(C3.CollisionPoly);
|
|
const DEFAULT_COLOR = C3.New(C3.Color, 1, 1, 1, 1);
|
|
const DEFAULT_RENDER_CELLS = C3.New(C3.Rect, 0, 0, -1, -1);
|
|
const DEFAULT_COLLISION_CELLS = C3.New(C3.Rect, 0, 0, -1, -1);
|
|
const VALID_SET_MESH_POINT_MODES = new Set(["absolute", "relative"]);
|
|
const EMPTY_ARRAY = [];
|
|
let enableUpdateRendererStateGroup = true;
|
|
const FLAG_IS_VISIBLE = 1 << 0;
|
|
const FLAG_BBOX_CHANGED = 1 << 1;
|
|
const FLAG_ENABLE_BBOX_CHANGED_EVENT = 1 << 2;
|
|
const FLAG_COLLISION_ENABLED = 1 << 3;
|
|
const FLAG_COLLISION_CELL_CHANGED = 1 << 4;
|
|
const FLAG_SOLID_FILTER_INCLUSIVE = 1 << 5;
|
|
const FLAG_HAS_ANY_ACTIVE_EFFECT = 1 << 6;
|
|
const FLAG_IS_ROTATABLE = 1 << 7;
|
|
const FLAG_DESTROY_WITH_PARENT = 1 << 8;
|
|
const FLAG_TRANSFORM_WITH_PARENT_X = 1 << 9;
|
|
const FLAG_TRANSFORM_WITH_PARENT_Y = 1 << 10;
|
|
const FLAG_TRANSFORM_WITH_PARENT_W = 1 << 11;
|
|
const FLAG_TRANSFORM_WITH_PARENT_H = 1 << 12;
|
|
const FLAG_TRANSFORM_WITH_PARENT_A = 1 << 13;
|
|
const FLAG_TRANSFORM_WITH_PARENT_Z_ELEVATION = 1 << 14;
|
|
const MASK_ALL_SCENE_GRAPH_FLAGS = FLAG_DESTROY_WITH_PARENT | FLAG_TRANSFORM_WITH_PARENT_X | FLAG_TRANSFORM_WITH_PARENT_Y | FLAG_TRANSFORM_WITH_PARENT_W | FLAG_TRANSFORM_WITH_PARENT_H | FLAG_TRANSFORM_WITH_PARENT_A | FLAG_TRANSFORM_WITH_PARENT_Z_ELEVATION;
|
|
const FLAG_MESH_CHANGED = 1 << 15;
|
|
const FLAG_PHYSICS_BODY_CHANGED = 1 << 16;
|
|
const FLAG_SIN_COS_ANGLE_CHANGED = 1 << 17;
|
|
const FLAG_BLEND_MODE_BIT_OFFSET = 26;
|
|
const FLAG_BLEND_MODE_MASK = 31 << FLAG_BLEND_MODE_BIT_OFFSET;
|
|
C3.WorldInfo = class WorldInfo extends C3.DefendedBase {
|
|
constructor(inst, layer) {
|
|
super();
|
|
this._inst = inst;
|
|
this._objectClass = inst.GetObjectClass();
|
|
this._runtime = inst.GetRuntime();
|
|
this._layer = layer;
|
|
this._zIndex = -1;
|
|
this._flags = FLAG_IS_VISIBLE | FLAG_BBOX_CHANGED | FLAG_COLLISION_ENABLED | FLAG_COLLISION_CELL_CHANGED | FLAG_MESH_CHANGED | FLAG_PHYSICS_BODY_CHANGED;
|
|
if (this._objectClass.GetPlugin().IsRotatable())
|
|
this._flags |= FLAG_IS_ROTATABLE;
|
|
this._x = NaN;
|
|
this._y = NaN;
|
|
this._zElevation = NaN;
|
|
this._w = NaN;
|
|
this._h = NaN;
|
|
this._a = NaN;
|
|
this._sinA = NaN;
|
|
this._cosA = NaN;
|
|
this._ox = NaN;
|
|
this._oy = NaN;
|
|
this._boundingBox = C3.New(C3.Rect);
|
|
this._boundingQuad = C3.New(C3.Quad);
|
|
this._collisionCells = DEFAULT_COLLISION_CELLS;
|
|
this._renderCells = DEFAULT_RENDER_CELLS;
|
|
this._sourceCollisionPoly = null;
|
|
this._transformedPolyInfo = null;
|
|
this._solidFilterTags = null;
|
|
this._color = DEFAULT_COLOR;
|
|
this._colorPremultiplied = DEFAULT_COLOR;
|
|
this._stateGroup = null;
|
|
this._instanceEffectList = null;
|
|
if (this._inst.GetObjectClass().UsesEffects())
|
|
this._instanceEffectList = C3.New(C3.InstanceEffectList, this._inst, this);
|
|
this._sceneGraphInfo = null;
|
|
this._sceneGraphFlagsExportData = NaN;
|
|
this._sceneGraphChildrenExportData = null;
|
|
this._meshInfo = null
|
|
}
|
|
Release() {
|
|
if (this._stateGroup) {
|
|
this._runtime.GetRenderer().ReleaseStateGroup(this._stateGroup);
|
|
this._stateGroup = null
|
|
}
|
|
this._sourceCollisionPoly = null;
|
|
if (this._transformedPolyInfo) {
|
|
this._transformedPolyInfo.poly.Release();
|
|
this._transformedPolyInfo = null
|
|
}
|
|
if (this._solidFilterTags) {
|
|
this._solidFilterTags.clear();
|
|
this._solidFilterTags = null
|
|
}
|
|
this.ReleaseMesh();
|
|
if (this.HasParent())
|
|
this.GetParent().RemoveChild(this);
|
|
if (this.HasChildren()) {
|
|
const childrenToRelease = [...this.GetChildren()];
|
|
for (const child of childrenToRelease)
|
|
this.RemoveChild(child)
|
|
}
|
|
this._ReleaseSceneGraphInfo();
|
|
this._inst = null;
|
|
this._objectClass = null;
|
|
this._runtime = null;
|
|
this._layer = null
|
|
}
|
|
Init(data) {
|
|
enableUpdateRendererStateGroup = false;
|
|
this.SetXY(data[0], data[1]);
|
|
this.SetZElevation(data[2]);
|
|
this.SetSize(data[3], data[4]);
|
|
if (this.IsRotatable())
|
|
this.SetAngle(data[6]);
|
|
else
|
|
this._a = 0;
|
|
tempColor.setFromJSON(data[7]);
|
|
this._SetColor(tempColor);
|
|
this.SetOriginX(data[8]);
|
|
this.SetOriginY(data[9]);
|
|
this.SetBlendMode(data[10]);
|
|
if (this._instanceEffectList)
|
|
this._instanceEffectList._LoadEffectParameters(data[12]);
|
|
if (data[14]) {
|
|
this._sceneGraphFlagsExportData = data[14][0];
|
|
this._sceneGraphChildrenExportData = data[14][1]
|
|
}
|
|
enableUpdateRendererStateGroup = true;
|
|
this._UpdateRendererStateGroup()
|
|
}
|
|
InitNoData() {
|
|
this._x = 0;
|
|
this._y = 0;
|
|
this._zElevation = 0;
|
|
this._w = 0;
|
|
this._h = 0;
|
|
this._a = 0;
|
|
this._sinA = 0;
|
|
this._cosA = 1;
|
|
this._ox = 0;
|
|
this._oy = 0;
|
|
this._UpdateRendererStateGroup()
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectClass
|
|
}
|
|
GetInstance() {
|
|
return this._inst
|
|
}
|
|
_GetParentOffsetAngle() {
|
|
if (this.GetTransformWithParentAngle())
|
|
return this.GetParent().GetAngle() - this._sceneGraphInfo.GetParentStartAngle();
|
|
else
|
|
return 0
|
|
}
|
|
SetX(x) {
|
|
x = +x;
|
|
if (this.GetTransformWithParentX()) {
|
|
const sgi = this._sceneGraphInfo;
|
|
const dx = x - this.GetX();
|
|
const da = -this._GetParentOffsetAngle();
|
|
if (da === 0)
|
|
this._x += dx / sgi.GetParentScaleX();
|
|
else {
|
|
this._x += Math.cos(da) * dx / sgi.GetParentScaleX();
|
|
if (this.GetTransformWithParentY())
|
|
this._y += Math.sin(da) * dx / sgi.GetParentScaleY()
|
|
}
|
|
} else
|
|
this._x = x
|
|
}
|
|
OffsetX(x) {
|
|
x = +x;
|
|
if (this.GetTransformWithParentX())
|
|
this.SetX(this.GetX() + x);
|
|
else
|
|
this._x += x
|
|
}
|
|
GetX() {
|
|
if (this.GetTransformWithParentX()) {
|
|
let x = this._x;
|
|
const sgi = this._sceneGraphInfo;
|
|
const parent = this.GetParent();
|
|
const da = this._GetParentOffsetAngle();
|
|
if (da === 0)
|
|
x *= sgi.GetParentScaleX();
|
|
else {
|
|
x = x * sgi.GetParentScaleX() * Math.cos(da);
|
|
if (this.GetTransformWithParentY())
|
|
x -= this._y * sgi.GetParentScaleY() * Math.sin(da)
|
|
}
|
|
return parent.GetX() + x
|
|
} else
|
|
return this._x
|
|
}
|
|
SetY(y) {
|
|
y = +y;
|
|
if (this.GetTransformWithParentY()) {
|
|
const sgi = this._sceneGraphInfo;
|
|
const dy = y - this.GetY();
|
|
const da = -this._GetParentOffsetAngle();
|
|
if (da === 0)
|
|
this._y += dy / sgi.GetParentScaleY();
|
|
else {
|
|
if (this.GetTransformWithParentX())
|
|
this._x -= Math.sin(da) * dy / sgi.GetParentScaleX();
|
|
this._y += Math.cos(da) * dy / sgi.GetParentScaleY()
|
|
}
|
|
} else
|
|
this._y = y
|
|
}
|
|
OffsetY(y) {
|
|
y = +y;
|
|
if (this.GetTransformWithParentY())
|
|
this.SetY(this.GetY() + y);
|
|
else
|
|
this._y += y
|
|
}
|
|
GetY() {
|
|
if (this.GetTransformWithParentY()) {
|
|
let y = this._y;
|
|
const sgi = this._sceneGraphInfo;
|
|
const parent = this.GetParent();
|
|
const da = this._GetParentOffsetAngle();
|
|
if (da === 0)
|
|
y *= sgi.GetParentScaleY();
|
|
else {
|
|
y = y * sgi.GetParentScaleY() * Math.cos(da);
|
|
if (this.GetTransformWithParentX())
|
|
y += this._x * sgi.GetParentScaleX() * Math.sin(da)
|
|
}
|
|
return parent.GetY() + y
|
|
} else
|
|
return this._y
|
|
}
|
|
SetXY(x, y) {
|
|
x = +x;
|
|
y = +y;
|
|
if (this.GetTransformWithParentXOrY()) {
|
|
const isTransformX = this.GetTransformWithParentX();
|
|
const isTransformY = this.GetTransformWithParentY();
|
|
const sgi = this._sceneGraphInfo;
|
|
const dx = x - this.GetX();
|
|
const dy = y - this.GetY();
|
|
const da = -this._GetParentOffsetAngle();
|
|
if (da === 0) {
|
|
if (isTransformX)
|
|
this._x += dx / sgi.GetParentScaleX();
|
|
else
|
|
this._x = x;
|
|
if (isTransformY)
|
|
this._y += dy / sgi.GetParentScaleY();
|
|
else
|
|
this._y = y
|
|
} else {
|
|
const sinDa = Math.sin(da);
|
|
const cosDa = Math.cos(da);
|
|
if (isTransformX)
|
|
if (isTransformY)
|
|
this._x += (cosDa * dx - sinDa * dy) / sgi.GetParentScaleX();
|
|
else
|
|
this._x += cosDa * dx / sgi.GetParentScaleX();
|
|
else
|
|
this._x = x;
|
|
if (isTransformY)
|
|
if (isTransformX)
|
|
this._y += (sinDa * dx + cosDa * dy) / sgi.GetParentScaleY();
|
|
else
|
|
this._y += cosDa * dy / sgi.GetParentScaleY();
|
|
else
|
|
this._y = y
|
|
}
|
|
} else {
|
|
this._x = x;
|
|
this._y = y
|
|
}
|
|
}
|
|
OffsetXY(x, y) {
|
|
x = +x;
|
|
y = +y;
|
|
if (this.GetTransformWithParentXOrY())
|
|
this.SetXY(this.GetX() + x, this.GetY() + y);
|
|
else {
|
|
this._x += x;
|
|
this._y += y
|
|
}
|
|
}
|
|
EqualsXY(x, y) {
|
|
return this.GetX() === x && this.GetY() === y
|
|
}
|
|
SetZElevation(z) {
|
|
z = +z;
|
|
if (this.GetTransformWithParentZElevation())
|
|
z -= this.GetParent().GetZElevation();
|
|
if (this._zElevation === z)
|
|
return;
|
|
this._zElevation = z;
|
|
this._UpdateZElevation();
|
|
const layer = this.GetLayer();
|
|
if (this._zElevation !== 0)
|
|
layer._SetAnyInstanceZElevated();
|
|
layer.SetZIndicesChanged()
|
|
}
|
|
_UpdateZElevation() {
|
|
this._UpdateRendererStateGroup();
|
|
if (this.HasChildren()) {
|
|
const children = this.GetChildren();
|
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
const child = children[i];
|
|
if (child.GetTransformWithParentZElevation())
|
|
child._UpdateZElevation()
|
|
}
|
|
}
|
|
}
|
|
OffsetZElevation(z) {
|
|
this.SetZElevation(this.GetZElevation() + z)
|
|
}
|
|
GetZElevation() {
|
|
if (this.GetTransformWithParentZElevation())
|
|
return this.GetParent().GetZElevation() + this._zElevation;
|
|
else
|
|
return this._zElevation
|
|
}
|
|
GetTotalZElevation() {
|
|
return this.GetLayer().GetZElevation() + this.GetZElevation()
|
|
}
|
|
SetWidth(w) {
|
|
w = +w;
|
|
if (this.GetTransformWithParentWidth())
|
|
this._w *= w / this.GetWidth();
|
|
else
|
|
this._w = w
|
|
}
|
|
OffsetWidth(w) {
|
|
w = +w;
|
|
if (this.GetTransformWithParentWidth())
|
|
this.SetWidth(this.GetWidth() + w);
|
|
else
|
|
this._w += w
|
|
}
|
|
GetWidth() {
|
|
if (this.GetTransformWithParentWidth())
|
|
return this.GetParent().GetWidth() * this._w;
|
|
else
|
|
return this._w
|
|
}
|
|
SetHeight(h) {
|
|
h = +h;
|
|
if (this.GetTransformWithParentHeight())
|
|
this._h *= h / this.GetHeight();
|
|
else
|
|
this._h = h
|
|
}
|
|
OffsetHeight(h) {
|
|
h = +h;
|
|
if (this.GetTransformWithParentHeight())
|
|
this.SetHeight(this.GetHeight() + h);
|
|
else
|
|
this._h += h
|
|
}
|
|
GetHeight() {
|
|
if (this.GetTransformWithParentHeight())
|
|
return this.GetParent().GetHeight() * this._h;
|
|
else
|
|
return this._h
|
|
}
|
|
SetSize(w, h) {
|
|
w = +w;
|
|
h = +h;
|
|
if (this.GetTransformWithParentWidth())
|
|
this._w *= w / this.GetWidth();
|
|
else
|
|
this._w = w;
|
|
if (this.GetTransformWithParentHeight())
|
|
this._h *= h / this.GetHeight();
|
|
else
|
|
this._h = h
|
|
}
|
|
GetSceneGraphScale() {
|
|
if (this.HasParent()) {
|
|
const sgi = this._sceneGraphInfo;
|
|
return Math.min(sgi.GetParentScaleX(), sgi.GetParentScaleY())
|
|
} else
|
|
return 1
|
|
}
|
|
IsRotatable() {
|
|
return (this._flags & FLAG_IS_ROTATABLE) !== 0
|
|
}
|
|
SetAngle(a) {
|
|
a = +a;
|
|
if (!this.IsRotatable())
|
|
return;
|
|
if (this.GetTransformWithParentAngle())
|
|
a -= this.GetParent().GetAngle();
|
|
a = C3.clampAngle(a);
|
|
if (this._a === a)
|
|
return;
|
|
this._a = a;
|
|
this._MarkSinCosAngleChanged()
|
|
}
|
|
OffsetAngle(a) {
|
|
a = +a;
|
|
if (a === 0 || !this.IsRotatable())
|
|
return;
|
|
this._a = C3.clampAngle(this._a + a);
|
|
this._MarkSinCosAngleChanged()
|
|
}
|
|
_MarkSinCosAngleChanged() {
|
|
this._flags |= FLAG_SIN_COS_ANGLE_CHANGED;
|
|
if (this.HasChildren()) {
|
|
const children = this.GetChildren();
|
|
for (let i = 0, len = children.length; i < len; i++)
|
|
children[i]._MarkSinCosAngleChanged()
|
|
}
|
|
}
|
|
GetAngle() {
|
|
if (this.GetTransformWithParentAngle())
|
|
return C3.clampAngle(this.GetParent().GetAngle() + this._a);
|
|
else
|
|
return this._a
|
|
}
|
|
_MaybeUpdateSinCosAngle() {
|
|
const flags = this._flags;
|
|
if ((flags & FLAG_SIN_COS_ANGLE_CHANGED) === 0)
|
|
return;
|
|
const a = this.GetAngle();
|
|
this._sinA = Math.sin(a);
|
|
this._cosA = Math.cos(a);
|
|
this._flags = flags & ~FLAG_SIN_COS_ANGLE_CHANGED
|
|
}
|
|
GetSinAngle() {
|
|
this._MaybeUpdateSinCosAngle();
|
|
return this._sinA
|
|
}
|
|
GetCosAngle() {
|
|
this._MaybeUpdateSinCosAngle();
|
|
return this._cosA
|
|
}
|
|
SetOriginX(x) {
|
|
this._ox = +x
|
|
}
|
|
OffsetOriginX(x) {
|
|
this._ox += +x
|
|
}
|
|
GetOriginX() {
|
|
return this._ox
|
|
}
|
|
SetOriginY(y) {
|
|
this._oy = +y
|
|
}
|
|
OffsetOriginY(y) {
|
|
this._oy += +y
|
|
}
|
|
GetOriginY() {
|
|
return this._oy
|
|
}
|
|
_SetColor(c) {
|
|
if (this._color.equals(c))
|
|
return;
|
|
if (this._color === DEFAULT_COLOR) {
|
|
this._color = C3.New(C3.Color, c);
|
|
this._colorPremultiplied = C3.New(C3.Color, c);
|
|
this._colorPremultiplied.premultiply()
|
|
} else if (c.equalsRgba(1, 1, 1, 1)) {
|
|
this._color = DEFAULT_COLOR;
|
|
this._colorPremultiplied = DEFAULT_COLOR
|
|
} else {
|
|
this._color.set(c);
|
|
this._colorPremultiplied.set(c);
|
|
this._colorPremultiplied.premultiply()
|
|
}
|
|
this._UpdateRendererStateGroup()
|
|
}
|
|
SetOpacity(o) {
|
|
o = C3.clamp(+o, 0, 1);
|
|
if (this._color.a === o)
|
|
return;
|
|
tempColor.copyRgb(this._color);
|
|
tempColor.a = o;
|
|
this._SetColor(tempColor)
|
|
}
|
|
OffsetOpacity(o) {
|
|
this.SetOpacity(this.GetOpacity() + o)
|
|
}
|
|
GetOpacity() {
|
|
return this._color.a
|
|
}
|
|
SetUnpremultipliedColor(c) {
|
|
if (this._color.equalsIgnoringAlpha(c))
|
|
return;
|
|
tempColor.copyRgb(c);
|
|
tempColor.a = this._color.a;
|
|
this._SetColor(tempColor)
|
|
}
|
|
SetUnpremultipliedColorRGB(r, g, b) {
|
|
tempColor.setRgb(r, g, b);
|
|
this.SetUnpremultipliedColor(tempColor)
|
|
}
|
|
OffsetUnpremultipliedColorRGB(r, g, b) {
|
|
if (r === 0 && g === 0 && b === 0)
|
|
return;
|
|
tempColor.copyRgb(this._color);
|
|
tempColor.r += r;
|
|
tempColor.g += g;
|
|
tempColor.b += b;
|
|
this.SetUnpremultipliedColor(tempColor)
|
|
}
|
|
GetUnpremultipliedColor() {
|
|
return this._color
|
|
}
|
|
GetPremultipliedColor() {
|
|
return this._colorPremultiplied
|
|
}
|
|
GetDestroyWithParent() {
|
|
return (this._flags & FLAG_DESTROY_WITH_PARENT) !== 0
|
|
}
|
|
SetDestroyWithParent(d) {
|
|
this._SetFlag(FLAG_DESTROY_WITH_PARENT, d)
|
|
}
|
|
GetTransformWithParentX() {
|
|
return (this._flags & FLAG_TRANSFORM_WITH_PARENT_X) !== 0
|
|
}
|
|
SetTransformWithParentX(tpx) {
|
|
this._SetFlag(FLAG_TRANSFORM_WITH_PARENT_X, tpx)
|
|
}
|
|
GetTransformWithParentY() {
|
|
return (this._flags & FLAG_TRANSFORM_WITH_PARENT_Y) !== 0
|
|
}
|
|
GetTransformWithParentXOrY() {
|
|
return (this._flags & (FLAG_TRANSFORM_WITH_PARENT_X | FLAG_TRANSFORM_WITH_PARENT_Y)) !== 0
|
|
}
|
|
SetTransformWithParentY(tpx) {
|
|
this._SetFlag(FLAG_TRANSFORM_WITH_PARENT_Y, tpx)
|
|
}
|
|
GetTransformWithParentWidth() {
|
|
return (this._flags & FLAG_TRANSFORM_WITH_PARENT_W) !== 0
|
|
}
|
|
SetTransformWithParentWidth(tpw) {
|
|
this._SetFlag(FLAG_TRANSFORM_WITH_PARENT_W, tpw)
|
|
}
|
|
GetTransformWithParentHeight() {
|
|
return (this._flags & FLAG_TRANSFORM_WITH_PARENT_H) !== 0
|
|
}
|
|
SetTransformWithParentHeight(tph) {
|
|
this._SetFlag(FLAG_TRANSFORM_WITH_PARENT_H, tph)
|
|
}
|
|
GetTransformWithParentAngle() {
|
|
return (this._flags & FLAG_TRANSFORM_WITH_PARENT_A) !== 0
|
|
}
|
|
SetTransformWithParentAngle(tpa) {
|
|
this._SetFlag(FLAG_TRANSFORM_WITH_PARENT_A, tpa)
|
|
}
|
|
GetTransformWithParentZElevation() {
|
|
return (this._flags & FLAG_TRANSFORM_WITH_PARENT_Z_ELEVATION) !== 0
|
|
}
|
|
SetTransformWithParentZElevation(tpz) {
|
|
this._SetFlag(FLAG_TRANSFORM_WITH_PARENT_Z_ELEVATION, tpz)
|
|
}
|
|
_ClearAllSceneGraphFlags() {
|
|
this._flags &= ~MASK_ALL_SCENE_GRAPH_FLAGS
|
|
}
|
|
AddChild(child, opts) {
|
|
if (child === this)
|
|
return;
|
|
if (child.HasParent())
|
|
return;
|
|
if (this._HasChildRecursive(child))
|
|
return;
|
|
if (this._HasAnyParent(child))
|
|
return;
|
|
const absX = child.GetX();
|
|
const absY = child.GetY();
|
|
const absW = child.GetWidth();
|
|
const absH = child.GetHeight();
|
|
const absA = child.GetAngle();
|
|
const absZElevation = child.GetZElevation();
|
|
child._SetParent(this);
|
|
child.SetTransformWithParentX(opts.transformX);
|
|
child.SetTransformWithParentY(opts.transformY);
|
|
child.SetTransformWithParentWidth(opts.transformWidth);
|
|
child.SetTransformWithParentHeight(opts.transformHeight);
|
|
child.SetTransformWithParentAngle(opts.transformAngle);
|
|
child.SetTransformWithParentZElevation(opts.transformZElevation);
|
|
child.SetDestroyWithParent(opts.destroyWithParent);
|
|
if (opts.transformX)
|
|
child._x = absX - this.GetX();
|
|
if (opts.transformY)
|
|
child._y = absY - this.GetY();
|
|
if (opts.transformWidth)
|
|
child._w = absW / this.GetWidth();
|
|
if (opts.transformHeight)
|
|
child._h = absH / this.GetHeight();
|
|
if (opts.transformAngle)
|
|
child._a = absA - this.GetAngle();
|
|
if (opts.transformZElevation)
|
|
child._zElevation = absZElevation - this.GetZElevation();
|
|
this._AddChildToSceneGraphInfo(child);
|
|
this.SetBboxChanged()
|
|
}
|
|
RemoveChild(child) {
|
|
if (child.GetParent() !== this)
|
|
return;
|
|
const absX = child.GetX();
|
|
const absY = child.GetY();
|
|
const absW = child.GetWidth();
|
|
const absH = child.GetHeight();
|
|
const absA = child.GetAngle();
|
|
const absZElevation = child.GetZElevation();
|
|
child._SetParent(null);
|
|
child._ClearAllSceneGraphFlags();
|
|
child.SetXY(absX, absY);
|
|
child.SetSize(absW, absH);
|
|
child.SetAngle(absA);
|
|
child.SetZElevation(absZElevation);
|
|
this._RemoveChildFromSceneGraphInfo(child);
|
|
this.SetBboxChanged()
|
|
}
|
|
_ResetAllSceneGraphState() {
|
|
for (const c of this.children())
|
|
this.RemoveChild(c);
|
|
const parent = this.GetParent();
|
|
if (parent)
|
|
parent.RemoveChild(this);
|
|
this._ClearAllSceneGraphFlags()
|
|
}
|
|
HasParent() {
|
|
return this.GetParent() !== null
|
|
}
|
|
GetParent() {
|
|
const sgi = this._sceneGraphInfo;
|
|
return sgi !== null ? sgi.GetParent() : null
|
|
}
|
|
GetTopParent() {
|
|
let p = this;
|
|
while (p.HasParent())
|
|
p = p.GetParent();
|
|
return p
|
|
}
|
|
*parents() {
|
|
let parent = this.GetParent();
|
|
while (parent) {
|
|
yield parent;
|
|
parent = parent.GetParent()
|
|
}
|
|
}
|
|
HasChild(child) {
|
|
return this.GetChildren().includes(child)
|
|
}
|
|
HasChildren() {
|
|
const sgi = this._sceneGraphInfo;
|
|
return sgi !== null ? sgi.HasChildren() : false
|
|
}
|
|
GetChildren() {
|
|
const sgi = this._sceneGraphInfo;
|
|
return sgi !== null ? sgi.GetChildren() : EMPTY_ARRAY
|
|
}
|
|
children() {
|
|
return this.GetChildren()
|
|
}
|
|
*allChildren() {
|
|
for (const child of this.children()) {
|
|
yield child;
|
|
yield*child.allChildren()
|
|
}
|
|
}
|
|
GetChildCount() {
|
|
return this.GetChildren().length
|
|
}
|
|
GetChildAt(index) {
|
|
const children = this.GetChildren();
|
|
index = Math.floor(+index);
|
|
if (index < 0 || index >= children.length)
|
|
return null;
|
|
return children[index]
|
|
}
|
|
_CreateSceneGraphInfo(parent) {
|
|
if (!this._sceneGraphInfo)
|
|
this._sceneGraphInfo = C3.New(C3.SceneGraphInfo, this);
|
|
if (parent)
|
|
this._sceneGraphInfo.SetParent(parent)
|
|
}
|
|
_GetSceneGraphInfo() {
|
|
return this._sceneGraphInfo
|
|
}
|
|
_ReleaseSceneGraphInfo() {
|
|
if (!this._sceneGraphInfo)
|
|
return;
|
|
this._sceneGraphInfo.Release();
|
|
this._sceneGraphInfo = null
|
|
}
|
|
_SetParent(parent) {
|
|
if (parent) {
|
|
parent._CreateSceneGraphInfo(null);
|
|
this._CreateSceneGraphInfo(parent)
|
|
} else {
|
|
if (this._sceneGraphInfo)
|
|
this._sceneGraphInfo.SetParent(null);
|
|
if (!this.HasChildren())
|
|
this._ReleaseSceneGraphInfo()
|
|
}
|
|
}
|
|
_HasAnyParent(child) {
|
|
if (!this.HasParent())
|
|
return false;
|
|
const parent = this.GetParent();
|
|
if (parent === child)
|
|
return true;
|
|
return parent._HasAnyParent(child)
|
|
}
|
|
_HasChildRecursive(child) {
|
|
if (this.HasChild(child))
|
|
return true;
|
|
for (const c of this.GetChildren())
|
|
if (c._HasChildRecursive(child))
|
|
return true;
|
|
return false
|
|
}
|
|
_AddChildToSceneGraphInfo(child) {
|
|
this._sceneGraphInfo.GetChildren().push(child)
|
|
}
|
|
_RemoveChildFromSceneGraphInfo(child) {
|
|
const children = this._sceneGraphInfo.GetChildren();
|
|
const index = children.indexOf(child);
|
|
if (index !== -1)
|
|
children.splice(index, 1);
|
|
if (children.length === 0 && !this.HasParent())
|
|
this._ReleaseSceneGraphInfo();
|
|
if (!child.HasChildren())
|
|
child._ReleaseSceneGraphInfo()
|
|
}
|
|
GetSceneGraphChildrenExportData() {
|
|
return this._sceneGraphChildrenExportData
|
|
}
|
|
_UpdateRendererStateGroup() {
|
|
if (!enableUpdateRendererStateGroup)
|
|
return;
|
|
const renderer = this._runtime.GetRenderer();
|
|
if (this._stateGroup)
|
|
renderer.ReleaseStateGroup(this._stateGroup);
|
|
this._stateGroup = renderer.AcquireStateGroup(renderer.GetTextureFillShaderProgram() || "<default>", this.GetBlendMode(), this._colorPremultiplied, this.GetZElevation())
|
|
}
|
|
GetRendererStateGroup() {
|
|
return this._stateGroup
|
|
}
|
|
HasDefaultColor() {
|
|
return this._color === DEFAULT_COLOR
|
|
}
|
|
SetBlendMode(bm) {
|
|
bm = bm | 0;
|
|
if (bm < 0 || bm > 31)
|
|
throw new RangeError("invalid blend mode");
|
|
if (this.GetBlendMode() === bm)
|
|
return;
|
|
this._flags = this._flags & ~FLAG_BLEND_MODE_MASK | bm << FLAG_BLEND_MODE_BIT_OFFSET;
|
|
this._UpdateRendererStateGroup()
|
|
}
|
|
GetBlendMode() {
|
|
return (this._flags & FLAG_BLEND_MODE_MASK) >> FLAG_BLEND_MODE_BIT_OFFSET
|
|
}
|
|
_SetLayer(layer) {
|
|
this._layer = layer;
|
|
if (this.GetZElevation() !== 0)
|
|
this._layer._SetAnyInstanceZElevated()
|
|
}
|
|
GetLayer() {
|
|
return this._layer
|
|
}
|
|
GetLayout() {
|
|
return this.GetLayer().GetLayout()
|
|
}
|
|
_SetZIndex(z) {
|
|
this._zIndex = z | 0
|
|
}
|
|
GetZIndex() {
|
|
this._layer._UpdateZIndices();
|
|
return this._zIndex
|
|
}
|
|
_GetLastCachedZIndex() {
|
|
return this._zIndex
|
|
}
|
|
_SetFlag(bit, enable) {
|
|
if (enable)
|
|
this._flags |= bit;
|
|
else
|
|
this._flags &= ~bit
|
|
}
|
|
IsVisible() {
|
|
return (this._flags & FLAG_IS_VISIBLE) !== 0
|
|
}
|
|
SetVisible(v) {
|
|
this._SetFlag(FLAG_IS_VISIBLE, v)
|
|
}
|
|
IsCollisionEnabled() {
|
|
return (this._flags & FLAG_COLLISION_ENABLED) !== 0
|
|
}
|
|
SetCollisionEnabled(e) {
|
|
e = !!e;
|
|
if (this.IsCollisionEnabled() === e)
|
|
return;
|
|
this._SetFlag(FLAG_COLLISION_ENABLED, e);
|
|
if (e)
|
|
this.SetBboxChanged();
|
|
else
|
|
this._RemoveFromCollisionCells()
|
|
}
|
|
SetSolidCollisionFilter(isInclusive, tags) {
|
|
this._SetFlag(FLAG_SOLID_FILTER_INCLUSIVE, isInclusive);
|
|
if (this._solidFilterTags)
|
|
this._solidFilterTags.clear();
|
|
if (!tags.trim()) {
|
|
this._solidFilterTags = null;
|
|
return
|
|
}
|
|
if (!this._solidFilterTags)
|
|
this._solidFilterTags = new Set;
|
|
for (const tag of tags.split(" "))
|
|
if (tag)
|
|
this._solidFilterTags.add(tag.toLowerCase())
|
|
}
|
|
IsSolidCollisionAllowed(solidTagSet) {
|
|
const isInclusive = (this._flags & FLAG_SOLID_FILTER_INCLUSIVE) !== 0;
|
|
const filterTags = this._solidFilterTags;
|
|
if (!solidTagSet || !filterTags)
|
|
return !isInclusive;
|
|
for (const tag of filterTags)
|
|
if (solidTagSet.has(tag))
|
|
return isInclusive;
|
|
return !isInclusive
|
|
}
|
|
SetBboxChanged() {
|
|
this._flags |= FLAG_BBOX_CHANGED | FLAG_COLLISION_CELL_CHANGED | FLAG_MESH_CHANGED;
|
|
this._objectClass._SetAnyCollisionCellChanged(true);
|
|
this._runtime.UpdateRender();
|
|
if (this._layer.UsesRenderCells()) {
|
|
this.CalculateBbox(this._boundingBox, this._boundingQuad, true);
|
|
this._flags &= ~FLAG_BBOX_CHANGED;
|
|
this._UpdateRenderCell()
|
|
}
|
|
if ((this._flags & FLAG_ENABLE_BBOX_CHANGED_EVENT) !== 0)
|
|
this._inst.Dispatcher().dispatchEvent(bboxChangeEvent);
|
|
if (this._sceneGraphInfo !== null) {
|
|
const children = this._sceneGraphInfo.GetChildren();
|
|
for (let i = 0, len = children.length; i < len; ++i)
|
|
children[i].SetBboxChanged()
|
|
}
|
|
}
|
|
CalculateBbox(bbox, bquad, includeMesh) {
|
|
const x = this.GetX();
|
|
const y = this.GetY();
|
|
const w = this.GetWidth();
|
|
const h = this.GetHeight();
|
|
const a = this.GetAngle();
|
|
bbox.setWH(x - this._ox * w, y - this._oy * h, w, h);
|
|
if (includeMesh && this.HasMesh())
|
|
this._ExpandBboxForMesh(bbox);
|
|
if (a === 0)
|
|
bquad.setFromRect(bbox);
|
|
else {
|
|
bbox.offset(-x, -y);
|
|
bquad.setFromRotatedRectPrecalc(bbox, this.GetSinAngle(), this.GetCosAngle());
|
|
bquad.offset(x, y);
|
|
bquad.getBoundingBox(bbox)
|
|
}
|
|
bbox.normalize()
|
|
}
|
|
_UpdateBbox() {
|
|
const flags = this._flags;
|
|
if ((flags & FLAG_BBOX_CHANGED) !== 0) {
|
|
this.CalculateBbox(this._boundingBox, this._boundingQuad, true);
|
|
this._flags = flags & ~FLAG_BBOX_CHANGED
|
|
}
|
|
}
|
|
GetBoundingBox() {
|
|
this._UpdateBbox();
|
|
return this._boundingBox
|
|
}
|
|
GetBoundingQuad() {
|
|
this._UpdateBbox();
|
|
return this._boundingQuad
|
|
}
|
|
PixelRoundQuad(quad) {
|
|
const x = this.GetX();
|
|
const y = this.GetY();
|
|
const ox = Math.round(x) - x;
|
|
const oy = Math.round(y) - y;
|
|
if (ox === 0 && oy === 0)
|
|
return quad;
|
|
else {
|
|
tempQuad.copy(quad);
|
|
tempQuad.offset(ox, oy);
|
|
return tempQuad
|
|
}
|
|
}
|
|
OverwriteBoundingBox(box) {
|
|
this._boundingBox.copy(box);
|
|
this._boundingQuad.setFromRect(this._boundingBox);
|
|
this._flags &= ~FLAG_BBOX_CHANGED;
|
|
this._UpdateCollisionCell();
|
|
this._UpdateRenderCell()
|
|
}
|
|
SetBboxChangeEventEnabled(e) {
|
|
this._SetFlag(FLAG_ENABLE_BBOX_CHANGED_EVENT, e)
|
|
}
|
|
IsBboxChangeEventEnabled() {
|
|
return (this._flags & FLAG_ENABLE_BBOX_CHANGED_EVENT) !== 0
|
|
}
|
|
IsInViewport(viewport) {
|
|
return this.GetZElevation() === 0 ? viewport.intersectsRect(this.GetBoundingBox()) : this._IsInViewport_ZElevated()
|
|
}
|
|
_IsInViewport_ZElevated() {
|
|
const layer = this.GetLayer();
|
|
const totalZElevation = this.GetTotalZElevation();
|
|
if (totalZElevation >= layer.GetCameraZ())
|
|
return false;
|
|
layer.GetViewportForZ(totalZElevation, tempRect);
|
|
return tempRect.intersectsRect(this.GetBoundingBox())
|
|
}
|
|
SetSourceCollisionPoly(poly) {
|
|
this._sourceCollisionPoly = poly;
|
|
this._DiscardTransformedCollisionPoly();
|
|
if (this.HasMesh())
|
|
this._meshInfo.meshPoly = null
|
|
}
|
|
GetSourceCollisionPoly() {
|
|
return this._sourceCollisionPoly
|
|
}
|
|
HasOwnCollisionPoly() {
|
|
return this._sourceCollisionPoly !== null || this.HasMesh()
|
|
}
|
|
GetTransformedCollisionPoly() {
|
|
return this._GetCustomTransformedCollisionPolyPrecalc(this.GetWidth(), this.GetHeight(), this.GetAngle(), this.GetSinAngle(), this.GetCosAngle())
|
|
}
|
|
GetCustomTransformedCollisionPoly(w, h, a) {
|
|
let sina = 0;
|
|
let cosa = 1;
|
|
if (a !== 0) {
|
|
sina = Math.sin(a);
|
|
cosa = Math.cos(a)
|
|
}
|
|
return this._GetCustomTransformedCollisionPolyPrecalc(w, h, a, sina, cosa)
|
|
}
|
|
_GetCustomTransformedCollisionPolyPrecalc(w, h, a, sinA, cosA) {
|
|
let tpi = this._transformedPolyInfo;
|
|
if (tpi === null) {
|
|
tpi = {
|
|
poly: C3.New(C3.CollisionPoly),
|
|
width: NaN,
|
|
height: NaN,
|
|
angle: NaN
|
|
};
|
|
this._transformedPolyInfo = tpi
|
|
}
|
|
const transformedPoly = tpi.poly;
|
|
if (tpi.width === w && tpi.height === h && tpi.angle === a)
|
|
return transformedPoly;
|
|
const sourcePoly = this._sourceCollisionPoly;
|
|
if (this.HasMesh()) {
|
|
const ox = this.GetOriginX();
|
|
const oy = this.GetOriginY();
|
|
const sourceMesh = this.GetSourceMesh();
|
|
let meshPoly = this._meshInfo.meshPoly;
|
|
if (!meshPoly) {
|
|
if (sourcePoly) {
|
|
tempCollisionPoly.copy(sourcePoly);
|
|
tempCollisionPoly.offset(ox, oy)
|
|
} else
|
|
tempCollisionPoly.setDefaultPoints();
|
|
meshPoly = sourceMesh.InsertPolyMeshVertices(tempCollisionPoly);
|
|
this._meshInfo.meshPoly = meshPoly
|
|
}
|
|
sourceMesh.TransformCollisionPoly(meshPoly, transformedPoly);
|
|
transformedPoly.offset(-ox, -oy);
|
|
transformedPoly.transformPrecalc(w, h, sinA, cosA)
|
|
} else if (sourcePoly) {
|
|
transformedPoly.copy(sourcePoly);
|
|
transformedPoly.transformPrecalc(w, h, sinA, cosA)
|
|
} else
|
|
transformedPoly.setFromQuad(this.GetBoundingQuad(), -this.GetX(), -this.GetY());
|
|
tpi.width = w;
|
|
tpi.height = h;
|
|
tpi.angle = a;
|
|
return transformedPoly
|
|
}
|
|
_DiscardTransformedCollisionPoly() {
|
|
this.SetPhysicsBodyChanged(true);
|
|
const tpi = this._transformedPolyInfo;
|
|
if (tpi === null)
|
|
return;
|
|
tpi.width = NaN
|
|
}
|
|
CreateMesh(hsize, vsize) {
|
|
hsize = Math.floor(hsize);
|
|
vsize = Math.floor(vsize);
|
|
if (!this.GetInstance().GetPlugin().SupportsMesh())
|
|
throw new Error("object does not support mesh");
|
|
this.ReleaseMesh();
|
|
this._meshInfo = {
|
|
sourceMesh: C3.New(C3.Gfx.Mesh, hsize, vsize),
|
|
transformedMesh: C3.New(C3.Gfx.Mesh, hsize, vsize),
|
|
meshPoly: null
|
|
}
|
|
}
|
|
HasMesh() {
|
|
return this._meshInfo !== null
|
|
}
|
|
GetSourceMesh() {
|
|
if (!this.HasMesh())
|
|
throw new Error("no mesh");
|
|
return this._meshInfo.sourceMesh
|
|
}
|
|
GetTransformedMesh() {
|
|
if (!this.HasMesh())
|
|
throw new Error("no mesh");
|
|
return this._meshInfo.transformedMesh
|
|
}
|
|
SetMeshChanged(e) {
|
|
this._SetFlag(FLAG_MESH_CHANGED, e)
|
|
}
|
|
IsMeshChanged() {
|
|
return (this._flags & FLAG_MESH_CHANGED) !== 0
|
|
}
|
|
SetPhysicsBodyChanged(e) {
|
|
this._SetFlag(FLAG_PHYSICS_BODY_CHANGED, e)
|
|
}
|
|
IsPhysicsBodyChanged() {
|
|
return (this._flags & FLAG_PHYSICS_BODY_CHANGED) !== 0
|
|
}
|
|
_ExpandBboxForMesh(bbox) {
|
|
const sourceMesh = this._meshInfo.sourceMesh;
|
|
const minX = Math.min(sourceMesh.GetMinX(), 0);
|
|
const minY = Math.min(sourceMesh.GetMinY(), 0);
|
|
const maxX = Math.max(sourceMesh.GetMaxX(), 1);
|
|
const maxY = Math.max(sourceMesh.GetMaxY(), 1);
|
|
const w = bbox.width();
|
|
const h = bbox.height();
|
|
bbox.offsetLeft(minX * w);
|
|
bbox.offsetTop(minY * h);
|
|
bbox.offsetRight((maxX - 1) * w);
|
|
bbox.offsetBottom((maxY - 1) * h)
|
|
}
|
|
ReleaseMesh() {
|
|
if (!this._meshInfo)
|
|
return;
|
|
this._meshInfo.sourceMesh.Release();
|
|
this._meshInfo.transformedMesh.Release();
|
|
this._meshInfo = null;
|
|
this._DiscardTransformedCollisionPoly()
|
|
}
|
|
SetMeshPoint(col, row, opts) {
|
|
col = Math.floor(col);
|
|
row = Math.floor(row);
|
|
const mode = opts.mode || "absolute";
|
|
if (!VALID_SET_MESH_POINT_MODES.has(mode))
|
|
throw new Error("invalid mode");
|
|
const isRelative = mode === "relative";
|
|
let posx = opts.x;
|
|
let posy = opts.y;
|
|
let texu = typeof opts.u === "number" ? opts.u : isRelative ? 0 : -1;
|
|
let texv = typeof opts.v === "number" ? opts.v : isRelative ? 0 : -1;
|
|
if (!this.HasMesh())
|
|
return false;
|
|
const sourceMesh = this.GetSourceMesh();
|
|
const p = sourceMesh.GetMeshPointAt(col, row);
|
|
if (p === null)
|
|
return false;
|
|
if (isRelative) {
|
|
posx += col / (sourceMesh.GetHSize() - 1);
|
|
posy += row / (sourceMesh.GetVSize() - 1)
|
|
}
|
|
if (texu === -1 && !isRelative)
|
|
texu = p.GetU();
|
|
else {
|
|
if (isRelative)
|
|
texu += col / (sourceMesh.GetHSize() - 1);
|
|
texu = C3.clamp(texu, 0, 1)
|
|
}
|
|
if (texv === -1 && !isRelative)
|
|
texv = p.GetV();
|
|
else {
|
|
if (isRelative)
|
|
texv += row / (sourceMesh.GetVSize() - 1);
|
|
texv = C3.clamp(texv, 0, 1)
|
|
}
|
|
if (p.GetX() === posx && p.GetY() === posy && p.GetU() === texu && p.GetV() === texv)
|
|
return false;
|
|
p.SetX(posx);
|
|
p.SetY(posy);
|
|
p.SetU(texu);
|
|
p.SetV(texv);
|
|
this._DiscardTransformedCollisionPoly();
|
|
return true
|
|
}
|
|
HasTilemap() {
|
|
return this._inst.HasTilemap()
|
|
}
|
|
ContainsPoint(x, y) {
|
|
if (!this.GetBoundingBox().containsPoint(x, y))
|
|
return false;
|
|
if (!this.GetBoundingQuad().containsPoint(x, y))
|
|
return false;
|
|
if (this.HasTilemap())
|
|
return this._inst.GetSdkInstance().TestPointOverlapTile(x, y);
|
|
if (!this.HasOwnCollisionPoly())
|
|
return true;
|
|
return this.GetTransformedCollisionPoly().containsPoint(x - this.GetX(), y - this.GetY())
|
|
}
|
|
_IsCollisionCellChanged() {
|
|
return (this._flags & FLAG_COLLISION_CELL_CHANGED) !== 0
|
|
}
|
|
_UpdateCollisionCell() {
|
|
if (!this._IsCollisionCellChanged() || !this.IsCollisionEnabled())
|
|
return;
|
|
const bbox = this.GetBoundingBox();
|
|
const grid = this._objectClass._GetCollisionCellGrid();
|
|
const collisionCells = this._collisionCells;
|
|
tempRect.set(grid.XToCell(bbox.getLeft()), grid.YToCell(bbox.getTop()), grid.XToCell(bbox.getRight()), grid.YToCell(bbox.getBottom()));
|
|
if (collisionCells.equals(tempRect))
|
|
return;
|
|
const inst = this._inst;
|
|
if (collisionCells === DEFAULT_COLLISION_CELLS) {
|
|
grid.Update(inst, null, tempRect);
|
|
this._collisionCells = C3.New(C3.Rect, tempRect)
|
|
} else {
|
|
grid.Update(inst, collisionCells, tempRect);
|
|
collisionCells.copy(tempRect)
|
|
}
|
|
this._flags &= ~FLAG_COLLISION_CELL_CHANGED
|
|
}
|
|
_RemoveFromCollisionCells() {
|
|
const collisionCells = this._collisionCells;
|
|
if (collisionCells === DEFAULT_COLLISION_CELLS)
|
|
return;
|
|
this._objectClass._GetCollisionCellGrid().Update(this._inst, collisionCells, null);
|
|
this._collisionCells = DEFAULT_COLLISION_CELLS
|
|
}
|
|
_UpdateRenderCell() {
|
|
const layer = this.GetLayer();
|
|
if (!layer.UsesRenderCells())
|
|
return;
|
|
const renderGrid = layer.GetRenderGrid();
|
|
const bbox = this.GetBoundingBox();
|
|
const renderCells = this._renderCells;
|
|
tempRect.set(renderGrid.XToCell(bbox.getLeft()), renderGrid.YToCell(bbox.getTop()), renderGrid.XToCell(bbox.getRight()), renderGrid.YToCell(bbox.getBottom()));
|
|
if (renderCells.equals(tempRect))
|
|
return;
|
|
const inst = this._inst;
|
|
if (renderCells === DEFAULT_RENDER_CELLS) {
|
|
renderGrid.Update(inst, null, tempRect);
|
|
this._renderCells = C3.New(C3.Rect, tempRect)
|
|
} else {
|
|
renderGrid.Update(inst, renderCells, tempRect);
|
|
renderCells.copy(tempRect)
|
|
}
|
|
layer.SetRenderListStale()
|
|
}
|
|
_RemoveFromRenderCells() {
|
|
const renderCells = this._renderCells;
|
|
if (renderCells === DEFAULT_RENDER_CELLS)
|
|
return;
|
|
this.GetLayer().GetRenderGrid().Update(this._inst, renderCells, null);
|
|
this._renderCells = DEFAULT_RENDER_CELLS
|
|
}
|
|
GetRenderCellRange() {
|
|
return this._renderCells
|
|
}
|
|
ZOrderMoveToTop() {
|
|
const inst = this._inst;
|
|
const layer = this._layer;
|
|
const layerInstances = layer._GetInstances();
|
|
if (layerInstances.length && layerInstances[layerInstances.length - 1] === inst)
|
|
return;
|
|
layer._RemoveInstance(inst, false);
|
|
layer._AddInstance(inst, false);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
ZOrderMoveToBottom() {
|
|
const inst = this._inst;
|
|
const layer = this._layer;
|
|
const layerInstances = layer._GetInstances();
|
|
if (layerInstances.length && layerInstances[0] === inst)
|
|
return;
|
|
layer._RemoveInstance(inst, false);
|
|
layer._PrependInstance(inst, false);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
ZOrderMoveToLayer(layerMove) {
|
|
const inst = this._inst;
|
|
const curLayer = this._layer;
|
|
if (curLayer.GetLayout() !== layerMove.GetLayout())
|
|
throw new Error("layer from different layout");
|
|
if (layerMove === curLayer)
|
|
return;
|
|
curLayer._RemoveInstance(inst, true);
|
|
this._SetLayer(layerMove);
|
|
layerMove._AddInstance(inst, true);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
ZOrderMoveAdjacentToInstance(otherInst, isAfter) {
|
|
const inst = this._inst;
|
|
const curLayer = this._layer;
|
|
if (otherInst.GetUID() === inst.GetUID())
|
|
return;
|
|
const otherWi = otherInst.GetWorldInfo();
|
|
if (!otherWi)
|
|
throw new Error("expected world instance");
|
|
const otherLayer = otherWi.GetLayer();
|
|
let didChangeLayer = false;
|
|
if (curLayer.GetIndex() !== otherLayer.GetIndex()) {
|
|
curLayer._RemoveInstance(inst, true);
|
|
this._SetLayer(otherLayer);
|
|
otherLayer._AddInstance(inst, true);
|
|
didChangeLayer = true
|
|
}
|
|
const didChangeZOrder = otherLayer.MoveInstanceAdjacent(inst, otherInst, !!isAfter);
|
|
if (didChangeLayer || didChangeZOrder)
|
|
this._runtime.UpdateRender()
|
|
}
|
|
GetInstanceEffectList() {
|
|
return this._instanceEffectList
|
|
}
|
|
_SetHasAnyActiveEffect(e) {
|
|
this._SetFlag(FLAG_HAS_ANY_ACTIVE_EFFECT, e)
|
|
}
|
|
HasAnyActiveEffect() {
|
|
return (this._flags & FLAG_HAS_ANY_ACTIVE_EFFECT) !== 0
|
|
}
|
|
_SaveToJson() {
|
|
const o = {
|
|
"x": this.GetX(),
|
|
"y": this.GetY(),
|
|
"w": this.GetWidth(),
|
|
"h": this.GetHeight(),
|
|
"l": this.GetLayer().GetSID(),
|
|
"zi": this.GetZIndex()
|
|
};
|
|
if (this.GetZElevation() !== 0)
|
|
o["ze"] = this.GetZElevation();
|
|
if (this.GetAngle() !== 0)
|
|
o["a"] = this.GetAngle();
|
|
if (!this.HasDefaultColor())
|
|
o["c"] = this._color.toJSON();
|
|
if (this.GetOriginX() !== .5)
|
|
o["oX"] = this.GetOriginX();
|
|
if (this.GetOriginY() !== .5)
|
|
o["oY"] = this.GetOriginY();
|
|
if (this.GetBlendMode() !== 0)
|
|
o["bm"] = this.GetBlendMode();
|
|
if (!this.IsVisible())
|
|
o["v"] = this.IsVisible();
|
|
if (!this.IsCollisionEnabled())
|
|
o["ce"] = this.IsCollisionEnabled();
|
|
if (this.IsBboxChangeEventEnabled())
|
|
o["be"] = this.IsBboxChangeEventEnabled();
|
|
if (this._instanceEffectList)
|
|
o["fx"] = this._instanceEffectList._SaveToJson();
|
|
const isSolidFilterInclusive = (this._flags & FLAG_SOLID_FILTER_INCLUSIVE) !== 0;
|
|
if (isSolidFilterInclusive)
|
|
o["sfi"] = isSolidFilterInclusive;
|
|
if (this._solidFilterTags)
|
|
o["sft"] = [...this._solidFilterTags].join(" ");
|
|
if (this._sceneGraphInfo)
|
|
o["sgi"] = this._sceneGraphInfo._SaveToJson();
|
|
return o
|
|
}
|
|
_LoadFromJson(o) {
|
|
enableUpdateRendererStateGroup = false;
|
|
this._ResetAllSceneGraphState();
|
|
this.SetX(o["x"]);
|
|
this.SetY(o["y"]);
|
|
this.SetWidth(o["w"]);
|
|
this.SetHeight(o["h"]);
|
|
this._SetZIndex(o["zi"]);
|
|
this.SetZElevation(o.hasOwnProperty("ze") ? o["ze"] : 0);
|
|
this.SetAngle(o.hasOwnProperty("a") ? o["a"] : 0);
|
|
if (o.hasOwnProperty("c"))
|
|
tempColor.setFromJSON(o["c"]);
|
|
else if (o.hasOwnProperty("o")) {
|
|
tempColor.copyRgb(this._color);
|
|
tempColor.a = o["o"]
|
|
} else
|
|
tempColor.setRgba(1, 1, 1, 1);
|
|
this._SetColor(tempColor);
|
|
this.SetOriginX(o.hasOwnProperty("oX") ? o["oX"] : .5);
|
|
this.SetOriginY(o.hasOwnProperty("oY") ? o["oY"] : .5);
|
|
this.SetBlendMode(o.hasOwnProperty("bm") ? o["bm"] : 0);
|
|
this.SetVisible(o.hasOwnProperty("v") ? o["v"] : true);
|
|
this.SetCollisionEnabled(o.hasOwnProperty("ce") ? o["ce"] : true);
|
|
this.SetBboxChangeEventEnabled(o.hasOwnProperty("be") ? o["be"] : false);
|
|
this.SetSolidCollisionFilter(o.hasOwnProperty("sfi") ? o["sfi"] : false, o.hasOwnProperty("sft") ? o["sft"] : "");
|
|
if (this._instanceEffectList && o.hasOwnProperty("fx"))
|
|
this._instanceEffectList._LoadFromJson(o["fx"]);
|
|
if (o.hasOwnProperty("sgi")) {
|
|
this._CreateSceneGraphInfo(null);
|
|
const sgi = this._sceneGraphInfo;
|
|
const sgiData = o["sgi"];
|
|
sgi._LoadFromJson(sgiData);
|
|
const runtimeDispatcher = this.GetRuntime().Dispatcher();
|
|
const onAfterLoad = ()=>{
|
|
runtimeDispatcher.removeEventListener("afterload", onAfterLoad);
|
|
sgi._OnAfterLoad(sgiData)
|
|
}
|
|
;
|
|
runtimeDispatcher.addEventListener("afterload", onAfterLoad)
|
|
}
|
|
this.SetBboxChanged();
|
|
enableUpdateRendererStateGroup = true;
|
|
this._UpdateRendererStateGroup()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.BehaviorType = class BehaviorType extends C3.DefendedBase {
|
|
constructor(objectClass, data) {
|
|
super();
|
|
const runtime = objectClass.GetRuntime();
|
|
const pluginManager = runtime.GetPluginManager();
|
|
const BehaviorCtor = runtime.GetObjectReference(data[1]);
|
|
if (!pluginManager.HasBehaviorByConstructorFunction(BehaviorCtor))
|
|
pluginManager.CreateBehavior(data);
|
|
this._runtime = runtime;
|
|
this._objectClass = objectClass;
|
|
this._behavior = pluginManager.GetBehaviorByConstructorFunction(BehaviorCtor);
|
|
this._sdkType = null;
|
|
this._instSdkCtor = BehaviorCtor.Instance;
|
|
this._sid = data[2];
|
|
this._name = data[0];
|
|
this._jsPropName = this._runtime.GetJsPropName(data[3]);
|
|
this._sdkType = C3.New(BehaviorCtor.Type, this);
|
|
this.OnCreate()
|
|
}
|
|
static Create(objectClass, behaviorTypeData) {
|
|
return C3.New(C3.BehaviorType, objectClass, behaviorTypeData)
|
|
}
|
|
Release() {
|
|
this._runtime = null;
|
|
this._behavior = null;
|
|
this._sdkType.Release();
|
|
this._sdkType = null;
|
|
this._instSdkCtor = null
|
|
}
|
|
GetSdkType() {
|
|
return this._sdkType
|
|
}
|
|
OnCreate() {
|
|
this._sdkType.OnCreate()
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetObjectClass() {
|
|
return this._objectClass
|
|
}
|
|
GetBehavior() {
|
|
return this._behavior
|
|
}
|
|
GetInstanceSdkCtor() {
|
|
return this._instSdkCtor
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
GetSID() {
|
|
return this._sid
|
|
}
|
|
GetJsPropName() {
|
|
return this._jsPropName
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const IBehaviorInstance = self.IBehaviorInstance;
|
|
C3.BehaviorInstance = class BehaviorInstance extends C3.DefendedBase {
|
|
constructor(opts) {
|
|
super();
|
|
this._runtime = opts.runtime;
|
|
this._behaviorType = opts.behaviorType;
|
|
this._behavior = this._behaviorType.GetBehavior();
|
|
this._inst = opts.instance;
|
|
this._index = opts.index;
|
|
this._sdkInst = null;
|
|
this._iScriptInterface = null;
|
|
this._behavior._AddInstance(this._inst)
|
|
}
|
|
Release() {
|
|
if (this._iScriptInterface) {
|
|
this._iScriptInterface._Release();
|
|
this._iScriptInterface = null
|
|
}
|
|
this._behavior._RemoveInstance(this._inst);
|
|
this._sdkInst.Release();
|
|
this._sdkInst = null;
|
|
this._iScriptInterface = null;
|
|
this._runtime = null;
|
|
this._behaviorType = null;
|
|
this._behavior = null;
|
|
this._inst = null
|
|
}
|
|
_CreateSdkInstance(properties) {
|
|
if (this._sdkInst)
|
|
throw new Error("already got sdk instance");
|
|
this._sdkInst = C3.New(this._behaviorType.GetInstanceSdkCtor(), this, properties);
|
|
this._InitScriptInterface()
|
|
}
|
|
GetSdkInstance() {
|
|
return this._sdkInst
|
|
}
|
|
GetObjectInstance() {
|
|
return this._inst
|
|
}
|
|
GetRuntime() {
|
|
return this._runtime
|
|
}
|
|
GetBehaviorType() {
|
|
return this._behaviorType
|
|
}
|
|
GetBehavior() {
|
|
return this._behavior
|
|
}
|
|
_GetIndex() {
|
|
return this._index
|
|
}
|
|
PostCreate() {
|
|
this._sdkInst.PostCreate()
|
|
}
|
|
OnSpriteFrameChanged(prevFrame, nextFrame) {
|
|
this._sdkInst.OnSpriteFrameChanged(prevFrame, nextFrame)
|
|
}
|
|
_GetDebuggerProperties() {
|
|
return this._sdkInst.GetDebuggerProperties()
|
|
}
|
|
SaveToJson() {
|
|
return this._sdkInst.SaveToJson()
|
|
}
|
|
LoadFromJson(o) {
|
|
return this._sdkInst.LoadFromJson(o)
|
|
}
|
|
static SortByTickSequence(a, b) {
|
|
const instA = a.GetObjectInstance();
|
|
const instB = b.GetObjectInstance();
|
|
const typeIndexA = instA.GetObjectClass().GetIndex();
|
|
const typeIndexB = instB.GetObjectClass().GetIndex();
|
|
if (typeIndexA !== typeIndexB)
|
|
return typeIndexA - typeIndexB;
|
|
const seqA = instA.GetPUID();
|
|
const seqB = instB.GetPUID();
|
|
if (seqA !== seqB)
|
|
return seqA - seqB;
|
|
return a.GetBehaviorInstance()._GetIndex() - b.GetBehaviorInstance()._GetIndex()
|
|
}
|
|
_InitScriptInterface() {
|
|
const DefaultScriptClass = IBehaviorInstance;
|
|
const SdkScriptClass = this._sdkInst.GetScriptInterfaceClass();
|
|
const ScriptInterfaceClass = SdkScriptClass || DefaultScriptClass;
|
|
IBehaviorInstance._Init(this);
|
|
this._iScriptInterface = new ScriptInterfaceClass;
|
|
IBehaviorInstance._Init(null);
|
|
if (SdkScriptClass && !(this._iScriptInterface instanceof DefaultScriptClass))
|
|
throw new TypeError(`script interface class '${SdkScriptClass.name}' does not extend the right base class '${DefaultScriptClass.name}'`);
|
|
}
|
|
GetScriptInterface() {
|
|
return this._iScriptInterface
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.EffectList = class EffectList extends C3.DefendedBase {
|
|
constructor(owner, data) {
|
|
super();
|
|
this._owner = owner;
|
|
this._allEffectTypes = [];
|
|
this._activeEffectTypes = [];
|
|
this._effectTypesByName = new Map;
|
|
this._effectParams = [];
|
|
this._preservesOpaqueness = true;
|
|
for (const d of data) {
|
|
const et = C3.New(C3.EffectType, this, d, this._allEffectTypes.length);
|
|
this._allEffectTypes.push(et);
|
|
this._effectTypesByName.set(et.GetName().toLowerCase(), et);
|
|
if (d.length >= 3)
|
|
this._effectParams.push(this._LoadSingleEffectParameters(d[2]))
|
|
}
|
|
this.GetRuntime()._AddEffectList(this)
|
|
}
|
|
Release() {
|
|
C3.clearArray(this._allEffectTypes);
|
|
C3.clearArray(this._activeEffectTypes);
|
|
this._effectTypesByName.clear();
|
|
C3.clearArray(this._effectParams);
|
|
this._owner = null
|
|
}
|
|
PrependEffectTypes(arr) {
|
|
if (!arr.length)
|
|
return;
|
|
this._allEffectTypes = arr.concat(this._allEffectTypes);
|
|
for (const et of arr)
|
|
this._effectTypesByName.set(et.GetName().toLowerCase(), et);
|
|
for (let i = 0, len = this._allEffectTypes.length; i < len; ++i)
|
|
this._allEffectTypes[i]._SetIndex(i)
|
|
}
|
|
_LoadSingleEffectParameters(arr) {
|
|
const ret = arr.slice(0);
|
|
for (let i = 0, len = ret.length; i < len; ++i) {
|
|
const p = ret[i];
|
|
if (Array.isArray(p)) {
|
|
const c = C3.New(C3.Color);
|
|
c.setFromJSON(p);
|
|
ret[i] = c
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
GetOwner() {
|
|
return this._owner
|
|
}
|
|
GetRuntime() {
|
|
return this._owner.GetRuntime()
|
|
}
|
|
UpdateActiveEffects() {
|
|
C3.clearArray(this._activeEffectTypes);
|
|
let preservesOpaqueness = true;
|
|
for (const et of this._allEffectTypes)
|
|
if (et.IsActive()) {
|
|
this._activeEffectTypes.push(et);
|
|
if (!et.GetShaderProgram().PreservesOpaqueness())
|
|
preservesOpaqueness = false
|
|
}
|
|
this._preservesOpaqueness = preservesOpaqueness
|
|
}
|
|
GetAllEffectTypes() {
|
|
return this._allEffectTypes
|
|
}
|
|
HasAnyEffectType() {
|
|
return this._allEffectTypes.length > 0
|
|
}
|
|
GetEffectTypeByName(name) {
|
|
return this._effectTypesByName.get(name.toLowerCase()) || null
|
|
}
|
|
GetEffectTypeByIndex(index) {
|
|
index = Math.floor(+index);
|
|
if (index < 0 || index >= this._allEffectTypes.length)
|
|
throw new RangeError("invalid effect type index");
|
|
return this._allEffectTypes[index]
|
|
}
|
|
IsEffectIndexActive(index) {
|
|
return this.GetEffectTypeByIndex(index).IsActive()
|
|
}
|
|
SetEffectIndexActive(index, a) {
|
|
this.GetEffectTypeByIndex(index).SetActive(a)
|
|
}
|
|
GetActiveEffectTypes() {
|
|
return this._activeEffectTypes
|
|
}
|
|
HasAnyActiveEffect() {
|
|
return this._activeEffectTypes.length > 0
|
|
}
|
|
PreservesOpaqueness() {
|
|
return this._preservesOpaqueness
|
|
}
|
|
GetEffectParametersForIndex(index) {
|
|
return this._effectParams[index]
|
|
}
|
|
static SaveFxParamToJson(param) {
|
|
if (param && param instanceof C3.Color)
|
|
return {
|
|
"t": "color",
|
|
"v": param.toJSON()
|
|
};
|
|
else
|
|
return param
|
|
}
|
|
static LoadFxParamFromJson(o) {
|
|
if (typeof o === "object") {
|
|
const type = o["t"];
|
|
if (type === "color") {
|
|
const color = C3.New(C3.Color);
|
|
color.setFromJSON(o["v"]);
|
|
return color
|
|
} else
|
|
throw new Error("invalid effect parameter type");
|
|
} else
|
|
return o
|
|
}
|
|
static SaveFxParamsToJson(params) {
|
|
return params.map(C3.EffectList.SaveFxParamToJson)
|
|
}
|
|
static LoadFxParamsFromJson(arr) {
|
|
return arr.map(C3.EffectList.LoadFxParamFromJson)
|
|
}
|
|
SaveToJson() {
|
|
return this._allEffectTypes.map(et=>({
|
|
"name": et.GetName(),
|
|
"active": et.IsActive(),
|
|
"params": C3.EffectList.SaveFxParamsToJson(this._effectParams[et.GetIndex()])
|
|
}))
|
|
}
|
|
LoadFromJson(arr) {
|
|
for (const o of arr) {
|
|
const et = this.GetEffectTypeByName(o["name"]);
|
|
if (!et)
|
|
continue;
|
|
et.SetActive(o["active"]);
|
|
this._effectParams[et.GetIndex()] = C3.EffectList.LoadFxParamsFromJson(o["params"])
|
|
}
|
|
this.UpdateActiveEffects()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.EffectType = class EffectType extends C3.DefendedBase {
|
|
constructor(effectList, data, index) {
|
|
super();
|
|
this._effectList = effectList;
|
|
this._id = data[0];
|
|
this._name = data[1];
|
|
this._index = index;
|
|
this._shaderProgram = null;
|
|
this._isActive = true
|
|
}
|
|
Release() {
|
|
this._effectList = null;
|
|
this._shaderProgram = null
|
|
}
|
|
Clone(effectListOwner) {
|
|
const ret = C3.New(C3.EffectType, effectListOwner, [this._id, this._name], -1);
|
|
ret._shaderProgram = this._shaderProgram;
|
|
ret._isActive = this._isActive;
|
|
return ret
|
|
}
|
|
_InitRenderer(renderer) {
|
|
const shaderProgram = renderer.GetShaderProgramByName(this._id);
|
|
if (!shaderProgram)
|
|
throw new Error("failed to find shader program '" + this._id + "'");
|
|
this._shaderProgram = shaderProgram
|
|
}
|
|
GetEffectList() {
|
|
return this._effectList
|
|
}
|
|
GetName() {
|
|
return this._name
|
|
}
|
|
_SetIndex(i) {
|
|
this._index = i
|
|
}
|
|
GetIndex() {
|
|
return this._index
|
|
}
|
|
GetOwner() {
|
|
return this._effectList.GetOwner()
|
|
}
|
|
GetRuntime() {
|
|
return this._effectList.GetRuntime()
|
|
}
|
|
SetActive(a) {
|
|
this._isActive = !!a
|
|
}
|
|
IsActive() {
|
|
return this._isActive
|
|
}
|
|
GetShaderProgram() {
|
|
return this._shaderProgram
|
|
}
|
|
GetDefaultParameterValues() {
|
|
const ret = [];
|
|
for (let i = 0, len = this._shaderProgram.GetParameterCount(); i < len; ++i) {
|
|
const type = this._shaderProgram.GetParameterType(i);
|
|
if (type === "float" || type === "percent")
|
|
ret.push(0);
|
|
else if (type === "color")
|
|
ret.push(C3.New(C3.Color, 1, 1, 1, 1));
|
|
else
|
|
throw new TypeError("unknown effect parameter type");
|
|
}
|
|
return ret
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.InstanceEffectList = class InstanceEffectList extends C3.DefendedBase {
|
|
constructor(inst, wi, data) {
|
|
super();
|
|
this._inst = inst;
|
|
this._wi = wi;
|
|
this._effectList = inst.GetObjectClass().GetEffectList();
|
|
this._activeEffectFlags = [];
|
|
this._activeEffectTypes = [];
|
|
this._preservesOpaqueness = true;
|
|
this._effectParams = [];
|
|
for (const et of this._effectList.GetAllEffectTypes())
|
|
this._activeEffectFlags.push(true);
|
|
this.UpdateActiveEffects()
|
|
}
|
|
Release() {
|
|
C3.clearArray(this._activeEffectFlags);
|
|
C3.clearArray(this._activeEffectTypes);
|
|
C3.clearArray(this._effectParams);
|
|
this._inst = null;
|
|
this._effectList = null
|
|
}
|
|
_LoadEffectParameters(data) {
|
|
for (const e of data)
|
|
this._effectParams.push(this._LoadSingleEffectParameters(e))
|
|
}
|
|
_LoadSingleEffectParameters(arr) {
|
|
const ret = arr.slice(0);
|
|
for (let i = 0, len = ret.length; i < len; ++i) {
|
|
const p = ret[i];
|
|
if (Array.isArray(p)) {
|
|
const c = C3.New(C3.Color);
|
|
c.setFromJSON(p);
|
|
ret[i] = c
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
LoadDefaultEffectParameters() {
|
|
for (const effectType of this._effectList.GetAllEffectTypes())
|
|
this._effectParams.push(effectType.GetDefaultParameterValues())
|
|
}
|
|
GetOwner() {
|
|
return this._owner
|
|
}
|
|
GetEffectList() {
|
|
return this._effectList
|
|
}
|
|
GetRuntime() {
|
|
return this._inst.GetRuntime()
|
|
}
|
|
UpdateActiveEffects() {
|
|
C3.clearArray(this._activeEffectTypes);
|
|
const allEffectTypes = this._effectList.GetAllEffectTypes();
|
|
const activeEffectTypes = this._activeEffectTypes;
|
|
const activeEffectFlags = this._activeEffectFlags;
|
|
let preservesOpaqueness = true;
|
|
for (let i = 0, len = allEffectTypes.length; i < len; ++i)
|
|
if (activeEffectFlags[i]) {
|
|
const et = allEffectTypes[i];
|
|
activeEffectTypes.push(et);
|
|
if (!et.GetShaderProgram().PreservesOpaqueness())
|
|
preservesOpaqueness = false
|
|
}
|
|
this._preservesOpaqueness = preservesOpaqueness;
|
|
this._wi._SetHasAnyActiveEffect(!!activeEffectTypes.length)
|
|
}
|
|
GetActiveEffectTypes() {
|
|
return this._activeEffectTypes
|
|
}
|
|
GetEffectParametersForIndex(index) {
|
|
return this._effectParams[index]
|
|
}
|
|
PreservesOpaqueness() {
|
|
return this._preservesOpaqueness
|
|
}
|
|
HasAnyActiveBackgroundBlendingEffect() {
|
|
return this._activeEffectTypes.some(et=>et.GetShaderProgram().UsesDest())
|
|
}
|
|
IsEffectIndexActive(i) {
|
|
return this._activeEffectFlags[i]
|
|
}
|
|
SetEffectIndexActive(i, e) {
|
|
this._activeEffectFlags[i] = !!e
|
|
}
|
|
GetAllEffectTypes() {
|
|
return this._effectList.GetAllEffectTypes()
|
|
}
|
|
_SaveToJson() {
|
|
return this._effectList.GetAllEffectTypes().map(et=>({
|
|
"name": et.GetName(),
|
|
"active": this._activeEffectFlags[et.GetIndex()],
|
|
"params": C3.EffectList.SaveFxParamsToJson(this._effectParams[et.GetIndex()])
|
|
}))
|
|
}
|
|
_LoadFromJson(arr) {
|
|
for (const o of arr) {
|
|
const et = this._effectList.GetEffectTypeByName(o["name"]);
|
|
if (!et)
|
|
continue;
|
|
this._activeEffectFlags[et.GetIndex()] = o["active"];
|
|
this._effectParams[et.GetIndex()] = C3.EffectList.LoadFxParamsFromJson(o["params"])
|
|
}
|
|
this.UpdateActiveEffects()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tempCandidates = [];
|
|
const tileCollRectCandidates = [];
|
|
const tempJumpthruRet = [];
|
|
const tempPolyA = C3.New(C3.CollisionPoly);
|
|
const tempPolyB = C3.New(C3.CollisionPoly);
|
|
const tempQuad = C3.New(C3.Quad);
|
|
const tempRect = C3.New(C3.Rect);
|
|
const tempRect2 = C3.New(C3.Rect);
|
|
C3.CollisionEngine = class CollisionEngine extends C3.DefendedBase {
|
|
constructor(runtime) {
|
|
super();
|
|
this._runtime = runtime;
|
|
this._registeredCollisions = [];
|
|
this._collisionCheckCount = 0;
|
|
this._collisionCheckSec = 0;
|
|
this._polyCheckCount = 0;
|
|
this._polyCheckSec = 0
|
|
}
|
|
Release() {
|
|
this._runtime = null
|
|
}
|
|
_Update1sStats() {
|
|
this._collisionCheckSec = this._collisionCheckCount;
|
|
this._collisionCheckCount = 0;
|
|
this._polyCheckSec = this._polyCheckCount;
|
|
this._polyCheckCount = 0
|
|
}
|
|
Get1secCollisionChecks() {
|
|
return this._collisionCheckSec
|
|
}
|
|
Get1secPolyChecks() {
|
|
return this._polyCheckSec
|
|
}
|
|
RegisterCollision(a, b) {
|
|
const aw = a.GetWorldInfo();
|
|
const bw = b.GetWorldInfo();
|
|
if (!aw || !bw)
|
|
return;
|
|
if (!aw.IsCollisionEnabled() || !bw.IsCollisionEnabled())
|
|
return;
|
|
this._registeredCollisions.push([a, b])
|
|
}
|
|
AddRegisteredCollisionCandidates(inst, otherType, arr) {
|
|
for (const [a,b] of this._registeredCollisions) {
|
|
let otherInst = null;
|
|
if (inst === a)
|
|
otherInst = b;
|
|
else if (inst === b)
|
|
otherInst = a;
|
|
else
|
|
continue;
|
|
if (!otherInst.BelongsToObjectClass(otherType))
|
|
continue;
|
|
if (!arr.includes(otherInst))
|
|
arr.push(otherInst)
|
|
}
|
|
}
|
|
CheckRegisteredCollision(a, b) {
|
|
if (!this._registeredCollisions.length)
|
|
return false;
|
|
for (const [c,d] of this._registeredCollisions)
|
|
if (a === c && b === d || a === d && b === c)
|
|
return true;
|
|
return false
|
|
}
|
|
ClearRegisteredCollisions() {
|
|
C3.clearArray(this._registeredCollisions)
|
|
}
|
|
TestOverlap(a, b) {
|
|
if (!a || !b || a === b)
|
|
return false;
|
|
const aw = a.GetWorldInfo();
|
|
const bw = b.GetWorldInfo();
|
|
if (!aw.IsCollisionEnabled() || !bw.IsCollisionEnabled())
|
|
return false;
|
|
this._collisionCheckCount++;
|
|
const layerA = aw.GetLayer();
|
|
const layerB = bw.GetLayer();
|
|
const areLayerTransformsCompatible = layerA.IsTransformCompatibleWith(layerB);
|
|
if (areLayerTransformsCompatible)
|
|
return this._TestOverlap_SameLayers(aw, bw);
|
|
else
|
|
return this._TestOverlap_DifferentLayers(aw, bw)
|
|
}
|
|
_TestOverlap_SameLayers(aw, bw) {
|
|
if (!aw.GetBoundingBox().intersectsRect(bw.GetBoundingBox()))
|
|
return false;
|
|
this._polyCheckCount++;
|
|
if (!aw.GetBoundingQuad().intersectsQuad(bw.GetBoundingQuad()))
|
|
return false;
|
|
if (aw.HasTilemap() && bw.HasTilemap())
|
|
return false;
|
|
if (aw.HasTilemap())
|
|
return this.TestTilemapOverlap(aw, bw);
|
|
else if (bw.HasTilemap())
|
|
return this.TestTilemapOverlap(bw, aw);
|
|
if (!aw.HasOwnCollisionPoly() && !bw.HasOwnCollisionPoly())
|
|
return true;
|
|
const polyA = aw.GetTransformedCollisionPoly();
|
|
const polyB = bw.GetTransformedCollisionPoly();
|
|
return polyA.intersectsPoly(polyB, bw.GetX() - aw.GetX(), bw.GetY() - aw.GetY())
|
|
}
|
|
_TestOverlap_DifferentLayers(aw, bw) {
|
|
const layerA = aw.GetLayer();
|
|
const layerB = bw.GetLayer();
|
|
tempPolyA.copy(aw.GetTransformedCollisionPoly());
|
|
tempPolyB.copy(bw.GetTransformedCollisionPoly());
|
|
const ptsArrA = tempPolyA.pointsArr();
|
|
for (let i = 0, len = ptsArrA.length; i < len; i += 2) {
|
|
const j = i + 1;
|
|
const x = ptsArrA[i];
|
|
const y = ptsArrA[j];
|
|
const [lx,ly] = layerA.LayerToCanvasCss(x + aw.GetX(), y + aw.GetY());
|
|
ptsArrA[i] = lx;
|
|
ptsArrA[j] = ly
|
|
}
|
|
const ptsArrB = tempPolyB.pointsArr();
|
|
for (let i = 0, len = ptsArrB.length; i < len; i += 2) {
|
|
const j = i + 1;
|
|
const x = ptsArrB[i];
|
|
const y = ptsArrB[j];
|
|
const [lx,ly] = layerB.LayerToCanvasCss(x + bw.GetX(), y + bw.GetY());
|
|
ptsArrB[i] = lx;
|
|
ptsArrB[j] = ly
|
|
}
|
|
tempPolyA.setBboxChanged();
|
|
tempPolyB.setBboxChanged();
|
|
this._polyCheckCount++;
|
|
return tempPolyA.intersectsPoly(tempPolyB, 0, 0)
|
|
}
|
|
TestTilemapOverlap(tmWi, wi) {
|
|
const bbox = wi.GetBoundingBox();
|
|
const tmX = tmWi.GetX();
|
|
const tmY = tmWi.GetY();
|
|
const tmSdkInst = tmWi.GetInstance().GetSdkInstance();
|
|
const instX = wi.GetX();
|
|
const instY = wi.GetY();
|
|
const instHasPoly = wi.HasOwnCollisionPoly();
|
|
const instQuad = wi.GetBoundingQuad();
|
|
const collRects = tileCollRectCandidates;
|
|
tmSdkInst.GetCollisionRectCandidates(bbox, collRects);
|
|
for (let i = 0, len = collRects.length; i < len; ++i) {
|
|
const c = collRects[i];
|
|
const rc = c.GetRect();
|
|
this._collisionCheckCount++;
|
|
if (bbox.intersectsRectOffset(rc, tmX, tmY)) {
|
|
tempQuad.setFromRect(rc);
|
|
tempQuad.offset(tmX, tmY);
|
|
if (tempQuad.intersectsQuad(instQuad))
|
|
if (instHasPoly) {
|
|
const instPoly = wi.GetTransformedCollisionPoly();
|
|
const tilePoly = c.GetPoly();
|
|
if (tilePoly) {
|
|
this._polyCheckCount++;
|
|
if (tilePoly.intersectsPoly(instPoly, instX - (tmX + rc.getLeft()), instY - (tmY + rc.getTop()))) {
|
|
C3.clearArray(collRects);
|
|
return true
|
|
}
|
|
} else {
|
|
tempPolyA.setFromQuad(tempQuad, 0, 0);
|
|
if (tempPolyA.intersectsPoly(instPoly, instX, instY)) {
|
|
C3.clearArray(collRects);
|
|
return true
|
|
}
|
|
}
|
|
} else {
|
|
const tilePoly = c.GetPoly();
|
|
if (tilePoly) {
|
|
tempPolyA.setFromQuad(instQuad, 0, 0);
|
|
if (tilePoly.intersectsPoly(tempPolyA, -(tmX + rc.getLeft()), -(tmY + rc.getTop()))) {
|
|
C3.clearArray(collRects);
|
|
return true
|
|
}
|
|
} else {
|
|
C3.clearArray(collRects);
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
C3.clearArray(collRects);
|
|
return false
|
|
}
|
|
TestAndSelectCanvasPointOverlap(objectClass, ptx, pty, isInverted) {
|
|
const sol = objectClass.GetCurrentSol();
|
|
const currentEvent = this._runtime.GetCurrentEvent();
|
|
if (!currentEvent)
|
|
throw new Error("cannot call outside event");
|
|
const isOrBlock = currentEvent.IsOrBlock();
|
|
if (sol.IsSelectAll()) {
|
|
if (!isInverted) {
|
|
sol._SetSelectAll(false);
|
|
C3.clearArray(sol._GetOwnInstances())
|
|
}
|
|
for (const inst of objectClass.GetInstances()) {
|
|
const wi = inst.GetWorldInfo();
|
|
const layer = wi.GetLayer();
|
|
const [lx,ly] = layer.CanvasCssToLayer(ptx, pty, wi.GetTotalZElevation());
|
|
if (wi.ContainsPoint(lx, ly))
|
|
if (isInverted)
|
|
return false;
|
|
else
|
|
sol._PushInstance(inst);
|
|
else if (isOrBlock)
|
|
sol._PushElseInstance(inst)
|
|
}
|
|
} else {
|
|
const arr = isOrBlock ? sol._GetOwnElseInstances() : sol._GetOwnInstances();
|
|
let j = 0;
|
|
for (let i = 0, len = arr.length; i < len; ++i) {
|
|
const inst = arr[i];
|
|
const wi = inst.GetWorldInfo();
|
|
const layer = wi.GetLayer();
|
|
const [lx,ly] = layer.CanvasCssToLayer(ptx, pty, wi.GetTotalZElevation());
|
|
if (wi.ContainsPoint(lx, ly))
|
|
if (isInverted)
|
|
return false;
|
|
else if (isOrBlock)
|
|
sol._PushInstance(inst);
|
|
else
|
|
arr[j++] = inst;
|
|
else if (isOrBlock)
|
|
arr[j++] = inst
|
|
}
|
|
if (!isInverted)
|
|
arr.length = j
|
|
}
|
|
objectClass.ApplySolToContainer();
|
|
if (isInverted)
|
|
return true;
|
|
else
|
|
return sol.HasAnyInstances()
|
|
}
|
|
GetCollisionCandidates(layer, rtype, bbox, candidates) {
|
|
const isParallaxed = layer ? layer.GetParallaxX() !== 1 || layer.GetParallaxY() !== 1 : false;
|
|
if (rtype.IsFamily())
|
|
for (const memberType of rtype.GetFamilyMembers())
|
|
if (isParallaxed || memberType.IsAnyInstanceParallaxed())
|
|
C3.appendArray(candidates, memberType.GetInstances());
|
|
else {
|
|
memberType._UpdateAllCollisionCells();
|
|
memberType._GetCollisionCellGrid().QueryRange(bbox, candidates)
|
|
}
|
|
else if (isParallaxed || rtype.IsAnyInstanceParallaxed())
|
|
C3.appendArray(candidates, rtype.GetInstances());
|
|
else {
|
|
rtype._UpdateAllCollisionCells();
|
|
rtype._GetCollisionCellGrid().QueryRange(bbox, candidates)
|
|
}
|
|
}
|
|
GetObjectClassesCollisionCandidates(layer, objectClasses, bbox, candidates) {
|
|
for (const objectClass of objectClasses)
|
|
this.GetCollisionCandidates(layer, objectClass, bbox, candidates)
|
|
}
|
|
GetSolidCollisionCandidates(layer, bbox, candidates) {
|
|
const solidBehavior = this._runtime.GetSolidBehavior();
|
|
if (!solidBehavior)
|
|
return;
|
|
this.GetObjectClassesCollisionCandidates(layer, solidBehavior.GetObjectClasses(), bbox, candidates)
|
|
}
|
|
GetJumpthruCollisionCandidates(layer, bbox, candidates) {
|
|
const jumpthruBehavior = this._runtime.GetJumpthruBehavior();
|
|
if (!jumpthruBehavior)
|
|
return;
|
|
this.GetObjectClassesCollisionCandidates(layer, jumpthruBehavior.GetObjectClasses(), bbox, candidates)
|
|
}
|
|
IsSolidCollisionAllowed(solidInst, inst) {
|
|
return solidInst._IsSolidEnabled() && (!inst || inst.GetWorldInfo().IsSolidCollisionAllowed(solidInst.GetSavedDataMap().get("solidTags")))
|
|
}
|
|
TestOverlapSolid(inst) {
|
|
const wi = inst.GetWorldInfo();
|
|
this.GetSolidCollisionCandidates(wi.GetLayer(), wi.GetBoundingBox(), tempCandidates);
|
|
for (const s of tempCandidates) {
|
|
if (!this.IsSolidCollisionAllowed(s, inst))
|
|
continue;
|
|
if (this.TestOverlap(inst, s)) {
|
|
C3.clearArray(tempCandidates);
|
|
return s
|
|
}
|
|
}
|
|
C3.clearArray(tempCandidates);
|
|
return null
|
|
}
|
|
TestRectOverlapSolid(rect, inst) {
|
|
this.GetSolidCollisionCandidates(null, rect, tempCandidates);
|
|
for (const s of tempCandidates) {
|
|
if (!this.IsSolidCollisionAllowed(s, inst))
|
|
continue;
|
|
if (this.TestRectOverlap(rect, s)) {
|
|
C3.clearArray(tempCandidates);
|
|
return s
|
|
}
|
|
}
|
|
C3.clearArray(tempCandidates);
|
|
return null
|
|
}
|
|
TestOverlapJumpthru(inst, all) {
|
|
let ret = null;
|
|
if (all) {
|
|
ret = tempJumpthruRet;
|
|
C3.clearArray(ret)
|
|
}
|
|
const wi = inst.GetWorldInfo();
|
|
this.GetJumpthruCollisionCandidates(wi.GetLayer(), wi.GetBoundingBox(), tempCandidates);
|
|
for (const j of tempCandidates) {
|
|
if (!j._IsJumpthruEnabled())
|
|
continue;
|
|
if (this.TestOverlap(inst, j))
|
|
if (all)
|
|
ret.push(j);
|
|
else {
|
|
C3.clearArray(tempCandidates);
|
|
return j
|
|
}
|
|
}
|
|
C3.clearArray(tempCandidates);
|
|
return ret
|
|
}
|
|
PushOut(inst, xdir, ydir, dist, otherInst) {
|
|
dist = dist || 50;
|
|
const wi = inst.GetWorldInfo();
|
|
const oldX = wi.GetX();
|
|
const oldY = wi.GetY();
|
|
for (let i = 0; i < dist; ++i) {
|
|
wi.SetXY(oldX + xdir * i, oldY + ydir * i);
|
|
wi.SetBboxChanged();
|
|
if (!this.TestOverlap(inst, otherInst))
|
|
return true
|
|
}
|
|
wi.SetXY(oldX, oldY);
|
|
wi.SetBboxChanged();
|
|
return false
|
|
}
|
|
PushOutSolid(inst, xdir, ydir, dist, includeJumpthrus, specificJumpthru) {
|
|
dist = dist || 50;
|
|
const wi = inst.GetWorldInfo();
|
|
const oldX = wi.GetX();
|
|
const oldY = wi.GetY();
|
|
let lastOverlapped = null;
|
|
let secondLastOverlapped = null;
|
|
for (let i = 0; i < dist; ++i) {
|
|
wi.SetXY(oldX + xdir * i, oldY + ydir * i);
|
|
wi.SetBboxChanged();
|
|
if (!this.TestOverlap(inst, lastOverlapped)) {
|
|
lastOverlapped = this.TestOverlapSolid(inst);
|
|
if (lastOverlapped)
|
|
secondLastOverlapped = lastOverlapped;
|
|
else {
|
|
if (includeJumpthrus) {
|
|
if (specificJumpthru)
|
|
lastOverlapped = this.TestOverlap(inst, specificJumpthru) ? specificJumpthru : null;
|
|
else
|
|
lastOverlapped = this.TestOverlapJumpthru(inst);
|
|
if (lastOverlapped)
|
|
secondLastOverlapped = lastOverlapped
|
|
}
|
|
if (!lastOverlapped) {
|
|
if (secondLastOverlapped)
|
|
this.PushInFractional(inst, xdir, ydir, secondLastOverlapped, 16, true);
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
wi.SetXY(oldX, oldY);
|
|
wi.SetBboxChanged();
|
|
return false
|
|
}
|
|
PushOutSolidAxis(inst, xdir, ydir, dist) {
|
|
dist = dist || 50;
|
|
const wi = inst.GetWorldInfo();
|
|
const oldX = wi.GetX();
|
|
const oldY = wi.GetY();
|
|
let lastOverlapped = null;
|
|
let secondLastOverlapped = null;
|
|
for (let i = 0; i < dist; ++i)
|
|
for (let which = 0; which < 2; ++which) {
|
|
const sign = which * 2 - 1;
|
|
wi.SetXY(oldX + xdir * i * sign, oldY + ydir * i * sign);
|
|
wi.SetBboxChanged();
|
|
if (!this.TestOverlap(inst, lastOverlapped)) {
|
|
lastOverlapped = this.TestOverlapSolid(inst);
|
|
if (lastOverlapped)
|
|
secondLastOverlapped = lastOverlapped;
|
|
else {
|
|
if (secondLastOverlapped)
|
|
this.PushInFractional(inst, xdir * sign, ydir * sign, secondLastOverlapped, 16, true);
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
wi.SetXY(oldX, oldY);
|
|
wi.SetBboxChanged();
|
|
return false
|
|
}
|
|
PushInFractional(inst, xdir, ydir, otherInst, limit, includeAnySolid) {
|
|
let divisor = 2;
|
|
let forward = false;
|
|
let overlapping = false;
|
|
const wi = inst.GetWorldInfo();
|
|
let bestX = wi.GetX();
|
|
let bestY = wi.GetY();
|
|
while (divisor <= limit) {
|
|
const frac = 1 / divisor;
|
|
divisor *= 2;
|
|
wi.OffsetXY(xdir * frac * (forward ? 1 : -1), ydir * frac * (forward ? 1 : -1));
|
|
wi.SetBboxChanged();
|
|
if (this.TestOverlap(inst, otherInst) || includeAnySolid && this.TestOverlapSolid(inst)) {
|
|
forward = true;
|
|
overlapping = true
|
|
} else {
|
|
forward = false;
|
|
overlapping = false;
|
|
bestX = wi.GetX();
|
|
bestY = wi.GetY()
|
|
}
|
|
}
|
|
if (overlapping) {
|
|
wi.SetXY(bestX, bestY);
|
|
wi.SetBboxChanged()
|
|
}
|
|
}
|
|
PushOutSolidNearest(inst, maxDist=100) {
|
|
let dist = 0;
|
|
const wi = inst.GetWorldInfo();
|
|
const oldX = wi.GetX();
|
|
const oldY = wi.GetY();
|
|
let dir = 0;
|
|
let lastOverlapped = this.TestOverlapSolid(inst);
|
|
if (!lastOverlapped)
|
|
return true;
|
|
while (dist <= maxDist) {
|
|
let dx = 0;
|
|
let dy = 0;
|
|
switch (dir) {
|
|
case 0:
|
|
dx = 0;
|
|
dy = -1;
|
|
dist++;
|
|
break;
|
|
case 1:
|
|
dx = 1;
|
|
dy = -1;
|
|
break;
|
|
case 2:
|
|
dx = 1;
|
|
dy = 0;
|
|
break;
|
|
case 3:
|
|
dx = 1;
|
|
dy = 1;
|
|
break;
|
|
case 4:
|
|
dx = 0;
|
|
dy = 1;
|
|
break;
|
|
case 5:
|
|
dx = -1;
|
|
dy = 1;
|
|
break;
|
|
case 6:
|
|
dx = -1;
|
|
dy = 0;
|
|
break;
|
|
case 7:
|
|
dx = -1;
|
|
dy = -1;
|
|
break
|
|
}
|
|
dir = (dir + 1) % 8;
|
|
wi.SetXY(Math.floor(oldX + dx * dist), Math.floor(oldY + dy * dist));
|
|
wi.SetBboxChanged();
|
|
if (!this.TestOverlap(inst, lastOverlapped)) {
|
|
lastOverlapped = this.TestOverlapSolid(inst);
|
|
if (!lastOverlapped)
|
|
return true
|
|
}
|
|
}
|
|
wi.SetXY(oldX, oldY);
|
|
wi.SetBboxChanged();
|
|
return false
|
|
}
|
|
CalculateBounceAngle(inst, startX, startY, otherInst) {
|
|
const wi = inst.GetWorldInfo();
|
|
const oldX = wi.GetX();
|
|
const oldY = wi.GetY();
|
|
const radius = Math.max(10, C3.distanceTo(startX, startY, oldX, oldY));
|
|
const startAngle = C3.angleTo(startX, startY, oldX, oldY);
|
|
const firstInst = otherInst || this.TestOverlapSolid(inst);
|
|
if (!firstInst)
|
|
return C3.clampAngle(startAngle + Math.PI);
|
|
let curInst = firstInst;
|
|
let anticlockwiseFreeAngle = 0;
|
|
let clockwiseFreeAngle = 0;
|
|
const increment = C3.toRadians(5);
|
|
let i;
|
|
for (i = 1; i < 36; ++i) {
|
|
const curAngle = startAngle - i * increment;
|
|
wi.SetXY(startX + Math.cos(curAngle) * radius, startY + Math.sin(curAngle) * radius);
|
|
wi.SetBboxChanged();
|
|
if (!this.TestOverlap(inst, curInst)) {
|
|
curInst = otherInst ? null : this.TestOverlapSolid(inst);
|
|
if (!curInst) {
|
|
anticlockwiseFreeAngle = curAngle;
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if (i === 36)
|
|
anticlockwiseFreeAngle = C3.clampAngle(startAngle + Math.PI);
|
|
curInst = firstInst;
|
|
for (i = 1; i < 36; ++i) {
|
|
const curAngle = startAngle + i * increment;
|
|
wi.SetXY(startX + Math.cos(curAngle) * radius, startY + Math.sin(curAngle) * radius);
|
|
wi.SetBboxChanged();
|
|
if (!this.TestOverlap(inst, curInst)) {
|
|
curInst = otherInst ? null : this.TestOverlapSolid(inst);
|
|
if (!curInst) {
|
|
clockwiseFreeAngle = curAngle;
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if (i === 36)
|
|
clockwiseFreeAngle = C3.clampAngle(startAngle + Math.PI);
|
|
wi.SetXY(oldX, oldY);
|
|
wi.SetBboxChanged();
|
|
if (clockwiseFreeAngle === anticlockwiseFreeAngle)
|
|
return clockwiseFreeAngle;
|
|
const halfDiff = C3.angleDiff(clockwiseFreeAngle, anticlockwiseFreeAngle) / 2;
|
|
let normal;
|
|
if (C3.angleClockwise(clockwiseFreeAngle, anticlockwiseFreeAngle))
|
|
normal = C3.clampAngle(anticlockwiseFreeAngle + halfDiff + Math.PI);
|
|
else
|
|
normal = C3.clampAngle(clockwiseFreeAngle + halfDiff);
|
|
const vx = Math.cos(startAngle);
|
|
const vy = Math.sin(startAngle);
|
|
const nx = Math.cos(normal);
|
|
const ny = Math.sin(normal);
|
|
const v_dot_n = vx * nx + vy * ny;
|
|
const rx = vx - 2 * v_dot_n * nx;
|
|
const ry = vy - 2 * v_dot_n * ny;
|
|
return C3.angleTo(0, 0, rx, ry)
|
|
}
|
|
TestSegmentOverlap(x1, y1, x2, y2, inst) {
|
|
if (!inst)
|
|
return false;
|
|
const wi = inst.GetWorldInfo();
|
|
if (!wi.IsCollisionEnabled())
|
|
return false;
|
|
this._collisionCheckCount++;
|
|
tempRect.set(Math.min(x1, x2), Math.min(y1, y2), Math.max(x1, x2), Math.max(y1, y2));
|
|
if (!wi.GetBoundingBox().intersectsRect(tempRect))
|
|
return false;
|
|
if (inst.HasTilemap())
|
|
return this._TestSegmentOverlapTilemap(x1, y1, x2, y2, inst, wi);
|
|
this._polyCheckCount++;
|
|
if (!wi.GetBoundingQuad().intersectsSegment(x1, y1, x2, y2))
|
|
return false;
|
|
if (!wi.HasOwnCollisionPoly())
|
|
return true;
|
|
const poly = wi.GetTransformedCollisionPoly();
|
|
return poly.intersectsSegment(wi.GetX(), wi.GetY(), x1, y1, x2, y2)
|
|
}
|
|
_TestSegmentOverlapTilemap(x1, y1, x2, y2, inst, wi) {
|
|
const tmX = wi.GetX();
|
|
const tmY = wi.GetY();
|
|
const sdkInst = inst.GetSdkInstance();
|
|
const collRects = tileCollRectCandidates;
|
|
tempRect2.set(x1, y1, x2, y2);
|
|
tempRect2.normalize();
|
|
sdkInst.GetCollisionRectCandidates(tempRect2, collRects);
|
|
for (let i = 0, len = collRects.length; i < len; ++i) {
|
|
const c = collRects[i];
|
|
const tileRc = c.GetRect();
|
|
this._collisionCheckCount++;
|
|
if (tempRect.intersectsRectOffset(tileRc, tmX, tmY)) {
|
|
tempQuad.setFromRect(tileRc);
|
|
tempQuad.offset(tmX, tmY);
|
|
if (tempQuad.intersectsSegment(x1, y1, x2, y2)) {
|
|
const tilePoly = c.GetPoly();
|
|
if (tilePoly) {
|
|
this._polyCheckCount++;
|
|
if (tilePoly.intersectsSegment(tmX + tileRc.getLeft(), tmY + tileRc.getTop(), x1, y1, x2, y2)) {
|
|
C3.clearArray(collRects);
|
|
return true
|
|
}
|
|
} else {
|
|
C3.clearArray(collRects);
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
C3.clearArray(collRects);
|
|
return false
|
|
}
|
|
TestRectOverlap(rect, inst) {
|
|
if (!inst)
|
|
return false;
|
|
const wi = inst.GetWorldInfo();
|
|
if (!wi.IsCollisionEnabled())
|
|
return false;
|
|
this._collisionCheckCount++;
|
|
if (!wi.GetBoundingBox().intersectsRect(rect))
|
|
return false;
|
|
if (inst.HasTilemap())
|
|
return this._TestRectOverlapTilemap(rect, inst, wi);
|
|
this._polyCheckCount++;
|
|
tempQuad.setFromRect(rect);
|
|
if (!wi.GetBoundingQuad().intersectsQuad(tempQuad))
|
|
return false;
|
|
if (!wi.HasOwnCollisionPoly())
|
|
return true;
|
|
const polyA = tempPolyA;
|
|
polyA.setFromRect(rect, wi.GetX(), wi.GetY());
|
|
const polyB = wi.GetTransformedCollisionPoly();
|
|
return polyA.intersectsPoly(polyB, 0, 0)
|
|
}
|
|
_TestRectOverlapTilemap(rect, inst, wi) {
|
|
const tmX = wi.GetX();
|
|
const tmY = wi.GetY();
|
|
const sdkInst = inst.GetSdkInstance();
|
|
const collRects = tileCollRectCandidates;
|
|
sdkInst.GetCollisionRectCandidates(rect, collRects);
|
|
for (let i = 0, len = collRects.length; i < len; ++i) {
|
|
const c = collRects[i];
|
|
const tileRc = c.GetRect();
|
|
this._collisionCheckCount++;
|
|
if (rect.intersectsRectOffset(tileRc, tmX, tmY)) {
|
|
const tilePoly = c.GetPoly();
|
|
if (tilePoly) {
|
|
this._polyCheckCount++;
|
|
tempPolyA.setFromRect(rect, 0, 0);
|
|
if (tilePoly.intersectsPoly(tempPolyA, -(tmX + tileRc.getLeft()), -(tmY + tileRc.getTop()))) {
|
|
C3.clearArray(collRects);
|
|
return true
|
|
}
|
|
} else {
|
|
C3.clearArray(collRects);
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
C3.clearArray(collRects);
|
|
return false
|
|
}
|
|
TestRayIntersectsInstance(inst, ray) {
|
|
if (!inst)
|
|
return;
|
|
const wi = inst.GetWorldInfo();
|
|
if (!wi.IsCollisionEnabled())
|
|
return;
|
|
this._collisionCheckCount++;
|
|
if (!wi.GetBoundingBox().intersectsRect(ray.rect))
|
|
return;
|
|
if (inst.HasTilemap()) {
|
|
this._TestRayIntersectsTilemap(inst, wi, ray);
|
|
return
|
|
}
|
|
this._polyCheckCount++;
|
|
if (wi.HasOwnCollisionPoly())
|
|
ray.TestInstancePoly(inst, wi.GetX(), wi.GetY(), wi.GetTransformedCollisionPoly());
|
|
else
|
|
ray.TestInstanceQuad(inst, wi.GetBoundingQuad())
|
|
}
|
|
_TestRayIntersectsTilemap(inst, wi, ray) {
|
|
const xOffset = wi.GetX();
|
|
const yOffset = wi.GetY();
|
|
const collRects = tileCollRectCandidates;
|
|
inst.GetSdkInstance().GetCollisionRectCandidates(ray.rect, collRects);
|
|
for (let i = 0, l = collRects.length; i < l; i++) {
|
|
const c = collRects[i];
|
|
const tileRc = c.GetRect();
|
|
this._collisionCheckCount++;
|
|
if (ray.rect.intersectsRectOffset(tileRc, xOffset, yOffset)) {
|
|
const tilePoly = c.GetPoly();
|
|
this._polyCheckCount++;
|
|
if (tilePoly)
|
|
ray.TestInstancePoly(inst, xOffset + tileRc.getLeft(), yOffset + tileRc.getTop(), tilePoly);
|
|
else
|
|
ray.TestInstanceRect(inst, wi.GetX(), wi.GetY(), tileRc)
|
|
}
|
|
}
|
|
C3.clearArray(collRects)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.SparseGrid = class SparseGrid extends C3.DefendedBase {
|
|
constructor(cellWidth, cellHeight) {
|
|
super();
|
|
this._cellWidth = cellWidth;
|
|
this._cellHeight = cellHeight;
|
|
this._cells = C3.New(C3.PairMap)
|
|
}
|
|
Release() {
|
|
this._cells.Release();
|
|
this._cells = null
|
|
}
|
|
GetCell(x, y, createIfMissing) {
|
|
let ret = this._cells.Get(x, y);
|
|
if (ret)
|
|
return ret;
|
|
else if (createIfMissing) {
|
|
ret = C3.New(C3.GridCell, this, x, y);
|
|
this._cells.Set(x, y, ret);
|
|
return ret
|
|
} else
|
|
return null
|
|
}
|
|
XToCell(x) {
|
|
const ret = Math.floor(x / this._cellWidth);
|
|
return isFinite(ret) ? ret : 0
|
|
}
|
|
YToCell(y) {
|
|
const ret = Math.floor(y / this._cellHeight);
|
|
return isFinite(ret) ? ret : 0
|
|
}
|
|
Update(inst, oldRange, newRange) {
|
|
if (oldRange)
|
|
for (let x = oldRange.getLeft(), lenx = oldRange.getRight(); x <= lenx; ++x)
|
|
for (let y = oldRange.getTop(), leny = oldRange.getBottom(); y <= leny; ++y) {
|
|
if (newRange && newRange.containsPoint(x, y))
|
|
continue;
|
|
const cell = this.GetCell(x, y, false);
|
|
if (!cell)
|
|
continue;
|
|
cell.Remove(inst);
|
|
if (cell.IsEmpty())
|
|
this._cells.Delete(x, y)
|
|
}
|
|
if (newRange)
|
|
for (let x = newRange.getLeft(), lenx = newRange.getRight(); x <= lenx; ++x)
|
|
for (let y = newRange.getTop(), leny = newRange.getBottom(); y <= leny; ++y) {
|
|
if (oldRange && oldRange.containsPoint(x, y))
|
|
continue;
|
|
this.GetCell(x, y, true).Insert(inst)
|
|
}
|
|
}
|
|
QueryRange(rc, result) {
|
|
let x = this.XToCell(rc.getLeft());
|
|
const ystart = this.YToCell(rc.getTop());
|
|
const lenx = this.XToCell(rc.getRight());
|
|
const leny = this.YToCell(rc.getBottom());
|
|
if (!isFinite(lenx) || !isFinite(leny))
|
|
return;
|
|
for (; x <= lenx; ++x)
|
|
for (let y = ystart; y <= leny; ++y) {
|
|
const cell = this.GetCell(x, y, false);
|
|
if (!cell)
|
|
continue;
|
|
cell.Dump(result)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.GridCell = class GridCell extends C3.DefendedBase {
|
|
constructor(grid, x, y) {
|
|
super();
|
|
this._grid = grid;
|
|
this._x = x;
|
|
this._y = y;
|
|
this._instances = C3.New(C3.ArraySet)
|
|
}
|
|
Release() {
|
|
this._instances.Release();
|
|
this._instances = null;
|
|
this._grid = null
|
|
}
|
|
IsEmpty() {
|
|
return this._instances.IsEmpty()
|
|
}
|
|
Insert(inst) {
|
|
this._instances.Add(inst)
|
|
}
|
|
Remove(inst) {
|
|
this._instances.Delete(inst)
|
|
}
|
|
Dump(result) {
|
|
C3.appendArray(result, this._instances.GetArray())
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const PADDING = 1E-6;
|
|
const NO_HIT = 2;
|
|
C3.Ray = class Ray {
|
|
constructor() {
|
|
this.x1 = 0;
|
|
this.y1 = 0;
|
|
this.x2 = 0;
|
|
this.y2 = 0;
|
|
this.dx = 0;
|
|
this.dy = 0;
|
|
this.rect = new C3.Rect;
|
|
this.hitFraction = NO_HIT;
|
|
this.hitUid = null;
|
|
this.hitNormal = 0;
|
|
this.hitNormalDx = 0;
|
|
this.hitNormalDy = 0;
|
|
this.hitX = 0;
|
|
this.hitY = 0;
|
|
this.distance = 0;
|
|
this.normalX = 1;
|
|
this.normalY = 0;
|
|
this.reflectionX = 1;
|
|
this.reflectionY = 0
|
|
}
|
|
DidCollide() {
|
|
return this.hitFraction < 1 + PADDING
|
|
}
|
|
Set(x1, y1, x2, y2) {
|
|
this.x1 = x1;
|
|
this.y1 = y1;
|
|
this.x2 = x2;
|
|
this.y2 = y2;
|
|
this.dx = x2 - x1;
|
|
this.dy = y2 - y1;
|
|
this.rect.set(x1, y1, x2, y2);
|
|
this.rect.normalize();
|
|
this.hitFraction = NO_HIT;
|
|
this.hitUid = null;
|
|
this.hitNormal = 0;
|
|
this.hitNormalDx = 0;
|
|
this.hitNormalDy = 0;
|
|
this.hitX = 0;
|
|
this.hitY = 0;
|
|
this.distance = 0;
|
|
this.normalX = 1;
|
|
this.normalY = 0;
|
|
this.reflectionX = 1;
|
|
this.reflectionY = 0;
|
|
return this
|
|
}
|
|
Complete() {
|
|
if (this.DidCollide() === false)
|
|
return;
|
|
const dx = this.dx * this.hitFraction;
|
|
const dy = this.dy * this.hitFraction;
|
|
const length = Math.sqrt(dx * dx + dy * dy);
|
|
const dirx = dx / length;
|
|
const diry = dy / length;
|
|
this.distance = length - PADDING;
|
|
this.hitX = this.x1 + dirx * this.distance;
|
|
this.hitY = this.y1 + diry * this.distance;
|
|
this.hitNormal = Math.atan2(this.hitNormalDy, this.hitNormalDx) + Math.PI / 2;
|
|
this.normalX = Math.cos(this.hitNormal);
|
|
this.normalY = Math.sin(this.hitNormal);
|
|
const dot = dirx * this.normalX + diry * this.normalY;
|
|
this.reflectionX = dirx - 2 * this.normalX * dot;
|
|
this.reflectionY = diry - 2 * this.normalY * dot;
|
|
if (dot > 0) {
|
|
const PI = Math.PI;
|
|
this.hitNormal = C3.clampAngle(this.hitNormal + PI);
|
|
this.normalX = -this.normalX;
|
|
this.normalY = -this.normalY
|
|
}
|
|
}
|
|
TestInstanceSegment(inst, sx1, sy1, sx2, sy2) {
|
|
const t = C3.rayIntersect(this.x1, this.y1, this.x2, this.y2, sx1, sy1, sx2, sy2);
|
|
if (t >= 0 && t < this.hitFraction) {
|
|
this.hitFraction = t;
|
|
this.hitUid = inst.GetUID();
|
|
this.hitNormalDx = sx1 - sx2;
|
|
this.hitNormalDy = sy1 - sy2
|
|
}
|
|
}
|
|
TestInstanceRect(inst, offX, offY, rect) {
|
|
const lt = offX + rect.getLeft()
|
|
, rt = offX + rect.getRight()
|
|
, tp = offY + rect.getTop()
|
|
, bm = offY + rect.getBottom();
|
|
this.TestInstanceSegment(inst, lt, tp, rt, tp);
|
|
this.TestInstanceSegment(inst, rt, tp, rt, bm);
|
|
this.TestInstanceSegment(inst, rt, bm, lt, bm);
|
|
this.TestInstanceSegment(inst, lt, bm, lt, tp)
|
|
}
|
|
TestInstanceQuad(inst, quad) {
|
|
const tlX = quad.getTlx()
|
|
, tlY = quad.getTly()
|
|
, trX = quad.getTrx()
|
|
, trY = quad.getTry()
|
|
, brX = quad.getBrx()
|
|
, brY = quad.getBry()
|
|
, blX = quad.getBlx()
|
|
, blY = quad.getBly();
|
|
this.TestInstanceSegment(inst, tlX, tlY, trX, trY);
|
|
this.TestInstanceSegment(inst, trX, trY, brX, brY);
|
|
this.TestInstanceSegment(inst, brX, brY, blX, blY);
|
|
this.TestInstanceSegment(inst, blX, blY, tlX, tlY)
|
|
}
|
|
TestInstancePoly(inst, offX, offY, poly) {
|
|
const points = poly.pointsArr();
|
|
for (let i = 0, l = points.length; i < l; i += 2) {
|
|
const ii = (i + 2) % l;
|
|
const x1 = points[i] + offX;
|
|
const y1 = points[i + 1] + offY;
|
|
const x2 = points[ii] + offX;
|
|
const y2 = points[ii + 1] + offY;
|
|
this.TestInstanceSegment(inst, x1, y1, x2, y2)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const VALID_FULLSCREEN_MODES = new Set(["off", "crop", "scale-inner", "scale-outer", "letterbox-scale", "letterbox-integer-scale"]);
|
|
const VALID_FULLSCREEN_SCALING_QUALITIES = new Set(["high", "low"]);
|
|
const PERCENTTEXT_WIDTH = 300;
|
|
const PERCENTTEXT_HEIGHT = 200;
|
|
const PROGRESSBAR_WIDTH = 120;
|
|
const PROGRESSBAR_HEIGHT = 8;
|
|
const tempQuad = C3.New(C3.Quad);
|
|
const tempRect = C3.New(C3.Rect);
|
|
const SPLASH_MIN_DISPLAY_TIME = 3E3;
|
|
const SPLASH_AFTER_FADEOUT_WAIT_TIME = 200;
|
|
const SPLASH_FADE_DURATION = 300;
|
|
C3.CanvasManager = class CanvasManager extends C3.DefendedBase {
|
|
constructor(runtime) {
|
|
super();
|
|
this._runtime = runtime;
|
|
this._canvas = null;
|
|
this._webglRenderer = null;
|
|
this._gpuPreference = "high-performance";
|
|
this._windowInnerWidth = 0;
|
|
this._windowInnerHeight = 0;
|
|
this._canvasCssWidth = 0;
|
|
this._canvasCssHeight = 0;
|
|
this._canvasDeviceWidth = 0;
|
|
this._canvasDeviceHeight = 0;
|
|
this._canvasCssOffsetX = 0;
|
|
this._canvasCssOffsetY = 0;
|
|
this._enableMipmaps = true;
|
|
this._drawWidth = 0;
|
|
this._drawHeight = 0;
|
|
this._fullscreenMode = "letterbox-scale";
|
|
this._documentFullscreenMode = "letterbox-scale";
|
|
this._deviceTransformOffX = 0;
|
|
this._deviceTransformOffY = 0;
|
|
this._wantFullscreenScalingQuality = "high";
|
|
this._fullscreenScalingQuality = this._wantFullscreenScalingQuality;
|
|
this._isDocumentFullscreen = false;
|
|
this._availableAdditionalRenderTargets = [];
|
|
this._usedAdditionalRenderTargets = new Set;
|
|
this._shaderData = null;
|
|
this._gpuFrameTimingsBuffer = null;
|
|
this._gpuTimeStartFrame = 0;
|
|
this._gpuTimeEndFrame = 0;
|
|
this._gpuCurUtilisation = NaN;
|
|
this._gpuLastUtilisation = 0;
|
|
this._layersGpuProfile = new Map;
|
|
this._snapshotFormat = "";
|
|
this._snapshotQuality = 1;
|
|
this._snapshotArea = C3.New(C3.Rect);
|
|
this._snapshotUrl = "";
|
|
this._snapshotPromise = null;
|
|
this._snapshotResolve = null;
|
|
this._loaderStartTime = 0;
|
|
this._rafId = -1;
|
|
this._loadingProgress = 0;
|
|
this._loadingprogress_handler = e=>this._loadingProgress = e.progress;
|
|
this._percentText = null;
|
|
this._loadingLogoAsset = null;
|
|
this._splashTextures = {
|
|
logo: null,
|
|
powered: null,
|
|
website: null
|
|
};
|
|
this._splashFrameNumber = 0;
|
|
this._splashFadeInFinishTime = 0;
|
|
this._splashFadeOutStartTime = 0;
|
|
this._splashState = "fade-in";
|
|
this._splashDoneResolve = null;
|
|
this._splashDonePromise = new Promise(resolve=>this._splashDoneResolve = resolve)
|
|
}
|
|
_SetGPUPowerPreference(pref) {
|
|
this._gpuPreference = pref
|
|
}
|
|
async CreateCanvas(opts) {
|
|
this._canvas = opts["canvas"];
|
|
this._canvas.addEventListener("webglcontextlost", e=>this._OnWebGLContextLost(e));
|
|
this._canvas.addEventListener("webglcontextrestored", e=>this._OnWebGLContextRestored(e));
|
|
const rendererOpts = {
|
|
powerPreference: this._gpuPreference,
|
|
enableGpuProfiling: true
|
|
};
|
|
if (C3.Platform.OS === "Android" && C3.Platform.BrowserEngine === "Chromium" && C3.Platform.BrowserVersionNumber < 75) {
|
|
console.warn("[Construct 3] Disabling WebGL 2 because this device appears to be affected by crbug.com/934823. Install software updates to avoid this.");
|
|
rendererOpts.maxWebGLVersion = 1
|
|
}
|
|
if (this._runtime.GetCompositingMode() === "standard")
|
|
rendererOpts.alpha = true;
|
|
else {
|
|
rendererOpts.alpha = false;
|
|
rendererOpts.lowLatency = true
|
|
}
|
|
this._webglRenderer = C3.New(C3.Gfx.WebGLRenderer, this._canvas, rendererOpts);
|
|
await this._webglRenderer.InitState();
|
|
if (!this._webglRenderer.SupportsGPUProfiling())
|
|
this._gpuLastUtilisation = NaN;
|
|
this._runtime.AddDOMComponentMessageHandler("runtime", "window-resize", e=>this._OnWindowResize(e));
|
|
this._runtime.AddDOMComponentMessageHandler("runtime", "fullscreenchange", e=>this._OnFullscreenChange(e));
|
|
this._runtime.AddDOMComponentMessageHandler("runtime", "fullscreenerror", e=>this._OnFullscreenError(e));
|
|
this._isDocumentFullscreen = !!opts["isFullscreen"];
|
|
this.SetSize(opts["windowInnerWidth"], opts["windowInnerHeight"], true);
|
|
this._shaderData = self["C3_Shaders"];
|
|
await this._LoadShaderPrograms();
|
|
let hasAnyBackgroundBlending = false;
|
|
for (const effectList of this._runtime._GetAllEffectLists()) {
|
|
for (const effectType of effectList.GetAllEffectTypes()) {
|
|
effectType._InitRenderer(this._webglRenderer);
|
|
if (effectType.GetShaderProgram().UsesDest())
|
|
hasAnyBackgroundBlending = true
|
|
}
|
|
effectList.UpdateActiveEffects()
|
|
}
|
|
this._runtime._SetUsesAnyBackgroundBlending(hasAnyBackgroundBlending);
|
|
if (this._webglRenderer.SupportsGPUProfiling())
|
|
this._gpuFrameTimingsBuffer = C3.New(C3.Gfx.WebGLQueryResultBuffer, this._webglRenderer);
|
|
this._webglRenderer.SetMipmapsEnabled(this._enableMipmaps)
|
|
}
|
|
async _LoadShaderPrograms() {
|
|
if (!this._shaderData)
|
|
return;
|
|
const promises = [];
|
|
for (const [id,data] of Object.entries(this._shaderData)) {
|
|
const vertexSrc = C3.Gfx.WebGLShaderProgram.GetDefaultVertexShaderSource(this._webglRenderer.Is3D());
|
|
promises.push(this._webglRenderer.CreateShaderProgram(data, vertexSrc, id))
|
|
}
|
|
await Promise.all(promises);
|
|
this._webglRenderer.ResetLastProgram();
|
|
this._webglRenderer.SetTextureFillMode()
|
|
}
|
|
Release() {
|
|
this._runtime = null;
|
|
this._webglRenderer = null;
|
|
this._canvas = null
|
|
}
|
|
_OnWindowResize(e) {
|
|
const dpr = e["devicePixelRatio"];
|
|
if (this._runtime.IsInWorker())
|
|
self.devicePixelRatio = dpr;
|
|
this._runtime._SetDevicePixelRatio(dpr);
|
|
this.SetSize(e["innerWidth"], e["innerHeight"]);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_OnFullscreenChange(e) {
|
|
this._isDocumentFullscreen = !!e["isFullscreen"];
|
|
this.SetSize(e["innerWidth"], e["innerHeight"], true);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_OnFullscreenError(e) {
|
|
this._isDocumentFullscreen = !!e["isFullscreen"];
|
|
this.SetSize(e["innerWidth"], e["innerHeight"], true);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
SetSize(availableWidth, availableHeight, force=false) {
|
|
availableWidth = Math.floor(availableWidth);
|
|
availableHeight = Math.floor(availableHeight);
|
|
if (availableWidth <= 0 || availableHeight <= 0)
|
|
throw new Error("invalid size");
|
|
if (this._windowInnerWidth === availableWidth && this._windowInnerHeight === availableHeight && !force)
|
|
return;
|
|
this._windowInnerWidth = availableWidth;
|
|
this._windowInnerHeight = availableHeight;
|
|
const fullscreenMode = this.GetCurrentFullscreenMode();
|
|
if (fullscreenMode === "letterbox-scale")
|
|
this._CalculateLetterboxScale(availableWidth, availableHeight);
|
|
else if (fullscreenMode === "letterbox-integer-scale")
|
|
this._CalculateLetterboxIntegerScale(availableWidth, availableHeight);
|
|
else if (fullscreenMode === "off")
|
|
this._CalculateFixedSizeCanvas(availableWidth, availableHeight);
|
|
else
|
|
this._CalculateFullsizeCanvas(availableWidth, availableHeight);
|
|
this._UpdateFullscreenScalingQuality(fullscreenMode);
|
|
this._canvas.width = this._canvasDeviceWidth;
|
|
this._canvas.height = this._canvasDeviceHeight;
|
|
this._runtime.PostComponentMessageToDOM("canvas", "update-size", {
|
|
"marginLeft": this._canvasCssOffsetX,
|
|
"marginTop": this._canvasCssOffsetY,
|
|
"styleWidth": this._canvasCssWidth,
|
|
"styleHeight": this._canvasCssHeight
|
|
});
|
|
this._webglRenderer.SetSize(this._canvasDeviceWidth, this._canvasDeviceHeight, true)
|
|
}
|
|
_CalculateLetterboxScale(availableWidth, availableHeight) {
|
|
const dpr = this._runtime.GetDevicePixelRatio();
|
|
const originalViewportWidth = this._runtime.GetOriginalViewportWidth();
|
|
const originalViewportHeight = this._runtime.GetOriginalViewportHeight();
|
|
const originalAspectRatio = originalViewportWidth / originalViewportHeight;
|
|
const availableAspectRatio = availableWidth / availableHeight;
|
|
if (availableAspectRatio > originalAspectRatio) {
|
|
const letterboxedWidth = availableHeight * originalAspectRatio;
|
|
this._canvasCssWidth = Math.round(letterboxedWidth);
|
|
this._canvasCssHeight = availableHeight;
|
|
this._canvasCssOffsetX = Math.floor((availableWidth - this._canvasCssWidth) / 2);
|
|
this._canvasCssOffsetY = 0
|
|
} else {
|
|
const letterboxedHeight = availableWidth / originalAspectRatio;
|
|
this._canvasCssWidth = availableWidth;
|
|
this._canvasCssHeight = Math.round(letterboxedHeight);
|
|
this._canvasCssOffsetX = 0;
|
|
this._canvasCssOffsetY = Math.floor((availableHeight - this._canvasCssHeight) / 2)
|
|
}
|
|
this._canvasDeviceWidth = Math.round(this._canvasCssWidth * dpr);
|
|
this._canvasDeviceHeight = Math.round(this._canvasCssHeight * dpr);
|
|
this._runtime.SetViewportSize(originalViewportWidth, originalViewportHeight)
|
|
}
|
|
_CalculateLetterboxIntegerScale(availableWidth, availableHeight) {
|
|
const dpr = this._runtime.GetDevicePixelRatio();
|
|
if (dpr !== 1) {
|
|
availableWidth += 1;
|
|
availableHeight += 1
|
|
}
|
|
const originalViewportWidth = this._runtime.GetOriginalViewportWidth();
|
|
const originalViewportHeight = this._runtime.GetOriginalViewportHeight();
|
|
const originalAspectRatio = originalViewportWidth / originalViewportHeight;
|
|
const availableAspectRatio = availableWidth / availableHeight;
|
|
let intScale;
|
|
if (availableAspectRatio > originalAspectRatio) {
|
|
const letterboxedWidth = availableHeight * originalAspectRatio;
|
|
intScale = letterboxedWidth * dpr / originalViewportWidth
|
|
} else {
|
|
const letterboxedHeight = availableWidth / originalAspectRatio;
|
|
intScale = letterboxedHeight * dpr / originalViewportHeight
|
|
}
|
|
if (intScale > 1)
|
|
intScale = Math.floor(intScale);
|
|
else if (intScale < 1)
|
|
intScale = 1 / Math.ceil(1 / intScale);
|
|
this._canvasDeviceWidth = Math.round(originalViewportWidth * intScale);
|
|
this._canvasDeviceHeight = Math.round(originalViewportHeight * intScale);
|
|
this._canvasCssWidth = this._canvasDeviceWidth / dpr;
|
|
this._canvasCssHeight = this._canvasDeviceHeight / dpr;
|
|
this._canvasCssOffsetX = Math.max(Math.floor((availableWidth - this._canvasCssWidth) / 2), 0);
|
|
this._canvasCssOffsetY = Math.max(Math.floor((availableHeight - this._canvasCssHeight) / 2), 0);
|
|
this._runtime.SetViewportSize(originalViewportWidth, originalViewportHeight)
|
|
}
|
|
_CalculateFullsizeCanvas(availableWidth, availableHeight) {
|
|
const dpr = this._runtime.GetDevicePixelRatio();
|
|
this._canvasCssWidth = availableWidth;
|
|
this._canvasCssHeight = availableHeight;
|
|
this._canvasDeviceWidth = Math.round(this._canvasCssWidth * dpr);
|
|
this._canvasDeviceHeight = Math.round(this._canvasCssHeight * dpr);
|
|
this._canvasCssOffsetX = 0;
|
|
this._canvasCssOffsetY = 0;
|
|
const displayScale = this.GetDisplayScale();
|
|
this._runtime.SetViewportSize(this._canvasCssWidth / displayScale, this._canvasCssHeight / displayScale)
|
|
}
|
|
_CalculateFixedSizeCanvas(availableWidth, availableHeight) {
|
|
const dpr = this._runtime.GetDevicePixelRatio();
|
|
this._canvasCssWidth = this._runtime.GetViewportWidth();
|
|
this._canvasCssHeight = this._runtime.GetViewportHeight();
|
|
this._canvasDeviceWidth = Math.round(this._canvasCssWidth * dpr);
|
|
this._canvasDeviceHeight = Math.round(this._canvasCssHeight * dpr);
|
|
if (this.IsDocumentFullscreen()) {
|
|
this._canvasCssOffsetX = Math.floor((availableWidth - this._canvasCssWidth) / 2);
|
|
this._canvasCssOffsetY = Math.floor((availableHeight - this._canvasCssHeight) / 2)
|
|
} else {
|
|
this._canvasCssOffsetX = 0;
|
|
this._canvasCssOffsetY = 0
|
|
}
|
|
this._runtime.SetViewportSize(this._runtime.GetViewportWidth(), this._runtime.GetViewportHeight())
|
|
}
|
|
_UpdateFullscreenScalingQuality(fullscreenMode) {
|
|
if (this._wantFullscreenScalingQuality === "high") {
|
|
this._drawWidth = this._canvasDeviceWidth;
|
|
this._drawHeight = this._canvasDeviceHeight;
|
|
this._fullscreenScalingQuality = "high"
|
|
} else {
|
|
let viewportWidth, viewportHeight;
|
|
if (this.GetCurrentFullscreenMode() === "off") {
|
|
viewportWidth = this._runtime.GetViewportWidth();
|
|
viewportHeight = this._runtime.GetViewportHeight()
|
|
} else {
|
|
viewportWidth = this._runtime.GetOriginalViewportWidth();
|
|
viewportHeight = this._runtime.GetOriginalViewportHeight()
|
|
}
|
|
if (this._canvasDeviceWidth < viewportWidth && this._canvasDeviceHeight < viewportHeight) {
|
|
this._drawWidth = this._canvasDeviceWidth;
|
|
this._drawHeight = this._canvasDeviceHeight;
|
|
this._fullscreenScalingQuality = "high"
|
|
} else {
|
|
this._drawWidth = viewportWidth;
|
|
this._drawHeight = viewportHeight;
|
|
this._fullscreenScalingQuality = "low";
|
|
if (fullscreenMode === "scale-inner") {
|
|
const originalAspectRatio = viewportWidth / viewportHeight;
|
|
const currentAspectRatio = this._windowInnerWidth / this._windowInnerHeight;
|
|
if (currentAspectRatio < originalAspectRatio)
|
|
this._drawWidth = this._drawHeight * currentAspectRatio;
|
|
else if (currentAspectRatio > originalAspectRatio)
|
|
this._drawHeight = this._drawWidth / currentAspectRatio
|
|
} else if (fullscreenMode === "scale-outer") {
|
|
const originalAspectRatio = viewportWidth / viewportHeight;
|
|
const currentAspectRatio = this._windowInnerWidth / this._windowInnerHeight;
|
|
if (currentAspectRatio > originalAspectRatio)
|
|
this._drawWidth = this._drawHeight * currentAspectRatio;
|
|
else if (currentAspectRatio < originalAspectRatio)
|
|
this._drawHeight = this._drawWidth / currentAspectRatio
|
|
}
|
|
}
|
|
}
|
|
}
|
|
IsDocumentFullscreen() {
|
|
return this._isDocumentFullscreen
|
|
}
|
|
SetFullscreenMode(m) {
|
|
if (!VALID_FULLSCREEN_MODES.has(m))
|
|
throw new Error("invalid fullscreen mode");
|
|
this._fullscreenMode = m
|
|
}
|
|
GetFullscreenMode() {
|
|
return this._fullscreenMode
|
|
}
|
|
SetDocumentFullscreenMode(m) {
|
|
if (!VALID_FULLSCREEN_MODES.has(m))
|
|
throw new Error("invalid fullscreen mode");
|
|
this._documentFullscreenMode = m
|
|
}
|
|
GetDocumentFullscreenMode() {
|
|
return this._documentFullscreenMode
|
|
}
|
|
GetCurrentFullscreenMode() {
|
|
if (this.IsDocumentFullscreen())
|
|
return this.GetDocumentFullscreenMode();
|
|
else
|
|
return this.GetFullscreenMode()
|
|
}
|
|
SetFullscreenScalingQuality(q) {
|
|
if (!VALID_FULLSCREEN_SCALING_QUALITIES.has(q))
|
|
throw new Error("invalid fullscreen scaling quality");
|
|
this._wantFullscreenScalingQuality = q
|
|
}
|
|
GetSetFullscreenScalingQuality() {
|
|
return this._wantFullscreenScalingQuality
|
|
}
|
|
GetCurrentFullscreenScalingQuality() {
|
|
return this._fullscreenScalingQuality
|
|
}
|
|
static _FullscreenModeNumberToString(n) {
|
|
switch (n) {
|
|
case 0:
|
|
return "off";
|
|
case 1:
|
|
return "crop";
|
|
case 2:
|
|
return "scale-inner";
|
|
case 3:
|
|
return "scale-outer";
|
|
case 4:
|
|
return "letterbox-scale";
|
|
case 5:
|
|
return "letterbox-integer-scale";
|
|
default:
|
|
throw new Error("invalid fullscreen mode");
|
|
}
|
|
}
|
|
GetLastWidth() {
|
|
return this._windowInnerWidth
|
|
}
|
|
GetLastHeight() {
|
|
return this._windowInnerHeight
|
|
}
|
|
GetDrawWidth() {
|
|
return this._drawWidth
|
|
}
|
|
GetDrawHeight() {
|
|
return this._drawHeight
|
|
}
|
|
SetMipmapsEnabled(e) {
|
|
this._enableMipmaps = !!e
|
|
}
|
|
IsWebGLContextLost() {
|
|
return this._webglRenderer.IsContextLost()
|
|
}
|
|
_OnWebGLContextLost(e) {
|
|
console.log("[Construct 3] WebGL context lost");
|
|
e.preventDefault();
|
|
this._availableAdditionalRenderTargets = [];
|
|
this._usedAdditionalRenderTargets.clear();
|
|
this._webglRenderer.OnContextLost();
|
|
this._runtime._OnWebGLContextLost()
|
|
}
|
|
async _OnWebGLContextRestored(e) {
|
|
await this._webglRenderer.OnContextRestored();
|
|
await this._LoadShaderPrograms();
|
|
for (const effectList of this._runtime._GetAllEffectLists())
|
|
for (const effectType of effectList.GetAllEffectTypes())
|
|
effectType._InitRenderer(this._webglRenderer);
|
|
await this._runtime._OnWebGLContextRestored();
|
|
console.log("[Construct 3] WebGL context restored")
|
|
}
|
|
GetWebGLRenderer() {
|
|
return this._webglRenderer
|
|
}
|
|
GetRenderScale() {
|
|
if (this._fullscreenScalingQuality === "low")
|
|
return 1 / this._runtime.GetDevicePixelRatio();
|
|
return this.GetDisplayScale()
|
|
}
|
|
GetDisplayScale() {
|
|
const fullscreenMode = this.GetCurrentFullscreenMode();
|
|
if (fullscreenMode === "off" || fullscreenMode === "crop")
|
|
return 1;
|
|
const originalViewportWidth = this._runtime.GetOriginalViewportWidth();
|
|
const originalViewportHeight = this._runtime.GetOriginalViewportHeight();
|
|
const originalAspectRatio = originalViewportWidth / originalViewportHeight;
|
|
const currentAspectRatio = this._canvasDeviceWidth / this._canvasDeviceHeight;
|
|
if (fullscreenMode !== "scale-inner" && currentAspectRatio > originalAspectRatio || fullscreenMode === "scale-inner" && currentAspectRatio < originalAspectRatio)
|
|
return this._canvasCssHeight / originalViewportHeight;
|
|
else
|
|
return this._canvasCssWidth / originalViewportWidth
|
|
}
|
|
SetDeviceTransformOffset(x, y) {
|
|
this._deviceTransformOffX = x;
|
|
this._deviceTransformOffY = y
|
|
}
|
|
SetDeviceTransform(renderer, w, h) {
|
|
const scrollX = (w || this._drawWidth) / 2 + this._deviceTransformOffX;
|
|
const scrollY = (h || this._drawHeight) / 2 + this._deviceTransformOffY;
|
|
renderer.SetCameraXYZ(scrollX, scrollY, 100 * this._runtime.GetDevicePixelRatio());
|
|
renderer.SetLookXYZ(scrollX, scrollY, 0);
|
|
renderer.ResetModelView();
|
|
renderer.UpdateModelView()
|
|
}
|
|
SetCssTransform(renderer) {
|
|
const scrollX = this._canvasCssWidth / 2;
|
|
const scrollY = this._canvasCssHeight / 2;
|
|
renderer.SetCameraXYZ(scrollX, scrollY, 100);
|
|
renderer.SetLookXYZ(scrollX, scrollY, 0);
|
|
renderer.ResetModelView();
|
|
renderer.UpdateModelView()
|
|
}
|
|
GetDeviceWidth() {
|
|
return this._canvasDeviceWidth
|
|
}
|
|
GetDeviceHeight() {
|
|
return this._canvasDeviceHeight
|
|
}
|
|
GetCssWidth() {
|
|
return this._canvasCssWidth
|
|
}
|
|
GetCssHeight() {
|
|
return this._canvasCssHeight
|
|
}
|
|
GetCanvasClientX() {
|
|
return this._canvasCssOffsetX
|
|
}
|
|
GetCanvasClientY() {
|
|
return this._canvasCssOffsetY
|
|
}
|
|
GetAdditionalRenderTarget(opts) {
|
|
const arr = this._availableAdditionalRenderTargets;
|
|
const useIndex = arr.findIndex(rt=>rt.IsCompatibleWithOptions(opts));
|
|
let ret;
|
|
if (useIndex !== -1) {
|
|
ret = arr[useIndex];
|
|
arr.splice(useIndex, 1)
|
|
} else
|
|
ret = this._webglRenderer.CreateRenderTarget(opts);
|
|
this._usedAdditionalRenderTargets.add(ret);
|
|
return ret
|
|
}
|
|
ReleaseAdditionalRenderTarget(renderTarget) {
|
|
if (!this._usedAdditionalRenderTargets.has(renderTarget))
|
|
throw new Error("render target not in use");
|
|
this._usedAdditionalRenderTargets.delete(renderTarget);
|
|
this._availableAdditionalRenderTargets.push(renderTarget)
|
|
}
|
|
*activeLayersGpuProfiles() {
|
|
for (const layout of this._runtime.GetLayoutManager().runningLayouts())
|
|
for (const layer of layout.GetLayers()) {
|
|
const p = this._layersGpuProfile.get(layer);
|
|
if (p)
|
|
yield p
|
|
}
|
|
}
|
|
GetLayerTimingsBuffer(layer) {
|
|
if (!this._webglRenderer.SupportsGPUProfiling())
|
|
return null;
|
|
let p = this._layersGpuProfile.get(layer);
|
|
if (!p) {
|
|
p = {
|
|
name: layer.GetName(),
|
|
timingsBuffer: C3.New(C3.Gfx.WebGLQueryResultBuffer, this._webglRenderer),
|
|
curUtilisation: 0,
|
|
lastUtilisation: 0
|
|
};
|
|
this._layersGpuProfile.set(layer, p)
|
|
}
|
|
return p.timingsBuffer
|
|
}
|
|
_Update1sFrameRange() {
|
|
if (!this._webglRenderer.SupportsGPUProfiling())
|
|
return;
|
|
if (this._gpuTimeEndFrame === 0) {
|
|
this._gpuTimeEndFrame = this._webglRenderer.GetFrameNumber();
|
|
this._gpuCurUtilisation = NaN;
|
|
for (const p of this.activeLayersGpuProfiles())
|
|
p.curUtilisation = NaN
|
|
}
|
|
}
|
|
_UpdateTick() {
|
|
if (!this._webglRenderer.SupportsGPUProfiling() || !isNaN(this._gpuCurUtilisation))
|
|
return;
|
|
this._gpuCurUtilisation = this._gpuFrameTimingsBuffer.GetFrameRangeResultSum(this._gpuTimeStartFrame, this._gpuTimeEndFrame);
|
|
if (isNaN(this._gpuCurUtilisation))
|
|
return;
|
|
if (this._runtime.IsDebug())
|
|
for (const p of this.activeLayersGpuProfiles()) {
|
|
p.curUtilisation = p.timingsBuffer.GetFrameRangeResultSum(this._gpuTimeStartFrame, this._gpuTimeEndFrame);
|
|
if (isNaN(p.curUtilisation))
|
|
return
|
|
}
|
|
this._gpuFrameTimingsBuffer.DeleteAllBeforeFrameNumber(this._gpuTimeEndFrame);
|
|
this._gpuLastUtilisation = Math.min(this._gpuCurUtilisation, 1);
|
|
if (this._runtime.IsDebug()) {
|
|
for (const p of this.activeLayersGpuProfiles()) {
|
|
p.timingsBuffer.DeleteAllBeforeFrameNumber(this._gpuTimeEndFrame);
|
|
p.lastUtilisation = Math.min(p.curUtilisation, 1)
|
|
}
|
|
self.C3Debugger.UpdateGPUProfile(this._gpuLastUtilisation, [...this.activeLayersGpuProfiles()])
|
|
}
|
|
this._gpuTimeStartFrame = this._gpuTimeEndFrame;
|
|
this._gpuTimeEndFrame = 0
|
|
}
|
|
GetGPUFrameTimingsBuffer() {
|
|
return this._gpuFrameTimingsBuffer
|
|
}
|
|
GetGPUUtilisation() {
|
|
return this._gpuLastUtilisation
|
|
}
|
|
SnapshotCanvas(format, quality, x, y, width, height) {
|
|
this._snapshotFormat = format;
|
|
this._snapshotQuality = quality;
|
|
this._snapshotArea.setWH(x, y, width, height);
|
|
if (this._snapshotPromise)
|
|
return this._snapshotPromise;
|
|
this._snapshotPromise = new Promise(resolve=>{
|
|
this._snapshotResolve = resolve
|
|
}
|
|
);
|
|
return this._snapshotPromise
|
|
}
|
|
_MaybeTakeSnapshot() {
|
|
if (!this._snapshotFormat)
|
|
return;
|
|
let canvas = this._canvas;
|
|
const snapArea = this._snapshotArea;
|
|
const x = C3.clamp(Math.floor(snapArea.getLeft()), 0, canvas.width);
|
|
const y = C3.clamp(Math.floor(snapArea.getTop()), 0, canvas.height);
|
|
let w = snapArea.width();
|
|
if (w === 0)
|
|
w = canvas.width - x;
|
|
else
|
|
w = C3.clamp(Math.floor(w), 0, canvas.width - x);
|
|
let h = snapArea.height();
|
|
if (h === 0)
|
|
h = canvas.height - y;
|
|
else
|
|
h = C3.clamp(Math.floor(h), 0, canvas.height - y);
|
|
if ((x !== 0 || y !== 0 || w !== canvas.width || h !== canvas.height) && (w > 0 && h > 0)) {
|
|
canvas = C3.CreateCanvas(w, h);
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.drawImage(this._canvas, x, y, w, h, 0, 0, w, h)
|
|
}
|
|
C3.CanvasToBlob(canvas, this._snapshotFormat, this._snapshotQuality).then(blob=>{
|
|
this._snapshotUrl = URL.createObjectURL(blob);
|
|
this._snapshotPromise = null;
|
|
this._snapshotResolve(this._snapshotUrl)
|
|
}
|
|
);
|
|
this._snapshotFormat = "";
|
|
this._snapshotQuality = 1
|
|
}
|
|
GetCanvasSnapshotUrl() {
|
|
return this._snapshotUrl
|
|
}
|
|
InitLoadingScreen(loaderStyle) {
|
|
if (loaderStyle === 2) {
|
|
this._percentText = C3.New(C3.Gfx.RendererText, this._webglRenderer);
|
|
this._percentText.SetIsAsync(false);
|
|
this._percentText.SetFontName("Arial");
|
|
this._percentText.SetFontSize(16);
|
|
this._percentText.SetHorizontalAlignment("center");
|
|
this._percentText.SetVerticalAlignment("center");
|
|
this._percentText.SetSize(PERCENTTEXT_WIDTH, PERCENTTEXT_HEIGHT)
|
|
} else if (loaderStyle === 0) {
|
|
const loadingLogoFilename = this._runtime.GetLoadingLogoFilename();
|
|
const assetManager = this._runtime.GetAssetManager();
|
|
let url;
|
|
if (this._runtime.IsPreview()) {
|
|
if (!assetManager._HasLocalUrlBlob(loadingLogoFilename))
|
|
return;
|
|
url = assetManager.GetLocalUrlAsBlobUrl(loadingLogoFilename)
|
|
} else
|
|
url = assetManager.GetIconsSubfolder() + loadingLogoFilename;
|
|
this._loadingLogoAsset = assetManager.LoadImage({
|
|
url
|
|
});
|
|
this._loadingLogoAsset.LoadStaticTexture(this._webglRenderer).catch(err=>console.warn(`[C3 runtime] Failed to load '${loadingLogoFilename}' for loading screen. Check the project has an icon with that name.`, err))
|
|
} else if (loaderStyle === 4) {
|
|
this._LoadSvgSplashImage("splash-images/splash-logo.svg").then(tex=>{
|
|
if (this._splashState === "done")
|
|
this._webglRenderer.DeleteTexture(tex);
|
|
else
|
|
this._splashTextures.logo = tex
|
|
}
|
|
).catch(err=>console.warn("Failed to load splash image: ", err));
|
|
this._LoadBitmapSplashImage("splash-images/splash-poweredby-512.png").then(tex=>{
|
|
if (this._splashState === "done")
|
|
this._webglRenderer.DeleteTexture(tex);
|
|
else
|
|
this._splashTextures.powered = tex
|
|
}
|
|
).catch(err=>console.warn("Failed to load splash image: ", err));
|
|
this._LoadBitmapSplashImage("splash-images/splash-website-512.png").then(tex=>{
|
|
if (this._splashState === "done")
|
|
this._webglRenderer.DeleteTexture(tex);
|
|
else
|
|
this._splashTextures.website = tex
|
|
}
|
|
).catch(err=>console.warn("Failed to load splash image: ", err))
|
|
}
|
|
}
|
|
async _LoadSvgSplashImage(url) {
|
|
url = (new URL(url,this._runtime.GetBaseURL())).toString();
|
|
const blob = await C3.FetchBlob(url);
|
|
const drawable = await this._runtime.RasterSvgImage(blob, 2048, 2048);
|
|
return await this._webglRenderer.CreateStaticTextureAsync(drawable, {
|
|
mipMapQuality: "high"
|
|
})
|
|
}
|
|
async _LoadBitmapSplashImage(url) {
|
|
url = (new URL(url,this._runtime.GetBaseURL())).toString();
|
|
const blob = await C3.FetchBlob(url);
|
|
return await this._webglRenderer.CreateStaticTextureAsync(blob, {
|
|
mipMapQuality: "high"
|
|
})
|
|
}
|
|
HideCordovaSplashScreen() {
|
|
this._runtime.PostComponentMessageToDOM("runtime", "hide-cordova-splash")
|
|
}
|
|
StartLoadingScreen() {
|
|
this._loaderStartTime = Date.now();
|
|
this._runtime.Dispatcher().addEventListener("loadingprogress", this._loadingprogress_handler);
|
|
this._rafId = requestAnimationFrame(()=>this._DrawLoadingScreen());
|
|
const loaderStyle = this._runtime.GetLoaderStyle();
|
|
if (loaderStyle !== 3)
|
|
this.HideCordovaSplashScreen()
|
|
}
|
|
async EndLoadingScreen() {
|
|
this._loadingProgress = 1;
|
|
const loaderStyle = this._runtime.GetLoaderStyle();
|
|
if (loaderStyle === 4)
|
|
await this._splashDonePromise;
|
|
this._splashDoneResolve = null;
|
|
this._splashDonePromise = null;
|
|
if (this._rafId !== -1) {
|
|
cancelAnimationFrame(this._rafId);
|
|
this._rafId = -1
|
|
}
|
|
this._runtime.Dispatcher().removeEventListener("loadingprogress", this._loadingprogress_handler);
|
|
this._loadingprogress_handler = null;
|
|
if (this._percentText) {
|
|
this._percentText.Release();
|
|
this._percentText = null
|
|
}
|
|
if (this._loadingLogoAsset) {
|
|
this._loadingLogoAsset.Release();
|
|
this._loadingLogoAsset = null
|
|
}
|
|
this._webglRenderer.Start();
|
|
if (this._splashTextures.logo) {
|
|
this._webglRenderer.DeleteTexture(this._splashTextures.logo);
|
|
this._splashTextures.logo = null
|
|
}
|
|
if (this._splashTextures.powered) {
|
|
this._webglRenderer.DeleteTexture(this._splashTextures.powered);
|
|
this._splashTextures.powered = null
|
|
}
|
|
if (this._splashTextures.website) {
|
|
this._webglRenderer.DeleteTexture(this._splashTextures.website);
|
|
this._splashTextures.website = null
|
|
}
|
|
this._webglRenderer.ClearRgba(0, 0, 0, 0);
|
|
this._webglRenderer.Finish();
|
|
this._splashState = "done";
|
|
this._gpuTimeStartFrame = this._webglRenderer.GetFrameNumber();
|
|
if (loaderStyle === 3)
|
|
this.HideCordovaSplashScreen()
|
|
}
|
|
_DrawLoadingScreen() {
|
|
if (this._rafId === -1)
|
|
return;
|
|
const renderer = this._webglRenderer;
|
|
renderer.Start();
|
|
this._rafId = -1;
|
|
const hasHadError = this._runtime.GetAssetManager().HasHadErrorLoading();
|
|
const loaderStyle = this._runtime.GetLoaderStyle();
|
|
if (loaderStyle !== 3) {
|
|
this.SetCssTransform(renderer);
|
|
renderer.ClearRgba(0, 0, 0, 0);
|
|
renderer.ResetColor();
|
|
renderer.SetTextureFillMode();
|
|
renderer.SetTexture(null)
|
|
}
|
|
if (loaderStyle === 0)
|
|
this._DrawProgressBarAndLogoLoadingScreen(hasHadError);
|
|
else if (loaderStyle === 1)
|
|
this._DrawProgressBarLoadingScreen(hasHadError, PROGRESSBAR_WIDTH, 0);
|
|
else if (loaderStyle === 2)
|
|
this._DrawPercentTextLoadingScreen(hasHadError);
|
|
else if (loaderStyle === 3)
|
|
C3.noop();
|
|
else if (loaderStyle === 4)
|
|
this._DrawSplashLoadingScreen(hasHadError);
|
|
else
|
|
throw new Error("invalid loader style");
|
|
renderer.Finish();
|
|
this._rafId = requestAnimationFrame(()=>this._DrawLoadingScreen())
|
|
}
|
|
_DrawPercentTextLoadingScreen(hasHadError) {
|
|
if (hasHadError)
|
|
this._percentText.SetColorRgb(1, 0, 0);
|
|
else
|
|
this._percentText.SetColorRgb(.6, .6, .6);
|
|
this._percentText.SetText(Math.round(this._loadingProgress * 100) + "%");
|
|
const midX = this._canvasCssWidth / 2;
|
|
const midY = this._canvasCssHeight / 2;
|
|
const hw = PERCENTTEXT_WIDTH / 2;
|
|
const hh = PERCENTTEXT_HEIGHT / 2;
|
|
tempQuad.setRect(midX - hw, midY - hh, midX + hw, midY + hh);
|
|
this._webglRenderer.SetTexture(this._percentText.GetTexture());
|
|
this._webglRenderer.Quad3(tempQuad, this._percentText.GetTexRect())
|
|
}
|
|
_DrawProgressBarLoadingScreen(hasHadError, width, yOff) {
|
|
const renderer = this._webglRenderer;
|
|
const height = PROGRESSBAR_HEIGHT;
|
|
renderer.SetColorFillMode();
|
|
if (hasHadError)
|
|
renderer.SetColorRgba(1, 0, 0, 1);
|
|
else
|
|
renderer.SetColorRgba(.118, .565, 1, 1);
|
|
const midX = this._canvasCssWidth / 2;
|
|
const midY = this._canvasCssHeight / 2;
|
|
const hw = width / 2;
|
|
const hh = height / 2;
|
|
tempRect.setWH(midX - hw, midY - hh + yOff, Math.floor(width * this._loadingProgress), height);
|
|
renderer.Rect(tempRect);
|
|
tempRect.setWH(midX - hw, midY - hh + yOff, width, height);
|
|
tempRect.offset(-.5, -.5);
|
|
tempRect.inflate(.5, .5);
|
|
renderer.SetColorRgba(0, 0, 0, 1);
|
|
renderer.LineRect2(tempRect);
|
|
tempRect.inflate(1, 1);
|
|
renderer.SetColorRgba(1, 1, 1, 1);
|
|
renderer.LineRect2(tempRect)
|
|
}
|
|
_DrawProgressBarAndLogoLoadingScreen(hasHadError) {
|
|
if (!this._loadingLogoAsset) {
|
|
this._DrawProgressBarLoadingScreen(hasHadError, PROGRESSBAR_WIDTH, 0);
|
|
return
|
|
}
|
|
const logoTexture = this._loadingLogoAsset.GetTexture();
|
|
if (!logoTexture) {
|
|
this._DrawProgressBarLoadingScreen(hasHadError, PROGRESSBAR_WIDTH, 0);
|
|
return
|
|
}
|
|
const logoW = logoTexture.GetWidth();
|
|
const logoH = logoTexture.GetHeight();
|
|
const midX = this._canvasCssWidth / 2;
|
|
const midY = this._canvasCssHeight / 2;
|
|
const hw = logoW / 2;
|
|
const hh = logoH / 2;
|
|
tempQuad.setRect(midX - hw, midY - hh, midX + hw, midY + hh);
|
|
this._webglRenderer.SetTexture(logoTexture);
|
|
this._webglRenderer.Quad(tempQuad);
|
|
this._DrawProgressBarLoadingScreen(hasHadError, logoW, hh + 16)
|
|
}
|
|
_DrawSplashLoadingScreen(hasHadError) {
|
|
const renderer = this._webglRenderer;
|
|
const logoTex = this._splashTextures.logo;
|
|
const poweredTex = this._splashTextures.powered;
|
|
const websiteTex = this._splashTextures.website;
|
|
const nowTime = Date.now();
|
|
if (this._splashFrameNumber === 0)
|
|
this._loaderStartTime = nowTime;
|
|
const allowQuickSplash = this._runtime.IsPreview() || this._runtime.IsFBInstantAvailable() && !this._runtime.IsCordova();
|
|
const splashAfterFadeOutWait = allowQuickSplash ? 0 : SPLASH_AFTER_FADEOUT_WAIT_TIME;
|
|
const splashMinDisplayTime = allowQuickSplash ? 0 : SPLASH_MIN_DISPLAY_TIME;
|
|
let a = 1;
|
|
if (this._splashState === "fade-in")
|
|
a = Math.min((nowTime - this._loaderStartTime) / SPLASH_FADE_DURATION, 1);
|
|
else if (this._splashState === "fade-out")
|
|
a = Math.max(1 - (nowTime - this._splashFadeOutStartTime) / SPLASH_FADE_DURATION, 0);
|
|
renderer.SetColorFillMode();
|
|
renderer.SetColorRgba(.231 * a, .251 * a, .271 * a, a);
|
|
tempRect.set(0, 0, this._canvasCssWidth, this._canvasCssHeight);
|
|
renderer.Rect(tempRect);
|
|
const w = Math.ceil(this._canvasCssWidth);
|
|
const h = Math.ceil(this._canvasCssHeight);
|
|
let drawW, drawH;
|
|
if (this._canvasCssHeight > 256) {
|
|
renderer.SetColorRgba(.302 * a, .334 * a, .365 * a, a);
|
|
drawW = w;
|
|
drawH = Math.max(h * .005, 2);
|
|
tempRect.setWH(0, h * .8 - drawH / 2, drawW, drawH);
|
|
renderer.Rect(tempRect);
|
|
if (hasHadError)
|
|
renderer.SetColorRgba(a, 0, 0, a);
|
|
else
|
|
renderer.SetColorRgba(.161 * a, .953 * a, .816 * a, a);
|
|
drawW = w * this._loadingProgress;
|
|
tempRect.setWH(w * .5 - drawW / 2, h * .8 - drawH / 2, drawW, drawH);
|
|
renderer.Rect(tempRect);
|
|
renderer.SetColorRgba(a, a, a, a);
|
|
renderer.SetTextureFillMode();
|
|
if (poweredTex) {
|
|
drawW = C3.clamp(h * .22, 105, w * .6) * 1.5;
|
|
drawH = drawW / 8;
|
|
tempRect.setWH(w * .5 - drawW / 2, h * .2 - drawH / 2, drawW, drawH);
|
|
renderer.SetTexture(poweredTex);
|
|
renderer.Rect(tempRect)
|
|
}
|
|
if (logoTex) {
|
|
drawW = Math.min(h * .395, w * .95);
|
|
drawH = drawW;
|
|
tempRect.setWH(w * .5 - drawW / 2, h * .485 - drawH / 2, drawW, drawH);
|
|
renderer.SetTexture(logoTex);
|
|
renderer.Rect(tempRect)
|
|
}
|
|
if (websiteTex) {
|
|
drawW = C3.clamp(h * .22, 105, w * .6) * 1.5;
|
|
drawH = drawW / 8;
|
|
tempRect.setWH(w * .5 - drawW / 2, h * .868 - drawH / 2, drawW, drawH);
|
|
renderer.SetTexture(websiteTex);
|
|
renderer.Rect(tempRect)
|
|
}
|
|
} else {
|
|
renderer.SetColorRgba(.302 * a, .334 * a, .365 * a, a);
|
|
drawW = w;
|
|
drawH = Math.max(h * .005, 2);
|
|
tempRect.setWH(0, h * .85 - drawH / 2, drawW, drawH);
|
|
renderer.Rect(tempRect);
|
|
if (hasHadError)
|
|
renderer.SetColorRgba(a, 0, 0, a);
|
|
else
|
|
renderer.SetColorRgba(.161 * a, .953 * a, .816 * a, a);
|
|
drawW = w * this._loadingProgress;
|
|
tempRect.setWH(w * .5 - drawW / 2, h * .85 - drawH / 2, drawW, drawH);
|
|
renderer.Rect(tempRect);
|
|
renderer.SetColorRgba(a, a, a, a);
|
|
renderer.SetTextureFillMode();
|
|
if (logoTex) {
|
|
drawW = h * .55;
|
|
drawH = drawW;
|
|
tempRect.setWH(w * .5 - drawW / 2, h * .45 - drawH / 2, drawW, drawH);
|
|
renderer.SetTexture(logoTex);
|
|
renderer.Rect(tempRect)
|
|
}
|
|
}
|
|
this._splashFrameNumber++;
|
|
if (this._splashState === "fade-in" && nowTime - this._loaderStartTime >= SPLASH_FADE_DURATION && this._splashFrameNumber >= 2) {
|
|
this._splashState = "wait";
|
|
this._splashFadeInFinishTime = nowTime
|
|
}
|
|
if (this._splashState === "wait" && nowTime - this._splashFadeInFinishTime >= splashMinDisplayTime && this._loadingProgress >= 1) {
|
|
this._splashState = "fade-out";
|
|
this._splashFadeOutStartTime = nowTime
|
|
}
|
|
if (this._splashState === "fade-out" && nowTime - this._splashFadeOutStartTime >= SPLASH_FADE_DURATION + splashAfterFadeOutWait || allowQuickSplash && this._loadingProgress >= 1 && nowTime - this._loaderStartTime < 500)
|
|
this._splashDoneResolve()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const C3Debugger = self.C3Debugger;
|
|
const assert = self.assert;
|
|
const DEFAULT_RUNTIME_OPTS = {
|
|
"messagePort": null,
|
|
"baseUrl": "",
|
|
"headless": false,
|
|
"hasDom": true,
|
|
"isInWorker": false,
|
|
"useAudio": true,
|
|
"projectData": "",
|
|
"exportType": ""
|
|
};
|
|
let ife = true;
|
|
C3.Runtime = class C3Runtime extends C3.DefendedBase {
|
|
constructor(opts) {
|
|
opts = Object.assign({}, DEFAULT_RUNTIME_OPTS, opts);
|
|
super();
|
|
this._messagePort = opts["messagePort"];
|
|
this._baseUrl = opts["baseUrl"];
|
|
this._isHeadless = !!opts["headless"];
|
|
this._hasDom = !!opts["hasDom"];
|
|
this._isInWorker = !!opts["isInWorker"];
|
|
ife = opts["ife"];
|
|
this._useAudio = !!opts["useAudio"];
|
|
this._exportType = opts["exportType"];
|
|
this._isiOSCordova = !!opts["isiOSCordova"];
|
|
this._isiOSWebView = !!opts["isiOSWebView"];
|
|
this._isFBInstantAvailable = !!opts["isFBInstantAvailable"];
|
|
this._opusWasmScriptUrl = opts["opusWasmScriptUrl"];
|
|
this._opusWasmBinaryUrl = opts["opusWasmBinaryUrl"];
|
|
this._dataJsonFilename = "data.json";
|
|
this._isDebug = !!(this._exportType === "preview" && opts["isDebug"]);
|
|
this._breakpointsEnabled = this._isDebug;
|
|
this._isDebugging = this._isDebug;
|
|
this._debuggingDisabled = 0;
|
|
const localUrlBlobs = opts["previewImageBlobs"];
|
|
const projectFileBlobs = opts["previewProjectFileBlobs"];
|
|
if (projectFileBlobs)
|
|
Object.assign(localUrlBlobs, projectFileBlobs);
|
|
const projectData = opts["projectData"];
|
|
if (projectData)
|
|
localUrlBlobs[this._dataJsonFilename] = projectData;
|
|
this._additionalLoadPromises = [];
|
|
this._additionalCreatePromises = [];
|
|
this._isUsingCreatePromises = false;
|
|
this._projectName = "";
|
|
this._projectVersion = "";
|
|
this._projectUniqueId = "";
|
|
this._appId = "";
|
|
this._originalViewportWidth = 0;
|
|
this._originalViewportHeight = 0;
|
|
this._devicePixelRatio = self.devicePixelRatio;
|
|
this._parallaxXorigin = 0;
|
|
this._parallaxYorigin = 0;
|
|
this._viewportWidth = 0;
|
|
this._viewportHeight = 0;
|
|
this._loaderStyle = 0;
|
|
this._usesLoaderLayout = false;
|
|
this._isLoading = true;
|
|
this._usesAnyBackgroundBlending = false;
|
|
this._loadingLogoFilename = "loading-logo.png";
|
|
const isRemoteLoadPolicy = this._exportType === "html5" || this._exportType === "scirra-arcade" || this._exportType === "instant-games";
|
|
this._assetManager = C3.New(C3.AssetManager, this, {
|
|
defaultLoadPolicy: isRemoteLoadPolicy ? "remote" : "local",
|
|
localUrlBlobs,
|
|
isCordova: this._exportType === "cordova",
|
|
isiOSCordova: this._isiOSCordova,
|
|
supportedAudioFormats: opts["supportedAudioFormats"]
|
|
});
|
|
this._layoutManager = C3.New(C3.LayoutManager, this);
|
|
this._eventSheetManager = C3.New(C3.EventSheetManager, this);
|
|
this._pluginManager = C3.New(C3.PluginManager, this);
|
|
this._collisionEngine = C3.New(C3.CollisionEngine, this);
|
|
this._timelineManager = C3.New(C3.TimelineManager, this);
|
|
this._transitionManager = C3.New(C3.TransitionManager, this);
|
|
this._allObjectClasses = [];
|
|
this._objectClassesByName = new Map;
|
|
this._objectClassesBySid = new Map;
|
|
this._familyCount = 0;
|
|
this._allContainers = [];
|
|
this._allEffectLists = [];
|
|
this._currentLayoutStack = [];
|
|
this._instancesPendingCreate = [];
|
|
this._instancesPendingDestroy = new Map;
|
|
this._hasPendingInstances = false;
|
|
this._isFlushingPendingInstances = false;
|
|
this._objectCount = 0;
|
|
this._nextUid = 0;
|
|
this._instancesByUid = new Map;
|
|
this._instancesToReleaseAtEndOfTick = new Set;
|
|
this._instancesToReleaseAffectedObjectClasses = new Set;
|
|
this._objectReferenceTable = [];
|
|
this._jsPropNameTable = [];
|
|
this._canvasManager = null;
|
|
this._framerateMode = "vsync";
|
|
this._compositingMode = "standard";
|
|
this._sampling = "trilinear";
|
|
this._isPixelRoundingEnabled = false;
|
|
this._needRender = true;
|
|
this._pauseOnBlur = false;
|
|
this._isPausedOnBlur = false;
|
|
this._tickCallbacks = {
|
|
normal: timestamp=>{
|
|
this._rafId = -1;
|
|
this._ruafId = -1;
|
|
this.Tick(timestamp)
|
|
}
|
|
,
|
|
tickOnly: timestamp=>{
|
|
this._ruafId = -1;
|
|
this.Tick(timestamp, false, "skip-render")
|
|
}
|
|
,
|
|
renderOnly: ()=>{
|
|
this._rafId = -1;
|
|
this.Render()
|
|
}
|
|
};
|
|
this._rafId = -1;
|
|
this._ruafId = -1;
|
|
this._tickCount = 0;
|
|
this._tickCountNoSave = 0;
|
|
this._execCount = 0;
|
|
this._hasStarted = false;
|
|
this._isInTick = false;
|
|
this._hasStartedTicking = false;
|
|
this._isLayoutFirstTick = true;
|
|
this._suspendCount = 0;
|
|
this._scheduleTriggersThrottle = new C3.PromiseThrottle(1);
|
|
this._randomNumberCallback = ()=>Math.random();
|
|
this._startTime = 0;
|
|
this._lastTickTime = 0;
|
|
this._dt1 = 0;
|
|
this._dt = 0;
|
|
this._timeScale = 1;
|
|
this._minimumFramerate = 30;
|
|
this._gameTime = C3.New(C3.KahanSum);
|
|
this._wallTime = C3.New(C3.KahanSum);
|
|
this._fpsFrameCount = -1;
|
|
this._fpsLastTime = 0;
|
|
this._fps = 0;
|
|
this._mainThreadTimeCounter = 0;
|
|
this._mainThreadTime = 0;
|
|
this._isLoadingState = false;
|
|
this._saveToSlotName = "";
|
|
this._loadFromSlotName = "";
|
|
this._loadFromJson = null;
|
|
this._lastSaveJson = "";
|
|
this._triggerOnCreateAfterLoad = [];
|
|
this._projectStorage = null;
|
|
this._savegamesStorage = null;
|
|
this._dispatcher = C3.New(C3.Event.Dispatcher);
|
|
this._domEventHandlers = new Map;
|
|
this._pendingResponsePromises = new Map;
|
|
this._nextDomResponseId = 0;
|
|
this._didRequestDeviceOrientationEvent = false;
|
|
this._didRequestDeviceMotionEvent = false;
|
|
this._isReadyToHandleEvents = false;
|
|
this._waitingToHandleEvents = [];
|
|
this._eventObjects = {
|
|
"pretick": C3.New(C3.Event, "pretick", false),
|
|
"tick": C3.New(C3.Event, "tick", false),
|
|
"tick2": C3.New(C3.Event, "tick2", false),
|
|
"instancedestroy": C3.New(C3.Event, "instancedestroy", false),
|
|
"beforelayoutchange": C3.New(C3.Event, "beforelayoutchange", false),
|
|
"layoutchange": C3.New(C3.Event, "layoutchange", false)
|
|
};
|
|
this._eventObjects["instancedestroy"].instance = null;
|
|
this._userScriptDispatcher = C3.New(C3.Event.Dispatcher);
|
|
this._userScriptEventObjects = null;
|
|
this._behInstsToTick = C3.New(C3.RedBlackSet, C3.BehaviorInstance.SortByTickSequence);
|
|
this._behInstsToPostTick = C3.New(C3.RedBlackSet, C3.BehaviorInstance.SortByTickSequence);
|
|
this._behInstsToTick2 = C3.New(C3.RedBlackSet, C3.BehaviorInstance.SortByTickSequence);
|
|
this._jobScheduler = C3.New(C3.JobSchedulerRuntime, this, opts["jobScheduler"]);
|
|
if (opts["canvas"])
|
|
this._canvasManager = C3.New(C3.CanvasManager, this);
|
|
this._messagePort.onmessage = e=>this["_OnMessageFromDOM"](e.data);
|
|
this.AddDOMComponentMessageHandler("runtime", "visibilitychange", e=>this._OnVisibilityChange(e));
|
|
this.AddDOMComponentMessageHandler("runtime", "opus-decode", e=>this._WasmDecodeWebMOpus(e["arrayBuffer"]));
|
|
this.AddDOMComponentMessageHandler("runtime", "get-remote-preview-status-info", ()=>this._GetRemotePreviewStatusInfo());
|
|
this.AddDOMComponentMessageHandler("runtime", "js-invoke-function", e=>this._InvokeFunctionFromJS(e));
|
|
this.AddDOMComponentMessageHandler("runtime", "go-to-last-error-script", self["goToLastErrorScript"]);
|
|
this._dispatcher.addEventListener("window-blur", e=>this._OnWindowBlur(e));
|
|
this._dispatcher.addEventListener("window-focus", ()=>this._OnWindowFocus());
|
|
this._timelineManager.AddRuntimeListeners();
|
|
this._iRuntime = null;
|
|
this._interfaceMap = new WeakMap;
|
|
this._commonScriptInterfaces = {
|
|
keyboard: null,
|
|
mouse: null,
|
|
touch: null
|
|
}
|
|
}
|
|
static Create(opts) {
|
|
return C3.New(C3.Runtime, opts)
|
|
}
|
|
Release() {
|
|
C3.clearArray(this._allObjectClasses);
|
|
this._objectClassesByName.clear();
|
|
this._objectClassesBySid.clear();
|
|
this._layoutManager.Release();
|
|
this._layoutManager = null;
|
|
this._eventSheetManager.Release();
|
|
this._eventSheetManager = null;
|
|
this._pluginManager.Release();
|
|
this._pluginManager = null;
|
|
this._assetManager.Release();
|
|
this._assetManager = null;
|
|
this._collisionEngine.Release();
|
|
this._collisionEngine = null;
|
|
this._timelineManager.Release();
|
|
this._timelineManager = null;
|
|
this._transitionManager.Release();
|
|
this._transitionManager = null;
|
|
if (this._canvasManager) {
|
|
this._canvasManager.Release();
|
|
this._canvasManager = null
|
|
}
|
|
this._dispatcher.Release();
|
|
this._dispatcher = null;
|
|
this._tickEvent = null
|
|
}
|
|
["_OnMessageFromDOM"](data) {
|
|
const type = data["type"];
|
|
if (type === "event")
|
|
this._OnEventFromDOM(data);
|
|
else if (type === "result")
|
|
this._OnResultFromDOM(data);
|
|
else
|
|
throw new Error(`unknown message '${type}'`);
|
|
}
|
|
_OnEventFromDOM(e) {
|
|
if (!this._isReadyToHandleEvents) {
|
|
this._waitingToHandleEvents.push(e);
|
|
return
|
|
}
|
|
const component = e["component"];
|
|
const handler = e["handler"];
|
|
const data = e["data"];
|
|
const dispatchOpts = e["dispatchOpts"];
|
|
const dispatchRuntimeEvent = !!(dispatchOpts && dispatchOpts["dispatchRuntimeEvent"]);
|
|
const dispatchUserScriptEvent = !!(dispatchOpts && dispatchOpts["dispatchUserScriptEvent"]);
|
|
const responseId = e["responseId"];
|
|
if (component === "runtime") {
|
|
if (dispatchRuntimeEvent) {
|
|
const event = new C3.Event(handler);
|
|
event.data = data;
|
|
this._dispatcher.dispatchEventAndWaitAsyncSequential(event)
|
|
}
|
|
if (dispatchUserScriptEvent) {
|
|
const event = new C3.Event(handler,true);
|
|
for (const [key,value] of Object.entries(data))
|
|
event[key] = value;
|
|
this.DispatchUserScriptEvent(event)
|
|
}
|
|
}
|
|
const handlerMap = this._domEventHandlers.get(component);
|
|
if (!handlerMap) {
|
|
if (!dispatchRuntimeEvent && !dispatchUserScriptEvent)
|
|
console.warn(`[Runtime] No DOM event handlers for component '${component}'`);
|
|
return
|
|
}
|
|
const func = handlerMap.get(handler);
|
|
if (!func) {
|
|
if (!dispatchRuntimeEvent && !dispatchUserScriptEvent)
|
|
console.warn(`[Runtime] No DOM handler '${handler}' for component '${component}'`);
|
|
return
|
|
}
|
|
let ret = null;
|
|
try {
|
|
ret = func(data)
|
|
} catch (err) {
|
|
console.error(`Exception in '${component}' handler '${handler}':`, err);
|
|
if (responseId !== null)
|
|
this._PostResultToDOM(responseId, false, "" + err);
|
|
return
|
|
}
|
|
if (responseId !== null)
|
|
if (ret && ret.then)
|
|
ret.then(result=>this._PostResultToDOM(responseId, true, result)).catch(err=>{
|
|
console.error(`Rejection from '${component}' handler '${handler}':`, err);
|
|
this._PostResultToDOM(responseId, false, "" + err)
|
|
}
|
|
);
|
|
else
|
|
this._PostResultToDOM(responseId, true, ret)
|
|
}
|
|
_PostResultToDOM(responseId, isOk, result) {
|
|
this._messagePort.postMessage({
|
|
"type": "result",
|
|
"responseId": responseId,
|
|
"isOk": isOk,
|
|
"result": result
|
|
})
|
|
}
|
|
_OnResultFromDOM(data) {
|
|
const responseId = data["responseId"];
|
|
const isOk = data["isOk"];
|
|
const result = data["result"];
|
|
const pendingPromise = this._pendingResponsePromises.get(responseId);
|
|
if (isOk)
|
|
pendingPromise.resolve(result);
|
|
else
|
|
pendingPromise.reject(result);
|
|
this._pendingResponsePromises.delete(responseId)
|
|
}
|
|
AddDOMComponentMessageHandler(component, handler, func) {
|
|
let handlerMap = this._domEventHandlers.get(component);
|
|
if (!handlerMap) {
|
|
handlerMap = new Map;
|
|
this._domEventHandlers.set(component, handlerMap)
|
|
}
|
|
if (handlerMap.has(handler))
|
|
throw new Error(`[Runtime] Component '${component}' already has handler '${handler}'`);
|
|
handlerMap.set(handler, func)
|
|
}
|
|
PostComponentMessageToDOM(component, handler, data) {
|
|
this._messagePort.postMessage({
|
|
"type": "event",
|
|
"component": component,
|
|
"handler": handler,
|
|
"data": data,
|
|
"responseId": null
|
|
})
|
|
}
|
|
PostComponentMessageToDOMAsync(component, handler, data) {
|
|
const responseId = this._nextDomResponseId++;
|
|
const ret = new Promise((resolve,reject)=>{
|
|
this._pendingResponsePromises.set(responseId, {
|
|
resolve,
|
|
reject
|
|
})
|
|
}
|
|
);
|
|
this._messagePort.postMessage({
|
|
"type": "event",
|
|
"component": component,
|
|
"handler": handler,
|
|
"data": data,
|
|
"responseId": responseId
|
|
});
|
|
return ret
|
|
}
|
|
PostToDebugger(data) {
|
|
if (!this.IsDebug())
|
|
throw new Error("not in debug mode");
|
|
this.PostComponentMessageToDOM("runtime", "post-to-debugger", data)
|
|
}
|
|
async Init(opts) {
|
|
if (this.IsDebug())
|
|
await C3Debugger.Init(this);
|
|
else if (self.C3Debugger)
|
|
self.C3Debugger.InitPreview(this);
|
|
const [o] = await Promise.all([this._assetManager.FetchJson(this._dataJsonFilename), this._MaybeLoadOpusDecoder(), this._jobScheduler.Init()]);
|
|
this._LoadDataJson(o);
|
|
await this._InitialiseCanvas(opts);
|
|
if (!this.IsPreview())
|
|
console.info("Made with Construct 3, the game and app creator :: https://www.construct.net");
|
|
const webglRenderer = this.GetWebGLRenderer();
|
|
if (webglRenderer) {
|
|
console.info(`[C3 runtime] Hosted in ${this.IsInWorker() ? "worker" : "DOM"}, rendering with WebGL ${webglRenderer.GetWebGLVersionNumber()} [${webglRenderer.GetUnmaskedRenderer()}] (${webglRenderer.IsDesynchronized() ? "desynchronized" : "standard"} compositing)`);
|
|
if (webglRenderer.HasMajorPerformanceCaveat())
|
|
console.warn("[C3 runtime] WebGL indicates a major performance caveat. Software rendering may be in use. This can result in significantly degraded performance.")
|
|
} else
|
|
console.info(`[C3 runtime] Hosted in ${this.IsInWorker() ? "worker" : "DOM"}, headless`);
|
|
this._isReadyToHandleEvents = true;
|
|
for (const e of this._waitingToHandleEvents)
|
|
this._OnEventFromDOM(e);
|
|
C3.clearArray(this._waitingToHandleEvents);
|
|
if (this._canvasManager)
|
|
this._canvasManager.StartLoadingScreen();
|
|
for (const f of opts["runOnStartupFunctions"])
|
|
this._additionalLoadPromises.push(this._RunOnStartupFunction(f));
|
|
await Promise.all([this._assetManager.WaitForAllToLoad(), ...this._additionalLoadPromises]);
|
|
C3.clearArray(this._additionalLoadPromises);
|
|
if (this._assetManager.HasHadErrorLoading()) {
|
|
if (this._canvasManager)
|
|
this._canvasManager.HideCordovaSplashScreen();
|
|
return
|
|
}
|
|
if (this._canvasManager)
|
|
await this._canvasManager.EndLoadingScreen();
|
|
await this._dispatcher.dispatchEventAndWaitAsync(new C3.Event("beforeruntimestart"));
|
|
await this.Start();
|
|
this._messagePort.postMessage({
|
|
"type": "runtime-ready"
|
|
});
|
|
return this
|
|
}
|
|
async _RunOnStartupFunction(f) {
|
|
try {
|
|
await f(this._iRuntime)
|
|
} catch (err) {
|
|
console.error("[C3 runtime] Error in runOnStartup function: ", err)
|
|
}
|
|
}
|
|
_LoadDataJson(o) {
|
|
const projectData = o["project"];
|
|
this._projectName = projectData[0];
|
|
this._projectVersion = projectData[16];
|
|
this._projectUniqueId = projectData[31];
|
|
this._appId = projectData[38];
|
|
this._loadingLogoFilename = projectData[39];
|
|
this._isPixelRoundingEnabled = !!projectData[9];
|
|
this._originalViewportWidth = this._viewportWidth = projectData[10];
|
|
this._originalViewportHeight = this._viewportHeight = projectData[11];
|
|
this._parallaxXorigin = this._originalViewportWidth / 2;
|
|
this._parallaxYorigin = this._originalViewportHeight / 2;
|
|
this._compositingMode = projectData[36];
|
|
this._framerateMode = projectData[37];
|
|
if (this._compositingMode === "low-latency" && this.IsAndroidWebView() && C3.Platform.BrowserVersionNumber <= 77) {
|
|
console.warn("[C3 runtime] Desynchronized (low-latency) compositing is enabled, but is disabled in the Android WebView <=77 due to crbug.com/1008842. Reverting to synchronized (standard) compositing.");
|
|
this._compositingMode = "standard"
|
|
}
|
|
this._sampling = projectData[14];
|
|
this._usesLoaderLayout = !!projectData[18];
|
|
this._loaderStyle = projectData[19];
|
|
this._nextUid = projectData[21];
|
|
this._pauseOnBlur = projectData[22];
|
|
this._assetManager._SetAudioFiles(projectData[7], projectData[25]);
|
|
this._assetManager._SetMediaSubfolder(projectData[8]);
|
|
this._assetManager._SetFontsSubfolder(projectData[32]);
|
|
this._assetManager._SetIconsSubfolder(projectData[28]);
|
|
this._assetManager._SetWebFonts(projectData[29]);
|
|
if (this._canvasManager) {
|
|
this._canvasManager.SetFullscreenMode(C3.CanvasManager._FullscreenModeNumberToString(projectData[12]));
|
|
this._canvasManager.SetFullscreenScalingQuality(projectData[23] ? "high" : "low");
|
|
this._canvasManager.SetMipmapsEnabled(projectData[24] !== 0);
|
|
this._canvasManager._SetGPUPowerPreference(projectData[34])
|
|
}
|
|
this._pluginManager.CreateSystemPlugin();
|
|
this._objectReferenceTable = self.C3_GetObjectRefTable();
|
|
for (const pluginData of projectData[2])
|
|
this._pluginManager.CreatePlugin(pluginData);
|
|
this._objectReferenceTable = self.C3_GetObjectRefTable();
|
|
this._LoadJsPropNameTable();
|
|
for (const objectClassData of projectData[3]) {
|
|
const objectClass = C3.ObjectClass.Create(this, this._allObjectClasses.length, objectClassData);
|
|
this._allObjectClasses.push(objectClass);
|
|
this._objectClassesByName.set(objectClass.GetName().toLowerCase(), objectClass);
|
|
this._objectClassesBySid.set(objectClass.GetSID(), objectClass)
|
|
}
|
|
for (const familyData of projectData[4]) {
|
|
const familyType = this._allObjectClasses[familyData[0]];
|
|
familyType._LoadFamily(familyData)
|
|
}
|
|
for (const containerData of projectData[27]) {
|
|
const containerTypes = containerData.map(index=>this._allObjectClasses[index]);
|
|
this._allContainers.push(C3.New(C3.Container, this, containerTypes))
|
|
}
|
|
for (const objectClass of this._allObjectClasses)
|
|
objectClass._OnAfterCreate();
|
|
for (const layoutData of projectData[5])
|
|
this._layoutManager.Create(layoutData);
|
|
const firstLayoutName = projectData[1];
|
|
if (firstLayoutName) {
|
|
const firstLayout = this._layoutManager.GetLayoutByName(firstLayoutName);
|
|
if (firstLayout)
|
|
this._layoutManager.SetFirstLayout(firstLayout)
|
|
}
|
|
for (const timelineData of projectData[33])
|
|
this._timelineManager.Create(timelineData);
|
|
for (const transitionData of projectData[35])
|
|
this._transitionManager.Create(transitionData);
|
|
this._InitScriptInterfaces();
|
|
for (const eventSheetData of projectData[6])
|
|
this._eventSheetManager.Create(eventSheetData);
|
|
this._eventSheetManager._PostInit();
|
|
this._InitGlobalVariableScriptInterface();
|
|
C3.clearArray(this._objectReferenceTable);
|
|
this.FlushPendingInstances();
|
|
let targetOrientation = "any";
|
|
const orientations = projectData[20];
|
|
if (orientations === 1)
|
|
targetOrientation = "portrait";
|
|
else if (orientations === 2)
|
|
targetOrientation = "landscape";
|
|
this.PostComponentMessageToDOM("runtime", "set-target-orientation", {
|
|
"targetOrientation": targetOrientation
|
|
})
|
|
}
|
|
GetLoaderStyle() {
|
|
return this._loaderStyle
|
|
}
|
|
IsFBInstantAvailable() {
|
|
return this._isFBInstantAvailable
|
|
}
|
|
IsLoading() {
|
|
return this._isLoading
|
|
}
|
|
AddLoadPromise(promise) {
|
|
this._additionalLoadPromises.push(promise)
|
|
}
|
|
SetUsingCreatePromises(e) {
|
|
this._isUsingCreatePromises = !!e
|
|
}
|
|
AddCreatePromise(promise) {
|
|
if (!this._isUsingCreatePromises)
|
|
return;
|
|
this._additionalCreatePromises.push(promise)
|
|
}
|
|
GetCreatePromises() {
|
|
return this._additionalCreatePromises
|
|
}
|
|
_GetNextFamilyIndex() {
|
|
return this._familyCount++
|
|
}
|
|
GetFamilyCount() {
|
|
return this._familyCount
|
|
}
|
|
_AddEffectList(el) {
|
|
this._allEffectLists.push(el)
|
|
}
|
|
_GetAllEffectLists() {
|
|
return this._allEffectLists
|
|
}
|
|
async _InitialiseCanvas(opts) {
|
|
if (!this._canvasManager)
|
|
return;
|
|
await this._canvasManager.CreateCanvas(opts);
|
|
this._canvasManager.InitLoadingScreen(this._loaderStyle)
|
|
}
|
|
async _MaybeLoadOpusDecoder() {
|
|
if (this._assetManager.IsAudioFormatSupported("audio/webm; codecs=opus"))
|
|
return;
|
|
let wasmBlob = null;
|
|
let wasmBuffer = null;
|
|
try {
|
|
if (this.IsiOSCordova() && location.protocol === "file:")
|
|
wasmBuffer = await this._assetManager.CordovaFetchLocalFileAsArrayBuffer(this._opusWasmBinaryUrl);
|
|
else
|
|
wasmBlob = await this._assetManager.FetchBlob(this._opusWasmBinaryUrl)
|
|
} catch (err) {
|
|
console.info("Failed to fetch Opus decoder WASM; assuming project has no Opus audio.", err);
|
|
return
|
|
}
|
|
if (wasmBuffer)
|
|
this.AddJobWorkerBuffer(wasmBuffer, "opus-decoder-wasm");
|
|
else
|
|
this.AddJobWorkerBlob(wasmBlob, "opus-decoder-wasm");
|
|
await this.AddJobWorkerScripts([this._opusWasmScriptUrl])
|
|
}
|
|
async _WasmDecodeWebMOpus(arrayBuffer) {
|
|
const result = await this.AddJob("OpusDecode", {
|
|
"arrayBuffer": arrayBuffer
|
|
}, [arrayBuffer]);
|
|
return result
|
|
}
|
|
async Start() {
|
|
this._hasStarted = true;
|
|
this._startTime = Date.now();
|
|
if (this._usesLoaderLayout) {
|
|
for (const objectClass of this._allObjectClasses)
|
|
if (!objectClass.IsFamily() && !objectClass.IsOnLoaderLayout() && objectClass.IsWorldType())
|
|
objectClass.OnCreate();
|
|
this._assetManager.WaitForAllToLoad().then(()=>{
|
|
this._isLoading = false;
|
|
this._OnLoadFinished()
|
|
}
|
|
)
|
|
} else
|
|
this._isLoading = false;
|
|
this._assetManager.SetInitialLoadFinished();
|
|
if (this.IsDebug())
|
|
C3Debugger.RuntimeInit(ife);
|
|
for (const layout of this._layoutManager.GetAllLayouts())
|
|
layout._CreateGlobalNonWorlds();
|
|
const firstLayout = this._layoutManager.GetFirstLayout();
|
|
await firstLayout._Load(null, this.GetWebGLRenderer());
|
|
await firstLayout._StartRunning(true);
|
|
this._fpsLastTime = performance.now();
|
|
if (!this._usesLoaderLayout)
|
|
this._OnLoadFinished();
|
|
const state = await this.PostComponentMessageToDOMAsync("runtime", "before-start-ticking");
|
|
if (state["isSuspended"])
|
|
this._suspendCount++;
|
|
else
|
|
this.Tick()
|
|
}
|
|
_OnLoadFinished() {
|
|
this.Trigger(C3.Plugins.System.Cnds.OnLoadFinished, null, null);
|
|
this.PostComponentMessageToDOM("runtime", "register-sw")
|
|
}
|
|
GetObjectReference(index) {
|
|
index = Math.floor(index);
|
|
const objRefTable = this._objectReferenceTable;
|
|
if (index < 0 || index >= objRefTable.length)
|
|
throw new Error("invalid object reference");
|
|
return objRefTable[index]
|
|
}
|
|
_LoadJsPropNameTable() {
|
|
for (const entry of self.C3_JsPropNameTable) {
|
|
const propName = C3.first(Object.keys(entry));
|
|
this._jsPropNameTable.push(propName)
|
|
}
|
|
}
|
|
GetJsPropName(index) {
|
|
index = Math.floor(index);
|
|
const jsPropNameTable = this._jsPropNameTable;
|
|
if (index < 0 || index >= jsPropNameTable.length)
|
|
throw new Error("invalid prop reference");
|
|
return jsPropNameTable[index]
|
|
}
|
|
HasDOM() {
|
|
return this._hasDom
|
|
}
|
|
IsHeadless() {
|
|
return this._isHeadless
|
|
}
|
|
IsInWorker() {
|
|
return this._isInWorker
|
|
}
|
|
GetBaseURL() {
|
|
return this._baseUrl
|
|
}
|
|
GetEventSheetManager() {
|
|
return this._eventSheetManager
|
|
}
|
|
GetEventStack() {
|
|
return this._eventSheetManager.GetEventStack()
|
|
}
|
|
GetCurrentEventStackFrame() {
|
|
return this._eventSheetManager.GetCurrentEventStackFrame()
|
|
}
|
|
GetCurrentEvent() {
|
|
return this._eventSheetManager.GetCurrentEvent()
|
|
}
|
|
GetCurrentCondition() {
|
|
return this._eventSheetManager.GetCurrentCondition()
|
|
}
|
|
IsCurrentConditionFirst() {
|
|
return this.GetCurrentEventStackFrame().GetConditionIndex() === 0
|
|
}
|
|
GetCurrentAction() {
|
|
return this._eventSheetManager.GetCurrentAction()
|
|
}
|
|
GetPluginManager() {
|
|
return this._pluginManager
|
|
}
|
|
GetSystemPlugin() {
|
|
return this._pluginManager.GetSystemPlugin()
|
|
}
|
|
GetObjectClassByIndex(i) {
|
|
i = Math.floor(i);
|
|
if (i < 0 || i >= this._allObjectClasses.length)
|
|
throw new RangeError("invalid index");
|
|
return this._allObjectClasses[i]
|
|
}
|
|
GetObjectClassByName(name) {
|
|
return this._objectClassesByName.get(name.toLowerCase()) || null
|
|
}
|
|
GetObjectClassBySID(sid) {
|
|
return this._objectClassesBySid.get(sid) || null
|
|
}
|
|
GetSingleGlobalObjectClassByCtor(ctor) {
|
|
const plugin = this._pluginManager.GetPluginByConstructorFunction(ctor);
|
|
if (!plugin)
|
|
return null;
|
|
return plugin.GetSingleGlobalObjectClass()
|
|
}
|
|
GetAllObjectClasses() {
|
|
return this._allObjectClasses
|
|
}
|
|
Dispatcher() {
|
|
return this._dispatcher
|
|
}
|
|
UserScriptDispatcher() {
|
|
return this._userScriptDispatcher
|
|
}
|
|
DispatchUserScriptEvent(e) {
|
|
e.runtime = this.GetIRuntime();
|
|
const shouldTime = this.IsDebug() && !this._eventSheetManager.IsInEventEngine();
|
|
if (shouldTime)
|
|
C3Debugger.StartMeasuringScriptTime();
|
|
this._userScriptDispatcher.dispatchEvent(e);
|
|
if (shouldTime)
|
|
C3Debugger.AddScriptTime()
|
|
}
|
|
DispatchUserScriptEventAsyncWait(e) {
|
|
e.runtime = this.GetIRuntime();
|
|
return this._userScriptDispatcher.dispatchEventAndWaitAsync(e)
|
|
}
|
|
GetOriginalViewportWidth() {
|
|
return this._originalViewportWidth
|
|
}
|
|
GetOriginalViewportHeight() {
|
|
return this._originalViewportHeight
|
|
}
|
|
SetOriginalViewportSize(w, h) {
|
|
this._originalViewportWidth = w;
|
|
this._originalViewportHeight = h
|
|
}
|
|
GetViewportWidth() {
|
|
return this._viewportWidth
|
|
}
|
|
GetViewportHeight() {
|
|
return this._viewportHeight
|
|
}
|
|
SetViewportSize(w, h) {
|
|
this._viewportWidth = w;
|
|
this._viewportHeight = h
|
|
}
|
|
_SetDevicePixelRatio(r) {
|
|
this._devicePixelRatio = r
|
|
}
|
|
GetDevicePixelRatio() {
|
|
return this._devicePixelRatio
|
|
}
|
|
GetParallaxXOrigin() {
|
|
return this._parallaxXorigin
|
|
}
|
|
GetParallaxYOrigin() {
|
|
return this._parallaxYorigin
|
|
}
|
|
GetCanvasManager() {
|
|
return this._canvasManager
|
|
}
|
|
GetDrawWidth() {
|
|
if (!this._canvasManager)
|
|
return this._viewportWidth;
|
|
return this._canvasManager.GetDrawWidth()
|
|
}
|
|
GetDrawHeight() {
|
|
if (!this._canvasManager)
|
|
return this._viewportHeight;
|
|
return this._canvasManager.GetDrawHeight()
|
|
}
|
|
GetRenderScale() {
|
|
if (!this._canvasManager)
|
|
return 1;
|
|
return this._canvasManager.GetRenderScale()
|
|
}
|
|
GetDisplayScale() {
|
|
if (!this._canvasManager)
|
|
return 1;
|
|
return this._canvasManager.GetDisplayScale()
|
|
}
|
|
GetCanvasClientX() {
|
|
if (!this._canvasManager)
|
|
return 0;
|
|
return this._canvasManager.GetCanvasClientX()
|
|
}
|
|
GetCanvasClientY() {
|
|
if (!this._canvasManager)
|
|
return 0;
|
|
return this._canvasManager.GetCanvasClientY()
|
|
}
|
|
GetCanvasCssWidth() {
|
|
if (!this._canvasManager)
|
|
return 0;
|
|
return this._canvasManager.GetCssWidth()
|
|
}
|
|
GetCanvasCssHeight() {
|
|
if (!this._canvasManager)
|
|
return 0;
|
|
return this._canvasManager.GetCssHeight()
|
|
}
|
|
GetFullscreenMode() {
|
|
if (!this._canvasManager)
|
|
return "off";
|
|
return this._canvasManager.GetFullscreenMode()
|
|
}
|
|
GetAdditionalRenderTarget(opts) {
|
|
if (!this._canvasManager)
|
|
return null;
|
|
return this._canvasManager.GetAdditionalRenderTarget(opts)
|
|
}
|
|
ReleaseAdditionalRenderTarget(renderTarget) {
|
|
if (!this._canvasManager)
|
|
return;
|
|
this._canvasManager.ReleaseAdditionalRenderTarget(renderTarget)
|
|
}
|
|
_SetUsesAnyBackgroundBlending(u) {
|
|
this._usesAnyBackgroundBlending = !!u
|
|
}
|
|
UsesAnyBackgroundBlending() {
|
|
return this._usesAnyBackgroundBlending
|
|
}
|
|
GetGPUUtilisation() {
|
|
if (!this._canvasManager)
|
|
return NaN;
|
|
return this._canvasManager.GetGPUUtilisation()
|
|
}
|
|
IsLinearSampling() {
|
|
return this.GetSampling() !== "nearest"
|
|
}
|
|
GetFramerateMode() {
|
|
return this._framerateMode
|
|
}
|
|
GetCompositingMode() {
|
|
return this._compositingMode
|
|
}
|
|
GetSampling() {
|
|
return this._sampling
|
|
}
|
|
UsesLoaderLayout() {
|
|
return this._usesLoaderLayout
|
|
}
|
|
GetLoadingLogoFilename() {
|
|
return this._loadingLogoFilename
|
|
}
|
|
GetLayoutManager() {
|
|
return this._layoutManager
|
|
}
|
|
GetMainRunningLayout() {
|
|
return this._layoutManager.GetMainRunningLayout()
|
|
}
|
|
GetTimelineManager() {
|
|
return this._timelineManager
|
|
}
|
|
GetTransitionManager() {
|
|
return this._transitionManager
|
|
}
|
|
GetAssetManager() {
|
|
return this._assetManager
|
|
}
|
|
LoadImage(opts) {
|
|
return this._assetManager.LoadImage(opts)
|
|
}
|
|
CreateInstance(objectClass, layer, x, y) {
|
|
return this.CreateInstanceFromData(objectClass, layer, false, x, y)
|
|
}
|
|
CreateInstanceFromData(instData_or_objectClass, layer, isStartupInstance, x, y, skipSiblings) {
|
|
let instData = null;
|
|
let objectClass = null;
|
|
if (instData_or_objectClass instanceof C3.ObjectClass) {
|
|
objectClass = instData_or_objectClass;
|
|
if (objectClass.IsFamily()) {
|
|
const members = objectClass.GetFamilyMembers();
|
|
const i = Math.floor(this.Random() * members.length);
|
|
objectClass = members[i]
|
|
}
|
|
instData = objectClass.GetDefaultInstanceData()
|
|
} else {
|
|
instData = instData_or_objectClass;
|
|
objectClass = this.GetObjectClassByIndex(instData[1])
|
|
}
|
|
const isWorld = objectClass.GetPlugin().IsWorldType();
|
|
if (this._isLoading && isWorld && !objectClass.IsOnLoaderLayout())
|
|
return null;
|
|
const originalLayer = layer;
|
|
if (!isWorld)
|
|
layer = null;
|
|
let uid;
|
|
if (isStartupInstance && !skipSiblings && instData && !this._instancesByUid.has(instData[2]))
|
|
uid = instData[2];
|
|
else
|
|
uid = this._nextUid++;
|
|
const worldData = instData ? instData[0] : null;
|
|
const inst = C3.New(C3.Instance, {
|
|
runtime: this,
|
|
objectType: objectClass,
|
|
layer: layer,
|
|
worldData,
|
|
instVarData: instData ? instData[3] : null,
|
|
uid: uid
|
|
});
|
|
this._instancesByUid.set(uid, inst);
|
|
let wi = null;
|
|
if (isWorld) {
|
|
wi = inst.GetWorldInfo();
|
|
if (typeof x !== "undefined" && typeof y !== "undefined") {
|
|
wi.SetX(x);
|
|
wi.SetY(y)
|
|
}
|
|
objectClass._SetAnyCollisionCellChanged(true)
|
|
}
|
|
if (layer) {
|
|
layer._AddInstance(inst, true);
|
|
if (layer.GetParallaxX() !== 1 || layer.GetParallaxY() !== 1)
|
|
objectClass._SetAnyInstanceParallaxed(true);
|
|
layer.GetLayout().MaybeLoadTexturesFor(objectClass)
|
|
}
|
|
this._objectCount++;
|
|
if (objectClass.IsInContainer() && !isStartupInstance && !skipSiblings) {
|
|
for (const containerType of objectClass.GetContainer().objectTypes()) {
|
|
if (containerType === objectClass)
|
|
continue;
|
|
const siblingInst = this.CreateInstanceFromData(containerType, originalLayer, false, wi ? wi.GetX() : x, wi ? wi.GetY() : y, true);
|
|
inst._AddSibling(siblingInst)
|
|
}
|
|
for (const s of inst.siblings()) {
|
|
s._AddSibling(inst);
|
|
for (const s2 of inst.siblings())
|
|
if (s !== s2)
|
|
s._AddSibling(s2)
|
|
}
|
|
}
|
|
objectClass._SetIIDsStale();
|
|
const instPropertyData = instData ? C3.cloneArray(instData[5]) : null;
|
|
const behPropertyData = instData ? instData[4].map(bp=>C3.cloneArray(bp)) : null;
|
|
const hasTilemap = isWorld && worldData && worldData.length === 14;
|
|
if (hasTilemap)
|
|
inst._SetHasTilemap();
|
|
inst._CreateSdkInstance(instPropertyData, behPropertyData);
|
|
if (hasTilemap) {
|
|
const tilemapData = worldData[13];
|
|
inst.GetSdkInstance().LoadTilemapData(tilemapData[2], tilemapData[0], tilemapData[1])
|
|
}
|
|
this._instancesPendingCreate.push(inst);
|
|
this._hasPendingInstances = true;
|
|
if (this.IsDebug())
|
|
C3Debugger.InstanceCreated(inst);
|
|
return inst
|
|
}
|
|
DestroyInstance(inst) {
|
|
if (this._instancesToReleaseAtEndOfTick.has(inst))
|
|
return;
|
|
const objectClass = inst.GetObjectClass();
|
|
let s = this._instancesPendingDestroy.get(objectClass);
|
|
if (s) {
|
|
if (s.has(inst))
|
|
return;
|
|
s.add(inst)
|
|
} else {
|
|
s = new Set;
|
|
s.add(inst);
|
|
this._instancesPendingDestroy.set(objectClass, s)
|
|
}
|
|
if (this.IsDebug())
|
|
C3Debugger.InstanceDestroyed(inst);
|
|
inst._MarkDestroyed();
|
|
this._hasPendingInstances = true;
|
|
if (inst.IsInContainer())
|
|
for (const s of inst.siblings())
|
|
this.DestroyInstance(s);
|
|
for (const c of inst.children())
|
|
if (c.GetDestroyWithParent())
|
|
this.DestroyInstance(c);
|
|
if (!this._layoutManager.IsEndingLayout() && !this._isLoadingState) {
|
|
const eventSheetManager = this.GetEventSheetManager();
|
|
eventSheetManager.BlockFlushingInstances(true);
|
|
inst._TriggerOnDestroyed();
|
|
eventSheetManager.BlockFlushingInstances(false)
|
|
}
|
|
inst._FireDestroyedScriptEvents(this._layoutManager.IsEndingLayout())
|
|
}
|
|
FlushPendingInstances() {
|
|
if (!this._hasPendingInstances)
|
|
return;
|
|
this._isFlushingPendingInstances = true;
|
|
this._FlushInstancesPendingCreate();
|
|
this._FlushInstancesPendingDestroy();
|
|
this._isFlushingPendingInstances = false;
|
|
this._hasPendingInstances = false;
|
|
this.UpdateRender()
|
|
}
|
|
_FlushInstancesPendingCreate() {
|
|
for (const inst of this._instancesPendingCreate) {
|
|
const objectType = inst.GetObjectClass();
|
|
objectType._AddInstance(inst);
|
|
for (const family of objectType.GetFamilies()) {
|
|
family._AddInstance(inst);
|
|
family._SetIIDsStale()
|
|
}
|
|
}
|
|
C3.clearArray(this._instancesPendingCreate)
|
|
}
|
|
_FlushInstancesPendingDestroy() {
|
|
this._dispatcher.SetDelayRemoveEventsEnabled(true);
|
|
for (const [objectClass,s] of this._instancesPendingDestroy.entries()) {
|
|
this._FlushInstancesPendingDestroyForObjectClass(objectClass, s);
|
|
s.clear()
|
|
}
|
|
this._instancesPendingDestroy.clear();
|
|
this._dispatcher.SetDelayRemoveEventsEnabled(false)
|
|
}
|
|
_FlushInstancesPendingDestroyForObjectClass(objectClass, s) {
|
|
for (const inst of s) {
|
|
const instanceDestroyEvent = this._eventObjects["instancedestroy"];
|
|
instanceDestroyEvent.instance = inst;
|
|
this._dispatcher.dispatchEvent(instanceDestroyEvent);
|
|
this._instancesByUid.delete(inst.GetUID());
|
|
const wi = inst.GetWorldInfo();
|
|
if (wi) {
|
|
wi._RemoveFromCollisionCells();
|
|
wi._RemoveFromRenderCells()
|
|
}
|
|
this._instancesToReleaseAtEndOfTick.add(inst);
|
|
this._objectCount--
|
|
}
|
|
C3.arrayRemoveAllInSet(objectClass.GetInstances(), s);
|
|
objectClass._SetIIDsStale();
|
|
this._instancesToReleaseAffectedObjectClasses.add(objectClass);
|
|
if (objectClass.GetInstances().length === 0)
|
|
objectClass._SetAnyInstanceParallaxed(false);
|
|
for (const family of objectClass.GetFamilies()) {
|
|
C3.arrayRemoveAllInSet(family.GetInstances(), s);
|
|
family._SetIIDsStale();
|
|
this._instancesToReleaseAffectedObjectClasses.add(family)
|
|
}
|
|
if (objectClass.GetPlugin().IsWorldType()) {
|
|
const layers = new Set([...s].map(i=>i.GetWorldInfo().GetLayer()));
|
|
for (const layer of layers)
|
|
layer._RemoveAllInstancesInSet(s)
|
|
}
|
|
}
|
|
_GetInstancesPendingCreate() {
|
|
return this._instancesPendingCreate
|
|
}
|
|
_GetNewUID() {
|
|
return this._nextUid++
|
|
}
|
|
_MapInstanceByUID(uid, inst) {
|
|
this._instancesByUid.set(uid, inst)
|
|
}
|
|
_OnWebGLContextLost() {
|
|
this._dispatcher.dispatchEvent(C3.New(C3.Event, "webglcontextlost"));
|
|
this.SetSuspended(true);
|
|
for (const objectClass of this._allObjectClasses)
|
|
if (!objectClass.IsFamily() && objectClass.HasLoadedTextures())
|
|
objectClass.ReleaseTextures();
|
|
const runningLayout = this.GetMainRunningLayout();
|
|
if (runningLayout)
|
|
runningLayout._OnWebGLContextLost();
|
|
C3.ImageInfo.OnWebGLContextLost();
|
|
C3.ImageAsset.OnWebGLContextLost()
|
|
}
|
|
async _OnWebGLContextRestored() {
|
|
await this.GetMainRunningLayout()._Load(null, this.GetWebGLRenderer());
|
|
this._dispatcher.dispatchEvent(C3.New(C3.Event, "webglcontextrestored"));
|
|
this.SetSuspended(false);
|
|
this.UpdateRender()
|
|
}
|
|
_OnVisibilityChange(e) {
|
|
this.SetSuspended(e["hidden"])
|
|
}
|
|
_OnWindowBlur(e) {
|
|
if (!this.IsPreview() || !this._pauseOnBlur || C3.Platform.IsMobile)
|
|
return;
|
|
if (!e.data["parentHasFocus"]) {
|
|
this.SetSuspended(true);
|
|
this._isPausedOnBlur = true
|
|
}
|
|
}
|
|
_OnWindowFocus() {
|
|
if (!this._isPausedOnBlur)
|
|
return;
|
|
this.SetSuspended(false);
|
|
this._isPausedOnBlur = false
|
|
}
|
|
_RequestAnimationFrame() {
|
|
const tickCallbacks = this._tickCallbacks;
|
|
if (this._framerateMode === "vsync") {
|
|
if (this._rafId === -1)
|
|
this._rafId = self.requestAnimationFrame(tickCallbacks.normal)
|
|
} else if (this._framerateMode === "unlimited-tick") {
|
|
if (this._ruafId === -1)
|
|
this._ruafId = C3.RequestUnlimitedAnimationFrame(tickCallbacks.tickOnly);
|
|
if (this._rafId === -1)
|
|
this._rafId = self.requestAnimationFrame(tickCallbacks.renderOnly)
|
|
} else if (this._ruafId === -1)
|
|
this._ruafId = C3.RequestUnlimitedAnimationFrame(tickCallbacks.normal)
|
|
}
|
|
_CancelAnimationFrame() {
|
|
if (this._rafId !== -1) {
|
|
self.cancelAnimationFrame(this._rafId);
|
|
this._rafId = -1
|
|
}
|
|
if (this._ruafId !== -1) {
|
|
C3.CancelUnlimitedAnimationFrame(this._ruafId);
|
|
this._ruafId = -1
|
|
}
|
|
}
|
|
IsSuspended() {
|
|
return this._suspendCount > 0
|
|
}
|
|
SetSuspended(s) {
|
|
const wasSuspended = this.IsSuspended();
|
|
this._suspendCount += s ? 1 : -1;
|
|
if (this._suspendCount < 0)
|
|
this._suspendCount = 0;
|
|
const isSuspended = this.IsSuspended();
|
|
if (!wasSuspended && isSuspended) {
|
|
console.log("[Construct 3] Suspending");
|
|
this._CancelAnimationFrame();
|
|
this._dispatcher.dispatchEvent(C3.New(C3.Event, "suspend"));
|
|
this.Trigger(C3.Plugins.System.Cnds.OnSuspend, null, null)
|
|
} else if (wasSuspended && !isSuspended) {
|
|
console.log("[Construct 3] Resuming");
|
|
const now = performance.now();
|
|
this._lastTickTime = now;
|
|
this._fpsLastTime = now;
|
|
this._fpsFrameCount = 0;
|
|
this._fps = 0;
|
|
this._mainThreadTime = 0;
|
|
this._mainThreadTimeCounter = 0;
|
|
this._dispatcher.dispatchEvent(C3.New(C3.Event, "resume"));
|
|
this.Trigger(C3.Plugins.System.Cnds.OnResume, null, null);
|
|
if (!this.HitBreakpoint())
|
|
this.Tick(now)
|
|
}
|
|
}
|
|
_AddBehInstToTick(behSdkInst) {
|
|
this._behInstsToTick.Add(behSdkInst)
|
|
}
|
|
_AddBehInstToPostTick(behSdkInst) {
|
|
this._behInstsToPostTick.Add(behSdkInst)
|
|
}
|
|
_AddBehInstToTick2(behSdkInst) {
|
|
this._behInstsToTick2.Add(behSdkInst)
|
|
}
|
|
_RemoveBehInstToTick(behSdkInst) {
|
|
this._behInstsToTick.Remove(behSdkInst)
|
|
}
|
|
_RemoveBehInstToPostTick(behSdkInst) {
|
|
this._behInstsToPostTick.Remove(behSdkInst)
|
|
}
|
|
_RemoveBehInstToTick2(behSdkInst) {
|
|
this._behInstsToTick2.Remove(behSdkInst)
|
|
}
|
|
_BehaviorTick() {
|
|
this._behInstsToTick.SetQueueingEnabled(true);
|
|
for (const bi of this._behInstsToTick)
|
|
bi.Tick();
|
|
this._behInstsToTick.SetQueueingEnabled(false)
|
|
}
|
|
_BehaviorPostTick() {
|
|
this._behInstsToPostTick.SetQueueingEnabled(true);
|
|
for (const bi of this._behInstsToPostTick)
|
|
bi.PostTick();
|
|
this._behInstsToPostTick.SetQueueingEnabled(false)
|
|
}
|
|
_BehaviorTick2() {
|
|
this._behInstsToTick2.SetQueueingEnabled(true);
|
|
for (const bi of this._behInstsToTick2)
|
|
bi.Tick2();
|
|
this._behInstsToTick2.SetQueueingEnabled(false)
|
|
}
|
|
*_DebugBehaviorTick() {
|
|
this._behInstsToTick.SetQueueingEnabled(true);
|
|
for (const bi of this._behInstsToTick) {
|
|
const ret = bi.Tick();
|
|
if (C3.IsIterator(ret))
|
|
yield*ret
|
|
}
|
|
this._behInstsToTick.SetQueueingEnabled(false)
|
|
}
|
|
*_DebugBehaviorPostTick() {
|
|
this._behInstsToPostTick.SetQueueingEnabled(true);
|
|
for (const bi of this._behInstsToPostTick) {
|
|
const ret = bi.PostTick();
|
|
if (C3.IsIterator(ret))
|
|
yield*ret
|
|
}
|
|
this._behInstsToPostTick.SetQueueingEnabled(false)
|
|
}
|
|
*_DebugBehaviorTick2() {
|
|
this._behInstsToTick2.SetQueueingEnabled(true);
|
|
for (const bi of this._behInstsToTick2) {
|
|
const ret = bi.Tick2();
|
|
if (C3.IsIterator(ret))
|
|
yield*ret
|
|
}
|
|
this._behInstsToTick2.SetQueueingEnabled(false)
|
|
}
|
|
async Tick(timestamp, isDebugStep, mode) {
|
|
this._hasStartedTicking = true;
|
|
const isBackgroundWake = mode === "background-wake";
|
|
const shouldRender = mode !== "background-wake" && mode !== "skip-render";
|
|
if (!this._hasStarted || this.IsSuspended() && !isDebugStep && !isBackgroundWake)
|
|
return;
|
|
const startTime = performance.now();
|
|
this._isInTick = true;
|
|
if (!timestamp)
|
|
timestamp = startTime;
|
|
this._MeasureDt(timestamp);
|
|
const beforePreTickRet = this.Step_BeforePreTick();
|
|
if (this.IsDebugging())
|
|
await beforePreTickRet;
|
|
const pretickRet = this._dispatcher.dispatchEventAndWait_AsyncOptional(this._eventObjects["pretick"]);
|
|
if (pretickRet instanceof Promise)
|
|
await pretickRet;
|
|
const afterPreTickRet = this.Step_AfterPreTick();
|
|
if (this.IsDebugging())
|
|
await afterPreTickRet;
|
|
if (this._NeedsHandleSaveOrLoad())
|
|
await this._HandleSaveOrLoad();
|
|
if (this.GetLayoutManager().IsPendingChangeMainLayout())
|
|
await this._MaybeChangeLayout();
|
|
const runEventsRet = this.Step_RunEventsEtc();
|
|
if (this.IsDebugging())
|
|
await runEventsRet;
|
|
if (shouldRender)
|
|
this.Render();
|
|
if (!this.IsSuspended() && !isBackgroundWake)
|
|
this._RequestAnimationFrame();
|
|
this._tickCount++;
|
|
this._tickCountNoSave++;
|
|
this._execCount++;
|
|
this._isInTick = false;
|
|
this._mainThreadTimeCounter += performance.now() - startTime
|
|
}
|
|
async Step_BeforePreTick() {
|
|
const eventSheetManager = this._eventSheetManager;
|
|
const isDebug = this.IsDebug();
|
|
this.FlushPendingInstances();
|
|
eventSheetManager.BlockFlushingInstances(true);
|
|
this.PushCurrentLayout(this.GetMainRunningLayout());
|
|
if (isDebug)
|
|
C3Debugger.StartMeasuringTime();
|
|
if (this.IsDebugging())
|
|
await eventSheetManager.DebugRunScheduledWaits();
|
|
else
|
|
eventSheetManager.RunScheduledWaits();
|
|
if (isDebug)
|
|
C3Debugger.AddEventsTime();
|
|
this.PopCurrentLayout();
|
|
eventSheetManager.BlockFlushingInstances(false);
|
|
this.FlushPendingInstances();
|
|
eventSheetManager.BlockFlushingInstances(true)
|
|
}
|
|
async Step_AfterPreTick() {
|
|
const isDebug = this.IsDebug();
|
|
const isDebugging = this.IsDebugging();
|
|
const dispatcher = this._dispatcher;
|
|
const eventObjects = this._eventObjects;
|
|
const userScriptEventObjects = this._userScriptEventObjects;
|
|
if (isDebug)
|
|
C3Debugger.StartMeasuringTime();
|
|
if (isDebugging)
|
|
await this.DebugIterateAndBreak(this._DebugBehaviorTick());
|
|
else
|
|
this._BehaviorTick();
|
|
if (isDebugging)
|
|
await this.DebugIterateAndBreak(this._DebugBehaviorPostTick());
|
|
else
|
|
this._BehaviorPostTick();
|
|
if (isDebug)
|
|
C3Debugger.AddBehaviorTickTime();
|
|
if (isDebug)
|
|
C3Debugger.StartMeasuringTime();
|
|
if (isDebugging)
|
|
await this.DebugFireGeneratorEventAndBreak(eventObjects["tick"]);
|
|
else
|
|
dispatcher.dispatchEvent(eventObjects["tick"]);
|
|
if (isDebug)
|
|
C3Debugger.AddPluginTickTime();
|
|
this._eventSheetManager.BlockFlushingInstances(false);
|
|
this.DispatchUserScriptEvent(userScriptEventObjects["tick"])
|
|
}
|
|
async Step_RunEventsEtc() {
|
|
const eventSheetManager = this._eventSheetManager;
|
|
const dispatcher = this._dispatcher;
|
|
const eventObjects = this._eventObjects;
|
|
const isDebug = this.IsDebug();
|
|
const isDebugging = this.IsDebugging();
|
|
if (isDebug)
|
|
C3Debugger.StartMeasuringTime();
|
|
if (isDebugging)
|
|
await eventSheetManager.DebugRunEvents(this._layoutManager);
|
|
else
|
|
eventSheetManager.RunEvents(this._layoutManager);
|
|
if (isDebug)
|
|
C3Debugger.AddEventsTime();
|
|
this._collisionEngine.ClearRegisteredCollisions();
|
|
if (this._instancesToReleaseAtEndOfTick.size > 0) {
|
|
dispatcher.SetDelayRemoveEventsEnabled(true);
|
|
for (const objectClass of this._instancesToReleaseAffectedObjectClasses)
|
|
objectClass.GetSolStack().RemoveInstances(this._instancesToReleaseAtEndOfTick);
|
|
this._instancesToReleaseAffectedObjectClasses.clear();
|
|
this._eventSheetManager.RemoveInstancesFromScheduledWaits(this._instancesToReleaseAtEndOfTick);
|
|
for (const inst of this._instancesToReleaseAtEndOfTick)
|
|
inst.Release();
|
|
this._instancesToReleaseAtEndOfTick.clear();
|
|
dispatcher.SetDelayRemoveEventsEnabled(false)
|
|
}
|
|
this._isLayoutFirstTick = false;
|
|
eventSheetManager.BlockFlushingInstances(true);
|
|
if (isDebug)
|
|
C3Debugger.StartMeasuringTime();
|
|
if (isDebugging)
|
|
await this.DebugIterateAndBreak(this._DebugBehaviorTick2());
|
|
else
|
|
this._BehaviorTick2();
|
|
if (isDebug)
|
|
C3Debugger.AddBehaviorTickTime();
|
|
if (isDebug)
|
|
C3Debugger.StartMeasuringTime();
|
|
if (isDebugging)
|
|
await this.DebugFireGeneratorEventAndBreak(eventObjects["tick2"]);
|
|
else
|
|
dispatcher.dispatchEvent(eventObjects["tick2"]);
|
|
if (isDebug)
|
|
C3Debugger.AddPluginTickTime();
|
|
eventSheetManager.BlockFlushingInstances(false);
|
|
if (isDebugging)
|
|
await eventSheetManager.RunQueuedDebugTriggersAsync()
|
|
}
|
|
async _MaybeChangeLayout() {
|
|
const layoutManager = this.GetLayoutManager();
|
|
let i = 0;
|
|
while (layoutManager.IsPendingChangeMainLayout() && i++ < 10)
|
|
await this._DoChangeLayout(layoutManager.GetPendingChangeMainLayout())
|
|
}
|
|
_MeasureDt(timestamp) {
|
|
if (this._lastTickTime !== 0) {
|
|
const msDiff = Math.max(timestamp - this._lastTickTime, 0);
|
|
this._dt1 = msDiff / 1E3;
|
|
const maxDt1 = 1 / this._minimumFramerate;
|
|
if (this._dt1 > .5)
|
|
this._dt1 = 0;
|
|
else if (this._dt1 > maxDt1)
|
|
this._dt1 = maxDt1
|
|
}
|
|
this._lastTickTime = timestamp;
|
|
this._dt = this._dt1 * this._timeScale;
|
|
this._gameTime.Add(this._dt);
|
|
this._wallTime.Add(this._dt1);
|
|
if (this._canvasManager)
|
|
this._canvasManager._UpdateTick();
|
|
if (timestamp - this._fpsLastTime >= 1E3) {
|
|
this._fpsLastTime += 1E3;
|
|
if (timestamp - this._fpsLastTime >= 1E3)
|
|
this._fpsLastTime = timestamp;
|
|
this._fps = this._fpsFrameCount;
|
|
this._fpsFrameCount = 0;
|
|
this._mainThreadTime = Math.min(this._mainThreadTimeCounter / 1E3, 1);
|
|
this._mainThreadTimeCounter = 0;
|
|
if (this._canvasManager)
|
|
this._canvasManager._Update1sFrameRange();
|
|
this._collisionEngine._Update1sStats();
|
|
if (this.IsDebug())
|
|
C3Debugger.Update1sPerfStats()
|
|
}
|
|
this._fpsFrameCount++
|
|
}
|
|
async _DoChangeLayout(changeToLayout) {
|
|
const dispatcher = this._dispatcher;
|
|
const layoutManager = this.GetLayoutManager();
|
|
const prevLayout = layoutManager.GetMainRunningLayout();
|
|
await prevLayout._StopRunning();
|
|
prevLayout._Unload(changeToLayout, this.GetWebGLRenderer());
|
|
if (prevLayout === changeToLayout)
|
|
this._eventSheetManager.ClearAllScheduledWaits();
|
|
this._collisionEngine.ClearRegisteredCollisions();
|
|
dispatcher.dispatchEvent(this._eventObjects["beforelayoutchange"]);
|
|
C3.Asyncify.SetHighThroughputMode(true);
|
|
await changeToLayout._Load(prevLayout, this.GetWebGLRenderer());
|
|
C3.Asyncify.SetHighThroughputMode(false);
|
|
await changeToLayout._StartRunning(false);
|
|
dispatcher.dispatchEvent(this._eventObjects["layoutchange"]);
|
|
this.UpdateRender();
|
|
this._isLayoutFirstTick = true;
|
|
this.FlushPendingInstances()
|
|
}
|
|
UpdateRender() {
|
|
this._needRender = true
|
|
}
|
|
GetWebGLRenderer() {
|
|
if (!this._canvasManager)
|
|
return null;
|
|
return this._canvasManager.GetWebGLRenderer()
|
|
}
|
|
GetRenderer() {
|
|
return this.GetWebGLRenderer()
|
|
}
|
|
Render() {
|
|
if (!this._canvasManager || this._canvasManager.IsWebGLContextLost())
|
|
return;
|
|
const renderer = this.GetWebGLRenderer();
|
|
renderer.Start();
|
|
renderer.CheckForQueryResults();
|
|
if (!this._needRender) {
|
|
renderer.IncrementFrameNumber();
|
|
return
|
|
}
|
|
const isDebug = this.IsDebug();
|
|
if (isDebug)
|
|
C3Debugger.StartMeasuringTime();
|
|
this._needRender = false;
|
|
let frameQuery = null;
|
|
if (renderer.SupportsGPUProfiling()) {
|
|
frameQuery = this._canvasManager.GetGPUFrameTimingsBuffer().AddTimeElapsedQuery();
|
|
renderer.StartQuery(frameQuery)
|
|
}
|
|
renderer.SetTextureFillMode();
|
|
renderer.SetAlphaBlend();
|
|
renderer.SetColorRgba(1, 1, 1, 1);
|
|
renderer.SetRenderTarget(null);
|
|
renderer.SetTexture(null);
|
|
const layout = this._layoutManager.GetMainRunningLayout();
|
|
layout.Draw(renderer);
|
|
if (frameQuery)
|
|
renderer.EndQuery(frameQuery);
|
|
renderer.Finish();
|
|
if (isDebug) {
|
|
C3Debugger.AddDrawCallsTime();
|
|
C3Debugger.UpdateInspectHighlight()
|
|
}
|
|
if (this._canvasManager)
|
|
this._canvasManager._MaybeTakeSnapshot()
|
|
}
|
|
Trigger(method, inst, behaviorType) {
|
|
if (!this._hasStarted)
|
|
return false;
|
|
const isTopLevel = !this._isInTick && !this._eventSheetManager.IsInTrigger();
|
|
let startTime = 0;
|
|
if (isTopLevel)
|
|
startTime = performance.now();
|
|
const isDebug = this.IsDebug();
|
|
if (isDebug)
|
|
this.SetDebuggingEnabled(false);
|
|
const ret = this._eventSheetManager._Trigger(this._layoutManager, method, inst, behaviorType);
|
|
if (isTopLevel) {
|
|
const triggerTime = performance.now() - startTime;
|
|
this._mainThreadTimeCounter += triggerTime;
|
|
if (isDebug)
|
|
C3Debugger.AddTriggersTime(triggerTime)
|
|
}
|
|
if (isDebug)
|
|
this.SetDebuggingEnabled(true);
|
|
return ret
|
|
}
|
|
DebugTrigger(method, inst, behaviorType) {
|
|
if (!this.IsDebug())
|
|
return this.Trigger(method, inst, behaviorType);
|
|
if (this.HitBreakpoint())
|
|
throw new Error("called DebugTrigger() while stopped on breakpoint");
|
|
if (!this._isInTick && !this._eventSheetManager.IsInTrigger())
|
|
throw new Error("called DebugTrigger() outside of event code - use TriggerAsync() instead");
|
|
return this._eventSheetManager._DebugTrigger(this._layoutManager, method, inst, behaviorType)
|
|
}
|
|
async TriggerAsync(method, inst, behaviorType) {
|
|
if (!this.IsDebugging())
|
|
return this.Trigger(method, inst, behaviorType);
|
|
if (!this._hasStarted)
|
|
return false;
|
|
if (this.HitBreakpoint())
|
|
return this._eventSheetManager.QueueDebugTrigger(method, inst, behaviorType);
|
|
if (!this.GetMainRunningLayout())
|
|
return this._eventSheetManager.QueueTrigger(method, inst, behaviorType);
|
|
const startTime = performance.now();
|
|
const iter = this._eventSheetManager._DebugTrigger(this._layoutManager, method, inst, behaviorType);
|
|
let result = iter.next();
|
|
while (!result.done) {
|
|
await this.DebugBreak(result.value);
|
|
result = iter.next()
|
|
}
|
|
if (!this.IsSuspended() && !this._eventSheetManager.IsInTrigger()) {
|
|
await this._eventSheetManager.RunQueuedDebugTriggersAsync();
|
|
if (this._hasStartedTicking && !this._isInTick)
|
|
this._RequestAnimationFrame()
|
|
}
|
|
this._mainThreadTimeCounter += performance.now() - startTime;
|
|
return result.value
|
|
}
|
|
FastTrigger(method, inst, value) {
|
|
const isDebug = this.IsDebug();
|
|
if (isDebug)
|
|
this.SetDebuggingEnabled(false);
|
|
const ret = this._eventSheetManager._FastTrigger(this._layoutManager, method, inst, value);
|
|
if (isDebug)
|
|
this.SetDebuggingEnabled(true);
|
|
return ret
|
|
}
|
|
DebugFastTrigger(method, inst, value) {
|
|
return this._eventSheetManager._DebugFastTrigger(this._layoutManager, method, inst, value)
|
|
}
|
|
ScheduleTriggers(f) {
|
|
return this._scheduleTriggersThrottle.Add(f)
|
|
}
|
|
PushCurrentLayout(layout) {
|
|
this._currentLayoutStack.push(layout)
|
|
}
|
|
PopCurrentLayout() {
|
|
if (!this._currentLayoutStack.length)
|
|
throw new Error("layout stack empty");
|
|
this._currentLayoutStack.pop()
|
|
}
|
|
GetCurrentLayout() {
|
|
if (!this._currentLayoutStack.length)
|
|
return this.GetMainRunningLayout();
|
|
return this._currentLayoutStack[this._currentLayoutStack.length - 1]
|
|
}
|
|
GetDt(inst) {
|
|
if (!inst || inst.GetTimeScale() === -1)
|
|
return this._dt;
|
|
return this._dt1 * inst.GetTimeScale()
|
|
}
|
|
_GetDtFast() {
|
|
return this._dt
|
|
}
|
|
GetDt1() {
|
|
return this._dt1
|
|
}
|
|
GetTimeScale() {
|
|
return this._timeScale
|
|
}
|
|
SetTimeScale(ts) {
|
|
if (isNaN(ts) || ts < 0)
|
|
ts = 0;
|
|
this._timeScale = ts
|
|
}
|
|
SetMinimumFramerate(fps) {
|
|
this._minimumFramerate = C3.clamp(fps, 1, 120)
|
|
}
|
|
GetMinimumFramerate() {
|
|
return this._minimumFramerate
|
|
}
|
|
GetFPS() {
|
|
return this._fps
|
|
}
|
|
GetMainThreadTime() {
|
|
return this._mainThreadTime
|
|
}
|
|
GetStartTime() {
|
|
return this._startTime
|
|
}
|
|
GetGameTime() {
|
|
return this._gameTime.Get()
|
|
}
|
|
GetWallTime() {
|
|
return this._wallTime.Get()
|
|
}
|
|
GetTickCount() {
|
|
return this._tickCount
|
|
}
|
|
GetTickCountNoSave() {
|
|
return this._tickCountNoSave
|
|
}
|
|
IncrementExecCount() {
|
|
++this._execCount
|
|
}
|
|
GetExecCount() {
|
|
return this._execCount
|
|
}
|
|
GetObjectCount() {
|
|
return this._objectCount
|
|
}
|
|
GetProjectName() {
|
|
return this._projectName
|
|
}
|
|
GetProjectVersion() {
|
|
return this._projectVersion
|
|
}
|
|
GetProjectUniqueId() {
|
|
return this._projectUniqueId
|
|
}
|
|
GetAppId() {
|
|
return this._appId
|
|
}
|
|
GetInstanceByUID(uid) {
|
|
if (this._isLoadingState)
|
|
throw new Error("cannot call while loading state - wait until afterload event");
|
|
return this._instancesByUid.get(uid) || null
|
|
}
|
|
_RefreshUidMap() {
|
|
this._instancesByUid.clear();
|
|
for (const objectClass of this._allObjectClasses) {
|
|
if (objectClass.IsFamily())
|
|
continue;
|
|
for (const inst of objectClass.GetInstances())
|
|
this._instancesByUid.set(inst.GetUID(), inst)
|
|
}
|
|
}
|
|
IsPreview() {
|
|
return this._exportType === "preview"
|
|
}
|
|
IsDebug() {
|
|
return this._isDebug
|
|
}
|
|
GetExportType() {
|
|
return this._exportType
|
|
}
|
|
IsCordova() {
|
|
return this._exportType === "cordova"
|
|
}
|
|
IsAndroidWebView() {
|
|
return C3.Platform.OS === "Android" && (this._exportType === "cordova" || this._exportType === "playable-ad" || this._exportType === "instant-games")
|
|
}
|
|
IsiOSCordova() {
|
|
return this._isiOSCordova
|
|
}
|
|
IsiOSWebView() {
|
|
return this._isiOSWebView
|
|
}
|
|
GetCollisionEngine() {
|
|
return this._collisionEngine
|
|
}
|
|
GetSolidBehavior() {
|
|
return this._pluginManager.GetSolidBehavior()
|
|
}
|
|
GetJumpthruBehavior() {
|
|
return this._pluginManager.GetJumpthruBehavior()
|
|
}
|
|
IsLayoutFirstTick() {
|
|
return this._isLayoutFirstTick
|
|
}
|
|
SetPixelRoundingEnabled(e) {
|
|
e = !!e;
|
|
if (this._isPixelRoundingEnabled === e)
|
|
return;
|
|
this._isPixelRoundingEnabled = e;
|
|
this.UpdateRender()
|
|
}
|
|
IsPixelRoundingEnabled() {
|
|
return this._isPixelRoundingEnabled
|
|
}
|
|
SaveToSlot(slotName) {
|
|
this._saveToSlotName = slotName
|
|
}
|
|
LoadFromSlot(slotName) {
|
|
this._loadFromSlotName = slotName
|
|
}
|
|
LoadFromJsonString(str) {
|
|
this._loadFromJson = str
|
|
}
|
|
GetLastSaveJsonString() {
|
|
return this._lastSaveJson
|
|
}
|
|
_NeedsHandleSaveOrLoad() {
|
|
return !!(this._saveToSlotName || this._loadFromSlotName || this._loadFromJson !== null)
|
|
}
|
|
async _HandleSaveOrLoad() {
|
|
if (this._saveToSlotName) {
|
|
this.FlushPendingInstances();
|
|
await this._DoSaveToSlot(this._saveToSlotName);
|
|
this._ClearSaveOrLoad()
|
|
}
|
|
if (this._loadFromSlotName) {
|
|
await this._DoLoadFromSlot(this._loadFromSlotName);
|
|
this._ClearSaveOrLoad();
|
|
if (this.IsDebug())
|
|
C3Debugger.StepIfPausedInDebugger()
|
|
}
|
|
if (this._loadFromJson !== null) {
|
|
this.FlushPendingInstances();
|
|
try {
|
|
await this._DoLoadFromJsonString(this._loadFromJson);
|
|
this._lastSaveJson = this._loadFromJson;
|
|
await this.TriggerAsync(C3.Plugins.System.Cnds.OnLoadComplete, null);
|
|
this._lastSaveJson = ""
|
|
} catch (err) {
|
|
console.error("[Construct 3] Failed to load state from JSON string: ", err);
|
|
await this.TriggerAsync(C3.Plugins.System.Cnds.OnLoadFailed, null)
|
|
}
|
|
this._ClearSaveOrLoad()
|
|
}
|
|
}
|
|
_ClearSaveOrLoad() {
|
|
this._saveToSlotName = "";
|
|
this._loadFromSlotName = "";
|
|
this._loadFromJson = null
|
|
}
|
|
_GetProjectStorage() {
|
|
if (!this._projectStorage)
|
|
this._projectStorage = localforage.createInstance({
|
|
name: "c3-localstorage-" + this.GetProjectUniqueId(),
|
|
description: this.GetProjectName()
|
|
});
|
|
return this._projectStorage
|
|
}
|
|
_GetSavegamesStorage() {
|
|
if (!this._savegamesStorage)
|
|
this._savegamesStorage = localforage.createInstance({
|
|
name: "c3-savegames-" + this.GetProjectUniqueId(),
|
|
description: this.GetProjectName()
|
|
});
|
|
return this._savegamesStorage
|
|
}
|
|
async _DoSaveToSlot(slotName) {
|
|
const saveJson = await this._SaveToJsonString();
|
|
try {
|
|
await this._GetSavegamesStorage().setItem(slotName, saveJson);
|
|
console.log("[Construct 3] Saved state to storage (" + saveJson.length + " chars)");
|
|
this._lastSaveJson = saveJson;
|
|
await this.TriggerAsync(C3.Plugins.System.Cnds.OnSaveComplete, null);
|
|
this._lastSaveJson = ""
|
|
} catch (err) {
|
|
console.error("[Construct 3] Failed to save state to storage: ", err);
|
|
await this.TriggerAsync(C3.Plugins.System.Cnds.OnSaveFailed, null)
|
|
}
|
|
}
|
|
async _DoLoadFromSlot(slotName) {
|
|
try {
|
|
const loadJson = await this._GetSavegamesStorage().getItem(slotName);
|
|
if (!loadJson)
|
|
throw new Error("empty slot");
|
|
console.log("[Construct 3] Loaded state from storage (" + loadJson.length + " chars)");
|
|
await this._DoLoadFromJsonString(loadJson);
|
|
this._lastSaveJson = loadJson;
|
|
await this.TriggerAsync(C3.Plugins.System.Cnds.OnLoadComplete, null);
|
|
this._lastSaveJson = ""
|
|
} catch (err) {
|
|
console.error("[Construct 3] Failed to load state from storage: ", err);
|
|
await this.TriggerAsync(C3.Plugins.System.Cnds.OnLoadFailed, null)
|
|
}
|
|
}
|
|
async _SaveToJsonString() {
|
|
const o = {
|
|
"c3save": true,
|
|
"version": 1,
|
|
"rt": {
|
|
"time": this.GetGameTime(),
|
|
"walltime": this.GetWallTime(),
|
|
"timescale": this.GetTimeScale(),
|
|
"tickcount": this.GetTickCount(),
|
|
"execcount": this.GetExecCount(),
|
|
"next_uid": this._nextUid,
|
|
"running_layout": this.GetMainRunningLayout().GetSID(),
|
|
"start_time_offset": Date.now() - this._startTime
|
|
},
|
|
"types": {},
|
|
"layouts": {},
|
|
"events": this._eventSheetManager._SaveToJson(),
|
|
"timelines": this._timelineManager._SaveToJson(),
|
|
"user_script_data": null
|
|
};
|
|
for (const objectClass of this._allObjectClasses) {
|
|
if (objectClass.IsFamily() || objectClass.HasNoSaveBehavior())
|
|
continue;
|
|
o["types"][objectClass.GetSID().toString()] = objectClass._SaveToJson()
|
|
}
|
|
for (const layout of this._layoutManager.GetAllLayouts())
|
|
o["layouts"][layout.GetSID().toString()] = layout._SaveToJson();
|
|
const saveEvent = this._CreateUserScriptEvent("save");
|
|
saveEvent.saveData = null;
|
|
await this.DispatchUserScriptEventAsyncWait(saveEvent);
|
|
o["user_script_data"] = saveEvent.saveData;
|
|
return JSON.stringify(o)
|
|
}
|
|
IsLoadingState() {
|
|
return this._isLoadingState
|
|
}
|
|
_TriggerOnCreateAfterLoad(arr) {
|
|
C3.shallowAssignArray(this._triggerOnCreateAfterLoad, arr)
|
|
}
|
|
async _DoLoadFromJsonString(jsonStr) {
|
|
const o = JSON.parse(jsonStr);
|
|
if (o["c2save"])
|
|
throw new Error("C2 saves are incompatible with C3 runtime");
|
|
if (!o["c3save"])
|
|
throw new Error("not valid C3 save data");
|
|
if (o["version"] > 1)
|
|
throw new Error("C3 save data from future version");
|
|
this._isLoadingState = true;
|
|
const rt = o["rt"];
|
|
this._gameTime.Set(rt["time"]);
|
|
this._wallTime.Set(rt["walltime"]);
|
|
this._timeScale = rt["timescale"];
|
|
this._tickCount = rt["tickcount"];
|
|
this._execCount = rt["execcount"];
|
|
this._startTime = Date.now() - rt["start_time_offset"];
|
|
const layoutSid = rt["running_layout"];
|
|
if (layoutSid !== this.GetMainRunningLayout().GetSID()) {
|
|
const changeToLayout = this._layoutManager.GetLayoutBySID(layoutSid);
|
|
if (changeToLayout)
|
|
await this._DoChangeLayout(changeToLayout);
|
|
else
|
|
return
|
|
}
|
|
for (const [sidStr,data] of Object.entries(o["types"])) {
|
|
const sid = parseInt(sidStr, 10);
|
|
const objectClass = this.GetObjectClassBySID(sid);
|
|
if (!objectClass || objectClass.IsFamily() || objectClass.HasNoSaveBehavior())
|
|
continue;
|
|
objectClass._LoadFromJson(data)
|
|
}
|
|
this.FlushPendingInstances();
|
|
this._RefreshUidMap();
|
|
this._isLoadingState = false;
|
|
this._nextUid = rt["next_uid"];
|
|
for (const [sidStr,data] of Object.entries(o["layouts"])) {
|
|
const sid = parseInt(sidStr, 10);
|
|
const layout = this._layoutManager.GetLayoutBySID(sid);
|
|
if (!layout)
|
|
continue;
|
|
layout._LoadFromJson(data)
|
|
}
|
|
this._eventSheetManager._LoadFromJson(o["events"]);
|
|
for (const inst of this._triggerOnCreateAfterLoad) {
|
|
inst._TriggerOnCreated();
|
|
inst.SetupInitialSceneGraphConnections()
|
|
}
|
|
C3.clearArray(this._triggerOnCreateAfterLoad);
|
|
for (const objectClass of this._allObjectClasses) {
|
|
if (objectClass.IsFamily() || !objectClass.IsInContainer())
|
|
continue;
|
|
for (const inst of objectClass.GetInstances()) {
|
|
const iid = inst.GetIID();
|
|
for (const otherType of objectClass.GetContainer().objectTypes()) {
|
|
if (otherType === objectClass)
|
|
continue;
|
|
const otherInstances = otherType.GetInstances();
|
|
if (iid < 0 || iid >= otherInstances.length)
|
|
throw new Error("missing sibling instance");
|
|
inst._AddSibling(otherInstances[iid])
|
|
}
|
|
}
|
|
}
|
|
this._timelineManager._LoadFromJson(o["timelines"]);
|
|
this._dispatcher.dispatchEvent(C3.New(C3.Event, "afterload"));
|
|
const loadEvent = this._CreateUserScriptEvent("load");
|
|
loadEvent.saveData = o["user_script_data"];
|
|
await this.DispatchUserScriptEventAsyncWait(loadEvent);
|
|
this.UpdateRender()
|
|
}
|
|
async AddJobWorkerScripts(scripts) {
|
|
const blobs = await Promise.all(scripts.map(url=>this._assetManager.FetchBlob(url)));
|
|
const blobUrls = blobs.map(b=>URL.createObjectURL(b));
|
|
this._jobScheduler.ImportScriptsToJobWorkers(blobUrls)
|
|
}
|
|
AddJobWorkerBlob(blob, id) {
|
|
this._jobScheduler.SendBlobToJobWorkers(blob, id)
|
|
}
|
|
AddJobWorkerBuffer(buffer, id) {
|
|
this._jobScheduler.SendBufferToJobWorkers(buffer, id)
|
|
}
|
|
AddJob(type, params, transferables) {
|
|
return this._jobScheduler.AddJob(type, params, transferables)
|
|
}
|
|
BroadcastJob(type, params, transferables) {
|
|
return this._jobScheduler.BroadcastJob(type, params, transferables)
|
|
}
|
|
InvokeDownload(url, filename) {
|
|
this.PostComponentMessageToDOM("runtime", "invoke-download", {
|
|
"url": url,
|
|
"filename": filename
|
|
})
|
|
}
|
|
async RasterSvgImage(blob, imageWidth, imageHeight, surfaceWidth, surfaceHeight, imageBitmapOpts) {
|
|
surfaceWidth = surfaceWidth || imageWidth;
|
|
surfaceHeight = surfaceHeight || imageHeight;
|
|
if (this.IsInWorker()) {
|
|
const result = await this.PostComponentMessageToDOMAsync("runtime", "raster-svg-image", {
|
|
"blob": blob,
|
|
"imageWidth": imageWidth,
|
|
"imageHeight": imageHeight,
|
|
"surfaceWidth": surfaceWidth,
|
|
"surfaceHeight": surfaceHeight,
|
|
"imageBitmapOpts": imageBitmapOpts
|
|
});
|
|
return result["imageBitmap"]
|
|
} else {
|
|
const canvas = await self["C3_RasterSvgImageBlob"](blob, imageWidth, imageHeight, surfaceWidth, surfaceHeight);
|
|
if (imageBitmapOpts)
|
|
return await self.createImageBitmap(canvas, imageBitmapOpts);
|
|
else
|
|
return canvas
|
|
}
|
|
}
|
|
async GetSvgImageSize(blob) {
|
|
if (this.IsInWorker())
|
|
return await this.PostComponentMessageToDOMAsync("runtime", "get-svg-image-size", {
|
|
"blob": blob
|
|
});
|
|
else
|
|
return await self["C3_GetSvgImageSize"](blob)
|
|
}
|
|
RequestDeviceOrientationEvent() {
|
|
if (this._didRequestDeviceOrientationEvent)
|
|
return;
|
|
this._didRequestDeviceOrientationEvent = true;
|
|
this.PostComponentMessageToDOM("runtime", "enable-device-orientation")
|
|
}
|
|
RequestDeviceMotionEvent() {
|
|
if (this._didRequestDeviceMotionEvent)
|
|
return;
|
|
this._didRequestDeviceMotionEvent = true;
|
|
this.PostComponentMessageToDOM("runtime", "enable-device-motion")
|
|
}
|
|
Random() {
|
|
return this._randomNumberCallback()
|
|
}
|
|
SetRandomNumberGeneratorCallback(f) {
|
|
this._randomNumberCallback = f
|
|
}
|
|
_GetRemotePreviewStatusInfo() {
|
|
return {
|
|
"fps": this.GetFPS(),
|
|
"cpu": this.GetMainThreadTime(),
|
|
"gpu": this.GetGPUUtilisation(),
|
|
"layout": this.GetMainRunningLayout() ? this.GetMainRunningLayout().GetName() : "",
|
|
"renderer": this.GetWebGLRenderer().GetUnmaskedRenderer()
|
|
}
|
|
}
|
|
HitBreakpoint() {
|
|
if (!this.IsDebug())
|
|
return false;
|
|
return C3Debugger.HitBreakpoint()
|
|
}
|
|
DebugBreak(eventObject) {
|
|
if (!this.IsDebugging())
|
|
return Promise.resolve();
|
|
return C3Debugger.DebugBreak(eventObject)
|
|
}
|
|
DebugBreakNext() {
|
|
if (!this.IsDebugging())
|
|
return false;
|
|
return C3Debugger.BreakNext()
|
|
}
|
|
SetDebugBreakpointsEnabled(e) {
|
|
this._breakpointsEnabled = !!e;
|
|
this._UpdateDebuggingFlag()
|
|
}
|
|
AreDebugBreakpointsEnabled() {
|
|
return this._breakpointsEnabled
|
|
}
|
|
IsDebugging() {
|
|
return this._isDebugging
|
|
}
|
|
SetDebuggingEnabled(d) {
|
|
if (d)
|
|
this._debuggingDisabled--;
|
|
else
|
|
this._debuggingDisabled++;
|
|
this._UpdateDebuggingFlag()
|
|
}
|
|
_UpdateDebuggingFlag() {
|
|
this._isDebugging = this.IsDebug() && this._breakpointsEnabled && this._debuggingDisabled === 0
|
|
}
|
|
IsCPUProfiling() {
|
|
return this.IsDebug() && C3Debugger.IsCPUProfiling()
|
|
}
|
|
IsGPUProfiling() {
|
|
return this.IsDebug() && this.GetWebGLRenderer().SupportsGPUProfiling() && C3Debugger.IsGPUProfiling()
|
|
}
|
|
async DebugIterateAndBreak(iter) {
|
|
if (!iter)
|
|
return;
|
|
for (const breakEventObject of iter)
|
|
await this.DebugBreak(breakEventObject)
|
|
}
|
|
DebugFireGeneratorEventAndBreak(event) {
|
|
return this.DebugIterateAndBreak(this._dispatcher.dispatchGeneratorEvent(event))
|
|
}
|
|
_InvokeFunctionFromJS(e) {
|
|
return this._eventSheetManager._InvokeFunctionFromJS(e["name"], e["params"])
|
|
}
|
|
GetIRuntime() {
|
|
return this._iRuntime
|
|
}
|
|
_CreateUserScriptEvent(name) {
|
|
const e = C3.New(C3.Event, name, false);
|
|
e.runtime = this._iRuntime;
|
|
return e
|
|
}
|
|
_InitScriptInterfaces() {
|
|
const objectDescriptors = {};
|
|
for (const objectClass of this._allObjectClasses)
|
|
objectDescriptors[objectClass.GetJsPropName()] = {
|
|
value: objectClass.GetIObjectClass(),
|
|
enumerable: true,
|
|
writable: false
|
|
};
|
|
const objects = Object.create(Object.prototype, objectDescriptors);
|
|
this._iRuntime = new self.IRuntime(this,objects);
|
|
this._userScriptEventObjects = {
|
|
"tick": this._CreateUserScriptEvent("tick")
|
|
}
|
|
}
|
|
_InitGlobalVariableScriptInterface() {
|
|
const globalVarDescriptors = {};
|
|
for (const globalVar of this.GetEventSheetManager().GetAllGlobalVariables())
|
|
globalVarDescriptors[globalVar.GetJsPropName()] = globalVar._GetScriptInterfaceDescriptor();
|
|
this._iRuntime._InitGlobalVars(globalVarDescriptors)
|
|
}
|
|
_GetCommonScriptInterfaces() {
|
|
return this._commonScriptInterfaces
|
|
}
|
|
_MapScriptInterface(interface_, class_) {
|
|
this._interfaceMap.set(interface_, class_)
|
|
}
|
|
_UnwrapScriptInterface(interface_) {
|
|
return this._interfaceMap.get(interface_)
|
|
}
|
|
}
|
|
;
|
|
self["C3_CreateRuntime"] = C3.Runtime.Create;
|
|
self["C3_InitRuntime"] = (runtime,opts)=>runtime.Init(opts)
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.JobSchedulerRuntime = class JobSchedulerRuntime extends C3.DefendedBase {
|
|
constructor(runtime, data) {
|
|
super();
|
|
this._runtime = runtime;
|
|
this._jobPromises = new Map;
|
|
this._nextJobId = 0;
|
|
this._inputPort = data["inputPort"];
|
|
data["outputPort"].onmessage = e=>this._OnJobWorkerMessage(e);
|
|
this._maxNumWorkers = data["maxNumWorkers"];
|
|
this._jobWorkerCount = 1;
|
|
this._isCreatingWorker = false;
|
|
this._hadErrorCreatingWorker = false
|
|
}
|
|
async Init() {}
|
|
ImportScriptsToJobWorkers(scripts) {
|
|
this._inputPort.postMessage({
|
|
"type": "_import_scripts",
|
|
"scripts": scripts
|
|
})
|
|
}
|
|
SendBlobToJobWorkers(blob, id) {
|
|
this._inputPort.postMessage({
|
|
"type": "_send_blob",
|
|
"blob": blob,
|
|
"id": id
|
|
})
|
|
}
|
|
SendBufferToJobWorkers(buffer, id) {
|
|
this._inputPort.postMessage({
|
|
"type": "_send_buffer",
|
|
"buffer": buffer,
|
|
"id": id
|
|
}, [buffer])
|
|
}
|
|
AddJob(type, params, transferables, progressHandler, abortDisposable) {
|
|
if (!transferables)
|
|
transferables = [];
|
|
const jobId = this._nextJobId++;
|
|
const job = {
|
|
"type": type,
|
|
"isBroadcast": false,
|
|
"jobId": jobId,
|
|
"params": params,
|
|
"transferables": transferables
|
|
};
|
|
const promise = new Promise((resolve,reject)=>{
|
|
this._jobPromises.set(jobId, {
|
|
resolve: resolve,
|
|
progress: progressHandler,
|
|
reject: reject,
|
|
cancelled: false
|
|
})
|
|
}
|
|
);
|
|
if (abortDisposable)
|
|
abortDisposable.SetAction(()=>this._CancelJob(jobId));
|
|
this._inputPort.postMessage(job, transferables);
|
|
this._MaybeCreateExtraWorker();
|
|
return promise
|
|
}
|
|
BroadcastJob(type, params, transferables) {
|
|
if (!transferables)
|
|
transferables = [];
|
|
const jobId = this._nextJobId++;
|
|
const job = {
|
|
"type": type,
|
|
"isBroadcast": true,
|
|
"jobId": jobId,
|
|
"params": params,
|
|
"transferables": transferables
|
|
};
|
|
this._inputPort.postMessage(job, transferables)
|
|
}
|
|
_CancelJob(jobId) {
|
|
const job = this._jobPromises.get(jobId);
|
|
if (job) {
|
|
job.cancelled = true;
|
|
job.resolve = null;
|
|
job.progress = null;
|
|
job.reject = null;
|
|
this._inputPort.postMessage({
|
|
"type": "_cancel",
|
|
"jobId": jobId
|
|
})
|
|
}
|
|
}
|
|
_OnJobWorkerMessage(e) {
|
|
const msg = e.data;
|
|
const type = msg["type"];
|
|
const id = msg["jobId"];
|
|
switch (type) {
|
|
case "result":
|
|
this._OnJobResult(id, msg["result"]);
|
|
break;
|
|
case "progress":
|
|
this._OnJobProgress(id, msg["progress"]);
|
|
break;
|
|
case "error":
|
|
this._OnJobError(id, msg["error"]);
|
|
break;
|
|
case "ready":
|
|
this._OnJobWorkerReady();
|
|
break;
|
|
default:
|
|
throw new Error(`unknown message from worker '${type}'`);
|
|
}
|
|
}
|
|
_OnJobResult(jobId, result) {
|
|
const p = this._jobPromises.get(jobId);
|
|
if (!p)
|
|
throw new Error("invalid job ID");
|
|
if (!p.cancelled)
|
|
p.resolve(result);
|
|
this._jobPromises.delete(jobId)
|
|
}
|
|
_OnJobProgress(jobId, progress) {
|
|
const p = this._jobPromises.get(jobId);
|
|
if (!p)
|
|
throw new Error("invalid job ID");
|
|
if (!p.cancelled && p.progress)
|
|
p.progress(progress)
|
|
}
|
|
_OnJobError(jobId, error) {
|
|
const p = this._jobPromises.get(jobId);
|
|
if (!p)
|
|
throw new Error("invalid job ID");
|
|
if (!p.cancelled)
|
|
p.reject(error);
|
|
this._jobPromises.delete(jobId)
|
|
}
|
|
_OnJobWorkerReady() {
|
|
if (!this._isCreatingWorker)
|
|
return;
|
|
this._isCreatingWorker = false;
|
|
this._jobWorkerCount++;
|
|
if (this._jobWorkerCount < this._maxNumWorkers)
|
|
this._MaybeCreateExtraWorker();
|
|
else
|
|
this._inputPort.postMessage({
|
|
"type": "_no_more_workers"
|
|
})
|
|
}
|
|
async _MaybeCreateExtraWorker() {
|
|
if (this._jobWorkerCount >= this._maxNumWorkers || this._isCreatingWorker || this._hadErrorCreatingWorker || this._jobPromises.size <= this._jobWorkerCount)
|
|
return;
|
|
try {
|
|
this._isCreatingWorker = true;
|
|
const result = await this._runtime.PostComponentMessageToDOMAsync("runtime", "create-job-worker");
|
|
result["outputPort"].onmessage = e=>this._OnJobWorkerMessage(e)
|
|
} catch (err) {
|
|
this._hadErrorCreatingWorker = true;
|
|
this._isCreatingWorker = false;
|
|
console.error(`[Construct 3] Failed to create job worker; stopping creating any more (created ${this._jobWorkerCount} so far)`, err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;self["C3_Shaders"] = {};
|
|
self["C3_Shaders"]["hsladjust"] = {
|
|
src: "varying mediump vec2 vTex;\nuniform lowp sampler2D samplerFront;\nprecision mediump float;\nuniform float huerotate;\nuniform float satadjust;\nuniform float lumadjust;\nvec3 rgb_to_hsl(vec3 color)\n{\nvec3 hsl = vec3(0.0, 0.0, 0.0);\nfloat fmin = min(min(color.r, color.g), color.b);\nfloat fmax = max(max(color.r, color.g), color.b);\nfloat delta = fmax - fmin;\nhsl.z = (fmax + fmin) / 2.0;\nif (delta == 0.0)\n{\nhsl.x = 0.0;\nhsl.y = 0.0;\n}\nelse\n{\nif (hsl.z < 0.5)\nhsl.y = delta / (fmax + fmin);\nelse\nhsl.y = delta / (2.0 - fmax - fmin);\nfloat dR = (((fmax - color.r) / 6.0) + (delta / 2.0)) / delta;\nfloat dG = (((fmax - color.g) / 6.0) + (delta / 2.0)) / delta;\nfloat dB = (((fmax - color.b) / 6.0) + (delta / 2.0)) / delta;\nif (color.r == fmax)\nhsl.x = dB - dG;\nelse if (color.g == fmax)\nhsl.x = (1.0 / 3.0) + dR - dB;\nelse if (color.b == fmax)\nhsl.x = (2.0 / 3.0) + dG - dR;\nif (hsl.x < 0.0)\nhsl.x += 1.0;\nelse if (hsl.x > 1.0)\nhsl.x -= 1.0;\n}\nreturn hsl;\n}\nfloat hue_to_rgb(float f1, float f2, float hue)\n{\nif (hue < 0.0)\nhue += 1.0;\nelse if (hue > 1.0)\nhue -= 1.0;\nfloat ret;\nif ((6.0 * hue) < 1.0)\nret = f1 + (f2 - f1) * 6.0 * hue;\nelse if ((2.0 * hue) < 1.0)\nret = f2;\nelse if ((3.0 * hue) < 2.0)\nret = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0;\nelse\nret = f1;\nreturn ret;\n}\nvec3 hsl_to_rgb(vec3 hsl)\n{\nvec3 rgb = vec3(hsl.z);\nif (hsl.y != 0.0)\n{\nfloat f2;\nif (hsl.z < 0.5)\nf2 = hsl.z * (1.0 + hsl.y);\nelse\nf2 = (hsl.z + hsl.y) - (hsl.y * hsl.z);\nfloat f1 = 2.0 * hsl.z - f2;\nrgb.r = hue_to_rgb(f1, f2, hsl.x + (1.0 / 3.0));\nrgb.g = hue_to_rgb(f1, f2, hsl.x);\nrgb.b = hue_to_rgb(f1, f2, hsl.x - (1.0 / 3.0));\n}\nreturn rgb;\n}\nvoid main(void)\n{\nvec4 front = texture2D(samplerFront, vTex);\nvec3 rgb = rgb_to_hsl(front.rgb) + vec3((huerotate > 0.5 ? huerotate - 1.0 : huerotate), 0, (lumadjust - 1.0) * front.a);\nrgb.y *= satadjust;\nrgb = hsl_to_rgb(rgb);\ngl_FragColor = vec4(rgb, front.a);\n}",
|
|
extendBoxHorizontal: 0,
|
|
extendBoxVertical: 0,
|
|
crossSampling: false,
|
|
mustPreDraw: false,
|
|
preservesOpaqueness: true,
|
|
animated: false,
|
|
parameters: [["huerotate", 0, "percent"], ["satadjust", 0, "percent"], ["lumadjust", 0, "percent"]]
|
|
};
|
|
self["C3_Shaders"]["brightness"] = {
|
|
src: "varying mediump vec2 vTex;\nuniform lowp sampler2D samplerFront;\nuniform lowp float brightness;\nvoid main(void)\n{\nlowp vec4 front = texture2D(samplerFront, vTex);\nlowp float a = front.a;\nif (a != 0.0)\nfront.rgb /= front.a;\nfront.rgb += (brightness - 1.0);\nfront.rgb *= a;\ngl_FragColor = front;\n}",
|
|
extendBoxHorizontal: 0,
|
|
extendBoxVertical: 0,
|
|
crossSampling: false,
|
|
mustPreDraw: false,
|
|
preservesOpaqueness: true,
|
|
animated: false,
|
|
parameters: [["brightness", 0, "percent"]]
|
|
};
|
|
function forge() {
|
|
return function(e) {
|
|
function t(a) {
|
|
if (r[a])
|
|
return r[a].exports;
|
|
var n = r[a] = {
|
|
i: a,
|
|
l: !1,
|
|
exports: {}
|
|
};
|
|
return e[a].call(n.exports, n, n.exports, t),
|
|
n.l = !0,
|
|
n.exports
|
|
}
|
|
var r = {};
|
|
return t.m = e,
|
|
t.c = r,
|
|
t.d = function(e, r, a) {
|
|
t.o(e, r) || Object.defineProperty(e, r, {
|
|
configurable: !1,
|
|
enumerable: !0,
|
|
get: a
|
|
})
|
|
}
|
|
,
|
|
t.n = function(e) {
|
|
var r = e && e.__esModule ? function() {
|
|
return e.default
|
|
}
|
|
: function() {
|
|
return e
|
|
}
|
|
;
|
|
return t.d(r, "a", r),
|
|
r
|
|
}
|
|
,
|
|
t.o = function(e, t) {
|
|
return Object.prototype.hasOwnProperty.call(e, t)
|
|
}
|
|
,
|
|
t.p = "",
|
|
t(t.s = 34)
|
|
}([function(e, t) {
|
|
e.exports = {
|
|
options: {
|
|
usePureJavaScript: !1
|
|
}
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
(function(t) {
|
|
function a(e) {
|
|
if (8 !== e && 16 !== e && 24 !== e && 32 !== e)
|
|
throw new Error("Only 8, 16, 24, or 32 bits supported: " + e)
|
|
}
|
|
function n(e) {
|
|
if (this.data = "",
|
|
this.read = 0,
|
|
"string" == typeof e)
|
|
this.data = e;
|
|
else if (c.isArrayBuffer(e) || c.isArrayBufferView(e))
|
|
if ("undefined" != typeof Buffer && e instanceof Buffer)
|
|
this.data = e.toString("binary");
|
|
else {
|
|
var t = new Uint8Array(e);
|
|
try {
|
|
this.data = String.fromCharCode.apply(null, t)
|
|
} catch (e) {
|
|
for (var r = 0; r < t.length; ++r)
|
|
this.putByte(t[r])
|
|
}
|
|
}
|
|
else
|
|
(e instanceof n || "object" == typeof e && "string" == typeof e.data && "number" == typeof e.read) && (this.data = e.data,
|
|
this.read = e.read);
|
|
this._constructedStringLength = 0
|
|
}
|
|
function i(e, t) {
|
|
t = t || {},
|
|
this.read = t.readOffset || 0,
|
|
this.growSize = t.growSize || 1024;
|
|
var r = c.isArrayBuffer(e)
|
|
, a = c.isArrayBufferView(e);
|
|
if (r || a)
|
|
return this.data = r ? new DataView(e) : new DataView(e.buffer,e.byteOffset,e.byteLength),
|
|
void (this.write = "writeOffset"in t ? t.writeOffset : this.data.byteLength);
|
|
this.data = new DataView(new ArrayBuffer(0)),
|
|
this.write = 0,
|
|
null !== e && void 0 !== e && this.putBytes(e),
|
|
"writeOffset"in t && (this.write = t.writeOffset)
|
|
}
|
|
var s = r(0)
|
|
, o = r(37)
|
|
, c = e.exports = s.util = s.util || {};
|
|
!function() {
|
|
function e(e) {
|
|
if (e.source === window && e.data === t) {
|
|
e.stopPropagation();
|
|
var a = r.slice();
|
|
r.length = 0,
|
|
a.forEach(function(e) {
|
|
e()
|
|
})
|
|
}
|
|
}
|
|
if ("undefined" != typeof process && process.nextTick && !process.browser)
|
|
return c.nextTick = process.nextTick,
|
|
void ("function" == typeof setImmediate ? c.setImmediate = setImmediate : c.setImmediate = c.nextTick);
|
|
if ("function" == typeof setImmediate)
|
|
return c.setImmediate = function() {
|
|
return setImmediate.apply(void 0, arguments)
|
|
}
|
|
,
|
|
void (c.nextTick = function(e) {
|
|
return setImmediate(e)
|
|
}
|
|
);
|
|
if (c.setImmediate = function(e) {
|
|
setTimeout(e, 0)
|
|
}
|
|
,
|
|
"undefined" != typeof window && "function" == typeof window.postMessage) {
|
|
var t = "forge.setImmediate"
|
|
, r = [];
|
|
c.setImmediate = function(e) {
|
|
r.push(e),
|
|
1 === r.length && window.postMessage(t, "*")
|
|
}
|
|
,
|
|
window.addEventListener("message", e, !0)
|
|
}
|
|
if ("undefined" != typeof MutationObserver) {
|
|
var a = Date.now()
|
|
, n = !0
|
|
, i = document.createElement("div")
|
|
, r = [];
|
|
new MutationObserver(function() {
|
|
var e = r.slice();
|
|
r.length = 0,
|
|
e.forEach(function(e) {
|
|
e()
|
|
})
|
|
}
|
|
).observe(i, {
|
|
attributes: !0
|
|
});
|
|
var s = c.setImmediate;
|
|
c.setImmediate = function(e) {
|
|
Date.now() - a > 15 ? (a = Date.now(),
|
|
s(e)) : (r.push(e),
|
|
1 === r.length && i.setAttribute("a", n = !n))
|
|
}
|
|
}
|
|
c.nextTick = c.setImmediate
|
|
}(),
|
|
c.isNodejs = "undefined" != typeof process && process.versions && process.versions.node,
|
|
c.globalScope = function() {
|
|
return c.isNodejs ? t : "undefined" == typeof self ? window : self
|
|
}(),
|
|
c.isArray = Array.isArray || function(e) {
|
|
return "[object Array]" === Object.prototype.toString.call(e)
|
|
}
|
|
,
|
|
c.isArrayBuffer = function(e) {
|
|
return "undefined" != typeof ArrayBuffer && e instanceof ArrayBuffer
|
|
}
|
|
,
|
|
c.isArrayBufferView = function(e) {
|
|
return e && c.isArrayBuffer(e.buffer) && void 0 !== e.byteLength
|
|
}
|
|
,
|
|
c.ByteBuffer = n,
|
|
c.ByteStringBuffer = n;
|
|
c.ByteStringBuffer.prototype._optimizeConstructedString = function(e) {
|
|
this._constructedStringLength += e,
|
|
this._constructedStringLength > 4096 && (this.data.substr(0, 1),
|
|
this._constructedStringLength = 0)
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.length = function() {
|
|
return this.data.length - this.read
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.isEmpty = function() {
|
|
return this.length() <= 0
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putByte = function(e) {
|
|
return this.putBytes(String.fromCharCode(e))
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.fillWithByte = function(e, t) {
|
|
e = String.fromCharCode(e);
|
|
for (var r = this.data; t > 0; )
|
|
1 & t && (r += e),
|
|
(t >>>= 1) > 0 && (e += e);
|
|
return this.data = r,
|
|
this._optimizeConstructedString(t),
|
|
this
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putBytes = function(e) {
|
|
return this.data += e,
|
|
this._optimizeConstructedString(e.length),
|
|
this
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putString = function(e) {
|
|
return this.putBytes(c.encodeUtf8(e))
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putInt16 = function(e) {
|
|
return this.putBytes(String.fromCharCode(e >> 8 & 255) + String.fromCharCode(255 & e))
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putInt24 = function(e) {
|
|
return this.putBytes(String.fromCharCode(e >> 16 & 255) + String.fromCharCode(e >> 8 & 255) + String.fromCharCode(255 & e))
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putInt32 = function(e) {
|
|
return this.putBytes(String.fromCharCode(e >> 24 & 255) + String.fromCharCode(e >> 16 & 255) + String.fromCharCode(e >> 8 & 255) + String.fromCharCode(255 & e))
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putInt16Le = function(e) {
|
|
return this.putBytes(String.fromCharCode(255 & e) + String.fromCharCode(e >> 8 & 255))
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putInt24Le = function(e) {
|
|
return this.putBytes(String.fromCharCode(255 & e) + String.fromCharCode(e >> 8 & 255) + String.fromCharCode(e >> 16 & 255))
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putInt32Le = function(e) {
|
|
return this.putBytes(String.fromCharCode(255 & e) + String.fromCharCode(e >> 8 & 255) + String.fromCharCode(e >> 16 & 255) + String.fromCharCode(e >> 24 & 255))
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putInt = function(e, t) {
|
|
a(t);
|
|
var r = "";
|
|
do {
|
|
t -= 8,
|
|
r += String.fromCharCode(e >> t & 255)
|
|
} while (t > 0);
|
|
return this.putBytes(r)
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putSignedInt = function(e, t) {
|
|
return e < 0 && (e += 2 << t - 1),
|
|
this.putInt(e, t)
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.putBuffer = function(e) {
|
|
return this.putBytes(e.getBytes())
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.getByte = function() {
|
|
return this.data.charCodeAt(this.read++)
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.getInt16 = function() {
|
|
var e = this.data.charCodeAt(this.read) << 8 ^ this.data.charCodeAt(this.read + 1);
|
|
return this.read += 2,
|
|
e
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.getInt24 = function() {
|
|
var e = this.data.charCodeAt(this.read) << 16 ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2);
|
|
return this.read += 3,
|
|
e
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.getInt32 = function() {
|
|
var e = this.data.charCodeAt(this.read) << 24 ^ this.data.charCodeAt(this.read + 1) << 16 ^ this.data.charCodeAt(this.read + 2) << 8 ^ this.data.charCodeAt(this.read + 3);
|
|
return this.read += 4,
|
|
e
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.getInt16Le = function() {
|
|
var e = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8;
|
|
return this.read += 2,
|
|
e
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.getInt24Le = function() {
|
|
var e = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2) << 16;
|
|
return this.read += 3,
|
|
e
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.getInt32Le = function() {
|
|
var e = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2) << 16 ^ this.data.charCodeAt(this.read + 3) << 24;
|
|
return this.read += 4,
|
|
e
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.getInt = function(e) {
|
|
a(e);
|
|
var t = 0;
|
|
do {
|
|
t = (t << 8) + this.data.charCodeAt(this.read++),
|
|
e -= 8
|
|
} while (e > 0);
|
|
return t
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.getSignedInt = function(e) {
|
|
var t = this.getInt(e)
|
|
, r = 2 << e - 2;
|
|
return t >= r && (t -= r << 1),
|
|
t
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.getBytes = function(e) {
|
|
var t;
|
|
return e ? (e = Math.min(this.length(), e),
|
|
t = this.data.slice(this.read, this.read + e),
|
|
this.read += e) : 0 === e ? t = "" : (t = 0 === this.read ? this.data : this.data.slice(this.read),
|
|
this.clear()),
|
|
t
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.bytes = function(e) {
|
|
return void 0 === e ? this.data.slice(this.read) : this.data.slice(this.read, this.read + e)
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.at = function(e) {
|
|
return this.data.charCodeAt(this.read + e)
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.setAt = function(e, t) {
|
|
return this.data = this.data.substr(0, this.read + e) + String.fromCharCode(t) + this.data.substr(this.read + e + 1),
|
|
this
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.last = function() {
|
|
return this.data.charCodeAt(this.data.length - 1)
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.copy = function() {
|
|
var e = c.createBuffer(this.data);
|
|
return e.read = this.read,
|
|
e
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.compact = function() {
|
|
return this.read > 0 && (this.data = this.data.slice(this.read),
|
|
this.read = 0),
|
|
this
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.clear = function() {
|
|
return this.data = "",
|
|
this.read = 0,
|
|
this
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.truncate = function(e) {
|
|
var t = Math.max(0, this.length() - e);
|
|
return this.data = this.data.substr(this.read, t),
|
|
this.read = 0,
|
|
this
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.toHex = function() {
|
|
for (var e = "", t = this.read; t < this.data.length; ++t) {
|
|
var r = this.data.charCodeAt(t);
|
|
r < 16 && (e += "0"),
|
|
e += r.toString(16)
|
|
}
|
|
return e
|
|
}
|
|
,
|
|
c.ByteStringBuffer.prototype.toString = function() {
|
|
return c.decodeUtf8(this.bytes())
|
|
}
|
|
,
|
|
c.DataBuffer = i,
|
|
c.DataBuffer.prototype.length = function() {
|
|
return this.write - this.read
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.isEmpty = function() {
|
|
return this.length() <= 0
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.accommodate = function(e, t) {
|
|
if (this.length() >= e)
|
|
return this;
|
|
t = Math.max(t || this.growSize, e);
|
|
var r = new Uint8Array(this.data.buffer,this.data.byteOffset,this.data.byteLength)
|
|
, a = new Uint8Array(this.length() + t);
|
|
return a.set(r),
|
|
this.data = new DataView(a.buffer),
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putByte = function(e) {
|
|
return this.accommodate(1),
|
|
this.data.setUint8(this.write++, e),
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.fillWithByte = function(e, t) {
|
|
this.accommodate(t);
|
|
for (var r = 0; r < t; ++r)
|
|
this.data.setUint8(e);
|
|
return this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putBytes = function(e, t) {
|
|
if (c.isArrayBufferView(e)) {
|
|
var r = new Uint8Array(e.buffer,e.byteOffset,e.byteLength)
|
|
, a = r.byteLength - r.byteOffset;
|
|
this.accommodate(a);
|
|
var n = new Uint8Array(this.data.buffer,this.write);
|
|
return n.set(r),
|
|
this.write += a,
|
|
this
|
|
}
|
|
if (c.isArrayBuffer(e)) {
|
|
var r = new Uint8Array(e);
|
|
this.accommodate(r.byteLength);
|
|
var n = new Uint8Array(this.data.buffer);
|
|
return n.set(r, this.write),
|
|
this.write += r.byteLength,
|
|
this
|
|
}
|
|
if (e instanceof c.DataBuffer || "object" == typeof e && "number" == typeof e.read && "number" == typeof e.write && c.isArrayBufferView(e.data)) {
|
|
var r = new Uint8Array(e.data.byteLength,e.read,e.length());
|
|
this.accommodate(r.byteLength);
|
|
var n = new Uint8Array(e.data.byteLength,this.write);
|
|
return n.set(r),
|
|
this.write += r.byteLength,
|
|
this
|
|
}
|
|
if (e instanceof c.ByteStringBuffer && (e = e.data,
|
|
t = "binary"),
|
|
t = t || "binary",
|
|
"string" == typeof e) {
|
|
var i;
|
|
if ("hex" === t)
|
|
return this.accommodate(Math.ceil(e.length / 2)),
|
|
i = new Uint8Array(this.data.buffer,this.write),
|
|
this.write += c.binary.hex.decode(e, i, this.write),
|
|
this;
|
|
if ("base64" === t)
|
|
return this.accommodate(3 * Math.ceil(e.length / 4)),
|
|
i = new Uint8Array(this.data.buffer,this.write),
|
|
this.write += c.binary.base64.decode(e, i, this.write),
|
|
this;
|
|
if ("utf8" === t && (e = c.encodeUtf8(e),
|
|
t = "binary"),
|
|
"binary" === t || "raw" === t)
|
|
return this.accommodate(e.length),
|
|
i = new Uint8Array(this.data.buffer,this.write),
|
|
this.write += c.binary.raw.decode(i),
|
|
this;
|
|
if ("utf16" === t)
|
|
return this.accommodate(2 * e.length),
|
|
i = new Uint16Array(this.data.buffer,this.write),
|
|
this.write += c.text.utf16.encode(i),
|
|
this;
|
|
throw new Error("Invalid encoding: " + t)
|
|
}
|
|
throw Error("Invalid parameter: " + e)
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putBuffer = function(e) {
|
|
return this.putBytes(e),
|
|
e.clear(),
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putString = function(e) {
|
|
return this.putBytes(e, "utf16")
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putInt16 = function(e) {
|
|
return this.accommodate(2),
|
|
this.data.setInt16(this.write, e),
|
|
this.write += 2,
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putInt24 = function(e) {
|
|
return this.accommodate(3),
|
|
this.data.setInt16(this.write, e >> 8 & 65535),
|
|
this.data.setInt8(this.write, e >> 16 & 255),
|
|
this.write += 3,
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putInt32 = function(e) {
|
|
return this.accommodate(4),
|
|
this.data.setInt32(this.write, e),
|
|
this.write += 4,
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putInt16Le = function(e) {
|
|
return this.accommodate(2),
|
|
this.data.setInt16(this.write, e, !0),
|
|
this.write += 2,
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putInt24Le = function(e) {
|
|
return this.accommodate(3),
|
|
this.data.setInt8(this.write, e >> 16 & 255),
|
|
this.data.setInt16(this.write, e >> 8 & 65535, !0),
|
|
this.write += 3,
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putInt32Le = function(e) {
|
|
return this.accommodate(4),
|
|
this.data.setInt32(this.write, e, !0),
|
|
this.write += 4,
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putInt = function(e, t) {
|
|
a(t),
|
|
this.accommodate(t / 8);
|
|
do {
|
|
t -= 8,
|
|
this.data.setInt8(this.write++, e >> t & 255)
|
|
} while (t > 0);
|
|
return this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.putSignedInt = function(e, t) {
|
|
return a(t),
|
|
this.accommodate(t / 8),
|
|
e < 0 && (e += 2 << t - 1),
|
|
this.putInt(e, t)
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.getByte = function() {
|
|
return this.data.getInt8(this.read++)
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.getInt16 = function() {
|
|
var e = this.data.getInt16(this.read);
|
|
return this.read += 2,
|
|
e
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.getInt24 = function() {
|
|
var e = this.data.getInt16(this.read) << 8 ^ this.data.getInt8(this.read + 2);
|
|
return this.read += 3,
|
|
e
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.getInt32 = function() {
|
|
var e = this.data.getInt32(this.read);
|
|
return this.read += 4,
|
|
e
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.getInt16Le = function() {
|
|
var e = this.data.getInt16(this.read, !0);
|
|
return this.read += 2,
|
|
e
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.getInt24Le = function() {
|
|
var e = this.data.getInt8(this.read) ^ this.data.getInt16(this.read + 1, !0) << 8;
|
|
return this.read += 3,
|
|
e
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.getInt32Le = function() {
|
|
var e = this.data.getInt32(this.read, !0);
|
|
return this.read += 4,
|
|
e
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.getInt = function(e) {
|
|
a(e);
|
|
var t = 0;
|
|
do {
|
|
t = (t << 8) + this.data.getInt8(this.read++),
|
|
e -= 8
|
|
} while (e > 0);
|
|
return t
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.getSignedInt = function(e) {
|
|
var t = this.getInt(e)
|
|
, r = 2 << e - 2;
|
|
return t >= r && (t -= r << 1),
|
|
t
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.getBytes = function(e) {
|
|
var t;
|
|
return e ? (e = Math.min(this.length(), e),
|
|
t = this.data.slice(this.read, this.read + e),
|
|
this.read += e) : 0 === e ? t = "" : (t = 0 === this.read ? this.data : this.data.slice(this.read),
|
|
this.clear()),
|
|
t
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.bytes = function(e) {
|
|
return void 0 === e ? this.data.slice(this.read) : this.data.slice(this.read, this.read + e)
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.at = function(e) {
|
|
return this.data.getUint8(this.read + e)
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.setAt = function(e, t) {
|
|
return this.data.setUint8(e, t),
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.last = function() {
|
|
return this.data.getUint8(this.write - 1)
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.copy = function() {
|
|
return new c.DataBuffer(this)
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.compact = function() {
|
|
if (this.read > 0) {
|
|
var e = new Uint8Array(this.data.buffer,this.read)
|
|
, t = new Uint8Array(e.byteLength);
|
|
t.set(e),
|
|
this.data = new DataView(t),
|
|
this.write -= this.read,
|
|
this.read = 0
|
|
}
|
|
return this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.clear = function() {
|
|
return this.data = new DataView(new ArrayBuffer(0)),
|
|
this.read = this.write = 0,
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.truncate = function(e) {
|
|
return this.write = Math.max(0, this.length() - e),
|
|
this.read = Math.min(this.read, this.write),
|
|
this
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.toHex = function() {
|
|
for (var e = "", t = this.read; t < this.data.byteLength; ++t) {
|
|
var r = this.data.getUint8(t);
|
|
r < 16 && (e += "0"),
|
|
e += r.toString(16)
|
|
}
|
|
return e
|
|
}
|
|
,
|
|
c.DataBuffer.prototype.toString = function(e) {
|
|
var t = new Uint8Array(this.data,this.read,this.length());
|
|
if ("binary" === (e = e || "utf8") || "raw" === e)
|
|
return c.binary.raw.encode(t);
|
|
if ("hex" === e)
|
|
return c.binary.hex.encode(t);
|
|
if ("base64" === e)
|
|
return c.binary.base64.encode(t);
|
|
if ("utf8" === e)
|
|
return c.text.utf8.decode(t);
|
|
if ("utf16" === e)
|
|
return c.text.utf16.decode(t);
|
|
throw new Error("Invalid encoding: " + e)
|
|
}
|
|
,
|
|
c.createBuffer = function(e, t) {
|
|
return t = t || "raw",
|
|
void 0 !== e && "utf8" === t && (e = c.encodeUtf8(e)),
|
|
new c.ByteBuffer(e)
|
|
}
|
|
,
|
|
c.fillString = function(e, t) {
|
|
for (var r = ""; t > 0; )
|
|
1 & t && (r += e),
|
|
(t >>>= 1) > 0 && (e += e);
|
|
return r
|
|
}
|
|
,
|
|
c.xorBytes = function(e, t, r) {
|
|
for (var a = "", n = "", i = "", s = 0, o = 0; r > 0; --r,
|
|
++s)
|
|
n = e.charCodeAt(s) ^ t.charCodeAt(s),
|
|
o >= 10 && (a += i,
|
|
i = "",
|
|
o = 0),
|
|
i += String.fromCharCode(n),
|
|
++o;
|
|
return a += i
|
|
}
|
|
,
|
|
c.hexToBytes = function(e) {
|
|
var t = ""
|
|
, r = 0;
|
|
for (!0 & e.length && (r = 1,
|
|
t += String.fromCharCode(parseInt(e[0], 16))); r < e.length; r += 2)
|
|
t += String.fromCharCode(parseInt(e.substr(r, 2), 16));
|
|
return t
|
|
}
|
|
,
|
|
c.bytesToHex = function(e) {
|
|
return c.createBuffer(e).toHex()
|
|
}
|
|
,
|
|
c.int32ToBytes = function(e) {
|
|
return String.fromCharCode(e >> 24 & 255) + String.fromCharCode(e >> 16 & 255) + String.fromCharCode(e >> 8 & 255) + String.fromCharCode(255 & e)
|
|
}
|
|
;
|
|
var u = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
|
, l = [62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 64, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]
|
|
, p = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
c.encode64 = function(e, t) {
|
|
for (var r, a, n, i = "", s = "", o = 0; o < e.length; )
|
|
r = e.charCodeAt(o++),
|
|
a = e.charCodeAt(o++),
|
|
n = e.charCodeAt(o++),
|
|
i += u.charAt(r >> 2),
|
|
i += u.charAt((3 & r) << 4 | a >> 4),
|
|
isNaN(a) ? i += "==" : (i += u.charAt((15 & a) << 2 | n >> 6),
|
|
i += isNaN(n) ? "=" : u.charAt(63 & n)),
|
|
t && i.length > t && (s += i.substr(0, t) + "\r\n",
|
|
i = i.substr(t));
|
|
return s += i
|
|
}
|
|
,
|
|
c.decode64 = function(e) {
|
|
e = e.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
|
for (var t, r, a, n, i = "", s = 0; s < e.length; )
|
|
t = l[e.charCodeAt(s++) - 43],
|
|
r = l[e.charCodeAt(s++) - 43],
|
|
a = l[e.charCodeAt(s++) - 43],
|
|
n = l[e.charCodeAt(s++) - 43],
|
|
i += String.fromCharCode(t << 2 | r >> 4),
|
|
64 !== a && (i += String.fromCharCode((15 & r) << 4 | a >> 2),
|
|
64 !== n && (i += String.fromCharCode((3 & a) << 6 | n)));
|
|
return i
|
|
}
|
|
,
|
|
c.encodeUtf8 = function(e) {
|
|
return unescape(encodeURIComponent(e))
|
|
}
|
|
,
|
|
c.decodeUtf8 = function(e) {
|
|
return decodeURIComponent(escape(e))
|
|
}
|
|
,
|
|
c.binary = {
|
|
raw: {},
|
|
hex: {},
|
|
base64: {},
|
|
base58: {},
|
|
baseN: {
|
|
encode: o.encode,
|
|
decode: o.decode
|
|
}
|
|
},
|
|
c.binary.raw.encode = function(e) {
|
|
return String.fromCharCode.apply(null, e)
|
|
}
|
|
,
|
|
c.binary.raw.decode = function(e, t, r) {
|
|
var a = t;
|
|
a || (a = new Uint8Array(e.length)),
|
|
r = r || 0;
|
|
for (var n = r, i = 0; i < e.length; ++i)
|
|
a[n++] = e.charCodeAt(i);
|
|
return t ? n - r : a
|
|
}
|
|
,
|
|
c.binary.hex.encode = c.bytesToHex,
|
|
c.binary.hex.decode = function(e, t, r) {
|
|
var a = t;
|
|
a || (a = new Uint8Array(Math.ceil(e.length / 2))),
|
|
r = r || 0;
|
|
var n = 0
|
|
, i = r;
|
|
for (1 & e.length && (n = 1,
|
|
a[i++] = parseInt(e[0], 16)); n < e.length; n += 2)
|
|
a[i++] = parseInt(e.substr(n, 2), 16);
|
|
return t ? i - r : a
|
|
}
|
|
,
|
|
c.binary.base64.encode = function(e, t) {
|
|
for (var r, a, n, i = "", s = "", o = 0; o < e.byteLength; )
|
|
r = e[o++],
|
|
a = e[o++],
|
|
n = e[o++],
|
|
i += u.charAt(r >> 2),
|
|
i += u.charAt((3 & r) << 4 | a >> 4),
|
|
isNaN(a) ? i += "==" : (i += u.charAt((15 & a) << 2 | n >> 6),
|
|
i += isNaN(n) ? "=" : u.charAt(63 & n)),
|
|
t && i.length > t && (s += i.substr(0, t) + "\r\n",
|
|
i = i.substr(t));
|
|
return s += i
|
|
}
|
|
,
|
|
c.binary.base64.decode = function(e, t, r) {
|
|
var a = t;
|
|
a || (a = new Uint8Array(3 * Math.ceil(e.length / 4))),
|
|
e = e.replace(/[^A-Za-z0-9\+\/\=]/g, ""),
|
|
r = r || 0;
|
|
for (var n, i, s, o, c = 0, u = r; c < e.length; )
|
|
n = l[e.charCodeAt(c++) - 43],
|
|
i = l[e.charCodeAt(c++) - 43],
|
|
s = l[e.charCodeAt(c++) - 43],
|
|
o = l[e.charCodeAt(c++) - 43],
|
|
a[u++] = n << 2 | i >> 4,
|
|
64 !== s && (a[u++] = (15 & i) << 4 | s >> 2,
|
|
64 !== o && (a[u++] = (3 & s) << 6 | o));
|
|
return t ? u - r : a.subarray(0, u)
|
|
}
|
|
,
|
|
c.binary.base58.encode = function(e, t) {
|
|
return c.binary.baseN.encode(e, p, t)
|
|
}
|
|
,
|
|
c.binary.base58.decode = function(e, t) {
|
|
return c.binary.baseN.decode(e, p, t)
|
|
}
|
|
,
|
|
c.text = {
|
|
utf8: {},
|
|
utf16: {}
|
|
},
|
|
c.text.utf8.encode = function(e, t, r) {
|
|
e = c.encodeUtf8(e);
|
|
var a = t;
|
|
a || (a = new Uint8Array(e.length)),
|
|
r = r || 0;
|
|
for (var n = r, i = 0; i < e.length; ++i)
|
|
a[n++] = e.charCodeAt(i);
|
|
return t ? n - r : a
|
|
}
|
|
,
|
|
c.text.utf8.decode = function(e) {
|
|
return c.decodeUtf8(String.fromCharCode.apply(null, e))
|
|
}
|
|
,
|
|
c.text.utf16.encode = function(e, t, r) {
|
|
var a = t;
|
|
a || (a = new Uint8Array(2 * e.length));
|
|
var n = new Uint16Array(a.buffer);
|
|
r = r || 0;
|
|
for (var i = r, s = r, o = 0; o < e.length; ++o)
|
|
n[s++] = e.charCodeAt(o),
|
|
i += 2;
|
|
return t ? i - r : a
|
|
}
|
|
,
|
|
c.text.utf16.decode = function(e) {
|
|
return String.fromCharCode.apply(null, new Uint16Array(e.buffer))
|
|
}
|
|
,
|
|
c.deflate = function(e, t, r) {
|
|
if (t = c.decode64(e.deflate(c.encode64(t)).rval),
|
|
r) {
|
|
var a = 2;
|
|
32 & t.charCodeAt(1) && (a = 6),
|
|
t = t.substring(a, t.length - 4)
|
|
}
|
|
return t
|
|
}
|
|
,
|
|
c.inflate = function(e, t, r) {
|
|
var a = e.inflate(c.encode64(t)).rval;
|
|
return null === a ? null : c.decode64(a)
|
|
}
|
|
;
|
|
var f = function(e, t, r) {
|
|
if (!e)
|
|
throw new Error("WebStorage not available.");
|
|
var a;
|
|
if (null === r ? a = e.removeItem(t) : (r = c.encode64(JSON.stringify(r)),
|
|
a = e.setItem(t, r)),
|
|
void 0 !== a && !0 !== a.rval) {
|
|
var n = new Error(a.error.message);
|
|
throw n.id = a.error.id,
|
|
n.name = a.error.name,
|
|
n
|
|
}
|
|
}
|
|
, h = function(e, t) {
|
|
if (!e)
|
|
throw new Error("WebStorage not available.");
|
|
var r = e.getItem(t);
|
|
if (e.init)
|
|
if (null === r.rval) {
|
|
if (r.error) {
|
|
var a = new Error(r.error.message);
|
|
throw a.id = r.error.id,
|
|
a.name = r.error.name,
|
|
a
|
|
}
|
|
r = null
|
|
} else
|
|
r = r.rval;
|
|
return null !== r && (r = JSON.parse(c.decode64(r))),
|
|
r
|
|
}
|
|
, d = function(e, t, r, a) {
|
|
var n = h(e, t);
|
|
null === n && (n = {}),
|
|
n[r] = a,
|
|
f(e, t, n)
|
|
}
|
|
, y = function(e, t, r) {
|
|
var a = h(e, t);
|
|
return null !== a && (a = r in a ? a[r] : null),
|
|
a
|
|
}
|
|
, g = function(e, t, r) {
|
|
var a = h(e, t);
|
|
if (null !== a && r in a) {
|
|
delete a[r];
|
|
var n = !0;
|
|
for (var i in a) {
|
|
n = !1;
|
|
break
|
|
}
|
|
n && (a = null),
|
|
f(e, t, a)
|
|
}
|
|
}
|
|
, v = function(e, t) {
|
|
f(e, t, null)
|
|
}
|
|
, m = function(e, t, r) {
|
|
var a = null;
|
|
void 0 === r && (r = ["web", "flash"]);
|
|
var n, i = !1, s = null;
|
|
for (var o in r) {
|
|
n = r[o];
|
|
try {
|
|
if ("flash" === n || "both" === n) {
|
|
if (null === t[0])
|
|
throw new Error("Flash local storage not available.");
|
|
a = e.apply(this, t),
|
|
i = "flash" === n
|
|
}
|
|
"web" !== n && "both" !== n || (t[0] = localStorage,
|
|
a = e.apply(this, t),
|
|
i = !0)
|
|
} catch (e) {
|
|
s = e
|
|
}
|
|
if (i)
|
|
break
|
|
}
|
|
if (!i)
|
|
throw s;
|
|
return a
|
|
};
|
|
c.setItem = function(e, t, r, a, n) {
|
|
m(d, arguments, n)
|
|
}
|
|
,
|
|
c.getItem = function(e, t, r, a) {
|
|
return m(y, arguments, a)
|
|
}
|
|
,
|
|
c.removeItem = function(e, t, r, a) {
|
|
m(g, arguments, a)
|
|
}
|
|
,
|
|
c.clearItems = function(e, t, r) {
|
|
m(v, arguments, r)
|
|
}
|
|
,
|
|
c.parseUrl = function(e) {
|
|
var t = /^(https?):\/\/([^:&^\/]*):?(\d*)(.*)$/g;
|
|
t.lastIndex = 0;
|
|
var r = t.exec(e)
|
|
, a = null === r ? null : {
|
|
full: e,
|
|
scheme: r[1],
|
|
host: r[2],
|
|
port: r[3],
|
|
path: r[4]
|
|
};
|
|
console.log("--fx--host--", a);
|
|
return a && (a.fullHost = a.host,
|
|
a.port ? 80 !== a.port && "http" === a.scheme ? a.fullHost += ":" + a.port : 443 !== a.port && "https" === a.scheme && (a.fullHost += ":" + a.port) : "http" === a.scheme ? a.port = 80 : "https" === a.scheme && (a.port = 443),
|
|
a.full = a.scheme + "://" + a.fullHost),
|
|
a
|
|
}
|
|
;
|
|
var C = null;
|
|
c.getQueryVariables = function(e) {
|
|
var t, r = function(e) {
|
|
for (var t = {}, r = e.split("&"), a = 0; a < r.length; a++) {
|
|
var n, i, s = r[a].indexOf("=");
|
|
s > 0 ? (n = r[a].substring(0, s),
|
|
i = r[a].substring(s + 1)) : (n = r[a],
|
|
i = null),
|
|
n in t || (t[n] = []),
|
|
n in Object.prototype || null === i || t[n].push(unescape(i))
|
|
}
|
|
return t
|
|
};
|
|
return void 0 === e ? (null === C && (C = "undefined" != typeof window && window.location && window.location.search ? r(window.location.search.substring(1)) : {}),
|
|
t = C) : t = r(e),
|
|
t
|
|
}
|
|
,
|
|
c.parseFragment = function(e) {
|
|
var t = e
|
|
, r = ""
|
|
, a = e.indexOf("?");
|
|
a > 0 && (t = e.substring(0, a),
|
|
r = e.substring(a + 1));
|
|
var n = t.split("/");
|
|
return n.length > 0 && "" === n[0] && n.shift(),
|
|
{
|
|
pathString: t,
|
|
queryString: r,
|
|
path: n,
|
|
query: "" === r ? {} : c.getQueryVariables(r)
|
|
}
|
|
}
|
|
,
|
|
c.makeRequest = function(e) {
|
|
var t = c.parseFragment(e)
|
|
, r = {
|
|
path: t.pathString,
|
|
query: t.queryString,
|
|
getPath: function(e) {
|
|
return void 0 === e ? t.path : t.path[e]
|
|
},
|
|
getQuery: function(e, r) {
|
|
var a;
|
|
return void 0 === e ? a = t.query : (a = t.query[e]) && void 0 !== r && (a = a[r]),
|
|
a
|
|
},
|
|
getQueryLast: function(e, t) {
|
|
var a = r.getQuery(e);
|
|
return a ? a[a.length - 1] : t
|
|
}
|
|
};
|
|
return r
|
|
}
|
|
,
|
|
c.makeLink = function(e, t, r) {
|
|
e = jQuery.isArray(e) ? e.join("/") : e;
|
|
var a = jQuery.param(t || {});
|
|
return r = r || "",
|
|
e + (a.length > 0 ? "?" + a : "") + (r.length > 0 ? "#" + r : "")
|
|
}
|
|
,
|
|
c.setPath = function(e, t, r) {
|
|
if ("object" == typeof e && null !== e)
|
|
for (var a = 0, n = t.length; a < n; ) {
|
|
var i = t[a++];
|
|
if (a == n)
|
|
e[i] = r;
|
|
else {
|
|
var s = i in e;
|
|
(!s || s && "object" != typeof e[i] || s && null === e[i]) && (e[i] = {}),
|
|
e = e[i]
|
|
}
|
|
}
|
|
}
|
|
,
|
|
c.getPath = function(e, t, r) {
|
|
for (var a = 0, n = t.length, i = !0; i && a < n && "object" == typeof e && null !== e; ) {
|
|
var s = t[a++];
|
|
i = s in e,
|
|
i && (e = e[s])
|
|
}
|
|
return i ? e : r
|
|
}
|
|
,
|
|
c.deletePath = function(e, t) {
|
|
if ("object" == typeof e && null !== e)
|
|
for (var r = 0, a = t.length; r < a; ) {
|
|
var n = t[r++];
|
|
if (r == a)
|
|
delete e[n];
|
|
else {
|
|
if (!(n in e) || "object" != typeof e[n] || null === e[n])
|
|
break;
|
|
e = e[n]
|
|
}
|
|
}
|
|
}
|
|
,
|
|
c.isEmpty = function(e) {
|
|
for (var t in e)
|
|
if (e.hasOwnProperty(t))
|
|
return !1;
|
|
return !0
|
|
}
|
|
,
|
|
c.format = function(e) {
|
|
for (var t, r, a = /%./g, n = 0, i = [], s = 0; t = a.exec(e); ) {
|
|
r = e.substring(s, a.lastIndex - 2),
|
|
r.length > 0 && i.push(r),
|
|
s = a.lastIndex;
|
|
var o = t[0][1];
|
|
switch (o) {
|
|
case "s":
|
|
case "o":
|
|
n < arguments.length ? i.push(arguments[1 + n++]) : i.push("<?>");
|
|
break;
|
|
case "%":
|
|
i.push("%");
|
|
break;
|
|
default:
|
|
i.push("<%" + o + "?>")
|
|
}
|
|
}
|
|
return i.push(e.substring(s)),
|
|
i.join("")
|
|
}
|
|
,
|
|
c.formatNumber = function(e, t, r, a) {
|
|
var n = e
|
|
, i = isNaN(t = Math.abs(t)) ? 2 : t
|
|
, s = void 0 === r ? "," : r
|
|
, o = void 0 === a ? "." : a
|
|
, c = n < 0 ? "-" : ""
|
|
, u = parseInt(n = Math.abs(+n || 0).toFixed(i), 10) + ""
|
|
, l = u.length > 3 ? u.length % 3 : 0;
|
|
return c + (l ? u.substr(0, l) + o : "") + u.substr(l).replace(/(\d{3})(?=\d)/g, "$1" + o) + (i ? s + Math.abs(n - u).toFixed(i).slice(2) : "")
|
|
}
|
|
,
|
|
c.formatSize = function(e) {
|
|
return e = e >= 1073741824 ? c.formatNumber(e / 1073741824, 2, ".", "") + " GiB" : e >= 1048576 ? c.formatNumber(e / 1048576, 2, ".", "") + " MiB" : e >= 1024 ? c.formatNumber(e / 1024, 0) + " KiB" : c.formatNumber(e, 0) + " bytes"
|
|
}
|
|
,
|
|
c.bytesFromIP = function(e) {
|
|
return -1 !== e.indexOf(".") ? c.bytesFromIPv4(e) : -1 !== e.indexOf(":") ? c.bytesFromIPv6(e) : null
|
|
}
|
|
,
|
|
c.bytesFromIPv4 = function(e) {
|
|
if (e = e.split("."),
|
|
4 !== e.length)
|
|
return null;
|
|
for (var t = c.createBuffer(), r = 0; r < e.length; ++r) {
|
|
var a = parseInt(e[r], 10);
|
|
if (isNaN(a))
|
|
return null;
|
|
t.putByte(a)
|
|
}
|
|
return t.getBytes()
|
|
}
|
|
,
|
|
c.bytesFromIPv6 = function(e) {
|
|
var t = 0;
|
|
e = e.split(":").filter(function(e) {
|
|
return 0 === e.length && ++t,
|
|
!0
|
|
});
|
|
for (var r = 2 * (8 - e.length + t), a = c.createBuffer(), n = 0; n < 8; ++n)
|
|
if (e[n] && 0 !== e[n].length) {
|
|
var i = c.hexToBytes(e[n]);
|
|
i.length < 2 && a.putByte(0),
|
|
a.putBytes(i)
|
|
} else
|
|
a.fillWithByte(0, r),
|
|
r = 0;
|
|
return a.getBytes()
|
|
}
|
|
,
|
|
c.bytesToIP = function(e) {
|
|
return 4 === e.length ? c.bytesToIPv4(e) : 16 === e.length ? c.bytesToIPv6(e) : null
|
|
}
|
|
,
|
|
c.bytesToIPv4 = function(e) {
|
|
if (4 !== e.length)
|
|
return null;
|
|
for (var t = [], r = 0; r < e.length; ++r)
|
|
t.push(e.charCodeAt(r));
|
|
return t.join(".")
|
|
}
|
|
,
|
|
c.bytesToIPv6 = function(e) {
|
|
if (16 !== e.length)
|
|
return null;
|
|
for (var t = [], r = [], a = 0, n = 0; n < e.length; n += 2) {
|
|
for (var i = c.bytesToHex(e[n] + e[n + 1]); "0" === i[0] && "0" !== i; )
|
|
i = i.substr(1);
|
|
if ("0" === i) {
|
|
var s = r[r.length - 1]
|
|
, o = t.length;
|
|
s && o === s.end + 1 ? (s.end = o,
|
|
s.end - s.start > r[a].end - r[a].start && (a = r.length - 1)) : r.push({
|
|
start: o,
|
|
end: o
|
|
})
|
|
}
|
|
t.push(i)
|
|
}
|
|
if (r.length > 0) {
|
|
var u = r[a];
|
|
u.end - u.start > 0 && (t.splice(u.start, u.end - u.start + 1, ""),
|
|
0 === u.start && t.unshift(""),
|
|
7 === u.end && t.push(""))
|
|
}
|
|
return t.join(":")
|
|
}
|
|
,
|
|
c.estimateCores = function(e, t) {
|
|
function r(e, s, o) {
|
|
if (0 === s) {
|
|
var u = Math.floor(e.reduce(function(e, t) {
|
|
return e + t
|
|
}, 0) / e.length);
|
|
return c.cores = Math.max(1, u),
|
|
URL.revokeObjectURL(i),
|
|
t(null, c.cores)
|
|
}
|
|
a(o, function(t, a) {
|
|
e.push(n(o, a)),
|
|
r(e, s - 1, o)
|
|
})
|
|
}
|
|
function a(e, t) {
|
|
for (var r = [], a = [], n = 0; n < e; ++n) {
|
|
var s = new Worker(i);
|
|
s.addEventListener("message", function(n) {
|
|
if (a.push(n.data),
|
|
a.length === e) {
|
|
for (var i = 0; i < e; ++i)
|
|
r[i].terminate();
|
|
t(null, a)
|
|
}
|
|
}),
|
|
r.push(s)
|
|
}
|
|
for (var n = 0; n < e; ++n)
|
|
r[n].postMessage(n)
|
|
}
|
|
function n(e, t) {
|
|
for (var r = [], a = 0; a < e; ++a)
|
|
for (var n = t[a], i = r[a] = [], s = 0; s < e; ++s)
|
|
if (a !== s) {
|
|
var o = t[s];
|
|
(n.st > o.st && n.st < o.et || o.st > n.st && o.st < n.et) && i.push(s)
|
|
}
|
|
return r.reduce(function(e, t) {
|
|
return Math.max(e, t.length)
|
|
}, 0)
|
|
}
|
|
if ("function" == typeof e && (t = e,
|
|
e = {}),
|
|
e = e || {},
|
|
"cores"in c && !e.update)
|
|
return t(null, c.cores);
|
|
if ("undefined" != typeof navigator && "hardwareConcurrency"in navigator && navigator.hardwareConcurrency > 0)
|
|
return c.cores = navigator.hardwareConcurrency,
|
|
t(null, c.cores);
|
|
if ("undefined" == typeof Worker)
|
|
return c.cores = 1,
|
|
t(null, c.cores);
|
|
if ("undefined" == typeof Blob)
|
|
return c.cores = 2,
|
|
t(null, c.cores);
|
|
var i = URL.createObjectURL(new Blob(["(", function() {
|
|
self.addEventListener("message", function(e) {
|
|
for (var t = Date.now(), r = t + 4; Date.now() < r; )
|
|
;
|
|
self.postMessage({
|
|
st: t,
|
|
et: r
|
|
})
|
|
})
|
|
}
|
|
.toString(), ")()"],{
|
|
type: "application/javascript"
|
|
}));
|
|
r([], 5, 16)
|
|
}
|
|
}
|
|
).call(t, r(36))
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(5),
|
|
r(23),
|
|
r(24),
|
|
r(1),
|
|
function() {
|
|
if (a.random && a.random.getBytes)
|
|
return void (e.exports = a.random);
|
|
!function(t) {
|
|
function r() {
|
|
var e = a.prng.create(n);
|
|
return e.getBytes = function(t, r) {
|
|
return e.generate(t, r)
|
|
}
|
|
,
|
|
e.getBytesSync = function(t) {
|
|
return e.generate(t)
|
|
}
|
|
,
|
|
e
|
|
}
|
|
var n = {}
|
|
, i = new Array(4)
|
|
, s = a.util.createBuffer();
|
|
n.formatKey = function(e) {
|
|
var t = a.util.createBuffer(e);
|
|
return e = new Array(4),
|
|
e[0] = t.getInt32(),
|
|
e[1] = t.getInt32(),
|
|
e[2] = t.getInt32(),
|
|
e[3] = t.getInt32(),
|
|
a.aes._expandKey(e, !1)
|
|
}
|
|
,
|
|
n.formatSeed = function(e) {
|
|
var t = a.util.createBuffer(e);
|
|
return e = new Array(4),
|
|
e[0] = t.getInt32(),
|
|
e[1] = t.getInt32(),
|
|
e[2] = t.getInt32(),
|
|
e[3] = t.getInt32(),
|
|
e
|
|
}
|
|
,
|
|
n.cipher = function(e, t) {
|
|
return a.aes._updateBlock(e, t, i, !1),
|
|
s.putInt32(i[0]),
|
|
s.putInt32(i[1]),
|
|
s.putInt32(i[2]),
|
|
s.putInt32(i[3]),
|
|
s.getBytes()
|
|
}
|
|
,
|
|
n.increment = function(e) {
|
|
return ++e[3],
|
|
e
|
|
}
|
|
,
|
|
n.md = a.md.sha256;
|
|
var o = r()
|
|
, c = null
|
|
, u = a.util.globalScope
|
|
, l = u.crypto || u.msCrypto;
|
|
if (l && l.getRandomValues && (c = function(e) {
|
|
return l.getRandomValues(e)
|
|
}
|
|
),
|
|
a.options.usePureJavaScript || !a.util.isNodejs && !c) {
|
|
if ("undefined" == typeof window || window.document,
|
|
o.collectInt(+new Date, 32),
|
|
"undefined" != typeof navigator) {
|
|
var p = "";
|
|
for (var f in navigator)
|
|
try {
|
|
"string" == typeof navigator[f] && (p += navigator[f])
|
|
} catch (e) {}
|
|
o.collect(p),
|
|
p = null
|
|
}
|
|
t && (t().mousemove(function(e) {
|
|
o.collectInt(e.clientX, 16),
|
|
o.collectInt(e.clientY, 16)
|
|
}),
|
|
t().keypress(function(e) {
|
|
o.collectInt(e.charCode, 8)
|
|
}))
|
|
}
|
|
if (a.random)
|
|
for (var f in o)
|
|
a.random[f] = o[f];
|
|
else
|
|
a.random = o;
|
|
a.random.createInstance = r,
|
|
e.exports = a.random
|
|
}("undefined" != typeof jQuery ? jQuery : null)
|
|
}()
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t, r) {
|
|
if (r > t) {
|
|
var a = new Error("Too few bytes to parse DER.");
|
|
throw a.available = e.length(),
|
|
a.remaining = t,
|
|
a.requested = r,
|
|
a
|
|
}
|
|
}
|
|
function n(e, t, r, i) {
|
|
var c;
|
|
a(e, t, 2);
|
|
var u = e.getByte();
|
|
t--;
|
|
var l = 192 & u
|
|
, p = 31 & u;
|
|
c = e.length();
|
|
var f = o(e, t);
|
|
if (t -= c - e.length(),
|
|
void 0 !== f && f > t) {
|
|
if (i.strict) {
|
|
var h = new Error("Too few bytes to read ASN.1 value.");
|
|
throw h.available = e.length(),
|
|
h.remaining = t,
|
|
h.requested = f,
|
|
h
|
|
}
|
|
f = t
|
|
}
|
|
var d, y, g = 32 == (32 & u);
|
|
if (g)
|
|
if (d = [],
|
|
void 0 === f)
|
|
for (; ; ) {
|
|
if (a(e, t, 2),
|
|
e.bytes(2) === String.fromCharCode(0, 0)) {
|
|
e.getBytes(2),
|
|
t -= 2;
|
|
break
|
|
}
|
|
c = e.length(),
|
|
d.push(n(e, t, r + 1, i)),
|
|
t -= c - e.length()
|
|
}
|
|
else
|
|
for (; f > 0; )
|
|
c = e.length(),
|
|
d.push(n(e, f, r + 1, i)),
|
|
t -= c - e.length(),
|
|
f -= c - e.length();
|
|
if (void 0 === d && l === s.Class.UNIVERSAL && p === s.Type.BITSTRING && (y = e.bytes(f)),
|
|
void 0 === d && i.decodeBitStrings && l === s.Class.UNIVERSAL && p === s.Type.BITSTRING && f > 1) {
|
|
var v = e.read
|
|
, m = t
|
|
, C = 0;
|
|
if (p === s.Type.BITSTRING && (a(e, t, 1),
|
|
C = e.getByte(),
|
|
t--),
|
|
0 === C)
|
|
try {
|
|
c = e.length();
|
|
var E = {
|
|
verbose: i.verbose,
|
|
strict: !0,
|
|
decodeBitStrings: !0
|
|
}
|
|
, S = n(e, t, r + 1, E)
|
|
, T = c - e.length();
|
|
t -= T,
|
|
p == s.Type.BITSTRING && T++;
|
|
var I = S.tagClass;
|
|
T !== f || I !== s.Class.UNIVERSAL && I !== s.Class.CONTEXT_SPECIFIC || (d = [S])
|
|
} catch (e) {}
|
|
void 0 === d && (e.read = v,
|
|
t = m)
|
|
}
|
|
if (void 0 === d) {
|
|
if (void 0 === f) {
|
|
if (i.strict)
|
|
throw new Error("Non-constructed ASN.1 object of indefinite length.");
|
|
f = t
|
|
}
|
|
if (p === s.Type.BMPSTRING)
|
|
for (d = ""; f > 0; f -= 2)
|
|
a(e, t, 2),
|
|
d += String.fromCharCode(e.getInt16()),
|
|
t -= 2;
|
|
else
|
|
d = e.getBytes(f)
|
|
}
|
|
var b = void 0 === y ? null : {
|
|
bitStringContents: y
|
|
};
|
|
return s.create(l, p, g, d, b)
|
|
}
|
|
var i = r(0);
|
|
r(1),
|
|
r(6);
|
|
var s = e.exports = i.asn1 = i.asn1 || {};
|
|
s.Class = {
|
|
UNIVERSAL: 0,
|
|
APPLICATION: 64,
|
|
CONTEXT_SPECIFIC: 128,
|
|
PRIVATE: 192
|
|
},
|
|
s.Type = {
|
|
NONE: 0,
|
|
BOOLEAN: 1,
|
|
INTEGER: 2,
|
|
BITSTRING: 3,
|
|
OCTETSTRING: 4,
|
|
NULL: 5,
|
|
OID: 6,
|
|
ODESC: 7,
|
|
EXTERNAL: 8,
|
|
REAL: 9,
|
|
ENUMERATED: 10,
|
|
EMBEDDED: 11,
|
|
UTF8: 12,
|
|
ROID: 13,
|
|
SEQUENCE: 16,
|
|
SET: 17,
|
|
PRINTABLESTRING: 19,
|
|
IA5STRING: 22,
|
|
UTCTIME: 23,
|
|
GENERALIZEDTIME: 24,
|
|
BMPSTRING: 30
|
|
},
|
|
s.create = function(e, t, r, a, n) {
|
|
if (i.util.isArray(a)) {
|
|
for (var o = [], c = 0; c < a.length; ++c)
|
|
void 0 !== a[c] && o.push(a[c]);
|
|
a = o
|
|
}
|
|
var u = {
|
|
tagClass: e,
|
|
type: t,
|
|
constructed: r,
|
|
composed: r || i.util.isArray(a),
|
|
value: a
|
|
};
|
|
return n && "bitStringContents"in n && (u.bitStringContents = n.bitStringContents,
|
|
u.original = s.copy(u)),
|
|
u
|
|
}
|
|
,
|
|
s.copy = function(e, t) {
|
|
var r;
|
|
if (i.util.isArray(e)) {
|
|
r = [];
|
|
for (var a = 0; a < e.length; ++a)
|
|
r.push(s.copy(e[a], t));
|
|
return r
|
|
}
|
|
return "string" == typeof e ? e : (r = {
|
|
tagClass: e.tagClass,
|
|
type: e.type,
|
|
constructed: e.constructed,
|
|
composed: e.composed,
|
|
value: s.copy(e.value, t)
|
|
},
|
|
t && !t.excludeBitStringContents && (r.bitStringContents = e.bitStringContents),
|
|
r)
|
|
}
|
|
,
|
|
s.equals = function(e, t, r) {
|
|
if (i.util.isArray(e)) {
|
|
if (!i.util.isArray(t))
|
|
return !1;
|
|
if (e.length !== t.length)
|
|
return !1;
|
|
for (var a = 0; a < e.length; ++a)
|
|
if (!s.equals(e[a], t[a]))
|
|
return !1;
|
|
return !0
|
|
}
|
|
if (typeof e != typeof t)
|
|
return !1;
|
|
if ("string" == typeof e)
|
|
return e === t;
|
|
var n = e.tagClass === t.tagClass && e.type === t.type && e.constructed === t.constructed && e.composed === t.composed && s.equals(e.value, t.value);
|
|
return r && r.includeBitStringContents && (n = n && e.bitStringContents === t.bitStringContents),
|
|
n
|
|
}
|
|
,
|
|
s.getBerValueLength = function(e) {
|
|
var t = e.getByte();
|
|
if (128 !== t) {
|
|
return 128 & t ? e.getInt((127 & t) << 3) : t
|
|
}
|
|
}
|
|
;
|
|
var o = function(e, t) {
|
|
var r = e.getByte();
|
|
if (t--,
|
|
128 !== r) {
|
|
var n;
|
|
if (128 & r) {
|
|
var i = 127 & r;
|
|
a(e, t, i),
|
|
n = e.getInt(i << 3)
|
|
} else
|
|
n = r;
|
|
if (n < 0)
|
|
throw new Error("Negative length: " + n);
|
|
return n
|
|
}
|
|
};
|
|
s.fromDer = function(e, t) {
|
|
return void 0 === t && (t = {
|
|
strict: !0,
|
|
decodeBitStrings: !0
|
|
}),
|
|
"boolean" == typeof t && (t = {
|
|
strict: t,
|
|
decodeBitStrings: !0
|
|
}),
|
|
"strict"in t || (t.strict = !0),
|
|
"decodeBitStrings"in t || (t.decodeBitStrings = !0),
|
|
"string" == typeof e && (e = i.util.createBuffer(e)),
|
|
n(e, e.length(), 0, t)
|
|
}
|
|
,
|
|
s.toDer = function(e) {
|
|
var t = i.util.createBuffer()
|
|
, r = e.tagClass | e.type
|
|
, a = i.util.createBuffer()
|
|
, n = !1;
|
|
if ("bitStringContents"in e && (n = !0,
|
|
e.original && (n = s.equals(e, e.original))),
|
|
n)
|
|
a.putBytes(e.bitStringContents);
|
|
else if (e.composed) {
|
|
e.constructed ? r |= 32 : a.putByte(0);
|
|
for (var o = 0; o < e.value.length; ++o)
|
|
void 0 !== e.value[o] && a.putBuffer(s.toDer(e.value[o]))
|
|
} else if (e.type === s.Type.BMPSTRING)
|
|
for (var o = 0; o < e.value.length; ++o)
|
|
a.putInt16(e.value.charCodeAt(o));
|
|
else
|
|
e.type === s.Type.INTEGER && e.value.length > 1 && (0 === e.value.charCodeAt(0) && 0 == (128 & e.value.charCodeAt(1)) || 255 === e.value.charCodeAt(0) && 128 == (128 & e.value.charCodeAt(1))) ? a.putBytes(e.value.substr(1)) : a.putBytes(e.value);
|
|
if (t.putByte(r),
|
|
a.length() <= 127)
|
|
t.putByte(127 & a.length());
|
|
else {
|
|
var c = a.length()
|
|
, u = "";
|
|
do {
|
|
u += String.fromCharCode(255 & c),
|
|
c >>>= 8
|
|
} while (c > 0);
|
|
t.putByte(128 | u.length);
|
|
for (var o = u.length - 1; o >= 0; --o)
|
|
t.putByte(u.charCodeAt(o))
|
|
}
|
|
return t.putBuffer(a),
|
|
t
|
|
}
|
|
,
|
|
s.oidToDer = function(e) {
|
|
var t = e.split(".")
|
|
, r = i.util.createBuffer();
|
|
r.putByte(40 * parseInt(t[0], 10) + parseInt(t[1], 10));
|
|
for (var a, n, s, o, c = 2; c < t.length; ++c) {
|
|
a = !0,
|
|
n = [],
|
|
s = parseInt(t[c], 10);
|
|
do {
|
|
o = 127 & s,
|
|
s >>>= 7,
|
|
a || (o |= 128),
|
|
n.push(o),
|
|
a = !1
|
|
} while (s > 0);
|
|
for (var u = n.length - 1; u >= 0; --u)
|
|
r.putByte(n[u])
|
|
}
|
|
return r
|
|
}
|
|
,
|
|
s.derToOid = function(e) {
|
|
var t;
|
|
"string" == typeof e && (e = i.util.createBuffer(e));
|
|
var r = e.getByte();
|
|
t = Math.floor(r / 40) + "." + r % 40;
|
|
for (var a = 0; e.length() > 0; )
|
|
r = e.getByte(),
|
|
a <<= 7,
|
|
128 & r ? a += 127 & r : (t += "." + (a + r),
|
|
a = 0);
|
|
return t
|
|
}
|
|
,
|
|
s.utcTimeToDate = function(e) {
|
|
var t = new Date
|
|
, r = parseInt(e.substr(0, 2), 10);
|
|
r = r >= 50 ? 1900 + r : 2e3 + r;
|
|
var a = parseInt(e.substr(2, 2), 10) - 1
|
|
, n = parseInt(e.substr(4, 2), 10)
|
|
, i = parseInt(e.substr(6, 2), 10)
|
|
, s = parseInt(e.substr(8, 2), 10)
|
|
, o = 0;
|
|
if (e.length > 11) {
|
|
var c = e.charAt(10)
|
|
, u = 10;
|
|
"+" !== c && "-" !== c && (o = parseInt(e.substr(10, 2), 10),
|
|
u += 2)
|
|
}
|
|
if (t.setUTCFullYear(r, a, n),
|
|
t.setUTCHours(i, s, o, 0),
|
|
u && ("+" === (c = e.charAt(u)) || "-" === c)) {
|
|
var l = parseInt(e.substr(u + 1, 2), 10)
|
|
, p = parseInt(e.substr(u + 4, 2), 10)
|
|
, f = 60 * l + p;
|
|
f *= 6e4,
|
|
"+" === c ? t.setTime(+t - f) : t.setTime(+t + f)
|
|
}
|
|
return t
|
|
}
|
|
,
|
|
s.generalizedTimeToDate = function(e) {
|
|
var t = new Date
|
|
, r = parseInt(e.substr(0, 4), 10)
|
|
, a = parseInt(e.substr(4, 2), 10) - 1
|
|
, n = parseInt(e.substr(6, 2), 10)
|
|
, i = parseInt(e.substr(8, 2), 10)
|
|
, s = parseInt(e.substr(10, 2), 10)
|
|
, o = parseInt(e.substr(12, 2), 10)
|
|
, c = 0
|
|
, u = 0
|
|
, l = !1;
|
|
"Z" === e.charAt(e.length - 1) && (l = !0);
|
|
var p = e.length - 5
|
|
, f = e.charAt(p);
|
|
if ("+" === f || "-" === f) {
|
|
u = 60 * parseInt(e.substr(p + 1, 2), 10) + parseInt(e.substr(p + 4, 2), 10),
|
|
u *= 6e4,
|
|
"+" === f && (u *= -1),
|
|
l = !0
|
|
}
|
|
return "." === e.charAt(14) && (c = 1e3 * parseFloat(e.substr(14), 10)),
|
|
l ? (t.setUTCFullYear(r, a, n),
|
|
t.setUTCHours(i, s, o, c),
|
|
t.setTime(+t + u)) : (t.setFullYear(r, a, n),
|
|
t.setHours(i, s, o, c)),
|
|
t
|
|
}
|
|
,
|
|
s.dateToUtcTime = function(e) {
|
|
if ("string" == typeof e)
|
|
return e;
|
|
var t = ""
|
|
, r = [];
|
|
r.push(("" + e.getUTCFullYear()).substr(2)),
|
|
r.push("" + (e.getUTCMonth() + 1)),
|
|
r.push("" + e.getUTCDate()),
|
|
r.push("" + e.getUTCHours()),
|
|
r.push("" + e.getUTCMinutes()),
|
|
r.push("" + e.getUTCSeconds());
|
|
for (var a = 0; a < r.length; ++a)
|
|
r[a].length < 2 && (t += "0"),
|
|
t += r[a];
|
|
return t += "Z"
|
|
}
|
|
,
|
|
s.dateToGeneralizedTime = function(e) {
|
|
if ("string" == typeof e)
|
|
return e;
|
|
var t = ""
|
|
, r = [];
|
|
r.push("" + e.getUTCFullYear()),
|
|
r.push("" + (e.getUTCMonth() + 1)),
|
|
r.push("" + e.getUTCDate()),
|
|
r.push("" + e.getUTCHours()),
|
|
r.push("" + e.getUTCMinutes()),
|
|
r.push("" + e.getUTCSeconds());
|
|
for (var a = 0; a < r.length; ++a)
|
|
r[a].length < 2 && (t += "0"),
|
|
t += r[a];
|
|
return t += "Z"
|
|
}
|
|
,
|
|
s.integerToDer = function(e) {
|
|
var t = i.util.createBuffer();
|
|
if (e >= -128 && e < 128)
|
|
return t.putSignedInt(e, 8);
|
|
if (e >= -32768 && e < 32768)
|
|
return t.putSignedInt(e, 16);
|
|
if (e >= -8388608 && e < 8388608)
|
|
return t.putSignedInt(e, 24);
|
|
if (e >= -2147483648 && e < 2147483648)
|
|
return t.putSignedInt(e, 32);
|
|
var r = new Error("Integer too large; max is 32-bits.");
|
|
throw r.integer = e,
|
|
r
|
|
}
|
|
,
|
|
s.derToInteger = function(e) {
|
|
"string" == typeof e && (e = i.util.createBuffer(e));
|
|
var t = 8 * e.length();
|
|
if (t > 32)
|
|
throw new Error("Integer too large; max is 32-bits.");
|
|
return e.getSignedInt(t)
|
|
}
|
|
,
|
|
s.validate = function(e, t, r, a) {
|
|
var n = !1;
|
|
if (e.tagClass !== t.tagClass && void 0 !== t.tagClass || e.type !== t.type && void 0 !== t.type)
|
|
a && (e.tagClass !== t.tagClass && a.push("[" + t.name + '] Expected tag class "' + t.tagClass + '", got "' + e.tagClass + '"'),
|
|
e.type !== t.type && a.push("[" + t.name + '] Expected type "' + t.type + '", got "' + e.type + '"'));
|
|
else if (e.constructed === t.constructed || void 0 === t.constructed) {
|
|
if (n = !0,
|
|
t.value && i.util.isArray(t.value))
|
|
for (var o = 0, c = 0; n && c < t.value.length; ++c)
|
|
n = t.value[c].optional || !1,
|
|
e.value[o] && (n = s.validate(e.value[o], t.value[c], r, a),
|
|
n ? ++o : t.value[c].optional && (n = !0)),
|
|
!n && a && a.push("[" + t.name + '] Tag class "' + t.tagClass + '", type "' + t.type + '" expected value length "' + t.value.length + '", got "' + e.value.length + '"');
|
|
if (n && r && (t.capture && (r[t.capture] = e.value),
|
|
t.captureAsn1 && (r[t.captureAsn1] = e),
|
|
t.captureBitStringContents && "bitStringContents"in e && (r[t.captureBitStringContents] = e.bitStringContents),
|
|
t.captureBitStringValue && "bitStringContents"in e)) {
|
|
if (e.bitStringContents.length < 2)
|
|
r[t.captureBitStringValue] = "";
|
|
else {
|
|
var u = e.bitStringContents.charCodeAt(0);
|
|
if (0 !== u)
|
|
throw new Error("captureBitStringValue only supported for zero unused bits");
|
|
r[t.captureBitStringValue] = e.bitStringContents.slice(1)
|
|
}
|
|
}
|
|
} else
|
|
a && a.push("[" + t.name + '] Expected constructed "' + t.constructed + '", got "' + e.constructed + '"');
|
|
return n
|
|
}
|
|
;
|
|
var c = /[^\\u0000-\\u00ff]/;
|
|
s.prettyPrint = function(e, t, r) {
|
|
var a = "";
|
|
t = t || 0,
|
|
r = r || 2,
|
|
t > 0 && (a += "\n");
|
|
for (var n = "", o = 0; o < t * r; ++o)
|
|
n += " ";
|
|
switch (a += n + "Tag: ",
|
|
e.tagClass) {
|
|
case s.Class.UNIVERSAL:
|
|
a += "Universal:";
|
|
break;
|
|
case s.Class.APPLICATION:
|
|
a += "Application:";
|
|
break;
|
|
case s.Class.CONTEXT_SPECIFIC:
|
|
a += "Context-Specific:";
|
|
break;
|
|
case s.Class.PRIVATE:
|
|
a += "Private:"
|
|
}
|
|
if (e.tagClass === s.Class.UNIVERSAL)
|
|
switch (a += e.type,
|
|
e.type) {
|
|
case s.Type.NONE:
|
|
a += " (None)";
|
|
break;
|
|
case s.Type.BOOLEAN:
|
|
a += " (Boolean)";
|
|
break;
|
|
case s.Type.INTEGER:
|
|
a += " (Integer)";
|
|
break;
|
|
case s.Type.BITSTRING:
|
|
a += " (Bit string)";
|
|
break;
|
|
case s.Type.OCTETSTRING:
|
|
a += " (Octet string)";
|
|
break;
|
|
case s.Type.NULL:
|
|
a += " (Null)";
|
|
break;
|
|
case s.Type.OID:
|
|
a += " (Object Identifier)";
|
|
break;
|
|
case s.Type.ODESC:
|
|
a += " (Object Descriptor)";
|
|
break;
|
|
case s.Type.EXTERNAL:
|
|
a += " (External or Instance of)";
|
|
break;
|
|
case s.Type.REAL:
|
|
a += " (Real)";
|
|
break;
|
|
case s.Type.ENUMERATED:
|
|
a += " (Enumerated)";
|
|
break;
|
|
case s.Type.EMBEDDED:
|
|
a += " (Embedded PDV)";
|
|
break;
|
|
case s.Type.UTF8:
|
|
a += " (UTF8)";
|
|
break;
|
|
case s.Type.ROID:
|
|
a += " (Relative Object Identifier)";
|
|
break;
|
|
case s.Type.SEQUENCE:
|
|
a += " (Sequence)";
|
|
break;
|
|
case s.Type.SET:
|
|
a += " (Set)";
|
|
break;
|
|
case s.Type.PRINTABLESTRING:
|
|
a += " (Printable String)";
|
|
break;
|
|
case s.Type.IA5String:
|
|
a += " (IA5String (ASCII))";
|
|
break;
|
|
case s.Type.UTCTIME:
|
|
a += " (UTC time)";
|
|
break;
|
|
case s.Type.GENERALIZEDTIME:
|
|
a += " (Generalized time)";
|
|
break;
|
|
case s.Type.BMPSTRING:
|
|
a += " (BMP String)"
|
|
}
|
|
else
|
|
a += e.type;
|
|
if (a += "\n",
|
|
a += n + "Constructed: " + e.constructed + "\n",
|
|
e.composed) {
|
|
for (var u = 0, l = "", o = 0; o < e.value.length; ++o)
|
|
void 0 !== e.value[o] && (u += 1,
|
|
l += s.prettyPrint(e.value[o], t + 1, r),
|
|
o + 1 < e.value.length && (l += ","));
|
|
a += n + "Sub values: " + u + l
|
|
} else {
|
|
if (a += n + "Value: ",
|
|
e.type === s.Type.OID) {
|
|
var p = s.derToOid(e.value);
|
|
a += p,
|
|
i.pki && i.pki.oids && p in i.pki.oids && (a += " (" + i.pki.oids[p] + ") ")
|
|
}
|
|
if (e.type === s.Type.INTEGER)
|
|
try {
|
|
a += s.derToInteger(e.value)
|
|
} catch (t) {
|
|
a += "0x" + i.util.bytesToHex(e.value)
|
|
}
|
|
else if (e.type === s.Type.BITSTRING) {
|
|
if (e.value.length > 1 ? a += "0x" + i.util.bytesToHex(e.value.slice(1)) : a += "(none)",
|
|
e.value.length > 0) {
|
|
var f = e.value.charCodeAt(0);
|
|
1 == f ? a += " (1 unused bit shown)" : f > 1 && (a += " (" + f + " unused bits shown)")
|
|
}
|
|
} else
|
|
e.type === s.Type.OCTETSTRING ? (c.test(e.value) || (a += "(" + e.value + ") "),
|
|
a += "0x" + i.util.bytesToHex(e.value)) : e.type === s.Type.UTF8 ? a += i.util.decodeUtf8(e.value) : e.type === s.Type.PRINTABLESTRING || e.type === s.Type.IA5String ? a += e.value : c.test(e.value) ? a += "0x" + i.util.bytesToHex(e.value) : 0 === e.value.length ? a += "[null]" : a += e.value
|
|
}
|
|
return a
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
e.exports = a.md = a.md || {},
|
|
a.md.algorithms = a.md.algorithms || {}
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t) {
|
|
var r = function() {
|
|
return new c.aes.Algorithm(e,t)
|
|
};
|
|
c.cipher.registerAlgorithm(e, r)
|
|
}
|
|
function n() {
|
|
d = !0,
|
|
p = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54];
|
|
for (var e = new Array(256), t = 0; t < 128; ++t)
|
|
e[t] = t << 1,
|
|
e[t + 128] = t + 128 << 1 ^ 283;
|
|
u = new Array(256),
|
|
l = new Array(256),
|
|
f = new Array(4),
|
|
h = new Array(4);
|
|
for (var t = 0; t < 4; ++t)
|
|
f[t] = new Array(256),
|
|
h[t] = new Array(256);
|
|
for (var r, a, n, i, s, o, c, y = 0, g = 0, t = 0; t < 256; ++t) {
|
|
i = g ^ g << 1 ^ g << 2 ^ g << 3 ^ g << 4,
|
|
i = i >> 8 ^ 255 & i ^ 99,
|
|
u[y] = i,
|
|
l[i] = y,
|
|
s = e[i],
|
|
r = e[y],
|
|
a = e[r],
|
|
n = e[a],
|
|
o = s << 24 ^ i << 16 ^ i << 8 ^ i ^ s,
|
|
c = (r ^ a ^ n) << 24 ^ (y ^ n) << 16 ^ (y ^ a ^ n) << 8 ^ y ^ r ^ n;
|
|
for (var v = 0; v < 4; ++v)
|
|
f[v][y] = o,
|
|
h[v][i] = c,
|
|
o = o << 24 | o >>> 8,
|
|
c = c << 24 | c >>> 8;
|
|
0 === y ? y = g = 1 : (y = r ^ e[e[e[r ^ n]]],
|
|
g ^= e[e[g]])
|
|
}
|
|
}
|
|
function i(e, t) {
|
|
for (var r, a = e.slice(0), n = 1, i = a.length, s = i + 6 + 1, o = y * s, c = i; c < o; ++c)
|
|
r = a[c - 1],
|
|
c % i == 0 ? (r = u[r >>> 16 & 255] << 24 ^ u[r >>> 8 & 255] << 16 ^ u[255 & r] << 8 ^ u[r >>> 24] ^ p[n] << 24,
|
|
n++) : i > 6 && c % i == 4 && (r = u[r >>> 24] << 24 ^ u[r >>> 16 & 255] << 16 ^ u[r >>> 8 & 255] << 8 ^ u[255 & r]),
|
|
a[c] = a[c - i] ^ r;
|
|
if (t) {
|
|
var l, f = h[0], d = h[1], g = h[2], v = h[3], m = a.slice(0);
|
|
o = a.length;
|
|
for (var c = 0, C = o - y; c < o; c += y,
|
|
C -= y)
|
|
if (0 === c || c === o - y)
|
|
m[c] = a[C],
|
|
m[c + 1] = a[C + 3],
|
|
m[c + 2] = a[C + 2],
|
|
m[c + 3] = a[C + 1];
|
|
else
|
|
for (var E = 0; E < y; ++E)
|
|
l = a[C + E],
|
|
m[c + (3 & -E)] = f[u[l >>> 24]] ^ d[u[l >>> 16 & 255]] ^ g[u[l >>> 8 & 255]] ^ v[u[255 & l]];
|
|
a = m
|
|
}
|
|
return a
|
|
}
|
|
function s(e, t, r, a) {
|
|
var n, i, s, o, c, p = e.length / 4 - 1;
|
|
a ? (n = h[0],
|
|
i = h[1],
|
|
s = h[2],
|
|
o = h[3],
|
|
c = l) : (n = f[0],
|
|
i = f[1],
|
|
s = f[2],
|
|
o = f[3],
|
|
c = u);
|
|
var d, y, g, v, m, C, E;
|
|
d = t[0] ^ e[0],
|
|
y = t[a ? 3 : 1] ^ e[1],
|
|
g = t[2] ^ e[2],
|
|
v = t[a ? 1 : 3] ^ e[3];
|
|
for (var S = 3, T = 1; T < p; ++T)
|
|
m = n[d >>> 24] ^ i[y >>> 16 & 255] ^ s[g >>> 8 & 255] ^ o[255 & v] ^ e[++S],
|
|
C = n[y >>> 24] ^ i[g >>> 16 & 255] ^ s[v >>> 8 & 255] ^ o[255 & d] ^ e[++S],
|
|
E = n[g >>> 24] ^ i[v >>> 16 & 255] ^ s[d >>> 8 & 255] ^ o[255 & y] ^ e[++S],
|
|
v = n[v >>> 24] ^ i[d >>> 16 & 255] ^ s[y >>> 8 & 255] ^ o[255 & g] ^ e[++S],
|
|
d = m,
|
|
y = C,
|
|
g = E;
|
|
r[0] = c[d >>> 24] << 24 ^ c[y >>> 16 & 255] << 16 ^ c[g >>> 8 & 255] << 8 ^ c[255 & v] ^ e[++S],
|
|
r[a ? 3 : 1] = c[y >>> 24] << 24 ^ c[g >>> 16 & 255] << 16 ^ c[v >>> 8 & 255] << 8 ^ c[255 & d] ^ e[++S],
|
|
r[2] = c[g >>> 24] << 24 ^ c[v >>> 16 & 255] << 16 ^ c[d >>> 8 & 255] << 8 ^ c[255 & y] ^ e[++S],
|
|
r[a ? 1 : 3] = c[v >>> 24] << 24 ^ c[d >>> 16 & 255] << 16 ^ c[y >>> 8 & 255] << 8 ^ c[255 & g] ^ e[++S]
|
|
}
|
|
function o(e) {
|
|
e = e || {};
|
|
var t, r = (e.mode || "CBC").toUpperCase(), a = "AES-" + r;
|
|
t = e.decrypt ? c.cipher.createDecipher(a, e.key) : c.cipher.createCipher(a, e.key);
|
|
var n = t.start;
|
|
return t.start = function(e, r) {
|
|
var a = null;
|
|
r instanceof c.util.ByteBuffer && (a = r,
|
|
r = {}),
|
|
r = r || {},
|
|
r.output = a,
|
|
r.iv = e,
|
|
n.call(t, r)
|
|
}
|
|
,
|
|
t
|
|
}
|
|
var c = r(0);
|
|
r(13),
|
|
r(19),
|
|
r(1),
|
|
e.exports = c.aes = c.aes || {},
|
|
c.aes.startEncrypting = function(e, t, r, a) {
|
|
var n = o({
|
|
key: e,
|
|
output: r,
|
|
decrypt: !1,
|
|
mode: a
|
|
});
|
|
return n.start(t),
|
|
n
|
|
}
|
|
,
|
|
c.aes.createEncryptionCipher = function(e, t) {
|
|
return o({
|
|
key: e,
|
|
output: null,
|
|
decrypt: !1,
|
|
mode: t
|
|
})
|
|
}
|
|
,
|
|
c.aes.startDecrypting = function(e, t, r, a) {
|
|
var n = o({
|
|
key: e,
|
|
output: r,
|
|
decrypt: !0,
|
|
mode: a
|
|
});
|
|
return n.start(t),
|
|
n
|
|
}
|
|
,
|
|
c.aes.createDecryptionCipher = function(e, t) {
|
|
return o({
|
|
key: e,
|
|
output: null,
|
|
decrypt: !0,
|
|
mode: t
|
|
})
|
|
}
|
|
,
|
|
c.aes.Algorithm = function(e, t) {
|
|
d || n();
|
|
var r = this;
|
|
r.name = e,
|
|
r.mode = new t({
|
|
blockSize: 16,
|
|
cipher: {
|
|
encrypt: function(e, t) {
|
|
return s(r._w, e, t, !1)
|
|
},
|
|
decrypt: function(e, t) {
|
|
return s(r._w, e, t, !0)
|
|
}
|
|
}
|
|
}),
|
|
r._init = !1
|
|
}
|
|
,
|
|
c.aes.Algorithm.prototype.initialize = function(e) {
|
|
if (!this._init) {
|
|
var t, r = e.key;
|
|
if ("string" != typeof r || 16 !== r.length && 24 !== r.length && 32 !== r.length) {
|
|
if (c.util.isArray(r) && (16 === r.length || 24 === r.length || 32 === r.length)) {
|
|
t = r,
|
|
r = c.util.createBuffer();
|
|
for (var a = 0; a < t.length; ++a)
|
|
r.putByte(t[a])
|
|
}
|
|
} else
|
|
r = c.util.createBuffer(r);
|
|
if (!c.util.isArray(r)) {
|
|
t = r,
|
|
r = [];
|
|
var n = t.length();
|
|
if (16 === n || 24 === n || 32 === n) {
|
|
n >>>= 2;
|
|
for (var a = 0; a < n; ++a)
|
|
r.push(t.getInt32())
|
|
}
|
|
}
|
|
if (!c.util.isArray(r) || 4 !== r.length && 6 !== r.length && 8 !== r.length)
|
|
throw new Error("Invalid key parameter.");
|
|
var s = this.mode.name
|
|
, o = -1 !== ["CFB", "OFB", "CTR", "GCM"].indexOf(s);
|
|
this._w = i(r, e.decrypt && !o),
|
|
this._init = !0
|
|
}
|
|
}
|
|
,
|
|
c.aes._expandKey = function(e, t) {
|
|
return d || n(),
|
|
i(e, t)
|
|
}
|
|
,
|
|
c.aes._updateBlock = s,
|
|
a("AES-ECB", c.cipher.modes.ecb),
|
|
a("AES-CBC", c.cipher.modes.cbc),
|
|
a("AES-CFB", c.cipher.modes.cfb),
|
|
a("AES-OFB", c.cipher.modes.ofb),
|
|
a("AES-CTR", c.cipher.modes.ctr),
|
|
a("AES-GCM", c.cipher.modes.gcm);
|
|
var u, l, p, f, h, d = !1, y = 4
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t) {
|
|
s[e] = t,
|
|
s[t] = e
|
|
}
|
|
function n(e, t) {
|
|
s[e] = t
|
|
}
|
|
var i = r(0);
|
|
i.pki = i.pki || {};
|
|
var s = e.exports = i.pki.oids = i.oids = i.oids || {};
|
|
a("1.2.840.113549.1.1.1", "rsaEncryption"),
|
|
a("1.2.840.113549.1.1.4", "md5WithRSAEncryption"),
|
|
a("1.2.840.113549.1.1.5", "sha1WithRSAEncryption"),
|
|
a("1.2.840.113549.1.1.7", "RSAES-OAEP"),
|
|
a("1.2.840.113549.1.1.8", "mgf1"),
|
|
a("1.2.840.113549.1.1.9", "pSpecified"),
|
|
a("1.2.840.113549.1.1.10", "RSASSA-PSS"),
|
|
a("1.2.840.113549.1.1.11", "sha256WithRSAEncryption"),
|
|
a("1.2.840.113549.1.1.12", "sha384WithRSAEncryption"),
|
|
a("1.2.840.113549.1.1.13", "sha512WithRSAEncryption"),
|
|
a("1.2.840.10040.4.3", "dsa-with-sha1"),
|
|
a("1.3.14.3.2.7", "desCBC"),
|
|
a("1.3.14.3.2.26", "sha1"),
|
|
a("2.16.840.1.101.3.4.2.1", "sha256"),
|
|
a("2.16.840.1.101.3.4.2.2", "sha384"),
|
|
a("2.16.840.1.101.3.4.2.3", "sha512"),
|
|
a("1.2.840.113549.2.5", "md5"),
|
|
a("1.2.840.113549.1.7.1", "data"),
|
|
a("1.2.840.113549.1.7.2", "signedData"),
|
|
a("1.2.840.113549.1.7.3", "envelopedData"),
|
|
a("1.2.840.113549.1.7.4", "signedAndEnvelopedData"),
|
|
a("1.2.840.113549.1.7.5", "digestedData"),
|
|
a("1.2.840.113549.1.7.6", "encryptedData"),
|
|
a("1.2.840.113549.1.9.1", "emailAddress"),
|
|
a("1.2.840.113549.1.9.2", "unstructuredName"),
|
|
a("1.2.840.113549.1.9.3", "contentType"),
|
|
a("1.2.840.113549.1.9.4", "messageDigest"),
|
|
a("1.2.840.113549.1.9.5", "signingTime"),
|
|
a("1.2.840.113549.1.9.6", "counterSignature"),
|
|
a("1.2.840.113549.1.9.7", "challengePassword"),
|
|
a("1.2.840.113549.1.9.8", "unstructuredAddress"),
|
|
a("1.2.840.113549.1.9.14", "extensionRequest"),
|
|
a("1.2.840.113549.1.9.20", "friendlyName"),
|
|
a("1.2.840.113549.1.9.21", "localKeyId"),
|
|
a("1.2.840.113549.1.9.22.1", "x509Certificate"),
|
|
a("1.2.840.113549.1.12.10.1.1", "keyBag"),
|
|
a("1.2.840.113549.1.12.10.1.2", "pkcs8ShroudedKeyBag"),
|
|
a("1.2.840.113549.1.12.10.1.3", "certBag"),
|
|
a("1.2.840.113549.1.12.10.1.4", "crlBag"),
|
|
a("1.2.840.113549.1.12.10.1.5", "secretBag"),
|
|
a("1.2.840.113549.1.12.10.1.6", "safeContentsBag"),
|
|
a("1.2.840.113549.1.5.13", "pkcs5PBES2"),
|
|
a("1.2.840.113549.1.5.12", "pkcs5PBKDF2"),
|
|
a("1.2.840.113549.1.12.1.1", "pbeWithSHAAnd128BitRC4"),
|
|
a("1.2.840.113549.1.12.1.2", "pbeWithSHAAnd40BitRC4"),
|
|
a("1.2.840.113549.1.12.1.3", "pbeWithSHAAnd3-KeyTripleDES-CBC"),
|
|
a("1.2.840.113549.1.12.1.4", "pbeWithSHAAnd2-KeyTripleDES-CBC"),
|
|
a("1.2.840.113549.1.12.1.5", "pbeWithSHAAnd128BitRC2-CBC"),
|
|
a("1.2.840.113549.1.12.1.6", "pbewithSHAAnd40BitRC2-CBC"),
|
|
a("1.2.840.113549.2.7", "hmacWithSHA1"),
|
|
a("1.2.840.113549.2.8", "hmacWithSHA224"),
|
|
a("1.2.840.113549.2.9", "hmacWithSHA256"),
|
|
a("1.2.840.113549.2.10", "hmacWithSHA384"),
|
|
a("1.2.840.113549.2.11", "hmacWithSHA512"),
|
|
a("1.2.840.113549.3.7", "des-EDE3-CBC"),
|
|
a("2.16.840.1.101.3.4.1.2", "aes128-CBC"),
|
|
a("2.16.840.1.101.3.4.1.22", "aes192-CBC"),
|
|
a("2.16.840.1.101.3.4.1.42", "aes256-CBC"),
|
|
a("2.5.4.3", "commonName"),
|
|
a("2.5.4.5", "serialName"),
|
|
a("2.5.4.6", "countryName"),
|
|
a("2.5.4.7", "localityName"),
|
|
a("2.5.4.8", "stateOrProvinceName"),
|
|
a("2.5.4.10", "organizationName"),
|
|
a("2.5.4.11", "organizationalUnitName"),
|
|
a("2.5.4.13", "description"),
|
|
a("2.16.840.1.113730.1.1", "nsCertType"),
|
|
a("2.16.840.1.113730.1.13", "nsComment"),
|
|
n("2.5.29.1", "authorityKeyIdentifier"),
|
|
n("2.5.29.2", "keyAttributes"),
|
|
n("2.5.29.3", "certificatePolicies"),
|
|
n("2.5.29.4", "keyUsageRestriction"),
|
|
n("2.5.29.5", "policyMapping"),
|
|
n("2.5.29.6", "subtreesConstraint"),
|
|
n("2.5.29.7", "subjectAltName"),
|
|
n("2.5.29.8", "issuerAltName"),
|
|
n("2.5.29.9", "subjectDirectoryAttributes"),
|
|
n("2.5.29.10", "basicConstraints"),
|
|
n("2.5.29.11", "nameConstraints"),
|
|
n("2.5.29.12", "policyConstraints"),
|
|
n("2.5.29.13", "basicConstraints"),
|
|
a("2.5.29.14", "subjectKeyIdentifier"),
|
|
a("2.5.29.15", "keyUsage"),
|
|
n("2.5.29.16", "privateKeyUsagePeriod"),
|
|
a("2.5.29.17", "subjectAltName"),
|
|
a("2.5.29.18", "issuerAltName"),
|
|
a("2.5.29.19", "basicConstraints"),
|
|
n("2.5.29.20", "cRLNumber"),
|
|
n("2.5.29.21", "cRLReason"),
|
|
n("2.5.29.22", "expirationDate"),
|
|
n("2.5.29.23", "instructionCode"),
|
|
n("2.5.29.24", "invalidityDate"),
|
|
n("2.5.29.25", "cRLDistributionPoints"),
|
|
n("2.5.29.26", "issuingDistributionPoint"),
|
|
n("2.5.29.27", "deltaCRLIndicator"),
|
|
n("2.5.29.28", "issuingDistributionPoint"),
|
|
n("2.5.29.29", "certificateIssuer"),
|
|
n("2.5.29.30", "nameConstraints"),
|
|
a("2.5.29.31", "cRLDistributionPoints"),
|
|
a("2.5.29.32", "certificatePolicies"),
|
|
n("2.5.29.33", "policyMappings"),
|
|
n("2.5.29.34", "policyConstraints"),
|
|
a("2.5.29.35", "authorityKeyIdentifier"),
|
|
n("2.5.29.36", "policyConstraints"),
|
|
a("2.5.29.37", "extKeyUsage"),
|
|
n("2.5.29.46", "freshestCRL"),
|
|
n("2.5.29.54", "inhibitAnyPolicy"),
|
|
a("1.3.6.1.4.1.11129.2.4.2", "timestampList"),
|
|
a("1.3.6.1.5.5.7.1.1", "authorityInfoAccess"),
|
|
a("1.3.6.1.5.5.7.3.1", "serverAuth"),
|
|
a("1.3.6.1.5.5.7.3.2", "clientAuth"),
|
|
a("1.3.6.1.5.5.7.3.3", "codeSigning"),
|
|
a("1.3.6.1.5.5.7.3.4", "emailProtection"),
|
|
a("1.3.6.1.5.5.7.3.8", "timeStamping")
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e) {
|
|
for (var t = e.name + ": ", r = [], a = function(e, t) {
|
|
return " " + t
|
|
}, n = 0; n < e.values.length; ++n)
|
|
r.push(e.values[n].replace(/^(\S+\r\n)/, a));
|
|
t += r.join(",") + "\r\n";
|
|
for (var i = 0, s = -1, n = 0; n < t.length; ++n,
|
|
++i)
|
|
if (i > 65 && -1 !== s) {
|
|
var o = t[s];
|
|
"," === o ? (++s,
|
|
t = t.substr(0, s) + "\r\n " + t.substr(s)) : t = t.substr(0, s) + "\r\n" + o + t.substr(s + 1),
|
|
i = n - s - 1,
|
|
s = -1,
|
|
++n
|
|
} else
|
|
" " !== t[n] && "\t" !== t[n] && "," !== t[n] || (s = n);
|
|
return t
|
|
}
|
|
function n(e) {
|
|
return e.replace(/^\s+/, "")
|
|
}
|
|
var i = r(0);
|
|
r(1);
|
|
var s = e.exports = i.pem = i.pem || {};
|
|
s.encode = function(e, t) {
|
|
t = t || {};
|
|
var r, n = "-----BEGIN " + e.type + "-----\r\n";
|
|
if (e.procType && (r = {
|
|
name: "Proc-Type",
|
|
values: [String(e.procType.version), e.procType.type]
|
|
},
|
|
n += a(r)),
|
|
e.contentDomain && (r = {
|
|
name: "Content-Domain",
|
|
values: [e.contentDomain]
|
|
},
|
|
n += a(r)),
|
|
e.dekInfo && (r = {
|
|
name: "DEK-Info",
|
|
values: [e.dekInfo.algorithm]
|
|
},
|
|
e.dekInfo.parameters && r.values.push(e.dekInfo.parameters),
|
|
n += a(r)),
|
|
e.headers)
|
|
for (var s = 0; s < e.headers.length; ++s)
|
|
n += a(e.headers[s]);
|
|
return e.procType && (n += "\r\n"),
|
|
n += i.util.encode64(e.body, t.maxline || 64) + "\r\n",
|
|
n += "-----END " + e.type + "-----\r\n"
|
|
}
|
|
,
|
|
s.decode = function(e) {
|
|
for (var t, r = [], a = /\s*-----BEGIN ([A-Z0-9- ]+)-----\r?\n?([\x21-\x7e\s]+?(?:\r?\n\r?\n))?([:A-Za-z0-9+\/=\s]+?)-----END \1-----/g, s = /([\x21-\x7e]+):\s*([\x21-\x7e\s^:]+)/, o = /\r?\n/; ; ) {
|
|
if (!(t = a.exec(e)))
|
|
break;
|
|
var c = {
|
|
type: t[1],
|
|
procType: null,
|
|
contentDomain: null,
|
|
dekInfo: null,
|
|
headers: [],
|
|
body: i.util.decode64(t[3])
|
|
};
|
|
if (r.push(c),
|
|
t[2]) {
|
|
for (var u = t[2].split(o), l = 0; t && l < u.length; ) {
|
|
for (var p = u[l].replace(/\s+$/, ""), f = l + 1; f < u.length; ++f) {
|
|
var h = u[f];
|
|
if (!/\s/.test(h[0]))
|
|
break;
|
|
p += h,
|
|
l = f
|
|
}
|
|
if (t = p.match(s)) {
|
|
for (var d = {
|
|
name: t[1],
|
|
values: []
|
|
}, y = t[2].split(","), g = 0; g < y.length; ++g)
|
|
d.values.push(n(y[g]));
|
|
if (c.procType)
|
|
if (c.contentDomain || "Content-Domain" !== d.name)
|
|
if (c.dekInfo || "DEK-Info" !== d.name)
|
|
c.headers.push(d);
|
|
else {
|
|
if (0 === d.values.length)
|
|
throw new Error('Invalid PEM formatted message. The "DEK-Info" header must have at least one subfield.');
|
|
c.dekInfo = {
|
|
algorithm: y[0],
|
|
parameters: y[1] || null
|
|
}
|
|
}
|
|
else
|
|
c.contentDomain = y[0] || "";
|
|
else {
|
|
if ("Proc-Type" !== d.name)
|
|
throw new Error('Invalid PEM formatted message. The first encapsulated header must be "Proc-Type".');
|
|
if (2 !== d.values.length)
|
|
throw new Error('Invalid PEM formatted message. The "Proc-Type" header must have two subfields.');
|
|
c.procType = {
|
|
version: y[0],
|
|
type: y[1]
|
|
}
|
|
}
|
|
}
|
|
++l
|
|
}
|
|
if ("ENCRYPTED" === c.procType && !c.dekInfo)
|
|
throw new Error('Invalid PEM formatted message. The "DEK-Info" header must be present if "Proc-Type" is "ENCRYPTED".')
|
|
}
|
|
}
|
|
if (0 === r.length)
|
|
throw new Error("Invalid PEM formatted message.");
|
|
return r
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(4),
|
|
r(1),
|
|
(e.exports = a.hmac = a.hmac || {}).create = function() {
|
|
var e = null
|
|
, t = null
|
|
, r = null
|
|
, n = null
|
|
, i = {};
|
|
return i.start = function(i, s) {
|
|
if (null !== i)
|
|
if ("string" == typeof i) {
|
|
if (!((i = i.toLowerCase())in a.md.algorithms))
|
|
throw new Error('Unknown hash algorithm "' + i + '"');
|
|
t = a.md.algorithms[i].create()
|
|
} else
|
|
t = i;
|
|
if (null === s)
|
|
s = e;
|
|
else {
|
|
if ("string" == typeof s)
|
|
s = a.util.createBuffer(s);
|
|
else if (a.util.isArray(s)) {
|
|
var o = s;
|
|
s = a.util.createBuffer();
|
|
for (var c = 0; c < o.length; ++c)
|
|
s.putByte(o[c])
|
|
}
|
|
var u = s.length();
|
|
u > t.blockLength && (t.start(),
|
|
t.update(s.bytes()),
|
|
s = t.digest()),
|
|
r = a.util.createBuffer(),
|
|
n = a.util.createBuffer(),
|
|
u = s.length();
|
|
for (var c = 0; c < u; ++c) {
|
|
var o = s.at(c);
|
|
r.putByte(54 ^ o),
|
|
n.putByte(92 ^ o)
|
|
}
|
|
if (u < t.blockLength)
|
|
for (var o = t.blockLength - u, c = 0; c < o; ++c)
|
|
r.putByte(54),
|
|
n.putByte(92);
|
|
e = s,
|
|
r = r.bytes(),
|
|
n = n.bytes()
|
|
}
|
|
t.start(),
|
|
t.update(r)
|
|
}
|
|
,
|
|
i.update = function(e) {
|
|
t.update(e)
|
|
}
|
|
,
|
|
i.getMac = function() {
|
|
var e = t.digest().bytes();
|
|
return t.start(),
|
|
t.update(n),
|
|
t.update(e),
|
|
t.digest()
|
|
}
|
|
,
|
|
i.digest = i.getMac,
|
|
i
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
function a() {
|
|
o = String.fromCharCode(128),
|
|
o += i.util.fillString(String.fromCharCode(0), 64),
|
|
c = !0
|
|
}
|
|
function n(e, t, r) {
|
|
for (var a, n, i, s, o, c, u, l, p = r.length(); p >= 64; ) {
|
|
for (n = e.h0,
|
|
i = e.h1,
|
|
s = e.h2,
|
|
o = e.h3,
|
|
c = e.h4,
|
|
l = 0; l < 16; ++l)
|
|
a = r.getInt32(),
|
|
t[l] = a,
|
|
u = o ^ i & (s ^ o),
|
|
a = (n << 5 | n >>> 27) + u + c + 1518500249 + a,
|
|
c = o,
|
|
o = s,
|
|
s = (i << 30 | i >>> 2) >>> 0,
|
|
i = n,
|
|
n = a;
|
|
for (; l < 20; ++l)
|
|
a = t[l - 3] ^ t[l - 8] ^ t[l - 14] ^ t[l - 16],
|
|
a = a << 1 | a >>> 31,
|
|
t[l] = a,
|
|
u = o ^ i & (s ^ o),
|
|
a = (n << 5 | n >>> 27) + u + c + 1518500249 + a,
|
|
c = o,
|
|
o = s,
|
|
s = (i << 30 | i >>> 2) >>> 0,
|
|
i = n,
|
|
n = a;
|
|
for (; l < 32; ++l)
|
|
a = t[l - 3] ^ t[l - 8] ^ t[l - 14] ^ t[l - 16],
|
|
a = a << 1 | a >>> 31,
|
|
t[l] = a,
|
|
u = i ^ s ^ o,
|
|
a = (n << 5 | n >>> 27) + u + c + 1859775393 + a,
|
|
c = o,
|
|
o = s,
|
|
s = (i << 30 | i >>> 2) >>> 0,
|
|
i = n,
|
|
n = a;
|
|
for (; l < 40; ++l)
|
|
a = t[l - 6] ^ t[l - 16] ^ t[l - 28] ^ t[l - 32],
|
|
a = a << 2 | a >>> 30,
|
|
t[l] = a,
|
|
u = i ^ s ^ o,
|
|
a = (n << 5 | n >>> 27) + u + c + 1859775393 + a,
|
|
c = o,
|
|
o = s,
|
|
s = (i << 30 | i >>> 2) >>> 0,
|
|
i = n,
|
|
n = a;
|
|
for (; l < 60; ++l)
|
|
a = t[l - 6] ^ t[l - 16] ^ t[l - 28] ^ t[l - 32],
|
|
a = a << 2 | a >>> 30,
|
|
t[l] = a,
|
|
u = i & s | o & (i ^ s),
|
|
a = (n << 5 | n >>> 27) + u + c + 2400959708 + a,
|
|
c = o,
|
|
o = s,
|
|
s = (i << 30 | i >>> 2) >>> 0,
|
|
i = n,
|
|
n = a;
|
|
for (; l < 80; ++l)
|
|
a = t[l - 6] ^ t[l - 16] ^ t[l - 28] ^ t[l - 32],
|
|
a = a << 2 | a >>> 30,
|
|
t[l] = a,
|
|
u = i ^ s ^ o,
|
|
a = (n << 5 | n >>> 27) + u + c + 3395469782 + a,
|
|
c = o,
|
|
o = s,
|
|
s = (i << 30 | i >>> 2) >>> 0,
|
|
i = n,
|
|
n = a;
|
|
e.h0 = e.h0 + n | 0,
|
|
e.h1 = e.h1 + i | 0,
|
|
e.h2 = e.h2 + s | 0,
|
|
e.h3 = e.h3 + o | 0,
|
|
e.h4 = e.h4 + c | 0,
|
|
p -= 64
|
|
}
|
|
}
|
|
var i = r(0);
|
|
r(4),
|
|
r(1);
|
|
var s = e.exports = i.sha1 = i.sha1 || {};
|
|
i.md.sha1 = i.md.algorithms.sha1 = s,
|
|
s.create = function() {
|
|
c || a();
|
|
var e = null
|
|
, t = i.util.createBuffer()
|
|
, r = new Array(80)
|
|
, s = {
|
|
algorithm: "sha1",
|
|
blockLength: 64,
|
|
digestLength: 20,
|
|
messageLength: 0,
|
|
fullMessageLength: null,
|
|
messageLengthSize: 8
|
|
};
|
|
return s.start = function() {
|
|
s.messageLength = 0,
|
|
s.fullMessageLength = s.messageLength64 = [];
|
|
for (var r = s.messageLengthSize / 4, a = 0; a < r; ++a)
|
|
s.fullMessageLength.push(0);
|
|
return t = i.util.createBuffer(),
|
|
e = {
|
|
h0: 1732584193,
|
|
h1: 4023233417,
|
|
h2: 2562383102,
|
|
h3: 271733878,
|
|
h4: 3285377520
|
|
},
|
|
s
|
|
}
|
|
,
|
|
s.start(),
|
|
s.update = function(a, o) {
|
|
"utf8" === o && (a = i.util.encodeUtf8(a));
|
|
var c = a.length;
|
|
s.messageLength += c,
|
|
c = [c / 4294967296 >>> 0, c >>> 0];
|
|
for (var u = s.fullMessageLength.length - 1; u >= 0; --u)
|
|
s.fullMessageLength[u] += c[1],
|
|
c[1] = c[0] + (s.fullMessageLength[u] / 4294967296 >>> 0),
|
|
s.fullMessageLength[u] = s.fullMessageLength[u] >>> 0,
|
|
c[0] = c[1] / 4294967296 >>> 0;
|
|
return t.putBytes(a),
|
|
n(e, r, t),
|
|
(t.read > 2048 || 0 === t.length()) && t.compact(),
|
|
s
|
|
}
|
|
,
|
|
s.digest = function() {
|
|
var a = i.util.createBuffer();
|
|
a.putBytes(t.bytes());
|
|
var c = s.fullMessageLength[s.fullMessageLength.length - 1] + s.messageLengthSize
|
|
, u = c & s.blockLength - 1;
|
|
a.putBytes(o.substr(0, s.blockLength - u));
|
|
for (var l, p, f = 8 * s.fullMessageLength[0], h = 0; h < s.fullMessageLength.length - 1; ++h)
|
|
l = 8 * s.fullMessageLength[h + 1],
|
|
p = l / 4294967296 >>> 0,
|
|
f += p,
|
|
a.putInt32(f >>> 0),
|
|
f = l >>> 0;
|
|
a.putInt32(f);
|
|
var d = {
|
|
h0: e.h0,
|
|
h1: e.h1,
|
|
h2: e.h2,
|
|
h3: e.h3,
|
|
h4: e.h4
|
|
};
|
|
n(d, r, a);
|
|
var y = i.util.createBuffer();
|
|
return y.putInt32(d.h0),
|
|
y.putInt32(d.h1),
|
|
y.putInt32(d.h2),
|
|
y.putInt32(d.h3),
|
|
y.putInt32(d.h4),
|
|
y
|
|
}
|
|
,
|
|
s
|
|
}
|
|
;
|
|
var o = null
|
|
, c = !1
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t) {
|
|
var r = function() {
|
|
return new o.des.Algorithm(e,t)
|
|
};
|
|
o.cipher.registerAlgorithm(e, r)
|
|
}
|
|
function n(e) {
|
|
for (var t, r = [0, 4, 536870912, 536870916, 65536, 65540, 536936448, 536936452, 512, 516, 536871424, 536871428, 66048, 66052, 536936960, 536936964], a = [0, 1, 1048576, 1048577, 67108864, 67108865, 68157440, 68157441, 256, 257, 1048832, 1048833, 67109120, 67109121, 68157696, 68157697], n = [0, 8, 2048, 2056, 16777216, 16777224, 16779264, 16779272, 0, 8, 2048, 2056, 16777216, 16777224, 16779264, 16779272], i = [0, 2097152, 134217728, 136314880, 8192, 2105344, 134225920, 136323072, 131072, 2228224, 134348800, 136445952, 139264, 2236416, 134356992, 136454144], s = [0, 262144, 16, 262160, 0, 262144, 16, 262160, 4096, 266240, 4112, 266256, 4096, 266240, 4112, 266256], o = [0, 1024, 32, 1056, 0, 1024, 32, 1056, 33554432, 33555456, 33554464, 33555488, 33554432, 33555456, 33554464, 33555488], c = [0, 268435456, 524288, 268959744, 2, 268435458, 524290, 268959746, 0, 268435456, 524288, 268959744, 2, 268435458, 524290, 268959746], u = [0, 65536, 2048, 67584, 536870912, 536936448, 536872960, 536938496, 131072, 196608, 133120, 198656, 537001984, 537067520, 537004032, 537069568], l = [0, 262144, 0, 262144, 2, 262146, 2, 262146, 33554432, 33816576, 33554432, 33816576, 33554434, 33816578, 33554434, 33816578], p = [0, 268435456, 8, 268435464, 0, 268435456, 8, 268435464, 1024, 268436480, 1032, 268436488, 1024, 268436480, 1032, 268436488], f = [0, 32, 0, 32, 1048576, 1048608, 1048576, 1048608, 8192, 8224, 8192, 8224, 1056768, 1056800, 1056768, 1056800], h = [0, 16777216, 512, 16777728, 2097152, 18874368, 2097664, 18874880, 67108864, 83886080, 67109376, 83886592, 69206016, 85983232, 69206528, 85983744], d = [0, 4096, 134217728, 134221824, 524288, 528384, 134742016, 134746112, 16, 4112, 134217744, 134221840, 524304, 528400, 134742032, 134746128], y = [0, 4, 256, 260, 0, 4, 256, 260, 1, 5, 257, 261, 1, 5, 257, 261], g = e.length() > 8 ? 3 : 1, v = [], m = [0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0], C = 0, E = 0; E < g; E++) {
|
|
var S = e.getInt32()
|
|
, T = e.getInt32();
|
|
t = 252645135 & (S >>> 4 ^ T),
|
|
T ^= t,
|
|
S ^= t << 4,
|
|
t = 65535 & (T >>> -16 ^ S),
|
|
S ^= t,
|
|
T ^= t << -16,
|
|
t = 858993459 & (S >>> 2 ^ T),
|
|
T ^= t,
|
|
S ^= t << 2,
|
|
t = 65535 & (T >>> -16 ^ S),
|
|
S ^= t,
|
|
T ^= t << -16,
|
|
t = 1431655765 & (S >>> 1 ^ T),
|
|
T ^= t,
|
|
S ^= t << 1,
|
|
t = 16711935 & (T >>> 8 ^ S),
|
|
S ^= t,
|
|
T ^= t << 8,
|
|
t = 1431655765 & (S >>> 1 ^ T),
|
|
T ^= t,
|
|
S ^= t << 1,
|
|
t = S << 8 | T >>> 20 & 240,
|
|
S = T << 24 | T << 8 & 16711680 | T >>> 8 & 65280 | T >>> 24 & 240,
|
|
T = t;
|
|
for (var I = 0; I < m.length; ++I) {
|
|
m[I] ? (S = S << 2 | S >>> 26,
|
|
T = T << 2 | T >>> 26) : (S = S << 1 | S >>> 27,
|
|
T = T << 1 | T >>> 27),
|
|
S &= -15,
|
|
T &= -15;
|
|
var b = r[S >>> 28] | a[S >>> 24 & 15] | n[S >>> 20 & 15] | i[S >>> 16 & 15] | s[S >>> 12 & 15] | o[S >>> 8 & 15] | c[S >>> 4 & 15]
|
|
, A = u[T >>> 28] | l[T >>> 24 & 15] | p[T >>> 20 & 15] | f[T >>> 16 & 15] | h[T >>> 12 & 15] | d[T >>> 8 & 15] | y[T >>> 4 & 15];
|
|
t = 65535 & (A >>> 16 ^ b),
|
|
v[C++] = b ^ t,
|
|
v[C++] = A ^ t << 16
|
|
}
|
|
}
|
|
return v
|
|
}
|
|
function i(e, t, r, a) {
|
|
var n, i = 32 === e.length ? 3 : 9;
|
|
n = 3 === i ? a ? [30, -2, -2] : [0, 32, 2] : a ? [94, 62, -2, 32, 64, 2, 30, -2, -2] : [0, 32, 2, 62, 30, -2, 64, 96, 2];
|
|
var s, o = t[0], g = t[1];
|
|
s = 252645135 & (o >>> 4 ^ g),
|
|
g ^= s,
|
|
o ^= s << 4,
|
|
s = 65535 & (o >>> 16 ^ g),
|
|
g ^= s,
|
|
o ^= s << 16,
|
|
s = 858993459 & (g >>> 2 ^ o),
|
|
o ^= s,
|
|
g ^= s << 2,
|
|
s = 16711935 & (g >>> 8 ^ o),
|
|
o ^= s,
|
|
g ^= s << 8,
|
|
s = 1431655765 & (o >>> 1 ^ g),
|
|
g ^= s,
|
|
o ^= s << 1,
|
|
o = o << 1 | o >>> 31,
|
|
g = g << 1 | g >>> 31;
|
|
for (var v = 0; v < i; v += 3) {
|
|
for (var m = n[v + 1], C = n[v + 2], E = n[v]; E != m; E += C) {
|
|
var S = g ^ e[E]
|
|
, T = (g >>> 4 | g << 28) ^ e[E + 1];
|
|
s = o,
|
|
o = g,
|
|
g = s ^ (u[S >>> 24 & 63] | p[S >>> 16 & 63] | h[S >>> 8 & 63] | y[63 & S] | c[T >>> 24 & 63] | l[T >>> 16 & 63] | f[T >>> 8 & 63] | d[63 & T])
|
|
}
|
|
s = o,
|
|
o = g,
|
|
g = s
|
|
}
|
|
o = o >>> 1 | o << 31,
|
|
g = g >>> 1 | g << 31,
|
|
s = 1431655765 & (o >>> 1 ^ g),
|
|
g ^= s,
|
|
o ^= s << 1,
|
|
s = 16711935 & (g >>> 8 ^ o),
|
|
o ^= s,
|
|
g ^= s << 8,
|
|
s = 858993459 & (g >>> 2 ^ o),
|
|
o ^= s,
|
|
g ^= s << 2,
|
|
s = 65535 & (o >>> 16 ^ g),
|
|
g ^= s,
|
|
o ^= s << 16,
|
|
s = 252645135 & (o >>> 4 ^ g),
|
|
g ^= s,
|
|
o ^= s << 4,
|
|
r[0] = o,
|
|
r[1] = g
|
|
}
|
|
function s(e) {
|
|
e = e || {};
|
|
var t, r = (e.mode || "CBC").toUpperCase(), a = "DES-" + r;
|
|
t = e.decrypt ? o.cipher.createDecipher(a, e.key) : o.cipher.createCipher(a, e.key);
|
|
var n = t.start;
|
|
return t.start = function(e, r) {
|
|
var a = null;
|
|
r instanceof o.util.ByteBuffer && (a = r,
|
|
r = {}),
|
|
r = r || {},
|
|
r.output = a,
|
|
r.iv = e,
|
|
n.call(t, r)
|
|
}
|
|
,
|
|
t
|
|
}
|
|
var o = r(0);
|
|
r(13),
|
|
r(19),
|
|
r(1),
|
|
e.exports = o.des = o.des || {},
|
|
o.des.startEncrypting = function(e, t, r, a) {
|
|
var n = s({
|
|
key: e,
|
|
output: r,
|
|
decrypt: !1,
|
|
mode: a || (null === t ? "ECB" : "CBC")
|
|
});
|
|
return n.start(t),
|
|
n
|
|
}
|
|
,
|
|
o.des.createEncryptionCipher = function(e, t) {
|
|
return s({
|
|
key: e,
|
|
output: null,
|
|
decrypt: !1,
|
|
mode: t
|
|
})
|
|
}
|
|
,
|
|
o.des.startDecrypting = function(e, t, r, a) {
|
|
var n = s({
|
|
key: e,
|
|
output: r,
|
|
decrypt: !0,
|
|
mode: a || (null === t ? "ECB" : "CBC")
|
|
});
|
|
return n.start(t),
|
|
n
|
|
}
|
|
,
|
|
o.des.createDecryptionCipher = function(e, t) {
|
|
return s({
|
|
key: e,
|
|
output: null,
|
|
decrypt: !0,
|
|
mode: t
|
|
})
|
|
}
|
|
,
|
|
o.des.Algorithm = function(e, t) {
|
|
var r = this;
|
|
r.name = e,
|
|
r.mode = new t({
|
|
blockSize: 8,
|
|
cipher: {
|
|
encrypt: function(e, t) {
|
|
return i(r._keys, e, t, !1)
|
|
},
|
|
decrypt: function(e, t) {
|
|
return i(r._keys, e, t, !0)
|
|
}
|
|
}
|
|
}),
|
|
r._init = !1
|
|
}
|
|
,
|
|
o.des.Algorithm.prototype.initialize = function(e) {
|
|
if (!this._init) {
|
|
var t = o.util.createBuffer(e.key);
|
|
if (0 === this.name.indexOf("3DES") && 24 !== t.length())
|
|
throw new Error("Invalid Triple-DES key size: " + 8 * t.length());
|
|
this._keys = n(t),
|
|
this._init = !0
|
|
}
|
|
}
|
|
,
|
|
a("DES-ECB", o.cipher.modes.ecb),
|
|
a("DES-CBC", o.cipher.modes.cbc),
|
|
a("DES-CFB", o.cipher.modes.cfb),
|
|
a("DES-OFB", o.cipher.modes.ofb),
|
|
a("DES-CTR", o.cipher.modes.ctr),
|
|
a("3DES-ECB", o.cipher.modes.ecb),
|
|
a("3DES-CBC", o.cipher.modes.cbc),
|
|
a("3DES-CFB", o.cipher.modes.cfb),
|
|
a("3DES-OFB", o.cipher.modes.ofb),
|
|
a("3DES-CTR", o.cipher.modes.ctr);
|
|
var c = [16843776, 0, 65536, 16843780, 16842756, 66564, 4, 65536, 1024, 16843776, 16843780, 1024, 16778244, 16842756, 16777216, 4, 1028, 16778240, 16778240, 66560, 66560, 16842752, 16842752, 16778244, 65540, 16777220, 16777220, 65540, 0, 1028, 66564, 16777216, 65536, 16843780, 4, 16842752, 16843776, 16777216, 16777216, 1024, 16842756, 65536, 66560, 16777220, 1024, 4, 16778244, 66564, 16843780, 65540, 16842752, 16778244, 16777220, 1028, 66564, 16843776, 1028, 16778240, 16778240, 0, 65540, 66560, 0, 16842756]
|
|
, u = [-2146402272, -2147450880, 32768, 1081376, 1048576, 32, -2146435040, -2147450848, -2147483616, -2146402272, -2146402304, -2147483648, -2147450880, 1048576, 32, -2146435040, 1081344, 1048608, -2147450848, 0, -2147483648, 32768, 1081376, -2146435072, 1048608, -2147483616, 0, 1081344, 32800, -2146402304, -2146435072, 32800, 0, 1081376, -2146435040, 1048576, -2147450848, -2146435072, -2146402304, 32768, -2146435072, -2147450880, 32, -2146402272, 1081376, 32, 32768, -2147483648, 32800, -2146402304, 1048576, -2147483616, 1048608, -2147450848, -2147483616, 1048608, 1081344, 0, -2147450880, 32800, -2147483648, -2146435040, -2146402272, 1081344]
|
|
, l = [520, 134349312, 0, 134348808, 134218240, 0, 131592, 134218240, 131080, 134217736, 134217736, 131072, 134349320, 131080, 134348800, 520, 134217728, 8, 134349312, 512, 131584, 134348800, 134348808, 131592, 134218248, 131584, 131072, 134218248, 8, 134349320, 512, 134217728, 134349312, 134217728, 131080, 520, 131072, 134349312, 134218240, 0, 512, 131080, 134349320, 134218240, 134217736, 512, 0, 134348808, 134218248, 131072, 134217728, 134349320, 8, 131592, 131584, 134217736, 134348800, 134218248, 520, 134348800, 131592, 8, 134348808, 131584]
|
|
, p = [8396801, 8321, 8321, 128, 8396928, 8388737, 8388609, 8193, 0, 8396800, 8396800, 8396929, 129, 0, 8388736, 8388609, 1, 8192, 8388608, 8396801, 128, 8388608, 8193, 8320, 8388737, 1, 8320, 8388736, 8192, 8396928, 8396929, 129, 8388736, 8388609, 8396800, 8396929, 129, 0, 0, 8396800, 8320, 8388736, 8388737, 1, 8396801, 8321, 8321, 128, 8396929, 129, 1, 8192, 8388609, 8193, 8396928, 8388737, 8193, 8320, 8388608, 8396801, 128, 8388608, 8192, 8396928]
|
|
, f = [256, 34078976, 34078720, 1107296512, 524288, 256, 1073741824, 34078720, 1074266368, 524288, 33554688, 1074266368, 1107296512, 1107820544, 524544, 1073741824, 33554432, 1074266112, 1074266112, 0, 1073742080, 1107820800, 1107820800, 33554688, 1107820544, 1073742080, 0, 1107296256, 34078976, 33554432, 1107296256, 524544, 524288, 1107296512, 256, 33554432, 1073741824, 34078720, 1107296512, 1074266368, 33554688, 1073741824, 1107820544, 34078976, 1074266368, 256, 33554432, 1107820544, 1107820800, 524544, 1107296256, 1107820800, 34078720, 0, 1074266112, 1107296256, 524544, 33554688, 1073742080, 524288, 0, 1074266112, 34078976, 1073742080]
|
|
, h = [536870928, 541065216, 16384, 541081616, 541065216, 16, 541081616, 4194304, 536887296, 4210704, 4194304, 536870928, 4194320, 536887296, 536870912, 16400, 0, 4194320, 536887312, 16384, 4210688, 536887312, 16, 541065232, 541065232, 0, 4210704, 541081600, 16400, 4210688, 541081600, 536870912, 536887296, 16, 541065232, 4210688, 541081616, 4194304, 16400, 536870928, 4194304, 536887296, 536870912, 16400, 536870928, 541081616, 4210688, 541065216, 4210704, 541081600, 0, 541065232, 16, 16384, 541065216, 4210704, 16384, 4194320, 536887312, 0, 541081600, 536870912, 4194320, 536887312]
|
|
, d = [2097152, 69206018, 67110914, 0, 2048, 67110914, 2099202, 69208064, 69208066, 2097152, 0, 67108866, 2, 67108864, 69206018, 2050, 67110912, 2099202, 2097154, 67110912, 67108866, 69206016, 69208064, 2097154, 69206016, 2048, 2050, 69208066, 2099200, 2, 67108864, 2099200, 67108864, 2099200, 2097152, 67110914, 67110914, 69206018, 69206018, 2, 2097154, 67108864, 67110912, 2097152, 69208064, 2050, 2099202, 69208064, 2050, 67108866, 69208066, 69206016, 2099200, 0, 2, 69208066, 0, 2099202, 69206016, 2048, 67108866, 67110912, 2048, 2097154]
|
|
, y = [268439616, 4096, 262144, 268701760, 268435456, 268439616, 64, 268435456, 262208, 268697600, 268701760, 266240, 268701696, 266304, 4096, 64, 268697600, 268435520, 268439552, 4160, 266240, 262208, 268697664, 268701696, 4160, 0, 0, 268697664, 268435520, 268439552, 266304, 262144, 266304, 262144, 268701696, 4096, 64, 268697664, 4096, 266304, 268439552, 64, 268435520, 268697600, 268697664, 268435456, 262144, 268439616, 0, 268701760, 262208, 268435520, 268697600, 268439552, 268439616, 0, 268701760, 266240, 266240, 4160, 4160, 262208, 268435456, 268701696]
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t, r) {
|
|
var a = f.util.createBuffer()
|
|
, n = Math.ceil(t.n.bitLength() / 8);
|
|
if (e.length > n - 11) {
|
|
var i = new Error("Message is too long for PKCS#1 v1.5 padding.");
|
|
throw i.length = e.length,
|
|
i.max = n - 11,
|
|
i
|
|
}
|
|
a.putByte(0),
|
|
a.putByte(r);
|
|
var s, o = n - 3 - e.length;
|
|
if (0 === r || 1 === r) {
|
|
s = 0 === r ? 0 : 255;
|
|
for (var c = 0; c < o; ++c)
|
|
a.putByte(s)
|
|
} else
|
|
for (; o > 0; ) {
|
|
for (var u = 0, l = f.random.getBytes(o), c = 0; c < o; ++c)
|
|
s = l.charCodeAt(c),
|
|
0 === s ? ++u : a.putByte(s);
|
|
o = u
|
|
}
|
|
return a.putByte(0),
|
|
a.putBytes(e),
|
|
a
|
|
}
|
|
function n(e, t, r, a) {
|
|
var n = Math.ceil(t.n.bitLength() / 8)
|
|
, i = f.util.createBuffer(e)
|
|
, s = i.getByte()
|
|
, o = i.getByte();
|
|
if (0 !== s || r && 0 !== o && 1 !== o || !r && 2 != o || r && 0 === o && void 0 === a)
|
|
throw new Error("Encryption block is invalid.");
|
|
var c = 0;
|
|
if (0 === o) {
|
|
c = n - 3 - a;
|
|
for (var u = 0; u < c; ++u)
|
|
if (0 !== i.getByte())
|
|
throw new Error("Encryption block is invalid.")
|
|
} else if (1 === o)
|
|
for (c = 0; i.length() > 1; ) {
|
|
if (255 !== i.getByte()) {
|
|
--i.read;
|
|
break
|
|
}
|
|
++c
|
|
}
|
|
else if (2 === o)
|
|
for (c = 0; i.length() > 1; ) {
|
|
if (0 === i.getByte()) {
|
|
--i.read;
|
|
break
|
|
}
|
|
++c
|
|
}
|
|
if (0 !== i.getByte() || c !== n - 3 - i.length())
|
|
throw new Error("Encryption block is invalid.");
|
|
return i.getBytes()
|
|
}
|
|
function i(e, t, r) {
|
|
function a() {
|
|
n(e.pBits, function(t, a) {
|
|
return t ? r(t) : (e.p = a,
|
|
null !== e.q ? i(t, e.q) : void n(e.qBits, i))
|
|
})
|
|
}
|
|
function n(e, t) {
|
|
f.prime.generateProbablePrime(e, s, t)
|
|
}
|
|
function i(t, s) {
|
|
if (t)
|
|
return r(t);
|
|
if (e.q = s,
|
|
e.p.compareTo(e.q) < 0) {
|
|
var o = e.p;
|
|
e.p = e.q,
|
|
e.q = o
|
|
}
|
|
if (0 !== e.p.subtract(h.ONE).gcd(e.e).compareTo(h.ONE))
|
|
return e.p = null,
|
|
void a();
|
|
if (0 !== e.q.subtract(h.ONE).gcd(e.e).compareTo(h.ONE))
|
|
return e.q = null,
|
|
void n(e.qBits, i);
|
|
if (e.p1 = e.p.subtract(h.ONE),
|
|
e.q1 = e.q.subtract(h.ONE),
|
|
e.phi = e.p1.multiply(e.q1),
|
|
0 !== e.phi.gcd(e.e).compareTo(h.ONE))
|
|
return e.p = e.q = null,
|
|
void a();
|
|
if (e.n = e.p.multiply(e.q),
|
|
e.n.bitLength() !== e.bits)
|
|
return e.q = null,
|
|
void n(e.qBits, i);
|
|
var c = e.e.modInverse(e.phi);
|
|
e.keys = {
|
|
privateKey: v.rsa.setPrivateKey(e.n, e.e, c, e.p, e.q, c.mod(e.p1), c.mod(e.q1), e.q.modInverse(e.p)),
|
|
publicKey: v.rsa.setPublicKey(e.n, e.e)
|
|
},
|
|
r(null, e.keys)
|
|
}
|
|
"function" == typeof t && (r = t,
|
|
t = {}),
|
|
t = t || {};
|
|
var s = {
|
|
algorithm: {
|
|
name: t.algorithm || "PRIMEINC",
|
|
options: {
|
|
workers: t.workers || 2,
|
|
workLoad: t.workLoad || 100,
|
|
workerScript: t.workerScript
|
|
}
|
|
}
|
|
};
|
|
"prng"in t && (s.prng = t.prng),
|
|
a()
|
|
}
|
|
function s(e) {
|
|
var t = e.toString(16);
|
|
t[0] >= "8" && (t = "00" + t);
|
|
var r = f.util.hexToBytes(t);
|
|
return r.length > 1 && (0 === r.charCodeAt(0) && 0 == (128 & r.charCodeAt(1)) || 255 === r.charCodeAt(0) && 128 == (128 & r.charCodeAt(1))) ? r.substr(1) : r
|
|
}
|
|
function o(e) {
|
|
return e <= 100 ? 27 : e <= 150 ? 18 : e <= 200 ? 15 : e <= 250 ? 12 : e <= 300 ? 9 : e <= 350 ? 8 : e <= 400 ? 7 : e <= 500 ? 6 : e <= 600 ? 5 : e <= 800 ? 4 : e <= 1250 ? 3 : 2
|
|
}
|
|
function c(e) {
|
|
return f.util.isNodejs && "function" == typeof d[e]
|
|
}
|
|
function u(e) {
|
|
return void 0 !== g.globalScope && "object" == typeof g.globalScope.crypto && "object" == typeof g.globalScope.crypto.subtle && "function" == typeof g.globalScope.crypto.subtle[e]
|
|
}
|
|
function l(e) {
|
|
return void 0 !== g.globalScope && "object" == typeof g.globalScope.msCrypto && "object" == typeof g.globalScope.msCrypto.subtle && "function" == typeof g.globalScope.msCrypto.subtle[e]
|
|
}
|
|
function p(e) {
|
|
for (var t = f.util.hexToBytes(e.toString(16)), r = new Uint8Array(t.length), a = 0; a < t.length; ++a)
|
|
r[a] = t.charCodeAt(a);
|
|
return r
|
|
}
|
|
var f = r(0);
|
|
if (r(3),
|
|
r(12),
|
|
r(6),
|
|
r(26),
|
|
r(27),
|
|
r(2),
|
|
r(1),
|
|
void 0 === h)
|
|
var h = f.jsbn.BigInteger;
|
|
var d = f.util.isNodejs ? r(16) : null
|
|
, y = f.asn1
|
|
, g = f.util;
|
|
f.pki = f.pki || {},
|
|
e.exports = f.pki.rsa = f.rsa = f.rsa || {};
|
|
var v = f.pki
|
|
, m = [6, 4, 2, 4, 2, 4, 6, 2]
|
|
, C = {
|
|
name: "PrivateKeyInfo",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "PrivateKeyInfo.version",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "privateKeyVersion"
|
|
}, {
|
|
name: "PrivateKeyInfo.privateKeyAlgorithm",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "AlgorithmIdentifier.algorithm",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.OID,
|
|
constructed: !1,
|
|
capture: "privateKeyOid"
|
|
}]
|
|
}, {
|
|
name: "PrivateKeyInfo",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.OCTETSTRING,
|
|
constructed: !1,
|
|
capture: "privateKey"
|
|
}]
|
|
}
|
|
, E = {
|
|
name: "RSAPrivateKey",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "RSAPrivateKey.version",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "privateKeyVersion"
|
|
}, {
|
|
name: "RSAPrivateKey.modulus",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "privateKeyModulus"
|
|
}, {
|
|
name: "RSAPrivateKey.publicExponent",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "privateKeyPublicExponent"
|
|
}, {
|
|
name: "RSAPrivateKey.privateExponent",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "privateKeyPrivateExponent"
|
|
}, {
|
|
name: "RSAPrivateKey.prime1",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "privateKeyPrime1"
|
|
}, {
|
|
name: "RSAPrivateKey.prime2",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "privateKeyPrime2"
|
|
}, {
|
|
name: "RSAPrivateKey.exponent1",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "privateKeyExponent1"
|
|
}, {
|
|
name: "RSAPrivateKey.exponent2",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "privateKeyExponent2"
|
|
}, {
|
|
name: "RSAPrivateKey.coefficient",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "privateKeyCoefficient"
|
|
}]
|
|
}
|
|
, S = {
|
|
name: "RSAPublicKey",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "RSAPublicKey.modulus",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "publicKeyModulus"
|
|
}, {
|
|
name: "RSAPublicKey.exponent",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "publicKeyExponent"
|
|
}]
|
|
}
|
|
, T = f.pki.rsa.publicKeyValidator = {
|
|
name: "SubjectPublicKeyInfo",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.SEQUENCE,
|
|
constructed: !0,
|
|
captureAsn1: "subjectPublicKeyInfo",
|
|
value: [{
|
|
name: "SubjectPublicKeyInfo.AlgorithmIdentifier",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "AlgorithmIdentifier.algorithm",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.OID,
|
|
constructed: !1,
|
|
capture: "publicKeyOid"
|
|
}]
|
|
}, {
|
|
name: "SubjectPublicKeyInfo.subjectPublicKey",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.BITSTRING,
|
|
constructed: !1,
|
|
value: [{
|
|
name: "SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey",
|
|
tagClass: y.Class.UNIVERSAL,
|
|
type: y.Type.SEQUENCE,
|
|
constructed: !0,
|
|
optional: !0,
|
|
captureAsn1: "rsaPublicKey"
|
|
}]
|
|
}]
|
|
}
|
|
, I = function(e) {
|
|
var t;
|
|
if (!(e.algorithm in v.oids)) {
|
|
var r = new Error("Unknown message digest algorithm.");
|
|
throw r.algorithm = e.algorithm,
|
|
r
|
|
}
|
|
t = v.oids[e.algorithm];
|
|
var a = y.oidToDer(t).getBytes()
|
|
, n = y.create(y.Class.UNIVERSAL, y.Type.SEQUENCE, !0, [])
|
|
, i = y.create(y.Class.UNIVERSAL, y.Type.SEQUENCE, !0, []);
|
|
i.value.push(y.create(y.Class.UNIVERSAL, y.Type.OID, !1, a)),
|
|
i.value.push(y.create(y.Class.UNIVERSAL, y.Type.NULL, !1, ""));
|
|
var s = y.create(y.Class.UNIVERSAL, y.Type.OCTETSTRING, !1, e.digest().getBytes());
|
|
return n.value.push(i),
|
|
n.value.push(s),
|
|
y.toDer(n).getBytes()
|
|
}
|
|
, b = function(e, t, r) {
|
|
if (r)
|
|
return e.modPow(t.e, t.n);
|
|
if (!t.p || !t.q)
|
|
return e.modPow(t.d, t.n);
|
|
t.dP || (t.dP = t.d.mod(t.p.subtract(h.ONE))),
|
|
t.dQ || (t.dQ = t.d.mod(t.q.subtract(h.ONE))),
|
|
t.qInv || (t.qInv = t.q.modInverse(t.p));
|
|
var a;
|
|
do {
|
|
a = new h(f.util.bytesToHex(f.random.getBytes(t.n.bitLength() / 8)),16)
|
|
} while (a.compareTo(t.n) >= 0 || !a.gcd(t.n).equals(h.ONE));
|
|
e = e.multiply(a.modPow(t.e, t.n)).mod(t.n);
|
|
for (var n = e.mod(t.p).modPow(t.dP, t.p), i = e.mod(t.q).modPow(t.dQ, t.q); n.compareTo(i) < 0; )
|
|
n = n.add(t.p);
|
|
var s = n.subtract(i).multiply(t.qInv).mod(t.p).multiply(t.q).add(i);
|
|
return s = s.multiply(a.modInverse(t.n)).mod(t.n)
|
|
};
|
|
v.rsa.encrypt = function(e, t, r) {
|
|
var n, i = r, s = Math.ceil(t.n.bitLength() / 8);
|
|
!1 !== r && !0 !== r ? (i = 2 === r,
|
|
n = a(e, t, r)) : (n = f.util.createBuffer(),
|
|
n.putBytes(e));
|
|
for (var o = new h(n.toHex(),16), c = b(o, t, i), u = c.toString(16), l = f.util.createBuffer(), p = s - Math.ceil(u.length / 2); p > 0; )
|
|
l.putByte(0),
|
|
--p;
|
|
return l.putBytes(f.util.hexToBytes(u)),
|
|
l.getBytes()
|
|
}
|
|
,
|
|
v.rsa.decrypt = function(e, t, r, a) {
|
|
var i = Math.ceil(t.n.bitLength() / 8);
|
|
if (e.length !== i) {
|
|
var s = new Error("Encrypted message length is invalid.");
|
|
throw s.length = e.length,
|
|
s.expected = i,
|
|
s
|
|
}
|
|
var o = new h(f.util.createBuffer(e).toHex(),16);
|
|
if (o.compareTo(t.n) >= 0)
|
|
throw new Error("Encrypted message is invalid.");
|
|
for (var c = b(o, t, r), u = c.toString(16), l = f.util.createBuffer(), p = i - Math.ceil(u.length / 2); p > 0; )
|
|
l.putByte(0),
|
|
--p;
|
|
return l.putBytes(f.util.hexToBytes(u)),
|
|
!1 !== a ? n(l.getBytes(), t, r) : l.getBytes()
|
|
}
|
|
,
|
|
v.rsa.createKeyPairGenerationState = function(e, t, r) {
|
|
"string" == typeof e && (e = parseInt(e, 10)),
|
|
e = e || 2048,
|
|
r = r || {};
|
|
var a, n = r.prng || f.random, i = {
|
|
nextBytes: function(e) {
|
|
for (var t = n.getBytesSync(e.length), r = 0; r < e.length; ++r)
|
|
e[r] = t.charCodeAt(r)
|
|
}
|
|
}, s = r.algorithm || "PRIMEINC";
|
|
if ("PRIMEINC" !== s)
|
|
throw new Error("Invalid key generation algorithm: " + s);
|
|
return a = {
|
|
algorithm: s,
|
|
state: 0,
|
|
bits: e,
|
|
rng: i,
|
|
eInt: t || 65537,
|
|
e: new h(null),
|
|
p: null,
|
|
q: null,
|
|
qBits: e >> 1,
|
|
pBits: e - (e >> 1),
|
|
pqState: 0,
|
|
num: null,
|
|
keys: null
|
|
},
|
|
a.e.fromInt(a.eInt),
|
|
a
|
|
}
|
|
,
|
|
v.rsa.stepKeyPairGenerationState = function(e, t) {
|
|
"algorithm"in e || (e.algorithm = "PRIMEINC");
|
|
var r = new h(null);
|
|
r.fromInt(30);
|
|
for (var a, n = 0, i = function(e, t) {
|
|
return e | t
|
|
}, s = +new Date, c = 0; null === e.keys && (t <= 0 || c < t); ) {
|
|
if (0 === e.state) {
|
|
var u = null === e.p ? e.pBits : e.qBits
|
|
, l = u - 1;
|
|
0 === e.pqState ? (e.num = new h(u,e.rng),
|
|
e.num.testBit(l) || e.num.bitwiseTo(h.ONE.shiftLeft(l), i, e.num),
|
|
e.num.dAddOffset(31 - e.num.mod(r).byteValue(), 0),
|
|
n = 0,
|
|
++e.pqState) : 1 === e.pqState ? e.num.bitLength() > u ? e.pqState = 0 : e.num.isProbablePrime(o(e.num.bitLength())) ? ++e.pqState : e.num.dAddOffset(m[n++ % 8], 0) : 2 === e.pqState ? e.pqState = 0 === e.num.subtract(h.ONE).gcd(e.e).compareTo(h.ONE) ? 3 : 0 : 3 === e.pqState && (e.pqState = 0,
|
|
null === e.p ? e.p = e.num : e.q = e.num,
|
|
null !== e.p && null !== e.q && ++e.state,
|
|
e.num = null)
|
|
} else if (1 === e.state)
|
|
e.p.compareTo(e.q) < 0 && (e.num = e.p,
|
|
e.p = e.q,
|
|
e.q = e.num),
|
|
++e.state;
|
|
else if (2 === e.state)
|
|
e.p1 = e.p.subtract(h.ONE),
|
|
e.q1 = e.q.subtract(h.ONE),
|
|
e.phi = e.p1.multiply(e.q1),
|
|
++e.state;
|
|
else if (3 === e.state)
|
|
0 === e.phi.gcd(e.e).compareTo(h.ONE) ? ++e.state : (e.p = null,
|
|
e.q = null,
|
|
e.state = 0);
|
|
else if (4 === e.state)
|
|
e.n = e.p.multiply(e.q),
|
|
e.n.bitLength() === e.bits ? ++e.state : (e.q = null,
|
|
e.state = 0);
|
|
else if (5 === e.state) {
|
|
var p = e.e.modInverse(e.phi);
|
|
e.keys = {
|
|
privateKey: v.rsa.setPrivateKey(e.n, e.e, p, e.p, e.q, p.mod(e.p1), p.mod(e.q1), e.q.modInverse(e.p)),
|
|
publicKey: v.rsa.setPublicKey(e.n, e.e)
|
|
}
|
|
}
|
|
a = +new Date,
|
|
c += a - s,
|
|
s = a
|
|
}
|
|
return null !== e.keys
|
|
}
|
|
,
|
|
v.rsa.generateKeyPair = function(e, t, r, a) {
|
|
if (1 === arguments.length ? "object" == typeof e ? (r = e,
|
|
e = void 0) : "function" == typeof e && (a = e,
|
|
e = void 0) : 2 === arguments.length ? "number" == typeof e ? "function" == typeof t ? (a = t,
|
|
t = void 0) : "number" != typeof t && (r = t,
|
|
t = void 0) : (r = e,
|
|
a = t,
|
|
e = void 0,
|
|
t = void 0) : 3 === arguments.length && ("number" == typeof t ? "function" == typeof r && (a = r,
|
|
r = void 0) : (a = r,
|
|
r = t,
|
|
t = void 0)),
|
|
r = r || {},
|
|
void 0 === e && (e = r.bits || 2048),
|
|
void 0 === t && (t = r.e || 65537),
|
|
!f.options.usePureJavaScript && !r.prng && e >= 256 && e <= 16384 && (65537 === t || 3 === t))
|
|
if (a) {
|
|
if (c("generateKeyPair"))
|
|
return d.generateKeyPair("rsa", {
|
|
modulusLength: e,
|
|
publicExponent: t,
|
|
publicKeyEncoding: {
|
|
type: "spki",
|
|
format: "pem"
|
|
},
|
|
privateKeyEncoding: {
|
|
type: "pkcs8",
|
|
format: "pem"
|
|
}
|
|
}, function(e, t, r) {
|
|
if (e)
|
|
return a(e);
|
|
a(null, {
|
|
privateKey: v.privateKeyFromPem(r),
|
|
publicKey: v.publicKeyFromPem(t)
|
|
})
|
|
});
|
|
if (u("generateKey") && u("exportKey"))
|
|
return g.globalScope.crypto.subtle.generateKey({
|
|
name: "RSASSA-PKCS1-v1_5",
|
|
modulusLength: e,
|
|
publicExponent: p(t),
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
}, !0, ["sign", "verify"]).then(function(e) {
|
|
return g.globalScope.crypto.subtle.exportKey("pkcs8", e.privateKey)
|
|
}).then(void 0, function(e) {
|
|
a(e)
|
|
}).then(function(e) {
|
|
if (e) {
|
|
var t = v.privateKeyFromAsn1(y.fromDer(f.util.createBuffer(e)));
|
|
a(null, {
|
|
privateKey: t,
|
|
publicKey: v.setRsaPublicKey(t.n, t.e)
|
|
})
|
|
}
|
|
});
|
|
if (l("generateKey") && l("exportKey")) {
|
|
var n = g.globalScope.msCrypto.subtle.generateKey({
|
|
name: "RSASSA-PKCS1-v1_5",
|
|
modulusLength: e,
|
|
publicExponent: p(t),
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
}, !0, ["sign", "verify"]);
|
|
return n.oncomplete = function(e) {
|
|
var t = e.target.result
|
|
, r = g.globalScope.msCrypto.subtle.exportKey("pkcs8", t.privateKey);
|
|
r.oncomplete = function(e) {
|
|
var t = e.target.result
|
|
, r = v.privateKeyFromAsn1(y.fromDer(f.util.createBuffer(t)));
|
|
a(null, {
|
|
privateKey: r,
|
|
publicKey: v.setRsaPublicKey(r.n, r.e)
|
|
})
|
|
}
|
|
,
|
|
r.onerror = function(e) {
|
|
a(e)
|
|
}
|
|
}
|
|
,
|
|
void (n.onerror = function(e) {
|
|
a(e)
|
|
}
|
|
)
|
|
}
|
|
} else if (c("generateKeyPairSync")) {
|
|
var s = d.generateKeyPairSync("rsa", {
|
|
modulusLength: e,
|
|
publicExponent: t,
|
|
publicKeyEncoding: {
|
|
type: "spki",
|
|
format: "pem"
|
|
},
|
|
privateKeyEncoding: {
|
|
type: "pkcs8",
|
|
format: "pem"
|
|
}
|
|
});
|
|
return {
|
|
privateKey: v.privateKeyFromPem(s.privateKey),
|
|
publicKey: v.publicKeyFromPem(s.publicKey)
|
|
}
|
|
}
|
|
var o = v.rsa.createKeyPairGenerationState(e, t, r);
|
|
if (!a)
|
|
return v.rsa.stepKeyPairGenerationState(o, 0),
|
|
o.keys;
|
|
i(o, r, a)
|
|
}
|
|
,
|
|
v.setRsaPublicKey = v.rsa.setPublicKey = function(e, t) {
|
|
var r = {
|
|
n: e,
|
|
e: t
|
|
};
|
|
return r.encrypt = function(e, t, n) {
|
|
if ("string" == typeof t ? t = t.toUpperCase() : void 0 === t && (t = "RSAES-PKCS1-V1_5"),
|
|
"RSAES-PKCS1-V1_5" === t)
|
|
t = {
|
|
encode: function(e, t, r) {
|
|
return a(e, t, 2).getBytes()
|
|
}
|
|
};
|
|
else if ("RSA-OAEP" === t || "RSAES-OAEP" === t)
|
|
t = {
|
|
encode: function(e, t) {
|
|
return f.pkcs1.encode_rsa_oaep(t, e, n)
|
|
}
|
|
};
|
|
else if (-1 !== ["RAW", "NONE", "NULL", null].indexOf(t))
|
|
t = {
|
|
encode: function(e) {
|
|
return e
|
|
}
|
|
};
|
|
else if ("string" == typeof t)
|
|
throw new Error('Unsupported encryption scheme: "' + t + '".');
|
|
var i = t.encode(e, r, !0);
|
|
return v.rsa.encrypt(i, r, !0)
|
|
}
|
|
,
|
|
r.verify = function(e, t, a) {
|
|
"string" == typeof a ? a = a.toUpperCase() : void 0 === a && (a = "RSASSA-PKCS1-V1_5"),
|
|
"RSASSA-PKCS1-V1_5" === a ? a = {
|
|
verify: function(e, t) {
|
|
return t = n(t, r, !0),
|
|
e === y.fromDer(t).value[1].value
|
|
}
|
|
} : "NONE" !== a && "NULL" !== a && null !== a || (a = {
|
|
verify: function(e, t) {
|
|
return t = n(t, r, !0),
|
|
e === t
|
|
}
|
|
});
|
|
var i = v.rsa.decrypt(t, r, !0, !1);
|
|
return a.verify(e, i, r.n.bitLength())
|
|
}
|
|
,
|
|
r
|
|
}
|
|
,
|
|
v.setRsaPrivateKey = v.rsa.setPrivateKey = function(e, t, r, a, i, s, o, c) {
|
|
var u = {
|
|
n: e,
|
|
e: t,
|
|
d: r,
|
|
p: a,
|
|
q: i,
|
|
dP: s,
|
|
dQ: o,
|
|
qInv: c
|
|
};
|
|
return u.decrypt = function(e, t, r) {
|
|
"string" == typeof t ? t = t.toUpperCase() : void 0 === t && (t = "RSAES-PKCS1-V1_5");
|
|
var a = v.rsa.decrypt(e, u, !1, !1);
|
|
if ("RSAES-PKCS1-V1_5" === t)
|
|
t = {
|
|
decode: n
|
|
};
|
|
else if ("RSA-OAEP" === t || "RSAES-OAEP" === t)
|
|
t = {
|
|
decode: function(e, t) {
|
|
return f.pkcs1.decode_rsa_oaep(t, e, r)
|
|
}
|
|
};
|
|
else {
|
|
if (-1 === ["RAW", "NONE", "NULL", null].indexOf(t))
|
|
throw new Error('Unsupported encryption scheme: "' + t + '".');
|
|
t = {
|
|
decode: function(e) {
|
|
return e
|
|
}
|
|
}
|
|
}
|
|
return t.decode(a, u, !1)
|
|
}
|
|
,
|
|
u.sign = function(e, t) {
|
|
var r = !1;
|
|
"string" == typeof t && (t = t.toUpperCase()),
|
|
void 0 === t || "RSASSA-PKCS1-V1_5" === t ? (t = {
|
|
encode: I
|
|
},
|
|
r = 1) : "NONE" !== t && "NULL" !== t && null !== t || (t = {
|
|
encode: function() {
|
|
return e
|
|
}
|
|
},
|
|
r = 1);
|
|
var a = t.encode(e, u.n.bitLength());
|
|
return v.rsa.encrypt(a, u, r)
|
|
}
|
|
,
|
|
u
|
|
}
|
|
,
|
|
v.wrapRsaPrivateKey = function(e) {
|
|
return y.create(y.Class.UNIVERSAL, y.Type.SEQUENCE, !0, [y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, y.integerToDer(0).getBytes()), y.create(y.Class.UNIVERSAL, y.Type.SEQUENCE, !0, [y.create(y.Class.UNIVERSAL, y.Type.OID, !1, y.oidToDer(v.oids.rsaEncryption).getBytes()), y.create(y.Class.UNIVERSAL, y.Type.NULL, !1, "")]), y.create(y.Class.UNIVERSAL, y.Type.OCTETSTRING, !1, y.toDer(e).getBytes())])
|
|
}
|
|
,
|
|
v.privateKeyFromAsn1 = function(e) {
|
|
var t = {}
|
|
, r = [];
|
|
if (y.validate(e, C, t, r) && (e = y.fromDer(f.util.createBuffer(t.privateKey))),
|
|
t = {},
|
|
r = [],
|
|
!y.validate(e, E, t, r)) {
|
|
var a = new Error("Cannot read private key. ASN.1 object does not contain an RSAPrivateKey.");
|
|
throw a.errors = r,
|
|
a
|
|
}
|
|
var n, i, s, o, c, u, l, p;
|
|
return n = f.util.createBuffer(t.privateKeyModulus).toHex(),
|
|
i = f.util.createBuffer(t.privateKeyPublicExponent).toHex(),
|
|
s = f.util.createBuffer(t.privateKeyPrivateExponent).toHex(),
|
|
o = f.util.createBuffer(t.privateKeyPrime1).toHex(),
|
|
c = f.util.createBuffer(t.privateKeyPrime2).toHex(),
|
|
u = f.util.createBuffer(t.privateKeyExponent1).toHex(),
|
|
l = f.util.createBuffer(t.privateKeyExponent2).toHex(),
|
|
p = f.util.createBuffer(t.privateKeyCoefficient).toHex(),
|
|
v.setRsaPrivateKey(new h(n,16), new h(i,16), new h(s,16), new h(o,16), new h(c,16), new h(u,16), new h(l,16), new h(p,16))
|
|
}
|
|
,
|
|
v.privateKeyToAsn1 = v.privateKeyToRSAPrivateKey = function(e) {
|
|
return y.create(y.Class.UNIVERSAL, y.Type.SEQUENCE, !0, [y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, y.integerToDer(0).getBytes()), y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, s(e.n)), y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, s(e.e)), y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, s(e.d)), y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, s(e.p)), y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, s(e.q)), y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, s(e.dP)), y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, s(e.dQ)), y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, s(e.qInv))])
|
|
}
|
|
,
|
|
v.publicKeyFromAsn1 = function(e) {
|
|
var t = {}
|
|
, r = [];
|
|
if (y.validate(e, T, t, r)) {
|
|
var a = y.derToOid(t.publicKeyOid);
|
|
if (a !== v.oids.rsaEncryption) {
|
|
var n = new Error("Cannot read public key. Unknown OID.");
|
|
throw n.oid = a,
|
|
n
|
|
}
|
|
e = t.rsaPublicKey
|
|
}
|
|
if (r = [],
|
|
!y.validate(e, S, t, r)) {
|
|
var n = new Error("Cannot read public key. ASN.1 object does not contain an RSAPublicKey.");
|
|
throw n.errors = r,
|
|
n
|
|
}
|
|
var i = f.util.createBuffer(t.publicKeyModulus).toHex()
|
|
, s = f.util.createBuffer(t.publicKeyExponent).toHex();
|
|
return v.setRsaPublicKey(new h(i,16), new h(s,16))
|
|
}
|
|
,
|
|
v.publicKeyToAsn1 = v.publicKeyToSubjectPublicKeyInfo = function(e) {
|
|
return y.create(y.Class.UNIVERSAL, y.Type.SEQUENCE, !0, [y.create(y.Class.UNIVERSAL, y.Type.SEQUENCE, !0, [y.create(y.Class.UNIVERSAL, y.Type.OID, !1, y.oidToDer(v.oids.rsaEncryption).getBytes()), y.create(y.Class.UNIVERSAL, y.Type.NULL, !1, "")]), y.create(y.Class.UNIVERSAL, y.Type.BITSTRING, !1, [v.publicKeyToRSAPublicKey(e)])])
|
|
}
|
|
,
|
|
v.publicKeyToRSAPublicKey = function(e) {
|
|
return y.create(y.Class.UNIVERSAL, y.Type.SEQUENCE, !0, [y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, s(e.n)), y.create(y.Class.UNIVERSAL, y.Type.INTEGER, !1, s(e.e))])
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t, r) {
|
|
this.data = [],
|
|
null != e && ("number" == typeof e ? this.fromNumber(e, t, r) : null == t && "string" != typeof e ? this.fromString(e, 256) : this.fromString(e, t))
|
|
}
|
|
function n() {
|
|
return new a(null)
|
|
}
|
|
function i(e, t, r, a, n, i) {
|
|
for (; --i >= 0; ) {
|
|
var s = t * this.data[e++] + r.data[a] + n;
|
|
n = Math.floor(s / 67108864),
|
|
r.data[a++] = 67108863 & s
|
|
}
|
|
return n
|
|
}
|
|
function s(e, t, r, a, n, i) {
|
|
for (var s = 32767 & t, o = t >> 15; --i >= 0; ) {
|
|
var c = 32767 & this.data[e]
|
|
, u = this.data[e++] >> 15
|
|
, l = o * c + u * s;
|
|
c = s * c + ((32767 & l) << 15) + r.data[a] + (1073741823 & n),
|
|
n = (c >>> 30) + (l >>> 15) + o * u + (n >>> 30),
|
|
r.data[a++] = 1073741823 & c
|
|
}
|
|
return n
|
|
}
|
|
function o(e, t, r, a, n, i) {
|
|
for (var s = 16383 & t, o = t >> 14; --i >= 0; ) {
|
|
var c = 16383 & this.data[e]
|
|
, u = this.data[e++] >> 14
|
|
, l = o * c + u * s;
|
|
c = s * c + ((16383 & l) << 14) + r.data[a] + n,
|
|
n = (c >> 28) + (l >> 14) + o * u,
|
|
r.data[a++] = 268435455 & c
|
|
}
|
|
return n
|
|
}
|
|
function c(e) {
|
|
return it.charAt(e)
|
|
}
|
|
function u(e, t) {
|
|
var r = st[e.charCodeAt(t)];
|
|
return null == r ? -1 : r
|
|
}
|
|
function l(e) {
|
|
for (var t = this.t - 1; t >= 0; --t)
|
|
e.data[t] = this.data[t];
|
|
e.t = this.t,
|
|
e.s = this.s
|
|
}
|
|
function p(e) {
|
|
this.t = 1,
|
|
this.s = e < 0 ? -1 : 0,
|
|
e > 0 ? this.data[0] = e : e < -1 ? this.data[0] = e + this.DV : this.t = 0
|
|
}
|
|
function f(e) {
|
|
var t = n();
|
|
return t.fromInt(e),
|
|
t
|
|
}
|
|
function h(e, t) {
|
|
var r;
|
|
if (16 == t)
|
|
r = 4;
|
|
else if (8 == t)
|
|
r = 3;
|
|
else if (256 == t)
|
|
r = 8;
|
|
else if (2 == t)
|
|
r = 1;
|
|
else if (32 == t)
|
|
r = 5;
|
|
else {
|
|
if (4 != t)
|
|
return void this.fromRadix(e, t);
|
|
r = 2
|
|
}
|
|
this.t = 0,
|
|
this.s = 0;
|
|
for (var n = e.length, i = !1, s = 0; --n >= 0; ) {
|
|
var o = 8 == r ? 255 & e[n] : u(e, n);
|
|
o < 0 ? "-" == e.charAt(n) && (i = !0) : (i = !1,
|
|
0 == s ? this.data[this.t++] = o : s + r > this.DB ? (this.data[this.t - 1] |= (o & (1 << this.DB - s) - 1) << s,
|
|
this.data[this.t++] = o >> this.DB - s) : this.data[this.t - 1] |= o << s,
|
|
(s += r) >= this.DB && (s -= this.DB))
|
|
}
|
|
8 == r && 0 != (128 & e[0]) && (this.s = -1,
|
|
s > 0 && (this.data[this.t - 1] |= (1 << this.DB - s) - 1 << s)),
|
|
this.clamp(),
|
|
i && a.ZERO.subTo(this, this)
|
|
}
|
|
function d() {
|
|
for (var e = this.s & this.DM; this.t > 0 && this.data[this.t - 1] == e; )
|
|
--this.t
|
|
}
|
|
function y(e) {
|
|
if (this.s < 0)
|
|
return "-" + this.negate().toString(e);
|
|
var t;
|
|
if (16 == e)
|
|
t = 4;
|
|
else if (8 == e)
|
|
t = 3;
|
|
else if (2 == e)
|
|
t = 1;
|
|
else if (32 == e)
|
|
t = 5;
|
|
else {
|
|
if (4 != e)
|
|
return this.toRadix(e);
|
|
t = 2
|
|
}
|
|
var r, a = (1 << t) - 1, n = !1, i = "", s = this.t, o = this.DB - s * this.DB % t;
|
|
if (s-- > 0)
|
|
for (o < this.DB && (r = this.data[s] >> o) > 0 && (n = !0,
|
|
i = c(r)); s >= 0; )
|
|
o < t ? (r = (this.data[s] & (1 << o) - 1) << t - o,
|
|
r |= this.data[--s] >> (o += this.DB - t)) : (r = this.data[s] >> (o -= t) & a,
|
|
o <= 0 && (o += this.DB,
|
|
--s)),
|
|
r > 0 && (n = !0),
|
|
n && (i += c(r));
|
|
return n ? i : "0"
|
|
}
|
|
function g() {
|
|
var e = n();
|
|
return a.ZERO.subTo(this, e),
|
|
e
|
|
}
|
|
function v() {
|
|
return this.s < 0 ? this.negate() : this
|
|
}
|
|
function m(e) {
|
|
var t = this.s - e.s;
|
|
if (0 != t)
|
|
return t;
|
|
var r = this.t;
|
|
if (0 != (t = r - e.t))
|
|
return this.s < 0 ? -t : t;
|
|
for (; --r >= 0; )
|
|
if (0 != (t = this.data[r] - e.data[r]))
|
|
return t;
|
|
return 0
|
|
}
|
|
function C(e) {
|
|
var t, r = 1;
|
|
return 0 != (t = e >>> 16) && (e = t,
|
|
r += 16),
|
|
0 != (t = e >> 8) && (e = t,
|
|
r += 8),
|
|
0 != (t = e >> 4) && (e = t,
|
|
r += 4),
|
|
0 != (t = e >> 2) && (e = t,
|
|
r += 2),
|
|
0 != (t = e >> 1) && (e = t,
|
|
r += 1),
|
|
r
|
|
}
|
|
function E() {
|
|
return this.t <= 0 ? 0 : this.DB * (this.t - 1) + C(this.data[this.t - 1] ^ this.s & this.DM)
|
|
}
|
|
function S(e, t) {
|
|
var r;
|
|
for (r = this.t - 1; r >= 0; --r)
|
|
t.data[r + e] = this.data[r];
|
|
for (r = e - 1; r >= 0; --r)
|
|
t.data[r] = 0;
|
|
t.t = this.t + e,
|
|
t.s = this.s
|
|
}
|
|
function T(e, t) {
|
|
for (var r = e; r < this.t; ++r)
|
|
t.data[r - e] = this.data[r];
|
|
t.t = Math.max(this.t - e, 0),
|
|
t.s = this.s
|
|
}
|
|
function I(e, t) {
|
|
var r, a = e % this.DB, n = this.DB - a, i = (1 << n) - 1, s = Math.floor(e / this.DB), o = this.s << a & this.DM;
|
|
for (r = this.t - 1; r >= 0; --r)
|
|
t.data[r + s + 1] = this.data[r] >> n | o,
|
|
o = (this.data[r] & i) << a;
|
|
for (r = s - 1; r >= 0; --r)
|
|
t.data[r] = 0;
|
|
t.data[s] = o,
|
|
t.t = this.t + s + 1,
|
|
t.s = this.s,
|
|
t.clamp()
|
|
}
|
|
function b(e, t) {
|
|
t.s = this.s;
|
|
var r = Math.floor(e / this.DB);
|
|
if (r >= this.t)
|
|
return void (t.t = 0);
|
|
var a = e % this.DB
|
|
, n = this.DB - a
|
|
, i = (1 << a) - 1;
|
|
t.data[0] = this.data[r] >> a;
|
|
for (var s = r + 1; s < this.t; ++s)
|
|
t.data[s - r - 1] |= (this.data[s] & i) << n,
|
|
t.data[s - r] = this.data[s] >> a;
|
|
a > 0 && (t.data[this.t - r - 1] |= (this.s & i) << n),
|
|
t.t = this.t - r,
|
|
t.clamp()
|
|
}
|
|
function A(e, t) {
|
|
for (var r = 0, a = 0, n = Math.min(e.t, this.t); r < n; )
|
|
a += this.data[r] - e.data[r],
|
|
t.data[r++] = a & this.DM,
|
|
a >>= this.DB;
|
|
if (e.t < this.t) {
|
|
for (a -= e.s; r < this.t; )
|
|
a += this.data[r],
|
|
t.data[r++] = a & this.DM,
|
|
a >>= this.DB;
|
|
a += this.s
|
|
} else {
|
|
for (a += this.s; r < e.t; )
|
|
a -= e.data[r],
|
|
t.data[r++] = a & this.DM,
|
|
a >>= this.DB;
|
|
a -= e.s
|
|
}
|
|
t.s = a < 0 ? -1 : 0,
|
|
a < -1 ? t.data[r++] = this.DV + a : a > 0 && (t.data[r++] = a),
|
|
t.t = r,
|
|
t.clamp()
|
|
}
|
|
function B(e, t) {
|
|
var r = this.abs()
|
|
, n = e.abs()
|
|
, i = r.t;
|
|
for (t.t = i + n.t; --i >= 0; )
|
|
t.data[i] = 0;
|
|
for (i = 0; i < n.t; ++i)
|
|
t.data[i + r.t] = r.am(0, n.data[i], t, i, 0, r.t);
|
|
t.s = 0,
|
|
t.clamp(),
|
|
this.s != e.s && a.ZERO.subTo(t, t)
|
|
}
|
|
function N(e) {
|
|
for (var t = this.abs(), r = e.t = 2 * t.t; --r >= 0; )
|
|
e.data[r] = 0;
|
|
for (r = 0; r < t.t - 1; ++r) {
|
|
var a = t.am(r, t.data[r], e, 2 * r, 0, 1);
|
|
(e.data[r + t.t] += t.am(r + 1, 2 * t.data[r], e, 2 * r + 1, a, t.t - r - 1)) >= t.DV && (e.data[r + t.t] -= t.DV,
|
|
e.data[r + t.t + 1] = 1)
|
|
}
|
|
e.t > 0 && (e.data[e.t - 1] += t.am(r, t.data[r], e, 2 * r, 0, 1)),
|
|
e.s = 0,
|
|
e.clamp()
|
|
}
|
|
function k(e, t, r) {
|
|
var i = e.abs();
|
|
if (!(i.t <= 0)) {
|
|
var s = this.abs();
|
|
if (s.t < i.t)
|
|
return null != t && t.fromInt(0),
|
|
void (null != r && this.copyTo(r));
|
|
null == r && (r = n());
|
|
var o = n()
|
|
, c = this.s
|
|
, u = e.s
|
|
, l = this.DB - C(i.data[i.t - 1]);
|
|
l > 0 ? (i.lShiftTo(l, o),
|
|
s.lShiftTo(l, r)) : (i.copyTo(o),
|
|
s.copyTo(r));
|
|
var p = o.t
|
|
, f = o.data[p - 1];
|
|
if (0 != f) {
|
|
var h = f * (1 << this.F1) + (p > 1 ? o.data[p - 2] >> this.F2 : 0)
|
|
, d = this.FV / h
|
|
, y = (1 << this.F1) / h
|
|
, g = 1 << this.F2
|
|
, v = r.t
|
|
, m = v - p
|
|
, E = null == t ? n() : t;
|
|
for (o.dlShiftTo(m, E),
|
|
r.compareTo(E) >= 0 && (r.data[r.t++] = 1,
|
|
r.subTo(E, r)),
|
|
a.ONE.dlShiftTo(p, E),
|
|
E.subTo(o, o); o.t < p; )
|
|
o.data[o.t++] = 0;
|
|
for (; --m >= 0; ) {
|
|
var S = r.data[--v] == f ? this.DM : Math.floor(r.data[v] * d + (r.data[v - 1] + g) * y);
|
|
if ((r.data[v] += o.am(0, S, r, m, 0, p)) < S)
|
|
for (o.dlShiftTo(m, E),
|
|
r.subTo(E, r); r.data[v] < --S; )
|
|
r.subTo(E, r)
|
|
}
|
|
null != t && (r.drShiftTo(p, t),
|
|
c != u && a.ZERO.subTo(t, t)),
|
|
r.t = p,
|
|
r.clamp(),
|
|
l > 0 && r.rShiftTo(l, r),
|
|
c < 0 && a.ZERO.subTo(r, r)
|
|
}
|
|
}
|
|
}
|
|
function w(e) {
|
|
var t = n();
|
|
return this.abs().divRemTo(e, null, t),
|
|
this.s < 0 && t.compareTo(a.ZERO) > 0 && e.subTo(t, t),
|
|
t
|
|
}
|
|
function R(e) {
|
|
this.m = e
|
|
}
|
|
function _(e) {
|
|
return e.s < 0 || e.compareTo(this.m) >= 0 ? e.mod(this.m) : e
|
|
}
|
|
function L(e) {
|
|
return e
|
|
}
|
|
function U(e) {
|
|
e.divRemTo(this.m, null, e)
|
|
}
|
|
function D(e, t, r) {
|
|
e.multiplyTo(t, r),
|
|
this.reduce(r)
|
|
}
|
|
function P(e, t) {
|
|
e.squareTo(t),
|
|
this.reduce(t)
|
|
}
|
|
function V() {
|
|
if (this.t < 1)
|
|
return 0;
|
|
var e = this.data[0];
|
|
if (0 == (1 & e))
|
|
return 0;
|
|
var t = 3 & e;
|
|
return t = t * (2 - (15 & e) * t) & 15,
|
|
t = t * (2 - (255 & e) * t) & 255,
|
|
t = t * (2 - ((65535 & e) * t & 65535)) & 65535,
|
|
t = t * (2 - e * t % this.DV) % this.DV,
|
|
t > 0 ? this.DV - t : -t
|
|
}
|
|
function O(e) {
|
|
this.m = e,
|
|
this.mp = e.invDigit(),
|
|
this.mpl = 32767 & this.mp,
|
|
this.mph = this.mp >> 15,
|
|
this.um = (1 << e.DB - 15) - 1,
|
|
this.mt2 = 2 * e.t
|
|
}
|
|
function K(e) {
|
|
var t = n();
|
|
return e.abs().dlShiftTo(this.m.t, t),
|
|
t.divRemTo(this.m, null, t),
|
|
e.s < 0 && t.compareTo(a.ZERO) > 0 && this.m.subTo(t, t),
|
|
t
|
|
}
|
|
function x(e) {
|
|
var t = n();
|
|
return e.copyTo(t),
|
|
this.reduce(t),
|
|
t
|
|
}
|
|
function M(e) {
|
|
for (; e.t <= this.mt2; )
|
|
e.data[e.t++] = 0;
|
|
for (var t = 0; t < this.m.t; ++t) {
|
|
var r = 32767 & e.data[t]
|
|
, a = r * this.mpl + ((r * this.mph + (e.data[t] >> 15) * this.mpl & this.um) << 15) & e.DM;
|
|
for (r = t + this.m.t,
|
|
e.data[r] += this.m.am(0, a, e, t, 0, this.m.t); e.data[r] >= e.DV; )
|
|
e.data[r] -= e.DV,
|
|
e.data[++r]++
|
|
}
|
|
e.clamp(),
|
|
e.drShiftTo(this.m.t, e),
|
|
e.compareTo(this.m) >= 0 && e.subTo(this.m, e)
|
|
}
|
|
function F(e, t) {
|
|
e.squareTo(t),
|
|
this.reduce(t)
|
|
}
|
|
function q(e, t, r) {
|
|
e.multiplyTo(t, r),
|
|
this.reduce(r)
|
|
}
|
|
function j() {
|
|
return 0 == (this.t > 0 ? 1 & this.data[0] : this.s)
|
|
}
|
|
function G(e, t) {
|
|
if (e > 4294967295 || e < 1)
|
|
return a.ONE;
|
|
var r = n()
|
|
, i = n()
|
|
, s = t.convert(this)
|
|
, o = C(e) - 1;
|
|
for (s.copyTo(r); --o >= 0; )
|
|
if (t.sqrTo(r, i),
|
|
(e & 1 << o) > 0)
|
|
t.mulTo(i, s, r);
|
|
else {
|
|
var c = r;
|
|
r = i,
|
|
i = c
|
|
}
|
|
return t.revert(r)
|
|
}
|
|
function H(e, t) {
|
|
var r;
|
|
return r = e < 256 || t.isEven() ? new R(t) : new O(t),
|
|
this.exp(e, r)
|
|
}
|
|
function Q() {
|
|
var e = n();
|
|
return this.copyTo(e),
|
|
e
|
|
}
|
|
function z() {
|
|
if (this.s < 0) {
|
|
if (1 == this.t)
|
|
return this.data[0] - this.DV;
|
|
if (0 == this.t)
|
|
return -1
|
|
} else {
|
|
if (1 == this.t)
|
|
return this.data[0];
|
|
if (0 == this.t)
|
|
return 0
|
|
}
|
|
return (this.data[1] & (1 << 32 - this.DB) - 1) << this.DB | this.data[0]
|
|
}
|
|
function W() {
|
|
return 0 == this.t ? this.s : this.data[0] << 24 >> 24
|
|
}
|
|
function Y() {
|
|
return 0 == this.t ? this.s : this.data[0] << 16 >> 16
|
|
}
|
|
function X(e) {
|
|
return Math.floor(Math.LN2 * this.DB / Math.log(e))
|
|
}
|
|
function Z() {
|
|
return this.s < 0 ? -1 : this.t <= 0 || 1 == this.t && this.data[0] <= 0 ? 0 : 1
|
|
}
|
|
function J(e) {
|
|
if (null == e && (e = 10),
|
|
0 == this.signum() || e < 2 || e > 36)
|
|
return "0";
|
|
var t = this.chunkSize(e)
|
|
, r = Math.pow(e, t)
|
|
, a = f(r)
|
|
, i = n()
|
|
, s = n()
|
|
, o = "";
|
|
for (this.divRemTo(a, i, s); i.signum() > 0; )
|
|
o = (r + s.intValue()).toString(e).substr(1) + o,
|
|
i.divRemTo(a, i, s);
|
|
return s.intValue().toString(e) + o
|
|
}
|
|
function $(e, t) {
|
|
this.fromInt(0),
|
|
null == t && (t = 10);
|
|
for (var r = this.chunkSize(t), n = Math.pow(t, r), i = !1, s = 0, o = 0, c = 0; c < e.length; ++c) {
|
|
var l = u(e, c);
|
|
l < 0 ? "-" == e.charAt(c) && 0 == this.signum() && (i = !0) : (o = t * o + l,
|
|
++s >= r && (this.dMultiply(n),
|
|
this.dAddOffset(o, 0),
|
|
s = 0,
|
|
o = 0))
|
|
}
|
|
s > 0 && (this.dMultiply(Math.pow(t, s)),
|
|
this.dAddOffset(o, 0)),
|
|
i && a.ZERO.subTo(this, this)
|
|
}
|
|
function ee(e, t, r) {
|
|
if ("number" == typeof t)
|
|
if (e < 2)
|
|
this.fromInt(1);
|
|
else
|
|
for (this.fromNumber(e, r),
|
|
this.testBit(e - 1) || this.bitwiseTo(a.ONE.shiftLeft(e - 1), ce, this),
|
|
this.isEven() && this.dAddOffset(1, 0); !this.isProbablePrime(t); )
|
|
this.dAddOffset(2, 0),
|
|
this.bitLength() > e && this.subTo(a.ONE.shiftLeft(e - 1), this);
|
|
else {
|
|
var n = new Array
|
|
, i = 7 & e;
|
|
n.length = 1 + (e >> 3),
|
|
t.nextBytes(n),
|
|
i > 0 ? n[0] &= (1 << i) - 1 : n[0] = 0,
|
|
this.fromString(n, 256)
|
|
}
|
|
}
|
|
function te() {
|
|
var e = this.t
|
|
, t = new Array;
|
|
t[0] = this.s;
|
|
var r, a = this.DB - e * this.DB % 8, n = 0;
|
|
if (e-- > 0)
|
|
for (a < this.DB && (r = this.data[e] >> a) != (this.s & this.DM) >> a && (t[n++] = r | this.s << this.DB - a); e >= 0; )
|
|
a < 8 ? (r = (this.data[e] & (1 << a) - 1) << 8 - a,
|
|
r |= this.data[--e] >> (a += this.DB - 8)) : (r = this.data[e] >> (a -= 8) & 255,
|
|
a <= 0 && (a += this.DB,
|
|
--e)),
|
|
0 != (128 & r) && (r |= -256),
|
|
0 == n && (128 & this.s) != (128 & r) && ++n,
|
|
(n > 0 || r != this.s) && (t[n++] = r);
|
|
return t
|
|
}
|
|
function re(e) {
|
|
return 0 == this.compareTo(e)
|
|
}
|
|
function ae(e) {
|
|
return this.compareTo(e) < 0 ? this : e
|
|
}
|
|
function ne(e) {
|
|
return this.compareTo(e) > 0 ? this : e
|
|
}
|
|
function ie(e, t, r) {
|
|
var a, n, i = Math.min(e.t, this.t);
|
|
for (a = 0; a < i; ++a)
|
|
r.data[a] = t(this.data[a], e.data[a]);
|
|
if (e.t < this.t) {
|
|
for (n = e.s & this.DM,
|
|
a = i; a < this.t; ++a)
|
|
r.data[a] = t(this.data[a], n);
|
|
r.t = this.t
|
|
} else {
|
|
for (n = this.s & this.DM,
|
|
a = i; a < e.t; ++a)
|
|
r.data[a] = t(n, e.data[a]);
|
|
r.t = e.t
|
|
}
|
|
r.s = t(this.s, e.s),
|
|
r.clamp()
|
|
}
|
|
function se(e, t) {
|
|
return e & t
|
|
}
|
|
function oe(e) {
|
|
var t = n();
|
|
return this.bitwiseTo(e, se, t),
|
|
t
|
|
}
|
|
function ce(e, t) {
|
|
return e | t
|
|
}
|
|
function ue(e) {
|
|
var t = n();
|
|
return this.bitwiseTo(e, ce, t),
|
|
t
|
|
}
|
|
function le(e, t) {
|
|
return e ^ t
|
|
}
|
|
function pe(e) {
|
|
var t = n();
|
|
return this.bitwiseTo(e, le, t),
|
|
t
|
|
}
|
|
function fe(e, t) {
|
|
return e & ~t
|
|
}
|
|
function he(e) {
|
|
var t = n();
|
|
return this.bitwiseTo(e, fe, t),
|
|
t
|
|
}
|
|
function de() {
|
|
for (var e = n(), t = 0; t < this.t; ++t)
|
|
e.data[t] = this.DM & ~this.data[t];
|
|
return e.t = this.t,
|
|
e.s = ~this.s,
|
|
e
|
|
}
|
|
function ye(e) {
|
|
var t = n();
|
|
return e < 0 ? this.rShiftTo(-e, t) : this.lShiftTo(e, t),
|
|
t
|
|
}
|
|
function ge(e) {
|
|
var t = n();
|
|
return e < 0 ? this.lShiftTo(-e, t) : this.rShiftTo(e, t),
|
|
t
|
|
}
|
|
function ve(e) {
|
|
if (0 == e)
|
|
return -1;
|
|
var t = 0;
|
|
return 0 == (65535 & e) && (e >>= 16,
|
|
t += 16),
|
|
0 == (255 & e) && (e >>= 8,
|
|
t += 8),
|
|
0 == (15 & e) && (e >>= 4,
|
|
t += 4),
|
|
0 == (3 & e) && (e >>= 2,
|
|
t += 2),
|
|
0 == (1 & e) && ++t,
|
|
t
|
|
}
|
|
function me() {
|
|
for (var e = 0; e < this.t; ++e)
|
|
if (0 != this.data[e])
|
|
return e * this.DB + ve(this.data[e]);
|
|
return this.s < 0 ? this.t * this.DB : -1
|
|
}
|
|
function Ce(e) {
|
|
for (var t = 0; 0 != e; )
|
|
e &= e - 1,
|
|
++t;
|
|
return t
|
|
}
|
|
function Ee() {
|
|
for (var e = 0, t = this.s & this.DM, r = 0; r < this.t; ++r)
|
|
e += Ce(this.data[r] ^ t);
|
|
return e
|
|
}
|
|
function Se(e) {
|
|
var t = Math.floor(e / this.DB);
|
|
return t >= this.t ? 0 != this.s : 0 != (this.data[t] & 1 << e % this.DB)
|
|
}
|
|
function Te(e, t) {
|
|
var r = a.ONE.shiftLeft(e);
|
|
return this.bitwiseTo(r, t, r),
|
|
r
|
|
}
|
|
function Ie(e) {
|
|
return this.changeBit(e, ce)
|
|
}
|
|
function be(e) {
|
|
return this.changeBit(e, fe)
|
|
}
|
|
function Ae(e) {
|
|
return this.changeBit(e, le)
|
|
}
|
|
function Be(e, t) {
|
|
for (var r = 0, a = 0, n = Math.min(e.t, this.t); r < n; )
|
|
a += this.data[r] + e.data[r],
|
|
t.data[r++] = a & this.DM,
|
|
a >>= this.DB;
|
|
if (e.t < this.t) {
|
|
for (a += e.s; r < this.t; )
|
|
a += this.data[r],
|
|
t.data[r++] = a & this.DM,
|
|
a >>= this.DB;
|
|
a += this.s
|
|
} else {
|
|
for (a += this.s; r < e.t; )
|
|
a += e.data[r],
|
|
t.data[r++] = a & this.DM,
|
|
a >>= this.DB;
|
|
a += e.s
|
|
}
|
|
t.s = a < 0 ? -1 : 0,
|
|
a > 0 ? t.data[r++] = a : a < -1 && (t.data[r++] = this.DV + a),
|
|
t.t = r,
|
|
t.clamp()
|
|
}
|
|
function Ne(e) {
|
|
var t = n();
|
|
return this.addTo(e, t),
|
|
t
|
|
}
|
|
function ke(e) {
|
|
var t = n();
|
|
return this.subTo(e, t),
|
|
t
|
|
}
|
|
function we(e) {
|
|
var t = n();
|
|
return this.multiplyTo(e, t),
|
|
t
|
|
}
|
|
function Re(e) {
|
|
var t = n();
|
|
return this.divRemTo(e, t, null),
|
|
t
|
|
}
|
|
function _e(e) {
|
|
var t = n();
|
|
return this.divRemTo(e, null, t),
|
|
t
|
|
}
|
|
function Le(e) {
|
|
var t = n()
|
|
, r = n();
|
|
return this.divRemTo(e, t, r),
|
|
new Array(t,r)
|
|
}
|
|
function Ue(e) {
|
|
this.data[this.t] = this.am(0, e - 1, this, 0, 0, this.t),
|
|
++this.t,
|
|
this.clamp()
|
|
}
|
|
function De(e, t) {
|
|
if (0 != e) {
|
|
for (; this.t <= t; )
|
|
this.data[this.t++] = 0;
|
|
for (this.data[t] += e; this.data[t] >= this.DV; )
|
|
this.data[t] -= this.DV,
|
|
++t >= this.t && (this.data[this.t++] = 0),
|
|
++this.data[t]
|
|
}
|
|
}
|
|
function Pe() {}
|
|
function Ve(e) {
|
|
return e
|
|
}
|
|
function Oe(e, t, r) {
|
|
e.multiplyTo(t, r)
|
|
}
|
|
function Ke(e, t) {
|
|
e.squareTo(t)
|
|
}
|
|
function xe(e) {
|
|
return this.exp(e, new Pe)
|
|
}
|
|
function Me(e, t, r) {
|
|
var a = Math.min(this.t + e.t, t);
|
|
for (r.s = 0,
|
|
r.t = a; a > 0; )
|
|
r.data[--a] = 0;
|
|
var n;
|
|
for (n = r.t - this.t; a < n; ++a)
|
|
r.data[a + this.t] = this.am(0, e.data[a], r, a, 0, this.t);
|
|
for (n = Math.min(e.t, t); a < n; ++a)
|
|
this.am(0, e.data[a], r, a, 0, t - a);
|
|
r.clamp()
|
|
}
|
|
function Fe(e, t, r) {
|
|
--t;
|
|
var a = r.t = this.t + e.t - t;
|
|
for (r.s = 0; --a >= 0; )
|
|
r.data[a] = 0;
|
|
for (a = Math.max(t - this.t, 0); a < e.t; ++a)
|
|
r.data[this.t + a - t] = this.am(t - a, e.data[a], r, 0, 0, this.t + a - t);
|
|
r.clamp(),
|
|
r.drShiftTo(1, r)
|
|
}
|
|
function qe(e) {
|
|
this.r2 = n(),
|
|
this.q3 = n(),
|
|
a.ONE.dlShiftTo(2 * e.t, this.r2),
|
|
this.mu = this.r2.divide(e),
|
|
this.m = e
|
|
}
|
|
function je(e) {
|
|
if (e.s < 0 || e.t > 2 * this.m.t)
|
|
return e.mod(this.m);
|
|
if (e.compareTo(this.m) < 0)
|
|
return e;
|
|
var t = n();
|
|
return e.copyTo(t),
|
|
this.reduce(t),
|
|
t
|
|
}
|
|
function Ge(e) {
|
|
return e
|
|
}
|
|
function He(e) {
|
|
for (e.drShiftTo(this.m.t - 1, this.r2),
|
|
e.t > this.m.t + 1 && (e.t = this.m.t + 1,
|
|
e.clamp()),
|
|
this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3),
|
|
this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); e.compareTo(this.r2) < 0; )
|
|
e.dAddOffset(1, this.m.t + 1);
|
|
for (e.subTo(this.r2, e); e.compareTo(this.m) >= 0; )
|
|
e.subTo(this.m, e)
|
|
}
|
|
function Qe(e, t) {
|
|
e.squareTo(t),
|
|
this.reduce(t)
|
|
}
|
|
function ze(e, t, r) {
|
|
e.multiplyTo(t, r),
|
|
this.reduce(r)
|
|
}
|
|
function We(e, t) {
|
|
var r, a, i = e.bitLength(), s = f(1);
|
|
if (i <= 0)
|
|
return s;
|
|
r = i < 18 ? 1 : i < 48 ? 3 : i < 144 ? 4 : i < 768 ? 5 : 6,
|
|
a = i < 8 ? new R(t) : t.isEven() ? new qe(t) : new O(t);
|
|
var o = new Array
|
|
, c = 3
|
|
, u = r - 1
|
|
, l = (1 << r) - 1;
|
|
if (o[1] = a.convert(this),
|
|
r > 1) {
|
|
var p = n();
|
|
for (a.sqrTo(o[1], p); c <= l; )
|
|
o[c] = n(),
|
|
a.mulTo(p, o[c - 2], o[c]),
|
|
c += 2
|
|
}
|
|
var h, d, y = e.t - 1, g = !0, v = n();
|
|
for (i = C(e.data[y]) - 1; y >= 0; ) {
|
|
for (i >= u ? h = e.data[y] >> i - u & l : (h = (e.data[y] & (1 << i + 1) - 1) << u - i,
|
|
y > 0 && (h |= e.data[y - 1] >> this.DB + i - u)),
|
|
c = r; 0 == (1 & h); )
|
|
h >>= 1,
|
|
--c;
|
|
if ((i -= c) < 0 && (i += this.DB,
|
|
--y),
|
|
g)
|
|
o[h].copyTo(s),
|
|
g = !1;
|
|
else {
|
|
for (; c > 1; )
|
|
a.sqrTo(s, v),
|
|
a.sqrTo(v, s),
|
|
c -= 2;
|
|
c > 0 ? a.sqrTo(s, v) : (d = s,
|
|
s = v,
|
|
v = d),
|
|
a.mulTo(v, o[h], s)
|
|
}
|
|
for (; y >= 0 && 0 == (e.data[y] & 1 << i); )
|
|
a.sqrTo(s, v),
|
|
d = s,
|
|
s = v,
|
|
v = d,
|
|
--i < 0 && (i = this.DB - 1,
|
|
--y)
|
|
}
|
|
return a.revert(s)
|
|
}
|
|
function Ye(e) {
|
|
var t = this.s < 0 ? this.negate() : this.clone()
|
|
, r = e.s < 0 ? e.negate() : e.clone();
|
|
if (t.compareTo(r) < 0) {
|
|
var a = t;
|
|
t = r,
|
|
r = a
|
|
}
|
|
var n = t.getLowestSetBit()
|
|
, i = r.getLowestSetBit();
|
|
if (i < 0)
|
|
return t;
|
|
for (n < i && (i = n),
|
|
i > 0 && (t.rShiftTo(i, t),
|
|
r.rShiftTo(i, r)); t.signum() > 0; )
|
|
(n = t.getLowestSetBit()) > 0 && t.rShiftTo(n, t),
|
|
(n = r.getLowestSetBit()) > 0 && r.rShiftTo(n, r),
|
|
t.compareTo(r) >= 0 ? (t.subTo(r, t),
|
|
t.rShiftTo(1, t)) : (r.subTo(t, r),
|
|
r.rShiftTo(1, r));
|
|
return i > 0 && r.lShiftTo(i, r),
|
|
r
|
|
}
|
|
function Xe(e) {
|
|
if (e <= 0)
|
|
return 0;
|
|
var t = this.DV % e
|
|
, r = this.s < 0 ? e - 1 : 0;
|
|
if (this.t > 0)
|
|
if (0 == t)
|
|
r = this.data[0] % e;
|
|
else
|
|
for (var a = this.t - 1; a >= 0; --a)
|
|
r = (t * r + this.data[a]) % e;
|
|
return r
|
|
}
|
|
function Ze(e) {
|
|
var t = e.isEven();
|
|
if (this.isEven() && t || 0 == e.signum())
|
|
return a.ZERO;
|
|
for (var r = e.clone(), n = this.clone(), i = f(1), s = f(0), o = f(0), c = f(1); 0 != r.signum(); ) {
|
|
for (; r.isEven(); )
|
|
r.rShiftTo(1, r),
|
|
t ? (i.isEven() && s.isEven() || (i.addTo(this, i),
|
|
s.subTo(e, s)),
|
|
i.rShiftTo(1, i)) : s.isEven() || s.subTo(e, s),
|
|
s.rShiftTo(1, s);
|
|
for (; n.isEven(); )
|
|
n.rShiftTo(1, n),
|
|
t ? (o.isEven() && c.isEven() || (o.addTo(this, o),
|
|
c.subTo(e, c)),
|
|
o.rShiftTo(1, o)) : c.isEven() || c.subTo(e, c),
|
|
c.rShiftTo(1, c);
|
|
r.compareTo(n) >= 0 ? (r.subTo(n, r),
|
|
t && i.subTo(o, i),
|
|
s.subTo(c, s)) : (n.subTo(r, n),
|
|
t && o.subTo(i, o),
|
|
c.subTo(s, c))
|
|
}
|
|
return 0 != n.compareTo(a.ONE) ? a.ZERO : c.compareTo(e) >= 0 ? c.subtract(e) : c.signum() < 0 ? (c.addTo(e, c),
|
|
c.signum() < 0 ? c.add(e) : c) : c
|
|
}
|
|
function Je(e) {
|
|
var t, r = this.abs();
|
|
if (1 == r.t && r.data[0] <= ot[ot.length - 1]) {
|
|
for (t = 0; t < ot.length; ++t)
|
|
if (r.data[0] == ot[t])
|
|
return !0;
|
|
return !1
|
|
}
|
|
if (r.isEven())
|
|
return !1;
|
|
for (t = 1; t < ot.length; ) {
|
|
for (var a = ot[t], n = t + 1; n < ot.length && a < ct; )
|
|
a *= ot[n++];
|
|
for (a = r.modInt(a); t < n; )
|
|
if (a % ot[t++] == 0)
|
|
return !1
|
|
}
|
|
return r.millerRabin(e)
|
|
}
|
|
function $e(e) {
|
|
var t = this.subtract(a.ONE)
|
|
, r = t.getLowestSetBit();
|
|
if (r <= 0)
|
|
return !1;
|
|
for (var n, i = t.shiftRight(r), s = et(), o = 0; o < e; ++o) {
|
|
do {
|
|
n = new a(this.bitLength(),s)
|
|
} while (n.compareTo(a.ONE) <= 0 || n.compareTo(t) >= 0);
|
|
var c = n.modPow(i, this);
|
|
if (0 != c.compareTo(a.ONE) && 0 != c.compareTo(t)) {
|
|
for (var u = 1; u++ < r && 0 != c.compareTo(t); )
|
|
if (c = c.modPowInt(2, this),
|
|
0 == c.compareTo(a.ONE))
|
|
return !1;
|
|
if (0 != c.compareTo(t))
|
|
return !1
|
|
}
|
|
}
|
|
return !0
|
|
}
|
|
function et() {
|
|
return {
|
|
nextBytes: function(e) {
|
|
for (var t = 0; t < e.length; ++t)
|
|
e[t] = Math.floor(256 * Math.random())
|
|
}
|
|
}
|
|
}
|
|
var tt = r(0);
|
|
e.exports = tt.jsbn = tt.jsbn || {};
|
|
var rt;
|
|
tt.jsbn.BigInteger = a,
|
|
"undefined" == typeof navigator ? (a.prototype.am = o,
|
|
rt = 28) : "Microsoft Internet Explorer" == navigator.appName ? (a.prototype.am = s,
|
|
rt = 30) : "Netscape" != navigator.appName ? (a.prototype.am = i,
|
|
rt = 26) : (a.prototype.am = o,
|
|
rt = 28),
|
|
a.prototype.DB = rt,
|
|
a.prototype.DM = (1 << rt) - 1,
|
|
a.prototype.DV = 1 << rt;
|
|
a.prototype.FV = Math.pow(2, 52),
|
|
a.prototype.F1 = 52 - rt,
|
|
a.prototype.F2 = 2 * rt - 52;
|
|
var at, nt, it = "0123456789abcdefghijklmnopqrstuvwxyz", st = new Array;
|
|
for (at = "0".charCodeAt(0),
|
|
nt = 0; nt <= 9; ++nt)
|
|
st[at++] = nt;
|
|
for (at = "a".charCodeAt(0),
|
|
nt = 10; nt < 36; ++nt)
|
|
st[at++] = nt;
|
|
for (at = "A".charCodeAt(0),
|
|
nt = 10; nt < 36; ++nt)
|
|
st[at++] = nt;
|
|
R.prototype.convert = _,
|
|
R.prototype.revert = L,
|
|
R.prototype.reduce = U,
|
|
R.prototype.mulTo = D,
|
|
R.prototype.sqrTo = P,
|
|
O.prototype.convert = K,
|
|
O.prototype.revert = x,
|
|
O.prototype.reduce = M,
|
|
O.prototype.mulTo = q,
|
|
O.prototype.sqrTo = F,
|
|
a.prototype.copyTo = l,
|
|
a.prototype.fromInt = p,
|
|
a.prototype.fromString = h,
|
|
a.prototype.clamp = d,
|
|
a.prototype.dlShiftTo = S,
|
|
a.prototype.drShiftTo = T,
|
|
a.prototype.lShiftTo = I,
|
|
a.prototype.rShiftTo = b,
|
|
a.prototype.subTo = A,
|
|
a.prototype.multiplyTo = B,
|
|
a.prototype.squareTo = N,
|
|
a.prototype.divRemTo = k,
|
|
a.prototype.invDigit = V,
|
|
a.prototype.isEven = j,
|
|
a.prototype.exp = G,
|
|
a.prototype.toString = y,
|
|
a.prototype.negate = g,
|
|
a.prototype.abs = v,
|
|
a.prototype.compareTo = m,
|
|
a.prototype.bitLength = E,
|
|
a.prototype.mod = w,
|
|
a.prototype.modPowInt = H,
|
|
a.ZERO = f(0),
|
|
a.ONE = f(1),
|
|
Pe.prototype.convert = Ve,
|
|
Pe.prototype.revert = Ve,
|
|
Pe.prototype.mulTo = Oe,
|
|
Pe.prototype.sqrTo = Ke,
|
|
qe.prototype.convert = je,
|
|
qe.prototype.revert = Ge,
|
|
qe.prototype.reduce = He,
|
|
qe.prototype.mulTo = ze,
|
|
qe.prototype.sqrTo = Qe;
|
|
var ot = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509]
|
|
, ct = (1 << 26) / ot[ot.length - 1];
|
|
a.prototype.chunkSize = X,
|
|
a.prototype.toRadix = J,
|
|
a.prototype.fromRadix = $,
|
|
a.prototype.fromNumber = ee,
|
|
a.prototype.bitwiseTo = ie,
|
|
a.prototype.changeBit = Te,
|
|
a.prototype.addTo = Be,
|
|
a.prototype.dMultiply = Ue,
|
|
a.prototype.dAddOffset = De,
|
|
a.prototype.multiplyLowerTo = Me,
|
|
a.prototype.multiplyUpperTo = Fe,
|
|
a.prototype.modInt = Xe,
|
|
a.prototype.millerRabin = $e,
|
|
a.prototype.clone = Q,
|
|
a.prototype.intValue = z,
|
|
a.prototype.byteValue = W,
|
|
a.prototype.shortValue = Y,
|
|
a.prototype.signum = Z,
|
|
a.prototype.toByteArray = te,
|
|
a.prototype.equals = re,
|
|
a.prototype.min = ae,
|
|
a.prototype.max = ne,
|
|
a.prototype.and = oe,
|
|
a.prototype.or = ue,
|
|
a.prototype.xor = pe,
|
|
a.prototype.andNot = he,
|
|
a.prototype.not = de,
|
|
a.prototype.shiftLeft = ye,
|
|
a.prototype.shiftRight = ge,
|
|
a.prototype.getLowestSetBit = me,
|
|
a.prototype.bitCount = Ee,
|
|
a.prototype.testBit = Se,
|
|
a.prototype.setBit = Ie,
|
|
a.prototype.clearBit = be,
|
|
a.prototype.flipBit = Ae,
|
|
a.prototype.add = Ne,
|
|
a.prototype.subtract = ke,
|
|
a.prototype.multiply = we,
|
|
a.prototype.divide = Re,
|
|
a.prototype.remainder = _e,
|
|
a.prototype.divideAndRemainder = Le,
|
|
a.prototype.modPow = We,
|
|
a.prototype.modInverse = Ze,
|
|
a.prototype.pow = xe,
|
|
a.prototype.gcd = Ye,
|
|
a.prototype.isProbablePrime = Je
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(1),
|
|
e.exports = a.cipher = a.cipher || {},
|
|
a.cipher.algorithms = a.cipher.algorithms || {},
|
|
a.cipher.createCipher = function(e, t) {
|
|
var r = e;
|
|
if ("string" == typeof r && (r = a.cipher.getAlgorithm(r)) && (r = r()),
|
|
!r)
|
|
throw new Error("Unsupported algorithm: " + e);
|
|
return new a.cipher.BlockCipher({
|
|
algorithm: r,
|
|
key: t,
|
|
decrypt: !1
|
|
})
|
|
}
|
|
,
|
|
a.cipher.createDecipher = function(e, t) {
|
|
var r = e;
|
|
if ("string" == typeof r && (r = a.cipher.getAlgorithm(r)) && (r = r()),
|
|
!r)
|
|
throw new Error("Unsupported algorithm: " + e);
|
|
return new a.cipher.BlockCipher({
|
|
algorithm: r,
|
|
key: t,
|
|
decrypt: !0
|
|
})
|
|
}
|
|
,
|
|
a.cipher.registerAlgorithm = function(e, t) {
|
|
e = e.toUpperCase(),
|
|
a.cipher.algorithms[e] = t
|
|
}
|
|
,
|
|
a.cipher.getAlgorithm = function(e) {
|
|
return e = e.toUpperCase(),
|
|
e in a.cipher.algorithms ? a.cipher.algorithms[e] : null
|
|
}
|
|
;
|
|
var n = a.cipher.BlockCipher = function(e) {
|
|
this.algorithm = e.algorithm,
|
|
this.mode = this.algorithm.mode,
|
|
this.blockSize = this.mode.blockSize,
|
|
this._finish = !1,
|
|
this._input = null,
|
|
this.output = null,
|
|
this._op = e.decrypt ? this.mode.decrypt : this.mode.encrypt,
|
|
this._decrypt = e.decrypt,
|
|
this.algorithm.initialize(e)
|
|
}
|
|
;
|
|
n.prototype.start = function(e) {
|
|
e = e || {};
|
|
var t = {};
|
|
for (var r in e)
|
|
t[r] = e[r];
|
|
t.decrypt = this._decrypt,
|
|
this._finish = !1,
|
|
this._input = a.util.createBuffer(),
|
|
this.output = e.output || a.util.createBuffer(),
|
|
this.mode.start(t)
|
|
}
|
|
,
|
|
n.prototype.update = function(e) {
|
|
for (e && this._input.putBuffer(e); !this._op.call(this.mode, this._input, this.output, this._finish) && !this._finish; )
|
|
;
|
|
this._input.compact()
|
|
}
|
|
,
|
|
n.prototype.finish = function(e) {
|
|
!e || "ECB" !== this.mode.name && "CBC" !== this.mode.name || (this.mode.pad = function(t) {
|
|
return e(this.blockSize, t, !1)
|
|
}
|
|
,
|
|
this.mode.unpad = function(t) {
|
|
return e(this.blockSize, t, !0)
|
|
}
|
|
);
|
|
var t = {};
|
|
return t.decrypt = this._decrypt,
|
|
t.overflow = this._input.length() % this.blockSize,
|
|
!(!this._decrypt && this.mode.pad && !this.mode.pad(this._input, t)) && (this._finish = !0,
|
|
this.update(),
|
|
!(this._decrypt && this.mode.unpad && !this.mode.unpad(this.output, t)) && !(this.mode.afterFinish && !this.mode.afterFinish(this.output, t)))
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
function a() {
|
|
o = String.fromCharCode(128),
|
|
o += i.util.fillString(String.fromCharCode(0), 64),
|
|
c = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9],
|
|
u = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21],
|
|
l = new Array(64);
|
|
for (var e = 0; e < 64; ++e)
|
|
l[e] = Math.floor(4294967296 * Math.abs(Math.sin(e + 1)));
|
|
p = !0
|
|
}
|
|
function n(e, t, r) {
|
|
for (var a, n, i, s, o, p, f, h, d = r.length(); d >= 64; ) {
|
|
for (n = e.h0,
|
|
i = e.h1,
|
|
s = e.h2,
|
|
o = e.h3,
|
|
h = 0; h < 16; ++h)
|
|
t[h] = r.getInt32Le(),
|
|
p = o ^ i & (s ^ o),
|
|
a = n + p + l[h] + t[h],
|
|
f = u[h],
|
|
n = o,
|
|
o = s,
|
|
s = i,
|
|
i += a << f | a >>> 32 - f;
|
|
for (; h < 32; ++h)
|
|
p = s ^ o & (i ^ s),
|
|
a = n + p + l[h] + t[c[h]],
|
|
f = u[h],
|
|
n = o,
|
|
o = s,
|
|
s = i,
|
|
i += a << f | a >>> 32 - f;
|
|
for (; h < 48; ++h)
|
|
p = i ^ s ^ o,
|
|
a = n + p + l[h] + t[c[h]],
|
|
f = u[h],
|
|
n = o,
|
|
o = s,
|
|
s = i,
|
|
i += a << f | a >>> 32 - f;
|
|
for (; h < 64; ++h)
|
|
p = s ^ (i | ~o),
|
|
a = n + p + l[h] + t[c[h]],
|
|
f = u[h],
|
|
n = o,
|
|
o = s,
|
|
s = i,
|
|
i += a << f | a >>> 32 - f;
|
|
e.h0 = e.h0 + n | 0,
|
|
e.h1 = e.h1 + i | 0,
|
|
e.h2 = e.h2 + s | 0,
|
|
e.h3 = e.h3 + o | 0,
|
|
d -= 64
|
|
}
|
|
}
|
|
var i = r(0);
|
|
r(4),
|
|
r(1);
|
|
var s = e.exports = i.md5 = i.md5 || {};
|
|
i.md.md5 = i.md.algorithms.md5 = s,
|
|
s.create = function() {
|
|
p || a();
|
|
var e = null
|
|
, t = i.util.createBuffer()
|
|
, r = new Array(16)
|
|
, s = {
|
|
algorithm: "md5",
|
|
blockLength: 64,
|
|
digestLength: 16,
|
|
messageLength: 0,
|
|
fullMessageLength: null,
|
|
messageLengthSize: 8
|
|
};
|
|
return s.start = function() {
|
|
s.messageLength = 0,
|
|
s.fullMessageLength = s.messageLength64 = [];
|
|
for (var r = s.messageLengthSize / 4, a = 0; a < r; ++a)
|
|
s.fullMessageLength.push(0);
|
|
return t = i.util.createBuffer(),
|
|
e = {
|
|
h0: 1732584193,
|
|
h1: 4023233417,
|
|
h2: 2562383102,
|
|
h3: 271733878
|
|
},
|
|
s
|
|
}
|
|
,
|
|
s.start(),
|
|
s.update = function(a, o) {
|
|
"utf8" === o && (a = i.util.encodeUtf8(a));
|
|
var c = a.length;
|
|
s.messageLength += c,
|
|
c = [c / 4294967296 >>> 0, c >>> 0];
|
|
for (var u = s.fullMessageLength.length - 1; u >= 0; --u)
|
|
s.fullMessageLength[u] += c[1],
|
|
c[1] = c[0] + (s.fullMessageLength[u] / 4294967296 >>> 0),
|
|
s.fullMessageLength[u] = s.fullMessageLength[u] >>> 0,
|
|
c[0] = c[1] / 4294967296 >>> 0;
|
|
return t.putBytes(a),
|
|
n(e, r, t),
|
|
(t.read > 2048 || 0 === t.length()) && t.compact(),
|
|
s
|
|
}
|
|
,
|
|
s.digest = function() {
|
|
var a = i.util.createBuffer();
|
|
a.putBytes(t.bytes());
|
|
var c = s.fullMessageLength[s.fullMessageLength.length - 1] + s.messageLengthSize
|
|
, u = c & s.blockLength - 1;
|
|
a.putBytes(o.substr(0, s.blockLength - u));
|
|
for (var l, p = 0, f = s.fullMessageLength.length - 1; f >= 0; --f)
|
|
l = 8 * s.fullMessageLength[f] + p,
|
|
p = l / 4294967296 >>> 0,
|
|
a.putInt32Le(l >>> 0);
|
|
var h = {
|
|
h0: e.h0,
|
|
h1: e.h1,
|
|
h2: e.h2,
|
|
h3: e.h3
|
|
};
|
|
n(h, r, a);
|
|
var d = i.util.createBuffer();
|
|
return d.putInt32Le(h.h0),
|
|
d.putInt32Le(h.h1),
|
|
d.putInt32Le(h.h2),
|
|
d.putInt32Le(h.h3),
|
|
d
|
|
}
|
|
,
|
|
s
|
|
}
|
|
;
|
|
var o = null
|
|
, c = null
|
|
, u = null
|
|
, l = null
|
|
, p = !1
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(8),
|
|
r(4),
|
|
r(1);
|
|
var n, i = a.pkcs5 = a.pkcs5 || {};
|
|
a.util.isNodejs && !a.options.usePureJavaScript && (n = r(16)),
|
|
e.exports = a.pbkdf2 = i.pbkdf2 = function(e, t, r, i, s, o) {
|
|
function c() {
|
|
if (C > f)
|
|
return o(null, m);
|
|
d.start(null, null),
|
|
d.update(t),
|
|
d.update(a.util.int32ToBytes(C)),
|
|
y = v = d.digest().getBytes(),
|
|
E = 2,
|
|
u()
|
|
}
|
|
function u() {
|
|
if (E <= r)
|
|
return d.start(null, null),
|
|
d.update(v),
|
|
g = d.digest().getBytes(),
|
|
y = a.util.xorBytes(y, g, l),
|
|
v = g,
|
|
++E,
|
|
a.util.setImmediate(u);
|
|
m += C < f ? y : y.substr(0, h),
|
|
++C,
|
|
c()
|
|
}
|
|
if ("function" == typeof s && (o = s,
|
|
s = null),
|
|
a.util.isNodejs && !a.options.usePureJavaScript && n.pbkdf2 && (null === s || "object" != typeof s) && (n.pbkdf2Sync.length > 4 || !s || "sha1" === s))
|
|
return "string" != typeof s && (s = "sha1"),
|
|
e = new Buffer(e,"binary"),
|
|
t = new Buffer(t,"binary"),
|
|
o ? 4 === n.pbkdf2Sync.length ? n.pbkdf2(e, t, r, i, function(e, t) {
|
|
if (e)
|
|
return o(e);
|
|
o(null, t.toString("binary"))
|
|
}) : n.pbkdf2(e, t, r, i, s, function(e, t) {
|
|
if (e)
|
|
return o(e);
|
|
o(null, t.toString("binary"))
|
|
}) : 4 === n.pbkdf2Sync.length ? n.pbkdf2Sync(e, t, r, i).toString("binary") : n.pbkdf2Sync(e, t, r, i, s).toString("binary");
|
|
if (void 0 !== s && null !== s || (s = "sha1"),
|
|
"string" == typeof s) {
|
|
if (!(s in a.md.algorithms))
|
|
throw new Error("Unknown hash algorithm: " + s);
|
|
s = a.md[s].create()
|
|
}
|
|
var l = s.digestLength;
|
|
if (i > 4294967295 * l) {
|
|
var p = new Error("Derived key is too long.");
|
|
if (o)
|
|
return o(p);
|
|
throw p
|
|
}
|
|
var f = Math.ceil(i / l)
|
|
, h = i - (f - 1) * l
|
|
, d = a.hmac.create();
|
|
d.start(s, e);
|
|
var y, g, v, m = "";
|
|
if (!o) {
|
|
for (var C = 1; C <= f; ++C) {
|
|
d.start(null, null),
|
|
d.update(t),
|
|
d.update(a.util.int32ToBytes(C)),
|
|
y = v = d.digest().getBytes();
|
|
for (var E = 2; E <= r; ++E)
|
|
d.start(null, null),
|
|
d.update(v),
|
|
g = d.digest().getBytes(),
|
|
y = a.util.xorBytes(y, g, l),
|
|
v = g;
|
|
m += C < f ? y : y.substr(0, h)
|
|
}
|
|
return m
|
|
}
|
|
var E, C = 1;
|
|
c()
|
|
}
|
|
}
|
|
, function(e, t) {}
|
|
, function(e, t, r) {
|
|
function a(e, t) {
|
|
"string" == typeof t && (t = {
|
|
shortName: t
|
|
});
|
|
for (var r, a = null, n = 0; null === a && n < e.attributes.length; ++n)
|
|
r = e.attributes[n],
|
|
t.type && t.type === r.type ? a = r : t.name && t.name === r.name ? a = r : t.shortName && t.shortName === r.shortName && (a = r);
|
|
return a
|
|
}
|
|
function n(e) {
|
|
for (var t, r, a = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, []), n = e.attributes, i = 0; i < n.length; ++i) {
|
|
t = n[i];
|
|
var s = t.value
|
|
, o = p.Type.PRINTABLESTRING;
|
|
"valueTagClass"in t && (o = t.valueTagClass) === p.Type.UTF8 && (s = l.util.encodeUtf8(s)),
|
|
r = p.create(p.Class.UNIVERSAL, p.Type.SET, !0, [p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(t.type).getBytes()), p.create(p.Class.UNIVERSAL, o, !1, s)])]),
|
|
a.value.push(r)
|
|
}
|
|
return a
|
|
}
|
|
function i(e) {
|
|
for (var t, r = 0; r < e.length; ++r) {
|
|
if (t = e[r],
|
|
void 0 === t.name && (t.type && t.type in f.oids ? t.name = f.oids[t.type] : t.shortName && t.shortName in d && (t.name = f.oids[d[t.shortName]])),
|
|
void 0 === t.type) {
|
|
if (!(t.name && t.name in f.oids)) {
|
|
var a = new Error("Attribute type not specified.");
|
|
throw a.attribute = t,
|
|
a
|
|
}
|
|
t.type = f.oids[t.name]
|
|
}
|
|
if (void 0 === t.shortName && t.name && t.name in d && (t.shortName = d[t.name]),
|
|
t.type === h.extensionRequest && (t.valueConstructed = !0,
|
|
t.valueTagClass = p.Type.SEQUENCE,
|
|
!t.value && t.extensions)) {
|
|
t.value = [];
|
|
for (var n = 0; n < t.extensions.length; ++n)
|
|
t.value.push(f.certificateExtensionToAsn1(s(t.extensions[n])))
|
|
}
|
|
if (void 0 === t.value) {
|
|
var a = new Error("Attribute value not specified.");
|
|
throw a.attribute = t,
|
|
a
|
|
}
|
|
}
|
|
}
|
|
function s(e, t) {
|
|
if (t = t || {},
|
|
void 0 === e.name && e.id && e.id in f.oids && (e.name = f.oids[e.id]),
|
|
void 0 === e.id) {
|
|
if (!(e.name && e.name in f.oids)) {
|
|
var r = new Error("Extension ID not specified.");
|
|
throw r.extension = e,
|
|
r
|
|
}
|
|
e.id = f.oids[e.name]
|
|
}
|
|
if (void 0 !== e.value)
|
|
return e;
|
|
if ("keyUsage" === e.name) {
|
|
var a = 0
|
|
, i = 0
|
|
, s = 0;
|
|
e.digitalSignature && (i |= 128,
|
|
a = 7),
|
|
e.nonRepudiation && (i |= 64,
|
|
a = 6),
|
|
e.keyEncipherment && (i |= 32,
|
|
a = 5),
|
|
e.dataEncipherment && (i |= 16,
|
|
a = 4),
|
|
e.keyAgreement && (i |= 8,
|
|
a = 3),
|
|
e.keyCertSign && (i |= 4,
|
|
a = 2),
|
|
e.cRLSign && (i |= 2,
|
|
a = 1),
|
|
e.encipherOnly && (i |= 1,
|
|
a = 0),
|
|
e.decipherOnly && (s |= 128,
|
|
a = 7);
|
|
var o = String.fromCharCode(a);
|
|
0 !== s ? o += String.fromCharCode(i) + String.fromCharCode(s) : 0 !== i && (o += String.fromCharCode(i)),
|
|
e.value = p.create(p.Class.UNIVERSAL, p.Type.BITSTRING, !1, o)
|
|
} else if ("basicConstraints" === e.name)
|
|
e.value = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, []),
|
|
e.cA && e.value.value.push(p.create(p.Class.UNIVERSAL, p.Type.BOOLEAN, !1, String.fromCharCode(255))),
|
|
"pathLenConstraint"in e && e.value.value.push(p.create(p.Class.UNIVERSAL, p.Type.INTEGER, !1, p.integerToDer(e.pathLenConstraint).getBytes()));
|
|
else if ("extKeyUsage" === e.name) {
|
|
e.value = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, []);
|
|
var c = e.value.value;
|
|
for (var u in e)
|
|
!0 === e[u] && (u in h ? c.push(p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(h[u]).getBytes())) : -1 !== u.indexOf(".") && c.push(p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(u).getBytes())))
|
|
} else if ("nsCertType" === e.name) {
|
|
var a = 0
|
|
, i = 0;
|
|
e.client && (i |= 128,
|
|
a = 7),
|
|
e.server && (i |= 64,
|
|
a = 6),
|
|
e.email && (i |= 32,
|
|
a = 5),
|
|
e.objsign && (i |= 16,
|
|
a = 4),
|
|
e.reserved && (i |= 8,
|
|
a = 3),
|
|
e.sslCA && (i |= 4,
|
|
a = 2),
|
|
e.emailCA && (i |= 2,
|
|
a = 1),
|
|
e.objCA && (i |= 1,
|
|
a = 0);
|
|
var o = String.fromCharCode(a);
|
|
0 !== i && (o += String.fromCharCode(i)),
|
|
e.value = p.create(p.Class.UNIVERSAL, p.Type.BITSTRING, !1, o)
|
|
} else if ("subjectAltName" === e.name || "issuerAltName" === e.name) {
|
|
e.value = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, []);
|
|
for (var d, y = 0; y < e.altNames.length; ++y) {
|
|
d = e.altNames[y];
|
|
var o = d.value;
|
|
if (7 === d.type && d.ip) {
|
|
if (null === (o = l.util.bytesFromIP(d.ip))) {
|
|
var r = new Error('Extension "ip" value is not a valid IPv4 or IPv6 address.');
|
|
throw r.extension = e,
|
|
r
|
|
}
|
|
} else
|
|
8 === d.type && (o = d.oid ? p.oidToDer(p.oidToDer(d.oid)) : p.oidToDer(o));
|
|
e.value.value.push(p.create(p.Class.CONTEXT_SPECIFIC, d.type, !1, o))
|
|
}
|
|
} else if ("nsComment" === e.name && t.cert) {
|
|
if (!/^[\x00-\x7F]*$/.test(e.comment) || e.comment.length < 1 || e.comment.length > 128)
|
|
throw new Error('Invalid "nsComment" content.');
|
|
e.value = p.create(p.Class.UNIVERSAL, p.Type.IA5STRING, !1, e.comment)
|
|
} else if ("subjectKeyIdentifier" === e.name && t.cert) {
|
|
var g = t.cert.generateSubjectKeyIdentifier();
|
|
e.subjectKeyIdentifier = g.toHex(),
|
|
e.value = p.create(p.Class.UNIVERSAL, p.Type.OCTETSTRING, !1, g.getBytes())
|
|
} else if ("authorityKeyIdentifier" === e.name && t.cert) {
|
|
e.value = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, []);
|
|
var c = e.value.value;
|
|
if (e.keyIdentifier) {
|
|
var v = !0 === e.keyIdentifier ? t.cert.generateSubjectKeyIdentifier().getBytes() : e.keyIdentifier;
|
|
c.push(p.create(p.Class.CONTEXT_SPECIFIC, 0, !1, v))
|
|
}
|
|
if (e.authorityCertIssuer) {
|
|
var m = [p.create(p.Class.CONTEXT_SPECIFIC, 4, !0, [n(!0 === e.authorityCertIssuer ? t.cert.issuer : e.authorityCertIssuer)])];
|
|
c.push(p.create(p.Class.CONTEXT_SPECIFIC, 1, !0, m))
|
|
}
|
|
if (e.serialNumber) {
|
|
var C = l.util.hexToBytes(!0 === e.serialNumber ? t.cert.serialNumber : e.serialNumber);
|
|
c.push(p.create(p.Class.CONTEXT_SPECIFIC, 2, !1, C))
|
|
}
|
|
} else if ("cRLDistributionPoints" === e.name) {
|
|
e.value = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, []);
|
|
for (var d, c = e.value.value, E = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, []), S = p.create(p.Class.CONTEXT_SPECIFIC, 0, !0, []), y = 0; y < e.altNames.length; ++y) {
|
|
d = e.altNames[y];
|
|
var o = d.value;
|
|
if (7 === d.type && d.ip) {
|
|
if (null === (o = l.util.bytesFromIP(d.ip))) {
|
|
var r = new Error('Extension "ip" value is not a valid IPv4 or IPv6 address.');
|
|
throw r.extension = e,
|
|
r
|
|
}
|
|
} else
|
|
8 === d.type && (o = d.oid ? p.oidToDer(p.oidToDer(d.oid)) : p.oidToDer(o));
|
|
S.value.push(p.create(p.Class.CONTEXT_SPECIFIC, d.type, !1, o))
|
|
}
|
|
E.value.push(p.create(p.Class.CONTEXT_SPECIFIC, 0, !0, [S])),
|
|
c.push(E)
|
|
}
|
|
if (void 0 === e.value) {
|
|
var r = new Error("Extension value not specified.");
|
|
throw r.extension = e,
|
|
r
|
|
}
|
|
return e
|
|
}
|
|
function o(e, t) {
|
|
switch (e) {
|
|
case h["RSASSA-PSS"]:
|
|
var r = [];
|
|
return void 0 !== t.hash.algorithmOid && r.push(p.create(p.Class.CONTEXT_SPECIFIC, 0, !0, [p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(t.hash.algorithmOid).getBytes()), p.create(p.Class.UNIVERSAL, p.Type.NULL, !1, "")])])),
|
|
void 0 !== t.mgf.algorithmOid && r.push(p.create(p.Class.CONTEXT_SPECIFIC, 1, !0, [p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(t.mgf.algorithmOid).getBytes()), p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(t.mgf.hash.algorithmOid).getBytes()), p.create(p.Class.UNIVERSAL, p.Type.NULL, !1, "")])])])),
|
|
void 0 !== t.saltLength && r.push(p.create(p.Class.CONTEXT_SPECIFIC, 2, !0, [p.create(p.Class.UNIVERSAL, p.Type.INTEGER, !1, p.integerToDer(t.saltLength).getBytes())])),
|
|
p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, r);
|
|
default:
|
|
return p.create(p.Class.UNIVERSAL, p.Type.NULL, !1, "")
|
|
}
|
|
}
|
|
function c(e) {
|
|
var t = p.create(p.Class.CONTEXT_SPECIFIC, 0, !0, []);
|
|
if (0 === e.attributes.length)
|
|
return t;
|
|
for (var r = e.attributes, a = 0; a < r.length; ++a) {
|
|
var n = r[a]
|
|
, i = n.value
|
|
, s = p.Type.UTF8;
|
|
"valueTagClass"in n && (s = n.valueTagClass),
|
|
s === p.Type.UTF8 && (i = l.util.encodeUtf8(i));
|
|
var o = !1;
|
|
"valueConstructed"in n && (o = n.valueConstructed);
|
|
var c = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(n.type).getBytes()), p.create(p.Class.UNIVERSAL, p.Type.SET, !0, [p.create(p.Class.UNIVERSAL, s, o, i)])]);
|
|
t.value.push(c)
|
|
}
|
|
return t
|
|
}
|
|
function u(e) {
|
|
return e >= S && e < T ? p.create(p.Class.UNIVERSAL, p.Type.UTCTIME, !1, p.dateToUtcTime(e)) : p.create(p.Class.UNIVERSAL, p.Type.GENERALIZEDTIME, !1, p.dateToGeneralizedTime(e))
|
|
}
|
|
var l = r(0);
|
|
r(5),
|
|
r(3),
|
|
r(10),
|
|
r(4),
|
|
r(39),
|
|
r(6),
|
|
r(7),
|
|
r(18),
|
|
r(11),
|
|
r(1);
|
|
var p = l.asn1
|
|
, f = e.exports = l.pki = l.pki || {}
|
|
, h = f.oids
|
|
, d = {};
|
|
d.CN = h.commonName,
|
|
d.commonName = "CN",
|
|
d.C = h.countryName,
|
|
d.countryName = "C",
|
|
d.L = h.localityName,
|
|
d.localityName = "L",
|
|
d.ST = h.stateOrProvinceName,
|
|
d.stateOrProvinceName = "ST",
|
|
d.O = h.organizationName,
|
|
d.organizationName = "O",
|
|
d.OU = h.organizationalUnitName,
|
|
d.organizationalUnitName = "OU",
|
|
d.E = h.emailAddress,
|
|
d.emailAddress = "E";
|
|
var y = l.pki.rsa.publicKeyValidator
|
|
, g = {
|
|
name: "Certificate",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "Certificate.TBSCertificate",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
captureAsn1: "tbsCertificate",
|
|
value: [{
|
|
name: "Certificate.TBSCertificate.version",
|
|
tagClass: p.Class.CONTEXT_SPECIFIC,
|
|
type: 0,
|
|
constructed: !0,
|
|
optional: !0,
|
|
value: [{
|
|
name: "Certificate.TBSCertificate.version.integer",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "certVersion"
|
|
}]
|
|
}, {
|
|
name: "Certificate.TBSCertificate.serialNumber",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "certSerialNumber"
|
|
}, {
|
|
name: "Certificate.TBSCertificate.signature",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "Certificate.TBSCertificate.signature.algorithm",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.OID,
|
|
constructed: !1,
|
|
capture: "certinfoSignatureOid"
|
|
}, {
|
|
name: "Certificate.TBSCertificate.signature.parameters",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
optional: !0,
|
|
captureAsn1: "certinfoSignatureParams"
|
|
}]
|
|
}, {
|
|
name: "Certificate.TBSCertificate.issuer",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
captureAsn1: "certIssuer"
|
|
}, {
|
|
name: "Certificate.TBSCertificate.validity",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "Certificate.TBSCertificate.validity.notBefore (utc)",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.UTCTIME,
|
|
constructed: !1,
|
|
optional: !0,
|
|
capture: "certValidity1UTCTime"
|
|
}, {
|
|
name: "Certificate.TBSCertificate.validity.notBefore (generalized)",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.GENERALIZEDTIME,
|
|
constructed: !1,
|
|
optional: !0,
|
|
capture: "certValidity2GeneralizedTime"
|
|
}, {
|
|
name: "Certificate.TBSCertificate.validity.notAfter (utc)",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.UTCTIME,
|
|
constructed: !1,
|
|
optional: !0,
|
|
capture: "certValidity3UTCTime"
|
|
}, {
|
|
name: "Certificate.TBSCertificate.validity.notAfter (generalized)",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.GENERALIZEDTIME,
|
|
constructed: !1,
|
|
optional: !0,
|
|
capture: "certValidity4GeneralizedTime"
|
|
}]
|
|
}, {
|
|
name: "Certificate.TBSCertificate.subject",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
captureAsn1: "certSubject"
|
|
}, y, {
|
|
name: "Certificate.TBSCertificate.issuerUniqueID",
|
|
tagClass: p.Class.CONTEXT_SPECIFIC,
|
|
type: 1,
|
|
constructed: !0,
|
|
optional: !0,
|
|
value: [{
|
|
name: "Certificate.TBSCertificate.issuerUniqueID.id",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.BITSTRING,
|
|
constructed: !1,
|
|
captureBitStringValue: "certIssuerUniqueId"
|
|
}]
|
|
}, {
|
|
name: "Certificate.TBSCertificate.subjectUniqueID",
|
|
tagClass: p.Class.CONTEXT_SPECIFIC,
|
|
type: 2,
|
|
constructed: !0,
|
|
optional: !0,
|
|
value: [{
|
|
name: "Certificate.TBSCertificate.subjectUniqueID.id",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.BITSTRING,
|
|
constructed: !1,
|
|
captureBitStringValue: "certSubjectUniqueId"
|
|
}]
|
|
}, {
|
|
name: "Certificate.TBSCertificate.extensions",
|
|
tagClass: p.Class.CONTEXT_SPECIFIC,
|
|
type: 3,
|
|
constructed: !0,
|
|
captureAsn1: "certExtensions",
|
|
optional: !0
|
|
}]
|
|
}, {
|
|
name: "Certificate.signatureAlgorithm",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "Certificate.signatureAlgorithm.algorithm",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.OID,
|
|
constructed: !1,
|
|
capture: "certSignatureOid"
|
|
}, {
|
|
name: "Certificate.TBSCertificate.signature.parameters",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
optional: !0,
|
|
captureAsn1: "certSignatureParams"
|
|
}]
|
|
}, {
|
|
name: "Certificate.signatureValue",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.BITSTRING,
|
|
constructed: !1,
|
|
captureBitStringValue: "certSignature"
|
|
}]
|
|
}
|
|
, v = {
|
|
name: "rsapss",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "rsapss.hashAlgorithm",
|
|
tagClass: p.Class.CONTEXT_SPECIFIC,
|
|
type: 0,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "rsapss.hashAlgorithm.AlgorithmIdentifier",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Class.SEQUENCE,
|
|
constructed: !0,
|
|
optional: !0,
|
|
value: [{
|
|
name: "rsapss.hashAlgorithm.AlgorithmIdentifier.algorithm",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.OID,
|
|
constructed: !1,
|
|
capture: "hashOid"
|
|
}]
|
|
}]
|
|
}, {
|
|
name: "rsapss.maskGenAlgorithm",
|
|
tagClass: p.Class.CONTEXT_SPECIFIC,
|
|
type: 1,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "rsapss.maskGenAlgorithm.AlgorithmIdentifier",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Class.SEQUENCE,
|
|
constructed: !0,
|
|
optional: !0,
|
|
value: [{
|
|
name: "rsapss.maskGenAlgorithm.AlgorithmIdentifier.algorithm",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.OID,
|
|
constructed: !1,
|
|
capture: "maskGenOid"
|
|
}, {
|
|
name: "rsapss.maskGenAlgorithm.AlgorithmIdentifier.params",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "rsapss.maskGenAlgorithm.AlgorithmIdentifier.params.algorithm",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.OID,
|
|
constructed: !1,
|
|
capture: "maskGenHashOid"
|
|
}]
|
|
}]
|
|
}]
|
|
}, {
|
|
name: "rsapss.saltLength",
|
|
tagClass: p.Class.CONTEXT_SPECIFIC,
|
|
type: 2,
|
|
optional: !0,
|
|
value: [{
|
|
name: "rsapss.saltLength.saltLength",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Class.INTEGER,
|
|
constructed: !1,
|
|
capture: "saltLength"
|
|
}]
|
|
}, {
|
|
name: "rsapss.trailerField",
|
|
tagClass: p.Class.CONTEXT_SPECIFIC,
|
|
type: 3,
|
|
optional: !0,
|
|
value: [{
|
|
name: "rsapss.trailer.trailer",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Class.INTEGER,
|
|
constructed: !1,
|
|
capture: "trailer"
|
|
}]
|
|
}]
|
|
}
|
|
, m = {
|
|
name: "CertificationRequestInfo",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
captureAsn1: "certificationRequestInfo",
|
|
value: [{
|
|
name: "CertificationRequestInfo.integer",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "certificationRequestInfoVersion"
|
|
}, {
|
|
name: "CertificationRequestInfo.subject",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
captureAsn1: "certificationRequestInfoSubject"
|
|
}, y, {
|
|
name: "CertificationRequestInfo.attributes",
|
|
tagClass: p.Class.CONTEXT_SPECIFIC,
|
|
type: 0,
|
|
constructed: !0,
|
|
optional: !0,
|
|
capture: "certificationRequestInfoAttributes",
|
|
value: [{
|
|
name: "CertificationRequestInfo.attributes",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "CertificationRequestInfo.attributes.type",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.OID,
|
|
constructed: !1
|
|
}, {
|
|
name: "CertificationRequestInfo.attributes.value",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SET,
|
|
constructed: !0
|
|
}]
|
|
}]
|
|
}]
|
|
}
|
|
, C = {
|
|
name: "CertificationRequest",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
captureAsn1: "csr",
|
|
value: [m, {
|
|
name: "CertificationRequest.signatureAlgorithm",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "CertificationRequest.signatureAlgorithm.algorithm",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.OID,
|
|
constructed: !1,
|
|
capture: "csrSignatureOid"
|
|
}, {
|
|
name: "CertificationRequest.signatureAlgorithm.parameters",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
optional: !0,
|
|
captureAsn1: "csrSignatureParams"
|
|
}]
|
|
}, {
|
|
name: "CertificationRequest.signature",
|
|
tagClass: p.Class.UNIVERSAL,
|
|
type: p.Type.BITSTRING,
|
|
constructed: !1,
|
|
captureBitStringValue: "csrSignature"
|
|
}]
|
|
};
|
|
f.RDNAttributesAsArray = function(e, t) {
|
|
for (var r, a, n, i = [], s = 0; s < e.value.length; ++s) {
|
|
r = e.value[s];
|
|
for (var o = 0; o < r.value.length; ++o)
|
|
n = {},
|
|
a = r.value[o],
|
|
n.type = p.derToOid(a.value[0].value),
|
|
n.value = a.value[1].value,
|
|
n.valueTagClass = a.value[1].type,
|
|
n.type in h && (n.name = h[n.type],
|
|
n.name in d && (n.shortName = d[n.name])),
|
|
t && (t.update(n.type),
|
|
t.update(n.value)),
|
|
i.push(n)
|
|
}
|
|
return i
|
|
}
|
|
,
|
|
f.CRIAttributesAsArray = function(e) {
|
|
for (var t = [], r = 0; r < e.length; ++r)
|
|
for (var a = e[r], n = p.derToOid(a.value[0].value), i = a.value[1].value, s = 0; s < i.length; ++s) {
|
|
var o = {};
|
|
if (o.type = n,
|
|
o.value = i[s].value,
|
|
o.valueTagClass = i[s].type,
|
|
o.type in h && (o.name = h[o.type],
|
|
o.name in d && (o.shortName = d[o.name])),
|
|
o.type === h.extensionRequest) {
|
|
o.extensions = [];
|
|
for (var c = 0; c < o.value.length; ++c)
|
|
o.extensions.push(f.certificateExtensionFromAsn1(o.value[c]))
|
|
}
|
|
t.push(o)
|
|
}
|
|
return t
|
|
}
|
|
;
|
|
var E = function(e, t, r) {
|
|
var a = {};
|
|
if (e !== h["RSASSA-PSS"])
|
|
return a;
|
|
r && (a = {
|
|
hash: {
|
|
algorithmOid: h.sha1
|
|
},
|
|
mgf: {
|
|
algorithmOid: h.mgf1,
|
|
hash: {
|
|
algorithmOid: h.sha1
|
|
}
|
|
},
|
|
saltLength: 20
|
|
});
|
|
var n = {}
|
|
, i = [];
|
|
if (!p.validate(t, v, n, i)) {
|
|
var s = new Error("Cannot read RSASSA-PSS parameter block.");
|
|
throw s.errors = i,
|
|
s
|
|
}
|
|
return void 0 !== n.hashOid && (a.hash = a.hash || {},
|
|
a.hash.algorithmOid = p.derToOid(n.hashOid)),
|
|
void 0 !== n.maskGenOid && (a.mgf = a.mgf || {},
|
|
a.mgf.algorithmOid = p.derToOid(n.maskGenOid),
|
|
a.mgf.hash = a.mgf.hash || {},
|
|
a.mgf.hash.algorithmOid = p.derToOid(n.maskGenHashOid)),
|
|
void 0 !== n.saltLength && (a.saltLength = n.saltLength.charCodeAt(0)),
|
|
a
|
|
};
|
|
f.certificateFromPem = function(e, t, r) {
|
|
var a = l.pem.decode(e)[0];
|
|
if ("CERTIFICATE" !== a.type && "X509 CERTIFICATE" !== a.type && "TRUSTED CERTIFICATE" !== a.type) {
|
|
var n = new Error('Could not convert certificate from PEM; PEM header type is not "CERTIFICATE", "X509 CERTIFICATE", or "TRUSTED CERTIFICATE".');
|
|
throw n.headerType = a.type,
|
|
n
|
|
}
|
|
if (a.procType && "ENCRYPTED" === a.procType.type)
|
|
throw new Error("Could not convert certificate from PEM; PEM is encrypted.");
|
|
var i = p.fromDer(a.body, r);
|
|
return f.certificateFromAsn1(i, t)
|
|
}
|
|
,
|
|
f.certificateToPem = function(e, t) {
|
|
var r = {
|
|
type: "CERTIFICATE",
|
|
body: p.toDer(f.certificateToAsn1(e)).getBytes()
|
|
};
|
|
return l.pem.encode(r, {
|
|
maxline: t
|
|
})
|
|
}
|
|
,
|
|
f.publicKeyFromPem = function(e) {
|
|
var t = l.pem.decode(e)[0];
|
|
if ("PUBLIC KEY" !== t.type && "RSA PUBLIC KEY" !== t.type) {
|
|
var r = new Error('Could not convert public key from PEM; PEM header type is not "PUBLIC KEY" or "RSA PUBLIC KEY".');
|
|
throw r.headerType = t.type,
|
|
r
|
|
}
|
|
if (t.procType && "ENCRYPTED" === t.procType.type)
|
|
throw new Error("Could not convert public key from PEM; PEM is encrypted.");
|
|
var a = p.fromDer(t.body);
|
|
return f.publicKeyFromAsn1(a)
|
|
}
|
|
,
|
|
f.publicKeyToPem = function(e, t) {
|
|
var r = {
|
|
type: "PUBLIC KEY",
|
|
body: p.toDer(f.publicKeyToAsn1(e)).getBytes()
|
|
};
|
|
return l.pem.encode(r, {
|
|
maxline: t
|
|
})
|
|
}
|
|
,
|
|
f.publicKeyToRSAPublicKeyPem = function(e, t) {
|
|
var r = {
|
|
type: "RSA PUBLIC KEY",
|
|
body: p.toDer(f.publicKeyToRSAPublicKey(e)).getBytes()
|
|
};
|
|
return l.pem.encode(r, {
|
|
maxline: t
|
|
})
|
|
}
|
|
,
|
|
f.getPublicKeyFingerprint = function(e, t) {
|
|
t = t || {};
|
|
var r, a = t.md || l.md.sha1.create(), n = t.type || "RSAPublicKey";
|
|
switch (n) {
|
|
case "RSAPublicKey":
|
|
r = p.toDer(f.publicKeyToRSAPublicKey(e)).getBytes();
|
|
break;
|
|
case "SubjectPublicKeyInfo":
|
|
r = p.toDer(f.publicKeyToAsn1(e)).getBytes();
|
|
break;
|
|
default:
|
|
throw new Error('Unknown fingerprint type "' + t.type + '".')
|
|
}
|
|
a.start(),
|
|
a.update(r);
|
|
var i = a.digest();
|
|
if ("hex" === t.encoding) {
|
|
var s = i.toHex();
|
|
return t.delimiter ? s.match(/.{2}/g).join(t.delimiter) : s
|
|
}
|
|
if ("binary" === t.encoding)
|
|
return i.getBytes();
|
|
if (t.encoding)
|
|
throw new Error('Unknown encoding "' + t.encoding + '".');
|
|
return i
|
|
}
|
|
,
|
|
f.certificationRequestFromPem = function(e, t, r) {
|
|
var a = l.pem.decode(e)[0];
|
|
if ("CERTIFICATE REQUEST" !== a.type) {
|
|
var n = new Error('Could not convert certification request from PEM; PEM header type is not "CERTIFICATE REQUEST".');
|
|
throw n.headerType = a.type,
|
|
n
|
|
}
|
|
if (a.procType && "ENCRYPTED" === a.procType.type)
|
|
throw new Error("Could not convert certification request from PEM; PEM is encrypted.");
|
|
var i = p.fromDer(a.body, r);
|
|
return f.certificationRequestFromAsn1(i, t)
|
|
}
|
|
,
|
|
f.certificationRequestToPem = function(e, t) {
|
|
var r = {
|
|
type: "CERTIFICATE REQUEST",
|
|
body: p.toDer(f.certificationRequestToAsn1(e)).getBytes()
|
|
};
|
|
return l.pem.encode(r, {
|
|
maxline: t
|
|
})
|
|
}
|
|
,
|
|
f.createCertificate = function() {
|
|
var e = {};
|
|
return e.version = 2,
|
|
e.serialNumber = "00",
|
|
e.signatureOid = null,
|
|
e.signature = null,
|
|
e.siginfo = {},
|
|
e.siginfo.algorithmOid = null,
|
|
e.validity = {},
|
|
e.validity.notBefore = new Date,
|
|
e.validity.notAfter = new Date,
|
|
e.issuer = {},
|
|
e.issuer.getField = function(t) {
|
|
return a(e.issuer, t)
|
|
}
|
|
,
|
|
e.issuer.addField = function(t) {
|
|
i([t]),
|
|
e.issuer.attributes.push(t)
|
|
}
|
|
,
|
|
e.issuer.attributes = [],
|
|
e.issuer.hash = null,
|
|
e.subject = {},
|
|
e.subject.getField = function(t) {
|
|
return a(e.subject, t)
|
|
}
|
|
,
|
|
e.subject.addField = function(t) {
|
|
i([t]),
|
|
e.subject.attributes.push(t)
|
|
}
|
|
,
|
|
e.subject.attributes = [],
|
|
e.subject.hash = null,
|
|
e.extensions = [],
|
|
e.publicKey = null,
|
|
e.md = null,
|
|
e.setSubject = function(t, r) {
|
|
i(t),
|
|
e.subject.attributes = t,
|
|
delete e.subject.uniqueId,
|
|
r && (e.subject.uniqueId = r),
|
|
e.subject.hash = null
|
|
}
|
|
,
|
|
e.setIssuer = function(t, r) {
|
|
i(t),
|
|
e.issuer.attributes = t,
|
|
delete e.issuer.uniqueId,
|
|
r && (e.issuer.uniqueId = r),
|
|
e.issuer.hash = null
|
|
}
|
|
,
|
|
e.setExtensions = function(t) {
|
|
for (var r = 0; r < t.length; ++r)
|
|
s(t[r], {
|
|
cert: e
|
|
});
|
|
e.extensions = t
|
|
}
|
|
,
|
|
e.getExtension = function(t) {
|
|
"string" == typeof t && (t = {
|
|
name: t
|
|
});
|
|
for (var r, a = null, n = 0; null === a && n < e.extensions.length; ++n)
|
|
r = e.extensions[n],
|
|
t.id && r.id === t.id ? a = r : t.name && r.name === t.name && (a = r);
|
|
return a
|
|
}
|
|
,
|
|
e.sign = function(t, r) {
|
|
e.md = r || l.md.sha1.create();
|
|
var a = h[e.md.algorithm + "WithRSAEncryption"];
|
|
if (!a) {
|
|
var n = new Error("Could not compute certificate digest. Unknown message digest algorithm OID.");
|
|
throw n.algorithm = e.md.algorithm,
|
|
n
|
|
}
|
|
e.signatureOid = e.siginfo.algorithmOid = a,
|
|
e.tbsCertificate = f.getTBSCertificate(e);
|
|
var i = p.toDer(e.tbsCertificate);
|
|
e.md.update(i.getBytes()),
|
|
e.signature = t.sign(e.md)
|
|
}
|
|
,
|
|
e.verify = function(t) {
|
|
var r = !1;
|
|
if (!e.issued(t)) {
|
|
var a = t.issuer
|
|
, n = e.subject
|
|
, i = new Error("The parent certificate did not issue the given child certificate; the child certificate's issuer does not match the parent's subject.");
|
|
throw i.expectedIssuer = a.attributes,
|
|
i.actualIssuer = n.attributes,
|
|
i
|
|
}
|
|
var s = t.md;
|
|
if (null === s) {
|
|
if (t.signatureOid in h) {
|
|
switch (h[t.signatureOid]) {
|
|
case "sha1WithRSAEncryption":
|
|
s = l.md.sha1.create();
|
|
break;
|
|
case "md5WithRSAEncryption":
|
|
s = l.md.md5.create();
|
|
break;
|
|
case "sha256WithRSAEncryption":
|
|
s = l.md.sha256.create();
|
|
break;
|
|
case "sha384WithRSAEncryption":
|
|
s = l.md.sha384.create();
|
|
break;
|
|
case "sha512WithRSAEncryption":
|
|
s = l.md.sha512.create();
|
|
break;
|
|
case "RSASSA-PSS":
|
|
s = l.md.sha256.create()
|
|
}
|
|
}
|
|
if (null === s) {
|
|
var i = new Error("Could not compute certificate digest. Unknown signature OID.");
|
|
throw i.signatureOid = t.signatureOid,
|
|
i
|
|
}
|
|
var o = t.tbsCertificate || f.getTBSCertificate(t)
|
|
, c = p.toDer(o);
|
|
s.update(c.getBytes())
|
|
}
|
|
if (null !== s) {
|
|
var u;
|
|
switch (t.signatureOid) {
|
|
case h.sha1WithRSAEncryption:
|
|
u = void 0;
|
|
break;
|
|
case h["RSASSA-PSS"]:
|
|
var d, y;
|
|
if (void 0 === (d = h[t.signatureParameters.mgf.hash.algorithmOid]) || void 0 === l.md[d]) {
|
|
var i = new Error("Unsupported MGF hash function.");
|
|
throw i.oid = t.signatureParameters.mgf.hash.algorithmOid,
|
|
i.name = d,
|
|
i
|
|
}
|
|
if (void 0 === (y = h[t.signatureParameters.mgf.algorithmOid]) || void 0 === l.mgf[y]) {
|
|
var i = new Error("Unsupported MGF function.");
|
|
throw i.oid = t.signatureParameters.mgf.algorithmOid,
|
|
i.name = y,
|
|
i
|
|
}
|
|
if (y = l.mgf[y].create(l.md[d].create()),
|
|
void 0 === (d = h[t.signatureParameters.hash.algorithmOid]) || void 0 === l.md[d])
|
|
throw {
|
|
message: "Unsupported RSASSA-PSS hash function.",
|
|
oid: t.signatureParameters.hash.algorithmOid,
|
|
name: d
|
|
};
|
|
u = l.pss.create(l.md[d].create(), y, t.signatureParameters.saltLength)
|
|
}
|
|
r = e.publicKey.verify(s.digest().getBytes(), t.signature, u)
|
|
}
|
|
return r
|
|
}
|
|
,
|
|
e.isIssuer = function(t) {
|
|
var r = !1
|
|
, a = e.issuer
|
|
, n = t.subject;
|
|
if (a.hash && n.hash)
|
|
r = a.hash === n.hash;
|
|
else if (a.attributes.length === n.attributes.length) {
|
|
r = !0;
|
|
for (var i, s, o = 0; r && o < a.attributes.length; ++o)
|
|
i = a.attributes[o],
|
|
s = n.attributes[o],
|
|
i.type === s.type && i.value === s.value || (r = !1)
|
|
}
|
|
return r
|
|
}
|
|
,
|
|
e.issued = function(t) {
|
|
return t.isIssuer(e)
|
|
}
|
|
,
|
|
e.generateSubjectKeyIdentifier = function() {
|
|
return f.getPublicKeyFingerprint(e.publicKey, {
|
|
type: "RSAPublicKey"
|
|
})
|
|
}
|
|
,
|
|
e.verifySubjectKeyIdentifier = function() {
|
|
for (var t = h.subjectKeyIdentifier, r = 0; r < e.extensions.length; ++r) {
|
|
var a = e.extensions[r];
|
|
if (a.id === t) {
|
|
var n = e.generateSubjectKeyIdentifier().getBytes();
|
|
return l.util.hexToBytes(a.subjectKeyIdentifier) === n
|
|
}
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
e
|
|
}
|
|
,
|
|
f.certificateFromAsn1 = function(e, t) {
|
|
var r = {}
|
|
, n = [];
|
|
if (!p.validate(e, g, r, n)) {
|
|
var s = new Error("Cannot read X.509 certificate. ASN.1 object is not an X509v3 Certificate.");
|
|
throw s.errors = n,
|
|
s
|
|
}
|
|
var o = p.derToOid(r.publicKeyOid);
|
|
if (o !== f.oids.rsaEncryption)
|
|
throw new Error("Cannot read public key. OID is not RSA.");
|
|
var c = f.createCertificate();
|
|
c.version = r.certVersion ? r.certVersion.charCodeAt(0) : 0;
|
|
var u = l.util.createBuffer(r.certSerialNumber);
|
|
c.serialNumber = u.toHex(),
|
|
c.signatureOid = l.asn1.derToOid(r.certSignatureOid),
|
|
c.signatureParameters = E(c.signatureOid, r.certSignatureParams, !0),
|
|
c.siginfo.algorithmOid = l.asn1.derToOid(r.certinfoSignatureOid),
|
|
c.siginfo.parameters = E(c.siginfo.algorithmOid, r.certinfoSignatureParams, !1),
|
|
c.signature = r.certSignature;
|
|
var d = [];
|
|
if (void 0 !== r.certValidity1UTCTime && d.push(p.utcTimeToDate(r.certValidity1UTCTime)),
|
|
void 0 !== r.certValidity2GeneralizedTime && d.push(p.generalizedTimeToDate(r.certValidity2GeneralizedTime)),
|
|
void 0 !== r.certValidity3UTCTime && d.push(p.utcTimeToDate(r.certValidity3UTCTime)),
|
|
void 0 !== r.certValidity4GeneralizedTime && d.push(p.generalizedTimeToDate(r.certValidity4GeneralizedTime)),
|
|
d.length > 2)
|
|
throw new Error("Cannot read notBefore/notAfter validity times; more than two times were provided in the certificate.");
|
|
if (d.length < 2)
|
|
throw new Error("Cannot read notBefore/notAfter validity times; they were not provided as either UTCTime or GeneralizedTime.");
|
|
if (c.validity.notBefore = d[0],
|
|
c.validity.notAfter = d[1],
|
|
c.tbsCertificate = r.tbsCertificate,
|
|
t) {
|
|
if (c.md = null,
|
|
c.signatureOid in h) {
|
|
var o = h[c.signatureOid];
|
|
switch (o) {
|
|
case "sha1WithRSAEncryption":
|
|
c.md = l.md.sha1.create();
|
|
break;
|
|
case "md5WithRSAEncryption":
|
|
c.md = l.md.md5.create();
|
|
break;
|
|
case "sha256WithRSAEncryption":
|
|
c.md = l.md.sha256.create();
|
|
break;
|
|
case "sha384WithRSAEncryption":
|
|
c.md = l.md.sha384.create();
|
|
break;
|
|
case "sha512WithRSAEncryption":
|
|
c.md = l.md.sha512.create();
|
|
break;
|
|
case "RSASSA-PSS":
|
|
c.md = l.md.sha256.create()
|
|
}
|
|
}
|
|
if (null === c.md) {
|
|
var s = new Error("Could not compute certificate digest. Unknown signature OID.");
|
|
throw s.signatureOid = c.signatureOid,
|
|
s
|
|
}
|
|
var y = p.toDer(c.tbsCertificate);
|
|
c.md.update(y.getBytes())
|
|
}
|
|
var v = l.md.sha1.create();
|
|
c.issuer.getField = function(e) {
|
|
return a(c.issuer, e)
|
|
}
|
|
,
|
|
c.issuer.addField = function(e) {
|
|
i([e]),
|
|
c.issuer.attributes.push(e)
|
|
}
|
|
,
|
|
c.issuer.attributes = f.RDNAttributesAsArray(r.certIssuer, v),
|
|
r.certIssuerUniqueId && (c.issuer.uniqueId = r.certIssuerUniqueId),
|
|
c.issuer.hash = v.digest().toHex();
|
|
var m = l.md.sha1.create();
|
|
return c.subject.getField = function(e) {
|
|
return a(c.subject, e)
|
|
}
|
|
,
|
|
c.subject.addField = function(e) {
|
|
i([e]),
|
|
c.subject.attributes.push(e)
|
|
}
|
|
,
|
|
c.subject.attributes = f.RDNAttributesAsArray(r.certSubject, m),
|
|
r.certSubjectUniqueId && (c.subject.uniqueId = r.certSubjectUniqueId),
|
|
c.subject.hash = m.digest().toHex(),
|
|
r.certExtensions ? c.extensions = f.certificateExtensionsFromAsn1(r.certExtensions) : c.extensions = [],
|
|
c.publicKey = f.publicKeyFromAsn1(r.subjectPublicKeyInfo),
|
|
c
|
|
}
|
|
,
|
|
f.certificateExtensionsFromAsn1 = function(e) {
|
|
for (var t = [], r = 0; r < e.value.length; ++r)
|
|
for (var a = e.value[r], n = 0; n < a.value.length; ++n)
|
|
t.push(f.certificateExtensionFromAsn1(a.value[n]));
|
|
return t
|
|
}
|
|
,
|
|
f.certificateExtensionFromAsn1 = function(e) {
|
|
var t = {};
|
|
if (t.id = p.derToOid(e.value[0].value),
|
|
t.critical = !1,
|
|
e.value[1].type === p.Type.BOOLEAN ? (t.critical = 0 !== e.value[1].value.charCodeAt(0),
|
|
t.value = e.value[2].value) : t.value = e.value[1].value,
|
|
t.id in h)
|
|
if (t.name = h[t.id],
|
|
"keyUsage" === t.name) {
|
|
var r = p.fromDer(t.value)
|
|
, a = 0
|
|
, n = 0;
|
|
r.value.length > 1 && (a = r.value.charCodeAt(1),
|
|
n = r.value.length > 2 ? r.value.charCodeAt(2) : 0),
|
|
t.digitalSignature = 128 == (128 & a),
|
|
t.nonRepudiation = 64 == (64 & a),
|
|
t.keyEncipherment = 32 == (32 & a),
|
|
t.dataEncipherment = 16 == (16 & a),
|
|
t.keyAgreement = 8 == (8 & a),
|
|
t.keyCertSign = 4 == (4 & a),
|
|
t.cRLSign = 2 == (2 & a),
|
|
t.encipherOnly = 1 == (1 & a),
|
|
t.decipherOnly = 128 == (128 & n)
|
|
} else if ("basicConstraints" === t.name) {
|
|
var r = p.fromDer(t.value);
|
|
r.value.length > 0 && r.value[0].type === p.Type.BOOLEAN ? t.cA = 0 !== r.value[0].value.charCodeAt(0) : t.cA = !1;
|
|
var i = null;
|
|
r.value.length > 0 && r.value[0].type === p.Type.INTEGER ? i = r.value[0].value : r.value.length > 1 && (i = r.value[1].value),
|
|
null !== i && (t.pathLenConstraint = p.derToInteger(i))
|
|
} else if ("extKeyUsage" === t.name)
|
|
for (var r = p.fromDer(t.value), s = 0; s < r.value.length; ++s) {
|
|
var o = p.derToOid(r.value[s].value);
|
|
o in h ? t[h[o]] = !0 : t[o] = !0
|
|
}
|
|
else if ("nsCertType" === t.name) {
|
|
var r = p.fromDer(t.value)
|
|
, a = 0;
|
|
r.value.length > 1 && (a = r.value.charCodeAt(1)),
|
|
t.client = 128 == (128 & a),
|
|
t.server = 64 == (64 & a),
|
|
t.email = 32 == (32 & a),
|
|
t.objsign = 16 == (16 & a),
|
|
t.reserved = 8 == (8 & a),
|
|
t.sslCA = 4 == (4 & a),
|
|
t.emailCA = 2 == (2 & a),
|
|
t.objCA = 1 == (1 & a)
|
|
} else if ("subjectAltName" === t.name || "issuerAltName" === t.name) {
|
|
t.altNames = [];
|
|
for (var c, r = p.fromDer(t.value), u = 0; u < r.value.length; ++u) {
|
|
c = r.value[u];
|
|
var f = {
|
|
type: c.type,
|
|
value: c.value
|
|
};
|
|
switch (t.altNames.push(f),
|
|
c.type) {
|
|
case 1:
|
|
case 2:
|
|
case 6:
|
|
break;
|
|
case 7:
|
|
f.ip = l.util.bytesToIP(c.value);
|
|
break;
|
|
case 8:
|
|
f.oid = p.derToOid(c.value)
|
|
}
|
|
}
|
|
} else if ("subjectKeyIdentifier" === t.name) {
|
|
var r = p.fromDer(t.value);
|
|
t.subjectKeyIdentifier = l.util.bytesToHex(r.value)
|
|
}
|
|
return t
|
|
}
|
|
,
|
|
f.certificationRequestFromAsn1 = function(e, t) {
|
|
var r = {}
|
|
, n = [];
|
|
if (!p.validate(e, C, r, n)) {
|
|
var s = new Error("Cannot read PKCS#10 certificate request. ASN.1 object is not a PKCS#10 CertificationRequest.");
|
|
throw s.errors = n,
|
|
s
|
|
}
|
|
var o = p.derToOid(r.publicKeyOid);
|
|
if (o !== f.oids.rsaEncryption)
|
|
throw new Error("Cannot read public key. OID is not RSA.");
|
|
var c = f.createCertificationRequest();
|
|
if (c.version = r.csrVersion ? r.csrVersion.charCodeAt(0) : 0,
|
|
c.signatureOid = l.asn1.derToOid(r.csrSignatureOid),
|
|
c.signatureParameters = E(c.signatureOid, r.csrSignatureParams, !0),
|
|
c.siginfo.algorithmOid = l.asn1.derToOid(r.csrSignatureOid),
|
|
c.siginfo.parameters = E(c.siginfo.algorithmOid, r.csrSignatureParams, !1),
|
|
c.signature = r.csrSignature,
|
|
c.certificationRequestInfo = r.certificationRequestInfo,
|
|
t) {
|
|
if (c.md = null,
|
|
c.signatureOid in h) {
|
|
var o = h[c.signatureOid];
|
|
switch (o) {
|
|
case "sha1WithRSAEncryption":
|
|
c.md = l.md.sha1.create();
|
|
break;
|
|
case "md5WithRSAEncryption":
|
|
c.md = l.md.md5.create();
|
|
break;
|
|
case "sha256WithRSAEncryption":
|
|
c.md = l.md.sha256.create();
|
|
break;
|
|
case "sha384WithRSAEncryption":
|
|
c.md = l.md.sha384.create();
|
|
break;
|
|
case "sha512WithRSAEncryption":
|
|
c.md = l.md.sha512.create();
|
|
break;
|
|
case "RSASSA-PSS":
|
|
c.md = l.md.sha256.create()
|
|
}
|
|
}
|
|
if (null === c.md) {
|
|
var s = new Error("Could not compute certification request digest. Unknown signature OID.");
|
|
throw s.signatureOid = c.signatureOid,
|
|
s
|
|
}
|
|
var u = p.toDer(c.certificationRequestInfo);
|
|
c.md.update(u.getBytes())
|
|
}
|
|
var d = l.md.sha1.create();
|
|
return c.subject.getField = function(e) {
|
|
return a(c.subject, e)
|
|
}
|
|
,
|
|
c.subject.addField = function(e) {
|
|
i([e]),
|
|
c.subject.attributes.push(e)
|
|
}
|
|
,
|
|
c.subject.attributes = f.RDNAttributesAsArray(r.certificationRequestInfoSubject, d),
|
|
c.subject.hash = d.digest().toHex(),
|
|
c.publicKey = f.publicKeyFromAsn1(r.subjectPublicKeyInfo),
|
|
c.getAttribute = function(e) {
|
|
return a(c, e)
|
|
}
|
|
,
|
|
c.addAttribute = function(e) {
|
|
i([e]),
|
|
c.attributes.push(e)
|
|
}
|
|
,
|
|
c.attributes = f.CRIAttributesAsArray(r.certificationRequestInfoAttributes || []),
|
|
c
|
|
}
|
|
,
|
|
f.createCertificationRequest = function() {
|
|
var e = {};
|
|
return e.version = 0,
|
|
e.signatureOid = null,
|
|
e.signature = null,
|
|
e.siginfo = {},
|
|
e.siginfo.algorithmOid = null,
|
|
e.subject = {},
|
|
e.subject.getField = function(t) {
|
|
return a(e.subject, t)
|
|
}
|
|
,
|
|
e.subject.addField = function(t) {
|
|
i([t]),
|
|
e.subject.attributes.push(t)
|
|
}
|
|
,
|
|
e.subject.attributes = [],
|
|
e.subject.hash = null,
|
|
e.publicKey = null,
|
|
e.attributes = [],
|
|
e.getAttribute = function(t) {
|
|
return a(e, t)
|
|
}
|
|
,
|
|
e.addAttribute = function(t) {
|
|
i([t]),
|
|
e.attributes.push(t)
|
|
}
|
|
,
|
|
e.md = null,
|
|
e.setSubject = function(t) {
|
|
i(t),
|
|
e.subject.attributes = t,
|
|
e.subject.hash = null
|
|
}
|
|
,
|
|
e.setAttributes = function(t) {
|
|
i(t),
|
|
e.attributes = t
|
|
}
|
|
,
|
|
e.sign = function(t, r) {
|
|
e.md = r || l.md.sha1.create();
|
|
var a = h[e.md.algorithm + "WithRSAEncryption"];
|
|
if (!a) {
|
|
var n = new Error("Could not compute certification request digest. Unknown message digest algorithm OID.");
|
|
throw n.algorithm = e.md.algorithm,
|
|
n
|
|
}
|
|
e.signatureOid = e.siginfo.algorithmOid = a,
|
|
e.certificationRequestInfo = f.getCertificationRequestInfo(e);
|
|
var i = p.toDer(e.certificationRequestInfo);
|
|
e.md.update(i.getBytes()),
|
|
e.signature = t.sign(e.md)
|
|
}
|
|
,
|
|
e.verify = function() {
|
|
var t = !1
|
|
, r = e.md;
|
|
if (null === r) {
|
|
if (e.signatureOid in h) {
|
|
switch (h[e.signatureOid]) {
|
|
case "sha1WithRSAEncryption":
|
|
r = l.md.sha1.create();
|
|
break;
|
|
case "md5WithRSAEncryption":
|
|
r = l.md.md5.create();
|
|
break;
|
|
case "sha256WithRSAEncryption":
|
|
r = l.md.sha256.create();
|
|
break;
|
|
case "sha384WithRSAEncryption":
|
|
r = l.md.sha384.create();
|
|
break;
|
|
case "sha512WithRSAEncryption":
|
|
r = l.md.sha512.create();
|
|
break;
|
|
case "RSASSA-PSS":
|
|
r = l.md.sha256.create()
|
|
}
|
|
}
|
|
if (null === r) {
|
|
var a = new Error("Could not compute certification request digest. Unknown signature OID.");
|
|
throw a.signatureOid = e.signatureOid,
|
|
a
|
|
}
|
|
var n = e.certificationRequestInfo || f.getCertificationRequestInfo(e)
|
|
, i = p.toDer(n);
|
|
r.update(i.getBytes())
|
|
}
|
|
if (null !== r) {
|
|
var s;
|
|
switch (e.signatureOid) {
|
|
case h.sha1WithRSAEncryption:
|
|
break;
|
|
case h["RSASSA-PSS"]:
|
|
var o, c;
|
|
if (void 0 === (o = h[e.signatureParameters.mgf.hash.algorithmOid]) || void 0 === l.md[o]) {
|
|
var a = new Error("Unsupported MGF hash function.");
|
|
throw a.oid = e.signatureParameters.mgf.hash.algorithmOid,
|
|
a.name = o,
|
|
a
|
|
}
|
|
if (void 0 === (c = h[e.signatureParameters.mgf.algorithmOid]) || void 0 === l.mgf[c]) {
|
|
var a = new Error("Unsupported MGF function.");
|
|
throw a.oid = e.signatureParameters.mgf.algorithmOid,
|
|
a.name = c,
|
|
a
|
|
}
|
|
if (c = l.mgf[c].create(l.md[o].create()),
|
|
void 0 === (o = h[e.signatureParameters.hash.algorithmOid]) || void 0 === l.md[o]) {
|
|
var a = new Error("Unsupported RSASSA-PSS hash function.");
|
|
throw a.oid = e.signatureParameters.hash.algorithmOid,
|
|
a.name = o,
|
|
a
|
|
}
|
|
s = l.pss.create(l.md[o].create(), c, e.signatureParameters.saltLength)
|
|
}
|
|
t = e.publicKey.verify(r.digest().getBytes(), e.signature, s)
|
|
}
|
|
return t
|
|
}
|
|
,
|
|
e
|
|
}
|
|
;
|
|
const S = new Date("1950-01-01T00:00:00Z")
|
|
, T = new Date("2050-01-01T00:00:00Z");
|
|
f.getTBSCertificate = function(e) {
|
|
var t = u(e.validity.notBefore)
|
|
, r = u(e.validity.notAfter)
|
|
, a = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [p.create(p.Class.CONTEXT_SPECIFIC, 0, !0, [p.create(p.Class.UNIVERSAL, p.Type.INTEGER, !1, p.integerToDer(e.version).getBytes())]), p.create(p.Class.UNIVERSAL, p.Type.INTEGER, !1, l.util.hexToBytes(e.serialNumber)), p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(e.siginfo.algorithmOid).getBytes()), o(e.siginfo.algorithmOid, e.siginfo.parameters)]), n(e.issuer), p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [t, r]), n(e.subject), f.publicKeyToAsn1(e.publicKey)]);
|
|
return e.issuer.uniqueId && a.value.push(p.create(p.Class.CONTEXT_SPECIFIC, 1, !0, [p.create(p.Class.UNIVERSAL, p.Type.BITSTRING, !1, String.fromCharCode(0) + e.issuer.uniqueId)])),
|
|
e.subject.uniqueId && a.value.push(p.create(p.Class.CONTEXT_SPECIFIC, 2, !0, [p.create(p.Class.UNIVERSAL, p.Type.BITSTRING, !1, String.fromCharCode(0) + e.subject.uniqueId)])),
|
|
e.extensions.length > 0 && a.value.push(f.certificateExtensionsToAsn1(e.extensions)),
|
|
a
|
|
}
|
|
,
|
|
f.getCertificationRequestInfo = function(e) {
|
|
return p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [p.create(p.Class.UNIVERSAL, p.Type.INTEGER, !1, p.integerToDer(e.version).getBytes()), n(e.subject), f.publicKeyToAsn1(e.publicKey), c(e)])
|
|
}
|
|
,
|
|
f.distinguishedNameToAsn1 = function(e) {
|
|
return n(e)
|
|
}
|
|
,
|
|
f.certificateToAsn1 = function(e) {
|
|
var t = e.tbsCertificate || f.getTBSCertificate(e);
|
|
return p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [t, p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(e.signatureOid).getBytes()), o(e.signatureOid, e.signatureParameters)]), p.create(p.Class.UNIVERSAL, p.Type.BITSTRING, !1, String.fromCharCode(0) + e.signature)])
|
|
}
|
|
,
|
|
f.certificateExtensionsToAsn1 = function(e) {
|
|
var t = p.create(p.Class.CONTEXT_SPECIFIC, 3, !0, [])
|
|
, r = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, []);
|
|
t.value.push(r);
|
|
for (var a = 0; a < e.length; ++a)
|
|
r.value.push(f.certificateExtensionToAsn1(e[a]));
|
|
return t
|
|
}
|
|
,
|
|
f.certificateExtensionToAsn1 = function(e) {
|
|
var t = p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, []);
|
|
t.value.push(p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(e.id).getBytes())),
|
|
e.critical && t.value.push(p.create(p.Class.UNIVERSAL, p.Type.BOOLEAN, !1, String.fromCharCode(255)));
|
|
var r = e.value;
|
|
return "string" != typeof e.value && (r = p.toDer(r).getBytes()),
|
|
t.value.push(p.create(p.Class.UNIVERSAL, p.Type.OCTETSTRING, !1, r)),
|
|
t
|
|
}
|
|
,
|
|
f.certificationRequestToAsn1 = function(e) {
|
|
var t = e.certificationRequestInfo || f.getCertificationRequestInfo(e);
|
|
return p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [t, p.create(p.Class.UNIVERSAL, p.Type.SEQUENCE, !0, [p.create(p.Class.UNIVERSAL, p.Type.OID, !1, p.oidToDer(e.signatureOid).getBytes()), o(e.signatureOid, e.signatureParameters)]), p.create(p.Class.UNIVERSAL, p.Type.BITSTRING, !1, String.fromCharCode(0) + e.signature)])
|
|
}
|
|
,
|
|
f.createCaStore = function(e) {
|
|
function t(e) {
|
|
return r(e),
|
|
a.certs[e.hash] || null
|
|
}
|
|
function r(e) {
|
|
if (!e.hash) {
|
|
var t = l.md.sha1.create();
|
|
e.attributes = f.RDNAttributesAsArray(n(e), t),
|
|
e.hash = t.digest().toHex()
|
|
}
|
|
}
|
|
var a = {
|
|
certs: {}
|
|
};
|
|
if (a.getIssuer = function(e) {
|
|
return t(e.issuer)
|
|
}
|
|
,
|
|
a.addCertificate = function(e) {
|
|
if ("string" == typeof e && (e = l.pki.certificateFromPem(e)),
|
|
r(e.subject),
|
|
!a.hasCertificate(e))
|
|
if (e.subject.hash in a.certs) {
|
|
var t = a.certs[e.subject.hash];
|
|
l.util.isArray(t) || (t = [t]),
|
|
t.push(e),
|
|
a.certs[e.subject.hash] = t
|
|
} else
|
|
a.certs[e.subject.hash] = e
|
|
}
|
|
,
|
|
a.hasCertificate = function(e) {
|
|
"string" == typeof e && (e = l.pki.certificateFromPem(e));
|
|
var r = t(e.subject);
|
|
if (!r)
|
|
return !1;
|
|
l.util.isArray(r) || (r = [r]);
|
|
for (var a = p.toDer(f.certificateToAsn1(e)).getBytes(), n = 0; n < r.length; ++n) {
|
|
if (a === p.toDer(f.certificateToAsn1(r[n])).getBytes())
|
|
return !0
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
a.listAllCertificates = function() {
|
|
var e = [];
|
|
for (var t in a.certs)
|
|
if (a.certs.hasOwnProperty(t)) {
|
|
var r = a.certs[t];
|
|
if (l.util.isArray(r))
|
|
for (var n = 0; n < r.length; ++n)
|
|
e.push(r[n]);
|
|
else
|
|
e.push(r)
|
|
}
|
|
return e
|
|
}
|
|
,
|
|
a.removeCertificate = function(e) {
|
|
var n;
|
|
if ("string" == typeof e && (e = l.pki.certificateFromPem(e)),
|
|
r(e.subject),
|
|
!a.hasCertificate(e))
|
|
return null;
|
|
var i = t(e.subject);
|
|
if (!l.util.isArray(i))
|
|
return n = a.certs[e.subject.hash],
|
|
delete a.certs[e.subject.hash],
|
|
n;
|
|
for (var s = p.toDer(f.certificateToAsn1(e)).getBytes(), o = 0; o < i.length; ++o) {
|
|
s === p.toDer(f.certificateToAsn1(i[o])).getBytes() && (n = i[o],
|
|
i.splice(o, 1))
|
|
}
|
|
return 0 === i.length && delete a.certs[e.subject.hash],
|
|
n
|
|
}
|
|
,
|
|
e)
|
|
for (var i = 0; i < e.length; ++i) {
|
|
var s = e[i];
|
|
a.addCertificate(s)
|
|
}
|
|
return a
|
|
}
|
|
,
|
|
f.certificateError = {
|
|
bad_certificate: "forge.pki.BadCertificate",
|
|
unsupported_certificate: "forge.pki.UnsupportedCertificate",
|
|
certificate_revoked: "forge.pki.CertificateRevoked",
|
|
certificate_expired: "forge.pki.CertificateExpired",
|
|
certificate_unknown: "forge.pki.CertificateUnknown",
|
|
unknown_ca: "forge.pki.UnknownCertificateAuthority"
|
|
},
|
|
f.verifyCertificateChain = function(e, t, r) {
|
|
"function" == typeof r && (r = {
|
|
verify: r
|
|
}),
|
|
r = r || {},
|
|
t = t.slice(0);
|
|
var a = t.slice(0)
|
|
, n = r.validityCheckDate;
|
|
void 0 === n && (n = new Date);
|
|
var i = !0
|
|
, s = null
|
|
, o = 0;
|
|
do {
|
|
var c = t.shift()
|
|
, u = null
|
|
, p = !1;
|
|
if (n && (n < c.validity.notBefore || n > c.validity.notAfter) && (s = {
|
|
message: "Certificate is not valid yet or has expired.",
|
|
error: f.certificateError.certificate_expired,
|
|
notBefore: c.validity.notBefore,
|
|
notAfter: c.validity.notAfter,
|
|
now: n
|
|
}),
|
|
null === s) {
|
|
if (u = t[0] || e.getIssuer(c),
|
|
null === u && c.isIssuer(c) && (p = !0,
|
|
u = c),
|
|
u) {
|
|
var h = u;
|
|
l.util.isArray(h) || (h = [h]);
|
|
for (var d = !1; !d && h.length > 0; ) {
|
|
u = h.shift();
|
|
try {
|
|
d = u.verify(c)
|
|
} catch (e) {}
|
|
}
|
|
d || (s = {
|
|
message: "Certificate signature is invalid.",
|
|
error: f.certificateError.bad_certificate
|
|
})
|
|
}
|
|
null !== s || u && !p || e.hasCertificate(c) || (s = {
|
|
message: "Certificate is not trusted.",
|
|
error: f.certificateError.unknown_ca
|
|
})
|
|
}
|
|
if (null === s && u && !c.isIssuer(u) && (s = {
|
|
message: "Certificate issuer is invalid.",
|
|
error: f.certificateError.bad_certificate
|
|
}),
|
|
null === s)
|
|
for (var y = {
|
|
keyUsage: !0,
|
|
basicConstraints: !0
|
|
}, g = 0; null === s && g < c.extensions.length; ++g) {
|
|
var v = c.extensions[g];
|
|
!v.critical || v.name in y || (s = {
|
|
message: "Certificate has an unsupported critical extension.",
|
|
error: f.certificateError.unsupported_certificate
|
|
})
|
|
}
|
|
if (null === s && (!i || 0 === t.length && (!u || p))) {
|
|
var m = c.getExtension("basicConstraints")
|
|
, C = c.getExtension("keyUsage");
|
|
if (null !== C && (C.keyCertSign && null !== m || (s = {
|
|
message: "Certificate keyUsage or basicConstraints conflict or indicate that the certificate is not a CA. If the certificate is the only one in the chain or isn't the first then the certificate must be a valid CA.",
|
|
error: f.certificateError.bad_certificate
|
|
})),
|
|
null !== s || null === m || m.cA || (s = {
|
|
message: "Certificate basicConstraints indicates the certificate is not a CA.",
|
|
error: f.certificateError.bad_certificate
|
|
}),
|
|
null === s && null !== C && "pathLenConstraint"in m) {
|
|
o - 1 > m.pathLenConstraint && (s = {
|
|
message: "Certificate basicConstraints pathLenConstraint violated.",
|
|
error: f.certificateError.bad_certificate
|
|
})
|
|
}
|
|
}
|
|
var E = null === s || s.error
|
|
, S = r.verify ? r.verify(E, o, a) : E;
|
|
if (!0 !== S)
|
|
throw !0 === E && (s = {
|
|
message: "The application rejected the certificate.",
|
|
error: f.certificateError.bad_certificate
|
|
}),
|
|
(S || 0 === S) && ("object" != typeof S || l.util.isArray(S) ? "string" == typeof S && (s.error = S) : (S.message && (s.message = S.message),
|
|
S.error && (s.error = S.error))),
|
|
s;
|
|
s = null,
|
|
i = !1,
|
|
++o
|
|
} while (t.length > 0);
|
|
return !0
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(2),
|
|
r(1),
|
|
(e.exports = a.pss = a.pss || {}).create = function(e) {
|
|
3 === arguments.length && (e = {
|
|
md: arguments[0],
|
|
mgf: arguments[1],
|
|
saltLength: arguments[2]
|
|
});
|
|
var t = e.md
|
|
, r = e.mgf
|
|
, n = t.digestLength
|
|
, i = e.salt || null;
|
|
"string" == typeof i && (i = a.util.createBuffer(i));
|
|
var s;
|
|
if ("saltLength"in e)
|
|
s = e.saltLength;
|
|
else {
|
|
if (null === i)
|
|
throw new Error("Salt length not specified or specific salt not given.");
|
|
s = i.length()
|
|
}
|
|
if (null !== i && i.length() !== s)
|
|
throw new Error("Given salt length does not match length of given salt.");
|
|
var o = e.prng || a.random
|
|
, c = {};
|
|
return c.encode = function(e, c) {
|
|
var u, l = c - 1, p = Math.ceil(l / 8), f = e.digest().getBytes();
|
|
if (p < n + s + 2)
|
|
throw new Error("Message is too long to encrypt.");
|
|
var h;
|
|
h = null === i ? o.getBytesSync(s) : i.bytes();
|
|
var d = new a.util.ByteBuffer;
|
|
d.fillWithByte(0, 8),
|
|
d.putBytes(f),
|
|
d.putBytes(h),
|
|
t.start(),
|
|
t.update(d.getBytes());
|
|
var y = t.digest().getBytes()
|
|
, g = new a.util.ByteBuffer;
|
|
g.fillWithByte(0, p - s - n - 2),
|
|
g.putByte(1),
|
|
g.putBytes(h);
|
|
var v = g.getBytes()
|
|
, m = p - n - 1
|
|
, C = r.generate(y, m)
|
|
, E = "";
|
|
for (u = 0; u < m; u++)
|
|
E += String.fromCharCode(v.charCodeAt(u) ^ C.charCodeAt(u));
|
|
var S = 65280 >> 8 * p - l & 255;
|
|
return (E = String.fromCharCode(E.charCodeAt(0) & ~S) + E.substr(1)) + y + String.fromCharCode(188)
|
|
}
|
|
,
|
|
c.verify = function(e, i, o) {
|
|
var c, u = o - 1, l = Math.ceil(u / 8);
|
|
if (i = i.substr(-l),
|
|
l < n + s + 2)
|
|
throw new Error("Inconsistent parameters to PSS signature verification.");
|
|
if (188 !== i.charCodeAt(l - 1))
|
|
throw new Error("Encoded message does not end in 0xBC.");
|
|
var p = l - n - 1
|
|
, f = i.substr(0, p)
|
|
, h = i.substr(p, n)
|
|
, d = 65280 >> 8 * l - u & 255;
|
|
if (0 != (f.charCodeAt(0) & d))
|
|
throw new Error("Bits beyond keysize not zero as expected.");
|
|
var y = r.generate(h, p)
|
|
, g = "";
|
|
for (c = 0; c < p; c++)
|
|
g += String.fromCharCode(f.charCodeAt(c) ^ y.charCodeAt(c));
|
|
g = String.fromCharCode(g.charCodeAt(0) & ~d) + g.substr(1);
|
|
var v = l - n - s - 2;
|
|
for (c = 0; c < v; c++)
|
|
if (0 !== g.charCodeAt(c))
|
|
throw new Error("Leftmost octets not zero as expected");
|
|
if (1 !== g.charCodeAt(v))
|
|
throw new Error("Inconsistent PSS signature, 0x01 marker not found");
|
|
var m = g.substr(-s)
|
|
, C = new a.util.ByteBuffer;
|
|
return C.fillWithByte(0, 8),
|
|
C.putBytes(e),
|
|
C.putBytes(m),
|
|
t.start(),
|
|
t.update(C.getBytes()),
|
|
h === t.digest().getBytes()
|
|
}
|
|
,
|
|
c
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e) {
|
|
if ("string" == typeof e && (e = s.util.createBuffer(e)),
|
|
s.util.isArray(e) && e.length > 4) {
|
|
var t = e;
|
|
e = s.util.createBuffer();
|
|
for (var r = 0; r < t.length; ++r)
|
|
e.putByte(t[r])
|
|
}
|
|
return s.util.isArray(e) || (e = [e.getInt32(), e.getInt32(), e.getInt32(), e.getInt32()]),
|
|
e
|
|
}
|
|
function n(e) {
|
|
e[e.length - 1] = e[e.length - 1] + 1 & 4294967295
|
|
}
|
|
function i(e) {
|
|
return [e / 4294967296 | 0, 4294967295 & e]
|
|
}
|
|
var s = r(0);
|
|
r(1),
|
|
s.cipher = s.cipher || {};
|
|
var o = e.exports = s.cipher.modes = s.cipher.modes || {};
|
|
o.ecb = function(e) {
|
|
e = e || {},
|
|
this.name = "ECB",
|
|
this.cipher = e.cipher,
|
|
this.blockSize = e.blockSize || 16,
|
|
this._ints = this.blockSize / 4,
|
|
this._inBlock = new Array(this._ints),
|
|
this._outBlock = new Array(this._ints)
|
|
}
|
|
,
|
|
o.ecb.prototype.start = function(e) {}
|
|
,
|
|
o.ecb.prototype.encrypt = function(e, t, r) {
|
|
if (e.length() < this.blockSize && !(r && e.length() > 0))
|
|
return !0;
|
|
for (var a = 0; a < this._ints; ++a)
|
|
this._inBlock[a] = e.getInt32();
|
|
this.cipher.encrypt(this._inBlock, this._outBlock);
|
|
for (var a = 0; a < this._ints; ++a)
|
|
t.putInt32(this._outBlock[a])
|
|
}
|
|
,
|
|
o.ecb.prototype.decrypt = function(e, t, r) {
|
|
if (e.length() < this.blockSize && !(r && e.length() > 0))
|
|
return !0;
|
|
for (var a = 0; a < this._ints; ++a)
|
|
this._inBlock[a] = e.getInt32();
|
|
this.cipher.decrypt(this._inBlock, this._outBlock);
|
|
for (var a = 0; a < this._ints; ++a)
|
|
t.putInt32(this._outBlock[a])
|
|
}
|
|
,
|
|
o.ecb.prototype.pad = function(e, t) {
|
|
var r = e.length() === this.blockSize ? this.blockSize : this.blockSize - e.length();
|
|
return e.fillWithByte(r, r),
|
|
!0
|
|
}
|
|
,
|
|
o.ecb.prototype.unpad = function(e, t) {
|
|
if (t.overflow > 0)
|
|
return !1;
|
|
var r = e.length()
|
|
, a = e.at(r - 1);
|
|
return !(a > this.blockSize << 2) && (e.truncate(a),
|
|
!0)
|
|
}
|
|
,
|
|
o.cbc = function(e) {
|
|
e = e || {},
|
|
this.name = "CBC",
|
|
this.cipher = e.cipher,
|
|
this.blockSize = e.blockSize || 16,
|
|
this._ints = this.blockSize / 4,
|
|
this._inBlock = new Array(this._ints),
|
|
this._outBlock = new Array(this._ints)
|
|
}
|
|
,
|
|
o.cbc.prototype.start = function(e) {
|
|
if (null === e.iv) {
|
|
if (!this._prev)
|
|
throw new Error("Invalid IV parameter.");
|
|
this._iv = this._prev.slice(0)
|
|
} else {
|
|
if (!("iv"in e))
|
|
throw new Error("Invalid IV parameter.");
|
|
this._iv = a(e.iv),
|
|
this._prev = this._iv.slice(0)
|
|
}
|
|
}
|
|
,
|
|
o.cbc.prototype.encrypt = function(e, t, r) {
|
|
if (e.length() < this.blockSize && !(r && e.length() > 0))
|
|
return !0;
|
|
for (var a = 0; a < this._ints; ++a)
|
|
this._inBlock[a] = this._prev[a] ^ e.getInt32();
|
|
this.cipher.encrypt(this._inBlock, this._outBlock);
|
|
for (var a = 0; a < this._ints; ++a)
|
|
t.putInt32(this._outBlock[a]);
|
|
this._prev = this._outBlock
|
|
}
|
|
,
|
|
o.cbc.prototype.decrypt = function(e, t, r) {
|
|
if (e.length() < this.blockSize && !(r && e.length() > 0))
|
|
return !0;
|
|
for (var a = 0; a < this._ints; ++a)
|
|
this._inBlock[a] = e.getInt32();
|
|
this.cipher.decrypt(this._inBlock, this._outBlock);
|
|
for (var a = 0; a < this._ints; ++a)
|
|
t.putInt32(this._prev[a] ^ this._outBlock[a]);
|
|
this._prev = this._inBlock.slice(0)
|
|
}
|
|
,
|
|
o.cbc.prototype.pad = function(e, t) {
|
|
var r = e.length() === this.blockSize ? this.blockSize : this.blockSize - e.length();
|
|
return e.fillWithByte(r, r),
|
|
!0
|
|
}
|
|
,
|
|
o.cbc.prototype.unpad = function(e, t) {
|
|
if (t.overflow > 0)
|
|
return !1;
|
|
var r = e.length()
|
|
, a = e.at(r - 1);
|
|
return !(a > this.blockSize << 2) && (e.truncate(a),
|
|
!0)
|
|
}
|
|
,
|
|
o.cfb = function(e) {
|
|
e = e || {},
|
|
this.name = "CFB",
|
|
this.cipher = e.cipher,
|
|
this.blockSize = e.blockSize || 16,
|
|
this._ints = this.blockSize / 4,
|
|
this._inBlock = null,
|
|
this._outBlock = new Array(this._ints),
|
|
this._partialBlock = new Array(this._ints),
|
|
this._partialOutput = s.util.createBuffer(),
|
|
this._partialBytes = 0
|
|
}
|
|
,
|
|
o.cfb.prototype.start = function(e) {
|
|
if (!("iv"in e))
|
|
throw new Error("Invalid IV parameter.");
|
|
this._iv = a(e.iv),
|
|
this._inBlock = this._iv.slice(0),
|
|
this._partialBytes = 0
|
|
}
|
|
,
|
|
o.cfb.prototype.encrypt = function(e, t, r) {
|
|
var a = e.length();
|
|
if (0 === a)
|
|
return !0;
|
|
if (this.cipher.encrypt(this._inBlock, this._outBlock),
|
|
0 === this._partialBytes && a >= this.blockSize)
|
|
for (var n = 0; n < this._ints; ++n)
|
|
this._inBlock[n] = e.getInt32() ^ this._outBlock[n],
|
|
t.putInt32(this._inBlock[n]);
|
|
else {
|
|
var i = (this.blockSize - a) % this.blockSize;
|
|
i > 0 && (i = this.blockSize - i),
|
|
this._partialOutput.clear();
|
|
for (var n = 0; n < this._ints; ++n)
|
|
this._partialBlock[n] = e.getInt32() ^ this._outBlock[n],
|
|
this._partialOutput.putInt32(this._partialBlock[n]);
|
|
if (i > 0)
|
|
e.read -= this.blockSize;
|
|
else
|
|
for (var n = 0; n < this._ints; ++n)
|
|
this._inBlock[n] = this._partialBlock[n];
|
|
if (this._partialBytes > 0 && this._partialOutput.getBytes(this._partialBytes),
|
|
i > 0 && !r)
|
|
return t.putBytes(this._partialOutput.getBytes(i - this._partialBytes)),
|
|
this._partialBytes = i,
|
|
!0;
|
|
t.putBytes(this._partialOutput.getBytes(a - this._partialBytes)),
|
|
this._partialBytes = 0
|
|
}
|
|
}
|
|
,
|
|
o.cfb.prototype.decrypt = function(e, t, r) {
|
|
var a = e.length();
|
|
if (0 === a)
|
|
return !0;
|
|
if (this.cipher.encrypt(this._inBlock, this._outBlock),
|
|
0 === this._partialBytes && a >= this.blockSize)
|
|
for (var n = 0; n < this._ints; ++n)
|
|
this._inBlock[n] = e.getInt32(),
|
|
t.putInt32(this._inBlock[n] ^ this._outBlock[n]);
|
|
else {
|
|
var i = (this.blockSize - a) % this.blockSize;
|
|
i > 0 && (i = this.blockSize - i),
|
|
this._partialOutput.clear();
|
|
for (var n = 0; n < this._ints; ++n)
|
|
this._partialBlock[n] = e.getInt32(),
|
|
this._partialOutput.putInt32(this._partialBlock[n] ^ this._outBlock[n]);
|
|
if (i > 0)
|
|
e.read -= this.blockSize;
|
|
else
|
|
for (var n = 0; n < this._ints; ++n)
|
|
this._inBlock[n] = this._partialBlock[n];
|
|
if (this._partialBytes > 0 && this._partialOutput.getBytes(this._partialBytes),
|
|
i > 0 && !r)
|
|
return t.putBytes(this._partialOutput.getBytes(i - this._partialBytes)),
|
|
this._partialBytes = i,
|
|
!0;
|
|
t.putBytes(this._partialOutput.getBytes(a - this._partialBytes)),
|
|
this._partialBytes = 0
|
|
}
|
|
}
|
|
,
|
|
o.ofb = function(e) {
|
|
e = e || {},
|
|
this.name = "OFB",
|
|
this.cipher = e.cipher,
|
|
this.blockSize = e.blockSize || 16,
|
|
this._ints = this.blockSize / 4,
|
|
this._inBlock = null,
|
|
this._outBlock = new Array(this._ints),
|
|
this._partialOutput = s.util.createBuffer(),
|
|
this._partialBytes = 0
|
|
}
|
|
,
|
|
o.ofb.prototype.start = function(e) {
|
|
if (!("iv"in e))
|
|
throw new Error("Invalid IV parameter.");
|
|
this._iv = a(e.iv),
|
|
this._inBlock = this._iv.slice(0),
|
|
this._partialBytes = 0
|
|
}
|
|
,
|
|
o.ofb.prototype.encrypt = function(e, t, r) {
|
|
var a = e.length();
|
|
if (0 === e.length())
|
|
return !0;
|
|
if (this.cipher.encrypt(this._inBlock, this._outBlock),
|
|
0 === this._partialBytes && a >= this.blockSize)
|
|
for (var n = 0; n < this._ints; ++n)
|
|
t.putInt32(e.getInt32() ^ this._outBlock[n]),
|
|
this._inBlock[n] = this._outBlock[n];
|
|
else {
|
|
var i = (this.blockSize - a) % this.blockSize;
|
|
i > 0 && (i = this.blockSize - i),
|
|
this._partialOutput.clear();
|
|
for (var n = 0; n < this._ints; ++n)
|
|
this._partialOutput.putInt32(e.getInt32() ^ this._outBlock[n]);
|
|
if (i > 0)
|
|
e.read -= this.blockSize;
|
|
else
|
|
for (var n = 0; n < this._ints; ++n)
|
|
this._inBlock[n] = this._outBlock[n];
|
|
if (this._partialBytes > 0 && this._partialOutput.getBytes(this._partialBytes),
|
|
i > 0 && !r)
|
|
return t.putBytes(this._partialOutput.getBytes(i - this._partialBytes)),
|
|
this._partialBytes = i,
|
|
!0;
|
|
t.putBytes(this._partialOutput.getBytes(a - this._partialBytes)),
|
|
this._partialBytes = 0
|
|
}
|
|
}
|
|
,
|
|
o.ofb.prototype.decrypt = o.ofb.prototype.encrypt,
|
|
o.ctr = function(e) {
|
|
e = e || {},
|
|
this.name = "CTR",
|
|
this.cipher = e.cipher,
|
|
this.blockSize = e.blockSize || 16,
|
|
this._ints = this.blockSize / 4,
|
|
this._inBlock = null,
|
|
this._outBlock = new Array(this._ints),
|
|
this._partialOutput = s.util.createBuffer(),
|
|
this._partialBytes = 0
|
|
}
|
|
,
|
|
o.ctr.prototype.start = function(e) {
|
|
if (!("iv"in e))
|
|
throw new Error("Invalid IV parameter.");
|
|
this._iv = a(e.iv),
|
|
this._inBlock = this._iv.slice(0),
|
|
this._partialBytes = 0
|
|
}
|
|
,
|
|
o.ctr.prototype.encrypt = function(e, t, r) {
|
|
var a = e.length();
|
|
if (0 === a)
|
|
return !0;
|
|
if (this.cipher.encrypt(this._inBlock, this._outBlock),
|
|
0 === this._partialBytes && a >= this.blockSize)
|
|
for (var i = 0; i < this._ints; ++i)
|
|
t.putInt32(e.getInt32() ^ this._outBlock[i]);
|
|
else {
|
|
var s = (this.blockSize - a) % this.blockSize;
|
|
s > 0 && (s = this.blockSize - s),
|
|
this._partialOutput.clear();
|
|
for (var i = 0; i < this._ints; ++i)
|
|
this._partialOutput.putInt32(e.getInt32() ^ this._outBlock[i]);
|
|
if (s > 0 && (e.read -= this.blockSize),
|
|
this._partialBytes > 0 && this._partialOutput.getBytes(this._partialBytes),
|
|
s > 0 && !r)
|
|
return t.putBytes(this._partialOutput.getBytes(s - this._partialBytes)),
|
|
this._partialBytes = s,
|
|
!0;
|
|
t.putBytes(this._partialOutput.getBytes(a - this._partialBytes)),
|
|
this._partialBytes = 0
|
|
}
|
|
n(this._inBlock)
|
|
}
|
|
,
|
|
o.ctr.prototype.decrypt = o.ctr.prototype.encrypt,
|
|
o.gcm = function(e) {
|
|
e = e || {},
|
|
this.name = "GCM",
|
|
this.cipher = e.cipher,
|
|
this.blockSize = e.blockSize || 16,
|
|
this._ints = this.blockSize / 4,
|
|
this._inBlock = new Array(this._ints),
|
|
this._outBlock = new Array(this._ints),
|
|
this._partialOutput = s.util.createBuffer(),
|
|
this._partialBytes = 0,
|
|
this._R = 3774873600
|
|
}
|
|
,
|
|
o.gcm.prototype.start = function(e) {
|
|
if (!("iv"in e))
|
|
throw new Error("Invalid IV parameter.");
|
|
var t = s.util.createBuffer(e.iv);
|
|
this._cipherLength = 0;
|
|
var r;
|
|
if (r = "additionalData"in e ? s.util.createBuffer(e.additionalData) : s.util.createBuffer(),
|
|
this._tagLength = "tagLength"in e ? e.tagLength : 128,
|
|
this._tag = null,
|
|
e.decrypt && (this._tag = s.util.createBuffer(e.tag).getBytes(),
|
|
this._tag.length !== this._tagLength / 8))
|
|
throw new Error("Authentication tag does not match tag length.");
|
|
this._hashBlock = new Array(this._ints),
|
|
this.tag = null,
|
|
this._hashSubkey = new Array(this._ints),
|
|
this.cipher.encrypt([0, 0, 0, 0], this._hashSubkey),
|
|
this.componentBits = 4,
|
|
this._m = this.generateHashTable(this._hashSubkey, this.componentBits);
|
|
var a = t.length();
|
|
if (12 === a)
|
|
this._j0 = [t.getInt32(), t.getInt32(), t.getInt32(), 1];
|
|
else {
|
|
for (this._j0 = [0, 0, 0, 0]; t.length() > 0; )
|
|
this._j0 = this.ghash(this._hashSubkey, this._j0, [t.getInt32(), t.getInt32(), t.getInt32(), t.getInt32()]);
|
|
this._j0 = this.ghash(this._hashSubkey, this._j0, [0, 0].concat(i(8 * a)))
|
|
}
|
|
this._inBlock = this._j0.slice(0),
|
|
n(this._inBlock),
|
|
this._partialBytes = 0,
|
|
r = s.util.createBuffer(r),
|
|
this._aDataLength = i(8 * r.length());
|
|
var o = r.length() % this.blockSize;
|
|
for (o && r.fillWithByte(0, this.blockSize - o),
|
|
this._s = [0, 0, 0, 0]; r.length() > 0; )
|
|
this._s = this.ghash(this._hashSubkey, this._s, [r.getInt32(), r.getInt32(), r.getInt32(), r.getInt32()])
|
|
}
|
|
,
|
|
o.gcm.prototype.encrypt = function(e, t, r) {
|
|
var a = e.length();
|
|
if (0 === a)
|
|
return !0;
|
|
if (this.cipher.encrypt(this._inBlock, this._outBlock),
|
|
0 === this._partialBytes && a >= this.blockSize) {
|
|
for (var i = 0; i < this._ints; ++i)
|
|
t.putInt32(this._outBlock[i] ^= e.getInt32());
|
|
this._cipherLength += this.blockSize
|
|
} else {
|
|
var s = (this.blockSize - a) % this.blockSize;
|
|
s > 0 && (s = this.blockSize - s),
|
|
this._partialOutput.clear();
|
|
for (var i = 0; i < this._ints; ++i)
|
|
this._partialOutput.putInt32(e.getInt32() ^ this._outBlock[i]);
|
|
if (s <= 0 || r) {
|
|
if (r) {
|
|
var o = a % this.blockSize;
|
|
this._cipherLength += o,
|
|
this._partialOutput.truncate(this.blockSize - o)
|
|
} else
|
|
this._cipherLength += this.blockSize;
|
|
for (var i = 0; i < this._ints; ++i)
|
|
this._outBlock[i] = this._partialOutput.getInt32();
|
|
this._partialOutput.read -= this.blockSize
|
|
}
|
|
if (this._partialBytes > 0 && this._partialOutput.getBytes(this._partialBytes),
|
|
s > 0 && !r)
|
|
return e.read -= this.blockSize,
|
|
t.putBytes(this._partialOutput.getBytes(s - this._partialBytes)),
|
|
this._partialBytes = s,
|
|
!0;
|
|
t.putBytes(this._partialOutput.getBytes(a - this._partialBytes)),
|
|
this._partialBytes = 0
|
|
}
|
|
this._s = this.ghash(this._hashSubkey, this._s, this._outBlock),
|
|
n(this._inBlock)
|
|
}
|
|
,
|
|
o.gcm.prototype.decrypt = function(e, t, r) {
|
|
var a = e.length();
|
|
if (a < this.blockSize && !(r && a > 0))
|
|
return !0;
|
|
this.cipher.encrypt(this._inBlock, this._outBlock),
|
|
n(this._inBlock),
|
|
this._hashBlock[0] = e.getInt32(),
|
|
this._hashBlock[1] = e.getInt32(),
|
|
this._hashBlock[2] = e.getInt32(),
|
|
this._hashBlock[3] = e.getInt32(),
|
|
this._s = this.ghash(this._hashSubkey, this._s, this._hashBlock);
|
|
for (var i = 0; i < this._ints; ++i)
|
|
t.putInt32(this._outBlock[i] ^ this._hashBlock[i]);
|
|
a < this.blockSize ? this._cipherLength += a % this.blockSize : this._cipherLength += this.blockSize
|
|
}
|
|
,
|
|
o.gcm.prototype.afterFinish = function(e, t) {
|
|
var r = !0;
|
|
t.decrypt && t.overflow && e.truncate(this.blockSize - t.overflow),
|
|
this.tag = s.util.createBuffer();
|
|
var a = this._aDataLength.concat(i(8 * this._cipherLength));
|
|
this._s = this.ghash(this._hashSubkey, this._s, a);
|
|
var n = [];
|
|
this.cipher.encrypt(this._j0, n);
|
|
for (var o = 0; o < this._ints; ++o)
|
|
this.tag.putInt32(this._s[o] ^ n[o]);
|
|
return this.tag.truncate(this.tag.length() % (this._tagLength / 8)),
|
|
t.decrypt && this.tag.bytes() !== this._tag && (r = !1),
|
|
r
|
|
}
|
|
,
|
|
o.gcm.prototype.multiply = function(e, t) {
|
|
for (var r = [0, 0, 0, 0], a = t.slice(0), n = 0; n < 128; ++n) {
|
|
e[n / 32 | 0] & 1 << 31 - n % 32 && (r[0] ^= a[0],
|
|
r[1] ^= a[1],
|
|
r[2] ^= a[2],
|
|
r[3] ^= a[3]),
|
|
this.pow(a, a)
|
|
}
|
|
return r
|
|
}
|
|
,
|
|
o.gcm.prototype.pow = function(e, t) {
|
|
for (var r = 1 & e[3], a = 3; a > 0; --a)
|
|
t[a] = e[a] >>> 1 | (1 & e[a - 1]) << 31;
|
|
t[0] = e[0] >>> 1,
|
|
r && (t[0] ^= this._R)
|
|
}
|
|
,
|
|
o.gcm.prototype.tableMultiply = function(e) {
|
|
for (var t = [0, 0, 0, 0], r = 0; r < 32; ++r) {
|
|
var a = r / 8 | 0
|
|
, n = e[a] >>> 4 * (7 - r % 8) & 15
|
|
, i = this._m[r][n];
|
|
t[0] ^= i[0],
|
|
t[1] ^= i[1],
|
|
t[2] ^= i[2],
|
|
t[3] ^= i[3]
|
|
}
|
|
return t
|
|
}
|
|
,
|
|
o.gcm.prototype.ghash = function(e, t, r) {
|
|
return t[0] ^= r[0],
|
|
t[1] ^= r[1],
|
|
t[2] ^= r[2],
|
|
t[3] ^= r[3],
|
|
this.tableMultiply(t)
|
|
}
|
|
,
|
|
o.gcm.prototype.generateHashTable = function(e, t) {
|
|
for (var r = 8 / t, a = 4 * r, n = 16 * r, i = new Array(n), s = 0; s < n; ++s) {
|
|
var o = [0, 0, 0, 0]
|
|
, c = s / a | 0
|
|
, u = (a - 1 - s % a) * t;
|
|
o[c] = 1 << t - 1 << u,
|
|
i[s] = this.generateSubHashTable(this.multiply(o, e), t)
|
|
}
|
|
return i
|
|
}
|
|
,
|
|
o.gcm.prototype.generateSubHashTable = function(e, t) {
|
|
var r = 1 << t
|
|
, a = r >>> 1
|
|
, n = new Array(r);
|
|
n[a] = e.slice(0);
|
|
for (var i = a >>> 1; i > 0; )
|
|
this.pow(n[2 * i], n[i] = []),
|
|
i >>= 1;
|
|
for (i = 2; i < a; ) {
|
|
for (var s = 1; s < i; ++s) {
|
|
var o = n[i]
|
|
, c = n[s];
|
|
n[i + s] = [o[0] ^ c[0], o[1] ^ c[1], o[2] ^ c[2], o[3] ^ c[3]]
|
|
}
|
|
i *= 2
|
|
}
|
|
for (n[0] = [0, 0, 0, 0],
|
|
i = a + 1; i < r; ++i) {
|
|
var u = n[i ^ a];
|
|
n[i] = [e[0] ^ u[0], e[1] ^ u[1], e[2] ^ u[2], e[3] ^ u[3]]
|
|
}
|
|
return n
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(3),
|
|
r(8),
|
|
r(14),
|
|
r(7),
|
|
r(21),
|
|
r(2),
|
|
r(9),
|
|
r(1);
|
|
var n = function(e, t, r, n) {
|
|
var i = a.util.createBuffer()
|
|
, s = e.length >> 1
|
|
, o = s + (1 & e.length)
|
|
, c = e.substr(0, o)
|
|
, u = e.substr(s, o)
|
|
, l = a.util.createBuffer()
|
|
, p = a.hmac.create();
|
|
r = t + r;
|
|
var f = Math.ceil(n / 16)
|
|
, h = Math.ceil(n / 20);
|
|
p.start("MD5", c);
|
|
var d = a.util.createBuffer();
|
|
l.putBytes(r);
|
|
for (var y = 0; y < f; ++y)
|
|
p.start(null, null),
|
|
p.update(l.getBytes()),
|
|
l.putBuffer(p.digest()),
|
|
p.start(null, null),
|
|
p.update(l.bytes() + r),
|
|
d.putBuffer(p.digest());
|
|
p.start("SHA1", u);
|
|
var g = a.util.createBuffer();
|
|
l.clear(),
|
|
l.putBytes(r);
|
|
for (var y = 0; y < h; ++y)
|
|
p.start(null, null),
|
|
p.update(l.getBytes()),
|
|
l.putBuffer(p.digest()),
|
|
p.start(null, null),
|
|
p.update(l.bytes() + r),
|
|
g.putBuffer(p.digest());
|
|
return i.putBytes(a.util.xorBytes(d.getBytes(), g.getBytes(), n)),
|
|
i
|
|
}
|
|
, i = function(e, t, r) {
|
|
var n = a.hmac.create();
|
|
n.start("SHA1", e);
|
|
var i = a.util.createBuffer();
|
|
return i.putInt32(t[0]),
|
|
i.putInt32(t[1]),
|
|
i.putByte(r.type),
|
|
i.putByte(r.version.major),
|
|
i.putByte(r.version.minor),
|
|
i.putInt16(r.length),
|
|
i.putBytes(r.fragment.bytes()),
|
|
n.update(i.getBytes()),
|
|
n.digest().getBytes()
|
|
}
|
|
, s = function(e, t, r) {
|
|
var n = !1;
|
|
try {
|
|
var i = e.deflate(t.fragment.getBytes());
|
|
t.fragment = a.util.createBuffer(i),
|
|
t.length = i.length,
|
|
n = !0
|
|
} catch (e) {}
|
|
return n
|
|
}
|
|
, o = function(e, t, r) {
|
|
var n = !1;
|
|
try {
|
|
var i = e.inflate(t.fragment.getBytes());
|
|
t.fragment = a.util.createBuffer(i),
|
|
t.length = i.length,
|
|
n = !0
|
|
} catch (e) {}
|
|
return n
|
|
}
|
|
, c = function(e, t) {
|
|
var r = 0;
|
|
switch (t) {
|
|
case 1:
|
|
r = e.getByte();
|
|
break;
|
|
case 2:
|
|
r = e.getInt16();
|
|
break;
|
|
case 3:
|
|
r = e.getInt24();
|
|
break;
|
|
case 4:
|
|
r = e.getInt32()
|
|
}
|
|
return a.util.createBuffer(e.getBytes(r))
|
|
}
|
|
, u = function(e, t, r) {
|
|
e.putInt(r.length(), t << 3),
|
|
e.putBuffer(r)
|
|
}
|
|
, l = {};
|
|
l.Versions = {
|
|
TLS_1_0: {
|
|
major: 3,
|
|
minor: 1
|
|
},
|
|
TLS_1_1: {
|
|
major: 3,
|
|
minor: 2
|
|
},
|
|
TLS_1_2: {
|
|
major: 3,
|
|
minor: 3
|
|
}
|
|
},
|
|
l.SupportedVersions = [l.Versions.TLS_1_1, l.Versions.TLS_1_0],
|
|
l.Version = l.SupportedVersions[0],
|
|
l.MaxFragment = 15360,
|
|
l.ConnectionEnd = {
|
|
server: 0,
|
|
client: 1
|
|
},
|
|
l.PRFAlgorithm = {
|
|
tls_prf_sha256: 0
|
|
},
|
|
l.BulkCipherAlgorithm = {
|
|
none: null,
|
|
rc4: 0,
|
|
des3: 1,
|
|
aes: 2
|
|
},
|
|
l.CipherType = {
|
|
stream: 0,
|
|
block: 1,
|
|
aead: 2
|
|
},
|
|
l.MACAlgorithm = {
|
|
none: null,
|
|
hmac_md5: 0,
|
|
hmac_sha1: 1,
|
|
hmac_sha256: 2,
|
|
hmac_sha384: 3,
|
|
hmac_sha512: 4
|
|
},
|
|
l.CompressionMethod = {
|
|
none: 0,
|
|
deflate: 1
|
|
},
|
|
l.ContentType = {
|
|
change_cipher_spec: 20,
|
|
alert: 21,
|
|
handshake: 22,
|
|
application_data: 23,
|
|
heartbeat: 24
|
|
},
|
|
l.HandshakeType = {
|
|
hello_request: 0,
|
|
client_hello: 1,
|
|
server_hello: 2,
|
|
certificate: 11,
|
|
server_key_exchange: 12,
|
|
certificate_request: 13,
|
|
server_hello_done: 14,
|
|
certificate_verify: 15,
|
|
client_key_exchange: 16,
|
|
finished: 20
|
|
},
|
|
l.Alert = {},
|
|
l.Alert.Level = {
|
|
warning: 1,
|
|
fatal: 2
|
|
},
|
|
l.Alert.Description = {
|
|
close_notify: 0,
|
|
unexpected_message: 10,
|
|
bad_record_mac: 20,
|
|
decryption_failed: 21,
|
|
record_overflow: 22,
|
|
decompression_failure: 30,
|
|
handshake_failure: 40,
|
|
bad_certificate: 42,
|
|
unsupported_certificate: 43,
|
|
certificate_revoked: 44,
|
|
certificate_expired: 45,
|
|
certificate_unknown: 46,
|
|
illegal_parameter: 47,
|
|
unknown_ca: 48,
|
|
access_denied: 49,
|
|
decode_error: 50,
|
|
decrypt_error: 51,
|
|
export_restriction: 60,
|
|
protocol_version: 70,
|
|
insufficient_security: 71,
|
|
internal_error: 80,
|
|
user_canceled: 90,
|
|
no_renegotiation: 100
|
|
},
|
|
l.HeartbeatMessageType = {
|
|
heartbeat_request: 1,
|
|
heartbeat_response: 2
|
|
},
|
|
l.CipherSuites = {},
|
|
l.getCipherSuite = function(e) {
|
|
var t = null;
|
|
for (var r in l.CipherSuites) {
|
|
var a = l.CipherSuites[r];
|
|
if (a.id[0] === e.charCodeAt(0) && a.id[1] === e.charCodeAt(1)) {
|
|
t = a;
|
|
break
|
|
}
|
|
}
|
|
return t
|
|
}
|
|
,
|
|
l.handleUnexpected = function(e, t) {
|
|
!e.open && e.entity === l.ConnectionEnd.client || e.error(e, {
|
|
message: "Unexpected message. Received TLS record out of order.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.unexpected_message
|
|
}
|
|
})
|
|
}
|
|
,
|
|
l.handleHelloRequest = function(e, t, r) {
|
|
!e.handshaking && e.handshakes > 0 && (l.queue(e, l.createAlert(e, {
|
|
level: l.Alert.Level.warning,
|
|
description: l.Alert.Description.no_renegotiation
|
|
})),
|
|
l.flush(e)),
|
|
e.process()
|
|
}
|
|
,
|
|
l.parseHelloMessage = function(e, t, r) {
|
|
var n = null
|
|
, i = e.entity === l.ConnectionEnd.client;
|
|
if (r < 38)
|
|
e.error(e, {
|
|
message: i ? "Invalid ServerHello message. Message too short." : "Invalid ClientHello message. Message too short.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.illegal_parameter
|
|
}
|
|
});
|
|
else {
|
|
var s = t.fragment
|
|
, o = s.length();
|
|
if (n = {
|
|
version: {
|
|
major: s.getByte(),
|
|
minor: s.getByte()
|
|
},
|
|
random: a.util.createBuffer(s.getBytes(32)),
|
|
session_id: c(s, 1),
|
|
extensions: []
|
|
},
|
|
i ? (n.cipher_suite = s.getBytes(2),
|
|
n.compression_method = s.getByte()) : (n.cipher_suites = c(s, 2),
|
|
n.compression_methods = c(s, 1)),
|
|
(o = r - (o - s.length())) > 0) {
|
|
for (var u = c(s, 2); u.length() > 0; )
|
|
n.extensions.push({
|
|
type: [u.getByte(), u.getByte()],
|
|
data: c(u, 2)
|
|
});
|
|
if (!i)
|
|
for (var p = 0; p < n.extensions.length; ++p) {
|
|
var f = n.extensions[p];
|
|
if (0 === f.type[0] && 0 === f.type[1])
|
|
for (var h = c(f.data, 2); h.length() > 0; ) {
|
|
var d = h.getByte();
|
|
if (0 !== d)
|
|
break;
|
|
e.session.extensions.server_name.serverNameList.push(c(h, 2).getBytes())
|
|
}
|
|
}
|
|
}
|
|
if (e.session.version && (n.version.major !== e.session.version.major || n.version.minor !== e.session.version.minor))
|
|
return e.error(e, {
|
|
message: "TLS version change is disallowed during renegotiation.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.protocol_version
|
|
}
|
|
});
|
|
if (i)
|
|
e.session.cipherSuite = l.getCipherSuite(n.cipher_suite);
|
|
else
|
|
for (var y = a.util.createBuffer(n.cipher_suites.bytes()); y.length() > 0 && (e.session.cipherSuite = l.getCipherSuite(y.getBytes(2)),
|
|
null === e.session.cipherSuite); )
|
|
;
|
|
if (null === e.session.cipherSuite)
|
|
return e.error(e, {
|
|
message: "No cipher suites in common.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.handshake_failure
|
|
},
|
|
cipherSuite: a.util.bytesToHex(n.cipher_suite)
|
|
});
|
|
e.session.compressionMethod = i ? n.compression_method : l.CompressionMethod.none
|
|
}
|
|
return n
|
|
}
|
|
,
|
|
l.createSecurityParameters = function(e, t) {
|
|
var r = e.entity === l.ConnectionEnd.client
|
|
, a = t.random.bytes()
|
|
, n = r ? e.session.sp.client_random : a
|
|
, i = r ? a : l.createRandom().getBytes();
|
|
e.session.sp = {
|
|
entity: e.entity,
|
|
prf_algorithm: l.PRFAlgorithm.tls_prf_sha256,
|
|
bulk_cipher_algorithm: null,
|
|
cipher_type: null,
|
|
enc_key_length: null,
|
|
block_length: null,
|
|
fixed_iv_length: null,
|
|
record_iv_length: null,
|
|
mac_algorithm: null,
|
|
mac_length: null,
|
|
mac_key_length: null,
|
|
compression_algorithm: e.session.compressionMethod,
|
|
pre_master_secret: null,
|
|
master_secret: null,
|
|
client_random: n,
|
|
server_random: i
|
|
}
|
|
}
|
|
,
|
|
l.handleServerHello = function(e, t, r) {
|
|
var a = l.parseHelloMessage(e, t, r);
|
|
if (!e.fail) {
|
|
if (!(a.version.minor <= e.version.minor))
|
|
return e.error(e, {
|
|
message: "Incompatible TLS version.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.protocol_version
|
|
}
|
|
});
|
|
e.version.minor = a.version.minor,
|
|
e.session.version = e.version;
|
|
var n = a.session_id.bytes();
|
|
n.length > 0 && n === e.session.id ? (e.expect = y,
|
|
e.session.resuming = !0,
|
|
e.session.sp.server_random = a.random.bytes()) : (e.expect = p,
|
|
e.session.resuming = !1,
|
|
l.createSecurityParameters(e, a)),
|
|
e.session.id = n,
|
|
e.process()
|
|
}
|
|
}
|
|
,
|
|
l.handleClientHello = function(e, t, r) {
|
|
var n = l.parseHelloMessage(e, t, r);
|
|
if (!e.fail) {
|
|
var i = n.session_id.bytes()
|
|
, s = null;
|
|
if (e.sessionCache && (s = e.sessionCache.getSession(i),
|
|
null === s ? i = "" : (s.version.major !== n.version.major || s.version.minor > n.version.minor) && (s = null,
|
|
i = "")),
|
|
0 === i.length && (i = a.random.getBytes(32)),
|
|
e.session.id = i,
|
|
e.session.clientHelloVersion = n.version,
|
|
e.session.sp = {},
|
|
s)
|
|
e.version = e.session.version = s.version,
|
|
e.session.sp = s.sp;
|
|
else {
|
|
for (var o, c = 1; c < l.SupportedVersions.length && (o = l.SupportedVersions[c],
|
|
!(o.minor <= n.version.minor)); ++c)
|
|
;
|
|
e.version = {
|
|
major: o.major,
|
|
minor: o.minor
|
|
},
|
|
e.session.version = e.version
|
|
}
|
|
null !== s ? (e.expect = T,
|
|
e.session.resuming = !0,
|
|
e.session.sp.client_random = n.random.bytes()) : (e.expect = !1 !== e.verifyClient ? C : E,
|
|
e.session.resuming = !1,
|
|
l.createSecurityParameters(e, n)),
|
|
e.open = !0,
|
|
l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createServerHello(e)
|
|
})),
|
|
e.session.resuming ? (l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.change_cipher_spec,
|
|
data: l.createChangeCipherSpec()
|
|
})),
|
|
e.state.pending = l.createConnectionState(e),
|
|
e.state.current.write = e.state.pending.write,
|
|
l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createFinished(e)
|
|
}))) : (l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createCertificate(e)
|
|
})),
|
|
e.fail || (l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createServerKeyExchange(e)
|
|
})),
|
|
!1 !== e.verifyClient && l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createCertificateRequest(e)
|
|
})),
|
|
l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createServerHelloDone(e)
|
|
})))),
|
|
l.flush(e),
|
|
e.process()
|
|
}
|
|
}
|
|
,
|
|
l.handleCertificate = function(e, t, r) {
|
|
if (r < 3)
|
|
return e.error(e, {
|
|
message: "Invalid Certificate message. Message too short.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.illegal_parameter
|
|
}
|
|
});
|
|
var n, i, s = t.fragment, o = {
|
|
certificate_list: c(s, 3)
|
|
}, u = [];
|
|
try {
|
|
for (; o.certificate_list.length() > 0; )
|
|
n = c(o.certificate_list, 3),
|
|
i = a.asn1.fromDer(n),
|
|
n = a.pki.certificateFromAsn1(i, !0),
|
|
u.push(n)
|
|
} catch (t) {
|
|
return e.error(e, {
|
|
message: "Could not parse certificate list.",
|
|
cause: t,
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.bad_certificate
|
|
}
|
|
})
|
|
}
|
|
var p = e.entity === l.ConnectionEnd.client;
|
|
!p && !0 !== e.verifyClient || 0 !== u.length ? 0 === u.length ? e.expect = p ? f : E : (p ? e.session.serverCertificate = u[0] : e.session.clientCertificate = u[0],
|
|
l.verifyCertificateChain(e, u) && (e.expect = p ? f : E)) : e.error(e, {
|
|
message: p ? "No server certificate provided." : "No client certificate provided.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.illegal_parameter
|
|
}
|
|
}),
|
|
e.process()
|
|
}
|
|
,
|
|
l.handleServerKeyExchange = function(e, t, r) {
|
|
if (r > 0)
|
|
return e.error(e, {
|
|
message: "Invalid key parameters. Only RSA is supported.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.unsupported_certificate
|
|
}
|
|
});
|
|
e.expect = h,
|
|
e.process()
|
|
}
|
|
,
|
|
l.handleClientKeyExchange = function(e, t, r) {
|
|
if (r < 48)
|
|
return e.error(e, {
|
|
message: "Invalid key parameters. Only RSA is supported.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.unsupported_certificate
|
|
}
|
|
});
|
|
var n = t.fragment
|
|
, i = {
|
|
enc_pre_master_secret: c(n, 2).getBytes()
|
|
}
|
|
, s = null;
|
|
if (e.getPrivateKey)
|
|
try {
|
|
s = e.getPrivateKey(e, e.session.serverCertificate),
|
|
s = a.pki.privateKeyFromPem(s)
|
|
} catch (t) {
|
|
e.error(e, {
|
|
message: "Could not get private key.",
|
|
cause: t,
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.internal_error
|
|
}
|
|
})
|
|
}
|
|
if (null === s)
|
|
return e.error(e, {
|
|
message: "No private key set.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.internal_error
|
|
}
|
|
});
|
|
try {
|
|
var o = e.session.sp;
|
|
o.pre_master_secret = s.decrypt(i.enc_pre_master_secret);
|
|
var u = e.session.clientHelloVersion;
|
|
if (u.major !== o.pre_master_secret.charCodeAt(0) || u.minor !== o.pre_master_secret.charCodeAt(1))
|
|
throw new Error("TLS version rollback attack detected.")
|
|
} catch (e) {
|
|
o.pre_master_secret = a.random.getBytes(48)
|
|
}
|
|
e.expect = T,
|
|
null !== e.session.clientCertificate && (e.expect = S),
|
|
e.process()
|
|
}
|
|
,
|
|
l.handleCertificateRequest = function(e, t, r) {
|
|
if (r < 3)
|
|
return e.error(e, {
|
|
message: "Invalid CertificateRequest. Message too short.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.illegal_parameter
|
|
}
|
|
});
|
|
var a = t.fragment
|
|
, n = {
|
|
certificate_types: c(a, 1),
|
|
certificate_authorities: c(a, 2)
|
|
};
|
|
e.session.certificateRequest = n,
|
|
e.expect = d,
|
|
e.process()
|
|
}
|
|
,
|
|
l.handleCertificateVerify = function(e, t, r) {
|
|
if (r < 2)
|
|
return e.error(e, {
|
|
message: "Invalid CertificateVerify. Message too short.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.illegal_parameter
|
|
}
|
|
});
|
|
var n = t.fragment;
|
|
n.read -= 4;
|
|
var i = n.bytes();
|
|
n.read += 4;
|
|
var s = {
|
|
signature: c(n, 2).getBytes()
|
|
}
|
|
, o = a.util.createBuffer();
|
|
o.putBuffer(e.session.md5.digest()),
|
|
o.putBuffer(e.session.sha1.digest()),
|
|
o = o.getBytes();
|
|
try {
|
|
if (!e.session.clientCertificate.publicKey.verify(o, s.signature, "NONE"))
|
|
throw new Error("CertificateVerify signature does not match.");
|
|
e.session.md5.update(i),
|
|
e.session.sha1.update(i)
|
|
} catch (t) {
|
|
return e.error(e, {
|
|
message: "Bad signature in CertificateVerify.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.handshake_failure
|
|
}
|
|
})
|
|
}
|
|
e.expect = T,
|
|
e.process()
|
|
}
|
|
,
|
|
l.handleServerHelloDone = function(e, t, r) {
|
|
if (r > 0)
|
|
return e.error(e, {
|
|
message: "Invalid ServerHelloDone message. Invalid length.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.record_overflow
|
|
}
|
|
});
|
|
if (null === e.serverCertificate) {
|
|
var n = {
|
|
message: "No server certificate provided. Not enough security.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.insufficient_security
|
|
}
|
|
}
|
|
, i = e.verify(e, n.alert.description, 0, []);
|
|
if (!0 !== i)
|
|
return (i || 0 === i) && ("object" != typeof i || a.util.isArray(i) ? "number" == typeof i && (n.alert.description = i) : (i.message && (n.message = i.message),
|
|
i.alert && (n.alert.description = i.alert))),
|
|
e.error(e, n)
|
|
}
|
|
null !== e.session.certificateRequest && (t = l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createCertificate(e)
|
|
}),
|
|
l.queue(e, t)),
|
|
t = l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createClientKeyExchange(e)
|
|
}),
|
|
l.queue(e, t),
|
|
e.expect = m;
|
|
var s = function(e, t) {
|
|
null !== e.session.certificateRequest && null !== e.session.clientCertificate && l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createCertificateVerify(e, t)
|
|
})),
|
|
l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.change_cipher_spec,
|
|
data: l.createChangeCipherSpec()
|
|
})),
|
|
e.state.pending = l.createConnectionState(e),
|
|
e.state.current.write = e.state.pending.write,
|
|
l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createFinished(e)
|
|
})),
|
|
e.expect = y,
|
|
l.flush(e),
|
|
e.process()
|
|
};
|
|
if (null === e.session.certificateRequest || null === e.session.clientCertificate)
|
|
return s(e, null);
|
|
l.getClientSignature(e, s)
|
|
}
|
|
,
|
|
l.handleChangeCipherSpec = function(e, t) {
|
|
if (1 !== t.fragment.getByte())
|
|
return e.error(e, {
|
|
message: "Invalid ChangeCipherSpec message received.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.illegal_parameter
|
|
}
|
|
});
|
|
var r = e.entity === l.ConnectionEnd.client;
|
|
(e.session.resuming && r || !e.session.resuming && !r) && (e.state.pending = l.createConnectionState(e)),
|
|
e.state.current.read = e.state.pending.read,
|
|
(!e.session.resuming && r || e.session.resuming && !r) && (e.state.pending = null),
|
|
e.expect = r ? g : I,
|
|
e.process()
|
|
}
|
|
,
|
|
l.handleFinished = function(e, t, r) {
|
|
var i = t.fragment;
|
|
i.read -= 4;
|
|
var s = i.bytes();
|
|
i.read += 4;
|
|
var o = t.fragment.getBytes();
|
|
i = a.util.createBuffer(),
|
|
i.putBuffer(e.session.md5.digest()),
|
|
i.putBuffer(e.session.sha1.digest());
|
|
var c = e.entity === l.ConnectionEnd.client
|
|
, u = c ? "server finished" : "client finished"
|
|
, p = e.session.sp;
|
|
if (i = n(p.master_secret, u, i.getBytes(), 12),
|
|
i.getBytes() !== o)
|
|
return e.error(e, {
|
|
message: "Invalid verify_data in Finished message.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.decrypt_error
|
|
}
|
|
});
|
|
e.session.md5.update(s),
|
|
e.session.sha1.update(s),
|
|
(e.session.resuming && c || !e.session.resuming && !c) && (l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.change_cipher_spec,
|
|
data: l.createChangeCipherSpec()
|
|
})),
|
|
e.state.current.write = e.state.pending.write,
|
|
e.state.pending = null,
|
|
l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createFinished(e)
|
|
}))),
|
|
e.expect = c ? v : b,
|
|
e.handshaking = !1,
|
|
++e.handshakes,
|
|
e.peerCertificate = c ? e.session.serverCertificate : e.session.clientCertificate,
|
|
l.flush(e),
|
|
e.isConnected = !0,
|
|
e.connected(e),
|
|
e.process()
|
|
}
|
|
,
|
|
l.handleAlert = function(e, t) {
|
|
var r, a = t.fragment, n = {
|
|
level: a.getByte(),
|
|
description: a.getByte()
|
|
};
|
|
switch (n.description) {
|
|
case l.Alert.Description.close_notify:
|
|
r = "Connection closed.";
|
|
break;
|
|
case l.Alert.Description.unexpected_message:
|
|
r = "Unexpected message.";
|
|
break;
|
|
case l.Alert.Description.bad_record_mac:
|
|
r = "Bad record MAC.";
|
|
break;
|
|
case l.Alert.Description.decryption_failed:
|
|
r = "Decryption failed.";
|
|
break;
|
|
case l.Alert.Description.record_overflow:
|
|
r = "Record overflow.";
|
|
break;
|
|
case l.Alert.Description.decompression_failure:
|
|
r = "Decompression failed.";
|
|
break;
|
|
case l.Alert.Description.handshake_failure:
|
|
r = "Handshake failure.";
|
|
break;
|
|
case l.Alert.Description.bad_certificate:
|
|
r = "Bad certificate.";
|
|
break;
|
|
case l.Alert.Description.unsupported_certificate:
|
|
r = "Unsupported certificate.";
|
|
break;
|
|
case l.Alert.Description.certificate_revoked:
|
|
r = "Certificate revoked.";
|
|
break;
|
|
case l.Alert.Description.certificate_expired:
|
|
r = "Certificate expired.";
|
|
break;
|
|
case l.Alert.Description.certificate_unknown:
|
|
r = "Certificate unknown.";
|
|
break;
|
|
case l.Alert.Description.illegal_parameter:
|
|
r = "Illegal parameter.";
|
|
break;
|
|
case l.Alert.Description.unknown_ca:
|
|
r = "Unknown certificate authority.";
|
|
break;
|
|
case l.Alert.Description.access_denied:
|
|
r = "Access denied.";
|
|
break;
|
|
case l.Alert.Description.decode_error:
|
|
r = "Decode error.";
|
|
break;
|
|
case l.Alert.Description.decrypt_error:
|
|
r = "Decrypt error.";
|
|
break;
|
|
case l.Alert.Description.export_restriction:
|
|
r = "Export restriction.";
|
|
break;
|
|
case l.Alert.Description.protocol_version:
|
|
r = "Unsupported protocol version.";
|
|
break;
|
|
case l.Alert.Description.insufficient_security:
|
|
r = "Insufficient security.";
|
|
break;
|
|
case l.Alert.Description.internal_error:
|
|
r = "Internal error.";
|
|
break;
|
|
case l.Alert.Description.user_canceled:
|
|
r = "User canceled.";
|
|
break;
|
|
case l.Alert.Description.no_renegotiation:
|
|
r = "Renegotiation not supported.";
|
|
break;
|
|
default:
|
|
r = "Unknown error."
|
|
}
|
|
if (n.description === l.Alert.Description.close_notify)
|
|
return e.close();
|
|
e.error(e, {
|
|
message: r,
|
|
send: !1,
|
|
origin: e.entity === l.ConnectionEnd.client ? "server" : "client",
|
|
alert: n
|
|
}),
|
|
e.process()
|
|
}
|
|
,
|
|
l.handleHandshake = function(e, t) {
|
|
var r = t.fragment
|
|
, n = r.getByte()
|
|
, i = r.getInt24();
|
|
if (i > r.length())
|
|
return e.fragmented = t,
|
|
t.fragment = a.util.createBuffer(),
|
|
r.read -= 4,
|
|
e.process();
|
|
e.fragmented = null,
|
|
r.read -= 4;
|
|
var s = r.bytes(i + 4);
|
|
r.read += 4,
|
|
n in x[e.entity][e.expect] ? (e.entity !== l.ConnectionEnd.server || e.open || e.fail || (e.handshaking = !0,
|
|
e.session = {
|
|
version: null,
|
|
extensions: {
|
|
server_name: {
|
|
serverNameList: []
|
|
}
|
|
},
|
|
cipherSuite: null,
|
|
compressionMethod: null,
|
|
serverCertificate: null,
|
|
clientCertificate: null,
|
|
md5: a.md.md5.create(),
|
|
sha1: a.md.sha1.create()
|
|
}),
|
|
n !== l.HandshakeType.hello_request && n !== l.HandshakeType.certificate_verify && n !== l.HandshakeType.finished && (e.session.md5.update(s),
|
|
e.session.sha1.update(s)),
|
|
x[e.entity][e.expect][n](e, t, i)) : l.handleUnexpected(e, t)
|
|
}
|
|
,
|
|
l.handleApplicationData = function(e, t) {
|
|
e.data.putBuffer(t.fragment),
|
|
e.dataReady(e),
|
|
e.process()
|
|
}
|
|
,
|
|
l.handleHeartbeat = function(e, t) {
|
|
var r = t.fragment
|
|
, n = r.getByte()
|
|
, i = r.getInt16()
|
|
, s = r.getBytes(i);
|
|
if (n === l.HeartbeatMessageType.heartbeat_request) {
|
|
if (e.handshaking || i > s.length)
|
|
return e.process();
|
|
l.queue(e, l.createRecord(e, {
|
|
type: l.ContentType.heartbeat,
|
|
data: l.createHeartbeat(l.HeartbeatMessageType.heartbeat_response, s)
|
|
})),
|
|
l.flush(e)
|
|
} else if (n === l.HeartbeatMessageType.heartbeat_response) {
|
|
if (s !== e.expectedHeartbeatPayload)
|
|
return e.process();
|
|
e.heartbeatReceived && e.heartbeatReceived(e, a.util.createBuffer(s))
|
|
}
|
|
e.process()
|
|
}
|
|
;
|
|
var p = 1
|
|
, f = 2
|
|
, h = 3
|
|
, d = 4
|
|
, y = 5
|
|
, g = 6
|
|
, v = 7
|
|
, m = 8
|
|
, C = 1
|
|
, E = 2
|
|
, S = 3
|
|
, T = 4
|
|
, I = 5
|
|
, b = 6
|
|
, A = l.handleUnexpected
|
|
, B = l.handleChangeCipherSpec
|
|
, N = l.handleAlert
|
|
, k = l.handleHandshake
|
|
, w = l.handleApplicationData
|
|
, R = l.handleHeartbeat
|
|
, _ = [];
|
|
_[l.ConnectionEnd.client] = [[A, N, k, A, R], [A, N, k, A, R], [A, N, k, A, R], [A, N, k, A, R], [A, N, k, A, R], [B, N, A, A, R], [A, N, k, A, R], [A, N, k, w, R], [A, N, k, A, R]],
|
|
_[l.ConnectionEnd.server] = [[A, N, k, A, R], [A, N, k, A, R], [A, N, k, A, R], [A, N, k, A, R], [B, N, A, A, R], [A, N, k, A, R], [A, N, k, w, R], [A, N, k, A, R]];
|
|
var L = l.handleHelloRequest
|
|
, U = l.handleServerHello
|
|
, D = l.handleCertificate
|
|
, P = l.handleServerKeyExchange
|
|
, V = l.handleCertificateRequest
|
|
, O = l.handleServerHelloDone
|
|
, K = l.handleFinished
|
|
, x = [];
|
|
x[l.ConnectionEnd.client] = [[A, A, U, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A], [L, A, A, A, A, A, A, A, A, A, A, D, P, V, O, A, A, A, A, A, A], [L, A, A, A, A, A, A, A, A, A, A, A, P, V, O, A, A, A, A, A, A], [L, A, A, A, A, A, A, A, A, A, A, A, A, V, O, A, A, A, A, A, A], [L, A, A, A, A, A, A, A, A, A, A, A, A, A, O, A, A, A, A, A, A], [L, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A], [L, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, K], [L, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A], [L, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A]];
|
|
var M = l.handleClientHello
|
|
, F = l.handleClientKeyExchange
|
|
, q = l.handleCertificateVerify;
|
|
x[l.ConnectionEnd.server] = [[A, M, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A], [A, A, A, A, A, A, A, A, A, A, A, D, A, A, A, A, A, A, A, A, A], [A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, F, A, A, A, A], [A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, q, A, A, A, A, A], [A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A], [A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, K], [A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A], [A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A]],
|
|
l.generateKeys = function(e, t) {
|
|
var r = n
|
|
, a = t.client_random + t.server_random;
|
|
e.session.resuming || (t.master_secret = r(t.pre_master_secret, "master secret", a, 48).bytes(),
|
|
t.pre_master_secret = null),
|
|
a = t.server_random + t.client_random;
|
|
var i = 2 * t.mac_key_length + 2 * t.enc_key_length
|
|
, s = e.version.major === l.Versions.TLS_1_0.major && e.version.minor === l.Versions.TLS_1_0.minor;
|
|
s && (i += 2 * t.fixed_iv_length);
|
|
var o = r(t.master_secret, "key expansion", a, i)
|
|
, c = {
|
|
client_write_MAC_key: o.getBytes(t.mac_key_length),
|
|
server_write_MAC_key: o.getBytes(t.mac_key_length),
|
|
client_write_key: o.getBytes(t.enc_key_length),
|
|
server_write_key: o.getBytes(t.enc_key_length)
|
|
};
|
|
return s && (c.client_write_IV = o.getBytes(t.fixed_iv_length),
|
|
c.server_write_IV = o.getBytes(t.fixed_iv_length)),
|
|
c
|
|
}
|
|
,
|
|
l.createConnectionState = function(e) {
|
|
var t = e.entity === l.ConnectionEnd.client
|
|
, r = function() {
|
|
var e = {
|
|
sequenceNumber: [0, 0],
|
|
macKey: null,
|
|
macLength: 0,
|
|
macFunction: null,
|
|
cipherState: null,
|
|
cipherFunction: function(e) {
|
|
return !0
|
|
},
|
|
compressionState: null,
|
|
compressFunction: function(e) {
|
|
return !0
|
|
},
|
|
updateSequenceNumber: function() {
|
|
4294967295 === e.sequenceNumber[1] ? (e.sequenceNumber[1] = 0,
|
|
++e.sequenceNumber[0]) : ++e.sequenceNumber[1]
|
|
}
|
|
};
|
|
return e
|
|
}
|
|
, a = {
|
|
read: r(),
|
|
write: r()
|
|
};
|
|
if (a.read.update = function(e, t) {
|
|
return a.read.cipherFunction(t, a.read) ? a.read.compressFunction(e, t, a.read) || e.error(e, {
|
|
message: "Could not decompress record.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.decompression_failure
|
|
}
|
|
}) : e.error(e, {
|
|
message: "Could not decrypt record or bad MAC.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.bad_record_mac
|
|
}
|
|
}),
|
|
!e.fail
|
|
}
|
|
,
|
|
a.write.update = function(e, t) {
|
|
return a.write.compressFunction(e, t, a.write) ? a.write.cipherFunction(t, a.write) || e.error(e, {
|
|
message: "Could not encrypt record.",
|
|
send: !1,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.internal_error
|
|
}
|
|
}) : e.error(e, {
|
|
message: "Could not compress record.",
|
|
send: !1,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.internal_error
|
|
}
|
|
}),
|
|
!e.fail
|
|
}
|
|
,
|
|
e.session) {
|
|
var n = e.session.sp;
|
|
switch (e.session.cipherSuite.initSecurityParameters(n),
|
|
n.keys = l.generateKeys(e, n),
|
|
a.read.macKey = t ? n.keys.server_write_MAC_key : n.keys.client_write_MAC_key,
|
|
a.write.macKey = t ? n.keys.client_write_MAC_key : n.keys.server_write_MAC_key,
|
|
e.session.cipherSuite.initConnectionState(a, e, n),
|
|
n.compression_algorithm) {
|
|
case l.CompressionMethod.none:
|
|
break;
|
|
case l.CompressionMethod.deflate:
|
|
a.read.compressFunction = o,
|
|
a.write.compressFunction = s;
|
|
break;
|
|
default:
|
|
throw new Error("Unsupported compression algorithm.")
|
|
}
|
|
}
|
|
return a
|
|
}
|
|
,
|
|
l.createRandom = function() {
|
|
var e = new Date
|
|
, t = +e + 6e4 * e.getTimezoneOffset()
|
|
, r = a.util.createBuffer();
|
|
return r.putInt32(t),
|
|
r.putBytes(a.random.getBytes(28)),
|
|
r
|
|
}
|
|
,
|
|
l.createRecord = function(e, t) {
|
|
return t.data ? {
|
|
type: t.type,
|
|
version: {
|
|
major: e.version.major,
|
|
minor: e.version.minor
|
|
},
|
|
length: t.data.length(),
|
|
fragment: t.data
|
|
} : null
|
|
}
|
|
,
|
|
l.createAlert = function(e, t) {
|
|
var r = a.util.createBuffer();
|
|
return r.putByte(t.level),
|
|
r.putByte(t.description),
|
|
l.createRecord(e, {
|
|
type: l.ContentType.alert,
|
|
data: r
|
|
})
|
|
}
|
|
,
|
|
l.createClientHello = function(e) {
|
|
e.session.clientHelloVersion = {
|
|
major: e.version.major,
|
|
minor: e.version.minor
|
|
};
|
|
for (var t = a.util.createBuffer(), r = 0; r < e.cipherSuites.length; ++r) {
|
|
var n = e.cipherSuites[r];
|
|
t.putByte(n.id[0]),
|
|
t.putByte(n.id[1])
|
|
}
|
|
var i = t.length()
|
|
, s = a.util.createBuffer();
|
|
s.putByte(l.CompressionMethod.none);
|
|
var o = s.length()
|
|
, c = a.util.createBuffer();
|
|
if (e.virtualHost) {
|
|
var p = a.util.createBuffer();
|
|
p.putByte(0),
|
|
p.putByte(0);
|
|
var f = a.util.createBuffer();
|
|
f.putByte(0),
|
|
u(f, 2, a.util.createBuffer(e.virtualHost));
|
|
var h = a.util.createBuffer();
|
|
u(h, 2, f),
|
|
u(p, 2, h),
|
|
c.putBuffer(p)
|
|
}
|
|
var d = c.length();
|
|
d > 0 && (d += 2);
|
|
var y = e.session.id
|
|
, g = y.length + 1 + 2 + 4 + 28 + 2 + i + 1 + o + d
|
|
, v = a.util.createBuffer();
|
|
return v.putByte(l.HandshakeType.client_hello),
|
|
v.putInt24(g),
|
|
v.putByte(e.version.major),
|
|
v.putByte(e.version.minor),
|
|
v.putBytes(e.session.sp.client_random),
|
|
u(v, 1, a.util.createBuffer(y)),
|
|
u(v, 2, t),
|
|
u(v, 1, s),
|
|
d > 0 && u(v, 2, c),
|
|
v
|
|
}
|
|
,
|
|
l.createServerHello = function(e) {
|
|
var t = e.session.id
|
|
, r = t.length + 1 + 2 + 4 + 28 + 2 + 1
|
|
, n = a.util.createBuffer();
|
|
return n.putByte(l.HandshakeType.server_hello),
|
|
n.putInt24(r),
|
|
n.putByte(e.version.major),
|
|
n.putByte(e.version.minor),
|
|
n.putBytes(e.session.sp.server_random),
|
|
u(n, 1, a.util.createBuffer(t)),
|
|
n.putByte(e.session.cipherSuite.id[0]),
|
|
n.putByte(e.session.cipherSuite.id[1]),
|
|
n.putByte(e.session.compressionMethod),
|
|
n
|
|
}
|
|
,
|
|
l.createCertificate = function(e) {
|
|
var t = e.entity === l.ConnectionEnd.client
|
|
, r = null;
|
|
if (e.getCertificate) {
|
|
var n;
|
|
n = t ? e.session.certificateRequest : e.session.extensions.server_name.serverNameList,
|
|
r = e.getCertificate(e, n)
|
|
}
|
|
var i = a.util.createBuffer();
|
|
if (null !== r)
|
|
try {
|
|
a.util.isArray(r) || (r = [r]);
|
|
for (var s = null, o = 0; o < r.length; ++o) {
|
|
var c = a.pem.decode(r[o])[0];
|
|
if ("CERTIFICATE" !== c.type && "X509 CERTIFICATE" !== c.type && "TRUSTED CERTIFICATE" !== c.type) {
|
|
var p = new Error('Could not convert certificate from PEM; PEM header type is not "CERTIFICATE", "X509 CERTIFICATE", or "TRUSTED CERTIFICATE".');
|
|
throw p.headerType = c.type,
|
|
p
|
|
}
|
|
if (c.procType && "ENCRYPTED" === c.procType.type)
|
|
throw new Error("Could not convert certificate from PEM; PEM is encrypted.");
|
|
var f = a.util.createBuffer(c.body);
|
|
null === s && (s = a.asn1.fromDer(f.bytes(), !1));
|
|
var h = a.util.createBuffer();
|
|
u(h, 3, f),
|
|
i.putBuffer(h)
|
|
}
|
|
r = a.pki.certificateFromAsn1(s),
|
|
t ? e.session.clientCertificate = r : e.session.serverCertificate = r
|
|
} catch (t) {
|
|
return e.error(e, {
|
|
message: "Could not send certificate list.",
|
|
cause: t,
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.bad_certificate
|
|
}
|
|
})
|
|
}
|
|
var d = 3 + i.length()
|
|
, y = a.util.createBuffer();
|
|
return y.putByte(l.HandshakeType.certificate),
|
|
y.putInt24(d),
|
|
u(y, 3, i),
|
|
y
|
|
}
|
|
,
|
|
l.createClientKeyExchange = function(e) {
|
|
var t = a.util.createBuffer();
|
|
t.putByte(e.session.clientHelloVersion.major),
|
|
t.putByte(e.session.clientHelloVersion.minor),
|
|
t.putBytes(a.random.getBytes(46));
|
|
var r = e.session.sp;
|
|
r.pre_master_secret = t.getBytes(),
|
|
t = e.session.serverCertificate.publicKey.encrypt(r.pre_master_secret);
|
|
var n = t.length + 2
|
|
, i = a.util.createBuffer();
|
|
return i.putByte(l.HandshakeType.client_key_exchange),
|
|
i.putInt24(n),
|
|
i.putInt16(t.length),
|
|
i.putBytes(t),
|
|
i
|
|
}
|
|
,
|
|
l.createServerKeyExchange = function(e) {
|
|
var t = a.util.createBuffer();
|
|
return t
|
|
}
|
|
,
|
|
l.getClientSignature = function(e, t) {
|
|
var r = a.util.createBuffer();
|
|
r.putBuffer(e.session.md5.digest()),
|
|
r.putBuffer(e.session.sha1.digest()),
|
|
r = r.getBytes(),
|
|
e.getSignature = e.getSignature || function(e, t, r) {
|
|
var n = null;
|
|
if (e.getPrivateKey)
|
|
try {
|
|
n = e.getPrivateKey(e, e.session.clientCertificate),
|
|
n = a.pki.privateKeyFromPem(n)
|
|
} catch (t) {
|
|
e.error(e, {
|
|
message: "Could not get private key.",
|
|
cause: t,
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.internal_error
|
|
}
|
|
})
|
|
}
|
|
null === n ? e.error(e, {
|
|
message: "No private key set.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.internal_error
|
|
}
|
|
}) : t = n.sign(t, null),
|
|
r(e, t)
|
|
}
|
|
,
|
|
e.getSignature(e, r, t)
|
|
}
|
|
,
|
|
l.createCertificateVerify = function(e, t) {
|
|
var r = t.length + 2
|
|
, n = a.util.createBuffer();
|
|
return n.putByte(l.HandshakeType.certificate_verify),
|
|
n.putInt24(r),
|
|
n.putInt16(t.length),
|
|
n.putBytes(t),
|
|
n
|
|
}
|
|
,
|
|
l.createCertificateRequest = function(e) {
|
|
var t = a.util.createBuffer();
|
|
t.putByte(1);
|
|
var r = a.util.createBuffer();
|
|
for (var n in e.caStore.certs) {
|
|
var i = e.caStore.certs[n]
|
|
, s = a.pki.distinguishedNameToAsn1(i.subject)
|
|
, o = a.asn1.toDer(s);
|
|
r.putInt16(o.length()),
|
|
r.putBuffer(o)
|
|
}
|
|
var c = 1 + t.length() + 2 + r.length()
|
|
, p = a.util.createBuffer();
|
|
return p.putByte(l.HandshakeType.certificate_request),
|
|
p.putInt24(c),
|
|
u(p, 1, t),
|
|
u(p, 2, r),
|
|
p
|
|
}
|
|
,
|
|
l.createServerHelloDone = function(e) {
|
|
var t = a.util.createBuffer();
|
|
return t.putByte(l.HandshakeType.server_hello_done),
|
|
t.putInt24(0),
|
|
t
|
|
}
|
|
,
|
|
l.createChangeCipherSpec = function() {
|
|
var e = a.util.createBuffer();
|
|
return e.putByte(1),
|
|
e
|
|
}
|
|
,
|
|
l.createFinished = function(e) {
|
|
var t = a.util.createBuffer();
|
|
t.putBuffer(e.session.md5.digest()),
|
|
t.putBuffer(e.session.sha1.digest());
|
|
var r = e.entity === l.ConnectionEnd.client
|
|
, i = e.session.sp
|
|
, s = n
|
|
, o = r ? "client finished" : "server finished";
|
|
t = s(i.master_secret, o, t.getBytes(), 12);
|
|
var c = a.util.createBuffer();
|
|
return c.putByte(l.HandshakeType.finished),
|
|
c.putInt24(t.length()),
|
|
c.putBuffer(t),
|
|
c
|
|
}
|
|
,
|
|
l.createHeartbeat = function(e, t, r) {
|
|
void 0 === r && (r = t.length);
|
|
var n = a.util.createBuffer();
|
|
n.putByte(e),
|
|
n.putInt16(r),
|
|
n.putBytes(t);
|
|
var i = n.length()
|
|
, s = Math.max(16, i - r - 3);
|
|
return n.putBytes(a.random.getBytes(s)),
|
|
n
|
|
}
|
|
,
|
|
l.queue = function(e, t) {
|
|
if (t && (0 !== t.fragment.length() || t.type !== l.ContentType.handshake && t.type !== l.ContentType.alert && t.type !== l.ContentType.change_cipher_spec)) {
|
|
if (t.type === l.ContentType.handshake) {
|
|
var r = t.fragment.bytes();
|
|
e.session.md5.update(r),
|
|
e.session.sha1.update(r),
|
|
r = null
|
|
}
|
|
var n;
|
|
if (t.fragment.length() <= l.MaxFragment)
|
|
n = [t];
|
|
else {
|
|
n = [];
|
|
for (var i = t.fragment.bytes(); i.length > l.MaxFragment; )
|
|
n.push(l.createRecord(e, {
|
|
type: t.type,
|
|
data: a.util.createBuffer(i.slice(0, l.MaxFragment))
|
|
})),
|
|
i = i.slice(l.MaxFragment);
|
|
i.length > 0 && n.push(l.createRecord(e, {
|
|
type: t.type,
|
|
data: a.util.createBuffer(i)
|
|
}))
|
|
}
|
|
for (var s = 0; s < n.length && !e.fail; ++s) {
|
|
var o = n[s];
|
|
e.state.current.write.update(e, o) && e.records.push(o)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
l.flush = function(e) {
|
|
for (var t = 0; t < e.records.length; ++t) {
|
|
var r = e.records[t];
|
|
e.tlsData.putByte(r.type),
|
|
e.tlsData.putByte(r.version.major),
|
|
e.tlsData.putByte(r.version.minor),
|
|
e.tlsData.putInt16(r.fragment.length()),
|
|
e.tlsData.putBuffer(e.records[t].fragment)
|
|
}
|
|
return e.records = [],
|
|
e.tlsDataReady(e)
|
|
}
|
|
;
|
|
var j = function(e) {
|
|
switch (e) {
|
|
case !0:
|
|
return !0;
|
|
case a.pki.certificateError.bad_certificate:
|
|
return l.Alert.Description.bad_certificate;
|
|
case a.pki.certificateError.unsupported_certificate:
|
|
return l.Alert.Description.unsupported_certificate;
|
|
case a.pki.certificateError.certificate_revoked:
|
|
return l.Alert.Description.certificate_revoked;
|
|
case a.pki.certificateError.certificate_expired:
|
|
return l.Alert.Description.certificate_expired;
|
|
case a.pki.certificateError.certificate_unknown:
|
|
return l.Alert.Description.certificate_unknown;
|
|
case a.pki.certificateError.unknown_ca:
|
|
return l.Alert.Description.unknown_ca;
|
|
default:
|
|
return l.Alert.Description.bad_certificate
|
|
}
|
|
}
|
|
, G = function(e) {
|
|
switch (e) {
|
|
case !0:
|
|
return !0;
|
|
case l.Alert.Description.bad_certificate:
|
|
return a.pki.certificateError.bad_certificate;
|
|
case l.Alert.Description.unsupported_certificate:
|
|
return a.pki.certificateError.unsupported_certificate;
|
|
case l.Alert.Description.certificate_revoked:
|
|
return a.pki.certificateError.certificate_revoked;
|
|
case l.Alert.Description.certificate_expired:
|
|
return a.pki.certificateError.certificate_expired;
|
|
case l.Alert.Description.certificate_unknown:
|
|
return a.pki.certificateError.certificate_unknown;
|
|
case l.Alert.Description.unknown_ca:
|
|
return a.pki.certificateError.unknown_ca;
|
|
default:
|
|
return a.pki.certificateError.bad_certificate
|
|
}
|
|
};
|
|
l.verifyCertificateChain = function(e, t) {
|
|
try {
|
|
var r = {};
|
|
for (var n in e.verifyOptions)
|
|
r[n] = e.verifyOptions[n];
|
|
r.verify = function(t, r, n) {
|
|
var i = (j(t),
|
|
e.verify(e, t, r, n));
|
|
if (!0 !== i) {
|
|
if ("object" == typeof i && !a.util.isArray(i)) {
|
|
var s = new Error("The application rejected the certificate.");
|
|
throw s.send = !0,
|
|
s.alert = {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.bad_certificate
|
|
},
|
|
i.message && (s.message = i.message),
|
|
i.alert && (s.alert.description = i.alert),
|
|
s
|
|
}
|
|
i !== t && (i = G(i))
|
|
}
|
|
return i
|
|
}
|
|
,
|
|
a.pki.verifyCertificateChain(e.caStore, t, r)
|
|
} catch (t) {
|
|
var i = t;
|
|
("object" != typeof i || a.util.isArray(i)) && (i = {
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: j(t)
|
|
}
|
|
}),
|
|
"send"in i || (i.send = !0),
|
|
"alert"in i || (i.alert = {
|
|
level: l.Alert.Level.fatal,
|
|
description: j(i.error)
|
|
}),
|
|
e.error(e, i)
|
|
}
|
|
return !e.fail
|
|
}
|
|
,
|
|
l.createSessionCache = function(e, t) {
|
|
var r = null;
|
|
if (e && e.getSession && e.setSession && e.order)
|
|
r = e;
|
|
else {
|
|
r = {},
|
|
r.cache = e || {},
|
|
r.capacity = Math.max(t || 100, 1),
|
|
r.order = [];
|
|
for (var n in e)
|
|
r.order.length <= t ? r.order.push(n) : delete e[n];
|
|
r.getSession = function(e) {
|
|
var t = null
|
|
, n = null;
|
|
if (e ? n = a.util.bytesToHex(e) : r.order.length > 0 && (n = r.order[0]),
|
|
null !== n && n in r.cache) {
|
|
t = r.cache[n],
|
|
delete r.cache[n];
|
|
for (var i in r.order)
|
|
if (r.order[i] === n) {
|
|
r.order.splice(i, 1);
|
|
break
|
|
}
|
|
}
|
|
return t
|
|
}
|
|
,
|
|
r.setSession = function(e, t) {
|
|
if (r.order.length === r.capacity) {
|
|
var n = r.order.shift();
|
|
delete r.cache[n]
|
|
}
|
|
var n = a.util.bytesToHex(e);
|
|
r.order.push(n),
|
|
r.cache[n] = t
|
|
}
|
|
}
|
|
return r
|
|
}
|
|
,
|
|
l.createConnection = function(e) {
|
|
var t = null;
|
|
t = e.caStore ? a.util.isArray(e.caStore) ? a.pki.createCaStore(e.caStore) : e.caStore : a.pki.createCaStore();
|
|
var r = e.cipherSuites || null;
|
|
if (null === r) {
|
|
r = [];
|
|
for (var n in l.CipherSuites)
|
|
r.push(l.CipherSuites[n])
|
|
}
|
|
var i = e.server ? l.ConnectionEnd.server : l.ConnectionEnd.client
|
|
, s = e.sessionCache ? l.createSessionCache(e.sessionCache) : null
|
|
, o = {
|
|
version: {
|
|
major: l.Version.major,
|
|
minor: l.Version.minor
|
|
},
|
|
entity: i,
|
|
sessionId: e.sessionId,
|
|
caStore: t,
|
|
sessionCache: s,
|
|
cipherSuites: r,
|
|
connected: e.connected,
|
|
virtualHost: e.virtualHost || null,
|
|
verifyClient: e.verifyClient || !1,
|
|
verify: e.verify || function(e, t, r, a) {
|
|
return t
|
|
}
|
|
,
|
|
verifyOptions: e.verifyOptions || {},
|
|
getCertificate: e.getCertificate || null,
|
|
getPrivateKey: e.getPrivateKey || null,
|
|
getSignature: e.getSignature || null,
|
|
input: a.util.createBuffer(),
|
|
tlsData: a.util.createBuffer(),
|
|
data: a.util.createBuffer(),
|
|
tlsDataReady: e.tlsDataReady,
|
|
dataReady: e.dataReady,
|
|
heartbeatReceived: e.heartbeatReceived,
|
|
closed: e.closed,
|
|
error: function(t, r) {
|
|
r.origin = r.origin || (t.entity === l.ConnectionEnd.client ? "client" : "server"),
|
|
r.send && (l.queue(t, l.createAlert(t, r.alert)),
|
|
l.flush(t));
|
|
var a = !1 !== r.fatal;
|
|
a && (t.fail = !0),
|
|
e.error(t, r),
|
|
a && t.close(!1)
|
|
},
|
|
deflate: e.deflate || null,
|
|
inflate: e.inflate || null
|
|
};
|
|
o.reset = function(e) {
|
|
o.version = {
|
|
major: l.Version.major,
|
|
minor: l.Version.minor
|
|
},
|
|
o.record = null,
|
|
o.session = null,
|
|
o.peerCertificate = null,
|
|
o.state = {
|
|
pending: null,
|
|
current: null
|
|
},
|
|
o.expect = (o.entity,
|
|
l.ConnectionEnd.client,
|
|
0),
|
|
o.fragmented = null,
|
|
o.records = [],
|
|
o.open = !1,
|
|
o.handshakes = 0,
|
|
o.handshaking = !1,
|
|
o.isConnected = !1,
|
|
o.fail = !(e || void 0 === e),
|
|
o.input.clear(),
|
|
o.tlsData.clear(),
|
|
o.data.clear(),
|
|
o.state.current = l.createConnectionState(o)
|
|
}
|
|
,
|
|
o.reset();
|
|
var c = function(e, t) {
|
|
var r = t.type - l.ContentType.change_cipher_spec
|
|
, a = _[e.entity][e.expect];
|
|
r in a ? a[r](e, t) : l.handleUnexpected(e, t)
|
|
}
|
|
, u = function(e) {
|
|
var t = 0
|
|
, r = e.input
|
|
, n = r.length();
|
|
if (n < 5)
|
|
t = 5 - n;
|
|
else {
|
|
e.record = {
|
|
type: r.getByte(),
|
|
version: {
|
|
major: r.getByte(),
|
|
minor: r.getByte()
|
|
},
|
|
length: r.getInt16(),
|
|
fragment: a.util.createBuffer(),
|
|
ready: !1
|
|
};
|
|
var i = e.record.version.major === e.version.major;
|
|
i && e.session && e.session.version && (i = e.record.version.minor === e.version.minor),
|
|
i || e.error(e, {
|
|
message: "Incompatible TLS version.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.protocol_version
|
|
}
|
|
})
|
|
}
|
|
return t
|
|
}
|
|
, p = function(e) {
|
|
var t = 0
|
|
, r = e.input
|
|
, a = r.length();
|
|
if (a < e.record.length)
|
|
t = e.record.length - a;
|
|
else {
|
|
e.record.fragment.putBytes(r.getBytes(e.record.length)),
|
|
r.compact();
|
|
e.state.current.read.update(e, e.record) && (null !== e.fragmented && (e.fragmented.type === e.record.type ? (e.fragmented.fragment.putBuffer(e.record.fragment),
|
|
e.record = e.fragmented) : e.error(e, {
|
|
message: "Invalid fragmented record.",
|
|
send: !0,
|
|
alert: {
|
|
level: l.Alert.Level.fatal,
|
|
description: l.Alert.Description.unexpected_message
|
|
}
|
|
})),
|
|
e.record.ready = !0)
|
|
}
|
|
return t
|
|
};
|
|
return o.handshake = function(e) {
|
|
if (o.entity !== l.ConnectionEnd.client)
|
|
o.error(o, {
|
|
message: "Cannot initiate handshake as a server.",
|
|
fatal: !1
|
|
});
|
|
else if (o.handshaking)
|
|
o.error(o, {
|
|
message: "Handshake already in progress.",
|
|
fatal: !1
|
|
});
|
|
else {
|
|
o.fail && !o.open && 0 === o.handshakes && (o.fail = !1),
|
|
o.handshaking = !0,
|
|
e = e || "";
|
|
var t = null;
|
|
e.length > 0 && (o.sessionCache && (t = o.sessionCache.getSession(e)),
|
|
null === t && (e = "")),
|
|
0 === e.length && o.sessionCache && null !== (t = o.sessionCache.getSession()) && (e = t.id),
|
|
o.session = {
|
|
id: e,
|
|
version: null,
|
|
cipherSuite: null,
|
|
compressionMethod: null,
|
|
serverCertificate: null,
|
|
certificateRequest: null,
|
|
clientCertificate: null,
|
|
sp: {},
|
|
md5: a.md.md5.create(),
|
|
sha1: a.md.sha1.create()
|
|
},
|
|
t && (o.version = t.version,
|
|
o.session.sp = t.sp),
|
|
o.session.sp.client_random = l.createRandom().getBytes(),
|
|
o.open = !0,
|
|
l.queue(o, l.createRecord(o, {
|
|
type: l.ContentType.handshake,
|
|
data: l.createClientHello(o)
|
|
})),
|
|
l.flush(o)
|
|
}
|
|
}
|
|
,
|
|
o.process = function(e) {
|
|
var t = 0;
|
|
return e && o.input.putBytes(e),
|
|
o.fail || (null !== o.record && o.record.ready && o.record.fragment.isEmpty() && (o.record = null),
|
|
null === o.record && (t = u(o)),
|
|
o.fail || null === o.record || o.record.ready || (t = p(o)),
|
|
!o.fail && null !== o.record && o.record.ready && c(o, o.record)),
|
|
t
|
|
}
|
|
,
|
|
o.prepare = function(e) {
|
|
return l.queue(o, l.createRecord(o, {
|
|
type: l.ContentType.application_data,
|
|
data: a.util.createBuffer(e)
|
|
})),
|
|
l.flush(o)
|
|
}
|
|
,
|
|
o.prepareHeartbeatRequest = function(e, t) {
|
|
return e instanceof a.util.ByteBuffer && (e = e.bytes()),
|
|
void 0 === t && (t = e.length),
|
|
o.expectedHeartbeatPayload = e,
|
|
l.queue(o, l.createRecord(o, {
|
|
type: l.ContentType.heartbeat,
|
|
data: l.createHeartbeat(l.HeartbeatMessageType.heartbeat_request, e, t)
|
|
})),
|
|
l.flush(o)
|
|
}
|
|
,
|
|
o.close = function(e) {
|
|
if (!o.fail && o.sessionCache && o.session) {
|
|
var t = {
|
|
id: o.session.id,
|
|
version: o.session.version,
|
|
sp: o.session.sp
|
|
};
|
|
t.sp.keys = null,
|
|
o.sessionCache.setSession(t.id, t)
|
|
}
|
|
o.open && (o.open = !1,
|
|
o.input.clear(),
|
|
(o.isConnected || o.handshaking) && (o.isConnected = o.handshaking = !1,
|
|
l.queue(o, l.createAlert(o, {
|
|
level: l.Alert.Level.warning,
|
|
description: l.Alert.Description.close_notify
|
|
})),
|
|
l.flush(o)),
|
|
o.closed(o)),
|
|
o.reset(e)
|
|
}
|
|
,
|
|
o
|
|
}
|
|
,
|
|
e.exports = a.tls = a.tls || {};
|
|
for (var H in l)
|
|
"function" != typeof l[H] && (a.tls[H] = l[H]);
|
|
a.tls.prf_tls1 = n,
|
|
a.tls.hmac_sha1 = i,
|
|
a.tls.createSessionCache = l.createSessionCache,
|
|
a.tls.createConnection = l.createConnection
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(3),
|
|
r(6),
|
|
r(22),
|
|
r(7),
|
|
r(15),
|
|
r(28),
|
|
r(18),
|
|
r(11),
|
|
r(1),
|
|
r(17);
|
|
var n = a.asn1
|
|
, i = e.exports = a.pki = a.pki || {};
|
|
i.pemToDer = function(e) {
|
|
var t = a.pem.decode(e)[0];
|
|
if (t.procType && "ENCRYPTED" === t.procType.type)
|
|
throw new Error("Could not convert PEM to DER; PEM is encrypted.");
|
|
return a.util.createBuffer(t.body)
|
|
}
|
|
,
|
|
i.privateKeyFromPem = function(e) {
|
|
var t = a.pem.decode(e)[0];
|
|
if ("PRIVATE KEY" !== t.type && "RSA PRIVATE KEY" !== t.type) {
|
|
var r = new Error('Could not convert private key from PEM; PEM header type is not "PRIVATE KEY" or "RSA PRIVATE KEY".');
|
|
throw r.headerType = t.type,
|
|
r
|
|
}
|
|
if (t.procType && "ENCRYPTED" === t.procType.type)
|
|
throw new Error("Could not convert private key from PEM; PEM is encrypted.");
|
|
var s = n.fromDer(t.body);
|
|
return i.privateKeyFromAsn1(s)
|
|
}
|
|
,
|
|
i.privateKeyToPem = function(e, t) {
|
|
var r = {
|
|
type: "RSA PRIVATE KEY",
|
|
body: n.toDer(i.privateKeyToAsn1(e)).getBytes()
|
|
};
|
|
return a.pem.encode(r, {
|
|
maxline: t
|
|
})
|
|
}
|
|
,
|
|
i.privateKeyInfoToPem = function(e, t) {
|
|
var r = {
|
|
type: "PRIVATE KEY",
|
|
body: n.toDer(e).getBytes()
|
|
};
|
|
return a.pem.encode(r, {
|
|
maxline: t
|
|
})
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t) {
|
|
return e.start().update(t).digest().getBytes()
|
|
}
|
|
function n(e) {
|
|
var t;
|
|
if (e) {
|
|
if (!(t = l.oids[u.derToOid(e)])) {
|
|
var r = new Error("Unsupported PRF OID.");
|
|
throw r.oid = e,
|
|
r.supported = ["hmacWithSHA1", "hmacWithSHA224", "hmacWithSHA256", "hmacWithSHA384", "hmacWithSHA512"],
|
|
r
|
|
}
|
|
} else
|
|
t = "hmacWithSHA1";
|
|
return i(t)
|
|
}
|
|
function i(e) {
|
|
var t = o.md;
|
|
switch (e) {
|
|
case "hmacWithSHA224":
|
|
t = o.md.sha512;
|
|
case "hmacWithSHA1":
|
|
case "hmacWithSHA256":
|
|
case "hmacWithSHA384":
|
|
case "hmacWithSHA512":
|
|
e = e.substr(8).toLowerCase();
|
|
break;
|
|
default:
|
|
var r = new Error("Unsupported PRF algorithm.");
|
|
throw r.algorithm = e,
|
|
r.supported = ["hmacWithSHA1", "hmacWithSHA224", "hmacWithSHA256", "hmacWithSHA384", "hmacWithSHA512"],
|
|
r
|
|
}
|
|
if (!(t && e in t))
|
|
throw new Error("Unknown hash algorithm: " + e);
|
|
return t[e].create()
|
|
}
|
|
function s(e, t, r, a) {
|
|
var n = u.create(u.Class.UNIVERSAL, u.Type.SEQUENCE, !0, [u.create(u.Class.UNIVERSAL, u.Type.OCTETSTRING, !1, e), u.create(u.Class.UNIVERSAL, u.Type.INTEGER, !1, t.getBytes())]);
|
|
return "hmacWithSHA1" !== a && n.value.push(u.create(u.Class.UNIVERSAL, u.Type.INTEGER, !1, o.util.hexToBytes(r.toString(16))), u.create(u.Class.UNIVERSAL, u.Type.SEQUENCE, !0, [u.create(u.Class.UNIVERSAL, u.Type.OID, !1, u.oidToDer(l.oids[a]).getBytes()), u.create(u.Class.UNIVERSAL, u.Type.NULL, !1, "")])),
|
|
n
|
|
}
|
|
var o = r(0);
|
|
if (r(5),
|
|
r(3),
|
|
r(10),
|
|
r(4),
|
|
r(6),
|
|
r(15),
|
|
r(7),
|
|
r(2),
|
|
r(25),
|
|
r(11),
|
|
r(1),
|
|
void 0 === c)
|
|
var c = o.jsbn.BigInteger;
|
|
var u = o.asn1
|
|
, l = o.pki = o.pki || {};
|
|
e.exports = l.pbe = o.pbe = o.pbe || {};
|
|
var p = l.oids
|
|
, f = {
|
|
name: "EncryptedPrivateKeyInfo",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "EncryptedPrivateKeyInfo.encryptionAlgorithm",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "AlgorithmIdentifier.algorithm",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.OID,
|
|
constructed: !1,
|
|
capture: "encryptionOid"
|
|
}, {
|
|
name: "AlgorithmIdentifier.parameters",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.SEQUENCE,
|
|
constructed: !0,
|
|
captureAsn1: "encryptionParams"
|
|
}]
|
|
}, {
|
|
name: "EncryptedPrivateKeyInfo.encryptedData",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.OCTETSTRING,
|
|
constructed: !1,
|
|
capture: "encryptedData"
|
|
}]
|
|
}
|
|
, h = {
|
|
name: "PBES2Algorithms",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "PBES2Algorithms.keyDerivationFunc",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "PBES2Algorithms.keyDerivationFunc.oid",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.OID,
|
|
constructed: !1,
|
|
capture: "kdfOid"
|
|
}, {
|
|
name: "PBES2Algorithms.params",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "PBES2Algorithms.params.salt",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.OCTETSTRING,
|
|
constructed: !1,
|
|
capture: "kdfSalt"
|
|
}, {
|
|
name: "PBES2Algorithms.params.iterationCount",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "kdfIterationCount"
|
|
}, {
|
|
name: "PBES2Algorithms.params.keyLength",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.INTEGER,
|
|
constructed: !1,
|
|
optional: !0,
|
|
capture: "keyLength"
|
|
}, {
|
|
name: "PBES2Algorithms.params.prf",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.SEQUENCE,
|
|
constructed: !0,
|
|
optional: !0,
|
|
value: [{
|
|
name: "PBES2Algorithms.params.prf.algorithm",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.OID,
|
|
constructed: !1,
|
|
capture: "prfOid"
|
|
}]
|
|
}]
|
|
}]
|
|
}, {
|
|
name: "PBES2Algorithms.encryptionScheme",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "PBES2Algorithms.encryptionScheme.oid",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.OID,
|
|
constructed: !1,
|
|
capture: "encOid"
|
|
}, {
|
|
name: "PBES2Algorithms.encryptionScheme.iv",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.OCTETSTRING,
|
|
constructed: !1,
|
|
capture: "encIv"
|
|
}]
|
|
}]
|
|
}
|
|
, d = {
|
|
name: "pkcs-12PbeParams",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "pkcs-12PbeParams.salt",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.OCTETSTRING,
|
|
constructed: !1,
|
|
capture: "salt"
|
|
}, {
|
|
name: "pkcs-12PbeParams.iterations",
|
|
tagClass: u.Class.UNIVERSAL,
|
|
type: u.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "iterations"
|
|
}]
|
|
};
|
|
l.encryptPrivateKeyInfo = function(e, t, r) {
|
|
r = r || {},
|
|
r.saltSize = r.saltSize || 8,
|
|
r.count = r.count || 2048,
|
|
r.algorithm = r.algorithm || "aes128",
|
|
r.prfAlgorithm = r.prfAlgorithm || "sha1";
|
|
var a, n, c, f = o.random.getBytesSync(r.saltSize), h = r.count, d = u.integerToDer(h);
|
|
if (0 === r.algorithm.indexOf("aes") || "des" === r.algorithm) {
|
|
var y, g, v;
|
|
switch (r.algorithm) {
|
|
case "aes128":
|
|
a = 16,
|
|
y = 16,
|
|
g = p["aes128-CBC"],
|
|
v = o.aes.createEncryptionCipher;
|
|
break;
|
|
case "aes192":
|
|
a = 24,
|
|
y = 16,
|
|
g = p["aes192-CBC"],
|
|
v = o.aes.createEncryptionCipher;
|
|
break;
|
|
case "aes256":
|
|
a = 32,
|
|
y = 16,
|
|
g = p["aes256-CBC"],
|
|
v = o.aes.createEncryptionCipher;
|
|
break;
|
|
case "des":
|
|
a = 8,
|
|
y = 8,
|
|
g = p.desCBC,
|
|
v = o.des.createEncryptionCipher;
|
|
break;
|
|
default:
|
|
var m = new Error("Cannot encrypt private key. Unknown encryption algorithm.");
|
|
throw m.algorithm = r.algorithm,
|
|
m
|
|
}
|
|
var C = "hmacWith" + r.prfAlgorithm.toUpperCase()
|
|
, E = i(C)
|
|
, S = o.pkcs5.pbkdf2(t, f, h, a, E)
|
|
, T = o.random.getBytesSync(y)
|
|
, I = v(S);
|
|
I.start(T),
|
|
I.update(u.toDer(e)),
|
|
I.finish(),
|
|
c = I.output.getBytes();
|
|
var b = s(f, d, a, C);
|
|
n = u.create(u.Class.UNIVERSAL, u.Type.SEQUENCE, !0, [u.create(u.Class.UNIVERSAL, u.Type.OID, !1, u.oidToDer(p.pkcs5PBES2).getBytes()), u.create(u.Class.UNIVERSAL, u.Type.SEQUENCE, !0, [u.create(u.Class.UNIVERSAL, u.Type.SEQUENCE, !0, [u.create(u.Class.UNIVERSAL, u.Type.OID, !1, u.oidToDer(p.pkcs5PBKDF2).getBytes()), b]), u.create(u.Class.UNIVERSAL, u.Type.SEQUENCE, !0, [u.create(u.Class.UNIVERSAL, u.Type.OID, !1, u.oidToDer(g).getBytes()), u.create(u.Class.UNIVERSAL, u.Type.OCTETSTRING, !1, T)])])])
|
|
} else {
|
|
if ("3des" !== r.algorithm) {
|
|
var m = new Error("Cannot encrypt private key. Unknown encryption algorithm.");
|
|
throw m.algorithm = r.algorithm,
|
|
m
|
|
}
|
|
a = 24;
|
|
var A = new o.util.ByteBuffer(f)
|
|
, S = l.pbe.generatePkcs12Key(t, A, 1, h, a)
|
|
, T = l.pbe.generatePkcs12Key(t, A, 2, h, a)
|
|
, I = o.des.createEncryptionCipher(S);
|
|
I.start(T),
|
|
I.update(u.toDer(e)),
|
|
I.finish(),
|
|
c = I.output.getBytes(),
|
|
n = u.create(u.Class.UNIVERSAL, u.Type.SEQUENCE, !0, [u.create(u.Class.UNIVERSAL, u.Type.OID, !1, u.oidToDer(p["pbeWithSHAAnd3-KeyTripleDES-CBC"]).getBytes()), u.create(u.Class.UNIVERSAL, u.Type.SEQUENCE, !0, [u.create(u.Class.UNIVERSAL, u.Type.OCTETSTRING, !1, f), u.create(u.Class.UNIVERSAL, u.Type.INTEGER, !1, d.getBytes())])])
|
|
}
|
|
return u.create(u.Class.UNIVERSAL, u.Type.SEQUENCE, !0, [n, u.create(u.Class.UNIVERSAL, u.Type.OCTETSTRING, !1, c)])
|
|
}
|
|
,
|
|
l.decryptPrivateKeyInfo = function(e, t) {
|
|
var r = null
|
|
, a = {}
|
|
, n = [];
|
|
if (!u.validate(e, f, a, n)) {
|
|
var i = new Error("Cannot read encrypted private key. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");
|
|
throw i.errors = n,
|
|
i
|
|
}
|
|
var s = u.derToOid(a.encryptionOid)
|
|
, c = l.pbe.getCipher(s, a.encryptionParams, t)
|
|
, p = o.util.createBuffer(a.encryptedData);
|
|
return c.update(p),
|
|
c.finish() && (r = u.fromDer(c.output)),
|
|
r
|
|
}
|
|
,
|
|
l.encryptedPrivateKeyToPem = function(e, t) {
|
|
var r = {
|
|
type: "ENCRYPTED PRIVATE KEY",
|
|
body: u.toDer(e).getBytes()
|
|
};
|
|
return o.pem.encode(r, {
|
|
maxline: t
|
|
})
|
|
}
|
|
,
|
|
l.encryptedPrivateKeyFromPem = function(e) {
|
|
var t = o.pem.decode(e)[0];
|
|
if ("ENCRYPTED PRIVATE KEY" !== t.type) {
|
|
var r = new Error('Could not convert encrypted private key from PEM; PEM header type is "ENCRYPTED PRIVATE KEY".');
|
|
throw r.headerType = t.type,
|
|
r
|
|
}
|
|
if (t.procType && "ENCRYPTED" === t.procType.type)
|
|
throw new Error("Could not convert encrypted private key from PEM; PEM is encrypted.");
|
|
return u.fromDer(t.body)
|
|
}
|
|
,
|
|
l.encryptRsaPrivateKey = function(e, t, r) {
|
|
if (r = r || {},
|
|
!r.legacy) {
|
|
var a = l.wrapRsaPrivateKey(l.privateKeyToAsn1(e));
|
|
return a = l.encryptPrivateKeyInfo(a, t, r),
|
|
l.encryptedPrivateKeyToPem(a)
|
|
}
|
|
var n, i, s, c;
|
|
switch (r.algorithm) {
|
|
case "aes128":
|
|
n = "AES-128-CBC",
|
|
s = 16,
|
|
i = o.random.getBytesSync(16),
|
|
c = o.aes.createEncryptionCipher;
|
|
break;
|
|
case "aes192":
|
|
n = "AES-192-CBC",
|
|
s = 24,
|
|
i = o.random.getBytesSync(16),
|
|
c = o.aes.createEncryptionCipher;
|
|
break;
|
|
case "aes256":
|
|
n = "AES-256-CBC",
|
|
s = 32,
|
|
i = o.random.getBytesSync(16),
|
|
c = o.aes.createEncryptionCipher;
|
|
break;
|
|
case "3des":
|
|
n = "DES-EDE3-CBC",
|
|
s = 24,
|
|
i = o.random.getBytesSync(8),
|
|
c = o.des.createEncryptionCipher;
|
|
break;
|
|
case "des":
|
|
n = "DES-CBC",
|
|
s = 8,
|
|
i = o.random.getBytesSync(8),
|
|
c = o.des.createEncryptionCipher;
|
|
break;
|
|
default:
|
|
var p = new Error('Could not encrypt RSA private key; unsupported encryption algorithm "' + r.algorithm + '".');
|
|
throw p.algorithm = r.algorithm,
|
|
p
|
|
}
|
|
var f = o.pbe.opensslDeriveBytes(t, i.substr(0, 8), s)
|
|
, h = c(f);
|
|
h.start(i),
|
|
h.update(u.toDer(l.privateKeyToAsn1(e))),
|
|
h.finish();
|
|
var d = {
|
|
type: "RSA PRIVATE KEY",
|
|
procType: {
|
|
version: "4",
|
|
type: "ENCRYPTED"
|
|
},
|
|
dekInfo: {
|
|
algorithm: n,
|
|
parameters: o.util.bytesToHex(i).toUpperCase()
|
|
},
|
|
body: h.output.getBytes()
|
|
};
|
|
return o.pem.encode(d)
|
|
}
|
|
,
|
|
l.decryptRsaPrivateKey = function(e, t) {
|
|
var r = null
|
|
, a = o.pem.decode(e)[0];
|
|
if ("ENCRYPTED PRIVATE KEY" !== a.type && "PRIVATE KEY" !== a.type && "RSA PRIVATE KEY" !== a.type) {
|
|
var n = new Error('Could not convert private key from PEM; PEM header type is not "ENCRYPTED PRIVATE KEY", "PRIVATE KEY", or "RSA PRIVATE KEY".');
|
|
throw n.headerType = n,
|
|
n
|
|
}
|
|
if (a.procType && "ENCRYPTED" === a.procType.type) {
|
|
var i, s;
|
|
switch (a.dekInfo.algorithm) {
|
|
case "DES-CBC":
|
|
i = 8,
|
|
s = o.des.createDecryptionCipher;
|
|
break;
|
|
case "DES-EDE3-CBC":
|
|
i = 24,
|
|
s = o.des.createDecryptionCipher;
|
|
break;
|
|
case "AES-128-CBC":
|
|
i = 16,
|
|
s = o.aes.createDecryptionCipher;
|
|
break;
|
|
case "AES-192-CBC":
|
|
i = 24,
|
|
s = o.aes.createDecryptionCipher;
|
|
break;
|
|
case "AES-256-CBC":
|
|
i = 32,
|
|
s = o.aes.createDecryptionCipher;
|
|
break;
|
|
case "RC2-40-CBC":
|
|
i = 5,
|
|
s = function(e) {
|
|
return o.rc2.createDecryptionCipher(e, 40)
|
|
}
|
|
;
|
|
break;
|
|
case "RC2-64-CBC":
|
|
i = 8,
|
|
s = function(e) {
|
|
return o.rc2.createDecryptionCipher(e, 64)
|
|
}
|
|
;
|
|
break;
|
|
case "RC2-128-CBC":
|
|
i = 16,
|
|
s = function(e) {
|
|
return o.rc2.createDecryptionCipher(e, 128)
|
|
}
|
|
;
|
|
break;
|
|
default:
|
|
var n = new Error('Could not decrypt private key; unsupported encryption algorithm "' + a.dekInfo.algorithm + '".');
|
|
throw n.algorithm = a.dekInfo.algorithm,
|
|
n
|
|
}
|
|
var c = o.util.hexToBytes(a.dekInfo.parameters)
|
|
, p = o.pbe.opensslDeriveBytes(t, c.substr(0, 8), i)
|
|
, f = s(p);
|
|
if (f.start(c),
|
|
f.update(o.util.createBuffer(a.body)),
|
|
!f.finish())
|
|
return r;
|
|
r = f.output.getBytes()
|
|
} else
|
|
r = a.body;
|
|
return r = "ENCRYPTED PRIVATE KEY" === a.type ? l.decryptPrivateKeyInfo(u.fromDer(r), t) : u.fromDer(r),
|
|
null !== r && (r = l.privateKeyFromAsn1(r)),
|
|
r
|
|
}
|
|
,
|
|
l.pbe.generatePkcs12Key = function(e, t, r, a, n, i) {
|
|
var s, c;
|
|
if (void 0 === i || null === i) {
|
|
if (!("sha1"in o.md))
|
|
throw new Error('"sha1" hash algorithm unavailable.');
|
|
i = o.md.sha1.create()
|
|
}
|
|
var u = i.digestLength
|
|
, l = i.blockLength
|
|
, p = new o.util.ByteBuffer
|
|
, f = new o.util.ByteBuffer;
|
|
if (null !== e && void 0 !== e) {
|
|
for (c = 0; c < e.length; c++)
|
|
f.putInt16(e.charCodeAt(c));
|
|
f.putInt16(0)
|
|
}
|
|
var h = f.length()
|
|
, d = t.length()
|
|
, y = new o.util.ByteBuffer;
|
|
y.fillWithByte(r, l);
|
|
var g = l * Math.ceil(d / l)
|
|
, v = new o.util.ByteBuffer;
|
|
for (c = 0; c < g; c++)
|
|
v.putByte(t.at(c % d));
|
|
var m = l * Math.ceil(h / l)
|
|
, C = new o.util.ByteBuffer;
|
|
for (c = 0; c < m; c++)
|
|
C.putByte(f.at(c % h));
|
|
var E = v;
|
|
E.putBuffer(C);
|
|
for (var S = Math.ceil(n / u), T = 1; T <= S; T++) {
|
|
var I = new o.util.ByteBuffer;
|
|
I.putBytes(y.bytes()),
|
|
I.putBytes(E.bytes());
|
|
for (var b = 0; b < a; b++)
|
|
i.start(),
|
|
i.update(I.getBytes()),
|
|
I = i.digest();
|
|
var A = new o.util.ByteBuffer;
|
|
for (c = 0; c < l; c++)
|
|
A.putByte(I.at(c % u));
|
|
var B = Math.ceil(d / l) + Math.ceil(h / l)
|
|
, N = new o.util.ByteBuffer;
|
|
for (s = 0; s < B; s++) {
|
|
var k = new o.util.ByteBuffer(E.getBytes(l))
|
|
, w = 511;
|
|
for (c = A.length() - 1; c >= 0; c--)
|
|
w >>= 8,
|
|
w += A.at(c) + k.at(c),
|
|
k.setAt(c, 255 & w);
|
|
N.putBuffer(k)
|
|
}
|
|
E = N,
|
|
p.putBuffer(I)
|
|
}
|
|
return p.truncate(p.length() - n),
|
|
p
|
|
}
|
|
,
|
|
l.pbe.getCipher = function(e, t, r) {
|
|
switch (e) {
|
|
case l.oids.pkcs5PBES2:
|
|
return l.pbe.getCipherForPBES2(e, t, r);
|
|
case l.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:
|
|
case l.oids["pbewithSHAAnd40BitRC2-CBC"]:
|
|
return l.pbe.getCipherForPKCS12PBE(e, t, r);
|
|
default:
|
|
var a = new Error("Cannot read encrypted PBE data block. Unsupported OID.");
|
|
throw a.oid = e,
|
|
a.supportedOids = ["pkcs5PBES2", "pbeWithSHAAnd3-KeyTripleDES-CBC", "pbewithSHAAnd40BitRC2-CBC"],
|
|
a
|
|
}
|
|
}
|
|
,
|
|
l.pbe.getCipherForPBES2 = function(e, t, r) {
|
|
var a = {}
|
|
, i = [];
|
|
if (!u.validate(t, h, a, i)) {
|
|
var s = new Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");
|
|
throw s.errors = i,
|
|
s
|
|
}
|
|
if ((e = u.derToOid(a.kdfOid)) !== l.oids.pkcs5PBKDF2) {
|
|
var s = new Error("Cannot read encrypted private key. Unsupported key derivation function OID.");
|
|
throw s.oid = e,
|
|
s.supportedOids = ["pkcs5PBKDF2"],
|
|
s
|
|
}
|
|
if ((e = u.derToOid(a.encOid)) !== l.oids["aes128-CBC"] && e !== l.oids["aes192-CBC"] && e !== l.oids["aes256-CBC"] && e !== l.oids["des-EDE3-CBC"] && e !== l.oids.desCBC) {
|
|
var s = new Error("Cannot read encrypted private key. Unsupported encryption scheme OID.");
|
|
throw s.oid = e,
|
|
s.supportedOids = ["aes128-CBC", "aes192-CBC", "aes256-CBC", "des-EDE3-CBC", "desCBC"],
|
|
s
|
|
}
|
|
var c = a.kdfSalt
|
|
, p = o.util.createBuffer(a.kdfIterationCount);
|
|
p = p.getInt(p.length() << 3);
|
|
var f, d;
|
|
switch (l.oids[e]) {
|
|
case "aes128-CBC":
|
|
f = 16,
|
|
d = o.aes.createDecryptionCipher;
|
|
break;
|
|
case "aes192-CBC":
|
|
f = 24,
|
|
d = o.aes.createDecryptionCipher;
|
|
break;
|
|
case "aes256-CBC":
|
|
f = 32,
|
|
d = o.aes.createDecryptionCipher;
|
|
break;
|
|
case "des-EDE3-CBC":
|
|
f = 24,
|
|
d = o.des.createDecryptionCipher;
|
|
break;
|
|
case "desCBC":
|
|
f = 8,
|
|
d = o.des.createDecryptionCipher
|
|
}
|
|
var y = n(a.prfOid)
|
|
, g = o.pkcs5.pbkdf2(r, c, p, f, y)
|
|
, v = a.encIv
|
|
, m = d(g);
|
|
return m.start(v),
|
|
m
|
|
}
|
|
,
|
|
l.pbe.getCipherForPKCS12PBE = function(e, t, r) {
|
|
var a = {}
|
|
, i = [];
|
|
if (!u.validate(t, d, a, i)) {
|
|
var s = new Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");
|
|
throw s.errors = i,
|
|
s
|
|
}
|
|
var c = o.util.createBuffer(a.salt)
|
|
, p = o.util.createBuffer(a.iterations);
|
|
p = p.getInt(p.length() << 3);
|
|
var f, h, y;
|
|
switch (e) {
|
|
case l.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:
|
|
f = 24,
|
|
h = 8,
|
|
y = o.des.startDecrypting;
|
|
break;
|
|
case l.oids["pbewithSHAAnd40BitRC2-CBC"]:
|
|
f = 5,
|
|
h = 8,
|
|
y = function(e, t) {
|
|
var r = o.rc2.createDecryptionCipher(e, 40);
|
|
return r.start(t, null),
|
|
r
|
|
}
|
|
;
|
|
break;
|
|
default:
|
|
var s = new Error("Cannot read PKCS #12 PBE data block. Unsupported OID.");
|
|
throw s.oid = e,
|
|
s
|
|
}
|
|
var g = n(a.prfOid)
|
|
, v = l.pbe.generatePkcs12Key(r, c, 1, p, f, g);
|
|
return g.start(),
|
|
y(v, l.pbe.generatePkcs12Key(r, c, 2, p, h, g))
|
|
}
|
|
,
|
|
l.pbe.opensslDeriveBytes = function(e, t, r, n) {
|
|
if (void 0 === n || null === n) {
|
|
if (!("md5"in o.md))
|
|
throw new Error('"md5" hash algorithm unavailable.');
|
|
n = o.md.md5.create()
|
|
}
|
|
null === t && (t = "");
|
|
for (var i = [a(n, e + t)], s = 16, c = 1; s < r; ++c,
|
|
s += 16)
|
|
i.push(a(n, i[c - 1] + e + t));
|
|
return i.join("").substr(0, r)
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
function a() {
|
|
o = String.fromCharCode(128),
|
|
o += i.util.fillString(String.fromCharCode(0), 64),
|
|
u = [1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298],
|
|
c = !0
|
|
}
|
|
function n(e, t, r) {
|
|
for (var a, n, i, s, o, c, l, p, f, h, d, y, g, v, m, C = r.length(); C >= 64; ) {
|
|
for (l = 0; l < 16; ++l)
|
|
t[l] = r.getInt32();
|
|
for (; l < 64; ++l)
|
|
a = t[l - 2],
|
|
a = (a >>> 17 | a << 15) ^ (a >>> 19 | a << 13) ^ a >>> 10,
|
|
n = t[l - 15],
|
|
n = (n >>> 7 | n << 25) ^ (n >>> 18 | n << 14) ^ n >>> 3,
|
|
t[l] = a + t[l - 7] + n + t[l - 16] | 0;
|
|
for (p = e.h0,
|
|
f = e.h1,
|
|
h = e.h2,
|
|
d = e.h3,
|
|
y = e.h4,
|
|
g = e.h5,
|
|
v = e.h6,
|
|
m = e.h7,
|
|
l = 0; l < 64; ++l)
|
|
s = (y >>> 6 | y << 26) ^ (y >>> 11 | y << 21) ^ (y >>> 25 | y << 7),
|
|
o = v ^ y & (g ^ v),
|
|
i = (p >>> 2 | p << 30) ^ (p >>> 13 | p << 19) ^ (p >>> 22 | p << 10),
|
|
c = p & f | h & (p ^ f),
|
|
a = m + s + o + u[l] + t[l],
|
|
n = i + c,
|
|
m = v,
|
|
v = g,
|
|
g = y,
|
|
y = d + a >>> 0,
|
|
d = h,
|
|
h = f,
|
|
f = p,
|
|
p = a + n >>> 0;
|
|
e.h0 = e.h0 + p | 0,
|
|
e.h1 = e.h1 + f | 0,
|
|
e.h2 = e.h2 + h | 0,
|
|
e.h3 = e.h3 + d | 0,
|
|
e.h4 = e.h4 + y | 0,
|
|
e.h5 = e.h5 + g | 0,
|
|
e.h6 = e.h6 + v | 0,
|
|
e.h7 = e.h7 + m | 0,
|
|
C -= 64
|
|
}
|
|
}
|
|
var i = r(0);
|
|
r(4),
|
|
r(1);
|
|
var s = e.exports = i.sha256 = i.sha256 || {};
|
|
i.md.sha256 = i.md.algorithms.sha256 = s,
|
|
s.create = function() {
|
|
c || a();
|
|
var e = null
|
|
, t = i.util.createBuffer()
|
|
, r = new Array(64)
|
|
, s = {
|
|
algorithm: "sha256",
|
|
blockLength: 64,
|
|
digestLength: 32,
|
|
messageLength: 0,
|
|
fullMessageLength: null,
|
|
messageLengthSize: 8
|
|
};
|
|
return s.start = function() {
|
|
s.messageLength = 0,
|
|
s.fullMessageLength = s.messageLength64 = [];
|
|
for (var r = s.messageLengthSize / 4, a = 0; a < r; ++a)
|
|
s.fullMessageLength.push(0);
|
|
return t = i.util.createBuffer(),
|
|
e = {
|
|
h0: 1779033703,
|
|
h1: 3144134277,
|
|
h2: 1013904242,
|
|
h3: 2773480762,
|
|
h4: 1359893119,
|
|
h5: 2600822924,
|
|
h6: 528734635,
|
|
h7: 1541459225
|
|
},
|
|
s
|
|
}
|
|
,
|
|
s.start(),
|
|
s.update = function(a, o) {
|
|
"utf8" === o && (a = i.util.encodeUtf8(a));
|
|
var c = a.length;
|
|
s.messageLength += c,
|
|
c = [c / 4294967296 >>> 0, c >>> 0];
|
|
for (var u = s.fullMessageLength.length - 1; u >= 0; --u)
|
|
s.fullMessageLength[u] += c[1],
|
|
c[1] = c[0] + (s.fullMessageLength[u] / 4294967296 >>> 0),
|
|
s.fullMessageLength[u] = s.fullMessageLength[u] >>> 0,
|
|
c[0] = c[1] / 4294967296 >>> 0;
|
|
return t.putBytes(a),
|
|
n(e, r, t),
|
|
(t.read > 2048 || 0 === t.length()) && t.compact(),
|
|
s
|
|
}
|
|
,
|
|
s.digest = function() {
|
|
var a = i.util.createBuffer();
|
|
a.putBytes(t.bytes());
|
|
var c = s.fullMessageLength[s.fullMessageLength.length - 1] + s.messageLengthSize
|
|
, u = c & s.blockLength - 1;
|
|
a.putBytes(o.substr(0, s.blockLength - u));
|
|
for (var l, p, f = 8 * s.fullMessageLength[0], h = 0; h < s.fullMessageLength.length - 1; ++h)
|
|
l = 8 * s.fullMessageLength[h + 1],
|
|
p = l / 4294967296 >>> 0,
|
|
f += p,
|
|
a.putInt32(f >>> 0),
|
|
f = l >>> 0;
|
|
a.putInt32(f);
|
|
var d = {
|
|
h0: e.h0,
|
|
h1: e.h1,
|
|
h2: e.h2,
|
|
h3: e.h3,
|
|
h4: e.h4,
|
|
h5: e.h5,
|
|
h6: e.h6,
|
|
h7: e.h7
|
|
};
|
|
n(d, r, a);
|
|
var y = i.util.createBuffer();
|
|
return y.putInt32(d.h0),
|
|
y.putInt32(d.h1),
|
|
y.putInt32(d.h2),
|
|
y.putInt32(d.h3),
|
|
y.putInt32(d.h4),
|
|
y.putInt32(d.h5),
|
|
y.putInt32(d.h6),
|
|
y.putInt32(d.h7),
|
|
y
|
|
}
|
|
,
|
|
s
|
|
}
|
|
;
|
|
var o = null
|
|
, c = !1
|
|
, u = null
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(1);
|
|
var n = null;
|
|
!a.util.isNodejs || a.options.usePureJavaScript || process.versions["node-webkit"] || (n = r(16)),
|
|
(e.exports = a.prng = a.prng || {}).create = function(e) {
|
|
function t(e) {
|
|
if (o.pools[0].messageLength >= 32)
|
|
return i(),
|
|
e();
|
|
var t = 32 - o.pools[0].messageLength << 5;
|
|
o.seedFile(t, function(t, r) {
|
|
if (t)
|
|
return e(t);
|
|
o.collect(r),
|
|
i(),
|
|
e()
|
|
})
|
|
}
|
|
function r() {
|
|
if (o.pools[0].messageLength >= 32)
|
|
return i();
|
|
var e = 32 - o.pools[0].messageLength << 5;
|
|
o.collect(o.seedFileSync(e)),
|
|
i()
|
|
}
|
|
function i() {
|
|
o.reseeds = 4294967295 === o.reseeds ? 0 : o.reseeds + 1;
|
|
var e = o.plugin.md.create();
|
|
e.update(o.keyBytes);
|
|
for (var t = 1, r = 0; r < 32; ++r)
|
|
o.reseeds % t == 0 && (e.update(o.pools[r].digest().getBytes()),
|
|
o.pools[r].start()),
|
|
t <<= 1;
|
|
o.keyBytes = e.digest().getBytes(),
|
|
e.start(),
|
|
e.update(o.keyBytes);
|
|
var a = e.digest().getBytes();
|
|
o.key = o.plugin.formatKey(o.keyBytes),
|
|
o.seed = o.plugin.formatSeed(a),
|
|
o.generated = 0
|
|
}
|
|
function s(e) {
|
|
var t = null
|
|
, r = a.util.globalScope
|
|
, n = r.crypto || r.msCrypto;
|
|
n && n.getRandomValues && (t = function(e) {
|
|
return n.getRandomValues(e)
|
|
}
|
|
);
|
|
var i = a.util.createBuffer();
|
|
if (t)
|
|
for (; i.length() < e; ) {
|
|
var s = Math.max(1, Math.min(e - i.length(), 65536) / 4)
|
|
, o = new Uint32Array(Math.floor(s));
|
|
try {
|
|
t(o);
|
|
for (var c = 0; c < o.length; ++c)
|
|
i.putInt32(o[c])
|
|
} catch (e) {
|
|
if (!("undefined" != typeof QuotaExceededError && e instanceof QuotaExceededError))
|
|
throw e
|
|
}
|
|
}
|
|
if (i.length() < e)
|
|
for (var u, l, p, f = Math.floor(65536 * Math.random()); i.length() < e; ) {
|
|
l = 16807 * (65535 & f),
|
|
u = 16807 * (f >> 16),
|
|
l += (32767 & u) << 16,
|
|
l += u >> 15,
|
|
l = (2147483647 & l) + (l >> 31),
|
|
f = 4294967295 & l;
|
|
for (var c = 0; c < 3; ++c)
|
|
p = f >>> (c << 3),
|
|
p ^= Math.floor(256 * Math.random()),
|
|
i.putByte(String.fromCharCode(255 & p))
|
|
}
|
|
return i.getBytes(e)
|
|
}
|
|
for (var o = {
|
|
plugin: e,
|
|
key: null,
|
|
seed: null,
|
|
time: null,
|
|
reseeds: 0,
|
|
generated: 0,
|
|
keyBytes: ""
|
|
}, c = e.md, u = new Array(32), l = 0; l < 32; ++l)
|
|
u[l] = c.create();
|
|
return o.pools = u,
|
|
o.pool = 0,
|
|
o.generate = function(e, r) {
|
|
function n(p) {
|
|
if (p)
|
|
return r(p);
|
|
if (l.length() >= e)
|
|
return r(null, l.getBytes(e));
|
|
if (o.generated > 1048575 && (o.key = null),
|
|
null === o.key)
|
|
return a.util.nextTick(function() {
|
|
t(n)
|
|
});
|
|
var f = i(o.key, o.seed);
|
|
o.generated += f.length,
|
|
l.putBytes(f),
|
|
o.key = c(i(o.key, s(o.seed))),
|
|
o.seed = u(i(o.key, o.seed)),
|
|
a.util.setImmediate(n)
|
|
}
|
|
if (!r)
|
|
return o.generateSync(e);
|
|
var i = o.plugin.cipher
|
|
, s = o.plugin.increment
|
|
, c = o.plugin.formatKey
|
|
, u = o.plugin.formatSeed
|
|
, l = a.util.createBuffer();
|
|
o.key = null,
|
|
n()
|
|
}
|
|
,
|
|
o.generateSync = function(e) {
|
|
var t = o.plugin.cipher
|
|
, n = o.plugin.increment
|
|
, i = o.plugin.formatKey
|
|
, s = o.plugin.formatSeed;
|
|
o.key = null;
|
|
for (var c = a.util.createBuffer(); c.length() < e; ) {
|
|
o.generated > 1048575 && (o.key = null),
|
|
null === o.key && r();
|
|
var u = t(o.key, o.seed);
|
|
o.generated += u.length,
|
|
c.putBytes(u),
|
|
o.key = i(t(o.key, n(o.seed))),
|
|
o.seed = s(t(o.key, o.seed))
|
|
}
|
|
return c.getBytes(e)
|
|
}
|
|
,
|
|
n ? (o.seedFile = function(e, t) {
|
|
n.randomBytes(e, function(e, r) {
|
|
if (e)
|
|
return t(e);
|
|
t(null, r.toString())
|
|
})
|
|
}
|
|
,
|
|
o.seedFileSync = function(e) {
|
|
return n.randomBytes(e).toString()
|
|
}
|
|
) : (o.seedFile = function(e, t) {
|
|
try {
|
|
t(null, s(e))
|
|
} catch (e) {
|
|
t(e)
|
|
}
|
|
}
|
|
,
|
|
o.seedFileSync = s),
|
|
o.collect = function(e) {
|
|
for (var t = e.length, r = 0; r < t; ++r)
|
|
o.pools[o.pool].update(e.substr(r, 1)),
|
|
o.pool = 31 === o.pool ? 0 : o.pool + 1
|
|
}
|
|
,
|
|
o.collectInt = function(e, t) {
|
|
for (var r = "", a = 0; a < t; a += 8)
|
|
r += String.fromCharCode(e >> a & 255);
|
|
o.collect(r)
|
|
}
|
|
,
|
|
o.registerWorker = function(e) {
|
|
if (e === self)
|
|
o.seedFile = function(e, t) {
|
|
function r(e) {
|
|
var a = e.data;
|
|
a.forge && a.forge.prng && (self.removeEventListener("message", r),
|
|
t(a.forge.prng.err, a.forge.prng.bytes))
|
|
}
|
|
self.addEventListener("message", r),
|
|
self.postMessage({
|
|
forge: {
|
|
prng: {
|
|
needed: e
|
|
}
|
|
}
|
|
})
|
|
}
|
|
;
|
|
else {
|
|
var t = function(t) {
|
|
var r = t.data;
|
|
r.forge && r.forge.prng && o.seedFile(r.forge.prng.needed, function(t, r) {
|
|
e.postMessage({
|
|
forge: {
|
|
prng: {
|
|
err: t,
|
|
bytes: r
|
|
}
|
|
}
|
|
})
|
|
})
|
|
};
|
|
e.addEventListener("message", t)
|
|
}
|
|
}
|
|
,
|
|
o
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(1);
|
|
var n = [217, 120, 249, 196, 25, 221, 181, 237, 40, 233, 253, 121, 74, 160, 216, 157, 198, 126, 55, 131, 43, 118, 83, 142, 98, 76, 100, 136, 68, 139, 251, 162, 23, 154, 89, 245, 135, 179, 79, 19, 97, 69, 109, 141, 9, 129, 125, 50, 189, 143, 64, 235, 134, 183, 123, 11, 240, 149, 33, 34, 92, 107, 78, 130, 84, 214, 101, 147, 206, 96, 178, 28, 115, 86, 192, 20, 167, 140, 241, 220, 18, 117, 202, 31, 59, 190, 228, 209, 66, 61, 212, 48, 163, 60, 182, 38, 111, 191, 14, 218, 70, 105, 7, 87, 39, 242, 29, 155, 188, 148, 67, 3, 248, 17, 199, 246, 144, 239, 62, 231, 6, 195, 213, 47, 200, 102, 30, 215, 8, 232, 234, 222, 128, 82, 238, 247, 132, 170, 114, 172, 53, 77, 106, 42, 150, 26, 210, 113, 90, 21, 73, 116, 75, 159, 208, 94, 4, 24, 164, 236, 194, 224, 65, 110, 15, 81, 203, 204, 36, 145, 175, 80, 161, 244, 112, 57, 153, 124, 58, 133, 35, 184, 180, 122, 252, 2, 54, 91, 37, 85, 151, 49, 45, 93, 250, 152, 227, 138, 146, 174, 5, 223, 41, 16, 103, 108, 186, 201, 211, 0, 230, 207, 225, 158, 168, 44, 99, 22, 1, 63, 88, 226, 137, 169, 13, 56, 52, 27, 171, 51, 255, 176, 187, 72, 12, 95, 185, 177, 205, 46, 197, 243, 219, 71, 229, 165, 156, 119, 10, 166, 32, 104, 254, 127, 193, 173]
|
|
, i = [1, 2, 3, 5]
|
|
, s = function(e, t) {
|
|
return e << t & 65535 | (65535 & e) >> 16 - t
|
|
}
|
|
, o = function(e, t) {
|
|
return (65535 & e) >> t | e << 16 - t & 65535
|
|
};
|
|
e.exports = a.rc2 = a.rc2 || {},
|
|
a.rc2.expandKey = function(e, t) {
|
|
"string" == typeof e && (e = a.util.createBuffer(e)),
|
|
t = t || 128;
|
|
var r, i = e, s = e.length(), o = t, c = Math.ceil(o / 8), u = 255 >> (7 & o);
|
|
for (r = s; r < 128; r++)
|
|
i.putByte(n[i.at(r - 1) + i.at(r - s) & 255]);
|
|
for (i.setAt(128 - c, n[i.at(128 - c) & u]),
|
|
r = 127 - c; r >= 0; r--)
|
|
i.setAt(r, n[i.at(r + 1) ^ i.at(r + c)]);
|
|
return i
|
|
}
|
|
;
|
|
var c = function(e, t, r) {
|
|
var n, c, u, l, p = !1, f = null, h = null, d = null, y = [];
|
|
for (e = a.rc2.expandKey(e, t),
|
|
u = 0; u < 64; u++)
|
|
y.push(e.getInt16Le());
|
|
r ? (n = function(e) {
|
|
for (u = 0; u < 4; u++)
|
|
e[u] += y[l] + (e[(u + 3) % 4] & e[(u + 2) % 4]) + (~e[(u + 3) % 4] & e[(u + 1) % 4]),
|
|
e[u] = s(e[u], i[u]),
|
|
l++
|
|
}
|
|
,
|
|
c = function(e) {
|
|
for (u = 0; u < 4; u++)
|
|
e[u] += y[63 & e[(u + 3) % 4]]
|
|
}
|
|
) : (n = function(e) {
|
|
for (u = 3; u >= 0; u--)
|
|
e[u] = o(e[u], i[u]),
|
|
e[u] -= y[l] + (e[(u + 3) % 4] & e[(u + 2) % 4]) + (~e[(u + 3) % 4] & e[(u + 1) % 4]),
|
|
l--
|
|
}
|
|
,
|
|
c = function(e) {
|
|
for (u = 3; u >= 0; u--)
|
|
e[u] -= y[63 & e[(u + 3) % 4]]
|
|
}
|
|
);
|
|
var g = function(e) {
|
|
var t = [];
|
|
for (u = 0; u < 4; u++) {
|
|
var a = f.getInt16Le();
|
|
null !== d && (r ? a ^= d.getInt16Le() : d.putInt16Le(a)),
|
|
t.push(65535 & a)
|
|
}
|
|
l = r ? 0 : 63;
|
|
for (var n = 0; n < e.length; n++)
|
|
for (var i = 0; i < e[n][0]; i++)
|
|
e[n][1](t);
|
|
for (u = 0; u < 4; u++)
|
|
null !== d && (r ? d.putInt16Le(t[u]) : t[u] ^= d.getInt16Le()),
|
|
h.putInt16Le(t[u])
|
|
}
|
|
, v = null;
|
|
return v = {
|
|
start: function(e, t) {
|
|
e && "string" == typeof e && (e = a.util.createBuffer(e)),
|
|
p = !1,
|
|
f = a.util.createBuffer(),
|
|
h = t || new a.util.createBuffer,
|
|
d = e,
|
|
v.output = h
|
|
},
|
|
update: function(e) {
|
|
for (p || f.putBuffer(e); f.length() >= 8; )
|
|
g([[5, n], [1, c], [6, n], [1, c], [5, n]])
|
|
},
|
|
finish: function(e) {
|
|
var t = !0;
|
|
if (r)
|
|
if (e)
|
|
t = e(8, f, !r);
|
|
else {
|
|
var a = 8 === f.length() ? 8 : 8 - f.length();
|
|
f.fillWithByte(a, a)
|
|
}
|
|
if (t && (p = !0,
|
|
v.update()),
|
|
!r && (t = 0 === f.length()))
|
|
if (e)
|
|
t = e(8, h, !r);
|
|
else {
|
|
var n = h.length()
|
|
, i = h.at(n - 1);
|
|
i > n ? t = !1 : h.truncate(i)
|
|
}
|
|
return t
|
|
}
|
|
}
|
|
};
|
|
a.rc2.startEncrypting = function(e, t, r) {
|
|
var n = a.rc2.createEncryptionCipher(e, 128);
|
|
return n.start(t, r),
|
|
n
|
|
}
|
|
,
|
|
a.rc2.createEncryptionCipher = function(e, t) {
|
|
return c(e, t, !0)
|
|
}
|
|
,
|
|
a.rc2.startDecrypting = function(e, t, r) {
|
|
var n = a.rc2.createDecryptionCipher(e, 128);
|
|
return n.start(t, r),
|
|
n
|
|
}
|
|
,
|
|
a.rc2.createDecryptionCipher = function(e, t) {
|
|
return c(e, t, !1)
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t, r) {
|
|
r || (r = n.md.sha1.create());
|
|
for (var a = "", i = Math.ceil(t / r.digestLength), s = 0; s < i; ++s) {
|
|
var o = String.fromCharCode(s >> 24 & 255, s >> 16 & 255, s >> 8 & 255, 255 & s);
|
|
r.start(),
|
|
r.update(e + o),
|
|
a += r.digest().getBytes()
|
|
}
|
|
return a.substring(0, t)
|
|
}
|
|
var n = r(0);
|
|
r(1),
|
|
r(2),
|
|
r(9);
|
|
var i = e.exports = n.pkcs1 = n.pkcs1 || {};
|
|
i.encode_rsa_oaep = function(e, t, r) {
|
|
var i, s, o, c;
|
|
"string" == typeof r ? (i = r,
|
|
s = arguments[3] || void 0,
|
|
o = arguments[4] || void 0) : r && (i = r.label || void 0,
|
|
s = r.seed || void 0,
|
|
o = r.md || void 0,
|
|
r.mgf1 && r.mgf1.md && (c = r.mgf1.md)),
|
|
o ? o.start() : o = n.md.sha1.create(),
|
|
c || (c = o);
|
|
var u = Math.ceil(e.n.bitLength() / 8)
|
|
, l = u - 2 * o.digestLength - 2;
|
|
if (t.length > l) {
|
|
var p = new Error("RSAES-OAEP input message length is too long.");
|
|
throw p.length = t.length,
|
|
p.maxLength = l,
|
|
p
|
|
}
|
|
i || (i = ""),
|
|
o.update(i, "raw");
|
|
for (var f = o.digest(), h = "", d = l - t.length, y = 0; y < d; y++)
|
|
h += "\0";
|
|
var g = f.getBytes() + h + "" + t;
|
|
if (s) {
|
|
if (s.length !== o.digestLength) {
|
|
var p = new Error("Invalid RSAES-OAEP seed. The seed length must match the digest length.");
|
|
throw p.seedLength = s.length,
|
|
p.digestLength = o.digestLength,
|
|
p
|
|
}
|
|
} else
|
|
s = n.random.getBytes(o.digestLength);
|
|
var v = a(s, u - o.digestLength - 1, c)
|
|
, m = n.util.xorBytes(g, v, g.length)
|
|
, C = a(m, o.digestLength, c);
|
|
return "\0" + n.util.xorBytes(s, C, s.length) + m
|
|
}
|
|
,
|
|
i.decode_rsa_oaep = function(e, t, r) {
|
|
var i, s, o;
|
|
"string" == typeof r ? (i = r,
|
|
s = arguments[3] || void 0) : r && (i = r.label || void 0,
|
|
s = r.md || void 0,
|
|
r.mgf1 && r.mgf1.md && (o = r.mgf1.md));
|
|
var c = Math.ceil(e.n.bitLength() / 8);
|
|
if (t.length !== c) {
|
|
var u = new Error("RSAES-OAEP encoded message length is invalid.");
|
|
throw u.length = t.length,
|
|
u.expectedLength = c,
|
|
u
|
|
}
|
|
if (void 0 === s ? s = n.md.sha1.create() : s.start(),
|
|
o || (o = s),
|
|
c < 2 * s.digestLength + 2)
|
|
throw new Error("RSAES-OAEP key is too short for the hash function.");
|
|
i || (i = ""),
|
|
s.update(i, "raw");
|
|
for (var l = s.digest().getBytes(), p = t.charAt(0), f = t.substring(1, s.digestLength + 1), h = t.substring(1 + s.digestLength), d = a(h, s.digestLength, o), y = n.util.xorBytes(f, d, f.length), g = a(y, c - s.digestLength - 1, o), v = n.util.xorBytes(h, g, h.length), m = v.substring(0, s.digestLength), u = "\0" !== p, C = 0; C < s.digestLength; ++C)
|
|
u |= l.charAt(C) !== m.charAt(C);
|
|
for (var E = 1, S = s.digestLength, T = s.digestLength; T < v.length; T++) {
|
|
var I = v.charCodeAt(T)
|
|
, b = 1 & I ^ 1;
|
|
u |= I & (E ? 65534 : 0),
|
|
E &= b,
|
|
S += E
|
|
}
|
|
if (u || 1 !== v.charCodeAt(S))
|
|
throw new Error("Invalid RSAES-OAEP padding.");
|
|
return v.substring(S + 1)
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(1),
|
|
r(12),
|
|
r(2),
|
|
function() {
|
|
function t(e, t, a, n) {
|
|
return "workers"in a ? i(e, t, a, n) : r(e, t, a, n)
|
|
}
|
|
function r(e, t, r, a) {
|
|
var i = s(e, t)
|
|
, c = o(i.bitLength());
|
|
"millerRabinTests"in r && (c = r.millerRabinTests);
|
|
var u = 10;
|
|
"maxBlockTime"in r && (u = r.maxBlockTime),
|
|
n(i, e, t, 0, c, u, a)
|
|
}
|
|
function n(e, t, r, i, o, c, u) {
|
|
var p = +new Date;
|
|
do {
|
|
if (e.bitLength() > t && (e = s(t, r)),
|
|
e.isProbablePrime(o))
|
|
return u(null, e);
|
|
e.dAddOffset(l[i++ % 8], 0)
|
|
} while (c < 0 || +new Date - p < c);
|
|
a.util.setImmediate(function() {
|
|
n(e, t, r, i, o, c, u)
|
|
})
|
|
}
|
|
function i(e, t, n, i) {
|
|
function o() {
|
|
function r(r) {
|
|
if (!d) {
|
|
--o;
|
|
var n = r.data;
|
|
if (n.found) {
|
|
for (var l = 0; l < a.length; ++l)
|
|
a[l].terminate();
|
|
return d = !0,
|
|
i(null, new u(n.prime,16))
|
|
}
|
|
c.bitLength() > e && (c = s(e, t));
|
|
var h = c.toString(16);
|
|
r.target.postMessage({
|
|
hex: h,
|
|
workLoad: p
|
|
}),
|
|
c.dAddOffset(f, 0)
|
|
}
|
|
}
|
|
l = Math.max(1, l);
|
|
for (var a = [], n = 0; n < l; ++n)
|
|
a[n] = new Worker(h);
|
|
for (var o = l, n = 0; n < l; ++n)
|
|
a[n].addEventListener("message", r);
|
|
var d = !1
|
|
}
|
|
if ("undefined" == typeof Worker)
|
|
return r(e, t, n, i);
|
|
var c = s(e, t)
|
|
, l = n.workers
|
|
, p = n.workLoad || 100
|
|
, f = 30 * p / 8
|
|
, h = n.workerScript || "forge/prime.worker.js";
|
|
if (-1 === l)
|
|
return a.util.estimateCores(function(e, t) {
|
|
e && (t = 2),
|
|
l = t - 1,
|
|
o()
|
|
});
|
|
o()
|
|
}
|
|
function s(e, t) {
|
|
var r = new u(e,t)
|
|
, a = e - 1;
|
|
return r.testBit(a) || r.bitwiseTo(u.ONE.shiftLeft(a), f, r),
|
|
r.dAddOffset(31 - r.mod(p).byteValue(), 0),
|
|
r
|
|
}
|
|
function o(e) {
|
|
return e <= 100 ? 27 : e <= 150 ? 18 : e <= 200 ? 15 : e <= 250 ? 12 : e <= 300 ? 9 : e <= 350 ? 8 : e <= 400 ? 7 : e <= 500 ? 6 : e <= 600 ? 5 : e <= 800 ? 4 : e <= 1250 ? 3 : 2
|
|
}
|
|
if (a.prime)
|
|
return void (e.exports = a.prime);
|
|
var c = e.exports = a.prime = a.prime || {}
|
|
, u = a.jsbn.BigInteger
|
|
, l = [6, 4, 2, 4, 2, 4, 6, 2]
|
|
, p = new u(null);
|
|
p.fromInt(30);
|
|
var f = function(e, t) {
|
|
return e | t
|
|
};
|
|
c.generateProbablePrime = function(e, r, n) {
|
|
"function" == typeof r && (n = r,
|
|
r = {}),
|
|
r = r || {};
|
|
var i = r.algorithm || "PRIMEINC";
|
|
"string" == typeof i && (i = {
|
|
name: i
|
|
}),
|
|
i.options = i.options || {};
|
|
var s = r.prng || a.random
|
|
, o = {
|
|
nextBytes: function(e) {
|
|
for (var t = s.getBytesSync(e.length), r = 0; r < e.length; ++r)
|
|
e[r] = t.charCodeAt(r)
|
|
}
|
|
};
|
|
if ("PRIMEINC" === i.name)
|
|
return t(e, o, i.options, n);
|
|
throw new Error("Invalid prime generation algorithm: " + i.name)
|
|
}
|
|
}()
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t, r, a) {
|
|
for (var n = [], i = 0; i < e.length; i++)
|
|
for (var s = 0; s < e[i].safeBags.length; s++) {
|
|
var o = e[i].safeBags[s];
|
|
void 0 !== a && o.type !== a || (null !== t ? void 0 !== o.attributes[t] && o.attributes[t].indexOf(r) >= 0 && n.push(o) : n.push(o))
|
|
}
|
|
return n
|
|
}
|
|
function n(e) {
|
|
if (e.composed || e.constructed) {
|
|
for (var t = u.util.createBuffer(), r = 0; r < e.value.length; ++r)
|
|
t.putBytes(e.value[r].value);
|
|
e.composed = e.constructed = !1,
|
|
e.value = t.getBytes()
|
|
}
|
|
return e
|
|
}
|
|
function i(e, t, r, a) {
|
|
if (t = l.fromDer(t, r),
|
|
t.tagClass !== l.Class.UNIVERSAL || t.type !== l.Type.SEQUENCE || !0 !== t.constructed)
|
|
throw new Error("PKCS#12 AuthenticatedSafe expected to be a SEQUENCE OF ContentInfo");
|
|
for (var i = 0; i < t.value.length; i++) {
|
|
var c = t.value[i]
|
|
, u = {}
|
|
, f = [];
|
|
if (!l.validate(c, h, u, f)) {
|
|
var d = new Error("Cannot read ContentInfo.");
|
|
throw d.errors = f,
|
|
d
|
|
}
|
|
var y = {
|
|
encrypted: !1
|
|
}
|
|
, g = null
|
|
, v = u.content.value[0];
|
|
switch (l.derToOid(u.contentType)) {
|
|
case p.oids.data:
|
|
if (v.tagClass !== l.Class.UNIVERSAL || v.type !== l.Type.OCTETSTRING)
|
|
throw new Error("PKCS#12 SafeContents Data is not an OCTET STRING.");
|
|
g = n(v).value;
|
|
break;
|
|
case p.oids.encryptedData:
|
|
g = s(v, a),
|
|
y.encrypted = !0;
|
|
break;
|
|
default:
|
|
var d = new Error("Unsupported PKCS#12 contentType.");
|
|
throw d.contentType = l.derToOid(u.contentType),
|
|
d
|
|
}
|
|
y.safeBags = o(g, r, a),
|
|
e.safeContents.push(y)
|
|
}
|
|
}
|
|
function s(e, t) {
|
|
var r = {}
|
|
, a = [];
|
|
if (!l.validate(e, u.pkcs7.asn1.encryptedDataValidator, r, a)) {
|
|
var i = new Error("Cannot read EncryptedContentInfo.");
|
|
throw i.errors = a,
|
|
i
|
|
}
|
|
var s = l.derToOid(r.contentType);
|
|
if (s !== p.oids.data) {
|
|
var i = new Error("PKCS#12 EncryptedContentInfo ContentType is not Data.");
|
|
throw i.oid = s,
|
|
i
|
|
}
|
|
s = l.derToOid(r.encAlgorithm);
|
|
var o = p.pbe.getCipher(s, r.encParameter, t)
|
|
, c = n(r.encryptedContentAsn1)
|
|
, f = u.util.createBuffer(c.value);
|
|
if (o.update(f),
|
|
!o.finish())
|
|
throw new Error("Failed to decrypt PKCS#12 SafeContents.");
|
|
return o.output.getBytes()
|
|
}
|
|
function o(e, t, r) {
|
|
if (!t && 0 === e.length)
|
|
return [];
|
|
if (e = l.fromDer(e, t),
|
|
e.tagClass !== l.Class.UNIVERSAL || e.type !== l.Type.SEQUENCE || !0 !== e.constructed)
|
|
throw new Error("PKCS#12 SafeContents expected to be a SEQUENCE OF SafeBag.");
|
|
for (var a = [], n = 0; n < e.value.length; n++) {
|
|
var i = e.value[n]
|
|
, s = {}
|
|
, o = [];
|
|
if (!l.validate(i, y, s, o)) {
|
|
var u = new Error("Cannot read SafeBag.");
|
|
throw u.errors = o,
|
|
u
|
|
}
|
|
var f = {
|
|
type: l.derToOid(s.bagId),
|
|
attributes: c(s.bagAttributes)
|
|
};
|
|
a.push(f);
|
|
var h, d, g = s.bagValue.value[0];
|
|
switch (f.type) {
|
|
case p.oids.pkcs8ShroudedKeyBag:
|
|
if (null === (g = p.decryptPrivateKeyInfo(g, r)))
|
|
throw new Error("Unable to decrypt PKCS#8 ShroudedKeyBag, wrong password?");
|
|
case p.oids.keyBag:
|
|
try {
|
|
f.key = p.privateKeyFromAsn1(g)
|
|
} catch (e) {
|
|
f.key = null,
|
|
f.asn1 = g
|
|
}
|
|
continue;
|
|
case p.oids.certBag:
|
|
h = v,
|
|
d = function() {
|
|
if (l.derToOid(s.certId) !== p.oids.x509Certificate) {
|
|
var e = new Error("Unsupported certificate type, only X.509 supported.");
|
|
throw e.oid = l.derToOid(s.certId),
|
|
e
|
|
}
|
|
var r = l.fromDer(s.cert, t);
|
|
try {
|
|
f.cert = p.certificateFromAsn1(r, !0)
|
|
} catch (e) {
|
|
f.cert = null,
|
|
f.asn1 = r
|
|
}
|
|
}
|
|
;
|
|
break;
|
|
default:
|
|
var u = new Error("Unsupported PKCS#12 SafeBag type.");
|
|
throw u.oid = f.type,
|
|
u
|
|
}
|
|
if (void 0 !== h && !l.validate(g, h, s, o)) {
|
|
var u = new Error("Cannot read PKCS#12 " + h.name);
|
|
throw u.errors = o,
|
|
u
|
|
}
|
|
d()
|
|
}
|
|
return a
|
|
}
|
|
function c(e) {
|
|
var t = {};
|
|
if (void 0 !== e)
|
|
for (var r = 0; r < e.length; ++r) {
|
|
var a = {}
|
|
, n = [];
|
|
if (!l.validate(e[r], g, a, n)) {
|
|
var i = new Error("Cannot read PKCS#12 BagAttribute.");
|
|
throw i.errors = n,
|
|
i
|
|
}
|
|
var s = l.derToOid(a.oid);
|
|
if (void 0 !== p.oids[s]) {
|
|
t[p.oids[s]] = [];
|
|
for (var o = 0; o < a.values.length; ++o)
|
|
t[p.oids[s]].push(a.values[o].value)
|
|
}
|
|
}
|
|
return t
|
|
}
|
|
var u = r(0);
|
|
r(3),
|
|
r(8),
|
|
r(6),
|
|
r(29),
|
|
r(22),
|
|
r(2),
|
|
r(11),
|
|
r(9),
|
|
r(1),
|
|
r(17);
|
|
var l = u.asn1
|
|
, p = u.pki
|
|
, f = e.exports = u.pkcs12 = u.pkcs12 || {}
|
|
, h = {
|
|
name: "ContentInfo",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "ContentInfo.contentType",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.OID,
|
|
constructed: !1,
|
|
capture: "contentType"
|
|
}, {
|
|
name: "ContentInfo.content",
|
|
tagClass: l.Class.CONTEXT_SPECIFIC,
|
|
constructed: !0,
|
|
captureAsn1: "content"
|
|
}]
|
|
}
|
|
, d = {
|
|
name: "PFX",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "PFX.version",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "version"
|
|
}, h, {
|
|
name: "PFX.macData",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.SEQUENCE,
|
|
constructed: !0,
|
|
optional: !0,
|
|
captureAsn1: "mac",
|
|
value: [{
|
|
name: "PFX.macData.mac",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "PFX.macData.mac.digestAlgorithm",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "PFX.macData.mac.digestAlgorithm.algorithm",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.OID,
|
|
constructed: !1,
|
|
capture: "macAlgorithm"
|
|
}, {
|
|
name: "PFX.macData.mac.digestAlgorithm.parameters",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
captureAsn1: "macAlgorithmParameters"
|
|
}]
|
|
}, {
|
|
name: "PFX.macData.mac.digest",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.OCTETSTRING,
|
|
constructed: !1,
|
|
capture: "macDigest"
|
|
}]
|
|
}, {
|
|
name: "PFX.macData.macSalt",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.OCTETSTRING,
|
|
constructed: !1,
|
|
capture: "macSalt"
|
|
}, {
|
|
name: "PFX.macData.iterations",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.INTEGER,
|
|
constructed: !1,
|
|
optional: !0,
|
|
capture: "macIterations"
|
|
}]
|
|
}]
|
|
}
|
|
, y = {
|
|
name: "SafeBag",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "SafeBag.bagId",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.OID,
|
|
constructed: !1,
|
|
capture: "bagId"
|
|
}, {
|
|
name: "SafeBag.bagValue",
|
|
tagClass: l.Class.CONTEXT_SPECIFIC,
|
|
constructed: !0,
|
|
captureAsn1: "bagValue"
|
|
}, {
|
|
name: "SafeBag.bagAttributes",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.SET,
|
|
constructed: !0,
|
|
optional: !0,
|
|
capture: "bagAttributes"
|
|
}]
|
|
}
|
|
, g = {
|
|
name: "Attribute",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "Attribute.attrId",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.OID,
|
|
constructed: !1,
|
|
capture: "oid"
|
|
}, {
|
|
name: "Attribute.attrValues",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.SET,
|
|
constructed: !0,
|
|
capture: "values"
|
|
}]
|
|
}
|
|
, v = {
|
|
name: "CertBag",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "CertBag.certId",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Type.OID,
|
|
constructed: !1,
|
|
capture: "certId"
|
|
}, {
|
|
name: "CertBag.certValue",
|
|
tagClass: l.Class.CONTEXT_SPECIFIC,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "CertBag.certValue[0]",
|
|
tagClass: l.Class.UNIVERSAL,
|
|
type: l.Class.OCTETSTRING,
|
|
constructed: !1,
|
|
capture: "cert"
|
|
}]
|
|
}]
|
|
};
|
|
f.pkcs12FromAsn1 = function(e, t, r) {
|
|
"string" == typeof t ? (r = t,
|
|
t = !0) : void 0 === t && (t = !0);
|
|
var s = {}
|
|
, o = [];
|
|
if (!l.validate(e, d, s, o)) {
|
|
var c = new Error("Cannot read PKCS#12 PFX. ASN.1 object is not an PKCS#12 PFX.");
|
|
throw c.errors = c,
|
|
c
|
|
}
|
|
var h = {
|
|
version: s.version.charCodeAt(0),
|
|
safeContents: [],
|
|
getBags: function(e) {
|
|
var t, r = {};
|
|
return "localKeyId"in e ? t = e.localKeyId : "localKeyIdHex"in e && (t = u.util.hexToBytes(e.localKeyIdHex)),
|
|
void 0 === t && !("friendlyName"in e) && "bagType"in e && (r[e.bagType] = a(h.safeContents, null, null, e.bagType)),
|
|
void 0 !== t && (r.localKeyId = a(h.safeContents, "localKeyId", t, e.bagType)),
|
|
"friendlyName"in e && (r.friendlyName = a(h.safeContents, "friendlyName", e.friendlyName, e.bagType)),
|
|
r
|
|
},
|
|
getBagsByFriendlyName: function(e, t) {
|
|
return a(h.safeContents, "friendlyName", e, t)
|
|
},
|
|
getBagsByLocalKeyId: function(e, t) {
|
|
return a(h.safeContents, "localKeyId", e, t)
|
|
}
|
|
};
|
|
if (3 !== s.version.charCodeAt(0)) {
|
|
var c = new Error("PKCS#12 PFX of version other than 3 not supported.");
|
|
throw c.version = s.version.charCodeAt(0),
|
|
c
|
|
}
|
|
if (l.derToOid(s.contentType) !== p.oids.data) {
|
|
var c = new Error("Only PKCS#12 PFX in password integrity mode supported.");
|
|
throw c.oid = l.derToOid(s.contentType),
|
|
c
|
|
}
|
|
var y = s.content.value[0];
|
|
if (y.tagClass !== l.Class.UNIVERSAL || y.type !== l.Type.OCTETSTRING)
|
|
throw new Error("PKCS#12 authSafe content data is not an OCTET STRING.");
|
|
if (y = n(y),
|
|
s.mac) {
|
|
var g = null
|
|
, v = 0
|
|
, m = l.derToOid(s.macAlgorithm);
|
|
switch (m) {
|
|
case p.oids.sha1:
|
|
g = u.md.sha1.create(),
|
|
v = 20;
|
|
break;
|
|
case p.oids.sha256:
|
|
g = u.md.sha256.create(),
|
|
v = 32;
|
|
break;
|
|
case p.oids.sha384:
|
|
g = u.md.sha384.create(),
|
|
v = 48;
|
|
break;
|
|
case p.oids.sha512:
|
|
g = u.md.sha512.create(),
|
|
v = 64;
|
|
break;
|
|
case p.oids.md5:
|
|
g = u.md.md5.create(),
|
|
v = 16
|
|
}
|
|
if (null === g)
|
|
throw new Error("PKCS#12 uses unsupported MAC algorithm: " + m);
|
|
var C = new u.util.ByteBuffer(s.macSalt)
|
|
, E = "macIterations"in s ? parseInt(u.util.bytesToHex(s.macIterations), 16) : 1
|
|
, S = f.generateKey(r, C, 3, E, v, g)
|
|
, T = u.hmac.create();
|
|
T.start(g, S),
|
|
T.update(y.value);
|
|
if (T.getMac().getBytes() !== s.macDigest)
|
|
throw new Error("PKCS#12 MAC could not be verified. Invalid password?")
|
|
}
|
|
return i(h, y.value, t, r),
|
|
h
|
|
}
|
|
,
|
|
f.toPkcs12Asn1 = function(e, t, r, a) {
|
|
a = a || {},
|
|
a.saltSize = a.saltSize || 8,
|
|
a.count = a.count || 2048,
|
|
a.algorithm = a.algorithm || a.encAlgorithm || "aes128",
|
|
"useMac"in a || (a.useMac = !0),
|
|
"localKeyId"in a || (a.localKeyId = null),
|
|
"generateLocalKeyId"in a || (a.generateLocalKeyId = !0);
|
|
var n, i = a.localKeyId;
|
|
if (null !== i)
|
|
i = u.util.hexToBytes(i);
|
|
else if (a.generateLocalKeyId)
|
|
if (t) {
|
|
var s = u.util.isArray(t) ? t[0] : t;
|
|
"string" == typeof s && (s = p.certificateFromPem(s));
|
|
var o = u.md.sha1.create();
|
|
o.update(l.toDer(p.certificateToAsn1(s)).getBytes()),
|
|
i = o.digest().getBytes()
|
|
} else
|
|
i = u.random.getBytes(20);
|
|
var c = [];
|
|
null !== i && c.push(l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.OID, !1, l.oidToDer(p.oids.localKeyId).getBytes()), l.create(l.Class.UNIVERSAL, l.Type.SET, !0, [l.create(l.Class.UNIVERSAL, l.Type.OCTETSTRING, !1, i)])])),
|
|
"friendlyName"in a && c.push(l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.OID, !1, l.oidToDer(p.oids.friendlyName).getBytes()), l.create(l.Class.UNIVERSAL, l.Type.SET, !0, [l.create(l.Class.UNIVERSAL, l.Type.BMPSTRING, !1, a.friendlyName)])])),
|
|
c.length > 0 && (n = l.create(l.Class.UNIVERSAL, l.Type.SET, !0, c));
|
|
var h = []
|
|
, d = [];
|
|
null !== t && (d = u.util.isArray(t) ? t : [t]);
|
|
for (var y = [], g = 0; g < d.length; ++g) {
|
|
t = d[g],
|
|
"string" == typeof t && (t = p.certificateFromPem(t));
|
|
var v = 0 === g ? n : void 0
|
|
, m = p.certificateToAsn1(t)
|
|
, C = l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.OID, !1, l.oidToDer(p.oids.certBag).getBytes()), l.create(l.Class.CONTEXT_SPECIFIC, 0, !0, [l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.OID, !1, l.oidToDer(p.oids.x509Certificate).getBytes()), l.create(l.Class.CONTEXT_SPECIFIC, 0, !0, [l.create(l.Class.UNIVERSAL, l.Type.OCTETSTRING, !1, l.toDer(m).getBytes())])])]), v]);
|
|
y.push(C)
|
|
}
|
|
if (y.length > 0) {
|
|
var E = l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, y)
|
|
, S = l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.OID, !1, l.oidToDer(p.oids.data).getBytes()), l.create(l.Class.CONTEXT_SPECIFIC, 0, !0, [l.create(l.Class.UNIVERSAL, l.Type.OCTETSTRING, !1, l.toDer(E).getBytes())])]);
|
|
h.push(S)
|
|
}
|
|
var T = null;
|
|
if (null !== e) {
|
|
var I = p.wrapRsaPrivateKey(p.privateKeyToAsn1(e));
|
|
T = null === r ? l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.OID, !1, l.oidToDer(p.oids.keyBag).getBytes()), l.create(l.Class.CONTEXT_SPECIFIC, 0, !0, [I]), n]) : l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.OID, !1, l.oidToDer(p.oids.pkcs8ShroudedKeyBag).getBytes()), l.create(l.Class.CONTEXT_SPECIFIC, 0, !0, [p.encryptPrivateKeyInfo(I, r, a)]), n]);
|
|
var b = l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [T])
|
|
, A = l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.OID, !1, l.oidToDer(p.oids.data).getBytes()), l.create(l.Class.CONTEXT_SPECIFIC, 0, !0, [l.create(l.Class.UNIVERSAL, l.Type.OCTETSTRING, !1, l.toDer(b).getBytes())])]);
|
|
h.push(A)
|
|
}
|
|
var B, N = l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, h);
|
|
if (a.useMac) {
|
|
var o = u.md.sha1.create()
|
|
, k = new u.util.ByteBuffer(u.random.getBytes(a.saltSize))
|
|
, w = a.count
|
|
, e = f.generateKey(r, k, 3, w, 20)
|
|
, R = u.hmac.create();
|
|
R.start(o, e),
|
|
R.update(l.toDer(N).getBytes());
|
|
var _ = R.getMac();
|
|
B = l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.OID, !1, l.oidToDer(p.oids.sha1).getBytes()), l.create(l.Class.UNIVERSAL, l.Type.NULL, !1, "")]), l.create(l.Class.UNIVERSAL, l.Type.OCTETSTRING, !1, _.getBytes())]), l.create(l.Class.UNIVERSAL, l.Type.OCTETSTRING, !1, k.getBytes()), l.create(l.Class.UNIVERSAL, l.Type.INTEGER, !1, l.integerToDer(w).getBytes())])
|
|
}
|
|
return l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.INTEGER, !1, l.integerToDer(3).getBytes()), l.create(l.Class.UNIVERSAL, l.Type.SEQUENCE, !0, [l.create(l.Class.UNIVERSAL, l.Type.OID, !1, l.oidToDer(p.oids.data).getBytes()), l.create(l.Class.CONTEXT_SPECIFIC, 0, !0, [l.create(l.Class.UNIVERSAL, l.Type.OCTETSTRING, !1, l.toDer(N).getBytes())])]), B])
|
|
}
|
|
,
|
|
f.generateKey = u.pbe.generatePkcs12Key
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(3),
|
|
r(1);
|
|
var n = a.asn1
|
|
, i = e.exports = a.pkcs7asn1 = a.pkcs7asn1 || {};
|
|
a.pkcs7 = a.pkcs7 || {},
|
|
a.pkcs7.asn1 = i;
|
|
var s = {
|
|
name: "ContentInfo",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "ContentInfo.ContentType",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.OID,
|
|
constructed: !1,
|
|
capture: "contentType"
|
|
}, {
|
|
name: "ContentInfo.content",
|
|
tagClass: n.Class.CONTEXT_SPECIFIC,
|
|
type: 0,
|
|
constructed: !0,
|
|
optional: !0,
|
|
captureAsn1: "content"
|
|
}]
|
|
};
|
|
i.contentInfoValidator = s;
|
|
var o = {
|
|
name: "EncryptedContentInfo",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "EncryptedContentInfo.contentType",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.OID,
|
|
constructed: !1,
|
|
capture: "contentType"
|
|
}, {
|
|
name: "EncryptedContentInfo.contentEncryptionAlgorithm",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "EncryptedContentInfo.contentEncryptionAlgorithm.algorithm",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.OID,
|
|
constructed: !1,
|
|
capture: "encAlgorithm"
|
|
}, {
|
|
name: "EncryptedContentInfo.contentEncryptionAlgorithm.parameter",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
captureAsn1: "encParameter"
|
|
}]
|
|
}, {
|
|
name: "EncryptedContentInfo.encryptedContent",
|
|
tagClass: n.Class.CONTEXT_SPECIFIC,
|
|
type: 0,
|
|
capture: "encryptedContent",
|
|
captureAsn1: "encryptedContentAsn1"
|
|
}]
|
|
};
|
|
i.envelopedDataValidator = {
|
|
name: "EnvelopedData",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "EnvelopedData.Version",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "version"
|
|
}, {
|
|
name: "EnvelopedData.RecipientInfos",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SET,
|
|
constructed: !0,
|
|
captureAsn1: "recipientInfos"
|
|
}].concat(o)
|
|
},
|
|
i.encryptedDataValidator = {
|
|
name: "EncryptedData",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "EncryptedData.Version",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "version"
|
|
}].concat(o)
|
|
};
|
|
var c = {
|
|
name: "SignerInfo",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "SignerInfo.version",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.INTEGER,
|
|
constructed: !1
|
|
}, {
|
|
name: "SignerInfo.issuerAndSerialNumber",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "SignerInfo.issuerAndSerialNumber.issuer",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
captureAsn1: "issuer"
|
|
}, {
|
|
name: "SignerInfo.issuerAndSerialNumber.serialNumber",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "serial"
|
|
}]
|
|
}, {
|
|
name: "SignerInfo.digestAlgorithm",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "SignerInfo.digestAlgorithm.algorithm",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.OID,
|
|
constructed: !1,
|
|
capture: "digestAlgorithm"
|
|
}, {
|
|
name: "SignerInfo.digestAlgorithm.parameter",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
constructed: !1,
|
|
captureAsn1: "digestParameter",
|
|
optional: !0
|
|
}]
|
|
}, {
|
|
name: "SignerInfo.authenticatedAttributes",
|
|
tagClass: n.Class.CONTEXT_SPECIFIC,
|
|
type: 0,
|
|
constructed: !0,
|
|
optional: !0,
|
|
capture: "authenticatedAttributes"
|
|
}, {
|
|
name: "SignerInfo.digestEncryptionAlgorithm",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
capture: "signatureAlgorithm"
|
|
}, {
|
|
name: "SignerInfo.encryptedDigest",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.OCTETSTRING,
|
|
constructed: !1,
|
|
capture: "signature"
|
|
}, {
|
|
name: "SignerInfo.unauthenticatedAttributes",
|
|
tagClass: n.Class.CONTEXT_SPECIFIC,
|
|
type: 1,
|
|
constructed: !0,
|
|
optional: !0,
|
|
capture: "unauthenticatedAttributes"
|
|
}]
|
|
};
|
|
i.signedDataValidator = {
|
|
name: "SignedData",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "SignedData.Version",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "version"
|
|
}, {
|
|
name: "SignedData.DigestAlgorithms",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SET,
|
|
constructed: !0,
|
|
captureAsn1: "digestAlgorithms"
|
|
}, s, {
|
|
name: "SignedData.Certificates",
|
|
tagClass: n.Class.CONTEXT_SPECIFIC,
|
|
type: 0,
|
|
optional: !0,
|
|
captureAsn1: "certificates"
|
|
}, {
|
|
name: "SignedData.CertificateRevocationLists",
|
|
tagClass: n.Class.CONTEXT_SPECIFIC,
|
|
type: 1,
|
|
optional: !0,
|
|
captureAsn1: "crls"
|
|
}, {
|
|
name: "SignedData.SignerInfos",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SET,
|
|
capture: "signerInfos",
|
|
optional: !0,
|
|
value: [c]
|
|
}]
|
|
},
|
|
i.recipientInfoValidator = {
|
|
name: "RecipientInfo",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "RecipientInfo.version",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "version"
|
|
}, {
|
|
name: "RecipientInfo.issuerAndSerial",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "RecipientInfo.issuerAndSerial.issuer",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
captureAsn1: "issuer"
|
|
}, {
|
|
name: "RecipientInfo.issuerAndSerial.serialNumber",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.INTEGER,
|
|
constructed: !1,
|
|
capture: "serial"
|
|
}]
|
|
}, {
|
|
name: "RecipientInfo.keyEncryptionAlgorithm",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.SEQUENCE,
|
|
constructed: !0,
|
|
value: [{
|
|
name: "RecipientInfo.keyEncryptionAlgorithm.algorithm",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.OID,
|
|
constructed: !1,
|
|
capture: "encAlgorithm"
|
|
}, {
|
|
name: "RecipientInfo.keyEncryptionAlgorithm.parameter",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
constructed: !1,
|
|
captureAsn1: "encParameter"
|
|
}]
|
|
}, {
|
|
name: "RecipientInfo.encryptedKey",
|
|
tagClass: n.Class.UNIVERSAL,
|
|
type: n.Type.OCTETSTRING,
|
|
constructed: !1,
|
|
capture: "encKey"
|
|
}]
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(1),
|
|
a.mgf = a.mgf || {},
|
|
(e.exports = a.mgf.mgf1 = a.mgf1 = a.mgf1 || {}).create = function(e) {
|
|
return {
|
|
generate: function(t, r) {
|
|
for (var n = new a.util.ByteBuffer, i = Math.ceil(r / e.digestLength), s = 0; s < i; s++) {
|
|
var o = new a.util.ByteBuffer;
|
|
o.putInt32(s),
|
|
e.start(),
|
|
e.update(t + o.getBytes()),
|
|
n.putBuffer(e.digest())
|
|
}
|
|
return n.truncate(n.length() - r),
|
|
n.getBytes()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
e.exports = a.debug = a.debug || {},
|
|
a.debug.storage = {},
|
|
a.debug.get = function(e, t) {
|
|
var r;
|
|
return void 0 === e ? r = a.debug.storage : e in a.debug.storage && (r = void 0 === t ? a.debug.storage[e] : a.debug.storage[e][t]),
|
|
r
|
|
}
|
|
,
|
|
a.debug.set = function(e, t, r) {
|
|
e in a.debug.storage || (a.debug.storage[e] = {}),
|
|
a.debug.storage[e][t] = r
|
|
}
|
|
,
|
|
a.debug.clear = function(e, t) {
|
|
void 0 === e ? a.debug.storage = {} : e in a.debug.storage && (void 0 === t ? delete a.debug.storage[e] : delete a.debug.storage[e][t])
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
function a() {
|
|
c = String.fromCharCode(128),
|
|
c += i.util.fillString(String.fromCharCode(0), 128),
|
|
l = [[1116352408, 3609767458], [1899447441, 602891725], [3049323471, 3964484399], [3921009573, 2173295548], [961987163, 4081628472], [1508970993, 3053834265], [2453635748, 2937671579], [2870763221, 3664609560], [3624381080, 2734883394], [310598401, 1164996542], [607225278, 1323610764], [1426881987, 3590304994], [1925078388, 4068182383], [2162078206, 991336113], [2614888103, 633803317], [3248222580, 3479774868], [3835390401, 2666613458], [4022224774, 944711139], [264347078, 2341262773], [604807628, 2007800933], [770255983, 1495990901], [1249150122, 1856431235], [1555081692, 3175218132], [1996064986, 2198950837], [2554220882, 3999719339], [2821834349, 766784016], [2952996808, 2566594879], [3210313671, 3203337956], [3336571891, 1034457026], [3584528711, 2466948901], [113926993, 3758326383], [338241895, 168717936], [666307205, 1188179964], [773529912, 1546045734], [1294757372, 1522805485], [1396182291, 2643833823], [1695183700, 2343527390], [1986661051, 1014477480], [2177026350, 1206759142], [2456956037, 344077627], [2730485921, 1290863460], [2820302411, 3158454273], [3259730800, 3505952657], [3345764771, 106217008], [3516065817, 3606008344], [3600352804, 1432725776], [4094571909, 1467031594], [275423344, 851169720], [430227734, 3100823752], [506948616, 1363258195], [659060556, 3750685593], [883997877, 3785050280], [958139571, 3318307427], [1322822218, 3812723403], [1537002063, 2003034995], [1747873779, 3602036899], [1955562222, 1575990012], [2024104815, 1125592928], [2227730452, 2716904306], [2361852424, 442776044], [2428436474, 593698344], [2756734187, 3733110249], [3204031479, 2999351573], [3329325298, 3815920427], [3391569614, 3928383900], [3515267271, 566280711], [3940187606, 3454069534], [4118630271, 4000239992], [116418474, 1914138554], [174292421, 2731055270], [289380356, 3203993006], [460393269, 320620315], [685471733, 587496836], [852142971, 1086792851], [1017036298, 365543100], [1126000580, 2618297676], [1288033470, 3409855158], [1501505948, 4234509866], [1607167915, 987167468], [1816402316, 1246189591]],
|
|
p = {},
|
|
p["SHA-512"] = [[1779033703, 4089235720], [3144134277, 2227873595], [1013904242, 4271175723], [2773480762, 1595750129], [1359893119, 2917565137], [2600822924, 725511199], [528734635, 4215389547], [1541459225, 327033209]],
|
|
p["SHA-384"] = [[3418070365, 3238371032], [1654270250, 914150663], [2438529370, 812702999], [355462360, 4144912697], [1731405415, 4290775857], [2394180231, 1750603025], [3675008525, 1694076839], [1203062813, 3204075428]],
|
|
p["SHA-512/256"] = [[573645204, 4230739756], [2673172387, 3360449730], [596883563, 1867755857], [2520282905, 1497426621], [2519219938, 2827943907], [3193839141, 1401305490], [721525244, 746961066], [246885852, 2177182882]],
|
|
p["SHA-512/224"] = [[2352822216, 424955298], [1944164710, 2312950998], [502970286, 855612546], [1738396948, 1479516111], [258812777, 2077511080], [2011393907, 79989058], [1067287976, 1780299464], [286451373, 2446758561]],
|
|
u = !0
|
|
}
|
|
function n(e, t, r) {
|
|
for (var a, n, i, s, o, c, u, p, f, h, d, y, g, v, m, C, E, S, T, I, b, A, B, N, k, w, R, _, L, U, D, P, V, O, K, x = r.length(); x >= 128; ) {
|
|
for (L = 0; L < 16; ++L)
|
|
t[L][0] = r.getInt32() >>> 0,
|
|
t[L][1] = r.getInt32() >>> 0;
|
|
for (; L < 80; ++L)
|
|
P = t[L - 2],
|
|
U = P[0],
|
|
D = P[1],
|
|
a = ((U >>> 19 | D << 13) ^ (D >>> 29 | U << 3) ^ U >>> 6) >>> 0,
|
|
n = ((U << 13 | D >>> 19) ^ (D << 3 | U >>> 29) ^ (U << 26 | D >>> 6)) >>> 0,
|
|
O = t[L - 15],
|
|
U = O[0],
|
|
D = O[1],
|
|
i = ((U >>> 1 | D << 31) ^ (U >>> 8 | D << 24) ^ U >>> 7) >>> 0,
|
|
s = ((U << 31 | D >>> 1) ^ (U << 24 | D >>> 8) ^ (U << 25 | D >>> 7)) >>> 0,
|
|
V = t[L - 7],
|
|
K = t[L - 16],
|
|
D = n + V[1] + s + K[1],
|
|
t[L][0] = a + V[0] + i + K[0] + (D / 4294967296 >>> 0) >>> 0,
|
|
t[L][1] = D >>> 0;
|
|
for (g = e[0][0],
|
|
v = e[0][1],
|
|
m = e[1][0],
|
|
C = e[1][1],
|
|
E = e[2][0],
|
|
S = e[2][1],
|
|
T = e[3][0],
|
|
I = e[3][1],
|
|
b = e[4][0],
|
|
A = e[4][1],
|
|
B = e[5][0],
|
|
N = e[5][1],
|
|
k = e[6][0],
|
|
w = e[6][1],
|
|
R = e[7][0],
|
|
_ = e[7][1],
|
|
L = 0; L < 80; ++L)
|
|
u = ((b >>> 14 | A << 18) ^ (b >>> 18 | A << 14) ^ (A >>> 9 | b << 23)) >>> 0,
|
|
p = ((b << 18 | A >>> 14) ^ (b << 14 | A >>> 18) ^ (A << 23 | b >>> 9)) >>> 0,
|
|
f = (k ^ b & (B ^ k)) >>> 0,
|
|
h = (w ^ A & (N ^ w)) >>> 0,
|
|
o = ((g >>> 28 | v << 4) ^ (v >>> 2 | g << 30) ^ (v >>> 7 | g << 25)) >>> 0,
|
|
c = ((g << 4 | v >>> 28) ^ (v << 30 | g >>> 2) ^ (v << 25 | g >>> 7)) >>> 0,
|
|
d = (g & m | E & (g ^ m)) >>> 0,
|
|
y = (v & C | S & (v ^ C)) >>> 0,
|
|
D = _ + p + h + l[L][1] + t[L][1],
|
|
a = R + u + f + l[L][0] + t[L][0] + (D / 4294967296 >>> 0) >>> 0,
|
|
n = D >>> 0,
|
|
D = c + y,
|
|
i = o + d + (D / 4294967296 >>> 0) >>> 0,
|
|
s = D >>> 0,
|
|
R = k,
|
|
_ = w,
|
|
k = B,
|
|
w = N,
|
|
B = b,
|
|
N = A,
|
|
D = I + n,
|
|
b = T + a + (D / 4294967296 >>> 0) >>> 0,
|
|
A = D >>> 0,
|
|
T = E,
|
|
I = S,
|
|
E = m,
|
|
S = C,
|
|
m = g,
|
|
C = v,
|
|
D = n + s,
|
|
g = a + i + (D / 4294967296 >>> 0) >>> 0,
|
|
v = D >>> 0;
|
|
D = e[0][1] + v,
|
|
e[0][0] = e[0][0] + g + (D / 4294967296 >>> 0) >>> 0,
|
|
e[0][1] = D >>> 0,
|
|
D = e[1][1] + C,
|
|
e[1][0] = e[1][0] + m + (D / 4294967296 >>> 0) >>> 0,
|
|
e[1][1] = D >>> 0,
|
|
D = e[2][1] + S,
|
|
e[2][0] = e[2][0] + E + (D / 4294967296 >>> 0) >>> 0,
|
|
e[2][1] = D >>> 0,
|
|
D = e[3][1] + I,
|
|
e[3][0] = e[3][0] + T + (D / 4294967296 >>> 0) >>> 0,
|
|
e[3][1] = D >>> 0,
|
|
D = e[4][1] + A,
|
|
e[4][0] = e[4][0] + b + (D / 4294967296 >>> 0) >>> 0,
|
|
e[4][1] = D >>> 0,
|
|
D = e[5][1] + N,
|
|
e[5][0] = e[5][0] + B + (D / 4294967296 >>> 0) >>> 0,
|
|
e[5][1] = D >>> 0,
|
|
D = e[6][1] + w,
|
|
e[6][0] = e[6][0] + k + (D / 4294967296 >>> 0) >>> 0,
|
|
e[6][1] = D >>> 0,
|
|
D = e[7][1] + _,
|
|
e[7][0] = e[7][0] + R + (D / 4294967296 >>> 0) >>> 0,
|
|
e[7][1] = D >>> 0,
|
|
x -= 128
|
|
}
|
|
}
|
|
var i = r(0);
|
|
r(4),
|
|
r(1);
|
|
var s = e.exports = i.sha512 = i.sha512 || {};
|
|
i.md.sha512 = i.md.algorithms.sha512 = s;
|
|
var o = i.sha384 = i.sha512.sha384 = i.sha512.sha384 || {};
|
|
o.create = function() {
|
|
return s.create("SHA-384")
|
|
}
|
|
,
|
|
i.md.sha384 = i.md.algorithms.sha384 = o,
|
|
i.sha512.sha256 = i.sha512.sha256 || {
|
|
create: function() {
|
|
return s.create("SHA-512/256")
|
|
}
|
|
},
|
|
i.md["sha512/256"] = i.md.algorithms["sha512/256"] = i.sha512.sha256,
|
|
i.sha512.sha224 = i.sha512.sha224 || {
|
|
create: function() {
|
|
return s.create("SHA-512/224")
|
|
}
|
|
},
|
|
i.md["sha512/224"] = i.md.algorithms["sha512/224"] = i.sha512.sha224,
|
|
s.create = function(e) {
|
|
if (u || a(),
|
|
void 0 === e && (e = "SHA-512"),
|
|
!(e in p))
|
|
throw new Error("Invalid SHA-512 algorithm: " + e);
|
|
for (var t = p[e], r = null, s = i.util.createBuffer(), o = new Array(80), l = 0; l < 80; ++l)
|
|
o[l] = new Array(2);
|
|
var f = 64;
|
|
switch (e) {
|
|
case "SHA-384":
|
|
f = 48;
|
|
break;
|
|
case "SHA-512/256":
|
|
f = 32;
|
|
break;
|
|
case "SHA-512/224":
|
|
f = 28
|
|
}
|
|
var h = {
|
|
algorithm: e.replace("-", "").toLowerCase(),
|
|
blockLength: 128,
|
|
digestLength: f,
|
|
messageLength: 0,
|
|
fullMessageLength: null,
|
|
messageLengthSize: 16
|
|
};
|
|
return h.start = function() {
|
|
h.messageLength = 0,
|
|
h.fullMessageLength = h.messageLength128 = [];
|
|
for (var e = h.messageLengthSize / 4, a = 0; a < e; ++a)
|
|
h.fullMessageLength.push(0);
|
|
s = i.util.createBuffer(),
|
|
r = new Array(t.length);
|
|
for (var a = 0; a < t.length; ++a)
|
|
r[a] = t[a].slice(0);
|
|
return h
|
|
}
|
|
,
|
|
h.start(),
|
|
h.update = function(e, t) {
|
|
"utf8" === t && (e = i.util.encodeUtf8(e));
|
|
var a = e.length;
|
|
h.messageLength += a,
|
|
a = [a / 4294967296 >>> 0, a >>> 0];
|
|
for (var c = h.fullMessageLength.length - 1; c >= 0; --c)
|
|
h.fullMessageLength[c] += a[1],
|
|
a[1] = a[0] + (h.fullMessageLength[c] / 4294967296 >>> 0),
|
|
h.fullMessageLength[c] = h.fullMessageLength[c] >>> 0,
|
|
a[0] = a[1] / 4294967296 >>> 0;
|
|
return s.putBytes(e),
|
|
n(r, o, s),
|
|
(s.read > 2048 || 0 === s.length()) && s.compact(),
|
|
h
|
|
}
|
|
,
|
|
h.digest = function() {
|
|
var t = i.util.createBuffer();
|
|
t.putBytes(s.bytes());
|
|
var a = h.fullMessageLength[h.fullMessageLength.length - 1] + h.messageLengthSize
|
|
, u = a & h.blockLength - 1;
|
|
t.putBytes(c.substr(0, h.blockLength - u));
|
|
for (var l, p, f = 8 * h.fullMessageLength[0], d = 0; d < h.fullMessageLength.length - 1; ++d)
|
|
l = 8 * h.fullMessageLength[d + 1],
|
|
p = l / 4294967296 >>> 0,
|
|
f += p,
|
|
t.putInt32(f >>> 0),
|
|
f = l >>> 0;
|
|
t.putInt32(f);
|
|
for (var y = new Array(r.length), d = 0; d < r.length; ++d)
|
|
y[d] = r[d].slice(0);
|
|
n(y, o, t);
|
|
var g, v = i.util.createBuffer();
|
|
g = "SHA-512" === e ? y.length : "SHA-384" === e ? y.length - 2 : y.length - 4;
|
|
for (var d = 0; d < g; ++d)
|
|
v.putInt32(y[d][0]),
|
|
d === g - 1 && "SHA-512/224" === e || v.putInt32(y[d][1]);
|
|
return v
|
|
}
|
|
,
|
|
h
|
|
}
|
|
;
|
|
var c = null
|
|
, u = !1
|
|
, l = null
|
|
, p = null
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(1),
|
|
e.exports = a.log = a.log || {},
|
|
a.log.levels = ["none", "error", "warning", "info", "debug", "verbose", "max"];
|
|
var n = {}
|
|
, i = []
|
|
, s = null;
|
|
a.log.LEVEL_LOCKED = 2,
|
|
a.log.NO_LEVEL_CHECK = 4,
|
|
a.log.INTERPOLATE = 8;
|
|
for (var o = 0; o < a.log.levels.length; ++o) {
|
|
var c = a.log.levels[o];
|
|
n[c] = {
|
|
index: o,
|
|
name: c.toUpperCase()
|
|
}
|
|
}
|
|
a.log.logMessage = function(e) {
|
|
for (var t = n[e.level].index, r = 0; r < i.length; ++r) {
|
|
var s = i[r];
|
|
if (s.flags & a.log.NO_LEVEL_CHECK)
|
|
s.f(e);
|
|
else {
|
|
t <= n[s.level].index && s.f(s, e)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
a.log.prepareStandard = function(e) {
|
|
"standard"in e || (e.standard = n[e.level].name + " [" + e.category + "] " + e.message)
|
|
}
|
|
,
|
|
a.log.prepareFull = function(e) {
|
|
if (!("full"in e)) {
|
|
var t = [e.message];
|
|
t = t.concat([] || e.arguments),
|
|
e.full = a.util.format.apply(this, t)
|
|
}
|
|
}
|
|
,
|
|
a.log.prepareStandardFull = function(e) {
|
|
"standardFull"in e || (a.log.prepareStandard(e),
|
|
e.standardFull = e.standard)
|
|
}
|
|
;
|
|
for (var u = ["error", "warning", "info", "debug", "verbose"], o = 0; o < u.length; ++o)
|
|
!function(e) {
|
|
a.log[e] = function(t, r) {
|
|
var n = Array.prototype.slice.call(arguments).slice(2)
|
|
, i = {
|
|
timestamp: new Date,
|
|
level: e,
|
|
category: t,
|
|
message: r,
|
|
arguments: n
|
|
};
|
|
a.log.logMessage(i)
|
|
}
|
|
}(u[o]);
|
|
if (a.log.makeLogger = function(e) {
|
|
var t = {
|
|
flags: 0,
|
|
f: e
|
|
};
|
|
return a.log.setLevel(t, "none"),
|
|
t
|
|
}
|
|
,
|
|
a.log.setLevel = function(e, t) {
|
|
var r = !1;
|
|
if (e && !(e.flags & a.log.LEVEL_LOCKED))
|
|
for (var n = 0; n < a.log.levels.length; ++n) {
|
|
var i = a.log.levels[n];
|
|
if (t == i) {
|
|
e.level = t,
|
|
r = !0;
|
|
break
|
|
}
|
|
}
|
|
return r
|
|
}
|
|
,
|
|
a.log.lock = function(e, t) {
|
|
void 0 === t || t ? e.flags |= a.log.LEVEL_LOCKED : e.flags &= ~a.log.LEVEL_LOCKED
|
|
}
|
|
,
|
|
a.log.addLogger = function(e) {
|
|
i.push(e)
|
|
}
|
|
,
|
|
"undefined" != typeof console && "log"in console) {
|
|
var l;
|
|
if (console.error && console.warn && console.info && console.debug) {
|
|
var p = {
|
|
error: console.error,
|
|
warning: console.warn,
|
|
info: console.info,
|
|
debug: console.debug,
|
|
verbose: console.debug
|
|
}
|
|
, f = function(e, t) {
|
|
a.log.prepareStandard(t);
|
|
var r = p[t.level]
|
|
, n = [t.standard];
|
|
n = n.concat(t.arguments.slice()),
|
|
r.apply(console, n)
|
|
};
|
|
l = a.log.makeLogger(f)
|
|
} else {
|
|
var f = function(e, t) {
|
|
a.log.prepareStandardFull(t),
|
|
console.log(t.standardFull)
|
|
};
|
|
l = a.log.makeLogger(f)
|
|
}
|
|
a.log.setLevel(l, "debug"),
|
|
a.log.addLogger(l),
|
|
s = l
|
|
} else
|
|
console = {
|
|
log: function() {}
|
|
};
|
|
if (null !== s) {
|
|
var h = a.util.getQueryVariables();
|
|
if ("console.level"in h && a.log.setLevel(s, h["console.level"].slice(-1)[0]),
|
|
"console.lock"in h) {
|
|
"true" == h["console.lock"].slice(-1)[0] && a.log.lock(s)
|
|
}
|
|
}
|
|
a.log.consoleLogger = s
|
|
}
|
|
, function(e, t, r) {
|
|
e.exports = r(35)
|
|
}
|
|
, function(e, t, r) {
|
|
e.exports = r(0),
|
|
r(5),
|
|
r(38),
|
|
r(3),
|
|
r(13),
|
|
r(31),
|
|
r(10),
|
|
r(40),
|
|
r(8),
|
|
r(41),
|
|
r(33),
|
|
r(42),
|
|
r(30),
|
|
r(15),
|
|
r(7),
|
|
r(26),
|
|
r(28),
|
|
r(43),
|
|
r(21),
|
|
r(27),
|
|
r(24),
|
|
r(18),
|
|
r(2),
|
|
r(25),
|
|
r(44),
|
|
r(45),
|
|
r(20),
|
|
r(1)
|
|
}
|
|
, function(e, t) {
|
|
var r;
|
|
r = function() {
|
|
return this
|
|
}();
|
|
try {
|
|
r = r || Function("return this")() || (0,
|
|
eval)("this")
|
|
} catch (e) {
|
|
"object" == typeof window && (r = window)
|
|
}
|
|
e.exports = r
|
|
}
|
|
, function(e, t) {
|
|
function r(e, t) {
|
|
var r = 0
|
|
, a = t.length
|
|
, n = t.charAt(0)
|
|
, i = [0];
|
|
for (r = 0; r < e.length(); ++r) {
|
|
for (var s = 0, o = e.at(r); s < i.length; ++s)
|
|
o += i[s] << 8,
|
|
i[s] = o % a,
|
|
o = o / a | 0;
|
|
for (; o > 0; )
|
|
i.push(o % a),
|
|
o = o / a | 0
|
|
}
|
|
var c = "";
|
|
for (r = 0; 0 === e.at(r) && r < e.length() - 1; ++r)
|
|
c += n;
|
|
for (r = i.length - 1; r >= 0; --r)
|
|
c += t[i[r]];
|
|
return c
|
|
}
|
|
var a = {};
|
|
e.exports = a;
|
|
var n = {};
|
|
a.encode = function(e, t, a) {
|
|
if ("string" != typeof t)
|
|
throw new TypeError('"alphabet" must be a string.');
|
|
if (void 0 !== a && "number" != typeof a)
|
|
throw new TypeError('"maxline" must be a number.');
|
|
var n = "";
|
|
if (e instanceof Uint8Array) {
|
|
var i = 0
|
|
, s = t.length
|
|
, o = t.charAt(0)
|
|
, c = [0];
|
|
for (i = 0; i < e.length; ++i) {
|
|
for (var u = 0, l = e[i]; u < c.length; ++u)
|
|
l += c[u] << 8,
|
|
c[u] = l % s,
|
|
l = l / s | 0;
|
|
for (; l > 0; )
|
|
c.push(l % s),
|
|
l = l / s | 0
|
|
}
|
|
for (i = 0; 0 === e[i] && i < e.length - 1; ++i)
|
|
n += o;
|
|
for (i = c.length - 1; i >= 0; --i)
|
|
n += t[c[i]]
|
|
} else
|
|
n = r(e, t);
|
|
if (a) {
|
|
var p = new RegExp(".{1," + a + "}","g");
|
|
n = n.match(p).join("\r\n")
|
|
}
|
|
return n
|
|
}
|
|
,
|
|
a.decode = function(e, t) {
|
|
if ("string" != typeof e)
|
|
throw new TypeError('"input" must be a string.');
|
|
if ("string" != typeof t)
|
|
throw new TypeError('"alphabet" must be a string.');
|
|
var r = n[t];
|
|
if (!r) {
|
|
r = n[t] = [];
|
|
for (var a = 0; a < t.length; ++a)
|
|
r[t.charCodeAt(a)] = a
|
|
}
|
|
e = e.replace(/\s/g, "");
|
|
for (var i = t.length, s = t.charAt(0), o = [0], a = 0; a < e.length; a++) {
|
|
var c = r[e.charCodeAt(a)];
|
|
if (void 0 === c)
|
|
return;
|
|
for (var u = 0, l = c; u < o.length; ++u)
|
|
l += o[u] * i,
|
|
o[u] = 255 & l,
|
|
l >>= 8;
|
|
for (; l > 0; )
|
|
o.push(255 & l),
|
|
l >>= 8
|
|
}
|
|
for (var p = 0; e[p] === s && p < e.length - 1; ++p)
|
|
o.push(0);
|
|
return "undefined" != typeof Buffer ? Buffer.from(o.reverse()) : new Uint8Array(o.reverse())
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t, r) {
|
|
var a = t.entity === u.tls.ConnectionEnd.client;
|
|
e.read.cipherState = {
|
|
init: !1,
|
|
cipher: u.cipher.createDecipher("AES-CBC", a ? r.keys.server_write_key : r.keys.client_write_key),
|
|
iv: a ? r.keys.server_write_IV : r.keys.client_write_IV
|
|
},
|
|
e.write.cipherState = {
|
|
init: !1,
|
|
cipher: u.cipher.createCipher("AES-CBC", a ? r.keys.client_write_key : r.keys.server_write_key),
|
|
iv: a ? r.keys.client_write_IV : r.keys.server_write_IV
|
|
},
|
|
e.read.cipherFunction = o,
|
|
e.write.cipherFunction = n,
|
|
e.read.macLength = e.write.macLength = r.mac_length,
|
|
e.read.macFunction = e.write.macFunction = l.hmac_sha1
|
|
}
|
|
function n(e, t) {
|
|
var r = !1
|
|
, a = t.macFunction(t.macKey, t.sequenceNumber, e);
|
|
e.fragment.putBytes(a),
|
|
t.updateSequenceNumber();
|
|
var n;
|
|
n = e.version.minor === l.Versions.TLS_1_0.minor ? t.cipherState.init ? null : t.cipherState.iv : u.random.getBytesSync(16),
|
|
t.cipherState.init = !0;
|
|
var s = t.cipherState.cipher;
|
|
return s.start({
|
|
iv: n
|
|
}),
|
|
e.version.minor >= l.Versions.TLS_1_1.minor && s.output.putBytes(n),
|
|
s.update(e.fragment),
|
|
s.finish(i) && (e.fragment = s.output,
|
|
e.length = e.fragment.length(),
|
|
r = !0),
|
|
r
|
|
}
|
|
function i(e, t, r) {
|
|
if (!r) {
|
|
var a = e - t.length() % e;
|
|
t.fillWithByte(a - 1, a)
|
|
}
|
|
return !0
|
|
}
|
|
function s(e, t, r) {
|
|
var a = !0;
|
|
if (r) {
|
|
for (var n = t.length(), i = t.last(), s = n - 1 - i; s < n - 1; ++s)
|
|
a = a && t.at(s) == i;
|
|
a && t.truncate(i + 1)
|
|
}
|
|
return a
|
|
}
|
|
function o(e, t) {
|
|
var r, a = !1;
|
|
r = e.version.minor === l.Versions.TLS_1_0.minor ? t.cipherState.init ? null : t.cipherState.iv : e.fragment.getBytes(16),
|
|
t.cipherState.init = !0;
|
|
var n = t.cipherState.cipher;
|
|
n.start({
|
|
iv: r
|
|
}),
|
|
n.update(e.fragment),
|
|
a = n.finish(s);
|
|
var i = t.macLength
|
|
, o = u.random.getBytesSync(i)
|
|
, p = n.output.length();
|
|
p >= i ? (e.fragment = n.output.getBytes(p - i),
|
|
o = n.output.getBytes(i)) : e.fragment = n.output.getBytes(),
|
|
e.fragment = u.util.createBuffer(e.fragment),
|
|
e.length = e.fragment.length();
|
|
var f = t.macFunction(t.macKey, t.sequenceNumber, e);
|
|
return t.updateSequenceNumber(),
|
|
a = c(t.macKey, o, f) && a
|
|
}
|
|
function c(e, t, r) {
|
|
var a = u.hmac.create();
|
|
return a.start("SHA1", e),
|
|
a.update(t),
|
|
t = a.digest().getBytes(),
|
|
a.start(null, null),
|
|
a.update(r),
|
|
r = a.digest().getBytes(),
|
|
t === r
|
|
}
|
|
var u = r(0);
|
|
r(5),
|
|
r(20);
|
|
var l = e.exports = u.tls;
|
|
l.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA = {
|
|
id: [0, 47],
|
|
name: "TLS_RSA_WITH_AES_128_CBC_SHA",
|
|
initSecurityParameters: function(e) {
|
|
e.bulk_cipher_algorithm = l.BulkCipherAlgorithm.aes,
|
|
e.cipher_type = l.CipherType.block,
|
|
e.enc_key_length = 16,
|
|
e.block_length = 16,
|
|
e.fixed_iv_length = 16,
|
|
e.record_iv_length = 16,
|
|
e.mac_algorithm = l.MACAlgorithm.hmac_sha1,
|
|
e.mac_length = 20,
|
|
e.mac_key_length = 20
|
|
},
|
|
initConnectionState: a
|
|
},
|
|
l.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA = {
|
|
id: [0, 53],
|
|
name: "TLS_RSA_WITH_AES_256_CBC_SHA",
|
|
initSecurityParameters: function(e) {
|
|
e.bulk_cipher_algorithm = l.BulkCipherAlgorithm.aes,
|
|
e.cipher_type = l.CipherType.block,
|
|
e.enc_key_length = 32,
|
|
e.block_length = 16,
|
|
e.fixed_iv_length = 16,
|
|
e.record_iv_length = 16,
|
|
e.mac_algorithm = l.MACAlgorithm.hmac_sha1,
|
|
e.mac_length = 20,
|
|
e.mac_key_length = 20
|
|
},
|
|
initConnectionState: a
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(30),
|
|
e.exports = a.mgf = a.mgf || {},
|
|
a.mgf.mgf1 = a.mgf1
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e) {
|
|
var t = e.message;
|
|
if (t instanceof Uint8Array)
|
|
return t;
|
|
var r = e.encoding;
|
|
if (void 0 === t) {
|
|
if (!e.md)
|
|
throw new TypeError('"options.message" or "options.md" not specified.');
|
|
t = e.md.digest().getBytes(),
|
|
r = "binary"
|
|
}
|
|
if ("string" == typeof t && !r)
|
|
throw new TypeError('"options.encoding" must be "binary" or "utf8".');
|
|
if ("string" == typeof t) {
|
|
if ("undefined" != typeof Buffer)
|
|
return new Buffer(t,r);
|
|
t = new D(t,r)
|
|
} else if (!(t instanceof D))
|
|
throw new TypeError('"options.message" must be a node.js Buffer, a Uint8Array, a forge ByteBuffer, or a string with "options.encoding" specifying its encoding.');
|
|
for (var a = new P(t.length()), n = 0; n < a.length; ++n)
|
|
a[n] = t.at(n);
|
|
return a
|
|
}
|
|
function n(e, t) {
|
|
var r = L.md.sha512.create()
|
|
, a = new D(e);
|
|
r.update(a.getBytes(t), "binary");
|
|
var n = r.digest().getBytes();
|
|
if ("undefined" != typeof Buffer)
|
|
return new Buffer(n,"binary");
|
|
for (var i = new P(V.constants.HASH_BYTE_LENGTH), s = 0; s < 64; ++s)
|
|
i[s] = n.charCodeAt(s);
|
|
return i
|
|
}
|
|
function i(e, t) {
|
|
var r, a = [N(), N(), N(), N()], i = n(t, 32);
|
|
for (i[0] &= 248,
|
|
i[31] &= 127,
|
|
i[31] |= 64,
|
|
T(a, i),
|
|
f(e, a),
|
|
r = 0; r < 32; ++r)
|
|
t[r + 32] = e[r];
|
|
return 0
|
|
}
|
|
function s(e, t, r, a) {
|
|
var i, s, o = new Float64Array(64), l = [N(), N(), N(), N()], p = n(a, 32);
|
|
p[0] &= 248,
|
|
p[31] &= 127,
|
|
p[31] |= 64;
|
|
var h = r + 64;
|
|
for (i = 0; i < r; ++i)
|
|
e[64 + i] = t[i];
|
|
for (i = 0; i < 32; ++i)
|
|
e[32 + i] = p[32 + i];
|
|
var d = n(e.subarray(32), r + 32);
|
|
for (u(d),
|
|
T(l, d),
|
|
f(e, l),
|
|
i = 32; i < 64; ++i)
|
|
e[i] = a[i];
|
|
var y = n(e, r + 64);
|
|
for (u(y),
|
|
i = 32; i < 64; ++i)
|
|
o[i] = 0;
|
|
for (i = 0; i < 32; ++i)
|
|
o[i] = d[i];
|
|
for (i = 0; i < 32; ++i)
|
|
for (s = 0; s < 32; s++)
|
|
o[i + s] += y[i] * p[s];
|
|
return c(e.subarray(32), o),
|
|
h
|
|
}
|
|
function o(e, t, r, a) {
|
|
var i, s = new P(32), o = [N(), N(), N(), N()], c = [N(), N(), N(), N()];
|
|
if (-1,
|
|
r < 64)
|
|
return -1;
|
|
if (d(c, a))
|
|
return -1;
|
|
for (i = 0; i < r; ++i)
|
|
e[i] = t[i];
|
|
for (i = 0; i < 32; ++i)
|
|
e[i + 32] = a[i];
|
|
var p = n(e, r);
|
|
if (u(p),
|
|
S(o, c, p),
|
|
T(c, t.subarray(32)),
|
|
l(o, c),
|
|
f(s, o),
|
|
r -= 64,
|
|
m(t, 0, s, 0)) {
|
|
for (i = 0; i < r; ++i)
|
|
e[i] = 0;
|
|
return -1
|
|
}
|
|
for (i = 0; i < r; ++i)
|
|
e[i] = t[i + 64];
|
|
return r
|
|
}
|
|
function c(e, t) {
|
|
var r, a, n, i;
|
|
for (a = 63; a >= 32; --a) {
|
|
for (r = 0,
|
|
n = a - 32,
|
|
i = a - 12; n < i; ++n)
|
|
t[n] += r - 16 * t[a] * j[n - (a - 32)],
|
|
r = t[n] + 128 >> 8,
|
|
t[n] -= 256 * r;
|
|
t[n] += r,
|
|
t[a] = 0
|
|
}
|
|
for (r = 0,
|
|
n = 0; n < 32; ++n)
|
|
t[n] += r - (t[31] >> 4) * j[n],
|
|
r = t[n] >> 8,
|
|
t[n] &= 255;
|
|
for (n = 0; n < 32; ++n)
|
|
t[n] -= r * j[n];
|
|
for (a = 0; a < 32; ++a)
|
|
t[a + 1] += t[a] >> 8,
|
|
e[a] = 255 & t[a]
|
|
}
|
|
function u(e) {
|
|
for (var t = new Float64Array(64), r = 0; r < 64; ++r)
|
|
t[r] = e[r],
|
|
e[r] = 0;
|
|
c(e, t)
|
|
}
|
|
function l(e, t) {
|
|
var r = N()
|
|
, a = N()
|
|
, n = N()
|
|
, i = N()
|
|
, s = N()
|
|
, o = N()
|
|
, c = N()
|
|
, u = N()
|
|
, l = N();
|
|
w(r, e[1], e[0]),
|
|
w(l, t[1], t[0]),
|
|
_(r, r, l),
|
|
k(a, e[0], e[1]),
|
|
k(l, t[0], t[1]),
|
|
_(a, a, l),
|
|
_(n, e[3], t[3]),
|
|
_(n, n, M),
|
|
_(i, e[2], t[2]),
|
|
k(i, i, i),
|
|
w(s, a, r),
|
|
w(o, i, n),
|
|
k(c, i, n),
|
|
k(u, a, r),
|
|
_(e[0], s, o),
|
|
_(e[1], u, c),
|
|
_(e[2], c, o),
|
|
_(e[3], s, u)
|
|
}
|
|
function p(e, t, r) {
|
|
for (var a = 0; a < 4; ++a)
|
|
B(e[a], t[a], r)
|
|
}
|
|
function f(e, t) {
|
|
var r = N()
|
|
, a = N()
|
|
, n = N();
|
|
b(n, t[2]),
|
|
_(r, t[0], n),
|
|
_(a, t[1], n),
|
|
h(e, a),
|
|
e[31] ^= E(r) << 7
|
|
}
|
|
function h(e, t) {
|
|
var r, a, n, i = N(), s = N();
|
|
for (r = 0; r < 16; ++r)
|
|
s[r] = t[r];
|
|
for (A(s),
|
|
A(s),
|
|
A(s),
|
|
a = 0; a < 2; ++a) {
|
|
for (i[0] = s[0] - 65517,
|
|
r = 1; r < 15; ++r)
|
|
i[r] = s[r] - 65535 - (i[r - 1] >> 16 & 1),
|
|
i[r - 1] &= 65535;
|
|
i[15] = s[15] - 32767 - (i[14] >> 16 & 1),
|
|
n = i[15] >> 16 & 1,
|
|
i[14] &= 65535,
|
|
B(s, i, 1 - n)
|
|
}
|
|
for (r = 0; r < 16; r++)
|
|
e[2 * r] = 255 & s[r],
|
|
e[2 * r + 1] = s[r] >> 8
|
|
}
|
|
function d(e, t) {
|
|
var r = N()
|
|
, a = N()
|
|
, n = N()
|
|
, i = N()
|
|
, s = N()
|
|
, o = N()
|
|
, c = N();
|
|
return I(e[2], K),
|
|
y(e[1], t),
|
|
R(n, e[1]),
|
|
_(i, n, x),
|
|
w(n, n, e[2]),
|
|
k(i, e[2], i),
|
|
R(s, i),
|
|
R(o, s),
|
|
_(c, o, s),
|
|
_(r, c, n),
|
|
_(r, r, i),
|
|
g(r, r),
|
|
_(r, r, n),
|
|
_(r, r, i),
|
|
_(r, r, i),
|
|
_(e[0], r, i),
|
|
R(a, e[0]),
|
|
_(a, a, i),
|
|
v(a, n) && _(e[0], e[0], G),
|
|
R(a, e[0]),
|
|
_(a, a, i),
|
|
v(a, n) ? -1 : (E(e[0]) === t[31] >> 7 && w(e[0], O, e[0]),
|
|
_(e[3], e[0], e[1]),
|
|
0)
|
|
}
|
|
function y(e, t) {
|
|
var r;
|
|
for (r = 0; r < 16; ++r)
|
|
e[r] = t[2 * r] + (t[2 * r + 1] << 8);
|
|
e[15] &= 32767
|
|
}
|
|
function g(e, t) {
|
|
var r, a = N();
|
|
for (r = 0; r < 16; ++r)
|
|
a[r] = t[r];
|
|
for (r = 250; r >= 0; --r)
|
|
R(a, a),
|
|
1 !== r && _(a, a, t);
|
|
for (r = 0; r < 16; ++r)
|
|
e[r] = a[r]
|
|
}
|
|
function v(e, t) {
|
|
var r = new P(32)
|
|
, a = new P(32);
|
|
return h(r, e),
|
|
h(a, t),
|
|
m(r, 0, a, 0)
|
|
}
|
|
function m(e, t, r, a) {
|
|
return C(e, t, r, a, 32)
|
|
}
|
|
function C(e, t, r, a, n) {
|
|
var i, s = 0;
|
|
for (i = 0; i < n; ++i)
|
|
s |= e[t + i] ^ r[a + i];
|
|
return (1 & s - 1 >>> 8) - 1
|
|
}
|
|
function E(e) {
|
|
var t = new P(32);
|
|
return h(t, e),
|
|
1 & t[0]
|
|
}
|
|
function S(e, t, r) {
|
|
var a, n;
|
|
for (I(e[0], O),
|
|
I(e[1], K),
|
|
I(e[2], K),
|
|
I(e[3], O),
|
|
n = 255; n >= 0; --n)
|
|
a = r[n / 8 | 0] >> (7 & n) & 1,
|
|
p(e, t, a),
|
|
l(t, e),
|
|
l(e, e),
|
|
p(e, t, a)
|
|
}
|
|
function T(e, t) {
|
|
var r = [N(), N(), N(), N()];
|
|
I(r[0], F),
|
|
I(r[1], q),
|
|
I(r[2], K),
|
|
_(r[3], F, q),
|
|
S(e, r, t)
|
|
}
|
|
function I(e, t) {
|
|
var r;
|
|
for (r = 0; r < 16; r++)
|
|
e[r] = 0 | t[r]
|
|
}
|
|
function b(e, t) {
|
|
var r, a = N();
|
|
for (r = 0; r < 16; ++r)
|
|
a[r] = t[r];
|
|
for (r = 253; r >= 0; --r)
|
|
R(a, a),
|
|
2 !== r && 4 !== r && _(a, a, t);
|
|
for (r = 0; r < 16; ++r)
|
|
e[r] = a[r]
|
|
}
|
|
function A(e) {
|
|
var t, r, a = 1;
|
|
for (t = 0; t < 16; ++t)
|
|
r = e[t] + a + 65535,
|
|
a = Math.floor(r / 65536),
|
|
e[t] = r - 65536 * a;
|
|
e[0] += a - 1 + 37 * (a - 1)
|
|
}
|
|
function B(e, t, r) {
|
|
for (var a, n = ~(r - 1), i = 0; i < 16; ++i)
|
|
a = n & (e[i] ^ t[i]),
|
|
e[i] ^= a,
|
|
t[i] ^= a
|
|
}
|
|
function N(e) {
|
|
var t, r = new Float64Array(16);
|
|
if (e)
|
|
for (t = 0; t < e.length; ++t)
|
|
r[t] = e[t];
|
|
return r
|
|
}
|
|
function k(e, t, r) {
|
|
for (var a = 0; a < 16; ++a)
|
|
e[a] = t[a] + r[a]
|
|
}
|
|
function w(e, t, r) {
|
|
for (var a = 0; a < 16; ++a)
|
|
e[a] = t[a] - r[a]
|
|
}
|
|
function R(e, t) {
|
|
_(e, t, t)
|
|
}
|
|
function _(e, t, r) {
|
|
var a, n, i = 0, s = 0, o = 0, c = 0, u = 0, l = 0, p = 0, f = 0, h = 0, d = 0, y = 0, g = 0, v = 0, m = 0, C = 0, E = 0, S = 0, T = 0, I = 0, b = 0, A = 0, B = 0, N = 0, k = 0, w = 0, R = 0, _ = 0, L = 0, U = 0, D = 0, P = 0, V = r[0], O = r[1], K = r[2], x = r[3], M = r[4], F = r[5], q = r[6], j = r[7], G = r[8], H = r[9], Q = r[10], z = r[11], W = r[12], Y = r[13], X = r[14], Z = r[15];
|
|
a = t[0],
|
|
i += a * V,
|
|
s += a * O,
|
|
o += a * K,
|
|
c += a * x,
|
|
u += a * M,
|
|
l += a * F,
|
|
p += a * q,
|
|
f += a * j,
|
|
h += a * G,
|
|
d += a * H,
|
|
y += a * Q,
|
|
g += a * z,
|
|
v += a * W,
|
|
m += a * Y,
|
|
C += a * X,
|
|
E += a * Z,
|
|
a = t[1],
|
|
s += a * V,
|
|
o += a * O,
|
|
c += a * K,
|
|
u += a * x,
|
|
l += a * M,
|
|
p += a * F,
|
|
f += a * q,
|
|
h += a * j,
|
|
d += a * G,
|
|
y += a * H,
|
|
g += a * Q,
|
|
v += a * z,
|
|
m += a * W,
|
|
C += a * Y,
|
|
E += a * X,
|
|
S += a * Z,
|
|
a = t[2],
|
|
o += a * V,
|
|
c += a * O,
|
|
u += a * K,
|
|
l += a * x,
|
|
p += a * M,
|
|
f += a * F,
|
|
h += a * q,
|
|
d += a * j,
|
|
y += a * G,
|
|
g += a * H,
|
|
v += a * Q,
|
|
m += a * z,
|
|
C += a * W,
|
|
E += a * Y,
|
|
S += a * X,
|
|
T += a * Z,
|
|
a = t[3],
|
|
c += a * V,
|
|
u += a * O,
|
|
l += a * K,
|
|
p += a * x,
|
|
f += a * M,
|
|
h += a * F,
|
|
d += a * q,
|
|
y += a * j,
|
|
g += a * G,
|
|
v += a * H,
|
|
m += a * Q,
|
|
C += a * z,
|
|
E += a * W,
|
|
S += a * Y,
|
|
T += a * X,
|
|
I += a * Z,
|
|
a = t[4],
|
|
u += a * V,
|
|
l += a * O,
|
|
p += a * K,
|
|
f += a * x,
|
|
h += a * M,
|
|
d += a * F,
|
|
y += a * q,
|
|
g += a * j,
|
|
v += a * G,
|
|
m += a * H,
|
|
C += a * Q,
|
|
E += a * z,
|
|
S += a * W,
|
|
T += a * Y,
|
|
I += a * X,
|
|
b += a * Z,
|
|
a = t[5],
|
|
l += a * V,
|
|
p += a * O,
|
|
f += a * K,
|
|
h += a * x,
|
|
d += a * M,
|
|
y += a * F,
|
|
g += a * q,
|
|
v += a * j,
|
|
m += a * G,
|
|
C += a * H,
|
|
E += a * Q,
|
|
S += a * z,
|
|
T += a * W,
|
|
I += a * Y,
|
|
b += a * X,
|
|
A += a * Z,
|
|
a = t[6],
|
|
p += a * V,
|
|
f += a * O,
|
|
h += a * K,
|
|
d += a * x,
|
|
y += a * M,
|
|
g += a * F,
|
|
v += a * q,
|
|
m += a * j,
|
|
C += a * G,
|
|
E += a * H,
|
|
S += a * Q,
|
|
T += a * z,
|
|
I += a * W,
|
|
b += a * Y,
|
|
A += a * X,
|
|
B += a * Z,
|
|
a = t[7],
|
|
f += a * V,
|
|
h += a * O,
|
|
d += a * K,
|
|
y += a * x,
|
|
g += a * M,
|
|
v += a * F,
|
|
m += a * q,
|
|
C += a * j,
|
|
E += a * G,
|
|
S += a * H,
|
|
T += a * Q,
|
|
I += a * z,
|
|
b += a * W,
|
|
A += a * Y,
|
|
B += a * X,
|
|
N += a * Z,
|
|
a = t[8],
|
|
h += a * V,
|
|
d += a * O,
|
|
y += a * K,
|
|
g += a * x,
|
|
v += a * M,
|
|
m += a * F,
|
|
C += a * q,
|
|
E += a * j,
|
|
S += a * G,
|
|
T += a * H,
|
|
I += a * Q,
|
|
b += a * z,
|
|
A += a * W,
|
|
B += a * Y,
|
|
N += a * X,
|
|
k += a * Z,
|
|
a = t[9],
|
|
d += a * V,
|
|
y += a * O,
|
|
g += a * K,
|
|
v += a * x,
|
|
m += a * M,
|
|
C += a * F,
|
|
E += a * q,
|
|
S += a * j,
|
|
T += a * G,
|
|
I += a * H,
|
|
b += a * Q,
|
|
A += a * z,
|
|
B += a * W,
|
|
N += a * Y,
|
|
k += a * X,
|
|
w += a * Z,
|
|
a = t[10],
|
|
y += a * V,
|
|
g += a * O,
|
|
v += a * K,
|
|
m += a * x,
|
|
C += a * M,
|
|
E += a * F,
|
|
S += a * q,
|
|
T += a * j,
|
|
I += a * G,
|
|
b += a * H,
|
|
A += a * Q,
|
|
B += a * z,
|
|
N += a * W,
|
|
k += a * Y,
|
|
w += a * X,
|
|
R += a * Z,
|
|
a = t[11],
|
|
g += a * V,
|
|
v += a * O,
|
|
m += a * K,
|
|
C += a * x,
|
|
E += a * M,
|
|
S += a * F,
|
|
T += a * q,
|
|
I += a * j,
|
|
b += a * G,
|
|
A += a * H,
|
|
B += a * Q,
|
|
N += a * z;
|
|
k += a * W,
|
|
w += a * Y,
|
|
R += a * X,
|
|
_ += a * Z,
|
|
a = t[12],
|
|
v += a * V,
|
|
m += a * O,
|
|
C += a * K,
|
|
E += a * x,
|
|
S += a * M,
|
|
T += a * F,
|
|
I += a * q,
|
|
b += a * j,
|
|
A += a * G,
|
|
B += a * H,
|
|
N += a * Q,
|
|
k += a * z,
|
|
w += a * W,
|
|
R += a * Y,
|
|
_ += a * X,
|
|
L += a * Z,
|
|
a = t[13],
|
|
m += a * V,
|
|
C += a * O,
|
|
E += a * K,
|
|
S += a * x,
|
|
T += a * M,
|
|
I += a * F,
|
|
b += a * q,
|
|
A += a * j,
|
|
B += a * G,
|
|
N += a * H,
|
|
k += a * Q,
|
|
w += a * z,
|
|
R += a * W,
|
|
_ += a * Y,
|
|
L += a * X,
|
|
U += a * Z,
|
|
a = t[14],
|
|
C += a * V,
|
|
E += a * O,
|
|
S += a * K,
|
|
T += a * x,
|
|
I += a * M,
|
|
b += a * F,
|
|
A += a * q,
|
|
B += a * j,
|
|
N += a * G,
|
|
k += a * H,
|
|
w += a * Q,
|
|
R += a * z,
|
|
_ += a * W,
|
|
L += a * Y,
|
|
U += a * X,
|
|
D += a * Z,
|
|
a = t[15],
|
|
E += a * V,
|
|
S += a * O,
|
|
T += a * K,
|
|
I += a * x,
|
|
b += a * M,
|
|
A += a * F,
|
|
B += a * q,
|
|
N += a * j,
|
|
k += a * G,
|
|
w += a * H,
|
|
R += a * Q,
|
|
_ += a * z,
|
|
L += a * W,
|
|
U += a * Y,
|
|
D += a * X,
|
|
P += a * Z,
|
|
i += 38 * S,
|
|
s += 38 * T,
|
|
o += 38 * I,
|
|
c += 38 * b,
|
|
u += 38 * A,
|
|
l += 38 * B,
|
|
p += 38 * N,
|
|
f += 38 * k,
|
|
h += 38 * w,
|
|
d += 38 * R,
|
|
y += 38 * _,
|
|
g += 38 * L,
|
|
v += 38 * U,
|
|
m += 38 * D,
|
|
C += 38 * P,
|
|
n = 1,
|
|
a = i + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
i = a - 65536 * n,
|
|
a = s + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
s = a - 65536 * n,
|
|
a = o + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
o = a - 65536 * n,
|
|
a = c + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
c = a - 65536 * n,
|
|
a = u + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
u = a - 65536 * n,
|
|
a = l + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
l = a - 65536 * n,
|
|
a = p + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
p = a - 65536 * n,
|
|
a = f + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
f = a - 65536 * n,
|
|
a = h + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
h = a - 65536 * n,
|
|
a = d + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
d = a - 65536 * n,
|
|
a = y + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
y = a - 65536 * n,
|
|
a = g + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
g = a - 65536 * n,
|
|
a = v + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
v = a - 65536 * n,
|
|
a = m + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
m = a - 65536 * n,
|
|
a = C + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
C = a - 65536 * n,
|
|
a = E + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
E = a - 65536 * n,
|
|
i += n - 1 + 37 * (n - 1),
|
|
n = 1,
|
|
a = i + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
i = a - 65536 * n,
|
|
a = s + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
s = a - 65536 * n,
|
|
a = o + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
o = a - 65536 * n,
|
|
a = c + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
c = a - 65536 * n,
|
|
a = u + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
u = a - 65536 * n,
|
|
a = l + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
l = a - 65536 * n,
|
|
a = p + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
p = a - 65536 * n,
|
|
a = f + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
f = a - 65536 * n,
|
|
a = h + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
h = a - 65536 * n,
|
|
a = d + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
d = a - 65536 * n,
|
|
a = y + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
y = a - 65536 * n,
|
|
a = g + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
g = a - 65536 * n,
|
|
a = v + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
v = a - 65536 * n,
|
|
a = m + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
m = a - 65536 * n,
|
|
a = C + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
C = a - 65536 * n,
|
|
a = E + n + 65535,
|
|
n = Math.floor(a / 65536),
|
|
E = a - 65536 * n,
|
|
i += n - 1 + 37 * (n - 1),
|
|
e[0] = i,
|
|
e[1] = s,
|
|
e[2] = o,
|
|
e[3] = c,
|
|
e[4] = u,
|
|
e[5] = l,
|
|
e[6] = p,
|
|
e[7] = f,
|
|
e[8] = h,
|
|
e[9] = d,
|
|
e[10] = y,
|
|
e[11] = g,
|
|
e[12] = v;
|
|
e[13] = m,
|
|
e[14] = C,
|
|
e[15] = E
|
|
}
|
|
var L = r(0);
|
|
if (r(12),
|
|
r(2),
|
|
r(32),
|
|
r(1),
|
|
void 0 === U)
|
|
var U = L.jsbn.BigInteger;
|
|
var D = L.util.ByteBuffer
|
|
, P = "undefined" == typeof Buffer ? Uint8Array : Buffer;
|
|
L.pki = L.pki || {},
|
|
e.exports = L.pki.ed25519 = L.ed25519 = L.ed25519 || {};
|
|
var V = L.ed25519;
|
|
V.constants = {},
|
|
V.constants.PUBLIC_KEY_BYTE_LENGTH = 32,
|
|
V.constants.PRIVATE_KEY_BYTE_LENGTH = 64,
|
|
V.constants.SEED_BYTE_LENGTH = 32,
|
|
V.constants.SIGN_BYTE_LENGTH = 64,
|
|
V.constants.HASH_BYTE_LENGTH = 64,
|
|
V.generateKeyPair = function(e) {
|
|
e = e || {};
|
|
var t = e.seed;
|
|
if (void 0 === t)
|
|
t = L.random.getBytesSync(V.constants.SEED_BYTE_LENGTH);
|
|
else if ("string" == typeof t) {
|
|
if (t.length !== V.constants.SEED_BYTE_LENGTH)
|
|
throw new TypeError('"seed" must be ' + V.constants.SEED_BYTE_LENGTH + " bytes in length.")
|
|
} else if (!(t instanceof Uint8Array))
|
|
throw new TypeError('"seed" must be a node.js Buffer, Uint8Array, or a binary string.');
|
|
t = a({
|
|
message: t,
|
|
encoding: "binary"
|
|
});
|
|
for (var r = new P(V.constants.PUBLIC_KEY_BYTE_LENGTH), n = new P(V.constants.PRIVATE_KEY_BYTE_LENGTH), s = 0; s < 32; ++s)
|
|
n[s] = t[s];
|
|
return i(r, n),
|
|
{
|
|
publicKey: r,
|
|
privateKey: n
|
|
}
|
|
}
|
|
,
|
|
V.publicKeyFromPrivateKey = function(e) {
|
|
e = e || {};
|
|
var t = a({
|
|
message: e.privateKey,
|
|
encoding: "binary"
|
|
});
|
|
if (t.length !== V.constants.PRIVATE_KEY_BYTE_LENGTH)
|
|
throw new TypeError('"options.privateKey" must have a byte length of ' + V.constants.PRIVATE_KEY_BYTE_LENGTH);
|
|
for (var r = new P(V.constants.PUBLIC_KEY_BYTE_LENGTH), n = 0; n < r.length; ++n)
|
|
r[n] = t[32 + n];
|
|
return r
|
|
}
|
|
,
|
|
V.sign = function(e) {
|
|
e = e || {};
|
|
var t = a(e)
|
|
, r = a({
|
|
message: e.privateKey,
|
|
encoding: "binary"
|
|
});
|
|
if (r.length !== V.constants.PRIVATE_KEY_BYTE_LENGTH)
|
|
throw new TypeError('"options.privateKey" must have a byte length of ' + V.constants.PRIVATE_KEY_BYTE_LENGTH);
|
|
var n = new P(V.constants.SIGN_BYTE_LENGTH + t.length);
|
|
s(n, t, t.length, r);
|
|
for (var i = new P(V.constants.SIGN_BYTE_LENGTH), o = 0; o < i.length; ++o)
|
|
i[o] = n[o];
|
|
return i
|
|
}
|
|
,
|
|
V.verify = function(e) {
|
|
e = e || {};
|
|
var t = a(e);
|
|
if (void 0 === e.signature)
|
|
throw new TypeError('"options.signature" must be a node.js Buffer, a Uint8Array, a forge ByteBuffer, or a binary string.');
|
|
var r = a({
|
|
message: e.signature,
|
|
encoding: "binary"
|
|
});
|
|
if (r.length !== V.constants.SIGN_BYTE_LENGTH)
|
|
throw new TypeError('"options.signature" must have a byte length of ' + V.constants.SIGN_BYTE_LENGTH);
|
|
var n = a({
|
|
message: e.publicKey,
|
|
encoding: "binary"
|
|
});
|
|
if (n.length !== V.constants.PUBLIC_KEY_BYTE_LENGTH)
|
|
throw new TypeError('"options.publicKey" must have a byte length of ' + V.constants.PUBLIC_KEY_BYTE_LENGTH);
|
|
var i, s = new P(V.constants.SIGN_BYTE_LENGTH + t.length), c = new P(V.constants.SIGN_BYTE_LENGTH + t.length);
|
|
for (i = 0; i < V.constants.SIGN_BYTE_LENGTH; ++i)
|
|
s[i] = r[i];
|
|
for (i = 0; i < t.length; ++i)
|
|
s[i + V.constants.SIGN_BYTE_LENGTH] = t[i];
|
|
return o(c, s, s.length, n) >= 0
|
|
}
|
|
;
|
|
var O = N()
|
|
, K = N([1])
|
|
, x = N([30883, 4953, 19914, 30187, 55467, 16705, 2637, 112, 59544, 30585, 16505, 36039, 65139, 11119, 27886, 20995])
|
|
, M = N([61785, 9906, 39828, 60374, 45398, 33411, 5274, 224, 53552, 61171, 33010, 6542, 64743, 22239, 55772, 9222])
|
|
, F = N([54554, 36645, 11616, 51542, 42930, 38181, 51040, 26924, 56412, 64982, 57905, 49316, 21502, 52590, 14035, 8553])
|
|
, q = N([26200, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214])
|
|
, j = new Float64Array([237, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16])
|
|
, G = N([41136, 18958, 6951, 50414, 58488, 44335, 6150, 12099, 55207, 15867, 153, 11085, 57099, 20417, 9344, 11139])
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t, r, a) {
|
|
e.generate = function(e, i) {
|
|
for (var s = new n.util.ByteBuffer, o = Math.ceil(i / a) + r, c = new n.util.ByteBuffer, u = r; u < o; ++u) {
|
|
c.putInt32(u),
|
|
t.start(),
|
|
t.update(e + c.getBytes());
|
|
var l = t.digest();
|
|
s.putBytes(l.getBytes(a))
|
|
}
|
|
return s.truncate(s.length() - i),
|
|
s.getBytes()
|
|
}
|
|
}
|
|
var n = r(0);
|
|
r(1),
|
|
r(2),
|
|
r(12),
|
|
e.exports = n.kem = n.kem || {};
|
|
var i = n.jsbn.BigInteger;
|
|
n.kem.rsa = {},
|
|
n.kem.rsa.create = function(e, t) {
|
|
t = t || {};
|
|
var r = t.prng || n.random
|
|
, a = {};
|
|
return a.encrypt = function(t, a) {
|
|
var s, o = Math.ceil(t.n.bitLength() / 8);
|
|
do {
|
|
s = new i(n.util.bytesToHex(r.getBytesSync(o)),16).mod(t.n)
|
|
} while (s.compareTo(i.ONE) <= 0);
|
|
s = n.util.hexToBytes(s.toString(16));
|
|
var c = o - s.length;
|
|
return c > 0 && (s = n.util.fillString(String.fromCharCode(0), c) + s),
|
|
{
|
|
encapsulation: t.encrypt(s, "NONE"),
|
|
key: e.generate(s, a)
|
|
}
|
|
}
|
|
,
|
|
a.decrypt = function(t, r, a) {
|
|
var n = t.decrypt(r, "NONE");
|
|
return e.generate(n, a)
|
|
}
|
|
,
|
|
a
|
|
}
|
|
,
|
|
n.kem.kdf1 = function(e, t) {
|
|
a(this, e, 0, t || e.digestLength)
|
|
}
|
|
,
|
|
n.kem.kdf2 = function(e, t) {
|
|
a(this, e, 1, t || e.digestLength)
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
e.exports = r(4),
|
|
r(14),
|
|
r(9),
|
|
r(23),
|
|
r(32)
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e) {
|
|
var t = {}
|
|
, r = [];
|
|
if (!d.validate(e, y.asn1.recipientInfoValidator, t, r)) {
|
|
var a = new Error("Cannot read PKCS#7 RecipientInfo. ASN.1 object is not an PKCS#7 RecipientInfo.");
|
|
throw a.errors = r,
|
|
a
|
|
}
|
|
return {
|
|
version: t.version.charCodeAt(0),
|
|
issuer: h.pki.RDNAttributesAsArray(t.issuer),
|
|
serialNumber: h.util.createBuffer(t.serial).toHex(),
|
|
encryptedContent: {
|
|
algorithm: d.derToOid(t.encAlgorithm),
|
|
parameter: t.encParameter.value,
|
|
content: t.encKey
|
|
}
|
|
}
|
|
}
|
|
function n(e) {
|
|
return d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.INTEGER, !1, d.integerToDer(e.version).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [h.pki.distinguishedNameToAsn1({
|
|
attributes: e.issuer
|
|
}), d.create(d.Class.UNIVERSAL, d.Type.INTEGER, !1, h.util.hexToBytes(e.serialNumber))]), d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(e.encryptedContent.algorithm).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.NULL, !1, "")]), d.create(d.Class.UNIVERSAL, d.Type.OCTETSTRING, !1, e.encryptedContent.content)])
|
|
}
|
|
function i(e) {
|
|
for (var t = [], r = 0; r < e.length; ++r)
|
|
t.push(a(e[r]));
|
|
return t
|
|
}
|
|
function s(e) {
|
|
for (var t = [], r = 0; r < e.length; ++r)
|
|
t.push(n(e[r]));
|
|
return t
|
|
}
|
|
function o(e) {
|
|
var t = d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.INTEGER, !1, d.integerToDer(e.version).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [h.pki.distinguishedNameToAsn1({
|
|
attributes: e.issuer
|
|
}), d.create(d.Class.UNIVERSAL, d.Type.INTEGER, !1, h.util.hexToBytes(e.serialNumber))]), d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(e.digestAlgorithm).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.NULL, !1, "")])]);
|
|
if (e.authenticatedAttributesAsn1 && t.value.push(e.authenticatedAttributesAsn1),
|
|
t.value.push(d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(e.signatureAlgorithm).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.NULL, !1, "")])),
|
|
t.value.push(d.create(d.Class.UNIVERSAL, d.Type.OCTETSTRING, !1, e.signature)),
|
|
e.unauthenticatedAttributes.length > 0) {
|
|
for (var r = d.create(d.Class.CONTEXT_SPECIFIC, 1, !0, []), a = 0; a < e.unauthenticatedAttributes.length; ++a) {
|
|
var n = e.unauthenticatedAttributes[a];
|
|
r.values.push(u(n))
|
|
}
|
|
t.value.push(r)
|
|
}
|
|
return t
|
|
}
|
|
function c(e) {
|
|
for (var t = [], r = 0; r < e.length; ++r)
|
|
t.push(o(e[r]));
|
|
return t
|
|
}
|
|
function u(e) {
|
|
var t;
|
|
if (e.type === h.pki.oids.contentType)
|
|
t = d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(e.value).getBytes());
|
|
else if (e.type === h.pki.oids.messageDigest)
|
|
t = d.create(d.Class.UNIVERSAL, d.Type.OCTETSTRING, !1, e.value.bytes());
|
|
else if (e.type === h.pki.oids.signingTime) {
|
|
var r = new Date("1950-01-01T00:00:00Z")
|
|
, a = new Date("2050-01-01T00:00:00Z")
|
|
, n = e.value;
|
|
if ("string" == typeof n) {
|
|
var i = Date.parse(n);
|
|
n = isNaN(i) ? 13 === n.length ? d.utcTimeToDate(n) : d.generalizedTimeToDate(n) : new Date(i)
|
|
}
|
|
t = n >= r && n < a ? d.create(d.Class.UNIVERSAL, d.Type.UTCTIME, !1, d.dateToUtcTime(n)) : d.create(d.Class.UNIVERSAL, d.Type.GENERALIZEDTIME, !1, d.dateToGeneralizedTime(n))
|
|
}
|
|
return d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(e.type).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.SET, !0, [t])])
|
|
}
|
|
function l(e) {
|
|
return [d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(h.pki.oids.data).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(e.algorithm).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.OCTETSTRING, !1, e.parameter.getBytes())]), d.create(d.Class.CONTEXT_SPECIFIC, 0, !0, [d.create(d.Class.UNIVERSAL, d.Type.OCTETSTRING, !1, e.content.getBytes())])]
|
|
}
|
|
function p(e, t, r) {
|
|
var a = {}
|
|
, n = [];
|
|
if (!d.validate(t, r, a, n)) {
|
|
var i = new Error("Cannot read PKCS#7 message. ASN.1 object is not a supported PKCS#7 message.");
|
|
throw i.errors = i,
|
|
i
|
|
}
|
|
if (d.derToOid(a.contentType) !== h.pki.oids.data)
|
|
throw new Error("Unsupported PKCS#7 message. Only wrapped ContentType Data supported.");
|
|
if (a.encryptedContent) {
|
|
var s = "";
|
|
if (h.util.isArray(a.encryptedContent))
|
|
for (var o = 0; o < a.encryptedContent.length; ++o) {
|
|
if (a.encryptedContent[o].type !== d.Type.OCTETSTRING)
|
|
throw new Error("Malformed PKCS#7 message, expecting encrypted content constructed of only OCTET STRING objects.");
|
|
s += a.encryptedContent[o].value
|
|
}
|
|
else
|
|
s = a.encryptedContent;
|
|
e.encryptedContent = {
|
|
algorithm: d.derToOid(a.encAlgorithm),
|
|
parameter: h.util.createBuffer(a.encParameter.value),
|
|
content: h.util.createBuffer(s)
|
|
}
|
|
}
|
|
if (a.content) {
|
|
var s = "";
|
|
if (h.util.isArray(a.content))
|
|
for (var o = 0; o < a.content.length; ++o) {
|
|
if (a.content[o].type !== d.Type.OCTETSTRING)
|
|
throw new Error("Malformed PKCS#7 message, expecting content constructed of only OCTET STRING objects.");
|
|
s += a.content[o].value
|
|
}
|
|
else
|
|
s = a.content;
|
|
e.content = h.util.createBuffer(s)
|
|
}
|
|
return e.version = a.version.charCodeAt(0),
|
|
e.rawCapture = a,
|
|
a
|
|
}
|
|
function f(e) {
|
|
if (void 0 === e.encryptedContent.key)
|
|
throw new Error("Symmetric key not available.");
|
|
if (void 0 === e.content) {
|
|
var t;
|
|
switch (e.encryptedContent.algorithm) {
|
|
case h.pki.oids["aes128-CBC"]:
|
|
case h.pki.oids["aes192-CBC"]:
|
|
case h.pki.oids["aes256-CBC"]:
|
|
t = h.aes.createDecryptionCipher(e.encryptedContent.key);
|
|
break;
|
|
case h.pki.oids.desCBC:
|
|
case h.pki.oids["des-EDE3-CBC"]:
|
|
t = h.des.createDecryptionCipher(e.encryptedContent.key);
|
|
break;
|
|
default:
|
|
throw new Error("Unsupported symmetric cipher, OID " + e.encryptedContent.algorithm)
|
|
}
|
|
if (t.start(e.encryptedContent.parameter),
|
|
t.update(e.encryptedContent.content),
|
|
!t.finish())
|
|
throw new Error("Symmetric decryption failed.");
|
|
e.content = t.output
|
|
}
|
|
}
|
|
var h = r(0);
|
|
r(5),
|
|
r(3),
|
|
r(10),
|
|
r(6),
|
|
r(7),
|
|
r(29),
|
|
r(2),
|
|
r(1),
|
|
r(17);
|
|
var d = h.asn1
|
|
, y = e.exports = h.pkcs7 = h.pkcs7 || {};
|
|
y.messageFromPem = function(e) {
|
|
var t = h.pem.decode(e)[0];
|
|
if ("PKCS7" !== t.type) {
|
|
var r = new Error('Could not convert PKCS#7 message from PEM; PEM header type is not "PKCS#7".');
|
|
throw r.headerType = t.type,
|
|
r
|
|
}
|
|
if (t.procType && "ENCRYPTED" === t.procType.type)
|
|
throw new Error("Could not convert PKCS#7 message from PEM; PEM is encrypted.");
|
|
var a = d.fromDer(t.body);
|
|
return y.messageFromAsn1(a)
|
|
}
|
|
,
|
|
y.messageToPem = function(e, t) {
|
|
var r = {
|
|
type: "PKCS7",
|
|
body: d.toDer(e.toAsn1()).getBytes()
|
|
};
|
|
return h.pem.encode(r, {
|
|
maxline: t
|
|
})
|
|
}
|
|
,
|
|
y.messageFromAsn1 = function(e) {
|
|
var t = {}
|
|
, r = [];
|
|
if (!d.validate(e, y.asn1.contentInfoValidator, t, r)) {
|
|
var a = new Error("Cannot read PKCS#7 message. ASN.1 object is not an PKCS#7 ContentInfo.");
|
|
throw a.errors = r,
|
|
a
|
|
}
|
|
var n, i = d.derToOid(t.contentType);
|
|
switch (i) {
|
|
case h.pki.oids.envelopedData:
|
|
n = y.createEnvelopedData();
|
|
break;
|
|
case h.pki.oids.encryptedData:
|
|
n = y.createEncryptedData();
|
|
break;
|
|
case h.pki.oids.signedData:
|
|
n = y.createSignedData();
|
|
break;
|
|
default:
|
|
throw new Error("Cannot read PKCS#7 message. ContentType with OID " + i + " is not (yet) supported.")
|
|
}
|
|
return n.fromAsn1(t.content.value[0]),
|
|
n
|
|
}
|
|
,
|
|
y.createSignedData = function() {
|
|
function e() {
|
|
for (var e = {}, t = 0; t < r.signers.length; ++t) {
|
|
var a = r.signers[t]
|
|
, n = a.digestAlgorithm;
|
|
n in e || (e[n] = h.md[h.pki.oids[n]].create()),
|
|
0 === a.authenticatedAttributes.length ? a.md = e[n] : a.md = h.md[h.pki.oids[n]].create()
|
|
}
|
|
r.digestAlgorithmIdentifiers = [];
|
|
for (var n in e)
|
|
r.digestAlgorithmIdentifiers.push(d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(n).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.NULL, !1, "")]));
|
|
return e
|
|
}
|
|
function t(e) {
|
|
var t;
|
|
if (r.detachedContent ? t = r.detachedContent : (t = r.contentInfo.value[1],
|
|
t = t.value[0]),
|
|
!t)
|
|
throw new Error("Could not sign PKCS#7 message; there is no content to sign.");
|
|
var a = d.derToOid(r.contentInfo.value[0].value)
|
|
, n = d.toDer(t);
|
|
n.getByte(),
|
|
d.getBerValueLength(n),
|
|
n = n.getBytes();
|
|
for (var i in e)
|
|
e[i].start().update(n);
|
|
for (var s = new Date, o = 0; o < r.signers.length; ++o) {
|
|
var l = r.signers[o];
|
|
if (0 === l.authenticatedAttributes.length) {
|
|
if (a !== h.pki.oids.data)
|
|
throw new Error("Invalid signer; authenticatedAttributes must be present when the ContentInfo content type is not PKCS#7 Data.")
|
|
} else {
|
|
l.authenticatedAttributesAsn1 = d.create(d.Class.CONTEXT_SPECIFIC, 0, !0, []);
|
|
for (var p = d.create(d.Class.UNIVERSAL, d.Type.SET, !0, []), f = 0; f < l.authenticatedAttributes.length; ++f) {
|
|
var y = l.authenticatedAttributes[f];
|
|
y.type === h.pki.oids.messageDigest ? y.value = e[l.digestAlgorithm].digest() : y.type === h.pki.oids.signingTime && (y.value || (y.value = s)),
|
|
p.value.push(u(y)),
|
|
l.authenticatedAttributesAsn1.value.push(u(y))
|
|
}
|
|
n = d.toDer(p).getBytes(),
|
|
l.md.start().update(n)
|
|
}
|
|
l.signature = l.key.sign(l.md, "RSASSA-PKCS1-V1_5")
|
|
}
|
|
r.signerInfos = c(r.signers)
|
|
}
|
|
var r = null;
|
|
return r = {
|
|
type: h.pki.oids.signedData,
|
|
version: 1,
|
|
certificates: [],
|
|
crls: [],
|
|
signers: [],
|
|
digestAlgorithmIdentifiers: [],
|
|
contentInfo: null,
|
|
signerInfos: [],
|
|
fromAsn1: function(e) {
|
|
if (p(r, e, y.asn1.signedDataValidator),
|
|
r.certificates = [],
|
|
r.crls = [],
|
|
r.digestAlgorithmIdentifiers = [],
|
|
r.contentInfo = null,
|
|
r.signerInfos = [],
|
|
r.rawCapture.certificates)
|
|
for (var t = r.rawCapture.certificates.value, a = 0; a < t.length; ++a)
|
|
r.certificates.push(h.pki.certificateFromAsn1(t[a]))
|
|
},
|
|
toAsn1: function() {
|
|
r.contentInfo || r.sign();
|
|
for (var e = [], t = 0; t < r.certificates.length; ++t)
|
|
e.push(h.pki.certificateToAsn1(r.certificates[t]));
|
|
var a = []
|
|
, n = d.create(d.Class.CONTEXT_SPECIFIC, 0, !0, [d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.INTEGER, !1, d.integerToDer(r.version).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.SET, !0, r.digestAlgorithmIdentifiers), r.contentInfo])]);
|
|
return e.length > 0 && n.value[0].value.push(d.create(d.Class.CONTEXT_SPECIFIC, 0, !0, e)),
|
|
a.length > 0 && n.value[0].value.push(d.create(d.Class.CONTEXT_SPECIFIC, 1, !0, a)),
|
|
n.value[0].value.push(d.create(d.Class.UNIVERSAL, d.Type.SET, !0, r.signerInfos)),
|
|
d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(r.type).getBytes()), n])
|
|
},
|
|
addSigner: function(e) {
|
|
var t = e.issuer
|
|
, a = e.serialNumber;
|
|
if (e.certificate) {
|
|
var n = e.certificate;
|
|
"string" == typeof n && (n = h.pki.certificateFromPem(n)),
|
|
t = n.issuer.attributes,
|
|
a = n.serialNumber
|
|
}
|
|
var i = e.key;
|
|
if (!i)
|
|
throw new Error("Could not add PKCS#7 signer; no private key specified.");
|
|
"string" == typeof i && (i = h.pki.privateKeyFromPem(i));
|
|
var s = e.digestAlgorithm || h.pki.oids.sha1;
|
|
switch (s) {
|
|
case h.pki.oids.sha1:
|
|
case h.pki.oids.sha256:
|
|
case h.pki.oids.sha384:
|
|
case h.pki.oids.sha512:
|
|
case h.pki.oids.md5:
|
|
break;
|
|
default:
|
|
throw new Error("Could not add PKCS#7 signer; unknown message digest algorithm: " + s)
|
|
}
|
|
var o = e.authenticatedAttributes || [];
|
|
if (o.length > 0) {
|
|
for (var c = !1, u = !1, l = 0; l < o.length; ++l) {
|
|
var p = o[l];
|
|
if (c || p.type !== h.pki.oids.contentType) {
|
|
if (u || p.type !== h.pki.oids.messageDigest)
|
|
;
|
|
else if (u = !0,
|
|
c)
|
|
break
|
|
} else if (c = !0,
|
|
u)
|
|
break
|
|
}
|
|
if (!c || !u)
|
|
throw new Error("Invalid signer.authenticatedAttributes. If signer.authenticatedAttributes is specified, then it must contain at least two attributes, PKCS #9 content-type and PKCS #9 message-digest.")
|
|
}
|
|
r.signers.push({
|
|
key: i,
|
|
version: 1,
|
|
issuer: t,
|
|
serialNumber: a,
|
|
digestAlgorithm: s,
|
|
signatureAlgorithm: h.pki.oids.rsaEncryption,
|
|
signature: null,
|
|
authenticatedAttributes: o,
|
|
unauthenticatedAttributes: []
|
|
})
|
|
},
|
|
sign: function(a) {
|
|
if (a = a || {},
|
|
("object" != typeof r.content || null === r.contentInfo) && (r.contentInfo = d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(h.pki.oids.data).getBytes())]),
|
|
"content"in r)) {
|
|
var n;
|
|
r.content instanceof h.util.ByteBuffer ? n = r.content.bytes() : "string" == typeof r.content && (n = h.util.encodeUtf8(r.content)),
|
|
a.detached ? r.detachedContent = d.create(d.Class.UNIVERSAL, d.Type.OCTETSTRING, !1, n) : r.contentInfo.value.push(d.create(d.Class.CONTEXT_SPECIFIC, 0, !0, [d.create(d.Class.UNIVERSAL, d.Type.OCTETSTRING, !1, n)]))
|
|
}
|
|
if (0 !== r.signers.length) {
|
|
t(e())
|
|
}
|
|
},
|
|
verify: function() {
|
|
throw new Error("PKCS#7 signature verification not yet implemented.")
|
|
},
|
|
addCertificate: function(e) {
|
|
"string" == typeof e && (e = h.pki.certificateFromPem(e)),
|
|
r.certificates.push(e)
|
|
},
|
|
addCertificateRevokationList: function(e) {
|
|
throw new Error("PKCS#7 CRL support not yet implemented.")
|
|
}
|
|
}
|
|
}
|
|
,
|
|
y.createEncryptedData = function() {
|
|
var e = null;
|
|
return e = {
|
|
type: h.pki.oids.encryptedData,
|
|
version: 0,
|
|
encryptedContent: {
|
|
algorithm: h.pki.oids["aes256-CBC"]
|
|
},
|
|
fromAsn1: function(t) {
|
|
p(e, t, y.asn1.encryptedDataValidator)
|
|
},
|
|
decrypt: function(t) {
|
|
void 0 !== t && (e.encryptedContent.key = t),
|
|
f(e)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
y.createEnvelopedData = function() {
|
|
var e = null;
|
|
return e = {
|
|
type: h.pki.oids.envelopedData,
|
|
version: 0,
|
|
recipients: [],
|
|
encryptedContent: {
|
|
algorithm: h.pki.oids["aes256-CBC"]
|
|
},
|
|
fromAsn1: function(t) {
|
|
var r = p(e, t, y.asn1.envelopedDataValidator);
|
|
e.recipients = i(r.recipientInfos.value)
|
|
},
|
|
toAsn1: function() {
|
|
return d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.OID, !1, d.oidToDer(e.type).getBytes()), d.create(d.Class.CONTEXT_SPECIFIC, 0, !0, [d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, [d.create(d.Class.UNIVERSAL, d.Type.INTEGER, !1, d.integerToDer(e.version).getBytes()), d.create(d.Class.UNIVERSAL, d.Type.SET, !0, s(e.recipients)), d.create(d.Class.UNIVERSAL, d.Type.SEQUENCE, !0, l(e.encryptedContent))])])])
|
|
},
|
|
findRecipient: function(t) {
|
|
for (var r = t.issuer.attributes, a = 0; a < e.recipients.length; ++a) {
|
|
var n = e.recipients[a]
|
|
, i = n.issuer;
|
|
if (n.serialNumber === t.serialNumber && i.length === r.length) {
|
|
for (var s = !0, o = 0; o < r.length; ++o)
|
|
if (i[o].type !== r[o].type || i[o].value !== r[o].value) {
|
|
s = !1;
|
|
break
|
|
}
|
|
if (s)
|
|
return n
|
|
}
|
|
}
|
|
return null
|
|
},
|
|
decrypt: function(t, r) {
|
|
if (void 0 === e.encryptedContent.key && void 0 !== t && void 0 !== r)
|
|
switch (t.encryptedContent.algorithm) {
|
|
case h.pki.oids.rsaEncryption:
|
|
case h.pki.oids.desCBC:
|
|
var a = r.decrypt(t.encryptedContent.content);
|
|
e.encryptedContent.key = h.util.createBuffer(a);
|
|
break;
|
|
default:
|
|
throw new Error("Unsupported asymmetric cipher, OID " + t.encryptedContent.algorithm)
|
|
}
|
|
f(e)
|
|
},
|
|
addRecipient: function(t) {
|
|
e.recipients.push({
|
|
version: 0,
|
|
issuer: t.issuer.attributes,
|
|
serialNumber: t.serialNumber,
|
|
encryptedContent: {
|
|
algorithm: h.pki.oids.rsaEncryption,
|
|
key: t.publicKey
|
|
}
|
|
})
|
|
},
|
|
encrypt: function(t, r) {
|
|
if (void 0 === e.encryptedContent.content) {
|
|
r = r || e.encryptedContent.algorithm,
|
|
t = t || e.encryptedContent.key;
|
|
var a, n, i;
|
|
switch (r) {
|
|
case h.pki.oids["aes128-CBC"]:
|
|
a = 16,
|
|
n = 16,
|
|
i = h.aes.createEncryptionCipher;
|
|
break;
|
|
case h.pki.oids["aes192-CBC"]:
|
|
a = 24,
|
|
n = 16,
|
|
i = h.aes.createEncryptionCipher;
|
|
break;
|
|
case h.pki.oids["aes256-CBC"]:
|
|
a = 32,
|
|
n = 16,
|
|
i = h.aes.createEncryptionCipher;
|
|
break;
|
|
case h.pki.oids["des-EDE3-CBC"]:
|
|
a = 24,
|
|
n = 8,
|
|
i = h.des.createEncryptionCipher;
|
|
break;
|
|
default:
|
|
throw new Error("Unsupported symmetric cipher, OID " + r)
|
|
}
|
|
if (void 0 === t)
|
|
t = h.util.createBuffer(h.random.getBytes(a));
|
|
else if (t.length() != a)
|
|
throw new Error("Symmetric key has wrong length; got " + t.length() + " bytes, expected " + a + ".");
|
|
e.encryptedContent.algorithm = r,
|
|
e.encryptedContent.key = t,
|
|
e.encryptedContent.parameter = h.util.createBuffer(h.random.getBytes(n));
|
|
var s = i(t);
|
|
if (s.start(e.encryptedContent.parameter.copy()),
|
|
s.update(e.content),
|
|
!s.finish())
|
|
throw new Error("Symmetric encryption failed.");
|
|
e.encryptedContent.content = s.output
|
|
}
|
|
for (var o = 0; o < e.recipients.length; ++o) {
|
|
var c = e.recipients[o];
|
|
if (void 0 === c.encryptedContent.content)
|
|
switch (c.encryptedContent.algorithm) {
|
|
case h.pki.oids.rsaEncryption:
|
|
c.encryptedContent.content = c.encryptedContent.key.encrypt(e.encryptedContent.key.data);
|
|
break;
|
|
default:
|
|
throw new Error("Unsupported asymmetric cipher, OID " + c.encryptedContent.algorithm)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
function a(e, t) {
|
|
var r = t.toString(16);
|
|
r[0] >= "8" && (r = "00" + r);
|
|
var a = s.util.hexToBytes(r);
|
|
e.putInt32(a.length),
|
|
e.putBytes(a)
|
|
}
|
|
function n(e, t) {
|
|
e.putInt32(t.length),
|
|
e.putString(t)
|
|
}
|
|
function i() {
|
|
for (var e = s.md.sha1.create(), t = arguments.length, r = 0; r < t; ++r)
|
|
e.update(arguments[r]);
|
|
return e.digest()
|
|
}
|
|
var s = r(0);
|
|
r(5),
|
|
r(8),
|
|
r(14),
|
|
r(9),
|
|
r(1);
|
|
var o = e.exports = s.ssh = s.ssh || {};
|
|
o.privateKeyToPutty = function(e, t, r) {
|
|
r = r || "",
|
|
t = t || "";
|
|
var o = "" === t ? "none" : "aes256-cbc"
|
|
, c = "PuTTY-User-Key-File-2: ssh-rsa\r\n";
|
|
c += "Encryption: " + o + "\r\n",
|
|
c += "Comment: " + r + "\r\n";
|
|
var u = s.util.createBuffer();
|
|
n(u, "ssh-rsa"),
|
|
a(u, e.e),
|
|
a(u, e.n);
|
|
var l = s.util.encode64(u.bytes(), 64)
|
|
, p = Math.floor(l.length / 66) + 1;
|
|
c += "Public-Lines: " + p + "\r\n",
|
|
c += l;
|
|
var f = s.util.createBuffer();
|
|
a(f, e.d),
|
|
a(f, e.p),
|
|
a(f, e.q),
|
|
a(f, e.qInv);
|
|
var h;
|
|
if (t) {
|
|
var d = f.length() + 16 - 1;
|
|
d -= d % 16;
|
|
var y = i(f.bytes());
|
|
y.truncate(y.length() - d + f.length()),
|
|
f.putBuffer(y);
|
|
var g = s.util.createBuffer();
|
|
g.putBuffer(i("\0\0\0\0", t)),
|
|
g.putBuffer(i("\0\0\0", t));
|
|
var v = s.aes.createEncryptionCipher(g.truncate(8), "CBC");
|
|
v.start(s.util.createBuffer().fillWithByte(0, 16)),
|
|
v.update(f.copy()),
|
|
v.finish();
|
|
var m = v.output;
|
|
m.truncate(16),
|
|
h = s.util.encode64(m.bytes(), 64)
|
|
} else
|
|
h = s.util.encode64(f.bytes(), 64);
|
|
p = Math.floor(h.length / 66) + 1,
|
|
c += "\r\nPrivate-Lines: " + p + "\r\n",
|
|
c += h;
|
|
var C = i("putty-private-key-file-mac-key", t)
|
|
, E = s.util.createBuffer();
|
|
n(E, "ssh-rsa"),
|
|
n(E, o),
|
|
n(E, r),
|
|
E.putInt32(u.length()),
|
|
E.putBuffer(u),
|
|
E.putInt32(f.length()),
|
|
E.putBuffer(f);
|
|
var S = s.hmac.create();
|
|
return S.start("sha1", C),
|
|
S.update(E.bytes()),
|
|
c += "\r\nPrivate-MAC: " + S.digest().toHex() + "\r\n"
|
|
}
|
|
,
|
|
o.publicKeyToOpenSSH = function(e, t) {
|
|
t = t || "";
|
|
var r = s.util.createBuffer();
|
|
return n(r, "ssh-rsa"),
|
|
a(r, e.e),
|
|
a(r, e.n),
|
|
"ssh-rsa " + s.util.encode64(r.bytes()) + " " + t
|
|
}
|
|
,
|
|
o.privateKeyToOpenSSH = function(e, t) {
|
|
return t ? s.pki.encryptRsaPrivateKey(e, t, {
|
|
legacy: !0,
|
|
algorithm: "aes128"
|
|
}) : s.pki.privateKeyToPem(e)
|
|
}
|
|
,
|
|
o.getPublicKeyFingerprint = function(e, t) {
|
|
t = t || {};
|
|
var r = t.md || s.md.md5.create()
|
|
, i = s.util.createBuffer();
|
|
n(i, "ssh-rsa"),
|
|
a(i, e.e),
|
|
a(i, e.n),
|
|
r.start(),
|
|
r.update(i.getBytes());
|
|
var o = r.digest();
|
|
if ("hex" === t.encoding) {
|
|
var c = o.toHex();
|
|
return t.delimiter ? c.match(/.{2}/g).join(t.delimiter) : c
|
|
}
|
|
if ("binary" === t.encoding)
|
|
return o.getBytes();
|
|
if (t.encoding)
|
|
throw new Error('Unknown encoding "' + t.encoding + '".');
|
|
return o
|
|
}
|
|
}
|
|
, function(e, t, r) {
|
|
var a = r(0);
|
|
r(31),
|
|
r(33),
|
|
r(1);
|
|
var n = "forge.task"
|
|
, i = {}
|
|
, s = 0;
|
|
a.debug.set(n, "tasks", i);
|
|
var o = {};
|
|
a.debug.set(n, "queues", o);
|
|
var c = "ready"
|
|
, u = "running"
|
|
, l = "blocked"
|
|
, p = "sleeping"
|
|
, f = "done"
|
|
, h = "error"
|
|
, d = "stop"
|
|
, y = "start"
|
|
, g = {};
|
|
g[c] = {},
|
|
g[c][d] = c,
|
|
g[c][y] = u,
|
|
g[c].cancel = f,
|
|
g[c].fail = h,
|
|
g[u] = {},
|
|
g[u][d] = c,
|
|
g[u][y] = u,
|
|
g[u].block = l,
|
|
g[u].unblock = u,
|
|
g[u].sleep = p,
|
|
g[u].wakeup = u,
|
|
g[u].cancel = f,
|
|
g[u].fail = h,
|
|
g[l] = {},
|
|
g[l][d] = l,
|
|
g[l][y] = l,
|
|
g[l].block = l,
|
|
g[l].unblock = l,
|
|
g[l].sleep = l,
|
|
g[l].wakeup = l,
|
|
g[l].cancel = f,
|
|
g[l].fail = h,
|
|
g[p] = {},
|
|
g[p][d] = p,
|
|
g[p][y] = p,
|
|
g[p].block = p,
|
|
g[p].unblock = p,
|
|
g[p].sleep = p,
|
|
g[p].wakeup = p,
|
|
g[p].cancel = f,
|
|
g[p].fail = h,
|
|
g[f] = {},
|
|
g[f][d] = f,
|
|
g[f][y] = f,
|
|
g[f].block = f,
|
|
g[f].unblock = f,
|
|
g[f].sleep = f,
|
|
g[f].wakeup = f,
|
|
g[f].cancel = f,
|
|
g[f].fail = h,
|
|
g[h] = {},
|
|
g[h][d] = h,
|
|
g[h][y] = h,
|
|
g[h].block = h,
|
|
g[h].unblock = h,
|
|
g[h].sleep = h,
|
|
g[h].wakeup = h,
|
|
g[h].cancel = h,
|
|
g[h].fail = h;
|
|
var v = function(e) {
|
|
this.id = -1,
|
|
this.name = e.name || "?",
|
|
this.parent = e.parent || null,
|
|
this.run = e.run,
|
|
this.subtasks = [],
|
|
this.error = !1,
|
|
this.state = c,
|
|
this.blocks = 0,
|
|
this.timeoutId = null,
|
|
this.swapTime = null,
|
|
this.userData = null,
|
|
this.id = s++,
|
|
i[this.id] = this
|
|
};
|
|
v.prototype.debug = function(e) {
|
|
e = e || "",
|
|
a.log.debug(n, e, "[%s][%s] task:", this.id, this.name, this, "subtasks:", this.subtasks.length, "queue:", o)
|
|
}
|
|
,
|
|
v.prototype.next = function(e, t) {
|
|
"function" == typeof e && (t = e,
|
|
e = this.name);
|
|
var r = new v({
|
|
run: t,
|
|
name: e,
|
|
parent: this
|
|
});
|
|
return r.state = u,
|
|
r.type = this.type,
|
|
r.successCallback = this.successCallback || null,
|
|
r.failureCallback = this.failureCallback || null,
|
|
this.subtasks.push(r),
|
|
this
|
|
}
|
|
,
|
|
v.prototype.parallel = function(e, t) {
|
|
return a.util.isArray(e) && (t = e,
|
|
e = this.name),
|
|
this.next(e, function(r) {
|
|
var n = r;
|
|
n.block(t.length);
|
|
for (var i = 0; i < t.length; i++) {
|
|
var s = e + "__parallel-" + r.id + "-" + i
|
|
, o = i;
|
|
!function(e, r) {
|
|
a.task.start({
|
|
type: e,
|
|
run: function(e) {
|
|
t[r](e)
|
|
},
|
|
success: function(e) {
|
|
n.unblock()
|
|
},
|
|
failure: function(e) {
|
|
n.unblock()
|
|
}
|
|
})
|
|
}(s, o)
|
|
}
|
|
})
|
|
}
|
|
,
|
|
v.prototype.stop = function() {
|
|
this.state = g[this.state][d]
|
|
}
|
|
,
|
|
v.prototype.start = function() {
|
|
this.error = !1,
|
|
this.state = g[this.state][y],
|
|
this.state === u && (this.start = new Date,
|
|
this.run(this),
|
|
C(this, 0))
|
|
}
|
|
,
|
|
v.prototype.block = function(e) {
|
|
e = void 0 === e ? 1 : e,
|
|
this.blocks += e,
|
|
this.blocks > 0 && (this.state = g[this.state].block)
|
|
}
|
|
,
|
|
v.prototype.unblock = function(e) {
|
|
return e = void 0 === e ? 1 : e,
|
|
this.blocks -= e,
|
|
0 === this.blocks && this.state !== f && (this.state = u,
|
|
C(this, 0)),
|
|
this.blocks
|
|
}
|
|
,
|
|
v.prototype.sleep = function(e) {
|
|
e = void 0 === e ? 0 : e,
|
|
this.state = g[this.state].sleep;
|
|
var t = this;
|
|
this.timeoutId = setTimeout(function() {
|
|
t.timeoutId = null,
|
|
t.state = u,
|
|
C(t, 0)
|
|
}, e)
|
|
}
|
|
,
|
|
v.prototype.wait = function(e) {
|
|
e.wait(this)
|
|
}
|
|
,
|
|
v.prototype.wakeup = function() {
|
|
this.state === p && (cancelTimeout(this.timeoutId),
|
|
this.timeoutId = null,
|
|
this.state = u,
|
|
C(this, 0))
|
|
}
|
|
,
|
|
v.prototype.cancel = function() {
|
|
this.state = g[this.state].cancel,
|
|
this.permitsNeeded = 0,
|
|
null !== this.timeoutId && (cancelTimeout(this.timeoutId),
|
|
this.timeoutId = null),
|
|
this.subtasks = []
|
|
}
|
|
,
|
|
v.prototype.fail = function(e) {
|
|
if (this.error = !0,
|
|
E(this, !0),
|
|
e)
|
|
e.error = this.error,
|
|
e.swapTime = this.swapTime,
|
|
e.userData = this.userData,
|
|
C(e, 0);
|
|
else {
|
|
if (null !== this.parent) {
|
|
for (var t = this.parent; null !== t.parent; )
|
|
t.error = this.error,
|
|
t.swapTime = this.swapTime,
|
|
t.userData = this.userData,
|
|
t = t.parent;
|
|
E(t, !0)
|
|
}
|
|
this.failureCallback && this.failureCallback(this)
|
|
}
|
|
}
|
|
;
|
|
var m = function(e) {
|
|
e.error = !1,
|
|
e.state = g[e.state][y],
|
|
setTimeout(function() {
|
|
e.state === u && (e.swapTime = +new Date,
|
|
e.run(e),
|
|
C(e, 0))
|
|
}, 0)
|
|
}
|
|
, C = function(e, t) {
|
|
var r = t > 30 || +new Date - e.swapTime > 20
|
|
, a = function(t) {
|
|
if (t++,
|
|
e.state === u)
|
|
if (r && (e.swapTime = +new Date),
|
|
e.subtasks.length > 0) {
|
|
var a = e.subtasks.shift();
|
|
a.error = e.error,
|
|
a.swapTime = e.swapTime,
|
|
a.userData = e.userData,
|
|
a.run(a),
|
|
a.error || C(a, t)
|
|
} else
|
|
E(e),
|
|
e.error || null !== e.parent && (e.parent.error = e.error,
|
|
e.parent.swapTime = e.swapTime,
|
|
e.parent.userData = e.userData,
|
|
C(e.parent, t))
|
|
};
|
|
r ? setTimeout(a, 0) : a(t)
|
|
}
|
|
, E = function(e, t) {
|
|
e.state = f,
|
|
delete i[e.id],
|
|
null === e.parent && (e.type in o ? 0 === o[e.type].length ? a.log.error(n, "[%s][%s] task queue empty [%s]", e.id, e.name, e.type) : o[e.type][0] !== e ? a.log.error(n, "[%s][%s] task not first in queue [%s]", e.id, e.name, e.type) : (o[e.type].shift(),
|
|
0 === o[e.type].length ? delete o[e.type] : o[e.type][0].start()) : a.log.error(n, "[%s][%s] task queue missing [%s]", e.id, e.name, e.type),
|
|
t || (e.error && e.failureCallback ? e.failureCallback(e) : !e.error && e.successCallback && e.successCallback(e)))
|
|
};
|
|
e.exports = a.task = a.task || {},
|
|
a.task.start = function(e) {
|
|
var t = new v({
|
|
run: e.run,
|
|
name: e.name || "?"
|
|
});
|
|
t.type = e.type,
|
|
t.successCallback = e.success || null,
|
|
t.failureCallback = e.failure || null,
|
|
t.type in o ? o[e.type].push(t) : (o[t.type] = [t],
|
|
m(t))
|
|
}
|
|
,
|
|
a.task.cancel = function(e) {
|
|
e in o && (o[e] = [o[e][0]])
|
|
}
|
|
,
|
|
a.task.createCondition = function() {
|
|
var e = {
|
|
tasks: {}
|
|
};
|
|
return e.wait = function(t) {
|
|
t.id in e.tasks || (t.block(),
|
|
e.tasks[t.id] = t)
|
|
}
|
|
,
|
|
e.notify = function() {
|
|
var t = e.tasks;
|
|
e.tasks = {};
|
|
for (var r in t)
|
|
t[r].unblock()
|
|
}
|
|
,
|
|
e
|
|
}
|
|
}
|
|
])
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
let cacheRegex = null;
|
|
let lastRegex = "";
|
|
let lastFlags = "";
|
|
let regexMatches = [];
|
|
let lastMatchesStr = "";
|
|
let lastMatchesRegex = "";
|
|
let lastMatchesFlags = "";
|
|
const forEachStack = C3.New(C3.ArrayStack);
|
|
function ForEachOrdered_SortInstances(a, b) {
|
|
const va = a[1];
|
|
const vb = b[1];
|
|
if (typeof va === "number" && typeof vb === "number")
|
|
return va - vb;
|
|
else {
|
|
const sa = "" + va;
|
|
const sb = "" + vb;
|
|
if (sa < sb)
|
|
return -1;
|
|
else if (sa > sb)
|
|
return 1;
|
|
else
|
|
return 0
|
|
}
|
|
}
|
|
C3.Plugins.System = class SystemPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
this._loopStack = this._runtime.GetEventSheetManager().GetLoopStack();
|
|
this._eventStack = this._runtime.GetEventSheetManager().GetEventStack();
|
|
this._imagesLoadingTotal = 0;
|
|
this._imagesLoadingComplete = 0;
|
|
this._functionMaps = new Map
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
UpdateRender() {
|
|
this._runtime.UpdateRender()
|
|
}
|
|
Trigger(method) {
|
|
this._runtime.Trigger(method, null, null)
|
|
}
|
|
GetRegex(regex, flags) {
|
|
if (!cacheRegex || regex !== lastRegex || flags !== lastFlags) {
|
|
cacheRegex = new RegExp(regex,flags);
|
|
lastRegex = regex;
|
|
lastFlags = flags
|
|
}
|
|
cacheRegex.lastIndex = 0;
|
|
return cacheRegex
|
|
}
|
|
GetRegexMatches(str, regex, flags) {
|
|
if (str === lastMatchesStr && regex === lastMatchesRegex && flags === lastMatchesFlags)
|
|
return regexMatches;
|
|
const cacheRegex = this.GetRegex(regex, flags);
|
|
regexMatches = str.match(cacheRegex);
|
|
lastMatchesStr = str;
|
|
lastMatchesRegex = regex;
|
|
lastMatchesFlags = flags;
|
|
return regexMatches
|
|
}
|
|
async _LoadTexturesForObjectClasses(layout, objectClasses) {
|
|
if (!objectClasses.length)
|
|
return;
|
|
this._imagesLoadingTotal += objectClasses.length;
|
|
const promises = [];
|
|
for (const oc of objectClasses)
|
|
promises.push(layout.MaybeLoadTexturesFor(oc));
|
|
await C3.PromiseAllWithProgress(promises, ()=>{
|
|
this._imagesLoadingComplete++
|
|
}
|
|
);
|
|
this._imagesLoadingComplete++;
|
|
if (this._imagesLoadingComplete === this._imagesLoadingTotal) {
|
|
this._runtime.Trigger(C3.Plugins.System.Cnds.OnImageLoadingComplete, null, null);
|
|
this._imagesLoadingComplete = 0;
|
|
this._imagesLoadingTotal = 0
|
|
}
|
|
}
|
|
_UnloadTexturesForObjectClasses(layout, objectClasses) {
|
|
for (const oc of objectClasses)
|
|
if (oc.GetInstanceCount() === 0)
|
|
layout.MaybeUnloadTexturesFor(oc)
|
|
}
|
|
_GetForEachStack() {
|
|
return forEachStack
|
|
}
|
|
_Repeat(count) {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const isSolModifierAfterCnds = oldFrame.IsSolModifierAfterCnds();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const loopStack = eventSheetManager.GetLoopStack();
|
|
const loop = loopStack.Push();
|
|
loop.SetEnd(count);
|
|
if (isSolModifierAfterCnds)
|
|
for (let i = 0; i < count && !loop.IsStopped(); ++i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
loop.SetIndex(i);
|
|
currentEvent.Retrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else
|
|
for (let i = 0; i < count && !loop.IsStopped(); ++i) {
|
|
loop.SetIndex(i);
|
|
currentEvent.Retrigger(oldFrame, newFrame)
|
|
}
|
|
eventStack.Pop();
|
|
loopStack.Pop();
|
|
return false
|
|
}
|
|
*_DebugRepeat(count) {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const isSolModifierAfterCnds = oldFrame.IsSolModifierAfterCnds();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const loopStack = eventSheetManager.GetLoopStack();
|
|
const loop = loopStack.Push();
|
|
loop.SetEnd(count);
|
|
if (isSolModifierAfterCnds)
|
|
for (let i = 0; i < count && !loop.IsStopped(); ++i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
loop.SetIndex(i);
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else
|
|
for (let i = 0; i < count && !loop.IsStopped(); ++i) {
|
|
loop.SetIndex(i);
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame)
|
|
}
|
|
eventStack.Pop();
|
|
loopStack.Pop();
|
|
return false
|
|
}
|
|
_While() {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const isSolModifierAfterCnds = oldFrame.IsSolModifierAfterCnds();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const loopStack = eventSheetManager.GetLoopStack();
|
|
const loop = loopStack.Push();
|
|
if (isSolModifierAfterCnds)
|
|
for (let i = 0; !loop.IsStopped(); ++i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
loop.SetIndex(i);
|
|
if (!currentEvent.Retrigger(oldFrame, newFrame))
|
|
loop.Stop();
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else
|
|
for (let i = 0; !loop.IsStopped(); ++i) {
|
|
loop.SetIndex(i);
|
|
if (!currentEvent.Retrigger(oldFrame, newFrame))
|
|
loop.Stop()
|
|
}
|
|
eventStack.Pop();
|
|
loopStack.Pop();
|
|
return false
|
|
}
|
|
*_DebugWhile() {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const isSolModifierAfterCnds = oldFrame.IsSolModifierAfterCnds();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const loopStack = eventSheetManager.GetLoopStack();
|
|
const loop = loopStack.Push();
|
|
if (isSolModifierAfterCnds)
|
|
for (let i = 0; !loop.IsStopped(); ++i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
loop.SetIndex(i);
|
|
const ret = yield*currentEvent.DebugRetrigger(oldFrame, newFrame);
|
|
if (!ret)
|
|
loop.Stop();
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else
|
|
for (let i = 0; !loop.IsStopped(); ++i) {
|
|
loop.SetIndex(i);
|
|
const ret = yield*currentEvent.DebugRetrigger(oldFrame, newFrame);
|
|
if (!ret)
|
|
loop.Stop()
|
|
}
|
|
eventStack.Pop();
|
|
loopStack.Pop();
|
|
return false
|
|
}
|
|
_For(name, start, end) {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const isSolModifierAfterCnds = oldFrame.IsSolModifierAfterCnds();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const loopStack = eventSheetManager.GetLoopStack();
|
|
const loop = loopStack.Push();
|
|
loop.SetName(name);
|
|
loop.SetEnd(end);
|
|
if (end < start)
|
|
if (isSolModifierAfterCnds)
|
|
for (let i = start; i >= end && !loop.IsStopped(); --i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
loop.SetIndex(i);
|
|
currentEvent.Retrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else
|
|
for (let i = start; i >= end && !loop.IsStopped(); --i) {
|
|
loop.SetIndex(i);
|
|
currentEvent.Retrigger(oldFrame, newFrame)
|
|
}
|
|
else if (isSolModifierAfterCnds)
|
|
for (let i = start; i <= end && !loop.IsStopped(); ++i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
loop.SetIndex(i);
|
|
currentEvent.Retrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else
|
|
for (let i = start; i <= end && !loop.IsStopped(); ++i) {
|
|
loop.SetIndex(i);
|
|
currentEvent.Retrigger(oldFrame, newFrame)
|
|
}
|
|
eventStack.Pop();
|
|
loopStack.Pop();
|
|
return false
|
|
}
|
|
*_DebugFor(name, start, end) {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const isSolModifierAfterCnds = oldFrame.IsSolModifierAfterCnds();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const loopStack = eventSheetManager.GetLoopStack();
|
|
const loop = loopStack.Push();
|
|
loop.SetName(name);
|
|
loop.SetEnd(end);
|
|
if (end < start)
|
|
if (isSolModifierAfterCnds)
|
|
for (let i = start; i >= end && !loop.IsStopped(); --i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
loop.SetIndex(i);
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else
|
|
for (let i = start; i >= end && !loop.IsStopped(); --i) {
|
|
loop.SetIndex(i);
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame)
|
|
}
|
|
else if (isSolModifierAfterCnds)
|
|
for (let i = start; i <= end && !loop.IsStopped(); ++i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
loop.SetIndex(i);
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else
|
|
for (let i = start; i <= end && !loop.IsStopped(); ++i) {
|
|
loop.SetIndex(i);
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame)
|
|
}
|
|
eventStack.Pop();
|
|
loopStack.Pop();
|
|
return false
|
|
}
|
|
_ForEach(objectClass) {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const isSolModifierAfterCnds = oldFrame.IsSolModifierAfterCnds();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const loopStack = eventSheetManager.GetLoopStack();
|
|
const loop = loopStack.Push();
|
|
const isInContainer = objectClass.IsInContainer();
|
|
const sol = objectClass.GetCurrentSol();
|
|
const instances = forEachStack.Push();
|
|
C3.shallowAssignArray(instances, sol.GetInstances());
|
|
loop.SetEnd(instances.length);
|
|
if (isSolModifierAfterCnds)
|
|
for (let i = 0, len = instances.length; i < len && !loop.IsStopped(); ++i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
const inst = instances[i];
|
|
objectClass.GetCurrentSol().SetSinglePicked(inst);
|
|
if (isInContainer)
|
|
inst.SetSiblingsSinglePicked();
|
|
loop.SetIndex(i);
|
|
currentEvent.Retrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else {
|
|
sol._SetSelectAll(false);
|
|
const solInstances = sol._GetOwnInstances();
|
|
C3.clearArray(solInstances);
|
|
solInstances.push(null);
|
|
for (let i = 0, len = instances.length; i < len && !loop.IsStopped(); ++i) {
|
|
const inst = instances[i];
|
|
solInstances[0] = inst;
|
|
if (isInContainer)
|
|
inst.SetSiblingsSinglePicked();
|
|
loop.SetIndex(i);
|
|
currentEvent.Retrigger(oldFrame, newFrame)
|
|
}
|
|
}
|
|
eventStack.Pop();
|
|
loopStack.Pop();
|
|
C3.clearArray(instances);
|
|
forEachStack.Pop();
|
|
return false
|
|
}
|
|
*_DebugForEach(objectClass) {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const isSolModifierAfterCnds = oldFrame.IsSolModifierAfterCnds();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const loopStack = eventSheetManager.GetLoopStack();
|
|
const loop = loopStack.Push();
|
|
const isInContainer = objectClass.IsInContainer();
|
|
const sol = objectClass.GetCurrentSol();
|
|
const instances = forEachStack.Push();
|
|
C3.shallowAssignArray(instances, sol.GetInstances());
|
|
loop.SetEnd(instances.length);
|
|
if (isSolModifierAfterCnds)
|
|
for (let i = 0, len = instances.length; i < len && !loop.IsStopped(); ++i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
const inst = instances[i];
|
|
objectClass.GetCurrentSol().SetSinglePicked(inst);
|
|
if (isInContainer)
|
|
inst.SetSiblingsSinglePicked();
|
|
loop.SetIndex(i);
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else {
|
|
sol._SetSelectAll(false);
|
|
const solInstances = sol._GetOwnInstances();
|
|
C3.clearArray(solInstances);
|
|
solInstances.push(null);
|
|
for (let i = 0, len = instances.length; i < len && !loop.IsStopped(); ++i) {
|
|
const inst = instances[i];
|
|
solInstances[0] = inst;
|
|
if (isInContainer)
|
|
inst.SetSiblingsSinglePicked();
|
|
loop.SetIndex(i);
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame)
|
|
}
|
|
}
|
|
eventStack.Pop();
|
|
loopStack.Pop();
|
|
C3.clearArray(instances);
|
|
forEachStack.Pop();
|
|
return false
|
|
}
|
|
_ForEachOrdered(objectClass, order) {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const cnd = eventSheetManager.GetCurrentCondition();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const isSolModifierAfterCnds = oldFrame.IsSolModifierAfterCnds();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const loopStack = eventSheetManager.GetLoopStack();
|
|
const loop = loopStack.Push();
|
|
const isInContainer = objectClass.IsInContainer();
|
|
const sol = objectClass.GetCurrentSol();
|
|
const instancesData = forEachStack.Push();
|
|
C3.clearArray(instancesData);
|
|
const iterInstances = sol.GetInstances();
|
|
loop.SetEnd(iterInstances.length);
|
|
for (let i = 0, len = iterInstances.length; i < len; ++i)
|
|
instancesData.push([iterInstances[i], cnd.ReevaluateParameter(1, i)]);
|
|
instancesData.sort(ForEachOrdered_SortInstances);
|
|
if (order === 1)
|
|
instancesData.reverse();
|
|
if (isSolModifierAfterCnds)
|
|
for (let i = 0, len = instancesData.length; i < len && !loop.IsStopped(); ++i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
const inst = instancesData[i][0];
|
|
objectClass.GetCurrentSol().SetSinglePicked(inst);
|
|
if (isInContainer)
|
|
inst.SetSiblingsSinglePicked();
|
|
loop.SetIndex(i);
|
|
currentEvent.Retrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else {
|
|
sol._SetSelectAll(false);
|
|
const solInstances = sol._GetOwnInstances();
|
|
C3.clearArray(solInstances);
|
|
solInstances.push(null);
|
|
for (let i = 0, len = instancesData.length; i < len && !loop.IsStopped(); ++i) {
|
|
const inst = instancesData[i][0];
|
|
solInstances[0] = inst;
|
|
if (isInContainer)
|
|
inst.SetSiblingsSinglePicked();
|
|
loop.SetIndex(i);
|
|
currentEvent.Retrigger(oldFrame, newFrame)
|
|
}
|
|
}
|
|
eventStack.Pop();
|
|
loopStack.Pop();
|
|
C3.clearArray(instancesData);
|
|
forEachStack.Pop();
|
|
return false
|
|
}
|
|
*_DebugForEachOrdered(objectClass, order) {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const cnd = eventSheetManager.GetCurrentCondition();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const isSolModifierAfterCnds = oldFrame.IsSolModifierAfterCnds();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const loopStack = eventSheetManager.GetLoopStack();
|
|
const loop = loopStack.Push();
|
|
const isInContainer = objectClass.IsInContainer();
|
|
const sol = objectClass.GetCurrentSol();
|
|
const instancesData = forEachStack.Push();
|
|
C3.clearArray(instancesData);
|
|
const iterInstances = sol.GetInstances();
|
|
loop.SetEnd(iterInstances.length);
|
|
for (let i = 0, len = iterInstances.length; i < len; ++i)
|
|
instancesData.push([iterInstances[i], cnd.ReevaluateParameter(1, i)]);
|
|
instancesData.sort(ForEachOrdered_SortInstances);
|
|
if (order === 1)
|
|
instancesData.reverse();
|
|
if (isSolModifierAfterCnds)
|
|
for (let i = 0, len = instancesData.length; i < len && !loop.IsStopped(); ++i) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
const inst = instancesData[i][0];
|
|
objectClass.GetCurrentSol().SetSinglePicked(inst);
|
|
if (isInContainer)
|
|
inst.SetSiblingsSinglePicked();
|
|
loop.SetIndex(i);
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
else {
|
|
sol._SetSelectAll(false);
|
|
const solInstances = sol._GetOwnInstances();
|
|
C3.clearArray(solInstances);
|
|
solInstances.push(null);
|
|
for (let i = 0, len = instancesData.length; i < len && !loop.IsStopped(); ++i) {
|
|
const inst = instancesData[i][0];
|
|
solInstances[0] = inst;
|
|
if (isInContainer)
|
|
inst.SetSiblingsSinglePicked();
|
|
loop.SetIndex(i);
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame)
|
|
}
|
|
}
|
|
eventStack.Pop();
|
|
loopStack.Pop();
|
|
C3.clearArray(instancesData);
|
|
forEachStack.Pop();
|
|
return false
|
|
}
|
|
_GetFunctionMap(name, createIfMissing) {
|
|
let ret = this._functionMaps.get(name);
|
|
if (ret)
|
|
return ret;
|
|
if (!createIfMissing)
|
|
return null;
|
|
ret = {
|
|
defaultFunc: null,
|
|
strMap: new Map
|
|
};
|
|
this._functionMaps.set(name, ret);
|
|
return ret
|
|
}
|
|
_DoCallMappedFunction(eventSheetManager, functionBlock, paramResults, hasAnySolModifiers, solModifiers) {
|
|
functionBlock.GetEventBlock().RunAsMappedFunctionCall(paramResults);
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
*_DebugDoCallMappedFunction(eventSheetManager, functionBlock, paramResults, hasAnySolModifiers, solModifiers) {
|
|
yield*functionBlock.GetEventBlock().DebugRunAsMappedFunctionCall(paramResults);
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.System.Type = class SystemType extends C3.DefendedBase {
|
|
constructor(objectClass) {
|
|
super();
|
|
this._objectClass = objectClass;
|
|
this._runtime = objectClass.GetRuntime();
|
|
this._plugin = objectClass.GetPlugin()
|
|
}
|
|
OnCreate() {}
|
|
Release() {
|
|
this._objectClass = null;
|
|
this._runtime = null;
|
|
this._plugin = null
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.System.Instance = class SystemInstance extends C3.DefendedBase {
|
|
constructor(inst, properties) {
|
|
super();
|
|
this._inst = inst;
|
|
this._objectClass = this._inst.GetObjectClass();
|
|
this._sdkType = this._objectClass.GetSdkType();
|
|
this._runtime = this._inst.GetRuntime()
|
|
}
|
|
Release() {
|
|
this._inst = null;
|
|
this._objectClass = null;
|
|
this._sdkType = null;
|
|
this._runtime = null
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tmpPickArray = [];
|
|
C3.Plugins.System.Cnds = {
|
|
EveryTick() {
|
|
return true
|
|
},
|
|
OnLayoutStart() {
|
|
return true
|
|
},
|
|
OnLayoutEnd() {
|
|
return true
|
|
},
|
|
OnSuspend() {
|
|
return true
|
|
},
|
|
OnResume() {
|
|
return true
|
|
},
|
|
IsSuspended() {
|
|
return this._runtime.IsSuspended()
|
|
},
|
|
Else() {
|
|
const frame = this._runtime.GetCurrentEventStackFrame();
|
|
if (frame.GetElseBranchRan())
|
|
return false;
|
|
else
|
|
return !frame.GetLastEventTrue()
|
|
},
|
|
TriggerOnce() {
|
|
const cnd = this._runtime.GetCurrentCondition();
|
|
const cndSavedData = cnd.GetSavedDataMap();
|
|
let lastTick = cndSavedData.get("TriggerOnce_lastTick");
|
|
if (typeof lastTick === "undefined") {
|
|
lastTick = -1;
|
|
cndSavedData.set("TriggerOnce_lastTick", -1)
|
|
}
|
|
const curTick = this._runtime.GetTickCount();
|
|
cndSavedData.set("TriggerOnce_lastTick", curTick);
|
|
return this._runtime.IsLayoutFirstTick() || lastTick !== curTick - 1
|
|
},
|
|
Every(seconds) {
|
|
const cnd = this._runtime.GetCurrentCondition();
|
|
const cndSavedData = cnd.GetSavedDataMap();
|
|
const lastTime = cndSavedData.get("Every_lastTime") || 0;
|
|
const curTime = this._runtime.GetGameTime();
|
|
if (!cndSavedData.has("Every_seconds"))
|
|
cndSavedData.set("Every_seconds", seconds);
|
|
const thisSeconds = cndSavedData.get("Every_seconds");
|
|
if (curTime >= lastTime + thisSeconds) {
|
|
cndSavedData.set("Every_lastTime", lastTime + thisSeconds);
|
|
if (curTime >= cndSavedData.get("Every_lastTime") + .04)
|
|
cndSavedData.set("Every_lastTime", curTime);
|
|
cndSavedData.set("Every_seconds", seconds);
|
|
return true
|
|
} else if (curTime < lastTime - .1)
|
|
cndSavedData.set("Every_lastTime", curTime);
|
|
return false
|
|
},
|
|
IsGroupActive(groupName) {
|
|
const eventGroup = this._runtime.GetEventSheetManager().GetEventGroupByName(groupName);
|
|
return eventGroup && eventGroup.IsGroupActive()
|
|
},
|
|
IsPreview() {
|
|
return this._runtime.IsPreview()
|
|
},
|
|
IsMobile() {
|
|
return C3.Platform.IsMobile
|
|
},
|
|
OnLoadFinished() {
|
|
return true
|
|
},
|
|
OnCanvasSnapshot() {
|
|
return true
|
|
},
|
|
EffectsSupported() {
|
|
return true
|
|
},
|
|
OnSaveComplete() {
|
|
return true
|
|
},
|
|
OnSaveFailed() {
|
|
return true
|
|
},
|
|
OnLoadComplete() {
|
|
return true
|
|
},
|
|
OnLoadFailed() {
|
|
return true
|
|
},
|
|
ObjectUIDExists(uid) {
|
|
return !!this._runtime.GetInstanceByUID(uid)
|
|
},
|
|
IsOnPlatform(p) {
|
|
switch (p) {
|
|
case 0:
|
|
return C3.Platform.Context === "browser";
|
|
case 1:
|
|
return C3.Platform.OS === "iOS";
|
|
case 2:
|
|
return C3.Platform.OS === "Android";
|
|
case 8:
|
|
return C3.Platform.Context === "cordova";
|
|
case 9:
|
|
return this._runtime.GetExportType() === "scirra-arcade";
|
|
case 10:
|
|
return C3.Platform.Context === "nwjs";
|
|
case 13:
|
|
return this._runtime.GetExportType() === "windows-uwp";
|
|
default:
|
|
return false
|
|
}
|
|
},
|
|
RegexTest(str, regex, flags) {
|
|
const cacheRegex = this.GetRegex(regex, flags);
|
|
return cacheRegex.test(str)
|
|
},
|
|
Compare(x, cmp, y) {
|
|
return C3.compare(x, cmp, y)
|
|
},
|
|
CompareBetween(x, a, b) {
|
|
return x >= a && x <= b
|
|
},
|
|
CompareVar(ev, cmp, val) {
|
|
return C3.compare(ev.GetValue(), cmp, val)
|
|
},
|
|
CompareBoolVar(ev) {
|
|
return !!ev.GetValue()
|
|
},
|
|
CompareTime(cmp, t) {
|
|
const gameTime = this._runtime.GetGameTime();
|
|
if (cmp === 0) {
|
|
const cnd = this._runtime.GetCurrentCondition();
|
|
const cndSavedData = cnd.GetSavedDataMap();
|
|
if (!cndSavedData.get("CompareTime_executed"))
|
|
if (gameTime >= t) {
|
|
cndSavedData.set("CompareTime_executed", true);
|
|
return true
|
|
}
|
|
return false
|
|
} else
|
|
return C3.compare(gameTime, cmp, t)
|
|
},
|
|
IsNaN(n) {
|
|
return isNaN(n)
|
|
},
|
|
AngleWithin(a1, within, a2) {
|
|
return C3.angleDiff(C3.toRadians(a1), C3.toRadians(a2)) <= C3.toRadians(within)
|
|
},
|
|
IsClockwiseFrom(a1, a2) {
|
|
return C3.angleClockwise(C3.toRadians(a1), C3.toRadians(a2))
|
|
},
|
|
IsBetweenAngles(a, la, ua) {
|
|
let angle = C3.toRadians(a);
|
|
let lower = C3.toRadians(la);
|
|
let upper = C3.toRadians(ua);
|
|
let obtuse = !C3.angleClockwise(upper, lower);
|
|
if (obtuse)
|
|
return !(!C3.angleClockwise(angle, lower) && C3.angleClockwise(angle, upper));
|
|
else
|
|
return C3.angleClockwise(angle, lower) && !C3.angleClockwise(angle, upper)
|
|
},
|
|
IsValueType(v, t) {
|
|
if (typeof v === "number")
|
|
return t === 0;
|
|
else
|
|
return t === 1
|
|
},
|
|
EvaluateExpression(v) {
|
|
return !!v
|
|
},
|
|
PickByComparison(objectClass, exp, cmp, val) {
|
|
if (!objectClass)
|
|
return false;
|
|
const forEachStack = this._GetForEachStack();
|
|
const tempInstances = forEachStack.Push();
|
|
const sol = objectClass.GetCurrentSol();
|
|
C3.shallowAssignArray(tempInstances, sol.GetInstances());
|
|
if (sol.IsSelectAll())
|
|
C3.clearArray(sol._GetOwnElseInstances());
|
|
const cnd = this._runtime.GetCurrentCondition();
|
|
let k = 0;
|
|
for (let i = 0, len = tempInstances.length; i < len; ++i) {
|
|
const inst = tempInstances[i];
|
|
tempInstances[k] = inst;
|
|
exp = cnd.ReevaluateParameter(1, i);
|
|
val = cnd.ReevaluateParameter(3, i);
|
|
if (C3.compare(exp, cmp, val))
|
|
++k;
|
|
else
|
|
sol._PushElseInstance(inst)
|
|
}
|
|
C3.truncateArray(tempInstances, k);
|
|
sol.SetArrayPicked(tempInstances);
|
|
const ret = !!tempInstances.length;
|
|
C3.clearArray(tempInstances);
|
|
forEachStack.Pop();
|
|
objectClass.ApplySolToContainer();
|
|
return ret
|
|
},
|
|
PickByEvaluate(objectClass, exp) {
|
|
if (!objectClass)
|
|
return false;
|
|
const forEachStack = this._GetForEachStack();
|
|
const tempInstances = forEachStack.Push();
|
|
const sol = objectClass.GetCurrentSol();
|
|
C3.shallowAssignArray(tempInstances, sol.GetInstances());
|
|
if (sol.IsSelectAll())
|
|
C3.clearArray(sol._GetOwnElseInstances());
|
|
const cnd = this._runtime.GetCurrentCondition();
|
|
let k = 0;
|
|
for (let i = 0, len = tempInstances.length; i < len; ++i) {
|
|
const inst = tempInstances[i];
|
|
tempInstances[k] = inst;
|
|
exp = cnd.ReevaluateParameter(1, i);
|
|
if (exp)
|
|
++k;
|
|
else
|
|
sol._PushElseInstance(inst)
|
|
}
|
|
C3.truncateArray(tempInstances, k);
|
|
sol.SetArrayPicked(tempInstances);
|
|
const ret = !!tempInstances.length;
|
|
C3.clearArray(tempInstances);
|
|
forEachStack.Pop();
|
|
objectClass.ApplySolToContainer();
|
|
return ret
|
|
},
|
|
PickNth(objectClass, index) {
|
|
if (!objectClass)
|
|
return false;
|
|
const sol = objectClass.GetCurrentSol();
|
|
const instances = sol.GetInstances();
|
|
index = Math.floor(index);
|
|
if (index >= instances.length)
|
|
return false;
|
|
const inst = instances[index];
|
|
sol.PickOne(inst);
|
|
objectClass.ApplySolToContainer();
|
|
return true
|
|
},
|
|
PickRandom(objectClass) {
|
|
if (!objectClass)
|
|
return false;
|
|
const sol = objectClass.GetCurrentSol();
|
|
const instances = sol.GetInstances();
|
|
const index = Math.floor(this._runtime.Random() * instances.length);
|
|
if (index >= instances.length)
|
|
return false;
|
|
const inst = instances[index];
|
|
sol.PickOne(inst);
|
|
objectClass.ApplySolToContainer();
|
|
return true
|
|
},
|
|
PickAll(objectClass) {
|
|
if (!objectClass)
|
|
return false;
|
|
if (!objectClass.GetInstanceCount())
|
|
return false;
|
|
const sol = objectClass.GetCurrentSol();
|
|
sol._SetSelectAll(true);
|
|
objectClass.ApplySolToContainer();
|
|
return true
|
|
},
|
|
PickOverlappingPoint(objectClass, x, y) {
|
|
if (!objectClass)
|
|
return false;
|
|
const sol = objectClass.GetCurrentSol();
|
|
const instances = sol.GetInstances();
|
|
const currentEvent = this._runtime.GetCurrentEvent();
|
|
const isOrBlock = currentEvent.IsOrBlock();
|
|
const isInverted = this._runtime.GetCurrentCondition().IsInverted();
|
|
if (sol.IsSelectAll()) {
|
|
C3.shallowAssignArray(tmpPickArray, instances);
|
|
sol.ClearArrays();
|
|
sol._SetSelectAll(false)
|
|
} else if (isOrBlock) {
|
|
C3.shallowAssignArray(tmpPickArray, sol._GetOwnElseInstances());
|
|
C3.clearArray(sol._GetOwnElseInstances())
|
|
} else {
|
|
C3.shallowAssignArray(tmpPickArray, sol._GetOwnInstances());
|
|
C3.clearArray(sol._GetOwnInstances())
|
|
}
|
|
for (let i = 0, len = tmpPickArray.length; i < len; ++i) {
|
|
const inst = tmpPickArray[i];
|
|
if (C3.xor(inst.GetWorldInfo().ContainsPoint(x, y), isInverted))
|
|
sol._PushInstance(inst);
|
|
else
|
|
sol._PushElseInstance(inst)
|
|
}
|
|
objectClass.ApplySolToContainer();
|
|
return C3.xor(!!sol._GetOwnInstances().length, isInverted)
|
|
},
|
|
PickLastCreated(objectClass) {
|
|
if (!objectClass)
|
|
return false;
|
|
const isFamily = objectClass.IsFamily();
|
|
let pick = null;
|
|
const instancesPendingCreate = this._runtime._GetInstancesPendingCreate();
|
|
for (let i = instancesPendingCreate.length - 1; i >= 0; --i) {
|
|
const inst = instancesPendingCreate[i];
|
|
if (isFamily) {
|
|
if (inst.GetObjectClass().BelongsToFamily(objectClass)) {
|
|
pick = inst;
|
|
break
|
|
}
|
|
} else if (inst.GetObjectClass() === objectClass) {
|
|
pick = inst;
|
|
break
|
|
}
|
|
}
|
|
if (!pick) {
|
|
const instances = objectClass.GetInstances();
|
|
if (instances.length)
|
|
pick = instances[instances.length - 1]
|
|
}
|
|
if (!pick)
|
|
return false;
|
|
const sol = objectClass.GetCurrentSol();
|
|
sol.PickOne(pick);
|
|
objectClass.ApplySolToContainer();
|
|
return true
|
|
},
|
|
Repeat(count) {
|
|
if (this._runtime.IsDebugging())
|
|
return this._DebugRepeat(count);
|
|
else
|
|
return this._Repeat(count)
|
|
},
|
|
While() {
|
|
if (this._runtime.IsDebugging())
|
|
return this._DebugWhile();
|
|
else
|
|
return this._While()
|
|
},
|
|
For(name, start, end) {
|
|
if (this._runtime.IsDebugging())
|
|
return this._DebugFor(name, start, end);
|
|
else
|
|
return this._For(name, start, end)
|
|
},
|
|
ForEach(objectClass) {
|
|
if (this._runtime.IsDebugging())
|
|
return this._DebugForEach(objectClass);
|
|
else
|
|
return this._ForEach(objectClass)
|
|
},
|
|
ForEachOrdered(objectClass, expression, order) {
|
|
if (this._runtime.IsDebugging())
|
|
return this._DebugForEachOrdered(objectClass, order);
|
|
else
|
|
return this._ForEachOrdered(objectClass, order)
|
|
},
|
|
LayerVisible(layer) {
|
|
return layer ? layer.IsVisible() : false
|
|
},
|
|
LayerEmpty(layer) {
|
|
return layer ? !layer.GetInstanceCount() : false
|
|
},
|
|
LayerCmpOpacity(layer, cmp, o) {
|
|
if (!layer)
|
|
return false;
|
|
return C3.compare(layer.GetOpacity() * 100, cmp, o)
|
|
},
|
|
OnImageLoadingComplete() {
|
|
return true
|
|
},
|
|
IsLoadingImages() {
|
|
return this._imagesLoadingTotal > 0
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function SortZOrderList(a, b) {
|
|
const layerA = a[0];
|
|
const layerB = b[0];
|
|
const diff = layerA - layerB;
|
|
if (diff !== 0)
|
|
return diff;
|
|
const indexA = a[1];
|
|
const indexB = b[1];
|
|
return indexA - indexB
|
|
}
|
|
function SortInstancesByValue(a, b) {
|
|
return a[1] - b[1]
|
|
}
|
|
const tempZOrderList = [];
|
|
const tempInstValues = [];
|
|
const tempRect = C3.New(C3.Rect);
|
|
const tempColor = C3.New(C3.Color);
|
|
C3.Plugins.System.Acts = {
|
|
SetVar(ev, x) {
|
|
ev.SetValue(x)
|
|
},
|
|
AddVar(ev, x) {
|
|
if (ev.IsNumber() && typeof x !== "number")
|
|
x = parseFloat(x);
|
|
ev.SetValue(ev.GetValue() + x)
|
|
},
|
|
SubVar(ev, x) {
|
|
if (!ev.IsNumber())
|
|
return;
|
|
ev.SetValue(ev.GetValue() - x)
|
|
},
|
|
SetBoolVar(ev, x) {
|
|
ev.SetValue(!!x)
|
|
},
|
|
ToggleBoolVar(ev) {
|
|
ev.SetValue(!ev.GetValue())
|
|
},
|
|
ResetGlobals() {
|
|
this._runtime.GetEventSheetManager().ResetAllGlobalsToInitialValue()
|
|
},
|
|
CreateObject(objectClass, layer, x, y) {
|
|
if (!objectClass || !layer)
|
|
return;
|
|
const inst = this._runtime.CreateInstance(objectClass, layer, x, y);
|
|
if (!inst)
|
|
return;
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
eventSheetManager.BlockFlushingInstances(true);
|
|
inst._TriggerOnCreated();
|
|
if (inst.IsInContainer())
|
|
for (const s of inst.siblings())
|
|
s._TriggerOnCreated();
|
|
eventSheetManager.BlockFlushingInstances(false);
|
|
objectClass.GetCurrentSol().SetSinglePicked(inst);
|
|
if (inst.IsInContainer())
|
|
inst.SetSiblingsSinglePicked()
|
|
},
|
|
CreateObjectByName(objectClassName, layer, x, y) {
|
|
if (!objectClassName || !layer)
|
|
return;
|
|
const objectClass = this._runtime.GetObjectClassByName(objectClassName);
|
|
if (!objectClass)
|
|
return;
|
|
C3.Plugins.System.Acts.CreateObject.call(this, objectClass, layer, x, y)
|
|
},
|
|
RecreateInitialObjects(objectClass, x1, y1, x2, y2, sourceLayoutName, sourceLayerParam, offsetX, offsetY) {
|
|
if (!objectClass)
|
|
return;
|
|
let sourceLayout = this._runtime.GetCurrentLayout();
|
|
if (sourceLayoutName) {
|
|
const lookupLayout = this._runtime.GetLayoutManager().GetLayoutByName(sourceLayoutName);
|
|
if (lookupLayout)
|
|
sourceLayout = lookupLayout;
|
|
else
|
|
return
|
|
}
|
|
let sourceLayer = null;
|
|
if (typeof sourceLayerParam !== "number" || sourceLayerParam >= 0) {
|
|
sourceLayer = sourceLayout.GetLayer(sourceLayerParam);
|
|
if (!sourceLayer)
|
|
return
|
|
}
|
|
tempRect.set(x1, y1, x2, y2);
|
|
const allCreatedInstances = sourceLayout.RecreateInitialObjects(objectClass, tempRect, sourceLayer, offsetX, offsetY);
|
|
objectClass.GetCurrentSol().SetArrayPicked(allCreatedInstances);
|
|
objectClass.ApplySolToContainer()
|
|
},
|
|
StopLoop() {
|
|
const loopStack = this._loopStack;
|
|
if (!loopStack.IsInLoop())
|
|
return;
|
|
loopStack.GetCurrent().Stop()
|
|
},
|
|
SetGroupActive(groupName, a) {
|
|
const group = this._runtime.GetEventSheetManager().GetEventGroupByName(groupName);
|
|
if (!group)
|
|
return;
|
|
if (a === 0)
|
|
group.SetGroupActive(false);
|
|
else if (a === 1)
|
|
group.SetGroupActive(true);
|
|
else
|
|
group.SetGroupActive(!group.IsGroupActive())
|
|
},
|
|
SetTimescale(ts) {
|
|
this._runtime.SetTimeScale(ts)
|
|
},
|
|
SetObjectTimescale(objectClass, ts) {
|
|
if (ts < 0)
|
|
ts = 0;
|
|
if (!objectClass)
|
|
return;
|
|
const sol = objectClass.GetCurrentSol();
|
|
const instances = sol.GetInstances();
|
|
for (const inst of instances)
|
|
inst.SetTimeScale(ts)
|
|
},
|
|
RestoreObjectTimescale(objectClass) {
|
|
if (!objectClass)
|
|
return;
|
|
const sol = objectClass.GetCurrentSol();
|
|
const instances = sol.GetInstances();
|
|
for (const inst of instances)
|
|
inst.RestoreTimeScale()
|
|
},
|
|
Wait(seconds) {
|
|
if (seconds < 0)
|
|
return;
|
|
this._runtime.GetEventSheetManager().AddScheduledWait().InitTimer(seconds);
|
|
return true
|
|
},
|
|
WaitForSignal(tag) {
|
|
this._runtime.GetEventSheetManager().AddScheduledWait().InitSignal(tag);
|
|
return true
|
|
},
|
|
WaitForPreviousActions() {
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
eventSheetManager.AddScheduledWait().InitPromise(eventSheetManager.GetPromiseForAllAsyncActions());
|
|
return true
|
|
},
|
|
Signal(tag) {
|
|
const lowerTag = tag.toLowerCase();
|
|
for (const w of this._runtime.GetEventSheetManager().scheduledWaits())
|
|
if (w.IsSignal() && w.GetSignalTag() === lowerTag)
|
|
w.SetSignalled()
|
|
},
|
|
async SnapshotCanvas(format, quality, x, y, width, height) {
|
|
const canvasManager = this._runtime.GetCanvasManager();
|
|
if (!canvasManager)
|
|
return;
|
|
this.UpdateRender();
|
|
await canvasManager.SnapshotCanvas(format === 0 ? "image/png" : "image/jpeg", quality / 100, x, y, width, height);
|
|
await this._runtime.TriggerAsync(C3.Plugins.System.Cnds.OnCanvasSnapshot, null)
|
|
},
|
|
SetCanvasSize(w, h) {
|
|
if (w <= 0 || h <= 0)
|
|
return;
|
|
this._runtime.SetViewportSize(w, h);
|
|
const currentLayout = this._runtime.GetCurrentLayout();
|
|
currentLayout.BoundScrolling();
|
|
for (const layer of currentLayout.GetLayers())
|
|
layer.UpdateViewport();
|
|
const canvasManager = this._runtime.GetCanvasManager();
|
|
if (!canvasManager)
|
|
return;
|
|
if (canvasManager.GetCurrentFullscreenMode() === "off")
|
|
canvasManager.SetSize(canvasManager.GetLastWidth(), canvasManager.GetLastHeight(), true);
|
|
else {
|
|
this._runtime.SetOriginalViewportSize(w, h);
|
|
canvasManager.SetSize(canvasManager.GetLastWidth(), canvasManager.GetLastHeight(), true)
|
|
}
|
|
this._runtime.UpdateRender()
|
|
},
|
|
SetFullscreenQuality(q) {
|
|
const canvasManager = this._runtime.GetCanvasManager();
|
|
if (!canvasManager)
|
|
return;
|
|
if (canvasManager.GetCurrentFullscreenMode() === "off")
|
|
return;
|
|
canvasManager.SetFullscreenScalingQuality(q !== 0 ? "high" : "low");
|
|
canvasManager.SetSize(canvasManager.GetLastWidth(), canvasManager.GetLastHeight(), true)
|
|
},
|
|
SaveState(slot) {
|
|
this._runtime.SaveToSlot(slot)
|
|
},
|
|
LoadState(slot) {
|
|
this._runtime.LoadFromSlot(slot)
|
|
},
|
|
LoadStateJSON(jsonStr) {
|
|
this._runtime.LoadFromJsonString(jsonStr)
|
|
},
|
|
SetHalfFramerateMode(m) {},
|
|
ResetPersisted() {
|
|
for (const layout of this._runtime.GetLayoutManager().GetAllLayouts())
|
|
layout.ResetPersistData()
|
|
},
|
|
SetPixelRounding(m) {
|
|
this._runtime.SetPixelRoundingEnabled(m !== 0)
|
|
},
|
|
SetMinimumFramerate(fps) {
|
|
this._runtime.SetMinimumFramerate(fps)
|
|
},
|
|
SortZOrderByInstVar(objectClass, instVar) {
|
|
if (!objectClass)
|
|
return;
|
|
const sol = objectClass.GetCurrentSol();
|
|
const pickedInstances = sol.GetInstances();
|
|
const zOrderList = tempZOrderList;
|
|
const instValues = tempInstValues;
|
|
const layout = this._runtime.GetCurrentLayout();
|
|
const isFamily = objectClass.IsFamily();
|
|
const familyIndex = objectClass.GetFamilyIndex();
|
|
for (let i = 0, len = pickedInstances.length; i < len; ++i) {
|
|
const inst = pickedInstances[i];
|
|
const wi = inst.GetWorldInfo();
|
|
if (!wi)
|
|
continue;
|
|
let value;
|
|
if (isFamily)
|
|
value = inst.GetInstanceVariableValue(instVar + inst.GetObjectClass().GetFamilyInstanceVariableOffset(familyIndex));
|
|
else
|
|
value = inst.GetInstanceVariableValue(instVar);
|
|
zOrderList.push([wi.GetLayer().GetIndex(), wi.GetZIndex()]);
|
|
instValues.push([inst, value])
|
|
}
|
|
if (!zOrderList.length)
|
|
return;
|
|
zOrderList.sort(SortZOrderList);
|
|
instValues.sort(SortInstancesByValue);
|
|
let anyChanged = false;
|
|
for (let i = 0, len = zOrderList.length; i < len; ++i) {
|
|
const inst = instValues[i][0];
|
|
const layer = layout.GetLayerByIndex(zOrderList[i][0]);
|
|
const toZ = zOrderList[i][1];
|
|
const layerInstances = layer._GetInstances();
|
|
if (layerInstances[toZ] !== inst) {
|
|
layerInstances[toZ] = inst;
|
|
inst.GetWorldInfo()._SetLayer(layer);
|
|
layer.SetZIndicesChanged();
|
|
anyChanged = true
|
|
}
|
|
}
|
|
if (anyChanged)
|
|
this._runtime.UpdateRender();
|
|
C3.clearArray(tempZOrderList);
|
|
C3.clearArray(tempInstValues)
|
|
},
|
|
GoToLayout(layout) {
|
|
if (this._runtime.IsLoading())
|
|
return;
|
|
const layoutManager = this._runtime.GetLayoutManager();
|
|
if (layoutManager.IsPendingChangeMainLayout())
|
|
return;
|
|
layoutManager.ChangeMainLayout(layout)
|
|
},
|
|
GoToLayoutByName(layoutName) {
|
|
if (this._runtime.IsLoading())
|
|
return;
|
|
const layoutManager = this._runtime.GetLayoutManager();
|
|
if (layoutManager.IsPendingChangeMainLayout())
|
|
return;
|
|
const toLayout = layoutManager.GetLayoutByName(layoutName);
|
|
if (toLayout)
|
|
layoutManager.ChangeMainLayout(toLayout)
|
|
},
|
|
NextPrevLayout(prev) {
|
|
if (this._runtime.IsLoading())
|
|
return;
|
|
const layoutManager = this._runtime.GetLayoutManager();
|
|
if (layoutManager.IsPendingChangeMainLayout())
|
|
return;
|
|
const allLayouts = layoutManager.GetAllLayouts();
|
|
const index = allLayouts.indexOf(layoutManager.GetMainRunningLayout());
|
|
if (prev && index === 0)
|
|
return;
|
|
if (!prev && index === allLayouts.length - 1)
|
|
return;
|
|
const toLayout = allLayouts[index + (prev ? -1 : 1)];
|
|
layoutManager.ChangeMainLayout(toLayout)
|
|
},
|
|
RestartLayout() {
|
|
if (this._runtime.IsLoading())
|
|
return;
|
|
const layoutManager = this._runtime.GetLayoutManager();
|
|
if (layoutManager.IsPendingChangeMainLayout())
|
|
return;
|
|
layoutManager.ChangeMainLayout(layoutManager.GetMainRunningLayout());
|
|
this._runtime.GetEventSheetManager().ResetAllGroupsInitialActivation()
|
|
},
|
|
SetLayerVisible(layer, v) {
|
|
if (!layer)
|
|
return;
|
|
layer.SetVisible(v)
|
|
},
|
|
SetLayerOpacity(layer, o) {
|
|
if (!layer)
|
|
return;
|
|
layer.SetOpacity(o / 100)
|
|
},
|
|
SetLayerScale(layer, s) {
|
|
if (!layer)
|
|
return;
|
|
layer.SetOwnScale(s)
|
|
},
|
|
SetLayerScaleRate(layer, r) {
|
|
if (!layer)
|
|
return;
|
|
layer.SetScaleRate(r)
|
|
},
|
|
SetLayerAngle(layer, a) {
|
|
if (!layer)
|
|
return;
|
|
a = C3.clampAngle(C3.toRadians(+a));
|
|
if (layer.GetOwnAngle() === a)
|
|
return;
|
|
layer.SetAngle(a);
|
|
this.UpdateRender()
|
|
},
|
|
SetLayerParallax(layer, px, py) {
|
|
if (!layer)
|
|
return;
|
|
layer.SetParallax(px / 100, py / 100)
|
|
},
|
|
SetLayerZElevation(layer, z) {
|
|
if (!layer)
|
|
return;
|
|
layer.SetZElevation(z)
|
|
},
|
|
SetLayerBackground(layer, rgb) {
|
|
if (!layer)
|
|
return;
|
|
tempColor.setFromRgbValue(rgb);
|
|
tempColor.clamp();
|
|
const layerBgColor = layer.GetBackgroundColor();
|
|
if (layerBgColor.equalsIgnoringAlpha(tempColor))
|
|
return;
|
|
layerBgColor.copyRgb(tempColor);
|
|
this.UpdateRender()
|
|
},
|
|
SetLayerTransparent(layer, t) {
|
|
if (!layer)
|
|
return;
|
|
t = !!t;
|
|
if (layer.IsTransparent() === t)
|
|
return;
|
|
layer.SetTransparent(t);
|
|
this.UpdateRender()
|
|
},
|
|
SetLayerBlendMode(layer, bm) {
|
|
if (!layer)
|
|
return;
|
|
if (layer.GetBlendMode() === bm)
|
|
return;
|
|
layer.SetBlendMode(bm);
|
|
this.UpdateRender()
|
|
},
|
|
SetLayerEffectEnabled(layer, enabled, effectName) {
|
|
if (!layer)
|
|
return;
|
|
const effectList = layer.GetEffectList();
|
|
const effectType = effectList.GetEffectTypeByName(effectName);
|
|
if (!effectType)
|
|
return;
|
|
const e = enabled === 1;
|
|
if (effectType.IsActive() === e)
|
|
return;
|
|
effectType.SetActive(e);
|
|
effectList.UpdateActiveEffects();
|
|
this._runtime.UpdateRender()
|
|
},
|
|
SetLayerEffectParam(layer, effectName, paramIndex, value) {
|
|
if (!layer)
|
|
return;
|
|
const effectList = layer.GetEffectList();
|
|
const effectType = effectList.GetEffectTypeByName(effectName);
|
|
if (!effectType)
|
|
return;
|
|
const effectTypeIndex = effectType.GetIndex();
|
|
const paramsArr = effectList.GetEffectParametersForIndex(effectTypeIndex);
|
|
paramIndex = Math.floor(paramIndex);
|
|
if (paramIndex < 0 || paramIndex >= paramsArr.length)
|
|
return;
|
|
const paramType = effectType.GetShaderProgram().GetParameterType(paramIndex);
|
|
if (paramType === "color") {
|
|
tempColor.setFromRgbValue(value);
|
|
const curColor = paramsArr[paramIndex];
|
|
if (tempColor.equalsIgnoringAlpha(curColor))
|
|
return;
|
|
curColor.copyRgb(tempColor)
|
|
} else {
|
|
if (paramType === "percent")
|
|
value /= 100;
|
|
if (paramsArr[paramIndex] === value)
|
|
return;
|
|
paramsArr[paramIndex] = value
|
|
}
|
|
if (effectType.IsActive())
|
|
this._runtime.UpdateRender()
|
|
},
|
|
SetLayerForceOwnTexture(layer, f) {
|
|
if (!layer)
|
|
return;
|
|
f = !!f;
|
|
if (layer.IsForceOwnTexture() === f)
|
|
return;
|
|
layer.SetForceOwnTexture(f);
|
|
this.UpdateRender()
|
|
},
|
|
SetLayoutScale(s) {
|
|
const layout = this._runtime.GetCurrentLayout();
|
|
if (layout.GetScale() === s)
|
|
return;
|
|
layout.SetScale(s);
|
|
this.UpdateRender()
|
|
},
|
|
SetLayoutAngle(a) {
|
|
a = C3.clampAngle(C3.toRadians(+a));
|
|
const layout = this._runtime.GetCurrentLayout();
|
|
if (layout.GetAngle() === a)
|
|
return;
|
|
layout.SetAngle(a);
|
|
this.UpdateRender()
|
|
},
|
|
SetLayoutEffectEnabled(enabled, effectName) {
|
|
const layout = this._runtime.GetCurrentLayout();
|
|
const effectList = layout.GetEffectList();
|
|
const effectType = effectList.GetEffectTypeByName(effectName);
|
|
if (!effectType)
|
|
return;
|
|
const e = enabled === 1;
|
|
if (effectType.IsActive() === e)
|
|
return;
|
|
effectType.SetActive(e);
|
|
effectList.UpdateActiveEffects();
|
|
this._runtime.UpdateRender()
|
|
},
|
|
SetLayoutEffectParam(effectName, paramIndex, value) {
|
|
const layout = this._runtime.GetCurrentLayout();
|
|
const effectList = layout.GetEffectList();
|
|
const effectType = effectList.GetEffectTypeByName(effectName);
|
|
if (!effectType)
|
|
return;
|
|
const effectTypeIndex = effectType.GetIndex();
|
|
const paramsArr = effectList.GetEffectParametersForIndex(effectTypeIndex);
|
|
paramIndex = Math.floor(paramIndex);
|
|
if (paramIndex < 0 || paramIndex >= paramsArr.length)
|
|
return;
|
|
const paramType = effectType.GetShaderProgram().GetParameterType(paramIndex);
|
|
if (paramType === "color") {
|
|
tempColor.setFromRgbValue(value);
|
|
const curColor = paramsArr[paramIndex];
|
|
if (tempColor.equalsIgnoringAlpha(curColor))
|
|
return;
|
|
curColor.copyRgb(tempColor)
|
|
} else {
|
|
if (paramType === "percent")
|
|
value /= 100;
|
|
if (paramsArr[paramIndex] === value)
|
|
return;
|
|
paramsArr[paramIndex] = value
|
|
}
|
|
if (effectType.IsActive())
|
|
this._runtime.UpdateRender()
|
|
},
|
|
ScrollX(x) {
|
|
const layout = this._runtime.GetCurrentLayout();
|
|
layout.SetScrollX(x)
|
|
},
|
|
ScrollY(y) {
|
|
const layout = this._runtime.GetCurrentLayout();
|
|
layout.SetScrollY(y)
|
|
},
|
|
Scroll(x, y) {
|
|
const layout = this._runtime.GetCurrentLayout();
|
|
layout.SetScrollX(x);
|
|
layout.SetScrollY(y)
|
|
},
|
|
ScrollToObject(objectClass) {
|
|
if (!objectClass)
|
|
return;
|
|
const inst = objectClass.GetFirstPicked();
|
|
if (!inst)
|
|
return;
|
|
const wi = inst.GetWorldInfo();
|
|
if (!wi)
|
|
return;
|
|
const layout = this._runtime.GetCurrentLayout();
|
|
layout.SetScrollX(wi.GetX());
|
|
layout.SetScrollY(wi.GetY())
|
|
},
|
|
async LoadObjectTextures(objectClass) {
|
|
const layout = this._runtime.GetMainRunningLayout();
|
|
if (!layout || !objectClass || this._runtime.IsLoading())
|
|
return;
|
|
const objectClasses = objectClass.IsFamily() ? objectClass.GetFamilyMembers() : [objectClass];
|
|
await this._LoadTexturesForObjectClasses(layout, objectClasses)
|
|
},
|
|
async LoadObjectTexturesByName(objectClassName) {
|
|
await C3.Plugins.System.Acts.LoadObjectTextures.call(this, this._runtime.GetObjectClassByName(objectClassName))
|
|
},
|
|
UnloadObjectTextures(objectClass) {
|
|
const layout = this._runtime.GetMainRunningLayout();
|
|
if (!layout || !objectClass)
|
|
return;
|
|
const objectClasses = objectClass.IsFamily() ? objectClass.GetFamilyMembers() : [objectClass];
|
|
this._UnloadTexturesForObjectClasses(layout, objectClasses)
|
|
},
|
|
UnloadObjectTexturesByName(objectClassName) {
|
|
C3.Plugins.System.Acts.UnloadObjectTexturesByName.call(this, this._runtime.GetObjectClassByName(objectClassName))
|
|
},
|
|
UnloadUnusedTextures() {
|
|
const layout = this._runtime.GetMainRunningLayout();
|
|
if (!layout)
|
|
return;
|
|
const objectClasses = layout._GetTextureLoadedObjectTypes();
|
|
this._UnloadTexturesForObjectClasses(layout, objectClasses)
|
|
},
|
|
async LoadLayoutTextures(loadLayout) {
|
|
const curLayout = this._runtime.GetMainRunningLayout();
|
|
if (!loadLayout || !curLayout || this._runtime.IsLoading())
|
|
return;
|
|
await this._LoadTexturesForObjectClasses(curLayout, loadLayout._GetInitialObjectClasses())
|
|
},
|
|
async LoadLayoutTexturesByName(layoutName) {
|
|
const curLayout = this._runtime.GetMainRunningLayout();
|
|
const loadLayout = this._runtime.GetLayoutManager().GetLayoutByName(layoutName);
|
|
if (!loadLayout || !curLayout || this._runtime.IsLoading())
|
|
return;
|
|
await this._LoadTexturesForObjectClasses(curLayout, loadLayout._GetInitialObjectClasses())
|
|
},
|
|
SetFunctionReturnValue(v) {
|
|
const frame = this._eventStack.GetCurrentExpFuncStackFrame();
|
|
if (!frame)
|
|
return;
|
|
switch (frame.GetFunctionReturnType()) {
|
|
case 1:
|
|
if (typeof v === "number")
|
|
frame.SetFunctionReturnValue(v);
|
|
break;
|
|
case 2:
|
|
if (typeof v === "string")
|
|
frame.SetFunctionReturnValue(v);
|
|
break;
|
|
case 3:
|
|
frame.SetFunctionReturnValue(v);
|
|
break
|
|
}
|
|
},
|
|
MapFunction(name, str, functionBlock) {
|
|
const mapEntry = this._GetFunctionMap(name.toLowerCase(), true);
|
|
const strMap = mapEntry.strMap;
|
|
const lowerStr = str.toLowerCase();
|
|
if (strMap.has(lowerStr))
|
|
console.warn(`[Construct 3] Function map '${name}' string '${str}' already in map; overwriting entry`);
|
|
const firstFunctionBlock = C3.first(strMap.values()) || mapEntry.defaultFunc;
|
|
if (firstFunctionBlock) {
|
|
const firstReturnsValue = firstFunctionBlock.GetReturnType() !== 0;
|
|
const curReturnsValue = functionBlock.GetReturnType() !== 0;
|
|
if (firstReturnsValue !== curReturnsValue) {
|
|
console.error(`[Construct 3] Function map '${name}' string '${str}' function return type not compatible with other functions in the map; entry ignored`);
|
|
return
|
|
}
|
|
}
|
|
strMap.set(lowerStr, functionBlock)
|
|
},
|
|
MapFunctionDefault(name, functionBlock) {
|
|
const mapEntry = this._GetFunctionMap(name.toLowerCase(), true);
|
|
if (mapEntry.defaultFunc)
|
|
console.warn(`[Construct 3] Function map '${name}' already has a default; overwriting entry`);
|
|
const firstFunctionBlock = C3.first(mapEntry.strMap.values()) || mapEntry.defaultFunc;
|
|
if (firstFunctionBlock) {
|
|
const firstReturnsValue = firstFunctionBlock.GetReturnType() !== 0;
|
|
const curReturnsValue = functionBlock.GetReturnType() !== 0;
|
|
if (firstReturnsValue !== curReturnsValue) {
|
|
console.error(`[Construct 3] Function map '${name}' default: function return type not compatible with other functions in the map; entry ignored`);
|
|
return
|
|
}
|
|
}
|
|
mapEntry.defaultFunc = functionBlock
|
|
},
|
|
CallMappedFunction(name, str, forwardParams) {
|
|
forwardParams = Math.floor(forwardParams);
|
|
const mapEntry = this._GetFunctionMap(name.toLowerCase(), false);
|
|
if (!mapEntry) {
|
|
console.warn(`[Construct 3] Call mapped function: map name '${name}' not found; call ignored`);
|
|
return
|
|
}
|
|
let functionBlock = mapEntry.strMap.get(str.toLowerCase());
|
|
if (!functionBlock)
|
|
if (mapEntry.defaultFunc) {
|
|
functionBlock = mapEntry.defaultFunc;
|
|
forwardParams = 0
|
|
} else {
|
|
console.warn(`[Construct 3] Call mapped function: no function associated with map '${name}' string '${str}'; call ignored (consider setting a default)`);
|
|
return
|
|
}
|
|
if (!functionBlock.IsEnabled())
|
|
return;
|
|
if (functionBlock.GetReturnType() !== 0) {
|
|
console.warn(`[Construct 3] Call mapped function: map '${name}' string '${str}' has a return type so cannot be called`);
|
|
return
|
|
}
|
|
const runtime = this._runtime;
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const currentEvent = eventSheetManager.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiersIncludingParents();
|
|
const hasAnySolModifiers = solModifiers.length > 0;
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PushCleanSol(solModifiers);
|
|
const paramResults = [];
|
|
const callerFunctionBlock = eventSheetManager.FindFirstFunctionBlockParent(currentEvent);
|
|
if (callerFunctionBlock) {
|
|
const callerParameters = callerFunctionBlock.GetFunctionParameters();
|
|
for (let i = forwardParams, len = callerParameters.length; i < len; ++i)
|
|
paramResults.push(callerParameters[i].GetValue())
|
|
}
|
|
const calleeParameters = functionBlock.GetFunctionParameters();
|
|
for (let i = paramResults.length, len = calleeParameters.length; i < len; ++i)
|
|
paramResults.push(calleeParameters[i].GetInitialValue());
|
|
if (runtime.IsDebugging())
|
|
return this._DebugDoCallMappedFunction(eventSheetManager, functionBlock, paramResults, hasAnySolModifiers, solModifiers);
|
|
else
|
|
return this._DoCallMappedFunction(eventSheetManager, functionBlock, paramResults, hasAnySolModifiers, solModifiers)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.System.Exps = {
|
|
int: function(x) {
|
|
if (typeof x === "string") {
|
|
x = parseInt(x, 10);
|
|
if (isNaN(x))
|
|
x = 0
|
|
}
|
|
return Math.floor(x)
|
|
},
|
|
float: function(x) {
|
|
if (typeof x === "string") {
|
|
x = parseFloat(x);
|
|
if (isNaN(x))
|
|
x = 0
|
|
}
|
|
return x
|
|
},
|
|
str(x) {
|
|
return x.toString()
|
|
},
|
|
len(x) {
|
|
if (typeof x === "string")
|
|
return x.length;
|
|
else
|
|
return 0
|
|
},
|
|
random(a, b) {
|
|
if (typeof b === "undefined")
|
|
return this._runtime.Random() * a;
|
|
else
|
|
return this._runtime.Random() * (b - a) + a
|
|
},
|
|
choose(...args) {
|
|
const index = Math.floor(this._runtime.Random() * args.length);
|
|
return args[index]
|
|
},
|
|
pi() {
|
|
return Math.PI
|
|
},
|
|
infinity() {
|
|
return Infinity
|
|
},
|
|
sqrt(v) {
|
|
return Math.sqrt(v)
|
|
},
|
|
abs(v) {
|
|
return Math.abs(v)
|
|
},
|
|
round(v) {
|
|
return Math.round(v)
|
|
},
|
|
floor(v) {
|
|
return Math.floor(v)
|
|
},
|
|
ceil(v) {
|
|
return Math.ceil(v)
|
|
},
|
|
sign(v) {
|
|
return Math.sign(v)
|
|
},
|
|
sin(x) {
|
|
return Math.sin(C3.toRadians(x))
|
|
},
|
|
cos(x) {
|
|
return Math.cos(C3.toRadians(x))
|
|
},
|
|
tan(x) {
|
|
return Math.tan(C3.toRadians(x))
|
|
},
|
|
asin(x) {
|
|
return C3.toDegrees(Math.asin(x))
|
|
},
|
|
acos(x) {
|
|
return C3.toDegrees(Math.acos(x))
|
|
},
|
|
atan(x) {
|
|
return C3.toDegrees(Math.atan(x))
|
|
},
|
|
exp(x) {
|
|
return Math.exp(x)
|
|
},
|
|
ln(x) {
|
|
return Math.log(x)
|
|
},
|
|
log10(x) {
|
|
return Math.log(x) / Math.LN10
|
|
},
|
|
max(...args) {
|
|
let ret = args[0];
|
|
if (typeof ret !== "number")
|
|
ret = 0;
|
|
for (let i = 1, len = args.length; i < len; ++i) {
|
|
let n = args[i];
|
|
if (typeof n !== "number")
|
|
continue;
|
|
if (ret < n)
|
|
ret = n
|
|
}
|
|
return ret
|
|
},
|
|
min(...args) {
|
|
let ret = args[0];
|
|
if (typeof ret !== "number")
|
|
ret = 0;
|
|
for (let i = 1, len = args.length; i < len; ++i) {
|
|
let n = args[i];
|
|
if (typeof n !== "number")
|
|
continue;
|
|
if (ret > n)
|
|
ret = n
|
|
}
|
|
return ret
|
|
},
|
|
clamp(x, l, u) {
|
|
return C3.clamp(x, l, u)
|
|
},
|
|
distance(x1, y1, x2, y2) {
|
|
return C3.distanceTo(x1, y1, x2, y2)
|
|
},
|
|
angle(x1, y1, x2, y2) {
|
|
return C3.toDegrees(C3.angleTo(x1, y1, x2, y2))
|
|
},
|
|
lerp(a, b, x) {
|
|
return C3.lerp(a, b, x)
|
|
},
|
|
unlerp(a, b, y) {
|
|
return C3.unlerp(a, b, y)
|
|
},
|
|
qarp(a, b, c, x) {
|
|
return C3.qarp(a, b, c, x)
|
|
},
|
|
cubic(a, b, c, d, x) {
|
|
return C3.cubic(a, b, c, d, x)
|
|
},
|
|
cosp(a, b, x) {
|
|
return C3.cosp(a, b, x)
|
|
},
|
|
anglediff(a, b) {
|
|
return C3.toDegrees(C3.angleDiff(C3.toRadians(a), C3.toRadians(b)))
|
|
},
|
|
anglelerp(a, b, x) {
|
|
return C3.toDegrees(C3.angleLerp(C3.toRadians(a), C3.toRadians(b), x))
|
|
},
|
|
anglerotate(a, b, c) {
|
|
return C3.toDegrees(C3.angleRotate(C3.toRadians(a), C3.toRadians(b), C3.toRadians(c)))
|
|
},
|
|
setbit(n, b, v) {
|
|
n = n | 0;
|
|
b = b | 0;
|
|
v = v !== 0 ? 1 : 0;
|
|
return n & ~(1 << b) | v << b
|
|
},
|
|
togglebit(n, b) {
|
|
n = n | 0;
|
|
b = b | 0;
|
|
return n ^ 1 << b
|
|
},
|
|
getbit(n, b) {
|
|
n = n | 0;
|
|
b = b | 0;
|
|
return n & 1 << b ? 1 : 0
|
|
},
|
|
newline() {
|
|
return "\n"
|
|
},
|
|
uppercase(s) {
|
|
return typeof s === "string" ? s.toUpperCase() : ""
|
|
},
|
|
lowercase(s) {
|
|
return typeof s === "string" ? s.toLowerCase() : ""
|
|
},
|
|
left(text, n) {
|
|
return typeof text === "string" ? text.substr(0, n) : ""
|
|
},
|
|
mid(text, index, count) {
|
|
if (typeof text !== "string")
|
|
return "";
|
|
if (count < 0)
|
|
return text.substr(index);
|
|
else
|
|
return text.substr(index, count)
|
|
},
|
|
right(text, n) {
|
|
return typeof text === "string" ? text.substr(text.length - n) : ""
|
|
},
|
|
trim(text) {
|
|
return typeof text === "string" ? text.trim() : ""
|
|
},
|
|
tokenat(text, index, sep) {
|
|
if (typeof text !== "string" || typeof sep !== "string")
|
|
return "";
|
|
let arr = text.split(sep);
|
|
index = Math.floor(index);
|
|
if (index < 0 || index >= arr.length)
|
|
return "";
|
|
return arr[index]
|
|
},
|
|
tokencount(text, sep) {
|
|
if (typeof text !== "string" || typeof sep !== "string" || !text.length)
|
|
return 0;
|
|
return text.split(sep).length
|
|
},
|
|
find(text, searchStr) {
|
|
if (typeof text === "string" && typeof searchStr === "string")
|
|
return text.search(new RegExp(C3.EscapeRegex(searchStr),"i"));
|
|
else
|
|
return -1
|
|
},
|
|
findcase(text, searchStr) {
|
|
if (typeof text === "string" && typeof searchStr === "string")
|
|
return text.search(new RegExp(C3.EscapeRegex(searchStr),""));
|
|
else
|
|
return -1
|
|
},
|
|
replace(text, find, replace) {
|
|
if (typeof text === "string" && typeof find === "string" && typeof replace === "string")
|
|
return text.replace(new RegExp(C3.EscapeRegex(find),"gi"), replace);
|
|
else
|
|
return typeof text === "string" ? text : ""
|
|
},
|
|
regexsearch(text, regex, flags) {
|
|
const cacheRegex = this.GetRegex(regex, flags);
|
|
return text ? text.search(cacheRegex) : -1
|
|
},
|
|
regexreplace(text, regex, flags, replace) {
|
|
const cacheRegex = this.GetRegex(regex, flags);
|
|
return text ? text.replace(cacheRegex, replace) : ""
|
|
},
|
|
regexmatchcount(text, regex, flags) {
|
|
const matches = this.GetRegexMatches(text.toString(), regex, flags);
|
|
return matches ? matches.length : 0
|
|
},
|
|
regexmatchat(text, regex, flags, index) {
|
|
index = Math.floor(index);
|
|
const matches = this.GetRegexMatches(text.toString(), regex, flags);
|
|
if (!matches || index < 0 || index >= matches.length)
|
|
return "";
|
|
else
|
|
return matches[index]
|
|
},
|
|
zeropad(n, d) {
|
|
let s = n < 0 ? "-" : "";
|
|
if (n < 0)
|
|
n = -n;
|
|
const zeroes = d - n.toString().length;
|
|
s += "0".repeat(Math.max(zeroes, 0));
|
|
return s + n.toString()
|
|
},
|
|
urlencode(s) {
|
|
return encodeURIComponent(s)
|
|
},
|
|
urldecode(s) {
|
|
return decodeURIComponent(s)
|
|
},
|
|
dt() {
|
|
return this._runtime._GetDtFast()
|
|
},
|
|
timescale() {
|
|
return this._runtime.GetTimeScale()
|
|
},
|
|
wallclocktime() {
|
|
return (Date.now() - this._runtime.GetStartTime()) / 1E3
|
|
},
|
|
unixtime() {
|
|
return Date.now()
|
|
},
|
|
time() {
|
|
return this._runtime.GetGameTime()
|
|
},
|
|
tickcount() {
|
|
return this._runtime.GetTickCount()
|
|
},
|
|
objectcount() {
|
|
return this._runtime.GetObjectCount()
|
|
},
|
|
fps() {
|
|
return this._runtime.GetFPS()
|
|
},
|
|
cpuutilisation() {
|
|
return this._runtime.GetMainThreadTime()
|
|
},
|
|
gpuutilisation() {
|
|
return this._runtime.GetGPUUtilisation()
|
|
},
|
|
windowwidth() {
|
|
return this._runtime.GetCanvasManager().GetDeviceWidth()
|
|
},
|
|
windowheight() {
|
|
return this._runtime.GetCanvasManager().GetDeviceHeight()
|
|
},
|
|
originalwindowwidth() {
|
|
return this._runtime.GetOriginalViewportWidth()
|
|
},
|
|
originalwindowheight() {
|
|
return this._runtime.GetOriginalViewportHeight()
|
|
},
|
|
originalviewportwidth() {
|
|
return this._runtime.GetOriginalViewportWidth()
|
|
},
|
|
originalviewportheight() {
|
|
return this._runtime.GetOriginalViewportHeight()
|
|
},
|
|
scrollx() {
|
|
return this._runtime.GetCurrentLayout().GetScrollX()
|
|
},
|
|
scrolly() {
|
|
return this._runtime.GetCurrentLayout().GetScrollY()
|
|
},
|
|
layoutname() {
|
|
return this._runtime.GetCurrentLayout().GetName()
|
|
},
|
|
layoutscale() {
|
|
return this._runtime.GetCurrentLayout().GetScale()
|
|
},
|
|
layoutangle() {
|
|
return C3.toDegrees(this._runtime.GetCurrentLayout().GetAngle())
|
|
},
|
|
layoutwidth() {
|
|
return this._runtime.GetCurrentLayout().GetWidth()
|
|
},
|
|
layoutheight() {
|
|
return this._runtime.GetCurrentLayout().GetHeight()
|
|
},
|
|
viewportleft(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetViewport().getLeft() : 0
|
|
},
|
|
viewporttop(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetViewport().getTop() : 0
|
|
},
|
|
viewportright(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetViewport().getRight() : 0
|
|
},
|
|
viewportbottom(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetViewport().getBottom() : 0
|
|
},
|
|
viewportwidth(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetViewport().width() : 0
|
|
},
|
|
viewportheight(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetViewport().height() : 0
|
|
},
|
|
canvastolayerx(layerParam, x, y) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.CanvasCssToLayer(x, y)[0] : 0
|
|
},
|
|
canvastolayery(layerParam, x, y) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.CanvasCssToLayer(x, y)[1] : 0
|
|
},
|
|
layertocanvasx(layerParam, x, y) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.LayerToCanvasCss(x, y)[0] : 0
|
|
},
|
|
layertocanvasy(layerParam, x, y) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.LayerToCanvasCss(x, y)[1] : 0
|
|
},
|
|
layerscale(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetOwnScale() : 0
|
|
},
|
|
layerangle(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? C3.toDegrees(layer.GetOwnAngle()) : 0
|
|
},
|
|
layeropacity(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetOpacity() * 100 : 0
|
|
},
|
|
layerscalerate(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetScaleRate() : 0
|
|
},
|
|
layerparallaxx(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetParallaxX() * 100 : 0
|
|
},
|
|
layerparallaxy(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetParallaxY() * 100 : 0
|
|
},
|
|
layerzelevation(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetZElevation() : 0
|
|
},
|
|
layerindex(layerParam) {
|
|
const layer = this._runtime.GetCurrentLayout().GetLayer(layerParam);
|
|
return layer ? layer.GetIndex() : -1
|
|
},
|
|
canvassnapshot() {
|
|
const canvasManager = this._runtime.GetCanvasManager();
|
|
if (!canvasManager)
|
|
return "";
|
|
return canvasManager.GetCanvasSnapshotUrl()
|
|
},
|
|
loopindex(name) {
|
|
const loopStack = this._loopStack;
|
|
if (!loopStack.IsInLoop())
|
|
return 0;
|
|
if (name) {
|
|
const loop = loopStack.FindByName(name);
|
|
return loop ? loop.GetIndex() : 0
|
|
} else
|
|
return loopStack.GetCurrent().GetIndex()
|
|
},
|
|
savestatejson() {
|
|
return this._runtime.GetLastSaveJsonString()
|
|
},
|
|
callmapped(name, str, ...paramResults) {
|
|
const mapEntry = this._GetFunctionMap(name.toLowerCase(), false);
|
|
if (!mapEntry) {
|
|
console.warn(`[Construct 3] Call mapped function: map name '${name}' not found; returning 0`);
|
|
return 0
|
|
}
|
|
let functionBlock = mapEntry.strMap.get(str.toLowerCase());
|
|
if (!functionBlock)
|
|
if (mapEntry.defaultFunc)
|
|
functionBlock = mapEntry.defaultFunc;
|
|
else {
|
|
console.warn(`[Construct 3] Call mapped function: no function associated with map '${name}' string '${str}'; returning 0 (consider setting a default)`);
|
|
return 0
|
|
}
|
|
const returnType = functionBlock.GetReturnType();
|
|
const defaultReturnValue = functionBlock.GetDefaultReturnValue();
|
|
if (returnType === 0) {
|
|
console.warn(`[Construct 3] Call mapped function: map '${name}' string '${str}' has no return type so cannot be called from an expression; returning 0`);
|
|
return 0
|
|
}
|
|
if (!functionBlock.IsEnabled())
|
|
return defaultReturnValue;
|
|
const runtime = this._runtime;
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const currentEvent = eventSheetManager.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiersIncludingParents();
|
|
const hasAnySolModifiers = solModifiers.length > 0;
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PushCleanSol(solModifiers);
|
|
const calleeParameters = functionBlock.GetFunctionParameters();
|
|
for (let i = paramResults.length, len = calleeParameters.length; i < len; ++i)
|
|
paramResults.push(calleeParameters[i].GetInitialValue());
|
|
const callEventBlock = functionBlock.GetEventBlock();
|
|
const returnValue = callEventBlock.RunAsExpressionFunctionCall(callEventBlock.GetSolModifiersIncludingParents(), returnType, defaultReturnValue, ...paramResults);
|
|
if (hasAnySolModifiers)
|
|
eventSheetManager.PopSol(solModifiers);
|
|
return returnValue
|
|
},
|
|
loadingprogress() {
|
|
return this._runtime.GetAssetManager().GetLoadProgress()
|
|
},
|
|
imageloadingprogress() {
|
|
if (this._imagesLoadingTotal === 0)
|
|
return 1;
|
|
return this._imagesLoadingComplete / this._imagesLoadingTotal
|
|
},
|
|
renderer() {
|
|
return "webgl"
|
|
},
|
|
rendererdetail() {
|
|
return this._runtime.GetWebGLRenderer().GetUnmaskedRenderer()
|
|
},
|
|
imagememoryusage() {
|
|
let ret = this._runtime.GetWebGLRenderer().GetEstimatedTextureMemoryUsage();
|
|
return Math.round(100 * ret / (1024 * 1024)) / 100
|
|
},
|
|
rgb(r, g, b) {
|
|
return C3.PackRGB(r, g, b)
|
|
},
|
|
rgbex(r, g, b) {
|
|
return C3.PackRGBEx(r / 100, g / 100, b / 100)
|
|
},
|
|
rgba(r, g, b, a) {
|
|
return C3.PackRGBAEx(r / 100, g / 100, b / 100, a / 100)
|
|
},
|
|
rgbex255(r, g, b) {
|
|
return C3.PackRGBEx(r / 255, g / 255, b / 255)
|
|
},
|
|
rgba255(r, g, b, a) {
|
|
return C3.PackRGBAEx(r / 255, g / 255, b / 255, a / 255)
|
|
},
|
|
projectname() {
|
|
return this._runtime.GetProjectName()
|
|
},
|
|
projectversion() {
|
|
return this._runtime.GetProjectVersion()
|
|
},
|
|
currenteventsheetname() {
|
|
return this._runtime.GetCurrentEvent().GetEventSheet().GetName()
|
|
},
|
|
currenteventnumber() {
|
|
return this._runtime.GetCurrentEvent().GetDisplayNumber()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Spritefont2 = class SpriteFontPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Spritefont2.Type = class SpriteFontType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass);
|
|
this._spriteFont = C3.New(self.SpriteFont)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {
|
|
this.GetImageInfo().LoadAsset(this._runtime)
|
|
}
|
|
LoadTextures(renderer) {
|
|
return this.GetImageInfo().LoadStaticTexture(renderer, {
|
|
sampling: this._runtime.GetSampling()
|
|
})
|
|
}
|
|
ReleaseTextures() {
|
|
this.GetImageInfo().ReleaseTexture()
|
|
}
|
|
GetSpriteFont() {
|
|
return this._spriteFont
|
|
}
|
|
UpdateSettings(characterWidth, characterHeight, characterSet, spacingData) {
|
|
const imageInfo = this.GetImageInfo();
|
|
const sf = this._spriteFont;
|
|
sf.SetWidth(imageInfo.GetWidth());
|
|
sf.SetHeight(imageInfo.GetHeight());
|
|
sf.SetCharacterWidth(characterWidth);
|
|
sf.SetCharacterHeight(characterHeight);
|
|
sf.SetCharacterSet(characterSet);
|
|
sf.SetSpacingData(spacingData);
|
|
sf.UpdateCharacterMap()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const TEXT = 0;
|
|
const ENABLE_BBCODE = 1;
|
|
const CHARACTER_WIDTH = 2;
|
|
const CHARACTER_HEIGHT = 3;
|
|
const CHARACTER_SET = 4;
|
|
const SPACING_DATA = 5;
|
|
const SCALE = 6;
|
|
const CHARACTER_SPACING = 7;
|
|
const LINE_HEIGHT = 8;
|
|
const HORIZONTAL_ALIGNMENT = 9;
|
|
const VERTICAL_ALIGNMENT = 10;
|
|
const WRAPPING = 11;
|
|
const INITIALLY_VISIBLE = 12;
|
|
const ORIGIN = 13;
|
|
const HORIZONTAL_ALIGNMENTS = ["left", "center", "right"];
|
|
const VERTICAL_ALIGNMENTS = ["top", "center", "bottom"];
|
|
const WORD_WRAP = 0;
|
|
const CHARACTER_WRAP = 1;
|
|
C3.Plugins.Spritefont2.Instance = class SpriteFontInstance extends C3.SDKWorldInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this._text = "";
|
|
this._enableBBcode = true;
|
|
this._characterWidth = 16;
|
|
this._characterHeight = 16;
|
|
this._characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:?!-_~#\"'&()[]|`\\/@\u00b0+=*$\u00a3\u20ac<>";
|
|
let spacingData = "";
|
|
this._characterScale = 1;
|
|
this._characterSpacing = 0;
|
|
this._lineHeight = 0;
|
|
this._horizontalAlign = 0;
|
|
this._verticalAlign = 0;
|
|
this._wrapByWord = true;
|
|
this._spriteFontText = null;
|
|
this._typewriterStartTime = -1;
|
|
this._typewriterEndTime = -1;
|
|
this._typewriterLength = 0;
|
|
if (properties) {
|
|
this._text = properties[0];
|
|
this._enableBBcode = properties[1];
|
|
this._characterWidth = properties[2];
|
|
this._characterHeight = properties[3];
|
|
this._characterSet = properties[4];
|
|
spacingData = properties[5];
|
|
this._characterScale = properties[6];
|
|
this._characterSpacing = properties[7];
|
|
this._lineHeight = properties[8];
|
|
this._horizontalAlign = properties[9];
|
|
this._verticalAlign = properties[10];
|
|
this._wrapByWord = properties[11] === 0;
|
|
const wi = this.GetWorldInfo();
|
|
wi.SetVisible(properties[12])
|
|
}
|
|
this._sdkType.UpdateSettings(this._characterWidth, this._characterHeight, this._characterSet, spacingData);
|
|
this._spriteFontText = C3.New(self.SpriteFontText, this._sdkType.GetSpriteFont());
|
|
const wi = this.GetWorldInfo();
|
|
this._spriteFontText.SetSize(wi.GetWidth(), wi.GetHeight());
|
|
this._UpdateSettings()
|
|
}
|
|
Release() {
|
|
this._CancelTypewriter();
|
|
this._spriteFontText.Release();
|
|
this._spriteFontText = null;
|
|
super.Release()
|
|
}
|
|
_UpdateSettings() {
|
|
const sft = this._spriteFontText;
|
|
if (!sft)
|
|
return;
|
|
sft.SetBBCodeEnabled(this._enableBBcode);
|
|
sft.SetText(this._text);
|
|
sft.SetWordWrapMode(this._wrapByWord ? "word" : "character");
|
|
sft.SetHorizontalAlign(HORIZONTAL_ALIGNMENTS[this._horizontalAlign]);
|
|
sft.SetVerticalAlign(VERTICAL_ALIGNMENTS[this._verticalAlign]);
|
|
sft.SetSpacing(this._characterSpacing);
|
|
sft.SetLineHeight(this._lineHeight)
|
|
}
|
|
Draw(renderer) {
|
|
const imageInfo = this._objectClass.GetImageInfo();
|
|
const texture = imageInfo.GetTexture();
|
|
if (!texture)
|
|
return;
|
|
renderer.SetTexture(texture);
|
|
const wi = this.GetWorldInfo();
|
|
let q = wi.GetBoundingQuad();
|
|
const sft = this._spriteFontText;
|
|
sft.SetScale(this._characterScale * wi.GetSceneGraphScale());
|
|
if (this._runtime.IsPixelRoundingEnabled())
|
|
q = wi.PixelRoundQuad(q);
|
|
sft.SetSize(wi.GetWidth(), wi.GetHeight());
|
|
sft.GetSpriteFont().SetTexRect(imageInfo.GetTexRect());
|
|
sft.SetColor(wi.GetUnpremultipliedColor());
|
|
sft.Draw(renderer, q.getTlx(), q.getTly(), wi.GetAngle())
|
|
}
|
|
SaveToJson() {
|
|
const ret = {
|
|
"t": this._text,
|
|
"ebbc": this._enableBBcode,
|
|
"csc": this._characterScale,
|
|
"csp": this._characterSpacing,
|
|
"lh": this._lineHeight,
|
|
"ha": this._horizontalAlign,
|
|
"va": this._verticalAlign,
|
|
"w": this._wrapByWord,
|
|
"cw": this._sdkType.GetSpriteFont().GetCharacterWidth(),
|
|
"ch": this._sdkType.GetSpriteFont().GetCharacterHeight(),
|
|
"cs": this._sdkType.GetSpriteFont().GetCharacterSet(),
|
|
"sd": this._sdkType.GetSpriteFont().GetSpacingData()
|
|
};
|
|
if (this._typewriterEndTime !== -1)
|
|
ret["tw"] = {
|
|
"st": this._typewriterStartTime,
|
|
"en": this._typewriterEndTime,
|
|
"l": this._typewriterLength
|
|
};
|
|
return ret
|
|
}
|
|
LoadFromJson(o) {
|
|
this._CancelTypewriter();
|
|
this._text = o["t"];
|
|
this._enableBBcode = o["ebbc"];
|
|
this._characterScale = o["csc"];
|
|
this._characterSpacing = o["csp"];
|
|
this._lineHeight = o["lh"];
|
|
this._horizontalAlign = o["ha"];
|
|
this._verticalAlign = o["va"];
|
|
this._wrapByWord = o["w"];
|
|
if (o.hasOwnProperty("tw")) {
|
|
const tw = o["tw"];
|
|
this._typewriterStartTime = tw["st"];
|
|
this._typewriterEndTime = tw["en"];
|
|
this._typewriterLength = o["l"]
|
|
}
|
|
const spriteFont = this._sdkType.GetSpriteFont();
|
|
spriteFont.SetCharacterWidth(o["cw"]);
|
|
spriteFont.SetCharacterHeight(o["ch"]);
|
|
spriteFont.SetCharacterSet(o["cs"]);
|
|
spriteFont.SetSpacingData(o["sd"]);
|
|
this._UpdateSettings();
|
|
if (this._typewriterEndTime !== -1)
|
|
this._StartTicking()
|
|
}
|
|
GetPropertyValueByIndex(index) {
|
|
switch (index) {
|
|
case TEXT:
|
|
return this._text;
|
|
case ENABLE_BBCODE:
|
|
return this._enableBBcode;
|
|
case CHARACTER_WIDTH:
|
|
return this._sdkType.GetSpriteFont().GetCharacterWidth();
|
|
case CHARACTER_HEIGHT:
|
|
return this._sdkType.GetSpriteFont().GetCharacterHeight();
|
|
case CHARACTER_SET:
|
|
return this._sdkType.GetSpriteFont().GetCharacterSet();
|
|
case SPACING_DATA:
|
|
return this._sdkType.GetSpriteFont().GetSpacingData();
|
|
case SCALE:
|
|
return this._characterScale;
|
|
case CHARACTER_SPACING:
|
|
return this._characterSpacing;
|
|
case LINE_HEIGHT:
|
|
return this._lineHeight;
|
|
case HORIZONTAL_ALIGNMENT:
|
|
return this._horizontalAlign;
|
|
case VERTICAL_ALIGNMENT:
|
|
return this._verticalAlign;
|
|
case WRAPPING:
|
|
return this._wrapByWord ? CHARACTER_WRAP : WORD_WRAP
|
|
}
|
|
}
|
|
SetPropertyValueByIndex(index, value) {
|
|
switch (index) {
|
|
case TEXT:
|
|
if (this._text === value)
|
|
return;
|
|
this._text = value;
|
|
this._UpdateSettings();
|
|
break;
|
|
case ENABLE_BBCODE:
|
|
if (this._enableBBcode === !!value)
|
|
return;
|
|
this._enableBBcode = !!value;
|
|
this._UpdateSettings();
|
|
break;
|
|
case CHARACTER_WIDTH:
|
|
this._sdkType.GetSpriteFont().SetCharacterWidth(value);
|
|
break;
|
|
case CHARACTER_HEIGHT:
|
|
this._sdkType.GetSpriteFont().SetCharacterHeight(value);
|
|
break;
|
|
case CHARACTER_SET:
|
|
this._sdkType.GetSpriteFont().SetCharacterSet(value);
|
|
break;
|
|
case SPACING_DATA:
|
|
this._sdkType.GetSpriteFont().SetSpacingData(value);
|
|
break;
|
|
case SCALE:
|
|
if (this._characterScale === value)
|
|
return;
|
|
this._characterScale = value;
|
|
this._UpdateSettings();
|
|
break;
|
|
case CHARACTER_SPACING:
|
|
if (this._characterSpacing === value)
|
|
return;
|
|
this._characterSpacing = value;
|
|
this._UpdateSettings();
|
|
break;
|
|
case LINE_HEIGHT:
|
|
if (this._lineHeight === value)
|
|
return;
|
|
this._lineHeight = value;
|
|
this._UpdateSettings();
|
|
break;
|
|
case HORIZONTAL_ALIGNMENT:
|
|
if (this._horizontalAlign === value)
|
|
return;
|
|
this._horizontalAlign = value;
|
|
this._UpdateSettings();
|
|
break;
|
|
case VERTICAL_ALIGNMENT:
|
|
if (this._verticalAlign === value)
|
|
return;
|
|
this._verticalAlign = value;
|
|
this._UpdateSettings();
|
|
break;
|
|
case WRAPPING:
|
|
if (this._wrapByWord === (value === WORD_WRAP))
|
|
return;
|
|
this._wrapByWord = value === WORD_WRAP;
|
|
this._UpdateSettings();
|
|
break
|
|
}
|
|
}
|
|
_SetText(text) {
|
|
if (this._text === text)
|
|
return;
|
|
this._text = text;
|
|
this._spriteFontText.SetText(text);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
GetText() {
|
|
return this._text
|
|
}
|
|
_StartTypewriter(text, duration) {
|
|
this._SetText(text);
|
|
this._typewriterStartTime = this._runtime.GetWallTime();
|
|
this._typewriterEndTime = this._typewriterStartTime + duration / this.GetInstance().GetActiveTimeScale();
|
|
this._typewriterLength = C3.BBString.StripAnyTags(text).length;
|
|
this._spriteFontText.SetDrawMaxCharacterCount(0);
|
|
this._StartTicking()
|
|
}
|
|
_CancelTypewriter() {
|
|
this._typewriterStartTime = -1;
|
|
this._typewriterEndTime = -1;
|
|
this._typewriterLength = 0;
|
|
this._spriteFontText.SetDrawMaxCharacterCount(-1);
|
|
this._StopTicking()
|
|
}
|
|
_FinishTypewriter() {
|
|
if (this._typewriterEndTime === -1)
|
|
return;
|
|
this._CancelTypewriter();
|
|
this.Trigger(C3.Plugins.Spritefont2.Cnds.OnTypewriterTextFinished);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_SetScale(s) {
|
|
if (this._characterScale === s)
|
|
return;
|
|
this._characterScale = s;
|
|
this._spriteFontText.SetScale(this._characterScale);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_GetScale() {
|
|
return this._characterScale
|
|
}
|
|
_SetCharacterSpacing(s) {
|
|
if (this._characterSpacing === s)
|
|
return;
|
|
this._characterSpacing = s;
|
|
this._spriteFontText.SetSpacing(this._characterSpacing);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_GetCharacterSpacing() {
|
|
return this._characterSpacing
|
|
}
|
|
_SetLineHeight(h) {
|
|
if (this._lineHeight === h)
|
|
return;
|
|
this._lineHeight = h;
|
|
this._spriteFontText.SetLineHeight(this._lineHeight);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_GetLineHeight() {
|
|
return this._lineHeight
|
|
}
|
|
_SetHAlign(h) {
|
|
if (this._horizontalAlign === h)
|
|
return;
|
|
this._horizontalAlign = h;
|
|
this._UpdateSettings();
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_GetHAlign() {
|
|
return this._horizontalAlign
|
|
}
|
|
_SetVAlign(v) {
|
|
if (this._verticalAlign === v)
|
|
return;
|
|
this._verticalAlign = v;
|
|
this._UpdateSettings();
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_GetVAlign() {
|
|
return this._verticalAlign
|
|
}
|
|
_SetWrapByWord(w) {
|
|
w = !!w;
|
|
if (this._wrapByWord === w)
|
|
return;
|
|
this._wrapByWord = w;
|
|
this._UpdateSettings();
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_IsWrapByWord() {
|
|
return this._wrapByWord
|
|
}
|
|
Tick() {
|
|
const wallTime = this._runtime.GetWallTime();
|
|
if (wallTime >= this._typewriterEndTime) {
|
|
this._CancelTypewriter();
|
|
this.Trigger(C3.Plugins.Spritefont2.Cnds.OnTypewriterTextFinished);
|
|
this._runtime.UpdateRender()
|
|
} else {
|
|
let displayLength = C3.relerp(this._typewriterStartTime, this._typewriterEndTime, wallTime, 0, this._typewriterLength);
|
|
displayLength = Math.floor(displayLength);
|
|
if (displayLength !== this._spriteFontText.GetDrawMaxCharacterCount()) {
|
|
this._spriteFontText.SetDrawMaxCharacterCount(displayLength);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
}
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "plugins.spritefont2";
|
|
return [{
|
|
title: prefix + ".name",
|
|
properties: [{
|
|
name: prefix + ".properties.text.name",
|
|
value: this._text,
|
|
onedit: v=>this._SetText(v)
|
|
}]
|
|
}]
|
|
}
|
|
GetScriptInterfaceClass() {
|
|
return self.ISpriteFontInstance
|
|
}
|
|
}
|
|
;
|
|
const map = new WeakMap;
|
|
const SCRIPT_HORIZONTAL_ALIGNMENTS = new Map([["left", 0], ["center", 1], ["right", 2]]);
|
|
const SCRIPT_VERTICAL_ALIGNMENTS = new Map([["top", 0], ["center", 1], ["bottom", 2]]);
|
|
const SCRIPT_WRAP_MODES = new Map([["word", true], ["character", false]]);
|
|
self.ISpriteFontInstance = class ISpriteFontInstance extends self.IWorldInstance {
|
|
constructor() {
|
|
super();
|
|
map.set(this, self.IInstance._GetInitInst().GetSdkInstance())
|
|
}
|
|
get text() {
|
|
return map.get(this).GetText()
|
|
}
|
|
set text(str) {
|
|
const inst = map.get(this);
|
|
inst._CancelTypewriter();
|
|
inst._SetText(str)
|
|
}
|
|
typewriterText(str, duration) {
|
|
const inst = map.get(this);
|
|
inst._CancelTypewriter();
|
|
inst._StartTypewriter(str, duration)
|
|
}
|
|
typewriterFinish() {
|
|
map.get(this)._FinishTypewriter()
|
|
}
|
|
set characterScale(s) {
|
|
map.get(this)._SetScale(s)
|
|
}
|
|
get characterScale() {
|
|
return map.get(this)._GetScale()
|
|
}
|
|
set characterSpacing(s) {
|
|
map.get(this)._SetCharacterSpacing(s)
|
|
}
|
|
get characterSpacing() {
|
|
return map.get(this)._GetCharacterSpacing()
|
|
}
|
|
set lineHeight(lho) {
|
|
map.get(this)._SetLineHeight(lho)
|
|
}
|
|
get lineHeight() {
|
|
return map.get(this)._GetLineHeight()
|
|
}
|
|
set horizontalAlign(str) {
|
|
const h = SCRIPT_HORIZONTAL_ALIGNMENTS.get(str);
|
|
if (typeof h === "undefined")
|
|
throw new Error("invalid mode");
|
|
map.get(this)._SetHAlign(h)
|
|
}
|
|
get horizontalAlign() {
|
|
return HORIZONTAL_ALIGNMENTS[map.get(this)._GetHAlign()]
|
|
}
|
|
set verticalAlign(str) {
|
|
const v = SCRIPT_VERTICAL_ALIGNMENTS.get(str);
|
|
if (typeof v === "undefined")
|
|
throw new Error("invalid mode");
|
|
map.get(this)._SetVAlign(v)
|
|
}
|
|
get verticalAlign() {
|
|
return VERTICAL_ALIGNMENTS[map.get(this)._GetVAlign()]
|
|
}
|
|
set wordWrapMode(str) {
|
|
const isWrapByWord = SCRIPT_WRAP_MODES.get(str);
|
|
if (typeof isWrapByWord === "undefined")
|
|
throw new Error("invalid mode");
|
|
map.get(this)._SetWrapByWord(isWrapByWord)
|
|
}
|
|
get wordWrapMode() {
|
|
return map.get(this)._IsWrapByWord() ? "word" : "character"
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Spritefont2.Cnds = {
|
|
CompareText(text, caseSensitive) {
|
|
if (caseSensitive)
|
|
return this._text === text;
|
|
else
|
|
return C3.equalsNoCase(this._text, text)
|
|
},
|
|
IsRunningTypewriterText() {
|
|
return this._typewriterEndTime !== -1
|
|
},
|
|
OnTypewriterTextFinished() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Spritefont2.Acts = {
|
|
SetText(param) {
|
|
this._CancelTypewriter();
|
|
if (typeof param === "number" && param < 1E9)
|
|
param = Math.round(param * 1E10) / 1E10;
|
|
this._SetText(param.toString())
|
|
},
|
|
AppendText(param) {
|
|
this._CancelTypewriter();
|
|
if (typeof param === "number" && param < 1E9)
|
|
param = Math.round(param * 1E10) / 1E10;
|
|
param = param.toString();
|
|
if (!param)
|
|
return;
|
|
this._SetText(this._text + param)
|
|
},
|
|
TypewriterText(param, duration) {
|
|
this._CancelTypewriter();
|
|
if (typeof param === "number" && param < 1E9)
|
|
param = Math.round(param * 1E10) / 1E10;
|
|
this._StartTypewriter(param.toString(), duration)
|
|
},
|
|
TypewriterFinish() {
|
|
this._FinishTypewriter()
|
|
},
|
|
SetScale(s) {
|
|
this._SetScale(s)
|
|
},
|
|
SetCharacterSpacing(s) {
|
|
this._SetCharacterSpacing(s)
|
|
},
|
|
SetLineHeight(h) {
|
|
this._SetLineHeight(h)
|
|
},
|
|
SetCharacterWidth(chars, width) {
|
|
let didAnyChange = false;
|
|
const spriteFont = this._sdkType.GetSpriteFont();
|
|
for (const ch of chars)
|
|
if (ch === " ") {
|
|
spriteFont.SetSpaceWidth(width);
|
|
didAnyChange = true
|
|
} else {
|
|
const sfc = spriteFont.GetCharacter(ch);
|
|
if (sfc) {
|
|
sfc.SetDisplayWidth(width);
|
|
didAnyChange = true
|
|
}
|
|
}
|
|
if (didAnyChange)
|
|
spriteFont.SetCharacterWidthsChanged();
|
|
this._runtime.UpdateRender()
|
|
},
|
|
SetEffect(effect) {
|
|
this.GetWorldInfo().SetBlendMode(effect);
|
|
this._runtime.UpdateRender()
|
|
},
|
|
SetHAlign(h) {
|
|
this._SetHAlign(h)
|
|
},
|
|
SetVAlign(v) {
|
|
this._SetVAlign(v)
|
|
},
|
|
SetWrapping(w) {
|
|
this._SetWrapByWord(w === 0)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Spritefont2.Exps = {
|
|
CharacterWidth(ch) {
|
|
const sfc = this._sdkType.GetSpriteFont().GetCharacter(ch);
|
|
if (sfc)
|
|
return sfc.GetDisplayWidth();
|
|
else
|
|
return this._sdkType.GetSpriteFont().GetCharacterWidth()
|
|
},
|
|
CharacterHeight() {
|
|
return this._characterHeight
|
|
},
|
|
CharacterScale() {
|
|
return this._characterScale
|
|
},
|
|
CharacterSpacing() {
|
|
return this._characterSpacing
|
|
},
|
|
LineHeight() {
|
|
return this._lineHeight
|
|
},
|
|
Text() {
|
|
return this._text
|
|
},
|
|
PlainText() {
|
|
if (this._enableBBcode)
|
|
return C3.BBString.StripAnyTags(this._text);
|
|
else
|
|
return this._text
|
|
},
|
|
TextWidth() {
|
|
const wi = this.GetWorldInfo();
|
|
this._spriteFontText.SetSize(wi.GetWidth(), wi.GetHeight());
|
|
return this._spriteFontText.GetTextWidth()
|
|
},
|
|
TextHeight() {
|
|
const wi = this.GetWorldInfo();
|
|
this._spriteFontText.SetSize(wi.GetWidth(), wi.GetHeight());
|
|
return this._spriteFontText.GetTextHeight()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
self.SpriteFontCharacter = class SpriteFontCharacter {
|
|
constructor(spriteFont, char, x, y) {
|
|
let charWidth = spriteFont.GetCharacterWidth();
|
|
let charHeight = spriteFont.GetCharacterHeight();
|
|
this._spriteFont = spriteFont;
|
|
this._char = char;
|
|
this._pxRect = new C3.Rect(x,y,x + charWidth,y + charHeight);
|
|
this._texRect = new C3.Rect;
|
|
this._displayWidth = -1;
|
|
this._UpdateTexRect()
|
|
}
|
|
Release() {
|
|
this._spriteFont = null;
|
|
this._pxRect = null;
|
|
this._texRect = null
|
|
}
|
|
_UpdateTexRect() {
|
|
let w = this._spriteFont.GetWidth();
|
|
let h = this._spriteFont.GetHeight();
|
|
this._texRect.copy(this._pxRect);
|
|
this._texRect.divide(w, h);
|
|
this._texRect.lerpInto(this._spriteFont.GetTexRect())
|
|
}
|
|
GetSpriteFont() {
|
|
return this._spriteFont
|
|
}
|
|
GetChar() {
|
|
return this._char
|
|
}
|
|
GetTexRect() {
|
|
return this._texRect
|
|
}
|
|
SetDisplayWidth(w) {
|
|
this._displayWidth = w
|
|
}
|
|
GetDisplayWidth() {
|
|
if (this._displayWidth < 0)
|
|
return this._spriteFont.GetCharacterWidth();
|
|
else
|
|
return this._displayWidth
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tmpRect = new C3.Rect;
|
|
const tmpQuad = new C3.Quad;
|
|
const tmpColor = new C3.Color;
|
|
const VALID_HORIZ_ALIGNMENTS = new Set(["left", "center", "right"]);
|
|
const VALID_VERT_ALIGNMENTS = new Set(["top", "center", "bottom"]);
|
|
const VALID_WORD_WRAP_MODES = new Set(["word", "character"]);
|
|
self.SpriteFontText = class SpriteFontText {
|
|
constructor(spriteFont) {
|
|
this._spriteFont = spriteFont;
|
|
this._cssWidth = 0;
|
|
this._cssHeight = 0;
|
|
this._text = "";
|
|
this._isBBcodeEnabled = false;
|
|
this._bbString = null;
|
|
this._wrappedText = C3.New(C3.WordWrap);
|
|
this._wrapMode = "word";
|
|
this._wrapChanged = false;
|
|
this._horizontalAlign = "left";
|
|
this._verticalAlign = "top";
|
|
this._scale = 1;
|
|
this._spacing = 0;
|
|
this._lineHeight = 0;
|
|
this._color = C3.New(C3.Color);
|
|
this._drawMaxCharCount = -1;
|
|
this._drawCharCount = 0;
|
|
this._measureTextCallback = (str,styles)=>this._MeasureText(str, styles);
|
|
this._spriteFont._AddSpriteFontText(this)
|
|
}
|
|
Release() {
|
|
this._spriteFont._RemoveSpriteFontText(this);
|
|
this._color = null;
|
|
this._measureTextCallback = null;
|
|
this._wrappedText.Clear();
|
|
this._wrappedText = null;
|
|
this._spriteFont = null;
|
|
this._bbString = null
|
|
}
|
|
_MeasureText(str, styles) {
|
|
const scaleStyle = this._GetStyleTag(styles, "scale");
|
|
const scale = scaleStyle ? parseFloat(scaleStyle.param) : this._scale;
|
|
const scaleXStyle = this._GetStyleTag(styles, "scalex");
|
|
const scaleX = (scaleXStyle ? parseFloat(scaleXStyle.param) : 1) * scale;
|
|
const scaleYStyle = this._GetStyleTag(styles, "scaley");
|
|
const scaleY = (scaleYStyle ? parseFloat(scaleYStyle.param) : 1) * scale;
|
|
const lineTotalHeight = this._spriteFont.GetCharacterHeight() * scaleY + this._lineHeight;
|
|
const spriteFont = this.GetSpriteFont();
|
|
const defaultCharWidth = spriteFont.GetCharacterWidth() * scaleX;
|
|
const spacing = this.GetSpacing();
|
|
if (spriteFont.HasAnyCustomWidths()) {
|
|
let strLen = 0;
|
|
let totalWidth = 0;
|
|
for (const ch of str) {
|
|
let charWidth = defaultCharWidth;
|
|
const sfc = spriteFont.GetCharacter(ch);
|
|
if (sfc)
|
|
charWidth = sfc.GetDisplayWidth() * scaleX;
|
|
else if (ch === " ")
|
|
charWidth = spriteFont.GetSpaceWidth() * scaleX;
|
|
totalWidth += charWidth;
|
|
++strLen
|
|
}
|
|
return {
|
|
width: totalWidth + strLen * spacing,
|
|
height: lineTotalHeight
|
|
}
|
|
} else {
|
|
const strLen = [...str].length;
|
|
const spaceCount = Math.max(strLen, 0);
|
|
return {
|
|
width: defaultCharWidth * strLen + spaceCount * spacing,
|
|
height: lineTotalHeight
|
|
}
|
|
}
|
|
}
|
|
_SetWrapChanged() {
|
|
this._wrapChanged = true;
|
|
this._wrappedText.Clear()
|
|
}
|
|
SetSize(cssWidth, cssHeight) {
|
|
if (cssWidth <= 0 || cssHeight <= 0)
|
|
return;
|
|
if (this._cssWidth === cssWidth && this._cssHeight === cssHeight)
|
|
return;
|
|
if (this._cssWidth !== cssWidth)
|
|
this._SetWrapChanged();
|
|
this._cssWidth = cssWidth;
|
|
this._cssHeight = cssHeight
|
|
}
|
|
SetDrawMaxCharacterCount(n) {
|
|
this._drawMaxCharCount = Math.floor(n)
|
|
}
|
|
GetDrawMaxCharacterCount() {
|
|
return this._drawMaxCharCount
|
|
}
|
|
_GetStyleTag(styles, tag) {
|
|
for (let i = styles.length - 1; i >= 0; --i) {
|
|
const s = styles[i];
|
|
if (s.tag === tag)
|
|
return s
|
|
}
|
|
return null
|
|
}
|
|
_HasStyleTag(styles, tag) {
|
|
return !!this._GetStyleTag(styles, tag)
|
|
}
|
|
_MaybeWrapText() {
|
|
if (!this._wrapChanged)
|
|
return;
|
|
if (this._isBBcodeEnabled && (!this._bbString || this._bbString.toString() !== this._text))
|
|
this._bbString = new C3.BBString(this._text,{
|
|
noEscape: true
|
|
});
|
|
const endOfLineMargin = -this.GetSpacing();
|
|
this._wrappedText.WordWrap(this._isBBcodeEnabled ? this._bbString.toFragmentList() : this._text, this._measureTextCallback, this._cssWidth, this._wrapMode, endOfLineMargin);
|
|
this._wrapChanged = false
|
|
}
|
|
Draw(renderer, offX, offY, angle) {
|
|
this._MaybeWrapText();
|
|
this._drawCharCount = 0;
|
|
let penY = 0;
|
|
const lineSpaceHeight = this._lineHeight;
|
|
const lines = C3.cloneArray(this._wrappedText.GetLines());
|
|
const sin_a = Math.sin(angle);
|
|
const cos_a = Math.cos(angle);
|
|
const linesTotalHeight = lines.reduce((a,v)=>a + v.height, 0) - lineSpaceHeight;
|
|
if (this._verticalAlign === "center")
|
|
penY = Math.max(Math.floor(this._cssHeight / 2 - linesTotalHeight / 2), 0);
|
|
else if (this._verticalAlign === "bottom")
|
|
penY = Math.floor(this._cssHeight - linesTotalHeight);
|
|
for (let i = 0, len = lines.length; i < len; ++i) {
|
|
const line = lines[i];
|
|
const curLineTextHeight = line.height;
|
|
if (i > 0 && penY > this._cssHeight - (curLineTextHeight - lineSpaceHeight))
|
|
break;
|
|
if (penY >= 0)
|
|
this._DrawLine(renderer, line, offX, offY, penY, sin_a, cos_a);
|
|
penY += curLineTextHeight
|
|
}
|
|
}
|
|
_DrawLine(renderer, line, offX, offY, penY, sin_a, cos_a) {
|
|
const lineHeight = line.height;
|
|
let penX = 0;
|
|
if (this._horizontalAlign === "center")
|
|
penX = Math.max(Math.floor((this._cssWidth - line.width) / 2), 0);
|
|
else if (this._horizontalAlign === "right")
|
|
penX = Math.max(Math.floor(this._cssWidth - line.width), 0);
|
|
for (const frag of line.fragments) {
|
|
this._DrawFragment(renderer, frag, offX, offY, penX, penY, sin_a, cos_a, lineHeight);
|
|
penX += frag.width
|
|
}
|
|
}
|
|
_DrawFragment(renderer, frag, offX, offY, penX, penY, sin_a, cos_a, lineHeight) {
|
|
let text = frag.text;
|
|
let fragWidth = frag.width;
|
|
const styles = frag.styles;
|
|
if (this._drawMaxCharCount !== -1) {
|
|
if (this._drawCharCount >= this._drawMaxCharCount)
|
|
return;
|
|
if (this._drawCharCount + text.length > this._drawMaxCharCount) {
|
|
text = text.substr(0, this._drawMaxCharCount - this._drawCharCount);
|
|
fragWidth = this._MeasureText(text, styles).width
|
|
}
|
|
this._drawCharCount += text.length
|
|
}
|
|
const backgroundStyle = this._GetStyleTag(styles, "background");
|
|
if (C3.IsStringAllWhitespace(text) && !backgroundStyle || this._HasStyleTag(styles, "hide"))
|
|
return;
|
|
const scaleStyle = this._GetStyleTag(styles, "scale");
|
|
const scale = scaleStyle ? parseFloat(scaleStyle.param) : this._scale;
|
|
const scaleXStyle = this._GetStyleTag(styles, "scalex");
|
|
const scaleX = (scaleXStyle ? parseFloat(scaleXStyle.param) : 1) * scale;
|
|
const scaleYStyle = this._GetStyleTag(styles, "scaley");
|
|
const scaleY = (scaleYStyle ? parseFloat(scaleYStyle.param) : 1) * scale;
|
|
const charHeight = this._spriteFont.GetCharacterHeight() * scaleY;
|
|
const lineSpaceHeight = this._lineHeight;
|
|
penY += lineHeight - lineSpaceHeight - charHeight;
|
|
const offsetXStyle = this._GetStyleTag(styles, "offsetx");
|
|
penX += offsetXStyle ? parseFloat(offsetXStyle.param) : 0;
|
|
const offsetYStyle = this._GetStyleTag(styles, "offsety");
|
|
penY += offsetYStyle ? parseFloat(offsetYStyle.param) : 0;
|
|
if (backgroundStyle) {
|
|
renderer.SetColorFillMode();
|
|
tmpColor.parseString(backgroundStyle.param);
|
|
tmpColor.setA(1);
|
|
renderer.SetColor(tmpColor);
|
|
tmpRect.set(penX, penY, penX + fragWidth, penY + charHeight);
|
|
if (tmpRect.getRight() > this._cssWidth)
|
|
tmpRect.setRight(this._cssWidth);
|
|
tmpQuad.setFromRotatedRectPrecalc(tmpRect, sin_a, cos_a);
|
|
tmpQuad.offset(offX, offY);
|
|
renderer.Quad(tmpQuad);
|
|
renderer.SetTextureFillMode()
|
|
}
|
|
const colorStyle = this._GetStyleTag(styles, "color");
|
|
if (colorStyle) {
|
|
tmpColor.parseString(colorStyle.param);
|
|
tmpColor.setA(this._color.getA())
|
|
} else
|
|
tmpColor.copy(this._color);
|
|
const opacityStyle = this._GetStyleTag(styles, "opacity");
|
|
if (opacityStyle)
|
|
tmpColor.setA(tmpColor.getA() * parseFloat(opacityStyle.param) / 100);
|
|
tmpColor.premultiply();
|
|
renderer.SetColor(tmpColor);
|
|
const drawCharWidth = this._spriteFont.GetCharacterWidth() * scaleX;
|
|
const endOfLineMargin = Math.abs(this.GetSpacing());
|
|
for (const ch of text) {
|
|
const sfc = this._spriteFont.GetCharacter(ch);
|
|
if (sfc) {
|
|
const layoutCharWidth = sfc.GetDisplayWidth() * scaleX;
|
|
if (penX + layoutCharWidth > this._cssWidth + endOfLineMargin + 1E-5)
|
|
return;
|
|
tmpRect.set(penX, penY, penX + drawCharWidth, penY + charHeight);
|
|
tmpQuad.setFromRotatedRectPrecalc(tmpRect, sin_a, cos_a);
|
|
tmpQuad.offset(offX, offY);
|
|
renderer.Quad3(tmpQuad, sfc.GetTexRect());
|
|
penX += layoutCharWidth + this._spacing
|
|
} else
|
|
penX += this._spriteFont.GetSpaceWidth() * scaleX + this._spacing
|
|
}
|
|
}
|
|
GetSpriteFont() {
|
|
return this._spriteFont
|
|
}
|
|
SetBBCodeEnabled(e) {
|
|
e = !!e;
|
|
if (this._isBBcodeEnabled === e)
|
|
return;
|
|
this._isBBcodeEnabled = e;
|
|
this._SetWrapChanged()
|
|
}
|
|
IsBBCodeEnabled() {
|
|
return this._isBBcodeEnabled
|
|
}
|
|
SetText(text) {
|
|
if (this._text === text)
|
|
return;
|
|
this._text = text;
|
|
this._SetWrapChanged()
|
|
}
|
|
SetWordWrapMode(w) {
|
|
if (!VALID_WORD_WRAP_MODES.has(w))
|
|
throw new Error("invalid word wrap mode");
|
|
if (this._wrapMode === w)
|
|
return;
|
|
this._wrapMode = w;
|
|
this._SetWrapChanged()
|
|
}
|
|
SetHorizontalAlign(a) {
|
|
if (!VALID_HORIZ_ALIGNMENTS.has(a))
|
|
throw new Error("invalid alignment");
|
|
this._horizontalAlign = a
|
|
}
|
|
SetVerticalAlign(a) {
|
|
if (!VALID_VERT_ALIGNMENTS.has(a))
|
|
throw new Error("invalid alignment");
|
|
this._verticalAlign = a
|
|
}
|
|
SetScale(s) {
|
|
if (this._scale === s)
|
|
return;
|
|
this._scale = s;
|
|
this._SetWrapChanged()
|
|
}
|
|
GetScale() {
|
|
return this._scale
|
|
}
|
|
SetSpacing(s) {
|
|
if (this._spacing === s)
|
|
return;
|
|
this._spacing = s;
|
|
this._SetWrapChanged()
|
|
}
|
|
GetSpacing() {
|
|
return this._spacing
|
|
}
|
|
SetLineHeight(h) {
|
|
this._lineHeight = h;
|
|
this._SetWrapChanged()
|
|
}
|
|
GetLineHeight() {
|
|
return this._lineHeight
|
|
}
|
|
SetOpacity(o) {
|
|
o = C3.clamp(o, 0, 1);
|
|
this._color.a = o
|
|
}
|
|
SetColor(c) {
|
|
if (this._color.equals(c))
|
|
return;
|
|
this._color.copy(c)
|
|
}
|
|
GetColor() {
|
|
return this._color
|
|
}
|
|
GetTextWidth() {
|
|
this._MaybeWrapText();
|
|
return this._wrappedText.GetMaxLineWidth()
|
|
}
|
|
GetTextHeight() {
|
|
this._MaybeWrapText();
|
|
const lineTextHeight = this._spriteFont.GetCharacterHeight() * this._scale;
|
|
const lineSpaceHeight = this._lineHeight;
|
|
const lineTotalHeight = lineTextHeight + lineSpaceHeight;
|
|
return this._wrappedText.GetLineCount() * lineTotalHeight - lineSpaceHeight
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const SpriteFontText = self.SpriteFontText;
|
|
const DEFAULT_SPRITEFONT_OPTS = {
|
|
width: 256,
|
|
height: 256,
|
|
characterWidth: 16,
|
|
characterHeight: 16,
|
|
characterSet: ""
|
|
};
|
|
self.SpriteFont = class SpriteFont {
|
|
constructor(opts) {
|
|
opts = Object.assign({}, DEFAULT_SPRITEFONT_OPTS, opts);
|
|
if (opts.width <= 0 || opts.height <= 0 || opts.characterWidth <= 0 || opts.characterHeight <= 0)
|
|
throw new Error("invalid size");
|
|
this._width = opts.width;
|
|
this._height = opts.height;
|
|
this._characterWidth = opts.characterWidth;
|
|
this._characterHeight = opts.characterHeight;
|
|
this._characterSet = opts.characterSet;
|
|
this._spacingData = "";
|
|
this._spacingParsed = null;
|
|
this._hasAnyCustomWidths = false;
|
|
this._spaceWidth = -1;
|
|
this._texRect = new C3.Rect(0,0,1,1);
|
|
this._characterMap = new Map;
|
|
this._mapChanged = true;
|
|
this._allTexts = new Set
|
|
}
|
|
Release() {
|
|
this._texRect = null;
|
|
this._ReleaseCharacters();
|
|
this._characterMap = null;
|
|
if (this._allTexts)
|
|
this._allTexts.clear();
|
|
this._allTexts = null
|
|
}
|
|
_ReleaseCharacters() {
|
|
for (let c of this._characterMap.values())
|
|
c.Release();
|
|
this._characterMap.clear()
|
|
}
|
|
_AddSpriteFontText(sft) {
|
|
this._allTexts.add(sft)
|
|
}
|
|
_RemoveSpriteFontText(sft) {
|
|
this._allTexts.delete(sft)
|
|
}
|
|
UpdateCharacterMap() {
|
|
if (!this._mapChanged)
|
|
return;
|
|
this._ReleaseCharacters();
|
|
let charSetArr = [...this._characterSet];
|
|
let cols = Math.floor(this._width / this._characterWidth);
|
|
let rows = Math.floor(this._height / this._characterHeight);
|
|
let last = cols * rows;
|
|
for (let i = 0, len = charSetArr.length; i < len; ++i) {
|
|
if (i >= last)
|
|
break;
|
|
let x = i % cols;
|
|
let y = Math.floor(i / cols);
|
|
let char = charSetArr[i];
|
|
this._characterMap.set(char, C3.New(self.SpriteFontCharacter, this, char, x * this._characterWidth, y * this._characterHeight))
|
|
}
|
|
this._hasAnyCustomWidths = false;
|
|
this._spaceWidth = -1;
|
|
if (Array.isArray(this._spacingParsed))
|
|
for (let entry of this._spacingParsed) {
|
|
if (!Array.isArray(entry))
|
|
continue;
|
|
if (entry.length !== 2)
|
|
continue;
|
|
let charWidth = entry[0];
|
|
let str = entry[1];
|
|
if (typeof charWidth !== "number" || !isFinite(charWidth) || typeof str !== "string")
|
|
continue;
|
|
if (charWidth === this._characterWidth)
|
|
continue;
|
|
for (let ch of str) {
|
|
let sfc = this._characterMap.get(ch);
|
|
if (sfc) {
|
|
sfc.SetDisplayWidth(charWidth);
|
|
this._hasAnyCustomWidths = true
|
|
} else if (ch === " ") {
|
|
this._spaceWidth = charWidth;
|
|
this._hasAnyCustomWidths = true
|
|
}
|
|
}
|
|
}
|
|
this._mapChanged = false;
|
|
for (let sft of this._allTexts)
|
|
sft._SetWrapChanged()
|
|
}
|
|
SetCharacterWidthsChanged() {
|
|
this._hasAnyCustomWidths = true;
|
|
for (const sft of this._allTexts)
|
|
sft._SetWrapChanged()
|
|
}
|
|
GetCharacter(ch) {
|
|
this.UpdateCharacterMap();
|
|
return this._characterMap.get(ch) || null
|
|
}
|
|
HasAnyCustomWidths() {
|
|
return this._hasAnyCustomWidths
|
|
}
|
|
SetWidth(w) {
|
|
w = Math.floor(w);
|
|
if (w <= 0)
|
|
throw new Error("invalid size");
|
|
if (this._width === w)
|
|
return;
|
|
this._width = w;
|
|
this._mapChanged = true
|
|
}
|
|
GetWidth() {
|
|
return this._width
|
|
}
|
|
SetHeight(h) {
|
|
h = Math.floor(h);
|
|
if (h <= 0)
|
|
throw new Error("invalid size");
|
|
if (this._height === h)
|
|
return;
|
|
this._height = h;
|
|
this._mapChanged = true
|
|
}
|
|
GetHeight() {
|
|
return this._height
|
|
}
|
|
SetTexRect(rc) {
|
|
if (this._texRect.equals(rc))
|
|
return;
|
|
this._texRect.copy(rc);
|
|
for (const sfc of this._characterMap.values())
|
|
sfc._UpdateTexRect()
|
|
}
|
|
GetTexRect() {
|
|
return this._texRect
|
|
}
|
|
SetCharacterWidth(w) {
|
|
w = Math.floor(w);
|
|
if (w <= 0)
|
|
throw new Error("invalid size");
|
|
if (this._characterWidth === w)
|
|
return;
|
|
this._characterWidth = w;
|
|
this._mapChanged = true
|
|
}
|
|
GetCharacterWidth() {
|
|
return this._characterWidth
|
|
}
|
|
SetCharacterHeight(h) {
|
|
h = Math.floor(h);
|
|
if (h <= 0)
|
|
throw new Error("invalid size");
|
|
if (this._characterHeight === h)
|
|
return;
|
|
this._characterHeight = h;
|
|
this._mapChanged = true
|
|
}
|
|
GetCharacterHeight() {
|
|
return this._characterHeight
|
|
}
|
|
SetCharacterSet(s) {
|
|
if (this._characterSet === s)
|
|
return;
|
|
this._characterSet = s;
|
|
this._mapChanged = true
|
|
}
|
|
GetCharacterSet() {
|
|
return this._characterSet
|
|
}
|
|
SetSpacingData(s) {
|
|
if (this._spacingData === s)
|
|
return;
|
|
this._spacingData = s;
|
|
this._mapChanged = true;
|
|
this._spacingParsed = null;
|
|
if (this._spacingData.length)
|
|
try {
|
|
this._spacingParsed = JSON.parse(this._spacingData)
|
|
} catch (e) {
|
|
this._spacingParsed = null
|
|
}
|
|
}
|
|
GetSpacingData() {
|
|
return this._spacingData
|
|
}
|
|
SetSpaceWidth(w) {
|
|
if (w < 0)
|
|
w = -1;
|
|
if (this._spaceWidth === w)
|
|
return;
|
|
this._spaceWidth = w;
|
|
if (this._spaceWidth >= 0)
|
|
this._hasAnyCustomWidths = true
|
|
}
|
|
GetSpaceWidth() {
|
|
if (this._spaceWidth < 0)
|
|
return this._characterWidth;
|
|
else
|
|
return this._spaceWidth
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Sprite = class SpritePlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Sprite.Type = class SpriteType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass);
|
|
this._animations = objectClass.GetAnimations()
|
|
}
|
|
Release() {
|
|
C3.clearArray(this._animations);
|
|
super.Release()
|
|
}
|
|
OnCreate() {
|
|
for (const a of this._animations)
|
|
a.LoadAllAssets(this._runtime)
|
|
}
|
|
LoadTextures(renderer) {
|
|
const opts = {
|
|
sampling: this._runtime.GetSampling()
|
|
};
|
|
return Promise.all(this._animations.map(a=>a.LoadAllTextures(renderer, opts)))
|
|
}
|
|
ReleaseTextures() {
|
|
for (const a of this._animations)
|
|
a.ReleaseAllTextures()
|
|
}
|
|
OnDynamicTextureLoadComplete() {
|
|
this._UpdateAllCurrentTexture()
|
|
}
|
|
_UpdateAllCurrentTexture() {
|
|
for (const inst of this._objectClass.instancesIncludingPendingCreate())
|
|
inst.GetSdkInstance()._UpdateCurrentTexture()
|
|
}
|
|
FinishCondition(doPick) {
|
|
C3.Plugins.Sprite._FinishCondition(this, doPick)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const INITIALLY_VISIBLE = 0;
|
|
const INITIAL_ANIMATION = 1;
|
|
const INITIAL_FRAME = 2;
|
|
const ENABLE_COLLISIONS = 3;
|
|
const tempRect = C3.New(C3.Rect);
|
|
const tempQuad = C3.New(C3.Quad);
|
|
const tempVec2 = C3.New(C3.Vector2);
|
|
const FLAG_PLAYING_FORWARDS = 1 << 0;
|
|
const FLAG_ANIMATION_PLAYING = 1 << 1;
|
|
const FLAG_ANIMATION_TRIGGER = 1 << 2;
|
|
C3.Plugins.Sprite.Instance = class SpriteInstance extends C3.SDKWorldInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
let initiallyVisible = true;
|
|
let initialAnimation = "";
|
|
let initialFrame = 0;
|
|
let collisionEnabled = true;
|
|
if (properties) {
|
|
initiallyVisible = !!properties[INITIALLY_VISIBLE];
|
|
initialAnimation = properties[INITIAL_ANIMATION];
|
|
initialFrame = properties[INITIAL_FRAME];
|
|
collisionEnabled = properties[ENABLE_COLLISIONS]
|
|
}
|
|
this._currentAnimation = this._objectClass.GetAnimationByName(initialAnimation) || this._objectClass.GetAnimations()[0];
|
|
this._currentFrameIndex = C3.clamp(initialFrame, 0, this._currentAnimation.GetFrameCount() - 1);
|
|
this._currentAnimationFrame = this._currentAnimation.GetFrameAt(this._currentFrameIndex);
|
|
const initialImageInfo = this._currentAnimationFrame.GetImageInfo();
|
|
this._currentTexture = initialImageInfo.GetTexture();
|
|
this._currentRcTex = initialImageInfo.GetTexRect();
|
|
this.HandleWebGLContextLoss();
|
|
inst.SetFlag(FLAG_ANIMATION_PLAYING, true);
|
|
inst.SetFlag(FLAG_PLAYING_FORWARDS, this._currentAnimation.GetSpeed() >= 0);
|
|
this._currentAnimationSpeed = Math.abs(this._currentAnimation.GetSpeed());
|
|
this._currentAnimationRepeatTo = this._currentAnimation.GetRepeatTo();
|
|
this._animationTimer = C3.New(C3.KahanSum);
|
|
this._frameStartTime = 0;
|
|
this._animationRepeats = 0;
|
|
this._animTriggerName = "";
|
|
this._changeAnimFrameIndex = -1;
|
|
this._changeAnimationName = "";
|
|
this._changeAnimationFrom = 0;
|
|
const wi = this.GetWorldInfo();
|
|
this._bquadRef = wi.GetBoundingQuad();
|
|
wi.SetVisible(initiallyVisible);
|
|
wi.SetCollisionEnabled(collisionEnabled);
|
|
wi.SetOriginX(this._currentAnimationFrame.GetOriginX());
|
|
wi.SetOriginY(this._currentAnimationFrame.GetOriginY());
|
|
wi.SetSourceCollisionPoly(this._currentAnimationFrame.GetCollisionPoly());
|
|
wi.SetBboxChanged();
|
|
if ((this._objectClass.GetAnimationCount() !== 1 || this._objectClass.GetAnimations()[0].GetFrameCount() !== 1) && this._currentAnimationSpeed !== 0)
|
|
this._StartTicking()
|
|
}
|
|
Release() {
|
|
this._currentAnimation = null;
|
|
this._currentAnimationFrame = null;
|
|
this._currentTexture = null;
|
|
this._animationTimer = null;
|
|
super.Release()
|
|
}
|
|
GetCurrentImageInfo() {
|
|
return this._currentAnimationFrame.GetImageInfo()
|
|
}
|
|
OnWebGLContextLost() {
|
|
this._currentTexture = null
|
|
}
|
|
OnWebGLContextRestored() {
|
|
this._UpdateCurrentTexture()
|
|
}
|
|
Draw(renderer) {
|
|
const texture = this._currentTexture;
|
|
if (texture === null)
|
|
return;
|
|
renderer.SetTexture(texture);
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.HasMesh())
|
|
this._DrawMesh(wi, renderer);
|
|
else
|
|
this._DrawStandard(wi, renderer)
|
|
}
|
|
_DrawStandard(wi, renderer) {
|
|
let quad = this._bquadRef;
|
|
if (this._runtime.IsPixelRoundingEnabled())
|
|
quad = wi.PixelRoundQuad(quad);
|
|
renderer.Quad3(quad, this._currentRcTex)
|
|
}
|
|
_DrawMesh(wi, renderer) {
|
|
const transformedMesh = wi.GetTransformedMesh();
|
|
if (wi.IsMeshChanged()) {
|
|
wi.CalculateBbox(tempRect, tempQuad, false);
|
|
let quad = tempQuad;
|
|
if (this._runtime.IsPixelRoundingEnabled())
|
|
quad = wi.PixelRoundQuad(quad);
|
|
transformedMesh.CalculateTransformedMesh(wi.GetSourceMesh(), quad, this._currentRcTex);
|
|
wi.SetMeshChanged(false)
|
|
}
|
|
transformedMesh.Draw(renderer)
|
|
}
|
|
GetAnimationTime() {
|
|
return this._animationTimer.Get()
|
|
}
|
|
IsAnimationPlaying() {
|
|
return this._inst.GetFlag(FLAG_ANIMATION_PLAYING)
|
|
}
|
|
SetAnimationPlaying(e) {
|
|
this._inst.SetFlag(FLAG_ANIMATION_PLAYING, e)
|
|
}
|
|
IsPlayingForwards() {
|
|
return this._inst.GetFlag(FLAG_PLAYING_FORWARDS)
|
|
}
|
|
SetPlayingForwards(e) {
|
|
this._inst.SetFlag(FLAG_PLAYING_FORWARDS, e)
|
|
}
|
|
IsInAnimationTrigger() {
|
|
return this._inst.GetFlag(FLAG_ANIMATION_TRIGGER)
|
|
}
|
|
SetInAnimationTrigger(e) {
|
|
this._inst.SetFlag(FLAG_ANIMATION_TRIGGER, e)
|
|
}
|
|
Tick() {
|
|
if (this._changeAnimationName)
|
|
this._DoChangeAnimation();
|
|
if (this._changeAnimFrameIndex >= 0)
|
|
this._DoChangeAnimFrame();
|
|
const currentAnimationSpeed = this._currentAnimationSpeed;
|
|
if (!this.IsAnimationPlaying() || currentAnimationSpeed === 0) {
|
|
this._StopTicking();
|
|
return
|
|
}
|
|
const dt = this._runtime.GetDt(this._inst);
|
|
this._animationTimer.Add(dt);
|
|
const now = this.GetAnimationTime();
|
|
const prevFrame = this._currentAnimationFrame;
|
|
const currentFrameTime = prevFrame.GetDuration() / currentAnimationSpeed;
|
|
if (now < this._frameStartTime + currentFrameTime)
|
|
return;
|
|
const currentAnimation = this._currentAnimation;
|
|
const repeatTo = this._currentAnimationRepeatTo;
|
|
const frameCount = currentAnimation.GetFrameCount();
|
|
const repeatCount = currentAnimation.GetRepeatCount();
|
|
const isLooping = currentAnimation.IsLooping();
|
|
const isPingPong = currentAnimation.IsPingPong();
|
|
if (this.IsPlayingForwards())
|
|
this._currentFrameIndex++;
|
|
else
|
|
this._currentFrameIndex--;
|
|
this._frameStartTime += currentFrameTime;
|
|
if (this._currentFrameIndex >= frameCount)
|
|
if (isPingPong) {
|
|
this.SetPlayingForwards(false);
|
|
this._currentFrameIndex = frameCount - 2
|
|
} else if (isLooping)
|
|
this._currentFrameIndex = repeatTo;
|
|
else {
|
|
this._animationRepeats++;
|
|
if (this._animationRepeats >= repeatCount)
|
|
this._FinishAnimation(false);
|
|
else
|
|
this._currentFrameIndex = repeatTo
|
|
}
|
|
if (this._currentFrameIndex < 0)
|
|
if (isPingPong) {
|
|
this._currentFrameIndex = 1;
|
|
this.SetPlayingForwards(true);
|
|
if (!isLooping) {
|
|
this._animationRepeats++;
|
|
if (this._animationRepeats >= repeatCount)
|
|
this._FinishAnimation(true)
|
|
}
|
|
} else if (isLooping)
|
|
this._currentFrameIndex = repeatTo;
|
|
else {
|
|
this._animationRepeats++;
|
|
if (this._animationRepeats >= repeatCount)
|
|
this._FinishAnimation(true);
|
|
else
|
|
this._currentFrameIndex = repeatTo
|
|
}
|
|
this._currentFrameIndex = C3.clamp(this._currentFrameIndex, 0, frameCount - 1);
|
|
const nextFrame = currentAnimation.GetFrameAt(this._currentFrameIndex);
|
|
if (now > this._frameStartTime + nextFrame.GetDuration() / currentAnimationSpeed)
|
|
this._frameStartTime = now;
|
|
this._OnFrameChanged(prevFrame, nextFrame)
|
|
}
|
|
_FinishAnimation(reverse) {
|
|
this._currentFrameIndex = reverse ? 0 : this._currentAnimation.GetFrameCount() - 1;
|
|
this.SetAnimationPlaying(false);
|
|
this._animTriggerName = this._currentAnimation.GetName();
|
|
this.SetInAnimationTrigger(true);
|
|
this.Trigger(C3.Plugins.Sprite.Cnds.OnAnyAnimFinished);
|
|
this.Trigger(C3.Plugins.Sprite.Cnds.OnAnimFinished);
|
|
this.SetInAnimationTrigger(false);
|
|
this._animationRepeats = 0
|
|
}
|
|
_OnFrameChanged(prevFrame, nextFrame) {
|
|
if (prevFrame === nextFrame)
|
|
return;
|
|
const wi = this.GetWorldInfo();
|
|
const prevImage = prevFrame.GetImageInfo();
|
|
const nextImage = nextFrame.GetImageInfo();
|
|
const oldW = prevImage.GetWidth();
|
|
const oldH = prevImage.GetHeight();
|
|
const newW = nextImage.GetWidth();
|
|
const newH = nextImage.GetHeight();
|
|
if (oldW !== newW)
|
|
wi.SetWidth(wi.GetWidth() * (newW / oldW));
|
|
if (oldH !== newH)
|
|
wi.SetHeight(wi.GetHeight() * (newH / oldH));
|
|
wi.SetOriginX(nextFrame.GetOriginX());
|
|
wi.SetOriginY(nextFrame.GetOriginY());
|
|
wi.SetSourceCollisionPoly(nextFrame.GetCollisionPoly());
|
|
wi.SetBboxChanged();
|
|
this._currentAnimationFrame = nextFrame;
|
|
this._currentTexture = nextImage.GetTexture();
|
|
this._currentRcTex = nextImage.GetTexRect();
|
|
const behaviorInstances = this.GetInstance().GetBehaviorInstances();
|
|
for (let i = 0, len = behaviorInstances.length; i < len; ++i)
|
|
behaviorInstances[i].OnSpriteFrameChanged(prevFrame, nextFrame);
|
|
this.Trigger(C3.Plugins.Sprite.Cnds.OnFrameChanged);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_StartAnim(from) {
|
|
this.SetAnimationPlaying(true);
|
|
this._frameStartTime = this.GetAnimationTime();
|
|
if (from === 1 && this._currentFrameIndex !== 0) {
|
|
this._changeAnimFrameIndex = 0;
|
|
if (!this.IsInAnimationTrigger())
|
|
this._DoChangeAnimFrame()
|
|
}
|
|
this._StartTicking()
|
|
}
|
|
_SetAnim(animName, from) {
|
|
this._changeAnimationName = animName;
|
|
this._changeAnimationFrom = from;
|
|
this._StartTicking();
|
|
if (!this.IsInAnimationTrigger())
|
|
this._DoChangeAnimation()
|
|
}
|
|
_GetCurrentAnimationName() {
|
|
if (this._changeAnimationName)
|
|
return this._changeAnimationName;
|
|
else
|
|
return this._currentAnimation.GetName()
|
|
}
|
|
_SetAnimFrame(frameNum) {
|
|
if (!isFinite(frameNum))
|
|
return;
|
|
this._changeAnimFrameIndex = frameNum;
|
|
if (!this.IsInAnimationTrigger())
|
|
this._DoChangeAnimFrame()
|
|
}
|
|
_GetAnimFrame() {
|
|
return this._currentFrameIndex
|
|
}
|
|
_SetAnimSpeed(s) {
|
|
this._currentAnimationSpeed = Math.abs(s);
|
|
this.SetPlayingForwards(s >= 0);
|
|
if (this._currentAnimationSpeed > 0)
|
|
this._StartTicking()
|
|
}
|
|
_GetAnimSpeed() {
|
|
return this.IsPlayingForwards() ? this._currentAnimationSpeed : -this._currentAnimationSpeed
|
|
}
|
|
_SetAnimRepeatToFrame(f) {
|
|
f = C3.clamp(Math.floor(f), 0, this._currentAnimation.GetFrameCount() - 1);
|
|
this._currentAnimationRepeatTo = f
|
|
}
|
|
_GetAnimRepeatToFrame() {
|
|
return this._currentAnimationRepeatTo
|
|
}
|
|
_DoChangeAnimation() {
|
|
const prevFrame = this._currentAnimationFrame;
|
|
const animation = this._objectClass.GetAnimationByName(this._changeAnimationName);
|
|
this._changeAnimationName = "";
|
|
if (!animation)
|
|
return;
|
|
if (animation === this._currentAnimation && this.IsAnimationPlaying())
|
|
return;
|
|
this._currentAnimation = animation;
|
|
this.SetPlayingForwards(animation.GetSpeed() >= 0);
|
|
this._currentAnimationSpeed = Math.abs(animation.GetSpeed());
|
|
this._currentAnimationRepeatTo = animation.GetRepeatTo();
|
|
this._currentFrameIndex = C3.clamp(this._currentFrameIndex, 0, this._currentAnimation.GetFrameCount() - 1);
|
|
if (this._changeAnimationFrom === 1)
|
|
this._currentFrameIndex = 0;
|
|
this.SetAnimationPlaying(true);
|
|
this._frameStartTime = this.GetAnimationTime();
|
|
const nextFrame = this._currentAnimation.GetFrameAt(this._currentFrameIndex);
|
|
this._OnFrameChanged(prevFrame, nextFrame)
|
|
}
|
|
_DoChangeAnimFrame() {
|
|
const prevFrame = this._currentAnimationFrame;
|
|
const prevFrameIndex = this._currentFrameIndex;
|
|
this._currentFrameIndex = C3.clamp(Math.floor(this._changeAnimFrameIndex), 0, this._currentAnimation.GetFrameCount() - 1);
|
|
this._changeAnimFrameIndex = -1;
|
|
if (prevFrameIndex === this._currentFrameIndex)
|
|
return;
|
|
const nextFrame = this._currentAnimation.GetFrameAt(this._currentFrameIndex);
|
|
this._OnFrameChanged(prevFrame, nextFrame);
|
|
this._frameStartTime = this.GetAnimationTime()
|
|
}
|
|
_UpdateCurrentTexture() {
|
|
const curImageInfo = this._currentAnimationFrame.GetImageInfo();
|
|
this._currentTexture = curImageInfo.GetTexture();
|
|
this._currentRcTex = curImageInfo.GetTexRect();
|
|
this.GetWorldInfo().SetMeshChanged(true)
|
|
}
|
|
GetImagePointCount() {
|
|
return this._currentAnimationFrame.GetImagePointCount()
|
|
}
|
|
GetImagePoint(nameOrIndex) {
|
|
const frame = this._currentAnimationFrame;
|
|
const wi = this.GetWorldInfo();
|
|
let ip = null;
|
|
if (typeof nameOrIndex === "string")
|
|
ip = frame.GetImagePointByName(nameOrIndex);
|
|
else if (typeof nameOrIndex === "number")
|
|
ip = frame.GetImagePointByIndex(nameOrIndex - 1);
|
|
else
|
|
throw new TypeError("expected string or number");
|
|
if (!ip)
|
|
return [wi.GetX(), wi.GetY()];
|
|
tempVec2.copy(ip.GetVec2());
|
|
if (wi.HasMesh()) {
|
|
const [tx,ty] = wi.GetSourceMesh().TransformPoint(tempVec2.getX(), tempVec2.getY());
|
|
tempVec2.set(tx, ty)
|
|
}
|
|
tempVec2.offset(-frame.GetOriginX(), -frame.GetOriginY());
|
|
tempVec2.scale(wi.GetWidth(), wi.GetHeight());
|
|
tempVec2.rotate(wi.GetAngle());
|
|
tempVec2.offset(wi.GetX(), wi.GetY());
|
|
return [tempVec2.getX(), tempVec2.getY()]
|
|
}
|
|
GetCollisionPolyPointCount() {
|
|
return this.GetWorldInfo().GetTransformedCollisionPoly().pointCount()
|
|
}
|
|
GetCollisionPolyPoint(index) {
|
|
index = Math.floor(index);
|
|
const wi = this.GetWorldInfo();
|
|
const poly = wi.GetTransformedCollisionPoly();
|
|
const pointCount = poly.pointCount();
|
|
if (index === pointCount)
|
|
index = 0;
|
|
if (index < 0 || index >= pointCount)
|
|
return [0, 0];
|
|
const pointsArr = poly.pointsArr();
|
|
return [pointsArr[index * 2 + 0] + wi.GetX(), pointsArr[index * 2 + 1] + wi.GetY()]
|
|
}
|
|
GetDebuggerProperties() {
|
|
const Acts = C3.Plugins.Sprite.Acts;
|
|
const prefix = "plugins.sprite.debugger.animation-properties";
|
|
return [{
|
|
title: prefix + ".title",
|
|
properties: [{
|
|
name: prefix + ".current-animation",
|
|
value: this._currentAnimation.GetName(),
|
|
onedit: v=>this.CallAction(Acts.SetAnim, v, 0)
|
|
}, {
|
|
name: prefix + ".current-frame",
|
|
value: this._currentFrameIndex,
|
|
onedit: v=>this.CallAction(Acts.SetAnimFrame, v)
|
|
}, {
|
|
name: prefix + ".is-playing",
|
|
value: this.IsAnimationPlaying(),
|
|
onedit: v=>v ? this.CallAction(Acts.StartAnim, 0) : this.CallAction(Acts.StopAnim)
|
|
}, {
|
|
name: prefix + ".speed",
|
|
value: this._currentAnimationSpeed,
|
|
onedit: v=>this.CallAction(Acts.SetAnimSpeed, v)
|
|
}, {
|
|
name: prefix + ".repeats",
|
|
value: this._animationRepeats,
|
|
onedit: v=>this._animationRepeats = v
|
|
}]
|
|
}]
|
|
}
|
|
SaveToJson() {
|
|
const o = {
|
|
"a": this._currentAnimation.GetSID()
|
|
};
|
|
if (this._frameStartTime !== 0)
|
|
o["fs"] = this._frameStartTime;
|
|
const animTime = this.GetAnimationTime();
|
|
if (animTime !== 0)
|
|
o["at"] = animTime;
|
|
if (this._currentFrameIndex !== 0)
|
|
o["f"] = this._currentFrameIndex;
|
|
if (this._currentAnimationSpeed !== 0)
|
|
o["cas"] = this._currentAnimationSpeed;
|
|
if (this._animationRepeats !== 1)
|
|
o["ar"] = this._animationRepeats;
|
|
if (this._currentAnimationRepeatTo !== 0)
|
|
o["rt"] = this._currentAnimationRepeatTo;
|
|
if (!this.IsAnimationPlaying())
|
|
o["ap"] = this.IsAnimationPlaying();
|
|
if (!this.IsPlayingForwards())
|
|
o["af"] = this.IsPlayingForwards();
|
|
const wi = this.GetWorldInfo();
|
|
if (wi.IsCollisionEnabled())
|
|
o["ce"] = wi.IsCollisionEnabled();
|
|
return o
|
|
}
|
|
LoadFromJson(o) {
|
|
const anim = this.GetObjectClass().GetAnimationBySID(o["a"]);
|
|
if (anim)
|
|
this._currentAnimation = anim;
|
|
this._frameStartTime = o.hasOwnProperty("fs") ? o["fs"] : 0;
|
|
this._animationTimer.Set(o.hasOwnProperty("at") ? o["at"] : 0);
|
|
const frameIndex = o.hasOwnProperty("f") ? o["f"] : 0;
|
|
this._currentFrameIndex = C3.clamp(frameIndex, 0, this._currentAnimation.GetFrameCount() - 1);
|
|
this._currentAnimationSpeed = o.hasOwnProperty("cas") ? o["cas"] : 0;
|
|
this._animationRepeats = o.hasOwnProperty("ar") ? o["ar"] : 1;
|
|
const repeatToIndex = o.hasOwnProperty("rt") ? o["rt"] : 0;
|
|
this._currentAnimationRepeatTo = C3.clamp(repeatToIndex, 0, this._currentAnimation.GetFrameCount() - 1);
|
|
this.SetAnimationPlaying(o.hasOwnProperty("ap") ? !!o["ap"] : true);
|
|
this.SetPlayingForwards(o.hasOwnProperty("af") ? !!o["af"] : true);
|
|
const nextFrame = this._currentAnimation.GetFrameAt(this._currentFrameIndex);
|
|
this._currentAnimationFrame = nextFrame;
|
|
this._UpdateCurrentTexture();
|
|
const wi = this.GetWorldInfo();
|
|
wi.SetOriginX(nextFrame.GetOriginX());
|
|
wi.SetOriginY(nextFrame.GetOriginY());
|
|
wi.SetSourceCollisionPoly(nextFrame.GetCollisionPoly());
|
|
wi.SetCollisionEnabled(!!o["ce"])
|
|
}
|
|
GetPropertyValueByIndex(index) {
|
|
const wi = this.GetWorldInfo();
|
|
switch (index) {
|
|
case ENABLE_COLLISIONS:
|
|
return wi.IsCollisionEnabled();
|
|
case INITIAL_FRAME:
|
|
return C3.clamp(this._currentFrameIndex, 0, this._currentAnimation.GetFrameCount() - 1)
|
|
}
|
|
}
|
|
SetPropertyValueByIndex(index, value) {
|
|
const wi = this.GetWorldInfo();
|
|
switch (index) {
|
|
case ENABLE_COLLISIONS:
|
|
wi.SetCollisionEnabled(!!value);
|
|
break;
|
|
case INITIAL_FRAME:
|
|
this.SetAnimationPlaying(false);
|
|
const totalFrames = this._currentAnimation.GetFrameCount() - 1;
|
|
const nextIndex = value = C3.clamp(value, 0, totalFrames);
|
|
const prevFrame = this._currentAnimation.GetFrameAt(this._currentFrameIndex);
|
|
const nextFrame = this._currentAnimation.GetFrameAt(nextIndex);
|
|
this._OnFrameChanged(prevFrame, nextFrame);
|
|
this._currentFrameIndex = C3.clamp(nextIndex, 0, totalFrames);
|
|
break
|
|
}
|
|
}
|
|
GetScriptInterfaceClass() {
|
|
return self.ISpriteInstance
|
|
}
|
|
}
|
|
;
|
|
const map = new WeakMap;
|
|
const ANIM_FROM_MODES = new Map([["current-frame", 0], ["beginning", 1]]);
|
|
self.ISpriteInstance = class ISpriteInstance extends self.IWorldInstance {
|
|
constructor() {
|
|
super();
|
|
map.set(this, self.IInstance._GetInitInst().GetSdkInstance())
|
|
}
|
|
getImagePointCount() {
|
|
return map.get(this).GetImagePointCount()
|
|
}
|
|
getImagePointX(nameOrIndex) {
|
|
if (typeof nameOrIndex !== "string" && typeof nameOrIndex !== "number")
|
|
throw new TypeError("expected string or number");
|
|
return map.get(this).GetImagePoint(nameOrIndex)[0]
|
|
}
|
|
getImagePointY(nameOrIndex) {
|
|
if (typeof nameOrIndex !== "string" && typeof nameOrIndex !== "number")
|
|
throw new TypeError("expected string or number");
|
|
return map.get(this).GetImagePoint(nameOrIndex)[1]
|
|
}
|
|
getImagePoint(nameOrIndex) {
|
|
if (typeof nameOrIndex !== "string" && typeof nameOrIndex !== "number")
|
|
throw new TypeError("expected string or number");
|
|
return map.get(this).GetImagePoint(nameOrIndex)
|
|
}
|
|
getPolyPointCount() {
|
|
return map.get(this).GetCollisionPolyPointCount()
|
|
}
|
|
getPolyPointX(index) {
|
|
return map.get(this).GetCollisionPolyPoint(index)[0]
|
|
}
|
|
getPolyPointY(index) {
|
|
return map.get(this).GetCollisionPolyPoint(index)[1]
|
|
}
|
|
getPolyPoint(index) {
|
|
return map.get(this).GetCollisionPolyPoint(index)
|
|
}
|
|
stopAnimation() {
|
|
map.get(this).SetAnimationPlaying(false)
|
|
}
|
|
startAnimation(from="current-frame") {
|
|
const f = ANIM_FROM_MODES.get(from);
|
|
if (typeof f === "undefined")
|
|
throw new Error("invalid mode");
|
|
map.get(this)._StartAnim(f)
|
|
}
|
|
setAnimation(name, from="beginning") {
|
|
const f = ANIM_FROM_MODES.get(from);
|
|
if (typeof f === "undefined")
|
|
throw new Error("invalid mode");
|
|
map.get(this)._SetAnim(name, f)
|
|
}
|
|
get animationName() {
|
|
return map.get(this)._GetCurrentAnimationName()
|
|
}
|
|
set animationFrame(frameIndex) {
|
|
map.get(this)._SetAnimFrame(frameIndex)
|
|
}
|
|
get animationFrame() {
|
|
return map.get(this)._GetAnimFrame()
|
|
}
|
|
set animationSpeed(s) {
|
|
map.get(this)._SetAnimSpeed(s)
|
|
}
|
|
get animationSpeed() {
|
|
return map.get(this)._GetAnimSpeed()
|
|
}
|
|
set animationRepeatToFrame(f) {
|
|
map.get(this)._SetAnimRepeatToFrame(f)
|
|
}
|
|
get animationRepeatToFrame() {
|
|
return map.get(this)._GetAnimRepeatToFrame()
|
|
}
|
|
get imageWidth() {
|
|
return map.get(this).GetCurrentImageInfo().GetWidth()
|
|
}
|
|
get imageHeight() {
|
|
return map.get(this).GetCurrentImageInfo().GetHeight()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tempRect = C3.New(C3.Rect);
|
|
const tempCandidates1 = [];
|
|
const tempCandidates2 = [];
|
|
let needsCollisionFinish = false;
|
|
let rPickType = null;
|
|
let rPickFromElseInstances = false;
|
|
const rToPick = new Set;
|
|
function CollMemory_Add(collMemory, a, b, tickCount) {
|
|
const a_uid = a.GetUID();
|
|
const b_uid = b.GetUID();
|
|
if (a_uid < b_uid)
|
|
collMemory.Set(a, b, tickCount);
|
|
else
|
|
collMemory.Set(b, a, tickCount)
|
|
}
|
|
function CollMemory_Remove(collMemory, a, b) {
|
|
const a_uid = a.GetUID();
|
|
const b_uid = b.GetUID();
|
|
if (a_uid < b_uid)
|
|
collMemory.Delete(a, b);
|
|
else
|
|
collMemory.Delete(b, a)
|
|
}
|
|
function CollMemory_RemoveInstance(collMemory, inst) {
|
|
collMemory.DeleteEither(inst)
|
|
}
|
|
function CollMemory_Get(collMemory, a, b) {
|
|
const a_uid = a.GetUID();
|
|
const b_uid = b.GetUID();
|
|
if (a_uid < b_uid)
|
|
return collMemory.Get(a, b);
|
|
else
|
|
return collMemory.Get(b, a)
|
|
}
|
|
function DoOverlapCondition(sdkInst, rtype, offX, offY) {
|
|
if (!rtype)
|
|
return false;
|
|
const inst = sdkInst.GetInstance();
|
|
const hasOffset = offX !== 0 || offY !== 0;
|
|
const wi = inst.GetWorldInfo();
|
|
const runtime = inst.GetRuntime();
|
|
const collisionEngine = runtime.GetCollisionEngine();
|
|
const cnd = runtime.GetCurrentCondition();
|
|
const isOrBlock = cnd.GetEventBlock().IsOrBlock();
|
|
const ltype = cnd.GetObjectClass();
|
|
const isInverted = cnd.IsInverted();
|
|
const rsol = rtype.GetCurrentSol();
|
|
const isDifferentTypes = ltype !== rtype;
|
|
rPickType = rtype;
|
|
needsCollisionFinish = isDifferentTypes && !isInverted;
|
|
rPickFromElseInstances = false;
|
|
let rinstances;
|
|
let oldX = 0;
|
|
let oldY = 0;
|
|
let ret = false;
|
|
if (rsol.IsSelectAll()) {
|
|
tempRect.copy(wi.GetBoundingBox());
|
|
tempRect.offset(offX, offY);
|
|
collisionEngine.GetCollisionCandidates(wi.GetLayer(), rtype, tempRect, tempCandidates2);
|
|
rinstances = tempCandidates2
|
|
} else if (isOrBlock)
|
|
if (runtime.IsCurrentConditionFirst() && !rsol._GetOwnElseInstances().length && rsol._GetOwnInstances().length)
|
|
rinstances = rsol._GetOwnInstances();
|
|
else {
|
|
rinstances = rsol._GetOwnElseInstances();
|
|
rPickFromElseInstances = true
|
|
}
|
|
else
|
|
rinstances = rsol._GetOwnInstances();
|
|
if (hasOffset) {
|
|
oldX = wi.GetX();
|
|
oldY = wi.GetY();
|
|
wi.OffsetXY(offX, offY);
|
|
wi.SetBboxChanged()
|
|
}
|
|
for (const rinst of rinstances)
|
|
if (collisionEngine.TestOverlap(inst, rinst)) {
|
|
ret = true;
|
|
if (isInverted)
|
|
break;
|
|
if (isDifferentTypes)
|
|
rToPick.add(rinst)
|
|
}
|
|
if (hasOffset) {
|
|
wi.SetXY(oldX, oldY);
|
|
wi.SetBboxChanged()
|
|
}
|
|
C3.clearArray(tempCandidates2);
|
|
return ret
|
|
}
|
|
function FinishCollisionConditionPicking(type) {
|
|
const isOrBlock = type.GetRuntime().GetCurrentEvent().IsOrBlock();
|
|
const sol = rPickType.GetCurrentSol();
|
|
const solInstances = sol._GetOwnInstances();
|
|
const solElseInstances = sol._GetOwnElseInstances();
|
|
if (sol.IsSelectAll()) {
|
|
sol.SetSetPicked(rToPick);
|
|
if (isOrBlock) {
|
|
C3.clearArray(solElseInstances);
|
|
sol.AddElseInstances(rToPick, rPickType.GetInstances())
|
|
}
|
|
} else if (isOrBlock)
|
|
if (rPickFromElseInstances)
|
|
sol.TransferElseInstancesToOwn(rToPick);
|
|
else {
|
|
sol.AddElseInstances(rToPick, solInstances);
|
|
sol.SetSetPicked(rToPick)
|
|
}
|
|
else
|
|
sol.SetSetPicked(rToPick);
|
|
rPickType.ApplySolToContainer()
|
|
}
|
|
C3.Plugins.Sprite._FinishCondition = function(type, doPick) {
|
|
if (!needsCollisionFinish)
|
|
return;
|
|
if (doPick)
|
|
FinishCollisionConditionPicking(type);
|
|
rToPick.clear();
|
|
rPickType = null;
|
|
needsCollisionFinish = false
|
|
}
|
|
;
|
|
C3.Plugins.Sprite.Cnds = {
|
|
OnCollision(rtype) {
|
|
if (this._runtime.IsDebugging())
|
|
return C3.Plugins.Sprite.Cnds.DebugOnCollision.call(this, rtype);
|
|
if (!rtype)
|
|
return false;
|
|
const runtime = this._runtime;
|
|
const collisionEngine = runtime.GetCollisionEngine();
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const cnd = eventSheetManager.GetCurrentCondition();
|
|
const ltype = cnd.GetObjectClass();
|
|
const savedData = cnd.GetSavedDataMap();
|
|
const unsavedData = cnd.GetUnsavedDataMap();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const tickCount = runtime.GetTickCount();
|
|
const lastTickCount = tickCount - 1;
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
let collMemory = savedData.get("collmemory");
|
|
if (!collMemory) {
|
|
collMemory = C3.New(C3.PairMap);
|
|
savedData.set("collmemory", collMemory)
|
|
}
|
|
if (!unsavedData.get("spriteCreatedDestroyCallback")) {
|
|
unsavedData.set("spriteCreatedDestroyCallback", true);
|
|
runtime.Dispatcher().addEventListener("instancedestroy", e=>CollMemory_RemoveInstance(collMemory, e.instance))
|
|
}
|
|
const lsol = ltype.GetCurrentSol();
|
|
const rsol = rtype.GetCurrentSol();
|
|
const linstances = lsol.GetInstances();
|
|
let rinstances = null;
|
|
for (let l = 0; l < linstances.length; ++l) {
|
|
const linst = linstances[l];
|
|
if (rsol.IsSelectAll()) {
|
|
collisionEngine.GetCollisionCandidates(linst.GetWorldInfo().GetLayer(), rtype, linst.GetWorldInfo().GetBoundingBox(), tempCandidates1);
|
|
rinstances = tempCandidates1;
|
|
collisionEngine.AddRegisteredCollisionCandidates(linst, rtype, rinstances)
|
|
} else
|
|
rinstances = rsol.GetInstances();
|
|
for (let r = 0; r < rinstances.length; ++r) {
|
|
const rinst = rinstances[r];
|
|
if (collisionEngine.TestOverlap(linst, rinst) || collisionEngine.CheckRegisteredCollision(linst, rinst)) {
|
|
const entry = CollMemory_Get(collMemory, linst, rinst);
|
|
let entryExists = false;
|
|
let lastCollTickCount = -2;
|
|
if (typeof entry === "number") {
|
|
entryExists = true;
|
|
lastCollTickCount = entry
|
|
}
|
|
const shouldRun = !entryExists || lastCollTickCount < lastTickCount;
|
|
CollMemory_Add(collMemory, linst, rinst, tickCount);
|
|
if (shouldRun) {
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
const curlsol = ltype.GetCurrentSol();
|
|
const currsol = rtype.GetCurrentSol();
|
|
curlsol._SetSelectAll(false);
|
|
currsol._SetSelectAll(false);
|
|
if (ltype === rtype) {
|
|
const solInstances = curlsol._GetOwnInstances();
|
|
C3.clearArray(solInstances);
|
|
solInstances.push(linst);
|
|
solInstances.push(rinst);
|
|
ltype.ApplySolToContainer()
|
|
} else {
|
|
const lsolInstances = curlsol._GetOwnInstances();
|
|
const rsolInstances = currsol._GetOwnInstances();
|
|
C3.clearArray(lsolInstances);
|
|
C3.clearArray(rsolInstances);
|
|
lsolInstances.push(linst);
|
|
rsolInstances.push(rinst);
|
|
ltype.ApplySolToContainer();
|
|
rtype.ApplySolToContainer()
|
|
}
|
|
currentEvent.Retrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
} else
|
|
CollMemory_Remove(collMemory, linst, rinst)
|
|
}
|
|
C3.clearArray(tempCandidates1)
|
|
}
|
|
eventStack.Pop();
|
|
return false
|
|
},
|
|
*DebugOnCollision(rtype) {
|
|
if (!rtype)
|
|
return false;
|
|
const runtime = this._runtime;
|
|
const collisionEngine = runtime.GetCollisionEngine();
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const eventStack = eventSheetManager.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const tickCount = runtime.GetTickCount();
|
|
const lastTickCount = tickCount - 1;
|
|
const currentEvent = oldFrame.GetCurrentEvent();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const cnd = eventSheetManager.GetCurrentCondition();
|
|
const ltype = cnd.GetObjectClass();
|
|
const savedData = cnd.GetSavedDataMap();
|
|
const unsavedData = cnd.GetUnsavedDataMap();
|
|
let collMemory = savedData.get("collmemory");
|
|
if (!collMemory) {
|
|
collMemory = C3.New(C3.PairMap);
|
|
savedData.set("collmemory", collMemory)
|
|
}
|
|
if (!unsavedData.get("spriteCreatedDestroyCallback")) {
|
|
unsavedData.set("spriteCreatedDestroyCallback", true);
|
|
runtime.Dispatcher().addEventListener("instancedestroy", e=>CollMemory_RemoveInstance(collMemory, e.instance))
|
|
}
|
|
const lsol = ltype.GetCurrentSol();
|
|
const rsol = rtype.GetCurrentSol();
|
|
const linstances = lsol.GetInstances();
|
|
let rinstances = null;
|
|
for (let l = 0; l < linstances.length; ++l) {
|
|
const linst = linstances[l];
|
|
if (rsol.IsSelectAll()) {
|
|
collisionEngine.GetCollisionCandidates(linst.GetWorldInfo().GetLayer(), rtype, linst.GetWorldInfo().GetBoundingBox(), tempCandidates1);
|
|
rinstances = tempCandidates1;
|
|
collisionEngine.AddRegisteredCollisionCandidates(linst, rtype, rinstances)
|
|
} else
|
|
rinstances = rsol.GetInstances();
|
|
for (let r = 0; r < rinstances.length; ++r) {
|
|
const rinst = rinstances[r];
|
|
if (collisionEngine.TestOverlap(linst, rinst) || collisionEngine.CheckRegisteredCollision(linst, rinst)) {
|
|
const entry = CollMemory_Get(collMemory, linst, rinst);
|
|
let entryExists = false;
|
|
let lastCollTickCount = -2;
|
|
if (typeof entry === "number") {
|
|
entryExists = true;
|
|
lastCollTickCount = entry
|
|
}
|
|
const shouldRun = !entryExists || lastCollTickCount < lastTickCount;
|
|
CollMemory_Add(collMemory, linst, rinst, tickCount);
|
|
if (shouldRun) {
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
const curlsol = ltype.GetCurrentSol();
|
|
const currsol = rtype.GetCurrentSol();
|
|
curlsol._SetSelectAll(false);
|
|
currsol._SetSelectAll(false);
|
|
if (ltype === rtype) {
|
|
const solInstances = curlsol._GetOwnInstances();
|
|
C3.clearArray(solInstances);
|
|
solInstances.push(linst);
|
|
solInstances.push(rinst);
|
|
ltype.ApplySolToContainer()
|
|
} else {
|
|
const lsolInstances = curlsol._GetOwnInstances();
|
|
const rsolInstances = currsol._GetOwnInstances();
|
|
C3.clearArray(lsolInstances);
|
|
C3.clearArray(rsolInstances);
|
|
lsolInstances.push(linst);
|
|
rsolInstances.push(rinst);
|
|
ltype.ApplySolToContainer();
|
|
rtype.ApplySolToContainer()
|
|
}
|
|
yield*currentEvent.DebugRetrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
} else
|
|
CollMemory_Remove(collMemory, linst, rinst)
|
|
}
|
|
C3.clearArray(tempCandidates1)
|
|
}
|
|
eventStack.Pop();
|
|
return false
|
|
},
|
|
IsOverlapping(rtype) {
|
|
return DoOverlapCondition(this, rtype, 0, 0)
|
|
},
|
|
IsOverlappingOffset(rtype, offX, offY) {
|
|
return DoOverlapCondition(this, rtype, offX, offY)
|
|
},
|
|
IsAnimPlaying(animName) {
|
|
return C3.equalsNoCase(this._GetCurrentAnimationName(), animName)
|
|
},
|
|
CompareFrame(cmp, frameNum) {
|
|
return C3.compare(this._currentFrameIndex, cmp, frameNum)
|
|
},
|
|
CompareAnimSpeed(cmp, x) {
|
|
return C3.compare(this._GetAnimSpeed(), cmp, x)
|
|
},
|
|
OnAnimFinished(animName) {
|
|
return C3.equalsNoCase(this._animTriggerName, animName)
|
|
},
|
|
OnAnyAnimFinished() {
|
|
return true
|
|
},
|
|
OnFrameChanged() {
|
|
return true
|
|
},
|
|
IsMirrored() {
|
|
return this.GetWorldInfo().GetWidth() < 0
|
|
},
|
|
IsFlipped() {
|
|
return this.GetWorldInfo().GetHeight() < 0
|
|
},
|
|
OnURLLoaded() {
|
|
return true
|
|
},
|
|
OnURLFailed() {
|
|
return true
|
|
},
|
|
IsCollisionEnabled() {
|
|
return this.GetWorldInfo().IsCollisionEnabled()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Sprite.Acts = {
|
|
Spawn(objectClass, layer, imgPt) {
|
|
if (!objectClass || !layer)
|
|
return;
|
|
const [imgPtX,imgPtY] = this.GetImagePoint(imgPt);
|
|
const inst = this._runtime.CreateInstance(objectClass, layer, imgPtX, imgPtY);
|
|
if (!inst)
|
|
return;
|
|
if (objectClass.GetPlugin().IsRotatable()) {
|
|
const instWi = inst.GetWorldInfo();
|
|
instWi.SetAngle(this.GetWorldInfo().GetAngle());
|
|
instWi.SetBboxChanged()
|
|
}
|
|
const eventSheetManager = this._runtime.GetEventSheetManager();
|
|
eventSheetManager.BlockFlushingInstances(true);
|
|
inst._TriggerOnCreated();
|
|
if (inst.IsInContainer())
|
|
for (const s of inst.siblings())
|
|
s._TriggerOnCreated();
|
|
eventSheetManager.BlockFlushingInstances(false);
|
|
const act = this._runtime.GetCurrentAction();
|
|
const actData = act.GetSavedDataMap();
|
|
let resetSol = false;
|
|
if (!actData.has("Spawn_LastExec") || actData.get("Spawn_LastExec") < this._runtime.GetExecCount()) {
|
|
resetSol = true;
|
|
actData.set("Spawn_LastExec", this._runtime.GetExecCount())
|
|
}
|
|
if (objectClass !== this.GetObjectClass()) {
|
|
const sol = objectClass.GetCurrentSol();
|
|
sol._SetSelectAll(false);
|
|
const solInstances = sol._GetOwnInstances();
|
|
if (resetSol) {
|
|
C3.clearArray(solInstances);
|
|
solInstances.push(inst)
|
|
} else
|
|
solInstances.push(inst);
|
|
if (inst.IsInContainer())
|
|
for (const s of inst.siblings()) {
|
|
const sol2 = s.GetObjectClass().GetCurrentSol();
|
|
if (resetSol)
|
|
sol2.SetSinglePicked(s);
|
|
else {
|
|
sol2._SetSelectAll(false);
|
|
sol2._PushInstance(s)
|
|
}
|
|
}
|
|
}
|
|
},
|
|
StopAnim() {
|
|
this.SetAnimationPlaying(false)
|
|
},
|
|
StartAnim(from) {
|
|
this._StartAnim(from)
|
|
},
|
|
SetAnim(animName, from) {
|
|
this._SetAnim(animName, from)
|
|
},
|
|
SetAnimFrame(frameNum) {
|
|
this._SetAnimFrame(frameNum)
|
|
},
|
|
SetAnimSpeed(s) {
|
|
this._SetAnimSpeed(s)
|
|
},
|
|
SetAnimRepeatToFrame(f) {
|
|
this._SetAnimRepeatToFrame(f)
|
|
},
|
|
SetMirrored(m) {
|
|
const wi = this.GetWorldInfo();
|
|
const oldW = wi.GetWidth();
|
|
const newW = Math.abs(oldW) * (m === 0 ? -1 : 1);
|
|
if (oldW === newW)
|
|
return;
|
|
wi.SetWidth(newW);
|
|
wi.SetBboxChanged()
|
|
},
|
|
SetFlipped(f) {
|
|
const wi = this.GetWorldInfo();
|
|
const oldH = wi.GetHeight();
|
|
const newH = Math.abs(oldH) * (f === 0 ? -1 : 1);
|
|
if (oldH === newH)
|
|
return;
|
|
wi.SetHeight(newH);
|
|
wi.SetBboxChanged()
|
|
},
|
|
SetScale(s) {
|
|
const frame = this._currentAnimationFrame;
|
|
const imageInfo = frame.GetImageInfo();
|
|
const wi = this.GetWorldInfo();
|
|
const mirrorFactor = wi.GetWidth() < 0 ? -1 : 1;
|
|
const flipFactor = wi.GetHeight() < 0 ? -1 : 1;
|
|
const newWidth = imageInfo.GetWidth() * s * mirrorFactor;
|
|
const newHeight = imageInfo.GetHeight() * s * flipFactor;
|
|
if (wi.GetWidth() !== newWidth || wi.GetHeight() !== newHeight) {
|
|
wi.SetSize(newWidth, newHeight);
|
|
wi.SetBboxChanged()
|
|
}
|
|
},
|
|
async LoadURL(url, resize, crossOrigin) {
|
|
const curAnimFrame = this._currentAnimationFrame;
|
|
const curImageInfo = curAnimFrame.GetImageInfo();
|
|
const wi = this.GetWorldInfo();
|
|
const runtime = this._runtime;
|
|
if (curImageInfo.GetURL() === url) {
|
|
if (resize === 0) {
|
|
wi.SetSize(curImageInfo.GetWidth(), curImageInfo.GetHeight());
|
|
wi.SetBboxChanged()
|
|
}
|
|
this.Trigger(C3.Plugins.Sprite.Cnds.OnURLLoaded);
|
|
return
|
|
}
|
|
const imageInfo = C3.New(C3.ImageInfo);
|
|
await imageInfo.LoadDynamicAsset(runtime, url);
|
|
if (!imageInfo.IsLoaded()) {
|
|
this.Trigger(C3.Plugins.Sprite.Cnds.OnURLFailed);
|
|
return
|
|
}
|
|
await imageInfo.LoadStaticTexture(runtime.GetWebGLRenderer(), {
|
|
sampling: this._runtime.GetSampling()
|
|
});
|
|
curImageInfo.ReplaceWith(imageInfo);
|
|
this._sdkType._UpdateAllCurrentTexture();
|
|
if (!this.WasReleased() && resize === 0) {
|
|
wi.SetSize(curImageInfo.GetWidth(), curImageInfo.GetHeight());
|
|
wi.SetBboxChanged()
|
|
}
|
|
runtime.UpdateRender();
|
|
if (!this.WasReleased())
|
|
await this.TriggerAsync(C3.Plugins.Sprite.Cnds.OnURLLoaded)
|
|
},
|
|
SetCollisions(e) {
|
|
this.GetWorldInfo().SetCollisionEnabled(e)
|
|
},
|
|
SetSolidCollisionFilter(mode, tags) {
|
|
this.GetWorldInfo().SetSolidCollisionFilter(mode === 0, tags)
|
|
},
|
|
SetEffect(effect) {
|
|
this.GetWorldInfo().SetBlendMode(effect);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Sprite.Exps = {
|
|
AnimationFrame() {
|
|
return this._currentFrameIndex
|
|
},
|
|
AnimationFrameCount() {
|
|
return this._currentAnimation.GetFrameCount()
|
|
},
|
|
AnimationName() {
|
|
return this._currentAnimation.GetName()
|
|
},
|
|
AnimationSpeed() {
|
|
return this._GetAnimSpeed()
|
|
},
|
|
OriginalAnimationSpeed() {
|
|
return this._currentAnimation.GetSpeed()
|
|
},
|
|
ImagePointX(imgpt) {
|
|
return this.GetImagePoint(imgpt)[0]
|
|
},
|
|
ImagePointY(imgpt) {
|
|
return this.GetImagePoint(imgpt)[1]
|
|
},
|
|
ImagePointCount() {
|
|
return this.GetImagePointCount()
|
|
},
|
|
ImageWidth() {
|
|
return this.GetCurrentImageInfo().GetWidth()
|
|
},
|
|
ImageHeight() {
|
|
return this.GetCurrentImageInfo().GetHeight()
|
|
},
|
|
PolyPointXAt(i) {
|
|
return this.GetCollisionPolyPoint(i)[0]
|
|
},
|
|
PolyPointYAt(i) {
|
|
return this.GetCollisionPolyPoint(i)[1]
|
|
},
|
|
PolyPointCount() {
|
|
return this.GetCollisionPolyPointCount()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.NinePatch = class NinePatchPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.NinePatch.Type = class NinePatchType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass);
|
|
this._textureSet = null;
|
|
this._drawable = null
|
|
}
|
|
Release() {
|
|
this.ReleaseTextures();
|
|
super.Release()
|
|
}
|
|
OnCreate() {
|
|
this.GetImageInfo().LoadAsset(this._runtime)
|
|
}
|
|
async LoadTextures(renderer) {
|
|
const imageInfo = this.GetImageInfo();
|
|
this._drawable = await imageInfo.ExtractImageToCanvas()
|
|
}
|
|
CreatePatch(lm, rm, tm, bm) {
|
|
if (this._textureSet || !this._drawable)
|
|
return;
|
|
this._textureSet = new self.NinePatchTextureSet(this);
|
|
this._textureSet.CreateTextures(this._drawable, lm, rm, tm, bm)
|
|
}
|
|
ReleaseTextures() {
|
|
if (this._textureSet) {
|
|
this._textureSet.Release();
|
|
this._textureSet = null
|
|
}
|
|
}
|
|
GetTextureSet() {
|
|
return this._textureSet
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const LEFT_MARGIN = 0;
|
|
const RIGHT_MARGIN = 1;
|
|
const TOP_MARGIN = 2;
|
|
const BOTTOM_MARGIN = 3;
|
|
const EDGES = 4;
|
|
const FILL = 5;
|
|
const INITIALLY_VISIBLE = 6;
|
|
const ORIGIN = 7;
|
|
const SEAMS = 8;
|
|
const tempRect = C3.New(C3.Rect);
|
|
const tempQuad = C3.New(C3.Quad);
|
|
C3.Plugins.NinePatch.Instance = class NinePatchInstance extends C3.SDKWorldInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this._leftMargin = 16;
|
|
this._rightMargin = 16;
|
|
this._topMargin = 16;
|
|
this._bottomMargin = 16;
|
|
this._edges = 1;
|
|
this._fill = 1;
|
|
this._isSeamless = true;
|
|
if (properties) {
|
|
this._leftMargin = properties[LEFT_MARGIN];
|
|
this._rightMargin = properties[RIGHT_MARGIN];
|
|
this._topMargin = properties[TOP_MARGIN];
|
|
this._bottomMargin = properties[BOTTOM_MARGIN];
|
|
this._edges = properties[EDGES];
|
|
this._fill = properties[FILL];
|
|
this._isSeamless = !!properties[SEAMS];
|
|
this.GetWorldInfo().SetVisible(!!properties[INITIALLY_VISIBLE])
|
|
}
|
|
this._sdkType.CreatePatch(this._leftMargin, this._rightMargin, this._topMargin, this._bottomMargin)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
Draw(renderer) {
|
|
let textureSet = this._sdkType.GetTextureSet();
|
|
if (!textureSet) {
|
|
this._sdkType.CreatePatch(this._leftMargin, this._rightMargin, this._topMargin, this._bottomMargin);
|
|
textureSet = this._sdkType.GetTextureSet();
|
|
if (!textureSet)
|
|
return
|
|
}
|
|
const wi = this.GetWorldInfo();
|
|
const lm = this._leftMargin;
|
|
const rm = this._rightMargin;
|
|
const tm = this._topMargin;
|
|
const bm = this._bottomMargin;
|
|
const iw = textureSet.GetImageWidth();
|
|
const ih = textureSet.GetImageHeight();
|
|
const re = iw - rm;
|
|
const be = ih - bm;
|
|
const bquad = wi.GetBoundingQuad();
|
|
const myx = bquad.getTlx();
|
|
const myy = bquad.getTly();
|
|
const myw = wi.GetWidth();
|
|
const myh = wi.GetHeight();
|
|
const s = this._isSeamless ? 1 : 0;
|
|
const edges = this._edges;
|
|
const fill = this._fill;
|
|
if (lm > 0 && tm > 0)
|
|
this._DrawPatch(renderer, textureSet.GetTexture(), 0, 0, lm + s, tm + s, myx, myy, lm + s, tm + s);
|
|
if (rm > 0 && tm > 0)
|
|
this._DrawPatch(renderer, textureSet.GetTexture(), re - s, 0, rm + s, tm + s, myx + myw - rm - s, myy, rm + s, tm + s);
|
|
if (rm > 0 && bm > 0)
|
|
this._DrawPatch(renderer, textureSet.GetTexture(), re - s, be - s, rm + s, bm + s, myx + myw - rm - s, myy + myh - bm - s, rm + s, bm + s);
|
|
if (lm > 0 && bm > 0)
|
|
this._DrawPatch(renderer, textureSet.GetTexture(), 0, be - s, lm + s, bm + s, myx, myy + myh - bm - s, lm + s, bm + s);
|
|
if (edges === 0) {
|
|
const off = fill === 2 ? 0 : s;
|
|
if (lm > 0 && be > tm)
|
|
this._TilePatch(renderer, textureSet.GetLeftTexture(), myx, myy + tm, lm + off, myh - tm - bm, 0, 0);
|
|
if (rm > 0 && be > tm)
|
|
this._TilePatch(renderer, textureSet.GetRightTexture(), myx + myw - rm - off, myy + tm, rm + off, myh - tm - bm, off, 0);
|
|
if (tm > 0 && re > lm)
|
|
this._TilePatch(renderer, textureSet.GetTopTexture(), myx + lm, myy, myw - lm - rm, tm + off, 0, 0);
|
|
if (bm > 0 && re > lm)
|
|
this._TilePatch(renderer, textureSet.GetBottomTexture(), myx + lm, myy + myh - bm - off, myw - lm - rm, bm + off, 0, off)
|
|
} else if (edges === 1) {
|
|
if (lm > 0 && be > tm)
|
|
this._DrawPatch(renderer, textureSet.GetTexture(), 0, tm, lm, be - tm, myx, myy + tm, lm, myh - tm - bm);
|
|
if (rm > 0 && be > tm)
|
|
this._DrawPatch(renderer, textureSet.GetTexture(), re, tm, rm, be - tm, myx + myw - rm, myy + tm, rm, myh - tm - bm);
|
|
if (tm > 0 && re > lm)
|
|
this._DrawPatch(renderer, textureSet.GetTexture(), lm, 0, re - lm, tm, myx + lm, myy, myw - lm - rm, tm);
|
|
if (bm > 0 && re > lm)
|
|
this._DrawPatch(renderer, textureSet.GetTexture(), lm, be, re - lm, bm, myx + lm, myy + myh - bm, myw - lm - rm, bm)
|
|
}
|
|
if (be > tm && re > lm)
|
|
if (fill === 0)
|
|
this._TilePatch(renderer, textureSet.GetFillTexture(), myx + lm, myy + tm, myw - lm - rm, myh - tm - bm, 0, 0);
|
|
else if (fill === 1)
|
|
this._DrawPatch(renderer, textureSet.GetTexture(), lm, tm, re - lm, be - tm, myx + lm, myy + tm, myw - lm - rm, myh - tm - bm)
|
|
}
|
|
_DrawPatch(renderer, tex, sx, sy, sw, sh, dx, dy, dw, dh) {
|
|
const texW = tex.GetWidth();
|
|
const texH = tex.GetHeight();
|
|
renderer.SetTexture(tex);
|
|
const wi = this.GetWorldInfo();
|
|
const bquad = wi.GetBoundingQuad();
|
|
const offX = bquad.getTlx();
|
|
const offY = bquad.getTly();
|
|
tempRect.set(dx, dy, dx + dw, dy + dh);
|
|
tempRect.offset(-offX, -offY);
|
|
tempQuad.setFromRotatedRect(tempRect, wi.GetAngle());
|
|
tempQuad.offset(offX, offY);
|
|
tempRect.set(sx / texW, sy / texH, (sx + sw) / texW, (sy + sh) / texH);
|
|
renderer.Quad3(tempQuad, tempRect)
|
|
}
|
|
_TilePatch(renderer, tex, dx, dy, dw, dh, ox, oy) {
|
|
const texW = tex.GetWidth();
|
|
const texH = tex.GetHeight();
|
|
renderer.SetTexture(tex);
|
|
const wi = this.GetWorldInfo();
|
|
const bquad = wi.GetBoundingQuad();
|
|
const offX = bquad.getTlx();
|
|
const offY = bquad.getTly();
|
|
tempRect.set(dx, dy, dx + dw, dy + dh);
|
|
tempRect.offset(-offX, -offY);
|
|
tempQuad.setFromRotatedRect(tempRect, wi.GetAngle());
|
|
tempQuad.offset(offX, offY);
|
|
tempRect.set(-ox / texW, -oy / texH, (dw - ox) / texW, (dh - oy) / texH);
|
|
renderer.Quad3(tempQuad, tempRect)
|
|
}
|
|
GetCurrentImageInfo() {
|
|
this._objectClass.GetImageInfo()
|
|
}
|
|
GetPropertyValueByIndex(index) {}
|
|
SetPropertyValueByIndex(index, value) {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.NinePatch.Cnds = {}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.NinePatch.Acts = {
|
|
SetEffect(effect) {
|
|
this.GetWorldInfo().SetBlendMode(effect);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.NinePatch.Exps = {}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function CloneDrawable(drawable) {
|
|
const canvas = C3.CreateCanvas(drawable.width, drawable.height);
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.drawImage(drawable, 0, 0);
|
|
return canvas
|
|
}
|
|
self.NinePatchTextureSet = class NinePatchTextureSet {
|
|
constructor(sdkType) {
|
|
this._sdkType = sdkType;
|
|
this._runtime = this._sdkType.GetRuntime();
|
|
this._texture = null;
|
|
this._fillTexture = null;
|
|
this._leftTexture = null;
|
|
this._rightTexture = null;
|
|
this._topTexture = null;
|
|
this._bottomTexture = null;
|
|
this._imageWidth = 0;
|
|
this._imageHeight = 0;
|
|
this._renderer = this._runtime.GetWebGLRenderer();
|
|
this._isLoading = false;
|
|
this._wasReleased = false
|
|
}
|
|
Release() {
|
|
if (!this._renderer.IsContextLost()) {
|
|
this._renderer.DeleteTexture(this._texture);
|
|
this._renderer.DeleteTexture(this._fillTexture);
|
|
this._renderer.DeleteTexture(this._leftTexture);
|
|
this._renderer.DeleteTexture(this._rightTexture);
|
|
this._renderer.DeleteTexture(this._topTexture);
|
|
this._renderer.DeleteTexture(this._bottomTexture)
|
|
}
|
|
this._texture = null;
|
|
this._fillTexture = null;
|
|
this._leftTexture = null;
|
|
this._rightTexture = null;
|
|
this._topTexture = null;
|
|
this._bottomTexture = null;
|
|
this._sdkType = null;
|
|
this._renderer = null;
|
|
this._wasReleased = true
|
|
}
|
|
WasReleased() {
|
|
return this._wasReleased
|
|
}
|
|
CreateTextures(drawable, lm, rm, tm, bm) {
|
|
this._SliceImage(drawable, lm, rm, tm, bm)
|
|
}
|
|
HasCreatedTextures() {
|
|
return !!this._texture
|
|
}
|
|
_SliceImage(drawable, lm, rm, tm, bm) {
|
|
if (this._wasReleased)
|
|
return;
|
|
const iw = drawable.width;
|
|
const ih = drawable.height;
|
|
this._imageWidth = iw;
|
|
this._imageHeight = ih;
|
|
const re = iw - rm;
|
|
const be = ih - bm;
|
|
const sampling = this._runtime.GetSampling();
|
|
this._texture = this._renderer.CreateStaticTexture(CloneDrawable(drawable), {
|
|
sampling
|
|
});
|
|
if (re > lm && be > tm)
|
|
this._fillTexture = this._renderer.CreateStaticTexture(this._SliceSubImage(CloneDrawable(drawable), lm, tm, re, be), {
|
|
wrapX: "repeat",
|
|
wrapY: "repeat",
|
|
sampling
|
|
});
|
|
if (lm > 0 && be > tm)
|
|
this._leftTexture = this._renderer.CreateStaticTexture(this._SliceSubImage(CloneDrawable(drawable), 0, tm, lm, be), {
|
|
wrapY: "repeat",
|
|
sampling
|
|
});
|
|
if (rm > 0 && be > tm)
|
|
this._rightTexture = this._renderer.CreateStaticTexture(this._SliceSubImage(CloneDrawable(drawable), re, tm, iw, be), {
|
|
wrapY: "repeat",
|
|
sampling
|
|
});
|
|
if (tm > 0 && re > lm)
|
|
this._topTexture = this._renderer.CreateStaticTexture(this._SliceSubImage(CloneDrawable(drawable), lm, 0, re, tm), {
|
|
wrapX: "repeat",
|
|
sampling
|
|
});
|
|
if (bm > 0 && re > lm)
|
|
this._bottomTexture = this._renderer.CreateStaticTexture(this._SliceSubImage(CloneDrawable(drawable), lm, be, re, ih), {
|
|
wrapX: "repeat",
|
|
sampling
|
|
})
|
|
}
|
|
_SliceSubImage(drawable, x1, y1, x2, y2) {
|
|
const w = x2 - x1;
|
|
const h = y2 - y1;
|
|
const tmpCanvas = C3.CreateCanvas(w, h);
|
|
const tmpCtx = tmpCanvas.getContext("2d");
|
|
tmpCtx.drawImage(drawable, x1, y1, w, h, 0, 0, w, h);
|
|
return tmpCanvas
|
|
}
|
|
GetImageWidth() {
|
|
return this._imageWidth
|
|
}
|
|
GetImageHeight() {
|
|
return this._imageHeight
|
|
}
|
|
GetTexture() {
|
|
return this._texture
|
|
}
|
|
GetFillTexture() {
|
|
return this._fillTexture
|
|
}
|
|
GetLeftTexture() {
|
|
return this._leftTexture
|
|
}
|
|
GetRightTexture() {
|
|
return this._rightTexture
|
|
}
|
|
GetTopTexture() {
|
|
return this._topTexture
|
|
}
|
|
GetBottomTexture() {
|
|
return this._bottomTexture
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Arr = class ArrayPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Arr.Type = class ArrayType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const IInstance = self.IInstance;
|
|
function ResizeArray(arr, len, data) {
|
|
if (len < arr.length)
|
|
C3.truncateArray(arr, len);
|
|
else if (len > arr.length)
|
|
if (typeof data === "function")
|
|
for (let i = arr.length; i < len; ++i)
|
|
arr.push(data());
|
|
else
|
|
for (let i = arr.length; i < len; ++i)
|
|
arr.push(data)
|
|
}
|
|
C3.Plugins.Arr.Instance = class ArrayInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this._cx = 10;
|
|
this._cy = 1;
|
|
this._cz = 1;
|
|
this._arr = null;
|
|
this._forX = [];
|
|
this._forY = [];
|
|
this._forZ = [];
|
|
this._forDepth = -1;
|
|
if (properties) {
|
|
this._cx = properties[0];
|
|
this._cy = properties[1];
|
|
this._cz = properties[2]
|
|
}
|
|
this._arr = C3.MakeFilledArray(this._cx, ()=>C3.MakeFilledArray(this._cy, ()=>C3.MakeFilledArray(this._cz, 0)))
|
|
}
|
|
Release() {
|
|
this._arr = null;
|
|
super.Release()
|
|
}
|
|
At(x, y, z) {
|
|
x = Math.floor(x);
|
|
y = Math.floor(y);
|
|
z = Math.floor(z);
|
|
if (x >= 0 && x < this._cx && y >= 0 && y < this._cy && z >= 0 && z < this._cz)
|
|
return this._arr[x][y][z];
|
|
else
|
|
return 0
|
|
}
|
|
Set(x, y, z, val) {
|
|
x = Math.floor(x);
|
|
y = Math.floor(y);
|
|
z = Math.floor(z);
|
|
if (x >= 0 && x < this._cx && y >= 0 && y < this._cy && z >= 0 && z < this._cz)
|
|
this._arr[x][y][z] = val
|
|
}
|
|
SetSize(w, h, d) {
|
|
w = Math.floor(w);
|
|
h = Math.floor(h);
|
|
d = Math.floor(d);
|
|
if (w < 0)
|
|
w = 0;
|
|
if (h < 0)
|
|
h = 0;
|
|
if (d < 0)
|
|
d = 0;
|
|
if (this._cx === w && this._cy === h && this._cz === d)
|
|
return;
|
|
this._cx = w;
|
|
this._cy = h;
|
|
this._cz = d;
|
|
const arr = this._arr;
|
|
ResizeArray(arr, w, ()=>C3.MakeFilledArray(h, ()=>C3.MakeFilledArray(d, 0)));
|
|
for (let x = 0; x < w; ++x) {
|
|
ResizeArray(arr[x], h, ()=>C3.MakeFilledArray(d, 0));
|
|
for (let y = 0; y < h; ++y)
|
|
ResizeArray(arr[x][y], d, 0)
|
|
}
|
|
}
|
|
GetWidth() {
|
|
return this._cx
|
|
}
|
|
GetHeight() {
|
|
return this._cy
|
|
}
|
|
GetDepth() {
|
|
return this._cz
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "plugins.arr.debugger";
|
|
const propsPrefix = "plugins.arr.properties";
|
|
const ret = [{
|
|
title: prefix + ".array-properties.title",
|
|
properties: [{
|
|
name: propsPrefix + ".width.name",
|
|
value: this._cx,
|
|
onedit: v=>this.SetSize(v, this._cy, this._cz)
|
|
}, {
|
|
name: propsPrefix + ".height.name",
|
|
value: this._cy,
|
|
onedit: v=>this.SetSize(this._cx, v, this._cz)
|
|
}, {
|
|
name: propsPrefix + ".depth.name",
|
|
value: this._cz,
|
|
onedit: v=>this.SetSize(this._cx, this._cy, v)
|
|
}, {
|
|
name: propsPrefix + ".elements.name",
|
|
value: this._cx * this._cy * this._cz
|
|
}]
|
|
}];
|
|
const dataProps = [];
|
|
if (this._cy === 1 && this._cz === 1)
|
|
for (let x = 0; x < this._cx; ++x)
|
|
dataProps.push({
|
|
name: "$" + x,
|
|
value: this._arr[x][0][0],
|
|
onedit: v=>this._arr[x][0][0] = v
|
|
});
|
|
else
|
|
for (let x = 0; x < this._cx; ++x)
|
|
dataProps.push({
|
|
name: "$" + x,
|
|
value: this._arr[x].toString()
|
|
});
|
|
if (dataProps.length)
|
|
ret.push({
|
|
title: prefix + ".array-data.title",
|
|
properties: dataProps
|
|
});
|
|
return ret
|
|
}
|
|
GetAsJsonString() {
|
|
return JSON.stringify({
|
|
"c2array": true,
|
|
"size": [this._cx, this._cy, this._cz],
|
|
"data": this._arr
|
|
})
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"size": [this._cx, this._cy, this._cz],
|
|
"data": this._arr
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
const sz = o["size"];
|
|
this._cx = sz[0];
|
|
this._cy = sz[1];
|
|
this._cz = sz[2];
|
|
this._arr = o["data"]
|
|
}
|
|
_GetForX() {
|
|
if (this._forDepth >= 0 && this._forDepth < this._forX.length)
|
|
return this._forX[this._forDepth];
|
|
else
|
|
return 0
|
|
}
|
|
_GetForY() {
|
|
if (this._forDepth >= 0 && this._forDepth < this._forY.length)
|
|
return this._forY[this._forDepth];
|
|
else
|
|
return 0
|
|
}
|
|
_GetForZ() {
|
|
if (this._forDepth >= 0 && this._forDepth < this._forZ.length)
|
|
return this._forZ[this._forDepth];
|
|
else
|
|
return 0
|
|
}
|
|
GetScriptInterfaceClass() {
|
|
return self.IArrayInstance
|
|
}
|
|
}
|
|
;
|
|
const map = new WeakMap;
|
|
self.IArrayInstance = class IArrayInstance extends IInstance {
|
|
constructor() {
|
|
super();
|
|
map.set(this, IInstance._GetInitInst().GetSdkInstance())
|
|
}
|
|
get width() {
|
|
return map.get(this).GetWidth()
|
|
}
|
|
get height() {
|
|
return map.get(this).GetHeight()
|
|
}
|
|
get depth() {
|
|
return map.get(this).GetDepth()
|
|
}
|
|
setSize(w, h=1, d=1) {
|
|
map.get(this).SetSize(w, h, d)
|
|
}
|
|
getAt(x, y=0, z=0) {
|
|
return map.get(this).At(x, y, z)
|
|
}
|
|
setAt(val, x, y=0, z=0) {
|
|
if (typeof val !== "number" && typeof val !== "string")
|
|
throw new TypeError("invalid type");
|
|
map.get(this).Set(x, y, z, val)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function DoForEachTrigger(eventSheetManager, currentEvent, solModifiers, oldFrame, newFrame) {
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
currentEvent.Retrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
C3.Plugins.Arr.Cnds = {
|
|
CompareX(x, cmp, val) {
|
|
return C3.compare(this.At(x, 0, 0), cmp, val)
|
|
},
|
|
CompareXY(x, y, cmp, val) {
|
|
return C3.compare(this.At(x, y, 0), cmp, val)
|
|
},
|
|
CompareXYZ(x, y, z, cmp, val) {
|
|
return C3.compare(this.At(x, y, z), cmp, val)
|
|
},
|
|
ArrForEach(dims) {
|
|
const runtime = this._runtime;
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const currentEvent = runtime.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const eventStack = runtime.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const forDepth = ++this._forDepth;
|
|
const forX = this._forX;
|
|
const forY = this._forY;
|
|
const forZ = this._forZ;
|
|
const cx = this._cx;
|
|
const cy = this._cy;
|
|
const cz = this._cz;
|
|
if (forDepth === this._forX.length) {
|
|
forX.push(0);
|
|
forY.push(0);
|
|
forZ.push(0)
|
|
} else {
|
|
forX[forDepth] = 0;
|
|
forY[forDepth] = 0;
|
|
forZ[forDepth] = 0
|
|
}
|
|
runtime.SetDebuggingEnabled(false);
|
|
if (dims === 0)
|
|
for (let x = 0; x < cx; ++x)
|
|
for (let y = 0; y < cy; ++y)
|
|
for (let z = 0; z < cz; ++z) {
|
|
forX[forDepth] = x;
|
|
forY[forDepth] = y;
|
|
forZ[forDepth] = z;
|
|
DoForEachTrigger(eventSheetManager, currentEvent, solModifiers, oldFrame, newFrame)
|
|
}
|
|
else if (dims === 1)
|
|
for (let x = 0; x < cx; ++x)
|
|
for (let y = 0; y < cy; ++y) {
|
|
forX[forDepth] = x;
|
|
forY[forDepth] = y;
|
|
DoForEachTrigger(eventSheetManager, currentEvent, solModifiers, oldFrame, newFrame)
|
|
}
|
|
else
|
|
for (let x = 0; x < cx; ++x) {
|
|
forX[forDepth] = x;
|
|
DoForEachTrigger(eventSheetManager, currentEvent, solModifiers, oldFrame, newFrame)
|
|
}
|
|
runtime.SetDebuggingEnabled(true);
|
|
this._forDepth--;
|
|
eventStack.Pop();
|
|
return false
|
|
},
|
|
CompareCurrent(cmp, val) {
|
|
return C3.compare(this.At(this._GetForX(), this._GetForY(), this._GetForZ()), cmp, val)
|
|
},
|
|
Contains(val) {
|
|
const cx = this._cx;
|
|
const cy = this._cy;
|
|
const cz = this._cz;
|
|
const arr = this._arr;
|
|
for (let x = 0; x < cx; ++x)
|
|
for (let y = 0; y < cy; ++y)
|
|
for (let z = 0; z < cz; ++z)
|
|
if (arr[x][y][z] === val)
|
|
return true;
|
|
return false
|
|
},
|
|
IsEmpty() {
|
|
return this._cx === 0 || this._cy === 0 || this._cz === 0
|
|
},
|
|
CompareSize(axis, cmp, val) {
|
|
let s = 0;
|
|
switch (axis) {
|
|
case 0:
|
|
s = this._cx;
|
|
break;
|
|
case 1:
|
|
s = this._cy;
|
|
break;
|
|
case 2:
|
|
s = this._cz;
|
|
break
|
|
}
|
|
return C3.compare(s, cmp, val)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function CompareValues(va, vb) {
|
|
if (typeof va === "number" && typeof vb === "number")
|
|
return va - vb;
|
|
else {
|
|
const sa = va.toString();
|
|
const sb = vb.toString();
|
|
if (sa < sb)
|
|
return -1;
|
|
else if (sa > sb)
|
|
return 1;
|
|
else
|
|
return 0
|
|
}
|
|
}
|
|
C3.Plugins.Arr.Acts = {
|
|
Clear(v) {
|
|
const cx = this._cx;
|
|
const cy = this._cy;
|
|
const cz = this._cz;
|
|
const arr = this._arr;
|
|
for (let x = 0; x < cx; ++x)
|
|
for (let y = 0; y < cy; ++y)
|
|
for (let z = 0; z < cz; ++z)
|
|
arr[x][y][z] = v
|
|
},
|
|
SetSize(w, h, d) {
|
|
this.SetSize(w, h, d)
|
|
},
|
|
SetX(x, val) {
|
|
this.Set(x, 0, 0, val)
|
|
},
|
|
SetXY(x, y, val) {
|
|
this.Set(x, y, 0, val)
|
|
},
|
|
SetXYZ(x, y, z, val) {
|
|
this.Set(x, y, z, val)
|
|
},
|
|
Push(where, value, axis) {
|
|
const cx = this._cx;
|
|
const cy = this._cy;
|
|
const cz = this._cz;
|
|
const arr = this._arr;
|
|
if (axis === 0) {
|
|
const add = C3.MakeFilledArray(cy, ()=>C3.MakeFilledArray(cz, value));
|
|
if (where === 0)
|
|
arr.push(add);
|
|
else
|
|
arr.unshift(add);
|
|
this._cx++
|
|
} else if (axis === 1) {
|
|
for (let x = 0; x < cx; ++x) {
|
|
const add = C3.MakeFilledArray(cz, value);
|
|
if (where === 0)
|
|
arr[x].push(add);
|
|
else
|
|
arr[x].unshift(add)
|
|
}
|
|
this._cy++
|
|
} else {
|
|
for (let x = 0; x < cx; ++x)
|
|
for (let y = 0; y < cy; ++y)
|
|
if (where === 0)
|
|
arr[x][y].push(value);
|
|
else
|
|
arr[x][y].unshift(value);
|
|
this._cz++
|
|
}
|
|
},
|
|
Pop(where, axis) {
|
|
const cx = this._cx;
|
|
const cy = this._cy;
|
|
const cz = this._cz;
|
|
const arr = this._arr;
|
|
if (axis === 0) {
|
|
if (cx === 0)
|
|
return;
|
|
if (where === 0)
|
|
arr.pop();
|
|
else
|
|
arr.shift();
|
|
this._cx--
|
|
} else if (axis === 1) {
|
|
if (cy === 0)
|
|
return;
|
|
for (let x = 0; x < cx; ++x)
|
|
if (where === 0)
|
|
arr[x].pop();
|
|
else
|
|
arr[x].shift();
|
|
this._cy--
|
|
} else {
|
|
if (cz === 0)
|
|
return;
|
|
for (let x = 0; x < cx; ++x)
|
|
for (let y = 0; y < cy; ++y)
|
|
if (where === 0)
|
|
arr[x][y].pop();
|
|
else
|
|
arr[x][y].shift();
|
|
this._cz--
|
|
}
|
|
},
|
|
Reverse(axis) {
|
|
const cx = this._cx;
|
|
const cy = this._cy;
|
|
const cz = this._cz;
|
|
const arr = this._arr;
|
|
if (cx === 0 || cy === 0 || cz === 0)
|
|
return;
|
|
if (axis === 0)
|
|
arr.reverse();
|
|
else if (axis === 1)
|
|
for (let x = 0; x < cx; ++x)
|
|
arr[x].reverse();
|
|
else
|
|
for (let x = 0; x < cx; ++x)
|
|
for (let y = 0; y < cy; ++y)
|
|
arr[x][y].reverse()
|
|
},
|
|
Sort(axis) {
|
|
const cx = this._cx;
|
|
const cy = this._cy;
|
|
const cz = this._cz;
|
|
const arr = this._arr;
|
|
if (cx === 0 || cy === 0 || cz === 0)
|
|
return;
|
|
if (axis === 0)
|
|
arr.sort((a,b)=>CompareValues(a[0][0], b[0][0]));
|
|
else if (axis === 1)
|
|
for (let x = 0; x < cx; ++x)
|
|
arr[x].sort((a,b)=>CompareValues(a[0], b[0]));
|
|
else
|
|
for (let x = 0; x < cx; ++x)
|
|
for (let y = 0; y < cy; ++y)
|
|
arr[x][y].sort(CompareValues)
|
|
},
|
|
Delete(index, axis) {
|
|
index = Math.floor(index);
|
|
if (index < 0)
|
|
return;
|
|
const cx = this._cx;
|
|
const cy = this._cy;
|
|
const cz = this._cz;
|
|
const arr = this._arr;
|
|
if (axis === 0) {
|
|
if (index >= cx)
|
|
return;
|
|
arr.splice(index, 1);
|
|
this._cx--
|
|
} else if (axis === 1) {
|
|
if (index >= cy)
|
|
return;
|
|
for (let x = 0; x < cx; ++x)
|
|
arr[x].splice(index, 1);
|
|
this._cy--
|
|
} else {
|
|
if (index >= cz)
|
|
return;
|
|
for (let x = 0; x < cx; ++x)
|
|
for (let y = 0; y < cy; ++y)
|
|
arr[x][y].splice(index, 1);
|
|
this._cz--
|
|
}
|
|
},
|
|
Insert(value, index, axis) {
|
|
index = Math.floor(index);
|
|
if (index < 0)
|
|
return;
|
|
const cx = this._cx;
|
|
const cy = this._cy;
|
|
const cz = this._cz;
|
|
const arr = this._arr;
|
|
if (axis === 0) {
|
|
if (index > cx)
|
|
return;
|
|
arr.splice(index, 0, C3.MakeFilledArray(cy, ()=>C3.MakeFilledArray(cz, value)));
|
|
this._cx++
|
|
} else if (axis === 1) {
|
|
if (index > cy)
|
|
return;
|
|
for (let x = 0; x < cx; ++x)
|
|
arr[x].splice(index, 0, C3.MakeFilledArray(cz, value));
|
|
this._cy++
|
|
} else {
|
|
if (index > cz)
|
|
return;
|
|
for (let x = 0; x < cx; ++x)
|
|
for (let y = 0; y < cy; ++y)
|
|
arr[x][y].splice(index, 0, value);
|
|
this._cz++
|
|
}
|
|
},
|
|
JSONLoad(json) {
|
|
let o = null;
|
|
try {
|
|
o = JSON.parse(json)
|
|
} catch (err) {
|
|
console.error("[Construct 3] Failed to parse JSON: ", err);
|
|
return
|
|
}
|
|
if (!o["c2array"])
|
|
return;
|
|
const sz = o["size"];
|
|
this._cx = sz[0];
|
|
this._cy = sz[1];
|
|
this._cz = sz[2];
|
|
this._arr = o["data"]
|
|
},
|
|
JSONDownload(filename) {
|
|
const url = URL.createObjectURL(new Blob([this.GetAsJsonString()],{
|
|
type: "application/json"
|
|
}));
|
|
this._runtime.InvokeDownload(url, filename)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Arr.Exps = {
|
|
At(x, y, z) {
|
|
return this.At(x, y || 0, z || 0)
|
|
},
|
|
Width() {
|
|
return this._cx
|
|
},
|
|
Height() {
|
|
return this._cy
|
|
},
|
|
Depth() {
|
|
return this._cz
|
|
},
|
|
CurX() {
|
|
return this._GetForX()
|
|
},
|
|
CurY() {
|
|
return this._GetForY()
|
|
},
|
|
CurZ() {
|
|
return this._GetForZ()
|
|
},
|
|
CurValue() {
|
|
return this.At(this._GetForX(), this._GetForY(), this._GetForZ())
|
|
},
|
|
Front() {
|
|
return this.At(0, 0, 0)
|
|
},
|
|
Back() {
|
|
return this.At(this._cx - 1, 0, 0)
|
|
},
|
|
IndexOf(v) {
|
|
const arr = this._arr;
|
|
for (let x = 0, len = this._cx; x < len; ++x)
|
|
if (arr[x][0][0] === v)
|
|
return x;
|
|
return -1
|
|
},
|
|
LastIndexOf(v) {
|
|
const arr = this._arr;
|
|
for (let x = this._cx - 1; x >= 0; --x)
|
|
if (arr[x][0][0] === v)
|
|
return x;
|
|
return -1
|
|
},
|
|
AsJSON() {
|
|
return this.GetAsJsonString()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.AJAX = class AJAXPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.AJAX.Type = class AJAXType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.AJAX.Instance = class AJAXInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this._lastData = "";
|
|
this._curTag = "";
|
|
this._progress = 0;
|
|
this._timeout = -1;
|
|
this._nextRequestHeaders = new Map;
|
|
this._nextReponseBinaryData = null;
|
|
this._nextRequestOverrideMimeType = "";
|
|
this._nwjsFs = null;
|
|
this._nwjsPath = null;
|
|
this._nwjsAppFolder = null;
|
|
this._isNWjs = this._runtime.GetExportType() === "nwjs";
|
|
if (this._isNWjs) {
|
|
this._nwjsFs = require("fs");
|
|
this._nwjsPath = require("path");
|
|
const process = self["process"] || nw["process"];
|
|
this._nwjsAppFolder = this._nwjsPath["dirname"](process["execPath"]) + "\\"
|
|
}
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
async _TriggerError(tag, url, err) {
|
|
console.error(`[Construct 3] AJAX request to '${url}' (tag '${tag}') failed: `, err);
|
|
this._curTag = tag;
|
|
await this.TriggerAsync(C3.Plugins.AJAX.Cnds.OnAnyError);
|
|
await this.TriggerAsync(C3.Plugins.AJAX.Cnds.OnError)
|
|
}
|
|
async _TriggerComplete(tag) {
|
|
this._curTag = tag;
|
|
await this.TriggerAsync(C3.Plugins.AJAX.Cnds.OnAnyComplete);
|
|
await this.TriggerAsync(C3.Plugins.AJAX.Cnds.OnComplete)
|
|
}
|
|
async _OnProgress(tag, e) {
|
|
if (!e["lengthComputable"])
|
|
return;
|
|
this._progress = e["loaded"] / e["total"];
|
|
this._curTag = tag;
|
|
await this.TriggerAsync(C3.Plugins.AJAX.Cnds.OnProgress)
|
|
}
|
|
_OnError(tag, url, err) {
|
|
if (!this._isNWjs) {
|
|
this._TriggerError(tag, url, err);
|
|
return
|
|
}
|
|
const fs = this._nwjsFs;
|
|
const filePath = this._nwjsAppFolder + url;
|
|
if (fs["existsSync"](filePath))
|
|
fs["readFile"](filePath, {
|
|
"encoding": "utf8"
|
|
}, (err2,data)=>{
|
|
if (err2)
|
|
this._TriggerError(tag, url, err2);
|
|
else {
|
|
this._lastData = data.replace(/\r\n/g, "\n");
|
|
this._TriggerComplete(tag)
|
|
}
|
|
}
|
|
);
|
|
else
|
|
this._TriggerError(tag, url, err)
|
|
}
|
|
async _DoCordovaRequest(tag, file) {
|
|
const assetManager = this._runtime.GetAssetManager();
|
|
const binaryData = this._nextReponseBinaryData;
|
|
this._nextReponseBinaryData = null;
|
|
try {
|
|
if (binaryData) {
|
|
const buffer = await assetManager.CordovaFetchLocalFileAsArrayBuffer(file);
|
|
binaryData.SetArrayBufferTransfer(buffer);
|
|
this._lastData = "";
|
|
this._TriggerComplete(tag)
|
|
} else {
|
|
const data = await assetManager.CordovaFetchLocalFileAsText(file);
|
|
this._lastData = data.replace(/\r\n/g, "\n");
|
|
this._TriggerComplete(tag)
|
|
}
|
|
} catch (err) {
|
|
this._TriggerError(tag, file, err)
|
|
}
|
|
}
|
|
_DoRequest(tag, url, method, data) {
|
|
return new Promise(resolve=>{
|
|
const errorFunc = err=>{
|
|
this._OnError(tag, url, err);
|
|
resolve()
|
|
}
|
|
;
|
|
const binaryData = this._nextReponseBinaryData;
|
|
this._nextReponseBinaryData = null;
|
|
try {
|
|
const request = new XMLHttpRequest;
|
|
request.onreadystatechange = ()=>{
|
|
if (request.readyState === 4) {
|
|
if (binaryData)
|
|
this._lastData = "";
|
|
else
|
|
this._lastData = (request.responseText || "").replace(/\r\n/g, "\n");
|
|
if (request.status >= 400)
|
|
this._TriggerError(tag, url, request.status + request.statusText);
|
|
else {
|
|
const hasData = this._lastData.length || binaryData && request.response instanceof ArrayBuffer;
|
|
if ((!this._isNWjs || hasData) && !(!this._isNWjs && request.status === 0 && !hasData)) {
|
|
if (binaryData)
|
|
binaryData.SetArrayBufferTransfer(request.response);
|
|
this._TriggerComplete(tag)
|
|
}
|
|
}
|
|
resolve()
|
|
}
|
|
}
|
|
;
|
|
request.onerror = errorFunc;
|
|
request.ontimeout = errorFunc;
|
|
request.onabort = errorFunc;
|
|
request["onprogress"] = e=>this._OnProgress(tag, e);
|
|
request.open(method, url);
|
|
if (this._timeout >= 0 && typeof request["timeout"] !== "undefined")
|
|
request["timeout"] = this._timeout;
|
|
request.responseType = binaryData ? "arraybuffer" : "text";
|
|
if (data && !this._nextRequestHeaders.has("Content-Type"))
|
|
if (typeof data !== "string")
|
|
request["setRequestHeader"]("Content-Type", "application/octet-stream");
|
|
else
|
|
request["setRequestHeader"]("Content-Type", "application/x-www-form-urlencoded");
|
|
for (const [header,value] of this._nextRequestHeaders)
|
|
try {
|
|
request["setRequestHeader"](header, value)
|
|
} catch (err) {
|
|
console.error(`[Construct 3] AJAX: Failed to set header '${header}: ${value}': `, err)
|
|
}
|
|
this._nextRequestHeaders.clear();
|
|
if (this._nextRequestOverrideMimeType) {
|
|
try {
|
|
request["overrideMimeType"](this._nextRequestOverrideMimeType)
|
|
} catch (err) {
|
|
console.error(`[Construct 3] AJAX: failed to override MIME type: `, err)
|
|
}
|
|
this._nextRequestOverrideMimeType = ""
|
|
}
|
|
if (data)
|
|
request.send(data);
|
|
else
|
|
request.send()
|
|
} catch (err) {
|
|
errorFunc(err)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "plugins.ajax.debugger";
|
|
return [{
|
|
title: prefix + ".title",
|
|
properties: [{
|
|
name: prefix + ".last-data",
|
|
value: this._lastData
|
|
}]
|
|
}]
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"lastData": this._lastData
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this._lastData = o["lastData"];
|
|
this._curTag = "";
|
|
this._progress = 0
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.AJAX.Cnds = {
|
|
OnComplete(tag) {
|
|
return C3.equalsNoCase(this._curTag, tag)
|
|
},
|
|
OnAnyComplete() {
|
|
return true
|
|
},
|
|
OnError(tag) {
|
|
return C3.equalsNoCase(this._curTag, tag)
|
|
},
|
|
OnAnyError() {
|
|
return true
|
|
},
|
|
OnProgress(tag) {
|
|
return C3.equalsNoCase(this._curTag, tag)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.AJAX.Acts = {
|
|
async Request(tag, url) {
|
|
if (this._runtime.IsCordova() && C3.IsRelativeURL(url) && location.protocol === "file:")
|
|
await this._DoCordovaRequest(tag, url);
|
|
else if (this._runtime.IsPreview() && C3.IsRelativeURL(url)) {
|
|
const localurl = this._runtime.GetAssetManager().GetLocalUrlAsBlobUrl(url.toLowerCase());
|
|
await this._DoRequest(tag, localurl, "GET", null)
|
|
} else
|
|
await this._DoRequest(tag, url, "GET", null)
|
|
},
|
|
async RequestFile(tag, file) {
|
|
if (this._runtime.IsCordova() && location.protocol === "file:")
|
|
await this._DoCordovaRequest(tag, file);
|
|
else
|
|
await this._DoRequest(tag, this._runtime.GetAssetManager().GetLocalUrlAsBlobUrl(file), "GET", null)
|
|
},
|
|
async Post(tag, url, data, method) {
|
|
await this._DoRequest(tag, url, method, data)
|
|
},
|
|
async PostBinary(tag, url, objectClass, method) {
|
|
if (!objectClass)
|
|
return;
|
|
const target = objectClass.GetFirstPicked(this._inst);
|
|
if (!target)
|
|
return;
|
|
const sdkInst = target.GetSdkInstance();
|
|
const buffer = sdkInst.GetArrayBufferReadOnly();
|
|
await this._DoRequest(tag, url, method, buffer)
|
|
},
|
|
SetTimeout(t) {
|
|
this._timeout = t * 1E3
|
|
},
|
|
SetHeader(n, v) {
|
|
this._nextRequestHeaders.set(n, v)
|
|
},
|
|
SetResponseBinary(objectClass) {
|
|
if (!objectClass)
|
|
return;
|
|
const inst = objectClass.GetFirstPicked(this._inst);
|
|
if (!inst)
|
|
return;
|
|
this._nextReponseBinaryData = inst.GetSdkInstance()
|
|
},
|
|
OverrideMIMEType(m) {
|
|
this._nextRequestOverrideMimeType = m
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.AJAX.Exps = {
|
|
LastData() {
|
|
return this._lastData
|
|
},
|
|
Progress() {
|
|
return this._progress
|
|
},
|
|
Tag() {
|
|
return this._curTag
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Json = class JSONPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Json.Type = class JSONType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const IInstance = self.IInstance;
|
|
C3.Plugins.Json.Instance = class JSONInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this._valueCache = [null, null];
|
|
this._locationCache = [null, null];
|
|
this._data = {};
|
|
this._path = [];
|
|
this._currentKey = "";
|
|
this._currentValue = 0
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
_InvalidateValueCache() {
|
|
this._valueCache[0] = null;
|
|
this._valueCache[1] = null
|
|
}
|
|
_HasValueCache(arr) {
|
|
if (arr === null || this._valueCache[0] === null)
|
|
return false;
|
|
return this._valueCache[0] === arr || C3.arraysEqual(this._valueCache[0], arr)
|
|
}
|
|
_GetValueCache() {
|
|
return this._valueCache[1]
|
|
}
|
|
_UpdateValueCache(str, value) {
|
|
this._valueCache[0] = str;
|
|
this._valueCache[1] = value
|
|
}
|
|
_InvalidateLocationCache() {
|
|
this._locationCache[0] = null;
|
|
this._locationCache[1] = null
|
|
}
|
|
_HasLocationCache(str) {
|
|
return this._locationCache[0] === str
|
|
}
|
|
_GetLocationCache() {
|
|
return this._locationCache[1]
|
|
}
|
|
_UpdateLocationCache(str, value) {
|
|
this._locationCache[0] = str;
|
|
this._locationCache[1] = value
|
|
}
|
|
_SetData(obj) {
|
|
this._data = obj;
|
|
this._InvalidateValueCache()
|
|
}
|
|
_GetData() {
|
|
return this._data
|
|
}
|
|
_SetPath(str) {
|
|
this._path = this._ParsePathUnsafe(str);
|
|
this._InvalidateLocationCache()
|
|
}
|
|
_ParsePath(str) {
|
|
return C3.cloneArray(this._ParsePathUnsafe(str))
|
|
}
|
|
_ParsePathUnsafe(str) {
|
|
const buffer = [];
|
|
let escaped = false;
|
|
let parts;
|
|
if (this._HasLocationCache(str))
|
|
return this._GetLocationCache();
|
|
if (str[0] === ".") {
|
|
parts = C3.cloneArray(this._path);
|
|
str = str.slice(1)
|
|
} else
|
|
parts = [];
|
|
for (const c of str)
|
|
if (escaped) {
|
|
buffer.push(c);
|
|
escaped = false
|
|
} else if (c === "\\")
|
|
escaped = true;
|
|
else if (c === ".") {
|
|
parts.push(buffer.join(""));
|
|
C3.clearArray(buffer)
|
|
} else
|
|
buffer.push(c);
|
|
if (buffer.length !== 0)
|
|
parts.push(buffer.join(""));
|
|
this._UpdateLocationCache(str, parts);
|
|
return parts
|
|
}
|
|
_GetValueAtFullPath(path, lazyCreate) {
|
|
if (this._HasValueCache(path))
|
|
return this._GetValueCache();
|
|
let result = this._data;
|
|
for (const part of path)
|
|
if (Array.isArray(result)) {
|
|
const index = parseInt(part, 10);
|
|
if (index < 0 || index >= result.length || !isFinite(index)) {
|
|
result = null;
|
|
break
|
|
}
|
|
result = result[index]
|
|
} else if (typeof result === "object" && result !== null)
|
|
if (result.hasOwnProperty(part))
|
|
result = result[part];
|
|
else if (lazyCreate) {
|
|
const o = {};
|
|
result[part] = o;
|
|
result = o
|
|
} else {
|
|
result = null;
|
|
break
|
|
}
|
|
else {
|
|
result = null;
|
|
break
|
|
}
|
|
this._UpdateValueCache(path, result);
|
|
return result
|
|
}
|
|
_GetValue(str) {
|
|
const path = this._ParsePath(str);
|
|
if (!path.length)
|
|
return this._data;
|
|
const key = path.pop();
|
|
const obj = this._GetValueAtFullPath(path, false);
|
|
if (Array.isArray(obj)) {
|
|
const index = parseInt(key, 10);
|
|
return index >= 0 && index < obj.length ? obj[index] : null
|
|
} else if (typeof obj === "object" && obj !== null)
|
|
return obj.hasOwnProperty(key) ? obj[key] : null;
|
|
else
|
|
return null
|
|
}
|
|
_JSONTypeOf(val) {
|
|
if (val === null)
|
|
return "null";
|
|
else if (Array.isArray(val))
|
|
return "array";
|
|
else
|
|
return typeof val
|
|
}
|
|
_GetTypeOf(str) {
|
|
const val = this._GetValue(str);
|
|
return this._JSONTypeOf(val)
|
|
}
|
|
_ToSafeValue(value) {
|
|
const type = typeof value;
|
|
if (type === "number" || type === "string")
|
|
return value;
|
|
else if (type === "boolean")
|
|
return value ? 1 : 0;
|
|
else
|
|
return 0
|
|
}
|
|
_GetSafeValue(str) {
|
|
return this._ToSafeValue(this._GetValue(str))
|
|
}
|
|
_HasKey(str) {
|
|
const path = this._ParsePath(str);
|
|
if (!path.length)
|
|
return false;
|
|
const key = path.pop();
|
|
const obj = this._GetValueAtFullPath(path, false);
|
|
if (Array.isArray(obj)) {
|
|
const index = parseInt(key, 10);
|
|
return index >= 0 && index < obj.length
|
|
} else if (typeof obj === "object" && obj !== null)
|
|
return obj.hasOwnProperty(key);
|
|
else
|
|
return false
|
|
}
|
|
_SetValue(str, value) {
|
|
const path = this._ParsePath(str);
|
|
if (!path.length)
|
|
return false;
|
|
if (this._HasValueCache(path))
|
|
this._InvalidateValueCache();
|
|
const key = path.pop();
|
|
const obj = this._GetValueAtFullPath(path, true);
|
|
if (Array.isArray(obj)) {
|
|
const index = parseInt(key, 10);
|
|
if (!isFinite(index) || index < 0 || index >= obj.length)
|
|
return false;
|
|
obj[index] = value;
|
|
return true
|
|
} else if (typeof obj === "object" && obj !== null) {
|
|
obj[key] = value;
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
_DeleteKey(str) {
|
|
const path = this._ParsePath(str);
|
|
if (!path.length)
|
|
return false;
|
|
if (this._HasValueCache(path))
|
|
this._InvalidateValueCache();
|
|
const key = path.pop();
|
|
const obj = this._GetValueAtFullPath(path, false);
|
|
if (Array.isArray(obj))
|
|
return false;
|
|
else if (typeof obj === "object" && obj !== null) {
|
|
delete obj[key];
|
|
return true
|
|
} else
|
|
return false
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"path": this._path,
|
|
"data": this._data
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this._InvalidateValueCache();
|
|
this._InvalidateLocationCache();
|
|
this._path = o["path"];
|
|
this._data = o["data"]
|
|
}
|
|
_SanitizeValue(val) {
|
|
const type = typeof val;
|
|
if (type === "number") {
|
|
if (!isFinite(val))
|
|
return 0;
|
|
return val
|
|
}
|
|
if (typeof val == "object")
|
|
return JSON.stringify(val);
|
|
return val + ""
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "plugins.json.debugger";
|
|
let topLevelData;
|
|
try {
|
|
topLevelData = this._SanitizeValue(this._data)
|
|
} catch (e) {
|
|
topLevelData = '"invalid"'
|
|
}
|
|
return [{
|
|
title: prefix + ".title",
|
|
properties: [{
|
|
name: prefix + ".data",
|
|
value: topLevelData,
|
|
onedit: v=>{
|
|
try {
|
|
const n = JSON.parse(v);
|
|
this._SetData(n)
|
|
} catch (e) {}
|
|
}
|
|
}, {
|
|
name: prefix + ".path",
|
|
value: this._path.map(seg=>seg.replace(/\./g, "\\.")).join(".")
|
|
}]
|
|
}]
|
|
}
|
|
GetScriptInterfaceClass() {
|
|
return self.IJSONInstance
|
|
}
|
|
}
|
|
;
|
|
const map = new WeakMap;
|
|
self.IJSONInstance = class IJSONInstance extends IInstance {
|
|
constructor() {
|
|
super();
|
|
map.set(this, IInstance._GetInitInst().GetSdkInstance())
|
|
}
|
|
getJsonDataCopy() {
|
|
const data = map.get(this)._GetData();
|
|
return JSON.parse(JSON.stringify(data))
|
|
}
|
|
setJsonDataCopy(o) {
|
|
try {
|
|
const o2 = JSON.parse(JSON.stringify(o));
|
|
map.get(this)._SetData(o2)
|
|
} catch (err) {
|
|
console.error("[JSON plugin] setJsonData: object is not valid JSON: ", err);
|
|
throw err;
|
|
}
|
|
}
|
|
setJsonString(str) {
|
|
try {
|
|
const o = JSON.parse(str);
|
|
map.get(this)._SetData(o)
|
|
} catch (err) {
|
|
console.error("[JSON plugin] setJsonString: string is not valid JSON: ", err);
|
|
throw err;
|
|
}
|
|
}
|
|
toCompactString() {
|
|
return JSON.stringify(map.get(this)._GetData())
|
|
}
|
|
toBeautifiedString() {
|
|
return JSON.stringify(map.get(this)._GetData(), null, 4)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const JSON_TYPES = ["null", "boolean", "number", "string", "object", "array"];
|
|
C3.Plugins.Json.Cnds = {
|
|
HasKey(str) {
|
|
return this._HasKey(str)
|
|
},
|
|
CompareType(str, typeIndex) {
|
|
return this._GetTypeOf(str) === JSON_TYPES[typeIndex]
|
|
},
|
|
CompareValue(str, cmp, value) {
|
|
return C3.compare(this._GetSafeValue(str), cmp, value)
|
|
},
|
|
IsBooleanSet(str) {
|
|
return this._GetValue(str) === true
|
|
},
|
|
ForEach(str) {
|
|
const value = this._GetValue(str);
|
|
if (typeof value !== "object" || value === null)
|
|
return false;
|
|
const runtime = this._runtime;
|
|
const eventSheetManager = runtime.GetEventSheetManager();
|
|
const currentEvent = runtime.GetCurrentEvent();
|
|
const solModifiers = currentEvent.GetSolModifiers();
|
|
const eventStack = runtime.GetEventStack();
|
|
const oldFrame = eventStack.GetCurrentStackFrame();
|
|
const newFrame = eventStack.Push(currentEvent);
|
|
const oldPath = this._path;
|
|
const oldKey = this._currentKey;
|
|
const oldValue = this._currentValue;
|
|
const subPath = this._ParsePathUnsafe(str);
|
|
runtime.SetDebuggingEnabled(false);
|
|
for (const [k,v] of Object.entries(value)) {
|
|
this._path = C3.cloneArray(subPath);
|
|
this._path.push(k);
|
|
this._currentKey = k;
|
|
this._currentValue = v;
|
|
eventSheetManager.PushCopySol(solModifiers);
|
|
currentEvent.Retrigger(oldFrame, newFrame);
|
|
eventSheetManager.PopSol(solModifiers)
|
|
}
|
|
runtime.SetDebuggingEnabled(true);
|
|
this._path = oldPath;
|
|
this._currentKey = oldKey;
|
|
this._currentValue = oldValue;
|
|
eventStack.Pop();
|
|
return false
|
|
},
|
|
OnParseError() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Json.Acts = {
|
|
Parse(str) {
|
|
try {
|
|
this._SetData(JSON.parse(str))
|
|
} catch (err) {
|
|
console.warn("[JSON plugin] Failed to parse JSON data: ", err);
|
|
this._SetData({});
|
|
this.Trigger(C3.Plugins.Json.Cnds.OnParseError)
|
|
}
|
|
},
|
|
SetPath(str) {
|
|
this._SetPath(str)
|
|
},
|
|
SetValue(str, value) {
|
|
this._SetValue(str, value)
|
|
},
|
|
SetArray(str, size) {
|
|
let value = this._GetValue(str);
|
|
if (Array.isArray(value))
|
|
C3.resizeArray(value, size, 0);
|
|
else {
|
|
value = [];
|
|
C3.extendArray(value, size, 0);
|
|
this._SetValue(str, value)
|
|
}
|
|
},
|
|
SetObject(str) {
|
|
this._SetValue(str, {})
|
|
},
|
|
SetJSON(location, value) {
|
|
let obj = null;
|
|
try {
|
|
obj = JSON.parse(value)
|
|
} catch (err) {
|
|
console.warn("[JSON plugin] Failed to parse JSON data: ", err);
|
|
this.Trigger(C3.Plugins.Json.Cnds.OnParseError)
|
|
}
|
|
this._SetValue(location, obj)
|
|
},
|
|
SetNull(str) {
|
|
this._SetValue(str, null)
|
|
},
|
|
SetBoolean(str, value) {
|
|
this._SetValue(str, value !== 0)
|
|
},
|
|
ToggleBoolean(str) {
|
|
const value = this._GetValue(str);
|
|
if (typeof value === "boolean")
|
|
this._SetValue(str, !value)
|
|
},
|
|
AddTo(str, inc) {
|
|
const value = this._GetValue(str);
|
|
if (typeof value === "number")
|
|
this._SetValue(str, value + inc)
|
|
},
|
|
SubtractFrom(str, dec) {
|
|
const value = this._GetValue(str);
|
|
if (typeof value === "number")
|
|
this._SetValue(str, value - dec)
|
|
},
|
|
DeleteKey(str) {
|
|
this._DeleteKey(str)
|
|
},
|
|
PushValue(side, str, value) {
|
|
const parent = this._GetValue(str);
|
|
if (Array.isArray(parent))
|
|
side === 0 ? parent.push(value) : parent.unshift(value)
|
|
},
|
|
PopValue(side, str) {
|
|
const parent = this._GetValue(str);
|
|
if (Array.isArray(parent))
|
|
side === 0 ? parent.pop() : parent.shift()
|
|
},
|
|
InsertValue(value, str, index) {
|
|
const parent = this._GetValue(str);
|
|
if (Array.isArray(parent))
|
|
parent.splice(index, 0, value)
|
|
},
|
|
RemoveValues(count, str, index) {
|
|
const parent = this._GetValue(str);
|
|
if (Array.isArray(parent))
|
|
parent.splice(index, count)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Json.Exps = {
|
|
ToCompactString() {
|
|
try {
|
|
return JSON.stringify(this._data)
|
|
} catch (err) {
|
|
return ""
|
|
}
|
|
},
|
|
ToBeautifiedString() {
|
|
try {
|
|
return JSON.stringify(this._data, null, 4)
|
|
} catch (err) {
|
|
return ""
|
|
}
|
|
},
|
|
Get(str) {
|
|
return this._GetSafeValue(str)
|
|
},
|
|
GetAsCompactString(str) {
|
|
const value = this._GetValue(str);
|
|
return JSON.stringify(value)
|
|
},
|
|
GetAsBeautifiedString(str) {
|
|
const value = this._GetValue(str);
|
|
return JSON.stringify(value, null, 4)
|
|
},
|
|
Front(str) {
|
|
const parent = this._GetValue(str);
|
|
if (Array.isArray(parent)) {
|
|
const value = parent[0];
|
|
return this._ToSafeValue(value)
|
|
} else
|
|
return -1
|
|
},
|
|
Back(str) {
|
|
const parent = this._GetValue(str);
|
|
if (Array.isArray(parent)) {
|
|
const value = parent[parent.length - 1];
|
|
return this._ToSafeValue(value)
|
|
} else
|
|
return -1
|
|
},
|
|
Type(str) {
|
|
return this._GetTypeOf(str)
|
|
},
|
|
ArraySize(str) {
|
|
const value = this._GetValue(str);
|
|
if (Array.isArray(value))
|
|
return value.length;
|
|
else
|
|
return -1
|
|
},
|
|
Path() {
|
|
return this._path.map(seg=>seg.replace(/\./g, "\\.")).join(".")
|
|
},
|
|
CurrentKey() {
|
|
return this._currentKey
|
|
},
|
|
CurrentValue() {
|
|
return this._ToSafeValue(this._currentValue)
|
|
},
|
|
CurrentType() {
|
|
return this._JSONTypeOf(this._currentValue)
|
|
}
|
|
}
|
|
}
|
|
;"use strict";
|
|
{
|
|
C3.Plugins.aekiro_proui = class aekiro_prouiSingleGlobalPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.aekiro_proui.Type = class aekiro_prouiSingleGlobalType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
var C3 = self.C3;
|
|
C3.Plugins.aekiro_proui.Instance = class aekiro_prouiSingleGlobalInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this.ignoreInput = false;
|
|
this.goManager = globalThis.aekiro_goManager;
|
|
this.goManager.init(this.GetRuntime());
|
|
this.lastLayout = null;
|
|
this.GetRuntime().Dispatcher().addEventListener("beforelayoutchange", ()=>{
|
|
this.goManager.isInit = false;
|
|
}
|
|
);
|
|
}
|
|
Initialise() {
|
|
this.goManager.gos = {};
|
|
this.goManager.registerGameObjects();
|
|
this.goManager.cleanSceneGraph();
|
|
this.goManager.createSceneGraph();
|
|
this.goManager.isInit = true;
|
|
}
|
|
setUIAudioVolume(volume) {
|
|
var list = [C3.Behaviors.aekiro_button, C3.Behaviors.aekiro_checkbox, C3.Behaviors.aekiro_radiobutton, C3.Behaviors.aekiro_dialog];
|
|
var behaviorBase, insts, audioSources;
|
|
for (var i = 0, l = list.length; i < l; i++) {
|
|
behaviorBase = this.GetRuntime()._pluginManager._behaviorsByCtor.get(list[i]);
|
|
if (!behaviorBase)
|
|
continue;
|
|
insts = behaviorBase.GetInstances();
|
|
for (var j = 0, m = insts.length; j < m; j++) {
|
|
audioSources = insts[j].GetUnsavedDataMap().audioSources;
|
|
if (!audioSources)
|
|
continue;
|
|
for (var key in audioSources) {
|
|
audioSources[key].setVolume(volume);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
isTypeValid(inst, types) {
|
|
var ctr = inst.GetPlugin().constructor;
|
|
for (var i = 0, l = types.length; i < l; i++) {
|
|
if (ctr == types[i]) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {};
|
|
}
|
|
LoadFromJson(o) {}
|
|
}
|
|
;
|
|
}
|
|
var Tween = globalThis["TWEEN"];
|
|
globalThis.Aekiro = {};
|
|
globalThis.AudioSource = class AudioSource {
|
|
constructor(opts, runtime) {
|
|
this.runtime = runtime;
|
|
this.parseConfig(opts);
|
|
if (C3.Plugins.Audio) {
|
|
this.act_PlayByName = C3.Plugins.Audio.Acts.PlayByName;
|
|
}
|
|
}
|
|
parseConfig(opts) {
|
|
opts = opts.split(";");
|
|
this.fileName = opts[0];
|
|
this.volume = parseInt(opts[1]);
|
|
if (!this.volume)
|
|
this.volume = 0;
|
|
}
|
|
getAudioSdkInstance() {
|
|
if (!this.audio) {
|
|
var plugin = this.runtime.GetSingleGlobalObjectClassByCtor(C3.Plugins.Audio);
|
|
if (plugin) {
|
|
this.audio = plugin.GetSingleGlobalInstance().GetSdkInstance();
|
|
}
|
|
}
|
|
return this.audio;
|
|
}
|
|
setVolume(v) {
|
|
this.volume = v;
|
|
}
|
|
play() {
|
|
if (!this.fileName)
|
|
return;
|
|
var audio = this.getAudioSdkInstance();
|
|
if (!audio) {
|
|
console.error("ProUI: Please add the Audio plugin to the project.");
|
|
return;
|
|
}
|
|
this.act_PlayByName.call(audio, 0, this.fileName, 0, this.volume, "sound");
|
|
}
|
|
}
|
|
;
|
|
globalThis.EventManager = class EventManager {
|
|
constructor(inst) {
|
|
this.map = {};
|
|
this.inst = inst;
|
|
}
|
|
on(eventName, callback, options) {
|
|
if (!this.map[eventName]) {
|
|
this.map[eventName] = [];
|
|
}
|
|
var once = false;
|
|
if (options) {
|
|
once = options["once"];
|
|
}
|
|
var listener = {
|
|
"callback": callback,
|
|
"once": once,
|
|
"eventName": eventName
|
|
};
|
|
this.map[eventName].push(listener);
|
|
return listener;
|
|
}
|
|
emit(eventName, options) {
|
|
options = options || {};
|
|
var listeners = this.map[eventName];
|
|
var listener;
|
|
if (listeners) {
|
|
for (var i = 0, l = listeners.length; i < l; i++) {
|
|
listener = listeners[i];
|
|
listener["callback"](options["args"]);
|
|
if (listener["once"]) {
|
|
this.removeListener(listener);
|
|
l = listeners.length;
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
if (options["propagate"] == undefined)
|
|
options["propagate"] = true;
|
|
if (options["bubble"] == undefined)
|
|
options["bubble"] = true;
|
|
var options2 = Object.assign({}, options);
|
|
options2["propagate"] = false;
|
|
if (options["bubble"] === true && this.inst) {
|
|
var go = this.inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (go.parent) {
|
|
go.parent.GetUnsavedDataMap().aekiro_gameobject.eventManager.emit(eventName, options2);
|
|
}
|
|
}
|
|
options2 = Object.assign({}, options);
|
|
options2["bubble"] = false;
|
|
if (options["propagate"] === true && this.inst) {
|
|
var go = this.inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
var children = go.children;
|
|
for (var i = 0, l = children.length; i < l; i++) {
|
|
children[i].GetUnsavedDataMap().aekiro_gameobject.eventManager.emit(eventName, options);
|
|
}
|
|
}
|
|
}
|
|
removeListener(listener) {
|
|
var listeners = this.map[listener["eventName"]];
|
|
var index = listeners.indexOf(listener);
|
|
listeners.splice(index, 1);
|
|
}
|
|
}
|
|
;
|
|
globalThis.aekiro_goManager = {
|
|
gos: {},
|
|
haltNext: false,
|
|
isRegistering: false,
|
|
eventManager: new globalThis.EventManager(),
|
|
lastLayout: 0,
|
|
init: function(runtime) {
|
|
if (this.runtime)
|
|
return;
|
|
this.runtime = runtime;
|
|
this.runtime.Dispatcher().addEventListener("instancedestroy", function(e) {
|
|
var go = e.instance.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (go) {
|
|
go.Release2();
|
|
}
|
|
});
|
|
},
|
|
clean: function() {
|
|
var key;
|
|
for (key in this.gos) {
|
|
if (this.gos[key].IsDestroyed()) {
|
|
this.removeGO(key);
|
|
}
|
|
}
|
|
},
|
|
addGO: function(inst) {
|
|
if (!inst)
|
|
return;
|
|
if (this.haltNext)
|
|
return;
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (!aekiro_gameobject.name) {
|
|
aekiro_gameobject.name = "o" + inst.GetUID();
|
|
}
|
|
var name = aekiro_gameobject.name;
|
|
if (this.gos.hasOwnProperty(name)) {
|
|
console.error("Aekiro Hierarchy: GameObject already exist with name: %s !", name);
|
|
aekiro_gameobject.name = "o" + inst.GetUID();
|
|
name = aekiro_gameobject.name;
|
|
}
|
|
this.gos[name] = inst;
|
|
},
|
|
removeGO: function(name) {
|
|
delete this.gos[name];
|
|
},
|
|
setGoName: function(oldName, newName) {
|
|
if (!this.gos[oldName]) {
|
|
throw new Error("ProUI-goManager.setGoName() : game object to be renamed not found");
|
|
}
|
|
if (this.gos.hasOwnProperty(newName)) {
|
|
throw new Error("ProUI-goManager.setGoName() : game object already exist with name: " + name);
|
|
}
|
|
this.gos[newName] = this.gos[oldName];
|
|
this.removeGO(oldName);
|
|
},
|
|
getName: function(inst) {
|
|
var key;
|
|
for (key in this.gos) {
|
|
if (this.gos[key] == inst) {
|
|
return key;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
removeGO2: function(inst) {
|
|
var key;
|
|
for (key in this.gos) {
|
|
if (this.gos[key] == inst) {
|
|
this.removeGO(key);
|
|
}
|
|
}
|
|
},
|
|
createInstance: function(objectClass, layer, x, y) {
|
|
var inst = this.runtime.CreateInstance(this.runtime.GetObjectClassByName(objectClass), layer, x, y);
|
|
const b = this.runtime.GetEventSheetManager();
|
|
b.BlockFlushingInstances(!0);
|
|
b.BlockFlushingInstances(!1);
|
|
return inst;
|
|
},
|
|
clone: function(template, name, parent, layer, x, y, onNodeCreated) {
|
|
if (this.gos[name]) {
|
|
console.error("Aekiro GameObject: GameObject already exist with name: %s !", name);
|
|
return;
|
|
}
|
|
if (typeof parent === 'string') {
|
|
parent = this.gos[parent];
|
|
}
|
|
if (parent) {
|
|
var wp = parent.GetWorldInfo();
|
|
var res = this.globalToLocal3(x, y, 0, wp.GetX(), wp.GetY(), wp.GetAngle());
|
|
x = res.x;
|
|
y = res.y;
|
|
}
|
|
var inst = this._clone(template, name, parent, layer, x, y, onNodeCreated);
|
|
inst.GetUnsavedDataMap().aekiro_gameobject.children_update();
|
|
inst.GetUnsavedDataMap().aekiro_gameobject.updateZindex();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
aekiro_gameobject.eventManager.emit("cloned");
|
|
return inst;
|
|
},
|
|
_clone: function(t_node, name, parent, layer, x, y, onNodeCreated) {
|
|
this.haltNext = true;
|
|
var inst = this.createInstance(t_node.type, layer);
|
|
this.haltNext = false;
|
|
var b;
|
|
try {
|
|
b = JSON.parse(t_node.json);
|
|
} catch (a) {
|
|
return void console.error("Failed to load from JSON string: ", a);
|
|
}
|
|
inst.LoadFromJson(b, !0);
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
inst.GetUnsavedDataMap().zindex = t_node.zindex;
|
|
inst.GetSdkInstance().CallAction(aekiro_gameobject.acts.MoveToLayer, layer);
|
|
aekiro_gameobject.name = "";
|
|
aekiro_gameobject.parentName = "";
|
|
if (name)
|
|
aekiro_gameobject.name = name;
|
|
this.addGO(inst);
|
|
if (parent) {
|
|
parent.GetUnsavedDataMap().aekiro_gameobject.children_add(inst);
|
|
}
|
|
var wi = inst.GetWorldInfo();
|
|
wi.SetX(x, true);
|
|
wi.SetY(y, true);
|
|
wi.SetBboxChanged();
|
|
if (onNodeCreated)
|
|
onNodeCreated(inst);
|
|
inst._TriggerOnCreated();
|
|
var child;
|
|
for (var i = 0, l = t_node.children.length; i < l; i++) {
|
|
child = t_node.children[i];
|
|
this._clone(child, null, inst, layer, child.x, child.y, onNodeCreated);
|
|
}
|
|
return inst;
|
|
},
|
|
globalToLocal3: function(x, y, a, p_x, p_y, p_angle) {
|
|
var res = {};
|
|
res.x = (x - p_x) * Math.cos(p_angle) + (y - p_y) * Math.sin(p_angle);
|
|
res.y = -(x - p_x) * Math.sin(p_angle) + (y - p_y) * Math.cos(p_angle);
|
|
res.angle = a - p_angle;
|
|
return res;
|
|
},
|
|
registerGameObjects: function() {
|
|
var aekiro_gameobjectBehaviorBase = this.runtime._pluginManager._behaviorsByCtor.get(C3.Behaviors.aekiro_gameobject);
|
|
if (!aekiro_gameobjectBehaviorBase)
|
|
return;
|
|
var insts = aekiro_gameobjectBehaviorBase.GetInstances();
|
|
var l = insts.length;
|
|
for (var i = 0; i < l; i++) {
|
|
if (!insts[i].IsDestroyed()) {
|
|
this.addGO(insts[i]);
|
|
}
|
|
}
|
|
},
|
|
createSceneGraph: function() {
|
|
var key, go, aekiro_gameobject;
|
|
var parentSameLayer = {};
|
|
for (key in this.gos) {
|
|
go = this.gos[key];
|
|
aekiro_gameobject = go.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (aekiro_gameobject.parentName && this.gos[aekiro_gameobject.parentName]) {
|
|
this.gos[aekiro_gameobject.parentName].GetUnsavedDataMap().aekiro_gameobject.children_add(go);
|
|
}
|
|
if (aekiro_gameobject.parentSameLayer) {
|
|
parentSameLayer[key] = go;
|
|
}
|
|
}
|
|
for (key in parentSameLayer) {
|
|
go = parentSameLayer[key];
|
|
aekiro_gameobject = go.GetUnsavedDataMap().aekiro_gameobject;
|
|
aekiro_gameobject.children_addFromLayer(aekiro_gameobject.GetWorldInfo().GetLayer());
|
|
}
|
|
for (key in this.gos) {
|
|
this.gos[key].GetUnsavedDataMap().aekiro_gameobject.children_update();
|
|
}
|
|
this.eventManager.emit("childrenRegistred");
|
|
},
|
|
cleanSceneGraph: function() {
|
|
var key, inst;
|
|
for (key in this.gos) {
|
|
inst = this.gos[key];
|
|
inst.GetUnsavedDataMap().aekiro_gameobject.removeFromParent();
|
|
}
|
|
}
|
|
};
|
|
globalThis.Aekiro.button = class aekiro_button extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
}
|
|
button_constructor() {
|
|
this.proui = this.GetRuntime().GetSingleGlobalObjectClassByCtor(C3.Plugins.aekiro_proui);
|
|
if (this.proui) {
|
|
this.proui = this.proui.GetSingleGlobalInstance().GetSdkInstance();
|
|
}
|
|
this.proui.isTypeValid(this.GetObjectInstance(), [C3.Plugins.Sprite, C3.Plugins.NinePatch, C3.Plugins.TiledBg], "Pro UI: Button behavior is only applicable to Sprite, 9-patch or tiled backgrounds objects.");
|
|
this.inst = this.GetObjectInstance();
|
|
this.wi = this.inst.GetWorldInfo();
|
|
this.goManager = globalThis.aekiro_goManager;
|
|
this.scrollViews = globalThis.aekiro_scrollViewManager.scrollViews;
|
|
this.aekiro_dialogManager = globalThis.aekiro_dialogManager;
|
|
this.GetObjectInstance().GetUnsavedDataMap().aekiro_button = this;
|
|
this.isInstanceOfSprite = this.GetObjectInstance().GetPlugin().constructor == C3.Plugins.Sprite;
|
|
this.STATES = {
|
|
NORMAL: 0,
|
|
HOVER: 1,
|
|
CLICKED: 2,
|
|
DISABLED: 3,
|
|
FOCUSED: 4
|
|
};
|
|
this.isOnMobile = C3.Platform.IsMobile;
|
|
this.isTouchStarted = false;
|
|
this.isMouseEnter = false;
|
|
this.isFocused = false;
|
|
this.callbacks = [];
|
|
this.frameAnim = [];
|
|
this.initProps = {
|
|
animationFrame: null,
|
|
animationName: null,
|
|
color: null
|
|
};
|
|
}
|
|
PostCreate() {
|
|
this.aekiro_gameobject = this.GetObjectInstance().GetUnsavedDataMap().aekiro_gameobject;
|
|
this.sdkInstance = this.GetObjectInstance().GetSdkInstance();
|
|
this.sdkInstance_callAction = this.sdkInstance.CallAction;
|
|
this.sdkInstance_callExpression = this.sdkInstance.CallExpression;
|
|
this.sdkInstance_acts = this.GetObjectInstance().GetPlugin().constructor.Acts;
|
|
this.sdkInstance_exps = this.GetObjectInstance().GetPlugin().constructor.Exps;
|
|
this.onPropsLoaded();
|
|
this.updateViewTick();
|
|
}
|
|
onPropsLoaded() {
|
|
this.useStates = true;
|
|
if (!this.isInstanceOfSprite || (this.frame_normal == "" && this.frame_hover == "" && this.frame_clicked == "" && this.frame_disabled == "")) {
|
|
this.useStates = false;
|
|
}
|
|
this.state = this.isEnabled ? this.STATES.NORMAL : this.STATES.DISABLED;
|
|
this.setInitProps();
|
|
this.initSounds();
|
|
this.initFrameAnim();
|
|
this.initAnimations();
|
|
this.initColors();
|
|
}
|
|
onInitPropsLoaded() {
|
|
var t = this.initProps.color;
|
|
this.initProps.color = new C3.Color();
|
|
this.initProps.color.setFromJSON(t);
|
|
}
|
|
updateView() {
|
|
this.setFrameAnim(this.state);
|
|
this.setColor(this.state);
|
|
}
|
|
updateViewTick() {
|
|
this.updateV = true;
|
|
this._StartTicking();
|
|
}
|
|
setEnabled(isEnabled) {
|
|
if (this.isEnabled == isEnabled)
|
|
return;
|
|
this.isEnabled = isEnabled;
|
|
this.state = isEnabled ? this.STATES.NORMAL : this.STATES.DISABLED;
|
|
this.setFrameAnim(this.state);
|
|
this.setColor(this.state);
|
|
}
|
|
parseFrameAnim(frameAnim, defaults) {
|
|
if (frameAnim == undefined)
|
|
frameAnim = "";
|
|
frameAnim = frameAnim.split('/');
|
|
var frame, anim;
|
|
if (isNaN(parseInt(frameAnim[0]))) {
|
|
anim = frameAnim[0];
|
|
frame = parseInt(frameAnim[1])
|
|
} else {
|
|
anim = frameAnim[1];
|
|
frame = parseInt(frameAnim[0]);
|
|
}
|
|
if (isNaN(frame)) {
|
|
frame = defaults ? defaults["f"] : this.initProps.animationFrame;
|
|
}
|
|
if (!isNaN(anim) || !anim) {
|
|
anim = defaults ? defaults["a"] : this.initProps.animationName;
|
|
}
|
|
var res = {
|
|
"f": frame,
|
|
"a": anim
|
|
};
|
|
return res;
|
|
}
|
|
parseColor(color, defaultColor) {
|
|
if (color) {
|
|
color = color.split(",");
|
|
color = new C3.Color(color[0] / 255,color[1] / 255,color[2] / 255,1);
|
|
} else {
|
|
if (defaultColor !== undefined) {
|
|
color = defaultColor;
|
|
} else {
|
|
color = this.initProps.color;
|
|
}
|
|
}
|
|
return color;
|
|
}
|
|
initSounds() {
|
|
var map = this.GetObjectInstance().GetUnsavedDataMap();
|
|
if (!map.audioSources) {
|
|
map.audioSources = {};
|
|
}
|
|
var AudioSource = globalThis.AudioSource;
|
|
this.audioSources = map.audioSources;
|
|
this.audioSources.click = new AudioSource(this.clickSound,this.GetRuntime());
|
|
this.audioSources.hover = new AudioSource(this.hoverSound,this.GetRuntime());
|
|
this.audioSources.focus = new AudioSource(this.focusSound,this.GetRuntime());
|
|
}
|
|
initColors() {
|
|
this.colors = [];
|
|
this.colors[this.STATES.NORMAL] = this.parseColor(this.color_normal);
|
|
this.colors[this.STATES.HOVER] = this.parseColor(this.color_hover, null);
|
|
this.colors[this.STATES.CLICKED] = this.parseColor(this.color_clicked, null);
|
|
this.colors[this.STATES.DISABLED] = this.parseColor(this.color_disabled);
|
|
this.colors[this.STATES.FOCUSED] = this.parseColor(this.color_focus, null);
|
|
}
|
|
setColor(state) {
|
|
var color;
|
|
if (this.isFocused) {
|
|
if (this.state == this.STATES.NORMAL) {
|
|
color = this.colors[this.STATES.FOCUSED] || this.colors[this.STATES.NORMAL];
|
|
} else {
|
|
color = this.colors[state] || this.colors[this.STATES.FOCUSED];
|
|
if (!this.colors[state] && !this.colors[this.STATES.FOCUSED]) {
|
|
color = this.colors[this.STATES.NORMAL];
|
|
}
|
|
}
|
|
} else {
|
|
color = this.colors[state];
|
|
}
|
|
if (color) {
|
|
this.wi.SetUnpremultipliedColor(color);
|
|
this.wi.SetBboxChanged();
|
|
}
|
|
}
|
|
setInitProps() {
|
|
if (this.isInstanceOfSprite) {
|
|
this.initProps.animationFrame = this.initProps.animationFrame === null ? this.sdkInstance.CallExpression(this.sdkInstance_exps.AnimationFrame) : this.initProps.animationFrame;
|
|
this.initProps.animationName = this.initProps.animationName || this.sdkInstance.CallExpression(this.sdkInstance_exps.AnimationName);
|
|
}
|
|
this.initProps.color = this.initProps.color || this.wi.GetUnpremultipliedColor();
|
|
}
|
|
initFrameAnim() {
|
|
if (!this.useStates)
|
|
return;
|
|
this.frameAnim[this.STATES.NORMAL] = this.parseFrameAnim(this.frame_normal);
|
|
this.frameAnim[this.STATES.HOVER] = this.parseFrameAnim(this.frame_hover, {
|
|
"f": null,
|
|
"a": null
|
|
});
|
|
this.frameAnim[this.STATES.CLICKED] = this.parseFrameAnim(this.frame_clicked, {
|
|
"f": null,
|
|
"a": null
|
|
});
|
|
this.frameAnim[this.STATES.DISABLED] = this.parseFrameAnim(this.frame_disabled);
|
|
this.frameAnim[this.STATES.FOCUSED] = this.parseFrameAnim(this.frame_focus, {
|
|
"f": null,
|
|
"a": null
|
|
});
|
|
}
|
|
setFrameAnim(state) {
|
|
if (!this.useStates) {
|
|
return;
|
|
}
|
|
var frame, anim;
|
|
if (this.isFocused) {
|
|
if (this.state == this.STATES.NORMAL) {
|
|
frame = (this.frameAnim[this.STATES.FOCUSED]["f"] === null) ? this.frameAnim[this.STATES.NORMAL]["f"] : this.frameAnim[this.STATES.FOCUSED]["f"];
|
|
anim = this.frameAnim[this.STATES.FOCUSED]["a"] || this.frameAnim[this.STATES.NORMAL]["a"];
|
|
} else {
|
|
if (this.frameAnim[state]["f"] == null && !this.frameAnim[state]["a"]) {
|
|
frame = this.frameAnim[this.STATES.NORMAL]["f"];
|
|
anim = this.frameAnim[this.STATES.NORMAL]["a"];
|
|
} else {
|
|
frame = (this.frameAnim[state]["f"] === null) ? this.frameAnim[this.STATES.FOCUSED]["f"] : this.frameAnim[state]["f"];
|
|
anim = this.frameAnim[state]["a"] || this.frameAnim[this.STATES.FOCUSED]["a"];
|
|
}
|
|
}
|
|
} else {
|
|
frame = this.frameAnim[state]["f"];
|
|
anim = this.frameAnim[state]["a"];
|
|
}
|
|
if (anim) {
|
|
this.sdkInstance.CallAction(this.sdkInstance_acts.SetAnim, anim, 0);
|
|
}
|
|
if (frame !== null) {
|
|
this.sdkInstance.CallAction(this.sdkInstance_acts.SetAnimFrame, frame, 0);
|
|
}
|
|
}
|
|
initAnimations() {
|
|
this.currentDelta = {
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0
|
|
};
|
|
this.targetDelta = {
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0
|
|
};
|
|
this.tween = new Tween["Tween"](this.currentDelta);
|
|
}
|
|
setAnimations(type) {
|
|
this.prev = {
|
|
x: this.currentDelta.x,
|
|
y: this.currentDelta.y,
|
|
width: this.currentDelta.width,
|
|
height: this.currentDelta.height
|
|
};
|
|
if (type == 1) {
|
|
this.tween["easing"](Tween["Easing"]["Quadratic"]["Out"])["to"](this.targetDelta, 200);
|
|
} else if (type == 2) {
|
|
this.tween["easing"](Tween["Easing"]["Elastic"]["Out"])["to"](this.targetDelta, 500);
|
|
} else if (type == 3) {
|
|
this.tween["easing"](Tween["Easing"]["Quadratic"]["Out"])["to"](this.targetDelta, 100);
|
|
} else if (type == 4) {
|
|
this.tween["easing"](Tween["Easing"]["Quadratic"]["Out"])["to"](this.targetDelta, 100);
|
|
} else if (type == 5) {
|
|
this.tween["easing"](Tween["Easing"]["Quadratic"]["Out"])["to"](this.targetDelta, 100);
|
|
} else if (type == 6) {
|
|
this.tween["easing"](Tween["Easing"]["Quadratic"]["Out"])["to"](this.targetDelta, 100);
|
|
}
|
|
}
|
|
getTargetDelta(type, state) {
|
|
var wi = this.wi;
|
|
var t = {
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0
|
|
};
|
|
var f = 0.1;
|
|
if (state == "click") {
|
|
f = this.clickAnimationFactor;
|
|
} else if (state == "hover") {
|
|
f = this.hoverAnimationFactor;
|
|
} else if (state == "focus") {
|
|
f = this.focusAnimationFactor;
|
|
}
|
|
if (type == 1 || type == 2) {
|
|
t.width = wi.GetWidth() * f;
|
|
t.height = wi.GetHeight() * f;
|
|
} else if (type == 3) {
|
|
t.y = wi.GetHeight() * f;
|
|
} else if (type == 4) {
|
|
t.y = -wi.GetHeight() * f;
|
|
} else if (type == 5) {
|
|
t.x = -wi.GetWidth() * f;
|
|
} else if (type == 6) {
|
|
t.x = wi.GetWidth() * f;
|
|
}
|
|
return t;
|
|
}
|
|
OnAnyInputDown(x, y) {
|
|
if (this.wi.ContainsPoint(x, y)) {
|
|
this.OnInputDown(x, y);
|
|
}
|
|
}
|
|
OnAnyInputMove(x, y) {
|
|
if (this.isOnMobile)
|
|
return;
|
|
if (this.wi.ContainsPoint(x, y)) {
|
|
if (!this.isMouseEnter) {
|
|
this.OnMouseEnter(x, y);
|
|
}
|
|
} else {
|
|
if (this.isMouseEnter) {
|
|
this.OnMouseLeave();
|
|
}
|
|
}
|
|
}
|
|
setFocused(isFocused) {
|
|
if (!this.isEnabled)
|
|
return;
|
|
if (isFocused == this.isFocused)
|
|
return;
|
|
this.isFocused = isFocused;
|
|
if (isFocused) {
|
|
this.setFrameAnim(this.state);
|
|
this.setColor(this.state);
|
|
this.audioSources.focus.play();
|
|
if (this.focusAnimation > 0) {
|
|
this.tween["stop"]();
|
|
this.targetDelta_focus = this.getTargetDelta(this.focusAnimation, "focus");
|
|
this.targetDelta.width += this.targetDelta_focus.width;
|
|
this.targetDelta.height += this.targetDelta_focus.height;
|
|
this.targetDelta.x += this.targetDelta_focus.x;
|
|
this.targetDelta.y += this.targetDelta_focus.y;
|
|
this.setAnimations(this.focusAnimation);
|
|
;this._StartTicking();
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
}
|
|
if (this.OnFocusedC)
|
|
this.OnFocusedC();
|
|
} else {
|
|
this.setFrameAnim(this.STATES.NORMAL);
|
|
this.setColor(this.STATES.NORMAL);
|
|
this.setFrameAnim(this.state);
|
|
this.setColor(this.state);
|
|
if (this.focusAnimation > 0) {
|
|
this.tween["stop"]();
|
|
this.targetDelta.width -= this.targetDelta_focus.width;
|
|
this.targetDelta.height -= this.targetDelta_focus.height;
|
|
this.targetDelta.x -= this.targetDelta_focus.x;
|
|
this.targetDelta.y -= this.targetDelta_focus.y;
|
|
this.setAnimations(this.focusAnimation);
|
|
this._StartTicking();
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
}
|
|
if (this.OnUnFocusedC)
|
|
this.OnUnFocusedC();
|
|
}
|
|
}
|
|
OnMouseEnter(x, y) {
|
|
if (!this.isClickable(x, y))
|
|
return;
|
|
if (this.isTouchStarted)
|
|
return;
|
|
this.isMouseEnter = true;
|
|
this.state = this.STATES.HOVER;
|
|
this.setFrameAnim(this.state);
|
|
this.setColor(this.state);
|
|
this.audioSources.hover.play();
|
|
if (this.OnMouseEnterC)
|
|
this.OnMouseEnterC();
|
|
if (this.hoverAnimation > 0) {
|
|
var wi = this.wi;
|
|
this.tween["stop"]();
|
|
this.targetDelta_hover = this.getTargetDelta(this.hoverAnimation, "hover");
|
|
this.targetDelta.width += this.targetDelta_hover.width;
|
|
this.targetDelta.height += this.targetDelta_hover.height;
|
|
this.targetDelta.x += this.targetDelta_hover.x;
|
|
this.targetDelta.y += this.targetDelta_hover.y;
|
|
this.setAnimations(this.hoverAnimation);
|
|
this._StartTicking();
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
}
|
|
}
|
|
async OnInputDown(x, y) {
|
|
var res = await this.isOnMovingScrollView();
|
|
if (res)
|
|
return;
|
|
if (!this.isClickable(x, y) || this.isTouchStarted)
|
|
return;
|
|
this.isTouchStarted = true;
|
|
if (this.clickAnimation > 0) {
|
|
this.tween["stop"]();
|
|
this.targetDelta_click = this.getTargetDelta(this.clickAnimation, "click");
|
|
this.targetDelta.width += this.targetDelta_click.width;
|
|
this.targetDelta.height += this.targetDelta_click.height;
|
|
this.targetDelta.x += this.targetDelta_click.x;
|
|
this.targetDelta.y += this.targetDelta_click.y;
|
|
this.setAnimations(this.clickAnimation);
|
|
this._StartTicking();
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
}
|
|
if (!this.isFocused && this.focusAnimation > 0) {
|
|
this.tween["stop"]();
|
|
this.targetDelta_focus = this.getTargetDelta(this.focusAnimation, "focus");
|
|
this.targetDelta.width += this.targetDelta_focus.width;
|
|
this.targetDelta.height += this.targetDelta_focus.height;
|
|
this.targetDelta.x += this.targetDelta_focus.x;
|
|
this.targetDelta.y += this.targetDelta_focus.y;
|
|
this.setAnimations(this.focusAnimation);
|
|
this._StartTicking();
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
}
|
|
if (!this.isFocused) {
|
|
if (this.OnFocusedC)
|
|
this.OnFocusedC();
|
|
}
|
|
this.isFocused = true;
|
|
this.state = this.STATES.CLICKED;
|
|
this.setFrameAnim(this.state);
|
|
this.setColor(this.state);
|
|
this.audioSources.click.play();
|
|
}
|
|
OnAnyInputUp(x, y) {
|
|
if (!this.isTouchStarted)
|
|
return;
|
|
this.isTouchStarted = false;
|
|
if (this.clickAnimation > 0 && this.state != this.STATES.NORMAL) {
|
|
this.tween["stop"]();
|
|
this.targetDelta.width -= this.targetDelta_click.width;
|
|
this.targetDelta.height -= this.targetDelta_click.height;
|
|
this.targetDelta.x -= this.targetDelta_click.x;
|
|
this.targetDelta.y -= this.targetDelta_click.y;
|
|
this.setAnimations(this.clickAnimation);
|
|
this._StartTicking();
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
}
|
|
if (this.wi.ContainsPoint(x, y)) {
|
|
if (this.isOnMobile) {
|
|
this.state = this.STATES.NORMAL;
|
|
} else {
|
|
this.state = this.STATES.HOVER;
|
|
}
|
|
this.Callbacks();
|
|
} else {
|
|
this.state = this.STATES.NORMAL;
|
|
}
|
|
this.setFrameAnim(this.state);
|
|
this.setColor(this.state);
|
|
}
|
|
Callbacks() {
|
|
for (var i = 0, l = this.callbacks.length; i < l; i++) {
|
|
this.callbacks[i]();
|
|
}
|
|
if (this.OnAnyInputUpC)
|
|
this.OnAnyInputUpC();
|
|
}
|
|
OnMouseLeave() {
|
|
this.isMouseEnter = false;
|
|
if (this.state != this.STATES.DISABLED) {
|
|
this.state = this.STATES.NORMAL;
|
|
}
|
|
this.setFrameAnim(this.state);
|
|
this.setColor(this.state);
|
|
if (this.hoverAnimation > 0) {
|
|
this.targetDelta.width -= this.targetDelta_hover.width;
|
|
this.targetDelta.height -= this.targetDelta_hover.height;
|
|
this.targetDelta.x -= this.targetDelta_hover.x;
|
|
this.targetDelta.y -= this.targetDelta_hover.y;
|
|
}
|
|
if (this.clickAnimation > 0 && this.isTouchStarted) {
|
|
this.targetDelta.width -= this.targetDelta_click.width;
|
|
this.targetDelta.height -= this.targetDelta_click.height;
|
|
this.targetDelta.x -= this.targetDelta_click.x;
|
|
this.targetDelta.y -= this.targetDelta_click.y;
|
|
}
|
|
if (this.hoverAnimation > 0 || (this.clickAnimation > 0 && this.isTouchStarted)) {
|
|
this.tween["stop"]();
|
|
this.tween["easing"](Tween["Easing"]["Quadratic"]["Out"])["to"](this.targetDelta, 100);
|
|
this._StartTicking();
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
}
|
|
if (this.OnMouseLeaveC)
|
|
this.OnMouseLeaveC();
|
|
}
|
|
setIgnoreInput(state) {
|
|
this.ignoreInput = state;
|
|
}
|
|
Tick() {
|
|
if (this.updateV) {
|
|
this.updateView();
|
|
this._StopTicking();
|
|
this.updateV = false;
|
|
return;
|
|
}
|
|
if (this.isTweenPlaying) {
|
|
this.isTweenPlaying = false;
|
|
}
|
|
if (this.tween["isPlaying"]) {
|
|
this.tween["update"](this.GetRuntime().GetWallTime() * 1000);
|
|
this.isTweenPlaying = true;
|
|
}
|
|
if (this.isTweenPlaying) {
|
|
var wi = this.wi;
|
|
this.wi.OffsetXY(this.currentDelta.x - this.prev.x, this.currentDelta.y - this.prev.y);
|
|
this.wi.SetSize(wi.GetWidth() + this.currentDelta.width - this.prev.width, wi.GetHeight() + this.currentDelta.height - this.prev.height);
|
|
this.wi.SetBboxChanged();
|
|
this.prev = {
|
|
x: this.currentDelta.x,
|
|
y: this.currentDelta.y,
|
|
width: this.currentDelta.width,
|
|
height: this.currentDelta.height
|
|
};
|
|
} else {
|
|
this._StopTicking();
|
|
}
|
|
}
|
|
isClickable(x, y) {
|
|
if (x === undefined || y === undefined) {
|
|
x = this.wi.GetBoundingBox().getLeft() + 10;
|
|
y = this.wi.GetBoundingBox().getTop() + 10;
|
|
}
|
|
if (this.ignoreInput === 1 || this.proui.ignoreInput) {
|
|
return false;
|
|
}
|
|
var isVisible = (this.wi.GetLayer().IsVisible() && this.wi.IsVisible());
|
|
var isInsideScrollView = this.isInsideScrollView(x, y);
|
|
var isUnder = false;
|
|
if (this.ignoreInput === 2 && this.aekiro_dialogManager) {
|
|
isUnder = this.aekiro_dialogManager.isInstanceUnder(this.wi.GetLayer().GetIndex());
|
|
}
|
|
return this.isEnabled && isVisible && !isUnder && isInsideScrollView;
|
|
}
|
|
isInsideScrollView(x, y) {
|
|
var insideScrollView = true;
|
|
var scrollView = this.scrollViews["l" + this.inst.GetWorldInfo().GetLayer().GetIndex()];
|
|
if (scrollView) {
|
|
insideScrollView = scrollView.GetWorldInfo().ContainsPoint(x, y);
|
|
}
|
|
return insideScrollView;
|
|
}
|
|
isOnMovingScrollView() {
|
|
var scrollView = this.scrollViews["l" + this.inst.GetWorldInfo().GetLayer().GetIndex()];
|
|
if (scrollView) {
|
|
return new Promise(resolve=>{
|
|
setTimeout(()=>{
|
|
if (scrollView.GetUnsavedDataMap().aekiro_scrollView.isMoving()) {
|
|
console.log("moving");
|
|
resolve(true);
|
|
} else {
|
|
resolve(false);
|
|
}
|
|
}
|
|
, 10);
|
|
}
|
|
);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
globalThis.Aekiro.button.Cnds = {
|
|
OnMouseEnter() {
|
|
return true;
|
|
},
|
|
OnMouseLeave() {
|
|
return true;
|
|
},
|
|
IsEnabled() {
|
|
return this.isEnabled;
|
|
},
|
|
IsClickable() {
|
|
return this.isClickable();
|
|
},
|
|
OnFocused() {
|
|
return true;
|
|
},
|
|
OnUnFocused() {
|
|
return true;
|
|
},
|
|
IsFocused() {
|
|
return this.isFocused;
|
|
},
|
|
OnClicked() {
|
|
return true;
|
|
}
|
|
};
|
|
globalThis.Aekiro.button.Acts = {
|
|
setEnabled(isEnabled) {
|
|
this.setEnabled(isEnabled);
|
|
},
|
|
SetFocused(v) {
|
|
this.setFocused(v);
|
|
},
|
|
SetIgnoreInput(s) {
|
|
this.setIgnoreInput(s);
|
|
},
|
|
SetClickSoundVolume(v) {
|
|
this.audioSources.click.setVolume(v);
|
|
},
|
|
SetHoverSoundVolume(v) {
|
|
this.audioSources.hover.setVolume(v);
|
|
},
|
|
SimulateClick() {
|
|
if (this.isTouchStarted)
|
|
return;
|
|
var x = this.wi.GetBoundingBox().getLeft() + 10;
|
|
var y = this.wi.GetBoundingBox().getTop() + 10;
|
|
this.OnInputDown(x, y);
|
|
setTimeout(()=>{
|
|
x = this.wi.GetBoundingBox().getLeft() - 50;
|
|
y = this.wi.GetBoundingBox().getTop() - 50;
|
|
this.OnAnyInputUp(x, y);
|
|
this.Callbacks();
|
|
}
|
|
, 100);
|
|
},
|
|
setNormalFrame(v) {
|
|
this.frame_normal = v;
|
|
this.initFrameAnim();
|
|
this.setFrameAnim(this.state);
|
|
},
|
|
setHoverFrame(v) {
|
|
this.frame_hover = v;
|
|
this.initFrameAnim();
|
|
},
|
|
setClickedFrame(v) {
|
|
this.frame_clicked = v;
|
|
this.initFrameAnim();
|
|
},
|
|
setDisabledFrame(v) {
|
|
this.frame_disabled = v;
|
|
this.initFrameAnim();
|
|
},
|
|
setFocusFrame(v) {
|
|
this.frame_focus = v;
|
|
this.initFrameAnim();
|
|
},
|
|
setClickAnimation(v) {
|
|
this.clickAnimation = v;
|
|
this.initAnimations();
|
|
},
|
|
setHoverAnimation(v) {
|
|
this.hoverAnimation = v;
|
|
this.initAnimations();
|
|
},
|
|
setFocusAnimation(v) {
|
|
this.focusAnimation = v;
|
|
this.initAnimations();
|
|
},
|
|
setNormalColor(v) {
|
|
this.color_normal = v;
|
|
this.initColors();
|
|
},
|
|
setHoverColor(v) {
|
|
this.color_hover = v;
|
|
this.initColors();
|
|
},
|
|
setClickedColor(v) {
|
|
this.color_clicked = v;
|
|
this.initColors();
|
|
},
|
|
setFocusColor(v) {
|
|
this.color_focus = v;
|
|
this.initColors();
|
|
}
|
|
};
|
|
globalThis.Aekiro.checkbox = class aekiro_checkbox extends globalThis.Aekiro.button {
|
|
constructor(behInst, properties) {
|
|
super(behInst, properties);
|
|
}
|
|
checkbox_constructor() {
|
|
this.button_constructor();
|
|
this.frameAnim = [[], []];
|
|
}
|
|
initFrameAnim() {
|
|
this.useStates = true;
|
|
if (!this.isInstanceOfSprite || (this.frame_normal == "" && this.frame_hover == "" && this.frame_disabled == "")) {
|
|
this.useStates = false;
|
|
return;
|
|
}
|
|
this.cur_AnimationFrame = this.sdkInstance.CallExpression(this.sdkInstance_exps.AnimationFrame);
|
|
this.cur_AnimationName = this.sdkInstance.CallExpression(this.sdkInstance_exps.AnimationName);
|
|
var f = this.frame_normal.split(',');
|
|
this.frameAnim[0][this.STATES.NORMAL] = this.parseFrameAnim(f[0]);
|
|
this.frameAnim[1][this.STATES.NORMAL] = this.parseFrameAnim(f[1]);
|
|
f = this.frame_hover.split(',');
|
|
this.frameAnim[0][this.STATES.HOVER] = this.parseFrameAnim(f[0], {
|
|
"f": null,
|
|
"a": null
|
|
});
|
|
this.frameAnim[1][this.STATES.HOVER] = this.parseFrameAnim(f[1], {
|
|
"f": null,
|
|
"a": null
|
|
});
|
|
f = this.frame_disabled.split(',');
|
|
this.frameAnim[0][this.STATES.DISABLED] = this.parseFrameAnim(f[0]);
|
|
this.frameAnim[1][this.STATES.DISABLED] = this.parseFrameAnim(f[1]);
|
|
f = this.frame_focus.split(',');
|
|
this.frameAnim[0][this.STATES.FOCUSED] = this.parseFrameAnim(f[0], {
|
|
"f": null,
|
|
"a": null
|
|
});
|
|
this.frameAnim[1][this.STATES.FOCUSED] = this.parseFrameAnim(f[1], {
|
|
"f": null,
|
|
"a": null
|
|
});
|
|
}
|
|
setFrameAnim(state) {
|
|
if (!this.useStates) {
|
|
return;
|
|
}
|
|
if (state == this.STATES.CLICKED)
|
|
state = this.STATES.NORMAL;
|
|
var v = this.value ? 1 : 0;
|
|
var frame, anim;
|
|
if (this.isFocused) {
|
|
if (this.state == this.STATES.NORMAL) {
|
|
frame = (this.frameAnim[v][this.STATES.FOCUSED]["f"] === null) ? this.frameAnim[v][this.STATES.NORMAL]["f"] : this.frameAnim[v][this.STATES.FOCUSED]["f"];
|
|
anim = this.frameAnim[v][this.STATES.FOCUSED]["a"] || this.frameAnim[v][this.STATES.NORMAL]["a"];
|
|
} else {
|
|
if (this.frameAnim[v][state]["f"] == null && !this.frameAnim[v][state]["a"]) {
|
|
frame = this.frameAnim[v][this.STATES.NORMAL]["f"];
|
|
anim = this.frameAnim[v][this.STATES.NORMAL]["a"];
|
|
} else {
|
|
frame = (this.frameAnim[v][state]["f"] === null) ? this.frameAnim[v][this.STATES.FOCUSED]["f"] : this.frameAnim[v][state]["f"];
|
|
anim = this.frameAnim[v][state]["a"] || this.frameAnim[v][this.STATES.FOCUSED]["a"];
|
|
}
|
|
}
|
|
} else {
|
|
frame = this.frameAnim[v][state]["f"];
|
|
anim = this.frameAnim[v][state]["a"];
|
|
}
|
|
if (anim) {
|
|
this.sdkInstance.CallAction(this.sdkInstance_acts.SetAnim, anim, 0);
|
|
}
|
|
if (frame !== null) {
|
|
this.sdkInstance.CallAction(this.sdkInstance_acts.SetAnimFrame, frame, 0);
|
|
}
|
|
}
|
|
initColors() {
|
|
this.cur_color = this.wi.GetUnpremultipliedColor();
|
|
this.colors = [[], []];
|
|
var c;
|
|
c = this.color_normal.split(';');
|
|
this.colors[0][this.STATES.NORMAL] = this.parseColor(c[0]);
|
|
this.colors[1][this.STATES.NORMAL] = this.parseColor(c[1], this.colors[0][this.STATES.NORMAL]);
|
|
c = this.color_hover.split(';');
|
|
this.colors[0][this.STATES.HOVER] = this.parseColor(c[0], null);
|
|
this.colors[1][this.STATES.HOVER] = this.parseColor(c[1], this.colors[0][this.STATES.HOVER]);
|
|
c = this.color_clicked.split(';');
|
|
this.colors[0][this.STATES.CLICKED] = this.parseColor(c[0], null);
|
|
this.colors[1][this.STATES.CLICKED] = this.parseColor(c[1], this.colors[0][this.STATES.CLICKED]);
|
|
c = this.color_disabled.split(';');
|
|
this.colors[0][this.STATES.DISABLED] = this.parseColor(c[0]);
|
|
this.colors[1][this.STATES.DISABLED] = this.parseColor(c[1]),
|
|
this.colors[0][this.STATES.DISABLED];
|
|
c = this.color_focus.split(';');
|
|
this.colors[0][this.STATES.FOCUSED] = this.parseColor(c[0], null);
|
|
this.colors[1][this.STATES.FOCUSED] = this.parseColor(c[1], this.colors[0][this.STATES.FOCUSED]);
|
|
}
|
|
setColor(state) {
|
|
var v = this.value ? 1 : 0;
|
|
var color;
|
|
if (this.isFocused) {
|
|
if (this.state == this.STATES.NORMAL) {
|
|
color = this.colors[v][this.STATES.FOCUSED] || this.colors[v][this.STATES.NORMAL];
|
|
} else {
|
|
color = this.colors[v][state] || this.colors[v][this.STATES.FOCUSED];
|
|
if (!this.colors[v][state] && !this.colors[v][this.STATES.FOCUSED]) {
|
|
color = this.colors[v][this.STATES.NORMAL];
|
|
}
|
|
}
|
|
} else {
|
|
color = this.colors[v][state];
|
|
}
|
|
if (color) {
|
|
this.wi.SetUnpremultipliedColor(color);
|
|
this.wi.SetBboxChanged();
|
|
}
|
|
}
|
|
isValueValid(value) {
|
|
if (value == null || value === "") {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
setValue(value) {
|
|
value = !!value;
|
|
value = value ? 1 : 0;
|
|
if (this.value != value) {
|
|
this.value = value;
|
|
this.setFrameAnim(this.state);
|
|
this.setColor(this.state);
|
|
}
|
|
}
|
|
}
|
|
;
|
|
globalThis.aekiro_scrollViewManager = {
|
|
scrollViews: {},
|
|
add: function(inst) {
|
|
this.scrollViews["l" + inst.GetWorldInfo().GetLayer().GetIndex()] = inst;
|
|
},
|
|
remove: function(inst) {
|
|
for (var key in this.scrollViews) {
|
|
if (this.scrollViews[key] == inst) {
|
|
delete this.scrollViews[key];
|
|
}
|
|
}
|
|
},
|
|
isOverlaped: function(inst, x, y) {
|
|
var n = inst.GetRuntime().GetMainRunningLayout().GetLayerCount();
|
|
var scrollView;
|
|
var isOverlaped = false;
|
|
for (var i = inst.GetWorldInfo().GetLayer().GetIndex() + 1, l = n; i < l; i++) {
|
|
scrollView = this.scrollViews["l" + i];
|
|
if (scrollView) {
|
|
if (!scrollView.GetWorldInfo().GetLayer().IsVisible()) {
|
|
continue;
|
|
}
|
|
if (scrollView.GetWorldInfo().ContainsPoint(x, y)) {
|
|
isOverlaped = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return isOverlaped;
|
|
}
|
|
};
|
|
globalThis.aekiro_dialogManager = {
|
|
currentDialogs: [],
|
|
addDialog: function(inst) {
|
|
this.currentDialogs.push(inst);
|
|
},
|
|
removeDialog: function(inst) {
|
|
var i = this.currentDialogs.indexOf(inst);
|
|
if (i != -1) {
|
|
this.currentDialogs.splice(i, 1);
|
|
}
|
|
},
|
|
isDialogOpened: function() {
|
|
return this.currentDialogs.length;
|
|
},
|
|
isModalDialogOpened: function() {
|
|
for (var i = 0; i < this.currentDialogs.length; i++) {
|
|
if (this.currentDialogs[i].GetUnsavedDataMap().aekiro_dialog.isModal) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
isInstanceUnder: function(layerIndex) {
|
|
for (var i = 0, l = this.currentDialogs.length; i < l; i++) {
|
|
if (layerIndex < this.currentDialogs[i].GetWorldInfo().GetLayer().GetIndex()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
"use strict";
|
|
{
|
|
C3.Plugins.aekiro_proui.Cnds = {
|
|
IsDialogOpened() {
|
|
return globalThis.aekiro_dialogManager.isDialogOpened();
|
|
},
|
|
OnAnyButtonClicked() {
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.aekiro_proui.Acts = {
|
|
SetInputIgnored(state) {
|
|
this.ignoreInput = state;
|
|
},
|
|
Clone(json, layer, x, y, name, parentName) {
|
|
json = JSON.parse(json);
|
|
var inst = this.aekiro_goManager.clone(json, name, parentName, layer, x, y);
|
|
inst.GetUnsavedDataMap().aekiro_gameobject.updateZindex();
|
|
},
|
|
SetUIAudioVolume(v) {
|
|
this.setUIAudioVolume(v);
|
|
},
|
|
Init() {
|
|
this.Initialise();
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.aekiro_proui.Exps = {};
|
|
}
|
|
'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Touch = class TouchPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Touch.Type = class TouchType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
GetScriptInterfaceClass() {
|
|
return self.ITouchObjectType
|
|
}
|
|
}
|
|
;
|
|
let touchObjectType = null;
|
|
function GetTouchSdkInstance() {
|
|
return touchObjectType.GetSingleGlobalInstance().GetSdkInstance()
|
|
}
|
|
self.ITouchObjectType = class ITouchObjectType extends self.IObjectClass {
|
|
constructor(objectType) {
|
|
super(objectType);
|
|
touchObjectType = objectType;
|
|
objectType.GetRuntime()._GetCommonScriptInterfaces().touch = this
|
|
}
|
|
requestPermission(type) {
|
|
const touchInst = GetTouchSdkInstance();
|
|
if (type === "orientation")
|
|
return touchInst._RequestPermission(0);
|
|
else if (type === "motion")
|
|
return touchInst._RequestPermission(1);
|
|
else
|
|
throw new Error("invalid type");
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const DOM_COMPONENT_ID = "touch";
|
|
C3.Plugins.Touch.Instance = class TouchInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst, DOM_COMPONENT_ID);
|
|
this._touches = new Map;
|
|
this._useMouseInput = false;
|
|
this._isMouseDown = false;
|
|
this._orientCompassHeading = 0;
|
|
this._orientAlpha = 0;
|
|
this._orientBeta = 0;
|
|
this._orientGamma = 0;
|
|
this._accX = 0;
|
|
this._accY = 0;
|
|
this._accZ = 0;
|
|
this._accWithGX = 0;
|
|
this._accWithGY = 0;
|
|
this._accWithGZ = 0;
|
|
this._triggerIndex = 0;
|
|
this._triggerId = 0;
|
|
this._triggerPermission = 0;
|
|
this._curTouchX = 0;
|
|
this._curTouchY = 0;
|
|
this._getTouchIndex = 0;
|
|
this._permissionPromises = [];
|
|
if (properties)
|
|
this._useMouseInput = properties[0];
|
|
this.AddDOMMessageHandler("permission-result", e=>this._OnPermissionResult(e));
|
|
const rt = this.GetRuntime().Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(rt, "pointerdown", e=>this._OnPointerDown(e.data)),C3.Disposable.From(rt, "pointermove", e=>this._OnPointerMove(e.data)),C3.Disposable.From(rt, "pointerup", e=>this._OnPointerUp(e.data, false)),C3.Disposable.From(rt, "pointercancel", e=>this._OnPointerUp(e.data, true)),C3.Disposable.From(rt, "deviceorientation", e=>this._OnDeviceOrientation(e.data)),C3.Disposable.From(rt, "deviceorientationabsolute", e=>this._OnDeviceOrientationAbsolute(e.data)),C3.Disposable.From(rt, "devicemotion", e=>this._OnDeviceMotion(e.data)),C3.Disposable.From(rt, "tick2", e=>this._OnTick2()))
|
|
}
|
|
Release() {
|
|
this._touches.clear();
|
|
super.Release()
|
|
}
|
|
_OnPointerDown(e) {
|
|
if (e["pointerType"] === "mouse")
|
|
if (this._useMouseInput)
|
|
this._isMouseDown = true;
|
|
else
|
|
return;
|
|
const pointerId = e["pointerId"];
|
|
if (this._touches.has(pointerId))
|
|
return;
|
|
const x = e["pageX"] - this._runtime.GetCanvasClientX();
|
|
const y = e["pageY"] - this._runtime.GetCanvasClientY();
|
|
const nowTime = e["timeStamp"];
|
|
const index = this._touches.size;
|
|
this._triggerIndex = index;
|
|
this._triggerId = pointerId;
|
|
const touchInfo = C3.New(C3.Plugins.Touch.TouchInfo);
|
|
touchInfo.Init(nowTime, x, y, pointerId, index);
|
|
this._touches.set(pointerId, touchInfo);
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnNthTouchStart);
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnTouchStart);
|
|
this._curTouchX = x;
|
|
this._curTouchY = y;
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnTouchObject)
|
|
}
|
|
_OnPointerMove(e) {
|
|
if (e["pointerType"] === "mouse" && !this._isMouseDown)
|
|
return;
|
|
const touchInfo = this._touches.get(e["pointerId"]);
|
|
if (!touchInfo)
|
|
return;
|
|
const nowTime = e["timeStamp"];
|
|
if (nowTime - touchInfo.GetTime() < 2)
|
|
return;
|
|
const x = e["pageX"] - this._runtime.GetCanvasClientX();
|
|
const y = e["pageY"] - this._runtime.GetCanvasClientY();
|
|
touchInfo.Update(nowTime, x, y, e["width"], e["height"], e["pressure"])
|
|
}
|
|
_OnPointerUp(e, isCancel) {
|
|
if (e["pointerType"] === "mouse")
|
|
if (this._isMouseDown)
|
|
this._isMouseDown = false;
|
|
else
|
|
return;
|
|
const nowTime = e["timeStamp"];
|
|
const pointerId = e["pointerId"];
|
|
const touchInfo = this._touches.get(pointerId);
|
|
if (!touchInfo)
|
|
return;
|
|
this._triggerIndex = touchInfo.GetStartIndex();
|
|
this._triggerId = touchInfo.GetId();
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnNthTouchEnd);
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnTouchEnd);
|
|
if (!isCancel) {
|
|
const tap = touchInfo.ShouldTriggerTap(nowTime);
|
|
if (tap === "single-tap") {
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnTapGesture);
|
|
this._curTouchX = touchInfo.GetX();
|
|
this._curTouchY = touchInfo.GetY();
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnTapGestureObject)
|
|
} else if (tap === "double-tap") {
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnDoubleTapGesture);
|
|
this._curTouchX = touchInfo.GetX();
|
|
this._curTouchY = touchInfo.GetY();
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnDoubleTapGestureObject)
|
|
}
|
|
}
|
|
touchInfo.Release();
|
|
this._touches.delete(pointerId)
|
|
}
|
|
_RequestPermission(type) {
|
|
this._PostToDOMMaybeSync("request-permission", {
|
|
"type": type
|
|
});
|
|
return new Promise((resolve,reject)=>{
|
|
this._permissionPromises.push({
|
|
type,
|
|
resolve,
|
|
reject
|
|
})
|
|
}
|
|
)
|
|
}
|
|
_OnPermissionResult(e) {
|
|
const isGranted = e["result"];
|
|
const type = e["type"];
|
|
this._triggerPermission = type;
|
|
const toResolve = this._permissionPromises.filter(o=>o.type === type);
|
|
for (const o of toResolve)
|
|
o.resolve(isGranted ? "granted" : "denied");
|
|
this._permissionPromises = this._permissionPromises.filter(o=>o.type !== type);
|
|
if (isGranted) {
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnPermissionGranted);
|
|
if (type === 0)
|
|
this._runtime.RequestDeviceOrientationEvent();
|
|
else
|
|
this._runtime.RequestDeviceMotionEvent()
|
|
} else
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnPermissionDenied)
|
|
}
|
|
_OnDeviceOrientation(e) {
|
|
if (typeof e["webkitCompassHeading"] === "number")
|
|
this._orientCompassHeading = e["webkitCompassHeading"];
|
|
else if (e["absolute"])
|
|
this._orientCompassHeading = e["alpha"];
|
|
this._orientAlpha = e["alpha"];
|
|
this._orientBeta = e["beta"];
|
|
this._orientGamma = e["gamma"]
|
|
}
|
|
_OnDeviceOrientationAbsolute(e) {
|
|
this._orientCompassHeading = e["alpha"]
|
|
}
|
|
_OnDeviceMotion(e) {
|
|
const acc = e["acceleration"];
|
|
if (acc) {
|
|
this._accX = acc["x"];
|
|
this._accY = acc["y"];
|
|
this._accZ = acc["z"]
|
|
}
|
|
const withG = e["accelerationIncludingGravity"];
|
|
if (withG) {
|
|
this._accWithGX = withG["x"];
|
|
this._accWithGY = withG["y"];
|
|
this._accWithGZ = withG["z"]
|
|
}
|
|
}
|
|
_OnTick2() {
|
|
const nowTime = performance.now();
|
|
let index = 0;
|
|
for (const touchInfo of this._touches.values()) {
|
|
if (touchInfo.GetTime() <= nowTime - 50)
|
|
touchInfo._SetLastTime(nowTime);
|
|
if (touchInfo.ShouldTriggerHold(nowTime)) {
|
|
this._triggerIndex = touchInfo.GetStartIndex();
|
|
this._triggerId = touchInfo.GetId();
|
|
this._getTouchIndex = index;
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnHoldGesture);
|
|
this._curTouchX = touchInfo.GetX();
|
|
this._curTouchY = touchInfo.GetY();
|
|
this.Trigger(C3.Plugins.Touch.Cnds.OnHoldGestureObject);
|
|
this._getTouchIndex = 0
|
|
}
|
|
++index
|
|
}
|
|
}
|
|
_GetTouchByIndex(index) {
|
|
index = Math.floor(index);
|
|
for (const touchInfo of this._touches.values()) {
|
|
if (index === 0)
|
|
return touchInfo;
|
|
--index
|
|
}
|
|
return null
|
|
}
|
|
_IsClientPosOnCanvas(touchX, touchY) {
|
|
return touchX >= 0 && touchY >= 0 && touchX < this._runtime.GetCanvasCssWidth() && touchY < this._runtime.GetCanvasCssHeight()
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "plugins.touch.debugger";
|
|
return [{
|
|
title: prefix + ".touches",
|
|
properties: [...this._touches.values()].map(ti=>({
|
|
name: "$" + ti.GetId(),
|
|
value: ti.GetX() + ", " + ti.GetY()
|
|
}))
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tempArr = [];
|
|
C3.Plugins.Touch.Cnds = {
|
|
OnTouchStart() {
|
|
return true
|
|
},
|
|
OnTouchEnd() {
|
|
return true
|
|
},
|
|
IsInTouch() {
|
|
return this._touches.size > 0
|
|
},
|
|
OnTouchObject(objectClass) {
|
|
if (!objectClass)
|
|
return false;
|
|
if (!this._IsClientPosOnCanvas(this._curTouchX, this._curTouchY))
|
|
return false;
|
|
return this._runtime.GetCollisionEngine().TestAndSelectCanvasPointOverlap(objectClass, this._curTouchX, this._curTouchY, false)
|
|
},
|
|
IsTouchingObject(objectClass) {
|
|
if (!objectClass)
|
|
return false;
|
|
const sol = objectClass.GetCurrentSol();
|
|
const instances = sol.GetInstances();
|
|
for (const inst of instances) {
|
|
const wi = inst.GetWorldInfo();
|
|
const layer = wi.GetLayer();
|
|
for (const touchInfo of this._touches.values()) {
|
|
if (!this._IsClientPosOnCanvas(touchInfo.GetX(), touchInfo.GetY()))
|
|
continue;
|
|
const [px,py] = layer.CanvasCssToLayer(touchInfo.GetX(), touchInfo.GetY(), wi.GetTotalZElevation());
|
|
if (wi.ContainsPoint(px, py)) {
|
|
tempArr.push(inst);
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if (tempArr.length) {
|
|
sol.SetArrayPicked(tempArr);
|
|
objectClass.ApplySolToContainer();
|
|
C3.clearArray(tempArr);
|
|
return true
|
|
} else
|
|
return false
|
|
},
|
|
CompareTouchSpeed(index, cmp, s) {
|
|
const touchInfo = this._GetTouchByIndex(index);
|
|
if (!touchInfo)
|
|
return false;
|
|
return C3.compare(touchInfo.GetSpeed(), cmp, s)
|
|
},
|
|
OrientationSupported() {
|
|
return true
|
|
},
|
|
MotionSupported() {
|
|
return true
|
|
},
|
|
CompareOrientation(orientation, cmp, a) {
|
|
this._runtime.RequestDeviceOrientationEvent();
|
|
let v = 0;
|
|
if (orientation === 0)
|
|
v = this._orientAlpha;
|
|
else if (orientation === 1)
|
|
v = this._orientBeta;
|
|
else
|
|
v = this._orientGamma;
|
|
return C3.compare(v, cmp, a)
|
|
},
|
|
CompareAcceleration(a, cmp, x) {
|
|
this._runtime.RequestDeviceMotionEvent();
|
|
let v = 0;
|
|
if (a === 0)
|
|
v = this._accWithGX;
|
|
else if (a === 1)
|
|
v = this._accWithGY;
|
|
else if (a === 2)
|
|
v = this._accWithGZ;
|
|
else if (a === 3)
|
|
v = this._accX;
|
|
else if (a === 4)
|
|
v = this._accY;
|
|
else
|
|
v = this._accZ;
|
|
return C3.compare(v, cmp, x)
|
|
},
|
|
OnNthTouchStart(index) {
|
|
index = Math.floor(index);
|
|
return index === this._triggerIndex
|
|
},
|
|
OnNthTouchEnd(index) {
|
|
index = Math.floor(index);
|
|
return index === this._triggerIndex
|
|
},
|
|
HasNthTouch(index) {
|
|
index = Math.floor(index);
|
|
return this._touches.size >= index + 1
|
|
},
|
|
OnHoldGesture() {
|
|
return true
|
|
},
|
|
OnTapGesture() {
|
|
return true
|
|
},
|
|
OnDoubleTapGesture() {
|
|
return true
|
|
},
|
|
OnHoldGestureObject(objectClass) {
|
|
if (!objectClass)
|
|
return false;
|
|
if (!this._IsClientPosOnCanvas(this._curTouchX, this._curTouchY))
|
|
return false;
|
|
return this._runtime.GetCollisionEngine().TestAndSelectCanvasPointOverlap(objectClass, this._curTouchX, this._curTouchY, false)
|
|
},
|
|
OnTapGestureObject(objectClass) {
|
|
if (!objectClass)
|
|
return false;
|
|
if (!this._IsClientPosOnCanvas(this._curTouchX, this._curTouchY))
|
|
return false;
|
|
return this._runtime.GetCollisionEngine().TestAndSelectCanvasPointOverlap(objectClass, this._curTouchX, this._curTouchY, false)
|
|
},
|
|
OnDoubleTapGestureObject(objectClass) {
|
|
if (!objectClass)
|
|
return false;
|
|
if (!this._IsClientPosOnCanvas(this._curTouchX, this._curTouchY))
|
|
return false;
|
|
return this._runtime.GetCollisionEngine().TestAndSelectCanvasPointOverlap(objectClass, this._curTouchX, this._curTouchY, false)
|
|
},
|
|
OnPermissionGranted(type) {
|
|
return this._triggerPermission === type
|
|
},
|
|
OnPermissionDenied(type) {
|
|
return this._triggerPermission === type
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Touch.Acts = {
|
|
RequestPermission(type) {
|
|
this._RequestPermission(type)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Touch.Exps = {
|
|
TouchCount() {
|
|
return this._touches.size
|
|
},
|
|
X(layerParam) {
|
|
const touchInfo = this._GetTouchByIndex(this._getTouchIndex);
|
|
if (!touchInfo)
|
|
return 0;
|
|
return touchInfo.GetPositionForLayer(this._runtime.GetCurrentLayout(), layerParam, true)
|
|
},
|
|
Y(layerParam) {
|
|
const touchInfo = this._GetTouchByIndex(this._getTouchIndex);
|
|
if (!touchInfo)
|
|
return 0;
|
|
return touchInfo.GetPositionForLayer(this._runtime.GetCurrentLayout(), layerParam, false)
|
|
},
|
|
XAt(index, layerParam) {
|
|
const touchInfo = this._GetTouchByIndex(index);
|
|
if (!touchInfo)
|
|
return 0;
|
|
return touchInfo.GetPositionForLayer(this._runtime.GetCurrentLayout(), layerParam, true)
|
|
},
|
|
YAt(index, layerParam) {
|
|
const touchInfo = this._GetTouchByIndex(index);
|
|
if (!touchInfo)
|
|
return 0;
|
|
return touchInfo.GetPositionForLayer(this._runtime.GetCurrentLayout(), layerParam, false)
|
|
},
|
|
XForID(id, layerParam) {
|
|
const touchInfo = this._touches.get(id);
|
|
if (!touchInfo)
|
|
return 0;
|
|
return touchInfo.GetPositionForLayer(this._runtime.GetCurrentLayout(), layerParam, true)
|
|
},
|
|
YForID(id, layerParam) {
|
|
const touchInfo = this._touches.get(id);
|
|
if (!touchInfo)
|
|
return 0;
|
|
return touchInfo.GetPositionForLayer(this._runtime.GetCurrentLayout(), layerParam, false)
|
|
},
|
|
AbsoluteX() {
|
|
const touchInfo = this._GetTouchByIndex(0);
|
|
if (touchInfo)
|
|
return touchInfo.GetX();
|
|
else
|
|
return 0
|
|
},
|
|
AbsoluteY() {
|
|
const touchInfo = this._GetTouchByIndex(0);
|
|
if (touchInfo)
|
|
return touchInfo.GetY();
|
|
else
|
|
return 0
|
|
},
|
|
AbsoluteXAt(index) {
|
|
const touchInfo = this._GetTouchByIndex(index);
|
|
if (touchInfo)
|
|
return touchInfo.GetX();
|
|
else
|
|
return 0
|
|
},
|
|
AbsoluteYAt(index) {
|
|
const touchInfo = this._GetTouchByIndex(index);
|
|
if (touchInfo)
|
|
return touchInfo.GetY();
|
|
else
|
|
return 0
|
|
},
|
|
AbsoluteXForID(id) {
|
|
const touchInfo = this._touches.get(id);
|
|
if (touchInfo)
|
|
return touchInfo.GetX();
|
|
else
|
|
return 0
|
|
},
|
|
AbsoluteYForID(id) {
|
|
const touchInfo = this._touches.get(id);
|
|
if (touchInfo)
|
|
return touchInfo.GetY();
|
|
else
|
|
return 0
|
|
},
|
|
SpeedAt(index) {
|
|
const touchInfo = this._GetTouchByIndex(index);
|
|
if (touchInfo)
|
|
return touchInfo.GetSpeed();
|
|
else
|
|
return 0
|
|
},
|
|
SpeedForID(id) {
|
|
const touchInfo = this._touches.get(id);
|
|
if (touchInfo)
|
|
return touchInfo.GetSpeed();
|
|
else
|
|
return 0
|
|
},
|
|
AngleAt(index) {
|
|
const touchInfo = this._GetTouchByIndex(index);
|
|
if (touchInfo)
|
|
return C3.toDegrees(touchInfo.GetAngle());
|
|
else
|
|
return 0
|
|
},
|
|
AngleForID(id) {
|
|
const touchInfo = this._touches.get(id);
|
|
if (touchInfo)
|
|
return C3.toDegrees(touchInfo.GetAngle());
|
|
else
|
|
return 0
|
|
},
|
|
CompassHeading() {
|
|
this._runtime.RequestDeviceOrientationEvent();
|
|
return this._orientCompassHeading
|
|
},
|
|
Alpha() {
|
|
this._runtime.RequestDeviceOrientationEvent();
|
|
return this._orientAlpha
|
|
},
|
|
Beta() {
|
|
this._runtime.RequestDeviceOrientationEvent();
|
|
return this._orientBeta
|
|
},
|
|
Gamma() {
|
|
this._runtime.RequestDeviceOrientationEvent();
|
|
return this._orientGamma
|
|
},
|
|
AccelerationXWithG() {
|
|
this._runtime.RequestDeviceMotionEvent();
|
|
return this._accWithGX
|
|
},
|
|
AccelerationYWithG() {
|
|
this._runtime.RequestDeviceMotionEvent();
|
|
return this._accWithGY
|
|
},
|
|
AccelerationZWithG() {
|
|
this._runtime.RequestDeviceMotionEvent();
|
|
return this._accWithGZ
|
|
},
|
|
AccelerationX() {
|
|
this._runtime.RequestDeviceMotionEvent();
|
|
return this._accX
|
|
},
|
|
AccelerationY() {
|
|
this._runtime.RequestDeviceMotionEvent();
|
|
return this._accY
|
|
},
|
|
AccelerationZ() {
|
|
this._runtime.RequestDeviceMotionEvent();
|
|
return this._accZ
|
|
},
|
|
TouchIndex() {
|
|
return this._triggerIndex
|
|
},
|
|
TouchID() {
|
|
return this._triggerId
|
|
},
|
|
WidthForID(id) {
|
|
const touchInfo = this._touches.get(id);
|
|
if (touchInfo)
|
|
return touchInfo.GetWidth();
|
|
else
|
|
return 0
|
|
},
|
|
HeightForID(id) {
|
|
const touchInfo = this._touches.get(id);
|
|
if (touchInfo)
|
|
return touchInfo.GetHeight();
|
|
else
|
|
return 0
|
|
},
|
|
PressureForID(id) {
|
|
const touchInfo = this._touches.get(id);
|
|
if (touchInfo)
|
|
return touchInfo.GetPressure();
|
|
else
|
|
return 0
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const GESTURE_HOLD_THRESHOLD = 15;
|
|
const GESTURE_HOLD_TIMEOUT = 500;
|
|
const GESTURE_TAP_TIMEOUT = 333;
|
|
const GESTURE_DOUBLETAP_THRESHOLD = 25;
|
|
let lastTapX = -1E3;
|
|
let lastTapY = -1E3;
|
|
let lastTapTime = -1E4;
|
|
C3.Plugins.Touch.TouchInfo = class TouchInfo extends C3.DefendedBase {
|
|
constructor() {
|
|
super();
|
|
this._pointerId = 0;
|
|
this._startIndex = 0;
|
|
this._startTime = 0;
|
|
this._time = 0;
|
|
this._lastTime = 0;
|
|
this._startX = 0;
|
|
this._startY = 0;
|
|
this._x = 0;
|
|
this._y = 0;
|
|
this._lastX = 0;
|
|
this._lastY = 0;
|
|
this._width = 0;
|
|
this._height = 0;
|
|
this._pressure = 0;
|
|
this._hasTriggeredHold = false;
|
|
this._isTooFarForHold = false
|
|
}
|
|
Release() {}
|
|
Init(nowTime, x, y, id, index) {
|
|
this._pointerId = id;
|
|
this._startIndex = index;
|
|
this._time = nowTime;
|
|
this._lastTime = nowTime;
|
|
this._startTime = nowTime;
|
|
this._startX = x;
|
|
this._startY = y;
|
|
this._x = x;
|
|
this._y = y;
|
|
this._lastX = x;
|
|
this._lastY = y
|
|
}
|
|
Update(nowTime, x, y, width, height, pressure) {
|
|
this._lastTime = this._time;
|
|
this._time = nowTime;
|
|
this._lastX = this._x;
|
|
this._lastY = this._y;
|
|
this._x = x;
|
|
this._y = y;
|
|
this._width = width;
|
|
this._height = height;
|
|
this._pressure = pressure;
|
|
if (!this._isTooFarForHold && C3.distanceTo(this._startX, this._startY, this._x, this._y) >= GESTURE_HOLD_THRESHOLD)
|
|
this._isTooFarForHold = true
|
|
}
|
|
GetId() {
|
|
return this._pointerId
|
|
}
|
|
GetStartIndex() {
|
|
return this._startIndex
|
|
}
|
|
GetTime() {
|
|
return this._time
|
|
}
|
|
_SetLastTime(t) {
|
|
this._lastTime = t
|
|
}
|
|
GetX() {
|
|
return this._x
|
|
}
|
|
GetY() {
|
|
return this._y
|
|
}
|
|
GetSpeed() {
|
|
const dist = C3.distanceTo(this._x, this._y, this._lastX, this._lastY);
|
|
const dt = (this._time - this._lastTime) / 1E3;
|
|
if (dt > 0)
|
|
return dist / dt;
|
|
else
|
|
return 0
|
|
}
|
|
GetAngle() {
|
|
return C3.angleTo(this._lastX, this._lastY, this._x, this._y)
|
|
}
|
|
GetWidth() {
|
|
return this._width
|
|
}
|
|
GetHeight() {
|
|
return this._height
|
|
}
|
|
GetPressure() {
|
|
return this._pressure
|
|
}
|
|
ShouldTriggerHold(nowTime) {
|
|
if (this._hasTriggeredHold)
|
|
return false;
|
|
if (nowTime - this._startTime >= GESTURE_HOLD_TIMEOUT && !this._isTooFarForHold && C3.distanceTo(this._startX, this._startY, this._x, this._y) < GESTURE_HOLD_THRESHOLD) {
|
|
this._hasTriggeredHold = true;
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
ShouldTriggerTap(nowTime) {
|
|
if (this._hasTriggeredHold)
|
|
return "";
|
|
if (nowTime - this._startTime <= GESTURE_TAP_TIMEOUT && !this._isTooFarForHold && C3.distanceTo(this._startX, this._startY, this._x, this._y) < GESTURE_HOLD_THRESHOLD)
|
|
if (nowTime - lastTapTime <= GESTURE_TAP_TIMEOUT * 2 && C3.distanceTo(lastTapX, lastTapY, this._x, this._y) < GESTURE_DOUBLETAP_THRESHOLD) {
|
|
lastTapX = -1E3;
|
|
lastTapY = -1E3;
|
|
lastTapTime = -1E4;
|
|
return "double-tap"
|
|
} else {
|
|
lastTapX = this._x;
|
|
lastTapY = this._y;
|
|
lastTapTime = nowTime;
|
|
return "single-tap"
|
|
}
|
|
return ""
|
|
}
|
|
GetPositionForLayer(layout, layerNameOrNumber, getx) {
|
|
if (typeof layerNameOrNumber === "undefined") {
|
|
const layer = layout.GetLayerByIndex(0);
|
|
return layer.CanvasCssToLayer_DefaultTransform(this._x, this._y)[getx ? 0 : 1]
|
|
} else {
|
|
const layer = layout.GetLayer(layerNameOrNumber);
|
|
if (layer)
|
|
return layer.CanvasCssToLayer(this._x, this._y)[getx ? 0 : 1];
|
|
else
|
|
return 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Mouse = class MousePlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Mouse.Type = class MouseType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
GetScriptInterfaceClass() {
|
|
return self.IMouseObjectType
|
|
}
|
|
}
|
|
;
|
|
let mouseObjectType = null;
|
|
function GetMouseSdkInstance() {
|
|
return mouseObjectType.GetSingleGlobalInstance().GetSdkInstance()
|
|
}
|
|
self.IMouseObjectType = class IMouseObjectType extends self.IObjectClass {
|
|
constructor(objectType) {
|
|
super(objectType);
|
|
mouseObjectType = objectType;
|
|
objectType.GetRuntime()._GetCommonScriptInterfaces().mouse = this
|
|
}
|
|
getMouseX(layerNameOrNumber) {
|
|
return GetMouseSdkInstance().GetMousePositionForLayer(layerNameOrNumber)[0]
|
|
}
|
|
getMouseY(layerNameOrNumber) {
|
|
return GetMouseSdkInstance().GetMousePositionForLayer(layerNameOrNumber)[1]
|
|
}
|
|
getMousePosition(layerNameOrNumber) {
|
|
return GetMouseSdkInstance().GetMousePositionForLayer(layerNameOrNumber)
|
|
}
|
|
isMouseButtonDown(button) {
|
|
return GetMouseSdkInstance().IsMouseButtonDown(button)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const DOM_COMPONENT_ID = "mouse";
|
|
C3.Plugins.Mouse.Instance = class MouseInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst, DOM_COMPONENT_ID);
|
|
this._buttonMap = [false, false, false];
|
|
this._mouseXcanvas = 0;
|
|
this._mouseYcanvas = 0;
|
|
this._triggerButton = 0;
|
|
this._triggerType = 0;
|
|
this._triggerDir = 0;
|
|
const rt = this.GetRuntime().Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(rt, "pointermove", e=>this._OnPointerMove(e.data)),C3.Disposable.From(rt, "pointerdown", e=>this._OnPointerDown(e.data)),C3.Disposable.From(rt, "pointerup", e=>this._OnPointerUp(e.data)),C3.Disposable.From(rt, "dblclick", e=>this._OnDoubleClick(e.data)),C3.Disposable.From(rt, "wheel", e=>this._OnMouseWheel(e.data)),C3.Disposable.From(rt, "window-blur", ()=>this._OnWindowBlur()))
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
_OnPointerDown(e) {
|
|
if (e["pointerType"] !== "mouse")
|
|
return;
|
|
this._mouseXcanvas = e["pageX"] - this._runtime.GetCanvasClientX();
|
|
this._mouseYcanvas = e["pageY"] - this._runtime.GetCanvasClientY();
|
|
this._CheckButtonChanges(e["lastButtons"], e["buttons"])
|
|
}
|
|
_OnPointerMove(e) {
|
|
if (e["pointerType"] !== "mouse")
|
|
return;
|
|
this._mouseXcanvas = e["pageX"] - this._runtime.GetCanvasClientX();
|
|
this._mouseYcanvas = e["pageY"] - this._runtime.GetCanvasClientY();
|
|
this._CheckButtonChanges(e["lastButtons"], e["buttons"])
|
|
}
|
|
_OnPointerUp(e) {
|
|
if (e["pointerType"] !== "mouse")
|
|
return;
|
|
this._CheckButtonChanges(e["lastButtons"], e["buttons"])
|
|
}
|
|
_CheckButtonChanges(lastButtons, buttons) {
|
|
this._CheckButtonChange(lastButtons, buttons, 1, 0);
|
|
this._CheckButtonChange(lastButtons, buttons, 4, 1);
|
|
this._CheckButtonChange(lastButtons, buttons, 2, 2)
|
|
}
|
|
_CheckButtonChange(lastButtons, buttons, checkButtonFlag, resultButton) {
|
|
if (!(lastButtons & checkButtonFlag) && buttons & checkButtonFlag)
|
|
this._OnMouseDown(resultButton);
|
|
else if (lastButtons & checkButtonFlag && !(buttons & checkButtonFlag))
|
|
this._OnMouseUp(resultButton)
|
|
}
|
|
_OnMouseDown(button) {
|
|
this._buttonMap[button] = true;
|
|
this.Trigger(C3.Plugins.Mouse.Cnds.OnAnyClick);
|
|
this._triggerButton = button;
|
|
this._triggerType = 0;
|
|
this.Trigger(C3.Plugins.Mouse.Cnds.OnClick);
|
|
this.Trigger(C3.Plugins.Mouse.Cnds.OnObjectClicked)
|
|
}
|
|
_OnMouseUp(button) {
|
|
if (!this._buttonMap[button])
|
|
return;
|
|
this._buttonMap[button] = false;
|
|
this._triggerButton = button;
|
|
this.Trigger(C3.Plugins.Mouse.Cnds.OnRelease)
|
|
}
|
|
_OnDoubleClick(e) {
|
|
this._triggerButton = e["button"];
|
|
this._triggerType = 1;
|
|
this.Trigger(C3.Plugins.Mouse.Cnds.OnClick);
|
|
this.Trigger(C3.Plugins.Mouse.Cnds.OnObjectClicked)
|
|
}
|
|
_OnMouseWheel(e) {
|
|
this._triggerDir = e["deltaY"] < 0 ? 1 : 0;
|
|
this.Trigger(C3.Plugins.Mouse.Cnds.OnWheel)
|
|
}
|
|
_OnWindowBlur() {
|
|
for (let i = 0, len = this._buttonMap.length; i < len; ++i) {
|
|
if (!this._buttonMap[i])
|
|
return;
|
|
this._buttonMap[i] = false;
|
|
this._triggerButton = i;
|
|
this.Trigger(C3.Plugins.Mouse.Cnds.OnRelease)
|
|
}
|
|
}
|
|
GetMousePositionForLayer(layerNameOrNumber) {
|
|
const layout = this._runtime.GetMainRunningLayout();
|
|
const x = this._mouseXcanvas;
|
|
const y = this._mouseYcanvas;
|
|
if (typeof layerNameOrNumber === "undefined") {
|
|
const layer = layout.GetLayerByIndex(0);
|
|
return layer.CanvasCssToLayer_DefaultTransform(x, y)
|
|
} else {
|
|
const layer = layout.GetLayer(layerNameOrNumber);
|
|
if (layer)
|
|
return layer.CanvasCssToLayer(x, y);
|
|
else
|
|
return [0, 0]
|
|
}
|
|
}
|
|
IsMouseButtonDown(button) {
|
|
button = Math.floor(button);
|
|
return !!this._buttonMap[button]
|
|
}
|
|
_IsMouseOverCanvas() {
|
|
return this._mouseXcanvas >= 0 && this._mouseYcanvas >= 0 && this._mouseXcanvas < this._runtime.GetCanvasCssWidth() && this._mouseYcanvas < this._runtime.GetCanvasCssHeight()
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "plugins.mouse";
|
|
return [{
|
|
title: prefix + ".name",
|
|
properties: [{
|
|
name: prefix + ".debugger.absolute-position",
|
|
value: this._mouseXcanvas + "," + this._mouseYcanvas
|
|
}, {
|
|
name: prefix + ".debugger.left-button",
|
|
value: this._buttonMap[0]
|
|
}, {
|
|
name: prefix + ".debugger.middle-button",
|
|
value: this._buttonMap[1]
|
|
}, {
|
|
name: prefix + ".debugger.right-button",
|
|
value: this._buttonMap[2]
|
|
}]
|
|
}, {
|
|
title: prefix + ".debugger.position-on-each-layer",
|
|
properties: this._runtime.GetMainRunningLayout().GetLayers().map(layer=>({
|
|
name: "$" + layer.GetName(),
|
|
value: layer.CanvasCssToLayer(this._mouseXcanvas, this._mouseYcanvas).join(", ")
|
|
}))
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Mouse.Cnds = {
|
|
OnClick(button, type) {
|
|
return this._triggerButton === button && this._triggerType === type
|
|
},
|
|
OnAnyClick() {
|
|
return true
|
|
},
|
|
IsButtonDown(button) {
|
|
return this._buttonMap[button]
|
|
},
|
|
OnRelease(button) {
|
|
return this._triggerButton === button
|
|
},
|
|
IsOverObject(objectClass) {
|
|
if (!this._IsMouseOverCanvas())
|
|
return false;
|
|
const cnd = this._runtime.GetCurrentCondition();
|
|
const isInverted = cnd.IsInverted();
|
|
const mx = this._mouseXcanvas;
|
|
const my = this._mouseYcanvas;
|
|
return C3.xor(this._runtime.GetCollisionEngine().TestAndSelectCanvasPointOverlap(objectClass, mx, my, isInverted), isInverted)
|
|
},
|
|
OnObjectClicked(button, type, objectClass) {
|
|
if (button !== this._triggerButton || type !== this._triggerType)
|
|
return false;
|
|
if (!this._IsMouseOverCanvas())
|
|
return false;
|
|
const mx = this._mouseXcanvas;
|
|
const my = this._mouseYcanvas;
|
|
return this._runtime.GetCollisionEngine().TestAndSelectCanvasPointOverlap(objectClass, mx, my, false)
|
|
},
|
|
OnWheel(dir) {
|
|
return this._triggerDir === dir
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
let lastSetCursor = null;
|
|
const CURSOR_STYLES = ["auto", "pointer", "text", "crosshair", "move", "help", "wait", "none"];
|
|
C3.Plugins.Mouse.Acts = {
|
|
SetCursor(c) {
|
|
const cursorStyle = CURSOR_STYLES[c];
|
|
if (lastSetCursor === cursorStyle)
|
|
return;
|
|
lastSetCursor = cursorStyle;
|
|
this.PostToDOM("cursor", cursorStyle)
|
|
},
|
|
SetCursorSprite(objectClass) {
|
|
if (C3.Platform.IsMobile || !objectClass)
|
|
return;
|
|
const inst = objectClass.GetFirstPicked();
|
|
if (!inst)
|
|
return;
|
|
const wi = inst.GetWorldInfo();
|
|
const imageInfo = inst.GetCurrentImageInfo();
|
|
if (!wi || !imageInfo)
|
|
return;
|
|
if (lastSetCursor === imageInfo)
|
|
return;
|
|
lastSetCursor = imageInfo;
|
|
imageInfo.ExtractImageToCanvas().then(canvas=>C3.CanvasToBlob(canvas)).then(blob=>{
|
|
const url = URL.createObjectURL(blob);
|
|
const cursorStyle = `url(${url}) ${Math.round(wi.GetOriginX() * imageInfo.GetWidth())} ${Math.round(wi.GetOriginY() * imageInfo.GetHeight())}, auto`;
|
|
this.PostToDOM("cursor", "");
|
|
this.PostToDOM("cursor", cursorStyle)
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Mouse.Exps = {
|
|
X(layerParam) {
|
|
return this.GetMousePositionForLayer(layerParam)[0]
|
|
},
|
|
Y(layerParam) {
|
|
return this.GetMousePositionForLayer(layerParam)[1]
|
|
},
|
|
AbsoluteX() {
|
|
return this._mouseXcanvas
|
|
},
|
|
AbsoluteY() {
|
|
return this._mouseYcanvas
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Keyboard = class KeyboardPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Keyboard.Type = class KeyboardType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
GetScriptInterfaceClass() {
|
|
return self.IKeyboardObjectType
|
|
}
|
|
}
|
|
;
|
|
let keyboardObjectType = null;
|
|
function GetKeyboardSdkInstance() {
|
|
return keyboardObjectType.GetSingleGlobalInstance().GetSdkInstance()
|
|
}
|
|
self.IKeyboardObjectType = class IKeyboardObjectType extends self.IObjectClass {
|
|
constructor(objectType) {
|
|
super(objectType);
|
|
keyboardObjectType = objectType;
|
|
objectType.GetRuntime()._GetCommonScriptInterfaces().keyboard = this
|
|
}
|
|
isKeyDown(keyOrCode) {
|
|
const keyboardInst = GetKeyboardSdkInstance();
|
|
if (typeof keyOrCode === "string")
|
|
return keyboardInst.IsKeyDown(keyOrCode);
|
|
else if (typeof keyOrCode === "number")
|
|
return keyboardInst.IsKeyCodeDown(keyOrCode);
|
|
else
|
|
throw new TypeError("expected string or number");
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Keyboard.Instance = class KeyboardInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this._keysDownByString = new Set;
|
|
this._keysDownByWhich = new Set;
|
|
this._triggerWhich = 0;
|
|
this._triggerString = "";
|
|
this._triggerTypedKey = "";
|
|
const rt = this.GetRuntime().Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(rt, "keydown", e=>this._OnKeyDown(e.data)),C3.Disposable.From(rt, "keyup", e=>this._OnKeyUp(e.data)),C3.Disposable.From(rt, "window-blur", ()=>this._OnWindowBlur()))
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
_OnKeyDown(e) {
|
|
const which = e["which"];
|
|
const keyString = e["code"] || which.toString();
|
|
const typedKey = e["key"];
|
|
if (this._keysDownByString.has(keyString))
|
|
return;
|
|
this._keysDownByString.add(keyString);
|
|
this._keysDownByWhich.add(which);
|
|
this._triggerString = keyString;
|
|
this._triggerWhich = which;
|
|
this._triggerTypedKey = typedKey;
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnAnyKey);
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnKey);
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnLeftRightKeyPressed);
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnKeyCode)
|
|
}
|
|
_OnKeyUp(e) {
|
|
const which = e["which"];
|
|
const keyString = e["code"] || which.toString();
|
|
const typedKey = e["key"];
|
|
this._keysDownByString.delete(keyString);
|
|
this._keysDownByWhich.delete(which);
|
|
this._triggerString = keyString;
|
|
this._triggerWhich = which;
|
|
this._triggerTypedKey = typedKey;
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnAnyKeyReleased);
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnKeyReleased);
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnLeftRightKeyReleased);
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnKeyCodeReleased)
|
|
}
|
|
_OnWindowBlur() {
|
|
for (const which of this._keysDownByWhich) {
|
|
this._keysDownByWhich.delete(which);
|
|
this._triggerWhich = which;
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnAnyKeyReleased);
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnKeyReleased);
|
|
this.Trigger(C3.Plugins.Keyboard.Cnds.OnKeyCodeReleased)
|
|
}
|
|
this._keysDownByString.clear()
|
|
}
|
|
IsKeyDown(str) {
|
|
return this._keysDownByString.has(str)
|
|
}
|
|
IsKeyCodeDown(which) {
|
|
return this._keysDownByWhich.has(which)
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"tk": this._triggerWhich,
|
|
"tkk": this._triggerTypedKey
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this._triggerWhich = o["tk"];
|
|
if (o.hasOwnProperty("tkk"))
|
|
this._triggerTypedKey = o["tkk"]
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "plugins.keyboard";
|
|
return [{
|
|
title: prefix + ".name",
|
|
properties: [{
|
|
name: prefix + ".debugger.last-key-code",
|
|
value: this._triggerWhich
|
|
}, {
|
|
name: prefix + ".debugger.last-key-string",
|
|
value: C3.Plugins.Keyboard.Exps.StringFromKeyCode(this._triggerWhich)
|
|
}, {
|
|
name: prefix + ".debugger.last-typed-key",
|
|
value: this._triggerTypedKey
|
|
}]
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const LEFTRIGHT_KEY_STRINGS = ["ShiftLeft", "ShiftRight", "ControlLeft", "ControlRight", "AltLeft", "AltRight", "MetaLeft", "MetaRight"];
|
|
C3.Plugins.Keyboard.Cnds = {
|
|
IsKeyDown(which) {
|
|
return this._keysDownByWhich.has(which)
|
|
},
|
|
OnKey(which) {
|
|
return this._triggerWhich === which
|
|
},
|
|
OnAnyKey() {
|
|
return true
|
|
},
|
|
OnAnyKeyReleased() {
|
|
return true
|
|
},
|
|
OnKeyReleased(which) {
|
|
return this._triggerWhich === which
|
|
},
|
|
IsKeyCodeDown(which) {
|
|
which = Math.floor(which);
|
|
return this._keysDownByWhich.has(which)
|
|
},
|
|
OnKeyCode(which) {
|
|
return this._triggerWhich === which
|
|
},
|
|
OnKeyCodeReleased(which) {
|
|
return this._triggerWhich === which
|
|
},
|
|
OnLeftRightKeyPressed(index) {
|
|
const keyString = LEFTRIGHT_KEY_STRINGS[index];
|
|
return this._triggerString === keyString
|
|
},
|
|
OnLeftRightKeyReleased(index) {
|
|
const keyString = LEFTRIGHT_KEY_STRINGS[index];
|
|
return this._triggerString === keyString
|
|
},
|
|
IsLeftRightKeyDown(index) {
|
|
const keyString = LEFTRIGHT_KEY_STRINGS[index];
|
|
return this._keysDownByString.has(keyString)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Keyboard.Acts = {}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function StringFromCharCode(kc) {
|
|
kc = Math.floor(kc);
|
|
switch (kc) {
|
|
case 8:
|
|
return "backspace";
|
|
case 9:
|
|
return "tab";
|
|
case 13:
|
|
return "enter";
|
|
case 16:
|
|
return "shift";
|
|
case 17:
|
|
return "control";
|
|
case 18:
|
|
return "alt";
|
|
case 19:
|
|
return "pause";
|
|
case 20:
|
|
return "capslock";
|
|
case 27:
|
|
return "esc";
|
|
case 33:
|
|
return "pageup";
|
|
case 34:
|
|
return "pagedown";
|
|
case 35:
|
|
return "end";
|
|
case 36:
|
|
return "home";
|
|
case 37:
|
|
return "\u2190";
|
|
case 38:
|
|
return "\u2191";
|
|
case 39:
|
|
return "\u2192";
|
|
case 40:
|
|
return "\u2193";
|
|
case 45:
|
|
return "insert";
|
|
case 46:
|
|
return "del";
|
|
case 91:
|
|
return "left window key";
|
|
case 92:
|
|
return "right window key";
|
|
case 93:
|
|
return "select";
|
|
case 96:
|
|
return "numpad 0";
|
|
case 97:
|
|
return "numpad 1";
|
|
case 98:
|
|
return "numpad 2";
|
|
case 99:
|
|
return "numpad 3";
|
|
case 100:
|
|
return "numpad 4";
|
|
case 101:
|
|
return "numpad 5";
|
|
case 102:
|
|
return "numpad 6";
|
|
case 103:
|
|
return "numpad 7";
|
|
case 104:
|
|
return "numpad 8";
|
|
case 105:
|
|
return "numpad 9";
|
|
case 106:
|
|
return "numpad *";
|
|
case 107:
|
|
return "numpad +";
|
|
case 109:
|
|
return "numpad -";
|
|
case 110:
|
|
return "numpad .";
|
|
case 111:
|
|
return "numpad /";
|
|
case 112:
|
|
return "F1";
|
|
case 113:
|
|
return "F2";
|
|
case 114:
|
|
return "F3";
|
|
case 115:
|
|
return "F4";
|
|
case 116:
|
|
return "F5";
|
|
case 117:
|
|
return "F6";
|
|
case 118:
|
|
return "F7";
|
|
case 119:
|
|
return "F8";
|
|
case 120:
|
|
return "F9";
|
|
case 121:
|
|
return "F10";
|
|
case 122:
|
|
return "F11";
|
|
case 123:
|
|
return "F12";
|
|
case 144:
|
|
return "numlock";
|
|
case 145:
|
|
return "scroll lock";
|
|
case 186:
|
|
return ";";
|
|
case 187:
|
|
return "=";
|
|
case 188:
|
|
return ",";
|
|
case 189:
|
|
return "-";
|
|
case 190:
|
|
return ".";
|
|
case 191:
|
|
return "/";
|
|
case 192:
|
|
return "'";
|
|
case 219:
|
|
return "[";
|
|
case 220:
|
|
return "\\";
|
|
case 221:
|
|
return "]";
|
|
case 222:
|
|
return "#";
|
|
case 223:
|
|
return "`";
|
|
default:
|
|
return String.fromCharCode(kc)
|
|
}
|
|
}
|
|
C3.Plugins.Keyboard.Exps = {
|
|
LastKeyCode() {
|
|
return this._triggerWhich
|
|
},
|
|
StringFromKeyCode(kc) {
|
|
return StringFromCharCode(kc)
|
|
},
|
|
TypedKey() {
|
|
return this._triggerTypedKey
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Browser = class BrowserPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Browser.Type = class BrowserType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const DOM_COMPONENT_ID = "browser";
|
|
C3.Plugins.Browser.Instance = class BrowserInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst, DOM_COMPONENT_ID);
|
|
this._initLocationStr = "";
|
|
this._isOnline = false;
|
|
this._referrer = "";
|
|
this._docTitle = "";
|
|
this._isCookieEnabled = false;
|
|
this._screenWidth = 0;
|
|
this._screenHeight = 0;
|
|
this._windowOuterWidth = 0;
|
|
this._windowOuterHeight = 0;
|
|
this._isScirraArcade = false;
|
|
this.AddDOMMessageHandlers([["online-state", e=>this._OnOnlineStateChanged(e)], ["backbutton", ()=>this._OnBackButton()], ["sw-message", e=>this._OnSWMessage(e)], ["hashchange", e=>this._OnHashChange(e)]]);
|
|
const rt = this.GetRuntime().Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(rt, "afterfirstlayoutstart", ()=>this._OnAfterFirstLayoutStart()),C3.Disposable.From(rt, "window-resize", ()=>this._OnWindowResize()),C3.Disposable.From(rt, "suspend", ()=>this._OnSuspend()),C3.Disposable.From(rt, "resume", ()=>this._OnResume()));
|
|
this._runtime.AddLoadPromise(this.PostToDOMAsync("get-initial-state", {
|
|
"exportType": this._runtime.GetExportType()
|
|
}).then(data=>{
|
|
this._initLocationStr = data["location"];
|
|
this._isOnline = data["isOnline"];
|
|
this._referrer = data["referrer"];
|
|
this._docTitle = data["title"];
|
|
this._isCookieEnabled = data["isCookieEnabled"];
|
|
this._screenWidth = data["screenWidth"];
|
|
this._screenHeight = data["screenHeight"];
|
|
this._windowOuterWidth = data["windowOuterWidth"];
|
|
this._windowOuterHeight = data["windowOuterHeight"];
|
|
this._isScirraArcade = data["isScirraArcade"]
|
|
}
|
|
))
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
_OnAfterFirstLayoutStart() {
|
|
this.PostToDOM("ready-for-sw-messages")
|
|
}
|
|
async _OnOnlineStateChanged(e) {
|
|
const isOnline = !!e["isOnline"];
|
|
if (this._isOnline === isOnline)
|
|
return;
|
|
this._isOnline = isOnline;
|
|
if (this._isOnline)
|
|
await this.TriggerAsync(C3.Plugins.Browser.Cnds.OnOnline);
|
|
else
|
|
await this.TriggerAsync(C3.Plugins.Browser.Cnds.OnOffline)
|
|
}
|
|
async _OnWindowResize() {
|
|
await this.TriggerAsync(C3.Plugins.Browser.Cnds.OnResize)
|
|
}
|
|
_OnSuspend() {
|
|
this.Trigger(C3.Plugins.Browser.Cnds.OnPageHidden)
|
|
}
|
|
_OnResume() {
|
|
this.Trigger(C3.Plugins.Browser.Cnds.OnPageVisible)
|
|
}
|
|
async _OnBackButton() {
|
|
await this.TriggerAsync(C3.Plugins.Browser.Cnds.OnBackButton)
|
|
}
|
|
_OnSWMessage(e) {
|
|
const messageType = e["type"];
|
|
if (messageType === "downloading-update")
|
|
this.Trigger(C3.Plugins.Browser.Cnds.OnUpdateFound);
|
|
else if (messageType === "update-ready" || messageType === "update-pending")
|
|
this.Trigger(C3.Plugins.Browser.Cnds.OnUpdateReady);
|
|
else if (messageType === "offline-ready")
|
|
this.Trigger(C3.Plugins.Browser.Cnds.OnOfflineReady)
|
|
}
|
|
_OnHashChange(e) {
|
|
this._initLocationStr = e["location"];
|
|
this.Trigger(C3.Plugins.Browser.Cnds.OnHashChange)
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "plugins.browser.debugger";
|
|
return [{
|
|
title: "plugins.browser.name",
|
|
properties: [{
|
|
name: prefix + ".user-agent",
|
|
value: navigator.userAgent
|
|
}, {
|
|
name: prefix + ".is-online",
|
|
value: this._isOnline
|
|
}, {
|
|
name: prefix + ".is-fullscreen",
|
|
value: this._runtime.GetCanvasManager().IsDocumentFullscreen()
|
|
}]
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Browser.Cnds = {
|
|
IsOnline() {
|
|
return this._isOnline
|
|
},
|
|
OnOnline() {
|
|
return true
|
|
},
|
|
OnOffline() {
|
|
return true
|
|
},
|
|
OnResize() {
|
|
return true
|
|
},
|
|
CookiesEnabled() {
|
|
return this._isCookieEnabled
|
|
},
|
|
IsFullscreen() {
|
|
return this._runtime.GetCanvasManager().IsDocumentFullscreen()
|
|
},
|
|
OnBackButton() {
|
|
return true
|
|
},
|
|
IsPortraitLandscape(p) {
|
|
const lastInnerWidth = this._runtime.GetCanvasManager().GetLastWidth();
|
|
const lastInnerHeight = this._runtime.GetCanvasManager().GetLastHeight();
|
|
const current = lastInnerWidth <= lastInnerHeight ? 0 : 1;
|
|
return current === p
|
|
},
|
|
OnUpdateFound() {
|
|
return true
|
|
},
|
|
OnUpdateReady() {
|
|
return true
|
|
},
|
|
OnOfflineReady() {
|
|
return true
|
|
},
|
|
OnHashChange() {
|
|
return true
|
|
},
|
|
PageVisible() {
|
|
return !this._runtime.IsSuspended()
|
|
},
|
|
OnPageHidden() {
|
|
return true
|
|
},
|
|
OnPageVisible() {
|
|
return true
|
|
},
|
|
HasJava() {
|
|
return false
|
|
},
|
|
IsDownloadingUpdate() {
|
|
return false
|
|
},
|
|
OnMenuButton() {
|
|
return false
|
|
},
|
|
OnSearchButton() {
|
|
return false
|
|
},
|
|
IsMetered() {
|
|
return false
|
|
},
|
|
IsCharging() {
|
|
return true
|
|
},
|
|
SupportsFullscreen() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const ORIENTATIONS = ["portrait", "landscape", "portrait-primary", "portrait-secondary", "landscape-primary", "landscape-secondary"];
|
|
C3.Plugins.Browser.Acts = {
|
|
Alert(message) {
|
|
this.PostToDOM("alert", {
|
|
"message": message.toString()
|
|
})
|
|
},
|
|
Close() {
|
|
if (this._isScirraArcade)
|
|
return;
|
|
if (this._runtime.IsDebug())
|
|
self.C3Debugger.CloseWindow();
|
|
else
|
|
this.PostToDOM("close")
|
|
},
|
|
Focus() {
|
|
this.PostToDOM("set-focus", {
|
|
"isFocus": true
|
|
})
|
|
},
|
|
Blur() {
|
|
this.PostToDOM("set-focus", {
|
|
"isFocus": false
|
|
})
|
|
},
|
|
GoBack() {
|
|
if (this._isScirraArcade)
|
|
return;
|
|
this.PostToDOM("navigate", {
|
|
"type": "back"
|
|
})
|
|
},
|
|
GoForward() {
|
|
if (this._isScirraArcade)
|
|
return;
|
|
this.PostToDOM("navigate", {
|
|
"type": "forward"
|
|
})
|
|
},
|
|
GoHome() {
|
|
if (this._isScirraArcade)
|
|
return;
|
|
this.PostToDOM("navigate", {
|
|
"type": "home"
|
|
})
|
|
},
|
|
Reload() {
|
|
if (this._isScirraArcade)
|
|
return;
|
|
if (this._runtime.IsDebug())
|
|
this._runtime.PostToDebugger({
|
|
"type": "reload"
|
|
});
|
|
else
|
|
this.PostToDOM("navigate", {
|
|
"type": "reload"
|
|
})
|
|
},
|
|
GoToURL(url, target) {
|
|
this._PostToDOMMaybeSync("navigate", {
|
|
"type": "url",
|
|
"url": "?"+url,
|
|
"target": target,
|
|
"exportType": this._runtime.GetExportType()
|
|
})
|
|
},
|
|
GoToURLWindow(url, tag) {
|
|
this._PostToDOMMaybeSync("navigate", {
|
|
"type": "new-window",
|
|
"url": url,
|
|
"tag": tag,
|
|
"exportType": this._runtime.GetExportType()
|
|
})
|
|
},
|
|
RequestFullScreen(mode, navUi) {
|
|
if (mode >= 2)
|
|
mode += 1;
|
|
if (mode === 6)
|
|
mode = 2;
|
|
if (mode === 1)
|
|
mode = 0;
|
|
const modeStr = C3.CanvasManager._FullscreenModeNumberToString(mode);
|
|
this._runtime.GetCanvasManager().SetDocumentFullscreenMode(modeStr);
|
|
this._PostToDOMMaybeSync("request-fullscreen", {
|
|
"navUI": navUi
|
|
})
|
|
},
|
|
CancelFullScreen() {
|
|
this._PostToDOMMaybeSync("exit-fullscreen")
|
|
},
|
|
Vibrate(pattern) {
|
|
const arr = pattern.split(",");
|
|
for (let i = 0, len = arr.length; i < len; ++i)
|
|
arr[i] = parseInt(arr[i], 10);
|
|
this._PostToDOMMaybeSync("vibrate", {
|
|
"pattern": arr
|
|
})
|
|
},
|
|
async InvokeDownload(url, filename) {
|
|
if (!filename)
|
|
return;
|
|
const urlToDownload = await this._runtime.GetAssetManager().GetProjectFileUrl(url);
|
|
this._runtime.InvokeDownload(urlToDownload, filename)
|
|
},
|
|
InvokeDownloadString(str, mimeType, filename) {
|
|
if (!filename)
|
|
return;
|
|
const dataUri = `data:${mimeType},${encodeURIComponent(str)}`;
|
|
this._runtime.InvokeDownload(dataUri, filename)
|
|
},
|
|
ConsoleLog(type, msg) {
|
|
msg = msg.toString();
|
|
if (type === 0)
|
|
console.log(msg);
|
|
else if (type === 1)
|
|
console.warn(msg);
|
|
else if (type === 2)
|
|
console.error(msg)
|
|
},
|
|
ConsoleGroup(name) {
|
|
console.group(name)
|
|
},
|
|
ConsoleGroupEnd() {
|
|
console.groupEnd()
|
|
},
|
|
ExecJs(jsStr) {
|
|
try {
|
|
console.log("--fx--eval--", jsStr);
|
|
// eval(jsStr)
|
|
} catch (err) {
|
|
console.error("Error executing JavaScript: ", err)
|
|
}
|
|
},
|
|
LockOrientation(o) {
|
|
o = Math.floor(o);
|
|
if (o < 0 || o >= ORIENTATIONS.length)
|
|
return;
|
|
const orientation = ORIENTATIONS[o];
|
|
this._PostToDOMMaybeSync("lock-orientation", {
|
|
"orientation": orientation
|
|
})
|
|
},
|
|
UnlockOrientation() {
|
|
this._PostToDOMMaybeSync("unlock-orientation")
|
|
},
|
|
LoadStyleSheet(url) {
|
|
this._runtime.GetAssetManager().LoadStyleSheet(url)
|
|
},
|
|
SetHash(h) {
|
|
this.PostToDOM("set-hash", {
|
|
"hash": h
|
|
})
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Browser.Exps = {
|
|
URL() {
|
|
if (this._runtime.IsInWorker())
|
|
return this._initLocationStr;
|
|
else
|
|
return location.toString()
|
|
},
|
|
Protocol() {
|
|
if (this._runtime.IsInWorker())
|
|
return (new URL(this._initLocationStr)).protocol;
|
|
else
|
|
return location.protocol
|
|
},
|
|
Domain() {
|
|
return "games-online.io";
|
|
console.log("--fx--host--", location.hostname);
|
|
console.log("--fx--host--", (new URL(this._initLocationStr)).hostname);
|
|
if (this._runtime.IsInWorker())
|
|
return (new URL(this._initLocationStr)).hostname;
|
|
else
|
|
return location.hostname
|
|
},
|
|
Port() {
|
|
if (this._runtime.IsInWorker())
|
|
return (new URL(this._initLocationStr)).port;
|
|
else
|
|
return location.port
|
|
},
|
|
PathName() {
|
|
if (this._runtime.IsInWorker())
|
|
return (new URL(this._initLocationStr)).pathname;
|
|
else
|
|
return location.pathname
|
|
},
|
|
Hash() {
|
|
if (this._runtime.IsInWorker())
|
|
return (new URL(this._initLocationStr)).hash;
|
|
else
|
|
return location.hash
|
|
},
|
|
QueryString() {
|
|
if (this._runtime.IsInWorker())
|
|
return (new URL(this._initLocationStr)).search;
|
|
else
|
|
return location.search
|
|
},
|
|
QueryParam(param) {
|
|
const search = this._runtime.IsInWorker() ? (new URL(this._initLocationStr)).search : location.search;
|
|
const match = RegExp("[?&]" + param + "=([^&]*)").exec(search);
|
|
if (match)
|
|
return decodeURIComponent(match[1].replace(/\+/g, " "));
|
|
else
|
|
return ""
|
|
},
|
|
Referrer() {
|
|
return this._referrer
|
|
},
|
|
Title() {
|
|
return this._docTitle
|
|
},
|
|
Language() {
|
|
return navigator.language
|
|
},
|
|
Platform() {
|
|
return navigator.platform
|
|
},
|
|
UserAgent() {
|
|
return navigator.userAgent
|
|
},
|
|
ExecJS(jsStr) {
|
|
let result = 0;
|
|
try {
|
|
result = eval(jsStr)
|
|
} catch (err) {
|
|
console.error("Error executing JavaScript: ", err)
|
|
}
|
|
if (typeof result === "number" || typeof result === "string")
|
|
return result;
|
|
if (typeof result === "boolean")
|
|
return result ? 1 : 0;
|
|
else
|
|
return 0
|
|
},
|
|
Name() {
|
|
return navigator.appName
|
|
},
|
|
Version() {
|
|
return navigator.appVersion
|
|
},
|
|
Product() {
|
|
return navigator.product
|
|
},
|
|
Vendor() {
|
|
return navigator.vendor
|
|
},
|
|
BatteryLevel() {
|
|
return 1
|
|
},
|
|
BatteryTimeLeft() {
|
|
return Infinity
|
|
},
|
|
Bandwidth() {
|
|
const connection = navigator["connection"];
|
|
if (connection)
|
|
return connection["downlink"] || connection["downlinkMax"] || connection["bandwidth"] || Infinity;
|
|
else
|
|
return Infinity
|
|
},
|
|
ConnectionType() {
|
|
const connection = navigator["connection"];
|
|
if (connection)
|
|
return connection["type"] || "unknown";
|
|
else
|
|
return "unknown"
|
|
},
|
|
DevicePixelRatio() {
|
|
return self.devicePixelRatio
|
|
},
|
|
ScreenWidth() {
|
|
return this._screenWidth
|
|
},
|
|
ScreenHeight() {
|
|
return this._screenHeight
|
|
},
|
|
WindowInnerWidth() {
|
|
return this._runtime.GetCanvasManager().GetLastWidth()
|
|
},
|
|
WindowInnerHeight() {
|
|
return this._runtime.GetCanvasManager().GetLastHeight()
|
|
},
|
|
WindowOuterWidth() {
|
|
return this._windowOuterWidth
|
|
},
|
|
WindowOuterHeight() {
|
|
return this._windowOuterWidth
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.TiledBg = class TiledBgPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function WrapModeToStr(wrapMode) {
|
|
switch (wrapMode) {
|
|
case 0:
|
|
return "clamp-to-edge";
|
|
case 1:
|
|
return "repeat";
|
|
case 2:
|
|
return "mirror-repeat"
|
|
}
|
|
return "repeat"
|
|
}
|
|
C3.Plugins.TiledBg.Type = class TiledBgType extends C3.SDKTypeBase {
|
|
constructor(objectClass, exportData) {
|
|
super(objectClass);
|
|
this._wrapX = "repeat";
|
|
this._wrapY = "repeat";
|
|
if (exportData) {
|
|
this._wrapX = WrapModeToStr(exportData[0]);
|
|
this._wrapY = WrapModeToStr(exportData[1])
|
|
}
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {
|
|
this.GetImageInfo().LoadAsset(this._runtime)
|
|
}
|
|
LoadTextures(renderer) {
|
|
return this.GetImageInfo().LoadStaticTexture(renderer, {
|
|
sampling: this._runtime.GetSampling(),
|
|
wrapX: this._wrapX,
|
|
wrapY: this._wrapY
|
|
})
|
|
}
|
|
ReleaseTextures() {
|
|
this.GetImageInfo().ReleaseTexture()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const INITIALLY_VISIBLE = 0;
|
|
const ORIGIN = 1;
|
|
const IMAGE_OFFSET_X = 4;
|
|
const IMAGE_OFFSET_Y = 5;
|
|
const IMAGE_SCALE_X = 6;
|
|
const IMAGE_SCALE_Y = 7;
|
|
const IMAGE_ANGLE = 8;
|
|
const tempRect = C3.New(C3.Rect);
|
|
const tempQuad = C3.New(C3.Quad);
|
|
const rcTex = C3.New(C3.Rect);
|
|
const qTex = C3.New(C3.Quad);
|
|
C3.Plugins.TiledBg.Instance = class TiledBgInstance extends C3.SDKWorldInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this._imageOffsetX = 0;
|
|
this._imageOffsetY = 0;
|
|
this._imageScaleX = 1;
|
|
this._imageScaleY = 1;
|
|
this._imageAngle = 0;
|
|
this._ownImageInfo = null;
|
|
if (properties) {
|
|
this.GetWorldInfo().SetVisible(!!properties[INITIALLY_VISIBLE]);
|
|
this._imageOffsetX = properties[IMAGE_OFFSET_X];
|
|
this._imageOffsetY = properties[IMAGE_OFFSET_Y];
|
|
this._imageScaleX = properties[IMAGE_SCALE_X];
|
|
this._imageScaleY = properties[IMAGE_SCALE_Y];
|
|
this._imageAngle = C3.toRadians(properties[IMAGE_ANGLE])
|
|
}
|
|
}
|
|
Release() {
|
|
this._ReleaseOwnImage();
|
|
super.Release()
|
|
}
|
|
_ReleaseOwnImage() {
|
|
if (this._ownImageInfo) {
|
|
this._ownImageInfo.Release();
|
|
this._ownImageInfo = null
|
|
}
|
|
}
|
|
Draw(renderer) {
|
|
const imageInfo = this.GetCurrentImageInfo();
|
|
const texture = imageInfo.GetTexture();
|
|
if (texture === null)
|
|
return;
|
|
renderer.SetTexture(texture);
|
|
const imageWidth = imageInfo.GetWidth();
|
|
const imageHeight = imageInfo.GetHeight();
|
|
const imageOffsetX = this._imageOffsetX / imageWidth;
|
|
const imageOffsetY = this._imageOffsetY / imageHeight;
|
|
const wi = this.GetWorldInfo();
|
|
rcTex.set(0, 0, wi.GetWidth() / (imageWidth * this._imageScaleX), wi.GetHeight() / (imageHeight * this._imageScaleY));
|
|
rcTex.offset(-imageOffsetX, -imageOffsetY);
|
|
if (wi.HasMesh())
|
|
this._DrawMesh(wi, renderer);
|
|
else
|
|
this._DrawStandard(wi, renderer)
|
|
}
|
|
_DrawStandard(wi, renderer) {
|
|
let quad = wi.GetBoundingQuad();
|
|
if (this._runtime.IsPixelRoundingEnabled())
|
|
quad = wi.PixelRoundQuad(quad);
|
|
if (this._imageAngle === 0)
|
|
renderer.Quad3(quad, rcTex);
|
|
else {
|
|
qTex.setFromRotatedRect(rcTex, -this._imageAngle);
|
|
renderer.Quad4(quad, qTex)
|
|
}
|
|
}
|
|
_DrawMesh(wi, renderer) {
|
|
const transformedMesh = wi.GetTransformedMesh();
|
|
if (wi.IsMeshChanged()) {
|
|
wi.CalculateBbox(tempRect, tempQuad, false);
|
|
let quad = tempQuad;
|
|
if (this._runtime.IsPixelRoundingEnabled())
|
|
quad = wi.PixelRoundQuad(quad);
|
|
let texCoords = rcTex;
|
|
if (this._imageAngle !== 0) {
|
|
qTex.setFromRotatedRect(rcTex, -this._imageAngle);
|
|
texCoords = qTex
|
|
}
|
|
transformedMesh.CalculateTransformedMesh(wi.GetSourceMesh(), quad, texCoords);
|
|
wi.SetMeshChanged(false)
|
|
}
|
|
transformedMesh.Draw(renderer)
|
|
}
|
|
GetCurrentImageInfo() {
|
|
return this._ownImageInfo || this._objectClass.GetImageInfo()
|
|
}
|
|
_SetMeshChanged() {
|
|
this.GetWorldInfo().SetMeshChanged(true)
|
|
}
|
|
_SetImageOffsetX(x) {
|
|
if (this._imageOffsetX === x)
|
|
return;
|
|
this._imageOffsetX = x;
|
|
this._runtime.UpdateRender();
|
|
this._SetMeshChanged()
|
|
}
|
|
_GetImageOffsetX() {
|
|
return this._imageOffsetX
|
|
}
|
|
_SetImageOffsetY(y) {
|
|
if (this._imageOffsetY === y)
|
|
return;
|
|
this._imageOffsetY = y;
|
|
this._runtime.UpdateRender();
|
|
this._SetMeshChanged()
|
|
}
|
|
_GetImageOffsetY() {
|
|
return this._imageOffsetY
|
|
}
|
|
_SetImageScaleX(x) {
|
|
if (this._imageScaleX === x)
|
|
return;
|
|
this._imageScaleX = x;
|
|
this._runtime.UpdateRender();
|
|
this._SetMeshChanged()
|
|
}
|
|
_GetImageScaleX() {
|
|
return this._imageScaleX
|
|
}
|
|
_SetImageScaleY(y) {
|
|
if (this._imageScaleY === y)
|
|
return;
|
|
this._imageScaleY = y;
|
|
this._runtime.UpdateRender();
|
|
this._SetMeshChanged()
|
|
}
|
|
_GetImageScaleY() {
|
|
return this._imageScaleY
|
|
}
|
|
_SetImageAngle(a) {
|
|
if (this._imageAngle === a)
|
|
return;
|
|
this._imageAngle = a;
|
|
this._runtime.UpdateRender();
|
|
this._SetMeshChanged()
|
|
}
|
|
_GetImageAngle() {
|
|
return this._imageAngle
|
|
}
|
|
GetPropertyValueByIndex(index) {
|
|
switch (index) {
|
|
case IMAGE_OFFSET_X:
|
|
return this._GetImageOffsetX();
|
|
case IMAGE_OFFSET_Y:
|
|
return this._GetImageOffsetY();
|
|
case IMAGE_SCALE_X:
|
|
return this._GetImageScaleX();
|
|
case IMAGE_SCALE_Y:
|
|
return this._GetImageScaleY();
|
|
case IMAGE_ANGLE:
|
|
return this._GetImageAngle()
|
|
}
|
|
}
|
|
SetPropertyValueByIndex(index, value) {
|
|
switch (index) {
|
|
case IMAGE_OFFSET_X:
|
|
this._SetImageOffsetX(value);
|
|
break;
|
|
case IMAGE_OFFSET_Y:
|
|
this._SetImageOffsetY(value);
|
|
break;
|
|
case IMAGE_SCALE_X:
|
|
this._SetImageScaleX(value);
|
|
break;
|
|
case IMAGE_SCALE_Y:
|
|
this._SetImageScaleY(value);
|
|
break;
|
|
case IMAGE_ANGLE:
|
|
this._SetImageAngle(value);
|
|
break
|
|
}
|
|
}
|
|
GetScriptInterfaceClass() {
|
|
return self.ITiledBackgroundInstance
|
|
}
|
|
}
|
|
;
|
|
const map = new WeakMap;
|
|
self.ITiledBackgroundInstance = class ITiledBackgroundInstance extends self.IWorldInstance {
|
|
constructor() {
|
|
super();
|
|
map.set(this, self.IInstance._GetInitInst().GetSdkInstance())
|
|
}
|
|
set imageOffsetX(x) {
|
|
map.get(this)._SetImageOffsetX(x)
|
|
}
|
|
get imageOffsetX() {
|
|
return map.get(this)._GetImageOffsetX()
|
|
}
|
|
set imageOffsetY(y) {
|
|
map.get(this)._SetImageOffsetY(y)
|
|
}
|
|
get imageOffsetY() {
|
|
return map.get(this)._GetImageOffsetY()
|
|
}
|
|
set imageScaleX(x) {
|
|
map.get(this)._SetImageScaleX(x)
|
|
}
|
|
get imageScaleX() {
|
|
return map.get(this)._GetImageScaleX()
|
|
}
|
|
set imageScaleY(y) {
|
|
map.get(this)._SetImageScaleY(y)
|
|
}
|
|
get imageScaleY() {
|
|
return map.get(this)._GetImageScaleY()
|
|
}
|
|
set imageAngle(a) {
|
|
map.get(this)._SetImageAngle(a)
|
|
}
|
|
get imageAngle() {
|
|
return map.get(this)._GetImageAngle()
|
|
}
|
|
set imageAngleDegrees(a) {
|
|
map.get(this)._SetImageAngle(C3.toRadians(a))
|
|
}
|
|
get imageAngleDegrees() {
|
|
return C3.toDegrees(map.get(this)._GetImageAngle())
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.TiledBg.Cnds = {
|
|
OnURLLoaded() {
|
|
return true
|
|
},
|
|
OnURLFailed() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.TiledBg.Acts = {
|
|
SetImageOffsetX(x) {
|
|
this._SetImageOffsetX(x)
|
|
},
|
|
SetImageOffsetY(y) {
|
|
this._SetImageOffsetY(y)
|
|
},
|
|
SetImageScaleX(x) {
|
|
this._SetImageScaleX(x / 100)
|
|
},
|
|
SetImageScaleY(y) {
|
|
this._SetImageScaleY(y / 100)
|
|
},
|
|
SetImageAngle(a) {
|
|
this._SetImageAngle(C3.toRadians(a))
|
|
},
|
|
SetEffect(effect) {
|
|
this.GetWorldInfo().SetBlendMode(effect);
|
|
this._runtime.UpdateRender()
|
|
},
|
|
async LoadURL(url, crossOrigin) {
|
|
if (this._ownImageInfo && this._ownImageInfo.GetURL() === url)
|
|
return;
|
|
const runtime = this._runtime;
|
|
const imageInfo = C3.New(C3.ImageInfo);
|
|
await imageInfo.LoadDynamicAsset(runtime, url);
|
|
if (!imageInfo.IsLoaded()) {
|
|
this.Trigger(C3.Plugins.TiledBg.Cnds.OnURLFailed);
|
|
return
|
|
}
|
|
if (this.WasReleased()) {
|
|
imageInfo.Release();
|
|
return null
|
|
}
|
|
const texture = await imageInfo.LoadStaticTexture(runtime.GetWebGLRenderer(), {
|
|
sampling: this._runtime.GetSampling(),
|
|
wrapX: "repeat",
|
|
wrapY: "repeat"
|
|
});
|
|
if (!texture)
|
|
return;
|
|
if (this.WasReleased()) {
|
|
imageInfo.Release();
|
|
return
|
|
}
|
|
this._ReleaseOwnImage();
|
|
this._ownImageInfo = imageInfo;
|
|
runtime.UpdateRender();
|
|
await this.TriggerAsync(C3.Plugins.TiledBg.Cnds.OnURLLoaded)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.TiledBg.Exps = {
|
|
ImageWidth() {
|
|
return this.GetCurrentImageInfo().GetWidth()
|
|
},
|
|
ImageHeight() {
|
|
return this.GetCurrentImageInfo().GetHeight()
|
|
},
|
|
ImageOffsetX() {
|
|
return this._imageOffsetX
|
|
},
|
|
ImageOffsetY() {
|
|
return this._imageOffsetY
|
|
},
|
|
ImageScaleX() {
|
|
return this._imageScaleX * 100
|
|
},
|
|
ImageScaleY() {
|
|
return this._imageScaleY * 100
|
|
},
|
|
ImageAngle() {
|
|
return C3.toDegrees(this._imageAngle)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.DrawingCanvas = class DrawingCanvasPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.DrawingCanvas.Type = class DrawingCanvasType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const INITIALLY_VISIBLE = 0;
|
|
const ORIGIN = 1;
|
|
const MULTISAMPLING = 2;
|
|
const tempColor = C3.New(C3.Color);
|
|
let drawDepth = 0;
|
|
C3.Plugins.DrawingCanvas.Instance = class DrawingCanvasInstance extends C3.SDKWorldInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this._renderTarget = null;
|
|
this._rcTex = C3.New(C3.Rect);
|
|
this._multisampling = 0;
|
|
this._texRenderTarget = null;
|
|
this._drawCommands = [];
|
|
this._currentPoly = [];
|
|
this._drawBlendMode = 0;
|
|
this._drawScale = 1;
|
|
this._texScale = 1;
|
|
this._lineDashTexture = null;
|
|
this._savedImageUrl = "";
|
|
this._snapshot = null;
|
|
this._tempRect = C3.New(C3.Rect);
|
|
this._tempQuad = C3.New(C3.Quad);
|
|
if (properties) {
|
|
this.GetWorldInfo().SetVisible(!!properties[INITIALLY_VISIBLE]);
|
|
this._multisampling = [0, 2, 4, 8][properties[MULTISAMPLING]]
|
|
}
|
|
const renderer = this._runtime.GetWebGLRenderer();
|
|
this._SetDrawingBlendMode(0);
|
|
if (renderer.GetWebGLVersionNumber() < 2)
|
|
this._multisampling = 0;
|
|
this._StartTicking2()
|
|
}
|
|
Release() {
|
|
if (this._renderTarget) {
|
|
this._renderTarget.GetWebGLRenderer().DeleteRenderTarget(this._renderTarget);
|
|
this._renderTarget = null
|
|
}
|
|
if (this._texRenderTarget) {
|
|
this._texRenderTarget.GetWebGLRenderer().DeleteRenderTarget(this._texRenderTarget);
|
|
this._texRenderTarget = null
|
|
}
|
|
C3.clearArray(this._drawCommands);
|
|
super.Release()
|
|
}
|
|
_ClonePoly() {
|
|
return this._currentPoly.map(p=>p.slice(0))
|
|
}
|
|
_GetLineDashTexture() {
|
|
this._MaybeCreateLineDashTexture();
|
|
return this._lineDashTexture
|
|
}
|
|
_MaybeCreateLineDashTexture() {
|
|
if (this._lineDashTexture)
|
|
return;
|
|
const canvas = C3.CreateCanvas(512, 8);
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.clearRect(0, 0, 512, 8);
|
|
ctx.fillStyle = "white";
|
|
ctx.fillRect(0, 0, 256, 8);
|
|
this._lineDashTexture = this._runtime.GetWebGLRenderer().CreateStaticTexture(canvas, {
|
|
wrapX: "repeat",
|
|
sampling: this._runtime.GetSampling()
|
|
})
|
|
}
|
|
_SetDrawingBlendMode(bm) {
|
|
this._drawBlendMode = bm
|
|
}
|
|
_ApplyCurrentDrawingBlendMode(renderer) {
|
|
renderer.SetBlendMode(this._drawBlendMode)
|
|
}
|
|
_AddDrawCommand(cmd) {
|
|
this._drawCommands.push(cmd);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
_UpdateRenderTargetSize(renderer, rtWidth, rtHeight) {
|
|
if (this._renderTarget)
|
|
renderer.DeleteRenderTarget(this._renderTarget);
|
|
this._renderTarget = renderer.CreateRenderTarget({
|
|
width: rtWidth,
|
|
height: rtHeight,
|
|
sampling: this._runtime.GetSampling(),
|
|
readback: this._multisampling === 0,
|
|
multisampling: this._multisampling
|
|
});
|
|
if (this._multisampling > 0) {
|
|
if (this._texRenderTarget)
|
|
renderer.DeleteRenderTarget(this._texRenderTarget);
|
|
this._texRenderTarget = renderer.CreateRenderTarget({
|
|
width: rtWidth,
|
|
height: rtHeight,
|
|
sampling: this._runtime.GetSampling(),
|
|
readback: true
|
|
})
|
|
}
|
|
renderer.SetTexture(null)
|
|
}
|
|
_GetRenderTarget() {
|
|
return this._renderTarget
|
|
}
|
|
_GetTexRenderTarget() {
|
|
return this._texRenderTarget
|
|
}
|
|
GetMultisampling() {
|
|
return this._multisampling
|
|
}
|
|
_SetRenderTargetDeviceTransform(renderer) {
|
|
this._runtime.GetCanvasManager().SetDeviceTransform(renderer, this._renderTarget.GetWidth(), this._renderTarget.GetHeight())
|
|
}
|
|
HasAnyDrawingCommandInQueue() {
|
|
return this._drawCommands.some(c=>!(c instanceof C3.Plugins.DrawingCanvas.DrawCommand.SaveImage))
|
|
}
|
|
Tick2() {
|
|
const renderer = this._runtime.GetWebGLRenderer();
|
|
const wi = this.GetWorldInfo();
|
|
const layer = wi.GetLayer();
|
|
const layout = layer.GetLayout();
|
|
const tempQuad = this._tempQuad;
|
|
const tempRect = this._tempRect;
|
|
++drawDepth;
|
|
const angle = wi.GetAngle();
|
|
const layerAngle = layer.GetOwnAngle();
|
|
const layoutAngle = layout.GetAngle();
|
|
if (angle !== 0 || layerAngle !== 0 || layoutAngle !== 0) {
|
|
layout.SetAngle(0);
|
|
layer.SetAngle(0);
|
|
wi.SetAngle(0);
|
|
wi.SetBboxChanged()
|
|
}
|
|
const quad = wi.GetBoundingQuad();
|
|
const [dl,dt] = layer.LayerToDrawSurface(quad.getTlx(), quad.getTly());
|
|
const [dr,db] = layer.LayerToDrawSurface(quad.getBrx(), quad.getBry());
|
|
const offX = dl - Math.round(dl);
|
|
const offY = dt - Math.round(dt);
|
|
tempRect.set(dl, dt, dr, db);
|
|
tempRect.offset(-offX, -offY);
|
|
tempRect.normalize();
|
|
tempQuad.setFromRect(tempRect);
|
|
if (angle !== 0 || layerAngle !== 0 || layoutAngle !== 0) {
|
|
layout.SetAngle(layoutAngle);
|
|
layer.SetAngle(layerAngle);
|
|
wi.SetAngle(angle);
|
|
wi.SetBboxChanged()
|
|
}
|
|
let rtWidth = Math.ceil(tempRect.width());
|
|
let rtHeight = Math.ceil(tempRect.height());
|
|
this._rcTex.set(0, 1, tempRect.width() / rtWidth, 1 - tempRect.height() / rtHeight);
|
|
const maxTextureSize = renderer.GetMaxTextureSize();
|
|
const maxRtDim = Math.max(rtWidth, rtHeight);
|
|
if (maxRtDim > maxTextureSize) {
|
|
this._texScale = maxTextureSize / maxRtDim;
|
|
rtWidth = Math.round(rtWidth * this._texScale);
|
|
rtHeight = Math.round(rtHeight * this._texScale)
|
|
} else
|
|
this._texScale = 1;
|
|
if (rtWidth <= 0 || rtHeight <= 0) {
|
|
--drawDepth;
|
|
return
|
|
}
|
|
this._drawScale = tempRect.width() / wi.GetWidth();
|
|
const drawScale = this._drawScale * this._texScale;
|
|
const didRenderTargetChange = !this._renderTarget || this._renderTarget.GetWidth() !== rtWidth || this._renderTarget.GetHeight() !== rtHeight;
|
|
if (didRenderTargetChange)
|
|
this.Trigger(C3.Plugins.DrawingCanvas.Cnds.OnResolutionChanged);
|
|
if (this._drawCommands.length > 0 || !this._renderTarget) {
|
|
if (!this._renderTarget || didRenderTargetChange && this.HasAnyDrawingCommandInQueue())
|
|
this._UpdateRenderTargetSize(renderer, rtWidth, rtHeight);
|
|
renderer.SetRenderTarget(this._renderTarget);
|
|
this._SetRenderTargetDeviceTransform(renderer);
|
|
this._ApplyCurrentDrawingBlendMode(renderer);
|
|
for (const dc of this._drawCommands)
|
|
dc.Do(renderer, drawScale, this);
|
|
C3.clearArray(this._drawCommands);
|
|
renderer.SetAlphaBlend();
|
|
if (this._multisampling > 0) {
|
|
renderer.SetRenderTarget(this._texRenderTarget);
|
|
renderer.CopyRenderTarget(this._renderTarget, "crop")
|
|
}
|
|
}
|
|
--drawDepth
|
|
}
|
|
Draw(renderer) {
|
|
const wi = this.GetWorldInfo();
|
|
const layer = wi.GetLayer();
|
|
const canvasManager = this._runtime.GetCanvasManager();
|
|
const lastRenderTarget = renderer.GetRenderTarget();
|
|
let quad = this._tempQuad;
|
|
if (!this._renderTarget)
|
|
return;
|
|
renderer.SetTextureFillMode();
|
|
renderer.SetBlendMode(wi.GetBlendMode());
|
|
renderer.SetColor(wi.GetPremultipliedColor());
|
|
if (this._multisampling === 0)
|
|
renderer.SetTexture(this._renderTarget.GetTexture());
|
|
else
|
|
renderer.SetTexture(this._texRenderTarget.GetTexture());
|
|
let didChangeTransform = false;
|
|
if (drawDepth > 0) {
|
|
canvasManager.SetDeviceTransform(renderer, lastRenderTarget.GetWidth(), lastRenderTarget.GetHeight());
|
|
didChangeTransform = true
|
|
} else if (wi.GetAngle() === 0 && wi.GetLayer().GetAngle() === 0) {
|
|
canvasManager.SetDeviceTransform(renderer);
|
|
didChangeTransform = true
|
|
} else
|
|
quad = wi.GetBoundingQuad();
|
|
renderer.Quad3(quad, this._rcTex);
|
|
if (didChangeTransform)
|
|
layer._SetTransform(renderer)
|
|
}
|
|
GetSnapshotPixel(x, y) {
|
|
if (!this._snapshot)
|
|
return [0, 0, 0, 0];
|
|
const width = this._snapshot.width;
|
|
const height = this._snapshot.height;
|
|
x = Math.floor(x);
|
|
y = height - 1 - Math.floor(y);
|
|
if (x < 0 || y < 0 || x >= width || y >= height)
|
|
return [0, 0, 0, 0];
|
|
const data = this._snapshot.data;
|
|
const ptr = y * width * 4 + x * 4;
|
|
let r = data[ptr] / 255;
|
|
let g = data[ptr + 1] / 255;
|
|
let b = data[ptr + 2] / 255;
|
|
let a = data[ptr + 3] / 255;
|
|
if (a !== 0) {
|
|
r /= a;
|
|
g /= a;
|
|
b /= a
|
|
}
|
|
return [r * 100, g * 100, b * 100, a * 100]
|
|
}
|
|
SetSnapshotPixel(x, y, rgb) {
|
|
if (!this._snapshot)
|
|
return [0, 0, 0, 0];
|
|
tempColor.setFromRgbValue(rgb);
|
|
tempColor.premultiply();
|
|
const width = this._snapshot.width;
|
|
const height = this._snapshot.height;
|
|
x = Math.floor(x);
|
|
y = height - 1 - Math.floor(y);
|
|
if (x < 0 || y < 0 || x >= width || y >= height)
|
|
return;
|
|
const data = this._snapshot.data;
|
|
const ptr = y * width * 4 + x * 4;
|
|
data[ptr] = Math.floor(tempColor.getR() * 255);
|
|
data[ptr + 1] = Math.floor(tempColor.getG() * 255);
|
|
data[ptr + 2] = Math.floor(tempColor.getB() * 255);
|
|
data[ptr + 3] = Math.floor(tempColor.getA() * 255)
|
|
}
|
|
GetImagePixelData() {
|
|
return new Promise(resolve=>{
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.SaveImage(async imageData=>{
|
|
const imgDataBuffer = imageData.data.buffer;
|
|
const width = imageData.width;
|
|
const height = imageData.height;
|
|
const processedBuffer = await this._runtime.AddJob("ProcessImageData", {
|
|
"buffer": imgDataBuffer,
|
|
"width": width,
|
|
"height": height,
|
|
"unpremultiply": true,
|
|
"flipY": true
|
|
}, [imgDataBuffer]);
|
|
resolve(new ImageData(new Uint8ClampedArray(processedBuffer),width,height))
|
|
}
|
|
))
|
|
}
|
|
)
|
|
}
|
|
LoadImagePixelData(imageData, premultiplyAlpha, flipY) {
|
|
if (!this._renderTarget)
|
|
throw new Error("canvas not yet ready");
|
|
if (imageData.width !== this._renderTarget.GetWidth() || imageData.height !== this._renderTarget.GetHeight())
|
|
throw new Error(`wrong size ImageData: expected ${this._renderTarget.GetWidth()} x ${this._renderTarget.GetHeight()}, got ${imageData.width} x ${imageData.height}`);
|
|
C3.clearArray(this._drawCommands);
|
|
const renderer = this._runtime.GetWebGLRenderer();
|
|
if (this._texRenderTarget) {
|
|
const lastRenderTarget = renderer.GetRenderTarget();
|
|
const texture = this._texRenderTarget.GetTexture();
|
|
renderer.UpdateTexture(imageData, texture, {
|
|
premultiplyAlpha: !!premultiplyAlpha,
|
|
flipY: !!flipY
|
|
});
|
|
renderer.SetRenderTarget(this._renderTarget);
|
|
renderer.CopyRenderTarget(this._texRenderTarget, "crop");
|
|
renderer.SetRenderTarget(lastRenderTarget)
|
|
} else {
|
|
const texture = this._renderTarget.GetTexture();
|
|
renderer.UpdateTexture(imageData, texture, {
|
|
premultiplyAlpha: !!premultiplyAlpha,
|
|
flipY: !!flipY
|
|
})
|
|
}
|
|
this._runtime.UpdateRender()
|
|
}
|
|
GetScriptInterfaceClass() {
|
|
return self.IDrawingCanvasInstance
|
|
}
|
|
}
|
|
;
|
|
const map = new WeakMap;
|
|
self.IDrawingCanvasInstance = class IDrawingCanvasInstance extends self.IWorldInstance {
|
|
constructor() {
|
|
super();
|
|
map.set(this, self.IInstance._GetInitInst().GetSdkInstance())
|
|
}
|
|
getImagePixelData() {
|
|
return map.get(this).GetImagePixelData()
|
|
}
|
|
loadImagePixelData(imageData, premultiplyAlpha=false) {
|
|
map.get(this).LoadImagePixelData(imageData, premultiplyAlpha, true)
|
|
}
|
|
get surfaceDeviceWidth() {
|
|
const rt = map.get(this)._GetRenderTarget();
|
|
if (!rt)
|
|
throw new Error("canvas not yet ready");
|
|
return rt.GetWidth()
|
|
}
|
|
get surfaceDeviceHeight() {
|
|
const rt = map.get(this)._GetRenderTarget();
|
|
if (!rt)
|
|
throw new Error("canvas not yet ready");
|
|
return rt.GetHeight()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.DrawingCanvas.Cnds = {
|
|
OnSavedImage() {
|
|
return true
|
|
},
|
|
OnSnapshot() {
|
|
return true
|
|
},
|
|
OnResolutionChanged() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function SortByInstanceZIndex(a, b) {
|
|
return a.GetWorldInfo().GetZIndex() - b.GetWorldInfo().GetZIndex()
|
|
}
|
|
C3.Plugins.DrawingCanvas.Acts = {
|
|
SetEffect(effect) {
|
|
this.GetWorldInfo().SetBlendMode(effect);
|
|
this._runtime.UpdateRender()
|
|
},
|
|
ClearCanvas(rgb) {
|
|
C3.clearArray(this._drawCommands);
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.ClearCanvas(rgb))
|
|
},
|
|
ClearRect(left, top, right, bottom, rgb) {
|
|
if (left === right || top === bottom)
|
|
return;
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.ClearRect(left,top,right,bottom,rgb))
|
|
},
|
|
FillRect(left, top, right, bottom, rgb) {
|
|
if (left === right || top === bottom)
|
|
return;
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.FillRect(left,top,right,bottom,rgb))
|
|
},
|
|
FillLinearGradient(left, top, right, bottom, rgb1, rgb2, dir) {
|
|
if (left === right || top === bottom)
|
|
return;
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.FillLinearGradient(left,top,right,bottom,rgb1,rgb2,dir))
|
|
},
|
|
FillEllipse(x, y, radiusX, radiusY, rgb, edge) {
|
|
if (radiusX <= 0 || radiusY <= 0)
|
|
return;
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.FillEllipse(x,y,radiusX,radiusY,rgb,edge !== 0))
|
|
},
|
|
OutlineEllipse(x, y, radiusX, radiusY, rgb, thickness, edge) {
|
|
if (radiusX <= 0 || radiusY <= 0 || thickness <= 0)
|
|
return;
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.OutlineEllipse(x,y,radiusX,radiusY,rgb,thickness,edge !== 0))
|
|
},
|
|
OutlineRect(left, top, right, bottom, rgb, thickness) {
|
|
if (left === right || top === bottom || thickness <= 0)
|
|
return;
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.OutlineRect(left,top,right,bottom,rgb,thickness))
|
|
},
|
|
Line(x1, y1, x2, y2, rgb, thickness, cap) {
|
|
if (x1 === x2 && y1 === y2 || thickness <= 0)
|
|
return;
|
|
const capStr = cap === 0 ? "butt" : "square";
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.Line(x1,y1,x2,y2,rgb,thickness,capStr))
|
|
},
|
|
LineDashed(x1, y1, x2, y2, rgb, thickness, dashLength, cap) {
|
|
if (x1 === x2 && y1 === y2 || thickness <= 0 || dashLength <= 0)
|
|
return;
|
|
const capStr = cap === 0 ? "butt" : "square";
|
|
const dashTex = this._GetLineDashTexture();
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.LineDashed(x1,y1,x2,y2,rgb,thickness,dashLength,dashTex,capStr))
|
|
},
|
|
AddPolyPoint(x, y) {
|
|
this._currentPoly.push([x, y])
|
|
},
|
|
ResetPoly() {
|
|
C3.clearArray(this._currentPoly)
|
|
},
|
|
LinePoly(rgb, thickness, cap) {
|
|
if (this._currentPoly.length < 2 || thickness <= 0)
|
|
return;
|
|
const capStr = cap === 0 ? "butt" : "square";
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.LinePoly(this._ClonePoly(),rgb,thickness,capStr))
|
|
},
|
|
LineDashedPoly(rgb, thickness, dashLength, cap) {
|
|
if (this._currentPoly.length < 2 || thickness <= 0 || dashLength <= 0)
|
|
return;
|
|
const capStr = cap === 0 ? "butt" : "square";
|
|
const dashTex = this._GetLineDashTexture();
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.LineDashedPoly(this._ClonePoly(),rgb,thickness,dashLength,dashTex,capStr))
|
|
},
|
|
FillPoly(rgb) {
|
|
if (this._currentPoly.length < 3)
|
|
return;
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.FillPoly(this._ClonePoly(),rgb))
|
|
},
|
|
SetDrawBlend(blendMode) {
|
|
if (blendMode >= 2)
|
|
blendMode++;
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.SetDrawBlend(blendMode))
|
|
},
|
|
PasteObject(objectClass, includeFx) {
|
|
if (!objectClass)
|
|
return;
|
|
const myWi = this.GetWorldInfo();
|
|
const myBbox = myWi.GetBoundingBox();
|
|
const myQuad = myWi.GetBoundingQuad();
|
|
const instances = objectClass.GetCurrentSol().GetInstances().filter(inst=>{
|
|
const instWi = inst.GetWorldInfo();
|
|
return instWi && myBbox.intersectsRect(instWi.GetBoundingBox()) && (myWi.GetAngle() === 0 || myQuad.intersectsQuad(instWi.GetBoundingQuad()))
|
|
}
|
|
);
|
|
if (instances.length === 0)
|
|
return;
|
|
instances.sort(SortByInstanceZIndex);
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.DrawInstances(instances,includeFx !== 0,myWi))
|
|
},
|
|
SaveImage(format, quality, x, y, width, height) {
|
|
const formatStr = format === 0 ? "image/png" : "image/jpeg";
|
|
quality /= 100;
|
|
const areaRect = C3.New(C3.Rect);
|
|
areaRect.setWH(x, y, width, height);
|
|
return new Promise(resolve=>{
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.SaveImage(async imageData=>{
|
|
const imgDataBuffer = imageData.data.buffer;
|
|
const width = imageData.width;
|
|
const height = imageData.height;
|
|
const processedBuffer = await this._runtime.AddJob("ProcessImageData", {
|
|
"buffer": imgDataBuffer,
|
|
"width": width,
|
|
"height": height,
|
|
"unpremultiply": true,
|
|
"flipY": !C3.Supports.ImageBitmapOptions
|
|
}, [imgDataBuffer]);
|
|
imageData = new ImageData(new Uint8ClampedArray(processedBuffer),width,height);
|
|
let blob;
|
|
if (C3.Supports.ImageBitmapOptions) {
|
|
const imageBitmap = await createImageBitmap(imageData, {
|
|
"premultiplyAlpha": "none",
|
|
"imageOrientation": "flipY"
|
|
});
|
|
blob = await C3.DrawableToBlob(imageBitmap, formatStr, quality)
|
|
} else
|
|
blob = await C3.ImageDataToBlob(imageData, formatStr, quality);
|
|
if (this._savedImageUrl)
|
|
URL.revokeObjectURL(this._savedImageUrl);
|
|
this._savedImageUrl = URL.createObjectURL(blob);
|
|
this.Trigger(C3.Plugins.DrawingCanvas.Cnds.OnSavedImage);
|
|
resolve()
|
|
}
|
|
,areaRect))
|
|
}
|
|
)
|
|
},
|
|
SaveSnapshot() {
|
|
return new Promise(resolve=>{
|
|
this._AddDrawCommand(new C3.Plugins.DrawingCanvas.DrawCommand.SaveImage(imageData=>{
|
|
this._snapshot = imageData;
|
|
this.Trigger(C3.Plugins.DrawingCanvas.Cnds.OnSnapshot);
|
|
resolve()
|
|
}
|
|
))
|
|
}
|
|
)
|
|
},
|
|
ClearSnapshot() {
|
|
this._snapshot = null
|
|
},
|
|
SnapshotSetPixel(x, y, rgb) {
|
|
this.SetSnapshotPixel(x, y, rgb)
|
|
},
|
|
LoadSnapshot() {
|
|
if (!this._snapshot || !this._renderTarget)
|
|
return;
|
|
if (this._snapshot.width !== this._renderTarget.GetWidth() || this._snapshot.height !== this._renderTarget.GetHeight())
|
|
return;
|
|
this.LoadImagePixelData(this._snapshot, false)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.DrawingCanvas.Exps = {
|
|
SavedImageURL() {
|
|
return this._savedImageUrl
|
|
},
|
|
SnapshotRedAt(x, y) {
|
|
return this.GetSnapshotPixel(x, y)[0]
|
|
},
|
|
SnapshotGreenAt(x, y) {
|
|
return this.GetSnapshotPixel(x, y)[1]
|
|
},
|
|
SnapshotBlueAt(x, y) {
|
|
return this.GetSnapshotPixel(x, y)[2]
|
|
},
|
|
SnapshotAlphaAt(x, y) {
|
|
return this.GetSnapshotPixel(x, y)[3]
|
|
},
|
|
SnapshotWidth() {
|
|
return this._snapshot ? this._snapshot.width : 0
|
|
},
|
|
SnapshotHeight() {
|
|
return this._snapshot ? this._snapshot.height : 0
|
|
},
|
|
PixelScale() {
|
|
return 1 / (this._drawScale * this._texScale)
|
|
},
|
|
SurfaceDeviceWidth() {
|
|
const rt = this._GetRenderTarget();
|
|
return rt ? rt.GetWidth() : 0
|
|
},
|
|
SurfaceDeviceHeight() {
|
|
const rt = this._GetRenderTarget();
|
|
return rt ? rt.GetHeight() : 0
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const tempQuad = C3.New(C3.Quad);
|
|
const tempUvQuad = C3.New(C3.Quad);
|
|
const tempVector2 = C3.New(C3.Vector2);
|
|
C3.Plugins.DrawingCanvas.DrawCommand = class DrawCommand {
|
|
constructor() {}
|
|
Do(renderer) {
|
|
throw new Error("required override");
|
|
}
|
|
}
|
|
;
|
|
const DrawCommand = C3.Plugins.DrawingCanvas.DrawCommand;
|
|
DrawCommand.SaveImage = class SaveImageCommand extends DrawCommand {
|
|
constructor(callback, areaRect) {
|
|
super();
|
|
this._callback = callback;
|
|
this._areaRect = areaRect
|
|
}
|
|
Do(renderer, scale, canvasInst) {
|
|
let readRenderTarget = renderer.GetRenderTarget();
|
|
if (readRenderTarget.GetMultisampling() > 0) {
|
|
const texRenderTarget = canvasInst._GetTexRenderTarget();
|
|
renderer.SetRenderTarget(texRenderTarget);
|
|
renderer.CopyRenderTarget(readRenderTarget, "crop");
|
|
renderer.SetRenderTarget(readRenderTarget);
|
|
readRenderTarget = texRenderTarget
|
|
}
|
|
renderer.ReadBackRenderTargetToImageData(readRenderTarget, false, this._areaRect).then(this._callback)
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.ClearCanvas = class ClearCanvasCommand extends DrawCommand {
|
|
constructor(rgb) {
|
|
super();
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply()
|
|
}
|
|
Do(renderer) {
|
|
renderer.Clear(this._color)
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.ClearRect = class ClearRectCommand extends DrawCommand {
|
|
constructor(left, top, right, bottom, rgb) {
|
|
super();
|
|
this._rect = C3.New(C3.Rect);
|
|
this._rect.set(left, top, right, bottom);
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply()
|
|
}
|
|
Do(renderer, scale, inst) {
|
|
const rtHeight = inst._GetRenderTarget().GetHeight();
|
|
this._rect.multiply(scale, scale);
|
|
this._rect.shuntY(rtHeight);
|
|
renderer.ClearRect3(this._rect, this._color)
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.FillRect = class FillRectCommand extends DrawCommand {
|
|
constructor(left, top, right, bottom, rgb) {
|
|
super();
|
|
this._rect = C3.New(C3.Rect);
|
|
this._rect.set(left, top, right, bottom);
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply()
|
|
}
|
|
Do(renderer, scale) {
|
|
renderer.SetColorFillMode();
|
|
renderer.SetColor(this._color);
|
|
this._rect.multiply(scale, scale);
|
|
renderer.Rect(this._rect)
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.FillLinearGradient = class FillLinearGradientCommand extends DrawCommand {
|
|
constructor(left, top, right, bottom, rgb1, rgb2, dir) {
|
|
super();
|
|
this._rect = C3.New(C3.Rect);
|
|
this._rect.set(left, top, right, bottom);
|
|
this._color1 = C3.New(C3.Color);
|
|
this._color1.setFromRgbValue(rgb1);
|
|
this._color2 = C3.New(C3.Color);
|
|
this._color2.setFromRgbValue(rgb2);
|
|
this._dir = dir
|
|
}
|
|
Do(renderer, scale) {
|
|
renderer.SetLinearGradientFillMode();
|
|
renderer.SetColor(this._color1);
|
|
renderer.SetGradientColor(this._color2);
|
|
this._rect.multiply(scale, scale);
|
|
tempQuad.setFromRect(this._rect);
|
|
if (this._dir === 0)
|
|
tempUvQuad.set(0, 0, 1, 0, 1, 1, 0, 1);
|
|
else
|
|
tempUvQuad.set(0, 1, 0, 0, 1, 0, 1, 1);
|
|
renderer.Quad4(tempQuad, tempUvQuad)
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.FillEllipse = class FillEllipseCommand extends DrawCommand {
|
|
constructor(x, y, radiusX, radiusY, rgb, isSmooth) {
|
|
super();
|
|
this._rect = C3.New(C3.Rect);
|
|
this._rect.set(x - radiusX, y - radiusY, x + radiusX, y + radiusY);
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply();
|
|
this._isSmooth = isSmooth
|
|
}
|
|
Do(renderer, scale) {
|
|
this._rect.multiply(scale, scale);
|
|
if (this._isSmooth) {
|
|
renderer.SetSmoothEllipseFillMode();
|
|
renderer.SetColor(this._color);
|
|
this._rect.inflate(.5, .5);
|
|
renderer.SetEllipseParams(1 / this._rect.width(), 1 / this._rect.height());
|
|
renderer.Rect(this._rect)
|
|
} else {
|
|
renderer.SetHardEllipseFillMode();
|
|
renderer.SetColor(this._color);
|
|
renderer.Rect(this._rect)
|
|
}
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.OutlineEllipse = class OutlinellipseCommand extends DrawCommand {
|
|
constructor(x, y, radiusX, radiusY, rgb, thickness, isSmooth) {
|
|
super();
|
|
this._rect = C3.New(C3.Rect);
|
|
this._rect.set(x - radiusX, y - radiusY, x + radiusX, y + radiusY);
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply();
|
|
this._thickness = thickness;
|
|
this._isSmooth = isSmooth
|
|
}
|
|
Do(renderer, scale) {
|
|
this._rect.multiply(scale, scale);
|
|
if (this._isSmooth) {
|
|
renderer.SetSmoothEllipseOutlineMode();
|
|
renderer.SetColor(this._color);
|
|
this._rect.inflate(.5, .5);
|
|
renderer.SetEllipseParams(1 / this._rect.width(), 1 / this._rect.height(), this._thickness * scale);
|
|
renderer.Rect(this._rect)
|
|
} else {
|
|
renderer.SetHardEllipseOutlineMode();
|
|
renderer.SetEllipseParams(1 / this._rect.width(), 1 / this._rect.height(), this._thickness * scale);
|
|
renderer.SetColor(this._color);
|
|
renderer.Rect(this._rect)
|
|
}
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.OutlineRect = class OutlineRectCommand extends DrawCommand {
|
|
constructor(left, top, right, bottom, rgb, thickness) {
|
|
super();
|
|
this._rect = C3.New(C3.Rect);
|
|
this._rect.set(left, top, right, bottom);
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply();
|
|
this._thickness = thickness
|
|
}
|
|
Do(renderer, scale) {
|
|
renderer.SetColorFillMode();
|
|
renderer.SetColor(this._color);
|
|
renderer.PushLineCapZag();
|
|
renderer.PushLineWidth(this._thickness * scale);
|
|
this._rect.multiply(scale, scale);
|
|
renderer.LineRect2(this._rect);
|
|
renderer.PopLineCap();
|
|
renderer.PopLineWidth()
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.Line = class LineCommand extends DrawCommand {
|
|
constructor(x1, y1, x2, y2, rgb, thickness, cap) {
|
|
super();
|
|
this._rect = C3.New(C3.Rect);
|
|
this._rect.set(x1, y1, x2, y2);
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply();
|
|
this._thickness = thickness;
|
|
this._cap = cap
|
|
}
|
|
Do(renderer, scale) {
|
|
renderer.SetColorFillMode();
|
|
renderer.SetColor(this._color);
|
|
renderer.PushLineCap(this._cap);
|
|
renderer.PushLineWidth(this._thickness * scale);
|
|
const rc = this._rect;
|
|
rc.multiply(scale, scale);
|
|
renderer.Line(rc.getLeft(), rc.getTop(), rc.getRight(), rc.getBottom());
|
|
renderer.PopLineCap();
|
|
renderer.PopLineWidth()
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.LinePoly = class LinePolyCommand extends DrawCommand {
|
|
constructor(poly, rgb, thickness, cap) {
|
|
super();
|
|
this._poly = poly;
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply();
|
|
this._thickness = thickness;
|
|
this._cap = cap
|
|
}
|
|
Do(renderer, scale) {
|
|
renderer.SetColorFillMode();
|
|
renderer.SetColor(this._color);
|
|
renderer.PushLineCap(this._cap);
|
|
renderer.PushLineWidth(this._thickness * scale);
|
|
const poly = this._poly;
|
|
for (let i = 0, len = poly.length; i < len; ++i) {
|
|
const j = (i + 1) % len;
|
|
const x1 = poly[i][0] * scale;
|
|
const y1 = poly[i][1] * scale;
|
|
const x2 = poly[j][0] * scale;
|
|
const y2 = poly[j][1] * scale;
|
|
renderer.Line(x1, y1, x2, y2)
|
|
}
|
|
renderer.PopLineCap();
|
|
renderer.PopLineWidth()
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.LineDashed = class LineDashedCommand extends DrawCommand {
|
|
constructor(x1, y1, x2, y2, rgb, thickness, dashLength, dashTex, cap) {
|
|
super();
|
|
this._rect = C3.New(C3.Rect);
|
|
this._rect.set(x1, y1, x2, y2);
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply();
|
|
this._thickness = thickness;
|
|
this._dashLength = dashLength;
|
|
this._dashTex = dashTex;
|
|
this._cap = cap
|
|
}
|
|
Do(renderer, scale) {
|
|
renderer.SetTextureFillMode();
|
|
renderer.SetTexture(this._dashTex);
|
|
renderer.SetColor(this._color);
|
|
renderer.PushLineCap(this._cap);
|
|
renderer.PushLineWidth(this._thickness * scale);
|
|
const rc = this._rect;
|
|
const numDashes = C3.distanceTo(rc.getLeft(), rc.getTop(), rc.getRight(), rc.getBottom()) / (this._dashLength * 2);
|
|
rc.multiply(scale, scale);
|
|
renderer.TexturedLine(rc.getLeft(), rc.getTop(), rc.getRight(), rc.getBottom(), 0, numDashes);
|
|
renderer.PopLineCap();
|
|
renderer.PopLineWidth()
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.LineDashedPoly = class LineDashedPolyCommand extends DrawCommand {
|
|
constructor(poly, rgb, thickness, dashLength, dashTex, cap) {
|
|
super();
|
|
this._poly = poly;
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply();
|
|
this._thickness = thickness;
|
|
this._dashLength = dashLength;
|
|
this._dashTex = dashTex;
|
|
this._cap = cap
|
|
}
|
|
Do(renderer, scale) {
|
|
renderer.SetTextureFillMode();
|
|
renderer.SetTexture(this._dashTex);
|
|
renderer.SetColor(this._color);
|
|
renderer.PushLineCap(this._cap);
|
|
renderer.PushLineWidth(this._thickness * scale);
|
|
let u = 0;
|
|
const poly = this._poly;
|
|
for (let i = 0, len = poly.length; i < len; ++i) {
|
|
const j = (i + 1) % len;
|
|
const x1 = poly[i][0];
|
|
const y1 = poly[i][1];
|
|
const x2 = poly[j][0];
|
|
const y2 = poly[j][1];
|
|
const v = u + C3.distanceTo(x1, y1, x2, y2) / (this._dashLength * 2);
|
|
renderer.TexturedLine(x1 * scale, y1 * scale, x2 * scale, y2 * scale, u, v);
|
|
u = v - Math.floor(v)
|
|
}
|
|
renderer.PopLineCap();
|
|
renderer.PopLineWidth()
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.FillPoly = class FillPolyCommand extends DrawCommand {
|
|
constructor(poly, rgb) {
|
|
super();
|
|
this._poly = poly;
|
|
this._color = C3.New(C3.Color);
|
|
this._color.setFromRgbValue(rgb);
|
|
this._color.premultiply()
|
|
}
|
|
Do(renderer, scale) {
|
|
renderer.SetColorFillMode();
|
|
renderer.SetColor(this._color);
|
|
const poly = this._poly;
|
|
for (let i = 0, len = poly.length; i < len; ++i) {
|
|
const p = poly[i];
|
|
p[0] *= scale;
|
|
p[1] *= scale
|
|
}
|
|
const polyDecomp = self.polyDecomp;
|
|
if (!polyDecomp.isSimple(poly))
|
|
return;
|
|
polyDecomp.makeCCW(poly);
|
|
polyDecomp.removeCollinearPoints(poly, C3.toRadians(.1));
|
|
const convexPolygons = polyDecomp.quickDecomp(poly);
|
|
for (const convexPoly of convexPolygons)
|
|
renderer.ConvexPoly(convexPoly.flat())
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.SetDrawBlend = class SetDrawBlend extends DrawCommand {
|
|
constructor(bm) {
|
|
super();
|
|
this._blendIndex = bm
|
|
}
|
|
Do(renderer, scale, canvasInst) {
|
|
canvasInst._SetDrawingBlendMode(this._blendIndex);
|
|
canvasInst._ApplyCurrentDrawingBlendMode(renderer)
|
|
}
|
|
}
|
|
;
|
|
DrawCommand.DrawInstances = class DrawInstancesCommand extends DrawCommand {
|
|
constructor(instances, includeFx, canvasWi) {
|
|
super();
|
|
this._includeFx = includeFx;
|
|
this._instances = instances.map(inst=>this._SaveInstanceState(inst, canvasWi))
|
|
}
|
|
_SaveInstanceState(inst, canvasWi) {
|
|
const canvasAngle = canvasWi.GetAngle();
|
|
const canvasLayer = canvasWi.GetLayer();
|
|
const instWi = inst.GetWorldInfo();
|
|
const instLayer = instWi.GetLayer();
|
|
const oldX = instWi.GetX();
|
|
const oldY = instWi.GetY();
|
|
const oldWidth = instWi.GetWidth();
|
|
const oldHeight = instWi.GetHeight();
|
|
const oldAngle = instWi.GetAngle();
|
|
const areLayerTransformsCompatible = canvasLayer.IsTransformCompatibleWith(instLayer);
|
|
if (!areLayerTransformsCompatible) {
|
|
const [dsx,dsy] = instLayer.LayerToDrawSurface(oldX, oldY);
|
|
const [tx,ty] = canvasLayer.DrawSurfaceToLayer(dsx, dsy);
|
|
instWi.SetXY(tx, ty);
|
|
const scaleFactor = instLayer.GetNormalScale() / canvasLayer.GetNormalScale();
|
|
instWi.SetSize(oldWidth * scaleFactor, oldHeight * scaleFactor);
|
|
const angleOffset = canvasLayer.GetOwnAngle() - instLayer.GetOwnAngle();
|
|
instWi.OffsetAngle(angleOffset)
|
|
}
|
|
if (canvasAngle !== 0) {
|
|
const canvasQuad = canvasWi.GetBoundingQuad();
|
|
const canvasMidX = canvasQuad.midX();
|
|
const canvasMidY = canvasQuad.midY();
|
|
const sinA = -canvasWi.GetSinAngle();
|
|
const cosA = canvasWi.GetCosAngle();
|
|
tempVector2.set(oldX, oldY);
|
|
tempVector2.offset(-canvasMidX, -canvasMidY);
|
|
tempVector2.rotatePrecalc(sinA, cosA);
|
|
tempVector2.offset(canvasMidX, canvasMidY);
|
|
instWi.SetXY(tempVector2.getX(), tempVector2.getY());
|
|
instWi.OffsetAngle(-canvasAngle)
|
|
}
|
|
if (canvasAngle !== 0 || !areLayerTransformsCompatible)
|
|
instWi.SetBboxChanged();
|
|
const ret = [inst, inst.SaveToJson("visual-state")];
|
|
if (canvasAngle !== 0 || !areLayerTransformsCompatible) {
|
|
instWi.SetXY(oldX, oldY);
|
|
instWi.SetSize(oldWidth, oldHeight);
|
|
instWi.SetAngle(oldAngle);
|
|
instWi.SetBboxChanged()
|
|
}
|
|
return ret
|
|
}
|
|
Do(renderer, scale, canvasInst) {
|
|
const canvasManager = canvasInst.GetRuntime().GetCanvasManager();
|
|
const layer = canvasInst.GetWorldInfo().GetLayer();
|
|
const viewport = layer.GetViewport();
|
|
const canvasBbox = canvasInst.GetWorldInfo().GetBoundingBox();
|
|
const renderTarget = canvasInst._GetRenderTarget();
|
|
const isMultisamplng = canvasInst.GetMultisampling() > 0;
|
|
const includeFx = this._includeFx;
|
|
const viewOffX = (viewport.width() - canvasBbox.width()) / -2;
|
|
const viewOffY = (viewport.height() - canvasBbox.height()) / -2;
|
|
const [canvasDeviceLeft,canvasDeviceTop] = layer.LayerToDrawSurface(canvasBbox.getLeft(), canvasBbox.getTop());
|
|
canvasManager.SetDeviceTransformOffset(canvasDeviceLeft, canvasDeviceTop);
|
|
const canvasOffX = canvasBbox.getLeft() - viewport.getLeft();
|
|
const canvasOffY = canvasBbox.getTop() - viewport.getTop();
|
|
const offX = viewOffX + canvasOffX;
|
|
const offY = viewOffY + canvasOffY;
|
|
layer._SetTransform(renderer, offX, offY);
|
|
for (let i = 0, len = this._instances.length; i < len; ++i) {
|
|
const info = this._instances[i];
|
|
const inst = info[0];
|
|
const instState = info[1];
|
|
if (inst.IsDestroyed())
|
|
continue;
|
|
const wi = inst.GetWorldInfo();
|
|
const bbox = wi.GetBoundingBox();
|
|
const oldState = inst.SaveToJson("visual-state");
|
|
inst.LoadFromJson(instState, "visual-state");
|
|
wi.GetBoundingBox();
|
|
if (includeFx && wi.HasAnyActiveEffect() && (!isMultisamplng || !wi.GetInstanceEffectList().HasAnyActiveBackgroundBlendingEffect())) {
|
|
bbox.offset(-offX, -offY);
|
|
const opts = {
|
|
preTransform: ()=>layer._SetTransform(renderer, offX, offY)
|
|
};
|
|
if (layer._DrawInstanceWithEffects(inst, wi, renderer, renderTarget, opts))
|
|
layer._SetTransform(renderer, offX, offY);
|
|
wi.SetBboxChanged();
|
|
wi.GetBoundingBox()
|
|
} else
|
|
layer._DrawInstance(inst, wi, renderer);
|
|
inst.LoadFromJson(oldState, "visual-state")
|
|
}
|
|
canvasManager.SetDeviceTransformOffset(0, 0);
|
|
canvasInst._SetRenderTargetDeviceTransform(renderer);
|
|
canvasInst._ApplyCurrentDrawingBlendMode(renderer)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Audio = class AudioPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Audio.Type = class AudioType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
GetScriptInterfaceClass() {
|
|
return self.IAudioObjectType
|
|
}
|
|
}
|
|
;
|
|
function GetAudioDOMInterface() {
|
|
if (self["C3Audio_DOMInterface"])
|
|
return self["C3Audio_DOMInterface"];
|
|
else
|
|
throw new Error("audio scripting API cannot be used here - make sure the project is using DOM mode, not worker mode");
|
|
}
|
|
self.IAudioObjectType = class IAudioObjectType extends self.IObjectClass {
|
|
constructor(objectType) {
|
|
super(objectType)
|
|
}
|
|
get audioContext() {
|
|
return GetAudioDOMInterface().GetAudioContext()
|
|
}
|
|
get destinationNode() {
|
|
return GetAudioDOMInterface().GetDestinationNode()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const DOM_COMPONENT_ID = "audio";
|
|
const LATENCY_HINTS = ["interactive", "balanced", "playback"];
|
|
C3.Plugins.Audio.Instance = class AudioInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst, DOM_COMPONENT_ID);
|
|
this._nextPlayTime = 0;
|
|
this._triggerTag = "";
|
|
this._timeScaleMode = 0;
|
|
this._saveLoadMode = 0;
|
|
this._playInBackground = false;
|
|
this._panningModel = 1;
|
|
this._distanceModel = 1;
|
|
this._listenerX = this._runtime.GetViewportWidth() / 2;
|
|
this._listenerY = this._runtime.GetViewportHeight() / 2;
|
|
this._listenerZ = -600;
|
|
this._referenceDistance = 600;
|
|
this._maxDistance = 1E4;
|
|
this._rolloffFactor = 1;
|
|
this._listenerInst = null;
|
|
this._loadListenerUid = -1;
|
|
this._masterVolume = 1;
|
|
this._isSilent = false;
|
|
this._sampleRate = 0;
|
|
this._effectCount = new Map;
|
|
this._preloadTotal = 0;
|
|
this._preloadCount = 0;
|
|
this._remoteUrls = new Map;
|
|
let latencyHint = "interactive";
|
|
if (properties) {
|
|
this._timeScaleMode = properties[0];
|
|
this._saveLoadMode = properties[1];
|
|
this._playInBackground = properties[2];
|
|
latencyHint = LATENCY_HINTS[properties[3]];
|
|
this._panningModel = properties[4];
|
|
this._distanceModel = properties[5];
|
|
this._listenerZ = -properties[6];
|
|
this._referenceDistance = properties[7];
|
|
this._maxDistance = properties[8];
|
|
this._rolloffFactor = properties[9]
|
|
}
|
|
this._lastAIState = [];
|
|
this._lastFxState = [];
|
|
this._lastAnalysersData = [];
|
|
this.AddDOMMessageHandlers([["state", e=>this._OnUpdateState(e)], ["fxstate", e=>this._OnUpdateFxState(e)], ["trigger", e=>this._OnTrigger(e)]]);
|
|
const rt = this.GetRuntime().Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(rt, "instancedestroy", e=>this._OnInstanceDestroyed(e.instance)),C3.Disposable.From(rt, "afterload", ()=>this._OnAfterLoad()),C3.Disposable.From(rt, "suspend", ()=>this._OnSuspend()),C3.Disposable.From(rt, "resume", ()=>this._OnResume()));
|
|
this._runtime.AddLoadPromise(this.PostToDOMAsync("create-audio-context", {
|
|
"preloadList": this._runtime.GetAssetManager().GetAudioToPreload().map(o=>({
|
|
"originalUrl": o.originalUrl,
|
|
"url": o.url,
|
|
"type": o.type,
|
|
"fileSize": o.fileSize
|
|
})),
|
|
"isiOSCordova": this._runtime.IsiOSCordova(),
|
|
"timeScaleMode": this._timeScaleMode,
|
|
"latencyHint": latencyHint,
|
|
"panningModel": this._panningModel,
|
|
"distanceModel": this._distanceModel,
|
|
"refDistance": this._referenceDistance,
|
|
"maxDistance": this._maxDistance,
|
|
"rolloffFactor": this._rolloffFactor,
|
|
"listenerPos": [this._listenerX, this._listenerY, this._listenerZ]
|
|
}).then(info=>{
|
|
this._sampleRate = info["sampleRate"]
|
|
}
|
|
));
|
|
this._StartTicking()
|
|
}
|
|
Release() {
|
|
this._listenerInst = null;
|
|
super.Release()
|
|
}
|
|
_OnInstanceDestroyed(inst) {
|
|
if (this._listenerInst === inst)
|
|
this._listenerInst = null
|
|
}
|
|
DbToLinearNoCap(x) {
|
|
return Math.pow(10, x / 20)
|
|
}
|
|
DbToLinear(x) {
|
|
const v = this.DbToLinearNoCap(x);
|
|
if (!isFinite(v))
|
|
return 0;
|
|
return Math.max(Math.min(v, 1), 0)
|
|
}
|
|
LinearToDbNoCap(x) {
|
|
return Math.log(x) / Math.log(10) * 20
|
|
}
|
|
LinearToDb(x) {
|
|
return this.LinearToDbNoCap(Math.max(Math.min(x, 1), 0))
|
|
}
|
|
_OnSuspend() {
|
|
if (this._playInBackground)
|
|
return;
|
|
this.PostToDOM("set-suspended", {
|
|
"isSuspended": true
|
|
})
|
|
}
|
|
_OnResume() {
|
|
if (this._playInBackground)
|
|
return;
|
|
this.PostToDOM("set-suspended", {
|
|
"isSuspended": false
|
|
})
|
|
}
|
|
_OnUpdateState(e) {
|
|
const tickCount = e["tickCount"];
|
|
const preservePlaceholders = this._lastAIState.filter(ai=>ai.hasOwnProperty("placeholder") && (ai["placeholder"] > tickCount || ai["placeholder"] === -1));
|
|
this._lastAIState = e["audioInstances"];
|
|
this._lastAnalysersData = e["analysers"];
|
|
if (preservePlaceholders.length > 0)
|
|
C3.appendArray(this._lastAIState, preservePlaceholders)
|
|
}
|
|
_OnUpdateFxState(e) {
|
|
this._lastFxState = e["fxstate"]
|
|
}
|
|
_GetFirstAudioStateByTag(tag) {
|
|
for (const a of this._lastAIState)
|
|
if (C3.equalsNoCase(a["tag"], tag))
|
|
return a;
|
|
return null
|
|
}
|
|
_IsTagPlaying(tag) {
|
|
return this._lastAIState.some(ai=>C3.equalsNoCase(tag, ai["tag"]) && ai["isPlaying"])
|
|
}
|
|
_MaybeMarkAsPlaying(tag, isMusic, isLooping, vol) {
|
|
if (this._IsTagPlaying(tag))
|
|
return null;
|
|
const state = {
|
|
"tag": tag,
|
|
"duration": 0,
|
|
"volume": vol,
|
|
"isPlaying": true,
|
|
"playbackTime": 0,
|
|
"playbackRate": 1,
|
|
"uid": -1,
|
|
"bufferOriginalUrl": "",
|
|
"bufferUrl": "",
|
|
"bufferType": "",
|
|
"isMusic": isMusic,
|
|
"isLooping": isLooping,
|
|
"isMuted": false,
|
|
"resumePosition": 0,
|
|
"pan": null,
|
|
"placeholder": -1
|
|
};
|
|
this._lastAIState.push(state);
|
|
return state
|
|
}
|
|
async _OnTrigger(e) {
|
|
const type = e["type"];
|
|
this._triggerTag = e["tag"];
|
|
const aiId = e["aiid"];
|
|
if (type === "ended") {
|
|
for (const aiState of this._lastAIState)
|
|
if (aiState["aiid"] === aiId) {
|
|
aiState["isPlaying"] = false;
|
|
break
|
|
}
|
|
await this.TriggerAsync(C3.Plugins.Audio.Cnds.OnEnded)
|
|
} else if (type === "fade-ended")
|
|
await this.TriggerAsync(C3.Plugins.Audio.Cnds.OnFadeEnded)
|
|
}
|
|
Tick() {
|
|
const o = {
|
|
"timeScale": this._runtime.GetTimeScale(),
|
|
"gameTime": this._runtime.GetGameTime(),
|
|
"instPans": this.GetInstancePans(),
|
|
"tickCount": this._runtime.GetTickCountNoSave()
|
|
};
|
|
if (this._listenerInst) {
|
|
const wi = this._listenerInst.GetWorldInfo();
|
|
this._listenerX = wi.GetX();
|
|
this._listenerY = wi.GetY();
|
|
o["listenerPos"] = [this._listenerX, this._listenerY, this._listenerZ]
|
|
}
|
|
this.PostToDOM("tick", o)
|
|
}
|
|
rotatePtAround(px, py, a, ox, oy) {
|
|
if (a === 0)
|
|
return [px, py];
|
|
const sin_a = Math.sin(a);
|
|
const cos_a = Math.cos(a);
|
|
px -= ox;
|
|
py -= oy;
|
|
const left_sin_a = px * sin_a;
|
|
const top_sin_a = py * sin_a;
|
|
const left_cos_a = px * cos_a;
|
|
const top_cos_a = py * cos_a;
|
|
px = left_cos_a - top_sin_a;
|
|
py = top_cos_a + left_sin_a;
|
|
px += ox;
|
|
py += oy;
|
|
return [px, py]
|
|
}
|
|
GetInstancePans() {
|
|
return this._lastAIState.filter(ai=>ai["uid"] !== -1).map(ai=>this._runtime.GetInstanceByUID(ai["uid"])).filter(inst=>inst).map(inst=>{
|
|
const wi = inst.GetWorldInfo();
|
|
const layerAngle = wi.GetLayer().GetAngle();
|
|
const [x,y] = this.rotatePtAround(wi.GetX(), wi.GetY(), -layerAngle, this._listenerX, this._listenerY);
|
|
return {
|
|
"uid": inst.GetUID(),
|
|
"x": x,
|
|
"y": y,
|
|
"angle": wi.GetAngle() - layerAngle
|
|
}
|
|
}
|
|
)
|
|
}
|
|
GetAnalyserData(tag, index) {
|
|
for (const o of this._lastAnalysersData)
|
|
if (o.index === index && C3.equalsNoCase(o.tag, tag))
|
|
return o;
|
|
return null
|
|
}
|
|
_IncrementEffectCount(tag) {
|
|
this._effectCount.set(tag, (this._effectCount.get(tag) || 0) + 1)
|
|
}
|
|
_ShouldSave(ai) {
|
|
if (ai.hasOwnProperty("placeholder"))
|
|
return false;
|
|
if (this._saveLoadMode === 3)
|
|
return false;
|
|
else if (ai["isMusic"] && this._saveLoadMode === 1)
|
|
return false;
|
|
else if (!ai["isMusic"] && this._saveLoadMode === 2)
|
|
return false;
|
|
else
|
|
return true
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"isSilent": this._isSilent,
|
|
"masterVolume": this._masterVolume,
|
|
"listenerZ": this._listenerZ,
|
|
"listenerUid": this._listenerInst ? this._listenerInst.GetUID() : -1,
|
|
"remoteUrls": [...this._remoteUrls.entries()],
|
|
"playing": this._lastAIState.filter(ai=>this._ShouldSave(ai)),
|
|
"effects": this._lastFxState,
|
|
"analysers": this._lastAnalysersData
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this._isSilent = o["isSilent"];
|
|
this._masterVolume = o["masterVolume"];
|
|
this._listenerZ = o["listenerZ"];
|
|
this._listenerInst = null;
|
|
this._loadListenerUid = o["listenerUid"];
|
|
this._remoteUrls.clear();
|
|
if (o["remoteUrls"])
|
|
for (const [k,v] of o["remoteUrls"])
|
|
this._remoteUrls.set(k, v);
|
|
this._lastAIState = o["playing"];
|
|
this._lastFxState = o["effects"];
|
|
this._lastAnalysersData = o["analysers"]
|
|
}
|
|
_OnAfterLoad() {
|
|
if (this._loadListenerUid !== -1) {
|
|
this._listenerInst = this._runtime.GetInstanceByUID(this._loadListenerUid);
|
|
this._loadListenerUid = -1;
|
|
if (this._listenerInst) {
|
|
const wi = this._listenerInst.GetWorldInfo();
|
|
this._listenerX = wi.GetX();
|
|
this._listenerY = wi.GetY()
|
|
}
|
|
}
|
|
for (const ai of this._lastAIState) {
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(ai["bufferOriginalUrl"]);
|
|
if (info) {
|
|
ai["bufferUrl"] = info.url;
|
|
ai["bufferType"] = info.type
|
|
} else
|
|
ai["bufferUrl"] = null
|
|
}
|
|
for (const fxChainData of Object.values(this._lastFxState))
|
|
for (const fxData of fxChainData)
|
|
if (fxData.hasOwnProperty("bufferOriginalUrl")) {
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(fxData["bufferOriginalUrl"]);
|
|
if (info) {
|
|
fxData["bufferUrl"] = info.url;
|
|
fxData["bufferType"] = info.type
|
|
}
|
|
}
|
|
this.PostToDOM("load-state", {
|
|
"saveLoadMode": this._saveLoadMode,
|
|
"timeScale": this._runtime.GetTimeScale(),
|
|
"gameTime": this._runtime.GetGameTime(),
|
|
"listenerPos": [this._listenerX, this._listenerY, this._listenerZ],
|
|
"isSilent": this._isSilent,
|
|
"masterVolume": this._masterVolume,
|
|
"playing": this._lastAIState.filter(ai=>ai["bufferUrl"] !== null),
|
|
"effects": this._lastFxState
|
|
})
|
|
}
|
|
GetDebuggerProperties() {
|
|
const fxProps = [];
|
|
for (const [tag,fxChainData] of Object.entries(this._lastFxState))
|
|
fxProps.push({
|
|
name: "$" + tag,
|
|
value: fxChainData.map(d=>d["type"]).join(", ")
|
|
});
|
|
const prefix = "plugins.audio.debugger";
|
|
return [{
|
|
title: prefix + ".tag-effects",
|
|
properties: fxProps
|
|
}, {
|
|
title: prefix + ".currently-playing",
|
|
properties: [{
|
|
name: prefix + ".currently-playing-count",
|
|
value: this._lastAIState.length
|
|
}, ...this._lastAIState.map((s,index)=>({
|
|
name: "$#" + index,
|
|
value: `${s["bufferOriginalUrl"]} ("${s["tag"]}") ${Math.round(s["playbackTime"] * 10) / 10} / ${Math.round(s["duration"] * 10) / 10}`
|
|
}))]
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Audio.Cnds = {
|
|
OnEnded(tag) {
|
|
return C3.equalsNoCase(this._triggerTag, tag)
|
|
},
|
|
OnFadeEnded(tag) {
|
|
return C3.equalsNoCase(this._triggerTag, tag)
|
|
},
|
|
PreloadsComplete() {
|
|
return this._preloadCount === this._preloadTotal
|
|
},
|
|
AdvancedAudioSupported() {
|
|
return true
|
|
},
|
|
IsSilent() {
|
|
return this._isSilent
|
|
},
|
|
IsAnyPlaying() {
|
|
for (const ai of this._lastAIState)
|
|
if (ai["isPlaying"])
|
|
return true;
|
|
return false
|
|
},
|
|
IsTagPlaying(tag) {
|
|
return this._IsTagPlaying(tag)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const FILTER_TYPES = ["lowpass", "highpass", "bandpass", "lowshelf", "highshelf", "peaking", "notch", "allpass"];
|
|
C3.Plugins.Audio.Acts = {
|
|
async Play(file, looping, vol, tag) {
|
|
if (this._isSilent)
|
|
return;
|
|
const isMusic = file[1];
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(file[0]);
|
|
if (!info)
|
|
return;
|
|
const nextPlayTime = this._nextPlayTime;
|
|
this._nextPlayTime = 0;
|
|
const state = this._MaybeMarkAsPlaying(tag.toLowerCase(), isMusic, looping !== 0, this.DbToLinear(vol));
|
|
try {
|
|
await this.PostToDOMAsync("play", {
|
|
"originalUrl": file[0],
|
|
"url": info.url,
|
|
"type": info.type,
|
|
"isMusic": isMusic,
|
|
"tag": tag.toLowerCase(),
|
|
"isLooping": looping !== 0,
|
|
"vol": this.DbToLinear(vol),
|
|
"pos": 0,
|
|
"off": nextPlayTime,
|
|
"trueClock": !!self["C3_GetAudioContextCurrentTime"]
|
|
})
|
|
} finally {
|
|
if (state)
|
|
state["placeholder"] = this._runtime.GetTickCountNoSave()
|
|
}
|
|
},
|
|
async PlayAtPosition(file, looping, vol, x, y, angle, innerAngle, outerAngle, outerGain, tag) {
|
|
if (this._isSilent)
|
|
return;
|
|
const isMusic = file[1];
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(file[0]);
|
|
if (!info)
|
|
return;
|
|
const nextPlayTime = this._nextPlayTime;
|
|
this._nextPlayTime = 0;
|
|
const state = this._MaybeMarkAsPlaying(tag.toLowerCase(), isMusic, looping !== 0, this.DbToLinear(vol));
|
|
try {
|
|
await this.PostToDOMAsync("play", {
|
|
"originalUrl": file[0],
|
|
"url": info.url,
|
|
"type": info.type,
|
|
"isMusic": isMusic,
|
|
"tag": tag.toLowerCase(),
|
|
"isLooping": looping !== 0,
|
|
"vol": this.DbToLinear(vol),
|
|
"pos": 0,
|
|
"off": nextPlayTime,
|
|
"trueClock": !!self["C3_GetAudioContextCurrentTime"],
|
|
"panning": {
|
|
"x": x,
|
|
"y": y,
|
|
"angle": C3.toRadians(angle),
|
|
"innerAngle": C3.toRadians(innerAngle),
|
|
"outerAngle": C3.toRadians(outerAngle),
|
|
"outerGain": this.DbToLinear(outerGain)
|
|
}
|
|
})
|
|
} finally {
|
|
if (state)
|
|
state["placeholder"] = this._runtime.GetTickCountNoSave()
|
|
}
|
|
},
|
|
async PlayAtObject(file, looping, vol, objectClass, innerAngle, outerAngle, outerGain, tag) {
|
|
if (this._isSilent)
|
|
return;
|
|
if (!objectClass)
|
|
return;
|
|
const inst = objectClass.GetFirstPicked();
|
|
if (!inst || !inst.GetWorldInfo())
|
|
return;
|
|
const wi = inst.GetWorldInfo();
|
|
const layerAngle = wi.GetLayer().GetAngle();
|
|
const [x,y] = this.rotatePtAround(wi.GetX(), wi.GetY(), -layerAngle, this._listenerX, this._listenerY);
|
|
const isMusic = file[1];
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(file[0]);
|
|
if (!info)
|
|
return;
|
|
const nextPlayTime = this._nextPlayTime;
|
|
this._nextPlayTime = 0;
|
|
const state = this._MaybeMarkAsPlaying(tag.toLowerCase(), isMusic, looping !== 0, this.DbToLinear(vol));
|
|
try {
|
|
await this.PostToDOMAsync("play", {
|
|
"originalUrl": file[0],
|
|
"url": info.url,
|
|
"type": info.type,
|
|
"isMusic": isMusic,
|
|
"tag": tag.toLowerCase(),
|
|
"isLooping": looping !== 0,
|
|
"vol": this.DbToLinear(vol),
|
|
"pos": 0,
|
|
"off": nextPlayTime,
|
|
"trueClock": !!self["C3_GetAudioContextCurrentTime"],
|
|
"panning": {
|
|
"x": x,
|
|
"y": y,
|
|
"angle": wi.GetAngle() - layerAngle,
|
|
"innerAngle": C3.toRadians(innerAngle),
|
|
"outerAngle": C3.toRadians(outerAngle),
|
|
"outerGain": this.DbToLinear(outerGain),
|
|
"uid": inst.GetUID()
|
|
}
|
|
})
|
|
} finally {
|
|
if (state)
|
|
state["placeholder"] = this._runtime.GetTickCountNoSave()
|
|
}
|
|
},
|
|
async PlayByName(folder, filename, looping, vol, tag) {
|
|
if (this._isSilent)
|
|
return;
|
|
const isMusic = folder === 1;
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(filename) || this._remoteUrls.get(filename.toLowerCase());
|
|
if (!info)
|
|
return;
|
|
const nextPlayTime = this._nextPlayTime;
|
|
this._nextPlayTime = 0;
|
|
const state = this._MaybeMarkAsPlaying(tag.toLowerCase(), isMusic, looping !== 0, this.DbToLinear(vol));
|
|
try {
|
|
await this.PostToDOMAsync("play", {
|
|
"originalUrl": filename,
|
|
"url": info.url,
|
|
"type": info.type,
|
|
"isMusic": isMusic,
|
|
"tag": tag.toLowerCase(),
|
|
"isLooping": looping !== 0,
|
|
"vol": this.DbToLinear(vol),
|
|
"pos": 0,
|
|
"off": nextPlayTime,
|
|
"trueClock": !!self["C3_GetAudioContextCurrentTime"]
|
|
})
|
|
} finally {
|
|
if (state)
|
|
state["placeholder"] = this._runtime.GetTickCountNoSave()
|
|
}
|
|
},
|
|
async PlayAtPositionByName(folder, filename, looping, vol, x, y, angle, innerAngle, outerAngle, outerGain, tag) {
|
|
if (this._isSilent)
|
|
return;
|
|
const isMusic = folder === 1;
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(filename) || this._remoteUrls.get(filename.toLowerCase());
|
|
if (!info)
|
|
return;
|
|
const nextPlayTime = this._nextPlayTime;
|
|
this._nextPlayTime = 0;
|
|
const state = this._MaybeMarkAsPlaying(tag.toLowerCase(), isMusic, looping !== 0, this.DbToLinear(vol));
|
|
try {
|
|
await this.PostToDOMAsync("play", {
|
|
"originalUrl": filename,
|
|
"url": info.url,
|
|
"type": info.type,
|
|
"isMusic": isMusic,
|
|
"tag": tag.toLowerCase(),
|
|
"isLooping": looping !== 0,
|
|
"vol": this.DbToLinear(vol),
|
|
"pos": 0,
|
|
"off": nextPlayTime,
|
|
"trueClock": !!self["C3_GetAudioContextCurrentTime"],
|
|
"panning": {
|
|
"x": x,
|
|
"y": y,
|
|
"angle": C3.toRadians(angle),
|
|
"innerAngle": C3.toRadians(innerAngle),
|
|
"outerAngle": C3.toRadians(outerAngle),
|
|
"outerGain": this.DbToLinear(outerGain)
|
|
}
|
|
})
|
|
} finally {
|
|
if (state)
|
|
state["placeholder"] = this._runtime.GetTickCountNoSave()
|
|
}
|
|
},
|
|
async PlayAtObjectByName(folder, filename, looping, vol, objectClass, innerAngle, outerAngle, outerGain, tag) {
|
|
if (this._isSilent)
|
|
return;
|
|
if (this._isSilent)
|
|
return;
|
|
if (!objectClass)
|
|
return;
|
|
const inst = objectClass.GetFirstPicked();
|
|
if (!inst || !inst.GetWorldInfo())
|
|
return;
|
|
const wi = inst.GetWorldInfo();
|
|
const layerAngle = wi.GetLayer().GetAngle();
|
|
const [x,y] = this.rotatePtAround(wi.GetX(), wi.GetY(), -layerAngle, this._listenerX, this._listenerY);
|
|
const isMusic = folder === 1;
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(filename) || this._remoteUrls.get(filename.toLowerCase());
|
|
if (!info)
|
|
return;
|
|
const nextPlayTime = this._nextPlayTime;
|
|
this._nextPlayTime = 0;
|
|
const state = this._MaybeMarkAsPlaying(tag.toLowerCase(), isMusic, looping !== 0, this.DbToLinear(vol));
|
|
try {
|
|
await this.PostToDOMAsync("play", {
|
|
"originalUrl": filename,
|
|
"url": info.url,
|
|
"type": info.type,
|
|
"isMusic": isMusic,
|
|
"tag": tag.toLowerCase(),
|
|
"isLooping": looping !== 0,
|
|
"vol": this.DbToLinear(vol),
|
|
"pos": 0,
|
|
"off": nextPlayTime,
|
|
"trueClock": !!self["C3_GetAudioContextCurrentTime"],
|
|
"panning": {
|
|
"x": x,
|
|
"y": y,
|
|
"angle": wi.GetAngle() - layerAngle,
|
|
"innerAngle": C3.toRadians(innerAngle),
|
|
"outerAngle": C3.toRadians(outerAngle),
|
|
"outerGain": this.DbToLinear(outerGain),
|
|
"uid": inst.GetUID()
|
|
}
|
|
})
|
|
} finally {
|
|
if (state)
|
|
state["placeholder"] = this._runtime.GetTickCountNoSave()
|
|
}
|
|
},
|
|
SetLooping(tag, looping) {
|
|
this.PostToDOM("set-looping", {
|
|
"tag": tag.toLowerCase(),
|
|
"isLooping": looping === 0
|
|
})
|
|
},
|
|
SetMuted(tag, muted) {
|
|
this.PostToDOM("set-muted", {
|
|
"tag": tag.toLowerCase(),
|
|
"isMuted": muted === 0
|
|
})
|
|
},
|
|
SetVolume(tag, vol) {
|
|
this.PostToDOM("set-volume", {
|
|
"tag": tag.toLowerCase(),
|
|
"vol": this.DbToLinear(vol)
|
|
})
|
|
},
|
|
FadeVolume(tag, vol, duration, ending) {
|
|
this.PostToDOM("fade-volume", {
|
|
"tag": tag.toLowerCase(),
|
|
"vol": this.DbToLinear(vol),
|
|
"duration": duration,
|
|
"stopOnEnd": ending === 0
|
|
})
|
|
},
|
|
async Preload(file) {
|
|
const isMusic = file[1];
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(file[0]);
|
|
if (!info)
|
|
return;
|
|
this._preloadTotal++;
|
|
await this.PostToDOMAsync("preload", {
|
|
"originalUrl": file[0],
|
|
"url": info.url,
|
|
"type": info.type,
|
|
"isMusic": isMusic
|
|
});
|
|
this._preloadCount++
|
|
},
|
|
async PreloadByName(folder, filename) {
|
|
const isMusic = folder === 1;
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(filename) || this._remoteUrls.get(filename.toLowerCase());
|
|
if (!info)
|
|
return;
|
|
this._preloadTotal++;
|
|
await this.PostToDOMAsync("preload", {
|
|
"originalUrl": filename,
|
|
"url": info.url,
|
|
"type": info.type,
|
|
"isMusic": isMusic
|
|
});
|
|
this._preloadCount++
|
|
},
|
|
SetPlaybackRate(tag, rate) {
|
|
this.PostToDOM("set-playback-rate", {
|
|
"tag": tag.toLowerCase(),
|
|
"rate": Math.max(rate, 0)
|
|
})
|
|
},
|
|
Stop(tag) {
|
|
this.PostToDOM("stop", {
|
|
"tag": tag.toLowerCase()
|
|
})
|
|
},
|
|
StopAll() {
|
|
this.PostToDOM("stop-all")
|
|
},
|
|
SetPaused(tag, state) {
|
|
this.PostToDOM("set-paused", {
|
|
"tag": tag.toLowerCase(),
|
|
"paused": state === 0
|
|
})
|
|
},
|
|
Seek(tag, pos) {
|
|
this.PostToDOM("seek", {
|
|
"tag": tag.toLowerCase(),
|
|
"pos": pos
|
|
})
|
|
},
|
|
SetSilent(s) {
|
|
if (s === 2)
|
|
s = this._isSilent ? 1 : 0;
|
|
s = s === 0;
|
|
if (this._isSilent === s)
|
|
return;
|
|
this._isSilent = s;
|
|
this.PostToDOM("set-silent", {
|
|
"isSilent": s
|
|
})
|
|
},
|
|
SetMasterVolume(vol) {
|
|
const mv = this.DbToLinear(vol);
|
|
if (this._masterVolume === mv)
|
|
return;
|
|
this._masterVolume = mv;
|
|
this.PostToDOM("set-master-volume", {
|
|
"vol": mv
|
|
})
|
|
},
|
|
AddFilterEffect(tag, type, freq, detune, q, gain, mix) {
|
|
tag = tag.toLowerCase();
|
|
const typeStr = FILTER_TYPES[type];
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "filter",
|
|
"tag": tag,
|
|
"params": [typeStr, freq, detune, q, gain, C3.clamp(mix / 100, 0, 1)]
|
|
})
|
|
},
|
|
AddDelayEffect(tag, delay, gain, mix) {
|
|
tag = tag.toLowerCase();
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "delay",
|
|
"tag": tag,
|
|
"params": [delay, this.DbToLinear(gain), C3.clamp(mix / 100, 0, 1)]
|
|
})
|
|
},
|
|
AddFlangerEffect(tag, delay, modulation, freq, feedback, mix) {
|
|
tag = tag.toLowerCase();
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "flanger",
|
|
"tag": tag,
|
|
"params": [delay / 1E3, modulation / 1E3, freq, feedback / 100, C3.clamp(mix / 100, 0, 1)]
|
|
})
|
|
},
|
|
AddPhaserEffect(tag, freq, detune, q, mod, modfreq, mix) {
|
|
tag = tag.toLowerCase();
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "phaser",
|
|
"tag": tag,
|
|
"params": [freq, detune, q, mod, modfreq, C3.clamp(mix / 100, 0, 1)]
|
|
})
|
|
},
|
|
AddConvolutionEffect(tag, file, norm, mix) {
|
|
tag = tag.toLowerCase();
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(file[0]);
|
|
if (!info)
|
|
return;
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "convolution",
|
|
"tag": tag,
|
|
"bufferOriginalUrl": file[0],
|
|
"bufferUrl": info.url,
|
|
"bufferType": info.type,
|
|
"params": [norm === 0, C3.clamp(mix / 100, 0, 1)]
|
|
})
|
|
},
|
|
AddGainEffect(tag, g) {
|
|
tag = tag.toLowerCase();
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "gain",
|
|
"tag": tag,
|
|
"params": [this.DbToLinear(g)]
|
|
})
|
|
},
|
|
AddMuteEffect(tag) {
|
|
tag = tag.toLowerCase();
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "gain",
|
|
"tag": tag,
|
|
"params": [0]
|
|
})
|
|
},
|
|
AddTremoloEffect(tag, freq, mix) {
|
|
tag = tag.toLowerCase();
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "tremolo",
|
|
"tag": tag,
|
|
"params": [freq, C3.clamp(mix / 100, 0, 1)]
|
|
})
|
|
},
|
|
AddRingModEffect(tag, freq, mix) {
|
|
tag = tag.toLowerCase();
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "ringmod",
|
|
"tag": tag,
|
|
"params": [freq, C3.clamp(mix / 100, 0, 1)]
|
|
})
|
|
},
|
|
AddDistortionEffect(tag, threshold, headroom, drive, makeupgain, mix) {
|
|
tag = tag.toLowerCase();
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "distortion",
|
|
"tag": tag,
|
|
"params": [this.DbToLinearNoCap(threshold), this.DbToLinearNoCap(headroom), drive, this.DbToLinearNoCap(makeupgain), C3.clamp(mix / 100, 0, 1)]
|
|
})
|
|
},
|
|
AddCompressorEffect(tag, threshold, knee, ratio, attack, release) {
|
|
tag = tag.toLowerCase();
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "compressor",
|
|
"tag": tag,
|
|
"params": [threshold, knee, ratio, attack / 1E3, release / 1E3]
|
|
})
|
|
},
|
|
AddAnalyserEffect(tag, fftSize, smoothing) {
|
|
tag = tag.toLowerCase();
|
|
this._IncrementEffectCount(tag);
|
|
this.PostToDOM("add-effect", {
|
|
"type": "analyser",
|
|
"tag": tag,
|
|
"params": [fftSize, smoothing]
|
|
})
|
|
},
|
|
RemoveEffects(tag) {
|
|
tag = tag.toLowerCase();
|
|
this._effectCount.set(tag, 0);
|
|
this.PostToDOM("remove-effects", {
|
|
"tag": tag
|
|
});
|
|
this._lastFxState = {}
|
|
},
|
|
SetEffectParameter(tag, index, param, value, ramp, time) {
|
|
this.PostToDOM("set-effect-param", {
|
|
"tag": tag.toLowerCase(),
|
|
"index": Math.floor(index),
|
|
"param": param,
|
|
"value": value,
|
|
"ramp": ramp,
|
|
"time": time
|
|
})
|
|
},
|
|
SetListenerObject(objectClass) {
|
|
if (!objectClass)
|
|
return;
|
|
const inst = objectClass.GetFirstPicked();
|
|
if (!inst || !inst.GetWorldInfo())
|
|
return;
|
|
this._listenerInst = inst
|
|
},
|
|
SetListenerZ(z) {
|
|
this._listenerZ = z
|
|
},
|
|
ScheduleNextPlay(t) {
|
|
this._nextPlayTime = Math.max(t, 0)
|
|
},
|
|
UnloadAudio(file) {
|
|
const isMusic = file[1];
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(file[0]);
|
|
if (!info)
|
|
return;
|
|
this.PostToDOM("unload", {
|
|
"url": info.url,
|
|
"type": info.type,
|
|
"isMusic": isMusic
|
|
})
|
|
},
|
|
UnloadAudioByName(folder, filename) {
|
|
const isMusic = folder === 1;
|
|
const info = this._runtime.GetAssetManager().GetProjectAudioFileUrl(filename) || this._remoteUrls.get(filename.toLowerCase());
|
|
if (!info)
|
|
return;
|
|
this.PostToDOM("unload", {
|
|
"url": info.url,
|
|
"type": info.type,
|
|
"isMusic": isMusic
|
|
})
|
|
},
|
|
UnloadAll() {
|
|
this.PostToDOM("unload-all")
|
|
},
|
|
AddRemoteURL(url, type, name) {
|
|
this._remoteUrls.set(name.toLowerCase(), {
|
|
url,
|
|
type
|
|
})
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.Audio.Exps = {
|
|
Duration(tag) {
|
|
const a = this._GetFirstAudioStateByTag(tag);
|
|
return a ? a["duration"] : 0
|
|
},
|
|
PlaybackTime(tag) {
|
|
const a = this._GetFirstAudioStateByTag(tag);
|
|
return a ? a["playbackTime"] : 0
|
|
},
|
|
PlaybackRate(tag) {
|
|
const a = this._GetFirstAudioStateByTag(tag);
|
|
return a ? a["playbackRate"] : 0
|
|
},
|
|
Volume(tag) {
|
|
const a = this._GetFirstAudioStateByTag(tag);
|
|
return a ? this.LinearToDb(a["volume"]) : 0
|
|
},
|
|
MasterVolume() {
|
|
return this.LinearToDb(this._masterVolume)
|
|
},
|
|
EffectCount(tag) {
|
|
return this._effectCount.get(tag.toLowerCase()) || 0
|
|
},
|
|
AnalyserFreqBinCount(tag, index) {
|
|
const o = this.GetAnalyserData(tag, Math.floor(index));
|
|
return o ? o["binCount"] : 0
|
|
},
|
|
AnalyserFreqBinAt(tag, index, bin) {
|
|
const o = this.GetAnalyserData(tag, Math.floor(index));
|
|
if (!o)
|
|
return 0;
|
|
bin = Math.floor(bin);
|
|
if (bin < 0 || bin >= o["binCount"])
|
|
return 0;
|
|
return o["freqBins"][bin]
|
|
},
|
|
AnalyserPeakLevel(tag, index) {
|
|
const o = this.GetAnalyserData(tag, Math.floor(index));
|
|
return o ? o["peak"] : 0
|
|
},
|
|
AnalyserRMSLevel(tag, index) {
|
|
const o = this.GetAnalyserData(tag, Math.floor(index));
|
|
return o ? o["rms"] : 0
|
|
},
|
|
SampleRate() {
|
|
return this._sampleRate
|
|
},
|
|
CurrentTime() {
|
|
if (self["C3_GetAudioContextCurrentTime"])
|
|
return self["C3_GetAudioContextCurrentTime"]();
|
|
else
|
|
return performance.now() / 1E3
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.LocalStorage = class LocalStoragePlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.LocalStorage.Type = class LocalStorageType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.LocalStorage.Instance = class LocalStorageInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this._currentKey = "";
|
|
this._lastValue = "";
|
|
this._keyNamesList = [];
|
|
this._errorMessage = "";
|
|
this._pendingGets = 0;
|
|
this._pendingSets = 0;
|
|
this._storage = this._runtime._GetProjectStorage();
|
|
this._debugCache = new Map;
|
|
this._isLoadingDebugCache = false
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
async _TriggerStorageError(err) {
|
|
this._errorMessage = this._GetErrorString(err);
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnError)
|
|
}
|
|
_GetErrorString(err) {
|
|
if (!err)
|
|
return "unknown error";
|
|
else if (typeof err === "string")
|
|
return err;
|
|
else if (typeof err.message === "string")
|
|
return err.message;
|
|
else if (typeof err.name === "string")
|
|
return err.name;
|
|
else if (typeof err.data === "string")
|
|
return err.data;
|
|
else
|
|
return "unknown error"
|
|
}
|
|
GetDebuggerProperties() {
|
|
if (!this._isLoadingDebugCache)
|
|
this._DebugCacheStorage();
|
|
return [{
|
|
title: "plugins.localstorage.name",
|
|
properties: [...this._debugCache.entries()].map(entry=>({
|
|
name: "$" + entry[0],
|
|
value: entry[1],
|
|
onedit: v=>this._storage.setItem(entry[0], v)
|
|
}))
|
|
}]
|
|
}
|
|
async _DebugCacheStorage() {
|
|
this._isLoadingDebugCache = true;
|
|
try {
|
|
const keyList = await this._storage.keys();
|
|
keyList.sort((a,b)=>{
|
|
const la = a.toLowerCase();
|
|
const lb = b.toLowerCase();
|
|
if (la < lb)
|
|
return -1;
|
|
else if (lb < la)
|
|
return 1;
|
|
else
|
|
return 0
|
|
}
|
|
);
|
|
const values = await Promise.all(keyList.map(key=>this._storage.getItem(key)));
|
|
this._debugCache.clear();
|
|
for (let i = 0, len = keyList.length; i < len; ++i)
|
|
this._debugCache.set(keyList[i], values[i])
|
|
} catch (err) {
|
|
console.warn("[C3 debugger] Error displaying local storage: ", err)
|
|
} finally {
|
|
this._isLoadingDebugCache = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.LocalStorage.Cnds = {
|
|
OnItemSet(key) {
|
|
return this._currentKey === key
|
|
},
|
|
OnAnyItemSet() {
|
|
return true
|
|
},
|
|
OnItemGet(key) {
|
|
return this._currentKey === key
|
|
},
|
|
OnAnyItemGet() {
|
|
return true
|
|
},
|
|
OnItemRemoved(key) {
|
|
return this._currentKey === key
|
|
},
|
|
OnAnyItemRemoved() {
|
|
return true
|
|
},
|
|
OnCleared() {
|
|
return true
|
|
},
|
|
OnAllKeyNamesLoaded() {
|
|
return true
|
|
},
|
|
OnError() {
|
|
return true
|
|
},
|
|
OnItemExists(key) {
|
|
return this._currentKey === key
|
|
},
|
|
OnItemMissing(key) {
|
|
return this._currentKey === key
|
|
},
|
|
CompareKey(cmp, key) {
|
|
return C3.compare(this._currentKey, cmp, key)
|
|
},
|
|
CompareValue(cmp, v) {
|
|
return C3.compare(this._lastValue, cmp, v)
|
|
},
|
|
IsProcessingSets() {
|
|
return this._pendingSets > 0
|
|
},
|
|
IsProcessingGets() {
|
|
return this._pendingGets > 0
|
|
},
|
|
OnAllSetsComplete() {
|
|
return true
|
|
},
|
|
OnAllGetsComplete() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
function IsExpressionType(x) {
|
|
return typeof x === "string" || typeof x === "number"
|
|
}
|
|
C3.Plugins.LocalStorage.Acts = {
|
|
async SetItem(key, value) {
|
|
this._pendingSets++;
|
|
try {
|
|
const valueSet = await this._storage.setItem(key, value);
|
|
await this.ScheduleTriggers(async()=>{
|
|
this._currentKey = key;
|
|
this._lastValue = valueSet;
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnAnyItemSet);
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnItemSet)
|
|
}
|
|
)
|
|
} catch (err) {
|
|
await this._TriggerStorageError(err)
|
|
} finally {
|
|
this._pendingSets--;
|
|
if (this._pendingSets === 0)
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnAllSetsComplete)
|
|
}
|
|
},
|
|
async SetBinaryItem(key, objectClass) {
|
|
if (!objectClass)
|
|
return;
|
|
const inst = objectClass.GetFirstPicked(this._inst);
|
|
if (!inst)
|
|
return;
|
|
const sdkInst = inst.GetSdkInstance();
|
|
if (!sdkInst)
|
|
return;
|
|
const buffer = sdkInst.GetArrayBufferReadOnly();
|
|
this._pendingSets++;
|
|
try {
|
|
await this._storage.setItem(key, buffer);
|
|
await this.ScheduleTriggers(async()=>{
|
|
this._currentKey = key;
|
|
this._lastValue = "";
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnAnyItemSet);
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnItemSet)
|
|
}
|
|
)
|
|
} catch (err) {
|
|
await this._TriggerStorageError(err)
|
|
} finally {
|
|
this._pendingSets--;
|
|
if (this._pendingSets === 0)
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnAllSetsComplete)
|
|
}
|
|
},
|
|
async GetItem(key) {
|
|
this._pendingGets++;
|
|
try {
|
|
const value = await this._storage.getItem(key);
|
|
await this.ScheduleTriggers(async()=>{
|
|
this._currentKey = key;
|
|
this._lastValue = IsExpressionType(value) ? value : "";
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnAnyItemGet);
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnItemGet)
|
|
}
|
|
)
|
|
} catch (err) {
|
|
await this._TriggerStorageError(err)
|
|
} finally {
|
|
this._pendingGets--;
|
|
if (this._pendingGets === 0)
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnAllGetsComplete)
|
|
}
|
|
},
|
|
async GetBinaryItem(key, objectClass) {
|
|
if (!objectClass)
|
|
return;
|
|
const inst = objectClass.GetFirstPicked(this._inst);
|
|
if (!inst)
|
|
return;
|
|
const sdkInst = inst.GetSdkInstance();
|
|
this._pendingGets++;
|
|
try {
|
|
let value = await this._storage.getItem(key);
|
|
value = value instanceof ArrayBuffer ? value : new ArrayBuffer(0);
|
|
await this.ScheduleTriggers(async()=>{
|
|
this._lastValue = "";
|
|
this._currentKey = key;
|
|
sdkInst.SetArrayBufferTransfer(value);
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnAnyItemGet);
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnItemGet)
|
|
}
|
|
)
|
|
} catch (err) {
|
|
await this._TriggerStorageError(err)
|
|
} finally {
|
|
this._pendingGets--;
|
|
if (this._pendingGets === 0)
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnAllGetsComplete)
|
|
}
|
|
},
|
|
async CheckItemExists(key) {
|
|
try {
|
|
const value = await this._storage.getItem(key);
|
|
await this.ScheduleTriggers(async()=>{
|
|
this._currentKey = key;
|
|
if (typeof value === "undefined" || value === null) {
|
|
this._lastValue = "";
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnItemMissing)
|
|
} else {
|
|
this._lastValue = IsExpressionType(value) ? value : "";
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnItemExists)
|
|
}
|
|
}
|
|
)
|
|
} catch (err) {
|
|
await this._TriggerStorageError(err)
|
|
}
|
|
},
|
|
async RemoveItem(key) {
|
|
try {
|
|
await this._storage.removeItem(key);
|
|
await this.ScheduleTriggers(async()=>{
|
|
this._currentKey = key;
|
|
this._lastValue = "";
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnAnyItemRemoved);
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnItemRemoved)
|
|
}
|
|
)
|
|
} catch (err) {
|
|
await this._TriggerStorageError(err)
|
|
}
|
|
},
|
|
async ClearStorage() {
|
|
try {
|
|
await this._storage.clear();
|
|
await this.ScheduleTriggers(async()=>{
|
|
this._currentKey = "";
|
|
this._lastValue = "";
|
|
C3.clearArray(this._keyNamesList);
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnCleared)
|
|
}
|
|
)
|
|
} catch (err) {
|
|
await this._TriggerStorageError(err)
|
|
}
|
|
},
|
|
async GetAllKeyNames() {
|
|
try {
|
|
const keyList = await this._storage.keys();
|
|
await this.ScheduleTriggers(async()=>{
|
|
this._keyNamesList = keyList;
|
|
await this.TriggerAsync(C3.Plugins.LocalStorage.Cnds.OnAllKeyNamesLoaded)
|
|
}
|
|
)
|
|
} catch (err) {
|
|
await this._TriggerStorageError(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.LocalStorage.Exps = {
|
|
ItemValue() {
|
|
return this._lastValue
|
|
},
|
|
Key() {
|
|
return this._currentKey
|
|
},
|
|
KeyCount() {
|
|
return this._keyNamesList.length
|
|
},
|
|
KeyAt(i) {
|
|
i = Math.floor(i);
|
|
if (i < 0 || i >= this._keyNamesList.length)
|
|
return "";
|
|
return this._keyNamesList[i]
|
|
},
|
|
ErrorMessage() {
|
|
return this._errorMessage
|
|
}
|
|
}
|
|
}
|
|
;"use strict";
|
|
function rstr_md5(s) {
|
|
return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
|
|
}
|
|
function rstr_hmac_md5(key, data) {
|
|
var bkey = rstr2binl(key);
|
|
if (bkey.length > 16)
|
|
bkey = binl_md5(bkey, key.length * 8);
|
|
var ipad = Array(16)
|
|
, opad = Array(16);
|
|
for (var i = 0; i < 16; i++) {
|
|
ipad[i] = bkey[i] ^ 0x36363636;
|
|
opad[i] = bkey[i] ^ 0x5C5C5C5C;
|
|
}
|
|
var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
|
|
return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
|
|
}
|
|
function rstr2any(input, encoding) {
|
|
var divisor = encoding.length;
|
|
var i, j, q, x, quotient;
|
|
var dividend = Array(Math.ceil(input.length / 2));
|
|
for (i = 0; i < dividend.length; i++) {
|
|
dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
|
|
}
|
|
var full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
|
|
var remainders = Array(full_length);
|
|
for (j = 0; j < full_length; j++) {
|
|
quotient = Array();
|
|
x = 0;
|
|
for (i = 0; i < dividend.length; i++) {
|
|
x = (x << 16) + dividend[i];
|
|
q = Math.floor(x / divisor);
|
|
x -= q * divisor;
|
|
if (quotient.length > 0 || q > 0)
|
|
quotient[quotient.length] = q;
|
|
}
|
|
remainders[j] = x;
|
|
dividend = quotient;
|
|
}
|
|
var output = "";
|
|
for (i = remainders.length - 1; i >= 0; i--)
|
|
output += encoding.charAt(remainders[i]);
|
|
return output;
|
|
}
|
|
function str2rstr_utf8(input) {
|
|
var output = "";
|
|
var i = -1;
|
|
var x, y;
|
|
while (++i < input.length) {
|
|
x = input.charCodeAt(i);
|
|
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
|
|
if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
|
|
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
|
|
i++;
|
|
}
|
|
if (x <= 0x7F)
|
|
output += String.fromCharCode(x);
|
|
else if (x <= 0x7FF)
|
|
output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), 0x80 | (x & 0x3F));
|
|
else if (x <= 0xFFFF)
|
|
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
|
|
else if (x <= 0x1FFFFF)
|
|
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
|
|
}
|
|
return output;
|
|
}
|
|
function str2rstr_utf16le(input) {
|
|
var output = "";
|
|
for (var i = 0; i < input.length; i++)
|
|
output += String.fromCharCode(input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF);
|
|
return output;
|
|
}
|
|
function str2rstr_utf16be(input) {
|
|
var output = "";
|
|
for (var i = 0; i < input.length; i++)
|
|
output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF);
|
|
return output;
|
|
}
|
|
function rstr2binl(input) {
|
|
var output = Array(input.length >> 2);
|
|
for (var i = 0; i < output.length; i++)
|
|
output[i] = 0;
|
|
for (var i = 0; i < input.length * 8; i += 8)
|
|
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
|
|
return output;
|
|
}
|
|
function binl2rstr(input) {
|
|
var output = "";
|
|
for (var i = 0; i < input.length * 32; i += 8)
|
|
output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
|
|
return output;
|
|
}
|
|
function binl_md5(x, len) {
|
|
x[len >> 5] |= 0x80 << ((len) % 32);
|
|
x[(((len + 64) >>> 9) << 4) + 14] = len;
|
|
var a = 1732584193;
|
|
var b = -271733879;
|
|
var c = -1732584194;
|
|
var d = 271733878;
|
|
for (var i = 0; i < x.length; i += 16) {
|
|
var olda = a;
|
|
var oldb = b;
|
|
var oldc = c;
|
|
var oldd = d;
|
|
a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
|
|
d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
|
|
c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
|
|
b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
|
|
a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
|
|
d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
|
|
c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
|
|
b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
|
|
a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
|
|
d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
|
|
c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
|
|
b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
|
|
a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
|
|
d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
|
|
c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
|
|
b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
|
|
a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
|
|
d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
|
|
c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
|
|
b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
|
|
a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
|
|
d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
|
|
c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
|
|
b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
|
|
a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
|
|
d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
|
|
c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
|
|
b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
|
|
a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
|
|
d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
|
|
c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
|
|
b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
|
|
a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
|
|
d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
|
|
c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
|
|
b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
|
|
a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
|
|
d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
|
|
c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
|
|
b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
|
|
a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
|
|
d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
|
|
c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
|
|
b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
|
|
a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
|
|
d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
|
|
c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
|
|
b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
|
|
a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
|
|
d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
|
|
c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
|
|
b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
|
|
a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
|
|
d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
|
|
c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
|
|
b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
|
|
a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
|
|
d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
|
|
c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
|
|
b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
|
|
a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
|
|
d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
|
|
c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
|
|
b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
|
|
a = safe_add(a, olda);
|
|
b = safe_add(b, oldb);
|
|
c = safe_add(c, oldc);
|
|
d = safe_add(d, oldd);
|
|
}
|
|
return Array(a, b, c, d);
|
|
}
|
|
function md5_cmn(q, a, b, x, s, t) {
|
|
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
|
|
}
|
|
function md5_ff(a, b, c, d, x, s, t) {
|
|
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
|
}
|
|
function md5_gg(a, b, c, d, x, s, t) {
|
|
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
|
}
|
|
function md5_hh(a, b, c, d, x, s, t) {
|
|
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
|
|
}
|
|
function md5_ii(a, b, c, d, x, s, t) {
|
|
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
|
|
}
|
|
function safe_add(x, y) {
|
|
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
|
|
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
|
return (msw << 16) | (lsw & 0xFFFF);
|
|
}
|
|
function bit_rol(num, cnt) {
|
|
return (num << cnt) | (num >>> (32 - cnt));
|
|
}
|
|
function rstr_sha1(s) {
|
|
return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
|
|
}
|
|
function rstr_hmac_sha1(key, data) {
|
|
var bkey = rstr2binb(key);
|
|
if (bkey.length > 16)
|
|
bkey = binb_sha1(bkey, key.length * 8);
|
|
var ipad = Array(16)
|
|
, opad = Array(16);
|
|
for (var i = 0; i < 16; i++) {
|
|
ipad[i] = bkey[i] ^ 0x36363636;
|
|
opad[i] = bkey[i] ^ 0x5C5C5C5C;
|
|
}
|
|
var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
|
|
return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
|
|
}
|
|
function rstr2binb(input) {
|
|
var output = Array(input.length >> 2);
|
|
for (var i = 0; i < output.length; i++)
|
|
output[i] = 0;
|
|
for (var i = 0; i < input.length * 8; i += 8)
|
|
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
|
|
return output;
|
|
}
|
|
function binb2rstr(input) {
|
|
var output = "";
|
|
for (var i = 0; i < input.length * 32; i += 8)
|
|
output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
|
|
return output;
|
|
}
|
|
function binb_sha1(x, len) {
|
|
x[len >> 5] |= 0x80 << (24 - len % 32);
|
|
x[((len + 64 >> 9) << 4) + 15] = len;
|
|
var w = Array(80);
|
|
var a = 1732584193;
|
|
var b = -271733879;
|
|
var c = -1732584194;
|
|
var d = 271733878;
|
|
var e = -1009589776;
|
|
for (var i = 0; i < x.length; i += 16) {
|
|
var olda = a;
|
|
var oldb = b;
|
|
var oldc = c;
|
|
var oldd = d;
|
|
var olde = e;
|
|
for (var j = 0; j < 80; j++) {
|
|
if (j < 16)
|
|
w[j] = x[i + j];
|
|
else
|
|
w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
|
|
var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));
|
|
e = d;
|
|
d = c;
|
|
c = bit_rol(b, 30);
|
|
b = a;
|
|
a = t;
|
|
}
|
|
a = safe_add(a, olda);
|
|
b = safe_add(b, oldb);
|
|
c = safe_add(c, oldc);
|
|
d = safe_add(d, oldd);
|
|
e = safe_add(e, olde);
|
|
}
|
|
return Array(a, b, c, d, e);
|
|
}
|
|
function sha1_ft(t, b, c, d) {
|
|
if (t < 20)
|
|
return (b & c) | ((~b) & d);
|
|
if (t < 40)
|
|
return b ^ c ^ d;
|
|
if (t < 60)
|
|
return (b & c) | (b & d) | (c & d);
|
|
return b ^ c ^ d;
|
|
}
|
|
function sha1_kt(t) {
|
|
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514;
|
|
}
|
|
function rstr_sha256(s) {
|
|
return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
|
|
}
|
|
function rstr_hmac_sha256(key, data) {
|
|
var bkey = rstr2binb(key);
|
|
if (bkey.length > 16)
|
|
bkey = binb_sha256(bkey, key.length * 8);
|
|
var ipad = Array(16)
|
|
, opad = Array(16);
|
|
for (var i = 0; i < 16; i++) {
|
|
ipad[i] = bkey[i] ^ 0x36363636;
|
|
opad[i] = bkey[i] ^ 0x5C5C5C5C;
|
|
}
|
|
var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
|
|
return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256));
|
|
}
|
|
function sha256_S(X, n) {
|
|
return (X >>> n) | (X << (32 - n));
|
|
}
|
|
function sha256_R(X, n) {
|
|
return (X >>> n);
|
|
}
|
|
function sha256_Ch(x, y, z) {
|
|
return ((x & y) ^ ((~x) & z));
|
|
}
|
|
function sha256_Maj(x, y, z) {
|
|
return ((x & y) ^ (x & z) ^ (y & z));
|
|
}
|
|
function sha256_Sigma0256(x) {
|
|
return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));
|
|
}
|
|
function sha256_Sigma1256(x) {
|
|
return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));
|
|
}
|
|
function sha256_Gamma0256(x) {
|
|
return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));
|
|
}
|
|
function sha256_Gamma1256(x) {
|
|
return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));
|
|
}
|
|
function sha256_Sigma0512(x) {
|
|
return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));
|
|
}
|
|
function sha256_Sigma1512(x) {
|
|
return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));
|
|
}
|
|
function sha256_Gamma0512(x) {
|
|
return (sha256_S(x, 1) ^ sha256_S(x, 8) ^ sha256_R(x, 7));
|
|
}
|
|
function sha256_Gamma1512(x) {
|
|
return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));
|
|
}
|
|
var sha256_K = new Array(1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,-778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998);
|
|
function binb_sha256(m, l) {
|
|
var HASH = new Array(1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225);
|
|
var W = new Array(64);
|
|
var a, b, c, d, e, f, g, h;
|
|
var i, j, T1, T2;
|
|
m[l >> 5] |= 0x80 << (24 - l % 32);
|
|
m[((l + 64 >> 9) << 4) + 15] = l;
|
|
for (i = 0; i < m.length; i += 16) {
|
|
a = HASH[0];
|
|
b = HASH[1];
|
|
c = HASH[2];
|
|
d = HASH[3];
|
|
e = HASH[4];
|
|
f = HASH[5];
|
|
g = HASH[6];
|
|
h = HASH[7];
|
|
for (j = 0; j < 64; j++) {
|
|
if (j < 16)
|
|
W[j] = m[j + i];
|
|
else
|
|
W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]), sha256_Gamma0256(W[j - 15])), W[j - 16]);
|
|
T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)), sha256_K[j]), W[j]);
|
|
T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
|
|
h = g;
|
|
g = f;
|
|
f = e;
|
|
e = safe_add(d, T1);
|
|
d = c;
|
|
c = b;
|
|
b = a;
|
|
a = safe_add(T1, T2);
|
|
}
|
|
HASH[0] = safe_add(a, HASH[0]);
|
|
HASH[1] = safe_add(b, HASH[1]);
|
|
HASH[2] = safe_add(c, HASH[2]);
|
|
HASH[3] = safe_add(d, HASH[3]);
|
|
HASH[4] = safe_add(e, HASH[4]);
|
|
HASH[5] = safe_add(f, HASH[5]);
|
|
HASH[6] = safe_add(g, HASH[6]);
|
|
HASH[7] = safe_add(h, HASH[7]);
|
|
}
|
|
return HASH;
|
|
}
|
|
{
|
|
C3.Plugins.CBhash = class CBhashPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.CBhash.Type = class CBhashType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.CBhash.Instance = class CBhashInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this._testProperty = 0;
|
|
this.lastResult = "";
|
|
this.hexcase = 0;
|
|
this.b64pad = " ";
|
|
if (properties) {}
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {};
|
|
}
|
|
LoadFromJson(o) {}
|
|
hex_md5(s) {
|
|
return this.rstr2hex(rstr_md5(str2rstr_utf8(s)));
|
|
}
|
|
b64_md5(s) {
|
|
return this.rstr2b64(rstr_md5(str2rstr_utf8(s)));
|
|
}
|
|
any_md5(s, e) {
|
|
return rstr2any(rstr_md5(str2rstr_utf8(s)), e);
|
|
}
|
|
hex_hmac_md5(k, d) {
|
|
return this.rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)));
|
|
}
|
|
b64_hmac_md5(k, d) {
|
|
return this.rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)));
|
|
}
|
|
any_hmac_md5(k, d, e) {
|
|
return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e);
|
|
}
|
|
hex_sha1(s) {
|
|
return this.rstr2hex(rstr_sha1(str2rstr_utf8(s)));
|
|
}
|
|
b64_sha1(s) {
|
|
return this.rstr2b64(rstr_sha1(str2rstr_utf8(s)));
|
|
}
|
|
any_sha1(s, e) {
|
|
return rstr2any(rstr_sha1(str2rstr_utf8(s)), e);
|
|
}
|
|
hex_hmac_sha1(k, d) {
|
|
return this.rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)));
|
|
}
|
|
b64_hmac_sha1(k, d) {
|
|
return this.rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)));
|
|
}
|
|
any_hmac_sha1(k, d, e) {
|
|
return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e);
|
|
}
|
|
hex_sha256(s) {
|
|
return this.rstr2hex(rstr_sha256(str2rstr_utf8(s)));
|
|
}
|
|
b64_sha256(s) {
|
|
return this.rstr2b64(rstr_sha256(str2rstr_utf8(s)));
|
|
}
|
|
any_sha256(s, e) {
|
|
return rstr2any(rstr_sha256(str2rstr_utf8(s)), e);
|
|
}
|
|
hex_hmac_sha256(k, d) {
|
|
return this.rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)));
|
|
}
|
|
b64_hmac_sha256(k, d) {
|
|
return this.rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)));
|
|
}
|
|
any_hmac_sha256(k, d, e) {
|
|
return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e);
|
|
}
|
|
rstr2hex(input) {
|
|
try {
|
|
this.hexcase
|
|
} catch (e) {
|
|
this.hexcase = 0;
|
|
}
|
|
var hex_tab = this.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
|
|
var output = "";
|
|
var x;
|
|
for (var i = 0; i < input.length; i++) {
|
|
x = input.charCodeAt(i);
|
|
output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
|
|
}
|
|
return output;
|
|
}
|
|
rstr2b64(input) {
|
|
try {
|
|
this.b64pad
|
|
} catch (e) {
|
|
this.b64pad = '';
|
|
}
|
|
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
var output = "";
|
|
var len = input.length;
|
|
for (var i = 0; i < len; i += 3) {
|
|
var triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
|
|
for (var j = 0; j < 4; j++) {
|
|
if (i * 8 + j * 6 > input.length * 8)
|
|
output += this.b64pad;
|
|
else
|
|
output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
|
|
}
|
|
}
|
|
return output;
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.CBhash.Cnds = {
|
|
OnHashed() {
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.CBhash.Acts = {
|
|
set_hexoutput(format) {
|
|
if (format == 0)
|
|
this.hexcase = 0;
|
|
else
|
|
this.hexcase = 1;
|
|
},
|
|
set_bpad(charac) {
|
|
this.b64pad = charac;
|
|
},
|
|
MD5_hash(string, format) {
|
|
var outF = format;
|
|
if (outF == 0)
|
|
this.lastResult = this.hex_md5(string);
|
|
else
|
|
this.lastResult = this.b64_md5(string);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
MD5_pass(string, encoding) {
|
|
this.lastResult = this.any_md5(string, encoding);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMAC_hash(key, data, Format) {
|
|
if (Format == 0)
|
|
this.lastResult = this.hex_hmac_md5(key, data);
|
|
else
|
|
this.lastResult = this.b64_hmac_md5(key, data);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMAC_pass(key, data, charString) {
|
|
this.lastResult = this.any_hmac_md5(key, data, charString);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
SHA1_hash(string, format) {
|
|
var outF = format;
|
|
if (outF == 0)
|
|
this.lastResult = this.hex_sha1(string);
|
|
else
|
|
this.lastResult = this.b64_sha1(string);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
SHA1_pass(string, encoding) {
|
|
this.lastResult = this.any_sha1(string, encoding);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACSHA1_hash(key, data, Format) {
|
|
if (Format == 0)
|
|
this.lastResult = this.hex_hmac_sha1(key, data);
|
|
else
|
|
this.lastResult = this.b64_hmac_sha1(key, data);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACSHA1_pass(key, data, charString) {
|
|
this.lastResult = this.any_hmac_sha1(key, data, charString);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
SHA256_hash(string, format) {
|
|
var outF = format;
|
|
if (outF == 0)
|
|
this.lastResult = this.hex_sha256(string);
|
|
else
|
|
this.lastResult = this.b64_sha256(string);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
SHA256_pass(string, encoding) {
|
|
this.lastResult = this.any_sha256(string, encoding);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACSHA256_hash(key, data, Format) {
|
|
if (Format == 0)
|
|
this.lastResult = this.hex_hmac_sha256(key, data);
|
|
else
|
|
this.lastResult = this.b64_hmac_sha256(key, data);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACSHA256_pass(key, data, charString) {
|
|
this.lastResult = this.any_hmac_sha256(key, data, charString);
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.CBhash.Exps = {
|
|
get_lastResult() {
|
|
return (this.lastResult);
|
|
},
|
|
MD5(data) {
|
|
return (this.hex_md5(data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
MD5B(data) {
|
|
return (this.b64_md5(data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
MD5pass(data, charstring) {
|
|
return (this.any_md5(data, charstring));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACMD5(key, data) {
|
|
return (this.hex_hmac_md5(key, data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACMD5B(key, data) {
|
|
return (this.b64_hmac_md5(key, data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACMD5pass(key, data, charstring) {
|
|
return (this.any_hmac_md5(key, data, charstring));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
SHA1(data) {
|
|
return (this.hex_sha1(data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
SHA1B(data) {
|
|
return (this.b64_sha1(data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
SHA1pass(data, charstring) {
|
|
return (this.any_sha1(data, charstring));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACSHA1(key, data) {
|
|
return (this.hex_hmac_sha1(key, data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACSHA1B(key, data) {
|
|
return (this.b64_hmac_sha1(key, data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACSHA1pass(key, data, charstring) {
|
|
return (this.any_hmac_sha1(key, data, charstring));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
SHA256(data) {
|
|
return (this.hex_sha256(data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
SHA256B(data) {
|
|
return (this.b64_sha256(data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
SHA256pass(data, charstring) {
|
|
return (this.any_sha256(data, charstring));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACSHA256(key, data) {
|
|
return (this.hex_hmac_sha256(key, data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACSHA256B(key, data) {
|
|
return (this.b64_hmac_sha256(key, data));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
},
|
|
HMACSHA256pass(key, data, charstring) {
|
|
return (this.any_hmac_sha256(key, data, charstring));
|
|
this.Trigger(C3.Plugins.CBhash.Cnds.OnHashed);
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Sparsha_copyclip = class copyclipPlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Sparsha_copyclip.Type = class copyclipType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
var textToCopy = "";
|
|
if (typeof document != "undefined")
|
|
var Input = document.createElement("input");
|
|
var onCopy = 0;
|
|
var errorClipboard = "";
|
|
var onErrorCopy = 0;
|
|
var onGet = 0;
|
|
var onErrorGet = 0;
|
|
var GetText = "";
|
|
{
|
|
C3.Plugins.Sparsha_copyclip.Instance = class copyclipInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
if (properties) {}
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {};
|
|
}
|
|
LoadFromJson(o) {}
|
|
GetDebuggerProperties() {
|
|
return [{
|
|
title: "copyclip",
|
|
properties: []
|
|
}];
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Sparsha_copyclip.Cnds = {
|
|
OnCopy() {
|
|
if (onCopy == 1) {
|
|
onCopy = 0;
|
|
return true;
|
|
} else
|
|
return false;
|
|
},
|
|
OnGet() {
|
|
if (onGet == 1) {
|
|
onGet = 0;
|
|
return true;
|
|
} else
|
|
return false;
|
|
},
|
|
OnCopyError() {
|
|
if (onErrorCopy == 1) {
|
|
onErrorCopy = 0;
|
|
return true;
|
|
} else
|
|
return false;
|
|
},
|
|
OnGetError() {
|
|
if (onErrorGet == 1) {
|
|
onErrorGet = 0;
|
|
return true;
|
|
} else
|
|
return false;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Sparsha_copyclip.Acts = {
|
|
Copy(Text, buttonId) {
|
|
textToCopy = Text;
|
|
Input.id = "Texty";
|
|
Input.value = textToCopy;
|
|
document.getElementById(buttonId).onclick = function() {
|
|
doCopy();
|
|
}
|
|
;
|
|
function doCopy() {
|
|
Input = document.createElement("input");
|
|
Input.id = "Texty";
|
|
Input.value = textToCopy;
|
|
document.getElementsByTagName('body')[0].appendChild(Input);
|
|
var copyText = document.getElementById("Texty");
|
|
copyText.select();
|
|
copyText.setSelectionRange(0, 99999);
|
|
document.execCommand("copy");
|
|
Input.remove();
|
|
}
|
|
},
|
|
async ApiCopy(Text) {
|
|
window.focus();
|
|
await navigator.clipboard.writeText(Text).then(()=>{
|
|
onCopy = 1;
|
|
}
|
|
).catch(err=>{
|
|
errorClipboard = err.message;
|
|
onErrorCopy = 1;
|
|
console.log("--Error Report----------------")
|
|
console.error("error: ", errorClipboard);
|
|
console.log("------------------------------")
|
|
}
|
|
);
|
|
},
|
|
async ApiGet() {
|
|
window.focus();
|
|
await navigator.clipboard.readText().then(Text=>{
|
|
GetText = Text;
|
|
onGet = 1;
|
|
}
|
|
).catch(err=>{
|
|
errorClipboard = err.message;
|
|
onErrorGet = 1;
|
|
console.log("--Error Report----------------")
|
|
console.error("error: ", errorClipboard);
|
|
console.log("------------------------------")
|
|
}
|
|
);
|
|
},
|
|
ClearError() {
|
|
errorClipboard = "";
|
|
onErrorCopy = 0;
|
|
onErrorGet = 0;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Sparsha_copyclip.Exps = {
|
|
clipboardData() {
|
|
return GetText;
|
|
},
|
|
error() {
|
|
return errorClipboard;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Massive_Cube_Forge = class ForgePlugin extends C3.SDKPluginBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Massive_Cube_Forge.Type = class ForgeType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Massive_Cube_Forge.Instance = class ForgeInstance extends C3.SDKInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst);
|
|
this.ky = undefined;
|
|
this.iv = undefined;
|
|
this.kyIsLongEnough = false;
|
|
this.IVIsLongEnough = false;
|
|
this.result = "";
|
|
if (properties) {}
|
|
this.cipher = undefined;
|
|
this.decipher = undefined;
|
|
this.forg = new globalThis["forge"];
|
|
this.encb64 = function(str) {
|
|
return this.forg.util.encode64(str);
|
|
}
|
|
this.decb64 = function(str) {
|
|
return this.forg.util.decode64(str);
|
|
}
|
|
this.psrand = function(lng) {
|
|
var bytes = this.forg.random.getBytesSync(lng);
|
|
return this.forg.util.bytesToHex(bytes);
|
|
}
|
|
this.sha1 = function(data, _this) {
|
|
var md = _this.forg.md.sha1.create();
|
|
md.update(data);
|
|
return md.digest().toHex();
|
|
}
|
|
this.sha256 = function(data, _this) {
|
|
var md = _this.forg.md.sha256.create();
|
|
md.update(data);
|
|
return md.digest().toHex();
|
|
}
|
|
this.sha384 = function(data, _this) {
|
|
var md = _this.forg.md.sha384.create();
|
|
md.update(data);
|
|
return md.digest().toHex();
|
|
}
|
|
this.sha512 = function(data, _this) {
|
|
var md = _this.forg.md.sha512.create();
|
|
md.update(data);
|
|
return md.digest().toHex();
|
|
}
|
|
this.md5 = function(data, _this) {
|
|
var md = _this.forg.md.md5.create();
|
|
md.update(data);
|
|
return md.digest().toHex();
|
|
}
|
|
this.clKAiV = function(_this) {
|
|
_this.ky = "";
|
|
_this.iv = "";
|
|
}
|
|
this.getTypeIDStr = function(id) {
|
|
switch (id) {
|
|
case 0:
|
|
return "AES-ECB";
|
|
break;
|
|
case 1:
|
|
return "AES-CBC";
|
|
break;
|
|
case 2:
|
|
return "AES-CFB";
|
|
break;
|
|
case 3:
|
|
return "AES-OFB";
|
|
break;
|
|
case 4:
|
|
return "AES-GCM";
|
|
break;
|
|
case 5:
|
|
return "3DES-ECB";
|
|
break;
|
|
case 6:
|
|
return "3DES-CBC";
|
|
break;
|
|
case 7:
|
|
return "DES-ECB";
|
|
break;
|
|
case 8:
|
|
return "DES-CBC";
|
|
break;
|
|
default:
|
|
return "AES-ECB";
|
|
}
|
|
}
|
|
this.encr = function(type, _this, text) {
|
|
var plaintext = text.toString();
|
|
var ky = _this.ky;
|
|
var objiv = {};
|
|
objiv["iv"] = _this.iv;
|
|
var cipher = _this.forg.cipher.createCipher(_this.getTypeIDStr(type), ky);
|
|
cipher.start(objiv);
|
|
cipher.update(_this.forg.util.createBuffer(plaintext));
|
|
cipher.finish();
|
|
var encrypted = cipher.output;
|
|
_this.result = _this.forg.util.encode64(encrypted.data);
|
|
}
|
|
this.decr = function(type, _this, text) {
|
|
var plaintext = text.toString();
|
|
var ky = _this.ky;
|
|
var objiv = {};
|
|
objiv["iv"] = _this.iv;
|
|
var decodedB64 = _this.forg.util.decode64(plaintext);
|
|
var input = _this.forg.util.createBuffer(decodedB64, 'binary');
|
|
input.getBytes(decodedB64);
|
|
var decipher = _this.forg.cipher.createDecipher(_this.getTypeIDStr(type), ky);
|
|
decipher.start(objiv);
|
|
decipher.update(input);
|
|
var result = decipher.finish();
|
|
_this.result = decipher.output.data;
|
|
}
|
|
this.setky = function(ky, _this) {
|
|
if ((ky.length == 16) || (ky.length == 24) || (ky.length == 32)) {
|
|
_this.ky = ky;
|
|
_this.kyIsLongEnough = true;
|
|
} else {
|
|
_this.kyIsLongEnough = false;
|
|
console.warn("ky is not 16, 24 or 32 chars long!");
|
|
}
|
|
}
|
|
this.setIV = function(iv, _this) {
|
|
if (iv.length > 0) {
|
|
_this.iv = iv;
|
|
_this.IVIsLongEnough = true;
|
|
} else {
|
|
_this.IVIsLongEnough = false;
|
|
_this.iv = "";
|
|
console.warn("iv is not long enough!");
|
|
}
|
|
}
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {};
|
|
}
|
|
LoadFromJson(o) {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Massive_Cube_Forge.Cnds = {};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Massive_Cube_Forge.Acts = {
|
|
setKey(key) {
|
|
this.setky(key, this);
|
|
},
|
|
setIV(iv) {
|
|
this.setIV(iv, this);
|
|
},
|
|
encrypt(type, text) {
|
|
this.encr(type, this, text);
|
|
},
|
|
decrypt(type, text) {
|
|
this.decr(type, this, text);
|
|
},
|
|
clKyAIV() {
|
|
this.clKAiV(this);
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Plugins.Massive_Cube_Forge.Exps = {
|
|
getresult() {
|
|
return this.result;
|
|
},
|
|
getSHA1(data) {
|
|
return this.sha1(data, this);
|
|
},
|
|
getSHA256(data) {
|
|
return this.sha256(data, this);
|
|
},
|
|
getSHA384(data) {
|
|
return this.sha384(data, this);
|
|
},
|
|
getSHA512(data) {
|
|
return this.sha512(data, this);
|
|
},
|
|
MD5(data) {
|
|
return this.md5(data, this);
|
|
},
|
|
getrandomvalues(lng) {
|
|
return this.psrand(lng);
|
|
},
|
|
encodeb64(str) {
|
|
return this.encb64(str);
|
|
},
|
|
decodeb64(str) {
|
|
return this.decb64(str);
|
|
}
|
|
};
|
|
}
|
|
'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const DOM_COMPONENT_ID = "text-input";
|
|
C3.Plugins.TextBox = class TextInputPlugin extends C3.SDKDOMPluginBase {
|
|
constructor(opts) {
|
|
super(opts, DOM_COMPONENT_ID);
|
|
this.AddElementMessageHandler("click", (sdkInst,e)=>sdkInst._OnClick(e));
|
|
this.AddElementMessageHandler("dblclick", (sdkInst,e)=>sdkInst._OnDoubleClick(e));
|
|
this.AddElementMessageHandler("change", (sdkInst,e)=>sdkInst._OnChange(e))
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.TextBox.Type = class TextInputType extends C3.SDKTypeBase {
|
|
constructor(objectClass) {
|
|
super(objectClass)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const TEXT = 0;
|
|
const PLACEHOLDER = 1;
|
|
const TOOLTIP = 2;
|
|
const INITIALLY_VISIBLE = 3;
|
|
const ENABLE = 4;
|
|
const READ_ONLY = 5;
|
|
const SPELL_CHECK = 6;
|
|
const TYPE = 7;
|
|
const AUTO_FONT_SIZE = 8;
|
|
const ID = 9;
|
|
const DOM_COMPONENT_ID = "text-input";
|
|
const elemTypes = ["text", "password", "email", "number", "tel", "url", "textarea", "search"];
|
|
C3.Plugins.TextBox.Instance = class TextInputInstance extends C3.SDKDOMInstanceBase {
|
|
constructor(inst, properties) {
|
|
super(inst, DOM_COMPONENT_ID);
|
|
this._text = "";
|
|
this._placeholder = "";
|
|
this._title = "";
|
|
this._isEnabled = true;
|
|
this._isReadOnly = false;
|
|
this._spellCheck = false;
|
|
this._type = "text";
|
|
this._autoFontSize = true;
|
|
this._maxLength = -1;
|
|
this._id = "";
|
|
if (properties) {
|
|
this._text = properties[TEXT];
|
|
this._placeholder = properties[PLACEHOLDER];
|
|
this._title = properties[TOOLTIP];
|
|
this.GetWorldInfo().SetVisible(properties[INITIALLY_VISIBLE]);
|
|
this._isEnabled = properties[ENABLE];
|
|
this._isReadOnly = properties[READ_ONLY];
|
|
this._spellCheck = properties[SPELL_CHECK];
|
|
this._type = elemTypes[properties[TYPE]];
|
|
this._autoFontSize = properties[AUTO_FONT_SIZE];
|
|
this._id = properties[ID]
|
|
}
|
|
this.CreateElement({
|
|
"type": this._type,
|
|
"id": this._id
|
|
})
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
GetElementState() {
|
|
return {
|
|
"text": this._text,
|
|
"placeholder": this._placeholder,
|
|
"title": this._title,
|
|
"isEnabled": this._isEnabled,
|
|
"isReadOnly": this._isReadOnly,
|
|
"spellCheck": this._spellCheck,
|
|
"maxLength": this._maxLength
|
|
}
|
|
}
|
|
async _OnClick(e) {
|
|
this.GetScriptInterface().dispatchEvent(C3.New(C3.Event, "click", true));
|
|
await this.TriggerAsync(C3.Plugins.TextBox.Cnds.OnClicked)
|
|
}
|
|
async _OnDoubleClick(e) {
|
|
this.GetScriptInterface().dispatchEvent(C3.New(C3.Event, "dblclick", true));
|
|
await this.TriggerAsync(C3.Plugins.TextBox.Cnds.OnDoubleClicked)
|
|
}
|
|
async _OnChange(e) {
|
|
this._text = e["text"];
|
|
this.GetScriptInterface().dispatchEvent(C3.New(C3.Event, "change", true));
|
|
await this.TriggerAsync(C3.Plugins.TextBox.Cnds.OnTextChanged)
|
|
}
|
|
_SetText(text) {
|
|
if (this._text === text)
|
|
return;
|
|
this._text = text;
|
|
this.UpdateElementState()
|
|
}
|
|
_GetText() {
|
|
return this._text
|
|
}
|
|
_SetPlaceholder(placeholder) {
|
|
if (this._placeholder === placeholder)
|
|
return;
|
|
this._placeholder = placeholder;
|
|
this.UpdateElementState()
|
|
}
|
|
_GetPlaceholder() {
|
|
return this._placeholder
|
|
}
|
|
_SetTooltip(title) {
|
|
if (this._title === title)
|
|
return;
|
|
this._title = title;
|
|
this.UpdateElementState()
|
|
}
|
|
_GetTooltip() {
|
|
return this._title
|
|
}
|
|
_SetEnabled(e) {
|
|
e = !!e;
|
|
if (this._isEnabled === e)
|
|
return;
|
|
this._isEnabled = e;
|
|
this.UpdateElementState()
|
|
}
|
|
_IsEnabled() {
|
|
return this._isEnabled
|
|
}
|
|
_SetReadOnly(r) {
|
|
r = !!r;
|
|
if (this._isReadOnly === r)
|
|
return;
|
|
this._isReadOnly = r;
|
|
this.UpdateElementState()
|
|
}
|
|
_IsReadOnly() {
|
|
return this._isReadOnly
|
|
}
|
|
_SetMaxLength(l) {
|
|
l = Math.max(+l, -1);
|
|
if (this._maxLength === l)
|
|
return;
|
|
this._maxLength = l;
|
|
this.UpdateElementState()
|
|
}
|
|
_GetMaxLength() {
|
|
return this._maxLength
|
|
}
|
|
_ScrollToBottom() {
|
|
this.PostToDOMElement("scroll-to-bottom")
|
|
}
|
|
Draw(renderer) {}
|
|
SaveToJson() {
|
|
return {
|
|
"t": this._text,
|
|
"p": this._placeholder,
|
|
"ti": this._title,
|
|
"e": this._isEnabled,
|
|
"r": this._isReadOnly,
|
|
"sp": this._spellCheck,
|
|
"ml": this._maxLength,
|
|
"type": this._type,
|
|
"id": this._id
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this._text = o["t"];
|
|
this._placeholder = o["p"];
|
|
this._title = o["ti"];
|
|
this._isEnabled = o["e"];
|
|
this._isReadOnly = o["r"];
|
|
this._spellCheck = o["sp"];
|
|
this._maxLength = o.hasOwnProperty("ml") ? o["ml"] : -1;
|
|
this._type = o["type"];
|
|
this._id = o["id"];
|
|
this.UpdateElementState()
|
|
}
|
|
GetPropertyValueByIndex(index) {
|
|
switch (index) {
|
|
case TEXT:
|
|
return this._text;
|
|
case PLACEHOLDER:
|
|
return this._placeholder;
|
|
case TOOLTIP:
|
|
return this._title;
|
|
case ENABLE:
|
|
return this._isEnabled;
|
|
case READ_ONLY:
|
|
return this._isReadOnly;
|
|
case SPELL_CHECK:
|
|
return this._spellCheck;
|
|
case AUTO_FONT_SIZE:
|
|
return this._autoFontSize;
|
|
case ID:
|
|
return this._id
|
|
}
|
|
}
|
|
SetPropertyValueByIndex(index, value) {
|
|
switch (index) {
|
|
case TEXT:
|
|
if (this._text === value)
|
|
return;
|
|
this._text = value;
|
|
this.UpdateElementState();
|
|
break;
|
|
case PLACEHOLDER:
|
|
if (this._placeholder === value)
|
|
return;
|
|
this._placeholder = value;
|
|
this.UpdateElementState();
|
|
break;
|
|
case TOOLTIP:
|
|
if (this._title === value)
|
|
return;
|
|
this._title = value;
|
|
this.UpdateElementState();
|
|
break;
|
|
case ENABLE:
|
|
if (this._isEnabled === !!value)
|
|
return;
|
|
this._isEnabled = !!value;
|
|
this.UpdateElementState();
|
|
break;
|
|
case READ_ONLY:
|
|
if (this._isReadOnly === !!value)
|
|
return;
|
|
this._isReadOnly = !!value;
|
|
this.UpdateElementState();
|
|
break;
|
|
case SPELL_CHECK:
|
|
if (this._spellCheck === !!value)
|
|
return;
|
|
this._spellCheck = !!value;
|
|
this.UpdateElementState();
|
|
break;
|
|
case AUTO_FONT_SIZE:
|
|
this._autoFontSize = !!value;
|
|
break;
|
|
case ID:
|
|
if (this._id === value)
|
|
return;
|
|
this._id = value;
|
|
this.UpdateElementState();
|
|
break
|
|
}
|
|
}
|
|
GetDebuggerProperties() {
|
|
const Acts = C3.Plugins.TextBox.Acts;
|
|
const prefix = "plugins.textbox";
|
|
return [{
|
|
title: prefix + ".name",
|
|
properties: [{
|
|
name: prefix + ".properties.text.name",
|
|
value: this._text,
|
|
onedit: v=>this.CallAction(Acts.SetText, v)
|
|
}, {
|
|
name: prefix + ".properties.enabled.name",
|
|
value: this._isEnabled,
|
|
onedit: v=>this.CallAction(Acts.SetEnabled, v)
|
|
}, {
|
|
name: prefix + ".properties.read-only.name",
|
|
value: this._isReadOnly,
|
|
onedit: v=>this.CallAction(Acts.SetReadOnly, v)
|
|
}]
|
|
}]
|
|
}
|
|
GetScriptInterfaceClass() {
|
|
return self.ITextInputInstance
|
|
}
|
|
}
|
|
;
|
|
const map = new WeakMap;
|
|
self.ITextInputInstance = class ITextInputInstance extends self.IDOMInstance {
|
|
constructor() {
|
|
super();
|
|
map.set(this, self.IInstance._GetInitInst().GetSdkInstance())
|
|
}
|
|
set text(str) {
|
|
map.get(this)._SetText(str)
|
|
}
|
|
get text() {
|
|
return map.get(this)._GetText()
|
|
}
|
|
set placeholder(str) {
|
|
map.get(this)._SetPlaceholder(str)
|
|
}
|
|
get placeholder() {
|
|
return map.get(this)._GetPlaceholder()
|
|
}
|
|
set tooltip(str) {
|
|
map.get(this)._SetTooltip(str)
|
|
}
|
|
get tooltip() {
|
|
return map.get(this)._GetTooltip()
|
|
}
|
|
set isEnabled(e) {
|
|
map.get(this)._SetEnabled(e)
|
|
}
|
|
get isEnabled() {
|
|
return map.get(this)._IsEnabled()
|
|
}
|
|
set isReadOnly(r) {
|
|
map.get(this)._SetReadOnly(r)
|
|
}
|
|
get isReadOnly() {
|
|
return map.get(this)._IsReadOnly()
|
|
}
|
|
set maxLength(l) {
|
|
map.get(this)._SetMaxLength(l)
|
|
}
|
|
get maxLength() {
|
|
return map.get(this)._GetMaxLength()
|
|
}
|
|
scrollToBottom() {
|
|
map.get(this)._ScrollToBottom()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.TextBox.Cnds = {
|
|
CompareText(text, case_) {
|
|
if (case_ === 0)
|
|
return C3.equalsNoCase(this._text, text);
|
|
else
|
|
return this._text === text
|
|
},
|
|
OnTextChanged() {
|
|
return true
|
|
},
|
|
OnClicked() {
|
|
return true
|
|
},
|
|
OnDoubleClicked() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.TextBox.Acts = {
|
|
SetText(text) {
|
|
this._SetText(text)
|
|
},
|
|
AppendText(text) {
|
|
if (!text)
|
|
return;
|
|
this._SetText(this._GetText() + text)
|
|
},
|
|
SetPlaceholder(placeholder) {
|
|
this._SetPlaceholder(placeholder)
|
|
},
|
|
SetTooltip(title) {
|
|
this._SetTooltip(title)
|
|
},
|
|
SetReadOnly(r) {
|
|
this._SetReadOnly(r === 0)
|
|
},
|
|
ScrollToBottom() {
|
|
this._ScrollToBottom()
|
|
},
|
|
SetMaxLength(l) {
|
|
this._SetMaxLength(l)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Plugins.TextBox.Exps = {
|
|
Text() {
|
|
return this._GetText()
|
|
},
|
|
MaxLength() {
|
|
return this._GetMaxLength()
|
|
}
|
|
}
|
|
}
|
|
;"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gameobject = class MyBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gameobject.Type = class MyBehaviorType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gameobject.Instance = class MyBehaviorInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
if (properties) {
|
|
this.name = properties[0];
|
|
this.parentName = properties[1];
|
|
this.parentSameLayer = properties[2];
|
|
}
|
|
this.GetObjectInstance().GetUnsavedDataMap().aekiro_gameobject = this;
|
|
this.inst = this.GetObjectInstance();
|
|
this.wi = this.GetWorldInfo();
|
|
this.acts = this.GetObjectInstance().GetPlugin().constructor.Acts;
|
|
this.eventManager = new EventManager(this.inst);
|
|
this.goManager = globalThis["aekiro_goManager"];
|
|
this.userName = this.name ? this.name : null;
|
|
this.areChildrenRegistred = false;
|
|
this.children = [];
|
|
this.parent = null;
|
|
this.local = {
|
|
x: this.wi.GetX(),
|
|
y: this.wi.GetY(),
|
|
angle: this.wi.GetAngle(),
|
|
_sinA: Math.sin(this.wi.GetAngle()),
|
|
_cosA: Math.cos(this.wi.GetAngle())
|
|
};
|
|
this.overrideWorldInfo();
|
|
this.prev = {
|
|
x: this.wi.GetX(),
|
|
y: this.wi.GetY(),
|
|
angle: this.wi.GetAngle(),
|
|
width: this.wi.GetWidth(),
|
|
height: this.wi.GetHeight()
|
|
};
|
|
if (this.goManager.isInit) {
|
|
this.name = "";
|
|
this.parentName = "";
|
|
}
|
|
this.goManager.addGO(this.inst);
|
|
}
|
|
PostCreate() {}
|
|
overrideWorldInfo() {
|
|
if (this.isWorldInfoOverrided)
|
|
return;
|
|
this.isWorldInfoOverrided = true;
|
|
var inst = this.GetObjectInstance();
|
|
var wi = inst.GetWorldInfo();
|
|
wi.SetX_old = wi.SetX;
|
|
wi.SetX = function(x, isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (!aekiro_gameobject)
|
|
return;
|
|
if (isLocal && aekiro_gameobject.parent) {
|
|
aekiro_gameobject.local.x = x;
|
|
aekiro_gameobject.updateGlobals();
|
|
} else {
|
|
this.SetX_old(x);
|
|
aekiro_gameobject.updateLocals();
|
|
}
|
|
aekiro_gameobject.children_update();
|
|
}
|
|
;
|
|
wi.SetY_old = wi.SetY;
|
|
wi.SetY = function(y, isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (!aekiro_gameobject)
|
|
return;
|
|
if (isLocal && aekiro_gameobject.parent) {
|
|
aekiro_gameobject.local.y = y;
|
|
aekiro_gameobject.updateGlobals();
|
|
} else {
|
|
this.SetY_old(y);
|
|
aekiro_gameobject.updateLocals();
|
|
}
|
|
aekiro_gameobject.children_update();
|
|
}
|
|
;
|
|
wi.SetXY_old = wi.SetXY;
|
|
wi.SetXY = function(x, y, isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (!aekiro_gameobject)
|
|
return;
|
|
if (isLocal && aekiro_gameobject.parent) {
|
|
aekiro_gameobject.local.x = x;
|
|
aekiro_gameobject.local.y = y;
|
|
aekiro_gameobject.updateGlobals();
|
|
} else {
|
|
this.SetXY_old(x, y);
|
|
aekiro_gameobject.updateLocals();
|
|
}
|
|
aekiro_gameobject.children_update();
|
|
}
|
|
;
|
|
wi.OffsetX_old = wi.OffsetX;
|
|
wi.OffsetX = function(x, isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (!aekiro_gameobject)
|
|
return;
|
|
if (isLocal && aekiro_gameobject.parent) {
|
|
aekiro_gameobject.local.x += x;
|
|
aekiro_gameobject.updateGlobals();
|
|
} else {
|
|
this.OffsetX_old(x);
|
|
aekiro_gameobject.updateLocals();
|
|
}
|
|
aekiro_gameobject.children_update();
|
|
}
|
|
;
|
|
wi.OffsetY_old = wi.OffsetY;
|
|
wi.OffsetY = function(y, isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (!aekiro_gameobject)
|
|
return;
|
|
if (isLocal && aekiro_gameobject.parent) {
|
|
aekiro_gameobject.local.y += y;
|
|
aekiro_gameobject.updateGlobals();
|
|
} else {
|
|
this.OffsetY_old(y);
|
|
aekiro_gameobject.updateLocals();
|
|
}
|
|
aekiro_gameobject.children_update();
|
|
}
|
|
;
|
|
wi.OffsetXY_old = wi.OffsetXY;
|
|
wi.OffsetXY = function(x, y, isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (!aekiro_gameobject)
|
|
return;
|
|
if (isLocal && aekiro_gameobject.parent) {
|
|
aekiro_gameobject.local.x += x;
|
|
aekiro_gameobject.local.y += y;
|
|
aekiro_gameobject.updateGlobals();
|
|
} else {
|
|
this.OffsetXY_old(x, y);
|
|
aekiro_gameobject.updateLocals();
|
|
}
|
|
aekiro_gameobject.children_update();
|
|
}
|
|
;
|
|
wi.SetAngle_old = wi.SetAngle;
|
|
wi.SetAngle = function(angle, isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (!aekiro_gameobject)
|
|
return;
|
|
if (isLocal && aekiro_gameobject.parent) {
|
|
aekiro_gameobject.local.angle = angle;
|
|
aekiro_gameobject.local._sinA = Math.sin(angle);
|
|
aekiro_gameobject.local._cosA = Math.cos(angle);
|
|
aekiro_gameobject.updateGlobals();
|
|
} else {
|
|
this.SetAngle_old(angle);
|
|
aekiro_gameobject.updateLocals();
|
|
}
|
|
aekiro_gameobject.children_update();
|
|
}
|
|
;
|
|
wi.GetX_old = wi.GetX;
|
|
wi.GetX = function(isLocal) {
|
|
if (isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (aekiro_gameobject.parent) {
|
|
return aekiro_gameobject.local.x;
|
|
}
|
|
}
|
|
return this.GetX_old();
|
|
}
|
|
;
|
|
wi.GetY_old = wi.GetY;
|
|
wi.GetY = function(isLocal) {
|
|
if (isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (aekiro_gameobject.parent) {
|
|
return aekiro_gameobject.local.y;
|
|
}
|
|
}
|
|
return this.GetY_old();
|
|
}
|
|
;
|
|
wi.GetAngle_old = wi.GetAngle;
|
|
wi.GetAngle = function(isLocal) {
|
|
if (isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (aekiro_gameobject.parent) {
|
|
return aekiro_gameobject.local.angle;
|
|
}
|
|
}
|
|
return this.GetAngle_old();
|
|
}
|
|
;
|
|
wi.GetCosAngle_old = wi.GetCosAngle;
|
|
wi.GetCosAngle = function(isLocal) {
|
|
if (isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (aekiro_gameobject.parent) {
|
|
return aekiro_gameobject.local._cosA;
|
|
}
|
|
}
|
|
return this.GetCosAngle_old();
|
|
}
|
|
;
|
|
wi.GetSinAngle_old = wi.GetSinAngle;
|
|
wi.GetSinAngle = function(isLocal) {
|
|
if (isLocal) {
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (aekiro_gameobject.parent) {
|
|
return aekiro_gameobject.local._sinA;
|
|
}
|
|
}
|
|
return this.GetSinAngle_old();
|
|
}
|
|
;
|
|
wi.SetWidth_old = wi.SetWidth;
|
|
wi.SetWidth = function(w, onlyNode) {
|
|
if (onlyNode) {
|
|
this.SetWidth_old(w);
|
|
return;
|
|
}
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
w = w == 0 ? 0.1 : w;
|
|
var f = w / this.GetWidth();
|
|
this.SetWidth_old(w);
|
|
var c = aekiro_gameobject.children;
|
|
var l = c.length;
|
|
for (var i = 0, l; i < l; i++) {
|
|
wi = c[i].GetWorldInfo();
|
|
wi.SetX(wi.GetX(true) * f, true);
|
|
wi.SetWidth(wi.GetWidth() * f);
|
|
wi.SetBboxChanged();
|
|
}
|
|
}
|
|
;
|
|
wi.SetHeight_old = wi.SetHeight;
|
|
wi.SetHeight = function(h, onlyNode) {
|
|
if (onlyNode) {
|
|
this.SetHeight_old(h);
|
|
return;
|
|
}
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
h = h == 0 ? 0.1 : h;
|
|
var f = h / this.GetHeight();
|
|
this.SetHeight_old(h);
|
|
var c = aekiro_gameobject.children;
|
|
var l = c.length;
|
|
for (var i = 0, l; i < l; i++) {
|
|
wi = c[i].GetWorldInfo();
|
|
wi.SetY(wi.GetY(true) * f, true);
|
|
wi.SetHeight(wi.GetHeight() * f);
|
|
wi.SetBboxChanged();
|
|
}
|
|
}
|
|
;
|
|
wi.SetSize_old = wi.SetSize;
|
|
wi.SetSize = function(w, h, onlyNode) {
|
|
if (onlyNode) {
|
|
this.SetSize_old(w, h);
|
|
return;
|
|
}
|
|
var inst = this.GetInstance();
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
w = w == 0 ? 0.1 : w;
|
|
h = h == 0 ? 0.1 : h;
|
|
var fw = h / this.GetHeight();
|
|
var fh = w / this.GetWidth();
|
|
this.SetSize_old(w, h);
|
|
var c = aekiro_gameobject.children;
|
|
var l = c.length;
|
|
for (var i = 0, l; i < l; i++) {
|
|
wi = c[i].GetWorldInfo();
|
|
wi.SetX(wi.GetX(true) * fw, true);
|
|
wi.SetY(wi.GetY(true) * fh, true);
|
|
wi.SetSize(wi.GetWidth() * fw, wi.GetHeight() * fh);
|
|
wi.SetBboxChanged();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
children_update() {
|
|
if (!this.children.length) {
|
|
return;
|
|
}
|
|
var inst, wi, l = this.children.length;
|
|
for (var i = 0; i < l; i++) {
|
|
inst = this.children[i];
|
|
wi = inst.GetWorldInfo();
|
|
wi.SetXY(wi.GetX(true), wi.GetY(true), true);
|
|
wi.SetAngle(wi.GetAngle(true), true);
|
|
wi.SetBboxChanged();
|
|
}
|
|
}
|
|
children_add(inst) {
|
|
var name, aekiro_gameobject;
|
|
if (typeof inst === 'string') {
|
|
name = inst;
|
|
inst = null;
|
|
} else {
|
|
aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (!aekiro_gameobject) {
|
|
console.error("Aekiro GameObject: You're adding a child (uid=%s) without a gameobject behavior on it.", inst.GetUID());
|
|
return;
|
|
}
|
|
name = aekiro_gameobject.name;
|
|
}
|
|
inst = this.goManager.gos[name];
|
|
if (inst == this.GetObjectInstance()) {
|
|
return;
|
|
}
|
|
if (!inst) {
|
|
console.error("Aekiro GameObject: Object of name : %s not found !", name);
|
|
return;
|
|
}
|
|
if (name == this.parentName) {
|
|
console.error("Aekiro GameObject: Cannot add %s as a child of %s, because %s is its parent !", name, this.name, name);
|
|
return;
|
|
}
|
|
if (this.children.indexOf(inst) > -1) {
|
|
console.warn("Aekiro GameObject: Object %s already have a child named %s !", this.name, name);
|
|
return;
|
|
}
|
|
aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
aekiro_gameobject.removeFromParent();
|
|
aekiro_gameobject.parentName = this.name;
|
|
aekiro_gameobject.parent = this.GetObjectInstance();
|
|
var res = this.globalToLocal(inst, this.GetObjectInstance());
|
|
aekiro_gameobject.local.x = res.x;
|
|
aekiro_gameobject.local.y = res.y;
|
|
aekiro_gameobject.local.angle = res.angle;
|
|
this.children.push(inst);
|
|
this.eventManager.emit("childrenAdded", {
|
|
"args": inst,
|
|
"propagate": false
|
|
});
|
|
}
|
|
setName(name) {
|
|
try {
|
|
this.goManager.setGoName(this.name, name);
|
|
} catch (e) {
|
|
console.error(e);
|
|
return;
|
|
}
|
|
this.name = name;
|
|
const l = this.children.length;
|
|
for (var i = 0; i < l; i++) {
|
|
this.children[i].GetUnsavedDataMap().aekiro_gameobject.parentName = name;
|
|
}
|
|
}
|
|
updateLocals() {
|
|
var parent = this.parent_get();
|
|
if (!parent)
|
|
return;
|
|
if (this.GetObjectInstance() === null)
|
|
return;
|
|
var res = this.globalToLocal(this.GetObjectInstance(), parent);
|
|
this.local.x = res.x;
|
|
this.local.y = res.y;
|
|
this.local.angle = res.angle;
|
|
}
|
|
updateGlobals() {
|
|
var parent = this.parent_get();
|
|
if (!parent)
|
|
return;
|
|
var res = this.localToGlobal(this.GetObjectInstance(), parent);
|
|
this.wi.SetXY_old(res.x, res.y);
|
|
this.wi.SetAngle_old(res.angle);
|
|
}
|
|
children_addFromLayer(layer) {
|
|
var insts = layer._instances;
|
|
var myInst = this.GetObjectInstance();
|
|
var inst, aekiro_gameobject;
|
|
for (var i = 0, l = insts.length; i < l; i++) {
|
|
inst = insts[i];
|
|
aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (inst != myInst && aekiro_gameobject && aekiro_gameobject.parentName == "") {
|
|
this.children_add(inst);
|
|
}
|
|
}
|
|
}
|
|
children_addFromType(type) {
|
|
var insts = type.GetCurrentSol().GetInstances();
|
|
for (var i = 0, l = insts.length; i < l; i++) {
|
|
this.children_add(insts[i]);
|
|
}
|
|
}
|
|
children_remove(inst) {
|
|
var index = -1;
|
|
if (typeof inst === 'string') {
|
|
for (var i = 0, l = this.children.length; i < l; i++) {
|
|
if (this.children[i].GetUnsavedDataMap().aekiro_gameobject.name == inst) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
index = this.children.indexOf(inst);
|
|
}
|
|
if (index != -1) {
|
|
var aekiro_gameobject = this.children[index].GetUnsavedDataMap().aekiro_gameobject;
|
|
aekiro_gameobject.parent = null;
|
|
this.children.splice(index, 1);
|
|
}
|
|
}
|
|
children_removeFromType(type) {
|
|
var insts = type.GetCurrentSol().GetInstances();
|
|
for (var i = 0, l = insts.length; i < l; i++) {
|
|
this.children_remove(insts[i]);
|
|
}
|
|
}
|
|
removeAllChildren() {
|
|
if (!this.children.length)
|
|
return;
|
|
var aekiro_gameobject;
|
|
var l = this.children.length;
|
|
for (var i = 0; i < l; i++) {
|
|
aekiro_gameobject = this.children[i].GetUnsavedDataMap().aekiro_gameobject;
|
|
aekiro_gameobject.parent = null;
|
|
}
|
|
this.children.length = 0;
|
|
}
|
|
removeFromParent() {
|
|
var parent = this.parent;
|
|
var inst = this.GetObjectInstance();
|
|
if (parent) {
|
|
var aekiro_gameobject = parent.GetUnsavedDataMap().aekiro_gameobject;
|
|
if (aekiro_gameobject) {
|
|
aekiro_gameobject.children_remove(inst);
|
|
}
|
|
}
|
|
}
|
|
destroyHierarchy() {
|
|
var runtime = this.GetRuntime();
|
|
runtime.DestroyInstance(this.GetObjectInstance());
|
|
for (var i = 0, l = this.children.length; i < l; i++) {
|
|
this.children[i].GetUnsavedDataMap().aekiro_gameobject.destroyHierarchy()
|
|
}
|
|
this.children.length = 0;
|
|
}
|
|
parent_get() {
|
|
if (!this.parent && this.parentName && this.name) {
|
|
this.parent = this.goManager.gos[this.parentName];
|
|
}
|
|
return this.parent;
|
|
}
|
|
getTemplate(node) {
|
|
if (!node) {
|
|
node = this._inst;
|
|
}
|
|
var template = {
|
|
type: node.GetObjectClass().GetName(),
|
|
x: node.GetWorldInfo().GetX(true),
|
|
y: node.GetWorldInfo().GetY(true),
|
|
zindex: node.GetWorldInfo().GetZIndex() + node.GetWorldInfo().GetLayer().GetIndex() * 100,
|
|
json: JSON.stringify(node.SaveToJson(!0)),
|
|
children: []
|
|
};
|
|
var children = node.GetUnsavedDataMap().aekiro_gameobject.children;
|
|
for (var i = 0, l = children.length; i < l; i++) {
|
|
template.children.push(this.getTemplate(children[i]));
|
|
}
|
|
return template;
|
|
}
|
|
hierarchyToArray(node, ar) {
|
|
if (!node) {
|
|
node = this.GetObjectInstance();
|
|
}
|
|
if (!ar) {
|
|
ar = [];
|
|
}
|
|
ar.push(node);
|
|
var children = node.GetUnsavedDataMap().aekiro_gameobject.children;
|
|
for (var i = 0, l = children.length; i < l; i++) {
|
|
this.hierarchyToArray(children[i], ar);
|
|
}
|
|
return ar;
|
|
}
|
|
updateZindex() {
|
|
var children = this.hierarchyToArray();
|
|
children.sort(function(a, b) {
|
|
return a.GetUnsavedDataMap().zindex - b.GetUnsavedDataMap().zindex;
|
|
});
|
|
var layer = children[0].GetWorldInfo().GetLayer();
|
|
for (var i = 1, l = children.length; i < l; i++) {
|
|
layer.MoveInstanceAdjacent(children[i], children[i - 1], true);
|
|
}
|
|
this.GetRuntime().UpdateRender();
|
|
}
|
|
moveToTop() {
|
|
var children = this.hierarchyToArray();
|
|
children.sort(function(a, b) {
|
|
return a.GetWorldInfo().GetZIndex() - b.GetWorldInfo().GetZIndex();
|
|
});
|
|
for (var i = 0, l = children.length; i < l; i++) {
|
|
children[i].GetSdkInstance().CallAction(this.acts.MoveToTop);
|
|
}
|
|
this.GetRuntime().UpdateRender();
|
|
}
|
|
moveToBottom() {
|
|
var children = this.hierarchyToArray();
|
|
children.sort(function(a, b) {
|
|
return b.GetWorldInfo().GetZIndex() - a.GetWorldInfo().GetZIndex();
|
|
});
|
|
for (var i = 0, l = children.length; i < l; i++) {
|
|
children[i].GetSdkInstance().CallAction(this.acts.MoveToBottom);
|
|
}
|
|
this.GetRuntime().UpdateRender();
|
|
}
|
|
setTimeScale(s) {
|
|
var children = this.hierarchyToArray();
|
|
for (var i = 1, l = children.length; i < l; i++) {
|
|
children[i].SetTimeScale(s);
|
|
}
|
|
}
|
|
Tick() {}
|
|
Release() {}
|
|
Release2() {
|
|
this.goManager.removeGO(this.name);
|
|
this.removeFromParent();
|
|
for (var i = 0, l = this.children.length; i < l; i++) {
|
|
this.children_remove(this.children[i]);
|
|
}
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"name": this.name,
|
|
"parentName": this.parentName,
|
|
"parentSameLayer": this.parentSameLayer,
|
|
"global_x": this.wi.GetX(),
|
|
"global_y": this.wi.GetY()
|
|
};
|
|
}
|
|
LoadFromJson(o) {
|
|
this.name = o["name"];
|
|
this.parentName = o["parentName"];
|
|
this.parentSameLayer = o["parentSameLayer"];
|
|
this.wi.SetXY(o["global_x"], o["global_y"]);
|
|
this.wi.SetBboxChanged();
|
|
}
|
|
GetDebuggerProperties() {
|
|
var children = [];
|
|
for (var i = 0, l = this.children.length; i < l; i++) {
|
|
children.push(this.children[i].GetUnsavedDataMap().aekiro_gameobject.name);
|
|
}
|
|
var children_str = JSON.stringify(children, null, "\t");
|
|
return [{
|
|
title: "aekiro_gameobject",
|
|
properties: [{
|
|
name: "name",
|
|
value: this.name
|
|
}, {
|
|
name: "parentName",
|
|
value: this.parentName
|
|
}, {
|
|
name: "children",
|
|
value: children_str
|
|
}, {
|
|
name: "local_x",
|
|
value: this.local.x
|
|
}, {
|
|
name: "local_y",
|
|
value: this.local.y
|
|
}, {
|
|
name: "local_angle",
|
|
value: this.local.angle
|
|
}]
|
|
}];
|
|
}
|
|
applyActionToHierarchy(action, v) {
|
|
if (!action)
|
|
return;
|
|
this.GetObjectInstance().GetSdkInstance().CallAction(action, v);
|
|
var h = this.children;
|
|
var l = h.length;
|
|
for (var i = 0; i < l; i++) {
|
|
h[i].GetUnsavedDataMap().aekiro_gameobject.applyActionToHierarchy(action, v);
|
|
}
|
|
}
|
|
SetBlendMode(bm) {
|
|
this.wi.SetBlendMode(bm);
|
|
var h = this.children;
|
|
for (var i = 0, l = h.length; i < l; i++) {
|
|
h[i].GetWorldInfo().SetBlendMode(bm);
|
|
}
|
|
}
|
|
globalToLocal(inst, parent_inst) {
|
|
var wip = parent_inst.GetWorldInfo();
|
|
return this.globalToLocal2(inst, wip.GetX(), wip.GetY(), wip.GetAngle());
|
|
}
|
|
globalToLocal2(inst, p_x, p_y, p_angle) {
|
|
var res = {};
|
|
var wi = inst.GetWorldInfo();
|
|
res.x = (wi.GetX() - p_x) * Math.cos(p_angle) + (wi.GetY() - p_y) * Math.sin(p_angle);
|
|
res.y = -(wi.GetX() - p_x) * Math.sin(p_angle) + (wi.GetY() - p_y) * Math.cos(p_angle);
|
|
res.angle = wi.GetAngle() - p_angle;
|
|
return res;
|
|
}
|
|
localToGlobal(inst, parent_inst) {
|
|
var wip = parent_inst.GetWorldInfo();
|
|
return this.localToGlobal2(inst, wip.GetX(), wip.GetY(), wip.GetAngle());
|
|
}
|
|
localToGlobal2(inst, p_x, p_y, p_angle) {
|
|
var res = {};
|
|
var aekiro_gameobject = inst.GetUnsavedDataMap().aekiro_gameobject;
|
|
res.x = p_x + aekiro_gameobject.local.x * Math.cos(p_angle) - aekiro_gameobject.local.y * Math.sin(p_angle);
|
|
res.y = p_y + aekiro_gameobject.local.x * Math.sin(p_angle) + aekiro_gameobject.local.y * Math.cos(p_angle);
|
|
res.angle = p_angle + aekiro_gameobject.local.angle;
|
|
return res;
|
|
}
|
|
localToGlobal_x() {
|
|
var parent = this.parent_get();
|
|
if (parent) {
|
|
var wp = parent.GetWorldInfo();
|
|
var x = wp.GetX() + this.local.x * Math.cos(wp.GetAngle()) - this.local.y * Math.sin(wp.GetAngle());
|
|
return x;
|
|
} else {
|
|
return wp.GetX();
|
|
}
|
|
}
|
|
localToGlobal_y() {
|
|
var parent = this.parent_get();
|
|
if (parent) {
|
|
var wp = parent.GetWorldInfo();
|
|
var y = wp.GetY("g") + this.local.x * Math.sin(wp.GetAngle("g")) + this.local.y * Math.cos(wp.GetAngle("g"));
|
|
return y;
|
|
} else {
|
|
return this.local.y;
|
|
}
|
|
}
|
|
localToGlobal_angle() {
|
|
var parent = this.parent_get();
|
|
if (parent) {
|
|
var wp = parent.GetWorldInfo();
|
|
var angle = wp.GetAngle("g") + this.local.angle;
|
|
return angle;
|
|
} else {
|
|
return this.local.angle;
|
|
}
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gameobject.Cnds = {
|
|
IsName(name) {
|
|
return name == this.name;
|
|
},
|
|
IsParentName(name) {
|
|
return name == this.parentName;
|
|
},
|
|
OnCloned() {
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gameobject.Acts = {
|
|
Clone(layer, x, y, name, parentName) {
|
|
var template = this.getTemplate();
|
|
var inst = aekiro_goManager.clone(template, name, parentName, layer, x, y);
|
|
inst.GetUnsavedDataMap().aekiro_gameobject.updateZindex();
|
|
},
|
|
SetName(name) {
|
|
this.setName(name);
|
|
},
|
|
AddChildrenFromLayer(layer) {
|
|
this.children_addFromLayer(layer);
|
|
},
|
|
AddChildrenFromType(type) {
|
|
this.children_addFromType(type);
|
|
},
|
|
AddChildByName(name) {
|
|
this.children_add(name);
|
|
},
|
|
RemoveChildByName(name) {
|
|
this.children_remove(name);
|
|
},
|
|
RemoveChildByType(type) {
|
|
this.children_removeFromType(type);
|
|
},
|
|
RemoveFromParent() {
|
|
this.removeFromParent();
|
|
},
|
|
RemoveAllchildren() {
|
|
this.removeAllChildren();
|
|
},
|
|
SetOpacity(v) {
|
|
this.applyActionToHierarchy(this.acts.SetOpacity, v);
|
|
},
|
|
SetVisible(v) {
|
|
this.applyActionToHierarchy(this.acts.SetVisible, v);
|
|
},
|
|
SetColor(v) {
|
|
this.applyActionToHierarchy(this.acts.SetDefaultColor, v);
|
|
},
|
|
SetMirrored(v) {
|
|
this.applyActionToHierarchy(this.acts.SetMirrored, v);
|
|
},
|
|
SetFlipped(v) {
|
|
this.applyActionToHierarchy(this.acts.SetFlipped, v);
|
|
},
|
|
MoveToLayer(v) {
|
|
this.applyActionToHierarchy(this.acts.MoveToLayer, v);
|
|
},
|
|
MoveToTop() {
|
|
this.moveToTop();
|
|
},
|
|
MoveToBottom() {
|
|
this.moveToBottom();
|
|
},
|
|
SetZElevation(v) {
|
|
this.applyActionToHierarchy(this.acts.SetZElevation, v);
|
|
},
|
|
SetEffect(v) {
|
|
this.SetBlendMode(v);
|
|
},
|
|
SetWidth(v) {
|
|
this.wi.SetWidth(v, true);
|
|
this.wi.SetBboxChanged();
|
|
},
|
|
SetHeight(v) {
|
|
this.wi.SetHeight(v, true);
|
|
this.wi.SetBboxChanged();
|
|
},
|
|
Destroy() {
|
|
this.destroyHierarchy();
|
|
},
|
|
SetLocalX(v) {
|
|
this.wi.SetX(v, true);
|
|
this.wi.SetBboxChanged();
|
|
},
|
|
SetLocalY(v) {
|
|
this.wi.SetY(v, true);
|
|
this.wi.SetBboxChanged();
|
|
},
|
|
SetLocalAngle(v) {
|
|
this.wi.SetAngle(v, true);
|
|
this.wi.SetBboxChanged();
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gameobject.Exps = {
|
|
name() {
|
|
return this.name;
|
|
},
|
|
parent() {
|
|
return this.parentName;
|
|
},
|
|
asjson() {
|
|
var t = this.getTemplate();
|
|
return JSON.stringify(t);
|
|
},
|
|
globalX() {
|
|
return this.GetObjectInstance().GetWorldInfo().GetX_old();
|
|
},
|
|
globalY() {
|
|
return this.GetObjectInstance().GetWorldInfo().GetY_old();
|
|
},
|
|
globalAngle() {
|
|
return this.GetObjectInstance().GetWorldInfo().GetAngle_old();
|
|
},
|
|
localX() {
|
|
return this.wi.GetX(true);
|
|
},
|
|
localY() {
|
|
return this.wi.GetY(true);
|
|
},
|
|
localAngle() {
|
|
return this.wi.GetAngle(true);
|
|
}
|
|
};
|
|
}
|
|
'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.MoveTo = class MoveToBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.MoveTo.Type = class MoveToType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const IBehaviorInstance = self.IBehaviorInstance;
|
|
const PROP_MAX_SPEED = 0;
|
|
const PROP_ACCELERATION = 1;
|
|
const PROP_DECELERATION = 2;
|
|
const PROP_ROTATE_SPEED = 3;
|
|
const PROP_SET_ANGLE = 4;
|
|
const PROP_STOP_ON_SOLIDS = 5;
|
|
const PROP_ENABLED = 6;
|
|
C3.Behaviors.MoveTo.Instance = class MoveToInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this._maxSpeed = 200;
|
|
this._acc = 600;
|
|
this._dec = 600;
|
|
this._rotateSpeed = 0;
|
|
this._setAngle = true;
|
|
this._stopOnSolids = false;
|
|
this._isEnabled = true;
|
|
this._speed = 0;
|
|
this._movingAngle = this.GetWorldInfo().GetAngle();
|
|
this._waypoints = [];
|
|
if (properties) {
|
|
this._maxSpeed = properties[PROP_MAX_SPEED];
|
|
this._acc = properties[PROP_ACCELERATION];
|
|
this._dec = properties[PROP_DECELERATION];
|
|
this._rotateSpeed = C3.toRadians(properties[PROP_ROTATE_SPEED]);
|
|
this._setAngle = properties[PROP_SET_ANGLE];
|
|
this._stopOnSolids = properties[PROP_STOP_ON_SOLIDS];
|
|
this._isEnabled = properties[PROP_ENABLED]
|
|
}
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"ms": this._maxSpeed,
|
|
"acc": this._acc,
|
|
"dec": this._dec,
|
|
"rs": this._rotateSpeed,
|
|
"sa": this._setAngle,
|
|
"sos": this._stopOnSolids,
|
|
"s": this._speed,
|
|
"ma": this._movingAngle,
|
|
"wp": this._waypoints.map(p=>({
|
|
"x": p.x,
|
|
"y": p.y
|
|
})),
|
|
"e": this._isEnabled
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this._maxSpeed = o["ms"];
|
|
this._acc = o["acc"];
|
|
this._dec = o["dec"];
|
|
this._rotateSpeed = o["rs"];
|
|
this._setAngle = o["sa"];
|
|
this._stopOnSolids = o["sos"];
|
|
this._speed = o["s"];
|
|
this._movingAngle = o["ma"];
|
|
this._waypoints = o["wp"].map(p=>({
|
|
x: p["x"],
|
|
y: p["y"]
|
|
}));
|
|
this._SetEnabled(o["e"]);
|
|
if (this._isEnabled && this._waypoints.length > 0)
|
|
this._StartTicking()
|
|
}
|
|
_AddWaypoint(x, y, isDirect) {
|
|
if (isDirect)
|
|
C3.clearArray(this._waypoints);
|
|
this._waypoints.push({
|
|
x,
|
|
y
|
|
});
|
|
if (this._isEnabled)
|
|
this._StartTicking()
|
|
}
|
|
_GetWaypointCount() {
|
|
return this._waypoints.length
|
|
}
|
|
_GetWaypointXAt(i) {
|
|
i = Math.floor(i);
|
|
if (i < 0 || i >= this._waypoints.length)
|
|
return 0;
|
|
return this._waypoints[i].x
|
|
}
|
|
_GetWaypointYAt(i) {
|
|
i = Math.floor(i);
|
|
if (i < 0 || i >= this._waypoints.length)
|
|
return 0;
|
|
return this._waypoints[i].y
|
|
}
|
|
_IsMoving() {
|
|
return this._waypoints.length > 0
|
|
}
|
|
_Stop() {
|
|
C3.clearArray(this._waypoints);
|
|
this._speed = 0;
|
|
this._StopTicking()
|
|
}
|
|
_GetTargetX() {
|
|
if (this._waypoints.length > 0)
|
|
return this._waypoints[0].x;
|
|
else
|
|
return 0
|
|
}
|
|
_GetTargetY() {
|
|
if (this._waypoints.length > 0)
|
|
return this._waypoints[0].y;
|
|
else
|
|
return 0
|
|
}
|
|
_SetSpeed(s) {
|
|
if (!this._IsMoving())
|
|
return;
|
|
this._speed = Math.min(s, this._maxSpeed)
|
|
}
|
|
_GetSpeed() {
|
|
return this._speed
|
|
}
|
|
_SetMaxSpeed(ms) {
|
|
this._maxSpeed = Math.max(ms, 0);
|
|
this._SetSpeed(this._speed)
|
|
}
|
|
_GetMaxSpeed() {
|
|
return this._maxSpeed
|
|
}
|
|
_IsRotationEnabled() {
|
|
return this._rotateSpeed !== 0
|
|
}
|
|
Tick() {
|
|
if (!this._isEnabled || !this._IsMoving())
|
|
return;
|
|
const dt = this._runtime.GetDt(this._inst);
|
|
const wi = this._inst.GetWorldInfo();
|
|
const startX = wi.GetX();
|
|
const startY = wi.GetY();
|
|
const startAngle = wi.GetAngle();
|
|
let curSpeed = this._speed;
|
|
let maxSpeed = this._maxSpeed;
|
|
const acc = this._acc;
|
|
const dec = this._dec;
|
|
const targetX = this._GetTargetX();
|
|
const targetY = this._GetTargetY();
|
|
const angleToTarget = C3.angleTo(startX, startY, targetX, targetY);
|
|
let isWithinStoppingDistance = false;
|
|
if (dec > 0 && this._waypoints.length === 1) {
|
|
const stoppingDist = .5 * curSpeed * curSpeed / dec * 1.0001;
|
|
isWithinStoppingDistance = C3.distanceSquared(startX, startY, targetX, targetY) <= stoppingDist * stoppingDist;
|
|
if (isWithinStoppingDistance) {
|
|
const remainingDist = C3.distanceTo(startX, startY, targetX, targetY);
|
|
curSpeed = Math.sqrt(2 * dec * remainingDist);
|
|
maxSpeed = curSpeed;
|
|
this._speed = curSpeed
|
|
}
|
|
}
|
|
if (this._IsRotationEnabled()) {
|
|
const da = C3.angleDiff(this._movingAngle, angleToTarget);
|
|
if (da > Number.EPSILON) {
|
|
const t = da / this._rotateSpeed;
|
|
const dist = C3.distanceTo(wi.GetX(), wi.GetY(), targetX, targetY);
|
|
const r = dist / (2 * Math.sin(da));
|
|
const curveDist = r * da;
|
|
maxSpeed = Math.min(maxSpeed, C3.clamp(curveDist / t, 0, this._maxSpeed))
|
|
}
|
|
}
|
|
let curAcc = isWithinStoppingDistance ? -dec : acc;
|
|
const stepDist = Math.min(curSpeed * dt + .5 * curAcc * dt * dt, maxSpeed * dt);
|
|
if (isWithinStoppingDistance) {
|
|
if (dec > 0) {
|
|
this._speed = Math.max(this._speed - dec * dt, 0);
|
|
if (this._speed === 0) {
|
|
this._OnArrived(wi, targetX, targetY);
|
|
return
|
|
}
|
|
}
|
|
} else if (acc === 0)
|
|
this._speed = maxSpeed;
|
|
else
|
|
this._speed = Math.min(this._speed + acc * dt, maxSpeed);
|
|
if (C3.distanceSquared(wi.GetX(), wi.GetY(), targetX, targetY) <= stepDist * stepDist) {
|
|
this._OnArrived(wi, targetX, targetY);
|
|
return
|
|
}
|
|
if (this._IsRotationEnabled())
|
|
this._movingAngle = C3.angleRotate(this._movingAngle, angleToTarget, this._rotateSpeed * dt);
|
|
else
|
|
this._movingAngle = angleToTarget;
|
|
wi.OffsetXY(Math.cos(this._movingAngle) * stepDist, Math.sin(this._movingAngle) * stepDist);
|
|
if (this._setAngle)
|
|
wi.SetAngle(this._movingAngle);
|
|
wi.SetBboxChanged();
|
|
this._CheckSolidCollision(startX, startY, startAngle)
|
|
}
|
|
_OnArrived(wi, targetX, targetY) {
|
|
wi.SetXY(targetX, targetY);
|
|
wi.SetBboxChanged();
|
|
this._waypoints.shift();
|
|
if (this._waypoints.length === 0) {
|
|
this._speed = 0;
|
|
this._StopTicking()
|
|
}
|
|
this.GetScriptInterface().dispatchEvent(C3.New(C3.Event, "arrived"));
|
|
this.Trigger(C3.Behaviors.MoveTo.Cnds.OnArrived)
|
|
}
|
|
_CheckSolidCollision(startX, startY, startAngle) {
|
|
const collisionEngine = this._runtime.GetCollisionEngine();
|
|
if (this._stopOnSolids && collisionEngine.TestOverlapSolid(this._inst)) {
|
|
this._Stop();
|
|
const wi = this._inst.GetWorldInfo();
|
|
const x = wi.GetX();
|
|
const y = wi.GetY();
|
|
const a = C3.angleTo(x, y, startX, startY);
|
|
const dist = C3.distanceTo(x, y, startX, startY);
|
|
if (!collisionEngine.PushOutSolid(this._inst, Math.cos(a), Math.sin(a), Math.max(dist, 1))) {
|
|
wi.SetXY(startX, startY);
|
|
wi.SetAngle(startAngle);
|
|
wi.SetBboxChanged()
|
|
}
|
|
this.GetScriptInterface().dispatchEvent(C3.New(C3.Event, "hitsolid"));
|
|
this.Trigger(C3.Behaviors.MoveTo.Cnds.OnHitSolid)
|
|
}
|
|
}
|
|
_IsSetAngle() {
|
|
return this._setAngle
|
|
}
|
|
_SetSetAngle(a) {
|
|
this._setAngle = !!a
|
|
}
|
|
_SetAngleOfMotion(a) {
|
|
this._movingAngle = a;
|
|
if (this._isEnabled && this._setAngle && !this._IsMoving()) {
|
|
const wi = this.GetWorldInfo();
|
|
wi.SetAngle(this._movingAngle);
|
|
wi.SetBboxChanged()
|
|
}
|
|
}
|
|
_GetAngleOfMotion() {
|
|
return this._movingAngle
|
|
}
|
|
_SetAcceleration(a) {
|
|
this._acc = Math.max(a, 0)
|
|
}
|
|
_GetAcceleration() {
|
|
return this._acc
|
|
}
|
|
_SetDeceleration(d) {
|
|
this._dec = Math.max(d, 0)
|
|
}
|
|
_GetDeceleration() {
|
|
return this._dec
|
|
}
|
|
_SetRotateSpeed(r) {
|
|
this._rotateSpeed = Math.max(r, 0)
|
|
}
|
|
_GetRotateSpeed() {
|
|
return this._rotateSpeed
|
|
}
|
|
_SetStopOnSolids(e) {
|
|
this._stopOnSolids = !!e
|
|
}
|
|
_IsStopOnSolids() {
|
|
return this._stopOnSolids
|
|
}
|
|
_SetEnabled(e) {
|
|
e = !!e;
|
|
if (this._isEnabled === e)
|
|
return;
|
|
this._isEnabled = e;
|
|
if (this._isEnabled && this._IsMoving())
|
|
this._StartTicking();
|
|
else
|
|
this._StopTicking()
|
|
}
|
|
_IsEnabled() {
|
|
return this._isEnabled
|
|
}
|
|
GetPropertyValueByIndex(index) {
|
|
switch (index) {
|
|
case PROP_MAX_SPEED:
|
|
return this._GetMaxSpeed();
|
|
case PROP_ACCELERATION:
|
|
return this._GetAcceleration();
|
|
case PROP_DECELERATION:
|
|
return this._GetDeceleration();
|
|
case PROP_ROTATE_SPEED:
|
|
return C3.toDegrees(this._GetRotateSpeed());
|
|
case PROP_SET_ANGLE:
|
|
return this._IsSetAngle();
|
|
case PROP_STOP_ON_SOLIDS:
|
|
return this._IsStopOnSolids();
|
|
case PROP_ENABLED:
|
|
return this._IsEnabled()
|
|
}
|
|
}
|
|
SetPropertyValueByIndex(index, value) {
|
|
switch (index) {
|
|
case PROP_MAX_SPEED:
|
|
this._SetMaxSpeed(value);
|
|
break;
|
|
case PROP_ACCELERATION:
|
|
this._SetAcceleration(value);
|
|
break;
|
|
case PROP_DECELERATION:
|
|
this._SetDeceleration(value);
|
|
break;
|
|
case PROP_ROTATE_SPEED:
|
|
this._SetRotateSpeed(C3.toRadians(value));
|
|
break;
|
|
case PROP_SET_ANGLE:
|
|
this._SetSetAngle(value);
|
|
break;
|
|
case PROP_STOP_ON_SOLIDS:
|
|
this._SetStopOnSolids(value);
|
|
break;
|
|
case PROP_ENABLED:
|
|
this._SetEnabled(value);
|
|
break
|
|
}
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "behaviors.moveto";
|
|
return [{
|
|
title: "$" + this.GetBehaviorType().GetName(),
|
|
properties: [{
|
|
name: prefix + ".debugger.speed",
|
|
value: this._GetSpeed(),
|
|
onedit: v=>this._SetSpeed(v)
|
|
}, {
|
|
name: prefix + ".debugger.angle-of-motion",
|
|
value: C3.toDegrees(this._GetAngleOfMotion()),
|
|
onedit: v=>this._movingAngle = C3.toRadians(v)
|
|
}, {
|
|
name: prefix + ".debugger.target-x",
|
|
value: this._GetTargetX()
|
|
}, {
|
|
name: prefix + ".debugger.target-y",
|
|
value: this._GetTargetY()
|
|
}, {
|
|
name: prefix + ".debugger.waypoint-count",
|
|
value: this._GetWaypointCount()
|
|
}, {
|
|
name: prefix + ".properties.max-speed.name",
|
|
value: this._GetMaxSpeed(),
|
|
onedit: v=>this._SetMaxSpeed(v)
|
|
}, {
|
|
name: prefix + ".properties.acceleration.name",
|
|
value: this._GetAcceleration(),
|
|
onedit: v=>this._SetAcceleration(v)
|
|
}, {
|
|
name: prefix + ".properties.deceleration.name",
|
|
value: this._GetDeceleration(),
|
|
onedit: v=>this._SetDeceleration(v)
|
|
}, {
|
|
name: prefix + ".properties.rotate-speed.name",
|
|
value: C3.toDegrees(this._GetRotateSpeed()),
|
|
onedit: v=>this._SetRotateSpeed(C3.toRadians(v))
|
|
}, {
|
|
name: prefix + ".properties.enabled.name",
|
|
value: this._IsEnabled(),
|
|
onedit: v=>this._SetEnabled(v)
|
|
}]
|
|
}]
|
|
}
|
|
GetScriptInterfaceClass() {
|
|
return self.IMoveToBehaviorInstance
|
|
}
|
|
}
|
|
;
|
|
const map = new WeakMap;
|
|
self.IMoveToBehaviorInstance = class IMoveToBehaviorInstance extends IBehaviorInstance {
|
|
constructor() {
|
|
super();
|
|
map.set(this, IBehaviorInstance._GetInitInst().GetSdkInstance())
|
|
}
|
|
moveToPosition(x, y, isDirect=true) {
|
|
map.get(this)._AddWaypoint(x, y, !!isDirect)
|
|
}
|
|
getTargetX() {
|
|
return map.get(this)._GetTargetX()
|
|
}
|
|
getTargetY() {
|
|
return map.get(this)._GetTargetY()
|
|
}
|
|
getTargetPosition() {
|
|
const b = map.get(this);
|
|
return [b._GetTargetX(), b._GetTargetY()]
|
|
}
|
|
getWaypointCount() {
|
|
return map.get(this)._GetWaypointCount()
|
|
}
|
|
getWaypointX(i) {
|
|
return map.get(this)._GetWaypointXAt(+i)
|
|
}
|
|
getWaypointY(i) {
|
|
return map.get(this)._GetWaypointYAt(+i)
|
|
}
|
|
getWaypoint(i) {
|
|
i = +i;
|
|
const b = map.get(this);
|
|
return [b._GetWaypointXAt(i), b._GetWaypointYAt(i)]
|
|
}
|
|
stop() {
|
|
map.get(this)._Stop()
|
|
}
|
|
get isMoving() {
|
|
return map.get(this)._IsMoving()
|
|
}
|
|
get speed() {
|
|
return map.get(this)._GetSpeed()
|
|
}
|
|
set speed(s) {
|
|
map.get(this)._SetSpeed(s)
|
|
}
|
|
get maxSpeed() {
|
|
return map.get(this)._GetMaxSpeed()
|
|
}
|
|
set maxSpeed(ms) {
|
|
map.get(this)._SetMaxSpeed(ms)
|
|
}
|
|
get acceleration() {
|
|
return map.get(this)._GetAcceleration()
|
|
}
|
|
set acceleration(a) {
|
|
map.get(this)._SetAcceleration(a)
|
|
}
|
|
get deceleration() {
|
|
return map.get(this)._GetDeceleration()
|
|
}
|
|
set deceleration(d) {
|
|
map.get(this)._SetDeceleration(d)
|
|
}
|
|
get angleOfMotion() {
|
|
return map.get(this)._GetAngleOfMotion()
|
|
}
|
|
set angleOfMotion(a) {
|
|
map.get(this)._SetAngleOfMotion(a)
|
|
}
|
|
get rotateSpeed() {
|
|
return map.get(this)._GetRotateSpeed()
|
|
}
|
|
set rotateSpeed(r) {
|
|
map.get(this)._SetRotateSpeed(r)
|
|
}
|
|
get isStopOnSolids() {
|
|
return map.get(this)._IsStopOnSolids()
|
|
}
|
|
set isStopOnSolids(e) {
|
|
map.get(this)._SetStopOnSolids(e)
|
|
}
|
|
get isEnabled() {
|
|
return map.get(this)._IsEnabled()
|
|
}
|
|
set isEnabled(e) {
|
|
map.get(this)._SetEnabled(e)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.MoveTo.Cnds = {
|
|
IsMoving() {
|
|
return this._IsMoving()
|
|
},
|
|
CompareSpeed(cmp, s) {
|
|
return C3.compare(this._GetSpeed(), cmp, s)
|
|
},
|
|
IsEnabled() {
|
|
return this._IsEnabled()
|
|
},
|
|
OnArrived() {
|
|
return true
|
|
},
|
|
OnHitSolid() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.MoveTo.Acts = {
|
|
MoveToPosition(x, y, mode) {
|
|
this._AddWaypoint(x, y, mode === 0)
|
|
},
|
|
MoveToObject(objectClass, imgPt, mode) {
|
|
if (!objectClass)
|
|
return;
|
|
const inst = objectClass.GetPairedInstance(this._inst);
|
|
if (!inst || !inst.GetWorldInfo())
|
|
return;
|
|
const [x,y] = inst.GetImagePoint(imgPt);
|
|
this._AddWaypoint(x, y, mode === 0)
|
|
},
|
|
MoveAlongPathfindingPath(mode) {
|
|
const behInst = this._inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.Pathfinding);
|
|
if (!behInst)
|
|
return;
|
|
const path = behInst._GetPath();
|
|
if (path.length === 0)
|
|
return;
|
|
for (let i = 0, len = path.length; i < len; ++i) {
|
|
const n = path[i];
|
|
this._AddWaypoint(n.x, n.y, i === 0 && mode === 0)
|
|
}
|
|
},
|
|
MoveAlongTimeline(timeline, trackId, mode) {
|
|
let trackState = null;
|
|
if (trackId)
|
|
trackState = timeline.GetTrackById(trackId);
|
|
else
|
|
trackState = C3.first(timeline.GetTracks());
|
|
if (!trackState)
|
|
return;
|
|
const xTrack = trackState.GetPropertyTrack("offsetX");
|
|
const yTrack = trackState.GetPropertyTrack("offsetY");
|
|
if (!xTrack || !yTrack)
|
|
return;
|
|
const xPositions = [...xTrack.GetPropertyKeyframeValues()];
|
|
const yPositions = [...yTrack.GetPropertyKeyframeValues()];
|
|
if (xPositions.length === 0 || yPositions.length === 0)
|
|
return;
|
|
let xOrigin = 0;
|
|
let yOrigin = 0;
|
|
const wi = this._inst.GetWorldInfo();
|
|
if (xTrack.GetResultMode() === "relative")
|
|
xOrigin = wi.GetX();
|
|
if (yTrack.GetResultMode() === "relative")
|
|
yOrigin = wi.GetY();
|
|
for (let i = 0, len = Math.min(xPositions.length, yPositions.length); i < len; ++i) {
|
|
const x = xPositions[i] + xOrigin;
|
|
const y = yPositions[i] + yOrigin;
|
|
this._AddWaypoint(x, y, i === 0 && mode === 0)
|
|
}
|
|
},
|
|
MoveAlongTimelineByName(timelineName, trackId, mode) {
|
|
const timeline = this._runtime.GetTimelineManager().GetTimelineByName(timelineName);
|
|
if (!timeline)
|
|
return;
|
|
C3.Behaviors.MoveTo.Acts.MoveAlongTimeline.call(this, timeline, trackId, mode)
|
|
},
|
|
Stop() {
|
|
this._Stop()
|
|
},
|
|
SetMovingAngle(a) {
|
|
this._SetAngleOfMotion(C3.toRadians(a))
|
|
},
|
|
SetSpeed(s) {
|
|
this._SetSpeed(s)
|
|
},
|
|
SetMaxSpeed(ms) {
|
|
this._SetMaxSpeed(ms)
|
|
},
|
|
SetAcceleration(a) {
|
|
this._SetAcceleration(a)
|
|
},
|
|
SetDeceleration(d) {
|
|
this._SetDeceleration(d)
|
|
},
|
|
SetRotateSpeed(r) {
|
|
this._SetRotateSpeed(C3.toRadians(r))
|
|
},
|
|
SetStopOnSolids(e) {
|
|
this._SetStopOnSolids(e)
|
|
},
|
|
SetEnabled(e) {
|
|
this._SetEnabled(e)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.MoveTo.Exps = {
|
|
Speed() {
|
|
return this._GetSpeed()
|
|
},
|
|
MaxSpeed() {
|
|
return this._GetMaxSpeed()
|
|
},
|
|
Acceleration() {
|
|
return this._GetAcceleration()
|
|
},
|
|
Deceleration() {
|
|
return this._GetDeceleration()
|
|
},
|
|
MovingAngle() {
|
|
return C3.toDegrees(this._GetAngleOfMotion())
|
|
},
|
|
RotateSpeed() {
|
|
return C3.toDegrees(this._GetRotateSpeed())
|
|
},
|
|
TargetX() {
|
|
return this._GetTargetX()
|
|
},
|
|
TargetY() {
|
|
return this._GetTargetY()
|
|
},
|
|
WaypointCount() {
|
|
return this._GetWaypointCount()
|
|
},
|
|
WaypointXAt(i) {
|
|
return this._GetWaypointXAt(i)
|
|
},
|
|
WaypointYAt(i) {
|
|
return this._GetWaypointYAt(i)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Fade = class FadeBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Fade.Type = class FadeType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const FADE_IN_TIME = 0;
|
|
const WAIT_TIME = 1;
|
|
const FADE_OUT_TIME = 2;
|
|
const DESTROY = 3;
|
|
const ACTIVE_AT_START = 4;
|
|
C3.Behaviors.Fade.Instance = class FadeInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this._fadeInTime = 0;
|
|
this._waitTime = 0;
|
|
this._fadeOutTime = 0;
|
|
this._destroy = true;
|
|
this._activeAtStart = true;
|
|
this._setMaxOpacity = false;
|
|
this._stage = 0;
|
|
this._stageTime = C3.New(C3.KahanSum);
|
|
this._maxOpacity = this._inst.GetWorldInfo().GetOpacity() || 1;
|
|
if (properties) {
|
|
this._fadeInTime = properties[FADE_IN_TIME];
|
|
this._waitTime = properties[WAIT_TIME];
|
|
this._fadeOutTime = properties[FADE_OUT_TIME];
|
|
this._destroy = !!properties[DESTROY];
|
|
this._activeAtStart = !!properties[ACTIVE_AT_START];
|
|
this._stage = this._activeAtStart ? 0 : 3
|
|
}
|
|
if (this._activeAtStart)
|
|
if (this._fadeInTime === 0) {
|
|
this._stage = 1;
|
|
if (this._waitTime === 0)
|
|
this._stage = 2
|
|
} else {
|
|
this._inst.GetWorldInfo().SetOpacity(0);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
this._StartTicking()
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"fit": this._fadeInTime,
|
|
"wt": this._waitTime,
|
|
"fot": this._fadeOutTime,
|
|
"d": this._destroy,
|
|
"s": this._stage,
|
|
"st": this._stageTime.Get(),
|
|
"mo": this._maxOpacity
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this._fadeInTime = o["fit"];
|
|
this._waitTime = o["wt"];
|
|
this._fadeOutTime = o["fot"];
|
|
this._destroy = o["d"];
|
|
this._stage = o["s"];
|
|
this._stageTime.Set(o["st"]);
|
|
this._maxOpacity = o["mo"]
|
|
}
|
|
Tick() {
|
|
const dt = this._runtime.GetDt(this._inst);
|
|
this._stageTime.Add(dt);
|
|
const wi = this._inst.GetWorldInfo();
|
|
if (this._stage === 0) {
|
|
wi.SetOpacity(this._stageTime.Get() / this._fadeInTime * this._maxOpacity);
|
|
this._runtime.UpdateRender();
|
|
if (wi.GetOpacity() >= this._maxOpacity) {
|
|
wi.SetOpacity(this._maxOpacity);
|
|
this._stage = 1;
|
|
this._stageTime.Reset();
|
|
this.Trigger(C3.Behaviors.Fade.Cnds.OnFadeInEnd)
|
|
}
|
|
}
|
|
if (this._stage === 1)
|
|
if (this._stageTime.Get() >= this._waitTime) {
|
|
this._stage = 2;
|
|
this._stageTime.Reset();
|
|
this.Trigger(C3.Behaviors.Fade.Cnds.OnWaitEnd)
|
|
}
|
|
if (this._stage === 2)
|
|
if (this._fadeOutTime !== 0) {
|
|
wi.SetOpacity(this._maxOpacity - this._stageTime.Get() / this._fadeOutTime * this._maxOpacity);
|
|
this._runtime.UpdateRender();
|
|
if (wi.GetOpacity() <= 0) {
|
|
this._stage = 3;
|
|
this._stageTime.Reset();
|
|
this.Trigger(C3.Behaviors.Fade.Cnds.OnFadeOutEnd);
|
|
if (this._destroy)
|
|
this._runtime.DestroyInstance(this._inst)
|
|
}
|
|
}
|
|
}
|
|
Start() {
|
|
this._stage = 0;
|
|
this._stageTime.Reset();
|
|
if (this._fadeInTime === 0) {
|
|
this._stage = 1;
|
|
if (this._waitTime === 0)
|
|
this._stage = 2
|
|
} else {
|
|
this._inst.GetWorldInfo().SetOpacity(0);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
}
|
|
GetPropertyValueByIndex(index) {
|
|
switch (index) {
|
|
case FADE_IN_TIME:
|
|
return this._fadeInTime;
|
|
case WAIT_TIME:
|
|
return this._waitTime;
|
|
case FADE_OUT_TIME:
|
|
return this._fadeOutTime;
|
|
case DESTROY:
|
|
return this._destroy
|
|
}
|
|
}
|
|
SetPropertyValueByIndex(index, value) {
|
|
switch (index) {
|
|
case FADE_IN_TIME:
|
|
this._fadeInTime = value;
|
|
break;
|
|
case WAIT_TIME:
|
|
this._waitTime = value;
|
|
break;
|
|
case FADE_OUT_TIME:
|
|
this._fadeOutTime = value;
|
|
break;
|
|
case DESTROY:
|
|
this._destroy = !!value;
|
|
break
|
|
}
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "behaviors.fade";
|
|
return [{
|
|
title: "$" + this.GetBehaviorType().GetName(),
|
|
properties: [{
|
|
name: prefix + ".properties.fade-in-time.name",
|
|
value: this._fadeInTime,
|
|
onedit: v=>this._fadeInTime = v
|
|
}, {
|
|
name: prefix + ".properties.wait-time.name",
|
|
value: this._waitTime,
|
|
onedit: v=>this._waitTime = v
|
|
}, {
|
|
name: prefix + ".properties.fade-out-time.name",
|
|
value: this._fadeOutTime,
|
|
onedit: v=>this._fadeOutTime = v
|
|
}, {
|
|
name: prefix + ".debugger.stage",
|
|
value: [prefix + ".debugger." + ["fade-in", "wait", "fade-out", "done"][this._stage]]
|
|
}]
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Fade.Cnds = {
|
|
OnFadeOutEnd() {
|
|
return true
|
|
},
|
|
OnFadeInEnd() {
|
|
return true
|
|
},
|
|
OnWaitEnd() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Fade.Acts = {
|
|
StartFade() {
|
|
if (!this._activeAtStart && !this._setMaxOpacity) {
|
|
this._maxOpacity = this._inst.GetWorldInfo().GetOpacity() || 1;
|
|
this._setMaxOpacity = true
|
|
}
|
|
if (this._stage === 3)
|
|
this.Start()
|
|
},
|
|
RestartFade() {
|
|
this.Start()
|
|
},
|
|
SetFadeInTime(t) {
|
|
if (t < 0)
|
|
t = 0;
|
|
this._fadeInTime = t
|
|
},
|
|
SetWaitTime(t) {
|
|
if (t < 0)
|
|
t = 0;
|
|
this._waitTime = t
|
|
},
|
|
SetFadeOutTime(t) {
|
|
if (t < 0)
|
|
t = 0;
|
|
this._fadeOutTime = t
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Fade.Exps = {
|
|
FadeInTime() {
|
|
return this._fadeInTime
|
|
},
|
|
WaitTime() {
|
|
return this._waitTime
|
|
},
|
|
FadeOutTime() {
|
|
return this._fadeOutTime
|
|
}
|
|
}
|
|
}
|
|
;"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridviewbind = class aekiro_gridviewbindBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridviewbind.Type = class aekiro_gridviewbindType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridviewbind.Instance = class aekiro_bindInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this.GetObjectInstance().GetUnsavedDataMap().aekiro_gridviewbind = this;
|
|
this.index = -1;
|
|
this.gridView = null;
|
|
this.value = 0;
|
|
}
|
|
setValue(value) {
|
|
this.value = value;
|
|
}
|
|
triggerOnGridViewRender() {
|
|
this.Trigger(C3.Behaviors.aekiro_gridviewbind.Cnds.OnGridViewRender);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {};
|
|
}
|
|
LoadFromJson(o) {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridviewbind.Cnds = {
|
|
IsIndex(index) {
|
|
return (index == this.index);
|
|
},
|
|
OnGridViewRender() {
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridviewbind.Acts = {};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridviewbind.Exps = {
|
|
index() {
|
|
return this.index;
|
|
},
|
|
get(key) {
|
|
var v = self["_"]["get"](this.value, key);
|
|
if (v == undefined) {
|
|
return "";
|
|
} else {
|
|
return v;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Pin = class PinBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Pin.Type = class PinType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Pin.Instance = class PinInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this._pinInst = null;
|
|
this._pinUid = -1;
|
|
this._mode = "";
|
|
this._propSet = new Set;
|
|
this._pinDist = 0;
|
|
this._pinAngle = 0;
|
|
this._pinImagePoint = 0;
|
|
this._dx = 0;
|
|
this._dy = 0;
|
|
this._dWidth = 0;
|
|
this._dHeight = 0;
|
|
this._dAngle = 0;
|
|
this._dz = 0;
|
|
this._lastKnownAngle = 0;
|
|
this._destroy = false;
|
|
if (properties)
|
|
this._destroy = properties[0];
|
|
const rt = this._runtime.Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(rt, "instancedestroy", e=>this._OnInstanceDestroyed(e.instance)),C3.Disposable.From(rt, "afterload", e=>this._OnAfterLoad()))
|
|
}
|
|
Release() {
|
|
this._pinInst = null;
|
|
super.Release()
|
|
}
|
|
_SetPinInst(inst) {
|
|
if (inst) {
|
|
this._pinInst = inst;
|
|
this._StartTicking2()
|
|
} else {
|
|
this._pinInst = null;
|
|
this._StopTicking2()
|
|
}
|
|
}
|
|
_Pin(objectClass, mode, propList) {
|
|
if (!objectClass)
|
|
return;
|
|
const otherInst = objectClass.GetFirstPicked(this._inst);
|
|
if (!otherInst)
|
|
return;
|
|
this._mode = mode;
|
|
this._SetPinInst(otherInst);
|
|
const myWi = this._inst.GetWorldInfo();
|
|
const otherWi = otherInst.GetWorldInfo();
|
|
if (this._mode === "properties") {
|
|
const propSet = this._propSet;
|
|
propSet.clear();
|
|
for (const p of propList)
|
|
propSet.add(p);
|
|
this._dx = myWi.GetX() - otherWi.GetX();
|
|
this._dy = myWi.GetY() - otherWi.GetY();
|
|
this._dAngle = myWi.GetAngle() - otherWi.GetAngle();
|
|
this._lastKnownAngle = myWi.GetAngle();
|
|
this._dz = myWi.GetZElevation() - otherWi.GetZElevation();
|
|
if (propSet.has("x") && propSet.has("y")) {
|
|
this._pinAngle = C3.angleTo(otherWi.GetX(), otherWi.GetY(), myWi.GetX(), myWi.GetY()) - otherWi.GetAngle();
|
|
this._pinDist = C3.distanceTo(otherWi.GetX(), otherWi.GetY(), myWi.GetX(), myWi.GetY())
|
|
}
|
|
if (propSet.has("width-abs"))
|
|
this._dWidth = myWi.GetWidth() - otherWi.GetWidth();
|
|
else if (propSet.has("width-scale"))
|
|
this._dWidth = myWi.GetWidth() / otherWi.GetWidth();
|
|
if (propSet.has("height-abs"))
|
|
this._dHeight = myWi.GetHeight() - otherWi.GetHeight();
|
|
else if (propSet.has("height-scale"))
|
|
this._dHeight = myWi.GetHeight() / otherWi.GetHeight()
|
|
} else
|
|
this._pinDist = C3.distanceTo(otherWi.GetX(), otherWi.GetY(), myWi.GetX(), myWi.GetY())
|
|
}
|
|
SaveToJson() {
|
|
const propSet = this._propSet;
|
|
const mode = this._mode;
|
|
const ret = {
|
|
"uid": this._pinInst ? this._pinInst.GetUID() : -1,
|
|
"m": mode
|
|
};
|
|
if (mode === "rope" || mode === "bar")
|
|
ret["pd"] = this._pinDist;
|
|
else if (mode === "properties") {
|
|
ret["ps"] = [...this._propSet];
|
|
if (propSet.has("imagepoint"))
|
|
ret["ip"] = this._pinImagePoint;
|
|
else if (propSet.has("x") && propSet.has("y")) {
|
|
ret["pa"] = this._pinAngle;
|
|
ret["pd"] = this._pinDist
|
|
} else {
|
|
if (propSet.has("x"))
|
|
ret["dx"] = this._dx;
|
|
if (propSet.has("y"))
|
|
ret["dy"] = this._dy
|
|
}
|
|
if (propSet.has("angle")) {
|
|
ret["da"] = this._dAngle;
|
|
ret["lka"] = this._lastKnownAngle
|
|
}
|
|
if (propSet.has("width-abs") || propSet.has("width-scale"))
|
|
ret["dw"] = this._dWidth;
|
|
if (propSet.has("height-abs") || propSet.has("height-scale"))
|
|
ret["dh"] = this._dHeight;
|
|
if (propSet.has("z"))
|
|
ret["dz"] = this._dz
|
|
}
|
|
return ret
|
|
}
|
|
LoadFromJson(o) {
|
|
const mode = o["m"];
|
|
const propSet = this._propSet;
|
|
propSet.clear();
|
|
this._pinUid = o["uid"];
|
|
if (typeof mode === "number") {
|
|
this._LoadFromJson_Legacy(o);
|
|
return
|
|
}
|
|
this._mode = mode;
|
|
if (mode === "rope" || mode === "bar")
|
|
this._pinDist = o["pd"];
|
|
else if (mode === "properties") {
|
|
for (const p of o["ps"])
|
|
propSet.add(p);
|
|
if (propSet.has("imagepoint"))
|
|
this._pinImagePoint = o["ip"];
|
|
else if (propSet.has("x") && propSet.has("y")) {
|
|
this._pinAngle = o["pa"];
|
|
this._pinDist = o["pd"]
|
|
} else {
|
|
if (propSet.has("x"))
|
|
this._dx = o["dx"];
|
|
if (propSet.has("y"))
|
|
this._dy = o["dy"]
|
|
}
|
|
if (propSet.has("angle")) {
|
|
this._dAngle = o["da"];
|
|
this._lastKnownAngle = o["lka"] || 0
|
|
}
|
|
if (propSet.has("width-abs") || propSet.has("width-scale"))
|
|
this._dWidth = o["dw"];
|
|
if (propSet.has("height-abs") || propSet.has("height-scale"))
|
|
this._dHeight = o["dh"];
|
|
if (propSet.has("z"))
|
|
this._dz = o["dz"]
|
|
}
|
|
}
|
|
_LoadFromJson_Legacy(o) {
|
|
const propSet = this._propSet;
|
|
const myStartAngle = o["msa"];
|
|
const theirStartAngle = o["tsa"];
|
|
const pinAngle = o["pa"];
|
|
const pinDist = o["pd"];
|
|
const mode = o["m"];
|
|
switch (mode) {
|
|
case 0:
|
|
this._mode = "properties";
|
|
propSet.add("x").add("y").add("angle");
|
|
this._pinAngle = pinAngle;
|
|
this._pinDist = pinDist;
|
|
this._dAngle = myStartAngle - theirStartAngle;
|
|
this._lastKnownAngle = o["lka"];
|
|
break;
|
|
case 1:
|
|
this._mode = "properties";
|
|
propSet.add("x").add("y");
|
|
this._pinAngle = pinAngle;
|
|
this._pinDist = pinDist;
|
|
break;
|
|
case 2:
|
|
this._mode = "properties";
|
|
propSet.add("angle");
|
|
this._dAngle = myStartAngle - theirStartAngle;
|
|
this._lastKnownAngle = o["lka"];
|
|
break;
|
|
case 3:
|
|
this._mode = "rope";
|
|
this._pinDist = o["pd"];
|
|
break;
|
|
case 4:
|
|
this._mode = "bar";
|
|
this._pinDist = o["pd"];
|
|
break
|
|
}
|
|
}
|
|
_OnAfterLoad() {
|
|
if (this._pinUid === -1)
|
|
this._SetPinInst(null);
|
|
else {
|
|
this._SetPinInst(this._runtime.GetInstanceByUID(this._pinUid));
|
|
this._pinUid = -1
|
|
}
|
|
}
|
|
_OnInstanceDestroyed(inst) {
|
|
if (this._pinInst === inst) {
|
|
this._SetPinInst(null);
|
|
if (this._destroy)
|
|
this._runtime.DestroyInstance(this._inst)
|
|
}
|
|
}
|
|
Tick2() {
|
|
const pinInst = this._pinInst;
|
|
if (!pinInst)
|
|
return;
|
|
const pinWi = pinInst.GetWorldInfo();
|
|
const myInst = this._inst;
|
|
const myWi = myInst.GetWorldInfo();
|
|
const mode = this._mode;
|
|
let bboxChanged = false;
|
|
if (mode === "rope" || mode === "bar") {
|
|
const dist = C3.distanceTo(myWi.GetX(), myWi.GetY(), pinWi.GetX(), pinWi.GetY());
|
|
if (dist > this._pinDist || mode === "bar" && dist < this._pinDist) {
|
|
const a = C3.angleTo(pinWi.GetX(), pinWi.GetY(), myWi.GetX(), myWi.GetY());
|
|
myWi.SetXY(pinWi.GetX() + Math.cos(a) * this._pinDist, pinWi.GetY() + Math.sin(a) * this._pinDist);
|
|
bboxChanged = true
|
|
}
|
|
} else {
|
|
const propSet = this._propSet;
|
|
let v = 0;
|
|
if (propSet.has("imagepoint")) {
|
|
const [newX,newY] = pinInst.GetImagePoint(this._pinImagePoint);
|
|
if (!myWi.EqualsXY(newX, newY)) {
|
|
myWi.SetXY(newX, newY);
|
|
bboxChanged = true
|
|
}
|
|
} else if (propSet.has("x") && propSet.has("y")) {
|
|
const newX = pinWi.GetX() + Math.cos(pinWi.GetAngle() + this._pinAngle) * this._pinDist;
|
|
const newY = pinWi.GetY() + Math.sin(pinWi.GetAngle() + this._pinAngle) * this._pinDist;
|
|
if (!myWi.EqualsXY(newX, newY)) {
|
|
myWi.SetXY(newX, newY);
|
|
bboxChanged = true
|
|
}
|
|
} else {
|
|
v = pinWi.GetX() + this._dx;
|
|
if (propSet.has("x") && v !== myWi.GetX()) {
|
|
myWi.SetX(v);
|
|
bboxChanged = true
|
|
}
|
|
v = pinWi.GetY() + this._dy;
|
|
if (propSet.has("y") && v !== myWi.GetY()) {
|
|
myWi.SetY(v);
|
|
bboxChanged = true
|
|
}
|
|
}
|
|
if (propSet.has("angle")) {
|
|
if (this._lastKnownAngle !== myWi.GetAngle())
|
|
this._dAngle = C3.clampAngle(this._dAngle + (myWi.GetAngle() - this._lastKnownAngle));
|
|
v = C3.clampAngle(pinWi.GetAngle() + this._dAngle);
|
|
if (v !== myWi.GetAngle()) {
|
|
myWi.SetAngle(v);
|
|
bboxChanged = true
|
|
}
|
|
this._lastKnownAngle = myWi.GetAngle()
|
|
}
|
|
if (propSet.has("width-abs")) {
|
|
v = pinWi.GetWidth() + this._dWidth;
|
|
if (v !== myWi.GetWidth()) {
|
|
myWi.SetWidth(v);
|
|
bboxChanged = true
|
|
}
|
|
}
|
|
if (propSet.has("width-scale")) {
|
|
v = pinWi.GetWidth() * this._dWidth;
|
|
if (v !== myWi.GetWidth()) {
|
|
myWi.SetWidth(v);
|
|
bboxChanged = true
|
|
}
|
|
}
|
|
if (propSet.has("height-abs")) {
|
|
v = pinWi.GetHeight() + this._dHeight;
|
|
if (v !== myWi.GetHeight()) {
|
|
myWi.SetHeight(v);
|
|
bboxChanged = true
|
|
}
|
|
}
|
|
if (propSet.has("height-scale")) {
|
|
v = pinWi.GetHeight() * this._dHeight;
|
|
if (v !== myWi.GetHeight()) {
|
|
myWi.SetHeight(v);
|
|
bboxChanged = true
|
|
}
|
|
}
|
|
if (propSet.has("z")) {
|
|
v = pinWi.GetZElevation() + this._dz;
|
|
if (v !== myWi.GetZElevation()) {
|
|
myWi.SetZElevation(v);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
}
|
|
}
|
|
if (bboxChanged)
|
|
myWi.SetBboxChanged()
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "behaviors.pin.debugger";
|
|
return [{
|
|
title: "$" + this.GetBehaviorType().GetName(),
|
|
properties: [{
|
|
name: prefix + ".is-pinned",
|
|
value: !!this._pinInst
|
|
}, {
|
|
name: prefix + ".pinned-uid",
|
|
value: this._pinInst ? this._pinInst.GetUID() : 0
|
|
}]
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Pin.Cnds = {
|
|
IsPinned() {
|
|
return !!this._pinInst
|
|
},
|
|
WillDestroy() {
|
|
return this._destroy
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Pin.Acts = {
|
|
PinByDistance(objectClass, mode) {
|
|
this._Pin(objectClass, mode === 0 ? "rope" : "bar")
|
|
},
|
|
PinByProperties(objectClass, ex, ey, ea, ew, eh, ez) {
|
|
const propList = [];
|
|
if (ex)
|
|
propList.push("x");
|
|
if (ey)
|
|
propList.push("y");
|
|
if (ea)
|
|
propList.push("angle");
|
|
if (ez)
|
|
propList.push("z");
|
|
if (ew === 1)
|
|
propList.push("width-abs");
|
|
else if (ew === 2)
|
|
propList.push("width-scale");
|
|
if (eh === 1)
|
|
propList.push("height-abs");
|
|
else if (eh === 2)
|
|
propList.push("height-scale");
|
|
if (propList.length === 0)
|
|
return;
|
|
this._Pin(objectClass, "properties", propList)
|
|
},
|
|
PinByImagePoint(objectClass, imgPt, ea, ew, eh, ez) {
|
|
const propList = ["imagepoint"];
|
|
if (ea)
|
|
propList.push("angle");
|
|
if (ez)
|
|
propList.push("z");
|
|
if (ew === 1)
|
|
propList.push("width-abs");
|
|
else if (ew === 2)
|
|
propList.push("width-scale");
|
|
if (eh === 1)
|
|
propList.push("height-abs");
|
|
else if (eh === 2)
|
|
propList.push("height-scale");
|
|
this._pinImagePoint = imgPt;
|
|
this._Pin(objectClass, "properties", propList)
|
|
},
|
|
SetPinDistance(d) {
|
|
if (this._mode === "rope" || this._mode === "bar")
|
|
this._pinDist = Math.max(d, 0)
|
|
},
|
|
SetDestroy(d) {
|
|
this._destroy = d
|
|
},
|
|
Unpin() {
|
|
this._SetPinInst(null);
|
|
this._mode = "";
|
|
this._propSet.clear();
|
|
this._pinImagePoint = ""
|
|
},
|
|
Pin(objectClass, mode) {
|
|
switch (mode) {
|
|
case 0:
|
|
this._Pin(objectClass, "properties", ["x", "y", "angle"]);
|
|
break;
|
|
case 1:
|
|
this._Pin(objectClass, "properties", ["x", "y"]);
|
|
break;
|
|
case 2:
|
|
this._Pin(objectClass, "properties", ["angle"]);
|
|
break;
|
|
case 3:
|
|
this._Pin(objectClass, "rope");
|
|
break;
|
|
case 4:
|
|
this._Pin(objectClass, "bar");
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Pin.Exps = {
|
|
PinnedUID() {
|
|
return this._pinInst ? this._pinInst.GetUID() : -1
|
|
}
|
|
}
|
|
}
|
|
;"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_button = class aekiro_buttonBehavior extends C3.SDKBehaviorBase {
|
|
constructor(a) {
|
|
super(a);
|
|
const b = this._runtime.Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(b, "pointerdown", (a)=>this._OnPointerDown(a.data)),C3.Disposable.From(b, "pointermove", (a)=>this._OnPointerMove(a.data)),C3.Disposable.From(b, "pointerup", (a)=>this._OnPointerUp(a.data, !1)),C3.Disposable.From(b, "pointercancel", (a)=>this._OnPointerUp(a.data, !0)))
|
|
}
|
|
Release() {
|
|
this._disposables.Release(),
|
|
this._disposables = null,
|
|
super.Release();
|
|
}
|
|
_OnPointerDown(a) {
|
|
this._OnInputDown(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnPointerMove(a) {
|
|
this._OnInputMove(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnPointerUp(a) {
|
|
this._OnInputUp(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
async _OnInputDown(source, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_button);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputDown)
|
|
await beh.OnAnyInputDown(x, y, source);
|
|
}
|
|
}
|
|
_OnInputMove(source, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_button);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputMove)
|
|
beh.OnAnyInputMove(x, y, source);
|
|
}
|
|
}
|
|
async _OnInputUp(a, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_button);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputUp)
|
|
await beh.OnAnyInputUp(x, y);
|
|
}
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_button.Type = class aekiro_buttonType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_button.Instance = class aekiro_buttonInstance extends Aekiro.button {
|
|
constructor(behInst, properties) {
|
|
super(behInst, properties);
|
|
this.isEnabled = properties[0];
|
|
this.frame_normal = properties[1];
|
|
this.frame_hover = properties[2];
|
|
this.frame_clicked = properties[3];
|
|
this.frame_disabled = properties[4];
|
|
this.frame_focus = properties[5];
|
|
this.clickSound = properties[6];
|
|
this.hoverSound = properties[7];
|
|
this.focusSound = properties[8];
|
|
this.clickAnimation = properties[9];
|
|
this.hoverAnimation = properties[10];
|
|
this.focusAnimation = properties[11];
|
|
this.color_normal = properties[12];
|
|
this.color_hover = properties[13];
|
|
this.color_clicked = properties[14];
|
|
this.color_disabled = properties[15];
|
|
this.color_focus = properties[16];
|
|
this.clickAnimationFactor = properties[17];
|
|
this.hoverAnimationFactor = properties[18];
|
|
this.focusAnimationFactor = properties[19];
|
|
this.ignoreInput = properties[20];
|
|
this.button_constructor();
|
|
}
|
|
OnAnyInputUpC() {
|
|
this.Trigger(C3.Behaviors.aekiro_button.Cnds.OnClicked);
|
|
this.proui.Trigger(C3.Plugins.aekiro_proui.Cnds.OnAnyButtonClicked);
|
|
}
|
|
OnMouseEnterC() {
|
|
this.Trigger(C3.Behaviors.aekiro_button.Cnds.OnMouseEnter);
|
|
}
|
|
OnMouseLeaveC() {
|
|
this.Trigger(C3.Behaviors.aekiro_button.Cnds.OnMouseLeave);
|
|
}
|
|
OnFocusedC() {
|
|
this.Trigger(C3.Behaviors.aekiro_button.Cnds.OnFocused);
|
|
}
|
|
OnUnFocusedC() {
|
|
this.Trigger(C3.Behaviors.aekiro_button.Cnds.OnUnFocused);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"isEnabled": this.isEnabled,
|
|
"frame_normal": this.frame_normal,
|
|
"frame_hover": this.frame_hover,
|
|
"frame_clicked": this.frame_clicked,
|
|
"frame_disabled": this.frame_disabled,
|
|
"frame_focus": this.frame_focus,
|
|
"clickSound": this.clickSound,
|
|
"hoverSound": this.hoverSound,
|
|
"focusSound": this.focusSound,
|
|
"clickAnimation": this.clickAnimation,
|
|
"hoverAnimation": this.hoverAnimation,
|
|
"focusAnimation": this.focusAnimation,
|
|
"color_normal": this.color_normal,
|
|
"color_hover": this.color_hover,
|
|
"color_clicked": this.color_clicked,
|
|
"color_disabled": this.color_disabled,
|
|
"color_focus": this.color_focus,
|
|
"ignoreInput": this.ignoreInput,
|
|
"initProps": this.initProps
|
|
};
|
|
}
|
|
LoadFromJson(o) {
|
|
this.isEnabled = o["isEnabled"];
|
|
this.frame_normal = o["frame_normal"];
|
|
this.frame_hover = o["frame_hover"];
|
|
this.frame_clicked = o["frame_clicked"];
|
|
this.frame_disabled = o["frame_disabled"];
|
|
this.frame_focus = o["frame_focus"];
|
|
this.clickSound = o["clickSound"];
|
|
this.hoverSound = o["hoverSound"];
|
|
this.focusSound = o["focusSound"];
|
|
this.clickAnimation = o["clickAnimation"];
|
|
this.hoverAnimation = o["hoverAnimation"];
|
|
this.focusAnimation = o["focusAnimation"];
|
|
this.color_normal = o["color_normal"];
|
|
this.color_hover = o["color_hover"];
|
|
this.color_clicked = o["color_clicked"];
|
|
this.color_disabled = o["color_disabled"];
|
|
this.color_focus = o["color_focus"];
|
|
this.ignoreInput = o["ignoreInput"];
|
|
this.initProps = o["initProps"];
|
|
this.onInitPropsLoaded();
|
|
this.onPropsLoaded();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_button.Cnds = {};
|
|
Object.assign(C3.Behaviors.aekiro_button.Cnds, Aekiro.button.Cnds);
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_button.Acts = {};
|
|
Object.assign(C3.Behaviors.aekiro_button.Acts, Aekiro.button.Acts);
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_button.Exps = {};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_checkbox = class aekiro_checkboxBehavior extends C3.SDKBehaviorBase {
|
|
constructor(a) {
|
|
super(a);
|
|
const b = this._runtime.Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(b, "pointerdown", (a)=>this._OnPointerDown(a.data)),C3.Disposable.From(b, "pointermove", (a)=>this._OnPointerMove(a.data)),C3.Disposable.From(b, "pointerup", (a)=>this._OnPointerUp(a.data, !1)),C3.Disposable.From(b, "pointercancel", (a)=>this._OnPointerUp(a.data, !0)))
|
|
}
|
|
Release() {
|
|
this._disposables.Release(),
|
|
this._disposables = null,
|
|
super.Release()
|
|
}
|
|
_OnPointerDown(a) {
|
|
this._OnInputDown(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnPointerMove(a) {
|
|
this._OnInputMove(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnPointerUp(a) {
|
|
this._OnInputUp(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
async _OnInputDown(source, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_checkbox);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputDown)
|
|
await beh.OnAnyInputDown(x, y, source);
|
|
}
|
|
}
|
|
_OnInputMove(source, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_checkbox);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputMove)
|
|
beh.OnAnyInputMove(x, y, source);
|
|
}
|
|
}
|
|
async _OnInputUp(a, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_checkbox);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputUp)
|
|
await beh.OnAnyInputUp(x, y);
|
|
}
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_checkbox.Type = class aekiro_checkboxType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_checkbox.Instance = class aekiro_checkboxInstance extends Aekiro.checkbox {
|
|
constructor(behInst, properties) {
|
|
super(behInst, properties);
|
|
this.isEnabled = properties[0];
|
|
this.value = properties[1];
|
|
this.frame_normal = properties[2];
|
|
this.frame_hover = properties[3];
|
|
this.frame_disabled = properties[4];
|
|
this.frame_focus = properties[5];
|
|
this.clickSound = properties[6];
|
|
this.hoverSound = properties[7];
|
|
this.focusSound = properties[8];
|
|
this.clickAnimation = properties[9];
|
|
this.hoverAnimation = properties[10];
|
|
this.focusAnimation = properties[11];
|
|
this.color_normal = properties[12];
|
|
this.color_hover = properties[13];
|
|
this.color_clicked = properties[14];
|
|
this.color_disabled = properties[15];
|
|
this.color_focus = properties[16];
|
|
this.clickAnimationFactor = properties[17];
|
|
this.hoverAnimationFactor = properties[18];
|
|
this.focusAnimationFactor = properties[19];
|
|
this.ignoreInput = properties[20];
|
|
this.checkbox_constructor();
|
|
}
|
|
OnAnyInputUpC() {
|
|
this.setValue(1 - this.value);
|
|
this.Trigger(C3.Behaviors.aekiro_checkbox.Cnds.OnClicked);
|
|
}
|
|
OnMouseEnterC() {
|
|
this.Trigger(C3.Behaviors.aekiro_checkbox.Cnds.OnMouseEnter);
|
|
}
|
|
OnMouseLeaveC() {
|
|
this.Trigger(C3.Behaviors.aekiro_checkbox.Cnds.OnMouseLeave);
|
|
}
|
|
OnFocusedC() {
|
|
this.Trigger(C3.Behaviors.aekiro_checkbox.Cnds.OnFocused);
|
|
}
|
|
OnUnFocusedC() {
|
|
this.Trigger(C3.Behaviors.aekiro_checkbox.Cnds.OnUnFocused);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"isEnabled": this.isEnabled,
|
|
"value": this.value,
|
|
"frame_normal": this.frame_normal,
|
|
"frame_hover": this.frame_hover,
|
|
"frame_disabled": this.frame_disabled,
|
|
"frame_focus": this.frame_focus,
|
|
"clickSound": this.clickSound,
|
|
"hoverSound": this.hoverSound,
|
|
"focusSound": this.focusSound,
|
|
"clickAnimation": this.clickAnimation,
|
|
"hoverAnimation": this.hoverAnimation,
|
|
"focusAnimation": this.focusAnimation,
|
|
"color_normal": this.color_normal,
|
|
"color_hover": this.color_hover,
|
|
"color_clicked": this.color_clicked,
|
|
"color_disabled": this.color_disabled,
|
|
"color_focus": this.color_focus,
|
|
"ignoreInput": this.ignoreInput,
|
|
"initProps": this.initProps
|
|
};
|
|
}
|
|
LoadFromJson(o) {
|
|
this.isEnabled = o["isEnabled"];
|
|
this.value = o["value"];
|
|
this.frame_normal = o["frame_normal"];
|
|
this.frame_hover = o["frame_hover"];
|
|
this.frame_disabled = o["frame_disabled"];
|
|
this.frame_focus = o["frame_focus"];
|
|
this.clickSound = o["clickSound"];
|
|
this.hoverSound = o["hoverSound"];
|
|
this.focusSound = o["focusSound"];
|
|
this.clickAnimation = o["clickAnimation"];
|
|
this.hoverAnimation = o["hoverAnimation"];
|
|
this.focusAnimation = o["focusAnimation"];
|
|
this.color_normal = o["color_normal"];
|
|
this.color_hover = o["color_hover"];
|
|
this.color_clicked = o["color_clicked"];
|
|
this.color_disabled = o["color_disabled"];
|
|
this.color_focus = o["color_focus"];
|
|
this.ignoreInput = o["ignoreInput"];
|
|
this.initProps = o["initProps"];
|
|
this.onInitPropsLoaded();
|
|
this.onPropsLoaded();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_checkbox.Cnds = {
|
|
IsChecked() {
|
|
return this.value;
|
|
}
|
|
};
|
|
Object.assign(C3.Behaviors.aekiro_checkbox.Cnds, Aekiro.button.Cnds);
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_checkbox.Acts = {
|
|
setValue(value) {
|
|
this.setValue(value);
|
|
},
|
|
SetIgnoreInput(s) {
|
|
this.setIgnoreInput(s);
|
|
},
|
|
SetClickSoundVolume(v) {
|
|
this.audioSources.click.setVolume(v);
|
|
},
|
|
SetHoverSoundVolume(v) {
|
|
this.audioSources.hover.setVolume(v);
|
|
}
|
|
};
|
|
Object.assign(C3.Behaviors.aekiro_checkbox.Acts, Aekiro.button.Acts);
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_checkbox.Exps = {
|
|
value() {
|
|
return this.value;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiobutton = class aekiro_radiobuttonBehavior extends C3.SDKBehaviorBase {
|
|
constructor(a) {
|
|
super(a);
|
|
const b = this._runtime.Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(b, "pointerdown", (a)=>this._OnPointerDown(a.data)),C3.Disposable.From(b, "pointermove", (a)=>this._OnPointerMove(a.data)),C3.Disposable.From(b, "pointerup", (a)=>this._OnPointerUp(a.data, !1)),C3.Disposable.From(b, "pointercancel", (a)=>this._OnPointerUp(a.data, !0)));
|
|
}
|
|
Release() {
|
|
this._disposables.Release(),
|
|
this._disposables = null,
|
|
super.Release()
|
|
}
|
|
_OnPointerDown(a) {
|
|
this._OnInputDown(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnPointerMove(a) {
|
|
this._OnInputMove(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnPointerUp(a) {
|
|
this._OnInputUp(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
async _OnInputDown(source, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_radiobutton);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputDown)
|
|
await beh.OnAnyInputDown(x, y, source);
|
|
}
|
|
}
|
|
_OnInputMove(source, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_radiobutton);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputMove)
|
|
beh.OnAnyInputMove(x, y, source);
|
|
}
|
|
}
|
|
async _OnInputUp(a, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_radiobutton);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputUp)
|
|
await beh.OnAnyInputUp(x, y);
|
|
}
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiobutton.Type = class aekiro_radiobuttonType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiobutton.Instance = class aekiro_radiobuttonInstance extends globalThis.Aekiro.checkbox {
|
|
constructor(behInst, properties) {
|
|
super(behInst, properties);
|
|
this.isEnabled = properties[0];
|
|
this.name = properties[1];
|
|
this.frame_normal = properties[2];
|
|
this.frame_hover = properties[3];
|
|
this.frame_disabled = properties[4];
|
|
this.frame_focus = properties[5];
|
|
this.clickSound = properties[6];
|
|
this.hoverSound = properties[7];
|
|
this.focusSound = properties[8];
|
|
this.clickAnimation = properties[9];
|
|
this.hoverAnimation = properties[10];
|
|
this.focusAnimation = properties[11];
|
|
this.color_normal = properties[12];
|
|
this.color_hover = properties[13];
|
|
this.color_clicked = properties[14];
|
|
this.color_disabled = properties[15];
|
|
this.color_focus = properties[16];
|
|
this.clickAnimationFactor = properties[17];
|
|
this.hoverAnimationFactor = properties[18];
|
|
this.focusAnimationFactor = properties[19];
|
|
this.ignoreInput = properties[17];
|
|
this.GetObjectInstance().GetUnsavedDataMap().aekiro_radiobutton = this;
|
|
this.checkbox_constructor();
|
|
}
|
|
init() {
|
|
if (!this.aekiro_gameobject) {
|
|
return;
|
|
}
|
|
this.radioGroup = this.aekiro_gameobject.parent_get();
|
|
if (!this.radioGroup) {
|
|
console.error("ProUI-Radiobutton uid=%s: Radiogroup not found.", this.inst.GetUID());
|
|
return;
|
|
}
|
|
if (!this.radioGroup.GetUnsavedDataMap().aekiro_radiogroup) {
|
|
console.error("ProUI-Radiobutton uid=%s: Radiogroup needs to have a Radiogroup behavior.", this.inst.GetUID());
|
|
return;
|
|
}
|
|
this.radioGroup = this.radioGroup.GetUnsavedDataMap().aekiro_radiogroup;
|
|
}
|
|
GetRadioGroup() {
|
|
var p = this.aekiro_gameobject.parent_get();
|
|
if (p) {
|
|
return p.GetUnsavedDataMap().aekiro_radiogroup;
|
|
}
|
|
return null;
|
|
}
|
|
setEnabled(isEnabled) {
|
|
super.setEnabled(isEnabled);
|
|
var radioGroup = this.GetRadioGroup();
|
|
if (isEnabled && radioGroup) {
|
|
radioGroup.isEnabled = isEnabled;
|
|
}
|
|
}
|
|
OnAnyInputUpC() {
|
|
var radioGroup = this.GetRadioGroup();
|
|
if (radioGroup) {
|
|
radioGroup.setValue(this.name);
|
|
}
|
|
this.Trigger(C3.Behaviors.aekiro_radiobutton.Cnds.OnClicked);
|
|
}
|
|
OnMouseEnterC() {
|
|
this.Trigger(C3.Behaviors.aekiro_radiobutton.Cnds.OnMouseEnter);
|
|
}
|
|
OnMouseLeaveC() {
|
|
this.Trigger(C3.Behaviors.aekiro_radiobutton.Cnds.OnMouseLeave);
|
|
}
|
|
OnFocusedC() {
|
|
this.Trigger(C3.Behaviors.aekiro_radiobutton.Cnds.OnFocused);
|
|
}
|
|
OnUnFocusedC() {
|
|
this.Trigger(C3.Behaviors.aekiro_radiobutton.Cnds.OnUnFocused);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"isEnabled": this.isEnabled,
|
|
"name": this.name,
|
|
"frame_normal": this.frame_normal,
|
|
"frame_hover": this.frame_hover,
|
|
"frame_disabled": this.frame_disabled,
|
|
"frame_focus": this.frame_focus,
|
|
"clickSound": this.clickSound,
|
|
"hoverSound": this.hoverSound,
|
|
"focusSound": this.focusSound,
|
|
"clickAnimation": this.clickAnimation,
|
|
"hoverAnimation": this.hoverAnimation,
|
|
"focusAnimation": this.focusAnimation,
|
|
"color_normal": this.color_normal,
|
|
"color_hover": this.color_hover,
|
|
"color_clicked": this.color_clicked,
|
|
"color_disabled": this.color_disabled,
|
|
"color_focus": this.color_focus,
|
|
"ignoreInput": this.ignoreInput,
|
|
"initProps": this.initProps
|
|
};
|
|
}
|
|
LoadFromJson(o) {
|
|
this.isEnabled = o["isEnabled"];
|
|
this.name = o["name"];
|
|
this.frame_normal = o["frame_normal"];
|
|
this.frame_hover = o["frame_hover"];
|
|
this.frame_disabled = o["frame_disabled"];
|
|
this.frame_focus = o["frame_focus"];
|
|
this.clickSound = o["clickSound"];
|
|
this.hoverSound = o["hoverSound"];
|
|
this.focusSound = o["focusSound"];
|
|
this.clickAnimation = o["clickAnimation"];
|
|
this.hoverAnimation = o["hoverAnimation"];
|
|
this.focusAnimation = o["focusAnimation"];
|
|
this.color_normal = o["color_normal"];
|
|
this.color_hover = o["color_hover"];
|
|
this.color_clicked = o["color_clicked"];
|
|
this.color_disabled = o["color_disabled"];
|
|
this.color_focus = o["color_focus"];
|
|
this.ignoreInput = o["ignoreInput"];
|
|
this.initProps = o["initProps"];
|
|
this.onInitPropsLoaded();
|
|
this.onPropsLoaded();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiobutton.Cnds = {};
|
|
Object.assign(C3.Behaviors.aekiro_radiobutton.Cnds, globalThis.Aekiro.button.Cnds);
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiobutton.Acts = {
|
|
SetIgnoreInput(s) {
|
|
this.setIgnoreInput(s);
|
|
},
|
|
SetClickSoundVolume(v) {
|
|
this.audioSources.click.setVolume(v);
|
|
},
|
|
SetHoverSoundVolume(v) {
|
|
this.audioSources.hover.setVolume(v);
|
|
},
|
|
SetName(v) {
|
|
this.name = v;
|
|
}
|
|
};
|
|
Object.assign(C3.Behaviors.aekiro_radiobutton.Acts, globalThis.Aekiro.button.Acts);
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiobutton.Exps = {
|
|
name() {
|
|
return this.name;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_progress = class aekiro_progressBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_progress.Type = class aekiro_progressType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
var Tween = globalThis["TWEEN"];
|
|
C3.Behaviors.aekiro_progress.Instance = class aekiro_progressInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
if (properties) {
|
|
this.maxValue = properties[0];
|
|
this.value = C3.clamp(properties[1], 0, this.maxValue);
|
|
this.animation = properties[2];
|
|
}
|
|
this.inst = this.GetObjectInstance();
|
|
this.wi = this.GetWorldInfo();
|
|
this.goManager = globalThis.aekiro_goManager;
|
|
this.aekiro_dialogManager = globalThis.aekiro_dialogManager;
|
|
this.goManager.eventManager.on("childrenRegistred", ()=>this.init(), {
|
|
"once": true
|
|
});
|
|
}
|
|
PostCreate() {
|
|
this.aekiro_gameobject = this.GetObjectInstance().GetUnsavedDataMap().aekiro_gameobject;
|
|
if (this.aekiro_gameobject) {
|
|
this.aekiro_gameobject.eventManager.on("cloned", ()=>this.init(), {
|
|
"once": true
|
|
});
|
|
}
|
|
}
|
|
init() {
|
|
var wi = this.wi;
|
|
this.initWidth = wi.GetWidth();
|
|
this.transf = {
|
|
width: wi.GetWidth()
|
|
};
|
|
this.tween = new Tween["Tween"](this.transf);
|
|
if (this.animation == 1) {
|
|
this.tween["easing"](Tween["Easing"]["Linear"]["None"]);
|
|
} else if (this.animation == 2) {
|
|
this.tween["easing"](Tween["Easing"]["Quadratic"]["Out"]);
|
|
}
|
|
this.updateView();
|
|
}
|
|
onInitPropsLoaded() {
|
|
var wi = this.wi;
|
|
wi.SetWidth(this.initWidth, true);
|
|
}
|
|
isValueValid(value) {
|
|
if (value == null || isNaN(value) || value === "") {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
setMaxValue(v) {
|
|
this.maxValue = v;
|
|
this.value = C3.clamp(this.value, 0, this.maxValue);
|
|
this.updateView();
|
|
}
|
|
setValue(value) {
|
|
if (!this.isValueValid(value)) {
|
|
return false;
|
|
}
|
|
value = C3.clamp(value, 0, this.maxValue);
|
|
if (this.value != value) {
|
|
this.value = value;
|
|
this.updateView();
|
|
}
|
|
}
|
|
updateView() {
|
|
var targetProp = 0;
|
|
var progress = this.value / this.maxValue;
|
|
targetProp = progress * this.initWidth;
|
|
if (this.animation) {
|
|
var wi = this.wi;
|
|
this.transf.width = wi.GetWidth();
|
|
this.tween["to"]({
|
|
width: targetProp
|
|
}, 500)["start"]();
|
|
this._StartTicking();
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
} else {
|
|
this.wi.SetWidth(targetProp, true);
|
|
this.wi.SetBboxChanged();
|
|
if (this.tween["isPlaying"]) {
|
|
this.tween["stop"]();
|
|
this.isTweenPlaying = false;
|
|
}
|
|
}
|
|
}
|
|
Tick() {
|
|
if (this.isTweenPlaying) {
|
|
this.isTweenPlaying = false;
|
|
}
|
|
if (this.tween["isPlaying"]) {
|
|
this.tween["update"](this.GetRuntime().GetWallTime() * 1000);
|
|
this.isTweenPlaying = true;
|
|
}
|
|
if (this.isTweenPlaying) {
|
|
this.wi.SetWidth(this.transf.width, true);
|
|
this.wi.SetBboxChanged();
|
|
} else {
|
|
this._StopTicking();
|
|
}
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"maxValue": this.maxValue,
|
|
"value": this.value,
|
|
"animation": this.animation,
|
|
"initWidth": this.initWidth
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this.maxValue = o["maxValue"];
|
|
this.value = o["value"];
|
|
this.animation = o["animation"];
|
|
this.initWidth = o["initWidth"];
|
|
this.onInitPropsLoaded();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_progress.Cnds = {};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_progress.Acts = {
|
|
setValue(value, animation) {
|
|
this.animation = animation;
|
|
this.setValue(value);
|
|
},
|
|
SetMaxValue(v) {
|
|
this.setMaxValue(v);
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_progress.Exps = {
|
|
value() {
|
|
return this.value;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.mcube_rexspline = class MCRexSpline extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.mcube_rexspline.Type = class MCRexSplineType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.mcube_rexspline.Instance = class MCRexSplineInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this._myProperty = 0;
|
|
if (properties) {
|
|
this._myProperty = properties[0];
|
|
this.enabled = (properties[0] === 1);
|
|
this.speed = properties[1];
|
|
this.setAngle = (properties[2] !== 0);
|
|
this.isLooping = (properties[3] === 1);
|
|
this.tension = properties[4];
|
|
}
|
|
if (!this.recycled) {
|
|
this.points = [];
|
|
this.curSeg = {
|
|
ptr: -1,
|
|
t: 1,
|
|
p0: null,
|
|
p1: null,
|
|
p2: null,
|
|
p3: null,
|
|
dist: 0,
|
|
preX: 0,
|
|
preY: 0
|
|
};
|
|
}
|
|
this.traveledDist = 0;
|
|
this.movingAngle = 0;
|
|
this.is_moving = false;
|
|
this.is_my_call = false;
|
|
this.lastTick = null;
|
|
this.LASTU;
|
|
this.LASTUU;
|
|
this.LASTUUU;
|
|
this.wi = this._inst.GetWorldInfo();
|
|
this._StartTicking();
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {};
|
|
}
|
|
LoadFromJson(o) {}
|
|
Tick() {
|
|
if (!this.enabled || !this.is_moving) {
|
|
return;
|
|
} else {
|
|
const dt = this._runtime.GetDt(this._inst);
|
|
this.move(dt);
|
|
}
|
|
}
|
|
move(dt) {
|
|
if (dt == null)
|
|
dt = this._runtime.GetDt(this._inst);
|
|
if ((dt === 0) || (this.speed == 0))
|
|
return;
|
|
var tickMovingDist = this.speed * dt;
|
|
var tMD2 = tickMovingDist * tickMovingDist;
|
|
var sTickMovingDist = tickMovingDist / 20;
|
|
var segDist = null, t;
|
|
var x0 = this.wi._x
|
|
, y0 = this.wi._y;
|
|
var seg, nx, ny, dist, dist2, i = 0;
|
|
var preX, preY, preDist2, preSegT;
|
|
while (1) {
|
|
seg = this.getSeg();
|
|
if (seg == null)
|
|
break;
|
|
if (seg.dist === 0)
|
|
continue;
|
|
if (segDist !== seg.dist) {
|
|
segDist = seg.dist
|
|
t = (sTickMovingDist / segDist);
|
|
if (t > 0.5)
|
|
t = 0.5;
|
|
}
|
|
seg.t += t;
|
|
i++;
|
|
if (seg.t >= 1) {
|
|
seg.t = 1;
|
|
nx = seg.p2[0];
|
|
ny = seg.p2[1];
|
|
} else {
|
|
nx = this.interpolate(seg, 0, this.tension);
|
|
ny = this.interpolate(seg, 1, this.tension);
|
|
}
|
|
dist2 = this.distance2(x0, y0, nx, ny);
|
|
if (dist2 >= tMD2) {
|
|
if (Math.abs(preDist2 - tMD2) < Math.abs(dist2 - tMD2)) {
|
|
nx = preX;
|
|
ny = preY;
|
|
dist2 = preDist2;
|
|
seg.t = preSegT;
|
|
}
|
|
dist = Math.sqrt(dist2);
|
|
this.traveledDist += dist;
|
|
this.wi.SetX(nx);
|
|
this.wi.SetY(ny);
|
|
break;
|
|
} else {
|
|
preX = nx;
|
|
preY = ny;
|
|
preDist2 = dist2;
|
|
preSegT = (seg.t === 1) ? 0 : seg.t;
|
|
}
|
|
}
|
|
if ((x0 === this.wi._x) && (y0 === this.wi._y)) {} else {
|
|
this.movingAngle = C3.angleTo(x0, y0, this.wi._x, this.wi._y);
|
|
}
|
|
if (this.setAngle) {
|
|
if (this.is_moving) {
|
|
this.wi.SetAngle(this.movingAngle);
|
|
}
|
|
}
|
|
if (this.speed !== 0) {
|
|
this.wi.SetBboxChanged();
|
|
if (seg == null) {
|
|
this.onReachLastPoint();
|
|
} else {
|
|
seg.preX = nx;
|
|
seg.preY = ny;
|
|
}
|
|
}
|
|
}
|
|
start() {
|
|
this.curSeg.ptr = -1;
|
|
this.curSeg.t = 1;
|
|
this.traveledDist = 0;
|
|
this.is_moving = true;
|
|
var seg = this.getSeg();
|
|
if (seg === null)
|
|
this.onReachLastPoint();
|
|
}
|
|
onReachLastPoint() {
|
|
if (!this.is_moving)
|
|
return;
|
|
this.is_moving = false;
|
|
this.is_my_call = true;
|
|
this.Trigger(C3.Behaviors.mcube_rexspline.Cnds.OnHitTarget, this.wi);
|
|
this.is_my_call = false;
|
|
}
|
|
hitPoint() {
|
|
this.is_my_call = true;
|
|
this.Trigger(C3.Behaviors.mcube_rexspline.Cnds.OnHitAnyPoint, this.wi);
|
|
this.is_my_call = false;
|
|
}
|
|
wrapIndex(idx) {
|
|
if (this.isLooping) {
|
|
var cnt = this.points.length;
|
|
idx = idx % cnt;
|
|
if (idx < 0)
|
|
idx = cnt + idx;
|
|
}
|
|
return idx;
|
|
}
|
|
getSeg() {
|
|
if (this.curSeg.t === 1) {
|
|
this.curSeg.ptr = this.wrapIndex(this.curSeg.ptr + 1);
|
|
var ptr1 = this.curSeg.ptr;
|
|
var ptr2 = this.wrapIndex(ptr1 + 1);
|
|
if (ptr2 >= this.points.length)
|
|
return null;
|
|
var ptr0 = this.wrapIndex(ptr1 - 1);
|
|
var ptr3 = this.wrapIndex(ptr2 + 1);
|
|
this.curSeg.p0 = this.points[ptr0];
|
|
this.curSeg.p1 = this.points[ptr1];
|
|
this.curSeg.p2 = this.points[ptr2];
|
|
this.curSeg.p3 = this.points[ptr3];
|
|
this.curSeg.dist = C3.distanceTo(this.curSeg.p1[0], this.curSeg.p1[1], this.curSeg.p2[0], this.curSeg.p2[1]);
|
|
this.curSeg.t = 0;
|
|
this.curSeg.preX = this.curSeg.p1[0];
|
|
this.curSeg.preY = this.curSeg.p1[1];
|
|
this.hitPoint();
|
|
}
|
|
return this.curSeg;
|
|
}
|
|
interpolate(seg, i, tension) {
|
|
var p1 = seg.p1[i];
|
|
var p2 = seg.p2[i];
|
|
var t = seg.t;
|
|
var p0 = (seg.p0) ? seg.p0[i] : p1 + (p1 - p2);
|
|
var p3 = (seg.p3) ? seg.p3[i] : p2 + (p2 - p1);
|
|
var u, uu, uuu;
|
|
if (t === this.LASTU) {
|
|
u = this.LASTU;
|
|
uu = this.LASTUU;
|
|
uuu = this.LASTUUU;
|
|
} else {
|
|
this.LASTU = u = t;
|
|
this.LASTUU = uu = u * u;
|
|
this.LASTUUU = uuu = uu * u;
|
|
}
|
|
return (-tension * u + 2 * tension * uu - tension * uuu) * p0 + (+1 + (tension - 3) * uu + (2 - tension) * uuu) * p1 + (+tension * u + (3 - 2 * tension) * uu + (tension - 2) * uuu) * p2 + (-tension * uu + tension * uuu) * p3;
|
|
}
|
|
din(d, default_value) {
|
|
var o;
|
|
if (d === true)
|
|
o = 1;
|
|
else if (d === false)
|
|
o = 0;
|
|
else if (d == null) {
|
|
if (default_value != null)
|
|
o = default_value;
|
|
else
|
|
o = 0;
|
|
} else if (typeof (d) == "object")
|
|
o = JSON.stringify(d);
|
|
else
|
|
o = d;
|
|
return o;
|
|
}
|
|
distance2(x0, y0, x1, y1) {
|
|
var dx = (x1 - x0);
|
|
var dy = (y1 - y0);
|
|
return dx * dx + dy * dy;
|
|
}
|
|
isTickChanged() {
|
|
var curTick = this._runtime.GetTickCount();
|
|
var tickChanged = (this.lastTick != curTick);
|
|
this.lastTick = curTick;
|
|
return tickChanged;
|
|
}
|
|
getMovingAngle(ret) {
|
|
if (this.isTickChanged()) {
|
|
return to_clamped_degrees(this.movingAngle);
|
|
}
|
|
}
|
|
}
|
|
;
|
|
}
|
|
var clamp_angle_degrees = function(a) {
|
|
a %= 360;
|
|
if (a < 0)
|
|
a += 360;
|
|
return a;
|
|
};
|
|
var to_degrees = function(x) {
|
|
return x * (180.0 / Math.PI);
|
|
};
|
|
var to_clamped_degrees = function(x) {
|
|
return clamp_angle_degrees(to_degrees(x));
|
|
};
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.mcube_rexspline.Cnds = {
|
|
OnHitTarget() {
|
|
return (this.is_my_call);
|
|
},
|
|
OnHitAnyPoint() {
|
|
return (this.is_my_call);
|
|
},
|
|
IsMoving() {
|
|
return (this.enabled && this.is_moving);
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.mcube_rexspline.Acts = {
|
|
SetEnabled(en) {
|
|
this.enabled = (en === 1);
|
|
},
|
|
SetAngleEnabled(en) {
|
|
this.setAngle = (en === 1);
|
|
},
|
|
AddPoint(x, y) {
|
|
this.points.push([x, y]);
|
|
},
|
|
ResetPoint(i, x, y) {
|
|
if (this.is_moving) {
|
|
var idxp1 = this.curSeg.ptr;
|
|
var idxp2 = this.curSeg.ptr + 1;
|
|
if ((idxp1 === i) || (idxp2 === i))
|
|
return;
|
|
}
|
|
if (i < 0) {
|
|
this.points.unshift([x, y]);
|
|
} else if (i < this.points.length) {
|
|
var p = this.points[i];
|
|
p[0] = x;
|
|
p[1] = y;
|
|
} else {
|
|
this.points.push([x, y]);
|
|
}
|
|
},
|
|
CleanAll() {
|
|
this.points.length = 0;
|
|
this.is_moving = false;
|
|
},
|
|
Start() {
|
|
this.start();
|
|
},
|
|
Stop() {
|
|
this.is_moving = false;
|
|
},
|
|
SetSpeed(spd) {
|
|
this.speed = spd;
|
|
},
|
|
SetLooping(en) {
|
|
this.isLooping = (en === 1);
|
|
},
|
|
SetTension(tension) {
|
|
this.tension = tension;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.mcube_rexspline.Exps = {
|
|
Speed() {
|
|
return (this.speed);
|
|
},
|
|
Tension() {
|
|
return (this.tension);
|
|
},
|
|
AngleOfMotion() {
|
|
if (typeof this.movingAngle != "undefined") {
|
|
return (this.getMovingAngle());
|
|
} else {
|
|
return 0;
|
|
}
|
|
},
|
|
Point(idx, part) {
|
|
var val = this.points;
|
|
if (idx != null)
|
|
val = val[idx];
|
|
if ((val != null) && (part != null)) {
|
|
if ((part === 0) || (part === "x") || (part === "X"))
|
|
val = val[0];
|
|
else if ((part === 1) || (part === "y") || (part === "Y"))
|
|
val = val[1];
|
|
}
|
|
return (din(val));
|
|
},
|
|
CurSegP0(part) {
|
|
var val = this.curSeg.ptr;
|
|
if (part != null) {
|
|
val = this.points[val];
|
|
if (val != null) {
|
|
if ((part === 0) || (part === "x") || (part === "X"))
|
|
val = val[0];
|
|
else if ((part === 1) || (part === "y") || (part === "Y"))
|
|
val = val[1];
|
|
} else
|
|
val = 0;
|
|
}
|
|
return (val);
|
|
},
|
|
CurSegP1(part) {
|
|
var val = this.wrapIndex(this.curSeg.ptr + 1);
|
|
if (part != null) {
|
|
val = this.points[val];
|
|
if (val != null) {
|
|
if ((part === 0) || (part === "x") || (part === "X"))
|
|
val = val[0];
|
|
else if ((part === 1) || (part === "y") || (part === "Y"))
|
|
val = val[1];
|
|
} else
|
|
val = 0;
|
|
}
|
|
return (val);
|
|
},
|
|
PointsCount() {
|
|
return (this.points.length);
|
|
},
|
|
TraveledDistance() {
|
|
return (this.traveledDist);
|
|
}
|
|
};
|
|
}
|
|
'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Timer = class TimerBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Timer.Type = class TimerType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Timer.SingleTimer = class SingleTimer {
|
|
constructor(current, total, duration, isRegular) {
|
|
this._current = C3.New(C3.KahanSum);
|
|
this._current.Set(current || 0);
|
|
this._total = C3.New(C3.KahanSum);
|
|
this._total.Set(total || 0);
|
|
this._duration = duration || 0;
|
|
this._isRegular = !!isRegular;
|
|
this._isPaused = false
|
|
}
|
|
GetCurrentTime() {
|
|
return this._current.Get()
|
|
}
|
|
GetTotalTime() {
|
|
return this._total.Get()
|
|
}
|
|
GetDuration() {
|
|
return this._duration
|
|
}
|
|
SetPaused(p) {
|
|
this._isPaused = !!p
|
|
}
|
|
IsPaused() {
|
|
return this._isPaused
|
|
}
|
|
Add(t) {
|
|
this._current.Add(t);
|
|
this._total.Add(t)
|
|
}
|
|
HasFinished() {
|
|
return this._current.Get() >= this._duration
|
|
}
|
|
Update() {
|
|
if (this.HasFinished())
|
|
if (this._isRegular)
|
|
this._current.Subtract(this._duration);
|
|
else
|
|
return true;
|
|
return false
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"c": this._current.Get(),
|
|
"t": this._total.Get(),
|
|
"d": this._duration,
|
|
"r": this._isRegular,
|
|
"p": this._isPaused
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this._current.Set(o["c"]);
|
|
this._total.Set(o["t"]);
|
|
this._duration = o["d"];
|
|
this._isRegular = !!o["r"];
|
|
this._isPaused = !!o["p"]
|
|
}
|
|
}
|
|
;
|
|
C3.Behaviors.Timer.Instance = class TimerInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this._timers = new Map
|
|
}
|
|
Release() {
|
|
this._timers.clear();
|
|
super.Release()
|
|
}
|
|
_UpdateTickState() {
|
|
if (this._timers.size > 0) {
|
|
this._StartTicking();
|
|
this._StartTicking2()
|
|
} else {
|
|
this._StopTicking();
|
|
this._StopTicking2()
|
|
}
|
|
}
|
|
SaveToJson() {
|
|
const ret = {};
|
|
for (const [name,timer] of this._timers.entries())
|
|
ret[name] = timer.SaveToJson();
|
|
return ret
|
|
}
|
|
LoadFromJson(o) {
|
|
this._timers.clear();
|
|
for (const [name,data] of Object.entries(o)) {
|
|
const timer = new C3.Behaviors.Timer.SingleTimer;
|
|
timer.LoadFromJson(data);
|
|
this._timers.set(name, timer)
|
|
}
|
|
this._UpdateTickState()
|
|
}
|
|
Tick() {
|
|
const dt = this._runtime.GetDt(this._inst);
|
|
for (const timer of this._timers.values())
|
|
if (!timer.IsPaused())
|
|
timer.Add(dt)
|
|
}
|
|
Tick2() {
|
|
for (const [name,timer] of this._timers.entries()) {
|
|
const shouldDelete = timer.Update();
|
|
if (shouldDelete)
|
|
this._timers.delete(name)
|
|
}
|
|
}
|
|
GetDebuggerProperties() {
|
|
return [{
|
|
title: "behaviors.timer.debugger.timers",
|
|
properties: [...this._timers.entries()].map(entry=>({
|
|
name: "$" + entry[0],
|
|
value: `${Math.round(entry[1].GetCurrentTime() * 10) / 10} / ${Math.round(entry[1].GetDuration() * 10) / 10}`
|
|
}))
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Timer.Cnds = {
|
|
OnTimer(name) {
|
|
const timer = this._timers.get(name.toLowerCase());
|
|
if (!timer)
|
|
return false;
|
|
return timer.HasFinished()
|
|
},
|
|
IsTimerRunning(name) {
|
|
return this._timers.has(name.toLowerCase())
|
|
},
|
|
IsTimerPaused(name) {
|
|
const timer = this._timers.get(name.toLowerCase());
|
|
return timer && timer.IsPaused()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Timer.Acts = {
|
|
StartTimer(duration, type, name) {
|
|
const timer = new C3.Behaviors.Timer.SingleTimer(0,0,duration,type === 1);
|
|
this._timers.set(name.toLowerCase(), timer);
|
|
this._UpdateTickState()
|
|
},
|
|
StopTimer(name) {
|
|
this._timers.delete(name.toLowerCase());
|
|
this._UpdateTickState()
|
|
},
|
|
PauseResumeTimer(name, state) {
|
|
const timer = this._timers.get(name.toLowerCase());
|
|
if (timer)
|
|
timer.SetPaused(state === 0)
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Timer.Exps = {
|
|
CurrentTime(name) {
|
|
const timer = this._timers.get(name.toLowerCase());
|
|
if (!timer)
|
|
return 0;
|
|
return timer.GetCurrentTime()
|
|
},
|
|
TotalTime(name) {
|
|
const timer = this._timers.get(name.toLowerCase());
|
|
if (!timer)
|
|
return 0;
|
|
return timer.GetTotalTime()
|
|
},
|
|
Duration(name) {
|
|
const timer = this._timers.get(name.toLowerCase());
|
|
if (!timer)
|
|
return 0;
|
|
return timer.GetDuration()
|
|
}
|
|
}
|
|
}
|
|
;"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiogroup = class aekiro_radiogroupBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiogroup.Type = class aekiro_radiogroupType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiogroup.Instance = class aekiro_radiogroupInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this.value = properties[0];
|
|
this.GetObjectInstance().GetUnsavedDataMap().aekiro_radiogroup = this;
|
|
this.radioButtons = [];
|
|
this.isEnabled = true;
|
|
this.goManager = globalThis.aekiro_goManager;
|
|
this.goManager.eventManager.on("childrenRegistred", ()=>this.init(), {
|
|
"once": true
|
|
});
|
|
}
|
|
PostCreate() {
|
|
this.aekiro_gameobject = this.GetObjectInstance().GetUnsavedDataMap().aekiro_gameobject;
|
|
if (this.aekiro_gameobject) {
|
|
this.aekiro_gameobject.eventManager.on("cloned", ()=>this.init(), {
|
|
"once": true
|
|
});
|
|
}
|
|
}
|
|
GetRadioButtons() {
|
|
return this.aekiro_gameobject.children;
|
|
}
|
|
init() {
|
|
if (!this.aekiro_gameobject) {
|
|
return;
|
|
}
|
|
this.radioButtons = this.GetRadioButtons();
|
|
var b;
|
|
var l = this.radioButtons.length;
|
|
for (var i = 0; i < l; i++) {
|
|
b = this.radioButtons[i].GetUnsavedDataMap().aekiro_radiobutton;
|
|
b.init();
|
|
}
|
|
this.updateView();
|
|
}
|
|
isValueValid(value) {
|
|
var b;
|
|
var radioButtons = this.GetRadioButtons();
|
|
for (var i = 0; i < radioButtons.length; i++) {
|
|
b = radioButtons[i].GetUnsavedDataMap().aekiro_radiobutton;
|
|
if (b.name == value) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
setValue(value) {
|
|
if (!this.isValueValid(value)) {
|
|
return false;
|
|
}
|
|
var radioButtons = this.GetRadioButtons();
|
|
var b, l = radioButtons.length;
|
|
for (var i = 0; i < l; i++) {
|
|
b = radioButtons[i].GetUnsavedDataMap().aekiro_radiobutton;
|
|
if (b.name == value) {
|
|
this.value = value;
|
|
b.setValue(1);
|
|
} else {
|
|
b.setValue(0);
|
|
}
|
|
}
|
|
}
|
|
updateView() {
|
|
var areAllDisabled = true;
|
|
var radioButtons = this.GetRadioButtons();
|
|
for (var i = 0; i < radioButtons.length; i++) {
|
|
var b = radioButtons[i].GetUnsavedDataMap().aekiro_radiobutton;
|
|
if (b.name == this.value) {
|
|
b.setValue(1);
|
|
} else {
|
|
b.setValue(0);
|
|
}
|
|
if (b.isEnabled) {
|
|
areAllDisabled = false;
|
|
}
|
|
}
|
|
if (areAllDisabled) {
|
|
this.isEnabled = false;
|
|
}
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"value": this.value,
|
|
};
|
|
}
|
|
LoadFromJson(o) {
|
|
this.value = o["value"];
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiogroup.Cnds = {
|
|
IsEnabled() {
|
|
return this.isEnabled;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiogroup.Acts = {
|
|
setValue(value) {
|
|
this.setValue(value);
|
|
},
|
|
setEnabled(isEnabled) {
|
|
this.isEnabled = isEnabled;
|
|
for (var i = 0, l = this.radioButtons.length; i < l; i++) {
|
|
this.radioButtons[i].GetUnsavedDataMap().aekiro_radiobutton.setEnabled(isEnabled);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_radiogroup.Exps = {
|
|
value() {
|
|
return this.value;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridView = class aekiro_gridViewBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridView.Type = class aekiro_gridViewType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridView.Instance = class aekiro_gridViewInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this.proui = this.GetRuntime().GetSingleGlobalObjectClassByCtor(C3.Plugins.aekiro_proui);
|
|
if (this.proui) {
|
|
this.proui = this.proui.GetSingleGlobalInstance().GetSdkInstance();
|
|
}
|
|
if (properties) {
|
|
this.itemName = properties[0];
|
|
this.columns = properties[1];
|
|
this.rows = properties[2];
|
|
this.vspace = properties[3];
|
|
this.hspace = properties[4];
|
|
this.VPadding = properties[5];
|
|
this.HPadding = properties[6];
|
|
}
|
|
this.GetObjectInstance().GetUnsavedDataMap().aekiro_gridview = this;
|
|
this.inst = this.GetObjectInstance();
|
|
this.wi = this.GetWorldInfo();
|
|
this.acts = this.GetObjectInstance().GetPlugin().constructor.Acts;
|
|
this.goManager = globalThis["aekiro_goManager"];
|
|
this.template = {};
|
|
this.isTemplateSet = false;
|
|
this.value = [];
|
|
this.items = [];
|
|
this.it_column = 0;
|
|
this.it_row = 0;
|
|
this.goManager.eventManager.on("childrenRegistred", ()=>{
|
|
var children = this.GetObjectInstance().GetUnsavedDataMap().aekiro_gameobject.children;
|
|
for (var i = 0, l = children.length; i < l; i++) {
|
|
this.items.push(children[i]);
|
|
}
|
|
}
|
|
, {
|
|
"once": true
|
|
});
|
|
}
|
|
PostCreate() {
|
|
this.aekiro_gameobject = this.GetObjectInstance().GetUnsavedDataMap().aekiro_gameobject;
|
|
}
|
|
setItemTemplate() {
|
|
if (this.isTemplateSet) {
|
|
return;
|
|
}
|
|
var item = this.goManager.gos[this.itemName];
|
|
if (!item) {
|
|
throw new Error("ProUI-GRIDVIEW: Grid item not found, please check the grid item's name");
|
|
return;
|
|
}
|
|
this.proui.isTypeValid(this.GetObjectInstance(), [C3.Plugins.Sprite, C3.Plugins.NinePatch, C3.Plugins.TiledBg], "ProUI-GRIDVIEW: Grid item can only be Sprite, 9-patch or tiled backgrounds objects.");
|
|
var go = item.GetUnsavedDataMap().aekiro_gameobject;
|
|
this.template = go.getTemplate();
|
|
go.destroyHierarchy();
|
|
this.isTemplateSet = true;
|
|
}
|
|
build() {
|
|
if (this.rows <= 0 && this.columns <= 0) {
|
|
console.error("ProUI-GRIDVIEW: max rows and max columns can't be both -1 or 0");
|
|
return;
|
|
}
|
|
this.setItemTemplate();
|
|
var diff = this.value.length - this.items.length;
|
|
var item, l;
|
|
if (diff > 0) {
|
|
l = this.value.length;
|
|
for (var i = this.items.length; i < l; i++) {
|
|
item = this.add(i);
|
|
if (!this.nextRowColumn()) {
|
|
break;
|
|
}
|
|
}
|
|
} else if (diff < 0) {
|
|
l = this.items.length;
|
|
for (var i = this.value.length; i < l; i++) {
|
|
this.items[i].GetUnsavedDataMap().aekiro_gameobject.destroyHierarchy();
|
|
if (!this.previousRowColumn()) {
|
|
break;
|
|
}
|
|
}
|
|
this.items.splice(this.value.length, -diff);
|
|
}
|
|
this.resize();
|
|
l = this.value.length;
|
|
for (var i = 0; i < l; i++) {
|
|
this.mapData(this.items[i], this.value[i], i);
|
|
}
|
|
var self = this;
|
|
setTimeout(function() {
|
|
self.Trigger(C3.Behaviors.aekiro_gridView.Cnds.OnRender);
|
|
}, 0);
|
|
}
|
|
add(itemIndex) {
|
|
var self = this;
|
|
var item = this.goManager.clone(this.template, null, this.inst, this.wi.GetLayer(), 0, 0);
|
|
var wi = item.GetWorldInfo();
|
|
var offsetX = wi.GetX() - wi.GetBoundingBox().getLeft();
|
|
var offsetY = wi.GetY() - wi.GetBoundingBox().getTop();
|
|
wi.SetX(this.wi.GetBoundingBox().getLeft() + offsetX + (this.vspace + wi.GetWidth()) * this.it_column + this.HPadding);
|
|
wi.SetY(this.wi.GetBoundingBox().getTop() + offsetY + (this.hspace + wi.GetHeight()) * this.it_row + this.VPadding);
|
|
wi.SetBboxChanged();
|
|
this.items.push(item);
|
|
return item;
|
|
}
|
|
clear() {
|
|
this.setItemTemplate();
|
|
var items = this.items;
|
|
for (var i = 0, l = this.items.length; i < l; i++) {
|
|
items[i].GetUnsavedDataMap().aekiro_gameobject.destroyHierarchy();
|
|
}
|
|
items.length = 0;
|
|
this.it_column = 0;
|
|
this.it_row = 0;
|
|
this.value = [];
|
|
this.resize();
|
|
}
|
|
resize() {
|
|
var wi = this.wi;
|
|
var prevBboxTop = wi.GetBoundingBox().getTop();
|
|
var prevBboxLeft = wi.GetBoundingBox().getLeft();
|
|
var prevX = wi.GetX();
|
|
var prevY = wi.GetY();
|
|
if (this.value.length == 0) {
|
|
wi.SetWidth(5, true);
|
|
wi.SetHeight(5, true);
|
|
wi.SetBboxChanged();
|
|
wi.SetX(prevBboxLeft + (wi.GetX() - wi.GetBoundingBox().getLeft()));
|
|
wi.SetY(prevBboxTop + (wi.GetY() - wi.GetBoundingBox().getTop()));
|
|
wi.SetBboxChanged();
|
|
return;
|
|
}
|
|
var row = Math.ceil(this.value.length / this.columns);
|
|
var column = Math.ceil(this.value.length / this.rows);
|
|
if (this.rows < 0) {
|
|
column = this.columns;
|
|
if (this.value.length < this.columns) {
|
|
column = this.value.length;
|
|
}
|
|
} else if (this.columns < 0) {
|
|
row = this.rows;
|
|
if (this.value.length < this.rows) {
|
|
row = this.value.length;
|
|
}
|
|
} else {
|
|
column = this.columns;
|
|
row = this.rows;
|
|
}
|
|
var itemWidth = this.items[0].GetWorldInfo().GetWidth();
|
|
var itemHeight = this.items[0].GetWorldInfo().GetHeight();
|
|
wi.SetWidth(itemWidth * column + this.vspace * (column - 1) + 2 * this.HPadding, true);
|
|
wi.SetHeight(itemHeight * row + this.hspace * (row - 1) + 2 * this.VPadding, true);
|
|
wi.SetBboxChanged();
|
|
if (wi.GetX() != prevX || wi.GetX() != prevY) {
|
|
return;
|
|
}
|
|
wi.SetX(prevBboxLeft + (wi.GetX() - wi.GetBoundingBox().getLeft()));
|
|
wi.SetY(prevBboxTop + (wi.GetY() - wi.GetBoundingBox().getTop()));
|
|
wi.SetBboxChanged();
|
|
}
|
|
mapData(inst, data, index) {
|
|
var binder = inst.GetUnsavedDataMap().aekiro_gridviewbind;
|
|
if (binder && this.isObject(data)) {
|
|
binder.index = index;
|
|
binder.setValue(data);
|
|
binder.gridView = this;
|
|
binder.triggerOnGridViewRender();
|
|
}
|
|
var children = inst.GetUnsavedDataMap().aekiro_gameobject.children;
|
|
for (var i = 0, l = children.length; i < l; i++) {
|
|
this.mapData(children[i], data, index);
|
|
}
|
|
}
|
|
item_setKey(i, key, value) {
|
|
self["_"]["set"](this.value[i], key, value);
|
|
}
|
|
nextRowColumn() {
|
|
if (this.rows < 0) {
|
|
this.it_column++;
|
|
if (this.it_column == this.columns) {
|
|
this.it_column = 0;
|
|
this.it_row++;
|
|
}
|
|
} else if (this.columns < 0) {
|
|
this.it_row++;
|
|
if (this.it_row == this.rows) {
|
|
this.it_row = 0;
|
|
this.it_column++;
|
|
}
|
|
} else {
|
|
this.it_column++;
|
|
if (this.it_column == this.columns) {
|
|
this.it_column = 0;
|
|
this.it_row++;
|
|
}
|
|
if (this.it_row == this.rows)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
previousRowColumn() {
|
|
if (this.rows < 0) {
|
|
this.it_column--;
|
|
if (this.it_column < 0) {
|
|
this.it_column = this.columns - 1;
|
|
this.it_row--;
|
|
}
|
|
} else if (this.columns < 0) {
|
|
this.it_row--;
|
|
if (this.it_row < 0) {
|
|
this.it_row = this.rows - 1;
|
|
this.it_column--;
|
|
}
|
|
} else {
|
|
this.it_column--;
|
|
if (this.it_column < 0) {
|
|
this.it_column = this.columns - 1;
|
|
this.it_row--;
|
|
}
|
|
if (this.it_row == 0)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
isObject(a) {
|
|
return (!!a) && (a.constructor === Object);
|
|
}
|
|
isArray(a) {
|
|
return (!!a) && (a.constructor === Array);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"itemName": this.itemName,
|
|
"columns": this.columns,
|
|
"rows": this.rows,
|
|
"vspace": this.vspace,
|
|
"hspace": this.hspace,
|
|
"VPadding": this.VPadding,
|
|
"HPadding": this.HPadding,
|
|
"template": this.template,
|
|
"isTemplateSet": this.isTemplateSet,
|
|
"value": this.value,
|
|
"it_column": this.it_column,
|
|
"it_row": this.it_row
|
|
};
|
|
}
|
|
LoadFromJson(o) {
|
|
this.itemName = o["itemName"];
|
|
this.columns = o["columns"];
|
|
this.rows = o["rows"];
|
|
this.vspace = o["vspace"];
|
|
this.hspace = o["hspace"];
|
|
this.VPadding = o["VPadding"];
|
|
this.HPadding = o["HPadding"];
|
|
this.template = o["template"];
|
|
this.isTemplateSet = o["isTemplateSet"];
|
|
this.value = o["value"];
|
|
this.it_column = o["it_column"];
|
|
this.it_row = o["it_row"];
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridView.Cnds = {
|
|
OnRender() {
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridView.Acts = {
|
|
SetDataByJsonString(data) {
|
|
try {
|
|
data = JSON.parse(data);
|
|
} catch (e) {
|
|
console.error("ProUI-GRIDVIEW: json parse error !");
|
|
return;
|
|
}
|
|
if (!this.isArray(data)) {
|
|
console.error("ProUI-GRIDVIEW: json is not an array !");
|
|
return;
|
|
}
|
|
this.value = data;
|
|
this.build();
|
|
},
|
|
SetDataByJsonObject(jsonObject, root) {
|
|
var data = jsonObject.GetFirstPicked().GetSdkInstance()._data;
|
|
if (root) {
|
|
data = data[root];
|
|
}
|
|
if (data && !this.isArray(data)) {
|
|
console.error("ProUI-GRIDVIEW: json is not an array !");
|
|
return;
|
|
}
|
|
this.value = data;
|
|
this.build();
|
|
},
|
|
Clear() {
|
|
this.clear();
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_gridView.Acts = {
|
|
SetDataByJsonString(data) {
|
|
try {
|
|
data = JSON.parse(data);
|
|
} catch (e) {
|
|
console.error("ProUI-GRIDVIEW: json parse error !");
|
|
return;
|
|
}
|
|
if (!this.isArray(data)) {
|
|
console.error("ProUI-GRIDVIEW: json is not an array !");
|
|
return;
|
|
}
|
|
this.value = data;
|
|
this.build();
|
|
},
|
|
SetDataByJsonObject(jsonObject) {
|
|
var data = jsonObject.GetFirstPicked().GetSdkInstance()._data;
|
|
if (!this.isArray(data)) {
|
|
console.error("ProUI-GRIDVIEW: json is not an array !");
|
|
return;
|
|
}
|
|
this.value = data;
|
|
this.build();
|
|
},
|
|
Clear() {
|
|
this.clear();
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_scrollView = class aekiro_scrollViewBehavior extends C3.SDKBehaviorBase {
|
|
constructor(a) {
|
|
super(a);
|
|
const b = this._runtime.Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(b, "pointerdown", (a)=>this._OnPointerDown(a.data)),C3.Disposable.From(b, "pointermove", (a)=>this._OnPointerMove(a.data)),C3.Disposable.From(b, "pointerup", (a)=>this._OnPointerUp(a.data, !1)),C3.Disposable.From(b, "pointercancel", (a)=>this._OnPointerUp(a.data, !0))),
|
|
C3.Disposable.From(b, "wheel", (a)=>this._OnMouseWheel(a.data))
|
|
}
|
|
Release() {
|
|
this._disposables.Release(),
|
|
this._disposables = null,
|
|
super.Release()
|
|
}
|
|
_OnPointerDown(a) {
|
|
this._OnInputDown(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnPointerMove(a) {
|
|
this._OnInputMove(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnPointerUp(a) {
|
|
this._OnInputUp(a["pointerId"].toString(), a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnMouseWheel(a) {
|
|
this._OnMouseWheel2(a["deltaY"], a["clientX"] - this._runtime.GetCanvasClientX(), a["clientY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
async _OnInputDown(source, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_scrollView);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputDown)
|
|
await beh.OnAnyInputDown(x, y, source);
|
|
}
|
|
}
|
|
_OnInputMove(source, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_scrollView);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputMove)
|
|
beh.OnAnyInputMove(x, y, source);
|
|
}
|
|
}
|
|
async _OnInputUp(a, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_scrollView);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnAnyInputUp)
|
|
await beh.OnAnyInputUp(x, y);
|
|
}
|
|
}
|
|
_OnMouseWheel2(a, b, c) {
|
|
const insts = this.GetInstances();
|
|
for (const inst of insts) {
|
|
const beh = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.aekiro_scrollView);
|
|
const wi = inst.GetWorldInfo()
|
|
, layer = wi.GetLayer()
|
|
, [x,y] = layer.CanvasCssToLayer(b, c, wi.GetTotalZElevation());
|
|
if (beh.OnMouseWheel)
|
|
beh.OnMouseWheel(x, y, a);
|
|
}
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_scrollView.Type = class aekiro_scrollView2Type extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_scrollView.Instance = class aekiro_scrollViewInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this.proui = this.GetRuntime().GetSingleGlobalObjectClassByCtor(C3.Plugins.aekiro_proui);
|
|
if (this.proui) {
|
|
this.proui = this.proui.GetSingleGlobalInstance().GetSdkInstance();
|
|
}
|
|
this._SetVisible = this.GetObjectInstance().GetPlugin().constructor.Acts.SetVisible;
|
|
this.runtime = this.GetRuntime();
|
|
this.aekiro_scrollViewManager = globalThis.aekiro_scrollViewManager;
|
|
this.aekiro_scrollViewManager.add(this.GetObjectInstance());
|
|
this.aekiro_dialogManager = globalThis.aekiro_dialogManager;
|
|
this.goManager = globalThis.aekiro_goManager;
|
|
this.GetObjectInstance().GetUnsavedDataMap().aekiro_scrollView = this;
|
|
this.inst = this.GetObjectInstance();
|
|
this.wi = this.GetWorldInfo();
|
|
if (properties) {
|
|
this.isEnabled = properties[0];
|
|
this.direction = properties[1];
|
|
this.isSwipeScrollEnabled = properties[2];
|
|
this.isMouseScroll = properties[3];
|
|
this.inertia = properties[4];
|
|
this.movement = properties[5];
|
|
this.contentUID = properties[6];
|
|
this.vSliderUID = properties[7];
|
|
this.vScrollBarUID = properties[8];
|
|
this.hSliderUID = properties[9];
|
|
this.hScrollBarUID = properties[10];
|
|
}
|
|
if (!this.inertia) {
|
|
this.movement = 0;
|
|
}
|
|
this.elasticF = 1;
|
|
if (this.movement) {
|
|
this.elasticF = 0.4;
|
|
}
|
|
this.onTouchStarted = false;
|
|
this.isTouchMoving = false;
|
|
this.onSliderTouchStarted = false;
|
|
this.onvSliderTouchStarted = false;
|
|
this.onhSliderTouchStarted = false;
|
|
this.content = null;
|
|
this.vSlider = null;
|
|
this.vScrollBar = null;
|
|
this.hSlider = null;
|
|
this.hScrollBar = null;
|
|
this.isInit = false;
|
|
this.isContentScrollableV = true;
|
|
this.isContentScrollableH = true;
|
|
this.scroll = {
|
|
isIdle: true,
|
|
offsetX: 0,
|
|
offestY: 0,
|
|
scrollRatio: 0,
|
|
decelerationVelocityX: 0,
|
|
decelerationVelocityY: 0,
|
|
scrollToTargetY: null,
|
|
scrollToTargetX: null,
|
|
scrollToX: false,
|
|
scrollToY: false,
|
|
scrollToSmooth: 0.3
|
|
};
|
|
this.goManager.eventManager.on("childrenRegistred", ()=>{
|
|
this.init();
|
|
}
|
|
, {
|
|
"once": true
|
|
});
|
|
this.SetForceOwnTextureListener = this.goManager.eventManager.on("childrenRegistred", ()=>{
|
|
this.wi.GetLayer().SetForceOwnTexture(true);
|
|
}
|
|
);
|
|
}
|
|
init() {
|
|
if (this.isInit) {
|
|
return;
|
|
}
|
|
this.isVScrollEnabled = (this.direction == 0) || (this.direction == 2);
|
|
this.isHScrollEnabled = (this.direction == 1) || (this.direction == 2);
|
|
this.prevSelfLayerVisible = this.wi.GetLayer().IsVisible();
|
|
try {
|
|
this.vSlider = this.getPart(this.vSliderUID, "vertical slider");
|
|
this.vScrollBar = this.getPart(this.vScrollBarUID, "vertical scrollbar");
|
|
this.hSlider = this.getPart(this.hSliderUID, "horizontal slider");
|
|
this.hScrollBar = this.getPart(this.hScrollBarUID, "horizontal scrollbar");
|
|
this.content = this.getPart(this.contentUID, "content", true);
|
|
var contentWi = this.content.GetWorldInfo();
|
|
this.contentWi = this.content.GetWorldInfo();
|
|
} catch (e) {
|
|
console.error(e)
|
|
this.isEnabled = false;
|
|
return;
|
|
}
|
|
this.content.GetUnsavedDataMap().aekiro_scrollView = this;
|
|
this.contentWi.SetHeight_old2 = this.contentWi.SetHeight;
|
|
this.contentWi.SetHeight = function(v, onlyNode) {
|
|
this.SetHeight_old2(v, onlyNode);
|
|
this.GetInstance().GetUnsavedDataMap().aekiro_scrollView.OnSizeChanged();
|
|
}
|
|
;
|
|
this.contentWi.SetWidth_old2 = this.contentWi.SetWidth;
|
|
this.contentWi.SetWidth = function(v, onlyNode) {
|
|
this.SetWidth_old2(v, onlyNode);
|
|
this.GetInstance().GetUnsavedDataMap().aekiro_scrollView.OnSizeChanged();
|
|
}
|
|
;
|
|
this.content.GetUnsavedDataMap().aekiro_gameobject.eventManager.on("childrenAdded", function(inst) {
|
|
if (inst) {
|
|
inst.GetUnsavedDataMap().aekiro_gameobject.applyActionToHierarchy(inst.GetUnsavedDataMap().aekiro_gameobject.acts.SetEffect, 9);
|
|
}
|
|
});
|
|
if (contentWi.GetHeight(true) <= this.wi.GetHeight(true)) {
|
|
this.isContentScrollableV = false;
|
|
}
|
|
if (contentWi.GetWidth(true) <= this.wi.GetWidth(true)) {
|
|
this.isContentScrollableH = false;
|
|
}
|
|
contentWi.SetX(this.wi.GetBoundingBox().getLeft() + (contentWi.GetX() - contentWi.GetBoundingBox().getLeft()));
|
|
contentWi.SetY(this.wi.GetBoundingBox().getTop() + (contentWi.GetY() - contentWi.GetBoundingBox().getTop()));
|
|
contentWi.SetBboxChanged();
|
|
this.wi.GetLayer().SetForceOwnTexture(true);
|
|
this.GetRuntime().UpdateRender();
|
|
this.content.GetUnsavedDataMap().aekiro_gameobject.applyActionToHierarchy(this.content.GetUnsavedDataMap().aekiro_gameobject.acts.SetEffect, 9);
|
|
if (this.hSlider && this.hScrollBar) {
|
|
this.hSliderWi = this.hSlider.GetWorldInfo();
|
|
this.hScrollBarWi = this.hScrollBar.GetWorldInfo();
|
|
var x = this.hScrollBarWi.GetBoundingBox().getLeft() + (this.hSliderWi.GetX() - this.hSliderWi.GetBoundingBox().getLeft());
|
|
this.hSliderWi.SetX(x);
|
|
this.hSliderWi.SetBboxChanged();
|
|
this.hScrollBar.GetSdkInstance().CallAction(this.hScrollBar.GetPlugin().constructor.Acts.MoveToTop);
|
|
this.hSlider.GetSdkInstance().CallAction(this.hSlider.GetPlugin().constructor.Acts.MoveToTop);
|
|
}
|
|
if (this.vSlider && this.vScrollBar) {
|
|
this.vSliderWi = this.vSlider.GetWorldInfo();
|
|
this.vScrollBarWi = this.vScrollBar.GetWorldInfo();
|
|
var y = this.vScrollBarWi.GetBoundingBox().getTop() + (this.vSliderWi.GetY() - this.vSliderWi.GetBoundingBox().getTop());
|
|
this.vSliderWi.SetY(y);
|
|
this.vSliderWi.SetBboxChanged();
|
|
this.vScrollBar.GetSdkInstance().CallAction(this.vScrollBar.GetPlugin().constructor.Acts.MoveToTop);
|
|
this.vSlider.GetSdkInstance().CallAction(this.vSlider.GetPlugin().constructor.Acts.MoveToTop);
|
|
}
|
|
this.isInit = true;
|
|
this._StartTicking();
|
|
}
|
|
getPart(name, errorLabel, isRequired) {
|
|
if (!name && !isRequired)
|
|
return;
|
|
var invalidName = false;
|
|
var p = this.goManager.gos[name];
|
|
if (p) {
|
|
if (!this.proui.isTypeValid(p, [C3.Plugins.Sprite, C3.Plugins.NinePatch, C3.Plugins.TiledBg])) {
|
|
throw new Error("ProUI-ScrollView-UID = " + this.GetObjectInstance().GetUID() + " : The " + errorLabel + " of the scrollView can only be a Sprite, TiledBackground Or 9-patch object.");
|
|
}
|
|
return p;
|
|
} else {
|
|
invalidName = true;
|
|
}
|
|
if (!name && isRequired) {
|
|
invalidName = true;
|
|
}
|
|
if (invalidName) {
|
|
throw new Error("ProUI-ScrollView: " + errorLabel + " not found, please check its name");
|
|
}
|
|
return;
|
|
}
|
|
PostCreate() {
|
|
this.sdkInstance_callAction = this.GetObjectInstance().GetSdkInstance().CallAction;
|
|
this.sdkInstance_acts = this.GetObjectInstance().GetPlugin().constructor.Acts;
|
|
}
|
|
OnMouseWheel(x, y, deltaY) {
|
|
if (this.isEnabled && this.isVScrollEnabled && this.isContentScrollableV && this.isMouseScroll && this.isInteractible(x, y) && this.wi.ContainsPoint(x, y)) {
|
|
this.scroll.scrollToX = false;
|
|
this.scroll.scrollToY = false;
|
|
this.scroll.isIdle = false;
|
|
this._StartTicking();
|
|
this.onWheelStarted = true;
|
|
var dir = (deltaY > 0 ? -1 : 1);
|
|
if (this.inertia) {
|
|
this.scroll.decelerationVelocityY = dir * 650;
|
|
} else {
|
|
this.contentWi.OffsetY(30 * dir);
|
|
}
|
|
this.scroll.decelerationVelocityX = 0;
|
|
}
|
|
}
|
|
isInteractible(x, y) {
|
|
if (this.proui.ignoreInput) {
|
|
return false;
|
|
}
|
|
var isUnder = false;
|
|
if (this.aekiro_dialogManager) {
|
|
isUnder = this.aekiro_dialogManager.isInstanceUnder(this.wi.GetLayer().GetIndex());
|
|
}
|
|
var isOverlaped = this.aekiro_scrollViewManager.isOverlaped(this.GetObjectInstance(), x, y);
|
|
return !isUnder && !isOverlaped;
|
|
}
|
|
OnAnyInputDown(x, y) {
|
|
if (!this.isEnabled || !this.isInteractible(x, y)) {
|
|
return;
|
|
}
|
|
if (this.wi.ContainsPoint(x, y)) {
|
|
this.OnInputDown(x, y);
|
|
}
|
|
if (this.vSlider && this.vScrollBar && this.isVScrollEnabled && this.isContentScrollableV && this.vSliderWi.ContainsPoint(x, y)) {
|
|
this.OnSliderTouchStart("v", x, y);
|
|
}
|
|
if (this.hSlider && this.hScrollBar && this.isHScrollEnabled && this.isContentScrollableH && this.hSliderWi.ContainsPoint(x, y)) {
|
|
this.OnSliderTouchStart("h", x, y);
|
|
}
|
|
}
|
|
OnInputDown(x, y) {
|
|
if (!this.isEnabled || !this.isSwipeScrollEnabled) {
|
|
return;
|
|
}
|
|
this.onTouchStarted = true;
|
|
this.scroll.startTime = Date.now();
|
|
if (this.isVScrollEnabled && this.isContentScrollableV) {
|
|
this.scroll.offsetY = y - this.contentWi.GetY();
|
|
this.scroll.touchStartY = y;
|
|
this.scroll.isIdle = false;
|
|
this._StartTicking();
|
|
this.scroll.scrollToX = false;
|
|
this.scroll.scrollToY = false;
|
|
}
|
|
if (this.isHScrollEnabled && this.isContentScrollableH) {
|
|
this.scroll.offsetX = x - this.contentWi.GetX();
|
|
this.scroll.touchStartX = x;
|
|
this.scroll.isIdle = false;
|
|
this._StartTicking();
|
|
this.scroll.scrollToX = false;
|
|
this.scroll.scrollToY = false;
|
|
}
|
|
this.touchX = x;
|
|
this.touchY = y;
|
|
this.scroll.decelerationVelocityX = 0;
|
|
this.scroll.decelerationVelocityY = 0;
|
|
}
|
|
OnSliderTouchStart(type, x, y) {
|
|
if (type == "v") {
|
|
this.scroll.offsetY = y - this.vSliderWi.GetY();
|
|
this.onvSliderTouchStarted = true;
|
|
} else {
|
|
this.scroll.offsetX = x - this.hSliderWi.GetX();
|
|
this.onhSliderTouchStarted = true;
|
|
}
|
|
this.onSliderTouchStarted = true;
|
|
this.scroll.isIdle = true;
|
|
this._StopTicking();
|
|
this.boundContent();
|
|
this.scroll.scrollToX = false;
|
|
this.scroll.scrollToY = false;
|
|
this.scroll.decelerationVelocityX = 0;
|
|
this.scroll.decelerationVelocityY = 0;
|
|
}
|
|
OnAnyInputUp(x, y) {
|
|
if (!this.isEnabled) {
|
|
return;
|
|
}
|
|
if (this.onTouchStarted) {
|
|
this.OnInputUp(x, y);
|
|
}
|
|
this.onTouchStarted = false;
|
|
this.onSliderTouchStarted = false;
|
|
this.onvSliderTouchStarted = false;
|
|
this.onhSliderTouchStarted = false;
|
|
}
|
|
OnInputUp(x, y) {
|
|
this.scroll.elapsedTime = (Date.now() - this.scroll.startTime) / 1000;
|
|
if (this.isSwipeScrollEnabled && this.inertia) {
|
|
if (this.isHScrollEnabled && this.isContentScrollableH) {
|
|
this.scroll.decelerationVelocityX = (x - this.scroll.touchStartX) / this.scroll.elapsedTime;
|
|
if (Math.abs(this.scroll.decelerationVelocityX) < 100) {
|
|
this.scroll.decelerationVelocityX = 0;
|
|
}
|
|
}
|
|
if (this.isVScrollEnabled && this.isContentScrollableV) {
|
|
this.scroll.decelerationVelocityY = (y - this.scroll.touchStartY) / this.scroll.elapsedTime;
|
|
if (Math.abs(this.scroll.decelerationVelocityY) < 100) {
|
|
this.scroll.decelerationVelocityY = 0;
|
|
}
|
|
}
|
|
}
|
|
this.isTouchMoving = false;
|
|
}
|
|
OnAnyInputMove(x, y, source) {
|
|
if (this.onTouchStarted) {
|
|
this.isTouchMoving = true;
|
|
this.touchX = x;
|
|
this.touchY = y;
|
|
}
|
|
if (this.onvSliderTouchStarted && this.isVScrollEnabled && this.isContentScrollableV) {
|
|
var newy = y - this.scroll.offsetY;
|
|
this.vSliderWi.SetY(C3.clamp(newy, this.vScrollBarWi.GetBoundingBox().getTop() + (this.vSliderWi.GetY() - this.vSliderWi.GetBoundingBox().getTop()), this.vScrollBarWi.GetBoundingBox().getBottom() - (this.vSliderWi.GetBoundingBox().getBottom() - this.vSliderWi.GetY())));
|
|
this.vSliderWi.SetBboxChanged();
|
|
this.contentWi.SetY(this.wi.GetBoundingBox().getTop() + (this.contentWi.GetY() - this.contentWi.GetBoundingBox().getTop()) - ((this.vSliderWi.GetBoundingBox().getTop() - this.vScrollBarWi.GetBoundingBox().getTop()) / (this.vScrollBarWi.GetHeight(true) - this.vSliderWi.GetHeight(true))) * (this.contentWi.GetHeight(true) - this.wi.GetHeight(true)));
|
|
this.contentWi.SetBboxChanged();
|
|
}
|
|
if (this.onhSliderTouchStarted && this.isHScrollEnabled && this.isContentScrollableH) {
|
|
var newx = x - this.scroll.offsetX;
|
|
this.hSliderWi.SetX(C3.clamp(newx, this.hScrollBarWi.GetBoundingBox().getLeft() + (this.hSliderWi.GetX() - this.hSliderWi.GetBoundingBox().getLeft()), this.hScrollBarWi.GetBoundingBox().getRight() - (this.hSliderWi.GetBoundingBox().getRight() - this.hSliderWi.GetX())));
|
|
this.hSliderWi.SetBboxChanged();
|
|
this.contentWi.SetX(this.wi.GetBoundingBox().getLeft() + (this.contentWi.GetX() - this.contentWi.GetBoundingBox().getLeft()) - ((this.hSliderWi.GetBoundingBox().getLeft() - this.hScrollBarWi.GetBoundingBox().getLeft()) / (this.hScrollBarWi.GetWidth(true) - this.hSliderWi.GetWidth(true))) * (this.contentWi.GetWidth(true) - this.wi.GetWidth(true)));
|
|
this.contentWi.SetBboxChanged();
|
|
}
|
|
}
|
|
boundContent() {
|
|
if (this.contentWi.GetHeight(true) <= this.wi.GetHeight(true)) {
|
|
this.contentWi.SetY(this.wi.GetBoundingBox().getTop() + (this.contentWi.GetY() - this.contentWi.GetBoundingBox().getTop()));
|
|
} else {
|
|
var diff_topY = this.contentWi.GetBoundingBox().getTop() - this.wi.GetBoundingBox().getTop();
|
|
var diff_bottomY = this.wi.GetBoundingBox().getBottom() - this.contentWi.GetBoundingBox().getBottom();
|
|
if (diff_topY > 0 || diff_bottomY > 0) {
|
|
this.contentWi.SetY(C3.clamp(this.contentWi.GetY(), this.contentWi.GetY() + diff_bottomY, this.contentWi.GetY() - diff_topY));
|
|
}
|
|
}
|
|
if (this.contentWi.GetWidth(true) <= this.wi.GetWidth(true)) {
|
|
this.contentWi.SetX(this.wi.GetBoundingBox().getLeft() + (this.contentWi.GetX() - this.contentWi.GetBoundingBox().getLeft()));
|
|
} else {
|
|
var diff_rightX = this.wi.GetBoundingBox().getRight() - this.contentWi.GetBoundingBox().getRight();
|
|
var diff_leftX = this.contentWi.GetBoundingBox().getLeft() - this.wi.GetBoundingBox().getLeft();
|
|
if (diff_rightX > 0 || diff_leftX > 0) {
|
|
this.contentWi.SetX(C3.clamp(this.contentWi.GetX(), this.contentWi.GetX() + diff_rightX, this.contentWi.GetX() - diff_leftX));
|
|
}
|
|
}
|
|
this.contentWi.SetBboxChanged();
|
|
}
|
|
boundContentX(elasticF) {
|
|
if (this.isHScrollEnabled) {
|
|
var isOutOfBound;
|
|
this.contentWi.SetBboxChanged();
|
|
if (this.contentWi.GetWidth(true) <= this.wi.GetWidth(true)) {
|
|
this.contentWi.SetX(this.wi.GetBoundingBox().getLeft() + (this.contentWi.GetX() - this.contentWi.GetBoundingBox().getLeft()));
|
|
isOutOfBound = true;
|
|
} else {
|
|
var diff_rightX = this.wi.GetBoundingBox().getRight() - this.contentWi.GetBoundingBox().getRight();
|
|
var diff_leftX = this.contentWi.GetBoundingBox().getLeft() - this.wi.GetBoundingBox().getLeft();
|
|
isOutOfBound = diff_rightX > 0 || diff_leftX > 0;
|
|
if (isOutOfBound) {
|
|
if (elasticF && this.elasticF != 1) {
|
|
this.contentWi.SetX(C3.clamp(this.contentWi.GetX(), C3.lerp(this.contentWi.GetX(), this.contentWi.GetX() + diff_rightX, this.elasticF), C3.lerp(this.contentWi.GetX(), this.contentWi.GetX() - diff_leftX, this.elasticF)));
|
|
} else {
|
|
this.contentWi.SetX(C3.clamp(this.contentWi.GetX(), this.contentWi.GetX() + diff_rightX, this.contentWi.GetX() - diff_leftX));
|
|
}
|
|
}
|
|
}
|
|
this.contentWi.SetBboxChanged();
|
|
return isOutOfBound;
|
|
}
|
|
}
|
|
boundContentY(elasticF) {
|
|
if (this.isVScrollEnabled) {
|
|
var isOutOfBound;
|
|
this.contentWi.SetBboxChanged();
|
|
if (this.contentWi.GetHeight(true) <= this.wi.GetHeight(true)) {
|
|
this.contentWi.SetY(this.wi.GetBoundingBox().getTop() + (this.contentWi.GetY() - this.contentWi.GetBoundingBox().getTop()));
|
|
isOutOfBound = true;
|
|
} else {
|
|
var diff_topY = this.contentWi.GetBoundingBox().getTop() - this.wi.GetBoundingBox().getTop();
|
|
var diff_bottomY = this.wi.GetBoundingBox().getBottom() - this.contentWi.GetBoundingBox().getBottom();
|
|
isOutOfBound = diff_topY > 0 || diff_bottomY > 0;
|
|
if (isOutOfBound) {
|
|
if (elasticF && this.elasticF != 1) {
|
|
this.contentWi.SetY(C3.clamp(this.contentWi.GetY(), C3.lerp(this.contentWi.GetY(), this.contentWi.GetY() + diff_bottomY, this.elasticF), C3.lerp(this.contentWi.GetY(), this.contentWi.GetY() - diff_topY, this.elasticF)));
|
|
} else {
|
|
this.contentWi.SetY(C3.clamp(this.contentWi.GetY(), this.contentWi.GetY() + diff_bottomY, this.contentWi.GetY() - diff_topY));
|
|
}
|
|
}
|
|
}
|
|
this.contentWi.SetBboxChanged();
|
|
return isOutOfBound;
|
|
}
|
|
}
|
|
scrollTo(targetX, targetY, targetType, smooth) {
|
|
if (!this.isEnabled)
|
|
return;
|
|
this.scroll.scrollToSmooth = smooth;
|
|
this.scroll.scrollToTargetY = null;
|
|
this.scroll.scrollToTargetX = null;
|
|
this.scroll.scrollToX = false;
|
|
this.scroll.scrollToY = false;
|
|
this.onScrollToStarted = false;
|
|
if (this.isVScrollEnabled && this.isContentScrollableV) {
|
|
var viewportCenterY = (this.wi.GetBoundingBox().getTop() + this.wi.GetBoundingBox().getBottom()) / 2;
|
|
if (targetType) {
|
|
targetY = C3.clamp(targetY, 0, 1);
|
|
targetY = this.contentWi.GetBoundingBox().getTop() + targetY * this.contentWi.GetHeight(true);
|
|
}
|
|
this.scroll.scrollToTargetY = this.contentWi.GetY() + (viewportCenterY - targetY);
|
|
this.scroll.scrollToY = true;
|
|
this.scroll.isIdle = false;
|
|
this._StartTicking();
|
|
this.onScrollToStarted = true;
|
|
}
|
|
if (this.isHScrollEnabled && this.isContentScrollableH) {
|
|
var viewportCenterX = (this.wi.GetBoundingBox().getLeft() + this.wi.GetBoundingBox().getRight()) / 2;
|
|
if (targetType) {
|
|
targetX = C3.clamp(targetX, 0, 1);
|
|
targetX = this.contentWi.GetBoundingBox().getLeft() + targetX * this.contentWi.GetWidth(true);
|
|
}
|
|
this.scroll.scrollToTargetX = this.contentWi.GetX() + (viewportCenterX - targetX);
|
|
this.scroll.scrollToX = true;
|
|
this.scroll.isIdle = false;
|
|
this._StartTicking();
|
|
this.onScrollToStarted = true;
|
|
}
|
|
this.contentWi.SetBboxChanged();
|
|
}
|
|
scrollBy(distanceX, distanceY, targetType, smooth) {
|
|
if (!this.isEnabled)
|
|
return;
|
|
this.scroll.scrollToSmooth = smooth;
|
|
this.scroll.scrollToTargetY = null;
|
|
this.scroll.scrollToTargetX = null;
|
|
this.scroll.scrollToX = false;
|
|
this.scroll.scrollToY = false;
|
|
this.onScrollToStarted = false;
|
|
this.boundContent();
|
|
if (this.isVScrollEnabled && this.isContentScrollableV) {
|
|
if (targetType) {
|
|
distanceY = C3.clamp(distanceY, -1, 1);
|
|
distanceY = distanceY * this.contentWi.GetHeight(true);
|
|
}
|
|
this.scroll.scrollToTargetY = this.contentWi.GetY() - distanceY;
|
|
this.scroll.scrollToY = true;
|
|
this.scroll.isIdle = false;
|
|
this._StartTicking();
|
|
this.onScrollToStarted = true;
|
|
}
|
|
if (this.isHScrollEnabled && this.isContentScrollableH) {
|
|
if (targetType) {
|
|
distanceX = C3.clamp(distanceX, -1, 1);
|
|
distanceX = distanceX * this.contentWi.GetWidth(true);
|
|
}
|
|
this.scroll.scrollToTargetX = this.contentWi.GetX() - distanceX;
|
|
this.scroll.scrollToX = true;
|
|
this.scroll.isIdle = false;
|
|
this._StartTicking();
|
|
this.onScrollToStarted = true;
|
|
}
|
|
this.contentWi.SetBboxChanged();
|
|
}
|
|
boundSlider(slider) {
|
|
if (slider == "v" && this.vSlider && this.vScrollBar) {
|
|
var sy = this.vScrollBarWi.GetBoundingBox().getTop() + (this.vSliderWi.GetY() - this.vSliderWi.GetBoundingBox().getTop()) + (this.vScrollBarWi.GetHeight(true) - this.vSliderWi.GetHeight(true)) * ((this.contentWi.GetBoundingBox().getTop() - this.wi.GetBoundingBox().getTop()) / (this.wi.GetHeight(true) - this.contentWi.GetHeight(true)));
|
|
sy = C3.clamp(sy, this.vScrollBarWi.GetBoundingBox().getTop() + (this.vSliderWi.GetY() - this.vSliderWi.GetBoundingBox().getTop()), this.vScrollBarWi.GetBoundingBox().getBottom() - (this.vSliderWi.GetBoundingBox().getBottom() - this.vSliderWi.GetY()));
|
|
this.vSliderWi.SetY(sy);
|
|
this.vSliderWi.SetBboxChanged();
|
|
}
|
|
if (slider == "h" && this.hSlider && this.hScrollBar) {
|
|
var sx = this.hScrollBarWi.GetBoundingBox().getLeft() + (this.hSliderWi.GetX() - this.hSliderWi.GetBoundingBox().getLeft()) + (this.hScrollBarWi.GetWidth(true) - this.hSliderWi.GetWidth(true)) * ((this.contentWi.GetBoundingBox().getLeft() - this.wi.GetBoundingBox().getLeft()) / (this.wi.GetWidth(true) - this.contentWi.GetWidth(true)));
|
|
sx = C3.clamp(sx, this.hScrollBarWi.GetBoundingBox().getLeft() + (this.hSliderWi.GetX() - this.hSliderWi.GetBoundingBox().getLeft()), this.hScrollBarWi.GetBoundingBox().getRight() - (this.hSliderWi.GetBoundingBox().getRight() - this.hSliderWi.GetX()));
|
|
this.hSliderWi.SetX(sx);
|
|
this.hSliderWi.SetBboxChanged();
|
|
}
|
|
}
|
|
postGridviewUpdate() {
|
|
var parts = [this.vScrollBar, this.vSlider, this.hScrollBar, this.hSlider];
|
|
for (var i = 0, l = parts.length; i < l; i++) {
|
|
if (parts[i]) {
|
|
parts[i].GetSdkInstance().CallAction(parts[i].GetPlugin().constructor.Acts.MoveToTop);
|
|
}
|
|
}
|
|
}
|
|
OnSizeChanged() {
|
|
this.contentWi.SetBboxChanged();
|
|
this.boundContent();
|
|
this.boundSlider("v");
|
|
this.boundSlider("h");
|
|
this.isContentScrollableV = true;
|
|
this.isContentScrollableH = true;
|
|
if (this.contentWi.GetHeight(true) <= this.wi.GetHeight(true)) {
|
|
this.isContentScrollableV = false;
|
|
}
|
|
if (this.contentWi.GetWidth(true) <= this.wi.GetWidth(true)) {
|
|
this.isContentScrollableH = false;
|
|
}
|
|
}
|
|
isMoving() {
|
|
return this.isTouchMoving;
|
|
}
|
|
Tick() {
|
|
if (this.scroll.isIdle || !this.content || !this.isEnabled) {
|
|
this._StopTicking();
|
|
}
|
|
if (this.onTouchStarted && this.isSwipeScrollEnabled && !this.onSliderTouchStarted) {
|
|
if (this.isHScrollEnabled && this.isContentScrollableH) {
|
|
this.contentWi.SetX(this.touchX - this.scroll.offsetX);
|
|
}
|
|
if (this.isVScrollEnabled && this.isContentScrollableV) {
|
|
this.contentWi.SetY(this.touchY - this.scroll.offsetY);
|
|
}
|
|
this.contentWi.SetBboxChanged();
|
|
}
|
|
if (this.inertia) {
|
|
if (this.isHScrollEnabled && Math.abs(this.scroll.decelerationVelocityX) > 1) {
|
|
this.contentWi.OffsetX(this.scroll.decelerationVelocityX * this.runtime.GetDt(this.content));
|
|
this.scroll.decelerationVelocityX *= 0.95;
|
|
this.contentWi.SetBboxChanged();
|
|
}
|
|
if (this.isVScrollEnabled && Math.abs(this.scroll.decelerationVelocityY) > 1) {
|
|
this.contentWi.OffsetY(this.scroll.decelerationVelocityY * this.runtime.GetDt(this.content));
|
|
this.scroll.decelerationVelocityY *= 0.95;
|
|
this.contentWi.SetBboxChanged();
|
|
}
|
|
}
|
|
if (this.scroll.scrollToY && this.scroll.scrollToTargetY != null && this.isVScrollEnabled && this.isContentScrollableV && !this.onSliderTouchStarted) {
|
|
this.contentWi.SetY(C3.lerp(this.contentWi.GetY(), this.scroll.scrollToTargetY, this.scroll.scrollToSmooth));
|
|
if (this.boundContentY()) {
|
|
this.scroll.scrollToY = false;
|
|
this.boundContentY();
|
|
} else if (Math.abs(this.contentWi.GetY() - this.scroll.scrollToTargetY) < 1) {
|
|
this.contentWi.SetY(this.scroll.scrollToTargetY);
|
|
this.contentWi.SetBboxChanged();
|
|
this.scroll.scrollToY = false;
|
|
}
|
|
}
|
|
if (this.scroll.scrollToX && this.scroll.scrollToTargetX != null && this.isHScrollEnabled && this.isContentScrollableH && !this.onSliderTouchStarted) {
|
|
this.contentWi.SetX(C3.lerp(this.contentWi.GetX(), this.scroll.scrollToTargetX, this.scroll.scrollToSmooth));
|
|
if (this.boundContentX()) {
|
|
this.scroll.scrollToX = false;
|
|
this.boundContentX();
|
|
} else if (Math.abs(this.contentWi.GetX() - this.scroll.scrollToTargetX) < 1) {
|
|
this.contentWi.SetX(this.scroll.scrollToTargetX);
|
|
this.contentWi.SetBboxChanged();
|
|
this.scroll.scrollToX = false;
|
|
}
|
|
}
|
|
if (this.onScrollToStarted && !this.scroll.scrollToX && !this.scroll.scrollToY) {
|
|
this.scroll.isIdle = true;
|
|
this.onScrollToStarted = false;
|
|
}
|
|
if (this.isVScrollEnabled && this.isContentScrollableV) {
|
|
this.boundSlider("v");
|
|
}
|
|
if (this.isHScrollEnabled && this.isContentScrollableH) {
|
|
this.boundSlider("h");
|
|
}
|
|
if (this.isVScrollEnabled && !this.scroll.scrollToY) {
|
|
this.boundContentY(true);
|
|
}
|
|
if (this.isHScrollEnabled && !this.scroll.scrollToX) {
|
|
this.boundContentX(true);
|
|
}
|
|
if (!this.onTouchStarted && Math.abs(this.scroll.decelerationVelocityX) <= 1 && Math.abs(this.scroll.decelerationVelocityY) <= 1 && !this.scroll.scrollToX && !this.scroll.scrollToY) {
|
|
this.scroll.isIdle = true;
|
|
this.boundContent();
|
|
}
|
|
}
|
|
Release() {
|
|
this.aekiro_scrollViewManager.remove(this.GetObjectInstance());
|
|
this.goManager.eventManager.removeListener(this.SetForceOwnTextureListener);
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"isEnabled": this.isEnabled,
|
|
"direction": this.direction,
|
|
"isSwipeScrollEnabled": this.isSwipeScrollEnabled,
|
|
"isMouseScroll": this.isMouseScroll,
|
|
"inertia": this.inertia,
|
|
"movement": this.movement,
|
|
"contentUID": this.contentUID,
|
|
"vSliderUID": this.vSliderUID,
|
|
"vScrollBarUID": this.vScrollBarUID,
|
|
"hSliderUID": this.hSliderUID,
|
|
"hScrollBarUID": this.hScrollBarUID
|
|
};
|
|
}
|
|
LoadFromJson(o) {
|
|
this.isEnabled = o["isEnabled"];
|
|
this.direction = o["direction"];
|
|
this.isSwipeScrollEnabled = o["isSwipeScrollEnabled"];
|
|
this.isMouseScroll = o["isMouseScroll"];
|
|
this.inertia = o["inertia"];
|
|
this.movement = o["movement"];
|
|
this.contentUID = o["contentUID"];
|
|
this.vSliderUID = o["vSliderUID"];
|
|
this.vScrollBarUID = o["vScrollBarUID"];
|
|
this.hSliderUID = o["hSliderUID"];
|
|
this.hScrollBarUID = o["hScrollBarUID"];
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_scrollView.Cnds = {};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_scrollView.Acts = {
|
|
ScrollTo(targetX, targetY, targetType, smooth) {
|
|
this.scrollTo(targetX, targetY, targetType, smooth);
|
|
},
|
|
ScrollBy(distanceX, distanceY, targetType, smooth) {
|
|
this.scrollBy(distanceX, distanceY, targetType, smooth);
|
|
},
|
|
setEnabled(isEnabled) {
|
|
this.isEnabled = isEnabled;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_scrollView.Exps = {};
|
|
}
|
|
'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.DragnDrop = class DragnDropBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
const rt = this._runtime.Dispatcher();
|
|
this._disposables = new C3.CompositeDisposable(C3.Disposable.From(rt, "pointerdown", e=>this._OnPointerDown(e.data)),C3.Disposable.From(rt, "pointermove", e=>this._OnPointerMove(e.data)),C3.Disposable.From(rt, "pointerup", e=>this._OnPointerUp(e.data, false)),C3.Disposable.From(rt, "pointercancel", e=>this._OnPointerUp(e.data, true)))
|
|
}
|
|
Release() {
|
|
this._disposables.Release();
|
|
this._disposables = null;
|
|
super.Release()
|
|
}
|
|
_OnPointerDown(e) {
|
|
this._OnInputDown(e["pointerId"].toString(), e["pageX"] - this._runtime.GetCanvasClientX(), e["pageY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnPointerMove(e) {
|
|
this._OnInputMove(e["pointerId"].toString(), e["pageX"] - this._runtime.GetCanvasClientX(), e["pageY"] - this._runtime.GetCanvasClientY())
|
|
}
|
|
_OnPointerUp(e, isCancel) {
|
|
this._OnInputUp(e["pointerId"].toString())
|
|
}
|
|
async _OnInputDown(src, clientX, clientY) {
|
|
const myInstances = this.GetInstances();
|
|
let topMost = null;
|
|
let topBehInst = null;
|
|
let topX = 0;
|
|
let topY = 0;
|
|
for (const inst of myInstances) {
|
|
const behInst = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.DragnDrop);
|
|
if (!behInst.IsEnabled() || behInst.IsDragging())
|
|
continue;
|
|
const wi = inst.GetWorldInfo();
|
|
const layer = wi.GetLayer();
|
|
const [lx,ly] = layer.CanvasCssToLayer(clientX, clientY, wi.GetTotalZElevation());
|
|
if (!wi.ContainsPoint(lx, ly))
|
|
continue;
|
|
if (!topMost) {
|
|
topMost = inst;
|
|
topBehInst = behInst;
|
|
topX = lx;
|
|
topY = ly;
|
|
continue
|
|
}
|
|
const topWi = topMost.GetWorldInfo();
|
|
if (layer.GetIndex() > topWi.GetLayer().GetIndex() || layer.GetIndex() === topWi.GetLayer().GetIndex() && wi.GetZIndex() > topWi.GetZIndex()) {
|
|
topMost = inst;
|
|
topBehInst = behInst;
|
|
topX = lx;
|
|
topY = ly
|
|
}
|
|
}
|
|
if (topMost)
|
|
await topBehInst._OnDown(src, topX, topY)
|
|
}
|
|
_OnInputMove(src, clientX, clientY) {
|
|
const myInstances = this.GetInstances();
|
|
for (const inst of myInstances) {
|
|
const behInst = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.DragnDrop);
|
|
if (!behInst.IsEnabled() || !behInst.IsDragging() || behInst.IsDragging() && behInst.GetDragSource() !== src)
|
|
continue;
|
|
const wi = inst.GetWorldInfo();
|
|
const layer = wi.GetLayer();
|
|
const [lx,ly] = layer.CanvasCssToLayer(clientX, clientY, wi.GetTotalZElevation());
|
|
behInst._OnMove(lx, ly)
|
|
}
|
|
}
|
|
async _OnInputUp(src) {
|
|
const myInstances = this.GetInstances();
|
|
for (const inst of myInstances) {
|
|
const behInst = inst.GetBehaviorSdkInstanceFromCtor(C3.Behaviors.DragnDrop);
|
|
if (behInst.IsDragging() && behInst.GetDragSource() === src)
|
|
await behInst._OnUp()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.DragnDrop.Type = class DragnDropType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
const AXES = 0;
|
|
const ENABLE = 1;
|
|
C3.Behaviors.DragnDrop.Instance = class DragnDropInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this._isDragging = false;
|
|
this._dx = 0;
|
|
this._dy = 0;
|
|
this._dragSource = "<none>";
|
|
this._axes = 0;
|
|
this._isEnabled = true;
|
|
if (properties) {
|
|
this._axes = properties[AXES];
|
|
this._isEnabled = properties[ENABLE]
|
|
}
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"a": this._axes,
|
|
"e": this._isEnabled
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this._axes = o["a"];
|
|
this._isEnabled = o["e"];
|
|
this._isDragging = false
|
|
}
|
|
IsEnabled() {
|
|
return this._isEnabled
|
|
}
|
|
IsDragging() {
|
|
return this._isDragging
|
|
}
|
|
GetDragSource() {
|
|
return this._dragSource
|
|
}
|
|
async _OnDown(src, x, y) {
|
|
const wi = this.GetWorldInfo();
|
|
this._dx = x - wi.GetX();
|
|
this._dy = y - wi.GetY();
|
|
this._isDragging = true;
|
|
this._dragSource = src;
|
|
await this.TriggerAsync(C3.Behaviors.DragnDrop.Cnds.OnDragStart)
|
|
}
|
|
_OnMove(x, y) {
|
|
const wi = this.GetWorldInfo();
|
|
const newX = x - this._dx;
|
|
const newY = y - this._dy;
|
|
if (this._axes === 0) {
|
|
if (wi.GetX() !== newX || wi.GetY() !== newY) {
|
|
wi.SetXY(newX, newY);
|
|
wi.SetBboxChanged()
|
|
}
|
|
} else if (this._axes === 1) {
|
|
if (wi.GetX() !== newX) {
|
|
wi.SetX(newX);
|
|
wi.SetBboxChanged()
|
|
}
|
|
} else if (this._axes === 2)
|
|
if (wi.GetY() !== newY) {
|
|
wi.SetY(newY);
|
|
wi.SetBboxChanged()
|
|
}
|
|
}
|
|
async _OnUp() {
|
|
this._isDragging = false;
|
|
await this.TriggerAsync(C3.Behaviors.DragnDrop.Cnds.OnDrop)
|
|
}
|
|
GetPropertyValueByIndex(index) {
|
|
switch (index) {
|
|
case AXES:
|
|
return this._axes;
|
|
case ENABLE:
|
|
return this._isEnabled
|
|
}
|
|
}
|
|
SetPropertyValueByIndex(index, value) {
|
|
switch (index) {
|
|
case AXES:
|
|
this._axes = value;
|
|
break;
|
|
case ENABLE:
|
|
this._isEnabled = !!value;
|
|
break
|
|
}
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "behaviors.dragndrop";
|
|
return [{
|
|
title: "$" + this.GetBehaviorType().GetName(),
|
|
properties: [{
|
|
name: prefix + ".debugger.is-dragging",
|
|
value: this._isDragging
|
|
}, {
|
|
name: prefix + ".properties.enabled.name",
|
|
value: this._isEnabled,
|
|
onedit: v=>this._isEnabled = v
|
|
}]
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.DragnDrop.Cnds = {
|
|
IsDragging() {
|
|
return this._isDragging
|
|
},
|
|
OnDragStart() {
|
|
return true
|
|
},
|
|
OnDrop() {
|
|
return true
|
|
},
|
|
IsEnabled() {
|
|
return this._isEnabled
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.DragnDrop.Acts = {
|
|
SetEnabled(e) {
|
|
this._isEnabled = !!e;
|
|
if (!this._isEnabled)
|
|
this._isDragging = false
|
|
},
|
|
SetAxes(a) {
|
|
this._axes = a
|
|
},
|
|
Drop() {
|
|
if (this._isDragging)
|
|
this._OnUp()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.DragnDrop.Exps = {}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Flash = class FlashBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Flash.Type = class FlashType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType)
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Flash.Instance = class FlashInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
this._onTime = 0;
|
|
this._offTime = 0;
|
|
this._stage = 0;
|
|
this._stageTimeLeft = 0;
|
|
this._timeLeft = 0;
|
|
this._StartTicking()
|
|
}
|
|
Release() {
|
|
super.Release()
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"on": this._onTime,
|
|
"off": this._offTime,
|
|
"s": this._stage,
|
|
"stl": this._stageTimeLeft,
|
|
"tl": this._timeLeft
|
|
}
|
|
}
|
|
LoadFromJson(o) {
|
|
this._onTime = o["on"];
|
|
this._offTime = o["off"];
|
|
this._stage = o["s"];
|
|
this._stageTimeLeft = o["stl"];
|
|
this._timeLeft = o["tl"] === null ? Infinity : o["tl"]
|
|
}
|
|
Tick() {
|
|
if (this._timeLeft <= 0)
|
|
return;
|
|
const dt = this._runtime.GetDt(this._inst);
|
|
this._timeLeft -= dt;
|
|
if (this._timeLeft <= 0) {
|
|
this._timeLeft = 0;
|
|
this._inst.GetWorldInfo().SetVisible(true);
|
|
this._runtime.UpdateRender();
|
|
return this.DebugTrigger(C3.Behaviors.Flash.Cnds.OnFlashEnded)
|
|
}
|
|
this._stageTimeLeft -= dt;
|
|
if (this._stageTimeLeft <= 0) {
|
|
if (this._stage === 0) {
|
|
this._inst.GetWorldInfo().SetVisible(false);
|
|
this._stage = 1;
|
|
this._stageTimeLeft += this._offTime
|
|
} else {
|
|
this._inst.GetWorldInfo().SetVisible(true);
|
|
this._stage = 0;
|
|
this._stageTimeLeft += this._onTime
|
|
}
|
|
this._runtime.UpdateRender()
|
|
}
|
|
}
|
|
GetDebuggerProperties() {
|
|
const prefix = "behaviors.flash.debugger";
|
|
return [{
|
|
title: "$" + this.GetBehaviorType().GetName(),
|
|
properties: [{
|
|
name: prefix + ".on-time",
|
|
value: this._onTime,
|
|
onedit: v=>this._onTime = v
|
|
}, {
|
|
name: prefix + ".off-time",
|
|
value: this._offTime,
|
|
onedit: v=>this._offTime = v
|
|
}, {
|
|
name: prefix + ".is-flashing",
|
|
value: this._timeLeft > 0
|
|
}, {
|
|
name: prefix + ".time-left",
|
|
value: this._timeLeft
|
|
}]
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Flash.Cnds = {
|
|
IsFlashing() {
|
|
return this._timeLeft > 0
|
|
},
|
|
OnFlashEnded() {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Flash.Acts = {
|
|
Flash(on, off, dur) {
|
|
this._onTime = on;
|
|
this._offTime = off;
|
|
this._stage = 1;
|
|
this._stageTimeLeft = off;
|
|
this._timeLeft = dur;
|
|
this._inst.GetWorldInfo().SetVisible(false);
|
|
this._runtime.UpdateRender()
|
|
},
|
|
StopFlashing() {
|
|
this._timeLeft = 0;
|
|
this._inst.GetWorldInfo().SetVisible(true);
|
|
this._runtime.UpdateRender()
|
|
}
|
|
}
|
|
}
|
|
;'use strict';
|
|
{
|
|
const C3 = self.C3;
|
|
C3.Behaviors.Flash.Exps = {}
|
|
}
|
|
;"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_dialog = class aekiro_dialogBehavior extends C3.SDKBehaviorBase {
|
|
constructor(opts) {
|
|
super(opts);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_dialog.Type = class aekiro_dialogType extends C3.SDKBehaviorTypeBase {
|
|
constructor(behaviorType) {
|
|
super(behaviorType);
|
|
}
|
|
Release() {
|
|
super.Release();
|
|
}
|
|
OnCreate() {}
|
|
}
|
|
;
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_dialog.Instance = class aekiro_dialogInstance extends C3.SDKBehaviorInstanceBase {
|
|
constructor(behInst, properties) {
|
|
super(behInst);
|
|
if (properties) {
|
|
this.openAnimation = properties[0];
|
|
this.openAnimTweenFunction = properties[1];
|
|
this.openAnimDuration = properties[2];
|
|
this.openSound = properties[3];
|
|
this.closeAnimation = properties[4];
|
|
this.closeAnimTweenFunction = properties[5];
|
|
this.closeAnimDuration = properties[6];
|
|
this.closeSound = properties[7];
|
|
this.closeButtonUID = properties[8];
|
|
this.isModal = properties[9];
|
|
}
|
|
this.proui = this.GetRuntime().GetSingleGlobalObjectClassByCtor(C3.Plugins.aekiro_proui);
|
|
if (this.proui) {
|
|
this.proui = this.proui.GetSingleGlobalInstance().GetSdkInstance();
|
|
}
|
|
this.GetObjectInstance().GetUnsavedDataMap().aekiro_dialog = this;
|
|
this.wi = this.GetWorldInfo();
|
|
this.inst = this.GetObjectInstance();
|
|
this.aekiro_dialogManager = globalThis["aekiro_dialogManager"];
|
|
this.goManager = globalThis["aekiro_goManager"];
|
|
this.isInit = false;
|
|
this.isOpen = false;
|
|
this.tween = new self["TWEEN"]["Tween"]();
|
|
this.tween_opacity = new self["TWEEN"]["Tween"]();
|
|
this.tweenObject = {};
|
|
this.reverseTweenObject = {};
|
|
this.tweenFunctions = [self["TWEEN"]["Easing"]["Linear"]["None"], self["TWEEN"]["Easing"]["Quadratic"]["Out"], self["TWEEN"]["Easing"]["Quartic"]["Out"], self["TWEEN"]["Easing"]["Exponential"]["Out"], self["TWEEN"]["Easing"]["Circular"]["Out"], self["TWEEN"]["Easing"]["Back"]["Out"], self["TWEEN"]["Easing"]["Elastic"]["Out"], self["TWEEN"]["Easing"]["Bounce"]["Out"]];
|
|
this.goManager.eventManager.on("childrenRegistred", ()=>{
|
|
this.setCloseButton();
|
|
this.onCreateInit();
|
|
}
|
|
, {
|
|
"once": true
|
|
});
|
|
}
|
|
PostCreate() {
|
|
this.aekiro_gameobject = this.GetObjectInstance().GetUnsavedDataMap().aekiro_gameobject;
|
|
}
|
|
onCreateInit() {
|
|
var map = this.GetObjectInstance().GetUnsavedDataMap();
|
|
if (!map.audioSources) {
|
|
map.audioSources = {};
|
|
}
|
|
this.audioSources = map.audioSources;
|
|
this.audioSources.open = new AudioSource(this.openSound,this.GetRuntime());
|
|
this.audioSources.close = new AudioSource(this.closeSound,this.GetRuntime());
|
|
this.setVisible(false);
|
|
this.wi.SetX(this.wi.GetLayer().GetViewport().getLeft());
|
|
this.wi.SetBboxChanged();
|
|
this.isInit = true;
|
|
}
|
|
setCloseButton() {
|
|
if (!this.closeButtonUID)
|
|
return;
|
|
this.closeButton = this.goManager.gos[this.closeButtonUID];
|
|
if (!this.closeButton) {
|
|
console.error("ProUI-Dialog: Close button not found; Please check its name !");
|
|
return;
|
|
}
|
|
if (!this.closeButton.GetUnsavedDataMap().aekiro_button) {
|
|
console.error("ProUI-Dialog: The close button needs to have a button behavior !");
|
|
return;
|
|
}
|
|
var self = this;
|
|
this.closeButton.GetUnsavedDataMap().aekiro_button.callbacks.push(function() {
|
|
self.close();
|
|
});
|
|
}
|
|
SetOwnScale(scale) {
|
|
var layers = this.getOutLayers();
|
|
layers.push(this.wi.GetLayer());
|
|
for (var i = 0, l = layers.length; i < l; i++) {
|
|
layers[i].SetOwnScale(scale);
|
|
}
|
|
}
|
|
SetOpacity(opacity) {
|
|
var layers = this.getOutLayers();
|
|
layers.push(this.wi.GetLayer());
|
|
for (var i = 0, l = layers.length; i < l; i++) {
|
|
layers[i].SetOpacity(opacity);
|
|
}
|
|
}
|
|
setVisible(isVisible) {
|
|
var layers = this.getOutLayers();
|
|
layers.push(this.wi.GetLayer());
|
|
for (var i = 0, l = layers.length; i < l; i++) {
|
|
layers[i].SetVisible(isVisible);
|
|
}
|
|
}
|
|
getOutLayers() {
|
|
var mylayer = this.wi.GetLayer();
|
|
var insts = this.aekiro_gameobject.hierarchyToArray();
|
|
var layers = [];
|
|
var layer;
|
|
for (var i = 0, l = insts.length; i < l; i++) {
|
|
layer = insts[i].GetWorldInfo().GetLayer();
|
|
if (layer != mylayer && layers.indexOf(layer) == -1) {
|
|
layers.push(layer);
|
|
}
|
|
}
|
|
return layers;
|
|
}
|
|
setInitialState(targetX, targetY, center) {
|
|
var initX, initY;
|
|
var viewport = this.wi.GetLayer().GetViewport();
|
|
if (this.openAnimation == 0 || this.openAnimation == 5 || this.openAnimation == 6) {
|
|
initX = targetX;
|
|
initY = targetY;
|
|
if (center) {
|
|
initY = (viewport.getTop() + viewport.getBottom()) / 2;
|
|
initX = (viewport.getLeft() + viewport.getRight()) / 2;
|
|
}
|
|
if (this.openAnimation == 5 || this.openAnimation == 6) {
|
|
if (this.openAnimation == 5) {
|
|
this.wi.GetLayer().SetOwnScale(2);
|
|
} else {
|
|
this.wi.GetLayer().SetOwnScale(0.2);
|
|
}
|
|
this.wi.GetLayer().SetOpacity(0);
|
|
}
|
|
} else if (this.openAnimation == 1) {
|
|
initY = viewport.getTop() - this.wi.GetHeight() / 2 - 100;
|
|
if (center) {
|
|
initX = (viewport.getLeft() + viewport.getRight()) / 2;
|
|
} else {
|
|
initX = targetX;
|
|
}
|
|
} else if (this.openAnimation == 2) {
|
|
initY = viewport.getBottom() + this.wi.GetHeight() / 2 + 100;
|
|
if (center) {
|
|
initX = (viewport.getLeft() + viewport.getRight()) / 2;
|
|
} else {
|
|
initX = targetX;
|
|
}
|
|
} else if (this.openAnimation == 3) {
|
|
initX = viewport.getRight() + this.wi.GetWidth() / 2 + 100;
|
|
if (center) {
|
|
initY = (viewport.getTop() + viewport.getBottom()) / 2;
|
|
} else {
|
|
initY = targetY;
|
|
}
|
|
} else if (this.openAnimation == 4) {
|
|
initX = viewport.getLeft() - this.wi.GetWidth() / 2 - 100;
|
|
if (center) {
|
|
initY = (viewport.getTop() + viewport.getBottom()) / 2;
|
|
} else {
|
|
initY = targetY;
|
|
}
|
|
}
|
|
this.wi.SetX(initX);
|
|
this.wi.SetY(initY);
|
|
this.wi.SetBboxChanged();
|
|
}
|
|
open(_targetX, _targetY, center) {
|
|
if (this.isOpen) {
|
|
return;
|
|
}
|
|
if (this.aekiro_dialogManager.isModalDialogOpened()) {
|
|
console.log("ProUI-Dialog: Can not open dialog because modal dialog is already opened");
|
|
return;
|
|
}
|
|
if (!this.isOpen && this.tween["isPlaying"]) {
|
|
this.tween["stop"]();
|
|
}
|
|
this.postClose();
|
|
this.aekiro_dialogManager.addDialog(this.GetObjectInstance());
|
|
this.isOpen = true;
|
|
this.Trigger(C3.Behaviors.aekiro_dialog.Cnds.onDialogOpened);
|
|
if (this.GetRuntime().GetTimeScale() != 1) {
|
|
this.aekiro_gameobject.setTimeScale(1);
|
|
}
|
|
this.setInitialState(_targetX, _targetY, center);
|
|
this.setVisible(true);
|
|
var targetX = _targetX;
|
|
var targetY = _targetY;
|
|
var viewport = this.wi.GetLayer().GetViewport();
|
|
if (center) {
|
|
targetX = (viewport.getLeft() + viewport.getRight()) / 2;
|
|
targetY = (viewport.getTop() + viewport.getBottom()) / 2;
|
|
}
|
|
if (this.openAnimDuration == 0) {
|
|
this.openAnimation = 0;
|
|
}
|
|
this.isScaleAnimation = false;
|
|
this.tweenObject.x = this.wi.GetX();
|
|
this.tweenObject.y = this.wi.GetY();
|
|
this.tweenObject.scale = this.wi.GetLayer().GetOwnScale();
|
|
this.tweenObject.opacity = this.wi.GetLayer().GetOpacity();
|
|
this.tween["setObject"](this.tweenObject);
|
|
this.tween["easing"](this.tweenFunctions[this.openAnimTweenFunction]);
|
|
this.tween["onComplete"](this.postOpen, this);
|
|
if (this.openAnimation == 1 || this.openAnimation == 2) {
|
|
this.tween["to"]({
|
|
y: targetY
|
|
}, this.openAnimDuration);
|
|
this.reverseTweenObject.y = this.wi.GetY();
|
|
} else if (this.openAnimation == 3 || this.openAnimation == 4) {
|
|
this.tween["to"]({
|
|
x: targetX
|
|
}, this.openAnimDuration);
|
|
this.reverseTweenObject.x = this.wi.GetX();
|
|
} else if (this.openAnimation == 5 || this.openAnimation == 6) {
|
|
this.tween["to"]({
|
|
scale: 1
|
|
}, this.openAnimDuration);
|
|
this.reverseTweenObject.scale = this.wi.GetLayer().GetOwnScale();
|
|
this.tween_opacity["setObject"](this.tweenObject);
|
|
this.tween_opacity["to"]({
|
|
opacity: 1
|
|
}, 300);
|
|
this.tween_opacity["easing"](self["TWEEN"]["Easing"]["Quartic"]["Out"]);
|
|
this.isScaleAnimation = true;
|
|
this.outLayers = this.getOutLayers();
|
|
}
|
|
if (this.openAnimation > 0) {
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
this._StartTicking();
|
|
if (this.openAnimation == 5 || this.openAnimation == 6) {
|
|
this.tween_opacity["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
}
|
|
} else {
|
|
this.wi.SetXY(targetX, targetY);
|
|
this.wi.SetBboxChanged();
|
|
}
|
|
this.audioSources.open.play();
|
|
}
|
|
postOpen() {}
|
|
getCloseTargetPosition() {
|
|
var viewport = this.wi.GetLayer().GetViewport();
|
|
var X = this.wi.GetX();
|
|
var Y = this.wi.GetY();
|
|
if (this.closeAnimation == 2) {
|
|
Y = viewport.getBottom() + this.wi.GetHeight() / 2 + 100;
|
|
} else if (this.closeAnimation == 3) {
|
|
Y = viewport.getTop() - this.wi.GetHeight() / 2 - 100;
|
|
} else if (this.closeAnimation == 4) {
|
|
X = viewport.getLeft() - this.wi.GetWidth() / 2 - 100;
|
|
} else if (this.closeAnimation == 5) {
|
|
X = viewport.getRight() + this.wi.GetWidth() / 2 + 100;
|
|
}
|
|
return {
|
|
x: X,
|
|
y: Y
|
|
};
|
|
}
|
|
close() {
|
|
if (!this.isOpen || this.tween["isPlaying"]) {
|
|
return;
|
|
}
|
|
this.isOpen = false;
|
|
this.aekiro_dialogManager.removeDialog(this.GetObjectInstance());
|
|
this.Trigger(C3.Behaviors.aekiro_dialog.Cnds.onDialogClosed);
|
|
var target = this.getCloseTargetPosition();
|
|
var targetX = target.x;
|
|
var targetY = target.y;
|
|
if (this.closeAnimDuration == 0) {
|
|
this.closeAnimation = 0;
|
|
}
|
|
this.isScaleAnimation = false;
|
|
this.tweenObject.x = this.wi.GetX();
|
|
this.tweenObject.y = this.wi.GetY();
|
|
this.tweenObject.scale = this.wi.GetLayer().GetOwnScale();
|
|
this.tweenObject.opacity = this.wi.GetLayer().GetOpacity();
|
|
this.tween["setObject"](this.tweenObject);
|
|
this.tween["easing"](this.tweenFunctions[this.closeAnimTweenFunction]);
|
|
this.tween["onComplete"](this.postClose, this);
|
|
if (this.closeAnimation == 2 || this.closeAnimation == 3) {
|
|
this.tween["to"]({
|
|
y: targetY
|
|
}, this.closeAnimDuration);
|
|
} else if (this.closeAnimation == 4 || this.closeAnimation == 5) {
|
|
this.tween["to"]({
|
|
x: targetX
|
|
}, this.closeAnimDuration);
|
|
} else if (this.closeAnimation == 6 || this.closeAnimation == 7) {
|
|
if (this.closeAnimation == 6) {
|
|
this.tween["to"]({
|
|
scale: 0.2
|
|
}, this.closeAnimDuration);
|
|
} else {
|
|
this.tween["to"]({
|
|
scale: 2
|
|
}, this.closeAnimDuration);
|
|
}
|
|
this.tween_opacity["setObject"](this.tweenObject);
|
|
this.tween_opacity["to"]({
|
|
opacity: 0
|
|
}, 300);
|
|
this.tween_opacity["easing"](self["TWEEN"]["Easing"]["Quartic"]["Out"]);
|
|
this.isScaleAnimation = true;
|
|
this.outLayers = this.getOutLayers();
|
|
} else if (this.closeAnimation == 1) {
|
|
this.tween["to"](this.reverseTweenObject, this.openAnimDuration);
|
|
if (this.openAnimation == 5 || this.openAnimation == 6) {
|
|
this.isScaleAnimation = true;
|
|
this.tween_opacity["to"]({
|
|
opacity: 0
|
|
}, 300);
|
|
}
|
|
}
|
|
if (this.closeAnimation == 0 || (this.openAnimation == 0 && this.closeAnimation == 1)) {
|
|
this.postClose();
|
|
} else if (this.closeAnimation == 1) {
|
|
if (this.openAnimation == 5 || this.openAnimation == 6) {
|
|
this.tween_opacity["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
}
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
this._StartTicking();
|
|
} else {
|
|
this.tween["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
if (this.closeAnimation == 6 || this.closeAnimation == 7) {
|
|
this.tween_opacity["start"](this.GetRuntime().GetWallTime() * 1000);
|
|
}
|
|
this._StartTicking();
|
|
}
|
|
this.audioSources.close.play();
|
|
}
|
|
postClose() {
|
|
var layer = this.wi.GetLayer();
|
|
var viewport = layer.GetViewport();
|
|
this.SetOwnScale(1);
|
|
this.SetOpacity(1);
|
|
this.setVisible(false);
|
|
var x = (viewport.getLeft() + viewport.getRight()) / 2;
|
|
var y = viewport.getTop() - this.wi.GetHeight() / 2 - 100;
|
|
this.wi.SetX(x);
|
|
this.wi.SetY(y);
|
|
this.wi.SetBboxChanged();
|
|
this._StopTicking();
|
|
}
|
|
Tick() {
|
|
var layer;
|
|
if (this.tween["isPlaying"]) {
|
|
this.tween["update"](this.GetRuntime().GetWallTime() * 1000);
|
|
if (this.isScaleAnimation) {
|
|
layer = this.wi.GetLayer();
|
|
layer.SetOwnScale(this.tweenObject.scale);
|
|
for (var i = 0, l = this.outLayers.length; i < l; i++) {
|
|
this.outLayers[i].SetOwnScale(this.tweenObject.scale);
|
|
}
|
|
} else {
|
|
this.wi.SetXY(this.tweenObject.x, this.tweenObject.y);
|
|
this.wi.SetBboxChanged();
|
|
}
|
|
}
|
|
if (this.tween_opacity["isPlaying"]) {
|
|
this.tween_opacity["update"](this.GetRuntime().GetWallTime() * 1000);
|
|
layer.SetOpacity(this.tweenObject.opacity);
|
|
for (var i = 0, l = this.outLayers.length; i < l; i++) {
|
|
this.outLayers[i].SetOpacity(this.tweenObject.opacity);
|
|
}
|
|
}
|
|
if (!this.tween["isPlaying"]) {
|
|
this._StopTicking();
|
|
}
|
|
}
|
|
Release() {
|
|
this.aekiro_dialogManager.removeDialog(this.GetObjectInstance());
|
|
super.Release();
|
|
}
|
|
SaveToJson() {
|
|
return {
|
|
"openAnimation": this.openAnimation,
|
|
"openAnimTweenFunction": this.openAnimTweenFunction,
|
|
"openAnimDuration": this.openAnimDuration,
|
|
"openSound": this.openSound,
|
|
"closeAnimation": this.closeAnimation,
|
|
"closeAnimTweenFunction": this.closeAnimTweenFunction,
|
|
"closeAnimDuration": this.closeAnimDuration,
|
|
"closeSound": this.closeSound,
|
|
"closeButtonUID": this.closeButtonUID,
|
|
"isModal": this.isModal
|
|
};
|
|
}
|
|
LoadFromJson(o) {
|
|
this.openAnimation = o["openAnimation"];
|
|
this.openAnimTweenFunction = o["openAnimTweenFunction"];
|
|
this.openAnimDuration = o["openAnimDuration"];
|
|
this.openSound = o["openSound"];
|
|
this.closeAnimation = o["closeAnimation"];
|
|
this.closeAnimTweenFunction = o["closeAnimTweenFunction"];
|
|
this.closeAnimDuration = o["closeAnimDuration"];
|
|
this.closeSound = o["closeSound"];
|
|
this.closeButtonUID = o["closeButtonUID"];
|
|
this.isModal = o["isModal"];
|
|
}
|
|
}
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_dialog.Cnds = {
|
|
onDialogOpened() {
|
|
return true;
|
|
},
|
|
onDialogClosed() {
|
|
return true;
|
|
},
|
|
isOpened() {
|
|
return this.isOpen;
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_dialog.Acts = {
|
|
Open(targetX, targetY, isCentered) {
|
|
this.open(targetX, targetY, isCentered);
|
|
},
|
|
Close() {
|
|
this.close();
|
|
},
|
|
SetOpenSoundVolume(v) {
|
|
this.audioSources.open.setVolume(v);
|
|
},
|
|
SetCloseSoundVolume(v) {
|
|
this.audioSources.close.setVolume(v);
|
|
}
|
|
};
|
|
}
|
|
"use strict";
|
|
{
|
|
C3.Behaviors.aekiro_dialog.Exps = {};
|
|
}
|
|
"use strict"
|
|
{
|
|
const C3 = self.C3;
|
|
self.C3_GetObjectRefTable = function() {
|
|
return [C3.Plugins.Spritefont2, C3.Behaviors.aekiro_gameobject, C3.Behaviors.MoveTo, C3.Behaviors.Fade, C3.Behaviors.aekiro_gridviewbind, C3.Behaviors.Pin, C3.Plugins.Sprite, C3.Behaviors.aekiro_button, C3.Behaviors.aekiro_checkbox, C3.Behaviors.aekiro_radiobutton, C3.Plugins.NinePatch, C3.Plugins.Arr, C3.Plugins.AJAX, C3.Plugins.Json, C3.Plugins.aekiro_proui, C3.Behaviors.aekiro_progress, C3.Behaviors.mcube_rexspline, C3.Behaviors.Timer, C3.Plugins.Touch, C3.Plugins.Mouse, C3.Plugins.Keyboard, C3.Plugins.Browser, C3.Behaviors.aekiro_radiogroup, C3.Behaviors.aekiro_gridView, C3.Behaviors.aekiro_scrollView, C3.Plugins.TiledBg, C3.Behaviors.DragnDrop, C3.Plugins.DrawingCanvas, C3.Behaviors.Flash, C3.Plugins.Audio, C3.Plugins.LocalStorage, C3.Plugins.CBhash, C3.Behaviors.aekiro_dialog, C3.Plugins.Sparsha_copyclip, C3.Plugins.Massive_Cube_Forge, C3.Plugins.TextBox, C3.Plugins.System.Cnds.OnLayoutStart, C3.Plugins.System.Acts.SetTimescale, C3.Plugins.aekiro_proui.Acts.Init, C3.Plugins.Spritefont2.Acts.SetText, C3.Plugins.Audio.Acts.StopAll, C3.ScriptsInEvents.Egame_Event1_Act5, C3.Plugins.Arr.Acts.SetX, C3.Plugins.Json.Acts.Parse, C3.Behaviors.aekiro_gridView.Acts.Clear, C3.Plugins.AJAX.Acts.RequestFile, C3.Plugins.System.Acts.MapFunction, C3.Plugins.System.Acts.SetLayerVisible, C3.Plugins.System.Acts.SetVar, C3.Plugins.Sprite.Acts.Destroy, C3.Plugins.DrawingCanvas.Acts.ClearCanvas, C3.Plugins.System.Exps.rgba, C3.Plugins.DrawingCanvas.Acts.PasteObject, C3.Plugins.Spritefont2.Acts.Destroy, C3.Plugins.System.Cnds.Compare, C3.Plugins.Audio.Acts.Play, C3.Plugins.System.Cnds.Else, C3.Plugins.System.Cnds.For, C3.Plugins.System.Exps.loopindex, C3.Plugins.System.Acts.CreateObject, C3.Plugins.System.Exps.int, C3.Plugins.System.Exps.tokenat, C3.Plugins.Sprite.Exps.Width, C3.Plugins.Sprite.Acts.SetInstanceVar, C3.Plugins.Sprite.Acts.SetAnimFrame, C3.Plugins.Sprite.Acts.MoveToTop, C3.Plugins.Spritefont2.Acts.MoveToTop, C3.Plugins.Sprite.Acts.AddChild, C3.Plugins.Sprite.Acts.SetPos, C3.Plugins.Arr.Exps.At, C3.Plugins.System.Cnds.IsGroupActive, C3.Plugins.System.Exps.random, C3.Plugins.System.Exps.tokencount, C3.Plugins.Json.Exps.Get, C3.Plugins.System.Acts.CreateObjectByName, C3.ScriptsInEvents.Egame_Event16_Act9, C3.Plugins.Sprite.Acts.SetOpacity, C3.Behaviors.aekiro_progress.Acts.SetMaxValue, C3.Behaviors.aekiro_progress.Acts.setValue, C3.Plugins.Sprite.Cnds.OnAnimFinished, C3.Plugins.Sprite.Acts.SetAnim, C3.Behaviors.mcube_rexspline.Cnds.OnHitTarget, C3.Behaviors.Timer.Cnds.OnTimer, C3.Plugins.Sprite.Cnds.OnDestroyed, C3.Plugins.Sprite.Acts.Spawn, C3.Behaviors.MoveTo.Acts.MoveToPosition, C3.Plugins.Spritefont2.Exps.X, C3.Plugins.Spritefont2.Exps.Y, C3.Plugins.System.Acts.AddVar, C3.Plugins.Sprite.Cnds.OnAnyAnimFinished, C3.Plugins.Touch.Cnds.OnTouchObject, C3.Plugins.Sprite.Cnds.IsBoolInstanceVarSet, C3.Plugins.System.Cnds.LayerVisible, C3.Plugins.Sprite.Acts.SetPosToObject, C3.Plugins.Sprite.Acts.StartAnim, C3.Plugins.Audio.Acts.PlayByName, C3.Plugins.System.Exps.choose, C3.Plugins.Mouse.Cnds.IsOverObject, C3.Plugins.Touch.Cnds.OnTapGestureObject, C3.Behaviors.aekiro_radiobutton.Cnds.OnClicked, C3.Behaviors.aekiro_gameobject.Cnds.IsName, C3.Plugins.Json.Exps.ArraySize, C3.Plugins.System.Cnds.PickAll, C3.Plugins.Sprite.Acts.SetEffectParam, C3.ScriptsInEvents.Egame_Event65_Act1, C3.Plugins.System.Acts.SetFunctionReturnValue, C3.Plugins.System.Exps.len, C3.ScriptsInEvents.Egame_Event67_Act3, C3.Plugins.System.Cnds.Repeat, C3.Plugins.System.Exps.left, C3.Plugins.System.Exps.right, C3.Plugins.Arr.Cnds.CompareXY, C3.Plugins.Arr.Acts.SetXY, C3.Plugins.Sprite.Cnds.PickByUID, C3.Plugins.Spritefont2.Acts.AppendText, C3.Plugins.NinePatch.Acts.SetSize, C3.Plugins.Spritefont2.Exps.TextWidth, C3.Plugins.Spritefont2.Exps.TextHeight, C3.Plugins.NinePatch.Acts.SetPosToObject, C3.Plugins.NinePatch.Acts.SetY, C3.Plugins.NinePatch.Exps.Y, C3.Plugins.NinePatch.Exps.Height, C3.Plugins.System.Exps.viewportheight, C3.Plugins.Spritefont2.Acts.SetPos, C3.Plugins.NinePatch.Exps.X, C3.Plugins.Sprite.Exps.AnimationFrame, C3.Plugins.NinePatch.Acts.MoveToTop, C3.Plugins.System.Cnds.CompareBoolVar, C3.Behaviors.Timer.Acts.StopTimer, C3.Behaviors.Timer.Acts.StartTimer, C3.Plugins.Spritefont2.Acts.SetY, C3.Plugins.Json.Acts.PushValue, C3.Plugins.Json.Acts.SetJSON, C3.Plugins.Json.Exps.GetAsCompactString, C3.Behaviors.aekiro_gridView.Acts.SetDataByJsonObject, C3.Plugins.System.Cnds.ForEach, C3.Plugins.NinePatch.Cnds.CompareInstanceVar, C3.Behaviors.aekiro_gameobject.Cnds.IsParentName, C3.Behaviors.aekiro_gameobject.Exps.parent, C3.Plugins.Sprite.Acts.SetVisible, C3.Plugins.Sprite.Cnds.IsVisible, C3.Plugins.Sprite.Cnds.CompareInstanceVar, C3.Plugins.Sprite.Acts.SetDefaultColor, C3.Behaviors.aekiro_button.Acts.setNormalColor, C3.Plugins.System.Exps.rgbex255, C3.ScriptsInEvents.Egame_Event193_Act1, C3.Plugins.Spritefont2.Acts.SetX, C3.Plugins.Sprite.Acts.SetX, C3.Plugins.Sprite.Exps.LayerName, C3.Behaviors.mcube_rexspline.Acts.AddPoint, C3.Behaviors.mcube_rexspline.Acts.Start, C3.Plugins.Arr.Cnds.ArrForEach, C3.Plugins.Arr.Cnds.CompareCurrent, C3.Plugins.Arr.Exps.CurX, C3.Plugins.System.Acts.WaitForPreviousActions, C3.Plugins.Json.Cnds.ForEach, C3.Plugins.Arr.Cnds.CompareX, C3.Plugins.Json.Exps.CurrentKey, C3.Behaviors.aekiro_gridviewbind.Cnds.OnGridViewRender, C3.Behaviors.aekiro_gridviewbind.Exps.get, C3.Behaviors.aekiro_button.Cnds.OnMouseEnter, C3.Plugins.Sprite.Exps.UID, C3.Behaviors.aekiro_button.Cnds.OnMouseLeave, C3.Plugins.Sprite.Acts.SubInstanceVar, C3.Plugins.Sprite.Acts.SetBoolInstanceVar, C3.Plugins.System.Cnds.CompareVar, C3.Plugins.Sprite.Exps.X, C3.Plugins.Sprite.Exps.Y, C3.Plugins.LocalStorage.Acts.SetItem, C3.Plugins.Massive_Cube_Forge.Exps.encodeb64, C3.Plugins.Arr.Exps.AsJSON, C3.Plugins.Sprite.Cnds.PickInstVarHiLow, C3.Behaviors.Pin.Acts.PinByProperties, C3.Plugins.Arr.Exps.Width, C3.Plugins.System.Acts.CallMappedFunction, C3.Behaviors.aekiro_button.Cnds.OnClicked, C3.Plugins.Sprite.Acts.SetY, C3.Plugins.Sprite.Acts.AddInstanceVar, C3.Plugins.NinePatch.Exps.Width, C3.Behaviors.aekiro_scrollView.Acts.ScrollBy, C3.Plugins.NinePatch.Acts.SetInstanceVar, C3.Plugins.System.Exps.callmapped, C3.Behaviors.aekiro_gridView.Cnds.OnRender, C3.Plugins.Arr.Acts.Clear, C3.Plugins.Spritefont2.Acts.SetScale, C3.Plugins.AJAX.Cnds.OnComplete, C3.Plugins.AJAX.Exps.LastData, C3.Plugins.Sprite.Cnds.IsOverlapping, C3.Behaviors.MoveTo.Cnds.IsMoving, C3.Plugins.System.Cnds.CompareBetween, C3.Behaviors.aekiro_checkbox.Cnds.OnClicked, C3.Behaviors.aekiro_checkbox.Cnds.IsChecked, C3.Plugins.Audio.Cnds.IsTagPlaying, C3.Plugins.Audio.Acts.SetPaused, C3.Behaviors.aekiro_dialog.Acts.Open, C3.Behaviors.aekiro_dialog.Acts.Close, C3.Behaviors.Fade.Acts.RestartFade, C3.Plugins.System.Acts.ResetGlobals, C3.Plugins.System.Acts.RestartLayout, C3.Plugins.TextBox.Cnds.CompareText, C3.Plugins.Massive_Cube_Forge.Exps.decodeb64, C3.Plugins.TextBox.Exps.Text, C3.Plugins.LocalStorage.Acts.GetItem, C3.Plugins.System.Cnds.Every, C3.Plugins.LocalStorage.Cnds.OnItemGet, C3.Plugins.Sparsha_copyclip.Acts.ApiCopy, C3.Plugins.LocalStorage.Exps.ItemValue, C3.Behaviors.aekiro_dialog.Cnds.onDialogOpened, C3.Plugins.CBhash.Cnds.OnHashed, C3.Plugins.Browser.Exps.Domain, C3.Plugins.Massive_Cube_Forge.Exps.MD5, C3.Plugins.LocalStorage.Acts.CheckItemExists, C3.Plugins.Browser.Acts.GoToURL, C3.Plugins.LocalStorage.Cnds.OnItemMissing, C3.ScriptsInEvents.Eloading_Event5_Act1, C3.Plugins.System.Acts.GoToLayout, C3.Plugins.LocalStorage.Cnds.OnItemExists, C3.Plugins.Arr.Acts.JSONLoad, C3.ScriptsInEvents.Eloaddata_Event3_Act19];
|
|
}
|
|
;
|
|
self.C3_JsPropNameTable = [{
|
|
Monster_Name_Sf: 0
|
|
}, {
|
|
HP_Monster: 0
|
|
}, {
|
|
MapName_Sf: 0
|
|
}, {
|
|
RequireMonster_Sf: 0
|
|
}, {
|
|
GameObject: 0
|
|
}, {
|
|
CoinShop_sf: 0
|
|
}, {
|
|
CoinTotal_sf: 0
|
|
}, {
|
|
DPS_sf: 0
|
|
}, {
|
|
General_Sf: 0
|
|
}, {
|
|
MoveTo: 0
|
|
}, {
|
|
Fade: 0
|
|
}, {
|
|
GoldDrop_Sf: 0
|
|
}, {
|
|
GridViewDataBind: 0
|
|
}, {
|
|
HIRE_Sf: 0
|
|
}, {
|
|
TimeBoss_Sf: 0
|
|
}, {
|
|
Pin: 0
|
|
}, {
|
|
HeroDescriptionDialog_sf: 0
|
|
}, {
|
|
HeroLevel_sf: 0
|
|
}, {
|
|
CoinTop_img: 0
|
|
}, {
|
|
music: 0
|
|
}, {
|
|
NextMap_Btn: 0
|
|
}, {
|
|
Setting_Icon: 0
|
|
}, {
|
|
Skull_Icon: 0
|
|
}, {
|
|
Sound_Icon: 0
|
|
}, {
|
|
pos: 0
|
|
}, {
|
|
posJSON: 0
|
|
}, {
|
|
idHero: 0
|
|
}, {
|
|
Bought: 0
|
|
}, {
|
|
requireLevel: 0
|
|
}, {
|
|
cost: 0
|
|
}, {
|
|
requireSkillUpdate: 0
|
|
}, {
|
|
description: 0
|
|
}, {
|
|
idSkill: 0
|
|
}, {
|
|
upgradeFunction: 0
|
|
}, {
|
|
nameSkill: 0
|
|
}, {
|
|
paramUpgrade: 0
|
|
}, {
|
|
Button: 0
|
|
}, {
|
|
Upgrade_Icon: 0
|
|
}, {
|
|
Achivement_Icon: 0
|
|
}, {
|
|
BorderLeft_Btn: 0
|
|
}, {
|
|
Checkbox: 0
|
|
}, {
|
|
CheckBoxSound_Btn: 0
|
|
}, {
|
|
RadioButton: 0
|
|
}, {
|
|
Tab_Btn: 0
|
|
}, {
|
|
bgMap: 0
|
|
}, {
|
|
BorderGamePad: 0
|
|
}, {
|
|
BorderGamePad2: 0
|
|
}, {
|
|
borderHudTop: 0
|
|
}, {
|
|
level: 0
|
|
}, {
|
|
id: 0
|
|
}, {
|
|
baseDPS: 0
|
|
}, {
|
|
baseClick: 0
|
|
}, {
|
|
baseCost: 0
|
|
}, {
|
|
costFormula: 0
|
|
}, {
|
|
hero: 0
|
|
}, {
|
|
HeroName_sf: 0
|
|
}, {
|
|
currentCost: 0
|
|
}, {
|
|
idHeroJSON: 0
|
|
}, {
|
|
BuyHero_Btn: 0
|
|
}, {
|
|
BgCharacter: 0
|
|
}, {
|
|
Array_Hero: 0
|
|
}, {
|
|
Array_SkillUpgrade: 0
|
|
}, {
|
|
Array_UI_Upgrade: 0
|
|
}, {
|
|
AJAX: 0
|
|
}, {
|
|
JSON: 0
|
|
}, {
|
|
JSON_All: 0
|
|
}, {
|
|
JSON_HeroShop: 0
|
|
}, {
|
|
JSON_Achievement: 0
|
|
}, {
|
|
Array_DataSave: 0
|
|
}, {
|
|
dead: 0
|
|
}, {
|
|
killed: 0
|
|
}, {
|
|
Boss: 0
|
|
}, {
|
|
monster1: 0
|
|
}, {
|
|
monster10: 0
|
|
}, {
|
|
monster11: 0
|
|
}, {
|
|
monster12: 0
|
|
}, {
|
|
monster13: 0
|
|
}, {
|
|
monster14: 0
|
|
}, {
|
|
monster15: 0
|
|
}, {
|
|
monster16: 0
|
|
}, {
|
|
monster17: 0
|
|
}, {
|
|
monster18: 0
|
|
}, {
|
|
monster19: 0
|
|
}, {
|
|
monster2: 0
|
|
}, {
|
|
monster20: 0
|
|
}, {
|
|
monster21: 0
|
|
}, {
|
|
monster22: 0
|
|
}, {
|
|
monster23: 0
|
|
}, {
|
|
monster24: 0
|
|
}, {
|
|
monster25: 0
|
|
}, {
|
|
monster26: 0
|
|
}, {
|
|
monster27: 0
|
|
}, {
|
|
monster28: 0
|
|
}, {
|
|
monster29: 0
|
|
}, {
|
|
monster3: 0
|
|
}, {
|
|
monster30: 0
|
|
}, {
|
|
monster31: 0
|
|
}, {
|
|
monster32: 0
|
|
}, {
|
|
monster33: 0
|
|
}, {
|
|
monster34: 0
|
|
}, {
|
|
monster35: 0
|
|
}, {
|
|
monster36: 0
|
|
}, {
|
|
monster37: 0
|
|
}, {
|
|
monster38: 0
|
|
}, {
|
|
monster39: 0
|
|
}, {
|
|
monster4: 0
|
|
}, {
|
|
monster40: 0
|
|
}, {
|
|
monster41: 0
|
|
}, {
|
|
monster42: 0
|
|
}, {
|
|
monster43: 0
|
|
}, {
|
|
monster44: 0
|
|
}, {
|
|
monster45: 0
|
|
}, {
|
|
monster46: 0
|
|
}, {
|
|
monster47: 0
|
|
}, {
|
|
monster48: 0
|
|
}, {
|
|
monster49: 0
|
|
}, {
|
|
monster5: 0
|
|
}, {
|
|
monster50: 0
|
|
}, {
|
|
monster51: 0
|
|
}, {
|
|
monster52: 0
|
|
}, {
|
|
monster53: 0
|
|
}, {
|
|
monster54: 0
|
|
}, {
|
|
monster55: 0
|
|
}, {
|
|
monster56: 0
|
|
}, {
|
|
monster57: 0
|
|
}, {
|
|
monster58: 0
|
|
}, {
|
|
monster59: 0
|
|
}, {
|
|
monster6: 0
|
|
}, {
|
|
monster60: 0
|
|
}, {
|
|
monster61: 0
|
|
}, {
|
|
monster62: 0
|
|
}, {
|
|
monster63: 0
|
|
}, {
|
|
monster64: 0
|
|
}, {
|
|
monster65: 0
|
|
}, {
|
|
monster66: 0
|
|
}, {
|
|
monster67: 0
|
|
}, {
|
|
monster68: 0
|
|
}, {
|
|
monster69: 0
|
|
}, {
|
|
monster7: 0
|
|
}, {
|
|
monster70: 0
|
|
}, {
|
|
monster71: 0
|
|
}, {
|
|
monster72: 0
|
|
}, {
|
|
monster73: 0
|
|
}, {
|
|
monster74: 0
|
|
}, {
|
|
monster75: 0
|
|
}, {
|
|
monster76: 0
|
|
}, {
|
|
monster77: 0
|
|
}, {
|
|
monster78: 0
|
|
}, {
|
|
monster79: 0
|
|
}, {
|
|
monster8: 0
|
|
}, {
|
|
monster80: 0
|
|
}, {
|
|
monster81: 0
|
|
}, {
|
|
monster82: 0
|
|
}, {
|
|
monster83: 0
|
|
}, {
|
|
monster84: 0
|
|
}, {
|
|
monster85: 0
|
|
}, {
|
|
monster9: 0
|
|
}, {
|
|
template: 0
|
|
}, {
|
|
ProUI: 0
|
|
}, {
|
|
up: 0
|
|
}, {
|
|
Up_Scroll: 0
|
|
}, {
|
|
Bar_Scroll: 0
|
|
}, {
|
|
Bar_Btn: 0
|
|
}, {
|
|
TopHP_monster: 0
|
|
}, {
|
|
borderHP: 0
|
|
}, {
|
|
curValue: 0
|
|
}, {
|
|
maxHP: 0
|
|
}, {
|
|
isBoss: 0
|
|
}, {
|
|
Gold: 0
|
|
}, {
|
|
baseSize: 0
|
|
}, {
|
|
dieSound: 0
|
|
}, {
|
|
Progress: 0
|
|
}, {
|
|
barGreen: 0
|
|
}, {
|
|
UpLevel_Eff: 0
|
|
}, {
|
|
Critical_Click: 0
|
|
}, {
|
|
coinValue: 0
|
|
}, {
|
|
Spline: 0
|
|
}, {
|
|
Timer: 0
|
|
}, {
|
|
CoinDrop: 0
|
|
}, {
|
|
Mapmini_Bg: 0
|
|
}, {
|
|
MapBorder_btn: 0
|
|
}, {
|
|
levelMap: 0
|
|
}, {
|
|
MapLv_Btn: 0
|
|
}, {
|
|
MapLevel_Sf: 0
|
|
}, {
|
|
Prevent: 0
|
|
}, {
|
|
Touch: 0
|
|
}, {
|
|
Mouse: 0
|
|
}, {
|
|
Keyboard: 0
|
|
}, {
|
|
Browser: 0
|
|
}, {
|
|
RadioGroup: 0
|
|
}, {
|
|
MapBtn_RadioGroup: 0
|
|
}, {
|
|
ClickDmg_sf: 0
|
|
}, {
|
|
DmgFly_Sf: 0
|
|
}, {
|
|
CoinShop_img: 0
|
|
}, {
|
|
TabBtn_RadioGroup: 0
|
|
}, {
|
|
GridView: 0
|
|
}, {
|
|
GridViewachivement: 0
|
|
}, {
|
|
ScrollView: 0
|
|
}, {
|
|
GridViewShop: 0
|
|
}, {
|
|
Check_Icon: 0
|
|
}, {
|
|
NewMap_Icon: 0
|
|
}, {
|
|
ToolTip: 0
|
|
}, {
|
|
DialogHero: 0
|
|
}, {
|
|
GridViewMap: 0
|
|
}, {
|
|
FadeBuyBtn: 0
|
|
}, {
|
|
DragDrop: 0
|
|
}, {
|
|
TestWidth: 0
|
|
}, {
|
|
DialogSkill: 0
|
|
}, {
|
|
SkillDescriptionDialog_sf: 0
|
|
}, {
|
|
Clock_Icon: 0
|
|
}, {
|
|
JSON2: 0
|
|
}, {
|
|
MapBtnPanel: 0
|
|
}, {
|
|
DrawingCanvas: 0
|
|
}, {
|
|
Flash: 0
|
|
}, {
|
|
CompleteArea_sf: 0
|
|
}, {
|
|
SkillUpgrade_sf: 0
|
|
}, {
|
|
Audio: 0
|
|
}, {
|
|
EnterMap_Sf: 0
|
|
}, {
|
|
Achivement_sf: 0
|
|
}, {
|
|
Array_Achievement: 0
|
|
}, {
|
|
BgAchivement: 0
|
|
}, {
|
|
DialogAchievement: 0
|
|
}, {
|
|
AchievementDecription_sf: 0
|
|
}, {
|
|
Array_Map_Pos: 0
|
|
}, {
|
|
LocalStorage: 0
|
|
}, {
|
|
CBHash: 0
|
|
}, {
|
|
Setting_Btn: 0
|
|
}, {
|
|
Dialog: 0
|
|
}, {
|
|
Setting_Dialog: 0
|
|
}, {
|
|
CloseIcon: 0
|
|
}, {
|
|
GameSettingBottomtxt: 0
|
|
}, {
|
|
Copyclip: 0
|
|
}, {
|
|
Forge: 0
|
|
}, {
|
|
InputImport: 0
|
|
}, {
|
|
TestSprite: 0
|
|
}, {
|
|
MapBG: 0
|
|
}, {
|
|
Monster_fml: 0
|
|
}, {
|
|
Btn_fml: 0
|
|
}, {
|
|
MapBtn_fml: 0
|
|
}, {
|
|
Family1: 0
|
|
}, {
|
|
MapMember: 0
|
|
}, {
|
|
monsterKilledInMap: 0
|
|
}, {
|
|
requireMonster: 0
|
|
}, {
|
|
st1: 0
|
|
}, {
|
|
urlHome: 0
|
|
}, {
|
|
posMonster: 0
|
|
}, {
|
|
spacingMapBtn: 0
|
|
}, {
|
|
widthCoinTop: 0
|
|
}, {
|
|
posCoinTotal: 0
|
|
}, {
|
|
posDialogHeroX: 0
|
|
}, {
|
|
posCenterMapBtn: 0
|
|
}, {
|
|
posBtnMap: 0
|
|
}, {
|
|
posBtnBuyHero: 0
|
|
}, {
|
|
maxIdMonster: 0
|
|
}, {
|
|
clickPerSecond: 0
|
|
}, {
|
|
timeBoss: 0
|
|
}, {
|
|
currentDPS: 0
|
|
}, {
|
|
hasNewLevel: 0
|
|
}, {
|
|
stringMonster: 0
|
|
}, {
|
|
bossId: 0
|
|
}, {
|
|
widthCoinShopHero: 0
|
|
}, {
|
|
coinImgWidth: 0
|
|
}, {
|
|
COIN_DISSAPEAR: 0
|
|
}, {
|
|
currentMap: 0
|
|
}, {
|
|
soundOn: 0
|
|
}, {
|
|
soundEffect: 0
|
|
}, {
|
|
clickDamage: 0
|
|
}, {
|
|
clickMultiplier: 0
|
|
}, {
|
|
allDpsMultiplier: 0
|
|
}, {
|
|
goldMultiplier: 0
|
|
}, {
|
|
abaddonMultiplier: 0
|
|
}, {
|
|
clickDpsPercent: 0
|
|
}, {
|
|
reachedMap: 0
|
|
}, {
|
|
totalClick: 0
|
|
}, {
|
|
currentCoin: 0
|
|
}, {
|
|
totalGoldReceive: 0
|
|
}, {
|
|
CurrentHero: 0
|
|
}, {
|
|
totalKills: 0
|
|
}, {
|
|
totalBossKills: 0
|
|
}, {
|
|
totalUpgrades: 0
|
|
}, {
|
|
totalHeroLevels: 0
|
|
}, {
|
|
mostClicksPerSecond: 0
|
|
}, {
|
|
idMonster: 0
|
|
}, {
|
|
hpMonster: 0
|
|
}, {
|
|
levelMonster: 0
|
|
}, {
|
|
baseLife: 0
|
|
}, {
|
|
lengthNumber: 0
|
|
}, {
|
|
offsetNumber: 0
|
|
}, {
|
|
remainNumber: 0
|
|
}, {
|
|
returnString: 0
|
|
}, {
|
|
startString: 0
|
|
}, {
|
|
numberFormat: 0
|
|
}, {
|
|
lengthLimit: 0
|
|
}, {
|
|
numberCoin: 0
|
|
}, {
|
|
returnCost: 0
|
|
}, {
|
|
factorMultiply: 0
|
|
}, {
|
|
valueIncrease: 0
|
|
}, {
|
|
param: 0
|
|
}, {
|
|
baseAttack: 0
|
|
}, {
|
|
NameHero: 0
|
|
}, {
|
|
NameSkill2: 0
|
|
}, {
|
|
Description: 0
|
|
}, {
|
|
price: 0
|
|
}, {
|
|
requireSkill: 0
|
|
}, {
|
|
uidSkillIcon: 0
|
|
}, {
|
|
PosY: 0
|
|
}, {
|
|
NameAchieve: 0
|
|
}, {
|
|
uidAchiIcon: 0
|
|
}, {
|
|
currentLevel: 0
|
|
}, {
|
|
baseDps: 0
|
|
}, {
|
|
idHeroJS: 0
|
|
}, {
|
|
shouldShow: 0
|
|
}, {
|
|
stringCoin: 0
|
|
}, {
|
|
direction: 0
|
|
}, {
|
|
distanceMove: 0
|
|
}, {
|
|
dmg: 0
|
|
}, {
|
|
Parameter0: 0
|
|
}, {
|
|
Parameter1: 0
|
|
}, {
|
|
Parameter2: 0
|
|
}, {
|
|
func: 0
|
|
}, {
|
|
mapOneZone: 0
|
|
}, {
|
|
directionCoin: 0
|
|
}, {
|
|
spacing: 0
|
|
}, {
|
|
newMap: 0
|
|
}, {
|
|
tempDPS: 0
|
|
}, {
|
|
FunctionCall: 0
|
|
}, {
|
|
mapFunction: 0
|
|
}, {
|
|
WidthTotal: 0
|
|
}, {
|
|
idUpgrade: 0
|
|
}, {
|
|
testValueNumpad: 0
|
|
}, {
|
|
testValue3: 0
|
|
}, {
|
|
testValueUp: 0
|
|
}, {
|
|
st2: 0
|
|
}, {
|
|
stringDomain: 0
|
|
}, {
|
|
st3: 0
|
|
}, {
|
|
stringData: 0
|
|
}];
|
|
}
|
|
"use strict";
|
|
{
|
|
const C3 = self.C3;
|
|
function unaryminus(n) {
|
|
return (typeof n === "number" ? -n : n);
|
|
}
|
|
function bothNumbers(a, b) {
|
|
return typeof a === "number" && typeof b === "number";
|
|
}
|
|
function add(l, r) {
|
|
if (bothNumbers(l, r))
|
|
return l + r;
|
|
else
|
|
return l;
|
|
}
|
|
function subtract(l, r) {
|
|
if (bothNumbers(l, r))
|
|
return l - r;
|
|
else
|
|
return l;
|
|
}
|
|
function multiply(l, r) {
|
|
if (bothNumbers(l, r))
|
|
return l * r;
|
|
else
|
|
return l;
|
|
}
|
|
function divide(l, r) {
|
|
if (bothNumbers(l, r))
|
|
return l / r;
|
|
else
|
|
return l;
|
|
}
|
|
function mod(l, r) {
|
|
if (bothNumbers(l, r))
|
|
return l % r;
|
|
else
|
|
return l;
|
|
}
|
|
function pow(l, r) {
|
|
if (bothNumbers(l, r))
|
|
return Math.pow(l, r);
|
|
else
|
|
return l;
|
|
}
|
|
function and(l, r) {
|
|
if (typeof l === "string" || typeof r === "string") {
|
|
let lstr, rstr;
|
|
if (typeof l === "number")
|
|
lstr = (Math.round(l * 1e10) / 1e10).toString();
|
|
else
|
|
lstr = l;
|
|
if (typeof r === "number")
|
|
rstr = (Math.round(r * 1e10) / 1e10).toString();
|
|
else
|
|
rstr = r;
|
|
return lstr + rstr;
|
|
} else {
|
|
return (l && r ? 1 : 0);
|
|
}
|
|
}
|
|
function or(l, r) {
|
|
if (bothNumbers(l, r))
|
|
return (l || r ? 1 : 0);
|
|
else
|
|
return l;
|
|
}
|
|
self.C3_ExpressionFuncs = [()=>1, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>(f0(Math.floor((f1() * v2.GetValue()))) + " Click Damage");
|
|
}
|
|
, ()=>0, ()=>"870, 384", ()=>2, ()=>"872, 378", ()=>3, ()=>"855, 375", ()=>4, ()=>"857, 381", ()=>5, ()=>"876, 378", ()=>6, ()=>"893, 417", ()=>7, ()=>"898, 410", ()=>8, ()=>"898, 412", ()=>9, ()=>"895, 415", ()=>10, ()=>11, ()=>"820, 358", ()=>12, ()=>13, ()=>"823, 362", ()=>14, ()=>15, ()=>16, ()=>"849, 574", ()=>17, ()=>"854, 565", ()=>18, ()=>19, ()=>20, ()=>21, ()=>"850, 473", ()=>22, ()=>23, ()=>24, ()=>25, ()=>26, ()=>"868, 332", ()=>27, ()=>28, ()=>"863, 327", ()=>29, ()=>30, ()=>31, ()=>"853, 456", ()=>32, ()=>"860, 457", ()=>33, ()=>34, ()=>35, ()=>36, ()=>"847, 395", ()=>37, ()=>38, ()=>39, ()=>40, ()=>41, ()=>"857, 385", ()=>42, ()=>43, ()=>44, ()=>45, ()=>"[]", ()=>"data", ()=>"", ()=>"heroCostFormula1", ()=>"skill", ()=>"upgradeClickPercent", ()=>"upgradeHeroPercent", ()=>"upgradeEveryonePercent", ()=>"upgradeGoldFoundPercent", ()=>"upgradeAbaddon", ()=>"Import", p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
return ()=>f0(0, 0, 0, 0);
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>v0.GetValue();
|
|
}
|
|
, ()=>"bg", ()=>"RequireMonster", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>and(and(v0.GetValue(), "/"), v1.GetValue());
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
return ()=>f0();
|
|
}
|
|
, ()=>"HUD", p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
const v3 = p._GetNode(3).GetVar();
|
|
const f4 = p._GetNode(4).GetBoundMethod();
|
|
const n5 = p._GetNode(5);
|
|
const v6 = p._GetNode(6).GetVar();
|
|
return ()=>(f0(f1(v2.GetValue(), 0, ",")) - ((v3.GetValue() - f4()) * (n5.ExpObject() + v6.GetValue())));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>f0(f1(v2.GetValue(), 1, ","));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(((v0.GetValue() - 1) % 45) + 1);
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const n2 = p._GetNode(2);
|
|
const v3 = p._GetNode(3).GetVar();
|
|
return ()=>f0(f1(n2.ExpObject((((v3.GetValue() - 1) % 45) + 1)), 0, ","));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const n2 = p._GetNode(2);
|
|
const v3 = p._GetNode(3).GetVar();
|
|
return ()=>f0(f1(n2.ExpObject((((v3.GetValue() - 1) % 45) + 1)), 1, ","));
|
|
}
|
|
, ()=>"ANIMATION_HANDLE", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() % 5);
|
|
}
|
|
, ()=>"TimerBoss", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>and(v0.GetValue(), " sec");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const f2 = p._GetNode(2).GetBoundMethod();
|
|
const f3 = p._GetNode(3).GetBoundMethod();
|
|
const v4 = p._GetNode(4).GetVar();
|
|
return ()=>f0(v1.GetValue(), Math.floor(f2(f3(v4.GetValue(), ","))), ",");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const f2 = p._GetNode(2).GetBoundMethod();
|
|
const v3 = p._GetNode(3).GetVar();
|
|
const v4 = p._GetNode(4).GetVar();
|
|
return ()=>((((v0.GetValue()) > (v1.GetValue()) ? 1 : 0)) ? (Math.floor(f2(v3.GetValue()))) : (v4.GetValue()));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>((((v0.GetValue()) === (1) ? 1 : 0)) ? (v1.GetValue()) : (v2.GetValue()));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>n0.ExpObject((and("monsters.", v1.GetValue()) + ".baseLife"));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>((((v0.GetValue()) <= (0) ? 1 : 0)) ? (10) : (v1.GetValue()));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>and("monster", v0.GetValue());
|
|
}
|
|
, ()=>"Game", p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>f0(f1(v2.GetValue(), 0, ","));
|
|
}
|
|
, ()=>100, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>n0.ExpObject((and("monsters.", v1.GetValue()) + ".baseSize"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>n0.ExpObject((and("monsters.", v1.GetValue()) + ".dieSoundId"));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>Math.ceil(((v0.GetValue() / 15) * v1.GetValue()));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const n2 = p._GetNode(2);
|
|
return ()=>((((n0.ExpInstVar()) === (0) ? 1 : 0)) ? ("Dead") : ((f1(Math.floor(n2.ExpInstVar())) + " HP")));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>and(and(n0.ExpObject((and("monsters.", v1.GetValue()) + ".name")), ", Lvl "), v2.GetValue());
|
|
}
|
|
, ()=>"dmg", ()=>"idle", ()=>"died", ()=>"Drop", ()=>"Effect", p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(and("+ ", Math.floor(n0.ExpInstVar())) + " Gold");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject();
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(n0.ExpObject() - 50);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpInstVar();
|
|
}
|
|
, ()=>"gold", ()=>"totalGold", ()=>"effect", ()=>"TOUCH_CTRL", ()=>"Setting", p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>Math.floor((f0() * v1.GetValue()));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>(f0() * v1.GetValue());
|
|
}
|
|
, ()=>"totalClicks", p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
return ()=>and("hit", f0(1, 2, 3));
|
|
}
|
|
, ()=>"TAB_HANDLE", ()=>"TabAchivements", ()=>"AchivementTab", ()=>"HeroTab", ()=>"BarScroll", ()=>"SubHeroTab", p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject("");
|
|
}
|
|
, ()=>"HEALTH_BAR", ()=>"AdjustHSL", p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>((n0.ExpObject() / 139) * 30);
|
|
}
|
|
, ()=>"FUNCTION", ()=>"FORMAT", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>Math.floor(v0.GetValue());
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>f0((v1.GetValue()).toString());
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>Math.floor((v0.GetValue() / 3));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>f0(v1.GetValue(), (v2.GetValue() % 3));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
const v3 = p._GetNode(3).GetVar();
|
|
return ()=>f0(v1.GetValue(), (v2.GetValue() - (v3.GetValue() % 3)));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>f0(v1.GetValue());
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>((v0.GetValue() + ",") + f1(v2.GetValue(), 3));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>f0(v1.GetValue(), (v2.GetValue() - 3));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + "K");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + "M");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + "B");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + "T");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + "q");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + "Q");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + "s");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + "S");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(Math.floor(((v0.GetValue() - 1) / 3)) + 1);
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
const v3 = p._GetNode(3).GetVar();
|
|
return ()=>f0(v1.GetValue(), (((((v2.GetValue() % 3)) === (0) ? 1 : 0)) ? (3) : ((v3.GetValue() % 3))));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
const v3 = p._GetNode(3).GetVar();
|
|
const v4 = p._GetNode(4).GetVar();
|
|
return ()=>f0(v1.GetValue(), (((((v2.GetValue() - (v3.GetValue() % 3))) === (0) ? 1 : 0)) ? (3) : ((v4.GetValue() % 3))));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue()).toString();
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
const v3 = p._GetNode(3).GetVar();
|
|
const v4 = p._GetNode(4).GetVar();
|
|
return ()=>(f0(v1.GetValue(), ((((v2.GetValue()) < (3) ? 1 : 0)) ? (v3.GetValue()) : (3))) + v4.GetValue());
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
const v3 = p._GetNode(3).GetVar();
|
|
const v4 = p._GetNode(4).GetVar();
|
|
return ()=>((f0(v1.GetValue(), ((((v2.GetValue()) < (3) ? 1 : 0)) ? (v3.GetValue()) : (3))) + ",") + v4.GetValue());
|
|
}
|
|
, ()=>"FORMULAR", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
const v3 = p._GetNode(3).GetVar();
|
|
return ()=>Math.floor(((v0.GetValue() + v1.GetValue()) * Math.pow(v2.GetValue(), v3.GetValue())));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>Math.floor((20 * Math.pow(v0.GetValue(), v1.GetValue())));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>Math.floor((v0.GetValue() * Math.pow(v1.GetValue(), v2.GetValue())));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>(v0.GetValue() * (1 + (v1.GetValue() / 100)));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>f0(v1.GetValue(), 0, ",");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>f0(v1.GetValue(), 1, ",");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const n2 = p._GetNode(2);
|
|
const v3 = p._GetNode(3).GetVar();
|
|
return ()=>((((n0.ExpObject(v1.GetValue(), 2)) <= (0) ? 1 : 0)) ? (1) : (n2.ExpObject(v3.GetValue(), 2)));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const n2 = p._GetNode(2);
|
|
const v3 = p._GetNode(3).GetVar();
|
|
const v4 = p._GetNode(4).GetVar();
|
|
return ()=>add(n0.ExpObject(v1.GetValue(), 2), multiply(n2.ExpObject(v3.GetValue(), 2), (v4.GetValue() / 100)));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>(v0.GetValue() * v1.GetValue());
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
const v3 = p._GetNode(3).GetVar();
|
|
return ()=>(Math.floor((v0.GetValue() + v1.GetValue())) * Math.pow(v2.GetValue(), v3.GetValue()));
|
|
}
|
|
, ()=>"DIALOG", p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>n0.ExpObject((and("heroes.", n1.ExpInstVar()) + ".name"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(("[scale=0.5]" + n0.ExpInstVar()) + "[/scale]");
|
|
}
|
|
, ()=>"\n", p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const n1 = p._GetNode(1);
|
|
return ()=>(("[color=#FFFB59 ] Cost " + f0(n1.ExpInstVar())) + " Gold[/color]");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const n1 = p._GetNode(1);
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>f0(n1.ExpObject((and("heroes.", v2.GetValue()) + ".baseClickDamage")));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>n0.ExpObject((and("heroes.", v1.GetValue()) + ".description"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>n0.ExpObject(n1.ExpInstVar());
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const n1 = p._GetNode(1);
|
|
const n2 = p._GetNode(2);
|
|
return ()=>(and((("[color=#F42D20] Requires " + v0.GetValue()) + "'s upgrade: "), n1.ExpObject((and("upgrades.", n2.ExpInstVar()) + ".name"))) + "[/color]");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(and("[color=#F42D20] Requires hero level: ", n0.ExpInstVar()) + "[/color]");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const n1 = p._GetNode(1);
|
|
return ()=>(((("Increases [color=#33F178] " + v0.GetValue()) + "[/color]'s Click Damage by [color=#33F178] ") + n1.ExpInstVar()) + "[/color] %.");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const n2 = p._GetNode(2);
|
|
return ()=>(((("Increases [color=#33F178] " + v0.GetValue()) + "[/color]'s DPS by [color=#33F178]") + f1(n2.ExpInstVar(), 1, ",")) + "[/color] %.");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(("[color=#999999]" + n0.ExpInstVar()) + "[/color]");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(n0.ExpObject() + 20);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
const f2 = p._GetNode(2).GetBoundMethod();
|
|
const f3 = p._GetNode(3).GetBoundMethod();
|
|
const n4 = p._GetNode(4);
|
|
const n5 = p._GetNode(5);
|
|
return ()=>(((((n0.ExpObject() + n1.ExpObject())) > (f2(0)) ? 1 : 0)) ? ((f3(0) - n4.ExpObject())) : (n5.ExpObject()));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(n0.ExpObject() + 10);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>n0.ExpObject((and("achievements.", n1.ExpObject()) + ".name"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>n0.ExpObject((and("achievements.", n1.ExpObject()) + ".description"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>n0.ExpObject((and("achievements.", n1.ExpObject()) + ".checkParams"));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(("[scale=0.5]" + v0.GetValue()) + "[/scale]");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
const f3 = p._GetNode(3).GetBoundMethod();
|
|
const v4 = p._GetNode(4).GetVar();
|
|
return ()=>((f0(v1.GetValue(), 0, "%1") + v2.GetValue()) + f3(v4.GetValue(), 1, "%1"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(n0.ExpObject() + 50);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>n0.ExpObject((and("heroes.", v1.GetValue()) + ".name"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>n0.ExpObject(v1.GetValue());
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const n1 = p._GetNode(1);
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>f0(n1.ExpObject((and("heroes.", v2.GetValue()) + ".baseAttack")));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(and("[color=#00ff00]Click Damage: ", (v0.GetValue() + 1)) + "[/color]");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>and("Current Level:\n Click Damage: ", ((v0.GetValue() * v1.GetValue()) + 1));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>(and("[color=#00ff00]Next Level:[/color]\n[color=#00ff00] Click Damage: ", ((v0.GetValue() * (v1.GetValue() + 1)) + 1)) + "[/color]");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>(("[color=#00ff00]DPS: " + f0(Math.floor(v1.GetValue()))) + "[/color]");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>("Current Level:\n DPS: " + f0(Math.floor((v1.GetValue() * v2.GetValue()))));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>(("[color=#00ff00]Next Level:[/color]\n[color=#00ff00] DPS: " + f0(Math.floor((v1.GetValue() * (v2.GetValue() + 1))))) + "[/color]");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(("[color=#999999]" + v0.GetValue()) + "[/color]");
|
|
}
|
|
, ()=>"hideHero", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const n1 = p._GetNode(1);
|
|
const f2 = p._GetNode(2).GetBoundMethod();
|
|
const f3 = p._GetNode(3).GetBoundMethod();
|
|
const n4 = p._GetNode(4);
|
|
const v5 = p._GetNode(5).GetVar();
|
|
return ()=>(((((v0.GetValue() + n1.ExpObject())) > (f2(0)) ? 1 : 0)) ? ((f3(0) - n4.ExpObject())) : (v5.GetValue()));
|
|
}
|
|
, ()=>"CHECK_COIN", p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>n0.ExpObject((and("heroes.", v1.GetValue()) + ".baseCost"));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + 1);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>and(".", (n0.ExpObject(".") - 1));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>n0.ExpObject(and("heroes.", v1.GetValue()));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpBehavior();
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
return ()=>f0(20, 20, 20, 255);
|
|
}
|
|
, ()=>"48, 48, 48", p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
return ()=>f0(255, 255, 255);
|
|
}
|
|
, ()=>"255,255,255", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const n1 = p._GetNode(1);
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>(v0.GetValue() + (((n1.ExpObject() + v2.GetValue()) + 5) / 2));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const n1 = p._GetNode(1);
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>(v0.GetValue() - (((n1.ExpObject() + v2.GetValue()) + 5) / 2));
|
|
}
|
|
, ()=>"EFFECT", p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
return ()=>f0(50, 90);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>(n0.ExpObject() + (v1.GetValue() * v2.GetValue()));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
return ()=>(n0.ExpObject() - f1(30, 50));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>(n0.ExpObject() + ((v1.GetValue() * v2.GetValue()) * 2));
|
|
}
|
|
, ()=>12345, ()=>"ACHIEVEMENT", p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>n0.ExpObject(and("achievements.", n1.ExpObject()));
|
|
}
|
|
, ()=>"achievements", p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".checkFunction");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const n1 = p._GetNode(1);
|
|
return ()=>f0(n1.ExpObject(".checkParams"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".id");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const n1 = p._GetNode(1);
|
|
return ()=>f0(n1.ExpObject());
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>n0.ExpObject(("achievements." + n1.ExpObject()));
|
|
}
|
|
, ()=>388, ()=>132, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>and("ACHIEVEMENT: ", n0.ExpObject((("achievements." + n1.ExpObject()) + ".name")));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(10 * v0.GetValue());
|
|
}
|
|
, ()=>"highestFinishedZone", ()=>"10", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(25 * v0.GetValue());
|
|
}
|
|
, ()=>"25", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(50 * v0.GetValue());
|
|
}
|
|
, ()=>"50", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(100 * v0.GetValue());
|
|
}
|
|
, ()=>"100", ()=>1000, ()=>10000, ()=>50000, ()=>100000, ()=>1000000, ()=>1000000000, ()=>100000000000000, ()=>1000000000000000000, ()=>"totalBossKills", ()=>"totalKills", ()=>500000, ()=>5000000000, ()=>50000000000000, ()=>500000000000000000, ()=>"totalUpgrades", ()=>50, ()=>75, ()=>83, ()=>"maxDps", ()=>1000000000000, ()=>1000000000000000, ()=>"totalHeroLevels", ()=>"mostClicksPerSecond", p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpBehavior("id");
|
|
}
|
|
, ()=>-1000, ()=>"OTHER", p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>((((n0.ExpInstVar()) <= (0) ? 1 : 0)) ? (0) : (n1.ExpInstVar()));
|
|
}
|
|
, ()=>"Fly", p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(and("Sound (", n0.ExpInstVar()) + ")");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
return ()=>f0(1, (-1));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
return ()=>f0(20, 60);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
return ()=>(n0.ExpObject() - f1(50, 90));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
return ()=>(n0.ExpObject() + f1(30, 80));
|
|
}
|
|
, ()=>861, ()=>265, ()=>"staticData", p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const n1 = p._GetNode(1);
|
|
const n2 = p._GetNode(2);
|
|
const n3 = p._GetNode(3);
|
|
const n4 = p._GetNode(4);
|
|
return ()=>f0(((((((n1.ExpObject() + "||") + n2.ExpObject()) + "||") + n3.ExpObject()) + "||") + n4.ExpObject()));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>((n0.ExpObject() + n1.ExpObject()) + v2.GetValue());
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(n0.ExpInstVar_Family() + 1);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(n0.ExpObject() - 1);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
return ()=>n0.ExpObject(f1(), 1);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const n2 = p._GetNode(2);
|
|
const f3 = p._GetNode(3).GetBoundMethod();
|
|
const n4 = p._GetNode(4);
|
|
const f5 = p._GetNode(5).GetBoundMethod();
|
|
return ()=>multiply(n0.ExpObject(f1(), 1), ((((n2.ExpObject(f3(), 2)) <= (0) ? 1 : 0)) ? (1) : (n4.ExpObject(f5(), 2))));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>(f0(Math.floor(v1.GetValue())) + " DPS");
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>(v0.GetValue() + Math.floor((v1.GetValue() * (v2.GetValue() / 100))));
|
|
}
|
|
, ()=>"SHOP_HANDLE", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const n1 = p._GetNode(1);
|
|
return ()=>(v0.GetValue() - n1.ExpInstVar());
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(n0.ExpObject() + 30);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
const n2 = p._GetNode(2);
|
|
return ()=>add(n0.ExpObject(n1.ExpInstVar(), 1), n2.ExpInstVar());
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>(n0.ExpObject() - (n1.ExpObject() / 2));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>(v0.GetValue() * ((100 + v1.GetValue()) / 100));
|
|
}
|
|
, ()=>411, ()=>103, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>(("Gained " + n0.ExpInstVar()) + "!");
|
|
}
|
|
, ()=>-0.1, ()=>0.1, ()=>"GRIDVIEW_CTRL", ()=>"SHOP", p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const n1 = p._GetNode(1);
|
|
const n2 = p._GetNode(2);
|
|
const n3 = p._GetNode(3);
|
|
const n4 = p._GetNode(4);
|
|
const n5 = p._GetNode(5);
|
|
return ()=>f0("", n1.ExpBehavior("costFormula"), n2.ExpBehavior("id"), n3.ExpObject(n4.ExpBehavior("id")), n5.ExpBehavior("baseCost"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>n0.ExpObject(n1.ExpBehavior("id"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpBehavior("baseClickDamage");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpBehavior("baseAttack");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpBehavior("baseCost");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpBehavior("costFormula");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpBehavior("name");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
return ()=>((((n0.ExpObject(n1.ExpBehavior("id"), 0)) > (0) ? 1 : 0)) ? ("LVL UP ") : ("HIRE"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
const n2 = p._GetNode(2);
|
|
const n3 = p._GetNode(3);
|
|
return ()=>((((n0.ExpObject(n1.ExpBehavior("id"), 0)) > (0) ? 1 : 0)) ? (and("Lvl ", n2.ExpObject(n3.ExpBehavior("id"), 0))) : (""));
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
const n2 = p._GetNode(2);
|
|
const n3 = p._GetNode(3);
|
|
const n4 = p._GetNode(4);
|
|
const n5 = p._GetNode(5);
|
|
const n6 = p._GetNode(6);
|
|
return ()=>f0(f1("", n2.ExpInstVar(), n3.ExpInstVar(), n4.ExpObject(n5.ExpInstVar()), n6.ExpInstVar()));
|
|
}
|
|
, ()=>0.6, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>((n0.ExpObject() + v1.GetValue()) + 5);
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>(v0.GetValue() - (v1.GetValue() / 2));
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>(v0.GetValue() + (v1.GetValue() / 2));
|
|
}
|
|
, ()=>"upgrades", p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".heroId");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>add(n0.ExpObject(v1.GetValue()), 1);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".iconId");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".cost");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".upgradeFunction");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".upgradeParams");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".name");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".upgradeRequired");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".heroLevelRequired");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(".description");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
return ()=>n0.ExpObject(and("heroes.", (f1() + 1)));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>and(and(n0.ExpObject((and("zones.", ((Math.floor(((v1.GetValue() - 1) / 5)) % 9) + 1)) + ".name")), " Lvl "), v2.GetValue());
|
|
}
|
|
, ()=>853, ()=>290, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>and((and("Entering ", n0.ExpObject((and("zones.", ((Math.floor(((v1.GetValue() - 1) / 5)) % 9) + 1)) + ".name"))) + " Lvl "), v2.GetValue());
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>n0.ExpObject((and("zones.", ((Math.floor(((v1.GetValue() - 1) / 5)) % 9) + 1)) + ".bossId"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>n0.ExpObject((and("zones.", ((Math.floor(((v1.GetValue() - 1) / 5)) % 9) + 1)) + ".monsterIds"));
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>subtract(n0.ExpObject((and("zones.", ((Math.floor(((v1.GetValue() - 1) / 5)) % 9) + 1)) + ".background")), 1);
|
|
}
|
|
, ()=>"MAP_CTRL", p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
const f2 = p._GetNode(2).GetBoundMethod();
|
|
const f3 = p._GetNode(3).GetBoundMethod();
|
|
const v4 = p._GetNode(4).GetVar();
|
|
return ()=>(n0.ExpObject() + ((-n1.ExpObject()) + f2(f3(v4.GetValue(), 0, ","))));
|
|
}
|
|
, ()=>"MapBack", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() - 5);
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + 5);
|
|
}
|
|
, ()=>"MapNext", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() - 10);
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() + 10);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
const n1 = p._GetNode(1);
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>((n0.ExpObject() - n1.ExpObject()) - v2.GetValue());
|
|
}
|
|
, ()=>"SETTING", ()=>"MusicBtn", ()=>"EffSoundBtn", ()=>"SettingBtn", ()=>"CloseSettingBtn", ()=>"SaveBtn", ()=>"Game saved!", ()=>"ResetBtn", ()=>"Game reset!", ()=>"ImportBtn", ()=>"ImportDataBtn", ()=>"ExportBtn", ()=>"TICK", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() / 10);
|
|
}
|
|
, p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
return ()=>(v0.GetValue() - 0.1);
|
|
}
|
|
, ()=>"Game data copied to Clipboard. Paste it in a notepad to save!", p=>{
|
|
const v0 = p._GetNode(0).GetVar();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
const v2 = p._GetNode(2).GetVar();
|
|
return ()=>((v0.GetValue() + v1.GetValue()) + v2.GetValue());
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
return ()=>f0(f1(), "||");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const f1 = p._GetNode(1).GetBoundMethod();
|
|
return ()=>f0(f1());
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>f0(v1.GetValue(), 0, "||");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>f0(v1.GetValue(), 1, "||");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>f0(v1.GetValue(), 2, "||");
|
|
}
|
|
, p=>{
|
|
const f0 = p._GetNode(0).GetBoundMethod();
|
|
const v1 = p._GetNode(1).GetVar();
|
|
return ()=>f0(v1.GetValue(), 3, "||");
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(0);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(1);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(2);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(3);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(4);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(5);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(6);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(7);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(8);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(9);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(10);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(11);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(12);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(13);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(14);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(15);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(16);
|
|
}
|
|
, p=>{
|
|
const n0 = p._GetNode(0);
|
|
return ()=>n0.ExpObject(17);
|
|
}
|
|
];
|
|
}
|
|
"use strict";
|
|
{
|
|
const scriptsInEvents = {
|
|
async Egame_Event1_Act5(runtime, localVars) {
|
|
Hideloading();
|
|
},
|
|
async Egame_Event16_Act9(runtime, localVars) {
|
|
localVars.hpMonster = monsterLifeFormula1(localVars.levelMonster, localVars.baseLife, localVars.isBoss)
|
|
},
|
|
async Egame_Event65_Act1(runtime, localVars) {
|
|
localVars.returnString = format_number_limit(localVars.numberFormat, 5);
|
|
},
|
|
async Egame_Event67_Act3(runtime, localVars) {
|
|
localVars.star = runtime.globalVars.currentCoin.toLocaleString('fullwide', {
|
|
useGrouping: false
|
|
});
|
|
},
|
|
async Egame_Event193_Act1(runtime, localVars) {
|
|
localVars.stringCoin = format_number_limit(runtime.globalVars.currentCoin, 15);
|
|
},
|
|
async Eloading_Event5_Act1(runtime, localVars) {
|
|
Hideloading();
|
|
},
|
|
async Eloaddata_Event3_Act19(runtime, localVars) {
|
|
Hideloading();
|
|
}
|
|
};
|
|
self.C3.ScriptsInEvents = scriptsInEvents;
|
|
}
|
|
function monsterLifeFormula1(levelMonster, baseLife, isBoss) {
|
|
var hpCalculation;
|
|
var levelFactor;
|
|
levelFactor = 0;
|
|
if (isBoss) {
|
|
levelFactor = Math.pow(1.6, levelMonster - 1);
|
|
hpCalculation = 10 * (baseLife * levelFactor) + (levelMonster - 1) * 10;
|
|
} else {
|
|
levelFactor = Math.pow(1.6, levelMonster - 1);
|
|
hpCalculation = baseLife * levelFactor + (levelMonster - 1) * 10;
|
|
}
|
|
return Math.ceil(hpCalculation);
|
|
}
|
|
function upgradeClickPercent(clickPercent) {
|
|
var a = clickPercent;
|
|
this.clickMultiplier = this.clickMultiplier * (1 + a / 100);
|
|
}
|
|
let array_number_view = ["", "K", "M", "B", "T", "q", "Q", "s", "S", "O", "N", "d", "U", "D", "Z"]
|
|
function format_number_limit(value_input, limit) {
|
|
var number_input = Math.floor(value_input).toLocaleString('fullwide', {
|
|
useGrouping: false
|
|
});
|
|
var show_length_number = number_input.length;
|
|
var count_unit = 0;
|
|
while (show_length_number > limit) {
|
|
show_length_number = show_length_number - 3;
|
|
count_unit = count_unit + 1;
|
|
}
|
|
var returnvalue = format_number(number_input.substring(0, show_length_number)) + array_number_view[count_unit];
|
|
return returnvalue;
|
|
}
|
|
function format_number(num) {
|
|
return num.replace(/(?<!\..*)(\d)(?=(?:\d{3})+(?:\.|$))/g, '$1,')
|
|
}
|