Files
monkeygg2.github.io/games/evowars/c2runtime.js
T
2023-08-25 13:31:04 +05:30

42516 lines
1.2 MiB
Plaintext

// Generated by Construct 2, the HTML5 game and app creator :: https://www.construct.net
var cr = {};
cr.plugins_ = {};
cr.behaviors = {};
if (typeof Object.getPrototypeOf !== "function")
{
if (typeof "test".__proto__ === "object")
{
Object.getPrototypeOf = function(object) {
return object.__proto__;
};
}
else
{
Object.getPrototypeOf = function(object) {
return object.constructor.prototype;
};
}
}
(function(){
cr.logexport = function (msg)
{
if (window.console && window.console.log)
window.console.log(msg);
};
cr.logerror = function (msg)
{
if (window.console && window.console.error)
window.console.error(msg);
};
cr.seal = function(x)
{
return x;
};
cr.freeze = function(x)
{
return x;
};
cr.is_undefined = function (x)
{
return typeof x === "undefined";
};
cr.is_number = function (x)
{
return typeof x === "number";
};
cr.is_string = function (x)
{
return typeof x === "string";
};
cr.isPOT = function (x)
{
return x > 0 && ((x - 1) & x) === 0;
};
cr.nextHighestPowerOfTwo = function(x) {
--x;
for (var i = 1; i < 32; i <<= 1) {
x = x | x >> i;
}
return x + 1;
}
cr.abs = function (x)
{
return (x < 0 ? -x : x);
};
cr.max = function (a, b)
{
return (a > b ? a : b);
};
cr.min = function (a, b)
{
return (a < b ? a : b);
};
cr.PI = Math.PI;
cr.round = function (x)
{
return (x + 0.5) | 0;
};
cr.floor = function (x)
{
if (x >= 0)
return x | 0;
else
return (x | 0) - 1; // correctly round down when negative
};
cr.ceil = function (x)
{
var f = x | 0;
return (f === x ? f : f + 1);
};
function Vector2(x, y)
{
this.x = x;
this.y = y;
cr.seal(this);
};
Vector2.prototype.offset = function (px, py)
{
this.x += px;
this.y += py;
return this;
};
Vector2.prototype.mul = function (px, py)
{
this.x *= px;
this.y *= py;
return this;
};
cr.vector2 = Vector2;
cr.segments_intersect = function(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y)
{
var max_ax, min_ax, max_ay, min_ay, max_bx, min_bx, max_by, min_by;
if (a1x < a2x)
{
min_ax = a1x;
max_ax = a2x;
}
else
{
min_ax = a2x;
max_ax = a1x;
}
if (b1x < b2x)
{
min_bx = b1x;
max_bx = b2x;
}
else
{
min_bx = b2x;
max_bx = b1x;
}
if (max_ax < min_bx || min_ax > max_bx)
return false;
if (a1y < a2y)
{
min_ay = a1y;
max_ay = a2y;
}
else
{
min_ay = a2y;
max_ay = a1y;
}
if (b1y < b2y)
{
min_by = b1y;
max_by = b2y;
}
else
{
min_by = b2y;
max_by = b1y;
}
if (max_ay < min_by || min_ay > max_by)
return false;
var dpx = b1x - a1x + b2x - a2x;
var dpy = b1y - a1y + b2y - a2y;
var qax = a2x - a1x;
var qay = a2y - a1y;
var qbx = b2x - b1x;
var qby = b2y - b1y;
var d = cr.abs(qay * qbx - qby * qax);
var la = qbx * dpy - qby * dpx;
if (cr.abs(la) > d)
return false;
var lb = qax * dpy - qay * dpx;
return cr.abs(lb) <= d;
};
function Rect(left, top, right, bottom)
{
this.set(left, top, right, bottom);
cr.seal(this);
};
Rect.prototype.set = function (left, top, right, bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
};
Rect.prototype.copy = function (r)
{
this.left = r.left;
this.top = r.top;
this.right = r.right;
this.bottom = r.bottom;
};
Rect.prototype.width = function ()
{
return this.right - this.left;
};
Rect.prototype.height = function ()
{
return this.bottom - this.top;
};
Rect.prototype.offset = function (px, py)
{
this.left += px;
this.top += py;
this.right += px;
this.bottom += py;
return this;
};
Rect.prototype.normalize = function ()
{
var temp = 0;
if (this.left > this.right)
{
temp = this.left;
this.left = this.right;
this.right = temp;
}
if (this.top > this.bottom)
{
temp = this.top;
this.top = this.bottom;
this.bottom = temp;
}
};
Rect.prototype.intersects_rect = function (rc)
{
return !(rc.right < this.left || rc.bottom < this.top || rc.left > this.right || rc.top > this.bottom);
};
Rect.prototype.intersects_rect_off = function (rc, ox, oy)
{
return !(rc.right + ox < this.left || rc.bottom + oy < this.top || rc.left + ox > this.right || rc.top + oy > this.bottom);
};
Rect.prototype.contains_pt = function (x, y)
{
return (x >= this.left && x <= this.right) && (y >= this.top && y <= this.bottom);
};
Rect.prototype.equals = function (r)
{
return this.left === r.left && this.top === r.top && this.right === r.right && this.bottom === r.bottom;
};
cr.rect = Rect;
function Quad()
{
this.tlx = 0;
this.tly = 0;
this.trx = 0;
this.try_ = 0; // is a keyword otherwise!
this.brx = 0;
this.bry = 0;
this.blx = 0;
this.bly = 0;
cr.seal(this);
};
Quad.prototype.set_from_rect = function (rc)
{
this.tlx = rc.left;
this.tly = rc.top;
this.trx = rc.right;
this.try_ = rc.top;
this.brx = rc.right;
this.bry = rc.bottom;
this.blx = rc.left;
this.bly = rc.bottom;
};
Quad.prototype.set_from_rotated_rect = function (rc, a)
{
if (a === 0)
{
this.set_from_rect(rc);
}
else
{
var sin_a = Math.sin(a);
var cos_a = Math.cos(a);
var left_sin_a = rc.left * sin_a;
var top_sin_a = rc.top * sin_a;
var right_sin_a = rc.right * sin_a;
var bottom_sin_a = rc.bottom * sin_a;
var left_cos_a = rc.left * cos_a;
var top_cos_a = rc.top * cos_a;
var right_cos_a = rc.right * cos_a;
var bottom_cos_a = rc.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;
}
};
Quad.prototype.offset = function (px, py)
{
this.tlx += px;
this.tly += py;
this.trx += px;
this.try_ += py;
this.brx += px;
this.bry += py;
this.blx += px;
this.bly += py;
return this;
};
var minresult = 0;
var maxresult = 0;
function minmax4(a, b, c, d)
{
if (a < b)
{
if (c < d)
{
if (a < c)
minresult = a;
else
minresult = c;
if (b > d)
maxresult = b;
else
maxresult = d;
}
else
{
if (a < d)
minresult = a;
else
minresult = d;
if (b > c)
maxresult = b;
else
maxresult = c;
}
}
else
{
if (c < d)
{
if (b < c)
minresult = b;
else
minresult = c;
if (a > d)
maxresult = a;
else
maxresult = d;
}
else
{
if (b < d)
minresult = b;
else
minresult = d;
if (a > c)
maxresult = a;
else
maxresult = c;
}
}
};
Quad.prototype.bounding_box = function (rc)
{
minmax4(this.tlx, this.trx, this.brx, this.blx);
rc.left = minresult;
rc.right = maxresult;
minmax4(this.tly, this.try_, this.bry, this.bly);
rc.top = minresult;
rc.bottom = maxresult;
};
Quad.prototype.contains_pt = function (x, y)
{
var tlx = this.tlx;
var tly = this.tly;
var v0x = this.trx - tlx;
var v0y = this.try_ - tly;
var v1x = this.brx - tlx;
var v1y = this.bry - tly;
var v2x = x - tlx;
var v2y = y - tly;
var dot00 = v0x * v0x + v0y * v0y
var dot01 = v0x * v1x + v0y * v1y
var dot02 = v0x * v2x + v0y * v2y
var dot11 = v1x * v1x + v1y * v1y
var dot12 = v1x * v2x + v1y * v2y
var invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
if ((u >= 0.0) && (v > 0.0) && (u + v < 1))
return true;
v0x = this.blx - tlx;
v0y = this.bly - tly;
var dot00 = v0x * v0x + v0y * v0y
var dot01 = v0x * v1x + v0y * v1y
var dot02 = v0x * v2x + v0y * v2y
invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
u = (dot11 * dot02 - dot01 * dot12) * invDenom;
v = (dot00 * dot12 - dot01 * dot02) * invDenom;
return (u >= 0.0) && (v > 0.0) && (u + v < 1);
};
Quad.prototype.at = function (i, xory)
{
if (xory)
{
switch (i)
{
case 0: return this.tlx;
case 1: return this.trx;
case 2: return this.brx;
case 3: return this.blx;
case 4: return this.tlx;
default: return this.tlx;
}
}
else
{
switch (i)
{
case 0: return this.tly;
case 1: return this.try_;
case 2: return this.bry;
case 3: return this.bly;
case 4: return this.tly;
default: return this.tly;
}
}
};
Quad.prototype.midX = function ()
{
return (this.tlx + this.trx + this.brx + this.blx) / 4;
};
Quad.prototype.midY = function ()
{
return (this.tly + this.try_ + this.bry + this.bly) / 4;
};
Quad.prototype.intersects_segment = function (x1, y1, x2, y2)
{
if (this.contains_pt(x1, y1) || this.contains_pt(x2, y2))
return true;
var a1x, a1y, a2x, a2y;
var i;
for (i = 0; i < 4; i++)
{
a1x = this.at(i, true);
a1y = this.at(i, false);
a2x = this.at(i + 1, true);
a2y = this.at(i + 1, false);
if (cr.segments_intersect(x1, y1, x2, y2, a1x, a1y, a2x, a2y))
return true;
}
return false;
};
Quad.prototype.intersects_quad = function (rhs)
{
var midx = rhs.midX();
var midy = rhs.midY();
if (this.contains_pt(midx, midy))
return true;
midx = this.midX();
midy = this.midY();
if (rhs.contains_pt(midx, midy))
return true;
var a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y;
var i, j;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
a1x = this.at(i, true);
a1y = this.at(i, false);
a2x = this.at(i + 1, true);
a2y = this.at(i + 1, false);
b1x = rhs.at(j, true);
b1y = rhs.at(j, false);
b2x = rhs.at(j + 1, true);
b2y = rhs.at(j + 1, false);
if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
return true;
}
}
return false;
};
cr.quad = Quad;
cr.RGB = function (red, green, blue)
{
return Math.max(Math.min(red, 255), 0)
| (Math.max(Math.min(green, 255), 0) << 8)
| (Math.max(Math.min(blue, 255), 0) << 16);
};
cr.GetRValue = function (rgb)
{
return rgb & 0xFF;
};
cr.GetGValue = function (rgb)
{
return (rgb & 0xFF00) >> 8;
};
cr.GetBValue = function (rgb)
{
return (rgb & 0xFF0000) >> 16;
};
cr.shallowCopy = function (a, b, allowOverwrite)
{
var attr;
for (attr in b)
{
if (b.hasOwnProperty(attr))
{
;
a[attr] = b[attr];
}
}
return a;
};
cr.arrayRemove = function (arr, index)
{
var i, len;
index = cr.floor(index);
if (index < 0 || index >= arr.length)
return; // index out of bounds
for (i = index, len = arr.length - 1; i < len; i++)
arr[i] = arr[i + 1];
cr.truncateArray(arr, len);
};
cr.truncateArray = function (arr, index)
{
arr.length = index;
};
cr.clearArray = function (arr)
{
cr.truncateArray(arr, 0);
};
cr.shallowAssignArray = function (dest, src)
{
cr.clearArray(dest);
var i, len;
for (i = 0, len = src.length; i < len; ++i)
dest[i] = src[i];
};
cr.appendArray = function (a, b)
{
a.push.apply(a, b);
};
cr.fastIndexOf = function (arr, item)
{
var i, len;
for (i = 0, len = arr.length; i < len; ++i)
{
if (arr[i] === item)
return i;
}
return -1;
};
cr.arrayFindRemove = function (arr, item)
{
var index = cr.fastIndexOf(arr, item);
if (index !== -1)
cr.arrayRemove(arr, index);
};
cr.clamp = function(x, a, b)
{
if (x < a)
return a;
else if (x > b)
return b;
else
return x;
};
cr.to_radians = function(x)
{
return x / (180.0 / cr.PI);
};
cr.to_degrees = function(x)
{
return x * (180.0 / cr.PI);
};
cr.clamp_angle_degrees = function (a)
{
a %= 360; // now in (-360, 360) range
if (a < 0)
a += 360; // now in [0, 360) range
return a;
};
cr.clamp_angle = function (a)
{
a %= 2 * cr.PI; // now in (-2pi, 2pi) range
if (a < 0)
a += 2 * cr.PI; // now in [0, 2pi) range
return a;
};
cr.to_clamped_degrees = function (x)
{
return cr.clamp_angle_degrees(cr.to_degrees(x));
};
cr.to_clamped_radians = function (x)
{
return cr.clamp_angle(cr.to_radians(x));
};
cr.angleTo = function(x1, y1, x2, y2)
{
var dx = x2 - x1;
var dy = y2 - y1;
return Math.atan2(dy, dx);
};
cr.angleDiff = function (a1, a2)
{
if (a1 === a2)
return 0;
var s1 = Math.sin(a1);
var c1 = Math.cos(a1);
var s2 = Math.sin(a2);
var c2 = Math.cos(a2);
var n = s1 * s2 + c1 * c2;
if (n >= 1)
return 0;
if (n <= -1)
return cr.PI;
return Math.acos(n);
};
cr.angleRotate = function (start, end, step)
{
var ss = Math.sin(start);
var cs = Math.cos(start);
var se = Math.sin(end);
var ce = Math.cos(end);
if (Math.acos(ss * se + cs * ce) > step)
{
if (cs * se - ss * ce > 0)
return cr.clamp_angle(start + step);
else
return cr.clamp_angle(start - step);
}
else
return cr.clamp_angle(end);
};
cr.angleClockwise = function (a1, a2)
{
var s1 = Math.sin(a1);
var c1 = Math.cos(a1);
var s2 = Math.sin(a2);
var c2 = Math.cos(a2);
return c1 * s2 - s1 * c2 <= 0;
};
cr.rotatePtAround = function (px, py, a, ox, oy, getx)
{
if (a === 0)
return getx ? px : py;
var sin_a = Math.sin(a);
var cos_a = Math.cos(a);
px -= ox;
py -= oy;
var left_sin_a = px * sin_a;
var top_sin_a = py * sin_a;
var left_cos_a = px * cos_a;
var 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 getx ? px : py;
}
cr.distanceTo = function(x1, y1, x2, y2)
{
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt(dx*dx + dy*dy);
};
cr.xor = function (x, y)
{
return !x !== !y;
};
cr.lerp = function (a, b, x)
{
return a + (b - a) * x;
};
cr.unlerp = function (a, b, c)
{
if (a === b)
return 0; // avoid divide by 0
return (c - a) / (b - a);
};
cr.anglelerp = function (a, b, x)
{
var diff = cr.angleDiff(a, b);
if (cr.angleClockwise(b, a))
{
return a + diff * x;
}
else
{
return a - diff * x;
}
};
cr.qarp = function (a, b, c, x)
{
return cr.lerp(cr.lerp(a, b, x), cr.lerp(b, c, x), x);
};
cr.cubic = function (a, b, c, d, x)
{
return cr.lerp(cr.qarp(a, b, c, x), cr.qarp(b, c, d, x), x);
};
cr.cosp = function (a, b, x)
{
return (a + b + (a - b) * Math.cos(x * Math.PI)) / 2;
};
cr.hasAnyOwnProperty = function (o)
{
var p;
for (p in o)
{
if (o.hasOwnProperty(p))
return true;
}
return false;
};
cr.wipe = function (obj)
{
var p;
for (p in obj)
{
if (obj.hasOwnProperty(p))
delete obj[p];
}
};
var startup_time = +(new Date());
cr.performance_now = function()
{
if (typeof window["performance"] !== "undefined")
{
var winperf = window["performance"];
if (typeof winperf.now !== "undefined")
return winperf.now();
else if (typeof winperf["webkitNow"] !== "undefined")
return winperf["webkitNow"]();
else if (typeof winperf["mozNow"] !== "undefined")
return winperf["mozNow"]();
else if (typeof winperf["msNow"] !== "undefined")
return winperf["msNow"]();
}
return Date.now() - startup_time;
};
var isChrome = false;
var isSafari = false;
var isiOS = false;
var isEjecta = false;
if (typeof window !== "undefined") // not c2 editor
{
isChrome = /chrome/i.test(navigator.userAgent) || /chromium/i.test(navigator.userAgent);
isSafari = !isChrome && /safari/i.test(navigator.userAgent);
isiOS = /(iphone|ipod|ipad)/i.test(navigator.userAgent);
isEjecta = window["c2ejecta"];
}
var supports_set = ((!isSafari && !isEjecta && !isiOS) && (typeof Set !== "undefined" && typeof Set.prototype["forEach"] !== "undefined"));
function ObjectSet_()
{
this.s = null;
this.items = null; // lazy allocated (hopefully results in better GC performance)
this.item_count = 0;
if (supports_set)
{
this.s = new Set();
}
this.values_cache = [];
this.cache_valid = true;
cr.seal(this);
};
ObjectSet_.prototype.contains = function (x)
{
if (this.isEmpty())
return false;
if (supports_set)
return this.s["has"](x);
else
return (this.items && this.items.hasOwnProperty(x));
};
ObjectSet_.prototype.add = function (x)
{
if (supports_set)
{
if (!this.s["has"](x))
{
this.s["add"](x);
this.cache_valid = false;
}
}
else
{
var str = x.toString();
var items = this.items;
if (!items)
{
this.items = {};
this.items[str] = x;
this.item_count = 1;
this.cache_valid = false;
}
else if (!items.hasOwnProperty(str))
{
items[str] = x;
this.item_count++;
this.cache_valid = false;
}
}
};
ObjectSet_.prototype.remove = function (x)
{
if (this.isEmpty())
return;
if (supports_set)
{
if (this.s["has"](x))
{
this.s["delete"](x);
this.cache_valid = false;
}
}
else if (this.items)
{
var str = x.toString();
var items = this.items;
if (items.hasOwnProperty(str))
{
delete items[str];
this.item_count--;
this.cache_valid = false;
}
}
};
ObjectSet_.prototype.clear = function (/*wipe_*/)
{
if (this.isEmpty())
return;
if (supports_set)
{
this.s["clear"](); // best!
}
else
{
this.items = null; // creates garbage; will lazy allocate on next add()
this.item_count = 0;
}
cr.clearArray(this.values_cache);
this.cache_valid = true;
};
ObjectSet_.prototype.isEmpty = function ()
{
return this.count() === 0;
};
ObjectSet_.prototype.count = function ()
{
if (supports_set)
return this.s["size"];
else
return this.item_count;
};
var current_arr = null;
var current_index = 0;
function set_append_to_arr(x)
{
current_arr[current_index++] = x;
};
ObjectSet_.prototype.update_cache = function ()
{
if (this.cache_valid)
return;
if (supports_set)
{
cr.clearArray(this.values_cache);
current_arr = this.values_cache;
current_index = 0;
this.s["forEach"](set_append_to_arr);
;
current_arr = null;
current_index = 0;
}
else
{
var values_cache = this.values_cache;
cr.clearArray(values_cache);
var p, n = 0, items = this.items;
if (items)
{
for (p in items)
{
if (items.hasOwnProperty(p))
values_cache[n++] = items[p];
}
}
;
}
this.cache_valid = true;
};
ObjectSet_.prototype.valuesRef = function ()
{
this.update_cache();
return this.values_cache;
};
cr.ObjectSet = ObjectSet_;
var tmpSet = new cr.ObjectSet();
cr.removeArrayDuplicates = function (arr)
{
var i, len;
for (i = 0, len = arr.length; i < len; ++i)
{
tmpSet.add(arr[i]);
}
cr.shallowAssignArray(arr, tmpSet.valuesRef());
tmpSet.clear();
};
cr.arrayRemoveAllFromObjectSet = function (arr, remset)
{
if (supports_set)
cr.arrayRemoveAll_set(arr, remset.s);
else
cr.arrayRemoveAll_arr(arr, remset.valuesRef());
};
cr.arrayRemoveAll_set = function (arr, s)
{
var i, j, len, item;
for (i = 0, j = 0, len = arr.length; i < len; ++i)
{
item = arr[i];
if (!s["has"](item)) // not an item to remove
arr[j++] = item; // keep it
}
cr.truncateArray(arr, j);
};
cr.arrayRemoveAll_arr = function (arr, rem)
{
var i, j, len, item;
for (i = 0, j = 0, len = arr.length; i < len; ++i)
{
item = arr[i];
if (cr.fastIndexOf(rem, item) === -1) // not an item to remove
arr[j++] = item; // keep it
}
cr.truncateArray(arr, j);
};
function KahanAdder_()
{
this.c = 0;
this.y = 0;
this.t = 0;
this.sum = 0;
cr.seal(this);
};
KahanAdder_.prototype.add = function (v)
{
this.y = v - this.c;
this.t = this.sum + this.y;
this.c = (this.t - this.sum) - this.y;
this.sum = this.t;
};
KahanAdder_.prototype.reset = function ()
{
this.c = 0;
this.y = 0;
this.t = 0;
this.sum = 0;
};
cr.KahanAdder = KahanAdder_;
cr.regexp_escape = function(text)
{
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};
function CollisionPoly_(pts_array_)
{
this.pts_cache = [];
this.bboxLeft = 0;
this.bboxTop = 0;
this.bboxRight = 0;
this.bboxBottom = 0;
this.convexpolys = null; // for physics behavior to cache separated polys
this.set_pts(pts_array_);
cr.seal(this);
};
CollisionPoly_.prototype.set_pts = function(pts_array_)
{
this.pts_array = pts_array_;
this.pts_count = pts_array_.length / 2; // x, y, x, y... in array
this.pts_cache.length = pts_array_.length;
this.cache_width = -1;
this.cache_height = -1;
this.cache_angle = 0;
};
CollisionPoly_.prototype.is_empty = function()
{
return !this.pts_array.length;
};
CollisionPoly_.prototype.update_bbox = function ()
{
var myptscache = this.pts_cache;
var bboxLeft_ = myptscache[0];
var bboxRight_ = bboxLeft_;
var bboxTop_ = myptscache[1];
var bboxBottom_ = bboxTop_;
var x, y, i = 1, i2, len = this.pts_count;
for ( ; i < len; ++i)
{
i2 = i*2;
x = myptscache[i2];
y = myptscache[i2+1];
if (x < bboxLeft_)
bboxLeft_ = x;
if (x > bboxRight_)
bboxRight_ = x;
if (y < bboxTop_)
bboxTop_ = y;
if (y > bboxBottom_)
bboxBottom_ = y;
}
this.bboxLeft = bboxLeft_;
this.bboxRight = bboxRight_;
this.bboxTop = bboxTop_;
this.bboxBottom = bboxBottom_;
};
CollisionPoly_.prototype.set_from_rect = function(rc, offx, offy)
{
this.pts_cache.length = 8;
this.pts_count = 4;
var myptscache = this.pts_cache;
myptscache[0] = rc.left - offx;
myptscache[1] = rc.top - offy;
myptscache[2] = rc.right - offx;
myptscache[3] = rc.top - offy;
myptscache[4] = rc.right - offx;
myptscache[5] = rc.bottom - offy;
myptscache[6] = rc.left - offx;
myptscache[7] = rc.bottom - offy;
this.cache_width = rc.right - rc.left;
this.cache_height = rc.bottom - rc.top;
this.update_bbox();
};
CollisionPoly_.prototype.set_from_quad = function(q, offx, offy, w, h)
{
this.pts_cache.length = 8;
this.pts_count = 4;
var myptscache = this.pts_cache;
myptscache[0] = q.tlx - offx;
myptscache[1] = q.tly - offy;
myptscache[2] = q.trx - offx;
myptscache[3] = q.try_ - offy;
myptscache[4] = q.brx - offx;
myptscache[5] = q.bry - offy;
myptscache[6] = q.blx - offx;
myptscache[7] = q.bly - offy;
this.cache_width = w;
this.cache_height = h;
this.update_bbox();
};
CollisionPoly_.prototype.set_from_poly = function (r)
{
this.pts_count = r.pts_count;
cr.shallowAssignArray(this.pts_cache, r.pts_cache);
this.bboxLeft = r.bboxLeft;
this.bboxTop - r.bboxTop;
this.bboxRight = r.bboxRight;
this.bboxBottom = r.bboxBottom;
};
CollisionPoly_.prototype.cache_poly = function(w, h, a)
{
if (this.cache_width === w && this.cache_height === h && this.cache_angle === a)
return; // cache up-to-date
this.cache_width = w;
this.cache_height = h;
this.cache_angle = a;
var i, i2, i21, len, x, y;
var sina = 0;
var cosa = 1;
var myptsarray = this.pts_array;
var myptscache = this.pts_cache;
if (a !== 0)
{
sina = Math.sin(a);
cosa = Math.cos(a);
}
for (i = 0, len = this.pts_count; i < len; i++)
{
i2 = i*2;
i21 = i2+1;
x = myptsarray[i2] * w;
y = myptsarray[i21] * h;
myptscache[i2] = (x * cosa) - (y * sina);
myptscache[i21] = (y * cosa) + (x * sina);
}
this.update_bbox();
};
CollisionPoly_.prototype.contains_pt = function (a2x, a2y)
{
var myptscache = this.pts_cache;
if (a2x === myptscache[0] && a2y === myptscache[1])
return true;
var i, i2, imod, len = this.pts_count;
var a1x = this.bboxLeft - 110;
var a1y = this.bboxTop - 101;
var a3x = this.bboxRight + 131
var a3y = this.bboxBottom + 120;
var b1x, b1y, b2x, b2y;
var count1 = 0, count2 = 0;
for (i = 0; i < len; i++)
{
i2 = i*2;
imod = ((i+1)%len)*2;
b1x = myptscache[i2];
b1y = myptscache[i2+1];
b2x = myptscache[imod];
b2y = myptscache[imod+1];
if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
count1++;
if (cr.segments_intersect(a3x, a3y, a2x, a2y, b1x, b1y, b2x, b2y))
count2++;
}
return (count1 % 2 === 1) || (count2 % 2 === 1);
};
CollisionPoly_.prototype.intersects_poly = function (rhs, offx, offy)
{
var rhspts = rhs.pts_cache;
var mypts = this.pts_cache;
if (this.contains_pt(rhspts[0] + offx, rhspts[1] + offy))
return true;
if (rhs.contains_pt(mypts[0] - offx, mypts[1] - offy))
return true;
var i, i2, imod, leni, j, j2, jmod, lenj;
var a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y;
for (i = 0, leni = this.pts_count; i < leni; i++)
{
i2 = i*2;
imod = ((i+1)%leni)*2;
a1x = mypts[i2];
a1y = mypts[i2+1];
a2x = mypts[imod];
a2y = mypts[imod+1];
for (j = 0, lenj = rhs.pts_count; j < lenj; j++)
{
j2 = j*2;
jmod = ((j+1)%lenj)*2;
b1x = rhspts[j2] + offx;
b1y = rhspts[j2+1] + offy;
b2x = rhspts[jmod] + offx;
b2y = rhspts[jmod+1] + offy;
if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
return true;
}
}
return false;
};
CollisionPoly_.prototype.intersects_segment = function (offx, offy, x1, y1, x2, y2)
{
var mypts = this.pts_cache;
if (this.contains_pt(x1 - offx, y1 - offy))
return true;
var i, leni, i2, imod;
var a1x, a1y, a2x, a2y;
for (i = 0, leni = this.pts_count; i < leni; i++)
{
i2 = i*2;
imod = ((i+1)%leni)*2;
a1x = mypts[i2] + offx;
a1y = mypts[i2+1] + offy;
a2x = mypts[imod] + offx;
a2y = mypts[imod+1] + offy;
if (cr.segments_intersect(x1, y1, x2, y2, a1x, a1y, a2x, a2y))
return true;
}
return false;
};
CollisionPoly_.prototype.mirror = function (px)
{
var i, leni, i2;
for (i = 0, leni = this.pts_count; i < leni; ++i)
{
i2 = i*2;
this.pts_cache[i2] = px * 2 - this.pts_cache[i2];
}
};
CollisionPoly_.prototype.flip = function (py)
{
var i, leni, i21;
for (i = 0, leni = this.pts_count; i < leni; ++i)
{
i21 = i*2+1;
this.pts_cache[i21] = py * 2 - this.pts_cache[i21];
}
};
CollisionPoly_.prototype.diag = function ()
{
var i, leni, i2, i21, temp;
for (i = 0, leni = this.pts_count; i < leni; ++i)
{
i2 = i*2;
i21 = i2+1;
temp = this.pts_cache[i2];
this.pts_cache[i2] = this.pts_cache[i21];
this.pts_cache[i21] = temp;
}
};
cr.CollisionPoly = CollisionPoly_;
function SparseGrid_(cellwidth_, cellheight_)
{
this.cellwidth = cellwidth_;
this.cellheight = cellheight_;
this.cells = {};
};
SparseGrid_.prototype.totalCellCount = 0;
SparseGrid_.prototype.getCell = function (x_, y_, create_if_missing)
{
var ret;
var col = this.cells[x_];
if (!col)
{
if (create_if_missing)
{
ret = allocGridCell(this, x_, y_);
this.cells[x_] = {};
this.cells[x_][y_] = ret;
return ret;
}
else
return null;
}
ret = col[y_];
if (ret)
return ret;
else if (create_if_missing)
{
ret = allocGridCell(this, x_, y_);
this.cells[x_][y_] = ret;
return ret;
}
else
return null;
};
SparseGrid_.prototype.XToCell = function (x_)
{
return cr.floor(x_ / this.cellwidth);
};
SparseGrid_.prototype.YToCell = function (y_)
{
return cr.floor(y_ / this.cellheight);
};
SparseGrid_.prototype.update = function (inst, oldrange, newrange)
{
var x, lenx, y, leny, cell;
if (oldrange)
{
for (x = oldrange.left, lenx = oldrange.right; x <= lenx; ++x)
{
for (y = oldrange.top, leny = oldrange.bottom; y <= leny; ++y)
{
if (newrange && newrange.contains_pt(x, y))
continue; // is still in this cell
cell = this.getCell(x, y, false); // don't create if missing
if (!cell)
continue; // cell does not exist yet
cell.remove(inst);
if (cell.isEmpty())
{
freeGridCell(cell);
this.cells[x][y] = null;
}
}
}
}
if (newrange)
{
for (x = newrange.left, lenx = newrange.right; x <= lenx; ++x)
{
for (y = newrange.top, leny = newrange.bottom; y <= leny; ++y)
{
if (oldrange && oldrange.contains_pt(x, y))
continue; // is still in this cell
this.getCell(x, y, true).insert(inst);
}
}
}
};
SparseGrid_.prototype.queryRange = function (rc, result)
{
var x, lenx, ystart, y, leny, cell;
x = this.XToCell(rc.left);
ystart = this.YToCell(rc.top);
lenx = this.XToCell(rc.right);
leny = this.YToCell(rc.bottom);
for ( ; x <= lenx; ++x)
{
for (y = ystart; y <= leny; ++y)
{
cell = this.getCell(x, y, false);
if (!cell)
continue;
cell.dump(result);
}
}
};
cr.SparseGrid = SparseGrid_;
function RenderGrid_(cellwidth_, cellheight_)
{
this.cellwidth = cellwidth_;
this.cellheight = cellheight_;
this.cells = {};
};
RenderGrid_.prototype.totalCellCount = 0;
RenderGrid_.prototype.getCell = function (x_, y_, create_if_missing)
{
var ret;
var col = this.cells[x_];
if (!col)
{
if (create_if_missing)
{
ret = allocRenderCell(this, x_, y_);
this.cells[x_] = {};
this.cells[x_][y_] = ret;
return ret;
}
else
return null;
}
ret = col[y_];
if (ret)
return ret;
else if (create_if_missing)
{
ret = allocRenderCell(this, x_, y_);
this.cells[x_][y_] = ret;
return ret;
}
else
return null;
};
RenderGrid_.prototype.XToCell = function (x_)
{
return cr.floor(x_ / this.cellwidth);
};
RenderGrid_.prototype.YToCell = function (y_)
{
return cr.floor(y_ / this.cellheight);
};
RenderGrid_.prototype.update = function (inst, oldrange, newrange)
{
var x, lenx, y, leny, cell;
if (oldrange)
{
for (x = oldrange.left, lenx = oldrange.right; x <= lenx; ++x)
{
for (y = oldrange.top, leny = oldrange.bottom; y <= leny; ++y)
{
if (newrange && newrange.contains_pt(x, y))
continue; // is still in this cell
cell = this.getCell(x, y, false); // don't create if missing
if (!cell)
continue; // cell does not exist yet
cell.remove(inst);
if (cell.isEmpty())
{
freeRenderCell(cell);
this.cells[x][y] = null;
}
}
}
}
if (newrange)
{
for (x = newrange.left, lenx = newrange.right; x <= lenx; ++x)
{
for (y = newrange.top, leny = newrange.bottom; y <= leny; ++y)
{
if (oldrange && oldrange.contains_pt(x, y))
continue; // is still in this cell
this.getCell(x, y, true).insert(inst);
}
}
}
};
RenderGrid_.prototype.queryRange = function (left, top, right, bottom, result)
{
var x, lenx, ystart, y, leny, cell;
x = this.XToCell(left);
ystart = this.YToCell(top);
lenx = this.XToCell(right);
leny = this.YToCell(bottom);
for ( ; x <= lenx; ++x)
{
for (y = ystart; y <= leny; ++y)
{
cell = this.getCell(x, y, false);
if (!cell)
continue;
cell.dump(result);
}
}
};
RenderGrid_.prototype.markRangeChanged = function (rc)
{
var x, lenx, ystart, y, leny, cell;
x = rc.left;
ystart = rc.top;
lenx = rc.right;
leny = rc.bottom;
for ( ; x <= lenx; ++x)
{
for (y = ystart; y <= leny; ++y)
{
cell = this.getCell(x, y, false);
if (!cell)
continue;
cell.is_sorted = false;
}
}
};
cr.RenderGrid = RenderGrid_;
var gridcellcache = [];
function allocGridCell(grid_, x_, y_)
{
var ret;
SparseGrid_.prototype.totalCellCount++;
if (gridcellcache.length)
{
ret = gridcellcache.pop();
ret.grid = grid_;
ret.x = x_;
ret.y = y_;
return ret;
}
else
return new cr.GridCell(grid_, x_, y_);
};
function freeGridCell(c)
{
SparseGrid_.prototype.totalCellCount--;
c.objects.clear();
if (gridcellcache.length < 1000)
gridcellcache.push(c);
};
function GridCell_(grid_, x_, y_)
{
this.grid = grid_;
this.x = x_;
this.y = y_;
this.objects = new cr.ObjectSet();
};
GridCell_.prototype.isEmpty = function ()
{
return this.objects.isEmpty();
};
GridCell_.prototype.insert = function (inst)
{
this.objects.add(inst);
};
GridCell_.prototype.remove = function (inst)
{
this.objects.remove(inst);
};
GridCell_.prototype.dump = function (result)
{
cr.appendArray(result, this.objects.valuesRef());
};
cr.GridCell = GridCell_;
var rendercellcache = [];
function allocRenderCell(grid_, x_, y_)
{
var ret;
RenderGrid_.prototype.totalCellCount++;
if (rendercellcache.length)
{
ret = rendercellcache.pop();
ret.grid = grid_;
ret.x = x_;
ret.y = y_;
return ret;
}
else
return new cr.RenderCell(grid_, x_, y_);
};
function freeRenderCell(c)
{
RenderGrid_.prototype.totalCellCount--;
c.reset();
if (rendercellcache.length < 1000)
rendercellcache.push(c);
};
function RenderCell_(grid_, x_, y_)
{
this.grid = grid_;
this.x = x_;
this.y = y_;
this.objects = []; // array which needs to be sorted by Z order
this.is_sorted = true; // whether array is in correct sort order or not
this.pending_removal = new cr.ObjectSet();
this.any_pending_removal = false;
};
RenderCell_.prototype.isEmpty = function ()
{
if (!this.objects.length)
{
;
;
return true;
}
if (this.objects.length > this.pending_removal.count())
return false;
;
this.flush_pending(); // takes fast path and just resets state
return true;
};
RenderCell_.prototype.insert = function (inst)
{
if (this.pending_removal.contains(inst))
{
this.pending_removal.remove(inst);
if (this.pending_removal.isEmpty())
this.any_pending_removal = false;
return;
}
if (this.objects.length)
{
var top = this.objects[this.objects.length - 1];
if (top.get_zindex() > inst.get_zindex())
this.is_sorted = false; // 'inst' should be somewhere beneath 'top'
this.objects.push(inst);
}
else
{
this.objects.push(inst);
this.is_sorted = true;
}
;
};
RenderCell_.prototype.remove = function (inst)
{
this.pending_removal.add(inst);
this.any_pending_removal = true;
if (this.pending_removal.count() >= 30)
this.flush_pending();
};
RenderCell_.prototype.flush_pending = function ()
{
;
if (!this.any_pending_removal)
return; // not changed
if (this.pending_removal.count() === this.objects.length)
{
this.reset();
return;
}
cr.arrayRemoveAllFromObjectSet(this.objects, this.pending_removal);
this.pending_removal.clear();
this.any_pending_removal = false;
};
function sortByInstanceZIndex(a, b)
{
return a.zindex - b.zindex;
};
RenderCell_.prototype.ensure_sorted = function ()
{
if (this.is_sorted)
return; // already sorted
this.objects.sort(sortByInstanceZIndex);
this.is_sorted = true;
};
RenderCell_.prototype.reset = function ()
{
cr.clearArray(this.objects);
this.is_sorted = true;
this.pending_removal.clear();
this.any_pending_removal = false;
};
RenderCell_.prototype.dump = function (result)
{
this.flush_pending();
this.ensure_sorted();
if (this.objects.length)
result.push(this.objects);
};
cr.RenderCell = RenderCell_;
var fxNames = [ "lighter",
"xor",
"copy",
"destination-over",
"source-in",
"destination-in",
"source-out",
"destination-out",
"source-atop",
"destination-atop"];
cr.effectToCompositeOp = function(effect)
{
if (effect <= 0 || effect >= 11)
return "source-over";
return fxNames[effect - 1]; // not including "none" so offset by 1
};
cr.setGLBlend = function(this_, effect, gl)
{
if (!gl)
return;
this_.srcBlend = gl.ONE;
this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
switch (effect) {
case 1: // lighter (additive)
this_.srcBlend = gl.ONE;
this_.destBlend = gl.ONE;
break;
case 2: // xor
break; // todo
case 3: // copy
this_.srcBlend = gl.ONE;
this_.destBlend = gl.ZERO;
break;
case 4: // destination-over
this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
this_.destBlend = gl.ONE;
break;
case 5: // source-in
this_.srcBlend = gl.DST_ALPHA;
this_.destBlend = gl.ZERO;
break;
case 6: // destination-in
this_.srcBlend = gl.ZERO;
this_.destBlend = gl.SRC_ALPHA;
break;
case 7: // source-out
this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
this_.destBlend = gl.ZERO;
break;
case 8: // destination-out
this_.srcBlend = gl.ZERO;
this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
break;
case 9: // source-atop
this_.srcBlend = gl.DST_ALPHA;
this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
break;
case 10: // destination-atop
this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
this_.destBlend = gl.SRC_ALPHA;
break;
}
};
cr.round6dp = function (x)
{
return Math.round(x * 1000000) / 1000000;
};
/*
var localeCompare_options = {
"usage": "search",
"sensitivity": "accent"
};
var has_localeCompare = !!"a".localeCompare;
var localeCompare_works1 = (has_localeCompare && "a".localeCompare("A", undefined, localeCompare_options) === 0);
var localeCompare_works2 = (has_localeCompare && "a".localeCompare("á", undefined, localeCompare_options) !== 0);
var supports_localeCompare = (has_localeCompare && localeCompare_works1 && localeCompare_works2);
*/
cr.equals_nocase = function (a, b)
{
if (typeof a !== "string" || typeof b !== "string")
return false;
if (a.length !== b.length)
return false;
if (a === b)
return true;
/*
if (supports_localeCompare)
{
return (a.localeCompare(b, undefined, localeCompare_options) === 0);
}
else
{
*/
return a.toLowerCase() === b.toLowerCase();
};
cr.isCanvasInputEvent = function (e)
{
var target = e.target;
if (!target)
return true;
if (target === document || target === window)
return true;
if (document && document.body && target === document.body)
return true;
if (cr.equals_nocase(target.tagName, "canvas"))
return true;
return false;
};
}());
var MatrixArray=typeof Float32Array!=="undefined"?Float32Array:Array,glMatrixArrayType=MatrixArray,vec3={},mat3={},mat4={},quat4={};vec3.create=function(a){var b=new MatrixArray(3);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2]);return b};vec3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];return b};vec3.add=function(a,b,c){if(!c||a===c)return a[0]+=b[0],a[1]+=b[1],a[2]+=b[2],a;c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];return c};
vec3.subtract=function(a,b,c){if(!c||a===c)return a[0]-=b[0],a[1]-=b[1],a[2]-=b[2],a;c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];return c};vec3.negate=function(a,b){b||(b=a);b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];return b};vec3.scale=function(a,b,c){if(!c||a===c)return a[0]*=b,a[1]*=b,a[2]*=b,a;c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b;return c};
vec3.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=Math.sqrt(c*c+d*d+e*e);if(g){if(g===1)return b[0]=c,b[1]=d,b[2]=e,b}else return b[0]=0,b[1]=0,b[2]=0,b;g=1/g;b[0]=c*g;b[1]=d*g;b[2]=e*g;return b};vec3.cross=function(a,b,c){c||(c=a);var d=a[0],e=a[1],a=a[2],g=b[0],f=b[1],b=b[2];c[0]=e*b-a*f;c[1]=a*g-d*b;c[2]=d*f-e*g;return c};vec3.length=function(a){var b=a[0],c=a[1],a=a[2];return Math.sqrt(b*b+c*c+a*a)};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]};
vec3.direction=function(a,b,c){c||(c=a);var d=a[0]-b[0],e=a[1]-b[1],a=a[2]-b[2],b=Math.sqrt(d*d+e*e+a*a);if(!b)return c[0]=0,c[1]=0,c[2]=0,c;b=1/b;c[0]=d*b;c[1]=e*b;c[2]=a*b;return c};vec3.lerp=function(a,b,c,d){d||(d=a);d[0]=a[0]+c*(b[0]-a[0]);d[1]=a[1]+c*(b[1]-a[1]);d[2]=a[2]+c*(b[2]-a[2]);return d};vec3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+"]"};
mat3.create=function(a){var b=new MatrixArray(9);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3],b[4]=a[4],b[5]=a[5],b[6]=a[6],b[7]=a[7],b[8]=a[8]);return b};mat3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return b};mat3.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a};
mat3.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[5];a[1]=a[3];a[2]=a[6];a[3]=c;a[5]=a[7];a[6]=d;a[7]=e;return a}b[0]=a[0];b[1]=a[3];b[2]=a[6];b[3]=a[1];b[4]=a[4];b[5]=a[7];b[6]=a[2];b[7]=a[5];b[8]=a[8];return b};mat3.toMat4=function(a,b){b||(b=mat4.create());b[15]=1;b[14]=0;b[13]=0;b[12]=0;b[11]=0;b[10]=a[8];b[9]=a[7];b[8]=a[6];b[7]=0;b[6]=a[5];b[5]=a[4];b[4]=a[3];b[3]=0;b[2]=a[2];b[1]=a[1];b[0]=a[0];return b};
mat3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+"]"};mat4.create=function(a){var b=new MatrixArray(16);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3],b[4]=a[4],b[5]=a[5],b[6]=a[6],b[7]=a[7],b[8]=a[8],b[9]=a[9],b[10]=a[10],b[11]=a[11],b[12]=a[12],b[13]=a[13],b[14]=a[14],b[15]=a[15]);return b};
mat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return b};mat4.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a};
mat4.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[3],g=a[6],f=a[7],h=a[11];a[1]=a[4];a[2]=a[8];a[3]=a[12];a[4]=c;a[6]=a[9];a[7]=a[13];a[8]=d;a[9]=g;a[11]=a[14];a[12]=e;a[13]=f;a[14]=h;return a}b[0]=a[0];b[1]=a[4];b[2]=a[8];b[3]=a[12];b[4]=a[1];b[5]=a[5];b[6]=a[9];b[7]=a[13];b[8]=a[2];b[9]=a[6];b[10]=a[10];b[11]=a[14];b[12]=a[3];b[13]=a[7];b[14]=a[11];b[15]=a[15];return b};
mat4.determinant=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],g=a[4],f=a[5],h=a[6],i=a[7],j=a[8],k=a[9],l=a[10],n=a[11],o=a[12],m=a[13],p=a[14],a=a[15];return o*k*h*e-j*m*h*e-o*f*l*e+g*m*l*e+j*f*p*e-g*k*p*e-o*k*d*i+j*m*d*i+o*c*l*i-b*m*l*i-j*c*p*i+b*k*p*i+o*f*d*n-g*m*d*n-o*c*h*n+b*m*h*n+g*c*p*n-b*f*p*n-j*f*d*a+g*k*d*a+j*c*h*a-b*k*h*a-g*c*l*a+b*f*l*a};
mat4.inverse=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=a[4],h=a[5],i=a[6],j=a[7],k=a[8],l=a[9],n=a[10],o=a[11],m=a[12],p=a[13],r=a[14],s=a[15],A=c*h-d*f,B=c*i-e*f,t=c*j-g*f,u=d*i-e*h,v=d*j-g*h,w=e*j-g*i,x=k*p-l*m,y=k*r-n*m,z=k*s-o*m,C=l*r-n*p,D=l*s-o*p,E=n*s-o*r,q=1/(A*E-B*D+t*C+u*z-v*y+w*x);b[0]=(h*E-i*D+j*C)*q;b[1]=(-d*E+e*D-g*C)*q;b[2]=(p*w-r*v+s*u)*q;b[3]=(-l*w+n*v-o*u)*q;b[4]=(-f*E+i*z-j*y)*q;b[5]=(c*E-e*z+g*y)*q;b[6]=(-m*w+r*t-s*B)*q;b[7]=(k*w-n*t+o*B)*q;b[8]=(f*D-h*z+j*x)*q;
b[9]=(-c*D+d*z-g*x)*q;b[10]=(m*v-p*t+s*A)*q;b[11]=(-k*v+l*t-o*A)*q;b[12]=(-f*C+h*y-i*x)*q;b[13]=(c*C-d*y+e*x)*q;b[14]=(-m*u+p*B-r*A)*q;b[15]=(k*u-l*B+n*A)*q;return b};mat4.toRotationMat=function(a,b){b||(b=mat4.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};
mat4.toMat3=function(a,b){b||(b=mat3.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[4];b[4]=a[5];b[5]=a[6];b[6]=a[8];b[7]=a[9];b[8]=a[10];return b};mat4.toInverseMat3=function(a,b){var c=a[0],d=a[1],e=a[2],g=a[4],f=a[5],h=a[6],i=a[8],j=a[9],k=a[10],l=k*f-h*j,n=-k*g+h*i,o=j*g-f*i,m=c*l+d*n+e*o;if(!m)return null;m=1/m;b||(b=mat3.create());b[0]=l*m;b[1]=(-k*d+e*j)*m;b[2]=(h*d-e*f)*m;b[3]=n*m;b[4]=(k*c-e*i)*m;b[5]=(-h*c+e*g)*m;b[6]=o*m;b[7]=(-j*c+d*i)*m;b[8]=(f*c-d*g)*m;return b};
mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],f=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],n=a[9],o=a[10],m=a[11],p=a[12],r=a[13],s=a[14],a=a[15],A=b[0],B=b[1],t=b[2],u=b[3],v=b[4],w=b[5],x=b[6],y=b[7],z=b[8],C=b[9],D=b[10],E=b[11],q=b[12],F=b[13],G=b[14],b=b[15];c[0]=A*d+B*h+t*l+u*p;c[1]=A*e+B*i+t*n+u*r;c[2]=A*g+B*j+t*o+u*s;c[3]=A*f+B*k+t*m+u*a;c[4]=v*d+w*h+x*l+y*p;c[5]=v*e+w*i+x*n+y*r;c[6]=v*g+w*j+x*o+y*s;c[7]=v*f+w*k+x*m+y*a;c[8]=z*d+C*h+D*l+E*p;c[9]=z*e+C*i+D*n+E*r;c[10]=z*g+C*
j+D*o+E*s;c[11]=z*f+C*k+D*m+E*a;c[12]=q*d+F*h+G*l+b*p;c[13]=q*e+F*i+G*n+b*r;c[14]=q*g+F*j+G*o+b*s;c[15]=q*f+F*k+G*m+b*a;return c};mat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],b=b[2];c[0]=a[0]*d+a[4]*e+a[8]*b+a[12];c[1]=a[1]*d+a[5]*e+a[9]*b+a[13];c[2]=a[2]*d+a[6]*e+a[10]*b+a[14];return c};
mat4.multiplyVec4=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2],b=b[3];c[0]=a[0]*d+a[4]*e+a[8]*g+a[12]*b;c[1]=a[1]*d+a[5]*e+a[9]*g+a[13]*b;c[2]=a[2]*d+a[6]*e+a[10]*g+a[14]*b;c[3]=a[3]*d+a[7]*e+a[11]*g+a[15]*b;return c};
mat4.translate=function(a,b,c){var d=b[0],e=b[1],b=b[2],g,f,h,i,j,k,l,n,o,m,p,r;if(!c||a===c)return a[12]=a[0]*d+a[4]*e+a[8]*b+a[12],a[13]=a[1]*d+a[5]*e+a[9]*b+a[13],a[14]=a[2]*d+a[6]*e+a[10]*b+a[14],a[15]=a[3]*d+a[7]*e+a[11]*b+a[15],a;g=a[0];f=a[1];h=a[2];i=a[3];j=a[4];k=a[5];l=a[6];n=a[7];o=a[8];m=a[9];p=a[10];r=a[11];c[0]=g;c[1]=f;c[2]=h;c[3]=i;c[4]=j;c[5]=k;c[6]=l;c[7]=n;c[8]=o;c[9]=m;c[10]=p;c[11]=r;c[12]=g*d+j*e+o*b+a[12];c[13]=f*d+k*e+m*b+a[13];c[14]=h*d+l*e+p*b+a[14];c[15]=i*d+n*e+r*b+a[15];
return c};mat4.scale=function(a,b,c){var d=b[0],e=b[1],b=b[2];if(!c||a===c)return a[0]*=d,a[1]*=d,a[2]*=d,a[3]*=d,a[4]*=e,a[5]*=e,a[6]*=e,a[7]*=e,a[8]*=b,a[9]*=b,a[10]*=b,a[11]*=b,a;c[0]=a[0]*d;c[1]=a[1]*d;c[2]=a[2]*d;c[3]=a[3]*d;c[4]=a[4]*e;c[5]=a[5]*e;c[6]=a[6]*e;c[7]=a[7]*e;c[8]=a[8]*b;c[9]=a[9]*b;c[10]=a[10]*b;c[11]=a[11]*b;c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15];return c};
mat4.rotate=function(a,b,c,d){var e=c[0],g=c[1],c=c[2],f=Math.sqrt(e*e+g*g+c*c),h,i,j,k,l,n,o,m,p,r,s,A,B,t,u,v,w,x,y,z;if(!f)return null;f!==1&&(f=1/f,e*=f,g*=f,c*=f);h=Math.sin(b);i=Math.cos(b);j=1-i;b=a[0];f=a[1];k=a[2];l=a[3];n=a[4];o=a[5];m=a[6];p=a[7];r=a[8];s=a[9];A=a[10];B=a[11];t=e*e*j+i;u=g*e*j+c*h;v=c*e*j-g*h;w=e*g*j-c*h;x=g*g*j+i;y=c*g*j+e*h;z=e*c*j+g*h;e=g*c*j-e*h;g=c*c*j+i;d?a!==d&&(d[12]=a[12],d[13]=a[13],d[14]=a[14],d[15]=a[15]):d=a;d[0]=b*t+n*u+r*v;d[1]=f*t+o*u+s*v;d[2]=k*t+m*u+A*
v;d[3]=l*t+p*u+B*v;d[4]=b*w+n*x+r*y;d[5]=f*w+o*x+s*y;d[6]=k*w+m*x+A*y;d[7]=l*w+p*x+B*y;d[8]=b*z+n*e+r*g;d[9]=f*z+o*e+s*g;d[10]=k*z+m*e+A*g;d[11]=l*z+p*e+B*g;return d};mat4.rotateX=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[4],g=a[5],f=a[6],h=a[7],i=a[8],j=a[9],k=a[10],l=a[11];c?a!==c&&(c[0]=a[0],c[1]=a[1],c[2]=a[2],c[3]=a[3],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[4]=e*b+i*d;c[5]=g*b+j*d;c[6]=f*b+k*d;c[7]=h*b+l*d;c[8]=e*-d+i*b;c[9]=g*-d+j*b;c[10]=f*-d+k*b;c[11]=h*-d+l*b;return c};
mat4.rotateY=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[0],g=a[1],f=a[2],h=a[3],i=a[8],j=a[9],k=a[10],l=a[11];c?a!==c&&(c[4]=a[4],c[5]=a[5],c[6]=a[6],c[7]=a[7],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[0]=e*b+i*-d;c[1]=g*b+j*-d;c[2]=f*b+k*-d;c[3]=h*b+l*-d;c[8]=e*d+i*b;c[9]=g*d+j*b;c[10]=f*d+k*b;c[11]=h*d+l*b;return c};
mat4.rotateZ=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[0],g=a[1],f=a[2],h=a[3],i=a[4],j=a[5],k=a[6],l=a[7];c?a!==c&&(c[8]=a[8],c[9]=a[9],c[10]=a[10],c[11]=a[11],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[0]=e*b+i*d;c[1]=g*b+j*d;c[2]=f*b+k*d;c[3]=h*b+l*d;c[4]=e*-d+i*b;c[5]=g*-d+j*b;c[6]=f*-d+k*b;c[7]=h*-d+l*b;return c};
mat4.frustum=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f};mat4.perspective=function(a,b,c,d,e){a=c*Math.tan(a*Math.PI/360);b*=a;return mat4.frustum(-b,b,-a,a,c,d,e)};
mat4.ortho=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=2/i;f[6]=0;f[7]=0;f[8]=0;f[9]=0;f[10]=-2/j;f[11]=0;f[12]=-(a+b)/h;f[13]=-(d+c)/i;f[14]=-(g+e)/j;f[15]=1;return f};
mat4.lookAt=function(a,b,c,d){d||(d=mat4.create());var e,g,f,h,i,j,k,l,n=a[0],o=a[1],a=a[2];g=c[0];f=c[1];e=c[2];c=b[1];j=b[2];if(n===b[0]&&o===c&&a===j)return mat4.identity(d);c=n-b[0];j=o-b[1];k=a-b[2];l=1/Math.sqrt(c*c+j*j+k*k);c*=l;j*=l;k*=l;b=f*k-e*j;e=e*c-g*k;g=g*j-f*c;(l=Math.sqrt(b*b+e*e+g*g))?(l=1/l,b*=l,e*=l,g*=l):g=e=b=0;f=j*g-k*e;h=k*b-c*g;i=c*e-j*b;(l=Math.sqrt(f*f+h*h+i*i))?(l=1/l,f*=l,h*=l,i*=l):i=h=f=0;d[0]=b;d[1]=f;d[2]=c;d[3]=0;d[4]=e;d[5]=h;d[6]=j;d[7]=0;d[8]=g;d[9]=i;d[10]=k;d[11]=
0;d[12]=-(b*n+e*o+g*a);d[13]=-(f*n+h*o+i*a);d[14]=-(c*n+j*o+k*a);d[15]=1;return d};mat4.fromRotationTranslation=function(a,b,c){c||(c=mat4.create());var d=a[0],e=a[1],g=a[2],f=a[3],h=d+d,i=e+e,j=g+g,a=d*h,k=d*i;d*=j;var l=e*i;e*=j;g*=j;h*=f;i*=f;f*=j;c[0]=1-(l+g);c[1]=k+f;c[2]=d-i;c[3]=0;c[4]=k-f;c[5]=1-(a+g);c[6]=e+h;c[7]=0;c[8]=d+i;c[9]=e-h;c[10]=1-(a+l);c[11]=0;c[12]=b[0];c[13]=b[1];c[14]=b[2];c[15]=1;return c};
mat4.str=function(a){return"["+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]+"]"};quat4.create=function(a){var b=new MatrixArray(4);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3]);return b};quat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];return b};
quat4.calculateW=function(a,b){var c=a[0],d=a[1],e=a[2];if(!b||a===b)return a[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e)),a;b[0]=c;b[1]=d;b[2]=e;b[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e));return b};quat4.inverse=function(a,b){if(!b||a===b)return a[0]*=-1,a[1]*=-1,a[2]*=-1,a;b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];b[3]=a[3];return b};quat4.length=function(a){var b=a[0],c=a[1],d=a[2],a=a[3];return Math.sqrt(b*b+c*c+d*d+a*a)};
quat4.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=Math.sqrt(c*c+d*d+e*e+g*g);if(f===0)return b[0]=0,b[1]=0,b[2]=0,b[3]=0,b;f=1/f;b[0]=c*f;b[1]=d*f;b[2]=e*f;b[3]=g*f;return b};quat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],a=a[3],f=b[0],h=b[1],i=b[2],b=b[3];c[0]=d*b+a*f+e*i-g*h;c[1]=e*b+a*h+g*f-d*i;c[2]=g*b+a*i+d*h-e*f;c[3]=a*b-d*f-e*h-g*i;return c};
quat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2],b=a[0],f=a[1],h=a[2],a=a[3],i=a*d+f*g-h*e,j=a*e+h*d-b*g,k=a*g+b*e-f*d,d=-b*d-f*e-h*g;c[0]=i*a+d*-b+j*-h-k*-f;c[1]=j*a+d*-f+k*-b-i*-h;c[2]=k*a+d*-h+i*-f-j*-b;return c};quat4.toMat3=function(a,b){b||(b=mat3.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c*=i;var l=d*h;d*=i;e*=i;f*=g;h*=g;g*=i;b[0]=1-(l+e);b[1]=k+g;b[2]=c-h;b[3]=k-g;b[4]=1-(j+e);b[5]=d+f;b[6]=c+h;b[7]=d-f;b[8]=1-(j+l);return b};
quat4.toMat4=function(a,b){b||(b=mat4.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c*=i;var l=d*h;d*=i;e*=i;f*=g;h*=g;g*=i;b[0]=1-(l+e);b[1]=k+g;b[2]=c-h;b[3]=0;b[4]=k-g;b[5]=1-(j+e);b[6]=d+f;b[7]=0;b[8]=c+h;b[9]=d-f;b[10]=1-(j+l);b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};
quat4.slerp=function(a,b,c,d){d||(d=a);var e=a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3],g,f;if(Math.abs(e)>=1)return d!==a&&(d[0]=a[0],d[1]=a[1],d[2]=a[2],d[3]=a[3]),d;g=Math.acos(e);f=Math.sqrt(1-e*e);if(Math.abs(f)<0.001)return d[0]=a[0]*0.5+b[0]*0.5,d[1]=a[1]*0.5+b[1]*0.5,d[2]=a[2]*0.5+b[2]*0.5,d[3]=a[3]*0.5+b[3]*0.5,d;e=Math.sin((1-c)*g)/f;c=Math.sin(c*g)/f;d[0]=a[0]*e+b[0]*c;d[1]=a[1]*e+b[1]*c;d[2]=a[2]*e+b[2]*c;d[3]=a[3]*e+b[3]*c;return d};
quat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+"]"};
(function()
{
var MAX_VERTICES = 8000; // equates to 2500 objects being drawn
var MAX_INDICES = (MAX_VERTICES / 2) * 3; // 6 indices for every 4 vertices
var MAX_POINTS = 8000;
var MULTI_BUFFERS = 4; // cycle 4 buffers to try and avoid blocking
var BATCH_NULL = 0;
var BATCH_QUAD = 1;
var BATCH_SETTEXTURE = 2;
var BATCH_SETOPACITY = 3;
var BATCH_SETBLEND = 4;
var BATCH_UPDATEMODELVIEW = 5;
var BATCH_RENDERTOTEXTURE = 6;
var BATCH_CLEAR = 7;
var BATCH_POINTS = 8;
var BATCH_SETPROGRAM = 9;
var BATCH_SETPROGRAMPARAMETERS = 10;
var BATCH_SETTEXTURE1 = 11;
var BATCH_SETCOLOR = 12;
var BATCH_SETDEPTHTEST = 13;
var BATCH_SETEARLYZMODE = 14;
/*
var lose_ext = null;
window.lose_context = function ()
{
if (!lose_ext)
{
console.log("WEBGL_lose_context not supported");
return;
}
lose_ext.loseContext();
};
window.restore_context = function ()
{
if (!lose_ext)
{
console.log("WEBGL_lose_context not supported");
return;
}
lose_ext.restoreContext();
};
*/
var tempMat4 = mat4.create();
function GLWrap_(gl, isMobile, enableFrontToBack)
{
this.isIE = /msie/i.test(navigator.userAgent) || /trident/i.test(navigator.userAgent);
this.width = 0; // not yet known, wait for call to setSize()
this.height = 0;
this.enableFrontToBack = !!enableFrontToBack;
this.isEarlyZPass = false;
this.isBatchInEarlyZPass = false;
this.currentZ = 0;
this.zNear = 1;
this.zFar = 1000;
this.zIncrement = ((this.zFar - this.zNear) / 32768);
this.zA = this.zFar / (this.zFar - this.zNear);
this.zB = this.zFar * this.zNear / (this.zNear - this.zFar);
this.kzA = 65536 * this.zA;
this.kzB = 65536 * this.zB;
this.cam = vec3.create([0, 0, 100]); // camera position
this.look = vec3.create([0, 0, 0]); // lookat position
this.up = vec3.create([0, 1, 0]); // up vector
this.worldScale = vec3.create([1, 1, 1]); // world scaling factor
this.enable_mipmaps = true;
this.matP = mat4.create(); // perspective matrix
this.matMV = mat4.create(); // model view matrix
this.lastMV = mat4.create();
this.currentMV = mat4.create();
this.gl = gl;
this.version = (this.gl.getParameter(this.gl.VERSION).indexOf("WebGL 2") === 0 ? 2 : 1);
this.initState();
};
GLWrap_.prototype.initState = function ()
{
var gl = this.gl;
var i, len;
this.lastOpacity = 1;
this.lastTexture0 = null; // last bound to TEXTURE0
this.lastTexture1 = null; // last bound to TEXTURE1
this.currentOpacity = 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);
gl.disable(gl.CULL_FACE);
gl.disable(gl.STENCIL_TEST);
gl.disable(gl.DITHER);
if (this.enableFrontToBack)
{
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
}
else
{
gl.disable(gl.DEPTH_TEST);
}
this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
this.lastSrcBlend = gl.ONE;
this.lastDestBlend = gl.ONE_MINUS_SRC_ALPHA;
this.vertexData = new Float32Array(MAX_VERTICES * (this.enableFrontToBack ? 3 : 2));
this.texcoordData = new Float32Array(MAX_VERTICES * 2);
this.pointData = new Float32Array(MAX_POINTS * 4);
this.pointBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.pointData.byteLength, gl.DYNAMIC_DRAW);
this.vertexBuffers = new Array(MULTI_BUFFERS);
this.texcoordBuffers = new Array(MULTI_BUFFERS);
for (i = 0; i < MULTI_BUFFERS; i++)
{
this.vertexBuffers[i] = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffers[i]);
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData.byteLength, gl.DYNAMIC_DRAW);
this.texcoordBuffers[i] = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffers[i]);
gl.bufferData(gl.ARRAY_BUFFER, this.texcoordData.byteLength, gl.DYNAMIC_DRAW);
}
this.curBuffer = 0;
this.indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
var indexData = new Uint16Array(MAX_INDICES);
i = 0, len = MAX_INDICES;
var fv = 0;
while (i < len)
{
indexData[i++] = fv; // top left
indexData[i++] = fv + 1; // top right
indexData[i++] = fv + 2; // bottom right (first tri)
indexData[i++] = fv; // top left
indexData[i++] = fv + 2; // bottom right
indexData[i++] = fv + 3; // bottom left
fv += 4;
}
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW);
this.vertexPtr = 0;
this.texPtr = 0;
this.pointPtr = 0;
var fsSource, vsSource;
this.shaderPrograms = [];
fsSource = [
"varying mediump vec2 vTex;",
"uniform lowp float opacity;",
"uniform lowp sampler2D samplerFront;",
"void main(void) {",
" gl_FragColor = texture2D(samplerFront, vTex);",
" gl_FragColor *= opacity;",
"}"
].join("\n");
if (this.enableFrontToBack)
{
vsSource = [
"attribute highp vec3 aPos;",
"attribute mediump vec2 aTex;",
"varying mediump vec2 vTex;",
"uniform highp mat4 matP;",
"uniform highp mat4 matMV;",
"void main(void) {",
" gl_Position = matP * matMV * vec4(aPos.x, aPos.y, aPos.z, 1.0);",
" vTex = aTex;",
"}"
].join("\n");
}
else
{
vsSource = [
"attribute highp vec2 aPos;",
"attribute mediump vec2 aTex;",
"varying mediump vec2 vTex;",
"uniform highp mat4 matP;",
"uniform highp mat4 matMV;",
"void main(void) {",
" gl_Position = matP * matMV * vec4(aPos.x, aPos.y, 0.0, 1.0);",
" vTex = aTex;",
"}"
].join("\n");
}
var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, "<default>");
;
this.shaderPrograms.push(shaderProg); // Default shader is always shader 0
fsSource = [
"uniform mediump sampler2D samplerFront;",
"varying lowp float opacity;",
"void main(void) {",
" gl_FragColor = texture2D(samplerFront, gl_PointCoord);",
" gl_FragColor *= opacity;",
"}"
].join("\n");
var pointVsSource = [
"attribute vec4 aPos;",
"varying float opacity;",
"uniform mat4 matP;",
"uniform mat4 matMV;",
"void main(void) {",
" gl_Position = matP * matMV * vec4(aPos.x, aPos.y, 0.0, 1.0);",
" gl_PointSize = aPos.z;",
" opacity = aPos.w;",
"}"
].join("\n");
shaderProg = this.createShaderProgram({src: fsSource}, pointVsSource, "<point>");
;
this.shaderPrograms.push(shaderProg); // Point shader is always shader 1
fsSource = [
"varying mediump vec2 vTex;",
"uniform lowp sampler2D samplerFront;",
"void main(void) {",
" if (texture2D(samplerFront, vTex).a < 1.0)",
" discard;", // discarding non-opaque fragments
"}"
].join("\n");
var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, "<earlyz>");
;
this.shaderPrograms.push(shaderProg); // Early-Z shader is always shader 2
fsSource = [
"uniform lowp vec4 colorFill;",
"void main(void) {",
" gl_FragColor = colorFill;",
"}"
].join("\n");
var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, "<fill>");
;
this.shaderPrograms.push(shaderProg); // Fill-color shader is always shader 3
for (var shader_name in cr.shaders)
{
if (cr.shaders.hasOwnProperty(shader_name))
this.shaderPrograms.push(this.createShaderProgram(cr.shaders[shader_name], vsSource, shader_name));
}
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, null);
this.batch = [];
this.batchPtr = 0;
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
this.lastProgram = -1; // start -1 so first switchProgram can do work
this.currentProgram = -1; // current program during batch execution
this.currentShader = null;
this.fbo = gl.createFramebuffer();
this.renderToTex = null;
this.depthBuffer = null;
this.attachedDepthBuffer = false; // wait until first size call to attach, otherwise it has no storage
if (this.enableFrontToBack)
{
this.depthBuffer = gl.createRenderbuffer();
}
this.tmpVec3 = vec3.create([0, 0, 0]);
;
var pointsizes = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
this.minPointSize = pointsizes[0];
this.maxPointSize = pointsizes[1];
if (this.maxPointSize > 2048)
this.maxPointSize = 2048;
;
this.switchProgram(0);
cr.seal(this);
};
function GLShaderProgram(gl, shaderProgram, name)
{
this.gl = gl;
this.shaderProgram = shaderProgram;
this.name = name;
this.locAPos = gl.getAttribLocation(shaderProgram, "aPos");
this.locATex = gl.getAttribLocation(shaderProgram, "aTex");
this.locMatP = gl.getUniformLocation(shaderProgram, "matP");
this.locMatMV = gl.getUniformLocation(shaderProgram, "matMV");
this.locOpacity = gl.getUniformLocation(shaderProgram, "opacity");
this.locColorFill = gl.getUniformLocation(shaderProgram, "colorFill");
this.locSamplerFront = gl.getUniformLocation(shaderProgram, "samplerFront");
this.locSamplerBack = gl.getUniformLocation(shaderProgram, "samplerBack");
this.locDestStart = gl.getUniformLocation(shaderProgram, "destStart");
this.locDestEnd = gl.getUniformLocation(shaderProgram, "destEnd");
this.locSeconds = gl.getUniformLocation(shaderProgram, "seconds");
this.locPixelWidth = gl.getUniformLocation(shaderProgram, "pixelWidth");
this.locPixelHeight = gl.getUniformLocation(shaderProgram, "pixelHeight");
this.locLayerScale = gl.getUniformLocation(shaderProgram, "layerScale");
this.locLayerAngle = gl.getUniformLocation(shaderProgram, "layerAngle");
this.locViewOrigin = gl.getUniformLocation(shaderProgram, "viewOrigin");
this.locScrollPos = gl.getUniformLocation(shaderProgram, "scrollPos");
this.hasAnyOptionalUniforms = !!(this.locPixelWidth || this.locPixelHeight || this.locSeconds || this.locSamplerBack || this.locDestStart || this.locDestEnd || this.locLayerScale || this.locLayerAngle || this.locViewOrigin || this.locScrollPos);
this.lpPixelWidth = -999; // set to something unlikely so never counts as cached on first set
this.lpPixelHeight = -999;
this.lpOpacity = 1;
this.lpDestStartX = 0.0;
this.lpDestStartY = 0.0;
this.lpDestEndX = 1.0;
this.lpDestEndY = 1.0;
this.lpLayerScale = 1.0;
this.lpLayerAngle = 0.0;
this.lpViewOriginX = 0.0;
this.lpViewOriginY = 0.0;
this.lpScrollPosX = 0.0;
this.lpScrollPosY = 0.0;
this.lpSeconds = 0.0;
this.lastCustomParams = [];
this.lpMatMV = mat4.create();
if (this.locOpacity)
gl.uniform1f(this.locOpacity, 1);
if (this.locColorFill)
gl.uniform4f(this.locColorFill, 1.0, 1.0, 1.0, 1.0);
if (this.locSamplerFront)
gl.uniform1i(this.locSamplerFront, 0);
if (this.locSamplerBack)
gl.uniform1i(this.locSamplerBack, 1);
if (this.locDestStart)
gl.uniform2f(this.locDestStart, 0.0, 0.0);
if (this.locDestEnd)
gl.uniform2f(this.locDestEnd, 1.0, 1.0);
if (this.locLayerScale)
gl.uniform1f(this.locLayerScale, 1.0);
if (this.locLayerAngle)
gl.uniform1f(this.locLayerAngle, 0.0);
if (this.locViewOrigin)
gl.uniform2f(this.locViewOrigin, 0.0, 0.0);
if (this.locScrollPos)
gl.uniform2f(this.locScrollPos, 0.0, 0.0);
if (this.locSeconds)
gl.uniform1f(this.locSeconds, 0.0);
this.hasCurrentMatMV = false; // matMV needs updating
};
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];
};
GLShaderProgram.prototype.updateMatMV = function (mv)
{
if (areMat4sEqual(this.lpMatMV, mv))
return; // no change, save the expensive GL call
mat4.set(mv, this.lpMatMV);
this.gl.uniformMatrix4fv(this.locMatMV, false, mv);
};
GLWrap_.prototype.createShaderProgram = function(shaderEntry, vsSource, name)
{
var gl = this.gl;
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, shaderEntry.src);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS))
{
var compilationlog = gl.getShaderInfoLog(fragmentShader);
gl.deleteShader(fragmentShader);
throw new Error("error compiling fragment shader: " + compilationlog);
}
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS))
{
var compilationlog = gl.getShaderInfoLog(vertexShader);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
throw new Error("error compiling vertex shader: " + compilationlog);
}
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, fragmentShader);
gl.attachShader(shaderProgram, vertexShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS))
{
var compilationlog = gl.getProgramInfoLog(shaderProgram);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
gl.deleteProgram(shaderProgram);
throw new Error("error linking shader program: " + compilationlog);
}
gl.useProgram(shaderProgram);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
var ret = new GLShaderProgram(gl, shaderProgram, name);
ret.extendBoxHorizontal = shaderEntry.extendBoxHorizontal || 0;
ret.extendBoxVertical = shaderEntry.extendBoxVertical || 0;
ret.crossSampling = !!shaderEntry.crossSampling;
ret.preservesOpaqueness = !!shaderEntry.preservesOpaqueness;
ret.animated = !!shaderEntry.animated;
ret.parameters = shaderEntry.parameters || [];
var i, len;
for (i = 0, len = ret.parameters.length; i < len; i++)
{
ret.parameters[i][1] = gl.getUniformLocation(shaderProgram, ret.parameters[i][0]);
ret.lastCustomParams.push(0);
gl.uniform1f(ret.parameters[i][1], 0);
}
cr.seal(ret);
return ret;
};
GLWrap_.prototype.getShaderIndex = function(name_)
{
var i, len;
for (i = 0, len = this.shaderPrograms.length; i < len; i++)
{
if (this.shaderPrograms[i].name === name_)
return i;
}
return -1;
};
GLWrap_.prototype.project = function (x, y, out)
{
var mv = this.matMV;
var proj = this.matP;
var fTempo = [0, 0, 0, 0, 0, 0, 0, 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.0) //The w value
return;
fTempo[7]=1.0/fTempo[7];
fTempo[4]*=fTempo[7];
fTempo[5]*=fTempo[7];
fTempo[6]*=fTempo[7];
out[0]=(fTempo[4]*0.5+0.5)*this.width;
out[1]=(fTempo[5]*0.5+0.5)*this.height;
};
GLWrap_.prototype.setSize = function(w, h, force)
{
if (this.width === w && this.height === h && !force)
return;
this.endBatch();
var gl = this.gl;
this.width = w;
this.height = h;
gl.viewport(0, 0, w, h);
mat4.lookAt(this.cam, this.look, this.up, this.matMV);
if (this.enableFrontToBack)
{
mat4.ortho(-w/2, w/2, h/2, -h/2, this.zNear, this.zFar, this.matP);
this.worldScale[0] = 1;
this.worldScale[1] = 1;
}
else
{
mat4.perspective(45, w / h, this.zNear, this.zFar, this.matP);
var tl = [0, 0];
var br = [0, 0];
this.project(0, 0, tl);
this.project(1, 1, br);
this.worldScale[0] = 1 / (br[0] - tl[0]);
this.worldScale[1] = -1 / (br[1] - tl[1]);
}
var i, len, s;
for (i = 0, len = this.shaderPrograms.length; i < len; i++)
{
s = this.shaderPrograms[i];
s.hasCurrentMatMV = false;
if (s.locMatP)
{
gl.useProgram(s.shaderProgram);
gl.uniformMatrix4fv(s.locMatP, false, this.matP);
}
}
gl.useProgram(this.shaderPrograms[this.lastProgram].shaderProgram);
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.depthBuffer)
{
gl.bindFramebuffer(gl.FRAMEBUFFER, this.fbo);
gl.bindRenderbuffer(gl.RENDERBUFFER, this.depthBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height);
if (!this.attachedDepthBuffer)
{
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.depthBuffer);
this.attachedDepthBuffer = true;
}
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
this.renderToTex = null;
}
};
GLWrap_.prototype.resetModelView = function ()
{
mat4.lookAt(this.cam, this.look, this.up, this.matMV);
mat4.scale(this.matMV, this.worldScale);
};
GLWrap_.prototype.translate = function (x, y)
{
if (x === 0 && y === 0)
return;
this.tmpVec3[0] = x;// * this.worldScale[0];
this.tmpVec3[1] = y;// * this.worldScale[1];
this.tmpVec3[2] = 0;
mat4.translate(this.matMV, this.tmpVec3);
};
GLWrap_.prototype.scale = function (x, y)
{
if (x === 1 && y === 1)
return;
this.tmpVec3[0] = x;
this.tmpVec3[1] = y;
this.tmpVec3[2] = 1;
mat4.scale(this.matMV, this.tmpVec3);
};
GLWrap_.prototype.rotateZ = function (a)
{
if (a === 0)
return;
mat4.rotateZ(this.matMV, a);
};
GLWrap_.prototype.updateModelView = function()
{
if (areMat4sEqual(this.lastMV, this.matMV))
return;
var b = this.pushBatch();
b.type = BATCH_UPDATEMODELVIEW;
if (b.mat4param)
mat4.set(this.matMV, b.mat4param);
else
b.mat4param = mat4.create(this.matMV);
mat4.set(this.matMV, this.lastMV);
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
/*
var debugBatch = false;
jQuery(document).mousedown(
function(info) {
if (info.which === 2)
debugBatch = true;
}
);
*/
GLWrap_.prototype.setEarlyZIndex = function (i)
{
if (!this.enableFrontToBack)
return;
if (i > 32760)
i = 32760;
this.currentZ = this.cam[2] - this.zNear - i * this.zIncrement;
};
function GLBatchJob(type_, glwrap_)
{
this.type = type_;
this.glwrap = glwrap_;
this.gl = glwrap_.gl;
this.opacityParam = 0; // for setOpacity()
this.startIndex = 0; // for quad()
this.indexCount = 0; // "
this.texParam = null; // for setTexture()
this.mat4param = null; // for updateModelView()
this.shaderParams = []; // for user parameters
cr.seal(this);
};
GLBatchJob.prototype.doSetEarlyZPass = function ()
{
var gl = this.gl;
var glwrap = this.glwrap;
if (this.startIndex !== 0) // enable
{
gl.depthMask(true); // enable depth writes
gl.colorMask(false, false, false, false); // disable color writes
gl.disable(gl.BLEND); // no color writes so disable blend
gl.bindFramebuffer(gl.FRAMEBUFFER, glwrap.fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
gl.clear(gl.DEPTH_BUFFER_BIT); // auto-clear depth buffer
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
glwrap.isBatchInEarlyZPass = true;
}
else
{
gl.depthMask(false); // disable depth writes, only test existing depth values
gl.colorMask(true, true, true, true); // enable color writes
gl.enable(gl.BLEND); // turn blending back on
glwrap.isBatchInEarlyZPass = false;
}
};
GLBatchJob.prototype.doSetTexture = function ()
{
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texParam);
};
GLBatchJob.prototype.doSetTexture1 = function ()
{
var gl = this.gl;
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, this.texParam);
gl.activeTexture(gl.TEXTURE0);
};
GLBatchJob.prototype.doSetOpacity = function ()
{
var o = this.opacityParam;
var glwrap = this.glwrap;
glwrap.currentOpacity = o;
var curProg = glwrap.currentShader;
if (curProg.locOpacity && curProg.lpOpacity !== o)
{
curProg.lpOpacity = o;
this.gl.uniform1f(curProg.locOpacity, o);
}
};
GLBatchJob.prototype.doQuad = function ()
{
this.gl.drawElements(this.gl.TRIANGLES, this.indexCount, this.gl.UNSIGNED_SHORT, this.startIndex);
};
GLBatchJob.prototype.doSetBlend = function ()
{
this.gl.blendFunc(this.startIndex, this.indexCount);
};
GLBatchJob.prototype.doUpdateModelView = function ()
{
var i, len, s, shaderPrograms = this.glwrap.shaderPrograms, currentProgram = this.glwrap.currentProgram;
for (i = 0, len = shaderPrograms.length; i < len; i++)
{
s = shaderPrograms[i];
if (i === currentProgram && s.locMatMV)
{
s.updateMatMV(this.mat4param);
s.hasCurrentMatMV = true;
}
else
s.hasCurrentMatMV = false;
}
mat4.set(this.mat4param, this.glwrap.currentMV);
};
GLBatchJob.prototype.doRenderToTexture = function ()
{
var gl = this.gl;
var glwrap = this.glwrap;
if (this.texParam)
{
if (glwrap.lastTexture1 === this.texParam)
{
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, null);
glwrap.lastTexture1 = null;
gl.activeTexture(gl.TEXTURE0);
}
gl.bindFramebuffer(gl.FRAMEBUFFER, glwrap.fbo);
if (!glwrap.isBatchInEarlyZPass)
{
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texParam, 0);
}
}
else
{
if (!glwrap.enableFrontToBack)
{
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
};
GLBatchJob.prototype.doClear = function ()
{
var gl = this.gl;
var mode = this.startIndex;
if (mode === 0) // clear whole surface
{
gl.clearColor(this.mat4param[0], this.mat4param[1], this.mat4param[2], this.mat4param[3]);
gl.clear(gl.COLOR_BUFFER_BIT);
}
else if (mode === 1) // clear rectangle
{
gl.enable(gl.SCISSOR_TEST);
gl.scissor(this.mat4param[0], this.mat4param[1], this.mat4param[2], this.mat4param[3]);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.disable(gl.SCISSOR_TEST);
}
else // clear depth
{
gl.clear(gl.DEPTH_BUFFER_BIT);
}
};
GLBatchJob.prototype.doSetDepthTestEnabled = function ()
{
var gl = this.gl;
var enable = this.startIndex;
if (enable !== 0)
{
gl.enable(gl.DEPTH_TEST);
}
else
{
gl.disable(gl.DEPTH_TEST);
}
};
GLBatchJob.prototype.doPoints = function ()
{
var gl = this.gl;
var glwrap = this.glwrap;
if (glwrap.enableFrontToBack)
gl.disable(gl.DEPTH_TEST);
var s = glwrap.shaderPrograms[1];
gl.useProgram(s.shaderProgram);
if (!s.hasCurrentMatMV && s.locMatMV)
{
s.updateMatMV(glwrap.currentMV);
s.hasCurrentMatMV = true;
}
gl.enableVertexAttribArray(s.locAPos);
gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.pointBuffer);
gl.vertexAttribPointer(s.locAPos, 4, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.POINTS, this.startIndex / 4, this.indexCount);
s = glwrap.currentShader;
gl.useProgram(s.shaderProgram);
if (s.locAPos >= 0)
{
gl.enableVertexAttribArray(s.locAPos);
gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.vertexBuffers[glwrap.curBuffer]);
gl.vertexAttribPointer(s.locAPos, glwrap.enableFrontToBack ? 3 : 2, gl.FLOAT, false, 0, 0);
}
if (s.locATex >= 0)
{
gl.enableVertexAttribArray(s.locATex);
gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.texcoordBuffers[glwrap.curBuffer]);
gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
}
if (glwrap.enableFrontToBack)
gl.enable(gl.DEPTH_TEST);
};
GLBatchJob.prototype.doSetProgram = function ()
{
var gl = this.gl;
var glwrap = this.glwrap;
var s = glwrap.shaderPrograms[this.startIndex]; // recycled param to save memory
glwrap.currentProgram = this.startIndex; // current batch program
glwrap.currentShader = s;
gl.useProgram(s.shaderProgram); // switch to
if (!s.hasCurrentMatMV && s.locMatMV)
{
s.updateMatMV(glwrap.currentMV);
s.hasCurrentMatMV = true;
}
if (s.locOpacity && s.lpOpacity !== glwrap.currentOpacity)
{
s.lpOpacity = glwrap.currentOpacity;
gl.uniform1f(s.locOpacity, glwrap.currentOpacity);
}
if (s.locAPos >= 0)
{
gl.enableVertexAttribArray(s.locAPos);
gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.vertexBuffers[glwrap.curBuffer]);
gl.vertexAttribPointer(s.locAPos, glwrap.enableFrontToBack ? 3 : 2, gl.FLOAT, false, 0, 0);
}
if (s.locATex >= 0)
{
gl.enableVertexAttribArray(s.locATex);
gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.texcoordBuffers[glwrap.curBuffer]);
gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
}
}
GLBatchJob.prototype.doSetColor = function ()
{
var s = this.glwrap.currentShader;
var mat4param = this.mat4param;
this.gl.uniform4f(s.locColorFill, mat4param[0], mat4param[1], mat4param[2], mat4param[3]);
};
GLBatchJob.prototype.doSetProgramParameters = function ()
{
var i, len, s = this.glwrap.currentShader;
var gl = this.gl;
var mat4param = this.mat4param;
if (s.locSamplerBack && this.glwrap.lastTexture1 !== this.texParam)
{
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, this.texParam);
this.glwrap.lastTexture1 = this.texParam;
gl.activeTexture(gl.TEXTURE0);
}
var v = mat4param[0];
var v2;
if (s.locPixelWidth && v !== s.lpPixelWidth)
{
s.lpPixelWidth = v;
gl.uniform1f(s.locPixelWidth, v);
}
v = mat4param[1];
if (s.locPixelHeight && v !== s.lpPixelHeight)
{
s.lpPixelHeight = v;
gl.uniform1f(s.locPixelHeight, v);
}
v = mat4param[2];
v2 = mat4param[3];
if (s.locDestStart && (v !== s.lpDestStartX || v2 !== s.lpDestStartY))
{
s.lpDestStartX = v;
s.lpDestStartY = v2;
gl.uniform2f(s.locDestStart, v, v2);
}
v = mat4param[4];
v2 = mat4param[5];
if (s.locDestEnd && (v !== s.lpDestEndX || v2 !== s.lpDestEndY))
{
s.lpDestEndX = v;
s.lpDestEndY = v2;
gl.uniform2f(s.locDestEnd, v, v2);
}
v = mat4param[6];
if (s.locLayerScale && v !== s.lpLayerScale)
{
s.lpLayerScale = v;
gl.uniform1f(s.locLayerScale, v);
}
v = mat4param[7];
if (s.locLayerAngle && v !== s.lpLayerAngle)
{
s.lpLayerAngle = v;
gl.uniform1f(s.locLayerAngle, v);
}
v = mat4param[8];
v2 = mat4param[9];
if (s.locViewOrigin && (v !== s.lpViewOriginX || v2 !== s.lpViewOriginY))
{
s.lpViewOriginX = v;
s.lpViewOriginY = v2;
gl.uniform2f(s.locViewOrigin, v, v2);
}
v = mat4param[10];
v2 = mat4param[11];
if (s.locScrollPos && (v !== s.lpScrollPosX || v2 !== s.lpScrollPosY))
{
s.lpScrollPosX = v;
s.lpScrollPosY = v2;
gl.uniform2f(s.locScrollPos, v, v2);
}
v = mat4param[12];
if (s.locSeconds && v !== s.lpSeconds)
{
s.lpSeconds = v;
gl.uniform1f(s.locSeconds, v);
}
if (s.parameters.length)
{
for (i = 0, len = s.parameters.length; i < len; i++)
{
v = this.shaderParams[i];
if (v !== s.lastCustomParams[i])
{
s.lastCustomParams[i] = v;
gl.uniform1f(s.parameters[i][1], v);
}
}
}
};
GLWrap_.prototype.pushBatch = function ()
{
if (this.batchPtr === this.batch.length)
this.batch.push(new GLBatchJob(BATCH_NULL, this));
return this.batch[this.batchPtr++];
};
GLWrap_.prototype.endBatch = function ()
{
if (this.batchPtr === 0)
return;
if (this.gl.isContextLost())
return;
var 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 (s && s.locAPos >= 0 && s.name === "<point>")
gl.vertexAttribPointer(s.locAPos, 4, gl.FLOAT, false, 0, 0);
}
if (this.vertexPtr > 0)
{
var s = this.currentShader;
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffers[this.curBuffer]);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexData.subarray(0, this.vertexPtr));
if (s && s.locAPos >= 0 && s.name !== "<point>")
gl.vertexAttribPointer(s.locAPos, this.enableFrontToBack ? 3 : 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffers[this.curBuffer]);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.texcoordData.subarray(0, this.texPtr));
if (s && s.locATex >= 0 && s.name !== "<point>")
gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
}
var i, len, b;
for (i = 0, len = this.batchPtr; i < len; i++)
{
b = this.batch[i];
switch (b.type) {
case 1:
b.doQuad();
break;
case 2:
b.doSetTexture();
break;
case 3:
b.doSetOpacity();
break;
case 4:
b.doSetBlend();
break;
case 5:
b.doUpdateModelView();
break;
case 6:
b.doRenderToTexture();
break;
case 7:
b.doClear();
break;
case 8:
b.doPoints();
break;
case 9:
b.doSetProgram();
break;
case 10:
b.doSetProgramParameters();
break;
case 11:
b.doSetTexture1();
break;
case 12:
b.doSetColor();
break;
case 13:
b.doSetDepthTestEnabled();
break;
case 14:
b.doSetEarlyZPass();
break;
}
}
this.batchPtr = 0;
this.vertexPtr = 0;
this.texPtr = 0;
this.pointPtr = 0;
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
this.isBatchInEarlyZPass = false;
this.curBuffer++;
if (this.curBuffer >= MULTI_BUFFERS)
this.curBuffer = 0;
};
GLWrap_.prototype.setOpacity = function (op)
{
if (op === this.lastOpacity)
return;
if (this.isEarlyZPass)
return; // ignore
var b = this.pushBatch();
b.type = BATCH_SETOPACITY;
b.opacityParam = op;
this.lastOpacity = op;
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
GLWrap_.prototype.setTexture = function (tex)
{
if (tex === this.lastTexture0)
return;
;
var b = this.pushBatch();
b.type = BATCH_SETTEXTURE;
b.texParam = tex;
this.lastTexture0 = tex;
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
GLWrap_.prototype.setBlend = function (s, d)
{
if (s === this.lastSrcBlend && d === this.lastDestBlend)
return;
if (this.isEarlyZPass)
return; // ignore
var b = this.pushBatch();
b.type = BATCH_SETBLEND;
b.startIndex = s; // recycle params to save memory
b.indexCount = d;
this.lastSrcBlend = s;
this.lastDestBlend = d;
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
GLWrap_.prototype.isPremultipliedAlphaBlend = function ()
{
return (this.lastSrcBlend === this.gl.ONE && this.lastDestBlend === this.gl.ONE_MINUS_SRC_ALPHA);
};
GLWrap_.prototype.setAlphaBlend = function ()
{
this.setBlend(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
};
GLWrap_.prototype.setNoPremultiplyAlphaBlend = function ()
{
this.setBlend(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
};
var LAST_VERTEX = MAX_VERTICES * 2 - 8;
GLWrap_.prototype.quad = function(tlx, tly, trx, try_, brx, bry, blx, bly)
{
if (this.vertexPtr >= LAST_VERTEX)
this.endBatch();
var v = this.vertexPtr; // vertex cursor
var t = this.texPtr;
var vd = this.vertexData; // vertex data array
var td = this.texcoordData; // texture coord data array
var currentZ = this.currentZ;
if (this.hasQuadBatchTop)
{
this.batch[this.batchPtr - 1].indexCount += 6;
}
else
{
var b = this.pushBatch();
b.type = BATCH_QUAD;
b.startIndex = this.enableFrontToBack ? v : (v / 2) * 3;
b.indexCount = 6;
this.hasQuadBatchTop = true;
this.hasPointBatchTop = false;
}
if (this.enableFrontToBack)
{
vd[v++] = tlx;
vd[v++] = tly;
vd[v++] = currentZ;
vd[v++] = trx;
vd[v++] = try_;
vd[v++] = currentZ;
vd[v++] = brx;
vd[v++] = bry;
vd[v++] = currentZ;
vd[v++] = blx;
vd[v++] = bly;
vd[v++] = currentZ;
}
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;
}
td[t++] = 0;
td[t++] = 0;
td[t++] = 1;
td[t++] = 0;
td[t++] = 1;
td[t++] = 1;
td[t++] = 0;
td[t++] = 1;
this.vertexPtr = v;
this.texPtr = t;
};
GLWrap_.prototype.quadTex = function(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex)
{
if (this.vertexPtr >= LAST_VERTEX)
this.endBatch();
var v = this.vertexPtr; // vertex cursor
var t = this.texPtr;
var vd = this.vertexData; // vertex data array
var td = this.texcoordData; // texture coord data array
var currentZ = this.currentZ;
if (this.hasQuadBatchTop)
{
this.batch[this.batchPtr - 1].indexCount += 6;
}
else
{
var b = this.pushBatch();
b.type = BATCH_QUAD;
b.startIndex = this.enableFrontToBack ? v : (v / 2) * 3;
b.indexCount = 6;
this.hasQuadBatchTop = true;
this.hasPointBatchTop = false;
}
var rc_left = rcTex.left;
var rc_top = rcTex.top;
var rc_right = rcTex.right;
var rc_bottom = rcTex.bottom;
if (this.enableFrontToBack)
{
vd[v++] = tlx;
vd[v++] = tly;
vd[v++] = currentZ;
vd[v++] = trx;
vd[v++] = try_;
vd[v++] = currentZ;
vd[v++] = brx;
vd[v++] = bry;
vd[v++] = currentZ;
vd[v++] = blx;
vd[v++] = bly;
vd[v++] = currentZ;
}
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;
}
td[t++] = rc_left;
td[t++] = rc_top;
td[t++] = rc_right;
td[t++] = rc_top;
td[t++] = rc_right;
td[t++] = rc_bottom;
td[t++] = rc_left;
td[t++] = rc_bottom;
this.vertexPtr = v;
this.texPtr = t;
};
GLWrap_.prototype.quadTexUV = function(tlx, tly, trx, try_, brx, bry, blx, bly, tlu, tlv, tru, trv, bru, brv, blu, blv)
{
if (this.vertexPtr >= LAST_VERTEX)
this.endBatch();
var v = this.vertexPtr; // vertex cursor
var t = this.texPtr;
var vd = this.vertexData; // vertex data array
var td = this.texcoordData; // texture coord data array
var currentZ = this.currentZ;
if (this.hasQuadBatchTop)
{
this.batch[this.batchPtr - 1].indexCount += 6;
}
else
{
var b = this.pushBatch();
b.type = BATCH_QUAD;
b.startIndex = this.enableFrontToBack ? v : (v / 2) * 3;
b.indexCount = 6;
this.hasQuadBatchTop = true;
this.hasPointBatchTop = false;
}
if (this.enableFrontToBack)
{
vd[v++] = tlx;
vd[v++] = tly;
vd[v++] = currentZ;
vd[v++] = trx;
vd[v++] = try_;
vd[v++] = currentZ;
vd[v++] = brx;
vd[v++] = bry;
vd[v++] = currentZ;
vd[v++] = blx;
vd[v++] = bly;
vd[v++] = currentZ;
}
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;
}
td[t++] = tlu;
td[t++] = tlv;
td[t++] = tru;
td[t++] = trv;
td[t++] = bru;
td[t++] = brv;
td[t++] = blu;
td[t++] = blv;
this.vertexPtr = v;
this.texPtr = t;
};
GLWrap_.prototype.convexPoly = function(pts)
{
var pts_count = pts.length / 2;
;
var tris = pts_count - 2; // 3 points = 1 tri, 4 points = 2 tris, 5 points = 3 tris etc.
var last_tri = tris - 1;
var p0x = pts[0];
var p0y = pts[1];
var i, i2, p1x, p1y, p2x, p2y, p3x, p3y;
for (i = 0; i < tris; i += 2) // draw 2 triangles at a time
{
i2 = i * 2;
p1x = pts[i2 + 2];
p1y = pts[i2 + 3];
p2x = pts[i2 + 4];
p2y = pts[i2 + 5];
if (i === last_tri)
{
this.quad(p0x, p0y, p1x, p1y, p2x, p2y, p2x, p2y);
}
else
{
p3x = pts[i2 + 6];
p3y = pts[i2 + 7];
this.quad(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y);
}
}
};
var LAST_POINT = MAX_POINTS - 4;
GLWrap_.prototype.point = function(x_, y_, size_, opacity_)
{
if (this.pointPtr >= LAST_POINT)
this.endBatch();
var p = this.pointPtr; // point cursor
var pd = this.pointData; // point data array
if (this.hasPointBatchTop)
{
this.batch[this.batchPtr - 1].indexCount++;
}
else
{
var b = this.pushBatch();
b.type = BATCH_POINTS;
b.startIndex = p;
b.indexCount = 1;
this.hasPointBatchTop = true;
this.hasQuadBatchTop = false;
}
pd[p++] = x_;
pd[p++] = y_;
pd[p++] = size_;
pd[p++] = opacity_;
this.pointPtr = p;
};
GLWrap_.prototype.switchProgram = function (progIndex)
{
if (this.lastProgram === progIndex)
return; // no change
var shaderProg = this.shaderPrograms[progIndex];
if (!shaderProg)
{
if (this.lastProgram === 0)
return; // already on default shader
progIndex = 0;
shaderProg = this.shaderPrograms[0];
}
var b = this.pushBatch();
b.type = BATCH_SETPROGRAM;
b.startIndex = progIndex;
this.lastProgram = progIndex;
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
GLWrap_.prototype.programUsesDest = function (progIndex)
{
var s = this.shaderPrograms[progIndex];
return !!(s.locDestStart || s.locDestEnd);
};
GLWrap_.prototype.programUsesCrossSampling = function (progIndex)
{
var s = this.shaderPrograms[progIndex];
return !!(s.locDestStart || s.locDestEnd || s.crossSampling);
};
GLWrap_.prototype.programPreservesOpaqueness = function (progIndex)
{
return this.shaderPrograms[progIndex].preservesOpaqueness;
};
GLWrap_.prototype.programExtendsBox = function (progIndex)
{
var s = this.shaderPrograms[progIndex];
return s.extendBoxHorizontal !== 0 || s.extendBoxVertical !== 0;
};
GLWrap_.prototype.getProgramBoxExtendHorizontal = function (progIndex)
{
return this.shaderPrograms[progIndex].extendBoxHorizontal;
};
GLWrap_.prototype.getProgramBoxExtendVertical = function (progIndex)
{
return this.shaderPrograms[progIndex].extendBoxVertical;
};
GLWrap_.prototype.getProgramParameterType = function (progIndex, paramIndex)
{
return this.shaderPrograms[progIndex].parameters[paramIndex][2];
};
GLWrap_.prototype.programIsAnimated = function (progIndex)
{
return this.shaderPrograms[progIndex].animated;
};
GLWrap_.prototype.setProgramParameters = function (backTex, pixelWidth, pixelHeight, destStartX, destStartY, destEndX, destEndY, layerScale, layerAngle, viewOriginLeft, viewOriginTop, scrollPosX, scrollPosY, seconds, params)
{
var i, len;
var s = this.shaderPrograms[this.lastProgram];
var b, mat4param, shaderParams;
if (s.hasAnyOptionalUniforms || params.length)
{
b = this.pushBatch();
b.type = BATCH_SETPROGRAMPARAMETERS;
if (b.mat4param)
mat4.set(this.matMV, b.mat4param);
else
b.mat4param = mat4.create();
mat4param = b.mat4param;
mat4param[0] = pixelWidth;
mat4param[1] = pixelHeight;
mat4param[2] = destStartX;
mat4param[3] = destStartY;
mat4param[4] = destEndX;
mat4param[5] = destEndY;
mat4param[6] = layerScale;
mat4param[7] = layerAngle;
mat4param[8] = viewOriginLeft;
mat4param[9] = viewOriginTop;
mat4param[10] = scrollPosX;
mat4param[11] = scrollPosY;
mat4param[12] = seconds;
if (s.locSamplerBack)
{
;
b.texParam = backTex;
}
else
b.texParam = null;
if (params.length)
{
shaderParams = b.shaderParams;
shaderParams.length = params.length;
for (i = 0, len = params.length; i < len; i++)
shaderParams[i] = params[i];
}
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
}
};
GLWrap_.prototype.clear = function (r, g, b_, a)
{
var b = this.pushBatch();
b.type = BATCH_CLEAR;
b.startIndex = 0; // clear all mode
if (!b.mat4param)
b.mat4param = mat4.create();
b.mat4param[0] = r;
b.mat4param[1] = g;
b.mat4param[2] = b_;
b.mat4param[3] = a;
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
GLWrap_.prototype.clearRect = function (x, y, w, h)
{
if (w < 0 || h < 0)
return; // invalid clear area
var b = this.pushBatch();
b.type = BATCH_CLEAR;
b.startIndex = 1; // clear rect mode
if (!b.mat4param)
b.mat4param = mat4.create();
b.mat4param[0] = x;
b.mat4param[1] = y;
b.mat4param[2] = w;
b.mat4param[3] = h;
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
GLWrap_.prototype.clearDepth = function ()
{
var b = this.pushBatch();
b.type = BATCH_CLEAR;
b.startIndex = 2; // clear depth mode
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
GLWrap_.prototype.setEarlyZPass = function (e)
{
if (!this.enableFrontToBack)
return; // no depth buffer in use
e = !!e;
if (this.isEarlyZPass === e)
return; // no change
var b = this.pushBatch();
b.type = BATCH_SETEARLYZMODE;
b.startIndex = (e ? 1 : 0);
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
this.isEarlyZPass = e;
this.renderToTex = null;
if (this.isEarlyZPass)
{
this.switchProgram(2); // early Z program
}
else
{
this.switchProgram(0); // normal rendering
}
};
GLWrap_.prototype.setDepthTestEnabled = function (e)
{
if (!this.enableFrontToBack)
return; // no depth buffer in use
var b = this.pushBatch();
b.type = BATCH_SETDEPTHTEST;
b.startIndex = (e ? 1 : 0);
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
GLWrap_.prototype.fullscreenQuad = function ()
{
mat4.set(this.lastMV, tempMat4);
this.resetModelView();
this.updateModelView();
var halfw = this.width / 2;
var halfh = this.height / 2;
this.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
mat4.set(tempMat4, this.matMV);
this.updateModelView();
};
GLWrap_.prototype.setColorFillMode = function (r_, g_, b_, a_)
{
this.switchProgram(3);
var b = this.pushBatch();
b.type = BATCH_SETCOLOR;
if (!b.mat4param)
b.mat4param = mat4.create();
b.mat4param[0] = r_;
b.mat4param[1] = g_;
b.mat4param[2] = b_;
b.mat4param[3] = a_;
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
GLWrap_.prototype.setTextureFillMode = function ()
{
;
this.switchProgram(0);
};
GLWrap_.prototype.restoreEarlyZMode = function ()
{
;
this.switchProgram(2);
};
GLWrap_.prototype.present = function ()
{
this.endBatch();
this.gl.flush();
/*
if (debugBatch)
{
;
debugBatch = false;
}
*/
};
function nextHighestPowerOfTwo(x) {
--x;
for (var i = 1; i < 32; i <<= 1) {
x = x | x >> i;
}
return x + 1;
}
var all_textures = [];
var textures_by_src = {};
GLWrap_.prototype.contextLost = function ()
{
cr.clearArray(all_textures);
textures_by_src = {};
};
var BF_RGBA8 = 0;
var BF_RGB8 = 1;
var BF_RGBA4 = 2;
var BF_RGB5_A1 = 3;
var BF_RGB565 = 4;
GLWrap_.prototype.loadTexture = function (img, tiling, linearsampling, pixelformat, tiletype, nomip)
{
tiling = !!tiling;
linearsampling = !!linearsampling;
var tex_key = img.src + "," + tiling + "," + linearsampling + (tiling ? ("," + tiletype) : "");
var webGL_texture = null;
if (typeof img.src !== "undefined" && textures_by_src.hasOwnProperty(tex_key))
{
webGL_texture = textures_by_src[tex_key];
webGL_texture.c2refcount++;
return webGL_texture;
}
this.endBatch();
;
var gl = this.gl;
var isPOT = (cr.isPOT(img.width) && cr.isPOT(img.height));
webGL_texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, webGL_texture);
gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], true);
var internalformat = gl.RGBA;
var format = gl.RGBA;
var type = gl.UNSIGNED_BYTE;
if (pixelformat && !this.isIE)
{
switch (pixelformat) {
case BF_RGB8:
internalformat = gl.RGB;
format = gl.RGB;
break;
case BF_RGBA4:
type = gl.UNSIGNED_SHORT_4_4_4_4;
break;
case BF_RGB5_A1:
type = gl.UNSIGNED_SHORT_5_5_5_1;
break;
case BF_RGB565:
internalformat = gl.RGB;
format = gl.RGB;
type = gl.UNSIGNED_SHORT_5_6_5;
break;
}
}
if (this.version === 1 && !isPOT && tiling)
{
var canvas = document.createElement("canvas");
canvas.width = cr.nextHighestPowerOfTwo(img.width);
canvas.height = cr.nextHighestPowerOfTwo(img.height);
var ctx = canvas.getContext("2d");
if (typeof ctx["imageSmoothingEnabled"] !== "undefined")
{
ctx["imageSmoothingEnabled"] = linearsampling;
}
else
{
ctx["webkitImageSmoothingEnabled"] = linearsampling;
ctx["mozImageSmoothingEnabled"] = linearsampling;
ctx["msImageSmoothingEnabled"] = linearsampling;
}
ctx.drawImage(img,
0, 0, img.width, img.height,
0, 0, canvas.width, canvas.height);
gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, canvas);
}
else
gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, img);
if (tiling)
{
if (tiletype === "repeat-x")
{
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
else if (tiletype === "repeat-y")
{
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
}
else
{
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
}
}
else
{
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
if (linearsampling)
{
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
if ((isPOT || this.version >= 2) && this.enable_mipmaps && !nomip)
{
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.generateMipmap(gl.TEXTURE_2D);
}
else
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
}
else
{
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
}
gl.bindTexture(gl.TEXTURE_2D, null);
this.lastTexture0 = null;
webGL_texture.c2width = img.width;
webGL_texture.c2height = img.height;
webGL_texture.c2refcount = 1;
webGL_texture.c2texkey = tex_key;
all_textures.push(webGL_texture);
textures_by_src[tex_key] = webGL_texture;
return webGL_texture;
};
GLWrap_.prototype.createEmptyTexture = function (w, h, linearsampling, _16bit, tiling)
{
this.endBatch();
var gl = this.gl;
if (this.isIE)
_16bit = false;
var webGL_texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, webGL_texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, _16bit ? gl.UNSIGNED_SHORT_4_4_4_4 : gl.UNSIGNED_BYTE, null);
if (tiling)
{
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
}
else
{
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, linearsampling ? gl.LINEAR : gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linearsampling ? gl.LINEAR : gl.NEAREST);
gl.bindTexture(gl.TEXTURE_2D, null);
this.lastTexture0 = null;
webGL_texture.c2width = w;
webGL_texture.c2height = h;
all_textures.push(webGL_texture);
return webGL_texture;
};
GLWrap_.prototype.videoToTexture = function (video_, texture_, _16bit)
{
this.endBatch();
var gl = this.gl;
if (this.isIE)
_16bit = false;
gl.bindTexture(gl.TEXTURE_2D, texture_);
gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], true);
try {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, _16bit ? gl.UNSIGNED_SHORT_4_4_4_4 : gl.UNSIGNED_BYTE, video_);
}
catch (e)
{
if (console && console.error)
console.error("Error updating WebGL texture: ", e);
}
gl.bindTexture(gl.TEXTURE_2D, null);
this.lastTexture0 = null;
};
GLWrap_.prototype.deleteTexture = function (tex)
{
if (!tex)
return;
if (typeof tex.c2refcount !== "undefined" && tex.c2refcount > 1)
{
tex.c2refcount--;
return;
}
this.endBatch();
if (tex === this.lastTexture0)
{
this.gl.bindTexture(this.gl.TEXTURE_2D, null);
this.lastTexture0 = null;
}
if (tex === 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;
}
cr.arrayFindRemove(all_textures, tex);
if (typeof tex.c2texkey !== "undefined")
delete textures_by_src[tex.c2texkey];
this.gl.deleteTexture(tex);
};
GLWrap_.prototype.estimateVRAM = function ()
{
var total = this.width * this.height * 4 * 2;
var i, len, t;
for (i = 0, len = all_textures.length; i < len; i++)
{
t = all_textures[i];
total += (t.c2width * t.c2height * 4);
}
return total;
};
GLWrap_.prototype.textureCount = function ()
{
return all_textures.length;
};
GLWrap_.prototype.setRenderingToTexture = function (tex)
{
if (tex === this.renderToTex)
return;
;
var b = this.pushBatch();
b.type = BATCH_RENDERTOTEXTURE;
b.texParam = tex;
this.renderToTex = tex;
this.hasQuadBatchTop = false;
this.hasPointBatchTop = false;
};
cr.GLWrap = GLWrap_;
}());
;
(function()
{
var raf = window["requestAnimationFrame"] ||
window["mozRequestAnimationFrame"] ||
window["webkitRequestAnimationFrame"] ||
window["msRequestAnimationFrame"] ||
window["oRequestAnimationFrame"];
function Runtime(canvas)
{
if (!canvas || (!canvas.getContext && !canvas["dc"]))
return;
if (canvas["c2runtime"])
return;
else
canvas["c2runtime"] = this;
var self = this;
this.isCrosswalk = /crosswalk/i.test(navigator.userAgent) || /xwalk/i.test(navigator.userAgent) || !!(typeof window["c2isCrosswalk"] !== "undefined" && window["c2isCrosswalk"]);
this.isCordova = this.isCrosswalk || (typeof window["device"] !== "undefined" && (typeof window["device"]["cordova"] !== "undefined" || typeof window["device"]["phonegap"] !== "undefined")) || (typeof window["c2iscordova"] !== "undefined" && window["c2iscordova"]);
this.isPhoneGap = this.isCordova;
this.isDirectCanvas = !!canvas["dc"];
this.isAppMobi = (typeof window["AppMobi"] !== "undefined" || this.isDirectCanvas);
this.isCocoonJs = !!window["c2cocoonjs"];
this.isEjecta = !!window["c2ejecta"];
if (this.isCocoonJs)
{
CocoonJS["App"]["onSuspended"].addEventListener(function() {
self["setSuspended"](true);
});
CocoonJS["App"]["onActivated"].addEventListener(function () {
self["setSuspended"](false);
});
}
if (this.isEjecta)
{
document.addEventListener("pagehide", function() {
self["setSuspended"](true);
});
document.addEventListener("pageshow", function() {
self["setSuspended"](false);
});
document.addEventListener("resize", function () {
self["setSize"](window.innerWidth, window.innerHeight);
});
}
this.isDomFree = (this.isDirectCanvas || this.isCocoonJs || this.isEjecta);
this.isMicrosoftEdge = /edge\//i.test(navigator.userAgent);
this.isIE = (/msie/i.test(navigator.userAgent) || /trident/i.test(navigator.userAgent) || /iemobile/i.test(navigator.userAgent)) && !this.isMicrosoftEdge;
this.isTizen = /tizen/i.test(navigator.userAgent);
this.isAndroid = /android/i.test(navigator.userAgent) && !this.isTizen && !this.isIE && !this.isMicrosoftEdge; // IE mobile and Tizen masquerade as Android
this.isiPhone = (/iphone/i.test(navigator.userAgent) || /ipod/i.test(navigator.userAgent)) && !this.isIE && !this.isMicrosoftEdge; // treat ipod as an iphone; IE mobile masquerades as iPhone
this.isiPad = /ipad/i.test(navigator.userAgent);
this.isiPadMacitosh = /macintosh/i.test(navigator.userAgent) && this.isCordova;
this.isiOS = this.isiPhone || this.isiPad || this.isEjecta || this.isiPadMacitosh;
this.isiPhoneiOS6 = (this.isiPhone && /os\s6/i.test(navigator.userAgent));
this.isChrome = (/chrome/i.test(navigator.userAgent) || /chromium/i.test(navigator.userAgent)) && !this.isIE && !this.isMicrosoftEdge; // note true on Chromium-based webview on Android 4.4+; IE 'Edge' mode also pretends to be Chrome
this.isAmazonWebApp = /amazonwebappplatform/i.test(navigator.userAgent);
this.isFirefox = /firefox/i.test(navigator.userAgent);
this.isSafari = /safari/i.test(navigator.userAgent) && !this.isChrome && !this.isIE && !this.isMicrosoftEdge; // Chrome and IE Mobile masquerade as Safari
this.isWindows = /windows/i.test(navigator.userAgent);
this.isNWjs = (typeof window["c2nodewebkit"] !== "undefined" || typeof window["c2nwjs"] !== "undefined" || /nodewebkit/i.test(navigator.userAgent) || /nwjs/i.test(navigator.userAgent));
this.isNodeWebkit = this.isNWjs; // old name for backwards compat
this.isArcade = (typeof window["is_scirra_arcade"] !== "undefined");
this.isWindows8App = !!(typeof window["c2isWindows8"] !== "undefined" && window["c2isWindows8"]);
this.isWindows8Capable = !!(typeof window["c2isWindows8Capable"] !== "undefined" && window["c2isWindows8Capable"]);
this.isWindowsPhone8 = !!(typeof window["c2isWindowsPhone8"] !== "undefined" && window["c2isWindowsPhone8"]);
this.isWindowsPhone81 = !!(typeof window["c2isWindowsPhone81"] !== "undefined" && window["c2isWindowsPhone81"]);
this.isWindows10 = !!window["cr_windows10"];
this.isWinJS = (this.isWindows8App || this.isWindows8Capable || this.isWindowsPhone81 || this.isWindows10); // note not WP8.0
this.isBlackberry10 = !!(typeof window["c2isBlackberry10"] !== "undefined" && window["c2isBlackberry10"]);
this.isAndroidStockBrowser = (this.isAndroid && !this.isChrome && !this.isCrosswalk && !this.isFirefox && !this.isAmazonWebApp && !this.isDomFree);
this.devicePixelRatio = 1;
this.isMobile = (this.isCordova || this.isCrosswalk || this.isAppMobi || this.isCocoonJs || this.isAndroid || this.isiOS || this.isWindowsPhone8 || this.isWindowsPhone81 || this.isBlackberry10 || this.isTizen || this.isEjecta);
if (!this.isMobile)
{
this.isMobile = /(blackberry|bb10|playbook|palm|symbian|nokia|windows\s+ce|phone|mobile|tablet|kindle|silk)/i.test(navigator.userAgent);
}
this.isWKWebView = !!(this.isiOS && this.isCordova && window["webkit"]);
if (typeof cr_is_preview !== "undefined" && !this.isNWjs && (window.location.search === "?nw" || /nodewebkit/i.test(navigator.userAgent) || /nwjs/i.test(navigator.userAgent)))
{
this.isNWjs = true;
}
this.isDebug = (typeof cr_is_preview !== "undefined" && window.location.search.indexOf("debug") > -1);
this.canvas = canvas;
this.canvasdiv = document.getElementById("c2canvasdiv");
this.gl = null;
this.glwrap = null;
this.glUnmaskedRenderer = "(unavailable)";
this.enableFrontToBack = false;
this.earlyz_index = 0;
this.ctx = null;
this.firstInFullscreen = false;
this.oldWidth = 0; // for restoring non-fullscreen canvas after fullscreen
this.oldHeight = 0;
this.canvas.oncontextmenu = function (e) { if (e.preventDefault) e.preventDefault(); return false; };
this.canvas.onselectstart = function (e) { if (e.preventDefault) e.preventDefault(); return false; };
this.canvas.ontouchstart = function (e) { if(e.preventDefault) e.preventDefault(); return false; };
if (this.isDirectCanvas)
window["c2runtime"] = this;
if (this.isNWjs)
{
window["ondragover"] = function(e) { e.preventDefault(); return false; };
window["ondrop"] = function(e) { e.preventDefault(); return false; };
if (window["nwgui"] && window["nwgui"]["App"]["clearCache"])
window["nwgui"]["App"]["clearCache"]();
}
if (this.isAndroidStockBrowser && typeof jQuery !== "undefined")
{
jQuery("canvas").parents("*").css("overflow", "visible");
}
this.width = canvas.width;
this.height = canvas.height;
this.draw_width = this.width;
this.draw_height = this.height;
this.cssWidth = this.width;
this.cssHeight = this.height;
this.lastWindowWidth = window.innerWidth;
this.lastWindowHeight = window.innerHeight;
this.forceCanvasAlpha = false; // note: now unused, left for backwards compat since plugins could modify it
this.redraw = true;
this.isSuspended = false;
if (!Date.now) {
Date.now = function now() {
return +new Date();
};
}
this.plugins = [];
this.types = {};
this.types_by_index = [];
this.behaviors = [];
this.layouts = {};
this.layouts_by_index = [];
this.eventsheets = {};
this.eventsheets_by_index = [];
this.wait_for_textures = []; // for blocking until textures loaded
this.triggers_to_postinit = [];
this.all_global_vars = [];
this.all_local_vars = [];
this.solidBehavior = null;
this.jumpthruBehavior = null;
this.shadowcasterBehavior = null;
this.deathRow = {};
this.hasPendingInstances = false; // true if anything exists in create row or death row
this.isInClearDeathRow = false;
this.isInOnDestroy = 0; // needs to support recursion so increments and decrements and is true if > 0
this.isRunningEvents = false;
this.isEndingLayout = false;
this.createRow = [];
this.isLoadingState = false;
this.saveToSlot = "";
this.loadFromSlot = "";
this.loadFromJson = null; // set to string when there is something to try to load
this.lastSaveJson = "";
this.signalledContinuousPreview = false;
this.suspendDrawing = false; // for hiding display until continuous preview loads
this.fireOnCreateAfterLoad = []; // for delaying "On create" triggers until loading complete
this.dt = 0;
this.dt1 = 0;
this.minimumFramerate = 30;
this.logictime = 0; // used to calculate CPUUtilisation
this.cpuutilisation = 0;
this.timescale = 1.0;
this.kahanTime = new cr.KahanAdder();
this.wallTime = new cr.KahanAdder();
this.last_tick_time = 0;
this.fps = 0;
this.last_fps_time = 0;
this.tickcount = 0;
this.tickcount_nosave = 0; // same as tickcount but never saved/loaded
this.execcount = 0;
this.framecount = 0; // for fps
this.objectcount = 0;
this.changelayout = null;
this.destroycallbacks = [];
this.event_stack = [];
this.event_stack_index = -1;
this.localvar_stack = [[]];
this.localvar_stack_index = 0;
this.trigger_depth = 0; // recursion depth for triggers
this.pushEventStack(null);
this.loop_stack = [];
this.loop_stack_index = -1;
this.next_uid = 0;
this.next_puid = 0; // permanent unique ids
this.layout_first_tick = true;
this.family_count = 0;
this.suspend_events = [];
this.raf_id = -1;
this.timeout_id = -1;
this.isloading = true;
this.loadingprogress = 0;
this.isNodeFullscreen = false;
this.stackLocalCount = 0; // number of stack-based local vars for recursion
this.audioInstance = null;
this.had_a_click = false;
this.isInUserInputEvent = false;
this.objects_to_pretick = new cr.ObjectSet();
this.objects_to_tick = new cr.ObjectSet();
this.objects_to_tick2 = new cr.ObjectSet();
this.registered_collisions = [];
this.temp_poly = new cr.CollisionPoly([]);
this.temp_poly2 = new cr.CollisionPoly([]);
this.allGroups = []; // array of all event groups
this.groups_by_name = {};
this.cndsBySid = {};
this.actsBySid = {};
this.varsBySid = {};
this.blocksBySid = {};
this.running_layout = null; // currently running layout
this.layer_canvas = null; // for layers "render-to-texture"
this.layer_ctx = null;
this.layer_tex = null;
this.layout_tex = null;
this.layout_canvas = null;
this.layout_ctx = null;
this.is_WebGL_context_lost = false;
this.uses_background_blending = false; // if any shader uses background blending, so entire layout renders to texture
this.fx_tex = [null, null];
this.fullscreen_scaling = 0;
this.files_subfolder = ""; // path with project files
this.objectsByUid = {}; // maps every in-use UID (as a string) to its instance
this.loaderlogos = null;
this.snapshotCanvas = null;
this.snapshotData = "";
this.objectRefTable = [];
this.requestProjectData();
};
Runtime.prototype.requestProjectData = function ()
{
var self = this;
if (this.isWKWebView)
{
this.fetchLocalFileViaCordovaAsText("data.js", function (str)
{
self.loadProject(JSON.parse(str));
}, function (err)
{
alert("Error fetching data.js");
});
return;
}
var xhr;
if (this.isWindowsPhone8)
xhr = new ActiveXObject("Microsoft.XMLHTTP");
else
xhr = new XMLHttpRequest();
var datajs_filename = "data.js";
if (typeof window['NSG_G_VER'] !== 'undefined')
{
datajs_filename += '?' + window['NSG_G_VER'];
}
if (this.isWindows8App || this.isWindowsPhone8 || this.isWindowsPhone81 || this.isWindows10)
datajs_filename = "data.json";
xhr.open("GET", datajs_filename, true);
var supportsJsonResponse = false;
if (!this.isDomFree && ("response" in xhr) && ("responseType" in xhr))
{
try {
xhr["responseType"] = "json";
supportsJsonResponse = (xhr["responseType"] === "json");
}
catch (e) {
supportsJsonResponse = false;
}
}
if (!supportsJsonResponse && ("responseType" in xhr))
{
try {
xhr["responseType"] = "text";
}
catch (e) {}
}
if ("overrideMimeType" in xhr)
{
try {
xhr["overrideMimeType"]("application/json; charset=utf-8");
}
catch (e) {}
}
if (this.isWindowsPhone8)
{
xhr.onreadystatechange = function ()
{
if (xhr.readyState !== 4)
return;
self.loadProject(JSON.parse(xhr["responseText"]));
};
}
else
{
xhr.onload = function ()
{
if (supportsJsonResponse)
{
self.loadProject(xhr["response"]); // already parsed by browser
}
else
{
if (self.isEjecta)
{
var str = xhr["responseText"];
str = str.substr(str.indexOf("{")); // trim any BOM
self.loadProject(JSON.parse(str));
}
else
{
self.loadProject(JSON.parse(xhr["responseText"])); // forced to sync parse JSON
}
}
};
xhr.onerror = function (e)
{
cr.logerror("Error requesting " + datajs_filename + ":");
cr.logerror(e);
};
}
xhr.send();
};
Runtime.prototype.initRendererAndLoader = function ()
{
var self = this;
var i, len, j, lenj, k, lenk, t, s, l, y;
this.isRetina = ((!this.isDomFree || this.isEjecta || this.isCordova) && this.useHighDpi && !this.isAndroidStockBrowser);
if (this.fullscreen_mode === 0 && this.isiOS)
this.isRetina = false;
this.devicePixelRatio = (this.isRetina ? (window["devicePixelRatio"] || window["webkitDevicePixelRatio"] || window["mozDevicePixelRatio"] || window["msDevicePixelRatio"] || 1) : 1);
if (typeof window["StatusBar"] === "object")
window["StatusBar"]["hide"]();
this.ClearDeathRow();
var attribs;
if (this.fullscreen_mode > 0)
this["setSize"](window.innerWidth, window.innerHeight, true);
this.canvas.addEventListener("webglcontextlost", function (ev) {
ev.preventDefault();
self.onContextLost();
cr.logexport("[Construct 2] WebGL context lost");
window["cr_setSuspended"](true); // stop rendering
}, false);
this.canvas.addEventListener("webglcontextrestored", function (ev) {
self.glwrap.initState();
self.glwrap.setSize(self.glwrap.width, self.glwrap.height, true);
self.layer_tex = null;
self.layout_tex = null;
self.fx_tex[0] = null;
self.fx_tex[1] = null;
self.onContextRestored();
self.redraw = true;
cr.logexport("[Construct 2] WebGL context restored");
window["cr_setSuspended"](false); // resume rendering
}, false);
try {
if (this.enableWebGL && (this.isCocoonJs || this.isEjecta || !this.isDomFree))
{
attribs = {
"alpha": true,
"depth": false,
"antialias": false,
"powerPreference": "high-performance",
"failIfMajorPerformanceCaveat": true
};
if (!this.isAndroid)
this.gl = this.canvas.getContext("webgl2", attribs);
if (!this.gl)
{
this.gl = (this.canvas.getContext("webgl", attribs) ||
this.canvas.getContext("experimental-webgl", attribs));
}
}
}
catch (e) {
}
if (this.gl)
{
var isWebGL2 = (this.gl.getParameter(this.gl.VERSION).indexOf("WebGL 2") === 0);
var debug_ext = this.gl.getExtension("WEBGL_debug_renderer_info");
if (debug_ext)
{
var unmasked_vendor = this.gl.getParameter(debug_ext.UNMASKED_VENDOR_WEBGL);
var unmasked_renderer = this.gl.getParameter(debug_ext.UNMASKED_RENDERER_WEBGL);
this.glUnmaskedRenderer = unmasked_renderer + " [" + unmasked_vendor + "]";
}
if (this.enableFrontToBack)
this.glUnmaskedRenderer += " [front-to-back enabled]";
;
if (!this.isDomFree)
{
this.overlay_canvas = document.createElement("canvas");
jQuery(this.overlay_canvas).appendTo(this.canvas.parentNode);
this.overlay_canvas.oncontextmenu = function (e) { return false; };
this.overlay_canvas.onselectstart = function (e) { return false; };
this.overlay_canvas.width = Math.round(this.cssWidth * this.devicePixelRatio);
this.overlay_canvas.height = Math.round(this.cssHeight * this.devicePixelRatio);
jQuery(this.overlay_canvas).css({"width": this.cssWidth + "px",
"height": this.cssHeight + "px"});
this.positionOverlayCanvas();
this.overlay_ctx = this.overlay_canvas.getContext("2d");
}
this.glwrap = new cr.GLWrap(this.gl, this.isMobile, this.enableFrontToBack);
this.glwrap.setSize(this.canvas.width, this.canvas.height);
this.glwrap.enable_mipmaps = (this.downscalingQuality !== 0);
this.ctx = null;
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
t = this.types_by_index[i];
for (j = 0, lenj = t.effect_types.length; j < lenj; j++)
{
s = t.effect_types[j];
s.shaderindex = this.glwrap.getShaderIndex(s.id);
s.preservesOpaqueness = this.glwrap.programPreservesOpaqueness(s.shaderindex);
this.uses_background_blending = this.uses_background_blending || this.glwrap.programUsesDest(s.shaderindex);
}
}
for (i = 0, len = this.layouts_by_index.length; i < len; i++)
{
l = this.layouts_by_index[i];
for (j = 0, lenj = l.effect_types.length; j < lenj; j++)
{
s = l.effect_types[j];
s.shaderindex = this.glwrap.getShaderIndex(s.id);
s.preservesOpaqueness = this.glwrap.programPreservesOpaqueness(s.shaderindex);
}
l.updateActiveEffects(); // update preserves opaqueness flag
for (j = 0, lenj = l.layers.length; j < lenj; j++)
{
y = l.layers[j];
for (k = 0, lenk = y.effect_types.length; k < lenk; k++)
{
s = y.effect_types[k];
s.shaderindex = this.glwrap.getShaderIndex(s.id);
s.preservesOpaqueness = this.glwrap.programPreservesOpaqueness(s.shaderindex);
this.uses_background_blending = this.uses_background_blending || this.glwrap.programUsesDest(s.shaderindex);
}
y.updateActiveEffects(); // update preserves opaqueness flag
}
}
}
else
{
if (this.fullscreen_mode > 0 && this.isDirectCanvas)
{
;
this.canvas = null;
document.oncontextmenu = function (e) { return false; };
document.onselectstart = function (e) { return false; };
this.ctx = AppMobi["canvas"]["getContext"]("2d");
try {
this.ctx["samplingMode"] = this.linearSampling ? "smooth" : "sharp";
this.ctx["globalScale"] = 1;
this.ctx["HTML5CompatibilityMode"] = true;
this.ctx["imageSmoothingEnabled"] = this.linearSampling;
} catch(e){}
if (this.width !== 0 && this.height !== 0)
{
this.ctx.width = this.width;
this.ctx.height = this.height;
}
}
if (!this.ctx)
{
;
if (this.isCocoonJs)
{
attribs = {
"antialias": !!this.linearSampling,
"alpha": true
};
this.ctx = this.canvas.getContext("2d", attribs);
}
else
{
attribs = {
"alpha": true
};
this.ctx = this.canvas.getContext("2d", attribs);
}
this.setCtxImageSmoothingEnabled(this.ctx, this.linearSampling);
}
this.overlay_canvas = null;
this.overlay_ctx = null;
}
this.tickFunc = function (timestamp) { self.tick(false, timestamp); };
if (window != window.top && !this.isDomFree && !this.isWinJS && !this.isWindowsPhone8)
{
document.addEventListener("mousedown", function () {
window.focus();
}, true);
document.addEventListener("touchstart", function () {
window.focus();
}, true);
}
if (typeof cr_is_preview !== "undefined")
{
if (this.isCocoonJs)
console.log("[Construct 2] In preview-over-wifi via CocoonJS mode");
if (window.location.search.indexOf("continuous") > -1)
{
cr.logexport("Reloading for continuous preview");
this.loadFromSlot = "__c2_continuouspreview";
this.suspendDrawing = true;
}
if (this.pauseOnBlur && !this.isMobile)
{
jQuery(window).focus(function ()
{
self["setSuspended"](false);
});
jQuery(window).blur(function ()
{
var parent = window.parent;
if (!parent || !parent.document.hasFocus())
self["setSuspended"](true);
});
}
}
window.addEventListener("blur", function () {
self.onWindowBlur();
});
if (!this.isDomFree)
{
var unfocusFormControlFunc = function (e) {
if (cr.isCanvasInputEvent(e) && document["activeElement"] && document["activeElement"] !== document.getElementsByTagName("body")[0] && document["activeElement"].blur)
{
try {
document["activeElement"].blur();
}
catch (e) {}
}
}
if (typeof PointerEvent !== "undefined")
{
document.addEventListener("pointerdown", unfocusFormControlFunc);
}
else if (window.navigator["msPointerEnabled"])
{
document.addEventListener("MSPointerDown", unfocusFormControlFunc);
}
else
{
document.addEventListener("touchstart", unfocusFormControlFunc);
}
document.addEventListener("mousedown", unfocusFormControlFunc);
}
if (this.fullscreen_mode === 0 && this.isRetina && this.devicePixelRatio > 1)
{
this["setSize"](this.original_width, this.original_height, true);
}
this.tryLockOrientation();
this.getready(); // determine things to preload
this.go(); // run loading screen
this.extra = {};
cr.seal(this);
};
var webkitRepaintFlag = false;
Runtime.prototype["setSize"] = function (w, h, force)
{
var offx = 0, offy = 0;
var neww = 0, newh = 0, intscale = 0;
if (this.lastWindowWidth === w && this.lastWindowHeight === h && !force)
return;
this.lastWindowWidth = w;
this.lastWindowHeight = h;
var mode = this.fullscreen_mode;
var orig_aspect, cur_aspect;
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.isNodeFullscreen) && !this.isCordova;
if (!isfullscreen && this.fullscreen_mode === 0 && !force)
return; // ignore size events when not fullscreen and not using a fullscreen-in-browser mode
if (isfullscreen)
mode = this.fullscreen_scaling;
var dpr = this.devicePixelRatio;
if (mode >= 4)
{
if (mode === 5 && dpr !== 1) // integer scaling
{
w += 1;
h += 1;
}
orig_aspect = this.original_width / this.original_height;
cur_aspect = w / h;
if (cur_aspect > orig_aspect)
{
neww = h * orig_aspect;
if (mode === 5) // integer scaling
{
intscale = (neww * dpr) / this.original_width;
if (intscale > 1)
intscale = Math.floor(intscale);
else if (intscale < 1)
intscale = 1 / Math.ceil(1 / intscale);
neww = this.original_width * intscale / dpr;
newh = this.original_height * intscale / dpr;
offx = (w - neww) / 2;
offy = (h - newh) / 2;
w = neww;
h = newh;
}
else
{
offx = (w - neww) / 2;
w = neww;
}
}
else
{
newh = w / orig_aspect;
if (mode === 5) // integer scaling
{
intscale = (newh * dpr) / this.original_height;
if (intscale > 1)
intscale = Math.floor(intscale);
else if (intscale < 1)
intscale = 1 / Math.ceil(1 / intscale);
neww = this.original_width * intscale / dpr;
newh = this.original_height * intscale / dpr;
offx = (w - neww) / 2;
offy = (h - newh) / 2;
w = neww;
h = newh;
}
else
{
offy = (h - newh) / 2;
h = newh;
}
}
}
else if (isfullscreen && mode === 0)
{
offx = Math.floor((w - this.original_width) / 2);
offy = Math.floor((h - this.original_height) / 2);
w = this.original_width;
h = this.original_height;
}
if (mode < 2)
this.aspect_scale = dpr;
this.cssWidth = Math.round(w);
this.cssHeight = Math.round(h);
this.width = Math.round(w * dpr);
this.height = Math.round(h * dpr);
this.redraw = true;
if (this.wantFullscreenScalingQuality)
{
this.draw_width = this.width;
this.draw_height = this.height;
this.fullscreenScalingQuality = true;
}
else
{
if ((this.width < this.original_width && this.height < this.original_height) || mode === 1)
{
this.draw_width = this.width;
this.draw_height = this.height;
this.fullscreenScalingQuality = true;
}
else
{
this.draw_width = this.original_width;
this.draw_height = this.original_height;
this.fullscreenScalingQuality = false;
/*var orig_aspect = this.original_width / this.original_height;
var cur_aspect = this.width / this.height;
if ((this.fullscreen_mode !== 2 && cur_aspect > orig_aspect) || (this.fullscreen_mode === 2 && cur_aspect < orig_aspect))
this.aspect_scale = this.height / this.original_height;
else
this.aspect_scale = this.width / this.original_width;*/
if (mode === 2) // scale inner
{
orig_aspect = this.original_width / this.original_height;
cur_aspect = this.lastWindowWidth / this.lastWindowHeight;
if (cur_aspect < orig_aspect)
this.draw_width = this.draw_height * cur_aspect;
else if (cur_aspect > orig_aspect)
this.draw_height = this.draw_width / cur_aspect;
}
else if (mode === 3)
{
orig_aspect = this.original_width / this.original_height;
cur_aspect = this.lastWindowWidth / this.lastWindowHeight;
if (cur_aspect > orig_aspect)
this.draw_width = this.draw_height * cur_aspect;
else if (cur_aspect < orig_aspect)
this.draw_height = this.draw_width / cur_aspect;
}
}
}
if (this.canvasdiv && !this.isDomFree)
{
jQuery(this.canvasdiv).css({"width": Math.round(w) + "px",
"height": Math.round(h) + "px",
"margin-left": Math.floor(offx) + "px",
"margin-top": Math.floor(offy) + "px"});
if (typeof cr_is_preview !== "undefined")
{
jQuery("#borderwrap").css({"width": Math.round(w) + "px",
"height": Math.round(h) + "px"});
}
}
if (this.canvas)
{
this.canvas.width = Math.round(w * dpr);
this.canvas.height = Math.round(h * dpr);
if (this.isEjecta)
{
this.canvas.style.left = Math.floor(offx) + "px";
this.canvas.style.top = Math.floor(offy) + "px";
this.canvas.style.width = Math.round(w) + "px";
this.canvas.style.height = Math.round(h) + "px";
}
else if (this.isRetina && !this.isDomFree)
{
this.canvas.style.width = Math.round(w) + "px";
this.canvas.style.height = Math.round(h) + "px";
}
}
if (this.overlay_canvas)
{
this.overlay_canvas.width = Math.round(w * dpr);
this.overlay_canvas.height = Math.round(h * dpr);
this.overlay_canvas.style.width = this.cssWidth + "px";
this.overlay_canvas.style.height = this.cssHeight + "px";
}
if (this.glwrap)
{
this.glwrap.setSize(Math.round(w * dpr), Math.round(h * dpr));
}
if (this.isDirectCanvas && this.ctx)
{
this.ctx.width = Math.round(w);
this.ctx.height = Math.round(h);
}
if (this.ctx)
{
this.setCtxImageSmoothingEnabled(this.ctx, this.linearSampling);
}
this.tryLockOrientation();
if (this.isiPhone && !this.isCordova)
{
window.scrollTo(0, 0);
}
};
Runtime.prototype.tryLockOrientation = function ()
{
if (!this.autoLockOrientation || this.orientations === 0)
return;
var orientation = "portrait";
if (this.orientations === 2)
orientation = "landscape";
try {
if (screen["orientation"] && screen["orientation"]["lock"])
screen["orientation"]["lock"](orientation).catch(function(){});
else if (screen["lockOrientation"])
screen["lockOrientation"](orientation);
else if (screen["webkitLockOrientation"])
screen["webkitLockOrientation"](orientation);
else if (screen["mozLockOrientation"])
screen["mozLockOrientation"](orientation);
else if (screen["msLockOrientation"])
screen["msLockOrientation"](orientation);
}
catch (e)
{
if (console && console.warn)
console.warn("Failed to lock orientation: ", e);
}
};
Runtime.prototype.onContextLost = function ()
{
this.glwrap.contextLost();
this.is_WebGL_context_lost = true;
var i, len, t;
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
t = this.types_by_index[i];
if (t.onLostWebGLContext)
t.onLostWebGLContext();
}
};
Runtime.prototype.onContextRestored = function ()
{
this.is_WebGL_context_lost = false;
var i, len, t;
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
t = this.types_by_index[i];
if (t.onRestoreWebGLContext)
t.onRestoreWebGLContext();
}
};
Runtime.prototype.positionOverlayCanvas = function()
{
if (this.isDomFree)
return;
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"] || this.isNodeFullscreen) && !this.isCordova;
var overlay_position = isfullscreen ? jQuery(this.canvas).offset() : jQuery(this.canvas).position();
overlay_position.position = "absolute";
jQuery(this.overlay_canvas).css(overlay_position);
};
var caf = window["cancelAnimationFrame"] ||
window["mozCancelAnimationFrame"] ||
window["webkitCancelAnimationFrame"] ||
window["msCancelAnimationFrame"] ||
window["oCancelAnimationFrame"];
Runtime.prototype["setSuspended"] = function (s)
{
var i, len;
var self = this;
if (s && !this.isSuspended)
{
cr.logexport("[Construct 2] Suspending");
this.isSuspended = true; // next tick will be last
if (this.raf_id !== -1 && caf) // note: CocoonJS does not implement cancelAnimationFrame
caf(this.raf_id);
if (this.timeout_id !== -1)
clearTimeout(this.timeout_id);
for (i = 0, len = this.suspend_events.length; i < len; i++)
this.suspend_events[i](true);
}
else if (!s && this.isSuspended)
{
cr.logexport("[Construct 2] Resuming");
this.isSuspended = false;
this.last_tick_time = cr.performance_now(); // ensure first tick is a zero-dt one
this.last_fps_time = cr.performance_now(); // reset FPS counter
this.framecount = 0;
this.logictime = 0;
for (i = 0, len = this.suspend_events.length; i < len; i++)
this.suspend_events[i](false);
this.tick(false); // kick off runtime again
}
};
Runtime.prototype.addSuspendCallback = function (f)
{
this.suspend_events.push(f);
};
Runtime.prototype.GetObjectReference = function (i)
{
;
return this.objectRefTable[i];
};
Runtime.prototype.loadProject = function (data_response)
{
;
if (!data_response || !data_response["project"])
cr.logerror("Project model unavailable");
var pm = data_response["project"];
this.name = pm[0];
this.first_layout = pm[1];
this.fullscreen_mode = pm[12]; // 0 = off, 1 = crop, 2 = scale inner, 3 = scale outer, 4 = letterbox scale, 5 = integer letterbox scale
this.fullscreen_mode_set = pm[12];
this.original_width = pm[10];
this.original_height = pm[11];
this.parallax_x_origin = this.original_width / 2;
this.parallax_y_origin = this.original_height / 2;
if (this.isDomFree && !this.isEjecta && (pm[12] >= 4 || pm[12] === 0))
{
cr.logexport("[Construct 2] Letterbox scale fullscreen modes are not supported on this platform - falling back to 'Scale outer'");
this.fullscreen_mode = 3;
this.fullscreen_mode_set = 3;
}
this.uses_loader_layout = pm[18];
this.loaderstyle = pm[19];
if (this.loaderstyle === 0)
{
var loaderImage = new Image();
loaderImage.crossOrigin = "anonymous";
this.setImageSrc(loaderImage, "loading-logo.png");
this.loaderlogos = {
logo: loaderImage
};
}
else if (this.loaderstyle === 4) // c2 splash
{
var loaderC2logo_1024 = new Image();
loaderC2logo_1024.src = "";
var loaderC2logo_512 = new Image();
loaderC2logo_512.src = "";
var loaderC2logo_256 = new Image();
loaderC2logo_256.src = "";
var loaderC2logo_128 = new Image();
loaderC2logo_128.src = "";
var loaderPowered_1024 = new Image();
loaderPowered_1024.src = "";
var loaderPowered_512 = new Image();
loaderPowered_512.src = "";
var loaderPowered_256 = new Image();
loaderPowered_256.src = "";
var loaderPowered_128 = new Image();
loaderPowered_128.src = "";
var loaderWebsite_1024 = new Image();
loaderWebsite_1024.src = "";
var loaderWebsite_512 = new Image();
loaderWebsite_512.src = "";
var loaderWebsite_256 = new Image();
loaderWebsite_256.src = "";
var loaderWebsite_128 = new Image();
loaderWebsite_128.src = "";
this.loaderlogos = {
logo: [loaderC2logo_1024, loaderC2logo_512, loaderC2logo_256, loaderC2logo_128],
powered: [loaderPowered_1024, loaderPowered_512, loaderPowered_256, loaderPowered_128],
website: [loaderWebsite_1024, loaderWebsite_512, loaderWebsite_256, loaderWebsite_128]
};
}
this.next_uid = pm[21];
this.objectRefTable = cr.getObjectRefTable();
this.system = new cr.system_object(this);
var i, len, j, lenj, k, lenk, idstr, m, b, t, f, p;
var plugin, plugin_ctor;
for (i = 0, len = pm[2].length; i < len; i++)
{
m = pm[2][i];
p = this.GetObjectReference(m[0]);
;
cr.add_common_aces(m, p.prototype);
plugin = new p(this);
plugin.singleglobal = m[1];
plugin.is_world = m[2];
plugin.is_rotatable = m[5];
plugin.must_predraw = m[9];
if (plugin.onCreate)
plugin.onCreate(); // opportunity to override default ACEs
cr.seal(plugin);
this.plugins.push(plugin);
}
this.objectRefTable = cr.getObjectRefTable();
for (i = 0, len = pm[3].length; i < len; i++)
{
m = pm[3][i];
plugin_ctor = this.GetObjectReference(m[1]);
;
plugin = null;
for (j = 0, lenj = this.plugins.length; j < lenj; j++)
{
if (this.plugins[j] instanceof plugin_ctor)
{
plugin = this.plugins[j];
break;
}
}
;
;
var type_inst = new plugin.Type(plugin);
;
type_inst.name = m[0];
type_inst.is_family = m[2];
type_inst.instvar_sids = m[3].slice(0);
type_inst.vars_count = m[3].length;
type_inst.behs_count = m[4];
type_inst.fx_count = m[5];
type_inst.sid = m[11];
if (type_inst.is_family)
{
type_inst.members = []; // types in this family
type_inst.family_index = this.family_count++;
type_inst.families = null;
}
else
{
type_inst.members = null;
type_inst.family_index = -1;
type_inst.families = []; // families this type belongs to
}
type_inst.family_var_map = null;
type_inst.family_beh_map = null;
type_inst.family_fx_map = null;
type_inst.is_contained = false;
type_inst.container = null;
if (m[6])
{
type_inst.texture_file = m[6][0];
type_inst.texture_filesize = m[6][1];
type_inst.texture_pixelformat = m[6][2];
}
else
{
type_inst.texture_file = null;
type_inst.texture_filesize = 0;
type_inst.texture_pixelformat = 0; // rgba8
}
if (m[7])
{
type_inst.animations = m[7];
}
else
{
type_inst.animations = null;
}
type_inst.index = i; // save index in to types array in type
type_inst.instances = []; // all instances of this type
type_inst.deadCache = []; // destroyed instances to recycle next create
type_inst.solstack = [new cr.selection(type_inst)]; // initialise SOL stack with one empty SOL
type_inst.cur_sol = 0;
type_inst.default_instance = null;
type_inst.default_layerindex = 0;
type_inst.stale_iids = true;
type_inst.updateIIDs = cr.type_updateIIDs;
type_inst.getFirstPicked = cr.type_getFirstPicked;
type_inst.getPairedInstance = cr.type_getPairedInstance;
type_inst.getCurrentSol = cr.type_getCurrentSol;
type_inst.pushCleanSol = cr.type_pushCleanSol;
type_inst.pushCopySol = cr.type_pushCopySol;
type_inst.popSol = cr.type_popSol;
type_inst.getBehaviorByName = cr.type_getBehaviorByName;
type_inst.getBehaviorIndexByName = cr.type_getBehaviorIndexByName;
type_inst.getEffectIndexByName = cr.type_getEffectIndexByName;
type_inst.applySolToContainer = cr.type_applySolToContainer;
type_inst.getInstanceByIID = cr.type_getInstanceByIID;
type_inst.collision_grid = new cr.SparseGrid(this.original_width, this.original_height);
type_inst.any_cell_changed = true;
type_inst.any_instance_parallaxed = false;
type_inst.extra = {};
type_inst.toString = cr.type_toString;
type_inst.behaviors = [];
for (j = 0, lenj = m[8].length; j < lenj; j++)
{
b = m[8][j];
var behavior_ctor = this.GetObjectReference(b[1]);
var behavior_plugin = null;
for (k = 0, lenk = this.behaviors.length; k < lenk; k++)
{
if (this.behaviors[k] instanceof behavior_ctor)
{
behavior_plugin = this.behaviors[k];
break;
}
}
if (!behavior_plugin)
{
behavior_plugin = new behavior_ctor(this);
behavior_plugin.my_types = []; // types using this behavior
behavior_plugin.my_instances = new cr.ObjectSet(); // instances of this behavior
if (behavior_plugin.onCreate)
behavior_plugin.onCreate();
cr.seal(behavior_plugin);
this.behaviors.push(behavior_plugin);
if (cr.behaviors.solid && behavior_plugin instanceof cr.behaviors.solid)
this.solidBehavior = behavior_plugin;
if (cr.behaviors.jumpthru && behavior_plugin instanceof cr.behaviors.jumpthru)
this.jumpthruBehavior = behavior_plugin;
if (cr.behaviors.shadowcaster && behavior_plugin instanceof cr.behaviors.shadowcaster)
this.shadowcasterBehavior = behavior_plugin;
}
if (behavior_plugin.my_types.indexOf(type_inst) === -1)
behavior_plugin.my_types.push(type_inst);
var behavior_type = new behavior_plugin.Type(behavior_plugin, type_inst);
behavior_type.name = b[0];
behavior_type.sid = b[2];
behavior_type.onCreate();
cr.seal(behavior_type);
type_inst.behaviors.push(behavior_type);
}
type_inst.global = m[9];
type_inst.isOnLoaderLayout = m[10];
type_inst.effect_types = [];
for (j = 0, lenj = m[12].length; j < lenj; j++)
{
type_inst.effect_types.push({
id: m[12][j][0],
name: m[12][j][1],
shaderindex: -1,
preservesOpaqueness: false,
active: true,
index: j
});
}
type_inst.tile_poly_data = m[13];
if (!this.uses_loader_layout || type_inst.is_family || type_inst.isOnLoaderLayout || !plugin.is_world)
{
type_inst.onCreate();
cr.seal(type_inst);
}
if (type_inst.name)
this.types[type_inst.name] = type_inst;
this.types_by_index.push(type_inst);
if (plugin.singleglobal)
{
var instance = new plugin.Instance(type_inst);
instance.uid = this.next_uid++;
instance.puid = this.next_puid++;
instance.iid = 0;
instance.get_iid = cr.inst_get_iid;
instance.toString = cr.inst_toString;
instance.properties = m[14];
instance.onCreate();
cr.seal(instance);
type_inst.instances.push(instance);
this.objectsByUid[instance.uid.toString()] = instance;
}
}
for (i = 0, len = pm[4].length; i < len; i++)
{
var familydata = pm[4][i];
var familytype = this.types_by_index[familydata[0]];
var familymember;
for (j = 1, lenj = familydata.length; j < lenj; j++)
{
familymember = this.types_by_index[familydata[j]];
familymember.families.push(familytype);
familytype.members.push(familymember);
}
}
for (i = 0, len = pm[28].length; i < len; i++)
{
var containerdata = pm[28][i];
var containertypes = [];
for (j = 0, lenj = containerdata.length; j < lenj; j++)
containertypes.push(this.types_by_index[containerdata[j]]);
for (j = 0, lenj = containertypes.length; j < lenj; j++)
{
containertypes[j].is_contained = true;
containertypes[j].container = containertypes;
}
}
if (this.family_count > 0)
{
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
t = this.types_by_index[i];
if (t.is_family || !t.families.length)
continue;
t.family_var_map = new Array(this.family_count);
t.family_beh_map = new Array(this.family_count);
t.family_fx_map = new Array(this.family_count);
var all_fx = [];
var varsum = 0;
var behsum = 0;
var fxsum = 0;
for (j = 0, lenj = t.families.length; j < lenj; j++)
{
f = t.families[j];
t.family_var_map[f.family_index] = varsum;
varsum += f.vars_count;
t.family_beh_map[f.family_index] = behsum;
behsum += f.behs_count;
t.family_fx_map[f.family_index] = fxsum;
fxsum += f.fx_count;
for (k = 0, lenk = f.effect_types.length; k < lenk; k++)
all_fx.push(cr.shallowCopy({}, f.effect_types[k]));
}
t.effect_types = all_fx.concat(t.effect_types);
for (j = 0, lenj = t.effect_types.length; j < lenj; j++)
t.effect_types[j].index = j;
}
}
for (i = 0, len = pm[5].length; i < len; i++)
{
m = pm[5][i];
var layout = new cr.layout(this, m);
cr.seal(layout);
this.layouts[layout.name] = layout;
this.layouts_by_index.push(layout);
}
for (i = 0, len = pm[6].length; i < len; i++)
{
m = pm[6][i];
var sheet = new cr.eventsheet(this, m);
cr.seal(sheet);
this.eventsheets[sheet.name] = sheet;
this.eventsheets_by_index.push(sheet);
}
for (i = 0, len = this.eventsheets_by_index.length; i < len; i++)
this.eventsheets_by_index[i].postInit();
for (i = 0, len = this.eventsheets_by_index.length; i < len; i++)
this.eventsheets_by_index[i].updateDeepIncludes();
for (i = 0, len = this.triggers_to_postinit.length; i < len; i++)
this.triggers_to_postinit[i].postInit();
cr.clearArray(this.triggers_to_postinit)
this.audio_to_preload = pm[7];
this.files_subfolder = pm[8];
this.pixel_rounding = pm[9];
this.aspect_scale = 1.0;
this.enableWebGL = pm[13];
this.linearSampling = pm[14];
this.clearBackground = pm[15];
this.versionstr = pm[16];
this.useHighDpi = pm[17];
this.orientations = pm[20]; // 0 = any, 1 = portrait, 2 = landscape
this.autoLockOrientation = (this.orientations > 0);
this.pauseOnBlur = pm[22];
this.wantFullscreenScalingQuality = pm[23]; // false = low quality, true = high quality
this.fullscreenScalingQuality = this.wantFullscreenScalingQuality;
this.downscalingQuality = pm[24]; // 0 = low (mips off), 1 = medium (mips on, dense spritesheet), 2 = high (mips on, sparse spritesheet)
this.preloadSounds = pm[25]; // 0 = no, 1 = yes
this.projectName = pm[26];
this.enableFrontToBack = pm[27] && !this.isIE; // front-to-back renderer disabled in IE (but not Edge)
this.start_time = Date.now();
cr.clearArray(this.objectRefTable);
this.initRendererAndLoader();
};
var anyImageHadError = false;
var MAX_PARALLEL_IMAGE_LOADS = 100;
var currentlyActiveImageLoads = 0;
var imageLoadQueue = []; // array of [img, srcToSet]
Runtime.prototype.queueImageLoad = function (img_, src_)
{
var self = this;
var doneFunc = function ()
{
currentlyActiveImageLoads--;
self.maybeLoadNextImages();
};
img_.addEventListener("load", doneFunc);
img_.addEventListener("error", doneFunc);
if (typeof window['NSG_G_VER'] !== 'undefined')
{
src_ += '?' + window['NSG_G_VER'];
}
imageLoadQueue.push([img_, src_]);
this.maybeLoadNextImages();
};
Runtime.prototype.maybeLoadNextImages = function ()
{
var next;
while (imageLoadQueue.length && currentlyActiveImageLoads < MAX_PARALLEL_IMAGE_LOADS)
{
currentlyActiveImageLoads++;
next = imageLoadQueue.shift();
this.setImageSrc(next[0], next[1]);
}
};
Runtime.prototype.waitForImageLoad = function (img_, src_)
{
img_["cocoonLazyLoad"] = true;
img_.onerror = function (e)
{
img_.c2error = true;
anyImageHadError = true;
if (console && console.error)
console.error("Error loading image '" + img_.src + "': ", e);
};
if (this.isEjecta)
{
img_.src = src_;
}
else if (!img_.src)
{
if (typeof XAPKReader !== "undefined")
{
XAPKReader.get(src_, function (expanded_url)
{
img_.src = expanded_url;
}, function (e)
{
img_.c2error = true;
anyImageHadError = true;
if (console && console.error)
console.error("Error extracting image '" + src_ + "' from expansion file: ", e);
});
}
else
{
img_.crossOrigin = "anonymous"; // required for Arcade sandbox compatibility
this.queueImageLoad(img_, src_); // use a queue to avoid requesting all images simultaneously
}
}
this.wait_for_textures.push(img_);
};
Runtime.prototype.findWaitingTexture = function (src_)
{
var i, len;
for (i = 0, len = this.wait_for_textures.length; i < len; i++)
{
if (this.wait_for_textures[i].cr_src === src_)
return this.wait_for_textures[i];
}
return null;
};
var audio_preload_totalsize = 0;
var audio_preload_started = false;
Runtime.prototype.getready = function ()
{
if (!this.audioInstance)
return;
audio_preload_totalsize = this.audioInstance.setPreloadList(this.audio_to_preload);
};
Runtime.prototype.areAllTexturesAndSoundsLoaded = function ()
{
var totalsize = audio_preload_totalsize;
var completedsize = 0;
var audiocompletedsize = 0;
var ret = true;
var i, len, img;
for (i = 0, len = this.wait_for_textures.length; i < len; i++)
{
img = this.wait_for_textures[i];
var filesize = img.cr_filesize;
if (!filesize || filesize <= 0)
filesize = 50000;
totalsize += filesize;
if (!!img.src && (img.complete || img["loaded"]) && !img.c2error)
completedsize += filesize;
else
ret = false; // not all textures loaded
}
if (ret && this.preloadSounds && this.audioInstance)
{
if (!audio_preload_started)
{
this.audioInstance.startPreloads();
audio_preload_started = true;
}
audiocompletedsize = this.audioInstance.getPreloadedSize();
completedsize += audiocompletedsize;
if (audiocompletedsize < audio_preload_totalsize)
ret = false; // not done yet
}
if (totalsize == 0)
this.progress = 1; // indicate to C2 splash loader that it can finish now
else
this.progress = (completedsize / totalsize);
return ret;
};
var isC2SplashDone = false;
Runtime.prototype.go = function ()
{
if (!this.ctx && !this.glwrap)
return;
var ctx = this.ctx || this.overlay_ctx;
if (this.overlay_canvas)
this.positionOverlayCanvas();
var curwidth = window.innerWidth;
var curheight = window.innerHeight;
if (this.lastWindowWidth !== curwidth || this.lastWindowHeight !== curheight)
{
this["setSize"](curwidth, curheight);
}
this.progress = 0;
this.last_progress = -1;
var self = this;
if (this.areAllTexturesAndSoundsLoaded() && (this.loaderstyle !== 4 || isC2SplashDone))
{
this.go_loading_finished();
}
else
{
var ms_elapsed = Date.now() - this.start_time;
if (ctx)
{
var overlay_width = this.width;
var overlay_height = this.height;
var dpr = this.devicePixelRatio;
if (this.loaderstyle < 3 && (this.isCocoonJs || (ms_elapsed >= 500 && this.last_progress != this.progress)))
{
ctx.clearRect(0, 0, overlay_width, overlay_height);
var mx = overlay_width / 2;
var my = overlay_height / 2;
var haslogo = (this.loaderstyle === 0 && this.loaderlogos.logo.complete);
var hlw = 40 * dpr;
var hlh = 0;
var logowidth = 80 * dpr;
var logoheight;
if (haslogo)
{
var loaderLogoImage = this.loaderlogos.logo;
logowidth = loaderLogoImage.width * dpr;
logoheight = loaderLogoImage.height * dpr;
hlw = logowidth / 2;
hlh = logoheight / 2;
ctx.drawImage(loaderLogoImage, cr.floor(mx - hlw), cr.floor(my - hlh), logowidth, logoheight);
}
if (this.loaderstyle <= 1)
{
my += hlh + (haslogo ? 12 * dpr : 0);
mx -= hlw;
mx = cr.floor(mx) + 0.5;
my = cr.floor(my) + 0.5;
ctx.fillStyle = anyImageHadError ? "red" : "DodgerBlue";
ctx.fillRect(mx, my, Math.floor(logowidth * this.progress), 6 * dpr);
ctx.strokeStyle = "black";
ctx.strokeRect(mx, my, logowidth, 6 * dpr);
ctx.strokeStyle = "white";
ctx.strokeRect(mx - 1 * dpr, my - 1 * dpr, logowidth + 2 * dpr, 8 * dpr);
}
else if (this.loaderstyle === 2)
{
ctx.font = (this.isEjecta ? "12pt ArialMT" : "12pt Arial");
ctx.fillStyle = anyImageHadError ? "#f00" : "#999";
ctx.textBaseLine = "middle";
var percent_text = Math.round(this.progress * 100) + "%";
var text_dim = ctx.measureText ? ctx.measureText(percent_text) : null;
var text_width = text_dim ? text_dim.width : 0;
ctx.fillText(percent_text, mx - (text_width / 2), my);
}
this.last_progress = this.progress;
}
else if (this.loaderstyle === 4)
{
this.draw_c2_splash_loader(ctx);
if (raf)
raf(function() { self.go(); });
else
setTimeout(function() { self.go(); }, 16);
return;
}
}
setTimeout(function() { self.go(); }, (this.isCocoonJs ? 10 : 100));
}
};
var splashStartTime = -1;
var splashFadeInDuration = 300;
var splashFadeOutDuration = 300;
var splashAfterFadeOutWait = (typeof cr_is_preview === "undefined" ? 200 : 0);
var splashIsFadeIn = true;
var splashIsFadeOut = false;
var splashFadeInFinish = 0;
var splashFadeOutStart = 0;
var splashMinDisplayTime = (typeof cr_is_preview === "undefined" ? 3000 : 0);
var renderViaCanvas = null;
var renderViaCtx = null;
var splashFrameNumber = 0;
function maybeCreateRenderViaCanvas(w, h)
{
if (!renderViaCanvas || renderViaCanvas.width !== w || renderViaCanvas.height !== h)
{
renderViaCanvas = document.createElement("canvas");
renderViaCanvas.width = w;
renderViaCanvas.height = h;
renderViaCtx = renderViaCanvas.getContext("2d");
}
};
function mipImage(arr, size)
{
if (size <= 128)
return arr[3];
else if (size <= 256)
return arr[2];
else if (size <= 512)
return arr[1];
else
return arr[0];
};
Runtime.prototype.draw_c2_splash_loader = function(ctx)
{
if (isC2SplashDone)
return;
var w = Math.ceil(this.width);
var h = Math.ceil(this.height);
var dpr = this.devicePixelRatio;
var logoimages = this.loaderlogos.logo;
var poweredimages = this.loaderlogos.powered;
var websiteimages = this.loaderlogos.website;
for (var i = 0; i < 4; ++i)
{
if (!logoimages[i].complete || !poweredimages[i].complete || !websiteimages[i].complete)
return;
}
if (splashFrameNumber === 0)
splashStartTime = Date.now();
var nowTime = Date.now();
var isRenderingVia = false;
var renderToCtx = ctx;
var drawW, drawH;
if (splashIsFadeIn || splashIsFadeOut)
{
ctx.clearRect(0, 0, w, h);
maybeCreateRenderViaCanvas(w, h);
renderToCtx = renderViaCtx;
isRenderingVia = true;
if (splashIsFadeIn && splashFrameNumber === 1)
splashStartTime = Date.now();
}
else
{
ctx.globalAlpha = 1;
}
renderToCtx.fillStyle = "#333333";
renderToCtx.fillRect(0, 0, w, h);
if (this.cssHeight > 256)
{
drawW = cr.clamp(h * 0.22, 105, w * 0.6);
drawH = drawW * 0.25;
renderToCtx.drawImage(mipImage(poweredimages, drawW), w * 0.5 - drawW/2, h * 0.2 - drawH/2, drawW, drawH);
drawW = Math.min(h * 0.395, w * 0.95);
drawH = drawW;
renderToCtx.drawImage(mipImage(logoimages, drawW), w * 0.5 - drawW/2, h * 0.485 - drawH/2, drawW, drawH);
drawW = cr.clamp(h * 0.22, 105, w * 0.6);
drawH = drawW * 0.25;
renderToCtx.drawImage(mipImage(websiteimages, drawW), w * 0.5 - drawW/2, h * 0.868 - drawH/2, drawW, drawH);
renderToCtx.fillStyle = "#3C3C3C";
drawW = w;
drawH = Math.max(h * 0.005, 2);
renderToCtx.fillRect(0, h * 0.8 - drawH/2, drawW, drawH);
renderToCtx.fillStyle = anyImageHadError ? "red" : "#E0FF65";
drawW = w * this.progress;
renderToCtx.fillRect(w * 0.5 - drawW/2, h * 0.8 - drawH/2, drawW, drawH);
}
else
{
drawW = h * 0.55;
drawH = drawW;
renderToCtx.drawImage(mipImage(logoimages, drawW), w * 0.5 - drawW/2, h * 0.45 - drawH/2, drawW, drawH);
renderToCtx.fillStyle = "#3C3C3C";
drawW = w;
drawH = Math.max(h * 0.005, 2);
renderToCtx.fillRect(0, h * 0.85 - drawH/2, drawW, drawH);
renderToCtx.fillStyle = anyImageHadError ? "red" : "#E0FF65";
drawW = w * this.progress;
renderToCtx.fillRect(w * 0.5 - drawW/2, h * 0.85 - drawH/2, drawW, drawH);
}
if (isRenderingVia)
{
if (splashIsFadeIn)
{
if (splashFrameNumber === 0)
ctx.globalAlpha = 0;
else
ctx.globalAlpha = Math.min((nowTime - splashStartTime) / splashFadeInDuration, 1);
}
else if (splashIsFadeOut)
{
ctx.globalAlpha = Math.max(1 - (nowTime - splashFadeOutStart) / splashFadeOutDuration, 0);
}
ctx.drawImage(renderViaCanvas, 0, 0, w, h);
}
if (splashIsFadeIn && nowTime - splashStartTime >= splashFadeInDuration && splashFrameNumber >= 2)
{
splashIsFadeIn = false;
splashFadeInFinish = nowTime;
}
if (!splashIsFadeIn && nowTime - splashFadeInFinish >= splashMinDisplayTime && !splashIsFadeOut && this.progress >= 1)
{
splashIsFadeOut = true;
splashFadeOutStart = nowTime;
}
if ((splashIsFadeOut && nowTime - splashFadeOutStart >= splashFadeOutDuration + splashAfterFadeOutWait) ||
(typeof cr_is_preview !== "undefined" && this.progress >= 1 && Date.now() - splashStartTime < 500))
{
isC2SplashDone = true;
splashIsFadeIn = false;
splashIsFadeOut = false;
renderViaCanvas = null;
renderViaCtx = null;
this.loaderlogos = null;
}
++splashFrameNumber;
};
Runtime.prototype.go_loading_finished = function ()
{
if (this.overlay_canvas)
{
this.canvas.parentNode.removeChild(this.overlay_canvas);
this.overlay_ctx = null;
this.overlay_canvas = null;
}
this.start_time = Date.now();
this.last_fps_time = cr.performance_now(); // for counting framerate
var i, len, t;
if (this.uses_loader_layout)
{
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
t = this.types_by_index[i];
if (!t.is_family && !t.isOnLoaderLayout && t.plugin.is_world)
{
t.onCreate();
cr.seal(t);
}
}
}
else
this.isloading = false;
for (i = 0, len = this.layouts_by_index.length; i < len; i++)
{
this.layouts_by_index[i].createGlobalNonWorlds();
}
if (this.fullscreen_mode >= 2)
{
var orig_aspect = this.original_width / this.original_height;
var cur_aspect = this.width / this.height;
if ((this.fullscreen_mode !== 2 && cur_aspect > orig_aspect) || (this.fullscreen_mode === 2 && cur_aspect < orig_aspect))
this.aspect_scale = this.height / this.original_height;
else
this.aspect_scale = this.width / this.original_width;
}
if (this.first_layout)
this.layouts[this.first_layout].startRunning();
else
this.layouts_by_index[0].startRunning();
;
if (!this.uses_loader_layout)
{
this.loadingprogress = 1;
this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null);
if (window["C2_RegisterSW"]) // note not all platforms use SW
window["C2_RegisterSW"]();
}
if (navigator["splashscreen"] && navigator["splashscreen"]["hide"])
navigator["splashscreen"]["hide"]();
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
t = this.types_by_index[i];
if (t.onAppBegin)
t.onAppBegin();
}
if (document["hidden"] || document["webkitHidden"] || document["mozHidden"] || document["msHidden"])
{
window["cr_setSuspended"](true); // stop rendering
}
else
{
this.tick(false);
}
if (this.isDirectCanvas)
AppMobi["webview"]["execute"]("onGameReady();");
};
Runtime.prototype.tick = function (background_wake, timestamp, debug_step)
{
if (!this.running_layout)
return;
var nowtime = cr.performance_now();
var logic_start = nowtime;
if (!debug_step && this.isSuspended && !background_wake)
return;
if (!background_wake)
{
if (raf)
this.raf_id = raf(this.tickFunc);
else
{
this.timeout_id = setTimeout(this.tickFunc, this.isMobile ? 1 : 16);
}
}
var raf_time = timestamp || nowtime;
var fsmode = this.fullscreen_mode;
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"]) && !this.isCordova;
if ((isfullscreen || this.isNodeFullscreen) && this.fullscreen_scaling > 0)
fsmode = this.fullscreen_scaling;
if (fsmode > 0) // r222: experimentally enabling this workaround for all platforms
{
var curwidth = window.innerWidth;
var curheight = window.innerHeight;
if (this.lastWindowWidth !== curwidth || this.lastWindowHeight !== curheight)
{
this["setSize"](curwidth, curheight);
}
}
if (!this.isDomFree)
{
if (isfullscreen)
{
if (!this.firstInFullscreen)
this.firstInFullscreen = true;
}
else
{
if (this.firstInFullscreen)
{
this.firstInFullscreen = false;
if (this.fullscreen_mode === 0)
{
this["setSize"](Math.round(this.oldWidth / this.devicePixelRatio), Math.round(this.oldHeight / this.devicePixelRatio), true);
}
}
else
{
this.oldWidth = this.width;
this.oldHeight = this.height;
}
}
}
if (this.isloading)
{
var done = this.areAllTexturesAndSoundsLoaded(); // updates this.progress
this.loadingprogress = this.progress;
if (done)
{
this.isloading = false;
this.progress = 1;
this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null);
if (window["C2_RegisterSW"])
window["C2_RegisterSW"]();
}
}
this.logic(raf_time);
if ((this.redraw || this.isCocoonJs) && !this.is_WebGL_context_lost && !this.suspendDrawing && !background_wake)
{
this.redraw = false;
if (this.glwrap)
this.drawGL();
else
this.draw();
if (this.snapshotCanvas)
{
if (this.canvas && this.canvas.toDataURL)
{
this.snapshotData = this.canvas.toDataURL(this.snapshotCanvas[0], this.snapshotCanvas[1]);
if (window["cr_onSnapshot"])
window["cr_onSnapshot"](this.snapshotData);
this.trigger(cr.system_object.prototype.cnds.OnCanvasSnapshot, null);
}
this.snapshotCanvas = null;
}
}
if (!this.hit_breakpoint)
{
this.tickcount++;
this.tickcount_nosave++;
this.execcount++;
this.framecount++;
}
this.logictime += cr.performance_now() - logic_start;
};
Runtime.prototype.logic = function (cur_time)
{
var i, leni, j, lenj, k, lenk, type, inst, binst;
if (cur_time - this.last_fps_time >= 1000) // every 1 second
{
this.last_fps_time += 1000;
if (cur_time - this.last_fps_time >= 1000)
this.last_fps_time = cur_time;
this.fps = this.framecount;
this.framecount = 0;
this.cpuutilisation = this.logictime;
this.logictime = 0;
}
var wallDt = 0;
if (this.last_tick_time !== 0)
{
var ms_diff = cur_time - this.last_tick_time;
if (ms_diff < 0)
ms_diff = 0;
wallDt = ms_diff / 1000.0; // dt measured in seconds
this.dt1 = wallDt;
if (this.dt1 > 0.5)
this.dt1 = 0;
else if (this.dt1 > 1 / this.minimumFramerate)
this.dt1 = 1 / this.minimumFramerate;
}
this.last_tick_time = cur_time;
this.dt = this.dt1 * this.timescale;
this.kahanTime.add(this.dt);
this.wallTime.add(wallDt); // prevent min/max framerate affecting wall clock
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"] || this.isNodeFullscreen) && !this.isCordova;
if (this.fullscreen_mode >= 2 /* scale */ || (isfullscreen && this.fullscreen_scaling > 0))
{
var orig_aspect = this.original_width / this.original_height;
var cur_aspect = this.width / this.height;
var mode = this.fullscreen_mode;
if (isfullscreen && this.fullscreen_scaling > 0)
mode = this.fullscreen_scaling;
if ((mode !== 2 && cur_aspect > orig_aspect) || (mode === 2 && cur_aspect < orig_aspect))
{
this.aspect_scale = this.height / this.original_height;
}
else
{
this.aspect_scale = this.width / this.original_width;
}
if (this.running_layout)
{
this.running_layout.scrollToX(this.running_layout.scrollX);
this.running_layout.scrollToY(this.running_layout.scrollY);
}
}
else
this.aspect_scale = (this.isRetina ? this.devicePixelRatio : 1);
this.ClearDeathRow();
this.isInOnDestroy++;
this.system.runWaits(); // prevent instance list changing
this.isInOnDestroy--;
this.ClearDeathRow(); // allow instance list changing
this.isInOnDestroy++;
var tickarr = this.objects_to_pretick.valuesRef();
for (i = 0, leni = tickarr.length; i < leni; i++)
tickarr[i].pretick();
for (i = 0, leni = this.types_by_index.length; i < leni; i++)
{
type = this.types_by_index[i];
if (type.is_family || (!type.behaviors.length && !type.families.length))
continue;
for (j = 0, lenj = type.instances.length; j < lenj; j++)
{
inst = type.instances[j];
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
{
inst.behavior_insts[k].tick();
}
}
}
for (i = 0, leni = this.types_by_index.length; i < leni; i++)
{
type = this.types_by_index[i];
if (type.is_family || (!type.behaviors.length && !type.families.length))
continue; // type doesn't have any behaviors
for (j = 0, lenj = type.instances.length; j < lenj; j++)
{
inst = type.instances[j];
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
{
binst = inst.behavior_insts[k];
if (binst.posttick)
{
binst.posttick();
}
}
}
}
tickarr = this.objects_to_tick.valuesRef();
for (i = 0, leni = tickarr.length; i < leni; i++)
tickarr[i].tick();
this.isInOnDestroy--; // end preventing instance lists from being changed
this.handleSaveLoad(); // save/load now if queued
i = 0;
while (this.changelayout && i++ < 10)
{
this.doChangeLayout(this.changelayout);
}
for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++)
this.eventsheets_by_index[i].hasRun = false;
if (this.running_layout.event_sheet)
this.running_layout.event_sheet.run();
cr.clearArray(this.registered_collisions);
this.layout_first_tick = false;
this.isInOnDestroy++; // prevent instance lists from being changed
for (i = 0, leni = this.types_by_index.length; i < leni; i++)
{
type = this.types_by_index[i];
if (type.is_family || (!type.behaviors.length && !type.families.length))
continue; // type doesn't have any behaviors
for (j = 0, lenj = type.instances.length; j < lenj; j++)
{
var inst = type.instances[j];
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
{
binst = inst.behavior_insts[k];
if (binst.tick2)
{
binst.tick2();
}
}
}
}
tickarr = this.objects_to_tick2.valuesRef();
for (i = 0, leni = tickarr.length; i < leni; i++)
tickarr[i].tick2();
this.isInOnDestroy--; // end preventing instance lists from being changed
};
Runtime.prototype.onWindowBlur = function ()
{
var i, leni, j, lenj, k, lenk, type, inst, binst;
for (i = 0, leni = this.types_by_index.length; i < leni; i++)
{
type = this.types_by_index[i];
if (type.is_family)
continue;
for (j = 0, lenj = type.instances.length; j < lenj; j++)
{
inst = type.instances[j];
if (inst.onWindowBlur)
inst.onWindowBlur();
if (!inst.behavior_insts)
continue; // single-globals don't have behavior_insts
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
{
binst = inst.behavior_insts[k];
if (binst.onWindowBlur)
binst.onWindowBlur();
}
}
}
};
Runtime.prototype.doChangeLayout = function (changeToLayout)
{
var prev_layout = this.running_layout;
this.running_layout.stopRunning();
var i, len, j, lenj, k, lenk, type, inst, binst;
if (this.glwrap)
{
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
type = this.types_by_index[i];
if (type.is_family)
continue;
if (type.unloadTextures && (!type.global || type.instances.length === 0) && changeToLayout.initial_types.indexOf(type) === -1)
{
type.unloadTextures();
}
}
}
if (prev_layout == changeToLayout)
cr.clearArray(this.system.waits);
cr.clearArray(this.registered_collisions);
this.runLayoutChangeMethods(true);
changeToLayout.startRunning();
this.runLayoutChangeMethods(false);
this.redraw = true;
this.layout_first_tick = true;
this.ClearDeathRow();
};
Runtime.prototype.runLayoutChangeMethods = function (isBeforeChange)
{
var i, len, beh, type, j, lenj, inst, k, lenk, binst;
for (i = 0, len = this.behaviors.length; i < len; i++)
{
beh = this.behaviors[i];
if (isBeforeChange)
{
if (beh.onBeforeLayoutChange)
beh.onBeforeLayoutChange();
}
else
{
if (beh.onLayoutChange)
beh.onLayoutChange();
}
}
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
type = this.types_by_index[i];
if (!type.global && !type.plugin.singleglobal)
continue;
for (j = 0, lenj = type.instances.length; j < lenj; j++)
{
inst = type.instances[j];
if (isBeforeChange)
{
if (inst.onBeforeLayoutChange)
inst.onBeforeLayoutChange();
}
else
{
if (inst.onLayoutChange)
inst.onLayoutChange();
}
if (inst.behavior_insts)
{
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
{
binst = inst.behavior_insts[k];
if (isBeforeChange)
{
if (binst.onBeforeLayoutChange)
binst.onBeforeLayoutChange();
}
else
{
if (binst.onLayoutChange)
binst.onLayoutChange();
}
}
}
}
}
};
Runtime.prototype.pretickMe = function (inst)
{
this.objects_to_pretick.add(inst);
};
Runtime.prototype.unpretickMe = function (inst)
{
this.objects_to_pretick.remove(inst);
};
Runtime.prototype.tickMe = function (inst)
{
this.objects_to_tick.add(inst);
};
Runtime.prototype.untickMe = function (inst)
{
this.objects_to_tick.remove(inst);
};
Runtime.prototype.tick2Me = function (inst)
{
this.objects_to_tick2.add(inst);
};
Runtime.prototype.untick2Me = function (inst)
{
this.objects_to_tick2.remove(inst);
};
Runtime.prototype.getDt = function (inst)
{
if (!inst || inst.my_timescale === -1.0)
return this.dt;
return this.dt1 * inst.my_timescale;
};
Runtime.prototype.draw = function ()
{
this.running_layout.draw(this.ctx);
if (this.isDirectCanvas)
this.ctx["present"]();
};
Runtime.prototype.drawGL = function ()
{
if (this.enableFrontToBack)
{
this.earlyz_index = 1; // start from front, 1-based to avoid exactly equalling near plane Z value
this.running_layout.drawGL_earlyZPass(this.glwrap);
}
this.running_layout.drawGL(this.glwrap);
this.glwrap.present();
};
Runtime.prototype.addDestroyCallback = function (f)
{
if (f)
this.destroycallbacks.push(f);
};
Runtime.prototype.removeDestroyCallback = function (f)
{
cr.arrayFindRemove(this.destroycallbacks, f);
};
Runtime.prototype.getObjectByUID = function (uid_)
{
;
var uidstr = uid_.toString();
if (this.objectsByUid.hasOwnProperty(uidstr))
return this.objectsByUid[uidstr];
else
return null;
};
var objectset_cache = [];
function alloc_objectset()
{
if (objectset_cache.length)
return objectset_cache.pop();
else
return new cr.ObjectSet();
};
function free_objectset(s)
{
s.clear();
objectset_cache.push(s);
};
Runtime.prototype.DestroyInstance = function (inst)
{
var i, len;
var type = inst.type;
var typename = type.name;
var has_typename = this.deathRow.hasOwnProperty(typename);
var obj_set = null;
if (has_typename)
{
obj_set = this.deathRow[typename];
if (obj_set.contains(inst))
return; // already had DestroyInstance called
}
else
{
obj_set = alloc_objectset();
this.deathRow[typename] = obj_set;
}
obj_set.add(inst);
this.hasPendingInstances = true;
if (inst.is_contained)
{
for (i = 0, len = inst.siblings.length; i < len; i++)
{
this.DestroyInstance(inst.siblings[i]);
}
}
if (this.isInClearDeathRow)
obj_set.values_cache.push(inst);
if (!this.isEndingLayout)
{
this.isInOnDestroy++; // support recursion
this.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnDestroyed, inst);
this.isInOnDestroy--;
}
};
Runtime.prototype.ClearDeathRow = function ()
{
if (!this.hasPendingInstances)
return;
var inst, type, instances;
var i, j, leni, lenj, obj_set;
this.isInClearDeathRow = true;
for (i = 0, leni = this.createRow.length; i < leni; ++i)
{
inst = this.createRow[i];
type = inst.type;
type.instances.push(inst);
for (j = 0, lenj = type.families.length; j < lenj; ++j)
{
type.families[j].instances.push(inst);
type.families[j].stale_iids = true;
}
}
cr.clearArray(this.createRow);
this.IterateDeathRow(); // moved to separate function so for-in performance doesn't hobble entire function
cr.wipe(this.deathRow); // all objectsets have already been recycled
this.isInClearDeathRow = false;
this.hasPendingInstances = false;
};
Runtime.prototype.IterateDeathRow = function ()
{
for (var p in this.deathRow)
{
if (this.deathRow.hasOwnProperty(p))
{
this.ClearDeathRowForType(this.deathRow[p]);
}
}
};
Runtime.prototype.ClearDeathRowForType = function (obj_set)
{
var arr = obj_set.valuesRef(); // get array of items from set
;
var type = arr[0].type;
;
;
var i, len, j, lenj, w, f, layer_instances, inst;
cr.arrayRemoveAllFromObjectSet(type.instances, obj_set);
type.stale_iids = true;
if (type.instances.length === 0)
type.any_instance_parallaxed = false;
for (i = 0, len = type.families.length; i < len; ++i)
{
f = type.families[i];
cr.arrayRemoveAllFromObjectSet(f.instances, obj_set);
f.stale_iids = true;
}
for (i = 0, len = this.system.waits.length; i < len; ++i)
{
w = this.system.waits[i];
if (w.sols.hasOwnProperty(type.index))
cr.arrayRemoveAllFromObjectSet(w.sols[type.index].insts, obj_set);
if (!type.is_family)
{
for (j = 0, lenj = type.families.length; j < lenj; ++j)
{
f = type.families[j];
if (w.sols.hasOwnProperty(f.index))
cr.arrayRemoveAllFromObjectSet(w.sols[f.index].insts, obj_set);
}
}
}
var first_layer = arr[0].layer;
if (first_layer)
{
if (first_layer.useRenderCells)
{
layer_instances = first_layer.instances;
for (i = 0, len = layer_instances.length; i < len; ++i)
{
inst = layer_instances[i];
if (!obj_set.contains(inst))
continue; // not destroying this instance
inst.update_bbox();
first_layer.render_grid.update(inst, inst.rendercells, null);
inst.rendercells.set(0, 0, -1, -1);
}
}
cr.arrayRemoveAllFromObjectSet(first_layer.instances, obj_set);
first_layer.setZIndicesStaleFrom(0);
}
for (i = 0; i < arr.length; ++i) // check array length every time in case it changes
{
this.ClearDeathRowForSingleInstance(arr[i], type);
}
free_objectset(obj_set);
this.redraw = true;
};
Runtime.prototype.ClearDeathRowForSingleInstance = function (inst, type)
{
var i, len, binst;
for (i = 0, len = this.destroycallbacks.length; i < len; ++i)
this.destroycallbacks[i](inst);
if (inst.collcells)
{
type.collision_grid.update(inst, inst.collcells, null);
}
var layer = inst.layer;
if (layer)
{
layer.removeFromInstanceList(inst, true); // remove from both instance list and render grid
}
if (inst.behavior_insts)
{
for (i = 0, len = inst.behavior_insts.length; i < len; ++i)
{
binst = inst.behavior_insts[i];
if (binst.onDestroy)
binst.onDestroy();
binst.behavior.my_instances.remove(inst);
}
}
this.objects_to_pretick.remove(inst);
this.objects_to_tick.remove(inst);
this.objects_to_tick2.remove(inst);
if (inst.onDestroy)
inst.onDestroy();
if (this.objectsByUid.hasOwnProperty(inst.uid.toString()))
delete this.objectsByUid[inst.uid.toString()];
this.objectcount--;
if (type.deadCache.length < 100)
type.deadCache.push(inst);
};
Runtime.prototype.createInstance = function (type, layer, sx, sy)
{
if (type.is_family)
{
var i = cr.floor(Math.random() * type.members.length);
return this.createInstance(type.members[i], layer, sx, sy);
}
if (!type.default_instance)
{
return null;
}
return this.createInstanceFromInit(type.default_instance, layer, false, sx, sy, false);
};
var all_behaviors = [];
Runtime.prototype.createInstanceFromInit = function (initial_inst, layer, is_startup_instance, sx, sy, skip_siblings)
{
var i, len, j, lenj, p, effect_fallback, x, y;
if (!initial_inst)
return null;
var type = this.types_by_index[initial_inst[1]];
;
;
var is_world = type.plugin.is_world;
;
if (this.isloading && is_world && !type.isOnLoaderLayout)
return null;
if (is_world && !this.glwrap && initial_inst[0][11] === 11)
return null;
var original_layer = layer;
if (!is_world)
layer = null;
var inst;
if (type.deadCache.length)
{
inst = type.deadCache.pop();
inst.recycled = true;
type.plugin.Instance.call(inst, type);
}
else
{
inst = new type.plugin.Instance(type);
inst.recycled = false;
}
if (is_startup_instance && !skip_siblings && !this.objectsByUid.hasOwnProperty(initial_inst[2].toString()))
inst.uid = initial_inst[2];
else
inst.uid = this.next_uid++;
this.objectsByUid[inst.uid.toString()] = inst;
inst.puid = this.next_puid++;
inst.iid = type.instances.length;
for (i = 0, len = this.createRow.length; i < len; ++i)
{
if (this.createRow[i].type === type)
inst.iid++;
}
inst.get_iid = cr.inst_get_iid;
inst.toString = cr.inst_toString;
var initial_vars = initial_inst[3];
if (inst.recycled)
{
cr.wipe(inst.extra);
}
else
{
inst.extra = {};
if (typeof cr_is_preview !== "undefined")
{
inst.instance_var_names = [];
inst.instance_var_names.length = initial_vars.length;
for (i = 0, len = initial_vars.length; i < len; i++)
inst.instance_var_names[i] = initial_vars[i][1];
}
inst.instance_vars = [];
inst.instance_vars.length = initial_vars.length;
}
for (i = 0, len = initial_vars.length; i < len; i++)
inst.instance_vars[i] = initial_vars[i][0];
if (is_world)
{
var wm = initial_inst[0];
;
inst.x = cr.is_undefined(sx) ? wm[0] : sx;
inst.y = cr.is_undefined(sy) ? wm[1] : sy;
inst.z = wm[2];
inst.width = wm[3];
inst.height = wm[4];
inst.depth = wm[5];
inst.angle = wm[6];
inst.opacity = wm[7];
inst.hotspotX = wm[8];
inst.hotspotY = wm[9];
inst.blend_mode = wm[10];
effect_fallback = wm[11];
if (!this.glwrap && type.effect_types.length) // no WebGL renderer and shaders used
inst.blend_mode = effect_fallback; // use fallback blend mode - destroy mode was handled above
inst.compositeOp = cr.effectToCompositeOp(inst.blend_mode);
if (this.gl)
cr.setGLBlend(inst, inst.blend_mode, this.gl);
if (inst.recycled)
{
for (i = 0, len = wm[12].length; i < len; i++)
{
for (j = 0, lenj = wm[12][i].length; j < lenj; j++)
inst.effect_params[i][j] = wm[12][i][j];
}
inst.bbox.set(0, 0, 0, 0);
inst.collcells.set(0, 0, -1, -1);
inst.rendercells.set(0, 0, -1, -1);
inst.bquad.set_from_rect(inst.bbox);
cr.clearArray(inst.bbox_changed_callbacks);
}
else
{
inst.effect_params = wm[12].slice(0);
for (i = 0, len = inst.effect_params.length; i < len; i++)
inst.effect_params[i] = wm[12][i].slice(0);
inst.active_effect_types = [];
inst.active_effect_flags = [];
inst.active_effect_flags.length = type.effect_types.length;
inst.bbox = new cr.rect(0, 0, 0, 0);
inst.collcells = new cr.rect(0, 0, -1, -1);
inst.rendercells = new cr.rect(0, 0, -1, -1);
inst.bquad = new cr.quad();
inst.bbox_changed_callbacks = [];
inst.set_bbox_changed = cr.set_bbox_changed;
inst.add_bbox_changed_callback = cr.add_bbox_changed_callback;
inst.contains_pt = cr.inst_contains_pt;
inst.update_bbox = cr.update_bbox;
inst.update_render_cell = cr.update_render_cell;
inst.update_collision_cell = cr.update_collision_cell;
inst.get_zindex = cr.inst_get_zindex;
}
inst.tilemap_exists = false;
inst.tilemap_width = 0;
inst.tilemap_height = 0;
inst.tilemap_data = null;
if (wm.length === 14)
{
inst.tilemap_exists = true;
inst.tilemap_width = wm[13][0];
inst.tilemap_height = wm[13][1];
inst.tilemap_data = wm[13][2];
}
for (i = 0, len = type.effect_types.length; i < len; i++)
inst.active_effect_flags[i] = true;
inst.shaders_preserve_opaqueness = true;
inst.updateActiveEffects = cr.inst_updateActiveEffects;
inst.updateActiveEffects();
inst.uses_shaders = !!inst.active_effect_types.length;
inst.bbox_changed = true;
inst.cell_changed = true;
type.any_cell_changed = true;
inst.visible = true;
inst.my_timescale = -1.0;
inst.layer = layer;
inst.zindex = layer.instances.length; // will be placed at top of current layer
inst.earlyz_index = 0;
if (typeof inst.collision_poly === "undefined")
inst.collision_poly = null;
inst.collisionsEnabled = true;
this.redraw = true;
}
var initial_props, binst;
cr.clearArray(all_behaviors);
for (i = 0, len = type.families.length; i < len; i++)
{
all_behaviors.push.apply(all_behaviors, type.families[i].behaviors);
}
all_behaviors.push.apply(all_behaviors, type.behaviors);
if (inst.recycled)
{
for (i = 0, len = all_behaviors.length; i < len; i++)
{
var btype = all_behaviors[i];
binst = inst.behavior_insts[i];
binst.recycled = true;
btype.behavior.Instance.call(binst, btype, inst);
initial_props = initial_inst[4][i];
for (j = 0, lenj = initial_props.length; j < lenj; j++)
binst.properties[j] = initial_props[j];
binst.onCreate();
btype.behavior.my_instances.add(inst);
}
}
else
{
inst.behavior_insts = [];
for (i = 0, len = all_behaviors.length; i < len; i++)
{
var btype = all_behaviors[i];
var binst = new btype.behavior.Instance(btype, inst);
binst.recycled = false;
binst.properties = initial_inst[4][i].slice(0);
binst.onCreate();
cr.seal(binst);
inst.behavior_insts.push(binst);
btype.behavior.my_instances.add(inst);
}
}
initial_props = initial_inst[5];
if (inst.recycled)
{
for (i = 0, len = initial_props.length; i < len; i++)
inst.properties[i] = initial_props[i];
}
else
inst.properties = initial_props.slice(0);
this.createRow.push(inst);
this.hasPendingInstances = true;
if (layer)
{
;
layer.appendToInstanceList(inst, true);
if (layer.parallaxX !== 1 || layer.parallaxY !== 1)
type.any_instance_parallaxed = true;
}
this.objectcount++;
if (type.is_contained)
{
inst.is_contained = true;
if (inst.recycled)
cr.clearArray(inst.siblings);
else
inst.siblings = []; // note: should not include self in siblings
if (!is_startup_instance && !skip_siblings) // layout links initial instances
{
for (i = 0, len = type.container.length; i < len; i++)
{
if (type.container[i] === type)
continue;
if (!type.container[i].default_instance)
{
return null;
}
inst.siblings.push(this.createInstanceFromInit(type.container[i].default_instance, original_layer, false, is_world ? inst.x : sx, is_world ? inst.y : sy, true));
}
for (i = 0, len = inst.siblings.length; i < len; i++)
{
inst.siblings[i].siblings.push(inst);
for (j = 0; j < len; j++)
{
if (i !== j)
inst.siblings[i].siblings.push(inst.siblings[j]);
}
}
}
}
else
{
inst.is_contained = false;
inst.siblings = null;
}
inst.onCreate();
if (!inst.recycled)
cr.seal(inst);
for (i = 0, len = inst.behavior_insts.length; i < len; i++)
{
if (inst.behavior_insts[i].postCreate)
inst.behavior_insts[i].postCreate();
}
return inst;
};
Runtime.prototype.getLayerByName = function (layer_name)
{
var i, len;
for (i = 0, len = this.running_layout.layers.length; i < len; i++)
{
var layer = this.running_layout.layers[i];
if (cr.equals_nocase(layer.name, layer_name))
return layer;
}
return null;
};
Runtime.prototype.getLayerByNumber = function (index)
{
index = cr.floor(index);
if (index < 0)
index = 0;
if (index >= this.running_layout.layers.length)
index = this.running_layout.layers.length - 1;
return this.running_layout.layers[index];
};
Runtime.prototype.getLayer = function (l)
{
if (cr.is_number(l))
return this.getLayerByNumber(l);
else
return this.getLayerByName(l.toString());
};
Runtime.prototype.clearSol = function (solModifiers)
{
var i, len;
for (i = 0, len = solModifiers.length; i < len; i++)
{
solModifiers[i].getCurrentSol().select_all = true;
}
};
Runtime.prototype.pushCleanSol = function (solModifiers)
{
var i, len;
for (i = 0, len = solModifiers.length; i < len; i++)
{
solModifiers[i].pushCleanSol();
}
};
Runtime.prototype.pushCopySol = function (solModifiers)
{
var i, len;
for (i = 0, len = solModifiers.length; i < len; i++)
{
solModifiers[i].pushCopySol();
}
};
Runtime.prototype.popSol = function (solModifiers)
{
var i, len;
for (i = 0, len = solModifiers.length; i < len; i++)
{
solModifiers[i].popSol();
}
};
Runtime.prototype.updateAllCells = function (type)
{
if (!type.any_cell_changed)
return; // all instances must already be up-to-date
var i, len, instances = type.instances;
for (i = 0, len = instances.length; i < len; ++i)
{
instances[i].update_collision_cell();
}
var createRow = this.createRow;
for (i = 0, len = createRow.length; i < len; ++i)
{
if (createRow[i].type === type)
createRow[i].update_collision_cell();
}
type.any_cell_changed = false;
};
Runtime.prototype.getCollisionCandidates = function (layer, rtype, bbox, candidates)
{
var i, len, t;
var is_parallaxed = (layer ? (layer.parallaxX !== 1 || layer.parallaxY !== 1) : false);
if (rtype.is_family)
{
for (i = 0, len = rtype.members.length; i < len; ++i)
{
t = rtype.members[i];
if (is_parallaxed || t.any_instance_parallaxed)
{
cr.appendArray(candidates, t.instances);
}
else
{
this.updateAllCells(t);
t.collision_grid.queryRange(bbox, candidates);
}
}
}
else
{
if (is_parallaxed || rtype.any_instance_parallaxed)
{
cr.appendArray(candidates, rtype.instances);
}
else
{
this.updateAllCells(rtype);
rtype.collision_grid.queryRange(bbox, candidates);
}
}
};
Runtime.prototype.getTypesCollisionCandidates = function (layer, types, bbox, candidates)
{
var i, len;
for (i = 0, len = types.length; i < len; ++i)
{
this.getCollisionCandidates(layer, types[i], bbox, candidates);
}
};
Runtime.prototype.getSolidCollisionCandidates = function (layer, bbox, candidates)
{
var solid = this.getSolidBehavior();
if (!solid)
return null;
this.getTypesCollisionCandidates(layer, solid.my_types, bbox, candidates);
};
Runtime.prototype.getJumpthruCollisionCandidates = function (layer, bbox, candidates)
{
var jumpthru = this.getJumpthruBehavior();
if (!jumpthru)
return null;
this.getTypesCollisionCandidates(layer, jumpthru.my_types, bbox, candidates);
};
Runtime.prototype.testAndSelectCanvasPointOverlap = function (type, ptx, pty, inverted)
{
var sol = type.getCurrentSol();
var i, j, inst, len;
var orblock = this.getCurrentEventStack().current_event.orblock;
var lx, ly, arr;
if (sol.select_all)
{
if (!inverted)
{
sol.select_all = false;
cr.clearArray(sol.instances); // clear contents
}
for (i = 0, len = type.instances.length; i < len; i++)
{
inst = type.instances[i];
inst.update_bbox();
lx = inst.layer.canvasToLayer(ptx, pty, true);
ly = inst.layer.canvasToLayer(ptx, pty, false);
if (inst.contains_pt(lx, ly))
{
if (inverted)
return false;
else
sol.instances.push(inst);
}
else if (orblock)
sol.else_instances.push(inst);
}
}
else
{
j = 0;
arr = (orblock ? sol.else_instances : sol.instances);
for (i = 0, len = arr.length; i < len; i++)
{
inst = arr[i];
inst.update_bbox();
lx = inst.layer.canvasToLayer(ptx, pty, true);
ly = inst.layer.canvasToLayer(ptx, pty, false);
if (inst.contains_pt(lx, ly))
{
if (inverted)
return false;
else if (orblock)
sol.instances.push(inst);
else
{
sol.instances[j] = sol.instances[i];
j++;
}
}
}
if (!inverted)
arr.length = j;
}
type.applySolToContainer();
if (inverted)
return true; // did not find anything overlapping
else
return sol.hasObjects();
};
Runtime.prototype.testOverlap = function (a, b)
{
if (!a || !b || a === b || !a.collisionsEnabled || !b.collisionsEnabled)
return false;
a.update_bbox();
b.update_bbox();
var layera = a.layer;
var layerb = b.layer;
var different_layers = (layera !== layerb && (layera.parallaxX !== layerb.parallaxX || layerb.parallaxY !== layerb.parallaxY || layera.scale !== layerb.scale || layera.angle !== layerb.angle || layera.zoomRate !== layerb.zoomRate));
var i, len, i2, i21, x, y, haspolya, haspolyb, polya, polyb;
if (!different_layers) // same layers: easy check
{
if (!a.bbox.intersects_rect(b.bbox))
return false;
if (!a.bquad.intersects_quad(b.bquad))
return false;
if (a.tilemap_exists && b.tilemap_exists)
return false;
if (a.tilemap_exists)
return this.testTilemapOverlap(a, b);
if (b.tilemap_exists)
return this.testTilemapOverlap(b, a);
haspolya = (a.collision_poly && !a.collision_poly.is_empty());
haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
if (!haspolya && !haspolyb)
return true;
if (haspolya)
{
a.collision_poly.cache_poly(a.width, a.height, a.angle);
polya = a.collision_poly;
}
else
{
this.temp_poly.set_from_quad(a.bquad, a.x, a.y, a.width, a.height);
polya = this.temp_poly;
}
if (haspolyb)
{
b.collision_poly.cache_poly(b.width, b.height, b.angle);
polyb = b.collision_poly;
}
else
{
this.temp_poly.set_from_quad(b.bquad, b.x, b.y, b.width, b.height);
polyb = this.temp_poly;
}
return polya.intersects_poly(polyb, b.x - a.x, b.y - a.y);
}
else // different layers: need to do full translated check
{
haspolya = (a.collision_poly && !a.collision_poly.is_empty());
haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
if (haspolya)
{
a.collision_poly.cache_poly(a.width, a.height, a.angle);
this.temp_poly.set_from_poly(a.collision_poly);
}
else
{
this.temp_poly.set_from_quad(a.bquad, a.x, a.y, a.width, a.height);
}
polya = this.temp_poly;
if (haspolyb)
{
b.collision_poly.cache_poly(b.width, b.height, b.angle);
this.temp_poly2.set_from_poly(b.collision_poly);
}
else
{
this.temp_poly2.set_from_quad(b.bquad, b.x, b.y, b.width, b.height);
}
polyb = this.temp_poly2;
for (i = 0, len = polya.pts_count; i < len; i++)
{
i2 = i * 2;
i21 = i2 + 1;
x = polya.pts_cache[i2];
y = polya.pts_cache[i21];
polya.pts_cache[i2] = layera.layerToCanvas(x + a.x, y + a.y, true);
polya.pts_cache[i21] = layera.layerToCanvas(x + a.x, y + a.y, false);
}
polya.update_bbox();
for (i = 0, len = polyb.pts_count; i < len; i++)
{
i2 = i * 2;
i21 = i2 + 1;
x = polyb.pts_cache[i2];
y = polyb.pts_cache[i21];
polyb.pts_cache[i2] = layerb.layerToCanvas(x + b.x, y + b.y, true);
polyb.pts_cache[i21] = layerb.layerToCanvas(x + b.x, y + b.y, false);
}
polyb.update_bbox();
return polya.intersects_poly(polyb, 0, 0);
}
};
var tmpQuad = new cr.quad();
var tmpRect = new cr.rect(0, 0, 0, 0);
var collrect_candidates = [];
Runtime.prototype.testTilemapOverlap = function (tm, a)
{
var i, len, c, rc;
var bbox = a.bbox;
var tmx = tm.x;
var tmy = tm.y;
tm.getCollisionRectCandidates(bbox, collrect_candidates);
var collrects = collrect_candidates;
var haspolya = (a.collision_poly && !a.collision_poly.is_empty());
for (i = 0, len = collrects.length; i < len; ++i)
{
c = collrects[i];
rc = c.rc;
if (bbox.intersects_rect_off(rc, tmx, tmy))
{
tmpQuad.set_from_rect(rc);
tmpQuad.offset(tmx, tmy);
if (tmpQuad.intersects_quad(a.bquad))
{
if (haspolya)
{
a.collision_poly.cache_poly(a.width, a.height, a.angle);
if (c.poly)
{
if (c.poly.intersects_poly(a.collision_poly, a.x - (tmx + rc.left), a.y - (tmy + rc.top)))
{
cr.clearArray(collrect_candidates);
return true;
}
}
else
{
this.temp_poly.set_from_quad(tmpQuad, 0, 0, rc.right - rc.left, rc.bottom - rc.top);
if (this.temp_poly.intersects_poly(a.collision_poly, a.x, a.y))
{
cr.clearArray(collrect_candidates);
return true;
}
}
}
else
{
if (c.poly)
{
this.temp_poly.set_from_quad(a.bquad, 0, 0, a.width, a.height);
if (c.poly.intersects_poly(this.temp_poly, -(tmx + rc.left), -(tmy + rc.top)))
{
cr.clearArray(collrect_candidates);
return true;
}
}
else
{
cr.clearArray(collrect_candidates);
return true;
}
}
}
}
}
cr.clearArray(collrect_candidates);
return false;
};
Runtime.prototype.testRectOverlap = function (r, b)
{
if (!b || !b.collisionsEnabled)
return false;
b.update_bbox();
var layerb = b.layer;
var haspolyb, polyb;
if (!b.bbox.intersects_rect(r))
return false;
if (b.tilemap_exists)
{
b.getCollisionRectCandidates(r, collrect_candidates);
var collrects = collrect_candidates;
var i, len, c, tilerc;
var tmx = b.x;
var tmy = b.y;
for (i = 0, len = collrects.length; i < len; ++i)
{
c = collrects[i];
tilerc = c.rc;
if (r.intersects_rect_off(tilerc, tmx, tmy))
{
if (c.poly)
{
this.temp_poly.set_from_rect(r, 0, 0);
if (c.poly.intersects_poly(this.temp_poly, -(tmx + tilerc.left), -(tmy + tilerc.top)))
{
cr.clearArray(collrect_candidates);
return true;
}
}
else
{
cr.clearArray(collrect_candidates);
return true;
}
}
}
cr.clearArray(collrect_candidates);
return false;
}
else
{
tmpQuad.set_from_rect(r);
if (!b.bquad.intersects_quad(tmpQuad))
return false;
haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
if (!haspolyb)
return true;
b.collision_poly.cache_poly(b.width, b.height, b.angle);
tmpQuad.offset(-r.left, -r.top);
this.temp_poly.set_from_quad(tmpQuad, 0, 0, 1, 1);
return b.collision_poly.intersects_poly(this.temp_poly, r.left - b.x, r.top - b.y);
}
};
Runtime.prototype.testSegmentOverlap = function (x1, y1, x2, y2, b)
{
if (!b || !b.collisionsEnabled)
return false;
b.update_bbox();
var layerb = b.layer;
var haspolyb, polyb;
tmpRect.set(cr.min(x1, x2), cr.min(y1, y2), cr.max(x1, x2), cr.max(y1, y2));
if (!b.bbox.intersects_rect(tmpRect))
return false;
if (b.tilemap_exists)
{
b.getCollisionRectCandidates(tmpRect, collrect_candidates);
var collrects = collrect_candidates;
var i, len, c, tilerc;
var tmx = b.x;
var tmy = b.y;
for (i = 0, len = collrects.length; i < len; ++i)
{
c = collrects[i];
tilerc = c.rc;
if (tmpRect.intersects_rect_off(tilerc, tmx, tmy))
{
tmpQuad.set_from_rect(tilerc);
tmpQuad.offset(tmx, tmy);
if (tmpQuad.intersects_segment(x1, y1, x2, y2))
{
if (c.poly)
{
if (c.poly.intersects_segment(tmx + tilerc.left, tmy + tilerc.top, x1, y1, x2, y2))
{
cr.clearArray(collrect_candidates);
return true;
}
}
else
{
cr.clearArray(collrect_candidates);
return true;
}
}
}
}
cr.clearArray(collrect_candidates);
return false;
}
else
{
if (!b.bquad.intersects_segment(x1, y1, x2, y2))
return false;
haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
if (!haspolyb)
return true;
b.collision_poly.cache_poly(b.width, b.height, b.angle);
return b.collision_poly.intersects_segment(b.x, b.y, x1, y1, x2, y2);
}
};
Runtime.prototype.typeHasBehavior = function (t, b)
{
if (!b)
return false;
var i, len, j, lenj, f;
for (i = 0, len = t.behaviors.length; i < len; i++)
{
if (t.behaviors[i].behavior instanceof b)
return true;
}
if (!t.is_family)
{
for (i = 0, len = t.families.length; i < len; i++)
{
f = t.families[i];
for (j = 0, lenj = f.behaviors.length; j < lenj; j++)
{
if (f.behaviors[j].behavior instanceof b)
return true;
}
}
}
return false;
};
Runtime.prototype.typeHasNoSaveBehavior = function (t)
{
return this.typeHasBehavior(t, cr.behaviors.NoSave);
};
Runtime.prototype.typeHasPersistBehavior = function (t)
{
return this.typeHasBehavior(t, cr.behaviors.Persist);
};
Runtime.prototype.getSolidBehavior = function ()
{
return this.solidBehavior;
};
Runtime.prototype.getJumpthruBehavior = function ()
{
return this.jumpthruBehavior;
};
var candidates = [];
Runtime.prototype.testOverlapSolid = function (inst)
{
var i, len, s;
inst.update_bbox();
this.getSolidCollisionCandidates(inst.layer, inst.bbox, candidates);
for (i = 0, len = candidates.length; i < len; ++i)
{
s = candidates[i];
if (!s.extra["solidEnabled"])
continue;
if (this.testOverlap(inst, s))
{
cr.clearArray(candidates);
return s;
}
}
cr.clearArray(candidates);
return null;
};
Runtime.prototype.testRectOverlapSolid = function (r)
{
var i, len, s;
this.getSolidCollisionCandidates(null, r, candidates);
for (i = 0, len = candidates.length; i < len; ++i)
{
s = candidates[i];
if (!s.extra["solidEnabled"])
continue;
if (this.testRectOverlap(r, s))
{
cr.clearArray(candidates);
return s;
}
}
cr.clearArray(candidates);
return null;
};
var jumpthru_array_ret = [];
Runtime.prototype.testOverlapJumpThru = function (inst, all)
{
var ret = null;
if (all)
{
ret = jumpthru_array_ret;
cr.clearArray(ret);
}
inst.update_bbox();
this.getJumpthruCollisionCandidates(inst.layer, inst.bbox, candidates);
var i, len, j;
for (i = 0, len = candidates.length; i < len; ++i)
{
j = candidates[i];
if (!j.extra["jumpthruEnabled"])
continue;
if (this.testOverlap(inst, j))
{
if (all)
ret.push(j);
else
{
cr.clearArray(candidates);
return j;
}
}
}
cr.clearArray(candidates);
return ret;
};
Runtime.prototype.pushOutSolid = function (inst, xdir, ydir, dist, include_jumpthrus, specific_jumpthru)
{
var push_dist = dist || 50;
var oldx = inst.x
var oldy = inst.y;
var i;
var last_overlapped = null, secondlast_overlapped = null;
for (i = 0; i < push_dist; i++)
{
inst.x = (oldx + (xdir * i));
inst.y = (oldy + (ydir * i));
inst.set_bbox_changed();
if (!this.testOverlap(inst, last_overlapped))
{
last_overlapped = this.testOverlapSolid(inst);
if (last_overlapped)
secondlast_overlapped = last_overlapped;
if (!last_overlapped)
{
if (include_jumpthrus)
{
if (specific_jumpthru)
last_overlapped = (this.testOverlap(inst, specific_jumpthru) ? specific_jumpthru : null);
else
last_overlapped = this.testOverlapJumpThru(inst);
if (last_overlapped)
secondlast_overlapped = last_overlapped;
}
if (!last_overlapped)
{
if (secondlast_overlapped)
this.pushInFractional(inst, xdir, ydir, secondlast_overlapped, 16);
return true;
}
}
}
}
inst.x = oldx;
inst.y = oldy;
inst.set_bbox_changed();
return false;
};
Runtime.prototype.pushOutSolidAxis = function(inst, xdir, ydir, dist)
{
dist = dist || 50;
var oldX = inst.x;
var oldY = inst.y;
var lastOverlapped = null;
var secondLastOverlapped = null;
var i, which, sign;
for (i = 0; i < dist; ++i)
{
for (which = 0; which < 2; ++which)
{
sign = which * 2 - 1; // -1 or 1
inst.x = oldX + (xdir * i * sign);
inst.y = oldY + (ydir * i * sign);
inst.set_bbox_changed();
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);
return true;
}
}
}
}
inst.x = oldX;
inst.y = oldY;
inst.set_bbox_changed();
return false;
};
Runtime.prototype.pushOut = function (inst, xdir, ydir, dist, otherinst)
{
var push_dist = dist || 50;
var oldx = inst.x
var oldy = inst.y;
var i;
for (i = 0; i < push_dist; i++)
{
inst.x = (oldx + (xdir * i));
inst.y = (oldy + (ydir * i));
inst.set_bbox_changed();
if (!this.testOverlap(inst, otherinst))
return true;
}
inst.x = oldx;
inst.y = oldy;
inst.set_bbox_changed();
return false;
};
Runtime.prototype.pushInFractional = function (inst, xdir, ydir, obj, limit)
{
var divisor = 2;
var frac;
var forward = false;
var overlapping = false;
var bestx = inst.x;
var besty = inst.y;
while (divisor <= limit)
{
frac = 1 / divisor;
divisor *= 2;
inst.x += xdir * frac * (forward ? 1 : -1);
inst.y += ydir * frac * (forward ? 1 : -1);
inst.set_bbox_changed();
if (this.testOverlap(inst, obj))
{
forward = true;
overlapping = true;
}
else
{
forward = false;
overlapping = false;
bestx = inst.x;
besty = inst.y;
}
}
if (overlapping)
{
inst.x = bestx;
inst.y = besty;
inst.set_bbox_changed();
}
};
Runtime.prototype.pushOutSolidNearest = function (inst, max_dist_)
{
var max_dist = (cr.is_undefined(max_dist_) ? 100 : max_dist_);
var dist = 0;
var oldx = inst.x
var oldy = inst.y;
var dir = 0;
var dx = 0, dy = 0;
var last_overlapped = this.testOverlapSolid(inst);
if (!last_overlapped)
return true; // already clear of solids
while (dist <= max_dist)
{
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;
inst.x = cr.floor(oldx + (dx * dist));
inst.y = cr.floor(oldy + (dy * dist));
inst.set_bbox_changed();
if (!this.testOverlap(inst, last_overlapped))
{
last_overlapped = this.testOverlapSolid(inst);
if (!last_overlapped)
return true;
}
}
inst.x = oldx;
inst.y = oldy;
inst.set_bbox_changed();
return false;
};
Runtime.prototype.registerCollision = function (a, b)
{
if (!a.collisionsEnabled || !b.collisionsEnabled)
return;
this.registered_collisions.push([a, b]);
};
Runtime.prototype.addRegisteredCollisionCandidates = function (inst, otherType, arr)
{
var i, len, r, otherInst;
for (i = 0, len = this.registered_collisions.length; i < len; ++i)
{
r = this.registered_collisions[i];
if (r[0] === inst)
otherInst = r[1];
else if (r[1] === inst)
otherInst = r[0];
else
continue;
if (otherType.is_family)
{
if (otherType.members.indexOf(otherType) === -1)
continue;
}
else
{
if (otherInst.type !== otherType)
continue;
}
if (arr.indexOf(otherInst) === -1)
arr.push(otherInst);
}
};
Runtime.prototype.checkRegisteredCollision = function (a, b)
{
var i, len, x;
for (i = 0, len = this.registered_collisions.length; i < len; i++)
{
x = this.registered_collisions[i];
if ((x[0] === a && x[1] === b) || (x[0] === b && x[1] === a))
return true;
}
return false;
};
Runtime.prototype.calculateSolidBounceAngle = function(inst, startx, starty, obj)
{
var objx = inst.x;
var objy = inst.y;
var radius = cr.max(10, cr.distanceTo(startx, starty, objx, objy));
var startangle = cr.angleTo(startx, starty, objx, objy);
var firstsolid = obj || this.testOverlapSolid(inst);
if (!firstsolid)
return cr.clamp_angle(startangle + cr.PI);
var cursolid = firstsolid;
var i, curangle, anticlockwise_free_angle, clockwise_free_angle;
var increment = cr.to_radians(5); // 5 degree increments
for (i = 1; i < 36; i++)
{
curangle = startangle - i * increment;
inst.x = startx + Math.cos(curangle) * radius;
inst.y = starty + Math.sin(curangle) * radius;
inst.set_bbox_changed();
if (!this.testOverlap(inst, cursolid))
{
cursolid = obj ? null : this.testOverlapSolid(inst);
if (!cursolid)
{
anticlockwise_free_angle = curangle;
break;
}
}
}
if (i === 36)
anticlockwise_free_angle = cr.clamp_angle(startangle + cr.PI);
var cursolid = firstsolid;
for (i = 1; i < 36; i++)
{
curangle = startangle + i * increment;
inst.x = startx + Math.cos(curangle) * radius;
inst.y = starty + Math.sin(curangle) * radius;
inst.set_bbox_changed();
if (!this.testOverlap(inst, cursolid))
{
cursolid = obj ? null : this.testOverlapSolid(inst);
if (!cursolid)
{
clockwise_free_angle = curangle;
break;
}
}
}
if (i === 36)
clockwise_free_angle = cr.clamp_angle(startangle + cr.PI);
inst.x = objx;
inst.y = objy;
inst.set_bbox_changed();
if (clockwise_free_angle === anticlockwise_free_angle)
return clockwise_free_angle;
var half_diff = cr.angleDiff(clockwise_free_angle, anticlockwise_free_angle) / 2;
var normal;
if (cr.angleClockwise(clockwise_free_angle, anticlockwise_free_angle))
{
normal = cr.clamp_angle(anticlockwise_free_angle + half_diff + cr.PI);
}
else
{
normal = cr.clamp_angle(clockwise_free_angle + half_diff);
}
;
var vx = Math.cos(startangle);
var vy = Math.sin(startangle);
var nx = Math.cos(normal);
var ny = Math.sin(normal);
var v_dot_n = vx * nx + vy * ny;
var rx = vx - 2 * v_dot_n * nx;
var ry = vy - 2 * v_dot_n * ny;
return cr.angleTo(0, 0, rx, ry);
};
var triggerSheetIndex = -1;
Runtime.prototype.trigger = function (method, inst, value /* for fast triggers */)
{
;
if (!this.running_layout)
return false;
var sheet = this.running_layout.event_sheet;
if (!sheet)
return false; // no event sheet active; nothing to trigger
var ret = false;
var r, i, len;
triggerSheetIndex++;
var deep_includes = sheet.deep_includes;
for (i = 0, len = deep_includes.length; i < len; ++i)
{
r = this.triggerOnSheet(method, inst, deep_includes[i], value);
ret = ret || r;
}
r = this.triggerOnSheet(method, inst, sheet, value);
ret = ret || r;
triggerSheetIndex--;
return ret;
};
Runtime.prototype.triggerOnSheet = function (method, inst, sheet, value)
{
var ret = false;
var i, leni, r, families;
if (!inst)
{
r = this.triggerOnSheetForTypeName(method, inst, "system", sheet, value);
ret = ret || r;
}
else
{
r = this.triggerOnSheetForTypeName(method, inst, inst.type.name, sheet, value);
ret = ret || r;
families = inst.type.families;
for (i = 0, leni = families.length; i < leni; ++i)
{
r = this.triggerOnSheetForTypeName(method, inst, families[i].name, sheet, value);
ret = ret || r;
}
}
return ret; // true if anything got triggered
};
Runtime.prototype.triggerOnSheetForTypeName = function (method, inst, type_name, sheet, value)
{
var i, leni;
var ret = false, ret2 = false;
var trig, index;
var fasttrigger = (typeof value !== "undefined");
var triggers = (fasttrigger ? sheet.fasttriggers : sheet.triggers);
var obj_entry = triggers[type_name];
if (!obj_entry)
return ret;
var triggers_list = null;
for (i = 0, leni = obj_entry.length; i < leni; ++i)
{
if (obj_entry[i].method == method)
{
triggers_list = obj_entry[i].evs;
break;
}
}
if (!triggers_list)
return ret;
var triggers_to_fire;
if (fasttrigger)
{
triggers_to_fire = triggers_list[value];
}
else
{
triggers_to_fire = triggers_list;
}
if (!triggers_to_fire)
return null;
for (i = 0, leni = triggers_to_fire.length; i < leni; i++)
{
trig = triggers_to_fire[i][0];
index = triggers_to_fire[i][1];
ret2 = this.executeSingleTrigger(inst, type_name, trig, index);
ret = ret || ret2;
}
return ret;
};
Runtime.prototype.executeSingleTrigger = function (inst, type_name, trig, index)
{
var i, leni;
var ret = false;
this.trigger_depth++;
var current_event = this.getCurrentEventStack().current_event;
if (current_event)
this.pushCleanSol(current_event.solModifiersIncludingParents);
var isrecursive = (this.trigger_depth > 1); // calling trigger from inside another trigger
this.pushCleanSol(trig.solModifiersIncludingParents);
if (isrecursive)
this.pushLocalVarStack();
var event_stack = this.pushEventStack(trig);
event_stack.current_event = trig;
if (inst)
{
var sol = this.types[type_name].getCurrentSol();
sol.select_all = false;
cr.clearArray(sol.instances);
sol.instances[0] = inst;
this.types[type_name].applySolToContainer();
}
var ok_to_run = true;
if (trig.parent)
{
var temp_parents_arr = event_stack.temp_parents_arr;
var cur_parent = trig.parent;
while (cur_parent)
{
temp_parents_arr.push(cur_parent);
cur_parent = cur_parent.parent;
}
temp_parents_arr.reverse();
for (i = 0, leni = temp_parents_arr.length; i < leni; i++)
{
if (!temp_parents_arr[i].run_pretrigger()) // parent event failed
{
ok_to_run = false;
break;
}
}
}
if (ok_to_run)
{
this.execcount++;
if (trig.orblock)
trig.run_orblocktrigger(index);
else
trig.run();
ret = ret || event_stack.last_event_true;
}
this.popEventStack();
if (isrecursive)
this.popLocalVarStack();
this.popSol(trig.solModifiersIncludingParents);
if (current_event)
this.popSol(current_event.solModifiersIncludingParents);
if (this.hasPendingInstances && this.isInOnDestroy === 0 && triggerSheetIndex === 0 && !this.isRunningEvents)
{
this.ClearDeathRow();
}
this.trigger_depth--;
return ret;
};
Runtime.prototype.getCurrentCondition = function ()
{
var evinfo = this.getCurrentEventStack();
return evinfo.current_event.conditions[evinfo.cndindex];
};
Runtime.prototype.getCurrentConditionObjectType = function ()
{
var cnd = this.getCurrentCondition();
return cnd.type;
};
Runtime.prototype.isCurrentConditionFirst = function ()
{
var evinfo = this.getCurrentEventStack();
return evinfo.cndindex === 0;
};
Runtime.prototype.getCurrentAction = function ()
{
var evinfo = this.getCurrentEventStack();
return evinfo.current_event.actions[evinfo.actindex];
};
Runtime.prototype.pushLocalVarStack = function ()
{
this.localvar_stack_index++;
if (this.localvar_stack_index >= this.localvar_stack.length)
this.localvar_stack.push([]);
};
Runtime.prototype.popLocalVarStack = function ()
{
;
this.localvar_stack_index--;
};
Runtime.prototype.getCurrentLocalVarStack = function ()
{
return this.localvar_stack[this.localvar_stack_index];
};
Runtime.prototype.pushEventStack = function (cur_event)
{
this.event_stack_index++;
if (this.event_stack_index >= this.event_stack.length)
this.event_stack.push(new cr.eventStackFrame());
var ret = this.getCurrentEventStack();
ret.reset(cur_event);
return ret;
};
Runtime.prototype.popEventStack = function ()
{
;
this.event_stack_index--;
};
Runtime.prototype.getCurrentEventStack = function ()
{
return this.event_stack[this.event_stack_index];
};
Runtime.prototype.pushLoopStack = function (name_)
{
this.loop_stack_index++;
if (this.loop_stack_index >= this.loop_stack.length)
{
this.loop_stack.push(cr.seal({ name: name_, index: 0, stopped: false }));
}
var ret = this.getCurrentLoop();
ret.name = name_;
ret.index = 0;
ret.stopped = false;
return ret;
};
Runtime.prototype.popLoopStack = function ()
{
;
this.loop_stack_index--;
};
Runtime.prototype.getCurrentLoop = function ()
{
return this.loop_stack[this.loop_stack_index];
};
Runtime.prototype.getEventVariableByName = function (name, scope)
{
var i, leni, j, lenj, sheet, e;
while (scope)
{
for (i = 0, leni = scope.subevents.length; i < leni; i++)
{
e = scope.subevents[i];
if (e instanceof cr.eventvariable && cr.equals_nocase(name, e.name))
return e;
}
scope = scope.parent;
}
for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++)
{
sheet = this.eventsheets_by_index[i];
for (j = 0, lenj = sheet.events.length; j < lenj; j++)
{
e = sheet.events[j];
if (e instanceof cr.eventvariable && cr.equals_nocase(name, e.name))
return e;
}
}
return null;
};
Runtime.prototype.getLayoutBySid = function (sid_)
{
var i, len;
for (i = 0, len = this.layouts_by_index.length; i < len; i++)
{
if (this.layouts_by_index[i].sid === sid_)
return this.layouts_by_index[i];
}
return null;
};
Runtime.prototype.getObjectTypeBySid = function (sid_)
{
var i, len;
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
if (this.types_by_index[i].sid === sid_)
return this.types_by_index[i];
}
return null;
};
Runtime.prototype.getGroupBySid = function (sid_)
{
var i, len;
for (i = 0, len = this.allGroups.length; i < len; i++)
{
if (this.allGroups[i].sid === sid_)
return this.allGroups[i];
}
return null;
};
Runtime.prototype.doCanvasSnapshot = function (format_, quality_)
{
this.snapshotCanvas = [format_, quality_];
this.redraw = true; // force redraw so snapshot is always taken
};
function IsIndexedDBAvailable()
{
try {
return !!window.indexedDB;
}
catch (e)
{
return false;
}
};
function makeSaveDb(e)
{
var db = e.target.result;
db.createObjectStore("saves", { keyPath: "slot" });
};
function IndexedDB_WriteSlot(slot_, data_, oncomplete_, onerror_)
{
try {
var request = indexedDB.open("_C2SaveStates");
request.onupgradeneeded = makeSaveDb;
request.onerror = onerror_;
request.onsuccess = function (e)
{
var db = e.target.result;
db.onerror = onerror_;
var transaction = db.transaction(["saves"], "readwrite");
var objectStore = transaction.objectStore("saves");
var putReq = objectStore.put({"slot": slot_, "data": data_ });
putReq.onsuccess = oncomplete_;
};
}
catch (err)
{
onerror_(err);
}
};
function IndexedDB_ReadSlot(slot_, oncomplete_, onerror_)
{
try {
var request = indexedDB.open("_C2SaveStates");
request.onupgradeneeded = makeSaveDb;
request.onerror = onerror_;
request.onsuccess = function (e)
{
var db = e.target.result;
db.onerror = onerror_;
var transaction = db.transaction(["saves"]);
var objectStore = transaction.objectStore("saves");
var readReq = objectStore.get(slot_);
readReq.onsuccess = function (e)
{
if (readReq.result)
oncomplete_(readReq.result["data"]);
else
oncomplete_(null);
};
};
}
catch (err)
{
onerror_(err);
}
};
Runtime.prototype.signalContinuousPreview = function ()
{
this.signalledContinuousPreview = true;
};
function doContinuousPreviewReload()
{
cr.logexport("Reloading for continuous preview");
if (!!window["c2cocoonjs"])
{
CocoonJS["App"]["reload"]();
}
else
{
if (window.location.search.indexOf("continuous") > -1)
window.location.reload(true);
else
window.location = window.location + "?continuous";
}
};
Runtime.prototype.handleSaveLoad = function ()
{
var self = this;
var savingToSlot = this.saveToSlot;
var savingJson = this.lastSaveJson;
var loadingFromSlot = this.loadFromSlot;
var continuous = false;
if (this.signalledContinuousPreview)
{
continuous = true;
savingToSlot = "__c2_continuouspreview";
this.signalledContinuousPreview = false;
}
if (savingToSlot.length)
{
this.ClearDeathRow();
savingJson = this.saveToJSONString();
if (IsIndexedDBAvailable() && !this.isCocoonJs)
{
IndexedDB_WriteSlot(savingToSlot, savingJson, function ()
{
cr.logexport("Saved state to IndexedDB storage (" + savingJson.length + " bytes)");
self.lastSaveJson = savingJson;
self.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
self.lastSaveJson = "";
savingJson = "";
if (continuous)
doContinuousPreviewReload();
}, function (e)
{
try {
localStorage.setItem("__c2save_" + savingToSlot, savingJson);
cr.logexport("Saved state to WebStorage (" + savingJson.length + " bytes)");
self.lastSaveJson = savingJson;
self.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
self.lastSaveJson = "";
savingJson = "";
if (continuous)
doContinuousPreviewReload();
}
catch (f)
{
cr.logexport("Failed to save game state: " + e + "; " + f);
self.trigger(cr.system_object.prototype.cnds.OnSaveFailed, null);
}
});
}
else
{
try {
localStorage.setItem("__c2save_" + savingToSlot, savingJson);
cr.logexport("Saved state to WebStorage (" + savingJson.length + " bytes)");
self.lastSaveJson = savingJson;
this.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
self.lastSaveJson = "";
savingJson = "";
if (continuous)
doContinuousPreviewReload();
}
catch (e)
{
cr.logexport("Error saving to WebStorage: " + e);
self.trigger(cr.system_object.prototype.cnds.OnSaveFailed, null);
}
}
this.saveToSlot = "";
this.loadFromSlot = "";
this.loadFromJson = null;
}
if (loadingFromSlot.length)
{
if (IsIndexedDBAvailable() && !this.isCocoonJs)
{
IndexedDB_ReadSlot(loadingFromSlot, function (result_)
{
if (result_)
{
self.loadFromJson = result_;
cr.logexport("Loaded state from IndexedDB storage (" + self.loadFromJson.length + " bytes)");
}
else
{
self.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
cr.logexport("Loaded state from WebStorage (" + self.loadFromJson.length + " bytes)");
}
self.suspendDrawing = false;
if (!self.loadFromJson)
{
self.loadFromJson = null;
self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
}
}, function (e)
{
self.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
cr.logexport("Loaded state from WebStorage (" + self.loadFromJson.length + " bytes)");
self.suspendDrawing = false;
if (!self.loadFromJson)
{
self.loadFromJson = null;
self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
}
});
}
else
{
try {
this.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
cr.logexport("Loaded state from WebStorage (" + this.loadFromJson.length + " bytes)");
}
catch (e)
{
this.loadFromJson = null;
}
this.suspendDrawing = false;
if (!self.loadFromJson)
{
self.loadFromJson = null;
self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
}
}
this.loadFromSlot = "";
this.saveToSlot = "";
}
if (this.loadFromJson !== null)
{
this.ClearDeathRow();
var ok = this.loadFromJSONString(this.loadFromJson);
if (ok)
{
this.lastSaveJson = this.loadFromJson;
this.trigger(cr.system_object.prototype.cnds.OnLoadComplete, null);
this.lastSaveJson = "";
}
else
{
self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
}
this.loadFromJson = null;
}
};
function CopyExtraObject(extra)
{
var p, ret = {};
for (p in extra)
{
if (extra.hasOwnProperty(p))
{
if (extra[p] instanceof cr.ObjectSet)
continue;
if (extra[p] && typeof extra[p].c2userdata !== "undefined")
continue;
if (p === "spriteCreatedDestroyCallback")
continue;
ret[p] = extra[p];
}
}
return ret;
};
Runtime.prototype.saveToJSONString = function()
{
var i, len, j, lenj, type, layout, typeobj, g, c, a, v, p;
var o = {
"c2save": true,
"version": 1,
"rt": {
"time": this.kahanTime.sum,
"walltime": this.wallTime.sum,
"timescale": this.timescale,
"tickcount": this.tickcount,
"execcount": this.execcount,
"next_uid": this.next_uid,
"running_layout": this.running_layout.sid,
"start_time_offset": (Date.now() - this.start_time)
},
"types": {},
"layouts": {},
"events": {
"groups": {},
"cnds": {},
"acts": {},
"vars": {}
}
};
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
type = this.types_by_index[i];
if (type.is_family || this.typeHasNoSaveBehavior(type))
continue;
typeobj = {
"instances": []
};
if (cr.hasAnyOwnProperty(type.extra))
typeobj["ex"] = CopyExtraObject(type.extra);
for (j = 0, lenj = type.instances.length; j < lenj; j++)
{
typeobj["instances"].push(this.saveInstanceToJSON(type.instances[j]));
}
o["types"][type.sid.toString()] = typeobj;
}
for (i = 0, len = this.layouts_by_index.length; i < len; i++)
{
layout = this.layouts_by_index[i];
o["layouts"][layout.sid.toString()] = layout.saveToJSON();
}
var ogroups = o["events"]["groups"];
for (i = 0, len = this.allGroups.length; i < len; i++)
{
g = this.allGroups[i];
ogroups[g.sid.toString()] = this.groups_by_name[g.group_name].group_active;
}
var ocnds = o["events"]["cnds"];
for (p in this.cndsBySid)
{
if (this.cndsBySid.hasOwnProperty(p))
{
c = this.cndsBySid[p];
if (cr.hasAnyOwnProperty(c.extra))
ocnds[p] = { "ex": CopyExtraObject(c.extra) };
}
}
var oacts = o["events"]["acts"];
for (p in this.actsBySid)
{
if (this.actsBySid.hasOwnProperty(p))
{
a = this.actsBySid[p];
if (cr.hasAnyOwnProperty(a.extra))
oacts[p] = { "ex": CopyExtraObject(a.extra) };
}
}
var ovars = o["events"]["vars"];
for (p in this.varsBySid)
{
if (this.varsBySid.hasOwnProperty(p))
{
v = this.varsBySid[p];
if (!v.is_constant && (!v.parent || v.is_static))
ovars[p] = v.data;
}
}
o["system"] = this.system.saveToJSON();
return JSON.stringify(o);
};
Runtime.prototype.refreshUidMap = function ()
{
var i, len, type, j, lenj, inst;
this.objectsByUid = {};
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
type = this.types_by_index[i];
if (type.is_family)
continue;
for (j = 0, lenj = type.instances.length; j < lenj; j++)
{
inst = type.instances[j];
this.objectsByUid[inst.uid.toString()] = inst;
}
}
};
Runtime.prototype.loadFromJSONString = function (str)
{
var o;
try {
o = JSON.parse(str);
}
catch (e) {
return false;
}
if (!o["c2save"])
return false; // probably not a c2 save state
if (o["version"] > 1)
return false; // from future version of c2; assume not compatible
this.isLoadingState = true;
var rt = o["rt"];
this.kahanTime.reset();
this.kahanTime.sum = rt["time"];
this.wallTime.reset();
this.wallTime.sum = rt["walltime"] || 0;
this.timescale = rt["timescale"];
this.tickcount = rt["tickcount"];
this.execcount = rt["execcount"];
this.start_time = Date.now() - rt["start_time_offset"];
var layout_sid = rt["running_layout"];
if (layout_sid !== this.running_layout.sid)
{
var changeToLayout = this.getLayoutBySid(layout_sid);
if (changeToLayout)
this.doChangeLayout(changeToLayout);
else
return; // layout that was saved on has gone missing (deleted?)
}
var i, len, j, lenj, k, lenk, p, type, existing_insts, load_insts, inst, binst, layout, layer, g, iid, t;
var otypes = o["types"];
for (p in otypes)
{
if (otypes.hasOwnProperty(p))
{
type = this.getObjectTypeBySid(parseInt(p, 10));
if (!type || type.is_family || this.typeHasNoSaveBehavior(type))
continue;
if (otypes[p]["ex"])
type.extra = otypes[p]["ex"];
else
cr.wipe(type.extra);
existing_insts = type.instances;
load_insts = otypes[p]["instances"];
for (i = 0, len = cr.min(existing_insts.length, load_insts.length); i < len; i++)
{
this.loadInstanceFromJSON(existing_insts[i], load_insts[i]);
}
for (i = load_insts.length, len = existing_insts.length; i < len; i++)
this.DestroyInstance(existing_insts[i]);
for (i = existing_insts.length, len = load_insts.length; i < len; i++)
{
layer = null;
if (type.plugin.is_world)
{
layer = this.running_layout.getLayerBySid(load_insts[i]["w"]["l"]);
if (!layer)
continue;
}
inst = this.createInstanceFromInit(type.default_instance, layer, false, 0, 0, true);
this.loadInstanceFromJSON(inst, load_insts[i]);
}
type.stale_iids = true;
}
}
this.ClearDeathRow();
this.refreshUidMap();
var olayouts = o["layouts"];
for (p in olayouts)
{
if (olayouts.hasOwnProperty(p))
{
layout = this.getLayoutBySid(parseInt(p, 10));
if (!layout)
continue; // must've gone missing
layout.loadFromJSON(olayouts[p]);
}
}
var ogroups = o["events"]["groups"];
for (p in ogroups)
{
if (ogroups.hasOwnProperty(p))
{
g = this.getGroupBySid(parseInt(p, 10));
if (g && this.groups_by_name[g.group_name])
this.groups_by_name[g.group_name].setGroupActive(ogroups[p]);
}
}
var ocnds = o["events"]["cnds"];
for (p in this.cndsBySid)
{
if (this.cndsBySid.hasOwnProperty(p))
{
if (ocnds.hasOwnProperty(p))
{
this.cndsBySid[p].extra = ocnds[p]["ex"];
}
else
{
this.cndsBySid[p].extra = {};
}
}
}
var oacts = o["events"]["acts"];
for (p in this.actsBySid)
{
if (this.actsBySid.hasOwnProperty(p))
{
if (oacts.hasOwnProperty(p))
{
this.actsBySid[p].extra = oacts[p]["ex"];
}
else
{
this.actsBySid[p].extra = {};
}
}
}
var ovars = o["events"]["vars"];
for (p in ovars)
{
if (ovars.hasOwnProperty(p) && this.varsBySid.hasOwnProperty(p))
{
this.varsBySid[p].data = ovars[p];
}
}
this.next_uid = rt["next_uid"];
this.isLoadingState = false;
for (i = 0, len = this.fireOnCreateAfterLoad.length; i < len; ++i)
{
inst = this.fireOnCreateAfterLoad[i];
this.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
}
cr.clearArray(this.fireOnCreateAfterLoad);
this.system.loadFromJSON(o["system"]);
for (i = 0, len = this.types_by_index.length; i < len; i++)
{
type = this.types_by_index[i];
if (type.is_family || this.typeHasNoSaveBehavior(type))
continue;
for (j = 0, lenj = type.instances.length; j < lenj; j++)
{
inst = type.instances[j];
if (type.is_contained)
{
iid = inst.get_iid();
cr.clearArray(inst.siblings);
for (k = 0, lenk = type.container.length; k < lenk; k++)
{
t = type.container[k];
if (type === t)
continue;
;
inst.siblings.push(t.instances[iid]);
}
}
if (inst.afterLoad)
inst.afterLoad();
if (inst.behavior_insts)
{
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
{
binst = inst.behavior_insts[k];
if (binst.afterLoad)
binst.afterLoad();
}
}
}
}
this.redraw = true;
return true;
};
Runtime.prototype.saveInstanceToJSON = function(inst, state_only)
{
var i, len, world, behinst, et;
var type = inst.type;
var plugin = type.plugin;
var o = {};
if (state_only)
o["c2"] = true; // mark as known json data from Construct 2
else
o["uid"] = inst.uid;
if (cr.hasAnyOwnProperty(inst.extra))
o["ex"] = CopyExtraObject(inst.extra);
if (inst.instance_vars && inst.instance_vars.length)
{
o["ivs"] = {};
for (i = 0, len = inst.instance_vars.length; i < len; i++)
{
o["ivs"][inst.type.instvar_sids[i].toString()] = inst.instance_vars[i];
}
}
if (plugin.is_world)
{
world = {
"x": inst.x,
"y": inst.y,
"w": inst.width,
"h": inst.height,
"l": inst.layer.sid,
"zi": inst.get_zindex()
};
if (inst.angle !== 0)
world["a"] = inst.angle;
if (inst.opacity !== 1)
world["o"] = inst.opacity;
if (inst.hotspotX !== 0.5)
world["hX"] = inst.hotspotX;
if (inst.hotspotY !== 0.5)
world["hY"] = inst.hotspotY;
if (inst.blend_mode !== 0)
world["bm"] = inst.blend_mode;
if (!inst.visible)
world["v"] = inst.visible;
if (!inst.collisionsEnabled)
world["ce"] = inst.collisionsEnabled;
if (inst.my_timescale !== -1)
world["mts"] = inst.my_timescale;
if (type.effect_types.length)
{
world["fx"] = [];
for (i = 0, len = type.effect_types.length; i < len; i++)
{
et = type.effect_types[i];
world["fx"].push({"name": et.name,
"active": inst.active_effect_flags[et.index],
"params": inst.effect_params[et.index] });
}
}
o["w"] = world;
}
if (inst.behavior_insts && inst.behavior_insts.length)
{
o["behs"] = {};
for (i = 0, len = inst.behavior_insts.length; i < len; i++)
{
behinst = inst.behavior_insts[i];
if (behinst.saveToJSON)
o["behs"][behinst.type.sid.toString()] = behinst.saveToJSON();
}
}
if (inst.saveToJSON)
o["data"] = inst.saveToJSON();
return o;
};
Runtime.prototype.getInstanceVarIndexBySid = function (type, sid_)
{
var i, len;
for (i = 0, len = type.instvar_sids.length; i < len; i++)
{
if (type.instvar_sids[i] === sid_)
return i;
}
return -1;
};
Runtime.prototype.getBehaviorIndexBySid = function (inst, sid_)
{
var i, len;
for (i = 0, len = inst.behavior_insts.length; i < len; i++)
{
if (inst.behavior_insts[i].type.sid === sid_)
return i;
}
return -1;
};
Runtime.prototype.loadInstanceFromJSON = function(inst, o, state_only)
{
var p, i, len, iv, oivs, world, fxindex, obehs, behindex, value;
var oldlayer;
var type = inst.type;
var plugin = type.plugin;
if (state_only)
{
if (!o["c2"])
return;
}
else
inst.uid = o["uid"];
if (o["ex"])
inst.extra = o["ex"];
else
cr.wipe(inst.extra);
oivs = o["ivs"];
if (oivs)
{
for (p in oivs)
{
if (oivs.hasOwnProperty(p))
{
iv = this.getInstanceVarIndexBySid(type, parseInt(p, 10));
if (iv < 0 || iv >= inst.instance_vars.length)
continue; // must've gone missing
value = oivs[p];
if (value === null)
value = NaN;
inst.instance_vars[iv] = value;
}
}
}
if (plugin.is_world)
{
world = o["w"];
if (inst.layer.sid !== world["l"])
{
oldlayer = inst.layer;
inst.layer = this.running_layout.getLayerBySid(world["l"]);
if (inst.layer)
{
oldlayer.removeFromInstanceList(inst, true);
inst.layer.appendToInstanceList(inst, true);
inst.set_bbox_changed();
inst.layer.setZIndicesStaleFrom(0);
}
else
{
inst.layer = oldlayer;
if (!state_only)
this.DestroyInstance(inst);
}
}
inst.x = world["x"];
inst.y = world["y"];
inst.width = world["w"];
inst.height = world["h"];
inst.zindex = world["zi"];
inst.angle = world.hasOwnProperty("a") ? world["a"] : 0;
inst.opacity = world.hasOwnProperty("o") ? world["o"] : 1;
inst.hotspotX = world.hasOwnProperty("hX") ? world["hX"] : 0.5;
inst.hotspotY = world.hasOwnProperty("hY") ? world["hY"] : 0.5;
inst.visible = world.hasOwnProperty("v") ? world["v"] : true;
inst.collisionsEnabled = world.hasOwnProperty("ce") ? world["ce"] : true;
inst.my_timescale = world.hasOwnProperty("mts") ? world["mts"] : -1;
inst.blend_mode = world.hasOwnProperty("bm") ? world["bm"] : 0;;
inst.compositeOp = cr.effectToCompositeOp(inst.blend_mode);
if (this.gl)
cr.setGLBlend(inst, inst.blend_mode, this.gl);
inst.set_bbox_changed();
if (world.hasOwnProperty("fx"))
{
for (i = 0, len = world["fx"].length; i < len; i++)
{
fxindex = type.getEffectIndexByName(world["fx"][i]["name"]);
if (fxindex < 0)
continue; // must've gone missing
inst.active_effect_flags[fxindex] = world["fx"][i]["active"];
inst.effect_params[fxindex] = world["fx"][i]["params"];
}
}
inst.updateActiveEffects();
}
obehs = o["behs"];
if (obehs)
{
for (p in obehs)
{
if (obehs.hasOwnProperty(p))
{
behindex = this.getBehaviorIndexBySid(inst, parseInt(p, 10));
if (behindex < 0)
continue; // must've gone missing
inst.behavior_insts[behindex].loadFromJSON(obehs[p]);
}
}
}
if (o["data"])
inst.loadFromJSON(o["data"]);
};
Runtime.prototype.fetchLocalFileViaCordova = function (filename, successCallback, errorCallback)
{
var path = cordova["file"]["applicationDirectory"] + "www/" + filename;
window["resolveLocalFileSystemURL"](path, function (entry)
{
entry.file(successCallback, errorCallback);
}, errorCallback);
};
Runtime.prototype.fetchLocalFileViaCordovaAsText = function (filename, successCallback, errorCallback)
{
this.fetchLocalFileViaCordova(filename, function (file)
{
var reader = new FileReader();
reader.onload = function (e)
{
successCallback(e.target.result);
};
reader.onerror = errorCallback;
reader.readAsText(file);
}, errorCallback);
};
var queuedArrayBufferReads = [];
var activeArrayBufferReads = 0;
var MAX_ARRAYBUFFER_READS = 8;
Runtime.prototype.maybeStartNextArrayBufferRead = function()
{
if (!queuedArrayBufferReads.length)
return; // none left
if (activeArrayBufferReads >= MAX_ARRAYBUFFER_READS)
return; // already got maximum number in-flight
activeArrayBufferReads++;
var job = queuedArrayBufferReads.shift();
this.doFetchLocalFileViaCordovaAsArrayBuffer(job.filename, job.successCallback, job.errorCallback);
};
Runtime.prototype.fetchLocalFileViaCordovaAsArrayBuffer = function (filename, successCallback_, errorCallback_)
{
var self = this;
queuedArrayBufferReads.push({
filename: filename,
successCallback: function (result)
{
activeArrayBufferReads--;
self.maybeStartNextArrayBufferRead();
successCallback_(result);
},
errorCallback: function (err)
{
activeArrayBufferReads--;
self.maybeStartNextArrayBufferRead();
errorCallback_(err);
}
});
this.maybeStartNextArrayBufferRead();
};
Runtime.prototype.doFetchLocalFileViaCordovaAsArrayBuffer = function (filename, successCallback, errorCallback)
{
this.fetchLocalFileViaCordova(filename, function (file)
{
var reader = new FileReader();
reader.onload = function (e)
{
successCallback(e.target.result);
};
reader.readAsArrayBuffer(file);
}, errorCallback);
};
Runtime.prototype.fetchLocalFileViaCordovaAsURL = function (filename, successCallback, errorCallback)
{
var blobType = "";
var lowername = filename.toLowerCase();
var ext3 = lowername.substr(lowername.length - 4);
var ext4 = lowername.substr(lowername.length - 5);
if (ext3 === ".mp4")
blobType = "video/mp4";
else if (ext4 === ".webm")
blobType = "video/webm"; // use video type but hopefully works with audio too
else if (ext3 === ".m4a")
blobType = "audio/mp4";
else if (ext3 === ".mp3")
blobType = "audio/mpeg";
this.fetchLocalFileViaCordovaAsArrayBuffer(filename, function (arrayBuffer)
{
var blob = new Blob([arrayBuffer], { type: blobType });
var url = URL.createObjectURL(blob);
successCallback(url);
}, errorCallback);
};
Runtime.prototype.isAbsoluteUrl = function (url)
{
return /^(?:[a-z]+:)?\/\//.test(url) || url.substr(0, 5) === "data:" || url.substr(0, 5) === "blob:";
};
Runtime.prototype.setImageSrc = function (img, src)
{
if (this.isWKWebView && !this.isAbsoluteUrl(src))
{
this.fetchLocalFileViaCordovaAsURL(src, function (url)
{
img.src = url;
}, function (err)
{
alert("Failed to load image: " + err);
});
}
else
{
img.src = src;
}
};
Runtime.prototype.setCtxImageSmoothingEnabled = function (ctx, e)
{
if (typeof ctx["imageSmoothingEnabled"] !== "undefined")
{
ctx["imageSmoothingEnabled"] = e;
}
else
{
ctx["webkitImageSmoothingEnabled"] = e;
ctx["mozImageSmoothingEnabled"] = e;
ctx["msImageSmoothingEnabled"] = e;
}
};
cr.runtime = Runtime;
cr.createRuntime = function (canvasid)
{
return new Runtime(document.getElementById(canvasid));
};
cr.createDCRuntime = function (w, h)
{
return new Runtime({ "dc": true, "width": w, "height": h });
};
window["cr_createRuntime"] = cr.createRuntime;
window["cr_createDCRuntime"] = cr.createDCRuntime;
window["createCocoonJSRuntime"] = function ()
{
window["c2cocoonjs"] = true;
var canvas = document.createElement("screencanvas") || document.createElement("canvas");
canvas.screencanvas = true;
document.body.appendChild(canvas);
var rt = new Runtime(canvas);
window["c2runtime"] = rt;
window.addEventListener("orientationchange", function () {
window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
});
window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
return rt;
};
window["createEjectaRuntime"] = function ()
{
var canvas = document.getElementById("canvas");
var rt = new Runtime(canvas);
window["c2runtime"] = rt;
window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
return rt;
};
}());
window["cr_getC2Runtime"] = function()
{
var canvas = document.getElementById("c2canvas");
if (canvas)
return canvas["c2runtime"];
else if (window["c2runtime"])
return window["c2runtime"];
else
return null;
}
window["cr_getSnapshot"] = function (format_, quality_)
{
var runtime = window["cr_getC2Runtime"]();
if (runtime)
runtime.doCanvasSnapshot(format_, quality_);
}
window["cr_sizeCanvas"] = function(w, h)
{
if (w === 0 || h === 0)
return;
var runtime = window["cr_getC2Runtime"]();
if (runtime)
runtime["setSize"](w, h);
}
window["cr_setSuspended"] = function(s)
{
var runtime = window["cr_getC2Runtime"]();
if (runtime)
runtime["setSuspended"](s);
}
;
(function()
{
function Layout(runtime, m)
{
this.runtime = runtime;
this.event_sheet = null;
this.scrollX = (this.runtime.original_width / 2);
this.scrollY = (this.runtime.original_height / 2);
this.scale = 1.0;
this.angle = 0;
this.first_visit = true;
this.name = m[0];
this.originalWidth = m[1];
this.originalHeight = m[2];
this.width = m[1];
this.height = m[2];
this.unbounded_scrolling = m[3];
this.sheetname = m[4];
this.sid = m[5];
var lm = m[6];
var i, len;
this.layers = [];
this.initial_types = [];
for (i = 0, len = lm.length; i < len; i++)
{
var layer = new cr.layer(this, lm[i]);
layer.number = i;
cr.seal(layer);
this.layers.push(layer);
}
var im = m[7];
this.initial_nonworld = [];
for (i = 0, len = im.length; i < len; i++)
{
var inst = im[i];
var type = this.runtime.types_by_index[inst[1]];
;
if (!type.default_instance)
type.default_instance = inst;
this.initial_nonworld.push(inst);
if (this.initial_types.indexOf(type) === -1)
this.initial_types.push(type);
}
this.effect_types = [];
this.active_effect_types = [];
this.shaders_preserve_opaqueness = true;
this.effect_params = [];
for (i = 0, len = m[8].length; i < len; i++)
{
this.effect_types.push({
id: m[8][i][0],
name: m[8][i][1],
shaderindex: -1,
preservesOpaqueness: false,
active: true,
index: i
});
this.effect_params.push(m[8][i][2].slice(0));
}
this.updateActiveEffects();
this.rcTex = new cr.rect(0, 0, 1, 1);
this.rcTex2 = new cr.rect(0, 0, 1, 1);
this.persist_data = {};
};
Layout.prototype.saveObjectToPersist = function (inst)
{
var sidStr = inst.type.sid.toString();
if (!this.persist_data.hasOwnProperty(sidStr))
this.persist_data[sidStr] = [];
var type_persist = this.persist_data[sidStr];
type_persist.push(this.runtime.saveInstanceToJSON(inst));
};
Layout.prototype.hasOpaqueBottomLayer = function ()
{
var layer = this.layers[0];
return !layer.transparent && layer.opacity === 1.0 && !layer.forceOwnTexture && layer.visible;
};
Layout.prototype.updateActiveEffects = function ()
{
cr.clearArray(this.active_effect_types);
this.shaders_preserve_opaqueness = true;
var i, len, et;
for (i = 0, len = this.effect_types.length; i < len; i++)
{
et = this.effect_types[i];
if (et.active)
{
this.active_effect_types.push(et);
if (!et.preservesOpaqueness)
this.shaders_preserve_opaqueness = false;
}
}
};
Layout.prototype.getEffectByName = function (name_)
{
var i, len, et;
for (i = 0, len = this.effect_types.length; i < len; i++)
{
et = this.effect_types[i];
if (et.name === name_)
return et;
}
return null;
};
var created_instances = [];
function sort_by_zindex(a, b)
{
return a.zindex - b.zindex;
};
var first_layout = true;
Layout.prototype.startRunning = function ()
{
if (this.sheetname)
{
this.event_sheet = this.runtime.eventsheets[this.sheetname];
;
this.event_sheet.updateDeepIncludes();
}
this.runtime.running_layout = this;
this.width = this.originalWidth;
this.height = this.originalHeight;
this.scrollX = (this.runtime.original_width / 2);
this.scrollY = (this.runtime.original_height / 2);
var i, k, len, lenk, type, type_instances, initial_inst, inst, iid, t, s, p, q, type_data, layer;
for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
{
type = this.runtime.types_by_index[i];
if (type.is_family)
continue; // instances are only transferred for their real type
type_instances = type.instances;
for (k = 0, lenk = type_instances.length; k < lenk; k++)
{
inst = type_instances[k];
if (inst.layer)
{
var num = inst.layer.number;
if (num >= this.layers.length)
num = this.layers.length - 1;
inst.layer = this.layers[num];
if (inst.layer.instances.indexOf(inst) === -1)
inst.layer.instances.push(inst);
inst.layer.zindices_stale = true;
}
}
}
if (!first_layout)
{
for (i = 0, len = this.layers.length; i < len; ++i)
{
this.layers[i].instances.sort(sort_by_zindex);
}
}
var layer;
cr.clearArray(created_instances);
this.boundScrolling();
for (i = 0, len = this.layers.length; i < len; i++)
{
layer = this.layers[i];
layer.createInitialInstances(); // fills created_instances
layer.updateViewport(null);
}
var uids_changed = false;
if (!this.first_visit)
{
for (p in this.persist_data)
{
if (this.persist_data.hasOwnProperty(p))
{
type = this.runtime.getObjectTypeBySid(parseInt(p, 10));
if (!type || type.is_family || !this.runtime.typeHasPersistBehavior(type))
continue;
type_data = this.persist_data[p];
for (i = 0, len = type_data.length; i < len; i++)
{
layer = null;
if (type.plugin.is_world)
{
layer = this.getLayerBySid(type_data[i]["w"]["l"]);
if (!layer)
continue;
}
inst = this.runtime.createInstanceFromInit(type.default_instance, layer, false, 0, 0, true);
this.runtime.loadInstanceFromJSON(inst, type_data[i]);
uids_changed = true;
created_instances.push(inst);
}
cr.clearArray(type_data);
}
}
for (i = 0, len = this.layers.length; i < len; i++)
{
this.layers[i].instances.sort(sort_by_zindex);
this.layers[i].zindices_stale = true; // in case of duplicates/holes
}
}
if (uids_changed)
{
this.runtime.ClearDeathRow();
this.runtime.refreshUidMap();
}
for (i = 0; i < created_instances.length; i++)
{
inst = created_instances[i];
if (!inst.type.is_contained)
continue;
iid = inst.get_iid();
for (k = 0, lenk = inst.type.container.length; k < lenk; k++)
{
t = inst.type.container[k];
if (inst.type === t)
continue;
if (t.instances.length > iid)
inst.siblings.push(t.instances[iid]);
else
{
if (!t.default_instance)
{
}
else
{
s = this.runtime.createInstanceFromInit(t.default_instance, inst.layer, true, inst.x, inst.y, true);
this.runtime.ClearDeathRow();
t.updateIIDs();
inst.siblings.push(s);
created_instances.push(s); // come back around and link up its own instances too
}
}
}
}
for (i = 0, len = this.initial_nonworld.length; i < len; i++)
{
initial_inst = this.initial_nonworld[i];
type = this.runtime.types_by_index[initial_inst[1]];
if (!type.is_contained)
{
inst = this.runtime.createInstanceFromInit(this.initial_nonworld[i], null, true);
}
;
}
this.runtime.changelayout = null;
this.runtime.ClearDeathRow();
if (this.runtime.ctx && !this.runtime.isDomFree)
{
for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
{
t = this.runtime.types_by_index[i];
if (t.is_family || !t.instances.length || !t.preloadCanvas2D)
continue;
t.preloadCanvas2D(this.runtime.ctx);
}
}
/*
if (this.runtime.glwrap)
{
console.log("Estimated VRAM at layout start: " + this.runtime.glwrap.textureCount() + " textures, approx. " + Math.round(this.runtime.glwrap.estimateVRAM() / 1024) + " kb");
}
*/
if (this.runtime.isLoadingState)
{
cr.shallowAssignArray(this.runtime.fireOnCreateAfterLoad, created_instances);
}
else
{
for (i = 0, len = created_instances.length; i < len; i++)
{
inst = created_instances[i];
this.runtime.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
}
}
cr.clearArray(created_instances);
if (!this.runtime.isLoadingState)
{
this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutStart, null);
}
this.first_visit = false;
};
Layout.prototype.createGlobalNonWorlds = function ()
{
var i, k, len, initial_inst, inst, type;
for (i = 0, k = 0, len = this.initial_nonworld.length; i < len; i++)
{
initial_inst = this.initial_nonworld[i];
type = this.runtime.types_by_index[initial_inst[1]];
if (type.global)
{
if (!type.is_contained)
{
inst = this.runtime.createInstanceFromInit(initial_inst, null, true);
}
}
else
{
this.initial_nonworld[k] = initial_inst;
k++;
}
}
cr.truncateArray(this.initial_nonworld, k);
};
Layout.prototype.stopRunning = function ()
{
;
/*
if (this.runtime.glwrap)
{
console.log("Estimated VRAM at layout end: " + this.runtime.glwrap.textureCount() + " textures, approx. " + Math.round(this.runtime.glwrap.estimateVRAM() / 1024) + " kb");
}
*/
if (!this.runtime.isLoadingState)
{
this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutEnd, null);
}
this.runtime.isEndingLayout = true;
cr.clearArray(this.runtime.system.waits);
var i, leni, j, lenj;
var layer_instances, inst, type;
if (!this.first_visit)
{
for (i = 0, leni = this.layers.length; i < leni; i++)
{
this.layers[i].updateZIndices();
layer_instances = this.layers[i].instances;
for (j = 0, lenj = layer_instances.length; j < lenj; j++)
{
inst = layer_instances[j];
if (!inst.type.global)
{
if (this.runtime.typeHasPersistBehavior(inst.type))
this.saveObjectToPersist(inst);
}
}
}
}
for (i = 0, leni = this.layers.length; i < leni; i++)
{
layer_instances = this.layers[i].instances;
for (j = 0, lenj = layer_instances.length; j < lenj; j++)
{
inst = layer_instances[j];
if (!inst.type.global)
{
this.runtime.DestroyInstance(inst);
}
}
this.runtime.ClearDeathRow();
cr.clearArray(layer_instances);
this.layers[i].zindices_stale = true;
}
for (i = 0, leni = this.runtime.types_by_index.length; i < leni; i++)
{
type = this.runtime.types_by_index[i];
if (type.global || type.plugin.is_world || type.plugin.singleglobal || type.is_family)
continue;
for (j = 0, lenj = type.instances.length; j < lenj; j++)
this.runtime.DestroyInstance(type.instances[j]);
this.runtime.ClearDeathRow();
}
first_layout = false;
this.runtime.isEndingLayout = false;
};
var temp_rect = new cr.rect(0, 0, 0, 0);
Layout.prototype.recreateInitialObjects = function (type, x1, y1, x2, y2)
{
temp_rect.set(x1, y1, x2, y2);
var i, len;
for (i = 0, len = this.layers.length; i < len; i++)
{
this.layers[i].recreateInitialObjects(type, temp_rect);
}
};
Layout.prototype.draw = function (ctx)
{
var layout_canvas;
var layout_ctx = ctx;
var ctx_changed = false;
var render_offscreen = !this.runtime.fullscreenScalingQuality;
if (render_offscreen)
{
if (!this.runtime.layout_canvas)
{
this.runtime.layout_canvas = document.createElement("canvas");
layout_canvas = this.runtime.layout_canvas;
layout_canvas.width = this.runtime.draw_width;
layout_canvas.height = this.runtime.draw_height;
this.runtime.layout_ctx = layout_canvas.getContext("2d");
ctx_changed = true;
}
layout_canvas = this.runtime.layout_canvas;
layout_ctx = this.runtime.layout_ctx;
if (layout_canvas.width !== this.runtime.draw_width)
{
layout_canvas.width = this.runtime.draw_width;
ctx_changed = true;
}
if (layout_canvas.height !== this.runtime.draw_height)
{
layout_canvas.height = this.runtime.draw_height;
ctx_changed = true;
}
if (ctx_changed)
{
this.runtime.setCtxImageSmoothingEnabled(layout_ctx, this.runtime.linearSampling);
}
}
layout_ctx.globalAlpha = 1;
layout_ctx.globalCompositeOperation = "source-over";
if (this.runtime.clearBackground && !this.hasOpaqueBottomLayer())
layout_ctx.clearRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
var i, len, l;
for (i = 0, len = this.layers.length; i < len; i++)
{
l = this.layers[i];
if (l.visible && l.opacity > 0 && l.blend_mode !== 11 && (l.instances.length || !l.transparent))
l.draw(layout_ctx);
else
l.updateViewport(null); // even if not drawing, keep viewport up to date
}
if (render_offscreen)
{
ctx.drawImage(layout_canvas, 0, 0, this.runtime.width, this.runtime.height);
}
};
Layout.prototype.drawGL_earlyZPass = function (glw)
{
glw.setEarlyZPass(true);
if (!this.runtime.layout_tex)
{
this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
}
if (this.runtime.layout_tex.c2width !== this.runtime.draw_width || this.runtime.layout_tex.c2height !== this.runtime.draw_height)
{
glw.deleteTexture(this.runtime.layout_tex);
this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
}
glw.setRenderingToTexture(this.runtime.layout_tex);
if (!this.runtime.fullscreenScalingQuality)
{
glw.setSize(this.runtime.draw_width, this.runtime.draw_height);
}
var i, l;
for (i = this.layers.length - 1; i >= 0; --i)
{
l = this.layers[i];
if (l.visible && l.opacity === 1 && l.shaders_preserve_opaqueness &&
l.blend_mode === 0 && (l.instances.length || !l.transparent))
{
l.drawGL_earlyZPass(glw);
}
else
{
l.updateViewport(null); // even if not drawing, keep viewport up to date
}
}
glw.setEarlyZPass(false);
};
Layout.prototype.drawGL = function (glw)
{
var render_to_texture = (this.active_effect_types.length > 0 ||
this.runtime.uses_background_blending ||
!this.runtime.fullscreenScalingQuality ||
this.runtime.enableFrontToBack);
if (render_to_texture)
{
if (!this.runtime.layout_tex)
{
this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
}
if (this.runtime.layout_tex.c2width !== this.runtime.draw_width || this.runtime.layout_tex.c2height !== this.runtime.draw_height)
{
glw.deleteTexture(this.runtime.layout_tex);
this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
}
glw.setRenderingToTexture(this.runtime.layout_tex);
if (!this.runtime.fullscreenScalingQuality)
{
glw.setSize(this.runtime.draw_width, this.runtime.draw_height);
}
}
else
{
if (this.runtime.layout_tex)
{
glw.setRenderingToTexture(null);
glw.deleteTexture(this.runtime.layout_tex);
this.runtime.layout_tex = null;
}
}
if (this.runtime.clearBackground && !this.hasOpaqueBottomLayer())
glw.clear(0, 0, 0, 0);
var i, len, l;
for (i = 0, len = this.layers.length; i < len; i++)
{
l = this.layers[i];
if (l.visible && l.opacity > 0 && (l.instances.length || !l.transparent))
l.drawGL(glw);
else
l.updateViewport(null); // even if not drawing, keep viewport up to date
}
if (render_to_texture)
{
if (this.active_effect_types.length === 0 ||
(this.active_effect_types.length === 1 && this.runtime.fullscreenScalingQuality))
{
if (this.active_effect_types.length === 1)
{
var etindex = this.active_effect_types[0].index;
glw.switchProgram(this.active_effect_types[0].shaderindex);
glw.setProgramParameters(null, // backTex
1.0 / this.runtime.draw_width, // pixelWidth
1.0 / this.runtime.draw_height, // pixelHeight
0.0, 0.0, // destStart
1.0, 1.0, // destEnd
this.scale, // layerScale
this.angle, // layerAngle
0.0, 0.0, // viewOrigin
this.runtime.draw_width / 2, this.runtime.draw_height / 2, // scrollPos
this.runtime.kahanTime.sum, // seconds
this.effect_params[etindex]); // fx parameters
if (glw.programIsAnimated(this.active_effect_types[0].shaderindex))
this.runtime.redraw = true;
}
else
glw.switchProgram(0);
if (!this.runtime.fullscreenScalingQuality)
{
glw.setSize(this.runtime.width, this.runtime.height);
}
glw.setRenderingToTexture(null); // to backbuffer
glw.setDepthTestEnabled(false); // ignore depth buffer, copy full texture
glw.setOpacity(1);
glw.setTexture(this.runtime.layout_tex);
glw.setAlphaBlend();
glw.resetModelView();
glw.updateModelView();
var halfw = this.runtime.width / 2;
var halfh = this.runtime.height / 2;
glw.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
glw.setTexture(null);
glw.setDepthTestEnabled(true); // turn depth test back on
}
else
{
this.renderEffectChain(glw, null, null, null);
}
}
};
Layout.prototype.getRenderTarget = function()
{
if (this.active_effect_types.length > 0 ||
this.runtime.uses_background_blending ||
!this.runtime.fullscreenScalingQuality ||
this.runtime.enableFrontToBack)
{
return this.runtime.layout_tex;
}
else
{
return null;
}
};
Layout.prototype.getMinLayerScale = function ()
{
var m = this.layers[0].getScale();
var i, len, l;
for (i = 1, len = this.layers.length; i < len; i++)
{
l = this.layers[i];
if (l.parallaxX === 0 && l.parallaxY === 0)
continue;
if (l.getScale() < m)
m = l.getScale();
}
return m;
};
Layout.prototype.scrollToX = function (x)
{
if (!this.unbounded_scrolling)
{
var widthBoundary = (this.runtime.draw_width * (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.redraw = true;
}
};
Layout.prototype.scrollToY = function (y)
{
if (!this.unbounded_scrolling)
{
var heightBoundary = (this.runtime.draw_height * (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.redraw = true;
}
};
Layout.prototype.boundScrolling = function ()
{
this.scrollToX(this.scrollX);
this.scrollToY(this.scrollY);
};
Layout.prototype.renderEffectChain = function (glw, layer, inst, rendertarget)
{
var active_effect_types = inst ?
inst.active_effect_types :
layer ?
layer.active_effect_types :
this.active_effect_types;
var layerScale = 1, layerAngle = 0, viewOriginLeft = 0, viewOriginTop = 0, viewOriginRight = this.runtime.draw_width, viewOriginBottom = this.runtime.draw_height;
if (inst)
{
layerScale = inst.layer.getScale();
layerAngle = inst.layer.getAngle();
viewOriginLeft = inst.layer.viewLeft;
viewOriginTop = inst.layer.viewTop;
viewOriginRight = inst.layer.viewRight;
viewOriginBottom = inst.layer.viewBottom;
}
else if (layer)
{
layerScale = layer.getScale();
layerAngle = layer.getAngle();
viewOriginLeft = layer.viewLeft;
viewOriginTop = layer.viewTop;
viewOriginRight = layer.viewRight;
viewOriginBottom = layer.viewBottom;
}
var fx_tex = this.runtime.fx_tex;
var i, len, last, temp, fx_index = 0, other_fx_index = 1;
var y, h;
var windowWidth = this.runtime.draw_width;
var windowHeight = this.runtime.draw_height;
var halfw = windowWidth / 2;
var halfh = windowHeight / 2;
var rcTex = layer ? layer.rcTex : this.rcTex;
var rcTex2 = layer ? layer.rcTex2 : this.rcTex2;
var screenleft = 0, clearleft = 0;
var screentop = 0, cleartop = 0;
var screenright = windowWidth, clearright = windowWidth;
var screenbottom = windowHeight, clearbottom = windowHeight;
var boxExtendHorizontal = 0;
var boxExtendVertical = 0;
var inst_layer_angle = inst ? inst.layer.getAngle() : 0;
if (inst)
{
for (i = 0, len = active_effect_types.length; i < len; i++)
{
boxExtendHorizontal += glw.getProgramBoxExtendHorizontal(active_effect_types[i].shaderindex);
boxExtendVertical += glw.getProgramBoxExtendVertical(active_effect_types[i].shaderindex);
}
var bbox = inst.bbox;
screenleft = layer.layerToCanvas(bbox.left, bbox.top, true, true);
screentop = layer.layerToCanvas(bbox.left, bbox.top, false, true);
screenright = layer.layerToCanvas(bbox.right, bbox.bottom, true, true);
screenbottom = layer.layerToCanvas(bbox.right, bbox.bottom, false, true);
if (inst_layer_angle !== 0)
{
var screentrx = layer.layerToCanvas(bbox.right, bbox.top, true, true);
var screentry = layer.layerToCanvas(bbox.right, bbox.top, false, true);
var screenblx = layer.layerToCanvas(bbox.left, bbox.bottom, true, true);
var screenbly = layer.layerToCanvas(bbox.left, bbox.bottom, false, true);
temp = Math.min(screenleft, screenright, screentrx, screenblx);
screenright = Math.max(screenleft, screenright, screentrx, screenblx);
screenleft = temp;
temp = Math.min(screentop, screenbottom, screentry, screenbly);
screenbottom = Math.max(screentop, screenbottom, screentry, screenbly);
screentop = temp;
}
screenleft -= boxExtendHorizontal;
screentop -= boxExtendVertical;
screenright += boxExtendHorizontal;
screenbottom += boxExtendVertical;
rcTex2.left = screenleft / windowWidth;
rcTex2.top = 1 - screentop / windowHeight;
rcTex2.right = screenright / windowWidth;
rcTex2.bottom = 1 - screenbottom / windowHeight;
clearleft = screenleft = cr.floor(screenleft);
cleartop = screentop = cr.floor(screentop);
clearright = screenright = cr.ceil(screenright);
clearbottom = screenbottom = cr.ceil(screenbottom);
clearleft -= boxExtendHorizontal;
cleartop -= boxExtendVertical;
clearright += boxExtendHorizontal;
clearbottom += boxExtendVertical;
if (screenleft < 0) screenleft = 0;
if (screentop < 0) screentop = 0;
if (screenright > windowWidth) screenright = windowWidth;
if (screenbottom > windowHeight) screenbottom = windowHeight;
if (clearleft < 0) clearleft = 0;
if (cleartop < 0) cleartop = 0;
if (clearright > windowWidth) clearright = windowWidth;
if (clearbottom > windowHeight) clearbottom = windowHeight;
rcTex.left = screenleft / windowWidth;
rcTex.top = 1 - screentop / windowHeight;
rcTex.right = screenright / windowWidth;
rcTex.bottom = 1 - screenbottom / windowHeight;
}
else
{
rcTex.left = rcTex2.left = 0;
rcTex.top = rcTex2.top = 0;
rcTex.right = rcTex2.right = 1;
rcTex.bottom = rcTex2.bottom = 1;
}
var pre_draw = (inst && (glw.programUsesDest(active_effect_types[0].shaderindex) || boxExtendHorizontal !== 0 || boxExtendVertical !== 0 || inst.opacity !== 1 || inst.type.plugin.must_predraw)) || (layer && !inst && layer.opacity !== 1);
glw.setAlphaBlend();
if (pre_draw)
{
if (!fx_tex[fx_index])
{
fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
}
if (fx_tex[fx_index].c2width !== windowWidth || fx_tex[fx_index].c2height !== windowHeight)
{
glw.deleteTexture(fx_tex[fx_index]);
fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
}
glw.switchProgram(0);
glw.setRenderingToTexture(fx_tex[fx_index]);
h = clearbottom - cleartop;
y = (windowHeight - cleartop) - h;
glw.clearRect(clearleft, y, clearright - clearleft, h);
if (inst)
{
inst.drawGL(glw);
}
else
{
glw.setTexture(this.runtime.layer_tex);
glw.setOpacity(layer.opacity);
glw.resetModelView();
glw.translate(-halfw, -halfh);
glw.updateModelView();
glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
}
rcTex2.left = rcTex2.top = 0;
rcTex2.right = rcTex2.bottom = 1;
if (inst)
{
temp = rcTex.top;
rcTex.top = rcTex.bottom;
rcTex.bottom = temp;
}
fx_index = 1;
other_fx_index = 0;
}
glw.setOpacity(1);
var last = active_effect_types.length - 1;
var post_draw = glw.programUsesCrossSampling(active_effect_types[last].shaderindex) ||
(!layer && !inst && !this.runtime.fullscreenScalingQuality);
var etindex = 0;
for (i = 0, len = active_effect_types.length; i < len; i++)
{
if (!fx_tex[fx_index])
{
fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
}
if (fx_tex[fx_index].c2width !== windowWidth || fx_tex[fx_index].c2height !== windowHeight)
{
glw.deleteTexture(fx_tex[fx_index]);
fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
}
glw.switchProgram(active_effect_types[i].shaderindex);
etindex = active_effect_types[i].index;
if (glw.programIsAnimated(active_effect_types[i].shaderindex))
this.runtime.redraw = true;
if (i == 0 && !pre_draw)
{
glw.setRenderingToTexture(fx_tex[fx_index]);
h = clearbottom - cleartop;
y = (windowHeight - cleartop) - h;
glw.clearRect(clearleft, y, clearright - clearleft, h);
if (inst)
{
var pixelWidth;
var pixelHeight;
if (inst.curFrame && inst.curFrame.texture_img)
{
var img = inst.curFrame.texture_img;
pixelWidth = 1.0 / img.width;
pixelHeight = 1.0 / img.height;
}
else
{
pixelWidth = 1.0 / inst.width;
pixelHeight = 1.0 / inst.height;
}
glw.setProgramParameters(rendertarget, // backTex
pixelWidth,
pixelHeight,
rcTex2.left, rcTex2.top, // destStart
rcTex2.right, rcTex2.bottom, // destEnd
layerScale,
layerAngle,
viewOriginLeft, viewOriginTop,
(viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
this.runtime.kahanTime.sum,
inst.effect_params[etindex]); // fx params
inst.drawGL(glw);
}
else
{
glw.setProgramParameters(rendertarget, // backTex
1.0 / windowWidth, // pixelWidth
1.0 / windowHeight, // pixelHeight
0.0, 0.0, // destStart
1.0, 1.0, // destEnd
layerScale,
layerAngle,
viewOriginLeft, viewOriginTop,
(viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
this.runtime.kahanTime.sum,
layer ? // fx params
layer.effect_params[etindex] :
this.effect_params[etindex]);
glw.setTexture(layer ? this.runtime.layer_tex : this.runtime.layout_tex);
glw.resetModelView();
glw.translate(-halfw, -halfh);
glw.updateModelView();
glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
}
rcTex2.left = rcTex2.top = 0;
rcTex2.right = rcTex2.bottom = 1;
if (inst && !post_draw)
{
temp = screenbottom;
screenbottom = screentop;
screentop = temp;
}
}
else
{
glw.setProgramParameters(rendertarget, // backTex
1.0 / windowWidth, // pixelWidth
1.0 / windowHeight, // pixelHeight
rcTex2.left, rcTex2.top, // destStart
rcTex2.right, rcTex2.bottom, // destEnd
layerScale,
layerAngle,
viewOriginLeft, viewOriginTop,
(viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
this.runtime.kahanTime.sum,
inst ? // fx params
inst.effect_params[etindex] :
layer ?
layer.effect_params[etindex] :
this.effect_params[etindex]);
glw.setTexture(null);
if (i === last && !post_draw)
{
if (inst)
glw.setBlend(inst.srcBlend, inst.destBlend);
else if (layer)
glw.setBlend(layer.srcBlend, layer.destBlend);
glw.setRenderingToTexture(rendertarget);
}
else
{
glw.setRenderingToTexture(fx_tex[fx_index]);
h = clearbottom - cleartop;
y = (windowHeight - cleartop) - h;
glw.clearRect(clearleft, y, clearright - clearleft, h);
}
glw.setTexture(fx_tex[other_fx_index]);
glw.resetModelView();
glw.translate(-halfw, -halfh);
glw.updateModelView();
glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
if (i === last && !post_draw)
glw.setTexture(null);
}
fx_index = (fx_index === 0 ? 1 : 0);
other_fx_index = (fx_index === 0 ? 1 : 0); // will be opposite to fx_index since it was just assigned
}
if (post_draw)
{
glw.switchProgram(0);
if (inst)
glw.setBlend(inst.srcBlend, inst.destBlend);
else if (layer)
glw.setBlend(layer.srcBlend, layer.destBlend);
else
{
if (!this.runtime.fullscreenScalingQuality)
{
glw.setSize(this.runtime.width, this.runtime.height);
halfw = this.runtime.width / 2;
halfh = this.runtime.height / 2;
screenleft = 0;
screentop = 0;
screenright = this.runtime.width;
screenbottom = this.runtime.height;
}
}
glw.setRenderingToTexture(rendertarget);
glw.setTexture(fx_tex[other_fx_index]);
glw.resetModelView();
glw.translate(-halfw, -halfh);
glw.updateModelView();
if (inst && active_effect_types.length === 1 && !pre_draw)
glw.quadTex(screenleft, screentop, screenright, screentop, screenright, screenbottom, screenleft, screenbottom, rcTex);
else
glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
glw.setTexture(null);
}
};
Layout.prototype.getLayerBySid = function (sid_)
{
var i, len;
for (i = 0, len = this.layers.length; i < len; i++)
{
if (this.layers[i].sid === sid_)
return this.layers[i];
}
return null;
};
Layout.prototype.saveToJSON = function ()
{
var i, len, layer, et;
var o = {
"sx": this.scrollX,
"sy": this.scrollY,
"s": this.scale,
"a": this.angle,
"w": this.width,
"h": this.height,
"fv": this.first_visit, // added r127
"persist": this.persist_data,
"fx": [],
"layers": {}
};
for (i = 0, len = this.effect_types.length; i < len; i++)
{
et = this.effect_types[i];
o["fx"].push({"name": et.name, "active": et.active, "params": this.effect_params[et.index] });
}
for (i = 0, len = this.layers.length; i < len; i++)
{
layer = this.layers[i];
o["layers"][layer.sid.toString()] = layer.saveToJSON();
}
return o;
};
Layout.prototype.loadFromJSON = function (o)
{
var i, j, len, fx, p, layer;
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.persist_data = o["persist"];
if (typeof o["fv"] !== "undefined")
this.first_visit = o["fv"];
var ofx = o["fx"];
for (i = 0, len = ofx.length; i < len; i++)
{
fx = this.getEffectByName(ofx[i]["name"]);
if (!fx)
continue; // must've gone missing
fx.active = ofx[i]["active"];
this.effect_params[fx.index] = ofx[i]["params"];
}
this.updateActiveEffects();
var olayers = o["layers"];
for (p in olayers)
{
if (olayers.hasOwnProperty(p))
{
layer = this.getLayerBySid(parseInt(p, 10));
if (!layer)
continue; // must've gone missing
layer.loadFromJSON(olayers[p]);
}
}
};
cr.layout = Layout;
function Layer(layout, m)
{
this.layout = layout;
this.runtime = layout.runtime;
this.instances = []; // running instances
this.scale = 1.0;
this.angle = 0;
this.disableAngle = false;
this.tmprect = new cr.rect(0, 0, 0, 0);
this.tmpquad = new cr.quad();
this.viewLeft = 0;
this.viewRight = 0;
this.viewTop = 0;
this.viewBottom = 0;
this.zindices_stale = false;
this.zindices_stale_from = -1; // first index that has changed, or -1 if no bound
this.clear_earlyz_index = 0;
this.name = m[0];
this.index = m[1];
this.sid = m[2];
this.visible = m[3]; // initially visible
this.background_color = m[4];
this.transparent = m[5];
this.parallaxX = m[6];
this.parallaxY = m[7];
this.opacity = m[8];
this.forceOwnTexture = m[9];
this.useRenderCells = m[10];
this.zoomRate = m[11];
this.blend_mode = m[12];
this.effect_fallback = m[13];
this.compositeOp = "source-over";
this.srcBlend = 0;
this.destBlend = 0;
this.render_grid = null;
this.last_render_list = alloc_arr();
this.render_list_stale = true;
this.last_render_cells = new cr.rect(0, 0, -1, -1);
this.cur_render_cells = new cr.rect(0, 0, -1, -1);
if (this.useRenderCells)
{
this.render_grid = new cr.RenderGrid(this.runtime.original_width, this.runtime.original_height);
}
this.render_offscreen = false;
var im = m[14];
var i, len;
this.startup_initial_instances = []; // for restoring initial_instances after load
this.initial_instances = [];
this.created_globals = []; // global object UIDs already created - for save/load to avoid recreating
for (i = 0, len = im.length; i < len; i++)
{
var inst = im[i];
var type = this.runtime.types_by_index[inst[1]];
;
if (!type.default_instance)
{
type.default_instance = inst;
type.default_layerindex = this.index;
}
this.initial_instances.push(inst);
if (this.layout.initial_types.indexOf(type) === -1)
this.layout.initial_types.push(type);
}
cr.shallowAssignArray(this.startup_initial_instances, this.initial_instances);
this.effect_types = [];
this.active_effect_types = [];
this.shaders_preserve_opaqueness = true;
this.effect_params = [];
for (i = 0, len = m[15].length; i < len; i++)
{
this.effect_types.push({
id: m[15][i][0],
name: m[15][i][1],
shaderindex: -1,
preservesOpaqueness: false,
active: true,
index: i
});
this.effect_params.push(m[15][i][2].slice(0));
}
this.updateActiveEffects();
this.rcTex = new cr.rect(0, 0, 1, 1);
this.rcTex2 = new cr.rect(0, 0, 1, 1);
};
Layer.prototype.updateActiveEffects = function ()
{
cr.clearArray(this.active_effect_types);
this.shaders_preserve_opaqueness = true;
var i, len, et;
for (i = 0, len = this.effect_types.length; i < len; i++)
{
et = this.effect_types[i];
if (et.active)
{
this.active_effect_types.push(et);
if (!et.preservesOpaqueness)
this.shaders_preserve_opaqueness = false;
}
}
};
Layer.prototype.getEffectByName = function (name_)
{
var i, len, et;
for (i = 0, len = this.effect_types.length; i < len; i++)
{
et = this.effect_types[i];
if (et.name === name_)
return et;
}
return null;
};
Layer.prototype.createInitialInstances = function ()
{
var i, k, len, inst, initial_inst, type, keep, hasPersistBehavior;
for (i = 0, k = 0, len = this.initial_instances.length; i < len; i++)
{
initial_inst = this.initial_instances[i];
type = this.runtime.types_by_index[initial_inst[1]];
;
hasPersistBehavior = this.runtime.typeHasPersistBehavior(type);
keep = true;
if (!hasPersistBehavior || this.layout.first_visit)
{
inst = this.runtime.createInstanceFromInit(initial_inst, this, true);
if (!inst)
continue; // may have skipped creation due to fallback effect "destroy"
created_instances.push(inst);
if (inst.type.global)
{
keep = false;
this.created_globals.push(inst.uid);
}
}
if (keep)
{
this.initial_instances[k] = this.initial_instances[i];
k++;
}
}
this.initial_instances.length = k;
this.runtime.ClearDeathRow(); // flushes creation row so IIDs will be correct
if (!this.runtime.glwrap && this.effect_types.length) // no WebGL renderer and shaders used
this.blend_mode = this.effect_fallback; // use fallback blend mode
this.compositeOp = cr.effectToCompositeOp(this.blend_mode);
if (this.runtime.gl)
cr.setGLBlend(this, this.blend_mode, this.runtime.gl);
this.render_list_stale = true;
};
Layer.prototype.recreateInitialObjects = function (only_type, rc)
{
var i, len, initial_inst, type, wm, x, y, inst, j, lenj, s;
var types_by_index = this.runtime.types_by_index;
var only_type_is_family = only_type.is_family;
var only_type_members = only_type.members;
for (i = 0, len = this.initial_instances.length; i < len; ++i)
{
initial_inst = this.initial_instances[i];
wm = initial_inst[0];
x = wm[0];
y = wm[1];
if (!rc.contains_pt(x, y))
continue; // not in the given area
type = types_by_index[initial_inst[1]];
if (type !== only_type)
{
if (only_type_is_family)
{
if (only_type_members.indexOf(type) < 0)
continue;
}
else
continue; // only_type is not a family, and the initial inst type does not match
}
inst = this.runtime.createInstanceFromInit(initial_inst, this, false);
this.runtime.isInOnDestroy++;
this.runtime.trigger(Object.getPrototypeOf(type.plugin).cnds.OnCreated, inst);
if (inst.is_contained)
{
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
{
s = inst.siblings[i];
this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
}
}
this.runtime.isInOnDestroy--;
}
};
Layer.prototype.removeFromInstanceList = function (inst, remove_from_grid)
{
var index = cr.fastIndexOf(this.instances, inst);
if (index < 0)
return; // not found
if (remove_from_grid && this.useRenderCells && inst.rendercells && inst.rendercells.right >= inst.rendercells.left)
{
inst.update_bbox(); // make sure actually in its current rendercells
this.render_grid.update(inst, inst.rendercells, null); // no new range provided - remove only
inst.rendercells.set(0, 0, -1, -1); // set to invalid state to indicate not inserted
}
if (index === this.instances.length - 1)
this.instances.pop();
else
{
cr.arrayRemove(this.instances, index);
this.setZIndicesStaleFrom(index);
}
this.render_list_stale = true;
};
Layer.prototype.appendToInstanceList = function (inst, add_to_grid)
{
;
inst.zindex = this.instances.length;
this.instances.push(inst);
if (add_to_grid && this.useRenderCells && inst.rendercells)
{
inst.set_bbox_changed(); // will cause immediate update and new insertion to grid
}
this.render_list_stale = true;
};
Layer.prototype.prependToInstanceList = function (inst, add_to_grid)
{
;
this.instances.unshift(inst);
this.setZIndicesStaleFrom(0);
if (add_to_grid && this.useRenderCells && inst.rendercells)
{
inst.set_bbox_changed(); // will cause immediate update and new insertion to grid
}
};
Layer.prototype.moveInstanceAdjacent = function (inst, other, isafter)
{
;
var myZ = inst.get_zindex();
var insertZ = other.get_zindex();
cr.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.setZIndicesStaleFrom(myZ < insertZ ? myZ : insertZ);
};
Layer.prototype.setZIndicesStaleFrom = function (index)
{
if (this.zindices_stale_from === -1) // not yet set
this.zindices_stale_from = index;
else if (index < this.zindices_stale_from) // determine minimum z index affected
this.zindices_stale_from = index;
this.zindices_stale = true;
this.render_list_stale = true;
};
Layer.prototype.updateZIndices = function ()
{
if (!this.zindices_stale)
return;
if (this.zindices_stale_from === -1)
this.zindices_stale_from = 0;
var i, len, inst;
if (this.useRenderCells)
{
for (i = this.zindices_stale_from, len = this.instances.length; i < len; ++i)
{
inst = this.instances[i];
inst.zindex = i;
this.render_grid.markRangeChanged(inst.rendercells);
}
}
else
{
for (i = this.zindices_stale_from, len = this.instances.length; i < len; ++i)
{
this.instances[i].zindex = i;
}
}
this.zindices_stale = false;
this.zindices_stale_from = -1;
};
Layer.prototype.getScale = function (include_aspect)
{
return this.getNormalScale() * (this.runtime.fullscreenScalingQuality || include_aspect ? this.runtime.aspect_scale : 1);
};
Layer.prototype.getNormalScale = function ()
{
return ((this.scale * this.layout.scale) - 1) * this.zoomRate + 1;
};
Layer.prototype.getAngle = function ()
{
if (this.disableAngle)
return 0;
return cr.clamp_angle(this.layout.angle + this.angle);
};
var arr_cache = [];
function alloc_arr()
{
if (arr_cache.length)
return arr_cache.pop();
else
return [];
}
function free_arr(a)
{
cr.clearArray(a);
arr_cache.push(a);
};
function mergeSortedZArrays(a, b, out)
{
var i = 0, j = 0, k = 0, lena = a.length, lenb = b.length, ai, bj;
out.length = lena + lenb;
for ( ; i < lena && j < lenb; ++k)
{
ai = a[i];
bj = b[j];
if (ai.zindex < bj.zindex)
{
out[k] = ai;
++i;
}
else
{
out[k] = bj;
++j;
}
}
for ( ; i < lena; ++i, ++k)
out[k] = a[i];
for ( ; j < lenb; ++j, ++k)
out[k] = b[j];
};
var next_arr = [];
function mergeAllSortedZArrays_pass(arr, first_pass)
{
var i, len, arr1, arr2, out;
for (i = 0, len = arr.length; i < len - 1; i += 2)
{
arr1 = arr[i];
arr2 = arr[i+1];
out = alloc_arr();
mergeSortedZArrays(arr1, arr2, out);
if (!first_pass)
{
free_arr(arr1);
free_arr(arr2);
}
next_arr.push(out);
}
if (len % 2 === 1)
{
if (first_pass)
{
arr1 = alloc_arr();
cr.shallowAssignArray(arr1, arr[len - 1]);
next_arr.push(arr1);
}
else
{
next_arr.push(arr[len - 1]);
}
}
cr.shallowAssignArray(arr, next_arr);
cr.clearArray(next_arr);
};
function mergeAllSortedZArrays(arr)
{
var first_pass = true;
while (arr.length > 1)
{
mergeAllSortedZArrays_pass(arr, first_pass);
first_pass = false;
}
return arr[0];
};
var render_arr = [];
Layer.prototype.getRenderCellInstancesToDraw = function ()
{
;
this.updateZIndices();
this.render_grid.queryRange(this.viewLeft, this.viewTop, this.viewRight, this.viewBottom, render_arr);
if (!render_arr.length)
return alloc_arr();
if (render_arr.length === 1)
{
var a = alloc_arr();
cr.shallowAssignArray(a, render_arr[0]);
cr.clearArray(render_arr);
return a;
}
var draw_list = mergeAllSortedZArrays(render_arr);
cr.clearArray(render_arr);
return draw_list;
};
Layer.prototype.draw = function (ctx)
{
this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0 || this.blend_mode !== 0);
var layer_canvas = this.runtime.canvas;
var layer_ctx = ctx;
var ctx_changed = false;
if (this.render_offscreen)
{
if (!this.runtime.layer_canvas)
{
this.runtime.layer_canvas = document.createElement("canvas");
;
layer_canvas = this.runtime.layer_canvas;
layer_canvas.width = this.runtime.draw_width;
layer_canvas.height = this.runtime.draw_height;
this.runtime.layer_ctx = layer_canvas.getContext("2d");
;
ctx_changed = true;
}
layer_canvas = this.runtime.layer_canvas;
layer_ctx = this.runtime.layer_ctx;
if (layer_canvas.width !== this.runtime.draw_width)
{
layer_canvas.width = this.runtime.draw_width;
ctx_changed = true;
}
if (layer_canvas.height !== this.runtime.draw_height)
{
layer_canvas.height = this.runtime.draw_height;
ctx_changed = true;
}
if (ctx_changed)
{
this.runtime.setCtxImageSmoothingEnabled(layer_ctx, this.runtime.linearSampling);
}
if (this.transparent)
layer_ctx.clearRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
}
layer_ctx.globalAlpha = 1;
layer_ctx.globalCompositeOperation = "source-over";
if (!this.transparent)
{
layer_ctx.fillStyle = "rgb(" + this.background_color[0] + "," + this.background_color[1] + "," + this.background_color[2] + ")";
layer_ctx.fillRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
}
layer_ctx.save();
this.disableAngle = true;
var px = this.canvasToLayer(0, 0, true, true);
var py = this.canvasToLayer(0, 0, false, true);
this.disableAngle = false;
if (this.runtime.pixel_rounding)
{
px = Math.round(px);
py = Math.round(py);
}
this.rotateViewport(px, py, layer_ctx);
var myscale = this.getScale();
layer_ctx.scale(myscale, myscale);
layer_ctx.translate(-px, -py);
var instances_to_draw;
if (this.useRenderCells)
{
this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
{
free_arr(this.last_render_list);
instances_to_draw = this.getRenderCellInstancesToDraw();
this.render_list_stale = false;
this.last_render_cells.copy(this.cur_render_cells);
}
else
instances_to_draw = this.last_render_list;
}
else
instances_to_draw = this.instances;
var i, len, inst, last_inst = null;
for (i = 0, len = instances_to_draw.length; i < len; ++i)
{
inst = instances_to_draw[i];
if (inst === last_inst)
continue;
this.drawInstance(inst, layer_ctx);
last_inst = inst;
}
if (this.useRenderCells)
this.last_render_list = instances_to_draw;
layer_ctx.restore();
if (this.render_offscreen)
{
ctx.globalCompositeOperation = this.compositeOp;
ctx.globalAlpha = this.opacity;
ctx.drawImage(layer_canvas, 0, 0);
}
};
Layer.prototype.drawInstance = function(inst, layer_ctx)
{
if (!inst.visible || inst.width === 0 || inst.height === 0)
return;
inst.update_bbox();
var bbox = inst.bbox;
if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
return;
layer_ctx.globalCompositeOperation = inst.compositeOp;
inst.draw(layer_ctx);
};
Layer.prototype.updateViewport = function (ctx)
{
this.disableAngle = true;
var px = this.canvasToLayer(0, 0, true, true);
var py = this.canvasToLayer(0, 0, false, true);
this.disableAngle = false;
if (this.runtime.pixel_rounding)
{
px = Math.round(px);
py = Math.round(py);
}
this.rotateViewport(px, py, ctx);
};
Layer.prototype.rotateViewport = function (px, py, ctx)
{
var myscale = this.getScale();
this.viewLeft = px;
this.viewTop = py;
this.viewRight = px + (this.runtime.draw_width * (1 / myscale));
this.viewBottom = py + (this.runtime.draw_height * (1 / myscale));
var temp;
if (this.viewLeft > this.viewRight)
{
temp = this.viewLeft;
this.viewLeft = this.viewRight;
this.viewRight = temp;
}
if (this.viewTop > this.viewBottom)
{
temp = this.viewTop;
this.viewTop = this.viewBottom;
this.viewBottom = temp;
}
var myAngle = this.getAngle();
if (myAngle !== 0)
{
if (ctx)
{
ctx.translate(this.runtime.draw_width / 2, this.runtime.draw_height / 2);
ctx.rotate(-myAngle);
ctx.translate(this.runtime.draw_width / -2, this.runtime.draw_height / -2);
}
this.tmprect.set(this.viewLeft, this.viewTop, this.viewRight, this.viewBottom);
this.tmprect.offset((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
this.tmpquad.set_from_rotated_rect(this.tmprect, myAngle);
this.tmpquad.bounding_box(this.tmprect);
this.tmprect.offset((this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2);
this.viewLeft = this.tmprect.left;
this.viewTop = this.tmprect.top;
this.viewRight = this.tmprect.right;
this.viewBottom = this.tmprect.bottom;
}
}
Layer.prototype.drawGL_earlyZPass = function (glw)
{
var windowWidth = this.runtime.draw_width;
var windowHeight = this.runtime.draw_height;
var shaderindex = 0;
var etindex = 0;
this.render_offscreen = this.forceOwnTexture;
if (this.render_offscreen)
{
if (!this.runtime.layer_tex)
{
this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
}
if (this.runtime.layer_tex.c2width !== this.runtime.draw_width || this.runtime.layer_tex.c2height !== this.runtime.draw_height)
{
glw.deleteTexture(this.runtime.layer_tex);
this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
}
glw.setRenderingToTexture(this.runtime.layer_tex);
}
this.disableAngle = true;
var px = this.canvasToLayer(0, 0, true, true);
var py = this.canvasToLayer(0, 0, false, true);
this.disableAngle = false;
if (this.runtime.pixel_rounding)
{
px = Math.round(px);
py = Math.round(py);
}
this.rotateViewport(px, py, null);
var myscale = this.getScale();
glw.resetModelView();
glw.scale(myscale, myscale);
glw.rotateZ(-this.getAngle());
glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
glw.updateModelView();
var instances_to_draw;
if (this.useRenderCells)
{
this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
{
free_arr(this.last_render_list);
instances_to_draw = this.getRenderCellInstancesToDraw();
this.render_list_stale = false;
this.last_render_cells.copy(this.cur_render_cells);
}
else
instances_to_draw = this.last_render_list;
}
else
instances_to_draw = this.instances;
var i, inst, last_inst = null;
for (i = instances_to_draw.length - 1; i >= 0; --i)
{
inst = instances_to_draw[i];
if (inst === last_inst)
continue;
this.drawInstanceGL_earlyZPass(instances_to_draw[i], glw);
last_inst = inst;
}
if (this.useRenderCells)
this.last_render_list = instances_to_draw;
if (!this.transparent)
{
this.clear_earlyz_index = this.runtime.earlyz_index++;
glw.setEarlyZIndex(this.clear_earlyz_index);
glw.setColorFillMode(1, 1, 1, 1);
glw.fullscreenQuad(); // fill remaining space in depth buffer with current Z value
glw.restoreEarlyZMode();
}
};
Layer.prototype.drawGL = function (glw)
{
var windowWidth = this.runtime.draw_width;
var windowHeight = this.runtime.draw_height;
var shaderindex = 0;
var etindex = 0;
this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0 || this.active_effect_types.length > 0 || this.blend_mode !== 0);
if (this.render_offscreen)
{
if (!this.runtime.layer_tex)
{
this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
}
if (this.runtime.layer_tex.c2width !== this.runtime.draw_width || this.runtime.layer_tex.c2height !== this.runtime.draw_height)
{
glw.deleteTexture(this.runtime.layer_tex);
this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
}
glw.setRenderingToTexture(this.runtime.layer_tex);
if (this.transparent)
glw.clear(0, 0, 0, 0);
}
if (!this.transparent)
{
if (this.runtime.enableFrontToBack)
{
glw.setEarlyZIndex(this.clear_earlyz_index);
glw.setColorFillMode(this.background_color[0] / 255, this.background_color[1] / 255, this.background_color[2] / 255, 1);
glw.fullscreenQuad();
glw.setTextureFillMode();
}
else
{
glw.clear(this.background_color[0] / 255, this.background_color[1] / 255, this.background_color[2] / 255, 1);
}
}
this.disableAngle = true;
var px = this.canvasToLayer(0, 0, true, true);
var py = this.canvasToLayer(0, 0, false, true);
this.disableAngle = false;
if (this.runtime.pixel_rounding)
{
px = Math.round(px);
py = Math.round(py);
}
this.rotateViewport(px, py, null);
var myscale = this.getScale();
glw.resetModelView();
glw.scale(myscale, myscale);
glw.rotateZ(-this.getAngle());
glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
glw.updateModelView();
var instances_to_draw;
if (this.useRenderCells)
{
this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
{
free_arr(this.last_render_list);
instances_to_draw = this.getRenderCellInstancesToDraw();
this.render_list_stale = false;
this.last_render_cells.copy(this.cur_render_cells);
}
else
instances_to_draw = this.last_render_list;
}
else
instances_to_draw = this.instances;
var i, len, inst, last_inst = null;
for (i = 0, len = instances_to_draw.length; i < len; ++i)
{
inst = instances_to_draw[i];
if (inst === last_inst)
continue;
this.drawInstanceGL(instances_to_draw[i], glw);
last_inst = inst;
}
if (this.useRenderCells)
this.last_render_list = instances_to_draw;
if (this.render_offscreen)
{
shaderindex = this.active_effect_types.length ? this.active_effect_types[0].shaderindex : 0;
etindex = this.active_effect_types.length ? this.active_effect_types[0].index : 0;
if (this.active_effect_types.length === 0 || (this.active_effect_types.length === 1 &&
!glw.programUsesCrossSampling(shaderindex) && this.opacity === 1))
{
if (this.active_effect_types.length === 1)
{
glw.switchProgram(shaderindex);
glw.setProgramParameters(this.layout.getRenderTarget(), // backTex
1.0 / this.runtime.draw_width, // pixelWidth
1.0 / this.runtime.draw_height, // pixelHeight
0.0, 0.0, // destStart
1.0, 1.0, // destEnd
myscale, // layerScale
this.getAngle(),
this.viewLeft, this.viewTop,
(this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2,
this.runtime.kahanTime.sum,
this.effect_params[etindex]); // fx parameters
if (glw.programIsAnimated(shaderindex))
this.runtime.redraw = true;
}
else
glw.switchProgram(0);
glw.setRenderingToTexture(this.layout.getRenderTarget());
glw.setOpacity(this.opacity);
glw.setTexture(this.runtime.layer_tex);
glw.setBlend(this.srcBlend, this.destBlend);
glw.resetModelView();
glw.updateModelView();
var halfw = this.runtime.draw_width / 2;
var halfh = this.runtime.draw_height / 2;
glw.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
glw.setTexture(null);
}
else
{
this.layout.renderEffectChain(glw, this, null, this.layout.getRenderTarget());
}
}
};
Layer.prototype.drawInstanceGL = function (inst, glw)
{
;
if (!inst.visible || inst.width === 0 || inst.height === 0)
return;
inst.update_bbox();
var bbox = inst.bbox;
if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
return;
glw.setEarlyZIndex(inst.earlyz_index);
if (inst.uses_shaders)
{
this.drawInstanceWithShadersGL(inst, glw);
}
else
{
glw.switchProgram(0); // un-set any previously set shader
glw.setBlend(inst.srcBlend, inst.destBlend);
inst.drawGL(glw);
}
};
Layer.prototype.drawInstanceGL_earlyZPass = function (inst, glw)
{
;
if (!inst.visible || inst.width === 0 || inst.height === 0)
return;
inst.update_bbox();
var bbox = inst.bbox;
if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
return;
inst.earlyz_index = this.runtime.earlyz_index++;
if (inst.blend_mode !== 0 || inst.opacity !== 1 || !inst.shaders_preserve_opaqueness || !inst.drawGL_earlyZPass)
return;
glw.setEarlyZIndex(inst.earlyz_index);
inst.drawGL_earlyZPass(glw);
};
Layer.prototype.drawInstanceWithShadersGL = function (inst, glw)
{
var shaderindex = inst.active_effect_types[0].shaderindex;
var etindex = inst.active_effect_types[0].index;
var myscale = this.getScale();
if (inst.active_effect_types.length === 1 && !glw.programUsesCrossSampling(shaderindex) &&
!glw.programExtendsBox(shaderindex) && ((!inst.angle && !inst.layer.getAngle()) || !glw.programUsesDest(shaderindex)) &&
inst.opacity === 1 && !inst.type.plugin.must_predraw)
{
glw.switchProgram(shaderindex);
glw.setBlend(inst.srcBlend, inst.destBlend);
if (glw.programIsAnimated(shaderindex))
this.runtime.redraw = true;
var destStartX = 0, destStartY = 0, destEndX = 0, destEndY = 0;
if (glw.programUsesDest(shaderindex))
{
var bbox = inst.bbox;
var screenleft = this.layerToCanvas(bbox.left, bbox.top, true, true);
var screentop = this.layerToCanvas(bbox.left, bbox.top, false, true);
var screenright = this.layerToCanvas(bbox.right, bbox.bottom, true, true);
var screenbottom = this.layerToCanvas(bbox.right, bbox.bottom, false, true);
destStartX = screenleft / windowWidth;
destStartY = 1 - screentop / windowHeight;
destEndX = screenright / windowWidth;
destEndY = 1 - screenbottom / windowHeight;
}
var pixelWidth;
var pixelHeight;
if (inst.curFrame && inst.curFrame.texture_img)
{
var img = inst.curFrame.texture_img;
pixelWidth = 1.0 / img.width;
pixelHeight = 1.0 / img.height;
}
else
{
pixelWidth = 1.0 / inst.width;
pixelHeight = 1.0 / inst.height;
}
glw.setProgramParameters(this.render_offscreen ? this.runtime.layer_tex : this.layout.getRenderTarget(), // backTex
pixelWidth,
pixelHeight,
destStartX, destStartY,
destEndX, destEndY,
myscale,
this.getAngle(),
this.viewLeft, this.viewTop,
(this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2,
this.runtime.kahanTime.sum,
inst.effect_params[etindex]);
inst.drawGL(glw);
}
else
{
this.layout.renderEffectChain(glw, this, inst, this.render_offscreen ? this.runtime.layer_tex : this.layout.getRenderTarget());
glw.resetModelView();
glw.scale(myscale, myscale);
glw.rotateZ(-this.getAngle());
glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
glw.updateModelView();
}
};
Layer.prototype.canvasToLayer = function (ptx, pty, getx, using_draw_area)
{
var multiplier = this.runtime.devicePixelRatio;
if (this.runtime.isRetina)
{
ptx *= multiplier;
pty *= multiplier;
}
var ox = this.runtime.parallax_x_origin;
var oy = this.runtime.parallax_y_origin;
var par_x = ((this.layout.scrollX - ox) * this.parallaxX) + ox;
var par_y = ((this.layout.scrollY - oy) * this.parallaxY) + oy;
var x = par_x;
var y = par_y;
var invScale = 1 / this.getScale(!using_draw_area);
if (using_draw_area)
{
x -= (this.runtime.draw_width * invScale) / 2;
y -= (this.runtime.draw_height * invScale) / 2;
}
else
{
x -= (this.runtime.width * invScale) / 2;
y -= (this.runtime.height * invScale) / 2;
}
x += ptx * invScale;
y += pty * invScale;
var a = this.getAngle();
if (a !== 0)
{
x -= par_x;
y -= par_y;
var cosa = Math.cos(a);
var sina = Math.sin(a);
var x_temp = (x * cosa) - (y * sina);
y = (y * cosa) + (x * sina);
x = x_temp;
x += par_x;
y += par_y;
}
return getx ? x : y;
};
Layer.prototype.layerToCanvas = function (ptx, pty, getx, using_draw_area)
{
var ox = this.runtime.parallax_x_origin;
var oy = this.runtime.parallax_y_origin;
var par_x = ((this.layout.scrollX - ox) * this.parallaxX) + ox;
var par_y = ((this.layout.scrollY - oy) * this.parallaxY) + oy;
var x = par_x;
var y = par_y;
var a = this.getAngle();
if (a !== 0)
{
ptx -= par_x;
pty -= par_y;
var cosa = Math.cos(-a);
var sina = Math.sin(-a);
var x_temp = (ptx * cosa) - (pty * sina);
pty = (pty * cosa) + (ptx * sina);
ptx = x_temp;
ptx += par_x;
pty += par_y;
}
var invScale = 1 / this.getScale(!using_draw_area);
if (using_draw_area)
{
x -= (this.runtime.draw_width * invScale) / 2;
y -= (this.runtime.draw_height * invScale) / 2;
}
else
{
x -= (this.runtime.width * invScale) / 2;
y -= (this.runtime.height * invScale) / 2;
}
x = (ptx - x) / invScale;
y = (pty - y) / invScale;
var multiplier = this.runtime.devicePixelRatio;
if (this.runtime.isRetina && !using_draw_area)
{
x /= multiplier;
y /= multiplier;
}
return getx ? x : y;
};
Layer.prototype.rotatePt = function (x_, y_, getx)
{
if (this.getAngle() === 0)
return getx ? x_ : y_;
var nx = this.layerToCanvas(x_, y_, true);
var ny = this.layerToCanvas(x_, y_, false);
this.disableAngle = true;
var px = this.canvasToLayer(nx, ny, true);
var py = this.canvasToLayer(nx, ny, true);
this.disableAngle = false;
return getx ? px : py;
};
Layer.prototype.saveToJSON = function ()
{
var i, len, et;
var o = {
"s": this.scale,
"a": this.angle,
"vl": this.viewLeft,
"vt": this.viewTop,
"vr": this.viewRight,
"vb": this.viewBottom,
"v": this.visible,
"bc": this.background_color,
"t": this.transparent,
"px": this.parallaxX,
"py": this.parallaxY,
"o": this.opacity,
"zr": this.zoomRate,
"fx": [],
"cg": this.created_globals, // added r197; list of global UIDs already created
"instances": []
};
for (i = 0, len = this.effect_types.length; i < len; i++)
{
et = this.effect_types[i];
o["fx"].push({"name": et.name, "active": et.active, "params": this.effect_params[et.index] });
}
return o;
};
Layer.prototype.loadFromJSON = function (o)
{
var i, j, len, p, inst, fx;
this.scale = o["s"];
this.angle = o["a"];
this.viewLeft = o["vl"];
this.viewTop = o["vt"];
this.viewRight = o["vr"];
this.viewBottom = o["vb"];
this.visible = o["v"];
this.background_color = o["bc"];
this.transparent = o["t"];
this.parallaxX = o["px"];
this.parallaxY = o["py"];
this.opacity = o["o"];
this.zoomRate = o["zr"];
this.created_globals = o["cg"] || []; // added r197
cr.shallowAssignArray(this.initial_instances, this.startup_initial_instances);
var temp_set = new cr.ObjectSet();
for (i = 0, len = this.created_globals.length; i < len; ++i)
temp_set.add(this.created_globals[i]);
for (i = 0, j = 0, len = this.initial_instances.length; i < len; ++i)
{
if (!temp_set.contains(this.initial_instances[i][2])) // UID in element 2
{
this.initial_instances[j] = this.initial_instances[i];
++j;
}
}
cr.truncateArray(this.initial_instances, j);
var ofx = o["fx"];
for (i = 0, len = ofx.length; i < len; i++)
{
fx = this.getEffectByName(ofx[i]["name"]);
if (!fx)
continue; // must've gone missing
fx.active = ofx[i]["active"];
this.effect_params[fx.index] = ofx[i]["params"];
}
this.updateActiveEffects();
this.instances.sort(sort_by_zindex);
this.zindices_stale = true;
};
cr.layer = Layer;
}());
;
(function()
{
var allUniqueSolModifiers = [];
function testSolsMatch(arr1, arr2)
{
var i, len = arr1.length;
switch (len) {
case 0:
return true;
case 1:
return arr1[0] === arr2[0];
case 2:
return arr1[0] === arr2[0] && arr1[1] === arr2[1];
default:
for (i = 0; i < len; i++)
{
if (arr1[i] !== arr2[i])
return false;
}
return true;
}
};
function solArraySorter(t1, t2)
{
return t1.index - t2.index;
};
function findMatchingSolModifier(arr)
{
var i, len, u, temp, subarr;
if (arr.length === 2)
{
if (arr[0].index > arr[1].index)
{
temp = arr[0];
arr[0] = arr[1];
arr[1] = temp;
}
}
else if (arr.length > 2)
arr.sort(solArraySorter); // so testSolsMatch compares in same order
if (arr.length >= allUniqueSolModifiers.length)
allUniqueSolModifiers.length = arr.length + 1;
if (!allUniqueSolModifiers[arr.length])
allUniqueSolModifiers[arr.length] = [];
subarr = allUniqueSolModifiers[arr.length];
for (i = 0, len = subarr.length; i < len; i++)
{
u = subarr[i];
if (testSolsMatch(arr, u))
return u;
}
subarr.push(arr);
return arr;
};
function EventSheet(runtime, m)
{
this.runtime = runtime;
this.triggers = {};
this.fasttriggers = {};
this.hasRun = false;
this.includes = new cr.ObjectSet(); // all event sheets included by this sheet, at first-level indirection only
this.deep_includes = []; // all includes from this sheet recursively, in trigger order
this.already_included_sheets = []; // used while building deep_includes
this.name = m[0];
var em = m[1]; // events model
this.events = []; // triggers won't make it to this array
var i, len;
for (i = 0, len = em.length; i < len; i++)
this.init_event(em[i], null, this.events);
};
EventSheet.prototype.toString = function ()
{
return this.name;
};
EventSheet.prototype.init_event = function (m, parent, nontriggers)
{
switch (m[0]) {
case 0: // event block
{
var block = new cr.eventblock(this, parent, m);
cr.seal(block);
if (block.orblock)
{
nontriggers.push(block);
var i, len;
for (i = 0, len = block.conditions.length; i < len; i++)
{
if (block.conditions[i].trigger)
this.init_trigger(block, i);
}
}
else
{
if (block.is_trigger())
this.init_trigger(block, 0);
else
nontriggers.push(block);
}
break;
}
case 1: // variable
{
var v = new cr.eventvariable(this, parent, m);
cr.seal(v);
nontriggers.push(v);
break;
}
case 2: // include
{
var inc = new cr.eventinclude(this, parent, m);
cr.seal(inc);
nontriggers.push(inc);
break;
}
default:
;
}
};
EventSheet.prototype.postInit = function ()
{
var i, len;
for (i = 0, len = this.events.length; i < len; i++)
{
this.events[i].postInit(i < len - 1 && this.events[i + 1].is_else_block);
}
};
EventSheet.prototype.updateDeepIncludes = function ()
{
cr.clearArray(this.deep_includes);
cr.clearArray(this.already_included_sheets);
this.addDeepIncludes(this);
cr.clearArray(this.already_included_sheets);
};
EventSheet.prototype.addDeepIncludes = function (root_sheet)
{
var i, len, inc, sheet;
var deep_includes = root_sheet.deep_includes;
var already_included_sheets = root_sheet.already_included_sheets;
var arr = this.includes.valuesRef();
for (i = 0, len = arr.length; i < len; ++i)
{
inc = arr[i];
sheet = inc.include_sheet;
if (!inc.isActive() || root_sheet === sheet || already_included_sheets.indexOf(sheet) > -1)
continue;
already_included_sheets.push(sheet);
sheet.addDeepIncludes(root_sheet);
deep_includes.push(sheet);
}
};
EventSheet.prototype.run = function (from_include)
{
if (!this.runtime.resuming_breakpoint)
{
this.hasRun = true;
if (!from_include)
this.runtime.isRunningEvents = true;
}
var i, len;
for (i = 0, len = this.events.length; i < len; i++)
{
var ev = this.events[i];
ev.run();
this.runtime.clearSol(ev.solModifiers);
if (this.runtime.hasPendingInstances)
this.runtime.ClearDeathRow();
}
if (!from_include)
this.runtime.isRunningEvents = false;
};
function isPerformanceSensitiveTrigger(method)
{
if (cr.plugins_.Sprite && method === cr.plugins_.Sprite.prototype.cnds.OnFrameChanged)
{
return true;
}
return false;
};
EventSheet.prototype.init_trigger = function (trig, index)
{
if (!trig.orblock)
this.runtime.triggers_to_postinit.push(trig); // needs to be postInit'd later
var i, len;
var cnd = trig.conditions[index];
var type_name;
if (cnd.type)
type_name = cnd.type.name;
else
type_name = "system";
var fasttrigger = cnd.fasttrigger;
var triggers = (fasttrigger ? this.fasttriggers : this.triggers);
if (!triggers[type_name])
triggers[type_name] = [];
var obj_entry = triggers[type_name];
var method = cnd.func;
if (fasttrigger)
{
if (!cnd.parameters.length) // no parameters
return;
var firstparam = cnd.parameters[0];
if (firstparam.type !== 1 || // not a string param
firstparam.expression.type !== 2) // not a string literal node
{
return;
}
var fastevs;
var firstvalue = firstparam.expression.value.toLowerCase();
var i, len;
for (i = 0, len = obj_entry.length; i < len; i++)
{
if (obj_entry[i].method == method)
{
fastevs = obj_entry[i].evs;
if (!fastevs[firstvalue])
fastevs[firstvalue] = [[trig, index]];
else
fastevs[firstvalue].push([trig, index]);
return;
}
}
fastevs = {};
fastevs[firstvalue] = [[trig, index]];
obj_entry.push({ method: method, evs: fastevs });
}
else
{
for (i = 0, len = obj_entry.length; i < len; i++)
{
if (obj_entry[i].method == method)
{
obj_entry[i].evs.push([trig, index]);
return;
}
}
if (isPerformanceSensitiveTrigger(method))
obj_entry.unshift({ method: method, evs: [[trig, index]]});
else
obj_entry.push({ method: method, evs: [[trig, index]]});
}
};
cr.eventsheet = EventSheet;
function Selection(type)
{
this.type = type;
this.instances = []; // subset of picked instances
this.else_instances = []; // subset of unpicked instances
this.select_all = true;
};
Selection.prototype.hasObjects = function ()
{
if (this.select_all)
return this.type.instances.length;
else
return this.instances.length;
};
Selection.prototype.getObjects = function ()
{
if (this.select_all)
return this.type.instances;
else
return this.instances;
};
/*
Selection.prototype.ensure_picked = function (inst, skip_siblings)
{
var i, len;
var orblock = inst.runtime.getCurrentEventStack().current_event.orblock;
if (this.select_all)
{
this.select_all = false;
if (orblock)
{
cr.shallowAssignArray(this.else_instances, inst.type.instances);
cr.arrayFindRemove(this.else_instances, inst);
}
this.instances.length = 1;
this.instances[0] = inst;
}
else
{
if (orblock)
{
i = this.else_instances.indexOf(inst);
if (i !== -1)
{
this.instances.push(this.else_instances[i]);
this.else_instances.splice(i, 1);
}
}
else
{
if (this.instances.indexOf(inst) === -1)
this.instances.push(inst);
}
}
if (!skip_siblings)
{
}
};
*/
Selection.prototype.pick_one = function (inst)
{
if (!inst)
return;
if (inst.runtime.getCurrentEventStack().current_event.orblock)
{
if (this.select_all)
{
cr.clearArray(this.instances);
cr.shallowAssignArray(this.else_instances, inst.type.instances);
this.select_all = false;
}
var i = this.else_instances.indexOf(inst);
if (i !== -1)
{
this.instances.push(this.else_instances[i]);
this.else_instances.splice(i, 1);
}
}
else
{
this.select_all = false;
cr.clearArray(this.instances);
this.instances[0] = inst;
}
};
cr.selection = Selection;
function EventBlock(sheet, parent, m)
{
this.sheet = sheet;
this.parent = parent;
this.runtime = sheet.runtime;
this.solModifiers = [];
this.solModifiersIncludingParents = [];
this.solWriterAfterCnds = false; // block does not change SOL after running its conditions
this.group = false; // is group of events
this.initially_activated = false; // if a group, is active on startup
this.toplevelevent = false; // is an event block parented only by a top-level group
this.toplevelgroup = false; // is parented only by other groups or is top-level (i.e. not in a subevent)
this.has_else_block = false; // is followed by else
;
this.conditions = [];
this.actions = [];
this.subevents = [];
this.group_name = "";
this.group = false;
this.initially_activated = false;
this.group_active = false;
this.contained_includes = null;
if (m[1])
{
this.group_name = m[1][1].toLowerCase();
this.group = true;
this.initially_activated = !!m[1][0];
this.contained_includes = [];
this.group_active = this.initially_activated;
this.runtime.allGroups.push(this);
this.runtime.groups_by_name[this.group_name] = this;
}
this.orblock = m[2];
this.sid = m[4];
if (!this.group)
this.runtime.blocksBySid[this.sid.toString()] = this;
var i, len;
var cm = m[5];
for (i = 0, len = cm.length; i < len; i++)
{
var cnd = new cr.condition(this, cm[i]);
cnd.index = i;
cr.seal(cnd);
this.conditions.push(cnd);
/*
if (cnd.is_logical())
this.is_logical = true;
if (cnd.type && !cnd.type.plugin.singleglobal && this.cndReferences.indexOf(cnd.type) === -1)
this.cndReferences.push(cnd.type);
*/
this.addSolModifier(cnd.type);
}
var am = m[6];
for (i = 0, len = am.length; i < len; i++)
{
var act = new cr.action(this, am[i]);
act.index = i;
cr.seal(act);
this.actions.push(act);
}
if (m.length === 8)
{
var em = m[7];
for (i = 0, len = em.length; i < len; i++)
this.sheet.init_event(em[i], this, this.subevents);
}
this.is_else_block = false;
if (this.conditions.length)
{
this.is_else_block = (this.conditions[0].type == null && this.conditions[0].func == cr.system_object.prototype.cnds.Else);
}
};
window["_c2hh_"] = "3D2B739A1CCDEED5BB9AD9934803BF00AAC05827";
EventBlock.prototype.postInit = function (hasElse/*, prevBlock_*/)
{
var i, len;
var p = this.parent;
if (this.group)
{
this.toplevelgroup = true;
while (p)
{
if (!p.group)
{
this.toplevelgroup = false;
break;
}
p = p.parent;
}
}
this.toplevelevent = !this.is_trigger() && (!this.parent || (this.parent.group && this.parent.toplevelgroup));
this.has_else_block = !!hasElse;
this.solModifiersIncludingParents = this.solModifiers.slice(0);
p = this.parent;
while (p)
{
for (i = 0, len = p.solModifiers.length; i < len; i++)
this.addParentSolModifier(p.solModifiers[i]);
p = p.parent;
}
this.solModifiers = findMatchingSolModifier(this.solModifiers);
this.solModifiersIncludingParents = findMatchingSolModifier(this.solModifiersIncludingParents);
var i, len/*, s*/;
for (i = 0, len = this.conditions.length; i < len; i++)
this.conditions[i].postInit();
for (i = 0, len = this.actions.length; i < len; i++)
this.actions[i].postInit();
for (i = 0, len = this.subevents.length; i < len; i++)
{
this.subevents[i].postInit(i < len - 1 && this.subevents[i + 1].is_else_block);
}
/*
if (this.is_else_block && this.prev_block)
{
for (i = 0, len = this.prev_block.solModifiers.length; i < len; i++)
{
s = this.prev_block.solModifiers[i];
if (this.solModifiers.indexOf(s) === -1)
this.solModifiers.push(s);
}
}
*/
};
EventBlock.prototype.setGroupActive = function (a)
{
if (this.group_active === !!a)
return; // same state
this.group_active = !!a;
var i, len;
for (i = 0, len = this.contained_includes.length; i < len; ++i)
{
this.contained_includes[i].updateActive();
}
if (len > 0 && this.runtime.running_layout.event_sheet)
this.runtime.running_layout.event_sheet.updateDeepIncludes();
};
function addSolModifierToList(type, arr)
{
var i, len, t;
if (!type)
return;
if (arr.indexOf(type) === -1)
arr.push(type);
if (type.is_contained)
{
for (i = 0, len = type.container.length; i < len; i++)
{
t = type.container[i];
if (type === t)
continue; // already handled
if (arr.indexOf(t) === -1)
arr.push(t);
}
}
};
EventBlock.prototype.addSolModifier = function (type)
{
addSolModifierToList(type, this.solModifiers);
};
EventBlock.prototype.addParentSolModifier = function (type)
{
addSolModifierToList(type, this.solModifiersIncludingParents);
};
EventBlock.prototype.setSolWriterAfterCnds = function ()
{
this.solWriterAfterCnds = true;
if (this.parent)
this.parent.setSolWriterAfterCnds();
};
EventBlock.prototype.is_trigger = function ()
{
if (!this.conditions.length) // no conditions
return false;
else
return this.conditions[0].trigger;
};
EventBlock.prototype.run = function ()
{
var i, len, c, any_true = false, cnd_result;
var runtime = this.runtime;
var evinfo = this.runtime.getCurrentEventStack();
evinfo.current_event = this;
var conditions = this.conditions;
if (!this.is_else_block)
evinfo.else_branch_ran = false;
if (this.orblock)
{
if (conditions.length === 0)
any_true = true; // be sure to run if empty block
evinfo.cndindex = 0
for (len = conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
{
c = conditions[evinfo.cndindex];
if (c.trigger) // skip triggers when running OR block
continue;
cnd_result = c.run();
if (cnd_result) // make sure all conditions run and run if any were true
any_true = true;
}
evinfo.last_event_true = any_true;
if (any_true)
this.run_actions_and_subevents();
}
else
{
evinfo.cndindex = 0
for (len = conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
{
cnd_result = conditions[evinfo.cndindex].run();
if (!cnd_result) // condition failed
{
evinfo.last_event_true = false;
if (this.toplevelevent && runtime.hasPendingInstances)
runtime.ClearDeathRow();
return; // bail out now
}
}
evinfo.last_event_true = true;
this.run_actions_and_subevents();
}
this.end_run(evinfo);
};
EventBlock.prototype.end_run = function (evinfo)
{
if (evinfo.last_event_true && this.has_else_block)
evinfo.else_branch_ran = true;
if (this.toplevelevent && this.runtime.hasPendingInstances)
this.runtime.ClearDeathRow();
};
EventBlock.prototype.run_orblocktrigger = function (index)
{
var evinfo = this.runtime.getCurrentEventStack();
evinfo.current_event = this;
if (this.conditions[index].run())
{
this.run_actions_and_subevents();
this.runtime.getCurrentEventStack().last_event_true = true;
}
};
EventBlock.prototype.run_actions_and_subevents = function ()
{
var evinfo = this.runtime.getCurrentEventStack();
var len;
for (evinfo.actindex = 0, len = this.actions.length; evinfo.actindex < len; evinfo.actindex++)
{
if (this.actions[evinfo.actindex].run())
return;
}
this.run_subevents();
};
EventBlock.prototype.resume_actions_and_subevents = function ()
{
var evinfo = this.runtime.getCurrentEventStack();
var len;
for (len = this.actions.length; evinfo.actindex < len; evinfo.actindex++)
{
if (this.actions[evinfo.actindex].run())
return;
}
this.run_subevents();
};
EventBlock.prototype.run_subevents = function ()
{
if (!this.subevents.length)
return;
var i, len, subev, pushpop/*, skipped_pop = false, pop_modifiers = null*/;
var last = this.subevents.length - 1;
this.runtime.pushEventStack(this);
if (this.solWriterAfterCnds)
{
for (i = 0, len = this.subevents.length; i < len; i++)
{
subev = this.subevents[i];
pushpop = (!this.toplevelgroup || (!this.group && i < last));
if (pushpop)
this.runtime.pushCopySol(subev.solModifiers);
subev.run();
if (pushpop)
this.runtime.popSol(subev.solModifiers);
else
this.runtime.clearSol(subev.solModifiers);
}
}
else
{
for (i = 0, len = this.subevents.length; i < len; i++)
{
this.subevents[i].run();
}
}
this.runtime.popEventStack();
};
EventBlock.prototype.run_pretrigger = function ()
{
var evinfo = this.runtime.getCurrentEventStack();
evinfo.current_event = this;
var any_true = false;
var i, len;
for (evinfo.cndindex = 0, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
{
;
if (this.conditions[evinfo.cndindex].run())
any_true = true;
else if (!this.orblock) // condition failed (let OR blocks run all conditions anyway)
return false; // bail out
}
return this.orblock ? any_true : true;
};
EventBlock.prototype.retrigger = function ()
{
this.runtime.execcount++;
var prevcndindex = this.runtime.getCurrentEventStack().cndindex;
var len;
var evinfo = this.runtime.pushEventStack(this);
if (!this.orblock)
{
for (evinfo.cndindex = prevcndindex + 1, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
{
if (!this.conditions[evinfo.cndindex].run()) // condition failed
{
this.runtime.popEventStack(); // moving up level of recursion
return false; // bail out
}
}
}
this.run_actions_and_subevents();
this.runtime.popEventStack();
return true; // ran an iteration
};
EventBlock.prototype.isFirstConditionOfType = function (cnd)
{
var cndindex = cnd.index;
if (cndindex === 0)
return true;
--cndindex;
for ( ; cndindex >= 0; --cndindex)
{
if (this.conditions[cndindex].type === cnd.type)
return false;
}
return true;
};
cr.eventblock = EventBlock;
function Condition(block, m)
{
this.block = block;
this.sheet = block.sheet;
this.runtime = block.runtime;
this.parameters = [];
this.results = [];
this.extra = {}; // for plugins to stow away some custom info
this.index = -1;
this.anyParamVariesPerInstance = false;
this.func = this.runtime.GetObjectReference(m[1]);
;
this.trigger = (m[3] > 0);
this.fasttrigger = (m[3] === 2);
this.looping = m[4];
this.inverted = m[5];
this.isstatic = m[6];
this.sid = m[7];
this.runtime.cndsBySid[this.sid.toString()] = this;
if (m[0] === -1) // system object
{
this.type = null;
this.run = this.run_system;
this.behaviortype = null;
this.beh_index = -1;
}
else
{
this.type = this.runtime.types_by_index[m[0]];
;
if (this.isstatic)
this.run = this.run_static;
else
this.run = this.run_object;
if (m[2])
{
this.behaviortype = this.type.getBehaviorByName(m[2]);
;
this.beh_index = this.type.getBehaviorIndexByName(m[2]);
;
}
else
{
this.behaviortype = null;
this.beh_index = -1;
}
if (this.block.parent)
this.block.parent.setSolWriterAfterCnds();
}
if (this.fasttrigger)
this.run = this.run_true;
if (m.length === 10)
{
var i, len;
var em = m[9];
for (i = 0, len = em.length; i < len; i++)
{
var param = new cr.parameter(this, em[i]);
cr.seal(param);
this.parameters.push(param);
}
this.results.length = em.length;
}
};
Condition.prototype.postInit = function ()
{
var i, len, p;
for (i = 0, len = this.parameters.length; i < len; i++)
{
p = this.parameters[i];
p.postInit();
if (p.variesPerInstance)
this.anyParamVariesPerInstance = true;
}
};
/*
Condition.prototype.is_logical = function ()
{
return !this.type || this.type.plugin.singleglobal;
};
*/
Condition.prototype.run_true = function ()
{
return true;
};
Condition.prototype.run_system = function ()
{
var i, len;
for (i = 0, len = this.parameters.length; i < len; i++)
this.results[i] = this.parameters[i].get();
return cr.xor(this.func.apply(this.runtime.system, this.results), this.inverted);
};
Condition.prototype.run_static = function ()
{
var i, len;
for (i = 0, len = this.parameters.length; i < len; i++)
this.results[i] = this.parameters[i].get();
var ret = this.func.apply(this.behaviortype ? this.behaviortype : this.type, this.results);
this.type.applySolToContainer();
return ret;
};
Condition.prototype.run_object = function ()
{
var i, j, k, leni, lenj, p, ret, met, inst, s, sol2;
var type = this.type;
var sol = type.getCurrentSol();
var is_orblock = this.block.orblock && !this.trigger; // triggers in OR blocks need to work normally
var offset = 0;
var is_contained = type.is_contained;
var is_family = type.is_family;
var family_index = type.family_index;
var beh_index = this.beh_index;
var is_beh = (beh_index > -1);
var params_vary = this.anyParamVariesPerInstance;
var parameters = this.parameters;
var results = this.results;
var inverted = this.inverted;
var func = this.func;
var arr, container;
if (params_vary)
{
for (j = 0, lenj = parameters.length; j < lenj; ++j)
{
p = parameters[j];
if (!p.variesPerInstance)
results[j] = p.get(0);
}
}
else
{
for (j = 0, lenj = parameters.length; j < lenj; ++j)
results[j] = parameters[j].get(0);
}
if (sol.select_all) {
cr.clearArray(sol.instances); // clear contents
cr.clearArray(sol.else_instances);
arr = type.instances;
for (i = 0, leni = arr.length; i < leni; ++i)
{
inst = arr[i];
;
if (params_vary)
{
for (j = 0, lenj = parameters.length; j < lenj; ++j)
{
p = parameters[j];
if (p.variesPerInstance)
results[j] = p.get(i); // default SOL index is current object
}
}
if (is_beh)
{
offset = 0;
if (is_family)
{
offset = inst.type.family_beh_map[family_index];
}
ret = func.apply(inst.behavior_insts[beh_index + offset], results);
}
else
ret = func.apply(inst, results);
met = cr.xor(ret, inverted);
if (met)
sol.instances.push(inst);
else if (is_orblock) // in OR blocks, keep the instances not meeting the condition for subsequent testing
sol.else_instances.push(inst);
}
if (type.finish)
type.finish(true);
sol.select_all = false;
type.applySolToContainer();
return sol.hasObjects();
}
else {
k = 0;
var using_else_instances = (is_orblock && !this.block.isFirstConditionOfType(this));
arr = (using_else_instances ? sol.else_instances : sol.instances);
var any_true = false;
for (i = 0, leni = arr.length; i < leni; ++i)
{
inst = arr[i];
;
if (params_vary)
{
for (j = 0, lenj = parameters.length; j < lenj; ++j)
{
p = parameters[j];
if (p.variesPerInstance)
results[j] = p.get(i); // default SOL index is current object
}
}
if (is_beh)
{
offset = 0;
if (is_family)
{
offset = inst.type.family_beh_map[family_index];
}
ret = func.apply(inst.behavior_insts[beh_index + offset], results);
}
else
ret = func.apply(inst, results);
if (cr.xor(ret, inverted))
{
any_true = true;
if (using_else_instances)
{
sol.instances.push(inst);
if (is_contained)
{
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
{
s = inst.siblings[j];
s.type.getCurrentSol().instances.push(s);
}
}
}
else
{
arr[k] = inst;
if (is_contained)
{
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
{
s = inst.siblings[j];
s.type.getCurrentSol().instances[k] = s;
}
}
k++;
}
}
else
{
if (using_else_instances)
{
arr[k] = inst;
if (is_contained)
{
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
{
s = inst.siblings[j];
s.type.getCurrentSol().else_instances[k] = s;
}
}
k++;
}
else if (is_orblock)
{
sol.else_instances.push(inst);
if (is_contained)
{
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
{
s = inst.siblings[j];
s.type.getCurrentSol().else_instances.push(s);
}
}
}
}
}
cr.truncateArray(arr, k);
if (is_contained)
{
container = type.container;
for (i = 0, leni = container.length; i < leni; i++)
{
sol2 = container[i].getCurrentSol();
if (using_else_instances)
cr.truncateArray(sol2.else_instances, k);
else
cr.truncateArray(sol2.instances, k);
}
}
var pick_in_finish = any_true; // don't pick in finish() if we're only doing the logic test below
if (using_else_instances && !any_true)
{
for (i = 0, leni = sol.instances.length; i < leni; i++)
{
inst = sol.instances[i];
if (params_vary)
{
for (j = 0, lenj = parameters.length; j < lenj; j++)
{
p = parameters[j];
if (p.variesPerInstance)
results[j] = p.get(i);
}
}
if (is_beh)
ret = func.apply(inst.behavior_insts[beh_index], results);
else
ret = func.apply(inst, results);
if (cr.xor(ret, inverted))
{
any_true = true;
break; // got our flag, don't need to test any more
}
}
}
if (type.finish)
type.finish(pick_in_finish || is_orblock);
return is_orblock ? any_true : sol.hasObjects();
}
};
cr.condition = Condition;
function Action(block, m)
{
this.block = block;
this.sheet = block.sheet;
this.runtime = block.runtime;
this.parameters = [];
this.results = [];
this.extra = {}; // for plugins to stow away some custom info
this.index = -1;
this.anyParamVariesPerInstance = false;
this.func = this.runtime.GetObjectReference(m[1]);
;
if (m[0] === -1) // system
{
this.type = null;
this.run = this.run_system;
this.behaviortype = null;
this.beh_index = -1;
}
else
{
this.type = this.runtime.types_by_index[m[0]];
;
this.run = this.run_object;
if (m[2])
{
this.behaviortype = this.type.getBehaviorByName(m[2]);
;
this.beh_index = this.type.getBehaviorIndexByName(m[2]);
;
}
else
{
this.behaviortype = null;
this.beh_index = -1;
}
}
this.sid = m[3];
this.runtime.actsBySid[this.sid.toString()] = this;
if (m.length === 6)
{
var i, len;
var em = m[5];
for (i = 0, len = em.length; i < len; i++)
{
var param = new cr.parameter(this, em[i]);
cr.seal(param);
this.parameters.push(param);
}
this.results.length = em.length;
}
};
Action.prototype.postInit = function ()
{
var i, len, p;
for (i = 0, len = this.parameters.length; i < len; i++)
{
p = this.parameters[i];
p.postInit();
if (p.variesPerInstance)
this.anyParamVariesPerInstance = true;
}
};
Action.prototype.run_system = function ()
{
var runtime = this.runtime;
var i, len;
var parameters = this.parameters;
var results = this.results;
for (i = 0, len = parameters.length; i < len; ++i)
results[i] = parameters[i].get();
return this.func.apply(runtime.system, results);
};
Action.prototype.run_object = function ()
{
var type = this.type;
var beh_index = this.beh_index;
var family_index = type.family_index;
var params_vary = this.anyParamVariesPerInstance;
var parameters = this.parameters;
var results = this.results;
var func = this.func;
var instances = type.getCurrentSol().getObjects();
var is_family = type.is_family;
var is_beh = (beh_index > -1);
var i, j, leni, lenj, p, inst, offset;
if (params_vary)
{
for (j = 0, lenj = parameters.length; j < lenj; ++j)
{
p = parameters[j];
if (!p.variesPerInstance)
results[j] = p.get(0);
}
}
else
{
for (j = 0, lenj = parameters.length; j < lenj; ++j)
results[j] = parameters[j].get(0);
}
for (i = 0, leni = instances.length; i < leni; ++i)
{
inst = instances[i];
if (params_vary)
{
for (j = 0, lenj = parameters.length; j < lenj; ++j)
{
p = parameters[j];
if (p.variesPerInstance)
results[j] = p.get(i); // pass i to use as default SOL index
}
}
if (is_beh)
{
offset = 0;
if (is_family)
{
offset = inst.type.family_beh_map[family_index];
}
func.apply(inst.behavior_insts[beh_index + offset], results);
}
else
func.apply(inst, results);
}
return false;
};
cr.action = Action;
var tempValues = [];
var tempValuesPtr = -1;
function pushTempValue()
{
tempValuesPtr++;
if (tempValues.length === tempValuesPtr)
tempValues.push(new cr.expvalue());
return tempValues[tempValuesPtr];
};
function popTempValue()
{
tempValuesPtr--;
};
function Parameter(owner, m)
{
this.owner = owner;
this.block = owner.block;
this.sheet = owner.sheet;
this.runtime = owner.runtime;
this.type = m[0];
this.expression = null;
this.solindex = 0;
this.get = null;
this.combosel = 0;
this.layout = null;
this.key = 0;
this.object = null;
this.index = 0;
this.varname = null;
this.eventvar = null;
this.fileinfo = null;
this.subparams = null;
this.variadicret = null;
this.subparams = null;
this.variadicret = null;
this.variesPerInstance = false;
var i, len, param;
switch (m[0])
{
case 0: // number
case 7: // any
this.expression = new cr.expNode(this, m[1]);
this.solindex = 0;
this.get = this.get_exp;
break;
case 1: // string
this.expression = new cr.expNode(this, m[1]);
this.solindex = 0;
this.get = this.get_exp_str;
break;
case 5: // layer
this.expression = new cr.expNode(this, m[1]);
this.solindex = 0;
this.get = this.get_layer;
break;
case 3: // combo
case 8: // cmp
this.combosel = m[1];
this.get = this.get_combosel;
break;
case 6: // layout
this.layout = this.runtime.layouts[m[1]];
;
this.get = this.get_layout;
break;
case 9: // keyb
this.key = m[1];
this.get = this.get_key;
break;
case 4: // object
this.object = this.runtime.types_by_index[m[1]];
;
this.get = this.get_object;
this.block.addSolModifier(this.object);
if (this.owner instanceof cr.action)
this.block.setSolWriterAfterCnds();
else if (this.block.parent)
this.block.parent.setSolWriterAfterCnds();
break;
case 10: // instvar
this.index = m[1];
if (owner.type && owner.type.is_family)
{
this.get = this.get_familyvar;
this.variesPerInstance = true;
}
else
this.get = this.get_instvar;
break;
case 11: // eventvar
this.varname = m[1];
this.eventvar = null;
this.get = this.get_eventvar;
break;
case 2: // audiofile ["name", ismusic]
case 12: // fileinfo "name"
this.fileinfo = m[1];
this.get = this.get_audiofile;
break;
case 13: // variadic
this.get = this.get_variadic;
this.subparams = [];
this.variadicret = [];
for (i = 1, len = m.length; i < len; i++)
{
param = new cr.parameter(this.owner, m[i]);
cr.seal(param);
this.subparams.push(param);
this.variadicret.push(0);
}
break;
default:
;
}
};
Parameter.prototype.postInit = function ()
{
var i, len;
if (this.type === 11) // eventvar
{
this.eventvar = this.runtime.getEventVariableByName(this.varname, this.block.parent);
;
}
else if (this.type === 13) // variadic, postInit all sub-params
{
for (i = 0, len = this.subparams.length; i < len; i++)
this.subparams[i].postInit();
}
if (this.expression)
this.expression.postInit();
};
Parameter.prototype.maybeVaryForType = function (t)
{
if (this.variesPerInstance)
return; // already varies per instance, no need to check again
if (!t)
return; // never vary for system type
if (!t.plugin.singleglobal)
{
this.variesPerInstance = true;
return;
}
};
Parameter.prototype.setVaries = function ()
{
this.variesPerInstance = true;
};
Parameter.prototype.get_exp = function (solindex)
{
this.solindex = solindex || 0; // default SOL index to use
var temp = pushTempValue();
this.expression.get(temp);
popTempValue();
return temp.data; // return actual JS value, not expvalue
};
Parameter.prototype.get_exp_str = function (solindex)
{
this.solindex = solindex || 0; // default SOL index to use
var temp = pushTempValue();
this.expression.get(temp);
popTempValue();
if (cr.is_string(temp.data))
return temp.data;
else
return "";
};
Parameter.prototype.get_object = function ()
{
return this.object;
};
Parameter.prototype.get_combosel = function ()
{
return this.combosel;
};
Parameter.prototype.get_layer = function (solindex)
{
this.solindex = solindex || 0; // default SOL index to use
var temp = pushTempValue();
this.expression.get(temp);
popTempValue();
if (temp.is_number())
return this.runtime.getLayerByNumber(temp.data);
else
return this.runtime.getLayerByName(temp.data);
}
Parameter.prototype.get_layout = function ()
{
return this.layout;
};
Parameter.prototype.get_key = function ()
{
return this.key;
};
Parameter.prototype.get_instvar = function ()
{
return this.index;
};
Parameter.prototype.get_familyvar = function (solindex_)
{
var solindex = solindex_ || 0;
var familytype = this.owner.type;
var realtype = null;
var sol = familytype.getCurrentSol();
var objs = sol.getObjects();
if (objs.length)
realtype = objs[solindex % objs.length].type;
else if (sol.else_instances.length)
realtype = sol.else_instances[solindex % sol.else_instances.length].type;
else if (familytype.instances.length)
realtype = familytype.instances[solindex % familytype.instances.length].type;
else
return 0;
return this.index + realtype.family_var_map[familytype.family_index];
};
Parameter.prototype.get_eventvar = function ()
{
return this.eventvar;
};
Parameter.prototype.get_audiofile = function ()
{
return this.fileinfo;
};
Parameter.prototype.get_variadic = function ()
{
var i, len;
for (i = 0, len = this.subparams.length; i < len; i++)
{
this.variadicret[i] = this.subparams[i].get();
}
return this.variadicret;
};
cr.parameter = Parameter;
function EventVariable(sheet, parent, m)
{
this.sheet = sheet;
this.parent = parent;
this.runtime = sheet.runtime;
this.solModifiers = [];
this.name = m[1];
this.vartype = m[2];
this.initial = m[3];
this.is_static = !!m[4];
this.is_constant = !!m[5];
this.sid = m[6];
this.runtime.varsBySid[this.sid.toString()] = this;
this.data = this.initial; // note: also stored in event stack frame for local nonstatic nonconst vars
if (this.parent) // local var
{
if (this.is_static || this.is_constant)
this.localIndex = -1;
else
this.localIndex = this.runtime.stackLocalCount++;
this.runtime.all_local_vars.push(this);
}
else // global var
{
this.localIndex = -1;
this.runtime.all_global_vars.push(this);
}
};
EventVariable.prototype.postInit = function ()
{
this.solModifiers = findMatchingSolModifier(this.solModifiers);
};
EventVariable.prototype.setValue = function (x)
{
;
var lvs = this.runtime.getCurrentLocalVarStack();
if (!this.parent || this.is_static || !lvs)
this.data = x;
else // local nonstatic variable: use event stack to keep value at this level of recursion
{
if (this.localIndex >= lvs.length)
lvs.length = this.localIndex + 1;
lvs[this.localIndex] = x;
}
};
EventVariable.prototype.getValue = function ()
{
var lvs = this.runtime.getCurrentLocalVarStack();
if (!this.parent || this.is_static || !lvs || this.is_constant)
return this.data;
else // local nonstatic variable
{
if (this.localIndex >= lvs.length)
{
return this.initial;
}
if (typeof lvs[this.localIndex] === "undefined")
{
return this.initial;
}
return lvs[this.localIndex];
}
};
EventVariable.prototype.run = function ()
{
if (this.parent && !this.is_static && !this.is_constant)
this.setValue(this.initial);
};
cr.eventvariable = EventVariable;
function EventInclude(sheet, parent, m)
{
this.sheet = sheet;
this.parent = parent;
this.runtime = sheet.runtime;
this.solModifiers = [];
this.include_sheet = null; // determined in postInit
this.include_sheet_name = m[1];
this.active = true;
};
EventInclude.prototype.toString = function ()
{
return "include:" + this.include_sheet.toString();
};
EventInclude.prototype.postInit = function ()
{
this.include_sheet = this.runtime.eventsheets[this.include_sheet_name];
;
;
this.sheet.includes.add(this);
this.solModifiers = findMatchingSolModifier(this.solModifiers);
var p = this.parent;
while (p)
{
if (p.group)
p.contained_includes.push(this);
p = p.parent;
}
this.updateActive();
};
EventInclude.prototype.run = function ()
{
if (this.parent)
this.runtime.pushCleanSol(this.runtime.types_by_index);
if (!this.include_sheet.hasRun)
this.include_sheet.run(true); // from include
if (this.parent)
this.runtime.popSol(this.runtime.types_by_index);
};
EventInclude.prototype.updateActive = function ()
{
var p = this.parent;
while (p)
{
if (p.group && !p.group_active)
{
this.active = false;
return;
}
p = p.parent;
}
this.active = true;
};
EventInclude.prototype.isActive = function ()
{
return this.active;
};
cr.eventinclude = EventInclude;
function EventStackFrame()
{
this.temp_parents_arr = [];
this.reset(null);
cr.seal(this);
};
EventStackFrame.prototype.reset = function (cur_event)
{
this.current_event = cur_event;
this.cndindex = 0;
this.actindex = 0;
cr.clearArray(this.temp_parents_arr);
this.last_event_true = false;
this.else_branch_ran = false;
this.any_true_state = false;
};
EventStackFrame.prototype.isModifierAfterCnds = function ()
{
if (this.current_event.solWriterAfterCnds)
return true;
if (this.cndindex < this.current_event.conditions.length - 1)
return !!this.current_event.solModifiers.length;
return false;
};
cr.eventStackFrame = EventStackFrame;
}());
(function()
{
function ExpNode(owner_, m)
{
this.owner = owner_;
this.runtime = owner_.runtime;
this.type = m[0];
;
this.get = [this.eval_int,
this.eval_float,
this.eval_string,
this.eval_unaryminus,
this.eval_add,
this.eval_subtract,
this.eval_multiply,
this.eval_divide,
this.eval_mod,
this.eval_power,
this.eval_and,
this.eval_or,
this.eval_equal,
this.eval_notequal,
this.eval_less,
this.eval_lessequal,
this.eval_greater,
this.eval_greaterequal,
this.eval_conditional,
this.eval_system_exp,
this.eval_object_exp,
this.eval_instvar_exp,
this.eval_behavior_exp,
this.eval_eventvar_exp][this.type];
var paramsModel = null;
this.value = null;
this.first = null;
this.second = null;
this.third = null;
this.func = null;
this.results = null;
this.parameters = null;
this.object_type = null;
this.beh_index = -1;
this.instance_expr = null;
this.varindex = -1;
this.behavior_type = null;
this.varname = null;
this.eventvar = null;
this.return_string = false;
switch (this.type) {
case 0: // int
case 1: // float
case 2: // string
this.value = m[1];
break;
case 3: // unaryminus
this.first = new cr.expNode(owner_, m[1]);
break;
case 18: // conditional
this.first = new cr.expNode(owner_, m[1]);
this.second = new cr.expNode(owner_, m[2]);
this.third = new cr.expNode(owner_, m[3]);
break;
case 19: // system_exp
this.func = this.runtime.GetObjectReference(m[1]);
;
if (this.func === cr.system_object.prototype.exps.random
|| this.func === cr.system_object.prototype.exps.choose)
{
this.owner.setVaries();
}
this.results = [];
this.parameters = [];
if (m.length === 3)
{
paramsModel = m[2];
this.results.length = paramsModel.length + 1; // must also fit 'ret'
}
else
this.results.length = 1; // to fit 'ret'
break;
case 20: // object_exp
this.object_type = this.runtime.types_by_index[m[1]];
;
this.beh_index = -1;
this.func = this.runtime.GetObjectReference(m[2]);
this.return_string = m[3];
if (cr.plugins_.Function && this.func === cr.plugins_.Function.prototype.exps.Call)
{
this.owner.setVaries();
}
if (m[4])
this.instance_expr = new cr.expNode(owner_, m[4]);
else
this.instance_expr = null;
this.results = [];
this.parameters = [];
if (m.length === 6)
{
paramsModel = m[5];
this.results.length = paramsModel.length + 1;
}
else
this.results.length = 1; // to fit 'ret'
break;
case 21: // instvar_exp
this.object_type = this.runtime.types_by_index[m[1]];
;
this.return_string = m[2];
if (m[3])
this.instance_expr = new cr.expNode(owner_, m[3]);
else
this.instance_expr = null;
this.varindex = m[4];
break;
case 22: // behavior_exp
this.object_type = this.runtime.types_by_index[m[1]];
;
this.behavior_type = this.object_type.getBehaviorByName(m[2]);
;
this.beh_index = this.object_type.getBehaviorIndexByName(m[2]);
this.func = this.runtime.GetObjectReference(m[3]);
this.return_string = m[4];
if (m[5])
this.instance_expr = new cr.expNode(owner_, m[5]);
else
this.instance_expr = null;
this.results = [];
this.parameters = [];
if (m.length === 7)
{
paramsModel = m[6];
this.results.length = paramsModel.length + 1;
}
else
this.results.length = 1; // to fit 'ret'
break;
case 23: // eventvar_exp
this.varname = m[1];
this.eventvar = null; // assigned in postInit
break;
}
this.owner.maybeVaryForType(this.object_type);
if (this.type >= 4 && this.type <= 17)
{
this.first = new cr.expNode(owner_, m[1]);
this.second = new cr.expNode(owner_, m[2]);
}
if (paramsModel)
{
var i, len;
for (i = 0, len = paramsModel.length; i < len; i++)
this.parameters.push(new cr.expNode(owner_, paramsModel[i]));
}
cr.seal(this);
};
ExpNode.prototype.postInit = function ()
{
if (this.type === 23) // eventvar_exp
{
this.eventvar = this.owner.runtime.getEventVariableByName(this.varname, this.owner.block.parent);
;
}
if (this.first)
this.first.postInit();
if (this.second)
this.second.postInit();
if (this.third)
this.third.postInit();
if (this.instance_expr)
this.instance_expr.postInit();
if (this.parameters)
{
var i, len;
for (i = 0, len = this.parameters.length; i < len; i++)
this.parameters[i].postInit();
}
};
var tempValues = [];
var tempValuesPtr = -1;
function pushTempValue()
{
++tempValuesPtr;
if (tempValues.length === tempValuesPtr)
tempValues.push(new cr.expvalue());
return tempValues[tempValuesPtr];
};
function popTempValue()
{
--tempValuesPtr;
};
function eval_params(parameters, results, temp)
{
var i, len;
for (i = 0, len = parameters.length; i < len; ++i)
{
parameters[i].get(temp);
results[i + 1] = temp.data; // passing actual javascript value as argument instead of expvalue
}
}
ExpNode.prototype.eval_system_exp = function (ret)
{
var parameters = this.parameters;
var results = this.results;
results[0] = ret;
var temp = pushTempValue();
eval_params(parameters, results, temp);
popTempValue();
this.func.apply(this.runtime.system, results);
};
ExpNode.prototype.eval_object_exp = function (ret)
{
var object_type = this.object_type;
var results = this.results;
var parameters = this.parameters;
var instance_expr = this.instance_expr;
var func = this.func;
var index = this.owner.solindex; // default to parameter's intended SOL index
var sol = object_type.getCurrentSol();
var instances = sol.getObjects();
if (!instances.length)
{
if (sol.else_instances.length)
instances = sol.else_instances;
else
{
if (this.return_string)
ret.set_string("");
else
ret.set_int(0);
return;
}
}
results[0] = ret;
ret.object_class = object_type; // so expression can access family type if need be
var temp = pushTempValue();
eval_params(parameters, results, temp);
if (instance_expr) {
instance_expr.get(temp);
if (temp.is_number()) {
index = temp.data;
instances = object_type.instances; // pick from all instances, not SOL
}
}
popTempValue();
var len = instances.length;
if (index >= len || index <= -len)
index %= len; // wraparound
if (index < 0)
index += len;
var returned_val = func.apply(instances[index], results);
;
};
ExpNode.prototype.eval_behavior_exp = function (ret)
{
var object_type = this.object_type;
var results = this.results;
var parameters = this.parameters;
var instance_expr = this.instance_expr;
var beh_index = this.beh_index;
var func = this.func;
var index = this.owner.solindex; // default to parameter's intended SOL index
var sol = object_type.getCurrentSol();
var instances = sol.getObjects();
if (!instances.length)
{
if (sol.else_instances.length)
instances = sol.else_instances;
else
{
if (this.return_string)
ret.set_string("");
else
ret.set_int(0);
return;
}
}
results[0] = ret;
ret.object_class = object_type; // so expression can access family type if need be
var temp = pushTempValue();
eval_params(parameters, results, temp);
if (instance_expr) {
instance_expr.get(temp);
if (temp.is_number()) {
index = temp.data;
instances = object_type.instances; // pick from all instances, not SOL
}
}
popTempValue();
var len = instances.length;
if (index >= len || index <= -len)
index %= len; // wraparound
if (index < 0)
index += len;
var inst = instances[index];
var offset = 0;
if (object_type.is_family)
{
offset = inst.type.family_beh_map[object_type.family_index];
}
var returned_val = func.apply(inst.behavior_insts[beh_index + offset], results);
;
};
ExpNode.prototype.eval_instvar_exp = function (ret)
{
var instance_expr = this.instance_expr;
var object_type = this.object_type;
var varindex = this.varindex;
var index = this.owner.solindex; // default to parameter's intended SOL index
var sol = object_type.getCurrentSol();
var instances = sol.getObjects();
var inst;
if (!instances.length)
{
if (sol.else_instances.length)
instances = sol.else_instances;
else
{
if (this.return_string)
ret.set_string("");
else
ret.set_int(0);
return;
}
}
if (instance_expr)
{
var temp = pushTempValue();
instance_expr.get(temp);
if (temp.is_number())
{
index = temp.data;
var type_instances = object_type.instances;
if (type_instances.length !== 0) // avoid NaN result with %
{
index %= type_instances.length; // wraparound
if (index < 0) // offset
index += type_instances.length;
}
inst = object_type.getInstanceByIID(index);
var to_ret = inst.instance_vars[varindex];
if (cr.is_string(to_ret))
ret.set_string(to_ret);
else
ret.set_float(to_ret);
popTempValue();
return; // done
}
popTempValue();
}
var len = instances.length;
if (index >= len || index <= -len)
index %= len; // wraparound
if (index < 0)
index += len;
inst = instances[index];
var offset = 0;
if (object_type.is_family)
{
offset = inst.type.family_var_map[object_type.family_index];
}
var to_ret = inst.instance_vars[varindex + offset];
if (cr.is_string(to_ret))
ret.set_string(to_ret);
else
ret.set_float(to_ret);
};
ExpNode.prototype.eval_int = function (ret)
{
ret.type = cr.exptype.Integer;
ret.data = this.value;
};
ExpNode.prototype.eval_float = function (ret)
{
ret.type = cr.exptype.Float;
ret.data = this.value;
};
ExpNode.prototype.eval_string = function (ret)
{
ret.type = cr.exptype.String;
ret.data = this.value;
};
ExpNode.prototype.eval_unaryminus = function (ret)
{
this.first.get(ret); // retrieve operand
if (ret.is_number())
ret.data = -ret.data;
};
ExpNode.prototype.eval_add = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
if (ret.is_number() && temp.is_number())
{
ret.data += temp.data; // both operands numbers: add
if (temp.is_float())
ret.make_float();
}
popTempValue();
};
ExpNode.prototype.eval_subtract = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
if (ret.is_number() && temp.is_number())
{
ret.data -= temp.data; // both operands numbers: subtract
if (temp.is_float())
ret.make_float();
}
popTempValue();
};
ExpNode.prototype.eval_multiply = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
if (ret.is_number() && temp.is_number())
{
ret.data *= temp.data; // both operands numbers: multiply
if (temp.is_float())
ret.make_float();
}
popTempValue();
};
ExpNode.prototype.eval_divide = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
if (ret.is_number() && temp.is_number())
{
ret.data /= temp.data; // both operands numbers: divide
ret.make_float();
}
popTempValue();
};
ExpNode.prototype.eval_mod = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
if (ret.is_number() && temp.is_number())
{
ret.data %= temp.data; // both operands numbers: modulo
if (temp.is_float())
ret.make_float();
}
popTempValue();
};
ExpNode.prototype.eval_power = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
if (ret.is_number() && temp.is_number())
{
ret.data = Math.pow(ret.data, temp.data); // both operands numbers: raise to power
if (temp.is_float())
ret.make_float();
}
popTempValue();
};
ExpNode.prototype.eval_and = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
if (temp.is_string() || ret.is_string())
this.eval_and_stringconcat(ret, temp);
else
this.eval_and_logical(ret, temp);
popTempValue();
};
ExpNode.prototype.eval_and_stringconcat = function (ret, temp)
{
if (ret.is_string() && temp.is_string())
this.eval_and_stringconcat_str_str(ret, temp);
else
this.eval_and_stringconcat_num(ret, temp);
};
ExpNode.prototype.eval_and_stringconcat_str_str = function (ret, temp)
{
ret.data += temp.data;
};
ExpNode.prototype.eval_and_stringconcat_num = function (ret, temp)
{
if (ret.is_string())
{
ret.data += (Math.round(temp.data * 1e10) / 1e10).toString();
}
else
{
ret.set_string(ret.data.toString() + temp.data);
}
};
ExpNode.prototype.eval_and_logical = function (ret, temp)
{
ret.set_int(ret.data && temp.data ? 1 : 0);
};
ExpNode.prototype.eval_or = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
if (ret.is_number() && temp.is_number())
{
if (ret.data || temp.data)
ret.set_int(1);
else
ret.set_int(0);
}
popTempValue();
};
ExpNode.prototype.eval_conditional = function (ret)
{
this.first.get(ret); // condition operand
if (ret.data) // is true
this.second.get(ret); // evaluate second operand to ret
else
this.third.get(ret); // evaluate third operand to ret
};
ExpNode.prototype.eval_equal = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
ret.set_int(ret.data === temp.data ? 1 : 0);
popTempValue();
};
ExpNode.prototype.eval_notequal = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
ret.set_int(ret.data !== temp.data ? 1 : 0);
popTempValue();
};
ExpNode.prototype.eval_less = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
ret.set_int(ret.data < temp.data ? 1 : 0);
popTempValue();
};
ExpNode.prototype.eval_lessequal = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
ret.set_int(ret.data <= temp.data ? 1 : 0);
popTempValue();
};
ExpNode.prototype.eval_greater = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
ret.set_int(ret.data > temp.data ? 1 : 0);
popTempValue();
};
ExpNode.prototype.eval_greaterequal = function (ret)
{
this.first.get(ret); // left operand
var temp = pushTempValue();
this.second.get(temp); // right operand
ret.set_int(ret.data >= temp.data ? 1 : 0);
popTempValue();
};
ExpNode.prototype.eval_eventvar_exp = function (ret)
{
var val = this.eventvar.getValue();
if (cr.is_number(val))
ret.set_float(val);
else
ret.set_string(val);
};
cr.expNode = ExpNode;
function ExpValue(type, data)
{
this.type = type || cr.exptype.Integer;
this.data = data || 0;
this.object_class = null;
;
;
;
if (this.type == cr.exptype.Integer)
this.data = Math.floor(this.data);
cr.seal(this);
};
ExpValue.prototype.is_int = function ()
{
return this.type === cr.exptype.Integer;
};
ExpValue.prototype.is_float = function ()
{
return this.type === cr.exptype.Float;
};
ExpValue.prototype.is_number = function ()
{
return this.type === cr.exptype.Integer || this.type === cr.exptype.Float;
};
ExpValue.prototype.is_string = function ()
{
return this.type === cr.exptype.String;
};
ExpValue.prototype.make_int = function ()
{
if (!this.is_int())
{
if (this.is_float())
this.data = Math.floor(this.data); // truncate float
else if (this.is_string())
this.data = parseInt(this.data, 10);
this.type = cr.exptype.Integer;
}
};
ExpValue.prototype.make_float = function ()
{
if (!this.is_float())
{
if (this.is_string())
this.data = parseFloat(this.data);
this.type = cr.exptype.Float;
}
};
ExpValue.prototype.make_string = function ()
{
if (!this.is_string())
{
this.data = this.data.toString();
this.type = cr.exptype.String;
}
};
ExpValue.prototype.set_int = function (val)
{
;
this.type = cr.exptype.Integer;
this.data = Math.floor(val);
};
ExpValue.prototype.set_float = function (val)
{
;
this.type = cr.exptype.Float;
this.data = val;
};
ExpValue.prototype.set_string = function (val)
{
;
this.type = cr.exptype.String;
this.data = val;
};
ExpValue.prototype.set_any = function (val)
{
if (cr.is_number(val))
{
this.type = cr.exptype.Float;
this.data = val;
}
else if (cr.is_string(val))
{
this.type = cr.exptype.String;
this.data = val.toString();
}
else
{
this.type = cr.exptype.Integer;
this.data = 0;
}
};
cr.expvalue = ExpValue;
cr.exptype = {
Integer: 0, // emulated; no native integer support in javascript
Float: 1,
String: 2
};
}());
;
cr.system_object = function (runtime)
{
this.runtime = runtime;
this.waits = [];
};
cr.system_object.prototype.saveToJSON = function ()
{
var o = {};
var i, len, j, lenj, p, w, t, sobj;
o["waits"] = [];
var owaits = o["waits"];
var waitobj;
for (i = 0, len = this.waits.length; i < len; i++)
{
w = this.waits[i];
waitobj = {
"t": w.time,
"st": w.signaltag,
"s": w.signalled,
"ev": w.ev.sid,
"sm": [],
"sols": {}
};
if (w.ev.actions[w.actindex])
waitobj["act"] = w.ev.actions[w.actindex].sid;
for (j = 0, lenj = w.solModifiers.length; j < lenj; j++)
waitobj["sm"].push(w.solModifiers[j].sid);
for (p in w.sols)
{
if (w.sols.hasOwnProperty(p))
{
t = this.runtime.types_by_index[parseInt(p, 10)];
;
sobj = {
"sa": w.sols[p].sa,
"insts": []
};
for (j = 0, lenj = w.sols[p].insts.length; j < lenj; j++)
sobj["insts"].push(w.sols[p].insts[j].uid);
waitobj["sols"][t.sid.toString()] = sobj;
}
}
owaits.push(waitobj);
}
return o;
};
cr.system_object.prototype.loadFromJSON = function (o)
{
var owaits = o["waits"];
var i, len, j, lenj, p, w, addWait, e, aindex, t, savedsol, nusol, inst;
cr.clearArray(this.waits);
for (i = 0, len = owaits.length; i < len; i++)
{
w = owaits[i];
e = this.runtime.blocksBySid[w["ev"].toString()];
if (!e)
continue; // event must've gone missing
aindex = -1;
for (j = 0, lenj = e.actions.length; j < lenj; j++)
{
if (e.actions[j].sid === w["act"])
{
aindex = j;
break;
}
}
if (aindex === -1)
continue; // action must've gone missing
addWait = {};
addWait.sols = {};
addWait.solModifiers = [];
addWait.deleteme = false;
addWait.time = w["t"];
addWait.signaltag = w["st"] || "";
addWait.signalled = !!w["s"];
addWait.ev = e;
addWait.actindex = aindex;
for (j = 0, lenj = w["sm"].length; j < lenj; j++)
{
t = this.runtime.getObjectTypeBySid(w["sm"][j]);
if (t)
addWait.solModifiers.push(t);
}
for (p in w["sols"])
{
if (w["sols"].hasOwnProperty(p))
{
t = this.runtime.getObjectTypeBySid(parseInt(p, 10));
if (!t)
continue; // type must've been deleted
savedsol = w["sols"][p];
nusol = {
sa: savedsol["sa"],
insts: []
};
for (j = 0, lenj = savedsol["insts"].length; j < lenj; j++)
{
inst = this.runtime.getObjectByUID(savedsol["insts"][j]);
if (inst)
nusol.insts.push(inst);
}
addWait.sols[t.index.toString()] = nusol;
}
}
this.waits.push(addWait);
}
};
(function ()
{
var sysProto = cr.system_object.prototype;
function SysCnds() {};
SysCnds.prototype.EveryTick = function()
{
return true;
};
SysCnds.prototype.OnLayoutStart = function()
{
return true;
};
SysCnds.prototype.OnLayoutEnd = function()
{
return true;
};
SysCnds.prototype.Compare = function(x, cmp, y)
{
return cr.do_cmp(x, cmp, y);
};
SysCnds.prototype.CompareTime = function (cmp, t)
{
var elapsed = this.runtime.kahanTime.sum;
if (cmp === 0)
{
var cnd = this.runtime.getCurrentCondition();
if (!cnd.extra["CompareTime_executed"])
{
if (elapsed >= t)
{
cnd.extra["CompareTime_executed"] = true;
return true;
}
}
return false;
}
return cr.do_cmp(elapsed, cmp, t);
};
SysCnds.prototype.LayerVisible = function (layer)
{
if (!layer)
return false;
else
return layer.visible;
};
SysCnds.prototype.LayerEmpty = function (layer)
{
if (!layer)
return false;
else
return !layer.instances.length;
};
SysCnds.prototype.LayerCmpOpacity = function (layer, cmp, opacity_)
{
if (!layer)
return false;
return cr.do_cmp(layer.opacity * 100, cmp, opacity_);
};
SysCnds.prototype.Repeat = function (count)
{
var current_frame = this.runtime.getCurrentEventStack();
var current_event = current_frame.current_event;
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
var current_loop = this.runtime.pushLoopStack();
var i;
if (solModifierAfterCnds)
{
for (i = 0; i < count && !current_loop.stopped; i++)
{
this.runtime.pushCopySol(current_event.solModifiers);
current_loop.index = i;
current_event.retrigger();
this.runtime.popSol(current_event.solModifiers);
}
}
else
{
for (i = 0; i < count && !current_loop.stopped; i++)
{
current_loop.index = i;
current_event.retrigger();
}
}
this.runtime.popLoopStack();
return false;
};
SysCnds.prototype.While = function (count)
{
var current_frame = this.runtime.getCurrentEventStack();
var current_event = current_frame.current_event;
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
var current_loop = this.runtime.pushLoopStack();
var i;
if (solModifierAfterCnds)
{
for (i = 0; !current_loop.stopped; i++)
{
this.runtime.pushCopySol(current_event.solModifiers);
current_loop.index = i;
if (!current_event.retrigger()) // one of the other conditions returned false
current_loop.stopped = true; // break
this.runtime.popSol(current_event.solModifiers);
}
}
else
{
for (i = 0; !current_loop.stopped; i++)
{
current_loop.index = i;
if (!current_event.retrigger())
current_loop.stopped = true;
}
}
this.runtime.popLoopStack();
return false;
};
SysCnds.prototype.For = function (name, start, end)
{
var current_frame = this.runtime.getCurrentEventStack();
var current_event = current_frame.current_event;
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
var current_loop = this.runtime.pushLoopStack(name);
var i;
if (end < start)
{
if (solModifierAfterCnds)
{
for (i = start; i >= end && !current_loop.stopped; --i) // inclusive to end
{
this.runtime.pushCopySol(current_event.solModifiers);
current_loop.index = i;
current_event.retrigger();
this.runtime.popSol(current_event.solModifiers);
}
}
else
{
for (i = start; i >= end && !current_loop.stopped; --i) // inclusive to end
{
current_loop.index = i;
current_event.retrigger();
}
}
}
else
{
if (solModifierAfterCnds)
{
for (i = start; i <= end && !current_loop.stopped; ++i) // inclusive to end
{
this.runtime.pushCopySol(current_event.solModifiers);
current_loop.index = i;
current_event.retrigger();
this.runtime.popSol(current_event.solModifiers);
}
}
else
{
for (i = start; i <= end && !current_loop.stopped; ++i) // inclusive to end
{
current_loop.index = i;
current_event.retrigger();
}
}
}
this.runtime.popLoopStack();
return false;
};
var foreach_instancestack = [];
var foreach_instanceptr = -1;
SysCnds.prototype.ForEach = function (obj)
{
var sol = obj.getCurrentSol();
foreach_instanceptr++;
if (foreach_instancestack.length === foreach_instanceptr)
foreach_instancestack.push([]);
var instances = foreach_instancestack[foreach_instanceptr];
cr.shallowAssignArray(instances, sol.getObjects());
var current_frame = this.runtime.getCurrentEventStack();
var current_event = current_frame.current_event;
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
var current_loop = this.runtime.pushLoopStack();
var i, len, j, lenj, inst, s, sol2;
var is_contained = obj.is_contained;
if (solModifierAfterCnds)
{
for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
{
this.runtime.pushCopySol(current_event.solModifiers);
inst = instances[i];
sol = obj.getCurrentSol();
sol.select_all = false;
cr.clearArray(sol.instances);
sol.instances[0] = inst;
if (is_contained)
{
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
{
s = inst.siblings[j];
sol2 = s.type.getCurrentSol();
sol2.select_all = false;
cr.clearArray(sol2.instances);
sol2.instances[0] = s;
}
}
current_loop.index = i;
current_event.retrigger();
this.runtime.popSol(current_event.solModifiers);
}
}
else
{
sol.select_all = false;
cr.clearArray(sol.instances);
for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
{
inst = instances[i];
sol.instances[0] = inst;
if (is_contained)
{
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
{
s = inst.siblings[j];
sol2 = s.type.getCurrentSol();
sol2.select_all = false;
cr.clearArray(sol2.instances);
sol2.instances[0] = s;
}
}
current_loop.index = i;
current_event.retrigger();
}
}
cr.clearArray(instances);
this.runtime.popLoopStack();
foreach_instanceptr--;
return false;
};
function foreach_sortinstances(a, b)
{
var va = a.extra["c2_feo_val"];
var vb = b.extra["c2_feo_val"];
if (cr.is_number(va) && cr.is_number(vb))
return va - vb;
else
{
va = "" + va;
vb = "" + vb;
if (va < vb)
return -1;
else if (va > vb)
return 1;
else
return 0;
}
};
SysCnds.prototype.ForEachOrdered = function (obj, exp, order)
{
var sol = obj.getCurrentSol();
foreach_instanceptr++;
if (foreach_instancestack.length === foreach_instanceptr)
foreach_instancestack.push([]);
var instances = foreach_instancestack[foreach_instanceptr];
cr.shallowAssignArray(instances, sol.getObjects());
var current_frame = this.runtime.getCurrentEventStack();
var current_event = current_frame.current_event;
var current_condition = this.runtime.getCurrentCondition();
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
var current_loop = this.runtime.pushLoopStack();
var i, len, j, lenj, inst, s, sol2;
for (i = 0, len = instances.length; i < len; i++)
{
instances[i].extra["c2_feo_val"] = current_condition.parameters[1].get(i);
}
instances.sort(foreach_sortinstances);
if (order === 1)
instances.reverse();
var is_contained = obj.is_contained;
if (solModifierAfterCnds)
{
for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
{
this.runtime.pushCopySol(current_event.solModifiers);
inst = instances[i];
sol = obj.getCurrentSol();
sol.select_all = false;
cr.clearArray(sol.instances);
sol.instances[0] = inst;
if (is_contained)
{
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
{
s = inst.siblings[j];
sol2 = s.type.getCurrentSol();
sol2.select_all = false;
cr.clearArray(sol2.instances);
sol2.instances[0] = s;
}
}
current_loop.index = i;
current_event.retrigger();
this.runtime.popSol(current_event.solModifiers);
}
}
else
{
sol.select_all = false;
cr.clearArray(sol.instances);
for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
{
inst = instances[i];
sol.instances[0] = inst;
if (is_contained)
{
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
{
s = inst.siblings[j];
sol2 = s.type.getCurrentSol();
sol2.select_all = false;
cr.clearArray(sol2.instances);
sol2.instances[0] = s;
}
}
current_loop.index = i;
current_event.retrigger();
}
}
cr.clearArray(instances);
this.runtime.popLoopStack();
foreach_instanceptr--;
return false;
};
SysCnds.prototype.PickByComparison = function (obj_, exp_, cmp_, val_)
{
var i, len, k, inst;
if (!obj_)
return;
foreach_instanceptr++;
if (foreach_instancestack.length === foreach_instanceptr)
foreach_instancestack.push([]);
var tmp_instances = foreach_instancestack[foreach_instanceptr];
var sol = obj_.getCurrentSol();
cr.shallowAssignArray(tmp_instances, sol.getObjects());
if (sol.select_all)
cr.clearArray(sol.else_instances);
var current_condition = this.runtime.getCurrentCondition();
for (i = 0, k = 0, len = tmp_instances.length; i < len; i++)
{
inst = tmp_instances[i];
tmp_instances[k] = inst;
exp_ = current_condition.parameters[1].get(i);
val_ = current_condition.parameters[3].get(i);
if (cr.do_cmp(exp_, cmp_, val_))
{
k++;
}
else
{
sol.else_instances.push(inst);
}
}
cr.truncateArray(tmp_instances, k);
sol.select_all = false;
cr.shallowAssignArray(sol.instances, tmp_instances);
cr.clearArray(tmp_instances);
foreach_instanceptr--;
obj_.applySolToContainer();
return !!sol.instances.length;
};
SysCnds.prototype.PickByEvaluate = function (obj_, exp_)
{
var i, len, k, inst;
if (!obj_)
return;
foreach_instanceptr++;
if (foreach_instancestack.length === foreach_instanceptr)
foreach_instancestack.push([]);
var tmp_instances = foreach_instancestack[foreach_instanceptr];
var sol = obj_.getCurrentSol();
cr.shallowAssignArray(tmp_instances, sol.getObjects());
if (sol.select_all)
cr.clearArray(sol.else_instances);
var current_condition = this.runtime.getCurrentCondition();
for (i = 0, k = 0, len = tmp_instances.length; i < len; i++)
{
inst = tmp_instances[i];
tmp_instances[k] = inst;
exp_ = current_condition.parameters[1].get(i);
if (exp_)
{
k++;
}
else
{
sol.else_instances.push(inst);
}
}
cr.truncateArray(tmp_instances, k);
sol.select_all = false;
cr.shallowAssignArray(sol.instances, tmp_instances);
cr.clearArray(tmp_instances);
foreach_instanceptr--;
obj_.applySolToContainer();
return !!sol.instances.length;
};
SysCnds.prototype.TriggerOnce = function ()
{
var cndextra = this.runtime.getCurrentCondition().extra;
if (typeof cndextra["TriggerOnce_lastTick"] === "undefined")
cndextra["TriggerOnce_lastTick"] = -1;
var last_tick = cndextra["TriggerOnce_lastTick"];
var cur_tick = this.runtime.tickcount;
cndextra["TriggerOnce_lastTick"] = cur_tick;
return this.runtime.layout_first_tick || last_tick !== cur_tick - 1;
};
SysCnds.prototype.Every = function (seconds)
{
var cnd = this.runtime.getCurrentCondition();
var last_time = cnd.extra["Every_lastTime"] || 0;
var cur_time = this.runtime.kahanTime.sum;
if (typeof cnd.extra["Every_seconds"] === "undefined")
cnd.extra["Every_seconds"] = seconds;
var this_seconds = cnd.extra["Every_seconds"];
if (cur_time >= last_time + this_seconds)
{
cnd.extra["Every_lastTime"] = last_time + this_seconds;
if (cur_time >= cnd.extra["Every_lastTime"] + 0.04)
{
cnd.extra["Every_lastTime"] = cur_time;
}
cnd.extra["Every_seconds"] = seconds;
return true;
}
else if (cur_time < last_time - 0.1)
{
cnd.extra["Every_lastTime"] = cur_time;
}
return false;
};
SysCnds.prototype.PickNth = function (obj, index)
{
if (!obj)
return false;
var sol = obj.getCurrentSol();
var instances = sol.getObjects();
index = cr.floor(index);
if (index < 0 || index >= instances.length)
return false;
var inst = instances[index];
sol.pick_one(inst);
obj.applySolToContainer();
return true;
};
SysCnds.prototype.PickRandom = function (obj)
{
if (!obj)
return false;
var sol = obj.getCurrentSol();
var instances = sol.getObjects();
var index = cr.floor(Math.random() * instances.length);
if (index >= instances.length)
return false;
var inst = instances[index];
sol.pick_one(inst);
obj.applySolToContainer();
return true;
};
SysCnds.prototype.CompareVar = function (v, cmp, val)
{
return cr.do_cmp(v.getValue(), cmp, val);
};
SysCnds.prototype.IsGroupActive = function (group)
{
var g = this.runtime.groups_by_name[group.toLowerCase()];
return g && g.group_active;
};
SysCnds.prototype.IsPreview = function ()
{
return typeof cr_is_preview !== "undefined";
};
SysCnds.prototype.PickAll = function (obj)
{
if (!obj)
return false;
if (!obj.instances.length)
return false;
var sol = obj.getCurrentSol();
sol.select_all = true;
obj.applySolToContainer();
return true;
};
SysCnds.prototype.IsMobile = function ()
{
return this.runtime.isMobile;
};
SysCnds.prototype.CompareBetween = function (x, a, b)
{
return x >= a && x <= b;
};
SysCnds.prototype.Else = function ()
{
var current_frame = this.runtime.getCurrentEventStack();
if (current_frame.else_branch_ran)
return false; // another event in this else-if chain has run
else
return !current_frame.last_event_true;
/*
var current_frame = this.runtime.getCurrentEventStack();
var current_event = current_frame.current_event;
var prev_event = current_event.prev_block;
if (!prev_event)
return false;
if (prev_event.is_logical)
return !this.runtime.last_event_true;
var i, len, j, lenj, s, sol, temp, inst, any_picked = false;
for (i = 0, len = prev_event.cndReferences.length; i < len; i++)
{
s = prev_event.cndReferences[i];
sol = s.getCurrentSol();
if (sol.select_all || sol.instances.length === s.instances.length)
{
sol.select_all = false;
sol.instances.length = 0;
}
else
{
if (sol.instances.length === 1 && sol.else_instances.length === 0 && s.instances.length >= 2)
{
inst = sol.instances[0];
sol.instances.length = 0;
for (j = 0, lenj = s.instances.length; j < lenj; j++)
{
if (s.instances[j] != inst)
sol.instances.push(s.instances[j]);
}
any_picked = true;
}
else
{
temp = sol.instances;
sol.instances = sol.else_instances;
sol.else_instances = temp;
any_picked = true;
}
}
}
return any_picked;
*/
};
SysCnds.prototype.OnLoadFinished = function ()
{
return true;
};
SysCnds.prototype.OnCanvasSnapshot = function ()
{
return true;
};
SysCnds.prototype.EffectsSupported = function ()
{
return !!this.runtime.glwrap;
};
SysCnds.prototype.OnSaveComplete = function ()
{
return true;
};
SysCnds.prototype.OnSaveFailed = function ()
{
return true;
};
SysCnds.prototype.OnLoadComplete = function ()
{
return true;
};
SysCnds.prototype.OnLoadFailed = function ()
{
return true;
};
SysCnds.prototype.ObjectUIDExists = function (u)
{
return !!this.runtime.getObjectByUID(u);
};
SysCnds.prototype.IsOnPlatform = function (p)
{
var rt = this.runtime;
switch (p) {
case 0: // HTML5 website
return !rt.isDomFree && !rt.isNodeWebkit && !rt.isCordova && !rt.isWinJS && !rt.isWindowsPhone8 && !rt.isBlackberry10 && !rt.isAmazonWebApp;
case 1: // iOS
return rt.isiOS;
case 2: // Android
return rt.isAndroid;
case 3: // Windows 8
return rt.isWindows8App;
case 4: // Windows Phone 8
return rt.isWindowsPhone8;
case 5: // Blackberry 10
return rt.isBlackberry10;
case 6: // Tizen
return rt.isTizen;
case 7: // CocoonJS
return rt.isCocoonJs;
case 8: // Cordova
return rt.isCordova;
case 9: // Scirra Arcade
return rt.isArcade;
case 10: // node-webkit
return rt.isNodeWebkit;
case 11: // crosswalk
return rt.isCrosswalk;
case 12: // amazon webapp
return rt.isAmazonWebApp;
case 13: // windows 10 app
return rt.isWindows10;
default: // should not be possible
return false;
}
};
var cacheRegex = null;
var lastRegex = "";
var lastFlags = "";
function getRegex(regex_, flags_)
{
if (!cacheRegex || regex_ !== lastRegex || flags_ !== lastFlags)
{
cacheRegex = new RegExp(regex_, flags_);
lastRegex = regex_;
lastFlags = flags_;
}
cacheRegex.lastIndex = 0; // reset
return cacheRegex;
};
SysCnds.prototype.RegexTest = function (str_, regex_, flags_)
{
var regex = getRegex(regex_, flags_);
return regex.test(str_);
};
var tmp_arr = [];
SysCnds.prototype.PickOverlappingPoint = function (obj_, x_, y_)
{
if (!obj_)
return false;
var sol = obj_.getCurrentSol();
var instances = sol.getObjects();
var current_event = this.runtime.getCurrentEventStack().current_event;
var orblock = current_event.orblock;
var cnd = this.runtime.getCurrentCondition();
var i, len, inst, pick;
if (sol.select_all)
{
cr.shallowAssignArray(tmp_arr, instances);
cr.clearArray(sol.else_instances);
sol.select_all = false;
cr.clearArray(sol.instances);
}
else
{
if (orblock)
{
cr.shallowAssignArray(tmp_arr, sol.else_instances);
cr.clearArray(sol.else_instances);
}
else
{
cr.shallowAssignArray(tmp_arr, instances);
cr.clearArray(sol.instances);
}
}
for (i = 0, len = tmp_arr.length; i < len; ++i)
{
inst = tmp_arr[i];
inst.update_bbox();
pick = cr.xor(inst.contains_pt(x_, y_), cnd.inverted);
if (pick)
sol.instances.push(inst);
else
sol.else_instances.push(inst);
}
obj_.applySolToContainer();
return cr.xor(!!sol.instances.length, cnd.inverted);
};
SysCnds.prototype.IsNaN = function (n)
{
return !!isNaN(n);
};
SysCnds.prototype.AngleWithin = function (a1, within, a2)
{
return cr.angleDiff(cr.to_radians(a1), cr.to_radians(a2)) <= cr.to_radians(within);
};
SysCnds.prototype.IsClockwiseFrom = function (a1, a2)
{
return cr.angleClockwise(cr.to_radians(a1), cr.to_radians(a2));
};
SysCnds.prototype.IsBetweenAngles = function (a, la, ua)
{
var angle = cr.to_clamped_radians(a);
var lower = cr.to_clamped_radians(la);
var upper = cr.to_clamped_radians(ua);
var obtuse = (!cr.angleClockwise(upper, lower));
if (obtuse)
return !(!cr.angleClockwise(angle, lower) && cr.angleClockwise(angle, upper));
else
return cr.angleClockwise(angle, lower) && !cr.angleClockwise(angle, upper);
};
SysCnds.prototype.IsValueType = function (x, t)
{
if (typeof x === "number")
return t === 0;
else // string
return t === 1;
};
sysProto.cnds = new SysCnds();
function SysActs() {};
SysActs.prototype.GoToLayout = function (to)
{
if (this.runtime.isloading)
return; // cannot change layout while loading on loader layout
if (this.runtime.changelayout)
return; // already changing to a different layout
;
this.runtime.changelayout = to;
};
SysActs.prototype.NextPrevLayout = function (prev)
{
if (this.runtime.isloading)
return; // cannot change layout while loading on loader layout
if (this.runtime.changelayout)
return; // already changing to a different layout
var index = this.runtime.layouts_by_index.indexOf(this.runtime.running_layout);
if (prev && index === 0)
return; // cannot go to previous layout from first layout
if (!prev && index === this.runtime.layouts_by_index.length - 1)
return; // cannot go to next layout from last layout
var to = this.runtime.layouts_by_index[index + (prev ? -1 : 1)];
;
this.runtime.changelayout = to;
};
SysActs.prototype.CreateObject = function (obj, layer, x, y)
{
if (!layer || !obj)
return;
var inst = this.runtime.createInstance(obj, layer, x, y);
if (!inst)
return;
this.runtime.isInOnDestroy++;
var i, len, s;
this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst);
if (inst.is_contained)
{
for (i = 0, len = inst.siblings.length; i < len; i++)
{
s = inst.siblings[i];
this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
}
}
this.runtime.isInOnDestroy--;
var sol = obj.getCurrentSol();
sol.select_all = false;
cr.clearArray(sol.instances);
sol.instances[0] = inst;
if (inst.is_contained)
{
for (i = 0, len = inst.siblings.length; i < len; i++)
{
s = inst.siblings[i];
sol = s.type.getCurrentSol();
sol.select_all = false;
cr.clearArray(sol.instances);
sol.instances[0] = s;
}
}
};
SysActs.prototype.SetLayerVisible = function (layer, visible_)
{
if (!layer)
return;
if (layer.visible !== visible_)
{
layer.visible = visible_;
this.runtime.redraw = true;
}
};
SysActs.prototype.SetLayerOpacity = function (layer, opacity_)
{
if (!layer)
return;
opacity_ = cr.clamp(opacity_ / 100, 0, 1);
if (layer.opacity !== opacity_)
{
layer.opacity = opacity_;
this.runtime.redraw = true;
}
};
SysActs.prototype.SetLayerScaleRate = function (layer, sr)
{
if (!layer)
return;
if (layer.zoomRate !== sr)
{
layer.zoomRate = sr;
this.runtime.redraw = true;
}
};
SysActs.prototype.SetLayerForceOwnTexture = function (layer, f)
{
if (!layer)
return;
f = !!f;
if (layer.forceOwnTexture !== f)
{
layer.forceOwnTexture = f;
this.runtime.redraw = true;
}
};
SysActs.prototype.SetLayoutScale = function (s)
{
if (!this.runtime.running_layout)
return;
if (this.runtime.running_layout.scale !== s)
{
this.runtime.running_layout.scale = s;
this.runtime.running_layout.boundScrolling();
this.runtime.redraw = true;
}
};
SysActs.prototype.ScrollX = function(x)
{
this.runtime.running_layout.scrollToX(x);
};
SysActs.prototype.ScrollY = function(y)
{
this.runtime.running_layout.scrollToY(y);
};
SysActs.prototype.Scroll = function(x, y)
{
this.runtime.running_layout.scrollToX(x);
this.runtime.running_layout.scrollToY(y);
};
SysActs.prototype.ScrollToObject = function(obj)
{
var inst = obj.getFirstPicked();
if (inst)
{
this.runtime.running_layout.scrollToX(inst.x);
this.runtime.running_layout.scrollToY(inst.y);
}
};
SysActs.prototype.SetVar = function(v, x)
{
;
if (v.vartype === 0)
{
if (cr.is_number(x))
v.setValue(x);
else
v.setValue(parseFloat(x));
}
else if (v.vartype === 1)
v.setValue(x.toString());
};
SysActs.prototype.AddVar = function(v, x)
{
;
if (v.vartype === 0)
{
if (cr.is_number(x))
v.setValue(v.getValue() + x);
else
v.setValue(v.getValue() + parseFloat(x));
}
else if (v.vartype === 1)
v.setValue(v.getValue() + x.toString());
};
SysActs.prototype.SubVar = function(v, x)
{
;
if (v.vartype === 0)
{
if (cr.is_number(x))
v.setValue(v.getValue() - x);
else
v.setValue(v.getValue() - parseFloat(x));
}
};
SysActs.prototype.SetGroupActive = function (group, active)
{
var g = this.runtime.groups_by_name[group.toLowerCase()];
if (!g)
return;
switch (active) {
case 0:
g.setGroupActive(false);
break;
case 1:
g.setGroupActive(true);
break;
case 2:
g.setGroupActive(!g.group_active);
break;
}
};
SysActs.prototype.SetTimescale = function (ts_)
{
var ts = ts_;
if (ts < 0)
ts = 0;
this.runtime.timescale = ts;
};
SysActs.prototype.SetObjectTimescale = function (obj, ts_)
{
var ts = ts_;
if (ts < 0)
ts = 0;
if (!obj)
return;
var sol = obj.getCurrentSol();
var instances = sol.getObjects();
var i, len;
for (i = 0, len = instances.length; i < len; i++)
{
instances[i].my_timescale = ts;
}
};
SysActs.prototype.RestoreObjectTimescale = function (obj)
{
if (!obj)
return false;
var sol = obj.getCurrentSol();
var instances = sol.getObjects();
var i, len;
for (i = 0, len = instances.length; i < len; i++)
{
instances[i].my_timescale = -1.0;
}
};
var waitobjrecycle = [];
function allocWaitObject()
{
var w;
if (waitobjrecycle.length)
w = waitobjrecycle.pop();
else
{
w = {};
w.sols = {};
w.solModifiers = [];
}
w.deleteme = false;
return w;
};
function freeWaitObject(w)
{
cr.wipe(w.sols);
cr.clearArray(w.solModifiers);
waitobjrecycle.push(w);
};
var solstateobjects = [];
function allocSolStateObject()
{
var s;
if (solstateobjects.length)
s = solstateobjects.pop();
else
{
s = {};
s.insts = [];
}
s.sa = false;
return s;
};
function freeSolStateObject(s)
{
cr.clearArray(s.insts);
solstateobjects.push(s);
};
SysActs.prototype.Wait = function (seconds)
{
if (seconds < 0)
return;
var i, len, s, t, ss;
var evinfo = this.runtime.getCurrentEventStack();
var waitobj = allocWaitObject();
waitobj.time = this.runtime.kahanTime.sum + seconds;
waitobj.signaltag = "";
waitobj.signalled = false;
waitobj.ev = evinfo.current_event;
waitobj.actindex = evinfo.actindex + 1; // pointing at next action
for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
{
t = this.runtime.types_by_index[i];
s = t.getCurrentSol();
if (s.select_all && evinfo.current_event.solModifiers.indexOf(t) === -1)
continue;
waitobj.solModifiers.push(t);
ss = allocSolStateObject();
ss.sa = s.select_all;
cr.shallowAssignArray(ss.insts, s.instances);
waitobj.sols[i.toString()] = ss;
}
this.waits.push(waitobj);
return true;
};
SysActs.prototype.WaitForSignal = function (tag)
{
var i, len, s, t, ss;
var evinfo = this.runtime.getCurrentEventStack();
var waitobj = allocWaitObject();
waitobj.time = -1;
waitobj.signaltag = tag.toLowerCase();
waitobj.signalled = false;
waitobj.ev = evinfo.current_event;
waitobj.actindex = evinfo.actindex + 1; // pointing at next action
for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
{
t = this.runtime.types_by_index[i];
s = t.getCurrentSol();
if (s.select_all && evinfo.current_event.solModifiers.indexOf(t) === -1)
continue;
waitobj.solModifiers.push(t);
ss = allocSolStateObject();
ss.sa = s.select_all;
cr.shallowAssignArray(ss.insts, s.instances);
waitobj.sols[i.toString()] = ss;
}
this.waits.push(waitobj);
return true;
};
SysActs.prototype.Signal = function (tag)
{
var lowertag = tag.toLowerCase();
var i, len, w;
for (i = 0, len = this.waits.length; i < len; ++i)
{
w = this.waits[i];
if (w.time !== -1)
continue; // timer wait, ignore
if (w.signaltag === lowertag) // waiting for this signal
w.signalled = true; // will run on next check
}
};
SysActs.prototype.SetLayerScale = function (layer, scale)
{
if (!layer)
return;
if (layer.scale === scale)
return;
layer.scale = scale;
this.runtime.redraw = true;
};
SysActs.prototype.ResetGlobals = function ()
{
var i, len, g;
for (i = 0, len = this.runtime.all_global_vars.length; i < len; i++)
{
g = this.runtime.all_global_vars[i];
g.data = g.initial;
}
};
SysActs.prototype.SetLayoutAngle = function (a)
{
a = cr.to_radians(a);
a = cr.clamp_angle(a);
if (this.runtime.running_layout)
{
if (this.runtime.running_layout.angle !== a)
{
this.runtime.running_layout.angle = a;
this.runtime.redraw = true;
}
}
};
SysActs.prototype.SetLayerAngle = function (layer, a)
{
if (!layer)
return;
a = cr.to_radians(a);
a = cr.clamp_angle(a);
if (layer.angle === a)
return;
layer.angle = a;
this.runtime.redraw = true;
};
SysActs.prototype.SetLayerParallax = function (layer, px, py)
{
if (!layer)
return;
if (layer.parallaxX === px / 100 && layer.parallaxY === py / 100)
return;
layer.parallaxX = px / 100;
layer.parallaxY = py / 100;
if (layer.parallaxX !== 1 || layer.parallaxY !== 1)
{
var i, len, instances = layer.instances;
for (i = 0, len = instances.length; i < len; ++i)
{
instances[i].type.any_instance_parallaxed = true;
}
}
this.runtime.redraw = true;
};
SysActs.prototype.SetLayerBackground = function (layer, c)
{
if (!layer)
return;
var r = cr.GetRValue(c);
var g = cr.GetGValue(c);
var b = cr.GetBValue(c);
if (layer.background_color[0] === r && layer.background_color[1] === g && layer.background_color[2] === b)
return;
layer.background_color[0] = r;
layer.background_color[1] = g;
layer.background_color[2] = b;
this.runtime.redraw = true;
};
SysActs.prototype.SetLayerTransparent = function (layer, t)
{
if (!layer)
return;
if (!!t === !!layer.transparent)
return;
layer.transparent = !!t;
this.runtime.redraw = true;
};
SysActs.prototype.SetLayerBlendMode = function (layer, bm)
{
if (!layer)
return;
if (layer.blend_mode === bm)
return;
layer.blend_mode = bm;
layer.compositeOp = cr.effectToCompositeOp(layer.blend_mode);
if (this.runtime.gl)
cr.setGLBlend(layer, layer.blend_mode, this.runtime.gl);
this.runtime.redraw = true;
};
SysActs.prototype.StopLoop = function ()
{
if (this.runtime.loop_stack_index < 0)
return; // no loop currently running
this.runtime.getCurrentLoop().stopped = true;
};
SysActs.prototype.GoToLayoutByName = function (layoutname)
{
if (this.runtime.isloading)
return; // cannot change layout while loading on loader layout
if (this.runtime.changelayout)
return; // already changing to different layout
;
var l;
for (l in this.runtime.layouts)
{
if (this.runtime.layouts.hasOwnProperty(l) && cr.equals_nocase(l, layoutname))
{
this.runtime.changelayout = this.runtime.layouts[l];
return;
}
}
};
SysActs.prototype.RestartLayout = function (layoutname)
{
if (this.runtime.isloading)
return; // cannot restart loader layouts
if (this.runtime.changelayout)
return; // already changing to a different layout
;
if (!this.runtime.running_layout)
return;
this.runtime.changelayout = this.runtime.running_layout;
var i, len, g;
for (i = 0, len = this.runtime.allGroups.length; i < len; i++)
{
g = this.runtime.allGroups[i];
g.setGroupActive(g.initially_activated);
}
};
SysActs.prototype.SnapshotCanvas = function (format_, quality_)
{
this.runtime.doCanvasSnapshot(format_ === 0 ? "image/png" : "image/jpeg", quality_ / 100);
};
SysActs.prototype.SetCanvasSize = function (w, h)
{
if (w <= 0 || h <= 0)
return;
var mode = this.runtime.fullscreen_mode;
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.runtime.isNodeFullscreen);
if (isfullscreen && this.runtime.fullscreen_scaling > 0)
mode = this.runtime.fullscreen_scaling;
if (mode === 0)
{
this.runtime["setSize"](w, h, true);
}
else
{
this.runtime.original_width = w;
this.runtime.original_height = h;
this.runtime["setSize"](this.runtime.lastWindowWidth, this.runtime.lastWindowHeight, true);
}
};
SysActs.prototype.SetLayoutEffectEnabled = function (enable_, effectname_)
{
if (!this.runtime.running_layout || !this.runtime.glwrap)
return;
var et = this.runtime.running_layout.getEffectByName(effectname_);
if (!et)
return; // effect name not found
var enable = (enable_ === 1);
if (et.active == enable)
return; // no change
et.active = enable;
this.runtime.running_layout.updateActiveEffects();
this.runtime.redraw = true;
};
SysActs.prototype.SetLayerEffectEnabled = function (layer, enable_, effectname_)
{
if (!layer || !this.runtime.glwrap)
return;
var et = layer.getEffectByName(effectname_);
if (!et)
return; // effect name not found
var enable = (enable_ === 1);
if (et.active == enable)
return; // no change
et.active = enable;
layer.updateActiveEffects();
this.runtime.redraw = true;
};
SysActs.prototype.SetLayoutEffectParam = function (effectname_, index_, value_)
{
if (!this.runtime.running_layout || !this.runtime.glwrap)
return;
var et = this.runtime.running_layout.getEffectByName(effectname_);
if (!et)
return; // effect name not found
var params = this.runtime.running_layout.effect_params[et.index];
index_ = Math.floor(index_);
if (index_ < 0 || index_ >= params.length)
return; // effect index out of bounds
if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
value_ /= 100.0;
if (params[index_] === value_)
return; // no change
params[index_] = value_;
if (et.active)
this.runtime.redraw = true;
};
SysActs.prototype.SetLayerEffectParam = function (layer, effectname_, index_, value_)
{
if (!layer || !this.runtime.glwrap)
return;
var et = layer.getEffectByName(effectname_);
if (!et)
return; // effect name not found
var params = layer.effect_params[et.index];
index_ = Math.floor(index_);
if (index_ < 0 || index_ >= params.length)
return; // effect index out of bounds
if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
value_ /= 100.0;
if (params[index_] === value_)
return; // no change
params[index_] = value_;
if (et.active)
this.runtime.redraw = true;
};
SysActs.prototype.SaveState = function (slot_)
{
this.runtime.saveToSlot = slot_;
};
SysActs.prototype.LoadState = function (slot_)
{
this.runtime.loadFromSlot = slot_;
};
SysActs.prototype.LoadStateJSON = function (jsonstr_)
{
this.runtime.loadFromJson = jsonstr_;
};
SysActs.prototype.SetHalfFramerateMode = function (set_)
{
this.runtime.halfFramerateMode = (set_ !== 0);
};
SysActs.prototype.SetFullscreenQuality = function (q)
{
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.isNodeFullscreen);
if (!isfullscreen && this.runtime.fullscreen_mode === 0)
return;
this.runtime.wantFullscreenScalingQuality = (q !== 0);
this.runtime["setSize"](this.runtime.lastWindowWidth, this.runtime.lastWindowHeight, true);
};
SysActs.prototype.ResetPersisted = function ()
{
var i, len;
for (i = 0, len = this.runtime.layouts_by_index.length; i < len; ++i)
{
this.runtime.layouts_by_index[i].persist_data = {};
this.runtime.layouts_by_index[i].first_visit = true;
}
};
SysActs.prototype.RecreateInitialObjects = function (obj, x1, y1, x2, y2)
{
if (!obj)
return;
this.runtime.running_layout.recreateInitialObjects(obj, x1, y1, x2, y2);
};
SysActs.prototype.SetPixelRounding = function (m)
{
this.runtime.pixel_rounding = (m !== 0);
this.runtime.redraw = true;
};
SysActs.prototype.SetMinimumFramerate = function (f)
{
if (f < 1)
f = 1;
if (f > 120)
f = 120;
this.runtime.minimumFramerate = f;
};
function SortZOrderList(a, b)
{
var layerA = a[0];
var layerB = b[0];
var diff = layerA - layerB;
if (diff !== 0)
return diff;
var indexA = a[1];
var indexB = b[1];
return indexA - indexB;
};
function SortInstancesByValue(a, b)
{
return a[1] - b[1];
};
SysActs.prototype.SortZOrderByInstVar = function (obj, iv)
{
if (!obj)
return;
var i, len, inst, value, r, layer, toZ;
var sol = obj.getCurrentSol();
var pickedInstances = sol.getObjects();
var zOrderList = [];
var instValues = [];
var layout = this.runtime.running_layout;
var isFamily = obj.is_family;
var familyIndex = obj.family_index;
for (i = 0, len = pickedInstances.length; i < len; ++i)
{
inst = pickedInstances[i];
if (!inst.layer)
continue; // not a world instance
if (isFamily)
value = inst.instance_vars[iv + inst.type.family_var_map[familyIndex]];
else
value = inst.instance_vars[iv];
zOrderList.push([
inst.layer.index,
inst.get_zindex()
]);
instValues.push([
inst,
value
]);
}
if (!zOrderList.length)
return; // no instances were world instances
zOrderList.sort(SortZOrderList);
instValues.sort(SortInstancesByValue);
for (i = 0, len = zOrderList.length; i < len; ++i)
{
inst = instValues[i][0]; // instance in the order we want
layer = layout.layers[zOrderList[i][0]]; // layer to put it on
toZ = zOrderList[i][1]; // Z index on that layer to put it
if (layer.instances[toZ] !== inst) // not already got this instance there
{
layer.instances[toZ] = inst; // update instance
inst.layer = layer; // update instance's layer reference (could have changed)
layer.setZIndicesStaleFrom(toZ); // mark Z indices stale from this point since they have changed
}
}
};
sysProto.acts = new SysActs();
function SysExps() {};
SysExps.prototype["int"] = function(ret, x)
{
if (cr.is_string(x))
{
ret.set_int(parseInt(x, 10));
if (isNaN(ret.data))
ret.data = 0;
}
else
ret.set_int(x);
};
SysExps.prototype["float"] = function(ret, x)
{
if (cr.is_string(x))
{
ret.set_float(parseFloat(x));
if (isNaN(ret.data))
ret.data = 0;
}
else
ret.set_float(x);
};
SysExps.prototype.str = function(ret, x)
{
if (cr.is_string(x))
ret.set_string(x);
else
ret.set_string(x.toString());
};
SysExps.prototype.len = function(ret, x)
{
ret.set_int(x.length || 0);
};
SysExps.prototype.random = function (ret, a, b)
{
if (b === undefined)
{
ret.set_float(Math.random() * a);
}
else
{
ret.set_float(Math.random() * (b - a) + a);
}
};
SysExps.prototype.sqrt = function(ret, x)
{
ret.set_float(Math.sqrt(x));
};
SysExps.prototype.abs = function(ret, x)
{
ret.set_float(Math.abs(x));
};
SysExps.prototype.round = function(ret, x)
{
ret.set_int(Math.round(x));
};
SysExps.prototype.floor = function(ret, x)
{
ret.set_int(Math.floor(x));
};
SysExps.prototype.ceil = function(ret, x)
{
ret.set_int(Math.ceil(x));
};
SysExps.prototype.sin = function(ret, x)
{
ret.set_float(Math.sin(cr.to_radians(x)));
};
SysExps.prototype.cos = function(ret, x)
{
ret.set_float(Math.cos(cr.to_radians(x)));
};
SysExps.prototype.tan = function(ret, x)
{
ret.set_float(Math.tan(cr.to_radians(x)));
};
SysExps.prototype.asin = function(ret, x)
{
ret.set_float(cr.to_degrees(Math.asin(x)));
};
SysExps.prototype.acos = function(ret, x)
{
ret.set_float(cr.to_degrees(Math.acos(x)));
};
SysExps.prototype.atan = function(ret, x)
{
ret.set_float(cr.to_degrees(Math.atan(x)));
};
SysExps.prototype.exp = function(ret, x)
{
ret.set_float(Math.exp(x));
};
SysExps.prototype.ln = function(ret, x)
{
ret.set_float(Math.log(x));
};
SysExps.prototype.log10 = function(ret, x)
{
ret.set_float(Math.log(x) / Math.LN10);
};
SysExps.prototype.max = function(ret)
{
var max_ = arguments[1];
if (typeof max_ !== "number")
max_ = 0;
var i, len, a;
for (i = 2, len = arguments.length; i < len; i++)
{
a = arguments[i];
if (typeof a !== "number")
continue; // ignore non-numeric types
if (max_ < a)
max_ = a;
}
ret.set_float(max_);
};
SysExps.prototype.min = function(ret)
{
var min_ = arguments[1];
if (typeof min_ !== "number")
min_ = 0;
var i, len, a;
for (i = 2, len = arguments.length; i < len; i++)
{
a = arguments[i];
if (typeof a !== "number")
continue; // ignore non-numeric types
if (min_ > a)
min_ = a;
}
ret.set_float(min_);
};
SysExps.prototype.dt = function(ret)
{
ret.set_float(this.runtime.dt);
};
SysExps.prototype.timescale = function(ret)
{
ret.set_float(this.runtime.timescale);
};
SysExps.prototype.wallclocktime = function(ret)
{
ret.set_float((Date.now() - this.runtime.start_time) / 1000.0);
};
SysExps.prototype.time = function(ret)
{
ret.set_float(this.runtime.kahanTime.sum);
};
SysExps.prototype.tickcount = function(ret)
{
ret.set_int(this.runtime.tickcount);
};
SysExps.prototype.objectcount = function(ret)
{
ret.set_int(this.runtime.objectcount);
};
SysExps.prototype.fps = function(ret)
{
ret.set_int(this.runtime.fps);
};
SysExps.prototype.loopindex = function(ret, name_)
{
var loop, i, len;
if (!this.runtime.loop_stack.length)
{
ret.set_int(0);
return;
}
if (name_)
{
for (i = this.runtime.loop_stack_index; i >= 0; --i)
{
loop = this.runtime.loop_stack[i];
if (loop.name === name_)
{
ret.set_int(loop.index);
return;
}
}
ret.set_int(0);
}
else
{
loop = this.runtime.getCurrentLoop();
ret.set_int(loop ? loop.index : -1);
}
};
SysExps.prototype.distance = function(ret, x1, y1, x2, y2)
{
ret.set_float(cr.distanceTo(x1, y1, x2, y2));
};
SysExps.prototype.angle = function(ret, x1, y1, x2, y2)
{
ret.set_float(cr.to_degrees(cr.angleTo(x1, y1, x2, y2)));
};
SysExps.prototype.scrollx = function(ret)
{
ret.set_float(this.runtime.running_layout.scrollX);
};
SysExps.prototype.scrolly = function(ret)
{
ret.set_float(this.runtime.running_layout.scrollY);
};
SysExps.prototype.newline = function(ret)
{
ret.set_string("\n");
};
SysExps.prototype.lerp = function(ret, a, b, x)
{
ret.set_float(cr.lerp(a, b, x));
};
SysExps.prototype.qarp = function(ret, a, b, c, x)
{
ret.set_float(cr.qarp(a, b, c, x));
};
SysExps.prototype.cubic = function(ret, a, b, c, d, x)
{
ret.set_float(cr.cubic(a, b, c, d, x));
};
SysExps.prototype.cosp = function(ret, a, b, x)
{
ret.set_float(cr.cosp(a, b, x));
};
SysExps.prototype.windowwidth = function(ret)
{
ret.set_int(this.runtime.width);
};
SysExps.prototype.windowheight = function(ret)
{
ret.set_int(this.runtime.height);
};
SysExps.prototype.uppercase = function(ret, str)
{
ret.set_string(cr.is_string(str) ? str.toUpperCase() : "");
};
SysExps.prototype.lowercase = function(ret, str)
{
ret.set_string(cr.is_string(str) ? str.toLowerCase() : "");
};
SysExps.prototype.clamp = function(ret, x, l, u)
{
if (x < l)
ret.set_float(l);
else if (x > u)
ret.set_float(u);
else
ret.set_float(x);
};
SysExps.prototype.layerscale = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
if (!layer)
ret.set_float(0);
else
ret.set_float(layer.scale);
};
SysExps.prototype.layeropacity = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
if (!layer)
ret.set_float(0);
else
ret.set_float(layer.opacity * 100);
};
SysExps.prototype.layerscalerate = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
if (!layer)
ret.set_float(0);
else
ret.set_float(layer.zoomRate);
};
SysExps.prototype.layerparallaxx = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
if (!layer)
ret.set_float(0);
else
ret.set_float(layer.parallaxX * 100);
};
SysExps.prototype.layerparallaxy = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
if (!layer)
ret.set_float(0);
else
ret.set_float(layer.parallaxY * 100);
};
SysExps.prototype.layerindex = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
if (!layer)
ret.set_int(-1);
else
ret.set_int(layer.index);
};
SysExps.prototype.layoutscale = function (ret)
{
if (this.runtime.running_layout)
ret.set_float(this.runtime.running_layout.scale);
else
ret.set_float(0);
};
SysExps.prototype.layoutangle = function (ret)
{
ret.set_float(cr.to_degrees(this.runtime.running_layout.angle));
};
SysExps.prototype.layerangle = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
if (!layer)
ret.set_float(0);
else
ret.set_float(cr.to_degrees(layer.angle));
};
SysExps.prototype.layoutwidth = function (ret)
{
ret.set_int(this.runtime.running_layout.width);
};
SysExps.prototype.layoutheight = function (ret)
{
ret.set_int(this.runtime.running_layout.height);
};
SysExps.prototype.find = function (ret, text, searchstr)
{
if (cr.is_string(text) && cr.is_string(searchstr))
ret.set_int(text.search(new RegExp(cr.regexp_escape(searchstr), "i")));
else
ret.set_int(-1);
};
SysExps.prototype.findcase = function (ret, text, searchstr)
{
if (cr.is_string(text) && cr.is_string(searchstr))
ret.set_int(text.search(new RegExp(cr.regexp_escape(searchstr), "")));
else
ret.set_int(-1);
};
SysExps.prototype.left = function (ret, text, n)
{
ret.set_string(cr.is_string(text) ? text.substr(0, n) : "");
};
SysExps.prototype.right = function (ret, text, n)
{
ret.set_string(cr.is_string(text) ? text.substr(text.length - n) : "");
};
SysExps.prototype.mid = function (ret, text, index_, length_)
{
ret.set_string(cr.is_string(text) ? text.substr(index_, length_) : "");
};
SysExps.prototype.tokenat = function (ret, text, index_, sep)
{
if (cr.is_string(text) && cr.is_string(sep))
{
var arr = text.split(sep);
var i = cr.floor(index_);
if (i < 0 || i >= arr.length)
ret.set_string("");
else
ret.set_string(arr[i]);
}
else
ret.set_string("");
};
SysExps.prototype.tokencount = function (ret, text, sep)
{
if (cr.is_string(text) && text.length)
ret.set_int(text.split(sep).length);
else
ret.set_int(0);
};
SysExps.prototype.replace = function (ret, text, find_, replace_)
{
if (cr.is_string(text) && cr.is_string(find_) && cr.is_string(replace_))
ret.set_string(text.replace(new RegExp(cr.regexp_escape(find_), "gi"), replace_));
else
ret.set_string(cr.is_string(text) ? text : "");
};
SysExps.prototype.trim = function (ret, text)
{
ret.set_string(cr.is_string(text) ? text.trim() : "");
};
SysExps.prototype.pi = function (ret)
{
ret.set_float(cr.PI);
};
SysExps.prototype.layoutname = function (ret)
{
if (this.runtime.running_layout)
ret.set_string(this.runtime.running_layout.name);
else
ret.set_string("");
};
SysExps.prototype.renderer = function (ret)
{
ret.set_string(this.runtime.gl ? "webgl" : "canvas2d");
};
SysExps.prototype.rendererdetail = function (ret)
{
ret.set_string(this.runtime.glUnmaskedRenderer);
};
SysExps.prototype.anglediff = function (ret, a, b)
{
ret.set_float(cr.to_degrees(cr.angleDiff(cr.to_radians(a), cr.to_radians(b))));
};
SysExps.prototype.choose = function (ret)
{
var index = cr.floor(Math.random() * (arguments.length - 1));
ret.set_any(arguments[index + 1]);
};
SysExps.prototype.rgb = function (ret, r, g, b)
{
ret.set_int(cr.RGB(r, g, b));
};
SysExps.prototype.projectversion = function (ret)
{
ret.set_string(this.runtime.versionstr);
};
SysExps.prototype.projectname = function (ret)
{
ret.set_string(this.runtime.projectName);
};
SysExps.prototype.anglelerp = function (ret, a, b, x)
{
a = cr.to_radians(a);
b = cr.to_radians(b);
var diff = cr.angleDiff(a, b);
if (cr.angleClockwise(b, a))
{
ret.set_float(cr.to_clamped_degrees(a + diff * x));
}
else
{
ret.set_float(cr.to_clamped_degrees(a - diff * x));
}
};
SysExps.prototype.anglerotate = function (ret, a, b, c)
{
a = cr.to_radians(a);
b = cr.to_radians(b);
c = cr.to_radians(c);
ret.set_float(cr.to_clamped_degrees(cr.angleRotate(a, b, c)));
};
SysExps.prototype.zeropad = function (ret, n, d)
{
var s = (n < 0 ? "-" : "");
if (n < 0) n = -n;
var zeroes = d - n.toString().length;
for (var i = 0; i < zeroes; i++)
s += "0";
ret.set_string(s + n.toString());
};
SysExps.prototype.cpuutilisation = function (ret)
{
ret.set_float(this.runtime.cpuutilisation / 1000);
};
SysExps.prototype.viewportleft = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
ret.set_float(layer ? layer.viewLeft : 0);
};
SysExps.prototype.viewporttop = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
ret.set_float(layer ? layer.viewTop : 0);
};
SysExps.prototype.viewportright = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
ret.set_float(layer ? layer.viewRight : 0);
};
SysExps.prototype.viewportbottom = function (ret, layerparam)
{
var layer = this.runtime.getLayer(layerparam);
ret.set_float(layer ? layer.viewBottom : 0);
};
SysExps.prototype.loadingprogress = function (ret)
{
ret.set_float(this.runtime.loadingprogress);
};
SysExps.prototype.unlerp = function(ret, a, b, y)
{
ret.set_float(cr.unlerp(a, b, y));
};
SysExps.prototype.canvassnapshot = function (ret)
{
ret.set_string(this.runtime.snapshotData);
};
SysExps.prototype.urlencode = function (ret, s)
{
ret.set_string(encodeURIComponent(s));
};
SysExps.prototype.urldecode = function (ret, s)
{
ret.set_string(decodeURIComponent(s));
};
SysExps.prototype.canvastolayerx = function (ret, layerparam, x, y)
{
var layer = this.runtime.getLayer(layerparam);
ret.set_float(layer ? layer.canvasToLayer(x, y, true) : 0);
};
SysExps.prototype.canvastolayery = function (ret, layerparam, x, y)
{
var layer = this.runtime.getLayer(layerparam);
ret.set_float(layer ? layer.canvasToLayer(x, y, false) : 0);
};
SysExps.prototype.layertocanvasx = function (ret, layerparam, x, y)
{
var layer = this.runtime.getLayer(layerparam);
ret.set_float(layer ? layer.layerToCanvas(x, y, true) : 0);
};
SysExps.prototype.layertocanvasy = function (ret, layerparam, x, y)
{
var layer = this.runtime.getLayer(layerparam);
ret.set_float(layer ? layer.layerToCanvas(x, y, false) : 0);
};
SysExps.prototype.savestatejson = function (ret)
{
ret.set_string(this.runtime.lastSaveJson);
};
SysExps.prototype.imagememoryusage = function (ret)
{
if (this.runtime.glwrap)
ret.set_float(Math.round(100 * this.runtime.glwrap.estimateVRAM() / (1024 * 1024)) / 100);
else
ret.set_float(0);
};
SysExps.prototype.regexsearch = function (ret, str_, regex_, flags_)
{
var regex = getRegex(regex_, flags_);
ret.set_int(str_ ? str_.search(regex) : -1);
};
SysExps.prototype.regexreplace = function (ret, str_, regex_, flags_, replace_)
{
var regex = getRegex(regex_, flags_);
ret.set_string(str_ ? str_.replace(regex, replace_) : "");
};
var regexMatches = [];
var lastMatchesStr = "";
var lastMatchesRegex = "";
var lastMatchesFlags = "";
function updateRegexMatches(str_, regex_, flags_)
{
if (str_ === lastMatchesStr && regex_ === lastMatchesRegex && flags_ === lastMatchesFlags)
return;
var regex = getRegex(regex_, flags_);
regexMatches = str_.match(regex);
lastMatchesStr = str_;
lastMatchesRegex = regex_;
lastMatchesFlags = flags_;
};
SysExps.prototype.regexmatchcount = function (ret, str_, regex_, flags_)
{
var regex = getRegex(regex_, flags_);
updateRegexMatches(str_.toString(), regex_, flags_);
ret.set_int(regexMatches ? regexMatches.length : 0);
};
SysExps.prototype.regexmatchat = function (ret, str_, regex_, flags_, index_)
{
index_ = Math.floor(index_);
var regex = getRegex(regex_, flags_);
updateRegexMatches(str_.toString(), regex_, flags_);
if (!regexMatches || index_ < 0 || index_ >= regexMatches.length)
ret.set_string("");
else
ret.set_string(regexMatches[index_]);
};
SysExps.prototype.infinity = function (ret)
{
ret.set_float(Infinity);
};
SysExps.prototype.setbit = function (ret, n, b, v)
{
n = n | 0;
b = b | 0;
v = (v !== 0 ? 1 : 0);
ret.set_int((n & ~(1 << b)) | (v << b));
};
SysExps.prototype.togglebit = function (ret, n, b)
{
n = n | 0;
b = b | 0;
ret.set_int(n ^ (1 << b));
};
SysExps.prototype.getbit = function (ret, n, b)
{
n = n | 0;
b = b | 0;
ret.set_int((n & (1 << b)) ? 1 : 0);
};
SysExps.prototype.originalwindowwidth = function (ret)
{
ret.set_int(this.runtime.original_width);
};
SysExps.prototype.originalwindowheight = function (ret)
{
ret.set_int(this.runtime.original_height);
};
sysProto.exps = new SysExps();
sysProto.runWaits = function ()
{
var i, j, len, w, k, s, ss;
var evinfo = this.runtime.getCurrentEventStack();
for (i = 0, len = this.waits.length; i < len; i++)
{
w = this.waits[i];
if (w.time === -1) // signalled wait
{
if (!w.signalled)
continue; // not yet signalled
}
else // timer wait
{
if (w.time > this.runtime.kahanTime.sum)
continue; // timer not yet expired
}
evinfo.current_event = w.ev;
evinfo.actindex = w.actindex;
evinfo.cndindex = 0;
for (k in w.sols)
{
if (w.sols.hasOwnProperty(k))
{
s = this.runtime.types_by_index[parseInt(k, 10)].getCurrentSol();
ss = w.sols[k];
s.select_all = ss.sa;
cr.shallowAssignArray(s.instances, ss.insts);
freeSolStateObject(ss);
}
}
w.ev.resume_actions_and_subevents();
this.runtime.clearSol(w.solModifiers);
w.deleteme = true;
}
for (i = 0, j = 0, len = this.waits.length; i < len; i++)
{
w = this.waits[i];
this.waits[j] = w;
if (w.deleteme)
freeWaitObject(w);
else
j++;
}
cr.truncateArray(this.waits, j);
};
}());
;
(function () {
cr.add_common_aces = function (m, pluginProto)
{
var singleglobal_ = m[1];
var position_aces = m[3];
var size_aces = m[4];
var angle_aces = m[5];
var appearance_aces = m[6];
var zorder_aces = m[7];
var effects_aces = m[8];
if (!pluginProto.cnds)
pluginProto.cnds = {};
if (!pluginProto.acts)
pluginProto.acts = {};
if (!pluginProto.exps)
pluginProto.exps = {};
var cnds = pluginProto.cnds;
var acts = pluginProto.acts;
var exps = pluginProto.exps;
if (position_aces)
{
cnds.CompareX = function (cmp, x)
{
return cr.do_cmp(this.x, cmp, x);
};
cnds.CompareY = function (cmp, y)
{
return cr.do_cmp(this.y, cmp, y);
};
cnds.IsOnScreen = function ()
{
var layer = this.layer;
this.update_bbox();
var bbox = this.bbox;
return !(bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom);
};
cnds.IsOutsideLayout = function ()
{
this.update_bbox();
var bbox = this.bbox;
var layout = this.runtime.running_layout;
return (bbox.right < 0 || bbox.bottom < 0 || bbox.left > layout.width || bbox.top > layout.height);
};
cnds.PickDistance = function (which, x, y)
{
var sol = this.getCurrentSol();
var instances = sol.getObjects();
if (!instances.length)
return false;
var inst = instances[0];
var pickme = inst;
var dist = cr.distanceTo(inst.x, inst.y, x, y);
var i, len, d;
for (i = 1, len = instances.length; i < len; i++)
{
inst = instances[i];
d = cr.distanceTo(inst.x, inst.y, x, y);
if ((which === 0 && d < dist) || (which === 1 && d > dist))
{
dist = d;
pickme = inst;
}
}
sol.pick_one(pickme);
return true;
};
acts.SetX = function (x)
{
if (this.x !== x)
{
this.x = x;
this.set_bbox_changed();
}
};
acts.SetY = function (y)
{
if (this.y !== y)
{
this.y = y;
this.set_bbox_changed();
}
};
acts.SetPos = function (x, y)
{
if (this.x !== x || this.y !== y)
{
this.x = x;
this.y = y;
this.set_bbox_changed();
}
};
acts.SetPosToObject = function (obj, imgpt)
{
var inst = obj.getPairedInstance(this);
if (!inst)
return;
var newx, newy;
if (inst.getImagePoint)
{
newx = inst.getImagePoint(imgpt, true);
newy = inst.getImagePoint(imgpt, false);
}
else
{
newx = inst.x;
newy = inst.y;
}
if (this.x !== newx || this.y !== newy)
{
this.x = newx;
this.y = newy;
this.set_bbox_changed();
}
};
acts.MoveForward = function (dist)
{
if (dist !== 0)
{
this.x += Math.cos(this.angle) * dist;
this.y += Math.sin(this.angle) * dist;
this.set_bbox_changed();
}
};
acts.MoveAtAngle = function (a, dist)
{
if (dist !== 0)
{
this.x += Math.cos(cr.to_radians(a)) * dist;
this.y += Math.sin(cr.to_radians(a)) * dist;
this.set_bbox_changed();
}
};
exps.X = function (ret)
{
ret.set_float(this.x);
};
exps.Y = function (ret)
{
ret.set_float(this.y);
};
exps.dt = function (ret)
{
ret.set_float(this.runtime.getDt(this));
};
}
if (size_aces)
{
cnds.CompareWidth = function (cmp, w)
{
return cr.do_cmp(this.width, cmp, w);
};
cnds.CompareHeight = function (cmp, h)
{
return cr.do_cmp(this.height, cmp, h);
};
acts.SetWidth = function (w)
{
if (this.width !== w)
{
this.width = w;
this.set_bbox_changed();
}
};
acts.SetHeight = function (h)
{
if (this.height !== h)
{
this.height = h;
this.set_bbox_changed();
}
};
acts.SetSize = function (w, h)
{
if (this.width !== w || this.height !== h)
{
this.width = w;
this.height = h;
this.set_bbox_changed();
}
};
exps.Width = function (ret)
{
ret.set_float(this.width);
};
exps.Height = function (ret)
{
ret.set_float(this.height);
};
exps.BBoxLeft = function (ret)
{
this.update_bbox();
ret.set_float(this.bbox.left);
};
exps.BBoxTop = function (ret)
{
this.update_bbox();
ret.set_float(this.bbox.top);
};
exps.BBoxRight = function (ret)
{
this.update_bbox();
ret.set_float(this.bbox.right);
};
exps.BBoxBottom = function (ret)
{
this.update_bbox();
ret.set_float(this.bbox.bottom);
};
}
if (angle_aces)
{
cnds.AngleWithin = function (within, a)
{
return cr.angleDiff(this.angle, cr.to_radians(a)) <= cr.to_radians(within);
};
cnds.IsClockwiseFrom = function (a)
{
return cr.angleClockwise(this.angle, cr.to_radians(a));
};
cnds.IsBetweenAngles = function (a, b)
{
var lower = cr.to_clamped_radians(a);
var upper = cr.to_clamped_radians(b);
var angle = cr.clamp_angle(this.angle);
var obtuse = (!cr.angleClockwise(upper, lower));
if (obtuse)
return !(!cr.angleClockwise(angle, lower) && cr.angleClockwise(angle, upper));
else
return cr.angleClockwise(angle, lower) && !cr.angleClockwise(angle, upper);
};
acts.SetAngle = function (a)
{
var newangle = cr.to_radians(cr.clamp_angle_degrees(a));
if (isNaN(newangle))
return;
if (this.angle !== newangle)
{
this.angle = newangle;
this.set_bbox_changed();
}
};
acts.RotateClockwise = function (a)
{
if (a !== 0 && !isNaN(a))
{
this.angle += cr.to_radians(a);
this.angle = cr.clamp_angle(this.angle);
this.set_bbox_changed();
}
};
acts.RotateCounterclockwise = function (a)
{
if (a !== 0 && !isNaN(a))
{
this.angle -= cr.to_radians(a);
this.angle = cr.clamp_angle(this.angle);
this.set_bbox_changed();
}
};
acts.RotateTowardAngle = function (amt, target)
{
var newangle = cr.angleRotate(this.angle, cr.to_radians(target), cr.to_radians(amt));
if (isNaN(newangle))
return;
if (this.angle !== newangle)
{
this.angle = newangle;
this.set_bbox_changed();
}
};
acts.RotateTowardPosition = function (amt, x, y)
{
var dx = x - this.x;
var dy = y - this.y;
var target = Math.atan2(dy, dx);
var newangle = cr.angleRotate(this.angle, target, cr.to_radians(amt));
if (isNaN(newangle))
return;
if (this.angle !== newangle)
{
this.angle = newangle;
this.set_bbox_changed();
}
};
acts.SetTowardPosition = function (x, y)
{
var dx = x - this.x;
var dy = y - this.y;
var newangle = Math.atan2(dy, dx);
if (isNaN(newangle))
return;
if (this.angle !== newangle)
{
this.angle = newangle;
this.set_bbox_changed();
}
};
exps.Angle = function (ret)
{
ret.set_float(cr.to_clamped_degrees(this.angle));
};
}
if (!singleglobal_)
{
cnds.CompareInstanceVar = function (iv, cmp, val)
{
return cr.do_cmp(this.instance_vars[iv], cmp, val);
};
cnds.IsBoolInstanceVarSet = function (iv)
{
return this.instance_vars[iv];
};
cnds.PickInstVarHiLow = function (which, iv)
{
var sol = this.getCurrentSol();
var instances = sol.getObjects();
if (!instances.length)
return false;
var inst = instances[0];
var pickme = inst;
var val = inst.instance_vars[iv];
var i, len, v;
for (i = 1, len = instances.length; i < len; i++)
{
inst = instances[i];
v = inst.instance_vars[iv];
if ((which === 0 && v < val) || (which === 1 && v > val))
{
val = v;
pickme = inst;
}
}
sol.pick_one(pickme);
return true;
};
cnds.PickByUID = function (u)
{
var i, len, j, inst, families, instances, sol;
var cnd = this.runtime.getCurrentCondition();
if (cnd.inverted)
{
sol = this.getCurrentSol();
if (sol.select_all)
{
sol.select_all = false;
cr.clearArray(sol.instances);
cr.clearArray(sol.else_instances);
instances = this.instances;
for (i = 0, len = instances.length; i < len; i++)
{
inst = instances[i];
if (inst.uid === u)
sol.else_instances.push(inst);
else
sol.instances.push(inst);
}
this.applySolToContainer();
return !!sol.instances.length;
}
else
{
for (i = 0, j = 0, len = sol.instances.length; i < len; i++)
{
inst = sol.instances[i];
sol.instances[j] = inst;
if (inst.uid === u)
{
sol.else_instances.push(inst);
}
else
j++;
}
cr.truncateArray(sol.instances, j);
this.applySolToContainer();
return !!sol.instances.length;
}
}
else
{
inst = this.runtime.getObjectByUID(u);
if (!inst)
return false;
sol = this.getCurrentSol();
if (!sol.select_all && sol.instances.indexOf(inst) === -1)
return false; // not picked
if (this.is_family)
{
families = inst.type.families;
for (i = 0, len = families.length; i < len; i++)
{
if (families[i] === this)
{
sol.pick_one(inst);
this.applySolToContainer();
return true;
}
}
}
else if (inst.type === this)
{
sol.pick_one(inst);
this.applySolToContainer();
return true;
}
return false;
}
};
cnds.OnCreated = function ()
{
return true;
};
cnds.OnDestroyed = function ()
{
return true;
};
acts.SetInstanceVar = function (iv, val)
{
var myinstvars = this.instance_vars;
if (cr.is_number(myinstvars[iv]))
{
if (cr.is_number(val))
myinstvars[iv] = val;
else
myinstvars[iv] = parseFloat(val);
}
else if (cr.is_string(myinstvars[iv]))
{
if (cr.is_string(val))
myinstvars[iv] = val;
else
myinstvars[iv] = val.toString();
}
else
;
};
acts.AddInstanceVar = function (iv, val)
{
var myinstvars = this.instance_vars;
if (cr.is_number(myinstvars[iv]))
{
if (cr.is_number(val))
myinstvars[iv] += val;
else
myinstvars[iv] += parseFloat(val);
}
else if (cr.is_string(myinstvars[iv]))
{
if (cr.is_string(val))
myinstvars[iv] += val;
else
myinstvars[iv] += val.toString();
}
else
;
};
acts.SubInstanceVar = function (iv, val)
{
var myinstvars = this.instance_vars;
if (cr.is_number(myinstvars[iv]))
{
if (cr.is_number(val))
myinstvars[iv] -= val;
else
myinstvars[iv] -= parseFloat(val);
}
else
;
};
acts.SetBoolInstanceVar = function (iv, val)
{
this.instance_vars[iv] = val ? 1 : 0;
};
acts.ToggleBoolInstanceVar = function (iv)
{
this.instance_vars[iv] = 1 - this.instance_vars[iv];
};
acts.Destroy = function ()
{
this.runtime.DestroyInstance(this);
};
if (!acts.LoadFromJsonString)
{
acts.LoadFromJsonString = function (str_)
{
var o, i, len, binst;
try {
o = JSON.parse(str_);
}
catch (e) {
return;
}
this.runtime.loadInstanceFromJSON(this, o, true);
if (this.afterLoad)
this.afterLoad();
if (this.behavior_insts)
{
for (i = 0, len = this.behavior_insts.length; i < len; ++i)
{
binst = this.behavior_insts[i];
if (binst.afterLoad)
binst.afterLoad();
}
}
};
}
exps.Count = function (ret)
{
var count = ret.object_class.instances.length;
var i, len, inst;
for (i = 0, len = this.runtime.createRow.length; i < len; i++)
{
inst = this.runtime.createRow[i];
if (ret.object_class.is_family)
{
if (inst.type.families.indexOf(ret.object_class) >= 0)
count++;
}
else
{
if (inst.type === ret.object_class)
count++;
}
}
ret.set_int(count);
};
exps.PickedCount = function (ret)
{
ret.set_int(ret.object_class.getCurrentSol().getObjects().length);
};
exps.UID = function (ret)
{
ret.set_int(this.uid);
};
exps.IID = function (ret)
{
ret.set_int(this.get_iid());
};
if (!exps.AsJSON)
{
exps.AsJSON = function (ret)
{
ret.set_string(JSON.stringify(this.runtime.saveInstanceToJSON(this, true)));
};
}
}
if (appearance_aces)
{
cnds.IsVisible = function ()
{
return this.visible;
};
acts.SetVisible = function (v)
{
if (!v !== !this.visible)
{
this.visible = !!v;
this.runtime.redraw = true;
}
};
cnds.CompareOpacity = function (cmp, x)
{
return cr.do_cmp(cr.round6dp(this.opacity * 100), cmp, x);
};
acts.SetOpacity = function (x)
{
var new_opacity = x / 100.0;
if (new_opacity < 0)
new_opacity = 0;
else if (new_opacity > 1)
new_opacity = 1;
if (new_opacity !== this.opacity)
{
this.opacity = new_opacity;
this.runtime.redraw = true;
}
};
exps.Opacity = function (ret)
{
ret.set_float(cr.round6dp(this.opacity * 100.0));
};
}
if (zorder_aces)
{
cnds.IsOnLayer = function (layer_)
{
if (!layer_)
return false;
return this.layer === layer_;
};
cnds.PickTopBottom = function (which_)
{
var sol = this.getCurrentSol();
var instances = sol.getObjects();
if (!instances.length)
return false;
var inst = instances[0];
var pickme = inst;
var i, len;
for (i = 1, len = instances.length; i < len; i++)
{
inst = instances[i];
if (which_ === 0)
{
if (inst.layer.index > pickme.layer.index || (inst.layer.index === pickme.layer.index && inst.get_zindex() > pickme.get_zindex()))
{
pickme = inst;
}
}
else
{
if (inst.layer.index < pickme.layer.index || (inst.layer.index === pickme.layer.index && inst.get_zindex() < pickme.get_zindex()))
{
pickme = inst;
}
}
}
sol.pick_one(pickme);
return true;
};
acts.MoveToTop = function ()
{
var layer = this.layer;
var layer_instances = layer.instances;
if (layer_instances.length && layer_instances[layer_instances.length - 1] === this)
return; // is already at top
layer.removeFromInstanceList(this, false);
layer.appendToInstanceList(this, false);
this.runtime.redraw = true;
};
acts.MoveToBottom = function ()
{
var layer = this.layer;
var layer_instances = layer.instances;
if (layer_instances.length && layer_instances[0] === this)
return; // is already at bottom
layer.removeFromInstanceList(this, false);
layer.prependToInstanceList(this, false);
this.runtime.redraw = true;
};
acts.MoveToLayer = function (layerMove)
{
if (!layerMove || layerMove == this.layer)
return;
this.layer.removeFromInstanceList(this, true);
this.layer = layerMove;
layerMove.appendToInstanceList(this, true);
this.runtime.redraw = true;
};
acts.ZMoveToObject = function (where_, obj_)
{
var isafter = (where_ === 0);
if (!obj_)
return;
var other = obj_.getFirstPicked(this);
if (!other || other.uid === this.uid)
return;
if (this.layer.index !== other.layer.index)
{
this.layer.removeFromInstanceList(this, true);
this.layer = other.layer;
other.layer.appendToInstanceList(this, true);
}
this.layer.moveInstanceAdjacent(this, other, isafter);
this.runtime.redraw = true;
};
exps.LayerNumber = function (ret)
{
ret.set_int(this.layer.number);
};
exps.LayerName = function (ret)
{
ret.set_string(this.layer.name);
};
exps.ZIndex = function (ret)
{
ret.set_int(this.get_zindex());
};
}
if (effects_aces)
{
acts.SetEffectEnabled = function (enable_, effectname_)
{
if (!this.runtime.glwrap)
return;
var i = this.type.getEffectIndexByName(effectname_);
if (i < 0)
return; // effect name not found
var enable = (enable_ === 1);
if (this.active_effect_flags[i] === enable)
return; // no change
this.active_effect_flags[i] = enable;
this.updateActiveEffects();
this.runtime.redraw = true;
};
acts.SetEffectParam = function (effectname_, index_, value_)
{
if (!this.runtime.glwrap)
return;
var i = this.type.getEffectIndexByName(effectname_);
if (i < 0)
return; // effect name not found
var et = this.type.effect_types[i];
var params = this.effect_params[i];
index_ = Math.floor(index_);
if (index_ < 0 || index_ >= params.length)
return; // effect index out of bounds
if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
value_ /= 100.0;
if (params[index_] === value_)
return; // no change
params[index_] = value_;
if (et.active)
this.runtime.redraw = true;
};
}
};
cr.set_bbox_changed = function ()
{
this.bbox_changed = true; // will recreate next time box requested
this.cell_changed = true;
this.type.any_cell_changed = true; // avoid unnecessary updateAllBBox() calls
this.runtime.redraw = true; // assume runtime needs to redraw
var i, len, callbacks = this.bbox_changed_callbacks;
for (i = 0, len = callbacks.length; i < len; ++i)
{
callbacks[i](this);
}
if (this.layer.useRenderCells)
this.update_bbox();
};
cr.add_bbox_changed_callback = function (f)
{
if (f)
{
this.bbox_changed_callbacks.push(f);
}
};
cr.update_bbox = function ()
{
if (!this.bbox_changed)
return; // bounding box not changed
var bbox = this.bbox;
var bquad = this.bquad;
bbox.set(this.x, this.y, this.x + this.width, this.y + this.height);
bbox.offset(-this.hotspotX * this.width, -this.hotspotY * this.height);
if (!this.angle)
{
bquad.set_from_rect(bbox); // make bounding quad from box
}
else
{
bbox.offset(-this.x, -this.y); // translate to origin
bquad.set_from_rotated_rect(bbox, this.angle); // rotate around origin
bquad.offset(this.x, this.y); // translate back to original position
bquad.bounding_box(bbox);
}
bbox.normalize();
this.bbox_changed = false; // bounding box up to date
this.update_render_cell();
};
var tmprc = new cr.rect(0, 0, 0, 0);
cr.update_render_cell = function ()
{
if (!this.layer.useRenderCells)
return;
var mygrid = this.layer.render_grid;
var bbox = this.bbox;
tmprc.set(mygrid.XToCell(bbox.left), mygrid.YToCell(bbox.top), mygrid.XToCell(bbox.right), mygrid.YToCell(bbox.bottom));
if (this.rendercells.equals(tmprc))
return;
if (this.rendercells.right < this.rendercells.left)
mygrid.update(this, null, tmprc); // first insertion with invalid rect: don't provide old range
else
mygrid.update(this, this.rendercells, tmprc);
this.rendercells.copy(tmprc);
this.layer.render_list_stale = true;
};
cr.update_collision_cell = function ()
{
if (!this.cell_changed || !this.collisionsEnabled)
return;
this.update_bbox();
var mygrid = this.type.collision_grid;
var bbox = this.bbox;
tmprc.set(mygrid.XToCell(bbox.left), mygrid.YToCell(bbox.top), mygrid.XToCell(bbox.right), mygrid.YToCell(bbox.bottom));
if (this.collcells.equals(tmprc))
return;
if (this.collcells.right < this.collcells.left)
mygrid.update(this, null, tmprc); // first insertion with invalid rect: don't provide old range
else
mygrid.update(this, this.collcells, tmprc);
this.collcells.copy(tmprc);
this.cell_changed = false;
};
cr.inst_contains_pt = function (x, y)
{
if (!this.bbox.contains_pt(x, y))
return false;
if (!this.bquad.contains_pt(x, y))
return false;
if (this.tilemap_exists)
return this.testPointOverlapTile(x, y);
if (this.collision_poly && !this.collision_poly.is_empty())
{
this.collision_poly.cache_poly(this.width, this.height, this.angle);
return this.collision_poly.contains_pt(x - this.x, y - this.y);
}
else
return true;
};
cr.inst_get_iid = function ()
{
this.type.updateIIDs();
return this.iid;
};
cr.inst_get_zindex = function ()
{
this.layer.updateZIndices();
return this.zindex;
};
cr.inst_updateActiveEffects = function ()
{
cr.clearArray(this.active_effect_types);
var i, len, et;
var preserves_opaqueness = true;
for (i = 0, len = this.active_effect_flags.length; i < len; i++)
{
if (this.active_effect_flags[i])
{
et = this.type.effect_types[i];
this.active_effect_types.push(et);
if (!et.preservesOpaqueness)
preserves_opaqueness = false;
}
}
this.uses_shaders = !!this.active_effect_types.length;
this.shaders_preserve_opaqueness = preserves_opaqueness;
};
cr.inst_toString = function ()
{
return "Inst" + this.puid;
};
cr.type_getFirstPicked = function (frominst)
{
if (frominst && frominst.is_contained && frominst.type != this)
{
var i, len, s;
for (i = 0, len = frominst.siblings.length; i < len; i++)
{
s = frominst.siblings[i];
if (s.type == this)
return s;
}
}
var instances = this.getCurrentSol().getObjects();
if (instances.length)
return instances[0];
else
return null;
};
cr.type_getPairedInstance = function (inst)
{
var instances = this.getCurrentSol().getObjects();
if (instances.length)
return instances[inst.get_iid() % instances.length];
else
return null;
};
cr.type_updateIIDs = function ()
{
if (!this.stale_iids || this.is_family)
return; // up to date or is family - don't want family to overwrite IIDs
var i, len;
for (i = 0, len = this.instances.length; i < len; i++)
this.instances[i].iid = i;
var next_iid = i;
var createRow = this.runtime.createRow;
for (i = 0, len = createRow.length; i < len; ++i)
{
if (createRow[i].type === this)
createRow[i].iid = next_iid++;
}
this.stale_iids = false;
};
cr.type_getInstanceByIID = function (i)
{
if (i < this.instances.length)
return this.instances[i];
i -= this.instances.length;
var createRow = this.runtime.createRow;
var j, lenj;
for (j = 0, lenj = createRow.length; j < lenj; ++j)
{
if (createRow[j].type === this)
{
if (i === 0)
return createRow[j];
--i;
}
}
;
return null;
};
cr.type_getCurrentSol = function ()
{
return this.solstack[this.cur_sol];
};
cr.type_pushCleanSol = function ()
{
this.cur_sol++;
if (this.cur_sol === this.solstack.length)
{
this.solstack.push(new cr.selection(this));
}
else
{
this.solstack[this.cur_sol].select_all = true; // else clear next SOL
cr.clearArray(this.solstack[this.cur_sol].else_instances);
}
};
cr.type_pushCopySol = function ()
{
this.cur_sol++;
if (this.cur_sol === this.solstack.length)
this.solstack.push(new cr.selection(this));
var clonesol = this.solstack[this.cur_sol];
var prevsol = this.solstack[this.cur_sol - 1];
if (prevsol.select_all)
{
clonesol.select_all = true;
}
else
{
clonesol.select_all = false;
cr.shallowAssignArray(clonesol.instances, prevsol.instances);
}
cr.clearArray(clonesol.else_instances);
};
cr.type_popSol = function ()
{
;
this.cur_sol--;
};
cr.type_getBehaviorByName = function (behname)
{
var i, len, j, lenj, f, index = 0;
if (!this.is_family)
{
for (i = 0, len = this.families.length; i < len; i++)
{
f = this.families[i];
for (j = 0, lenj = f.behaviors.length; j < lenj; j++)
{
if (behname === f.behaviors[j].name)
{
this.extra["lastBehIndex"] = index;
return f.behaviors[j];
}
index++;
}
}
}
for (i = 0, len = this.behaviors.length; i < len; i++) {
if (behname === this.behaviors[i].name)
{
this.extra["lastBehIndex"] = index;
return this.behaviors[i];
}
index++;
}
return null;
};
cr.type_getBehaviorIndexByName = function (behname)
{
var b = this.getBehaviorByName(behname);
if (b)
return this.extra["lastBehIndex"];
else
return -1;
};
cr.type_getEffectIndexByName = function (name_)
{
var i, len;
for (i = 0, len = this.effect_types.length; i < len; i++)
{
if (this.effect_types[i].name === name_)
return i;
}
return -1;
};
cr.type_applySolToContainer = function ()
{
if (!this.is_contained || this.is_family)
return;
var i, len, j, lenj, t, sol, sol2;
this.updateIIDs();
sol = this.getCurrentSol();
var select_all = sol.select_all;
var es = this.runtime.getCurrentEventStack();
var orblock = es && es.current_event && es.current_event.orblock;
for (i = 0, len = this.container.length; i < len; i++)
{
t = this.container[i];
if (t === this)
continue;
t.updateIIDs();
sol2 = t.getCurrentSol();
sol2.select_all = select_all;
if (!select_all)
{
cr.clearArray(sol2.instances);
for (j = 0, lenj = sol.instances.length; j < lenj; ++j)
sol2.instances[j] = t.getInstanceByIID(sol.instances[j].iid);
if (orblock)
{
cr.clearArray(sol2.else_instances);
for (j = 0, lenj = sol.else_instances.length; j < lenj; ++j)
sol2.else_instances[j] = t.getInstanceByIID(sol.else_instances[j].iid);
}
}
}
};
cr.type_toString = function ()
{
return "Type" + this.sid;
};
cr.do_cmp = function (x, cmp, y)
{
if (typeof x === "undefined" || typeof y === "undefined")
return false;
switch (cmp)
{
case 0: // equal
return x === y;
case 1: // not equal
return x !== y;
case 2: // less
return x < y;
case 3: // less/equal
return x <= y;
case 4: // greater
return x > y;
case 5: // greater/equal
return x >= y;
default:
;
return false;
}
};
})();
cr.shaders = {};
;
;
cr.plugins_.AJAX = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var isNWjs = false;
var path = null;
var fs = null;
var nw_appfolder = "";
var pluginProto = cr.plugins_.AJAX.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
this.lastData = "";
this.curTag = "";
this.progress = 0;
this.timeout = -1;
isNWjs = this.runtime.isNWjs;
if (isNWjs)
{
path = require("path");
fs = require("fs");
var process = window["process"] || nw["process"];
nw_appfolder = path["dirname"](process["execPath"]) + "\\";
}
};
var instanceProto = pluginProto.Instance.prototype;
var theInstance = null;
window["C2_AJAX_DCSide"] = function (event_, tag_, param_)
{
if (!theInstance)
return;
if (event_ === "success")
{
theInstance.curTag = tag_;
theInstance.lastData = param_;
theInstance.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnAnyComplete, theInstance);
theInstance.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnComplete, theInstance);
}
else if (event_ === "error")
{
theInstance.curTag = tag_;
theInstance.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnAnyError, theInstance);
theInstance.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnError, theInstance);
}
else if (event_ === "progress")
{
theInstance.progress = param_;
theInstance.curTag = tag_;
theInstance.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnProgress, theInstance);
}
};
instanceProto.onCreate = function()
{
theInstance = this;
};
instanceProto.saveToJSON = function ()
{
return { "lastData": this.lastData };
};
instanceProto.loadFromJSON = function (o)
{
this.lastData = o["lastData"];
this.curTag = "";
this.progress = 0;
};
var next_request_headers = {};
var next_override_mime = "";
instanceProto.doRequest = function (tag_, url_, method_, data_)
{
if (this.runtime.isDirectCanvas)
{
AppMobi["webview"]["execute"]('C2_AJAX_WebSide("' + tag_ + '", "' + url_ + '", "' + method_ + '", ' + (data_ ? '"' + data_ + '"' : "null") + ');');
return;
}
var self = this;
var request = null;
var doErrorFunc = function ()
{
self.curTag = tag_;
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnAnyError, self);
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnError, self);
};
var errorFunc = function ()
{
if (isNWjs)
{
var filepath = nw_appfolder + url_;
if (fs["existsSync"](filepath))
{
fs["readFile"](filepath, {"encoding": "utf8"}, function (err, data) {
if (err)
{
doErrorFunc();
return;
}
self.curTag = tag_;
self.lastData = data.replace(/\r\n/g, "\n")
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnAnyComplete, self);
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnComplete, self);
});
}
else
doErrorFunc();
}
else
doErrorFunc();
};
var progressFunc = function (e)
{
if (!e["lengthComputable"])
return;
self.progress = e.loaded / e.total;
self.curTag = tag_;
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnProgress, self);
};
try
{
if (this.runtime.isWindowsPhone8)
request = new ActiveXObject("Microsoft.XMLHTTP");
else
request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (request.readyState === 4)
{
self.curTag = tag_;
if (request.responseText)
self.lastData = request.responseText.replace(/\r\n/g, "\n"); // fix windows style line endings
else
self.lastData = "";
if (request.status >= 400)
{
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnAnyError, self);
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnError, self);
}
else
{
if ((!isNWjs || self.lastData.length) && !(!isNWjs && request.status === 0 && !self.lastData.length))
{
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnAnyComplete, self);
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnComplete, self);
}
}
}
};
if (!this.runtime.isWindowsPhone8)
{
request.onerror = errorFunc;
request.ontimeout = errorFunc;
request.onabort = errorFunc;
request["onprogress"] = progressFunc;
}
request.open(method_, url_);
if (!this.runtime.isWindowsPhone8)
{
if (this.timeout >= 0 && typeof request["timeout"] !== "undefined")
request["timeout"] = this.timeout;
}
try {
request.responseType = "text";
} catch (e) {}
if (data_)
{
if (request["setRequestHeader"] && !next_request_headers.hasOwnProperty("Content-Type"))
{
request["setRequestHeader"]("Content-Type", "application/x-www-form-urlencoded");
}
}
if (request["setRequestHeader"])
{
var p;
for (p in next_request_headers)
{
if (next_request_headers.hasOwnProperty(p))
{
try {
request["setRequestHeader"](p, next_request_headers[p]);
}
catch (e) {}
}
}
next_request_headers = {};
}
if (next_override_mime && request["overrideMimeType"])
{
try {
request["overrideMimeType"](next_override_mime);
}
catch (e) {}
next_override_mime = "";
}
if (data_)
request.send(data_);
else
request.send();
}
catch (e)
{
errorFunc();
}
};
function Cnds() {};
Cnds.prototype.OnComplete = function (tag)
{
return cr.equals_nocase(tag, this.curTag);
};
Cnds.prototype.OnAnyComplete = function (tag)
{
return true;
};
Cnds.prototype.OnError = function (tag)
{
return cr.equals_nocase(tag, this.curTag);
};
Cnds.prototype.OnAnyError = function (tag)
{
return true;
};
Cnds.prototype.OnProgress = function (tag)
{
return cr.equals_nocase(tag, this.curTag);
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.Request = function (tag_, url_)
{
var self = this;
if (this.runtime.isWKWebView && !this.runtime.isAbsoluteUrl(url_))
{
this.runtime.fetchLocalFileViaCordovaAsText(url_,
function (str)
{
self.curTag = tag_;
self.lastData = str.replace(/\r\n/g, "\n"); // fix windows style line endings
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnAnyComplete, self);
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnComplete, self);
},
function (err)
{
self.curTag = tag_;
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnAnyError, self);
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnError, self);
});
}
else
{
this.doRequest(tag_, url_, "GET");
}
};
Acts.prototype.RequestFile = function (tag_, file_)
{
var self = this;
if (this.runtime.isWKWebView)
{
this.runtime.fetchLocalFileViaCordovaAsText(file_,
function (str)
{
self.curTag = tag_;
self.lastData = str.replace(/\r\n/g, "\n"); // fix windows style line endings
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnAnyComplete, self);
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnComplete, self);
},
function (err)
{
self.curTag = tag_;
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnAnyError, self);
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnError, self);
});
}
else
{
this.doRequest(tag_, file_, "GET");
}
};
Acts.prototype.Post = function (tag_, url_, data_, method_)
{
this.doRequest(tag_, url_, method_, data_);
};
Acts.prototype.SetTimeout = function (t)
{
this.timeout = t * 1000;
};
Acts.prototype.SetHeader = function (n, v)
{
next_request_headers[n] = v;
};
Acts.prototype.OverrideMIMEType = function (m)
{
next_override_mime = m;
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.LastData = function (ret)
{
ret.set_string(this.lastData);
};
Exps.prototype.Progress = function (ret)
{
ret.set_float(this.progress);
};
Exps.prototype.Tag = function (ret)
{
ret.set_string(this.curTag);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.Arr = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Arr.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
var arrCache = [];
function allocArray()
{
if (arrCache.length)
return arrCache.pop();
else
return [];
};
if (!Array.isArray)
{
Array.isArray = function (vArg) {
return Object.prototype.toString.call(vArg) === "[object Array]";
};
}
function freeArray(a)
{
var i, len;
for (i = 0, len = a.length; i < len; i++)
{
if (Array.isArray(a[i]))
freeArray(a[i]);
}
cr.clearArray(a);
arrCache.push(a);
};
instanceProto.onCreate = function()
{
this.cx = this.properties[0];
this.cy = this.properties[1];
this.cz = this.properties[2];
if (!this.recycled)
this.arr = allocArray();
var a = this.arr;
a.length = this.cx;
var x, y, z;
for (x = 0; x < this.cx; x++)
{
if (!a[x])
a[x] = allocArray();
a[x].length = this.cy;
for (y = 0; y < this.cy; y++)
{
if (!a[x][y])
a[x][y] = allocArray();
a[x][y].length = this.cz;
for (z = 0; z < this.cz; z++)
a[x][y][z] = 0;
}
}
this.forX = [];
this.forY = [];
this.forZ = [];
this.forDepth = -1;
};
instanceProto.onDestroy = function ()
{
var x;
for (x = 0; x < this.cx; x++)
freeArray(this.arr[x]); // will recurse down and recycle other arrays
cr.clearArray(this.arr);
};
instanceProto.at = function (x, y, z)
{
x = Math.floor(x);
y = Math.floor(y);
z = Math.floor(z);
if (isNaN(x) || x < 0 || x > this.cx - 1)
return 0;
if (isNaN(y) || y < 0 || y > this.cy - 1)
return 0;
if (isNaN(z) || z < 0 || z > this.cz - 1)
return 0;
return this.arr[x][y][z];
};
instanceProto.set = function (x, y, z, val)
{
x = Math.floor(x);
y = Math.floor(y);
z = Math.floor(z);
if (isNaN(x) || x < 0 || x > this.cx - 1)
return;
if (isNaN(y) || y < 0 || y > this.cy - 1)
return;
if (isNaN(z) || z < 0 || z > this.cz - 1)
return;
this.arr[x][y][z] = val;
};
instanceProto.getAsJSON = function ()
{
return JSON.stringify({
"c2array": true,
"size": [this.cx, this.cy, this.cz],
"data": this.arr
});
};
instanceProto.saveToJSON = function ()
{
return {
"size": [this.cx, this.cy, this.cz],
"data": this.arr
};
};
instanceProto.loadFromJSON = function (o)
{
var sz = o["size"];
this.cx = sz[0];
this.cy = sz[1];
this.cz = sz[2];
this.arr = o["data"];
};
instanceProto.setSize = function (w, h, 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; // no change
this.cx = w;
this.cy = h;
this.cz = d;
var x, y, z;
var a = this.arr;
a.length = w;
for (x = 0; x < this.cx; x++)
{
if (cr.is_undefined(a[x]))
a[x] = allocArray();
a[x].length = h;
for (y = 0; y < this.cy; y++)
{
if (cr.is_undefined(a[x][y]))
a[x][y] = allocArray();
a[x][y].length = d;
for (z = 0; z < this.cz; z++)
{
if (cr.is_undefined(a[x][y][z]))
a[x][y][z] = 0;
}
}
}
};
instanceProto.getForX = function ()
{
if (this.forDepth >= 0 && this.forDepth < this.forX.length)
return this.forX[this.forDepth];
else
return 0;
};
instanceProto.getForY = function ()
{
if (this.forDepth >= 0 && this.forDepth < this.forY.length)
return this.forY[this.forDepth];
else
return 0;
};
instanceProto.getForZ = function ()
{
if (this.forDepth >= 0 && this.forDepth < this.forZ.length)
return this.forZ[this.forDepth];
else
return 0;
};
function Cnds() {};
Cnds.prototype.CompareX = function (x, cmp, val)
{
return cr.do_cmp(this.at(x, 0, 0), cmp, val);
};
Cnds.prototype.CompareXY = function (x, y, cmp, val)
{
return cr.do_cmp(this.at(x, y, 0), cmp, val);
};
Cnds.prototype.CompareXYZ = function (x, y, z, cmp, val)
{
return cr.do_cmp(this.at(x, y, z), cmp, val);
};
instanceProto.doForEachTrigger = function (current_event)
{
this.runtime.pushCopySol(current_event.solModifiers);
current_event.retrigger();
this.runtime.popSol(current_event.solModifiers);
};
Cnds.prototype.ArrForEach = function (dims)
{
var current_event = this.runtime.getCurrentEventStack().current_event;
this.forDepth++;
var forDepth = this.forDepth;
if (forDepth === this.forX.length)
{
this.forX.push(0);
this.forY.push(0);
this.forZ.push(0);
}
else
{
this.forX[forDepth] = 0;
this.forY[forDepth] = 0;
this.forZ[forDepth] = 0;
}
switch (dims) {
case 0:
for (this.forX[forDepth] = 0; this.forX[forDepth] < this.cx; this.forX[forDepth]++)
{
for (this.forY[forDepth] = 0; this.forY[forDepth] < this.cy; this.forY[forDepth]++)
{
for (this.forZ[forDepth] = 0; this.forZ[forDepth] < this.cz; this.forZ[forDepth]++)
{
this.doForEachTrigger(current_event);
}
}
}
break;
case 1:
for (this.forX[forDepth] = 0; this.forX[forDepth] < this.cx; this.forX[forDepth]++)
{
for (this.forY[forDepth] = 0; this.forY[forDepth] < this.cy; this.forY[forDepth]++)
{
this.doForEachTrigger(current_event);
}
}
break;
case 2:
for (this.forX[forDepth] = 0; this.forX[forDepth] < this.cx; this.forX[forDepth]++)
{
this.doForEachTrigger(current_event);
}
break;
}
this.forDepth--;
return false;
};
Cnds.prototype.CompareCurrent = function (cmp, val)
{
return cr.do_cmp(this.at(this.getForX(), this.getForY(), this.getForZ()), cmp, val);
};
Cnds.prototype.Contains = function(val)
{
var x, y, z;
for (x = 0; x < this.cx; x++)
{
for (y = 0; y < this.cy; y++)
{
for (z = 0; z < this.cz; z++)
{
if (this.arr[x][y][z] === val)
return true;
}
}
}
return false;
};
Cnds.prototype.IsEmpty = function ()
{
return this.cx === 0 || this.cy === 0 || this.cz === 0;
};
Cnds.prototype.CompareSize = function (axis, cmp, value)
{
var s = 0;
switch (axis) {
case 0:
s = this.cx;
break;
case 1:
s = this.cy;
break;
case 2:
s = this.cz;
break;
}
return cr.do_cmp(s, cmp, value);
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.Clear = function ()
{
var x, y, z;
for (x = 0; x < this.cx; x++)
for (y = 0; y < this.cy; y++)
for (z = 0; z < this.cz; z++)
this.arr[x][y][z] = 0;
};
Acts.prototype.SetSize = function (w, h, d)
{
this.setSize(w, h, d);
};
Acts.prototype.SetX = function (x, val)
{
this.set(x, 0, 0, val);
};
Acts.prototype.SetXY = function (x, y, val)
{
this.set(x, y, 0, val);
};
Acts.prototype.SetXYZ = function (x, y, z, val)
{
this.set(x, y, z, val);
};
Acts.prototype.Push = function (where, value, axis)
{
var x = 0, y = 0, z = 0;
var a = this.arr;
switch (axis) {
case 0: // X axis
if (where === 0) // back
{
x = a.length;
a.push(allocArray());
}
else // front
{
x = 0;
a.unshift(allocArray());
}
a[x].length = this.cy;
for ( ; y < this.cy; y++)
{
a[x][y] = allocArray();
a[x][y].length = this.cz;
for (z = 0; z < this.cz; z++)
a[x][y][z] = value;
}
this.cx++;
break;
case 1: // Y axis
for ( ; x < this.cx; x++)
{
if (where === 0) // back
{
y = a[x].length;
a[x].push(allocArray());
}
else // front
{
y = 0;
a[x].unshift(allocArray());
}
a[x][y].length = this.cz;
for (z = 0; z < this.cz; z++)
a[x][y][z] = value;
}
this.cy++;
break;
case 2: // Z axis
for ( ; x < this.cx; x++)
{
for (y = 0; y < this.cy; y++)
{
if (where === 0) // back
{
a[x][y].push(value);
}
else // front
{
a[x][y].unshift(value);
}
}
}
this.cz++;
break;
}
};
Acts.prototype.Pop = function (where, axis)
{
var x = 0, y = 0, z = 0;
var a = this.arr;
switch (axis) {
case 0: // X axis
if (this.cx === 0)
break;
if (where === 0) // back
{
freeArray(a.pop());
}
else // front
{
freeArray(a.shift());
}
this.cx--;
break;
case 1: // Y axis
if (this.cy === 0)
break;
for ( ; x < this.cx; x++)
{
if (where === 0) // back
{
freeArray(a[x].pop());
}
else // front
{
freeArray(a[x].shift());
}
}
this.cy--;
break;
case 2: // Z axis
if (this.cz === 0)
break;
for ( ; x < this.cx; x++)
{
for (y = 0; y < this.cy; y++)
{
if (where === 0) // back
{
a[x][y].pop();
}
else // front
{
a[x][y].shift();
}
}
}
this.cz--;
break;
}
};
Acts.prototype.Reverse = function (axis)
{
var x = 0, y = 0, z = 0;
var a = this.arr;
if (this.cx === 0 || this.cy === 0 || this.cz === 0)
return; // no point reversing empty array
switch (axis) {
case 0: // X axis
a.reverse();
break;
case 1: // Y axis
for ( ; x < this.cx; x++)
a[x].reverse();
break;
case 2: // Z axis
for ( ; x < this.cx; x++)
for (y = 0; y < this.cy; y++)
a[x][y].reverse();
break;
}
};
function compareValues(va, vb)
{
if (cr.is_number(va) && cr.is_number(vb))
return va - vb;
else
{
var sa = "" + va;
var sb = "" + vb;
if (sa < sb)
return -1;
else if (sa > sb)
return 1;
else
return 0;
}
}
Acts.prototype.Sort = function (axis)
{
var x = 0, y = 0, z = 0;
var a = this.arr;
if (this.cx === 0 || this.cy === 0 || this.cz === 0)
return; // no point sorting empty array
switch (axis) {
case 0: // X axis
a.sort(function (a, b) {
return compareValues(a[0][0], b[0][0]);
});
break;
case 1: // Y axis
for ( ; x < this.cx; x++)
{
a[x].sort(function (a, b) {
return compareValues(a[0], b[0]);
});
}
break;
case 2: // Z axis
for ( ; x < this.cx; x++)
{
for (y = 0; y < this.cy; y++)
{
a[x][y].sort(compareValues);
}
}
break;
}
};
Acts.prototype.Delete = function (index, axis)
{
var x = 0, y = 0, z = 0;
index = Math.floor(index);
var a = this.arr;
if (index < 0)
return;
switch (axis) {
case 0: // X axis
if (index >= this.cx)
break;
freeArray(a[index]);
a.splice(index, 1);
this.cx--;
break;
case 1: // Y axis
if (index >= this.cy)
break;
for ( ; x < this.cx; x++)
{
freeArray(a[x][index]);
a[x].splice(index, 1);
}
this.cy--;
break;
case 2: // Z axis
if (index >= this.cz)
break;
for ( ; x < this.cx; x++)
{
for (y = 0; y < this.cy; y++)
{
a[x][y].splice(index, 1);
}
}
this.cz--;
break;
}
};
Acts.prototype.Insert = function (value, index, axis)
{
var x = 0, y = 0, z = 0;
index = Math.floor(index);
var a = this.arr;
if (index < 0)
return;
switch (axis) {
case 0: // X axis
if (index > this.cx)
return;
x = index;
a.splice(x, 0, allocArray());
a[x].length = this.cy;
for ( ; y < this.cy; y++)
{
a[x][y] = allocArray();
a[x][y].length = this.cz;
for (z = 0; z < this.cz; z++)
a[x][y][z] = value;
}
this.cx++;
break;
case 1: // Y axis
if (index > this.cy)
return;
for ( ; x < this.cx; x++)
{
y = index;
a[x].splice(y, 0, allocArray());
a[x][y].length = this.cz;
for (z = 0; z < this.cz; z++)
a[x][y][z] = value;
}
this.cy++;
break;
case 2: // Z axis
if (index > this.cz)
return;
for ( ; x < this.cx; x++)
{
for (y = 0; y < this.cy; y++)
{
a[x][y].splice(index, 0, value);
}
}
this.cz++;
break;
}
};
Acts.prototype.JSONLoad = function (json_)
{
var o;
try {
o = JSON.parse(json_);
}
catch(e) { return; }
if (!o["c2array"]) // presumably not a c2array object
return;
var sz = o["size"];
this.cx = sz[0];
this.cy = sz[1];
this.cz = sz[2];
this.arr = o["data"];
};
Acts.prototype.JSONDownload = function (filename)
{
var a = document.createElement("a");
if (typeof a.download === "undefined")
{
var str = 'data:text/html,' + encodeURIComponent("<p><a download='" + filename + "' href=\"data:application/json,"
+ encodeURIComponent(this.getAsJSON())
+ "\">Download link</a></p>");
window.open(str);
}
else
{
var body = document.getElementsByTagName("body")[0];
a.textContent = filename;
a.href = "data:application/json," + encodeURIComponent(this.getAsJSON());
a.download = filename;
body.appendChild(a);
var clickEvent = document.createEvent("MouseEvent");
clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
a.dispatchEvent(clickEvent);
body.removeChild(a);
}
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.At = function (ret, x, y_, z_)
{
var y = y_ || 0;
var z = z_ || 0;
ret.set_any(this.at(x, y, z));
};
Exps.prototype.Width = function (ret)
{
ret.set_int(this.cx);
};
Exps.prototype.Height = function (ret)
{
ret.set_int(this.cy);
};
Exps.prototype.Depth = function (ret)
{
ret.set_int(this.cz);
};
Exps.prototype.CurX = function (ret)
{
ret.set_int(this.getForX());
};
Exps.prototype.CurY = function (ret)
{
ret.set_int(this.getForY());
};
Exps.prototype.CurZ = function (ret)
{
ret.set_int(this.getForZ());
};
Exps.prototype.CurValue = function (ret)
{
ret.set_any(this.at(this.getForX(), this.getForY(), this.getForZ()));
};
Exps.prototype.Front = function (ret)
{
ret.set_any(this.at(0, 0, 0));
};
Exps.prototype.Back = function (ret)
{
ret.set_any(this.at(this.cx - 1, 0, 0));
};
Exps.prototype.IndexOf = function (ret, v)
{
for (var i = 0; i < this.cx; i++)
{
if (this.arr[i][0][0] === v)
{
ret.set_int(i);
return;
}
}
ret.set_int(-1);
};
Exps.prototype.LastIndexOf = function (ret, v)
{
for (var i = this.cx - 1; i >= 0; i--)
{
if (this.arr[i][0][0] === v)
{
ret.set_int(i);
return;
}
}
ret.set_int(-1);
};
Exps.prototype.AsJSON = function (ret)
{
ret.set_string(this.getAsJSON());
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.Audio = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Audio.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
var audRuntime = null;
var audInst = null;
var audTag = "";
var appPath = ""; // for Cordova only
var API_HTML5 = 0;
var API_WEBAUDIO = 1;
var API_CORDOVA = 2;
var API_APPMOBI = 3;
var api = API_HTML5;
var context = null;
var audioBuffers = []; // cache of buffers
var audioInstances = []; // cache of instances
var lastAudio = null;
var useOgg = false; // determined at create time
var timescale_mode = 0;
var silent = false;
var masterVolume = 1;
var listenerX = 0;
var listenerY = 0;
var isContextSuspended = false;
var panningModel = 1; // HRTF
var distanceModel = 1; // Inverse
var refDistance = 10;
var maxDistance = 10000;
var rolloffFactor = 1;
var micSource = null;
var micTag = "";
var useNextTouchWorkaround = false; // heuristic in case play() does not return a promise and we have to guess if the play was blocked
var playOnNextInput = []; // C2AudioInstances with HTMLAudioElements to play on next input event
var playMusicAsSoundWorkaround = false; // play music tracks with Web Audio API
var hasPlayedDummyBuffer = false; // dummy buffer played to unblock AudioContext on some platforms
function addAudioToPlayOnNextInput(a)
{
var i = playOnNextInput.indexOf(a);
if (i === -1)
playOnNextInput.push(a);
};
function tryPlayAudioElement(a)
{
var audioElem = a.instanceObject;
var playRet;
try {
playRet = audioElem.play();
}
catch (err) {
addAudioToPlayOnNextInput(a);
return;
}
if (playRet) // promise was returned
{
playRet.catch(function (err)
{
addAudioToPlayOnNextInput(a);
});
}
else if (useNextTouchWorkaround && !audRuntime.isInUserInputEvent)
{
addAudioToPlayOnNextInput(a);
}
};
function playQueuedAudio()
{
var i, len, m, playRet;
if (!hasPlayedDummyBuffer && !isContextSuspended && context)
{
playDummyBuffer();
if (context["state"] === "running")
hasPlayedDummyBuffer = true;
}
var tryPlay = playOnNextInput.slice(0);
cr.clearArray(playOnNextInput);
if (!silent)
{
for (i = 0, len = tryPlay.length; i < len; ++i)
{
m = tryPlay[i];
if (!m.stopped && !m.is_paused)
{
playRet = m.instanceObject.play();
if (playRet)
{
playRet.catch(function (err)
{
addAudioToPlayOnNextInput(m);
});
}
}
}
}
};
function playDummyBuffer()
{
if (context["state"] === "suspended" && context["resume"])
context["resume"]();
if (!context["createBuffer"])
return;
var buffer = context["createBuffer"](1, 220, 22050);
var source = context["createBufferSource"]();
source["buffer"] = buffer;
source["connect"](context["destination"]);
startSource(source);
};
document.addEventListener("pointerup", playQueuedAudio, true);
document.addEventListener("touchend", playQueuedAudio, true);
document.addEventListener("click", playQueuedAudio, true);
document.addEventListener("keydown", playQueuedAudio, true);
document.addEventListener("gamepadconnected", playQueuedAudio, true);
function dbToLinear(x)
{
var v = dbToLinear_nocap(x);
if (!isFinite(v)) // accidentally passing a string can result in NaN; set volume to 0 if so
v = 0;
if (v < 0)
v = 0;
if (v > 1)
v = 1;
return v;
};
function linearToDb(x)
{
if (x < 0)
x = 0;
if (x > 1)
x = 1;
return linearToDb_nocap(x);
};
function dbToLinear_nocap(x)
{
return Math.pow(10, x / 20);
};
function linearToDb_nocap(x)
{
return (Math.log(x) / Math.log(10)) * 20;
};
var effects = {};
function getDestinationForTag(tag)
{
tag = tag.toLowerCase();
if (effects.hasOwnProperty(tag))
{
if (effects[tag].length)
return effects[tag][0].getInputNode();
}
return context["destination"];
};
function createGain()
{
if (context["createGain"])
return context["createGain"]();
else
return context["createGainNode"]();
};
function createDelay(d)
{
if (context["createDelay"])
return context["createDelay"](d);
else
return context["createDelayNode"](d);
};
function startSource(s, scheduledTime)
{
if (s["start"])
s["start"](scheduledTime || 0);
else
s["noteOn"](scheduledTime || 0);
};
function startSourceAt(s, x, d, scheduledTime)
{
if (s["start"])
s["start"](scheduledTime || 0, x);
else
s["noteGrainOn"](scheduledTime || 0, x, d - x);
};
function stopSource(s)
{
try {
if (s["stop"])
s["stop"](0);
else
s["noteOff"](0);
}
catch (e) {}
};
function setAudioParam(ap, value, ramp, time)
{
if (!ap)
return; // iOS is missing some parameters
ap["cancelScheduledValues"](0);
if (time === 0)
{
ap["value"] = value;
return;
}
var curTime = context["currentTime"];
time += curTime;
switch (ramp) {
case 0: // step
ap["setValueAtTime"](value, time);
break;
case 1: // linear
ap["setValueAtTime"](ap["value"], curTime); // to set what to ramp from
ap["linearRampToValueAtTime"](value, time);
break;
case 2: // exponential
ap["setValueAtTime"](ap["value"], curTime); // to set what to ramp from
ap["exponentialRampToValueAtTime"](value, time);
break;
}
};
var filterTypes = ["lowpass", "highpass", "bandpass", "lowshelf", "highshelf", "peaking", "notch", "allpass"];
function FilterEffect(type, freq, detune, q, gain, mix)
{
this.type = "filter";
this.params = [type, freq, detune, q, gain, mix];
this.inputNode = createGain();
this.wetNode = createGain();
this.wetNode["gain"]["value"] = mix;
this.dryNode = createGain();
this.dryNode["gain"]["value"] = 1 - mix;
this.filterNode = context["createBiquadFilter"]();
if (typeof this.filterNode["type"] === "number")
this.filterNode["type"] = type;
else
this.filterNode["type"] = filterTypes[type];
this.filterNode["frequency"]["value"] = freq;
if (this.filterNode["detune"]) // iOS 6 doesn't have detune yet
this.filterNode["detune"]["value"] = detune;
this.filterNode["Q"]["value"] = q;
this.filterNode["gain"]["value"] = gain;
this.inputNode["connect"](this.filterNode);
this.inputNode["connect"](this.dryNode);
this.filterNode["connect"](this.wetNode);
};
FilterEffect.prototype.connectTo = function (node)
{
this.wetNode["disconnect"]();
this.wetNode["connect"](node);
this.dryNode["disconnect"]();
this.dryNode["connect"](node);
};
FilterEffect.prototype.remove = function ()
{
this.inputNode["disconnect"]();
this.filterNode["disconnect"]();
this.wetNode["disconnect"]();
this.dryNode["disconnect"]();
};
FilterEffect.prototype.getInputNode = function ()
{
return this.inputNode;
};
FilterEffect.prototype.setParam = function(param, value, ramp, time)
{
switch (param) {
case 0: // mix
value = value / 100;
if (value < 0) value = 0;
if (value > 1) value = 1;
this.params[5] = value;
setAudioParam(this.wetNode["gain"], value, ramp, time);
setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
break;
case 1: // filter frequency
this.params[1] = value;
setAudioParam(this.filterNode["frequency"], value, ramp, time);
break;
case 2: // filter detune
this.params[2] = value;
setAudioParam(this.filterNode["detune"], value, ramp, time);
break;
case 3: // filter Q
this.params[3] = value;
setAudioParam(this.filterNode["Q"], value, ramp, time);
break;
case 4: // filter/delay gain (note value is in dB here)
this.params[4] = value;
setAudioParam(this.filterNode["gain"], value, ramp, time);
break;
}
};
function DelayEffect(delayTime, delayGain, mix)
{
this.type = "delay";
this.params = [delayTime, delayGain, mix];
this.inputNode = createGain();
this.wetNode = createGain();
this.wetNode["gain"]["value"] = mix;
this.dryNode = createGain();
this.dryNode["gain"]["value"] = 1 - mix;
this.mainNode = createGain();
this.delayNode = createDelay(delayTime);
this.delayNode["delayTime"]["value"] = delayTime;
this.delayGainNode = createGain();
this.delayGainNode["gain"]["value"] = delayGain;
this.inputNode["connect"](this.mainNode);
this.inputNode["connect"](this.dryNode);
this.mainNode["connect"](this.wetNode);
this.mainNode["connect"](this.delayNode);
this.delayNode["connect"](this.delayGainNode);
this.delayGainNode["connect"](this.mainNode);
};
DelayEffect.prototype.connectTo = function (node)
{
this.wetNode["disconnect"]();
this.wetNode["connect"](node);
this.dryNode["disconnect"]();
this.dryNode["connect"](node);
};
DelayEffect.prototype.remove = function ()
{
this.inputNode["disconnect"]();
this.mainNode["disconnect"]();
this.delayNode["disconnect"]();
this.delayGainNode["disconnect"]();
this.wetNode["disconnect"]();
this.dryNode["disconnect"]();
};
DelayEffect.prototype.getInputNode = function ()
{
return this.inputNode;
};
DelayEffect.prototype.setParam = function(param, value, ramp, time)
{
switch (param) {
case 0: // mix
value = value / 100;
if (value < 0) value = 0;
if (value > 1) value = 1;
this.params[2] = value;
setAudioParam(this.wetNode["gain"], value, ramp, time);
setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
break;
case 4: // filter/delay gain (note value is passed in dB but needs to be linear here)
this.params[1] = dbToLinear(value);
setAudioParam(this.delayGainNode["gain"], dbToLinear(value), ramp, time);
break;
case 5: // delay time
this.params[0] = value;
setAudioParam(this.delayNode["delayTime"], value, ramp, time);
break;
}
};
function ConvolveEffect(buffer, normalize, mix, src)
{
this.type = "convolve";
this.params = [normalize, mix, src];
this.inputNode = createGain();
this.wetNode = createGain();
this.wetNode["gain"]["value"] = mix;
this.dryNode = createGain();
this.dryNode["gain"]["value"] = 1 - mix;
this.convolveNode = context["createConvolver"]();
if (buffer)
{
this.convolveNode["normalize"] = normalize;
this.convolveNode["buffer"] = buffer;
}
this.inputNode["connect"](this.convolveNode);
this.inputNode["connect"](this.dryNode);
this.convolveNode["connect"](this.wetNode);
};
ConvolveEffect.prototype.connectTo = function (node)
{
this.wetNode["disconnect"]();
this.wetNode["connect"](node);
this.dryNode["disconnect"]();
this.dryNode["connect"](node);
};
ConvolveEffect.prototype.remove = function ()
{
this.inputNode["disconnect"]();
this.convolveNode["disconnect"]();
this.wetNode["disconnect"]();
this.dryNode["disconnect"]();
};
ConvolveEffect.prototype.getInputNode = function ()
{
return this.inputNode;
};
ConvolveEffect.prototype.setParam = function(param, value, ramp, time)
{
switch (param) {
case 0: // mix
value = value / 100;
if (value < 0) value = 0;
if (value > 1) value = 1;
this.params[1] = value;
setAudioParam(this.wetNode["gain"], value, ramp, time);
setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
break;
}
};
function FlangerEffect(delay, modulation, freq, feedback, mix)
{
this.type = "flanger";
this.params = [delay, modulation, freq, feedback, mix];
this.inputNode = createGain();
this.dryNode = createGain();
this.dryNode["gain"]["value"] = 1 - (mix / 2);
this.wetNode = createGain();
this.wetNode["gain"]["value"] = mix / 2;
this.feedbackNode = createGain();
this.feedbackNode["gain"]["value"] = feedback;
this.delayNode = createDelay(delay + modulation);
this.delayNode["delayTime"]["value"] = delay;
this.oscNode = context["createOscillator"]();
this.oscNode["frequency"]["value"] = freq;
this.oscGainNode = createGain();
this.oscGainNode["gain"]["value"] = modulation;
this.inputNode["connect"](this.delayNode);
this.inputNode["connect"](this.dryNode);
this.delayNode["connect"](this.wetNode);
this.delayNode["connect"](this.feedbackNode);
this.feedbackNode["connect"](this.delayNode);
this.oscNode["connect"](this.oscGainNode);
this.oscGainNode["connect"](this.delayNode["delayTime"]);
startSource(this.oscNode);
};
FlangerEffect.prototype.connectTo = function (node)
{
this.dryNode["disconnect"]();
this.dryNode["connect"](node);
this.wetNode["disconnect"]();
this.wetNode["connect"](node);
};
FlangerEffect.prototype.remove = function ()
{
this.inputNode["disconnect"]();
this.delayNode["disconnect"]();
this.oscNode["disconnect"]();
this.oscGainNode["disconnect"]();
this.dryNode["disconnect"]();
this.wetNode["disconnect"]();
this.feedbackNode["disconnect"]();
};
FlangerEffect.prototype.getInputNode = function ()
{
return this.inputNode;
};
FlangerEffect.prototype.setParam = function(param, value, ramp, time)
{
switch (param) {
case 0: // mix
value = value / 100;
if (value < 0) value = 0;
if (value > 1) value = 1;
this.params[4] = value;
setAudioParam(this.wetNode["gain"], value / 2, ramp, time);
setAudioParam(this.dryNode["gain"], 1 - (value / 2), ramp, time);
break;
case 6: // modulation
this.params[1] = value / 1000;
setAudioParam(this.oscGainNode["gain"], value / 1000, ramp, time);
break;
case 7: // modulation frequency
this.params[2] = value;
setAudioParam(this.oscNode["frequency"], value, ramp, time);
break;
case 8: // feedback
this.params[3] = value / 100;
setAudioParam(this.feedbackNode["gain"], value / 100, ramp, time);
break;
}
};
function PhaserEffect(freq, detune, q, modulation, modfreq, mix)
{
this.type = "phaser";
this.params = [freq, detune, q, modulation, modfreq, mix];
this.inputNode = createGain();
this.dryNode = createGain();
this.dryNode["gain"]["value"] = 1 - (mix / 2);
this.wetNode = createGain();
this.wetNode["gain"]["value"] = mix / 2;
this.filterNode = context["createBiquadFilter"]();
if (typeof this.filterNode["type"] === "number")
this.filterNode["type"] = 7; // all-pass
else
this.filterNode["type"] = "allpass";
this.filterNode["frequency"]["value"] = freq;
if (this.filterNode["detune"]) // iOS 6 doesn't have detune yet
this.filterNode["detune"]["value"] = detune;
this.filterNode["Q"]["value"] = q;
this.oscNode = context["createOscillator"]();
this.oscNode["frequency"]["value"] = modfreq;
this.oscGainNode = createGain();
this.oscGainNode["gain"]["value"] = modulation;
this.inputNode["connect"](this.filterNode);
this.inputNode["connect"](this.dryNode);
this.filterNode["connect"](this.wetNode);
this.oscNode["connect"](this.oscGainNode);
this.oscGainNode["connect"](this.filterNode["frequency"]);
startSource(this.oscNode);
};
PhaserEffect.prototype.connectTo = function (node)
{
this.dryNode["disconnect"]();
this.dryNode["connect"](node);
this.wetNode["disconnect"]();
this.wetNode["connect"](node);
};
PhaserEffect.prototype.remove = function ()
{
this.inputNode["disconnect"]();
this.filterNode["disconnect"]();
this.oscNode["disconnect"]();
this.oscGainNode["disconnect"]();
this.dryNode["disconnect"]();
this.wetNode["disconnect"]();
};
PhaserEffect.prototype.getInputNode = function ()
{
return this.inputNode;
};
PhaserEffect.prototype.setParam = function(param, value, ramp, time)
{
switch (param) {
case 0: // mix
value = value / 100;
if (value < 0) value = 0;
if (value > 1) value = 1;
this.params[5] = value;
setAudioParam(this.wetNode["gain"], value / 2, ramp, time);
setAudioParam(this.dryNode["gain"], 1 - (value / 2), ramp, time);
break;
case 1: // filter frequency
this.params[0] = value;
setAudioParam(this.filterNode["frequency"], value, ramp, time);
break;
case 2: // filter detune
this.params[1] = value;
setAudioParam(this.filterNode["detune"], value, ramp, time);
break;
case 3: // filter Q
this.params[2] = value;
setAudioParam(this.filterNode["Q"], value, ramp, time);
break;
case 6: // modulation
this.params[3] = value;
setAudioParam(this.oscGainNode["gain"], value, ramp, time);
break;
case 7: // modulation frequency
this.params[4] = value;
setAudioParam(this.oscNode["frequency"], value, ramp, time);
break;
}
};
function GainEffect(g)
{
this.type = "gain";
this.params = [g];
this.node = createGain();
this.node["gain"]["value"] = g;
};
GainEffect.prototype.connectTo = function (node_)
{
this.node["disconnect"]();
this.node["connect"](node_);
};
GainEffect.prototype.remove = function ()
{
this.node["disconnect"]();
};
GainEffect.prototype.getInputNode = function ()
{
return this.node;
};
GainEffect.prototype.setParam = function(param, value, ramp, time)
{
switch (param) {
case 4: // gain
this.params[0] = dbToLinear(value);
setAudioParam(this.node["gain"], dbToLinear(value), ramp, time);
break;
}
};
function TremoloEffect(freq, mix)
{
this.type = "tremolo";
this.params = [freq, mix];
this.node = createGain();
this.node["gain"]["value"] = 1 - (mix / 2);
this.oscNode = context["createOscillator"]();
this.oscNode["frequency"]["value"] = freq;
this.oscGainNode = createGain();
this.oscGainNode["gain"]["value"] = mix / 2;
this.oscNode["connect"](this.oscGainNode);
this.oscGainNode["connect"](this.node["gain"]);
startSource(this.oscNode);
};
TremoloEffect.prototype.connectTo = function (node_)
{
this.node["disconnect"]();
this.node["connect"](node_);
};
TremoloEffect.prototype.remove = function ()
{
this.oscNode["disconnect"]();
this.oscGainNode["disconnect"]();
this.node["disconnect"]();
};
TremoloEffect.prototype.getInputNode = function ()
{
return this.node;
};
TremoloEffect.prototype.setParam = function(param, value, ramp, time)
{
switch (param) {
case 0: // mix
value = value / 100;
if (value < 0) value = 0;
if (value > 1) value = 1;
this.params[1] = value;
setAudioParam(this.node["gain"]["value"], 1 - (value / 2), ramp, time);
setAudioParam(this.oscGainNode["gain"]["value"], value / 2, ramp, time);
break;
case 7: // modulation frequency
this.params[0] = value;
setAudioParam(this.oscNode["frequency"], value, ramp, time);
break;
}
};
function RingModulatorEffect(freq, mix)
{
this.type = "ringmod";
this.params = [freq, mix];
this.inputNode = createGain();
this.wetNode = createGain();
this.wetNode["gain"]["value"] = mix;
this.dryNode = createGain();
this.dryNode["gain"]["value"] = 1 - mix;
this.ringNode = createGain();
this.ringNode["gain"]["value"] = 0;
this.oscNode = context["createOscillator"]();
this.oscNode["frequency"]["value"] = freq;
this.oscNode["connect"](this.ringNode["gain"]);
startSource(this.oscNode);
this.inputNode["connect"](this.ringNode);
this.inputNode["connect"](this.dryNode);
this.ringNode["connect"](this.wetNode);
};
RingModulatorEffect.prototype.connectTo = function (node_)
{
this.wetNode["disconnect"]();
this.wetNode["connect"](node_);
this.dryNode["disconnect"]();
this.dryNode["connect"](node_);
};
RingModulatorEffect.prototype.remove = function ()
{
this.oscNode["disconnect"]();
this.ringNode["disconnect"]();
this.inputNode["disconnect"]();
this.wetNode["disconnect"]();
this.dryNode["disconnect"]();
};
RingModulatorEffect.prototype.getInputNode = function ()
{
return this.inputNode;
};
RingModulatorEffect.prototype.setParam = function(param, value, ramp, time)
{
switch (param) {
case 0: // mix
value = value / 100;
if (value < 0) value = 0;
if (value > 1) value = 1;
this.params[1] = value;
setAudioParam(this.wetNode["gain"], value, ramp, time);
setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
break;
case 7: // modulation frequency
this.params[0] = value;
setAudioParam(this.oscNode["frequency"], value, ramp, time);
break;
}
};
function DistortionEffect(threshold, headroom, drive, makeupgain, mix)
{
this.type = "distortion";
this.params = [threshold, headroom, drive, makeupgain, mix];
this.inputNode = createGain();
this.preGain = createGain();
this.postGain = createGain();
this.setDrive(drive, dbToLinear_nocap(makeupgain));
this.wetNode = createGain();
this.wetNode["gain"]["value"] = mix;
this.dryNode = createGain();
this.dryNode["gain"]["value"] = 1 - mix;
this.waveShaper = context["createWaveShaper"]();
this.curve = new Float32Array(65536);
this.generateColortouchCurve(threshold, headroom);
this.waveShaper.curve = this.curve;
this.inputNode["connect"](this.preGain);
this.inputNode["connect"](this.dryNode);
this.preGain["connect"](this.waveShaper);
this.waveShaper["connect"](this.postGain);
this.postGain["connect"](this.wetNode);
};
DistortionEffect.prototype.setDrive = function (drive, makeupgain)
{
if (drive < 0.01)
drive = 0.01;
this.preGain["gain"]["value"] = drive;
this.postGain["gain"]["value"] = Math.pow(1 / drive, 0.6) * makeupgain;
};
function e4(x, k)
{
return 1.0 - Math.exp(-k * x);
}
DistortionEffect.prototype.shape = function (x, linearThreshold, linearHeadroom)
{
var maximum = 1.05 * linearHeadroom * linearThreshold;
var kk = (maximum - linearThreshold);
var sign = x < 0 ? -1 : +1;
var absx = x < 0 ? -x : x;
var shapedInput = absx < linearThreshold ? absx : linearThreshold + kk * e4(absx - linearThreshold, 1.0 / kk);
shapedInput *= sign;
return shapedInput;
};
DistortionEffect.prototype.generateColortouchCurve = function (threshold, headroom)
{
var linearThreshold = dbToLinear_nocap(threshold);
var linearHeadroom = dbToLinear_nocap(headroom);
var n = 65536;
var n2 = n / 2;
var x = 0;
for (var i = 0; i < n2; ++i) {
x = i / n2;
x = this.shape(x, linearThreshold, linearHeadroom);
this.curve[n2 + i] = x;
this.curve[n2 - i - 1] = -x;
}
};
DistortionEffect.prototype.connectTo = function (node)
{
this.wetNode["disconnect"]();
this.wetNode["connect"](node);
this.dryNode["disconnect"]();
this.dryNode["connect"](node);
};
DistortionEffect.prototype.remove = function ()
{
this.inputNode["disconnect"]();
this.preGain["disconnect"]();
this.waveShaper["disconnect"]();
this.postGain["disconnect"]();
this.wetNode["disconnect"]();
this.dryNode["disconnect"]();
};
DistortionEffect.prototype.getInputNode = function ()
{
return this.inputNode;
};
DistortionEffect.prototype.setParam = function(param, value, ramp, time)
{
switch (param) {
case 0: // mix
value = value / 100;
if (value < 0) value = 0;
if (value > 1) value = 1;
this.params[4] = value;
setAudioParam(this.wetNode["gain"], value, ramp, time);
setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
break;
}
};
function CompressorEffect(threshold, knee, ratio, attack, release)
{
this.type = "compressor";
this.params = [threshold, knee, ratio, attack, release];
this.node = context["createDynamicsCompressor"]();
try {
this.node["threshold"]["value"] = threshold;
this.node["knee"]["value"] = knee;
this.node["ratio"]["value"] = ratio;
this.node["attack"]["value"] = attack;
this.node["release"]["value"] = release;
}
catch (e) {}
};
CompressorEffect.prototype.connectTo = function (node_)
{
this.node["disconnect"]();
this.node["connect"](node_);
};
CompressorEffect.prototype.remove = function ()
{
this.node["disconnect"]();
};
CompressorEffect.prototype.getInputNode = function ()
{
return this.node;
};
CompressorEffect.prototype.setParam = function(param, value, ramp, time)
{
};
function AnalyserEffect(fftSize, smoothing)
{
this.type = "analyser";
this.params = [fftSize, smoothing];
this.node = context["createAnalyser"]();
this.node["fftSize"] = fftSize;
this.node["smoothingTimeConstant"] = smoothing;
this.freqBins = new Float32Array(this.node["frequencyBinCount"]);
this.signal = new Uint8Array(fftSize);
this.peak = 0;
this.rms = 0;
};
AnalyserEffect.prototype.tick = function ()
{
this.node["getFloatFrequencyData"](this.freqBins);
this.node["getByteTimeDomainData"](this.signal);
var fftSize = this.node["fftSize"];
var i = 0;
this.peak = 0;
var rmsSquaredSum = 0;
var s = 0;
for ( ; i < fftSize; i++)
{
s = (this.signal[i] - 128) / 128;
if (s < 0)
s = -s;
if (this.peak < s)
this.peak = s;
rmsSquaredSum += s * s;
}
this.peak = linearToDb(this.peak);
this.rms = linearToDb(Math.sqrt(rmsSquaredSum / fftSize));
};
AnalyserEffect.prototype.connectTo = function (node_)
{
this.node["disconnect"]();
this.node["connect"](node_);
};
AnalyserEffect.prototype.remove = function ()
{
this.node["disconnect"]();
};
AnalyserEffect.prototype.getInputNode = function ()
{
return this.node;
};
AnalyserEffect.prototype.setParam = function(param, value, ramp, time)
{
};
function ObjectTracker()
{
this.obj = null;
this.loadUid = 0;
};
ObjectTracker.prototype.setObject = function (obj_)
{
this.obj = obj_;
};
ObjectTracker.prototype.hasObject = function ()
{
return !!this.obj;
};
ObjectTracker.prototype.tick = function (dt)
{
};
function C2AudioBuffer(src_, is_music)
{
this.src = src_;
this.myapi = api;
this.is_music = is_music;
this.added_end_listener = false;
var self = this;
this.outNode = null;
this.mediaSourceNode = null;
this.panWhenReady = []; // for web audio API positioned sounds
this.seekWhenReady = 0;
this.pauseWhenReady = false;
this.supportWebAudioAPI = false;
this.failedToLoad = false;
this.wasEverReady = false; // if a buffer is ever marked as ready, it's permanently considered ready after then.
if (api === API_WEBAUDIO && is_music && !playMusicAsSoundWorkaround)
{
this.myapi = API_HTML5;
this.outNode = createGain();
}
this.bufferObject = null; // actual audio object
this.audioData = null; // web audio api: ajax request result (compressed audio that needs decoding)
var request;
switch (this.myapi) {
case API_HTML5:
this.bufferObject = new Audio();
this.bufferObject.crossOrigin = "anonymous";
this.bufferObject.addEventListener("canplaythrough", function () {
self.wasEverReady = true; // update loaded state so preload is considered complete
});
if (api === API_WEBAUDIO && context["createMediaElementSource"] && !/wiiu/i.test(navigator.userAgent))
{
this.supportWebAudioAPI = true; // can be routed through web audio api
this.bufferObject.addEventListener("canplay", function ()
{
if (!self.mediaSourceNode && self.bufferObject)
{
self.mediaSourceNode = context["createMediaElementSource"](self.bufferObject);
self.mediaSourceNode["connect"](self.outNode);
}
});
}
this.bufferObject.autoplay = false; // this is only a source buffer, not an instance
this.bufferObject.preload = "auto";
this.bufferObject.src = src_;
break;
case API_WEBAUDIO:
if (audRuntime.isWKWebView)
{
audRuntime.fetchLocalFileViaCordovaAsArrayBuffer(src_, function (arrayBuffer)
{
self.audioData = arrayBuffer;
self.decodeAudioBuffer();
}, function (err)
{
self.failedToLoad = true;
});
}
else
{
request = new XMLHttpRequest();
request.open("GET", src_, true);
request.responseType = "arraybuffer";
request.onload = function () {
self.audioData = request.response;
self.decodeAudioBuffer();
};
request.onerror = function () {
self.failedToLoad = true;
};
request.send();
}
break;
case API_CORDOVA:
this.bufferObject = true;
break;
case API_APPMOBI:
this.bufferObject = true;
break;
}
};
C2AudioBuffer.prototype.release = function ()
{
var i, len, j, a;
for (i = 0, j = 0, len = audioInstances.length; i < len; ++i)
{
a = audioInstances[i];
audioInstances[j] = a;
if (a.buffer === this)
a.stop();
else
++j; // keep
}
audioInstances.length = j;
if (this.mediaSourceNode)
{
this.mediaSourceNode["disconnect"]();
this.mediaSourceNode = null;
}
if (this.outNode)
{
this.outNode["disconnect"]();
this.outNode = null;
}
this.bufferObject = null;
this.audioData = null;
};
C2AudioBuffer.prototype.decodeAudioBuffer = function ()
{
if (this.bufferObject || !this.audioData)
return; // audio already decoded or AJAX request not yet complete
var self = this;
if (context["decodeAudioData"])
{
context["decodeAudioData"](this.audioData, function (buffer) {
self.bufferObject = buffer;
self.audioData = null; // clear AJAX response to allow GC and save memory, only need the bufferObject now
var p, i, len, a;
if (!cr.is_undefined(self.playTagWhenReady) && !silent)
{
if (self.panWhenReady.length)
{
for (i = 0, len = self.panWhenReady.length; i < len; i++)
{
p = self.panWhenReady[i];
a = new C2AudioInstance(self, p.thistag);
a.setPannerEnabled(true);
if (typeof p.objUid !== "undefined")
{
p.obj = audRuntime.getObjectByUID(p.objUid);
if (!p.obj)
continue;
}
if (p.obj)
{
var px = cr.rotatePtAround(p.obj.x, p.obj.y, -p.obj.layer.getAngle(), listenerX, listenerY, true);
var py = cr.rotatePtAround(p.obj.x, p.obj.y, -p.obj.layer.getAngle(), listenerX, listenerY, false);
a.setPan(px, py, cr.to_degrees(p.obj.angle - p.obj.layer.getAngle()), p.ia, p.oa, p.og);
a.setObject(p.obj);
}
else
{
a.setPan(p.x, p.y, p.a, p.ia, p.oa, p.og);
}
a.play(self.loopWhenReady, self.volumeWhenReady, self.seekWhenReady);
if (self.pauseWhenReady)
a.pause();
audioInstances.push(a);
}
cr.clearArray(self.panWhenReady);
}
else
{
a = new C2AudioInstance(self, self.playTagWhenReady || ""); // sometimes playTagWhenReady is not set - TODO: why?
a.play(self.loopWhenReady, self.volumeWhenReady, self.seekWhenReady);
if (self.pauseWhenReady)
a.pause();
audioInstances.push(a);
}
}
else if (!cr.is_undefined(self.convolveWhenReady))
{
var convolveNode = self.convolveWhenReady.convolveNode;
convolveNode["normalize"] = self.normalizeWhenReady;
convolveNode["buffer"] = buffer;
}
}, function (e) {
self.failedToLoad = true;
});
}
else
{
this.bufferObject = context["createBuffer"](this.audioData, false);
this.audioData = null; // clear AJAX response to allow GC and save memory, only need the bufferObject now
if (!cr.is_undefined(this.playTagWhenReady) && !silent)
{
var a = new C2AudioInstance(this, this.playTagWhenReady);
a.play(this.loopWhenReady, this.volumeWhenReady, this.seekWhenReady);
if (this.pauseWhenReady)
a.pause();
audioInstances.push(a);
}
else if (!cr.is_undefined(this.convolveWhenReady))
{
var convolveNode = this.convolveWhenReady.convolveNode;
convolveNode["normalize"] = this.normalizeWhenReady;
convolveNode["buffer"] = this.bufferObject;
}
}
};
C2AudioBuffer.prototype.isLoaded = function ()
{
switch (this.myapi) {
case API_HTML5:
var ret = this.bufferObject["readyState"] >= 4; // HAVE_ENOUGH_DATA
if (ret)
this.wasEverReady = true;
return ret || this.wasEverReady;
case API_WEBAUDIO:
return !!this.audioData || !!this.bufferObject;
case API_CORDOVA:
return true;
case API_APPMOBI:
return true;
}
return false;
};
C2AudioBuffer.prototype.isLoadedAndDecoded = function ()
{
switch (this.myapi) {
case API_HTML5:
return this.isLoaded(); // no distinction between loaded and decoded in HTML5 audio, just rely on ready state
case API_WEBAUDIO:
return !!this.bufferObject;
case API_CORDOVA:
return true;
case API_APPMOBI:
return true;
}
return false;
};
C2AudioBuffer.prototype.hasFailedToLoad = function ()
{
switch (this.myapi) {
case API_HTML5:
return !!this.bufferObject["error"];
case API_WEBAUDIO:
return this.failedToLoad;
}
return false;
};
function C2AudioInstance(buffer_, tag_)
{
var self = this;
this.tag = tag_;
this.fresh = true;
this.stopped = true;
this.src = buffer_.src;
this.buffer = buffer_;
this.myapi = api;
this.is_music = buffer_.is_music;
this.playbackRate = 1;
this.hasPlaybackEnded = true; // ended flag
this.resume_me = false; // make sure resumes when leaving suspend
this.is_paused = false;
this.resume_position = 0; // for web audio api to resume from correct playback position
this.looping = false;
this.is_muted = false;
this.is_silent = false;
this.volume = 1;
this.onended_handler = function (e)
{
if (self.is_paused || self.resume_me)
return;
var bufferThatEnded = this;
if (!bufferThatEnded)
bufferThatEnded = e.target;
if (bufferThatEnded !== self.active_buffer)
return;
self.hasPlaybackEnded = true;
self.stopped = true;
audTag = self.tag;
audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
};
this.active_buffer = null;
this.isTimescaled = ((timescale_mode === 1 && !this.is_music) || timescale_mode === 2);
this.mutevol = 1;
this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum);
this.gainNode = null;
this.pannerNode = null;
this.pannerEnabled = false;
this.objectTracker = null;
this.panX = 0;
this.panY = 0;
this.panAngle = 0;
this.panConeInner = 0;
this.panConeOuter = 0;
this.panConeOuterGain = 0;
this.instanceObject = null;
var add_end_listener = false;
if (this.myapi === API_WEBAUDIO && this.buffer.myapi === API_HTML5 && !this.buffer.supportWebAudioAPI)
this.myapi = API_HTML5;
switch (this.myapi) {
case API_HTML5:
if (this.is_music)
{
this.instanceObject = buffer_.bufferObject;
add_end_listener = !buffer_.added_end_listener;
buffer_.added_end_listener = true;
}
else
{
this.instanceObject = new Audio();
this.instanceObject.crossOrigin = "anonymous";
this.instanceObject.autoplay = false;
this.instanceObject.src = buffer_.bufferObject.src;
add_end_listener = true;
}
if (add_end_listener)
{
this.instanceObject.addEventListener('ended', function () {
audTag = self.tag;
self.stopped = true;
audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
});
}
break;
case API_WEBAUDIO:
this.gainNode = createGain();
this.gainNode["connect"](getDestinationForTag(tag_));
if (this.buffer.myapi === API_WEBAUDIO)
{
if (buffer_.bufferObject)
{
this.instanceObject = context["createBufferSource"]();
this.instanceObject["buffer"] = buffer_.bufferObject;
this.instanceObject["connect"](this.gainNode);
}
}
else
{
this.instanceObject = this.buffer.bufferObject; // reference the audio element
this.buffer.outNode["connect"](this.gainNode);
if (!this.buffer.added_end_listener)
{
this.buffer.added_end_listener = true;
this.buffer.bufferObject.addEventListener('ended', function () {
audTag = self.tag;
self.stopped = true;
audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
});
}
}
break;
case API_CORDOVA:
this.instanceObject = new window["Media"](appPath + this.src, null, null, function (status) {
if (status === window["Media"]["MEDIA_STOPPED"])
{
self.hasPlaybackEnded = true;
self.stopped = true;
audTag = self.tag;
audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
}
});
break;
case API_APPMOBI:
this.instanceObject = true;
break;
}
};
C2AudioInstance.prototype.hasEnded = function ()
{
var time;
switch (this.myapi) {
case API_HTML5:
return this.instanceObject.ended;
case API_WEBAUDIO:
if (this.buffer.myapi === API_WEBAUDIO)
{
if (!this.fresh && !this.stopped && this.instanceObject["loop"])
return false;
if (this.is_paused)
return false;
return this.hasPlaybackEnded;
}
else
return this.instanceObject.ended;
case API_CORDOVA:
return this.hasPlaybackEnded;
case API_APPMOBI:
true; // recycling an AppMobi sound does not matter because it will just do another throwaway playSound
}
return true;
};
C2AudioInstance.prototype.canBeRecycled = function ()
{
if (this.fresh || this.stopped)
return true; // not yet used or is not playing
return this.hasEnded();
};
C2AudioInstance.prototype.setPannerEnabled = function (enable_)
{
if (api !== API_WEBAUDIO)
return;
if (!this.pannerEnabled && enable_)
{
if (!this.gainNode)
return;
if (!this.pannerNode)
{
this.pannerNode = context["createPanner"]();
if (typeof this.pannerNode["panningModel"] === "number")
this.pannerNode["panningModel"] = panningModel;
else
this.pannerNode["panningModel"] = ["equalpower", "HRTF", "soundfield"][panningModel];
if (typeof this.pannerNode["distanceModel"] === "number")
this.pannerNode["distanceModel"] = distanceModel;
else
this.pannerNode["distanceModel"] = ["linear", "inverse", "exponential"][distanceModel];
this.pannerNode["refDistance"] = refDistance;
this.pannerNode["maxDistance"] = maxDistance;
this.pannerNode["rolloffFactor"] = rolloffFactor;
}
this.gainNode["disconnect"]();
this.gainNode["connect"](this.pannerNode);
this.pannerNode["connect"](getDestinationForTag(this.tag));
this.pannerEnabled = true;
}
else if (this.pannerEnabled && !enable_)
{
if (!this.gainNode)
return;
this.pannerNode["disconnect"]();
this.gainNode["disconnect"]();
this.gainNode["connect"](getDestinationForTag(this.tag));
this.pannerEnabled = false;
}
};
C2AudioInstance.prototype.setPan = function (x, y, angle, innerangle, outerangle, outergain)
{
if (!this.pannerEnabled || api !== API_WEBAUDIO)
return;
this.pannerNode["setPosition"](x, y, 0);
this.pannerNode["setOrientation"](Math.cos(cr.to_radians(angle)), Math.sin(cr.to_radians(angle)), 0);
this.pannerNode["coneInnerAngle"] = innerangle;
this.pannerNode["coneOuterAngle"] = outerangle;
this.pannerNode["coneOuterGain"] = outergain;
this.panX = x;
this.panY = y;
this.panAngle = angle;
this.panConeInner = innerangle;
this.panConeOuter = outerangle;
this.panConeOuterGain = outergain;
};
C2AudioInstance.prototype.setObject = function (o)
{
if (!this.pannerEnabled || api !== API_WEBAUDIO)
return;
if (!this.objectTracker)
this.objectTracker = new ObjectTracker();
this.objectTracker.setObject(o);
};
C2AudioInstance.prototype.tick = function (dt)
{
if (!this.pannerEnabled || api !== API_WEBAUDIO || !this.objectTracker || !this.objectTracker.hasObject() || !this.isPlaying())
{
return;
}
this.objectTracker.tick(dt);
var inst = this.objectTracker.obj;
var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
this.pannerNode["setPosition"](px, py, 0);
var a = 0;
if (typeof this.objectTracker.obj.angle !== "undefined")
{
a = inst.angle - inst.layer.getAngle();
this.pannerNode["setOrientation"](Math.cos(a), Math.sin(a), 0);
}
};
C2AudioInstance.prototype.play = function (looping, vol, fromPosition, scheduledTime)
{
var instobj = this.instanceObject;
this.looping = looping;
this.volume = vol;
var seekPos = fromPosition || 0;
scheduledTime = scheduledTime || 0;
switch (this.myapi) {
case API_HTML5:
if (instobj.playbackRate !== 1.0)
instobj.playbackRate = 1.0;
if (instobj.volume !== vol * masterVolume)
instobj.volume = vol * masterVolume;
if (instobj.loop !== looping)
instobj.loop = looping;
if (instobj.muted)
instobj.muted = false;
if (instobj.currentTime !== seekPos)
{
try {
instobj.currentTime = seekPos;
}
catch (err)
{
;
}
}
tryPlayAudioElement(this);
break;
case API_WEBAUDIO:
this.muted = false;
this.mutevol = 1;
if (this.buffer.myapi === API_WEBAUDIO)
{
this.gainNode["gain"]["value"] = vol * masterVolume;
if (!this.fresh)
{
this.instanceObject = context["createBufferSource"]();
this.instanceObject["buffer"] = this.buffer.bufferObject;
this.instanceObject["connect"](this.gainNode);
}
this.instanceObject["onended"] = this.onended_handler;
this.active_buffer = this.instanceObject;
this.instanceObject.loop = looping;
this.hasPlaybackEnded = false;
if (seekPos === 0)
startSource(this.instanceObject, scheduledTime);
else
startSourceAt(this.instanceObject, seekPos, this.getDuration(), scheduledTime);
}
else
{
if (instobj.playbackRate !== 1.0)
instobj.playbackRate = 1.0;
if (instobj.loop !== looping)
instobj.loop = looping;
instobj.volume = vol * masterVolume;
if (instobj.currentTime !== seekPos)
{
try {
instobj.currentTime = seekPos;
}
catch (err)
{
;
}
}
tryPlayAudioElement(this);
}
break;
case API_CORDOVA:
if ((!this.fresh && this.stopped) || seekPos !== 0)
instobj["seekTo"](seekPos);
instobj["play"]();
this.hasPlaybackEnded = false;
break;
case API_APPMOBI:
if (audRuntime.isDirectCanvas)
AppMobi["context"]["playSound"](this.src, looping);
else
AppMobi["player"]["playSound"](this.src, looping);
break;
}
this.playbackRate = 1;
this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - seekPos;
this.fresh = false;
this.stopped = false;
this.is_paused = false;
};
C2AudioInstance.prototype.stop = function ()
{
switch (this.myapi) {
case API_HTML5:
if (!this.instanceObject.paused)
this.instanceObject.pause();
break;
case API_WEBAUDIO:
if (this.buffer.myapi === API_WEBAUDIO)
stopSource(this.instanceObject);
else
{
if (!this.instanceObject.paused)
this.instanceObject.pause();
}
break;
case API_CORDOVA:
this.instanceObject["stop"]();
break;
case API_APPMOBI:
if (audRuntime.isDirectCanvas)
AppMobi["context"]["stopSound"](this.src);
break;
}
this.stopped = true;
this.is_paused = false;
};
C2AudioInstance.prototype.pause = function ()
{
if (this.fresh || this.stopped || this.hasEnded() || this.is_paused)
return;
switch (this.myapi) {
case API_HTML5:
if (!this.instanceObject.paused)
this.instanceObject.pause();
break;
case API_WEBAUDIO:
if (this.buffer.myapi === API_WEBAUDIO)
{
this.resume_position = this.getPlaybackTime(true);
if (this.looping)
this.resume_position = this.resume_position % this.getDuration();
this.is_paused = true;
stopSource(this.instanceObject);
}
else
{
if (!this.instanceObject.paused)
this.instanceObject.pause();
}
break;
case API_CORDOVA:
this.instanceObject["pause"]();
break;
case API_APPMOBI:
if (audRuntime.isDirectCanvas)
AppMobi["context"]["stopSound"](this.src);
break;
}
this.is_paused = true;
};
C2AudioInstance.prototype.resume = function ()
{
if (this.fresh || this.stopped || this.hasEnded() || !this.is_paused)
return;
switch (this.myapi) {
case API_HTML5:
tryPlayAudioElement(this);
break;
case API_WEBAUDIO:
if (this.buffer.myapi === API_WEBAUDIO)
{
this.instanceObject = context["createBufferSource"]();
this.instanceObject["buffer"] = this.buffer.bufferObject;
this.instanceObject["connect"](this.gainNode);
this.instanceObject["onended"] = this.onended_handler;
this.active_buffer = this.instanceObject;
this.instanceObject.loop = this.looping;
this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
this.updatePlaybackRate();
this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - (this.resume_position / (this.playbackRate || 0.001));
startSourceAt(this.instanceObject, this.resume_position, this.getDuration());
}
else
{
tryPlayAudioElement(this);
}
break;
case API_CORDOVA:
this.instanceObject["play"]();
break;
case API_APPMOBI:
if (audRuntime.isDirectCanvas)
AppMobi["context"]["resumeSound"](this.src);
break;
}
this.is_paused = false;
};
C2AudioInstance.prototype.seek = function (pos)
{
if (this.fresh || this.stopped || this.hasEnded())
return;
switch (this.myapi) {
case API_HTML5:
try {
this.instanceObject.currentTime = pos;
}
catch (e) {}
break;
case API_WEBAUDIO:
if (this.buffer.myapi === API_WEBAUDIO)
{
if (this.is_paused)
this.resume_position = pos;
else
{
this.pause();
this.resume_position = pos;
this.resume();
}
}
else
{
try {
this.instanceObject.currentTime = pos;
}
catch (e) {}
}
break;
case API_CORDOVA:
break;
case API_APPMOBI:
if (audRuntime.isDirectCanvas)
AppMobi["context"]["seekSound"](this.src, pos);
break;
}
};
C2AudioInstance.prototype.reconnect = function (toNode)
{
if (this.myapi !== API_WEBAUDIO)
return;
if (this.pannerEnabled)
{
this.pannerNode["disconnect"]();
this.pannerNode["connect"](toNode);
}
else
{
this.gainNode["disconnect"]();
this.gainNode["connect"](toNode);
}
};
C2AudioInstance.prototype.getDuration = function (applyPlaybackRate)
{
var ret = 0;
switch (this.myapi) {
case API_HTML5:
if (typeof this.instanceObject.duration !== "undefined")
ret = this.instanceObject.duration;
break;
case API_WEBAUDIO:
ret = this.buffer.bufferObject["duration"];
break;
case API_CORDOVA:
ret = this.instanceObject["getDuration"]();
break;
case API_APPMOBI:
if (audRuntime.isDirectCanvas)
ret = AppMobi["context"]["getDurationSound"](this.src);
break;
}
if (applyPlaybackRate)
ret /= (this.playbackRate || 0.001); // avoid divide-by-zero
return ret;
};
C2AudioInstance.prototype.getPlaybackTime = function (applyPlaybackRate)
{
var duration = this.getDuration();
var ret = 0;
switch (this.myapi) {
case API_HTML5:
if (typeof this.instanceObject.currentTime !== "undefined")
ret = this.instanceObject.currentTime;
break;
case API_WEBAUDIO:
if (this.buffer.myapi === API_WEBAUDIO)
{
if (this.is_paused)
return this.resume_position;
else
ret = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - this.startTime;
}
else if (typeof this.instanceObject.currentTime !== "undefined")
ret = this.instanceObject.currentTime;
break;
case API_CORDOVA:
break;
case API_APPMOBI:
if (audRuntime.isDirectCanvas)
ret = AppMobi["context"]["getPlaybackTimeSound"](this.src);
break;
}
if (applyPlaybackRate)
ret *= this.playbackRate;
if (!this.looping && ret > duration)
ret = duration;
return ret;
};
C2AudioInstance.prototype.isPlaying = function ()
{
return !this.is_paused && !this.fresh && !this.stopped && !this.hasEnded();
};
C2AudioInstance.prototype.shouldSave = function ()
{
return !this.fresh && !this.stopped && !this.hasEnded();
};
C2AudioInstance.prototype.setVolume = function (v)
{
this.volume = v;
this.updateVolume();
};
C2AudioInstance.prototype.updateVolume = function ()
{
var volToSet = this.volume * masterVolume;
if (!isFinite(volToSet))
volToSet = 0; // HTMLMediaElement throws if setting non-finite volume
switch (this.myapi) {
case API_HTML5:
if (typeof this.instanceObject.volume !== "undefined" && this.instanceObject.volume !== volToSet)
this.instanceObject.volume = volToSet;
break;
case API_WEBAUDIO:
if (this.buffer.myapi === API_WEBAUDIO)
{
this.gainNode["gain"]["value"] = volToSet * this.mutevol;
}
else
{
if (typeof this.instanceObject.volume !== "undefined" && this.instanceObject.volume !== volToSet)
this.instanceObject.volume = volToSet;
}
break;
case API_CORDOVA:
break;
case API_APPMOBI:
break;
}
};
C2AudioInstance.prototype.getVolume = function ()
{
return this.volume;
};
C2AudioInstance.prototype.doSetMuted = function (m)
{
switch (this.myapi) {
case API_HTML5:
if (this.instanceObject.muted !== !!m)
this.instanceObject.muted = !!m;
break;
case API_WEBAUDIO:
if (this.buffer.myapi === API_WEBAUDIO)
{
this.mutevol = (m ? 0 : 1);
this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
}
else
{
if (this.instanceObject.muted !== !!m)
this.instanceObject.muted = !!m;
}
break;
case API_CORDOVA:
break;
case API_APPMOBI:
break;
}
};
C2AudioInstance.prototype.setMuted = function (m)
{
this.is_muted = !!m;
this.doSetMuted(this.is_muted || this.is_silent);
};
C2AudioInstance.prototype.setSilent = function (m)
{
this.is_silent = !!m;
this.doSetMuted(this.is_muted || this.is_silent);
};
C2AudioInstance.prototype.setLooping = function (l)
{
this.looping = l;
switch (this.myapi) {
case API_HTML5:
if (this.instanceObject.loop !== !!l)
this.instanceObject.loop = !!l;
break;
case API_WEBAUDIO:
if (this.instanceObject.loop !== !!l)
this.instanceObject.loop = !!l;
break;
case API_CORDOVA:
break;
case API_APPMOBI:
if (audRuntime.isDirectCanvas)
AppMobi["context"]["setLoopingSound"](this.src, l);
break;
}
};
C2AudioInstance.prototype.setPlaybackRate = function (r)
{
this.playbackRate = r;
this.updatePlaybackRate();
};
C2AudioInstance.prototype.updatePlaybackRate = function ()
{
var r = this.playbackRate;
if (this.isTimescaled)
r *= audRuntime.timescale;
switch (this.myapi) {
case API_HTML5:
if (this.instanceObject.playbackRate !== r)
this.instanceObject.playbackRate = r;
break;
case API_WEBAUDIO:
if (this.buffer.myapi === API_WEBAUDIO)
{
if (this.instanceObject["playbackRate"]["value"] !== r)
this.instanceObject["playbackRate"]["value"] = r;
}
else
{
if (this.instanceObject.playbackRate !== r)
this.instanceObject.playbackRate = r;
}
break;
case API_CORDOVA:
break;
case API_APPMOBI:
break;
}
};
C2AudioInstance.prototype.setSuspended = function (s)
{
switch (this.myapi) {
case API_HTML5:
if (s)
{
if (this.isPlaying())
{
this.resume_me = true;
this.instanceObject["pause"]();
}
else
this.resume_me = false;
}
else
{
if (this.resume_me)
{
this.instanceObject["play"]();
this.resume_me = false;
}
}
break;
case API_WEBAUDIO:
if (s)
{
if (this.isPlaying())
{
this.resume_me = true;
if (this.buffer.myapi === API_WEBAUDIO)
{
this.resume_position = this.getPlaybackTime(true);
if (this.looping)
this.resume_position = this.resume_position % this.getDuration();
stopSource(this.instanceObject);
}
else
this.instanceObject["pause"]();
}
else
this.resume_me = false;
}
else
{
if (this.resume_me)
{
if (this.buffer.myapi === API_WEBAUDIO)
{
this.instanceObject = context["createBufferSource"]();
this.instanceObject["buffer"] = this.buffer.bufferObject;
this.instanceObject["connect"](this.gainNode);
this.instanceObject["onended"] = this.onended_handler;
this.active_buffer = this.instanceObject;
this.instanceObject.loop = this.looping;
this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
this.updatePlaybackRate();
this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - (this.resume_position / (this.playbackRate || 0.001));
startSourceAt(this.instanceObject, this.resume_position, this.getDuration());
}
else
{
this.instanceObject["play"]();
}
this.resume_me = false;
}
}
break;
case API_CORDOVA:
if (s)
{
if (this.isPlaying())
{
this.instanceObject["pause"]();
this.resume_me = true;
}
else
this.resume_me = false;
}
else
{
if (this.resume_me)
{
this.resume_me = false;
this.instanceObject["play"]();
}
}
break;
case API_APPMOBI:
break;
}
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
audRuntime = this.runtime;
audInst = this;
this.listenerTracker = null;
this.listenerZ = -600;
if (this.runtime.isWKWebView)
playMusicAsSoundWorkaround = true;
if ((this.runtime.isiOS || (this.runtime.isAndroid && (this.runtime.isChrome || this.runtime.isAndroidStockBrowser))) && !this.runtime.isCrosswalk && !this.runtime.isDomFree && !this.runtime.isAmazonWebApp && !playMusicAsSoundWorkaround)
{
useNextTouchWorkaround = true;
}
context = null;
if (typeof AudioContext !== "undefined")
{
api = API_WEBAUDIO;
context = new AudioContext();
}
else if (typeof webkitAudioContext !== "undefined")
{
api = API_WEBAUDIO;
context = new webkitAudioContext();
}
if (this.runtime.isiOS && context)
{
if (context.close)
context.close();
if (typeof AudioContext !== "undefined")
context = new AudioContext();
else if (typeof webkitAudioContext !== "undefined")
context = new webkitAudioContext();
}
if (api !== API_WEBAUDIO)
{
if (this.runtime.isCordova && typeof window["Media"] !== "undefined")
api = API_CORDOVA;
else if (this.runtime.isAppMobi)
api = API_APPMOBI;
}
if (api === API_CORDOVA)
{
appPath = location.href;
var i = appPath.lastIndexOf("/");
if (i > -1)
appPath = appPath.substr(0, i + 1);
appPath = appPath.replace("file://", "");
}
if (this.runtime.isSafari && this.runtime.isWindows && typeof Audio === "undefined")
{
alert("It looks like you're using Safari for Windows without Quicktime. Audio cannot be played until Quicktime is installed.");
this.runtime.DestroyInstance(this);
}
else
{
if (this.runtime.isDirectCanvas)
useOgg = this.runtime.isAndroid; // AAC on iOS, OGG on Android
else
{
try {
useOgg = !!(new Audio().canPlayType('audio/ogg; codecs="vorbis"')) &&
!this.runtime.isWindows10;
}
catch (e)
{
useOgg = false;
}
}
switch (api) {
case API_HTML5:
;
break;
case API_WEBAUDIO:
;
break;
case API_CORDOVA:
;
break;
case API_APPMOBI:
;
break;
default:
;
}
this.runtime.tickMe(this);
}
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function ()
{
this.runtime.audioInstance = this;
timescale_mode = this.properties[0]; // 0 = off, 1 = sounds only, 2 = all
this.saveload = this.properties[1]; // 0 = all, 1 = sounds only, 2 = music only, 3 = none
this.playinbackground = (this.properties[2] !== 0);
this.nextPlayTime = 0;
panningModel = this.properties[3]; // 0 = equalpower, 1 = hrtf, 3 = soundfield
distanceModel = this.properties[4]; // 0 = linear, 1 = inverse, 2 = exponential
this.listenerZ = -this.properties[5];
refDistance = this.properties[6];
maxDistance = this.properties[7];
rolloffFactor = this.properties[8];
this.listenerTracker = new ObjectTracker();
var draw_width = (this.runtime.draw_width || this.runtime.width);
var draw_height = (this.runtime.draw_height || this.runtime.height);
if (api === API_WEBAUDIO)
{
context["listener"]["setPosition"](draw_width / 2, draw_height / 2, this.listenerZ);
context["listener"]["setOrientation"](0, 0, 1, 0, -1, 0);
window["c2OnAudioMicStream"] = function (localMediaStream, tag)
{
if (micSource)
micSource["disconnect"]();
micTag = tag.toLowerCase();
micSource = context["createMediaStreamSource"](localMediaStream);
micSource["connect"](getDestinationForTag(micTag));
};
}
this.runtime.addSuspendCallback(function(s)
{
audInst.onSuspend(s);
});
var self = this;
this.runtime.addDestroyCallback(function (inst)
{
self.onInstanceDestroyed(inst);
});
};
instanceProto.onInstanceDestroyed = function (inst)
{
var i, len, a;
for (i = 0, len = audioInstances.length; i < len; i++)
{
a = audioInstances[i];
if (a.objectTracker)
{
if (a.objectTracker.obj === inst)
{
a.objectTracker.obj = null;
if (a.pannerEnabled && a.isPlaying() && a.looping)
a.stop();
}
}
}
if (this.listenerTracker.obj === inst)
this.listenerTracker.obj = null;
};
instanceProto.saveToJSON = function ()
{
var o = {
"silent": silent,
"masterVolume": masterVolume,
"listenerZ": this.listenerZ,
"listenerUid": this.listenerTracker.hasObject() ? this.listenerTracker.obj.uid : -1,
"playing": [],
"effects": {}
};
var playingarr = o["playing"];
var i, len, a, d, p, panobj, playbackTime;
for (i = 0, len = audioInstances.length; i < len; i++)
{
a = audioInstances[i];
if (!a.shouldSave())
continue; // no need to save stopped sounds
if (this.saveload === 3) // not saving/loading any sounds/music
continue;
if (a.is_music && this.saveload === 1) // not saving/loading music
continue;
if (!a.is_music && this.saveload === 2) // not saving/loading sound
continue;
playbackTime = a.getPlaybackTime();
if (a.looping)
playbackTime = playbackTime % a.getDuration();
d = {
"tag": a.tag,
"buffersrc": a.buffer.src,
"is_music": a.is_music,
"playbackTime": playbackTime,
"volume": a.volume,
"looping": a.looping,
"muted": a.is_muted,
"playbackRate": a.playbackRate,
"paused": a.is_paused,
"resume_position": a.resume_position
};
if (a.pannerEnabled)
{
d["pan"] = {};
panobj = d["pan"];
if (a.objectTracker && a.objectTracker.hasObject())
{
panobj["objUid"] = a.objectTracker.obj.uid;
}
else
{
panobj["x"] = a.panX;
panobj["y"] = a.panY;
panobj["a"] = a.panAngle;
}
panobj["ia"] = a.panConeInner;
panobj["oa"] = a.panConeOuter;
panobj["og"] = a.panConeOuterGain;
}
playingarr.push(d);
}
var fxobj = o["effects"];
var fxarr;
for (p in effects)
{
if (effects.hasOwnProperty(p))
{
fxarr = [];
for (i = 0, len = effects[p].length; i < len; i++)
{
fxarr.push({ "type": effects[p][i].type, "params": effects[p][i].params });
}
fxobj[p] = fxarr;
}
}
return o;
};
var objectTrackerUidsToLoad = [];
instanceProto.loadFromJSON = function (o)
{
var setSilent = o["silent"];
masterVolume = o["masterVolume"];
this.listenerZ = o["listenerZ"];
this.listenerTracker.setObject(null);
var listenerUid = o["listenerUid"];
if (listenerUid !== -1)
{
this.listenerTracker.loadUid = listenerUid;
objectTrackerUidsToLoad.push(this.listenerTracker);
}
var playingarr = o["playing"];
var i, len, d, src, is_music, tag, playbackTime, looping, vol, b, a, p, pan, panObjUid;
if (this.saveload !== 3)
{
for (i = 0, len = audioInstances.length; i < len; i++)
{
a = audioInstances[i];
if (a.is_music && this.saveload === 1)
continue; // only saving/loading sound: leave music playing
if (!a.is_music && this.saveload === 2)
continue; // only saving/loading music: leave sound playing
a.stop();
}
}
var fxarr, fxtype, fxparams, fx;
for (p in effects)
{
if (effects.hasOwnProperty(p))
{
for (i = 0, len = effects[p].length; i < len; i++)
effects[p][i].remove();
}
}
cr.wipe(effects);
for (p in o["effects"])
{
if (o["effects"].hasOwnProperty(p))
{
fxarr = o["effects"][p];
for (i = 0, len = fxarr.length; i < len; i++)
{
fxtype = fxarr[i]["type"];
fxparams = fxarr[i]["params"];
switch (fxtype) {
case "filter":
addEffectForTag(p, new FilterEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4], fxparams[5]));
break;
case "delay":
addEffectForTag(p, new DelayEffect(fxparams[0], fxparams[1], fxparams[2]));
break;
case "convolve":
src = fxparams[2];
b = this.getAudioBuffer(src, false);
if (b.bufferObject)
{
fx = new ConvolveEffect(b.bufferObject, fxparams[0], fxparams[1], src);
}
else
{
fx = new ConvolveEffect(null, fxparams[0], fxparams[1], src);
b.normalizeWhenReady = fxparams[0];
b.convolveWhenReady = fx;
}
addEffectForTag(p, fx);
break;
case "flanger":
addEffectForTag(p, new FlangerEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
break;
case "phaser":
addEffectForTag(p, new PhaserEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4], fxparams[5]));
break;
case "gain":
addEffectForTag(p, new GainEffect(fxparams[0]));
break;
case "tremolo":
addEffectForTag(p, new TremoloEffect(fxparams[0], fxparams[1]));
break;
case "ringmod":
addEffectForTag(p, new RingModulatorEffect(fxparams[0], fxparams[1]));
break;
case "distortion":
addEffectForTag(p, new DistortionEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
break;
case "compressor":
addEffectForTag(p, new CompressorEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
break;
case "analyser":
addEffectForTag(p, new AnalyserEffect(fxparams[0], fxparams[1]));
break;
}
}
}
}
for (i = 0, len = playingarr.length; i < len; i++)
{
if (this.saveload === 3) // not saving/loading any sounds/music
continue;
d = playingarr[i];
src = d["buffersrc"];
is_music = d["is_music"];
tag = d["tag"];
playbackTime = d["playbackTime"];
looping = d["looping"];
vol = d["volume"];
pan = d["pan"];
panObjUid = (pan && pan.hasOwnProperty("objUid")) ? pan["objUid"] : -1;
if (is_music && this.saveload === 1) // not saving/loading music
continue;
if (!is_music && this.saveload === 2) // not saving/loading sound
continue;
a = this.getAudioInstance(src, tag, is_music, looping, vol);
if (!a)
{
b = this.getAudioBuffer(src, is_music);
b.seekWhenReady = playbackTime;
b.pauseWhenReady = d["paused"];
if (pan)
{
if (panObjUid !== -1)
{
b.panWhenReady.push({ objUid: panObjUid, ia: pan["ia"], oa: pan["oa"], og: pan["og"], thistag: tag });
}
else
{
b.panWhenReady.push({ x: pan["x"], y: pan["y"], a: pan["a"], ia: pan["ia"], oa: pan["oa"], og: pan["og"], thistag: tag });
}
}
continue;
}
a.resume_position = d["resume_position"];
a.setPannerEnabled(!!pan);
a.play(looping, vol, playbackTime);
a.updatePlaybackRate();
a.updateVolume();
a.doSetMuted(a.is_muted || a.is_silent);
if (d["paused"])
a.pause();
if (d["muted"])
a.setMuted(true);
a.doSetMuted(a.is_muted || a.is_silent);
if (pan)
{
if (panObjUid !== -1)
{
a.objectTracker = a.objectTracker || new ObjectTracker();
a.objectTracker.loadUid = panObjUid;
objectTrackerUidsToLoad.push(a.objectTracker);
}
else
{
a.setPan(pan["x"], pan["y"], pan["a"], pan["ia"], pan["oa"], pan["og"]);
}
}
}
if (setSilent && !silent) // setting silent
{
for (i = 0, len = audioInstances.length; i < len; i++)
audioInstances[i].setSilent(true);
silent = true;
}
else if (!setSilent && silent) // setting not silent
{
for (i = 0, len = audioInstances.length; i < len; i++)
audioInstances[i].setSilent(false);
silent = false;
}
};
instanceProto.afterLoad = function ()
{
var i, len, ot, inst;
for (i = 0, len = objectTrackerUidsToLoad.length; i < len; i++)
{
ot = objectTrackerUidsToLoad[i];
inst = this.runtime.getObjectByUID(ot.loadUid);
ot.setObject(inst);
ot.loadUid = -1;
if (inst)
{
listenerX = inst.x;
listenerY = inst.y;
}
}
cr.clearArray(objectTrackerUidsToLoad);
};
instanceProto.onSuspend = function (s)
{
if (this.playinbackground)
return;
if (!s && context && context["resume"])
{
context["resume"]();
isContextSuspended = false;
}
var i, len;
for (i = 0, len = audioInstances.length; i < len; i++)
audioInstances[i].setSuspended(s);
if (s && context && context["suspend"])
{
context["suspend"]();
isContextSuspended = true;
}
};
instanceProto.tick = function ()
{
var dt = this.runtime.dt;
var i, len, a;
for (i = 0, len = audioInstances.length; i < len; i++)
{
a = audioInstances[i];
a.tick(dt);
if (timescale_mode !== 0)
a.updatePlaybackRate();
}
var p, arr, f;
for (p in effects)
{
if (effects.hasOwnProperty(p))
{
arr = effects[p];
for (i = 0, len = arr.length; i < len; i++)
{
f = arr[i];
if (f.tick)
f.tick();
}
}
}
if (api === API_WEBAUDIO && this.listenerTracker.hasObject())
{
this.listenerTracker.tick(dt);
listenerX = this.listenerTracker.obj.x;
listenerY = this.listenerTracker.obj.y;
context["listener"]["setPosition"](this.listenerTracker.obj.x, this.listenerTracker.obj.y, this.listenerZ);
}
};
var preload_list = [];
instanceProto.setPreloadList = function (arr)
{
var i, len, p, filename, size, isOgg;
var total_size = 0;
for (i = 0, len = arr.length; i < len; ++i)
{
p = arr[i];
filename = p[0];
size = p[1] * 2;
isOgg = (filename.length > 4 && filename.substr(filename.length - 4) === ".ogg");
if ((isOgg && useOgg) || (!isOgg && !useOgg))
{
preload_list.push({
filename: filename,
size: size,
obj: null
});
total_size += size;
}
}
return total_size;
};
instanceProto.startPreloads = function ()
{
var i, len, p, src;
for (i = 0, len = preload_list.length; i < len; ++i)
{
p = preload_list[i];
src = this.runtime.files_subfolder + p.filename;
p.obj = this.getAudioBuffer(src, false);
}
};
instanceProto.getPreloadedSize = function ()
{
var completed = 0;
var i, len, p;
for (i = 0, len = preload_list.length; i < len; ++i)
{
p = preload_list[i];
if (p.obj.isLoadedAndDecoded() || p.obj.hasFailedToLoad() || this.runtime.isDomFree || this.runtime.isAndroidStockBrowser)
{
completed += p.size;
}
else if (p.obj.isLoaded()) // downloaded but not decoded: only happens in Web Audio API, count as half-way progress
{
completed += Math.floor(p.size / 2);
}
};
return completed;
};
instanceProto.releaseAllMusicBuffers = function ()
{
var i, len, j, b;
for (i = 0, j = 0, len = audioBuffers.length; i < len; ++i)
{
b = audioBuffers[i];
audioBuffers[j] = b;
if (b.is_music)
b.release();
else
++j; // keep
}
audioBuffers.length = j;
};
instanceProto.getAudioBuffer = function (src_, is_music, dont_create)
{
var i, len, a, ret = null, j, k, lenj, ai;
for (i = 0, len = audioBuffers.length; i < len; i++)
{
a = audioBuffers[i];
if (a.src === src_)
{
ret = a;
break;
}
}
if (!ret && !dont_create)
{
if (playMusicAsSoundWorkaround && is_music)
this.releaseAllMusicBuffers();
ret = new C2AudioBuffer(src_, is_music);
audioBuffers.push(ret);
}
return ret;
};
instanceProto.getAudioInstance = function (src_, tag, is_music, looping, vol)
{
var i, len, a;
for (i = 0, len = audioInstances.length; i < len; i++)
{
a = audioInstances[i];
if (a.src === src_ && (a.canBeRecycled() || is_music))
{
a.tag = tag;
return a;
}
}
var b = this.getAudioBuffer(src_, is_music);
if (!b.bufferObject)
{
if (tag !== "<preload>")
{
b.playTagWhenReady = tag;
b.loopWhenReady = looping;
b.volumeWhenReady = vol;
}
return null;
}
a = new C2AudioInstance(b, tag);
audioInstances.push(a);
return a;
};
var taggedAudio = [];
function SortByIsPlaying(a, b)
{
var an = a.isPlaying() ? 1 : 0;
var bn = b.isPlaying() ? 1 : 0;
if (an === bn)
return 0;
else if (an < bn)
return 1;
else
return -1;
};
function getAudioByTag(tag, sort_by_playing)
{
cr.clearArray(taggedAudio);
if (!tag.length)
{
if (!lastAudio || lastAudio.hasEnded())
return;
else
{
cr.clearArray(taggedAudio);
taggedAudio[0] = lastAudio;
return;
}
}
var i, len, a;
for (i = 0, len = audioInstances.length; i < len; i++)
{
a = audioInstances[i];
if (cr.equals_nocase(tag, a.tag))
taggedAudio.push(a);
}
if (sort_by_playing)
taggedAudio.sort(SortByIsPlaying);
};
function reconnectEffects(tag)
{
var i, len, arr, n, toNode = context["destination"];
if (effects.hasOwnProperty(tag))
{
arr = effects[tag];
if (arr.length)
{
toNode = arr[0].getInputNode();
for (i = 0, len = arr.length; i < len; i++)
{
n = arr[i];
if (i + 1 === len)
n.connectTo(context["destination"]);
else
n.connectTo(arr[i + 1].getInputNode());
}
}
}
getAudioByTag(tag);
for (i = 0, len = taggedAudio.length; i < len; i++)
taggedAudio[i].reconnect(toNode);
if (micSource && micTag === tag)
{
micSource["disconnect"]();
micSource["connect"](toNode);
}
};
function addEffectForTag(tag, fx)
{
if (!effects.hasOwnProperty(tag))
effects[tag] = [fx];
else
effects[tag].push(fx);
reconnectEffects(tag);
};
function Cnds() {};
Cnds.prototype.OnEnded = function (t)
{
return cr.equals_nocase(audTag, t);
};
Cnds.prototype.PreloadsComplete = function ()
{
var i, len;
for (i = 0, len = audioBuffers.length; i < len; i++)
{
if (!audioBuffers[i].isLoadedAndDecoded() && !audioBuffers[i].hasFailedToLoad())
return false;
}
return true;
};
Cnds.prototype.AdvancedAudioSupported = function ()
{
return api === API_WEBAUDIO;
};
Cnds.prototype.IsSilent = function ()
{
return silent;
};
Cnds.prototype.IsAnyPlaying = function ()
{
var i, len;
for (i = 0, len = audioInstances.length; i < len; i++)
{
if (audioInstances[i].isPlaying())
return true;
}
return false;
};
Cnds.prototype.IsTagPlaying = function (tag)
{
getAudioByTag(tag);
var i, len;
for (i = 0, len = taggedAudio.length; i < len; i++)
{
if (taggedAudio[i].isPlaying())
return true;
}
return false;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.Play = function (file, looping, vol, tag)
{
if (silent)
return;
var v = dbToLinear(vol);
var is_music = file[1];
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
if (!lastAudio)
return;
lastAudio.setPannerEnabled(false);
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
this.nextPlayTime = 0;
};
Acts.prototype.PlayAtPosition = function (file, looping, vol, x_, y_, angle_, innerangle_, outerangle_, outergain_, tag)
{
if (silent)
return;
var v = dbToLinear(vol);
var is_music = file[1];
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
if (!lastAudio)
{
var b = this.getAudioBuffer(src, is_music);
b.panWhenReady.push({ x: x_, y: y_, a: angle_, ia: innerangle_, oa: outerangle_, og: dbToLinear(outergain_), thistag: tag });
return;
}
lastAudio.setPannerEnabled(true);
lastAudio.setPan(x_, y_, angle_, innerangle_, outerangle_, dbToLinear(outergain_));
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
this.nextPlayTime = 0;
};
Acts.prototype.PlayAtObject = function (file, looping, vol, obj, innerangle, outerangle, outergain, tag)
{
if (silent || !obj)
return;
var inst = obj.getFirstPicked();
if (!inst)
return;
var v = dbToLinear(vol);
var is_music = file[1];
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
if (!lastAudio)
{
var b = this.getAudioBuffer(src, is_music);
b.panWhenReady.push({ obj: inst, ia: innerangle, oa: outerangle, og: dbToLinear(outergain), thistag: tag });
return;
}
lastAudio.setPannerEnabled(true);
var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
lastAudio.setPan(px, py, cr.to_degrees(inst.angle - inst.layer.getAngle()), innerangle, outerangle, dbToLinear(outergain));
lastAudio.setObject(inst);
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
this.nextPlayTime = 0;
};
Acts.prototype.PlayByName = function (folder, filename, looping, vol, tag)
{
if (silent)
return;
var v = dbToLinear(vol);
var is_music = (folder === 1);
var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
if (!lastAudio)
return;
lastAudio.setPannerEnabled(false);
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
this.nextPlayTime = 0;
};
Acts.prototype.PlayAtPositionByName = function (folder, filename, looping, vol, x_, y_, angle_, innerangle_, outerangle_, outergain_, tag)
{
if (silent)
return;
var v = dbToLinear(vol);
var is_music = (folder === 1);
var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
if (!lastAudio)
{
var b = this.getAudioBuffer(src, is_music);
b.panWhenReady.push({ x: x_, y: y_, a: angle_, ia: innerangle_, oa: outerangle_, og: dbToLinear(outergain_), thistag: tag });
return;
}
lastAudio.setPannerEnabled(true);
lastAudio.setPan(x_, y_, angle_, innerangle_, outerangle_, dbToLinear(outergain_));
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
this.nextPlayTime = 0;
};
Acts.prototype.PlayAtObjectByName = function (folder, filename, looping, vol, obj, innerangle, outerangle, outergain, tag)
{
if (silent || !obj)
return;
var inst = obj.getFirstPicked();
if (!inst)
return;
var v = dbToLinear(vol);
var is_music = (folder === 1);
var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
if (!lastAudio)
{
var b = this.getAudioBuffer(src, is_music);
b.panWhenReady.push({ obj: inst, ia: innerangle, oa: outerangle, og: dbToLinear(outergain), thistag: tag });
return;
}
lastAudio.setPannerEnabled(true);
var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
lastAudio.setPan(px, py, cr.to_degrees(inst.angle - inst.layer.getAngle()), innerangle, outerangle, dbToLinear(outergain));
lastAudio.setObject(inst);
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
this.nextPlayTime = 0;
};
Acts.prototype.SetLooping = function (tag, looping)
{
getAudioByTag(tag);
var i, len;
for (i = 0, len = taggedAudio.length; i < len; i++)
taggedAudio[i].setLooping(looping === 0);
};
Acts.prototype.SetMuted = function (tag, muted)
{
getAudioByTag(tag);
var i, len;
for (i = 0, len = taggedAudio.length; i < len; i++)
taggedAudio[i].setMuted(muted === 0);
};
Acts.prototype.SetVolume = function (tag, vol)
{
getAudioByTag(tag);
var v = dbToLinear(vol);
var i, len;
for (i = 0, len = taggedAudio.length; i < len; i++)
taggedAudio[i].setVolume(v);
};
Acts.prototype.Preload = function (file)
{
if (silent)
return;
var is_music = file[1];
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
if (api === API_APPMOBI)
{
if (this.runtime.isDirectCanvas)
AppMobi["context"]["loadSound"](src);
else
AppMobi["player"]["loadSound"](src);
return;
}
else if (api === API_CORDOVA)
{
return;
}
this.getAudioInstance(src, "<preload>", is_music, false);
};
Acts.prototype.PreloadByName = function (folder, filename)
{
if (silent)
return;
var is_music = (folder === 1);
var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
if (api === API_APPMOBI)
{
if (this.runtime.isDirectCanvas)
AppMobi["context"]["loadSound"](src);
else
AppMobi["player"]["loadSound"](src);
return;
}
else if (api === API_CORDOVA)
{
return;
}
this.getAudioInstance(src, "<preload>", is_music, false);
};
Acts.prototype.SetPlaybackRate = function (tag, rate)
{
getAudioByTag(tag);
if (rate < 0.0)
rate = 0;
var i, len;
for (i = 0, len = taggedAudio.length; i < len; i++)
taggedAudio[i].setPlaybackRate(rate);
};
Acts.prototype.Stop = function (tag)
{
getAudioByTag(tag);
var i, len;
for (i = 0, len = taggedAudio.length; i < len; i++)
taggedAudio[i].stop();
};
Acts.prototype.StopAll = function ()
{
var i, len;
for (i = 0, len = audioInstances.length; i < len; i++)
audioInstances[i].stop();
};
Acts.prototype.SetPaused = function (tag, state)
{
getAudioByTag(tag);
var i, len;
for (i = 0, len = taggedAudio.length; i < len; i++)
{
if (state === 0)
taggedAudio[i].pause();
else
taggedAudio[i].resume();
}
};
Acts.prototype.Seek = function (tag, pos)
{
getAudioByTag(tag);
var i, len;
for (i = 0, len = taggedAudio.length; i < len; i++)
{
taggedAudio[i].seek(pos);
}
};
Acts.prototype.SetSilent = function (s)
{
var i, len;
if (s === 2) // toggling
s = (silent ? 1 : 0); // choose opposite state
if (s === 0 && !silent) // setting silent
{
for (i = 0, len = audioInstances.length; i < len; i++)
audioInstances[i].setSilent(true);
silent = true;
}
else if (s === 1 && silent) // setting not silent
{
for (i = 0, len = audioInstances.length; i < len; i++)
audioInstances[i].setSilent(false);
silent = false;
}
};
Acts.prototype.SetMasterVolume = function (vol)
{
masterVolume = dbToLinear(vol);
var i, len;
for (i = 0, len = audioInstances.length; i < len; i++)
audioInstances[i].updateVolume();
};
Acts.prototype.AddFilterEffect = function (tag, type, freq, detune, q, gain, mix)
{
if (api !== API_WEBAUDIO || type < 0 || type >= filterTypes.length || !context["createBiquadFilter"])
return;
tag = tag.toLowerCase();
mix = mix / 100;
if (mix < 0) mix = 0;
if (mix > 1) mix = 1;
addEffectForTag(tag, new FilterEffect(type, freq, detune, q, gain, mix));
};
Acts.prototype.AddDelayEffect = function (tag, delay, gain, mix)
{
if (api !== API_WEBAUDIO)
return;
tag = tag.toLowerCase();
mix = mix / 100;
if (mix < 0) mix = 0;
if (mix > 1) mix = 1;
addEffectForTag(tag, new DelayEffect(delay, dbToLinear(gain), mix));
};
Acts.prototype.AddFlangerEffect = function (tag, delay, modulation, freq, feedback, mix)
{
if (api !== API_WEBAUDIO || !context["createOscillator"])
return;
tag = tag.toLowerCase();
mix = mix / 100;
if (mix < 0) mix = 0;
if (mix > 1) mix = 1;
addEffectForTag(tag, new FlangerEffect(delay / 1000, modulation / 1000, freq, feedback / 100, mix));
};
Acts.prototype.AddPhaserEffect = function (tag, freq, detune, q, mod, modfreq, mix)
{
if (api !== API_WEBAUDIO || !context["createOscillator"])
return;
tag = tag.toLowerCase();
mix = mix / 100;
if (mix < 0) mix = 0;
if (mix > 1) mix = 1;
addEffectForTag(tag, new PhaserEffect(freq, detune, q, mod, modfreq, mix));
};
Acts.prototype.AddConvolutionEffect = function (tag, file, norm, mix)
{
if (api !== API_WEBAUDIO || !context["createConvolver"])
return;
var doNormalize = (norm === 0);
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
var b = this.getAudioBuffer(src, false);
tag = tag.toLowerCase();
mix = mix / 100;
if (mix < 0) mix = 0;
if (mix > 1) mix = 1;
var fx;
if (b.bufferObject)
{
fx = new ConvolveEffect(b.bufferObject, doNormalize, mix, src);
}
else
{
fx = new ConvolveEffect(null, doNormalize, mix, src);
b.normalizeWhenReady = doNormalize;
b.convolveWhenReady = fx;
}
addEffectForTag(tag, fx);
};
Acts.prototype.AddGainEffect = function (tag, g)
{
if (api !== API_WEBAUDIO)
return;
tag = tag.toLowerCase();
addEffectForTag(tag, new GainEffect(dbToLinear(g)));
};
Acts.prototype.AddMuteEffect = function (tag)
{
if (api !== API_WEBAUDIO)
return;
tag = tag.toLowerCase();
addEffectForTag(tag, new GainEffect(0)); // re-use gain effect with 0 gain
};
Acts.prototype.AddTremoloEffect = function (tag, freq, mix)
{
if (api !== API_WEBAUDIO || !context["createOscillator"])
return;
tag = tag.toLowerCase();
mix = mix / 100;
if (mix < 0) mix = 0;
if (mix > 1) mix = 1;
addEffectForTag(tag, new TremoloEffect(freq, mix));
};
Acts.prototype.AddRingModEffect = function (tag, freq, mix)
{
if (api !== API_WEBAUDIO || !context["createOscillator"])
return;
tag = tag.toLowerCase();
mix = mix / 100;
if (mix < 0) mix = 0;
if (mix > 1) mix = 1;
addEffectForTag(tag, new RingModulatorEffect(freq, mix));
};
Acts.prototype.AddDistortionEffect = function (tag, threshold, headroom, drive, makeupgain, mix)
{
if (api !== API_WEBAUDIO || !context["createWaveShaper"])
return;
tag = tag.toLowerCase();
mix = mix / 100;
if (mix < 0) mix = 0;
if (mix > 1) mix = 1;
addEffectForTag(tag, new DistortionEffect(threshold, headroom, drive, makeupgain, mix));
};
Acts.prototype.AddCompressorEffect = function (tag, threshold, knee, ratio, attack, release)
{
if (api !== API_WEBAUDIO || !context["createDynamicsCompressor"])
return;
tag = tag.toLowerCase();
addEffectForTag(tag, new CompressorEffect(threshold, knee, ratio, attack / 1000, release / 1000));
};
Acts.prototype.AddAnalyserEffect = function (tag, fftSize, smoothing)
{
if (api !== API_WEBAUDIO)
return;
tag = tag.toLowerCase();
addEffectForTag(tag, new AnalyserEffect(fftSize, smoothing));
};
Acts.prototype.RemoveEffects = function (tag)
{
if (api !== API_WEBAUDIO)
return;
tag = tag.toLowerCase();
var i, len, arr;
if (effects.hasOwnProperty(tag))
{
arr = effects[tag];
if (arr.length)
{
for (i = 0, len = arr.length; i < len; i++)
arr[i].remove();
cr.clearArray(arr);
reconnectEffects(tag);
}
}
};
Acts.prototype.SetEffectParameter = function (tag, index, param, value, ramp, time)
{
if (api !== API_WEBAUDIO)
return;
tag = tag.toLowerCase();
index = Math.floor(index);
var arr;
if (!effects.hasOwnProperty(tag))
return;
arr = effects[tag];
if (index < 0 || index >= arr.length)
return;
arr[index].setParam(param, value, ramp, time);
};
Acts.prototype.SetListenerObject = function (obj_)
{
if (!obj_ || api !== API_WEBAUDIO)
return;
var inst = obj_.getFirstPicked();
if (!inst)
return;
this.listenerTracker.setObject(inst);
listenerX = inst.x;
listenerY = inst.y;
};
Acts.prototype.SetListenerZ = function (z)
{
this.listenerZ = z;
};
Acts.prototype.ScheduleNextPlay = function (t)
{
if (!context)
return; // needs Web Audio API
this.nextPlayTime = t;
};
Acts.prototype.UnloadAudio = function (file)
{
var is_music = file[1];
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
var b = this.getAudioBuffer(src, is_music, true /* don't create if missing */);
if (!b)
return; // not loaded
b.release();
cr.arrayFindRemove(audioBuffers, b);
};
Acts.prototype.UnloadAudioByName = function (folder, filename)
{
var is_music = (folder === 1);
var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
var b = this.getAudioBuffer(src, is_music, true /* don't create if missing */);
if (!b)
return; // not loaded
b.release();
cr.arrayFindRemove(audioBuffers, b);
};
Acts.prototype.UnloadAll = function ()
{
var i, len;
for (i = 0, len = audioBuffers.length; i < len; ++i)
{
audioBuffers[i].release();
};
cr.clearArray(audioBuffers);
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.Duration = function (ret, tag)
{
getAudioByTag(tag, true);
if (taggedAudio.length)
ret.set_float(taggedAudio[0].getDuration());
else
ret.set_float(0);
};
Exps.prototype.PlaybackTime = function (ret, tag)
{
getAudioByTag(tag, true);
if (taggedAudio.length)
ret.set_float(taggedAudio[0].getPlaybackTime(true));
else
ret.set_float(0);
};
Exps.prototype.Volume = function (ret, tag)
{
getAudioByTag(tag, true);
if (taggedAudio.length)
{
var v = taggedAudio[0].getVolume();
ret.set_float(linearToDb(v));
}
else
ret.set_float(0);
};
Exps.prototype.MasterVolume = function (ret)
{
ret.set_float(linearToDb(masterVolume));
};
Exps.prototype.EffectCount = function (ret, tag)
{
tag = tag.toLowerCase();
var arr = null;
if (effects.hasOwnProperty(tag))
arr = effects[tag];
ret.set_int(arr ? arr.length : 0);
};
function getAnalyser(tag, index)
{
var arr = null;
if (effects.hasOwnProperty(tag))
arr = effects[tag];
if (arr && index >= 0 && index < arr.length && arr[index].freqBins)
return arr[index];
else
return null;
};
Exps.prototype.AnalyserFreqBinCount = function (ret, tag, index)
{
tag = tag.toLowerCase();
index = Math.floor(index);
var analyser = getAnalyser(tag, index);
ret.set_int(analyser ? analyser.node["frequencyBinCount"] : 0);
};
Exps.prototype.AnalyserFreqBinAt = function (ret, tag, index, bin)
{
tag = tag.toLowerCase();
index = Math.floor(index);
bin = Math.floor(bin);
var analyser = getAnalyser(tag, index);
if (!analyser)
ret.set_float(0);
else if (bin < 0 || bin >= analyser.node["frequencyBinCount"])
ret.set_float(0);
else
ret.set_float(analyser.freqBins[bin]);
};
Exps.prototype.AnalyserPeakLevel = function (ret, tag, index)
{
tag = tag.toLowerCase();
index = Math.floor(index);
var analyser = getAnalyser(tag, index);
if (analyser)
ret.set_float(analyser.peak);
else
ret.set_float(0);
};
Exps.prototype.AnalyserRMSLevel = function (ret, tag, index)
{
tag = tag.toLowerCase();
index = Math.floor(index);
var analyser = getAnalyser(tag, index);
if (analyser)
ret.set_float(analyser.rms);
else
ret.set_float(0);
};
Exps.prototype.SampleRate = function (ret)
{
ret.set_int(context ? context.sampleRate : 0);
};
Exps.prototype.CurrentTime = function (ret)
{
ret.set_float(context ? context.currentTime : cr.performance_now());
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.Browser = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Browser.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
var offlineScriptReady = false;
var browserPluginReady = false;
document.addEventListener("DOMContentLoaded", function ()
{
if (window["C2_RegisterSW"] && navigator["serviceWorker"])
{
var offlineClientScript = document.createElement("script");
offlineClientScript.onload = function ()
{
offlineScriptReady = true;
checkReady()
};
offlineClientScript.src = "offlineClient.js";
document.head.appendChild(offlineClientScript);
}
});
var browserInstance = null;
typeProto.onAppBegin = function ()
{
browserPluginReady = true;
checkReady();
};
function checkReady()
{
if (offlineScriptReady && browserPluginReady && window["OfflineClientInfo"])
{
window["OfflineClientInfo"]["SetMessageCallback"](function (e)
{
browserInstance.onSWMessage(e);
});
}
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
var self = this;
window.addEventListener("resize", function () {
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnResize, self);
});
browserInstance = this;
if (typeof navigator.onLine !== "undefined")
{
window.addEventListener("online", function() {
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOnline, self);
});
window.addEventListener("offline", function() {
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOffline, self);
});
}
if (!this.runtime.isDirectCanvas)
{
document.addEventListener("appMobi.device.update.available", function() {
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateReady, self);
});
document.addEventListener("backbutton", function() {
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
});
document.addEventListener("menubutton", function() {
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnMenuButton, self);
});
document.addEventListener("searchbutton", function() {
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnSearchButton, self);
});
document.addEventListener("tizenhwkey", function (e) {
var ret;
switch (e["keyName"]) {
case "back":
ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
if (!ret)
{
if (window["tizen"])
window["tizen"]["application"]["getCurrentApplication"]()["exit"]();
}
break;
case "menu":
ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnMenuButton, self);
if (!ret)
e.preventDefault();
break;
}
});
}
if (this.runtime.isWindows10 && typeof Windows !== "undefined")
{
Windows["UI"]["Core"]["SystemNavigationManager"]["getForCurrentView"]().addEventListener("backrequested", function (e)
{
var ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
if (ret)
e["handled"] = true;
});
}
else if (this.runtime.isWinJS && WinJS["Application"])
{
WinJS["Application"]["onbackclick"] = function (e)
{
return !!self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
};
}
this.runtime.addSuspendCallback(function(s) {
if (s)
{
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnPageHidden, self);
}
else
{
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnPageVisible, self);
}
});
this.is_arcade = (typeof window["is_scirra_arcade"] !== "undefined");
};
instanceProto.onSWMessage = function (e)
{
var messageType = e["data"]["type"];
if (messageType === "downloading-update")
this.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateFound, this);
else if (messageType === "update-ready" || messageType === "update-pending")
this.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateReady, this);
else if (messageType === "offline-ready")
this.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOfflineReady, this);
};
var batteryManager = null;
var loadedBatteryManager = false;
function maybeLoadBatteryManager()
{
if (loadedBatteryManager)
return;
if (!navigator["getBattery"])
return;
var promise = navigator["getBattery"]();
loadedBatteryManager = true;
if (promise)
{
promise.then(function (manager) {
batteryManager = manager;
});
}
};
function Cnds() {};
Cnds.prototype.CookiesEnabled = function()
{
return navigator ? navigator.cookieEnabled : false;
};
Cnds.prototype.IsOnline = function()
{
return navigator ? navigator.onLine : false;
};
Cnds.prototype.HasJava = function()
{
return navigator ? navigator.javaEnabled() : false;
};
Cnds.prototype.OnOnline = function()
{
return true;
};
Cnds.prototype.OnOffline = function()
{
return true;
};
Cnds.prototype.IsDownloadingUpdate = function ()
{
return false; // deprecated
};
Cnds.prototype.OnUpdateReady = function ()
{
return true;
};
Cnds.prototype.PageVisible = function ()
{
return !this.runtime.isSuspended;
};
Cnds.prototype.OnPageVisible = function ()
{
return true;
};
Cnds.prototype.OnPageHidden = function ()
{
return true;
};
Cnds.prototype.OnResize = function ()
{
return true;
};
Cnds.prototype.IsFullscreen = function ()
{
return !!(document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || this.runtime.isNodeFullscreen);
};
Cnds.prototype.OnBackButton = function ()
{
return true;
};
Cnds.prototype.OnMenuButton = function ()
{
return true;
};
Cnds.prototype.OnSearchButton = function ()
{
return true;
};
Cnds.prototype.IsMetered = function ()
{
var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
if (!connection)
return false;
return !!connection["metered"];
};
Cnds.prototype.IsCharging = function ()
{
var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
if (battery)
{
return !!battery["charging"]
}
else
{
maybeLoadBatteryManager();
if (batteryManager)
{
return !!batteryManager["charging"];
}
else
{
return true; // if unknown, default to charging (powered)
}
}
};
Cnds.prototype.IsPortraitLandscape = function (p)
{
var current = (window.innerWidth <= window.innerHeight ? 0 : 1);
return current === p;
};
Cnds.prototype.SupportsFullscreen = function ()
{
if (this.runtime.isNodeWebkit)
return true;
var elem = this.runtime.canvasdiv || this.runtime.canvas;
return !!(elem["requestFullscreen"] || elem["mozRequestFullScreen"] || elem["msRequestFullscreen"] || elem["webkitRequestFullScreen"]);
};
Cnds.prototype.OnUpdateFound = function ()
{
return true;
};
Cnds.prototype.OnUpdateReady = function ()
{
return true;
};
Cnds.prototype.OnOfflineReady = function ()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.Alert = function (msg)
{
if (!this.runtime.isDomFree)
alert(msg.toString());
};
Acts.prototype.Close = function ()
{
if (this.runtime.isCocoonJs)
CocoonJS["App"]["forceToFinish"]();
else if (window["tizen"])
window["tizen"]["application"]["getCurrentApplication"]()["exit"]();
else if (navigator["app"] && navigator["app"]["exitApp"])
navigator["app"]["exitApp"]();
else if (navigator["device"] && navigator["device"]["exitApp"])
navigator["device"]["exitApp"]();
else if (!this.is_arcade && !this.runtime.isDomFree)
window.close();
};
Acts.prototype.Focus = function ()
{
if (this.runtime.isNodeWebkit)
{
var win = window["nwgui"]["Window"]["get"]();
win["focus"]();
}
else if (!this.is_arcade && !this.runtime.isDomFree)
window.focus();
};
Acts.prototype.Blur = function ()
{
if (this.runtime.isNodeWebkit)
{
var win = window["nwgui"]["Window"]["get"]();
win["blur"]();
}
else if (!this.is_arcade && !this.runtime.isDomFree)
window.blur();
};
Acts.prototype.GoBack = function ()
{
if (navigator["app"] && navigator["app"]["backHistory"])
navigator["app"]["backHistory"]();
else if (!this.is_arcade && !this.runtime.isDomFree && window.back)
window.back();
};
Acts.prototype.GoForward = function ()
{
if (!this.is_arcade && !this.runtime.isDomFree && window.forward)
window.forward();
};
Acts.prototype.GoHome = function ()
{
if (!this.is_arcade && !this.runtime.isDomFree && window.home)
window.home();
};
Acts.prototype.GoToURL = function (url, target)
{
if (this.runtime.isCocoonJs)
CocoonJS["App"]["openURL"](url);
else if (this.runtime.isEjecta)
ejecta["openURL"](url);
else if (this.runtime.isWinJS)
Windows["System"]["Launcher"]["launchUriAsync"](new Windows["Foundation"]["Uri"](url));
else if (navigator["app"] && navigator["app"]["loadUrl"])
navigator["app"]["loadUrl"](url, { "openExternal": true });
else if (this.runtime.isCordova)
window.open(url, "_system");
else if (!this.is_arcade && !this.runtime.isDomFree)
{
if (target === 2 && !this.is_arcade) // top
window.top.location = url;
else if (target === 1 && !this.is_arcade) // parent
window.parent.location = url;
else // self
window.location = url;
}
};
Acts.prototype.GoToURLWindow = function (url, tag)
{
if (this.runtime.isCocoonJs)
CocoonJS["App"]["openURL"](url);
else if (this.runtime.isEjecta)
ejecta["openURL"](url);
else if (this.runtime.isWinJS)
Windows["System"]["Launcher"]["launchUriAsync"](new Windows["Foundation"]["Uri"](url));
else if (navigator["app"] && navigator["app"]["loadUrl"])
navigator["app"]["loadUrl"](url, { "openExternal": true });
else if (this.runtime.isCordova)
window.open(url, "_system");
else if (!this.is_arcade && !this.runtime.isDomFree)
window.open(url, tag);
};
Acts.prototype.Reload = function ()
{
if (!this.is_arcade && !this.runtime.isDomFree)
window.location.reload();
};
var firstRequestFullscreen = true;
var crruntime = null;
function onFullscreenError(e)
{
if (console && console.warn)
console.warn("Fullscreen request failed: ", e);
crruntime["setSize"](window.innerWidth, window.innerHeight);
};
Acts.prototype.RequestFullScreen = function (stretchmode)
{
if (this.runtime.isDomFree)
{
cr.logexport("[Construct 2] Requesting fullscreen is not supported on this platform - the request has been ignored");
return;
}
if (stretchmode >= 2)
stretchmode += 1;
if (stretchmode === 6)
stretchmode = 2;
if (this.runtime.isNodeWebkit)
{
if (this.runtime.isDebug)
{
debuggerFullscreen(true);
}
else if (!this.runtime.isNodeFullscreen && window["nwgui"])
{
window["nwgui"]["Window"]["get"]()["enterFullscreen"]();
this.runtime.isNodeFullscreen = true;
this.runtime.fullscreen_scaling = (stretchmode >= 2 ? stretchmode : 0);
}
}
else
{
if (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || document["fullScreenElement"])
{
return;
}
this.runtime.fullscreen_scaling = (stretchmode >= 2 ? stretchmode : 0);
var elem = document.documentElement;
if (firstRequestFullscreen)
{
firstRequestFullscreen = false;
crruntime = this.runtime;
elem.addEventListener("mozfullscreenerror", onFullscreenError);
elem.addEventListener("webkitfullscreenerror", onFullscreenError);
elem.addEventListener("MSFullscreenError", onFullscreenError);
elem.addEventListener("fullscreenerror", onFullscreenError);
}
if (elem["requestFullscreen"])
elem["requestFullscreen"]();
else if (elem["mozRequestFullScreen"])
elem["mozRequestFullScreen"]();
else if (elem["msRequestFullscreen"])
elem["msRequestFullscreen"]();
else if (elem["webkitRequestFullScreen"])
{
if (typeof Element !== "undefined" && typeof Element["ALLOW_KEYBOARD_INPUT"] !== "undefined")
elem["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"]);
else
elem["webkitRequestFullScreen"]();
}
}
};
Acts.prototype.CancelFullScreen = function ()
{
if (this.runtime.isDomFree)
{
cr.logexport("[Construct 2] Exiting fullscreen is not supported on this platform - the request has been ignored");
return;
}
if (this.runtime.isNodeWebkit)
{
if (this.runtime.isDebug)
{
debuggerFullscreen(false);
}
else if (this.runtime.isNodeFullscreen && window["nwgui"])
{
window["nwgui"]["Window"]["get"]()["leaveFullscreen"]();
this.runtime.isNodeFullscreen = false;
}
}
else
{
if (document["exitFullscreen"])
document["exitFullscreen"]();
else if (document["mozCancelFullScreen"])
document["mozCancelFullScreen"]();
else if (document["msExitFullscreen"])
document["msExitFullscreen"]();
else if (document["webkitCancelFullScreen"])
document["webkitCancelFullScreen"]();
}
};
Acts.prototype.Vibrate = function (pattern_)
{
try {
var arr = pattern_.split(",");
var i, len;
for (i = 0, len = arr.length; i < len; i++)
{
arr[i] = parseInt(arr[i], 10);
}
if (navigator["vibrate"])
navigator["vibrate"](arr);
else if (navigator["mozVibrate"])
navigator["mozVibrate"](arr);
else if (navigator["webkitVibrate"])
navigator["webkitVibrate"](arr);
else if (navigator["msVibrate"])
navigator["msVibrate"](arr);
}
catch (e) {}
};
Acts.prototype.InvokeDownload = function (url_, filename_)
{
var a = document.createElement("a");
if (typeof a["download"] === "undefined")
{
window.open(url_);
}
else
{
var body = document.getElementsByTagName("body")[0];
a.textContent = filename_;
a.href = url_;
a["download"] = filename_;
body.appendChild(a);
var clickEvent = new MouseEvent("click");
a.dispatchEvent(clickEvent);
body.removeChild(a);
}
};
Acts.prototype.InvokeDownloadString = function (str_, mimetype_, filename_)
{
var datauri = "data:" + mimetype_ + "," + encodeURIComponent(str_);
var a = document.createElement("a");
if (typeof a["download"] === "undefined")
{
window.open(datauri);
}
else
{
var body = document.getElementsByTagName("body")[0];
a.textContent = filename_;
a.href = datauri;
a["download"] = filename_;
body.appendChild(a);
var clickEvent = new MouseEvent("click");
a.dispatchEvent(clickEvent);
body.removeChild(a);
}
};
Acts.prototype.ConsoleLog = function (type_, msg_)
{
if (typeof console === "undefined")
return;
if (type_ === 0 && console.log)
console.log(msg_.toString());
if (type_ === 1 && console.warn)
console.warn(msg_.toString());
if (type_ === 2 && console.error)
console.error(msg_.toString());
};
Acts.prototype.ConsoleGroup = function (name_)
{
if (console && console.group)
console.group(name_);
};
Acts.prototype.ConsoleGroupEnd = function ()
{
if (console && console.groupEnd)
console.groupEnd();
};
Acts.prototype.ExecJs = function (js_)
{
try {
if (eval)
eval(js_);
}
catch (e)
{
if (console && console.error)
console.error("Error executing Javascript: ", e);
}
};
var orientations = [
"portrait",
"landscape",
"portrait-primary",
"portrait-secondary",
"landscape-primary",
"landscape-secondary"
];
Acts.prototype.LockOrientation = function (o)
{
o = Math.floor(o);
if (o < 0 || o >= orientations.length)
return;
this.runtime.autoLockOrientation = false;
var orientation = orientations[o];
if (screen["orientation"] && screen["orientation"]["lock"])
screen["orientation"]["lock"](orientation);
else if (screen["lockOrientation"])
screen["lockOrientation"](orientation);
else if (screen["webkitLockOrientation"])
screen["webkitLockOrientation"](orientation);
else if (screen["mozLockOrientation"])
screen["mozLockOrientation"](orientation);
else if (screen["msLockOrientation"])
screen["msLockOrientation"](orientation);
};
Acts.prototype.UnlockOrientation = function ()
{
this.runtime.autoLockOrientation = false;
if (screen["orientation"] && screen["orientation"]["unlock"])
screen["orientation"]["unlock"]();
else if (screen["unlockOrientation"])
screen["unlockOrientation"]();
else if (screen["webkitUnlockOrientation"])
screen["webkitUnlockOrientation"]();
else if (screen["mozUnlockOrientation"])
screen["mozUnlockOrientation"]();
else if (screen["msUnlockOrientation"])
screen["msUnlockOrientation"]();
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.URL = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : window.location.toString());
};
Exps.prototype.Protocol = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : window.location.protocol);
};
Exps.prototype.Domain = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : window.location.hostname);
};
Exps.prototype.PathName = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : window.location.pathname);
};
Exps.prototype.Hash = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : window.location.hash);
};
Exps.prototype.Referrer = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : document.referrer);
};
Exps.prototype.Title = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : document.title);
};
Exps.prototype.Name = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : navigator.appName);
};
Exps.prototype.Version = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : navigator.appVersion);
};
Exps.prototype.Language = function (ret)
{
if (navigator && navigator.language)
ret.set_string(navigator.language);
else
ret.set_string("");
};
Exps.prototype.Platform = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : navigator.platform);
};
Exps.prototype.Product = function (ret)
{
if (navigator && navigator.product)
ret.set_string(navigator.product);
else
ret.set_string("");
};
Exps.prototype.Vendor = function (ret)
{
if (navigator && navigator.vendor)
ret.set_string(navigator.vendor);
else
ret.set_string("");
};
Exps.prototype.UserAgent = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : navigator.userAgent);
};
Exps.prototype.QueryString = function (ret)
{
ret.set_string(this.runtime.isDomFree ? "" : window.location.search);
};
Exps.prototype.QueryParam = function (ret, paramname)
{
if (this.runtime.isDomFree)
{
ret.set_string("");
return;
}
var match = RegExp('[?&]' + paramname + '=([^&]*)').exec(window.location.search);
if (match)
ret.set_string(decodeURIComponent(match[1].replace(/\+/g, ' ')));
else
ret.set_string("");
};
Exps.prototype.Bandwidth = function (ret)
{
var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
if (!connection)
ret.set_float(Number.POSITIVE_INFINITY);
else
{
if (typeof connection["bandwidth"] !== "undefined")
ret.set_float(connection["bandwidth"]);
else if (typeof connection["downlinkMax"] !== "undefined")
ret.set_float(connection["downlinkMax"]);
else
ret.set_float(Number.POSITIVE_INFINITY);
}
};
Exps.prototype.ConnectionType = function (ret)
{
var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
if (!connection)
ret.set_string("unknown");
else
{
ret.set_string(connection["type"] || "unknown");
}
};
Exps.prototype.BatteryLevel = function (ret)
{
var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
if (battery)
{
ret.set_float(battery["level"]);
}
else
{
maybeLoadBatteryManager();
if (batteryManager)
{
ret.set_float(batteryManager["level"]);
}
else
{
ret.set_float(1); // not supported/unknown: assume charged
}
}
};
Exps.prototype.BatteryTimeLeft = function (ret)
{
var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
if (battery)
{
ret.set_float(battery["dischargingTime"]);
}
else
{
maybeLoadBatteryManager();
if (batteryManager)
{
ret.set_float(batteryManager["dischargingTime"]);
}
else
{
ret.set_float(Number.POSITIVE_INFINITY); // not supported/unknown: assume infinite time left
}
}
};
Exps.prototype.ExecJS = function (ret, js_)
{
if (!eval)
{
ret.set_any(0);
return;
}
var result = 0;
try {
result = eval(js_);
}
catch (e)
{
if (console && console.error)
console.error("Error executing Javascript: ", e);
}
if (typeof result === "number")
ret.set_any(result);
else if (typeof result === "string")
ret.set_any(result);
else if (typeof result === "boolean")
ret.set_any(result ? 1 : 0);
else
ret.set_any(0);
};
Exps.prototype.ScreenWidth = function (ret)
{
ret.set_int(screen.width);
};
Exps.prototype.ScreenHeight = function (ret)
{
ret.set_int(screen.height);
};
Exps.prototype.DevicePixelRatio = function (ret)
{
ret.set_float(this.runtime.devicePixelRatio);
};
Exps.prototype.WindowInnerWidth = function (ret)
{
ret.set_int(window.innerWidth);
};
Exps.prototype.WindowInnerHeight = function (ret)
{
ret.set_int(window.innerHeight);
};
Exps.prototype.WindowOuterWidth = function (ret)
{
ret.set_int(window.outerWidth);
};
Exps.prototype.WindowOuterHeight = function (ret)
{
ret.set_int(window.outerHeight);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.CBhash = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.CBhash.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
this.lastResult = "";
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.hexcase = 0;
this.b64pad = " ";
};
pluginProto.cnds = {};
var cnds = pluginProto.cnds;
cnds.OnHashed = function ()
{
return true;
};
instanceProto.hex_md5 = function(s) { return this.rstr2hex(rstr_md5(str2rstr_utf8(s))); }
instanceProto.b64_md5 = function(s) { return this.rstr2b64(rstr_md5(str2rstr_utf8(s))); }
instanceProto.any_md5 = function(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); }
instanceProto.hex_hmac_md5 = function(k, d) { return this.rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
instanceProto.b64_hmac_md5 = function(k, d) { return this.rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
instanceProto.any_hmac_md5= function(k, d, e) { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
instanceProto.hex_sha1 = function(s) { return this.rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
instanceProto.b64_sha1 = function(s) { return this.rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
instanceProto.any_sha1 = function(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
instanceProto.hex_hmac_sha1 = function(k, d) { return this.rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
instanceProto.b64_hmac_sha1 = function(k, d) { return this.rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
instanceProto.any_hmac_sha1 = function(k, d, e) { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
instanceProto.hex_sha256 = function(s) { return this.rstr2hex(rstr_sha256(str2rstr_utf8(s))); }
instanceProto.b64_sha256 = function(s) { return this.rstr2b64(rstr_sha256(str2rstr_utf8(s))); }
instanceProto.any_sha256 = function(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); }
instanceProto.hex_hmac_sha256 = function(k, d) { return this.rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
instanceProto.b64_hmac_sha256 = function(k, d) { return this.rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
instanceProto.any_hmac_sha256 = function(k, d, e) { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
/*
* Convert a raw string to a hex string
*/
instanceProto.rstr2hex = function(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;
}
/*
* Convert a raw string to a base-64 string
*/
instanceProto.rstr2b64 = function(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;
}
pluginProto.acts = {};
var acts = pluginProto.acts;
acts.set_hexoutput = function (format)
{
if (format == 0)
this.hexcase = 0;
else
this.hexcase = 1;
};
acts.set_bpad = function (charac)
{
this.b64pad = charac;
};
acts.MD5_hash = function (string, format)
{
var outF = format;
if (outF == 0)
this.lastResult = this.hex_md5(string);
else
this.lastResult = this.b64_md5(string);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.MD5_pass = function (string, encoding)
{
this.lastResult = this.any_md5(string, encoding);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.HMAC_hash = function (key, data, Format)
{
if (Format == 0)
this.lastResult = this.hex_hmac_md5(key, data);
else
this.lastResult = this.b64_hmac_md5(key, data);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.HMAC_pass = function (key, data, charString)
{
this.lastResult = this.any_hmac_md5(key, data, charString);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.SHA1_hash = function (string, format)
{
var outF = format;
if (outF == 0)
this.lastResult = this.hex_sha1(string);
else
this.lastResult = this.b64_sha1(string);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.SHA1_pass = function (string, encoding)
{
this.lastResult = this.any_sha1(string, encoding);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.HMACSHA1_hash = function (key, data, Format)
{
if (Format == 0)
this.lastResult = this.hex_hmac_sha1(key, data);
else
this.lastResult = this.b64_hmac_sha1(key, data);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.HMACSHA1_pass = function (key, data, charString)
{
this.lastResult = this.any_hmac_sha1(key, data, charString);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.SHA256_hash = function (string, format)
{
var outF = format;
if (outF == 0)
this.lastResult = this.hex_sha256(string);
else
this.lastResult = this.b64_sha256(string);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.SHA256_pass = function (string, encoding)
{
this.lastResult = this.any_sha256(string, encoding);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.HMACSHA256_hash = function (key, data, Format)
{
if (Format == 0)
this.lastResult = this.hex_hmac_sha256(key, data);
else
this.lastResult = this.b64_hmac_sha256(key, data);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
acts.HMACSHA256_pass = function (key, data, charString)
{
this.lastResult = this.any_hmac_sha256(key, data, charString);
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
pluginProto.exps = {};
var exps = pluginProto.exps;
exps.get_lastResult = function (ret)
{
ret.set_string(this.lastResult);
};
exps.MD5 = function (ret, data)
{
ret.set_string(this.hex_md5(data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.MD5B = function (ret, data)
{
ret.set_string(this.b64_md5(data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.MD5pass = function (ret, data, charstring)
{
ret.set_string(this.any_md5(data, charstring));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.HMACMD5 = function (ret, key, data)
{
ret.set_string(this.hex_hmac_md5(key, data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.HMACMD5B = function (ret, key, data)
{
ret.set_string(this.b64_hmac_md5(key, data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.HMACMD5pass = function (ret, key, data, charstring)
{
ret.set_string(this.any_hmac_md5(key, data, charstring));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.SHA1 = function (ret, data)
{
ret.set_string(this.hex_sha1(data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.SHA1B = function (ret, data)
{
ret.set_string(this.b64_sha1(data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.SHA1pass = function (ret, data, charstring)
{
ret.set_string(this.any_sha1(data, charstring));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.HMACSHA1 = function (ret, key, data)
{
ret.set_string(this.hex_hmac_sha1(key, data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.HMACSHA1B = function (ret, key, data)
{
ret.set_string(this.b64_hmac_sha1(key, data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.HMACSHA1pass = function (ret, key, data, charstring)
{
ret.set_string(this.any_hmac_sha1(key, data, charstring));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.SHA256 = function (ret, data)
{
ret.set_string(this.hex_sha256(data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.SHA256B = function (ret, data)
{
ret.set_string(this.b64_sha256(data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.SHA256pass = function (ret, data, charstring)
{
ret.set_string(this.any_sha256(data, charstring));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.HMACSHA256 = function (ret, key, data)
{
ret.set_string(this.hex_hmac_sha256(key, data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.HMACSHA256B = function (ret, key, data)
{
ret.set_string(this.b64_hmac_sha256(key, data));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
exps.HMACSHA256pass = function (ret, key, data, charstring)
{
ret.set_string(this.any_hmac_sha256(key, data, charstring));
this.runtime.trigger(cr.plugins_.CBhash.prototype.cnds.OnHashed, this);
};
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* The JavaScript code implementing the algorithm is derived from the C code in RFC 1321 and is covered by the following copyright:
* License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function.
* License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work.
* RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind.
* These notices must be retained in any copies of any part of this documentation and/or software.
* This copyright does not prohibit distribution of the JavaScript MD5 code under the BSD license.
*/
/*
* Calculate the MD5 of a raw string
*/
function rstr_md5(s)
{
return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
}
/*
* Calculate the HMAC-MD5, of a key and some data (raw strings)
*/
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));
}
/*
* Convert a raw string to an arbitrary string encoding
*/
function rstr2any(input, encoding)
{
var divisor = encoding.length;
var i, j, q, x, quotient;
/* Convert to an array of 16-bit big-endian values, forming the dividend */
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);
}
/*
* Repeatedly perform a long division. The binary array forms the dividend,
* the length of the encoding is the divisor. Once computed, the quotient
* forms the dividend for the next step. All remainders are stored for later
* use.
*/
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;
}
/* Convert the remainders to the output string */
var output = "";
for(i = remainders.length - 1; i >= 0; i--)
output += encoding.charAt(remainders[i]);
return output;
}
/*
* Encode a string as utf-8.
* For efficiency, this assumes the input is valid utf-16.
*/
function str2rstr_utf8(input)
{
var output = "";
var i = -1;
var x, y;
while(++i < input.length)
{
/* Decode utf-16 surrogate pairs */
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++;
}
/* Encode output as utf-8 */
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;
}
/*
* Encode a string as utf-16
*/
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;
}
/*
* Convert a raw string to an array of little-endian words
* Characters >255 have their high-byte silently ignored.
*/
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;
}
/*
* Convert an array of little-endian words to a string
*/
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;
}
/*
* Calculate the MD5 of an array of little-endian words, and a bit length.
*/
function binl_md5(x, len)
{
/* append padding */
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);
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
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);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bit_rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
* in FIPS 180-1
* Version 2.2 Copyright Paul Johnston 2000 - 2009.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*/
/*
* Calculate the SHA1 of a raw string
*/
function rstr_sha1(s)
{
return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
}
/*
* Calculate the HMAC-SHA1 of a key and some data (raw strings)
*/
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));
}
/*
* Convert a raw string to an array of big-endian words
* Characters >255 have their high-byte silently ignored.
*/
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;
}
/*
* Convert an array of big-endian words to a string
*/
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;
}
/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
*/
function binb_sha1(x, len)
{
/* append padding */
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);
}
/*
* Perform the appropriate triplet combination function for the current
* iteration
*/
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;
}
/*
* Determine the appropriate additive constant for the current iteration
*/
function sha1_kt(t)
{
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
}
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
* in FIPS 180-2
* Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
* Also http://anmar.eu.org/projects/jssha2/
*/
/*
* Calculate the sha256 of a raw string
*/
function rstr_sha256(s)
{
return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
}
/*
* Calculate the HMAC-sha256 of a key and some data (raw strings)
*/
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));
}
/*
* Main sha256 function, with its support functions
*/
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;
/* append padding */
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;
}
}());
;
;
var lastCSS = "";
var importList = [];
function importcssfile(filename){
if (importList.indexOf(filename)==-1){ //Only imports if file of same name not already imported
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
document.getElementsByTagName("head")[0].appendChild(fileref)
importList.push(filename)
}
};
if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function(what, i) {
i = i || 0;
var L = this.length;
while (i < L) {
if(this[i] === what) return i;
++i;
}
return -1;
};
};
function removecssfile(filename){
var removeList=document.getElementsByTagName("link")
for (var i=removeList.length; i>=0; i--){ //search backwards within nodelist for matching elements to remove
if (removeList[i] && removeList[i].getAttribute("href")!=null && removeList[i].getAttribute("href").indexOf(filename)!=-1)
removeList[i].parentNode.removeChild(removeList[i]) //remove element by calling parentNode.removeChild()
}
importList.splice(importList.indexOf(filename), 1);
};
cr.plugins_.CSS_import = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.CSS_import.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
if (this.properties[0] != ""){
importcssfile(this.properties[0]);
lastCSS = this.properties[0];
}
};
instanceProto.onDestroy = function ()
{
};
instanceProto.draw = function(ctx)
{
};
instanceProto.drawGL = function(glw)
{
};
pluginProto.cnds = {};
var cnds = pluginProto.cnds;
cnds.CompareCSS = function (text, case_)
{
return this.properties[0] === text;
};
pluginProto.acts = {};
var acts = pluginProto.acts;
acts.SetCSS = function (setName)
{
importcssfile(setName);
lastCSS = setName;
};
acts.RemCSS = function (remName)
{
removecssfile(remName);
};
pluginProto.exps = {};
var exps = pluginProto.exps;
exps.GetCSS = function (ret)
{
if (lastCSS != ""){
ret.set_string(lastCSS);
} else if (this.properties[0] != ""){
ret.set_string(this.properties[0]);
} else {
ret.set_string("");
}
};
}());
;
;
cr.plugins_.Function = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Function.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
var funcStack = [];
var funcStackPtr = -1;
var isInPreview = false; // set in onCreate
function FuncStackEntry()
{
this.name = "";
this.retVal = 0;
this.params = [];
};
function pushFuncStack()
{
funcStackPtr++;
if (funcStackPtr === funcStack.length)
funcStack.push(new FuncStackEntry());
return funcStack[funcStackPtr];
};
function getCurrentFuncStack()
{
if (funcStackPtr < 0)
return null;
return funcStack[funcStackPtr];
};
function getOneAboveFuncStack()
{
if (!funcStack.length)
return null;
var i = funcStackPtr + 1;
if (i >= funcStack.length)
i = funcStack.length - 1;
return funcStack[i];
};
function popFuncStack()
{
;
funcStackPtr--;
};
instanceProto.onCreate = function()
{
isInPreview = (typeof cr_is_preview !== "undefined");
var self = this;
window["c2_callFunction"] = function (name_, params_)
{
var i, len, v;
var fs = pushFuncStack();
fs.name = name_.toLowerCase();
fs.retVal = 0;
if (params_)
{
fs.params.length = params_.length;
for (i = 0, len = params_.length; i < len; ++i)
{
v = params_[i];
if (typeof v === "number" || typeof v === "string")
fs.params[i] = v;
else if (typeof v === "boolean")
fs.params[i] = (v ? 1 : 0);
else
fs.params[i] = 0;
}
}
else
{
cr.clearArray(fs.params);
}
self.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, self, fs.name);
popFuncStack();
return fs.retVal;
};
};
function Cnds() {};
Cnds.prototype.OnFunction = function (name_)
{
var fs = getCurrentFuncStack();
if (!fs)
return false;
return cr.equals_nocase(name_, fs.name);
};
Cnds.prototype.CompareParam = function (index_, cmp_, value_)
{
var fs = getCurrentFuncStack();
if (!fs)
return false;
index_ = cr.floor(index_);
if (index_ < 0 || index_ >= fs.params.length)
return false;
return cr.do_cmp(fs.params[index_], cmp_, value_);
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.CallFunction = function (name_, params_)
{
var fs = pushFuncStack();
fs.name = name_.toLowerCase();
fs.retVal = 0;
cr.shallowAssignArray(fs.params, params_);
var ran = this.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, this, fs.name);
if (isInPreview && !ran)
{
;
}
popFuncStack();
};
Acts.prototype.SetReturnValue = function (value_)
{
var fs = getCurrentFuncStack();
if (fs)
fs.retVal = value_;
else
;
};
Acts.prototype.CallExpression = function (unused)
{
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.ReturnValue = function (ret)
{
var fs = getOneAboveFuncStack();
if (fs)
ret.set_any(fs.retVal);
else
ret.set_int(0);
};
Exps.prototype.ParamCount = function (ret)
{
var fs = getCurrentFuncStack();
if (fs)
ret.set_int(fs.params.length);
else
{
;
ret.set_int(0);
}
};
Exps.prototype.Param = function (ret, index_)
{
index_ = cr.floor(index_);
var fs = getCurrentFuncStack();
if (fs)
{
if (index_ >= 0 && index_ < fs.params.length)
{
ret.set_any(fs.params[index_]);
}
else
{
;
ret.set_int(0);
}
}
else
{
;
ret.set_int(0);
}
};
Exps.prototype.Call = function (ret, name_)
{
var fs = pushFuncStack();
fs.name = name_.toLowerCase();
fs.retVal = 0;
cr.clearArray(fs.params);
var i, len;
for (i = 2, len = arguments.length; i < len; i++)
fs.params.push(arguments[i]);
var ran = this.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, this, fs.name);
if (isInPreview && !ran)
{
;
}
popFuncStack();
ret.set_any(fs.retVal);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.GameAnalytics = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.GameAnalytics.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.build = this.properties[0];
this.customUserId = this.properties[1];
this.enableManualSessionHandling = this.properties[2];
this.enableInfoLog = this.properties[3];
this.enableVerboseLog = this.properties[4];
this.autoDetectAppVersion = this.properties[5];
this.gameKeyBrowser = this.properties[6];
this.secretKeyBrowser = this.properties[7];
this.gameKeyAndroid = this.properties[8];
this.secretKeyAndroid = this.properties[9];
this.gameKeyIOS = this.properties[10];
this.secretKeyIOS = this.properties[11];
this.customDimensions01 = [];
this.customDimensions02 = [];
this.customDimensions03 = [];
this.resourceCurrencies = [];
this.resourceItemTypes = [];
};
instanceProto.onDestroy = function ()
{
};
instanceProto.saveToJSON = function ()
{
return {
};
};
instanceProto.loadFromJSON = function (o)
{
};
instanceProto.draw = function(ctx)
{
};
instanceProto.drawGL = function (glw)
{
};
function Cnds() {};
Cnds.prototype.isRemoteConfigsReady = function (functionName)
{
if(typeof window["GameAnalytics"]["isRemoteConfigsReady"] == "function")
{
var callback = function(result) {
if(functionName && window["c2_callFunction"]) {
window["c2_callFunction"](functionName, [result ? 1 : 0]);
}
}
window["GameAnalytics"]["isRemoteConfigsReady"](callback);
return false;
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
return window["gameanalytics"]["GameAnalytics"]["isRemoteConfigsReady"]();
}
else
{
console.log("isRemoteConfigsReady: GameAnalytics object not found");
return false;
}
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.addAvailableCustomDimension01 = function (dimension)
{
this.customDimensions01.push(dimension);
};
Acts.prototype.addAvailableCustomDimension02 = function (dimension)
{
this.customDimensions02.push(dimension);
};
Acts.prototype.addAvailableCustomDimension03 = function (dimension)
{
this.customDimensions03.push(dimension);
};
Acts.prototype.addAvailableResourceCurrency = function (currency)
{
this.resourceCurrencies.push(currency);
};
Acts.prototype.addAvailableResourceItemType = function (itemType)
{
this.resourceItemTypes.push(itemType);
};
Acts.prototype.initialize = function ()
{
var VERSION = "3.0.14";
if(typeof window["GameAnalytics"]["initialize"] == "function")
{
var ga = window["GameAnalytics"];
if(this.enableInfoLog)
{
ga["setEnabledInfoLog"](true);
}
if(this.enableVerboseLog)
{
ga["setEnabledVerboseLog"](true);
}
if(this.enableManualSessionHandling)
{
ga["setEnabledManualSessionHandling"](true);
}
if(this.customDimensions01.length > 0)
{
ga["configureAvailableCustomDimensions01"](this.customDimensions01);
}
if(this.customDimensions02.length > 0)
{
ga["configureAvailableCustomDimensions02"](this.customDimensions02);
}
if(this.customDimensions03.length > 0)
{
ga["configureAvailableCustomDimensions03"](this.customDimensions03);
}
if(this.resourceCurrencies.length > 0)
{
ga["configureAvailableResourceCurrencies"](this.resourceCurrencies);
}
if(this.resourceItemTypes.length > 0)
{
ga["configureAvailableResourceItemTypes"](this.resourceItemTypes);
}
ga["configureBuild"](this.build);
if(this.autoDetectAppVersion)
{
ga["configureAutoDetectAppVersion"](true);
}
var sdkVersion = "construct " + VERSION;
var gameKey = window["device"]["platform"] === "Android" ? this.gameKeyAndroid : this.gameKeyIOS;
var secretKey = window["device"]["platform"] === "Android" ? this.secretKeyAndroid : this.secretKeyIOS;
ga["initialize"]({
"gameKey": gameKey,
"secretKey": secretKey,
"sdkVersion": sdkVersion
});
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
var ga = window["gameanalytics"]["GameAnalytics"];
if(this.enableInfoLog)
{
ga["setEnabledInfoLog"](true);
}
if(this.enableVerboseLog)
{
ga["setEnabledVerboseLog"](true);
}
if(this.enableManualSessionHandling)
{
ga["setEnabledManualSessionHandling"](true);
}
if(this.customDimensions01.length > 0)
{
ga["configureAvailableCustomDimensions01"](this.customDimensions01);
}
if(this.customDimensions02.length > 0)
{
ga["configureAvailableCustomDimensions02"](this.customDimensions02);
}
if(this.customDimensions03.length > 0)
{
ga["configureAvailableCustomDimensions03"](this.customDimensions03);
}
if(this.resourceCurrencies.length > 0)
{
ga["configureAvailableResourceCurrencies"](this.resourceCurrencies);
}
if(this.resourceItemTypes.length > 0)
{
ga["configureAvailableResourceItemTypes"](this.resourceItemTypes);
}
ga["configureBuild"](this.build);
ga["configureSdkGameEngineVersion"]("construct " + VERSION);
ga["initialize"](this.gameKeyBrowser, this.secretKeyBrowser);
}
else
{
console.log("initialize: GameAnalytics object not found");
return;
}
};
Acts.prototype.addBusinessEvent = function (currency, amount, itemType, itemId, cartType)
{
if(typeof window["GameAnalytics"]["addBusinessEvent"] == "function")
{
window["GameAnalytics"]["addBusinessEvent"]({
"currency": currency,
"amount": amount,
"itemType": itemType,
"itemId": itemId,
"cartType": cartType
});
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["addBusinessEvent"](currency, amount, itemType, itemId, cartType);
}
else
{
console.log("addBusinessEvent: GameAnalytics object not found");
return;
}
};
Acts.prototype.addResourceEvent = function (flowType, currency, amount, itemType, itemId)
{
if(typeof window["GameAnalytics"]["addResourceEvent"] == "function")
{
window["GameAnalytics"]["addResourceEvent"]({
"flowType": flowType,
"currency": currency,
"amount": amount,
"itemType": itemType,
"itemId": itemId
});
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["addResourceEvent"](flowType, currency, amount, itemType, itemId);
}
else
{
console.log("addResourceEvent: GameAnalytics object not found");
return;
}
};
Acts.prototype.addProgressionEvent = function (progressionStatus, progression01, progression02, progression03)
{
if(typeof window["GameAnalytics"]["addProgressionEvent"] == "function")
{
window["GameAnalytics"]["addProgressionEvent"]({
"progressionStatus": progressionStatus,
"progression01": progression01,
"progression02": progression02,
"progression03": progression03
});
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["addProgressionEvent"](progressionStatus, progression01, progression02, progression03);
}
else
{
console.log("addProgressionEvent: GameAnalytics object not found");
return;
}
};
Acts.prototype.addProgressionEventWithScore = function (progressionStatus, progression01, progression02, progression03, score)
{
if(typeof window["GameAnalytics"]["addProgressionEvent"] == "function")
{
window["GameAnalytics"]["addProgressionEvent"]({
"progressionStatus": progressionStatus,
"progression01": progression01,
"progression02": progression02,
"progression03": progression03,
"score": score
});
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["addProgressionEvent"](progressionStatus, progression01, progression02, progression03, score);
}
else
{
console.log("addProgressionEventWithScore: GameAnalytics object not found");
return;
}
};
Acts.prototype.addDesignEvent = function (eventId)
{
if(typeof window["GameAnalytics"]["addDesignEvent"] == "function")
{
window["GameAnalytics"]["addDesignEvent"]({
"eventId": eventId
});
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["addDesignEvent"](eventId);
}
else
{
console.log("addDesignEvent: GameAnalytics object not found");
return;
}
};
Acts.prototype.addDesignEventWithValue = function (eventId, value)
{
if(typeof window["GameAnalytics"]["addDesignEvent"] == "function")
{
window["GameAnalytics"]["addDesignEvent"]({
"eventId": eventId,
"value": value
});
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["addDesignEvent"](eventId, value);
}
else
{
console.log("addDesignEventWithValue: GameAnalytics object not found");
return;
}
};
Acts.prototype.addErrorEvent = function (severity, message)
{
if(typeof window["GameAnalytics"]["addErrorEvent"] == "function")
{
window["GameAnalytics"]["addErrorEvent"]({
"severity": severity,
"message": message
});
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["addErrorEvent"](severity, message);
}
else
{
console.log("addErrorEvent: GameAnalytics object not found");
return;
}
};
Acts.prototype.setEnabledEventSubmission = function (flag)
{
if(typeof window["GameAnalytics"]["setEnabledEventSubmission"] == "function")
{
window["GameAnalytics"]["setEnabledEventSubmission"](flag ? true : false);
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["setEnabledEventSubmission"](flag ? true : false);
}
else
{
console.log("setEnabledEventSubmission: GameAnalytics object not found");
return;
}
};
Acts.prototype.setEnabledManualSessionHandling = function (flag)
{
if(typeof window["GameAnalytics"]["setEnabledManualSessionHandling"] == "function")
{
window["GameAnalytics"]["setEnabledManualSessionHandling"](flag ? true : false);
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["setEnabledManualSessionHandling"](flag ? true : false);
}
else
{
console.log("setEnabledManualSessionHandling: GameAnalytics object not found");
return;
}
};
Acts.prototype.setCustomDimension01 = function (dimension)
{
if(typeof window["GameAnalytics"]["setCustomDimension01"] == "function")
{
window["GameAnalytics"]["setCustomDimension01"](dimension);
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["setCustomDimension01"](dimension);
}
else
{
console.log("setCustomDimension01: GameAnalytics object not found");
return;
}
};
Acts.prototype.setCustomDimension02 = function (dimension)
{
if(typeof window["GameAnalytics"]["setCustomDimension02"] == "function")
{
window["GameAnalytics"]["setCustomDimension02"](dimension);
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["setCustomDimension02"](dimension);
}
else
{
console.log("setCustomDimension02: GameAnalytics object not found");
return;
}
};
Acts.prototype.setCustomDimension03 = function (dimension)
{
if(typeof window["GameAnalytics"]["setCustomDimension03"] == "function")
{
window["GameAnalytics"]["setCustomDimension03"](dimension);
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["setCustomDimension03"](dimension);
}
else
{
console.log("setCustomDimension03: GameAnalytics object not found");
return;
}
};
Acts.prototype.startSession = function ()
{
if(typeof window["GameAnalytics"]["startSession"] == "function")
{
window["GameAnalytics"]["startSession"]();
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["startSession"]();
}
else
{
console.log("startSession: GameAnalytics object not found");
return;
}
};
Acts.prototype.endSession = function ()
{
if(typeof window["GameAnalytics"]["endSession"] == "function")
{
window["GameAnalytics"]["endSession"]();
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
window["gameanalytics"]["GameAnalytics"]["endSession"]();
}
else
{
console.log("endSession: GameAnalytics object not found");
return;
}
};
Acts.prototype.configureBuild = function (buildNumber)
{
this.build = buildNumber;
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.getRemoteConfigsValueAsString = function (ret, key, defaultValue, functionName)
{
if(typeof window["GameAnalytics"]["getRemoteConfigsValueAsString"] == "function")
{
var callback = function(result) {
if(functionName && window["c2_callFunction"]) {
window["c2_callFunction"](functionName, [result]);
}
}
window["GameAnalytics"]["getRemoteConfigsValueAsString"]({
"key": key,
"defaultValue": defaultValue
}, );
ret.set_string("");
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
ret.set_string(window["gameanalytics"]["GameAnalytics"]["getRemoteConfigsValueAsString"](key, defaultValue));
}
else
{
console.log("getRemoteConfigsValueAsString: GameAnalytics object not found");
ret.set_string("");
}
};
Exps.prototype.getRemoteConfigsContentAsString = function (ret, functionName)
{
if(typeof window["GameAnalytics"]["getRemoteConfigsContentAsString"] == "function")
{
var callback = function(result) {
if(functionName && window["c2_callFunction"]) {
window["c2_callFunction"](functionName, [result]);
}
}
window["GameAnalytics"]["getRemoteConfigsContentAsString"](callback);
ret.set_string("");
}
else if(typeof window["gameanalytics"]["GameAnalytics"] != "undefined")
{
ret.set_string(window["gameanalytics"]["GameAnalytics"]["getRemoteConfigsContentAsString"]());
}
else
{
console.log("endSession: GameAnalytics object not found");
ret.set_string("");
}
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.Globals = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Globals.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.defaultVarsValues = JSON.stringify(this.instance_vars);
};
instanceProto.saveToJSON = function ()
{
return {
"v": JSON.stringify(this.instance_vars)
};
};
instanceProto.loadFromJSON = function (o)
{
this.instance_vars = JSON.parse(o["v"]);
};
function Cnds() {};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.ResetVariables = function()
{
this.instance_vars = JSON.parse(this.defaultVarsValues);
};
Acts.prototype.LoadVariables = function(varsJSON_)
{
this.instance_vars = JSON.parse(varsJSON_);
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.GetVariablesAsJSON = function(ret)
{
ret.set_string(JSON.stringify(this.instance_vars));
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.Keyboard = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Keyboard.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
this.keyMap = new Array(256); // stores key up/down state
this.usedKeys = new Array(256);
this.triggerKey = 0;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
var self = this;
if (!this.runtime.isDomFree)
{
jQuery(document).keydown(
function(info) {
self.onKeyDown(info);
}
);
jQuery(document).keyup(
function(info) {
self.onKeyUp(info);
}
);
}
};
var keysToBlockWhenFramed = [32, 33, 34, 35, 36, 37, 38, 39, 40, 44];
instanceProto.onKeyDown = function (info)
{
var alreadyPreventedDefault = false;
if (window != window.top && keysToBlockWhenFramed.indexOf(info.which) > -1)
{
info.preventDefault();
alreadyPreventedDefault = true;
info.stopPropagation();
}
if (this.keyMap[info.which])
{
if (this.usedKeys[info.which] && !alreadyPreventedDefault)
info.preventDefault();
return;
}
this.keyMap[info.which] = true;
this.triggerKey = info.which;
this.runtime.isInUserInputEvent = true;
this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnAnyKey, this);
var eventRan = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKey, this);
var eventRan2 = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyCode, this);
this.runtime.isInUserInputEvent = false;
if (eventRan || eventRan2)
{
this.usedKeys[info.which] = true;
if (!alreadyPreventedDefault)
info.preventDefault();
}
};
instanceProto.onKeyUp = function (info)
{
this.keyMap[info.which] = false;
this.triggerKey = info.which;
this.runtime.isInUserInputEvent = true;
this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnAnyKeyReleased, this);
var eventRan = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyReleased, this);
var eventRan2 = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyCodeReleased, this);
this.runtime.isInUserInputEvent = false;
if (eventRan || eventRan2 || this.usedKeys[info.which])
{
this.usedKeys[info.which] = true;
info.preventDefault();
}
};
instanceProto.onWindowBlur = function ()
{
var i;
for (i = 0; i < 256; ++i)
{
if (!this.keyMap[i])
continue; // key already up
this.keyMap[i] = false;
this.triggerKey = i;
this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnAnyKeyReleased, this);
var eventRan = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyReleased, this);
var eventRan2 = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyCodeReleased, this);
if (eventRan || eventRan2)
this.usedKeys[i] = true;
}
};
instanceProto.saveToJSON = function ()
{
return { "triggerKey": this.triggerKey };
};
instanceProto.loadFromJSON = function (o)
{
this.triggerKey = o["triggerKey"];
};
function Cnds() {};
Cnds.prototype.IsKeyDown = function(key)
{
return this.keyMap[key];
};
Cnds.prototype.OnKey = function(key)
{
return (key === this.triggerKey);
};
Cnds.prototype.OnAnyKey = function(key)
{
return true;
};
Cnds.prototype.OnAnyKeyReleased = function(key)
{
return true;
};
Cnds.prototype.OnKeyReleased = function(key)
{
return (key === this.triggerKey);
};
Cnds.prototype.IsKeyCodeDown = function(key)
{
key = Math.floor(key);
if (key < 0 || key >= this.keyMap.length)
return false;
return this.keyMap[key];
};
Cnds.prototype.OnKeyCode = function(key)
{
return (key === this.triggerKey);
};
Cnds.prototype.OnKeyCodeReleased = function(key)
{
return (key === this.triggerKey);
};
pluginProto.cnds = new Cnds();
function Acts() {};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.LastKeyCode = function (ret)
{
ret.set_int(this.triggerKey);
};
function fixedStringFromCharCode(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 "←";
case 38: return "↑";
case 39: return "→";
case 40: return "↓";
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);
}
};
Exps.prototype.StringFromKeyCode = function (ret, kc)
{
ret.set_string(fixedStringFromCharCode(kc));
};
pluginProto.exps = new Exps();
}());
;
;
var localForageInitFailed = false;
try {
/*!
localForage -- Offline Storage, Improved
Version 1.4.0
https://mozilla.github.io/localForage
(c) 2013-2015 Mozilla, Apache License 2.0
*/
!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)"exports"===i[l]?k.push(g={}):k.push(b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:void 0===this?window:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:void(c[a]=b)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a;a="undefined"!=typeof global?global:"undefined"!=typeof window&&window.document?window:self;var b="Promise"in a&&"resolve"in a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;return new a.Promise(function(a){b=a}),f(b)}();b||(a.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h){"use strict";function i(a){if(!v(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof i))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],j(a,this)}function j(a,b){function c(a){o(b,a)}function d(a){q(b,a)}try{a(c,d)}catch(e){d(e)}}function k(a,b,c,d){var e,f,g,h,i=v(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;n(b,e)||(i&&g?o(b,e):h?q(b,f):a===D?o(b,e):a===E&&q(b,e))}function l(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+D]=c,e[f+E]=d}function m(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],k(b,c,d,f);a._subscribers=null}function n(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(u(b)&&(d=b.then,v(d)))return d.call(b,function(d){return c?!0:(c=!0,void(b!==d?o(a,d):p(a,d)))},function(b){return c?!0:(c=!0,void q(a,b))}),!0}catch(e){return c?!0:(q(a,e),!0)}return!1}function o(a,b){a===b?p(a,b):n(a,b)||p(a,b)}function p(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(r,a))}function q(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(s,a))}function r(a){m(a,a._state=D)}function s(a){m(a,a._state=E)}var t=a.config,u=(a.configure,b.objectOrFunction),v=b.isFunction,w=(b.now,c.all),x=d.race,y=e.resolve,z=f.reject,A=g.asap;t.async=A;var B=void 0,C=0,D=1,E=2;i.prototype={constructor:i,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;t.async(function(){k(c._state,d,e[c._state-1],c._detail)})}else l(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},i.all=w,i.race=x,i.resolve=y,i.reject=z,h.Promise=i}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}(),function(a,b){"object"==typeof exports&&"object"==typeof module?module.exports=b():"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?exports.localforage=b():a.localforage=b()}(this,function(){return function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}b.__esModule=!0;var e=function(a){function b(a,b){a[b]=function(){var c=arguments;return a.ready().then(function(){return a[b].apply(a,c)})}}function e(){for(var a=1;a<arguments.length;a++){var b=arguments[a];if(b)for(var c in b)b.hasOwnProperty(c)&&(m(b[c])?arguments[0][c]=b[c].slice():arguments[0][c]=b[c])}return arguments[0]}function f(a){for(var b in h)if(h.hasOwnProperty(b)&&h[b]===a)return!0;return!1}var g={},h={INDEXEDDB:"asyncStorage",LOCALSTORAGE:"localStorageWrapper",WEBSQL:"webSQLStorage"},i=[h.INDEXEDDB,h.WEBSQL,h.LOCALSTORAGE],j=["clear","getItem","iterate","key","keys","length","removeItem","setItem"],k={description:"",driver:i.slice(),name:"localforage",size:4980736,storeName:"keyvaluepairs",version:1},l=function(a){var b={};return b[h.INDEXEDDB]=!!function(){try{var b=b||a.indexedDB||a.webkitIndexedDB||a.mozIndexedDB||a.OIndexedDB||a.msIndexedDB;return"undefined"!=typeof a.openDatabase&&a.navigator&&a.navigator.userAgent&&/Safari/.test(a.navigator.userAgent)&&!/Chrome/.test(a.navigator.userAgent)?!1:b&&"function"==typeof b.open&&"undefined"!=typeof a.IDBKeyRange}catch(c){return!1}}(),b[h.WEBSQL]=!!function(){try{return a.openDatabase}catch(b){return!1}}(),b[h.LOCALSTORAGE]=!!function(){try{return a.localStorage&&"setItem"in a.localStorage&&a.localStorage.setItem}catch(b){return!1}}(),b}(a),m=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},n=function(){function a(b){d(this,a),this.INDEXEDDB=h.INDEXEDDB,this.LOCALSTORAGE=h.LOCALSTORAGE,this.WEBSQL=h.WEBSQL,this._defaultConfig=e({},k),this._config=e({},this._defaultConfig,b),this._driverSet=null,this._initDriver=null,this._ready=!1,this._dbInfo=null,this._wrapLibraryMethodsWithReady(),this.setDriver(this._config.driver)}return a.prototype.config=function(a){if("object"==typeof a){if(this._ready)return new Error("Can't call config() after localforage has been used.");for(var b in a)"storeName"===b&&(a[b]=a[b].replace(/\W/g,"_")),this._config[b]=a[b];return"driver"in a&&a.driver&&this.setDriver(this._config.driver),!0}return"string"==typeof a?this._config[a]:this._config},a.prototype.defineDriver=function(a,b,c){var d=new Promise(function(b,c){try{var d=a._driver,e=new Error("Custom driver not compliant; see https://mozilla.github.io/localForage/#definedriver"),h=new Error("Custom driver name already in use: "+a._driver);if(!a._driver)return void c(e);if(f(a._driver))return void c(h);for(var i=j.concat("_initStorage"),k=0;k<i.length;k++){var m=i[k];if(!m||!a[m]||"function"!=typeof a[m])return void c(e)}var n=Promise.resolve(!0);"_support"in a&&(n=a._support&&"function"==typeof a._support?a._support():Promise.resolve(!!a._support)),n.then(function(c){l[d]=c,g[d]=a,b()},c)}catch(o){c(o)}});return d.then(b,c),d},a.prototype.driver=function(){return this._driver||null},a.prototype.getDriver=function(a,b,d){var e=this,h=function(){if(f(a))switch(a){case e.INDEXEDDB:return new Promise(function(a,b){a(c(1))});case e.LOCALSTORAGE:return new Promise(function(a,b){a(c(2))});case e.WEBSQL:return new Promise(function(a,b){a(c(4))})}else if(g[a])return Promise.resolve(g[a]);return Promise.reject(new Error("Driver not found."))}();return h.then(b,d),h},a.prototype.getSerializer=function(a){var b=new Promise(function(a,b){a(c(3))});return a&&"function"==typeof a&&b.then(function(b){a(b)}),b},a.prototype.ready=function(a){var b=this,c=b._driverSet.then(function(){return null===b._ready&&(b._ready=b._initDriver()),b._ready});return c.then(a,a),c},a.prototype.setDriver=function(a,b,c){function d(){f._config.driver=f.driver()}function e(a){return function(){function b(){for(;c<a.length;){var e=a[c];return c++,f._dbInfo=null,f._ready=null,f.getDriver(e).then(function(a){return f._extend(a),d(),f._ready=f._initStorage(f._config),f._ready})["catch"](b)}d();var g=new Error("No available storage method found.");return f._driverSet=Promise.reject(g),f._driverSet}var c=0;return b()}}var f=this;m(a)||(a=[a]);var g=this._getSupportedDrivers(a),h=null!==this._driverSet?this._driverSet["catch"](function(){return Promise.resolve()}):Promise.resolve();return this._driverSet=h.then(function(){var a=g[0];return f._dbInfo=null,f._ready=null,f.getDriver(a).then(function(a){f._driver=a._driver,d(),f._wrapLibraryMethodsWithReady(),f._initDriver=e(g)})})["catch"](function(){d();var a=new Error("No available storage method found.");return f._driverSet=Promise.reject(a),f._driverSet}),this._driverSet.then(b,c),this._driverSet},a.prototype.supports=function(a){return!!l[a]},a.prototype._extend=function(a){e(this,a)},a.prototype._getSupportedDrivers=function(a){for(var b=[],c=0,d=a.length;d>c;c++){var e=a[c];this.supports(e)&&b.push(e)}return b},a.prototype._wrapLibraryMethodsWithReady=function(){for(var a=0;a<j.length;a++)b(this,j[a])},a.prototype.createInstance=function(b){return new a(b)},a}();return new n}("undefined"!=typeof window?window:self);b["default"]=e,a.exports=b["default"]},function(a,b){"use strict";b.__esModule=!0;var c=function(a){function b(b,c){b=b||[],c=c||{};try{return new Blob(b,c)}catch(d){if("TypeError"!==d.name)throw d;for(var e=a.BlobBuilder||a.MSBlobBuilder||a.MozBlobBuilder||a.WebKitBlobBuilder,f=new e,g=0;g<b.length;g+=1)f.append(b[g]);return f.getBlob(c.type)}}function c(a){for(var b=a.length,c=new ArrayBuffer(b),d=new Uint8Array(c),e=0;b>e;e++)d[e]=a.charCodeAt(e);return c}function d(a){return new Promise(function(b,c){var d=new XMLHttpRequest;d.open("GET",a),d.withCredentials=!0,d.responseType="arraybuffer",d.onreadystatechange=function(){return 4===d.readyState?200===d.status?b({response:d.response,type:d.getResponseHeader("Content-Type")}):void c({status:d.status,response:d.response}):void 0},d.send()})}function e(a){return new Promise(function(c,e){var f=b([""],{type:"image/png"}),g=a.transaction([D],"readwrite");g.objectStore(D).put(f,"key"),g.oncomplete=function(){var b=a.transaction([D],"readwrite"),f=b.objectStore(D).get("key");f.onerror=e,f.onsuccess=function(a){var b=a.target.result,e=URL.createObjectURL(b);d(e).then(function(a){c(!(!a||"image/png"!==a.type))},function(){c(!1)}).then(function(){URL.revokeObjectURL(e)})}},g.onerror=g.onabort=e})["catch"](function(){return!1})}function f(a){return"boolean"==typeof B?Promise.resolve(B):e(a).then(function(a){return B=a})}function g(a){return new Promise(function(b,c){var d=new FileReader;d.onerror=c,d.onloadend=function(c){var d=btoa(c.target.result||"");b({__local_forage_encoded_blob:!0,data:d,type:a.type})},d.readAsBinaryString(a)})}function h(a){var d=c(atob(a.data));return b([d],{type:a.type})}function i(a){return a&&a.__local_forage_encoded_blob}function j(a){var b=this,c=b._initReady().then(function(){var a=C[b._dbInfo.name];return a&&a.dbReady?a.dbReady:void 0});return c.then(a,a),c}function k(a){var b=C[a.name],c={};c.promise=new Promise(function(a){c.resolve=a}),b.deferredOperations.push(c),b.dbReady?b.dbReady=b.dbReady.then(function(){return c.promise}):b.dbReady=c.promise}function l(a){var b=C[a.name],c=b.deferredOperations.pop();c&&c.resolve()}function m(a){function b(){return Promise.resolve()}var c=this,d={db:null};if(a)for(var e in a)d[e]=a[e];C||(C={});var f=C[d.name];f||(f={forages:[],db:null,dbReady:null,deferredOperations:[]},C[d.name]=f),f.forages.push(c),c._initReady||(c._initReady=c.ready,c.ready=j);for(var g=[],h=0;h<f.forages.length;h++){var i=f.forages[h];i!==c&&g.push(i._initReady()["catch"](b))}var k=f.forages.slice(0);return Promise.all(g).then(function(){return d.db=f.db,n(d)}).then(function(a){return d.db=a,q(d,c._defaultConfig.version)?o(d):a}).then(function(a){d.db=f.db=a,c._dbInfo=d;for(var b=0;b<k.length;b++){var e=k[b];e!==c&&(e._dbInfo.db=d.db,e._dbInfo.version=d.version)}})}function n(a){return p(a,!1)}function o(a){return p(a,!0)}function p(b,c){return new Promise(function(d,e){if(b.db){if(!c)return d(b.db);k(b),b.db.close()}var f=[b.name];c&&f.push(b.version);var g=A.open.apply(A,f);c&&(g.onupgradeneeded=function(c){var d=g.result;try{d.createObjectStore(b.storeName),c.oldVersion<=1&&d.createObjectStore(D)}catch(e){if("ConstraintError"!==e.name)throw e;a.console.warn('The database "'+b.name+'" has been upgraded from version '+c.oldVersion+" to version "+c.newVersion+', but the storage "'+b.storeName+'" already exists.')}}),g.onerror=function(){e(g.error)},g.onsuccess=function(){d(g.result),l(b)}})}function q(b,c){if(!b.db)return!0;var d=!b.db.objectStoreNames.contains(b.storeName),e=b.version<b.db.version,f=b.version>b.db.version;if(e&&(b.version!==c&&a.console.warn('The database "'+b.name+"\" can't be downgraded from version "+b.db.version+" to version "+b.version+"."),b.version=b.db.version),f||d){if(d){var g=b.db.version+1;g>b.version&&(b.version=g)}return!0}return!1}function r(b,c){var d=this;"string"!=typeof b&&(a.console.warn(b+" used as a key, but it is not a string."),b=String(b));var e=new Promise(function(a,c){d.ready().then(function(){var e=d._dbInfo,f=e.db.transaction(e.storeName,"readonly").objectStore(e.storeName),g=f.get(b);g.onsuccess=function(){var b=g.result;void 0===b&&(b=null),i(b)&&(b=h(b)),a(b)},g.onerror=function(){c(g.error)}})["catch"](c)});return z(e,c),e}function s(a,b){var c=this,d=new Promise(function(b,d){c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readonly").objectStore(e.storeName),g=f.openCursor(),j=1;g.onsuccess=function(){var c=g.result;if(c){var d=c.value;i(d)&&(d=h(d));var e=a(d,c.key,j++);void 0!==e?b(e):c["continue"]()}else b()},g.onerror=function(){d(g.error)}})["catch"](d)});return z(d,b),d}function t(b,c,d){var e=this;"string"!=typeof b&&(a.console.warn(b+" used as a key, but it is not a string."),b=String(b));var h=new Promise(function(a,d){var h;e.ready().then(function(){return h=e._dbInfo,c instanceof Blob?f(h.db).then(function(a){return a?c:g(c)}):c}).then(function(c){var e=h.db.transaction(h.storeName,"readwrite"),f=e.objectStore(h.storeName);null===c&&(c=void 0),e.oncomplete=function(){void 0===c&&(c=null),a(c)},e.onabort=e.onerror=function(){var a=g.error?g.error:g.transaction.error;d(a)};var g=f.put(c,b)})["catch"](d)});return z(h,d),h}function u(b,c){var d=this;"string"!=typeof b&&(a.console.warn(b+" used as a key, but it is not a string."),b=String(b));var e=new Promise(function(a,c){d.ready().then(function(){var e=d._dbInfo,f=e.db.transaction(e.storeName,"readwrite"),g=f.objectStore(e.storeName),h=g["delete"](b);f.oncomplete=function(){a()},f.onerror=function(){c(h.error)},f.onabort=function(){var a=h.error?h.error:h.transaction.error;c(a)}})["catch"](c)});return z(e,c),e}function v(a){var b=this,c=new Promise(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readwrite"),f=e.objectStore(d.storeName),g=f.clear();e.oncomplete=function(){a()},e.onabort=e.onerror=function(){var a=g.error?g.error:g.transaction.error;c(a)}})["catch"](c)});return z(c,a),c}function w(a){var b=this,c=new Promise(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readonly").objectStore(d.storeName),f=e.count();f.onsuccess=function(){a(f.result)},f.onerror=function(){c(f.error)}})["catch"](c)});return z(c,a),c}function x(a,b){var c=this,d=new Promise(function(b,d){return 0>a?void b(null):void c.ready().then(function(){var e=c._dbInfo,f=e.db.transaction(e.storeName,"readonly").objectStore(e.storeName),g=!1,h=f.openCursor();h.onsuccess=function(){var c=h.result;return c?void(0===a?b(c.key):g?b(c.key):(g=!0,c.advance(a))):void b(null)},h.onerror=function(){d(h.error)}})["catch"](d)});return z(d,b),d}function y(a){var b=this,c=new Promise(function(a,c){b.ready().then(function(){var d=b._dbInfo,e=d.db.transaction(d.storeName,"readonly").objectStore(d.storeName),f=e.openCursor(),g=[];f.onsuccess=function(){var b=f.result;return b?(g.push(b.key),void b["continue"]()):void a(g)},f.onerror=function(){c(f.error)}})["catch"](c)});return z(c,a),c}function z(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}var A=A||a.indexedDB||a.webkitIndexedDB||a.mozIndexedDB||a.OIndexedDB||a.msIndexedDB;if(A){var B,C,D="local-forage-detect-blob-support",E={_driver:"asyncStorage",_initStorage:m,iterate:s,getItem:r,setItem:t,removeItem:u,clear:v,length:w,key:x,keys:y};return E}}("undefined"!=typeof window?window:self);b["default"]=c,a.exports=b["default"]},function(a,b,c){"use strict";b.__esModule=!0;var d=function(a){function b(a){var b=this,d={};if(a)for(var e in a)d[e]=a[e];return d.keyPrefix=d.name+"/",d.storeName!==b._defaultConfig.storeName&&(d.keyPrefix+=d.storeName+"/"),b._dbInfo=d,new Promise(function(a,b){a(c(3))}).then(function(a){return d.serializer=a,Promise.resolve()})}function d(a){var b=this,c=b.ready().then(function(){for(var a=b._dbInfo.keyPrefix,c=m.length-1;c>=0;c--){var d=m.key(c);0===d.indexOf(a)&&m.removeItem(d)}});return l(c,a),c}function e(b,c){var d=this;"string"!=typeof b&&(a.console.warn(b+" used as a key, but it is not a string."),b=String(b));var e=d.ready().then(function(){var a=d._dbInfo,c=m.getItem(a.keyPrefix+b);return c&&(c=a.serializer.deserialize(c)),c});return l(e,c),e}function f(a,b){var c=this,d=c.ready().then(function(){for(var b=c._dbInfo,d=b.keyPrefix,e=d.length,f=m.length,g=1,h=0;f>h;h++){var i=m.key(h);if(0===i.indexOf(d)){var j=m.getItem(i);if(j&&(j=b.serializer.deserialize(j)),j=a(j,i.substring(e),g++),void 0!==j)return j}}});return l(d,b),d}function g(a,b){var c=this,d=c.ready().then(function(){var b,d=c._dbInfo;try{b=m.key(a)}catch(e){b=null}return b&&(b=b.substring(d.keyPrefix.length)),b});return l(d,b),d}function h(a){var b=this,c=b.ready().then(function(){for(var a=b._dbInfo,c=m.length,d=[],e=0;c>e;e++)0===m.key(e).indexOf(a.keyPrefix)&&d.push(m.key(e).substring(a.keyPrefix.length));return d});return l(c,a),c}function i(a){var b=this,c=b.keys().then(function(a){return a.length});return l(c,a),c}function j(b,c){var d=this;"string"!=typeof b&&(a.console.warn(b+" used as a key, but it is not a string."),b=String(b));var e=d.ready().then(function(){var a=d._dbInfo;m.removeItem(a.keyPrefix+b)});return l(e,c),e}function k(b,c,d){var e=this;"string"!=typeof b&&(a.console.warn(b+" used as a key, but it is not a string."),b=String(b));var f=e.ready().then(function(){void 0===c&&(c=null);var a=c;return new Promise(function(d,f){var g=e._dbInfo;g.serializer.serialize(c,function(c,e){if(e)f(e);else try{m.setItem(g.keyPrefix+b,c),d(a)}catch(h){("QuotaExceededError"===h.name||"NS_ERROR_DOM_QUOTA_REACHED"===h.name)&&f(h),f(h)}})})});return l(f,d),f}function l(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}var m=null;try{if(!(a.localStorage&&"setItem"in a.localStorage))return;m=a.localStorage}catch(n){return}var o={_driver:"localStorageWrapper",_initStorage:b,iterate:f,getItem:e,setItem:k,removeItem:j,clear:d,length:i,key:g,keys:h};return o}("undefined"!=typeof window?window:self);b["default"]=d,a.exports=b["default"]},function(a,b){"use strict";b.__esModule=!0;var c=function(a){function b(b,c){b=b||[],c=c||{};try{return new Blob(b,c)}catch(d){if("TypeError"!==d.name)throw d;for(var e=a.BlobBuilder||a.MSBlobBuilder||a.MozBlobBuilder||a.WebKitBlobBuilder,f=new e,g=0;g<b.length;g+=1)f.append(b[g]);return f.getBlob(c.type)}}function c(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=j;a instanceof ArrayBuffer?(d=a,e+=l):(d=a.buffer,"[object Int8Array]"===c?e+=n:"[object Uint8Array]"===c?e+=o:"[object Uint8ClampedArray]"===c?e+=p:"[object Int16Array]"===c?e+=q:"[object Uint16Array]"===c?e+=s:"[object Int32Array]"===c?e+=r:"[object Uint32Array]"===c?e+=t:"[object Float32Array]"===c?e+=u:"[object Float64Array]"===c?e+=v:b(new Error("Failed to get type for BinaryArray"))),b(e+f(d))}else if("[object Blob]"===c){var g=new FileReader;g.onload=function(){var c=h+a.type+"~"+f(this.result);b(j+m+c)},g.readAsArrayBuffer(a)}else try{b(JSON.stringify(a))}catch(i){console.error("Couldn't convert value into a JSON string: ",a),b(null,i)}}function d(a){if(a.substring(0,k)!==j)return JSON.parse(a);var c,d=a.substring(w),f=a.substring(k,w);if(f===m&&i.test(d)){var g=d.match(i);c=g[1],d=d.substring(g[0].length)}var h=e(d);switch(f){case l:return h;case m:return b([h],{type:c});case n:return new Int8Array(h);case o:return new Uint8Array(h);case p:return new Uint8ClampedArray(h);case q:return new Int16Array(h);case s:return new Uint16Array(h);case r:return new Int32Array(h);case t:return new Uint32Array(h);case u:return new Float32Array(h);case v:return new Float64Array(h);default:throw new Error("Unkown type: "+f)}}function e(a){var b,c,d,e,f,h=.75*a.length,i=a.length,j=0;"="===a[a.length-1]&&(h--,"="===a[a.length-2]&&h--);var k=new ArrayBuffer(h),l=new Uint8Array(k);for(b=0;i>b;b+=4)c=g.indexOf(a[b]),d=g.indexOf(a[b+1]),e=g.indexOf(a[b+2]),f=g.indexOf(a[b+3]),l[j++]=c<<2|d>>4,l[j++]=(15&d)<<4|e>>2,l[j++]=(3&e)<<6|63&f;return k}function f(a){var b,c=new Uint8Array(a),d="";for(b=0;b<c.length;b+=3)d+=g[c[b]>>2],d+=g[(3&c[b])<<4|c[b+1]>>4],d+=g[(15&c[b+1])<<2|c[b+2]>>6],d+=g[63&c[b+2]];return c.length%3===2?d=d.substring(0,d.length-1)+"=":c.length%3===1&&(d=d.substring(0,d.length-2)+"=="),d}var g="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",h="~~local_forage_type~",i=/^~~local_forage_type~([^~]+)~/,j="__lfsc__:",k=j.length,l="arbf",m="blob",n="si08",o="ui08",p="uic8",q="si16",r="si32",s="ur16",t="ui32",u="fl32",v="fl64",w=k+l.length,x={serialize:c,deserialize:d,stringToBuffer:e,bufferToString:f};return x}("undefined"!=typeof window?window:self);b["default"]=c,a.exports=b["default"]},function(a,b,c){"use strict";b.__esModule=!0;var d=function(a){function b(a){var b=this,d={db:null};if(a)for(var e in a)d[e]="string"!=typeof a[e]?a[e].toString():a[e];var f=new Promise(function(a,c){try{d.db=m(d.name,String(d.version),d.description,d.size)}catch(e){return c(e)}d.db.transaction(function(e){e.executeSql("CREATE TABLE IF NOT EXISTS "+d.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){b._dbInfo=d,a()},function(a,b){c(b)})})});return new Promise(function(a,b){a(c(3))}).then(function(a){return d.serializer=a,f})}function d(b,c){var d=this;"string"!=typeof b&&(a.console.warn(b+" used as a key, but it is not a string."),b=String(b));var e=new Promise(function(a,c){d.ready().then(function(){var e=d._dbInfo;e.db.transaction(function(d){d.executeSql("SELECT * FROM "+e.storeName+" WHERE key = ? LIMIT 1",[b],function(b,c){var d=c.rows.length?c.rows.item(0).value:null;d&&(d=e.serializer.deserialize(d)),a(d)},function(a,b){c(b)})})})["catch"](c)});return l(e,c),e}function e(a,b){var c=this,d=new Promise(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("SELECT * FROM "+e.storeName,[],function(c,d){for(var f=d.rows,g=f.length,h=0;g>h;h++){var i=f.item(h),j=i.value;if(j&&(j=e.serializer.deserialize(j)),j=a(j,i.key,h+1),void 0!==j)return void b(j)}b()},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function f(b,c,d){var e=this;"string"!=typeof b&&(a.console.warn(b+" used as a key, but it is not a string."),b=String(b));var f=new Promise(function(a,d){e.ready().then(function(){void 0===c&&(c=null);var f=c,g=e._dbInfo;g.serializer.serialize(c,function(c,e){e?d(e):g.db.transaction(function(e){e.executeSql("INSERT OR REPLACE INTO "+g.storeName+" (key, value) VALUES (?, ?)",[b,c],function(){a(f)},function(a,b){d(b)})},function(a){a.code===a.QUOTA_ERR&&d(a)})})})["catch"](d)});return l(f,d),f}function g(b,c){var d=this;"string"!=typeof b&&(a.console.warn(b+" used as a key, but it is not a string."),b=String(b));var e=new Promise(function(a,c){d.ready().then(function(){var e=d._dbInfo;e.db.transaction(function(d){d.executeSql("DELETE FROM "+e.storeName+" WHERE key = ?",[b],function(){a()},function(a,b){c(b)})})})["catch"](c)});return l(e,c),e}function h(a){var b=this,c=new Promise(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("DELETE FROM "+d.storeName,[],function(){a()},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function i(a){var b=this,c=new Promise(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("SELECT COUNT(key) as c FROM "+d.storeName,[],function(b,c){var d=c.rows.item(0).c;a(d)},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function j(a,b){var c=this,d=new Promise(function(b,d){c.ready().then(function(){var e=c._dbInfo;e.db.transaction(function(c){c.executeSql("SELECT key FROM "+e.storeName+" WHERE id = ? LIMIT 1",[a+1],function(a,c){var d=c.rows.length?c.rows.item(0).key:null;b(d)},function(a,b){d(b)})})})["catch"](d)});return l(d,b),d}function k(a){var b=this,c=new Promise(function(a,c){b.ready().then(function(){var d=b._dbInfo;d.db.transaction(function(b){b.executeSql("SELECT key FROM "+d.storeName,[],function(b,c){for(var d=[],e=0;e<c.rows.length;e++)d.push(c.rows.item(e).key);a(d)},function(a,b){c(b)})})})["catch"](c)});return l(c,a),c}function l(a,b){b&&a.then(function(a){b(null,a)},function(a){b(a)})}var m=a.openDatabase;if(m){var n={_driver:"webSQLStorage",_initStorage:b,iterate:e,getItem:d,setItem:f,removeItem:g,clear:h,length:i,key:j,keys:k};return n}}("undefined"!=typeof window?window:self);b["default"]=d,a.exports=b["default"]}])});
}
catch (e)
{
localForageInitFailed = true;
}
cr.plugins_.LocalStorage = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var currentKey = "";
var lastValue = "";
var keyNamesList = [];
var errorMessage = "";
function 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";
};
function TriggerStorageError(self, msg)
{
errorMessage = msg;
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnError, self);
};
var prefix = "";
var is_arcade = (typeof window["is_scirra_arcade"] !== "undefined");
if (is_arcade)
prefix = "sa" + window["scirra_arcade_id"] + "_";
function hasRequiredPrefix(key)
{
if (!prefix)
return true;
return key.substr(0, prefix.length) === prefix;
};
function removePrefix(key)
{
if (!prefix)
return key;
if (hasRequiredPrefix(key))
return key.substr(prefix.length);
};
var pluginProto = cr.plugins_.LocalStorage.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.pendingSets = 0; // number of pending 'Set item' actions
this.pendingGets = 0; // number of pending 'Get item' actions
};
instanceProto.onDestroy = function ()
{
};
instanceProto.saveToJSON = function ()
{
return {
};
};
instanceProto.loadFromJSON = function (o)
{
};
var debugDataChanged = true;
function Cnds() {};
Cnds.prototype.OnItemSet = function (key)
{
return currentKey === key;
};
Cnds.prototype.OnAnyItemSet = function ()
{
return true;
};
Cnds.prototype.OnItemGet = function (key)
{
return currentKey === key;
};
Cnds.prototype.OnAnyItemGet = function ()
{
return true;
};
Cnds.prototype.OnItemRemoved = function (key)
{
return currentKey === key;
};
Cnds.prototype.OnAnyItemRemoved = function ()
{
return true;
};
Cnds.prototype.OnCleared = function ()
{
return true;
};
Cnds.prototype.OnAllKeyNamesLoaded = function ()
{
return true;
};
Cnds.prototype.OnError = function ()
{
return true;
};
Cnds.prototype.OnItemExists = function (key)
{
return currentKey === key;
};
Cnds.prototype.OnItemMissing = function (key)
{
return currentKey === key;
};
Cnds.prototype.CompareKey = function (cmp, key)
{
return cr.do_cmp(currentKey, cmp, key);
};
Cnds.prototype.CompareValue = function (cmp, v)
{
return cr.do_cmp(lastValue, cmp, v);
};
Cnds.prototype.IsProcessingSets = function ()
{
return this.pendingSets > 0;
};
Cnds.prototype.IsProcessingGets = function ()
{
return this.pendingGets > 0;
};
Cnds.prototype.OnAllSetsComplete = function ()
{
return true;
};
Cnds.prototype.OnAllGetsComplete = function ()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetItem = function (keyNoPrefix, value)
{
if (localForageInitFailed)
{
TriggerStorageError(this, "storage failed to initialise - may be disabled in browser settings");
return;
}
var keyPrefix = prefix + keyNoPrefix;
this.pendingSets++;
var self = this;
localforage["setItem"](keyPrefix, value, function (err, valueSet)
{
debugDataChanged = true;
self.pendingSets--;
if (err)
{
errorMessage = getErrorString(err);
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnError, self);
}
else
{
currentKey = keyNoPrefix;
lastValue = valueSet;
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnAnyItemSet, self);
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnItemSet, self);
currentKey = "";
lastValue = "";
}
if (self.pendingSets === 0)
{
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnAllSetsComplete, self);
}
});
};
Acts.prototype.GetItem = function (keyNoPrefix)
{
if (localForageInitFailed)
{
TriggerStorageError(this, "storage failed to initialise - may be disabled in browser settings");
return;
}
var keyPrefix = prefix + keyNoPrefix;
this.pendingGets++;
var self = this;
localforage["getItem"](keyPrefix, function (err, value)
{
self.pendingGets--;
if (err)
{
errorMessage = getErrorString(err);
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnError, self);
}
else
{
currentKey = keyNoPrefix;
lastValue = value;
if (typeof lastValue === "undefined" || lastValue === null)
lastValue = "";
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnAnyItemGet, self);
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnItemGet, self);
currentKey = "";
lastValue = "";
}
if (self.pendingGets === 0)
{
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnAllGetsComplete, self);
}
});
};
Acts.prototype.CheckItemExists = function (keyNoPrefix)
{
if (localForageInitFailed)
{
TriggerStorageError(this, "storage failed to initialise - may be disabled in browser settings");
return;
}
var keyPrefix = prefix + keyNoPrefix;
var self = this;
localforage["getItem"](keyPrefix, function (err, value)
{
if (err)
{
errorMessage = getErrorString(err);
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnError, self);
}
else
{
currentKey = keyNoPrefix;
if (value === null) // null value indicates key missing
{
lastValue = ""; // prevent ItemValue meaning anything
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnItemMissing, self);
}
else
{
lastValue = value; // make available to ItemValue expression
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnItemExists, self);
}
currentKey = "";
lastValue = "";
}
});
};
Acts.prototype.RemoveItem = function (keyNoPrefix)
{
if (localForageInitFailed)
{
TriggerStorageError(this, "storage failed to initialise - may be disabled in browser settings");
return;
}
var keyPrefix = prefix + keyNoPrefix;
var self = this;
localforage["removeItem"](keyPrefix, function (err)
{
debugDataChanged = true;
if (err)
{
errorMessage = getErrorString(err);
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnError, self);
}
else
{
currentKey = keyNoPrefix;
lastValue = "";
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnAnyItemRemoved, self);
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnItemRemoved, self);
currentKey = "";
}
});
};
Acts.prototype.ClearStorage = function ()
{
if (localForageInitFailed)
{
TriggerStorageError(this, "storage failed to initialise - may be disabled in browser settings");
return;
}
if (is_arcade)
return;
var self = this;
localforage["clear"](function (err)
{
debugDataChanged = true;
if (err)
{
errorMessage = getErrorString(err);
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnError, self);
}
else
{
currentKey = "";
lastValue = "";
cr.clearArray(keyNamesList);
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnCleared, self);
}
});
};
Acts.prototype.GetAllKeyNames = function ()
{
if (localForageInitFailed)
{
TriggerStorageError(this, "storage failed to initialise - may be disabled in browser settings");
return;
}
var self = this;
localforage["keys"](function (err, keyList)
{
var i, len, k;
if (err)
{
errorMessage = getErrorString(err);
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnError, self);
}
else
{
cr.clearArray(keyNamesList);
for (i = 0, len = keyList.length; i < len; ++i)
{
k = keyList[i];
if (!hasRequiredPrefix(k))
continue;
keyNamesList.push(removePrefix(k));
}
self.runtime.trigger(cr.plugins_.LocalStorage.prototype.cnds.OnAllKeyNamesLoaded, self);
}
});
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.ItemValue = function (ret)
{
ret.set_any(lastValue);
};
Exps.prototype.Key = function (ret)
{
ret.set_string(currentKey);
};
Exps.prototype.KeyCount = function (ret)
{
ret.set_int(keyNamesList.length);
};
Exps.prototype.KeyAt = function (ret, i)
{
i = Math.floor(i);
if (i < 0 || i >= keyNamesList.length)
{
ret.set_string("");
return;
}
ret.set_string(keyNamesList[i]);
};
Exps.prototype.ErrorMessage = function (ret)
{
ret.set_string(errorMessage);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.MM_Debugger = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginStates = {
DEBUG: 0,
PRODUCTION: 1,
DISABLED: 2
};
var currentState = pluginStates.DEBUG;
var timestampModes = {
UNIX: {
MILLISECONDS: 0,
SECONDS: 1
},
DATE: {
MM_DD_YYYY: 2,
DD_MM_YYYY: 3,
YYYY_MM_DD: 4
},
NONE: 5
};
var assertionReportType = {
SIMPLE: 0,
DETAILED: 1
};
var outputTypes = {
ALL: 0,
CONSOLE: 1,
STACK_TRACE: 2,
CUSTOM: 3
};
var currentTimestampMode = timestampModes.UNIX.MILLISECONDS;
var timestampOffset = 0;
var stackTrace = [];
var stackTraceLimit = 100;
var lastLog = "";
var lastConsoleLog = "";
var lastStackTraceLog = "";
var lastCustomLog = "";
var disabledTags = [];
var spotlightTags = [];
var isGlobalSpotlightModeOn = false;
var currentAssertionReportType = assertionReportType.SIMPLE;
var MoMod = null;
var pluginProto = cr.plugins_.MM_Debugger.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
var self = this;
currentState = this.properties[1];
currentTimestampMode = this.properties[2];
timestampOffset = this.properties[3];
stackTraceLimit = this.properties[4];
currentAssertionReportType = this.properties[5];
this.executionTimers = {};
this.MoMod =
{
isReadyFlag: false,
instance: null,
type: null,
actions: null,
isReady: function()
{
if (this.isReadyFlag) return true;
if(cr.plugins_.MoMod)
{
var type;
for (type in self.runtime.types)
{
if ( ! self.runtime.types.hasOwnProperty(type)) continue;
if (self.runtime.types[type].plugin instanceof cr.plugins_.MoMod)
{
this.type = self.runtime.types[type];
}
}
if (this.type)
{
this.instance = this.type.instances[0];
this.actions = cr.plugins_.MoMod.prototype.acts;
this.isReadyFlag = true;
return true;
}
}
return false;
}
};
window.addEventListener("error", function (e)
{
self.streamLog(outputTypes.ALL, "[console error] " + e.message + "; file: " + e.filename + ", line: " + e.lineno + ", col: " + e.colno);
});
if(typeof console !== "undefined" && console.warn)
{
console.warn = (function()
{
var w = console.warn;
return function()
{
self.streamLog(outputTypes.ALL, "[console warning] " + arguments[0]);
w.apply(console, arguments);
}
})();
}
};
instanceProto.onDestroy = function ()
{
};
instanceProto.getTimestampPrefix = function()
{
var timestampPrefix = null;
var now = timestampOffset === 0 ? (new Date()) : (new Date((new Date()).getTime() + timestampOffset * 3600000));
switch (currentTimestampMode)
{
case timestampModes.UNIX.MILLISECONDS:
timestampPrefix = now.getTime();
break;
case timestampModes.UNIX.SECONDS:
timestampPrefix = now.getTime() / 1000|0;
break;
case timestampModes.DATE.MM_DD_YYYY:
timestampPrefix = (now.getUTCMonth()+1) + "-" + now.getUTCDate() + "-" + now.getUTCFullYear() + " " + now.getUTCHours() + ":" + now.getUTCMinutes() + ":" + now.getUTCSeconds() + "." + now.getUTCMilliseconds();
break;
case timestampModes.DATE.DD_MM_YYYY:
timestampPrefix = now.getUTCDate() + "-" + (now.getUTCMonth()+1) + "-" + now.getUTCFullYear() + " " + now.getUTCHours() + ":" + now.getUTCMinutes() + ":" + now.getUTCSeconds() + "." + now.getUTCMilliseconds();
break;
case timestampModes.DATE.YYYY_MM_DD:
timestampPrefix = now.getUTCFullYear() + "-" + (now.getUTCMonth()+1) + "-" + now.getUTCDate() + " " + now.getUTCHours() + ":" + now.getUTCMinutes() + ":" + now.getUTCSeconds() + "." + now.getUTCMilliseconds();
break;
}
if(timestampPrefix !== null)
{
timestampPrefix = timestampPrefix.toString() + ": ";
}
else
{
timestampPrefix = "";
}
return timestampPrefix;
};
instanceProto.isTagEnabled = function(tags)
{
if(disabledTags.length === 0) return true;
var i = 0;
var tagsArray = tags.split(",");
for (i; i < tagsArray.length; ++i)
{
if(disabledTags.indexOf(tagsArray[i]) > -1)
{
return false;
}
}
return true;
};
instanceProto.isTagInSpotlight = function(tags)
{
var i = 0;
var tagsArray = tags.split(",");
for (i; i < tagsArray.length; ++i)
{
if(spotlightTags.indexOf(tagsArray[i]) > -1)
{
return true;
}
}
return false;
};
instanceProto.streamLog = function(outputType, data)
{
var self = this;
lastLog = this.getTimestampPrefix() + data;
if ((outputType === outputTypes.CONSOLE || outputType === outputTypes.ALL) && currentState === pluginStates.DEBUG) // console log
{
lastConsoleLog = lastLog;
if(typeof console !== "undefined" && console.log)
{
console.log(lastConsoleLog);
}
self.runtime.trigger(cr.plugins_.MM_Debugger.prototype.cnds.OnConsoleLog, self);
}
if ((outputType === outputTypes.STACK_TRACE || outputType === outputTypes.ALL) && (currentState === pluginStates.DEBUG || currentState == pluginStates.PRODUCTION))
{
lastStackTraceLog = lastLog;
stackTrace.push(lastStackTraceLog);
if(stackTraceLimit > 0 && stackTrace.length > stackTraceLimit)
{
stackTrace = stackTrace.slice(-stackTraceLimit);
}
self.runtime.trigger(cr.plugins_.MM_Debugger.prototype.cnds.OnStackTraceLog, self);
}
if ((outputType === outputTypes.CUSTOM || outputType === outputTypes.ALL) && currentState === pluginStates.DEBUG)
{
lastCustomLog = lastLog;
self.runtime.trigger(cr.plugins_.MM_Debugger.prototype.cnds.OnCustomLog, self);
}
self.runtime.trigger(cr.plugins_.MM_Debugger.prototype.cnds.OnAnyLog, self);
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnConsoleLog = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnStackTraceLog = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnCustomLog = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnAnyLog = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.IsInState = function (stateToCompare)
{
return stateToCompare === currentState;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnAssertionFailed = function ()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.Log = function (outputType, data, tags)
{
this.log(outputType, data, tags);
};
Acts.prototype.ClearStackTrace = function ()
{
if(currentState === pluginStates.DISABLED) return null;
stackTrace = [];
};
Acts.prototype.SetTagState = function (tags, state)
{
var i = 0;
var disabledTagIndex = 0;
var tagsArray = tags.split(",");
for (i; i < tagsArray.length; ++i)
{
if(disabledTagIndex = disabledTags.indexOf(tagsArray[i]) === -1)
{
if(state === 0)
{
disabledTags.push(tagsArray[i]);
}
}
else
{
if(state === 1)
{
disabledTags.splice(disabledTagIndex, 1);
}
}
}
};
Acts.prototype.StartTagSpotlight = function (tags)
{
var i = 0;
var tagsArray = tags.split(",");
for (i; i < tagsArray.length; ++i)
{
spotlightTags.push(tagsArray[i]);
}
};
Acts.prototype.EndTagSpotlight = function ()
{
spotlightTags = [];
};
Acts.prototype.StartGlobalSpotlight = function ()
{
isGlobalSpotlightModeOn = true;
};
Acts.prototype.EndGlobalSpotlight = function ()
{
isGlobalSpotlightModeOn = false;
};
Acts.prototype.AssertAssertion = function (assertion, warningMessage)
{
if (currentState === pluginStates.DISABLED) return null;
if ( ! assertion)
{
var currentEvent = this.runtime.getCurrentEventStack().current_event;
var directEventSheet = currentEvent.actions[0].block.sheet.name;
var line = currentEvent.display_number;
if (currentAssertionReportType == assertionReportType.DETAILED)
{
var groupName = "";
while(currentEvent.parent !== null)
{
if (currentEvent.parent.group_name !== 'undefined' && currentEvent.parent.group_name !== '')
{
groupName = currentEvent.parent.group_name;
break;
}
currentEvent = currentEvent.parent;
}
this.streamLog(outputTypes.ALL, "[ASSERTION FAILED on line " + line + ", es: "+ directEventSheet +"]");
this.streamLog(outputTypes.ALL, "[message] " + warningMessage);
this.streamLog(outputTypes.ALL, "[layout]: " + this.runtime.running_layout.name);
this.streamLog(outputTypes.ALL, "[layout es]: " + this.runtime.running_layout.event_sheet);
this.streamLog(outputTypes.ALL, "[action es]: " + directEventSheet);
this.streamLog(outputTypes.ALL, "[group]: " + groupName);
this.streamLog(outputTypes.ALL, "[line]: " + line);
this.streamLog(outputTypes.ALL, "***************************");
}
else
{
this.streamLog(outputTypes.ALL, "[ASSERTION FAILED on line "+ line +", es: "+ directEventSheet +"] " + warningMessage);
}
this.runtime.trigger(cr.plugins_.MM_Debugger.prototype.cnds.OnAssertionFailed, this);
}
};
Acts.prototype.StartExecutionTimer = function (tag_)
{
this.executionTimers[tag_] = +new Date();
};
Acts.prototype.ClearExecutionTimer = function (tag_)
{
if (this.executionTimers[tag_])
delete this.executionTimers[tag_];
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.GetStackTrace = function (ret, separator)
{
ret.set_string(stackTrace.join(separator));
};
/** PRO +++ **/
Exps.prototype.GetProjectInfo = function (ret, separator)
{
var startTime = new Date(this.runtime.start_time);
startTime = startTime.getUTCFullYear() + "-" + (startTime.getUTCMonth()+1) + "-" + startTime.getUTCDate() + " " + startTime.getUTCHours() + ":" + startTime.getUTCMinutes() + ":" + startTime.getUTCSeconds() + "." + startTime.getUTCMilliseconds();
var output = [
"launched: " + startTime + " (" + this.runtime.start_time + ")",
this.runtime.name + " v" + this.runtime.versionstr,
this.runtime.glUnmaskedRenderer
];
ret.set_string(output.join(separator));
};
/** PRO --- **/
/** PRO +++ **/
Exps.prototype.GetCurrentState = function (ret)
{
var ram = 0;
if (this.runtime.glwrap)
ram = Math.round(100 * this.runtime.glwrap.estimateVRAM() / (1024 * 1024)) / 100;
var output = "FPS: " + this.runtime.fps + ", CPU: " + (Math.round(this.runtime.cpuutilisation*100) / 100000) + ", RAM: " + ram;
ret.set_string(output);
};
/** PRO --- **/
Exps.prototype.GetStackTraceSize = function (ret)
{
ret.set_int(stackTrace.length);
};
Exps.prototype.GetLastStackTraceLog = function (ret)
{
ret.set_string(lastStackTraceLog);
};
Exps.prototype.GetLastCustomLog = function (ret)
{
ret.set_string(lastCustomLog);
};
Exps.prototype.GetLastLog = function (ret)
{
ret.set_string(lastLog);
};
Exps.prototype.GetLastConsoleLog = function (ret)
{
ret.set_string(lastConsoleLog);
};
Exps.prototype.GetDataType = function (ret, data)
{
ret.set_string(typeof data);
};
Exps.prototype.GetExecutionTime = function (ret, tag_)
{
var executionTime = -1;
if (this.executionTimers[tag_])
{
executionTime = +new Date() - this.executionTimers[tag_];
}
ret.set_int(executionTime);
};
pluginProto.exps = new Exps();
/* //Shared functions
function Shared() {}
Shared.prototype.log = function(outputType, data, tags)
{
this.log(outputType, data, tags);
};
pluginProto.shared = new Shared();*/
instanceProto.log = function(outputType, data, tags)
{
if (currentState === pluginStates.DISABLED) return null;
if(isGlobalSpotlightModeOn === false)
{
if (spotlightTags.length > 0)
{
if(this.isTagInSpotlight(tags) === false) return null;
}
else
if (this.isTagEnabled(tags) === false) return null;
}
if(this.MoMod.isReady())
{
data = "[" + this.MoMod.instance.getModuleName() + "]" + "[" + this.MoMod.instance.getSectionName() + "]: " + data;
}
this.streamLog(outputType, data);
}
}());
;
;
cr.plugins_.MM_Preloader = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var preloader = {
items: [],
itemsCompleted: 0,
itemsCount: 0,
isLazyPreloading: false,
lazyInterval: 0
};
var MoMod = null;
var MM_Debugger = null;
var THIS_TAG = "MM_Preloader";
var thisInstance = null;
var objectPreloadId = 0;
var OBJECT_PRELOAD_KEY = "mm_preloader_object_preload_";
var objectPreloadQueue = [];
var isPreloadingObjects = false;
var tickForNextObjectPreloadTrigger = 0;
var intervalObject = null;
var objectsPreloadingState = 0;
var isC2EnginePreloaderAdded = false;
var C2_ENGINE_PRELOADER_KEY = "mm_preloader_c2_engine_";
var spriterInterval = null;
var spriterInst = null;
var spriterIndex = null;
var pluginProto = cr.plugins_.MM_Preloader.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
thisInstance = this;
stabilizer.isEnabled = !!this.properties[1];
stabilizer.maxChecks = Math.max(this.properties[2], 1);
stabilizer.frequency = this.properties[3];
stabilizer.minFps = Math.max(this.properties[4], 1);
stabilizer.confirmations = Math.max(this.properties[5], 1);
if(typeof cr.plugins_.MoMod !== 'undefined' && cr.plugins_.MoMod)
{
MoMod = cr.plugins_.MoMod.prototype.shared;
}
if(typeof cr.plugins_.MM_Debugger !== 'undefined' && cr.plugins_.MM_Debugger)
{
MM_Debugger = cr.plugins_.MM_Debugger.prototype.shared;
}
};
instanceProto.onDestroy = function ()
{
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnProgress = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnCompleted = function()
{
preloader.items = [];
preloader.itemsCompleted = 0;
preloader.itemsCount = 0;
objectPreloadId = 0;
objectPreloadQueue = [];
isPreloadingObjects = false;
tickForNextObjectPreloadTrigger = 0;
intervalObject = null;
objectsPreloadingState = 0;
isC2EnginePreloaderAdded = false;
if(stabilizer.isEnabled)
{
clearTimeout(stabilizer.instance.timerInstance);
stabilizer.instance.currentCheck = 0;
stabilizer.instance.currentConfirmations = 0;
stabilizer.instance.timerInstance = null;
}
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.HasItem = function(key_)
{
return (typeof preloader.items[key_.toLowerCase()] !== 'undefined' && preloader.items[key_.toLowerCase()]);
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.AddItem = function(key_, trigger_, dependency_)
{
addPreloaderItem(key_, trigger_, dependency_);
};
Acts.prototype.SetItemState = function(key_, newState_)
{
setItemState(key_, newState_, this);
};
Acts.prototype.Start = function()
{
preloader.isLazyPreloading = false;
if(preloader.itemsCount === 0 && stabilizer.isEnabled === false)
{
preloaderLog("[Preloader]: Cannot start Preloader, the list is empty.", this);
return;
}
if(stabilizer.isEnabled)
{
var key;
var dependencyList = [];
for (key in preloader.items)
{
if (preloader.items.hasOwnProperty(key))
{
dependencyList.push(key);
}
}
for (key in preloader.items)
{
if (preloader.items.hasOwnProperty(key) && preloader.items[key].dependency == "_last")
{
var localDependencyList = dependencyList;
localDependencyList.splice(dependencyList.indexOf(key), 1);
preloader.items[key].dependency = localDependencyList.join();
}
}
addPreloaderItem("Stabilizer", "true", "_last");
}
preloaderProcessItems(this);
};
Acts.prototype.StartLazy = function(lazyInterval_)
{
if(preloader.itemsCount === 0)
{
preloaderLog("[Preloader]: Cannot start Preloader, the list is empty.", this);
return;
}
preloader.isLazyPreloading = true;
preloader.lazyInterval = lazyInterval_;
preloaderProcessItems(this);
};
Acts.prototype.StabilizerSetState = function(state_)
{
stabilizer.isEnabled = !!state_;
};
Acts.prototype.PreloadObject = function(obj_)
{
if ( ! obj_) return;
addObjectToPreloader(obj_);
};
Acts.prototype.AddFromLayoutByName = function(layoutName_)
{
var l, layout;
for (l in this.runtime.layouts)
{
if (this.runtime.layouts.hasOwnProperty(l) && cr.equals_nocase(l, layoutName_))
{
layout = this.runtime.layouts[l];
break;
}
}
if( ! layout)
{
preloaderLog("[Preloader ERROR]: Cannot load objects from layout \"" + layoutName_ + "\" because such layout does not exist.", this);
return;
}
addObjectFromLayout(layout);
};
Acts.prototype.AddFromLayout = function(layout)
{
if( ! layout) return;
addObjectFromLayout(layout);
};
Acts.prototype.AddC2EngineProgress = function()
{
isC2EnginePreloaderAdded = true;
addPreloaderItem(C2_ENGINE_PRELOADER_KEY, "", "");
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.Progress = function(ret)
{
var generalPreloadProgress = Math.floor((preloader.itemsCompleted / preloader.itemsCount) * 10000) / 100;
var detailedPreloadProgress = 0;
var unitValue = 1 / preloader.itemsCount;
var key;
for (key in preloader.items)
{
if (preloader.items.hasOwnProperty(key) && preloader.items[key].currentState < 100 && preloader.items[key].currentState > 0)
{
detailedPreloadProgress += unitValue * (preloader.items[key].currentState / 100)
}
}
detailedPreloadProgress = Math.floor(detailedPreloadProgress * 10000) / 100;
ret.set_float(Math.floor((generalPreloadProgress + detailedPreloadProgress) * 100) / 100);
};
Exps.prototype.ItemProgress = function(ret, key_)
{
key_ = key_.toLowerCase();
if(typeof preloader.items[key_] === 'undefined' || ! preloader.items[key_])
{
preloaderLog("[Preloader ERROR]: Cannot get state of \"" + key_ + "\" item, because such item does not exist on preloader list.", this);
ret.set_int(0);
return;
}
ret.set_float(Math.floor(preloader.items[key_].currentState * 100) / 100);
};
Exps.prototype.ItemsCount = function(ret)
{
ret.set_int(preloader.itemsCount);
};
Exps.prototype.ObjectsProgress = function(ret)
{
if(objectPreloadQueue.length === 0)
{
preloaderLog("[Preloader ERROR]: Cannot get state of preloading objects, because none object has been added to the preloader list.", this);
ret.set_int(0);
return;
}
ret.set_float(Math.floor(objectsPreloadingState * 100) / 100);
};
Exps.prototype.C2EngineProgress = function(ret)
{
if(typeof preloader.items[C2_ENGINE_PRELOADER_KEY] === 'undefined' || ! preloader.items[C2_ENGINE_PRELOADER_KEY])
{
preloaderLog("[Preloader ERROR]: Cannot get state of \"C2 Engine\" item, because it does not exist on preloader list.", this);
ret.set_int(0);
return;
}
ret.set_float(Math.floor(preloader.items[C2_ENGINE_PRELOADER_KEY].currentState * 100) / 100);
};
pluginProto.exps = new Exps();
var stabilizer =
{
isEnabled: true,
maxChecks: 0,
frequency: 0,
minFps: 60,
confirmations: 1,
instance: {
currentCheck: 0,
currentConfirmations: 0,
timerInstance: null,
currentDis: null
},
checkFunction: function()
{
if (stabilizer.maxChecks > stabilizer.instance.currentCheck)
{
++stabilizer.instance.currentCheck;
if (stabilizer.minFps <= thisInstance.runtime.fps)
{
++stabilizer.instance.currentConfirmations;
if (stabilizer.instance.currentConfirmations >= stabilizer.confirmations)
{
setItemState("Stabilizer", 100, stabilizer.instance.currentDis);
return;
}
}
var currentState = (stabilizer.instance.currentCheck / stabilizer.maxChecks) * 100;
setItemState("Stabilizer", currentState, stabilizer.instance.currentDis);
if(currentState < 100)
{
stabilizer.instance.timerInstance = setTimeout(stabilizer.checkFunction, stabilizer.frequency * 1000);
}
}
else
{
setItemState("Stabilizer", 100, stabilizer.instance.currentDis);
}
}
};
function addPreloaderItem(key_, trigger_, dependency_)
{
key_ = key_.toLowerCase();
if(typeof preloader.items[key_] !== 'undefined' && preloader.items[key_])
{
preloaderLog("[Preloader]: Duplicate entry \"" + key_ + "\". This item already exists on preloader list.", this);
return;
}
preloader.items[key_] = {
trigger: trigger_.toLowerCase(),
dependency: dependency_.toLowerCase(),
currentState: 0,
isProcessing: ! trigger_
};
++preloader.itemsCount;
}
function preloaderProcessItems(dis_)
{
if(isC2EnginePreloaderAdded)
{
if( ! intervalObject)
{
intervalObject = setInterval(function()
{
var state = dis_.runtime.loadingprogress * 100;
if(state == 100)
{
clearInterval(intervalObject);
isC2EnginePreloaderAdded = false;
}
setItemState(C2_ENGINE_PRELOADER_KEY, state, dis_);
}, 50);
}
return;
}
var key;
for (key in preloader.items)
{
if( ! preloader.items.hasOwnProperty(key) || preloader.items[key].currentState === 100 || preloader.items[key].isProcessing === true) continue;
if( ! preloader.items[key].dependency)
{
preloaderTriggerItem(key);
}
else
if(preloader.items[key].dependency === "_last")
{
if(preloader.itemsCompleted === preloader.itemsCount - 1)
{
if(stabilizer.isEnabled)
{
preloader.items[key].isProcessing = true;
stabilizer.instance.currentDis = dis_;
stabilizer.instance.timerInstance = setTimeout(stabilizer.checkFunction, stabilizer.frequency * 1000);
}
else
{
preloaderTriggerItem(key);
}
}
}
else
if(preloader.items[key].dependency === OBJECT_PRELOAD_KEY)
{
if(isPreloadingObjects === false)
{
isPreloadingObjects = true;
triggerObjectsPreloadingQueue(dis_);
}
}
else
{
var dependencies = preloader.items[key].dependency.split(",");
var allDependenciesReady = true;
var i;
for(i = 0; i < dependencies.length; i++)
{
if( ! preloader.items[dependencies[i]])
{
preloaderLog("[Preloader ERROR]: item \"" + key + "\" has dependency \"" + dependencies[i] + "\" but \"" + dependencies[i] + "\" item does not exist in preloader's list.", dis_);
return;
}
if(preloader.items[dependencies[i]].currentState < 100)
{
allDependenciesReady = false;
break;
}
}
if (allDependenciesReady)
{
preloaderTriggerItem(key);
}
}
if(preloader.isLazyPreloading)
{
return;
}
}
}
function addObjectToPreloader(obj_)
{
/*
deadCache seems to be unpredictable and can't rely on it when it comes to sprites.
Also it isn't the factor for texture in the memory,
meaning that it happens that even thoug there's deadCache available, the texture isn't loaded.
if(obj_.deadCache.length > 0 || obj_.instances.length > 0)
{
return;
}
*/
var itemKey = OBJECT_PRELOAD_KEY + objectPreloadId;
objectPreloadQueue.push({
object: obj_,
key: itemKey,
isPreloaded: false
});
addPreloaderItem(itemKey, "automatic", OBJECT_PRELOAD_KEY);
++objectPreloadId;
}
function addObjectFromLayout(layout)
{
var i;
for(i = 0; i < layout.initial_types.length; i++)
{
if(typeof layout.initial_types[i].plugin !== 'object') continue;
if(cr.plugins_.Sprite && layout.initial_types[i].plugin instanceof cr.plugins_.Sprite)
{
if(layout.initial_types[i].has_loaded_textures) continue;
}
if(cr.plugins_.TiledBg && layout.initial_types[i].plugin instanceof cr.plugins_.TiledBg)
{
if(layout.initial_types[i].webGL_texture) continue;
}
if(cr.plugins_.Tilemap && layout.initial_types[i].plugin instanceof cr.plugins_.Tilemap)
{
if(layout.initial_types[i].cut_tiles_valid) continue;
}
if((cr.plugins_.SpriteFontPlus && layout.initial_types[i].plugin instanceof cr.plugins_.SpriteFontPlus)
|| (cr.plugins_.Spritefont2 && layout.initial_types[i].plugin instanceof cr.plugins_.Spritefont2))
{
if(layout.initial_types[i].webGL_texture) continue;
}
if(cr.plugins_.Spriter && layout.initial_types[i].plugin instanceof cr.plugins_.Spriter)
{
if(layout.initial_types[i].deadCache.length > 0 /* || layout.initial_types[i].instances.length > 0 */ ) continue;
}
addObjectToPreloader(layout.initial_types[i]);
}
}
var isWaitingForSpriterobject = false;
function triggerObjectsPreloadingQueue(dis_)
{
if(intervalObject)
{
clearInterval(intervalObject);
}
if(spriterInterval) return;
var i;
var isLastItem = false;
for(i = 0; i < objectPreloadQueue.length; i++)
{
if( ! objectPreloadQueue[i].isPreloaded)
{
isLastItem = i === objectPreloadQueue.length - 1;
var inst = dis_.runtime.createInstance(objectPreloadQueue[i].object, dis_.runtime.running_layout.layers[0], -10000, -10000);
if (inst)
{
if(cr.plugins_.Spriter && inst.type.plugin instanceof cr.plugins_.Spriter)
{
isWaitingForSpriterobject = true;
spriterInst = inst;
spriterIndex = i;
spriterInterval = setInterval(function()
{
if(spriterInst.entities)
{
clearInterval(spriterInterval);
spriterInterval = null;
objectPreloadQueue[spriterIndex].isPreloaded = true;
objectsPreloadingState = ((spriterIndex + 1) / objectPreloadQueue.length * 10000) / 100;
setTimeout(function() // whitout this delay it breaks 50% of time
{
dis_.runtime.isEndingLayout = true;
dis_.runtime.DestroyInstance(spriterInst);
dis_.runtime.isEndingLayout = false;
}, 50);
setItemState(objectPreloadQueue[spriterIndex].key, 100, dis_);
isWaitingForSpriterobject = false;
}
}, 10);
}
else
{
objectPreloadQueue[i].isPreloaded = true;
objectsPreloadingState = ((i + 1) / objectPreloadQueue.length * 10000) / 100;
setItemState(objectPreloadQueue[i].key, 100, dis_);
dis_.runtime.isEndingLayout = true;
dis_.runtime.DestroyInstance(inst);
dis_.runtime.isEndingLayout = false;
}
}
break;
}
}
if( ! isLastItem)
{
tickForNextObjectPreloadTrigger = dis_.runtime.tickcount + 2;
intervalObject = setInterval(function()
{
if(tickForNextObjectPreloadTrigger < dis_.runtime.tickcount)
{
triggerObjectsPreloadingQueue(dis_)
}
}, preloader.isLazyPreloading ? preloader.lazyInterval * 1000 : 50);
}
else
{
isPreloadingObjects = false;
}
}
function setItemState(key_, newState_, dis_)
{
key_ = key_.toLowerCase();
if (typeof preloader.items[key_] === 'undefined' || !preloader.items[key_])
{
preloaderLog("[Preloader ERROR]: Cannot update \"" + key_ + "\" item, because such item does not exist on preloader list.", dis_);
return;
}
if (preloader.items[key_].currentState >= 100) return; // avoid redundant state 100
preloader.items[key_].currentState = cr.clamp(newState_, 0, 100);
if (preloader.items[key_].currentState === 100)
{
++preloader.itemsCompleted;
}
dis_.runtime.trigger(cr.plugins_.MM_Preloader.prototype.cnds.OnProgress, dis_);
if (preloader.itemsCompleted === preloader.itemsCount)
{
dis_.runtime.trigger(cr.plugins_.MM_Preloader.prototype.cnds.OnCompleted, dis_);
}
else
{
if( ! isC2EnginePreloaderAdded)
{
if(preloader.isLazyPreloading && preloader.items[key_].currentState === 100)
{
setTimeout(function()
{
preloaderProcessItems(dis_);
}, preloader.lazyInterval * 1000);
}
else
{
preloaderProcessItems(dis_);
}
}
}
}
function preloaderTriggerItem(key_)
{
if(MoMod && preloader.items[key_].trigger.indexOf(" >>> ") !== -1)
{
var moduleName = preloader.items[key_].trigger.substring(0, preloader.items[key_].trigger.indexOf(" >>> "));
var eventName = preloader.items[key_].trigger.substring(preloader.items[key_].trigger.indexOf(" >>> ") + 5, preloader.items[key_].trigger.length);
preloader.items[key_].isProcessing = true;
MoMod.dispatchEvent(moduleName, eventName, []);
}
else
if (window['c2_callFunction'])
{
preloader.items[key_].isProcessing = true;
window['c2_callFunction'](preloader.items[key_].trigger, []);
}
}
function preloaderLog(message_, dis_)
{
MM_Debugger ? MM_Debugger.log(0, message_, THIS_TAG, dis_) : console.log(message_);
}
}());
;
;
cr.plugins_.MM_Unloader = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.MM_Unloader.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
};
instanceProto.onDestroy = function ()
{
};
function Cnds() {};
/**
* @returns {boolean}
*/
/*Cnds.prototype.OnDataMissing = function()
{
return true;
};*/
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.UnloadAllUnused = function()
{
var i, len, type;
if (this.runtime.glwrap)
{
for (i = 0, len = this.runtime.types_by_index.length; i < len; ++i)
{
type = this.runtime.types_by_index[i];
if (type.is_family) continue;
this.unload(type);
}
}
this.runtime.redraw = true;
};
Acts.prototype.UnloadObject = function(obj_)
{
this.unload(obj_);
this.runtime.redraw = true;
};
Acts.prototype.HardDestroyObject = function(obj_)
{
this.hardDestroy(obj_);
};
Acts.prototype.HardDestroyLayer = function(layer_)
{
var uniqueObjects = [];
var i, len = layer_.instances.length;
for (i = 0; i < len; ++i)
{
if (uniqueObjects.indexOf(layer_.instances[i].type) === -1)
uniqueObjects.push(layer_.instances[i].type);
}
len = uniqueObjects.length;
for (i = 0; i < len; ++i)
{
this.hardDestroy(uniqueObjects[i]);
}
};
Acts.prototype.DestroyLayer = function(layer_)
{
var i, len = layer_.instances.length;
for (i = 0; i < len; ++i)
{
this.runtime.DestroyInstance(layer_.instances[i]);
}
};
pluginProto.acts = new Acts();
function Exps() {};
/*Exps.prototype.GetData = function(ret, dataIndex_)
{
ret.set_any(this.data[dataIndex_]);
};*/
pluginProto.exps = new Exps();
instanceProto.unload = function(type_)
{
if (type_.is_family)
{
var i, len;
for (i = 0, len = type_.members.length; i < len; ++i)
{
this.unloadType(type_.members[i]);
}
}
else
{
this.unloadType(type_);
}
};
instanceProto.unloadType = function(type_)
{
if (type_.unloadTextures && (!type_.global || type_.instances.length === 0))
{
type_.unloadTextures();
}
}
instanceProto.hardDestroy = function(obj_)
{
var i, len;
for (i = 0, len = obj_.instances.length; i < len; ++i)
{
this.runtime.DestroyInstance(obj_.instances[i]);
}
if(obj_.instances.length === 0)
{
this.unload(obj_);
this.runtime.redraw = true;
}
else
{
var self = this;
var instanceMonitor = setInterval(function()
{
if(obj_.instances.length === 0)
{
self.unload(obj_);
clearInterval(instanceMonitor);
self.runtime.redraw = true;
}
}, 10);
}
}
}());
;
;
cr.plugins_.MoMod = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var moduleSection = {
HEAD: 'Head',
BODY: 'Body'
};
var branchStates = {
DISABLED: 0,
ENABLED: 1,
TOGGLE: 2
};
var currentlyProcessingModule = '';
var customBodySections = {};
var customHeadSections = {};
var eventsStack = [];
var eventsStackPointer = -1;
var MM_Debugger = null;
function MMsEventsStackEntry()
{
this.module = "";
this.event = "";
this.params = [];
}
function mmsPushEventsStack()
{
eventsStackPointer++;
if (eventsStackPointer === eventsStack.length)
eventsStack.push(new MMsEventsStackEntry());
return eventsStack[eventsStackPointer];
}
function mmsGetCurrentEventsStack()
{
if (eventsStackPointer < 0)
return null;
return eventsStack[eventsStackPointer];
}
function mmsPopEventsStack()
{
;
eventsStackPointer--;
}
var pluginProto = cr.plugins_.MoMod.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function ()
{
var self = this;
this.MMD =
{
isReadyFlag: false,
instance: null,
type: null,
actions: null,
isReady: function()
{
if (this.isReadyFlag) return true;
if(cr.plugins_.MM_Debugger)
{
var type;
for (type in self.runtime.types)
{
if ( ! self.runtime.types.hasOwnProperty(type)) continue;
if (self.runtime.types[type].plugin instanceof cr.plugins_.MM_Debugger)
{
this.type = self.runtime.types[type];
}
}
if (this.type)
{
this.instance = this.type.instances[0];
this.actions = cr.plugins_.MM_Debugger.prototype.acts;
this.isReadyFlag = true;
return true;
}
}
return false;
}
};
};
instanceProto.onDestroy = function ()
{
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnModuleEvent = function (eventName_)
{
var es = mmsGetCurrentEventsStack();
if (!es)
return false;
return cr.equals_nocase(this.getModuleName() + eventName_, es.module + es.event);
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnCustomModuleEvent = function (moduleName_, eventName_)
{
var es = mmsGetCurrentEventsStack();
if (!es)
return false;
return cr.equals_nocase(moduleName_ + eventName_, es.module + es.event);
};
/**
* @returns {boolean}
*/
Cnds.prototype.IsModuleEnabled = function (moduleName_)
{
if(this.getBranchState(moduleName_, null, null) !== branchStates.ENABLED || this.isModuleShutdown(moduleName_))
{
return false;
}
if(Array.isArray(customBodySections[moduleName_]) === true)
{
var i;
for(i = 0; i < customBodySections[moduleName_].length; i++)
{
if(this.getBranchState(moduleName_, customBodySections[moduleName_][i], null) === branchStates.DISABLED) return false;
}
}
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.IfModuleExists = function (moduleName_)
{
return this.isModule(moduleName_);
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnModuleEnabled = function ()
{
return cr.equals_nocase(currentlyProcessingModule, this.getModuleName());
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnModuleDisabled = function ()
{
return cr.equals_nocase(currentlyProcessingModule, this.getModuleName());
};
/**
* @returns {boolean}
*/
Cnds.prototype.IsSectionEnabled = function (section_, branch_)
{
var thisModuleName = this.getModuleName();
thisModuleName = this.parseName(thisModuleName);
if ( ! this.isModule(thisModuleName)) return false;
if ( ! this.isSection(thisModuleName, section_)) return false;
return this.getBranchState(thisModuleName, section_, branch_) === branchStates.ENABLED;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetModuleState = function (moduleName_, newState_)
{
if (this.isModule(moduleName_) === false) return;
moduleName_ = this.parseName(moduleName_);
if(this.isModuleShutdown(moduleName_))
{
this.MMD.isReady() && this.log("[Set module state]: Can't change module's state because '" + moduleName_ + "' is shutdown.", this);
return;
}
if(this.sectionExists(moduleName_, moduleSection.BODY.toLocaleLowerCase()))
{
this.setBranchState(newState_, moduleName_, moduleSection.BODY, null);
}
if(Array.isArray(customBodySections[moduleName_]) === true)
{
var i;
for(i = 0; i < customBodySections[moduleName_].length; i++)
{
this.setBranchState(newState_, moduleName_, customBodySections[moduleName_][i], null);
}
}
currentlyProcessingModule = moduleName_;
if(newState_)
{
this.runtime.trigger(cr.plugins_.MoMod.prototype.cnds.OnModuleEnabled, this);
}
else
{
this.runtime.trigger(cr.plugins_.MoMod.prototype.cnds.OnModuleDisabled, this);
}
this.dispatchEvent(moduleName_, newState_ ? "OnEnabled" : "OnDisabled", []);
};
Acts.prototype.TriggerModuleEvent = function (eventName_, params_)
{
this.dispatchEvent(this.getModuleName(), eventName_, params_);
};
Acts.prototype.TriggerCustomModuleEvent = function (moduleName_, eventName_, params_)
{
this.dispatchEvent(moduleName_, eventName_, params_);
};
Acts.prototype.SetSection = function (sectionName_, branchName_, newState_)
{
this.setBranchState(newState_, this.getModuleName(), sectionName_, branchName_);
};
Acts.prototype.ShutdownModule = function (moduleName_)
{
if ( ! this.isModule(moduleName_)) return;
moduleName_ = this.parseName(moduleName_);
this.setBranchState(branchStates.DISABLED, moduleName_, null, null);
if(this.sectionExists(moduleName_, moduleSection.HEAD.toLocaleLowerCase()))
{
this.setBranchState(branchStates.DISABLED, moduleName_, moduleSection.HEAD, null);
}
if(Array.isArray(customHeadSections[moduleName_]) === true)
{
var i;
for(i = 0; i < customHeadSections[moduleName_].length; i++)
{
this.setBranchState(branchStates.DISABLED, moduleName_, customHeadSections[moduleName_][i], null);
}
}
};
Acts.prototype.StartUpModule = function (moduleName_)
{
if ( ! this.isModule(moduleName_)) return;
moduleName_ = this.parseName(moduleName_);
this.setBranchState(branchStates.ENABLED, moduleName_, null, null);
if(this.sectionExists(moduleName_, moduleSection.HEAD.toLocaleLowerCase()))
{
this.setBranchState(branchStates.ENABLED, moduleName_, moduleSection.HEAD, null);
}
if(Array.isArray(customHeadSections[moduleName_]) === true)
{
var i;
for(i = 0; i < customHeadSections[moduleName_].length; i++)
{
this.setBranchState(branchStates.ENABLED, moduleName_, customHeadSections[moduleName_][i], null);
}
}
};
Acts.prototype.RegisterBodySection = function (sectionName_)
{
var thisModuleName = this.getModuleName();
thisModuleName = this.parseName(thisModuleName);
if ( ! this.isModule(thisModuleName) || ! this.isSection(thisModuleName, sectionName_)) return;
if(Array.isArray(customBodySections[thisModuleName]) === false)
{
customBodySections[thisModuleName] = [];
}
if(customBodySections[thisModuleName].indexOf(sectionName_) === -1)
{
customBodySections[thisModuleName].push(sectionName_);
}
};
Acts.prototype.RegisterHeadSection = function (sectionName_)
{
var thisModuleName = this.getModuleName();
thisModuleName = this.parseName(thisModuleName);
if ( ! this.isModule(thisModuleName) || ! this.isSection(thisModuleName, sectionName_)) return;
if(Array.isArray(customHeadSections[thisModuleName]) === false)
{
customHeadSections[thisModuleName] = [];
}
if(customHeadSections[thisModuleName].indexOf(sectionName_) === -1)
{
customHeadSections[thisModuleName].push(sectionName_);
}
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.ThisModule = function (ret)
{
ret.set_string(this.getModuleName());
};
Exps.prototype.ThisController = function (ret)
{
ret.set_string(this.getControllerName());
};
Exps.prototype.ThisSection = function (ret)
{
ret.set_string(this.getSectionName());
};
Exps.prototype.Param = function (ret, index_)
{
index_ = cr.floor(index_);
var es = mmsGetCurrentEventsStack();
if (es)
{
if (index_ >= 0 && index_ < es.params.length)
{
ret.set_any(es.params[index_]);
}
else
{
this.MMD.isReady() && this.log("[Event param]: In module event \"" + es.event + "@" + es.module + "\", accessed parameter out of bounds (accessed index " + index_ + ", " + es.params.length + " params available)", this);
ret.set_int(0);
}
}
else
{
this.MMD.isReady() && this.log("[Module event]: used \"MoMod.EventParam\" expression when not in a module event observer.", this);
ret.set_int(0);
}
};
Exps.prototype.ThisBranch = function (ret)
{
ret.set_string(this.getBranchName());
};
pluginProto.exps = new Exps();
/* // Shared functions
function Shared() {}
Shared.prototype.getModuleName = function(dis_)
{
return dis_.getModuleName();
};
Shared.prototype.getControllerName = function(dis_)
{
return dis_.getControllerName();
};
Shared.prototype.getSectionName = function(dis_)
{
var sectionName = dis_.getSectionName();
return sectionName.charAt(0).toUpperCase() + sectionName.slice(1);
};
Shared.prototype.dispatchEvent = function(moduleName_, eventName_, params_)
{
this.dispatchEvent(moduleName_, eventName_, params_);
};
pluginProto.shared = new Shared();*/
instanceProto.dispatchEvent = function (moduleName_, eventName_, params_)
{
var es = mmsPushEventsStack();
es.module = this.parseName(moduleName_);
es.event = this.parseName(eventName_);
cr.shallowAssignArray(es.params, params_);
this.runtime.trigger(cr.plugins_.MoMod.prototype.cnds.OnModuleEvent, this);
this.runtime.trigger(cr.plugins_.MoMod.prototype.cnds.OnCustomModuleEvent, this);
mmsPopEventsStack();
};
instanceProto.isModule = function (moduleName_)
{
moduleName_ = this.parseName(moduleName_);
if (moduleName_ === "MM_Core".toLocaleLowerCase()) return true;
if ( ! this.runtime.groups_by_name[moduleName_])
{
this.MMD.isReady() && this.log("[Module]: \"" + moduleName_ + "\" is not a valid module or does not exist.", this);
return false;
}
return true;
};
instanceProto.isSection = function (moduleName_, sectionName_)
{
moduleName_ = this.parseName(moduleName_);
sectionName_ = this.parseName(sectionName_);
if( ! this.sectionExists(moduleName_, sectionName_))
{
this.MMD.isReady() && this.log("[Module]: \"" + sectionName_ + "\" is not a valid section of \"" + moduleName_ + "\" module.", this);
return false;
}
return true;
};
instanceProto.sectionExists = function (moduleName_, sectionName_)
{
moduleName_ = this.parseName(moduleName_);
sectionName_ = this.parseName(sectionName_);
return !! this.runtime.groups_by_name[moduleName_ + '[' + sectionName_ + ']'];
};
instanceProto.isModuleShutdown = function (moduleName_)
{
moduleName_ = this.parseName(moduleName_);
if ( ! this.runtime.groups_by_name.hasOwnProperty(moduleName_))
{
return false;
}
return ! this.runtime.groups_by_name[moduleName_].group_active;
};
instanceProto.setBranchState = function (newState_, moduleName_, sectionName_, branch_)
{
moduleName_ = this.parseName(moduleName_);
sectionName_ = this.parseName(sectionName_);
branch_ = this.parseName(branch_);
if ( ! this.isModule(moduleName_)) return;
var groupName = moduleName_;
if (sectionName_)
{
if( ! this.isSection(moduleName_, sectionName_)) return;
groupName += '[' + sectionName_ + ']';
}
if(branch_)
{
groupName += " > " + branch_;
}
var branch = this.runtime.groups_by_name[groupName];
if( ! branch)
{
this.MMD.isReady() && this.log("[MoMod]: \"" + groupName + "\" is not a valid branch of \"" + moduleName_ + "\" module.", this);
return false;
}
switch(newState_)
{
case branchStates.DISABLED:
newState_ = false;
break;
case branchStates.ENABLED:
newState_ = true;
break;
case branchStates.TOGGLE:
newState_ = ! branch.group_active;
break;
}
branch.setGroupActive(newState_);
};
instanceProto.getBranchState = function (moduleName_, sectionName_, branch_)
{
moduleName_ = this.parseName(moduleName_);
sectionName_ = this.parseName(sectionName_);
branch_ = this.parseName(branch_);
if ( ! this.isModule(moduleName_)) return branchStates.DISABLED;
var groupName = moduleName_;
if (sectionName_)
{
if( ! this.isSection(moduleName_, sectionName_)) return branchStates.DISABLED;
groupName += '[' + sectionName_ + ']';
}
if(branch_)
{
groupName += " > " + branch_;
}
var branch = this.runtime.groups_by_name[groupName];
if( ! branch)
{
this.MMD.isReady() && this.log("[Get branch]: \"" + groupName + "\" is not a valid branch of \"" + moduleName_ + "\" module.", this);
return branchStates.DISABLED;
}
return +branch.group_active;
};
instanceProto.parseName = function (branchName_)
{
if (branchName_) branchName_ = branchName_.toLowerCase();
return branchName_;
};
instanceProto.getControllerName = function ()
{
var currentEvent = this.getCurrentRuntimeEvent();
if ( ! currentEvent.momod.controller)
{
currentEvent.momod.controller = String(this.runtime.running_layout.event_sheet);
}
return currentEvent.momod.controller;
};
instanceProto.getModuleName = function ()
{
return this.runtime.getCurrentEventStack().current_event.sheet.name;
/* --- Accessing sheet.name directly is slightly faster
var currentEvent = this.getCurrentRuntimeEvent();
if ( ! currentEvent.momod.module)
{
currentEvent.momod.module = currentEvent.sheet.name;
}
return currentEvent.momod.module;
*/
};
instanceProto.getBranchName = function ()
{
var currentEvent = this.getCurrentRuntimeEvent();
if ( ! currentEvent.momod.branch)
{
var groupName = this.getThisGroupName();
var sectionStartPos = groupName.indexOf(">");
if (sectionStartPos === -1)
{
return "";
}
currentEvent.momod.branch = groupName.substring(sectionStartPos + 2, groupName.length);
}
return currentEvent.momod.branch;
};
instanceProto.getSectionName = function ()
{
var currentEvent = this.getCurrentRuntimeEvent();
if ( ! currentEvent.momod.section)
{
var groupName = this.getThisGroupName();
if (groupName)
{
var sectionStartPos = groupName.indexOf("[");
var sectionEndPos = groupName.indexOf("]");
}
if( ! groupName || sectionStartPos === -1 || sectionEndPos === -1 || sectionStartPos + 1 === sectionEndPos)
{
this.MMD.isReady() && this.log("[Get section name]: This event doesn't belong to any section.");
return "";
}
currentEvent.momod.section = groupName.substring(sectionStartPos + 1, sectionEndPos);
}
return currentEvent.momod.section;
};
instanceProto.getThisGroupName = function ()
{
var currentEvent = this.getCurrentRuntimeEvent();
if ( ! currentEvent.momod.group)
{
var eventPointer = currentEvent;
while(eventPointer.parent !== null)
{
if (eventPointer.parent.group_name !== 'undefined' && eventPointer.parent.group_name !== '')
{
currentEvent.momod.group = eventPointer.parent.group_name;
break;
}
eventPointer = eventPointer.parent;
}
}
return currentEvent.momod.group;
};
instanceProto.getCurrentRuntimeEvent = function ()
{
if ( ! this.runtime.getCurrentEventStack().current_event.momod)
{
this.runtime.getCurrentEventStack().current_event.momod = {};
}
return this.runtime.getCurrentEventStack().current_event;
};
instanceProto.log = function (message_)
{
var currentEvent = this.runtime.getCurrentEventStack().current_event;
var directEventSheet = currentEvent.actions[0].block.sheet.name;
var line = currentEvent.display_number;
message_ = "[MoMod ERROR on line " + line + ", sheet " + directEventSheet + "]" + message_;
var es = mmsPushEventsStack();
es.module = "MM_Core".toLowerCase();
es.event = "Log".toLocaleLowerCase();
cr.shallowAssignArray(es.params, [message_]);
this.MMD.isReady() && this.MMD.instance.log(0, message_, 'MoMod', this);
this.runtime.trigger(cr.plugins_.MoMod.prototype.cnds.OnCustomModuleEvent, this);
mmsPopEventsStack();
};
}());
;
;
cr.plugins_.Mouse = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Mouse.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
this.buttonMap = new Array(4); // mouse down states
this.mouseXcanvas = 0; // mouse position relative to canvas
this.mouseYcanvas = 0;
this.triggerButton = 0;
this.triggerType = 0;
this.triggerDir = 0;
this.handled = false;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
var self = this;
if (!this.runtime.isDomFree)
{
jQuery(document).mousemove(
function(info) {
self.onMouseMove(info);
}
);
jQuery(document).mousedown(
function(info) {
self.onMouseDown(info);
}
);
jQuery(document).mouseup(
function(info) {
self.onMouseUp(info);
}
);
jQuery(document).dblclick(
function(info) {
self.onDoubleClick(info);
}
);
var wheelevent = function(info) {
self.onWheel(info);
};
document.addEventListener("mousewheel", wheelevent, false);
document.addEventListener("DOMMouseScroll", wheelevent, false);
}
};
var dummyoffset = {left: 0, top: 0};
instanceProto.onMouseMove = function(info)
{
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
this.mouseXcanvas = info.pageX - offset.left;
this.mouseYcanvas = info.pageY - offset.top;
};
instanceProto.mouseInGame = function ()
{
if (this.runtime.fullscreen_mode > 0)
return true;
return this.mouseXcanvas >= 0 && this.mouseYcanvas >= 0
&& this.mouseXcanvas < this.runtime.width && this.mouseYcanvas < this.runtime.height;
};
instanceProto.onMouseDown = function(info)
{
if (!this.mouseInGame())
return;
this.buttonMap[info.which] = true;
this.runtime.isInUserInputEvent = true;
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnAnyClick, this);
this.triggerButton = info.which - 1; // 1-based
this.triggerType = 0; // single click
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnClick, this);
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnObjectClicked, this);
this.runtime.isInUserInputEvent = false;
};
instanceProto.onMouseUp = function(info)
{
if (!this.buttonMap[info.which])
return;
if (this.runtime.had_a_click && !this.runtime.isMobile)
info.preventDefault();
this.runtime.had_a_click = true;
this.buttonMap[info.which] = false;
this.runtime.isInUserInputEvent = true;
this.triggerButton = info.which - 1; // 1-based
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnRelease, this);
this.runtime.isInUserInputEvent = false;
};
instanceProto.onDoubleClick = function(info)
{
if (!this.mouseInGame())
return;
info.preventDefault();
this.runtime.isInUserInputEvent = true;
this.triggerButton = info.which - 1; // 1-based
this.triggerType = 1; // double click
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnClick, this);
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnObjectClicked, this);
this.runtime.isInUserInputEvent = false;
};
instanceProto.onWheel = function (info)
{
var delta = info.wheelDelta ? info.wheelDelta : info.detail ? -info.detail : 0;
this.triggerDir = (delta < 0 ? 0 : 1);
this.handled = false;
this.runtime.isInUserInputEvent = true;
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnWheel, this);
this.runtime.isInUserInputEvent = false;
if (this.handled && cr.isCanvasInputEvent(info))
info.preventDefault();
};
instanceProto.onWindowBlur = function ()
{
var i, len;
for (i = 0, len = this.buttonMap.length; i < len; ++i)
{
if (!this.buttonMap[i])
continue;
this.buttonMap[i] = false;
this.triggerButton = i - 1;
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnRelease, this);
}
};
function Cnds() {};
Cnds.prototype.OnClick = function (button, type)
{
return button === this.triggerButton && type === this.triggerType;
};
Cnds.prototype.OnAnyClick = function ()
{
return true;
};
Cnds.prototype.IsButtonDown = function (button)
{
return this.buttonMap[button + 1]; // jQuery uses 1-based buttons for some reason
};
Cnds.prototype.OnRelease = function (button)
{
return button === this.triggerButton;
};
Cnds.prototype.IsOverObject = function (obj)
{
var cnd = this.runtime.getCurrentCondition();
var mx = this.mouseXcanvas;
var my = this.mouseYcanvas;
return cr.xor(this.runtime.testAndSelectCanvasPointOverlap(obj, mx, my, cnd.inverted), cnd.inverted);
};
Cnds.prototype.OnObjectClicked = function (button, type, obj)
{
if (button !== this.triggerButton || type !== this.triggerType)
return false; // wrong click type
return this.runtime.testAndSelectCanvasPointOverlap(obj, this.mouseXcanvas, this.mouseYcanvas, false);
};
Cnds.prototype.OnWheel = function (dir)
{
this.handled = true;
return dir === this.triggerDir;
};
pluginProto.cnds = new Cnds();
function Acts() {};
var lastSetCursor = null;
Acts.prototype.SetCursor = function (c)
{
if (this.runtime.isDomFree)
return;
var cursor_style = ["auto", "pointer", "text", "crosshair", "move", "help", "wait", "none"][c];
if (lastSetCursor === cursor_style)
return; // redundant
lastSetCursor = cursor_style;
document.body.style.cursor = cursor_style;
};
Acts.prototype.SetCursorSprite = function (obj)
{
if (this.runtime.isDomFree || this.runtime.isMobile || !obj)
return;
var inst = obj.getFirstPicked();
if (!inst || !inst.curFrame)
return;
var frame = inst.curFrame;
if (lastSetCursor === frame)
return; // already set this frame
lastSetCursor = frame;
var datauri = frame.getDataUri();
var cursor_style = "url(" + datauri + ") " + Math.round(frame.hotspotX * frame.width) + " " + Math.round(frame.hotspotY * frame.height) + ", auto";
document.body.style.cursor = "";
document.body.style.cursor = cursor_style;
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.X = function (ret, layerparam)
{
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxX = layer.parallaxX;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxX = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, true));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxX = oldParallaxX;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, true));
else
ret.set_float(0);
}
};
Exps.prototype.Y = function (ret, layerparam)
{
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxY = layer.parallaxY;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxY = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, false));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxY = oldParallaxY;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, false));
else
ret.set_float(0);
}
};
Exps.prototype.AbsoluteX = function (ret)
{
ret.set_float(this.mouseXcanvas);
};
Exps.prototype.AbsoluteY = function (ret)
{
ret.set_float(this.mouseYcanvas);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.NSG_DataBag = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.NSG_DataBag.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.bags = [];
};
function Cnds() {};
Cnds.prototype.IsBagEmpty = function (bagId_)
{
bagId_ = this.parseBagId(bagId_);
return this.isBagEmpty(bagId_);
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.AddData = function (data_, bagId_)
{
bagId_ = this.parseBagId(bagId_);
if (typeof this.bags[bagId_] === "undefined")
{
this.bags[bagId_] = [];
}
this.bags[bagId_].push(data_);
};
Acts.prototype.ClearBag = function (bagId_)
{
bagId_ = this.parseBagId(bagId_);
if (typeof this.bags[bagId_] === "undefined") return;
this.bags[bagId_] = [];
};
Acts.prototype.ClearAllBags = function ()
{
this.bags = [];
};
Acts.prototype.RemoveData = function (data_, bagId_)
{
bagId_ = this.parseBagId(bagId_);
if (typeof this.bags[bagId_] === "undefined") return;
this.bags[bagId_].splice(this.bags[bagId_].indexOf(data_), 1);
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.CutRandomData = function (ret, bagId_) // 'ret' must always be the first parameter - always return the expression's result through it!
{
bagId_ = this.parseBagId(bagId_);
if (this.isBagEmpty(bagId_))
{
ret.set_any(-1);
}
else
{
var dataIndex = Math.floor(Math.random()*this.bags[bagId_].length);
ret.set_any(this.bags[bagId_][dataIndex]);
this.bags[bagId_].splice(dataIndex, 1);
}
};
pluginProto.exps = new Exps();
instanceProto.parseBagId = function (bagId_)
{
return bagId_.trim().toLowerCase();
}
instanceProto.isBagEmpty = function(bagId_)
{
return typeof this.bags[bagId_] === "undefined" || this.bags[bagId_].length === 0;
}
}());
window['trSmartRedirect'] = function(url_)
{
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
if(inIframe())
{
window.top.location.href = url_;
}
else
{
window.location.href = url_;
}
};
;
;
cr.plugins_.NSG_MobilePopup = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.NSG_MobilePopup.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.android = { image: this.properties[0], URL: this.properties[1] };
this.iOS = { image: this.properties[2], URL: this.properties[3] };
this.closeButtonImageUrl = this.properties[4];
this.currentPlatform = this.runtime.isAndroid ? this.android : this.iOS;
if ( ! this.currentPlatform.image || ! this.currentPlatform.URL) return;
this.isActive = false;
if ( ! this.runtime.isMobile) return;
var i, exceptSources = [
"crazygames.com",
"1001juegos.com",
"speelspelletjes.nl",
"gioca.re",
"onlinegame.co.id"
];
for (i = 0; i < exceptSources.length; ++i)
{
if (document.referrer.indexOf(exceptSources[i]) !== -1)
{
this.isActive = false;
return;
}
}
this.isActive = true;
this.popupDiv = document.createElement("div");
var parent = this.runtime.canvasdiv ? this.runtime.canvasdiv : document.body;
parent.appendChild(this.popupDiv);
this.popupDiv.id = "NSG-mobile-popup";
this.popupDiv.style.width = "100%";
this.popupDiv.style.height = "100%";
this.popupDiv.style.display = "flex";
this.popupDiv.style.backgroundColor = "rgba(0, 0, 0, 0.8)";
this.popupDiv.style.top = "1px";
this.popupDiv.style.left = "1px";
this.popupDiv.style.zIndex = "9997";
this.popupDiv.style.position = "absolute";
this.popupDiv.style.justifyContent = "center";
this.popupDiv.style.alignItems = "center";
this.popupImage = document.createElement("img");
this.popupDiv.appendChild(this.popupImage);
this.popupImage.id = "NSG-mobile-popup-image";
this.popupImage.style.display = "block";
this.popupImage.src = this.currentPlatform.image;
this.popupImage.style.zIndex = "9998";
this.popupImage.style.maxHeight = "90%";
this.popupImage.style.maxWidth = "85%";
this.closeBtn = document.createElement("img");
parent.appendChild(this.closeBtn);
this.closeBtn.id = "NSG-mobile-popup-close-btn";
this.closeBtn.style.display = "flex";
this.closeBtn.src = this.closeButtonImageUrl;
this.closeBtn.style.top = "5%";
this.closeBtn.style.right = "3%";
this.closeBtn.style.zIndex = "9999";
this.closeBtn.style.position = "absolute";
var self = this;
this.popupImage.onclick = function ()
{
window["trSmartRedirect"](self.currentPlatform.URL);
};
this.closeBtn.onclick = function ()
{
self.isActive = false;
self.popupDiv.remove();
self.closeBtn.remove();
self.runtime.trigger(cr.plugins_.NSG_MobilePopup.prototype.cnds.OnClose, self);
}
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.IsActive = function ()
{
return !!this.isActive;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnClose = function ()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.IsActive = function (ret) // 'ret' must always be the first parameter - always return the expression's result through it!
{
ret.set_int( !! this.isActive); // return our value
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.NSG_NicknamesDB = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var isNWjs = false;
var path = null;
var fs = null;
var nw_appfolder = "";
var pluginProto = cr.plugins_.NSG_NicknamesDB.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this._DB = [];
this.lockedNicknames = [];
this.errorMessage = "";
this.filenamePrefix = this.properties[0];
this.filesQty = this.properties[1];
this.filesRemaining = [];
var i;
for (i = 0; i < this.filesQty; ++i)
{
this.filesRemaining.push(i+1);
}
isNWjs = this.runtime.isNWjs;
if (isNWjs)
{
path = require("path");
fs = require("fs");
var process = window["process"] || nw["process"];
nw_appfolder = path["dirname"](process["execPath"]) + "\\";
}
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnLoadingCompleted = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnLoadingFailed = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnAnyError = function ()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.Load = function ()
{
var self = this;
if (this.filesRemaining.length === 0)
{
self.errorMessage = "No more files to load";
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnAnyError, self);
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnLoadingFailed, self);
return;
}
var currentFileNumber, currentFileIndex = Math.floor(Math.random() * this.filesRemaining.length);
currentFileNumber = this.filesRemaining[currentFileIndex];
this.filesRemaining.splice(currentFileIndex, 1);
var file_ = this.filenamePrefix + currentFileNumber;
if (this.runtime.isWKWebView)
{
this.runtime.fetchLocalFileViaCordovaAsText(file_,
function (newNicknames_)
{
newNicknames_ = B.decode(newNicknames_.substring(5<<1^3)).split(",");
self._DB = self._DB.concat(newNicknames_);
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnLoadingCompleted, self);
},
function (err)
{
self.errorMessage = err.message;
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnAnyError, self);
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnLoadingFailed, self);
});
}
else
{
this.doRequest("NicknamesDB_call", file_, "GET");
}
};
instanceProto.doRequest = function (tag_, url_, method_, data_)
{
if (this.runtime.isDirectCanvas)
{
AppMobi["webview"]["execute"]('C2_AJAX_WebSide("' + tag_ + '", "' + url_ + '", "' + method_ + '", ' + (data_ ? '"' + data_ + '"' : "null") + ');');
return;
}
var self = this;
var request = null;
var doErrorFunc = function ()
{
self.errorMessage = "=== loading error 1";
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnAnyError, self);
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnLoadingFailed, self);
};
var errorFunc = function ()
{
if (isNWjs)
{
var filepath = nw_appfolder + url_;
if (fs["existsSync"](filepath))
{
fs["readFile"](filepath, {"encoding": "utf8"}, function (err, newNicknames_) {
if (err)
{
doErrorFunc();
return;
}
newNicknames_ = B.decode(newNicknames_.substring(5<<1^3)).split(",");
self._DB = self._DB.concat(newNicknames_);
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnLoadingCompleted, self);
});
}
else
doErrorFunc();
}
else
doErrorFunc();
};
/*var progressFunc = function (e)
{
if (!e["lengthComputable"])
return;
self.progress = e.loaded / e.total;
self.curTag = tag_;
self.runtime.trigger(cr.plugins_.AJAX.prototype.cnds.OnProgress, self);
};*/
try
{
if (this.runtime.isWindowsPhone8)
request = new ActiveXObject("Microsoft.XMLHTTP");
else
request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (request.readyState === 4)
{
self.curTag = tag_;
if (request.responseText)
{
var newNicknames_ = B.decode(request.responseText.substring(5<<1^3)).split(",");
self._DB = self._DB.concat(newNicknames_);
}
else
self.lastData = "";
if (request.status >= 400)
{
self.errorMessage = "=== loading error 2";
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnAnyError, self);
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnLoadingFailed, self);
}
else
{
if ((!isNWjs || self.lastData.length) && !(!isNWjs && request.status === 0 && !self.lastData.length))
{
self.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnLoadingCompleted, self);
}
}
}
};
if (!this.runtime.isWindowsPhone8)
{
request.onerror = errorFunc;
request.ontimeout = errorFunc;
request.onabort = errorFunc;
}
request.open(method_, url_);
if (!this.runtime.isWindowsPhone8)
{
if (this.timeout >= 0 && typeof request["timeout"] !== "undefined")
request["timeout"] = this.timeout;
}
try {
request.responseType = "text";
} catch (e) {}
/*if (data_)
{
if (request["setRequestHeader"] && !next_request_headers.hasOwnProperty("Content-Type"))
{
request["setRequestHeader"]("Content-Type", "application/x-www-form-urlencoded");
}
}
if (request["setRequestHeader"])
{
var p;
for (p in next_request_headers)
{
if (next_request_headers.hasOwnProperty(p))
{
try {
request["setRequestHeader"](p, next_request_headers[p]);
}
catch (e) {}
}
}
next_request_headers = {};
}
if (next_override_mime && request["overrideMimeType"])
{
try {
request["overrideMimeType"](next_override_mime);
}
catch (e) {}
next_override_mime = "";
}
if (data_)
request.send(data_);
else*/
request.send();
}
catch (e)
{
errorFunc();
}
};
Acts.prototype.Release = function (nickname_)
{
var index = this.lockedNicknames.indexOf(nickname_);
if (index !== -1)
{
this.lockedNicknames.splice(index, 1);
}
};
Acts.prototype.ReleaseAll = function ()
{
this.lockedNicknames = [];
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.RandomNickname = function (ret)
{
var defaultNickname = "Error123";
if (this._DB.length === 0)
{
this.errorMessage = "Cannot fetch a random nickname because the database is empty.";
this.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnAnyError, this);
ret.set_string(defaultNickname);
return;
}
var randomNickname, i = 0;
for (i = 0; i <= 50; ++i)
{
randomNickname = this._DB[Math.floor(Math.random() * this._DB.length)];
if (this.lockedNicknames.indexOf(randomNickname) === -1)
{
this.lockedNicknames.push(randomNickname);
break;
}
else
{
randomNickname = null;
}
}
if ( ! randomNickname)
{
var rawFile = new XMLHttpRequest();
rawFile.open("GET", "names.txt", false);
rawFile.onreadystatechange = function ()
{
var allText = rawFile.responseText;
var split = allText.split('\n')
var randomLine = split[Math.floor(Math.random() * split.length)];
randomNickname = randomLine;
}
rawFile.send(null);
this.errorMessage = "Couldn't find any free nickname with 50 attempts so a default nickname was provided instead.";
this.runtime.trigger(cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnAnyError, this);
}
ret.set_string(randomNickname); // for ef_return_string
};
Exps.prototype.ErrorMsg = function (ret)
{
ret.set_string(this.errorMessage);
};
pluginProto.exps = new Exps();
var B={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(r){var t,e,o,a,h,n,d,C="",i=0;for(r=B._utf8_encode(r);i<r.length;)a=(t=r.charCodeAt(i++))>>2,h=(3&t)<<4|(e=r.charCodeAt(i++))>>4,n=(15&e)<<2|(o=r.charCodeAt(i++))>>6,d=63&o,isNaN(e)?n=d=64:isNaN(o)&&(d=64),C=C+this._keyStr.charAt(a)+this._keyStr.charAt(h)+this._keyStr.charAt(n)+this._keyStr.charAt(d);return C},decode:function(r){var t,e,o,a,h,n,d="",C=0;for(r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");C<r.length;)t=this._keyStr.indexOf(r.charAt(C++))<<2|(a=this._keyStr.indexOf(r.charAt(C++)))>>4,e=(15&a)<<4|(h=this._keyStr.indexOf(r.charAt(C++)))>>2,o=(3&h)<<6|(n=this._keyStr.indexOf(r.charAt(C++))),d+=String.fromCharCode(t),64!=h&&(d+=String.fromCharCode(e)),64!=n&&(d+=String.fromCharCode(o));return d=B._utf8_decode(d)},_utf8_encode:function(r){r=r.replace(/\r\n/g,"\n");for(var t="",e=0;e<r.length;e++){var o=r.charCodeAt(e);o<128?t+=String.fromCharCode(o):o>127&&o<2048?(t+=String.fromCharCode(o>>6|192),t+=String.fromCharCode(63&o|128)):(t+=String.fromCharCode(o>>12|224),t+=String.fromCharCode(o>>6&63|128),t+=String.fromCharCode(63&o|128))}return t},_utf8_decode:function(r){for(var t="",e=0,o=0,a=0,h=0;e<r.length;)(o=r.charCodeAt(e))<128?(t+=String.fromCharCode(o),e++):o>191&&o<224?(a=r.charCodeAt(e+1),t+=String.fromCharCode((31&o)<<6|63&a),e+=2):(a=r.charCodeAt(e+1),h=r.charCodeAt(e+2),t+=String.fromCharCode((15&o)<<12|(63&a)<<6|63&h),e+=3);return t}};
}());
;
;
cr.plugins_.NSG_ObjectJS = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.NSG_ObjectJS.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.data = null;
this.loop_stack_index = -1;
this.loop_stack = [];
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.HasData = function (parameters_)
{
if ( ! this.data) return false;
var i, len = parameters_.length;
if (len === 0) return false;
var data = this.data;
for (i = 0; i < len; ++i)
{
if (typeof data[parameters_[i]] === 'undefined') return false;
data = data[parameters_[i]];
}
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.CompareData = function (parameters_, value_)
{
var i, len = parameters_.length;
if (len === 0) return false;
var data = this.data;
for (i = 0; i < len; ++i)
{
if (typeof data[parameters_[i]] === 'undefined') return false;
data = data[parameters_[i]];
}
return data === value_;
};
/**
* @returns {*} TODO stop loop
*/
Cnds.prototype.ForEachProperty = function (name_, objectsPath_)
{
var i, len = objectsPath_.length;
var targetObject = this.data;
var fullPath = "";
for (i = 0; i < len; ++i)
{
fullPath += "." + objectsPath_[i];
if (typeof targetObject[objectsPath_[i]] === 'undefined')
{
console.warn("[ObjectJS] ForEachProperty `" + fullPath + "` is undefined!")
return false;
}
targetObject = targetObject[objectsPath_[i]];
}
var current_frame = this.runtime.getCurrentEventStack();
var current_event = current_frame.current_event;
var current_loop = this.pushLoopStack(name_);
var key;
for (key in targetObject)
{
if ( ! targetObject.hasOwnProperty(key)) break;
if (current_loop.stopped) break;
current_loop.key = key;
current_loop.value = targetObject[key];
current_event.retrigger();
}
this.popLoopStack();
return false;
};
/**
* @returns {boolean}
*/
Cnds.prototype.IsEmpty = function ()
{
return this.data === null;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.Load = function (json_)
{
this.data = JSON.parse(json_);
this.runtime.trigger(cr.plugins_.NSG_ObjectJS.prototype.cnds.OnUpdate, this);
};
Acts.prototype.ResetData = function ()
{
this.data = null;
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.Get = function (ret, property_)
{
try{
var data = this.data[property_];
}catch (error)
{
console.error(property_, this.data)
}
if (arguments.length > 2)
{
var i, len = arguments.length;
for (i = 2; i < len; ++i)
{
data = data[arguments[i]];
}
}
ret.set_any(data);
};
Exps.prototype.DataAsJson = function (ret)
{
var data = this.data;
if (arguments.length > 1)
{
var i, len = arguments.length;
for (i = 1; i < len; ++i)
{
data = data[arguments[i]];
}
}
ret.set_string(JSON.stringify(data));
};
Exps.prototype.LoopKey = function(ret, name_)
{
var loop, i;
if (!this.loop_stack.length)
{
ret.set_string("ERR");
return;
}
if (name_)
{
for (i = this.loop_stack_index; i >= 0; --i)
{
loop = this.loop_stack[i];
if (loop.name === name_)
{
ret.set_string(loop.key);
return;
}
}
ret.set_string("-1");
}
else
{
loop = this.getCurrentLoop();
ret.set_string(loop ? loop.key : "-1");
}
};
Exps.prototype.LoopValue = function(ret, name_)
{
var loop, i;
if (!this.loop_stack.length)
{
ret.set_any("ERR");
return;
}
if (name_)
{
for (i = this.loop_stack_index; i >= 0; --i)
{
loop = this.loop_stack[i];
if (loop.name === name_)
{
ret.set_any(loop.value);
return;
}
}
ret.set_any("-1");
}
else
{
loop = this.getCurrentLoop();
ret.set_any(loop ? loop.value : "-1");
}
};
pluginProto.exps = new Exps();
instanceProto.pushLoopStack = function (name_)
{
this.loop_stack_index++;
if (this.loop_stack_index >= this.loop_stack.length)
{
this.loop_stack.push(cr.seal({ name: name_, index: 0, key: "", value: "", stopped: false }));
}
var ret = this.getCurrentLoop();
ret.name = name_;
ret.index = 0;
ret.key = "";
ret.value;
ret.stopped = false;
return ret;
};
instanceProto.popLoopStack = function ()
{
;
this.loop_stack_index--;
};
instanceProto.getCurrentLoop = function ()
{
return this.loop_stack[this.loop_stack_index];
};
}());
;
;
cr.plugins_.NSG_PowerWS = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.NSG_PowerWS.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
var isSupported = (typeof WebSocket !== "undefined");
var last_url = "";
instanceProto.onCreate = function()
{
this.stop = false;
this.isWSReady = false;
this.messageText = "";
this.errorMsg = "";
this.closeCode = "";
this.closeReason = "";
this.messageOutgoing = null;
this.currentAction = "";
this.messageIncoming = { action: "", data: "", timestamp: "" };
var self = this;
this.pingTesterSetup = {
pingRequired: 0,
maximumAttempts: 0,
testsInterval: 0,
urls: []
};
this.isPingTesterBusy = false;
this.pingTesterResults = null;
this.currentInstanceVarTrigger = { objInst: null, varIndex: -1};
this.ping = -1;
this.pingFrequency = this.properties[0] | 1;
this.rawArray = [];
this.syncTagData = {};
this.SYNC_TYPE = { POSITION_OBJECT: 0, ANGLE_OBJECT: 1, POSITION_ANGLE_OBJECT: 2, MOVE_OBJECT: 3, MOVE_AIM_OBJECT: 4 };
this.objectsMapData = { byUID: [], bySUID: [] };
this.objectsMap = {
/*hasId: function(tag, serverId)
{
return typeof self.objectsMapData[tag] !== 'undefined' && self.objectsMapData[tag] !== null && typeof self.objectsMapData[tag][serverId] !== 'undefined' && self.objectsMapData[tag][serverId] !== null;
},*/
existsBySUID: function(serverUID_)
{
return typeof self.objectsMapData.bySUID[serverUID_] !== 'undefined';
},
getUidBySUID: function(serverUID_)
{
return self.objectsMapData.bySUID[serverUID_].uid;
},
getTagBySUID: function(serverUID_)
{
return self.objectsMapData.bySUID[serverUID_].tag;
},
getTagByUID: function(serverUID_)
{
return self.objectsMapData.byUID[serverUID_].tag;
},
/*addUid: function(tag, serverId, uid)
{
if (typeof self.objectsMapData[tag] === 'undefined')
{
self.objectsMapData[tag] = {};
}
self.objectsMapData[tag][serverId] = uid;
},*/
addObject: function(tag_, serverUID_, instanceUID_)
{
var objData = {
uid: instanceUID_,
suid: serverUID_,
tag: tag_
}
self.objectsMapData.bySUID[serverUID_] = objData;
self.objectsMapData.byUID[instanceUID_] = objData;
},
removeBySUID: function(serverUID_)
{
var uid = self.objectsMapData.bySUID[serverUID_].uid;
delete self.objectsMapData.byUID[uid];
delete self.objectsMapData.bySUID[serverUID_];
}
};
/*this.ping = {
frequency: this.properties[0],
handler: null
};*/
/*if (typeof window['msgpack'] !== 'undefined')
{
this.msgPack = window['msgpack'];
}*/
this.movingObjects = {
byUID: {},
addObject: function (UID_)
{
this.byUID[UID_] = {};
this.byUID[UID_].lastUpdateTimestamp = 0;
},
removeObject: function (UID_)
{
delete this.byUID[UID_];
},
setTimestamp: function (UID_, timestamp_)
{
this.byUID[UID_].lastUpdateTimestamp = timestamp_;
}
};
this.wsWorker = new Worker("ws_worker.js?" + window['NSG_G_VER']);
this.wsWorker.onmessage = function(event)
{
switch(event.data.action)
{
case "ping":
self.ping = event.data.data;
self.runtime.trigger(cr.plugins_.NSG_PowerWS.prototype.cnds.OnPong, self);
break;
case "pingTester":
self.isPingTesterBusy = false;
self.pingTesterResults = event.data.data;
self.runtime.trigger(cr.plugins_.NSG_PowerWS.prototype.cnds.OnPingTesterFinished, self);
break;
case "message":
var action = event.data.data[0];
self.messageIncoming.timestamp = event.data.timestamp;
if (typeof action === "string")
{
if (typeof self.syncTagData[action] === "undefined")
{
self.messageIncoming.action = action;
self.messageIncoming.data = event.data.data;
self.runtime.trigger(cr.plugins_.NSG_PowerWS.prototype.cnds.OnEvent, self);
self.runtime.trigger(cr.plugins_.NSG_PowerWS.prototype.cnds.OnAnyEvent, self);
}
else
{
self.messageIncoming.action = "PowerWS-auto-spawn";
self.messageIncoming.data = "";
self.syncSpawnObjectsOfType(event.data.data);
}
}
else
{
if (typeof action === "undefined")
{
console.log(JSON.stringify(event.data))
console.log(JSON.stringify(event.data.data))
}
if (typeof action[0] === "string")
{
let i, len = event.data.data.length;
for (i = 0; i < len; ++i)
{
if (typeof self.syncTagData[event.data.data[i][0]] === "undefined")
{
console.warn("TAG '", event.data.data[i][0], "' is not synced!");
continue;
}
self.syncSpawnObjectsOfType(event.data.data[i]);
}
}
else
{
if (typeof action === "number") // update single
{
self.syncUpdateObject(event.data.data);
}
else // update mass
{
let i, len = event.data.data.length;
for (i = 0; i < len; ++i)
{
self.syncUpdateObject(event.data.data[i]);
}
}
}
}
break;
case "connect":
if (cr.is_undefined(event.data.errorMsg)) // ERR_MSG is on index 1
{
self.isWSReady = true;
self.runtime.trigger(cr.plugins_.NSG_PowerWS.prototype.cnds.OnOpened, self);
}
else
{
self.closeCode = "CONNECT_ERROR";
self.errorMsg = event.data.errorMsg;
self.runtime.trigger(cr.plugins_.NSG_PowerWS.prototype.cnds.OnError, self);
}
break;
case "close":
self.isWSReady = false;
self.closeCode = event.data.closeCode;
self.closeReason = event.data.closeReason;
self.runtime.trigger(cr.plugins_.NSG_PowerWS.prototype.cnds.OnClosed, self);
break;
}
};
var workerData = {
action: "setPing",
data: this.pingFrequency
}
this.wsWorker.postMessage(workerData);
this.runtime.tickMe(this);
};
instanceProto.tick = function()
{
var currentTimestamp = Date.now();
var movingUID, inst, dist, moveSpeed, moveAngle, objectTag, syncType;
for (movingUID in this.movingObjects.byUID)
{
if ( ! this.movingObjects.byUID.hasOwnProperty(movingUID)) continue;
objectTag = this.objectsMap.getTagByUID(movingUID);
inst = this.runtime.getObjectByUID(movingUID);
if ( ! inst)
{
this.movingObjects.removeObject(movingUID);
continue;
}
moveSpeed = inst.instance_vars[this.syncTagData[objectTag].moveSpeedVar];
dist = (currentTimestamp - this.movingObjects.byUID[movingUID].lastUpdateTimestamp) / 1000 * moveSpeed;
syncType = this.syncTagData[objectTag].syncType;
if (syncType === this.SYNC_TYPE.MOVE_OBJECT)
{
moveAngle = inst.angle;
}
else
if (syncType === this.SYNC_TYPE.MOVE_AIM_OBJECT)
{
moveAngle = cr.to_radians(inst.instance_vars[this.syncTagData[objectTag].moveAngleVar]);
}
if (dist !== 0)
{
inst.x += Math.cos(moveAngle) * dist;
inst.y += Math.sin(moveAngle) * dist;
inst.set_bbox_changed();
}
this.movingObjects.setTimestamp(inst.uid, currentTimestamp);
}
}
instanceProto.saveToJSON = function ()
{
return { "messageText": this.messageText, "errorMsg": this.errorMsg };
};
instanceProto.loadFromJSON = function (o)
{
this.messageText = o["messageText"];
this.errorMsg = o["errorMsg"];
};
function Cnds() {};
Cnds.prototype.OnOpened = function ()
{
return true;
};
Cnds.prototype.OnPong = function ()
{
return true;
};
Cnds.prototype.OnClosed = function ()
{
return true;
};
Cnds.prototype.OnError = function ()
{
return true;
};
Cnds.prototype.OnAnyEvent = function ()
{
return true;
};
Cnds.prototype.OnEvent = function (name_, comment_)
{
return cr.equals_nocase(name_, this.messageIncoming.action);
};
Cnds.prototype.OnRawData = function ()
{
return true;
};
Cnds.prototype.IsOpen = function ()
{
return this.isWSReady;
};
Cnds.prototype.IsConnecting = function ()
{
return !this.isWSReady;
};
Cnds.prototype.IsSupported = function ()
{
return isSupported;
};
Cnds.prototype.OnPingTesterFinished = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.HasData = function (parameters_)
{
var i, len = parameters_.length;
if (len === 0) return false;
var data = this.messageIncoming.data;
for (i = 0; i < len; ++i)
{
if (typeof data[parameters_[i]] === 'undefined') return false;
data = data[parameters_[i]];
}
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.CompareData = function (parameters_, value_)
{
var i, len = parameters_.length;
if (len === 0) return false;
var data = this.messageIncoming.data;
for (i = 0; i < len; ++i)
{
if (typeof data[parameters_[i]] === 'undefined') return false;
data = data[parameters_[i]];
}
return data === value_;
};
Cnds.prototype.OnInstanceVariableChanged = function(type_, variableIndex_)
{
if (type_ === this.currentInstanceVarTrigger.objInst.type && variableIndex_ === this.currentInstanceVarTrigger.varIndex)
{
var sol = type_.getCurrentSol();
sol.select_all = false;
sol.instances.length = 0;
sol.instances.push(this.currentInstanceVarTrigger.objInst);
return true;
}
return false;
};
Cnds.prototype.IsPingTesterBusy = function()
{
return this.isPingTesterBusy;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.Connect = function (url_, requireProtocol_)
{
if (!isSupported)
return;
var workerData = {
action: "connect",
url: url_,
requireProtocol: requireProtocol_
}
this.wsWorker.postMessage(workerData);
};
Acts.prototype.SendPing = function ()
{
var workerData = {
action: "sendPing"
}
this.wsWorker.postMessage(workerData);
};
Acts.prototype.Close = function ()
{
var workerData = {
action: "close"
}
this.wsWorker.postMessage(workerData);
/*this.stop = true;
var workerData = {
action: "stop"
}
this.wsWorker.postMessage(workerData);*/
};
Acts.prototype.SetMessage = function (property_, value_)
{
if (this.messageOutgoing === null)
{
this.messageOutgoing = {};
}
this.messageOutgoing[property_] = value_;
};
Acts.prototype.SetArray = function (property_)
{
if (this.messageOutgoing === null)
{
this.messageOutgoing = {};
}
this.messageOutgoing[property_] = [];
};
Acts.prototype.AddToArray = function (property_, value_)
{
if (this.messageOutgoing === null)
{
this.messageOutgoing = {};
}
this.messageOutgoing[property_].push(value_);
};
Acts.prototype.Send = function (actionName_)
{
var sendObj = {
a: actionName_
};
if (this.messageOutgoing !== null)
{
sendObj.d = this.messageOutgoing;
}
var workerData = {
action: "send",
data: sendObj
}
this.wsWorker.postMessage(workerData);
this.messageOutgoing = null;
};
Acts.prototype.SendRaw = function (data_)
{
var workerData = {
action: "sendRaw",
data: data_
}
this.wsWorker.postMessage(workerData);
};
Acts.prototype.AddToRawArray = function (data_)
{
this.rawArray.push(data_);
};
Acts.prototype.SendRawArray = function ()
{
var workerData = {
action: "send",
data: this.rawArray
}
this.wsWorker.postMessage(workerData);
this.rawArray = [];
};
Acts.prototype.SyncStaticObject = function(type_, idVariable_, messageTag_, syncType_, layer_)
{
if (type_.is_family)
{
console.warn("[PowerWS] 'SyncObject' can't use family type");
return;
}
this.syncTagData[messageTag_] = {
idVariable: idVariable_,
type: type_,
syncType: syncType_,
layer: layer_
};
};
Acts.prototype.SyncMovingObject = function(type_, idVariable_, messageTag_, layer_, moveSpeedVar_)
{
if (type_.is_family)
{
console.warn("[PowerWS] 'SyncMovingObject' can't use family type");
return;
}
this.syncTagData[messageTag_] = {
idVariable: idVariable_,
type: type_,
syncType: this.SYNC_TYPE.MOVE_OBJECT,
layer: layer_,
moveSpeedVar: moveSpeedVar_
};
};
Acts.prototype.SyncMoveAimObject = function(type_, idVariable_, messageTag_, layer_, moveAngleVar_, moveSpeedVar_)
{
if (type_.is_family)
{
console.warn("[PowerWS] 'SyncMoveAimObject' can't use family type");
return;
}
this.syncTagData[messageTag_] = {
idVariable: idVariable_,
type: type_,
syncType: this.SYNC_TYPE.MOVE_AIM_OBJECT,
layer: layer_,
moveAngleVar: moveAngleVar_,
moveSpeedVar: moveSpeedVar_
};
};
Acts.prototype.SyncObjectInstanceVar = function(type_, variableIndex_, instanceVariableTag_, shouldTrigger_)
{
for (var objectTag in this.syncTagData)
{
if ( ! this.syncTagData.hasOwnProperty(objectTag)) continue;
if (this.syncTagData[objectTag].type !== type_) continue;
if (typeof this.syncTagData[objectTag].vars === 'undefined')
{
this.syncTagData[objectTag].vars = {};
}
this.syncTagData[objectTag].vars[instanceVariableTag_] = {
index: variableIndex_,
shouldTrigger: !!shouldTrigger_
};
return;
}
};
Acts.prototype.AddURLToPingTester = function(url_)
{
this.pingTesterSetup.urls.push(url_);
};
Acts.prototype.StartPingTester = function(pingRequired_, maximumAttempts_, testsInterval_)
{
maximumAttempts_ = maximumAttempts_ < 1 ? 1 : maximumAttempts_;
testsInterval_ = testsInterval_ < 0 ? 1 : testsInterval_;
this.pingTesterSetup.pingRequired = pingRequired_;
this.pingTesterSetup.maximumAttempts = maximumAttempts_;
this.pingTesterSetup.testsInterval = testsInterval_;
if (this.pingTesterSetup.urls.length > 0)
{
this.isPingTesterBusy = true;
var workerData = {
action: "startPingTester",
data: this.pingTesterSetup
}
this.wsWorker.postMessage(workerData);
}
else
{
console.warn("[NSG_PowerWS] StartPingTester: URLs array empty. Nothing to test.")
}
this.pingTesterSetup = {
pingRequired: 0,
maximumAttempts: 0,
testsInterval: 0,
urls: []
}
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.Data = function (ret, property_)
{
var data = this.messageIncoming.data[property_];
if (arguments.length > 2)
{
var i, len = arguments.length;
for (i = 2; i < len; ++i)
{
data = data[arguments[i]];
}
}
ret.set_any(data);
};
Exps.prototype.DataAsJson = function (ret)
{
var data = this.messageIncoming.data;
var i, len = data.length;
var isFound = false;
for (i = 0; i < len; ++i)
{
if (typeof data[i] === "object" && !(data[i] instanceof Array) )
{
data = JSON.parse(JSON.stringify(data [i])); /// TODO--------------
isFound = true;
break;
}
}
if (data === null) console.warn(this.messageIncoming)
if (isFound)
if (arguments.length > 1)
{
len = arguments.length;
for (i = 1; i < len; ++i)
{
data = data[arguments[i]];
}
}
ret.set_string(JSON.stringify(data));
};
Exps.prototype.ErrorMsg = function (ret)
{
ret.set_string(cr.is_string(this.errorMsg) ? this.errorMsg : "");
};
Exps.prototype.CloseCode = function (ret)
{
ret.set_string(String(this.closeCode));
};
Exps.prototype.CloseReason = function (ret)
{
ret.set_string(this.closeReason);
};
Exps.prototype.Ping = function (ret)
{
ret.set_int(this.ping);
};
Exps.prototype.Timestamp = function (ret)
{
ret.set_int(this.messageIncoming.timestamp);
};
Exps.prototype.PingTesterResult = function (ret, testIndex_)
{
if ( ! this.pingTesterResults || typeof this.pingTesterResults[testIndex_] === 'undefined')
{
ret.set_int(-1);
return;
}
ret.set_int(this.pingTesterResults[testIndex_].minPing);
};
pluginProto.exps = new Exps();
instanceProto.syncInstanceVariables = function (customData_, vars_, inst_) // custom data
{
for (var customDataTag in customData_)
{
if ( ! customData_.hasOwnProperty(customDataTag)) continue;
if (typeof vars_ === "undefined")
{
console.warn("No instance variable synced for tag '" + customDataTag + "'; object hint:", inst_.curFrame.texture_file);
return;
}
if (typeof vars_[customDataTag] !== 'undefined')
{
var isTriggerNeeded = false;
if (vars_[customDataTag].shouldTrigger === true
&& inst_.instance_vars[vars_[customDataTag].index] !== customData_[customDataTag])
{
isTriggerNeeded = true;
}
inst_.instance_vars[vars_[customDataTag].index] = customData_[customDataTag];
if (isTriggerNeeded === true)
{
this.currentInstanceVarTrigger = { objInst: inst_, varIndex: vars_[customDataTag].index};
this.runtime.trigger(cr.plugins_.NSG_PowerWS.prototype.cnds.OnInstanceVariableChanged, this);
this.currentInstanceVarTrigger = { objInst: null, varIndex: -1};
}
}
}
};
instanceProto.syncSpawnObjectsOfType = function (data_)
{
var inst, serverUID, i, len = data_.length;
var objectTag = data_[0];
for (i = 1; i < len; ++i)
{
serverUID = parseInt(data_[i][0]);
if ( ! this.syncTagData[objectTag].layer)
{
console.warn('[PowerWS]: Cannot create instance for tag "' + objectTag + '", server uid ' + serverUID) + ", because the target layer does not exist!";
continue;
}
inst = this.runtime.createInstance(this.syncTagData[objectTag].type, this.syncTagData[objectTag].layer, 0, 0);
if ( ! inst)
{
console.warn('[PowerWS]: Cannot create instance for tag "' + objectTag + '", server uid ' + serverUID);
continue;
}
this.objectsMap.addObject(objectTag, serverUID, inst.uid);
inst.instance_vars[this.syncTagData[objectTag].idVariable] = serverUID;
var syncType = this.syncTagData[objectTag].syncType;
if (syncType === this.SYNC_TYPE.MOVE_OBJECT || syncType === this.SYNC_TYPE.MOVE_AIM_OBJECT)
{
this.movingObjects.addObject(inst.uid);
}
this.syncUpdateObject(data_[i]);
this.runtime.isInOnDestroy++;
var j, lenj, s;
this.runtime.trigger(Object.getPrototypeOf(this.syncTagData[objectTag].type.plugin).cnds.OnCreated, inst);
if (inst.is_contained)
{
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
{
s = inst.siblings[j];
this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
}
}
this.runtime.isInOnDestroy--;
}
}
instanceProto.syncUpdateObject = function (data_)
{
var i, len = data_.length;
var serverUID = parseInt(data_[0]);
if ( ! this.objectsMap.existsBySUID(serverUID))
{
console.warn("[PowerWS]: Cannot update instance server uid", serverUID, "because it doesn't exist in the client.");
return;
}
var objectTag = this.objectsMap.getTagBySUID(serverUID);
var uid = this.objectsMap.getUidBySUID(serverUID);
var inst = this.runtime.getObjectByUID(uid);
if ( ! inst)
{
console.warn('[PowerWS]: Cannot load & update instance for tag "' + objectTag + '", server uid ' + serverUID);
return;
}
if (data_.length === 1)
{
this.movingObjects.removeObject(inst.uid);
this.runtime.DestroyInstance(inst);
this.objectsMap.removeBySUID(serverUID);
return;
}
var syncType = this.syncTagData[objectTag].syncType;
switch (syncType)
{
case this.SYNC_TYPE.MOVE_OBJECT:
if (data_[1] !== 0)
{
inst.x = data_[1][0];
inst.y = data_[1][1];
inst.angle = cr.to_radians(data_[1][2]);
if (typeof data_[1][3] !== "undefined")
{
inst.instance_vars[this.syncTagData[objectTag].moveSpeedVar] = data_[1][3];
}
this.movingObjects.setTimestamp(inst.uid, this.messageIncoming.timestamp);
inst.set_bbox_changed();
}
if (typeof data_[2] !== "undefined")
{
this.syncInstanceVariables(data_[2], this.syncTagData[objectTag].vars, inst);
}
break;
case this.SYNC_TYPE.MOVE_AIM_OBJECT:
if (data_[1] !== 0)
{
if (typeof data_[1] === "number")
{
inst.angle = cr.to_radians(data_[1]);
}
else
{
inst.angle = cr.to_radians(data_[1][0]);
inst.instance_vars[this.syncTagData[objectTag].moveSpeedVar] = data_[1][1];
this.movingObjects.setTimestamp(inst.uid, this.messageIncoming.timestamp);
}
}
if (typeof data_[2] !== "undefined" && data_[2] !== 0)
{
try
{
inst.x = data_[2][0];
inst.y = data_[2][1];
this.movingObjects.setTimestamp(inst.uid, this.messageIncoming.timestamp);
}catch (e)
{
console.log(data_)
}
if (typeof data_[2][2] !== "undefined")
{
inst.instance_vars[this.syncTagData[objectTag].moveAngleVar] = data_[2][2];
this.movingObjects.setTimestamp(inst.uid, this.messageIncoming.timestamp);
}
inst.set_bbox_changed();
}
if (typeof data_[3] !== "undefined")
{
this.syncInstanceVariables(data_[3], this.syncTagData[objectTag].vars, inst);
}
break;
case this.SYNC_TYPE.POSITION_OBJECT:
if (data_[1] !== 0)
{
inst.x = data_[1][0];
inst.y = data_[1][1];
inst.set_bbox_changed();
}
if (typeof data_[2] !== "undefined")
{
this.syncInstanceVariables(data_[2], this.syncTagData[objectTag].vars, inst);
}
break;
case this.SYNC_TYPE.POSITION_ANGLE_OBJECT:
/*inst.x = currentObjectData[0];
inst.y = currentObjectData[1];
inst.angle = cr.to_radians(currentObjectData[2]);
inst.set_bbox_changed();*/
break;
case this.SYNC_TYPE.ANGLE_OBJECT:
break;
}
}
}());
window["NSG_REFERRER"] = "";
if (typeof window['NSG_GD_REF'] !== "undefined")
{
window["NSG_REFERRER"] = window['NSG_GD_REF'];
}
else
{
window["NSG_REFERRER"] = document.referrer.replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0];
if ( ! window["NSG_REFERRER"] || window["NSG_REFERRER"] === "") window["NSG_REFERRER"] = window.location.hostname;
}
console.log("NSG_REF", window["NSG_REFERRER"]);
;
;
cr.plugins_.NSG_Referrer = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.NSG_Referrer.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
};
function Cnds() {};
/***
* @returns {boolean}
*/
Cnds.prototype.Contains = function (hostname_)
{
return !(window["NSG_REFERRER"].indexOf(hostname_) === -1);
};
pluginProto.cnds = new Cnds();
function Acts() {};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.Referrer = function (ret) // 'ret' must always be the first parameter - always return the expression's result through it!
{
ret.set_string(window["NSG_REFERRER"]); // for ef_return_string
};
pluginProto.exps = new Exps();
}());
window["NSG_WebAdsPro_MedList"] = window["NSG_WebAdsPro_MedList"] || {};
window["NSG_WebAdsPro_Setup"] = {
preroll: { pointer: 0, sequence: ["a","c?"], mode: "sequence", frequency: 40, skipFirst: false, adWidth: 960, adHeight: 540, isFullscreen: false },
rewarded: { pointer: 0, sequence: ["a","c?"], mode: "sequence" }
};
var IS_ADBLOCKED = false;
var xhttp = new XMLHttpRequest ();
xhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 0)
IS_ADBLOCKED = true;
if(this.readyState ===4 && this.status ===200)
IS_ADBLOCKED = false;
};
xhttp.open ("GET", "adsbygoogle.js", true);
xhttp.send ();
/*
window["NSG_WebAdsPro_Setup"] = {
preroll: { pointer: 0, sequence: ["a","a"], mode: "sequence", frequency: 20, skipFirst: false, adWidth: 960, adHeight: 540, isFullscreen: false },
rewarded: { pointer: 0, sequence: ["a","c"], mode: "sequence" },
banner300: { pointer: 0, sequence: ["c","a"], mode: 'sequence', auid: {a: "seadragons-io_300x250", c: "banner300x250"}, timeFrequency: 40, impressionsFrequency: 2, safePeriod: 10 },
banner728: { pointer: 0, sequence: ["c","a"], mode: 'ab', auid: {a: "seadragons-io_728x90", c: "banner728x90"}, timeFrequency: 40, impressionsFrequency: 2, safePeriod: 10 },
banner970: { pointer: 0, sequence: ["c","a"], mode: 'sequence', auid: {a: "seadragons-io_970x250", c: "banner970x250"}, timeFrequency: 40, impressionsFrequency: 2, safePeriod: 10 }
};
*/
;
;
cr.plugins_.NSG_WebAdsPro = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var AD_TYPE = {
PREROLL: 'preroll',
REWARDED: 'rewarded'
};
var AD_MODE = {
AB: 'ab',
RANDOM: 'random',
SEQUENCE_INIT: 'sequence', // (in settings use "sequence") pointer should not move for sequence at first run, so we use it to detect the first run
SEQUENCE: 'sequence_ok'
};
var pluginProto = cr.plugins_.NSG_WebAdsPro.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
window["NSG_WebAdsPro_Core"] = this;
this.IS_IN_PREVIEW = (typeof cr_is_preview !== "undefined");
this.NSG_refSite = document.referrer.replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0];
if ( ! this.NSG_refSite || this.NSG_refSite === "") this.NSG_refSite = window.location.hostname;
var self = this;
this.setup = window["NSG_WebAdsPro_Setup"];
this.bannerLayoutInstanceByAdUnitId = {};
this.bannerAdTypeByAdUnitId = {};
this.bannerActiveByAdType = {};
this.isSetupDownloaded = false;
this.isRemoteSetupCompleted = false;
this.activeMediators = [];
this.DEBUG_MODE = !!this.properties[0];
this.TEST_MODE = !!this.properties[1];
this.gdprPosition = this.properties[2];
this.remoteAdsSetup = {
URL: this.properties[3],
PID: this.properties[4],
TOKEN: this.properties[5]
};
if (localStorage.getItem("NSG_DEBUG_MODE_ON") === "yes")
{
this.DEBUG_MODE = true;
}
this.DUMMY_ADS_MODE = (this.IS_IN_PREVIEW || this.NSG_refSite.includes("nsteed.dev")) && ! this.TEST_MODE;
this.frequencyTimer = null;
this.adInvokes = {};
for (var mediationTag in window["NSG_WebAdsPro_MedList"])
{
if ( ! window["NSG_WebAdsPro_MedList"].hasOwnProperty(mediationTag)) continue;
if (typeof window["NSG_WebAdsPro_MedList"][mediationTag].coreHandshake === "function")
{
window["NSG_WebAdsPro_MedList"][mediationTag].coreHandshake();
}
}
this.fetchRemoteSetup();
};
instanceProto.fetchRemoteSetup = function()
{
this.debugLog(">> Fetching remote setup from " + this.remoteAdsSetup.URL);
if (this.remoteAdsSetup.URL.trim() === "")
{
this.debugLog("<< remote setup failed, no remote URL found");
return;
}
/*var NSG_refSite = document.referrer.replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0];
if ( ! NSG_refSite || NSG_refSite === "") NSG_refSite = window.location.hostname;*/
if (window.location.href.indexOf("gamemonetize.com") > -1)
{
this.NSG_refSite = "gamemonetize.com";
}
var remoteSetupURL = this.remoteAdsSetup.URL;
var remoteSetupParams = {
gameTag: this.remoteAdsSetup.PID,
token: this.remoteAdsSetup.TOKEN,
source: this.NSG_refSite
};
var self = this;
var IDX_COUNTRY_CODE = "NSG_WebAdsPro_CountryCode";
if (localStorage.getItem(IDX_COUNTRY_CODE))
{
this.debugLog(">> found country code in storage: " + localStorage.getItem(IDX_COUNTRY_CODE));
remoteSetupParams["geo"] = localStorage.getItem(IDX_COUNTRY_CODE);
this.debugLog(">> remote URL params changed to: " + JSON.stringify(remoteSetupParams));
}
remoteSetupURL += (remoteSetupURL.includes("?") ? "&" : "?") + "d=" + window.btoa(JSON.stringify(remoteSetupParams));
this.debugLog(">> remote URL changed to: " + remoteSetupURL);
var mediationTag;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === XMLHttpRequest.DONE) {
if (xmlhttp.status === 200)
{
self.debugLog("Raw server data:");
self.debugLog(xmlhttp.responseText);
var response = JSON.parse(Secret.decode(xmlhttp.responseText));
self.debugLog("Decoded server data:");
self.debugLog(response);
if (typeof response["country"] !== "undefined" && response["country"] && response["country"].trim() !== "")
{
localStorage.setItem(IDX_COUNTRY_CODE, response["country"]);
}
self.setup = response["setup"];
self.initMediators();
self.isSetupDownloaded = true;
self.isRemoteSetupCompleted = true;
self.debugLog("<< remote setup downloaded");
self.debugLog(self.setup);
}
else
{
self.initMediators();
self.debugLog("<< remote setup failed with HTTP status", xmlhttp.status);
self.isRemoteSetupCompleted = true;
}
}
};
xmlhttp.open("GET", remoteSetupURL, true);
xmlhttp.send();
};
instanceProto.initMediators = function()
{
var mediationTag;
var medTagsInConfig = [];
var self = this;
for (var adType in self.setup)
{
if ( ! self.setup.hasOwnProperty(adType)) continue;
self.setup[adType].pointer = 0;
if (typeof self.setup[adType].sequence === "string")
{
self.setup[adType].sequence = self.setup[adType].sequence.replace(/\s/g, "").split(",");
}
medTagsInConfig = medTagsInConfig.concat(self.setup[adType].sequence);
}
medTagsInConfig = medTagsInConfig.filter((a, b) => medTagsInConfig.indexOf(a) === b);
for (var i = 0; i < medTagsInConfig.length; ++i)
{
medTagsInConfig[i] = self.getCleanMediationTag(medTagsInConfig[i]);
}
for (mediationTag in window["NSG_WebAdsPro_MedList"])
{
if ( ! window["NSG_WebAdsPro_MedList"].hasOwnProperty(mediationTag)) continue;
if (medTagsInConfig.indexOf(mediationTag) === -1) continue;
if (typeof window["NSG_WebAdsPro_MedList"][mediationTag].initializeMediator === "function")
{
window["NSG_WebAdsPro_MedList"][mediationTag].initializeMediator();
}
}
this.activeMediators = medTagsInConfig;
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.IsGDPRPopupPreloaded = function()
{
if (this.isRemoteSetupCompleted === false)
{
this.debugLog("Remote setup is not yet completed.");
return false;
}
if (typeof window["NSG_WebAdsPro_MedList"]["a"] === "undefined")
{
this.debugLog("Mediation tag \"a\" is not found.");
return false;
}
if (this.activeMediators.indexOf("a") === -1)
{
this.debugLog("Mediation tag \"a\" is not active in this session so GDPR passed automatically.");
return true;
}
return window["NSG_WebAdsPro_MedList"]["a"].isGDPRPreloaded;
};
/**
* @returns {boolean}
*/
Cnds.prototype.IsAdblocked = function()
{
return IS_ADBLOCKED;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnGDPRPopupOpened = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnGDPRPopupClosed = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnRewardedSuccessful = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnRewardedCanceled = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnRewardedEmpty = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnRewardedStart = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnPrerollStart = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnPrerollClosed = function()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetPrerollAdGlobalSettings = function (mode_, frequency_, skipFirst_, position_, adWidth_, adHeight_, sequence_)
{
if (this.isSetupDownloaded === true)
{
this.debugLog("Remote setup downloaded, ignoring local preroll setup request.");
return;
}
switch (mode_)
{
case 0: mode_ = "sequence"; break;
case 1: mode_ = "ab"; break;
case 2: mode_ = "random"; break;
}
sequence_ = sequence_.replace(/\s/g, "").split(",");
this.setup['preroll'] = {
pointer: 0,
sequence: sequence_,
mode: mode_,
frequency: frequency_,
skipFirst: !!skipFirst_,
adWidth: adWidth_,
adHeight: adHeight_,
isFullscreen: !!position_
};
this.initMediators();
};
Acts.prototype.SetRewardedAdGlobalSettings = function (mode_, sequence_)
{
if (this.isSetupDownloaded === true)
{
this.debugLog("Remote setup downloaded, ignoring local rewarded setup request.");
return;
}
switch (mode_)
{
case 0: mode_ = "sequence"; break;
case 1: mode_ = "ab"; break;
case 2: mode_ = "random"; break;
}
sequence_ = sequence_.replace(/\s/g, "").split(",");
this.setup['rewarded'] = {
pointer: 0,
sequence: sequence_,
mode: mode_
};
this.initMediators();
};
Acts.prototype.SetBannerAdGlobalSettings = function (bannerId_, mode_, impressionsFrequency_, timeFrequency_, safePeriod_, auids_, sequence_)
{
if (this.isSetupDownloaded === true)
{
this.debugLog("Remote setup downloaded, ignoring local banner " + bannerId_ + " setup request.");
return;
}
switch (mode_)
{
case 0: mode_ = "sequence"; break;
case 1: mode_ = "ab"; break;
case 2: mode_ = "random"; break;
}
sequence_ = sequence_.replace(/\s/g, "").split(",");
var i, row, tmpAuids = auids_.replace(/\s/g, "").split("|");
var auidsObj = {};
for (i = 0; i < tmpAuids.length; ++i)
{
row = tmpAuids[i].split(":");
auidsObj[row[0]] = row[1];
}
this.setup[bannerId_] = {
pointer: 0,
sequence: sequence_,
mode: mode_,
auid: auidsObj,
timeFrequency: timeFrequency_,
impressionsFrequency: impressionsFrequency_,
safePeriod: safePeriod_
};
this.initMediators();
};
Acts.prototype.Initialize = function ()
{
for (var mediationTag in window["NSG_WebAdsPro_MedList"])
{
if ( ! window["NSG_WebAdsPro_MedList"].hasOwnProperty(mediationTag)) continue;
if (this.activeMediators.indexOf(mediationTag) === -1)
{
this.debugLog("Mediation TAG " + mediationTag + " is not in activeMediators. Initialization skipped.");
continue;
}
if (typeof window["NSG_WebAdsPro_MedList"][mediationTag].initialize !== "function")
{
this.debugLog("Mediation TAG " + mediationTag + " does not have 'initialize' function!");
continue;
}
window["NSG_WebAdsPro_MedList"][mediationTag].initialize();
}
};
Acts.prototype.ShowPrerollAd = function ()
{
if (this.DUMMY_ADS_MODE === true)
{
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnPrerollClosed, this);
return;
}
if (this.setup.preroll.skipFirst === true)
{
this.setup.preroll.skipFirst = false;
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnPrerollClosed, this);
return;
}
if(this.frequencyTimer === null || ((new Date()).getTime() - this.frequencyTimer.startTime >= this.setup.preroll.frequency * 1000))
{
this.adInvokes[AD_TYPE.PREROLL] = {};
var inst = this.fetchNextAdInstance(AD_TYPE.PREROLL);
if (inst === null)
{
this.debugLog("Cannot trigger ShowPrerollAd because the instance is empty, mediation plugin probably corrupted.");
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnPrerollClosed, this);
return;
}
this.adInvokes[AD_TYPE.PREROLL] = {
startingPointer: this.setup[AD_TYPE.PREROLL].pointer,
testedMediationTags: [this.setup[AD_TYPE.PREROLL].sequence[this.setup[AD_TYPE.PREROLL].pointer]]
};
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnPrerollStart, this);
inst.showPrerollAd();
}
else
{
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnPrerollClosed, this);
}
};
instanceProto.onShowPrerollAdResult = function (response_) // expect "closed" or "empty"
{
if (response_ === "closed") // the ad was successfully invoked and watched
{
this.debugLog("Preroll ad successfully watched - closing show ad request sequence.");
this.adInvokes[AD_TYPE.PREROLL] = {};
if(this.frequencyTimer)
clearTimeout(this.frequencyTimer.id);
this.frequencyTimer = {
startTime: (new Date()).getTime(),
id: setTimeout(function (){}, 99999999)
};
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnPrerollClosed, this);
return;
}
this.debugLog("Preroll ad empty - looking for a filler ad.");
this.incrementPointerSequentially(AD_TYPE.PREROLL);
var inst = this.fetchFillerAdInstance(AD_TYPE.PREROLL);
if (inst === null)
{
this.debugLog("Cannot find valid filler preroll ad - closing show ad request sequence.");
this.adInvokes[AD_TYPE.PREROLL] = {};
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnPrerollClosed, this);
return;
}
this.debugLog("Preroll filler ad found - invoking.");
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnPrerollStart, this);
inst.showPrerollAd();
};
Acts.prototype.ShowRewardedAd = function ()
{
this.adInvokes[AD_TYPE.REWARDED] = {};
var inst = this.fetchNextAdInstance(AD_TYPE.REWARDED);
if (inst === null)
{
this.debugLog("Cannot trigger ShowRewardedAd because the instance is empty, mediation plugin probably corrupted.");
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnRewardedEmpty, this);
return;
}
this.adInvokes[AD_TYPE.REWARDED] = {
startingPointer: this.setup[AD_TYPE.REWARDED].pointer,
testedMediationTags: [this.setup[AD_TYPE.REWARDED].sequence[this.setup[AD_TYPE.REWARDED].pointer]]
};
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnRewardedStart, this);
inst.showRewardedAd();
};
Acts.prototype.ShowConsentToolSettings = function ()
{
window["aipAPItag"]["showCMPScreen"]();
};
instanceProto.onShowRewardedAdResult = function (response_) // expect "successful" or "canceled" or "empty"
{
if (response_ === "successful") // the ad was successfully invoked and watched
{
this.debugLog("Rewarded ad successfully watched - closing show ad request sequence.");
this.adInvokes[AD_TYPE.REWARDED] = {};
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnRewardedSuccessful, this);
return;
}
else
if (response_ === "canceled") // the ad was canceled by the user
{
this.debugLog("Rewarded ad canceled by the user - closing show ad request sequence.");
this.adInvokes[AD_TYPE.REWARDED] = {};
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnRewardedCanceled, this);
return;
}
this.debugLog("Rewarded ad empty - looking for a filler ad.");
this.incrementPointerSequentially(AD_TYPE.REWARDED);
var inst = this.fetchFillerAdInstance(AD_TYPE.REWARDED);
if (inst === null)
{
this.debugLog("Cannot find valid filler rewarded ad - closing show ad request sequence.");
this.adInvokes[AD_TYPE.REWARDED] = {};
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnRewardedEmpty, this);
return;
}
this.debugLog("Preroll filler ad found - invoking.");
this.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnRewardedStart, this);
inst.showRewardedAd();
};
pluginProto.acts = new Acts();
function Exps() {};
/*Exps.prototype.MyExpression = function (ret) // 'ret' must always be the first parameter - always return the expression's result through it!
{
ret.set_int(1337); // return our value
};*/
pluginProto.exps = new Exps();
instanceProto.showBanner = function (bannerAdType_)
{
this.adInvokes[bannerAdType_] = {};
var mediationTag = this.getCleanMediationTag(this.setup[bannerAdType_].sequence[this.setup[bannerAdType_].pointer]);
var bannerAdUnitId = this.setup[bannerAdType_].auid[mediationTag];
if (this.bannerActiveByAdType[bannerAdType_].mediationInstance !== null)
{
this.bannerActiveByAdType[bannerAdType_].mediationInstance.hideBannerAd(bannerAdUnitId);
}
var inst = this.fetchNextAdInstance(bannerAdType_);
if (inst === null)
{
this.debugLog("Cannot trigger showBanner because the instance is empty, mediation plugin probably corrupted.");
return;
}
bannerAdUnitId = this.setup[bannerAdType_].auid[this.setup[bannerAdType_].sequence[this.setup[bannerAdType_].pointer]];
this.bannerActiveByAdType[bannerAdType_] = {
mediationInstance: inst,
elem: inst.getBannerElem(bannerAdUnitId)
};
this.adInvokes[bannerAdType_] = {
startingPointer: this.setup[bannerAdType_].pointer,
testedMediationTags: [this.setup[bannerAdType_].sequence[this.setup[bannerAdType_].pointer]]
};
this.bannerLayoutInstanceByAdUnitId[bannerAdUnitId].updatePosition(); // this makes sure the HTML DIV is visible while requesting ad, so the visibility rank gets higher
this.bannerLayoutInstanceByAdUnitId[bannerAdUnitId].updatePosition();
inst.showBannerAd(bannerAdUnitId);
};
instanceProto.onShowBannerAdResult = function (bannerAdUnitId_, response_) // expect "ok" or "empty"
{
var adType = this.bannerAdTypeByAdUnitId[bannerAdUnitId_];
if (response_ === "ok") // the banner ad was successfully displayed
{
this.debugLog("Banner ad " + bannerAdUnitId_ + " successfully displayed - closing show ad request sequence.");
this.adInvokes[adType] = {};
return;
}
this.debugLog("Banner ad " + bannerAdUnitId_ + " is empty - looking for a filler ad.");
this.bannerActiveByAdType[adType].mediationInstance.hideBannerAd(bannerAdUnitId_);
this.incrementPointerSequentially(adType);
var inst = this.fetchFillerAdInstance(adType);
if (inst === null)
{
this.bannerActiveByAdType[adType].mediationInstance = null;
this.debugLog("Cannot find a valid filler banner ad " + bannerAdUnitId_ + " - closing show ad request sequence.");
this.adInvokes[adType] = {};
return;
}
var mediationTag = this.getCleanMediationTag(this.setup[adType].sequence[this.setup[adType].pointer]);
var bannerAdUnitId = this.setup[adType].auid[mediationTag];
this.debugLog("Banner filler ad " + bannerAdUnitId_ + " >> " + bannerAdUnitId + " found - invoking.");
this.bannerActiveByAdType[adType].mediationInstance = inst;
this.bannerActiveByAdType[adType].elem = inst.getBannerElem(bannerAdUnitId);
this.bannerLayoutInstanceByAdUnitId[bannerAdUnitId].updatePosition(); // this makes sure the HTML DIV is visible while requesting ad, so the visibility rank gets higher
this.bannerLayoutInstanceByAdUnitId[bannerAdUnitId].updatePosition();
inst.showBannerAd(bannerAdUnitId);
};
instanceProto.setBannerLayoutInstance = function(bannerAdType_, inst_)
{
var bannerAdUnitId, bannerAdUnitIds = this.setup[bannerAdType_].auid;
for (var mediationTag in bannerAdUnitIds)
{
if ( ! bannerAdUnitIds.hasOwnProperty(mediationTag)) continue;
bannerAdUnitId = bannerAdUnitIds[mediationTag];
this.bannerAdTypeByAdUnitId[bannerAdUnitId] = bannerAdType_;
this.bannerLayoutInstanceByAdUnitId[bannerAdUnitId] = inst_;
}
this.bannerActiveByAdType[bannerAdType_] = {
mediationInstance: null,
elem: null
};
};
instanceProto.destroyBanner = function(bannerAdType_)
{
if (typeof this.setup[bannerAdType_] === "undefined") return;
var elem, bannerAdUnitId, bannerAdUnitIds = this.setup[bannerAdType_].auid;
for (var mediationTag in bannerAdUnitIds)
{
if ( ! bannerAdUnitIds.hasOwnProperty(mediationTag)) continue;
bannerAdUnitId = bannerAdUnitIds[mediationTag];
this.bannerLayoutInstanceByAdUnitId[bannerAdUnitId] = null;
elem = document.getElementById(bannerAdUnitId);
elem && elem.parentNode.removeChild(elem);
}
};
instanceProto.fetchNextAdInstance = function (adType_)
{
if ( ! this.isAdTypeValid(adType_)) return null;
if ( ! this.movePointerByMode(adType_)) return null;
var mediationTag = this.setup[adType_].sequence[this.setup[adType_].pointer];
while (this.isAlternativeMediationTag(mediationTag)) // Note that if setup sequence has only Alternative tags like: a?,b?,c? then it will loop infinitely.
{
this.movePointerByMode(adType_);
mediationTag = this.setup[adType_].sequence[this.setup[adType_].pointer];
}
if ( ! this.isAdShowFunctionValid(adType_, mediationTag)) return null;
return window["NSG_WebAdsPro_MedList"][mediationTag];
};
instanceProto.fetchCurrentAdInstance = function (adType_)
{
if ( ! this.isAdTypeValid(adType_)) return null;
var mediationTag = this.setup[adType_].sequence[this.setup[adType_].pointer];
if ( ! this.isAdShowFunctionValid(adType_, mediationTag)) return null;
return window["NSG_WebAdsPro_MedList"][mediationTag];
};
instanceProto.fetchFillerAdInstance = function (adType_)
{
while(this.adInvokes[adType_].startingPointer !== this.setup[adType_].pointer)
{
var mediationTag = this.setup[adType_].sequence[this.setup[adType_].pointer];
if (this.isAlternativeMediationTag(mediationTag))
{
mediationTag = this.getCleanMediationTag(mediationTag);
}
if (this.adInvokes[adType_].testedMediationTags.indexOf(mediationTag) !== -1)
{
this.incrementPointerSequentially(adType_);
continue;
}
this.adInvokes[adType_].testedMediationTags.push(mediationTag);
if ( ! this.isAdShowFunctionValid(adType_, mediationTag))
{
this.incrementPointerSequentially(adType_);
continue;
}
return window["NSG_WebAdsPro_MedList"][mediationTag]
}
return null;
};
instanceProto.isAdTypeValid = function(adType_)
{
if (typeof this.setup[adType_] === "undefined")
{
this.debugLog("AD type " + adType_ + " is not defined");
return null;
}
if (typeof this.setup[adType_].mode === "undefined")
{
this.debugLog("'mode' is not defined for AD type " + adType_);
return null;
}
if (typeof this.setup[adType_].sequence === "undefined")
{
this.debugLog("'sequence' is not defined for AD type " + adType_);
return null;
}
if (typeof this.setup[adType_].pointer === "undefined")
{
this.debugLog("'pointer' is not defined for AD type " + adType_);
return null;
}
return true;
};
instanceProto.movePointerByMode = function (adType_)
{
switch (this.setup[adType_].mode)
{
case AD_MODE.AB: // ab testing is sequential mode with random initial pointer
this.setup[adType_].pointer = Math.floor(Math.random() * this.setup[adType_].sequence.length);
this.setup[adType_].mode = AD_MODE.SEQUENCE;
break;
case AD_MODE.SEQUENCE_INIT:
this.setup[adType_].mode = AD_MODE.SEQUENCE;
break;
case AD_MODE.RANDOM:
this.setup[adType_].pointer = Math.floor(Math.random() * this.setup[adType_].sequence.length);
break;
case AD_MODE.SEQUENCE:
this.incrementPointerSequentially(adType_);
break;
default:
this.debugLog("'mode' (", this.setup[adType_].mode, ") is not valid for AD type", adType_);
return null;
}
return true;
};
instanceProto.isAlternativeMediationTag = function (mediationTag_)
{
return mediationTag_.includes("?");
};
instanceProto.getCleanMediationTag = function (mediationTag_)
{
return mediationTag_.replace("?", "");
};
instanceProto.incrementPointerSequentially = function (adType_)
{
this.setup[adType_].pointer++;
if (this.setup[adType_].pointer >= this.setup[adType_].sequence.length)
{
this.setup[adType_].pointer = 0;
}
};
instanceProto.isAdShowFunctionValid = function(adType_, mediationTag_)
{
if (typeof window["NSG_WebAdsPro_MedList"][mediationTag_] === "undefined")
{
this.debugLog("Mediation plugin with tag " + mediationTag_ + " is not found");
return false;
}
switch (adType_)
{
case AD_TYPE.PREROLL:
if (typeof window["NSG_WebAdsPro_MedList"][mediationTag_].showPrerollAd === "function") return true;
this.debugLog("There is no 'showPrerollAd' function in the " + mediationTag_ + " plugin");
return null;
case AD_TYPE.REWARDED:
if (typeof window["NSG_WebAdsPro_MedList"][mediationTag_].showRewardedAd === "function") return true;
this.debugLog("There is no 'showPrerollAd' function in the " + mediationTag_ + " plugin");
return null;
default:
if (typeof window["NSG_WebAdsPro_MedList"][mediationTag_].showBannerAd === "function") return true;
this.debugLog("There is no 'showBannerAd' function in the " + mediationTag_ + " plugin");
return null;
}
};
instanceProto.debugLog = function (msg_)
{
if ( ! this.DEBUG_MODE) return;
console.log("%c WebAds Pro:", "font-weight: bolder; color: #00F");
console.log(msg_);
console.log("");
};
var Secret={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(r){var t,e,o,a,h,n,d,C="",i=0;for(r=Secret._utf8_encode(r);i<r.length;)a=(t=r.charCodeAt(i++))>>2,h=(3&t)<<4|(e=r.charCodeAt(i++))>>4,n=(15&e)<<2|(o=r.charCodeAt(i++))>>6,d=63&o,isNaN(e)?n=d=64:isNaN(o)&&(d=64),C=C+this._keyStr.charAt(a)+this._keyStr.charAt(h)+this._keyStr.charAt(n)+this._keyStr.charAt(d);return C},decode:function(r){var t,e,o,a,h,n,d="",C=0;for(r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");C<r.length;)t=this._keyStr.indexOf(r.charAt(C++))<<2|(a=this._keyStr.indexOf(r.charAt(C++)))>>4,e=(15&a)<<4|(h=this._keyStr.indexOf(r.charAt(C++)))>>2,o=(3&h)<<6|(n=this._keyStr.indexOf(r.charAt(C++))),d+=String.fromCharCode(t),64!=h&&(d+=String.fromCharCode(e)),64!=n&&(d+=String.fromCharCode(o));return d=Secret._utf8_decode(d)},_utf8_encode:function(r){r=r.replace(/\r\n/g,"\n");for(var t="",e=0;e<r.length;e++){var o=r.charCodeAt(e);o<128?t+=String.fromCharCode(o):o>127&&o<2048?(t+=String.fromCharCode(o>>6|192),t+=String.fromCharCode(63&o|128)):(t+=String.fromCharCode(o>>12|224),t+=String.fromCharCode(o>>6&63|128),t+=String.fromCharCode(63&o|128))}return t},_utf8_decode:function(r){for(var t="",e=0,o=0,a=0,h=0;e<r.length;)(o=r.charCodeAt(e))<128?(t+=String.fromCharCode(o),e++):o>191&&o<224?(a=r.charCodeAt(e+1),t+=String.fromCharCode((31&o)<<6|63&a),e+=2):(a=r.charCodeAt(e+1),h=r.charCodeAt(e+2),t+=String.fromCharCode((15&o)<<12|(63&a)<<6|63&h),e+=3);return t}};
}());
window["NSG_WebAdsPro_MedList"] = window["NSG_WebAdsPro_MedList"] || {};
window['aiptag'] = window['aiptag'] || {};
window['aiptag']['cmd'] = window['aiptag']['cmd'] || [];
window['aiptag']['cmd']['display'] = window['aiptag']['cmd']['display'] || [];
window['aiptag']['cmd']['player'] = window['aiptag']['cmd']['player'] || [];
window['aiptag']['gdprShowConsentTool'] = true;
window['aiptag']['gdprShowConsentToolButton'] = false;
window['aip_gdpr_helper_interval'] = null;
try {
var NSG_refSite = document.referrer.replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0];
if ( ! NSG_refSite || NSG_refSite === "") NSG_refSite = window.location.hostname;
window['aiptag']['subid'] = "" + NSG_refSite;
console.log("SID: " + window['aiptag']['subid']);
}
catch (e) {
console.log(e);
}
;
;
cr.plugins_.NSG_WebAdsProAIP = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.NSG_WebAdsProAIP.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
window["NSG_WebAdsPro_MedList"]["a"] = this;
this.apiURL = this.properties[0];
this.core = null;
this.isThisMediatorInitializationStarted = false;
this.isAPIInitialized = false;
this.isAdPlayerReady = false;
this.isGDPRPreloaded = false;
this.everInvokedBannerAdUnitIds = [];
this.coreHandshake();
};
instanceProto.coreHandshake = function() // this function might be called from the core plugin also
{
if (this.core !== null) return;
if (typeof window["NSG_WebAdsPro_Core"] !== "undefined")
{
this.core = window["NSG_WebAdsPro_Core"];
this.debugLog("Handshake with core DONE");
this.onHandshakeDone();
}
};
instanceProto.onHandshakeDone = function()
{
/*this.videoAdContainterInit();
this.setAIPCallbacks();
this.initializeAPI();*/
};
instanceProto.initializeMediator = function()
{
if (this.isThisMediatorInitializationStarted === true) return;
this.isThisMediatorInitializationStarted = true;
this.debugLog(">>>> Initializing mediator");
this.videoAdContainterInit();
this.setAIPCallbacks();
this.initializeAPI();
};
instanceProto.videoAdContainterInit = function()
{
this.lightbox = document.createElement('div');
this.lightbox.id = "a_nsg-webadspro-lightbox";
this.lightbox.style.position = "fixed";
this.lightbox.style.display = "none";
this.lightbox.style.width = "100%";
this.lightbox.style.height = "100%";
this.lightbox.style.top = "0";
this.lightbox.style.left = "0";
this.lightbox.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
document.getElementsByTagName('body')[0].appendChild(this.lightbox);
this.videoAdContainer = document.createElement('div');
this.videoAdContainer.id = 'a_nsg-webadspro-vadc';
this.videoAdContainer.style.width = this.core.setup.preroll.adWidth + "px";
this.videoAdContainer.style.height = this.core.setup.preroll.adHeight + "px";
document.getElementsByTagName('body')[0].appendChild(this.videoAdContainer);
};
instanceProto.videoAdContainerHide = function()
{
this.lightbox.style.display = "none";
};
instanceProto.videoAdContainerShow = function()
{
this.lightbox.style.display = "block";
};
instanceProto.setAIPCallbacks = function()
{
var self = this;
window['aiptag']['cmp'] = window['aiptag']['cmp'] || {};
window['aiptag']['cmp']['show'] = true;
window['aiptag']['cmp']['position'] = this.core.gdprPosition === 0 ? "centered" : "fullscreen";
window['aiptag']['cmp']['button'] = true;
window['aiptag']['cmp']['buttonText'] = "Privacy settings";
window['aiptag']['cmp']['buttonPosition'] = "bottom-left";
document.addEventListener("aip_slotRenderEnded", function(e)
{
if (self.everInvokedBannerAdUnitIds.indexOf(e["detail"]["slotElementId"]) === -1)
{
self.debugLog("aip_slotRenderEnded event triggered but it's not about banner so ignoring (" + e["detail"]["slotElementId"] + ")");
return;
}
if (e.detail.isEmpty)
{
self.core.onShowBannerAdResult(e["detail"]["slotElementId"], "empty");
return;
}
self.core.onShowBannerAdResult(e["detail"]["slotElementId"], "ok");
});
document.addEventListener("aip_consentnotrequired", function(e)
{
self.debugLog("CMP aip_consentnotrequired");
clearInterval(window['aip_gdpr_helper_interval']);
self.isGDPRPreloaded = true;
self.core && self.core.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnGDPRPopupClosed, self.core);
});
document.addEventListener("aip_consentinit", function(e)
{
self.debugLog("CMP aip_consentinit");
});
document.addEventListener("aip_consentscreen", function(e)
{
self.debugLog("CMP aip_consentscreen");
clearInterval(window['aip_gdpr_helper_interval']);
self.core && self.core.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnGDPRPopupOpened, self.core);
});
document.addEventListener("aip_consentscreenoff", function(e)
{
self.debugLog("CMP aip_consentscreenoff");
clearInterval(window['aip_gdpr_helper_interval']);
self.isGDPRPreloaded = true;
self.core && self.core.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnGDPRPopupClosed, self.core);
});
document.addEventListener("aip_consent", function(e)
{
self.debugLog("CMP aip_consent");
});
document.addEventListener("aip_consentapproved", function(e)
{
self.debugLog("CMP aip_consentapproved");
clearInterval(window['aip_gdpr_helper_interval']);
self.isGDPRPreloaded = true;
self.core && self.core.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnGDPRPopupClosed, self.core);
});
document.addEventListener("aip_consentrejected", function(e)
{
self.debugLog("CMP aip_consentrejected");
self.isGDPRPreloaded = true;
self.core && self.core.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnGDPRPopupClosed, self.core);
});
document.addEventListener("aip_consentcustom", function(e)
{
self.debugLog("CMP aip_consentcustom");
});
document.addEventListener("aip_consentliestablished", function(e)
{
self.debugLog("CMP aip_consentliestablished");
});
};
instanceProto.initializeAPI = function()
{
var self = this;
var headElm = document.head || document.getElementsByTagName('head')[0];
var script = document.createElement("script");
var once = true;
script.async = "async";
script.type = "text/javascript";
script.charset = "UTF-8";
script.src = this.apiURL;
script.onload = script.onreadystatechange = function ()
{
if (once && (!script.readyState || /loaded|complete/.test(script.readyState)))
{
once = false;
self.isAPIInitialized = true;
script.onload = script.onreadystatechange = null;
}
};
headElm.appendChild(script);
window['aip_gdpr_helper_counter'] = 0;
window['aip_gdpr_helper_interval'] = setInterval(function ()
{
if (++window['aip_gdpr_helper_counter'] >= 50)
{
console.log('aip_gdpr_helper_counter completed');
self.isGDPRPreloaded = true;
self.core && self.core.runtime.trigger(cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnGDPRPopupClosed, self.core);
clearInterval(window['aip_gdpr_helper_interval']);
}
}, 100);
};
function Cnds() {};
pluginProto.cnds = new Cnds();
function Acts() {};
pluginProto.acts = new Acts();
function Exps() {};
pluginProto.exps = new Exps();
instanceProto.initialize = function()
{
var self = this;
if (self.isAPIInitialized === false)
{
this.debugLog("Cannot initialize mediation plugin because API was not initialized. Reattempt in 1s");
setTimeout(function ()
{
self.initialize();
}, 1000);
return;
}
if(typeof window['aipPlayer'] === "undefined")
{
this.debugLog("Cannot initialize mediation plugin because \"window['aipPlayer']\" is undefined.");
return;
}
var aipObj = {};
aipObj['AIP_REWARDEDNOTGRANTED'] = function (state_)
{
self.debugLog("Rewarded: " + state_);
if (state_ === "timeout")
{
self.core.onShowRewardedAdResult("empty");
}
else
if (state_ === "unsupported")
{
self.core.onShowRewardedAdResult("empty");
}
else
if (state_ === "closed")
{
self.core.onShowRewardedAdResult("canceled");
}
else
if (state_ === "empty")
{
self.core.onShowRewardedAdResult("empty");
}
self.videoAdContainerHide();
};
aipObj['AIP_REWARDEDGRANTED'] = function () {
self.debugLog("Rewarded: successful");
self.core.onShowRewardedAdResult("successful");
self.videoAdContainerHide();
};
aipObj['AD_WIDTH'] = this.core.setup.preroll.adWidth;
aipObj['AD_HEIGHT'] = this.core.setup.preroll.adHeight;
aipObj['AD_FULLSCREEN'] = this.core.setup.preroll.isFullscreen;
aipObj['AD_CENTERPLAYER'] = !this.core.setup.preroll.isFullscreen;
aipObj['LOADING_TEXT'] = "loading ad";
aipObj['PREROLL_ELEM'] = this.videoAdContainer;
aipObj['AIP_COMPLETE'] = function (evt_)
{
/*******************
***** WARNING *****
*******************
Please do not remove the PREROLL_ELEM
from the page, it will be hidden automatically.
If you do want to remove it use the AIP_REMOVE callback below
*/
var result = "closed";
if (evt_ === "video-ad-empty")
{
result = "empty";
}
self.videoAdContainerHide();
self.core.onShowPrerollAdResult(result);
};
aipObj['AIP_REMOVE'] = function () {
};
window['aiptag']['cmd']['player'].push(function() {
window['aiptag']['adplayer'] = new window["aipPlayer"](aipObj);
});
this.isAdPlayerReady = true;
this.debugLog("initialized");
};
instanceProto.showBannerAd = function(bannerAdUnitId_)
{
this.debugLog("attempting to show banner ad " + bannerAdUnitId_);
/*if ( ! document.getElementById(bannerAdUnitId_))
{
this.debugLog("Banner " + bannerAdUnitId_ + " does not exist yet - initializing");
this.initializeBannerAd(bannerAdUnitId_);
if ( ! this.core.DUMMY_ADS_MODE)
{
if (this.everInvokedBannerAdUnitIds.indexOf(bannerAdUnitId_) === -1)
{
this.everInvokedBannerAdUnitIds.push(bannerAdUnitId_);
}
window['aiptag']['cmd']['display'].push(function() { window['aipDisplayTag']['display'](bannerAdUnitId_); });
}
else
{
this.core.onShowBannerAdResult(bannerAdUnitId_, "ok");
}
return;
}*/
var elem = document.getElementById(bannerAdUnitId_);
elem.style.display = 'flex';
if ( ! this.core.DUMMY_ADS_MODE)
{
if (this.everInvokedBannerAdUnitIds.indexOf(bannerAdUnitId_) === -1)
{
this.everInvokedBannerAdUnitIds.push(bannerAdUnitId_);
}
window['aiptag']['cmd']['display'].push(function() { window['aipDisplayTag']['refresh'](bannerAdUnitId_); });
}
else
{
this.core.onShowBannerAdResult(bannerAdUnitId_, "ok");
}
};
instanceProto.getBannerElem = function (bannerAdUnitId_)
{
if ( ! document.getElementById(bannerAdUnitId_))
{
this.debugLog("Banner " + bannerAdUnitId_ + " does not exist yet - initializing");
this.initializeBannerAd(bannerAdUnitId_);
if ( ! this.core.DUMMY_ADS_MODE)
{
if (this.everInvokedBannerAdUnitIds.indexOf(bannerAdUnitId_) === -1)
{
this.everInvokedBannerAdUnitIds.push(bannerAdUnitId_);
}
}
}
return document.getElementById(bannerAdUnitId_);
};
instanceProto.hideBannerAd = function(bannerAdUnitId_)
{
this.debugLog("attempting to hide banner ad " + bannerAdUnitId_);
var elem = document.getElementById(bannerAdUnitId_);
if ( ! elem) return;
elem.style.display = 'none';
};
instanceProto.initializeBannerAd = function(bannerAdUnitId_)
{
var elem = document.createElement("div");
elem.id = bannerAdUnitId_;
var parent = this.runtime.canvasdiv ? this.runtime.canvasdiv : document.body;
parent.appendChild(elem);
elem.style.width = this.core.bannerLayoutInstanceByAdUnitId[bannerAdUnitId_].width + "px";
elem.style.height = this.core.bannerLayoutInstanceByAdUnitId[bannerAdUnitId_].height + "px";
elem.style.display = "flex";
elem.style.justifyContent = "center";
elem.style.alignItems = "center";
if (this.core.DUMMY_ADS_MODE || ! elem.id || ! bannerAdUnitId_)
{
elem.style.backgroundColor = "#000";
elem.style.border = "1px solid #fff";
}
};
instanceProto.isPlayerReady = function()
{
return typeof window['aiptag']['adplayer'] !== "undefined";
};
instanceProto.showPrerollAd = function()
{
this.debugLog("attempting to show preroll ad");
if ( ! this.isPlayerReady())
{
this.debugLog("plugin is not ready to display the preroll ad - faking empty ad");
this.core.onShowPrerollAdResult("empty");
return;
}
this.videoAdContainerShow();
window['aiptag']['cmd']['player'].push(function() { window['aiptag']['adplayer']['startPreRoll'](); });
};
instanceProto.showRewardedAd = function()
{
this.debugLog("attempting to show rewarded ad");
if ( ! this.isPlayerReady())
{
this.debugLog("plugin is not ready to display the rewarded ad - faking empty ad");
this.core.onShowRewardedAdResult("empty");
return;
}
this.videoAdContainerShow();
window['aiptag']['cmd']['player'].push(function() { window['aiptag']['adplayer']['startRewardedAd'](); });
};
instanceProto.onSetupUpdate = function ()
{
if (this.isAdPlayerReady === false)
{
this.debugLog("API is not yet initialized so no need to force a setting update.");
return;
}
this.debugLog("API was already initialized so forcing a setting update.");
if (this.core.setup.preroll.isFullscreen === true)
{
window['adplayer']['aipConfig']['AD_FULLSCREEN'] = true;
window['adplayer']['aipConfig']['AD_CENTERPLAYER'] = false;
}
else
{
window['adplayer']['aipConfig']['AD_FULLSCREEN'] = false;
window['adplayer']['aipConfig']['AD_CENTERPLAYER'] = true;
}
};
instanceProto.debugLog = function (msg_)
{
if ( ! this.core.DEBUG_MODE) return;
console.log("%c WebAdsPro[%cAIP%c]:", "font-weight: bolder; color: #00F", "font-weight: bolder; color: #0A0", "font-weight: bolder; color: #00F");
console.log(msg_);
console.log("");
};
}());
window["NSG_WebAdsPro_MedList"] = window["NSG_WebAdsPro_MedList"] || {};
;
;
cr.plugins_.NSG_WebAdsProCPMStar = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.NSG_WebAdsProCPMStar.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
window["NSG_WebAdsPro_MedList"]["c"] = this;
this.isThisMediatorInitializationStarted = false;
this.core = null;
this.zonefile = this.properties[0];
this.rAd = null;
this.coreHandshake();
};
instanceProto.coreHandshake = function() // this function might be called from the core plugin also
{
if (this.core !== null) return;
if (typeof window["NSG_WebAdsPro_Core"] !== "undefined")
{
this.core = window["NSG_WebAdsPro_Core"];
this.debugLog("Handshake with core DONE");
this.onHandshakeDone();
}
};
instanceProto.onHandshakeDone = function()
{
/*this.videoAdContainterInit();
this.initializeCPMAPI();
this.setupAds();*/
};
instanceProto.initializeMediator = function()
{
if (this.isThisMediatorInitializationStarted === true) return;
this.isThisMediatorInitializationStarted = true;
this.debugLog(">>>> Initializing mediator");
this.videoAdContainterInit();
this.initializeCPMAPI();
this.setupAds();
};
instanceProto.videoAdContainterInit = function()
{
this.lightbox = document.createElement('div');
this.lightbox.id = "c_nsg-webadspro-lightbox";
this.lightbox.style.position = "fixed";
this.lightbox.style.display = "none";
this.lightbox.style.width = "100%";
this.lightbox.style.height = "100%";
this.lightbox.style.top = "0";
this.lightbox.style.left = "0";
this.lightbox.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
document.getElementsByTagName('body')[0].appendChild(this.lightbox);
this.videoAdContainer = document.createElement('div');
this.videoAdContainer.id = 'c_nsg-webadspro-vadc';
this.videoAdContainer.style.width = this.core.setup.preroll.adWidth + "px";
this.videoAdContainer.style.height = this.core.setup.preroll.adHeight + "px";
this.videoAdContainer.style.position = "fixed";
this.videoAdContainer.style.display = "none";
this.videoAdContainer.style.top = "50%";
this.videoAdContainer.style.left = "50%";
this.videoAdContainer.style.transform = "translate(-50%, -50%)";
this.videoAdContainer.style.zIndex = "999999";
document.getElementsByTagName('body')[0].appendChild(this.videoAdContainer);
};
instanceProto.videoAdContainerHide = function()
{
this.lightbox.style.display = "none";
this.videoAdContainer.style.display = "none";
};
instanceProto.videoAdContainerShow = function()
{
this.lightbox.style.display = "block";
this.videoAdContainer.style.display = "block";
};
instanceProto.setupAds = function()
{
var self = this;
if (typeof window['cpmstarAPI'] === 'undefined')
{
setTimeout(function ()
{
self.setupAds();
}, 100);
return;
}
window["cpmstarAPI"](function (api)
{
api["game"]["setTarget"](self.videoAdContainer);
self.rAd = new api["game"]["RewardedVideoView"]("rewardedvideo");
self.rAd.addEventListener("loaded", function (e)
{
self.debugLog("Rewarded ad loaded");
});
self.rAd.addEventListener("load_failed", function (e)
{
self.debugLog("Rewarded ad failed to load - reattempt in 10s");
setTimeout(function ()
{
if ( ! self.rAd["isLoaded"]())
{
self.debugLog("Rewarded ad - start preloading");
self.rAd["load"]();
}
else
{
self.debugLog("Rewarded was about to start preloading, but it's already loaded - ignoring");
}
}, 10000);
});
self.rAd.addEventListener("ad_closed", function (e)
{
self.videoAdContainerHide();
self.core.onShowRewardedAdResult("successful");
setTimeout(function ()
{
if ( ! self.rAd["isLoaded"]())
{
self.debugLog("Rewarded ad - start preloading2");
self.rAd["load"]();
}
else
{
self.debugLog("Rewarded was about to start preloading, but it's already loaded - ignoring2");
}
}, 1000);
});
self.debugLog("Rewarded ad - start preloading3");
self.rAd["load"]();
});
window["cpmstarAPI"]({
kind: "game.createInterstitial",
onAdOpened: function(){
console.log(">>>> CPM Preroll started");
},
onAdClosed: function(){
self.videoAdContainerHide();
self.core.onShowPrerollAdResult("closed");
}/*,
fail: function() {
console.log(arguments);
self.core.onShowPrerollAdResult("empty");
}*/
});
};
instanceProto.initializeCPMAPI = function ()
{
if (typeof window['cpmstarAPI'] === 'undefined')
{
/*(function (zonefile) {
var rnd = Math.round(Math.random() * 999999);
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
var host = "go.bloxplay.com";
if (window.location.hash == "#urlzing") {
host = "//staging.urlzing.com";
}
s.src = "//" + host + "/" + zonefile + "?rnd=" + rnd;
var s2 = document.getElementsByTagName('script')[0];
s2.parentNode.insertBefore(s, s2);
var y = window.location.href.split('#')[0].split('').reduce(function (a, b) {
return (a << 5) - a + b.charCodeAt(0) >>> 1
}, 0);
y = (10 + ((y * 7) % 26)).toString(36) + y.toString(36);
var drutObj = window[y] = window[y] || {};
window['cpmstarAPI'] = window["_" + zonefile] = function (o) {
(drutObj.cmd = drutObj.cmd || []).push(o);
}
}(this.zonefile));*/
(function(zonefile) {
var y=window.location.href.split('#')[0].split('').reduce(function(a,b){return(a<<5)-a+b.charCodeAt(0)>>>1},0);y=(10+((y*7)%26)).toString(36)+y.toString(36);
var drutObj = window[y] = window[y] || {};
function failCpmstarAPI() { var failFn = function(o) { o && typeof(o) === "object" && o.fail && o.fail(); }; drutObj && Array.isArray(drutObj.cmd) && drutObj.cmd.forEach(failFn) && (drutObj.cmd.length = 0); window.cpmstarAPI = window["_"+zonefile] = failFn; }
var rnd = Math.round(Math.random()*999999);
var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.onerror=failCpmstarAPI;
var proto = document.location.protocol;
var host = ( proto == "https:" || proto == "file:")?"https://server":"//cdn";
if(window.location.hash=="#cpmstarDev") host = "//dev.server";
if(window.location.hash=="#cpmstarStaging") host = "//staging.server";
s.src = host + ".cpmstar.com/cached/zonefiles/" + zonefile + ".js?rnd="+rnd;
var s2=document.getElementsByTagName('script')[0];
s2.parentNode.insertBefore(s, s2);
window['cpmstarAPI'] = function(o) { (drutObj.cmd = drutObj.cmd || []).push(o); }
}(this.zonefile));
}
};
function Cnds() {};
pluginProto.cnds = new Cnds();
function Acts() {};
pluginProto.acts = new Acts();
function Exps() {};
pluginProto.exps = new Exps();
instanceProto.initialize = function()
{
this.debugLog("initialized");
};
instanceProto.showPrerollAd = function()
{
var self = this;
this.debugLog("attempting to show preroll ad");
this.videoAdContainerShow();
window['cpmstarAPI']({
kind: "game.displayInterstitial",
fail: function() {
self.videoAdContainerHide();
self.core.onShowPrerollAdResult("empty");
}
});
};
instanceProto.showRewardedAd = function()
{
this.debugLog("attempting to show rewarded ad");
if(this.rAd && this.rAd["isLoaded"]())
{
this.videoAdContainerShow();
this.rAd["show"]();
}
else
{
this.videoAdContainerHide();
this.core.onShowRewardedAdResult("empty");
}
};
instanceProto.showBannerAd = function(bannerAdUnitId_)
{
this.debugLog("attempting to show banner ad " + bannerAdUnitId_);
/*if ( ! document.getElementById(bannerAdUnitId_))
{
this.debugLog("Banner " + bannerAdUnitId_ + " does not exist yet - initializing");
this.initializeBannerAd(bannerAdUnitId_);
if ( ! this.core.DUMMY_ADS_MODE)
{
cpmstarAPI({kind:"go",module:bannerAdUnitId_, config: {target:{find:'#' +bannerAdUnitId_,kind:'replace'}}});
this.core.onShowBannerAdResult(bannerAdUnitId_, "ok");
}
else
{
this.core.onShowBannerAdResult(bannerAdUnitId_, "ok");
}
return;
}*/
var elem = document.getElementById(bannerAdUnitId_);
elem.style.display = 'flex';
if ( ! this.core.DUMMY_ADS_MODE)
{
cpmstarAPI({kind:'go',module:bannerAdUnitId_, config: { conditions: { target: { find:'#' +bannerAdUnitId_, kind: 'replace' } }}});
this.core.onShowBannerAdResult(bannerAdUnitId_, "ok");
}
else
{
this.core.onShowBannerAdResult(bannerAdUnitId_, "ok");
}
};
instanceProto.getBannerElem = function (bannerAdUnitId_)
{
if ( ! document.getElementById(bannerAdUnitId_))
{
this.debugLog("Banner " + bannerAdUnitId_ + " does not exist yet - initializing");
this.initializeBannerAd(bannerAdUnitId_);
}
return document.getElementById(bannerAdUnitId_);
};
instanceProto.hideBannerAd = function(bannerAdUnitId_)
{
this.debugLog("attempting to hide banner ad " + bannerAdUnitId_);
var elem = document.getElementById(bannerAdUnitId_);
if ( ! elem) return;
elem.style.display = 'none';
};
instanceProto.initializeBannerAd = function(bannerAdUnitId_)
{
var elem = document.createElement("div");
elem.id = bannerAdUnitId_;
var parent = this.runtime.canvasdiv ? this.runtime.canvasdiv : document.body;
parent.appendChild(elem);
elem.style.width = this.core.bannerLayoutInstanceByAdUnitId[bannerAdUnitId_].width + "px";
elem.style.height = this.core.bannerLayoutInstanceByAdUnitId[bannerAdUnitId_].height + "px";
elem.style.display = "flex";
elem.style.justifyContent = "center";
elem.style.alignItems = "center";
if (this.core.DUMMY_ADS_MODE || ! elem.id || ! bannerAdUnitId_)
{
elem.style.backgroundColor = "#000";
elem.style.border = "1px solid #fff";
}
};
instanceProto.onSetupUpdate = function ()
{
};
instanceProto.debugLog = function (msg_)
{
if ( ! this.core.DEBUG_MODE) return;
console.log("%c WebAdsPro[%cCPMStar%c]:", "font-weight: bolder; color: #00F", "font-weight: bolder; color: #0A0", "font-weight: bolder; color: #00F");
console.log(msg_);
console.log("");
};
}());
;
;
cr.plugins_.NSG_WebAdsProCrazyGames = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.NSG_WebAdsProCrazyGames.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
var AD_TYPE = {
MIDGAME: 1,
REWARDED: 2
};
instanceProto.onCreate = function()
{
window["NSG_WebAdsPro_MedList"]["cg"] = this;
this.crazysdk = null;
this.core = null;
this.isThisMediatorInitializationStarted = false;
this.isAPIInitialized = false;
this.currentlyPlayingAdType = null;
this.everInvokedBannerAdUnitIds = [];
this.coreHandshake();
};
instanceProto.coreHandshake = function() // this function might be called from the core plugin also
{
if (this.core !== null) return;
if (typeof window["NSG_WebAdsPro_Core"] !== "undefined")
{
this.core = window["NSG_WebAdsPro_Core"];
this.debugLog("Handshake with core DONE");
this.onHandshakeDone();
}
};
instanceProto.onHandshakeDone = function()
{
};
instanceProto.initializeMediator = function()
{
if (this.isThisMediatorInitializationStarted === true) return;
this.isThisMediatorInitializationStarted = true;
this.debugLog(">>>> Initializing mediator");
this.videoAdContainerInit();
this.initializeAPI();
};
instanceProto.videoAdContainerInit = function()
{
};
instanceProto.installSDKListeners = function()
{
var self = this;
this.crazysdk.addEventListener('adStarted', function ()
{
});
this.crazysdk.addEventListener('adError', function ()
{
if ( ! self.currentlyPlayingAdType) return;
switch(self.currentlyPlayingAdType)
{
case AD_TYPE.REWARDED:
self.core.onShowRewardedAdResult("empty");
break;
case AD_TYPE.MIDGAME:
self.core.onShowPrerollAdResult("empty");
break;
}
self.currentlyPlayingAdType = null;
});
this.crazysdk.addEventListener('adFinished', function ()
{
if ( ! self.currentlyPlayingAdType) return;
switch(self.currentlyPlayingAdType)
{
case AD_TYPE.REWARDED:
self.core.onShowRewardedAdResult("successful");
break;
case AD_TYPE.MIDGAME:
self.core.onShowPrerollAdResult("closed");
break;
}
self.currentlyPlayingAdType = null;
});
this.crazysdk.addEventListener('bannerRendered', function (event)
{
self.debugLog('Banner ' + event.containerId + ' has been rendered!');
self.core.onShowBannerAdResult(event.containerId, "ok");
});
this.crazysdk.addEventListener('bannerError', function (event)
{
self.debugLog('Banner ' + event.containerId + ' render error: ' + event.error);
self.core.onShowBannerAdResult(event.containerId, "empty");
});
};
instanceProto.videoAdContainerHide = function()
{
};
instanceProto.videoAdContainerShow = function()
{
};
instanceProto.initializeAPI = function()
{
var self = this;
var headElm = document.head || document.getElementsByTagName('head')[0];
var script = document.createElement("script");
var once = true;
script.async = "async";
script.type = "text/javascript";
script.charset = "UTF-8";
script.src = "https://sdk.crazygames.com/crazygames-sdk-v1.js";
script.onload = script.onreadystatechange = function ()
{
if (once && (!script.readyState || /loaded|complete/.test(script.readyState)))
{
once = false;
self.isAPIInitialized = true;
script.onload = script.onreadystatechange = null;
self.crazysdk = window["CrazyGames"]["CrazySDK"]["getInstance"]();
self.crazysdk["init"]();
self.installSDKListeners();
}
};
headElm.appendChild(script);
};
function Cnds() {};
pluginProto.cnds = new Cnds();
function Acts() {};
pluginProto.acts = new Acts();
function Exps() {};
pluginProto.exps = new Exps();
instanceProto.initialize = function()
{
var self = this;
if (self.isAPIInitialized === false)
{
this.debugLog("Cannot initialize mediation plugin because API was not initialized. Reattempt in 1s");
setTimeout(function ()
{
self.initialize();
}, 1000);
return;
}
this.debugLog("initialized");
};
instanceProto.showBannerAd = function(bannerAdUnitId_)
{
var adType = this.core.bannerAdTypeByAdUnitId[bannerAdUnitId_];
if (typeof this.core.setup[adType].custom !== "undefined")
{
if (typeof this.core.setup[adType].custom.ignore !== "undefined") return;
this.showDoubleBanner(this.core.setup[adType].custom);
return;
}
this.debugLog("attempting to show banner ad " + bannerAdUnitId_);
var elem = document.getElementById(bannerAdUnitId_);
elem.style.display = 'flex';
if ( ! this.core.DUMMY_ADS_MODE)
{
if (this.everInvokedBannerAdUnitIds.indexOf(bannerAdUnitId_) === -1)
{
this.everInvokedBannerAdUnitIds.push(bannerAdUnitId_);
}
this.crazysdk["requestBanner"]([
{
containerId: elem.id,
size: elem.id.substring(elem.id.indexOf('-') + 1) //'300x250',
}
]);
}
else
{
this.core.onShowBannerAdResult(bannerAdUnitId_, "ok");
}
};
instanceProto.showDoubleBanner = function(customData_)
{
this.debugLog("Starting custom trigger - double banner request...");
var i, len, adUnitId, cgBannersSetup = [];
len = customData_.p.length;
for (i = 0; i < len; ++i)
{
adUnitId = customData_.p[i];
this.debugLog("attempting to show banner ad " + adUnitId);
var elem = this.getBannerElem(adUnitId);
elem.style.display = 'flex';
if ( ! this.core.DUMMY_ADS_MODE)
{
if (this.everInvokedBannerAdUnitIds.indexOf(adUnitId) === -1)
{
this.everInvokedBannerAdUnitIds.push(adUnitId);
}
cgBannersSetup.push(
{
containerId: elem.id,
size: elem.id.substring(elem.id.indexOf('-') + 1) //'300x250',
}
);
}
else
{
this.core.onShowBannerAdResult(adUnitId, "ok");
}
}
this.debugLog("requesting setup:");
this.debugLog(cgBannersSetup);
this.crazysdk["requestBanner"](cgBannersSetup);
};
instanceProto.getBannerElem = function (bannerAdUnitId_)
{
if ( ! document.getElementById(bannerAdUnitId_))
{
this.debugLog("Banner " + bannerAdUnitId_ + " does not exist yet - initializing");
this.initializeBannerAd(bannerAdUnitId_);
}
return document.getElementById(bannerAdUnitId_);
};
instanceProto.hideBannerAd = function(bannerAdUnitId_)
{
this.debugLog("attempting to hide banner ad " + bannerAdUnitId_);
var elem = document.getElementById(bannerAdUnitId_);
if ( ! elem) return;
elem.style.display = 'none';
};
instanceProto.initializeBannerAd = function(bannerAdUnitId_)
{
var elem = document.createElement("div");
elem.id = bannerAdUnitId_;
var parent = this.runtime.canvasdiv ? this.runtime.canvasdiv : document.body;
parent.appendChild(elem);
elem.style.width = this.core.bannerLayoutInstanceByAdUnitId[bannerAdUnitId_].width + "px";
elem.style.height = this.core.bannerLayoutInstanceByAdUnitId[bannerAdUnitId_].height + "px";
elem.style.display = "flex";
elem.style.justifyContent = "center";
elem.style.alignItems = "center";
if (this.core.DUMMY_ADS_MODE || ! elem.id || ! bannerAdUnitId_)
{
elem.style.backgroundColor = "#000";
elem.style.border = "1px solid #fff";
}
};
instanceProto.isPlayerReady = function()
{
};
instanceProto.showPrerollAd = function()
{
this.debugLog("attempting to show preroll ad");
/*if ( ! this.isPlayerReady())
{
this.debugLog("plugin is not ready to display the preroll ad - faking empty ad");
this.core.onShowPrerollAdResult("empty");
return;
}
this.videoAdContainerShow();*/
this.currentlyPlayingAdType = AD_TYPE.MIDGAME;
this.crazysdk["requestAd"]('midgame');
};
instanceProto.showRewardedAd = function()
{
this.debugLog("attempting to show rewarded ad");
/*if ( ! this.isPlayerReady())
{
this.debugLog("plugin is not ready to display the rewarded ad - faking empty ad");
this.core.onShowRewardedAdResult("empty");
return;
}*/
this.currentlyPlayingAdType = AD_TYPE.REWARDED;
this.crazysdk["requestAd"]('rewarded');
};
instanceProto.onSetupUpdate = function ()
{
/*if (this.isAdPlayerReady === false)
{
this.debugLog("API is not yet initialized so no need to force a setting update.");
return;
}
this.debugLog("API was already initialized so forcing a setting update.");
if (this.core.setup.preroll.isFullscreen === true)
{
window['adplayer']['aipConfig']['AD_FULLSCREEN'] = true;
window['adplayer']['aipConfig']['AD_CENTERPLAYER'] = false;
}
else
{
window['adplayer']['aipConfig']['AD_FULLSCREEN'] = false;
window['adplayer']['aipConfig']['AD_CENTERPLAYER'] = true;
}*/
};
instanceProto.debugLog = function (msg_)
{
if ( ! this.core.DEBUG_MODE) return;
console.log("%c WebAdsPro[%cCG%c]:", "font-weight: bolder; color: #00F", "font-weight: bolder; color: #0A0", "font-weight: bolder; color: #00F");
console.log(msg_);
console.log("");
};
}());
;
;
cr.plugins_.NSG_WebAdsPro_Banner = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.NSG_WebAdsPro_Banner.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.core = null;
this.bannerId = this.properties[0];
this.upscaleLock = !!this.properties[1];
this.scaleOffset = this.properties[2];
this.lastImpressionTimestamp = null;
this.impressionsCounter = 0;
this.coreHandshake();
this.element_hidden = false;
this.lastLeft = 0;
this.lastTop = 0;
this.lastRight = 0;
this.lastBottom = 0;
this.lastWinWidth = 0;
this.lastWinHeight = 0;
};
instanceProto.draw = function(ctx){};
instanceProto.drawGL = function (glw){};
instanceProto.coreHandshake = function() // this function might be called from the core plugin also
{
if (this.core !== null) return;
if (typeof window["NSG_WebAdsPro_Core"] !== "undefined")
{
this.core = window["NSG_WebAdsPro_Core"];
this.debugLog("Handshake with core DONE");
this.onHandshakeDone();
}
else
{
console.log("[Web Ads Pro Banner] Cannot finalize handshake!!!!!!!!!!!");
}
};
instanceProto.onHandshakeDone = function()
{
/*this.core.setBannerLayoutInstance(this.bannerId, this);
var self = this;
this.bannerPositionAdjuster = setInterval(function ()
{
if (self.core.bannerActiveByAdType[self.bannerId].elem === null) return;
self.updatePosition();
}, 100);*/
};
instanceProto.onDestroy = function()
{
this.core.destroyBanner(this.bannerId);
};
instanceProto.getScale = function()
{
var widthScale = $(window).width() / this.runtime.original_width;
var heightScale = $(window).height() / this.runtime.original_height;
return Math.min(widthScale, heightScale);
};
instanceProto.updatePosition = function ()
{
var left = this.layer.layerToCanvas(this.x, this.y, true);
var top = this.layer.layerToCanvas(this.x, this.y, false);
var right = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, true);
var bottom = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, false);
var rightEdge = this.runtime.width / this.runtime.devicePixelRatio;
var bottomEdge = this.runtime.height / this.runtime.devicePixelRatio;
var curScale = this.getScale() + this.scaleOffset;
var elem = this.core.bannerActiveByAdType[this.bannerId].elem;
if (!this.visible || !this.layer.visible || right <= 0 || bottom <= 0 || left >= rightEdge || top >= bottomEdge)
{
if (!this.element_hidden)
{
elem.style.display = 'none';
}
elem.style.display = 'none';
this.element_hidden = true;
return;
}
elem.style.display = "flex";
this.element_hidden = false;
if (left < 1)
left = 1;
if (top < 1)
top = 1;
if (right >= rightEdge)
right = rightEdge - 1;
if (bottom >= bottomEdge)
bottom = bottomEdge - 1;
var curWinWidth = window.innerWidth;
var curWinHeight = window.innerHeight;
if (this.lastScale === curScale && this.lastLeft === left && this.lastTop === top && this.lastRight === right && this.lastBottom === bottom && this.lastWinWidth === curWinWidth && this.lastWinHeight === curWinHeight)
{
/*if (this.element_hidden)
{
this.popupDiv.style = '';
this.element_hidden = false;
}*/
--this.fixesLeft;
if (this.fixesLeft < 0) return;
}
else
{
this.fixesLeft = 10;
}
this.lastLeft = left;
this.lastTop = top;
this.lastRight = right;
this.lastBottom = bottom;
this.lastWinWidth = curWinWidth;
this.lastWinHeight = curWinHeight;
if (this.element_hidden)
{
elem.style.display = "flex";
this.element_hidden = false;
}
var rect = this.runtime.canvas.getBoundingClientRect();
var offx = Math.round(left) + rect.left + document.body.scrollLeft;
var offy = Math.round(top) + rect.top + document.body.scrollTop;
/*if (this.scaleOffset !== 0)
{
offx *= (this.scaleOffset * 0.5 + 1);
offy *= (this.scaleOffset * 0.5 + 1);
}*/
elem.style.position = "absolute";
if (this.upscaleLock && curScale > 1)
{
jQuery(elem).offset({
left: offx + ((curScale - 1) * this.width * 0.5),
top: offy + ((curScale - 1) * this.height * 0.5)
});
elem.style.transform = 'scale(1)';
}
else
{
jQuery(elem).offset({left: offx, top: offy});
elem.style.transform = 'scale(' + (curScale) + ')';
}
};
function Cnds() {};
/* // the example condition
Cnds.prototype.MyCondition = function (myparam)
{
return myparam >= 0;
};*/
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.ShowBanner = function ()
{
if (this.core === null)
{
this.debugLog("The core instance is not handshaked yet - ignoring Show Banner request")
}
if (this.lastImpressionTimestamp === null)
{
this.core.setBannerLayoutInstance(this.bannerId, this);
var self = this;
if (this.bannerPositionAdjuster) clearTimeout(this.bannerPositionAdjuster);
this.bannerPositionAdjuster = setInterval(function ()
{
if (self.core.bannerActiveByAdType[self.bannerId].elem === null) return;
self.updatePosition();
}, 100);
/*window.addEventListener('resize', function()
{
if (self.core.bannerActiveByAdType[self.bannerId].elem === null) return;
self.updatePositionTickTarget = self.runtime.tickcount + 3;
self.updatePosition();
self.bannerPositionAdjuster = setInterval(function ()
{
self.updatePosition();
if (self.updatePositionTickTarget < self.runtime.tickcount)
{
clearInterval(self.bannerPositionAdjuster);
self.bannerPositionAdjuster = null;
}
}, 17);
}, true);*/
this.lastImpressionTimestamp = new Date();
this.impressionsCounter = 0;
this.core.showBanner(this.bannerId);
return;
}
++this.impressionsCounter;
var now = new Date();
var timePassed = now - this.lastImpressionTimestamp;
timePassed /= 1000;
if (timePassed < this.core.setup[this.bannerId].safePeriod)
{
this.debugLog("Cannot refresh banner " + this.bannerId + " because it's in SAFE PERIOD. " + timePassed + " >= " + this.core.setup[this.bannerId].safePeriod);
return; // cannot refresh during safe period
}
var canShowAd = false;
if (this.impressionsCounter >= this.core.setup[this.bannerId].impressionsFrequency)
{
canShowAd = true;
this.debugLog("Banner " + this.bannerId + " impressions frequency requirements met. " + this.impressionsCounter + " >= " + this.core.setup[this.bannerId].impressionsFrequency);
}
else
{
this.debugLog("Banner " + this.bannerId + " impressions frequency requirements not met. " + this.impressionsCounter + " >= " + this.core.setup[this.bannerId].impressionsFrequency);
}
if (canShowAd === false)
{
if (timePassed >= this.core.setup[this.bannerId].timeFrequency)
{
canShowAd = true;
this.debugLog("Banner " + this.bannerId + " time frequency requirements met. " + timePassed + " >= " + this.core.setup[this.bannerId].timeFrequency);
}
else
{
this.debugLog("Banner " + this.bannerId + " time frequency requirements not met. " + timePassed + " >= " + this.core.setup[this.bannerId].timeFrequency);
}
}
if (canShowAd === false) return;
this.core.showBanner(this.bannerId);
this.lastImpressionTimestamp = new Date();
this.impressionsCounter = 0;
};
pluginProto.acts = new Acts();
function Exps() {};
/*Exps.prototype.MyExpression = function (ret) // 'ret' must always be the first parameter - always return the expression's result through it!
{
ret.set_int(1337); // return our value
};*/
pluginProto.exps = new Exps();
instanceProto.debugLog = function (msg_)
{
if ( ! this.core.DEBUG_MODE) return;
console.log("%c WebAdsPro[%cBANNER-" + this.bannerId + "%c]:", "font-weight: bolder; color: #00F", "font-weight: bolder; color: #0A0", "font-weight: bolder; color: #00F");
console.log(msg_);
console.log("");
};
}());
;
;
cr.plugins_.NinePatch = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.NinePatch.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
if (this.is_family)
return;
this.texture_img = new Image();
this.texture_img.cr_filesize = this.texture_filesize;
this.runtime.waitForImageLoad(this.texture_img, this.texture_file);
this.fillPattern = null;
this.leftPattern = null;
this.rightPattern = null;
this.topPattern = null;
this.bottomPattern = null;
this.webGL_texture = null;
this.webGL_fillTexture = null;
this.webGL_leftTexture = null;
this.webGL_rightTexture = null;
this.webGL_topTexture = null;
this.webGL_bottomTexture = null;
};
typeProto.onLostWebGLContext = function ()
{
if (this.is_family)
return;
this.webGL_texture = null;
this.webGL_fillTexture = null;
this.webGL_leftTexture = null;
this.webGL_rightTexture = null;
this.webGL_topTexture = null;
this.webGL_bottomTexture = null;
};
typeProto.onRestoreWebGLContext = function ()
{
if (this.is_family || !this.instances.length)
return;
if (!this.webGL_texture)
{
this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, true, this.runtime.linearSampling, this.texture_pixelformat);
}
};
typeProto.unloadTextures = function ()
{
if (this.is_family || this.instances.length)
return;
if (this.runtime.glwrap)
{
this.runtime.glwrap.deleteTexture(this.webGL_texture);
this.runtime.glwrap.deleteTexture(this.webGL_fillTexture);
this.runtime.glwrap.deleteTexture(this.webGL_leftTexture);
this.runtime.glwrap.deleteTexture(this.webGL_rightTexture);
this.runtime.glwrap.deleteTexture(this.webGL_topTexture);
this.runtime.glwrap.deleteTexture(this.webGL_bottomTexture);
this.webGL_texture = null;
this.webGL_fillTexture = null;
this.webGL_leftTexture = null;
this.webGL_rightTexture = null;
this.webGL_topTexture = null;
this.webGL_bottomTexture = null;
}
};
typeProto.slicePatch = function (x1, y1, x2, y2)
{
var tmpcanvas = document.createElement("canvas");
var w = x2 - x1;
var h = y2 - y1;
tmpcanvas.width = w;
tmpcanvas.height = h;
var tmpctx = tmpcanvas.getContext("2d");
tmpctx.drawImage(this.texture_img, x1, y1, w, h, 0, 0, w, h);
return tmpcanvas;
};
typeProto.createPatch = function (lm, rm, tm, bm)
{
var iw = this.texture_img.width;
var ih = this.texture_img.height;
var re = iw - rm;
var be = ih - bm;
if (this.runtime.glwrap)
{
if (this.webGL_fillTexture)
return; // already created
var glwrap = this.runtime.glwrap;
var ls = this.runtime.linearSampling;
var tf = this.texture_pixelformat;
if (re > lm && be > tm)
this.webGL_fillTexture = glwrap.loadTexture(this.slicePatch(lm, tm, re, be), true, ls, tf);
if (lm > 0 && be > tm)
this.webGL_leftTexture = glwrap.loadTexture(this.slicePatch(0, tm, lm, be), true, ls, tf, "repeat-y");
if (rm > 0 && be > tm)
this.webGL_rightTexture = glwrap.loadTexture(this.slicePatch(re, tm, iw, be), true, ls, tf, "repeat-y");
if (tm > 0 && re > lm)
this.webGL_topTexture = glwrap.loadTexture(this.slicePatch(lm, 0, re, tm), true, ls, tf, "repeat-x");
if (bm > 0 && re > lm)
this.webGL_bottomTexture = glwrap.loadTexture(this.slicePatch(lm, be, re, ih), true, ls, tf, "repeat-x");
}
else
{
if (this.fillPattern)
return; // already created
var ctx = this.runtime.ctx;
if (re > lm && be > tm)
this.fillPattern = ctx.createPattern(this.slicePatch(lm, tm, re, be), "repeat");
if (lm > 0 && be > tm)
this.leftPattern = ctx.createPattern(this.slicePatch(0, tm, lm, be), "repeat");
if (rm > 0 && be > tm)
this.rightPattern = ctx.createPattern(this.slicePatch(re, tm, iw, be), "repeat");
if (tm > 0 && re > lm)
this.topPattern = ctx.createPattern(this.slicePatch(lm, 0, re, tm), "repeat");
if (bm > 0 && re > lm)
this.bottomPattern = ctx.createPattern(this.slicePatch(lm, be, re, ih), "repeat");
}
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.leftMargin = this.properties[0];
this.rightMargin = this.properties[1];
this.topMargin = this.properties[2];
this.bottomMargin = this.properties[3];
this.edges = this.properties[4]; // 0=tile, 1=stretch
this.fill = this.properties[5]; // 0=tile, 1=stretch, 2=transparent
this.visible = (this.properties[6] === 0); // 0=visible, 1=invisible
this.seamless = (this.properties[8] !== 0); // 1px overdraw to hide seams
if (this.recycled)
this.rcTex.set(0, 0, 0, 0);
else
this.rcTex = new cr.rect(0, 0, 0, 0);
if (this.runtime.glwrap)
{
if (!this.type.webGL_texture)
{
this.type.webGL_texture = this.runtime.glwrap.loadTexture(this.type.texture_img, false, this.runtime.linearSampling, this.type.texture_pixelformat);
}
}
this.type.createPatch(this.leftMargin, this.rightMargin, this.topMargin, this.bottomMargin);
};
function drawPatternProperly(ctx, pattern, pw, ph, drawX, drawY, w, h, ox, oy)
{
ctx.save();
ctx.fillStyle = pattern;
var offX = drawX % pw;
var offY = drawY % ph;
if (offX < 0)
offX += pw;
if (offY < 0)
offY += ph;
ctx.translate(offX + ox, offY + oy);
ctx.fillRect(drawX - offX - ox, drawY - offY - oy, w, h);
ctx.restore();
};
instanceProto.draw = function(ctx)
{
var img = this.type.texture_img;
var lm = this.leftMargin;
var rm = this.rightMargin;
var tm = this.topMargin;
var bm = this.bottomMargin;
var iw = img.width;
var ih = img.height;
var re = iw - rm;
var be = ih - bm;
ctx.globalAlpha = this.opacity;
ctx.save();
var myx = this.x;
var myy = this.y;
var myw = this.width;
var myh = this.height;
if (this.runtime.pixel_rounding)
{
myx = Math.round(myx);
myy = Math.round(myy);
}
var drawX = -(this.hotspotX * this.width);
var drawY = -(this.hotspotY * this.height);
var offX = drawX % iw;
var offY = drawY % ih;
if (offX < 0)
offX += iw;
if (offY < 0)
offY += ih;
ctx.translate(myx + offX, myy + offY);
var x = drawX - offX;
var y = drawY - offY;
var s = (this.seamless ? 1 : 0);
if (lm > 0 && tm > 0)
ctx.drawImage(img, 0, 0, lm + s, tm + s, x, y, lm + s, tm + s);
if (rm > 0 && tm > 0)
ctx.drawImage(img, re - s, 0, rm + s, tm + s, x + myw - rm - s, y, rm + s, tm + s);
if (rm > 0 && bm > 0)
ctx.drawImage(img, re - s, be - s, rm + s, bm + s, x + myw - rm - s, y + myh - bm - s, rm + s, bm + s);
if (lm > 0 && bm > 0)
ctx.drawImage(img, 0, be - s, lm + s, bm + s, x, y + myh - bm - s, lm + s, bm + s);
if (this.edges === 0) // tile edges
{
var off = (this.fill === 2 ? 0 : s);
if (lm > 0 && be > tm)
drawPatternProperly(ctx, this.type.leftPattern, lm, be - tm, x, y + tm, lm + off, myh - tm - bm, 0, 0);
if (rm > 0 && be > tm)
drawPatternProperly(ctx, this.type.rightPattern, rm, be - tm, x + myw - rm - off, y + tm, rm + off, myh - tm - bm, off, 0);
if (tm > 0 && re > lm)
drawPatternProperly(ctx, this.type.topPattern, re - lm, tm, x + lm, y, myw - lm - rm, tm + off, 0, 0);
if (bm > 0 && re > lm)
drawPatternProperly(ctx, this.type.bottomPattern, re - lm, bm, x + lm, y + myh - bm - off, myw - lm - rm, bm + off, 0, off);
}
else if (this.edges === 1) // stretch edges
{
if (lm > 0 && be > tm && myh - tm - bm > 0)
ctx.drawImage(img, 0, tm, lm, be - tm, x, y + tm, lm, myh - tm - bm);
if (rm > 0 && be > tm && myh - tm - bm > 0)
ctx.drawImage(img, re, tm, rm, be - tm, x + myw - rm, y + tm, rm, myh - tm - bm);
if (tm > 0 && re > lm && myw - lm - rm > 0)
ctx.drawImage(img, lm, 0, re - lm, tm, x + lm, y, myw - lm - rm, tm);
if (bm > 0 && re > lm && myw - lm - rm > 0)
ctx.drawImage(img, lm, be, re - lm, bm, x + lm, y + myh - bm, myw - lm - rm, bm);
}
if (be > tm && re > lm)
{
if (this.fill === 0) // tile fill
{
drawPatternProperly(ctx, this.type.fillPattern, re - lm, be - tm, x + lm, y + tm, myw - lm - rm, myh - tm - bm, 0, 0);
}
else if (this.fill === 1) // stretch fill
{
if (myw - lm - rm > 0 && myh - tm - bm > 0)
{
ctx.drawImage(img, lm, tm, re - lm, be - tm, x + lm, y + tm, myw - lm - rm, myh - tm - bm);
}
}
}
ctx.restore();
};
instanceProto.drawPatch = function(glw, tex, sx, sy, sw, sh, dx, dy, dw, dh)
{
glw.setTexture(tex);
var rcTex = this.rcTex;
rcTex.left = sx / tex.c2width;
rcTex.top = sy / tex.c2height;
rcTex.right = (sx + sw) / tex.c2width;
rcTex.bottom = (sy + sh) / tex.c2height;
glw.quadTex(dx, dy, dx + dw, dy, dx + dw, dy + dh, dx, dy + dh, rcTex);
};
instanceProto.tilePatch = function(glw, tex, dx, dy, dw, dh, ox, oy)
{
glw.setTexture(tex);
var rcTex = this.rcTex;
rcTex.left = -ox / tex.c2width;
rcTex.top = -oy / tex.c2height;
rcTex.right = (dw - ox) / tex.c2width;
rcTex.bottom = (dh - oy) / tex.c2height;
glw.quadTex(dx, dy, dx + dw, dy, dx + dw, dy + dh, dx, dy + dh, rcTex);
};
instanceProto.drawGL_earlyZPass = function(glw)
{
this.drawGL(glw);
};
instanceProto.drawGL = function(glw)
{
var lm = this.leftMargin;
var rm = this.rightMargin;
var tm = this.topMargin;
var bm = this.bottomMargin;
var iw = this.type.texture_img.width;
var ih = this.type.texture_img.height;
var re = iw - rm;
var be = ih - bm;
glw.setOpacity(this.opacity);
var rcTex = this.rcTex;
var q = this.bquad;
var myx = q.tlx;
var myy = q.tly;
var myw = this.width;
var myh = this.height;
if (this.runtime.pixel_rounding)
{
myx = Math.round(myx);
myy = Math.round(myy);
}
var s = (this.seamless ? 1 : 0);
if (lm > 0 && tm > 0)
this.drawPatch(glw, this.type.webGL_texture, 0, 0, lm + s, tm + s, myx, myy, lm + s, tm + s);
if (rm > 0 && tm > 0)
this.drawPatch(glw, this.type.webGL_texture, re - s, 0, rm + s, tm + s, myx + myw - rm - s, myy, rm + s, tm + s);
if (rm > 0 && bm > 0)
this.drawPatch(glw, this.type.webGL_texture, 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(glw, this.type.webGL_texture, 0, be - s, lm + s, bm + s, myx, myy + myh - bm - s, lm + s, bm + s);
if (this.edges === 0) // tile edges
{
var off = (this.fill === 2 ? 0 : s);
if (lm > 0 && be > tm)
this.tilePatch(glw, this.type.webGL_leftTexture, myx, myy + tm, lm + off, myh - tm - bm, 0, 0);
if (rm > 0 && be > tm)
this.tilePatch(glw, this.type.webGL_rightTexture, myx + myw - rm - off, myy + tm, rm + off, myh - tm - bm, off, 0);
if (tm > 0 && re > lm)
this.tilePatch(glw, this.type.webGL_topTexture, myx + lm, myy, myw - lm - rm, tm + off, 0, 0);
if (bm > 0 && re > lm)
this.tilePatch(glw, this.type.webGL_bottomTexture, myx + lm, myy + myh - bm - off, myw - lm - rm, bm + off, 0, off);
}
else if (this.edges === 1) // stretch edges
{
if (lm > 0 && be > tm)
this.drawPatch(glw, this.type.webGL_texture, 0, tm, lm, be - tm, myx, myy + tm, lm, myh - tm - bm);
if (rm > 0 && be > tm)
this.drawPatch(glw, this.type.webGL_texture, re, tm, rm, be - tm, myx + myw - rm, myy + tm, rm, myh - tm - bm);
if (tm > 0 && re > lm)
this.drawPatch(glw, this.type.webGL_texture, lm, 0, re - lm, tm, myx + lm, myy, myw - lm - rm, tm);
if (bm > 0 && re > lm)
this.drawPatch(glw, this.type.webGL_texture, lm, be, re - lm, bm, myx + lm, myy + myh - bm, myw - lm - rm, bm);
}
if (be > tm && re > lm)
{
if (this.fill === 0) // tile fill
{
this.tilePatch(glw, this.type.webGL_fillTexture, myx + lm, myy + tm, myw - lm - rm, myh - tm - bm, 0, 0);
}
else if (this.fill === 1) // stretch fill
{
this.drawPatch(glw, this.type.webGL_texture, lm, tm, re - lm, be - tm, myx + lm, myy + tm, myw - lm - rm, myh - tm - bm);
}
}
};
function Cnds() {};
Cnds.prototype.OnURLLoaded = function ()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetEffect = function (effect)
{
this.blend_mode = effect;
this.compositeOp = cr.effectToCompositeOp(effect);
cr.setGLBlend(this, effect, this.runtime.gl);
this.runtime.redraw = true;
};
pluginProto.acts = new Acts();
function Exps() {};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.Particles = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Particles.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
if (this.is_family)
return;
this.texture_img = new Image();
this.texture_img.cr_filesize = this.texture_filesize;
this.webGL_texture = null;
this.runtime.waitForImageLoad(this.texture_img, this.texture_file);
};
typeProto.onLostWebGLContext = function ()
{
if (this.is_family)
return;
this.webGL_texture = null;
};
typeProto.onRestoreWebGLContext = function ()
{
if (this.is_family || !this.instances.length)
return;
if (!this.webGL_texture)
{
this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, true, this.runtime.linearSampling, this.texture_pixelformat);
}
};
typeProto.loadTextures = function ()
{
if (this.is_family || this.webGL_texture || !this.runtime.glwrap)
return;
this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, true, this.runtime.linearSampling, this.texture_pixelformat);
};
typeProto.unloadTextures = function ()
{
if (this.is_family || this.instances.length || !this.webGL_texture)
return;
this.runtime.glwrap.deleteTexture(this.webGL_texture);
this.webGL_texture = null;
};
typeProto.preloadCanvas2D = function (ctx)
{
ctx.drawImage(this.texture_img, 0, 0);
};
function Particle(owner)
{
this.owner = owner;
this.active = false;
this.x = 0;
this.y = 0;
this.speed = 0;
this.angle = 0;
this.opacity = 1;
this.grow = 0;
this.size = 0;
this.gs = 0; // gravity speed
this.age = 0;
cr.seal(this);
};
Particle.prototype.init = function ()
{
var owner = this.owner;
this.x = owner.x - (owner.xrandom / 2) + (Math.random() * owner.xrandom);
this.y = owner.y - (owner.yrandom / 2) + (Math.random() * owner.yrandom);
this.speed = owner.initspeed - (owner.speedrandom / 2) + (Math.random() * owner.speedrandom);
this.angle = owner.angle - (owner.spraycone / 2) + (Math.random() * owner.spraycone);
this.opacity = owner.initopacity;
this.size = owner.initsize - (owner.sizerandom / 2) + (Math.random() * owner.sizerandom);
this.grow = owner.growrate - (owner.growrandom / 2) + (Math.random() * owner.growrandom);
this.gs = 0;
this.age = 0;
};
Particle.prototype.tick = function (dt)
{
var owner = this.owner;
this.x += Math.cos(this.angle) * this.speed * dt;
this.y += Math.sin(this.angle) * this.speed * dt;
this.y += this.gs * dt;
this.speed += owner.acc * dt;
this.size += this.grow * dt;
this.gs += owner.g * dt;
this.age += dt;
if (this.size < 1)
{
this.active = false;
return;
}
if (owner.lifeanglerandom !== 0)
this.angle += (Math.random() * owner.lifeanglerandom * dt) - (owner.lifeanglerandom * dt / 2);
if (owner.lifespeedrandom !== 0)
this.speed += (Math.random() * owner.lifespeedrandom * dt) - (owner.lifespeedrandom * dt / 2);
if (owner.lifeopacityrandom !== 0)
{
this.opacity += (Math.random() * owner.lifeopacityrandom * dt) - (owner.lifeopacityrandom * dt / 2);
if (this.opacity < 0)
this.opacity = 0;
else if (this.opacity > 1)
this.opacity = 1;
}
if (owner.destroymode <= 1 && this.age >= owner.timeout)
{
this.active = false;
}
if (owner.destroymode === 2 && this.speed <= 0)
{
this.active = false;
}
};
Particle.prototype.draw = function (ctx)
{
var curopacity = this.owner.opacity * this.opacity;
if (curopacity === 0)
return;
if (this.owner.destroymode === 0)
curopacity *= 1 - (this.age / this.owner.timeout);
ctx.globalAlpha = curopacity;
var drawx = this.x - this.size / 2;
var drawy = this.y - this.size / 2;
if (this.owner.runtime.pixel_rounding)
{
drawx = (drawx + 0.5) | 0;
drawy = (drawy + 0.5) | 0;
}
ctx.drawImage(this.owner.type.texture_img, drawx, drawy, this.size, this.size);
};
Particle.prototype.drawGL = function (glw)
{
var curopacity = this.owner.opacity * this.opacity;
if (this.owner.destroymode === 0)
curopacity *= 1 - (this.age / this.owner.timeout);
var drawsize = this.size;
var scaleddrawsize = drawsize * this.owner.particlescale;
var drawx = this.x - drawsize / 2;
var drawy = this.y - drawsize / 2;
if (this.owner.runtime.pixel_rounding)
{
drawx = (drawx + 0.5) | 0;
drawy = (drawy + 0.5) | 0;
}
if (scaleddrawsize < 1 || curopacity === 0)
return;
if (scaleddrawsize < glw.minPointSize || scaleddrawsize > glw.maxPointSize)
{
glw.setOpacity(curopacity);
glw.quad(drawx, drawy, drawx + drawsize, drawy, drawx + drawsize, drawy + drawsize, drawx, drawy + drawsize);
}
else
glw.point(this.x, this.y, scaleddrawsize, curopacity);
};
Particle.prototype.left = function ()
{
return this.x - this.size / 2;
};
Particle.prototype.right = function ()
{
return this.x + this.size / 2;
};
Particle.prototype.top = function ()
{
return this.y - this.size / 2;
};
Particle.prototype.bottom = function ()
{
return this.y + this.size / 2;
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
var deadparticles = [];
instanceProto.onCreate = function()
{
var props = this.properties;
this.rate = props[0];
this.spraycone = cr.to_radians(props[1]);
this.spraytype = props[2]; // 0 = continuous, 1 = one-shot
this.spraying = true; // for continuous mode only
this.initspeed = props[3];
this.initsize = props[4];
this.initopacity = props[5] / 100.0;
this.growrate = props[6];
this.xrandom = props[7];
this.yrandom = props[8];
this.speedrandom = props[9];
this.sizerandom = props[10];
this.growrandom = props[11];
this.acc = props[12];
this.g = props[13];
this.lifeanglerandom = props[14];
this.lifespeedrandom = props[15];
this.lifeopacityrandom = props[16];
this.destroymode = props[17]; // 0 = fade, 1 = timeout, 2 = stopped
this.timeout = props[18];
this.particleCreateCounter = 0;
this.particlescale = 1;
this.particleBoxLeft = this.x;
this.particleBoxTop = this.y;
this.particleBoxRight = this.x;
this.particleBoxBottom = this.y;
this.add_bbox_changed_callback(function (self) {
self.bbox.set(self.particleBoxLeft, self.particleBoxTop, self.particleBoxRight, self.particleBoxBottom);
self.bquad.set_from_rect(self.bbox);
self.bbox_changed = false;
self.update_collision_cell();
self.update_render_cell();
});
if (!this.recycled)
this.particles = [];
this.runtime.tickMe(this);
this.type.loadTextures();
if (this.spraytype === 1)
{
for (var i = 0; i < this.rate; i++)
this.allocateParticle().opacity = 0;
}
this.first_tick = true; // for re-init'ing one-shot particles on first tick so they assume any new angle/position
};
instanceProto.saveToJSON = function ()
{
var o = {
"r": this.rate,
"sc": this.spraycone,
"st": this.spraytype,
"s": this.spraying,
"isp": this.initspeed,
"isz": this.initsize,
"io": this.initopacity,
"gr": this.growrate,
"xr": this.xrandom,
"yr": this.yrandom,
"spr": this.speedrandom,
"szr": this.sizerandom,
"grnd": this.growrandom,
"acc": this.acc,
"g": this.g,
"lar": this.lifeanglerandom,
"lsr": this.lifespeedrandom,
"lor": this.lifeopacityrandom,
"dm": this.destroymode,
"to": this.timeout,
"pcc": this.particleCreateCounter,
"ft": this.first_tick,
"p": []
};
var i, len, p;
var arr = o["p"];
for (i = 0, len = this.particles.length; i < len; i++)
{
p = this.particles[i];
arr.push([p.x, p.y, p.speed, p.angle, p.opacity, p.grow, p.size, p.gs, p.age]);
}
return o;
};
instanceProto.loadFromJSON = function (o)
{
this.rate = o["r"];
this.spraycone = o["sc"];
this.spraytype = o["st"];
this.spraying = o["s"];
this.initspeed = o["isp"];
this.initsize = o["isz"];
this.initopacity = o["io"];
this.growrate = o["gr"];
this.xrandom = o["xr"];
this.yrandom = o["yr"];
this.speedrandom = o["spr"];
this.sizerandom = o["szr"];
this.growrandom = o["grnd"];
this.acc = o["acc"];
this.g = o["g"];
this.lifeanglerandom = o["lar"];
this.lifespeedrandom = o["lsr"];
this.lifeopacityrandom = o["lor"];
this.destroymode = o["dm"];
this.timeout = o["to"];
this.particleCreateCounter = o["pcc"];
this.first_tick = o["ft"];
deadparticles.push.apply(deadparticles, this.particles);
cr.clearArray(this.particles);
var i, len, p, d;
var arr = o["p"];
for (i = 0, len = arr.length; i < len; i++)
{
p = this.allocateParticle();
d = arr[i];
p.x = d[0];
p.y = d[1];
p.speed = d[2];
p.angle = d[3];
p.opacity = d[4];
p.grow = d[5];
p.size = d[6];
p.gs = d[7];
p.age = d[8];
}
};
instanceProto.onDestroy = function ()
{
deadparticles.push.apply(deadparticles, this.particles);
cr.clearArray(this.particles);
};
instanceProto.allocateParticle = function ()
{
var p;
if (deadparticles.length)
{
p = deadparticles.pop();
p.owner = this;
}
else
p = new Particle(this);
this.particles.push(p);
p.active = true;
return p;
};
instanceProto.tick = function()
{
var dt = this.runtime.getDt(this);
var i, len, p, n, j;
if (this.spraytype === 0 && this.spraying)
{
this.particleCreateCounter += dt * this.rate;
n = cr.floor(this.particleCreateCounter);
this.particleCreateCounter -= n;
for (i = 0; i < n; i++)
{
p = this.allocateParticle();
p.init();
}
}
this.particleBoxLeft = this.x;
this.particleBoxTop = this.y;
this.particleBoxRight = this.x;
this.particleBoxBottom = this.y;
for (i = 0, j = 0, len = this.particles.length; i < len; i++)
{
p = this.particles[i];
this.particles[j] = p;
this.runtime.redraw = true;
if (this.spraytype === 1 && this.first_tick)
p.init();
p.tick(dt);
if (!p.active)
{
deadparticles.push(p);
continue;
}
if (p.left() < this.particleBoxLeft)
this.particleBoxLeft = p.left();
if (p.right() > this.particleBoxRight)
this.particleBoxRight = p.right();
if (p.top() < this.particleBoxTop)
this.particleBoxTop = p.top();
if (p.bottom() > this.particleBoxBottom)
this.particleBoxBottom = p.bottom();
j++;
}
cr.truncateArray(this.particles, j);
this.set_bbox_changed();
this.first_tick = false;
if (this.spraytype === 1 && this.particles.length === 0)
this.runtime.DestroyInstance(this);
};
instanceProto.draw = function (ctx)
{
var i, len, p, layer = this.layer;
for (i = 0, len = this.particles.length; i < len; i++)
{
p = this.particles[i];
if (p.right() >= layer.viewLeft && p.bottom() >= layer.viewTop && p.left() <= layer.viewRight && p.top() <= layer.viewBottom)
{
p.draw(ctx);
}
}
};
instanceProto.drawGL = function (glw)
{
this.particlescale = this.layer.getScale();
glw.setTexture(this.type.webGL_texture);
var i, len, p, layer = this.layer;
for (i = 0, len = this.particles.length; i < len; i++)
{
p = this.particles[i];
if (p.right() >= layer.viewLeft && p.bottom() >= layer.viewTop && p.left() <= layer.viewRight && p.top() <= layer.viewBottom)
{
p.drawGL(glw);
}
}
};
function Cnds() {};
Cnds.prototype.IsSpraying = function ()
{
return this.spraying;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetSpraying = function (set_)
{
this.spraying = (set_ !== 0);
};
Acts.prototype.SetEffect = function (effect)
{
this.blend_mode = effect;
this.compositeOp = cr.effectToCompositeOp(effect);
cr.setGLBlend(this, effect, this.runtime.gl);
this.runtime.redraw = true;
};
Acts.prototype.SetRate = function (x)
{
this.rate = x;
var diff, i;
if (this.spraytype === 1 && this.first_tick)
{
if (x < this.particles.length)
{
diff = this.particles.length - x;
for (i = 0; i < diff; i++)
deadparticles.push(this.particles.pop());
}
else if (x > this.particles.length)
{
diff = x - this.particles.length;
for (i = 0; i < diff; i++)
this.allocateParticle().opacity = 0;
}
}
};
Acts.prototype.SetSprayCone = function (x)
{
this.spraycone = cr.to_radians(x);
};
Acts.prototype.SetInitSpeed = function (x)
{
this.initspeed = x;
};
Acts.prototype.SetInitSize = function (x)
{
this.initsize = x;
};
Acts.prototype.SetInitOpacity = function (x)
{
this.initopacity = x / 100;
};
Acts.prototype.SetGrowRate = function (x)
{
this.growrate = x;
};
Acts.prototype.SetXRandomiser = function (x)
{
this.xrandom = x;
};
Acts.prototype.SetYRandomiser = function (x)
{
this.yrandom = x;
};
Acts.prototype.SetSpeedRandomiser = function (x)
{
this.speedrandom = x;
};
Acts.prototype.SetSizeRandomiser = function (x)
{
this.sizerandom = x;
};
Acts.prototype.SetGrowRateRandomiser = function (x)
{
this.growrandom = x;
};
Acts.prototype.SetParticleAcc = function (x)
{
this.acc = x;
};
Acts.prototype.SetGravity = function (x)
{
this.g = x;
};
Acts.prototype.SetAngleRandomiser = function (x)
{
this.lifeanglerandom = x;
};
Acts.prototype.SetLifeSpeedRandomiser = function (x)
{
this.lifespeedrandom = x;
};
Acts.prototype.SetOpacityRandomiser = function (x)
{
this.lifeopacityrandom = x;
};
Acts.prototype.SetTimeout = function (x)
{
this.timeout = x;
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.ParticleCount = function (ret)
{
ret.set_int(this.particles.length);
};
Exps.prototype.Rate = function (ret)
{
ret.set_float(this.rate);
};
Exps.prototype.SprayCone = function (ret)
{
ret.set_float(cr.to_degrees(this.spraycone));
};
Exps.prototype.InitSpeed = function (ret)
{
ret.set_float(this.initspeed);
};
Exps.prototype.InitSize = function (ret)
{
ret.set_float(this.initsize);
};
Exps.prototype.InitOpacity = function (ret)
{
ret.set_float(this.initopacity * 100);
};
Exps.prototype.InitGrowRate = function (ret)
{
ret.set_float(this.growrate);
};
Exps.prototype.XRandom = function (ret)
{
ret.set_float(this.xrandom);
};
Exps.prototype.YRandom = function (ret)
{
ret.set_float(this.yrandom);
};
Exps.prototype.InitSpeedRandom = function (ret)
{
ret.set_float(this.speedrandom);
};
Exps.prototype.InitSizeRandom = function (ret)
{
ret.set_float(this.sizerandom);
};
Exps.prototype.InitGrowRandom = function (ret)
{
ret.set_float(this.growrandom);
};
Exps.prototype.ParticleAcceleration = function (ret)
{
ret.set_float(this.acc);
};
Exps.prototype.Gravity = function (ret)
{
ret.set_float(this.g);
};
Exps.prototype.ParticleAngleRandom = function (ret)
{
ret.set_float(this.lifeanglerandom);
};
Exps.prototype.ParticleSpeedRandom = function (ret)
{
ret.set_float(this.lifespeedrandom);
};
Exps.prototype.ParticleOpacityRandom = function (ret)
{
ret.set_float(this.lifeopacityrandom);
};
Exps.prototype.Timeout = function (ret)
{
ret.set_float(this.timeout);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.Rex_EventBalancer = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Rex_EventBalancer.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.is_dynamic_mode = (this.properties[0] == 0);
this.processing_time = percentage2time(this.properties[1]);
this.repeat_count = this.properties[2];
this.is_running = false;
this.elapsed_ticks = 0;
this.trigger_mode_init = false;
this.is_looping = false;
};
var percentage2time = function (percentage)
{
if (percentage < 0.01)
percentage = 0.01;
return (1/60)*1000*percentage;
};
instanceProto.tick = function()
{
if (!this.is_running)
return;
this.elapsed_ticks += 1;
if (this.is_dynamic_mode)
this._run_dynamic_mode()
else
this._run_static_mode()
};
instanceProto._run_dynamic_mode = function()
{
var is_timeout = false;
var start_time = Date.now();
while (!is_timeout)
{
this.runtime.trigger(cr.plugins_.Rex_EventBalancer.prototype.cnds.OnProcessing, this);
if (!this.is_running)
break;
is_timeout = ((Date.now() - start_time) > this.processing_time);
}
};
instanceProto._run_static_mode = function()
{
var i;
for (i=0; i<this.repeat_count; i++)
{
this.runtime.trigger(cr.plugins_.Rex_EventBalancer.prototype.cnds.OnProcessing, this);
if (!this.is_running)
break;
}
};
instanceProto.saveToJSON = function ()
{
return { "dm": this.is_dynamic_mode,
"pt": this.processing_time,
"rc": this.repeat_count,
"isrun": this.is_running,
};
};
instanceProto.loadFromJSON = function (o)
{
this.is_dynamic_mode = o["dm"];
this.processing_time = o["pt"];
this.repeat_count = o["rc"];
this.is_running = o["isrun"];
if (this.is_running)
this.runtime.tickMe(this);
};
function Cnds() {};
pluginProto.cnds = new Cnds();
Cnds.prototype.OnStart = function()
{
return true;
};
Cnds.prototype.OnProcessing = function()
{
return true;
};
Cnds.prototype.OnStop = function()
{
return true;
};
Cnds.prototype.IsProcessing = function()
{
return this.is_running;
};
Cnds.prototype.DynamicLoop = function()
{
var current_frame = this.runtime.getCurrentEventStack();
var current_event = current_frame.current_event;
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
var start_time = Date.now();
this.is_looping = true;
if (solModifierAfterCnds)
{
while ((Date.now() - start_time) <= this.processing_time)
{
this.runtime.pushCopySol(current_event.solModifiers);
current_event.retrigger();
this.runtime.popSol(current_event.solModifiers);
if (!this.is_looping)
break;
}
}
else
{
while ((Date.now() - start_time) <= this.processing_time)
{
current_event.retrigger();
if (!this.is_looping)
break;
}
}
return false;
};
function Acts() {};
pluginProto.acts = new Acts();
Acts.prototype.Start = function()
{
if (!this.trigger_mode_init)
{
this.runtime.tickMe(this);
this.trigger_mode_init = true;
}
this.is_running = true;
this.elapsed_ticks = 0;
this.runtime.trigger(cr.plugins_.Rex_EventBalancer.prototype.cnds.OnStart, this);
};
Acts.prototype.Stop = function()
{
if (!this.is_running)
return;
this.is_running = false;
this.runtime.trigger(cr.plugins_.Rex_EventBalancer.prototype.cnds.OnStop, this);
};
Acts.prototype.SetProcessingTime = function(percentage)
{
this.processing_time = percentage2time(percentage);
};
Acts.prototype.SetRepeatCount = function(repeat_count)
{
if (repeat_count < 1)
repeat_count = 1;
this.repeat_count = repeat_count;
};
Acts.prototype.StopLoop = function()
{
this.is_running = false;
};
function Exps() {};
pluginProto.exps = new Exps();
Exps.prototype.ProcessingTime = function (ret)
{
ret.set_float(this.processing_time);
};
Exps.prototype.ElapsedTicks = function (ret)
{
ret.set_int(this.elapsed_ticks);
};
}());
;
;
cr.plugins_.Sprite = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Sprite.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
function frame_getDataUri()
{
if (this.datauri.length === 0)
{
var tmpcanvas = document.createElement("canvas");
tmpcanvas.width = this.width;
tmpcanvas.height = this.height;
var tmpctx = tmpcanvas.getContext("2d");
if (this.spritesheeted)
{
tmpctx.drawImage(this.texture_img, this.offx, this.offy, this.width, this.height,
0, 0, this.width, this.height);
}
else
{
tmpctx.drawImage(this.texture_img, 0, 0, this.width, this.height);
}
this.datauri = tmpcanvas.toDataURL("image/png");
}
return this.datauri;
};
typeProto.onCreate = function()
{
if (this.is_family)
return;
var i, leni, j, lenj;
var anim, frame, animobj, frameobj, wt, uv;
this.all_frames = [];
this.has_loaded_textures = false;
for (i = 0, leni = this.animations.length; i < leni; i++)
{
anim = this.animations[i];
animobj = {};
animobj.name = anim[0];
animobj.speed = anim[1];
animobj.loop = anim[2];
animobj.repeatcount = anim[3];
animobj.repeatto = anim[4];
animobj.pingpong = anim[5];
animobj.sid = anim[6];
animobj.frames = [];
for (j = 0, lenj = anim[7].length; j < lenj; j++)
{
frame = anim[7][j];
frameobj = {};
frameobj.texture_file = frame[0];
frameobj.texture_filesize = frame[1];
frameobj.offx = frame[2];
frameobj.offy = frame[3];
frameobj.width = frame[4];
frameobj.height = frame[5];
frameobj.duration = frame[6];
frameobj.hotspotX = frame[7];
frameobj.hotspotY = frame[8];
frameobj.image_points = frame[9];
frameobj.poly_pts = frame[10];
frameobj.pixelformat = frame[11];
frameobj.spritesheeted = (frameobj.width !== 0);
frameobj.datauri = ""; // generated on demand and cached
frameobj.getDataUri = frame_getDataUri;
uv = {};
uv.left = 0;
uv.top = 0;
uv.right = 1;
uv.bottom = 1;
frameobj.sheetTex = uv;
frameobj.webGL_texture = null;
wt = this.runtime.findWaitingTexture(frame[0]);
if (wt)
{
frameobj.texture_img = wt;
}
else
{
frameobj.texture_img = new Image();
frameobj.texture_img.cr_src = frame[0];
frameobj.texture_img.cr_filesize = frame[1];
frameobj.texture_img.c2webGL_texture = null;
this.runtime.waitForImageLoad(frameobj.texture_img, frame[0]);
}
cr.seal(frameobj);
animobj.frames.push(frameobj);
this.all_frames.push(frameobj);
}
cr.seal(animobj);
this.animations[i] = animobj; // swap array data for object
}
};
typeProto.updateAllCurrentTexture = function ()
{
var i, len, inst;
for (i = 0, len = this.instances.length; i < len; i++)
{
inst = this.instances[i];
inst.curWebGLTexture = inst.curFrame.webGL_texture;
}
};
typeProto.onLostWebGLContext = function ()
{
if (this.is_family)
return;
var i, len, frame;
for (i = 0, len = this.all_frames.length; i < len; ++i)
{
frame = this.all_frames[i];
frame.texture_img.c2webGL_texture = null;
frame.webGL_texture = null;
}
this.has_loaded_textures = false;
this.updateAllCurrentTexture();
};
typeProto.onRestoreWebGLContext = function ()
{
if (this.is_family || !this.instances.length)
return;
var i, len, frame;
for (i = 0, len = this.all_frames.length; i < len; ++i)
{
frame = this.all_frames[i];
frame.webGL_texture = this.runtime.glwrap.loadTexture(frame.texture_img, false, this.runtime.linearSampling, frame.pixelformat);
}
this.updateAllCurrentTexture();
};
typeProto.loadTextures = function ()
{
if (this.is_family || this.has_loaded_textures || !this.runtime.glwrap)
return;
var i, len, frame;
for (i = 0, len = this.all_frames.length; i < len; ++i)
{
frame = this.all_frames[i];
frame.webGL_texture = this.runtime.glwrap.loadTexture(frame.texture_img, false, this.runtime.linearSampling, frame.pixelformat);
}
this.has_loaded_textures = true;
};
typeProto.unloadTextures = function ()
{
if (this.is_family || this.instances.length || !this.has_loaded_textures)
return;
var i, len, frame;
for (i = 0, len = this.all_frames.length; i < len; ++i)
{
frame = this.all_frames[i];
this.runtime.glwrap.deleteTexture(frame.webGL_texture);
frame.webGL_texture = null;
}
this.has_loaded_textures = false;
};
var already_drawn_images = [];
typeProto.preloadCanvas2D = function (ctx)
{
var i, len, frameimg;
cr.clearArray(already_drawn_images);
for (i = 0, len = this.all_frames.length; i < len; ++i)
{
frameimg = this.all_frames[i].texture_img;
if (already_drawn_images.indexOf(frameimg) !== -1)
continue;
ctx.drawImage(frameimg, 0, 0);
already_drawn_images.push(frameimg);
}
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
var poly_pts = this.type.animations[0].frames[0].poly_pts;
if (this.recycled)
this.collision_poly.set_pts(poly_pts);
else
this.collision_poly = new cr.CollisionPoly(poly_pts);
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.visible = (this.properties[0] === 0); // 0=visible, 1=invisible
this.isTicking = false;
this.inAnimTrigger = false;
this.collisionsEnabled = (this.properties[3] !== 0);
this.cur_animation = this.getAnimationByName(this.properties[1]) || this.type.animations[0];
this.cur_frame = this.properties[2];
if (this.cur_frame < 0)
this.cur_frame = 0;
if (this.cur_frame >= this.cur_animation.frames.length)
this.cur_frame = this.cur_animation.frames.length - 1;
var curanimframe = this.cur_animation.frames[this.cur_frame];
this.collision_poly.set_pts(curanimframe.poly_pts);
this.hotspotX = curanimframe.hotspotX;
this.hotspotY = curanimframe.hotspotY;
this.cur_anim_speed = this.cur_animation.speed;
this.cur_anim_repeatto = this.cur_animation.repeatto;
if (!(this.type.animations.length === 1 && this.type.animations[0].frames.length === 1) && this.cur_anim_speed !== 0)
{
this.runtime.tickMe(this);
this.isTicking = true;
}
if (this.recycled)
this.animTimer.reset();
else
this.animTimer = new cr.KahanAdder();
this.frameStart = this.getNowTime();
this.animPlaying = true;
this.animRepeats = 0;
this.animForwards = true;
this.animTriggerName = "";
this.changeAnimName = "";
this.changeAnimFrom = 0;
this.changeAnimFrame = -1;
this.type.loadTextures();
var i, leni, j, lenj;
var anim, frame, uv, maintex;
for (i = 0, leni = this.type.animations.length; i < leni; i++)
{
anim = this.type.animations[i];
for (j = 0, lenj = anim.frames.length; j < lenj; j++)
{
frame = anim.frames[j];
if (frame.width === 0)
{
frame.width = frame.texture_img.width;
frame.height = frame.texture_img.height;
}
if (frame.spritesheeted)
{
maintex = frame.texture_img;
uv = frame.sheetTex;
uv.left = frame.offx / maintex.width;
uv.top = frame.offy / maintex.height;
uv.right = (frame.offx + frame.width) / maintex.width;
uv.bottom = (frame.offy + frame.height) / maintex.height;
if (frame.offx === 0 && frame.offy === 0 && frame.width === maintex.width && frame.height === maintex.height)
{
frame.spritesheeted = false;
}
}
}
}
this.curFrame = this.cur_animation.frames[this.cur_frame];
this.curWebGLTexture = this.curFrame.webGL_texture;
};
instanceProto.saveToJSON = function ()
{
var o = {
"a": this.cur_animation.sid,
"f": this.cur_frame,
"cas": this.cur_anim_speed,
"fs": this.frameStart,
"ar": this.animRepeats,
"at": this.animTimer.sum,
"rt": this.cur_anim_repeatto
};
if (!this.animPlaying)
o["ap"] = this.animPlaying;
if (!this.animForwards)
o["af"] = this.animForwards;
return o;
};
instanceProto.loadFromJSON = function (o)
{
var anim = this.getAnimationBySid(o["a"]);
if (anim)
this.cur_animation = anim;
this.cur_frame = o["f"];
if (this.cur_frame < 0)
this.cur_frame = 0;
if (this.cur_frame >= this.cur_animation.frames.length)
this.cur_frame = this.cur_animation.frames.length - 1;
this.cur_anim_speed = o["cas"];
this.frameStart = o["fs"];
this.animRepeats = o["ar"];
this.animTimer.reset();
this.animTimer.sum = o["at"];
this.animPlaying = o.hasOwnProperty("ap") ? o["ap"] : true;
this.animForwards = o.hasOwnProperty("af") ? o["af"] : true;
if (o.hasOwnProperty("rt"))
this.cur_anim_repeatto = o["rt"];
else
this.cur_anim_repeatto = this.cur_animation.repeatto;
this.curFrame = this.cur_animation.frames[this.cur_frame];
this.curWebGLTexture = this.curFrame.webGL_texture;
this.collision_poly.set_pts(this.curFrame.poly_pts);
this.hotspotX = this.curFrame.hotspotX;
this.hotspotY = this.curFrame.hotspotY;
};
instanceProto.animationFinish = function (reverse)
{
this.cur_frame = reverse ? 0 : this.cur_animation.frames.length - 1;
this.animPlaying = false;
this.animTriggerName = this.cur_animation.name;
this.inAnimTrigger = true;
this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnAnyAnimFinished, this);
this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnAnimFinished, this);
this.inAnimTrigger = false;
this.animRepeats = 0;
};
instanceProto.getNowTime = function()
{
return this.animTimer.sum;
};
instanceProto.tick = function()
{
this.animTimer.add(this.runtime.getDt(this));
if (this.changeAnimName.length)
this.doChangeAnim();
if (this.changeAnimFrame >= 0)
this.doChangeAnimFrame();
var now = this.getNowTime();
var cur_animation = this.cur_animation;
var prev_frame = cur_animation.frames[this.cur_frame];
var next_frame;
var cur_frame_time = prev_frame.duration / this.cur_anim_speed;
if (this.animPlaying && now >= this.frameStart + cur_frame_time)
{
if (this.animForwards)
{
this.cur_frame++;
}
else
{
this.cur_frame--;
}
this.frameStart += cur_frame_time;
if (this.cur_frame >= cur_animation.frames.length)
{
if (cur_animation.pingpong)
{
this.animForwards = false;
this.cur_frame = cur_animation.frames.length - 2;
}
else if (cur_animation.loop)
{
this.cur_frame = this.cur_anim_repeatto;
}
else
{
this.animRepeats++;
if (this.animRepeats >= cur_animation.repeatcount)
{
this.animationFinish(false);
}
else
{
this.cur_frame = this.cur_anim_repeatto;
}
}
}
if (this.cur_frame < 0)
{
if (cur_animation.pingpong)
{
this.cur_frame = 1;
this.animForwards = true;
if (!cur_animation.loop)
{
this.animRepeats++;
if (this.animRepeats >= cur_animation.repeatcount)
{
this.animationFinish(true);
}
}
}
else
{
if (cur_animation.loop)
{
this.cur_frame = this.cur_anim_repeatto;
}
else
{
this.animRepeats++;
if (this.animRepeats >= cur_animation.repeatcount)
{
this.animationFinish(true);
}
else
{
this.cur_frame = this.cur_anim_repeatto;
}
}
}
}
if (this.cur_frame < 0)
this.cur_frame = 0;
else if (this.cur_frame >= cur_animation.frames.length)
this.cur_frame = cur_animation.frames.length - 1;
if (now > this.frameStart + (cur_animation.frames[this.cur_frame].duration / this.cur_anim_speed))
{
this.frameStart = now;
}
next_frame = cur_animation.frames[this.cur_frame];
this.OnFrameChanged(prev_frame, next_frame);
this.runtime.redraw = true;
}
};
instanceProto.getAnimationByName = function (name_)
{
var i, len, a;
for (i = 0, len = this.type.animations.length; i < len; i++)
{
a = this.type.animations[i];
if (cr.equals_nocase(a.name, name_))
return a;
}
return null;
};
instanceProto.getAnimationBySid = function (sid_)
{
var i, len, a;
for (i = 0, len = this.type.animations.length; i < len; i++)
{
a = this.type.animations[i];
if (a.sid === sid_)
return a;
}
return null;
};
instanceProto.doChangeAnim = function ()
{
var prev_frame = this.cur_animation.frames[this.cur_frame];
var anim = this.getAnimationByName(this.changeAnimName);
this.changeAnimName = "";
if (!anim)
return;
if (cr.equals_nocase(anim.name, this.cur_animation.name) && this.animPlaying)
return;
this.cur_animation = anim;
this.cur_anim_speed = anim.speed;
this.cur_anim_repeatto = anim.repeatto;
if (this.cur_frame < 0)
this.cur_frame = 0;
if (this.cur_frame >= this.cur_animation.frames.length)
this.cur_frame = this.cur_animation.frames.length - 1;
if (this.changeAnimFrom === 1)
this.cur_frame = 0;
this.animPlaying = true;
this.frameStart = this.getNowTime();
this.animForwards = true;
this.OnFrameChanged(prev_frame, this.cur_animation.frames[this.cur_frame]);
this.runtime.redraw = true;
};
instanceProto.doChangeAnimFrame = function ()
{
var prev_frame = this.cur_animation.frames[this.cur_frame];
var prev_frame_number = this.cur_frame;
this.cur_frame = cr.floor(this.changeAnimFrame);
if (this.cur_frame < 0)
this.cur_frame = 0;
if (this.cur_frame >= this.cur_animation.frames.length)
this.cur_frame = this.cur_animation.frames.length - 1;
if (prev_frame_number !== this.cur_frame)
{
this.OnFrameChanged(prev_frame, this.cur_animation.frames[this.cur_frame]);
this.frameStart = this.getNowTime();
this.runtime.redraw = true;
}
this.changeAnimFrame = -1;
};
instanceProto.OnFrameChanged = function (prev_frame, next_frame)
{
var oldw = prev_frame.width;
var oldh = prev_frame.height;
var neww = next_frame.width;
var newh = next_frame.height;
if (oldw != neww)
this.width *= (neww / oldw);
if (oldh != newh)
this.height *= (newh / oldh);
this.hotspotX = next_frame.hotspotX;
this.hotspotY = next_frame.hotspotY;
this.collision_poly.set_pts(next_frame.poly_pts);
this.set_bbox_changed();
this.curFrame = next_frame;
this.curWebGLTexture = next_frame.webGL_texture;
var i, len, b;
for (i = 0, len = this.behavior_insts.length; i < len; i++)
{
b = this.behavior_insts[i];
if (b.onSpriteFrameChanged)
b.onSpriteFrameChanged(prev_frame, next_frame);
}
this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnFrameChanged, this);
};
instanceProto.draw = function(ctx)
{
ctx.globalAlpha = this.opacity;
var cur_frame = this.curFrame;
var spritesheeted = cur_frame.spritesheeted;
var cur_image = cur_frame.texture_img;
var myx = this.x;
var myy = this.y;
var w = this.width;
var h = this.height;
if (this.angle === 0 && w >= 0 && h >= 0)
{
myx -= this.hotspotX * w;
myy -= this.hotspotY * h;
if (this.runtime.pixel_rounding)
{
myx = Math.round(myx);
myy = Math.round(myy);
}
if (spritesheeted)
{
ctx.drawImage(cur_image, cur_frame.offx, cur_frame.offy, cur_frame.width, cur_frame.height,
myx, myy, w, h);
}
else
{
ctx.drawImage(cur_image, myx, myy, w, h);
}
}
else
{
if (this.runtime.pixel_rounding)
{
myx = Math.round(myx);
myy = Math.round(myy);
}
ctx.save();
var widthfactor = w > 0 ? 1 : -1;
var heightfactor = h > 0 ? 1 : -1;
ctx.translate(myx, myy);
if (widthfactor !== 1 || heightfactor !== 1)
ctx.scale(widthfactor, heightfactor);
ctx.rotate(this.angle * widthfactor * heightfactor);
var drawx = 0 - (this.hotspotX * cr.abs(w))
var drawy = 0 - (this.hotspotY * cr.abs(h));
if (spritesheeted)
{
ctx.drawImage(cur_image, cur_frame.offx, cur_frame.offy, cur_frame.width, cur_frame.height,
drawx, drawy, cr.abs(w), cr.abs(h));
}
else
{
ctx.drawImage(cur_image, drawx, drawy, cr.abs(w), cr.abs(h));
}
ctx.restore();
}
/*
ctx.strokeStyle = "#f00";
ctx.lineWidth = 3;
ctx.beginPath();
this.collision_poly.cache_poly(this.width, this.height, this.angle);
var i, len, ax, ay, bx, by;
for (i = 0, len = this.collision_poly.pts_count; i < len; i++)
{
ax = this.collision_poly.pts_cache[i*2] + this.x;
ay = this.collision_poly.pts_cache[i*2+1] + this.y;
bx = this.collision_poly.pts_cache[((i+1)%len)*2] + this.x;
by = this.collision_poly.pts_cache[((i+1)%len)*2+1] + this.y;
ctx.moveTo(ax, ay);
ctx.lineTo(bx, by);
}
ctx.stroke();
ctx.closePath();
*/
/*
if (this.behavior_insts.length >= 1 && this.behavior_insts[0].draw)
{
this.behavior_insts[0].draw(ctx);
}
*/
};
instanceProto.drawGL_earlyZPass = function(glw)
{
this.drawGL(glw);
};
instanceProto.drawGL = function(glw)
{
glw.setTexture(this.curWebGLTexture);
glw.setOpacity(this.opacity);
var cur_frame = this.curFrame;
var q = this.bquad;
if (this.runtime.pixel_rounding)
{
var ox = Math.round(this.x) - this.x;
var oy = Math.round(this.y) - this.y;
if (cur_frame.spritesheeted)
glw.quadTex(q.tlx + ox, q.tly + oy, q.trx + ox, q.try_ + oy, q.brx + ox, q.bry + oy, q.blx + ox, q.bly + oy, cur_frame.sheetTex);
else
glw.quad(q.tlx + ox, q.tly + oy, q.trx + ox, q.try_ + oy, q.brx + ox, q.bry + oy, q.blx + ox, q.bly + oy);
}
else
{
if (cur_frame.spritesheeted)
glw.quadTex(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly, cur_frame.sheetTex);
else
glw.quad(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly);
}
};
instanceProto.getImagePointIndexByName = function(name_)
{
var cur_frame = this.curFrame;
var i, len;
for (i = 0, len = cur_frame.image_points.length; i < len; i++)
{
if (cr.equals_nocase(name_, cur_frame.image_points[i][0]))
return i;
}
return -1;
};
instanceProto.getImagePoint = function(imgpt, getX)
{
var cur_frame = this.curFrame;
var image_points = cur_frame.image_points;
var index;
if (cr.is_string(imgpt))
index = this.getImagePointIndexByName(imgpt);
else
index = imgpt - 1; // 0 is origin
index = cr.floor(index);
if (index < 0 || index >= image_points.length)
return getX ? this.x : this.y; // return origin
var x = (image_points[index][1] - cur_frame.hotspotX) * this.width;
var y = image_points[index][2];
y = (y - cur_frame.hotspotY) * this.height;
var cosa = Math.cos(this.angle);
var sina = Math.sin(this.angle);
var x_temp = (x * cosa) - (y * sina);
y = (y * cosa) + (x * sina);
x = x_temp;
x += this.x;
y += this.y;
return getX ? x : y;
};
function Cnds() {};
var arrCache = [];
function allocArr()
{
if (arrCache.length)
return arrCache.pop();
else
return [0, 0, 0];
};
function freeArr(a)
{
a[0] = 0;
a[1] = 0;
a[2] = 0;
arrCache.push(a);
};
function makeCollKey(a, b)
{
if (a < b)
return "" + a + "," + b;
else
return "" + b + "," + a;
};
function collmemory_add(collmemory, a, b, tickcount)
{
var a_uid = a.uid;
var b_uid = b.uid;
var key = makeCollKey(a_uid, b_uid);
if (collmemory.hasOwnProperty(key))
{
collmemory[key][2] = tickcount;
return;
}
var arr = allocArr();
arr[0] = a_uid;
arr[1] = b_uid;
arr[2] = tickcount;
collmemory[key] = arr;
};
function collmemory_remove(collmemory, a, b)
{
var key = makeCollKey(a.uid, b.uid);
if (collmemory.hasOwnProperty(key))
{
freeArr(collmemory[key]);
delete collmemory[key];
}
};
function collmemory_removeInstance(collmemory, inst)
{
var uid = inst.uid;
var p, entry;
for (p in collmemory)
{
if (collmemory.hasOwnProperty(p))
{
entry = collmemory[p];
if (entry[0] === uid || entry[1] === uid)
{
freeArr(collmemory[p]);
delete collmemory[p];
}
}
}
};
var last_coll_tickcount = -2;
function collmemory_has(collmemory, a, b)
{
var key = makeCollKey(a.uid, b.uid);
if (collmemory.hasOwnProperty(key))
{
last_coll_tickcount = collmemory[key][2];
return true;
}
else
{
last_coll_tickcount = -2;
return false;
}
};
var candidates1 = [];
Cnds.prototype.OnCollision = function (rtype)
{
if (!rtype)
return false;
var runtime = this.runtime;
var cnd = runtime.getCurrentCondition();
var ltype = cnd.type;
var collmemory = null;
if (cnd.extra["collmemory"])
{
collmemory = cnd.extra["collmemory"];
}
else
{
collmemory = {};
cnd.extra["collmemory"] = collmemory;
}
if (!cnd.extra["spriteCreatedDestroyCallback"])
{
cnd.extra["spriteCreatedDestroyCallback"] = true;
runtime.addDestroyCallback(function(inst) {
collmemory_removeInstance(cnd.extra["collmemory"], inst);
});
}
var lsol = ltype.getCurrentSol();
var rsol = rtype.getCurrentSol();
var linstances = lsol.getObjects();
var rinstances;
var registeredInstances;
var l, linst, r, rinst;
var curlsol, currsol;
var tickcount = this.runtime.tickcount;
var lasttickcount = tickcount - 1;
var exists, run;
var current_event = runtime.getCurrentEventStack().current_event;
var orblock = current_event.orblock;
for (l = 0; l < linstances.length; l++)
{
linst = linstances[l];
if (rsol.select_all)
{
linst.update_bbox();
this.runtime.getCollisionCandidates(linst.layer, rtype, linst.bbox, candidates1);
rinstances = candidates1;
this.runtime.addRegisteredCollisionCandidates(linst, rtype, rinstances);
}
else
{
rinstances = rsol.getObjects();
}
for (r = 0; r < rinstances.length; r++)
{
rinst = rinstances[r];
if (runtime.testOverlap(linst, rinst) || runtime.checkRegisteredCollision(linst, rinst))
{
exists = collmemory_has(collmemory, linst, rinst);
run = (!exists || (last_coll_tickcount < lasttickcount));
collmemory_add(collmemory, linst, rinst, tickcount);
if (run)
{
runtime.pushCopySol(current_event.solModifiers);
curlsol = ltype.getCurrentSol();
currsol = rtype.getCurrentSol();
curlsol.select_all = false;
currsol.select_all = false;
if (ltype === rtype)
{
curlsol.instances.length = 2; // just use lsol, is same reference as rsol
curlsol.instances[0] = linst;
curlsol.instances[1] = rinst;
ltype.applySolToContainer();
}
else
{
curlsol.instances.length = 1;
currsol.instances.length = 1;
curlsol.instances[0] = linst;
currsol.instances[0] = rinst;
ltype.applySolToContainer();
rtype.applySolToContainer();
}
current_event.retrigger();
runtime.popSol(current_event.solModifiers);
}
}
else
{
collmemory_remove(collmemory, linst, rinst);
}
}
cr.clearArray(candidates1);
}
return false;
};
var rpicktype = null;
var rtopick = new cr.ObjectSet();
var needscollisionfinish = false;
var candidates2 = [];
var temp_bbox = new cr.rect(0, 0, 0, 0);
function DoOverlapCondition(rtype, offx, offy)
{
if (!rtype)
return false;
var do_offset = (offx !== 0 || offy !== 0);
var oldx, oldy, ret = false, r, lenr, rinst;
var cnd = this.runtime.getCurrentCondition();
var ltype = cnd.type;
var inverted = cnd.inverted;
var rsol = rtype.getCurrentSol();
var orblock = this.runtime.getCurrentEventStack().current_event.orblock;
var rinstances;
if (rsol.select_all)
{
this.update_bbox();
temp_bbox.copy(this.bbox);
temp_bbox.offset(offx, offy);
this.runtime.getCollisionCandidates(this.layer, rtype, temp_bbox, candidates2);
rinstances = candidates2;
}
else if (orblock)
{
if (this.runtime.isCurrentConditionFirst() && !rsol.else_instances.length && rsol.instances.length)
rinstances = rsol.instances;
else
rinstances = rsol.else_instances;
}
else
{
rinstances = rsol.instances;
}
rpicktype = rtype;
needscollisionfinish = (ltype !== rtype && !inverted);
if (do_offset)
{
oldx = this.x;
oldy = this.y;
this.x += offx;
this.y += offy;
this.set_bbox_changed();
}
for (r = 0, lenr = rinstances.length; r < lenr; r++)
{
rinst = rinstances[r];
if (this.runtime.testOverlap(this, rinst))
{
ret = true;
if (inverted)
break;
if (ltype !== rtype)
rtopick.add(rinst);
}
}
if (do_offset)
{
this.x = oldx;
this.y = oldy;
this.set_bbox_changed();
}
cr.clearArray(candidates2);
return ret;
};
typeProto.finish = function (do_pick)
{
if (!needscollisionfinish)
return;
if (do_pick)
{
var orblock = this.runtime.getCurrentEventStack().current_event.orblock;
var sol = rpicktype.getCurrentSol();
var topick = rtopick.valuesRef();
var i, len, inst;
if (sol.select_all)
{
sol.select_all = false;
cr.clearArray(sol.instances);
for (i = 0, len = topick.length; i < len; ++i)
{
sol.instances[i] = topick[i];
}
if (orblock)
{
cr.clearArray(sol.else_instances);
for (i = 0, len = rpicktype.instances.length; i < len; ++i)
{
inst = rpicktype.instances[i];
if (!rtopick.contains(inst))
sol.else_instances.push(inst);
}
}
}
else
{
if (orblock)
{
var initsize = sol.instances.length;
for (i = 0, len = topick.length; i < len; ++i)
{
sol.instances[initsize + i] = topick[i];
cr.arrayFindRemove(sol.else_instances, topick[i]);
}
}
else
{
cr.shallowAssignArray(sol.instances, topick);
}
}
rpicktype.applySolToContainer();
}
rtopick.clear();
needscollisionfinish = false;
};
Cnds.prototype.IsOverlapping = function (rtype)
{
return DoOverlapCondition.call(this, rtype, 0, 0);
};
Cnds.prototype.IsOverlappingOffset = function (rtype, offx, offy)
{
return DoOverlapCondition.call(this, rtype, offx, offy);
};
Cnds.prototype.IsAnimPlaying = function (animname)
{
if (this.changeAnimName.length)
return cr.equals_nocase(this.changeAnimName, animname);
else
return cr.equals_nocase(this.cur_animation.name, animname);
};
Cnds.prototype.CompareFrame = function (cmp, framenum)
{
return cr.do_cmp(this.cur_frame, cmp, framenum);
};
Cnds.prototype.CompareAnimSpeed = function (cmp, x)
{
var s = (this.animForwards ? this.cur_anim_speed : -this.cur_anim_speed);
return cr.do_cmp(s, cmp, x);
};
Cnds.prototype.OnAnimFinished = function (animname)
{
return cr.equals_nocase(this.animTriggerName, animname);
};
Cnds.prototype.OnAnyAnimFinished = function ()
{
return true;
};
Cnds.prototype.OnFrameChanged = function ()
{
return true;
};
Cnds.prototype.IsMirrored = function ()
{
return this.width < 0;
};
Cnds.prototype.IsFlipped = function ()
{
return this.height < 0;
};
Cnds.prototype.OnURLLoaded = function ()
{
return true;
};
Cnds.prototype.IsCollisionEnabled = function ()
{
return this.collisionsEnabled;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.Spawn = function (obj, layer, imgpt)
{
if (!obj || !layer)
return;
var inst = this.runtime.createInstance(obj, layer, this.getImagePoint(imgpt, true), this.getImagePoint(imgpt, false));
if (!inst)
return;
if (typeof inst.angle !== "undefined")
{
inst.angle = this.angle;
inst.set_bbox_changed();
}
this.runtime.isInOnDestroy++;
var i, len, s;
this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst);
if (inst.is_contained)
{
for (i = 0, len = inst.siblings.length; i < len; i++)
{
s = inst.siblings[i];
this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
}
}
this.runtime.isInOnDestroy--;
var cur_act = this.runtime.getCurrentAction();
var reset_sol = false;
if (cr.is_undefined(cur_act.extra["Spawn_LastExec"]) || cur_act.extra["Spawn_LastExec"] < this.runtime.execcount)
{
reset_sol = true;
cur_act.extra["Spawn_LastExec"] = this.runtime.execcount;
}
var sol;
if (obj != this.type)
{
sol = obj.getCurrentSol();
sol.select_all = false;
if (reset_sol)
{
cr.clearArray(sol.instances);
sol.instances[0] = inst;
}
else
sol.instances.push(inst);
if (inst.is_contained)
{
for (i = 0, len = inst.siblings.length; i < len; i++)
{
s = inst.siblings[i];
sol = s.type.getCurrentSol();
sol.select_all = false;
if (reset_sol)
{
cr.clearArray(sol.instances);
sol.instances[0] = s;
}
else
sol.instances.push(s);
}
}
}
};
Acts.prototype.SetEffect = function (effect)
{
this.blend_mode = effect;
this.compositeOp = cr.effectToCompositeOp(effect);
cr.setGLBlend(this, effect, this.runtime.gl);
this.runtime.redraw = true;
};
Acts.prototype.StopAnim = function ()
{
this.animPlaying = false;
};
Acts.prototype.StartAnim = function (from)
{
this.animPlaying = true;
this.frameStart = this.getNowTime();
if (from === 1 && this.cur_frame !== 0)
{
this.changeAnimFrame = 0;
if (!this.inAnimTrigger)
this.doChangeAnimFrame();
}
if (!this.isTicking)
{
this.runtime.tickMe(this);
this.isTicking = true;
}
};
Acts.prototype.SetAnim = function (animname, from)
{
this.changeAnimName = animname;
this.changeAnimFrom = from;
if (!this.isTicking)
{
this.runtime.tickMe(this);
this.isTicking = true;
}
if (!this.inAnimTrigger)
this.doChangeAnim();
};
Acts.prototype.SetAnimFrame = function (framenumber)
{
this.changeAnimFrame = framenumber;
if (!this.isTicking)
{
this.runtime.tickMe(this);
this.isTicking = true;
}
if (!this.inAnimTrigger)
this.doChangeAnimFrame();
};
Acts.prototype.SetAnimSpeed = function (s)
{
this.cur_anim_speed = cr.abs(s);
this.animForwards = (s >= 0);
if (!this.isTicking)
{
this.runtime.tickMe(this);
this.isTicking = true;
}
};
Acts.prototype.SetAnimRepeatToFrame = function (s)
{
s = Math.floor(s);
if (s < 0)
s = 0;
if (s >= this.cur_animation.frames.length)
s = this.cur_animation.frames.length - 1;
this.cur_anim_repeatto = s;
};
Acts.prototype.SetMirrored = function (m)
{
var neww = cr.abs(this.width) * (m === 0 ? -1 : 1);
if (this.width === neww)
return;
this.width = neww;
this.set_bbox_changed();
};
Acts.prototype.SetFlipped = function (f)
{
var newh = cr.abs(this.height) * (f === 0 ? -1 : 1);
if (this.height === newh)
return;
this.height = newh;
this.set_bbox_changed();
};
Acts.prototype.SetScale = function (s)
{
var cur_frame = this.curFrame;
var mirror_factor = (this.width < 0 ? -1 : 1);
var flip_factor = (this.height < 0 ? -1 : 1);
var new_width = cur_frame.width * s * mirror_factor;
var new_height = cur_frame.height * s * flip_factor;
if (this.width !== new_width || this.height !== new_height)
{
this.width = new_width;
this.height = new_height;
this.set_bbox_changed();
}
};
Acts.prototype.LoadURL = function (url_, resize_, crossOrigin_)
{
var img = new Image();
var self = this;
var curFrame_ = this.curFrame;
img.onload = function ()
{
if (curFrame_.texture_img.src === img.src)
{
if (self.runtime.glwrap && self.curFrame === curFrame_)
self.curWebGLTexture = curFrame_.webGL_texture;
if (resize_ === 0) // resize to image size
{
self.width = img.width;
self.height = img.height;
self.set_bbox_changed();
}
self.runtime.redraw = true;
self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self);
return;
}
curFrame_.texture_img = img;
curFrame_.offx = 0;
curFrame_.offy = 0;
curFrame_.width = img.width;
curFrame_.height = img.height;
curFrame_.spritesheeted = false;
curFrame_.datauri = "";
curFrame_.pixelformat = 0; // reset to RGBA, since we don't know what type of image will have come in
if (self.runtime.glwrap)
{
if (curFrame_.webGL_texture)
self.runtime.glwrap.deleteTexture(curFrame_.webGL_texture);
curFrame_.webGL_texture = self.runtime.glwrap.loadTexture(img, false, self.runtime.linearSampling);
if (self.curFrame === curFrame_)
self.curWebGLTexture = curFrame_.webGL_texture;
self.type.updateAllCurrentTexture();
}
if (resize_ === 0) // resize to image size
{
self.width = img.width;
self.height = img.height;
self.set_bbox_changed();
}
self.runtime.redraw = true;
self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self);
};
if (url_.substr(0, 5) !== "data:" && crossOrigin_ === 0)
img["crossOrigin"] = "anonymous";
this.runtime.setImageSrc(img, url_);
};
Acts.prototype.SetCollisions = function (set_)
{
if (this.collisionsEnabled === (set_ !== 0))
return; // no change
this.collisionsEnabled = (set_ !== 0);
if (this.collisionsEnabled)
this.set_bbox_changed(); // needs to be added back to cells
else
{
if (this.collcells.right >= this.collcells.left)
this.type.collision_grid.update(this, this.collcells, null);
this.collcells.set(0, 0, -1, -1);
}
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.AnimationFrame = function (ret)
{
ret.set_int(this.cur_frame);
};
Exps.prototype.AnimationFrameCount = function (ret)
{
ret.set_int(this.cur_animation.frames.length);
};
Exps.prototype.AnimationName = function (ret)
{
ret.set_string(this.cur_animation.name);
};
Exps.prototype.AnimationSpeed = function (ret)
{
ret.set_float(this.animForwards ? this.cur_anim_speed : -this.cur_anim_speed);
};
Exps.prototype.ImagePointX = function (ret, imgpt)
{
ret.set_float(this.getImagePoint(imgpt, true));
};
Exps.prototype.ImagePointY = function (ret, imgpt)
{
ret.set_float(this.getImagePoint(imgpt, false));
};
Exps.prototype.ImagePointCount = function (ret)
{
ret.set_int(this.curFrame.image_points.length);
};
Exps.prototype.ImageWidth = function (ret)
{
ret.set_float(this.curFrame.width);
};
Exps.prototype.ImageHeight = function (ret)
{
ret.set_float(this.curFrame.height);
};
pluginProto.exps = new Exps();
}());
/* global cr,log,assert2 */
/* jshint globalstrict: true */
/* jshint strict: true */
;
;
var jText = '';
cr.plugins_.SpriteFontPlus = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.SpriteFontPlus.prototype;
pluginProto.onCreate = function ()
{
};
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
if (this.is_family)
return;
this.texture_img = new Image();
this.texture_img["idtkLoadDisposed"] = true;
this.texture_img.src = this.texture_file;
this.runtime.wait_for_textures.push(this.texture_img);
this.webGL_texture = null;
};
typeProto.onLostWebGLContext = function ()
{
if (this.is_family)
return;
this.webGL_texture = null;
};
typeProto.onRestoreWebGLContext = function ()
{
if (this.is_family || !this.instances.length)
return;
if (!this.webGL_texture)
{
this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, false, this.runtime.linearSampling, this.texture_pixelformat);
}
var i, len;
for (i = 0, len = this.instances.length; i < len; i++)
this.instances[i].webGL_texture = this.webGL_texture;
};
typeProto.unloadTextures = function ()
{
if (this.is_family || this.instances.length || !this.webGL_texture)
return;
this.runtime.glwrap.deleteTexture(this.webGL_texture);
this.webGL_texture = null;
};
typeProto.preloadCanvas2D = function (ctx)
{
ctx.drawImage(this.texture_img, 0, 0);
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onDestroy = function()
{
freeAllLines (this.lines);
freeAllClip (this.clipList);
freeAllClipUV(this.clipUV);
cr.wipe(this.characterWidthList);
};
instanceProto.onCreate = function()
{
this.texture_img = this.type.texture_img;
this.characterWidth = this.properties[0];
this.characterHeight = this.properties[1];
this.characterSet = this.properties[2];
this.text = this.properties[3];
this.characterScale = this.properties[4];
this.visible = (this.properties[5] === 0); // 0=visible, 1=invisible
this.halign = this.properties[6]/2.0; // 0=left, 1=center, 2=right
this.valign = this.properties[7]/2.0; // 0=top, 1=center, 2=bottom
this.wrapbyword = (this.properties[9] === 0); // 0=word, 1=character
this.characterSpacing = this.properties[10];
this.lineHeight = this.properties[11];
this.textWidth = 0;
this.textHeight = 0;
this.charWidthJSON = this.properties[12];
this.spaceWidth = this.properties[13];
jText = this.charWidthJSON;
if (this.recycled)
{
this.lines.length = 0;
cr.wipe(this.clipList);
cr.wipe(this.clipUV);
cr.wipe(this.characterWidthList);
}
else
{
this.lines = [];
this.clipList = {};
this.clipUV = {};
this.characterWidthList = {};
}
try{
if(this.charWidthJSON){
if(this.charWidthJSON.indexOf('""c2array""') !== -1) {
var jStr = jQuery.parseJSON(this.charWidthJSON.replace(/""/g,'"'));
var l = jStr.size[1];
for(var s = 0; s < l; s++) {
var cs = jStr.data[1][s][0];
var w = jStr.data[0][s][0];
for(var c = 0; c < cs.length; c++) {
this.characterWidthList[cs.charAt(c)] = w
}
}
} else {
var jStr = jQuery.parseJSON(this.charWidthJSON);
var l = jStr.length;
for(var s = 0; s < l; s++) {
var cs = jStr[s][1];
var w = jStr[s][0];
for(var c = 0; c < cs.length; c++) {
this.characterWidthList[cs.charAt(c)] = w
}
}
}
}
if(this.spaceWidth !== -1) {
this.characterWidthList[' '] = this.spaceWidth;
}
}
catch(e){
if(window.console && window.console.log) {
window.console.log('SpriteFont+ Failure: ' + e);
}
}
this.text_changed = true;
this.lastwrapwidth = this.width;
if (this.runtime.glwrap)
{
if (!this.type.webGL_texture)
{
this.type.webGL_texture = this.runtime.glwrap.loadTexture(this.type.texture_img, false, this.runtime.linearSampling, this.type.texture_pixelformat);
}
this.webGL_texture = this.type.webGL_texture;
}
this.SplitSheet();
};
instanceProto.saveToJSON = function ()
{
var save = {
"t": this.text,
"csc": this.characterScale,
"csp": this.characterSpacing,
"lh": this.lineHeight,
"tw": this.textWidth,
"th": this.textHeight,
"lrt": this.last_render_tick,
"cw": {}
};
for (var ch in this.characterWidthList)
save["cw"][ch] = this.characterWidthList[ch];
return save;
};
instanceProto.loadFromJSON = function (o)
{
this.text = o["t"];
this.characterScale = o["csc"];
this.characterSpacing = o["csp"];
this.lineHeight = o["lh"];
this.textWidth = o["tw"];
this.textHeight = o["th"];
this.last_render_tick = o["lrt"];
for(var ch in o["cw"])
this.characterWidthList[ch] = o["cw"][ch];
this.text_changed = true;
this.lastwrapwidth = this.width;
};
function trimRight(text)
{
return text.replace(/\s\s*$/, '');
}
var MAX_CACHE_SIZE = 1000;
function alloc(cache,Constructor)
{
if (cache.length)
return cache.pop();
else
return new Constructor();
}
function free(cache,data)
{
if (cache.length < MAX_CACHE_SIZE)
{
cache.push(data);
}
}
function freeAll(cache,dataList,isArray)
{
if (isArray) {
var i, len;
for (i = 0, len = dataList.length; i < len; i++)
{
free(cache,dataList[i]);
}
dataList.length = 0;
} else {
var prop;
for(prop in dataList) {
if(Object.prototype.hasOwnProperty.call(dataList,prop)) {
free(cache,dataList[prop]);
delete dataList[prop];
}
}
}
}
function addLine(inst,lineIndex,cur_line) {
var lines = inst.lines;
var line;
cur_line = trimRight(cur_line);
if (lineIndex >= lines.length)
lines.push(allocLine());
line = lines[lineIndex];
line.text = cur_line;
line.width = inst.measureWidth(cur_line);
inst.textWidth = cr.max(inst.textWidth,line.width);
}
var linesCache = [];
function allocLine() { return alloc(linesCache,Object); }
function freeLine(l) { free(linesCache,l); }
function freeAllLines(arr) { freeAll(linesCache,arr,true); }
function addClip(obj,property,x,y,w,h) {
if (obj[property] === undefined) {
obj[property] = alloc(clipCache,Object);
}
obj[property].x = x;
obj[property].y = y;
obj[property].w = w;
obj[property].h = h;
}
var clipCache = [];
function allocClip() { return alloc(clipCache,Object); }
function freeAllClip(obj) { freeAll(clipCache,obj,false);}
function addClipUV(obj,property,left,top,right,bottom) {
if (obj[property] === undefined) {
obj[property] = alloc(clipUVCache,cr.rect);
}
obj[property].left = left;
obj[property].top = top;
obj[property].right = right;
obj[property].bottom = bottom;
}
var clipUVCache = [];
function allocClipUV() { return alloc(clipUVCache,cr.rect);}
function freeAllClipUV(obj) { freeAll(clipUVCache,obj,false);}
instanceProto.SplitSheet = function() {
var texture = this.texture_img;
var texWidth = texture.width;
var texHeight = texture.height;
var charWidth = this.characterWidth;
var charHeight = this.characterHeight;
var charU = charWidth /texWidth;
var charV = charHeight/texHeight;
var charSet = this.characterSet ;
var cols = Math.floor(texWidth/charWidth);
var rows = Math.floor(texHeight/charHeight);
for ( var c = 0; c < charSet.length; c++) {
if (c >= cols * rows) break;
var x = c%cols;
var y = Math.floor(c/cols);
var letter = charSet.charAt(c);
if (this.runtime.glwrap) {
addClipUV(
this.clipUV, letter,
x * charU ,
y * charV ,
(x+1) * charU ,
(y+1) * charV
);
} else {
addClip(
this.clipList, letter,
x * charWidth,
y * charHeight,
charWidth,
charHeight
);
}
}
};
/*
* Word-Wrapping
*/
var wordsCache = [];
pluginProto.TokeniseWords = function (text)
{
wordsCache.length = 0;
var cur_word = "";
var ch;
var i = 0;
while (i < text.length)
{
ch = text.charAt(i);
if (ch === "\n")
{
if (cur_word.length)
{
wordsCache.push(cur_word);
cur_word = "";
}
wordsCache.push("\n");
++i;
}
else if (ch === " " || ch === "\t" || ch === "-")
{
do {
cur_word += text.charAt(i);
i++;
}
while (i < text.length && (text.charAt(i) === " " || text.charAt(i) === "\t"));
wordsCache.push(cur_word);
cur_word = "";
}
else if (i < text.length)
{
cur_word += ch;
i++;
}
}
if (cur_word.length)
wordsCache.push(cur_word);
};
pluginProto.WordWrap = function (inst)
{
var text = inst.text;
var lines = inst.lines;
if (!text || !text.length)
{
freeAllLines(lines);
return;
}
var width = inst.width;
if (width <= 2.0)
{
freeAllLines(lines);
return;
}
var charWidth = inst.characterWidth;
var charScale = inst.characterScale;
var charSpacing = inst.characterSpacing;
if ( (text.length * (charWidth * charScale + charSpacing) - charSpacing) <= width && text.indexOf("\n") === -1)
{
var all_width = inst.measureWidth(text);
if (all_width <= width)
{
freeAllLines(lines);
lines.push(allocLine());
lines[0].text = text;
lines[0].width = all_width;
inst.textWidth = all_width;
inst.textHeight = inst.characterHeight * charScale + inst.lineHeight;
return;
}
}
var wrapbyword = inst.wrapbyword;
this.WrapText(inst);
inst.textHeight = lines.length * (inst.characterHeight * charScale + inst.lineHeight);
};
pluginProto.WrapText = function (inst)
{
var wrapbyword = inst.wrapbyword;
var text = inst.text;
var lines = inst.lines;
var width = inst.width;
var wordArray;
if (wrapbyword) {
this.TokeniseWords(text); // writes to wordsCache
wordArray = wordsCache;
} else {
wordArray = text;
}
var cur_line = "";
var prev_line;
var line_width;
var i;
var lineIndex = 0;
var line;
var ignore_newline = false;
for (i = 0; i < wordArray.length; i++)
{
if (wordArray[i] === "\n")
{
if (ignore_newline === true) {
ignore_newline = false;
} else {
addLine(inst,lineIndex,cur_line);
lineIndex++;
}
cur_line = "";
continue;
}
ignore_newline = false;
prev_line = cur_line;
cur_line += wordArray[i];
line_width = inst.measureWidth(trimRight(cur_line));
if (line_width > width)
{
if (prev_line === "") {
addLine(inst,lineIndex,cur_line);
cur_line = "";
ignore_newline = true;
} else {
addLine(inst,lineIndex,prev_line);
cur_line = wordArray[i];
}
lineIndex++;
if (!wrapbyword && cur_line === " ")
cur_line = "";
}
}
if (trimRight(cur_line).length)
{
addLine(inst,lineIndex,cur_line);
lineIndex++;
}
for (i = lineIndex; i < lines.length; i++)
freeLine(lines[i]);
lines.length = lineIndex;
};
instanceProto.measureWidth = function(text) {
var spacing = this.characterSpacing;
var len = text.length;
var width = 0;
for (var i = 0; i < len; i++) {
width += this.getCharacterWidth(text.charAt(i)) * this.characterScale + spacing;
}
width -= (width > 0) ? spacing : 0;
return width;
};
/***/
instanceProto.getCharacterWidth = function(character) {
var widthList = this.characterWidthList;
if (widthList[character] !== undefined) {
return widthList[character];
} else {
return this.characterWidth;
}
};
instanceProto.rebuildText = function() {
if (this.text_changed || this.width !== this.lastwrapwidth) {
this.textWidth = 0;
this.textHeight = 0;
this.type.plugin.WordWrap(this);
this.text_changed = false;
this.lastwrapwidth = this.width;
}
};
var EPSILON = 0.00001;
instanceProto.draw = function(ctx, glmode)
{
var texture = this.texture_img;
if (this.text !== "" && texture != null) {
this.rebuildText();
if (this.height < this.characterHeight*this.characterScale + this.lineHeight) {
return;
}
ctx.globalAlpha = this.opacity;
var myx = this.x;
var myy = this.y;
if (this.runtime.pixel_rounding)
{
myx = (myx + 0.5) | 0;
myy = (myy + 0.5) | 0;
}
ctx.save();
ctx.translate(myx, myy);
ctx.rotate(this.angle);
var ha = this.halign;
var va = this.valign;
var scale = this.characterScale;
var charHeight = this.characterHeight * scale;
var lineHeight = this.lineHeight;
var charSpace = this.characterSpacing;
var lines = this.lines;
var textHeight = this.textHeight;
var halign;
var valign = va * cr.max(0,(this.height - textHeight));
var offx = -(this.hotspotX * this.width);
var offy = -(this.hotspotY * this.height);
offy += valign;
var drawX ;
var drawY = offy;
for(var i = 0; i < lines.length; i++) {
var line = lines[i].text;
var len = lines[i].width;
halign = ha * cr.max(0,this.width - len);
drawX = offx + halign;
drawY += lineHeight;
for(var j = 0; j < line.length; j++) {
var letter = line.charAt(j);
var clip = this.clipList[letter];
if ( drawX + this.getCharacterWidth(letter) * scale > this.width + EPSILON ) {
break;
}
if (clip !== undefined) {
ctx.drawImage( this.texture_img,
clip.x, clip.y, clip.w, clip.h,
Math.round(drawX),Math.round(drawY),clip.w*scale,clip.h*scale);
}
drawX += this.getCharacterWidth(letter) * scale + charSpace;
}
drawY += charHeight;
if ( drawY + charHeight + lineHeight > this.height) {
break;
}
}
ctx.restore();
}
};
var dQuad = new cr.quad();
function rotateQuad(quad,cosa,sina) {
var x_temp;
x_temp = (quad.tlx * cosa) - (quad.tly * sina);
quad.tly = (quad.tly * cosa) + (quad.tlx * sina);
quad.tlx = x_temp;
x_temp = (quad.trx * cosa) - (quad.try_ * sina);
quad.try_ = (quad.try_ * cosa) + (quad.trx * sina);
quad.trx = x_temp;
x_temp = (quad.blx * cosa) - (quad.bly * sina);
quad.bly = (quad.bly * cosa) + (quad.blx * sina);
quad.blx = x_temp;
x_temp = (quad.brx * cosa) - (quad.bry * sina);
quad.bry = (quad.bry * cosa) + (quad.brx * sina);
quad.brx = x_temp;
}
instanceProto.drawGL = function(glw)
{
glw.setTexture(this.webGL_texture);
glw.setOpacity(this.opacity);
if (this.text !== "") {
this.rebuildText();
if (this.height < this.characterHeight*this.characterScale + this.lineHeight) {
return;
}
this.update_bbox();
var q = this.bquad;
var ox = 0;
var oy = 0;
if (this.runtime.pixel_rounding)
{
ox = ((this.x + 0.5) | 0) - this.x;
oy = ((this.y + 0.5) | 0) - this.y;
}
var angle = this.angle;
var ha = this.halign;
var va = this.valign;
var scale = this.characterScale;
var charHeight = this.characterHeight * scale; // to precalculate in onCreate or on change
var lineHeight = this.lineHeight;
var charSpace = this.characterSpacing;
var lines = this.lines;
var textHeight = this.textHeight;
var cosa,sina;
if (angle !== 0)
{
cosa = Math.cos(angle);
sina = Math.sin(angle);
}
var halign;
var valign = va * cr.max(0,(this.height - textHeight));
var offx = q.tlx + ox;
var offy = q.tly + oy;
var drawX ;
var drawY = valign;
for(var i = 0; i < lines.length; i++) {
var line = lines[i].text;
var lineWidth = lines[i].width;
halign = ha * cr.max(0,this.width - lineWidth);
drawX = halign;
drawY += lineHeight;
for(var j = 0; j < line.length; j++) {
var letter = line.charAt(j);
var clipUV = this.clipUV[letter];
if ( drawX + this.getCharacterWidth(letter) * scale > this.width + EPSILON) {
break;
}
if (clipUV !== undefined) {
var clipWidth = this.characterWidth*scale;
var clipHeight = this.characterHeight*scale;
dQuad.tlx = drawX;
dQuad.tly = drawY;
dQuad.trx = drawX + clipWidth;
dQuad.try_ = drawY ;
dQuad.blx = drawX;
dQuad.bly = drawY + clipHeight;
dQuad.brx = drawX + clipWidth;
dQuad.bry = drawY + clipHeight;
if(angle !== 0)
{
rotateQuad(dQuad,cosa,sina);
}
dQuad.offset(offx,offy);
glw.quadTex(
dQuad.tlx, dQuad.tly,
dQuad.trx, dQuad.try_,
dQuad.brx, dQuad.bry,
dQuad.blx, dQuad.bly,
clipUV
);
}
drawX += this.getCharacterWidth(letter) * scale + charSpace;
}
drawY += charHeight;
if ( drawY + charHeight + lineHeight > this.height) {
break;
}
}
}
};
function Cnds() {}
Cnds.prototype.CompareText = function(text_to_compare, case_sensitive)
{
if (case_sensitive)
return this.text == text_to_compare;
else
return cr.equals_nocase(this.text, text_to_compare);
};
pluginProto.cnds = new Cnds();
function Acts() {}
Acts.prototype.SetText = function(param)
{
if (cr.is_number(param) && param < 1e9)
param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
var text_to_set = param.toString();
if (this.text !== text_to_set)
{
this.text = text_to_set;
this.text_changed = true;
this.runtime.redraw = true;
}
};
Acts.prototype.AppendText = function(param)
{
if (cr.is_number(param))
param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
var text_to_append = param.toString();
if (text_to_append) // not empty
{
this.text += text_to_append;
this.text_changed = true;
this.runtime.redraw = true;
}
};
Acts.prototype.SetScale = function(param)
{
if (param !== this.characterScale) {
this.characterScale = param;
this.text_changed = true;
this.runtime.redraw = true;
}
};
Acts.prototype.SetCharacterSpacing = function(param)
{
if (param !== this.CharacterSpacing) {
this.characterSpacing = param;
this.text_changed = true;
this.runtime.redraw = true;
}
};
Acts.prototype.SetLineHeight = function(param)
{
if (param !== this.lineHeight) {
this.lineHeight = param;
this.text_changed = true;
this.runtime.redraw = true;
}
};
instanceProto.SetCharWidth = function(character,width) {
var w = parseInt(width,10);
if (this.characterWidthList[character] !== w) {
this.characterWidthList[character] = w;
this.text_changed = true;
this.runtime.redraw = true;
}
};
Acts.prototype.SetCharacterWidth = function(characterSet,width)
{
if (characterSet !== "") {
for(var c = 0; c < characterSet.length; c++) {
this.SetCharWidth(characterSet.charAt(c),width);
}
}
};
Acts.prototype.SetEffect = function (effect)
{
this.compositeOp = cr.effectToCompositeOp(effect);
cr.setGLBlend(this, effect, this.runtime.gl);
this.runtime.redraw = true;
};
pluginProto.acts = new Acts();
function Exps() {}
Exps.prototype.CharacterWidth = function(ret,character)
{
ret.set_int(this.getCharacterWidth(character));
};
Exps.prototype.CharacterHeight = function(ret)
{
ret.set_int(this.characterHeight);
};
Exps.prototype.CharacterScale = function(ret)
{
ret.set_float(this.characterScale);
};
Exps.prototype.CharacterSpacing = function(ret)
{
ret.set_int(this.characterSpacing);
};
Exps.prototype.LineHeight = function(ret)
{
ret.set_int(this.lineHeight);
};
Exps.prototype.Text = function(ret)
{
ret.set_string(this.text);
};
Exps.prototype.TextWidth = function (ret)
{
this.rebuildText();
ret.set_float(this.textWidth);
};
Exps.prototype.TextHeight = function (ret)
{
this.rebuildText();
ret.set_float(this.textHeight);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.SyncStorage = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.SyncStorage.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.data = {};
this.isStorageLoaded = false;
this.storageIndex = this.properties[1];
this.isEncodingEnabled = !this.properties[3];
this.headSalt = this.properties[4];
this.tailSalt = this.properties[5];
this.isLocalStorageLoaded = null;
this.LS_Instance = null;
this.LS_ProtoActions = null;
this.lastErrorMsg = null;
};
instanceProto.onDestroy = function ()
{
};
instanceProto.isLocalStorageReady = function()
{
if (this.isLocalStorageLoaded) return true;
if ( ! this.storageIndex) return false;
if(cr.plugins_.LocalStorage) // check if LocalStorage plugin is added to the project
{
var type, LS_Type;
for (type in this.runtime.types)
{
if ( ! this.runtime.types.hasOwnProperty(type)) continue;
if (this.runtime.types[type].plugin instanceof cr.plugins_.LocalStorage)
{
LS_Type = this.runtime.types[type];
break;
}
}
if (LS_Type)
{
this.LS_Instance = LS_Type.instances[0];
this.LS_ProtoActions = cr.plugins_.LocalStorage.prototype.acts;
return true;
}
}
console.log("\n*\n*\n*\nERROR: LocalStorage plugin not found. You must add LocalStorage plugin to the project. It's a JS library for SyncStorage plugin.\n*\n*\n*\n");
return false;
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnLoaded = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnLoadError = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.IsLoaded = function()
{
return this.isStorageLoaded;
};
/**
* @returns {boolean}
*/
Cnds.prototype.HasData = function(index_)
{
return this.hasData(index_);
};
/**
* @returns {boolean}
*/
Cnds.prototype.CompareData = function(dataIndex_, cmp_, value_)
{
return cr.do_cmp(this.data[dataIndex_], cmp_, value_);
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnSave = function()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnDataMissing = function()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetData = function(index_, value_)
{
this.data[index_] = value_;
};
Acts.prototype.SaveData = function()
{
if(this.isLocalStorageReady())
{
this.LS_ProtoActions.SetItem.call(this.LS_Instance, this.storageIndex,
this.isEncodingEnabled
? this.encode(JSON.stringify(this.data))
: JSON.stringify(this.data));
}
this.runtime.trigger(cr.plugins_.SyncStorage.prototype.cnds.OnSave, this);
};
Acts.prototype.LoadData = function()
{
if( ! this.isLocalStorageReady())
{
this.lastErrorMsg = "Could not load data from LocalStorage. Possible reasons: \"LocalStorage IDX\" property not set or LocalStorage plugin is not added to the project.";
this.runtime.trigger(cr.plugins_.SyncStorage.prototype.cnds.OnLoadError, this);
this.lastErrorMsg = "";
return;
}
var self = this;
localforage["getItem"](this.storageIndex, function (err, value)
{
if (err)
{
if ( ! err)
err = "unknown error";
else if (typeof err.message === "string")
err = err.message;
else if (typeof err.name === "string")
err = err.name;
else if (typeof err.data === "string")
err = err.data;
else if (typeof err !== "string")
err = "unknown error";
self.isStorageLoaded = false;
self.lastErrorMsg = err;
self.runtime.trigger(cr.plugins_.SyncStorage.prototype.cnds.OnLoadError, self);
self.lastErrorMsg = null;
}
else
{
if (typeof value === "undefined" || value === null || value === "")
{
self.data = {};
self.runtime.trigger(cr.plugins_.SyncStorage.prototype.cnds.OnDataMissing, self);
}
else
{
if(self.isEncodingEnabled)
{
try
{
self.data = JSON.parse(self.decode(value));
}
catch (e)
{
self.data = JSON.parse(value);
}
}
else
{
try
{
self.data = JSON.parse(value);
}
catch (e)
{
self.data = JSON.parse(self.decode(value));
}
}
}
self.isStorageLoaded = true;
self.runtime.trigger(cr.plugins_.SyncStorage.prototype.cnds.OnLoaded, self);
}
});
};
Acts.prototype.ClearData = function()
{
this.data = {};
};
Acts.prototype.RemoveData = function(index_)
{
if(typeof this.data[index_] !== "undefined")
{
delete this.data[index_];
}
};
Acts.prototype.LoadString = function(data_)
{
try
{
if(data_ == "")
{
this.data = {};
this.runtime.trigger(cr.plugins_.SyncStorage.prototype.cnds.OnDataMissing, this);
}
else
{
if(data_.charAt(0) === "{")
{
this.data = JSON.parse(data_);
}
else
{
this.data = JSON.parse(this.decode(data_));
}
}
this.runtime.trigger(cr.plugins_.SyncStorage.prototype.cnds.OnLoaded, this);
}
catch(e)
{
this.lastErrorMsg = e.message;
this.runtime.trigger(cr.plugins_.SyncStorage.prototype.cnds.OnLoadError, this);
this.lastErrorMsg = "";
}
};
Acts.prototype.AddValue = function(index_, value_)
{
if ( ! this.hasData(index_))
{
this.data[index_] = 0;
}
if ( ! isNaN(parseFloat(value_)) && isFinite(value_))
{
this.data[index_] += value_;
}
};
Acts.prototype.SubtractValue = function(index_, value_)
{
if ( ! this.hasData(index_))
{
this.data[index_] = 0;
}
if ( ! isNaN(parseFloat(value_)) && isFinite(value_))
{
this.data[index_] -= value_;
}
};
Acts.prototype.AppendValue = function(index_, value_)
{
if ( ! this.hasData(index_))
{
this.data[index_] = "";
}
if (typeof value_ === "string")
{
this.data[index_] += value_;
}
};
Acts.prototype.PrependValue = function(index_, value_)
{
if ( ! this.hasData(index_))
{
this.data[index_] = "";
}
if (typeof value_ === "string")
{
this.data[index_] = value_ + this.data[index_];
}
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.GetData = function(ret, dataIndex_)
{
ret.set_any(this.data[dataIndex_]);
};
Exps.prototype.StorageIndex = function(ret)
{
ret.set_string(this.storageIndex);
};
Exps.prototype.HasData = function(ret, index_)
{
ret.set_int(+this.hasData(index_));
};
Exps.prototype.AsJSON = function(ret)
{
ret.set_string(JSON.stringify(this.data));
};
Exps.prototype.AsString = function(ret)
{
ret.set_string(this.isEncodingEnabled
? this.encode(JSON.stringify(this.data))
: JSON.stringify(this.data));
};
Exps.prototype.ErrorMsg = function(ret)
{
ret.set_string(this.lastErrorMsg);
};
Exps.prototype.Get = function(ret, dataIndex_)
{
ret.set_any(this.data[dataIndex_]);
};
Exps.prototype.Has = function(ret, index_)
{
ret.set_int(+this.hasData(index_));
};
instanceProto.encode = function (rawData)
{
var encodedData = Secret.encode(rawData);
var i;
for (i = 0; i < this.headSalt; i++)
{
encodedData = encodedData.charAt(Math.floor((Math.random() * (encodedData.length-1)))) + encodedData;
}
for (i = 0; i < this.tailSalt; i++)
{
encodedData += encodedData.charAt(Math.floor((Math.random() * (encodedData.length-1))));
}
return encodedData;
};
instanceProto.decode = function (encodedData)
{
var rawData = encodedData.substring(this.headSalt);
rawData = rawData.substring(0, rawData.length - this.tailSalt);
rawData = Secret.decode(rawData);
return rawData;
};
instanceProto.hasData = function(index_)
{
return typeof this.data[index_] !== 'undefined';
};
pluginProto.exps = new Exps();
var Secret={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(r){var t,e,o,a,h,n,d,C="",i=0;for(r=Secret._utf8_encode(r);i<r.length;)a=(t=r.charCodeAt(i++))>>2,h=(3&t)<<4|(e=r.charCodeAt(i++))>>4,n=(15&e)<<2|(o=r.charCodeAt(i++))>>6,d=63&o,isNaN(e)?n=d=64:isNaN(o)&&(d=64),C=C+this._keyStr.charAt(a)+this._keyStr.charAt(h)+this._keyStr.charAt(n)+this._keyStr.charAt(d);return C},decode:function(r){var t,e,o,a,h,n,d="",C=0;for(r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");C<r.length;)t=this._keyStr.indexOf(r.charAt(C++))<<2|(a=this._keyStr.indexOf(r.charAt(C++)))>>4,e=(15&a)<<4|(h=this._keyStr.indexOf(r.charAt(C++)))>>2,o=(3&h)<<6|(n=this._keyStr.indexOf(r.charAt(C++))),d+=String.fromCharCode(t),64!=h&&(d+=String.fromCharCode(e)),64!=n&&(d+=String.fromCharCode(o));return d=Secret._utf8_decode(d)},_utf8_encode:function(r){r=r.replace(/\r\n/g,"\n");for(var t="",e=0;e<r.length;e++){var o=r.charCodeAt(e);o<128?t+=String.fromCharCode(o):o>127&&o<2048?(t+=String.fromCharCode(o>>6|192),t+=String.fromCharCode(63&o|128)):(t+=String.fromCharCode(o>>12|224),t+=String.fromCharCode(o>>6&63|128),t+=String.fromCharCode(63&o|128))}return t},_utf8_decode:function(r){for(var t="",e=0,o=0,a=0,h=0;e<r.length;)(o=r.charCodeAt(e))<128?(t+=String.fromCharCode(o),e++):o>191&&o<224?(a=r.charCodeAt(e+1),t+=String.fromCharCode((31&o)<<6|63&a),e+=2):(a=r.charCodeAt(e+1),h=r.charCodeAt(e+2),t+=String.fromCharCode((15&o)<<12|(63&a)<<6|63&h),e+=3);return t}};
}());
;
;
cr.plugins_.TR_ClockParser = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.TR_ClockParser.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
};
instanceProto.onDestroy = function ()
{
};
function Cnds() {};
pluginProto.cnds = new Cnds();
function Acts() {};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.Minimal = function(ret, seconds_)
{
seconds_ = parseInt(seconds_, 10);
var hours = Math.floor(seconds_ / 3600);
var minutes = Math.floor((seconds_ - (hours * 3600)) / 60);
var seconds = seconds_ - (hours * 3600) - (minutes * 60);
var clockString = "";
if(hours > 0)
{
clockString += (hours < 10 ? "0" + hours : hours) + ":";
}
if(hours > 0 || minutes > 0)
{
clockString += (minutes < 10 ? "0" + minutes : minutes) + ":";
}
clockString += (seconds < 10 ? "0" + seconds : seconds);
ret.set_string(clockString);
};
Exps.prototype.MMSS = function(ret, seconds_)
{
seconds_ = parseInt(seconds_, 10);
var minutes = Math.floor(seconds_ / 60);
var seconds = seconds_ - minutes * 60;
if (minutes < 10) { minutes = "0" +minutes; }
if (seconds < 10) { seconds = "0" + seconds; }
ret.set_string(minutes + ':' + seconds);
};
Exps.prototype.HHMMSS = function(ret, seconds_)
{
seconds_ = parseInt(seconds_, 10);
var hours = Math.floor(seconds_ / 3600);
var minutes = Math.floor((seconds_ - (hours * 3600)) / 60);
var seconds = seconds_ - (hours * 3600) - (minutes * 60);
if (hours < 10) { hours = "0" + hours; }
if (minutes < 10) { minutes = "0" +minutes; }
if (seconds < 10) { seconds = "0" + seconds; }
ret.set_string(hours + ':' + minutes + ':' + seconds);
};
Exps.prototype.ToSeconds = function(ret, clockString_)
{
var a = clockString_.split(':');
var hours = +(a.length === 3 ? a[0] : 0);
var minutes = +(a.length === 3 ? a[1] : (a.length === 2 ? a[0] : 0));
var seconds = +(a.length === 3 ? a[2] : (a.length === 2 ? a[1] : (a.length === 1 ? a[0] : 0)));
seconds = hours * 3600 + minutes * 60 + seconds;
ret.set_int(seconds);
};
pluginProto.exps = new Exps();
}());
window['tr_cp_cfg_data'] = null;
window['nsgSmartRedirect'] = function(url_)
{
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
var a = document.createElement('a');
var linkText = document.createTextNode(url_);
a.appendChild(linkText);
a.id="externallink";
a.style="display: none";
a.href = url_;
if(inIframe())
{
a.target = "_blank";
}
document.body.appendChild(a);
$('#externallink')[0].click();
};
;
;
cr.plugins_.TR_CrossPromo = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.TR_CrossPromo.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4) {
if (xmlhttp.status === 200)
{
window['tr_cp_cfg_data'] = JSON.parse(xmlhttp.responseText || '{}');
}
else
{
window['tr_cp_cfg_data'] = {};
}
}
};
var platform = 'web';
if (typeof window["FBInstant"] !== 'undefined')
{
platform = 'fig';
}
else
if (this.runtime.isAndroid)
{
platform = 'android';
}
else
if (this.runtime.isiOS)
{
platform = 'ios';
}
xmlhttp.open("GET",
"https://tools.nightsteed.com/tr_cr/get_data3.php?r=" + Math.floor(Math.random() * 100000)
+ "&token=nnaQesObz9UnXxAZtV68&source=" + document.referrer
+ "&source_game=" + this.properties[0]
+ "&platform=" + platform, true);
xmlhttp.send();
this.currentGame = "";
this.currentlyLoading = "";
if(window['tr_cp_cfg_data'])
{
this.serverData = window['tr_cp_cfg_data'];
}
else
{
var self = this;
var checking = setInterval(function () {
if(window['tr_cp_cfg_data'])
{
self.serverData = window['tr_cp_cfg_data'];
clearInterval(checking);
}
}, 10);
}
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnBannerReady = function ()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.PickRandomBanner = function ()
{
if( ! this.serverData || typeof this.serverData['draw'] === 'undefined' || this.serverData['draw'].length === 0)
{
this.currentGame = '';
return;
}
var RND = Math.floor(Math.random() * 100);
var i, len = this.serverData['draw'].length;
for (i = len - 1; i >= 0; --i)
{
if (this.serverData['draw'][i]['draw_value'] <= RND)
{
this.currentlyLoading = this.serverData['draw'][i]['game_name'];
break;
}
}
if (this.currentGame !== this.currentlyLoading)
{
if (this.serverData['games'][this.currentlyLoading]['img'].substring(0, 4) !== 'http')
{
this.currentGame = this.currentlyLoading;
this.currentlyLoading = "";
this.runtime.trigger(cr.plugins_.TR_CrossPromo.prototype.cnds.OnBannerReady, this);
return;
}
this.loadCPImage(this.serverData['games'][this.currentlyLoading]['img']);
}
};
Acts.prototype.SmartRedirect = function (url_)
{
window['nsgSmartRedirect'](url_);
};
pluginProto.acts = new Acts();
instanceProto.loadCPImage = function(url_)
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4) {
if (xmlhttp.status === 200)
{
window['tr_cp_get_image'] = xmlhttp.responseText;
}
else
{
console.log('ajax err when loading image 64 txt');
}
}
};
xmlhttp.open("GET", url_ + "?r=" + Math.floor(Math.random() * 100000), true);
xmlhttp.send();
var self = this;
var checking2 = setInterval(function () {
if(window['tr_cp_get_image'])
{
self.serverData['games'][self.currentlyLoading]['img'] = window['tr_cp_get_image'];
window['tr_cp_get_image'] = null;
self.currentGame = self.currentlyLoading;
self.currentlyLoading = "";
self.runtime.trigger(cr.plugins_.TR_CrossPromo.prototype.cnds.OnBannerReady, self);
clearInterval(checking2);
}
}, 10);
};
function Exps() {};
Exps.prototype.MoreGamesURL = function (ret)
{
var url = document.createElement('a');
url.href = document.referrer;
var moreGamesURL = url.protocol + '//' + url.hostname;
if(this.serverData && typeof this.serverData['mg'] !== 'undefined' && this.serverData['mg'].trim() !== '')
{
moreGamesURL = this.serverData['mg'];
}
ret.set_string(moreGamesURL);
};
Exps.prototype.CurrentBannerURL = function (ret)
{
var currentBannerUrl = '';
if(this.serverData
&& typeof this.serverData['games'] !== 'undefined'
&& typeof this.serverData['games'][this.currentGame] !== 'undefined'
&& typeof this.serverData['games'][this.currentGame]['url'] !== 'undefined')
{
currentBannerUrl = this.serverData['games'][this.currentGame]['url'];
}
ret.set_any(currentBannerUrl);
};
Exps.prototype.CurrentBannerIMG = function (ret)
{
ret.set_string(this.serverData['games'][this.currentGame]['img']);
};
Exps.prototype.CurrentBannerLabel = function (ret)
{
ret.set_string(this.serverData['games'][this.currentGame]['label']);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.TR_DateTime = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.TR_DateTime.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.timers = [];
this.currentTimerTag = "";
};
instanceProto.onDestroy = function ()
{
};
instanceProto.setTimer = function(tag_, interval_, repeats_, data_, triggerCounter_)
{
this.timers[tag_] = {
isReady: false,
interval: interval_,
repeatsLeft: repeats_,
data: data_ || "",
triggerCounter: triggerCounter_ || 0,
startTime: (new Date()).getTime(),
id: null
};
var self = this;
this.timers[tag_].id = setTimeout(function()
{
self.timers[tag_].isReady = true;
self.timers[tag_].isOriginal = true;
--self.timers[tag_].repeatsLeft;
++self.timers[tag_].triggerCounter;
self.currentTimerTag = tag_;
self.runtime.trigger(cr.plugins_.TR_DateTime.prototype.cnds.OnTimer, self);
self.runtime.trigger(cr.plugins_.TR_DateTime.prototype.cnds.OnAnyTimer, self);
if ( ! self.timers[tag_] ) return; // timer can be cancelled in OnTimer condition
if ( ! self.timers[tag_].isOriginal) return; // isOriginal does not exist if tag was overriden in "OnTimer" events
if(self.timers[tag_].repeatsLeft <= 0)
{
self.timers[tag_] = null;
}
else
{
self.setTimer(tag_, interval_, self.timers[tag_].repeatsLeft, self.timers[tag_].data, self.timers[tag_].triggerCounter);
}
}
, this.timers[tag_].interval * 1000);
this.runtime.trigger(cr.plugins_.TR_DateTime.prototype.cnds.OnTimerStarted, this);
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnTimestamp = function(timestamp)
{
var cnd = this.runtime.getCurrentCondition();
if (typeof cnd.extra["OnTimestamp_tickSkipsLeft"] === "undefined")
{
cnd.extra["OnTimestamp_tickSkipsLeft"] = 0;
cnd.extra["OnTimestamp_isOff"] = false;
}
if(cnd.extra["OnTimestamp_isOff"] === true) return false;
if(cnd.extra["OnTimestamp_tickSkipsLeft"] === 0)
{
var timestampDiff = timestamp - ((new Date()).getTime() / 1000|0);
if(timestampDiff === 0)
{
cnd.extra["OnTimestamp_isOff"] = true;
return true;
}
if(timestampDiff < 0)
{
cnd.extra["OnTimestamp_isOff"] = true;
return false;
}
if(timestampDiff > 1)
{
cnd.extra["OnTimestamp_tickSkipsLeft"] = Math.floor(timestampDiff * this.runtime.fps / 2);
}
else
{
cnd.extra["OnTimestamp_tickSkipsLeft"] = Math.floor(this.runtime.fps / 10);
}
return false;
}
else
{
--cnd.extra["OnTimestamp_tickSkipsLeft"];
return false;
}
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnTimer = function(tag)
{
if(typeof this.timers[tag] !== 'undefined' && this.timers[tag] !== null && this.currentTimerTag === tag)
{
return true;
}
};
/**
* @returns {boolean}
*/
Cnds.prototype.IsActive = function(tag)
{
return (typeof this.timers[tag] !== 'undefined' && this.timers[tag] !== null)
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnAnyTimer = function()
{
return true;
};
Cnds.prototype.OnTimerStarted = function(tag)
{
if(typeof this.timers[tag] !== 'undefined' && this.timers[tag] !== null)
{
return true;
}
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.StartTimer = function(tag, interval, repeats)
{
if(typeof this.timers[tag] !== 'undefined' && this.timers[tag] !== null)
{
clearTimeout(this.timers[tag].id);
this.timers[tag] = null;
}
this.setTimer(tag, interval, repeats);
};
Acts.prototype.StartDataTimer = function(tag, interval, repeats, data_)
{
if(typeof this.timers[tag] !== 'undefined' && this.timers[tag] !== null)
{
clearTimeout(this.timers[tag].id);
this.timers[tag] = null;
}
this.setTimer(tag, interval, repeats, data_);
};
Acts.prototype.StopTimer = function(tag)
{
if(typeof this.timers[tag] !== 'undefined' && this.timers[tag] !== null)
{
clearTimeout(this.timers[tag].id);
this.timers[tag] = null;
}
};
Acts.prototype.StopAllTimers = function()
{
for(var tag in this.timers)
{
if(this.timers.hasOwnProperty(tag) && typeof this.timers[tag] !== 'undefined' && this.timers[tag] !== null)
{
clearTimeout(this.timers[tag].id);
this.timers[tag] = null;
}
}
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.Timestamp = function(ret)
{
ret.set_int((new Date()).getTime() / 1000|0);
};
Exps.prototype.FullTimestamp = function(ret)
{
ret.set_int((new Date()).getTime());
};
Exps.prototype.Date = function(ret, format_, offset_)
{
var now = offset_ === 0 ? (new Date()) : (new Date((new Date()).getTime() + offset_ * 3600000));
format_ = format_
.replace(/yy/g, now.getUTCFullYear())
.replace(/y/g, now.getUTCFullYear().toString().slice(-2))
.replace(/mm/g, ("0" + (now.getUTCMonth() + 1)).slice(-2))
.replace(/m/g, (now.getUTCMonth() + 1))
.replace(/dd/g, ("0" + now.getUTCDate()).slice(-2))
.replace(/d/g, now.getUTCDate())
.replace(/hh/g, ("0" + now.getUTCHours()).slice(-2))
.replace(/h/g, now.getUTCHours())
.replace(/ii/g, ("0" + now.getUTCMinutes()).slice(-2))
.replace(/i/g, now.getUTCMinutes())
.replace(/ss/g, ("0" + now.getUTCSeconds()).slice(-2))
.replace(/s/g, now.getUTCSeconds())
.replace(/u/g, now.getUTCMilliseconds());
ret.set_string(format_);
};
Exps.prototype.TimerTimeLeft = function (ret, tag_, secondsFormat_)
{
if(typeof this.timers[tag_] === 'undefined' || ! this.timers[tag_])
{
ret.set_int(-1);
return;
}
var timeDiff = (new Date()).getTime() - this.timers[tag_].startTime;
var remainingTime = this.timers[tag_].interval * 1000 - timeDiff;
ret.set_int(secondsFormat_ === 0 ? remainingTime : remainingTime / 1000|0);
};
Exps.prototype.TimerAge = function (ret, tag_, secondsFormat_)
{
if(typeof this.timers[tag_] === 'undefined' || ! this.timers[tag_])
{
ret.set_int(-1);
return;
}
var timeDiff = (new Date()).getTime() - this.timers[tag_].startTime;
ret.set_int(secondsFormat_ === 0 ? timeDiff : timeDiff / 1000|0);
};
Exps.prototype.TriggerAge = function (ret, tag_)
{
if(typeof this.timers[tag_] === 'undefined' || ! this.timers[tag_])
{
ret.set_int(-1);
return;
}
ret.set_int(this.timers[tag_].triggerCounter);
};
Exps.prototype.TriggersLeft = function (ret, tag_)
{
if(typeof this.timers[tag_] === 'undefined' || ! this.timers[tag_])
{
ret.set_int(-1);
return;
}
ret.set_int(this.timers[tag_].repeatsLeft);
};
Exps.prototype.Data = function (ret, tag_)
{
if(typeof this.timers[tag_] === 'undefined' || ! this.timers[tag_])
{
ret.set_int(-1);
return;
}
ret.set_any(this.timers[tag_].data);
};
Exps.prototype.Tag = function (ret)
{
ret.set_string(this.currentTimerTag);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.TR_HtmlText = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.TR_HtmlText.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.draw = function(ctx) {};
instanceProto.drawGL = function(glw) {};
instanceProto.tick2 = function ()
{
this.updatePosition();
};
instanceProto.onCreate = function()
{
this.elem = document.createElement("div");
this.elem.innerHTML = this.properties[0];
this.text = this.properties[0];
this.text_changed = false;
this.elem.id = this.properties[10] || this.makeID();
this.elem.class = this.properties[11];
this.elem.setAttribute("id", this.elem.id);
if (this.elem.class)
this.elem.setAttribute("class", this.elem.class);
this.elem.style.fontSize = this.properties[1] + 'em';
if (this.properties[5])
this.elem.setAttribute("title", this.properties[5]);
if (this.properties[2])
$(this.elem).css("font-family", this.properties[2]);
this.elem.style.background = this.properties[4];
this.elem.style.border = this.properties[6];
this.elem.style.color = this.properties[3];
this.elem.style.width = this.width + "px";
this.elem.style.height = this.height + "px";
if( ! this.properties[8])
{
$(this.elem).css("user-select", "none");
$(this.elem).css("cursor", "default");
}
switch (this.properties[7])
{
case 0:
this.elem.setAttribute("scrolling", "no");
this.elem.style.overflow = "hidden";
break;
case 1:
this.elem.style.overflow = "auto";
break;
case 2:
this.elem.style.overflowX = "auto";
this.elem.style.overflowY = "hidden";
break;
case 3:
this.elem.style.overflowX = "hidden";
this.elem.style.overflowY = "auto";
break;
}
switch (this.properties[9])
{
case 0:
this.elem.style.textAlign = "center";
break;
case 1:
this.elem.style.textAlign = "left";
break;
case 2:
this.elem.style.textAlign = "right";
break;
}
$(this.elem).appendTo(this.runtime.canvasdiv ? this.runtime.canvasdiv : "body");
this.updatePosition(true);
this.fixesLeft = 10;
this.runtime.tick2Me(this);
};
instanceProto.getScale = function()
{
var widthScale = $(window).width() / this.runtime.original_width;
var heightScale = $(window).height() / this.runtime.original_height;
return Math.min(widthScale, heightScale);
};
instanceProto.makeID = function()
{
return "tr_html_text_" + this.uid;
};
instanceProto.updatePosition = function (forceUpdate)
{
if (!this.visible || !this.layer.visible)
{
if (!this.element_hidden)
{
this.originalDisplay = this.elem.style.display;
this.elem.style.display = 'none';
}
this.element_hidden = true;
return;
}
if (this.runtime.isDomFree)
return;
if(this.text_changed === true)
{
this.elem.innerHTML = this.text;
this.text_changed = false;
}
var divX = this.x - this.width * 0.5;
var divY = this.y - this.height * 0.5;
var left = this.layer.layerToCanvas(divX, divY, true);
var top = this.layer.layerToCanvas(divX , divY, false);
var right = this.layer.layerToCanvas(divX + this.width, divY + this.height, true);
var bottom = this.layer.layerToCanvas(divX + this.width, divY + this.height, false);
var rightEdge = this.runtime.width / this.runtime.devicePixelRatio;
var bottomEdge = this.runtime.height / this.runtime.devicePixelRatio;
var curScale = this.getScale();
if (right <= 0 || bottom <= 0 || left >= rightEdge || top >= bottomEdge)
{
if (!this.element_hidden)
{
this.originalDisplay = this.elem.style.display;
this.elem.style.display = 'none';
}
this.element_hidden = true;
return;
}
if (this.element_hidden)
{
this.elem.style.display = this.originalDisplay;
this.element_hidden = false;
}
if (left < 1)
left = 1;
if (top < 1)
top = 1;
if (right >= rightEdge)
right = rightEdge - 1;
if (bottom >= bottomEdge)
bottom = bottomEdge - 1;
var curWinWidth = window.innerWidth;
var curWinHeight = window.innerHeight;
if (this.lastScale === curScale && this.lastLeft === left && this.lastTop === top && this.lastRight === right && this.lastBottom === bottom && this.lastWinWidth === curWinWidth && this.lastWinHeight === curWinHeight)
{
/*if (this.element_hidden)
{
this.popupDiv.style = '';
this.element_hidden = false;
}*/
--this.fixesLeft;
if (this.fixesLeft < 0) return;
}
else
{
this.fixesLeft = 10;
}
this.elem.style.width = this.width + "px";
this.elem.style.height = this.height + "px";
this.lastScale = curScale;
this.lastLeft = left;
this.lastTop = top;
this.lastRight = right;
this.lastBottom = bottom;
this.lastWinWidth = curWinWidth;
this.lastWinHeight = curWinHeight;
var rect = this.runtime.canvas.getBoundingClientRect();
var offx = Math.round(left) + rect.left + document.body.scrollLeft;
var offy = Math.round(top) + rect.top + document.body.scrollTop;
this.elem.style.position = "absolute";
jQuery(this.elem).offset({left: offx, top: offy});
this.elem.style.transform = 'scale(' + this.getScale() + ')';
};
instanceProto.onDestroy = function ()
{
if (this.runtime.isDomFree)
return;
this.elem.parentNode.removeChild(this.elem);
this.elem = null;
};
function Cnds() {};
/*// the example condition
Cnds.prototype.MyCondition = function (myparam)
{
return myparam >= 0;
};*/
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.AddNewFamily = function (familyName_, url_)
{
var style = document.createElement("style");
style.appendChild(document.createTextNode(""));
document.head.appendChild(style);
style.sheet.insertRule("@font-face { font-family: " + familyName_ + "; src: url('" + url_ + "'); }", 0);
};
Acts.prototype.SetText = function (newText_)
{
this.text = newText_;
this.elem.innerHTML = newText_;
};
Acts.prototype.SetTextSize = function (newSize_)
{
this.elem.style.fontSize = newSize_ + 'em';
};
Acts.prototype.SetTextColor = function (newColor_)
{
this.elem.style.color = newColor_;
};
Acts.prototype.SetCSSClass = function (newClass_)
{
this.elem.setAttribute("class", newClass_);
};
Acts.prototype.SetHorizontalAlignment = function (alignmentIdx_)
{
var newAlignment;
switch (alignmentIdx_)
{
case 0: newAlignment = "left"; break;
case 1: newAlignment = "center"; break;
case 2: newAlignment = "right"; break;
}
this.elem.style.textAlign = newAlignment;
};
pluginProto.acts = new Acts();
function Exps() {};
/*Exps.prototype.MyExpression = function (ret) // 'ret' must always be the first parameter - always return the expression's result through it!
{
ret.set_int(1337); // return our value
};*/
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.TR_Leaderboard = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.TR_Leaderboard.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
this.sortType =
{
DESC: 0,
ASC: 1
};
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
/*this.leaderboardByUsers = {};
this.leaderboardByScore = [];
this.textInstances = [];
this.requiredUsers = [];
this.drawnUsers = [];
this.x = 0;
this.y = 0;
this.layer = null;
this.columnSetup =
{
position: { font: null, width: 0 },
name: { font: null, width: 0 },
score: { font: null, width: 0 }
};
this.hasNewData = false;*/
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.sortType = this.properties[0];
this.topEntriesQty = this.properties[1];
this.verticalMargin = this.properties[2];
this.allowLowerScore = this.properties[3];
this.leaderboardByUsers = {};
this.leaderboardByScore = [];
this.textInstances = [];
this.requiredUsers = [];
this.drawnUsers = [];
this.x = 0;
this.y = 0;
this.layer = null;
this.columnSetup =
{
position: { font: null, width: 0 },
name: { font: null, width: 0 },
score: { font: null, width: 0 }
};
this.hasNewData = false;
/*if (this.type.isFirstInit)
{
this.type.isFirstInit = false;
this.runtime.DestroyInstance(this);
}*/
};
instanceProto.onDestroy = function ()
{
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnChange = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.HasNewData = function ()
{
return this.hasNewData;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetPositionColumn = function (font_, columnWidth_)
{
this.columnSetup.position.font = font_;
this.columnSetup.position.width = columnWidth_;
};
Acts.prototype.SetNameColumn = function (font_, columnWidth_)
{
this.columnSetup.name.font = font_;
this.columnSetup.name.width = columnWidth_;
};
Acts.prototype.SetScoreColumn = function (font_, columnWidth_)
{
this.columnSetup.score.font = font_;
this.columnSetup.score.width = columnWidth_;
};
Acts.prototype.SetEntry = function (playerId_, name_, score_)
{
playerId_ = playerId_.toLowerCase();
score_ = parseInt(score_);
if (typeof this.leaderboardByUsers[playerId_] === 'undefined')
{
this.leaderboardByUsers[playerId_] =
{
playerId: playerId_,
index: this.leaderboardByScore.length
};
this.leaderboardByScore.push(this.leaderboardByUsers[playerId_]);
}
if ((this.sortType === this.type.sortType.DESC && this.leaderboardByUsers[playerId_].score >= score_) // TODO score can now be lower
|| (this.sortType === this.type.sortType.ASC && this.leaderboardByUsers[playerId_].score <= score_))
{
if(!this.allowLowerScore){
return;
}
var checkJumpSize = Math.ceil(this.leaderboardByScore.length * 0.1);
var i, startIndex = null;
for (i = this.leaderboardByUsers[playerId_].index + 1; i >= 0; ++i) // TODO or + checkJumpSize
{
if (typeof this.leaderboardByScore[i] === 'undefined'
|| (this.sortType === this.type.sortType.DESC && this.leaderboardByScore[i].score < score_)
|| (this.sortType === this.type.sortType.ASC && this.leaderboardByScore[i].score > score_))
{
startIndex = i;
break;
}
}
var shuffleStartIndex = this.leaderboardByUsers[playerId_].index;
this.leaderboardByUsers[playerId_].index = startIndex - 1;
for (i = shuffleStartIndex; i >= 0; ++i)
{
if (i === this.leaderboardByUsers[playerId_].index)
{
this.leaderboardByScore[i] = this.leaderboardByUsers[playerId_];
break;
}
else
if (this.leaderboardByScore[i + 1])
{
this.leaderboardByScore[i] = this.leaderboardByScore[i + 1];
this.leaderboardByScore[i].index = i;
}
}
this.leaderboardByUsers[playerId_].name = name_;
this.leaderboardByUsers[playerId_].score = score_;
this.hasNewData = true;
return;
}
this.leaderboardByUsers[playerId_].name = name_;
this.leaderboardByUsers[playerId_].score = score_;
var scoreOfPlayerAbove = this.leaderboardByScore[this.leaderboardByUsers[playerId_].index - 1]; // TODO check player below if new score is lower than earlier score
var scoreOfPlayerBelow = this.leaderboardByScore[this.leaderboardByUsers[playerId_].index + 1];
if ( ! scoreOfPlayerAbove
|| ((this.sortType === this.type.sortType.DESC && scoreOfPlayerAbove.score >= score_)
|| (this.sortType === this.type.sortType.ASC && scoreOfPlayerAbove.score <= score_)))
{
if (this.requiredUsers.indexOf(playerId_) !== -1 || this.topEntriesQty > this.leaderboardByUsers[playerId_].index)
{
this.hasNewData = true;
}
return;
}
var checkJumpSize = Math.ceil(this.leaderboardByScore.length * 0.1);
var i, startIndex = null;
for (i = this.leaderboardByUsers[playerId_].index - checkJumpSize; i >= 0; i -= checkJumpSize) // TODO or + checkJumpSize
{
if ((this.sortType === this.type.sortType.DESC && this.leaderboardByScore[i].score > score_)
|| (this.sortType === this.type.sortType.ASC && this.leaderboardByScore[i].score < score_))
{
startIndex = i;
break;
}
}
if (startIndex === null)
{
startIndex = 0;
}
var entryIndex = 0, len = this.leaderboardByScore.length;
for (i = startIndex; i < len; ++i) // TODO...
{
if (this.leaderboardByScore[i]
&& ((this.sortType === this.type.sortType.DESC && this.leaderboardByScore[i].score < score_)
|| (this.sortType === this.type.sortType.ASC && this.leaderboardByScore[i].score > score_)))
{
entryIndex = i;
break;
}
}
var shuffleStartIndex = this.leaderboardByUsers[playerId_].index;
this.leaderboardByUsers[playerId_].index = entryIndex;
for (i = shuffleStartIndex; i >= 0; --i)
{
if (i === this.leaderboardByUsers[playerId_].index)
{
this.leaderboardByScore[i] = this.leaderboardByUsers[playerId_];
break;
}
else
if (this.leaderboardByScore[i - 1])
{
this.leaderboardByScore[i] = this.leaderboardByScore[i - 1];
this.leaderboardByScore[i].index = i;
}
}
this.hasNewData = true;
};
Acts.prototype.RemoveEntry = function (playerId_)
{
playerId_ = playerId_.toLowerCase();
if ( ! this.leaderboardByUsers[playerId_]) return;
var i, len = this.leaderboardByScore.length;
var shuffleStartIndex = this.leaderboardByUsers[playerId_].index;
for (i = shuffleStartIndex; i < len; ++i)
{
if (this.leaderboardByScore[i + 1])
{
this.leaderboardByScore[i] = this.leaderboardByScore[i + 1];
this.leaderboardByScore[i].index = i;
}
}
this.leaderboardByScore.pop();
delete this.leaderboardByUsers[playerId_];
if (this.requiredUsers.indexOf(playerId_) !== -1)
{
this.requiredUsers.splice(this.requiredUsers.indexOf(playerId_), 1);
}
this.hasNewData = true;
};
Acts.prototype.ClearLeaderboard = function ()
{
this.leaderboardByScore = [];
this.leaderboardByUsers = {};
this.requiredUsers = [];
this.drawnUsers = [];
this.destroyFontFrom(0);
};
Acts.prototype.ClearDestroy = function ()
{
this.leaderboardByScore = [];
this.leaderboardByUsers = {};
this.requiredUsers = [];
this.drawnUsers = [];
this.destroyFontFrom(0);
this.runtime.DestroyInstance(this);
};
Acts.prototype.SetRequired = function (playerId_)
{
playerId_ = playerId_.toLowerCase();
if (this.requiredUsers.indexOf(playerId_) === -1)
{
this.requiredUsers.push(playerId_);
}
};
Acts.prototype.SetPosition = function (x_, y_, layer_)
{
this.x = x_;
this.y = y_;
this.layer = layer_;
};
Acts.prototype.DrawLeaderboard = function ()
{
if (this.layer === null) return;
if (this.columnSetup.position.font === null) return;
if (this.columnSetup.name.font === null) return;
if (this.columnSetup.score.font === null) return;
this.drawnUsers.length = 0;
var inst, i, len = Math.min(this.leaderboardByScore.length - this.requiredUsers.length, this.topEntriesQty - this.requiredUsers.length);
for (i = 0; i < len; ++i)
{
this.drawUser(i, i);
}
if (this.requiredUsers.length === 0)
{
this.destroyFontFrom(i);
this.hasNewData = false;
return;
}
var currentUser, j;
len = this.requiredUsers.length;
for (j = 0; j < len; ++j)
{
currentUser = this.leaderboardByUsers[this.requiredUsers[j]];
if ( ! currentUser) continue;
if (this.drawnUsers.indexOf(currentUser.playerId) !== -1)
{
this.drawUser(i, i);
}
else
{
var userIndex = currentUser.index;
this.drawUser(i, userIndex);
}
++i;
}
this.destroyFontFrom(i);
this.hasNewData = false;
};
instanceProto.drawUser = function(leaderboardIndex_, userIndex_)
{
var inst, i = leaderboardIndex_;
if (this.textInstances[i])
{
inst = this.textInstances[i].position;
inst.type.plugin.acts.SetText.call(inst, (userIndex_ + 1) + ".");
inst = this.textInstances[i].name;
inst.type.plugin.acts.SetText.call(inst, this.leaderboardByScore[userIndex_].name);
inst = this.textInstances[i].score;
inst.type.plugin.acts.SetText.call(inst, this.leaderboardByScore[userIndex_].score);
}
else
{
this.textInstances.push( { position: null, name: null, score: null} );
inst = this.runtime.createInstance(this.columnSetup.position.font, this.layer, this.x, this.y + i * this.verticalMargin);
inst.type.plugin.acts.SetWidth.call(inst, this.columnSetup.position.width);
inst.type.plugin.acts.SetText.call(inst, (userIndex_+1) + ".");
this.textInstances[i].position = inst;
this.runtime.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
inst = this.runtime.createInstance(this.columnSetup.name.font, this.layer, this.x + this.columnSetup.position.width, this.y + i * this.verticalMargin);
inst.type.plugin.acts.SetWidth.call(inst, this.columnSetup.name.width);
inst.type.plugin.acts.SetText.call(inst, this.leaderboardByScore[userIndex_].name);
this.textInstances[i].name = inst;
this.runtime.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
inst = this.runtime.createInstance(this.columnSetup.score.font, this.layer, this.x + this.columnSetup.name.width + this.columnSetup.position.width, this.y + i * this.verticalMargin);
inst.type.plugin.acts.SetWidth.call(inst, this.columnSetup.score.width);
inst.type.plugin.acts.SetText.call(inst, this.leaderboardByScore[userIndex_].score);
this.textInstances[i].score = inst;
this.runtime.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
}
this.drawnUsers.push(this.leaderboardByScore[userIndex_].playerId);
};
instanceProto.destroyFontFrom = function(index_)
{
var i, len = this.textInstances.length;
for (i = index_; i < len; ++i)
{
if ( ! this.textInstances[i]) continue;
this.runtime.DestroyInstance(this.textInstances[i].position);
this.runtime.DestroyInstance(this.textInstances[i].name);
this.runtime.DestroyInstance(this.textInstances[i].score);
}
this.textInstances.length = index_;
};
Acts.prototype.ImportFromJSON = function (json_)
{
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.AsJSON = function (ret)
{
ret.set_string("");
};
Exps.prototype.GetPosition = function (ret, playerId_)
{
playerId_ = playerId_.toLowerCase();
if ( ! this.leaderboardByUsers[playerId_])
{
ret.set_int(-1);
return;
}
var position = this.leaderboardByUsers[playerId_] ? this.leaderboardByUsers[playerId_].index + 1 : -1;
ret.set_int(position);
};
Exps.prototype.GetX = function (ret)
{
var x = this.textInstances[0] ? this.textInstances[0].position.x : -1;
ret.set_int(x);
};
Exps.prototype.GetY = function (ret, playerId_)
{
playerId_ = playerId_.toLowerCase();
if ( ! this.leaderboardByUsers[playerId_])
{
ret.set_int(-1);
return;
}
var position = this.drawnUsers.indexOf(playerId_);
if (position === -1)
{
ret.set_int(-1);
return;
}
position = this.textInstances[position].position.y;
ret.set_int(position);
};
Exps.prototype.GetScoreByPosition = function (ret, position_)
{
position_ = Math.round(position_);
if(position_ < 1 || position_ > this.leaderboardByScore.length)
{
ret.set_int(-1);
return;
}
var score = this.leaderboardByScore[position_ - 1].score;
ret.set_int(score);
};
Exps.prototype.GetIdByPosition = function (ret, position_)
{
position_ = Math.round(position_);
if(position_ < 1 || position_ > this.leaderboardByScore.length)
{
ret.set_string("-1");
return;
}
var playerId = this.leaderboardByScore[position_ - 1].playerId;
ret.set_string(playerId);
};
Exps.prototype.GetNameByPosition = function (ret, position_)
{
position_ = Math.round(position_);
if(position_ < 1 || position_ > this.leaderboardByScore.length)
{
ret.set_string("-1");
return;
}
var name = this.leaderboardByScore[position_ - 1].name;
ret.set_string(name);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.Text = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Text.prototype;
pluginProto.onCreate = function ()
{
pluginProto.acts.SetWidth = function (w)
{
if (this.width !== w)
{
this.width = w;
this.text_changed = true; // also recalculate text wrapping
this.set_bbox_changed();
}
};
};
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
typeProto.onLostWebGLContext = function ()
{
if (this.is_family)
return;
var i, len, inst;
for (i = 0, len = this.instances.length; i < len; i++)
{
inst = this.instances[i];
inst.mycanvas = null;
inst.myctx = null;
inst.mytex = null;
}
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
if (this.recycled)
cr.clearArray(this.lines);
else
this.lines = []; // for word wrapping
this.text_changed = true;
};
var instanceProto = pluginProto.Instance.prototype;
var requestedWebFonts = {}; // already requested web fonts have an entry here
instanceProto.onCreate = function()
{
this.text = this.properties[0];
this.visible = (this.properties[1] === 0); // 0=visible, 1=invisible
this.font = this.properties[2];
this.color = this.properties[3];
this.halign = this.properties[4]; // 0=left, 1=center, 2=right
this.valign = this.properties[5]; // 0=top, 1=center, 2=bottom
this.wrapbyword = (this.properties[7] === 0); // 0=word, 1=character
this.lastwidth = this.width;
this.lastwrapwidth = this.width;
this.lastheight = this.height;
this.line_height_offset = this.properties[8];
this.facename = "";
this.fontstyle = "";
this.ptSize = 0;
this.textWidth = 0;
this.textHeight = 0;
this.parseFont();
this.mycanvas = null;
this.myctx = null;
this.mytex = null;
this.need_text_redraw = false;
this.last_render_tick = this.runtime.tickcount;
if (this.recycled)
this.rcTex.set(0, 0, 1, 1);
else
this.rcTex = new cr.rect(0, 0, 1, 1);
if (this.runtime.glwrap)
this.runtime.tickMe(this);
;
};
instanceProto.parseFont = function ()
{
var arr = this.font.split(" ");
var i;
for (i = 0; i < arr.length; i++)
{
if (arr[i].substr(arr[i].length - 2, 2) === "pt")
{
this.ptSize = parseInt(arr[i].substr(0, arr[i].length - 2));
this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi...
if (i > 0)
this.fontstyle = arr[i - 1];
this.facename = arr[i + 1];
for (i = i + 2; i < arr.length; i++)
this.facename += " " + arr[i];
break;
}
}
};
instanceProto.saveToJSON = function ()
{
return {
"t": this.text,
"f": this.font,
"c": this.color,
"ha": this.halign,
"va": this.valign,
"wr": this.wrapbyword,
"lho": this.line_height_offset,
"fn": this.facename,
"fs": this.fontstyle,
"ps": this.ptSize,
"pxh": this.pxHeight,
"tw": this.textWidth,
"th": this.textHeight,
"lrt": this.last_render_tick
};
};
instanceProto.loadFromJSON = function (o)
{
this.text = o["t"];
this.font = o["f"];
this.color = o["c"];
this.halign = o["ha"];
this.valign = o["va"];
this.wrapbyword = o["wr"];
this.line_height_offset = o["lho"];
this.facename = o["fn"];
this.fontstyle = o["fs"];
this.ptSize = o["ps"];
this.pxHeight = o["pxh"];
this.textWidth = o["tw"];
this.textHeight = o["th"];
this.last_render_tick = o["lrt"];
this.text_changed = true;
this.lastwidth = this.width;
this.lastwrapwidth = this.width;
this.lastheight = this.height;
};
instanceProto.tick = function ()
{
if (this.runtime.glwrap && this.mytex && (this.runtime.tickcount - this.last_render_tick >= 300))
{
var layer = this.layer;
this.update_bbox();
var bbox = this.bbox;
if (bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom)
{
this.runtime.glwrap.deleteTexture(this.mytex);
this.mytex = null;
this.myctx = null;
this.mycanvas = null;
}
}
};
instanceProto.onDestroy = function ()
{
this.myctx = null;
this.mycanvas = null;
if (this.runtime.glwrap && this.mytex)
this.runtime.glwrap.deleteTexture(this.mytex);
this.mytex = null;
};
instanceProto.updateFont = function ()
{
this.font = this.fontstyle + " " + this.ptSize.toString() + "pt " + this.facename;
this.text_changed = true;
this.runtime.redraw = true;
};
instanceProto.draw = function(ctx, glmode)
{
ctx.font = this.font;
ctx.textBaseline = "top";
ctx.fillStyle = this.color;
ctx.globalAlpha = glmode ? 1 : this.opacity;
var myscale = 1;
if (glmode)
{
myscale = Math.abs(this.layer.getScale());
ctx.save();
ctx.scale(myscale, myscale);
}
if (this.text_changed || this.width !== this.lastwrapwidth)
{
this.type.plugin.WordWrap(this.text, this.lines, ctx, this.width, this.wrapbyword);
this.text_changed = false;
this.lastwrapwidth = this.width;
}
this.update_bbox();
var penX = glmode ? 0 : this.bquad.tlx;
var penY = glmode ? 0 : this.bquad.tly;
if (this.runtime.pixel_rounding)
{
penX = (penX + 0.5) | 0;
penY = (penY + 0.5) | 0;
}
if (this.angle !== 0 && !glmode)
{
ctx.save();
ctx.translate(penX, penY);
ctx.rotate(this.angle);
penX = 0;
penY = 0;
}
var endY = penY + this.height;
var line_height = this.pxHeight;
line_height += this.line_height_offset;
var drawX;
var i;
if (this.valign === 1) // center
penY += Math.max(this.height / 2 - (this.lines.length * line_height) / 2, 0);
else if (this.valign === 2) // bottom
penY += Math.max(this.height - (this.lines.length * line_height) - 2, 0);
for (i = 0; i < this.lines.length; i++)
{
drawX = penX;
if (this.halign === 1) // center
drawX = penX + (this.width - this.lines[i].width) / 2;
else if (this.halign === 2) // right
drawX = penX + (this.width - this.lines[i].width);
ctx.fillText(this.lines[i].text, drawX, penY);
penY += line_height;
if (penY >= endY - line_height)
break;
}
if (this.angle !== 0 || glmode)
ctx.restore();
this.last_render_tick = this.runtime.tickcount;
};
instanceProto.drawGL = function(glw)
{
if (this.width < 1 || this.height < 1)
return;
var need_redraw = this.text_changed || this.need_text_redraw;
this.need_text_redraw = false;
var layer_scale = this.layer.getScale();
var layer_angle = this.layer.getAngle();
var rcTex = this.rcTex;
var floatscaledwidth = layer_scale * this.width;
var floatscaledheight = layer_scale * this.height;
var scaledwidth = Math.ceil(floatscaledwidth);
var scaledheight = Math.ceil(floatscaledheight);
var absscaledwidth = Math.abs(scaledwidth);
var absscaledheight = Math.abs(scaledheight);
var halfw = this.runtime.draw_width / 2;
var halfh = this.runtime.draw_height / 2;
if (!this.myctx)
{
this.mycanvas = document.createElement("canvas");
this.mycanvas.width = absscaledwidth;
this.mycanvas.height = absscaledheight;
this.lastwidth = absscaledwidth;
this.lastheight = absscaledheight;
need_redraw = true;
this.myctx = this.mycanvas.getContext("2d");
}
if (absscaledwidth !== this.lastwidth || absscaledheight !== this.lastheight)
{
this.mycanvas.width = absscaledwidth;
this.mycanvas.height = absscaledheight;
if (this.mytex)
{
glw.deleteTexture(this.mytex);
this.mytex = null;
}
need_redraw = true;
}
if (need_redraw)
{
this.myctx.clearRect(0, 0, absscaledwidth, absscaledheight);
this.draw(this.myctx, true);
if (!this.mytex)
this.mytex = glw.createEmptyTexture(absscaledwidth, absscaledheight, this.runtime.linearSampling, this.runtime.isMobile);
glw.videoToTexture(this.mycanvas, this.mytex, this.runtime.isMobile);
}
this.lastwidth = absscaledwidth;
this.lastheight = absscaledheight;
glw.setTexture(this.mytex);
glw.setOpacity(this.opacity);
glw.resetModelView();
glw.translate(-halfw, -halfh);
glw.updateModelView();
var q = this.bquad;
var tlx = this.layer.layerToCanvas(q.tlx, q.tly, true, true);
var tly = this.layer.layerToCanvas(q.tlx, q.tly, false, true);
var trx = this.layer.layerToCanvas(q.trx, q.try_, true, true);
var try_ = this.layer.layerToCanvas(q.trx, q.try_, false, true);
var brx = this.layer.layerToCanvas(q.brx, q.bry, true, true);
var bry = this.layer.layerToCanvas(q.brx, q.bry, false, true);
var blx = this.layer.layerToCanvas(q.blx, q.bly, true, true);
var bly = this.layer.layerToCanvas(q.blx, q.bly, false, true);
if (this.runtime.pixel_rounding || (this.angle === 0 && layer_angle === 0))
{
var ox = ((tlx + 0.5) | 0) - tlx;
var oy = ((tly + 0.5) | 0) - tly
tlx += ox;
tly += oy;
trx += ox;
try_ += oy;
brx += ox;
bry += oy;
blx += ox;
bly += oy;
}
if (this.angle === 0 && layer_angle === 0)
{
trx = tlx + scaledwidth;
try_ = tly;
brx = trx;
bry = tly + scaledheight;
blx = tlx;
bly = bry;
rcTex.right = 1;
rcTex.bottom = 1;
}
else
{
rcTex.right = floatscaledwidth / scaledwidth;
rcTex.bottom = floatscaledheight / scaledheight;
}
glw.quadTex(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex);
glw.resetModelView();
glw.scale(layer_scale, layer_scale);
glw.rotateZ(-this.layer.getAngle());
glw.translate((this.layer.viewLeft + this.layer.viewRight) / -2, (this.layer.viewTop + this.layer.viewBottom) / -2);
glw.updateModelView();
this.last_render_tick = this.runtime.tickcount;
};
var wordsCache = [];
pluginProto.TokeniseWords = function (text)
{
cr.clearArray(wordsCache);
var cur_word = "";
var ch;
var i = 0;
while (i < text.length)
{
ch = text.charAt(i);
if (ch === "\n")
{
if (cur_word.length)
{
wordsCache.push(cur_word);
cur_word = "";
}
wordsCache.push("\n");
++i;
}
else if (ch === " " || ch === "\t" || ch === "-")
{
do {
cur_word += text.charAt(i);
i++;
}
while (i < text.length && (text.charAt(i) === " " || text.charAt(i) === "\t"));
wordsCache.push(cur_word);
cur_word = "";
}
else if (i < text.length)
{
cur_word += ch;
i++;
}
}
if (cur_word.length)
wordsCache.push(cur_word);
};
var linesCache = [];
function allocLine()
{
if (linesCache.length)
return linesCache.pop();
else
return {};
};
function freeLine(l)
{
linesCache.push(l);
};
function freeAllLines(arr)
{
var i, len;
for (i = 0, len = arr.length; i < len; i++)
{
freeLine(arr[i]);
}
cr.clearArray(arr);
};
pluginProto.WordWrap = function (text, lines, ctx, width, wrapbyword)
{
if (!text || !text.length)
{
freeAllLines(lines);
return;
}
if (width <= 2.0)
{
freeAllLines(lines);
return;
}
if (text.length <= 100 && text.indexOf("\n") === -1)
{
var all_width = ctx.measureText(text).width;
if (all_width <= width)
{
freeAllLines(lines);
lines.push(allocLine());
lines[0].text = text;
lines[0].width = all_width;
return;
}
}
this.WrapText(text, lines, ctx, width, wrapbyword);
};
function trimSingleSpaceRight(str)
{
if (!str.length || str.charAt(str.length - 1) !== " ")
return str;
return str.substring(0, str.length - 1);
};
pluginProto.WrapText = function (text, lines, ctx, width, wrapbyword)
{
var wordArray;
if (wrapbyword)
{
this.TokeniseWords(text); // writes to wordsCache
wordArray = wordsCache;
}
else
wordArray = text;
var cur_line = "";
var prev_line;
var line_width;
var i;
var lineIndex = 0;
var line;
for (i = 0; i < wordArray.length; i++)
{
if (wordArray[i] === "\n")
{
if (lineIndex >= lines.length)
lines.push(allocLine());
cur_line = trimSingleSpaceRight(cur_line); // for correct center/right alignment
line = lines[lineIndex];
line.text = cur_line;
line.width = ctx.measureText(cur_line).width;
lineIndex++;
cur_line = "";
continue;
}
prev_line = cur_line;
cur_line += wordArray[i];
line_width = ctx.measureText(cur_line).width;
if (line_width >= width)
{
if (lineIndex >= lines.length)
lines.push(allocLine());
prev_line = trimSingleSpaceRight(prev_line);
line = lines[lineIndex];
line.text = prev_line;
line.width = ctx.measureText(prev_line).width;
lineIndex++;
cur_line = wordArray[i];
if (!wrapbyword && cur_line === " ")
cur_line = "";
}
}
if (cur_line.length)
{
if (lineIndex >= lines.length)
lines.push(allocLine());
cur_line = trimSingleSpaceRight(cur_line);
line = lines[lineIndex];
line.text = cur_line;
line.width = ctx.measureText(cur_line).width;
lineIndex++;
}
for (i = lineIndex; i < lines.length; i++)
freeLine(lines[i]);
lines.length = lineIndex;
};
function Cnds() {};
Cnds.prototype.CompareText = function(text_to_compare, case_sensitive)
{
if (case_sensitive)
return this.text == text_to_compare;
else
return cr.equals_nocase(this.text, text_to_compare);
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetText = function(param)
{
if (cr.is_number(param) && param < 1e9)
param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
var text_to_set = param.toString();
if (this.text !== text_to_set)
{
this.text = text_to_set;
this.text_changed = true;
this.runtime.redraw = true;
}
};
Acts.prototype.AppendText = function(param)
{
if (cr.is_number(param))
param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
var text_to_append = param.toString();
if (text_to_append) // not empty
{
this.text += text_to_append;
this.text_changed = true;
this.runtime.redraw = true;
}
};
Acts.prototype.SetFontFace = function (face_, style_)
{
var newstyle = "";
switch (style_) {
case 1: newstyle = "bold"; break;
case 2: newstyle = "italic"; break;
case 3: newstyle = "bold italic"; break;
}
if (face_ === this.facename && newstyle === this.fontstyle)
return; // no change
this.facename = face_;
this.fontstyle = newstyle;
this.updateFont();
};
Acts.prototype.SetFontSize = function (size_)
{
if (this.ptSize === size_)
return;
this.ptSize = size_;
this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi...
this.updateFont();
};
Acts.prototype.SetFontColor = function (rgb)
{
var newcolor = "rgb(" + cr.GetRValue(rgb).toString() + "," + cr.GetGValue(rgb).toString() + "," + cr.GetBValue(rgb).toString() + ")";
if (newcolor === this.color)
return;
this.color = newcolor;
this.need_text_redraw = true;
this.runtime.redraw = true;
};
Acts.prototype.SetWebFont = function (familyname_, cssurl_)
{
if (this.runtime.isDomFree)
{
cr.logexport("[Construct 2] Text plugin: 'Set web font' not supported on this platform - the action has been ignored");
return; // DC todo
}
var self = this;
var refreshFunc = (function () {
self.runtime.redraw = true;
self.text_changed = true;
});
if (requestedWebFonts.hasOwnProperty(cssurl_))
{
var newfacename = "'" + familyname_ + "'";
if (this.facename === newfacename)
return; // no change
this.facename = newfacename;
this.updateFont();
for (var i = 1; i < 10; i++)
{
setTimeout(refreshFunc, i * 100);
setTimeout(refreshFunc, i * 1000);
}
return;
}
var wf = document.createElement("link");
wf.href = cssurl_;
wf.rel = "stylesheet";
wf.type = "text/css";
wf.onload = refreshFunc;
document.getElementsByTagName('head')[0].appendChild(wf);
requestedWebFonts[cssurl_] = true;
this.facename = "'" + familyname_ + "'";
this.updateFont();
for (var i = 1; i < 10; i++)
{
setTimeout(refreshFunc, i * 100);
setTimeout(refreshFunc, i * 1000);
}
;
};
Acts.prototype.SetEffect = function (effect)
{
this.blend_mode = effect;
this.compositeOp = cr.effectToCompositeOp(effect);
cr.setGLBlend(this, effect, this.runtime.gl);
this.runtime.redraw = true;
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.Text = function(ret)
{
ret.set_string(this.text);
};
Exps.prototype.FaceName = function (ret)
{
ret.set_string(this.facename);
};
Exps.prototype.FaceSize = function (ret)
{
ret.set_int(this.ptSize);
};
Exps.prototype.TextWidth = function (ret)
{
var w = 0;
var i, len, x;
for (i = 0, len = this.lines.length; i < len; i++)
{
x = this.lines[i].width;
if (w < x)
w = x;
}
ret.set_int(w);
};
Exps.prototype.TextHeight = function (ret)
{
ret.set_int(this.lines.length * (this.pxHeight + this.line_height_offset) - this.line_height_offset);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.TextBox = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.TextBox.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
var elemTypes = ["text", "password", "email", "number", "tel", "url"];
if (navigator.userAgent.indexOf("MSIE 9") > -1)
{
elemTypes[2] = "text";
elemTypes[3] = "text";
elemTypes[4] = "text";
elemTypes[5] = "text";
}
instanceProto.onCreate = function()
{
if (this.runtime.isDomFree)
{
cr.logexport("[Construct 2] Textbox plugin not supported on this platform - the object will not be created");
return;
}
if (this.properties[7] === 6) // textarea
{
this.elem = document.createElement("textarea");
jQuery(this.elem).css("resize", "none");
}
else
{
this.elem = document.createElement("input");
this.elem.type = elemTypes[this.properties[7]];
}
this.elem.id = this.properties[9];
jQuery(this.elem).appendTo(this.runtime.canvasdiv ? this.runtime.canvasdiv : "body");
this.elem["autocomplete"] = "off";
this.elem.value = this.properties[0];
this.elem["placeholder"] = this.properties[1];
this.elem.title = this.properties[2];
this.elem.disabled = (this.properties[4] === 0);
this.elem["readOnly"] = (this.properties[5] === 1);
this.elem["spellcheck"] = (this.properties[6] === 1);
this.autoFontSize = (this.properties[8] !== 0);
this.element_hidden = false;
if (this.properties[3] === 0)
{
jQuery(this.elem).hide();
this.visible = false;
this.element_hidden = true;
}
var onchangetrigger = (function (self) {
return function() {
self.runtime.trigger(cr.plugins_.TextBox.prototype.cnds.OnTextChanged, self);
};
})(this);
this.elem["oninput"] = onchangetrigger;
if (navigator.userAgent.indexOf("MSIE") !== -1)
this.elem["oncut"] = onchangetrigger;
this.elem.onclick = (function (self) {
return function(e) {
e.stopPropagation();
self.runtime.isInUserInputEvent = true;
self.runtime.trigger(cr.plugins_.TextBox.prototype.cnds.OnClicked, self);
self.runtime.isInUserInputEvent = false;
};
})(this);
this.elem.ondblclick = (function (self) {
return function(e) {
e.stopPropagation();
self.runtime.isInUserInputEvent = true;
self.runtime.trigger(cr.plugins_.TextBox.prototype.cnds.OnDoubleClicked, self);
self.runtime.isInUserInputEvent = false;
};
})(this);
this.elem.addEventListener("touchstart", function (e) {
e.stopPropagation();
}, false);
this.elem.addEventListener("touchmove", function (e) {
e.stopPropagation();
}, false);
this.elem.addEventListener("touchend", function (e) {
e.stopPropagation();
}, false);
jQuery(this.elem).mousedown(function (e) {
e.stopPropagation();
});
jQuery(this.elem).mouseup(function (e) {
e.stopPropagation();
});
jQuery(this.elem).keydown(function (e) {
if (e.which !== 13 && e.which != 27) // allow enter and escape
e.stopPropagation();
});
jQuery(this.elem).keyup(function (e) {
if (e.which !== 13 && e.which != 27) // allow enter and escape
e.stopPropagation();
});
this.lastLeft = 0;
this.lastTop = 0;
this.lastRight = 0;
this.lastBottom = 0;
this.lastWinWidth = 0;
this.lastWinHeight = 0;
this.updatePosition(true);
this.runtime.tickMe(this);
};
instanceProto.saveToJSON = function ()
{
return {
"text": this.elem.value,
"placeholder": this.elem.placeholder,
"tooltip": this.elem.title,
"disabled": !!this.elem.disabled,
"readonly": !!this.elem.readOnly,
"spellcheck": !!this.elem["spellcheck"]
};
};
instanceProto.loadFromJSON = function (o)
{
this.elem.value = o["text"];
this.elem.placeholder = o["placeholder"];
this.elem.title = o["tooltip"];
this.elem.disabled = o["disabled"];
this.elem.readOnly = o["readonly"];
this.elem["spellcheck"] = o["spellcheck"];
};
instanceProto.onDestroy = function ()
{
if (this.runtime.isDomFree)
return;
jQuery(this.elem).remove();
this.elem = null;
};
instanceProto.tick = function ()
{
this.updatePosition();
};
instanceProto.updatePosition = function (first)
{
if (this.runtime.isDomFree)
return;
var left = this.layer.layerToCanvas(this.x, this.y, true);
var top = this.layer.layerToCanvas(this.x, this.y, false);
var right = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, true);
var bottom = this.layer.layerToCanvas(this.x + this.width, this.y + this.height, false);
var rightEdge = this.runtime.width / this.runtime.devicePixelRatio;
var bottomEdge = this.runtime.height / this.runtime.devicePixelRatio;
if (!this.visible || !this.layer.visible || right <= 0 || bottom <= 0 || left >= rightEdge || top >= bottomEdge)
{
if (!this.element_hidden)
jQuery(this.elem).hide();
this.element_hidden = true;
return;
}
if (left < 1)
left = 1;
if (top < 1)
top = 1;
if (right >= rightEdge)
right = rightEdge - 1;
if (bottom >= bottomEdge)
bottom = bottomEdge - 1;
var curWinWidth = window.innerWidth;
var curWinHeight = window.innerHeight;
if (!first && this.lastLeft === left && this.lastTop === top && this.lastRight === right && this.lastBottom === bottom && this.lastWinWidth === curWinWidth && this.lastWinHeight === curWinHeight)
{
if (this.element_hidden)
{
jQuery(this.elem).show();
this.element_hidden = false;
}
return;
}
this.lastLeft = left;
this.lastTop = top;
this.lastRight = right;
this.lastBottom = bottom;
this.lastWinWidth = curWinWidth;
this.lastWinHeight = curWinHeight;
if (this.element_hidden)
{
jQuery(this.elem).show();
this.element_hidden = false;
}
var offx = Math.round(left) + jQuery(this.runtime.canvas).offset().left;
var offy = Math.round(top) + jQuery(this.runtime.canvas).offset().top;
jQuery(this.elem).css("position", "absolute");
jQuery(this.elem).offset({left: offx, top: offy});
jQuery(this.elem).width(Math.round(right - left));
jQuery(this.elem).height(Math.round(bottom - top));
if (this.autoFontSize)
jQuery(this.elem).css("font-size", ((this.layer.getScale(true) / this.runtime.devicePixelRatio) - 0.2) + "em");
};
instanceProto.draw = function(ctx)
{
};
instanceProto.drawGL = function(glw)
{
};
function Cnds() {};
Cnds.prototype.CompareText = function (text, case_)
{
if (this.runtime.isDomFree)
return false;
if (case_ === 0) // insensitive
return cr.equals_nocase(this.elem.value, text);
else
return this.elem.value === text;
};
Cnds.prototype.OnTextChanged = function ()
{
return true;
};
Cnds.prototype.OnClicked = function ()
{
return true;
};
Cnds.prototype.OnDoubleClicked = function ()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetText = function (text)
{
if (this.runtime.isDomFree)
return;
this.elem.value = text;
};
Acts.prototype.SetPlaceholder = function (text)
{
if (this.runtime.isDomFree)
return;
this.elem.placeholder = text;
};
Acts.prototype.SetTooltip = function (text)
{
if (this.runtime.isDomFree)
return;
this.elem.title = text;
};
Acts.prototype.SetVisible = function (vis)
{
if (this.runtime.isDomFree)
return;
this.visible = (vis !== 0);
};
Acts.prototype.SetEnabled = function (en)
{
if (this.runtime.isDomFree)
return;
this.elem.disabled = (en === 0);
};
Acts.prototype.SetReadOnly = function (ro)
{
if (this.runtime.isDomFree)
return;
this.elem.readOnly = (ro === 0);
};
Acts.prototype.SetFocus = function ()
{
if (this.runtime.isDomFree)
return;
this.elem.focus();
};
Acts.prototype.SetBlur = function ()
{
if (this.runtime.isDomFree)
return;
this.elem.blur();
};
Acts.prototype.SetCSSStyle = function (p, v)
{
if (this.runtime.isDomFree)
return;
jQuery(this.elem).css(p, v);
};
Acts.prototype.ScrollToBottom = function ()
{
if (this.runtime.isDomFree)
return;
this.elem.scrollTop = this.elem.scrollHeight;
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.Text = function (ret)
{
if (this.runtime.isDomFree)
{
ret.set_string("");
return;
}
ret.set_string(this.elem.value);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.TiledBg = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.TiledBg.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
if (this.is_family)
return;
this.texture_img = new Image();
this.texture_img.cr_filesize = this.texture_filesize;
this.runtime.waitForImageLoad(this.texture_img, this.texture_file);
this.pattern = null;
this.webGL_texture = null;
};
typeProto.onLostWebGLContext = function ()
{
if (this.is_family)
return;
this.webGL_texture = null;
};
typeProto.onRestoreWebGLContext = function ()
{
if (this.is_family || !this.instances.length)
return;
if (!this.webGL_texture)
{
this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, true, this.runtime.linearSampling, this.texture_pixelformat);
}
var i, len;
for (i = 0, len = this.instances.length; i < len; i++)
this.instances[i].webGL_texture = this.webGL_texture;
};
typeProto.loadTextures = function ()
{
if (this.is_family || this.webGL_texture || !this.runtime.glwrap)
return;
this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, true, this.runtime.linearSampling, this.texture_pixelformat);
};
typeProto.unloadTextures = function ()
{
if (this.is_family || this.instances.length || !this.webGL_texture)
return;
this.runtime.glwrap.deleteTexture(this.webGL_texture);
this.webGL_texture = null;
};
typeProto.preloadCanvas2D = function (ctx)
{
ctx.drawImage(this.texture_img, 0, 0);
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
this.visible = (this.properties[0] === 0); // 0=visible, 1=invisible
this.rcTex = new cr.rect(0, 0, 0, 0);
this.has_own_texture = false; // true if a texture loaded in from URL
this.texture_img = this.type.texture_img;
if (this.runtime.glwrap)
{
this.type.loadTextures();
this.webGL_texture = this.type.webGL_texture;
}
else
{
if (!this.type.pattern)
this.type.pattern = this.runtime.ctx.createPattern(this.type.texture_img, "repeat");
this.pattern = this.type.pattern;
}
};
instanceProto.afterLoad = function ()
{
this.has_own_texture = false;
this.texture_img = this.type.texture_img;
};
instanceProto.onDestroy = function ()
{
if (this.runtime.glwrap && this.has_own_texture && this.webGL_texture)
{
this.runtime.glwrap.deleteTexture(this.webGL_texture);
this.webGL_texture = null;
}
};
instanceProto.draw = function(ctx)
{
ctx.globalAlpha = this.opacity;
ctx.save();
ctx.fillStyle = this.pattern;
var myx = this.x;
var myy = this.y;
if (this.runtime.pixel_rounding)
{
myx = Math.round(myx);
myy = Math.round(myy);
}
var drawX = -(this.hotspotX * this.width);
var drawY = -(this.hotspotY * this.height);
var offX = drawX % this.texture_img.width;
var offY = drawY % this.texture_img.height;
if (offX < 0)
offX += this.texture_img.width;
if (offY < 0)
offY += this.texture_img.height;
ctx.translate(myx, myy);
ctx.rotate(this.angle);
ctx.translate(offX, offY);
ctx.fillRect(drawX - offX,
drawY - offY,
this.width,
this.height);
ctx.restore();
};
instanceProto.drawGL_earlyZPass = function(glw)
{
this.drawGL(glw);
};
instanceProto.drawGL = function(glw)
{
glw.setTexture(this.webGL_texture);
glw.setOpacity(this.opacity);
var rcTex = this.rcTex;
rcTex.right = this.width / this.texture_img.width;
rcTex.bottom = this.height / this.texture_img.height;
var q = this.bquad;
if (this.runtime.pixel_rounding)
{
var ox = Math.round(this.x) - this.x;
var oy = Math.round(this.y) - this.y;
glw.quadTex(q.tlx + ox, q.tly + oy, q.trx + ox, q.try_ + oy, q.brx + ox, q.bry + oy, q.blx + ox, q.bly + oy, rcTex);
}
else
glw.quadTex(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly, rcTex);
};
function Cnds() {};
Cnds.prototype.OnURLLoaded = function ()
{
return true;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetEffect = function (effect)
{
this.blend_mode = effect;
this.compositeOp = cr.effectToCompositeOp(effect);
cr.setGLBlend(this, effect, this.runtime.gl);
this.runtime.redraw = true;
};
Acts.prototype.LoadURL = function (url_, crossOrigin_)
{
var img = new Image();
var self = this;
img.onload = function ()
{
self.texture_img = img;
if (self.runtime.glwrap)
{
if (self.has_own_texture && self.webGL_texture)
self.runtime.glwrap.deleteTexture(self.webGL_texture);
self.webGL_texture = self.runtime.glwrap.loadTexture(img, true, self.runtime.linearSampling);
}
else
{
self.pattern = self.runtime.ctx.createPattern(img, "repeat");
}
self.has_own_texture = true;
self.runtime.redraw = true;
self.runtime.trigger(cr.plugins_.TiledBg.prototype.cnds.OnURLLoaded, self);
};
if (url_.substr(0, 5) !== "data:" && crossOrigin_ === 0)
img.crossOrigin = "anonymous";
this.runtime.setImageSrc(img, url_);
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.ImageWidth = function (ret)
{
ret.set_float(this.texture_img.width);
};
Exps.prototype.ImageHeight = function (ret)
{
ret.set_float(this.texture_img.height);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.Touch = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.Touch.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
this.touches = [];
this.mouseDown = false;
};
var instanceProto = pluginProto.Instance.prototype;
var dummyoffset = {left: 0, top: 0};
instanceProto.findTouch = function (id)
{
var i, len;
for (i = 0, len = this.touches.length; i < len; i++)
{
if (this.touches[i]["id"] === id)
return i;
}
return -1;
};
var appmobi_accx = 0;
var appmobi_accy = 0;
var appmobi_accz = 0;
function AppMobiGetAcceleration(evt)
{
appmobi_accx = evt.x;
appmobi_accy = evt.y;
appmobi_accz = evt.z;
};
var pg_accx = 0;
var pg_accy = 0;
var pg_accz = 0;
function PhoneGapGetAcceleration(evt)
{
pg_accx = evt.x;
pg_accy = evt.y;
pg_accz = evt.z;
};
var theInstance = null;
var touchinfo_cache = [];
function AllocTouchInfo(x, y, id, index)
{
var ret;
if (touchinfo_cache.length)
ret = touchinfo_cache.pop();
else
ret = new TouchInfo();
ret.init(x, y, id, index);
return ret;
};
function ReleaseTouchInfo(ti)
{
if (touchinfo_cache.length < 100)
touchinfo_cache.push(ti);
};
var GESTURE_HOLD_THRESHOLD = 15; // max px motion for hold gesture to register
var GESTURE_HOLD_TIMEOUT = 500; // time for hold gesture to register
var GESTURE_TAP_TIMEOUT = 333; // time for tap gesture to register
var GESTURE_DOUBLETAP_THRESHOLD = 25; // max distance apart for taps to be
function TouchInfo()
{
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["id"] = 0;
this.startindex = 0;
this.triggeredHold = false;
this.tooFarForHold = false;
};
TouchInfo.prototype.init = function (x, y, id, index)
{
var nowtime = cr.performance_now();
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;
this.width = 0;
this.height = 0;
this.pressure = 0;
this["id"] = id;
this.startindex = index;
this.triggeredHold = false;
this.tooFarForHold = false;
};
TouchInfo.prototype.update = function (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.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) >= GESTURE_HOLD_THRESHOLD)
{
this.tooFarForHold = true;
}
};
TouchInfo.prototype.maybeTriggerHold = function (inst, index)
{
if (this.triggeredHold)
return; // already triggered this gesture
var nowtime = cr.performance_now();
if (nowtime - this.starttime >= GESTURE_HOLD_TIMEOUT && !this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) < GESTURE_HOLD_THRESHOLD)
{
this.triggeredHold = true;
inst.trigger_index = this.startindex;
inst.trigger_id = this["id"];
inst.getTouchIndex = index;
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnHoldGesture, inst);
inst.curTouchX = this.x;
inst.curTouchY = this.y;
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnHoldGestureObject, inst);
inst.getTouchIndex = 0;
}
};
var lastTapX = -1000;
var lastTapY = -1000;
var lastTapTime = -10000;
TouchInfo.prototype.maybeTriggerTap = function (inst, index)
{
if (this.triggeredHold)
return;
var nowtime = cr.performance_now();
if (nowtime - this.starttime <= GESTURE_TAP_TIMEOUT && !this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) < GESTURE_HOLD_THRESHOLD)
{
inst.trigger_index = this.startindex;
inst.trigger_id = this["id"];
inst.getTouchIndex = index;
if ((nowtime - lastTapTime <= GESTURE_TAP_TIMEOUT * 2) && cr.distanceTo(lastTapX, lastTapY, this.x, this.y) < GESTURE_DOUBLETAP_THRESHOLD)
{
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnDoubleTapGesture, inst);
inst.curTouchX = this.x;
inst.curTouchY = this.y;
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnDoubleTapGestureObject, inst);
lastTapX = -1000;
lastTapY = -1000;
lastTapTime = -10000;
}
else
{
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTapGesture, inst);
inst.curTouchX = this.x;
inst.curTouchY = this.y;
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTapGestureObject, inst);
lastTapX = this.x;
lastTapY = this.y;
lastTapTime = nowtime;
}
inst.getTouchIndex = 0;
}
};
instanceProto.onCreate = function()
{
theInstance = this;
this.isWindows8 = !!(typeof window["c2isWindows8"] !== "undefined" && window["c2isWindows8"]);
this.orient_alpha = 0;
this.orient_beta = 0;
this.orient_gamma = 0;
this.acc_g_x = 0;
this.acc_g_y = 0;
this.acc_g_z = 0;
this.acc_x = 0;
this.acc_y = 0;
this.acc_z = 0;
this.curTouchX = 0;
this.curTouchY = 0;
this.trigger_index = 0;
this.trigger_id = 0;
this.trigger_permission = 0;
this.getTouchIndex = 0;
this.useMouseInput = (this.properties[0] !== 0);
var elem = (this.runtime.fullscreen_mode > 0) ? document : this.runtime.canvas;
var elem2 = document;
if (this.runtime.isDirectCanvas)
elem2 = elem = window["Canvas"];
else if (this.runtime.isCocoonJs)
elem2 = elem = window;
var self = this;
if (typeof PointerEvent !== "undefined")
{
elem.addEventListener("pointerdown",
function(info) {
self.onPointerStart(info);
},
false
);
elem.addEventListener("pointermove",
function(info) {
self.onPointerMove(info);
},
false
);
elem2.addEventListener("pointerup",
function(info) {
self.onPointerEnd(info, false);
},
false
);
elem2.addEventListener("pointercancel",
function(info) {
self.onPointerEnd(info, true);
},
false
);
if (this.runtime.canvas)
{
this.runtime.canvas.addEventListener("MSGestureHold", function(e) {
e.preventDefault();
}, false);
document.addEventListener("MSGestureHold", function(e) {
e.preventDefault();
}, false);
this.runtime.canvas.addEventListener("gesturehold", function(e) {
e.preventDefault();
}, false);
document.addEventListener("gesturehold", function(e) {
e.preventDefault();
}, false);
}
}
else if (window.navigator["msPointerEnabled"])
{
elem.addEventListener("MSPointerDown",
function(info) {
self.onPointerStart(info);
},
false
);
elem.addEventListener("MSPointerMove",
function(info) {
self.onPointerMove(info);
},
false
);
elem2.addEventListener("MSPointerUp",
function(info) {
self.onPointerEnd(info, false);
},
false
);
elem2.addEventListener("MSPointerCancel",
function(info) {
self.onPointerEnd(info, true);
},
false
);
if (this.runtime.canvas)
{
this.runtime.canvas.addEventListener("MSGestureHold", function(e) {
e.preventDefault();
}, false);
document.addEventListener("MSGestureHold", function(e) {
e.preventDefault();
}, false);
}
}
else
{
elem.addEventListener("touchstart",
function(info) {
self.onTouchStart(info);
},
false
);
elem.addEventListener("touchmove",
function(info) {
self.onTouchMove(info);
},
false
);
elem2.addEventListener("touchend",
function(info) {
self.onTouchEnd(info, false);
},
false
);
elem2.addEventListener("touchcancel",
function(info) {
self.onTouchEnd(info, true);
},
false
);
}
if (this.isWindows8)
{
var win8accelerometerFn = function(e) {
var reading = e["reading"];
self.acc_x = reading["accelerationX"];
self.acc_y = reading["accelerationY"];
self.acc_z = reading["accelerationZ"];
};
var win8inclinometerFn = function(e) {
var reading = e["reading"];
self.orient_alpha = reading["yawDegrees"];
self.orient_beta = reading["pitchDegrees"];
self.orient_gamma = reading["rollDegrees"];
};
var accelerometer = Windows["Devices"]["Sensors"]["Accelerometer"]["getDefault"]();
if (accelerometer)
{
accelerometer["reportInterval"] = Math.max(accelerometer["minimumReportInterval"], 16);
accelerometer.addEventListener("readingchanged", win8accelerometerFn);
}
var inclinometer = Windows["Devices"]["Sensors"]["Inclinometer"]["getDefault"]();
if (inclinometer)
{
inclinometer["reportInterval"] = Math.max(inclinometer["minimumReportInterval"], 16);
inclinometer.addEventListener("readingchanged", win8inclinometerFn);
}
document.addEventListener("visibilitychange", function(e) {
if (document["hidden"] || document["msHidden"])
{
if (accelerometer)
accelerometer.removeEventListener("readingchanged", win8accelerometerFn);
if (inclinometer)
inclinometer.removeEventListener("readingchanged", win8inclinometerFn);
}
else
{
if (accelerometer)
accelerometer.addEventListener("readingchanged", win8accelerometerFn);
if (inclinometer)
inclinometer.addEventListener("readingchanged", win8inclinometerFn);
}
}, false);
}
else
{
window.addEventListener("deviceorientation", function (eventData) {
self.orient_alpha = eventData["alpha"] || 0;
self.orient_beta = eventData["beta"] || 0;
self.orient_gamma = eventData["gamma"] || 0;
}, false);
window.addEventListener("devicemotion", function (eventData) {
if (eventData["accelerationIncludingGravity"])
{
self.acc_g_x = eventData["accelerationIncludingGravity"]["x"] || 0;
self.acc_g_y = eventData["accelerationIncludingGravity"]["y"] || 0;
self.acc_g_z = eventData["accelerationIncludingGravity"]["z"] || 0;
}
if (eventData["acceleration"])
{
self.acc_x = eventData["acceleration"]["x"] || 0;
self.acc_y = eventData["acceleration"]["y"] || 0;
self.acc_z = eventData["acceleration"]["z"] || 0;
}
}, false);
}
if (this.useMouseInput && !this.runtime.isDomFree)
{
jQuery(document).mousemove(
function(info) {
self.onMouseMove(info);
}
);
jQuery(document).mousedown(
function(info) {
self.onMouseDown(info);
}
);
jQuery(document).mouseup(
function(info) {
self.onMouseUp(info);
}
);
}
if (!this.runtime.isiOS && this.runtime.isCordova && navigator["accelerometer"] && navigator["accelerometer"]["watchAcceleration"])
{
navigator["accelerometer"]["watchAcceleration"](PhoneGapGetAcceleration, null, { "frequency": 40 });
}
this.runtime.tick2Me(this);
};
instanceProto.onPointerMove = function (info)
{
if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
return;
if (info.preventDefault)
info.preventDefault();
var i = this.findTouch(info["pointerId"]);
var nowtime = cr.performance_now();
if (i >= 0)
{
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
var t = this.touches[i];
if (nowtime - t.time < 2)
return;
t.update(nowtime, info.pageX - offset.left, info.pageY - offset.top, info.width || 0, info.height || 0, info.pressure || 0);
}
};
instanceProto.onPointerStart = function (info)
{
if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
return;
if (info.preventDefault && cr.isCanvasInputEvent(info))
info.preventDefault();
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
var touchx = info.pageX - offset.left;
var touchy = info.pageY - offset.top;
var nowtime = cr.performance_now();
this.trigger_index = this.touches.length;
this.trigger_id = info["pointerId"];
this.touches.push(AllocTouchInfo(touchx, touchy, info["pointerId"], this.trigger_index));
this.runtime.isInUserInputEvent = true;
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchStart, this);
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchStart, this);
this.curTouchX = touchx;
this.curTouchY = touchy;
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchObject, this);
this.runtime.isInUserInputEvent = false;
};
instanceProto.onPointerEnd = function (info, isCancel)
{
if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
return;
if (info.preventDefault && cr.isCanvasInputEvent(info))
info.preventDefault();
var i = this.findTouch(info["pointerId"]);
this.trigger_index = (i >= 0 ? this.touches[i].startindex : -1);
this.trigger_id = (i >= 0 ? this.touches[i]["id"] : -1);
this.runtime.isInUserInputEvent = true;
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchEnd, this);
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchEnd, this);
if (i >= 0)
{
if (!isCancel)
this.touches[i].maybeTriggerTap(this, i);
ReleaseTouchInfo(this.touches[i]);
this.touches.splice(i, 1);
}
this.runtime.isInUserInputEvent = false;
};
instanceProto.onTouchMove = function (info)
{
if (info.preventDefault)
info.preventDefault();
var nowtime = cr.performance_now();
var i, len, t, u;
for (i = 0, len = info.changedTouches.length; i < len; i++)
{
t = info.changedTouches[i];
var j = this.findTouch(t["identifier"]);
if (j >= 0)
{
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
u = this.touches[j];
if (nowtime - u.time < 2)
continue;
var touchWidth = (t.radiusX || t.webkitRadiusX || t.mozRadiusX || t.msRadiusX || 0) * 2;
var touchHeight = (t.radiusY || t.webkitRadiusY || t.mozRadiusY || t.msRadiusY || 0) * 2;
var touchForce = t.force || t.webkitForce || t.mozForce || t.msForce || 0;
u.update(nowtime, t.pageX - offset.left, t.pageY - offset.top, touchWidth, touchHeight, touchForce);
}
}
};
instanceProto.onTouchStart = function (info)
{
if (info.preventDefault && cr.isCanvasInputEvent(info))
info.preventDefault();
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
var nowtime = cr.performance_now();
this.runtime.isInUserInputEvent = true;
var i, len, t, j;
for (i = 0, len = info.changedTouches.length; i < len; i++)
{
t = info.changedTouches[i];
j = this.findTouch(t["identifier"]);
if (j !== -1)
continue;
var touchx = t.pageX - offset.left;
var touchy = t.pageY - offset.top;
this.trigger_index = this.touches.length;
this.trigger_id = t["identifier"];
this.touches.push(AllocTouchInfo(touchx, touchy, t["identifier"], this.trigger_index));
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchStart, this);
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchStart, this);
this.curTouchX = touchx;
this.curTouchY = touchy;
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchObject, this);
}
this.runtime.isInUserInputEvent = false;
};
instanceProto.onTouchEnd = function (info, isCancel)
{
if (info.preventDefault && cr.isCanvasInputEvent(info))
info.preventDefault();
this.runtime.isInUserInputEvent = true;
var i, len, t, j;
for (i = 0, len = info.changedTouches.length; i < len; i++)
{
t = info.changedTouches[i];
j = this.findTouch(t["identifier"]);
if (j >= 0)
{
this.trigger_index = this.touches[j].startindex;
this.trigger_id = this.touches[j]["id"];
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchEnd, this);
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchEnd, this);
if (!isCancel)
this.touches[j].maybeTriggerTap(this, j);
ReleaseTouchInfo(this.touches[j]);
this.touches.splice(j, 1);
}
}
this.runtime.isInUserInputEvent = false;
};
instanceProto.getAlpha = function ()
{
if (this.runtime.isCordova && this.orient_alpha === 0 && pg_accz !== 0)
return pg_accz * 90;
else
return this.orient_alpha;
};
instanceProto.getBeta = function ()
{
if (this.runtime.isCordova && this.orient_beta === 0 && pg_accy !== 0)
return pg_accy * 90;
else
return this.orient_beta;
};
instanceProto.getGamma = function ()
{
if (this.runtime.isCordova && this.orient_gamma === 0 && pg_accx !== 0)
return pg_accx * 90;
else
return this.orient_gamma;
};
var noop_func = function(){};
function isCompatibilityMouseEvent(e)
{
return (e["sourceCapabilities"] && e["sourceCapabilities"]["firesTouchEvents"]) ||
(e.originalEvent && e.originalEvent["sourceCapabilities"] && e.originalEvent["sourceCapabilities"]["firesTouchEvents"]);
};
instanceProto.onMouseDown = function(info)
{
if (isCompatibilityMouseEvent(info))
return;
var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
var fakeinfo = { changedTouches: [t] };
this.onTouchStart(fakeinfo);
this.mouseDown = true;
};
instanceProto.onMouseMove = function(info)
{
if (!this.mouseDown)
return;
if (isCompatibilityMouseEvent(info))
return;
var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
var fakeinfo = { changedTouches: [t] };
this.onTouchMove(fakeinfo);
};
instanceProto.onMouseUp = function(info)
{
if (info.preventDefault && this.runtime.had_a_click && !this.runtime.isMobile)
info.preventDefault();
this.runtime.had_a_click = true;
if (isCompatibilityMouseEvent(info))
return;
var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
var fakeinfo = { changedTouches: [t] };
this.onTouchEnd(fakeinfo);
this.mouseDown = false;
};
instanceProto.tick2 = function()
{
var i, len, t;
var nowtime = cr.performance_now();
for (i = 0, len = this.touches.length; i < len; ++i)
{
t = this.touches[i];
if (t.time <= nowtime - 50)
t.lasttime = nowtime;
t.maybeTriggerHold(this, i);
}
};
function Cnds() {};
Cnds.prototype.OnTouchStart = function ()
{
return true;
};
Cnds.prototype.OnTouchEnd = function ()
{
return true;
};
Cnds.prototype.IsInTouch = function ()
{
return this.touches.length;
};
Cnds.prototype.OnTouchObject = function (type)
{
if (!type)
return false;
return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
};
var touching = [];
Cnds.prototype.IsTouchingObject = function (type)
{
if (!type)
return false;
var sol = type.getCurrentSol();
var instances = sol.getObjects();
var px, py;
var i, leni, j, lenj;
for (i = 0, leni = instances.length; i < leni; i++)
{
var inst = instances[i];
inst.update_bbox();
for (j = 0, lenj = this.touches.length; j < lenj; j++)
{
var touch = this.touches[j];
px = inst.layer.canvasToLayer(touch.x, touch.y, true);
py = inst.layer.canvasToLayer(touch.x, touch.y, false);
if (inst.contains_pt(px, py))
{
touching.push(inst);
break;
}
}
}
if (touching.length)
{
sol.select_all = false;
cr.shallowAssignArray(sol.instances, touching);
type.applySolToContainer();
cr.clearArray(touching);
return true;
}
else
return false;
};
Cnds.prototype.CompareTouchSpeed = function (index, cmp, s)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
return false;
var t = this.touches[index];
var dist = cr.distanceTo(t.x, t.y, t.lastx, t.lasty);
var timediff = (t.time - t.lasttime) / 1000;
var speed = 0;
if (timediff > 0)
speed = dist / timediff;
return cr.do_cmp(speed, cmp, s);
};
Cnds.prototype.OrientationSupported = function ()
{
return typeof window["DeviceOrientationEvent"] !== "undefined";
};
Cnds.prototype.MotionSupported = function ()
{
return typeof window["DeviceMotionEvent"] !== "undefined";
};
Cnds.prototype.CompareOrientation = function (orientation_, cmp_, angle_)
{
var v = 0;
if (orientation_ === 0)
v = this.getAlpha();
else if (orientation_ === 1)
v = this.getBeta();
else
v = this.getGamma();
return cr.do_cmp(v, cmp_, angle_);
};
Cnds.prototype.CompareAcceleration = function (acceleration_, cmp_, angle_)
{
var v = 0;
if (acceleration_ === 0)
v = this.acc_g_x;
else if (acceleration_ === 1)
v = this.acc_g_y;
else if (acceleration_ === 2)
v = this.acc_g_z;
else if (acceleration_ === 3)
v = this.acc_x;
else if (acceleration_ === 4)
v = this.acc_y;
else if (acceleration_ === 5)
v = this.acc_z;
return cr.do_cmp(v, cmp_, angle_);
};
Cnds.prototype.OnNthTouchStart = function (touch_)
{
touch_ = Math.floor(touch_);
return touch_ === this.trigger_index;
};
Cnds.prototype.OnNthTouchEnd = function (touch_)
{
touch_ = Math.floor(touch_);
return touch_ === this.trigger_index;
};
Cnds.prototype.HasNthTouch = function (touch_)
{
touch_ = Math.floor(touch_);
return this.touches.length >= touch_ + 1;
};
Cnds.prototype.OnHoldGesture = function ()
{
return true;
};
Cnds.prototype.OnTapGesture = function ()
{
return true;
};
Cnds.prototype.OnDoubleTapGesture = function ()
{
return true;
};
Cnds.prototype.OnHoldGestureObject = function (type)
{
if (!type)
return false;
return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
};
Cnds.prototype.OnTapGestureObject = function (type)
{
if (!type)
return false;
return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
};
Cnds.prototype.OnDoubleTapGestureObject = function (type)
{
if (!type)
return false;
return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
};
Cnds.prototype.OnPermissionGranted = function (type)
{
return this.trigger_permission === type;
};
Cnds.prototype.OnPermissionDenied = function (type)
{
return this.trigger_permission === type;
};
pluginProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.RequestPermission = function (type)
{
var self = this;
var promise = Promise.resolve(true);
if (type === 0) // orientation
{
if (window["DeviceOrientationEvent"] && window["DeviceOrientationEvent"]["requestPermission"])
{
promise = window["DeviceOrientationEvent"]["requestPermission"]()
.then(function (state)
{
return state === "granted";
});
}
}
else // motion
{
if (window["DeviceMotionEvent"] && window["DeviceMotionEvent"]["requestPermission"])
{
promise = window["DeviceMotionEvent"]["requestPermission"]()
.then(function (state)
{
return state === "granted";
});
}
}
promise.then(function (result)
{
self.trigger_permission = type;
if (result)
self.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnPermissionGranted, self);
else
self.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnPermissionDenied, self);
});
};
pluginProto.acts = new Acts();
function Exps() {};
Exps.prototype.TouchCount = function (ret)
{
ret.set_int(this.touches.length);
};
Exps.prototype.X = function (ret, layerparam)
{
var index = this.getTouchIndex;
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxX = layer.parallaxX;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxX = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxX = oldParallaxX;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
else
ret.set_float(0);
}
};
Exps.prototype.XAt = function (ret, index, layerparam)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxX = layer.parallaxX;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxX = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxX = oldParallaxX;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
else
ret.set_float(0);
}
};
Exps.prototype.XForID = function (ret, id, layerparam)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxX = layer.parallaxX;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxX = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(touch.x, touch.y, true));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxX = oldParallaxX;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(touch.x, touch.y, true));
else
ret.set_float(0);
}
};
Exps.prototype.Y = function (ret, layerparam)
{
var index = this.getTouchIndex;
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxY = layer.parallaxY;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxY = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxY = oldParallaxY;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
else
ret.set_float(0);
}
};
Exps.prototype.YAt = function (ret, index, layerparam)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxY = layer.parallaxY;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxY = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxY = oldParallaxY;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
else
ret.set_float(0);
}
};
Exps.prototype.YForID = function (ret, id, layerparam)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxY = layer.parallaxY;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxY = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(touch.x, touch.y, false));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxY = oldParallaxY;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(touch.x, touch.y, false));
else
ret.set_float(0);
}
};
Exps.prototype.AbsoluteX = function (ret)
{
if (this.touches.length)
ret.set_float(this.touches[0].x);
else
ret.set_float(0);
};
Exps.prototype.AbsoluteXAt = function (ret, index)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
ret.set_float(this.touches[index].x);
};
Exps.prototype.AbsoluteXForID = function (ret, id)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
ret.set_float(touch.x);
};
Exps.prototype.AbsoluteY = function (ret)
{
if (this.touches.length)
ret.set_float(this.touches[0].y);
else
ret.set_float(0);
};
Exps.prototype.AbsoluteYAt = function (ret, index)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
ret.set_float(this.touches[index].y);
};
Exps.prototype.AbsoluteYForID = function (ret, id)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
ret.set_float(touch.y);
};
Exps.prototype.SpeedAt = function (ret, index)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
var t = this.touches[index];
var dist = cr.distanceTo(t.x, t.y, t.lastx, t.lasty);
var timediff = (t.time - t.lasttime) / 1000;
if (timediff <= 0)
ret.set_float(0);
else
ret.set_float(dist / timediff);
};
Exps.prototype.SpeedForID = function (ret, id)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
var dist = cr.distanceTo(touch.x, touch.y, touch.lastx, touch.lasty);
var timediff = (touch.time - touch.lasttime) / 1000;
if (timediff <= 0)
ret.set_float(0);
else
ret.set_float(dist / timediff);
};
Exps.prototype.AngleAt = function (ret, index)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
var t = this.touches[index];
ret.set_float(cr.to_degrees(cr.angleTo(t.lastx, t.lasty, t.x, t.y)));
};
Exps.prototype.AngleForID = function (ret, id)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
ret.set_float(cr.to_degrees(cr.angleTo(touch.lastx, touch.lasty, touch.x, touch.y)));
};
Exps.prototype.Alpha = function (ret)
{
ret.set_float(this.getAlpha());
};
Exps.prototype.Beta = function (ret)
{
ret.set_float(this.getBeta());
};
Exps.prototype.Gamma = function (ret)
{
ret.set_float(this.getGamma());
};
Exps.prototype.AccelerationXWithG = function (ret)
{
ret.set_float(this.acc_g_x);
};
Exps.prototype.AccelerationYWithG = function (ret)
{
ret.set_float(this.acc_g_y);
};
Exps.prototype.AccelerationZWithG = function (ret)
{
ret.set_float(this.acc_g_z);
};
Exps.prototype.AccelerationX = function (ret)
{
ret.set_float(this.acc_x);
};
Exps.prototype.AccelerationY = function (ret)
{
ret.set_float(this.acc_y);
};
Exps.prototype.AccelerationZ = function (ret)
{
ret.set_float(this.acc_z);
};
Exps.prototype.TouchIndex = function (ret)
{
ret.set_int(this.trigger_index);
};
Exps.prototype.TouchID = function (ret)
{
ret.set_float(this.trigger_id);
};
Exps.prototype.WidthForID = function (ret, id)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
ret.set_float(touch.width);
};
Exps.prototype.HeightForID = function (ret, id)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
ret.set_float(touch.height);
};
Exps.prototype.PressureForID = function (ret, id)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
ret.set_float(touch.pressure);
};
pluginProto.exps = new Exps();
}());
;
;
cr.plugins_.aekiro_proui2 = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.aekiro_proui2.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
this.touches = [];
this.mouseDown = false;
this.touchDown = false;
this.cursor = {x:null, y:null};
this._callbackObjs = {};
this._callbackObjs["touch"] = [];
this._callbackObjs["wheel"] = [];
this.handled = false;
};
var instanceProto = pluginProto.Instance.prototype;
var dummyoffset = {left: 0, top: 0};
instanceProto.findTouch = function (id)
{
var i, len;
for (i = 0, len = this.touches.length; i < len; i++)
{
if (this.touches[i]["id"] === id)
return i;
}
return -1;
};
var theInstance = null;
var touchinfo_cache = [];
function AllocTouchInfo(x, y, id, index)
{
var ret;
if (touchinfo_cache.length)
ret = touchinfo_cache.pop();
else
ret = new TouchInfo();
ret.init(x, y, id, index);
return ret;
};
function ReleaseTouchInfo(ti)
{
if (touchinfo_cache.length < 100)
touchinfo_cache.push(ti);
};
var GESTURE_HOLD_THRESHOLD = 15; // max px motion for hold gesture to register
var GESTURE_HOLD_TIMEOUT = 500; // time for hold gesture to register
var GESTURE_TAP_TIMEOUT = 333; // time for tap gesture to register
var GESTURE_DOUBLETAP_THRESHOLD = 25; // max distance apart for taps to be
function TouchInfo()
{
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["id"] = 0;
this.startindex = 0;
this.triggeredHold = false;
this.tooFarForHold = false;
};
TouchInfo.prototype.init = function (x, y, id, index)
{
var nowtime = cr.performance_now();
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;
this.width = 0;
this.height = 0;
this.pressure = 0;
this["id"] = id;
this.startindex = index;
this.triggeredHold = false;
this.tooFarForHold = false;
};
TouchInfo.prototype.update = function (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.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) >= GESTURE_HOLD_THRESHOLD)
{
this.tooFarForHold = true;
}
};
var lastTapX = -1000;
var lastTapY = -1000;
var lastTapTime = -10000;
TouchInfo.prototype.maybeTriggerTap = function (inst, index)
{
if (this.triggeredHold)
return;
var nowtime = cr.performance_now();
if (nowtime - this.starttime <= GESTURE_TAP_TIMEOUT && !this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) < GESTURE_HOLD_THRESHOLD)
{
inst.trigger_index = this.startindex;
inst.trigger_id = this["id"];
inst.getTouchIndex = index;
if ((nowtime - lastTapTime <= GESTURE_TAP_TIMEOUT * 2) && cr.distanceTo(lastTapX, lastTapY, this.x, this.y) < GESTURE_DOUBLETAP_THRESHOLD)
{
inst.curTouchX = this.x;
inst.curTouchY = this.y;
lastTapX = -1000;
lastTapY = -1000;
lastTapTime = -10000;
}
else
{
inst.curTouchX = this.x;
inst.curTouchY = this.y;
lastTapX = this.x;
lastTapY = this.y;
lastTapTime = nowtime;
}
inst.getTouchIndex = 0;
}
};
instanceProto.onCreate = function()
{
theInstance = this;
this.isWindows8 = !!(typeof window["c2isWindows8"] !== "undefined" && window["c2isWindows8"]);
this.curTouchX = 0;
this.curTouchY = 0;
this.trigger_index = 0;
this.trigger_id = 0;
this.getTouchIndex = 0;
this.useMouseInput = true;
var elem = (this.runtime.fullscreen_mode > 0) ? document : this.runtime.canvas;
var elem2 = document;
if (this.runtime.isDirectCanvas)
elem2 = elem = window["Canvas"];
else if (this.runtime.isCocoonJs)
elem2 = elem = window;
var self = this;
if (typeof PointerEvent !== "undefined")
{
elem.addEventListener("pointerdown",
function(info) {
self.onPointerStart(info);
},
false
);
elem.addEventListener("pointermove",
function(info) {
self.onPointerMove(info);
},
false
);
elem2.addEventListener("pointerup",
function(info) {
self.onPointerEnd(info, false);
},
false
);
elem2.addEventListener("pointercancel",
function(info) {
self.onPointerEnd(info, true);
},
false
);
if (this.runtime.canvas)
{
this.runtime.canvas.addEventListener("MSGestureHold", function(e) {
e.preventDefault();
}, false);
document.addEventListener("MSGestureHold", function(e) {
e.preventDefault();
}, false);
this.runtime.canvas.addEventListener("gesturehold", function(e) {
e.preventDefault();
}, false);
document.addEventListener("gesturehold", function(e) {
e.preventDefault();
}, false);
}
}
else if (window.navigator["msPointerEnabled"])
{
elem.addEventListener("MSPointerDown",
function(info) {
self.onPointerStart(info);
},
false
);
elem.addEventListener("MSPointerMove",
function(info) {
self.onPointerMove(info);
},
false
);
elem2.addEventListener("MSPointerUp",
function(info) {
self.onPointerEnd(info, false);
},
false
);
elem2.addEventListener("MSPointerCancel",
function(info) {
self.onPointerEnd(info, true);
},
false
);
if (this.runtime.canvas)
{
this.runtime.canvas.addEventListener("MSGestureHold", function(e) {
e.preventDefault();
}, false);
document.addEventListener("MSGestureHold", function(e) {
e.preventDefault();
}, false);
}
}
else
{
elem.addEventListener("touchstart",
function(info) {
self.onTouchStart(info);
},
false
);
elem.addEventListener("touchmove",
function(info) {
self.onTouchMove(info);
},
false
);
elem2.addEventListener("touchend",
function(info) {
self.onTouchEnd(info, false);
},
false
);
elem2.addEventListener("touchcancel",
function(info) {
self.onTouchEnd(info, true);
},
false
);
}
if (this.useMouseInput && !this.runtime.isDomFree)
{
jQuery(document).mousemove(
function(info) {
self.onMouseMove(info);
}
);
jQuery(document).mousedown(
function(info) {
self.onMouseDown(info);
}
);
jQuery(document).mouseup(
function(info) {
self.onMouseUp(info);
}
);
}
if (!this.runtime.isDomFree)
{
var wheelevent = function(info){
self.onWheel(info);
};
document.addEventListener("mousewheel", wheelevent, false);
document.addEventListener("DOMMouseScroll", wheelevent, false);
}
this.runtime.tick2Me(this);
this.enable = true;
this.lastTouchX = null;
this.lastTouchY = null;
cr.proui = this;
this.cssURL = this.properties[0];
this.fontFamily = this.properties[1];
this.firstFrame = true;
/*The following is to get around not being able to destroy other instance in onDestroy of an instance,
cf onDestroy of radiogroup
*/
var runtime = this.runtime;
this.toBeDestroyed = [];
this.currentDialogs = [];
this.currentDialogs_lastResetTick = 0;
this.tags = {};
this.tags_lastResetTick = 0;
this.iter = 0;
this.notRegister = false;
};
instanceProto.getIter = function(){
this.iter++;
return this.iter;
};
instanceProto.setNoRegister = function(){
};
instanceProto.addTag = function(tag,inst){
if(this.runtime.extra.notRegister || !tag){
return;
}
/*if(this.runtime.changelayout && this.tags_lastResetTick != this.runtime.tickcount){
this.tags = {} ;
this.tags_lastResetTick = this.runtime.tickcount;
}*/
if(this.tags.hasOwnProperty(tag)){
console.error("PROUI: Tag %s already exist !",tag);
return;
}
this.tags[tag] = inst;
};
instanceProto.removeTag = function(tag){
delete this.tags[tag];
};
instanceProto.addDialog = function(behavior){
if(this.runtime.changelayout && this.currentDialogs_lastResetTick != this.runtime.tickcount){
this.currentDialogs.length = 0;
this.currentDialogs_lastResetTick = this.runtime.tickcount;
}
this.currentDialogs.push(behavior);
};
instanceProto.isModalDialogOpened = function(){
for (var i = 0; i < this.currentDialogs.length; i++) {
if(this.currentDialogs[i].isModal){
return true;
}
}
return false;
};
instanceProto.removeDialog = function(behavior){
this.removeFromArray(this.currentDialogs,behavior);
};
instanceProto.removeFromArray = function(array,e){
for (var i = 0,l=array.length; i < l; i++) {
if(array[i] == e){
array.splice(i, 1);
return;
}
}
};
instanceProto.clearDestroyList = function (){
var toBeDestroyed = this.toBeDestroyed;
for (var i = 0,l=toBeDestroyed.length; i < l; i++) {
this.runtime.DestroyInstance(toBeDestroyed[i]);
}
toBeDestroyed.length = 0;
};
instanceProto.playAudio = function (fileName){
this.getDependency(cr.plugins_.Audio,"audio");
if(this["audio"]){
cr.plugins_.Audio.prototype.acts.PlayByName.call(this["audio"],0,fileName, 0, 0, "sound");
}else{
console.error("ProUI: Please add the Audio plugin to the project.");
}
};
instanceProto.getDependency = function (dependency, dependencyRef)
{
if (this[dependencyRef] != null){
return this[dependencyRef];
}
if(!dependency){
console.error("ProUI: Can not find the "+dependencyRef+" object.");
return;
}
var plugins = this.runtime.types
var name, inst;
for (name in plugins)
{
inst = plugins[name].instances[0];
if (inst instanceof dependency.prototype.Instance)
{
this[dependencyRef] = inst;
return this[dependencyRef];
}
}
if(!this[dependencyRef]){
console.error("ProUI: Can not find "+dependencyRef+" object.");
}
};
instanceProto.isTypeValid = function (inst,types,errorMsg){
var test;
for (var i = 0, l= types.length; i < l; i++) {
test = types[i]?(inst.type.plugin instanceof types[i]):false;
if(test){
return;
}
}
throw new Error(errorMsg);
};
/*behinstProto.runCallback = function ()
{
if(this.callbackName == ""){
return;
}
var params = this.callbackParams.split(",");
if(this.callbackName[0]=="$"){ //$41$transitionToLayout
var callback = this.callbackName.split("$");
console.log(callback);
var inst = this.runtime.getObjectByUID(parseInt(callback[1]));
if(inst){
console.log(inst.type);
}
}else{
c2_callFunction(this.callbackName,params);
}
};*/
instanceProto.runCallback = function (callbackName,callbackParams)
{
if(callbackName == ""){
return;
}
var params = callbackParams.split(",");
var callFunction = window["c2_callFunction"];
if(callFunction){
callFunction(callbackName,params);
}else{
console.error("ProUI : Please add the Function plugin to the project.");
}
};
instanceProto.validateSimpleValue = function(value, default_value)
{
var o;
if (value === true){
o = 1;
}
else if (value === false){
o = 0;
}
else if (value == null || value == undefined || typeof(value) == "object")
{
if (default_value != null && default_value != undefined)
o = default_value;
else
o = 0;
}
else{
o = value;
}
return o;
};
instanceProto.HookMe = function (obj,types)
{
var type;
for (var i = 0,l=types.length; i < l; i++) {
type = types[i];
this._callbackObjs[type].push(obj);
}
};
instanceProto.UnHookMe = function (obj,types)
{
var type;
for (var i = 0,l=types.length; i < l; i++) {
type = types[i];
cr.arrayFindRemove(this._callbackObjs[type], obj);
}
};
function getThisBehavior(inst,behaviorProto)
{
var i, len;
for (i = 0, len = inst.behavior_insts.length; i < len; i++)
{
if (inst.behavior_insts[i] instanceof behaviorProto.Instance)
return inst.behavior_insts[i];
}
return null;
};
/*var dispatchTouchStart = function(touchX, touchY)
{
var instances = this.my_instances.valuesRef();
var instance;
var lx, ly;
var objectInstances = [];
for (var i=0,l=instances.length; i<l; i++ )
{
instance = instances[i];
if (!instance)
continue;
if(!instance.layer.visible || !instance.visible)
continue;
lx = instance.layer.canvasToLayer(touchX, touchY, true);
ly = instance.layer.canvasToLayer(touchX, touchY, false);
instance.update_bbox();
if (instance.contains_pt(lx, ly))
objectInstances.push(instance);
}
if (objectInstances.length == 0)
return;
var maxZInstance = objectInstances[0];
for (var i=1,l=objectInstances.length; i<l; i++)
{
if ( ( objectInstances[i].layer.index > maxZInstance.layer.index) || ( (objectInstances[i].layer.index == maxZInstance.layer.index) && (objectInstances[i].get_zindex() > maxZInstance.get_zindex()) ) )
{
maxZInstance = objectInstances[i];
}
}
var maxZInstanceBehavior = getThisBehavior(maxZInstance,this);
if(maxZInstanceBehavior.OnTouchStart){
maxZInstanceBehavior.OnTouchStart();
}
objectInstances.length = 0;
};*/
var dispatchTouchStart = function(touchX, touchY)
{
var instances = this.my_instances.valuesRef();
var instance;
var instanceBehavior;
var lx, ly;
for (var i=0,l=instances.length; i<l; i++ )
{
instance = instances[i];
if (!instance)
continue;
if(!instance.layer.visible || !instance.visible)
continue;
lx = instance.layer.canvasToLayer(touchX, touchY, true);
ly = instance.layer.canvasToLayer(touchX, touchY, false);
instance.update_bbox();
instanceBehavior = getThisBehavior(instance,this);
if(instanceBehavior.OnAnyTouchStart){
instanceBehavior.OnAnyTouchStart();
}
if (instance.contains_pt(lx, ly)){
if(instanceBehavior.OnTouchStart){
instanceBehavior.OnTouchStart();
}
}
}
};
var dispatchTouchEnd = function(touchX, touchY)
{
var instances = this.my_instances.valuesRef();
var instance;
var instanceBehavior;
var tx,ty;
for (var i=0,l=instances.length; i<l; i++ )
{
instance = instances[i];
if (!instance)
continue;
/*if(!instance.layer.visible || !instance.visible)
continue;*/
tx = instance.layer.canvasToLayer(touchX, touchY, true);
ty = instance.layer.canvasToLayer(touchX, touchY, false);
instanceBehavior = getThisBehavior(instance,this);
if(instanceBehavior.OnAnyTouchEnd){
instanceBehavior.OnAnyTouchEnd(tx, ty);
}
}
};
var dispatchWheel = function(triggerDir)
{
var instances = this.my_instances.valuesRef();
var instance;
var instanceBehavior;
for (var i=0,l=instances.length; i<l; i++ )
{
instance = instances[i];
if (!instance)
continue;
instanceBehavior = getThisBehavior(instance,this);
if(instanceBehavior.OnWheel){
instanceBehavior.OnWheel(triggerDir);
}
}
};
instanceProto.onWheel = function (info)
{
var delta = info.wheelDelta ? info.wheelDelta : info.detail ? -info.detail : 0;
this.triggerDir = (delta < 0 ? 0 : 1);
this.handled = false;
this.runtime.isInUserInputEvent = true;
for (var i=0,l=this._callbackObjs["wheel"].length; i<l; i++)
{
this.handled = true;
dispatchWheel.call(this._callbackObjs["wheel"][i],this.triggerDir);
}
this.runtime.isInUserInputEvent = false;
if (this.handled && cr.isCanvasInputEvent(info))
info.preventDefault();
};
instanceProto.onPointerMove = function (info)
{
if (!this.enable)
return;
if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
return;
if (info.preventDefault)
info.preventDefault();
var i = this.findTouch(info["pointerId"]);
var nowtime = cr.performance_now();
if (i >= 0)
{
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
var t = this.touches[i];
if (nowtime - t.time < 2)
return;
t.update(nowtime, info.pageX - offset.left, info.pageY - offset.top, info.width || 0, info.height || 0, info.pressure || 0);
var touchx = info.pageX - offset.left;
var touchy = info.pageY - offset.top;
/*var cnt=this._callbackObjs.length, hooki;
for (hooki=0; hooki<cnt; hooki++)
{
if (this._callbackObjs[hooki].OnTouchMove)
this._callbackObjs[hooki].OnTouchMove(t["identifier"], touchx, touchy);
} */
}
};
instanceProto.onPointerStart = function (info)
{
if (!this.enable)
return;
if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
return;
if (info.preventDefault && cr.isCanvasInputEvent(info))
info.preventDefault();
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
var touchx = info.pageX - offset.left;
var touchy = info.pageY - offset.top;
var nowtime = cr.performance_now();
this.trigger_index = this.touches.length;
this.trigger_id = info["pointerId"];
this.touches.push(AllocTouchInfo(touchx, touchy, info["pointerId"], this.trigger_index));
this.runtime.isInUserInputEvent = true;
this.curTouchX = touchx;
this.curTouchY = touchy;
var hooki, cnt=this._callbackObjs["touch"].length;
for (hooki=0; hooki<cnt; hooki++)
{
dispatchTouchStart.call(this._callbackObjs["touch"][hooki],this.curTouchX, this.curTouchY);
}
this.runtime.isInUserInputEvent = false;
};
instanceProto.onPointerEnd = function (info, isCancel)
{
if (!this.enable)
return;
if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
return;
if (info.preventDefault && cr.isCanvasInputEvent(info))
info.preventDefault();
var i = this.findTouch(info["pointerId"]);
this.trigger_index = (i >= 0 ? this.touches[i].startindex : -1);
this.trigger_id = (i >= 0 ? this.touches[i]["id"] : -1);
this.runtime.isInUserInputEvent = true;
if (i >= 0)
{
this.lastTouchX = this.touches[i].x;
this.lastTouchY = this.touches[i].y;
}
var cnt=this._callbackObjs["touch"].length, hooki;
for (hooki=0; hooki<cnt; hooki++)
{
dispatchTouchEnd.call(this._callbackObjs["touch"][hooki],this.lastTouchX,this.lastTouchY);
}
if (i >= 0)
{
if (!isCancel)
this.touches[i].maybeTriggerTap(this, i);
ReleaseTouchInfo(this.touches[i]);
this.touches.splice(i, 1);
}
this.runtime.isInUserInputEvent = false;
};
instanceProto.onTouchMove = function (info)
{
if (!this.enable)
return;
if (info.preventDefault)
info.preventDefault();
var nowtime = cr.performance_now();
var i, len, t, u;
var cnt=this._callbackObjs["touch"].length, hooki;
for (i = 0, len = info.changedTouches.length; i < len; i++)
{
t = info.changedTouches[i];
var j = this.findTouch(t["identifier"]);
if (j >= 0)
{
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
u = this.touches[j];
if (nowtime - u.time < 2)
continue;
var touchWidth = (t.radiusX || t.webkitRadiusX || t.mozRadiusX || t.msRadiusX || 0) * 2;
var touchHeight = (t.radiusY || t.webkitRadiusY || t.mozRadiusY || t.msRadiusY || 0) * 2;
var touchForce = t.force || t.webkitForce || t.mozForce || t.msForce || 0;
u.update(nowtime, t.pageX - offset.left, t.pageY - offset.top, touchWidth, touchHeight, touchForce);
var touchx = t.pageX - offset.left;
var touchy = t.pageY - offset.top;
/*for (hooki=0; hooki<cnt; hooki++)
{
if (this._callbackObjs["touch"][hooki].OnTouchMove)
this._callbackObjs["touch"][hooki].OnTouchMove(t["identifier"], touchx, touchy);
}*/
}
}
};
instanceProto.onTouchStart = function (info)
{
if (!this.enable)
return;
if (info.preventDefault && cr.isCanvasInputEvent(info))
info.preventDefault();
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
var nowtime = cr.performance_now();
this.runtime.isInUserInputEvent = true;
var i, len, t, j;
var cnt=this._callbackObjs["touch"].length, hooki;
for (i = 0, len = info.changedTouches.length; i < len; i++)
{
t = info.changedTouches[i];
j = this.findTouch(t["identifier"]);
if (j !== -1)
continue;
var touchx = t.pageX - offset.left;
var touchy = t.pageY - offset.top;
this.trigger_index = this.touches.length;
this.trigger_id = t["identifier"];
this.touches.push(AllocTouchInfo(touchx, touchy, t["identifier"], this.trigger_index));
this.curTouchX = touchx;
this.curTouchY = touchy;
for (hooki=0; hooki<cnt; hooki++)
{
dispatchTouchStart.call(this._callbackObjs["touch"][hooki],this.curTouchX, this.curTouchY);
}
}
this.runtime.isInUserInputEvent = false;
};
instanceProto.onTouchEnd = function (info, isCancel)
{
if (!this.enable)
return;
if (info.preventDefault && cr.isCanvasInputEvent(info))
info.preventDefault();
this.runtime.isInUserInputEvent = true;
var i, len, t, j;
var cnt=this._callbackObjs["touch"].length, hooki;
for (i = 0, len = info.changedTouches.length; i < len; i++)
{
t = info.changedTouches[i];
j = this.findTouch(t["identifier"]);
if (j >= 0)
{
this.trigger_index = this.touches[j].startindex;
this.trigger_id = this.touches[j]["id"];
this.lastTouchX = this.touches[j].x;
this.lastTouchY = this.touches[j].y;
for (hooki=0; hooki<cnt; hooki++)
{
dispatchTouchEnd.call(this._callbackObjs["touch"][hooki],this.lastTouchX,this.lastTouchY);
}
if (!isCancel)
this.touches[j].maybeTriggerTap(this, j);
ReleaseTouchInfo(this.touches[j]);
this.touches.splice(j, 1);
}
}
this.runtime.isInUserInputEvent = false;
};
instanceProto.updateCursor = function(info)
{
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
this.cursor.x = info.pageX - offset.left;
this.cursor.y = info.pageY - offset.top;
}
instanceProto.onMouseDown = function(info)
{
if (!this.enable)
return;
this.updateCursor(info);
this.mouseDown = true;
if (info.preventDefault && this.runtime.had_a_click && !this.runtime.isMobile)
info.preventDefault();
var index = this.findTouch(0);
if (index !== -1)
{
ReleaseTouchInfo(this.touches[index]);
cr.arrayRemove( this.touches, index );
}
var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
var fakeinfo = { changedTouches: [t] };
this.onTouchStart(fakeinfo);
};
instanceProto.onMouseMove = function(info)
{
if (!this.enable)
return;
this.updateCursor(info);
if (!this.mouseDown)
return;
var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
var fakeinfo = { changedTouches: [t] };
this.onTouchMove(fakeinfo);
};
instanceProto.onMouseUp = function(info)
{
if (!this.enable)
return;
this.updateCursor(info);
this.mouseDown = false;
if (info.preventDefault && this.runtime.had_a_click && !this.runtime.isMobile)
info.preventDefault();
this.runtime.had_a_click = true;
var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
var fakeinfo = { changedTouches: [t] };
this.onTouchEnd(fakeinfo);
};
instanceProto.tick2 = function()
{
if (!this.enable)
return;
var i, len, t;
var nowtime = cr.performance_now();
for (i = 0, len = this.touches.length; i < len; ++i)
{
t = this.touches[i];
if (t.time <= nowtime - 50)
t.lasttime = nowtime;
}
this.lastTouchX = null;
this.lastTouchY = null;
/*if(this.firstFrame){
this.firstFrame = false;
}*/
};
function Cnds() {};
Cnds.IsDialogOpened = function ()
{
return this.currentDialogs.length;
};
pluginProto.cnds = new Cnds();
function Acts() {};
pluginProto.acts = new Acts();
Acts.prototype.SetEnable = function(en)
{
this.enable = (en==1);
};
function Exps() {};
pluginProto.exps = new Exps();
instanceProto.TouchCount = function (ret)
{
ret.set_int(this.touches.length);
};
instanceProto.X = function (layerparam)
{
var index = this.getTouchIndex;
var result;
if (index < 0 || index >= this.touches.length)
{
result = 0;
return result;
}
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxX = layer.parallaxX;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxX = 1.0;
layer.angle = 0;
result = layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true);
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxX = oldParallaxX;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
result = layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true);
else
result = 0;
}
return result;
};
instanceProto.XAt = function (ret, index, layerparam)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxX = layer.parallaxX;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxX = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxX = oldParallaxX;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
else
ret.set_float(0);
}
};
instanceProto.XForID = function (ret, id, layerparam)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxX = layer.parallaxX;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxX = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(touch.x, touch.y, true));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxX = oldParallaxX;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(touch.x, touch.y, true));
else
ret.set_float(0);
}
};
instanceProto.Y = function (layerparam)
{
var index = this.getTouchIndex;
var result;
if (index < 0 || index >= this.touches.length)
{
result = 0;
return;
}
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxY = layer.parallaxY;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxY = 1.0;
layer.angle = 0;
result = layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false);
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxY = oldParallaxY;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
result = layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false);
else
result = 0;
}
return result;
};
instanceProto.YAt = function (ret, index, layerparam)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxY = layer.parallaxY;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxY = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxY = oldParallaxY;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
else
ret.set_float(0);
}
};
instanceProto.YForID = function (ret, id, layerparam)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxY = layer.parallaxY;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxY = 1.0;
layer.angle = 0;
ret.set_float(layer.canvasToLayer(touch.x, touch.y, false));
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxY = oldParallaxY;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
ret.set_float(layer.canvasToLayer(touch.x, touch.y, false));
else
ret.set_float(0);
}
};
instanceProto.AbsoluteX = function (ret)
{
if (this.touches.length)
ret.set_float(this.touches[0].x);
else
ret.set_float(0);
};
instanceProto.AbsoluteXAt = function (ret, index)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
ret.set_float(this.touches[index].x);
};
instanceProto.AbsoluteXForID = function (ret, id)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
ret.set_float(touch.x);
};
instanceProto.AbsoluteY = function (ret)
{
if (this.touches.length)
ret.set_float(this.touches[0].y);
else
ret.set_float(0);
};
instanceProto.AbsoluteYAt = function (ret, index)
{
index = Math.floor(index);
if (index < 0 || index >= this.touches.length)
{
ret.set_float(0);
return;
}
ret.set_float(this.touches[index].y);
};
instanceProto.AbsoluteYForID = function (ret, id)
{
var index = this.findTouch(id);
if (index < 0)
{
ret.set_float(0);
return;
}
var touch = this.touches[index];
ret.set_float(touch.y);
};
instanceProto.IsInTouch = function ()
{
return (this.touches.length > 0);
};
instanceProto.CursorX = function (layerparam)
{
if (this.cursor.x == null)
return null;
var x;
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxX = layer.parallaxX;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxX = 1.0;
layer.angle = 0;
x = layer.canvasToLayer(this.cursor.x, this.cursor.y, true);
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxX = oldParallaxX;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
x = layer.canvasToLayer(this.cursor.x, this.cursor.y, true);
else
x = 0;
}
return x;
};
instanceProto.CursorY = function (layerparam)
{
if (this.cursor.y == null)
return null;
var y;
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
if (cr.is_undefined(layerparam))
{
layer = this.runtime.getLayerByNumber(0);
oldScale = layer.scale;
oldZoomRate = layer.zoomRate;
oldParallaxX = layer.parallaxX;
oldAngle = layer.angle;
layer.scale = 1;
layer.zoomRate = 1.0;
layer.parallaxX = 1.0;
layer.angle = 0;
y = layer.canvasToLayer(this.cursor.x, this.cursor.y, false);
layer.scale = oldScale;
layer.zoomRate = oldZoomRate;
layer.parallaxX = oldParallaxX;
layer.angle = oldAngle;
}
else
{
if (cr.is_number(layerparam))
layer = this.runtime.getLayerByNumber(layerparam);
else
layer = this.runtime.getLayerByName(layerparam);
if (layer)
y = layer.canvasToLayer(this.cursor.x, this.cursor.y, false);
else
y = 0;
}
return y;
};
instanceProto.CursorAbsoluteX = function ()
{
return this.cursor.x;
};
instanceProto.CursorAbsoluteY = function ()
{
return this.cursor.y;
};
}());
;
;
cr.plugins_.rex_bbcodeText = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins_.rex_bbcodeText.prototype;
pluginProto.onCreate = function ()
{
pluginProto.acts.SetWidth = function (w)
{
if (this.width !== w)
{
this.width = w;
this.set_bbox_changed();
if (!this.isCanvasSizeLocked)
this.render_text(this.is_force_render);
}
};
};
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
typeProto.onLostWebGLContext = function ()
{
if (this.is_family)
return;
var i, len, inst;
for (i = 0, len = this.instances.length; i < len; i++)
{
inst = this.instances[i];
inst.mycanvas = null;
inst.myctx = null;
inst.mytex = null;
}
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
this.text_changed = true;
};
var instanceProto = pluginProto.Instance.prototype;
var requestedWebFonts = {}; // already requested web fonts have an entry here
var lineJoinMode = ["miter", "round", "bevel"];
instanceProto.onCreate = function()
{
this.text = "";
this.set_text(this.properties[0]);
this.visible = (this.properties[1] === 0); // 0=visible, 1=invisible
this.font = this.properties[2];
this.color = this.properties[3];
this.halign = this.properties[4]; // 0=left, 1=center, 2=right
this.valign = this.properties[5]; // 0=top, 1=center, 2=bottom
this.textShadow = "";
this.wrapbyword = (this.properties[7] === 0); // 0=word, 1=character
this.lastwidth = this.width;
this.lastwrapwidth = this.width;
this.lastheight = this.height;
this.line_height_offset = this.properties[8];
this.baseLine_mode = this.properties[9];
this.vshift = this.properties[10];
this.is_force_render = (this.properties[11] === 1);
this.LockCanvasSize( (this.properties[12] === 1), this.width, this.height);
this.facename = "";
this.fontstyle = "";
this.ptSize = 0;
this.textWidth = 0;
this.textHeight = 0;
this.parseFont();
this.mycanvas = null;
this.myctx = null;
this.mytex = null;
this.need_text_redraw = false;
this.last_render_tick = this.runtime.tickcount;
if (this.recycled)
this.rcTex.set(0, 0, 1, 1);
else
this.rcTex = new cr.rect(0, 0, 1, 1);
if (this.runtime.glwrap)
this.runtime.tickMe(this);
;
this._tag = null;
if (!this.recycled)
{
this.canvas_text = new CanvasText();
}
this.canvas_text.Reset(this);
this.canvas_text.textBaseline = (this.baseLine_mode === 0)? "alphabetic":"top";
this.canvas_text.stroke.lineWidth = this.properties[13];
this.canvas_text.stroke.lineJoin = lineJoinMode[this.properties[14]];
this.canvas_text.underline.thickness = this.properties[15];
this.canvas_text.underline.offset = this.properties[16];
this.setShadow(this.properties[17], this.properties[18], this.properties[19], this.properties[20]);
this.canvas_text.backgroundColor = this.properties[21];
if (this.text)
this.render_text(this.is_force_render);
};
instanceProto.parseFont = function ()
{
var arr = this.font.split(" ");
var i;
for (i = 0; i < arr.length; i++)
{
if (arr[i].substr(arr[i].length - 2, 2) === "pt")
{
this.ptSize = parseInt(arr[i].substr(0, arr[i].length - 2));
this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi...
if (i > 0)
this.fontstyle = arr[i - 1];
this.facename = arr[i + 1];
for (i = i + 2; i < arr.length; i++)
this.facename += " " + arr[i];
break;
}
}
};
instanceProto.saveToJSON = function ()
{
return {
"t": this.text,
"f": this.font,
"c": this.color,
"ha": this.halign,
"va": this.valign,
"wr": this.wrapbyword,
"lho": this.line_height_offset,
"vs": this.vshift,
"fn": this.facename,
"fs": this.fontstyle,
"ps": this.ptSize,
"pxh": this.pxHeight,
"tw": this.textWidth,
"th": this.textHeight,
"ts": this.textShadow,
"lrt": this.last_render_tick,
"bl": this.canvas_text.textBaseline,
"txtObj": this.canvas_text.saveToJSON(),
"isLcs": this.isCanvasSizeLocked,
"lcw": this.lockedCanvasWidth,
"lch": this.lockedCanvasHeight
};
};
instanceProto.loadFromJSON = function (o)
{
this.text = o["t"];
this.font = o["f"];
this.color = o["c"];
this.halign = o["ha"];
this.valign = o["va"];
this.wrapbyword = o["wr"];
this.line_height_offset = o["lho"];
this.vshift = o["vs"];
this.facename = o["fn"];
this.fontstyle = o["fs"];
this.ptSize = o["ps"];
this.pxHeight = o["pxh"];
this.textWidth = o["tw"];
this.textHeight = o["th"];
this.textShadow = o["ts"];
this.last_render_tick = o["lrt"];
this.text_changed = true;
this.lastwidth = this.width;
this.lastwrapwidth = this.width;
this.lastheight = this.height;
this.canvas_text.textBaseline = o["bl"];
this.canvas_text.loadFromJSON(o["txtObj"]);
this.isCanvasSizeLocked = o["isLcs"];
this.lockedCanvasWidth = o["lcw"];
this.lockedCanvasHeight = o["lch"];
};
instanceProto.tick = function ()
{
if (this.runtime.glwrap && this.mytex && (this.runtime.tickcount - this.last_render_tick >= 300))
{
var layer = this.layer;
this.update_bbox();
var bbox = this.bbox;
if (bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom)
{
this.runtime.glwrap.deleteTexture(this.mytex);
this.mytex = null;
this.myctx = null;
this.mycanvas = null;
}
}
};
instanceProto.onDestroy = function ()
{
this.myctx = null;
this.mycanvas = null;
if (this.runtime.glwrap && this.mytex)
this.runtime.glwrap.deleteTexture(this.mytex);
this.mytex = null;
};
instanceProto.updateFont = function ()
{
this.font = this.fontstyle + " " + this.ptSize.toString() + "pt " + this.facename;
this.render_text(this.is_force_render);
};
instanceProto.draw = function(ctx, glmode, is_ignore)
{
var isCtxSave = false;
var width = (this.isCanvasSizeLocked)? this.lockedCanvasWidth : this.width;
var height = (this.isCanvasSizeLocked)? this.lockedCanvasHeight : this.height;
ctx.globalAlpha = glmode ? 1 : this.opacity;
var myscale = 1;
if (glmode)
{
myscale = this.layer.getScale();
if (!isCtxSave)
{
ctx.save();
isCtxSave = true;
}
ctx.scale(myscale, myscale);
}
if (this.text_changed || width !== this.lastwrapwidth)
{
this.canvas_text.text_changed = true; // it will update pens (wordwrap) to redraw
this.text_changed = false;
this.lastwrapwidth = width;
}
this.update_bbox();
var penX = glmode ? 0 : this.bquad.tlx;
var penY = glmode ? 0 : this.bquad.tly;
if (this.runtime.pixel_rounding)
{
penX = (penX + 0.5) | 0;
penY = (penY + 0.5) | 0;
}
if (!glmode)
{
var isResized = (width !== this.width) || (height !== this.height);
var isRotated = (this.angle !== 0 );
if ( isRotated || isResized )
{
if (!isCtxSave)
{
ctx.save();
isCtxSave = true;
}
if (isResized)
{
var scalew = this.width/width;
var scaleh = this.height/height;
ctx.scale(scalew, scaleh);
ctx.translate(penX/scalew, penY/scaleh);
penX = 0;
penY = 0;
}
if (isRotated)
{
if ((penX !== 0) || (penY !== 0))
ctx.translate(penX, penY);
ctx.rotate(this.angle);
}
}
}
var line_height = this.pxHeight;
line_height += (this.line_height_offset * this.runtime.devicePixelRatio);
this.canvas_text.canvas = ctx.canvas;
this.canvas_text.context = ctx;
this.canvas_text.default_propScope.family = this.facename;
this.canvas_text.default_propScope.ptSize = this.ptSize.toString() + "pt";
this.canvas_text.default_propScope.style = this.fontstyle;
this.canvas_text.default_propScope.color = this.color;
this.canvas_text.default_propScope.shadow = this.textShadow;
this.canvas_text.lineHeight = line_height;
this.canvas_text.textInfo["text"] = this.text;
this.canvas_text.textInfo["x"] = penX;
this.canvas_text.textInfo["y"] = penY;
this.canvas_text.textInfo["boxWidth"] = width;
this.canvas_text.textInfo["boxHeight"] = height;
this.canvas_text.textInfo["ignore"] = is_ignore;
this.canvas_text.drawText();
if (isCtxSave)
ctx.restore();
this.last_render_tick = this.runtime.tickcount;
};
instanceProto.drawGL = function(glw)
{
if (this.width < 1 || this.height < 1)
return;
var need_redraw = this.text_changed || this.need_text_redraw;
this.need_text_redraw = false;
var layer_scale = this.layer.getScale();
var layer_angle = this.layer.getAngle();
var rcTex = this.rcTex;
var floatscaledwidth = layer_scale * this.width;
var floatscaledheight = layer_scale * this.height;
var scaledwidth = Math.ceil(floatscaledwidth);
var scaledheight = Math.ceil(floatscaledheight);
var halfw = this.runtime.draw_width / 2;
var halfh = this.runtime.draw_height / 2;
var canvaswidth = (!this.isCanvasSizeLocked)? scaledwidth : Math.ceil(layer_scale * this.lockedCanvasWidth);
var canvasheight = (!this.isCanvasSizeLocked)? scaledheight: Math.ceil(layer_scale * this.lockedCanvasHeight);
if (!this.myctx)
{
this.mycanvas = document.createElement("canvas");
this.mycanvas.width = canvaswidth;
this.mycanvas.height = canvasheight;
this.lastwidth = canvaswidth;
this.lastheight = canvasheight;
need_redraw = true;
this.myctx = this.mycanvas.getContext("2d");
}
if (canvaswidth !== this.lastwidth || canvasheight !== this.lastheight)
{
this.mycanvas.width = canvaswidth;
this.mycanvas.height = canvasheight;
if (this.mytex)
{
glw.deleteTexture(this.mytex);
this.mytex = null;
}
need_redraw = true;
}
if (need_redraw)
{
this.myctx.clearRect(0, 0, canvaswidth, canvasheight);
this.draw(this.myctx, true);
if (!this.mytex)
this.mytex = glw.createEmptyTexture(scaledwidth, scaledheight, this.runtime.linearSampling, this.runtime.isMobile);
glw.videoToTexture(this.mycanvas, this.mytex, this.runtime.isMobile);
}
this.lastwidth = canvaswidth;
this.lastheight = canvasheight;
glw.setTexture(this.mytex);
glw.setOpacity(this.opacity);
glw.resetModelView();
glw.translate(-halfw, -halfh);
glw.updateModelView();
var q = this.bquad;
var tlx = this.layer.layerToCanvas(q.tlx, q.tly, true, true);
var tly = this.layer.layerToCanvas(q.tlx, q.tly, false, true);
var trx = this.layer.layerToCanvas(q.trx, q.try_, true, true);
var try_ = this.layer.layerToCanvas(q.trx, q.try_, false, true);
var brx = this.layer.layerToCanvas(q.brx, q.bry, true, true);
var bry = this.layer.layerToCanvas(q.brx, q.bry, false, true);
var blx = this.layer.layerToCanvas(q.blx, q.bly, true, true);
var bly = this.layer.layerToCanvas(q.blx, q.bly, false, true);
if (this.runtime.pixel_rounding || (this.angle === 0 && layer_angle === 0))
{
var ox = ((tlx + 0.5) | 0) - tlx;
var oy = ((tly + 0.5) | 0) - tly
tlx += ox;
tly += oy;
trx += ox;
try_ += oy;
brx += ox;
bry += oy;
blx += ox;
bly += oy;
}
if (this.angle === 0 && layer_angle === 0)
{
trx = tlx + scaledwidth;
try_ = tly;
brx = trx;
bry = tly + scaledheight;
blx = tlx;
bly = bry;
rcTex.right = 1;
rcTex.bottom = 1;
}
else
{
rcTex.right = floatscaledwidth / scaledwidth;
rcTex.bottom = floatscaledheight / scaledheight;
}
glw.quadTex(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex);
glw.resetModelView();
glw.scale(layer_scale, layer_scale);
glw.rotateZ(-this.layer.getAngle());
glw.translate((this.layer.viewLeft + this.layer.viewRight) / -2, (this.layer.viewTop + this.layer.viewBottom) / -2);
glw.updateModelView();
this.last_render_tick = this.runtime.tickcount;
};
instanceProto._get_webgl_ctx = function ()
{
var inst = this;
var ctx = inst.myctx;
if (!ctx)
{
inst.mycanvas = document.createElement("canvas");
var scaledwidth = Math.ceil(inst.layer.getScale()*inst.width);
var scaledheight = Math.ceil(inst.layer.getAngle()*inst.height);
inst.mycanvas.width = scaledwidth;
inst.mycanvas.height = scaledheight;
inst.lastwidth = scaledwidth;
inst.lastheight = scaledheight;
inst.myctx = inst.mycanvas.getContext("2d");
ctx = inst.myctx;
}
return ctx;
};
instanceProto.fake_render = function ()
{
var inst = this;
var ctx = (this.runtime.enableWebGL)?
this._get_webgl_ctx():this.runtime.ctx;
inst.draw(ctx, null, true);
};
instanceProto.render_text = function (is_render_now)
{
if (is_render_now)
{
this.text_changed = true;
this.fake_render();
}
this.text_changed = true;
this.runtime.redraw = true;
};
instanceProto.set_text = function (txt)
{
if (this.text !== txt)
{
this.text = txt;
this.render_text(this.is_force_render);
}
};
instanceProto.setShadow = function(offsetX, offsetY, blur_, color_)
{
color_ = color_.replace(/ /g,'');
var shadow = offsetX.toString() + "px " + offsetY.toString() + "px " + blur_.toString() + "px " + color_;
this.textShadow = shadow;
};
instanceProto.LockCanvasSize = function(isLocked, width, height)
{
this.isCanvasSizeLocked = isLocked;
this.lockedCanvasWidth = width;
this.lockedCanvasHeight = height;
};
var copy_dict = function (in_obj, out_obj, is_merge)
{
if (out_obj == null)
out_obj = {};
if (!is_merge)
{
for (var k in out_obj)
{
if (!in_obj.hasOwnProperty(k))
delete out_obj[k];
}
}
for (var k in in_obj)
out_obj[k] = in_obj[k];
return out_obj;
};
instanceProto.getRawText = function (text)
{
return this.canvas_text.getRawText(text);
};
instanceProto.getSubText = function (start, end, text)
{
return this.canvas_text.getSubText(start, end, text);
};
instanceProto.copyPensMgr = function (pensMgr)
{
return this.canvas_text.copyPensMgr(pensMgr);
};
function Cnds() {};
pluginProto.cnds = new Cnds();
Cnds.prototype.CompareText = function(text_to_compare, case_sensitive)
{
if (case_sensitive)
return this.text == text_to_compare;
else
return cr.equals_nocase(this.text, text_to_compare);
};
function Acts() {};
pluginProto.acts = new Acts();
Acts.prototype.SetText = function(param)
{
if (cr.is_number(param) && param < 1e9)
param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
var text_to_set = param.toString();
this.set_text(text_to_set);
};
Acts.prototype.AppendText = function(param)
{
if (cr.is_number(param))
param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
var text_to_append = param.toString();
if (text_to_append.length > 0) // not empty
this.set_text(this.text+text_to_append);
};
Acts.prototype.SetFontFace = function (face_, style_)
{
var newstyle = "";
switch (style_) {
case 1: newstyle = "bold"; break;
case 2: newstyle = "italic"; break;
case 3: newstyle = "bold italic"; break;
}
if (face_ === this.facename && newstyle === this.fontstyle)
return; // no change
this.facename = face_;
this.fontstyle = newstyle;
this.updateFont();
};
Acts.prototype.SetFontSize = function (size_)
{
if (this.ptSize === size_)
return;
this.ptSize = size_;
this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi...
this.updateFont();
};
Acts.prototype.SetFontColor = function (rgb)
{
var newcolor;
if (typeof(rgb) == "number")
newcolor = "rgb(" + cr.GetRValue(rgb).toString() + "," + cr.GetGValue(rgb).toString() + "," + cr.GetBValue(rgb).toString() + ")";
else
newcolor = rgb;
if (newcolor === this.color)
return;
this.color = newcolor;
this.render_text(this.is_force_render);
};
Acts.prototype.SetWebFont = function (familyname_, cssurl_)
{
if (this.runtime.isDomFree)
{
cr.logexport("[Construct 2] Text plugin: 'Set web font' not supported on this platform - the action has been ignored");
return; // DC todo
}
var self = this;
var refreshFunc = (function () {
self.runtime.redraw = true;
self.text_changed = true;
});
var newfacename = "'" + familyname_ + "'";
if (requestedWebFonts.hasOwnProperty(cssurl_))
{
if (this.facename === newfacename)
return; // no change
this.facename = newfacename;
this.updateFont();
for (var i = 1; i < 10; i++)
{
setTimeout(refreshFunc, i * 100);
setTimeout(refreshFunc, i * 1000);
}
return;
}
var wf = document.createElement("link");
wf.href = cssurl_;
wf.rel = "stylesheet";
wf.type = "text/css";
wf.onload = refreshFunc;
document.getElementsByTagName('head')[0].appendChild(wf);
requestedWebFonts[cssurl_] = true;
this.facename = "'" + familyname_ + "'";
this.updateFont();
for (var i = 1; i < 10; i++)
{
setTimeout(refreshFunc, i * 100);
setTimeout(refreshFunc, i * 1000);
}
;
};
Acts.prototype.SetEffect = function (effect)
{
this.compositeOp = cr.effectToCompositeOp(effect);
cr.setGLBlend(this, effect, this.runtime.gl);
this.render_text(this.is_force_render);
};
Acts.prototype.SetFontStyle = function (style_)
{
var newstyle = "";
switch (style_) {
case 1: newstyle = "bold"; break;
case 2: newstyle = "italic"; break;
case 3: newstyle = "bold italic"; break;
}
if (newstyle === this.fontstyle)
return; // no change
this.fontstyle = newstyle;
this.updateFont();
};
Acts.prototype.SetFontFace2 = function (face_)
{
if (face_ === this.facename)
return; // no change
this.facename = face_;
this.updateFont();
};
Acts.prototype.SetLineHeight = function(line_height_offset)
{
if (this.line_height_offset === line_height_offset)
return;
this.line_height_offset = line_height_offset;
this.render_text(this.is_force_render);
};
Acts.prototype.SetHorizontalAlignment = function(align)
{
if (this.halign === align)
return;
this.halign = align; // 0=left, 1=center, 2=right
this.render_text(this.is_force_render);
};
Acts.prototype.SetVerticalAlignment = function(align)
{
if (this.valign === align)
return;
this.valign = align; // 0=top, 1=center, 2=bottom
this.render_text(this.is_force_render);
};
Acts.prototype.SetWrapping = function(wrap_mode)
{
wrap_mode = (wrap_mode === 0); // 0=word, 1=character
if (this.wrapbyword === wrap_mode)
return;
this.wrapbyword = wrap_mode;
this.render_text(this.is_force_render);
};
Acts.prototype.SetShadow = function(offsetX, offsetY, blur_, color_)
{
this.setShadow(offsetX, offsetY, blur_, color_);
this.render_text(this.is_force_render);
};
Acts.prototype.SetThickness = function(w)
{
if (w === this.canvas_text.underline.thickness)
return;
this.canvas_text.underline.thickness = w;
this.need_text_redraw = true;
this.runtime.redraw = true;
};
Acts.prototype.SetOffsetY = function(offset)
{
if (offset === this.canvas_text.underline.offset)
return;
this.canvas_text.underline.offset = offset;
this.need_text_redraw = true;
this.runtime.redraw = true;
};
Acts.prototype.SetStrokeLineWidth = function(w)
{
if (w === this.canvas_text.stroke.lineWidth)
return;
this.canvas_text.stroke.lineWidth = w;
this.need_text_redraw = true;
this.runtime.redraw = true;
};
Acts.prototype.SetStrokeLineJoin = function(m)
{
m = lineJoinMode[m];
if (m === this.canvas_text.stroke.lineJoin)
return;
this.canvas_text.stroke.lineJoin = m;
this.need_text_redraw = true;
this.runtime.redraw = true;
};
Acts.prototype.SetBackgroundColor = function(color)
{
if (color === this.canvas_text.backgroundColor)
return;
this.canvas_text.backgroundColor = color;
this.need_text_redraw = true;
this.runtime.redraw = true;
};
Acts.prototype.LockCanvasSize = function(width, height)
{
this.LockCanvasSize(true, width, height);
};
Acts.prototype.UnLockCanvasSize = function()
{
this.LockCanvasSize(false);
};
Acts.prototype.AddImage = function (key, objs, yoffset)
{
if (!objs)
return;
window.RexImageBank.AddImage(key, objs.getFirstPicked(), yoffset);
this.render_text(this.is_force_render);
};
Acts.prototype.RemoveImage = function (key)
{
window.RexImageBank.RemoveImage(key);
this.render_text(this.is_force_render);
};
Acts.prototype.RemoveAll = function ()
{
window.RexImageBank.RemoveAll();
this.render_text(this.is_force_render);
};
function Exps() {};
pluginProto.exps = new Exps();
Exps.prototype.Text = function(ret, start, end)
{
var txt;
if ((start == null) && (end == null))
txt = this.text;
else
txt = this.getSubText(start, end);
ret.set_string(txt);
};
Exps.prototype.FaceName = function (ret)
{
ret.set_string(this.facename);
};
Exps.prototype.FaceSize = function (ret)
{
ret.set_int(this.ptSize);
};
Exps.prototype.TextWidth = function (ret)
{
ret.set_int(this.canvas_text.getTextWidth());
};
Exps.prototype.TextHeight = function (ret)
{
var total_line_count = this.canvas_text.getLines().length;
var text_height = total_line_count * (this.pxHeight + this.line_height_offset) - this.line_height_offset;
if (this.baseLine_mode === 0) // alphabetic
text_height += this.vshift;
ret.set_float(text_height);
};
Exps.prototype.RawText = function(ret)
{
ret.set_string(this.canvas_text.getRawText());
};
Exps.prototype.LastClassPropValue = function(ret, name, default_value)
{
var val;
var last_pen = this.canvas_text.getLastPen();
if (last_pen)
val = last_pen.prop[name];
if (!val)
val = default_value || 0;
ret.set_any(val);
};
var ObjCacheKlass = function ()
{
this.lines = [];
};
var ObjCacheKlassProto = ObjCacheKlass.prototype;
ObjCacheKlassProto.allocLine = function()
{
return (this.lines.length > 0)? this.lines.pop(): null;
};
ObjCacheKlassProto.freeLine = function (l)
{
this.lines.push(l);
};
ObjCacheKlassProto.freeAllLines= function (arr)
{
var i, len;
for (i = 0, len = arr.length; i < len; i++)
this.freeLine(arr[i]);
arr.length = 0;
};
var CanvasText = function ()
{
this.canvas = null;
this.context = null;
this.savedClasses = {}; // class define
this.textInfo = {
"text":"",
"x":0,
"y":0,
"boxWidth":0,
"boxHeight":0,
"ignore":null,
};
this.pensMgr = new PensMgrKlass();
this.text_changed = true; // update this.pens to redraw
/*
* Default values, overwrite before draw by plugin
*/
this.default_propScope = {
family:"Verdana",
weight:"",
ptSize:"12pt",
color:"#000000",
style:"normal",
shadow:"",
};
this.stroke = {lineWidth: 1, lineJoin: "miter"};
this.underline = {thickness: 1, offset:0};
this.textAlign = "start";
this.lineHeight = "16";
this.textBaseline = "alphabetic";
this.backgroundColor = "";
};
var CanvasTextProto = CanvasText.prototype;
CanvasTextProto.Reset = function(plugin)
{
this.plugin = plugin;
};
CanvasTextProto.getLines = function()
{
return this.pensMgr.getLines();
};
CanvasTextProto.apply_propScope = function (propScope)
{
if (this.isTextMode(propScope))
{
var style;
if (propScope.hasOwnProperty("b") || propScope.hasOwnProperty("i"))
{
if (propScope["b"] && propScope["i"])
style = "bold italic";
else if (propScope["b"])
style = "bold";
else if (propScope["i"])
style = "italic";
}
else
{
style = this.default_propScope.weight;
}
var weight = propScope["weight"] || this.default_propScope.weight;
var ptSize = this.getTextSize(propScope);
var family = propScope["family"] || this.default_propScope.family;
this.context.font = style + " " + weight + " " + ptSize + " " + family;
var color = this.getFillColor(propScope);
if (color.toLowerCase() !== "none")
this.context.fillStyle = color;
var stroke = this.getStokeColor(propScope);
if (stroke.toLowerCase() !== "none")
{
this.context.strokeStyle = stroke;
this.context.lineWidth = this.stroke.lineWidth;
this.context.lineJoin = this.stroke.lineJoin;
this.context.miterLimit = 2;
}
}
var shadow = (propScope["shadow"])? this.default_propScope.shadow : "";
if (shadow !== "")
{
shadow = shadow.split(" ");
this.context.shadowOffsetX = parseFloat(shadow[0].replace("px", ""));
this.context.shadowOffsetY = parseFloat(shadow[1].replace("px", ""));
this.context.shadowBlur = parseFloat(shadow[2].replace("px", ""));
this.context.shadowColor = shadow[3];
}
};
CanvasTextProto.isTextMode = function(propScope)
{
var isImageMode = propScope.hasOwnProperty("img");
return !isImageMode;
};
CanvasTextProto.getTextSize = function(propScope)
{
var size;
if (propScope.hasOwnProperty("size"))
size = propScope["size"];
else
size = this.default_propScope.ptSize;
return size;
};
CanvasTextProto.getFillColor = function(propScope)
{
var color;
if (propScope.hasOwnProperty("color"))
color = propScope["color"];
else
color = this.default_propScope.color;
return color;
};
CanvasTextProto.getStokeColor = function(propScope)
{
var color;
if (propScope.hasOwnProperty("stroke"))
color = propScope["stroke"];
else
color = "none";
return color;
};
CanvasTextProto.draw_pen = function (pen, offset_x, offset_y)
{
var ctx = this.context;
ctx.save();
this.apply_propScope(pen.prop);
var startX = offset_x + pen.x;
var startY = offset_y + pen.y;
var underline = pen.prop["u"];
if (underline)
{
var color = (underline === true)? this.getFillColor(pen.prop) : underline;
this.draw_underline(pen.text, startX, startY,
this.getTextSize(pen.prop),
color );
}
if (pen.prop.hasOwnProperty("img"))
{
var img = window.RexImageBank.GetImage(pen.prop["img"]);
if (img)
{
var y = startY+img.yoffset;
if (this.textBaseline == "alphabetic")
{
y -= this.lineHeight;
}
ctx.drawImage(img.img, startX, y, img.width, img.height);
}
}
else
{
if (this.getStokeColor(pen.prop).toLowerCase() !== "none")
ctx.strokeText(pen.text, startX, startY);
if (this.getFillColor(pen.prop).toLowerCase() !== "none")
ctx.fillText(pen.text, startX, startY);
}
ctx.restore();
};
CanvasTextProto.draw_underline = function (text, x, y, size, color)
{
var ctx = this.context;
var width = ctx.measureText(text).width;
y += this.underline.offset;
if (this.textBaseline === "top")
y += parseInt(size);
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = this.underline.thickness;
ctx.moveTo(x,y);
ctx.lineTo(x+width,y);
ctx.stroke();
};
CanvasTextProto.preProcess = function()
{
if (this.backgroundColor !== "")
{
var ctx = this.context;
ctx.fillStyle = this.backgroundColor;
ctx.fillRect(0, 0, this.textInfo["boxWidth"], this.textInfo["boxHeight"]);
}
};
CanvasTextProto.drawPens = function (pensMgr, textInfo)
{
var boxWidth=textInfo["boxWidth"], boxHeight=textInfo["boxHeight"];
var start_x = textInfo["x"], start_y = textInfo["y"];
var lines=pensMgr.getLines(), lcnt=lines.length;
var offset_x, offset_y;
if (this.plugin.valign === 1) // center
offset_y = Math.max( (boxHeight - (lcnt * this.lineHeight)) / 2, 0);
else if (this.plugin.valign === 2) // bottom
offset_y = Math.max(boxHeight - (lcnt * this.lineHeight) - 2, 0);
else
offset_y = 0;
offset_y += start_y;
if (this.textBaseline == "alphabetic")
offset_y += (this.plugin.vshift * this.plugin.runtime.devicePixelRatio); // shift line down
var li, line_width;
var pi, pcnt, pens, pen;
for (li=0; li<lcnt; li++)
{
line_width = pensMgr.getLineWidth(li);
if (line_width === 0)
continue;
if (this.plugin.halign === 1) // center
offset_x = (boxWidth - line_width) / 2;
else if (this.plugin.halign === 2) // right
offset_x = boxWidth - line_width;
else
offset_x = 0;
offset_x += start_x;
pens = lines[li];
pcnt = pens.length;
for (pi=0; pi<pcnt; pi++)
{
pen = pens[pi];
if (pen.text === "")
continue;
this.draw_pen(pen, offset_x, offset_y);
}
}
};
CanvasTextProto.postProcess = function()
{
};
var RAWTEXTONLY_MODE = 1;
var __result=[];
var split_text = function(txt, mode)
{
var re = /\[b\]|\[\/b\]|\[i\]|\[\/i\]|\[size=(\d+)\]|\[\/size\]|\[color=([a-z]+|#[0-9abcdef]+)\]|\[\/color\]|\[u\]|\[u=([a-z]+|#[0-9abcdef]+)\]|\[\/u\]|\[shadow\]|\[\/shadow\]|\[stroke=([a-z]+|#[0-9abcdef]+)\]|\[\/stroke\]|\[img=([^\]]+)\]|\[\/img\]/ig;
__result.length = 0;
var arr, m, char_index=0, total_length=txt.length, match_start=total_length;
while(true)
{
arr = re.exec(txt);
if (!arr)
{
break;
}
m = arr[0];
match_start = re["lastIndex"] - m.length;
if (char_index < match_start)
{
__result.push(txt.substring(char_index,match_start));
}
if (mode == null)
__result.push(m);
char_index = re["lastIndex"];
}
if (char_index < total_length)
{
__result.push(txt.substring(char_index,total_length));
}
return __result;
};
var __re_bold_open = /\[b\]/i;
var __re_bold_close = /\[\/b\]/i;
var __re_italics_open = /\[i\]/i;
var __re_italics_close = /\[\/i\]/i;
var __re_size_open = /\[size=(\d+)\]/i;
var __re_size_close = /\[\/size\]/i;
var __re_color_open = /\[color=([a-z]+|#[0-9abcdef]+)\]/i;
var __re_color_close = /\[\/color\]/i;
var __re_underline_open = /\[u\]/i;
var __re_underline_openC = /\[u=([a-z]+|#[0-9abcdef]+)\]/i;
var __re_underline_close = /\[\/u\]/i;
var __re_shadow_open = /\[shadow\]/i;
var __re_shadow_close = /\[\/shadow\]/i;
var __re_stroke_open = /\[stroke=([a-z]+|#[0-9abcdef]+)\]/i;
var __re_stroke_close = /\[\/stroke\]/i;
var __re_image_open = /\[img=([^\]]+)\]/i;
var __re_image_close = /\[\/img\]/i;
var __curr_propScope = {};
var PROP_REMOVE = false;
var PROP_ADD = true;
CanvasTextProto.updatePens = function (pensMgr, textInfo, ignore_wrap)
{
if (textInfo == null)
textInfo = this.textInfo;
pensMgr.freePens();
var text=textInfo["text"], boxWidth=textInfo["boxWidth"], boxHeight=textInfo["boxHeight"];
if (text === "")
return;
var start_x = 0, start_y = 0;
var cursor_x=start_x, cursor_y=start_y;
var proText;
var m, match=split_text(text);
if (match.length === 0)
return;
var i, match_cnt = match.length;
var innerMatch = null;
for (i = 0; i < match_cnt; i++)
{
m = match[i];
if (__re_bold_open.test(m))
{
update_propScope(__curr_propScope, PROP_ADD, "b", true);
continue;
}
else if (__re_bold_close.test(m))
{
update_propScope(__curr_propScope, PROP_REMOVE, "b");
continue;
}
else if (__re_italics_open.test(m))
{
update_propScope(__curr_propScope, PROP_ADD, "i", true);
continue;
}
else if (__re_italics_close.test(m))
{
update_propScope(__curr_propScope, PROP_REMOVE, "i");
continue;
}
else if (__re_size_open.test(m))
{
innerMatch = m.match(__re_size_open);
update_propScope(__curr_propScope, PROP_ADD, "size", innerMatch[1]+"pt");
continue;
}
else if (__re_size_close.test(m))
{
update_propScope(__curr_propScope, PROP_REMOVE, "size");
continue;
}
else if (__re_color_open.test(m))
{
innerMatch = m.match(__re_color_open);
update_propScope(__curr_propScope, PROP_ADD, "color", innerMatch[1]);
continue;
}
else if (__re_color_close.test(m))
{
update_propScope(__curr_propScope, PROP_REMOVE, "color");
continue;
}
else if (__re_underline_open.test(m))
{
innerMatch = m.match(__re_underline_open);
update_propScope(__curr_propScope, PROP_ADD, "u", true);
continue;
}
else if (__re_underline_openC.test(m))
{
innerMatch = m.match(__re_underline_openC);
update_propScope(__curr_propScope, PROP_ADD, "u", innerMatch[1]);
continue;
}
else if (__re_underline_close.test(m))
{
update_propScope(__curr_propScope, PROP_REMOVE, "u");
continue;
}
else if (__re_shadow_open.test(m))
{
update_propScope(__curr_propScope, PROP_ADD, "shadow", true);
continue;
}
else if (__re_shadow_close.test(m))
{
update_propScope(__curr_propScope, PROP_REMOVE, "shadow");
continue;
}
else if (__re_stroke_open.test(m))
{
innerMatch = m.match(__re_stroke_open);
update_propScope(__curr_propScope, PROP_ADD, "stroke", innerMatch[1]);
continue;
}
else if (__re_stroke_close.test(m))
{
update_propScope(__curr_propScope, PROP_REMOVE, "stroke");
continue;
}
else if (__re_image_open.test(m))
{
innerMatch = m.match(__re_image_open);
var key = innerMatch[1];
var img = window.RexImageBank.GetImage(key);
if (!img)
continue;
update_propScope(__curr_propScope, PROP_ADD, "img", key);
if (!ignore_wrap)
{
if ( img.width > boxWidth - (cursor_x-start_x) )
{
cursor_x = start_x;
cursor_y += this.lineHeight;
}
pensMgr.addPen(null, // text
cursor_x, // x
cursor_y, // y
img.width, // width
__curr_propScope, // prop
0 // new_line_mode
);
cursor_x += img.width;
}
else
{
pensMgr.addPen(null, // text
null, // x
null, // y
null, // width
__curr_propScope, // prop
0 // new_line_mode
);
}
update_propScope(__curr_propScope, PROP_REMOVE, "img");
continue;
}
else if (__re_image_close.test(m))
{
update_propScope(__curr_propScope, PROP_REMOVE, "img");
continue;
}
else
{
proText = m;
if (!ignore_wrap)
{
this.context.save();
this.apply_propScope(__curr_propScope);
var wrap_lines = wordWrap(proText, this.context, boxWidth, this.plugin.wrapbyword, cursor_x-start_x );
var lcnt=wrap_lines.length, n, wrap_line;
for (n=0; n<lcnt; n++)
{
wrap_line = wrap_lines[n];
pensMgr.addPen(wrap_line.text, // text
cursor_x, // x
cursor_y, // y
wrap_line.width, // width
__curr_propScope, // prop
wrap_line.newLineMode // new_line_mode
);
if (wrap_line.newLineMode !== NO_NEWLINE)
{
cursor_x = start_x;
cursor_y += this.lineHeight;
}
else
{
cursor_x += wrap_line.width;
}
}
this.context.restore();
}
else
{
pensMgr.addPen(proText, // text
null, // x
null, // y
null, // width
__curr_propScope, // prop
0 // new_line_mode
);
}
continue;
}
} // for (i = 0; i < match_cnt; i++)
for (var k in __curr_propScope)
delete __curr_propScope[k];
};
var update_propScope = function(propScope, op, prop, value)
{
if (op === PROP_ADD)
propScope[prop] = value;
else
remove_prop(propScope, prop);
return propScope;
};
var remove_prop = function (propScope, prop)
{
if (propScope.hasOwnProperty(prop))
delete propScope[prop];
};
CanvasTextProto.drawText = function ()
{
var textInfo = this.textInfo;
if (this.text_changed)
{
this.updatePens(this.pensMgr, textInfo);
this.text_changed = false;
}
if (!textInfo["ignore"])
{
this.context.textBaseline = this.textBaseline;
this.context.textAlign = this.textAlign;
this.preProcess();
this.drawPens(this.pensMgr, textInfo);
this.postProcess();
}
};
var __tempPensMgr = null;
CanvasTextProto.getSubText = function (start, end, text)
{
if (text == null)
return this.pensMgr.getSliceTagText(start, end);
if (__tempPensMgr === null)
__tempPensMgr = new PensMgrKlass();
var text_save = this.textInfo["text"];
this.textInfo["text"] = text;
this.updatePens(__tempPensMgr, this.textInfo, true);
this.textInfo["text"] = text_save;
return __tempPensMgr.getSliceTagText(start, end);
};
CanvasTextProto.getRawText = function (text)
{
if (text == null)
return this.pensMgr.getRawText();
var m, match=split_text(text, RAWTEXTONLY_MODE);
if (match.length === 0)
return "";
var i, match_cnt = match.length;
var innerMatch, rawTxt ="";
for (i=0; i<match_cnt; i++)
{
rawTxt += match[i];
} // for (i = 0; i < match_cnt; i++)
return rawTxt;
};
CanvasTextProto.copyPensMgr = function (pensMgr)
{
return this.pensMgr.copy(pensMgr);
}
CanvasTextProto.getTextWidth = function (pensMgr)
{
if (pensMgr == null)
pensMgr = this.pensMgr;
return pensMgr.getMaxLineWidth();
} ;
CanvasTextProto.getLastPen = function (pensMgr)
{
if (pensMgr == null)
pensMgr = this.pensMgr;
return pensMgr.getLastPen();
} ;
/**
* Save a new class definition.
*/
CanvasTextProto.defineClass = function (id, definition) {
this.savedClasses[id] = definition;
return true;
};
/**
* Returns a saved class.
*/
CanvasTextProto.getClass = function (id) {
return this.savedClasses[id];
};
/**
* A simple function to check if the given value is empty.
*/
var isEmpty = function (str) {
str = str.replace(/^\s+|\s+$/, '');
return str.length == 0;
};
/**
* A simple function clear whitespaces.
*/
CanvasTextProto.trim = function (str) {
var ws, i;
str = str.replace(/^\s\s*/, '');
ws = /\s/;
i = str.length;
while (ws.test(str.charAt(--i))) {
continue;
}
return str.slice(0, i + 1);
};
CanvasTextProto.saveToJSON = function ()
{
return {
"cls": this.savedClasses,
"stroke": [this.stroke.lineWidth, this.stroke.lineJoin],
"u": [this.underline.thickness, this.underline.offset],
"bgc": this.backgroundColor
};
};
CanvasTextProto.loadFromJSON = function (o)
{
this.savedClasses = o["cls"];
this.stroke.lineWidth = o["stroke"][0];
this.stroke.lineJoin = o["stroke"][1];
this.underline.thickness = o["u"][0];
this.underline.offset = o["u"][1];
this.backgroundColor = o["bgc"];
};
var NO_NEWLINE = 0;
var RAW_NEWLINE = 1;
var WRAPPED_NEWLINE = 2;
var lineCache = new ObjCacheKlass();
lineCache.newline = function(text, width, newLineMode)
{
var l = this.allocLine() || {};
l.text = text;
l.width = width;
l.newLineMode = newLineMode; // 0= no new line, 1=raw "\n", 2=wrapped "\n"
return l;
};
var __wrapped_lines=[];
var wordWrap = function (text, ctx, width, wrapbyword, offset_x)
{
var lines=__wrapped_lines;
lineCache.freeAllLines(lines);
if (!text || !text.length)
{
return lines;
}
if (width <= 2.0)
{
return lines;
}
if (text.length <= 100 && text.indexOf("\n") === -1)
{
var all_width = ctx.measureText(text).width;
if (all_width <= (width - offset_x))
{
lineCache.freeAllLines(lines);
lines.push(lineCache.newline(text, all_width, NO_NEWLINE));
return lines;
}
}
return WrapText(text, lines, ctx, width, wrapbyword, offset_x);
};
var WrapText = function (text, lines, ctx, width, wrapbyword, offset_x)
{
var wordArray = (wrapbyword)? TokeniseWords(text) : text;
var cur_line = "";
var prev_line;
var line_width;
var i, wcnt=wordArray.length;
var lineIndex = 0;
var line;
for (i = 0; i < wcnt; i++)
{
if (wordArray[i] === "\n")
{
if (lineIndex >= lines.length)
lines.push(lineCache.newline(cur_line, ctx.measureText(cur_line).width, RAW_NEWLINE));
lineIndex++;
cur_line = "";
offset_x = 0;
continue;
}
prev_line = cur_line;
cur_line += wordArray[i];
line_width = ctx.measureText(cur_line).width;
if (line_width >= (width - offset_x))
{
if (lineIndex >= lines.length)
lines.push(lineCache.newline(prev_line, ctx.measureText(prev_line).width, WRAPPED_NEWLINE));
lineIndex++;
cur_line = wordArray[i];
if (!wrapbyword && cur_line === " ")
cur_line = "";
offset_x = 0;
}
}
if (cur_line.length)
{
if (lineIndex >= lines.length)
lines.push(lineCache.newline(cur_line, ctx.measureText(cur_line).width, NO_NEWLINE));
lineIndex++;
}
for (i = lineIndex; i < lines.length; i++)
lineCache.freeLine(lines[i]);
lines.length = lineIndex;
return lines;
};
var __wordsCache = [];
var TokeniseWords = function (text)
{
__wordsCache.length = 0;
var cur_word = "";
var ch;
var i = 0;
while (i < text.length)
{
ch = text.charAt(i);
if (ch === "\n")
{
if (cur_word.length)
{
__wordsCache.push(cur_word);
cur_word = "";
}
__wordsCache.push("\n");
++i;
}
else if (ch === " " || ch === "\t" || ch === "-")
{
do {
cur_word += text.charAt(i);
i++;
}
while (i < text.length && (text.charAt(i) === " " || text.charAt(i) === "\t"));
__wordsCache.push(cur_word);
cur_word = "";
}
else if (i < text.length)
{
cur_word += ch;
i++;
}
}
if (cur_word.length)
__wordsCache.push(cur_word);
return __wordsCache;
};
var __penMgr_penCache = new ObjCacheKlass();
var __penMgr_lineCache =new ObjCacheKlass();
var PensMgrKlass = function ()
{
this.pens = []; // all pens
this.lines= []; // pens in lines [ [],[],[],.. ]
};
var PensMgrKlassProto = PensMgrKlass.prototype;
PensMgrKlassProto.freePens = function ()
{
var li, lcnt=this.lines.length;
for(li=0; li<lcnt; li++)
this.lines[li].length = 0; // unlink pens
__penMgr_penCache.freeAllLines(this.pens);
__penMgr_lineCache.freeAllLines(this.lines);
};
PensMgrKlassProto.addPen = function (txt, x, y, width, prop, new_line_mode)
{
var pen = __penMgr_penCache.allocLine();
if (pen === null)
{
pen = new PenKlass();
}
pen.setPen(txt, x, y, width, prop, new_line_mode);
var prev_pen = this.pens[this.pens.length -1];
if (prev_pen == null)
pen.startIndex = 0;
else
pen.startIndex = prev_pen.getNextStartIndex();
this.pens.push(pen);
var line = this.lines[this.lines.length-1];
if (line == null)
{
line = __penMgr_lineCache.allocLine() || [];
this.lines.push(line);
}
line.push(pen);
if (new_line_mode !== NO_NEWLINE)
{
line = __penMgr_lineCache.allocLine() || [];
this.lines.push(line);
}
};
PensMgrKlassProto.getPens = function ()
{
return this.pens;
};
PensMgrKlassProto.getLastPen = function ()
{
return this.pens[this.pens.length -1];
};
PensMgrKlassProto.getLines = function ()
{
return this.lines;
};
PensMgrKlassProto.getLineStartChartIndex = function (i)
{
var line = this.lines[i];
if (line == null)
return 0;
return line[0].startIndex;
};
PensMgrKlassProto.getLineEndChartIndex = function (i)
{
var li, has_last_pen=false, line;
for(li=i; li>=0; li--)
{
line = this.lines[li];
has_last_pen = (line != null) && (line.length>0);
if (has_last_pen)
break;
}
if (!has_last_pen)
return 0;
var last_pen = line[line.length-1];
return last_pen.getEndIndex();
};
PensMgrKlassProto.copy = function (targetPensMgr)
{
if (targetPensMgr == null)
targetPensMgr = new PensMgrKlass();
targetPensMgr.freePens();
var li, lcnt=this.lines.length;
var pens, pi, pcnt, pen;
for (li=0; li<lcnt; li++ )
{
pens = this.lines[li];
pcnt = pens.length;
for (pi=0; pi<pcnt; pi++)
{
pen = pens[pi];
targetPensMgr.addPen(pen.text,
pen.x,
pen.y,
pen.width,
pen.prop,
pen.newLineMode);
}
}
return targetPensMgr;
};
PensMgrKlassProto.getLineWidth = function (i)
{
var line = this.lines[i];
if (!line)
return 0;
var last_pen = line[line.length -1];
if (!last_pen)
return 0;
var first_pen = line[0];
var line_width = last_pen.getLastX(); // start from 0
return line_width;
};
PensMgrKlassProto.getMaxLineWidth = function ()
{
var w, maxW=0, i, cnt=this.lines.length, line, last_pen;
for (i=0; i<cnt; i++)
{
w = this.getLineWidth(i);
if (w > maxW)
maxW = w;
}
return maxW;
};
PensMgrKlassProto.getRawText = function ()
{
var txt="", i, cnt=this.pens.length, pen;
for(i=0; i<cnt; i++)
txt += this.pens[i].getRawText();
return txt;
};
PensMgrKlassProto.getRawTextLength = function ()
{
var l=0, i, cnt=this.pens.length, pen;
for(i=0; i<cnt; i++)
l += this.pens[i].getRawText().length;
return l;
};
PensMgrKlassProto.getSliceTagText = function (start, end)
{
if (start == null)
start = 0;
if (end == null)
{
var last_pen = this.getLastPen();
if (last_pen == null)
return "";
end = last_pen.getEndIndex();
}
var txt="", i, cnt=this.pens.length, pen, pen_txt, pen_si, pen_ei, in_range;
var pre_prop;
var isFirstProp=true;
for(i=0; i<cnt; i++)
{
pen = this.pens[i];
pen_txt = pen.getRawText();
pen_si = pen.startIndex;
pen_ei = pen.getNextStartIndex();
if (pen_ei < start)
continue;
in_range = (pen_si >= start) && (pen_ei < end);
if (!in_range)
{
pen_txt = pen_txt.substring(start-pen_si, end-pen_si);
}
txt += prop2TagText(pen_txt, pen.prop, pre_prop);
pre_prop = pen.prop;
if (pen_ei >= end)
break;
}
return txt;
};
var __empty_prop = {};
var prop2TagText = function (txt, prop, pre_prop)
{
if (pre_prop == null)
pre_prop = __empty_prop;
for (var k in pre_prop)
{
if (prop.hasOwnProperty(k))
continue;
txt = "[/" + k + "]" + txt;
}
var header = "";
for (var k in prop)
{
if (pre_prop[k] === prop[k])
continue;
if (k === "size")
header += ("[size=" + prop[k].replace("pt", "") + "]");
else if ((k === "color") || (k === "stroke") || (k === "img"))
header += ("[" + k + "=" + prop[k] + "]");
else if (k === "u")
{
if (prop[k] === true)
header += "[u]";
else
header += ("[u=" + prop[k] + "]");
}
else
header += ("[" + k + "]");
}
txt = header + txt;
return txt;
};
var has_key = function (o)
{
for (var k in o)
return true;
return false;
}
var PenKlass = function ()
{
this.text = null;
this.x = null;
this.y = null;
this.width = null;
this.prop = {};
this.newLineMode = null;
this.startIndex = null;
}
var PenKlassProto = PenKlass.prototype;
PenKlassProto.setPen = function (txt, x, y, width, prop, new_line_mode, start_index)
{
this.text = txt;
this.x = x;
this.y = y;
this.width = width;
copy_dict(prop, this.prop); // font, size, color, shadow, etc...
this.newLineMode = new_line_mode; // 0= no new line, 1=raw "\n", 2=wrapped "\n"
this.startIndex = start_index;
};
PenKlassProto.getRawText = function ()
{
var txt = this.text || "";
if (this.newLineMode == RAW_NEWLINE)
txt += "\n";
return txt;
}
PenKlassProto.getNextStartIndex = function()
{
return this.startIndex + this.getRawText().length;
};
PenKlassProto.getEndIndex = function()
{
return this.getNextStartIndex() - 1;
};
PenKlassProto.getLastX = function()
{
return this.x + this.width;
};
var ImageBankKlass = function ()
{
this.images = {};
}
var ImageBankKlassProto = ImageBankKlass.prototype;
ImageBankKlassProto.AddImage = function (name, inst, yoffset_)
{
var img = getImage(inst)
if (!inst)
return;
this.images[name] = {
img: img,
width: inst.width,
height: inst.height,
yoffset: yoffset_
};
};
ImageBankKlassProto.GetImage = function (name, inst)
{
return this.images[name];
};
ImageBankKlassProto.RemoveImage = function (name)
{
if (this.images.hasOwnProperty(name))
delete this.images[name];
};
ImageBankKlassProto.RemoveAll = function ()
{
for (var n in this.images)
delete this.images[n];
};
var getImage = function (inst)
{
if (!inst)
return null;
var img;
if (inst.canvas)
img = inst.canvas;
else if (inst.curFrame && inst.curFrame.texture_img)
img = inst.curFrame.texture_img;
else
img = null;
return img;
};
window.RexImageBank = new ImageBankKlass();
}());
;
;
cr.behaviors.Anchor = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.Anchor.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.anch_left = this.properties[0]; // 0 = left, 1 = right, 2 = none
this.anch_top = this.properties[1]; // 0 = top, 1 = bottom, 2 = none
this.anch_right = this.properties[2]; // 0 = none, 1 = right
this.anch_bottom = this.properties[3]; // 0 = none, 1 = bottom
this.inst.update_bbox();
this.xleft = this.inst.bbox.left;
this.ytop = this.inst.bbox.top;
this.xright = this.runtime.original_width - this.inst.bbox.left;
this.ybottom = this.runtime.original_height - this.inst.bbox.top;
this.rdiff = this.runtime.original_width - this.inst.bbox.right;
this.bdiff = this.runtime.original_height - this.inst.bbox.bottom;
this.enabled = (this.properties[4] !== 0);
};
behinstProto.saveToJSON = function ()
{
return {
"xleft": this.xleft,
"ytop": this.ytop,
"xright": this.xright,
"ybottom": this.ybottom,
"rdiff": this.rdiff,
"bdiff": this.bdiff,
"enabled": this.enabled
};
};
behinstProto.loadFromJSON = function (o)
{
this.xleft = o["xleft"];
this.ytop = o["ytop"];
this.xright = o["xright"];
this.ybottom = o["ybottom"];
this.rdiff = o["rdiff"];
this.bdiff = o["bdiff"];
this.enabled = o["enabled"];
};
behinstProto.tick = function ()
{
if (!this.enabled)
return;
var n;
var layer = this.inst.layer;
var inst = this.inst;
var bbox = this.inst.bbox;
if (this.anch_left === 0)
{
inst.update_bbox();
n = (layer.viewLeft + this.xleft) - bbox.left;
if (n !== 0)
{
inst.x += n;
inst.set_bbox_changed();
}
}
else if (this.anch_left === 1)
{
inst.update_bbox();
n = (layer.viewRight - this.xright) - bbox.left;
if (n !== 0)
{
inst.x += n;
inst.set_bbox_changed();
}
}
if (this.anch_top === 0)
{
inst.update_bbox();
n = (layer.viewTop + this.ytop) - bbox.top;
if (n !== 0)
{
inst.y += n;
inst.set_bbox_changed();
}
}
else if (this.anch_top === 1)
{
inst.update_bbox();
n = (layer.viewBottom - this.ybottom) - bbox.top;
if (n !== 0)
{
inst.y += n;
inst.set_bbox_changed();
}
}
if (this.anch_right === 1)
{
inst.update_bbox();
n = (layer.viewRight - this.rdiff) - bbox.right;
if (n !== 0)
{
inst.width += n;
if (inst.width < 0)
inst.width = 0;
inst.set_bbox_changed();
}
}
if (this.anch_bottom === 1)
{
inst.update_bbox();
n = (layer.viewBottom - this.bdiff) - bbox.bottom;
if (n !== 0)
{
inst.height += n;
if (inst.height < 0)
inst.height = 0;
inst.set_bbox_changed();
}
}
};
function Cnds() {};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetEnabled = function (e)
{
if (this.enabled && e === 0)
this.enabled = false;
else if (!this.enabled && e !== 0)
{
this.inst.update_bbox();
this.xleft = this.inst.bbox.left;
this.ytop = this.inst.bbox.top;
this.xright = this.runtime.original_width - this.inst.bbox.left;
this.ybottom = this.runtime.original_height - this.inst.bbox.top;
this.rdiff = this.runtime.original_width - this.inst.bbox.right;
this.bdiff = this.runtime.original_height - this.inst.bbox.bottom;
this.enabled = true;
}
};
behaviorProto.acts = new Acts();
function Exps() {};
behaviorProto.exps = new Exps();
}());
;
;
cr.behaviors.Bullet = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.Bullet.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
var speed = this.properties[0];
this.acc = this.properties[1];
this.g = this.properties[2];
this.bounceOffSolid = (this.properties[3] !== 0);
this.setAngle = (this.properties[4] !== 0);
this.dx = Math.cos(this.inst.angle) * speed;
this.dy = Math.sin(this.inst.angle) * speed;
this.lastx = this.inst.x;
this.lasty = this.inst.y;
this.lastKnownAngle = this.inst.angle;
this.travelled = 0;
this.enabled = (this.properties[5] !== 0);
};
behinstProto.saveToJSON = function ()
{
return {
"acc": this.acc,
"g": this.g,
"dx": this.dx,
"dy": this.dy,
"lx": this.lastx,
"ly": this.lasty,
"lka": this.lastKnownAngle,
"t": this.travelled,
"e": this.enabled
};
};
behinstProto.loadFromJSON = function (o)
{
this.acc = o["acc"];
this.g = o["g"];
this.dx = o["dx"];
this.dy = o["dy"];
this.lastx = o["lx"];
this.lasty = o["ly"];
this.lastKnownAngle = o["lka"];
this.travelled = o["t"];
this.enabled = o["e"];
};
behinstProto.tick = function ()
{
if (!this.enabled)
return;
var dt = this.runtime.getDt(this.inst);
var s, a;
var bounceSolid, bounceAngle;
if (this.inst.angle !== this.lastKnownAngle)
{
if (this.setAngle)
{
s = cr.distanceTo(0, 0, this.dx, this.dy);
this.dx = Math.cos(this.inst.angle) * s;
this.dy = Math.sin(this.inst.angle) * s;
}
this.lastKnownAngle = this.inst.angle;
}
if (this.acc !== 0)
{
s = cr.distanceTo(0, 0, this.dx, this.dy);
if (this.dx === 0 && this.dy === 0)
a = this.inst.angle;
else
a = cr.angleTo(0, 0, this.dx, this.dy);
s += this.acc * dt;
if (s < 0)
s = 0;
this.dx = Math.cos(a) * s;
this.dy = Math.sin(a) * s;
}
if (this.g !== 0)
this.dy += this.g * dt;
this.lastx = this.inst.x;
this.lasty = this.inst.y;
if (this.dx !== 0 || this.dy !== 0)
{
this.inst.x += this.dx * dt;
this.inst.y += this.dy * dt;
this.travelled += cr.distanceTo(0, 0, this.dx * dt, this.dy * dt)
if (this.setAngle)
{
this.inst.angle = cr.angleTo(0, 0, this.dx, this.dy);
this.inst.set_bbox_changed();
this.lastKnownAngle = this.inst.angle;
}
this.inst.set_bbox_changed();
if (this.bounceOffSolid)
{
bounceSolid = this.runtime.testOverlapSolid(this.inst);
if (bounceSolid)
{
this.runtime.registerCollision(this.inst, bounceSolid);
s = cr.distanceTo(0, 0, this.dx, this.dy);
bounceAngle = this.runtime.calculateSolidBounceAngle(this.inst, this.lastx, this.lasty);
this.dx = Math.cos(bounceAngle) * s;
this.dy = Math.sin(bounceAngle) * s;
this.inst.x += this.dx * dt; // move out for one tick since the object can't have spent a tick in the solid
this.inst.y += this.dy * dt;
this.inst.set_bbox_changed();
if (this.setAngle)
{
this.inst.angle = bounceAngle;
this.lastKnownAngle = bounceAngle;
this.inst.set_bbox_changed();
}
if (!this.runtime.pushOutSolid(this.inst, this.dx / s, this.dy / s, Math.max(s * 2.5 * dt, 30)))
this.runtime.pushOutSolidNearest(this.inst, 100);
}
}
}
};
function Cnds() {};
Cnds.prototype.CompareSpeed = function (cmp, s)
{
return cr.do_cmp(cr.distanceTo(0, 0, this.dx, this.dy), cmp, s);
};
Cnds.prototype.CompareTravelled = function (cmp, d)
{
return cr.do_cmp(this.travelled, cmp, d);
};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetSpeed = function (s)
{
var a = cr.angleTo(0, 0, this.dx, this.dy);
this.dx = Math.cos(a) * s;
this.dy = Math.sin(a) * s;
};
Acts.prototype.SetAcceleration = function (a)
{
this.acc = a;
};
Acts.prototype.SetGravity = function (g)
{
this.g = g;
};
Acts.prototype.SetAngleOfMotion = function (a)
{
a = cr.to_radians(a);
var s = cr.distanceTo(0, 0, this.dx, this.dy)
this.dx = Math.cos(a) * s;
this.dy = Math.sin(a) * s;
};
Acts.prototype.Bounce = function (objtype)
{
if (!objtype)
return;
var otherinst = objtype.getFirstPicked(this.inst);
if (!otherinst)
return;
var dt = this.runtime.getDt(this.inst);
var s = cr.distanceTo(0, 0, this.dx, this.dy);
var bounceAngle = this.runtime.calculateSolidBounceAngle(this.inst, this.lastx, this.lasty, otherinst);
this.dx = Math.cos(bounceAngle) * s;
this.dy = Math.sin(bounceAngle) * s;
this.inst.x += this.dx * dt; // move out for one tick since the object can't have spent a tick in the solid
this.inst.y += this.dy * dt;
this.inst.set_bbox_changed();
if (this.setAngle)
{
this.inst.angle = bounceAngle;
this.lastKnownAngle = bounceAngle;
this.inst.set_bbox_changed();
}
if (s !== 0) // prevent divide-by-zero
{
if (this.bounceOffSolid)
{
if (!this.runtime.pushOutSolid(this.inst, this.dx / s, this.dy / s, Math.max(s * 2.5 * dt, 30)))
this.runtime.pushOutSolidNearest(this.inst, 100);
}
else
{
this.runtime.pushOut(this.inst, this.dx / s, this.dy / s, Math.max(s * 2.5 * dt, 30), otherinst)
}
}
};
Acts.prototype.SetDistanceTravelled = function (d)
{
this.travelled = d;
};
Acts.prototype.SetEnabled = function (en)
{
this.enabled = (en === 1);
};
behaviorProto.acts = new Acts();
function Exps() {};
Exps.prototype.Speed = function (ret)
{
var s = cr.distanceTo(0, 0, this.dx, this.dy);
s = cr.round6dp(s);
ret.set_float(s);
};
Exps.prototype.Acceleration = function (ret)
{
ret.set_float(this.acc);
};
Exps.prototype.AngleOfMotion = function (ret)
{
ret.set_float(cr.to_degrees(cr.angleTo(0, 0, this.dx, this.dy)));
};
Exps.prototype.DistanceTravelled = function (ret)
{
ret.set_float(this.travelled);
};
Exps.prototype.Gravity = function (ret)
{
ret.set_float(this.g);
};
behaviorProto.exps = new Exps();
}());
;
;
cr.behaviors.Fade = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.Fade.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.activeAtStart = this.properties[0] === 1;
this.setMaxOpacity = false; // used to retrieve maxOpacity once in first 'Start fade' action if initially inactive
this.fadeInTime = this.properties[1];
this.waitTime = this.properties[2];
this.fadeOutTime = this.properties[3];
this.destroy = this.properties[4]; // 0 = no, 1 = after fade out
this.stage = this.activeAtStart ? 0 : 3; // 0 = fade in, 1 = wait, 2 = fade out, 3 = done
if (this.recycled)
this.stageTime.reset();
else
this.stageTime = new cr.KahanAdder();
this.maxOpacity = (this.inst.opacity ? this.inst.opacity : 1.0);
if (this.activeAtStart)
{
if (this.fadeInTime === 0)
{
this.stage = 1;
if (this.waitTime === 0)
this.stage = 2;
}
else
{
this.inst.opacity = 0;
this.runtime.redraw = true;
}
}
};
behinstProto.saveToJSON = function ()
{
return {
"fit": this.fadeInTime,
"wt": this.waitTime,
"fot": this.fadeOutTime,
"s": this.stage,
"st": this.stageTime.sum,
"mo": this.maxOpacity,
};
};
behinstProto.loadFromJSON = function (o)
{
this.fadeInTime = o["fit"];
this.waitTime = o["wt"];
this.fadeOutTime = o["fot"];
this.stage = o["s"];
this.stageTime.reset();
this.stageTime.sum = o["st"];
this.maxOpacity = o["mo"];
};
behinstProto.tick = function ()
{
this.stageTime.add(this.runtime.getDt(this.inst));
if (this.stage === 0)
{
this.inst.opacity = (this.stageTime.sum / this.fadeInTime) * this.maxOpacity;
this.runtime.redraw = true;
if (this.inst.opacity >= this.maxOpacity)
{
this.inst.opacity = this.maxOpacity;
this.stage = 1; // wait stage
this.stageTime.reset();
this.runtime.trigger(cr.behaviors.Fade.prototype.cnds.OnFadeInEnd, this.inst);
}
}
if (this.stage === 1)
{
if (this.stageTime.sum >= this.waitTime)
{
this.stage = 2; // fade out stage
this.stageTime.reset();
this.runtime.trigger(cr.behaviors.Fade.prototype.cnds.OnWaitEnd, this.inst);
}
}
if (this.stage === 2)
{
if (this.fadeOutTime !== 0)
{
this.inst.opacity = this.maxOpacity - ((this.stageTime.sum / this.fadeOutTime) * this.maxOpacity);
this.runtime.redraw = true;
if (this.inst.opacity < 0)
{
this.inst.opacity = 0;
this.stage = 3; // done
this.stageTime.reset();
this.runtime.trigger(cr.behaviors.Fade.prototype.cnds.OnFadeOutEnd, this.inst);
if (this.destroy === 1)
this.runtime.DestroyInstance(this.inst);
}
}
}
};
behinstProto.doStart = function ()
{
this.stage = 0;
this.stageTime.reset();
if (this.fadeInTime === 0)
{
this.stage = 1;
if (this.waitTime === 0)
this.stage = 2;
}
else
{
this.inst.opacity = 0;
this.runtime.redraw = true;
}
};
function Cnds() {};
Cnds.prototype.OnFadeOutEnd = function ()
{
return true;
};
Cnds.prototype.OnFadeInEnd = function ()
{
return true;
};
Cnds.prototype.OnWaitEnd = function ()
{
return true;
};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.StartFade = function ()
{
if (!this.activeAtStart && !this.setMaxOpacity)
{
this.maxOpacity = (this.inst.opacity ? this.inst.opacity : 1.0);
this.setMaxOpacity = true;
}
if (this.stage === 3)
this.doStart();
};
Acts.prototype.RestartFade = function ()
{
this.doStart();
};
Acts.prototype.SetFadeInTime = function (t)
{
if (t < 0)
t = 0;
this.fadeInTime = t;
};
Acts.prototype.SetWaitTime = function (t)
{
if (t < 0)
t = 0;
this.waitTime = t;
};
Acts.prototype.SetFadeOutTime = function (t)
{
if (t < 0)
t = 0;
this.fadeOutTime = t;
};
behaviorProto.acts = new Acts();
function Exps() {};
Exps.prototype.FadeInTime = function (ret)
{
ret.set_float(this.fadeInTime);
};
Exps.prototype.WaitTime = function (ret)
{
ret.set_float(this.waitTime);
};
Exps.prototype.FadeOutTime = function (ret)
{
ret.set_float(this.fadeOutTime);
};
behaviorProto.exps = new Exps();
}());
;
;
cr.behaviors.NSG_TrueTimer = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.NSG_TrueTimer.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
function TimStackEntry()
{
this.tag = "";
this.params = [];
};
behinstProto.onCreate = function()
{
this.isInPreview = (typeof cr_is_preview !== "undefined");
this.timers = {};
this.params = [];
this.timStack = [];
this.timStackPtr = -1;
};
behinstProto.onDestroy = function ()
{
var tag;
for (tag in this.timers)
{
if (this.timers.hasOwnProperty(tag) && this.timers[tag] !== null)
{
clearInterval(this.timers[tag].id);
this.timers[tag] = null;
}
}
};
behinstProto.pushTimStack = function()
{
this.timStackPtr++;
if (this.timStackPtr === this.timStack.length)
this.timStack.push(new TimStackEntry());
return this.timStack[this.timStackPtr];
};
behinstProto.getCurrentTimStack = function()
{
if (this.timStackPtr < 0)
return null;
return this.timStack[this.timStackPtr];
};
behinstProto.popTimStack = function()
{
;
this.timStackPtr--;
};
behinstProto.parseTag = function(tag_)
{
return tag_.toLowerCase().trim();
};
behinstProto.timerExists = function(tag_)
{
return typeof this.timers[tag_] !== 'undefined';
};
behinstProto.setTimer = function(tag_, interval_, repeats_)
{
if (repeats_ <= 0)
{
this.params = [];
return;
}
var currentTimerData = this.pushTimStack();
currentTimerData.tag = tag_;
currentTimerData.params = this.params;
this.timers[tag_] = {
tag: tag_,
interval: interval_,
repeatsLeft: repeats_,
params: this.params,
triggerCounter: 0,
isActive: true,
startTime: (new Date()).getTime(),
id: null
};
this.params = [];
var self = this;
this.timers[tag_].id = setInterval( function ()
{
self.onTimerTrigger(tag_)
}
,this.timers[tag_].interval * 1000);
this.runtime.trigger(cr.behaviors.NSG_TrueTimer.prototype.cnds.OnTimerStarted, this.inst);
this.popTimStack();
};
behinstProto.onTimerTrigger = function(tag_)
{
var currentTimerData = this.pushTimStack();
currentTimerData.tag = tag_;
currentTimerData.params = this.timers[tag_].params;
--this.timers[tag_].repeatsLeft;
++this.timers[tag_].triggerCounter;
if (this.timers[tag_].repeatsLeft === 0)
{
this.timers[tag_].isActive = false;
}
this.runtime.trigger(cr.behaviors.NSG_TrueTimer.prototype.cnds.OnTimer, this.inst);
this.runtime.trigger(cr.behaviors.NSG_TrueTimer.prototype.cnds.OnAnyTimer, this.inst);
if ( ! this.timers[tag_] )
{
this.popTimStack();
return;
} // timer can be cancelled in OnTimer condition
if(this.timers[tag_].repeatsLeft <= 0)
{
clearInterval(this.timers[tag_].id);
delete this.timers[tag_];
}
this.popTimStack();
}
behinstProto.tick = function ()
{
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnTimer = function(tag_)
{
var currentTimerData = this.getCurrentTimStack();
if ( ! currentTimerData) return false;
tag_ = this.parseTag(tag_);
if(this.timerExists(tag_) && currentTimerData.tag === tag_)
{
return true;
}
};
/**
* @returns {boolean}
*/
Cnds.prototype.IsActive = function(tag_)
{
tag_ = this.parseTag(tag_);
if ( ! this.timerExists(tag_)) return false;
return this.timers[tag_].isActive;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnAnyTimer = function()
{
return true;
};
Cnds.prototype.OnTimerStarted = function(tag_)
{
var currentTimerData = this.getCurrentTimStack();
if ( ! currentTimerData) return false;
tag_ = this.parseTag(tag_);
return currentTimerData.tag === tag_;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnTimerStopped = function(tag_)
{
var currentTimerData = this.getCurrentTimStack();
if ( ! currentTimerData) return false;
tag_ = this.parseTag(tag_);
return currentTimerData.tag === tag_;
};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.StartTimer = function(tag_, interval_, repeats_)
{
tag_ = this.parseTag(tag_);
if(this.timerExists(tag_))
{
clearTimeout(this.timers[tag_].id);
delete this.timers[tag_];
}
this.setTimer(tag_, interval_, repeats_);
};
Acts.prototype.StopTimer = function(tag_)
{
tag_ = this.parseTag(tag_);
if(this.timerExists(tag_))
{
var currentTimerData = this.pushTimStack();
currentTimerData.tag = tag_;
currentTimerData.params = this.timers[tag_].params;
clearTimeout(this.timers[tag_].id);
delete this.timers[tag_];
this.runtime.trigger(cr.behaviors.NSG_TrueTimer.prototype.cnds.OnTimerStopped, this.inst);
this.popTimStack();
}
};
Acts.prototype.StopAllTimers = function()
{
for(var tag in this.timers)
{
if(this.timers.hasOwnProperty(tag) && typeof this.timers[tag] !== 'undefined' && this.timers[tag] !== null)
{
var currentTimerData = this.pushTimStack();
currentTimerData.tag = tag;
currentTimerData.params = this.timers[tag].params;
clearTimeout(this.timers[tag].id);
delete this.timers[tag];
this.runtime.trigger(cr.behaviors.NSG_TrueTimer.prototype.cnds.OnTimerStopped, this.inst);
this.popTimStack();
}
}
};
Acts.prototype.SetParam = function(paramId_, value_)
{
this.params[paramId_] = value_;
};
behaviorProto.acts = new Acts();
function Exps() {};
Exps.prototype.TimerTimeLeft = function (ret, tag_, secondsFormat_)
{
tag_ = this.parseTag(tag_);
if( ! this.timerExists(tag_))
{
ret.set_int(-1);
return;
}
var timeDiff = (new Date()).getTime() - this.timers[tag_].startTime;
var remainingTime = this.timers[tag_].interval * 1000 - timeDiff;
ret.set_int(secondsFormat_ === 0 ? remainingTime : remainingTime / 1000|0);
};
Exps.prototype.TimerAge = function (ret, tag_, secondsFormat_)
{
tag_ = this.parseTag(tag_);
if( ! this.timerExists(tag_))
{
ret.set_int(-1);
return;
}
var timeDiff = (new Date()).getTime() - this.timers[tag_].startTime;
ret.set_int(secondsFormat_ === 0 ? timeDiff : timeDiff / 1000|0);
};
Exps.prototype.TimerAgePercent = function (ret, tag_)
{
tag_ = this.parseTag(tag_);
if( ! this.timerExists(tag_))
{
ret.set_int(-1);
return;
}
var percentTimePassed = (Date.now() - this.timers[tag_].startTime) / (this.timers[tag_].interval * 1000);
ret.set_float(percentTimePassed);
};
Exps.prototype.TriggerAge = function (ret, tag_)
{
tag_ = this.parseTag(tag_);
if( ! this.timerExists(tag_))
{
ret.set_int(-1);
return;
}
ret.set_int(this.timers[tag_].triggerCounter);
};
Exps.prototype.TriggersLeft = function (ret, tag_)
{
tag_ = this.parseTag(tag_);
if( ! this.timerExists(tag_))
{
ret.set_int(-1);
return;
}
ret.set_int(this.timers[tag_].repeatsLeft);
};
Exps.prototype.Param = function (ret, tag_, paramId_)
{
tag_ = this.parseTag(tag_);
if( ! this.timerExists(tag_) || typeof this.timers[tag_].params[paramId_] === 'undefined')
{
ret.set_string("");
return;
}
ret.set_any(this.timers[tag_].params[paramId_]);
};
Exps.prototype.Tag = function (ret)
{
var currentTimerData = this.getCurrentTimStack();
if ( ! currentTimerData)
{
if (this.isInPreview)
{
console.warn("Cannot read timer TrueTimer Tag because expression is not in a timer call.")
}
ret.set_string("");
}
else
{
ret.set_string(currentTimerData.tag);
}
};
behaviorProto.exps = new Exps();
}());
;
;
cr.behaviors.Pin = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.Pin.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.pinObject = null;
this.pinObjectUid = -1; // for loading
this.pinAngle = 0;
this.pinDist = 0;
this.myStartAngle = 0;
this.theirStartAngle = 0;
this.lastKnownAngle = 0;
this.mode = 0; // 0 = position & angle; 1 = position; 2 = angle; 3 = rope; 4 = bar
var self = this;
if (!this.recycled)
{
this.myDestroyCallback = (function(inst) {
self.onInstanceDestroyed(inst);
});
}
this.runtime.addDestroyCallback(this.myDestroyCallback);
};
behinstProto.saveToJSON = function ()
{
return {
"uid": this.pinObject ? this.pinObject.uid : -1,
"pa": this.pinAngle,
"pd": this.pinDist,
"msa": this.myStartAngle,
"tsa": this.theirStartAngle,
"lka": this.lastKnownAngle,
"m": this.mode
};
};
behinstProto.loadFromJSON = function (o)
{
this.pinObjectUid = o["uid"]; // wait until afterLoad to look up
this.pinAngle = o["pa"];
this.pinDist = o["pd"];
this.myStartAngle = o["msa"];
this.theirStartAngle = o["tsa"];
this.lastKnownAngle = o["lka"];
this.mode = o["m"];
};
behinstProto.afterLoad = function ()
{
if (this.pinObjectUid === -1)
this.pinObject = null;
else
{
this.pinObject = this.runtime.getObjectByUID(this.pinObjectUid);
;
}
this.pinObjectUid = -1;
};
behinstProto.onInstanceDestroyed = function (inst)
{
if (this.pinObject == inst)
this.pinObject = null;
};
behinstProto.onDestroy = function()
{
this.pinObject = null;
this.runtime.removeDestroyCallback(this.myDestroyCallback);
};
behinstProto.tick = function ()
{
};
behinstProto.tick2 = function ()
{
if (!this.pinObject)
return;
if (this.lastKnownAngle !== this.inst.angle)
this.myStartAngle = cr.clamp_angle(this.myStartAngle + (this.inst.angle - this.lastKnownAngle));
var newx = this.inst.x;
var newy = this.inst.y;
if (this.mode === 3 || this.mode === 4) // rope mode or bar mode
{
var dist = cr.distanceTo(this.inst.x, this.inst.y, this.pinObject.x, this.pinObject.y);
if ((dist > this.pinDist) || (this.mode === 4 && dist < this.pinDist))
{
var a = cr.angleTo(this.pinObject.x, this.pinObject.y, this.inst.x, this.inst.y);
newx = this.pinObject.x + Math.cos(a) * this.pinDist;
newy = this.pinObject.y + Math.sin(a) * this.pinDist;
}
}
else
{
newx = this.pinObject.x + Math.cos(this.pinObject.angle + this.pinAngle) * this.pinDist;
newy = this.pinObject.y + Math.sin(this.pinObject.angle + this.pinAngle) * this.pinDist;
}
var newangle = cr.clamp_angle(this.myStartAngle + (this.pinObject.angle - this.theirStartAngle));
this.lastKnownAngle = newangle;
if ((this.mode === 0 || this.mode === 1 || this.mode === 3 || this.mode === 4)
&& (this.inst.x !== newx || this.inst.y !== newy))
{
this.inst.x = newx;
this.inst.y = newy;
this.inst.set_bbox_changed();
}
if ((this.mode === 0 || this.mode === 2) && (this.inst.angle !== newangle))
{
this.inst.angle = newangle;
this.inst.set_bbox_changed();
}
};
function Cnds() {};
Cnds.prototype.IsPinned = function ()
{
return !!this.pinObject;
};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.Pin = function (obj, mode_)
{
if (!obj)
return;
var otherinst = obj.getFirstPicked(this.inst);
if (!otherinst)
return;
this.pinObject = otherinst;
this.pinAngle = cr.angleTo(otherinst.x, otherinst.y, this.inst.x, this.inst.y) - otherinst.angle;
this.pinDist = cr.distanceTo(otherinst.x, otherinst.y, this.inst.x, this.inst.y);
this.myStartAngle = this.inst.angle;
this.lastKnownAngle = this.inst.angle;
this.theirStartAngle = otherinst.angle;
this.mode = mode_;
};
Acts.prototype.Unpin = function ()
{
this.pinObject = null;
};
behaviorProto.acts = new Acts();
function Exps() {};
Exps.prototype.PinnedUID = function (ret)
{
ret.set_int(this.pinObject ? this.pinObject.uid : -1);
};
behaviorProto.exps = new Exps();
}());
;
;
cr.behaviors.Rex_RotateTo = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.Rex_RotateTo.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.activated = (this.properties[0] == 1);
this.move = {"max":this.properties[1],
"acc":this.properties[2],
"dec":this.properties[3]};
this.target = {"a":0, "cw":true};
this.is_rotating = false;
this.current_speed = 0;
this.remain_distance = 0;
this.is_my_call = false;
};
behinstProto.tick = function ()
{
if ( (!this.activated) || (!this.is_rotating) )
{
return;
}
var dt = this.runtime.getDt(this.inst);
if (dt==0) // can not move if dt == 0
return;
var is_slow_down = false;
if (this.move["dec"] != 0)
{
var _speed = this.current_speed;
var _distance = (_speed*_speed)/(2*this.move["dec"]); // (v*v)/(2*a)
is_slow_down = (_distance >= this.remain_distance);
}
var acc = (is_slow_down)? (-this.move["dec"]):this.move["acc"];
if (acc != 0)
{
this.SetCurrentSpeed( this.current_speed + (acc * dt) );
}
var distance = this.current_speed * dt;
this.remain_distance -= distance;
var is_hit_target = false;
if ( (this.remain_distance <= 0) || (this.current_speed <= 0) )
{
this.is_rotating = false;
this.inst.angle = cr.to_clamped_radians(this.target["a"]);
this.SetCurrentSpeed(0);
is_hit_target = true;
}
else
{
if (this.target["cw"])
this.inst.angle += cr.to_clamped_radians(distance);
else
this.inst.angle -= cr.to_clamped_radians(distance);
}
this.inst.set_bbox_changed();
if (is_hit_target)
{
this.is_my_call = true;
this.runtime.trigger(cr.behaviors.Rex_RotateTo.prototype.cnds.OnHitTarget, this.inst);
this.is_my_call = false;
}
};
behinstProto.tick2 = function ()
{
};
behinstProto.SetCurrentSpeed = function(speed)
{
if (speed != null)
{
this.current_speed = (speed > this.move["max"])?
this.move["max"]: speed;
}
else if (this.move["acc"]==0)
{
this.current_speed = this.move["max"];
}
};
behinstProto.SetTargetAngle = function (target_angle_radians, clockwise_mode) // in radians
{
this.is_rotating = true;
var cur_angle_radians = this.inst.angle;
this.target["cw"] = (clockwise_mode == 2)? cr.angleClockwise(target_angle_radians, cur_angle_radians) :
(clockwise_mode == 1);
var remain_distance = (clockwise_mode == 2)? cr.angleDiff(cur_angle_radians, target_angle_radians) :
(clockwise_mode == 1)? (target_angle_radians - cur_angle_radians) :
(cur_angle_radians - target_angle_radians);
this.remain_distance = cr.to_clamped_degrees(remain_distance);
this.target["a"] = cr.to_clamped_degrees(target_angle_radians);
this.SetCurrentSpeed(null);
};
behinstProto.saveToJSON = function ()
{
return { "en": this.activated,
"v": this.move,
"t": this.target,
"ir": this.is_rotating,
"cs": this.current_speed,
"rd": this.remain_distance
};
};
behinstProto.loadFromJSON = function (o)
{
this.activated = o["en"];
this.move = o["v"];
this.target = o["t"];
this.is_rotating = o["ir"];
this.current_speed = o["cs"];
this.remain_distance = o["rd"];
};
function Cnds() {};
behaviorProto.cnds = new Cnds();
Cnds.prototype.OnHitTarget = function ()
{
return (this.is_my_call);
};
Cnds.prototype.CompareSpeed = function (cmp, s)
{
return cr.do_cmp(this.current_speed, cmp, s);
};
Cnds.prototype.OnMoving = function () // deprecated
{
return false;
};
Cnds.prototype.IsRotating = function ()
{
return (this.activated && this.is_rotating);
};
function Acts() {};
behaviorProto.acts = new Acts();
Acts.prototype.SetActivated = function (s)
{
this.activated = (s == 1);
};
Acts.prototype.SetMaxSpeed = function (s)
{
this.move["max"] = s;
this.SetCurrentSpeed(null);
};
Acts.prototype.SetAcceleration = function (a)
{
this.move["acc"] = a;
this.SetCurrentSpeed(null);
};
Acts.prototype.SetDeceleration = function (a)
{
this.move["dec"] = a;
};
Acts.prototype.SetTargetAngle = function (angle, clockwise_mode)
{
this.SetTargetAngle(cr.to_clamped_radians(angle), clockwise_mode)
};
Acts.prototype.SetCurrentSpeed = function (s)
{
this.SetCurrentSpeed(s);
};
Acts.prototype.SetTargetAngleOnObject = function (objtype, clockwise_mode)
{
if (!objtype)
return;
var inst = objtype.getFirstPicked();
if (inst != null)
{
var angle = Math.atan2(inst.y-this.inst.y , inst.x-this.inst.x);
this.SetTargetAngle(angle, clockwise_mode);
}
};
Acts.prototype.SetTargetAngleByDeltaAngle = function (dA, clockwise_mode)
{
var dA_rad = cr.to_clamped_radians(dA);
if (clockwise_mode==0)
dA_rad = -dA_rad;
var angle = this.inst.angle + dA_rad;
this.SetTargetAngle(angle, clockwise_mode);
};
Acts.prototype.SetTargetAngleToPos = function (tx, ty, clockwise_mode)
{
var angle = Math.atan2(ty-this.inst.y , tx-this.inst.x);
this.SetTargetAngle(angle, clockwise_mode);
};
Acts.prototype.Stop = function ()
{
this.is_rotating = false;
};
function Exps() {};
behaviorProto.exps = new Exps();
Exps.prototype.Activated = function (ret)
{
ret.set_int((this.activated)? 1:0);
};
Exps.prototype.Speed = function (ret)
{
ret.set_float(this.current_speed);
};
Exps.prototype.MaxSpeed = function (ret)
{
ret.set_float(this.move["max"]);
};
Exps.prototype.Acc = function (ret)
{
ret.set_float(this.move["acc"]);
};
Exps.prototype.Dec = function (ret)
{
ret.set_float(this.move["dec"]);
};
Exps.prototype.TargetAngle = function (ret)
{
var x = (this.is_rotating)? this.target["a"]:0;
ret.set_float(x);
};
}());
;
;
cr.behaviors.Rex_pinOffsetXY = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.Rex_pinOffsetXY.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst;
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.pinObject = null;
this.pinObjectUid = -1; // for loading
this.pinOffsetX = 0;
this.pinOffsetY = 0;
var self = this;
if (!this.recycled)
{
this.myDestroyCallback = (function(inst) {
self.onInstanceDestroyed(inst);
});
}
this.runtime.addDestroyCallback(this.myDestroyCallback);
};
behinstProto.saveToJSON = function ()
{
return {
"uid": this.pinObject ? this.pinObject.uid : -1,
"offx": this.pinOffsetX,
"offy": this.pinOffsetY,
};
};
behinstProto.loadFromJSON = function (o)
{
this.pinObjectUid = o["uid"]; // wait until afterLoad to look up
this.pinOffsetX = o["offx"];
this.pinOffsetY = o["offy"];
};
behinstProto.afterLoad = function ()
{
if (this.pinObjectUid === -1)
this.pinObject = null;
else
{
this.pinObject = this.runtime.getObjectByUID(this.pinObjectUid);
;
}
this.pinObjectUid = -1;
};
behinstProto.onInstanceDestroyed = function (inst)
{
if (this.pinObject == inst)
this.pinObject = null;
};
behinstProto.onDestroy = function()
{
this.pinObject = null;
this.runtime.removeDestroyCallback(this.myDestroyCallback);
};
behinstProto.tick = function ()
{
};
behinstProto.tick2 = function ()
{
if (!this.pinObject)
return;
var newx = this.pinObject.x + this.pinOffsetX;
var newy = this.pinObject.y + this.pinOffsetY;
if (this.inst.x !== newx || this.inst.y !== newy)
{
this.inst.x = newx;
this.inst.y = newy;
this.inst.set_bbox_changed();
}
};
function Cnds() {};
behaviorProto.cnds = new Cnds();
Cnds.prototype.IsPinned = function ()
{
return !!this.pinObject;
};
function Acts() {};
behaviorProto.acts = new Acts();
Acts.prototype.Pin = function (obj, offsetX, offsetY)
{
if (!obj)
return;
var otherinst = obj.getFirstPicked(this.inst);
if (!otherinst)
return;
if (offsetX == null)
offsetX = this.inst.x - otherinst.x;
if (offsetY == null)
offsetY = this.inst.y - otherinst.y;
this.pinObject = otherinst;
this.pinOffsetX = offsetX;
this.pinOffsetY = offsetY;
};
Acts.prototype.Unpin = function ()
{
this.pinObject = null;
};
function Exps() {};
behaviorProto.exps = new Exps();
Exps.prototype.PinnedUID = function (ret)
{
ret.set_int(this.pinObject ? this.pinObject.uid : -1);
};
}());
;
;
cr.behaviors.Sin = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.Sin.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
this.i = 0; // period offset (radians)
};
var behinstProto = behaviorProto.Instance.prototype;
var _2pi = 2 * Math.PI;
var _pi_2 = Math.PI / 2;
var _3pi_2 = (3 * Math.PI) / 2;
behinstProto.onCreate = function()
{
this.active = (this.properties[0] === 1);
this.movement = this.properties[1]; // 0=Horizontal|1=Vertical|2=Size|3=Width|4=Height|5=Angle|6=Opacity|7=Value only
this.wave = this.properties[2]; // 0=Sine|1=Triangle|2=Sawtooth|3=Reverse sawtooth|4=Square
this.period = this.properties[3];
this.period += Math.random() * this.properties[4]; // period random
if (this.period === 0)
this.i = 0;
else
{
this.i = (this.properties[5] / this.period) * _2pi; // period offset
this.i += ((Math.random() * this.properties[6]) / this.period) * _2pi; // period offset random
}
this.mag = this.properties[7]; // magnitude
this.mag += Math.random() * this.properties[8]; // magnitude random
this.initialValue = 0;
this.initialValue2 = 0;
this.ratio = 0;
if (this.movement === 5) // angle
this.mag = cr.to_radians(this.mag);
this.init();
};
behinstProto.saveToJSON = function ()
{
return {
"i": this.i,
"a": this.active,
"mv": this.movement,
"w": this.wave,
"p": this.period,
"mag": this.mag,
"iv": this.initialValue,
"iv2": this.initialValue2,
"r": this.ratio,
"lkv": this.lastKnownValue,
"lkv2": this.lastKnownValue2
};
};
behinstProto.loadFromJSON = function (o)
{
this.i = o["i"];
this.active = o["a"];
this.movement = o["mv"];
this.wave = o["w"];
this.period = o["p"];
this.mag = o["mag"];
this.initialValue = o["iv"];
this.initialValue2 = o["iv2"] || 0;
this.ratio = o["r"];
this.lastKnownValue = o["lkv"];
this.lastKnownValue2 = o["lkv2"] || 0;
};
behinstProto.init = function ()
{
switch (this.movement) {
case 0: // horizontal
this.initialValue = this.inst.x;
break;
case 1: // vertical
this.initialValue = this.inst.y;
break;
case 2: // size
this.initialValue = this.inst.width;
this.ratio = this.inst.height / this.inst.width;
break;
case 3: // width
this.initialValue = this.inst.width;
break;
case 4: // height
this.initialValue = this.inst.height;
break;
case 5: // angle
this.initialValue = this.inst.angle;
break;
case 6: // opacity
this.initialValue = this.inst.opacity;
break;
case 7:
this.initialValue = 0;
break;
case 8: // forwards/backwards
this.initialValue = this.inst.x;
this.initialValue2 = this.inst.y;
break;
default:
;
}
this.lastKnownValue = this.initialValue;
this.lastKnownValue2 = this.initialValue2;
};
behinstProto.waveFunc = function (x)
{
x = x % _2pi;
switch (this.wave) {
case 0: // sine
return Math.sin(x);
case 1: // triangle
if (x <= _pi_2)
return x / _pi_2;
else if (x <= _3pi_2)
return 1 - (2 * (x - _pi_2) / Math.PI);
else
return (x - _3pi_2) / _pi_2 - 1;
case 2: // sawtooth
return 2 * x / _2pi - 1;
case 3: // reverse sawtooth
return -2 * x / _2pi + 1;
case 4: // square
return x < Math.PI ? -1 : 1;
};
return 0;
};
behinstProto.tick = function ()
{
var dt = this.runtime.getDt(this.inst);
if (!this.active || dt === 0)
return;
if (this.period === 0)
this.i = 0;
else
{
this.i += (dt / this.period) * _2pi;
this.i = this.i % _2pi;
}
this.updateFromPhase();
};
behinstProto.updateFromPhase = function ()
{
switch (this.movement) {
case 0: // horizontal
if (this.inst.x !== this.lastKnownValue)
this.initialValue += this.inst.x - this.lastKnownValue;
this.inst.x = this.initialValue + this.waveFunc(this.i) * this.mag;
this.lastKnownValue = this.inst.x;
break;
case 1: // vertical
if (this.inst.y !== this.lastKnownValue)
this.initialValue += this.inst.y - this.lastKnownValue;
this.inst.y = this.initialValue + this.waveFunc(this.i) * this.mag;
this.lastKnownValue = this.inst.y;
break;
case 2: // size
this.inst.width = this.initialValue + this.waveFunc(this.i) * this.mag;
this.inst.height = this.inst.width * this.ratio;
break;
case 3: // width
this.inst.width = this.initialValue + this.waveFunc(this.i) * this.mag;
break;
case 4: // height
this.inst.height = this.initialValue + this.waveFunc(this.i) * this.mag;
break;
case 5: // angle
if (this.inst.angle !== this.lastKnownValue)
this.initialValue = cr.clamp_angle(this.initialValue + (this.inst.angle - this.lastKnownValue));
this.inst.angle = cr.clamp_angle(this.initialValue + this.waveFunc(this.i) * this.mag);
this.lastKnownValue = this.inst.angle;
break;
case 6: // opacity
this.inst.opacity = this.initialValue + (this.waveFunc(this.i) * this.mag) / 100;
if (this.inst.opacity < 0)
this.inst.opacity = 0;
else if (this.inst.opacity > 1)
this.inst.opacity = 1;
break;
case 8: // forwards/backwards
if (this.inst.x !== this.lastKnownValue)
this.initialValue += this.inst.x - this.lastKnownValue;
if (this.inst.y !== this.lastKnownValue2)
this.initialValue2 += this.inst.y - this.lastKnownValue2;
this.inst.x = this.initialValue + Math.cos(this.inst.angle) * this.waveFunc(this.i) * this.mag;
this.inst.y = this.initialValue2 + Math.sin(this.inst.angle) * this.waveFunc(this.i) * this.mag;
this.lastKnownValue = this.inst.x;
this.lastKnownValue2 = this.inst.y;
break;
}
this.inst.set_bbox_changed();
};
behinstProto.onSpriteFrameChanged = function (prev_frame, next_frame)
{
switch (this.movement) {
case 2: // size
this.initialValue *= (next_frame.width / prev_frame.width);
this.ratio = next_frame.height / next_frame.width;
break;
case 3: // width
this.initialValue *= (next_frame.width / prev_frame.width);
break;
case 4: // height
this.initialValue *= (next_frame.height / prev_frame.height);
break;
}
};
function Cnds() {};
Cnds.prototype.IsActive = function ()
{
return this.active;
};
Cnds.prototype.CompareMovement = function (m)
{
return this.movement === m;
};
Cnds.prototype.ComparePeriod = function (cmp, v)
{
return cr.do_cmp(this.period, cmp, v);
};
Cnds.prototype.CompareMagnitude = function (cmp, v)
{
if (this.movement === 5)
return cr.do_cmp(this.mag, cmp, cr.to_radians(v));
else
return cr.do_cmp(this.mag, cmp, v);
};
Cnds.prototype.CompareWave = function (w)
{
return this.wave === w;
};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetActive = function (a)
{
this.active = (a === 1);
};
Acts.prototype.SetPeriod = function (x)
{
this.period = x;
};
Acts.prototype.SetMagnitude = function (x)
{
this.mag = x;
if (this.movement === 5) // angle
this.mag = cr.to_radians(this.mag);
};
Acts.prototype.SetMovement = function (m)
{
if (this.movement === 5 && m !== 5)
this.mag = cr.to_degrees(this.mag);
this.movement = m;
this.init();
};
Acts.prototype.SetWave = function (w)
{
this.wave = w;
};
Acts.prototype.SetPhase = function (x)
{
this.i = (x * _2pi) % _2pi;
this.updateFromPhase();
};
Acts.prototype.UpdateInitialState = function ()
{
this.init();
};
behaviorProto.acts = new Acts();
function Exps() {};
Exps.prototype.CyclePosition = function (ret)
{
ret.set_float(this.i / _2pi);
};
Exps.prototype.Period = function (ret)
{
ret.set_float(this.period);
};
Exps.prototype.Magnitude = function (ret)
{
if (this.movement === 5) // angle
ret.set_float(cr.to_degrees(this.mag));
else
ret.set_float(this.mag);
};
Exps.prototype.Value = function (ret)
{
ret.set_float(this.waveFunc(this.i) * this.mag);
};
behaviorProto.exps = new Exps();
}());
;
;
cr.behaviors.TR_Level = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.TR_Level.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.lvl = {
baseExp: this.properties[1],
expScale: this.properties[2],
maxLevel: this.properties[3],
isDelevelingAllowed: !!this.properties[4],
expScaleMode: this.properties[5],
customExpScale: String(this.properties[6]).trim().split(","),
currentLevel: 1,
totalExp: 0,
levelExp: 0,
levelExpPool: 0
};
this.lvl.levelExpPool = this.getLevelExpPool(1);
this.levelChangeValue = 0;
};
behinstProto.onDestroy = function ()
{
};
behinstProto.saveToJSON = function ()
{
return {
"lvl": JSON.stringify(this.lvl),
};
};
behinstProto.loadFromJSON = function (o)
{
this.lvl = JSON.parse(o["lvl"]);
};
behinstProto.tick = function ()
{
};
var EXP_SCALE_MODES = {
PROGRESSIVE: 0,
CONSTANT: 1,
CUSTOM: 2
};
behinstProto.cleanArray = function(_array)
{
var i, j = 0, len = _array.length;
for (i = 0; i < len; ++i)
{
if (_array[i] === null) continue;
_array[j] = _array[i];
++j;
}
_array.length = j;
};
behinstProto.getLevelExpPool = function(level_)
{
var levelExpPool;
switch(this.lvl.expScaleMode)
{
case EXP_SCALE_MODES.PROGRESSIVE:
levelExpPool = this.lvl.baseExp * Math.pow(this.lvl.expScale, (level_ - 1));
break;
case EXP_SCALE_MODES.CONSTANT:
levelExpPool = this.lvl.baseExp + this.lvl.expScale * (level_ - 1);
break;
case EXP_SCALE_MODES.CUSTOM:
levelExpPool = this.lvl.customExpScale[level_ - 1] || this.lvl.customExpScale[this.lvl.customExpScale.length - 1];
break;
}
return Math.floor(levelExpPool);
};
behinstProto.addExperience = function(experience_)
{
if(this.lvl.currentLevel === this.lvl.maxLevel) return;
var levelChangeQty = 0;
while(experience_ > 0)
{
var missingExp = this.lvl.levelExpPool - this.lvl.levelExp;
if(missingExp > experience_)
{
this.lvl.levelExp += experience_;
this.lvl.totalExp += experience_;
experience_ = 0;
}
else
{
this.lvl.totalExp += missingExp;
experience_ -= missingExp;
++levelChangeQty;
++this.lvl.currentLevel;
this.lvl.levelExp = 0;
this.lvl.levelExpPool = this.getLevelExpPool(this.lvl.currentLevel);
this.runtime.trigger(cr.behaviors.TR_Level.prototype.cnds.OnLevelUp, this.inst);
if(this.lvl.currentLevel === this.lvl.maxLevel) break;
}
}
if(levelChangeQty > 0)
{
this.levelChangeValue = levelChangeQty;
this.runtime.trigger(cr.behaviors.TR_Level.prototype.cnds.OnLevelChange, this.inst);
this.levelChangeValue = 0;
if(this.lvl.currentLevel === this.lvl.maxLevel)
{
this.runtime.trigger(cr.behaviors.TR_Level.prototype.cnds.OnMaxLevelReached, this.inst);
}
}
this.runtime.trigger(cr.behaviors.TR_Level.prototype.cnds.OnExpAdded, this.inst);
this.runtime.trigger(cr.behaviors.TR_Level.prototype.cnds.OnExpChanged, this.inst);
};
behinstProto.subtractExperience = function(experience_)
{
if(this.lvl.totalExp < 1) return;
var levelChangeQty = 0;
while(experience_ > 0 && this.lvl.totalExp > 0)
{
if(this.lvl.levelExp >= experience_)
{
this.lvl.levelExp -= experience_;
this.lvl.totalExp -= experience_;
experience_ = 0;
}
else
{
experience_ -= this.lvl.levelExp;
this.lvl.totalExp -= this.lvl.levelExp;
this.lvl.levelExp = 0;
if(this.lvl.isDelevelingAllowed && this.lvl.currentLevel > 1)
{
--levelChangeQty;
--this.lvl.currentLevel;
this.lvl.levelExpPool = this.getLevelExpPool(this.lvl.currentLevel);
this.lvl.levelExp = this.lvl.levelExpPool;
this.runtime.trigger(cr.behaviors.TR_Level.prototype.cnds.OnLevelDown, this.inst);
}
else
{
break;
}
}
}
if(levelChangeQty < 0)
{
this.levelChangeValue = levelChangeQty;
this.runtime.trigger(cr.behaviors.TR_Level.prototype.cnds.OnLevelChange, this.inst);
this.levelChangeValue = 0;
}
this.runtime.trigger(cr.behaviors.TR_Level.prototype.cnds.OnExpSubtracted, this.inst);
this.runtime.trigger(cr.behaviors.TR_Level.prototype.cnds.OnExpChanged, this.inst);
};
behinstProto.getTotalExp = function(level_)
{
if(level_ < 1) return 0;
var i, totalExp = 0;
for(i = 1; i <= level_; ++i)
{
totalExp += this.getLevelExpPool(i);
}
return totalExp;
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnLevelUp = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnLevelDown = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnLevelChange = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnExpAdded = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnExpSubtracted = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnExpChanged = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnMaxLevelReached = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.OnLevelReached = function (level_)
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.LevelCompare = function (cmp_, value_)
{
return cr.do_cmp(this.lvl.currentLevel, cmp_, value_);
};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.AddExperience = function (experience_)
{
this.addExperience(experience_);
};
Acts.prototype.SubtractExperience = function (experience_)
{
this.subtractExperience(experience_);
};
Acts.prototype.SetExperience = function (experience_)
{
if(experience_ > this.lvl.totalExp)
{
this.addExperience(experience_ - this.lvl.totalExp);
}
else
if(experience_ < this.lvl.totalExp)
{
this.subtractExperience(this.lvl.totalExp - experience_);
}
};
Acts.prototype.SetExperienceScale = function (scale_)
{
this.lvl.expScale = scale_;
};
Acts.prototype.SetMaxLevel = function (level_)
{
this.lvl.maxLevel = level_;
};
Acts.prototype.LoadFromJSON = function (JSON_)
{
this.lvl = JSON.parse(JSON_);
};
behaviorProto.acts = new Acts();
function Exps() {};
/*Exps.prototype.MyExpression = function (ret) // 'ret' must always be the first parameter - always return the expression's result through it!
{
ret.set_int(1337); // return our value
};*/
Exps.prototype.AsJSON = function (ret)
{
ret.set_string(JSON.stringify(this.lvl));
};
Exps.prototype.CurrentLevel = function (ret)
{
ret.set_int(this.lvl.currentLevel);
};
Exps.prototype.MaxLevel = function (ret)
{
ret.set_int(this.lvl.maxLevel);
};
Exps.prototype.LevelExpValue = function (ret)
{
ret.set_int(this.lvl.levelExp);
};
Exps.prototype.LevelExpProgress = function (ret)
{
ret.set_float(Math.floor((this.lvl.levelExp/this.lvl.levelExpPool) * 100) / 100);
};
Exps.prototype.LevelExpPool = function (ret)
{
var level = arguments[1] || this.lvl.currentLevel;
var value = level === this.lvl.currentLevel ? this.lvl.levelExpPool : this.getLevelExpPool(level);
ret.set_int(value);
};
Exps.prototype.TotalExp = function (ret)
{
var value;
if(arguments[1])
{
value = this.getTotalExp(arguments[1]);
}
else
{
value = this.lvl.totalExp;
}
ret.set_int(value);
};
Exps.prototype.LevelChangeValue = function (ret)
{
ret.set_int(this.levelChangeValue);
};
behaviorProto.exps = new Exps();
}());
;
;
cr.behaviors.TR_Scale = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.TR_Scale.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
this.SCALE_DIMENSION =
{
GENERAL: 0,
WIDTH: 1,
HEIGHT: 2
};
this.SCALE_TYPE =
{
SELF: 0,
MASTER: 1,
IMAGE: 2
};
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.initialDimensions = {};
this.isParentValidObject = (this.inst.type.plugin.acts.SetSize && typeof this.inst.width !== "undefined" && typeof this.inst.height !== "undefined");
/*if (this.isParentValidObject)
{
var self = this;
var loop = setInterval(function()
{
if ( ! self.inst.curFrame) return; // this will most probably be never true, but let's leave it here just in case
clearInterval(loop);
/!* initialWidthScale = self.inst.width / self.inst.curFrame.width;
initialHeightScale = self.inst.height / self.inst.curFrame.height;
var i, j, len, len2, a, f;
for (i = 0, len = self.inst.type.animations.length; i < len; ++i)
{
a = self.inst.type.animations[i];
self.initialDimensions[a.name] = [];
for (j = 0, len2 = a.frames.length; j < len2; ++j)
{
f = a.frames[j];
self.initialDimensions[a.name].push(
{
width: f.width * initialWidthScale,
height: f.height * initialHeightScale
}
);
}
}*!/
}, 1);
}*/
};
behinstProto.postCreate = function()
{
if ( ! this.isParentValidObject) return;
var initialWidthScale = null;
var initialHeightScale = null;
var self = this;
initialWidthScale = self.inst.width / self.inst.curFrame.width;
initialHeightScale = self.inst.height / self.inst.curFrame.height;
var i, j, len, len2, a, f;
for (i = 0, len = self.inst.type.animations.length; i < len; ++i)
{
a = self.inst.type.animations[i];
self.initialDimensions[a.name] = [];
for (j = 0, len2 = a.frames.length; j < len2; ++j)
{
f = a.frames[j];
self.initialDimensions[a.name].push(
{
width: f.width * initialWidthScale,
height: f.height * initialHeightScale
}
);
}
}
};
behinstProto.getInitialWidth = function()
{
if(this.initialDimensions[this.inst.cur_animation.name] && this.initialDimensions[this.inst.cur_animation.name][this.inst.cur_frame])
{
return this.initialDimensions[this.inst.cur_animation.name][this.inst.cur_frame].width;
}
else
{
return NaN;
}
};
behinstProto.getInitialHeight = function()
{
if(this.initialDimensions[this.inst.cur_animation.name] && this.initialDimensions[this.inst.cur_animation.name][this.inst.cur_frame])
{
return this.initialDimensions[this.inst.cur_animation.name][this.inst.cur_frame].height;
}
else
{
return NaN;
}
};
behinstProto.onDestroy = function ()
{
};
/*// called when saving the full state of the game
behinstProto.saveToJSON = function ()
{
return {
};
};*/
/*// called when loading the full state of the game
behinstProto.loadFromJSON = function (o)
{
};*/
behinstProto.tick = function ()
{
};
behinstProto.setScale = function(dimensionType_, scaleType_, value_)
{
if ( ! this.isParentValidObject) return;
var height, width, baseHeight, baseWidth;
var mirrorFactor = (this.inst.width < 0 ? -1 : 1);
var flipFactor = (this.inst.height < 0 ? -1 : 1);
switch (scaleType_)
{
case this.type.SCALE_TYPE.SELF:
baseWidth = this.getInitialWidth();
baseHeight = this.getInitialHeight();
break;
/*case this.type.SCALE_TYPE.MASTER:
break;*/
case this.type.SCALE_TYPE.IMAGE:
baseWidth = this.inst.curFrame.width;
baseHeight = this.inst.curFrame.height;
break;
}
switch (dimensionType_)
{
case this.type.SCALE_DIMENSION.GENERAL:
width = value_ * baseWidth * mirrorFactor;
height = value_ * baseHeight * flipFactor;
this.inst.type.plugin.acts.SetSize.call(this.inst, width, height);
break;
case this.type.SCALE_DIMENSION.WIDTH:
width = value_ * baseWidth * mirrorFactor;
this.inst.type.plugin.acts.SetWidth.call(this.inst, width);
break;
case this.type.SCALE_DIMENSION.HEIGHT:
height = value_ * baseHeight * flipFactor;
this.inst.type.plugin.acts.SetHeight.call(this.inst, height);
break;
}
this.runtime.trigger(cr.behaviors.TR_Scale.prototype.cnds.OnScaleChanged, this.inst);
};
behinstProto.getScale = function(dimensionType_, scaleType_)
{
if ( ! this.isParentValidObject) return -1;
var scale, baseHeight, baseWidth;
switch (scaleType_)
{
case this.type.SCALE_TYPE.SELF:
baseWidth = this.getInitialWidth();
baseHeight = this.getInitialHeight();
break;
/*case this.type.SCALE_TYPE.MASTER:
break;*/
case this.type.SCALE_TYPE.IMAGE:
baseWidth = this.inst.curFrame.width;
baseHeight = this.inst.curFrame.height;
break;
}
switch (dimensionType_)
{
case this.type.SCALE_DIMENSION.GENERAL:
var scaleWidth = this.inst.width / baseWidth;
var scaleHeight = this.inst.height / baseHeight;
scale = (scaleWidth + scaleHeight) / 2;
break;
case this.type.SCALE_DIMENSION.WIDTH:
scale = this.inst.width / baseWidth;
break;
case this.type.SCALE_DIMENSION.HEIGHT:
scale = this.inst.height / baseHeight;
break;
}
return scale;
};
behinstProto.isValidObject = function()
{
return this.isParentValidObject;
};
function Cnds() {};
/**
* @returns {boolean}
*/
Cnds.prototype.OnScaleChanged = function ()
{
return true;
};
/**
* @returns {boolean}
*/
Cnds.prototype.CompareScaleSelf = function (scaleDimension_, cmp_, value_)
{
return cr.do_cmp(this.getScale(scaleDimension_, this.type.SCALE_TYPE.SELF), cmp_, value_);
};
/**
* @returns {boolean}
*/
Cnds.prototype.CompareScaleImage = function (scaleDimension_, cmp_, value_)
{
return cr.do_cmp(this.getScale(scaleDimension_, this.type.SCALE_TYPE.IMAGE), cmp_, value_);
};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetScaleSelf = function (scaleDimension_, value_)
{
this.setScale(scaleDimension_, this.type.SCALE_TYPE.SELF, value_);
};
Acts.prototype.SetScaleImage = function (scaleDimension_, value_)
{
this.setScale(scaleDimension_, this.type.SCALE_TYPE.IMAGE, value_);
};
behaviorProto.acts = new Acts();
function Exps() {};
/*Exps.prototype.MyExpression = function (ret) // 'ret' must always be the first parameter - always return the expression's result through it!
{
ret.set_int(1337); // return our value
};*/
Exps.prototype.Self = function (ret)
{
ret.set_float(this.getScale(this.type.SCALE_DIMENSION.GENERAL, this.type.SCALE_TYPE.SELF)); // for returning floats
};
Exps.prototype.SelfWidth = function (ret)
{
ret.set_float(this.getScale(this.type.SCALE_DIMENSION.WIDTH, this.type.SCALE_TYPE.SELF)); // for returning floats
};
Exps.prototype.SelfHeight = function (ret)
{
ret.set_float(this.getScale(this.type.SCALE_DIMENSION.HEIGHT, this.type.SCALE_TYPE.SELF)); // for returning floats
};
Exps.prototype.Image = function (ret)
{
ret.set_float(this.getScale(this.type.SCALE_DIMENSION.GENERAL, this.type.SCALE_TYPE.IMAGE)); // for returning floats
};
Exps.prototype.ImageWidth = function (ret)
{
ret.set_float(this.getScale(this.type.SCALE_DIMENSION.WIDTH, this.type.SCALE_TYPE.IMAGE)); // for returning floats
};
Exps.prototype.ImageHeight = function (ret)
{
ret.set_float(this.getScale(this.type.SCALE_DIMENSION.HEIGHT, this.type.SCALE_TYPE.IMAGE)); // for returning floats
};
behaviorProto.exps = new Exps();
}());
;
;
cr.behaviors.Timer = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.Timer.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.timers = {};
};
behinstProto.onDestroy = function ()
{
cr.wipe(this.timers);
};
behinstProto.saveToJSON = function ()
{
var o = {};
var p, t;
for (p in this.timers)
{
if (this.timers.hasOwnProperty(p))
{
t = this.timers[p];
o[p] = {
"c": t.current.sum,
"t": t.total.sum,
"d": t.duration,
"r": t.regular
};
}
}
return o;
};
behinstProto.loadFromJSON = function (o)
{
this.timers = {};
var p;
for (p in o)
{
if (o.hasOwnProperty(p))
{
this.timers[p] = {
current: new cr.KahanAdder(),
total: new cr.KahanAdder(),
duration: o[p]["d"],
regular: o[p]["r"]
};
this.timers[p].current.sum = o[p]["c"];
this.timers[p].total.sum = o[p]["t"];
}
}
};
behinstProto.tick = function ()
{
var dt = this.runtime.getDt(this.inst);
var p, t;
for (p in this.timers)
{
if (this.timers.hasOwnProperty(p))
{
t = this.timers[p];
t.current.add(dt);
t.total.add(dt);
}
}
};
behinstProto.tick2 = function ()
{
var p, t;
for (p in this.timers)
{
if (this.timers.hasOwnProperty(p))
{
t = this.timers[p];
if (t.current.sum >= t.duration)
{
if (t.regular)
t.current.sum -= t.duration;
else
delete this.timers[p];
}
}
}
};
function Cnds() {};
Cnds.prototype.OnTimer = function (tag_)
{
tag_ = tag_.toLowerCase();
var t = this.timers[tag_];
if (!t)
return false;
return t.current.sum >= t.duration;
};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.StartTimer = function (duration_, type_, tag_)
{
this.timers[tag_.toLowerCase()] = {
current: new cr.KahanAdder(),
total: new cr.KahanAdder(),
duration: duration_,
regular: (type_ === 1)
};
};
Acts.prototype.StopTimer = function (tag_)
{
tag_ = tag_.toLowerCase();
if (this.timers.hasOwnProperty(tag_))
delete this.timers[tag_];
};
behaviorProto.acts = new Acts();
function Exps() {};
Exps.prototype.CurrentTime = function (ret, tag_)
{
var t = this.timers[tag_.toLowerCase()];
ret.set_float(t ? t.current.sum : 0);
};
Exps.prototype.TotalTime = function (ret, tag_)
{
var t = this.timers[tag_.toLowerCase()];
ret.set_float(t ? t.total.sum : 0);
};
Exps.prototype.Duration = function (ret, tag_)
{
var t = this.timers[tag_.toLowerCase()];
ret.set_float(t ? t.duration : 0);
};
behaviorProto.exps = new Exps();
}());
;
;
cr.behaviors.aekiro_progress = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.aekiro_progress.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst;
this.runtime = type.runtime;
if(!cr.proui){
throw new Error("ProUI Plugin not found. Please add it to the project.");
return;
}
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.proui = cr.proui;
this.proui.isTypeValid(this.inst,[cr.plugins_.Sprite,cr.plugins_.NinePatch,cr.plugins_.TiledBg],"Pro UI: ProgressBar behavior is only applicable to Sprite , 9-patch or Tiled Background objects.");
this.progressType = 0;
this.maxValue = this.properties[0];
this.value = cr.clamp(this.properties[1],0,this.maxValue);
this.animation = this.properties[2];
this.firstFrame = true;
this.inst.uiType = "progress";
this.uiType = "progress";
this.inst._proui = this;
this.compParent = this;
this.isInit = false;
this.initWidth = 0;
this.initHeight = 0;
this.tween = new TWEEN["Tween"](this.inst);
if(this.animation == 1){
this.tween["easing"](TWEEN["Easing"]["Linear"]["None"]);
}else if(this.animation == 2){
this.tween["easing"](TWEEN["Easing"]["Quadratic"]["Out"]);
}
};
behinstProto.updateFromModel = function (){
if(this.runtime.extra.notRegister){
return;
}
var modelB = this.inst.proui_model;
if(modelB){
var value = modelB.getFromModel();
if(value == null){
return;
}
value = this.proui.validateSimpleValue(value,0);
value = cr.clamp(value,0,this.maxValue);
if(this.value!=value){
this.value = value;
}
}
};
behinstProto.setValue = function (value){
this.firstSetValue = true;
if(this._setValue(value)){
var modelB = this.inst.proui_model;
if(modelB){
modelB.setModelValue(value,{except:this.compParent});
}
if(this.inst.proui_bind){
this.inst.proui_bind.updateGridViewModel(value,{except:this.compParent});
}
}
};
behinstProto._setValue = function (value){
if(value == null){
return false;
}
value = this.proui.validateSimpleValue(value,0);
value = cr.clamp(value,0,this.maxValue);
if(this.value!=value){
this.value = value;
this.updateView();
return true;
}else{
return false;
}
};
behinstProto.updateView = function (){
if(!this.isInit){
return;
}
var targetProp = 0;
var progress = this.value/this.maxValue;
if(this.progressType == 0){
targetProp = progress*this.initWidth;
}else if (this.progressType == 1){
targetProp = progress*this.initHeight;
}
if(this.firstFrame || !this.animation){
if(this.progressType == 0){
this.inst.width = targetProp;
}else if (this.progressType == 1){
this.inst.height = targetProp;
}
this.inst.set_bbox_changed();
}else if(this.animation){
if(this.progressType == 0){
this.tween["to"]({ width:targetProp}, 500)["start"]();
}else if (this.progressType == 1){
this.tween["to"]({ height:targetProp}, 500)["start"]();
}
}
};
behinstProto.init = function (){
if(this.isInit){
return;
}
this.inst.cur_anim_speed = 0;
this.initWidth = this.inst.width;
this.initHeight = this.inst.height;
this.isInit = true;
};
behinstProto.tick = function ()
{
if(this.firstFrame){
this.init();
if(!this.firstSetValue){
this.updateFromModel();
}
this.updateView();
this.firstFrame = false; // has to be after the updateView so that no animation is played in the begining
}
if(this.tween["isPlaying"]){
var dt = this.runtime.getDt(this.inst)*1000
this.tween["update"](dt);
this.inst.set_bbox_changed();
}
};
behinstProto.onDestroy = function ()
{
};
behinstProto.saveToJSON = function ()
{
return {
"maxValue" : this.maxValue,
"animation" : this.animation,
"value" : this.value,
"progressType" : this.progressType,
"initWidth":this.initWidth,
"initHeight":this.initHeight,
};
};
behinstProto.loadFromJSON = function (o)
{
this.maxValue = o["maxValue"];
this.animation = o["animation"];
this.value = o["value"];
this.progressType = o["progressType"];
this.initWidth = o["initWidth"];
this.initHeight = o["initHeight"];
this.inst.width = this.initWidth;
this.inst.height = this.initHeight;
};
function Cnds() {};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.setValue = function (value){
this.setValue(value);
};
behaviorProto.acts = new Acts();
function Exps() {};
Exps.prototype.value = function (ret)
{
ret.set_float(this.value);
};
behaviorProto.exps = new Exps();
}());
;
;
cr.behaviors.bound = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.bound.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
this.mode = 0;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.mode = this.properties[0]; // 0 = origin, 1 = edge
};
behinstProto.tick = function ()
{
};
behinstProto.tick2 = function ()
{
this.inst.update_bbox();
var bbox = this.inst.bbox;
var layout = this.inst.layer.layout;
var changed = false;
if (this.mode === 0) // origin
{
if (this.inst.x < 0)
{
this.inst.x = 0;
changed = true;
}
if (this.inst.y < 0)
{
this.inst.y = 0;
changed = true;
}
if (this.inst.x > layout.width)
{
this.inst.x = layout.width;
changed = true;
}
if (this.inst.y > layout.height)
{
this.inst.y = layout.height;
changed = true;
}
}
else
{
if (bbox.left < 0)
{
this.inst.x -= bbox.left;
changed = true;
}
if (bbox.top < 0)
{
this.inst.y -= bbox.top;
changed = true;
}
if (bbox.right > layout.width)
{
this.inst.x -= (bbox.right - layout.width);
changed = true;
}
if (bbox.bottom > layout.height)
{
this.inst.y -= (bbox.bottom - layout.height);
changed = true;
}
}
if (changed)
this.inst.set_bbox_changed();
};
}());
;
;
cr.behaviors.destroy = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.destroy.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
};
behinstProto.tick = function ()
{
this.inst.update_bbox();
var bbox = this.inst.bbox;
var layout = this.inst.layer.layout;
if (bbox.right < 0 || bbox.bottom < 0 || bbox.left > layout.width || bbox.top > layout.height)
this.runtime.DestroyInstance(this.inst);
};
}());
var easeOutBounceArray = [];
var easeInElasticArray = [];
var easeOutElasticArray = [];
var easeInOutElasticArray = [];
var easeInCircle = [];
var easeOutCircle = [];
var easeInOutCircle = [];
var easeInBack = [];
var easeOutBack = [];
var easeInOutBack = [];
var litetween_precision = 10000;
var updateLimit = 0; //0.0165;
function easeOutBouncefunc(t) {
var b=0.0;
var c=1.0;
var d=1.0;
if ((t/=d) < (1/2.75)) {
result = c*(7.5625*t*t) + b;
} else if (t < (2/2.75)) {
result = c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
} else if (t < (2.5/2.75)) {
result = c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
} else {
result = c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
}
return result;
}
function integerize(t, d)
{
return Math.round(t/d*litetween_precision);
}
function easeFunc(easing, t, b, c, d, flip, param)
{
var ret_ease = 0;
switch (easing) {
case 0: // linear
ret_ease = c*t/d + b;
break;
case 1: // easeInQuad
ret_ease = c*(t/=d)*t + b;
break;
case 2: // easeOutQuad
ret_ease = -c *(t/=d)*(t-2) + b;
break;
case 3: // easeInOutQuad
if ((t/=d/2) < 1)
ret_ease = c/2*t*t + b
else
ret_ease = -c/2 * ((--t)*(t-2) - 1) + b;
break;
case 4: // easeInCubic
ret_ease = c*(t/=d)*t*t + b;
break;
case 5: // easeOutCubic
ret_ease = c*((t=t/d-1)*t*t + 1) + b;
break;
case 6: // easeInOutCubic
if ((t/=d/2) < 1)
ret_ease = c/2*t*t*t + b
else
ret_ease = c/2*((t-=2)*t*t + 2) + b;
break;
case 7: // easeInQuart
ret_ease = c*(t/=d)*t*t*t + b;
break;
case 8: // easeOutQuart
ret_ease = -c * ((t=t/d-1)*t*t*t - 1) + b;
break;
case 9: // easeInOutQuart
if ((t/=d/2) < 1)
ret_ease = c/2*t*t*t*t + b
else
ret_ease = -c/2 * ((t-=2)*t*t*t - 2) + b;
break;
case 10: // easeInQuint
ret_ease = c*(t/=d)*t*t*t*t + b;
break;
case 11: // easeOutQuint
ret_ease = c*((t=t/d-1)*t*t*t*t + 1) + b;
break;
case 12: // easeInOutQuint
if ((t/=d/2) < 1)
ret_ease = c/2*t*t*t*t*t + b
else
ret_ease = c/2*((t-=2)*t*t*t*t + 2) + b;
break;
case 13: // easeInCircle
if (param.optimized) {
ret_ease = easeInCircle[integerize(t,d)];
} else {
ret_ease = -(Math.sqrt(1-t*t) - 1);
}
break;
case 14: // easeOutCircle
if (param.optimized) {
ret_ease = easeOutCircle[integerize(t,d)];
} else {
ret_ease = Math.sqrt(1 - ((t-1)*(t-1)));
}
break;
case 15: // easeInOutCircle
if (param.optimized) {
ret_ease = easeInOutCircle[integerize(t,d)];
} else {
if ((t/=d/2) < 1) ret_ease = -c/2 * (Math.sqrt(1 - t*t) - 1) + b
else ret_ease = c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
}
break;
case 16: // easeInBack
if (param.optimized) {
ret_ease = easeInBack[integerize(t,d)];
} else {
var s = param.s;
ret_ease = c*(t/=d)*t*((s+1)*t - s) + b;
}
break;
case 17: // easeOutBack
if (param.optimized) {
ret_ease = easeOutBack[integerize(t,d)];
} else {
var s = param.s;
ret_ease = c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
}
break;
case 18: // easeInOutBack
if (param.optimized) {
ret_ease = easeInOutBack[integerize(t,d)];
} else {
var s = param.s
if ((t/=d/2) < 1)
ret_ease = c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b
else
ret_ease = c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
}
break;
case 19: //easeInElastic
if (param.optimized) {
ret_ease = easeInElasticArray[integerize(t, d)];
} else {
var a = param.a;
var p = param.p;
var s = 0;
if (t==0) ret_ease = b; if ((t/=d)==1) ret_ease = b+c;
if (p==0) p=d*.3; if (a==0 || a < Math.abs(c)) { a=c; s=p/4; }
else var s = p/(2*Math.PI) * Math.asin (c/a);
ret_ease = -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
}
break;
case 20: //easeOutElastic
if (param.optimized) {
ret_ease = easeOutElasticArray[integerize(t,d)];
} else {
var a = param.a;
var p = param.p;
var s = 0;
if (t==0) ret_ease= b; if ((t/=d)==1) ret_ease= b+c; if (p == 0) p=d*.3;
if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
else var s = p/(2*Math.PI) * Math.asin (c/a);
ret_ease= (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
}
break;
case 21: //easeInOutElastic
if (param.optimized) {
ret_ease = easeInOutElasticArray[integerize(t,d)];
} else {
var a = param.a;
var p = param.p;
var s = 0;
if (t==0) ret_ease = b;
if ((t/=d/2)==2) ret_ease = b+c;
if (p==0) p=d*(.3*1.5);
if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
else var s = p/(2*Math.PI) * Math.asin (c/a);
if (t < 1)
ret_ease = -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b
else
ret_ease = a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
}
break;
case 22: //easeInBounce
if (param.optimized) {
ret_ease = c - easeOutBounceArray[integerize(d-t, d)] + b;
} else {
ret_ease = c - easeOutBouncefunc(d-t/d) + b;
}
break;
case 23: //easeOutBounce
if (param.optimized) {
ret_ease = easeOutBounceArray[integerize(t, d)];
} else {
ret_ease = easeOutBouncefunc(t/d);
}
break;
case 24: //easeInOutBounce
if (param.optimized) {
if (t < d/2)
ret_ease = (c - easeOutBounceArray[integerize(d-(t*2), d)] + b) * 0.5 +b;
else
ret_ease = easeOutBounceArray[integerize(t*2-d, d)] * .5 + c*.5 + b;
} else {
if (t < d/2)
ret_ease = (c - easeOutBouncefunc(d-(t*2)) + b) * 0.5 +b;
else
ret_ease = easeOutBouncefunc((t*2-d)/d) * .5 + c *.5 + b;
}
break;
case 25: //easeInSmoothstep
var mt = (t/d) / 2;
ret_ease = (2*(mt * mt * (3 - 2*mt)));
break;
case 26: //easeOutSmoothstep
var mt = ((t/d) + 1) / 2;
ret_ease = ((2*(mt * mt * (3 - 2*mt))) - 1);
break;
case 27: //easeInOutSmoothstep
var mt = (t / d);
ret_ease = (mt * mt * (3 - 2*mt));
break;
};
if (flip)
return (c - b) - ret_ease
else
return ret_ease;
};
(function preCalculateArray() {
var d = 1.0;
var b = 0.0;
var c = 1.0;
var result = 0.0;
var a = 0.0;
var p = 0.0;
var t = 0.0;
var s = 0.0;
for (var ti = 0; ti <= litetween_precision; ti++) {
t = ti/litetween_precision;
if ((t/=d) < (1/2.75)) {
result = c*(7.5625*t*t) + b;
} else if (t < (2/2.75)) {
result = c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
} else if (t < (2.5/2.75)) {
result = c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
} else {
result = c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
}
easeOutBounceArray[ti] = result;
t = ti/litetween_precision; a = 0; p = 0;
if (t==0) result = b; if ((t/=d)==1) result = b+c;
if (p==0) p=d*.3; if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
else var s = p/(2*Math.PI) * Math.asin (c/a);
result = -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
easeInElasticArray[ti] = result;
t = ti/litetween_precision; a = 0; p = 0;
if (t==0) result= b; if ((t/=d)==1) result= b+c; if (p == 0) p=d*.3;
if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
else var s = p/(2*Math.PI) * Math.asin (c/a);
result= (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
easeOutElasticArray[ti] = result;
t = ti/litetween_precision; a = 0; p = 0;
if (t==0) result = b;
if ((t/=d/2)==2) result = b+c;
if (p==0) p=d*(.3*1.5);
if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
else var s = p/(2*Math.PI) * Math.asin (c/a);
if (t < 1)
result = -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b
else
result = a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
easeInOutElasticArray[ti] = result;
t = ti/litetween_precision; easeInCircle[ti] = -(Math.sqrt(1-t*t) - 1);
t = ti/litetween_precision; easeOutCircle[ti] = Math.sqrt(1 - ((t-1)*(t-1)));
t = ti/litetween_precision;
if ((t/=d/2) < 1) result = -c/2 * (Math.sqrt(1 - t*t) - 1) + b
else result = c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
easeInOutCircle[ti] = result;
t = ti/litetween_precision; s = 0;
if (s==0) s = 1.70158;
result = c*(t/=d)*t*((s+1)*t - s) + b;
easeInBack[ti] = result;
t = ti/litetween_precision; s = 0;
if (s==0) s = 1.70158;
result = c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
easeOutBack[ti] = result;
t = ti/litetween_precision; s = 0; if (s==0) s = 1.70158;
if ((t/=d/2) < 1)
result = c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b
else
result = c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
easeInOutBack[ti] = result;
}
}());
var TweenObject = function()
{
var constructor = function (tname, tweened, easefunc, initial, target, duration, enforce)
{
this.name = tname;
this.value = 0;
this.setInitial(initial);
this.setTarget(target);
this.easefunc = easefunc;
this.tweened = tweened;
this.duration = duration;
this.progress = 0;
this.state = 0;
this.onStart = false;
this.onEnd = false;
this.onReverseStart = false;
this.onReverseEnd = false;
this.lastKnownValue = 0;
this.lastKnownValue2 = 0;
this.enforce = enforce;
this.pingpong = 1.0;
this.flipEase = false;
this.easingparam = [];
this.lastState = 1;
for (var i=0; i<28; i++) {
this.easingparam[i] = {};
this.easingparam[i].a = 0.0;
this.easingparam[i].p = 0.0;
this.easingparam[i].t = 0.0;
this.easingparam[i].s = 0.0;
this.easingparam[i].optimized = true;
}
}
return constructor;
}();
(function () {
TweenObject.prototype = {
};
TweenObject.prototype.flipTarget = function ()
{
var x1 = this.initialparam1;
var x2 = this.initialparam2;
this.initialparam1 = this.targetparam1;
this.initialparam2 = this.targetparam2;
this.targetparam1 = x1;
this.targetparam2 = x2;
this.lastKnownValue = 0;
this.lastKnownValue2 = 0;
}
TweenObject.prototype.setInitial = function (initial)
{
this.initialparam1 = parseFloat(initial.split(",")[0]);
this.initialparam2 = parseFloat(initial.split(",")[1]);
this.lastKnownValue = 0;
this.lastKnownValue2 = 0;
}
TweenObject.prototype.setTarget = function (target)
{
this.targetparam1 = parseFloat(target.split(",")[0]);
this.targetparam2 = parseFloat(target.split(",")[1]);
if (isNaN(this.targetparam2)) this.targetparam2 = this.targetparam1;
}
TweenObject.prototype.OnTick = function(dt)
{
if (this.state === 0) return -1.0;
if (this.state === 1)
this.progress += dt;
if (this.state === 2)
this.progress -= dt;
if (this.state === 3) {
this.state = 0;
}
if ((this.state === 4) || (this.state === 6)) {
this.progress += dt * this.pingpong;
}
if (this.state === 5) {
this.progress += dt * this.pingpong;
}
if (this.progress < 0) {
this.progress = 0;
if (this.state === 4) {
this.pingpong = 1;
} else if (this.state === 6) {
this.pingpong = 1;
this.flipEase = false;
} else {
this.state = 0;
}
this.onReverseEnd = true;
return 0.0;
} else if (this.progress > this.duration) {
this.progress = this.duration;
if (this.state === 4) {
this.pingpong = -1;
} else if (this.state === 6) {
this.pingpong = -1;
this.flipEase = true;
} else if (this.state === 5) {
this.progress = 0.0;
} else {
this.state = 0;
}
this.onEnd = true;
return 1.0;
} else {
if (this.flipEase) {
var factor = easeFunc(this.easefunc, this.duration - this.progress, 0, 1, this.duration, this.flipEase, this.easingparam[this.easefunc]);
} else {
var factor = easeFunc(this.easefunc, this.progress, 0, 1, this.duration, this.flipEase, this.easingparam[this.easefunc]);
}
return factor;
}
};
}());
;
;
function trim (str) {
return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
cr.behaviors.lunarray_LiteTween = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.lunarray_LiteTween.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
this.i = 0; // progress
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.playmode = this.properties[0];
this.active = (this.playmode == 1) || (this.playmode == 2) || (this.playmode == 3) || (this.playmode == 4);
this.tweened = this.properties[1]; // 0=Position|1=Size|2=Width|3=Height|4=Angle|5=Opacity|6=Value only|7=Horizontal|8=Vertical|9=Scale
this.easing = this.properties[2];
this.target = this.properties[3];
this.targetmode = this.properties[4];
this.useCurrent = false;
if (this.targetmode === 1) this.target = "relative("+this.target+")";
this.duration = this.properties[5];
this.enforce = (this.properties[6] === 1);
this.value = 0;
this.tween_list = {};
this.addToTweenList("default", this.tweened, this.easing, "current", this.target, this.duration, this.enforce);
if (this.properties[0] === 1) this.startTween(0)
if (this.properties[0] === 2) this.startTween(2)
if (this.properties[0] === 3) this.startTween(3)
if (this.properties[0] === 4) this.startTween(4)
};
behinstProto.parseCurrent = function(tweened, parseText)
{
if (parseText === undefined) parseText = "current";
var parsed = trim(parseText);
parseText = trim(parseText);
var value = this.value;
if (parseText === "current") {
switch (tweened) {
case 0: parsed = this.inst.x + "," + this.inst.y; break;
case 1: parsed = this.inst.width + "," + this.inst.height; break;
case 2: parsed = this.inst.width + "," + this.inst.height; break;
case 3: parsed = this.inst.width + "," + this.inst.height; break;
case 4: parsed = cr.to_degrees(this.inst.angle) + "," + cr.to_degrees(this.inst.angle); break;
case 5: parsed = (this.inst.opacity*100) + "," + (this.inst.opacity*100); break;
case 6: parsed = value + "," + value; break;
case 7: parsed = this.inst.x + "," + this.inst.y; break;
case 8: parsed = this.inst.x + "," + this.inst.y; break;
case 9:
if (this.inst.curFrame !== undefined)
parsed = (this.inst.width/this.inst.curFrame.width) + "," +(this.inst.height/this.inst.curFrame.height)
else
parsed = "1,1";
break;
default: break;
}
}
if (parseText.substring(0,8) === "relative") {
var param1 = parseText.match(/\((.*?)\)/);
if (param1) {
var relativex = parseFloat(param1[1].split(",")[0]);
var relativey = parseFloat(param1[1].split(",")[1]);
}
if (isNaN(relativex)) relativex = 0;
if (isNaN(relativey)) relativey = 0;
switch (tweened) {
case 0: parsed = (this.inst.x+relativex) + "," + (this.inst.y+relativey); break;
case 1: parsed = (this.inst.width+relativex) + "," + (this.inst.height+relativey); break;
case 2: parsed = (this.inst.width+relativex) + "," + (this.inst.height+relativey); break;
case 3: parsed = (this.inst.width+relativex) + "," + (this.inst.height+relativey); break;
case 4: parsed = (cr.to_degrees(this.inst.angle)+relativex) + "," + (cr.to_degrees(this.inst.angle)+relativey); break;
case 5: parsed = (this.inst.opacity*100+relativex) + "," + (this.inst.opacity*100+relativey); break;
case 6: parsed = value+relativex + "," + value+relativex; break;
case 7: parsed = (this.inst.x+relativex) + "," + (this.inst.y); break;
case 8: parsed = (this.inst.x) + "," + (this.inst.y+relativex); break;
case 9: parsed = (relativex) + "," + (relativey); break;
default: break;
}
}
return parsed;
};
behinstProto.addToTweenList = function(tname, tweened, easing, init, targ, duration, enforce)
{
init = this.parseCurrent(tweened, init);
targ = this.parseCurrent(tweened, targ);
if (this.tween_list[tname] !== undefined) {
delete this.tween_list[tname]
}
this.tween_list[tname] = new TweenObject(tname, tweened, easing, init, targ, duration, enforce);
this.tween_list[tname].dt = 0;
};
behinstProto.saveToJSON = function ()
{
var v = JSON.stringify(this.tween_list["default"]);
return {
"playmode": this.playmode,
"active": this.active,
"tweened": this.tweened,
"easing": this.easing,
"target": this.target,
"targetmode": this.targetmode,
"useCurrent": this.useCurrent,
"duration": this.duration,
"enforce": this.enforce,
"value": this.value,
"tweenlist": JSON.stringify(this.tween_list["default"])
};
};
TweenObject.Load = function(rawObj, tname, tweened, easing, init, targ, duration, enforce)
{
var obj = new TweenObject(tname, tweened, easing, init, targ, duration, enforce);
for(var i in rawObj)
obj[i] = rawObj[i];
return obj;
};
behinstProto.loadFromJSON = function (o)
{
var x = JSON.parse(o["tweenlist"]);
var tempObj = TweenObject.Load(x, x.name, x.tweened, x.easefunc, x.initialparam1+","+x.initialparam2, x.targetparam1+","+x.targetparam2, x.duration, x.enforce);
this.tween_list["default"] = tempObj;
this.playmode = o["playmode"];
this.active = o["active"];
this.movement = o["tweened"];
this.easing = o["easing"];
this.target = o["target"];
this.targetmode = o["targetmode"];
this.useCurrent = o["useCurrent"];
this.duration = o["duration"];
this.enforce = o["enforce"];
this.value = o["value"];
};
behinstProto.setProgressTo = function (mark)
{
if (mark > 1.0) mark = 1.0;
if (mark < 0.0) mark = 0.0;
for (var i in this.tween_list) {
var inst = this.tween_list[i];
inst.lastKnownValue = 0;
inst.lastKnownValue2 = 0;
inst.state = 3;
inst.progress = mark * inst.duration;
var factor = inst.OnTick(0);
this.updateTween(inst, factor);
}
}
behinstProto.startTween = function (startMode)
{
for (var i in this.tween_list) {
var inst = this.tween_list[i];
if (this.useCurrent) {
var init = this.parseCurrent(inst.tweened, "current");
var target = this.parseCurrent(inst.tweened, this.target);
inst.setInitial(init);
inst.setTarget(target);
}
if (startMode === 0) {
inst.progress = 0.000001;
inst.lastKnownValue = 0;
inst.lastKnownValue2 = 0;
inst.onStart = true;
inst.state = 1;
}
if (startMode === 1) {
inst.state = inst.lastState;
}
if ((startMode === 2) || (startMode === 4)) {
inst.progress = 0.000001;
inst.lastKnownValue = 0;
inst.lastKnownValue2 = 0;
inst.onStart = true;
if (startMode == 2) inst.state = 4; //state ping pong
if (startMode == 4) inst.state = 6; //state flip flop
}
if (startMode === 3) {
inst.progress = 0.000001;
inst.lastKnownValue = 0;
inst.lastKnownValue2 = 0;
inst.onStart = true;
inst.state = 5;
}
}
}
behinstProto.stopTween = function (stopMode)
{
for (var i in this.tween_list) {
var inst = this.tween_list[i];
if ((inst.state != 3) && (inst.state != 0)) //don't save paused/seek state
inst.lastState = inst.state;
if (stopMode === 1) inst.progress = 0.0;
if (stopMode === 2) inst.progress = inst.duration;
inst.state = 3;
var factor = inst.OnTick(0);
this.updateTween(inst, factor);
}
}
behinstProto.reverseTween = function(reverseMode)
{
for (var i in this.tween_list) {
var inst = this.tween_list[i];
if (reverseMode === 1) {
inst.progress = inst.duration;
inst.lastKnownValue = 0;
inst.lastKnownValue2 = 0;
inst.onReverseStart = true;
}
inst.state = 2;
}
}
behinstProto.updateTween = function (inst, factor)
{
if (inst.tweened === 0) {
if (inst.enforce) {
this.inst.x = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
this.inst.y = inst.initialparam2 + (inst.targetparam2 - inst.initialparam2) * factor;
} else {
this.inst.x += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
this.inst.y += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
}
} else if (inst.tweened === 1) {
if (inst.enforce) {
this.inst.width = (inst.initialparam1 + ((inst.targetparam1 - inst.initialparam1) * (factor)));
this.inst.height = (inst.initialparam2 + ((inst.targetparam2 - inst.initialparam2) * (factor)));
} else {
this.inst.width += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
this.inst.height += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
}
} else if (inst.tweened === 2) {
if (inst.enforce) {
this.inst.width = (inst.initialparam1 + ((inst.targetparam1 - inst.initialparam1) * (factor)));
} else {
this.inst.width += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
}
} else if (inst.tweened === 3) {
if (inst.enforce) {
this.inst.height = (inst.initialparam2 + ((inst.targetparam2 - inst.initialparam2) * (factor)));
} else {
this.inst.height += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
}
} else if (inst.tweened === 4) {
if (inst.enforce) {
var tangle = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
this.inst.angle = cr.clamp_angle(cr.to_radians(tangle));
} else {
var tangle = ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
this.inst.angle = cr.clamp_angle(this.inst.angle + cr.to_radians(tangle));
inst.lastKnownValue = (inst.targetparam1 - inst.initialparam1) * factor;
}
} else if (inst.tweened === 5) {
if (inst.enforce) {
this.inst.opacity = (inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor) / 100;
} else {
this.inst.opacity += (((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue) / 100;
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
}
} else if (inst.tweened === 6) {
if (inst.enforce) {
this.value = (inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor);
} else {
this.value += (((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue);
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
}
} else if (inst.tweened === 7) {
if (inst.enforce) {
this.inst.x = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
} else {
this.inst.x += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
}
} else if (inst.tweened === 8) {
if (inst.enforce) {
this.inst.y = inst.initialparam2 + (inst.targetparam2 - inst.initialparam2) * factor;
} else {
this.inst.y += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
}
} else if (inst.tweened === 9) {
var scalex = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
var scaley = inst.initialparam2 + (inst.targetparam2 - inst.initialparam2) * factor;
if (this.inst.width < 0) scalex = inst.initialparam1 + (inst.targetparam1 + inst.initialparam1) * -factor;
if (this.inst.height < 0) scaley = inst.initialparam2 + (inst.targetparam2 + inst.initialparam2) * -factor;
if (inst.enforce) {
this.inst.width = this.inst.curFrame.width * scalex;
this.inst.height = this.inst.curFrame.height * scaley;
} else {
if (this.inst.width < 0) {
this.inst.width = scalex * (this.inst.width / (-1+inst.lastKnownValue));
inst.lastKnownValue = scalex + 1
} else {
this.inst.width = scalex * (this.inst.width / (1+inst.lastKnownValue));
inst.lastKnownValue = scalex - 1;
}
if (this.inst.height < 0) {
this.inst.height = scaley * (this.inst.height / (-1+inst.lastKnownValue2));
inst.lastKnownValue2 = scaley + 1
} else {
this.inst.height = scaley * (this.inst.height / (1+inst.lastKnownValue2));
inst.lastKnownValue2 = scaley - 1;
}
}
}
this.inst.set_bbox_changed();
}
behinstProto.tick = function ()
{
var dt = this.runtime.getDt(this.inst);
var inst = this.tween_list["default"];
if (inst.state !== 0) {
if (inst.onStart) {
this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnStart, this.inst);
inst.onStart = false;
}
if (inst.onReverseStart) {
this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnReverseStart, this.inst);
inst.onReverseStart = false;
}
this.active = (inst.state == 1) || (inst.state == 2) || (inst.state == 4) || (inst.state == 5) || (inst.state == 6);
var factor = inst.OnTick(dt);
this.updateTween(inst, factor);
if (inst.onEnd) {
this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnEnd, this.inst);
inst.onEnd = false;
}
if (inst.onReverseEnd) {
this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnReverseEnd, this.inst);
inst.onReverseEnd = false;
}
}
};
behaviorProto.cnds = {};
var cnds = behaviorProto.cnds;
cnds.IsActive = function ()
{
return (this.tween_list["default"].state !== 0);
};
cnds.IsReversing = function ()
{
return (this.tween_list["default"].state == 2);
};
cnds.CompareProgress = function (cmp, v)
{
var inst = this.tween_list["default"];
return cr.do_cmp((inst.progress / inst.duration), cmp, v);
};
cnds.OnThreshold = function (cmp, v)
{
var inst = this.tween_list["default"];
this.threshold = (cr.do_cmp((inst.progress / inst.duration), cmp, v));
var ret = (this.oldthreshold != this.threshold) && (this.threshold);
if (ret) {
this.oldthreshold = this.threshold;
}
return ret;
};
cnds.OnStart = function ()
{
if (this.tween_list["default"] === undefined)
return false;
return this.tween_list["default"].onStart;
};
cnds.OnReverseStart = function ()
{
if (this.tween_list["default"] === undefined)
return false;
return this.tween_list["default"].onReverseStart;
};
cnds.OnEnd = function ()
{
if (this.tween_list["default"] === undefined)
return false;
return this.tween_list["default"].onEnd;
};
cnds.OnReverseEnd = function ()
{
if (this.tween_list["default"] === undefined)
return false;
return this.tween_list["default"].onReverseEnd;
};
behaviorProto.acts = {};
var acts = behaviorProto.acts;
acts.Start = function (startmode, current)
{
this.threshold = false;
this.oldthreshold = false;
this.useCurrent = (current == 1);
this.startTween(startmode);
};
acts.Stop = function (stopmode)
{
this.stopTween(stopmode);
};
acts.Reverse = function (revMode)
{
this.threshold = false;
this.oldthreshold = false;
this.reverseTween(revMode);
};
acts.ProgressTo = function (progress)
{
this.setProgressTo(progress);
};
acts.SetDuration = function (x)
{
if (isNaN(x)) return;
if (x < 0) return;
if (this.tween_list["default"] === undefined) return;
this.tween_list["default"].duration = x;
};
acts.SetEnforce = function (x)
{
if (this.tween_list["default"] === undefined) return;
this.tween_list["default"].enforce = (x===1);
};
acts.SetInitial = function (x)
{
if (this.tween_list["default"] === undefined) return;
var init = this.parseCurrent(this.tween_list["default"].tweened, x);
this.tween_list["default"].setInitial(init);
};
acts.SetTarget = function (targettype, absrel, x)
{
if (this.tween_list["default"] === undefined) return;
if (isNaN(x)) return;
var inst = this.tween_list["default"];
var parsed = x + "";
this.targetmode = absrel;
var x1 = "";
var x2 = "";
if (absrel === 1) {
this.target = "relative(" + parsed + ")";
switch (targettype) {
case 0: x1 = (this.inst.x + x); x2 = inst.targetparam2; break;
case 1: x1 = inst.targetparam1; x2 = (this.inst.y + x); break;
case 2: x1 = "" + cr.to_degrees(this.inst.angle + cr.to_radians(x)); x2 = x1; break; //angle
case 3: x1 = "" + (this.inst.opacity*100) + x; x2 = x1; break; //opacity
case 4: x1 = (this.inst.width + x); x2 = inst.targetparam2; break; //width
case 5: x1 = inst.targetparam1; x2 = (this.inst.height + x); break; //height
case 6: x1 = x; x2 = x; break; //value
default: break;
}
parsed = x1 + "," + x2;
} else {
switch (targettype) {
case 0: x1 = x; x2 = inst.targetparam2; break;
case 1: x1 = inst.targetparam1; x2 = x; break;
case 2: x1 = x; x2 = x; break; //angle
case 3: x1 = x; x2 = x; break; //opacity
case 4: x1 = x; x2 = inst.targetparam2; break; //width
case 5: x1 = inst.targetparam1; x2 = x; break; //height
case 6: x1 = x; x2 = x; break; //value
default: break;
}
parsed = x1 + "," + x2;
this.target = parsed;
}
var init = this.parseCurrent(this.tween_list["default"].tweened, "current");
var targ = this.parseCurrent(this.tween_list["default"].tweened, parsed);
inst.setInitial(init);
inst.setTarget(targ);
};
acts.SetTweenedProperty = function (x)
{
if (this.tween_list["default"] === undefined) return;
this.tween_list["default"].tweened = x;
};
acts.SetEasing = function (x)
{
if (this.tween_list["default"] === undefined) return;
this.tween_list["default"].easefunc = x;
};
acts.SetEasingParam = function (x, a, p, t, s)
{
if (this.tween_list["default"] === undefined) return;
this.tween_list["default"].easingparam[x].optimized = false;
this.tween_list["default"].easingparam[x].a = a;
this.tween_list["default"].easingparam[x].p = p;
this.tween_list["default"].easingparam[x].t = t;
this.tween_list["default"].easingparam[x].s = s;
};
acts.ResetEasingParam = function ()
{
if (this.tween_list["default"] === undefined) return;
this.tween_list["default"].optimized = true;
};
acts.SetValue = function (x)
{
var inst = this.tween_list["default"];
this.value = x;
if (inst.tweened === 6)
inst.setInitial( this.parseCurrent(inst.tweened, "current") );
};
acts.SetParameter = function (tweened, easefunction, target, duration, enforce)
{
if (this.tween_list["default"] === undefined) {
this.addToTweenList("default", tweened, easefunction, initial, target, duration, enforce, 0);
} else {
var inst = this.tween_list["default"];
inst.tweened = tweened;
inst.easefunc = easefunction;
inst.setInitial( this.parseCurrent(tweened, "current") );
inst.setTarget( this.parseCurrent(tweened, target) );
inst.duration = duration;
inst.enforce = (enforce === 1);
}
};
behaviorProto.exps = {};
var exps = behaviorProto.exps;
exps.State = function (ret)
{
var parsed = "N/A";
switch (this.tween_list["default"].state) {
case 0: parsed = "paused"; break;
case 1: parsed = "playing"; break;
case 2: parsed = "reversing"; break;
case 3: parsed = "seeking"; break;
default: break;
}
ret.set_string(parsed);
};
exps.Progress = function (ret)
{
var progress = this.tween_list["default"].progress/this.tween_list["default"].duration;
ret.set_float(progress);
};
exps.Duration = function (ret)
{
ret.set_float(this.tween_list["default"].duration);
};
exps.Target = function (ret)
{
var inst = this.tween_list["default"];
var parsed = "N/A";
switch (inst.tweened) {
case 0: parsed = inst.targetparam1; break;
case 1: parsed = inst.targetparam2; break;
case 2: parsed = inst.targetparam1; break;
case 3: parsed = inst.targetparam1; break;
case 4: parsed = inst.targetparam1; break;
case 5: parsed = inst.targetparam2; break;
case 6: parsed = inst.targetparam1; break;
default: break;
}
ret.set_float(parsed);
};
exps.Value = function (ret)
{
var tval = this.value;
ret.set_float(tval);
};
exps.Tween = function (ret, a_, b_, x_, easefunc_)
{
var currX = (x_>1.0?1.0:x_);
var factor = easeFunc(easefunc_, currX<0.0?0.0:currX, 0.0, 1.0, 1.0, false, false);
ret.set_float(a_ + factor * (b_-a_));
};
}());
;
;
cr.behaviors.scrollto = function(runtime)
{
this.runtime = runtime;
this.shakeMag = 0;
this.shakeStart = 0;
this.shakeEnd = 0;
this.shakeMode = 0;
};
(function ()
{
var behaviorProto = cr.behaviors.scrollto.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.enabled = (this.properties[0] !== 0);
};
behinstProto.saveToJSON = function ()
{
return {
"smg": this.behavior.shakeMag,
"ss": this.behavior.shakeStart,
"se": this.behavior.shakeEnd,
"smd": this.behavior.shakeMode
};
};
behinstProto.loadFromJSON = function (o)
{
this.behavior.shakeMag = o["smg"];
this.behavior.shakeStart = o["ss"];
this.behavior.shakeEnd = o["se"];
this.behavior.shakeMode = o["smd"];
};
behinstProto.tick = function ()
{
};
function getScrollToBehavior(inst)
{
var i, len, binst;
for (i = 0, len = inst.behavior_insts.length; i < len; ++i)
{
binst = inst.behavior_insts[i];
if (binst.behavior instanceof cr.behaviors.scrollto)
return binst;
}
return null;
};
behinstProto.tick2 = function ()
{
if (!this.enabled)
return;
var all = this.behavior.my_instances.valuesRef();
var sumx = 0, sumy = 0;
var i, len, binst, count = 0;
for (i = 0, len = all.length; i < len; i++)
{
binst = getScrollToBehavior(all[i]);
if (!binst || !binst.enabled)
continue;
sumx += all[i].x;
sumy += all[i].y;
++count;
}
var layout = this.inst.layer.layout;
var now = this.runtime.kahanTime.sum;
var offx = 0, offy = 0;
if (now >= this.behavior.shakeStart && now < this.behavior.shakeEnd)
{
var mag = this.behavior.shakeMag * Math.min(this.runtime.timescale, 1);
if (this.behavior.shakeMode === 0)
mag *= 1 - (now - this.behavior.shakeStart) / (this.behavior.shakeEnd - this.behavior.shakeStart);
var a = Math.random() * Math.PI * 2;
var d = Math.random() * mag;
offx = Math.cos(a) * d;
offy = Math.sin(a) * d;
}
layout.scrollToX(sumx / count + offx);
layout.scrollToY(sumy / count + offy);
};
function Acts() {};
Acts.prototype.Shake = function (mag, dur, mode)
{
this.behavior.shakeMag = mag;
this.behavior.shakeStart = this.runtime.kahanTime.sum;
this.behavior.shakeEnd = this.behavior.shakeStart + dur;
this.behavior.shakeMode = mode;
};
Acts.prototype.SetEnabled = function (e)
{
this.enabled = (e !== 0);
};
behaviorProto.acts = new Acts();
}());
;
;
cr.behaviors.solid = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.solid.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.inst.extra["solidEnabled"] = (this.properties[0] !== 0);
};
behinstProto.tick = function ()
{
};
function Cnds() {};
Cnds.prototype.IsEnabled = function ()
{
return this.inst.extra["solidEnabled"];
};
behaviorProto.cnds = new Cnds();
function Acts() {};
Acts.prototype.SetEnabled = function (e)
{
this.inst.extra["solidEnabled"] = !!e;
};
behaviorProto.acts = new Acts();
}());
cr.getObjectRefTable = function () { return [
cr.plugins_.NinePatch,
cr.plugins_.aekiro_proui2,
cr.plugins_.AJAX,
cr.plugins_.Audio,
cr.plugins_.Arr,
cr.plugins_.Browser,
cr.plugins_.CBhash,
cr.plugins_.GameAnalytics,
cr.plugins_.CSS_import,
cr.plugins_.Function,
cr.plugins_.LocalStorage,
cr.plugins_.Keyboard,
cr.plugins_.Globals,
cr.plugins_.MM_Preloader,
cr.plugins_.MM_Debugger,
cr.plugins_.MoMod,
cr.plugins_.MM_Unloader,
cr.plugins_.NSG_NicknamesDB,
cr.plugins_.Mouse,
cr.plugins_.NSG_MobilePopup,
cr.plugins_.NSG_DataBag,
cr.plugins_.NSG_WebAdsProCPMStar,
cr.plugins_.NSG_ObjectJS,
cr.plugins_.NSG_PowerWS,
cr.plugins_.NSG_WebAdsProCrazyGames,
cr.plugins_.NSG_WebAdsProAIP,
cr.plugins_.NSG_Referrer,
cr.plugins_.NSG_WebAdsPro_Banner,
cr.plugins_.Particles,
cr.plugins_.NSG_WebAdsPro,
cr.plugins_.rex_bbcodeText,
cr.plugins_.Rex_EventBalancer,
cr.plugins_.Sprite,
cr.plugins_.SpriteFontPlus,
cr.plugins_.SyncStorage,
cr.plugins_.Touch,
cr.plugins_.TiledBg,
cr.plugins_.TR_DateTime,
cr.plugins_.TR_ClockParser,
cr.plugins_.TR_CrossPromo,
cr.plugins_.TR_HtmlText,
cr.plugins_.TextBox,
cr.plugins_.Text,
cr.plugins_.TR_Leaderboard,
cr.behaviors.Sin,
cr.behaviors.lunarray_LiteTween,
cr.behaviors.Pin,
cr.behaviors.Anchor,
cr.behaviors.solid,
cr.behaviors.Bullet,
cr.behaviors.Fade,
cr.behaviors.aekiro_progress,
cr.behaviors.destroy,
cr.behaviors.scrollto,
cr.behaviors.TR_Scale,
cr.behaviors.Rex_RotateTo,
cr.behaviors.Timer,
cr.behaviors.bound,
cr.behaviors.Rex_pinOffsetXY,
cr.behaviors.NSG_TrueTimer,
cr.behaviors.TR_Level,
cr.system_object.prototype.cnds.IsGroupActive,
cr.system_object.prototype.cnds.OnLayoutStart,
cr.plugins_.Globals.prototype.acts.SetInstanceVar,
cr.system_object.prototype.exps.layoutwidth,
cr.system_object.prototype.exps.layoutheight,
cr.plugins_.Globals.prototype.acts.SetBoolInstanceVar,
cr.system_object.prototype.acts.SetLayerVisible,
cr.system_object.prototype.acts.SetLayerOpacity,
cr.system_object.prototype.acts.SetGroupActive,
cr.plugins_.MM_Preloader.prototype.acts.AddItem,
cr.plugins_.MM_Preloader.prototype.acts.StabilizerSetState,
cr.plugins_.MM_Preloader.prototype.acts.Start,
cr.plugins_.Sprite.prototype.acts.SetPos,
cr.plugins_.Function.prototype.acts.CallFunction,
cr.plugins_.MoMod.prototype.acts.StartUpModule,
cr.behaviors.aekiro_progress.prototype.acts.setValue,
cr.system_object.prototype.cnds.IsMobile,
cr.plugins_.TiledBg.prototype.cnds.IsOnLayer,
cr.plugins_.TiledBg.prototype.acts.SetPos,
cr.system_object.prototype.exps.viewportleft,
cr.system_object.prototype.exps.viewporttop,
cr.plugins_.TiledBg.prototype.acts.SetSize,
cr.system_object.prototype.exps.viewportright,
cr.system_object.prototype.exps.viewportbottom,
cr.plugins_.TR_DateTime.prototype.cnds.IsActive,
cr.plugins_.NSG_NicknamesDB.prototype.acts.ReleaseAll,
cr.plugins_.TR_DateTime.prototype.acts.StartTimer,
cr.plugins_.Globals.prototype.acts.AddInstanceVar,
cr.plugins_.GameAnalytics.prototype.acts.addDesignEventWithValue,
cr.system_object.prototype.cnds.For,
cr.system_object.prototype.acts.Wait,
cr.plugins_.MM_Preloader.prototype.acts.SetItemState,
cr.plugins_.MM_Preloader.prototype.cnds.OnProgress,
cr.plugins_.MM_Preloader.prototype.exps.Progress,
cr.plugins_.SpriteFontPlus.prototype.cnds.CompareInstanceVar,
cr.plugins_.SpriteFontPlus.prototype.acts.SetText,
cr.system_object.prototype.exps.round,
cr.system_object.prototype.exps.min,
cr.plugins_.MM_Preloader.prototype.cnds.OnCompleted,
cr.plugins_.Globals.prototype.cnds.IsBoolInstanceVarSet,
cr.plugins_.Audio.prototype.acts.Play,
cr.behaviors.Pin.prototype.acts.Pin,
cr.behaviors.Anchor.prototype.acts.SetEnabled,
cr.system_object.prototype.cnds.LayerVisible,
cr.plugins_.Function.prototype.cnds.OnFunction,
cr.system_object.prototype.cnds.ForEach,
cr.plugins_.NSG_DataBag.prototype.acts.AddData,
cr.system_object.prototype.exps.str,
cr.plugins_.CSS_import.prototype.acts.SetCSS,
cr.system_object.prototype.exps.projectversion,
cr.plugins_.TR_HtmlText.prototype.acts.AddNewFamily,
cr.plugins_.Browser.prototype.acts.ConsoleLog,
cr.plugins_.MM_Preloader.prototype.acts.AddC2EngineProgress,
cr.plugins_.SyncStorage.prototype.acts.LoadData,
cr.plugins_.NSG_Referrer.prototype.cnds.Contains,
cr.system_object.prototype.cnds.Else,
cr.system_object.prototype.acts.SetVar,
cr.plugins_.SyncStorage.prototype.cnds.OnLoadError,
cr.plugins_.SyncStorage.prototype.cnds.OnLoaded,
cr.plugins_.SyncStorage.prototype.cnds.HasData,
cr.plugins_.Globals.prototype.acts.LoadVariables,
cr.plugins_.SyncStorage.prototype.exps.Get,
cr.plugins_.SyncStorage.prototype.acts.SetData,
cr.plugins_.Globals.prototype.exps.GetVariablesAsJSON,
cr.plugins_.SyncStorage.prototype.cnds.CompareData,
cr.system_object.prototype.cnds.CompareVar,
cr.plugins_.TR_DateTime.prototype.exps.Timestamp,
cr.plugins_.MoMod.prototype.cnds.OnCustomModuleEvent,
cr.plugins_.SyncStorage.prototype.acts.SaveData,
cr.plugins_.NSG_WebAdsPro.prototype.acts.Initialize,
cr.system_object.prototype.cnds.IsPreview,
cr.plugins_.GameAnalytics.prototype.acts.configureBuild,
cr.plugins_.GameAnalytics.prototype.acts.initialize,
cr.plugins_.Globals.prototype.cnds.CompareInstanceVar,
cr.plugins_.Sprite.prototype.acts.SetVisible,
cr.plugins_.SpriteFontPlus.prototype.acts.SetVisible,
cr.system_object.prototype.acts.GoToLayout,
cr.plugins_.Touch.prototype.cnds.OnTapGestureObject,
cr.plugins_.Sprite.prototype.cnds.IsVisible,
cr.plugins_.Browser.prototype.acts.RequestFullScreen,
cr.plugins_.Browser.prototype.acts.ExecJs,
cr.plugins_.NSG_WebAdsPro.prototype.cnds.IsGDPRPopupPreloaded,
cr.system_object.prototype.cnds.TriggerOnce,
cr.plugins_.NSG_WebAdsPro.prototype.acts.SetPrerollAdGlobalSettings,
cr.plugins_.NSG_WebAdsPro.prototype.acts.SetBannerAdGlobalSettings,
cr.plugins_.NSG_WebAdsPro.prototype.acts.SetRewardedAdGlobalSettings,
cr.plugins_.NSG_NicknamesDB.prototype.acts.Load,
cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnLoadingCompleted,
cr.plugins_.NSG_NicknamesDB.prototype.cnds.OnLoadingFailed,
cr.system_object.prototype.cnds.PickByComparison,
cr.plugins_.TR_HtmlText.prototype.acts.SetText,
cr.plugins_.Browser.prototype.exps.URL,
cr.plugins_.NSG_WebAdsPro.prototype.cnds.IsAdblocked,
cr.plugins_.GameAnalytics.prototype.acts.addDesignEvent,
cr.plugins_.SyncStorage.prototype.acts.RemoveData,
cr.plugins_.TextBox.prototype.acts.SetText,
cr.system_object.prototype.exps.trim,
cr.plugins_.Sprite.prototype.acts.SetAnimFrame,
cr.plugins_.TR_HtmlText.prototype.cnds.CompareInstanceVar,
cr.plugins_.TR_ClockParser.prototype.exps.HHMMSS,
cr.plugins_.Globals.prototype.acts.ResetVariables,
cr.plugins_.Audio.prototype.cnds.IsTagPlaying,
cr.plugins_.Function.prototype.exps.Call,
cr.plugins_.Arr.prototype.exps.Width,
cr.plugins_.NSG_MobilePopup.prototype.cnds.IsActive,
cr.plugins_.TextBox.prototype.acts.SetCSSStyle,
cr.plugins_.TR_HtmlText.prototype.acts.SetVisible,
cr.plugins_.Sprite.prototype.cnds.CompareInstanceVar,
cr.plugins_.TiledBg.prototype.acts.MoveToLayer,
cr.plugins_.TiledBg.prototype.acts.MoveToBottom,
cr.plugins_.MM_Unloader.prototype.acts.DestroyLayer,
cr.plugins_.TextBox.prototype.acts.SetVisible,
cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnPrerollStart,
cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnPrerollClosed,
cr.plugins_.Audio.prototype.acts.SetMuted,
cr.plugins_.Sprite.prototype.cnds.CompareFrame,
cr.system_object.prototype.cnds.Compare,
cr.plugins_.TR_DateTime.prototype.exps.TimerTimeLeft,
cr.plugins_.NSG_WebAdsPro.prototype.acts.ShowPrerollAd,
cr.plugins_.NSG_WebAdsPro.prototype.acts.ShowRewardedAd,
cr.plugins_.Touch.prototype.cnds.OnTouchObject,
cr.plugins_.Globals.prototype.acts.ToggleBoolInstanceVar,
cr.plugins_.Audio.prototype.acts.Stop,
cr.plugins_.SyncStorage.prototype.acts.SubtractValue,
cr.plugins_.TextBox.prototype.exps.Text,
cr.system_object.prototype.exps.left,
cr.plugins_.Sprite.prototype.acts.Spawn,
cr.plugins_.Sprite.prototype.exps.LayerName,
cr.plugins_.Sprite.prototype.acts.SetY,
cr.plugins_.Sprite.prototype.exps.Y,
cr.plugins_.Sprite.prototype.acts.Destroy,
cr.plugins_.SyncStorage.prototype.acts.AddValue,
cr.behaviors.Sin.prototype.acts.SetPhase,
cr.behaviors.Sin.prototype.acts.SetActive,
cr.plugins_.NSG_WebAdsPro_Banner.prototype.acts.ShowBanner,
cr.plugins_.TextBox.prototype.cnds.OnClicked,
cr.plugins_.NSG_MobilePopup.prototype.cnds.OnClose,
cr.plugins_.Browser.prototype.acts.GoToURLWindow,
cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnRewardedSuccessful,
cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnRewardedEmpty,
cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnRewardedCanceled,
cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnGDPRPopupOpened,
cr.plugins_.NSG_WebAdsPro.prototype.cnds.OnGDPRPopupClosed,
cr.plugins_.Browser.prototype.exps.Domain,
cr.plugins_.TR_CrossPromo.prototype.exps.MoreGamesURL,
cr.plugins_.NSG_WebAdsPro.prototype.acts.ShowConsentToolSettings,
cr.plugins_.Sprite.prototype.exps.PickedCount,
cr.system_object.prototype.acts.CreateObject,
cr.plugins_.Sprite.prototype.acts.SetInstanceVar,
cr.plugins_.Sprite.prototype.acts.SetAngle,
cr.plugins_.Sprite.prototype.acts.SetWidth,
cr.plugins_.Sprite.prototype.acts.SetX,
cr.plugins_.Function.prototype.exps.Param,
cr.plugins_.Sprite.prototype.cnds.PickByUID,
cr.plugins_.Sprite.prototype.exps.X,
cr.plugins_.Sprite.prototype.exps.BBoxTop,
cr.behaviors.Bullet.prototype.acts.SetAngleOfMotion,
cr.system_object.prototype.exps.random,
cr.behaviors.Bullet.prototype.acts.SetAcceleration,
cr.plugins_.Text.prototype.acts.SetFontSize,
cr.behaviors.TR_Level.prototype.exps.CurrentLevel,
cr.plugins_.Text.prototype.acts.SetText,
cr.behaviors.TR_Level.prototype.cnds.OnLevelChange,
cr.plugins_.Text.prototype.cnds.CompareInstanceVar,
cr.plugins_.Sprite.prototype.exps.UID,
cr.system_object.prototype.exps.abs,
cr.behaviors.TR_Level.prototype.exps.LevelChangeValue,
cr.plugins_.Sprite.prototype.acts.AddInstanceVar,
cr.plugins_.Arr.prototype.exps.At,
cr.behaviors.TR_Scale.prototype.acts.SetScaleSelf,
cr.behaviors.TR_Scale.prototype.exps.Self,
cr.plugins_.Sprite.prototype.acts.SetScale,
cr.behaviors.TR_Level.prototype.cnds.LevelCompare,
cr.plugins_.Sprite.prototype.cnds.IsBoolInstanceVarSet,
cr.behaviors.Bullet.prototype.acts.SetEnabled,
cr.system_object.prototype.cnds.Repeat,
cr.plugins_.Sprite.prototype.acts.SetAnim,
cr.plugins_.Text.prototype.acts.SetSize,
cr.plugins_.Text.prototype.exps.Width,
cr.plugins_.Text.prototype.exps.Height,
cr.behaviors.Rex_pinOffsetXY.prototype.acts.Pin,
cr.plugins_.Text.prototype.acts.SetBoolInstanceVar,
cr.system_object.prototype.cnds.Every,
cr.plugins_.Text.prototype.cnds.IsBoolInstanceVarSet,
cr.plugins_.Text.prototype.cnds.IsOnScreen,
cr.plugins_.Text.prototype.exps.TextWidth,
cr.plugins_.Text.prototype.exps.TextHeight,
cr.behaviors.NSG_TrueTimer.prototype.cnds.OnTimer,
cr.plugins_.Sprite.prototype.acts.SetOpacity,
cr.behaviors.NSG_TrueTimer.prototype.cnds.IsActive,
cr.behaviors.NSG_TrueTimer.prototype.exps.TimerAgePercent,
cr.plugins_.Sprite.prototype.exps.Width,
cr.behaviors.NSG_TrueTimer.prototype.acts.StartTimer,
cr.plugins_.TR_ClockParser.prototype.exps.MMSS,
cr.plugins_.Text.prototype.acts.SetFontColor,
cr.system_object.prototype.exps.rgb,
cr.system_object.prototype.acts.SetLayoutScale,
cr.plugins_.MoMod.prototype.acts.SetSection,
cr.system_object.prototype.exps.layoutscale,
cr.system_object.prototype.exps.dt,
cr.system_object.prototype.cnds.PickByEvaluate,
cr.plugins_.Sprite.prototype.cnds.IsOverlapping,
cr.system_object.prototype.acts.AddVar,
cr.plugins_.Function.prototype.acts.SetReturnValue,
cr.system_object.prototype.exps.loopindex,
cr.plugins_.SpriteFontPlus.prototype.acts.Destroy,
cr.behaviors.lunarray_LiteTween.prototype.cnds.IsActive,
cr.plugins_.TR_HtmlText.prototype.exps.LayerName,
cr.plugins_.SpriteFontPlus.prototype.exps.LayerName,
cr.plugins_.Sprite.prototype.cnds.CompareOpacity,
cr.system_object.prototype.acts.SubVar,
cr.behaviors.lunarray_LiteTween.prototype.acts.SetTarget,
cr.behaviors.lunarray_LiteTween.prototype.acts.Start,
cr.system_object.prototype.cnds.PickAll,
cr.behaviors.lunarray_LiteTween.prototype.acts.SetEasing,
cr.behaviors.lunarray_LiteTween.prototype.acts.SetDuration,
cr.behaviors.lunarray_LiteTween.prototype.acts.SetTweenedProperty,
cr.system_object.prototype.exps.floor,
cr.plugins_.Sprite.prototype.cnds.IsOnLayer,
cr.plugins_.MoMod.prototype.acts.ShutdownModule,
cr.plugins_.MoMod.prototype.exps.ThisModule,
cr.plugins_.Arr.prototype.acts.Push,
cr.plugins_.MoMod.prototype.acts.TriggerModuleEvent,
cr.plugins_.TR_Leaderboard.prototype.acts.ClearLeaderboard,
cr.plugins_.TR_Leaderboard.prototype.acts.SetPosition,
cr.plugins_.Sprite.prototype.exps.BBoxLeft,
cr.plugins_.TR_Leaderboard.prototype.acts.SetPositionColumn,
cr.plugins_.TR_Leaderboard.prototype.acts.SetNameColumn,
cr.plugins_.TR_Leaderboard.prototype.acts.SetScoreColumn,
cr.plugins_.Text.prototype.cnds.OnCreated,
cr.plugins_.TR_Leaderboard.prototype.cnds.HasNewData,
cr.plugins_.TR_Leaderboard.prototype.acts.DrawLeaderboard,
cr.behaviors.Pin.prototype.acts.Unpin,
cr.plugins_.TR_Leaderboard.prototype.exps.GetX,
cr.plugins_.TR_Leaderboard.prototype.exps.GetY,
cr.plugins_.TR_Leaderboard.prototype.exps.GetIdByPosition,
cr.plugins_.TR_Leaderboard.prototype.exps.GetScoreByPosition,
cr.behaviors.TR_Level.prototype.acts.SetExperience,
cr.plugins_.Sprite.prototype.exps.Height,
cr.plugins_.TR_Leaderboard.prototype.exps.GetPosition,
cr.plugins_.Sprite.prototype.acts.MoveToTop,
cr.plugins_.Sprite.prototype.exps.Angle,
cr.plugins_.Arr.prototype.acts.SetSize,
cr.plugins_.rex_bbcodeText.prototype.cnds.IsOnLayer,
cr.plugins_.rex_bbcodeText.prototype.acts.Destroy,
cr.plugins_.Text.prototype.cnds.IsOnLayer,
cr.plugins_.Text.prototype.acts.Destroy,
cr.plugins_.NSG_PowerWS.prototype.cnds.OnEvent,
cr.plugins_.NSG_ObjectJS.prototype.acts.Load,
cr.plugins_.NSG_PowerWS.prototype.exps.DataAsJson,
cr.plugins_.Arr.prototype.acts.SetXY,
cr.plugins_.NSG_ObjectJS.prototype.exps.Get,
cr.plugins_.TR_DateTime.prototype.cnds.OnTimer,
cr.plugins_.TR_DateTime.prototype.acts.StopTimer,
cr.plugins_.Arr.prototype.acts.Clear,
cr.plugins_.Arr.prototype.cnds.CompareXY,
cr.plugins_.Arr.prototype.acts.Sort,
cr.plugins_.Arr.prototype.acts.Reverse,
cr.plugins_.NSG_DataBag.prototype.acts.ClearAllBags,
cr.system_object.prototype.exps.layoutname,
cr.plugins_.NinePatch.prototype.exps.X,
cr.plugins_.NinePatch.prototype.exps.Y,
cr.plugins_.rex_bbcodeText.prototype.acts.SetFontFace,
cr.plugins_.rex_bbcodeText.prototype.acts.SetText,
cr.plugins_.NinePatch.prototype.exps.Width,
cr.plugins_.Sprite.prototype.acts.SetSize,
cr.plugins_.rex_bbcodeText.prototype.acts.SetFontColor,
cr.plugins_.NSG_PowerWS.prototype.acts.SyncMovingObject,
cr.plugins_.NSG_PowerWS.prototype.acts.SyncObjectInstanceVar,
cr.plugins_.NSG_PowerWS.prototype.acts.SyncStaticObject,
cr.plugins_.Sprite.prototype.exps.BBoxRight,
cr.plugins_.SpriteFontPlus.prototype.acts.SetInstanceVar,
cr.plugins_.NSG_PowerWS.prototype.exps.Ping,
cr.plugins_.NSG_PowerWS.prototype.acts.SetMessage,
cr.plugins_.NSG_PowerWS.prototype.acts.Send,
cr.plugins_.NSG_ObjectJS.prototype.exps.DataAsJson,
cr.plugins_.TR_Leaderboard.prototype.acts.RemoveEntry,
cr.plugins_.Sprite.prototype.cnds.OnCreated,
cr.plugins_.Sprite.prototype.acts.SetCollisions,
cr.plugins_.Sprite.prototype.cnds.IsOnScreen,
cr.plugins_.Particles.prototype.acts.SetSpraying,
cr.plugins_.Particles.prototype.exps.UID,
cr.plugins_.Text.prototype.acts.SetInstanceVar,
cr.behaviors.TR_Level.prototype.acts.SetMaxLevel,
cr.plugins_.Sprite.prototype.acts.ZMoveToObject,
cr.plugins_.Audio.prototype.acts.SetListenerObject,
cr.plugins_.Sprite.prototype.cnds.PickDistance,
cr.system_object.prototype.exps.distance,
cr.plugins_.Sprite.prototype.acts.SetBoolInstanceVar,
cr.system_object.prototype.exps.angle,
cr.plugins_.Mouse.prototype.exps.X,
cr.plugins_.Mouse.prototype.exps.Y,
cr.plugins_.NSG_PowerWS.prototype.acts.SendRaw,
cr.plugins_.NSG_ObjectJS.prototype.cnds.HasData,
cr.behaviors.TR_Level.prototype.cnds.OnExpChanged,
cr.behaviors.TR_Level.prototype.exps.TotalExp,
cr.behaviors.TR_Level.prototype.exps.LevelExpProgress,
cr.behaviors.TR_Level.prototype.acts.AddExperience,
cr.behaviors.TR_Level.prototype.exps.LevelExpPool,
cr.behaviors.TR_Level.prototype.acts.SubtractExperience,
cr.plugins_.NSG_PowerWS.prototype.cnds.OnInstanceVariableChanged,
cr.plugins_.Sprite.prototype.acts.MoveAtAngle,
cr.behaviors.lunarray_LiteTween.prototype.cnds.OnEnd,
cr.behaviors.lunarray_LiteTween.prototype.acts.Stop,
cr.plugins_.Audio.prototype.acts.PlayAtPosition,
cr.behaviors.Rex_RotateTo.prototype.acts.SetActivated,
cr.behaviors.Rex_RotateTo.prototype.acts.SetTargetAngle,
cr.behaviors.Rex_RotateTo.prototype.cnds.OnHitTarget,
cr.behaviors.Rex_RotateTo.prototype.acts.Stop,
cr.plugins_.Particles.prototype.cnds.PickByUID,
cr.plugins_.Sprite.prototype.exps.AnimationFrameCount,
cr.plugins_.Sprite.prototype.cnds.OnAnimFinished,
cr.plugins_.Sprite.prototype.cnds.OnDestroyed,
cr.plugins_.Particles.prototype.acts.Destroy,
cr.plugins_.TR_DateTime.prototype.exps.TimerAge,
cr.system_object.prototype.exps.windowwidth,
cr.system_object.prototype.exps.windowheight,
cr.plugins_.Particles.prototype.acts.SetVisible,
cr.plugins_.Text.prototype.acts.SetVisible,
cr.plugins_.TR_Leaderboard.prototype.acts.SetEntry,
cr.plugins_.TR_Leaderboard.prototype.acts.SetRequired,
cr.plugins_.Sprite.prototype.cnds.CompareX,
cr.plugins_.Sprite.prototype.cnds.CompareY,
cr.plugins_.Touch.prototype.exps.TouchID,
cr.plugins_.Touch.prototype.cnds.OnTouchEnd,
cr.plugins_.Touch.prototype.exps.XForID,
cr.plugins_.Touch.prototype.exps.YForID,
cr.plugins_.Sprite.prototype.acts.SetPosToObject,
cr.plugins_.Touch.prototype.cnds.IsTouchingObject,
cr.plugins_.Mouse.prototype.cnds.OnClick,
cr.plugins_.Mouse.prototype.cnds.OnRelease,
cr.plugins_.Sprite.prototype.acts.SetTowardPosition,
cr.plugins_.Mouse.prototype.cnds.IsOverObject,
cr.system_object.prototype.cnds.While,
cr.behaviors.Timer.prototype.acts.StartTimer,
cr.plugins_.NSG_DataBag.prototype.cnds.IsBagEmpty,
cr.plugins_.NSG_DataBag.prototype.exps.CutRandomData,
cr.plugins_.NSG_NicknamesDB.prototype.exps.RandomNickname,
cr.plugins_.Sprite.prototype.acts.MoveForward,
cr.behaviors.Timer.prototype.cnds.OnTimer,
cr.behaviors.Rex_RotateTo.prototype.acts.SetMaxSpeed,
cr.plugins_.Sprite.prototype.cnds.OnCollision,
cr.plugins_.MoMod.prototype.exps.Param,
cr.system_object.prototype.cnds.PickRandom,
cr.behaviors.Timer.prototype.acts.StopTimer,
cr.plugins_.MoMod.prototype.acts.TriggerCustomModuleEvent,
cr.plugins_.Rex_EventBalancer.prototype.cnds.IsProcessing,
cr.plugins_.Sprite.prototype.exps.Count,
cr.plugins_.Rex_EventBalancer.prototype.acts.Start,
cr.plugins_.Rex_EventBalancer.prototype.cnds.OnProcessing,
cr.plugins_.Rex_EventBalancer.prototype.acts.Stop,
cr.plugins_.Keyboard.prototype.cnds.OnKey,
cr.plugins_.Touch.prototype.cnds.OnTouchStart,
cr.plugins_.Mouse.prototype.cnds.IsButtonDown,
cr.plugins_.Sprite.prototype.acts.MoveToLayer,
cr.plugins_.NSG_NicknamesDB.prototype.acts.Release,
cr.plugins_.NSG_DataBag.prototype.acts.RemoveData,
cr.system_object.prototype.exps.scrollx,
cr.system_object.prototype.exps.scrolly,
cr.plugins_.MoMod.prototype.cnds.OnModuleEvent,
cr.system_object.prototype.exps["int"],
cr.plugins_.NSG_PowerWS.prototype.acts.Close,
cr.plugins_.TR_CrossPromo.prototype.acts.PickRandomBanner,
cr.plugins_.TR_CrossPromo.prototype.cnds.OnBannerReady,
cr.plugins_.Sprite.prototype.acts.LoadURL,
cr.plugins_.TR_CrossPromo.prototype.exps.CurrentBannerIMG,
cr.plugins_.TR_CrossPromo.prototype.acts.SmartRedirect,
cr.plugins_.TR_CrossPromo.prototype.exps.CurrentBannerURL,
cr.plugins_.Mouse.prototype.acts.SetCursor,
cr.plugins_.NSG_PowerWS.prototype.cnds.IsOpen,
cr.plugins_.Browser.prototype.exps.QueryParam,
cr.plugins_.NSG_PowerWS.prototype.acts.Connect,
cr.plugins_.NSG_PowerWS.prototype.cnds.OnOpened,
cr.plugins_.NSG_PowerWS.prototype.acts.SendPing,
cr.plugins_.NSG_PowerWS.prototype.cnds.OnPong,
cr.system_object.prototype.cnds.CompareBetween,
cr.plugins_.NSG_PowerWS.prototype.cnds.OnClosed,
cr.plugins_.NSG_PowerWS.prototype.exps.CloseCode,
cr.plugins_.NSG_PowerWS.prototype.exps.CloseReason,
cr.plugins_.NSG_PowerWS.prototype.exps.ErrorMsg,
cr.plugins_.NSG_PowerWS.prototype.cnds.OnError,
cr.plugins_.TR_DateTime.prototype.exps.TriggersLeft
];};