diff -r 000000000000 -r 6474c204b198 browser/extensions/shumway/content/shumway.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browser/extensions/shumway/content/shumway.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,51428 @@ +/* + * Copyright 2013 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This file is automatically generated + +(function (global) { + if (global.DataView) + return; + if (!global.ArrayBuffer) + fail('ArrayBuffer not supported'); + if (!Object.defineProperties) + fail('This module requires ECMAScript 5'); + var nativele = new Int8Array(new Int32Array([ + 1 + ]).buffer)[0] === 1; + var temp = new Uint8Array(8); + global.DataView = function DataView(buffer, offset, length) { + if (!(buffer instanceof ArrayBuffer)) + fail('Bad ArrayBuffer'); + offset = offset || 0; + length = length || buffer.byteLength - offset; + if (offset < 0 || length < 0 || offset + length > buffer.byteLength) + fail('Illegal offset and/or length'); + Object.defineProperties(this, { + buffer: { + value: buffer, + enumerable: false, + writable: false, + configurable: false + }, + byteOffset: { + value: offset, + enumerable: false, + writable: false, + configurable: false + }, + byteLength: { + value: length, + enumerable: false, + writable: false, + configurable: false + }, + _bytes: { + value: new Uint8Array(buffer, offset, length), + enumerable: false, + writable: false, + configurable: false + } + }); + }; + global.DataView.prototype = { + constructor: DataView, + getInt8: function getInt8(offset) { + return get(this, Int8Array, 1, offset); + }, + getUint8: function getUint8(offset) { + return get(this, Uint8Array, 1, offset); + }, + getInt16: function getInt16(offset, le) { + return get(this, Int16Array, 2, offset, le); + }, + getUint16: function getUint16(offset, le) { + return get(this, Uint16Array, 2, offset, le); + }, + getInt32: function getInt32(offset, le) { + return get(this, Int32Array, 4, offset, le); + }, + getUint32: function getUint32(offset, le) { + return get(this, Uint32Array, 4, offset, le); + }, + getFloat32: function getFloat32(offset, le) { + return get(this, Float32Array, 4, offset, le); + }, + getFloat64: function getFloat32(offset, le) { + return get(this, Float64Array, 8, offset, le); + }, + setInt8: function setInt8(offset, value) { + set(this, Int8Array, 1, offset, value); + }, + setUint8: function setUint8(offset, value) { + set(this, Uint8Array, 1, offset, value); + }, + setInt16: function setInt16(offset, value, le) { + set(this, Int16Array, 2, offset, value, le); + }, + setUint16: function setUint16(offset, value, le) { + set(this, Uint16Array, 2, offset, value, le); + }, + setInt32: function setInt32(offset, value, le) { + set(this, Int32Array, 4, offset, value, le); + }, + setUint32: function setUint32(offset, value, le) { + set(this, Uint32Array, 4, offset, value, le); + }, + setFloat32: function setFloat32(offset, value, le) { + set(this, Float32Array, 4, offset, value, le); + }, + setFloat64: function setFloat64(offset, value, le) { + set(this, Float64Array, 8, offset, value, le); + } + }; + function get(view, type, size, offset, le) { + if (offset === undefined) + fail('Missing required offset argument'); + if (offset < 0 || offset + size > view.byteLength) + fail('Invalid index: ' + offset); + if (size === 1 || !(!le) === nativele) { + if ((view.byteOffset + offset) % size === 0) + return new type(view.buffer, view.byteOffset + offset, 1)[0]; + else { + for (var i = 0; i < size; i++) + temp[i] = view._bytes[offset + i]; + return new type(temp.buffer)[0]; + } + } else { + for (var i = 0; i < size; i++) + temp[size - i - 1] = view._bytes[offset + i]; + return new type(temp.buffer)[0]; + } + } + function set(view, type, size, offset, value, le) { + if (offset === undefined) + fail('Missing required offset argument'); + if (value === undefined) + fail('Missing required value argument'); + if (offset < 0 || offset + size > view.byteLength) + fail('Invalid index: ' + offset); + if (size === 1 || !(!le) === nativele) { + if ((view.byteOffset + offset) % size === 0) { + new type(view.buffer, view.byteOffset + offset, 1)[0] = value; + } else { + new type(temp.buffer)[0] = value; + for (var i = 0; i < size; i++) + view._bytes[i + offset] = temp[i]; + } + } else { + new type(temp.buffer)[0] = value; + for (var i = 0; i < size; i++) + view._bytes[offset + i] = temp[size - 1 - i]; + } + } + function fail(msg) { + throw new Error(msg); + } +}(this)); +; +var ByteArray = ByteArray || function (undefined) { + ByteArrayClass.INITIAL_SIZE = 128; + ByteArrayClass.DEFAULT_OBJECT_ENCODING = 3; + function ByteArrayClass(bytes) { + if (bytes instanceof ByteArray) { + return bytes; + } + var initData = bytes || this.symbol && this.symbol.data; + if (initData) { + this.a = new ArrayBuffer(initData.length); + this.length = initData.length; + new Uint8Array(this.a).set(initData); + } else { + this.a = new ArrayBuffer(ByteArrayClass.INITIAL_SIZE); + this.length = 0; + } + this.position = 0; + this.cacheViews(); + this.nativele = new Int8Array(new Int32Array([]).buffer)[0] === 1; + this.le = this.nativele; + this.objectEncoding = ByteArrayClass.DEFAULT_OBJECT_ENCODING; + this.bitBuffer = 0; + this.bitLength = 0; + } + ; + function throwEOFError() { + runtime.throwErrorFromVM('flash.errors.EOFError', 'End of file was encountered.'); + } + function throwRangeError() { + var error = Errors.ParamRangeError; + runtime.throwErrorFromVM('RangeError', getErrorMessage(error.code), error.code); + } + function throwCompressedDataError() { + var error = Errors.CompressedDataError; + runtime.throwErrorFromVM('CompressedDataError', getErrorMessage(error.code), error.code); + } + function checkRange(x, min, max) { + if (x !== clamp(x, min, max)) { + throwRangeError(); + } + } + function get(b, m, size) { + if (b.position + size > b.length) { + throwEOFError(); + } + var v = b.view[m](b.position, b.le); + b.position += size; + return v; + } + function set(b, m, size, v) { + var len = b.position + size; + b.ensureCapacity(len); + b.view[m](b.position, v, b.le); + b.position = len; + if (len > b.length) { + b.length = len; + } + } + var BAp = ByteArrayClass.prototype; + BAp.cacheViews = function cacheViews() { + var a = this.a; + this.int8v = new Int8Array(a); + this.uint8v = new Uint8Array(a); + this.view = new DataView(a); + }; + BAp.getBytes = function getBytes() { + return new Uint8Array(this.a, 0, this.length); + }; + BAp.ensureCapacity = function ensureCapacity(size) { + var origa = this.a; + if (origa.byteLength < size) { + var newSize = origa.byteLength; + while (newSize < size) { + newSize *= 2; + } + var copya = new ArrayBuffer(newSize); + var origv = this.int8v; + this.a = copya; + this.cacheViews(); + this.int8v.set(origv); + } + }; + BAp.clear = function clear() { + this.length = 0; + this.position = 0; + }; + BAp.readBoolean = function readBoolean() { + if (this.position + 1 > this.length) { + throwEOFError(); + } + return this.int8v[this.position++] !== 0; + }; + BAp.readByte = function readByte() { + if (this.position + 1 > this.length) { + throwEOFError(); + } + return this.int8v[this.position++]; + }; + BAp.readUnsignedByte = function readUnsignedByte() { + if (this.position + 1 > this.length) { + throwEOFError(); + } + return this.uint8v[this.position++]; + }; + BAp.readBytes = function readBytes(bytes, offset, length) { + var pos = this.position; + if (!offset) { + offset = 0; + } + if (!length) { + length = this.length - pos; + } + if (pos + length > this.length) { + throwEOFError(); + } + if (bytes.length < offset + length) { + bytes.ensureCapacity(offset + length); + bytes.length = offset + length; + } + bytes.int8v.set(new Int8Array(this.a, pos, length), offset); + this.position += length; + }; + BAp.writeBoolean = function writeBoolean(v) { + var len = this.position + 1; + this.ensureCapacity(len); + this.int8v[this.position++] = v ? 1 : 0; + if (len > this.length) { + this.length = len; + } + }; + BAp.writeByte = function writeByte(v) { + var len = this.position + 1; + this.ensureCapacity(len); + this.int8v[this.position++] = v; + if (len > this.length) { + this.length = len; + } + }; + BAp.writeUnsignedByte = function writeUnsignedByte(v) { + var len = this.position + 1; + this.ensureCapacity(len); + this.uint8v[this.position++] = v; + if (len > this.length) { + this.length = len; + } + }; + BAp.writeRawBytes = function writeRawBytes(bytes) { + var len = this.position + bytes.length; + this.ensureCapacity(len); + this.int8v.set(bytes, this.position); + this.position = len; + if (len > this.length) { + this.length = len; + } + }; + BAp.readRawBytes = function readRawBytes() { + return new Int8Array(this.a, 0, this.length); + }; + BAp.writeBytes = function writeBytes(bytes, offset, length) { + if (arguments.length < 2) { + offset = 0; + } + if (arguments.length < 3) { + length = 0; + } + checkRange(offset, 0, bytes.length); + checkRange(offset + length, 0, bytes.length); + if (length === 0) { + length = bytes.length - offset; + } + this.writeRawBytes(new Int8Array(bytes.a, offset, length)); + }; + BAp.readDouble = function readDouble() { + return get(this, 'getFloat64', 8); + }; + BAp.readFloat = function readFloat() { + return get(this, 'getFloat32', 4); + }; + BAp.readInt = function readInt() { + return get(this, 'getInt32', 4); + }; + BAp.readShort = function readShort() { + return get(this, 'getInt16', 2); + }; + BAp.readUnsignedInt = function readUnsignedInt() { + return get(this, 'getUint32', 4); + }; + BAp.readUnsignedShort = function readUnsignedShort() { + return get(this, 'getUint16', 2); + }; + BAp.writeDouble = function writeDouble(v) { + set(this, 'setFloat64', 8, v); + }; + BAp.writeFloat = function writeFloat(v) { + set(this, 'setFloat32', 4, v); + }; + BAp.writeInt = function writeInt(v) { + set(this, 'setInt32', 4, v); + }; + BAp.writeShort = function writeShort(v) { + set(this, 'setInt16', 2, v); + }; + BAp.writeUnsignedInt = function writeUnsignedInt(v) { + set(this, 'setUint32', 4, v); + }; + BAp.writeUnsignedShort = function writeUnsignedShort(v) { + set(this, 'setUint16', 2, v); + }; + var codeLengthOrder = [ + 16, + 17, + 18, + 0, + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15 + ]; + var distanceCodes = []; + var distanceExtraBits = []; + for (var i = 0, j = 0, code = 1; i < 30; ++i) { + distanceCodes[i] = code; + code += 1 << (distanceExtraBits[i] = ~(~((j += i > 2 ? 1 : 0) / 2))); + } + var bitLengths = []; + for (var i = 0; i < 32; ++i) { + bitLengths[i] = 5; + } + var fixedDistanceTable = makeHuffmanTable(bitLengths); + var lengthCodes = []; + var lengthExtraBits = []; + for (var i = 0, j = 0, code = 3; i < 29; ++i) { + lengthCodes[i] = code - (i == 28 ? 1 : 0); + code += 1 << (lengthExtraBits[i] = ~(~((j += i > 4 ? 1 : 0) / 4 % 6))); + } + for (var i = 0; i < 288; ++i) { + bitLengths[i] = i < 144 || i > 279 ? 8 : i < 256 ? 9 : 7; + } + var fixedLiteralTable = makeHuffmanTable(bitLengths); + function makeHuffmanTable(bitLengths) { + var maxBits = Math.max.apply(null, bitLengths); + var numLengths = bitLengths.length; + var size = 1 << maxBits; + var codes = new Uint32Array(size); + for (var code = 0, len = 1, skip = 2; len <= maxBits; code <<= 1, ++len, skip <<= 1) { + for (var val = 0; val < numLengths; ++val) { + if (bitLengths[val] === len) { + var lsb = 0; + for (var i = 0; i < len; ++i) { + lsb = lsb * 2 + (code >> i & 1); + } + for (var i = lsb; i < size; i += skip) { + codes[i] = len << 16 | val; + } + ++code; + } + } + } + return { + codes: codes, + maxBits: maxBits + }; + } + function inflateBlock(input, output) { + var header = readBits(input, 3); + switch (header >> 1) { + case 0: + input.bitBuffer = input.bitLength = 0; + var len = input.readUnsignedShort(); + var nlen = input.readUnsignedShort(); + if ((~nlen & 65535) !== len) { + throwCompressedDataError(); + } + output.writeBytes(input, input.position, len); + input.position += len; + break; + case 1: + inflate(input, output, fixedLiteralTable, fixedDistanceTable); + break; + case 2: + var bitLengths = []; + var numLiteralCodes = readBits(input, 5) + 257; + var numDistanceCodes = readBits(input, 5) + 1; + var numCodes = numLiteralCodes + numDistanceCodes; + var numLengthCodes = readBits(input, 4) + 4; + for (var i = 0; i < 19; ++i) { + bitLengths[codeLengthOrder[i]] = i < numLengthCodes ? readBits(input, 3) : 0; + } + var codeLengthTable = makeHuffmanTable(bitLengths); + bitLengths = []; + var i = 0; + var prev = 0; + while (i < numCodes) { + var j = 1; + var sym = readCode(input, codeLengthTable); + switch (sym) { + case 16: + j = readBits(input, 2) + 3; + sym = prev; + break; + case 17: + j = readBits(input, 3) + 3; + sym = 0; + break; + case 18: + j = readBits(input, 7) + 11; + sym = 0; + break; + default: + prev = sym; + } + while (j--) { + bitLengths[i++] = sym; + } + } + var distanceTable = makeHuffmanTable(bitLengths.splice(numLiteralCodes, numDistanceCodes)); + var literalTable = makeHuffmanTable(bitLengths); + inflate(input, output, literalTable, distanceTable); + break; + default: + fail('unknown block type', 'inflate'); + } + } + function readBits(input, size) { + var buffer = input.bitBuffer; + var bufflen = input.bitLength; + while (size > bufflen) { + buffer |= input.readUnsignedByte() << bufflen; + bufflen += 8; + } + input.bitBuffer = buffer >>> size; + input.bitLength = bufflen - size; + return buffer & (1 << size) - 1; + } + function inflate(input, output, literalTable, distanceTable) { + var sym; + while ((sym = readCode(input, literalTable)) !== 256) { + if (sym < 256) { + output.writeUnsignedByte(sym); + } else { + sym -= 257; + var len = lengthCodes[sym] + readBits(input, lengthExtraBits[sym]); + sym = readCode(input, distanceTable); + var distance = distanceCodes[sym] + readBits(input, distanceExtraBits[sym]); + output.writeBytes(output, output.position - distance, len); + } + } + } + function readCode(input, codeTable) { + var buffer = input.bitBuffer; + var bitlen = input.bitLength; + var maxBits = codeTable.maxBits; + while (maxBits > bitlen) { + buffer |= input.readUnsignedByte() << bitlen; + bitlen += 8; + } + var code = codeTable.codes[buffer & (1 << maxBits) - 1]; + var len = code >> 16; + if (!len) { + throwCompressedDataError(); + } + input.bitBuffer = buffer >>> len; + input.bitLength = bitlen - len; + return code & 65535; + } + function adler32(data, start, end) { + var a = 1; + var b = 0; + for (var i = start; i < end; ++i) { + a = (a + (data[i] & 255)) % 65521; + b = (b + a) % 65521; + } + return b << 16 | a; + } + BAp.compress = function (algorithm) { + this.position = 0; + var output = new ByteArray(); + switch (algorithm) { + case 'zlib': + output.writeUnsignedByte(120); + output.writeUnsignedByte(156); + case 'deflate': + output.le = true; + var len = this.length; + output.ensureCapacity(len + Math.ceil(len / 65535) * 5 + 4); + while (len > 65535) { + output.writeUnsignedByte(0); + output.writeUnsignedShort(65535); + output.writeUnsignedShort(0); + output.writeBytes(this, this.position, 65535); + this.position += 65535; + len -= 65535; + } + output.writeUnsignedByte(0); + output.writeUnsignedShort(len); + output.writeUnsignedShort(~len & 65535); + output.writeBytes(this, this.position, len); + if (algorithm === 'zlib') { + output.writeUnsignedInt(adler32(this.uint8v, 0, this.length)); + } + break; + default: + return; + } + this.ensureCapacity(output.uint8v.length); + this.uint8v.set(output.uint8v); + this.length = output.length; + this.position = 0; + }; + BAp.uncompress = function (algorithm) { + var output = new ByteArray(); + switch (algorithm) { + case 'zlib': + var header = this.readUnsignedShort(); + if ((header & 3840) !== 2048 || header % 31 !== 0 || header & 32) { + throwCompressedDataError(); + } + case 'deflate': + var le = this.le; + this.le = true; + while (this.position < this.length - 6) { + inflateBlock(this, output); + } + this.le = le; + break; + default: + return; + } + this.ensureCapacity(output.uint8v.length); + this.uint8v.set(output.uint8v); + this.length = output.length; + this.position = 0; + }; + return ByteArrayClass; + }(); +var Shumway; +(function (Shumway) { + (function (Options) { + var Argument = function () { + function Argument(shortName, longName, type, options) { + this.shortName = shortName; + this.longName = longName; + this.type = type; + options = options || {}; + this.positional = options.positional; + this.parseFn = options.parse; + this.value = options.defaultValue; + } + Argument.prototype.parse = function (value) { + if (this.type === 'boolean') { + true; + this.value = value; + } else if (this.type === 'number') { + true; + this.value = parseInt(value, 10); + } else { + this.value = value; + } + if (this.parseFn) { + this.parseFn(this.value); + } + }; + return Argument; + }(); + Options.Argument = Argument; + var ArgumentParser = function () { + function ArgumentParser() { + this.args = []; + } + ArgumentParser.prototype.addArgument = function (shortName, longName, type, options) { + var argument = new Argument(shortName, longName, type, options); + this.args.push(argument); + return argument; + }; + ArgumentParser.prototype.addBoundOption = function (option) { + var options = { + parse: function (x) { + option.value = x; + } + }; + this.args.push(new Argument(option.shortName, option.longName, option.type, options)); + }; + ArgumentParser.prototype.addBoundOptionSet = function (optionSet) { + var self = this; + optionSet.options.forEach(function (x) { + if (x instanceof OptionSet) { + self.addBoundOptionSet(x); + } else { + true; + self.addBoundOption(x); + } + }); + }; + ArgumentParser.prototype.getUsage = function () { + var str = ''; + this.args.forEach(function (x) { + if (!x.positional) { + str += '[-' + x.shortName + '|--' + x.longName + (x.type === 'boolean' ? '' : ' ' + x.type[0].toUpperCase()) + ']'; + } else { + str += x.longName; + } + str += ' '; + }); + return str; + }; + ArgumentParser.prototype.parse = function (args) { + var nonPositionalArgumentMap = {}; + var positionalArgumentList = []; + this.args.forEach(function (x) { + if (x.positional) { + positionalArgumentList.push(x); + } else { + nonPositionalArgumentMap['-' + x.shortName] = x; + nonPositionalArgumentMap['--' + x.longName] = x; + } + }); + var leftoverArguments = []; + while (args.length) { + var argString = args.shift(); + var argument = null, value = argString; + if (argString == '--') { + leftoverArguments = leftoverArguments.concat(args); + break; + } else if (argString.slice(0, 1) == '-' || argString.slice(0, 2) == '--') { + argument = nonPositionalArgumentMap[argString]; + true; + if (!argument) { + continue; + } + if (argument.type !== 'boolean') { + value = args.shift(); + true; + } else { + value = true; + } + } else if (positionalArgumentList.length) { + argument = positionalArgumentList.shift(); + } else { + leftoverArguments.push(value); + } + if (argument) { + argument.parse(value); + } + } + true; + return leftoverArguments; + }; + return ArgumentParser; + }(); + Options.ArgumentParser = ArgumentParser; + var OptionSet = function () { + function OptionSet(name) { + this.name = name; + this.options = []; + } + OptionSet.prototype.register = function (option) { + this.options.push(option); + return option; + }; + OptionSet.prototype.trace = function (writer) { + writer.enter(this.name + ' {'); + this.options.forEach(function (option) { + option.trace(writer); + }); + writer.leave('}'); + }; + return OptionSet; + }(); + Options.OptionSet = OptionSet; + var Option = function () { + function Option(shortName, longName, type, defaultValue, description) { + this.longName = longName; + this.shortName = shortName; + this.type = type; + this.defaultValue = defaultValue; + this.value = defaultValue; + this.description = description; + } + Option.prototype.parse = function (value) { + this.value = value; + }; + Option.prototype.trace = function (writer) { + writer.writeLn(('-' + this.shortName + '|--' + this.longName).padRight(' ', 30) + ' = ' + this.type + ' ' + this.value + ' [' + this.defaultValue + ']' + ' (' + this.description + ')'); + }; + return Option; + }(); + Options.Option = Option; + }(Shumway.Options || (Shumway.Options = {}))); + var Options = Shumway.Options; +}(Shumway || (Shumway = {}))); +if (typeof exports !== 'undefined') { + exports['Shumway'] = Shumway; +} +var ArgumentParser = Shumway.Options.ArgumentParser; +var Option = Shumway.Options.Option; +var OptionSet = Shumway.Options.OptionSet; +var Option = Shumway.Options.Option; +var OptionSet = Shumway.Options.OptionSet; +var coreOptions = new OptionSet('Core Options'); +var Timeline = function () { + var barColor = 'rgba(255,255,255, 0.075)'; + var backgroundColor = 'rgb(61, 61, 61)'; + var backgroundColorInfo = 'rgba(0,0,0, 0.85)'; + var fpsLineColor = 'rgb(255,64,0)'; + var textColor = '#ccc'; + function timeline(canvas) { + this.depth = 0; + this.start = 0; + this.index = 0; + this.marks = new Shumway.CircularBuffer(Int32Array); + this.times = new Shumway.CircularBuffer(Float64Array); + this.frameRate = 12; + this.maxFrameTime = 1000 * 2 / this.frameRate; + this.refreshFrequency = 10; + this.refreshCounter = 0; + this.count = 0; + this.kinds = createEmptyObject(); + this.kindCount = 0; + this.canvas = canvas; + this.context = canvas.getContext('2d', { + original: true + }); + this.fillStyles = [ + 'rgb(85, 152, 213)', + '#bfd8a7', + '#d906d7' + ]; + window.addEventListener('resize', this.resizeHandler.bind(this), false); + this.resizeHandler(); + } + timeline.prototype.setFrameRate = function setFrameRate(frameRate) { + this.frameRate = frameRate; + this.maxFrameTime = 1000 * 2 / frameRate; + }; + timeline.prototype.refreshEvery = function refreshEvery(freq) { + this.refreshFrequency = freq; + this.refreshCounter = 0; + }; + var ENTER = 3203334144 | 0; + var LEAVE = 3735879680 | 0; + timeline.prototype.registerKind = function getKind(name, fillStyle) { + if (this.kinds[name] === undefined) { + this.fillStyles[this.kindCount] = fillStyle; + this.kinds[name] = this.kindCount++; + } else { + this.fillStyles[this.kinds[name]] = fillStyle; + } + }; + timeline.prototype.getKind = function getKind(name) { + if (this.kinds[name] === undefined) { + this.kinds[name] = this.kindCount++; + if (this.kindCount > this.fillStyles.length) { + this.fillStyles.push(randomStyle()); + } + } + return this.kinds[name]; + }; + timeline.prototype.enter = function enter(name) { + this.depth++; + this.marks.write(ENTER | this.getKind(name)); + this.times.write(performance.now()); + }; + timeline.prototype.leave = function leave(name) { + this.marks.write(LEAVE | this.getKind(name)); + this.times.write(performance.now()); + this.depth--; + if (this.depth === 0) { + this.count++; + if (++this.refreshCounter == this.refreshFrequency) { + this.refreshCounter = 0; + this.paint(); + } + } + }; + timeline.prototype.gatherFrames = function gatherFrames(maxFrames) { + var stack = []; + var frames = []; + var times = this.times; + maxFrames++; + this.marks.forEachInReverse(function (mark, i) { + var time = times.get(i); + if ((mark & 4294901760) === ENTER) { + var node = stack.pop(); + node.startTime = time; + if (!stack.length) { + if (frames.length && !frames[0].total) { + frames[0].total = frames[0].startTime - time; + } + frames.unshift(node); + } else { + var top = stack.top(); + if (!top.children) { + top.children = [ + node + ]; + } else { + top.children.push(node); + } + } + } else if ((mark & 4294901760) === LEAVE) { + if (frames.length > maxFrames) { + return true; + } + stack.push({ + kind: mark & 65535, + endTime: time + }); + } + }); + return frames; + }; + timeline.prototype.resizeHandler = function resizeHandler(event) { + var parent = this.canvas.parentElement; + this.cw = parent.offsetWidth; + this.ch = parent.offsetHeight - 1; + var devicePixelRatio = window.devicePixelRatio || 1; + var backingStoreRatio = this.context.webkitBackingStorePixelRatio || this.context.mozBackingStorePixelRatio || this.context.msBackingStorePixelRatio || this.context.oBackingStorePixelRatio || this.context.backingStorePixelRatio || 1; + if (devicePixelRatio !== backingStoreRatio) { + var ratio = devicePixelRatio / backingStoreRatio; + this.canvas.width = this.cw * ratio; + this.canvas.height = this.ch * ratio; + this.canvas.style.width = this.cw + 'px'; + this.canvas.style.height = this.ch + 'px'; + this.context.scale(ratio, ratio); + } else { + this.canvas.width = this.cw; + this.canvas.height = this.ch; + } + this.context.font = '10px Consolas, "Liberation Mono", Courier, monospace'; + }; + timeline.prototype.paint = function paint() { + var w = 10; + var gap = 1; + var maxFrames = this.cw / (w + gap) | 0; + var frames = this.gatherFrames(maxFrames); + var context = this.context; + var maxFrameTime = this.maxFrameTime; + var fillStyles = this.fillStyles; + context.clearRect(0, 0, this.cw, this.ch); + var maxFrameRate = 0; + var maxFrameRateCount = 0; + var avgFrameRate = 0; + var avgFrameRateCount = 0; + var offsetW; + context.save(); + context.translate(0, this.ch); + context.scale(1, -this.ch / maxFrameTime); + for (var i = 0; i < frames.length - 1; i++) { + var frame = frames[i]; + maxFrameRate += frame.endTime - frame.startTime; + maxFrameRateCount++; + if (frame.total) { + avgFrameRate += frame.total; + avgFrameRateCount++; + } + offsetW = i * (w + gap); + context.fillStyle = barColor; + context.fillRect(offsetW, 0, w, frames[i + 1].startTime - frame.startTime); + drawNode(frame, frame.startTime); + } + function drawNode(node, frameStartTime) { + var nodeTime = node.endTime - node.startTime; + var offsetH = node.startTime - frameStartTime; + context.fillStyle = fillStyles[node.kind]; + context.fillRect(offsetW, offsetH, w, nodeTime); + if (node.children) { + var children = node.children; + for (var i = 0, n = children.length; i < n; i++) { + drawNode(children[i], frameStartTime); + } + } + } + var lineH = 1000 / this.frameRate; + context.beginPath(); + context.lineWidth = 0.5; + context.moveTo(0, lineH); + context.lineTo(this.cw, lineH); + context.strokeStyle = fpsLineColor; + context.stroke(); + context.restore(); + context.fillStyle = backgroundColorInfo; + context.fillRect(0, 0, this.cw, 20); + var textOffset; + var sFrameCount = this.count; + var sMaxFrameRate = Math.round(1000 * maxFrameRateCount / maxFrameRate); + var sAvgFrameRate = Math.round(1000 * avgFrameRateCount / avgFrameRate); + var space = 5; + textOffset = 5; + context.fillStyle = textColor; + context.fillText(sFrameCount, textOffset, 13); + textOffset += context.measureText(sFrameCount).width + space; + context.fillText(sMaxFrameRate, textOffset, 13); + textOffset += context.measureText(sMaxFrameRate).width + space; + context.fillText(sAvgFrameRate, textOffset, 13); + var basicOffset = textOffset + context.measureText(sAvgFrameRate).width + space; + textOffset = this.cw; + for (var k in this.kinds) { + context.fillStyle = this.fillStyles[this.getKind(k)]; + textOffset -= context.measureText(k).width + space; + if (textOffset > basicOffset) { + this.context.fillText(k, textOffset, 13); + } + } + }; + return timeline; + }(); +var create = Object.create; +var defineProperty = Object.defineProperty; +var keys = Object.keys; +var isArray = Array.isArray; +var fromCharCode = String.fromCharCode; +var logE = Math.log; +var max = Math.max; +var min = Math.min; +var pow = Math.pow; +var push = Array.prototype.push; +var slice = Array.prototype.slice; +var splice = Array.prototype.splice; +function fail(msg, context) { + throw new Error((context ? context + ': ' : '') + msg); +} +function assert(cond, msg, context) { + if (!cond) + fail(msg, context); +} +function scriptProperties(namespace, props) { + return props.reduce(function (o, p) { + o[p] = namespace + ' ' + p; + return o; + }, {}); +} +function cloneObject(obj) { + var clone = Object.create(null); + for (var prop in obj) + clone[prop] = obj[prop]; + return clone; +} +function sortNumeric(a, b) { + return a - b; +} +function sortByZindex(a, b) { + return a._zindex - b._zindex; +} +function rgbaObjToStr(color) { + return 'rgba(' + color.red + ',' + color.green + ',' + color.blue + ',' + color.alpha / 255 + ')'; +} +function rgbIntAlphaToStr(color, alpha) { + color |= 0; + if (alpha >= 1) { + var colorStr = color.toString(16); + while (colorStr.length < 6) { + colorStr = '0' + colorStr; + } + return '#' + colorStr; + } + var red = color >> 16 & 255; + var green = color >> 8 & 255; + var blue = color & 255; + return 'rgba(' + red + ',' + green + ',' + blue + ',' + alpha + ')'; +} +function argbUintToStr(argb) { + return 'rgba(' + (argb >>> 16 & 255) + ',' + (argb >>> 8 & 255) + ',' + (argb & 255) + ',' + (argb >>> 24 & 255) / 255 + ')'; +} +(function functionNameSupport() { + if (eval('function t() {} t.name === \'t\'')) { + return; + } + Object.defineProperty(Function.prototype, 'name', { + get: function () { + if (this.__name) { + return this.__name; + } + var m = /function\s([^\(]+)/.exec(this.toString()); + var name = m && m[1] !== 'anonymous' ? m[1] : null; + this.__name = name; + return name; + }, + configurable: true, + enumerable: false + }); +}()); +var randomStyleCache; +var nextStyle = 0; +function randomStyle() { + if (!randomStyleCache) { + randomStyleCache = [ + '#ff5e3a', + '#ff9500', + '#ffdb4c', + '#87fc70', + '#52edc7', + '#1ad6fd', + '#c644fc', + '#ef4db6', + '#4a4a4a', + '#dbddde', + '#ff3b30', + '#ff9500', + '#ffcc00', + '#4cd964', + '#34aadc', + '#007aff', + '#5856d6', + '#ff2d55', + '#8e8e93', + '#c7c7cc', + '#5ad427', + '#c86edf', + '#d1eefc', + '#e0f8d8', + '#fb2b69', + '#f7f7f7', + '#1d77ef', + '#d6cec3', + '#55efcb', + '#ff4981', + '#ffd3e0', + '#f7f7f7', + '#ff1300', + '#1f1f21', + '#bdbec2', + '#ff3a2d' + ]; + } + return randomStyleCache[nextStyle++ % randomStyleCache.length]; +} +(function PromiseClosure() { + var global = Function('return this')(); + if (global.Promise) { + if (typeof global.Promise.all !== 'function') { + global.Promise.all = function (iterable) { + var count = 0, results = [], resolve, reject; + var promise = new global.Promise(function (resolve_, reject_) { + resolve = resolve_; + reject = reject_; + }); + iterable.forEach(function (p, i) { + count++; + p.then(function (result) { + results[i] = result; + count--; + if (count === 0) { + resolve(results); + } + }, reject); + }); + if (count === 0) { + resolve(results); + } + return promise; + }; + } + if (typeof global.Promise.resolve !== 'function') { + global.Promise.resolve = function (x) { + return new global.Promise(function (resolve) { + resolve(x); + }); + }; + } + return; + } + function getDeferred(C) { + if (typeof C !== 'function') { + throw new TypeError('Invalid deferred constructor'); + } + var resolver = createDeferredConstructionFunctions(); + var promise = new C(resolver); + var resolve = resolver.resolve; + if (typeof resolve !== 'function') { + throw new TypeError('Invalid resolve construction function'); + } + var reject = resolver.reject; + if (typeof reject !== 'function') { + throw new TypeError('Invalid reject construction function'); + } + return { + promise: promise, + resolve: resolve, + reject: reject + }; + } + function updateDeferredFromPotentialThenable(x, deferred) { + if (typeof x !== 'object' || x === null) { + return false; + } + try { + var then = x.then; + if (typeof then !== 'function') { + return false; + } + var thenCallResult = then.call(x, deferred.resolve, deferred.reject); + } catch (e) { + var reject = deferred.reject; + reject(e); + } + return true; + } + function isPromise(x) { + return typeof x === 'object' && x !== null && typeof x.promiseStatus !== 'undefined'; + } + function rejectPromise(promise, reason) { + if (promise.promiseStatus !== 'unresolved') { + return; + } + var reactions = promise.rejectReactions; + promise.result = reason; + promise.resolveReactions = undefined; + promise.rejectReactions = undefined; + promise.promiseStatus = 'has-rejection'; + triggerPromiseReactions(reactions, reason); + } + function resolvePromise(promise, resolution) { + if (promise.promiseStatus !== 'unresolved') { + return; + } + var reactions = promise.resolveReactions; + promise.result = resolution; + promise.resolveReactions = undefined; + promise.rejectReactions = undefined; + promise.promiseStatus = 'has-resolution'; + triggerPromiseReactions(reactions, resolution); + } + function triggerPromiseReactions(reactions, argument) { + for (var i = 0; i < reactions.length; i++) { + queueMicrotask({ + reaction: reactions[i], + argument: argument + }); + } + } + function queueMicrotask(task) { + if (microtasksQueue.length === 0) { + setTimeout(handleMicrotasksQueue, 0); + } + microtasksQueue.push(task); + } + function executePromiseReaction(reaction, argument) { + var deferred = reaction.deferred; + var handler = reaction.handler; + var handlerResult, updateResult; + try { + handlerResult = handler(argument); + } catch (e) { + var reject = deferred.reject; + return reject(e); + } + if (handlerResult === deferred.promise) { + var reject = deferred.reject; + return reject(new TypeError('Self resolution')); + } + try { + updateResult = updateDeferredFromPotentialThenable(handlerResult, deferred); + if (!updateResult) { + var resolve = deferred.resolve; + return resolve(handlerResult); + } + } catch (e) { + var reject = deferred.reject; + return reject(e); + } + } + var microtasksQueue = []; + function handleMicrotasksQueue() { + while (microtasksQueue.length > 0) { + var task = microtasksQueue[0]; + try { + executePromiseReaction(task.reaction, task.argument); + } catch (e) { + if (typeof Promise.onerror === 'function') { + Promise.onerror(e); + } + } + microtasksQueue.shift(); + } + } + function throwerFunction(e) { + throw e; + } + function identityFunction(x) { + return x; + } + function createRejectPromiseFunction(promise) { + return function (reason) { + rejectPromise(promise, reason); + }; + } + function createResolvePromiseFunction(promise) { + return function (resolution) { + resolvePromise(promise, resolution); + }; + } + function createDeferredConstructionFunctions() { + var fn = function (resolve, reject) { + fn.resolve = resolve; + fn.reject = reject; + }; + return fn; + } + function createPromiseResolutionHandlerFunctions(promise, fulfillmentHandler, rejectionHandler) { + return function (x) { + if (x === promise) { + return rejectionHandler(new TypeError('Self resolution')); + } + var cstr = promise.promiseConstructor; + if (isPromise(x)) { + var xConstructor = x.promiseConstructor; + if (xConstructor === cstr) { + return x.then(fulfillmentHandler, rejectionHandler); + } + } + var deferred = getDeferred(cstr); + var updateResult = updateDeferredFromPotentialThenable(x, deferred); + if (updateResult) { + var deferredPromise = deferred.promise; + return deferredPromise.then(fulfillmentHandler, rejectionHandler); + } + return fulfillmentHandler(x); + }; + } + function createPromiseAllCountdownFunction(index, values, deferred, countdownHolder) { + return function (x) { + values[index] = x; + countdownHolder.countdown--; + if (countdownHolder.countdown === 0) { + deferred.resolve(values); + } + }; + } + function Promise(resolver) { + if (typeof resolver !== 'function') { + throw new TypeError('resolver is not a function'); + } + var promise = this; + if (typeof promise !== 'object') { + throw new TypeError('Promise to initialize is not an object'); + } + promise.promiseStatus = 'unresolved'; + promise.resolveReactions = []; + promise.rejectReactions = []; + promise.result = undefined; + var resolve = createResolvePromiseFunction(promise); + var reject = createRejectPromiseFunction(promise); + try { + var result = resolver(resolve, reject); + } catch (e) { + rejectPromise(promise, e); + } + promise.promiseConstructor = Promise; + return promise; + } + Promise.all = function (iterable) { + var deferred = getDeferred(this); + var values = []; + var countdownHolder = { + countdown: 0 + }; + var index = 0; + iterable.forEach(function (nextValue) { + var nextPromise = this.cast(nextValue); + var fn = createPromiseAllCountdownFunction(index, values, deferred, countdownHolder); + nextPromise.then(fn, deferred.reject); + index++; + countdownHolder.countdown++; + }, this); + if (index === 0) { + deferred.resolve(values); + } + return deferred.promise; + }; + Promise.cast = function (x) { + if (isPromise(x)) { + return x; + } + var deferred = getDeferred(this); + deferred.resolve(x); + return deferred.promise; + }; + Promise.reject = function (r) { + var deferred = getDeferred(this); + var rejectResult = deferred.reject(r); + return deferred.promise; + }; + Promise.resolve = function (x) { + var deferred = getDeferred(this); + var rejectResult = deferred.resolve(x); + return deferred.promise; + }; + Promise.prototype = { + 'catch': function (onRejected) { + this.then(undefined, onRejected); + }, + then: function (onFulfilled, onRejected) { + var promise = this; + if (!isPromise(promise)) { + throw new TypeError('this is not a Promises'); + } + var cstr = promise.promiseConstructor; + var deferred = getDeferred(cstr); + var rejectionHandler = typeof onRejected === 'function' ? onRejected : throwerFunction; + var fulfillmentHandler = typeof onFulfilled === 'function' ? onFulfilled : identityFunction; + var resolutionHandler = createPromiseResolutionHandlerFunctions(promise, fulfillmentHandler, rejectionHandler); + var resolveReaction = { + deferred: deferred, + handler: resolutionHandler + }; + var rejectReaction = { + deferred: deferred, + handler: rejectionHandler + }; + switch (promise.promiseStatus) { + case 'unresolved': + promise.resolveReactions.push(resolveReaction); + promise.rejectReactions.push(rejectReaction); + break; + case 'has-resolution': + var resolution = promise.result; + queueMicrotask({ + reaction: resolveReaction, + argument: resolution + }); + break; + case 'has-rejection': + var rejection = promise.result; + queueMicrotask({ + reaction: rejectReaction, + argument: rejection + }); + break; + } + return deferred.promise; + } + }; + global.Promise = Promise; +}()); +var QuadTree = function (x, y, width, height, parent) { + this.x = x | 0; + this.y = y | 0; + this.width = width | 0; + this.height = height | 0; + if (parent) { + this.root = parent.root; + this.parent = parent; + this.level = parent.level + 1; + } else { + this.root = this; + this.parent = null; + this.level = 0; + } + this.reset(); +}; +QuadTree.prototype.reset = function () { + this.stuckObjects = null; + this.objects = null; + this.nodes = []; +}; +QuadTree.prototype._findIndex = function (xMin, xMax, yMin, yMax) { + var midX = this.x + (this.width / 2 | 0); + var midY = this.y + (this.height / 2 | 0); + var top = yMin < midY && yMax < midY; + var bottom = yMin > midY; + if (xMin < midX && xMax < midX) { + if (top) { + return 1; + } else if (bottom) { + return 2; + } + } else if (xMin > midX) { + if (top) { + return 0; + } else if (bottom) { + return 3; + } + } + return -1; +}; +QuadTree.prototype.insert = function (obj) { + var nodes = this.nodes; + if (nodes.length) { + var index = this._findIndex(obj.xMin, obj.xMax, obj.yMin, obj.yMax); + if (index > -1) { + nodes[index].insert(obj); + } else { + obj.prev = null; + if (this.stuckObjects) { + obj.next = this.stuckObjects; + this.stuckObjects.prev = obj; + } else { + obj.next = null; + } + this.stuckObjects = obj; + obj.parent = this; + } + return; + } + var numChildren = 1; + var item = this.objects; + if (!item) { + obj.prev = null; + obj.next = null; + this.objects = obj; + } else { + while (item.next) { + numChildren++; + item = item.next; + } + obj.prev = item; + obj.next = null; + item.next = obj; + } + if (numChildren > 4 && this.level < 10) { + this._subdivide(); + item = this.objects; + while (item) { + var next = item.next; + this.insert(item); + item = next; + } + this.objects = null; + return; + } + obj.parent = this; +}; +QuadTree.prototype.update = function (obj) { + var node = obj.parent; + if (node) { + if (obj.xMin >= node.x && obj.xMax <= node.x + node.width && obj.yMin >= node.y && obj.yMax <= node.y + node.height) { + if (node.nodes.length) { + var index = this._findIndex(obj.xMin, obj.xMax, obj.yMin, obj.yMax); + if (index > -1) { + node.remove(obj); + node = this.nodes[index]; + node.insert(obj); + } + } else { + node.remove(obj); + node.insert(obj); + } + return; + } + node.remove(obj); + } + this.root.insert(obj); +}; +QuadTree.prototype.remove = function (obj) { + var prev = obj.prev; + var next = obj.next; + if (prev) { + prev.next = next; + obj.prev = null; + } else { + var node = obj.parent; + if (node.objects === obj) { + node.objects = next; + } else if (node.stuckObjects === obj) { + node.stuckObjects = next; + } + } + if (next) { + next.prev = prev; + obj.next = null; + } + obj.parent = null; +}; +QuadTree.prototype.retrieve = function (xMin, xMax, yMin, yMax) { + var stack = []; + var out = []; + var node = this; + do { + if (node.nodes.length) { + var index = node._findIndex(xMin, xMax, yMin, yMax); + if (index > -1) { + stack.push(node.nodes[index]); + } else { + stack.push.apply(stack, node.nodes); + } + } + var item = node.objects; + for (var i = 0; i < 2; i++) { + while (item) { + if (!(item.xMin > xMax || item.xMax < xMin || item.yMin > yMax || item.yMax < yMin)) { + out.push(item); + } + item = item.next; + } + item = node.stuckObjects; + } + node = stack.pop(); + } while (node); + return out; +}; +QuadTree.prototype._subdivide = function () { + var halfWidth = this.width / 2 | 0; + var halfHeight = this.height / 2 | 0; + var midX = this.x + halfWidth; + var midY = this.y + halfHeight; + this.nodes[0] = new QuadTree(midX, this.y, halfWidth, halfHeight, this); + this.nodes[1] = new QuadTree(this.x, this.y, halfWidth, halfHeight, this); + this.nodes[2] = new QuadTree(this.x, midY, halfWidth, halfHeight, this); + this.nodes[3] = new QuadTree(midX, midY, halfWidth, halfHeight, this); +}; +var RegionCluster = function () { + this.regions = []; +}; +RegionCluster.prototype.reset = function () { + this.regions.length = 0; +}; +RegionCluster.prototype.insert = function (region) { + var regions = this.regions; + if (regions.length < 3) { + regions.push({ + xMin: region.xMin, + xMax: region.xMax, + yMin: region.yMin, + yMax: region.yMax + }); + return; + } + var a = region; + var b = regions[0]; + var c = regions[1]; + var d = regions[2]; + var ab = (max(a.xMax, b.xMax) - min(a.xMin, b.xMin)) * (max(a.yMax, b.yMax) - min(a.yMin, b.yMin)); + var rb = regions[0]; + var ac = (max(a.xMax, c.xMax) - min(a.xMin, c.xMin)) * (max(a.yMax, c.yMax) - min(a.yMin, c.yMin)); + var ad = (max(a.xMax, d.xMax) - min(a.xMin, d.xMin)) * (max(a.yMax, d.yMax) - min(a.yMin, d.yMin)); + if (ac < ab) { + ab = ac; + rb = c; + } + if (ad < ab) { + ab = ad; + rb = d; + } + var bc = (max(b.xMax, c.xMax) - min(b.xMin, c.xMin)) * (max(b.yMax, c.yMax) - min(b.yMin, c.yMin)); + var bd = (max(b.xMax, d.xMax) - min(b.xMin, d.xMin)) * (max(b.yMax, d.yMax) - min(b.yMin, d.yMin)); + var cd = (max(c.xMax, d.xMax) - min(c.xMin, d.xMin)) * (max(c.yMax, d.yMax) - min(c.yMin, d.yMin)); + if (ab < bc && ab < bd && ab < cd) { + if (a.xMin < rb.xMin) { + rb.xMin = a.xMin; + } + if (a.xMax > rb.xMax) { + rb.xMax = a.xMax; + } + if (a.yMin < rb.yMin) { + rb.yMin = a.yMin; + } + if (a.yMax > rb.yMax) { + rb.yMax = a.yMax; + } + return; + } + rb = regions[0]; + var rc = regions[1]; + if (bd < bc) { + bc = bd; + rc = regions[2]; + } + if (cd < bc) { + rb = regions[1]; + rc = regions[2]; + } + if (rc.xMin < rb.xMin) { + rb.xMin = rc.xMin; + } + if (rc.xMax > rb.xMax) { + rb.xMax = rc.xMax; + } + if (rc.yMin < rb.yMin) { + rb.yMin = rc.yMin; + } + if (rc.yMax > rb.yMax) { + rb.yMax = rc.yMax; + } + rc.xMin = a.xMin; + rc.xMax = a.xMax; + rc.yMin = a.yMin; + rc.yMax = a.yMax; +}; +RegionCluster.prototype.retrieve = function () { + return this.regions; +}; +var EXTERNAL_INTERFACE_FEATURE = 1; +var CLIPBOARD_FEATURE = 2; +var SHAREDOBJECT_FEATURE = 3; +var VIDEO_FEATURE = 4; +var SOUND_FEATURE = 5; +var NETCONNECTION_FEATURE = 6; +if (!this.performance) { + this.performance = {}; +} +if (!this.performance.now) { + this.performance.now = Date.now; +} +var SWF_TAG_CODE_CSM_TEXT_SETTINGS = 74; +var SWF_TAG_CODE_DEFINE_BINARY_DATA = 87; +var SWF_TAG_CODE_DEFINE_BITS = 6; +var SWF_TAG_CODE_DEFINE_BITS_JPEG2 = 21; +var SWF_TAG_CODE_DEFINE_BITS_JPEG3 = 35; +var SWF_TAG_CODE_DEFINE_BITS_JPEG4 = 90; +var SWF_TAG_CODE_DEFINE_BITS_LOSSLESS = 20; +var SWF_TAG_CODE_DEFINE_BITS_LOSSLESS2 = 36; +var SWF_TAG_CODE_DEFINE_BUTTON = 7; +var SWF_TAG_CODE_DEFINE_BUTTON2 = 34; +var SWF_TAG_CODE_DEFINE_BUTTON_CXFORM = 23; +var SWF_TAG_CODE_DEFINE_BUTTON_SOUND = 17; +var SWF_TAG_CODE_DEFINE_EDIT_TEXT = 37; +var SWF_TAG_CODE_DEFINE_FONT = 10; +var SWF_TAG_CODE_DEFINE_FONT2 = 48; +var SWF_TAG_CODE_DEFINE_FONT3 = 75; +var SWF_TAG_CODE_DEFINE_FONT4 = 91; +var SWF_TAG_CODE_DEFINE_FONT_ALIGN_ZONES = 73; +var SWF_TAG_CODE_DEFINE_FONT_INFO = 13; +var SWF_TAG_CODE_DEFINE_FONT_INFO2 = 62; +var SWF_TAG_CODE_DEFINE_FONT_NAME = 88; +var SWF_TAG_CODE_DEFINE_MORPH_SHAPE = 46; +var SWF_TAG_CODE_DEFINE_MORPH_SHAPE2 = 84; +var SWF_TAG_CODE_DEFINE_SCALING_GRID = 78; +var SWF_TAG_CODE_DEFINE_SCENE_AND_FRAME_LABEL_DATA = 86; +var SWF_TAG_CODE_DEFINE_SHAPE = 2; +var SWF_TAG_CODE_DEFINE_SHAPE2 = 22; +var SWF_TAG_CODE_DEFINE_SHAPE3 = 32; +var SWF_TAG_CODE_DEFINE_SHAPE4 = 83; +var SWF_TAG_CODE_DEFINE_SOUND = 14; +var SWF_TAG_CODE_DEFINE_SPRITE = 39; +var SWF_TAG_CODE_DEFINE_TEXT = 11; +var SWF_TAG_CODE_DEFINE_TEXT2 = 33; +var SWF_TAG_CODE_DEFINE_VIDEO_STREAM = 60; +var SWF_TAG_CODE_DO_ABC = 82; +var SWF_TAG_CODE_DO_ABC_ = 72; +var SWF_TAG_CODE_DO_ACTION = 12; +var SWF_TAG_CODE_DO_INIT_ACTION = 59; +var SWF_TAG_CODE_ENABLE_DEBUGGER = 58; +var SWF_TAG_CODE_ENABLE_DEBUGGER2 = 64; +var SWF_TAG_CODE_END = 0; +var SWF_TAG_CODE_EXPORT_ASSETS = 56; +var SWF_TAG_CODE_FILE_ATTRIBUTES = 69; +var SWF_TAG_CODE_FRAME_LABEL = 43; +var SWF_TAG_CODE_IMPORT_ASSETS = 57; +var SWF_TAG_CODE_IMPORT_ASSETS2 = 71; +var SWF_TAG_CODE_JPEG_TABLES = 8; +var SWF_TAG_CODE_METADATA = 77; +var SWF_TAG_CODE_PLACE_OBJECT = 4; +var SWF_TAG_CODE_PLACE_OBJECT2 = 26; +var SWF_TAG_CODE_PLACE_OBJECT3 = 70; +var SWF_TAG_CODE_PROTECT = 24; +var SWF_TAG_CODE_REMOVE_OBJECT = 5; +var SWF_TAG_CODE_REMOVE_OBJECT2 = 28; +var SWF_TAG_CODE_SCRIPT_LIMITS = 65; +var SWF_TAG_CODE_SET_BACKGROUND_COLOR = 9; +var SWF_TAG_CODE_SET_TAB_INDEX = 66; +var SWF_TAG_CODE_SHOW_FRAME = 1; +var SWF_TAG_CODE_SOUND_STREAM_BLOCK = 19; +var SWF_TAG_CODE_SOUND_STREAM_HEAD = 18; +var SWF_TAG_CODE_SOUND_STREAM_HEAD2 = 45; +var SWF_TAG_CODE_START_SOUND = 15; +var SWF_TAG_CODE_START_SOUND2 = 89; +var SWF_TAG_CODE_SYMBOL_CLASS = 76; +var SWF_TAG_CODE_VIDEO_FRAME = 61; +self.SWF = {}; +var codeLengthOrder = [ + 16, + 17, + 18, + 0, + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15 + ]; +var distanceCodes = []; +var distanceExtraBits = []; +for (var i = 0, j = 0, code = 1; i < 30; ++i) { + distanceCodes[i] = code; + code += 1 << (distanceExtraBits[i] = ~(~((j += i > 2 ? 1 : 0) / 2))); +} +var bitLengths = []; +for (var i = 0; i < 32; ++i) + bitLengths[i] = 5; +var fixedDistanceTable = makeHuffmanTable(bitLengths); +var lengthCodes = []; +var lengthExtraBits = []; +for (var i = 0, j = 0, code = 3; i < 29; ++i) { + lengthCodes[i] = code - (i == 28 ? 1 : 0); + code += 1 << (lengthExtraBits[i] = ~(~((j += i > 4 ? 1 : 0) / 4 % 6))); +} +for (var i = 0; i < 288; ++i) + bitLengths[i] = i < 144 || i > 279 ? 8 : i < 256 ? 9 : 7; +var fixedLiteralTable = makeHuffmanTable(bitLengths); +function makeHuffmanTable(bitLengths) { + var maxBits = Math.max.apply(null, bitLengths); + var numLengths = bitLengths.length; + var size = 1 << maxBits; + var codes = new Uint32Array(size); + for (var code = 0, len = 1, skip = 2; len <= maxBits; code <<= 1, ++len, skip <<= 1) { + for (var val = 0; val < numLengths; ++val) { + if (bitLengths[val] === len) { + var lsb = 0; + for (var i = 0; i < len; ++i) + lsb = lsb * 2 + (code >> i & 1); + for (var i = lsb; i < size; i += skip) + codes[i] = len << 16 | val; + ++code; + } + } + } + return { + codes: codes, + maxBits: maxBits + }; +} +function verifyDeflateHeader(bytes) { + var header = bytes[0] << 8 | bytes[1]; +} +function createInflatedStream(bytes, outputLength) { + verifyDeflateHeader(bytes); + var stream = new Stream(bytes, 2); + var output = { + data: new Uint8Array(outputLength), + available: 0, + completed: false + }; + var state = { + header: null, + distanceTable: null, + literalTable: null, + sym: null, + len: null, + sym2: null + }; + do { + inflateBlock(stream, output, state); + } while (!output.completed && stream.pos < stream.end); + return new Stream(output.data, 0, output.available); +} +var InflateNoDataError = {}; +function inflateBlock(stream, output, state) { + var header = state.header !== null ? state.header : state.header = readBits(stream.bytes, stream, 3); + switch (header >> 1) { + case 0: + stream.align(); + var pos = stream.pos; + if (stream.end - pos < 4) { + throw InflateNoDataError; + } + var len = stream.getUint16(pos, true); + var nlen = stream.getUint16(pos + 2, true); + if (stream.end - pos < 4 + len) { + throw InflateNoDataError; + } + var begin = pos + 4; + var end = stream.pos = begin + len; + var sbytes = stream.bytes, dbytes = output.data; + dbytes.set(sbytes.subarray(begin, end), output.available); + output.available += len; + break; + case 1: + inflate(stream, output, fixedLiteralTable, fixedDistanceTable, state); + break; + case 2: + var distanceTable, literalTable; + if (state.distanceTable !== null) { + distanceTable = state.distanceTable; + literalTable = state.literalTable; + } else { + var sbytes = stream.bytes; + var savedBufferPos = stream.pos; + var savedBitBuffer = stream.bitBuffer; + var savedBitLength = stream.bitLength; + var bitLengths = []; + var numLiteralCodes, numDistanceCodes; + try { + numLiteralCodes = readBits(sbytes, stream, 5) + 257; + numDistanceCodes = readBits(sbytes, stream, 5) + 1; + var numCodes = numLiteralCodes + numDistanceCodes; + var numLengthCodes = readBits(sbytes, stream, 4) + 4; + for (var i = 0; i < 19; ++i) + bitLengths[codeLengthOrder[i]] = i < numLengthCodes ? readBits(sbytes, stream, 3) : 0; + var codeLengthTable = makeHuffmanTable(bitLengths); + bitLengths = []; + var i = 0; + var prev = 0; + while (i < numCodes) { + var j = 1; + var sym = readCode(sbytes, stream, codeLengthTable); + switch (sym) { + case 16: + j = readBits(sbytes, stream, 2) + 3; + sym = prev; + break; + case 17: + j = readBits(sbytes, stream, 3) + 3; + sym = 0; + break; + case 18: + j = readBits(sbytes, stream, 7) + 11; + sym = 0; + break; + default: + prev = sym; + } + while (j--) + bitLengths[i++] = sym; + } + } catch (e) { + stream.pos = savedBufferPos; + stream.bitBuffer = savedBitBuffer; + stream.bitLength = savedBitLength; + throw e; + } + distanceTable = state.distanceTable = makeHuffmanTable(bitLengths.splice(numLiteralCodes, numDistanceCodes)); + literalTable = state.literalTable = makeHuffmanTable(bitLengths); + } + inflate(stream, output, literalTable, distanceTable, state); + state.distanceTable = null; + state.literalTable = null; + break; + default: + fail('unknown block type', 'inflate'); + } + state.header = null; + output.completed = !(!(header & 1)); +} +function readBits(bytes, stream, size) { + var bitBuffer = stream.bitBuffer; + var bitLength = stream.bitLength; + if (size > bitLength) { + var pos = stream.pos; + var end = stream.end; + do { + if (pos >= end) { + stream.pos = pos; + stream.bitBuffer = bitBuffer; + stream.bitLength = bitLength; + throw InflateNoDataError; + } + bitBuffer |= bytes[pos++] << bitLength; + bitLength += 8; + } while (size > bitLength); + stream.pos = pos; + } + stream.bitBuffer = bitBuffer >>> size; + stream.bitLength = bitLength - size; + return bitBuffer & (1 << size) - 1; +} +function inflate(stream, output, literalTable, distanceTable, state) { + var pos = output.available; + var dbytes = output.data; + var sbytes = stream.bytes; + var sym = state.sym !== null ? state.sym : readCode(sbytes, stream, literalTable); + while (sym !== 256) { + if (sym < 256) { + dbytes[pos++] = sym; + } else { + state.sym = sym; + sym -= 257; + var len = state.len !== null ? state.len : state.len = lengthCodes[sym] + readBits(sbytes, stream, lengthExtraBits[sym]); + var sym2 = state.sym2 !== null ? state.sym2 : state.sym2 = readCode(sbytes, stream, distanceTable); + var distance = distanceCodes[sym2] + readBits(sbytes, stream, distanceExtraBits[sym2]); + var i = pos - distance; + while (len--) + dbytes[pos++] = dbytes[i++]; + state.sym2 = null; + state.len = null; + state.sym = null; + } + output.available = pos; + sym = readCode(sbytes, stream, literalTable); + } +} +function readCode(bytes, stream, codeTable) { + var bitBuffer = stream.bitBuffer; + var bitLength = stream.bitLength; + var maxBits = codeTable.maxBits; + if (maxBits > bitLength) { + var pos = stream.pos; + var end = stream.end; + do { + if (pos >= end) { + stream.pos = pos; + stream.bitBuffer = bitBuffer; + stream.bitLength = bitLength; + throw InflateNoDataError; + } + bitBuffer |= bytes[pos++] << bitLength; + bitLength += 8; + } while (maxBits > bitLength); + stream.pos = pos; + } + var code = codeTable.codes[bitBuffer & (1 << maxBits) - 1]; + var len = code >> 16; + stream.bitBuffer = bitBuffer >>> len; + stream.bitLength = bitLength - len; + return code & 65535; +} +var StreamNoDataError = {}; +var Stream = function StreamClosure() { + function Stream_align() { + this.bitBuffer = this.bitLength = 0; + } + function Stream_ensure(size) { + if (this.pos + size > this.end) { + throw StreamNoDataError; + } + } + function Stream_remaining() { + return this.end - this.pos; + } + function Stream_substream(begin, end) { + var stream = new Stream(this.bytes); + stream.pos = begin; + stream.end = end; + return stream; + } + function Stream_push(data) { + var bytes = this.bytes; + var newBytesLength = this.end + data.length; + if (newBytesLength > bytes.length) { + throw 'stream buffer overfow'; + } + bytes.set(data, this.end); + this.end = newBytesLength; + } + function Stream(buffer, offset, length, maxLength) { + if (offset === undefined) + offset = 0; + if (buffer.buffer instanceof ArrayBuffer) { + offset += buffer.byteOffset; + buffer = buffer.buffer; + } + if (length === undefined) + length = buffer.byteLength - offset; + if (maxLength === undefined) + maxLength = length; + var bytes = new Uint8Array(buffer, offset, maxLength); + var stream = new DataView(buffer, offset, maxLength); + stream.bytes = bytes; + stream.pos = 0; + stream.end = length; + stream.bitBuffer = 0; + stream.bitLength = 0; + stream.align = Stream_align; + stream.ensure = Stream_ensure; + stream.remaining = Stream_remaining; + stream.substream = Stream_substream; + stream.push = Stream_push; + return stream; + } + return Stream; + }(); +var FORMAT_COLORMAPPED = 3; +var FORMAT_15BPP = 4; +var FORMAT_24BPP = 5; +var FACTOR_5BBP = 255 / 31; +var crcTable = []; +for (var i = 0; i < 256; i++) { + var c = i; + for (var h = 0; h < 8; h++) { + if (c & 1) + c = 3988292384 ^ c >> 1 & 2147483647; + else + c = c >> 1 & 2147483647; + } + crcTable[i] = c; +} +function crc32(data, start, end) { + var crc = -1; + for (var i = start; i < end; i++) { + var a = (crc ^ data[i]) & 255; + var b = crcTable[a]; + crc = crc >>> 8 ^ b; + } + return crc ^ -1; +} +function createPngChunk(type, data) { + var chunk = new Uint8Array(12 + data.length); + var p = 0; + var len = data.length; + chunk[p] = len >> 24 & 255; + chunk[p + 1] = len >> 16 & 255; + chunk[p + 2] = len >> 8 & 255; + chunk[p + 3] = len & 255; + chunk[p + 4] = type.charCodeAt(0) & 255; + chunk[p + 5] = type.charCodeAt(1) & 255; + chunk[p + 6] = type.charCodeAt(2) & 255; + chunk[p + 7] = type.charCodeAt(3) & 255; + if (data instanceof Uint8Array) + chunk.set(data, 8); + p = 8 + len; + var crc = crc32(chunk, 4, p); + chunk[p] = crc >> 24 & 255; + chunk[p + 1] = crc >> 16 & 255; + chunk[p + 2] = crc >> 8 & 255; + chunk[p + 3] = crc & 255; + return chunk; +} +function adler32(data, start, end) { + var a = 1; + var b = 0; + for (var i = start; i < end; ++i) { + a = (a + (data[i] & 255)) % 65521; + b = (b + a) % 65521; + } + return b << 16 | a; +} +function defineBitmap(tag) { + var width = tag.width; + var height = tag.height; + var hasAlpha = tag.hasAlpha; + var plte = ''; + var trns = ''; + var literals; + var bmpData = tag.bmpData; + switch (tag.format) { + case FORMAT_COLORMAPPED: + var colorType = 3; + var bytesPerLine = width + 3 & ~3; + var colorTableSize = tag.colorTableSize + 1; + var paletteSize = colorTableSize * (tag.hasAlpha ? 4 : 3); + var datalen = paletteSize + bytesPerLine * height; + var stream = createInflatedStream(bmpData, datalen); + var bytes = stream.bytes; + var pos = 0; + stream.ensure(paletteSize); + if (hasAlpha) { + var palette = new Uint8Array(paletteSize / 4 * 3); + var pp = 0; + var alphaValues = new Uint8Array(paletteSize / 4); + var pa = 0; + while (pos < paletteSize) { + palette[pp++] = bytes[pos]; + palette[pp++] = bytes[pos + 1]; + palette[pp++] = bytes[pos + 2]; + alphaValues[pa++] = bytes[pos + 3]; + pos += 4; + } + plte = createPngChunk('PLTE', palette); + trns = createPngChunk('tRNS', alphaValues); + } else { + plte = createPngChunk('PLTE', bytes.subarray(pos, pos + paletteSize)); + pos += paletteSize; + } + literals = new Uint8Array(width * height + height); + var pl = 0; + while (pos < datalen) { + stream.ensure(bytesPerLine); + var begin = pos; + var end = begin + width; + pl++; + literals.set(bytes.subarray(begin, end), pl); + pl += end - begin; + stream.pos = pos += bytesPerLine; + } + break; + case FORMAT_15BPP: + var colorType = 2; + var bytesPerLine = width * 2 + 3 & ~3; + var stream = createInflatedStream(bmpData, bytesPerLine * height); + var pos = 0; + literals = new Uint8Array(width * height * 3 + height); + var pl = 0; + for (var y = 0; y < height; ++y) { + pl++; + stream.ensure(bytesPerLine); + for (var x = 0; x < width; ++x) { + var word = stream.getUint16(pos); + pos += 2; + literals[pl++] = 0 | FACTOR_5BBP * (word >> 10 & 31); + literals[pl++] = 0 | FACTOR_5BBP * (word >> 5 & 31); + literals[pl++] = 0 | FACTOR_5BBP * (word & 31); + } + stream.pos = pos += bytesPerLine; + } + break; + case FORMAT_24BPP: + var padding; + if (hasAlpha) { + var colorType = 6; + padding = 0; + literals = new Uint8Array(width * height * 4 + height); + } else { + var colorType = 2; + padding = 1; + literals = new Uint8Array(width * height * 3 + height); + } + var bytesPerLine = width * 4; + var stream = createInflatedStream(bmpData, bytesPerLine * height); + var bytes = stream.bytes; + var pos = 0; + var pl = 0; + for (var y = 0; y < height; ++y) { + stream.ensure(bytesPerLine); + pl++; + for (var x = 0; x < width; ++x) { + pos += padding; + if (hasAlpha) { + var alpha = bytes[pos]; + if (alpha) { + var opacity = alpha / 255; + literals[pl++] = 0 | bytes[pos + 1] / opacity; + literals[pl++] = 0 | bytes[pos + 2] / opacity; + literals[pl++] = 0 | bytes[pos + 3] / opacity; + literals[pl++] = alpha; + } else { + pl += 4; + } + } else { + literals[pl++] = bytes[pos]; + literals[pl++] = bytes[pos + 1]; + literals[pl++] = bytes[pos + 2]; + } + pos += 4 - padding; + } + stream.pos = pos; + } + break; + default: + fail('invalid format', 'bitmap'); + } + var ihdr = new Uint8Array([ + width >> 24 & 255, + width >> 16 & 255, + width >> 8 & 255, + width & 255, + height >> 24 & 255, + height >> 16 & 255, + height >> 8 & 255, + height & 255, + 8, + colorType, + 0, + 0, + 0 + ]); + var len = literals.length; + var maxBlockLength = 65535; + var idat = new Uint8Array(2 + len + Math.ceil(len / maxBlockLength) * 5 + 4); + var pi = 0; + idat[pi++] = 120; + idat[pi++] = 156; + var pos = 0; + while (len > maxBlockLength) { + idat[pi++] = 0; + idat[pi++] = 255; + idat[pi++] = 255; + idat[pi++] = 0; + idat[pi++] = 0; + idat.set(literals.subarray(pos, pos + maxBlockLength), pi); + pi += maxBlockLength; + pos += maxBlockLength; + len -= maxBlockLength; + } + idat[pi++] = 1; + idat[pi++] = len & 255; + idat[pi++] = len >> 8 & 255; + idat[pi++] = ~len & 65535 & 255; + idat[pi++] = (~len & 65535) >> 8 & 255; + idat.set(literals.subarray(pos), pi); + pi += literals.length - pos; + var adler = adler32(literals, 0, literals.length); + idat[pi++] = adler >> 24 & 255; + idat[pi++] = adler >> 16 & 255; + idat[pi++] = adler >> 8 & 255; + idat[pi++] = adler & 255; + var chunks = [ + new Uint8Array([ + 137, + 80, + 78, + 71, + 13, + 10, + 26, + 10 + ]), + createPngChunk('IHDR', ihdr), + plte, + trns, + createPngChunk('IDAT', idat), + createPngChunk('IEND', '') + ]; + return { + type: 'image', + id: tag.id, + width: width, + height: height, + mimeType: 'image/png', + data: new Blob(chunks, { + type: 'image/png' + }) + }; +} +function defineButton(tag, dictionary) { + var characters = tag.characters; + var states = { + up: {}, + over: {}, + down: {}, + hitTest: {} + }; + var i = 0, character; + while (character = characters[i++]) { + if (character.eob) + break; + var characterItem = dictionary[character.symbolId]; + var entry = { + symbolId: characterItem.id, + hasMatrix: !(!character.matrix), + matrix: character.matrix + }; + if (character.stateUp) + states.up[character.depth] = entry; + if (character.stateOver) + states.over[character.depth] = entry; + if (character.stateDown) + states.down[character.depth] = entry; + if (character.stateHitTest) + states.hitTest[character.depth] = entry; + } + var button = { + type: 'button', + id: tag.id, + buttonActions: tag.buttonActions, + states: states + }; + return button; +} +var nextFontId = 1; +function maxPower2(num) { + var maxPower = 0; + var val = num; + while (val >= 2) { + val /= 2; + ++maxPower; + } + return pow(2, maxPower); +} +function toString16(val) { + return fromCharCode(val >> 8 & 255, val & 255); +} +function toString32(val) { + return toString16(val >> 16) + toString16(val); +} +function defineFont(tag, dictionary) { + var tables = {}; + var codes = []; + var glyphIndex = {}; + var ranges = []; + var glyphs = tag.glyphs; + var glyphCount = glyphs.length; + if (tag.codes) { + codes = codes.concat(tag.codes); + for (var i = 0, code; code = codes[i]; ++i) + glyphIndex[code] = i; + codes.sort(function (a, b) { + return a - b; + }); + var i = 0; + var code; + while (code = codes[i++]) { + var start = code; + var end = start; + var indices = [ + i - 1 + ]; + while ((code = codes[i]) && end + 1 === code) { + ++end; + indices.push(i); + ++i; + } + ranges.push([ + start, + end, + indices + ]); + } + } else { + var indices = []; + var UAC_OFFSET = 57344; + for (var i = 0; i < glyphCount; i++) { + var code = UAC_OFFSET + i; + codes.push(code); + glyphIndex[code] = i; + indices.push(i); + } + ranges.push([ + UAC_OFFSET, + UAC_OFFSET + glyphCount - 1, + indices + ]); + } + var resolution = tag.resolution || 1; + var ascent = Math.ceil(tag.ascent / resolution) || 1024; + var descent = -Math.ceil(tag.descent / resolution) | 0; + var leading = tag.leading / resolution | 0; + tables['OS/2'] = '\0\x01\0\0' + toString16(tag.bold ? 700 : 400) + '\0\x05' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0\0\0\0\0\0\0\0\0' + '\0\0\0\0' + '\0\0\0\0' + '\0\0\0\0' + '\0\0\0\0' + 'ALF ' + toString16((tag.italic ? 1 : 0) | (tag.bold ? 32 : 0)) + toString16(codes[0]) + toString16(codes[codes.length - 1]) + toString16(ascent) + toString16(descent) + toString16(leading) + toString16(ascent) + toString16(-descent) + '\0\0\0\0' + '\0\0\0\0'; + ; + var startCount = ''; + var endCount = ''; + var idDelta = ''; + var idRangeOffset = ''; + var i = 0; + var range; + while (range = ranges[i++]) { + var start = range[0]; + var end = range[1]; + var code = range[2][0]; + startCount += toString16(start); + endCount += toString16(end); + idDelta += toString16(code - start + 1 & 65535); + idRangeOffset += toString16(0); + } + endCount += '\xff\xff'; + startCount += '\xff\xff'; + idDelta += '\0\x01'; + idRangeOffset += '\0\0'; + var segCount = ranges.length + 1; + var searchRange = maxPower2(segCount) * 2; + var rangeShift = 2 * segCount - searchRange; + var format314 = '\0\0' + toString16(segCount * 2) + toString16(searchRange) + toString16(logE(segCount) / logE(2)) + toString16(rangeShift) + endCount + '\0\0' + startCount + idDelta + idRangeOffset; + ; + tables['cmap'] = '\0\0\0\x01\0\x03\0\x01\0\0\0\f\0\x04' + toString16(format314.length + 4) + format314; + ; + var glyf = '\0\x01\0\0\0\0\0\0\0\0\0\0\0\x001\0'; + var loca = '\0\0'; + var offset = 16; + var maxPoints = 0; + var xMins = []; + var xMaxs = []; + var yMins = []; + var yMaxs = []; + var maxContours = 0; + var i = 0; + var code; + while (code = codes[i++]) { + var glyph = glyphs[glyphIndex[code]]; + var records = glyph.records; + var numberOfContours = 1; + var endPoint = 0; + var endPtsOfContours = ''; + var flags = ''; + var xCoordinates = ''; + var yCoordinates = ''; + var x = 0; + var y = 0; + var xMin = 1024; + var xMax = -1024; + var yMin = 1024; + var yMax = -1024; + for (var j = 0, record; record = records[j]; ++j) { + if (record.type) { + if (record.isStraight) { + if (record.isGeneral) { + flags += '\x01'; + var dx = record.deltaX / resolution; + var dy = -record.deltaY / resolution; + xCoordinates += toString16(dx); + yCoordinates += toString16(dy); + x += dx; + y += dy; + } else if (record.isVertical) { + flags += '\x11'; + var dy = -record.deltaY / resolution; + yCoordinates += toString16(dy); + y += dy; + } else { + flags += '!'; + var dx = record.deltaX / resolution; + xCoordinates += toString16(dx); + x += dx; + } + } else { + flags += '\0'; + var cx = record.controlDeltaX / resolution; + var cy = -record.controlDeltaY / resolution; + xCoordinates += toString16(cx); + yCoordinates += toString16(cy); + flags += '\x01'; + var dx = record.anchorDeltaX / resolution; + var dy = -record.anchorDeltaY / resolution; + xCoordinates += toString16(dx); + yCoordinates += toString16(dy); + ++endPoint; + x += cx + dx; + y += cy + dy; + } + if (x < xMin) + xMin = x; + if (x > xMax) + xMax = x; + if (y < yMin) + yMin = y; + if (y > yMax) + yMax = y; + ++endPoint; + } else { + if (record.eos) + break; + if (record.move) { + if (endPoint) { + ++numberOfContours; + endPtsOfContours += toString16(endPoint - 1); + } + flags += '\x01'; + var moveX = record.moveX / resolution; + var moveY = -record.moveY / resolution; + var dx = moveX - x; + var dy = moveY - y; + xCoordinates += toString16(dx); + yCoordinates += toString16(dy); + x = moveX; + y = moveY; + if (endPoint > maxPoints) + maxPoints = endPoint; + if (x < xMin) + xMin = x; + if (x > xMax) + xMax = x; + if (y < yMin) + yMin = y; + if (y > yMax) + yMax = y; + ++endPoint; + } + } + } + endPtsOfContours += toString16((endPoint || 1) - 1); + if (!j) { + xMin = xMax = yMin = yMax = 0; + flags += '1'; + } + var entry = toString16(numberOfContours) + toString16(xMin) + toString16(yMin) + toString16(xMax) + toString16(yMax) + endPtsOfContours + '\0\0' + flags + xCoordinates + yCoordinates; + ; + if (entry.length & 1) + entry += '\0'; + glyf += entry; + loca += toString16(offset / 2); + offset += entry.length; + xMins.push(xMin); + xMaxs.push(xMax); + yMins.push(yMin); + yMaxs.push(yMax); + if (numberOfContours > maxContours) + maxContours = numberOfContours; + if (endPoint > maxPoints) + maxPoints = endPoint; + } + loca += toString16(offset / 2); + tables['glyf'] = glyf; + tables['head'] = '\0\x01\0\0\0\x01\0\0\0\0\0\0_\x0f<\xf5\0\v\x04\0\0\0\0\0' + toString32(Date.now()) + '\0\0\0\0' + toString32(Date.now()) + toString16(min.apply(null, xMins)) + toString16(min.apply(null, yMins)) + toString16(max.apply(null, xMaxs)) + toString16(max.apply(null, yMaxs)) + toString16((tag.italic ? 2 : 0) | (tag.bold ? 1 : 0)) + '\0\b' + '\0\x02' + '\0\0' + '\0\0'; + ; + var advance = tag.advance; + tables['hhea'] = '\0\x01\0\0' + toString16(ascent) + toString16(descent) + toString16(leading) + toString16(advance ? max.apply(null, advance) : 1024) + '\0\0' + '\0\0' + '\x03\xb8' + '\0\x01' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + toString16(glyphCount + 1); + ; + var hmtx = '\0\0\0\0'; + for (var i = 0; i < glyphCount; ++i) + hmtx += toString16(advance ? advance[i] / resolution : 1024) + '\0\0'; + tables['hmtx'] = hmtx; + if (tag.kerning) { + var kerning = tag.kerning; + var nPairs = kerning.length; + var searchRange = maxPower2(nPairs) * 2; + var kern = '\0\0\0\x01\0\0' + toString16(14 + nPairs * 6) + '\0\x01' + toString16(nPairs) + toString16(searchRange) + toString16(logE(nPairs) / logE(2)) + toString16(2 * nPairs - searchRange); + ; + var i = 0; + var record; + while (record = kerning[i++]) { + kern += toString16(glyphIndex[record.code1]) + toString16(glyphIndex[record.code2]) + toString16(record.adjustment); + ; + } + tables['kern'] = kern; + } + tables['loca'] = loca; + tables['maxp'] = '\0\x01\0\0' + toString16(glyphCount + 1) + toString16(maxPoints) + toString16(maxContours) + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0' + '\0\0'; + ; + var uniqueId = 'swf-font-' + nextFontId++; + var fontName = tag.name || uniqueId; + var psName = fontName.replace(/ /g, ''); + var strings = [ + tag.copyright || 'Original licence', + fontName, + 'Unknown', + uniqueId, + fontName, + '1.0', + psName, + 'Unknown', + 'Unknown', + 'Unknown' + ]; + var count = strings.length; + var name = '\0\0' + toString16(count) + toString16(count * 12 + 6); + var offset = 0; + var i = 0; + var str; + while (str = strings[i++]) { + name += '\0\x01\0\0\0\0' + toString16(i - 1) + toString16(str.length) + toString16(offset); + offset += str.length; + } + tables['name'] = name + strings.join(''); + tables['post'] = '\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'; + ; + var names = keys(tables); + var numTables = names.length; + var header = '\0\x01\0\0' + toString16(numTables) + '\0\x80' + '\0\x03' + '\0 '; + ; + var data = ''; + var offset = numTables * 16 + header.length; + var i = 0; + var name; + while (name = names[i++]) { + var table = tables[name]; + var length = table.length; + header += name + '\0\0\0\0' + toString32(offset) + toString32(length); + ; + while (length & 3) { + table += '\0'; + ++length; + } + data += table; + while (offset & 3) + ++offset; + offset += length; + } + var otf = header + data; + var unitPerEm = 1024; + var metrics = { + ascent: ascent / unitPerEm, + descent: -descent / unitPerEm, + leading: leading / unitPerEm + }; + return { + type: 'font', + id: tag.id, + name: fontName, + uniqueName: psName + uniqueId, + codes: codes, + metrics: metrics, + bold: tag.bold === 1, + italic: tag.italic === 1, + data: otf + }; +} +function getUint16(buff, pos) { + return buff[pos] << 8 | buff[pos + 1]; +} +function parseJpegChunks(imgDef, bytes) { + var i = 0; + var n = bytes.length; + var chunks = []; + var code; + do { + var begin = i; + while (i < n && bytes[i] !== 255) + ++i; + while (i < n && bytes[i] === 255) + ++i; + code = bytes[i++]; + if (code === 218) { + i = n; + } else if (code === 217) { + i += 2; + continue; + } else if (code < 208 || code > 216) { + var length = getUint16(bytes, i); + if (code >= 192 && code <= 195) { + imgDef.height = getUint16(bytes, i + 3); + imgDef.width = getUint16(bytes, i + 5); + } + i += length; + } + chunks.push(bytes.subarray(begin, i)); + } while (i < n); + return chunks; +} +function defineImage(tag, dictionary) { + var img = { + type: 'image', + id: tag.id, + mimeType: tag.mimeType + }; + var imgData = tag.imgData; + var chunks; + if (tag.mimeType === 'image/jpeg') { + chunks = parseJpegChunks(img, imgData); + var alphaData = tag.alphaData; + if (alphaData) { + img.mask = createInflatedStream(alphaData, img.width * img.height).bytes; + } + if (tag.incomplete) { + var tables = dictionary[0]; + var header = tables.data; + if (header && header.size) { + chunks[0] = chunks[0].subarray(2); + chunks.unshift(header.slice(0, header.size - 2)); + } + } + } else { + chunks = [ + imgData + ]; + } + img.data = new Blob(chunks, { + type: tag.mimeType + }); + return img; +} +function defineLabel(tag, dictionary) { + var records = tag.records; + var m = tag.matrix; + var cmds = [ + 'c.save()', + 'c.transform(' + [ + m.a, + m.b, + m.c, + m.d, + m.tx / 20, + m.ty / 20 + ].join(',') + ')', + 'c.scale(0.05, 0.05)' + ]; + var dependencies = []; + var x = 0; + var y = 0; + var i = 0; + var record; + var codes; + while (record = records[i++]) { + if (record.eot) + break; + if (record.hasFont) { + var font = dictionary[record.fontId]; + codes = font.codes; + cmds.push('c.font="' + record.fontHeight + 'px \'' + font.uniqueName + '\'"'); + dependencies.push(font.id); + } + if (record.hasColor) { + cmds.push('ct.setFillStyle(c,"' + rgbaObjToStr(record.color) + '")'); + cmds.push('ct.setAlpha(c)'); + } else { + cmds.push('ct.setAlpha(c,true)'); + } + if (record.hasMoveX) + x = record.moveX; + if (record.hasMoveY) + y = record.moveY; + var entries = record.entries; + var j = 0; + var entry; + while (entry = entries[j++]) { + var code = codes[entry.glyphIndex]; + var text = code >= 32 && code != 34 && code != 92 ? fromCharCode(code) : '\\u' + (code + 65536).toString(16).substring(1); + cmds.push('c.fillText("' + text + '",' + x + ',' + y + ')'); + x += entry.advance; + } + } + cmds.push('c.restore()'); + var label = { + type: 'label', + id: tag.id, + bbox: tag.bbox, + data: cmds.join('\n') + }; + if (dependencies.length) + label.require = dependencies; + return label; +} +var GRAPHICS_FILL_CLIPPED_BITMAP = 65; +var GRAPHICS_FILL_FOCAL_RADIAL_GRADIENT = 19; +var GRAPHICS_FILL_LINEAR_GRADIENT = 16; +var GRAPHICS_FILL_NONSMOOTHED_CLIPPED_BITMAP = 67; +var GRAPHICS_FILL_NONSMOOTHED_REPEATING_BITMAP = 66; +var GRAPHICS_FILL_RADIAL_GRADIENT = 18; +var GRAPHICS_FILL_REPEATING_BITMAP = 64; +var GRAPHICS_FILL_SOLID = 0; +function applySegmentToStyles(segment, styles, linePaths, fillPaths, isMorph) { + if (!segment) { + return; + } + var commands = segment.commands; + var data = segment.data; + var morphData = segment.morphData; + if (morphData) { + } + var path; + var targetSegment; + var command; + var i; + if (styles.fill0) { + path = fillPaths[styles.fill0 - 1]; + if (!(styles.fill1 || styles.line)) { + targetSegment = path.head(); + targetSegment.commands = []; + targetSegment.data = []; + targetSegment.morphData = isMorph ? [] : null; + } else { + targetSegment = path.addSegment([], [], isMorph ? [] : null); + } + var targetCommands = targetSegment.commands; + var targetData = targetSegment.data; + var targetMorphData = targetSegment.morphData; + targetCommands.push(SHAPE_MOVE_TO); + var j = data.length - 2; + targetData.push(data[j], data[j + 1]); + if (isMorph) { + targetMorphData.push(morphData[j], morphData[j + 1]); + } + for (i = commands.length; i-- > 1; j -= 2) { + command = commands[i]; + targetCommands.push(command); + targetData.push(data[j - 2], data[j - 1]); + if (isMorph) { + targetMorphData.push(morphData[j - 2], morphData[j - 1]); + } + if (command === SHAPE_CURVE_TO) { + targetData.push(data[j - 4], data[j - 3]); + if (isMorph) { + targetMorphData.push(morphData[j - 4], morphData[j - 3]); + } + j -= 2; + } + } + if (isMorph) { + } + } + if (styles.line && styles.fill1) { + path = linePaths[styles.line - 1]; + path.addSegment(commands, data, morphData); + } +} +function convertRecordsToStyledPaths(records, fillPaths, linePaths, dictionary, dependencies, recordsMorph, transferables) { + var isMorph = recordsMorph !== null; + var styles = { + fill0: 0, + fill1: 0, + line: 0 + }; + var segment = null; + var allPaths; + var defaultPath; + var numRecords = records.length - 1; + var x = 0; + var y = 0; + var morphX = 0; + var morphY = 0; + var path; + for (var i = 0, j = 0; i < numRecords; i++) { + var record = records[i]; + var morphRecord; + if (isMorph) { + morphRecord = recordsMorph[j++]; + } + if (record.type === 0) { + if (segment) { + applySegmentToStyles(segment, styles, linePaths, fillPaths, isMorph); + } + if (record.hasNewStyles) { + if (!allPaths) { + allPaths = []; + } + push.apply(allPaths, fillPaths); + fillPaths = createPathsList(record.fillStyles, false, dictionary, dependencies); + push.apply(allPaths, linePaths); + linePaths = createPathsList(record.lineStyles, true, dictionary, dependencies); + if (defaultPath) { + allPaths.push(defaultPath); + defaultPath = null; + } + styles = { + fill0: 0, + fill1: 0, + line: 0 + }; + } + if (record.hasFillStyle0) { + styles.fill0 = record.fillStyle0; + } + if (record.hasFillStyle1) { + styles.fill1 = record.fillStyle1; + } + if (record.hasLineStyle) { + styles.line = record.lineStyle; + } + if (styles.fill1) { + path = fillPaths[styles.fill1 - 1]; + } else if (styles.line) { + path = linePaths[styles.line - 1]; + } else if (styles.fill0) { + path = fillPaths[styles.fill0 - 1]; + } + if (record.move) { + x = record.moveX | 0; + y = record.moveY | 0; + } + if (path) { + segment = path.addSegment([], [], isMorph ? [] : null); + segment.commands.push(SHAPE_MOVE_TO); + segment.data.push(x, y); + if (isMorph) { + if (morphRecord.type === 0) { + morphX = morphRecord.moveX | 0; + morphY = morphRecord.moveY | 0; + } else { + morphX = x; + morphY = y; + j--; + } + segment.morphData.push(morphX, morphY); + } + } + } else { + if (!segment) { + if (!defaultPath) { + var style = { + color: { + red: 0, + green: 0, + blue: 0, + alpha: 255 + }, + width: 20 + }; + defaultPath = new SegmentedPath(null, processStyle(style, true)); + } + segment = defaultPath.addSegment([], [], isMorph ? [] : null); + segment.commands.push(SHAPE_MOVE_TO); + segment.data.push(x, y); + if (isMorph) { + segment.morphData.push(morphX, morphY); + } + } + if (isMorph) { + while (morphRecord && morphRecord.type === 0) { + morphRecord = recordsMorph[j++]; + } + if (!morphRecord) { + morphRecord = record; + } + } + if (record.isStraight && (!isMorph || morphRecord.isStraight)) { + x += record.deltaX | 0; + y += record.deltaY | 0; + segment.commands.push(SHAPE_LINE_TO); + segment.data.push(x, y); + if (isMorph) { + morphX += morphRecord.deltaX | 0; + morphY += morphRecord.deltaY | 0; + segment.morphData.push(morphX, morphY); + } + } else { + var cx, cy; + var deltaX, deltaY; + if (!record.isStraight) { + cx = x + record.controlDeltaX | 0; + cy = y + record.controlDeltaY | 0; + x = cx + record.anchorDeltaX | 0; + y = cy + record.anchorDeltaY | 0; + } else { + deltaX = record.deltaX | 0; + deltaY = record.deltaY | 0; + cx = x + (deltaX >> 1); + cy = y + (deltaY >> 1); + x += deltaX; + y += deltaY; + } + segment.commands.push(SHAPE_CURVE_TO); + segment.data.push(cx, cy, x, y); + if (isMorph) { + if (!morphRecord.isStraight) { + cx = morphX + morphRecord.controlDeltaX | 0; + cy = morphY + morphRecord.controlDeltaY | 0; + morphX = cx + morphRecord.anchorDeltaX | 0; + morphY = cy + morphRecord.anchorDeltaY | 0; + } else { + deltaX = morphRecord.deltaX | 0; + deltaY = morphRecord.deltaY | 0; + cx = morphX + (deltaX >> 1); + cy = morphY + (deltaY >> 1); + morphX += deltaX; + morphY += deltaY; + } + segment.morphData.push(cx, cy, morphX, morphY); + } + } + } + } + applySegmentToStyles(segment, styles, linePaths, fillPaths, isMorph); + if (allPaths) { + push.apply(allPaths, fillPaths); + } else { + allPaths = fillPaths; + } + push.apply(allPaths, linePaths); + if (defaultPath) { + allPaths.push(defaultPath); + } + var removeCount = 0; + for (i = 0; i < allPaths.length; i++) { + path = allPaths[i]; + if (!path.head()) { + removeCount++; + continue; + } + allPaths[i - removeCount] = segmentedPathToShapePath(path, isMorph, transferables); + } + allPaths.length -= removeCount; + return allPaths; +} +function segmentedPathToShapePath(path, isMorph, transferables) { + var start = path.head(); + var end = start; + var finalRoot = null; + var finalHead = null; + var skippedMoves = 0; + var current = start.prev; + while (start) { + while (current) { + if (path.segmentsConnect(current, start)) { + if (current.next !== start) { + path.removeSegment(current); + path.insertSegment(current, start); + } + start = current; + current = start.prev; + skippedMoves++; + continue; + } + if (path.segmentsConnect(end, current)) { + path.removeSegment(current); + end.next = current; + current = current.prev; + end.next.prev = end; + end.next.next = null; + end = end.next; + skippedMoves++; + continue; + } + current = current.prev; + } + current = start.prev; + if (!finalRoot) { + finalRoot = start; + finalHead = end; + } else { + finalHead.next = start; + start.prev = finalHead; + finalHead = end; + finalHead.next = null; + } + if (!current) { + break; + } + start = end = current; + current = start.prev; + } + var totalCommandsLength = -skippedMoves; + var totalDataLength = -skippedMoves << 1; + current = finalRoot; + while (current) { + totalCommandsLength += current.commands.length; + totalDataLength += current.data.length; + current = current.next; + } + var shape = new ShapePath(path.fillStyle, path.lineStyle, totalCommandsLength, totalDataLength, isMorph, transferables); + var allCommands = shape.commands; + var allData = shape.data; + var allMorphData = shape.morphData; + var commandsIndex = 0; + var dataIndex = 0; + current = finalRoot; + while (current) { + var commands = current.commands; + var data = current.data; + var morphData = current.morphData; + var offset = +(data[0] === allData[dataIndex - 2] && data[1] === allData[dataIndex - 1]); + for (var i = offset; i < commands.length; i++, commandsIndex++) { + allCommands[commandsIndex] = commands[i]; + } + for (i = offset << 1; i < data.length; i++, dataIndex++) { + allData[dataIndex] = data[i]; + if (isMorph) { + allMorphData[dataIndex] = morphData[i]; + } + } + current = current.next; + } + return shape; +} +var CAPS_STYLE_TYPES = [ + 'round', + 'none', + 'square' + ]; +var JOIN_STYLE_TYPES = [ + 'round', + 'bevel', + 'miter' + ]; +function processStyle(style, isLineStyle, dictionary, dependencies) { + if (isLineStyle) { + style.lineCap = CAPS_STYLE_TYPES[style.endCapStyle | 0]; + style.lineJoin = JOIN_STYLE_TYPES[style.joinStyle | 0]; + style.miterLimit = (style.miterLimitFactor || 1.5) * 2; + if (!style.color && style.hasFill) { + var fillStyle = processStyle(style.fillStyle, false, dictionary, dependencies); + style.style = fillStyle.style; + style.type = fillStyle.type; + style.transform = fillStyle.transform; + style.records = fillStyle.records; + style.focalPoint = fillStyle.focalPoint; + style.bitmapId = fillStyle.bitmapId; + style.repeat = fillStyle.repeat; + style.fillStyle = null; + return style; + } + } + var color; + if (style.type === undefined || style.type === GRAPHICS_FILL_SOLID) { + color = style.color; + style.style = 'rgba(' + color.red + ',' + color.green + ',' + color.blue + ',' + color.alpha / 255 + ')'; + style.color = null; + return style; + } + var scale; + switch (style.type) { + case GRAPHICS_FILL_LINEAR_GRADIENT: + case GRAPHICS_FILL_RADIAL_GRADIENT: + case GRAPHICS_FILL_FOCAL_RADIAL_GRADIENT: + scale = 819.2; + break; + case GRAPHICS_FILL_REPEATING_BITMAP: + case GRAPHICS_FILL_CLIPPED_BITMAP: + case GRAPHICS_FILL_NONSMOOTHED_REPEATING_BITMAP: + case GRAPHICS_FILL_NONSMOOTHED_CLIPPED_BITMAP: + if (dictionary[style.bitmapId]) { + dependencies.push(dictionary[style.bitmapId].id); + scale = 0.05; + } + break; + default: + fail('invalid fill style', 'shape'); + } + if (!style.matrix) { + return style; + } + var matrix = style.matrix; + style.transform = { + a: matrix.a * scale, + b: matrix.b * scale, + c: matrix.c * scale, + d: matrix.d * scale, + e: matrix.tx, + f: matrix.ty + }; + style.matrix = null; + return style; +} +function createPathsList(styles, isLineStyle, dictionary, dependencies) { + var paths = []; + for (var i = 0; i < styles.length; i++) { + var style = processStyle(styles[i], isLineStyle, dictionary, dependencies); + if (!isLineStyle) { + paths[i] = new SegmentedPath(style, null); + } else { + paths[i] = new SegmentedPath(null, style); + } + } + return paths; +} +function defineShape(tag, dictionary) { + var dependencies = []; + var transferables = []; + var fillPaths = createPathsList(tag.fillStyles, false, dictionary, dependencies); + var linePaths = createPathsList(tag.lineStyles, true, dictionary, dependencies); + var paths = convertRecordsToStyledPaths(tag.records, fillPaths, linePaths, dictionary, dependencies, tag.recordsMorph || null, transferables); + if (tag.bboxMorph) { + var mbox = tag.bboxMorph; + extendBoundsByPoint(tag.bbox, mbox.xMin, mbox.yMin); + extendBoundsByPoint(tag.bbox, mbox.xMax, mbox.yMax); + mbox = tag.strokeBboxMorph; + if (mbox) { + extendBoundsByPoint(tag.strokeBbox, mbox.xMin, mbox.yMin); + extendBoundsByPoint(tag.strokeBbox, mbox.xMax, mbox.yMax); + } + } + return { + type: 'shape', + id: tag.id, + strokeBbox: tag.strokeBbox, + strokeBboxMorph: tag.strokeBboxMorph, + bbox: tag.bbox, + bboxMorph: tag.bboxMorph, + isMorph: tag.isMorph, + paths: paths, + require: dependencies.length ? dependencies : null, + transferables: transferables + }; +} +function logShape(paths, bbox) { + var output = '{"bounds":' + JSON.stringify(bbox) + ',"paths":[' + paths.map(function (path) { + return path.serialize(); + }).join() + ']}'; + console.log(output); +} +function SegmentedPath(fillStyle, lineStyle) { + this.fillStyle = fillStyle; + this.lineStyle = lineStyle; + this._head = null; +} +SegmentedPath.prototype = { + addSegment: function (commands, data, morphData) { + var segment = { + commands: commands, + data: data, + morphData: morphData, + prev: this._head, + next: null + }; + if (this._head) { + this._head.next = segment; + } + this._head = segment; + return segment; + }, + removeSegment: function (segment) { + if (segment.prev) { + segment.prev.next = segment.next; + } + if (segment.next) { + segment.next.prev = segment.prev; + } + }, + insertSegment: function (segment, next) { + var prev = next.prev; + segment.prev = prev; + segment.next = next; + if (prev) { + prev.next = segment; + } + next.prev = segment; + }, + head: function () { + return this._head; + }, + segmentsConnect: function (first, second) { + var firstLength = first.data.length; + return first.data[firstLength - 2] === second.data[0] && first.data[firstLength - 1] === second.data[1]; + } +}; +var SHAPE_MOVE_TO = 1; +var SHAPE_LINE_TO = 2; +var SHAPE_CURVE_TO = 3; +var SHAPE_WIDE_MOVE_TO = 4; +var SHAPE_WIDE_LINE_TO = 5; +var SHAPE_CUBIC_CURVE_TO = 6; +var SHAPE_CIRCLE = 7; +var SHAPE_ELLIPSE = 8; +function ShapePath(fillStyle, lineStyle, commandsCount, dataLength, isMorph, transferables) { + this.fillStyle = fillStyle; + this.lineStyle = lineStyle; + if (commandsCount) { + this.commands = new Uint8Array(commandsCount); + this.data = new Int32Array(dataLength); + this.morphData = isMorph ? new Int32Array(dataLength) : null; + } else { + this.commands = []; + this.data = []; + } + this.bounds = null; + this.strokeBounds = null; + this.isMorph = !(!isMorph); + this.fullyInitialized = false; + if (inWorker) { + this.buffers = [ + this.commands.buffer, + this.data.buffer + ]; + transferables.push(this.commands.buffer, this.data.buffer); + if (isMorph) { + this.buffers.push(this.morphData.buffer); + transferables.push(this.morphData.buffer); + } + } else { + this.buffers = null; + } +} +ShapePath.prototype = { + get isEmpty() { + return this.commands.length === 0; + }, + moveTo: function (x, y) { + if (this.commands[this.commands.length - 1] === SHAPE_MOVE_TO) { + this.data[this.data.length - 2] = x; + this.data[this.data.length - 1] = y; + return; + } + this.commands.push(SHAPE_MOVE_TO); + this.data.push(x, y); + }, + lineTo: function (x, y) { + this.commands.push(SHAPE_LINE_TO); + this.data.push(x, y); + }, + curveTo: function (controlX, controlY, anchorX, anchorY) { + this.commands.push(SHAPE_CURVE_TO); + this.data.push(controlX, controlY, anchorX, anchorY); + }, + cubicCurveTo: function (control1X, control1Y, control2X, control2Y, anchorX, anchorY) { + this.commands.push(SHAPE_CUBIC_CURVE_TO); + this.data.push(control1X, control1Y, control2X, control2Y, anchorX, anchorY); + }, + rect: function (x, y, w, h) { + var x2 = x + w; + var y2 = y + h; + this.commands.push(SHAPE_MOVE_TO, SHAPE_LINE_TO, SHAPE_LINE_TO, SHAPE_LINE_TO, SHAPE_LINE_TO); + this.data.push(x, y, x2, y, x2, y2, x, y2, x, y); + }, + circle: function (x, y, radius) { + this.commands.push(SHAPE_CIRCLE); + this.data.push(x, y, radius); + }, + ellipse: function (x, y, radiusX, radiusY) { + this.commands.push(SHAPE_ELLIPSE); + this.data.push(x, y, radiusX, radiusY); + }, + draw: function (ctx, clip, ratio, colorTransform) { + if (clip && !this.fillStyle) { + return; + } + ctx.beginPath(); + var commands = this.commands; + var data = this.data; + var morphData = this.morphData; + var formOpen = false; + var formOpenX = 0; + var formOpenY = 0; + if (!this.isMorph) { + for (var j = 0, k = 0; j < commands.length; j++) { + switch (commands[j]) { + case SHAPE_MOVE_TO: + formOpen = true; + formOpenX = data[k++] / 20; + formOpenY = data[k++] / 20; + ctx.moveTo(formOpenX, formOpenY); + break; + case SHAPE_WIDE_MOVE_TO: + ctx.moveTo(data[k++] / 20, data[k++] / 20); + k += 2; + break; + case SHAPE_LINE_TO: + ctx.lineTo(data[k++] / 20, data[k++] / 20); + break; + case SHAPE_WIDE_LINE_TO: + ctx.lineTo(data[k++] / 20, data[k++] / 20); + k += 2; + break; + case SHAPE_CURVE_TO: + ctx.quadraticCurveTo(data[k++] / 20, data[k++] / 20, data[k++] / 20, data[k++] / 20); + break; + case SHAPE_CUBIC_CURVE_TO: + ctx.bezierCurveTo(data[k++] / 20, data[k++] / 20, data[k++] / 20, data[k++] / 20, data[k++] / 20, data[k++] / 20); + break; + case SHAPE_CIRCLE: + if (formOpen) { + ctx.lineTo(formOpenX, formOpenY); + formOpen = false; + } + ctx.moveTo((data[k] + data[k + 2]) / 20, data[k + 1] / 20); + ctx.arc(data[k++] / 20, data[k++] / 20, data[k++] / 20, 0, Math.PI * 2, false); + break; + case SHAPE_ELLIPSE: + if (formOpen) { + ctx.lineTo(formOpenX, formOpenY); + formOpen = false; + } + var x = data[k++]; + var y = data[k++]; + var rX = data[k++]; + var rY = data[k++]; + var radius; + if (rX !== rY) { + ctx.save(); + var ellipseScale; + if (rX > rY) { + ellipseScale = rX / rY; + radius = rY; + x /= ellipseScale; + ctx.scale(ellipseScale, 1); + } else { + ellipseScale = rY / rX; + radius = rX; + y /= ellipseScale; + ctx.scale(1, ellipseScale); + } + } + ctx.moveTo((x + radius) / 20, y / 20); + ctx.arc(x / 20, y / 20, radius / 20, 0, Math.PI * 2, false); + if (rX !== rY) { + ctx.restore(); + } + break; + default: + if (commands[j] === 0 && j === commands.length - 1) { + break; + } + console.warn('Unknown drawing command encountered: ' + commands[j]); + } + } + } else { + for (var j = 0, k = 0; j < commands.length; j++) { + switch (commands[j]) { + case SHAPE_MOVE_TO: + ctx.moveTo(morph(data[k] / 20, morphData[k++] / 20, ratio), morph(data[k] / 20, morphData[k++] / 20, ratio)); + break; + case SHAPE_LINE_TO: + ctx.lineTo(morph(data[k] / 20, morphData[k++] / 20, ratio), morph(data[k] / 20, morphData[k++] / 20, ratio)); + break; + case SHAPE_CURVE_TO: + ctx.quadraticCurveTo(morph(data[k] / 20, morphData[k++] / 20, ratio), morph(data[k] / 20, morphData[k++] / 20, ratio), morph(data[k] / 20, morphData[k++] / 20, ratio), morph(data[k] / 20, morphData[k++] / 20, ratio)); + break; + default: + console.warn('Drawing command not supported for morph shapes: ' + commands[j]); + } + } + } + if (!clip) { + var fillStyle = this.fillStyle; + if (fillStyle) { + colorTransform.setFillStyle(ctx, fillStyle.style); + ctx.imageSmoothingEnabled = ctx.mozImageSmoothingEnabled = fillStyle.smooth; + var m = fillStyle.transform; + ctx.save(); + colorTransform.setAlpha(ctx); + if (m) { + ctx.transform(m.a, m.b, m.c, m.d, m.e / 20, m.f / 20); + } + ctx.fill(); + ctx.restore(); + } + var lineStyle = this.lineStyle; + if (lineStyle) { + colorTransform.setStrokeStyle(ctx, lineStyle.style); + ctx.save(); + colorTransform.setAlpha(ctx); + ctx.lineWidth = Math.max(lineStyle.width / 20, 1); + ctx.lineCap = lineStyle.lineCap; + ctx.lineJoin = lineStyle.lineJoin; + ctx.miterLimit = lineStyle.miterLimit; + ctx.stroke(); + ctx.restore(); + } + } else { + ctx.fill(); + } + ctx.closePath(); + }, + isPointInPath: function (x, y) { + if (!(this.fillStyle || this.lineStyle)) { + return false; + } + var bounds = this.strokeBounds || this.bounds || this._calculateBounds(); + if (x < bounds.xMin || x > bounds.xMax || y < bounds.yMin || y > bounds.yMax) { + return false; + } + if (this.fillStyle && this.isPointInFill(x, y)) { + return true; + } + return this.lineStyle && this.lineStyle.width !== undefined && this.isPointInStroke(x, y); + }, + isPointInFill: function (x, y) { + var commands = this.commands; + var data = this.data; + var length = commands.length; + var inside = false; + var fromX = 0; + var fromY = 0; + var toX = 0; + var toY = 0; + var localX; + var localY; + var cpX; + var cpY; + var rX; + var rY; + var formOpen = false; + var formOpenX = 0; + var formOpenY = 0; + for (var commandIndex = 0, dataIndex = 0; commandIndex < length; commandIndex++) { + switch (commands[commandIndex]) { + case SHAPE_WIDE_MOVE_TO: + dataIndex += 2; + case SHAPE_MOVE_TO: + toX = data[dataIndex++]; + toY = data[dataIndex++]; + if (formOpen && intersectsLine(x, y, fromX, fromY, formOpenX, formOpenY)) { + inside = !inside; + } + formOpen = true; + formOpenX = toX; + formOpenY = toY; + break; + case SHAPE_WIDE_LINE_TO: + dataIndex += 2; + case SHAPE_LINE_TO: + toX = data[dataIndex++]; + toY = data[dataIndex++]; + if (intersectsLine(x, y, fromX, fromY, toX, toY)) { + inside = !inside; + } + break; + case SHAPE_CURVE_TO: + cpX = data[dataIndex++]; + cpY = data[dataIndex++]; + toX = data[dataIndex++]; + toY = data[dataIndex++]; + if (cpY > y === fromY > y && toY > y === fromY > y) { + break; + } + if (fromX >= x && cpX >= x && toX >= x) { + inside = !inside; + break; + } + var a = fromY - 2 * cpY + toY; + var c = fromY - y; + var b = 2 * (cpY - fromY); + var d = b * b - 4 * a * c; + if (d < 0) { + break; + } + d = Math.sqrt(d); + a = 1 / (a + a); + var t1 = (d - b) * a; + var t2 = (-b - d) * a; + if (t1 >= 0 && t1 <= 1 && quadraticBezier(fromX, cpX, toX, t1) > x) { + inside = !inside; + } + if (t2 >= 0 && t2 <= 1 && quadraticBezier(fromX, cpX, toX, t2) > x) { + inside = !inside; + } + break; + case SHAPE_CUBIC_CURVE_TO: + cpX = data[dataIndex++]; + cpY = data[dataIndex++]; + var cp2X = data[dataIndex++]; + var cp2Y = data[dataIndex++]; + toX = data[dataIndex++]; + toY = data[dataIndex++]; + if (cpY > y === fromY > y && cp2Y > y === fromY > y && toY > y === fromY > y) { + break; + } + if (fromX >= x && cpX >= x && cp2X >= x && toX >= x) { + inside = !inside; + break; + } + var roots = cubicXAtY(fromX, fromY, cpX, cpY, cp2X, cp2Y, toX, toY, y); + for (var i = roots.length; i--;) { + if (roots[i] >= x) { + inside = !inside; + } + } + break; + case SHAPE_CIRCLE: + toX = data[dataIndex++]; + toY = data[dataIndex++]; + var r = data[dataIndex++]; + localX = x - toX; + localY = y - toY; + if (localX * localX + localY * localY < r * r) { + inside = !inside; + } + toX += r; + break; + case SHAPE_ELLIPSE: + cpX = data[dataIndex++]; + cpY = data[dataIndex++]; + rX = data[dataIndex++]; + rY = data[dataIndex++]; + localX = x - cpX; + localY = y - cpY; + if (localX * localX / (rX * rX) + localY * localY / (rY * rY) <= 1) { + inside = !inside; + } + toX = cpX + rX; + toY = cpY; + break; + default: + if (!inWorker) { + console.warn('Drawing command not handled in isPointInPath: ' + commands[commandIndex]); + } + } + fromX = toX; + fromY = toY; + } + if (formOpen && intersectsLine(x, y, fromX, fromY, formOpenX, formOpenY)) { + inside = !inside; + } + return inside; + }, + isPointInStroke: function (x, y) { + var commands = this.commands; + var data = this.data; + var length = commands.length; + var width = this.lineStyle.width; + var halfWidth = width / 2; + var halfWidthSq = halfWidth * halfWidth; + var minX = x - halfWidth; + var maxX = x + halfWidth; + var minY = y - halfWidth; + var maxY = y + halfWidth; + var fromX = 0; + var fromY = 0; + var toX = 0; + var toY = 0; + var localX; + var localY; + var cpX; + var cpY; + var rX; + var rY; + var curveX; + var curveY; + var t; + for (var commandIndex = 0, dataIndex = 0; commandIndex < length; commandIndex++) { + switch (commands[commandIndex]) { + case SHAPE_WIDE_MOVE_TO: + dataIndex += 2; + case SHAPE_MOVE_TO: + toX = data[dataIndex++]; + toY = data[dataIndex++]; + break; + case SHAPE_WIDE_LINE_TO: + dataIndex += 2; + case SHAPE_LINE_TO: + toX = data[dataIndex++]; + toY = data[dataIndex++]; + if (fromX === toX && fromY === toY) { + break; + } + if (maxX < fromX && maxX < toX || minX > fromX && minX > toX || maxY < fromY && maxY < toY || minY > fromY && minY > toY) { + break; + } + if (toX === fromX || toY === fromY) { + return true; + } + t = ((x - fromX) * (toX - fromX) + (y - fromY) * (toY - fromY)) / distanceSq(fromX, fromY, toX, toY); + if (t < 0) { + if (distanceSq(x, y, fromX, fromY) <= halfWidthSq) { + return true; + } + break; + } + if (t > 1) { + if (distanceSq(x, y, toX, toY) <= halfWidthSq) { + return true; + } + break; + } + if (distanceSq(x, y, fromX + t * (toX - fromX), fromY + t * (toY - fromY)) <= halfWidthSq) { + return true; + } + break; + case SHAPE_CURVE_TO: + cpX = data[dataIndex++]; + cpY = data[dataIndex++]; + toX = data[dataIndex++]; + toY = data[dataIndex++]; + var extremeX = quadraticBezierExtreme(fromX, cpX, toX); + if (maxX < fromX && maxX < extremeX && maxX < toX || minX > fromX && minX > extremeX && minX > toX) { + break; + } + var extremeY = quadraticBezierExtreme(fromY, cpY, toY); + if (maxY < fromY && maxY < extremeY && maxY < toY || minY > fromY && minY > extremeY && minY > toY) { + break; + } + for (t = 0; t < 1; t += 0.02) { + curveX = quadraticBezier(fromX, cpX, toX, t); + if (curveX < minX || curveX > maxX) { + continue; + } + curveY = quadraticBezier(fromY, cpY, toY, t); + if (curveY < minY || curveY > maxY) { + continue; + } + if ((x - curveX) * (x - curveX) + (y - curveY) * (y - curveY) < halfWidthSq) { + return true; + } + } + break; + case SHAPE_CUBIC_CURVE_TO: + cpX = data[dataIndex++]; + cpY = data[dataIndex++]; + var cp2X = data[dataIndex++]; + var cp2Y = data[dataIndex++]; + toX = data[dataIndex++]; + toY = data[dataIndex++]; + var extremesX = cubicBezierExtremes(fromX, cpX, cp2X, toX); + while (extremesX.length < 2) { + extremesX.push(toX); + } + if (maxX < fromX && maxX < toX && maxX < extremesX[0] && maxX < extremesX[1] || minX > fromX && minX > toX && minX > extremesX[0] && minX > extremesX[1]) { + break; + } + var extremesY = cubicBezierExtremes(fromY, cpY, cp2Y, toY); + while (extremesY.length < 2) { + extremesY.push(toY); + } + if (maxY < fromY && maxY < toY && maxY < extremesY[0] && maxY < extremesY[1] || minY > fromY && minY > toY && minY > extremesY[0] && minY > extremesY[1]) { + break; + } + for (t = 0; t < 1; t += 0.02) { + curveX = cubicBezier(fromX, cpX, cp2X, toX, t); + if (curveX < minX || curveX > maxX) { + continue; + } + curveY = cubicBezier(fromY, cpY, cp2Y, toY, t); + if (curveY < minY || curveY > maxY) { + continue; + } + if ((x - curveX) * (x - curveX) + (y - curveY) * (y - curveY) < halfWidthSq) { + return true; + } + } + break; + case SHAPE_CIRCLE: + cpX = data[dataIndex++]; + cpY = data[dataIndex++]; + var r = data[dataIndex++]; + toX = cpX + r; + toY = cpY; + if (maxX < cpX - r || minX > cpX + r || maxY < cpY - r || minY > cpY + r) { + break; + } + localX = x - cpX; + localY = y - cpY; + var rMin = r - halfWidth; + var rMax = r + halfWidth; + var distSq = localX * localX + localY * localY; + if (distSq >= rMin * rMin && distSq <= rMax * rMax) { + return true; + } + break; + case SHAPE_ELLIPSE: + cpX = data[dataIndex++]; + cpY = data[dataIndex++]; + rX = data[dataIndex++]; + rY = data[dataIndex++]; + toX = cpX + rX; + toY = cpY; + localX = Math.abs(x - cpX); + localY = Math.abs(y - cpY); + localX -= halfWidth; + localY -= halfWidth; + if (localX * localX / (rX * rX) + localY * localY / (rY * rY) > 1) { + break; + } + localX += width; + localY += width; + if (localX * localX / (rX * rX) + localY * localY / (rY * rY) > 1) { + return true; + } + break; + default: + if (!inWorker) { + console.warn('Drawing command not handled in isPointInPath: ' + commands[commandIndex]); + } + } + fromX = toX; + fromY = toY; + } + return false; + }, + getBounds: function (includeStroke) { + var bounds = includeStroke ? this.strokeBounds : this.bounds; + if (!bounds) { + this._calculateBounds(); + bounds = includeStroke ? this.strokeBounds : this.bounds; + } + return bounds; + }, + _calculateBounds: function () { + var commands = this.commands; + var data = this.data; + var length = commands.length; + var bounds; + if (commands[0] === SHAPE_MOVE_TO || commands[0] > SHAPE_CUBIC_CURVE_TO) { + bounds = { + xMin: data[0], + yMin: data[1] + }; + } else { + bounds = { + xMin: 0, + yMin: 0 + }; + } + bounds.xMax = bounds.xMin; + bounds.yMax = bounds.yMin; + var fromX = bounds.xMin; + var fromY = bounds.yMin; + for (var commandIndex = 0, dataIndex = 0; commandIndex < length; commandIndex++) { + var toX; + var toY; + var cpX; + var cpY; + switch (commands[commandIndex]) { + case SHAPE_WIDE_MOVE_TO: + dataIndex += 2; + case SHAPE_MOVE_TO: + toX = data[dataIndex++]; + toY = data[dataIndex++]; + extendBoundsByPoint(bounds, toX, toY); + break; + case SHAPE_WIDE_LINE_TO: + dataIndex += 2; + case SHAPE_LINE_TO: + toX = data[dataIndex++]; + toY = data[dataIndex++]; + extendBoundsByPoint(bounds, toX, toY); + break; + case SHAPE_CURVE_TO: + cpX = data[dataIndex++]; + cpY = data[dataIndex++]; + toX = data[dataIndex++]; + toY = data[dataIndex++]; + extendBoundsByPoint(bounds, toX, toY); + if (cpX < fromX || cpX > toX) { + extendBoundsByX(bounds, quadraticBezierExtreme(fromX, cpX, toX)); + } + if (cpY < fromY || cpY > toY) { + extendBoundsByY(bounds, quadraticBezierExtreme(fromY, cpY, toY)); + } + break; + case SHAPE_CUBIC_CURVE_TO: + cpX = data[dataIndex++]; + cpY = data[dataIndex++]; + var cp2X = data[dataIndex++]; + var cp2Y = data[dataIndex++]; + toX = data[dataIndex++]; + toY = data[dataIndex++]; + extendBoundsByPoint(bounds, toX, toY); + var extremes; + var i; + if (cpX < fromX || cp2X < fromX || cpX > toX || cp2X > toX) { + extremes = cubicBezierExtremes(fromX, cpX, cp2X, toX); + for (i = extremes.length; i--;) { + extendBoundsByX(bounds, extremes[i]); + } + } + if (cpY < fromY || cp2Y < fromY || cpY > toY || cp2Y > toY) { + extremes = cubicBezierExtremes(fromY, cpY, cp2Y, toY); + for (i = extremes.length; i--;) { + extendBoundsByY(bounds, extremes[i]); + } + } + break; + case SHAPE_CIRCLE: + toX = data[dataIndex++]; + toY = data[dataIndex++]; + var radius = data[dataIndex++]; + extendBoundsByPoint(bounds, toX - radius, toY - radius); + extendBoundsByPoint(bounds, toX + radius, toY + radius); + toX += radius; + break; + case SHAPE_ELLIPSE: + toX = data[dataIndex++]; + toY = data[dataIndex++]; + var radiusX = data[dataIndex++]; + var radiusY = data[dataIndex++]; + extendBoundsByPoint(bounds, toX - radiusX, toY - radiusY); + extendBoundsByPoint(bounds, toX + radiusX, toY + radiusY); + toX += radiusX; + break; + default: + if (!inWorker) { + console.warn('Drawing command not handled in bounds calculation: ' + commands[commandIndex]); + } + } + fromX = toX; + fromY = toY; + } + this.bounds = bounds; + if (this.lineStyle) { + var halfLineWidth = this.lineStyle.width / 2; + this.strokeBounds = { + xMin: bounds.xMin - halfLineWidth, + yMin: bounds.yMin - halfLineWidth, + xMax: bounds.xMax + halfLineWidth, + yMax: bounds.yMax + halfLineWidth + }; + return this.strokeBounds; + } else { + this.strokeBounds = bounds; + } + return bounds; + }, + serialize: function () { + var output = '{'; + if (this.fillStyle) { + output += '"fill":' + JSON.stringify(this.fillStyle) + ','; + } + if (this.lineStyle) { + output += '"stroke":' + JSON.stringify(this.lineStyle) + ','; + } + output += '"commands":[' + Array.apply([], this.commands).join() + '],'; + output += '"data":[' + Array.apply([], this.data).join() + ']'; + return output + '}'; + } +}; +ShapePath.fromPlainObject = function (obj) { + var path = new ShapePath(obj.fill || null, obj.stroke || null); + path.commands = new Uint8Array(obj.commands); + path.data = new Int32Array(obj.data); + if (!inWorker) { + finishShapePath(path); + } + return path; +}; +function distanceSq(x1, y1, x2, y2) { + var dX = x2 - x1; + var dY = y2 - y1; + return dX * dX + dY * dY; +} +function intersectsLine(x, y, x1, y1, x2, y2) { + return y2 > y !== y1 > y && x < (x1 - x2) * (y - y2) / (y1 - y2) + x2; +} +function quadraticBezier(from, cp, to, t) { + var inverseT = 1 - t; + return from * inverseT * inverseT + 2 * cp * inverseT * t + to * t * t; +} +function quadraticBezierExtreme(from, cp, to) { + var t = (from - cp) / (from - 2 * cp + to); + if (t < 0) { + return from; + } + if (t > 1) { + return to; + } + return quadraticBezier(from, cp, to, t); +} +function cubicBezier(from, cp, cp2, to, t) { + var tSq = t * t; + var inverseT = 1 - t; + var inverseTSq = inverseT * inverseT; + return from * inverseT * inverseTSq + 3 * cp * t * inverseTSq + 3 * cp2 * inverseT * tSq + to * t * tSq; +} +function cubicBezierExtremes(from, cp, cp2, to) { + var d1 = cp - from; + var d2 = cp2 - cp; + d2 *= 2; + var d3 = to - cp2; + if (d1 + d3 === d2) { + d3 *= 1.0001; + } + var fHead = 2 * d1 - d2; + var part1 = d2 - 2 * d1; + var fCenter = Math.sqrt(part1 * part1 - 4 * d1 * (d1 - d2 + d3)); + var fTail = 2 * (d1 - d2 + d3); + var t1 = (fHead + fCenter) / fTail; + var t2 = (fHead - fCenter) / fTail; + var result = []; + if (t1 >= 0 && t1 <= 1) { + result.push(cubicBezier(from, cp, cp2, to, t1)); + } + if (t2 >= 0 && t2 <= 1) { + result.push(cubicBezier(from, cp, cp2, to, t2)); + } + return result; +} +function cubicXAtY(x0, y0, cx, cy, cx1, cy1, x1, y1, y) { + var dX = 3 * (cx - x0); + var dY = 3 * (cy - y0); + var bX = 3 * (cx1 - cx) - dX; + var bY = 3 * (cy1 - cy) - dY; + var c3X = x1 - x0 - dX - bX; + var c3Y = y1 - y0 - dY - bY; + function f(t) { + return t * (dY + t * (bY + t * c3Y)) + y0 - y; + } + function pointAt(t) { + if (t < 0) { + t = 0; + } else if (t > 1) { + t = 1; + } + return x0 + t * (dX + t * (bX + t * c3X)); + } + function bisectCubicBezierRange(f, l, r, limit) { + if (Math.abs(r - l) <= limit) { + return; + } + var middle = 0.5 * (l + r); + if (f(l) * f(r) <= 0) { + left = l; + right = r; + return; + } + bisectCubicBezierRange(f, l, middle, limit); + bisectCubicBezierRange(f, middle, r, limit); + } + var left = 0; + var right = 1; + bisectCubicBezierRange(f, 0, 1, 0.05); + var t0 = findRoot(left, right, f, 50, 0.000001); + var evalResult = Math.abs(f(t0)); + if (evalResult > 0.00001) { + return []; + } + var result = []; + if (t0 <= 1) { + result.push(pointAt(t0)); + } + var a = c3Y; + var b = t0 * a + bY; + var c = t0 * b + dY; + var d = b * b - 4 * a * c; + if (d < 0) { + return result; + } + d = Math.sqrt(d); + a = 1 / (a + a); + var t1 = (d - b) * a; + var t2 = (-b - d) * a; + if (t1 >= 0 && t1 <= 1) { + result.push(pointAt(t1)); + } + if (t2 >= 0 && t2 <= 1) { + result.push(pointAt(t2)); + } + return result; +} +function findRoot(x0, x2, f, maxIterations, epsilon) { + var x1; + var y0; + var y1; + var y2; + var b; + var c; + var y10; + var y20; + var y21; + var xm; + var ym; + var temp; + var xmlast = x0; + y0 = f(x0); + if (y0 === 0) { + return x0; + } + y2 = f(x2); + if (y2 === 0) { + return x2; + } + if (y2 * y0 > 0) { + return x0; + } + var __iter = 0; + for (var i = 0; i < maxIterations; ++i) { + __iter++; + x1 = 0.5 * (x2 + x0); + y1 = f(x1); + if (y1 === 0) { + return x1; + } + if (Math.abs(x1 - x0) < epsilon) { + return x1; + } + if (y1 * y0 > 0) { + temp = x0; + x0 = x2; + x2 = temp; + temp = y0; + y0 = y2; + y2 = temp; + } + y10 = y1 - y0; + y21 = y2 - y1; + y20 = y2 - y0; + if (y2 * y20 < 2 * y1 * y10) { + x2 = x1; + y2 = y1; + } else { + b = (x1 - x0) / y10; + c = (y10 - y21) / (y21 * y20); + xm = x0 - b * y0 * (1 - c * y1); + ym = f(xm); + if (ym === 0) { + return xm; + } + if (Math.abs(xm - xmlast) < epsilon) { + return xm; + } + xmlast = xm; + if (ym * y0 < 0) { + x2 = xm; + y2 = ym; + } else { + x0 = xm; + y0 = ym; + x2 = x1; + y2 = y1; + } + } + } + return x1; +} +function extendBoundsByPoint(bounds, x, y) { + if (x < bounds.xMin) { + bounds.xMin = x; + } else if (x > bounds.xMax) { + bounds.xMax = x; + } + if (y < bounds.yMin) { + bounds.yMin = y; + } else if (y > bounds.yMax) { + bounds.yMax = y; + } +} +function extendBoundsByX(bounds, x) { + if (x < bounds.xMin) { + bounds.xMin = x; + } else if (x > bounds.xMax) { + bounds.xMax = x; + } +} +function extendBoundsByY(bounds, y) { + if (y < bounds.yMin) { + bounds.yMin = y; + } else if (y > bounds.yMax) { + bounds.yMax = y; + } +} +function morph(start, end, ratio) { + return start + (end - start) * ratio; +} +function finishShapePath(path, dictionaryResolved) { + if (path.fullyInitialized) { + return path; + } + if (!(path instanceof ShapePath)) { + var untypedPath = path; + path = new ShapePath(path.fillStyle, path.lineStyle, 0, 0, path.isMorph); + path.commands = new Uint8Array(untypedPath.buffers[0]); + path.data = new Int32Array(untypedPath.buffers[1]); + if (untypedPath.isMorph) { + path.morphData = new Int32Array(untypedPath.buffers[2]); + } + path.buffers = null; + } + path.fillStyle && initStyle(path.fillStyle, dictionaryResolved); + path.lineStyle && initStyle(path.lineStyle, dictionaryResolved); + path.fullyInitialized = true; + return path; +} +var inWorker = typeof window === 'undefined'; +var factoryCtx = !inWorker ? document.createElement('canvas').getContext('2d') : null; +function buildLinearGradientFactory(colorStops) { + var defaultGradient = factoryCtx.createLinearGradient(-1, 0, 1, 0); + for (var i = 0; i < colorStops.length; i++) { + defaultGradient.addColorStop(colorStops[i].ratio, colorStops[i].color); + } + var fn = function createLinearGradient(ctx, colorTransform) { + var gradient = ctx.createLinearGradient(-1, 0, 1, 0); + for (var i = 0; i < colorStops.length; i++) { + colorTransform.addGradientColorStop(gradient, colorStops[i].ratio, colorStops[i].color); + } + return gradient; + }; + fn.defaultFillStyle = defaultGradient; + return fn; +} +function buildRadialGradientFactory(focalPoint, colorStops) { + var defaultGradient = factoryCtx.createRadialGradient(focalPoint, 0, 0, 0, 0, 1); + for (var i = 0; i < colorStops.length; i++) { + defaultGradient.addColorStop(colorStops[i].ratio, colorStops[i].color); + } + var fn = function createRadialGradient(ctx, colorTransform) { + var gradient = ctx.createRadialGradient(focalPoint, 0, 0, 0, 0, 1); + for (var i = 0; i < colorStops.length; i++) { + colorTransform.addGradientColorStop(gradient, colorStops[i].ratio, colorStops[i].color); + } + return gradient; + }; + fn.defaultFillStyle = defaultGradient; + return fn; +} +function buildBitmapPatternFactory(img, repeat) { + var defaultPattern = factoryCtx.createPattern(img, repeat); + var cachedTransform, cachedTransformKey; + var fn = function createBitmapPattern(ctx, colorTransform) { + if (!colorTransform.mode) { + return defaultPattern; + } + var key = colorTransform.getTransformFingerprint(); + if (key === cachedTransformKey) { + return cachedTransform; + } + var canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + var ctx = canvas.getContext('2d'); + colorTransform.setAlpha(ctx, true); + ctx.drawImage(img, 0, 0); + cachedTransform = ctx.createPattern(canvas, repeat); + cachedTransformKey = key; + return cachedTransform; + }; + fn.defaultFillStyle = defaultPattern; + return fn; +} +function initStyle(style, dictionaryResolved) { + if (style.type === undefined) { + return; + } + switch (style.type) { + case GRAPHICS_FILL_SOLID: + break; + case GRAPHICS_FILL_LINEAR_GRADIENT: + case GRAPHICS_FILL_RADIAL_GRADIENT: + case GRAPHICS_FILL_FOCAL_RADIAL_GRADIENT: + var records = style.records, colorStops = []; + for (var j = 0, n = records.length; j < n; j++) { + var record = records[j]; + var colorStr = rgbaObjToStr(record.color); + colorStops.push({ + ratio: record.ratio / 255, + color: colorStr + }); + } + var gradientConstructor; + var isLinear = style.type === GRAPHICS_FILL_LINEAR_GRADIENT; + if (isLinear) { + gradientConstructor = buildLinearGradientFactory(colorStops); + } else { + gradientConstructor = buildRadialGradientFactory((style.focalPoint | 0) / 20, colorStops); + } + style.style = gradientConstructor; + break; + case GRAPHICS_FILL_REPEATING_BITMAP: + case GRAPHICS_FILL_CLIPPED_BITMAP: + case GRAPHICS_FILL_NONSMOOTHED_REPEATING_BITMAP: + case GRAPHICS_FILL_NONSMOOTHED_CLIPPED_BITMAP: + var bitmap = dictionaryResolved[style.bitmapId]; + var repeat = style.type === GRAPHICS_FILL_REPEATING_BITMAP || style.type === GRAPHICS_FILL_NONSMOOTHED_REPEATING_BITMAP; + style.style = buildBitmapPatternFactory(bitmap.props.img, repeat ? 'repeat' : 'no-repeat'); + break; + default: + fail('invalid fill style', 'shape'); + } +} +var SOUND_SIZE_8_BIT = 0; +var SOUND_SIZE_16_BIT = 1; +var SOUND_TYPE_MONO = 0; +var SOUND_TYPE_STEREO = 1; +var SOUND_FORMAT_PCM_BE = 0; +var SOUND_FORMAT_ADPCM = 1; +var SOUND_FORMAT_MP3 = 2; +var SOUND_FORMAT_PCM_LE = 3; +var SOUND_FORMAT_NELLYMOSER_16 = 4; +var SOUND_FORMAT_NELLYMOSER_8 = 5; +var SOUND_FORMAT_NELLYMOSER = 6; +var SOUND_FORMAT_SPEEX = 11; +var SOUND_RATES = [ + 5512, + 11250, + 22500, + 44100 + ]; +var WaveHeader = new Uint8Array([ + 82, + 73, + 70, + 70, + 0, + 0, + 0, + 0, + 87, + 65, + 86, + 69, + 102, + 109, + 116, + 32, + 16, + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 68, + 172, + 0, + 0, + 16, + 177, + 2, + 0, + 4, + 0, + 16, + 0, + 100, + 97, + 116, + 97, + 0, + 0, + 0, + 0 + ]); +function packageWave(data, sampleRate, channels, size, swapBytes) { + var sizeInBytes = size >> 3; + var sizePerSecond = channels * sampleRate * sizeInBytes; + var sizePerSample = channels * sizeInBytes; + var dataLength = data.length + (data.length & 1); + var buffer = new ArrayBuffer(WaveHeader.length + dataLength); + var bytes = new Uint8Array(buffer); + bytes.set(WaveHeader); + if (swapBytes) { + for (var i = 0, j = WaveHeader.length; i < data.length; i += 2, j += 2) { + bytes[j] = data[i + 1]; + bytes[j + 1] = data[i]; + } + } else { + bytes.set(data, WaveHeader.length); + } + var view = new DataView(buffer); + view.setUint32(4, dataLength + 36, true); + view.setUint16(22, channels, true); + view.setUint32(24, sampleRate, true); + view.setUint32(28, sizePerSecond, true); + view.setUint16(32, sizePerSample, true); + view.setUint16(34, size, true); + view.setUint32(40, dataLength, true); + return { + data: bytes, + mimeType: 'audio/wav' + }; +} +function defineSound(tag, dictionary) { + var channels = tag.soundType == SOUND_TYPE_STEREO ? 2 : 1; + var samplesCount = tag.samplesCount; + var sampleRate = SOUND_RATES[tag.soundRate]; + var data = tag.soundData; + var pcm, packaged; + switch (tag.soundFormat) { + case SOUND_FORMAT_PCM_BE: + pcm = new Float32Array(samplesCount * channels); + if (tag.soundSize == SOUND_SIZE_16_BIT) { + for (var i = 0, j = 0; i < pcm.length; i++, j += 2) + pcm[i] = (data[j] << 24 | data[j + 1] << 16) / 2147483648; + packaged = packageWave(data, sampleRate, channels, 16, true); + } else { + for (var i = 0; i < pcm.length; i++) + pcm[i] = (data[i] - 128) / 128; + packaged = packageWave(data, sampleRate, channels, 8, false); + } + break; + case SOUND_FORMAT_PCM_LE: + pcm = new Float32Array(samplesCount * channels); + if (tag.soundSize == SOUND_SIZE_16_BIT) { + for (var i = 0, j = 0; i < pcm.length; i++, j += 2) + pcm[i] = (data[j + 1] << 24 | data[j] << 16) / 2147483648; + packaged = packageWave(data, sampleRate, channels, 16, false); + } else { + for (var i = 0; i < pcm.length; i++) + pcm[i] = (data[i] - 128) / 128; + packaged = packageWave(data, sampleRate, channels, 8, false); + } + break; + case SOUND_FORMAT_MP3: + packaged = { + data: new Uint8Array(data.subarray(2)), + mimeType: 'audio/mpeg' + }; + break; + case SOUND_FORMAT_ADPCM: + var pcm16 = new Int16Array(samplesCount * channels); + decodeACPCMSoundData(data, pcm16, channels); + pcm = new Float32Array(samplesCount * channels); + for (var i = 0; i < pcm.length; i++) + pcm[i] = pcm16[i] / 32768; + packaged = packageWave(new Uint8Array(pcm16.buffer), sampleRate, channels, 16, !new Uint8Array(new Uint16Array([ + 1 + ]).buffer)[0]); + break; + default: + throw new Error('Unsupported audio format: ' + tag.soundFormat); + } + var sound = { + type: 'sound', + id: tag.id, + sampleRate: sampleRate, + channels: channels, + pcm: pcm + }; + if (packaged) + sound.packaged = packaged; + return sound; +} +var ACPCMIndexTables = [ + [ + -1, + 2 + ], + [ + -1, + -1, + 2, + 4 + ], + [ + -1, + -1, + -1, + -1, + 2, + 4, + 6, + 8 + ], + [ + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 1, + 2, + 4, + 6, + 8, + 10, + 13, + 16 + ] + ]; +var ACPCMStepSizeTable = [ + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 16, + 17, + 19, + 21, + 23, + 25, + 28, + 31, + 34, + 37, + 41, + 45, + 50, + 55, + 60, + 66, + 73, + 80, + 88, + 97, + 107, + 118, + 130, + 143, + 157, + 173, + 190, + 209, + 230, + 253, + 279, + 307, + 337, + 371, + 408, + 449, + 494, + 544, + 598, + 658, + 724, + 796, + 876, + 963, + 1060, + 1166, + 1282, + 1411, + 1552, + 1707, + 1878, + 2066, + 2272, + 2499, + 2749, + 3024, + 3327, + 3660, + 4026, + 4428, + 4871, + 5358, + 5894, + 6484, + 7132, + 7845, + 8630, + 9493, + 10442, + 11487, + 12635, + 13899, + 15289, + 16818, + 18500, + 20350, + 22385, + 24623, + 27086, + 29794, + 32767 + ]; +function decodeACPCMSoundData(data, pcm16, channels) { + function readBits(n, signed) { + while (dataBufferLength < n) { + dataBuffer = dataBuffer << 8 | data[dataPosition++]; + dataBufferLength += 8; + } + dataBufferLength -= n; + return dataBuffer >>> dataBufferLength & (1 << n) - 1; + } + var dataPosition = 0; + var dataBuffer = 0; + var dataBufferLength = 0; + var pcmPosition = 0; + var codeSize = readBits(2); + var indexTable = ACPCMIndexTables[codeSize]; + while (pcmPosition < pcm16.length) { + var x = pcm16[pcmPosition++] = readBits(16) << 16 >> 16, x2; + var stepIndex = readBits(6), stepIndex2; + if (channels > 1) { + x2 = pcm16[pcmPosition++] = readBits(16) << 16 >> 16; + stepIndex2 = readBits(6); + } + var signMask = 1 << codeSize + 1; + for (var i = 0; i < 4095; i++) { + var nibble = readBits(codeSize + 2); + var step = ACPCMStepSizeTable[stepIndex]; + var sum = 0; + for (var currentBit = signMask >> 1; currentBit; currentBit >>= 1, step >>= 1) { + if (nibble & currentBit) + sum += step; + } + x += (nibble & signMask ? -1 : 1) * (sum + step); + pcm16[pcmPosition++] = x = x < -32768 ? -32768 : x > 32767 ? 32767 : x; + stepIndex += indexTable[nibble & ~signMask]; + stepIndex = stepIndex < 0 ? 0 : stepIndex > 88 ? 88 : stepIndex; + if (channels > 1) { + nibble = readBits(codeSize + 2); + step = ACPCMStepSizeTable[stepIndex2]; + sum = 0; + for (var currentBit = signMask >> 1; currentBit; currentBit >>= 1, step >>= 1) { + if (nibble & currentBit) + sum += step; + } + x2 += (nibble & signMask ? -1 : 1) * (sum + step); + pcm16[pcmPosition++] = x2 = x2 < -32768 ? -32768 : x2 > 32767 ? 32767 : x2; + stepIndex2 += indexTable[nibble & ~signMask]; + stepIndex2 = stepIndex2 < 0 ? 0 : stepIndex2 > 88 ? 88 : stepIndex2; + } + } + } +} +var nextSoundStreamId = 0; +function SwfSoundStream(samplesCount, sampleRate, channels) { + this.streamId = nextSoundStreamId++; + this.samplesCount = samplesCount; + this.sampleRate = sampleRate; + this.channels = channels; + this.format = null; + this.currentSample = 0; +} +SwfSoundStream.prototype = { + get info() { + return { + samplesCount: this.samplesCount, + sampleRate: this.sampleRate, + channels: this.channels, + format: this.format, + streamId: this.streamId + }; + }, + decode: function (data) { + throw new Error('SwfSoundStream.decode: not implemented'); + } +}; +function SwfSoundStream_decode_PCM(data) { + var pcm = new Float32Array(data.length); + for (var i = 0; i < pcm.length; i++) + pcm[i] = (data[i] - 128) / 128; + this.currentSample += pcm.length / this.channels; + return { + streamId: this.streamId, + samplesCount: pcm.length / this.channels, + pcm: pcm + }; +} +function SwfSoundStream_decode_PCM_be(data) { + var pcm = new Float32Array(data.length / 2); + for (var i = 0, j = 0; i < pcm.length; i++, j += 2) + pcm[i] = (data[j] << 24 | data[j + 1] << 16) / 2147483648; + this.currentSample += pcm.length / this.channels; + return { + streamId: this.streamId, + samplesCount: pcm.length / this.channels, + pcm: pcm + }; +} +function SwfSoundStream_decode_PCM_le(data) { + var pcm = new Float32Array(data.length / 2); + for (var i = 0, j = 0; i < pcm.length; i++, j += 2) + pcm[i] = (data[j + 1] << 24 | data[j] << 16) / 2147483648; + this.currentSample += pcm.length / this.channels; + return { + streamId: this.streamId, + samplesCount: pcm.length / this.channels, + pcm: pcm + }; +} +function SwfSoundStream_decode_MP3(data) { + var samplesCount = data[1] << 8 | data[0]; + var seek = data[3] << 8 | data[2]; + this.currentSample += samplesCount; + return { + streamId: this.streamId, + samplesCount: samplesCount, + data: new Uint8Array(data.subarray(4)), + seek: seek + }; +} +function createSoundStream(tag) { + var channels = tag.streamType == SOUND_TYPE_STEREO ? 2 : 1; + var samplesCount = tag.samplesCount; + var sampleRate = SOUND_RATES[tag.streamRate]; + var stream = new SwfSoundStream(samplesCount, sampleRate, channels); + switch (tag.streamCompression) { + case SOUND_FORMAT_PCM_BE: + stream.format = 'wave'; + if (tag.soundSize == SOUND_SIZE_16_BIT) { + stream.decode = SwfSoundStream_decode_PCM_be; + } else { + stream.decode = SwfSoundStream_decode_PCM; + } + break; + case SOUND_FORMAT_PCM_LE: + stream.format = 'wave'; + if (tag.soundSize == SOUND_SIZE_16_BIT) { + stream.decode = SwfSoundStream_decode_PCM_le; + } else { + stream.decode = SwfSoundStream_decode_PCM; + } + break; + case SOUND_FORMAT_MP3: + stream.format = 'mp3'; + stream.decode = SwfSoundStream_decode_MP3; + break; + default: + throw new Error('Unsupported audio format: ' + tag.soundFormat); + } + return stream; +} +function defineText(tag, dictionary) { + var dependencies = []; + if (tag.hasFont) { + var font = dictionary[tag.fontId]; + tag.font = font.uniqueName; + dependencies.push(font.id); + } + var props = { + type: 'text', + id: tag.id, + variableName: tag.variableName, + tag: tag + }; + if (dependencies.length) + props.require = dependencies; + return props; +} +var isWorker = typeof window === 'undefined'; +if (isWorker) { + importScripts('../../../lib/mp3/mp3.js'); + self.addEventListener('message', function (e) { + var data = e.data; + var sessionId = data.sessionId; + try { + switch (data.action) { + case 'create': + var session = new Session(sessionId); + sessions[sessionId] = session; + break; + case 'close': + var session = sessions[sessionId]; + if (session) { + session.close(); + sessions[sessionId] = null; + } + break; + case 'decode': + var session = sessions[sessionId]; + if (!session) { + throw new Error('mp3 decoding session is unavailable'); + } + session.decode(data.data); + break; + } + } catch (ex) { + self.postMessage({ + sessionId: sessionId, + action: 'error', + message: ex.message + }); + } + }, false); + var sessions = {}; + function Session(id) { + this.id = id; + if (typeof MP3Decoder === 'undefined') { + throw new Error('mp3 decoder is not available'); + } + var decoder = new MP3Decoder(); + decoder.onframedata = function (frameData, channels, sampleRate, bitRate) { + self.postMessage({ + sessionId: this.id, + action: 'frame', + frameData: frameData, + channels: channels, + sampleRate: sampleRate, + bitRate: bitRate + }); + }.bind(this); + decoder.onid3tag = function (data) { + self.postMessage({ + sessionId: this.id, + action: 'id3', + id3Data: data + }); + }.bind(this); + this.decoder = decoder; + } + Session.prototype = { + decode: function (data) { + this.decoder.push(data); + }, + close: function () { + self.postMessage({ + sessionId: this.id, + action: 'closed' + }); + } + }; + self.console = { + log: function (s) { + self.postMessage({ + action: 'console', + method: 'log', + message: s + }); + }, + error: function (s) { + self.postMessage({ + action: 'console', + method: 'error', + message: s + }); + } + }; +} else { + var mp3Worker; + function createMP3Worker() { + var worker = new Worker(SHUMWAY_ROOT + 'swf/mp3worker.js'); + worker.addEventListener('message', function (e) { + if (e.data.action === 'console') { + console[e.data.method].call(console, e.data.message); + } + }); + return worker; + } + var nextSessionId = 0; + function MP3DecoderSession() { + mp3Worker = mp3Worker || createMP3Worker(); + var sessionId = nextSessionId++; + this.id = sessionId; + this.onworkermessage = function (e) { + if (e.data.sessionId !== sessionId) + return; + var action = e.data.action; + switch (action) { + case 'closed': + if (this.onclosed) + this.onclosed(); + mp3Worker.removeEventListener('message', this.onworkermessage, false); + break; + case 'frame': + this.onframedata(e.data.frameData, e.data.channels, e.data.sampleRate, e.data.bitRate); + break; + case 'id3': + if (this.onid3tag) + this.onid3tag(e.data.id3Data); + break; + case 'error': + if (this.onerror) + this.onerror(e.data.message); + break; + } + }.bind(this); + mp3Worker.addEventListener('message', this.onworkermessage, false); + mp3Worker.postMessage({ + sessionId: sessionId, + action: 'create' + }); + } + MP3DecoderSession.prototype = { + pushAsync: function (data) { + mp3Worker.postMessage({ + sessionId: this.id, + action: 'decode', + data: data + }); + }, + close: function () { + mp3Worker.postMessage({ + sessionId: this.id, + action: 'close' + }); + } + }; + MP3DecoderSession.processAll = function (data, onloaded) { + var currentBufferSize = 8000; + var currentBuffer = new Float32Array(currentBufferSize); + var bufferPosition = 0; + var id3Tags = []; + var sessionAborted = false; + var session = new MP3DecoderSession(); + session.onframedata = function (frameData, channels, sampleRate, bitRate) { + var needed = frameData.length + bufferPosition; + if (needed > currentBufferSize) { + do { + currentBufferSize *= 2; + } while (needed > currentBufferSize); + var newBuffer = new Float32Array(currentBufferSize); + newBuffer.set(currentBuffer); + currentBuffer = newBuffer; + } + currentBuffer.set(frameData, bufferPosition); + bufferPosition += frameData.length; + }; + session.onid3tag = function (tagData) { + id3Tags.push(tagData); + }; + session.onclosed = function () { + if (sessionAborted) + return; + onloaded(currentBuffer.subarray(0, bufferPosition), id3Tags); + }; + session.onerror = function (error) { + if (sessionAborted) + return; + sessionAborted = true; + onloaded(null, null, error); + }; + session.pushAsync(data); + session.close(); + }; +} +SWF.embed = function (file, doc, container, options) { + var canvas = doc.createElement('canvas'); + var ctx = canvas.getContext('2d'); + var loader = new flash.display.Loader(); + var loaderInfo = loader._contentLoaderInfo; + var stage = new flash.display.Stage(); + var pixelRatio = 1; + var forceHidpiSetting = forceHidpi.value; + stage._loader = loader; + loaderInfo._parameters = options.movieParams; + loaderInfo._url = options.url || (typeof file === 'string' ? file : null); + loaderInfo._loaderURL = options.loaderURL || loaderInfo._url; + loader._parent = stage; + loader._stage = stage; + function setCanvasSize(width, height) { + if (pixelRatio === 1) { + canvas.width = width | 0; + canvas.height = height | 0; + return; + } + var canvasWidth = Math.floor(width * pixelRatio); + var canvasHeight = Math.floor(height * pixelRatio); + canvas.style.width = canvasWidth / pixelRatio + 'px'; + canvas.style.height = canvasHeight / pixelRatio + 'px'; + canvas.width = canvasWidth; + canvas.height = canvasHeight; + } + function fitCanvas(container) { + setCanvasSize(container.clientWidth, container.clientHeight); + stage._invalid = true; + } + loaderInfo._addEventListener('init', function () { + if (forceHidpiSetting || loaderInfo._swfVersion >= 18) { + pixelRatio = 'devicePixelRatio' in window ? window.devicePixelRatio : 1; + } + canvas._pixelRatio = pixelRatio; + stage._contentsScaleFactor = pixelRatio; + if (container.clientHeight) { + fitCanvas(container); + window.addEventListener('resize', function () { + fitCanvas(container); + }); + } else { + setCanvasSize(stage._stageWidth / 20, stage._stageHeight / 20); + } + container.setAttribute('style', 'position: relative'); + canvas.addEventListener('click', function () { + ShumwayKeyboardListener.focus = stage; + stage._mouseTarget._dispatchEvent('click'); + }); + canvas.addEventListener('dblclick', function () { + if (stage._mouseTarget._doubleClickEnabled) { + stage._mouseTarget._dispatchEvent('doubleClick'); + } + }); + canvas.addEventListener('mousedown', function () { + stage._mouseEvents.push('mousedown'); + }); + canvas.addEventListener('mousemove', function (domEvt) { + var node = this; + var left = 0; + var top = 0; + if (node.offsetParent) { + do { + left += node.offsetLeft; + top += node.offsetTop; + } while (node = node.offsetParent); + } + var m = stage._concatenatedTransform; + var mouseX = ((domEvt.pageX - left) * pixelRatio - m.tx / 20) / m.a; + var mouseY = ((domEvt.pageY - top) * pixelRatio - m.ty / 20) / m.d; + if (mouseX !== stage._mouseX || mouseY !== stage._mouseY) { + stage._mouseMoved = true; + stage._mouseX = mouseX * 20; + stage._mouseY = mouseY * 20; + } + }); + canvas.addEventListener('mouseup', function () { + stage._mouseEvents.push('mouseup'); + }); + canvas.addEventListener('mouseover', function () { + stage._mouseMoved = true; + stage._mouseOver = true; + }); + canvas.addEventListener('mouseout', function () { + stage._mouseMoved = true; + stage._mouseOver = false; + }); + window.addEventListener('message', function (evt) { + var data = evt.data; + if (typeof data !== 'object' || data === null) { + return; + } + var type = data.type; + switch (type) { + case 'mousemove': + case 'mouseup': + case 'mousedown': + var isMouseMove = type === 'mousemove'; + stage._mouseMoved = true; + stage._mouseOver = true; + stage._mouseX = data.x * 20; + stage._mouseY = data.y * 20; + if (!isMouseMove) { + stage._mouseEvents.push(type); + } + break; + case 'mouseover': + case 'mouseout': + stage._mouseMoved = true; + stage._mouseOver = type === 'mouseover'; + break; + case 'keyup': + case 'keydown': + stage._dispatchEvent(new flash.events.KeyboardEvent(type === 'keyup' ? 'keyUp' : 'keyDown', true, false, data.charCode, data.keyCode, data.keyLocation, data.ctrlKey || false, data.altKey || false, data.shiftKey || false)); + break; + } + }, false); + var bgcolor = loaderInfo._backgroundColor; + if (options.objectParams) { + var m; + if (options.objectParams.bgcolor && (m = /#([0-9A-F]{6})/i.exec(options.objectParams.bgcolor))) { + var hexColor = parseInt(m[1], 16); + bgcolor = { + red: hexColor >> 16 & 255, + green: hexColor >> 8 & 255, + blue: hexColor & 255, + alpha: 255 + }; + } + if (options.objectParams.wmode === 'transparent') { + bgcolor = { + red: 0, + green: 0, + blue: 0, + alpha: 0 + }; + } + } + stage._color = bgcolor; + ctx.fillStyle = rgbaObjToStr(bgcolor); + ctx.fillRect(0, 0, canvas.width, canvas.height); + var root = loader._content; + root._dispatchEvent('added', undefined, true); + root._dispatchEvent('addedToStage'); + container.appendChild(canvas); + stage._domContainer = container; + if (options.onStageInitialized) { + options.onStageInitialized(stage); + } + var startPromise = options.startPromise || Promise.resolve(); + startPromise.then(function () { + renderStage(stage, ctx, options); + }); + }); + if (options.onParsed) { + loaderInfo._addEventListener('parsed', function () { + options.onParsed(); + }); + } + if (options.onComplete) { + loaderInfo._addEventListener('complete', function () { + options.onComplete(); + }); + } + loader._load(typeof file === 'string' ? new flash.net.URLRequest(file) : file); + return loader; +}; +var rendererOptions = coreOptions.register(new OptionSet('Renderer Options')); +var traceRenderer = rendererOptions.register(new Option('tr', 'traceRenderer', 'number', 0, 'trace renderer execution')); +var disableRenderVisitor = rendererOptions.register(new Option('drv', 'disableRenderVisitor', 'boolean', false, 'disable render visitor')); +var disableMouseVisitor = rendererOptions.register(new Option('dmv', 'disableMouseVisitor', 'boolean', false, 'disable mouse visitor')); +var showRedrawRegions = rendererOptions.register(new Option('rr', 'showRedrawRegions', 'boolean', false, 'show redraw regions')); +var renderAsWireframe = rendererOptions.register(new Option('raw', 'renderAsWireframe', 'boolean', false, 'render as wireframe')); +var showQuadTree = rendererOptions.register(new Option('qt', 'showQuadTree', 'boolean', false, 'show quad tree')); +var turboMode = rendererOptions.register(new Option('', 'turbo', 'boolean', false, 'turbo mode')); +var forceHidpi = rendererOptions.register(new Option('', 'forceHidpi', 'boolean', false, 'force hidpi')); +var skipFrameDraw = rendererOptions.register(new Option('', 'skipFrameDraw', 'boolean', false, 'skip frame when not on time')); +var hud = rendererOptions.register(new Option('', 'hud', 'boolean', false, 'show hud mode')); +var dummyAnimation = rendererOptions.register(new Option('', 'dummy', 'boolean', false, 'show test balls animation')); +var enableConstructChildren = rendererOptions.register(new Option('', 'constructChildren', 'boolean', true, 'Construct Children')); +var enableEnterFrame = rendererOptions.register(new Option('', 'enterFrame', 'boolean', true, 'Enter Frame')); +var enableAdvanceFrame = rendererOptions.register(new Option('', 'advanceFrame', 'boolean', true, 'Advance Frame')); +var CanvasCache = { + cache: [], + getCanvas: function getCanvas(protoCanvas) { + var tempCanvas = this.cache.shift(); + if (!tempCanvas) { + tempCanvas = { + canvas: document.createElement('canvas') + }; + tempCanvas.ctx = tempCanvas.canvas.getContext('2d'); + } + tempCanvas.canvas.width = protoCanvas.width; + tempCanvas.canvas.height = protoCanvas.height; + tempCanvas.ctx.save(); + return tempCanvas; + }, + releaseCanvas: function releaseCanvas(tempCanvas) { + tempCanvas.ctx.restore(); + this.cache.push(tempCanvas); + } + }; +function isCanvasVisible(canvas) { + if (canvas.ownerDocument.hidden) { + return false; + } + if (canvas.mozVisible === false) { + return false; + } + return true; +} +function visitContainer(container, visitor, context) { + var children = container._children; + visitor.childrenStart(container); + for (var i = 0, n = children.length; i < n; i++) { + var child = children[i]; + if (!child) { + continue; + } + if (visitor.ignoreVisibleAttribute || child._visible && !child._maskedObject) { + visitor.visit(child, visitContainer, context); + } + } + visitor.childrenEnd(container); +} +var BlendModeNameMap = { + 'normal': 'normal', + 'multiply': 'multiply', + 'screen': 'screen', + 'lighten': 'lighten', + 'darken': 'darken', + 'difference': 'difference', + 'overlay': 'overlay', + 'hardlight': 'hard-light' + }; +function getBlendModeName(blendMode) { + return BlendModeNameMap[blendMode] || 'normal'; +} +function RenderVisitor(root, ctx, invalidPath, refreshStage) { + this.root = root; + this.ctx = ctx; + this.depth = 0; + this.invalidPath = invalidPath; + this.refreshStage = refreshStage; + this.clipDepth = null; + this.clipStack = null; +} +RenderVisitor.prototype = { + ignoreVisibleAttribute: false, + start: function () { + visitContainer(this.root, this, new RenderingContext(this.refreshStage, this.invalidPath)); + }, + startFragment: function (matrix) { + var root = this.root; + var currentTransform = root._currentTransform; + var t = currentTransform; + if (matrix) { + t = root._currentTransform = { + a: matrix.a, + b: matrix.b, + c: matrix.c, + d: matrix.d, + tx: matrix.tx * 20 | 0, + ty: matrix.ty * 20 | 0 + }; + root._invalidateTransform(); + } + var inverse; + if (t) { + inverse = new flash.geom.Matrix(t.a, t.b, t.c, t.d, t.tx / 20, t.ty / 20); + inverse.invert(); + this.ctx.save(); + this.ctx.transform(inverse.a, inverse.b, inverse.c, inverse.d, inverse.tx, inverse.ty); + } + this.visit(root, visitContainer, new RenderingContext(this.refreshStage, this.invalidPath)); + if (t) { + this.ctx.restore(); + } + if (matrix) { + root._currentTransform = currentTransform; + root._invalidateTransform(); + } + }, + childrenStart: function (parent) { + if (this.depth === 0) { + var ctx = this.ctx; + ctx.save(); + if (this.invalidPath && !this.refreshStage && !renderAsWireframe.value) { + this.invalidPath.draw(ctx, false, 0, null); + ctx.clip(); + } + var bgcolor = this.root._color; + if (bgcolor) { + if (bgcolor.alpha < 255) { + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + } + if (bgcolor.alpha > 0) { + ctx.fillStyle = rgbaObjToStr(bgcolor); + if (this.invalidPath && !this.refreshStage && !renderAsWireframe.value) { + ctx.fill(); + } else { + ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); + } + } + } + ctx.mozFillRule = 'evenodd'; + } + this.depth++; + if (this.clipDepth && this.clipDepth.length > 0) { + this.clipStack = { + depth: this.depth, + clip: this.clipDepth, + next: this.clipStack + }; + this.clipDepth = null; + } + }, + childrenEnd: function (parent) { + if (this.clipDepth) { + while (this.clipDepth.length > 0) { + var clipDepthInfo = this.clipDepth.pop(); + this.clipEnd(clipDepthInfo); + this.ctx = clipDepthInfo.ctx; + } + this.clipDepth = null; + } + if (this.clipStack && this.clipStack.depth === this.depth) { + this.clipDepth = this.clipStack.clip; + this.clipStack = this.clipStack.next; + } + this.depth--; + if (this.depth === 0) { + this.ctx.restore(); + this.invalidPath = null; + } + }, + visit: function (child, visitContainer, context) { + var ctx = this.ctx; + var parentHasClippingMask = context.isClippingMask; + var parentColorTransform = context.colorTransform; + var clippingMask = parentHasClippingMask === true; + if (child._cxform) { + context.colorTransform = parentColorTransform.applyCXForm(child._cxform); + } + if (!clippingMask) { + while (this.clipDepth && this.clipDepth.length > 0 && child._depth > this.clipDepth[0].clipDepth) { + var clipDepthInfo = this.clipDepth.shift(); + this.clipEnd(clipDepthInfo); + context.parentCtxs.shift(); + ctx = this.ctx = clipDepthInfo.ctx; + } + if (this.clipDepth && this.clipDepth.length > 0 && child._depth <= this.clipDepth[0].clipDepth) { + ctx = this.ctx = this.clipDepth[0].maskee.ctx; + } + if (child._clipDepth) { + context.isClippingMask = clippingMask = true; + var clipDepthInfo = this.clipStart(child); + if (!this.clipDepth) { + this.clipDepth = [ + clipDepthInfo + ]; + } else { + this.clipDepth.unshift(clipDepthInfo); + } + context.parentCtxs.unshift(ctx); + ctx = this.ctx = clipDepthInfo.mask.ctx; + } + } + if (clippingMask && child._isContainer) { + ctx.save(); + renderDisplayObject(child, ctx, context); + for (var i = 0, n = child._children.length; i < n; i++) { + var child1 = child._children[i]; + if (!child1) { + continue; + } + if (this.ignoreVisibleAttribute || child1._visible && !child1._maskedObject) { + this.visit(child1, visitContainer, context); + } + } + ctx.restore(); + ctx.fill(); + context.isClippingMask = parentHasClippingMask; + context.colorTransform = parentColorTransform; + return; + } + ctx.save(); + ctx.globalCompositeOperation = getBlendModeName(child._blendMode); + if (child._mask) { + var clipInfo = this.clipStart(child); + var mask = clipInfo.mask; + var maskee = clipInfo.maskee; + context.parentCtxs.push(ctx); + var savedClipDepth = this.clipDepth; + this.clipDepth = null; + this.ctx = mask.ctx; + this.visit(child._mask, visitContainer, new RenderingContext(this.refreshStage)); + this.ctx = ctx; + this.clipDepth = savedClipDepth; + renderDisplayObject(child, maskee.ctx, context); + if (child._isContainer) { + this.ctx = maskee.ctx; + visitContainer(child, this, context); + this.ctx = ctx; + } + context.parentCtxs.pop(); + this.clipEnd(clipInfo); + } else { + renderDisplayObject(child, ctx, context); + if (child._isContainer) { + visitContainer(child, this, context); + } + } + ctx.restore(); + if (clippingMask) { + ctx.fill(); + } + context.isClippingMask = parentHasClippingMask; + context.colorTransform = parentColorTransform; + }, + clipStart: function (child) { + var m = child._parent._getConcatenatedTransform(null, true); + var tx = m.tx / 20; + var ty = m.ty / 20; + var mask = CanvasCache.getCanvas(this.ctx.canvas); + mask.ctx.setTransform(m.a, m.b, m.c, m.d, tx, ty); + var maskee = CanvasCache.getCanvas(this.ctx.canvas); + maskee.ctx.setTransform(m.a, m.b, m.c, m.d, tx, ty); + var clipInfo = { + ctx: this.ctx, + mask: mask, + maskee: maskee, + clipDepth: child._clipDepth + }; + return clipInfo; + }, + clipEnd: function (clipInfo) { + var ctx = clipInfo.ctx; + var mask = clipInfo.mask; + var maskee = clipInfo.maskee; + maskee.ctx.globalCompositeOperation = 'destination-in'; + maskee.ctx.setTransform(1, 0, 0, 1, 0, 0); + maskee.ctx.drawImage(mask.canvas, 0, 0); + ctx.save(); + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.drawImage(maskee.canvas, 0, 0); + ctx.restore(); + CanvasCache.releaseCanvas(mask); + CanvasCache.releaseCanvas(maskee); + } +}; +function RenderingColorTransform() { + this.mode = null; + this.transform = [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0 + ]; +} +RenderingColorTransform.prototype = { + applyCXForm: function (cxform) { + var t = this.transform; + t = [ + t[0] * cxform.redMultiplier / 256, + t[1] * cxform.greenMultiplier / 256, + t[2] * cxform.blueMultiplier / 256, + t[3] * cxform.alphaMultiplier / 256, + t[4] * cxform.redMultiplier / 256 + cxform.redOffset, + t[5] * cxform.greenMultiplier / 256 + cxform.greenOffset, + t[6] * cxform.blueMultiplier / 256 + cxform.blueOffset, + t[7] * cxform.alphaMultiplier / 256 + cxform.alphaOffset + ]; + var mode; + var PRECISION = 0.0001; + if (Math.abs(t[0] - 1) < PRECISION && Math.abs(t[1] - 1) < PRECISION && Math.abs(t[2] - 1) < PRECISION && t[3] >= 0 && Math.abs(t[4]) < PRECISION && Math.abs(t[5]) < PRECISION && Math.abs(t[6]) < PRECISION && Math.abs(t[7]) < PRECISION) { + mode = Math.abs(t[3] - 1) < PRECISION ? null : 'simple'; + } else { + mode = 'complex'; + } + var clone = Object.create(RenderingColorTransform.prototype); + clone.mode = mode; + clone.transform = t; + return clone; + }, + setFillStyle: function (ctx, style) { + if (this.mode === 'complex') { + style = typeof style === 'function' ? style(ctx, this) : this.convertColor(style); + } else if (typeof style === 'number') { + style = this.convertNumericColor(style); + } else if (typeof style === 'function') { + style = style.defaultFillStyle; + } + ctx.fillStyle = style; + }, + setStrokeStyle: function (ctx, style) { + if (this.mode === 'complex') { + style = typeof style === 'function' ? style(ctx, this) : this.convertColor(style); + } else if (typeof style === 'number') { + style = this.convertNumericColor(style); + } else if (typeof style === 'function') { + style = style.defaultFillStyle; + } + ctx.strokeStyle = style; + }, + addGradientColorStop: function (gradient, ratio, style) { + if (this.mode === 'complex') { + style = this.convertColor(style); + } else if (typeof style === 'number') { + style = this.convertNumericColor(style); + } + gradient.addColorStop(ratio, style); + }, + setAlpha: function (ctx, force) { + if (this.mode === 'simple' || force) { + var t = this.transform; + ctx.globalAlpha = Math.min(1, Math.max(0, ctx.globalAlpha * t[3])); + } + }, + convertNumericColor: function (num) { + return '#' + (num | 16777216).toString(16).substr(1); + }, + convertColor: function (style) { + var t = this.transform; + var m; + switch (typeof style) { + case 'string': + if (style[0] === '#') { + m = [ + undefined, + parseInt(style.substr(1, 2), 16), + parseInt(style.substr(3, 2), 16), + parseInt(style.substr(5, 2), 16), + 1 + ]; + } + m = m || /rgba\(([^,]+),([^,]+),([^,]+),([^)]+)\)/.exec(style); + if (!m) { + return style; + } + break; + case 'number': + m = [ + style, + style >> 16 & 255, + style >> 8 & 255, + style & 255, + 1 + ]; + break; + default: + return style; + } + var r = Math.min(255, Math.max(0, m[1] * t[0] + t[4])) | 0; + var g = Math.min(255, Math.max(0, m[2] * t[1] + t[5])) | 0; + var b = Math.min(255, Math.max(0, m[3] * t[2] + t[6])) | 0; + var a = Math.min(1, Math.max(0, m[4] * t[3] + t[7] / 256)); + return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + }, + getTransformFingerprint: function () { + return this.transform.join('|'); + } +}; +function RenderingContext(refreshStage, invalidPath) { + this.refreshStage = refreshStage === true; + this.invalidPath = invalidPath; + this.isClippingMask = false; + this.colorTransform = new RenderingColorTransform(); + this.parentCtxs = []; +} +function renderDisplayObject(child, ctx, context) { + var m = child._currentTransform; + if (m) { + ctx.transform(m.a, m.b, m.c, m.d, m.tx / 20, m.ty / 20); + } + if (!renderAsWireframe.value) { + if (child._alpha !== 1) { + ctx.globalAlpha *= child._alpha; + } + if (context.invalidPath && !child._invalid && !context.refreshStage) { + return; + } + if (child._graphics) { + var graphics = child._graphics; + if (graphics._bitmap) { + ctx.save(); + ctx.translate(child._bbox.xMin / 20, child._bbox.yMin / 20); + context.colorTransform.setAlpha(ctx, true); + ctx.drawImage(graphics._bitmap, 0, 0); + ctx.restore(); + } else { + var ratio = child.ratio; + if (ratio === undefined) { + ratio = 0; + } + graphics.draw(ctx, context.isClippingMask, ratio, context.colorTransform); + } + } + if (child.draw) { + child.draw(ctx, child.ratio, context.colorTransform, context.parentCtxs); + } + } else { + if (!child._invalid && !context.refreshStage) { + return; + } + if (child.getBounds) { + var b = child.getBounds(null); + if (b && b.xMax - b.xMin > 0 && b.yMax - b.yMin > 0) { + if (!child._wireframeStrokeStyle) { + child._wireframeStrokeStyle = randomStyle(); + } + ctx.save(); + ctx.strokeStyle = child._wireframeStrokeStyle; + var x = b.xMin / 20; + var y = b.yMin / 20; + ctx.strokeRect(x + 0.5, y + 0.5, b.xMax / 20 - x - 1, b.yMax / 20 - y - 1); + ctx.restore(); + } + } + } + child._invalid = false; +} +function renderQuadTree(ctx, qtree) { + ctx.strokeRect(qtree.x / 20, qtree.y / 20, qtree.width / 20, qtree.height / 20); + var nodes = qtree.nodes; + for (var i = 0; i < nodes.length; i++) { + renderQuadTree(ctx, nodes[i]); + } +} +var renderingTerminated = false; +var samplesLeftPlusOne = 0; +function triggerSampling(count) { + samplesLeftPlusOne = -count - 1; +} +function sampleStart() { + if (!samplesLeftPlusOne) { + return; + } + if (samplesLeftPlusOne < 0) { + console.profile('Sample'); + samplesLeftPlusOne *= -1; + } + if (samplesLeftPlusOne > 0) { + console.info('Sampling Frame: ' + (samplesLeftPlusOne - 1)); + } +} +function sampleEnd() { + if (!samplesLeftPlusOne) { + return; + } + samplesLeftPlusOne--; + if (samplesLeftPlusOne === 1) { + console.profileEnd('Sample'); + } +} +var timeline; +var hudTimeline; +function timelineEnter(name) { + timeline && timeline.enter(name); + hudTimeline && hudTimeline.enter(name); +} +function timelineLeave(name) { + timeline && timeline.leave(name); + hudTimeline && hudTimeline.leave(name); +} +function timelineWrapBroadcastMessage(domain, message) { + timelineEnter(message); + domain.broadcastMessage(message); + timelineLeave(message); +} +function initializeHUD(stage, parentCanvas) { + var canvas = document.createElement('canvas'); + var canvasContainer = document.createElement('div'); + canvasContainer.appendChild(canvas); + canvasContainer.style.position = 'absolute'; + canvasContainer.style.top = '0px'; + canvasContainer.style.left = '0px'; + canvasContainer.style.width = '100%'; + canvasContainer.style.height = '150px'; + canvasContainer.style.backgroundColor = 'rgba(0, 0, 0, 0.4)'; + canvasContainer.style.pointerEvents = 'none'; + parentCanvas.parentElement.appendChild(canvasContainer); + hudTimeline = new Timeline(canvas); + hudTimeline.setFrameRate(stage._frameRate); + hudTimeline.refreshEvery(10); +} +function createRenderDummyBalls(ctx, stage) { + var dummyBalls; + var radius = 10; + var speed = 1; + var m = stage._concatenatedTransform; + var scaleX = m.a, scaleY = m.d; + dummyBalls = []; + for (var i = 0; i < 10; i++) { + dummyBalls.push({ + position: { + x: radius + Math.random() * ((ctx.canvas.width - 2 * radius) / scaleX), + y: radius + Math.random() * ((ctx.canvas.height - 2 * radius) / scaleY) + }, + velocity: { + x: speed * (Math.random() - 0.5), + y: speed * (Math.random() - 0.5) + } + }); + } + ctx.fillStyle = 'black'; + ctx.lineWidth = 2; + ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); + return function renderDummyBalls() { + ctx.fillStyle = 'black'; + ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); + ctx.strokeStyle = 'green'; + dummyBalls.forEach(function (ball) { + var position = ball.position; + var velocity = ball.velocity; + ctx.beginPath(); + ctx.arc(position.x, position.y, radius, 0, Math.PI * 2, true); + ctx.stroke(); + var x = position.x + velocity.x; + var y = position.y + velocity.y; + if (x < radius || x > ctx.canvas.width / scaleX - radius) { + velocity.x *= -1; + } + if (y < radius || y > ctx.canvas.height / scaleY - radius) { + velocity.y *= -1; + } + position.x += velocity.x; + position.y += velocity.y; + }); + }; +} +function renderStage(stage, ctx, events) { + var frameWidth, frameHeight; + if (!timeline && hud.value) { + initializeHUD(stage, ctx.canvas); + } + function updateRenderTransform() { + frameWidth = ctx.canvas.width; + frameHeight = ctx.canvas.height; + var scaleX = frameWidth / stage._stageWidth * 20; + var scaleY = frameHeight / stage._stageHeight * 20; + switch (stage._scaleMode) { + case 'exactFit': + break; + case 'noBorder': + if (scaleX > scaleY) { + scaleY = scaleX; + } else { + scaleX = scaleY; + } + break; + case 'noScale': + var pixelRatio = ctx.canvas._pixelRatio || 1; + scaleX = pixelRatio; + scaleY = pixelRatio; + break; + case 'showAll': + if (scaleX < scaleY) { + scaleY = scaleX; + } else { + scaleX = scaleY; + } + break; + } + var align = stage._align; + var offsetX, offsetY; + if (align.indexOf('L') >= 0) { + offsetX = 0; + } else if (align.indexOf('R') >= 0) { + offsetX = frameWidth - scaleX * stage._stageWidth / 20; + } else { + offsetX = (frameWidth - scaleX * stage._stageWidth / 20) / 2; + } + if (align.indexOf('T') >= 0) { + offsetY = 0; + } else if (align.indexOf('B') >= 0) { + offsetY = frameHeight - scaleY * stage._stageHeight / 20; + } else { + offsetY = (frameHeight - scaleY * stage._stageHeight / 20) / 2; + } + ctx.setTransform(scaleX, 0, 0, scaleY, offsetX, offsetY); + var m = stage._concatenatedTransform; + m.a = scaleX; + m.d = scaleY; + m.tx = offsetX * 20; + m.ty = offsetY * 20; + } + updateRenderTransform(); + var frameScheduler = new FrameScheduler(); + stage._frameScheduler = frameScheduler; + var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || window.setTimeout; + var renderDummyBalls = dummyAnimation.value && createRenderDummyBalls(ctx, stage); + console.timeEnd('Initialize Renderer'); + console.timeEnd('Total'); + var firstRun = true; + var frameCount = 0; + var frameFPSAverage = new Shumway.Metrics.Average(120); + var frameRequested = true; + function drawFrame(renderFrame, repaint) { + sampleStart(); + var refreshStage = false; + if (stage._invalid) { + updateRenderTransform(); + stage._invalid = false; + refreshStage = true; + } + var mouseMoved = false; + if (stage._mouseMoved) { + stage._mouseMoved = false; + mouseMoved = stage._mouseOver; + } else { + stage._handleMouseButtons(); + } + if (renderFrame || refreshStage || mouseMoved) { + FrameCounter.clear(); + var frameStartTime = performance.now(); + timelineEnter('frame'); + traceRenderer.value && appendToFrameTerminal('Begin Frame #' + frameCount++, 'purple'); + var domain = avm2.systemDomain; + if (renderFrame) { + timelineEnter('events'); + if (firstRun) { + firstRun = false; + } else { + enableAdvanceFrame.value && timelineWrapBroadcastMessage(domain, 'advanceFrame'); + enableEnterFrame.value && timelineWrapBroadcastMessage(domain, 'enterFrame'); + enableConstructChildren.value && timelineWrapBroadcastMessage(domain, 'constructChildren'); + } + timelineWrapBroadcastMessage(domain, 'frameConstructed'); + timelineWrapBroadcastMessage(domain, 'executeFrame'); + timelineWrapBroadcastMessage(domain, 'exitFrame'); + timelineLeave('events'); + } + if (stage._deferRenderEvent) { + stage._deferRenderEvent = false; + domain.broadcastMessage('render', 'render'); + } + var drawEnabled = isCanvasVisible(ctx.canvas) && (refreshStage || renderFrame) && (frameRequested || repaint || !skipFrameDraw.value); + if (drawEnabled && !repaint && skipFrameDraw.value && frameScheduler.shallSkipDraw) { + drawEnabled = false; + frameScheduler.skipDraw(); + traceRenderer.value && appendToFrameTerminal('Skip Frame Draw', 'red'); + } + if (drawEnabled) { + frameScheduler.startDraw(); + var invalidPath = null; + traceRenderer.value && frameWriter.enter('> Invalidation'); + timelineEnter('invalidate'); + invalidPath = stage._processInvalidations(refreshStage); + timelineLeave('invalidate'); + traceRenderer.value && frameWriter.leave('< Invalidation'); + if (!disableRenderVisitor.value && !invalidPath.isEmpty) { + timelineEnter('render'); + traceRenderer.value && frameWriter.enter('> Rendering'); + new RenderVisitor(stage, ctx, invalidPath, refreshStage).start(); + traceRenderer.value && frameWriter.leave('< Rendering'); + timelineLeave('render'); + } + if (showQuadTree.value) { + ctx.strokeStyle = 'green'; + renderQuadTree(ctx, stage._qtree); + } + if (invalidPath && !refreshStage && showRedrawRegions.value) { + ctx.strokeStyle = 'red'; + invalidPath.draw(ctx); + ctx.stroke(); + } + frameScheduler.endDraw(); + } + if (mouseMoved && !disableMouseVisitor.value) { + renderFrame && timelineEnter('mouse'); + traceRenderer.value && frameWriter.enter('> Mouse Handling'); + stage._handleMouse(); + traceRenderer.value && frameWriter.leave('< Mouse Handling'); + renderFrame && timelineLeave('mouse'); + ctx.canvas.style.cursor = stage._cursor; + } + if (traceRenderer.value) { + frameWriter.enter('> Frame Counters'); + for (var name in FrameCounter.counts) { + frameWriter.writeLn(name + ': ' + FrameCounter.counts[name]); + } + frameWriter.leave('< Frame Counters'); + var frameElapsedTime = performance.now() - frameStartTime; + var frameFPS = 1000 / frameElapsedTime; + frameFPSAverage.push(frameFPS); + traceRenderer.value && appendToFrameTerminal('End Frame Time: ' + frameElapsedTime.toFixed(2) + ' (' + frameFPS.toFixed(2) + ' fps, ' + frameFPSAverage.average().toFixed(2) + ' average fps)', 'purple'); + } + timelineLeave('frame'); + } else { + traceRenderer.value && appendToFrameTerminal('Skip Frame', 'black'); + } + sampleEnd(); + } + (function draw() { + var renderFrame = true; + if (events.onBeforeFrame) { + var e = { + cancel: false + }; + events.onBeforeFrame(e); + renderFrame = !e.cancel; + } + if (renderDummyBalls) { + if (renderFrame) { + renderDummyBalls(); + events.onAfterFrame && events.onAfterFrame(); + } + setTimeout(draw); + return; + } + frameScheduler.startFrame(stage._frameRate); + drawFrame(renderFrame, false); + frameScheduler.endFrame(); + frameRequested = false; + if (!frameScheduler.isOnTime) { + traceRenderer.value && appendToFrameTerminal('Frame Is Late', 'red'); + } + if (renderFrame && events.onAfterFrame) { + events.onAfterFrame(); + } + if (renderingTerminated) { + if (events.onTerminated) { + events.onTerminated(); + } + return; + } + setTimeout(draw, turboMode.value ? 0 : frameScheduler.nextFrameIn); + }()); + (function frame() { + if (renderingTerminated) { + return; + } + frameRequested = true; + if ((stage._invalid || stage._mouseMoved) && !renderDummyBalls) { + drawFrame(false, true); + } + requestAnimationFrame(frame); + }()); +} +var FrameScheduler = function () { + var STATS_TO_REMEMBER = 50; + var MAX_DRAWS_TO_SKIP = 2; + var INTERVAL_PADDING_MS = 4; + var SPEED_ADJUST_RATE = 0.9; + function FrameScheduler() { + this._drawStats = []; + this._drawStatsSum = 0; + this._drawStarted = 0; + this._drawsSkipped = 0; + this._expectedNextFrameAt = performance.now(); + this._onTime = true; + this._trackDelta = false; + this._delta = 0; + this._onTimeDelta = 0; + } + FrameScheduler.prototype = { + get shallSkipDraw() { + if (this._drawsSkipped >= MAX_DRAWS_TO_SKIP) { + return false; + } + var averageDraw = this._drawStats.length < STATS_TO_REMEMBER ? 0 : this._drawStatsSum / this._drawStats.length; + var estimatedDrawEnd = performance.now() + averageDraw; + return estimatedDrawEnd + INTERVAL_PADDING_MS > this._expectedNextFrameAt; + }, + get nextFrameIn() { + return Math.max(0, this._expectedNextFrameAt - performance.now()); + }, + get isOnTime() { + return this._onTime; + }, + startFrame: function (frameRate) { + var interval = 1000 / frameRate; + var adjustedInterval = interval; + var delta = this._onTimeDelta + this._delta; + if (delta !== 0) { + if (delta < 0) { + adjustedInterval *= SPEED_ADJUST_RATE; + } else if (delta > 0) { + adjustedInterval /= SPEED_ADJUST_RATE; + } + this._onTimeDelta += interval - adjustedInterval; + } + this._expectedNextFrameAt += adjustedInterval; + this._onTime = true; + }, + endFrame: function () { + var estimatedNextFrameStart = performance.now() + INTERVAL_PADDING_MS; + if (estimatedNextFrameStart > this._expectedNextFrameAt) { + if (this._trackDelta) { + this._onTimeDelta += this._expectedNextFrameAt - estimatedNextFrameStart; + console.log(this._onTimeDelta); + } + this._expectedNextFrameAt = estimatedNextFrameStart; + this._onTime = false; + } + }, + startDraw: function () { + this._drawsSkipped = 0; + this._drawStarted = performance.now(); + }, + endDraw: function () { + var drawTime = performance.now() - this._drawStarted; + this._drawStats.push(drawTime); + this._drawStatsSum += drawTime; + while (this._drawStats.length > STATS_TO_REMEMBER) { + this._drawStatsSum -= this._drawStats.shift(); + } + }, + skipDraw: function () { + this._drawsSkipped++; + }, + setDelta: function (value) { + if (!this._trackDelta) { + return; + } + this._delta = value; + }, + startTrackDelta: function () { + this._trackDelta = true; + }, + endTrackDelta: function () { + if (!this._trackDelta) { + return; + } + this._trackDelta = false; + this._delta = 0; + this._onTimeDelta = 0; + } + }; + return FrameScheduler; + }(); +var tagHandler = function (global) { + function defineShape($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.id = readUi16($bytes, $stream); + var $0 = $.bbox = {}; + bbox($bytes, $stream, $0, swfVersion, tagCode); + var isMorph = $.isMorph = tagCode === 46 || tagCode === 84; + if (isMorph) { + var $1 = $.bboxMorph = {}; + bbox($bytes, $stream, $1, swfVersion, tagCode); + } + var hasStrokes = $.hasStrokes = tagCode === 83 || tagCode === 84; + if (hasStrokes) { + var $2 = $.strokeBbox = {}; + bbox($bytes, $stream, $2, swfVersion, tagCode); + if (isMorph) { + var $3 = $.strokeBboxMorph = {}; + bbox($bytes, $stream, $3, swfVersion, tagCode); + } + var reserved = readUb($bytes, $stream, 5); + $.fillWinding = readUb($bytes, $stream, 1); + $.nonScalingStrokes = readUb($bytes, $stream, 1); + $.scalingStrokes = readUb($bytes, $stream, 1); + } + if (isMorph) { + $.offsetMorph = readUi32($bytes, $stream); + morphShapeWithStyle($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes); + } else { + shapeWithStyle($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes); + } + return $; + } + function placeObject($bytes, $stream, $, swfVersion, tagCode) { + var flags, hasEvents, clip, hasName, hasRatio, hasCxform, hasMatrix, place; + var move, hasBackgroundColor, hasVisibility, hasImage, hasClassName, cache; + var blend, hasFilters, eoe; + $ || ($ = {}); + if (tagCode > 4) { + if (tagCode > 26) { + flags = readUi16($bytes, $stream); + } else { + flags = readUi8($bytes, $stream); + } + hasEvents = $.hasEvents = flags >> 7 & 1; + clip = $.clip = flags >> 6 & 1; + hasName = $.hasName = flags >> 5 & 1; + hasRatio = $.hasRatio = flags >> 4 & 1; + hasCxform = $.hasCxform = flags >> 3 & 1; + hasMatrix = $.hasMatrix = flags >> 2 & 1; + place = $.place = flags >> 1 & 1; + move = $.move = flags & 1; + if (tagCode === 70) { + hasBackgroundColor = $.hasBackgroundColor = flags >> 15 & 1; + hasVisibility = $.hasVisibility = flags >> 14 & 1; + hasImage = $.hasImage = flags >> 12 & 1; + hasClassName = $.hasClassName = flags >> 11 & 1; + cache = $.cache = flags >> 10 & 1; + blend = $.blend = flags >> 9 & 1; + hasFilters = $.hasFilters = flags >> 8 & 1; + } else { + cache = $.cache = 0; + blend = $.blend = 0; + hasFilters = $.hasFilters = 0; + } + $.depth = readUi16($bytes, $stream); + if (hasClassName) { + $.className = readString($bytes, $stream, 0); + } + if (place) { + $.symbolId = readUi16($bytes, $stream); + } + if (hasMatrix) { + var $0 = $.matrix = {}; + matrix($bytes, $stream, $0, swfVersion, tagCode); + } + if (hasCxform) { + var $1 = $.cxform = {}; + cxform($bytes, $stream, $1, swfVersion, tagCode); + } + if (hasRatio) { + $.ratio = readUi16($bytes, $stream); + } + if (hasName) { + $.name = readString($bytes, $stream, 0); + } + if (clip) { + $.clipDepth = readUi16($bytes, $stream); + } + if (hasFilters) { + var count = readUi8($bytes, $stream); + var $2 = $.filters = []; + var $3 = count; + while ($3--) { + var $4 = {}; + anyFilter($bytes, $stream, $4, swfVersion, tagCode); + $2.push($4); + } + } + if (blend) { + $.blendMode = readUi8($bytes, $stream); + } + if (cache) { + $.bmpCache = readUi8($bytes, $stream); + } + if (hasEvents) { + var reserved = readUi16($bytes, $stream); + if (swfVersion >= 6) { + var allFlags = readUi32($bytes, $stream); + } else { + var allFlags = readUi16($bytes, $stream); + } + var $28 = $.events = []; + do { + var $29 = {}; + var temp = events($bytes, $stream, $29, swfVersion, tagCode); + eoe = temp.eoe; + $28.push($29); + } while (!eoe); + } + if (hasBackgroundColor) { + var $126 = $.backgroundColor = {}; + argb($bytes, $stream, $126, swfVersion, tagCode); + } + if (hasVisibility) { + $.visibility = readUi8($bytes, $stream); + } + } else { + $.place = 1; + $.symbolId = readUi16($bytes, $stream); + $.depth = readUi16($bytes, $stream); + $.hasMatrix = 1; + var $30 = $.matrix = {}; + matrix($bytes, $stream, $30, swfVersion, tagCode); + if ($stream.remaining()) { + $.hasCxform = 1; + var $31 = $.cxform = {}; + cxform($bytes, $stream, $31, swfVersion, tagCode); + } + } + return $; + } + function removeObject($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + if (tagCode === 5) { + $.symbolId = readUi16($bytes, $stream); + } + $.depth = readUi16($bytes, $stream); + return $; + } + function defineImage($bytes, $stream, $, swfVersion, tagCode) { + var imgData; + $ || ($ = {}); + $.id = readUi16($bytes, $stream); + if (tagCode > 21) { + var alphaDataOffset = readUi32($bytes, $stream); + if (tagCode === 90) { + $.deblock = readFixed8($bytes, $stream); + } + imgData = $.imgData = readBinary($bytes, $stream, alphaDataOffset); + $.alphaData = readBinary($bytes, $stream, 0); + } else { + imgData = $.imgData = readBinary($bytes, $stream, 0); + } + switch (imgData[0] << 8 | imgData[1]) { + case 65496: + case 65497: + $.mimeType = 'image/jpeg'; + break; + case 35152: + $.mimeType = 'image/png'; + break; + case 18249: + $.mimeType = 'image/gif'; + break; + default: + $.mimeType = 'application/octet-stream'; + } + if (tagCode === 6) { + $.incomplete = 1; + } + return $; + } + function defineButton($bytes, $stream, $, swfVersion, tagCode) { + var eob, hasFilters, count, blend; + $ || ($ = {}); + $.id = readUi16($bytes, $stream); + if (tagCode == 7) { + var $0 = $.characters = []; + do { + var $1 = {}; + var temp = button($bytes, $stream, $1, swfVersion, tagCode); + eob = temp.eob; + $0.push($1); + } while (!eob); + $.actionsData = readBinary($bytes, $stream, 0); + } else { + var trackFlags = readUi8($bytes, $stream); + $.trackAsMenu = trackFlags >> 7 & 1; + var actionOffset = readUi16($bytes, $stream); + var $28 = $.characters = []; + do { + var $29 = {}; + var flags = readUi8($bytes, $stream); + var eob = $29.eob = !flags; + if (swfVersion >= 8) { + blend = $29.blend = flags >> 5 & 1; + hasFilters = $29.hasFilters = flags >> 4 & 1; + } else { + blend = $29.blend = 0; + hasFilters = $29.hasFilters = 0; + } + $29.stateHitTest = flags >> 3 & 1; + $29.stateDown = flags >> 2 & 1; + $29.stateOver = flags >> 1 & 1; + $29.stateUp = flags & 1; + if (!eob) { + $29.symbolId = readUi16($bytes, $stream); + $29.depth = readUi16($bytes, $stream); + var $30 = $29.matrix = {}; + matrix($bytes, $stream, $30, swfVersion, tagCode); + if (tagCode === 34) { + var $31 = $29.cxform = {}; + cxform($bytes, $stream, $31, swfVersion, tagCode); + } + if (hasFilters) { + var count = readUi8($bytes, $stream); + var $2 = $.filters = []; + var $3 = count; + while ($3--) { + var $4 = {}; + anyFilter($bytes, $stream, $4, swfVersion, tagCode); + $2.push($4); + } + } + if (blend) { + $29.blendMode = readUi8($bytes, $stream); + } + } + $28.push($29); + } while (!eob); + if (!(!actionOffset)) { + var $56 = $.buttonActions = []; + do { + var $57 = {}; + buttonCondAction($bytes, $stream, $57, swfVersion, tagCode); + $56.push($57); + } while ($stream.remaining() > 0); + } + } + return $; + } + function defineJPEGTables($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.id = 0; + $.imgData = readBinary($bytes, $stream, 0); + $.mimeType = 'application/octet-stream'; + return $; + } + function setBackgroundColor($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + var $0 = $.color = {}; + rgb($bytes, $stream, $0, swfVersion, tagCode); + return $; + } + function defineBinaryData($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.id = readUi16($bytes, $stream); + var reserved = readUi32($bytes, $stream); + $.data = readBinary($bytes, $stream, 0); + return $; + } + function defineFont($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.id = readUi16($bytes, $stream); + var firstOffset = readUi16($bytes, $stream); + var glyphCount = $.glyphCount = firstOffset / 2; + var restOffsets = []; + var $0 = glyphCount - 1; + while ($0--) { + restOffsets.push(readUi16($bytes, $stream)); + } + $.offsets = [ + firstOffset + ].concat(restOffsets); + var $1 = $.glyphs = []; + var $2 = glyphCount; + while ($2--) { + var $3 = {}; + shape($bytes, $stream, $3, swfVersion, tagCode); + $1.push($3); + } + return $; + } + function defineLabel($bytes, $stream, $, swfVersion, tagCode) { + var eot; + $ || ($ = {}); + $.id = readUi16($bytes, $stream); + var $0 = $.bbox = {}; + bbox($bytes, $stream, $0, swfVersion, tagCode); + var $1 = $.matrix = {}; + matrix($bytes, $stream, $1, swfVersion, tagCode); + var glyphBits = $.glyphBits = readUi8($bytes, $stream); + var advanceBits = $.advanceBits = readUi8($bytes, $stream); + var $2 = $.records = []; + do { + var $3 = {}; + var temp = textRecord($bytes, $stream, $3, swfVersion, tagCode, glyphBits, advanceBits); + eot = temp.eot; + $2.push($3); + } while (!eot); + return $; + } + function doAction($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + if (tagCode === 59) { + $.spriteId = readUi16($bytes, $stream); + } + $.actionsData = readBinary($bytes, $stream, 0); + return $; + } + function defineSound($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.id = readUi16($bytes, $stream); + var soundFlags = readUi8($bytes, $stream); + $.soundFormat = soundFlags >> 4 & 15; + $.soundRate = soundFlags >> 2 & 3; + $.soundSize = soundFlags >> 1 & 1; + $.soundType = soundFlags & 1; + $.samplesCount = readUi32($bytes, $stream); + $.soundData = readBinary($bytes, $stream, 0); + return $; + } + function startSound($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + if (tagCode == 15) { + $.soundId = readUi16($bytes, $stream); + } + if (tagCode == 89) { + $.soundClassName = readString($bytes, $stream, 0); + } + var $0 = $.soundInfo = {}; + soundInfo($bytes, $stream, $0, swfVersion, tagCode); + return $; + } + function soundStreamHead($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + var playbackFlags = readUi8($bytes, $stream); + $.playbackRate = playbackFlags >> 2 & 3; + $.playbackSize = playbackFlags >> 1 & 1; + $.playbackType = playbackFlags & 1; + var streamFlags = readUi8($bytes, $stream); + var streamCompression = $.streamCompression = streamFlags >> 4 & 15; + $.streamRate = streamFlags >> 2 & 3; + $.streamSize = streamFlags >> 1 & 1; + $.streamType = streamFlags & 1; + $.samplesCount = readUi32($bytes, $stream); + if (streamCompression == 2) { + $.latencySeek = readSi16($bytes, $stream); + } + return $; + } + function soundStreamBlock($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.data = readBinary($bytes, $stream, 0); + return $; + } + function defineBitmap($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.id = readUi16($bytes, $stream); + var format = $.format = readUi8($bytes, $stream); + $.width = readUi16($bytes, $stream); + $.height = readUi16($bytes, $stream); + $.hasAlpha = tagCode === 36; + if (format === 3) { + $.colorTableSize = readUi8($bytes, $stream); + } + $.bmpData = readBinary($bytes, $stream, 0); + return $; + } + function defineText($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.id = readUi16($bytes, $stream); + var $0 = $.bbox = {}; + bbox($bytes, $stream, $0, swfVersion, tagCode); + var flags = readUi16($bytes, $stream); + var hasText = $.hasText = flags >> 7 & 1; + $.wordWrap = flags >> 6 & 1; + $.multiline = flags >> 5 & 1; + $.password = flags >> 4 & 1; + $.readonly = flags >> 3 & 1; + var hasColor = $.hasColor = flags >> 2 & 1; + var hasMaxLength = $.hasMaxLength = flags >> 1 & 1; + var hasFont = $.hasFont = flags & 1; + var hasFontClass = $.hasFontClass = flags >> 15 & 1; + $.autoSize = flags >> 14 & 1; + var hasLayout = $.hasLayout = flags >> 13 & 1; + $.noSelect = flags >> 12 & 1; + $.border = flags >> 11 & 1; + $.wasStatic = flags >> 10 & 1; + $.html = flags >> 9 & 1; + $.useOutlines = flags >> 8 & 1; + if (hasFont) { + $.fontId = readUi16($bytes, $stream); + } + if (hasFontClass) { + $.fontClass = readString($bytes, $stream, 0); + } + if (hasFont) { + $.fontHeight = readUi16($bytes, $stream); + } + if (hasColor) { + var $1 = $.color = {}; + rgba($bytes, $stream, $1, swfVersion, tagCode); + } + if (hasMaxLength) { + $.maxLength = readUi16($bytes, $stream); + } + if (hasLayout) { + $.align = readUi8($bytes, $stream); + $.leftMargin = readUi16($bytes, $stream); + $.rightMargin = readUi16($bytes, $stream); + $.indent = readSi16($bytes, $stream); + $.leading = readSi16($bytes, $stream); + } + $.variableName = readString($bytes, $stream, 0); + if (hasText) { + $.initialText = readString($bytes, $stream, 0); + } + return $; + } + function frameLabel($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.name = readString($bytes, $stream, 0); + return $; + } + function defineFont2($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.id = readUi16($bytes, $stream); + var hasLayout = $.hasLayout = readUb($bytes, $stream, 1); + if (swfVersion > 5) { + $.shiftJis = readUb($bytes, $stream, 1); + } else { + var reserved = readUb($bytes, $stream, 1); + } + $.smallText = readUb($bytes, $stream, 1); + $.ansi = readUb($bytes, $stream, 1); + var wideOffset = $.wideOffset = readUb($bytes, $stream, 1); + var wide = $.wide = readUb($bytes, $stream, 1); + $.italic = readUb($bytes, $stream, 1); + $.bold = readUb($bytes, $stream, 1); + if (swfVersion > 5) { + $.language = readUi8($bytes, $stream); + } else { + var reserved = readUi8($bytes, $stream); + $.language = 0; + } + var nameLength = readUi8($bytes, $stream); + $.name = readString($bytes, $stream, nameLength); + if (tagCode === 75) { + $.resolution = 20; + } + var glyphCount = $.glyphCount = readUi16($bytes, $stream); + if (wideOffset) { + var $0 = $.offsets = []; + var $1 = glyphCount; + while ($1--) { + $0.push(readUi32($bytes, $stream)); + } + $.mapOffset = readUi32($bytes, $stream); + } else { + var $2 = $.offsets = []; + var $3 = glyphCount; + while ($3--) { + $2.push(readUi16($bytes, $stream)); + } + $.mapOffset = readUi16($bytes, $stream); + } + var $4 = $.glyphs = []; + var $5 = glyphCount; + while ($5--) { + var $6 = {}; + shape($bytes, $stream, $6, swfVersion, tagCode); + $4.push($6); + } + if (wide) { + var $47 = $.codes = []; + var $48 = glyphCount; + while ($48--) { + $47.push(readUi16($bytes, $stream)); + } + } else { + var $49 = $.codes = []; + var $50 = glyphCount; + while ($50--) { + $49.push(readUi8($bytes, $stream)); + } + } + if (hasLayout) { + $.ascent = readUi16($bytes, $stream); + $.descent = readUi16($bytes, $stream); + $.leading = readSi16($bytes, $stream); + var $51 = $.advance = []; + var $52 = glyphCount; + while ($52--) { + $51.push(readSi16($bytes, $stream)); + } + var $53 = $.bbox = []; + var $54 = glyphCount; + while ($54--) { + var $55 = {}; + bbox($bytes, $stream, $55, swfVersion, tagCode); + $53.push($55); + } + var kerningCount = readUi16($bytes, $stream); + var $56 = $.kerning = []; + var $57 = kerningCount; + while ($57--) { + var $58 = {}; + kerning($bytes, $stream, $58, swfVersion, tagCode, wide); + $56.push($58); + } + } + return $; + } + function fileAttributes($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + var reserved = readUb($bytes, $stream, 1); + $.useDirectBlit = readUb($bytes, $stream, 1); + $.useGpu = readUb($bytes, $stream, 1); + $.hasMetadata = readUb($bytes, $stream, 1); + $.doAbc = readUb($bytes, $stream, 1); + $.noCrossDomainCaching = readUb($bytes, $stream, 1); + $.relativeUrls = readUb($bytes, $stream, 1); + $.network = readUb($bytes, $stream, 1); + var pad = readUb($bytes, $stream, 24); + return $; + } + function doABC($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + if (tagCode === 82) { + $.flags = readUi32($bytes, $stream); + } else { + $.flags = 0; + } + if (tagCode === 82) { + $.name = readString($bytes, $stream, 0); + } else { + $.name = ''; + } + $.data = readBinary($bytes, $stream, 0); + return $; + } + function exportAssets($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + var exportsCount = readUi16($bytes, $stream); + var $0 = $.exports = []; + var $1 = exportsCount; + while ($1--) { + var $2 = {}; + $2.symbolId = readUi16($bytes, $stream); + $2.className = readString($bytes, $stream, 0); + $0.push($2); + } + return $; + } + function symbolClass($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + var symbolCount = readUi16($bytes, $stream); + var $0 = $.exports = []; + var $1 = symbolCount; + while ($1--) { + var $2 = {}; + $2.symbolId = readUi16($bytes, $stream); + $2.className = readString($bytes, $stream, 0); + $0.push($2); + } + return $; + } + function defineScalingGrid($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + $.symbolId = readUi16($bytes, $stream); + var $0 = $.splitter = {}; + bbox($bytes, $stream, $0, swfVersion, tagCode); + return $; + } + function defineScene($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + var sceneCount = readEncodedU32($bytes, $stream); + var $0 = $.scenes = []; + var $1 = sceneCount; + while ($1--) { + var $2 = {}; + $2.offset = readEncodedU32($bytes, $stream); + $2.name = readString($bytes, $stream, 0); + $0.push($2); + } + var labelCount = readEncodedU32($bytes, $stream); + var $3 = $.labels = []; + var $4 = labelCount; + while ($4--) { + var $5 = {}; + $5.frame = readEncodedU32($bytes, $stream); + $5.name = readString($bytes, $stream, 0); + $3.push($5); + } + return $; + } + function bbox($bytes, $stream, $, swfVersion, tagCode) { + align($bytes, $stream); + var bits = readUb($bytes, $stream, 5); + var xMin = readSb($bytes, $stream, bits); + var xMax = readSb($bytes, $stream, bits); + var yMin = readSb($bytes, $stream, bits); + var yMax = readSb($bytes, $stream, bits); + $.xMin = xMin; + $.xMax = xMax; + $.yMin = yMin; + $.yMax = yMax; + align($bytes, $stream); + } + function rgb($bytes, $stream, $, swfVersion, tagCode) { + $.red = readUi8($bytes, $stream); + $.green = readUi8($bytes, $stream); + $.blue = readUi8($bytes, $stream); + $.alpha = 255; + return; + } + function rgba($bytes, $stream, $, swfVersion, tagCode) { + $.red = readUi8($bytes, $stream); + $.green = readUi8($bytes, $stream); + $.blue = readUi8($bytes, $stream); + $.alpha = readUi8($bytes, $stream); + return; + } + function argb($bytes, $stream, $, swfVersion, tagCode) { + $.alpha = readUi8($bytes, $stream); + $.red = readUi8($bytes, $stream); + $.green = readUi8($bytes, $stream); + $.blue = readUi8($bytes, $stream); + } + function fillSolid($bytes, $stream, $, swfVersion, tagCode, isMorph) { + if (tagCode > 22 || isMorph) { + var $125 = $.color = {}; + rgba($bytes, $stream, $125, swfVersion, tagCode); + } else { + var $126 = $.color = {}; + rgb($bytes, $stream, $126, swfVersion, tagCode); + } + if (isMorph) { + var $127 = $.colorMorph = {}; + rgba($bytes, $stream, $127, swfVersion, tagCode); + } + return; + } + function matrix($bytes, $stream, $, swfVersion, tagCode) { + align($bytes, $stream); + var hasScale = readUb($bytes, $stream, 1); + if (hasScale) { + var bits = readUb($bytes, $stream, 5); + $.a = readFb($bytes, $stream, bits); + $.d = readFb($bytes, $stream, bits); + } else { + $.a = 1; + $.d = 1; + } + var hasRotate = readUb($bytes, $stream, 1); + if (hasRotate) { + var bits = readUb($bytes, $stream, 5); + $.b = readFb($bytes, $stream, bits); + $.c = readFb($bytes, $stream, bits); + } else { + $.b = 0; + $.c = 0; + } + var bits = readUb($bytes, $stream, 5); + var e = readSb($bytes, $stream, bits); + var f = readSb($bytes, $stream, bits); + $.tx = e; + $.ty = f; + align($bytes, $stream); + } + function cxform($bytes, $stream, $, swfVersion, tagCode) { + align($bytes, $stream); + var hasOffsets = readUb($bytes, $stream, 1); + var hasMultipliers = readUb($bytes, $stream, 1); + var bits = readUb($bytes, $stream, 4); + if (hasMultipliers) { + $.redMultiplier = readSb($bytes, $stream, bits); + $.greenMultiplier = readSb($bytes, $stream, bits); + $.blueMultiplier = readSb($bytes, $stream, bits); + if (tagCode > 4) { + $.alphaMultiplier = readSb($bytes, $stream, bits); + } else { + $.alphaMultiplier = 256; + } + } else { + $.redMultiplier = 256; + $.greenMultiplier = 256; + $.blueMultiplier = 256; + $.alphaMultiplier = 256; + } + if (hasOffsets) { + $.redOffset = readSb($bytes, $stream, bits); + $.greenOffset = readSb($bytes, $stream, bits); + $.blueOffset = readSb($bytes, $stream, bits); + if (tagCode > 4) { + $.alphaOffset = readSb($bytes, $stream, bits); + } else { + $.alphaOffset = 0; + } + } else { + $.redOffset = 0; + $.greenOffset = 0; + $.blueOffset = 0; + $.alphaOffset = 0; + } + align($bytes, $stream); + } + function fillGradient($bytes, $stream, $, swfVersion, tagCode, isMorph, type) { + var $128 = $.matrix = {}; + matrix($bytes, $stream, $128, swfVersion, tagCode); + if (isMorph) { + var $129 = $.matrixMorph = {}; + matrix($bytes, $stream, $129, swfVersion, tagCode); + } + gradient($bytes, $stream, $, swfVersion, tagCode, isMorph, type); + } + function gradient($bytes, $stream, $, swfVersion, tagCode, isMorph, type) { + if (tagCode === 83) { + $.spreadMode = readUb($bytes, $stream, 2); + $.interpolationMode = readUb($bytes, $stream, 2); + } else { + var pad = readUb($bytes, $stream, 4); + } + var count = $.count = readUb($bytes, $stream, 4); + var $130 = $.records = []; + var $131 = count; + while ($131--) { + var $132 = {}; + gradientRecord($bytes, $stream, $132, swfVersion, tagCode, isMorph); + $130.push($132); + } + if (type === 19) { + $.focalPoint = readFixed8($bytes, $stream); + if (isMorph) { + $.focalPointMorph = readFixed8($bytes, $stream); + } + } + } + function gradientRecord($bytes, $stream, $, swfVersion, tagCode, isMorph) { + $.ratio = readUi8($bytes, $stream); + if (tagCode > 22) { + var $133 = $.color = {}; + rgba($bytes, $stream, $133, swfVersion, tagCode); + } else { + var $134 = $.color = {}; + rgb($bytes, $stream, $134, swfVersion, tagCode); + } + if (isMorph) { + $.ratioMorph = readUi8($bytes, $stream); + var $135 = $.colorMorph = {}; + rgba($bytes, $stream, $135, swfVersion, tagCode); + } + } + function morphShapeWithStyle($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes) { + var eos, bits; + var temp = styles($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes); + var lineBits = temp.lineBits; + var fillBits = temp.fillBits; + var $160 = $.records = []; + do { + var $161 = {}; + var temp = shapeRecord($bytes, $stream, $161, swfVersion, tagCode, isMorph, fillBits, lineBits, hasStrokes, bits); + var eos = temp.eos; + var flags = temp.flags; + var type = temp.type; + var fillBits = temp.fillBits; + var lineBits = temp.lineBits; + var bits = temp.bits; + $160.push($161); + } while (!eos); + var temp = styleBits($bytes, $stream, $, swfVersion, tagCode); + var fillBits = temp.fillBits; + var lineBits = temp.lineBits; + var $162 = $.recordsMorph = []; + do { + var $163 = {}; + var temp = shapeRecord($bytes, $stream, $163, swfVersion, tagCode, isMorph, fillBits, lineBits, hasStrokes, bits); + eos = temp.eos; + var flags = temp.flags; + var type = temp.type; + var fillBits = temp.fillBits; + var lineBits = temp.lineBits; + bits = temp.bits; + $162.push($163); + } while (!eos); + } + function shapeWithStyle($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes) { + var eos; + var temp = styles($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes); + var fillBits = temp.fillBits; + var lineBits = temp.lineBits; + var $160 = $.records = []; + do { + var $161 = {}; + var temp = shapeRecord($bytes, $stream, $161, swfVersion, tagCode, isMorph, fillBits, lineBits, hasStrokes, bits); + eos = temp.eos; + var flags = temp.flags; + var type = temp.type; + var fillBits = temp.fillBits; + var lineBits = temp.lineBits; + var bits = temp.bits; + $160.push($161); + } while (!eos); + } + function shapeRecord($bytes, $stream, $, swfVersion, tagCode, isMorph, fillBits, lineBits, hasStrokes, bits) { + var type = $.type = readUb($bytes, $stream, 1); + var flags = readUb($bytes, $stream, 5); + var eos = $.eos = !(type || flags); + if (type) { + var temp = shapeRecordEdge($bytes, $stream, $, swfVersion, tagCode, flags, bits); + var bits = temp.bits; + } else { + var temp = shapeRecordSetup($bytes, $stream, $, swfVersion, tagCode, flags, isMorph, fillBits, lineBits, hasStrokes, bits); + var fillBits = temp.fillBits; + var lineBits = temp.lineBits; + var bits = temp.bits; + } + return { + type: type, + flags: flags, + eos: eos, + fillBits: fillBits, + lineBits: lineBits, + bits: bits + }; + } + function shapeRecordEdge($bytes, $stream, $, swfVersion, tagCode, flags, bits) { + var isStraight = 0, tmp = 0, bits = 0, isGeneral = 0, isVertical = 0; + isStraight = $.isStraight = flags >> 4; + tmp = flags & 15; + bits = tmp + 2; + if (isStraight) { + isGeneral = $.isGeneral = readUb($bytes, $stream, 1); + if (isGeneral) { + $.deltaX = readSb($bytes, $stream, bits); + $.deltaY = readSb($bytes, $stream, bits); + } else { + isVertical = $.isVertical = readUb($bytes, $stream, 1); + if (isVertical) { + $.deltaY = readSb($bytes, $stream, bits); + } else { + $.deltaX = readSb($bytes, $stream, bits); + } + } + } else { + $.controlDeltaX = readSb($bytes, $stream, bits); + $.controlDeltaY = readSb($bytes, $stream, bits); + $.anchorDeltaX = readSb($bytes, $stream, bits); + $.anchorDeltaY = readSb($bytes, $stream, bits); + } + return { + bits: bits + }; + } + function shapeRecordSetup($bytes, $stream, $, swfVersion, tagCode, flags, isMorph, fillBits, lineBits, hasStrokes, bits) { + var hasNewStyles = 0, hasLineStyle = 0, hasFillStyle1 = 0; + var hasFillStyle0 = 0, move = 0; + if (tagCode > 2) { + hasNewStyles = $.hasNewStyles = flags >> 4; + } else { + hasNewStyles = $.hasNewStyles = 0; + } + hasLineStyle = $.hasLineStyle = flags >> 3 & 1; + hasFillStyle1 = $.hasFillStyle1 = flags >> 2 & 1; + hasFillStyle0 = $.hasFillStyle0 = flags >> 1 & 1; + move = $.move = flags & 1; + if (move) { + bits = readUb($bytes, $stream, 5); + $.moveX = readSb($bytes, $stream, bits); + $.moveY = readSb($bytes, $stream, bits); + } + if (hasFillStyle0) { + $.fillStyle0 = readUb($bytes, $stream, fillBits); + } + if (hasFillStyle1) { + $.fillStyle1 = readUb($bytes, $stream, fillBits); + } + if (hasLineStyle) { + $.lineStyle = readUb($bytes, $stream, lineBits); + } + if (hasNewStyles) { + var temp = styles($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes); + var lineBits = temp.lineBits; + var fillBits = temp.fillBits; + } + return { + lineBits: lineBits, + fillBits: fillBits, + bits: bits + }; + } + function styles($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes) { + fillStyleArray($bytes, $stream, $, swfVersion, tagCode, isMorph); + lineStyleArray($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes); + var temp = styleBits($bytes, $stream, $, swfVersion, tagCode); + var fillBits = temp.fillBits; + var lineBits = temp.lineBits; + return { + fillBits: fillBits, + lineBits: lineBits + }; + } + function fillStyleArray($bytes, $stream, $, swfVersion, tagCode, isMorph) { + var count; + var tmp = readUi8($bytes, $stream); + if (tagCode > 2 && tmp === 255) { + count = readUi16($bytes, $stream); + } else { + count = tmp; + } + var $4 = $.fillStyles = []; + var $5 = count; + while ($5--) { + var $6 = {}; + fillStyle($bytes, $stream, $6, swfVersion, tagCode, isMorph); + $4.push($6); + } + } + function lineStyleArray($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes) { + var count; + var tmp = readUi8($bytes, $stream); + if (tagCode > 2 && tmp === 255) { + count = readUi16($bytes, $stream); + } else { + count = tmp; + } + var $138 = $.lineStyles = []; + var $139 = count; + while ($139--) { + var $140 = {}; + lineStyle($bytes, $stream, $140, swfVersion, tagCode, isMorph, hasStrokes); + $138.push($140); + } + } + function styleBits($bytes, $stream, $, swfVersion, tagCode) { + align($bytes, $stream); + var fillBits = readUb($bytes, $stream, 4); + var lineBits = readUb($bytes, $stream, 4); + return { + fillBits: fillBits, + lineBits: lineBits + }; + } + function fillStyle($bytes, $stream, $, swfVersion, tagCode, isMorph) { + var type = $.type = readUi8($bytes, $stream); + switch (type) { + case 0: + fillSolid($bytes, $stream, $, swfVersion, tagCode, isMorph); + break; + case 16: + case 18: + case 19: + fillGradient($bytes, $stream, $, swfVersion, tagCode, isMorph, type); + break; + case 64: + case 65: + case 66: + case 67: + fillBitmap($bytes, $stream, $, swfVersion, tagCode, isMorph, type); + break; + default: + } + } + function lineStyle($bytes, $stream, $, swfVersion, tagCode, isMorph, hasStrokes) { + $.width = readUi16($bytes, $stream); + if (isMorph) { + $.widthMorph = readUi16($bytes, $stream); + } + if (hasStrokes) { + align($bytes, $stream); + $.startCapStyle = readUb($bytes, $stream, 2); + var joinStyle = $.joinStyle = readUb($bytes, $stream, 2); + var hasFill = $.hasFill = readUb($bytes, $stream, 1); + $.noHscale = readUb($bytes, $stream, 1); + $.noVscale = readUb($bytes, $stream, 1); + $.pixelHinting = readUb($bytes, $stream, 1); + var reserved = readUb($bytes, $stream, 5); + $.noClose = readUb($bytes, $stream, 1); + $.endCapStyle = readUb($bytes, $stream, 2); + if (joinStyle === 2) { + $.miterLimitFactor = readFixed8($bytes, $stream); + } + if (hasFill) { + var $141 = $.fillStyle = {}; + fillStyle($bytes, $stream, $141, swfVersion, tagCode, isMorph); + } else { + var $155 = $.color = {}; + rgba($bytes, $stream, $155, swfVersion, tagCode); + if (isMorph) { + var $156 = $.colorMorph = {}; + rgba($bytes, $stream, $156, swfVersion, tagCode); + } + } + } else { + if (tagCode > 22) { + var $157 = $.color = {}; + rgba($bytes, $stream, $157, swfVersion, tagCode); + } else { + var $158 = $.color = {}; + rgb($bytes, $stream, $158, swfVersion, tagCode); + } + if (isMorph) { + var $159 = $.colorMorph = {}; + rgba($bytes, $stream, $159, swfVersion, tagCode); + } + } + } + function fillBitmap($bytes, $stream, $, swfVersion, tagCode, isMorph, type) { + $.bitmapId = readUi16($bytes, $stream); + var $18 = $.matrix = {}; + matrix($bytes, $stream, $18, swfVersion, tagCode); + if (isMorph) { + var $19 = $.matrixMorph = {}; + matrix($bytes, $stream, $19, swfVersion, tagCode); + } + $.condition = type === 64 || type === 67; + } + function filterGlow($bytes, $stream, $, swfVersion, tagCode, type) { + var count; + if (type === 4 || type === 7) { + count = readUi8($bytes, $stream); + } else { + count = 1; + } + var $5 = $.colors = []; + var $6 = count; + while ($6--) { + var $7 = {}; + rgba($bytes, $stream, $7, swfVersion, tagCode); + $5.push($7); + } + if (type === 3) { + var $8 = $.higlightColor = {}; + rgba($bytes, $stream, $8, swfVersion, tagCode); + } + if (type === 4 || type === 7) { + var $9 = $.ratios = []; + var $10 = count; + while ($10--) { + $9.push(readUi8($bytes, $stream)); + } + } + $.blurX = readFixed($bytes, $stream); + $.blurY = readFixed($bytes, $stream); + if (type !== 2) { + $.angle = readFixed($bytes, $stream); + $.distance = readFixed($bytes, $stream); + } + $.strength = readFixed8($bytes, $stream); + $.innerShadow = readUb($bytes, $stream, 1); + $.knockout = readUb($bytes, $stream, 1); + $.compositeSource = readUb($bytes, $stream, 1); + if (type === 3) { + $.onTop = readUb($bytes, $stream, 1); + } else { + var reserved = readUb($bytes, $stream, 1); + } + if (type === 4 || type === 7) { + $.passes = readUb($bytes, $stream, 4); + } else { + var reserved = readUb($bytes, $stream, 4); + } + } + function filterBlur($bytes, $stream, $, swfVersion, tagCode) { + $.blurX = readFixed($bytes, $stream); + $.blurY = readFixed($bytes, $stream); + $.passes = readUb($bytes, $stream, 5); + var reserved = readUb($bytes, $stream, 3); + } + function filterConvolution($bytes, $stream, $, swfVersion, tagCode) { + var columns = $.columns = readUi8($bytes, $stream); + var rows = $.rows = readUi8($bytes, $stream); + $.divisor = readFloat($bytes, $stream); + $.bias = readFloat($bytes, $stream); + var $17 = $.weights = []; + var $18 = columns * rows; + while ($18--) { + $17.push(readFloat($bytes, $stream)); + } + var $19 = $.defaultColor = {}; + rgba($bytes, $stream, $19, swfVersion, tagCode); + var reserved = readUb($bytes, $stream, 6); + $.clamp = readUb($bytes, $stream, 1); + $.preserveAlpha = readUb($bytes, $stream, 1); + } + function filterColorMatrix($bytes, $stream, $, swfVersion, tagCode) { + var $20 = $.matrix = []; + var $21 = 20; + while ($21--) { + $20.push(readFloat($bytes, $stream)); + } + } + function anyFilter($bytes, $stream, $, swfVersion, tagCode) { + var type = $.type = readUi8($bytes, $stream); + switch (type) { + case 0: + case 2: + case 3: + case 4: + case 7: + filterGlow($bytes, $stream, $, swfVersion, tagCode, type); + break; + case 1: + filterBlur($bytes, $stream, $, swfVersion, tagCode); + break; + case 5: + filterConvolution($bytes, $stream, $, swfVersion, tagCode); + break; + case 6: + filterColorMatrix($bytes, $stream, $, swfVersion, tagCode); + break; + default: + } + } + function events($bytes, $stream, $, swfVersion, tagCode) { + var flags, keyPress; + if (swfVersion >= 6) { + flags = readUi32($bytes, $stream); + } else { + flags = readUi16($bytes, $stream); + } + var eoe = $.eoe = !flags; + $.onKeyUp = flags >> 7 & 1; + $.onKeyDown = flags >> 6 & 1; + $.onMouseUp = flags >> 5 & 1; + $.onMouseDown = flags >> 4 & 1; + $.onMouseMove = flags >> 3 & 1; + $.onUnload = flags >> 2 & 1; + $.onEnterFrame = flags >> 1 & 1; + $.onLoad = flags & 1; + if (swfVersion >= 6) { + $.onDragOver = flags >> 15 & 1; + $.onRollOut = flags >> 14 & 1; + $.onRollOver = flags >> 13 & 1; + $.onReleaseOutside = flags >> 12 & 1; + $.onRelease = flags >> 11 & 1; + $.onPress = flags >> 10 & 1; + $.onInitialize = flags >> 9 & 1; + $.onData = flags >> 8 & 1; + if (swfVersion >= 7) { + $.onConstruct = flags >> 18 & 1; + } else { + $.onConstruct = 0; + } + keyPress = $.keyPress = flags >> 17 & 1; + $.onDragOut = flags >> 16 & 1; + } + if (!eoe) { + var length = $.length = readUi32($bytes, $stream); + if (keyPress) { + $.keyCode = readUi8($bytes, $stream); + } + $.actionsData = readBinary($bytes, $stream, length - (keyPress ? 1 : 0)); + } + return { + eoe: eoe + }; + } + function kerning($bytes, $stream, $, swfVersion, tagCode, wide) { + if (wide) { + $.code1 = readUi16($bytes, $stream); + $.code2 = readUi16($bytes, $stream); + } else { + $.code1 = readUi8($bytes, $stream); + $.code2 = readUi8($bytes, $stream); + } + $.adjustment = readUi16($bytes, $stream); + } + function textEntry($bytes, $stream, $, swfVersion, tagCode, glyphBits, advanceBits) { + $.glyphIndex = readUb($bytes, $stream, glyphBits); + $.advance = readSb($bytes, $stream, advanceBits); + } + function textRecordSetup($bytes, $stream, $, swfVersion, tagCode, flags) { + var hasFont = $.hasFont = flags >> 3 & 1; + var hasColor = $.hasColor = flags >> 2 & 1; + var hasMoveY = $.hasMoveY = flags >> 1 & 1; + var hasMoveX = $.hasMoveX = flags & 1; + if (hasFont) { + $.fontId = readUi16($bytes, $stream); + } + if (hasColor) { + if (tagCode === 33) { + var $4 = $.color = {}; + rgba($bytes, $stream, $4, swfVersion, tagCode); + } else { + var $5 = $.color = {}; + rgb($bytes, $stream, $5, swfVersion, tagCode); + } + } + if (hasMoveX) { + $.moveX = readSi16($bytes, $stream); + } + if (hasMoveY) { + $.moveY = readSi16($bytes, $stream); + } + if (hasFont) { + $.fontHeight = readUi16($bytes, $stream); + } + } + function textRecord($bytes, $stream, $, swfVersion, tagCode, glyphBits, advanceBits) { + var glyphCount; + align($bytes, $stream); + var flags = readUb($bytes, $stream, 8); + var eot = $.eot = !flags; + textRecordSetup($bytes, $stream, $, swfVersion, tagCode, flags); + if (!eot) { + var tmp = readUi8($bytes, $stream); + if (swfVersion > 6) { + glyphCount = $.glyphCount = tmp; + } else { + glyphCount = $.glyphCount = tmp & 127; + } + var $6 = $.entries = []; + var $7 = glyphCount; + while ($7--) { + var $8 = {}; + textEntry($bytes, $stream, $8, swfVersion, tagCode, glyphBits, advanceBits); + $6.push($8); + } + } + return { + eot: eot + }; + } + function soundEnvelope($bytes, $stream, $, swfVersion, tagCode) { + $.pos44 = readUi32($bytes, $stream); + $.volumeLeft = readUi16($bytes, $stream); + $.volumeRight = readUi16($bytes, $stream); + } + function soundInfo($bytes, $stream, $, swfVersion, tagCode) { + var reserved = readUb($bytes, $stream, 2); + $.stop = readUb($bytes, $stream, 1); + $.noMultiple = readUb($bytes, $stream, 1); + var hasEnvelope = $.hasEnvelope = readUb($bytes, $stream, 1); + var hasLoops = $.hasLoops = readUb($bytes, $stream, 1); + var hasOutPoint = $.hasOutPoint = readUb($bytes, $stream, 1); + var hasInPoint = $.hasInPoint = readUb($bytes, $stream, 1); + if (hasInPoint) { + $.inPoint = readUi32($bytes, $stream); + } + if (hasOutPoint) { + $.outPoint = readUi32($bytes, $stream); + } + if (hasLoops) { + $.loopCount = readUi16($bytes, $stream); + } + if (hasEnvelope) { + var envelopeCount = $.envelopeCount = readUi8($bytes, $stream); + var $1 = $.envelopes = []; + var $2 = envelopeCount; + while ($2--) { + var $3 = {}; + soundEnvelope($bytes, $stream, $3, swfVersion, tagCode); + $1.push($3); + } + } + } + function button($bytes, $stream, $, swfVersion, tagCode) { + var hasFilters, blend; + var flags = readUi8($bytes, $stream); + var eob = $.eob = !flags; + if (swfVersion >= 8) { + blend = $.blend = flags >> 5 & 1; + hasFilters = $.hasFilters = flags >> 4 & 1; + } else { + blend = $.blend = 0; + hasFilters = $.hasFilters = 0; + } + $.stateHitTest = flags >> 3 & 1; + $.stateDown = flags >> 2 & 1; + $.stateOver = flags >> 1 & 1; + $.stateUp = flags & 1; + if (!eob) { + $.symbolId = readUi16($bytes, $stream); + $.depth = readUi16($bytes, $stream); + var $2 = $.matrix = {}; + matrix($bytes, $stream, $2, swfVersion, tagCode); + if (tagCode === 34) { + var $3 = $.cxform = {}; + cxform($bytes, $stream, $3, swfVersion, tagCode); + } + if (hasFilters) { + $.filterCount = readUi8($bytes, $stream); + var $4 = $.filters = {}; + anyFilter($bytes, $stream, $4, swfVersion, tagCode); + } + if (blend) { + $.blendMode = readUi8($bytes, $stream); + } + } + return { + eob: eob + }; + } + function buttonCondAction($bytes, $stream, $, swfVersion, tagCode) { + var buttonCondSize = readUi16($bytes, $stream); + var buttonConditions = readUi16($bytes, $stream); + $.idleToOverDown = buttonConditions >> 7 & 1; + $.outDownToIdle = buttonConditions >> 6 & 1; + $.outDownToOverDown = buttonConditions >> 5 & 1; + $.overDownToOutDown = buttonConditions >> 4 & 1; + $.overDownToOverUp = buttonConditions >> 3 & 1; + $.overUpToOverDown = buttonConditions >> 2 & 1; + $.overUpToIdle = buttonConditions >> 1 & 1; + $.idleToOverUp = buttonConditions & 1; + $.mouseEventFlags = buttonConditions & 511; + $.keyPress = buttonConditions >> 9 & 127; + $.overDownToIdle = buttonConditions >> 8 & 1; + if (!buttonCondSize) { + $.actionsData = readBinary($bytes, $stream, 0); + } else { + $.actionsData = readBinary($bytes, $stream, buttonCondSize - 4); + } + } + function shape($bytes, $stream, $, swfVersion, tagCode) { + var eos; + var temp = styleBits($bytes, $stream, $, swfVersion, tagCode); + var fillBits = temp.fillBits; + var lineBits = temp.lineBits; + var $4 = $.records = []; + do { + var $5 = {}; + var isMorph = false; + var hasStrokes = false; + var temp = shapeRecord($bytes, $stream, $5, swfVersion, tagCode, isMorph, fillBits, lineBits, hasStrokes, bits); + eos = temp.eos; + var fillBits = temp.fillBits; + var lineBits = temp.lineBits; + var bits = bits; + $4.push($5); + } while (!eos); + } + return { + 0: undefined, + 1: undefined, + 2: defineShape, + 4: placeObject, + 5: removeObject, + 6: defineImage, + 7: defineButton, + 8: defineJPEGTables, + 9: setBackgroundColor, + 10: defineFont, + 11: defineLabel, + 12: doAction, + 13: undefined, + 14: defineSound, + 15: startSound, + 17: undefined, + 18: soundStreamHead, + 19: soundStreamBlock, + 20: defineBitmap, + 21: defineImage, + 22: defineShape, + 23: undefined, + 24: undefined, + 26: placeObject, + 28: removeObject, + 32: defineShape, + 33: defineLabel, + 34: defineButton, + 35: defineImage, + 36: defineBitmap, + 37: defineText, + 39: undefined, + 43: frameLabel, + 45: soundStreamHead, + 46: defineShape, + 48: defineFont2, + 56: exportAssets, + 57: undefined, + 58: undefined, + 59: doAction, + 60: undefined, + 61: undefined, + 62: undefined, + 64: undefined, + 65: undefined, + 66: undefined, + 69: fileAttributes, + 70: placeObject, + 71: undefined, + 72: doABC, + 73: undefined, + 74: undefined, + 75: defineFont2, + 76: symbolClass, + 77: undefined, + 78: defineScalingGrid, + 82: doABC, + 83: defineShape, + 84: defineShape, + 86: defineScene, + 87: defineBinaryData, + 88: undefined, + 89: startSound, + 90: defineImage, + 91: undefined + }; + }(this); +var readHeader = function readHeader($bytes, $stream, $, swfVersion, tagCode) { + $ || ($ = {}); + var $0 = $.bbox = {}; + align($bytes, $stream); + var bits = readUb($bytes, $stream, 5); + var xMin = readSb($bytes, $stream, bits); + var xMax = readSb($bytes, $stream, bits); + var yMin = readSb($bytes, $stream, bits); + var yMax = readSb($bytes, $stream, bits); + $0.xMin = xMin; + $0.xMax = xMax; + $0.yMin = yMin; + $0.yMax = yMax; + align($bytes, $stream); + var frameRateFraction = readUi8($bytes, $stream); + $.frameRate = readUi8($bytes, $stream) + frameRateFraction / 256; + $.frameCount = readUi16($bytes, $stream); + return $; +}; +function readTags(context, stream, swfVersion, final, onprogress, onexception) { + var tags = context.tags; + var bytes = stream.bytes; + var lastSuccessfulPosition; + var tag = null; + if (context._readTag) { + tag = context._readTag; + context._readTag = null; + } + try { + while (stream.pos < stream.end) { + lastSuccessfulPosition = stream.pos; + stream.ensure(2); + var tagCodeAndLength = readUi16(bytes, stream); + if (!tagCodeAndLength) { + final = true; + break; + } + var tagCode = tagCodeAndLength >> 6; + var length = tagCodeAndLength & 63; + if (length === 63) { + stream.ensure(4); + length = readUi32(bytes, stream); + } + if (tag) { + if (tagCode === 1 && tag.code === 1) { + tag.repeat++; + stream.pos += length; + continue; + } + tags.push(tag); + if (onprogress && tag.id !== undefined) { + onprogress(context); + } + tag = null; + } + stream.ensure(length); + var substream = stream.substream(stream.pos, stream.pos += length); + var subbytes = substream.bytes; + var nextTag = { + code: tagCode + }; + if (tagCode === 39) { + nextTag.type = 'sprite'; + nextTag.id = readUi16(subbytes, substream); + nextTag.frameCount = readUi16(subbytes, substream); + nextTag.tags = []; + readTags(nextTag, substream, swfVersion, true); + } else if (tagCode === 1) { + nextTag.repeat = 1; + } else { + var handler = tagHandler[tagCode]; + if (handler) { + handler(subbytes, substream, nextTag, swfVersion, tagCode); + } + } + tag = nextTag; + } + if (tag && final) { + tag.finalTag = true; + tags.push(tag); + if (onprogress) { + onprogress(context); + } + } else { + context._readTag = tag; + } + } catch (e) { + if (e !== StreamNoDataError) { + onexception && onexception(e); + throw e; + } + stream.pos = lastSuccessfulPosition; + context._readTag = tag; + } +} +function HeadTailBuffer(defaultSize) { + this.bufferSize = defaultSize || 16; + this.buffer = new Uint8Array(this.bufferSize); + this.pos = 0; +} +HeadTailBuffer.prototype = { + push: function (data, need) { + var bufferLengthNeed = this.pos + data.length; + if (this.bufferSize < bufferLengthNeed) { + var newBufferSize = this.bufferSize; + while (newBufferSize < bufferLengthNeed) { + newBufferSize <<= 1; + } + var newBuffer = new Uint8Array(newBufferSize); + if (this.bufferSize > 0) { + newBuffer.set(this.buffer); + } + this.buffer = newBuffer; + this.bufferSize = newBufferSize; + } + this.buffer.set(data, this.pos); + this.pos += data.length; + if (need) + return this.pos >= need; + }, + getHead: function (size) { + return this.buffer.subarray(0, size); + }, + getTail: function (offset) { + return this.buffer.subarray(offset, this.pos); + }, + removeHead: function (size) { + var tail = this.getTail(size); + this.buffer = new Uint8Array(this.bufferSize); + this.buffer.set(tail); + this.pos = tail.length; + }, + get arrayBuffer() { + return this.buffer.buffer; + }, + get length() { + return this.pos; + }, + createStream: function () { + return new Stream(this.arrayBuffer, 0, this.length); + } +}; +function CompressedPipe(target, length) { + this.target = target; + this.length = length; + this.initialize = true; + this.buffer = new HeadTailBuffer(8096); + this.state = { + bitBuffer: 0, + bitLength: 0, + compression: { + header: null, + distanceTable: null, + literalTable: null, + sym: null, + len: null, + sym2: null + } + }; + this.output = { + data: new Uint8Array(length), + available: 0, + completed: false + }; +} +CompressedPipe.prototype = { + push: function (data, progressInfo) { + var buffer = this.buffer; + if (this.initialize) { + if (!buffer.push(data, 2)) + return; + var headerBytes = buffer.getHead(2); + verifyDeflateHeader(headerBytes); + buffer.removeHead(2); + this.initialize = false; + } else { + buffer.push(data); + } + var stream = buffer.createStream(); + stream.bitBuffer = this.state.bitBuffer; + stream.bitLength = this.state.bitLength; + var output = this.output; + var lastAvailable = output.available; + try { + do { + inflateBlock(stream, output, this.state.compression); + } while (stream.pos < buffer.length && !output.completed); + } catch (e) { + if (e !== InflateNoDataError) + throw e; + } finally { + this.state.bitBuffer = stream.bitBuffer; + this.state.bitLength = stream.bitLength; + } + buffer.removeHead(stream.pos); + this.target.push(output.data.subarray(lastAvailable, output.available), progressInfo); + } +}; +function BodyParser(swfVersion, length, options) { + this.swf = { + swfVersion: swfVersion, + parseTime: 0 + }; + this.buffer = new HeadTailBuffer(32768); + this.initialize = true; + this.totalRead = 0; + this.length = length; + this.options = options; +} +BodyParser.prototype = { + push: function (data, progressInfo) { + if (data.length === 0) + return; + var swf = this.swf; + var swfVersion = swf.swfVersion; + var buffer = this.buffer; + var options = this.options; + var stream; + if (this.initialize) { + var PREFETCH_SIZE = 27; + if (!buffer.push(data, PREFETCH_SIZE)) + return; + stream = buffer.createStream(); + var bytes = stream.bytes; + readHeader(bytes, stream, swf); + var nextTagHeader = readUi16(bytes, stream); + var FILE_ATTRIBUTES_LENGTH = 4; + if (nextTagHeader == (SWF_TAG_CODE_FILE_ATTRIBUTES << 6 | FILE_ATTRIBUTES_LENGTH)) { + stream.ensure(FILE_ATTRIBUTES_LENGTH); + var substream = stream.substream(stream.pos, stream.pos += FILE_ATTRIBUTES_LENGTH); + var handler = tagHandler[SWF_TAG_CODE_FILE_ATTRIBUTES]; + var fileAttributesTag = { + code: SWF_TAG_CODE_FILE_ATTRIBUTES + }; + handler(substream.bytes, substream, fileAttributesTag, swfVersion, SWF_TAG_CODE_FILE_ATTRIBUTES); + swf.fileAttributes = fileAttributesTag; + } else { + stream.pos -= 2; + swf.fileAttributes = {}; + } + if (options.onstart) + options.onstart(swf); + swf.tags = []; + this.initialize = false; + } else { + buffer.push(data); + stream = buffer.createStream(); + } + var finalBlock = false; + if (progressInfo) { + swf.bytesLoaded = progressInfo.bytesLoaded; + swf.bytesTotal = progressInfo.bytesTotal; + finalBlock = progressInfo.bytesLoaded >= progressInfo.bytesTotal; + } + var readStartTime = performance.now(); + readTags(swf, stream, swfVersion, finalBlock, options.onprogress, options.onexception); + swf.parseTime += performance.now() - readStartTime; + var read = stream.pos; + buffer.removeHead(read); + this.totalRead += read; + if (options.oncomplete && swf.tags[swf.tags.length - 1].finalTag) { + options.oncomplete(swf); + } + } +}; +SWF.parseAsync = function swf_parseAsync(options) { + var buffer = new HeadTailBuffer(); + var pipe = { + push: function (data, progressInfo) { + if (this.target !== undefined) { + return this.target.push(data, progressInfo); + } + if (!buffer.push(data, 8)) { + return null; + } + var bytes = buffer.getHead(8); + var magic1 = bytes[0]; + var magic2 = bytes[1]; + var magic3 = bytes[2]; + if ((magic1 === 70 || magic1 === 67) && magic2 === 87 && magic3 === 83) { + var swfVersion = bytes[3]; + var compressed = magic1 === 67; + parseSWF(compressed, swfVersion, progressInfo); + buffer = null; + return; + } + var isImage = false; + var imageType; + if (magic1 === 255 && magic2 === 216 && magic3 === 255) { + isImage = true; + imageType = 'image/jpeg'; + } else if (magic1 === 137 && magic2 === 80 && magic3 === 78) { + isImage = true; + imageType = 'image/png'; + } + if (isImage) { + parseImage(data, progressInfo.bytesTotal, imageType); + } + buffer = null; + }, + close: function () { + if (buffer) { + var symbol = { + command: 'empty', + data: buffer.buffer.subarray(0, buffer.pos) + }; + options.oncomplete && options.oncomplete(symbol); + } + if (this.target !== undefined && this.target.close) { + this.target.close(); + } + } + }; + function parseSWF(compressed, swfVersion, progressInfo) { + var stream = buffer.createStream(); + stream.pos += 4; + var fileLength = readUi32(null, stream); + var bodyLength = fileLength - 8; + var target = new BodyParser(swfVersion, bodyLength, options); + if (compressed) { + target = new CompressedPipe(target, bodyLength); + } + target.push(buffer.getTail(8), progressInfo); + pipe['target'] = target; + } + function parseImage(data, bytesTotal, type) { + var buffer = new Uint8Array(bytesTotal); + buffer.set(data); + var bufferPos = data.length; + pipe['target'] = { + push: function (data) { + buffer.set(data, bufferPos); + bufferPos += data.length; + }, + close: function () { + var props = {}; + var chunks; + if (type == 'image/jpeg') { + chunks = parseJpegChunks(props, buffer); + } else { + chunks = [ + buffer + ]; + } + var symbol = { + type: 'image', + props: props, + data: new Blob(chunks, { + type: type + }) + }; + options.oncomplete && options.oncomplete(symbol); + } + }; + } + return pipe; +}; +SWF.parse = function (buffer, options) { + if (!options) + options = {}; + var pipe = SWF.parseAsync(options); + var bytes = new Uint8Array(buffer); + var progressInfo = { + bytesLoaded: bytes.length, + bytesTotal: bytes.length + }; + pipe.push(bytes, progressInfo); + pipe.close(); +}; +var $RELEASE = false; +var isWorker = typeof window === 'undefined'; +if (isWorker && !true) { + importScripts.apply(null, [ + '../../lib/DataView.js/DataView.js', + '../flash/util.js', + 'config.js', + 'swf.js', + 'types.js', + 'structs.js', + 'tags.js', + 'inflate.js', + 'stream.js', + 'templates.js', + 'generator.js', + 'handlers.js', + 'parser.js', + 'bitmap.js', + 'button.js', + 'font.js', + 'image.js', + 'label.js', + 'shape.js', + 'sound.js', + 'text.js' + ]); +} +function defineSymbol(swfTag, symbols) { + var symbol; + switch (swfTag.code) { + case SWF_TAG_CODE_DEFINE_BITS: + case SWF_TAG_CODE_DEFINE_BITS_JPEG2: + case SWF_TAG_CODE_DEFINE_BITS_JPEG3: + case SWF_TAG_CODE_DEFINE_BITS_JPEG4: + case SWF_TAG_CODE_JPEG_TABLES: + symbol = defineImage(swfTag, symbols); + break; + case SWF_TAG_CODE_DEFINE_BITS_LOSSLESS: + case SWF_TAG_CODE_DEFINE_BITS_LOSSLESS2: + symbol = defineBitmap(swfTag); + break; + case SWF_TAG_CODE_DEFINE_BUTTON: + case SWF_TAG_CODE_DEFINE_BUTTON2: + symbol = defineButton(swfTag, symbols); + break; + case SWF_TAG_CODE_DEFINE_EDIT_TEXT: + symbol = defineText(swfTag, symbols); + break; + case SWF_TAG_CODE_DEFINE_FONT: + case SWF_TAG_CODE_DEFINE_FONT2: + case SWF_TAG_CODE_DEFINE_FONT3: + case SWF_TAG_CODE_DEFINE_FONT4: + symbol = defineFont(swfTag, symbols); + break; + case SWF_TAG_CODE_DEFINE_MORPH_SHAPE: + case SWF_TAG_CODE_DEFINE_MORPH_SHAPE2: + case SWF_TAG_CODE_DEFINE_SHAPE: + case SWF_TAG_CODE_DEFINE_SHAPE2: + case SWF_TAG_CODE_DEFINE_SHAPE3: + case SWF_TAG_CODE_DEFINE_SHAPE4: + symbol = defineShape(swfTag, symbols); + break; + case SWF_TAG_CODE_DEFINE_SOUND: + symbol = defineSound(swfTag, symbols); + break; + case SWF_TAG_CODE_DEFINE_BINARY_DATA: + symbol = { + type: 'binary', + id: swfTag.id, + data: swfTag.data + }; + break; + case SWF_TAG_CODE_DEFINE_SPRITE: + var depths = {}; + var frame = { + type: 'frame' + }; + var frames = []; + var tags = swfTag.tags; + var frameScripts = null; + var frameIndex = 0; + var soundStream = null; + for (var i = 0, n = tags.length; i < n; i++) { + var tag = tags[i]; + switch (tag.code) { + case SWF_TAG_CODE_DO_ACTION: + if (!frameScripts) + frameScripts = []; + frameScripts.push(frameIndex); + frameScripts.push(tag.actionsData); + break; + case SWF_TAG_CODE_START_SOUND: + var startSounds = frame.startSounds || (frame.startSounds = []); + startSounds.push(tag); + break; + case SWF_TAG_CODE_SOUND_STREAM_HEAD: + try { + soundStream = createSoundStream(tag); + frame.soundStream = soundStream.info; + } catch (e) { + } + break; + case SWF_TAG_CODE_SOUND_STREAM_BLOCK: + if (soundStream) { + frame.soundStreamBlock = soundStream.decode(tag.data); + } + break; + case SWF_TAG_CODE_FRAME_LABEL: + frame.labelName = tag.name; + break; + case SWF_TAG_CODE_PLACE_OBJECT: + case SWF_TAG_CODE_PLACE_OBJECT2: + case SWF_TAG_CODE_PLACE_OBJECT3: + depths[tag.depth] = tag; + break; + case SWF_TAG_CODE_REMOVE_OBJECT: + case SWF_TAG_CODE_REMOVE_OBJECT2: + depths[tag.depth] = null; + break; + case SWF_TAG_CODE_SHOW_FRAME: + frameIndex += tag.repeat; + frame.repeat = tag.repeat; + frame.depths = depths; + frames.push(frame); + depths = {}; + frame = { + type: 'frame' + }; + break; + } + } + symbol = { + type: 'sprite', + id: swfTag.id, + frameCount: swfTag.frameCount, + frames: frames, + frameScripts: frameScripts + }; + break; + case SWF_TAG_CODE_DEFINE_TEXT: + case SWF_TAG_CODE_DEFINE_TEXT2: + symbol = defineLabel(swfTag, symbols); + break; + } + if (!symbol) { + return { + command: 'error', + message: 'unknown symbol type: ' + swfTag.code + }; + } + symbol.isSymbol = true; + symbols[swfTag.id] = symbol; + return symbol; +} +function createParsingContext(commitData) { + var depths = {}; + var symbols = {}; + var frame = { + type: 'frame' + }; + var tagsProcessed = 0; + var soundStream = null; + var lastProgressSent = 0; + return { + onstart: function (result) { + commitData({ + command: 'init', + result: result + }); + }, + onprogress: function (result) { + if (Date.now() - lastProgressSent > 1000 / 24 || result.bytesLoaded === result.bytesTotal) { + commitData({ + command: 'progress', + result: { + bytesLoaded: result.bytesLoaded, + bytesTotal: result.bytesTotal + } + }); + lastProgressSent = Date.now(); + } + var tags = result.tags; + for (var n = tags.length; tagsProcessed < n; tagsProcessed++) { + var tag = tags[tagsProcessed]; + if ('id' in tag) { + var symbol = defineSymbol(tag, symbols); + commitData(symbol, symbol.transferables); + continue; + } + switch (tag.code) { + case SWF_TAG_CODE_DEFINE_SCENE_AND_FRAME_LABEL_DATA: + frame.sceneData = tag; + break; + case SWF_TAG_CODE_DEFINE_SCALING_GRID: + var symbolUpdate = { + isSymbol: true, + id: tag.symbolId, + updates: { + scale9Grid: tag.splitter + } + }; + commitData(symbolUpdate); + break; + case SWF_TAG_CODE_DO_ABC: + case SWF_TAG_CODE_DO_ABC_: + var abcBlocks = frame.abcBlocks; + if (abcBlocks) + abcBlocks.push({ + data: tag.data, + flags: tag.flags + }); + else + frame.abcBlocks = [ + { + data: tag.data, + flags: tag.flags + } + ]; + break; + case SWF_TAG_CODE_DO_ACTION: + var actionBlocks = frame.actionBlocks; + if (actionBlocks) + actionBlocks.push(tag.actionsData); + else + frame.actionBlocks = [ + tag.actionsData + ]; + break; + case SWF_TAG_CODE_DO_INIT_ACTION: + var initActionBlocks = frame.initActionBlocks || (frame.initActionBlocks = []); + initActionBlocks.push({ + spriteId: tag.spriteId, + actionsData: tag.actionsData + }); + break; + case SWF_TAG_CODE_START_SOUND: + var startSounds = frame.startSounds; + if (!startSounds) + frame.startSounds = startSounds = []; + startSounds.push(tag); + break; + case SWF_TAG_CODE_SOUND_STREAM_HEAD: + try { + soundStream = createSoundStream(tag); + frame.soundStream = soundStream.info; + } catch (e) { + } + break; + case SWF_TAG_CODE_SOUND_STREAM_BLOCK: + if (soundStream) { + frame.soundStreamBlock = soundStream.decode(tag.data); + } + break; + case SWF_TAG_CODE_EXPORT_ASSETS: + var exports = frame.exports; + if (exports) + frame.exports = exports.concat(tag.exports); + else + frame.exports = tag.exports.slice(0); + break; + case SWF_TAG_CODE_SYMBOL_CLASS: + var symbolClasses = frame.symbolClasses; + if (symbolClasses) + frame.symbolClasses = symbolClasses.concat(tag.exports); + else + frame.symbolClasses = tag.exports.slice(0); + break; + case SWF_TAG_CODE_FRAME_LABEL: + frame.labelName = tag.name; + break; + case SWF_TAG_CODE_PLACE_OBJECT: + case SWF_TAG_CODE_PLACE_OBJECT2: + case SWF_TAG_CODE_PLACE_OBJECT3: + depths[tag.depth] = tag; + break; + case SWF_TAG_CODE_REMOVE_OBJECT: + case SWF_TAG_CODE_REMOVE_OBJECT2: + depths[tag.depth] = null; + break; + case SWF_TAG_CODE_SET_BACKGROUND_COLOR: + frame.bgcolor = tag.color; + break; + case SWF_TAG_CODE_SHOW_FRAME: + frame.repeat = tag.repeat; + frame.depths = depths; + frame.complete = !(!tag.finalTag); + commitData(frame); + depths = {}; + frame = { + type: 'frame' + }; + break; + } + } + }, + oncomplete: function (result) { + commitData(result); + var stats; + if (typeof result.swfVersion === 'number') { + var bbox = result.bbox; + stats = { + topic: 'parseInfo', + parseTime: result.parseTime, + bytesTotal: result.bytesTotal, + swfVersion: result.swfVersion, + frameRate: result.frameRate, + width: (bbox.xMax - bbox.xMin) / 20, + height: (bbox.yMax - bbox.yMin) / 20, + isAvm2: !(!result.fileAttributes.doAbc) + }; + } + commitData({ + command: 'complete', + stats: stats + }); + }, + onexception: function (e) { + commitData({ + type: 'exception', + message: e.message, + stack: e.stack + }); + } + }; +} +function parseBytes(bytes, commitData) { + SWF.parse(bytes, createParsingContext(commitData)); +} +function ResourceLoader(scope) { + this.subscription = null; + var self = this; + if (!isWorker) { + this.messenger = { + postMessage: function (data) { + self.onmessage({ + data: data + }); + } + }; + } else { + this.messenger = scope; + scope.onmessage = function (event) { + self.listener(event.data); + }; + } +} +ResourceLoader.prototype = { + terminate: function () { + this.messenger = null; + this.listener = null; + }, + onmessage: function (event) { + this.listener(event.data); + }, + postMessage: function (data) { + this.listener && this.listener(data); + }, + listener: function (data) { + if (this.subscription) { + this.subscription.callback(data.data, data.progress); + } else if (data === 'pipe:') { + this.subscription = { + subscribe: function (callback) { + this.callback = callback; + } + }; + this.parseLoadedData(this.messenger, this.subscription); + } else { + this.parseLoadedData(this.messenger, data); + } + }, + parseLoadedData: function (loader, request, context) { + function commitData(data, transferables) { + try { + loader.postMessage(data, transferables); + } catch (ex) { + if (ex != 'DataCloneError') { + throw ex; + } + loader.postMessage(data); + } + } + if (request instanceof ArrayBuffer) { + parseBytes(request, commitData); + } else if ('subscribe' in request) { + var pipe = SWF.parseAsync(createParsingContext(commitData)); + request.subscribe(function (data, progress) { + if (data) { + pipe.push(data, progress); + } else { + pipe.close(); + } + }); + } else if (typeof FileReaderSync !== 'undefined') { + var reader = new FileReaderSync(); + var buffer = reader.readAsArrayBuffer(request); + parseBytes(buffer, commitData); + } else { + var reader = new FileReader(); + reader.onload = function () { + parseBytes(this.result, commitData); + }; + reader.readAsArrayBuffer(request); + } + } +}; +if (isWorker) { + var loader = new ResourceLoader(this); +} +function ActionsDataStream(array, swfVersion) { + this.array = array; + this.position = 0; + this.end = array.length; + if (swfVersion >= 6) { + this.readString = this.readUTF8String; + } else { + this.readString = this.readANSIString; + } + var buffer = new ArrayBuffer(4); + new Int32Array(buffer)[0] = 1; + if (!new Uint8Array(buffer)[0]) { + throw new Error('big-endian platform'); + } +} +ActionsDataStream.prototype = { + readUI8: function ActionsDataStream_readUI8() { + return this.array[this.position++]; + }, + readUI16: function ActionsDataStream_readUI16() { + var position = this.position, array = this.array; + var value = array[position + 1] << 8 | array[position]; + this.position = position + 2; + return value; + }, + readSI16: function ActionsDataStream_readSI16() { + var position = this.position, array = this.array; + var value = array[position + 1] << 8 | array[position]; + this.position = position + 2; + return value < 32768 ? value : value - 65536; + }, + readInteger: function ActionsDataStream_readInteger() { + var position = this.position, array = this.array; + var value = array[position] | array[position + 1] << 8 | array[position + 2] << 16 | array[position + 3] << 24; + this.position = position + 4; + return value; + }, + readFloat: function ActionsDataStream_readFloat() { + var position = this.position; + var array = this.array; + var buffer = new ArrayBuffer(4); + var bytes = new Uint8Array(buffer); + bytes[0] = array[position]; + bytes[1] = array[position + 1]; + bytes[2] = array[position + 2]; + bytes[3] = array[position + 3]; + this.position = position + 4; + return new Float32Array(buffer)[0]; + }, + readDouble: function ActionsDataStream_readDouble() { + var position = this.position; + var array = this.array; + var buffer = new ArrayBuffer(8); + var bytes = new Uint8Array(buffer); + bytes[4] = array[position]; + bytes[5] = array[position + 1]; + bytes[6] = array[position + 2]; + bytes[7] = array[position + 3]; + bytes[0] = array[position + 4]; + bytes[1] = array[position + 5]; + bytes[2] = array[position + 6]; + bytes[3] = array[position + 7]; + this.position = position + 8; + return new Float64Array(buffer)[0]; + }, + readBoolean: function ActionsDataStream_readBoolean() { + return !(!this.readUI8()); + }, + readANSIString: function ActionsDataStream_readANSIString() { + var value = ''; + var ch; + while (ch = this.readUI8()) { + value += String.fromCharCode(ch); + } + return value; + }, + readUTF8String: function ActionsDataStream_readUTF8String() { + var value = ''; + var ch; + while (ch = this.readUI8()) { + if (ch < 128) { + value += String.fromCharCode(ch); + continue; + } + if ((ch & 192) === 128) { + throw new Error('Invalid UTF8 encoding'); + } + var currentPrefix = 192; + var validBits = 5; + do { + var mask = currentPrefix >> 1 | 128; + if ((ch & mask) === currentPrefix) { + break; + } + currentPrefix = mask; + --validBits; + } while (validBits >= 0); + var code = ch & (1 << validBits) - 1; + for (var i = 5; i >= validBits; --i) { + ch = this.readUI8(); + if ((ch & 192) !== 128) { + throw new Error('Invalid UTF8 encoding'); + } + code = code << 6 | ch & 63; + } + if (code >= 65536) { + value += String.fromCharCode(code - 65536 >> 10 & 1023 | 55296, code & 1023 | 56320); + } else { + value += String.fromCharCode(code); + } + } + return value; + }, + readBytes: function ActionsDataStream_readBytes(length) { + var position = this.position; + var remaining = Math.max(this.end - position, 0); + if (remaining < length) { + length = remaining; + } + var subarray = this.array.subarray(position, position + length); + this.position = position + length; + return subarray; + } +}; +if (typeof GLOBAL !== 'undefined') { + GLOBAL.ActionsDataStream = ActionsDataStream; +} +var AVM1_TRACE_ENABLED = false; +var AVM1_ERRORS_IGNORED = true; +var MAX_AVM1_HANG_TIMEOUT = 1000; +var MAX_AVM1_ERRORS_LIMIT = 1000; +var MAX_AVM1_STACK_LIMIT = 256; +function AS2ScopeListItem(scope, next) { + this.scope = scope; + this.next = next; +} +AS2ScopeListItem.prototype = { + create: function (scope) { + return new AS2ScopeListItem(scope, this); + } +}; +function AS2Context(swfVersion) { + this.swfVersion = swfVersion; + this.globals = new avm1lib.AS2Globals(this); + this.initialScope = new AS2ScopeListItem(this.globals, null); + this.assets = {}; + this.isActive = false; + this.executionProhibited = false; + this.abortExecutionAt = 0; + this.stackDepth = 0; + this.isTryCatchListening = false; + this.errorsIgnored = 0; + this.deferScriptExecution = true; + this.pendingScripts = []; +} +AS2Context.instance = null; +AS2Context.prototype = { + addAsset: function (className, symbolProps) { + this.assets[className] = symbolProps; + }, + resolveTarget: function (target) { + if (!target) { + target = this.defaultTarget; + } else if (typeof target === 'string') { + target = lookupAS2Children(target, this.defaultTarget, this.globals.asGetPublicProperty('_root')); + } + if (typeof target !== 'object' || target === null || !('$nativeObject' in target)) { + throw new Error('Invalid AS2 target object: ' + Object.prototype.toString.call(target)); + } + return target; + }, + resolveLevel: function (level) { + return this.resolveTarget(this.globals['_level' + level]); + }, + addToPendingScripts: function (fn) { + if (!this.deferScriptExecution) { + return fn(); + } + this.pendingScripts.push(fn); + }, + flushPendingScripts: function () { + var scripts = this.pendingScripts; + while (scripts.length) { + scripts.shift()(); + } + this.deferScriptExecution = false; + } +}; +function AS2Error(error) { + this.error = error; +} +function AS2CriticalError(message, error) { + this.message = message; + this.error = error; +} +AS2CriticalError.prototype = Object.create(Error.prototype); +function isAS2MovieClip(obj) { + return typeof obj === 'object' && obj && obj instanceof avm1lib.AS2MovieClip; +} +function as2GetType(v) { + if (v === null) { + return 'null'; + } + var type = typeof v; + if (type === 'function') { + return 'object'; + } + if (type === 'object' && isAS2MovieClip(v)) { + return 'movieclip'; + } + return type; +} +function as2ToPrimitive(value) { + return as2GetType(value) !== 'object' ? value : value.valueOf(); +} +function as2ToAddPrimitive(value) { + if (as2GetType(value) !== 'object') { + return value; + } + if (value instanceof Date && AS2Context.instance.swfVersion >= 6) { + return value.toString(); + } else { + return value.valueOf(); + } +} +function as2ToBoolean(value) { + switch (as2GetType(value)) { + default: + case 'undefined': + case 'null': + return false; + case 'boolean': + return value; + case 'number': + return value !== 0 && !isNaN(value); + case 'string': + return value.length !== 0; + case 'movieclip': + case 'object': + return true; + } +} +function as2ToNumber(value) { + value = as2ToPrimitive(value); + switch (as2GetType(value)) { + case 'undefined': + case 'null': + return AS2Context.instance.swfVersion >= 7 ? NaN : 0; + case 'boolean': + return value ? 1 : +0; + case 'number': + return value; + case 'string': + if (value === '' && AS2Context.instance.swfVersion < 5) { + return 0; + } + return +value; + default: + return AS2Context.instance.swfVersion >= 5 ? NaN : 0; + } +} +function as2ToInteger(value) { + var result = as2ToNumber(value); + if (isNaN(result)) { + return 0; + } + if (!isFinite(result) || result === 0) { + return result; + } + return (result < 0 ? -1 : 1) * Math.abs(result) | 0; +} +function as2ToInt32(value) { + var result = as2ToNumber(value); + return isNaN(result) || !isFinite(result) || result === 0 ? 0 : result | 0; +} +function as2ToString(value) { + switch (as2GetType(value)) { + case 'undefined': + return AS2Context.instance.swfVersion >= 7 ? 'undefined' : ''; + case 'null': + return 'null'; + case 'boolean': + return value ? 'true' : 'false'; + case 'number': + return value.toString(); + case 'string': + return value; + case 'movieclip': + return value.$targetPath; + case 'object': + var result = value.toString !== Function.prototype.toString ? value.toString() : value; + if (typeof result === 'string') { + return result; + } + return typeof value === 'function' ? '[type Function]' : '[type Object]'; + } +} +function as2Compare(x, y) { + var x2 = as2ToPrimitive(x); + var y2 = as2ToPrimitive(y); + if (typeof x2 === 'string' && typeof y2 === 'string') { + return x2 < y2; + } else { + return as2ToNumber(x2) < as2ToNumber(y2); + } +} +function as2InstanceOf(obj, constructor) { + if (obj instanceof constructor) { + return true; + } + return false; +} +function as2ResolveProperty(obj, name) { + var avm2PublicName = Multiname.getPublicQualifiedName(name); + if (avm2PublicName in obj) { + return name; + } + if (isNumeric(name)) { + return null; + } + var lowerCaseName = avm2PublicName.toLowerCase(); + for (var i in obj) { + if (i.toLowerCase() === lowerCaseName) { + notImplemented('FIX THIS'); + } + } + return null; +} +function as2GetPrototype(obj) { + return obj && obj.asGetPublicProperty('prototype'); +} +function isAvm2Class(obj) { + return typeof obj === 'object' && obj !== null && 'instanceConstructor' in obj; +} +function as2CreatePrototypeProxy(obj) { + var prototype = obj.asGetPublicProperty('prototype'); + if (typeof Proxy === 'undefined') { + console.error('ES6 proxies are not found'); + return prototype; + } + return Proxy.create({ + getOwnPropertyDescriptor: function (name) { + return Object.getOwnPropertyDescriptor(prototype, name); + }, + getPropertyDescriptor: function (name) { + for (var p = prototype; p; p = Object.getPrototypeOf(p)) { + var desc = Object.getOwnPropertyDescriptor(p, name); + if (desc) + return desc; + } + }, + getOwnPropertyNames: function () { + return Object.getOwnPropertyNames(prototype); + }, + getPropertyNames: function () { + var names = Object.getOwnPropertyNames(prototype); + for (var p = Object.getPrototypeOf(prototype); p; p = Object.getPrototypeOf(p)) { + names = names.concat(Object.getOwnPropertyNames(p)); + } + return names; + }, + defineProperty: function (name, desc) { + if (desc) { + if (typeof desc.value === 'function' && desc.value._setClass) { + desc.value._setClass(obj); + } + if (typeof desc.get === 'function' && desc.get._setClass) { + desc.get._setClass(obj); + } + if (typeof desc.set === 'function' && desc.set._setClass) { + desc.set._setClass(obj); + } + } + return Object.defineProperty(prototype, name, desc); + }, + delete: function (name) { + return delete prototype[name]; + }, + fix: function () { + return undefined; + } + }); +} +function executeActions(actionsData, context, scope) { + if (context.executionProhibited) { + return; + } + var actionTracer = ActionTracerFactory.get(); + var scopeContainer = context.initialScope.create(scope); + var savedContext = AS2Context.instance; + try { + AS2Context.instance = context; + context.isActive = true; + context.abortExecutionAt = Date.now() + MAX_AVM1_HANG_TIMEOUT; + context.errorsIgnored = 0; + context.defaultTarget = scope; + context.globals.asSetPublicProperty('this', scope); + actionTracer.message('ActionScript Execution Starts'); + actionTracer.indent(); + interpretActions(actionsData, scopeContainer, null, []); + } catch (e) { + if (e instanceof AS2CriticalError) { + console.error('Disabling AVM1 execution'); + context.executionProhibited = true; + } + throw e; + } finally { + context.isActive = false; + actionTracer.unindent(); + actionTracer.message('ActionScript Execution Stops'); + AS2Context.instance = savedContext; + } +} +function lookupAS2Children(targetPath, defaultTarget, root) { + var path = targetPath.split(/[\/.]/g); + if (path[path.length - 1] === '') { + path.pop(); + } + var obj = defaultTarget; + if (path[0] === '' || path[0] === '_level0' || path[0] === '_root') { + obj = root; + path.shift(); + } + while (path.length > 0) { + var prevObj = obj; + obj = obj.$lookupChild(path[0]); + if (!obj) { + throw new Error(path[0] + ' (expr ' + targetPath + ') is not found in ' + prevObj._target); + } + path.shift(); + } + return obj; +} +function createBuiltinType(obj, args) { + if (obj === Array) { + var result = args; + if (args.length == 1 && typeof args[0] === 'number') { + result = []; + result.length = args[0]; + } + return result; + } + if (obj === Boolean || obj === Number || obj === String || obj === Function) { + return obj.apply(null, args); + } + if (obj === Date) { + switch (args.length) { + case 0: + return new Date(); + case 1: + return new Date(args[0]); + default: + return new Date(args[0], args[1], args.length > 2 ? args[2] : 1, args.length > 3 ? args[3] : 0, args.length > 4 ? args[4] : 0, args.length > 5 ? args[5] : 0, args.length > 6 ? args[6] : 0); + } + } + if (obj === Object) { + return {}; + } +} +var AS2_SUPER_STUB = {}; +function interpretActions(actionsData, scopeContainer, constantPool, registers) { + var currentContext = AS2Context.instance; + function setTarget(targetPath) { + if (!targetPath) { + currentContext.defaultTarget = scope; + return; + } + try { + currentContext.defaultTarget = lookupAS2Children(targetPath, defaultTarget, _global.asGetPublicProperty('_root')); + } catch (e) { + currentContext.defaultTarget = null; + throw e; + } + } + function defineFunction(functionName, parametersNames, registersAllocation, actionsData) { + var ownerClass; + var fn = function () { + var newScope = {}; + newScope.asSetPublicProperty('this', this); + newScope.asSetPublicProperty('arguments', arguments); + newScope.asSetPublicProperty('super', AS2_SUPER_STUB); + newScope.asSetPublicProperty('__class', ownerClass); + var newScopeContainer = scopeContainer.create(newScope); + var i; + for (i = 0; i < arguments.length || i < parametersNames.length; i++) { + newScope.asSetPublicProperty(parametersNames[i], arguments[i]); + } + var registers = []; + if (registersAllocation) { + for (i = 0; i < registersAllocation.length; i++) { + var registerAllocation = registersAllocation[i]; + if (!registerAllocation) { + continue; + } + if (registerAllocation.type == 'param') { + registers[i] = arguments[registerAllocation.index]; + } else { + switch (registerAllocation.name) { + case 'this': + registers[i] = this; + break; + case 'arguments': + registers[i] = arguments; + break; + case 'super': + registers[i] = AS2_SUPER_STUB; + break; + case '_global': + registers[i] = _global; + break; + case '_parent': + registers[i] = scope.asGetPublicProperty('_parent'); + break; + case '_root': + registers[i] = _global.asGetPublicProperty('_root'); + break; + } + } + } + } + var savedContext = AS2Context.instance; + var savedIsActive = currentContext.isActive; + try { + AS2Context.instance = currentContext; + if (!savedIsActive) { + currentContext.abortExecutionAt = Date.now() + MAX_AVM1_HANG_TIMEOUT; + currentContext.errorsIgnored = 0; + currentContext.isActive = true; + } + currentContext.defaultTarget = scope; + actionTracer.indent(); + currentContext.stackDepth++; + if (currentContext.stackDepth >= MAX_AVM1_STACK_LIMIT) { + throw new AS2CriticalError('long running script -- AVM1 recursion limit is reached'); + } + return interpretActions(actionsData, newScopeContainer, constantPool, registers); + } finally { + currentContext.isActive = savedIsActive; + currentContext.stackDepth--; + actionTracer.unindent(); + currentContext.defaultTarget = defaultTarget; + AS2Context.instance = savedContext; + } + }; + ownerClass = fn; + fn._setClass = function (class_) { + ownerClass = class_; + }; + fn.instanceConstructor = fn; + fn.debugName = 'avm1 ' + (functionName || ''); + if (functionName) { + fn.name = functionName; + } + return fn; + } + function deleteProperty(propertyName) { + for (var p = scopeContainer; p; p = p.next) { + if (p.scope.asHasProperty(undefined, propertyName, 0)) { + p.scope.asSetPublicProperty(propertyName, undefined); + return p.scope.asDeleteProperty(undefined, propertyName, 0); + } + } + return false; + } + function resolveVariableName(variableName, nonStrict) { + var obj, name, i; + if (variableName.indexOf(':') >= 0) { + var parts = variableName.split(':'); + obj = lookupAS2Children(parts[0], defaultTarget, _global.asGetPublicProperty('_root')); + if (!obj) { + throw new Error(parts[0] + ' is undefined'); + } + name = parts[1]; + } else if (variableName.indexOf('.') >= 0) { + var objPath = variableName.split('.'); + name = objPath.pop(); + obj = _global; + for (i = 0; i < objPath.length; i++) { + obj = obj.asGetPublicProperty(objPath[i]) || obj[objPath[i]]; + if (!obj) { + throw new Error(objPath.slice(0, i + 1) + ' is undefined'); + } + } + } + if (!obj) { + return null; + } + var resolvedName = as2ResolveProperty(obj, name); + var resolved = resolvedName !== null; + if (resolved || nonStrict) { + return { + obj: obj, + name: resolvedName || name, + resolved: resolved + }; + } + return null; + } + function getThis() { + var _this = scope.asGetPublicProperty('this'); + if (_this) { + return _this; + } + for (var p = scopeContainer; p; p = p.next) { + resolvedName = as2ResolveProperty(p.scope, 'this'); + if (resolvedName !== null) { + return p.scope.asGetPublicProperty(resolvedName); + } + } + } + function getVariable(variableName) { + if (scope.asHasProperty(undefined, variableName, 0)) { + return scope.asGetPublicProperty(variableName); + } + var target = resolveVariableName(variableName); + if (target) { + return target.obj.asGetPublicProperty(target.name); + } + var resolvedName, _this = getThis(); + for (var p = scopeContainer; p; p = p.next) { + resolvedName = as2ResolveProperty(p.scope, variableName); + if (resolvedName !== null) { + return p.scope.asGetPublicProperty(resolvedName); + } + } + if (_this && (resolvedName = as2ResolveProperty(_this, variableName))) { + return _this.asGetPublicProperty(resolvedName); + } + var mc = isAS2MovieClip(defaultTarget) && defaultTarget.$lookupChild(variableName); + if (mc) { + return mc; + } + } + function setVariable(variableName, value) { + if (scope.asHasProperty(undefined, variableName, 0)) { + scope.asSetPublicProperty(variableName, value); + return; + } + var target = resolveVariableName(variableName, true); + if (target) { + target.obj.asSetPublicProperty(target.name, value); + return; + } + var resolvedName, _this = getThis(); + if (_this && (resolvedName = as2ResolveProperty(_this, variableName))) { + return _this.asSetPublicProperty(resolvedName, value); + } + for (var p = scopeContainer; p.next; p = p.next) { + resolvedName = as2ResolveProperty(p.scope, variableName); + if (resolvedName !== null) { + return p.scope.asSetPublicProperty(resolvedName, value); + } + } + (_this || scope).asSetPublicProperty(variableName, value); + } + function getFunction(functionName) { + var fn = getVariable(functionName); + if (!(fn instanceof Function)) { + throw new Error('Function "' + functionName + '" is not found'); + } + return fn; + } + function getObjectByName(objectName) { + var obj = getVariable(objectName); + if (!(obj instanceof Object)) { + throw new Error('Object "' + objectName + '" is not found'); + } + return obj; + } + function processWith(obj, withBlock) { + var newScopeContainer = scopeContainer.create(Object(obj)); + interpretActions(withBlock, newScopeContainer, constantPool, registers); + } + function processTry(catchIsRegisterFlag, finallyBlockFlag, catchBlockFlag, catchTarget, tryBlock, catchBlock, finallyBlock) { + var savedTryCatchState = currentContext.isTryCatchListening; + try { + currentContext.isTryCatchListening = true; + interpretActions(tryBlock, scopeContainer, constantPool, registers); + } catch (e) { + currentContext.isTryCatchListening = savedTryCatchState; + if (!catchBlockFlag) { + throw e; + } + if (!(e instanceof AS2Error)) { + throw e; + } + if (typeof catchTarget === 'string') { + scope[catchTarget] = e.error; + } else { + registers[catchTarget] = e.error; + } + interpretActions(catchBlock, scopeContainer, constantPool, registers); + } finally { + currentContext.isTryCatchListening = savedTryCatchState; + if (finallyBlockFlag) { + interpretActions(finallyBlock, scopeContainer, constantPool, registers); + } + } + } + function validateArgsCount(numArgs, maxAmount) { + if (isNaN(numArgs) || numArgs < 0 || numArgs > maxAmount || numArgs != (0 | numArgs)) { + throw new Error('Invalid number of arguments: ' + numArgs); + } + } + function readArgs(stack) { + var numArgs = +stack.pop(); + validateArgsCount(numArgs, stack.length); + var args = []; + for (var i = 0; i < numArgs; i++) { + args.push(stack.pop()); + } + return args; + } + var stream = new ActionsDataStream(actionsData, currentContext.swfVersion); + var _global = currentContext.globals; + var defaultTarget = currentContext.defaultTarget; + var stack = []; + var scope = scopeContainer.scope; + var isSwfVersion5 = currentContext.swfVersion >= 5; + var actionTracer = ActionTracerFactory.get(); + var nextPosition; + if (scope.$nativeObject && scope.$nativeObject._deferScriptExecution) { + currentContext.deferScriptExecution = true; + } + function skipActions(count) { + while (count > 0 && stream.position < stream.end) { + var actionCode = stream.readUI8(); + var length = actionCode >= 128 ? stream.readUI16() : 0; + stream.position += length; + count--; + } + nextPosition = stream.position; + } + var recoveringFromError = false; + var stackItemsExpected; + while (stream.position < stream.end) { + try { + var instructionsExecuted = 0; + var abortExecutionAt = currentContext.abortExecutionAt; + while (stream.position < stream.end) { + if (instructionsExecuted++ % 100 === 0 && Date.now() >= abortExecutionAt) { + throw new AS2CriticalError('long running script -- AVM1 instruction hang timeout'); + } + var actionCode = stream.readUI8(); + var length = actionCode >= 128 ? stream.readUI16() : 0; + nextPosition = stream.position + length; + stackItemsExpected = 0; + actionTracer.print(stream.position, actionCode, stack); + var frame, type, count, index, target, method, constr, codeSize, offset; + var name, variableName, methodName, functionName, targetName; + var paramName, resolvedName, objectName; + var value, a, b, c, f, sa, sb, obj, args, fn, result, flags, i; + var dragParams, register; + switch (actionCode | 0) { + case 129: + frame = stream.readUI16(); + var nextActionCode = stream.readUI8(); + nextPosition++; + methodName = nextActionCode === 6 ? 'gotoAndPlay' : 'gotoAndStop'; + _global[methodName](frame + 1); + break; + case 131: + var urlString = stream.readString(); + var targetString = stream.readString(); + _global.getURL(urlString, targetString); + break; + case 4: + _global.nextFrame(); + break; + case 5: + _global.prevFrame(); + break; + case 6: + _global.play(); + break; + case 7: + _global.stop(); + break; + case 8: + _global.toggleHighQuality(); + break; + case 9: + _global.stopAllSounds(); + break; + case 138: + frame = stream.readUI16(); + count = stream.readUI8(); + if (!_global.ifFrameLoaded(frame)) { + skipActions(count); + } + break; + case 139: + targetName = stream.readString(); + setTarget(targetName); + break; + case 140: + var label = stream.readString(); + _global.gotoLabel(label); + break; + case 150: + while (stream.position < nextPosition) { + type = stream.readUI8(); + switch (type) { + case 0: + value = stream.readString(); + break; + case 1: + value = stream.readFloat(); + break; + case 2: + value = null; + break; + case 3: + value = void 0; + break; + case 4: + value = registers[stream.readUI8()]; + break; + case 5: + value = stream.readBoolean(); + break; + case 6: + value = stream.readDouble(); + break; + case 7: + value = stream.readInteger(); + break; + case 8: + value = constantPool[stream.readUI8()]; + break; + case 9: + value = constantPool[stream.readUI16()]; + break; + default: + throw new Error('Unknown value type: ' + type); + } + stack.push(value); + } + break; + case 23: + stack.pop(); + break; + case 10: + a = as2ToNumber(stack.pop()); + b = as2ToNumber(stack.pop()); + stack.push(a + b); + break; + case 11: + a = as2ToNumber(stack.pop()); + b = as2ToNumber(stack.pop()); + stack.push(b - a); + break; + case 12: + a = as2ToNumber(stack.pop()); + b = as2ToNumber(stack.pop()); + stack.push(a * b); + break; + case 13: + a = as2ToNumber(stack.pop()); + b = as2ToNumber(stack.pop()); + c = b / a; + stack.push(isSwfVersion5 ? c : isFinite(c) ? c : '#ERROR#'); + break; + case 14: + a = as2ToNumber(stack.pop()); + b = as2ToNumber(stack.pop()); + f = a == b; + stack.push(isSwfVersion5 ? f : f ? 1 : 0); + break; + case 15: + a = as2ToNumber(stack.pop()); + b = as2ToNumber(stack.pop()); + f = b < a; + stack.push(isSwfVersion5 ? f : f ? 1 : 0); + break; + case 16: + a = as2ToBoolean(stack.pop()); + b = as2ToBoolean(stack.pop()); + f = a && b; + stack.push(isSwfVersion5 ? f : f ? 1 : 0); + break; + case 17: + a = as2ToBoolean(stack.pop()); + b = as2ToBoolean(stack.pop()); + f = a || b; + stack.push(isSwfVersion5 ? f : f ? 1 : 0); + break; + case 18: + f = !as2ToBoolean(stack.pop()); + stack.push(isSwfVersion5 ? f : f ? 1 : 0); + break; + case 19: + sa = as2ToString(stack.pop()); + sb = as2ToString(stack.pop()); + f = sa == sb; + stack.push(isSwfVersion5 ? f : f ? 1 : 0); + break; + case 20: + case 49: + sa = as2ToString(stack.pop()); + stack.push(_global.length(sa)); + break; + case 33: + sa = as2ToString(stack.pop()); + sb = as2ToString(stack.pop()); + stack.push(sb + sa); + break; + case 21: + count = stack.pop(); + index = stack.pop(); + value = as2ToString(stack.pop()); + stack.push(_global.substring(value, index, count)); + break; + case 53: + count = stack.pop(); + index = stack.pop(); + value = as2ToString(stack.pop()); + stack.push(_global.mbsubstring(value, index, count)); + break; + case 41: + sa = as2ToString(stack.pop()); + sb = as2ToString(stack.pop()); + f = sb < sa; + stack.push(isSwfVersion5 ? f : f ? 1 : 0); + break; + case 24: + stack.push(_global.int(stack.pop())); + break; + case 50: + stack.push(_global.chr(stack.pop())); + break; + case 54: + stack.push(_global.mbchr(stack.pop())); + break; + case 51: + stack.push(_global.ord(stack.pop())); + break; + case 55: + stack.push(_global.mbord(stack.pop())); + break; + case 153: + offset = stream.readSI16(); + nextPosition += offset; + break; + case 157: + offset = stream.readSI16(); + f = !(!stack.pop()); + if (f) { + nextPosition += offset; + } + break; + case 158: + label = stack.pop(); + _global.call(label); + break; + case 28: + variableName = '' + stack.pop(); + stackItemsExpected++; + stack.push(getVariable(variableName)); + break; + case 29: + value = stack.pop(); + variableName = '' + stack.pop(); + setVariable(variableName, value); + break; + case 154: + flags = stream.readUI8(); + target = stack.pop(); + var url = stack.pop(); + var sendVarsMethod; + if (flags & 1) { + sendVarsMethod = 'GET'; + } else if (flags & 2) { + sendVarsMethod = 'POST'; + } + var loadTargetFlag = flags & 1 << 6; + if (!loadTargetFlag) { + _global.getURL(url, target, sendVarsMethod); + break; + } + var loadVariablesFlag = flags & 1 << 7; + if (loadVariablesFlag) { + _global.loadVariables(url, target, sendVarsMethod); + } else { + _global.loadMovie(url, target, sendVarsMethod); + } + break; + case 159: + flags = stream.readUI8(); + var gotoParams = [ + stack.pop() + ]; + if (!(!(flags & 2))) { + gotoParams.push(stream.readUI16()); + } + var gotoMethod = !(!(flags & 1)) ? _global.gotoAndPlay : _global.gotoAndStop; + gotoMethod.apply(_global, gotoParams); + break; + case 32: + target = stack.pop(); + setTarget(target); + break; + case 34: + index = stack.pop(); + target = stack.pop(); + stackItemsExpected++; + stack.push(_global.getAS2Property(target, index)); + break; + case 35: + value = stack.pop(); + index = stack.pop(); + target = stack.pop(); + _global.setAS2Property(target, index, value); + break; + case 36: + var depth = stack.pop(); + target = stack.pop(); + var source = stack.pop(); + _global.duplicateMovieClip(source, target, depth); + break; + case 37: + target = stack.pop(); + _global.removeMovieClip(target); + break; + case 39: + target = stack.pop(); + var lockcenter = stack.pop(); + var constrain = !stack.pop() ? null : { + y2: stack.pop(), + x2: stack.pop(), + y1: stack.pop(), + x1: stack.pop() + }; + dragParams = [ + target, + lockcenter + ]; + if (constrain) { + dragParams = dragParams.push(constrain.x1, constrain.y1, constrain.x2, constrain.y2); + } + _global.startDrag.apply(_global, dragParams); + break; + case 40: + _global.stopDrag(); + break; + case 141: + count = stream.readUI8(); + frame = stack.pop(); + if (!_global.ifFrameLoaded(frame)) { + skipActions(count); + } + break; + case 38: + value = stack.pop(); + _global.trace(value); + break; + case 52: + stack.push(_global.getTimer()); + break; + case 48: + stack.push(_global.random(stack.pop())); + break; + case 61: + functionName = stack.pop(); + args = readArgs(stack); + stackItemsExpected++; + fn = getFunction(functionName); + result = fn.apply(scope, args); + stack.push(result); + break; + case 82: + methodName = stack.pop(); + obj = stack.pop(); + args = readArgs(stack); + stackItemsExpected++; + if (methodName !== null && methodName !== undefined && methodName !== '') { + if (obj === null || obj === undefined) { + throw new Error('Cannot call method ' + methodName + ' of ' + typeof obj); + } else if (obj !== AS2_SUPER_STUB) { + target = Object(obj); + } else { + target = as2GetPrototype(getVariable('__class').__super); + obj = getVariable('this'); + } + resolvedName = as2ResolveProperty(target, methodName); + if (resolvedName === null) { + throw new Error('Method ' + methodName + ' is not defined.'); + } + result = target.asGetPublicProperty(resolvedName).apply(obj, args); + } else if (obj !== AS2_SUPER_STUB) { + result = obj.apply(obj, args); + } else { + result = getVariable('__class').__super.apply(getVariable('this'), args); + } + stack.push(result); + break; + case 136: + count = stream.readUI16(); + constantPool = []; + for (i = 0; i < count; i++) { + constantPool.push(stream.readString()); + } + break; + case 155: + functionName = stream.readString(); + count = stream.readUI16(); + args = []; + for (i = 0; i < count; i++) { + args.push(stream.readString()); + } + codeSize = stream.readUI16(); + nextPosition += codeSize; + fn = defineFunction(functionName, args, null, stream.readBytes(codeSize)); + if (functionName) { + scope.asSetPublicProperty(functionName, fn); + } else { + stack.push(fn); + } + break; + case 60: + value = stack.pop(); + name = stack.pop(); + scope.asSetPublicProperty(name, value); + break; + case 65: + name = stack.pop(); + scope.asSetPublicProperty(name, undefined); + break; + case 58: + name = stack.pop(); + obj = stack.pop(); + obj.asSetPublicProperty(name, undefined); + stack.push(obj.asDeleteProperty(undefined, name, 0)); + break; + case 59: + name = stack.pop(); + result = deleteProperty(name); + stack.push(result); + break; + case 70: + objectName = stack.pop(); + stack.push(null); + obj = getObjectByName(objectName); + forEachPublicProperty(obj, function (name) { + stack.push(name); + }); + break; + case 73: + a = stack.pop(); + b = stack.pop(); + stack.push(a == b); + break; + case 78: + name = stack.pop(); + obj = stack.pop(); + if (name === 'prototype') { + stack.push(as2CreatePrototypeProxy(obj)); + } else { + resolvedName = as2ResolveProperty(Object(obj), name); + stack.push(resolvedName === null ? undefined : obj.asGetPublicProperty(resolvedName)); + } + break; + case 66: + obj = readArgs(stack); + stack.push(obj); + break; + case 67: + count = +stack.pop(); + validateArgsCount(count, stack.length >> 1); + obj = {}; + for (i = 0; i < count; i++) { + value = stack.pop(); + name = stack.pop(); + obj.asSetPublicProperty(name, value); + } + stack.push(obj); + break; + case 83: + methodName = stack.pop(); + obj = stack.pop(); + args = readArgs(stack); + stackItemsExpected++; + if (methodName !== null && methodName !== undefined && methodName !== '') { + resolvedName = as2ResolveProperty(obj, methodName); + if (resolvedName === null) { + throw new Error('Method ' + methodName + ' is not defined.'); + } + if (obj === null || obj === undefined) { + throw new Error('Cannot call new using method ' + resolvedName + ' of ' + typeof obj); + } + method = obj.asGetPublicProperty(resolvedName); + } else { + if (obj === null || obj === undefined) { + throw new Error('Cannot call new using ' + typeof obj); + } + method = obj; + } + if (isAvm2Class(obj)) { + result = construct(obj, args); + } else { + result = Object.create(as2GetPrototype(method) || as2GetPrototype(Object)); + method.apply(result, args); + } + result.constructor = method; + stack.push(result); + break; + case 64: + objectName = stack.pop(); + obj = getObjectByName(objectName); + args = readArgs(stack); + stackItemsExpected++; + result = createBuiltinType(obj, args); + if (typeof result === 'undefined') { + if (isAvm2Class(obj)) { + result = construct(obj, args); + } else { + result = Object.create(as2GetPrototype(obj) || as2GetPrototype(Object)); + obj.apply(result, args); + } + result.constructor = obj; + } + stack.push(result); + break; + case 79: + value = stack.pop(); + name = stack.pop(); + obj = stack.pop(); + obj.asSetPublicProperty(name, value); + break; + case 69: + obj = stack.pop(); + stack.push(as2GetType(obj) === 'movieclip' ? obj._target : void 0); + break; + case 148: + codeSize = stream.readUI16(); + obj = stack.pop(); + nextPosition += codeSize; + processWith(obj, stream.readBytes(codeSize)); + break; + case 74: + stack.push(as2ToNumber(stack.pop())); + break; + case 75: + stack.push(as2ToString(stack.pop())); + break; + case 68: + obj = stack.pop(); + result = as2GetType(obj); + stack.push(result); + break; + case 71: + a = as2ToAddPrimitive(stack.pop()); + b = as2ToAddPrimitive(stack.pop()); + if (typeof a === 'string' || typeof b === 'string') { + stack.push(as2ToString(b) + as2ToString(a)); + } else { + stack.push(as2ToNumber(b) + as2ToNumber(a)); + } + break; + case 72: + a = stack.pop(); + b = stack.pop(); + stack.push(as2Compare(b, a)); + break; + case 63: + a = as2ToNumber(stack.pop()); + b = as2ToNumber(stack.pop()); + stack.push(b % a); + break; + case 96: + a = as2ToInt32(stack.pop()); + b = as2ToInt32(stack.pop()); + stack.push(b & a); + break; + case 99: + a = as2ToInt32(stack.pop()); + b = as2ToInt32(stack.pop()); + stack.push(b << a); + break; + case 97: + a = as2ToInt32(stack.pop()); + b = as2ToInt32(stack.pop()); + stack.push(b | a); + break; + case 100: + a = as2ToInt32(stack.pop()); + b = as2ToInt32(stack.pop()); + stack.push(b >> a); + break; + case 101: + a = as2ToInt32(stack.pop()); + b = as2ToInt32(stack.pop()); + stack.push(b >>> a); + break; + case 98: + a = as2ToInt32(stack.pop()); + b = as2ToInt32(stack.pop()); + stack.push(b ^ a); + break; + case 81: + a = as2ToNumber(stack.pop()); + a--; + stack.push(a); + break; + case 80: + a = as2ToNumber(stack.pop()); + a++; + stack.push(a); + break; + case 76: + stack.push(stack[stack.length - 1]); + break; + case 62: + return stack.pop(); + case 77: + stack.push(stack.pop(), stack.pop()); + break; + case 135: + register = stream.readUI8(); + registers[register] = stack[stack.length - 1]; + break; + case 84: + constr = stack.pop(); + obj = stack.pop(); + stack.push(as2InstanceOf(Object(obj), constr)); + break; + case 85: + obj = stack.pop(); + stack.push(null); + forEachPublicProperty(obj, function (name) { + stack.push(name); + }); + break; + case 102: + a = stack.pop(); + b = stack.pop(); + stack.push(b === a); + break; + case 103: + a = stack.pop(); + b = stack.pop(); + stack.push(as2Compare(a, b)); + break; + case 104: + sa = as2ToString(stack.pop()); + sb = as2ToString(stack.pop()); + f = sb > sa; + stack.push(isSwfVersion5 ? f : f ? 1 : 0); + break; + case 142: + functionName = stream.readString(); + count = stream.readUI16(); + var registerCount = stream.readUI8(); + flags = stream.readUI16(); + var registerAllocation = []; + args = []; + for (i = 0; i < count; i++) { + register = stream.readUI8(); + paramName = stream.readString(); + args.push(paramName); + if (register) { + registerAllocation[register] = { + type: 'param', + name: paramName, + index: i + }; + } + } + codeSize = stream.readUI16(); + nextPosition += codeSize; + var j = 1; + if (flags & 1) { + registerAllocation[j++] = { + type: 'var', + name: 'this' + }; + } + if (flags & 4) { + registerAllocation[j++] = { + type: 'var', + name: 'arguments' + }; + } + if (flags & 16) { + registerAllocation[j++] = { + type: 'var', + name: 'super' + }; + } + if (flags & 64) { + registerAllocation[j++] = { + type: 'var', + name: '_root' + }; + } + if (flags & 128) { + registerAllocation[j++] = { + type: 'var', + name: '_parent' + }; + } + if (flags & 256) { + registerAllocation[j++] = { + type: 'var', + name: '_global' + }; + } + fn = defineFunction(functionName, args, registerAllocation, stream.readBytes(codeSize)); + if (functionName) { + scope.asSetPublicProperty(functionName, fn); + } else { + stack.push(fn); + } + break; + case 105: + var constrSuper = stack.pop(); + constr = stack.pop(); + obj = Object.create(constrSuper.traitsPrototype || as2GetPrototype(constrSuper), { + constructor: { + value: constr, + enumerable: false + } + }); + constr.__super = constrSuper; + constr.prototype = obj; + break; + case 43: + obj = stack.pop(); + constr = stack.pop(); + stack.push(as2InstanceOf(obj, constr) ? obj : null); + break; + case 44: + constr = stack.pop(); + count = +stack.pop(); + validateArgsCount(count, stack.length); + var interfaces = []; + for (i = 0; i < count; i++) { + interfaces.push(stack.pop()); + } + constr.$interfaces = interfaces; + break; + case 143: + flags = stream.readUI8(); + var catchIsRegisterFlag = !(!(flags & 4)); + var finallyBlockFlag = !(!(flags & 2)); + var catchBlockFlag = !(!(flags & 1)); + var trySize = stream.readUI16(); + var catchSize = stream.readUI16(); + var finallySize = stream.readUI16(); + var catchTarget = catchIsRegisterFlag ? stream.readUI8() : stream.readString(); + nextPosition += trySize + catchSize + finallySize; + processTry(catchIsRegisterFlag, finallyBlockFlag, catchBlockFlag, catchTarget, stream.readBytes(trySize), stream.readBytes(catchSize), stream.readBytes(finallySize)); + break; + case 42: + obj = stack.pop(); + throw new AS2Error(obj); + case 45: + args = readArgs(stack); + stackItemsExpected++; + result = _global.fscommand.apply(null, args); + stack.push(result); + break; + case 137: + var mode = stream.readUI8(); + break; + case 0: + return; + default: + throw new Error('Unknown action code: ' + actionCode); + } + stream.position = nextPosition; + recoveringFromError = false; + } + } catch (e) { + if (!AVM1_ERRORS_IGNORED && !currentContext.isTryCatchListening || e instanceof AS2CriticalError) { + throw e; + } + if (e instanceof AS2Error) { + throw e; + } + var AVM1_ERROR_TYPE = 1; + TelemetryService.reportTelemetry({ + topic: 'error', + error: AVM1_ERROR_TYPE + }); + stream.position = nextPosition; + if (stackItemsExpected > 0) { + while (stackItemsExpected--) { + stack.push(undefined); + } + } + if (!recoveringFromError) { + if (currentContext.errorsIgnored++ >= MAX_AVM1_ERRORS_LIMIT) { + throw new AS2CriticalError('long running script -- AVM1 errors limit is reached'); + } + console.error('AVM1 error: ' + e); + avm2.exceptions.push({ + source: 'avm1', + message: e.message, + stack: e.stack + }); + recoveringFromError = true; + } + } + } +} +var ActionTracerFactory = function () { + var indentation = 0; + var tracer = { + print: function (position, actionCode, stack) { + var stackDump = []; + for (var q = 0; q < stack.length; q++) { + var item = stack[q]; + stackDump.push(item && typeof item === 'object' ? '[' + (item.constructor && item.constructor.name ? item.constructor.name : 'Object') + ']' : item); + } + var indent = new Array(indentation + 1).join('..'); + console.log('AVM1 trace: ' + indent + position + ': ' + ActionNamesMap[actionCode] + '(' + actionCode.toString(16) + '), ' + 'stack=' + stackDump); + }, + indent: function () { + indentation++; + }, + unindent: function () { + indentation--; + }, + message: function (str) { + console.log('AVM1 trace: ------- ' + str); + } + }; + var nullTracer = { + print: function () { + }, + indent: function () { + }, + unindent: function () { + }, + message: function () { + } + }; + function ActionTracerFactory() { + } + ActionTracerFactory.get = function () { + return AVM1_TRACE_ENABLED ? tracer : nullTracer; + }; + return ActionTracerFactory; + }(); +var ActionNamesMap = { + 0: 'EOA', + 4: 'ActionNextFrame', + 5: 'ActionPreviousFrame', + 6: 'ActionPlay', + 7: 'ActionStop', + 8: 'ActionToggleQuality', + 9: 'ActionStopSounds', + 10: 'ActionAdd', + 11: 'ActionSubtract', + 12: 'ActionMultiply', + 13: 'ActionDivide', + 14: 'ActionEquals', + 15: 'ActionLess', + 16: 'ActionAnd', + 17: 'ActionOr', + 18: 'ActionNot', + 19: 'ActionStringEquals', + 20: 'ActionStringLength', + 21: 'ActionStringExtract', + 23: 'ActionPop', + 24: 'ActionToInteger', + 28: 'ActionGetVariable', + 29: 'ActionSetVariable', + 32: 'ActionSetTarget2', + 33: 'ActionStringAdd', + 34: 'ActionGetProperty', + 35: 'ActionSetProperty', + 36: 'ActionCloneSprite', + 37: 'ActionRemoveSprite', + 38: 'ActionTrace', + 39: 'ActionStartDrag', + 40: 'ActionEndDrag', + 41: 'ActionStringLess', + 42: 'ActionThrow', + 43: 'ActionCastOp', + 44: 'ActionImplementsOp', + 45: 'ActionFSCommand2', + 48: 'ActionRandomNumber', + 49: 'ActionMBStringLength', + 50: 'ActionCharToAscii', + 51: 'ActionAsciiToChar', + 52: 'ActionGetTime', + 53: 'ActionMBStringExtrac', + 54: 'ActionMBCharToAscii', + 55: 'ActionMBAsciiToChar', + 58: 'ActionDelete', + 59: 'ActionDelete2', + 60: 'ActionDefineLocal', + 61: 'ActionCallFunction', + 62: 'ActionReturn', + 63: 'ActionModulo', + 64: 'ActionNewObject', + 65: 'ActionDefineLocal2', + 66: 'ActionInitArray', + 67: 'ActionInitObject', + 68: 'ActionTypeOf', + 69: 'ActionTargetPath', + 70: 'ActionEnumerate', + 71: 'ActionAdd2', + 72: 'ActionLess2', + 73: 'ActionEquals2', + 74: 'ActionToNumber', + 75: 'ActionToString', + 76: 'ActionPushDuplicate', + 77: 'ActionStackSwap', + 78: 'ActionGetMember', + 79: 'ActionSetMember', + 80: 'ActionIncrement', + 81: 'ActionDecrement', + 82: 'ActionCallMethod', + 83: 'ActionNewMethod', + 84: 'ActionInstanceOf', + 85: 'ActionEnumerate2', + 96: 'ActionBitAnd', + 97: 'ActionBitOr', + 98: 'ActionBitXor', + 99: 'ActionBitLShift', + 100: 'ActionBitRShift', + 101: 'ActionBitURShift', + 102: 'ActionStrictEquals', + 103: 'ActionGreater', + 104: 'ActionStringGreater', + 105: 'ActionExtends', + 129: 'ActionGotoFrame', + 131: 'ActionGetURL', + 135: 'ActionStoreRegister', + 136: 'ActionConstantPool', + 137: 'ActionStrictMode', + 138: 'ActionWaitForFrame', + 139: 'ActionSetTarget', + 140: 'ActionGoToLabel', + 141: 'ActionWaitForFrame2', + 142: 'ActionDefineFunction', + 143: 'ActionTry', + 148: 'ActionWith', + 150: 'ActionPush', + 153: 'ActionJump', + 154: 'ActionGetURL2', + 155: 'ActionDefineFunction', + 157: 'ActionIf', + 158: 'ActionCall', + 159: 'ActionGotoFrame2' + }; +if (typeof GLOBAL !== 'undefined') { + GLOBAL.createBuiltinType = createBuiltinType; + GLOBAL.executeActions = executeActions; + GLOBAL.AS2Context = AS2Context; +} +var jsGlobal = function () { + return this || (1, eval)('this'); + }(); +var inBrowser = typeof console != 'undefined'; +var release = true; +var debug = !true; +if (!jsGlobal.performance) { + jsGlobal.performance = {}; +} +if (!jsGlobal.performance.now) { + jsGlobal.performance.now = dateNow; +} +function log(message) { + var optionalParams = []; + for (var _i = 0; _i < arguments.length - 1; _i++) { + optionalParams[_i] = arguments[_i + 1]; + } + jsGlobal.print(message); +} +function warn(message) { + var optionalParams = []; + for (var _i = 0; _i < arguments.length - 1; _i++) { + optionalParams[_i] = arguments[_i + 1]; + } + if (inBrowser) { + console.warn(message); + } else { + jsGlobal.print(message); + } +} +var Shumway; +(function (Shumway) { + (function (CharacterCodes) { + CharacterCodes[CharacterCodes['_0'] = 48] = '_0'; + CharacterCodes[CharacterCodes['_1'] = 49] = '_1'; + CharacterCodes[CharacterCodes['_2'] = 50] = '_2'; + CharacterCodes[CharacterCodes['_3'] = 51] = '_3'; + CharacterCodes[CharacterCodes['_4'] = 52] = '_4'; + CharacterCodes[CharacterCodes['_5'] = 53] = '_5'; + CharacterCodes[CharacterCodes['_6'] = 54] = '_6'; + CharacterCodes[CharacterCodes['_7'] = 55] = '_7'; + CharacterCodes[CharacterCodes['_8'] = 56] = '_8'; + CharacterCodes[CharacterCodes['_9'] = 57] = '_9'; + }(Shumway.CharacterCodes || (Shumway.CharacterCodes = {}))); + var CharacterCodes = Shumway.CharacterCodes; + Shumway.UINT32_CHAR_BUFFER_LENGTH = 10; + Shumway.UINT32_MAX = 4294967295; + Shumway.UINT32_MAX_DIV_10 = 429496729; + Shumway.UINT32_MAX_MOD_10 = 5; + function isString(value) { + return typeof value === 'string'; + } + Shumway.isString = isString; + function isFunction(value) { + return typeof value === 'function'; + } + Shumway.isFunction = isFunction; + function isNumber(value) { + return typeof value === 'number'; + } + Shumway.isNumber = isNumber; + function isNumberOrString(value) { + return typeof value === 'number' || typeof value === 'string'; + } + Shumway.isNumberOrString = isNumberOrString; + function isObject(value) { + return typeof value === 'object' || typeof value === 'function'; + } + Shumway.isObject = isObject; + function toNumber(x) { + return +x; + } + Shumway.toNumber = toNumber; + function isNumericString(value) { + return String(Number(value)) === value; + } + Shumway.isNumericString = isNumericString; + function isNumeric(value) { + if (typeof value === 'number') { + return true; + } else if (typeof value === 'string') { + return isIndex(value) || isNumericString(value); + } else { + Debug.notImplemented(typeof value); + } + } + Shumway.isNumeric = isNumeric; + function isIndex(value) { + var index = 0; + if (typeof value === 'number') { + index = value | 0; + if (value === index && index >= 0) { + return true; + } + return value >>> 0 === value; + } + if (typeof value !== 'string') { + return false; + } + var length = value.length; + if (length === 0) { + return false; + } + if (value === '0') { + return true; + } + if (length > Shumway.UINT32_CHAR_BUFFER_LENGTH) { + return false; + } + var i = 0; + index = value.charCodeAt(i++) - 48; + if (index < 1 || index > 9) { + return false; + } + var oldIndex = 0; + var c = 0; + while (i < length) { + c = value.charCodeAt(i++) - 48; + if (c < 0 || c > 9) { + return false; + } + oldIndex = index; + index = 10 * index + c; + } + if (oldIndex < Shumway.UINT32_MAX_DIV_10 || oldIndex === Shumway.UINT32_MAX_DIV_10 && c <= Shumway.UINT32_MAX_MOD_10) { + return true; + } + return false; + } + Shumway.isIndex = isIndex; + function isNullOrUndefined(value) { + return value == undefined; + } + Shumway.isNullOrUndefined = isNullOrUndefined; + (function (Debug) { + function backtrace() { + try { + throw new Error(); + } catch (e) { + return e.stack ? e.stack.split('\n').slice(2).join('\n') : ''; + } + } + Debug.backtrace = backtrace; + function error(message) { + if (!inBrowser) { + warn(Debug.backtrace()); + } + throw new Error(message); + } + Debug.error = error; + function assert(condition) { + var args = []; + for (var _i = 0; _i < arguments.length - 1; _i++) { + args[_i] = arguments[_i + 1]; + } + if (condition === '') { + condition = true; + } + if (!condition) { + var message = Array.prototype.slice.call(arguments); + message.shift(); + Debug.error(message.join('')); + } + } + Debug.assert = assert; + function assertNotImplemented(condition, message) { + if (!condition) { + Debug.error('NotImplemented: ' + message); + } + } + Debug.assertNotImplemented = assertNotImplemented; + function warning(message) { + true; + } + Debug.warning = warning; + function notUsed(message) { + true; + } + Debug.notUsed = notUsed; + function notImplemented(message) { + true; + } + Debug.notImplemented = notImplemented; + function somewhatImplemented(message) { + Debug.warning('somewhatImplemented: ' + message); + } + Debug.somewhatImplemented = somewhatImplemented; + function unexpected(message) { + Debug.assert(false, 'Unexpected: ' + message); + } + Debug.unexpected = unexpected; + }(Shumway.Debug || (Shumway.Debug = {}))); + var Debug = Shumway.Debug; + function getTicks() { + return performance.now(); + } + Shumway.getTicks = getTicks; + (function (ArrayUtilities) { + function popManyInto(src, count, dst) { + true; + for (var i = count - 1; i >= 0; i--) { + dst[i] = src.pop(); + } + dst.length = count; + } + ArrayUtilities.popManyInto = popManyInto; + }(Shumway.ArrayUtilities || (Shumway.ArrayUtilities = {}))); + var ArrayUtilities = Shumway.ArrayUtilities; + (function (ObjectUtilities) { + function boxValue(value) { + if (Shumway.isNullOrUndefined(value) || Shumway.isObject(value)) { + return value; + } + return Object(value); + } + ObjectUtilities.boxValue = boxValue; + function toKeyValueArray(object) { + var hasOwnProperty = Object.prototype.hasOwnProperty; + var array = []; + for (var k in object) { + if (hasOwnProperty.call(object, k)) { + array.push([ + k, + object[k] + ]); + } + } + return array; + } + ObjectUtilities.toKeyValueArray = toKeyValueArray; + function hasOwnProperty(object, name) { + return Object.prototype.hasOwnProperty.call(object, name); + } + ObjectUtilities.hasOwnProperty = hasOwnProperty; + function createEmptyObject() { + return Object.create(null); + } + ObjectUtilities.createEmptyObject = createEmptyObject; + function createMap() { + return Object.create(null); + } + ObjectUtilities.createMap = createMap; + function createArrayMap() { + return []; + } + ObjectUtilities.createArrayMap = createArrayMap; + function defineReadOnlyProperty(object, name, value) { + Object.defineProperty(object, name, { + value: value, + writable: false, + configurable: true, + enumerable: false + }); + } + ObjectUtilities.defineReadOnlyProperty = defineReadOnlyProperty; + function getOwnPropertyDescriptors(object) { + var o = ObjectUtilities.createMap(); + var properties = Object.getOwnPropertyNames(object); + for (var i = 0; i < properties.length; i++) { + o[properties[i]] = Object.getOwnPropertyDescriptor(object, properties[i]); + } + return o; + } + ObjectUtilities.getOwnPropertyDescriptors = getOwnPropertyDescriptors; + function cloneObject(object) { + var clone = ObjectUtilities.createEmptyObject(); + for (var property in object) { + clone[property] = object[property]; + } + return clone; + } + ObjectUtilities.cloneObject = cloneObject; + function copyProperties(object, template) { + for (var property in template) { + object[property] = template[property]; + } + } + ObjectUtilities.copyProperties = copyProperties; + function getLatestGetterOrSetterPropertyDescriptor(object, name) { + var descriptor = {}; + while (object) { + var tmp = Object.getOwnPropertyDescriptor(object, name); + if (tmp) { + descriptor.get = descriptor.get || tmp.get; + descriptor.set = descriptor.set || tmp.set; + } + if (descriptor.get && descriptor.set) { + break; + } + object = Object.getPrototypeOf(object); + } + return descriptor; + } + ObjectUtilities.getLatestGetterOrSetterPropertyDescriptor = getLatestGetterOrSetterPropertyDescriptor; + function defineNonEnumerableGetterOrSetter(obj, name, value, isGetter) { + var descriptor = ObjectUtilities.getLatestGetterOrSetterPropertyDescriptor(obj, name); + descriptor.configurable = true; + descriptor.enumerable = false; + if (isGetter) { + descriptor.get = value; + } else { + descriptor.set = value; + } + Object.defineProperty(obj, name, descriptor); + } + ObjectUtilities.defineNonEnumerableGetterOrSetter = defineNonEnumerableGetterOrSetter; + function defineNonEnumerableGetter(obj, name, getter) { + Object.defineProperty(obj, name, { + get: getter, + configurable: true, + enumerable: false + }); + } + ObjectUtilities.defineNonEnumerableGetter = defineNonEnumerableGetter; + function defineNonEnumerableSetter(obj, name, setter) { + Object.defineProperty(obj, name, { + set: setter, + configurable: true, + enumerable: false + }); + } + ObjectUtilities.defineNonEnumerableSetter = defineNonEnumerableSetter; + function defineNonEnumerableProperty(obj, name, value) { + Object.defineProperty(obj, name, { + value: value, + writable: true, + configurable: true, + enumerable: false + }); + } + ObjectUtilities.defineNonEnumerableProperty = defineNonEnumerableProperty; + function defineNonEnumerableForwardingProperty(obj, name, otherName) { + Object.defineProperty(obj, name, { + get: FunctionUtilities.makeForwardingGetter(otherName), + set: FunctionUtilities.makeForwardingSetter(otherName), + writable: true, + configurable: true, + enumerable: false + }); + } + ObjectUtilities.defineNonEnumerableForwardingProperty = defineNonEnumerableForwardingProperty; + function defineNewNonEnumerableProperty(obj, name, value) { + true; + ObjectUtilities.defineNonEnumerableProperty(obj, name, value); + } + ObjectUtilities.defineNewNonEnumerableProperty = defineNewNonEnumerableProperty; + }(Shumway.ObjectUtilities || (Shumway.ObjectUtilities = {}))); + var ObjectUtilities = Shumway.ObjectUtilities; + (function (FunctionUtilities) { + function makeForwardingGetter(target) { + return new Function('return this["' + target + '"]'); + } + FunctionUtilities.makeForwardingGetter = makeForwardingGetter; + function makeForwardingSetter(target) { + return new Function('value', 'this["' + target + '"] = value;'); + } + FunctionUtilities.makeForwardingSetter = makeForwardingSetter; + function bindSafely(fn, object) { + true; + var f = fn.bind(object); + f.boundTo = object; + return f; + } + FunctionUtilities.bindSafely = bindSafely; + }(Shumway.FunctionUtilities || (Shumway.FunctionUtilities = {}))); + var FunctionUtilities = Shumway.FunctionUtilities; + (function (StringUtilities) { + function toSafeString(value) { + if (typeof value === 'string') { + return '"' + value + '"'; + } + if (typeof value === 'number' || typeof value === 'boolean') { + return String(value); + } + return typeof value; + } + StringUtilities.toSafeString = toSafeString; + function toSafeArrayString(array) { + var str = []; + for (var i = 0; i < array.length; i++) { + str.push(toSafeString(array[i])); + } + return str.join(', '); + } + StringUtilities.toSafeArrayString = toSafeArrayString; + function utf8decode(str) { + var bytes = new Uint8Array(str.length * 4); + var b = 0; + for (var i = 0, j = str.length; i < j; i++) { + var code = str.charCodeAt(i); + if (code <= 127) { + bytes[b++] = code; + continue; + } + if (55296 <= code && code <= 56319) { + var codeLow = str.charCodeAt(i + 1); + if (56320 <= codeLow && codeLow <= 57343) { + code = ((code & 1023) << 10) + (codeLow & 1023) + 65536; + ++i; + } + } + if ((code & 4292870144) !== 0) { + bytes[b++] = 248 | code >>> 24 & 3; + bytes[b++] = 128 | code >>> 18 & 63; + bytes[b++] = 128 | code >>> 12 & 63; + bytes[b++] = 128 | code >>> 6 & 63; + bytes[b++] = 128 | code & 63; + } else if ((code & 4294901760) !== 0) { + bytes[b++] = 240 | code >>> 18 & 7; + bytes[b++] = 128 | code >>> 12 & 63; + bytes[b++] = 128 | code >>> 6 & 63; + bytes[b++] = 128 | code & 63; + } else if ((code & 4294965248) !== 0) { + bytes[b++] = 224 | code >>> 12 & 15; + bytes[b++] = 128 | code >>> 6 & 63; + bytes[b++] = 128 | code & 63; + } else { + bytes[b++] = 192 | code >>> 6 & 31; + bytes[b++] = 128 | code & 63; + } + } + return bytes.subarray(0, b); + } + StringUtilities.utf8decode = utf8decode; + function utf8encode(bytes) { + var j = 0, str = ''; + while (j < bytes.length) { + var b1 = bytes[j++] & 255; + if (b1 <= 127) { + str += String.fromCharCode(b1); + } else { + var currentPrefix = 192; + var validBits = 5; + do { + var mask = currentPrefix >> 1 | 128; + if ((b1 & mask) === currentPrefix) + break; + currentPrefix = currentPrefix >> 1 | 128; + --validBits; + } while (validBits >= 0); + if (validBits <= 0) { + str += String.fromCharCode(b1); + continue; + } + var code = b1 & (1 << validBits) - 1; + var invalid = false; + for (var i = 5; i >= validBits; --i) { + var bi = bytes[j++]; + if ((bi & 192) != 128) { + invalid = true; + break; + } + code = code << 6 | bi & 63; + } + if (invalid) { + for (var k = j - (7 - i); k < j; ++k) { + str += String.fromCharCode(bytes[k] & 255); + } + continue; + } + if (code >= 65536) { + str += String.fromCharCode(code - 65536 >> 10 & 1023 | 55296, code & 1023 | 56320); + } else { + str += String.fromCharCode(code); + } + } + } + return str; + } + StringUtilities.utf8encode = utf8encode; + function base64ArrayBuffer(arrayBuffer) { + var base64 = ''; + var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + var bytes = new Uint8Array(arrayBuffer); + var byteLength = bytes.byteLength; + var byteRemainder = byteLength % 3; + var mainLength = byteLength - byteRemainder; + var a, b, c, d; + var chunk; + for (var i = 0; i < mainLength; i = i + 3) { + chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2]; + a = (chunk & 16515072) >> 18; + b = (chunk & 258048) >> 12; + c = (chunk & 4032) >> 6; + d = chunk & 63; + base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]; + } + if (byteRemainder == 1) { + chunk = bytes[mainLength]; + a = (chunk & 252) >> 2; + b = (chunk & 3) << 4; + base64 += encodings[a] + encodings[b] + '=='; + } else if (byteRemainder == 2) { + chunk = bytes[mainLength] << 8 | bytes[mainLength + 1]; + a = (chunk & 64512) >> 10; + b = (chunk & 1008) >> 4; + c = (chunk & 15) << 2; + base64 += encodings[a] + encodings[b] + encodings[c] + '='; + } + return base64; + } + StringUtilities.base64ArrayBuffer = base64ArrayBuffer; + function escapeString(str) { + if (str !== undefined) { + str = str.replace(/[^\w$]/gi, '$'); + if (/^\d/.test(str)) { + str = '$' + str; + } + } + return str; + } + StringUtilities.escapeString = escapeString; + function fromCharCodeArray(buffer) { + var str = '', SLICE = 1024 * 16; + for (var i = 0; i < buffer.length; i += SLICE) { + var chunk = Math.min(buffer.length - i, SLICE); + str += String.fromCharCode.apply(null, buffer.subarray(i, i + chunk)); + } + return str; + } + StringUtilities.fromCharCodeArray = fromCharCodeArray; + var _encoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$_'; + function variableLengthEncodeInt32(n) { + var e = _encoding; + var bitCount = 32 - IntegerUtilities.leadingZeros(n); + var l = Math.ceil(bitCount / 6); + var s = e[l]; + for (var i = l - 1; i >= 0; i--) { + var offset = i * 6; + s += e[n >> offset & 63]; + } + true; + return s; + } + StringUtilities.variableLengthEncodeInt32 = variableLengthEncodeInt32; + function toEncoding(n) { + return _encoding[n]; + } + StringUtilities.toEncoding = toEncoding; + function fromEncoding(s) { + var c = s.charCodeAt(0); + var e = 0; + if (c >= 65 && c <= 90) { + return c - 65; + } else if (c >= 97 && c <= 122) { + return c - 71; + } else if (c >= 48 && c <= 57) { + return c + 4; + } else if (c === 36) { + return 62; + } else if (c === 95) { + return 63; + } + } + StringUtilities.fromEncoding = fromEncoding; + function variableLengthDecodeInt32(s) { + var l = StringUtilities.fromEncoding(s[0]); + var n = 0; + for (var i = 0; i < l; i++) { + var offset = (l - i - 1) * 6; + n |= StringUtilities.fromEncoding(s[1 + i]) << offset; + } + return n; + } + StringUtilities.variableLengthDecodeInt32 = variableLengthDecodeInt32; + }(Shumway.StringUtilities || (Shumway.StringUtilities = {}))); + var StringUtilities = Shumway.StringUtilities; + (function (HashUtilities) { + var _md5R = new Uint8Array([ + 7, + 12, + 17, + 22, + 7, + 12, + 17, + 22, + 7, + 12, + 17, + 22, + 7, + 12, + 17, + 22, + 5, + 9, + 14, + 20, + 5, + 9, + 14, + 20, + 5, + 9, + 14, + 20, + 5, + 9, + 14, + 20, + 4, + 11, + 16, + 23, + 4, + 11, + 16, + 23, + 4, + 11, + 16, + 23, + 4, + 11, + 16, + 23, + 6, + 10, + 15, + 21, + 6, + 10, + 15, + 21, + 6, + 10, + 15, + 21, + 6, + 10, + 15, + 21 + ]); + var _md5K = new Int32Array([ + -680876936, + -389564586, + 606105819, + -1044525330, + -176418897, + 1200080426, + -1473231341, + -45705983, + 1770035416, + -1958414417, + -42063, + -1990404162, + 1804603682, + -40341101, + -1502002290, + 1236535329, + -165796510, + -1069501632, + 643717713, + -373897302, + -701558691, + 38016083, + -660478335, + -405537848, + 568446438, + -1019803690, + -187363961, + 1163531501, + -1444681467, + -51403784, + 1735328473, + -1926607734, + -378558, + -2022574463, + 1839030562, + -35309556, + -1530992060, + 1272893353, + -155497632, + -1094730640, + 681279174, + -358537222, + -722521979, + 76029189, + -640364487, + -421815835, + 530742520, + -995338651, + -198630844, + 1126891415, + -1416354905, + -57434055, + 1700485571, + -1894986606, + -1051523, + -2054922799, + 1873313359, + -30611744, + -1560198380, + 1309151649, + -145523070, + -1120210379, + 718787259, + -343485551 + ]); + function hashBytesTo32BitsMD5(data, offset, length) { + var r = _md5R; + var k = _md5K; + var h0 = 1732584193, h1 = -271733879, h2 = -1732584194, h3 = 271733878; + var paddedLength = length + 72 & ~63; + var padded = new Uint8Array(paddedLength); + var i, j, n; + for (i = 0; i < length; ++i) { + padded[i] = data[offset++]; + } + padded[i++] = 128; + n = paddedLength - 8; + while (i < n) { + padded[i++] = 0; + } + padded[i++] = length << 3 & 255; + padded[i++] = length >> 5 & 255; + padded[i++] = length >> 13 & 255; + padded[i++] = length >> 21 & 255; + padded[i++] = length >>> 29 & 255; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + var w = new Int32Array(16); + for (i = 0; i < paddedLength;) { + for (j = 0; j < 16; ++j, i += 4) { + w[j] = padded[i] | padded[i + 1] << 8 | padded[i + 2] << 16 | padded[i + 3] << 24; + } + var a = h0, b = h1, c = h2, d = h3, f, g; + for (j = 0; j < 64; ++j) { + if (j < 16) { + f = b & c | ~b & d; + g = j; + } else if (j < 32) { + f = d & b | ~d & c; + g = 5 * j + 1 & 15; + } else if (j < 48) { + f = b ^ c ^ d; + g = 3 * j + 5 & 15; + } else { + f = c ^ (b | ~d); + g = 7 * j & 15; + } + var tmp = d, rotateArg = a + f + k[j] + w[g] | 0, rotate = r[j]; + d = c; + c = b; + b = b + (rotateArg << rotate | rotateArg >>> 32 - rotate) | 0; + a = tmp; + } + h0 = h0 + a | 0; + h1 = h1 + b | 0; + h2 = h2 + c | 0; + h3 = h3 + d | 0; + } + return h0; + } + HashUtilities.hashBytesTo32BitsMD5 = hashBytesTo32BitsMD5; + function hashBytesTo32BitsAdler(data, offset, length) { + var a = 1; + var b = 0; + var end = offset + length; + for (var i = offset; i < end; ++i) { + a = (a + (data[i] & 255)) % 65521; + b = (b + a) % 65521; + } + return b << 16 | a; + } + HashUtilities.hashBytesTo32BitsAdler = hashBytesTo32BitsAdler; + }(Shumway.HashUtilities || (Shumway.HashUtilities = {}))); + var HashUtilities = Shumway.HashUtilities; + (function (IntegerUtilities) { + function bitCount(i) { + i = i - (i >> 1 & 1431655765); + i = (i & 858993459) + (i >> 2 & 858993459); + return (i + (i >> 4) & 252645135) * 16843009 >> 24; + } + IntegerUtilities.bitCount = bitCount; + function ones(i) { + i = i - (i >> 1 & 1431655765); + i = (i & 858993459) + (i >> 2 & 858993459); + return (i + (i >> 4) & 252645135) * 16843009 >> 24; + } + IntegerUtilities.ones = ones; + function leadingZeros(i) { + i |= i >> 1; + i |= i >> 2; + i |= i >> 4; + i |= i >> 8; + i |= i >> 16; + return 32 - IntegerUtilities.ones(i); + } + IntegerUtilities.leadingZeros = leadingZeros; + function trailingZeros(i) { + return IntegerUtilities.ones((i & -i) - 1); + } + IntegerUtilities.trailingZeros = trailingZeros; + function getFlags(i, flags) { + var str = ''; + for (var i = 0; i < flags.length; i++) { + if (i & 1 << i) { + str += flags[i] + ' '; + } + } + if (str.length === 0) { + return ''; + } + return str.trim(); + } + IntegerUtilities.getFlags = getFlags; + function isPowerOfTwo(x) { + return x && (x & x - 1) === 0; + } + IntegerUtilities.isPowerOfTwo = isPowerOfTwo; + }(Shumway.IntegerUtilities || (Shumway.IntegerUtilities = {}))); + var IntegerUtilities = Shumway.IntegerUtilities; + var IndentingWriter = function () { + function IndentingWriter(suppressOutput, outFn) { + if (typeof suppressOutput === 'undefined') { + suppressOutput = false; + } + this._tab = ' '; + this._padding = ''; + this._suppressOutput = suppressOutput; + this._out = outFn || IndentingWriter._consoleOutFn; + } + IndentingWriter.prototype.writeLn = function (str) { + if (!this._suppressOutput) { + this._out(this._padding + str); + } + }; + IndentingWriter.prototype.writeLns = function (str) { + var lines = str.split('\n'); + for (var i = 0; i < lines.length; i++) { + this.writeLn(lines[i]); + } + }; + IndentingWriter.prototype.debugLn = function (str) { + this.colorLn(IndentingWriter.PURPLE, str); + }; + IndentingWriter.prototype.yellowLn = function (str) { + this.colorLn(IndentingWriter.YELLOW, str); + }; + IndentingWriter.prototype.greenLn = function (str) { + this.colorLn(IndentingWriter.GREEN, str); + }; + IndentingWriter.prototype.redLn = function (str) { + this.colorLn(IndentingWriter.RED, str); + }; + IndentingWriter.prototype.colorLn = function (color, str) { + if (!this._suppressOutput) { + if (!inBrowser) { + this._out(this._padding + color + str + IndentingWriter.ENDC); + } else { + this._out(this._padding + str); + } + } + }; + IndentingWriter.prototype.enter = function (str) { + if (!this._suppressOutput) { + this._out(this._padding + str); + } + this.indent(); + }; + IndentingWriter.prototype.leaveAndEnter = function (str) { + this.leave(str); + this.indent(); + }; + IndentingWriter.prototype.leave = function (str) { + this.outdent(); + if (!this._suppressOutput) { + this._out(this._padding + str); + } + }; + IndentingWriter.prototype.indent = function () { + this._padding += this._tab; + }; + IndentingWriter.prototype.outdent = function () { + if (this._padding.length > 0) { + this._padding = this._padding.substring(0, this._padding.length - this._tab.length); + } + }; + IndentingWriter.prototype.writeArray = function (arr, detailed, noNumbers) { + if (typeof detailed === 'undefined') { + detailed = false; + } + if (typeof noNumbers === 'undefined') { + noNumbers = false; + } + detailed = detailed || false; + for (var i = 0, j = arr.length; i < j; i++) { + var prefix = ''; + if (detailed) { + if (arr[i] === null) { + prefix = 'null'; + } else if (arr[i] === undefined) { + prefix = 'undefined'; + } else { + prefix = arr[i].constructor.name; + } + prefix += ' '; + } + var number = noNumbers ? '' : ('' + i).padRight(' ', 4); + this.writeLn(number + prefix + arr[i]); + } + }; + IndentingWriter.PURPLE = '\x1b[94m'; + IndentingWriter.YELLOW = '\x1b[93m'; + IndentingWriter.GREEN = '\x1b[92m'; + IndentingWriter.RED = '\x1b[91m'; + IndentingWriter.ENDC = '\x1b[0m'; + IndentingWriter._consoleOutFn = inBrowser ? console.info.bind(console) : print; + return IndentingWriter; + }(); + Shumway.IndentingWriter = IndentingWriter; + var SortedListNode = function () { + function SortedListNode(value, next) { + this.value = value; + this.next = next; + } + return SortedListNode; + }(); + var SortedList = function () { + function SortedList(compare) { + true; + this._compare = compare; + this._head = null; + this._length = 0; + } + SortedList.prototype.push = function (value) { + true; + this._length++; + if (!this._head) { + this._head = new SortedListNode(value, null); + return; + } + var curr = this._head; + var prev = null; + var node = new SortedListNode(value, null); + var compare = this._compare; + while (curr) { + if (compare(curr.value, node.value) > 0) { + if (prev) { + node.next = curr; + prev.next = node; + } else { + node.next = this._head; + this._head = node; + } + return; + } + prev = curr; + curr = curr.next; + } + prev.next = node; + }; + SortedList.prototype.forEach = function (visitor) { + var curr = this._head; + var last = null; + while (curr) { + var result = visitor(curr.value); + if (result === SortedList.RETURN) { + return; + } else if (result === SortedList.DELETE) { + if (!last) { + curr = this._head = this._head.next; + } else { + curr = last.next = curr.next; + } + } else { + last = curr; + curr = curr.next; + } + } + }; + SortedList.prototype.isEmpty = function () { + return !this._head; + }; + SortedList.prototype.pop = function () { + if (!this._head) { + return undefined; + } + this._length--; + var ret = this._head; + this._head = this._head.next; + return ret.value; + }; + SortedList.prototype.contains = function (value) { + var curr = this._head; + while (curr) { + if (curr.value === value) { + return true; + } + curr = curr.next; + } + return false; + }; + SortedList.prototype.toString = function () { + var str = '['; + var curr = this._head; + while (curr) { + str += curr.value.toString(); + curr = curr.next; + if (curr) { + str += ','; + } + } + str += ']'; + return str; + }; + SortedList.RETURN = 1; + SortedList.DELETE = 2; + return SortedList; + }(); + Shumway.SortedList = SortedList; + var CIRCULAR_BUFFER_MASK = 4095; + var CIRCULAR_BUFFER_SIZE = 4096; + var CircularBuffer = function () { + function CircularBuffer(Type) { + this.index = 0; + this.start = 0; + this.array = new Type(CIRCULAR_BUFFER_SIZE); + } + CircularBuffer.prototype.get = function (i) { + return this.array[i]; + }; + CircularBuffer.prototype.forEachInReverse = function (visitor) { + if (this.isEmpty()) { + return; + } + var i = this.index === 0 ? CIRCULAR_BUFFER_SIZE - 1 : this.index - 1; + while (i !== this.start) { + if (visitor(this.array[i], i)) { + break; + } + i = i === 0 ? CIRCULAR_BUFFER_SIZE - 1 : i - 1; + } + }; + CircularBuffer.prototype.write = function (value) { + this.array[this.index] = value; + this.index = this.index + 1 & CIRCULAR_BUFFER_MASK; + if (this.index === this.start) { + this.start = this.start + 1 & CIRCULAR_BUFFER_MASK; + } + }; + CircularBuffer.prototype.isFull = function () { + return (this.index + 1 & CIRCULAR_BUFFER_MASK) === this.start; + }; + CircularBuffer.prototype.isEmpty = function () { + return this.index === this.start; + }; + return CircularBuffer; + }(); + Shumway.CircularBuffer = CircularBuffer; +}(Shumway || (Shumway = {}))); +var assert = Shumway.Debug.assert; +var IndentingWriter = Shumway.IndentingWriter; +var assert = Shumway.Debug.assert; +var $DEBUG; +var release = true; +var c4CoerceNonPrimitiveParameters = false; +var c4CoerceNonPrimitive = false; +var c4AsTypeLate = true; +var error = Shumway.Debug.error; +var assertNotImplemented = Shumway.Debug.assertNotImplemented; +var warning = Shumway.Debug.warning; +var notImplemented = Shumway.Debug.notImplemented; +var somewhatImplemented = Shumway.Debug.somewhatImplemented; +var unexpected = Shumway.Debug.unexpected; +var defineReadOnlyProperty = Shumway.ObjectUtilities.defineReadOnlyProperty; +var createEmptyObject = Shumway.ObjectUtilities.createEmptyObject; +var makeForwardingGetter = Shumway.FunctionUtilities.makeForwardingGetter; +var makeForwardingSetter = Shumway.FunctionUtilities.makeForwardingSetter; +var bindSafely = Shumway.FunctionUtilities.bindSafely; +var cloneObject = Shumway.ObjectUtilities.cloneObject; +var copyProperties = Shumway.ObjectUtilities.copyProperties; +var toSafeString = Shumway.StringUtilities.toSafeString; +var toSafeArrayString = Shumway.StringUtilities.toSafeArrayString; +var getLatestGetterOrSetterPropertyDescriptor = Shumway.ObjectUtilities.getLatestGetterOrSetterPropertyDescriptor; +var defineNonEnumerableGetterOrSetter = Shumway.ObjectUtilities.defineNonEnumerableGetterOrSetter; +var defineNonEnumerableGetter = Shumway.ObjectUtilities.defineNonEnumerableGetter; +var defineNonEnumerableSetter = Shumway.ObjectUtilities.defineNonEnumerableSetter; +var defineNonEnumerableProperty = Shumway.ObjectUtilities.defineNonEnumerableProperty; +var defineNonEnumerableForwardingProperty = Shumway.ObjectUtilities.defineNonEnumerableForwardingProperty; +var defineNewNonEnumerableProperty = Shumway.ObjectUtilities.defineNewNonEnumerableProperty; +var isNumeric = Shumway.isNumeric; +var isNullOrUndefined = Shumway.isNullOrUndefined; +var isPowerOfTwo = Shumway.IntegerUtilities.isPowerOfTwo; +function time(fn, count) { + var start = performance.now(); + for (var i = 0; i < count; i++) { + fn(); + } + var time = (performance.now() - start) / count; + console.info('Took: ' + time.toFixed(2) + 'ms.'); + return time; +} +function clamp(x, min, max) { + if (x < min) { + return min; + } else if (x > max) { + return max; + } + return x; +} +var fromCharCodeArray = Shumway.StringUtilities.fromCharCodeArray; +function hasOwnProperty(object, name) { + return Object.prototype.hasOwnProperty.call(object, name); +} +var toKeyValueArray = Shumway.ObjectUtilities.toKeyValueArray; +var boxValue = Shumway.ObjectUtilities.boxValue; +function isObject(value) { + return typeof value === 'object' || typeof value === 'function'; +} +function isString(value) { + return typeof value === 'string'; +} +function isFunction(value) { + return typeof value === 'function'; +} +function isNumber(value) { + return typeof value === 'number'; +} +function toNumber(x) { + return +x; +} +function setBitFlags(flags, flag, value) { + return value ? flags | flag : flags & ~flag; +} +function getBitFlags(flags, flag) { + return !(!(flags & flag)); +} +(function () { + function extendBuiltin(proto, prop, f) { + if (!proto[prop]) { + Object.defineProperty(proto, prop, { + value: f, + writable: true, + configurable: true, + enumerable: false + }); + } + } + var Sp = String.prototype; + function removeColors(s) { + return s.replace(/\033\[[0-9]*m/g, ''); + } + extendBuiltin(Sp, 'padRight', function (c, n) { + var str = this; + var length = removeColors(str).length; + if (!c || length >= n) { + return str; + } + var max = (n - length) / c.length; + for (var i = 0; i < max; i++) { + str += c; + } + return str; + }); + extendBuiltin(Sp, 'padLeft', function (c, n) { + var str = this; + var length = str.length; + if (!c || length >= n) { + return str; + } + var max = (n - length) / c.length; + for (var i = 0; i < max; i++) { + str = c + str; + } + return str; + }); + extendBuiltin(Sp, 'trim', function () { + return this.replace(/^\s+|\s+$/g, ''); + }); + extendBuiltin(Sp, 'endsWith', function (str) { + return this.indexOf(str, this.length - str.length) !== -1; + }); + var Ap = Array.prototype; + extendBuiltin(Ap, 'popMany', function (count) { + true; + var start = this.length - count; + var res = this.slice(start, this.length); + this.splice(start, count); + return res; + }); + extendBuiltin(Ap, 'pushMany', function (array) { + for (var i = 0; i < array.length; i++) { + this.push(array[i]); + } + }); + extendBuiltin(Ap, 'clone', function () { + return this.slice(0); + }); + extendBuiltin(Ap, 'first', function () { + true; + return this[0]; + }); + extendBuiltin(Ap, 'last', function () { + true; + return this[this.length - 1]; + }); + extendBuiltin(Ap, 'peek', function () { + true; + return this[this.length - 1]; + }); + extendBuiltin(Ap, 'empty', function () { + return this.length === 0; + }); + extendBuiltin(Ap, 'pushUnique', function (v) { + for (var i = 0, j = this.length; i < j; i++) { + if (this[i] === v) { + return; + } + } + this.push(v); + }); + var uniquesMap; + if (typeof Map !== 'undefined' && (uniquesMap = new Map()).clear) { + extendBuiltin(Ap, 'unique', function () { + var unique = []; + for (var i = 0; i < this.length; i++) { + if (uniquesMap.has(this[i])) { + continue; + } + unique.push(this[i]); + uniquesMap.set(this[i], true); + } + uniquesMap.clear(); + return unique; + }); + } else { + extendBuiltin(Ap, 'unique', function () { + var unique = []; + for (var i = 0; i < this.length; i++) { + unique.pushUnique(this[i]); + } + return unique; + }); + } + extendBuiltin(Ap, 'replace', function (x, y) { + if (x === y) { + return 0; + } + var count = 0; + for (var i = 0; i < this.length; i++) { + if (this[i] === x) { + this[i] = y; + count++; + } + } + return count; + }); + extendBuiltin(Ap, 'count', function (x) { + var count = 0; + for (var i = 0; i < this.length; i++) { + if (this[i] === x) { + count++; + } + } + return count; + }); + extendBuiltin(Ap, 'notEmpty', function () { + return this.length > 0; + }); + extendBuiltin(Ap, 'contains', function (val) { + return this.indexOf(val) >= 0; + }); + extendBuiltin(Ap, 'top', function () { + return this.length && this[this.length - 1]; + }); + extendBuiltin(Ap, 'mapWithIndex', function (fn) { + var arr = []; + for (var i = 0; i < this.length; i++) { + arr.push(fn(this[i], i)); + } + return arr; + }); +}()); +var utf8decode = Shumway.StringUtilities.utf8decode; +var utf8encode = Shumway.StringUtilities.utf8encode; +var escapeString = Shumway.StringUtilities.escapeString; +var bitCount = Shumway.IntegerUtilities.bitCount; +var ones = Shumway.IntegerUtilities.ones; +var leadingZeros = Shumway.IntegerUtilities.leadingZeros; +var trailingZeros = Shumway.IntegerUtilities.trailingZeros; +var getFlags = Shumway.IntegerUtilities.getFlags; +function BitSetFunctor(length) { + var ADDRESS_BITS_PER_WORD = 5; + var BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD; + var BIT_INDEX_MASK = BITS_PER_WORD - 1; + var SIZE = length + (BITS_PER_WORD - 1) >> ADDRESS_BITS_PER_WORD << ADDRESS_BITS_PER_WORD; + function BitSet() { + this.count = 0; + this.dirty = 0; + this.size = SIZE; + this.bits = new Uint32Array(SIZE >> ADDRESS_BITS_PER_WORD); + } + function BitSetS() { + this.count = 0; + this.dirty = 0; + this.size = SIZE; + this.bits = 0; + } + var singleword = SIZE >> ADDRESS_BITS_PER_WORD === 1; + var Ctor = singleword ? BitSetS : BitSet; + Ctor.ADDRESS_BITS_PER_WORD = ADDRESS_BITS_PER_WORD; + Ctor.BITS_PER_WORD = BITS_PER_WORD; + Ctor.BIT_INDEX_MASK = BIT_INDEX_MASK; + Ctor.singleword = singleword; + BitSet.prototype = { + recount: function recount() { + if (!this.dirty) { + return; + } + var bits = this.bits; + var c = 0; + for (var i = 0, j = bits.length; i < j; i++) { + var v = bits[i]; + v = v - (v >> 1 & 1431655765); + v = (v & 858993459) + (v >> 2 & 858993459); + c += (v + (v >> 4) & 252645135) * 16843009 >> 24; + } + this.count = c; + this.dirty = 0; + }, + set: function set(i) { + var n = i >> ADDRESS_BITS_PER_WORD; + var old = this.bits[n]; + var b = old | 1 << (i & BIT_INDEX_MASK); + this.bits[n] = b; + this.dirty |= old ^ b; + }, + setAll: function setAll() { + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + bits[i] = 4294967295; + } + this.count = this.size; + this.dirty = 0; + }, + assign: function assign(set) { + this.count = set.count; + this.dirty = set.dirty; + this.size = set.size; + for (var i = 0, j = this.bits.length; i < j; i++) { + this.bits[i] = set.bits[i]; + } + }, + clear: function clear(i) { + var n = i >> ADDRESS_BITS_PER_WORD; + var old = this.bits[n]; + var b = old & ~(1 << (i & BIT_INDEX_MASK)); + this.bits[n] = b; + this.dirty |= old ^ b; + }, + get: function get(i) { + var word = this.bits[i >> ADDRESS_BITS_PER_WORD]; + return (word & 1 << (i & BIT_INDEX_MASK)) !== 0; + }, + clearAll: function clearAll() { + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + bits[i] = 0; + } + this.count = 0; + this.dirty = 0; + }, + _union: function _union(other) { + var dirty = this.dirty; + var bits = this.bits; + var otherBits = other.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var old = bits[i]; + var b = old | otherBits[i]; + bits[i] = b; + dirty |= old ^ b; + } + this.dirty = dirty; + }, + intersect: function intersect(other) { + var dirty = this.dirty; + var bits = this.bits; + var otherBits = other.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var old = bits[i]; + var b = old & otherBits[i]; + bits[i] = b; + dirty |= old ^ b; + } + this.dirty = dirty; + }, + subtract: function subtract(other) { + var dirty = this.dirty; + var bits = this.bits; + var otherBits = other.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var old = bits[i]; + var b = old & ~otherBits[i]; + bits[i] = b; + dirty |= old ^ b; + } + this.dirty = dirty; + }, + negate: function negate() { + var dirty = this.dirty; + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var old = bits[i]; + var b = ~old; + bits[i] = b; + dirty |= old ^ b; + } + this.dirty = dirty; + }, + forEach: function forEach(fn) { + true; + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var word = bits[i]; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + fn(i * BITS_PER_WORD + k); + } + } + } + } + }, + toArray: function toArray() { + var set = []; + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var word = bits[i]; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + set.push(i * BITS_PER_WORD + k); + } + } + } + } + return set; + }, + equals: function equals(other) { + if (this.size !== other.size) { + return false; + } + var bits = this.bits; + var otherBits = other.bits; + for (var i = 0, j = bits.length; i < j; i++) { + if (bits[i] !== otherBits[i]) { + return false; + } + } + return true; + }, + contains: function contains(other) { + if (this.size !== other.size) { + return false; + } + var bits = this.bits; + var otherBits = other.bits; + for (var i = 0, j = bits.length; i < j; i++) { + if ((bits[i] | otherBits[i]) !== bits[i]) { + return false; + } + } + return true; + }, + toBitString: function toBitString(on, off) { + on = on || '1'; + off = off || '0'; + var str = ''; + for (var i = 0; i < length; i++) { + str += this.get(i) ? on : off; + } + return str; + }, + length: length, + toString: function toString(names) { + var set = []; + for (var i = 0; i < length; i++) { + if (this.get(i)) { + set.push(names ? names[i] : i); + } + } + return set.join(', '); + }, + isEmpty: function isEmpty() { + this.recount(); + return this.count === 0; + }, + clone: function clone() { + var set = new BitSet(); + set._union(this); + return set; + } + }; + BitSetS.prototype = { + recount: function recount() { + if (!this.dirty) { + return; + } + var c = 0; + var v = this.bits; + v = v - (v >> 1 & 1431655765); + v = (v & 858993459) + (v >> 2 & 858993459); + c += (v + (v >> 4) & 252645135) * 16843009 >> 24; + this.count = c; + this.dirty = 0; + }, + set: function set(i) { + var old = this.bits; + var b = old | 1 << (i & BIT_INDEX_MASK); + this.bits = b; + this.dirty |= old ^ b; + }, + setAll: function setAll() { + this.bits = 4294967295; + this.count = this.size; + this.dirty = 0; + }, + assign: function assign(set) { + this.count = set.count; + this.dirty = set.dirty; + this.size = set.size; + this.bits = set.bits; + }, + clear: function clear(i) { + var old = this.bits; + var b = old & ~(1 << (i & BIT_INDEX_MASK)); + this.bits = b; + this.dirty |= old ^ b; + }, + get: function get(i) { + return (this.bits & 1 << (i & BIT_INDEX_MASK)) !== 0; + }, + clearAll: function clearAll() { + this.bits = 0; + this.count = 0; + this.dirty = 0; + }, + _union: function _union(other) { + var old = this.bits; + var b = old | other.bits; + this.bits = b; + this.dirty = old ^ b; + }, + intersect: function intersect(other) { + var old = this.bits; + var b = old & other.bits; + this.bits = b; + this.dirty = old ^ b; + }, + subtract: function subtract(other) { + var old = this.bits; + var b = old & ~other.bits; + this.bits = b; + this.dirty = old ^ b; + }, + negate: function negate() { + var old = this.bits; + var b = ~old; + this.bits = b; + this.dirty = old ^ b; + }, + forEach: function forEach(fn) { + true; + var word = this.bits; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + fn(k); + } + } + } + }, + toArray: function toArray() { + var set = []; + var word = this.bits; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + set.push(k); + } + } + } + return set; + }, + equals: function equals(other) { + return this.bits === other.bits; + }, + contains: function contains(other) { + var bits = this.bits; + return (bits | other.bits) === bits; + }, + isEmpty: function isEmpty() { + this.recount(); + return this.count === 0; + }, + clone: function clone() { + var set = new BitSetS(); + set._union(this); + return set; + }, + toBitString: BitSet.prototype.toBitString, + toString: BitSet.prototype.toString, + length: length + }; + return Ctor; +} +var Map = function () { + function map() { + this.elements = {}; + } + map.prototype.set = function set(k, v) { + this.elements[k] = v; + }; + map.prototype.get = function get(k) { + if (this.has(k)) { + return this.elements[k]; + } + return undefined; + }; + map.prototype.has = function has(k) { + return Object.prototype.hasOwnProperty.call(this.elements, k); + }; + map.prototype.remove = function remove(k) { + if (this.has(k)) { + delete this.elements[k]; + } + }; + return map; + }(); +(function checkWeakMap() { + if (typeof this.WeakMap === 'function') + return; + var id = 0; + function WeakMap() { + this.id = '$weakmap' + id++; + } + ; + WeakMap.prototype = { + has: function (obj) { + return obj.hasOwnProperty(this.id); + }, + get: function (obj, defaultValue) { + return obj.hasOwnProperty(this.id) ? obj[this.id] : defaultValue; + }, + set: function (obj, value) { + Object.defineProperty(obj, this.id, { + value: value, + enumerable: false, + configurable: true + }); + } + }; + this.WeakMap = WeakMap; +}()); +var Callback = function () { + function callback() { + this.queues = {}; + } + callback.prototype.register = function register(type, callback) { + var queue = this.queues[type]; + if (queue) { + if (queue.indexOf(callback) > -1) { + return; + } + } else { + queue = this.queues[type] = []; + } + queue.push(callback); + }; + callback.prototype.unregister = function unregister(type, callback) { + var queue = this.queues[type]; + if (!queue) { + return; + } + var i = queue.indexOf(callback); + if (i !== -1) { + queue.splice(i, 1); + } + if (queue.length === 0) { + this.queues[type] = null; + } + }; + callback.prototype.notify = function notify(type, args) { + var queue = this.queues[type]; + if (!queue) { + return; + } + queue = queue.slice(); + var args = sliceArguments(arguments, 0); + for (var i = 0; i < queue.length; i++) { + if (false) { + Counter.count('callback(' + type + ').notify'); + } + var callback = queue[i]; + callback.apply(null, args); + } + }; + callback.prototype.notify1 = function notify1(type, value) { + var queue = this.queues[type]; + if (!queue) { + return; + } + queue = queue.slice(); + for (var i = 0; i < queue.length; i++) { + if (false) { + Counter.count('callback(' + type + ').notify1'); + } + var callback = queue[i]; + callback(type, value); + } + }; + return callback; + }(); +function lazyClass(holder, name, initialize) { + Object.defineProperty(holder, name, { + get: function () { + var start = performance.now(); + var value = initialize(); + print('Initialized Class: ' + name + ' ' + (performance.now() - start).toFixed(4)); + Object.defineProperty(holder, name, { + value: value, + writable: true + }); + return value; + }, + configurable: true + }); +} +var hashBytesTo32BitsAdler = Shumway.HashUtilities.hashBytesTo32BitsAdler; +var hashBytesTo32BitsMD5 = Shumway.HashUtilities.hashBytesTo32BitsMD5; +var variableLengthEncodeInt32 = Shumway.StringUtilities.variableLengthEncodeInt32; +var fromEncoding = Shumway.StringUtilities.fromEncoding; +var variableLengthDecodeIdentifier = Shumway.StringUtilities.variableLengthDecodeInt32; +var toEncoding = Shumway.StringUtilities.toEncoding; +var Shumway; +(function (Shumway) { + (function (Options) { + var Argument = function () { + function Argument(shortName, longName, type, options) { + this.shortName = shortName; + this.longName = longName; + this.type = type; + options = options || {}; + this.positional = options.positional; + this.parseFn = options.parse; + this.value = options.defaultValue; + } + Argument.prototype.parse = function (value) { + if (this.type === 'boolean') { + true; + this.value = value; + } else if (this.type === 'number') { + true; + this.value = parseInt(value, 10); + } else { + this.value = value; + } + if (this.parseFn) { + this.parseFn(this.value); + } + }; + return Argument; + }(); + Options.Argument = Argument; + var ArgumentParser = function () { + function ArgumentParser() { + this.args = []; + } + ArgumentParser.prototype.addArgument = function (shortName, longName, type, options) { + var argument = new Argument(shortName, longName, type, options); + this.args.push(argument); + return argument; + }; + ArgumentParser.prototype.addBoundOption = function (option) { + var options = { + parse: function (x) { + option.value = x; + } + }; + this.args.push(new Argument(option.shortName, option.longName, option.type, options)); + }; + ArgumentParser.prototype.addBoundOptionSet = function (optionSet) { + var self = this; + optionSet.options.forEach(function (x) { + if (x instanceof OptionSet) { + self.addBoundOptionSet(x); + } else { + true; + self.addBoundOption(x); + } + }); + }; + ArgumentParser.prototype.getUsage = function () { + var str = ''; + this.args.forEach(function (x) { + if (!x.positional) { + str += '[-' + x.shortName + '|--' + x.longName + (x.type === 'boolean' ? '' : ' ' + x.type[0].toUpperCase()) + ']'; + } else { + str += x.longName; + } + str += ' '; + }); + return str; + }; + ArgumentParser.prototype.parse = function (args) { + var nonPositionalArgumentMap = {}; + var positionalArgumentList = []; + this.args.forEach(function (x) { + if (x.positional) { + positionalArgumentList.push(x); + } else { + nonPositionalArgumentMap['-' + x.shortName] = x; + nonPositionalArgumentMap['--' + x.longName] = x; + } + }); + var leftoverArguments = []; + while (args.length) { + var argString = args.shift(); + var argument = null, value = argString; + if (argString == '--') { + leftoverArguments = leftoverArguments.concat(args); + break; + } else if (argString.slice(0, 1) == '-' || argString.slice(0, 2) == '--') { + argument = nonPositionalArgumentMap[argString]; + true; + if (!argument) { + continue; + } + if (argument.type !== 'boolean') { + value = args.shift(); + true; + } else { + value = true; + } + } else if (positionalArgumentList.length) { + argument = positionalArgumentList.shift(); + } else { + leftoverArguments.push(value); + } + if (argument) { + argument.parse(value); + } + } + true; + return leftoverArguments; + }; + return ArgumentParser; + }(); + Options.ArgumentParser = ArgumentParser; + var OptionSet = function () { + function OptionSet(name) { + this.name = name; + this.options = []; + } + OptionSet.prototype.register = function (option) { + this.options.push(option); + return option; + }; + OptionSet.prototype.trace = function (writer) { + writer.enter(this.name + ' {'); + this.options.forEach(function (option) { + option.trace(writer); + }); + writer.leave('}'); + }; + return OptionSet; + }(); + Options.OptionSet = OptionSet; + var Option = function () { + function Option(shortName, longName, type, defaultValue, description) { + this.longName = longName; + this.shortName = shortName; + this.type = type; + this.defaultValue = defaultValue; + this.value = defaultValue; + this.description = description; + } + Option.prototype.parse = function (value) { + this.value = value; + }; + Option.prototype.trace = function (writer) { + writer.writeLn(('-' + this.shortName + '|--' + this.longName).padRight(' ', 30) + ' = ' + this.type + ' ' + this.value + ' [' + this.defaultValue + ']' + ' (' + this.description + ')'); + }; + return Option; + }(); + Options.Option = Option; + }(Shumway.Options || (Shumway.Options = {}))); + var Options = Shumway.Options; +}(Shumway || (Shumway = {}))); +if (typeof exports !== 'undefined') { + exports['Shumway'] = Shumway; +} +var ArgumentParser = Shumway.Options.ArgumentParser; +var Option = Shumway.Options.Option; +var OptionSet = Shumway.Options.OptionSet; +var ArgumentParser = Shumway.Options.ArgumentParser; +var Option = Shumway.Options.Option; +var OptionSet = Shumway.Options.OptionSet; +var Shumway; +(function (Shumway) { + (function (Metrics) { + var Timer = function () { + function Timer(parent, name) { + this._parent = parent; + this._timers = Shumway.ObjectUtilities.createMap(); + this._name = name; + this._begin = 0; + this._last = 0; + this._total = 0; + this._count = 0; + } + Timer.time = function (name, fn) { + Timer.start(name); + fn(); + Timer.stop(); + }; + Timer.start = function (name) { + Timer._top = Timer._top._timers[name] || (Timer._top._timers[name] = new Timer(Timer._top, name)); + Timer._top.start(); + var tmp = Timer._flat._timers[name] || (Timer._flat._timers[name] = new Timer(Timer._flat, name)); + tmp.start(); + Timer._flatStack.push(tmp); + }; + Timer.stop = function () { + Timer._top.stop(); + Timer._top = Timer._top._parent; + Timer._flatStack.pop().stop(); + }; + Timer.stopStart = function (name) { + Timer.stop(); + Timer.start(name); + }; + Timer.prototype.start = function () { + this._begin = Shumway.getTicks(); + }; + Timer.prototype.stop = function () { + this._last = Shumway.getTicks() - this._begin; + this._total += this._last; + this._count += 1; + }; + Timer.prototype.toJSON = function () { + return { + name: this._name, + total: this._total, + timers: this._timers + }; + }; + Timer.prototype.trace = function (writer) { + writer.enter(this._name + ': ' + this._total.toFixed(2) + ' ms' + ', count: ' + this._count + ', average: ' + (this._total / this._count).toFixed(2) + ' ms'); + for (var name in this._timers) { + this._timers[name].trace(writer); + } + writer.outdent(); + }; + Timer.trace = function (writer) { + Timer._base.trace(writer); + Timer._flat.trace(writer); + }; + Timer._base = new Timer(null, 'Total'); + Timer._top = Timer._base; + Timer._flat = new Timer(null, 'Flat'); + Timer._flatStack = []; + return Timer; + }(); + Metrics.Timer = Timer; + var Counter = function () { + function Counter(enabled) { + this._enabled = enabled; + this.clear(); + } + Counter.prototype.setEnabled = function (enabled) { + this._enabled = enabled; + }; + Counter.prototype.clear = function () { + this._counts = Shumway.ObjectUtilities.createMap(); + }; + Counter.prototype.toJSON = function () { + return { + counts: this._counts + }; + }; + Counter.prototype.count = function (name, increment) { + if (typeof increment === 'undefined') { + increment = 1; + } + if (!this._enabled) { + return; + } + if (this._counts[name] === undefined) { + this._counts[name] = 0; + } + this._counts[name] += increment; + return this._counts[name]; + }; + Counter.prototype.trace = function (writer) { + for (var name in this._counts) { + writer.writeLn(name + ': ' + this._counts[name]); + } + }; + Counter.prototype.traceSorted = function (writer) { + var pairs = []; + for (var name in this._counts) { + pairs.push([ + name, + this._counts[name] + ]); + } + pairs.sort(function (a, b) { + return b[1] - a[1]; + }); + pairs.forEach(function (pair) { + writer.writeLn(pair[0] + ': ' + pair[1]); + }); + }; + return Counter; + }(); + Metrics.Counter = Counter; + var Average = function () { + function Average(max) { + this._samples = new Float64Array(max); + this._count = 0; + this._index = 0; + } + Average.prototype.push = function (sample) { + if (this._count < this._samples.length) { + this._count++; + } + this._index++; + this._samples[this._index % this._samples.length] = sample; + }; + Average.prototype.average = function () { + var sum = 0; + for (var i = 0; i < this._count; i++) { + sum += this._samples[i]; + } + return sum / this._count; + }; + return Average; + }(); + Metrics.Average = Average; + }(Shumway.Metrics || (Shumway.Metrics = {}))); + var Metrics = Shumway.Metrics; +}(Shumway || (Shumway = {}))); +var Timer = Shumway.Metrics.Timer; +var Counter = new Shumway.Metrics.Counter(true); +var Timer = Shumway.Metrics.Timer; +var Counter = new Shumway.Metrics.Counter(true); +var FrameCounter = new Shumway.Metrics.Counter(true); +var systemOptions = new OptionSet('System Options'); +var disassemble = systemOptions.register(new Option('d', 'disassemble', 'boolean', false, 'disassemble')); +var traceLevel = systemOptions.register(new Option('t', 'traceLevel', 'number', 0, 'trace level')); +window.print = function (s) { + console.log(s); +}; +var CONSTANT_Undefined = 0; +var CONSTANT_Utf8 = 1; +var CONSTANT_Float = 2; +var CONSTANT_Int = 3; +var CONSTANT_UInt = 4; +var CONSTANT_PrivateNs = 5; +var CONSTANT_Double = 6; +var CONSTANT_QName = 7; +var CONSTANT_Namespace = 8; +var CONSTANT_Multiname = 9; +var CONSTANT_False = 10; +var CONSTANT_True = 11; +var CONSTANT_Null = 12; +var CONSTANT_QNameA = 13; +var CONSTANT_MultinameA = 14; +var CONSTANT_RTQName = 15; +var CONSTANT_RTQNameA = 16; +var CONSTANT_RTQNameL = 17; +var CONSTANT_RTQNameLA = 18; +var CONSTANT_NameL = 19; +var CONSTANT_NameLA = 20; +var CONSTANT_NamespaceSet = 21; +var CONSTANT_PackageNamespace = 22; +var CONSTANT_PackageInternalNs = 23; +var CONSTANT_ProtectedNamespace = 24; +var CONSTANT_ExplicitNamespace = 25; +var CONSTANT_StaticProtectedNs = 26; +var CONSTANT_MultinameL = 27; +var CONSTANT_MultinameLA = 28; +var CONSTANT_TypeName = 29; +var CONSTANT_ClassSealed = 1; +var CONSTANT_ClassFinal = 2; +var CONSTANT_ClassInterface = 4; +var CONSTANT_ClassProtectedNs = 8; +var TRAIT_Slot = 0; +var TRAIT_Method = 1; +var TRAIT_Getter = 2; +var TRAIT_Setter = 3; +var TRAIT_Class = 4; +var TRAIT_Function = 5; +var TRAIT_Const = 6; +var ATTR_Final = 1; +var ATTR_Override = 2; +var ATTR_Metadata = 4; +var SLOT_var = 0; +var SLOT_method = 1; +var SLOT_getter = 2; +var SLOT_setter = 3; +var SLOT_class = 4; +var SLOT_function = 6; +var METHOD_Arguments = 1; +var METHOD_Activation = 2; +var METHOD_Needrest = 4; +var METHOD_HasOptional = 8; +var METHOD_IgnoreRest = 16; +var METHOD_Native = 32; +var METHOD_Setsdxns = 64; +var METHOD_HasParamNames = 128; +var OP_bkpt = 1; +var OP_nop = 2; +var OP_throw = 3; +var OP_getsuper = 4; +var OP_setsuper = 5; +var OP_dxns = 6; +var OP_dxnslate = 7; +var OP_kill = 8; +var OP_label = 9; +var OP_lf32x4 = 10; +var OP_sf32x4 = 11; +var OP_ifnlt = 12; +var OP_ifnle = 13; +var OP_ifngt = 14; +var OP_ifnge = 15; +var OP_jump = 16; +var OP_iftrue = 17; +var OP_iffalse = 18; +var OP_ifeq = 19; +var OP_ifne = 20; +var OP_iflt = 21; +var OP_ifle = 22; +var OP_ifgt = 23; +var OP_ifge = 24; +var OP_ifstricteq = 25; +var OP_ifstrictne = 26; +var OP_lookupswitch = 27; +var OP_pushwith = 28; +var OP_popscope = 29; +var OP_nextname = 30; +var OP_hasnext = 31; +var OP_pushnull = 32; +var OP_pushundefined = 33; +var OP_pushfloat = 34; +var OP_nextvalue = 35; +var OP_pushbyte = 36; +var OP_pushshort = 37; +var OP_pushtrue = 38; +var OP_pushfalse = 39; +var OP_pushnan = 40; +var OP_pop = 41; +var OP_dup = 42; +var OP_swap = 43; +var OP_pushstring = 44; +var OP_pushint = 45; +var OP_pushuint = 46; +var OP_pushdouble = 47; +var OP_pushscope = 48; +var OP_pushnamespace = 49; +var OP_hasnext2 = 50; +var OP_li8 = 53; +var OP_li16 = 54; +var OP_li32 = 55; +var OP_lf32 = 56; +var OP_lf64 = 57; +var OP_si8 = 58; +var OP_si16 = 59; +var OP_si32 = 60; +var OP_sf32 = 61; +var OP_sf64 = 62; +var OP_newfunction = 64; +var OP_call = 65; +var OP_construct = 66; +var OP_callmethod = 67; +var OP_callstatic = 68; +var OP_callsuper = 69; +var OP_callproperty = 70; +var OP_returnvoid = 71; +var OP_returnvalue = 72; +var OP_constructsuper = 73; +var OP_constructprop = 74; +var OP_callsuperid = 75; +var OP_callproplex = 76; +var OP_callinterface = 77; +var OP_callsupervoid = 78; +var OP_callpropvoid = 79; +var OP_sxi1 = 80; +var OP_sxi8 = 81; +var OP_sxi16 = 82; +var OP_applytype = 83; +var OP_pushfloat4 = 84; +var OP_newobject = 85; +var OP_newarray = 86; +var OP_newactivation = 87; +var OP_newclass = 88; +var OP_getdescendants = 89; +var OP_newcatch = 90; +var OP_findpropstrict = 93; +var OP_findproperty = 94; +var OP_finddef = 95; +var OP_getlex = 96; +var OP_setproperty = 97; +var OP_getlocal = 98; +var OP_setlocal = 99; +var OP_getglobalscope = 100; +var OP_getscopeobject = 101; +var OP_getproperty = 102; +var OP_getouterscope = 103; +var OP_initproperty = 104; +var OP_setpropertylate = 105; +var OP_deleteproperty = 106; +var OP_deletepropertylate = 107; +var OP_getslot = 108; +var OP_setslot = 109; +var OP_getglobalslot = 110; +var OP_setglobalslot = 111; +var OP_convert_s = 112; +var OP_esc_xelem = 113; +var OP_esc_xattr = 114; +var OP_convert_i = 115; +var OP_convert_u = 116; +var OP_convert_d = 117; +var OP_convert_b = 118; +var OP_convert_o = 119; +var OP_checkfilter = 120; +var OP_convert_f = 121; +var OP_unplus = 122; +var OP_convert_f4 = 123; +var OP_coerce = 128; +var OP_coerce_b = 129; +var OP_coerce_a = 130; +var OP_coerce_i = 131; +var OP_coerce_d = 132; +var OP_coerce_s = 133; +var OP_astype = 134; +var OP_astypelate = 135; +var OP_coerce_u = 136; +var OP_coerce_o = 137; +var OP_negate = 144; +var OP_increment = 145; +var OP_inclocal = 146; +var OP_decrement = 147; +var OP_declocal = 148; +var OP_typeof = 149; +var OP_not = 150; +var OP_bitnot = 151; +var OP_add = 160; +var OP_subtract = 161; +var OP_multiply = 162; +var OP_divide = 163; +var OP_modulo = 164; +var OP_lshift = 165; +var OP_rshift = 166; +var OP_urshift = 167; +var OP_bitand = 168; +var OP_bitor = 169; +var OP_bitxor = 170; +var OP_equals = 171; +var OP_strictequals = 172; +var OP_lessthan = 173; +var OP_lessequals = 174; +var OP_greaterthan = 175; +var OP_greaterequals = 176; +var OP_instanceof = 177; +var OP_istype = 178; +var OP_istypelate = 179; +var OP_in = 180; +var OP_increment_i = 192; +var OP_decrement_i = 193; +var OP_inclocal_i = 194; +var OP_declocal_i = 195; +var OP_negate_i = 196; +var OP_add_i = 197; +var OP_subtract_i = 198; +var OP_multiply_i = 199; +var OP_getlocal0 = 208; +var OP_getlocal1 = 209; +var OP_getlocal2 = 210; +var OP_getlocal3 = 211; +var OP_setlocal0 = 212; +var OP_setlocal1 = 213; +var OP_setlocal2 = 214; +var OP_setlocal3 = 215; +var OP_invalid = 237; +var OP_debug = 239; +var OP_debugline = 240; +var OP_debugfile = 241; +var OP_bkptline = 242; +var OP_timestamp = 243; +var INT_MIN_VALUE = -2147483648; +var INT_MAX_VALUE = 2147483647; +var UINT_MIN_VALUE = 0; +var UINT_MAX_VALUE = 4294967295; +var SORT_CASEINSENSITIVE = 1; +var SORT_DESCENDING = 2; +var SORT_UNIQUESORT = 4; +var SORT_RETURNINDEXEDARRAY = 8; +var SORT_NUMERIC = 16; +var Shumway; +(function (Shumway) { + (function (AVM2) { + AVM2.Errors = { + CallOfNonFunctionError: { + code: 1006, + message: '%1 is not a function.' + }, + ConvertNullToObjectError: { + code: 1009, + message: 'Cannot access a property or method of a null object reference.' + }, + ConvertUndefinedToObjectError: { + code: 1010, + message: 'A term is undefined and has no properties.' + }, + ClassNotFoundError: { + code: 1014, + message: 'Class %1 could not be found.' + }, + CheckTypeFailedError: { + code: 1034, + message: 'Type Coercion failed: cannot convert %1 to %2.' + }, + WrongArgumentCountError: { + code: 1063, + message: 'Argument count mismatch on %1. Expected %2, got %3.' + }, + XMLMarkupMustBeWellFormed: { + code: 1088, + message: 'The markup in the document following the root element must be well-formed.' + }, + OutOfRangeError: { + code: 1125, + message: 'The index %1 is out of range %2.' + }, + VectorFixedError: { + code: 1126, + message: 'Cannot change the length of a fixed Vector.' + }, + InvalidParamError: { + code: 2004, + message: 'One of the parameters is invalid.' + }, + ParamRangeError: { + code: 2006, + message: 'The supplied index is out of bounds.' + }, + NullPointerError: { + code: 2007, + message: 'Parameter %1 must be non-null.' + }, + InvalidEnumError: { + code: 2008, + message: 'Parameter %1 must be one of the accepted values.' + }, + ArgumentError: { + code: 2015, + message: 'Invalid BitmapData.' + }, + CompressedDataError: { + code: 2058, + message: 'There was an error decompressing the data.' + }, + SocketConnectError: { + code: 2011, + message: 'Socket connection failed to %1:%2.' + }, + CantAddSelfError: { + code: 2024, + message: 'An object cannot be added as a child of itself.' + }, + NotAChildError: { + code: 2025, + message: 'The supplied DisplayObject must be a child of the caller.' + }, + ExternalInterfaceNotAvailableError: { + code: 2067, + message: 'The ExternalInterface is not available in this container. ExternalInterface requires Internet Explorer ActiveX, Firefox, Mozilla 1.7.5 and greater, or other browsers that support NPRuntime.' + } + }; + function getErrorMessage(index) { + if (!Shumway.AVM2.Runtime.debuggerMode.value) { + return 'Error #' + index; + } + for (var k in AVM2.Errors) { + if (AVM2.Errors[k].code == index) { + return 'Error #' + index + ': ' + AVM2.Errors[k].message; + } + } + return 'Error #' + index + ': (unknown)'; + } + AVM2.getErrorMessage = getErrorMessage; + function formatErrorMessage(error) { + var args = []; + for (var _i = 0; _i < arguments.length - 1; _i++) { + args[_i] = arguments[_i + 1]; + } + var message = error.message; + Array.prototype.slice.call(arguments, 1).forEach(function (x, i) { + message = message.replace('%' + (i + 1), x); + }); + return 'Error #' + error.code + ': ' + message; + } + AVM2.formatErrorMessage = formatErrorMessage; + function translateErrorMessage(error) { + if (error.type) { + switch (error.type) { + case 'undefined_method': + return formatErrorMessage(AVM2.Errors.CallOfNonFunctionError, 'value'); + default: + throw Shumway.Debug.notImplemented(error.type); + } + } else { + if (error.message.indexOf('is not a function') >= 0) { + return formatErrorMessage(AVM2.Errors.CallOfNonFunctionError, 'value'); + } + return error.message; + } + } + AVM2.translateErrorMessage = translateErrorMessage; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +var Errors = Shumway.AVM2.Errors; +var getErrorMessage = Shumway.AVM2.getErrorMessage; +var formatErrorMessage = Shumway.AVM2.formatErrorMessage; +var translateErrorMessage = Shumway.AVM2.translateErrorMessage; +var Errors = Shumway.AVM2.Errors; +var getErrorMessage = Shumway.AVM2.getErrorMessage; +var formatErrorMessage = Shumway.AVM2.formatErrorMessage; +var translateErrorMessage = Shumway.AVM2.translateErrorMessage; +var Shumway; +(function (Shumway) { + (function (AVM2) { + AVM2.opcodeTable = [ + null, + { + name: 'bkpt', + canThrow: false, + operands: [] + }, + { + name: 'nop', + canThrow: false, + operands: [] + }, + { + name: 'throw', + canThrow: true, + operands: [] + }, + { + name: 'getsuper', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'setsuper', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'dxns', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'dxnslate', + canThrow: true, + operands: [] + }, + { + name: 'kill', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'label', + canThrow: false, + operands: [] + }, + { + name: 'lf32x4', + canThrow: true, + operands: [] + }, + { + name: 'sf32x4', + canThrow: true, + operands: [] + }, + { + name: 'ifnlt', + canThrow: true, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'ifnle', + canThrow: true, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'ifngt', + canThrow: true, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'ifnge', + canThrow: true, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'jump', + canThrow: false, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'iftrue', + canThrow: false, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'iffalse', + canThrow: false, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'ifeq', + canThrow: true, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'ifne', + canThrow: true, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'iflt', + canThrow: true, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'ifle', + canThrow: true, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'ifgt', + canThrow: true, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'ifge', + canThrow: true, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'ifstricteq', + canThrow: false, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'ifstrictne', + canThrow: false, + operands: [ + { + name: 'offset', + size: 's24', + type: '' + } + ] + }, + { + name: 'lookupswitch', + canThrow: false, + operands: null + }, + { + name: 'pushwith', + canThrow: false, + operands: [] + }, + { + name: 'popscope', + canThrow: false, + operands: [] + }, + { + name: 'nextname', + canThrow: true, + operands: [] + }, + { + name: 'hasnext', + canThrow: true, + operands: [] + }, + { + name: 'pushnull', + canThrow: false, + operands: [] + }, + { + name: 'pushundefined', + canThrow: false, + operands: [] + }, + null, + { + name: 'nextvalue', + canThrow: true, + operands: [] + }, + { + name: 'pushbyte', + canThrow: false, + operands: [ + { + name: 'value', + size: 's08', + type: '' + } + ] + }, + { + name: 'pushshort', + canThrow: false, + operands: [ + { + name: 'value', + size: 's16', + type: '' + } + ] + }, + { + name: 'pushtrue', + canThrow: false, + operands: [] + }, + { + name: 'pushfalse', + canThrow: false, + operands: [] + }, + { + name: 'pushnan', + canThrow: false, + operands: [] + }, + { + name: 'pop', + canThrow: false, + operands: [] + }, + { + name: 'dup', + canThrow: false, + operands: [] + }, + { + name: 'swap', + canThrow: false, + operands: [] + }, + { + name: 'pushstring', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: 'S' + } + ] + }, + { + name: 'pushint', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: 'I' + } + ] + }, + { + name: 'pushuint', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: 'U' + } + ] + }, + { + name: 'pushdouble', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: 'D' + } + ] + }, + { + name: 'pushscope', + canThrow: false, + operands: [] + }, + { + name: 'pushnamespace', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: 'N' + } + ] + }, + { + name: 'hasnext2', + canThrow: true, + operands: [ + { + name: 'object', + size: 'u30', + type: '' + }, + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'lix8', + canThrow: true, + operands: null + }, + { + name: 'lix16', + canThrow: true, + operands: null + }, + { + name: 'li8', + canThrow: true, + operands: [] + }, + { + name: 'li16', + canThrow: true, + operands: [] + }, + { + name: 'li32', + canThrow: true, + operands: [] + }, + { + name: 'lf32', + canThrow: true, + operands: [] + }, + { + name: 'lf64', + canThrow: true, + operands: [] + }, + { + name: 'si8', + canThrow: true, + operands: [] + }, + { + name: 'si16', + canThrow: true, + operands: [] + }, + { + name: 'si32', + canThrow: true, + operands: [] + }, + { + name: 'sf32', + canThrow: true, + operands: [] + }, + { + name: 'sf64', + canThrow: true, + operands: [] + }, + null, + { + name: 'newfunction', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'MI' + } + ] + }, + { + name: 'call', + canThrow: true, + operands: [ + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'construct', + canThrow: true, + operands: [ + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'callmethod', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + }, + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'callstatic', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'MI' + }, + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'callsuper', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + }, + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'callproperty', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + }, + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'returnvoid', + canThrow: false, + operands: [] + }, + { + name: 'returnvalue', + canThrow: true, + operands: [] + }, + { + name: 'constructsuper', + canThrow: true, + operands: [ + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'constructprop', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + }, + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'callsuperid', + canThrow: true, + operands: null + }, + { + name: 'callproplex', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + }, + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'callinterface', + canThrow: true, + operands: null + }, + { + name: 'callsupervoid', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + }, + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'callpropvoid', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + }, + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'sxi1', + canThrow: false, + operands: [] + }, + { + name: 'sxi8', + canThrow: false, + operands: [] + }, + { + name: 'sxi16', + canThrow: false, + operands: [] + }, + { + name: 'applytype', + canThrow: true, + operands: [ + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'pushfloat4', + canThrow: false, + operands: null + }, + { + name: 'newobject', + canThrow: true, + operands: [ + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'newarray', + canThrow: true, + operands: [ + { + name: 'argCount', + size: 'u30', + type: '' + } + ] + }, + { + name: 'newactivation', + canThrow: true, + operands: [] + }, + { + name: 'newclass', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'CI' + } + ] + }, + { + name: 'getdescendants', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + { + name: 'newcatch', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'EI' + } + ] + }, + { + name: 'findpropglobalstrict', + canThrow: true, + operands: null + }, + { + name: 'findpropglobal', + canThrow: true, + operands: null + }, + { + name: 'findpropstrict', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + { + name: 'findproperty', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + { + name: 'finddef', + canThrow: true, + operands: null + }, + { + name: 'getlex', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + { + name: 'setproperty', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + { + name: 'getlocal', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'setlocal', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'getglobalscope', + canThrow: false, + operands: [] + }, + { + name: 'getscopeobject', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'getproperty', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + { + name: 'getouterscope', + canThrow: false, + operands: null + }, + { + name: 'initproperty', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + null, + { + name: 'deleteproperty', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + null, + { + name: 'getslot', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'setslot', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'getglobalslot', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'setglobalslot', + canThrow: false, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'convert_s', + canThrow: true, + operands: [] + }, + { + name: 'esc_xelem', + canThrow: true, + operands: [] + }, + { + name: 'esc_xattr', + canThrow: true, + operands: [] + }, + { + name: 'convert_i', + canThrow: true, + operands: [] + }, + { + name: 'convert_u', + canThrow: true, + operands: [] + }, + { + name: 'convert_d', + canThrow: true, + operands: [] + }, + { + name: 'convert_b', + canThrow: true, + operands: [] + }, + { + name: 'convert_o', + canThrow: true, + operands: [] + }, + { + name: 'checkfilter', + canThrow: true, + operands: [] + }, + { + name: 'convert_f', + canThrow: true, + operands: [] + }, + { + name: 'unplus', + canThrow: true, + operands: [] + }, + { + name: 'convert_f4', + canThrow: true, + operands: [] + }, + null, + null, + null, + null, + { + name: 'coerce', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + { + name: 'coerce_b', + canThrow: true, + operands: [] + }, + { + name: 'coerce_a', + canThrow: true, + operands: [] + }, + { + name: 'coerce_i', + canThrow: true, + operands: [] + }, + { + name: 'coerce_d', + canThrow: true, + operands: [] + }, + { + name: 'coerce_s', + canThrow: true, + operands: [] + }, + { + name: 'astype', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + { + name: 'astypelate', + canThrow: true, + operands: [] + }, + { + name: 'coerce_u', + canThrow: true, + operands: [] + }, + { + name: 'coerce_o', + canThrow: true, + operands: [] + }, + null, + null, + null, + null, + null, + null, + { + name: 'negate', + canThrow: true, + operands: [] + }, + { + name: 'increment', + canThrow: true, + operands: [] + }, + { + name: 'inclocal', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'decrement', + canThrow: true, + operands: [] + }, + { + name: 'declocal', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'typeof', + canThrow: false, + operands: [] + }, + { + name: 'not', + canThrow: false, + operands: [] + }, + { + name: 'bitnot', + canThrow: true, + operands: [] + }, + null, + null, + null, + null, + null, + null, + null, + null, + { + name: 'add', + canThrow: true, + operands: [] + }, + { + name: 'subtract', + canThrow: true, + operands: [] + }, + { + name: 'multiply', + canThrow: true, + operands: [] + }, + { + name: 'divide', + canThrow: true, + operands: [] + }, + { + name: 'modulo', + canThrow: true, + operands: [] + }, + { + name: 'lshift', + canThrow: true, + operands: [] + }, + { + name: 'rshift', + canThrow: true, + operands: [] + }, + { + name: 'urshift', + canThrow: true, + operands: [] + }, + { + name: 'bitand', + canThrow: true, + operands: [] + }, + { + name: 'bitor', + canThrow: true, + operands: [] + }, + { + name: 'bitxor', + canThrow: true, + operands: [] + }, + { + name: 'equals', + canThrow: true, + operands: [] + }, + { + name: 'strictequals', + canThrow: true, + operands: [] + }, + { + name: 'lessthan', + canThrow: true, + operands: [] + }, + { + name: 'lessequals', + canThrow: true, + operands: [] + }, + { + name: 'greaterthan', + canThrow: true, + operands: [] + }, + { + name: 'greaterequals', + canThrow: true, + operands: [] + }, + { + name: 'instanceof', + canThrow: true, + operands: [] + }, + { + name: 'istype', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'M' + } + ] + }, + { + name: 'istypelate', + canThrow: true, + operands: [] + }, + { + name: 'in', + canThrow: true, + operands: [] + }, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + { + name: 'increment_i', + canThrow: true, + operands: [] + }, + { + name: 'decrement_i', + canThrow: true, + operands: [] + }, + { + name: 'inclocal_i', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'declocal_i', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: '' + } + ] + }, + { + name: 'negate_i', + canThrow: true, + operands: [] + }, + { + name: 'add_i', + canThrow: true, + operands: [] + }, + { + name: 'subtract_i', + canThrow: true, + operands: [] + }, + { + name: 'multiply_i', + canThrow: true, + operands: [] + }, + null, + null, + null, + null, + null, + null, + null, + null, + { + name: 'getlocal0', + canThrow: false, + operands: [] + }, + { + name: 'getlocal1', + canThrow: false, + operands: [] + }, + { + name: 'getlocal2', + canThrow: false, + operands: [] + }, + { + name: 'getlocal3', + canThrow: false, + operands: [] + }, + { + name: 'setlocal0', + canThrow: false, + operands: [] + }, + { + name: 'setlocal1', + canThrow: false, + operands: [] + }, + { + name: 'setlocal2', + canThrow: false, + operands: [] + }, + { + name: 'setlocal3', + canThrow: false, + operands: [] + }, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + { + name: 'invalid', + canThrow: false, + operands: [] + }, + null, + { + name: 'debug', + canThrow: true, + operands: [ + { + name: 'debugType', + size: 'u08', + type: '' + }, + { + name: 'index', + size: 'u30', + type: 'S' + }, + { + name: 'reg', + size: 'u08', + type: '' + }, + { + name: 'extra', + size: 'u30', + type: '' + } + ] + }, + { + name: 'debugline', + canThrow: true, + operands: [ + { + name: 'lineNumber', + size: 'u30', + type: '' + } + ] + }, + { + name: 'debugfile', + canThrow: true, + operands: [ + { + name: 'index', + size: 'u30', + type: 'S' + } + ] + }, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ]; + function opcodeName(op) { + return AVM2.opcodeTable[op].name; + } + AVM2.opcodeName = opcodeName; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +var opcodeTable = Shumway.AVM2.opcodeTable; +var opcodeName = Shumway.AVM2.opcodeName; +var opcodeTable = Shumway.AVM2.opcodeTable; +var opcodeName = Shumway.AVM2.opcodeName; +var __extends = this.__extends || function (d, b) { + for (var p in b) + if (b.hasOwnProperty(p)) + d[p] = b[p]; + function __() { + this.constructor = d; + } + __.prototype = b.prototype; + d.prototype = new __(); + }; +var Shumway; +(function (Shumway) { + (function (AVM2) { + (function (ABC) { + var Timer = Shumway.Metrics.Timer; + var isString = Shumway.isString; + var isNumber = Shumway.isNumber; + var isNumeric = Shumway.isNumeric; + var isObject = Shumway.isObject; + var textDecoder = null; + if (typeof TextDecoder !== 'undefined') { + textDecoder = new TextDecoder(); + } + var AbcStream = function () { + function AbcStream(bytes) { + this._bytes = bytes; + this._view = new DataView(bytes.buffer, bytes.byteOffset); + this._position = 0; + } + AbcStream._getResultBuffer = function (length) { + if (!AbcStream._resultBuffer || AbcStream._resultBuffer.length < length) { + AbcStream._resultBuffer = new Int32Array(length * 2); + } + return AbcStream._resultBuffer; + }; + Object.defineProperty(AbcStream.prototype, 'position', { + get: function () { + return this._position; + }, + enumerable: true, + configurable: true + }); + AbcStream.prototype.remaining = function () { + return this._bytes.length - this._position; + }; + AbcStream.prototype.seek = function (position) { + this._position = position; + }; + AbcStream.prototype.readU8 = function () { + return this._bytes[this._position++]; + }; + AbcStream.prototype.readU8s = function (count) { + var b = new Uint8Array(count); + b.set(this._bytes.subarray(this._position, this._position + count), 0); + this._position += count; + return b; + }; + AbcStream.prototype.readS8 = function () { + return this._bytes[this._position++] << 24 >> 24; + }; + AbcStream.prototype.readU32 = function () { + return this.readS32() >>> 0; + }; + AbcStream.prototype.readU30 = function () { + var result = this.readU32(); + if (result & 3221225472) { + return result; + } + return result; + }; + AbcStream.prototype.readU30Unsafe = function () { + return this.readU32(); + }; + AbcStream.prototype.readS16 = function () { + return this.readU30Unsafe() << 16 >> 16; + }; + AbcStream.prototype.readS32 = function () { + var result = this.readU8(); + if (result & 128) { + result = result & 127 | this.readU8() << 7; + if (result & 16384) { + result = result & 16383 | this.readU8() << 14; + if (result & 2097152) { + result = result & 2097151 | this.readU8() << 21; + if (result & 268435456) { + result = result & 268435455 | this.readU8() << 28; + result = result & 4294967295; + } + } + } + } + return result; + }; + AbcStream.prototype.readWord = function () { + var result = this._view.getUint32(this._position, true); + this._position += 4; + return result; + }; + AbcStream.prototype.readS24 = function () { + var u = this.readU8() | this.readU8() << 8 | this.readU8() << 16; + return u << 8 >> 8; + }; + AbcStream.prototype.readDouble = function () { + var result = this._view.getFloat64(this._position, true); + this._position += 8; + return result; + }; + AbcStream.prototype.readUTFString = function (length) { + if (textDecoder) { + var position = this._position; + this._position += length; + return textDecoder.decode(this._bytes.subarray(position, position + length)); + } + var pos = this._position; + var end = pos + length; + var bytes = this._bytes; + var i = 0; + var result = AbcStream._getResultBuffer(length * 2); + while (pos < end) { + var c = bytes[pos++]; + if (c <= 127) { + result[i++] = c; + } else if (c >= 192) { + var code = 0; + if (c < 224) { + code = (c & 31) << 6 | bytes[pos++] & 63; + } else if (c < 240) { + code = (c & 15) << 12 | (bytes[pos++] & 63) << 6 | bytes[pos++] & 63; + } else { + code = ((c & 7) << 18 | (bytes[pos++] & 63) << 12 | (bytes[pos++] & 63) << 6 | bytes[pos++] & 63) - 65536; + result[i++] = ((code & 1047552) >>> 10) + 55296; + code = (code & 1023) + 56320; + } + result[i++] = code; + } + } + this._position = pos; + return Shumway.StringUtilities.fromCharCodeArray(result.subarray(0, i)); + }; + AbcStream._resultBuffer = new Int32Array(256); + return AbcStream; + }(); + ABC.AbcStream = AbcStream; + var Parameter = function () { + function Parameter(name, type, value) { + this.name = name; + this.type = type; + this.value = value; + } + return Parameter; + }(); + ABC.Parameter = Parameter; + var Trait = function () { + function Trait(abc, stream, holder) { + var constantPool = abc.constantPool; + var methods = abc.methods; + var classes = abc.classes; + var metadata = abc.metadata; + this.holder = holder; + this.name = constantPool.multinames[stream.readU30()]; + var tag = stream.readU8(); + this.kind = tag & 15; + this.attributes = tag >> 4 & 15; + true; + switch (this.kind) { + case 0: + case 6: + this.slotId = stream.readU30(); + this.typeName = constantPool.multinames[stream.readU30()]; + var valueIndex = stream.readU30(); + this.value = undefined; + if (valueIndex !== 0) { + this.hasDefaultValue = true; + this.value = constantPool.getValue(stream.readU8(), valueIndex); + } + break; + case 1: + case 3: + case 2: + this.dispId = stream.readU30(); + this.methodInfo = methods[stream.readU30()]; + this.methodInfo.name = this.name; + AbcFile.attachHolder(this.methodInfo, this.holder); + this.methodInfo.abc = abc; + break; + case 4: + this.slotId = stream.readU30(); + true; + this.classInfo = classes[stream.readU30()]; + break; + case 5: + true; + break; + } + if (this.attributes & 4) { + var traitMetadata; + for (var i = 0, j = stream.readU30(); i < j; i++) { + var md = metadata[stream.readU30()]; + if (md.name === '__go_to_definition_help' || md.name === '__go_to_ctor_definition_help') { + continue; + } + if (!traitMetadata) { + traitMetadata = {}; + } + traitMetadata[md.name] = md; + } + if (traitMetadata) { + if (this.isClass()) { + this.classInfo.metadata = traitMetadata; + } + this.metadata = traitMetadata; + } + } + } + Trait.prototype.isSlot = function () { + return this.kind === 0; + }; + Trait.prototype.isConst = function () { + return this.kind === 6; + }; + Trait.prototype.isMethod = function () { + return this.kind === 1; + }; + Trait.prototype.isClass = function () { + return this.kind === 4; + }; + Trait.prototype.isGetter = function () { + return this.kind === 2; + }; + Trait.prototype.isSetter = function () { + return this.kind === 3; + }; + Trait.prototype.isProtected = function () { + true; + return this.name.namespaces[0].isProtected(); + }; + Trait.prototype.kindName = function () { + switch (this.kind) { + case 0: + return 'Slot'; + case 6: + return 'Const'; + case 1: + return 'Method'; + case 3: + return 'Setter'; + case 2: + return 'Getter'; + case 4: + return 'Class'; + case 5: + return 'Function'; + } + Shumway.Debug.unexpected(); + }; + Trait.prototype.isOverride = function () { + return this.attributes & 2; + }; + Trait.prototype.isFinal = function () { + return this.attributes & 1; + }; + Trait.prototype.toString = function () { + var str = Shumway.IntegerUtilities.getFlags(this.attributes, 'final|override|metadata'.split('|')); + if (str) { + str += ' '; + } + str += Multiname.getQualifiedName(this.name); + switch (this.kind) { + case 0: + case 6: + return str + ', typeName: ' + this.typeName + ', slotId: ' + this.slotId + ', value: ' + this.value; + case 1: + case 3: + case 2: + return str + ', ' + this.kindName() + ': ' + this.methodInfo.name; + case 4: + return str + ', slotId: ' + this.slotId + ', class: ' + this.classInfo; + case 5: + break; + } + }; + Trait.parseTraits = function (abc, stream, holder) { + var count = stream.readU30(); + var traits = []; + for (var i = 0; i < count; i++) { + traits.push(new Trait(abc, stream, holder)); + } + return traits; + }; + return Trait; + }(); + ABC.Trait = Trait; + var Info = function () { + function Info(abc, index) { + this.abc = abc; + this.index = index; + } + return Info; + }(); + ABC.Info = Info; + var MethodInfo = function (_super) { + __extends(MethodInfo, _super); + function MethodInfo(abc, index, stream) { + _super.call(this, abc, index); + var constantPool = abc.constantPool; + var parameterCount = stream.readU30(); + this.returnType = constantPool.multinames[stream.readU30()]; + this.parameters = []; + for (var i = 0; i < parameterCount; i++) { + this.parameters.push(new Parameter(undefined, constantPool.multinames[stream.readU30()], undefined)); + } + this.debugName = constantPool.strings[stream.readU30()]; + this.flags = stream.readU8(); + var optionalCount = 0; + if (this.flags & 8) { + optionalCount = stream.readU30(); + true; + for (var i = parameterCount - optionalCount; i < parameterCount; i++) { + var valueIndex = stream.readU30(); + this.parameters[i].value = constantPool.getValue(stream.readU8(), valueIndex); + } + } + if (this.flags & 128) { + for (var i = 0; i < parameterCount; i++) { + if (false) { + this.parameters[i].name = constantPool.strings[stream.readU30()]; + } else { + stream.readU30(); + this.parameters[i].name = MethodInfo._getParameterName(i); + } + } + } else { + for (var i = 0; i < parameterCount; i++) { + this.parameters[i].name = MethodInfo._getParameterName(i); + } + } + } + MethodInfo._getParameterName = function (i) { + true; + return String.fromCharCode('A'.charCodeAt(0) + i); + }; + MethodInfo.prototype.toString = function () { + var flags = Shumway.IntegerUtilities.getFlags(this.flags, 'NEED_ARGUMENTS|NEED_ACTIVATION|NEED_REST|HAS_OPTIONAL|||SET_DXN|HAS_PARAM_NAMES'.split('|')); + return (flags ? flags + ' ' : '') + this.name; + }; + MethodInfo.prototype.hasOptional = function () { + return !(!(this.flags & 8)); + }; + MethodInfo.prototype.needsActivation = function () { + return !(!(this.flags & 2)); + }; + MethodInfo.prototype.needsRest = function () { + return !(!(this.flags & 4)); + }; + MethodInfo.prototype.needsArguments = function () { + return !(!(this.flags & 1)); + }; + MethodInfo.prototype.isNative = function () { + return !(!(this.flags & 32)); + }; + MethodInfo.prototype.isClassMember = function () { + return this.holder instanceof ClassInfo; + }; + MethodInfo.prototype.isInstanceMember = function () { + return this.holder instanceof InstanceInfo; + }; + MethodInfo.prototype.isScriptMember = function () { + return this.holder instanceof ScriptInfo; + }; + MethodInfo.parseException = function (abc, stream) { + var multinames = abc.constantPool.multinames; + var ex = { + start: stream.readU30(), + end: stream.readU30(), + target: stream.readU30(), + typeName: multinames[stream.readU30()], + varName: multinames[stream.readU30()] + }; + true; + true; + return ex; + }; + MethodInfo.parseBody = function (abc, stream) { + var constantPool = abc.constantPool; + var methods = abc.methods; + var index = stream.readU30(); + var mi = methods[index]; + mi.index = index; + mi.hasBody = true; + mi.hash = abc.hash + 196608 + index; + true; + mi.maxStack = stream.readU30(); + mi.localCount = stream.readU30(); + mi.initScopeDepth = stream.readU30(); + mi.maxScopeDepth = stream.readU30(); + mi.code = stream.readU8s(stream.readU30()); + var exceptions = []; + var exceptionCount = stream.readU30(); + for (var i = 0; i < exceptionCount; ++i) { + exceptions.push(MethodInfo.parseException(abc, stream)); + } + mi.exceptions = exceptions; + mi.traits = Trait.parseTraits(abc, stream, mi); + }; + MethodInfo.prototype.hasExceptions = function () { + return this.exceptions.length > 0; + }; + return MethodInfo; + }(Info); + ABC.MethodInfo = MethodInfo; + var InstanceInfo = function (_super) { + __extends(InstanceInfo, _super); + function InstanceInfo(abc, index, stream) { + _super.call(this, abc, index); + this.runtimeId = InstanceInfo.nextID++; + var constantPool = abc.constantPool; + var methods = abc.methods; + this.name = constantPool.multinames[stream.readU30()]; + true; + this.superName = constantPool.multinames[stream.readU30()]; + this.flags = stream.readU8(); + this.protectedNs = undefined; + if (this.flags & 8) { + this.protectedNs = constantPool.namespaces[stream.readU30()]; + } + var interfaceCount = stream.readU30(); + this.interfaces = []; + for (var i = 0; i < interfaceCount; i++) { + this.interfaces[i] = constantPool.multinames[stream.readU30()]; + } + this.init = methods[stream.readU30()]; + this.init.isInstanceInitializer = true; + this.init.name = this.name; + AbcFile.attachHolder(this.init, this); + this.traits = Trait.parseTraits(abc, stream, this); + } + InstanceInfo.prototype.toString = function () { + var flags = Shumway.IntegerUtilities.getFlags(this.flags & 8, 'sealed|final|interface|protected'.split('|')); + var str = (flags ? flags + ' ' : '') + this.name; + if (this.superName) { + str += ' extends ' + this.superName; + } + return str; + }; + InstanceInfo.prototype.isFinal = function () { + return !(!(this.flags & 2)); + }; + InstanceInfo.prototype.isSealed = function () { + return !(!(this.flags & 1)); + }; + InstanceInfo.prototype.isInterface = function () { + return !(!(this.flags & 4)); + }; + InstanceInfo.nextID = 1; + return InstanceInfo; + }(Info); + ABC.InstanceInfo = InstanceInfo; + var ClassInfo = function (_super) { + __extends(ClassInfo, _super); + function ClassInfo(abc, index, stream) { + _super.call(this, abc, index); + this.runtimeId = ClassInfo.nextID++; + this.abc = abc; + this.hash = abc.hash + 65536 + index; + this.index = index; + this.init = abc.methods[stream.readU30()]; + this.init.isClassInitializer = true; + AbcFile.attachHolder(this.init, this); + this.traits = Trait.parseTraits(abc, stream, this); + this.instanceInfo = abc.instances[index]; + this.instanceInfo.classInfo = this; + this.defaultValue = ClassInfo._getDefaultValue(this.instanceInfo.name); + } + ClassInfo._getDefaultValue = function (qn) { + if (Multiname.getQualifiedName(qn) === Multiname.Int || Multiname.getQualifiedName(qn) === Multiname.Uint) { + return 0; + } else if (Multiname.getQualifiedName(qn) === Multiname.Number) { + return NaN; + } else if (Multiname.getQualifiedName(qn) === Multiname.Boolean) { + return false; + } else { + return null; + } + }; + ClassInfo.prototype.toString = function () { + return this.instanceInfo.name.toString(); + }; + ClassInfo.nextID = 1; + return ClassInfo; + }(Info); + ABC.ClassInfo = ClassInfo; + var ScriptInfo = function (_super) { + __extends(ScriptInfo, _super); + function ScriptInfo(abc, index, stream) { + _super.call(this, abc, index); + this.runtimeId = ClassInfo.nextID++; + this.hash = abc.hash + 131072 + index; + this.name = abc.name + '$script' + index; + this.init = abc.methods[stream.readU30()]; + this.init.isScriptInitializer = true; + AbcFile.attachHolder(this.init, this); + this.traits = Trait.parseTraits(abc, stream, this); + } + Object.defineProperty(ScriptInfo.prototype, 'entryPoint', { + get: function () { + return this.init; + }, + enumerable: true, + configurable: true + }); + ScriptInfo.prototype.toString = function () { + return this.name; + }; + ScriptInfo.nextID = 1; + return ScriptInfo; + }(Info); + ABC.ScriptInfo = ScriptInfo; + var AbcFile = function () { + function AbcFile(bytes, name, hash) { + if (typeof hash === 'undefined') { + hash = 0; + } + Timer.start('Parse ABC'); + this.name = name; + this.env = {}; + var computedHash; + if (!hash || !true) { + Timer.start('Adler'); + computedHash = Shumway.HashUtilities.hashBytesTo32BitsAdler(bytes, 0, bytes.length); + Timer.stop(); + } + if (hash) { + this.hash = hash; + true; + } else { + this.hash = computedHash; + } + var n, i; + var stream = new AbcStream(bytes); + AbcFile._checkMagic(stream); + Timer.start('Parse constantPool'); + this.constantPool = new ConstantPool(stream, this); + Timer.stop(); + Timer.start('Parse Method Infos'); + this.methods = []; + n = stream.readU30(); + for (i = 0; i < n; ++i) { + this.methods.push(new MethodInfo(this, i, stream)); + } + Timer.stop(); + Timer.start('Parse MetaData Infos'); + this.metadata = []; + n = stream.readU30(); + for (i = 0; i < n; ++i) { + this.metadata.push(new MetaDataInfo(this, stream)); + } + Timer.stop(); + Timer.start('Parse Instance Infos'); + this.instances = []; + n = stream.readU30(); + for (i = 0; i < n; ++i) { + this.instances.push(new InstanceInfo(this, i, stream)); + } + Timer.stop(); + Timer.start('Parse Class Infos'); + this.classes = []; + for (i = 0; i < n; ++i) { + this.classes.push(new ClassInfo(this, i, stream)); + } + Timer.stop(); + Timer.start('Parse Script Infos'); + this.scripts = []; + n = stream.readU30(); + for (i = 0; i < n; ++i) { + this.scripts.push(new ScriptInfo(this, i, stream)); + } + Timer.stop(); + Timer.start('Parse Method Body Info'); + n = stream.readU30(); + for (i = 0; i < n; ++i) { + MethodInfo.parseBody(this, stream); + } + Timer.stop(); + Timer.stop(); + } + AbcFile._checkMagic = function (stream) { + var magic = stream.readWord(); + var flashPlayerBrannan = 46 << 16 | 15; + if (magic < flashPlayerBrannan) { + throw new Error('Invalid ABC File (magic = ' + Number(magic).toString(16) + ')'); + } + }; + Object.defineProperty(AbcFile.prototype, 'lastScript', { + get: function () { + true; + return this.scripts[this.scripts.length - 1]; + }, + enumerable: true, + configurable: true + }); + AbcFile.attachHolder = function (mi, holder) { + true; + mi.holder = holder; + }; + AbcFile.prototype.toString = function () { + return this.name; + }; + return AbcFile; + }(); + ABC.AbcFile = AbcFile; + var Namespace = function () { + function Namespace(kind, uri, prefix, uniqueURIHash) { + if (typeof uri === 'undefined') { + uri = ''; + } + if (uri === undefined) { + uri = ''; + } + if (prefix !== undefined) { + this.prefix = prefix; + } + this.kind = kind; + this.uri = uri; + this._buildNamespace(uniqueURIHash); + } + Namespace.prototype._buildNamespace = function (uniqueURIHash) { + if (this.kind === 22) { + this.kind = 8; + } + if (this.isPublic() && this.uri) { + var n = this.uri.length - 1; + var mark = this.uri.charCodeAt(n); + if (mark > Namespace._MIN_API_MARK) { + this.uri = this.uri.substring(0, n - 1); + } + } else if (this.isUnique()) { + this.uri = 'private ' + uniqueURIHash; + } + this.qualifiedName = Namespace._qualifyNamespace(this.kind, this.uri, this.prefix ? this.prefix : ''); + }; + Namespace._hashNamespace = function (kind, uri, prefix) { + var data = new Int32Array(1 + uri.length + prefix.length); + var j = 0; + data[j++] = kind; + var index = Namespace._knownURIs.indexOf(uri); + if (index >= 0) { + return kind << 2 | index; + } else { + for (var i = 0; i < uri.length; i++) { + data[j++] = uri.charCodeAt(i); + } + } + for (var i = 0; i < prefix.length; i++) { + data[j++] = prefix.charCodeAt(i); + } + return Shumway.HashUtilities.hashBytesTo32BitsMD5(data, 0, j); + }; + Namespace._qualifyNamespace = function (kind, uri, prefix) { + var key = kind + uri; + var mangledNamespace = Namespace._mangledNamespaceCache[key]; + if (mangledNamespace) { + return mangledNamespace; + } + mangledNamespace = Shumway.StringUtilities.variableLengthEncodeInt32(Namespace._hashNamespace(kind, uri, prefix)); + Namespace._mangledNamespaceMap[mangledNamespace] = { + kind: kind, + uri: uri, + prefix: prefix + }; + Namespace._mangledNamespaceCache[key] = mangledNamespace; + return mangledNamespace; + }; + Namespace.fromQualifiedName = function (qn) { + var length = Shumway.StringUtilities.fromEncoding(qn[0]); + var mangledNamespace = qn.substring(0, length + 1); + var ns = Namespace._mangledNamespaceMap[mangledNamespace]; + return new Namespace(ns.kind, ns.uri, ns.prefix); + }; + Namespace.kindFromString = function (str) { + for (var kind in Namespace._kinds) { + if (Namespace._kinds[kind] === str) { + return kind; + } + } + return true; + }; + Namespace.createNamespace = function (uri, prefix) { + return new Namespace(8, uri, prefix); + }; + Namespace.parse = function (constantPool, stream, hash) { + var kind = stream.readU8(); + var uri = constantPool.strings[stream.readU30()]; + return new Namespace(kind, uri, undefined, hash); + }; + Namespace.prototype.isPublic = function () { + return this.kind === 8 || this.kind === 22; + }; + Namespace.prototype.isProtected = function () { + return this.kind === 24; + }; + Namespace.prototype.isUnique = function () { + return this.kind === 5 && !this.uri; + }; + Namespace.prototype.isDynamic = function () { + return this.isPublic() && !this.uri; + }; + Namespace.prototype.getURI = function () { + return this.uri; + }; + Namespace.prototype.toString = function () { + return Namespace._kinds[this.kind] + (this.uri ? ' ' + this.uri : ''); + }; + Namespace.prototype.clone = function () { + var ns = Object.create(Namespace.prototype); + ns.kind = this.kind; + ns.uri = this.uri; + ns.prefix = this.prefix; + ns.qualifiedName = this.qualifiedName; + return ns; + }; + Namespace.prototype.isEqualTo = function (other) { + return this.qualifiedName === other.qualifiedName; + }; + Namespace.prototype.inNamespaceSet = function (set) { + for (var i = 0; i < set.length; i++) { + if (set[i].qualifiedName === this.qualifiedName) { + return true; + } + } + return false; + }; + Namespace.prototype.getAccessModifier = function () { + return Namespace._kinds[this.kind]; + }; + Namespace.prototype.getQualifiedName = function () { + return this.qualifiedName; + }; + Namespace.fromSimpleName = function (simpleName) { + if (simpleName in Namespace._simpleNameCache) { + return Namespace._simpleNameCache[simpleName]; + } + var namespaceNames; + if (simpleName.indexOf('[') === 0) { + true; + namespaceNames = simpleName.substring(1, simpleName.length - 1).split(','); + } else { + namespaceNames = [ + simpleName + ]; + } + return Namespace._simpleNameCache[simpleName] = namespaceNames.map(function (name) { + name = name.trim(); + var kindName, uri; + if (name.indexOf(' ') > 0) { + kindName = name.substring(0, name.indexOf(' ')).trim(); + uri = name.substring(name.indexOf(' ') + 1).trim(); + } else { + var kinds = Namespace._kinds; + if (name === kinds[8] || name === kinds[23] || name === kinds[5] || name === kinds[24] || name === kinds[25] || name === kinds[26]) { + kindName = name; + uri = ''; + } else { + kindName = Namespace._publicPrefix; + uri = name; + } + } + return new Namespace(Namespace.kindFromString(kindName), uri); + }); + }; + Namespace._publicPrefix = 'public'; + Namespace._kinds = function () { + var map = Shumway.ObjectUtilities.createMap(); + map[8] = Namespace._publicPrefix; + map[23] = 'packageInternal'; + map[5] = 'private'; + map[24] = 'protected'; + map[25] = 'explicit'; + map[26] = 'staticProtected'; + return map; + }(); + Namespace._MIN_API_MARK = 58004; + Namespace._MAX_API_MARK = 63743; + Namespace._knownURIs = [ + '' + ]; + Namespace._mangledNamespaceCache = Shumway.ObjectUtilities.createMap(); + Namespace._mangledNamespaceMap = Shumway.ObjectUtilities.createMap(); + Namespace.PUBLIC = new Namespace(8); + Namespace.PROTECTED = new Namespace(24); + Namespace.PROXY = new Namespace(8, 'http://www.adobe.com/2006/actionscript/flash/proxy'); + Namespace._simpleNameCache = Shumway.ObjectUtilities.createMap(); + return Namespace; + }(); + ABC.Namespace = Namespace; + var Multiname = function () { + function Multiname(namespaces, name, flags) { + if (typeof flags === 'undefined') { + flags = 0; + } + if (name !== undefined) { + true; + } + this.runtimeId = Multiname._nextID++; + this.namespaces = namespaces; + this.name = name; + this.flags = flags; + } + Multiname.parse = function (constantPool, stream, multinames, patchFactoryTypes) { + var index = 0; + var kind = stream.readU8(); + var name, namespaces = [], flags = 0; + switch (kind) { + case 7: + case 13: + index = stream.readU30(); + if (index) { + namespaces = [ + constantPool.namespaces[index] + ]; + } else { + flags &= ~Multiname.RUNTIME_NAME; + } + index = stream.readU30(); + if (index) { + name = constantPool.strings[index]; + } + break; + case 15: + case 16: + index = stream.readU30(); + if (index) { + name = constantPool.strings[index]; + } else { + flags &= ~Multiname.RUNTIME_NAME; + } + flags |= Multiname.RUNTIME_NAMESPACE; + break; + case 17: + case 18: + flags |= Multiname.RUNTIME_NAMESPACE; + flags |= Multiname.RUNTIME_NAME; + break; + case 9: + case 14: + index = stream.readU30(); + if (index) { + name = constantPool.strings[index]; + } else { + flags &= ~Multiname.RUNTIME_NAME; + } + index = stream.readU30(); + true; + namespaces = constantPool.namespaceSets[index]; + break; + case 27: + case 28: + flags |= Multiname.RUNTIME_NAME; + index = stream.readU30(); + true; + namespaces = constantPool.namespaceSets[index]; + break; + case 29: + var factoryTypeIndex = stream.readU32(); + if (multinames[factoryTypeIndex]) { + namespaces = multinames[factoryTypeIndex].namespaces; + name = multinames[factoryTypeIndex].name; + } + var typeParameterCount = stream.readU32(); + true; + var typeParameterIndex = stream.readU32(); + true; + var mn = new Multiname(namespaces, name, flags); + mn.typeParameter = multinames[typeParameterIndex]; + if (!multinames[factoryTypeIndex]) { + patchFactoryTypes.push({ + multiname: mn, + index: factoryTypeIndex + }); + } + return mn; + default: + Shumway.Debug.unexpected(); + break; + } + switch (kind) { + case 13: + case 16: + case 18: + case 14: + case 28: + flags |= Multiname.ATTRIBUTE; + break; + } + return new Multiname(namespaces, name, flags); + }; + Multiname.isMultiname = function (mn) { + return typeof mn === 'number' || typeof mn === 'string' || mn instanceof Multiname || mn instanceof Number; + }; + Multiname.needsResolution = function (mn) { + return mn instanceof Multiname && mn.namespaces.length > 1; + }; + Multiname.isQName = function (mn) { + if (mn instanceof Multiname) { + return mn.namespaces && mn.namespaces.length === 1; + } + return true; + }; + Multiname.isRuntimeName = function (mn) { + return mn instanceof Multiname && mn.isRuntimeName(); + }; + Multiname.isRuntimeNamespace = function (mn) { + return mn instanceof Multiname && mn.isRuntimeNamespace(); + }; + Multiname.isRuntime = function (mn) { + return mn instanceof Multiname && mn.isRuntimeName() || mn.isRuntimeNamespace(); + }; + Multiname.getQualifiedName = function (mn) { + true; + if (mn instanceof Multiname) { + if (mn.qualifiedName !== undefined) { + return mn.qualifiedName; + } + var name = String(mn.name); + if (isNumeric(name) && mn.namespaces[0].isPublic()) { + return mn.qualifiedName = name; + } + mn = mn.qualifiedName = Multiname.qualifyName(mn.namespaces[0], name); + } + return mn; + }; + Multiname.qualifyName = function (namespace, name) { + return '$' + namespace.qualifiedName + name; + }; + Multiname.stripPublicQualifier = function (qn) { + var publicQualifier = '$' + Namespace.PUBLIC.qualifiedName; + var index = qn.indexOf(publicQualifier); + if (index !== 0) { + return undefined; + } + return qn.substring(publicQualifier.length); + }; + Multiname.fromQualifiedName = function (qn) { + if (qn instanceof Multiname) { + return qn; + } + if (isNumeric(qn)) { + return new Multiname([ + Namespace.PUBLIC + ], qn); + } + if (qn[0] !== '$') { + return; + } + var ns = Namespace.fromQualifiedName(qn.substring(1)); + return new Multiname([ + ns + ], qn.substring(1 + ns.qualifiedName.length)); + }; + Multiname.getNameFromPublicQualifiedName = function (qn) { + var mn = Multiname.fromQualifiedName(qn); + true; + return mn.name; + }; + Multiname.getFullQualifiedName = function (mn) { + var qn = Multiname.getQualifiedName(mn); + if (mn instanceof Multiname && mn.typeParameter) { + qn += '$' + Multiname.getFullQualifiedName(mn.typeParameter); + } + return qn; + }; + Multiname.getPublicQualifiedName = function (name) { + if (isNumeric(name)) { + return Shumway.toNumber(name); + } else if (name !== null && isObject(name)) { + return name; + } + return Multiname.qualifyName(Namespace.PUBLIC, name); + }; + Multiname.isPublicQualifiedName = function (qn) { + return typeof qn === 'number' || isNumeric(qn) || qn.indexOf(Namespace.PUBLIC.qualifiedName) === 1; + }; + Multiname.getAccessModifier = function (mn) { + true; + if (typeof mn === 'number' || typeof mn === 'string' || mn instanceof Number) { + return 'public'; + } + true; + return mn.namespaces[0].getAccessModifier(); + }; + Multiname.isNumeric = function (mn) { + if (typeof mn === 'number') { + return true; + } else if (typeof mn === 'string') { + return isNumeric(mn); + } + return !isNaN(parseInt(Multiname.getName(mn), 10)); + }; + Multiname.getName = function (mn) { + true; + true; + return mn.getName(); + }; + Multiname.isAnyName = function (mn) { + return typeof mn === 'object' && !mn.isRuntimeName() && !mn.name; + }; + Multiname.fromSimpleName = function (simpleName) { + true; + if (simpleName in Multiname._simpleNameCache) { + return Multiname._simpleNameCache[simpleName]; + } + var nameIndex, namespaceIndex, name, namespace; + nameIndex = simpleName.lastIndexOf('.'); + if (nameIndex <= 0) { + nameIndex = simpleName.lastIndexOf(' '); + } + if (nameIndex > 0 && nameIndex < simpleName.length - 1) { + name = simpleName.substring(nameIndex + 1).trim(); + namespace = simpleName.substring(0, nameIndex).trim(); + } else { + name = simpleName; + namespace = ''; + } + return Multiname._simpleNameCache[simpleName] = new Multiname(Namespace.fromSimpleName(namespace), name); + }; + Multiname.prototype.getQName = function (index) { + true; + if (!this._qualifiedNameCache) { + this._qualifiedNameCache = Shumway.ObjectUtilities.createArrayMap(); + } + var name = this._qualifiedNameCache[index]; + if (!name) { + name = this._qualifiedNameCache[index] = new Multiname([ + this.namespaces[index] + ], this.name, this.flags); + } + return name; + }; + Multiname.prototype.hasQName = function (qn) { + true; + if (this.name !== qn.name) { + return false; + } + for (var i = 0; i < this.namespaces.length; i++) { + if (this.namespaces[i].isEqualTo(qn.namespaces[0])) { + return true; + } + } + return false; + }; + Multiname.prototype.isAttribute = function () { + return this.flags & Multiname.ATTRIBUTE; + }; + Multiname.prototype.isAnyName = function () { + return Multiname.isAnyName(this); + }; + Multiname.prototype.isAnyNamespace = function () { + return !this.isRuntimeNamespace() && (this.namespaces.length === 0 || this.isAnyName() && this.namespaces.length !== 1); + }; + Multiname.prototype.isRuntimeName = function () { + return !(!(this.flags & Multiname.RUNTIME_NAME)); + }; + Multiname.prototype.isRuntimeNamespace = function () { + return !(!(this.flags & Multiname.RUNTIME_NAMESPACE)); + }; + Multiname.prototype.isRuntime = function () { + return !(!(this.flags & (Multiname.RUNTIME_NAME | Multiname.RUNTIME_NAMESPACE))); + }; + Multiname.prototype.isQName = function () { + return this.namespaces.length === 1 && !this.isAnyName(); + }; + Multiname.prototype.hasTypeParameter = function () { + return !(!this.typeParameter); + }; + Multiname.prototype.getName = function () { + return this.name; + }; + Multiname.prototype.getOriginalName = function () { + true; + var name = this.namespaces[0].uri; + if (name) { + name += '.'; + } + return name + this.name; + }; + Multiname.prototype.getNamespace = function () { + true; + true; + return this.namespaces[0]; + }; + Multiname.prototype.nameToString = function () { + if (this.isAnyName()) { + return '*'; + } else { + var name = this.getName(); + return this.isRuntimeName() ? '[]' : name; + } + }; + Multiname.prototype.hasObjectName = function () { + return typeof this.name === 'object'; + }; + Multiname.prototype.toString = function () { + var str = this.isAttribute() ? '@' : ''; + if (this.isAnyNamespace()) { + str += '*::' + this.nameToString(); + } else if (this.isRuntimeNamespace()) { + str += '[]::' + this.nameToString(); + } else if (this.namespaces.length === 1 && this.isQName()) { + str += this.namespaces[0].toString() + '::'; + str += this.nameToString(); + } else { + str += '{'; + for (var i = 0, count = this.namespaces.length; i < count; i++) { + str += this.namespaces[i].toString(); + if (i + 1 < count) { + str += ','; + } + } + str += '}::' + this.nameToString(); + } + if (this.hasTypeParameter()) { + str += '<' + this.typeParameter.toString() + '>'; + } + return str; + }; + Multiname.ATTRIBUTE = 1; + Multiname.RUNTIME_NAMESPACE = 2; + Multiname.RUNTIME_NAME = 4; + Multiname._nextID = 0; + Multiname._simpleNameCache = Shumway.ObjectUtilities.createMap(); + Multiname.Int = Multiname.getPublicQualifiedName('int'); + Multiname.Uint = Multiname.getPublicQualifiedName('uint'); + Multiname.Class = Multiname.getPublicQualifiedName('Class'); + Multiname.Array = Multiname.getPublicQualifiedName('Array'); + Multiname.Object = Multiname.getPublicQualifiedName('Object'); + Multiname.String = Multiname.getPublicQualifiedName('String'); + Multiname.Number = Multiname.getPublicQualifiedName('Number'); + Multiname.Boolean = Multiname.getPublicQualifiedName('Boolean'); + Multiname.Function = Multiname.getPublicQualifiedName('Function'); + Multiname.XML = Multiname.getPublicQualifiedName('XML'); + Multiname.XMLList = Multiname.getPublicQualifiedName('XMLList'); + Multiname.TEMPORARY = new Multiname([], ''); + return Multiname; + }(); + ABC.Multiname = Multiname; + var MetaDataInfo = function () { + function MetaDataInfo(abc, stream) { + var strings = abc.constantPool.strings; + var name = this.name = strings[stream.readU30()]; + var itemCount = stream.readU30(); + var keys = []; + var items = []; + for (var i = 0; i < itemCount; i++) { + keys[i] = strings[stream.readU30()]; + } + for (var i = 0; i < itemCount; i++) { + var key = keys[i]; + items[i] = { + key: key, + value: strings[stream.readU30()] + }; + if (key && name === 'native') { + true; + this[key] = items[i].value; + } + } + this.value = items; + } + MetaDataInfo.prototype.toString = function () { + return '[' + this.name + ']'; + }; + return MetaDataInfo; + }(); + ABC.MetaDataInfo = MetaDataInfo; + (function (CONSTANT) { + CONSTANT[CONSTANT['Undefined'] = 0] = 'Undefined'; + CONSTANT[CONSTANT['Utf8'] = 1] = 'Utf8'; + CONSTANT[CONSTANT['Float'] = 2] = 'Float'; + CONSTANT[CONSTANT['Int'] = 3] = 'Int'; + CONSTANT[CONSTANT['UInt'] = 4] = 'UInt'; + CONSTANT[CONSTANT['PrivateNs'] = 5] = 'PrivateNs'; + CONSTANT[CONSTANT['Double'] = 6] = 'Double'; + CONSTANT[CONSTANT['QName'] = 7] = 'QName'; + CONSTANT[CONSTANT['Namespace'] = 8] = 'Namespace'; + CONSTANT[CONSTANT['Multiname'] = 9] = 'Multiname'; + CONSTANT[CONSTANT['False'] = 10] = 'False'; + CONSTANT[CONSTANT['True'] = 11] = 'True'; + CONSTANT[CONSTANT['Null'] = 12] = 'Null'; + CONSTANT[CONSTANT['QNameA'] = 13] = 'QNameA'; + CONSTANT[CONSTANT['MultinameA'] = 14] = 'MultinameA'; + CONSTANT[CONSTANT['RTQName'] = 15] = 'RTQName'; + CONSTANT[CONSTANT['RTQNameA'] = 16] = 'RTQNameA'; + CONSTANT[CONSTANT['RTQNameL'] = 17] = 'RTQNameL'; + CONSTANT[CONSTANT['RTQNameLA'] = 18] = 'RTQNameLA'; + CONSTANT[CONSTANT['NameL'] = 19] = 'NameL'; + CONSTANT[CONSTANT['NameLA'] = 20] = 'NameLA'; + CONSTANT[CONSTANT['NamespaceSet'] = 21] = 'NamespaceSet'; + CONSTANT[CONSTANT['PackageNamespace'] = 22] = 'PackageNamespace'; + CONSTANT[CONSTANT['PackageInternalNs'] = 23] = 'PackageInternalNs'; + CONSTANT[CONSTANT['ProtectedNamespace'] = 24] = 'ProtectedNamespace'; + CONSTANT[CONSTANT['ExplicitNamespace'] = 25] = 'ExplicitNamespace'; + CONSTANT[CONSTANT['StaticProtectedNs'] = 26] = 'StaticProtectedNs'; + CONSTANT[CONSTANT['MultinameL'] = 27] = 'MultinameL'; + CONSTANT[CONSTANT['MultinameLA'] = 28] = 'MultinameLA'; + CONSTANT[CONSTANT['TypeName'] = 29] = 'TypeName'; + CONSTANT[CONSTANT['ClassSealed'] = 1] = 'ClassSealed'; + CONSTANT[CONSTANT['ClassFinal'] = 2] = 'ClassFinal'; + CONSTANT[CONSTANT['ClassInterface'] = 4] = 'ClassInterface'; + CONSTANT[CONSTANT['ClassProtectedNs'] = 8] = 'ClassProtectedNs'; + }(ABC.CONSTANT || (ABC.CONSTANT = {}))); + var CONSTANT = ABC.CONSTANT; + (function (METHOD) { + METHOD[METHOD['Arguments'] = 1] = 'Arguments'; + METHOD[METHOD['Activation'] = 2] = 'Activation'; + METHOD[METHOD['Needrest'] = 4] = 'Needrest'; + METHOD[METHOD['HasOptional'] = 8] = 'HasOptional'; + METHOD[METHOD['IgnoreRest'] = 16] = 'IgnoreRest'; + METHOD[METHOD['Native'] = 32] = 'Native'; + METHOD[METHOD['Setsdxns'] = 64] = 'Setsdxns'; + METHOD[METHOD['HasParamNames'] = 128] = 'HasParamNames'; + }(ABC.METHOD || (ABC.METHOD = {}))); + var METHOD = ABC.METHOD; + (function (TRAIT) { + TRAIT[TRAIT['Slot'] = 0] = 'Slot'; + TRAIT[TRAIT['Method'] = 1] = 'Method'; + TRAIT[TRAIT['Getter'] = 2] = 'Getter'; + TRAIT[TRAIT['Setter'] = 3] = 'Setter'; + TRAIT[TRAIT['Class'] = 4] = 'Class'; + TRAIT[TRAIT['Function'] = 5] = 'Function'; + TRAIT[TRAIT['Const'] = 6] = 'Const'; + }(ABC.TRAIT || (ABC.TRAIT = {}))); + var TRAIT = ABC.TRAIT; + (function (ATTR) { + ATTR[ATTR['Final'] = 1] = 'Final'; + ATTR[ATTR['Override'] = 2] = 'Override'; + ATTR[ATTR['Metadata'] = 4] = 'Metadata'; + }(ABC.ATTR || (ABC.ATTR = {}))); + var ATTR = ABC.ATTR; + (function (SORT) { + SORT[SORT['CASEINSENSITIVE'] = 1] = 'CASEINSENSITIVE'; + SORT[SORT['DESCENDING'] = 2] = 'DESCENDING'; + SORT[SORT['UNIQUESORT'] = 4] = 'UNIQUESORT'; + SORT[SORT['RETURNINDEXEDARRAY'] = 8] = 'RETURNINDEXEDARRAY'; + SORT[SORT['NUMERIC'] = 16] = 'NUMERIC'; + }(ABC.SORT || (ABC.SORT = {}))); + var SORT = ABC.SORT; + (function (OP) { + OP[OP['bkpt'] = 1] = 'bkpt'; + OP[OP['nop'] = 2] = 'nop'; + OP[OP['throw'] = 3] = 'throw'; + OP[OP['getsuper'] = 4] = 'getsuper'; + OP[OP['setsuper'] = 5] = 'setsuper'; + OP[OP['dxns'] = 6] = 'dxns'; + OP[OP['dxnslate'] = 7] = 'dxnslate'; + OP[OP['kill'] = 8] = 'kill'; + OP[OP['label'] = 9] = 'label'; + OP[OP['lf32x4'] = 10] = 'lf32x4'; + OP[OP['sf32x4'] = 11] = 'sf32x4'; + OP[OP['ifnlt'] = 12] = 'ifnlt'; + OP[OP['ifnle'] = 13] = 'ifnle'; + OP[OP['ifngt'] = 14] = 'ifngt'; + OP[OP['ifnge'] = 15] = 'ifnge'; + OP[OP['jump'] = 16] = 'jump'; + OP[OP['iftrue'] = 17] = 'iftrue'; + OP[OP['iffalse'] = 18] = 'iffalse'; + OP[OP['ifeq'] = 19] = 'ifeq'; + OP[OP['ifne'] = 20] = 'ifne'; + OP[OP['iflt'] = 21] = 'iflt'; + OP[OP['ifle'] = 22] = 'ifle'; + OP[OP['ifgt'] = 23] = 'ifgt'; + OP[OP['ifge'] = 24] = 'ifge'; + OP[OP['ifstricteq'] = 25] = 'ifstricteq'; + OP[OP['ifstrictne'] = 26] = 'ifstrictne'; + OP[OP['lookupswitch'] = 27] = 'lookupswitch'; + OP[OP['pushwith'] = 28] = 'pushwith'; + OP[OP['popscope'] = 29] = 'popscope'; + OP[OP['nextname'] = 30] = 'nextname'; + OP[OP['hasnext'] = 31] = 'hasnext'; + OP[OP['pushnull'] = 32] = 'pushnull'; + OP[OP['c'] = 33] = 'c'; + OP[OP['pushundefined'] = 33] = 'pushundefined'; + OP[OP['pushfloat'] = 34] = 'pushfloat'; + OP[OP['nextvalue'] = 35] = 'nextvalue'; + OP[OP['pushbyte'] = 36] = 'pushbyte'; + OP[OP['pushshort'] = 37] = 'pushshort'; + OP[OP['pushtrue'] = 38] = 'pushtrue'; + OP[OP['pushfalse'] = 39] = 'pushfalse'; + OP[OP['pushnan'] = 40] = 'pushnan'; + OP[OP['pop'] = 41] = 'pop'; + OP[OP['dup'] = 42] = 'dup'; + OP[OP['swap'] = 43] = 'swap'; + OP[OP['pushstring'] = 44] = 'pushstring'; + OP[OP['pushint'] = 45] = 'pushint'; + OP[OP['pushuint'] = 46] = 'pushuint'; + OP[OP['pushdouble'] = 47] = 'pushdouble'; + OP[OP['pushscope'] = 48] = 'pushscope'; + OP[OP['pushnamespace'] = 49] = 'pushnamespace'; + OP[OP['hasnext2'] = 50] = 'hasnext2'; + OP[OP['li8'] = 53] = 'li8'; + OP[OP['li16'] = 54] = 'li16'; + OP[OP['li32'] = 55] = 'li32'; + OP[OP['lf32'] = 56] = 'lf32'; + OP[OP['lf64'] = 57] = 'lf64'; + OP[OP['si8'] = 58] = 'si8'; + OP[OP['si16'] = 59] = 'si16'; + OP[OP['si32'] = 60] = 'si32'; + OP[OP['sf32'] = 61] = 'sf32'; + OP[OP['sf64'] = 62] = 'sf64'; + OP[OP['newfunction'] = 64] = 'newfunction'; + OP[OP['call'] = 65] = 'call'; + OP[OP['construct'] = 66] = 'construct'; + OP[OP['callmethod'] = 67] = 'callmethod'; + OP[OP['callstatic'] = 68] = 'callstatic'; + OP[OP['callsuper'] = 69] = 'callsuper'; + OP[OP['callproperty'] = 70] = 'callproperty'; + OP[OP['returnvoid'] = 71] = 'returnvoid'; + OP[OP['returnvalue'] = 72] = 'returnvalue'; + OP[OP['constructsuper'] = 73] = 'constructsuper'; + OP[OP['constructprop'] = 74] = 'constructprop'; + OP[OP['callsuperid'] = 75] = 'callsuperid'; + OP[OP['callproplex'] = 76] = 'callproplex'; + OP[OP['callinterface'] = 77] = 'callinterface'; + OP[OP['callsupervoid'] = 78] = 'callsupervoid'; + OP[OP['callpropvoid'] = 79] = 'callpropvoid'; + OP[OP['sxi1'] = 80] = 'sxi1'; + OP[OP['sxi8'] = 81] = 'sxi8'; + OP[OP['sxi16'] = 82] = 'sxi16'; + OP[OP['applytype'] = 83] = 'applytype'; + OP[OP['pushfloat4'] = 84] = 'pushfloat4'; + OP[OP['newobject'] = 85] = 'newobject'; + OP[OP['newarray'] = 86] = 'newarray'; + OP[OP['newactivation'] = 87] = 'newactivation'; + OP[OP['newclass'] = 88] = 'newclass'; + OP[OP['getdescendants'] = 89] = 'getdescendants'; + OP[OP['newcatch'] = 90] = 'newcatch'; + OP[OP['findpropstrict'] = 93] = 'findpropstrict'; + OP[OP['findproperty'] = 94] = 'findproperty'; + OP[OP['finddef'] = 95] = 'finddef'; + OP[OP['getlex'] = 96] = 'getlex'; + OP[OP['setproperty'] = 97] = 'setproperty'; + OP[OP['getlocal'] = 98] = 'getlocal'; + OP[OP['setlocal'] = 99] = 'setlocal'; + OP[OP['getglobalscope'] = 100] = 'getglobalscope'; + OP[OP['getscopeobject'] = 101] = 'getscopeobject'; + OP[OP['getproperty'] = 102] = 'getproperty'; + OP[OP['getouterscope'] = 103] = 'getouterscope'; + OP[OP['initproperty'] = 104] = 'initproperty'; + OP[OP['setpropertylate'] = 105] = 'setpropertylate'; + OP[OP['deleteproperty'] = 106] = 'deleteproperty'; + OP[OP['deletepropertylate'] = 107] = 'deletepropertylate'; + OP[OP['getslot'] = 108] = 'getslot'; + OP[OP['setslot'] = 109] = 'setslot'; + OP[OP['getglobalslot'] = 110] = 'getglobalslot'; + OP[OP['setglobalslot'] = 111] = 'setglobalslot'; + OP[OP['convert_s'] = 112] = 'convert_s'; + OP[OP['esc_xelem'] = 113] = 'esc_xelem'; + OP[OP['esc_xattr'] = 114] = 'esc_xattr'; + OP[OP['convert_i'] = 115] = 'convert_i'; + OP[OP['convert_u'] = 116] = 'convert_u'; + OP[OP['convert_d'] = 117] = 'convert_d'; + OP[OP['convert_b'] = 118] = 'convert_b'; + OP[OP['convert_o'] = 119] = 'convert_o'; + OP[OP['checkfilter'] = 120] = 'checkfilter'; + OP[OP['convert_f'] = 121] = 'convert_f'; + OP[OP['unplus'] = 122] = 'unplus'; + OP[OP['convert_f4'] = 123] = 'convert_f4'; + OP[OP['coerce'] = 128] = 'coerce'; + OP[OP['coerce_b'] = 129] = 'coerce_b'; + OP[OP['coerce_a'] = 130] = 'coerce_a'; + OP[OP['coerce_i'] = 131] = 'coerce_i'; + OP[OP['coerce_d'] = 132] = 'coerce_d'; + OP[OP['coerce_s'] = 133] = 'coerce_s'; + OP[OP['astype'] = 134] = 'astype'; + OP[OP['astypelate'] = 135] = 'astypelate'; + OP[OP['coerce_u'] = 136] = 'coerce_u'; + OP[OP['coerce_o'] = 137] = 'coerce_o'; + OP[OP['negate'] = 144] = 'negate'; + OP[OP['increment'] = 145] = 'increment'; + OP[OP['inclocal'] = 146] = 'inclocal'; + OP[OP['decrement'] = 147] = 'decrement'; + OP[OP['declocal'] = 148] = 'declocal'; + OP[OP['typeof'] = 149] = 'typeof'; + OP[OP['not'] = 150] = 'not'; + OP[OP['bitnot'] = 151] = 'bitnot'; + OP[OP['add'] = 160] = 'add'; + OP[OP['subtract'] = 161] = 'subtract'; + OP[OP['multiply'] = 162] = 'multiply'; + OP[OP['divide'] = 163] = 'divide'; + OP[OP['modulo'] = 164] = 'modulo'; + OP[OP['lshift'] = 165] = 'lshift'; + OP[OP['rshift'] = 166] = 'rshift'; + OP[OP['urshift'] = 167] = 'urshift'; + OP[OP['bitand'] = 168] = 'bitand'; + OP[OP['bitor'] = 169] = 'bitor'; + OP[OP['bitxor'] = 170] = 'bitxor'; + OP[OP['equals'] = 171] = 'equals'; + OP[OP['strictequals'] = 172] = 'strictequals'; + OP[OP['lessthan'] = 173] = 'lessthan'; + OP[OP['lessequals'] = 174] = 'lessequals'; + OP[OP['greaterthan'] = 175] = 'greaterthan'; + OP[OP['greaterequals'] = 176] = 'greaterequals'; + OP[OP['instanceof'] = 177] = 'instanceof'; + OP[OP['istype'] = 178] = 'istype'; + OP[OP['istypelate'] = 179] = 'istypelate'; + OP[OP['in'] = 180] = 'in'; + OP[OP['increment_i'] = 192] = 'increment_i'; + OP[OP['decrement_i'] = 193] = 'decrement_i'; + OP[OP['inclocal_i'] = 194] = 'inclocal_i'; + OP[OP['declocal_i'] = 195] = 'declocal_i'; + OP[OP['negate_i'] = 196] = 'negate_i'; + OP[OP['add_i'] = 197] = 'add_i'; + OP[OP['subtract_i'] = 198] = 'subtract_i'; + OP[OP['multiply_i'] = 199] = 'multiply_i'; + OP[OP['getlocal0'] = 208] = 'getlocal0'; + OP[OP['getlocal1'] = 209] = 'getlocal1'; + OP[OP['getlocal2'] = 210] = 'getlocal2'; + OP[OP['getlocal3'] = 211] = 'getlocal3'; + OP[OP['setlocal0'] = 212] = 'setlocal0'; + OP[OP['setlocal1'] = 213] = 'setlocal1'; + OP[OP['setlocal2'] = 214] = 'setlocal2'; + OP[OP['setlocal3'] = 215] = 'setlocal3'; + OP[OP['invalid'] = 237] = 'invalid'; + OP[OP['debug'] = 239] = 'debug'; + OP[OP['debugline'] = 240] = 'debugline'; + OP[OP['debugfile'] = 241] = 'debugfile'; + OP[OP['bkptline'] = 242] = 'bkptline'; + OP[OP['timestamp'] = 243] = 'timestamp'; + }(ABC.OP || (ABC.OP = {}))); + var OP = ABC.OP; + var ConstantPool = function () { + function ConstantPool(stream, abc) { + var n; + var ints = [ + 0 + ]; + n = stream.readU30(); + for (var i = 1; i < n; ++i) { + ints.push(stream.readS32()); + } + var uints = [ + 0 + ]; + n = stream.readU30(); + for (var i = 1; i < n; ++i) { + uints.push(stream.readU32()); + } + var doubles = [ + NaN + ]; + n = stream.readU30(); + for (var i = 1; i < n; ++i) { + doubles.push(stream.readDouble()); + } + Timer.start('Parse Strings'); + var strings = [ + '' + ]; + n = stream.readU30(); + for (var i = 1; i < n; ++i) { + strings.push(stream.readUTFString(stream.readU30())); + } + this.positionAfterUTFStrings = stream.position; + Timer.stop(); + this.ints = ints; + this.uints = uints; + this.doubles = doubles; + this.strings = strings; + Timer.start('Parse Namespaces'); + var namespaces = [ + undefined + ]; + n = stream.readU30(); + for (var i = 1; i < n; ++i) { + namespaces.push(Namespace.parse(this, stream, abc.hash + i)); + } + Timer.stop(); + Timer.start('Parse Namespace Sets'); + var namespaceSets = [ + undefined + ]; + n = stream.readU30(); + for (var i = 1; i < n; ++i) { + var count = stream.readU30(); + var set = []; + set.runtimeId = ConstantPool._nextNamespaceSetID++; + for (var j = 0; j < count; ++j) { + set.push(namespaces[stream.readU30()]); + } + namespaceSets.push(set); + } + Timer.stop(); + this.namespaces = namespaces; + this.namespaceSets = namespaceSets; + Timer.start('Parse Multinames'); + var multinames = [ + undefined + ]; + var patchFactoryTypes = []; + n = stream.readU30(); + for (var i = 1; i < n; ++i) { + multinames.push(Multiname.parse(this, stream, multinames, patchFactoryTypes)); + } + Timer.stop(); + this.multinames = multinames; + } + ConstantPool.prototype.getValue = function (kind, index) { + switch (kind) { + case 3: + return this.ints[index]; + case 4: + return this.uints[index]; + case 6: + return this.doubles[index]; + case 1: + return this.strings[index]; + case 11: + return true; + case 10: + return false; + case 12: + return null; + case 0: + return undefined; + case 8: + case 23: + return this.namespaces[index]; + case 7: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + return this.multinames[index]; + case 2: + Shumway.Debug.warning('TODO: CONSTANT.Float may be deprecated?'); + break; + default: + true; + } + }; + ConstantPool._nextNamespaceSetID = 1; + return ConstantPool; + }(); + ABC.ConstantPool = ConstantPool; + }(AVM2.ABC || (AVM2.ABC = {}))); + var ABC = AVM2.ABC; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +var AbcFile = Shumway.AVM2.ABC.AbcFile; +var AbcStream = Shumway.AVM2.ABC.AbcStream; +var ConstantPool = Shumway.AVM2.ABC.ConstantPool; +var ClassInfo = Shumway.AVM2.ABC.ClassInfo; +var MetaDataInfo = Shumway.AVM2.ABC.MetaDataInfo; +var InstanceInfo = Shumway.AVM2.ABC.InstanceInfo; +var ScriptInfo = Shumway.AVM2.ABC.ScriptInfo; +var Trait = Shumway.AVM2.ABC.Trait; +var MethodInfo = Shumway.AVM2.ABC.MethodInfo; +var Multiname = Shumway.AVM2.ABC.Multiname; +var ASNamespace = Shumway.AVM2.ABC.Namespace; +var AbcFile = Shumway.AVM2.ABC.AbcFile; +var AbcStream = Shumway.AVM2.ABC.AbcStream; +var ConstantPool = Shumway.AVM2.ABC.ConstantPool; +var ClassInfo = Shumway.AVM2.ABC.ClassInfo; +var MetaDataInfo = Shumway.AVM2.ABC.MetaDataInfo; +var InstanceInfo = Shumway.AVM2.ABC.InstanceInfo; +var ScriptInfo = Shumway.AVM2.ABC.ScriptInfo; +var Trait = Shumway.AVM2.ABC.Trait; +var MethodInfo = Shumway.AVM2.ABC.MethodInfo; +var Multiname = Shumway.AVM2.ABC.Multiname; +var ASNamespace = Shumway.AVM2.ABC.Namespace; +var Bytecode = function () { + function Bytecode(code) { + var op = code.readU8(); + this.op = op; + this.originalPosition = code.position; + var opdesc = Shumway.AVM2.opcodeTable[op]; + if (!opdesc) { + unexpected('Unknown Op ' + op); + } + this.canThrow = opdesc.canThrow; + var i, n; + switch (op) { + case OP_lookupswitch: + var defaultOffset = code.readS24(); + this.offsets = []; + var n = code.readU30() + 1; + for (i = 0; i < n; i++) { + this.offsets.push(code.readS24()); + } + this.offsets.push(defaultOffset); + break; + default: + for (i = 0, n = opdesc.operands.length; i < n; i++) { + var operand = opdesc.operands[i]; + switch (operand.size) { + case 'u08': + this[operand.name] = code.readU8(); + break; + case 's08': + this[operand.name] = code.readS8(); + break; + case 's16': + this[operand.name] = code.readS16(); + break; + case 's24': + this[operand.name] = code.readS24(); + break; + case 'u30': + this[operand.name] = code.readU30(); + break; + case 'u32': + this[operand.name] = code.readU32(); + break; + default: + unexpected(); + } + } + } + } + Bytecode.prototype = { + makeBlockHead: function makeBlockHead(id) { + if (this.succs) { + return id; + } + this.bid = id; + this.succs = []; + this.preds = []; + this.dominatees = []; + return id + 1; + }, + trace: function trace(writer) { + if (!this.succs) { + return; + } + writer.writeLn('#' + this.bid); + }, + toString: function toString(abc) { + var opDescription = Shumway.AVM2.opcodeTable[this.op]; + var str = opDescription.name.padRight(' ', 20); + var i, j; + if (this.op === OP_lookupswitch) { + str += 'targets:'; + for (i = 0, j = this.targets.length; i < j; i++) { + str += (i > 0 ? ',' : '') + this.targets[i].position; + } + } else { + for (i = 0, j = opDescription.operands.length; i < j; i++) { + var operand = opDescription.operands[i]; + if (operand.name === 'offset') { + str += 'target:' + this.target.position; + } else { + str += operand.name + ': '; + var value = this[operand.name]; + if (abc) { + switch (operand.type) { + case '': + str += value; + break; + case 'I': + str += abc.constantPool.ints[value]; + break; + case 'U': + str += abc.constantPool.uints[value]; + break; + case 'D': + str += abc.constantPool.doubles[value]; + break; + case 'S': + str += abc.constantPool.strings[value]; + break; + case 'N': + str += abc.constantPool.namespaces[value]; + break; + case 'CI': + str += abc.classes[value]; + break; + case 'M': + str += abc.constantPool.multinames[value]; + break; + default: + str += '?'; + break; + } + } else { + str += value; + } + } + if (i < j - 1) { + str += ', '; + } + } + } + return str; + } + }; + return Bytecode; + }(); +var Analysis = function () { + function blockSetClass(length, blockById) { + var BlockSet = BitSetFunctor(length); + var ADDRESS_BITS_PER_WORD = BlockSet.ADDRESS_BITS_PER_WORD; + var BITS_PER_WORD = BlockSet.BITS_PER_WORD; + var BIT_INDEX_MASK = BlockSet.BIT_INDEX_MASK; + BlockSet.singleton = function singleton(b) { + var bs = new BlockSet(); + bs.set(b.bid); + bs.count = 1; + bs.dirty = 0; + return bs; + }; + BlockSet.fromBlocks = function fromArray(other) { + var bs = new BlockSet(); + bs.setBlocks(other); + return bs; + }; + var Bsp = BlockSet.prototype; + if (BlockSet.singleword) { + Bsp.forEachBlock = function forEach(fn) { + true; + var byId = blockById; + var word = this.bits; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + fn(byId[k]); + } + } + } + }; + Bsp.choose = function choose() { + var byId = blockById; + var word = this.bits; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + return byId[k]; + } + } + } + }; + Bsp.members = function members() { + var byId = blockById; + var set = []; + var word = this.bits; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + set.push(byId[k]); + } + } + } + return set; + }; + Bsp.setBlocks = function setBlocks(bs) { + var bits = this.bits; + for (var i = 0, j = bs.length; i < j; i++) { + var id = bs[i].bid; + bits |= 1 << (id & BIT_INDEX_MASK); + } + this.bits = bits; + }; + } else { + Bsp.forEachBlock = function forEach(fn) { + true; + var byId = blockById; + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var word = bits[i]; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + fn(byId[i * BITS_PER_WORD + k]); + } + } + } + } + }; + Bsp.choose = function choose() { + var byId = blockById; + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var word = bits[i]; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + return byId[i * BITS_PER_WORD + k]; + } + } + } + } + }; + Bsp.members = function members() { + var byId = blockById; + var set = []; + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var word = bits[i]; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + set.push(byId[i * BITS_PER_WORD + k]); + } + } + } + } + return set; + }; + Bsp.setBlocks = function setBlocks(bs) { + var bits = this.bits; + for (var i = 0, j = bs.length; i < j; i++) { + var id = bs[i].bid; + bits[id >> ADDRESS_BITS_PER_WORD] |= 1 << (id & BIT_INDEX_MASK); + } + }; + } + return BlockSet; + } + function Analysis(method) { + Counter.count('Analysis'); + this.method = method; + if (this.method.code) { + Timer.start('Normalize'); + this.normalizeBytecode(); + Timer.stop(); + } + } + Analysis.prototype = { + normalizeBytecode: function normalizeBytecode() { + function getInvalidTarget(cache, offset) { + if (cache && cache[offset]) { + return cache[offset]; + } + var code = Object.create(Bytecode.prototype); + code.op = OP_invalid; + code.position = offset; + cache && (cache[offset] = code); + return code; + } + var method = this.method; + function accessLocal(index) { + if (index-- === 0) + return; + if (index < method.parameters.length) { + method.parameters[index].isUsed = true; + } + } + var bytecodesOffset = []; + var bytecodes = []; + var codeStream = new AbcStream(this.method.code); + var code; + while (codeStream.remaining() > 0) { + var pos = codeStream.position; + code = new Bytecode(codeStream); + switch (code.op) { + case OP_nop: + case OP_label: + bytecodesOffset[pos] = bytecodes.length; + continue; + case OP_lookupswitch: + this.method.hasLookupSwitches = true; + code.targets = []; + var offsets = code.offsets; + for (var i = 0, j = offsets.length; i < j; i++) { + offsets[i] += pos; + } + break; + case OP_jump: + case OP_iflt: + case OP_ifnlt: + case OP_ifle: + case OP_ifnle: + case OP_ifgt: + case OP_ifngt: + case OP_ifge: + case OP_ifnge: + case OP_ifeq: + case OP_ifne: + case OP_ifstricteq: + case OP_ifstrictne: + case OP_iftrue: + case OP_iffalse: + code.offset += codeStream.position; + break; + case OP_getlocal0: + case OP_getlocal1: + case OP_getlocal2: + case OP_getlocal3: + accessLocal(code.op - OP_getlocal0); + break; + case OP_getlocal: + accessLocal(code.index); + break; + default: + break; + } + code.position = bytecodes.length; + bytecodesOffset[pos] = bytecodes.length; + bytecodes.push(code); + } + var invalidJumps = {}; + var newOffset; + for (var pc = 0, end = bytecodes.length; pc < end; pc++) { + code = bytecodes[pc]; + switch (code.op) { + case OP_lookupswitch: + var offsets = code.offsets; + for (var i = 0, j = offsets.length; i < j; i++) { + newOffset = bytecodesOffset[offsets[i]]; + code.targets.push(bytecodes[newOffset] || getInvalidTarget(invalidJumps, offsets[i])); + offsets[i] = newOffset; + } + break; + case OP_jump: + case OP_iflt: + case OP_ifnlt: + case OP_ifle: + case OP_ifnle: + case OP_ifgt: + case OP_ifngt: + case OP_ifge: + case OP_ifnge: + case OP_ifeq: + case OP_ifne: + case OP_ifstricteq: + case OP_ifstrictne: + case OP_iftrue: + case OP_iffalse: + newOffset = bytecodesOffset[code.offset]; + code.target = bytecodes[newOffset] || getInvalidTarget(invalidJumps, code.offset); + code.offset = newOffset; + break; + default: + } + } + this.bytecodes = bytecodes; + var exceptions = this.method.exceptions; + for (var i = 0, j = exceptions.length; i < j; i++) { + var ex = exceptions[i]; + ex.start = bytecodesOffset[ex.start]; + ex.end = bytecodesOffset[ex.end]; + ex.offset = bytecodesOffset[ex.target]; + ex.target = bytecodes[ex.offset]; + ex.target.exception = ex; + } + }, + detectBasicBlocks: function detectBasicBlocks() { + var bytecodes = this.bytecodes; + var exceptions = this.method.exceptions; + var hasExceptions = exceptions.length > 0; + var blockById = {}; + var code; + var pc, end; + var id = 0; + function tryTargets(block) { + var targets = []; + for (var i = 0, j = exceptions.length; i < j; i++) { + var ex = exceptions[i]; + if (block.position >= ex.start && block.end.position <= ex.end) { + targets.push(ex.target); + } + } + return targets; + } + id = bytecodes[0].makeBlockHead(id); + for (pc = 0, end = bytecodes.length - 1; pc < end; pc++) { + code = bytecodes[pc]; + switch (code.op) { + case OP_returnvoid: + case OP_returnvalue: + case OP_throw: + id = bytecodes[pc + 1].makeBlockHead(id); + break; + case OP_lookupswitch: + var targets = code.targets; + for (var i = 0, j = targets.length; i < j; i++) { + id = targets[i].makeBlockHead(id); + } + id = bytecodes[pc + 1].makeBlockHead(id); + break; + case OP_jump: + case OP_iflt: + case OP_ifnlt: + case OP_ifle: + case OP_ifnle: + case OP_ifgt: + case OP_ifngt: + case OP_ifge: + case OP_ifnge: + case OP_ifeq: + case OP_ifne: + case OP_ifstricteq: + case OP_ifstrictne: + case OP_iftrue: + case OP_iffalse: + id = code.target.makeBlockHead(id); + id = bytecodes[pc + 1].makeBlockHead(id); + break; + default: + } + } + code = bytecodes[end]; + switch (code.op) { + case OP_returnvoid: + case OP_returnvalue: + case OP_throw: + break; + case OP_lookupswitch: + var targets = code.targets; + for (var i = 0, j = targets.length; i < j; i++) { + id = targets[i].makeBlockHead(id); + } + break; + case OP_jump: + id = code.target.makeBlockHead(id); + break; + case OP_iflt: + case OP_ifnlt: + case OP_ifle: + case OP_ifnle: + case OP_ifgt: + case OP_ifngt: + case OP_ifge: + case OP_ifnge: + case OP_ifeq: + case OP_ifne: + case OP_ifstricteq: + case OP_ifstrictne: + case OP_iftrue: + case OP_iffalse: + id = code.target.makeBlockHead(id); + bytecodes[pc + 1] = getInvalidTarget(null, pc + 1); + id = bytecodes[pc + 1].makeBlockHead(id); + break; + default: + } + if (hasExceptions) { + for (var i = 0, j = exceptions.length; i < j; i++) { + var ex = exceptions[i]; + var tryStart = bytecodes[ex.start]; + var afterTry = bytecodes[ex.end + 1]; + id = tryStart.makeBlockHead(id); + if (afterTry) { + id = afterTry.makeBlockHead(id); + } + id = ex.target.makeBlockHead(id); + } + } + var currentBlock = bytecodes[0]; + for (pc = 1, end = bytecodes.length; pc < end; pc++) { + if (!bytecodes[pc].succs) { + continue; + } + true; + blockById[currentBlock.bid] = currentBlock; + code = bytecodes[pc - 1]; + currentBlock.end = code; + var nextBlock = bytecodes[pc]; + switch (code.op) { + case OP_returnvoid: + case OP_returnvalue: + case OP_throw: + break; + case OP_lookupswitch: + for (var i = 0, j = code.targets.length; i < j; i++) { + currentBlock.succs.push(code.targets[i]); + } + break; + case OP_jump: + currentBlock.succs.push(code.target); + break; + case OP_iflt: + case OP_ifnlt: + case OP_ifle: + case OP_ifnle: + case OP_ifgt: + case OP_ifngt: + case OP_ifge: + case OP_ifnge: + case OP_ifeq: + case OP_ifne: + case OP_ifstricteq: + case OP_ifstrictne: + case OP_iftrue: + case OP_iffalse: + currentBlock.succs.push(code.target); + if (code.target !== nextBlock) { + currentBlock.succs.push(nextBlock); + } + break; + default: + currentBlock.succs.push(nextBlock); + } + if (hasExceptions) { + var targets = tryTargets(currentBlock); + currentBlock.hasCatches = targets.length > 0; + currentBlock.succs.push.apply(currentBlock.succs, targets); + } + currentBlock = nextBlock; + } + blockById[currentBlock.bid] = currentBlock; + code = bytecodes[end - 1]; + switch (code.op) { + case OP_lookupswitch: + for (var i = 0, j = code.targets.length; i < j; i++) { + currentBlock.succs.push(code.targets[i]); + } + break; + case OP_jump: + currentBlock.succs.push(code.target); + break; + default: + } + currentBlock.end = code; + this.BlockSet = blockSetClass(id, blockById); + }, + normalizeReachableBlocks: function normalizeReachableBlocks() { + var root = this.bytecodes[0]; + true; + var ONCE = 1; + var BUNCH_OF_TIMES = 2; + var BlockSet = this.BlockSet; + var blocks = []; + var visited = {}; + var ancestors = {}; + var worklist = [ + root + ]; + var node; + ancestors[root.bid] = true; + while (node = worklist.top()) { + if (visited[node.bid]) { + if (visited[node.bid] === ONCE) { + visited[node.bid] = BUNCH_OF_TIMES; + blocks.push(node); + var succs = node.succs; + for (var i = 0, j = succs.length; i < j; i++) { + succs[i].preds.push(node); + } + } + ancestors[node.bid] = false; + worklist.pop(); + continue; + } + visited[node.bid] = ONCE; + ancestors[node.bid] = true; + var succs = node.succs; + for (var i = 0, j = succs.length; i < j; i++) { + var s = succs[i]; + if (ancestors[s.bid]) { + if (!node.spbacks) { + node.spbacks = new BlockSet(); + } + node.spbacks.set(s.bid); + } + !visited[s.bid] && worklist.push(s); + } + } + this.blocks = blocks.reverse(); + }, + computeDominance: function computeDominance() { + function intersectDominators(doms, b1, b2) { + var finger1 = b1; + var finger2 = b2; + while (finger1 !== finger2) { + while (finger1 > finger2) { + finger1 = doms[finger1]; + } + while (finger2 > finger1) { + finger2 = doms[finger2]; + } + } + return finger1; + } + var blocks = this.blocks; + var n = blocks.length; + var doms = new Array(n); + doms[0] = 0; + var rpo = {}; + for (var b = 0; b < n; b++) { + rpo[blocks[b].bid] = b; + } + var changed = true; + while (changed) { + changed = false; + for (var b = 1; b < n; b++) { + var preds = blocks[b].preds; + var j = preds.length; + var newIdom = rpo[preds[0].bid]; + if (!(newIdom in doms)) { + for (var i = 1; i < j; i++) { + newIdom = rpo[preds[i].bid]; + if (newIdom in doms) { + break; + } + } + } + true; + for (var i = 0; i < j; i++) { + var p = rpo[preds[i].bid]; + if (p === newIdom) { + continue; + } + if (p in doms) { + newIdom = intersectDominators(doms, p, newIdom); + } + } + if (doms[b] !== newIdom) { + doms[b] = newIdom; + changed = true; + } + } + } + blocks[0].dominator = blocks[0]; + var block; + for (var b = 1; b < n; b++) { + block = blocks[b]; + var idom = blocks[doms[b]]; + block.dominator = idom; + idom.dominatees.push(block); + block.npreds = block.preds.length; + } + var worklist = [ + blocks[0] + ]; + blocks[0].level || (blocks[0].level = 0); + while (block = worklist.shift()) { + var dominatees = block.dominatees; + for (var i = 0, j = dominatees.length; i < j; i++) { + dominatees[i].level = block.level + 1; + } + worklist.push.apply(worklist, dominatees); + } + }, + analyzeControlFlow: function analyzeControlFlow() { + true; + this.detectBasicBlocks(); + this.normalizeReachableBlocks(); + this.computeDominance(); + this.analyzedControlFlow = true; + return true; + }, + markLoops: function markLoops() { + if (!this.analyzedControlFlow && !this.analyzeControlFlow()) { + return false; + } + var BlockSet = this.BlockSet; + function findSCCs(root) { + var preorderId = 1; + var preorder = {}; + var assigned = {}; + var unconnectedNodes = []; + var pendingNodes = []; + var sccs = []; + var level = root.level + 1; + var worklist = [ + root + ]; + var node; + var u, s; + while (node = worklist.top()) { + if (preorder[node.bid]) { + if (pendingNodes.peek() === node) { + pendingNodes.pop(); + var scc = []; + do { + u = unconnectedNodes.pop(); + assigned[u.bid] = true; + scc.push(u); + } while (u !== node); + if (scc.length > 1 || u.spbacks && u.spbacks.get(u.bid)) { + sccs.push(scc); + } + } + worklist.pop(); + continue; + } + preorder[node.bid] = preorderId++; + unconnectedNodes.push(node); + pendingNodes.push(node); + var succs = node.succs; + for (var i = 0, j = succs.length; i < j; i++) { + s = succs[i]; + if (s.level < level) { + continue; + } + var sid = s.bid; + if (!preorder[sid]) { + worklist.push(s); + } else if (!assigned[sid]) { + while (preorder[pendingNodes.peek().bid] > preorder[sid]) { + pendingNodes.pop(); + } + } + } + } + return sccs; + } + function findLoopHeads(blocks) { + var heads = new BlockSet(); + for (var i = 0, j = blocks.length; i < j; i++) { + var block = blocks[i]; + var spbacks = block.spbacks; + if (!spbacks) { + continue; + } + var succs = block.succs; + for (var k = 0, l = succs.length; k < l; k++) { + var s = succs[k]; + if (spbacks.get(s.bid)) { + heads.set(s.dominator.bid); + } + } + } + return heads.members(); + } + function LoopInfo(scc, loopId) { + var body = new BlockSet(); + body.setBlocks(scc); + body.recount(); + this.id = loopId; + this.body = body; + this.exit = new BlockSet(); + this.save = {}; + this.head = new BlockSet(); + this.npreds = 0; + } + var heads = findLoopHeads(this.blocks); + if (heads.length <= 0) { + this.markedLoops = true; + return true; + } + var worklist = heads.sort(function (a, b) { + return a.level - b.level; + }); + var loopId = 0; + for (var n = worklist.length - 1; n >= 0; n--) { + var top = worklist[n]; + var sccs = findSCCs(top); + if (sccs.length === 0) { + continue; + } + for (var i = 0, j = sccs.length; i < j; i++) { + var scc = sccs[i]; + var loop = new LoopInfo(scc, loopId++); + for (var k = 0, l = scc.length; k < l; k++) { + var h = scc[k]; + if (h.level === top.level + 1 && !h.loop) { + h.loop = loop; + loop.head.set(h.bid); + var preds = h.preds; + for (var pi = 0, pj = preds.length; pi < pj; pi++) { + loop.body.get(preds[pi].bid) && h.npreds--; + } + loop.npreds += h.npreds; + } + } + for (var k = 0, l = scc.length; k < l; k++) { + var h = scc[k]; + if (h.level === top.level + 1) { + h.npreds = loop.npreds; + } + } + loop.head.recount(); + } + } + this.markedLoops = true; + return true; + } + }; + return Analysis; + }(); +(function (exports) { + var lang = exports.lang = { + Node: {}, + Program: { + extends: 'Node', + fields: [ + '@body' + ] + }, + Statement: { + extends: 'Node' + }, + EmptyStatement: { + extends: 'Statement' + }, + BlockStatement: { + extends: 'Statement', + fields: [ + '@body' + ] + }, + ExpressionStatement: { + extends: 'Statement', + fields: [ + '@expression' + ] + }, + IfStatement: { + extends: 'Statement', + fields: [ + '@test', + '@consequent', + '@alternate' + ] + }, + LabeledStatement: { + extends: 'Statement', + fields: [ + '@label', + '@body' + ] + }, + BreakStatement: { + extends: 'Statement', + fields: [ + '@label' + ] + }, + ContinueStatement: { + extends: 'Statement', + fields: [ + '@label' + ] + }, + WithStatement: { + extends: 'Statement', + fields: [ + '@object', + '@body' + ] + }, + SwitchStatement: { + extends: 'Statement', + fields: [ + '@discriminant', + '@cases', + 'lexical' + ] + }, + ReturnStatement: { + extends: 'Statement', + fields: [ + '@argument' + ] + }, + ThrowStatement: { + extends: 'Statement', + fields: [ + '@argument' + ] + }, + TryStatement: { + extends: 'Statement', + fields: [ + '@block', + '@handlers', + '@finalizer' + ] + }, + WhileStatement: { + extends: 'Statement', + fields: [ + '@test', + '@body' + ] + }, + DoWhileStatement: { + extends: 'Statement', + fields: [ + '@body', + '@test' + ] + }, + ForStatement: { + extends: 'Statement', + fields: [ + '@init', + '@test', + '@update', + '@body' + ] + }, + ForInStatement: { + extends: 'Statement', + fields: [ + '@left', + '@right', + '@body', + 'each' + ] + }, + LetStatement: { + extends: 'Statement', + fields: [ + '@head', + '@body' + ] + }, + DebuggerStatement: { + extends: 'Statement' + }, + Declaration: { + extends: 'Statement' + }, + FunctionDeclaration: { + extends: 'Declaration', + fields: [ + '@id', + '@params', + '@body', + '@decltype', + 'generator', + 'expression', + '@modifiers' + ] + }, + VariableDeclaration: { + extends: 'Declaration', + fields: [ + 'kind', + '@declarations' + ] + }, + VariableDeclarator: { + extends: 'Node', + fields: [ + '@id', + '@init', + '@decltype', + '@arguments' + ] + }, + Expression: { + extends: 'Pattern' + }, + ThisExpression: { + extends: 'Expression' + }, + ArrayExpression: { + extends: 'Expression', + fields: [ + '@elements' + ] + }, + ObjectExpression: { + extends: 'Expression', + fields: [ + '@properties' + ] + }, + Property: { + extends: 'Node', + fields: [ + '@key', + '@value', + 'kind' + ] + }, + FunctionExpression: { + extends: 'Expression', + fields: [ + '@id', + '@params', + '@body', + '@decltype', + 'generator', + 'expression' + ] + }, + SequenceExpression: { + extends: 'Expression', + fields: [ + '@expressions' + ] + }, + UnaryExpression: { + extends: 'Expression', + fields: [ + 'operator', + '@argument', + 'prefix' + ] + }, + BinaryExpression: { + extends: 'Expression', + fields: [ + 'operator', + '@left', + '@right' + ] + }, + AssignmentExpression: { + extends: 'Expression', + fields: [ + '@left', + 'operator', + '@right' + ] + }, + UpdateExpression: { + extends: 'Expression', + fields: [ + 'operator', + '@argument', + 'prefix' + ] + }, + LogicalExpression: { + extends: 'Expression', + fields: [ + 'operator', + '@left', + '@right' + ] + }, + ConditionalExpression: { + extends: 'Expression', + fields: [ + '@test', + '@consequent', + '@alternate' + ] + }, + NewExpression: { + extends: 'Expression', + fields: [ + '@callee', + '@arguments' + ] + }, + CallExpression: { + extends: 'Expression', + fields: [ + '@callee', + '@arguments' + ] + }, + MemberExpression: { + extends: 'Expression', + fields: [ + '@object', + '@property', + 'computed', + 'kind' + ] + }, + YieldExpression: { + extends: 'Expression', + fields: [ + '@argument' + ] + }, + ComprehensionExpression: { + extends: 'Expression', + fields: [ + '@blocks', + '@filter' + ] + }, + GeneratorExpression: { + extends: 'Expression', + fields: [ + '@blocks', + '@filter' + ] + }, + LetExpression: { + extends: 'Expression', + fields: [ + '@head', + '@body' + ] + }, + Pattern: { + extends: 'Node' + }, + ObjectPattern: { + extends: 'Pattern', + fields: [ + '@properties' + ] + }, + ArrayPattern: { + extends: 'Pattern', + fields: [ + '@elements' + ] + }, + SwitchCase: { + extends: 'Node', + fields: [ + '@test', + '@consequent' + ] + }, + CatchClause: { + extends: 'Node', + fields: [ + '@param', + '@guard', + '@body' + ] + }, + Identifier: { + extends: 'Expression', + fields: [ + 'name', + 'kind' + ] + }, + Literal: { + extends: 'Expression', + fields: [ + 'value' + ] + }, + Type: { + extends: 'Node' + }, + PointerType: { + extends: 'Type', + fields: [ + '@base' + ] + }, + ArrayType: { + extends: 'PointerType', + fields: [ + 'length' + ] + }, + StructType: { + extends: 'Type', + fields: [ + '@id', + '@members', + 'isUnion' + ] + }, + MemberDeclarator: { + extends: 'Node', + fields: [ + 'modifiers', + '@declarator' + ] + }, + ArrowType: { + extends: 'Type', + fields: [ + '@params', + '@return' + ] + }, + TypeIdentifier: { + extends: 'Type', + fields: [ + 'name' + ] + }, + TypeAliasDirective: { + extends: 'Node', + fields: [ + '@original', + '@alias' + ] + }, + CastExpression: { + extends: 'Expression', + fields: [ + '@as', + '@argument' + ] + } + }; + function allFields(spec) { + var fields = [ + 'leadingComments', + 'loc' + ]; + while (spec) { + if (spec.fields) { + fields = spec.fields.concat(fields); + } + spec = spec.extends ? lang[spec.extends] : null; + } + return fields; + } + ; + exports.allFields = allFields; + function prefixUnderscore(s) { + return '_' + s; + } + function ensureConstructor(name, spec) { + if (!exports[name]) { + var fields = allFields(spec); + var children = []; + var body = [ + 'this.type = "' + name + '";' + ]; + for (var i = 0, j = fields.length; i < j; i++) { + var fname = fields[i]; + if (fname.charAt(0) === '@') { + fields[i] = fname = fname.substr(1); + children.push(fname); + } + body.push('this.' + fname + ' = _' + fname + ';'); + } + var node = new Function(fields.map(prefixUnderscore), body.join('\n')); + if (spec.extends) { + var pnode = ensureConstructor(spec.extends, lang[spec.extends]); + node.prototype = Object.create(pnode.prototype); + } + Object.defineProperty(node.prototype, '_children', { + value: children, + writable: true, + configurable: true, + enumerable: false + }); + exports[name] = node; + } + return exports[name]; + } + for (var name in lang) { + ensureConstructor(name, lang[name]); + } + exports.makePass = function makePass(name, prop) { + return function (o) { + var trans, arr; + var child, children = this._children; + for (var i = 0, j = children.length; i < j; i++) { + if (!(child = this[children[i]])) { + continue; + } + if (child instanceof Array) { + arr = this[children[i]] = []; + for (var k = 0, l = child.length; k < l; k++) { + if (!child[k]) { + arr.push(child[k]); + } else if (typeof child[k][name] === 'function') { + trans = child[k][name](o); + if (trans !== null) { + arr.push(trans); + } + } + } + } else if (typeof child[name] === 'function') { + trans = child[name](o); + if (trans === null) { + this[children[i]] = undefined; + } else { + this[children[i]] = trans; + } + } + } + if (typeof this[prop] === 'function') { + if (o.logger && typeof this.loc !== 'undefined') { + o.logger.push(this); + trans = this[prop](o); + o.logger.pop(); + } else { + trans = this[prop](o); + } + if (trans === null) { + return null; + } + return trans ? trans : this; + } + return this; + }; + }; + exports.makePass = function makePass(name, prop, backward) { + return function (o) { + var trans, arr; + var child, children = this._children; + var i, k; + for (var x = 0, j = children.length; x < j; x++) { + i = backward ? children.length - 1 - x : x; + if (!(child = this[children[i]])) { + continue; + } + if (child instanceof Array) { + arr = this[children[i]] = []; + var y; + for (var y = 0, l = child.length; y < l; y++) { + k = backward ? child.length - 1 - y : y; + if (!child[k]) { + if (backward) { + arr.unshift(child[k]); + } else { + arr.push(child[k]); + } + } else if (typeof child[k][name] === 'function') { + trans = child[k][name](o); + if (trans !== null) { + if (backward) { + arr.unshift(trans); + } else { + arr.push(trans); + } + } + } + } + } else if (typeof child[name] === 'function') { + trans = child[name](o); + if (trans === null) { + this[children[i]] = undefined; + } else { + this[children[i]] = trans; + } + } + } + if (typeof this[prop] === 'function') { + if (o.logger && typeof this.loc !== 'undefined') { + o.logger.push(this); + trans = this[prop](o); + o.logger.pop(); + } else { + trans = this[prop](o); + } + if (trans === null) { + return null; + } + return trans ? trans : this; + } + return this; + }; + }; + exports.lift = function lift(raw) { + if (!raw) { + return raw; + } + if (raw instanceof Array) { + return raw.map(function (r) { + return r ? lift(r) : r; + }); + } + var type = raw.type; + var Node = exports[type]; + if (!Node) { + throw new Error('unknown node type `' + type + '\''); + } + var node = new Node(); + node.loc = raw.loc; + var fields = allFields(lang[type]); + for (var i = 0, j = fields.length; i < j; i++) { + var field; + if (fields[i].charAt(0) === '@') { + field = fields[i].substr(1); + if (raw[field]) { + node[field] = lift(raw[field]); + } + } else { + field = fields[i]; + node[field] = raw[field]; + } + } + return node; + }; + exports.flatten = function flatten(node) { + if (!node) { + return node; + } + if (node instanceof Array) { + return node.map(function (n) { + return flatten(n); + }); + } + var type = node.type; + var raw = { + type: type + }; + var fields = allFields(lang[type]); + for (var i = 0, j = fields.length; i < j; i++) { + var field; + if (fields[i].charAt(0) === '@') { + field = fields[i].substr(1); + if (node[field]) { + raw[field] = flatten(node[field]); + } else { + raw[field] = null; + } + } else { + field = fields[i]; + raw[field] = node[field]; + } + } + return raw; + }; +}(typeof exports === 'undefined' ? estransform = {} : exports)); +(function (exports) { + var Syntax, Precedence, BinaryPrecedence, Regex, VisitorKeys, VisitorOption, isArray, base, indent, json, renumber, hexadecimal, quotes, escapeless, newline, space, parentheses, semicolons, extra, parse; + Syntax = { + AssignmentExpression: 'AssignmentExpression', + ArrayExpression: 'ArrayExpression', + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DoWhileStatement: 'DoWhileStatement', + DebuggerStatement: 'DebuggerStatement', + EmptyStatement: 'EmptyStatement', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForInStatement: 'ForInStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + Identifier: 'Identifier', + IfStatement: 'IfStatement', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + Program: 'Program', + Property: 'Property', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SwitchStatement: 'SwitchStatement', + SwitchCase: 'SwitchCase', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement' + }; + Precedence = { + Sequence: 0, + Assignment: 1, + Conditional: 2, + LogicalOR: 3, + LogicalAND: 4, + BitwiseOR: 5, + BitwiseXOR: 6, + BitwiseAND: 7, + Equality: 8, + Relational: 9, + BitwiseSHIFT: 10, + Additive: 11, + Multiplicative: 12, + Unary: 13, + Postfix: 14, + Call: 15, + New: 16, + Member: 17, + Primary: 18 + }; + BinaryPrecedence = { + '||': Precedence.LogicalOR, + '&&': Precedence.LogicalAND, + '|': Precedence.BitwiseOR, + '^': Precedence.BitwiseXOR, + '&': Precedence.BitwiseAND, + '==': Precedence.Equality, + '!=': Precedence.Equality, + '===': Precedence.Equality, + '!==': Precedence.Equality, + '<': Precedence.Relational, + '>': Precedence.Relational, + '<=': Precedence.Relational, + '>=': Precedence.Relational, + 'in': Precedence.Relational, + 'instanceof': Precedence.Relational, + '<<': Precedence.BitwiseSHIFT, + '>>': Precedence.BitwiseSHIFT, + '>>>': Precedence.BitwiseSHIFT, + '+': Precedence.Additive, + '-': Precedence.Additive, + '*': Precedence.Multiplicative, + '%': Precedence.Multiplicative, + '/': Precedence.Multiplicative + }; + Regex = { + NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]') + }; + function getDefaultOptions() { + return { + indent: null, + base: null, + parse: null, + comment: false, + format: { + indent: { + style: ' ', + base: 0, + adjustMultilineComment: false + }, + json: false, + renumber: false, + hexadecimal: false, + quotes: 'single', + escapeless: false, + compact: false, + parentheses: true, + semicolons: true + } + }; + } + function stringToArray(str) { + var length = str.length, result = [], i; + for (i = 0; i < length; i += 1) { + result[i] = str.charAt(i); + } + return result; + } + function stringRepeat(str, num) { + var result = ''; + for (num |= 0; num > 0; num >>>= 1, str += str) { + if (num & 1) { + result += str; + } + } + return result; + } + isArray = Array.isArray; + if (!isArray) { + isArray = function isArray(array) { + return Object.prototype.toString.call(array) === '[object Array]'; + }; + } + function endsWithLineTerminator(str) { + var len, ch; + len = str.length; + ch = str.charAt(len - 1); + return ch === '\r' || ch === '\n'; + } + function shallowCopy(obj) { + var ret = {}, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + ret[key] = obj[key]; + } + } + return ret; + } + function deepCopy(obj) { + var ret = {}, key, val; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + val = obj[key]; + if (typeof val === 'object' && val !== null) { + ret[key] = deepCopy(val); + } else { + ret[key] = val; + } + } + } + return ret; + } + function updateDeeply(target, override) { + var key, val; + function isHashObject(target) { + return typeof target === 'object' && target instanceof Object && !(target instanceof RegExp); + } + for (key in override) { + if (override.hasOwnProperty(key)) { + val = override[key]; + if (isHashObject(val)) { + if (isHashObject(target[key])) { + updateDeeply(target[key], val); + } else { + target[key] = updateDeeply({}, val); + } + } else { + target[key] = val; + } + } + } + return target; + } + function generateNumber(value) { + var result, point, temp, exponent, pos; + if (value !== value) { + throw new Error('Numeric literal whose value is NaN'); + } + if (1 / value < 0) { + throw new Error('Numeric literal whose value is negative'); + } + if (value === 1 / 0) { + return json ? 'null' : renumber ? '1e400' : '1e+400'; + } + result = '' + value; + if (!renumber || result.length < 3) { + return result; + } + point = result.indexOf('.'); + if (!json && result.charAt(0) === '0' && point === 1) { + point = 0; + result = result.slice(1); + } + temp = result; + result = result.replace('e+', 'e'); + exponent = 0; + if ((pos = temp.indexOf('e')) > 0) { + exponent = +temp.slice(pos + 1); + temp = temp.slice(0, pos); + } + if (point >= 0) { + exponent -= temp.length - point - 1; + temp = +(temp.slice(0, point) + temp.slice(point + 1)) + ''; + } + pos = 0; + while (temp.charAt(temp.length + pos - 1) === '0') { + pos -= 1; + } + if (pos !== 0) { + exponent -= pos; + temp = temp.slice(0, pos); + } + if (exponent !== 0) { + temp += 'e' + exponent; + } + if ((temp.length < result.length || hexadecimal && value > 1000000000000 && Math.floor(value) === value && (temp = '0x' + value.toString(16)).length < result.length) && +temp === value) { + result = temp; + } + return result; + } + function escapeAllowedCharacter(ch, next) { + var code = ch.charCodeAt(0), hex = code.toString(16), result = '\\'; + switch (ch) { + case '\b': + result += 'b'; + break; + case '\f': + result += 'f'; + break; + case '\t': + result += 't'; + break; + default: + if (json || code > 255) { + result += 'u' + '0000'.slice(hex.length) + hex; + } else if (ch === '\0' && '0123456789'.indexOf(next) < 0) { + result += '0'; + } else if (ch === '\v') { + result += 'v'; + } else { + result += 'x' + '00'.slice(hex.length) + hex; + } + break; + } + return result; + } + function escapeDisallowedCharacter(ch) { + var result = '\\'; + switch (ch) { + case '\\': + result += '\\'; + break; + case '\n': + result += 'n'; + break; + case '\r': + result += 'r'; + break; + case '\u2028': + result += 'u2028'; + break; + case '\u2029': + result += 'u2029'; + break; + default: + throw new Error('Incorrectly classified character'); + } + return result; + } + function escapeString(str) { + var result = '', i, len, ch, next, singleQuotes = 0, doubleQuotes = 0, single; + if (typeof str[0] === 'undefined') { + str = stringToArray(str); + } + for (i = 0, len = str.length; i < len; i += 1) { + ch = str[i]; + if (ch === '\'') { + singleQuotes += 1; + } else if (ch === '"') { + doubleQuotes += 1; + } else if (ch === '/' && json) { + result += '\\'; + } else if ('\\\n\r\u2028\u2029'.indexOf(ch) >= 0) { + result += escapeDisallowedCharacter(ch); + continue; + } else if (json && ch < ' ' || !(json || escapeless || ch >= ' ' && ch <= '~')) { + result += escapeAllowedCharacter(ch, str[i + 1]); + continue; + } + result += ch; + } + single = !(quotes === 'double' || quotes === 'auto' && doubleQuotes < singleQuotes); + str = result; + result = single ? '\'' : '"'; + if (typeof str[0] === 'undefined') { + str = stringToArray(str); + } + for (i = 0, len = str.length; i < len; i += 1) { + ch = str[i]; + if (ch === '\'' && single || ch === '"' && !single) { + result += '\\'; + } + result += ch; + } + return result + (single ? '\'' : '"'); + } + function isWhiteSpace(ch) { + return '\t\v\f \xa0'.indexOf(ch) >= 0 || ch.charCodeAt(0) >= 5760 && '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\ufeff'.indexOf(ch) >= 0; + } + function isLineTerminator(ch) { + return '\n\r\u2028\u2029'.indexOf(ch) >= 0; + } + function isIdentifierPart(ch) { + return ch === '$' || ch === '_' || ch === '\\' || ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9' || ch.charCodeAt(0) >= 128 && Regex.NonAsciiIdentifierPart.test(ch); + } + function join(left, right) { + var leftChar = left.charAt(left.length - 1), rightChar = right.charAt(0); + if ((leftChar === '+' || leftChar === '-') && leftChar === rightChar || isIdentifierPart(leftChar) && isIdentifierPart(rightChar)) { + return left + ' ' + right; + } else if (isWhiteSpace(leftChar) || isLineTerminator(leftChar) || isWhiteSpace(rightChar) || isLineTerminator(rightChar)) { + return left + right; + } + return left + space + right; + } + function addIndent(stmt) { + return base + stmt; + } + function calculateSpaces(str) { + var i; + for (i = str.length - 1; i >= 0; i -= 1) { + if (isLineTerminator(str.charAt(i))) { + break; + } + } + return str.length - 1 - i; + } + function adjustMultilineComment(value, specialBase) { + var array, i, len, line, j, ch, spaces, previousBase; + array = value.split(/\r\n|[\r\n]/); + spaces = Number.MAX_VALUE; + for (i = 1, len = array.length; i < len; i += 1) { + line = array[i]; + j = 0; + while (j < line.length && isWhiteSpace(line[j])) { + j += 1; + } + if (spaces > j) { + spaces = j; + } + } + if (typeof specialBase !== 'undefined') { + previousBase = base; + if (array[1][spaces] === '*') { + specialBase += ' '; + } + base = specialBase; + } else { + if (spaces % 2 === 1) { + spaces -= 1; + } + previousBase = base; + } + for (i = 1, len = array.length; i < len; i += 1) { + array[i] = addIndent(array[i].slice(spaces)); + } + base = previousBase; + return array.join('\n'); + } + function generateComment(comment, specialBase) { + if (comment.type === 'Line') { + if (endsWithLineTerminator(comment.value)) { + return '//' + comment.value; + } else { + return '//' + comment.value + '\n'; + } + } + if (extra.format.indent.adjustMultilineComment && /[\n\r]/.test(comment.value)) { + return adjustMultilineComment('/*' + comment.value + '*/', specialBase); + } + return '/*' + comment.value + '*/'; + } + function addCommentsToStatement(stmt, result) { + var i, len, comment, save, node, tailingToStatement, specialBase, fragment; + if (stmt.leadingComments) { + save = result; + comment = stmt.leadingComments[0]; + result = generateComment(comment); + if (!endsWithLineTerminator(result)) { + result += '\n'; + } + for (i = 1, len = stmt.leadingComments.length; i < len; i += 1) { + comment = stmt.leadingComments[i]; + fragment = generateComment(comment); + if (!endsWithLineTerminator(fragment)) { + fragment += '\n'; + } + result += addIndent(fragment); + } + result += addIndent(save); + } + if (stmt.trailingComments) { + tailingToStatement = !endsWithLineTerminator(result); + specialBase = stringRepeat(' ', calculateSpaces(base + result + indent)); + for (i = 0, len = stmt.trailingComments.length; i < len; i += 1) { + comment = stmt.trailingComments[i]; + if (tailingToStatement) { + if (i === 0) { + result += indent; + } else { + result += specialBase; + } + result += generateComment(comment, specialBase); + } else { + result += addIndent(generateComment(comment)); + } + if (i !== len - 1 && !endsWithLineTerminator(result)) { + result += '\n'; + } + } + } + return result; + } + function parenthesize(text, current, should) { + if (current < should) { + return '(' + text + ')'; + } + return text; + } + function maybeBlock(stmt, semicolonOptional) { + var previousBase, result, noLeadingComment; + noLeadingComment = !extra.comment || !stmt.leadingComments; + if (stmt.type === Syntax.BlockStatement && noLeadingComment) { + return space + generateStatement(stmt); + } + if (stmt.type === Syntax.EmptyStatement && noLeadingComment) { + return ';'; + } + previousBase = base; + base += indent; + result = newline + addIndent(generateStatement(stmt, { + semicolonOptional: semicolonOptional + })); + base = previousBase; + return result; + } + function maybeBlockSuffix(stmt, result) { + if (stmt.type === Syntax.BlockStatement && (!extra.comment || !stmt.leadingComments) && !endsWithLineTerminator(result)) { + return space; + } + if (endsWithLineTerminator(result)) { + return addIndent(''); + } + return (newline === '' ? ' ' : newline) + addIndent(''); + } + function generateFunctionBody(node) { + var result, i, len; + result = '('; + for (i = 0, len = node.params.length; i < len; i += 1) { + result += node.params[i].name; + if (i + 1 < len) { + result += ',' + space; + } + } + return result + ')' + maybeBlock(node.body); + } + function generateExpression(expr, option) { + var result, precedence, currentPrecedence, previousBase, i, len, raw, fragment, allowIn, allowCall, allowUnparenthesizedNew; + precedence = option.precedence; + allowIn = option.allowIn; + allowCall = option.allowCall; + switch (expr.type) { + case Syntax.SequenceExpression: + result = ''; + allowIn |= Precedence.Sequence < precedence; + for (i = 0, len = expr.expressions.length; i < len; i += 1) { + result += generateExpression(expr.expressions[i], { + precedence: Precedence.Assignment, + allowIn: allowIn, + allowCall: true + }); + if (i + 1 < len) { + result += ',' + space; + } + } + result = parenthesize(result, Precedence.Sequence, precedence); + break; + case Syntax.AssignmentExpression: + allowIn |= Precedence.Assignment < precedence; + result = parenthesize(generateExpression(expr.left, { + precedence: Precedence.Call, + allowIn: allowIn, + allowCall: true + }) + space + expr.operator + space + generateExpression(expr.right, { + precedence: Precedence.Assignment, + allowIn: allowIn, + allowCall: true + }), Precedence.Assignment, precedence); + break; + case Syntax.ConditionalExpression: + allowIn |= Precedence.Conditional < precedence; + result = parenthesize(generateExpression(expr.test, { + precedence: Precedence.LogicalOR, + allowIn: allowIn, + allowCall: true + }) + space + '?' + space + generateExpression(expr.consequent, { + precedence: Precedence.Assignment, + allowIn: allowIn, + allowCall: true + }) + space + ':' + space + generateExpression(expr.alternate, { + precedence: Precedence.Assignment, + allowIn: allowIn, + allowCall: true + }), Precedence.Conditional, precedence); + break; + case Syntax.LogicalExpression: + case Syntax.BinaryExpression: + currentPrecedence = BinaryPrecedence[expr.operator]; + allowIn |= currentPrecedence < precedence; + result = join(generateExpression(expr.left, { + precedence: currentPrecedence, + allowIn: allowIn, + allowCall: true + }), expr.operator); + fragment = generateExpression(expr.right, { + precedence: currentPrecedence + 1, + allowIn: allowIn, + allowCall: true + }); + if (expr.operator === '/' && result.charAt(result.length - 1) === '/') { + result += ' ' + fragment; + } else { + result = join(result, fragment); + } + if (expr.operator === 'in' && !allowIn) { + result = '(' + result + ')'; + } else { + result = parenthesize(result, currentPrecedence, precedence); + } + break; + case Syntax.CallExpression: + result = generateExpression(expr.callee, { + precedence: Precedence.Call, + allowIn: true, + allowCall: true, + allowUnparenthesizedNew: false + }); + result += '('; + for (i = 0, len = expr['arguments'].length; i < len; i += 1) { + result += generateExpression(expr['arguments'][i], { + precedence: Precedence.Assignment, + allowIn: true, + allowCall: true + }); + if (i + 1 < len) { + result += ',' + space; + } + } + result += ')'; + if (!allowCall) { + result = '(' + result + ')'; + } else { + result = parenthesize(result, Precedence.Call, precedence); + } + break; + case Syntax.NewExpression: + len = expr['arguments'].length; + allowUnparenthesizedNew = option.allowUnparenthesizedNew === undefined || option.allowUnparenthesizedNew; + result = join('new', generateExpression(expr.callee, { + precedence: Precedence.New, + allowIn: true, + allowCall: false, + allowUnparenthesizedNew: allowUnparenthesizedNew && !parentheses && len === 0 + })); + if (!allowUnparenthesizedNew || parentheses || len > 0) { + result += '('; + for (i = 0; i < len; i += 1) { + result += generateExpression(expr['arguments'][i], { + precedence: Precedence.Assignment, + allowIn: true, + allowCall: true + }); + if (i + 1 < len) { + result += ',' + space; + } + } + result += ')'; + } + result = parenthesize(result, Precedence.New, precedence); + break; + case Syntax.MemberExpression: + result = generateExpression(expr.object, { + precedence: Precedence.Call, + allowIn: true, + allowCall: allowCall, + allowUnparenthesizedNew: false + }); + if (expr.computed) { + result += '[' + generateExpression(expr.property, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: allowCall + }) + ']'; + } else { + if (expr.object.type === Syntax.Literal && typeof expr.object.value === 'number') { + if (result.indexOf('.') < 0) { + if (!/[eExX]/.test(result) && !(result.length >= 2 && result[0] === '0')) { + result += '.'; + } + } + } + result += '.' + expr.property.name; + } + result = parenthesize(result, Precedence.Member, precedence); + break; + case Syntax.UnaryExpression: + fragment = generateExpression(expr.argument, { + precedence: Precedence.Unary + (expr.argument.type === Syntax.UnaryExpression && expr.operator.length < 3 && expr.argument.operator === expr.operator ? 1 : 0), + allowIn: true, + allowCall: true + }); + if (space === '') { + result = join(expr.operator, fragment); + } else { + result = expr.operator; + if (result.length > 2) { + result += ' '; + } + result += fragment; + } + result = parenthesize(result, Precedence.Unary, precedence); + break; + case Syntax.UpdateExpression: + if (expr.prefix) { + result = parenthesize(expr.operator + generateExpression(expr.argument, { + precedence: Precedence.Unary, + allowIn: true, + allowCall: true + }), Precedence.Unary, precedence); + } else { + result = parenthesize(generateExpression(expr.argument, { + precedence: Precedence.Postfix, + allowIn: true, + allowCall: true + }) + expr.operator, Precedence.Postfix, precedence); + } + break; + case Syntax.FunctionExpression: + result = 'function'; + if (expr.id) { + result += ' ' + expr.id.name; + } else { + result += space; + } + result += generateFunctionBody(expr); + break; + case Syntax.ArrayExpression: + if (!expr.elements.length) { + result = '[]'; + break; + } + result = '[' + newline; + previousBase = base; + base += indent; + for (i = 0, len = expr.elements.length; i < len; i += 1) { + if (!expr.elements[i]) { + result += addIndent(''); + if (i + 1 === len) { + result += ','; + } + } else { + result += addIndent(generateExpression(expr.elements[i], { + precedence: Precedence.Assignment, + allowIn: true, + allowCall: true + })); + } + if (i + 1 < len) { + result += ',' + newline; + } + } + base = previousBase; + if (!endsWithLineTerminator(result)) { + result += newline; + } + result += addIndent(']'); + break; + case Syntax.Property: + if (expr.kind === 'get' || expr.kind === 'set') { + result = expr.kind + ' ' + generateExpression(expr.key, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + generateFunctionBody(expr.value); + } else { + result = generateExpression(expr.key, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ':' + space + generateExpression(expr.value, { + precedence: Precedence.Assignment, + allowIn: true, + allowCall: true + }); + } + break; + case Syntax.ObjectExpression: + if (!expr.properties.length) { + result = '{}'; + break; + } + result = '{' + newline; + previousBase = base; + base += indent; + for (i = 0, len = expr.properties.length; i < len; i += 1) { + result += addIndent(generateExpression(expr.properties[i], { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + })); + if (i + 1 < len) { + result += ',' + newline; + } + } + base = previousBase; + if (!endsWithLineTerminator(result)) { + result += newline; + } + result += addIndent('}'); + break; + case Syntax.ThisExpression: + result = 'this'; + break; + case Syntax.Identifier: + result = expr.name; + break; + case Syntax.Literal: + if (expr.hasOwnProperty('raw') && parse) { + try { + raw = parse(expr.raw).body[0].expression; + if (raw.type === Syntax.Literal) { + if (raw.value === expr.value) { + result = expr.raw; + break; + } + } + } catch (e) { + } + } + if (expr.value === null) { + result = 'null'; + break; + } + if (typeof expr.value === 'string') { + result = escapeString(expr.value); + break; + } + if (typeof expr.value === 'number') { + result = generateNumber(expr.value); + break; + } + result = expr.value.toString(); + break; + default: + break; + } + if (result === undefined) { + throw new Error('Unknown expression type: ' + expr.type); + } + return result; + } + function generateStatement(stmt, option) { + var i, len, result, previousBase, node, allowIn, fragment, semicolon; + allowIn = true; + semicolon = ';'; + if (option) { + allowIn = option.allowIn === undefined || option.allowIn; + if (!semicolons && option.semicolonOptional === true) { + semicolon = ''; + } + } + switch (stmt.type) { + case Syntax.BlockStatement: + result = '{' + newline; + previousBase = base; + base += indent; + for (i = 0, len = stmt.body.length; i < len; i += 1) { + fragment = addIndent(generateStatement(stmt.body[i], { + semicolonOptional: i === len - 1 + })); + result += fragment; + if (!endsWithLineTerminator(fragment)) { + result += newline; + } + } + base = previousBase; + result += addIndent('}'); + break; + case Syntax.BreakStatement: + if (stmt.label) { + result = 'break ' + stmt.label.name + semicolon; + } else { + result = 'break' + semicolon; + } + break; + case Syntax.ContinueStatement: + if (stmt.label) { + result = 'continue ' + stmt.label.name + semicolon; + } else { + result = 'continue' + semicolon; + } + break; + case Syntax.DoWhileStatement: + result = join('do', maybeBlock(stmt.body)); + result += maybeBlockSuffix(stmt.body, result); + result += 'while' + space + '(' + generateExpression(stmt.test, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ')' + semicolon; + break; + case Syntax.CatchClause: + previousBase = base; + base += indent; + result = 'catch' + space + '(' + generateExpression(stmt.param, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ')'; + base = previousBase; + result += maybeBlock(stmt.body); + break; + case Syntax.DebuggerStatement: + result = 'debugger' + semicolon; + break; + case Syntax.EmptyStatement: + result = ';'; + break; + case Syntax.ExpressionStatement: + result = generateExpression(stmt.expression, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }); + if (result.charAt(0) === '{' || result.slice(0, 8) === 'function' && ' ('.indexOf(result.charAt(8)) >= 0) { + result = '(' + result + ')' + semicolon; + } else { + result += semicolon; + } + break; + case Syntax.VariableDeclarator: + if (stmt.init) { + result = stmt.id.name + space + '=' + space + generateExpression(stmt.init, { + precedence: Precedence.Assignment, + allowIn: allowIn, + allowCall: true + }); + } else { + result = stmt.id.name; + } + break; + case Syntax.VariableDeclaration: + result = stmt.kind; + if (stmt.declarations.length === 1 && stmt.declarations[0].init && stmt.declarations[0].init.type === Syntax.FunctionExpression) { + result += ' ' + generateStatement(stmt.declarations[0], { + allowIn: allowIn + }); + } else { + previousBase = base; + base += indent; + node = stmt.declarations[0]; + if (extra.comment && node.leadingComments) { + result += '\n' + addIndent(generateStatement(node, { + allowIn: allowIn + })); + } else { + result += ' ' + generateStatement(node, { + allowIn: allowIn + }); + } + for (i = 1, len = stmt.declarations.length; i < len; i += 1) { + node = stmt.declarations[i]; + if (extra.comment && node.leadingComments) { + result += ',' + newline + addIndent(generateStatement(node, { + allowIn: allowIn + })); + } else { + result += ',' + space + generateStatement(node, { + allowIn: allowIn + }); + } + } + base = previousBase; + } + result += semicolon; + break; + case Syntax.ThrowStatement: + result = join('throw', generateExpression(stmt.argument, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + })) + semicolon; + break; + case Syntax.TryStatement: + result = 'try' + maybeBlock(stmt.block); + result += maybeBlockSuffix(stmt.block, result); + for (i = 0, len = stmt.handlers.length; i < len; i += 1) { + result += generateStatement(stmt.handlers[i]); + if (stmt.finalizer || i + 1 !== len) { + result += maybeBlockSuffix(stmt.handlers[i].body, result); + } + } + if (stmt.finalizer) { + result += 'finally' + maybeBlock(stmt.finalizer); + } + break; + case Syntax.SwitchStatement: + previousBase = base; + base += indent; + result = 'switch' + space + '(' + generateExpression(stmt.discriminant, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ')' + space + '{' + newline; + base = previousBase; + if (stmt.cases) { + for (i = 0, len = stmt.cases.length; i < len; i += 1) { + fragment = addIndent(generateStatement(stmt.cases[i], { + semicolonOptional: i === len - 1 + })); + result += fragment; + if (!endsWithLineTerminator(fragment)) { + result += newline; + } + } + } + result += addIndent('}'); + break; + case Syntax.SwitchCase: + previousBase = base; + base += indent; + if (stmt.test) { + result = join('case', generateExpression(stmt.test, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + })) + ':'; + } else { + result = 'default:'; + } + i = 0; + len = stmt.consequent.length; + if (len && stmt.consequent[0].type === Syntax.BlockStatement) { + fragment = maybeBlock(stmt.consequent[0]); + result += fragment; + i = 1; + } + if (i !== len && !endsWithLineTerminator(result)) { + result += newline; + } + for (; i < len; i += 1) { + fragment = addIndent(generateStatement(stmt.consequent[i], { + semicolonOptional: i === len - 1 && semicolon === '' + })); + result += fragment; + if (i + 1 !== len && !endsWithLineTerminator(fragment)) { + result += newline; + } + } + base = previousBase; + break; + case Syntax.IfStatement: + previousBase = base; + base += indent; + if (stmt.alternate) { + if (stmt.alternate.type === Syntax.IfStatement) { + result = 'if' + space + '(' + generateExpression(stmt.test, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ')'; + base = previousBase; + result += maybeBlock(stmt.consequent); + result += maybeBlockSuffix(stmt.consequent, result); + result += 'else ' + generateStatement(stmt.alternate); + } else { + result = 'if' + space + '(' + generateExpression(stmt.test, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ')'; + base = previousBase; + result += maybeBlock(stmt.consequent); + result += maybeBlockSuffix(stmt.consequent, result); + result += 'else'; + result = join(result, maybeBlock(stmt.alternate, semicolon === '')); + } + } else { + result = 'if' + space + '(' + generateExpression(stmt.test, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ')'; + base = previousBase; + result += maybeBlock(stmt.consequent, semicolon === ''); + } + break; + case Syntax.ForStatement: + previousBase = base; + base += indent; + result = 'for' + space + '('; + if (stmt.init) { + if (stmt.init.type === Syntax.VariableDeclaration) { + result += generateStatement(stmt.init, { + allowIn: false + }); + } else { + result += generateExpression(stmt.init, { + precedence: Precedence.Sequence, + allowIn: false, + allowCall: true + }) + ';'; + } + } else { + result += ';'; + } + if (stmt.test) { + result += space + generateExpression(stmt.test, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ';'; + } else { + result += ';'; + } + if (stmt.update) { + result += space + generateExpression(stmt.update, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ')'; + } else { + result += ')'; + } + base = previousBase; + result += maybeBlock(stmt.body, semicolon === ''); + break; + case Syntax.ForInStatement: + result = 'for' + space + '('; + if (stmt.left.type === Syntax.VariableDeclaration) { + previousBase = base; + base += indent + indent; + result += stmt.left.kind + ' ' + generateStatement(stmt.left.declarations[0], { + allowIn: false + }); + base = previousBase; + } else { + previousBase = base; + base += indent; + result += generateExpression(stmt.left, { + precedence: Precedence.Call, + allowIn: true, + allowCall: true + }); + base = previousBase; + } + previousBase = base; + base += indent; + result = join(result, 'in'); + result = join(result, generateExpression(stmt.right, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + })) + ')'; + base = previousBase; + result += maybeBlock(stmt.body, semicolon === ''); + break; + case Syntax.LabeledStatement: + result = stmt.label.name + ':' + maybeBlock(stmt.body, semicolon === ''); + break; + case Syntax.Program: + result = ''; + for (i = 0, len = stmt.body.length; i < len; i += 1) { + fragment = addIndent(generateStatement(stmt.body[i], { + semicolonOptional: i === len - 1 + })); + result += fragment; + if (i + 1 < len && !endsWithLineTerminator(fragment)) { + result += newline; + } + } + break; + case Syntax.FunctionDeclaration: + result = 'function' + space; + if (stmt.id) { + result += (space === '' ? ' ' : '') + stmt.id.name; + } + result += generateFunctionBody(stmt); + break; + case Syntax.ReturnStatement: + if (stmt.argument) { + result = join('return', generateExpression(stmt.argument, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + })) + semicolon; + } else { + result = 'return' + semicolon; + } + break; + case Syntax.WhileStatement: + previousBase = base; + base += indent; + result = 'while' + space + '(' + generateExpression(stmt.test, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ')'; + base = previousBase; + result += maybeBlock(stmt.body, semicolon === ''); + break; + case Syntax.WithStatement: + previousBase = base; + base += indent; + result = 'with' + space + '(' + generateExpression(stmt.object, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }) + ')'; + base = previousBase; + result += maybeBlock(stmt.body, semicolon === ''); + break; + default: + break; + } + if (result === undefined) { + throw new Error('Unknown statement type: ' + stmt.type); + } + if (extra.comment) { + return addCommentsToStatement(stmt, result); + } + return result; + } + function generate(node, options) { + var defaultOptions = getDefaultOptions(); + if (typeof options !== 'undefined') { + if (typeof options.indent === 'string') { + defaultOptions.format.indent.style = options.indent; + } + if (typeof options.base === 'number') { + defaultOptions.format.indent.base = options.base; + } + options = updateDeeply(defaultOptions, options); + indent = options.format.indent.style; + if (typeof options.base === 'string') { + base = options.base; + } else { + base = stringRepeat(indent, options.format.indent.base); + } + } else { + options = defaultOptions; + indent = options.format.indent.style; + base = stringRepeat(indent, options.format.indent.base); + } + json = options.format.json; + renumber = options.format.renumber; + hexadecimal = json ? false : options.format.hexadecimal; + quotes = json ? 'double' : options.format.quotes; + escapeless = options.format.escapeless; + if (options.format.compact) { + newline = space = indent = base = ''; + } else { + newline = '\n'; + space = ' '; + } + parentheses = options.format.parentheses; + semicolons = options.format.semicolons; + parse = json ? null : options.parse; + extra = options; + switch (node.type) { + case Syntax.BlockStatement: + case Syntax.BreakStatement: + case Syntax.CatchClause: + case Syntax.ContinueStatement: + case Syntax.DoWhileStatement: + case Syntax.DebuggerStatement: + case Syntax.EmptyStatement: + case Syntax.ExpressionStatement: + case Syntax.ForStatement: + case Syntax.ForInStatement: + case Syntax.FunctionDeclaration: + case Syntax.IfStatement: + case Syntax.LabeledStatement: + case Syntax.Program: + case Syntax.ReturnStatement: + case Syntax.SwitchStatement: + case Syntax.SwitchCase: + case Syntax.ThrowStatement: + case Syntax.TryStatement: + case Syntax.VariableDeclaration: + case Syntax.VariableDeclarator: + case Syntax.WhileStatement: + case Syntax.WithStatement: + return generateStatement(node); + case Syntax.AssignmentExpression: + case Syntax.ArrayExpression: + case Syntax.BinaryExpression: + case Syntax.CallExpression: + case Syntax.ConditionalExpression: + case Syntax.FunctionExpression: + case Syntax.Identifier: + case Syntax.Literal: + case Syntax.LogicalExpression: + case Syntax.MemberExpression: + case Syntax.NewExpression: + case Syntax.ObjectExpression: + case Syntax.Property: + case Syntax.SequenceExpression: + case Syntax.ThisExpression: + case Syntax.UnaryExpression: + case Syntax.UpdateExpression: + return generateExpression(node, { + precedence: Precedence.Sequence, + allowIn: true, + allowCall: true + }); + default: + break; + } + throw new Error('Unknown node type: ' + node.type); + } + VisitorKeys = { + AssignmentExpression: [ + 'left', + 'right' + ], + ArrayExpression: [ + 'elements' + ], + BlockStatement: [ + 'body' + ], + BinaryExpression: [ + 'left', + 'right' + ], + BreakStatement: [ + 'label' + ], + CallExpression: [ + 'callee', + 'arguments' + ], + CatchClause: [ + 'param', + 'body' + ], + ConditionalExpression: [ + 'test', + 'consequent', + 'alternate' + ], + ContinueStatement: [ + 'label' + ], + DoWhileStatement: [ + 'body', + 'test' + ], + DebuggerStatement: [], + EmptyStatement: [], + ExpressionStatement: [ + 'expression' + ], + ForStatement: [ + 'init', + 'test', + 'update', + 'body' + ], + ForInStatement: [ + 'left', + 'right', + 'body' + ], + FunctionDeclaration: [ + 'id', + 'params', + 'body' + ], + FunctionExpression: [ + 'id', + 'params', + 'body' + ], + Identifier: [], + IfStatement: [ + 'test', + 'consequent', + 'alternate' + ], + Literal: [], + LabeledStatement: [ + 'label', + 'body' + ], + LogicalExpression: [ + 'left', + 'right' + ], + MemberExpression: [ + 'object', + 'property' + ], + NewExpression: [ + 'callee', + 'arguments' + ], + ObjectExpression: [ + 'properties' + ], + Program: [ + 'body' + ], + Property: [ + 'key', + 'value' + ], + ReturnStatement: [ + 'argument' + ], + SequenceExpression: [ + 'expressions' + ], + SwitchStatement: [ + 'descriminant', + 'cases' + ], + SwitchCase: [ + 'test', + 'consequent' + ], + ThisExpression: [], + ThrowStatement: [ + 'argument' + ], + TryStatement: [ + 'block', + 'handlers', + 'finalizer' + ], + UnaryExpression: [ + 'argument' + ], + UpdateExpression: [ + 'argument' + ], + VariableDeclaration: [ + 'declarations' + ], + VariableDeclarator: [ + 'id', + 'init' + ], + WhileStatement: [ + 'test', + 'body' + ], + WithStatement: [ + 'object', + 'body' + ], + PointerType: [ + 'base' + ], + StructType: [ + 'id', + 'fields' + ], + FieldDeclarator: [ + 'id', + 'decltype' + ], + ArrowType: [ + 'params', + 'return' + ], + TypeIdentifier: [], + TypeAliasDirective: [ + 'original', + 'alias' + ], + CastExpression: [ + 'as', + 'argument' + ] + }; + VisitorOption = { + Break: 1, + Skip: 2 + }; + function traverse(top, visitor) { + var worklist, leavelist, node, ret, current, current2, candidates, candidate; + worklist = [ + top + ]; + leavelist = []; + while (worklist.length) { + node = worklist.pop(); + if (node) { + if (visitor.enter) { + ret = visitor.enter(node); + } else { + ret = undefined; + } + if (ret === VisitorOption.Break) { + return; + } + worklist.push(null); + leavelist.push(node); + if (ret !== VisitorOption.Skip) { + candidates = VisitorKeys[node.type]; + current = candidates.length; + while ((current -= 1) >= 0) { + candidate = node[candidates[current]]; + if (candidate) { + if (isArray(candidate)) { + current2 = candidate.length; + while ((current2 -= 1) >= 0) { + if (candidate[current2]) { + worklist.push(candidate[current2]); + } + } + } else { + worklist.push(candidate); + } + } + } + } + } else { + node = leavelist.pop(); + if (visitor.leave) { + ret = visitor.leave(node); + } else { + ret = undefined; + } + if (ret === VisitorOption.Break) { + return; + } + } + } + } + function upperBound(array, func) { + var diff, len, i, current; + len = array.length; + i = 0; + while (len) { + diff = len >>> 1; + current = i + diff; + if (func(array[current])) { + len = diff; + } else { + i = current + 1; + len -= diff + 1; + } + } + return i; + } + function lowerBound(array, func) { + var diff, len, i, current; + len = array.length; + i = 0; + while (len) { + diff = len >>> 1; + current = i + diff; + if (func(array[current])) { + i = current + 1; + len -= diff + 1; + } else { + len = diff; + } + } + return i; + } + function extendCommentRange(comment, tokens) { + var target, token; + target = upperBound(tokens, function search(token) { + return token.range[0] > comment.range[0]; + }); + comment.extendedRange = [ + comment.range[0], + comment.range[1] + ]; + if (target !== tokens.length) { + comment.extendedRange[1] = tokens[target].range[0]; + } + target -= 1; + if (target >= 0) { + if (target < tokens.length) { + comment.extendedRange[0] = tokens[target].range[1]; + } else if (token.length) { + comment.extendedRange[1] = tokens[tokens.length - 1].range[0]; + } + } + return comment; + } + function attachComments(tree, providedComments, tokens) { + var comments = [], comment, len, i; + if (!tree.range) { + throw new Error('attachComments needs range information'); + } + if (!tokens.length) { + if (providedComments.length) { + for (i = 0, len = providedComments.length; i < len; i += 1) { + comment = deepCopy(providedComments[i]); + comment.extendedRange = [ + 0, + tree.range[0] + ]; + comments.push(comment); + } + tree.leadingComments = comments; + } + return tree; + } + for (i = 0, len = providedComments.length; i < len; i += 1) { + comments.push(extendCommentRange(deepCopy(providedComments[i]), tokens)); + } + traverse(tree, { + cursor: 0, + enter: function (node) { + var comment; + while (this.cursor < comments.length) { + comment = comments[this.cursor]; + if (comment.extendedRange[1] > node.range[0]) { + break; + } + if (comment.extendedRange[1] === node.range[0]) { + if (!node.leadingComments) { + node.leadingComments = []; + } + node.leadingComments.push(comment); + comments.splice(this.cursor, 1); + } else { + this.cursor += 1; + } + } + if (this.cursor === comments.length) { + return VisitorOption.Break; + } + if (comments[this.cursor].extendedRange[0] > node.range[1]) { + return VisitorOption.Skip; + } + } + }); + traverse(tree, { + cursor: 0, + leave: function (node) { + var comment; + while (this.cursor < comments.length) { + comment = comments[this.cursor]; + if (node.range[1] < comment.extendedRange[0]) { + break; + } + if (node.range[1] === comment.extendedRange[0]) { + if (!node.trailingComments) { + node.trailingComments = []; + } + node.trailingComments.push(comment); + comments.splice(this.cursor, 1); + } else { + this.cursor += 1; + } + } + if (this.cursor === comments.length) { + return VisitorOption.Break; + } + if (comments[this.cursor].extendedRange[0] > node.range[1]) { + return VisitorOption.Skip; + } + } + }); + return tree; + } + exports.version = '0.0.6-dev'; + exports.generate = generate; + exports.traverse = traverse; + exports.attachComments = attachComments; +}(typeof exports === 'undefined' ? escodegen = {} : exports)); +var verifierOptions = systemOptions.register(new OptionSet('Verifier Options')); +var verifierTraceLevel = verifierOptions.register(new Option('tv', 'tv', 'number', 0, 'Verifier Trace Level')); +var Type = function () { + function type() { + unexpected('Type is Abstract'); + } + type.prototype.equals = function (other) { + return this === other; + }; + type.prototype.merge = function (other) { + unexpected('Merging ' + this + ' with ' + other); + }; + type.cache = { + name: {}, + classInfo: [], + instanceInfo: [], + scriptInfo: [], + methodInfo: [] + }; + type.from = function from(x, domain) { + var traitsTypeCache = null; + if (x instanceof ClassInfo) { + traitsTypeCache = type.cache.classInfo; + } else if (x instanceof InstanceInfo) { + traitsTypeCache = type.cache.instanceInfo; + } else if (x instanceof ScriptInfo) { + traitsTypeCache = type.cache.scriptInfo; + } + if (traitsTypeCache) { + return traitsTypeCache[x.runtimeId] || (traitsTypeCache[x.runtimeId] = new TraitsType(x, domain)); + } + if (x instanceof ActivationInfo) { + return new TraitsType(x.methodInfo); + } else if (x instanceof Global) { + return new TraitsType(x.scriptInfo); + } else if (x instanceof Interface) { + return new TraitsType(x.classInfo, domain); + } else if (x instanceof MethodInfo) { + return new MethodType(x); + } else if (domain && x instanceof Class) { + return type.from(x.classInfo, domain); + } + return Type.Any; + }; + type.fromSimpleName = function (name, domain) { + return Type.fromName(Multiname.fromSimpleName(name), domain); + }; + type.fromName = function fromName(mn, domain) { + if (mn === undefined) { + return Type.Undefined; + } else { + var qn = Multiname.isQName(mn) ? Multiname.getFullQualifiedName(mn) : undefined; + if (qn) { + var ty = type.cache.name[qn]; + if (ty) { + return ty; + } + } + if (qn === Multiname.getPublicQualifiedName('void')) { + return Type.Void; + } + true; + ty = domain.findClassInfo(mn); + ty = ty ? type.from(ty, domain) : Type.Any; + if (mn.hasTypeParameter()) { + ty = new ParameterizedType(ty, type.fromName(mn.typeParameter, domain)); + } + return type.cache.name[qn] = ty; + } + }; + type.prototype.applyType = function (parameter) { + return new ParameterizedType(this, parameter); + }; + type.prototype.toString = function () { + return '[type]'; + }; + type.prototype.isNumeric = function () { + return this === Type.Int || this === Type.Uint || this === Type.Number; + }; + type.prototype.isString = function () { + return this === Type.String; + }; + type.prototype.isDirectlyReadable = function () { + return this === Type.Array; + }; + type.prototype.isIndexedReadable = function () { + return this.isParameterizedType(); + }; + type.prototype.isDirectlyWriteable = function () { + return this === Type.Array; + }; + type.prototype.isIndexedWriteable = function () { + return this.isParameterizedType(); + }; + type.prototype.isVector = function () { + return this.isParameterizedType(); + }; + type.prototype.isNotDirectlyIndexable = function () { + return this === Type.Any || this === Type.XML || this === Type.XMLList || this === Type.Dictionary; + }; + type.prototype.isParameterizedType = function () { + return this instanceof ParameterizedType; + }; + type.prototype.instanceType = function () { + return this; + }; + type.prototype.getTrait = function () { + return null; + }; + type.prototype.super = function () { + unexpected('Can\'t call super on ' + this); + }; + type.prototype.isSubtypeOf = function (other) { + if (this === other || this.equals(other)) { + return true; + } + return this.merge(other) === this; + }; + var typesInitialized = false; + type.initializeTypes = function (domain) { + if (typesInitialized) { + return; + } + type.Any = new AtomType('Any'); + type.Null = new AtomType('Null'); + type.Undefined = new AtomType('Undefined'); + type.Void = new AtomType('Void'); + type.Int = Type.fromSimpleName('int', domain).instanceType(); + type.Uint = Type.fromSimpleName('uint', domain).instanceType(); + type.Class = Type.fromSimpleName('Class', domain).instanceType(); + type.Array = Type.fromSimpleName('Array', domain).instanceType(); + type.Object = Type.fromSimpleName('Object', domain).instanceType(); + type.String = Type.fromSimpleName('String', domain).instanceType(); + type.Number = Type.fromSimpleName('Number', domain).instanceType(); + type.Boolean = Type.fromSimpleName('Boolean', domain).instanceType(); + type.Function = Type.fromSimpleName('Function', domain).instanceType(); + type.XML = Type.fromSimpleName('XML', domain).instanceType(); + type.XMLList = Type.fromSimpleName('XMLList', domain).instanceType(); + type.Dictionary = Type.fromSimpleName('flash.utils.Dictionary', domain).instanceType(); + typesInitialized = true; + }; + return type; + }(); +var AtomType = function () { + function atomType(name) { + this.name = name; + } + atomType.prototype = Object.create(Type.prototype); + atomType.prototype.toString = function () { + if (this === Type.Any) { + return '?'; + } else if (this === Type.Undefined) { + return '_'; + } else if (this === Type.Null) { + return 'X'; + } else if (this === Type.Void) { + return 'V'; + } + unexpected(); + }; + atomType.prototype.merge = function merge(other) { + if (other instanceof TraitsType) { + return Type.Any; + } + if (this === other) { + return this; + } + if (this === Type.Any || other === Type.Any) { + return Type.Any; + } + return Type.Any; + }; + return atomType; + }(); +var MethodType = function () { + function methodType(methodInfo) { + this.methodInfo = methodInfo; + } + methodType.prototype = Object.create(Type.prototype); + methodType.prototype.toString = function () { + return 'MT ' + this.methodInfo; + }; + return methodType; + }(); +var TraitsType = function () { + function traitsType(object, domain) { + true; + this.object = object; + this.traits = object.traits; + this.domain = domain; + if (this.object instanceof InstanceInfo) { + true; + } + } + traitsType.prototype = Object.create(Type.prototype); + function nameOf(x) { + if (x instanceof ScriptInfo) { + return 'SI'; + } else if (x instanceof ClassInfo) { + return 'CI:' + x.instanceInfo.name.name; + } else if (x instanceof InstanceInfo) { + return 'II:' + x.name.name; + } else if (x instanceof MethodInfo) { + return 'MI'; + } else if (x instanceof ActivationInfo) { + return 'AC'; + } + true; + } + function findTraitBySlotId(traits, slotId) { + for (var i = traits.length - 1; i >= 0; i--) { + if (traits[i].slotId === slotId) { + return traits[i]; + } + } + unexpected('Cannot find trait with slotId: ' + slotId + ' in ' + traits); + } + function findTraitByName(traits, mn, isSetter) { + var isGetter = !isSetter; + var trait; + if (!Multiname.isQName(mn)) { + if (mn instanceof MultinameType) { + return; + } + true; + var dy; + for (var i = 0, j = mn.namespaces.length; i < j; i++) { + var qn = mn.getQName(i); + if (mn.namespaces[i].isDynamic()) { + dy = qn; + } else { + if (trait = findTraitByName(traits, qn, isSetter)) { + return trait; + } + } + } + if (dy) { + return findTraitByName(traits, dy, isSetter); + } + } else { + var qn = Multiname.getQualifiedName(mn); + for (var i = 0, j = traits.length; i < j; i++) { + trait = traits[i]; + if (Multiname.getQualifiedName(trait.name) === qn) { + if (isSetter && trait.isGetter() || isGetter && trait.isSetter()) { + continue; + } + return trait; + } + } + } + } + traitsType.prototype.getTrait = function (mn, isSetter, followSuperType) { + if (mn instanceof MultinameType) { + return null; + } + if (mn.isAttribute()) { + return null; + } + if (followSuperType && (this.isInstanceInfo() || this.isClassInfo())) { + var that = this; + do { + var trait = that.getTrait(mn, isSetter, false); + if (!trait) { + that = that.super(); + } + } while (!trait && that); + return trait; + } else { + return findTraitByName(this.traits, mn, isSetter); + } + }; + traitsType.prototype.getTraitAt = function (i) { + if (this.object instanceof ScriptInfo || this.object instanceof MethodInfo) { + return findTraitBySlotId(this.traits, i); + } + }; + traitsType.prototype.toString = function () { + switch (this) { + case Type.Int: + return 'I'; + case Type.Uint: + return 'U'; + case Type.Array: + return 'A'; + case Type.Object: + return 'O'; + case Type.String: + return 'S'; + case Type.Number: + return 'N'; + case Type.Boolean: + return 'B'; + case Type.Function: + return 'F'; + } + return nameOf(this.object); + }; + traitsType.prototype.instanceType = function () { + true; + return this.instanceCache || (this.instanceCache = Type.from(this.object.instanceInfo, this.domain)); + }; + traitsType.prototype.classType = function () { + true; + return this.instanceCache || (this.instanceCache = Type.from(this.object.classInfo, this.domain)); + }; + traitsType.prototype.super = function () { + if (this.object instanceof ClassInfo) { + return Type.Class; + } + true; + if (this.object.superName) { + var result = Type.fromName(this.object.superName, this.domain).instanceType(); + true; + return result; + } + return null; + }; + traitsType.prototype.isScriptInfo = function () { + return this.object instanceof ScriptInfo; + }; + traitsType.prototype.isClassInfo = function () { + return this.object instanceof ClassInfo; + }; + traitsType.prototype.isInstanceInfo = function () { + return this.object instanceof InstanceInfo; + }; + traitsType.prototype.isInstanceOrClassInfo = function () { + return this.isInstanceInfo() || this.isClassInfo(); + }; + traitsType.prototype.equals = function (other) { + return this.traits === other.traits; + }; + traitsType.prototype.merge = function (other) { + if (other instanceof TraitsType) { + if (this.equals(other)) { + return this; + } + if (this.isNumeric() && other.isNumeric()) { + return Type.Number; + } + if (this.isInstanceInfo() && other.isInstanceInfo()) { + var path = []; + for (var curr = this; curr; curr = curr.super()) { + path.push(curr); + } + for (var curr = other; curr; curr = curr.super()) { + for (var i = 0; i < path.length; i++) { + if (path[i].equals(curr)) { + return curr; + } + } + } + return Type.Object; + } + } + return Type.Any; + }; + return traitsType; + }(); +var MultinameType = function () { + function multinameType(namespaces, name, flags) { + this.namespaces = namespaces; + this.name = name; + this.flags = flags; + } + multinameType.prototype = Object.create(Type.prototype); + multinameType.prototype.toString = function () { + return 'MN'; + }; + return multinameType; + }(); +var ParameterizedType = function () { + function parameterizedType(type, parameter) { + this.type = type; + this.parameter = parameter; + } + parameterizedType.prototype = Object.create(Type.prototype); + parameterizedType.prototype.toString = function () { + return this.type + '<' + this.parameter + '>'; + }; + parameterizedType.prototype.instanceType = function () { + true; + return new ParameterizedType(this.type.instanceType(), this.parameter.instanceType()); + }; + parameterizedType.prototype.equals = function (other) { + if (other instanceof ParameterizedType) { + return this.type.equals(other.type) && this.parameter.equals(other.parameter); + } + return false; + }; + parameterizedType.prototype.merge = function (other) { + if (other instanceof TraitsType) { + if (this.equals(other)) { + return this; + } + } + return Type.Any; + }; + return parameterizedType; + }(); +var TypeInformation = function () { + function typeInformation() { + } + typeInformation.prototype.toString = function () { + return toKeyValueArray(this).map(function (x) { + return x[0] + ': ' + x[1]; + }).join(' | '); + }; + return typeInformation; + }(); +var Verifier = function () { + function VerifierError(message) { + this.name = 'VerifierError'; + this.message = message || ''; + } + var State = function () { + var id = 0; + function state() { + this.id = id += 1; + this.stack = []; + this.scope = []; + this.local = []; + } + state.prototype.clone = function clone() { + var s = new State(); + s.originalId = this.id; + s.stack = this.stack.slice(0); + s.scope = this.scope.slice(0); + s.local = this.local.slice(0); + return s; + }; + state.prototype.trace = function trace(writer) { + writer.writeLn(this.toString()); + }; + state.prototype.toString = function () { + return '<' + this.id + (this.originalId ? ':' + this.originalId : '') + ', L[' + this.local.join(', ') + ']' + ', S[' + this.stack.join(', ') + ']' + ', $[' + this.scope.join(', ') + ']>'; + }; + state.prototype.equals = function (other) { + return arrayEquals(this.stack, other.stack) && arrayEquals(this.scope, other.scope) && arrayEquals(this.local, other.local); + }; + function arrayEquals(a, b) { + if (a.length != b.length) { + return false; + } + for (var i = a.length - 1; i >= 0; i--) { + if (!a[i].equals(b[i])) { + return false; + } + } + return true; + } + state.prototype.isSubset = function (other) { + return arraySubset(this.stack, other.stack) && arraySubset(this.scope, other.scope) && arraySubset(this.local, other.local); + }; + function arraySubset(a, b) { + if (a.length != b.length) { + return false; + } + for (var i = a.length - 1; i >= 0; i--) { + if (a[i] === b[i] || a[i].equals(b[i])) { + continue; + } + if (a[i].merge(b[i]) !== a[i]) { + return false; + } + } + return true; + } + state.prototype.merge = function (other) { + mergeArrays(this.local, other.local); + mergeArrays(this.stack, other.stack); + mergeArrays(this.scope, other.scope); + }; + function mergeArrays(a, b) { + true; + for (var i = a.length - 1; i >= 0; i--) { + true; + if (a[i] === b[i]) { + continue; + } + a[i] = a[i].merge(b[i]); + } + } + return state; + }(); + var Verification = function () { + function verification(methodInfo, domain, savedScope) { + this.savedScope = savedScope; + this.methodInfo = methodInfo; + this.domain = domain; + this.writer = new IndentingWriter(); + this.returnType = Type.Undefined; + } + verification.prototype.verify = function verify() { + var mi = this.methodInfo; + var writer = verifierTraceLevel.value ? this.writer : null; + var blocks = mi.analysis.blocks; + blocks.forEach(function (x) { + x.entryState = x.exitState = null; + }); + if (writer) { + this.methodInfo.trace(writer); + } + var entryState = new State(); + true; + this.thisType = mi.holder ? Type.from(mi.holder, this.domain) : Type.Any; + entryState.local.push(this.thisType); + for (var i = 0; i < mi.parameters.length; i++) { + entryState.local.push(Type.fromName(mi.parameters[i].type, this.domain).instanceType()); + } + var remainingLocals = mi.localCount - mi.parameters.length - 1; + if (mi.needsRest() || mi.needsArguments()) { + entryState.local.push(Type.Array); + remainingLocals -= 1; + } + for (var i = 0; i < remainingLocals; i++) { + entryState.local.push(Type.Undefined); + } + true; + if (writer) { + entryState.trace(writer); + } + for (var bi = 0, len = blocks.length; bi < len; bi++) { + blocks[bi].bdo = bi; + } + var worklist = new Shumway.SortedList(function compare(blockA, blockB) { + return blockA.bdo - blockB.bdo; + }); + blocks[0].entryState = entryState; + worklist.push(blocks[0]); + while (!worklist.isEmpty()) { + var block = worklist.pop(); + var exitState = block.exitState = block.entryState.clone(); + this.verifyBlock(block, exitState); + block.succs.forEach(function (successor) { + if (worklist.contains(successor)) { + if (writer) { + writer.writeLn('Forward Merged Block: ' + successor.bid + ' ' + exitState.toString() + ' with ' + successor.entryState.toString()); + } + successor.entryState.merge(exitState); + if (writer) { + writer.writeLn('Merged State: ' + successor.entryState); + } + return; + } + if (successor.entryState) { + if (!successor.entryState.isSubset(exitState)) { + if (writer) { + writer.writeLn('Backward Merged Block: ' + block.bid + ' with ' + successor.bid + ' ' + exitState.toString() + ' with ' + successor.entryState.toString()); + } + successor.entryState.merge(exitState); + worklist.push(successor); + if (writer) { + writer.writeLn('Merged State: ' + successor.entryState); + } + } + return; + } + successor.entryState = exitState.clone(); + worklist.push(successor); + if (writer) { + writer.writeLn('Added Block: ' + successor.bid + ' to worklist: ' + successor.entryState.toString()); + } + }); + } + if (writer) { + writer.writeLn('Inferred return type: ' + this.returnType); + } + this.methodInfo.inferredReturnType = this.returnType; + }; + verification.prototype.verifyBlock = function verifyBlock(block, state) { + var savedScope = this.savedScope; + var globalScope = savedScope[0]; + var local = state.local; + var stack = state.stack; + var scope = state.scope; + var writer = verifierTraceLevel.value ? this.writer : null; + var bytecodes = this.methodInfo.analysis.bytecodes; + var domain = this.domain; + var multinames = this.methodInfo.abc.constantPool.multinames; + var mi = this.methodInfo; + var bc, obj, fn, mn, l, r, val, type, returnType; + if (writer) { + writer.enter('verifyBlock: ' + block.bid + ', range: [' + block.position + ', ' + block.end.position + '], entryState: ' + state.toString() + ' {'); + } + function construct(obj) { + if (obj instanceof TraitsType || obj instanceof ParameterizedType) { + if (obj === Type.Function || obj === Type.Class || obj === Type.Object) { + return Type.Object; + } + return obj.instanceType(); + } else { + return Type.Any; + } + } + function ti() { + return bc.ti || (bc.ti = new TypeInformation()); + } + function push(x) { + true; + ti().type = x; + stack.push(x); + } + function pop() { + return stack.pop(); + } + function findProperty(mn, strict) { + if (mn instanceof MultinameType) { + if (mn.name === 'Array') { + debugger; + } + return Type.Any; + } + for (var i = scope.length - 1; i >= -savedScope.length; i--) { + var s = i >= 0 ? scope[i] : savedScope[savedScope.length + i]; + if (s instanceof TraitsType) { + var trait = s.getTrait(mn, false, true); + if (trait) { + ti().scopeDepth = scope.length - i - 1; + if (s.isClassInfo() || s.isScriptInfo()) { + ti().object = LazyInitializer.create(s.object); + } + return s; + } + } else { + if (mn.name === 'Array') { + debugger; + } + return Type.Any; + } + } + var resolved = domain.findDefiningScript(mn, false); + if (resolved) { + ti().object = LazyInitializer.create(resolved.script); + return Type.from(resolved.script, domain); + } + if (mn.name === 'Array') { + debugger; + } + return Type.Any; + } + function popMultiname() { + var mn = multinames[bc.index]; + if (mn.isRuntime()) { + var namespaces = mn.namespaces; + var name = mn.name; + if (mn.isRuntimeName()) { + name = pop(); + } + if (mn.isRuntimeNamespace()) { + namespaces = [ + pop() + ]; + } + return new MultinameType(namespaces, name, mn.flags); + } + return mn; + } + function accessSlot(obj) { + if (obj instanceof TraitsType) { + var trait = obj.getTraitAt(bc.index); + writer && writer.debugLn('accessSlot() -> ' + trait); + if (trait) { + ti().trait = trait; + if (trait.isSlot()) { + return Type.fromName(trait.typeName, domain).instanceType(); + } else if (trait.isClass()) { + return Type.from(trait.classInfo, domain); + } + } + } + return Type.Any; + } + function isNumericMultiname(mn) { + return mn instanceof Multiname && Multiname.isNumeric(mn) || mn instanceof MultinameType && (mn.name instanceof TraitsType && mn.name.isNumeric()); + } + function getProperty(obj, mn) { + if (obj instanceof TraitsType || obj instanceof ParameterizedType) { + var trait = obj.getTrait(mn, false, true); + writer && writer.debugLn('getProperty(' + mn + ') -> ' + trait); + if (trait) { + ti().trait = trait; + if (trait.isSlot() || trait.isConst()) { + return Type.fromName(trait.typeName, domain).instanceType(); + } else if (trait.isGetter()) { + return Type.fromName(trait.methodInfo.returnType, domain).instanceType(); + } else if (trait.isClass()) { + return Type.from(trait.classInfo, domain); + } else if (trait.isMethod()) { + return Type.from(trait.methodInfo, domain); + } + } else if (obj.isDirectlyReadable() && mn instanceof Multiname) { + ti().propertyQName = Multiname.getPublicQualifiedName(mn.name); + } + if (isNumericMultiname(mn)) { + if (obj.isIndexedReadable()) { + ti().isIndexedReadable = true; + if (obj.isVector()) { + return obj.parameter; + } + } else if (obj.isDirectlyReadable()) { + ti().isDirectlyReadable = true; + } + } + } + return Type.Any; + } + function setProperty(obj, mn, value) { + if (obj instanceof TraitsType || obj instanceof ParameterizedType) { + var trait = obj.getTrait(mn, true, true); + writer && writer.debugLn('setProperty(' + mn + ') -> ' + trait); + if (trait) { + ti().trait = trait; + } else if (obj.isDirectlyWriteable() && mn instanceof Multiname) { + ti().propertyQName = Multiname.getPublicQualifiedName(mn.name); + } + if (isNumericMultiname(mn)) { + if (obj.isDirectlyWriteable()) { + ti().isDirectlyWriteable = true; + } else if (obj.isVector()) { + ti().isIndexedWriteable = true; + } + } + } + } + for (var bci = block.position, end = block.end.position; bci <= end; bci++) { + bc = bytecodes[bci]; + var op = bc.op; + if (writer && verifierTraceLevel.value > 1) { + writer.writeLn(('stateBefore: ' + state.toString() + ' $$[' + savedScope.join(', ') + ']').padRight(' ', 100) + ' : ' + bci + ', ' + bc.toString(mi.abc)); + } + switch (op) { + case 1: + break; + case 3: + pop(); + break; + case 4: + mn = popMultiname(); + obj = pop(); + true; + ti().baseClass = LazyInitializer.create(this.thisType.super().classType().object); + push(getProperty(obj.super(), mn)); + break; + case 5: + val = pop(); + mn = popMultiname(); + obj = pop(); + true; + ti().baseClass = LazyInitializer.create(this.thisType.super().classType().object); + setProperty(obj.super(), mn, val); + break; + case 6: + notImplemented(bc); + break; + case 7: + notImplemented(bc); + break; + case 8: + state.local[bc.index] = Type.Undefined; + break; + case 10: + notImplemented(bc); + break; + case 11: + notImplemented(bc); + break; + case 12: + case 24: + case 13: + case 23: + case 14: + case 22: + case 15: + case 21: + case 19: + case 20: + case 25: + case 26: + pop(); + pop(); + break; + case 16: + break; + case 17: + case 18: + pop(); + break; + case 27: + pop(Type.Int); + break; + case 29: + scope.pop(); + break; + case 30: + case 35: + pop(Type.Int); + pop(); + push(Type.Any); + break; + case 31: + push(Type.Boolean); + break; + case 50: + push(Type.Boolean); + break; + case 32: + push(Type.Null); + break; + case 33: + push(Type.Undefined); + break; + case 34: + notImplemented(bc); + break; + case 36: + push(Type.Int); + break; + case 37: + push(Type.Int); + break; + case 44: + push(Type.String); + break; + case 45: + push(Type.Int); + break; + case 46: + push(Type.Uint); + break; + case 47: + push(Type.Number); + break; + case 38: + push(Type.Boolean); + break; + case 39: + push(Type.Boolean); + break; + case 40: + push(Type.Number); + break; + case 41: + pop(); + break; + case 42: + val = pop(); + push(val); + push(val); + break; + case 43: + l = pop(); + r = pop(); + push(l); + push(r); + break; + case 28: + pop(); + scope.push(Type.Any); + break; + case 48: + scope.push(pop()); + break; + case 49: + notImplemented(bc); + break; + case 53: + case 54: + case 55: + push(Type.Int); + break; + case 56: + case 57: + push(Type.Number); + break; + case 58: + case 59: + case 60: + pop(Type.Int); + break; + case 61: + case 62: + pop(Type.Number); + break; + case 64: + push(Type.Function); + break; + case 65: + stack.popMany(bc.argCount); + obj = pop(); + fn = pop(); + push(Type.Any); + break; + case 67: + throw new VerifierError('callmethod'); + case 68: + notImplemented(bc); + break; + case 69: + case 78: + case 79: + case 70: + case 76: + stack.popMany(bc.argCount); + mn = popMultiname(); + obj = pop(); + if (op === OP_callsuper || op === OP_callsupervoid) { + obj = this.thisType.super(); + ti().baseClass = LazyInitializer.create(this.thisType.super().classType().object); + } + type = getProperty(obj, mn); + if (op === OP_callpropvoid || op === OP_callsupervoid) { + break; + } + if (type instanceof MethodType) { + returnType = Type.fromName(type.methodInfo.returnType, domain).instanceType(); + } else if (type instanceof TraitsType && type.isClassInfo()) { + returnType = type.instanceType(); + } else { + returnType = Type.Any; + } + push(returnType); + break; + case 71: + this.returnType.merge(Type.Undefined); + break; + case 72: + type = pop(); + if (mi.returnType) { + var coerceType = Type.fromName(mi.returnType, this.domain).instanceType(); + if (coerceType.isSubtypeOf(type)) { + ti().noCoercionNeeded = true; + } + } + break; + case 73: + stack.popMany(bc.argCount); + stack.pop(); + if (this.thisType.isInstanceInfo() && this.thisType.super() === Type.Object) { + ti().noCallSuperNeeded = true; + } else { + ti().baseClass = LazyInitializer.create(this.thisType.super().classType().object); + } + break; + case 66: + stack.popMany(bc.argCount); + push(construct(pop())); + break; + case 74: + stack.popMany(bc.argCount); + mn = popMultiname(); + push(construct(getProperty(stack.pop(), mn))); + break; + case 75: + notImplemented(bc); + break; + case 77: + notImplemented(bc); + break; + case 80: + case 81: + case 82: + break; + case 83: + true; + val = pop(); + obj = pop(); + if (obj === Type.Any) { + push(Type.Any); + } else { + push(obj.applyType(val)); + } + break; + case 84: + notImplemented(bc); + break; + case 85: + stack.popMany(bc.argCount * 2); + push(Type.Object); + break; + case 86: + stack.popMany(bc.argCount); + push(Type.Array); + break; + case 87: + push(Type.from(new ActivationInfo(this.methodInfo))); + break; + case 88: + push(Type.Any); + break; + case 89: + popMultiname(); + pop(); + push(Type.XMLList); + break; + case 90: + push(Type.Any); + break; + case 93: + push(findProperty(popMultiname(), true)); + break; + case 94: + push(findProperty(popMultiname(), false)); + break; + case 95: + notImplemented(bc); + break; + case 96: + mn = popMultiname(); + push(getProperty(findProperty(mn, true), mn)); + break; + case 104: + case 97: + val = pop(); + mn = popMultiname(); + obj = pop(); + setProperty(obj, mn, val, bc); + break; + case 98: + push(local[bc.index]); + break; + case 99: + local[bc.index] = pop(); + break; + case 100: + push(globalScope); + ti().object = LazyInitializer.create(globalScope.object); + break; + case 101: + push(scope[bc.index]); + break; + case 102: + mn = popMultiname(); + obj = pop(); + push(getProperty(obj, mn)); + break; + case 103: + notImplemented(bc); + break; + case 105: + notImplemented(bc); + break; + case 106: + popMultiname(); + pop(); + push(Type.Boolean); + break; + case 107: + notImplemented(bc); + break; + case 108: + push(accessSlot(pop())); + break; + case 109: + val = pop(); + obj = pop(); + accessSlot(obj); + break; + case 110: + notImplemented(bc); + break; + case 111: + notImplemented(bc); + break; + case 112: + pop(); + push(Type.String); + break; + case 113: + pop(); + push(Type.String); + break; + case 114: + pop(); + push(Type.String); + break; + case 131: + case 115: + pop(); + push(Type.Int); + break; + case 136: + case 116: + pop(); + push(Type.Uint); + break; + case 132: + case 117: + pop(); + push(Type.Number); + break; + case 129: + case 118: + pop(); + push(Type.Boolean); + break; + case 119: + notImplemented(bc); + break; + case 120: + break; + case 121: + pop(); + push(Type.Number); + break; + case 122: + notImplemented(bc); + break; + case 123: + notImplemented(bc); + break; + case 128: + type = pop(); + var coerceType = Type.fromName(multinames[bc.index], this.domain).instanceType(); + if (coerceType.isSubtypeOf(type)) { + ti().noCoercionNeeded = true; + } + push(coerceType); + break; + case 130: + break; + case 133: + pop(); + push(Type.String); + break; + case 134: + notImplemented(bc); + break; + case 135: + type = pop(); + pop(); + if (type instanceof TraitsType) { + push(type.instanceType()); + } else { + push(Type.Any); + } + break; + case 137: + notImplemented(bc); + break; + case 144: + case 145: + case 147: + pop(); + push(Type.Number); + break; + case 146: + case 148: + local[bc.index] = Type.Number; + break; + case 149: + pop(); + push(Type.String); + break; + case 150: + pop(); + push(Type.Boolean); + break; + case 160: + r = pop(); + l = pop(); + if (l.isNumeric() && r.isNumeric()) { + push(Type.Number); + } else if (l === Type.String || r === Type.String) { + push(Type.String); + } else { + push(Type.Any); + } + break; + case 161: + case 162: + case 163: + case 164: + pop(); + pop(); + push(Type.Number); + break; + case 168: + case 169: + case 170: + case 165: + case 166: + case 167: + pop(); + pop(); + push(Type.Int); + break; + case 151: + pop(); + push(Type.Int); + break; + case 171: + case 172: + case 173: + case 174: + case 175: + case 176: + case 177: + case 180: + pop(); + pop(); + push(Type.Boolean); + break; + case 178: + pop(); + push(Type.Boolean); + break; + case 179: + pop(); + pop(); + push(Type.Boolean); + break; + case 194: + case 195: + local[bc.index] = Type.Int; + break; + case 193: + case 192: + case 196: + pop(); + push(Type.Int); + break; + case 197: + case 198: + case 199: + pop(); + pop(); + push(Type.Int); + break; + case 208: + case 209: + case 210: + case 211: + push(local[op - OP_getlocal0]); + break; + case 212: + case 213: + case 214: + case 215: + local[op - OP_setlocal0] = pop(); + break; + case 239: + break; + case 240: + break; + case 241: + break; + case 242: + break; + case 243: + break; + default: + console.info('Not Implemented: ' + bc); + } + if (writer) { + if (bc.ti) { + writer.debugLn('> TI: ' + bc.ti); + } + } + } + if (writer) { + writer.leave('}'); + writer.writeLn('verifiedBlock: ' + block.bid + ', range: [' + block.position + ', ' + block.end.position + '], exitState: ' + state.toString()); + } + }; + return verification; + }(); + function verifier() { + this.writer = new IndentingWriter(); + } + verifier.prototype.verifyMethod = function (methodInfo, scope) { + try { + var domain = methodInfo.abc.applicationDomain; + var scopeObjects = scope.getScopeObjects(); + if (!scopeObjects[scopeObjects.length - 1]) { + if (methodInfo.holder instanceof InstanceInfo) { + scopeObjects[scopeObjects.length - 1] = methodInfo.holder.classInfo; + } else if (methodInfo.holder instanceof ClassInfo) { + scopeObjects[scopeObjects.length - 1] = methodInfo.holder; + } + } + var savedScope = scopeObjects.map(function (object) { + if (object instanceof MethodInfo) { + return Type.from(new ActivationInfo(object)); + } + return Type.from(object, domain); + }); + new Verification(methodInfo, methodInfo.abc.applicationDomain, savedScope).verify(); + methodInfo.verified = true; + Counter.count('Verifier: Methods'); + } catch (e) { + if (e instanceof VerifierError) { + return; + } + throw e; + } + }; + return verifier; + }(); +(function (exports) { + var debug = false; + var IRDefinition = { + Control: { + Region: { + predecessors: { + array: true, + expand: 'control' + }, + Start: { + _constructorText: 'this.control = this;', + scope: { + dynamic: true + }, + domain: { + dynamic: true + } + } + }, + End: { + control: { + assert: 'isControlOrNull' + }, + Stop: { + store: { + assert: 'isStore' + }, + argument: { + assert: '' + } + }, + If: { + predicate: { + assert: '' + } + }, + Switch: { + determinant: { + assert: '' + } + }, + Jump: {} + } + }, + Value: { + StoreDependent: { + control: { + assert: 'isControlOrNull', + nullable: true + }, + store: { + assert: 'isStoreOrNull', + nullable: true + }, + loads: { + dynamic: true, + nullable: true, + array: true + }, + Call: { + callee: { + assert: '' + }, + object: { + assert: 'isValueOrNull', + nullable: true + }, + args: { + assert: 'isArray', + array: true + }, + flags: { + internal: true, + assert: 'isNumber' + } + }, + CallProperty: { + object: { + assert: '' + }, + name: { + assert: '' + }, + args: { + assert: 'isArray', + array: true + }, + flags: { + internal: true, + assert: 'isNumber' + }, + ASCallProperty: { + isLex: { + assert: '', + internal: true + } + }, + ASCallSuper: { + scope: { + assert: '' + } + } + }, + New: { + callee: { + assert: '' + }, + args: { + assert: '', + array: true + }, + ASNew: {} + }, + GetProperty: { + object: { + assert: '' + }, + name: { + assert: '' + }, + ASGetProperty: { + flags: { + internal: true, + assert: 'isNumber' + } + }, + ASGetDescendants: {}, + ASHasProperty: {}, + ASGetSlot: {}, + ASGetSuper: { + scope: { + assert: '' + } + } + }, + SetProperty: { + object: { + assert: '' + }, + name: { + assert: '' + }, + value: { + assert: '' + }, + ASSetProperty: { + flags: { + internal: true + } + }, + ASSetSlot: {}, + ASSetSuper: { + scope: { + assert: '' + } + } + }, + DeleteProperty: { + object: { + assert: '' + }, + name: { + assert: '' + }, + ASDeleteProperty: {} + }, + ASFindProperty: { + scope: { + assert: '' + }, + name: { + assert: '' + }, + domain: { + assert: '' + }, + strict: { + internal: true + } + } + }, + Store: {}, + Phi: { + control: { + assert: 'isControl', + nullable: true + }, + args: { + array: true, + expand: 'value' + } + }, + Variable: { + name: { + internal: true + } + }, + Copy: { + argument: {} + }, + Move: { + to: {}, + from: {} + }, + Projection: { + argument: {}, + type: { + internal: true + }, + selector: { + internal: true, + optional: true + } + }, + Latch: { + control: { + assert: 'isControlOrNull', + nullable: true + }, + condition: {}, + left: {}, + right: {} + }, + Binary: { + operator: { + internal: true + }, + left: {}, + right: {} + }, + Unary: { + operator: { + internal: true + }, + argument: {} + }, + Constant: { + value: { + internal: true + } + }, + GlobalProperty: { + name: { + internal: true + } + }, + This: { + control: { + assert: 'isControl' + } + }, + Throw: { + control: { + assert: 'isControl' + }, + argument: {} + }, + Arguments: { + control: { + assert: 'isControl' + } + }, + Parameter: { + control: { + assert: 'isControl' + }, + index: { + internal: true + }, + name: { + internal: true + } + }, + NewArray: { + control: { + assert: 'isControl' + }, + elements: { + array: true + } + }, + NewObject: { + control: { + assert: 'isControl' + }, + properties: { + array: true + } + }, + KeyValuePair: { + key: {}, + value: {} + }, + ASScope: { + parent: {}, + object: {}, + isWith: { + internal: true + } + }, + ASGlobal: { + control: { + assert: 'isControlOrNull', + nullable: true + }, + scope: { + assert: 'isScope' + } + }, + ASNewActivation: { + methodInfo: { + internal: true + } + }, + ASMultiname: { + namespaces: {}, + name: {}, + flags: { + internal: true + } + } + } + }; + function IRGenerator(root) { + var str = ''; + function out(s) { + str += s + '\n'; + } + var writer = new IndentingWriter(false, out); + function makeProperties(node) { + var result = []; + for (var k in node) { + if (isProperty(k)) { + node[k].name = k; + result.push(node[k]); + } + } + return result; + } + function isProperty(v) { + if (v[0] === '_') { + return false; + } + return v[0].toLowerCase() === v[0]; + } + function generate(node, path) { + path = path.concat([ + node + ]); + writer.enter('var ' + node._name + ' = (function () {'); + var constructorName = node._name[0].toLowerCase() + node._name.slice(1) + 'Node'; + if (constructorName.substring(0, 2) === 'aS') { + constructorName = 'as' + constructorName.substring(2); + } + var prototypeName = constructorName + '.prototype'; + var properties = path.reduce(function (a, v) { + return a.concat(makeProperties(v)); + }, []); + var parameters = properties.filter(function (property) { + return !property.dynamic; + }); + var optionalParameters = parameters.filter(function (property) { + return property.optional; + }); + var parameterString = parameters.map(function (property) { + if (property.expand) { + return property.expand; + } + return property.name; + }).join(', '); + writer.enter('function ' + constructorName + '(' + parameterString + ') {'); + if (true) { + properties.forEach(function (property) { + if (property.assert === '') { + writer.writeLn('release || assert (!(' + property.name + ' == undefined), "' + property.name + '");'); + } else if (property.assert) { + writer.writeLn('release || assert (' + property.assert + '(' + property.name + '), "' + property.name + '");'); + } + }); + writer.writeLn('release || assert (arguments.length >= ' + (parameters.length - optionalParameters.length) + ', "' + node._name + ' not enough args.");'); + } + if (node._constructorText) { + writer.writeLn(node._constructorText); + } + properties.forEach(function (property) { + if (property.expand) { + writer.writeLn('this.' + property.name + ' = ' + property.expand + ' ? [' + property.expand + '] : [];'); + } else if (property.dynamic) { + writer.writeLn('this.' + property.name + ' = undefined;'); + } else { + writer.writeLn('this.' + property.name + ' = ' + property.name + ';'); + } + }); + writer.writeLn('this.id = nextID[nextID.length - 1] += 1;'); + writer.leave('}'); + if (path.length > 1) { + writer.writeLn(prototypeName + ' = ' + 'extend(' + path[path.length - 2]._name + ', "' + node._name + '");'); + } + writer.writeLn(prototypeName + '.nodeName = "' + node._name + '";'); + writer.enter(prototypeName + '.visitInputs = function (visitor) {'); + properties.forEach(function (property) { + if (property.internal) { + return; + } + var str = ''; + if (property.nullable) { + str += 'this.' + property.name + ' && '; + } + if (property.array) { + str += 'visitArrayInputs(this.' + property.name + ', visitor);'; + } else { + str += 'visitor(this.' + property.name + ');'; + } + writer.writeLn(str); + }); + writer.leave('};'); + writer.writeLn('return ' + constructorName + ';'); + writer.leave('})();'); + writer.writeLn(''); + for (var name in node) { + if (name[0] === '_' || isProperty(name)) { + continue; + } + var child = node[name]; + child._name = name; + generate(child, path); + } + } + IRDefinition._name = 'Node'; + generate(IRDefinition, []); + return str; + } + var nextID = []; + var Node = function () { + function nodeNode() { + true; + this.id = nextID[nextID.length - 1] += 1; + } + nodeNode.prototype.nodeName = 'Node'; + nodeNode.prototype.visitInputs = function (visitor) { + }; + return nodeNode; + }(); + var Control = function () { + function controlNode() { + true; + this.id = nextID[nextID.length - 1] += 1; + } + controlNode.prototype = extend(Node, 'Control'); + controlNode.prototype.nodeName = 'Control'; + controlNode.prototype.visitInputs = function (visitor) { + }; + return controlNode; + }(); + var Region = function () { + function regionNode(control) { + true; + this.predecessors = control ? [ + control + ] : []; + this.id = nextID[nextID.length - 1] += 1; + } + regionNode.prototype = extend(Control, 'Region'); + regionNode.prototype.nodeName = 'Region'; + regionNode.prototype.visitInputs = function (visitor) { + visitArrayInputs(this.predecessors, visitor); + }; + return regionNode; + }(); + var Start = function () { + function startNode(control) { + true; + this.control = this; + this.predecessors = control ? [ + control + ] : []; + this.scope = undefined; + this.domain = undefined; + this.id = nextID[nextID.length - 1] += 1; + } + startNode.prototype = extend(Region, 'Start'); + startNode.prototype.nodeName = 'Start'; + startNode.prototype.visitInputs = function (visitor) { + visitArrayInputs(this.predecessors, visitor); + visitor(this.scope); + visitor(this.domain); + }; + return startNode; + }(); + var End = function () { + function endNode(control) { + true; + true; + this.control = control; + this.id = nextID[nextID.length - 1] += 1; + } + endNode.prototype = extend(Control, 'End'); + endNode.prototype.nodeName = 'End'; + endNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + }; + return endNode; + }(); + var Stop = function () { + function stopNode(control, store, argument) { + true; + true; + true; + true; + this.control = control; + this.store = store; + this.argument = argument; + this.id = nextID[nextID.length - 1] += 1; + } + stopNode.prototype = extend(End, 'Stop'); + stopNode.prototype.nodeName = 'Stop'; + stopNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + visitor(this.store); + visitor(this.argument); + }; + return stopNode; + }(); + var If = function () { + function ifNode(control, predicate) { + true; + true; + true; + this.control = control; + this.predicate = predicate; + this.id = nextID[nextID.length - 1] += 1; + } + ifNode.prototype = extend(End, 'If'); + ifNode.prototype.nodeName = 'If'; + ifNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + visitor(this.predicate); + }; + return ifNode; + }(); + var Switch = function () { + function switchNode(control, determinant) { + true; + true; + true; + this.control = control; + this.determinant = determinant; + this.id = nextID[nextID.length - 1] += 1; + } + switchNode.prototype = extend(End, 'Switch'); + switchNode.prototype.nodeName = 'Switch'; + switchNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + visitor(this.determinant); + }; + return switchNode; + }(); + var Jump = function () { + function jumpNode(control) { + true; + true; + this.control = control; + this.id = nextID[nextID.length - 1] += 1; + } + jumpNode.prototype = extend(End, 'Jump'); + jumpNode.prototype.nodeName = 'Jump'; + jumpNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + }; + return jumpNode; + }(); + var Value = function () { + function valueNode() { + true; + this.id = nextID[nextID.length - 1] += 1; + } + valueNode.prototype = extend(Node, 'Value'); + valueNode.prototype.nodeName = 'Value'; + valueNode.prototype.visitInputs = function (visitor) { + }; + return valueNode; + }(); + var StoreDependent = function () { + function storeDependentNode(control, store) { + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.id = nextID[nextID.length - 1] += 1; + } + storeDependentNode.prototype = extend(Value, 'StoreDependent'); + storeDependentNode.prototype.nodeName = 'StoreDependent'; + storeDependentNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + }; + return storeDependentNode; + }(); + var Call = function () { + function callNode(control, store, callee, object, args, flags) { + true; + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.callee = callee; + this.object = object; + this.args = args; + this.flags = flags; + this.id = nextID[nextID.length - 1] += 1; + } + callNode.prototype = extend(StoreDependent, 'Call'); + callNode.prototype.nodeName = 'Call'; + callNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.callee); + this.object && visitor(this.object); + visitArrayInputs(this.args, visitor); + }; + return callNode; + }(); + var CallProperty = function () { + function callPropertyNode(control, store, object, name, args, flags) { + true; + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.args = args; + this.flags = flags; + this.id = nextID[nextID.length - 1] += 1; + } + callPropertyNode.prototype = extend(StoreDependent, 'CallProperty'); + callPropertyNode.prototype.nodeName = 'CallProperty'; + callPropertyNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + visitArrayInputs(this.args, visitor); + }; + return callPropertyNode; + }(); + var ASCallProperty = function () { + function asCallPropertyNode(control, store, object, name, args, flags, isLex) { + true; + true; + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.args = args; + this.flags = flags; + this.isLex = isLex; + this.id = nextID[nextID.length - 1] += 1; + } + asCallPropertyNode.prototype = extend(CallProperty, 'ASCallProperty'); + asCallPropertyNode.prototype.nodeName = 'ASCallProperty'; + asCallPropertyNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + visitArrayInputs(this.args, visitor); + }; + return asCallPropertyNode; + }(); + var ASCallSuper = function () { + function asCallSuperNode(control, store, object, name, args, flags, scope) { + true; + true; + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.args = args; + this.flags = flags; + this.scope = scope; + this.id = nextID[nextID.length - 1] += 1; + } + asCallSuperNode.prototype = extend(CallProperty, 'ASCallSuper'); + asCallSuperNode.prototype.nodeName = 'ASCallSuper'; + asCallSuperNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + visitArrayInputs(this.args, visitor); + visitor(this.scope); + }; + return asCallSuperNode; + }(); + var New = function () { + function newNode(control, store, callee, args) { + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.callee = callee; + this.args = args; + this.id = nextID[nextID.length - 1] += 1; + } + newNode.prototype = extend(StoreDependent, 'New'); + newNode.prototype.nodeName = 'New'; + newNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.callee); + visitArrayInputs(this.args, visitor); + }; + return newNode; + }(); + var ASNew = function () { + function asNewNode(control, store, callee, args) { + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.callee = callee; + this.args = args; + this.id = nextID[nextID.length - 1] += 1; + } + asNewNode.prototype = extend(New, 'ASNew'); + asNewNode.prototype.nodeName = 'ASNew'; + asNewNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.callee); + visitArrayInputs(this.args, visitor); + }; + return asNewNode; + }(); + var GetProperty = function () { + function getPropertyNode(control, store, object, name) { + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.id = nextID[nextID.length - 1] += 1; + } + getPropertyNode.prototype = extend(StoreDependent, 'GetProperty'); + getPropertyNode.prototype.nodeName = 'GetProperty'; + getPropertyNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + }; + return getPropertyNode; + }(); + var ASGetProperty = function () { + function asGetPropertyNode(control, store, object, name, flags) { + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.flags = flags; + this.id = nextID[nextID.length - 1] += 1; + } + asGetPropertyNode.prototype = extend(GetProperty, 'ASGetProperty'); + asGetPropertyNode.prototype.nodeName = 'ASGetProperty'; + asGetPropertyNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + }; + return asGetPropertyNode; + }(); + var ASGetDescendants = function () { + function asGetDescendantsNode(control, store, object, name) { + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.id = nextID[nextID.length - 1] += 1; + } + asGetDescendantsNode.prototype = extend(GetProperty, 'ASGetDescendants'); + asGetDescendantsNode.prototype.nodeName = 'ASGetDescendants'; + asGetDescendantsNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + }; + return asGetDescendantsNode; + }(); + var ASHasProperty = function () { + function asHasPropertyNode(control, store, object, name) { + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.id = nextID[nextID.length - 1] += 1; + } + asHasPropertyNode.prototype = extend(GetProperty, 'ASHasProperty'); + asHasPropertyNode.prototype.nodeName = 'ASHasProperty'; + asHasPropertyNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + }; + return asHasPropertyNode; + }(); + var ASGetSlot = function () { + function asGetSlotNode(control, store, object, name) { + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.id = nextID[nextID.length - 1] += 1; + } + asGetSlotNode.prototype = extend(GetProperty, 'ASGetSlot'); + asGetSlotNode.prototype.nodeName = 'ASGetSlot'; + asGetSlotNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + }; + return asGetSlotNode; + }(); + var ASGetSuper = function () { + function asGetSuperNode(control, store, object, name, scope) { + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.scope = scope; + this.id = nextID[nextID.length - 1] += 1; + } + asGetSuperNode.prototype = extend(GetProperty, 'ASGetSuper'); + asGetSuperNode.prototype.nodeName = 'ASGetSuper'; + asGetSuperNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + visitor(this.scope); + }; + return asGetSuperNode; + }(); + var SetProperty = function () { + function setPropertyNode(control, store, object, name, value) { + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.value = value; + this.id = nextID[nextID.length - 1] += 1; + } + setPropertyNode.prototype = extend(StoreDependent, 'SetProperty'); + setPropertyNode.prototype.nodeName = 'SetProperty'; + setPropertyNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + visitor(this.value); + }; + return setPropertyNode; + }(); + var ASSetProperty = function () { + function asSetPropertyNode(control, store, object, name, value, flags) { + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.value = value; + this.flags = flags; + this.id = nextID[nextID.length - 1] += 1; + } + asSetPropertyNode.prototype = extend(SetProperty, 'ASSetProperty'); + asSetPropertyNode.prototype.nodeName = 'ASSetProperty'; + asSetPropertyNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + visitor(this.value); + }; + return asSetPropertyNode; + }(); + var ASSetSlot = function () { + function asSetSlotNode(control, store, object, name, value) { + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.value = value; + this.id = nextID[nextID.length - 1] += 1; + } + asSetSlotNode.prototype = extend(SetProperty, 'ASSetSlot'); + asSetSlotNode.prototype.nodeName = 'ASSetSlot'; + asSetSlotNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + visitor(this.value); + }; + return asSetSlotNode; + }(); + var ASSetSuper = function () { + function asSetSuperNode(control, store, object, name, value, scope) { + true; + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.value = value; + this.scope = scope; + this.id = nextID[nextID.length - 1] += 1; + } + asSetSuperNode.prototype = extend(SetProperty, 'ASSetSuper'); + asSetSuperNode.prototype.nodeName = 'ASSetSuper'; + asSetSuperNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + visitor(this.value); + visitor(this.scope); + }; + return asSetSuperNode; + }(); + var DeleteProperty = function () { + function deletePropertyNode(control, store, object, name) { + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.id = nextID[nextID.length - 1] += 1; + } + deletePropertyNode.prototype = extend(StoreDependent, 'DeleteProperty'); + deletePropertyNode.prototype.nodeName = 'DeleteProperty'; + deletePropertyNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + }; + return deletePropertyNode; + }(); + var ASDeleteProperty = function () { + function asDeletePropertyNode(control, store, object, name) { + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.object = object; + this.name = name; + this.id = nextID[nextID.length - 1] += 1; + } + asDeletePropertyNode.prototype = extend(DeleteProperty, 'ASDeleteProperty'); + asDeletePropertyNode.prototype.nodeName = 'ASDeleteProperty'; + asDeletePropertyNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.object); + visitor(this.name); + }; + return asDeletePropertyNode; + }(); + var ASFindProperty = function () { + function asFindPropertyNode(control, store, scope, name, domain, strict) { + true; + true; + true; + true; + true; + true; + this.control = control; + this.store = store; + this.loads = undefined; + this.scope = scope; + this.name = name; + this.domain = domain; + this.strict = strict; + this.id = nextID[nextID.length - 1] += 1; + } + asFindPropertyNode.prototype = extend(StoreDependent, 'ASFindProperty'); + asFindPropertyNode.prototype.nodeName = 'ASFindProperty'; + asFindPropertyNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + this.store && visitor(this.store); + this.loads && visitArrayInputs(this.loads, visitor); + visitor(this.scope); + visitor(this.name); + visitor(this.domain); + }; + return asFindPropertyNode; + }(); + var Store = function () { + function storeNode() { + true; + this.id = nextID[nextID.length - 1] += 1; + } + storeNode.prototype = extend(Value, 'Store'); + storeNode.prototype.nodeName = 'Store'; + storeNode.prototype.visitInputs = function (visitor) { + }; + return storeNode; + }(); + var Phi = function () { + function phiNode(control, value) { + true; + true; + this.control = control; + this.args = value ? [ + value + ] : []; + this.id = nextID[nextID.length - 1] += 1; + } + phiNode.prototype = extend(Value, 'Phi'); + phiNode.prototype.nodeName = 'Phi'; + phiNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + visitArrayInputs(this.args, visitor); + }; + return phiNode; + }(); + var Variable = function () { + function variableNode(name) { + true; + this.name = name; + this.id = nextID[nextID.length - 1] += 1; + } + variableNode.prototype = extend(Value, 'Variable'); + variableNode.prototype.nodeName = 'Variable'; + variableNode.prototype.visitInputs = function (visitor) { + }; + return variableNode; + }(); + var Copy = function () { + function copyNode(argument) { + true; + this.argument = argument; + this.id = nextID[nextID.length - 1] += 1; + } + copyNode.prototype = extend(Value, 'Copy'); + copyNode.prototype.nodeName = 'Copy'; + copyNode.prototype.visitInputs = function (visitor) { + visitor(this.argument); + }; + return copyNode; + }(); + var Move = function () { + function moveNode(to, from) { + true; + this.to = to; + this.from = from; + this.id = nextID[nextID.length - 1] += 1; + } + moveNode.prototype = extend(Value, 'Move'); + moveNode.prototype.nodeName = 'Move'; + moveNode.prototype.visitInputs = function (visitor) { + visitor(this.to); + visitor(this.from); + }; + return moveNode; + }(); + var Projection = function () { + function projectionNode(argument, type, selector) { + true; + this.argument = argument; + this.type = type; + this.selector = selector; + this.id = nextID[nextID.length - 1] += 1; + } + projectionNode.prototype = extend(Value, 'Projection'); + projectionNode.prototype.nodeName = 'Projection'; + projectionNode.prototype.visitInputs = function (visitor) { + visitor(this.argument); + }; + return projectionNode; + }(); + var Latch = function () { + function latchNode(control, condition, left, right) { + true; + true; + this.control = control; + this.condition = condition; + this.left = left; + this.right = right; + this.id = nextID[nextID.length - 1] += 1; + } + latchNode.prototype = extend(Value, 'Latch'); + latchNode.prototype.nodeName = 'Latch'; + latchNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + visitor(this.condition); + visitor(this.left); + visitor(this.right); + }; + return latchNode; + }(); + var Binary = function () { + function binaryNode(operator, left, right) { + true; + this.operator = operator; + this.left = left; + this.right = right; + this.id = nextID[nextID.length - 1] += 1; + } + binaryNode.prototype = extend(Value, 'Binary'); + binaryNode.prototype.nodeName = 'Binary'; + binaryNode.prototype.visitInputs = function (visitor) { + visitor(this.left); + visitor(this.right); + }; + return binaryNode; + }(); + var Unary = function () { + function unaryNode(operator, argument) { + true; + this.operator = operator; + this.argument = argument; + this.id = nextID[nextID.length - 1] += 1; + } + unaryNode.prototype = extend(Value, 'Unary'); + unaryNode.prototype.nodeName = 'Unary'; + unaryNode.prototype.visitInputs = function (visitor) { + visitor(this.argument); + }; + return unaryNode; + }(); + var Constant = function () { + function constantNode(value) { + true; + this.value = value; + this.id = nextID[nextID.length - 1] += 1; + } + constantNode.prototype = extend(Value, 'Constant'); + constantNode.prototype.nodeName = 'Constant'; + constantNode.prototype.visitInputs = function (visitor) { + }; + return constantNode; + }(); + var GlobalProperty = function () { + function globalPropertyNode(name) { + true; + this.name = name; + this.id = nextID[nextID.length - 1] += 1; + } + globalPropertyNode.prototype = extend(Value, 'GlobalProperty'); + globalPropertyNode.prototype.nodeName = 'GlobalProperty'; + globalPropertyNode.prototype.visitInputs = function (visitor) { + }; + return globalPropertyNode; + }(); + var This = function () { + function thisNode(control) { + true; + true; + this.control = control; + this.id = nextID[nextID.length - 1] += 1; + } + thisNode.prototype = extend(Value, 'This'); + thisNode.prototype.nodeName = 'This'; + thisNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + }; + return thisNode; + }(); + var Throw = function () { + function throwNode(control, argument) { + true; + true; + this.control = control; + this.argument = argument; + this.id = nextID[nextID.length - 1] += 1; + } + throwNode.prototype = extend(Value, 'Throw'); + throwNode.prototype.nodeName = 'Throw'; + throwNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + visitor(this.argument); + }; + return throwNode; + }(); + var Arguments = function () { + function argumentsNode(control) { + true; + true; + this.control = control; + this.id = nextID[nextID.length - 1] += 1; + } + argumentsNode.prototype = extend(Value, 'Arguments'); + argumentsNode.prototype.nodeName = 'Arguments'; + argumentsNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + }; + return argumentsNode; + }(); + var Parameter = function () { + function parameterNode(control, index, name) { + true; + true; + this.control = control; + this.index = index; + this.name = name; + this.id = nextID[nextID.length - 1] += 1; + } + parameterNode.prototype = extend(Value, 'Parameter'); + parameterNode.prototype.nodeName = 'Parameter'; + parameterNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + }; + return parameterNode; + }(); + var NewArray = function () { + function newArrayNode(control, elements) { + true; + true; + this.control = control; + this.elements = elements; + this.id = nextID[nextID.length - 1] += 1; + } + newArrayNode.prototype = extend(Value, 'NewArray'); + newArrayNode.prototype.nodeName = 'NewArray'; + newArrayNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + visitArrayInputs(this.elements, visitor); + }; + return newArrayNode; + }(); + var NewObject = function () { + function newObjectNode(control, properties) { + true; + true; + this.control = control; + this.properties = properties; + this.id = nextID[nextID.length - 1] += 1; + } + newObjectNode.prototype = extend(Value, 'NewObject'); + newObjectNode.prototype.nodeName = 'NewObject'; + newObjectNode.prototype.visitInputs = function (visitor) { + visitor(this.control); + visitArrayInputs(this.properties, visitor); + }; + return newObjectNode; + }(); + var KeyValuePair = function () { + function keyValuePairNode(key, value) { + true; + this.key = key; + this.value = value; + this.id = nextID[nextID.length - 1] += 1; + } + keyValuePairNode.prototype = extend(Value, 'KeyValuePair'); + keyValuePairNode.prototype.nodeName = 'KeyValuePair'; + keyValuePairNode.prototype.visitInputs = function (visitor) { + visitor(this.key); + visitor(this.value); + }; + return keyValuePairNode; + }(); + var ASScope = function () { + function asScopeNode(parent, object, isWith) { + true; + this.parent = parent; + this.object = object; + this.isWith = isWith; + this.id = nextID[nextID.length - 1] += 1; + } + asScopeNode.prototype = extend(Value, 'ASScope'); + asScopeNode.prototype.nodeName = 'ASScope'; + asScopeNode.prototype.visitInputs = function (visitor) { + visitor(this.parent); + visitor(this.object); + }; + return asScopeNode; + }(); + var ASGlobal = function () { + function asGlobalNode(control, scope) { + true; + true; + true; + this.control = control; + this.scope = scope; + this.id = nextID[nextID.length - 1] += 1; + } + asGlobalNode.prototype = extend(Value, 'ASGlobal'); + asGlobalNode.prototype.nodeName = 'ASGlobal'; + asGlobalNode.prototype.visitInputs = function (visitor) { + this.control && visitor(this.control); + visitor(this.scope); + }; + return asGlobalNode; + }(); + var ASNewActivation = function () { + function asNewActivationNode(methodInfo) { + true; + this.methodInfo = methodInfo; + this.id = nextID[nextID.length - 1] += 1; + } + asNewActivationNode.prototype = extend(Value, 'ASNewActivation'); + asNewActivationNode.prototype.nodeName = 'ASNewActivation'; + asNewActivationNode.prototype.visitInputs = function (visitor) { + }; + return asNewActivationNode; + }(); + var ASMultiname = function () { + function asMultinameNode(namespaces, name, flags) { + true; + this.namespaces = namespaces; + this.name = name; + this.flags = flags; + this.id = nextID[nextID.length - 1] += 1; + } + asMultinameNode.prototype = extend(Value, 'ASMultiname'); + asMultinameNode.prototype.nodeName = 'ASMultiname'; + asMultinameNode.prototype.visitInputs = function (visitor) { + visitor(this.namespaces); + visitor(this.name); + }; + return asMultinameNode; + }(); + function node() { + this.id = nextID[nextID.length - 1] += 1; + } + Node.startNumbering = function () { + nextID.push(0); + }; + Node.stopNumbering = function () { + nextID.pop(); + }; + Node.prototype.toString = function (brief) { + if (brief) { + return nameOf(this); + } + var inputs = []; + this.visitInputs(function (input) { + inputs.push(nameOf(input)); + }); + var str = nameOf(this) + ' = ' + this.nodeName.toUpperCase(); + if (this.toStringDetails) { + str += ' ' + this.toStringDetails(); + } + if (inputs.length) { + str += ' ' + inputs.join(', '); + } + return str; + }; + Node.prototype.visitInputsNoConstants = function visitInputs(visitor) { + this.visitInputs(function (node) { + if (isConstant(node)) { + return; + } + visitor(node); + }); + }; + Node.prototype.replaceInput = function (oldInput, newInput) { + var count = 0; + for (var k in this) { + var v = this[k]; + if (v instanceof Node) { + if (v === oldInput) { + this[k] = newInput; + count++; + } + } + if (v instanceof Array) { + count += v.replace(oldInput, newInput); + } + } + return count; + }; + Projection.Type = { + CASE: 'case', + TRUE: 'true', + FALSE: 'false', + STORE: 'store', + SCOPE: 'scope' + }; + Projection.prototype.project = function () { + return this.argument; + }; + Phi.prototype.seal = function seal() { + this.sealed = true; + }; + Phi.prototype.pushValue = function pushValue(x) { + true; + true; + this.args.push(x); + }; + KeyValuePair.prototype.mustFloat = true; + ASMultiname.prototype.mustFloat = true; + ASMultiname.prototype.isAttribute = function () { + return this.flags & 1; + }; + var Flags = { + INDEXED: 1, + RESOLVED: 2, + PRISTINE: 4, + IS_METHOD: 8 + }; + var Operator = function () { + var map = {}; + function operator(name, evaluate, binary) { + this.name = name; + this.binary = binary; + this.evaluate = evaluate; + map[name] = this; + } + operator.ADD = new operator('+', function (l, r) { + return l + r; + }, true); + operator.SUB = new operator('-', function (l, r) { + return l - r; + }, true); + operator.MUL = new operator('*', function (l, r) { + return l * r; + }, true); + operator.DIV = new operator('/', function (l, r) { + return l / r; + }, true); + operator.MOD = new operator('%', function (l, r) { + return l % r; + }, true); + operator.AND = new operator('&', function (l, r) { + return l & r; + }, true); + operator.OR = new operator('|', function (l, r) { + return l | r; + }, true); + operator.XOR = new operator('^', function (l, r) { + return l ^ r; + }, true); + operator.LSH = new operator('<<', function (l, r) { + return l << r; + }, true); + operator.RSH = new operator('>>', function (l, r) { + return l >> r; + }, true); + operator.URSH = new operator('>>>', function (l, r) { + return l >>> r; + }, true); + operator.SEQ = new operator('===', function (l, r) { + return l === r; + }, true); + operator.SNE = new operator('!==', function (l, r) { + return l !== r; + }, true); + operator.EQ = new operator('==', function (l, r) { + return l == r; + }, true); + operator.NE = new operator('!=', function (l, r) { + return l != r; + }, true); + operator.LE = new operator('<=', function (l, r) { + return l <= r; + }, true); + operator.GT = new operator('>', function (l, r) { + return l > r; + }, true); + operator.LT = new operator('<', function (l, r) { + return l < r; + }, true); + operator.GE = new operator('>=', function (l, r) { + return l >= r; + }, true); + operator.BITWISE_NOT = new operator('~', function (a) { + return ~a; + }, false); + operator.PLUS = new operator('+', function (a) { + return +a; + }, false); + operator.NEG = new operator('-', function (a) { + return -a; + }, false); + operator.TYPE_OF = new operator('typeof', function (a) { + return typeof a; + }, false); + operator.TRUE = new operator('!!', function (a) { + return !(!a); + }, false); + operator.FALSE = new operator('!', function (a) { + return !a; + }, false); + operator.AS_ADD = new operator('+', function (l, r) { + if (typeof l === 'string' || typeof r === 'string') { + return String(l) + String(r); + } + return l + r; + }, true); + function linkOpposites(a, b) { + a.not = b; + b.not = a; + } + linkOpposites(operator.SEQ, operator.SNE); + linkOpposites(operator.EQ, operator.NE); + linkOpposites(operator.TRUE, operator.FALSE); + operator.fromName = function fromName(name) { + return map[name]; + }; + operator.prototype.isBinary = function isBinary() { + return this.binary; + }; + operator.prototype.toString = function toString() { + return this.name; + }; + return operator; + }(); + function extend(c, name) { + true; + return Object.create(c.prototype, { + nodeName: { + value: name + } + }); + } + function nameOf(o) { + var useColors = false; + var result; + if (o instanceof Constant) { + if (o.value instanceof Multiname) { + return o.value.name; + } + return o.value; + } else if (o instanceof Variable) { + return o.name; + } else if (o instanceof Phi) { + return result = '|' + o.id + '|', useColors ? PURPLE + result + ENDC : result; + } else if (o instanceof Control) { + return result = '{' + o.id + '}', useColors ? RED + result + ENDC : result; + } else if (o instanceof Projection) { + if (o.type === Projection.Type.STORE) { + return result = '[' + o.id + '->' + o.argument.id + ']', useColors ? YELLOW + result + ENDC : result; + } + return result = '(' + o.id + ')', useColors ? GREEN + result + ENDC : result; + } else if (o instanceof Value) { + return result = '(' + o.id + ')', useColors ? GREEN + result + ENDC : result; + } else if (o instanceof Node) { + return o.id; + } + unexpected(o + ' ' + typeof o); + } + function toID(node) { + return node.id; + } + function visitArrayInputs(array, visitor) { + for (var i = 0; i < array.length; i++) { + visitor(array[i]); + } + } + function visitNothing() { + } + function isNotPhi(phi) { + return !isPhi(phi); + } + function isPhi(phi) { + return phi instanceof Phi; + } + function isScope(scope) { + return isPhi(scope) || scope instanceof ASScope || isProjection(scope, Projection.Type.SCOPE); + } + function isMultinameConstant(node) { + return node instanceof Constant && node.value instanceof Multiname; + } + function isMultiname(name) { + return isMultinameConstant(name) || name instanceof ASMultiname; + } + function isStore(store) { + return isPhi(store) || store instanceof Store || isProjection(store, Projection.Type.STORE); + } + function isConstant(constant) { + return constant instanceof Constant; + } + function isBoolean(boolean) { + return boolean === true || boolean === false; + } + function isInteger(integer) { + return integer | 0 === integer; + } + function isArray(array) { + return array instanceof Array; + } + function isControlOrNull(control) { + return isControl(control) || control === null; + } + function isStoreOrNull(store) { + return isStore(store) || store === null; + } + function isControl(control) { + return control instanceof Control; + } + function isValueOrNull(value) { + return isValue(value) || value === null; + } + function isValue(value) { + return value instanceof Value; + } + function isProjection(node, type) { + return node instanceof Projection && (!type || node.type === type); + } + var Null = new Constant(null); + var Undefined = new Constant(undefined); + Undefined.toString = function () { + return '_'; + }; + var Block = function () { + function block(id, start, end) { + if (start) { + true; + } + this.region = start; + this.id = id; + this.successors = []; + this.predecessors = []; + this.nodes = [ + start, + end + ]; + } + block.prototype.pushSuccessorAt = function pushSuccessor(successor, index, pushPredecessor) { + true; + true; + this.successors[index] = successor; + if (pushPredecessor) { + successor.pushPredecessor(this); + } + }; + block.prototype.pushSuccessor = function pushSuccessor(successor, pushPredecessor) { + true; + this.successors.push(successor); + if (pushPredecessor) { + successor.pushPredecessor(this); + } + }; + block.prototype.pushPredecessor = function pushPredecessor(predecessor) { + true; + this.predecessors.push(predecessor); + }; + block.prototype.visitNodes = function (fn) { + var nodes = this.nodes; + for (var i = 0, j = nodes.length; i < j; i++) { + fn(nodes[i]); + } + }; + block.prototype.visitSuccessors = function (fn) { + var successors = this.successors; + for (var i = 0, j = successors.length; i < j; i++) { + fn(successors[i]); + } + }; + block.prototype.visitPredecessors = function (fn) { + var predecessors = this.predecessors; + for (var i = 0, j = predecessors.length; i < j; i++) { + fn(predecessors[i]); + } + }; + block.prototype.append = function (node) { + true; + true; + true; + true; + if (node.mustFloat) { + return; + } + this.nodes.splice(this.nodes.length - 1, 0, node); + }; + block.prototype.toString = function () { + return 'B' + this.id + (this.name ? ' (' + this.name + ')' : ''); + }; + block.prototype.trace = function (writer) { + writer.writeLn(this); + }; + return block; + }(); + var DFG = function () { + function constructor(exit) { + this.exit = exit; + } + constructor.prototype.buildCFG = function () { + return CFG.fromDFG(this); + }; + function preOrderDepthFirstSearch(root, visitChildren, pre) { + var visited = []; + var worklist = [ + root + ]; + var push = worklist.push.bind(worklist); + var node; + while (node = worklist.pop()) { + if (visited[node.id] === 1) { + continue; + } + visited[node.id] = 1; + pre(node); + worklist.push(node); + visitChildren(node, push); + } + } + function postOrderDepthFirstSearch(root, visitChildren, post) { + var ONE_TIME = 1, MANY_TIMES = 2; + var visited = []; + var worklist = [ + root + ]; + function visitChild(child) { + if (!visited[child.id]) { + worklist.push(child); + } + } + var node; + while (node = worklist.top()) { + if (visited[node.id]) { + if (visited[node.id] === ONE_TIME) { + visited[node.id] = MANY_TIMES; + post(node); + } + worklist.pop(); + continue; + } + visited[node.id] = ONE_TIME; + visitChildren(node, visitChild); + } + } + constructor.prototype.forEachInPreOrderDepthFirstSearch = function forEachInPreOrderDepthFirstSearch(visitor) { + var visited = new Array(1024); + var worklist = [ + this.exit + ]; + function push(node) { + if (isConstant(node)) { + return; + } + true; + worklist.push(node); + } + var node; + while (node = worklist.pop()) { + if (visited[node.id]) { + continue; + } + visited[node.id] = 1; + visitor && visitor(node); + worklist.push(node); + node.visitInputs(push); + } + }; + constructor.prototype.forEach = function forEach(visitor, postOrder) { + var search = postOrder ? postOrderDepthFirstSearch : preOrderDepthFirstSearch; + search(this.exit, function (node, v) { + node.visitInputsNoConstants(v); + }, visitor); + }; + constructor.prototype.traceMetrics = function (writer) { + var counter = new metrics.Counter(true); + preOrderDepthFirstSearch(this.exit, function (node, visitor) { + node.visitInputsNoConstants(visitor); + }, function (node) { + counter.count(node.nodeName); + }); + counter.trace(writer); + }; + constructor.prototype.trace = function (writer) { + var nodes = []; + var visited = {}; + function colorOf(node) { + if (node instanceof Control) { + return 'yellow'; + } else if (node instanceof Phi) { + return 'purple'; + } else if (node instanceof Value) { + return 'green'; + } + return 'white'; + } + var blocks = []; + function followProjection(node) { + return node instanceof Projection ? node.project() : node; + } + function next(node) { + node = followProjection(node); + if (!visited[node.id]) { + visited[node.id] = true; + if (node.block) { + blocks.push(node.block); + } + nodes.push(node); + node.visitInputsNoConstants(next); + } + } + next(this.exit); + writer.writeLn(''); + writer.enter('digraph DFG {'); + writer.writeLn('graph [bgcolor = gray10];'); + writer.writeLn('edge [color = white];'); + writer.writeLn('node [shape = box, fontname = Consolas, fontsize = 11, color = white, fontcolor = white];'); + writer.writeLn('rankdir = BT;'); + function writeNode(node) { + writer.writeLn('N' + node.id + ' [label = "' + node.toString() + '", color = "' + colorOf(node) + '"];'); + } + function defineNode(node) { + writer.writeLn('N' + node.id + ';'); + } + blocks.forEach(function (block) { + writer.enter('subgraph cluster' + block.nodes[0].id + ' { bgcolor = gray20;'); + block.visitNodes(function (node) { + defineNode(followProjection(node)); + }); + writer.leave('}'); + }); + nodes.forEach(writeNode); + nodes.forEach(function (node) { + node.visitInputsNoConstants(function (input) { + input = followProjection(input); + writer.writeLn('N' + node.id + ' -> ' + 'N' + input.id + ' [color=' + colorOf(input) + '];'); + }); + }); + writer.leave('}'); + writer.writeLn(''); + }; + return constructor; + }(); + var CFG = function () { + function constructor() { + this.nextBlockID = 0; + this.blocks = []; + this.exit; + this.root; + } + constructor.fromDFG = function fromDFG(dfg) { + var cfg = new CFG(); + true; + cfg.dfg = dfg; + var visited = []; + function buildEnd(end) { + if (end instanceof Projection) { + end = end.project(); + } + true; + if (visited[end.id]) { + return; + } + visited[end.id] = true; + var start = end.control; + if (!(start instanceof Region)) { + start = end.control = new Region(start); + } + var block = start.block = cfg.buildBlock(start, end); + if (start instanceof Start) { + cfg.root = block; + } + for (var i = 0; i < start.predecessors.length; i++) { + var c = start.predecessors[i]; + var d; + var trueProjection = false; + if (c instanceof Projection) { + d = c.project(); + trueProjection = c.type === Projection.Type.TRUE; + } else { + d = c; + } + if (d instanceof Region) { + d = new Jump(c); + d = new Projection(d, Projection.Type.TRUE); + start.predecessors[i] = d; + d = d.project(); + trueProjection = true; + } + buildEnd(d); + var controlBlock = d.control.block; + if (d instanceof Switch) { + true; + controlBlock.pushSuccessorAt(block, c.selector.value, true); + } else if (trueProjection && controlBlock.successors.length > 0) { + controlBlock.pushSuccessor(block, true); + controlBlock.hasFlippedSuccessors = true; + } else { + controlBlock.pushSuccessor(block, true); + } + } + } + buildEnd(dfg.exit); + cfg.splitCriticalEdges(); + cfg.exit = dfg.exit.control.block; + cfg.computeDominators(true); + return cfg; + }; + constructor.prototype.buildRootAndExit = function buildRootAndExit() { + true; + if (this.blocks[0].predecessors.length > 0) { + this.root = new Block(this.nextBlockID++); + this.blocks.push(this.root); + this.root.pushSuccessor(this.blocks[0], true); + } else { + this.root = this.blocks[0]; + } + var exitBlocks = []; + for (var i = 0; i < this.blocks.length; i++) { + var block = this.blocks[i]; + if (block.successors.length === 0) { + exitBlocks.push(block); + } + } + if (exitBlocks.length === 0) { + unexpected('Must have an exit block.'); + } else if (exitBlocks.length === 1 && exitBlocks[0] !== this.root) { + this.exit = exitBlocks[0]; + } else { + this.exit = new Block(this.nextBlockID++); + this.blocks.push(this.exit); + for (var i = 0; i < exitBlocks.length; i++) { + exitBlocks[i].pushSuccessor(this.exit, true); + } + } + true; + true; + }; + constructor.prototype.fromString = function (list, rootName) { + var cfg = this; + var names = cfg.blockNames || (cfg.blockNames = {}); + var blocks = cfg.blocks; + var sets = list.replace(/\ /g, '').split(','); + sets.forEach(function (set) { + var edgeList = set.split('->'); + var last = null; + for (var i = 0; i < edgeList.length; i++) { + var next = edgeList[i]; + if (last) { + buildEdge(last, next); + } else { + buildBlock(next); + } + last = next; + } + }); + function buildBlock(name) { + var block = names[name]; + if (block) { + return block; + } + names[name] = block = new Block(cfg.nextBlockID++); + block.name = name; + blocks.push(block); + return block; + } + function buildEdge(from, to) { + buildBlock(from).pushSuccessor(buildBlock(to), true); + } + true; + this.root = names[rootName]; + }; + constructor.prototype.buildBlock = function (start, end) { + var block = new Block(this.nextBlockID++, start, end); + this.blocks.push(block); + return block; + }; + constructor.prototype.createBlockSet = function () { + if (!this.setConstructor) { + this.setConstructor = BitSetFunctor(this.blocks.length); + } + return new this.setConstructor(); + }; + constructor.prototype.computeReversePostOrder = function computeReversePostOrder() { + if (this.order) { + return this.order; + } + var order = this.order = []; + this.depthFirstSearch(null, order.push.bind(order)); + order.reverse(); + for (var i = 0; i < order.length; i++) { + order[i].rpo = i; + } + return order; + }; + constructor.prototype.depthFirstSearch = function depthFirstSearch(preFn, postFn) { + var visited = this.createBlockSet(); + function visit(node) { + visited.set(node.id); + if (preFn) + preFn(node); + var successors = node.successors; + for (var i = 0, j = successors.length; i < j; i++) { + var s = successors[i]; + if (!visited.get(s.id)) { + visit(s); + } + } + if (postFn) + postFn(node); + } + visit(this.root); + }; + constructor.prototype.computeDominators = function (apply) { + true; + var dom = new Int32Array(this.blocks.length); + for (var i = 0; i < dom.length; i++) { + dom[i] = -1; + } + var map = this.createBlockSet(); + function computeCommonDominator(a, b) { + map.clearAll(); + while (a >= 0) { + map.set(a); + a = dom[a]; + } + while (b >= 0 && !map.get(b)) { + b = dom[b]; + } + return b; + } + function computeDominator(blockID, parentID) { + if (dom[blockID] < 0) { + dom[blockID] = parentID; + } else { + dom[blockID] = computeCommonDominator(dom[blockID], parentID); + } + } + this.depthFirstSearch(function visit(block) { + var s = block.successors; + for (var i = 0, j = s.length; i < j; i++) { + computeDominator(s[i].id, block.id); + } + }); + if (apply) { + for (var i = 0, j = this.blocks.length; i < j; i++) { + this.blocks[i].dominator = this.blocks[dom[i]]; + } + function computeDominatorDepth(block) { + var dominatorDepth; + if (block.dominatorDepth !== undefined) { + return block.dominatorDepth; + } else if (!block.dominator) { + dominatorDepth = 0; + } else { + dominatorDepth = computeDominatorDepth(block.dominator) + 1; + } + return block.dominatorDepth = dominatorDepth; + } + for (var i = 0, j = this.blocks.length; i < j; i++) { + computeDominatorDepth(this.blocks[i]); + } + } + return dom; + }; + constructor.prototype.computeLoops = function computeLoops() { + var active = this.createBlockSet(); + var visited = this.createBlockSet(); + var nextLoop = 0; + function makeLoopHeader(block) { + if (!block.isLoopHeader) { + block.isLoopHeader = true; + block.loops = 1 << nextLoop; + nextLoop += 1; + } + } + function visit(block) { + if (visited.get(block.id)) { + if (active.get(block.id)) { + makeLoopHeader(block); + } + return block.loops; + } + visited.set(block.id); + active.set(block.id); + var loops = 0; + for (var i = 0, j = block.successors.length; i < j; i++) { + loops |= visit(block.successors[i]); + } + if (block.isLoopHeader) { + loops &= ~block.loops; + } + block.loops = loops; + active.clear(block.id); + return loops; + } + var loop = visit(this.root); + }; + function followProjection(node) { + return node instanceof Projection ? node.project() : node; + } + var Uses = function () { + function constructor() { + this.entries = []; + } + constructor.prototype.addUse = function addUse(def, use) { + var entry = this.entries[def.id]; + if (!entry) { + entry = this.entries[def.id] = { + def: def, + uses: [] + }; + } + entry.uses.pushUnique(use); + }; + constructor.prototype.trace = function (writer) { + writer.enter('> Uses'); + this.entries.forEach(function (entry) { + writer.writeLn(entry.def.id + ' -> [' + entry.uses.map(toID).join(', ') + '] ' + entry.def); + }); + writer.leave('<'); + }; + constructor.prototype.replace = function (def, value) { + var entry = this.entries[def.id]; + if (entry.uses.length === 0) { + return false; + } + var count = 0; + entry.uses.forEach(function (use) { + count += use.replaceInput(def, value); + }); + true; + entry.uses = []; + return true; + }; + function updateUses(def, value) { + debug && writer.writeLn('Update ' + def + ' with ' + value); + var entry = useEntries[def.id]; + if (entry.uses.length === 0) { + return false; + } + debug && writer.writeLn('Replacing: ' + def.id + ' in [' + entry.uses.map(toID).join(', ') + '] with ' + value.id); + var count = 0; + entry.uses.forEach(function (use) { + count += use.replaceInput(def, value); + }); + true; + entry.uses = []; + return true; + } + return constructor; + }(); + constructor.prototype.computeUses = function computeUses() { + Timer.start('computeUses'); + var writer = debug && new IndentingWriter(); + debug && writer.enter('> Compute Uses'); + var dfg = this.dfg; + var uses = new Uses(); + dfg.forEachInPreOrderDepthFirstSearch(function (use) { + use.visitInputs(function (def) { + uses.addUse(def, use); + }); + }); + if (debug) { + writer.enter('> Uses'); + uses.entries.forEach(function (entry) { + writer.writeLn(entry.def.id + ' -> [' + entry.uses.map(toID).join(', ') + '] ' + entry.def); + }); + writer.leave('<'); + writer.leave('<'); + } + Timer.stop(); + return uses; + }; + constructor.prototype.verify = function verify() { + var writer = debug && new IndentingWriter(); + debug && writer.enter('> Verify'); + var order = this.computeReversePostOrder(); + order.forEach(function (block) { + if (block.phis) { + block.phis.forEach(function (phi) { + true; + true; + }); + } + }); + debug && writer.leave('<'); + }; + constructor.prototype.optimizePhis = function optimizePhis() { + var writer = debug && new IndentingWriter(); + debug && writer.enter('> Optimize Phis'); + var phis = []; + var useEntries = this.computeUses().entries; + useEntries.forEach(function (entry) { + if (isPhi(entry.def)) { + phis.push(entry.def); + } + }); + debug && writer.writeLn('Trying to optimize ' + phis.length + ' phis.'); + function updateUses(def, value) { + debug && writer.writeLn('Update ' + def + ' with ' + value); + var entry = useEntries[def.id]; + if (entry.uses.length === 0) { + return false; + } + debug && writer.writeLn('Replacing: ' + def.id + ' in [' + entry.uses.map(toID).join(', ') + '] with ' + value.id); + var count = 0; + var entryUses = entry.uses; + for (var i = 0, j = entryUses.length; i < j; i++) { + count += entryUses[i].replaceInput(def, value); + } + true; + entry.uses = []; + return true; + } + function simplify(phi, args) { + args = args.unique(); + if (args.length === 1) { + return args[0]; + } else { + if (args.length === 2) { + if (args[0] === phi) { + return args[1]; + } else if (args[1] === phi) { + return args[0]; + } + return phi; + } + } + return phi; + } + var count = 0; + var iterations = 0; + var changed = true; + while (changed) { + iterations++; + changed = false; + phis.forEach(function (phi) { + var value = simplify(phi, phi.args); + if (value !== phi) { + if (updateUses(phi, value)) { + changed = true; + count++; + } + } + }); + } + if (debug) { + writer.writeLn('Simplified ' + count + ' phis, in ' + iterations + ' iterations.'); + writer.leave('<'); + } + }; + constructor.prototype.splitCriticalEdges = function splitCriticalEdges() { + var writer = debug && new IndentingWriter(); + var blocks = this.blocks; + var criticalEdges = []; + debug && writer.enter('> Splitting Critical Edges'); + for (var i = 0; i < blocks.length; i++) { + var successors = blocks[i].successors; + if (successors.length > 1) { + for (var j = 0; j < successors.length; j++) { + if (successors[j].predecessors.length > 1) { + criticalEdges.push({ + from: blocks[i], + to: successors[j] + }); + } + } + } + } + var criticalEdgeCount = criticalEdges.length; + if (criticalEdgeCount && debug) { + writer.writeLn('Splitting: ' + criticalEdgeCount); + this.trace(writer); + } + var edge; + while (edge = criticalEdges.pop()) { + var fromIndex = edge.from.successors.indexOf(edge.to); + var toIndex = edge.to.predecessors.indexOf(edge.from); + true; + debug && writer.writeLn('Splitting critical edge: ' + edge.from + ' -> ' + edge.to); + var toBlock = edge.to; + var toRegion = toBlock.region; + var control = toRegion.predecessors[toIndex]; + var region = new Region(control); + var jump = new Jump(region); + var block = this.buildBlock(region, jump); + toRegion.predecessors[toIndex] = new Projection(jump, Projection.Type.TRUE); + var fromBlock = edge.from; + fromBlock.successors[fromIndex] = block; + block.pushPredecessor(fromBlock); + block.pushSuccessor(toBlock); + toBlock.predecessors[toIndex] = block; + } + if (criticalEdgeCount && debug) { + this.trace(writer); + } + if (criticalEdgeCount && !true) { + true; + } + debug && writer.leave('<'); + return criticalEdgeCount; + }; + constructor.prototype.allocateVariables = function allocateVariables() { + var writer = debug && new IndentingWriter(); + debug && writer.enter('> Allocating Virtual Registers'); + var order = this.computeReversePostOrder(); + function allocate(node) { + if (isProjection(node, Projection.Type.STORE)) { + return; + } + if (node instanceof SetProperty) { + return; + } + if (node instanceof Value) { + node.variable = new Variable('v' + node.id); + debug && writer.writeLn('Allocated: ' + node.variable + ' to ' + node); + } + } + order.forEach(function (block) { + block.nodes.forEach(allocate); + if (block.phis) { + block.phis.forEach(allocate); + } + }); + var blockMoves = []; + for (var i = 0; i < order.length; i++) { + var block = order[i]; + var phis = block.phis; + var predecessors = block.predecessors; + if (phis) { + for (var j = 0; j < phis.length; j++) { + var phi = phis[j]; + debug && writer.writeLn('Emitting moves for: ' + phi); + var arguments = phi.args; + true; + for (var k = 0; k < predecessors.length; k++) { + var predecessor = predecessors[k]; + var argument = arguments[k]; + if (argument.abstract || isProjection(argument, Projection.Type.STORE)) { + continue; + } + var moves = blockMoves[predecessor.id] || (blockMoves[predecessor.id] = []); + argument = argument.variable || argument; + if (phi.variable !== argument) { + moves.push(new Move(phi.variable, argument)); + } + } + } + } + } + var blocks = this.blocks; + blockMoves.forEach(function (moves, blockID) { + var block = blocks[blockID]; + var temporary = 0; + debug && writer.writeLn(block + ' Moves: ' + moves); + while (moves.length) { + for (var i = 0; i < moves.length; i++) { + var move = moves[i]; + for (var j = 0; j < moves.length; j++) { + if (i === j) { + continue; + } + if (moves[j].from === move.to) { + move = null; + break; + } + } + if (move) { + moves.splice(i--, 1); + block.append(move); + } + } + if (moves.length) { + debug && writer.writeLn('Breaking Cycle'); + var move = moves[0]; + var temp = new Variable('t' + temporary++); + blocks[blockID].append(new Move(temp, move.to)); + for (var i = 1; i < moves.length; i++) { + if (moves[i].from === move.to) { + moves[i].from = temp; + } + } + } + } + }); + debug && writer.leave('<'); + }; + constructor.prototype.scheduleEarly = function scheduleEarly() { + var debugScheduler = false; + var writer = debugScheduler && new IndentingWriter(); + debugScheduler && writer.enter('> Schedule Early'); + var cfg = this; + var dfg = this.dfg; + var scheduled = []; + var roots = []; + dfg.forEachInPreOrderDepthFirstSearch(function (node) { + if (node instanceof Region || node instanceof Jump) { + return; + } + if (node.control) { + roots.push(node); + } + if (isPhi(node)) { + node.args.forEach(function (input) { + if (shouldFloat(input)) { + input.mustNotFloat = true; + } + }); + } + }, true); + if (debugScheduler) { + roots.forEach(function (node) { + print('Root: ' + node); + }); + } + for (var i = 0; i < roots.length; i++) { + var root = roots[i]; + if (root instanceof Phi) { + var block = root.control.block; + (block.phis || (block.phis = [])).push(root); + } + if (root.control) { + schedule(root); + } + } + function isScheduled(node) { + return scheduled[node.id]; + } + function shouldFloat(node) { + if (node.mustNotFloat || node.shouldNotFloat) { + return false; + } + if (node.mustFloat || node.shouldFloat) { + return true; + } + if (node instanceof Parameter || node instanceof This || node instanceof Arguments) { + return true; + } + return node instanceof Binary || node instanceof Unary || node instanceof Parameter; + } + function append(node) { + true; + scheduled[node.id] = true; + true; + if (shouldFloat(node)) { + } else { + node.control.block.append(node); + } + } + function scheduleIn(node, region) { + true; + true; + true; + debugScheduler && writer.writeLn('Scheduled: ' + node + ' in ' + region); + node.control = region; + append(node); + } + function schedule(node) { + debugScheduler && writer.enter('> Schedule: ' + node); + var inputs = []; + node.visitInputs(function (input) { + if (isConstant(input)) { + { + return; + } + } + if (isValue(input)) { + inputs.push(followProjection(input)); + } + }); + debugScheduler && writer.writeLn('Inputs: [' + inputs.map(toID) + '], length: ' + inputs.length); + for (var i = 0; i < inputs.length; i++) { + var input = inputs[i]; + if (isNotPhi(input) && !isScheduled(input)) { + schedule(input); + } + } + if (node.control) { + if (node instanceof End || node instanceof Phi || node instanceof Start || isScheduled(node)) { + } else { + append(node); + } + } else { + if (inputs.length) { + var x = inputs[0].control; + for (var i = 1; i < inputs.length; i++) { + var y = inputs[i].control; + if (x.block.dominatorDepth < y.block.dominatorDepth) { + x = y; + } + } + scheduleIn(node, x); + } else { + scheduleIn(node, cfg.root.region); + } + } + debugScheduler && writer.leave('<'); + } + debugScheduler && writer.leave('<'); + roots.forEach(function (node) { + node = followProjection(node); + if (node === dfg.start || node instanceof Region) { + return; + } + true; + }); + }; + constructor.prototype.trace = function (writer) { + var visited = []; + var blocks = []; + function next(block) { + if (!visited[block.id]) { + visited[block.id] = true; + blocks.push(block); + block.visitSuccessors(next); + } + } + var root = this.root; + var exit = this.exit; + next(root); + function colorOf(block) { + return 'black'; + } + function styleOf(block) { + return 'filled'; + } + function shapeOf(block) { + true; + if (block === root) { + return 'house'; + } else if (block === exit) { + return 'invhouse'; + } + return 'box'; + } + writer.writeLn(''); + writer.enter('digraph CFG {'); + writer.writeLn('graph [bgcolor = gray10];'); + writer.writeLn('edge [fontname = Consolas, fontsize = 11, color = white, fontcolor = white];'); + writer.writeLn('node [shape = box, fontname = Consolas, fontsize = 11, color = white, fontcolor = white, style = filled];'); + writer.writeLn('rankdir = TB;'); + blocks.forEach(function (block) { + var loopInfo = ''; + var blockInfo = ''; + var intervalInfo = ''; + if (block.loops !== undefined) { + } + if (block.name !== undefined) { + blockInfo += ' ' + block.name; + } + if (block.rpo !== undefined) { + blockInfo += ' O: ' + block.rpo; + } + writer.writeLn('B' + block.id + ' [label = "B' + block.id + blockInfo + loopInfo + '", fillcolor = "' + colorOf(block) + '", shape=' + shapeOf(block) + ', style=' + styleOf(block) + '];'); + }); + blocks.forEach(function (block) { + block.visitSuccessors(function (successor) { + writer.writeLn('B' + block.id + ' -> ' + 'B' + successor.id); + }); + if (block.dominator) { + writer.writeLn('B' + block.id + ' -> ' + 'B' + block.dominator.id + ' [color = orange];'); + } + if (block.follow) { + writer.writeLn('B' + block.id + ' -> ' + 'B' + block.follow.id + ' [color = purple];'); + } + }); + writer.leave('}'); + writer.writeLn(''); + }; + return constructor; + }(); + var PeepholeOptimizer = function () { + function constructor() { + } + function foldUnary(node, truthy) { + true; + if (isConstant(node.argument)) { + return new Constant(node.operator.evaluate(node.argument.value)); + } + if (truthy) { + var argument = fold(node.argument, true); + if (node.operator === Operator.TRUE) { + return argument; + } + if (argument instanceof Unary) { + if (node.operator === Operator.FALSE && argument.operator === Operator.FALSE) { + return argument.argument; + } + } else { + return new Unary(node.operator, argument); + } + } + return node; + } + function foldBinary(node, truthy) { + true; + if (isConstant(node.left) && isConstant(node.right)) { + return new Constant(node.operator.evaluate(node.left.value, node.right.value)); + } + return node; + } + function fold(node, truthy) { + if (node instanceof Unary) { + return foldUnary(node, truthy); + } else if (node instanceof Binary) { + return foldBinary(node, truthy); + } + return node; + } + constructor.prototype.tryFold = fold; + return constructor; + }(); + exports.isConstant = isConstant; + exports.Block = Block; + exports.Node = Node; + exports.Start = Start; + exports.Null = Null; + exports.Undefined = Undefined; + exports.This = This; + exports.Throw = Throw; + exports.Arguments = Arguments; + exports.ASGlobal = ASGlobal; + exports.Projection = Projection; + exports.Region = Region; + exports.Latch = Latch; + exports.Binary = Binary; + exports.Unary = Unary; + exports.Constant = Constant; + exports.ASFindProperty = ASFindProperty; + exports.GlobalProperty = GlobalProperty; + exports.GetProperty = GetProperty; + exports.SetProperty = SetProperty; + exports.CallProperty = CallProperty; + exports.ASCallProperty = ASCallProperty; + exports.ASCallSuper = ASCallSuper; + exports.ASGetProperty = ASGetProperty; + exports.ASGetSuper = ASGetSuper; + exports.ASHasProperty = ASHasProperty; + exports.ASDeleteProperty = ASDeleteProperty; + exports.ASGetDescendants = ASGetDescendants; + exports.ASSetProperty = ASSetProperty; + exports.ASSetSuper = ASSetSuper; + exports.ASGetSlot = ASGetSlot; + exports.ASSetSlot = ASSetSlot; + exports.Call = Call; + exports.ASNew = ASNew; + exports.Phi = Phi; + exports.Stop = Stop; + exports.If = If; + exports.Switch = Switch; + exports.End = End; + exports.Jump = Jump; + exports.ASScope = ASScope; + exports.Operator = Operator; + exports.Variable = Variable; + exports.Move = Move; + exports.Copy = Copy; + exports.Parameter = Parameter; + exports.NewArray = NewArray; + exports.NewObject = NewObject; + exports.ASNewActivation = ASNewActivation; + exports.KeyValuePair = KeyValuePair; + exports.ASMultiname = ASMultiname; + exports.DFG = DFG; + exports.CFG = CFG; + exports.Flags = Flags; + exports.PeepholeOptimizer = PeepholeOptimizer; +}(typeof exports === 'undefined' ? IR = {} : exports)); +var c4Options = systemOptions.register(new OptionSet('C4 Options')); +var enableC4 = c4Options.register(new Option('c4', 'c4', 'boolean', false, 'Enable the C4 compiler.')); +var c4TraceLevel = c4Options.register(new Option('tc4', 'tc4', 'number', 0, 'Compiler Trace Level')); +var enableRegisterAllocator = c4Options.register(new Option('ra', 'ra', 'boolean', false, 'Enable register allocator.')); +var getPublicQualifiedName = Multiname.getPublicQualifiedName; +var createName = function createName(namespaces, name) { + if (isNumeric(name) || isObject(name)) { + return name; + } + return new Multiname(namespaces, name); +}; +(function (exports) { + var Node = IR.Node; + var Start = IR.Start; + var Null = IR.Null; + var Undefined = IR.Undefined; + var This = IR.This; + var Projection = IR.Projection; + var Region = IR.Region; + var Binary = IR.Binary; + var Unary = IR.Unary; + var Constant = IR.Constant; + var Call = IR.Call; + var Phi = IR.Phi; + var Stop = IR.Stop; + var Operator = IR.Operator; + var Parameter = IR.Parameter; + var NewArray = IR.NewArray; + var NewObject = IR.NewObject; + var KeyValuePair = IR.KeyValuePair; + var isConstant = IR.isConstant; + var DFG = IR.DFG; + var CFG = IR.CFG; + var writer = new IndentingWriter(); + var peepholeOptimizer = new IR.PeepholeOptimizer(); + var USE_TYPE_OF_DEFAULT_ARGUMENT_CHECKING = false; + var State = function () { + var nextID = 0; + function constructor(index) { + this.id = nextID += 1; + this.index = index; + this.local = []; + this.stack = []; + this.scope = []; + this.store = Undefined; + this.loads = []; + this.saved = Undefined; + } + constructor.prototype.clone = function clone(index) { + var s = new State(); + s.index = index !== undefined ? index : this.index; + s.local = this.local.slice(0); + s.stack = this.stack.slice(0); + s.scope = this.scope.slice(0); + s.loads = this.loads.slice(0); + s.saved = this.saved; + s.store = this.store; + return s; + }; + constructor.prototype.matches = function matches(other) { + return this.stack.length === other.stack.length && this.scope.length === other.scope.length && this.local.length === other.local.length; + }; + constructor.prototype.makeLoopPhis = function makeLoopPhis(control) { + var s = new State(); + true; + function makePhi(x) { + var phi = new Phi(control, x); + phi.isLoop = true; + return phi; + } + s.index = this.index; + s.local = this.local.map(makePhi); + s.stack = this.stack.map(makePhi); + s.scope = this.scope.map(makePhi); + s.loads = this.loads.slice(0); + s.saved = this.saved; + s.store = makePhi(this.store); + return s; + }; + constructor.prototype.optimize = function optimize() { + function optimize(x) { + if (x instanceof Phi && !x.isLoop) { + var args = x.args.unique(); + if (args.length === 1) { + x.seal(); + Counter.count('Builder: OptimizedPhi'); + return args[0]; + } + } + return x; + } + this.local = this.local.map(optimize); + this.stack = this.stack.map(optimize); + this.scope = this.scope.map(optimize); + this.saved = optimize(this.saved); + this.store = optimize(this.store); + }; + function mergeValue(control, a, b) { + var phi = a instanceof Phi && a.control === control ? a : new Phi(control, a); + phi.pushValue(b); + return phi; + } + function mergeValues(control, a, b) { + for (var i = 0; i < a.length; i++) { + a[i] = mergeValue(control, a[i], b[i]); + } + } + constructor.prototype.merge = function merge(control, other) { + true; + true; + mergeValues(control, this.local, other.local); + mergeValues(control, this.stack, other.stack); + mergeValues(control, this.scope, other.scope); + this.store = mergeValue(control, this.store, other.store); + this.store.abstract = true; + }; + constructor.prototype.trace = function trace(writer) { + writer.writeLn(this.toString()); + }; + function toBriefString(x) { + if (x instanceof Node) { + return x.toString(true); + } + return x; + } + constructor.prototype.toString = function () { + return '<' + String(this.id + ' @ ' + this.index).padRight(' ', 10) + (' M: ' + toBriefString(this.store)).padRight(' ', 14) + (' X: ' + toBriefString(this.saved)).padRight(' ', 14) + (' $: ' + this.scope.map(toBriefString).join(', ')).padRight(' ', 20) + (' L: ' + this.local.map(toBriefString).join(', ')).padRight(' ', 40) + (' S: ' + this.stack.map(toBriefString).join(', ')).padRight(' ', 60); + }; + return constructor; + }(); + function isNumericConstant(node) { + return node instanceof Constant && isNumeric(node.value); + } + function isStringConstant(node) { + return node instanceof Constant && isString(node.value); + } + function isMultinameConstant(node) { + return node instanceof Constant && node.value instanceof Multiname; + } + function hasNumericType(node) { + if (isNumericConstant(node)) { + return true; + } + return node.ty && node.ty.isNumeric(); + } + function typesAreEqual(a, b) { + if (hasNumericType(a) && hasNumericType(b) || hasStringType(a) && hasStringType(b)) { + return true; + } + return false; + } + function hasStringType(node) { + if (isStringConstant(node)) { + return true; + } + return node.ty && node.ty.isString(); + } + function constant(value) { + return new Constant(value); + } + function qualifiedNameConstant(name) { + return constant(Multiname.getQualifiedName(name)); + } + function getJSPropertyWithState(state, object, path) { + true; + var names = path.split('.'); + var node = object; + for (var i = 0; i < names.length; i++) { + node = new IR.GetProperty(null, state.store, node, constant(names[i])); + node.shouldFloat = true; + state.loads.push(node); + } + return node; + } + function globalProperty(name) { + var node = new IR.GlobalProperty(name); + node.mustFloat = true; + return node; + } + function warn(message) { + } + function unary(operator, argument) { + var node = new Unary(operator, argument); + if (peepholeOptimizer) { + node = peepholeOptimizer.tryFold(node); + } + return node; + } + function binary(operator, left, right) { + var node = new Binary(operator, left, right); + if (left.ty && left.ty !== Type.Any && left.ty === right.ty) { + if (operator === Operator.EQ) { + node.operator = Operator.SEQ; + } else if (operator === Operator.NE) { + node.operator = Operator.SNE; + } + } + if (peepholeOptimizer) { + node = peepholeOptimizer.tryFold(node); + } + return node; + } + function coerceInt(value) { + return binary(Operator.OR, value, constant(0)); + } + function coerceUint(value) { + return binary(Operator.URSH, value, constant(0)); + } + function coerceNumber(value) { + if (hasNumericType(value)) { + return value; + } + return unary(Operator.PLUS, value); + } + function coerceBoolean(value) { + return unary(Operator.FALSE, unary(Operator.FALSE, value)); + } + function shouldNotFloat(node) { + node.shouldNotFloat = true; + return node; + } + function shouldFloat(node) { + true; + node.shouldFloat = true; + return node; + } + function mustFloat(node) { + node.mustFloat = true; + return node; + } + function callPure(callee, object, args) { + return new Call(null, null, callee, object, args, IR.Flags.PRISTINE); + } + function callGlobalProperty(name, value) { + return callPure(globalProperty(name), null, [ + value + ]); + } + function convertString(value) { + if (isStringConstant(value)) { + return value; + } + return callPure(globalProperty('String'), null, [ + value + ]); + } + function coerceString(value) { + if (isStringConstant(value)) { + return value; + } + return callPure(globalProperty('asCoerceString'), null, [ + value + ]); + } + var coerceObject = callGlobalProperty.bind(null, 'asCoerceObject'); + var coercers = createEmptyObject(); + coercers[Multiname.Int] = coerceInt; + coercers[Multiname.Uint] = coerceUint; + coercers[Multiname.Number] = coerceNumber; + coercers[Multiname.String] = coerceString; + coercers[Multiname.Object] = coerceObject; + coercers[Multiname.Boolean] = coerceBoolean; + function getCoercerForType(multiname) { + true; + return coercers[Multiname.getQualifiedName(multiname)]; + } + var callableConstructors = createEmptyObject(); + callableConstructors[Multiname.Int] = coerceInt; + callableConstructors[Multiname.Uint] = coerceUint; + callableConstructors[Multiname.Number] = callGlobalProperty.bind(null, 'Number'); + callableConstructors[Multiname.String] = callGlobalProperty.bind(null, 'String'); + callableConstructors[Multiname.Object] = callGlobalProperty.bind(null, 'Object'); + callableConstructors[Multiname.Boolean] = callGlobalProperty.bind(null, 'Boolean'); + function getCallableConstructorForType(multiname) { + true; + return callableConstructors[Multiname.getQualifiedName(multiname)]; + } + var Builder = function () { + function builder(methodInfo, scope, hasDynamicScope) { + true; + this.abc = methodInfo.abc; + this.scope = scope; + this.methodInfo = methodInfo; + this.hasDynamicScope = hasDynamicScope; + } + builder.prototype.buildStart = function (start) { + var mi = this.methodInfo; + var state = start.entryState = new State(0); + state.local.push(new This(start)); + var parameterIndexOffset = this.hasDynamicScope ? 1 : 0; + var parameterCount = mi.parameters.length; + for (var i = 0; i < parameterCount; i++) { + state.local.push(new Parameter(start, parameterIndexOffset + i, mi.parameters[i].name)); + } + for (var i = parameterCount; i < mi.localCount; i++) { + state.local.push(Undefined); + } + state.store = new Projection(start, Projection.Type.STORE); + if (this.hasDynamicScope) { + start.scope = new Parameter(start, 0, SAVED_SCOPE_NAME); + } else { + start.scope = new Constant(this.scope); + } + state.saved = new Projection(start, Projection.Type.SCOPE); + start.domain = new Constant(this.domain); + var args = new IR.Arguments(start); + if (mi.needsRest() || mi.needsArguments()) { + var offset = constant(parameterIndexOffset + (mi.needsRest() ? parameterCount : 0)); + state.local[parameterCount + 1] = new Call(start, state.store, globalProperty('sliceArguments'), null, [ + args, + offset + ], IR.Flags.PRISTINE); + } + var argumentsLength = getJSPropertyWithState(state, args, 'length'); + for (var i = 0; i < parameterCount; i++) { + var parameter = mi.parameters[i]; + var index = i + 1; + var local = state.local[index]; + if (parameter.value !== undefined) { + var condition; + if (USE_TYPE_OF_DEFAULT_ARGUMENT_CHECKING) { + condition = new IR.Binary(Operator.SEQ, new IR.Unary(Operator.TYPE_OF, local), constant('undefined')); + } else { + condition = new IR.Binary(Operator.LT, argumentsLength, constant(parameterIndexOffset + i + 1)); + } + local = new IR.Latch(null, condition, constant(parameter.value), local); + } + if (parameter.type && !parameter.type.isAnyName()) { + var coercer = getCoercerForType(parameter.type); + if (coercer) { + local = coercer(local); + } else if (c4CoerceNonPrimitiveParameters) { + local = new Call(start, state.store, globalProperty('asCoerceByMultiname'), null, [ + constant(this.abc.applicationDomain), + constant(parameter.type), + local + ], true); + } + } + state.local[index] = local; + } + return start; + }; + builder.prototype.buildGraph = function buildGraph(callerRegion, callerState, inlineArguments) { + var analysis = this.methodInfo.analysis; + var blocks = analysis.blocks; + var bytecodes = analysis.bytecodes; + var methodInfo = this.methodInfo; + var ints = this.abc.constantPool.ints; + var uints = this.abc.constantPool.uints; + var doubles = this.abc.constantPool.doubles; + var strings = this.abc.constantPool.strings; + var methods = this.abc.methods; + var classes = this.abc.classes; + var multinames = this.abc.constantPool.multinames; + var domain = new Constant(this.abc.applicationDomain); + var traceBuilder = c4TraceLevel.value > 2; + var stopPoints = []; + for (var i = 0; i < blocks.length; i++) { + blocks[i].blockDominatorOrder = i; + } + var worklist = new Shumway.SortedList(function compare(a, b) { + return a.block.blockDominatorOrder - b.block.blockDominatorOrder; + }); + var start = new Start(null); + this.buildStart(start); + var createFunctionCallee = globalProperty('createFunction'); + worklist.push({ + region: start, + block: blocks[0] + }); + var next; + while (next = worklist.pop()) { + buildBlock(next.region, next.block, next.region.entryState.clone()).forEach(function (stop) { + var target = stop.target; + var region = target.region; + if (region) { + traceBuilder && writer.enter('Merging into region: ' + region + ' @ ' + target.position + ', block ' + target.bid + ' {'); + traceBuilder && writer.writeLn(' R ' + region.entryState); + traceBuilder && writer.writeLn('+ I ' + stop.state); + region.entryState.merge(region, stop.state); + region.predecessors.push(stop.control); + traceBuilder && writer.writeLn(' = ' + region.entryState); + traceBuilder && writer.leave('}'); + } else { + region = target.region = new Region(stop.control); + if (target.loop) { + traceBuilder && writer.writeLn('Adding PHIs to loop region.'); + } + region.entryState = target.loop ? stop.state.makeLoopPhis(region) : stop.state.clone(target.position); + traceBuilder && writer.writeLn('Adding new region: ' + region + ' @ ' + target.position + ' to worklist.'); + worklist.push({ + region: region, + block: target + }); + } + }); + traceBuilder && writer.enter('Worklist: {'); + worklist.forEach(function (item) { + traceBuilder && writer.writeLn(item.region + ' ' + item.block.bdo + ' ' + item.region.entryState); + }); + traceBuilder && writer.leave('}'); + } + traceBuilder && writer.writeLn('Done'); + function buildBlock(region, block, state) { + true; + state.optimize(); + var typeState = block.entryState; + if (typeState) { + traceBuilder && writer.writeLn('Type State: ' + typeState); + for (var i = 0; i < typeState.local.length; i++) { + var type = typeState.local[i]; + var local = state.local[i]; + if (local.ty) { + } else { + local.ty = type; + } + } + } + var local = state.local; + var stack = state.stack; + var scope = state.scope; + function savedScope() { + return state.saved; + } + function topScope(depth) { + if (depth !== undefined) { + if (depth < scope.length) { + return scope[scope.length - 1 - depth]; + } else if (depth === scope.length) { + return savedScope(); + } else { + var s = savedScope(); + var savedScopeDepth = depth - scope.length; + for (var i = 0; i < savedScopeDepth; i++) { + s = getJSProperty(s, 'parent'); + } + return s; + } + } + if (scope.length > 0) { + return scope.top(); + } + return savedScope(); + } + var object, receiver, index, callee, value, multiname, type, args, pristine, left, right, operator; + function push(x) { + true; + if (bc.ti) { + if (x.ty) { + } else { + x.ty = bc.ti.type; + } + } + stack.push(x); + } + function pop() { + return stack.pop(); + } + function popMany(count) { + return stack.popMany(count); + } + function pushLocal(index) { + push(local[index]); + } + function popLocal(index) { + local[index] = shouldNotFloat(pop()); + } + function buildMultiname(index) { + var multiname = multinames[index]; + var namespaces, name, flags = multiname.flags; + if (multiname.isRuntimeName()) { + name = stack.pop(); + } else { + name = constant(multiname.name); + } + if (multiname.isRuntimeNamespace()) { + namespaces = shouldFloat(new NewArray(region, [ + pop() + ])); + } else { + namespaces = constant(multiname.namespaces); + } + return new IR.ASMultiname(namespaces, name, flags); + } + function simplifyName(name) { + if (isMultinameConstant(name) && Multiname.isQName(name.value)) { + return constant(Multiname.getQualifiedName(name.value)); + } + return name; + } + function getGlobalScope(ti) { + if (ti && ti.object) { + return constant(ti.object); + } + return new IR.ASGlobal(null, savedScope()); + } + function findProperty(multiname, strict, ti) { + var slowPath = new IR.ASFindProperty(region, state.store, topScope(), multiname, domain, strict); + if (ti) { + if (ti.object) { + if (ti.object instanceof Global && !ti.object.isExecuting()) { + warn('Can\'t optimize findProperty ' + multiname + ', global object is not yet executed or executing.'); + return slowPath; + } + return constant(ti.object); + } else if (ti.scopeDepth !== undefined) { + return getScopeObject(topScope(ti.scopeDepth)); + } + } + warn('Can\'t optimize findProperty ' + multiname); + return slowPath; + } + function getJSProperty(object, path) { + return getJSPropertyWithState(state, object, path); + } + function coerce(multiname, value) { + if (false && isConstant(value)) { + return constant(asCoerceByMultiname(domain.value, multiname, value.value)); + } else { + var coercer = getCoercerForType(multiname); + if (coercer) { + return coercer(value); + } + } + if (c4CoerceNonPrimitive) { + return call(globalProperty('asCoerceByMultiname'), null, [ + domain, + constant(multiname), + value + ]); + } + return value; + } + function getScopeObject(scope) { + if (scope instanceof IR.ASScope) { + return scope.object; + } + return getJSProperty(scope, 'object'); + } + function store(node) { + state.store = new Projection(node, Projection.Type.STORE); + node.loads = state.loads.slice(0); + state.loads.length = 0; + return node; + } + function load(node) { + state.loads.push(node); + return node; + } + function resolveMultinameGlobally(multiname) { + var namespaces = multiname.namespaces; + var name = multiname.name; + if (!Shumway.AVM2.Runtime.globalMultinameAnalysis.value) { + return; + } + if (!isConstant(namespaces) || !isConstant(name) || multiname.isAttribute()) { + Counter.count('GlobalMultinameResolver: Cannot resolve runtime multiname or attribute.'); + return; + } + if (isNumeric(name.value) || !isString(name.value) || !name.value) { + Counter.count('GlobalMultinameResolver: Cannot resolve numeric or any names.'); + return false; + } + return GlobalMultinameResolver.resolveMultiname(new Multiname(namespaces.value, name.value, multiname.flags)); + } + function callSuper(scope, object, multiname, args, ti) { + if (ti && ti.trait && ti.trait.isMethod() && ti.baseClass) { + var qn = VM_OPEN_METHOD_PREFIX + Multiname.getQualifiedName(ti.trait.name); + var callee = getJSProperty(constant(ti.baseClass), 'traitsPrototype.' + qn); + return call(callee, object, args); + } + return store(new IR.ASCallSuper(region, state.store, object, multiname, args, IR.Flags.PRISTINE, scope)); + } + function getSuper(scope, object, multiname, ti) { + if (ti && ti.trait && ti.trait.isGetter() && ti.baseClass) { + var qn = VM_OPEN_GET_METHOD_PREFIX + Multiname.getQualifiedName(ti.trait.name); + var callee = getJSProperty(constant(ti.baseClass), 'traitsPrototype.' + qn); + return call(callee, object, []); + } + return store(new IR.ASGetSuper(region, state.store, object, multiname, scope)); + } + function setSuper(scope, object, multiname, value, ti) { + if (ti && ti.trait && ti.trait.isSetter() && ti.baseClass) { + var qn = VM_OPEN_SET_METHOD_PREFIX + Multiname.getQualifiedName(ti.trait.name); + var callee = getJSProperty(constant(ti.baseClass), 'traitsPrototype.' + qn); + return call(callee, object, [ + value + ]); + } + return store(new IR.ASSetSuper(region, state.store, object, multiname, value, scope)); + } + function constructSuper(scope, object, args, ti) { + if (ti) { + if (ti.noCallSuperNeeded) { + return; + } else if (ti.baseClass) { + var callee = getJSProperty(constant(ti.baseClass), 'instanceConstructorNoInitialize'); + call(callee, object, args); + return; + } + } + callee = getJSProperty(scope, 'object.baseClass.instanceConstructorNoInitialize'); + call(callee, object, args); + return; + } + function callProperty(object, multiname, args, isLex, ti) { + if (ti && ti.trait) { + if (ti.trait.isMethod()) { + var openQn; + if (ti.trait.holder instanceof InstanceInfo && ti.trait.holder.isInterface()) { + openQn = Multiname.getPublicQualifiedName(Multiname.getName(ti.trait.name)); + } else { + openQn = Multiname.getQualifiedName(ti.trait.name); + } + openQn = VM_OPEN_METHOD_PREFIX + openQn; + return store(new IR.CallProperty(region, state.store, object, constant(openQn), args, IR.Flags.PRISTINE)); + } else if (ti.trait.isClass()) { + var constructor = getCallableConstructorForType(ti.trait.name); + if (constructor) { + return constructor(args[0]); + } + var qn = Multiname.getQualifiedName(ti.trait.name); + return store(new IR.CallProperty(region, state.store, object, constant(qn), args, 0)); + } + } else if (ti && ti.propertyQName) { + return store(new IR.CallProperty(region, state.store, object, constant(ti.propertyQName), args, IR.Flags.PRISTINE)); + } + var qn = resolveMultinameGlobally(multiname); + if (qn) { + return store(new IR.ASCallProperty(region, state.store, object, constant(Multiname.getQualifiedName(qn)), args, IR.Flags.PRISTINE | IR.Flags.RESOLVED, isLex)); + } + return store(new IR.ASCallProperty(region, state.store, object, multiname, args, IR.Flags.PRISTINE, isLex)); + } + function getProperty(object, multiname, ti, getOpenMethod) { + true; + getOpenMethod = !(!getOpenMethod); + if (ti) { + if (ti.trait) { + if (ti.trait.isConst() && ti.trait.hasDefaultValue) { + return constant(ti.trait.value); + } + var get = new IR.GetProperty(region, state.store, object, qualifiedNameConstant(ti.trait.name)); + return ti.trait.isGetter() ? store(get) : load(get); + } + if (ti.propertyQName) { + return store(new IR.GetProperty(region, state.store, object, constant(ti.propertyQName))); + } else if (ti.isDirectlyReadable) { + return store(new IR.GetProperty(region, state.store, object, multiname.name)); + } else if (ti.isIndexedReadable) { + return store(new IR.ASGetProperty(region, state.store, object, multiname, IR.Flags.INDEXED | (getOpenMethod ? IR.Flagas.IS_METHOD : 0))); + } + } + warn('Can\'t optimize getProperty ' + multiname); + var qn = resolveMultinameGlobally(multiname); + if (qn) { + return store(new IR.ASGetProperty(region, state.store, object, constant(Multiname.getQualifiedName(qn)), IR.Flags.RESOLVED | (getOpenMethod ? IR.Flagas.IS_METHOD : 0))); + } + Counter.count('Compiler: Slow ASGetProperty'); + return store(new IR.ASGetProperty(region, state.store, object, multiname, getOpenMethod ? IR.Flagas.IS_METHOD : 0)); + } + function setProperty(object, multiname, value, ti) { + true; + if (ti) { + if (ti.trait) { + var coercer = ti.trait.typeName ? getCoercerForType(ti.trait.typeName) : null; + if (coercer) { + value = coercer(value); + } + store(new IR.SetProperty(region, state.store, object, qualifiedNameConstant(ti.trait.name), value)); + return; + } + if (ti.propertyQName) { + return store(new IR.SetProperty(region, state.store, object, constant(ti.propertyQName), value)); + } else if (ti.isDirectlyWriteable) { + return store(new IR.SetProperty(region, state.store, object, multiname.name, value)); + } else if (ti.isIndexedWriteable) { + return store(new IR.ASSetProperty(region, state.store, object, multiname, value, IR.Flags.INDEXED)); + } + } + warn('Can\'t optimize setProperty ' + multiname); + var qn = resolveMultinameGlobally(multiname); + if (qn) { + } + return store(new IR.ASSetProperty(region, state.store, object, multiname, value, 0)); + } + function getDescendants(object, name, ti) { + name = simplifyName(name); + return new IR.ASGetDescendants(region, state.store, object, name); + } + function getSlot(object, index, ti) { + if (ti) { + var trait = ti.trait; + if (trait) { + if (trait.isConst() && ti.trait.hasDefaultValue) { + return constant(trait.value); + } + var slotQn = Multiname.getQualifiedName(trait.name); + return store(new IR.GetProperty(region, state.store, object, constant(slotQn))); + } + } + warn('Can\'t optimize getSlot ' + index); + return store(new IR.ASGetSlot(null, state.store, object, index)); + } + function setSlot(object, index, value, ti) { + if (ti) { + var trait = ti.trait; + if (trait) { + var slotQn = Multiname.getQualifiedName(trait.name); + store(new IR.SetProperty(region, state.store, object, constant(slotQn), value)); + return; + } + } + warn('Can\'t optimize setSlot ' + index); + store(new IR.ASSetSlot(region, state.store, object, index, value)); + } + function call(callee, object, args) { + return store(new Call(region, state.store, callee, object, args, IR.Flags.PRISTINE)); + } + function callCall(callee, object, args, pristine) { + return store(new Call(region, state.store, callee, object, args, pristine ? IR.Flags.PRISTINE : 0)); + } + function truthyCondition(operator) { + var right; + if (operator.isBinary()) { + right = pop(); + } + var left = pop(); + var node; + if (right) { + node = binary(operator, left, right); + } else { + node = unary(operator, left); + } + if (peepholeOptimizer) { + node = peepholeOptimizer.tryFold(node, true); + } + return node; + } + function negatedTruthyCondition(operator) { + var node = unary(Operator.FALSE, truthyCondition(operator)); + if (peepholeOptimizer) { + node = peepholeOptimizer.tryFold(node, true); + } + return node; + } + function pushExpression(operator, toInt) { + var left, right; + if (operator.isBinary()) { + right = pop(); + left = pop(); + if (toInt) { + right = coerceInt(right); + left = coerceInt(left); + } + push(binary(operator, left, right)); + } else { + left = pop(); + if (toInt) { + left = coerceInt(left); + } + push(unary(operator, left)); + } + } + var stops = null; + function buildIfStops(predicate) { + true; + var _if = new IR.If(region, predicate); + stops = [ + { + control: new Projection(_if, Projection.Type.FALSE), + target: bytecodes[bc.position + 1], + state: state + }, + { + control: new Projection(_if, Projection.Type.TRUE), + target: bc.target, + state: state + } + ]; + } + function buildJumpStop() { + true; + stops = [ + { + control: region, + target: bc.target, + state: state + } + ]; + } + function buildThrowStop() { + true; + stops = []; + } + function buildReturnStop() { + true; + stops = []; + } + function buildSwitchStops(determinant) { + true; + if (bc.targets.length > 2) { + stops = []; + var _switch = new IR.Switch(region, determinant); + for (var i = 0; i < bc.targets.length; i++) { + stops.push({ + control: new Projection(_switch, Projection.Type.CASE, constant(i)), + target: bc.targets[i], + state: state + }); + } + } else { + true; + var predicate = binary(Operator.SEQ, determinant, constant(0)); + var _if = new IR.If(region, predicate); + stops = [ + { + control: new Projection(_if, Projection.Type.FALSE), + target: bc.targets[1], + state: state + }, + { + control: new Projection(_if, Projection.Type.TRUE), + target: bc.targets[0], + state: state + } + ]; + } + } + if (traceBuilder) { + writer.writeLn('Processing Region: ' + region + ', Block: ' + block.bid); + writer.enter(('> state: ' + region.entryState.toString()).padRight(' ', 100)); + } + region.processed = true; + var bc; + for (var bci = block.position, end = block.end.position; bci <= end; bci++) { + bc = bytecodes[bci]; + var op = bc.op; + state.index = bci; + switch (op) { + case 3: + store(new IR.Throw(region, pop())); + stopPoints.push({ + region: region, + store: state.store, + value: Undefined + }); + buildThrowStop(); + break; + case 98: + pushLocal(bc.index); + break; + case 208: + case 209: + case 210: + case 211: + pushLocal(op - OP_getlocal0); + break; + case 99: + popLocal(bc.index); + break; + case 212: + case 213: + case 214: + case 215: + popLocal(op - OP_setlocal0); + break; + case 28: + scope.push(new IR.ASScope(topScope(), pop(), true)); + break; + case 48: + scope.push(new IR.ASScope(topScope(), pop(), false)); + break; + case 29: + scope.pop(); + break; + case 100: + push(getGlobalScope(bc.ti)); + break; + case 101: + push(getScopeObject(state.scope[bc.index])); + break; + case 93: + push(findProperty(buildMultiname(bc.index), true, bc.ti)); + break; + case 94: + push(findProperty(buildMultiname(bc.index), false, bc.ti)); + break; + case 102: + multiname = buildMultiname(bc.index); + object = pop(); + push(getProperty(object, multiname, bc.ti, false)); + break; + case 89: + multiname = buildMultiname(bc.index); + object = pop(); + push(getDescendants(object, multiname, bc.ti)); + break; + case 96: + multiname = buildMultiname(bc.index); + push(getProperty(findProperty(multiname, true, bc.ti), multiname, bc.ti, false)); + break; + case 104: + case 97: + value = pop(); + multiname = buildMultiname(bc.index); + object = pop(); + setProperty(object, multiname, value, bc.ti); + break; + case 106: + multiname = buildMultiname(bc.index); + object = pop(); + push(store(new IR.ASDeleteProperty(region, state.store, object, multiname))); + break; + case 108: + object = pop(); + push(getSlot(object, constant(bc.index), bc.ti)); + break; + case 109: + value = pop(); + object = pop(); + setSlot(object, constant(bc.index), value, bc.ti); + break; + case 4: + multiname = buildMultiname(bc.index); + object = pop(); + push(getSuper(savedScope(), object, multiname, bc.ti)); + break; + case 5: + value = pop(); + multiname = buildMultiname(bc.index); + object = pop(); + setSuper(savedScope(), object, multiname, value, bc.ti); + break; + case 241: + case 240: + break; + case 64: + push(callPure(createFunctionCallee, null, [ + constant(methods[bc.index]), + topScope(), + constant(true) + ])); + break; + case 65: + args = popMany(bc.argCount); + object = pop(); + callee = pop(); + push(callCall(callee, object, args)); + break; + case 70: + case 79: + case 76: + args = popMany(bc.argCount); + multiname = buildMultiname(bc.index); + object = pop(); + value = callProperty(object, multiname, args, op === OP_callproplex, bc.ti); + if (op !== OP_callpropvoid) { + push(value); + } + break; + case 69: + case 78: + multiname = buildMultiname(bc.index); + args = popMany(bc.argCount); + object = pop(); + value = callSuper(savedScope(), object, multiname, args, bc.ti); + if (op !== OP_callsupervoid) { + push(value); + } + break; + case 66: + args = popMany(bc.argCount); + object = pop(); + push(store(new IR.ASNew(region, state.store, object, args))); + break; + case 73: + args = popMany(bc.argCount); + object = pop(); + constructSuper(savedScope(), object, args, bc.ti); + break; + case 74: + args = popMany(bc.argCount); + multiname = buildMultiname(bc.index); + object = pop(); + callee = getProperty(object, multiname, bc.ti, false); + push(store(new IR.ASNew(region, state.store, callee, args))); + break; + case 128: + if (bc.ti && bc.ti.noCoercionNeeded) { + Counter.count('Compiler: NoCoercionNeeded'); + break; + } else { + Counter.count('Compiler: CoercionNeeded'); + } + value = pop(); + push(coerce(multinames[bc.index], value)); + break; + case 131: + case 115: + push(coerceInt(pop())); + break; + case 136: + case 116: + push(coerceUint(pop())); + break; + case 132: + case 117: + push(coerceNumber(pop())); + break; + case 129: + case 118: + push(coerceBoolean(pop())); + break; + case 120: + push(call(globalProperty('checkFilter'), null, [ + pop() + ])); + break; + case 130: + break; + case 133: + push(coerceString(pop())); + break; + case 112: + push(convertString(pop())); + break; + case 135: + type = pop(); + if (c4AsTypeLate) { + value = pop(); + push(call(globalProperty('asAsType'), null, [ + type, + value + ])); + } + break; + case 72: + case 71: + value = Undefined; + if (op === OP_returnvalue) { + value = pop(); + if (methodInfo.returnType) { + if (!(bc.ti && bc.ti.noCoercionNeeded)) { + value = coerce(methodInfo.returnType, value); + } + } + } + stopPoints.push({ + region: region, + store: state.store, + value: value + }); + buildReturnStop(); + break; + case 30: + case 35: + index = pop(); + object = pop(); + push(new IR.CallProperty(region, state.store, object, constant(op === OP_nextname ? 'asNextName' : 'asNextValue'), [ + index + ], IR.Flags.PRISTINE)); + break; + case 50: + var temp = call(globalProperty('asHasNext2'), null, [ + local[bc.object], + local[bc.index] + ]); + local[bc.object] = getJSProperty(temp, 'object'); + push(local[bc.index] = getJSProperty(temp, 'index')); + break; + case 32: + push(Null); + break; + case 33: + push(Undefined); + break; + case 34: + notImplemented(); + break; + case 36: + push(constant(bc.value)); + break; + case 37: + push(constant(bc.value)); + break; + case 44: + push(constant(strings[bc.index])); + break; + case 45: + push(constant(ints[bc.index])); + break; + case 46: + push(constant(uints[bc.index])); + break; + case 47: + push(constant(doubles[bc.index])); + break; + case 38: + push(constant(true)); + break; + case 39: + push(constant(false)); + break; + case 40: + push(constant(NaN)); + break; + case 41: + pop(); + break; + case 42: + value = shouldNotFloat(pop()); + push(value); + push(value); + break; + case 43: + state.stack.push(pop(), pop()); + break; + case 239: + case OP_debugline: + case OP_debugfile: + break; + case 12: + buildIfStops(negatedTruthyCondition(Operator.LT)); + break; + case 24: + buildIfStops(truthyCondition(Operator.GE)); + break; + case 13: + buildIfStops(negatedTruthyCondition(Operator.LE)); + break; + case 23: + buildIfStops(truthyCondition(Operator.GT)); + break; + case 14: + buildIfStops(negatedTruthyCondition(Operator.GT)); + break; + case 22: + buildIfStops(truthyCondition(Operator.LE)); + break; + case 15: + buildIfStops(negatedTruthyCondition(Operator.GE)); + break; + case 21: + buildIfStops(truthyCondition(Operator.LT)); + break; + case 16: + buildJumpStop(); + break; + case 17: + buildIfStops(truthyCondition(Operator.TRUE)); + break; + case 18: + buildIfStops(truthyCondition(Operator.FALSE)); + break; + case 19: + buildIfStops(truthyCondition(Operator.EQ)); + break; + case 20: + buildIfStops(truthyCondition(Operator.NE)); + break; + case 25: + buildIfStops(truthyCondition(Operator.SEQ)); + break; + case 26: + buildIfStops(truthyCondition(Operator.SNE)); + break; + case 27: + buildSwitchStops(pop()); + break; + case 150: + pushExpression(Operator.FALSE); + break; + case 151: + pushExpression(Operator.BITWISE_NOT); + break; + case 160: + right = pop(); + left = pop(); + if (typesAreEqual(left, right)) { + operator = Operator.ADD; + } else if (Shumway.AVM2.Runtime.useAsAdd) { + operator = Operator.AS_ADD; + } else { + operator = Operator.ADD; + } + push(binary(operator, left, right)); + break; + case 197: + pushExpression(Operator.ADD, true); + break; + case 161: + pushExpression(Operator.SUB); + break; + case 198: + pushExpression(Operator.SUB, true); + break; + case 162: + pushExpression(Operator.MUL); + break; + case 199: + pushExpression(Operator.MUL, true); + break; + case 163: + pushExpression(Operator.DIV); + break; + case 164: + pushExpression(Operator.MOD); + break; + case 165: + pushExpression(Operator.LSH); + break; + case 166: + pushExpression(Operator.RSH); + break; + case 167: + pushExpression(Operator.URSH); + break; + case 168: + pushExpression(Operator.AND); + break; + case 169: + pushExpression(Operator.OR); + break; + case 170: + pushExpression(Operator.XOR); + break; + case 171: + pushExpression(Operator.EQ); + break; + case 172: + pushExpression(Operator.SEQ); + break; + case 173: + pushExpression(Operator.LT); + break; + case 174: + pushExpression(Operator.LE); + break; + case 175: + pushExpression(Operator.GT); + break; + case 176: + pushExpression(Operator.GE); + break; + case 144: + pushExpression(Operator.NEG); + break; + case 196: + pushExpression(Operator.NEG, true); + break; + case 145: + case 192: + case 147: + case 193: + push(constant(1)); + if (op === OP_increment || op === OP_decrement) { + push(coerceNumber(pop())); + } else { + push(coerceInt(pop())); + } + if (op === OP_increment || op === OP_increment_i) { + pushExpression(Operator.ADD); + } else { + pushExpression(Operator.SUB); + } + break; + case 146: + case 194: + case 148: + case 195: + push(constant(1)); + if (op === OP_inclocal || op === OP_declocal) { + push(coerceNumber(local[bc.index])); + } else { + push(coerceInt(local[bc.index])); + } + if (op === OP_inclocal || op === OP_inclocal_i) { + pushExpression(Operator.ADD); + } else { + pushExpression(Operator.SUB); + } + popLocal(bc.index); + break; + case 177: + type = pop(); + value = pop(); + push(call(getJSProperty(type, 'isInstanceOf'), null, [ + value + ])); + break; + case 178: + value = pop(); + multiname = buildMultiname(bc.index); + type = getProperty(findProperty(multiname, false), multiname); + push(call(globalProperty('asIsType'), null, [ + type, + value + ])); + break; + case 179: + type = pop(); + value = pop(); + push(call(globalProperty('asIsType'), null, [ + type, + value + ])); + break; + case 180: + object = pop(); + value = pop(); + multiname = new IR.ASMultiname(Undefined, value, 0); + push(store(new IR.ASHasProperty(region, state.store, object, multiname))); + break; + case 149: + push(call(globalProperty('asTypeOf'), null, [ + pop() + ])); + break; + case 8: + push(Undefined); + popLocal(bc.index); + break; + case 83: + args = popMany(bc.argCount); + type = pop(); + callee = globalProperty('applyType'); + push(call(callee, null, [ + domain, + type, + new NewArray(region, args) + ])); + break; + case 86: + args = popMany(bc.argCount); + push(new NewArray(region, args)); + break; + case 85: + var properties = []; + for (var i = 0; i < bc.argCount; i++) { + var value = pop(); + var key = pop(); + true; + key = constant(Multiname.getPublicQualifiedName(key.value)); + properties.push(new KeyValuePair(key, value)); + } + push(new NewObject(region, properties)); + break; + case 87: + push(new IR.ASNewActivation(constant(methodInfo))); + break; + case 88: + callee = globalProperty('createClass'); + push(call(callee, null, [ + constant(classes[bc.index]), + pop(), + topScope() + ])); + break; + default: + unexpected('Not Implemented: ' + bc); + } + if (op === OP_debug || op === OP_debugfile || op === OP_debugline) { + continue; + } + if (traceBuilder) { + writer.writeLn(('state: ' + state.toString()).padRight(' ', 100) + ' : ' + bci + ', ' + bc.toString(this.abc)); + } + } + if (traceBuilder) { + writer.leave(('< state: ' + state.toString()).padRight(' ', 100)); + } + if (!stops) { + stops = []; + if (bc.position + 1 <= bytecodes.length) { + stops.push({ + control: region, + target: bytecodes[bc.position + 1], + state: state + }); + } + } + return stops; + } + var stop; + if (stopPoints.length > 1) { + var stopRegion = new Region(null); + var stopValuePhi = new Phi(stopRegion, null); + var stopStorePhi = new Phi(stopRegion, null); + stopPoints.forEach(function (stopPoint) { + stopRegion.predecessors.push(stopPoint.region); + stopValuePhi.pushValue(stopPoint.value); + stopStorePhi.pushValue(stopPoint.store); + }); + stop = new Stop(stopRegion, stopStorePhi, stopValuePhi); + } else { + stop = new Stop(stopPoints[0].region, stopPoints[0].store, stopPoints[0].value); + } + return new DFG(stop); + }; + return builder; + }(); + function buildMethod(verifier, methodInfo, scope, hasDynamicScope) { + true; + true; + true; + Counter.count('Compiler: Compiled Methods'); + Timer.start('Compiler'); + Timer.start('Mark Loops'); + methodInfo.analysis.markLoops(); + Timer.stop(); + if (Shumway.AVM2.Runtime.enableVerifier.value) { + Timer.start('Verify'); + verifier.verifyMethod(methodInfo, scope); + Timer.stop(); + } + var traceSource = c4TraceLevel.value > 0; + var traceIR = c4TraceLevel.value > 1; + Timer.start('Build IR'); + Node.startNumbering(); + var dfg = new Builder(methodInfo, scope, hasDynamicScope).buildGraph(); + Timer.stop(); + traceIR && dfg.trace(writer); + Timer.start('Build CFG'); + var cfg = dfg.buildCFG(); + Timer.stop(); + Timer.start('Optimize Phis'); + cfg.optimizePhis(); + Timer.stop(); + Timer.start('Schedule Nodes'); + cfg.scheduleEarly(); + Timer.stop(); + traceIR && cfg.trace(writer); + Timer.start('Verify IR'); + cfg.verify(); + Timer.stop(); + Timer.start('Allocate Variables'); + cfg.allocateVariables(); + Timer.stop(); + Timer.start('Generate Source'); + var result = Backend.generate(cfg, enableRegisterAllocator.value); + Timer.stop(); + traceSource && writer.writeLn(result.body); + Node.stopNumbering(); + Timer.stop(); + return result; + } + exports.buildMethod = buildMethod; +}(typeof exports === 'undefined' ? Builder = {} : exports)); +var Compiler = new (function () { + function constructor() { + this.verifier = new Verifier(); + } + constructor.prototype.compileMethod = function (methodInfo, scope, hasDynamicScope) { + return Builder.buildMethod(this.verifier, methodInfo, scope, hasDynamicScope); + }; + return constructor; + }())(); +(function (exports) { + var Control = function () { + var SEQ = 1; + var LOOP = 2; + var IF = 3; + var CASE = 4; + var SWITCH = 5; + var LABEL_CASE = 6; + var LABEL_SWITCH = 7; + var EXIT = 8; + var BREAK = 9; + var CONTINUE = 10; + var TRY = 11; + var CATCH = 12; + function Seq(body) { + this.kind = SEQ; + this.body = body; + } + Seq.prototype = { + trace: function (writer) { + var body = this.body; + for (var i = 0, j = body.length; i < j; i++) { + body[i].trace(writer); + } + }, + first: function () { + return this.body[0]; + }, + slice: function (begin, end) { + return new Seq(this.body.slice(begin, end)); + } + }; + function Loop(body) { + this.kind = LOOP; + this.body = body; + } + Loop.prototype = { + trace: function (writer) { + writer.enter('loop {'); + this.body.trace(writer); + writer.leave('}'); + } + }; + function If(cond, then, els, nothingThrownLabel) { + this.kind = IF; + this.cond = cond; + this.then = then; + this.else = els; + this.negated = false; + this.nothingThrownLabel = nothingThrownLabel; + } + If.prototype = { + trace: function (writer) { + this.cond.trace(writer); + if (this.nothingThrownLabel) { + writer.enter('if (label is ' + this.nothingThrownLabel + ') {'); + } + writer.enter('if' + (this.negated ? ' not' : '') + ' {'); + this.then && this.then.trace(writer); + if (this.else) { + writer.outdent(); + writer.enter('} else {'); + this.else.trace(writer); + } + writer.leave('}'); + if (this.nothingThrownLabel) { + writer.leave('}'); + } + } + }; + function Case(index, body) { + this.kind = CASE; + this.index = index; + this.body = body; + } + Case.prototype = { + trace: function (writer) { + if (this.index >= 0) { + writer.writeLn('case ' + this.index + ':'); + } else { + writer.writeLn('default:'); + } + writer.indent(); + this.body && this.body.trace(writer); + writer.outdent(); + } + }; + function Switch(determinant, cases, nothingThrownLabel) { + this.kind = SWITCH; + this.determinant = determinant; + this.cases = cases; + this.nothingThrownLabel = nothingThrownLabel; + } + Switch.prototype = { + trace: function (writer) { + if (this.nothingThrownLabel) { + writer.enter('if (label is ' + this.nothingThrownLabel + ') {'); + } + this.determinant.trace(writer); + writer.writeLn('switch {'); + for (var i = 0, j = this.cases.length; i < j; i++) { + this.cases[i].trace(writer); + } + writer.writeLn('}'); + if (this.nothingThrownLabel) { + writer.leave('}'); + } + } + }; + function LabelCase(labels, body) { + this.kind = LABEL_CASE; + this.labels = labels; + this.body = body; + } + LabelCase.prototype = { + trace: function (writer) { + writer.enter('if (label is ' + this.labels.join(' or ') + ') {'); + this.body && this.body.trace(writer); + writer.leave('}'); + } + }; + function LabelSwitch(cases) { + var labelMap = {}; + for (var i = 0, j = cases.length; i < j; i++) { + var c = cases[i]; + if (!c.labels) { + print(c.toSource()); + } + for (var k = 0, l = c.labels.length; k < l; k++) { + labelMap[c.labels[k]] = c; + } + } + this.kind = LABEL_SWITCH; + this.cases = cases; + this.labelMap = labelMap; + } + LabelSwitch.prototype = { + trace: function (writer) { + for (var i = 0, j = this.cases.length; i < j; i++) { + this.cases[i].trace(writer); + } + } + }; + function Exit(label) { + this.kind = EXIT; + this.label = label; + } + Exit.prototype = { + trace: function (writer) { + writer.writeLn('label = ' + this.label); + } + }; + function Break(label, head) { + this.kind = BREAK; + this.label = label; + this.head = head; + } + Break.prototype = { + trace: function (writer) { + this.label && writer.writeLn('label = ' + this.label); + writer.writeLn('break'); + } + }; + function Continue(label, head) { + this.kind = CONTINUE; + this.label = label; + this.head = head; + this.necessary = true; + } + Continue.prototype = { + trace: function (writer) { + this.label && writer.writeLn('label = ' + this.label); + this.necessary && writer.writeLn('continue'); + } + }; + function Try(body, catches) { + this.kind = TRY; + this.body = body; + this.catches = catches; + } + Try.prototype = { + trace: function (writer) { + writer.enter('try {'); + this.body.trace(writer); + writer.writeLn('label = ' + this.nothingThrownLabel); + for (var i = 0, j = this.catches.length; i < j; i++) { + this.catches[i].trace(writer); + } + writer.leave('}'); + } + }; + function Catch(varName, typeName, body) { + this.kind = CATCH; + this.varName = varName; + this.typeName = typeName; + this.body = body; + } + Catch.prototype = { + trace: function (writer) { + writer.outdent(); + writer.enter('} catch (' + (this.varName || 'e') + (this.typeName ? ' : ' + this.typeName : '') + ') {'); + this.body.trace(writer); + } + }; + return { + SEQ: SEQ, + LOOP: LOOP, + IF: IF, + CASE: CASE, + SWITCH: SWITCH, + LABEL_CASE: LABEL_CASE, + LABEL_SWITCH: LABEL_SWITCH, + EXIT: EXIT, + BREAK: BREAK, + CONTINUE: CONTINUE, + TRY: TRY, + CATCH: CATCH, + Seq: Seq, + Loop: Loop, + If: If, + Case: Case, + Switch: Switch, + LabelCase: LabelCase, + LabelSwitch: LabelSwitch, + Exit: Exit, + Break: Break, + Continue: Continue, + Try: Try, + Catch: Catch + }; + }(); + var Analysis = function () { + function blockSetClass(length, blockById) { + var BlockSet = BitSetFunctor(length); + var ADDRESS_BITS_PER_WORD = BlockSet.ADDRESS_BITS_PER_WORD; + var BITS_PER_WORD = BlockSet.BITS_PER_WORD; + var BIT_INDEX_MASK = BlockSet.BIT_INDEX_MASK; + BlockSet.singleton = function singleton(b) { + var bs = new BlockSet(); + bs.set(b.id); + bs.count = 1; + bs.dirty = 0; + return bs; + }; + BlockSet.fromBlocks = function fromArray(other) { + var bs = new BlockSet(); + bs.setBlocks(other); + return bs; + }; + var Bsp = BlockSet.prototype; + if (BlockSet.singleword) { + Bsp.forEachBlock = function forEach(fn) { + true; + var byId = blockById; + var word = this.bits; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + fn(byId[k]); + } + } + } + }; + Bsp.choose = function choose() { + var byId = blockById; + var word = this.bits; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + return byId[k]; + } + } + } + }; + Bsp.members = function members() { + var byId = blockById; + var set = []; + var word = this.bits; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + set.push(byId[k]); + } + } + } + return set; + }; + Bsp.setBlocks = function setBlocks(bs) { + var bits = this.bits; + for (var i = 0, j = bs.length; i < j; i++) { + var id = bs[i].id; + bits |= 1 << (id & BIT_INDEX_MASK); + } + this.bits = bits; + }; + } else { + Bsp.forEachBlock = function forEach(fn) { + true; + var byId = blockById; + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var word = bits[i]; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + fn(byId[i * BITS_PER_WORD + k]); + } + } + } + } + }; + Bsp.choose = function choose() { + var byId = blockById; + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var word = bits[i]; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + return byId[i * BITS_PER_WORD + k]; + } + } + } + } + }; + Bsp.members = function members() { + var byId = blockById; + var set = []; + var bits = this.bits; + for (var i = 0, j = bits.length; i < j; i++) { + var word = bits[i]; + if (word) { + for (var k = 0; k < BITS_PER_WORD; k++) { + if (word & 1 << k) { + set.push(byId[i * BITS_PER_WORD + k]); + } + } + } + } + return set; + }; + Bsp.setBlocks = function setBlocks(bs) { + var bits = this.bits; + for (var i = 0, j = bs.length; i < j; i++) { + var id = bs[i].id; + bits[id >> ADDRESS_BITS_PER_WORD] |= 1 << (id & BIT_INDEX_MASK); + } + }; + } + return BlockSet; + } + function Analysis(cfg, options) { + this.options = options || {}; + this.BlockSet = blockSetClass(cfg.blocks.length, cfg.blocks); + this.hasExceptions = false; + this.normalizeReachableBlocks(cfg.root); + } + Analysis.prototype = { + normalizeReachableBlocks: function normalizeReachableBlocks(root) { + true; + var ONCE = 1; + var BUNCH_OF_TIMES = 2; + var BlockSet = this.BlockSet; + var blocks = []; + var visited = {}; + var ancestors = {}; + var worklist = [ + root + ]; + var node; + ancestors[root.id] = true; + while (node = worklist.top()) { + if (visited[node.id]) { + if (visited[node.id] === ONCE) { + visited[node.id] = BUNCH_OF_TIMES; + blocks.push(node); + } + ancestors[node.id] = false; + worklist.pop(); + continue; + } + visited[node.id] = ONCE; + ancestors[node.id] = true; + var successors = node.successors; + for (var i = 0, j = successors.length; i < j; i++) { + var s = successors[i]; + if (ancestors[s.id]) { + if (!node.spbacks) { + node.spbacks = new BlockSet(); + } + node.spbacks.set(s.id); + } + !visited[s.id] && worklist.push(s); + } + } + this.blocks = blocks.reverse(); + }, + computeDominance: function computeDominance() { + function intersectDominators(doms, b1, b2) { + var finger1 = b1; + var finger2 = b2; + while (finger1 !== finger2) { + while (finger1 > finger2) { + finger1 = doms[finger1]; + } + while (finger2 > finger1) { + finger2 = doms[finger2]; + } + } + return finger1; + } + var blocks = this.blocks; + var n = blocks.length; + var doms = new Array(n); + doms[0] = 0; + var rpo = []; + for (var b = 0; b < n; b++) { + rpo[blocks[b].id] = b; + blocks[b].dominatees = []; + } + var changed = true; + while (changed) { + changed = false; + for (var b = 1; b < n; b++) { + var predecessors = blocks[b].predecessors; + var j = predecessors.length; + var newIdom = rpo[predecessors[0].id]; + if (!(newIdom in doms)) { + for (var i = 1; i < j; i++) { + newIdom = rpo[predecessors[i].id]; + if (newIdom in doms) { + break; + } + } + } + true; + for (var i = 0; i < j; i++) { + var p = rpo[predecessors[i].id]; + if (p === newIdom) { + continue; + } + if (p in doms) { + newIdom = intersectDominators(doms, p, newIdom); + } + } + if (doms[b] !== newIdom) { + doms[b] = newIdom; + changed = true; + } + } + } + blocks[0].dominator = blocks[0]; + var block; + for (var b = 1; b < n; b++) { + block = blocks[b]; + var idom = blocks[doms[b]]; + block.dominator = idom; + idom.dominatees.push(block); + block.npredecessors = block.predecessors.length; + } + var worklist = [ + blocks[0] + ]; + blocks[0].level || (blocks[0].level = 0); + while (block = worklist.shift()) { + var dominatees = block.dominatees; + for (var i = 0, j = dominatees.length; i < j; i++) { + dominatees[i].level = block.level + 1; + } + worklist.push.apply(worklist, dominatees); + } + }, + computeFrontiers: function computeFrontiers() { + var BlockSet = this.BlockSet; + var blocks = this.blocks; + for (var b = 0, n = blocks.length; b < n; b++) { + blocks[b].frontier = new BlockSet(); + } + for (var b = 1, n = blocks.length; b < n; b++) { + var block = blocks[b]; + var predecessors = block.predecessors; + if (predecessors.length >= 2) { + var idom = block.dominator; + for (var i = 0, j = predecessors.length; i < j; i++) { + var runner = predecessors[i]; + while (runner !== idom) { + runner.frontier.set(block.id); + runner = runner.dominator; + } + } + } + } + }, + analyzeControlFlow: function analyzeControlFlow() { + this.computeDominance(); + this.analyzedControlFlow = true; + return true; + }, + markLoops: function markLoops() { + if (!this.analyzedControlFlow && !this.analyzeControlFlow()) { + return false; + } + var BlockSet = this.BlockSet; + function findSCCs(root) { + var preorderId = 1; + var preorder = {}; + var assigned = {}; + var unconnectedNodes = []; + var pendingNodes = []; + var sccs = []; + var level = root.level + 1; + var worklist = [ + root + ]; + var node; + var u, s; + while (node = worklist.top()) { + if (preorder[node.id]) { + if (pendingNodes.peek() === node) { + pendingNodes.pop(); + var scc = []; + do { + u = unconnectedNodes.pop(); + assigned[u.id] = true; + scc.push(u); + } while (u !== node); + if (scc.length > 1 || u.spbacks && u.spbacks.get(u.id)) { + sccs.push(scc); + } + } + worklist.pop(); + continue; + } + preorder[node.id] = preorderId++; + unconnectedNodes.push(node); + pendingNodes.push(node); + var successors = node.successors; + for (var i = 0, j = successors.length; i < j; i++) { + s = successors[i]; + if (s.level < level) { + continue; + } + var sid = s.id; + if (!preorder[sid]) { + worklist.push(s); + } else if (!assigned[sid]) { + while (preorder[pendingNodes.peek().id] > preorder[sid]) { + pendingNodes.pop(); + } + } + } + } + return sccs; + } + function findLoopHeads(blocks) { + var heads = new BlockSet(); + for (var i = 0, j = blocks.length; i < j; i++) { + var block = blocks[i]; + var spbacks = block.spbacks; + if (!spbacks) { + continue; + } + var successors = block.successors; + for (var k = 0, l = successors.length; k < l; k++) { + var s = successors[k]; + if (spbacks.get(s.id)) { + heads.set(s.dominator.id); + } + } + } + return heads.members(); + } + function LoopInfo(scc, loopId) { + var body = new BlockSet(); + body.setBlocks(scc); + body.recount(); + this.id = loopId; + this.body = body; + this.exit = new BlockSet(); + this.save = {}; + this.head = new BlockSet(); + this.npredecessors = 0; + } + var heads = findLoopHeads(this.blocks); + if (heads.length <= 0) { + this.markedLoops = true; + return true; + } + var worklist = heads.sort(function (a, b) { + return a.level - b.level; + }); + var loopId = 0; + for (var n = worklist.length - 1; n >= 0; n--) { + var top = worklist[n]; + var sccs = findSCCs(top); + if (sccs.length === 0) { + continue; + } + for (var i = 0, j = sccs.length; i < j; i++) { + var scc = sccs[i]; + var loop = new LoopInfo(scc, loopId++); + for (var k = 0, l = scc.length; k < l; k++) { + var h = scc[k]; + if (h.level === top.level + 1 && !h.loop) { + h.loop = loop; + loop.head.set(h.id); + var predecessors = h.predecessors; + for (var pi = 0, pj = predecessors.length; pi < pj; pi++) { + loop.body.get(predecessors[pi].id) && h.npredecessors--; + } + loop.npredecessors += h.npredecessors; + } + } + for (var k = 0, l = scc.length; k < l; k++) { + var h = scc[k]; + if (h.level === top.level + 1) { + h.npredecessors = loop.npredecessors; + } + } + loop.head.recount(); + } + } + this.markedLoops = true; + return true; + }, + induceControlTree: function induceControlTree() { + var hasExceptions = this.hasExceptions; + var BlockSet = this.BlockSet; + function maybe(exit, save) { + exit.recount(); + if (exit.count === 0) { + return null; + } + exit.save = save; + return exit; + } + var exceptionId = this.blocks.length; + function induce(head, exit, save, loop, inLoopHead, lookupSwitch, fallthrough) { + var v = []; + while (head) { + if (head.count > 1) { + var exit2 = new BlockSet(); + var save2 = {}; + var cases = []; + var heads = head.members(); + for (var i = 0, j = heads.length; i < j; i++) { + var h = heads[i]; + var bid = h.id; + var c; + if (h.loop && head.contains(h.loop.head)) { + var loop2 = h.loop; + if (!loop2.induced) { + var lheads = loop2.head.members(); + var lheadsave = 0; + for (k = 0, l = lheads.length; k < l; k++) { + lheadsave += head.save[lheads[k].id]; + } + if (h.npredecessors - lheadsave > 0) { + h.npredecessors -= head.save[bid]; + h.save = head.save[bid]; + c = induce(h, exit2, save2, loop); + cases.push(new Control.LabelCase([ + bid + ], c)); + } else { + for (k = 0, l = lheads.length; k < l; k++) { + var lh = lheads[k]; + lh.npredecessors -= lheadsave; + lh.save = lheadsave; + } + c = induce(h, exit2, save2, loop); + cases.push(new Control.LabelCase(loop2.head.toArray(), c)); + loop2.induced = true; + } + } + } else { + h.npredecessors -= head.save[bid]; + h.save = head.save[bid]; + c = induce(h, exit2, save2, loop); + cases.push(new Control.LabelCase([ + bid + ], c)); + } + } + var pruned = []; + var k = 0; + var c; + for (var i = 0, j = cases.length; i < j; i++) { + c = cases[i]; + var labels = c.labels; + var lk = 0; + for (var ln = 0, nlabels = labels.length; ln < nlabels; ln++) { + var bid = labels[ln]; + if (exit2.get(bid) && heads[i].npredecessors - head.save[bid] > 0) { + pruned.push(bid); + } else { + labels[lk++] = bid; + } + } + labels.length = lk; + if (labels.length > 0) { + cases[k++] = c; + } + } + cases.length = k; + if (cases.length === 0) { + for (var i = 0, j = pruned.length; i < j; i++) { + var bid = pruned[i]; + save[bid] = (save[bid] || 0) + head.save[bid]; + exit.set(bid); + } + break; + } + v.push(new Control.LabelSwitch(cases)); + head = maybe(exit2, save2); + continue; + } + var h, bid, c; + if (head.count === 1) { + h = head.choose(); + bid = h.id; + h.npredecessors -= head.save[bid]; + h.save = head.save[bid]; + } else { + h = head; + bid = h.id; + } + if (inLoopHead) { + inLoopHead = false; + } else { + if (loop && !loop.body.get(bid)) { + h.npredecessors += h.save; + loop.exit.set(bid); + loop.save[bid] = (loop.save[bid] || 0) + h.save; + v.push(new Control.Break(bid, loop)); + break; + } + if (loop && h.loop === loop) { + h.npredecessors += h.save; + v.push(new Control.Continue(bid, loop)); + break; + } + if (h === fallthrough) { + break; + } + if (h.npredecessors > 0) { + h.npredecessors += h.save; + save[bid] = (save[bid] || 0) + h.save; + exit.set(bid); + v.push(lookupSwitch ? new Control.Break(bid, lookupSwitch) : new Control.Exit(bid)); + break; + } + if (h.loop) { + var l = h.loop; + var body; + if (l.head.count === 1) { + body = induce(l.head.choose(), null, null, l, true); + } else { + var lcases = []; + var lheads = l.head.members(); + for (var i = 0, j = lheads.length; i < j; i++) { + var lh = lheads[i]; + var lbid = lh.id; + var c = induce(lh, null, null, l, true); + lcases.push(new Control.LabelCase([ + lbid + ], c)); + } + body = new Control.LabelSwitch(lcases); + } + v.push(new Control.Loop(body)); + head = maybe(l.exit, l.save); + continue; + } + } + var sv; + var successors; + var exit2 = new BlockSet(); + var save2 = {}; + if (hasExceptions && h.hasCatches) { + var allsuccessors = h.successors; + var catchsuccessors = []; + successors = []; + for (var i = 0, j = allsuccessors.length; i < j; i++) { + var s = allsuccessors[i]; + (s.exception ? catchsuccessors : successors).push(s); + } + var catches = []; + for (var i = 0, j = catchsuccessors.length; i < j; i++) { + var t = catchsuccessors[i]; + t.npredecessors -= 1; + t.save = 1; + var c = induce(t, exit2, save2, loop); + var ex = t.exception; + catches.push(new Control.Catch(ex.varName, ex.typeName, c)); + } + sv = new Control.Try(h, catches); + } else { + successors = h.successors; + sv = h; + } + if (successors.length > 2) { + var cases = []; + var targets = successors; + for (var i = targets.length - 1; i >= 0; i--) { + var t = targets[i]; + t.npredecessors -= 1; + t.save = 1; + c = induce(t, exit2, save2, loop, null, h, targets[i + 1]); + cases.unshift(new Control.Case(i, c)); + } + cases.top().index = undefined; + if (hasExceptions && h.hasCatches) { + sv.nothingThrownLabel = exceptionId; + sv = new Control.Switch(sv, cases, exceptionId++); + } else { + sv = new Control.Switch(sv, cases); + } + head = maybe(exit2, save2); + } else if (successors.length === 2) { + var branch1 = h.hasFlippedSuccessors ? successors[1] : successors[0]; + var branch2 = h.hasFlippedSuccessors ? successors[0] : successors[1]; + branch1.npredecessors -= 1; + branch1.save = 1; + var c1 = induce(branch1, exit2, save2, loop); + branch2.npredecessors -= 1; + branch2.save = 1; + var c2 = induce(branch2, exit2, save2, loop); + if (hasExceptions && h.hasCatches) { + sv.nothingThrownLabel = exceptionId; + sv = new Control.If(sv, c1, c2, exceptionId++); + } else { + sv = new Control.If(sv, c1, c2); + } + head = maybe(exit2, save2); + } else { + c = successors[0]; + if (c) { + if (hasExceptions && h.hasCatches) { + sv.nothingThrownLabel = c.id; + save2[c.id] = (save2[c.id] || 0) + 1; + exit2.set(c.id); + head = maybe(exit2, save2); + } else { + c.npredecessors -= 1; + c.save = 1; + head = c; + } + } else { + if (hasExceptions && h.hasCatches) { + sv.nothingThrownLabel = -1; + head = maybe(exit2, save2); + } else { + head = c; + } + } + } + v.push(sv); + } + if (v.length > 1) { + return new Control.Seq(v); + } + return v[0]; + } + var root = this.blocks[0]; + this.controlTree = induce(root, new BlockSet(), {}); + }, + restructureControlFlow: function restructureControlFlow() { + Timer.start('Restructure Control Flow'); + if (!this.markedLoops && !this.markLoops()) { + Timer.stop(); + return false; + } + this.induceControlTree(); + this.restructuredControlFlow = true; + Timer.stop(); + return true; + }, + trace: function (writer) { + function bid(node) { + return node.id; + } + function traceBlock(block) { + if (!block.dominator) { + writer.enter('block unreachable {'); + } else { + writer.enter('block ' + block.id + (block.successors.length > 0 ? ' -> ' + block.successors.map(bid).join(',') : '') + ' {'); + writer.writeLn('npredecessors'.padRight(' ', 10) + block.npredecessors); + writer.writeLn('idom'.padRight(' ', 10) + block.dominator.id); + writer.writeLn('domcs'.padRight(' ', 10) + block.dominatees.map(bid).join(',')); + if (block.frontier) { + writer.writeLn('frontier'.padRight(' ', 10) + '{' + block.frontier.toArray().join(',') + '}'); + } + writer.writeLn('level'.padRight(' ', 10) + block.level); + } + if (block.loop) { + writer.writeLn('loop'.padRight(' ', 10) + '{' + block.loop.body.toArray().join(',') + '}'); + writer.writeLn(' id'.padRight(' ', 10) + block.loop.id); + writer.writeLn(' head'.padRight(' ', 10) + '{' + block.loop.head.toArray().join(',') + '}'); + writer.writeLn(' exit'.padRight(' ', 10) + '{' + block.loop.exit.toArray().join(',') + '}'); + writer.writeLn(' npredecessors'.padRight(' ', 10) + block.loop.npredecessors); + } + writer.writeLn(''); + if (block.position >= 0) { + for (var bci = block.position; bci <= block.end.position; bci++) { + writer.writeLn(('' + bci).padRight(' ', 5) + bytecodes[bci]); + } + } else { + writer.writeLn('abstract'); + } + writer.leave('}'); + } + var bytecodes = this.bytecodes; + writer.enter('analysis {'); + writer.enter('cfg {'); + this.blocks.forEach(traceBlock); + writer.leave('}'); + if (this.controlTree) { + writer.enter('control-tree {'); + this.controlTree.trace(writer); + writer.leave('}'); + } + writer.leave('}'); + }, + traceCFG: makeVizTrace([ + { + fn: function (n) { + return n.successors || []; + }, + style: '' + } + ], [ + { + fn: function (n) { + return n.predecessors || []; + }, + style: '' + } + ]), + traceDJ: makeVizTrace([ + { + fn: function (n) { + return n.dominatees || []; + }, + style: 'style=dashed' + }, + { + fn: function (n) { + var crosses = new this.BlockSet(); + crosses.setBlocks(n.successors); + crosses.subtract(this.BlockSet.fromBlocks(n.dominatees)); + n.spbacks && crosses.subtract(n.spbacks); + return crosses.members(); + }, + style: '' + }, + { + fn: function (n) { + return n.spbacks ? n.spbacks.members() : []; + }, + style: 'style=bold' + } + ], [ + { + fn: function (n) { + return n.predecessors || []; + }, + style: '' + } + ], function (idFn, writer) { + var root = this.bytecodes[0]; + var worklist = [ + root + ]; + var n; + var level = root.level; + var currentLevel = []; + while (n = worklist.shift()) { + if (level != n.level) { + writer.writeLn('{rank=same; ' + currentLevel.map(function (n) { + return 'block_' + idFn(n); + }).join(' ') + '}'); + currentLevel.length = 0; + level = n.level; + } + currentLevel.push(n); + worklist.push.apply(worklist, n.dominatees); + } + }) + }; + function makeVizTrace(successorFns, predecessorFns, postHook) { + return function (writer, name, prefix) { + function idFn(n) { + return prefix + n.id; + } + var analysis = this; + function bindToThis(x) { + x.fn = x.fn.bind(analysis); + } + prefix = prefix || ''; + var bytecodes = this.bytecodes; + if (!bytecodes) { + return; + } + successorFns.forEach(bindToThis); + predecessorFns.forEach(bindToThis); + writeGraphViz(writer, name.toString(), bytecodes[0], idFn, function (n) { + return n.successors || []; + }, successorFns, predecessorFns, function (n) { + var str = 'Block: ' + n.id + '\\l'; + return str; + }, postHook && postHook.bind(this, idFn)); + }; + } + return Analysis; + }(); + exports.Control = Control; + exports.analyze = function (cfg) { + var analysis = new Analysis(cfg); + analysis.restructureControlFlow(); + return analysis.controlTree; + }; +}(typeof exports === 'undefined' ? Looper = {} : exports)); +(function (exports) { + var TRACE_REGISTER_ALLOCATOR = false; + var T = estransform; + var Node = T.Node; + var Identifier = T.Identifier; + var VariableDeclaration = T.VariableDeclaration; + var VariableDeclarator = T.VariableDeclarator; + var AssignmentExpression = T.AssignmentExpression; + var MemberExpression = T.MemberExpression; + var IfStatement = T.IfStatement; + var WhileStatement = T.WhileStatement; + var FunctionDeclaration = T.FunctionDeclaration; + var writer = new IndentingWriter(); + var LinearScan = function () { + function Interval(id, start, end) { + this.id = id; + this.start = start; + this.end = end; + } + Interval.prototype.toString = function () { + return '[' + this.start + ',' + this.end + ']'; + }; + function linearScan(intervals, maxRegisters) { + this.intervals = intervals.slice(0); + this.maxRegisters = maxRegisters; + } + linearScan.prototype.allocate = function () { + var intervals = this.intervals; + this.intervals.sort(function (a, b) { + return a.start - b.start; + }); + var active = new SortedList(function (a, b) { + return a.end - b.end; + }); + var maxRegisters = this.maxRegisters; + var freeRegisters = []; + for (var i = maxRegisters - 1; i >= 0; i--) { + freeRegisters.push('R' + i); + } + intervals.forEach(function (i) { + expireOldIntervals(i); + if (active.length === maxRegisters) { + notImplemented('Cannot Spill'); + } else { + i.register = freeRegisters.pop(); + TRACE_REGISTER_ALLOCATOR && writer.writeLn('Allocate: ' + i + ' ' + i.id + ' -> ' + i.register); + active.push(i); + } + }); + function expireOldIntervals(i) { + active.forEach(function (j) { + if (j.end >= i.start) { + return SortedList.RETURN; + } + freeRegisters.push(j.register); + TRACE_REGISTER_ALLOCATOR && writer.writeLn('Release: ' + j + ' -> ' + j.register); + return SortedList.DELETE; + }); + } + }; + linearScan.Interval = Interval; + return linearScan; + }(); + function allocateRegisters(program) { + var scan = T.makePass('scan', 'scanNode'); + var label = 0; + Node.prototype.scan = function (o) { + this.position = label++; + return scan.apply(this, o); + }; + var variables = []; + var variableIndexMap = {}; + var identifiers = []; + FunctionDeclaration.prototype.scan = function () { + this.params.forEach(function (identifier) { + if (!(identifier.name in variableIndexMap)) { + variableIndexMap[identifier.name] = variables.length; + variables.push(identifier.name); + } + }); + this.body.scan(); + return this; + }; + VariableDeclarator.prototype.scan = function () { + this.position = label++; + if (!(this.id.name in variableIndexMap)) { + variableIndexMap[this.id.name] = variables.length; + variables.push(this.id.name); + } + return this; + }; + AssignmentExpression.prototype.scan = function (o) { + this.left.scan(o); + this.right.scan(o); + this.position = label++; + return this; + }; + WhileStatement.prototype.scan = function (o) { + this.position = label++; + this.test.scan(o); + this.body.scan(o); + this.afterPosition = label++; + return this; + }; + program.scan(); + TRACE_REGISTER_ALLOCATOR && writer.writeLn('Local Variables: ' + variables); + var Set = BitSetFunctor(variables.length); + var Range = BitSetFunctor(label); + var ranges = []; + for (var i = 0; i < variables.length; i++) { + ranges.push(new Range()); + } + function fill(range) { + var start = -1; + for (var i = 0; i < range.length; i++) { + if (range.get(i)) { + start = i; + break; + } + } + for (var i = range.length - 1; i >= 0; i--) { + if (range.get(i)) { + end = i; + break; + } + } + for (var i = start; i < end; i++) { + range.set(i); + } + } + function getRange(range) { + var start = -1, end = -1; + for (var i = 0; i < range.length; i++) { + if (range.get(i)) { + start = i; + break; + } + } + for (var i = range.length - 1; i >= 0; i--) { + if (range.get(i)) { + end = i; + break; + } + } + return [ + start, + end + ]; + } + function use(set, name, position) { + var index = variableIndexMap[name]; + ranges[index].set(position); + set.set(index); + } + function def(set, name, position) { + var index = variableIndexMap[name]; + ranges[index].set(position); + set.clear(index); + } + Node.prototype.markLiveness = T.makePass('markLiveness', 'markLivenessNode', true); + Identifier.prototype.markLiveness = function (o) { + var name = this.name; + if (name === 'undefined') { + return this; + } + if (o && o.isProperty) { + return this; + } + if (!(name in variableIndexMap)) { + return this; + } + identifiers.push(this); + var live = o.live; + use(live, name, this.position); + return this; + }; + VariableDeclarator.prototype.markLiveness = function (o) { + var live = o.live; + identifiers.push(this.id); + return this; + }; + IfStatement.prototype.markLiveness = function (o) { + var a = o.live.clone(); + var b = o.live.clone(); + this.alternate && this.alternate.markLiveness({ + live: a + }); + this.consequent && this.consequent.markLiveness({ + live: b + }); + o.live.assign(a); + o.live._union(b); + this.test.markLiveness(o); + return this; + }; + WhileStatement.prototype.markLiveness = function (o) { + var a = o.live.clone(); + TRACE_REGISTER_ALLOCATOR && writer.writeLn('END OF LOOP: ' + a); + var afterPosition = this.afterPosition; + do { + var b = a.clone(); + this.body.markLiveness({ + live: a + }); + this.test.markLiveness({ + live: a + }); + TRACE_REGISTER_ALLOCATOR && writer.writeLn('TOP OF LOOP: ' + a); + var iterate = !b.equals(a); + if (iterate) { + TRACE_REGISTER_ALLOCATOR && writer.writeLn('ITERATE'); + a.forEach(function (i) { + ranges[i].set(afterPosition); + }); + } + } while (iterate); + o.live.assign(a); + return this; + }; + AssignmentExpression.prototype.markLiveness = function (o) { + this.right.markLiveness(o); + if (this.left instanceof Identifier) { + def(o.live, this.left.name, this.position); + identifiers.push(this.left); + } else { + this.left.markLiveness(o); + } + return this; + }; + MemberExpression.prototype.markLiveness = function (o) { + if (this.computed || !(this.property instanceof Identifier)) { + this.property.markLiveness(o); + } + this.object.markLiveness(o); + return this; + }; + program.markLiveness({ + live: new Set() + }); + var intervals = []; + for (var i = 0; i < ranges.length; i++) { + var r = getRange(ranges[i]); + intervals.push(new LinearScan.Interval(i, r[0], r[1])); + } + var allocator = new LinearScan(intervals, 1024); + allocator.allocate(); + var map = createEmptyObject(); + for (var i = 0; i < variables.length; i++) { + map[variables[i]] = intervals[i].register; + } + if (true) { + for (var i = 0; i < identifiers.length; i++) { + if (identifiers[i].patched) { + continue; + } + identifiers[i].name = map[identifiers[i].name]; + identifiers[i].patched = true; + } + } + if (TRACE_REGISTER_ALLOCATOR) { + for (var i = 0; i < ranges.length; i++) { + fill(ranges[i]); + writer.writeLn(String(i).padLeft(' ', 3) + ' ' + variables[i].padRight(' ', 5) + ': ' + ranges[i].toBitString('=', ' ') + ' ' + intervals[i].register); + } + } + return program; + } + Transform.transform = function (program) { + allocateRegisters(program); + }; +}(typeof exports === 'undefined' ? Transform = {} : exports)); +(function (exports) { + var T = estransform; + var Literal = T.Literal; + var Identifier = T.Identifier; + var VariableDeclaration = T.VariableDeclaration; + var VariableDeclarator = T.VariableDeclarator; + var MemberExpression = T.MemberExpression; + var BinaryExpression = T.BinaryExpression; + var CallExpression = T.CallExpression; + var AssignmentExpression = T.AssignmentExpression; + var ExpressionStatement = T.ExpressionStatement; + var ReturnStatement = T.ReturnStatement; + var FunctionDeclaration = T.FunctionDeclaration; + var ConditionalExpression = T.ConditionalExpression; + var ObjectExpression = T.ObjectExpression; + var ArrayExpression = T.ArrayExpression; + var UnaryExpression = T.UnaryExpression; + var NewExpression = T.NewExpression; + var Property = T.Property; + var BlockStatement = T.BlockStatement; + var ThisExpression = T.ThisExpression; + var ThrowStatement = T.ThrowStatement; + var IfStatement = T.IfStatement; + var WhileStatement = T.WhileStatement; + var BreakStatement = T.BreakStatement; + var ContinueStatement = T.ContinueStatement; + var SwitchStatement = T.SwitchStatement; + var SwitchCase = T.SwitchCase; + var Block = IR.Block; + var Operator = IR.Operator; + var Projection = IR.Projection; + var Start = IR.Start; + var Control = Looper.Control; + var Variable = IR.Variable; + Control.Break.prototype.compile = function (cx, state) { + return cx.compileBreak(this, state); + }; + Control.Continue.prototype.compile = function (cx, state) { + return cx.compileContinue(this, state); + }; + Control.Exit.prototype.compile = function (cx, state) { + return cx.compileExit(this, state); + }; + Control.LabelSwitch.prototype.compile = function (cx, state) { + return cx.compileLabelSwitch(this, state); + }; + Control.Seq.prototype.compile = function (cx, state) { + return cx.compileSequence(this, state); + }; + Block.prototype.compile = function (cx, state) { + return cx.compileBlock(this, state); + }; + Control.Loop.prototype.compile = function (cx, state) { + return cx.compileLoop(this, state); + }; + Control.Switch.prototype.compile = function (cx, state) { + return cx.compileSwitch(this, state); + }; + Control.If.prototype.compile = function (cx, state) { + return cx.compileIf(this, state); + }; + Control.Try.prototype.compile = function (cx, state) { + return cx.compileTry(this, state); + }; + function constant(value) { + if (typeof value === 'string' || value === null || value === true || value === false) { + return new Literal(value); + } else if (value === undefined) { + return new Identifier('undefined'); + } else if (typeof value === 'object' || typeof value === 'function') { + return new Identifier(objectConstantName(value)); + } else if (typeof value === 'number' && isNaN(value)) { + return new Identifier('NaN'); + } else if (value === Infinity) { + return new Identifier('Infinity'); + } else if (value === -Infinity) { + return new UnaryExpression('-', new Identifier('Infinity')); + } else if (typeof value === 'number' && 1 / value < 0) { + return new UnaryExpression('-', new Literal(Math.abs(value))); + } else if (typeof value === 'number') { + return new Literal(value); + } else { + unexpected('Cannot emit constant for value: ', value); + } + } + function id(name) { + true; + return new Identifier(name); + } + function isIdentifierStart(c) { + return c === '$' || c === '_' || c === '\\' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'; + } + function isIdentifierPart(c) { + return c === '$' || c === '_' || c === '\\' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9'; + } + function isIdentifierName(s) { + if (!isIdentifierStart(s[0])) { + return false; + } + for (var i = 1; i < s.length; i++) { + if (!isIdentifierPart(s[i])) { + return false; + } + } + return true; + } + function property(obj) { + for (var i = 1; i < arguments.length; i++) { + var x = arguments[i]; + if (typeof x === 'string') { + if (isIdentifierName(x)) { + obj = new MemberExpression(obj, new Identifier(x), false); + } else { + obj = new MemberExpression(obj, new Literal(x), true); + } + } else if (x instanceof Literal && isIdentifierName(x.value)) { + obj = new MemberExpression(obj, new Identifier(x.value), false); + } else { + obj = new MemberExpression(obj, x, true); + } + } + return obj; + } + function call(callee, args) { + true; + true; + return new CallExpression(callee, args); + } + function callCall(callee, object, args) { + return call(property(callee, 'call'), [ + object + ].concat(args)); + } + function assignment(left, right) { + true; + return new AssignmentExpression(left, '=', right); + } + function variableDeclaration(declarations) { + return new VariableDeclaration('var', declarations); + } + function negate(node) { + if (node instanceof Constant) { + if (node.value === true || node.value === false) { + return constant(!node.value); + } + } else if (node instanceof Identifier) { + return new UnaryExpression(Operator.FALSE.name, node); + } + true; + var left = node instanceof BinaryExpression ? node.left : node.argument; + var right = node.right; + var operator = Operator.fromName(node.operator); + if (operator === Operator.EQ && right instanceof Literal && right.value === false) { + return left; + } + if (operator === Operator.FALSE) { + return left; + } + if (operator.not) { + if (node instanceof BinaryExpression) { + return new BinaryExpression(operator.not.name, left, right); + } else { + return new UnaryExpression(operator.not.name, left); + } + } + return new UnaryExpression(Operator.FALSE.name, node); + } + function Context() { + this.label = new Variable('$L'); + this.variables = []; + this.parameters = []; + } + Context.prototype.useVariable = function (variable) { + true; + return this.variables.pushUnique(variable); + }; + Context.prototype.useParameter = function (parameter) { + return this.parameters[parameter.index] = parameter; + }; + Context.prototype.compileLabelBody = function compileLabelBody(node) { + var body = []; + if (node.label !== undefined) { + this.useVariable(this.label); + body.push(new ExpressionStatement(assignment(id(this.label.name), new Literal(node.label)))); + } + return body; + }; + Context.prototype.compileBreak = function compileBreak(node) { + var body = this.compileLabelBody(node); + body.push(new BreakStatement(null)); + return new BlockStatement(body); + }; + Context.prototype.compileContinue = function compileContinue(node) { + var body = this.compileLabelBody(node); + body.push(new ContinueStatement(null)); + return new BlockStatement(body); + }; + Context.prototype.compileExit = function compileExit(node) { + return new BlockStatement(this.compileLabelBody(node)); + }; + Context.prototype.compileIf = function compileIf(node) { + var cr = node.cond.compile(this); + var tr = null, er = null; + if (node.then) { + tr = node.then.compile(this); + } + if (node.else) { + er = node.else.compile(this); + } + var condition = compileValue(cr.end.predicate, this); + condition = node.negated ? negate(condition) : condition; + cr.body.push(new IfStatement(condition, tr || new BlockStatement([]), er || null)); + return cr; + }; + Context.prototype.compileSwitch = function compileSwitch(node) { + var dr = node.determinant.compile(this); + var cases = []; + node.cases.forEach(function (x) { + var br; + if (x.body) { + br = x.body.compile(this); + } + var test = typeof x.index === 'number' ? new Literal(x.index) : undefined; + cases.push(new SwitchCase(test, br ? [ + br + ] : [])); + }, this); + var determinant = compileValue(dr.end.determinant, this); + dr.body.push(new SwitchStatement(determinant, cases, false)); + return dr; + }; + Context.prototype.compileLabelSwitch = function compileLabelSwitch(node) { + var statement = null; + var labelName = id(this.label.name); + function compileLabelTest(labelID) { + true; + return new BinaryExpression('===', labelName, new Literal(labelID)); + } + for (var i = node.cases.length - 1; i >= 0; i--) { + var c = node.cases[i]; + var labels = c.labels; + var labelTest = compileLabelTest(labels[0]); + for (var j = 1; j < labels.length; j++) { + labelTest = new BinaryExpression('||', labelTest, compileLabelTest(labels[j])); + } + statement = new IfStatement(labelTest, c.body ? c.body.compile(this) : new BlockStatement(), statement); + } + return statement; + }; + Context.prototype.compileLoop = function compileLoop(node) { + var br = node.body.compile(this); + return new WhileStatement(constant(true), br); + }; + Context.prototype.compileSequence = function compileSequence(node) { + var cx = this; + var body = []; + node.body.forEach(function (x) { + var result = x.compile(cx); + if (result instanceof BlockStatement) { + body = body.concat(result.body); + } else { + body.push(result); + } + }); + return new BlockStatement(body); + }; + Context.prototype.compileBlock = function compileBlock(block) { + var body = []; + for (var i = 1; i < block.nodes.length - 1; i++) { + var node = block.nodes[i]; + var statement; + var to; + var from; + if (node instanceof IR.Throw) { + statement = compileValue(node, this, true); + } else { + if (node instanceof IR.Move) { + to = id(node.to.name); + this.useVariable(node.to); + from = compileValue(node.from, this); + } else { + if (node.variable) { + to = id(node.variable.name); + this.useVariable(node.variable); + } else { + to = null; + } + from = compileValue(node, this, true); + } + if (to) { + statement = new ExpressionStatement(assignment(to, from)); + } else { + statement = new ExpressionStatement(from); + } + } + body.push(statement); + } + var end = block.nodes.last(); + if (end instanceof IR.Stop) { + body.push(new ReturnStatement(compileValue(end.argument, this))); + } + var result = new BlockStatement(body); + result.end = block.nodes.last(); + true; + return result; + }; + function compileValue(value, cx, noVariable) { + true; + true; + true; + true; + if (noVariable || !value.variable) { + var node = value.compile(cx); + return node; + } + true; + return id(value.variable.name); + } + function compileMultiname(name, cx) { + return [ + compileValue(name.namespaces, cx), + compileValue(name.name, cx), + constant(name.flags) + ]; + } + function isArray(array) { + return array instanceof Array; + } + function compileValues(values, cx) { + true; + return values.map(function (value) { + return compileValue(value, cx); + }); + } + IR.Parameter.prototype.compile = function (cx) { + cx.useParameter(this); + return id(this.name); + }; + IR.Constant.prototype.compile = function (cx) { + return constant(this.value); + }; + IR.Variable.prototype.compile = function (cx) { + return id(this.name); + }; + IR.Phi.prototype.compile = function (cx) { + true; + return compileValue(this.variable, cx); + }; + IR.ASScope.prototype.compile = function (cx) { + var parent = compileValue(this.parent, cx); + var object = compileValue(this.object, cx); + var isWith = new Literal(this.isWith); + return new NewExpression(id('Scope'), [ + parent, + object, + isWith + ]); + }; + IR.ASFindProperty.prototype.compile = function (cx) { + var scope = compileValue(this.scope, cx); + var name = compileMultiname(this.name, cx); + var domain = compileValue(this.domain, cx); + var strict = new Literal(this.strict); + return call(property(scope, 'findScopeProperty'), name.concat([ + domain, + strict + ])); + }; + IR.ASGetProperty.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + if (this.flags & IR.Flags.INDEXED) { + true; + return call(property(object, 'asGetNumericProperty'), [ + compileValue(this.name.name, cx) + ]); + } else if (this.flags & IR.Flags.RESOLVED) { + return call(property(object, 'asGetResolvedStringProperty'), [ + compileValue(this.name, cx) + ]); + } + var name = compileMultiname(this.name, cx); + var isMethod = new Literal(this.flags & IR.Flags.IS_METHOD); + return call(property(object, 'asGetProperty'), name.concat(isMethod)); + }; + IR.ASGetSuper.prototype.compile = function (cx) { + var scope = compileValue(this.scope, cx); + var object = compileValue(this.object, cx); + var name = compileMultiname(this.name, cx); + return call(property(object, 'asGetSuper'), [ + scope + ].concat(name)); + }; + IR.Latch.prototype.compile = function (cx) { + return new ConditionalExpression(compileValue(this.condition, cx), compileValue(this.left, cx), compileValue(this.right, cx)); + }; + IR.Unary.prototype.compile = function (cx) { + return new UnaryExpression(this.operator.name, compileValue(this.argument, cx)); + }; + IR.Copy.prototype.compile = function (cx) { + return compileValue(this.argument, cx); + }; + IR.Binary.prototype.compile = function (cx) { + var left = compileValue(this.left, cx); + var right = compileValue(this.right, cx); + if (this.operator === Operator.AS_ADD) { + return call(id('asAdd'), [ + left, + right + ]); + } + return new BinaryExpression(this.operator.name, left, right); + }; + IR.CallProperty.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + var name = compileValue(this.name, cx); + var callee = property(object, name); + var args = this.args.map(function (arg) { + return compileValue(arg, cx); + }); + if (this.flags & IR.Flags.PRISTINE) { + return call(callee, args); + } else { + return callCall(callee, object, args); + } + }; + IR.ASCallProperty.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + var args = this.args.map(function (arg) { + return compileValue(arg, cx); + }); + if (this.flags & IR.Flags.RESOLVED) { + return call(property(object, 'asCallResolvedStringProperty'), [ + compileValue(this.name, cx), + new Literal(this.isLex), + new ArrayExpression(args) + ]); + } + var name = compileMultiname(this.name, cx); + return call(property(object, 'asCallProperty'), name.concat([ + new Literal(this.isLex), + new ArrayExpression(args) + ])); + }; + IR.ASCallSuper.prototype.compile = function (cx) { + var scope = compileValue(this.scope, cx); + var object = compileValue(this.object, cx); + var args = this.args.map(function (arg) { + return compileValue(arg, cx); + }); + var name = compileMultiname(this.name, cx); + return call(property(object, 'asCallSuper'), [ + scope + ].concat(name).concat(new ArrayExpression(args))); + }; + IR.Call.prototype.compile = function (cx) { + var args = this.args.map(function (arg) { + return compileValue(arg, cx); + }); + var callee = compileValue(this.callee, cx); + var object; + if (this.object) { + object = compileValue(this.object, cx); + } else { + object = new Literal(null); + } + if (false && this.pristine && (this.callee instanceof IR.GetProperty && this.callee.object === this.object) || this.object === null) { + return call(callee, args); + } else { + return callCall(callee, object, args); + } + }; + IR.ASNew.prototype.compile = function (cx) { + var args = this.args.map(function (arg) { + return compileValue(arg, cx); + }); + var callee = compileValue(this.callee, cx); + callee = property(callee, 'instanceConstructor'); + return new NewExpression(callee, args); + }; + IR.This.prototype.compile = function (cx) { + return new ThisExpression(); + }; + IR.Throw.prototype.compile = function (cx) { + var argument = compileValue(this.argument, cx); + return new ThrowStatement(argument); + }; + IR.Arguments.prototype.compile = function (cx) { + return id('arguments'); + }; + IR.ASGlobal.prototype.compile = function (cx) { + var scope = compileValue(this.scope, cx); + return property(scope, 'global', 'object'); + }; + IR.ASSetProperty.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + var value = compileValue(this.value, cx); + if (this.flags & IR.Flags.INDEXED) { + return call(property(object, 'asSetNumericProperty'), [ + compileValue(this.name.name, cx), + value + ]); + } + var name = compileMultiname(this.name, cx); + return call(property(object, 'asSetProperty'), name.concat(value)); + }; + IR.ASSetSuper.prototype.compile = function (cx) { + var scope = compileValue(this.scope, cx); + var object = compileValue(this.object, cx); + var name = compileMultiname(this.name, cx); + var value = compileValue(this.value, cx); + return call(property(object, 'asSetSuper'), [ + scope + ].concat(name).concat([ + value + ])); + }; + IR.ASDeleteProperty.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + var name = compileMultiname(this.name, cx); + return call(property(object, 'asDeleteProperty'), name); + }; + IR.ASHasProperty.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + var name = compileMultiname(this.name, cx); + return call(property(object, 'asHasProperty'), name); + }; + IR.GlobalProperty.prototype.compile = function (cx) { + return id(this.name); + }; + IR.GetProperty.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + var name = compileValue(this.name, cx); + return property(object, name); + }; + IR.SetProperty.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + var name = compileValue(this.name, cx); + var value = compileValue(this.value, cx); + return assignment(property(object, name), value); + }; + IR.ASGetDescendants.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + var name = compileValue(this.name, cx); + return call(id('getDescendants'), [ + object, + name + ]); + }; + IR.ASSetSlot.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + var name = compileValue(this.name, cx); + var value = compileValue(this.value, cx); + return call(id('asSetSlot'), [ + object, + name, + value + ]); + }; + IR.ASGetSlot.prototype.compile = function (cx) { + var object = compileValue(this.object, cx); + var name = compileValue(this.name, cx); + return call(id('asGetSlot'), [ + object, + name + ]); + }; + IR.Projection.prototype.compile = function (cx) { + true; + true; + return compileValue(this.argument.scope, cx); + }; + IR.NewArray.prototype.compile = function (cx) { + return new ArrayExpression(compileValues(this.elements, cx)); + }; + IR.NewObject.prototype.compile = function (cx) { + var properties = this.properties.map(function (property) { + var key = compileValue(property.key, cx); + var value = compileValue(property.value, cx); + return new Property(key, value, 'init'); + }); + return new ObjectExpression(properties); + }; + IR.ASNewActivation.prototype.compile = function (cx) { + var methodInfo = compileValue(this.methodInfo, cx); + return call(id('asCreateActivation'), [ + methodInfo + ]); + }; + IR.ASMultiname.prototype.compile = function (cx) { + var namespaces = compileValue(this.namespaces, cx); + var name = compileValue(this.name, cx); + return call(id('createName'), [ + namespaces, + name + ]); + }; + function generateSource(node) { + return escodegen.generate(node, { + base: '', + indent: ' ', + comment: true, + format: { + compact: false + } + }); + } + function generate(cfg, useRegisterAllocator) { + Timer.start('Looper'); + var root = Looper.analyze(cfg); + Timer.stop(); + var writer = new IndentingWriter(); + var cx = new Context(); + Timer.start('Construct AST'); + var code = root.compile(cx); + Timer.stop(); + var parameters = []; + for (var i = 0; i < cx.parameters.length; i++) { + var name = cx.parameters[i] ? cx.parameters[i].name : '_' + i; + parameters.push(id(name)); + } + if (cx.variables.length) { + Counter.count('Backend: Locals', cx.variables.length); + var variables = variableDeclaration(cx.variables.map(function (variable) { + return new VariableDeclarator(id(variable.name)); + })); + code.body.unshift(variables); + } + var node = new FunctionDeclaration(id('fn'), parameters, code); + if (useRegisterAllocator) { + if (c4TraceLevel.value > 0) { + writer.writeLn('=== BEFORE ==============================='); + writer.writeLn(generateSource(node)); + writer.writeLn('=== TRANSFORMING ========================='); + } + Transform.transform(node); + if (c4TraceLevel.value > 0) { + writer.writeLn('=== AFTER ================================'); + writer.writeLn(generateSource(node)); + writer.writeLn('=========================================='); + } + var body = generateSource(code); + return { + parameters: parameters.map(function (p) { + return p.name; + }), + body: body + }; + } + Timer.start('Serialize AST'); + var source = generateSource(code); + Timer.stop(); + return { + parameters: parameters.map(function (p) { + return p.name; + }), + body: source + }; + } + Backend.generate = generate; +}(typeof exports === 'undefined' ? Backend = {} : exports)); +var Shumway; +(function (Shumway) { + (function (AVM2) { + (function (Runtime) { + var Multiname = Shumway.AVM2.ABC.Multiname; + var Namespace = Shumway.AVM2.ABC.Namespace; + var ClassInfo = Shumway.AVM2.ABC.ClassInfo; + var InstanceInfo = Shumway.AVM2.ABC.InstanceInfo; + var Trait = Shumway.AVM2.ABC.Trait; + var IndentingWriter = Shumway.IndentingWriter; + var createMap = Shumway.ObjectUtilities.createMap; + var defineNonEnumerableGetterOrSetter = Shumway.ObjectUtilities.defineNonEnumerableGetterOrSetter; + var defineNonEnumerableProperty = Shumway.ObjectUtilities.defineNonEnumerableProperty; + var defineReadOnlyProperty = Shumway.ObjectUtilities.defineReadOnlyProperty; + var bindSafely = Shumway.FunctionUtilities.bindSafely; + var vmNextTrampolineId = 1; + var vmNextMemoizerId = 1; + function getMethodOverrideKey(methodInfo) { + var key; + if (methodInfo.holder instanceof ClassInfo) { + key = 'static ' + methodInfo.holder.instanceInfo.name.getOriginalName() + '::' + methodInfo.name.getOriginalName(); + } else if (methodInfo.holder instanceof InstanceInfo) { + key = methodInfo.holder.name.getOriginalName() + '::' + methodInfo.name.getOriginalName(); + } else { + key = methodInfo.name.getOriginalName(); + } + return key; + } + Runtime.getMethodOverrideKey = getMethodOverrideKey; + function checkMethodOverrides(methodInfo) { + if (methodInfo.name) { + var key = getMethodOverrideKey(methodInfo); + if (key in Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES) { + Shumway.Debug.warning('Overriding Method: ' + key); + return Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES[key]; + } + } + } + Runtime.checkMethodOverrides = checkMethodOverrides; + function makeTrampoline(forward, parameterLength, description) { + true; + return function trampolineContext() { + var target = null; + var trampoline = function execute() { + if (Shumway.AVM2.Runtime.traceExecution.value >= 3) { + log('Trampolining'); + } + Counter.count('Executing Trampoline'); + Shumway.AVM2.Runtime.traceCallExecution.value > 1 && callWriter.writeLn('Trampoline: ' + description); + if (!target) { + target = forward(trampoline); + true; + } + return target.apply(this, arguments); + }; + trampoline.trigger = function trigger() { + Counter.count('Triggering Trampoline'); + if (!target) { + target = forward(trampoline); + true; + } + }; + trampoline.isTrampoline = true; + trampoline.debugName = 'Trampoline #' + vmNextTrampolineId++; + defineReadOnlyProperty(trampoline, Shumway.AVM2.Runtime.VM_LENGTH, parameterLength); + return trampoline; + }(); + } + Runtime.makeTrampoline = makeTrampoline; + function makeMemoizer(qn, target) { + function memoizer() { + Counter.count('Runtime: Memoizing'); + if (Shumway.AVM2.Runtime.traceExecution.value >= 3) { + log('Memoizing: ' + qn); + } + Shumway.AVM2.Runtime.traceCallExecution.value > 1 && callWriter.writeLn('Memoizing: ' + qn); + if (Shumway.AVM2.Runtime.isNativePrototype(this)) { + Counter.count('Runtime: Method Closures'); + return bindSafely(target.value, this); + } + if (isTrampoline(target.value)) { + target.value.trigger(); + } + true; + var mc = null; + if (Shumway.AVM2.Runtime.isClass(this)) { + Counter.count('Runtime: Static Method Closures'); + mc = bindSafely(target.value, this); + defineReadOnlyProperty(this, qn, mc); + return mc; + } + if (Object.prototype.hasOwnProperty.call(this, qn)) { + var pd = Object.getOwnPropertyDescriptor(this, qn); + if (pd.get) { + Counter.count('Runtime: Method Closures'); + return bindSafely(target.value, this); + } + Counter.count('Runtime: Unpatched Memoizer'); + return this[qn]; + } + mc = bindSafely(target.value, this); + mc.methodInfo = target.value.methodInfo; + defineReadOnlyProperty(mc, Multiname.getPublicQualifiedName('prototype'), null); + defineReadOnlyProperty(this, qn, mc); + return mc; + } + var m = memoizer; + Counter.count('Runtime: Memoizers'); + m.isMemoizer = true; + m.debugName = 'Memoizer #' + vmNextMemoizerId++; + return m; + } + Runtime.makeMemoizer = makeMemoizer; + function isTrampoline(fn) { + true; + return fn.isTrampoline; + } + Runtime.isTrampoline = isTrampoline; + function isMemoizer(fn) { + true; + return fn.isMemoizer; + } + Runtime.isMemoizer = isMemoizer; + }(AVM2.Runtime || (AVM2.Runtime = {}))); + var Runtime = AVM2.Runtime; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +var __extends = this.__extends || function (d, b) { + for (var p in b) + if (b.hasOwnProperty(p)) + d[p] = b[p]; + function __() { + this.constructor = d; + } + __.prototype = b.prototype; + d.prototype = new __(); + }; +var Shumway; +(function (Shumway) { + (function (AVM2) { + (function (Runtime) { + var Multiname = Shumway.AVM2.ABC.Multiname; + var Namespace = Shumway.AVM2.ABC.Namespace; + var MethodInfo = Shumway.AVM2.ABC.MethodInfo; + var ClassInfo = Shumway.AVM2.ABC.ClassInfo; + var InstanceInfo = Shumway.AVM2.ABC.InstanceInfo; + var ScriptInfo = Shumway.AVM2.ABC.ScriptInfo; + var Trait = Shumway.AVM2.ABC.Trait; + var IndentingWriter = Shumway.IndentingWriter; + var hasOwnProperty = Shumway.ObjectUtilities.hasOwnProperty; + var createMap = Shumway.ObjectUtilities.createMap; + var cloneObject = Shumway.ObjectUtilities.cloneObject; + var copyProperties = Shumway.ObjectUtilities.copyProperties; + var createEmptyObject = Shumway.ObjectUtilities.createEmptyObject; + var bindSafely = Shumway.FunctionUtilities.bindSafely; + var defineNonEnumerableGetterOrSetter = Shumway.ObjectUtilities.defineNonEnumerableGetterOrSetter; + var defineNonEnumerableProperty = Shumway.ObjectUtilities.defineNonEnumerableProperty; + var defineReadOnlyProperty = Shumway.ObjectUtilities.defineReadOnlyProperty; + var defineNonEnumerableGetter = Shumway.ObjectUtilities.defineNonEnumerableGetter; + var makeForwardingGetter = Shumway.FunctionUtilities.makeForwardingGetter; + var makeForwardingSetter = Shumway.FunctionUtilities.makeForwardingSetter; + var Binding = function () { + function Binding(trait) { + this.trait = trait; + } + Binding.getKey = function (qn, trait) { + var key = qn; + if (trait.isGetter()) { + key = Binding.GET_PREFIX + qn; + } else if (trait.isSetter()) { + key = Binding.SET_PREFIX + qn; + } + return key; + }; + Binding.prototype.toString = function () { + return String(this.trait); + }; + Binding.SET_PREFIX = 'set '; + Binding.GET_PREFIX = 'get '; + Binding.KEY_PREFIX_LENGTH = 4; + return Binding; + }(); + Runtime.Binding = Binding; + var SlotInfo = function () { + function SlotInfo(name, isConst, type, trait) { + this.name = name; + this.isConst = isConst; + this.type = type; + this.trait = trait; + } + return SlotInfo; + }(); + Runtime.SlotInfo = SlotInfo; + var SlotInfoMap = function () { + function SlotInfoMap() { + this.byID = createMap(); + this.byQN = createMap(); + } + return SlotInfoMap; + }(); + Runtime.SlotInfoMap = SlotInfoMap; + var Bindings = function () { + function Bindings() { + this.map = createMap(); + this.slots = []; + this.nextSlotId = 1; + } + Bindings.prototype.assignNextSlot = function (trait) { + true; + true; + if (!trait.slotId) { + trait.slotId = this.nextSlotId++; + } else { + this.nextSlotId = trait.slotId + 1; + } + true; + this.slots[trait.slotId] = trait; + }; + Bindings.prototype.trace = function (writer) { + writer.enter('Bindings'); + for (var key in this.map) { + var binding = this.map[key]; + writer.writeLn(binding.trait.kindName() + ': ' + key + ' -> ' + binding); + } + writer.leaveAndEnter('Slots'); + writer.writeArray(this.slots); + writer.outdent(); + }; + Bindings.prototype.applyTo = function (domain, object) { + true; + true; + true; + defineNonEnumerableProperty(object, Shumway.AVM2.Runtime.VM_SLOTS, new SlotInfoMap()); + defineNonEnumerableProperty(object, Shumway.AVM2.Runtime.VM_BINDINGS, []); + defineNonEnumerableProperty(object, Shumway.AVM2.Runtime.VM_OPEN_METHODS, createMap()); + defineNonEnumerableProperty(object, 'bindings', this); + defineNonEnumerableProperty(object, 'resolutionMap', []); + traitsWriter && traitsWriter.greenLn('Applying Traits'); + for (var key in this.map) { + var binding = this.map[key]; + var trait = binding.trait; + var qn = Multiname.getQualifiedName(trait.name); + if (trait.isSlot() || trait.isConst() || trait.isClass()) { + var defaultValue = undefined; + if (trait.isSlot() || trait.isConst()) { + if (trait.hasDefaultValue) { + defaultValue = trait.value; + } else if (trait.typeName) { + defaultValue = domain.findClassInfo(trait.typeName).defaultValue; + } + } + if (key !== qn) { + traitsWriter && traitsWriter.yellowLn('Binding Trait: ' + key + ' -> ' + qn); + defineNonEnumerableGetter(object, key, makeForwardingGetter(qn)); + object.asBindings.pushUnique(key); + } else { + traitsWriter && traitsWriter.greenLn('Applying Trait ' + trait.kindName() + ': ' + trait); + defineNonEnumerableProperty(object, qn, defaultValue); + object.asBindings.pushUnique(qn); + var slotInfo = new SlotInfo(qn, trait.isConst(), trait.typeName ? domain.getProperty(trait.typeName, false, false) : null, trait); + object.asSlots.byID[trait.slotId] = slotInfo; + object.asSlots.byQN[qn] = slotInfo; + } + } else if (trait.isMethod() || trait.isGetter() || trait.isSetter()) { + if (trait.isGetter() || trait.isSetter()) { + key = key.substring(Binding.KEY_PREFIX_LENGTH); + } + if (key !== qn) { + traitsWriter && traitsWriter.yellowLn('Binding Trait: ' + key + ' -> ' + qn); + } else { + traitsWriter && traitsWriter.greenLn('Applying Trait ' + trait.kindName() + ': ' + trait); + } + object.asBindings.pushUnique(key); + if (this instanceof ScriptBindings) { + Shumway.AVM2.Runtime.applyNonMemoizedMethodTrait(key, trait, object, binding.scope, binding.natives); + } else { + Shumway.AVM2.Runtime.applyMemoizedMethodTrait(key, trait, object, binding.scope, binding.natives); + } + } + } + }; + return Bindings; + }(); + Runtime.Bindings = Bindings; + var ActivationBindings = function (_super) { + __extends(ActivationBindings, _super); + function ActivationBindings(methodInfo) { + _super.call(this); + true; + this.methodInfo = methodInfo; + var traits = methodInfo.traits; + for (var i = 0; i < traits.length; i++) { + var trait = traits[i]; + true; + var key = Multiname.getQualifiedName(trait.name); + this.map[key] = new Binding(trait); + this.assignNextSlot(trait); + } + } + return ActivationBindings; + }(Bindings); + Runtime.ActivationBindings = ActivationBindings; + var CatchBindings = function (_super) { + __extends(CatchBindings, _super); + function CatchBindings(scope, trait) { + _super.call(this); + var key = Multiname.getQualifiedName(trait.name); + this.map[key] = new Binding(trait); + true; + this.assignNextSlot(trait); + } + return CatchBindings; + }(Bindings); + Runtime.CatchBindings = CatchBindings; + var ScriptBindings = function (_super) { + __extends(ScriptBindings, _super); + function ScriptBindings(scriptInfo, scope) { + _super.call(this); + this.scope = scope; + this.scriptInfo = scriptInfo; + var traits = scriptInfo.traits; + for (var i = 0; i < traits.length; i++) { + var trait = traits[i]; + var name = Multiname.getQualifiedName(trait.name); + var key = Binding.getKey(name, trait); + var binding = this.map[key] = new Binding(trait); + if (trait.isSlot() || trait.isConst() || trait.isClass()) { + this.assignNextSlot(trait); + } + if (trait.isClass()) { + if (trait.metadata && trait.metadata.native) { + trait.classInfo.native = trait.metadata.native; + } + } + if (trait.isMethod() || trait.isGetter() || trait.isSetter()) { + binding.scope = this.scope; + } + } + } + return ScriptBindings; + }(Bindings); + Runtime.ScriptBindings = ScriptBindings; + var ClassBindings = function (_super) { + __extends(ClassBindings, _super); + function ClassBindings(classInfo, scope, natives) { + _super.call(this); + this.scope = scope; + this.natives = natives; + this.classInfo = classInfo; + var traits = classInfo.traits; + for (var i = 0; i < traits.length; i++) { + var trait = traits[i]; + var name = Multiname.getQualifiedName(trait.name); + var key = Binding.getKey(name, trait); + var binding = this.map[key] = new Binding(trait); + if (trait.isSlot() || trait.isConst()) { + this.assignNextSlot(trait); + } + if (trait.isMethod() || trait.isGetter() || trait.isSetter()) { + binding.scope = this.scope; + binding.natives = this.natives; + } + } + } + return ClassBindings; + }(Bindings); + Runtime.ClassBindings = ClassBindings; + var InstanceBindings = function (_super) { + __extends(InstanceBindings, _super); + function InstanceBindings(parent, instanceInfo, scope, natives) { + _super.call(this); + this.scope = scope; + this.natives = natives; + this.parent = parent; + this.instanceInfo = instanceInfo; + this.implementedInterfaces = parent ? cloneObject(parent.implementedInterfaces) : createEmptyObject(); + if (parent) { + this.slots = parent.slots.slice(); + this.nextSlotId = parent.nextSlotId; + } + this.extend(parent); + } + InstanceBindings.prototype.extend = function (parent) { + var ii = this.instanceInfo, ib; + var map = this.map; + var name, key, trait, binding, protectedName, protectedKey; + if (parent) { + for (key in parent.map) { + binding = parent.map[key]; + trait = binding.trait; + map[key] = binding; + if (trait.isProtected()) { + protectedName = Multiname.getQualifiedName(new Multiname([ + ii.protectedNs + ], trait.name.getName())); + protectedKey = Binding.getKey(protectedName, trait); + map[protectedKey] = binding; + } + } + } + function writeOrOverwriteBinding(object, key, binding) { + var trait = binding.trait; + var oldBinding = object[key]; + if (oldBinding) { + var oldTrait = oldBinding.trait; + true; + true; + } else { + true; + } + object[key] = binding; + } + function overwriteProtectedBinding(object, key, binding) { + if (key in object) { + object[key] = binding; + } + } + var traits = ii.traits; + for (var i = 0; i < traits.length; i++) { + trait = traits[i]; + name = Multiname.getQualifiedName(trait.name); + key = Binding.getKey(name, trait); + binding = new Binding(trait); + writeOrOverwriteBinding(map, key, binding); + if (trait.isProtected()) { + ib = this.parent; + while (ib) { + protectedName = Multiname.getQualifiedName(new Multiname([ + ib.instanceInfo.protectedNs + ], trait.name.getName())); + protectedKey = Binding.getKey(protectedName, trait); + overwriteProtectedBinding(map, protectedKey, binding); + ib = ib.parent; + } + } + if (trait.isSlot() || trait.isConst()) { + this.assignNextSlot(trait); + } + if (trait.isMethod() || trait.isGetter() || trait.isSetter()) { + binding.scope = this.scope; + binding.natives = this.natives; + } + } + var domain = ii.abc.applicationDomain; + var interfaces = ii.interfaces; + for (var i = 0; i < interfaces.length; i++) { + var interface = domain.getProperty(interfaces[i], true, true); + true; + copyProperties(this.implementedInterfaces, interface.interfaceBindings.implementedInterfaces); + this.implementedInterfaces[Multiname.getQualifiedName(interface.name)] = interface; + } + for (var interfaceName in this.implementedInterfaces) { + var interface = this.implementedInterfaces[interfaceName]; + ib = interface.interfaceBindings; + for (var interfaceKey in ib.map) { + var interfaceBinding = ib.map[interfaceKey]; + if (ii.isInterface()) { + map[interfaceKey] = interfaceBinding; + } else { + name = Multiname.getPublicQualifiedName(interfaceBinding.trait.name.getName()); + key = Binding.getKey(name, interfaceBinding.trait); + map[interfaceKey] = map[key]; + } + } + } + }; + InstanceBindings.prototype.toString = function () { + return this.instanceInfo.toString(); + }; + return InstanceBindings; + }(Bindings); + Runtime.InstanceBindings = InstanceBindings; + var traitsWriter = null; + }(AVM2.Runtime || (AVM2.Runtime = {}))); + var Runtime = AVM2.Runtime; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +var Binding = Shumway.AVM2.Runtime.Binding; +var Bindings = Shumway.AVM2.Runtime.Bindings; +var ActivationBindings = Shumway.AVM2.Runtime.ActivationBindings; +var CatchBindings = Shumway.AVM2.Runtime.CatchBindings; +var ScriptBindings = Shumway.AVM2.Runtime.ScriptBindings; +var ClassBindings = Shumway.AVM2.Runtime.ClassBindings; +var InstanceBindings = Shumway.AVM2.Runtime.InstanceBindings; +var Shumway; +(function (Shumway) { + (function (AVM2) { + (function (Runtime) { + var Multiname = Shumway.AVM2.ABC.Multiname; + var Namespace = Shumway.AVM2.ABC.Namespace; + var MethodInfo = Shumway.AVM2.ABC.MethodInfo; + var ClassInfo = Shumway.AVM2.ABC.ClassInfo; + var InstanceInfo = Shumway.AVM2.ABC.InstanceInfo; + var InstanceBindings = Shumway.AVM2.Runtime.InstanceBindings; + var ClassBindings = Shumway.AVM2.Runtime.ClassBindings; + var defineNonEnumerableGetterOrSetter = Shumway.ObjectUtilities.defineNonEnumerableGetterOrSetter; + var defineNonEnumerableProperty = Shumway.ObjectUtilities.defineNonEnumerableProperty; + var defineReadOnlyProperty = Shumway.ObjectUtilities.defineReadOnlyProperty; + var defineNonEnumerableGetter = Shumway.ObjectUtilities.defineNonEnumerableGetter; + var createEmptyObject = Shumway.ObjectUtilities.createEmptyObject; + var toKeyValueArray = Shumway.ObjectUtilities.toKeyValueArray; + var boxValue = Shumway.ObjectUtilities.boxValue; + function makeCacheKey(namespaces, name, flags) { + if (!namespaces) { + return name; + } else if (namespaces.length > 1) { + return namespaces.runtimeId + '$' + name; + } else { + return namespaces[0].qualifiedName + '$' + name; + } + } + var Scope = function () { + function Scope(parent, object, isWith) { + if (typeof isWith === 'undefined') { + isWith = false; + } + this.parent = parent; + this.object = boxValue(object); + true; + this.global = parent ? parent.global : this; + this.isWith = isWith; + this.cache = createEmptyObject(); + } + Scope.prototype.findDepth = function (object) { + var current = this; + var depth = 0; + while (current) { + if (current.object === object) { + return depth; + } + depth++; + current = current.parent; + } + return -1; + }; + Scope.prototype.getScopeObjects = function () { + var objects = []; + var current = this; + while (current) { + objects.unshift(current.object); + current = current.parent; + } + return objects; + }; + Scope.prototype.findScopeProperty = function (namespaces, name, flags, domain, strict, scopeOnly) { + Counter.count('findScopeProperty'); + var object; + var key = makeCacheKey(namespaces, name, flags); + if (!scopeOnly && (object = this.cache[key])) { + return object; + } + if (this.object.asHasProperty(namespaces, name, flags, true)) { + return this.isWith ? this.object : this.cache[key] = this.object; + } + if (this.parent) { + return this.cache[key] = this.parent.findScopeProperty(namespaces, name, flags, domain, strict, scopeOnly); + } + if (scopeOnly) + return null; + if (object = domain.findDomainProperty(new Multiname(namespaces, name, flags), strict, true)) { + return object; + } + if (strict) { + Shumway.Debug.unexpected('Cannot find property ' + name); + } + return this.global.object; + }; + return Scope; + }(); + Runtime.Scope = Scope; + function bindFreeMethodScope(methodInfo, scope) { + var fn = methodInfo.freeMethod; + if (methodInfo.lastBoundMethod && methodInfo.lastBoundMethod.scope === scope) { + return methodInfo.lastBoundMethod.boundMethod; + } + true; + var boundMethod; + var asGlobal = scope.global.object; + if (!methodInfo.hasOptional() && !methodInfo.needsArguments() && !methodInfo.needsRest()) { + switch (methodInfo.parameters.length) { + case 0: + boundMethod = function () { + return fn.call(this === jsGlobal ? asGlobal : this, scope); + }; + break; + case 1: + boundMethod = function (x) { + return fn.call(this === jsGlobal ? asGlobal : this, scope, x); + }; + break; + case 2: + boundMethod = function (x, y) { + return fn.call(this === jsGlobal ? asGlobal : this, scope, x, y); + }; + break; + case 3: + boundMethod = function (x, y, z) { + return fn.call(this === jsGlobal ? asGlobal : this, scope, x, y, z); + }; + break; + default: + break; + } + } + if (!boundMethod) { + Counter.count('Bind Scope - Slow Path'); + boundMethod = function () { + Array.prototype.unshift.call(arguments, scope); + var global = this === jsGlobal ? scope.global.object : this; + return fn.apply(global, arguments); + }; + } + boundMethod.methodInfo = methodInfo; + boundMethod.instanceConstructor = boundMethod; + methodInfo.lastBoundMethod = { + scope: scope, + boundMethod: boundMethod + }; + return boundMethod; + } + Runtime.bindFreeMethodScope = bindFreeMethodScope; + }(AVM2.Runtime || (AVM2.Runtime = {}))); + var Runtime = AVM2.Runtime; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +var playerglobalLoadedPromise; +var playerglobal; +var Shumway; +(function (Shumway) { + (function (AVM2) { + (function (Runtime) { + var AbcFile = Shumway.AVM2.ABC.AbcFile; + var Multiname = Shumway.AVM2.ABC.Multiname; + var Namespace = Shumway.AVM2.ABC.Namespace; + var MethodInfo = Shumway.AVM2.ABC.MethodInfo; + var ClassInfo = Shumway.AVM2.ABC.ClassInfo; + var InstanceInfo = Shumway.AVM2.ABC.InstanceInfo; + var ScriptInfo = Shumway.AVM2.ABC.ScriptInfo; + var createEmptyObject = Shumway.ObjectUtilities.createEmptyObject; + var IndentingWriter = Shumway.IndentingWriter; + (function (EXECUTION_MODE) { + EXECUTION_MODE[EXECUTION_MODE['INTERPRET'] = 1] = 'INTERPRET'; + EXECUTION_MODE[EXECUTION_MODE['COMPILE'] = 2] = 'COMPILE'; + }(Runtime.EXECUTION_MODE || (Runtime.EXECUTION_MODE = {}))); + var EXECUTION_MODE = Runtime.EXECUTION_MODE; + function createNewCompartment() { + return newGlobal('new-compartment'); + } + function executeScript(script) { + var abc = script.abc; + true; + var global = new Shumway.AVM2.Runtime.Global(script); + if (abc.applicationDomain.allowNatives) { + global[Multiname.getPublicQualifiedName('unsafeJSNative')] = getNative; + } + script.executing = true; + var scope = new Shumway.AVM2.Runtime.Scope(null, script.global); + createFunction(script.init, scope).call(script.global, false); + script.executed = true; + } + Runtime.executeScript = executeScript; + function ensureScriptIsExecuted(script, reason) { + if (typeof reason === 'undefined') { + reason = ''; + } + if (!script.executed && !script.executing) { + if (Shumway.AVM2.Runtime.traceExecution.value >= 2) { + log('Executing Script For: ' + reason); + } + executeScript(script); + } + } + Runtime.ensureScriptIsExecuted = ensureScriptIsExecuted; + (function (Glue) { + Glue[Glue['PUBLIC_PROPERTIES'] = 1] = 'PUBLIC_PROPERTIES'; + Glue[Glue['PUBLIC_METHODS'] = 2] = 'PUBLIC_METHODS'; + Glue[Glue['ALL'] = 1 | 2] = 'ALL'; + }(Runtime.Glue || (Runtime.Glue = {}))); + var Glue = Runtime.Glue; + function grabAbc(abcName) { + var entry = playerglobal.scripts[abcName]; + if (!entry) { + return null; + } + var offset = entry.offset; + var length = entry.length; + return new AbcFile(new Uint8Array(playerglobal.abcs, offset, length), abcName); + } + function findDefiningAbc(mn) { + if (!playerglobal) { + return null; + } + for (var i = 0; i < mn.namespaces.length; i++) { + var name = mn.namespaces[i].uri + ':' + mn.name; + var abcName = playerglobal.map[name]; + if (abcName) { + break; + } + } + if (abcName) { + return grabAbc(abcName); + } + return null; + } + function promiseFile(path, responseType) { + return new Promise(function (resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', path); + xhr.responseType = responseType; + xhr.onload = function () { + if (xhr.response) { + resolve(xhr.response); + } else { + reject('Unable to load ' + path + ': ' + xhr.statusText); + } + }; + xhr.send(); + }); + } + var AVM2 = function () { + function AVM2(sysMode, appMode, loadAVM1) { + this.systemDomain = new ApplicationDomain(this, null, sysMode, true); + this.applicationDomain = new ApplicationDomain(this, this.systemDomain, appMode, false); + this.findDefiningAbc = findDefiningAbc; + this.loadAVM1 = loadAVM1; + this.isAVM1Loaded = false; + this.exception = { + value: undefined + }; + this.exceptions = []; + } + AVM2.initialize = function (sysMode, appMode, loadAVM1) { + AVM2.instance = new AVM2(sysMode, appMode, loadAVM1); + }; + AVM2.currentAbc = function () { + var caller = arguments.callee; + var maxDepth = 20; + var abc = null; + for (var i = 0; i < maxDepth && caller; i++) { + var mi = caller.methodInfo; + if (mi) { + abc = mi.abc; + break; + } + caller = caller.caller; + } + return abc; + }; + AVM2.currentDomain = function () { + var abc = AVM2.currentAbc(); + return abc.applicationDomain; + }; + AVM2.isPlayerglobalLoaded = function () { + return !(!playerglobal); + }; + AVM2.loadPlayerglobal = function (abcsPath, catalogPath) { + if (playerglobalLoadedPromise) { + return Promise.reject('Playerglobal is already loaded'); + } + playerglobalLoadedPromise = Promise.all([ + promiseFile(abcsPath, 'arraybuffer'), + promiseFile(catalogPath, 'json') + ]).then(function (result) { + playerglobal = { + abcs: result[0], + map: Object.create(null), + scripts: Object.create(null) + }; + var catalog = result[1]; + for (var i = 0; i < catalog.length; i++) { + var abc = catalog[i]; + playerglobal.scripts[abc.name] = abc; + if (typeof abc.defs === 'string') { + playerglobal.map[abc.defs] = abc.name; + } else { + for (var j = 0; j < abc.defs.length; j++) { + var def = abc.defs[j]; + playerglobal.map[def] = abc.name; + } + } + } + }, function (e) { + console.error(e); + }); + return playerglobalLoadedPromise; + }; + AVM2.prototype.notifyConstruct = function (instanceConstructor, args) { + }; + AVM2.getStackTrace = function () { + Shumway.Debug.notImplemented('getStackTrace'); + }; + return AVM2; + }(); + Runtime.AVM2 = AVM2; + var ApplicationDomain = function () { + function ApplicationDomain(vm, base, mode, allowNatives) { + true; + true; + this.vm = vm; + this.abcs = []; + this.loadedAbcs = {}; + this.loadedClasses = []; + this.classCache = createEmptyObject(); + this.scriptCache = createEmptyObject(); + this.classInfoCache = createEmptyObject(); + this.base = base; + this.allowNatives = allowNatives; + this.mode = mode; + this.onMessage = new Callback(); + if (base) { + this.system = base.system; + } else { + this.system = this; + } + } + ApplicationDomain.passthroughCallable = function (f) { + return { + call: function ($this) { + Array.prototype.shift.call(arguments); + return f.apply($this, arguments); + }, + apply: function ($this, args) { + return f.apply($this, args); + } + }; + }; + ApplicationDomain.coerceCallable = function (type) { + return { + call: function ($this, value) { + return Shumway.AVM2.Runtime.asCoerce(type, value); + }, + apply: function ($this, args) { + return Shumway.AVM2.Runtime.asCoerce(type, args[0]); + } + }; + }; + ApplicationDomain.constructingCallable = function (instanceConstructor) { + return { + call: function (self) { + return new (Function.bind.apply(instanceConstructor, arguments))(); + }, + apply: function (self, args) { + return new (Function.bind.apply(instanceConstructor, [ + self + ].concat(args)))(); + } + }; + }; + ApplicationDomain.prototype.getType = function (multiname) { + return this.getProperty(multiname, true, true); + }; + ApplicationDomain.prototype.getProperty = function (multiname, strict, execute) { + var resolved = this.findDefiningScript(multiname, execute); + if (resolved) { + if (!resolved.script.executing) { + return undefined; + } + return resolved.script.global[Multiname.getQualifiedName(resolved.trait.name)]; + } + if (strict) { + return Shumway.Debug.unexpected('Cannot find property ' + multiname); + } + return undefined; + }; + ApplicationDomain.prototype.getClass = function (simpleName) { + var cache = this.classCache; + var c = cache[simpleName]; + if (!c) { + c = cache[simpleName] = this.getProperty(Multiname.fromSimpleName(simpleName), true, true); + } + true; + return c; + }; + ApplicationDomain.prototype.findClass = function (simpleName) { + if (simpleName in this.classCache) { + return true; + } + return this.findDomainProperty(Multiname.fromSimpleName(simpleName), false, true); + }; + ApplicationDomain.prototype.findDomainProperty = function (multiname, strict, execute) { + if (Shumway.AVM2.Runtime.traceDomain.value) { + log('ApplicationDomain.findDomainProperty: ' + multiname); + } + var resolved = this.findDefiningScript(multiname, execute); + if (resolved) { + return resolved.script.global; + } + if (strict) { + return Shumway.Debug.unexpected('Cannot find property ' + multiname); + } else { + return undefined; + } + return undefined; + }; + ApplicationDomain.prototype.findClassInfo = function (mn) { + var originalQn; + if (Multiname.isQName(mn)) { + originalQn = Multiname.getQualifiedName(mn); + var ci = this.classInfoCache[originalQn]; + if (ci) { + return ci; + } + } else { + var ci = this.classInfoCache[mn.runtimeId]; + if (ci) { + return ci; + } + } + if (this.base) { + ci = this.base.findClassInfo(mn); + if (ci) { + return ci; + } + } + var abcs = this.abcs; + for (var i = 0; i < abcs.length; i++) { + var abc = abcs[i]; + var scripts = abc.scripts; + for (var j = 0; j < scripts.length; j++) { + var script = scripts[j]; + var traits = script.traits; + for (var k = 0; k < traits.length; k++) { + var trait = traits[k]; + if (trait.isClass()) { + var traitName = Multiname.getQualifiedName(trait.name); + if (originalQn) { + if (traitName === originalQn) { + return this.classInfoCache[originalQn] = trait.classInfo; + } + } else { + for (var m = 0, n = mn.namespaces.length; m < n; m++) { + var qn = mn.getQName(m); + if (traitName === Multiname.getQualifiedName(qn)) { + return this.classInfoCache[qn] = trait.classInfo; + } + } + } + } + } + } + } + if (!this.base && this.vm.findDefiningAbc) { + var abc = this.vm.findDefiningAbc(mn); + if (abc !== null && !this.loadedAbcs[abc.name]) { + this.loadedAbcs[abc.name] = true; + this.loadAbc(abc); + return this.findClassInfo(mn); + } + } + return undefined; + }; + ApplicationDomain.prototype.installNative = function (name, func) { + natives[name] = function () { + return func; + }; + }; + ApplicationDomain.prototype.findDefiningScript = function (mn, execute) { + var resolved = this.scriptCache[mn.runtimeId]; + if (resolved && (resolved.script.executed || !execute)) { + return resolved; + } + if (this.base) { + resolved = this.base.findDefiningScript(mn, execute); + if (resolved) { + return resolved; + } + } + Counter.count('ApplicationDomain: findDefiningScript'); + var abcs = this.abcs; + for (var i = 0; i < abcs.length; i++) { + var abc = abcs[i]; + var scripts = abc.scripts; + for (var j = 0; j < scripts.length; j++) { + var script = scripts[j]; + var traits = script.traits; + if (mn instanceof Multiname) { + for (var k = 0; k < traits.length; k++) { + var trait = traits[k]; + if (mn.hasQName(trait.name)) { + if (execute) { + ensureScriptIsExecuted(script, String(trait.name)); + } + return this.scriptCache[mn.runtimeId] = { + script: script, + trait: trait + }; + } + } + } else { + Shumway.Debug.unexpected(); + } + } + } + if (!this.base && this.vm.findDefiningAbc) { + var abc = this.vm.findDefiningAbc(mn); + if (abc !== null && !this.loadedAbcs[abc.name]) { + this.loadedAbcs[abc.name] = true; + this.loadAbc(abc); + return this.findDefiningScript(mn, execute); + } + } + return undefined; + }; + ApplicationDomain.prototype.compileAbc = function (abc, writer) { + compileAbc(abc, writer); + }; + ApplicationDomain.prototype.executeAbc = function (abc) { + this.loadAbc(abc); + executeScript(abc.lastScript); + }; + ApplicationDomain.prototype.loadAbc = function (abc) { + if (Shumway.AVM2.Runtime.traceExecution.value) { + log('Loading: ' + abc.name); + } + abc.applicationDomain = this; + GlobalMultinameResolver.loadAbc(abc); + this.abcs.push(abc); + if (!this.base) { + Type.initializeTypes(this); + } + }; + ApplicationDomain.prototype.broadcastMessage = function (type, message, origin) { + if (debug) { + Timer.start('broadcast: ' + type); + } + try { + this.onMessage.notify1(type, { + data: message, + origin: origin, + source: this + }); + } catch (e) { + avm2.exceptions.push({ + source: type, + message: e.message, + stack: e.stack + }); + throw e; + } + if (debug) { + Timer.stop(); + } + }; + ApplicationDomain.prototype.traceLoadedClasses = function (lastOnly) { + var writer = new IndentingWriter(); + lastOnly || writer.enter('Loaded Classes And Interfaces'); + var classes = lastOnly ? [ + this.loadedClasses.last() + ] : this.loadedClasses; + classes.forEach(function (cls) { + if (cls !== Shumway.AVM2.Runtime.Class) { + cls.trace(writer); + } + }); + lastOnly || writer.leave(''); + }; + return ApplicationDomain; + }(); + Runtime.ApplicationDomain = ApplicationDomain; + var SecurityDomain = function () { + function SecurityDomain() { + this.compartment = createNewCompartment(); + this.compartment.homePath = homePath; + this.compartment.release = true; + this.compartment.eval(snarf('compartment.js')); + } + SecurityDomain.prototype.initializeShell = function (sysMode, appMode) { + var compartment = this.compartment; + compartment.AVM2.initialize(sysMode, appMode); + compartment.AVM2.instance.systemDomain.executeAbc(compartment.grabAbc(homePath + 'src/avm2/generated/builtin/builtin.abc')); + compartment.AVM2.instance.systemDomain.executeAbc(compartment.grabAbc(homePath + 'src/avm2/generated/shell/shell.abc')); + this.systemDomain = compartment.AVM2.instance.systemDomain; + this.applicationDomain = compartment.AVM2.instance.applicationDomain; + }; + return SecurityDomain; + }(); + Runtime.SecurityDomain = SecurityDomain; + }(AVM2.Runtime || (AVM2.Runtime = {}))); + var Runtime = AVM2.Runtime; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +var Glue = Shumway.AVM2.Runtime.Glue; +var ApplicationDomain = Shumway.AVM2.Runtime.ApplicationDomain; +var AVM2 = Shumway.AVM2.Runtime.AVM2; +var EXECUTION_MODE = Shumway.AVM2.Runtime.EXECUTION_MODE; +var ApplicationDomain = Shumway.AVM2.Runtime.ApplicationDomain; +var AVM2 = Shumway.AVM2.Runtime.AVM2; +var EXECUTION_MODE = Shumway.AVM2.Runtime.EXECUTION_MODE; +var Shumway; +(function (Shumway) { + (function (AVM2) { + (function (Runtime) { + var Multiname = Shumway.AVM2.ABC.Multiname; + var Namespace = Shumway.AVM2.ABC.Namespace; + var ClassInfo = Shumway.AVM2.ABC.ClassInfo; + var InstanceInfo = Shumway.AVM2.ABC.InstanceInfo; + var InstanceBindings = Shumway.AVM2.Runtime.InstanceBindings; + var ClassBindings = Shumway.AVM2.Runtime.ClassBindings; + var defineNonEnumerableGetterOrSetter = Shumway.ObjectUtilities.defineNonEnumerableGetterOrSetter; + var defineNonEnumerableProperty = Shumway.ObjectUtilities.defineNonEnumerableProperty; + var defineReadOnlyProperty = Shumway.ObjectUtilities.defineReadOnlyProperty; + var defineNonEnumerableGetter = Shumway.ObjectUtilities.defineNonEnumerableGetter; + var createEmptyObject = Shumway.ObjectUtilities.createEmptyObject; + var toKeyValueArray = Shumway.ObjectUtilities.toKeyValueArray; + var Interface = function () { + function Interface(classInfo) { + var ii = classInfo.instanceInfo; + true; + this.name = ii.name; + this.classInfo = classInfo; + } + Interface.createInterface = function (classInfo) { + var ii = classInfo.instanceInfo; + true; + if (Shumway.AVM2.Runtime.traceExecution.value) { + var str = 'Creating Interface ' + ii.name; + if (ii.interfaces.length) { + str += ' implements ' + ii.interfaces.map(function (name) { + return name.getName(); + }).join(', '); + } + log(str); + } + var cls = new Interface(classInfo); + cls.interfaceBindings = new InstanceBindings(null, ii, null, null); + return cls; + }; + Interface.prototype.toString = function () { + return '[interface ' + this.name + ']'; + }; + Interface.prototype.isInstance = function (value) { + if (value === null || typeof value !== 'object') { + return false; + } + true; + var qualifiedName = Multiname.getQualifiedName(this.name); + return value.class.implementedInterfaces[qualifiedName] !== undefined; + }; + Interface.prototype.trace = function (writer) { + writer.enter('interface ' + this.name.getName()); + writer.enter('interfaceBindings: '); + this.interfaceBindings.trace(writer); + writer.outdent(); + writer.outdent(); + writer.leave('}'); + }; + Interface.prototype.call = function (self, x) { + return x; + }; + Interface.prototype.apply = function (self, args) { + return args[0]; + }; + return Interface; + }(); + Runtime.Interface = Interface; + function setDefaultProperties(cls) { + defineNonEnumerableProperty(cls.dynamicPrototype, Multiname.getPublicQualifiedName('constructor'), cls); + defineReadOnlyProperty(cls.traitsPrototype, 'class', cls); + defineReadOnlyProperty(cls.instanceConstructor, 'class', cls); + } + Runtime.setDefaultProperties = setDefaultProperties; + var Class = function () { + function Class(name, instanceConstructor, callable) { + this.debugName = name; + if (instanceConstructor) { + true; + this.instanceConstructor = instanceConstructor; + this.instanceConstructorNoInitialize = instanceConstructor; + this.hasInitialize = 0; + this.instanceConstructor.class = this; + } + if (!callable) { + callable = Shumway.AVM2.Runtime.ApplicationDomain.coerceCallable(this); + } else if (callable === Shumway.AVM2.Runtime.ApplicationDomain.coerceCallable) { + callable = Shumway.AVM2.Runtime.ApplicationDomain.coerceCallable(this); + } + defineNonEnumerableProperty(this, 'call', callable.call); + defineNonEnumerableProperty(this, 'apply', callable.apply); + } + Class.createClass = function (classInfo, baseClass, scope) { + var ci = classInfo; + var ii = ci.instanceInfo; + var domain = ci.abc.applicationDomain; + var className = Multiname.getName(ii.name); + var isNativeClass = ci.native; + if (isNativeClass) { + var buildClass = getNative(ci.native.cls); + if (!buildClass) { + Shumway.Debug.unexpected('No native for ' + ci.native.cls); + } + if (!baseClass) { + scope = new Scope(scope, Class); + } + } + var classScope = new Scope(scope, null); + var instanceConstructor = createFunction(ii.init, classScope, false); + var cls; + if (isNativeClass) { + cls = buildClass(domain, classScope, instanceConstructor, baseClass); + } else { + cls = new Class(className, instanceConstructor); + } + cls.className = className; + cls.classInfo = classInfo; + cls.scope = classScope; + classScope.object = cls; + var classNatives; + var instanceNatives; + if (isNativeClass) { + if (cls.native) { + classNatives = cls.native.static; + instanceNatives = cls.native.instance; + } + } else { + cls.extend(baseClass); + } + cls.classBindings = new ClassBindings(classInfo, classScope, classNatives); + cls.classBindings.applyTo(domain, cls); + defineReadOnlyProperty(cls, Shumway.AVM2.Runtime.VM_IS_CLASS, true); + cls.instanceBindings = new InstanceBindings(baseClass ? baseClass.instanceBindings : null, ii, classScope, instanceNatives); + if (cls.instanceConstructor) { + cls.instanceBindings.applyTo(domain, cls.traitsPrototype); + } + cls.implementedInterfaces = cls.instanceBindings.implementedInterfaces; + return cls; + }; + Class.prototype.setSymbol = function (props) { + this.instanceConstructor.prototype.symbol = props; + }; + Class.prototype.getSymbol = function () { + return this.instanceConstructor.prototype.symbol; + }; + Class.prototype.initializeInstance = function (obj) { + var c = this; + var initializes = []; + while (c) { + if (c.hasInitialize & Class.OWN_INITIALIZE) { + initializes.push(c.instanceConstructor.prototype.initialize); + } + c = c.baseClass; + } + var s; + while (s = initializes.pop()) { + s.call(obj); + } + Counter.count('Initialize Instance ' + obj.class); + }; + Class.prototype.createInstance = function (args) { + var o = Object.create(this.instanceConstructor.prototype); + this.instanceConstructor.apply(o, args); + return o; + }; + Class.prototype.createAsSymbol = function (props) { + var o = Object.create(this.instanceConstructor.prototype); + if (o.symbol) { + var symbol = Object.create(o.symbol); + for (var prop in props) { + symbol[prop] = props[prop]; + } + o.symbol = symbol; + } else { + o.symbol = props; + } + return o; + }; + Class.prototype.extendNative = function (baseClass, native) { + this.baseClass = baseClass; + this.dynamicPrototype = Object.getPrototypeOf(native.prototype); + this.instanceConstructor.prototype = this.traitsPrototype = native.prototype; + setDefaultProperties(this); + }; + Class.prototype.extendWrapper = function (baseClass, wrapper) { + true; + this.baseClass = baseClass; + this.dynamicPrototype = Object.create(baseClass.dynamicPrototype); + var traitsPrototype = Object.create(this.dynamicPrototype, Shumway.ObjectUtilities.getOwnPropertyDescriptors(wrapper.prototype)); + this.instanceConstructor.prototype = this.traitsPrototype = traitsPrototype; + setDefaultProperties(this); + }; + Class.prototype.extendBuiltin = function (baseClass) { + true; + this.baseClass = baseClass; + this.dynamicPrototype = this.traitsPrototype = this.instanceConstructor.prototype; + setDefaultProperties(this); + }; + Class.prototype.extend = function (baseClass) { + true; + this.baseClass = baseClass; + this.dynamicPrototype = Object.create(baseClass.dynamicPrototype); + if (baseClass.hasInitialize) { + var instanceConstructorNoInitialize = this.instanceConstructor; + var self = this; + this.instanceConstructor = function () { + self.initializeInstance(this); + instanceConstructorNoInitialize.apply(this, arguments); + }; + defineReadOnlyProperty(this.instanceConstructor, 'class', instanceConstructorNoInitialize.class); + this.hasInitialize |= Class.SUPER_INITIALIZE; + } + this.instanceConstructor.prototype = this.traitsPrototype = Object.create(this.dynamicPrototype); + setDefaultProperties(this); + }; + Class.prototype.setDefaultProperties = function () { + setDefaultProperties(this); + }; + Class.prototype.link = function (definition) { + true; + true; + if (definition.initialize) { + if (!this.hasInitialize) { + var instanceConstructorNoInitialize = this.instanceConstructor; + var self = this; + this.instanceConstructor = function () { + self.initializeInstance(this); + instanceConstructorNoInitialize.apply(this, arguments); + }; + defineReadOnlyProperty(this.instanceConstructor, 'class', instanceConstructorNoInitialize.class); + this.instanceConstructor.prototype = instanceConstructorNoInitialize.prototype; + } + this.hasInitialize |= Class.OWN_INITIALIZE; + } + var dynamicPrototype = this.dynamicPrototype; + var keys = Object.keys(definition); + for (var i = 0; i < keys.length; i++) { + var propertyName = keys[i]; + Object.defineProperty(dynamicPrototype, propertyName, Object.getOwnPropertyDescriptor(definition, propertyName)); + } + function glueProperties(obj, properties) { + var keys = Object.keys(properties); + for (var i = 0; i < keys.length; i++) { + var propertyName = keys[i]; + var propertyGlue = properties[propertyName]; + var propertySimpleName; + var glueOpenMethod = false; + if (propertyGlue.indexOf('open ') >= 0) { + propertySimpleName = propertyGlue.substring(5); + glueOpenMethod = true; + } else { + propertySimpleName = propertyGlue; + } + true; + var qn = Multiname.getQualifiedName(Multiname.fromSimpleName(propertySimpleName)); + if (glueOpenMethod) { + qn = Shumway.AVM2.Runtime.VM_OPEN_METHOD_PREFIX + qn; + } + true; + var descriptor = Object.getOwnPropertyDescriptor(obj, qn); + if (descriptor && descriptor.get) { + Object.defineProperty(obj, propertyName, descriptor); + } else { + Object.defineProperty(obj, propertyName, { + get: new Function('', 'return this.' + qn), + set: new Function('v', 'this.' + qn + ' = v') + }); + } + } + } + function generatePropertiesFromTraits(traits) { + var properties = createEmptyObject(); + traits.forEach(function (trait) { + var ns = trait.name.getNamespace(); + if (!ns.isPublic()) { + return; + } + properties[trait.name.getName()] = (trait.isMethod() ? 'open ' : '') + 'public ' + trait.name.getName(); + }); + return properties; + } + var glue = definition.__glue__; + if (!glue) { + return; + } + if (glue.script) { + if (glue.script.instance) { + if (Shumway.isNumber(glue.script.instance)) { + true; + glueProperties(dynamicPrototype, generatePropertiesFromTraits(this.classInfo.instanceInfo.traits)); + } else { + glueProperties(dynamicPrototype, glue.script.instance); + } + } + if (glue.script.static) { + if (Shumway.isNumber(glue.script.static)) { + true; + glueProperties(this, generatePropertiesFromTraits(this.classInfo.traits)); + } else { + glueProperties(this, glue.script.static); + } + } + } + }; + Class.prototype.linkNatives = function (definition) { + var glue = definition.__glue__; + this.native = glue.native; + }; + Class.prototype.verify = function () { + var instanceConstructor = this.instanceConstructor; + var tP = this.traitsPrototype; + var dP = this.dynamicPrototype; + true; + true; + true; + true; + if (tP !== Object.prototype) { + } + true; + }; + Class.prototype.coerce = function (value) { + return value; + }; + Class.prototype.isInstanceOf = function (value) { + return this.isInstance(value); + }; + Class.prototype.isInstance = function (value) { + if (value === null || typeof value !== 'object') { + return false; + } + return this.dynamicPrototype.isPrototypeOf(value); + }; + Class.prototype.trace = function (writer) { + var description = this.debugName + (this.baseClass ? ' extends ' + this.baseClass.debugName : ''); + writer.enter('class ' + description + ' {'); + writer.writeLn('scope: ' + this.scope); + writer.writeLn('baseClass: ' + this.baseClass); + writer.writeLn('classInfo: ' + this.classInfo); + writer.writeLn('dynamicPrototype: ' + this.dynamicPrototype); + writer.writeLn('traitsPrototype: ' + this.traitsPrototype); + writer.writeLn('dynamicPrototype === traitsPrototype: ' + (this.dynamicPrototype === this.traitsPrototype)); + writer.writeLn('instanceConstructor: ' + this.instanceConstructor); + writer.writeLn('instanceConstructorNoInitialize: ' + this.instanceConstructorNoInitialize); + writer.writeLn('instanceConstructor === instanceConstructorNoInitialize: ' + (this.instanceConstructor === this.instanceConstructorNoInitialize)); + var traitsPrototype = this.traitsPrototype; + writer.enter('traitsPrototype: '); + if (traitsPrototype) { + writer.enter('VM_SLOTS: '); + writer.writeArray(traitsPrototype.asSlots.byID.map(function (slot) { + return slot.trait; + })); + writer.outdent(); + writer.enter('VM_BINDINGS: '); + writer.writeArray(traitsPrototype.asBindings.map(function (binding) { + var pd = Object.getOwnPropertyDescriptor(traitsPrototype, binding); + var str = binding; + if (pd.get || pd.set) { + if (pd.get) { + str += ' getter: ' + debugName(pd.get); + } + if (pd.set) { + str += ' setter: ' + debugName(pd.set); + } + } else { + str += ' value: ' + debugName(pd.value); + } + return str; + })); + writer.outdent(); + writer.enter('VM_OPEN_METHODS: '); + writer.writeArray(toKeyValueArray(traitsPrototype.asOpenMethods).map(function (pair) { + return pair[0] + ': ' + debugName(pair[1]); + })); + writer.outdent(); + } + writer.enter('classBindings: '); + this.classBindings.trace(writer); + writer.outdent(); + writer.enter('instanceBindings: '); + this.instanceBindings.trace(writer); + writer.outdent(); + writer.outdent(); + writer.writeLn('call: ' + this.call); + writer.writeLn('apply: ' + this.apply); + writer.leave('}'); + }; + Class.prototype.toString = function () { + return '[class ' + this.classInfo.instanceInfo.name.name + ']'; + }; + Class.OWN_INITIALIZE = 1; + Class.SUPER_INITIALIZE = 2; + return Class; + }(); + Runtime.Class = Class; + var callable = Shumway.AVM2.Runtime.ApplicationDomain.coerceCallable(Class); + defineNonEnumerableProperty(Class, 'call', callable.call); + defineNonEnumerableProperty(Class, 'apply', callable.apply); + Class.instanceConstructor = Class; + Class.toString = Class.prototype.toString; + Class.native = { + instance: { + prototype: { + get: function () { + return this.dynamicPrototype; + } + } + } + }; + }(AVM2.Runtime || (AVM2.Runtime = {}))); + var Runtime = AVM2.Runtime; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +var Interface = Shumway.AVM2.Runtime.Interface; +var Class = Shumway.AVM2.Runtime.Class; +var Binding = Shumway.AVM2.Runtime.Binding; +var Bindings = Shumway.AVM2.Runtime.Bindings; +var ActivationBindings = Shumway.AVM2.Runtime.ActivationBindings; +var CatchBindings = Shumway.AVM2.Runtime.CatchBindings; +var ScriptBindings = Shumway.AVM2.Runtime.ScriptBindings; +var ClassBindings = Shumway.AVM2.Runtime.ClassBindings; +var InstanceBindings = Shumway.AVM2.Runtime.InstanceBindings; +var Interface = Shumway.AVM2.Runtime.Interface; +var Class = Shumway.AVM2.Runtime.Class; +var XRegExp = function (undefined) { + var REGEX_DATA = 'xregexp', self, features = { + astral: false, + natives: false + }, nativ = { + exec: RegExp.prototype.exec, + test: RegExp.prototype.test, + match: String.prototype.match, + replace: String.prototype.replace, + split: String.prototype.split + }, fixed = {}, cache = {}, patternCache = {}, tokens = [], defaultScope = 'default', classScope = 'class', nativeTokens = { + 'default': /\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S])|\(\?[:=!]|[?*+]\?|{\d+(?:,\d*)?}\??|[\s\S]/, + 'class': /\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S])|[\s\S]/ + }, replacementToken = /\$(?:{([\w$]+)}|([\d$&`']))/g, correctExecNpcg = nativ.exec.call(/()??/, '')[1] === undefined, hasNativeY = RegExp.prototype.sticky !== undefined, registeredFlags = { + g: true, + i: true, + m: true, + y: hasNativeY + }, toString = {}.toString, add; + function augment(regex, captureNames, addProto) { + var p; + if (addProto) { + if (regex.__proto__) { + regex.__proto__ = self.prototype; + } else { + for (p in self.prototype) { + regex[p] = self.prototype[p]; + } + } + } + regex[REGEX_DATA] = { + captureNames: captureNames + }; + return regex; + } + function clipDuplicates(str) { + return nativ.replace.call(str, /([\s\S])(?=[\s\S]*\1)/g, ''); + } + function copy(regex, options) { + if (!self.isRegExp(regex)) { + throw new TypeError('Type RegExp expected'); + } + var flags = nativ.exec.call(/\/([a-z]*)$/i, String(regex))[1]; + options = options || {}; + if (options.add) { + flags = clipDuplicates(flags + options.add); + } + if (options.remove) { + flags = nativ.replace.call(flags, new RegExp('[' + options.remove + ']+', 'g'), ''); + } + regex = augment(new RegExp(regex.source, flags), hasNamedCapture(regex) ? regex[REGEX_DATA].captureNames.slice(0) : null, options.addProto); + return regex; + } + function getBaseProps() { + return { + captureNames: null + }; + } + function hasNamedCapture(regex) { + return !(!(regex[REGEX_DATA] && regex[REGEX_DATA].captureNames)); + } + function indexOf(array, value) { + if (Array.prototype.indexOf) { + return array.indexOf(value); + } + var len = array.length, i; + for (i = 0; i < len; ++i) { + if (array[i] === value) { + return i; + } + } + return -1; + } + function isType(value, type) { + return toString.call(value) === '[object ' + type + ']'; + } + function isQuantifierNext(pattern, pos, flags) { + return nativ.test.call(flags.indexOf('x') > -1 ? /^(?:\s+|#.*|\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/ : /^(?:\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/, pattern.slice(pos)); + } + function prepareFlags(pattern, flags) { + var i; + if (clipDuplicates(flags) !== flags) { + throw new SyntaxError('Invalid duplicate regex flag ' + flags); + } + pattern = nativ.replace.call(pattern, /^\(\?([\w$]+)\)/, function ($0, $1) { + if (nativ.test.call(/[gy]/, $1)) { + throw new SyntaxError('Cannot use flag g or y in mode modifier ' + $0); + } + flags = clipDuplicates(flags + $1); + return ''; + }); + for (i = 0; i < flags.length; ++i) { + if (!registeredFlags[flags.charAt(i)]) { + throw new SyntaxError('Unknown regex flag ' + flags.charAt(i)); + } + } + return { + pattern: pattern, + flags: flags + }; + } + function prepareOptions(value) { + value = value || {}; + if (isType(value, 'String')) { + value = self.forEach(value, /[^\s,]+/, function (match) { + this[match] = true; + }, {}); + } + return value; + } + function registerFlag(flag) { + if (!/^[\w$]$/.test(flag)) { + throw new Error('Flag must be a single character A-Za-z0-9_$'); + } + registeredFlags[flag] = true; + } + function runTokens(pattern, flags, pos, scope, context) { + var i = tokens.length, result = null, match, t; + while (i--) { + t = tokens[i]; + if ((t.scope === scope || t.scope === 'all') && (!t.flag || flags.indexOf(t.flag) > -1)) { + match = self.exec(pattern, t.regex, pos, 'sticky'); + if (match) { + result = { + matchLength: match[0].length, + output: t.handler.call(context, match, scope, flags), + reparse: t.reparse + }; + break; + } + } + } + return result; + } + function setAstral(on) { + self.cache.flush('patterns'); + features.astral = on; + } + function setNatives(on) { + RegExp.prototype.exec = (on ? fixed : nativ).exec; + RegExp.prototype.test = (on ? fixed : nativ).test; + String.prototype.match = (on ? fixed : nativ).match; + String.prototype.replace = (on ? fixed : nativ).replace; + String.prototype.split = (on ? fixed : nativ).split; + features.natives = on; + } + function toObject(value) { + if (value == null) { + throw new TypeError('Cannot convert null or undefined to object'); + } + return value; + } + self = function (pattern, flags) { + var context = { + hasNamedCapture: false, + captureNames: [] + }, scope = defaultScope, output = '', pos = 0, result, token, key; + if (self.isRegExp(pattern)) { + if (flags !== undefined) { + throw new TypeError('Cannot supply flags when copying a RegExp'); + } + return copy(pattern, { + addProto: true + }); + } + pattern = pattern === undefined ? '' : String(pattern); + flags = flags === undefined ? '' : String(flags); + key = pattern + '***' + flags; + if (!patternCache[key]) { + result = prepareFlags(pattern, flags); + pattern = result.pattern; + flags = result.flags; + while (pos < pattern.length) { + do { + result = runTokens(pattern, flags, pos, scope, context); + if (result && result.reparse) { + pattern = pattern.slice(0, pos) + result.output + pattern.slice(pos + result.matchLength); + } + } while (result && result.reparse); + if (result) { + output += result.output; + pos += result.matchLength || 1; + } else { + token = self.exec(pattern, nativeTokens[scope], pos, 'sticky')[0]; + output += token; + pos += token.length; + if (token === '[' && scope === defaultScope) { + scope = classScope; + } else if (token === ']' && scope === classScope) { + scope = defaultScope; + } + } + } + patternCache[key] = { + pattern: nativ.replace.call(output, /\(\?:\)(?=\(\?:\))|^\(\?:\)|\(\?:\)$/g, ''), + flags: nativ.replace.call(flags, /[^gimy]+/g, ''), + captures: context.hasNamedCapture ? context.captureNames : null + }; + } + key = patternCache[key]; + return augment(new RegExp(key.pattern, key.flags), key.captures, true); + }; + self.prototype = new RegExp(); + self.version = '3.0.0-pre'; + self.addToken = function (regex, handler, options) { + options = options || {}; + var optionalFlags = options.optionalFlags, i; + if (options.flag) { + registerFlag(options.flag); + } + if (optionalFlags) { + optionalFlags = nativ.split.call(optionalFlags, ''); + for (i = 0; i < optionalFlags.length; ++i) { + registerFlag(optionalFlags[i]); + } + } + tokens.push({ + regex: copy(regex, { + add: 'g' + (hasNativeY ? 'y' : '') + }), + handler: handler, + scope: options.scope || defaultScope, + flag: options.flag, + reparse: options.reparse + }); + self.cache.flush('patterns'); + }; + self.cache = function (pattern, flags) { + var key = pattern + '***' + (flags || ''); + return cache[key] || (cache[key] = self(pattern, flags)); + }; + self.cache.flush = function (cacheName) { + if (cacheName === 'patterns') { + patternCache = {}; + } else { + cache = {}; + } + }; + self.escape = function (str) { + return nativ.replace.call(toObject(str), /[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + }; + self.exec = function (str, regex, pos, sticky) { + var cacheFlags = 'g', match, r2; + if (hasNativeY && (sticky || regex.sticky && sticky !== false)) { + cacheFlags += 'y'; + } + regex[REGEX_DATA] = regex[REGEX_DATA] || getBaseProps(); + r2 = regex[REGEX_DATA][cacheFlags] || (regex[REGEX_DATA][cacheFlags] = copy(regex, { + add: cacheFlags, + remove: sticky === false ? 'y' : '' + })); + r2.lastIndex = pos = pos || 0; + match = fixed.exec.call(r2, str); + if (sticky && match && match.index !== pos) { + match = null; + } + if (regex.global) { + regex.lastIndex = match ? r2.lastIndex : 0; + } + return match; + }; + self.forEach = function (str, regex, callback, context) { + var pos = 0, i = -1, match; + while (match = self.exec(str, regex, pos)) { + callback.call(context, match, ++i, str, regex); + pos = match.index + (match[0].length || 1); + } + return context; + }; + self.globalize = function (regex) { + return copy(regex, { + add: 'g', + addProto: true + }); + }; + self.install = function (options) { + options = prepareOptions(options); + if (!features.astral && options.astral) { + setAstral(true); + } + if (!features.natives && options.natives) { + setNatives(true); + } + }; + self.isInstalled = function (feature) { + return !(!features[feature]); + }; + self.isRegExp = function (value) { + return toString.call(value) === '[object RegExp]'; + }; + self.match = function (str, regex, scope) { + var global = regex.global && scope !== 'one' || scope === 'all', cacheFlags = (global ? 'g' : '') + (regex.sticky ? 'y' : ''), result, r2; + regex[REGEX_DATA] = regex[REGEX_DATA] || getBaseProps(); + r2 = regex[REGEX_DATA][cacheFlags || 'noGY'] || (regex[REGEX_DATA][cacheFlags || 'noGY'] = copy(regex, { + add: cacheFlags, + remove: scope === 'one' ? 'g' : '' + })); + result = nativ.match.call(toObject(str), r2); + if (regex.global) { + regex.lastIndex = scope === 'one' && result ? result.index + result[0].length : 0; + } + return global ? result || [] : result && result[0]; + }; + self.matchChain = function (str, chain) { + return function recurseChain(values, level) { + var item = chain[level].regex ? chain[level] : { + regex: chain[level] + }, matches = [], addMatch = function (match) { + if (item.backref) { + if (!(match.hasOwnProperty(item.backref) || +item.backref < match.length)) { + throw new ReferenceError('Backreference to undefined group: ' + item.backref); + } + matches.push(match[item.backref] || ''); + } else { + matches.push(match[0]); + } + }, i; + for (i = 0; i < values.length; ++i) { + self.forEach(values[i], item.regex, addMatch); + } + return level === chain.length - 1 || !matches.length ? matches : recurseChain(matches, level + 1); + }([ + str + ], 0); + }; + self.replace = function (str, search, replacement, scope) { + var isRegex = self.isRegExp(search), global = search.global && scope !== 'one' || scope === 'all', cacheFlags = (global ? 'g' : '') + (search.sticky ? 'y' : ''), s2 = search, result; + if (isRegex) { + search[REGEX_DATA] = search[REGEX_DATA] || getBaseProps(); + s2 = search[REGEX_DATA][cacheFlags || 'noGY'] || (search[REGEX_DATA][cacheFlags || 'noGY'] = copy(search, { + add: cacheFlags, + remove: scope === 'one' ? 'g' : '' + })); + } else if (global) { + s2 = new RegExp(self.escape(String(search)), 'g'); + } + result = fixed.replace.call(toObject(str), s2, replacement); + if (isRegex && search.global) { + search.lastIndex = 0; + } + return result; + }; + self.replaceEach = function (str, replacements) { + var i, r; + for (i = 0; i < replacements.length; ++i) { + r = replacements[i]; + str = self.replace(str, r[0], r[1], r[2]); + } + return str; + }; + self.split = function (str, separator, limit) { + return fixed.split.call(toObject(str), separator, limit); + }; + self.test = function (str, regex, pos, sticky) { + return !(!self.exec(str, regex, pos, sticky)); + }; + self.uninstall = function (options) { + options = prepareOptions(options); + if (features.astral && options.astral) { + setAstral(false); + } + if (features.natives && options.natives) { + setNatives(false); + } + }; + self.union = function (patterns, flags) { + var parts = /(\()(?!\?)|\\([1-9]\d*)|\\[\s\S]|\[(?:[^\\\]]|\\[\s\S])*]/g, output = [], numCaptures = 0, numPriorCaptures, captureNames, pattern, rewrite = function (match, paren, backref) { + var name = captureNames[numCaptures - numPriorCaptures]; + if (paren) { + ++numCaptures; + if (name) { + return '(?<' + name + '>'; + } + } else if (backref) { + return '\\' + (+backref + numPriorCaptures); + } + return match; + }, i; + if (!(isType(patterns, 'Array') && patterns.length)) { + throw new TypeError('Must provide a nonempty array of patterns to merge'); + } + for (i = 0; i < patterns.length; ++i) { + pattern = patterns[i]; + if (self.isRegExp(pattern)) { + numPriorCaptures = numCaptures; + captureNames = pattern[REGEX_DATA] && pattern[REGEX_DATA].captureNames || []; + output.push(nativ.replace.call(self(pattern.source).source, parts, rewrite)); + } else { + output.push(self.escape(pattern)); + } + } + return self(output.join('|'), flags); + }; + fixed.exec = function (str) { + var origLastIndex = this.lastIndex, match = nativ.exec.apply(this, arguments), name, r2, i; + if (match) { + if (!correctExecNpcg && match.length > 1 && indexOf(match, '') > -1) { + r2 = copy(this, { + remove: 'g' + }); + nativ.replace.call(String(str).slice(match.index), r2, function () { + var len = arguments.length, i; + for (i = 1; i < len - 2; ++i) { + if (arguments[i] === undefined) { + match[i] = undefined; + } + } + }); + } + if (this[REGEX_DATA] && this[REGEX_DATA].captureNames) { + for (i = 1; i < match.length; ++i) { + name = this[REGEX_DATA].captureNames[i - 1]; + if (name) { + match[name] = match[i]; + } + } + } + if (this.global && !match[0].length && this.lastIndex > match.index) { + this.lastIndex = match.index; + } + } + if (!this.global) { + this.lastIndex = origLastIndex; + } + return match; + }; + fixed.test = function (str) { + return !(!fixed.exec.call(this, str)); + }; + fixed.match = function (regex) { + var result; + if (!self.isRegExp(regex)) { + regex = new RegExp(regex); + } else if (regex.global) { + result = nativ.match.apply(this, arguments); + regex.lastIndex = 0; + return result; + } + return fixed.exec.call(regex, toObject(this)); + }; + fixed.replace = function (search, replacement) { + var isRegex = self.isRegExp(search), origLastIndex, captureNames, result; + if (isRegex) { + if (search[REGEX_DATA]) { + captureNames = search[REGEX_DATA].captureNames; + } + origLastIndex = search.lastIndex; + } else { + search += ''; + } + if (isType(replacement, 'Function')) { + result = nativ.replace.call(String(this), search, function () { + var args = arguments, i; + if (captureNames) { + args[0] = new String(args[0]); + for (i = 0; i < captureNames.length; ++i) { + if (captureNames[i]) { + args[0][captureNames[i]] = args[i + 1]; + } + } + } + if (isRegex && search.global) { + search.lastIndex = args[args.length - 2] + args[0].length; + } + return replacement.apply(undefined, args); + }); + } else { + result = nativ.replace.call(this == null ? this : String(this), search, function () { + var args = arguments; + return nativ.replace.call(String(replacement), replacementToken, function ($0, $1, $2) { + var n; + if ($1) { + n = +$1; + if (n <= args.length - 3) { + return args[n] || ''; + } + n = captureNames ? indexOf(captureNames, $1) : -1; + if (n < 0) { + throw new SyntaxError('Backreference to undefined group ' + $0); + } + return args[n + 1] || ''; + } + if ($2 === '$') { + return '$'; + } + if ($2 === '&' || +$2 === 0) { + return args[0]; + } + if ($2 === '`') { + return args[args.length - 1].slice(0, args[args.length - 2]); + } + if ($2 === '\'') { + return args[args.length - 1].slice(args[args.length - 2] + args[0].length); + } + $2 = +$2; + if (!isNaN($2)) { + if ($2 > args.length - 3) { + throw new SyntaxError('Backreference to undefined group ' + $0); + } + return args[$2] || ''; + } + throw new SyntaxError('Invalid token ' + $0); + }); + }); + } + if (isRegex) { + if (search.global) { + search.lastIndex = 0; + } else { + search.lastIndex = origLastIndex; + } + } + return result; + }; + fixed.split = function (separator, limit) { + if (!self.isRegExp(separator)) { + return nativ.split.apply(this, arguments); + } + var str = String(this), output = [], origLastIndex = separator.lastIndex, lastLastIndex = 0, lastLength; + limit = (limit === undefined ? -1 : limit) >>> 0; + self.forEach(str, separator, function (match) { + if (match.index + match[0].length > lastLastIndex) { + output.push(str.slice(lastLastIndex, match.index)); + if (match.length > 1 && match.index < str.length) { + Array.prototype.push.apply(output, match.slice(1)); + } + lastLength = match[0].length; + lastLastIndex = match.index + lastLength; + } + }); + if (lastLastIndex === str.length) { + if (!nativ.test.call(separator, '') || lastLength) { + output.push(''); + } + } else { + output.push(str.slice(lastLastIndex)); + } + separator.lastIndex = origLastIndex; + return output.length > limit ? output.slice(0, limit) : output; + }; + add = self.addToken; + add(/\\([ABCE-RTUVXYZaeg-mopqyz]|c(?![A-Za-z])|u(?![\dA-Fa-f]{4})|x(?![\dA-Fa-f]{2}))/, function (match, scope) { + if (match[1] === 'B' && scope === defaultScope) { + return match[0]; + } + throw new SyntaxError('Invalid escape ' + match[0]); + }, { + scope: 'all' + }); + add(/\[(\^?)]/, function (match) { + return match[1] ? '[\\s\\S]' : '\\b\\B'; + }); + add(/\(\?#[^)]*\)/, function (match, scope, flags) { + return isQuantifierNext(match.input, match.index + match[0].length, flags) ? '' : '(?:)'; + }); + add(/\s+|#.*/, function (match, scope, flags) { + return isQuantifierNext(match.input, match.index + match[0].length, flags) ? '' : '(?:)'; + }, { + flag: 'x' + }); + add(/\./, function () { + return '[\\s\\S]'; + }, { + flag: 's' + }); + add(/\\k<([\w$]+)>/, function (match) { + var index = isNaN(match[1]) ? indexOf(this.captureNames, match[1]) + 1 : +match[1], endIndex = match.index + match[0].length; + if (!index || index > this.captureNames.length) { + throw new SyntaxError('Backreference to undefined group ' + match[0]); + } + return '\\' + index + (endIndex === match.input.length || isNaN(match.input.charAt(endIndex)) ? '' : '(?:)'); + }); + add(/\\(\d+)/, function (match, scope) { + if (!(scope === defaultScope && /^[1-9]/.test(match[1]) && +match[1] <= this.captureNames.length) && match[1] !== '0') { + throw new SyntaxError('Cannot use octal escape or backreference to undefined group ' + match[0]); + } + return match[0]; + }, { + scope: 'all' + }); + add(/\(\?P?<([\w$]+)>/, function (match) { + if (!isNaN(match[1])) { + throw new SyntaxError('Cannot use integer as capture name ' + match[0]); + } + if (match[1] === 'length' || match[1] === '__proto__') { + throw new SyntaxError('Cannot use reserved word as capture name ' + match[0]); + } + if (indexOf(this.captureNames, match[1]) > -1) { + throw new SyntaxError('Cannot use same name for multiple groups ' + match[0]); + } + this.captureNames.push(match[1]); + this.hasNamedCapture = true; + return '('; + }); + add(/\((?!\?)/, function (match, scope, flags) { + if (flags.indexOf('n') > -1) { + return '(?:'; + } + this.captureNames.push(null); + return '('; + }, { + optionalFlags: 'n' + }); + return self; + }(); +var Namespace = Shumway.AVM2.ABC.Namespace; +var Shumway; +(function (Shumway) { + (function (AVM2) { + (function (Runtime) { + var Option = Shumway.Options.Option; + var OptionSet = Shumway.Options.OptionSet; + var runtimeOptions = systemOptions.register(new OptionSet('Runtime Options')); + var traceScope = runtimeOptions.register(new Option('ts', 'traceScope', 'boolean', false, 'trace scope execution')); + Runtime.traceExecution = runtimeOptions.register(new Option('tx', 'traceExecution', 'number', 0, 'trace script execution')); + Runtime.traceCallExecution = runtimeOptions.register(new Option('txc', 'traceCallExecution', 'number', 0, 'trace call execution')); + var functionBreak = runtimeOptions.register(new Option('fb', 'functionBreak', 'number', -1, 'Inserts a debugBreak at function index #.')); + var compileOnly = runtimeOptions.register(new Option('co', 'compileOnly', 'number', -1, 'Compiles only function number.')); + var compileUntil = runtimeOptions.register(new Option('cu', 'compileUntil', 'number', -1, 'Compiles only until a function number.')); + Runtime.debuggerMode = runtimeOptions.register(new Option('dm', 'debuggerMode', 'boolean', false, 'matches avm2 debugger build semantics')); + Runtime.enableVerifier = runtimeOptions.register(new Option('verify', 'verify', 'boolean', false, 'Enable verifier.')); + Runtime.globalMultinameAnalysis = runtimeOptions.register(new Option('ga', 'globalMultinameAnalysis', 'boolean', false, 'Global multiname analysis.')); + var traceInlineCaching = runtimeOptions.register(new Option('tic', 'traceInlineCaching', 'boolean', false, 'Trace inline caching execution.')); + Runtime.codeCaching = runtimeOptions.register(new Option('cc', 'codeCaching', 'boolean', false, 'Enable code caching.')); + var compilerEnableExceptions = runtimeOptions.register(new Option('cex', 'exceptions', 'boolean', false, 'Compile functions with catch blocks.')); + var compilerMaximumMethodSize = runtimeOptions.register(new Option('cmms', 'maximumMethodSize', 'number', 4 * 1024, 'Compiler maximum method size.')); + Runtime.traceClasses = runtimeOptions.register(new Option('tc', 'traceClasses', 'boolean', false, 'trace class creation')); + Runtime.traceDomain = runtimeOptions.register(new Option('td', 'traceDomain', 'boolean', false, 'trace domain property access')); + Runtime.sealConstTraits = false; + Runtime.useAsAdd = true; + var useSurrogates = true; + var callCounter = new Shumway.Metrics.Counter(true); + var Multiname = Shumway.AVM2.ABC.Multiname; + var Namespace = Shumway.AVM2.ABC.Namespace; + var MethodInfo = Shumway.AVM2.ABC.MethodInfo; + var ClassInfo = Shumway.AVM2.ABC.ClassInfo; + var InstanceInfo = Shumway.AVM2.ABC.InstanceInfo; + var ScriptInfo = Shumway.AVM2.ABC.ScriptInfo; + var SORT = Shumway.AVM2.ABC.SORT; + var Trait = Shumway.AVM2.ABC.Trait; + var IndentingWriter = Shumway.IndentingWriter; + var hasOwnProperty = Shumway.ObjectUtilities.hasOwnProperty; + var createMap = Shumway.ObjectUtilities.createMap; + var cloneObject = Shumway.ObjectUtilities.cloneObject; + var copyProperties = Shumway.ObjectUtilities.copyProperties; + var createEmptyObject = Shumway.ObjectUtilities.createEmptyObject; + var boxValue = Shumway.ObjectUtilities.boxValue; + var bindSafely = Shumway.FunctionUtilities.bindSafely; + var defineNonEnumerableGetterOrSetter = Shumway.ObjectUtilities.defineNonEnumerableGetterOrSetter; + var defineNonEnumerableProperty = Shumway.ObjectUtilities.defineNonEnumerableProperty; + var defineReadOnlyProperty = Shumway.ObjectUtilities.defineReadOnlyProperty; + var defineNonEnumerableGetter = Shumway.ObjectUtilities.defineNonEnumerableGetter; + var makeForwardingGetter = Shumway.FunctionUtilities.makeForwardingGetter; + var makeForwardingSetter = Shumway.FunctionUtilities.makeForwardingSetter; + var toSafeString = Shumway.StringUtilities.toSafeString; + var toSafeArrayString = Shumway.StringUtilities.toSafeArrayString; + var TRAIT = Shumway.AVM2.ABC.TRAIT; + Runtime.VM_SLOTS = 'asSlots'; + Runtime.VM_LENGTH = 'asLength'; + Runtime.VM_BINDINGS = 'asBindings'; + Runtime.VM_NATIVE_PROTOTYPE_FLAG = 'asIsNative'; + Runtime.VM_OPEN_METHODS = 'asOpenMethods'; + Runtime.VM_IS_CLASS = 'asIsClass'; + Runtime.VM_IS_PROXY = 'asIsProxy'; + Runtime.VM_CALL_PROXY = 'asCallProxy'; + Runtime.VM_OPEN_METHOD_PREFIX = 'm'; + Runtime.VM_MEMOIZER_PREFIX = 'z'; + Runtime.VM_OPEN_SET_METHOD_PREFIX = 's'; + Runtime.VM_OPEN_GET_METHOD_PREFIX = 'g'; + Runtime.VM_NATIVE_BUILTIN_ORIGINALS = 'asOriginals'; + Runtime.VM_METHOD_OVERRIDES = createEmptyObject(); + var vmNextInterpreterFunctionId = 1; + var vmNextCompiledFunctionId = 1; + var totalFunctionCount = 0; + var compiledFunctionCount = 0; + var compilationCount = 0; + function isClass(object) { + true; + return Object.hasOwnProperty.call(object, Runtime.VM_IS_CLASS); + } + Runtime.isClass = isClass; + function isNativePrototype(object) { + return Object.prototype.hasOwnProperty.call(object, Runtime.VM_NATIVE_PROTOTYPE_FLAG); + } + Runtime.isNativePrototype = isNativePrototype; + var traitsWriter = null; + var callWriter = null; + function patch(patchTargets, value) { + true; + for (var i = 0; i < patchTargets.length; i++) { + var patchTarget = patchTargets[i]; + if (Runtime.traceExecution.value >= 3) { + var str = 'Patching: '; + if (patchTarget.name) { + str += patchTarget.name; + } else if (patchTarget.get) { + str += 'get ' + patchTarget.get; + } else if (patchTarget.set) { + str += 'set ' + patchTarget.set; + } + traitsWriter && traitsWriter.redLn(str); + } + if (patchTarget.get) { + defineNonEnumerableGetterOrSetter(patchTarget.object, patchTarget.get, value, true); + } else if (patchTarget.set) { + defineNonEnumerableGetterOrSetter(patchTarget.object, patchTarget.set, value, false); + } else { + defineNonEnumerableProperty(patchTarget.object, patchTarget.name, value); + } + } + } + Runtime.patch = patch; + function applyNonMemoizedMethodTrait(qn, trait, object, scope, natives) { + true; + if (trait.isMethod()) { + var trampoline = Shumway.AVM2.Runtime.makeTrampoline(function (self) { + var fn = getTraitFunction(trait, scope, natives); + patch(self.patchTargets, fn); + return fn; + }, trait.methodInfo.parameters.length); + trampoline.patchTargets = [ + { + object: object, + name: qn + }, + { + object: object, + name: Runtime.VM_OPEN_METHOD_PREFIX + qn + } + ]; + var closure = bindSafely(trampoline, object); + defineReadOnlyProperty(closure, Runtime.VM_LENGTH, trampoline.asLength); + defineReadOnlyProperty(closure, Multiname.getPublicQualifiedName('prototype'), null); + defineNonEnumerableProperty(object, qn, closure); + defineNonEnumerableProperty(object, Runtime.VM_OPEN_METHOD_PREFIX + qn, closure); + } else if (trait.isGetter() || trait.isSetter()) { + var trampoline = Shumway.AVM2.Runtime.makeTrampoline(function (self) { + var fn = getTraitFunction(trait, scope, natives); + patch(self.patchTargets, fn); + return fn; + }, trait.isSetter() ? 1 : 0); + if (trait.isGetter()) { + trampoline.patchTargets = [ + { + object: object, + get: qn + } + ]; + } else { + trampoline.patchTargets = [ + { + object: object, + set: qn + } + ]; + } + defineNonEnumerableGetterOrSetter(object, qn, trampoline, trait.isGetter()); + } else { + Shumway.Debug.unexpected(trait); + } + } + Runtime.applyNonMemoizedMethodTrait = applyNonMemoizedMethodTrait; + function applyMemoizedMethodTrait(qn, trait, object, scope, natives) { + true; + if (trait.isMethod()) { + var memoizerTarget = { + value: null + }; + var trampoline = Shumway.AVM2.Runtime.makeTrampoline(function (self) { + var fn = getTraitFunction(trait, scope, natives); + patch(self.patchTargets, fn); + return fn; + }, trait.methodInfo.parameters.length, String(trait.name)); + memoizerTarget.value = trampoline; + var openMethods = object.asOpenMethods; + openMethods[qn] = trampoline; + defineNonEnumerableProperty(object, Runtime.VM_OPEN_METHOD_PREFIX + qn, trampoline); + defineNonEnumerableGetter(object, qn, Shumway.AVM2.Runtime.makeMemoizer(qn, memoizerTarget)); + trampoline.patchTargets = [ + { + object: memoizerTarget, + name: 'value' + }, + { + object: openMethods, + name: qn + }, + { + object: object, + name: Runtime.VM_OPEN_METHOD_PREFIX + qn + } + ]; + } else if (trait.isGetter() || trait.isSetter()) { + var trampoline = Shumway.AVM2.Runtime.makeTrampoline(function (self) { + var fn = getTraitFunction(trait, scope, natives); + patch(self.patchTargets, fn); + return fn; + }, 0, String(trait.name)); + if (trait.isGetter()) { + defineNonEnumerableProperty(object, Runtime.VM_OPEN_GET_METHOD_PREFIX + qn, trampoline); + trampoline.patchTargets = [ + { + object: object, + get: qn + }, + { + object: object, + name: Runtime.VM_OPEN_GET_METHOD_PREFIX + qn + } + ]; + } else { + defineNonEnumerableProperty(object, Runtime.VM_OPEN_SET_METHOD_PREFIX + qn, trampoline); + trampoline.patchTargets = [ + { + object: object, + set: qn + }, + { + object: object, + name: Runtime.VM_OPEN_SET_METHOD_PREFIX + qn + } + ]; + } + defineNonEnumerableGetterOrSetter(object, qn, trampoline, trait.isGetter()); + } + } + Runtime.applyMemoizedMethodTrait = applyMemoizedMethodTrait; + function getNamespaceResolutionMap(namespaces) { + var self = this; + var map = self.resolutionMap[namespaces.runtimeId]; + if (map) + return map; + map = self.resolutionMap[namespaces.runtimeId] = Shumway.ObjectUtilities.createMap(); + var bindings = self.bindings; + for (var key in bindings.map) { + var multiname = key; + var trait = bindings.map[key].trait; + if (trait.isGetter() || trait.isSetter()) { + multiname = multiname.substring(Shumway.AVM2.Runtime.Binding.KEY_PREFIX_LENGTH); + } + multiname = Multiname.fromQualifiedName(multiname); + if (multiname.getNamespace().inNamespaceSet(namespaces)) { + map[multiname.getName()] = Multiname.getQualifiedName(trait.name); + } + } + return map; + } + Runtime.getNamespaceResolutionMap = getNamespaceResolutionMap; + function resolveMultinameProperty(namespaces, name, flags) { + var self = this; + if (typeof name === 'object') { + name = String(name); + } + if (Shumway.isNumeric(name)) { + return Shumway.toNumber(name); + } + if (!namespaces) { + return Multiname.getPublicQualifiedName(name); + } + if (namespaces.length > 1) { + var resolved = self.getNamespaceResolutionMap(namespaces)[name]; + if (resolved) + return resolved; + return Multiname.getPublicQualifiedName(name); + } else { + return Multiname.qualifyName(namespaces[0], name); + } + } + Runtime.resolveMultinameProperty = resolveMultinameProperty; + function asGetPublicProperty(name) { + var self = this; + return self.asGetProperty(undefined, name, 0); + } + Runtime.asGetPublicProperty = asGetPublicProperty; + function asGetProperty(namespaces, name, flags) { + var self = this; + var resolved = self.resolveMultinameProperty(namespaces, name, flags); + if (self.asGetNumericProperty && Multiname.isNumeric(resolved)) { + return self.asGetNumericProperty(resolved); + } + return self[resolved]; + } + Runtime.asGetProperty = asGetProperty; + function asGetPropertyLikelyNumeric(namespaces, name, flags) { + var self = this; + if (typeof name === 'number') { + return self.asGetNumericProperty(name); + } + return asGetProperty.call(self, namespaces, name, flags); + } + Runtime.asGetPropertyLikelyNumeric = asGetPropertyLikelyNumeric; + function asGetResolvedStringProperty(resolved) { + true; + return this[resolved]; + } + Runtime.asGetResolvedStringProperty = asGetResolvedStringProperty; + function asCallResolvedStringProperty(resolved, isLex, args) { + var self = this; + var receiver = isLex ? null : this; + var openMethods = self.asOpenMethods; + var method; + if (receiver && openMethods && openMethods[resolved]) { + method = openMethods[resolved]; + } else { + method = self[resolved]; + } + return method.apply(receiver, args); + } + Runtime.asCallResolvedStringProperty = asCallResolvedStringProperty; + function asGetResolvedStringPropertyFallback(resolved) { + var self = this; + var name = Multiname.getNameFromPublicQualifiedName(resolved); + return self.asGetProperty([ + Namespace.PUBLIC + ], name, 0); + } + Runtime.asGetResolvedStringPropertyFallback = asGetResolvedStringPropertyFallback; + function asSetPublicProperty(name, value) { + var self = this; + return self.asSetProperty(undefined, name, 0, value); + } + Runtime.asSetPublicProperty = asSetPublicProperty; + function asSetProperty(namespaces, name, flags, value) { + var self = this; + if (typeof name === 'object') { + name = String(name); + } + var resolved = self.resolveMultinameProperty(namespaces, name, flags); + if (self.asSetNumericProperty && Multiname.isNumeric(resolved)) { + return self.asSetNumericProperty(resolved, value); + } + var slotInfo = self.asSlots.byQN[resolved]; + if (slotInfo) { + if (slotInfo.isConst) { + } + var type = slotInfo.type; + if (type && type.coerce) { + value = type.coerce(value); + } + } + self[resolved] = value; + } + Runtime.asSetProperty = asSetProperty; + function asSetPropertyLikelyNumeric(namespaces, name, flags, value) { + var self = this; + if (typeof name === 'number') { + self.asSetNumericProperty(name, value); + return; + } + return asSetProperty.call(self, namespaces, name, flags, value); + } + Runtime.asSetPropertyLikelyNumeric = asSetPropertyLikelyNumeric; + function asDefinePublicProperty(name, descriptor) { + var self = this; + return self.asDefineProperty(undefined, name, 0, descriptor); + } + Runtime.asDefinePublicProperty = asDefinePublicProperty; + function asDefineProperty(namespaces, name, flags, descriptor) { + var self = this; + if (typeof name === 'object') { + name = String(name); + } + var resolved = self.resolveMultinameProperty(namespaces, name, flags); + Object.defineProperty(self, resolved, descriptor); + } + Runtime.asDefineProperty = asDefineProperty; + function asCallPublicProperty(name, args) { + var self = this; + return self.asCallProperty(undefined, name, 0, false, args); + } + Runtime.asCallPublicProperty = asCallPublicProperty; + function asCallProperty(namespaces, name, flags, isLex, args) { + var self = this; + if (Runtime.traceCallExecution.value) { + var receiverClassName = self.class ? self.class.className + ' ' : ''; + callWriter.enter('call ' + receiverClassName + name + '(' + toSafeArrayString(args) + ') #' + callCounter.count(name)); + } + var receiver = isLex ? null : self; + var result; + if (isProxyObject(self)) { + result = self[Runtime.VM_CALL_PROXY](new Multiname(namespaces, name, flags), receiver, args); + } else { + var method; + var resolved = self.resolveMultinameProperty(namespaces, name, flags); + if (self.asGetNumericProperty && Multiname.isNumeric(resolved)) { + method = self.asGetNumericProperty(resolved); + } else { + var openMethods = self.asOpenMethods; + if (receiver && openMethods && openMethods[resolved]) { + method = openMethods[resolved]; + } else { + method = self[resolved]; + } + } + result = method.apply(receiver, args); + } + Runtime.traceCallExecution.value > 0 && callWriter.leave('return ' + toSafeString(result)); + return result; + } + Runtime.asCallProperty = asCallProperty; + function asCallSuper(scope, namespaces, name, flags, args) { + var self = this; + if (Runtime.traceCallExecution.value) { + var receiverClassName = self.class ? self.class.className + ' ' : ''; + callWriter.enter('call super ' + receiverClassName + name + '(' + toSafeArrayString(args) + ') #' + callCounter.count(name)); + } + var baseClass = scope.object.baseClass; + var resolved = baseClass.traitsPrototype.resolveMultinameProperty(namespaces, name, flags); + var openMethods = baseClass.traitsPrototype.asOpenMethods; + var method = openMethods[resolved]; + var result = method.apply(this, args); + Runtime.traceCallExecution.value > 0 && callWriter.leave('return ' + toSafeString(result)); + return result; + } + Runtime.asCallSuper = asCallSuper; + function asSetSuper(scope, namespaces, name, flags, value) { + var self = this; + if (Runtime.traceCallExecution.value) { + var receiverClassName = self.class ? self.class.className + ' ' : ''; + callWriter.enter('set super ' + receiverClassName + name + '(' + toSafeString(value) + ') #' + callCounter.count(name)); + } + var baseClass = scope.object.baseClass; + var resolved = baseClass.traitsPrototype.resolveMultinameProperty(namespaces, name, flags); + if (self.asSlots.byQN[resolved]) { + this.asSetProperty(namespaces, name, flags, value); + } else { + baseClass.traitsPrototype[Runtime.VM_OPEN_SET_METHOD_PREFIX + resolved].call(this, value); + } + Runtime.traceCallExecution.value > 0 && callWriter.leave(''); + } + Runtime.asSetSuper = asSetSuper; + function asGetSuper(scope, namespaces, name, flags) { + var self = this; + if (Runtime.traceCallExecution.value) { + var receiver = self.class ? self.class.className + ' ' : ''; + callWriter.enter('get super ' + receiver + name + ' #' + callCounter.count(name)); + } + var baseClass = scope.object.baseClass; + var resolved = baseClass.traitsPrototype.resolveMultinameProperty(namespaces, name, flags); + var result; + if (self.asSlots.byQN[resolved]) { + result = this.asGetProperty(namespaces, name, flags); + } else { + result = baseClass.traitsPrototype[Runtime.VM_OPEN_GET_METHOD_PREFIX + resolved].call(this); + } + Runtime.traceCallExecution.value > 0 && callWriter.leave('return ' + toSafeString(result)); + return result; + } + Runtime.asGetSuper = asGetSuper; + function construct(cls, args) { + if (cls.classInfo) { + var qn = Multiname.getQualifiedName(cls.classInfo.instanceInfo.name); + if (qn === Multiname.String) { + return String.apply(null, args); + } + if (qn === Multiname.Boolean) { + return Boolean.apply(null, args); + } + if (qn === Multiname.Number) { + return Number.apply(null, args); + } + } + var c = cls.instanceConstructor; + var a = args; + switch (args.length) { + case 0: + return new c(); + case 1: + return new c(a[0]); + case 2: + return new c(a[0], a[1]); + case 3: + return new c(a[0], a[1], a[2]); + case 4: + return new c(a[0], a[1], a[2], a[3]); + case 5: + return new c(a[0], a[1], a[2], a[3], a[4]); + case 6: + return new c(a[0], a[1], a[2], a[3], a[4], a[5]); + case 7: + return new c(a[0], a[1], a[2], a[3], a[4], a[5], a[6]); + case 8: + return new c(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); + case 9: + return new c(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); + case 10: + return new c(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]); + } + var applyArguments = []; + for (var i = 0; i < args.length; i++) { + applyArguments[i + 1] = args[i]; + } + return new (Function.bind.apply(c, applyArguments))(); + } + Runtime.construct = construct; + function asConstructProperty(namespaces, name, flags, args) { + var self = this; + var constructor = self.asGetProperty(namespaces, name, flags); + if (Runtime.traceCallExecution.value) { + callWriter.enter('construct ' + name + '(' + toSafeArrayString(args) + ') #' + callCounter.count(name)); + } + var result = construct(constructor, args); + Runtime.traceCallExecution.value > 0 && callWriter.leave('return ' + toSafeString(result)); + return result; + } + Runtime.asConstructProperty = asConstructProperty; + function nonProxyingHasProperty(object, name) { + return name in object; + } + Runtime.nonProxyingHasProperty = nonProxyingHasProperty; + function asHasProperty(namespaces, name, flags, nonProxy) { + var self = this; + if (self.hasProperty) { + return self.hasProperty(namespaces, name, flags); + } + if (nonProxy) { + return nonProxyingHasProperty(self, self.resolveMultinameProperty(namespaces, name, flags)); + } else { + return self.resolveMultinameProperty(namespaces, name, flags) in this; + } + } + Runtime.asHasProperty = asHasProperty; + function asDeleteProperty(namespaces, name, flags) { + var self = this; + if (self.asHasTraitProperty(namespaces, name, flags)) { + return false; + } + var resolved = self.resolveMultinameProperty(namespaces, name, flags); + return delete self[resolved]; + } + Runtime.asDeleteProperty = asDeleteProperty; + function asHasTraitProperty(namespaces, name, flags) { + var self = this; + var resolved = self.resolveMultinameProperty(namespaces, name, flags); + return self.asBindings.indexOf(resolved) >= 0; + } + Runtime.asHasTraitProperty = asHasTraitProperty; + function asGetNumericProperty(i) { + return this[i]; + } + Runtime.asGetNumericProperty = asGetNumericProperty; + function asSetNumericProperty(i, v) { + this[i] = v; + } + Runtime.asSetNumericProperty = asSetNumericProperty; + function asGetDescendants(namespaces, name, flags) { + Shumway.Debug.notImplemented('asGetDescendants'); + } + Runtime.asGetDescendants = asGetDescendants; + function asNextNameIndex(index) { + var self = this; + if (index === 0) { + defineNonEnumerableProperty(self, 'asEnumerableKeys', self.asGetEnumerableKeys()); + } + var asEnumerableKeys = self.asEnumerableKeys; + while (index < asEnumerableKeys.length) { + if (self.asHasProperty(undefined, asEnumerableKeys[index], 0)) { + return index + 1; + } + index++; + } + return 0; + } + Runtime.asNextNameIndex = asNextNameIndex; + function asNextName(index) { + var self = this; + var asEnumerableKeys = self.asEnumerableKeys; + true; + return asEnumerableKeys[index - 1]; + } + Runtime.asNextName = asNextName; + function asNextValue(index) { + return this.asGetPublicProperty(this.asNextName(index)); + } + Runtime.asNextValue = asNextValue; + function asGetEnumerableKeys() { + var self = this; + var boxedValue = self.valueOf(); + if (typeof boxedValue === 'string' || typeof boxedValue === 'number') { + return []; + } + var keys = Object.keys(this); + var result = []; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (Shumway.isNumeric(key)) { + result.push(key); + } else { + var name = Multiname.stripPublicQualifier(key); + if (name !== undefined) { + result.push(name); + } + } + } + return result; + } + Runtime.asGetEnumerableKeys = asGetEnumerableKeys; + function asTypeOf(x) { + if (x) { + if (x.constructor === String) { + return 'string'; + } else if (x.constructor === Number) { + return 'number'; + } else if (x.constructor === Boolean) { + return 'boolean'; + } else if (x instanceof XML || x instanceof XMLList) { + return 'xml'; + } + } + return typeof x; + } + Runtime.asTypeOf = asTypeOf; + function publicizeProperties(object) { + var keys = Object.keys(object); + for (var i = 0; i < keys.length; i++) { + var k = keys[i]; + if (!Multiname.isPublicQualifiedName(k)) { + var v = object[k]; + object[Multiname.getPublicQualifiedName(k)] = v; + delete object[k]; + } + } + } + Runtime.publicizeProperties = publicizeProperties; + function asGetSlot(object, index) { + return object[object.asSlots.byID[index].name]; + } + Runtime.asGetSlot = asGetSlot; + function asSetSlot(object, index, value) { + var slotInfo = object.asSlots.byID[index]; + if (slotInfo.const) { + return; + } + var name = slotInfo.name; + var type = slotInfo.type; + if (type && type.coerce) { + object[name] = type.coerce(value); + } else { + object[name] = value; + } + } + Runtime.asSetSlot = asSetSlot; + function throwError(name, error) { + if (true) { + var message = Shumway.AVM2.formatErrorMessage.apply(null, Array.prototype.slice.call(arguments, 1)); + throwErrorFromVM(Shumway.AVM2.Runtime.AVM2.currentDomain(), name, message, error.code); + } else { + throwErrorFromVM(Shumway.AVM2.Runtime.AVM2.currentDomain(), name, Shumway.AVM2.getErrorMessage(error.code), error.code); + } + } + Runtime.throwError = throwError; + function throwErrorFromVM(domain, errorClass, message, id) { + var error = new (domain.getClass(errorClass)).instanceConstructor(message, id); + throw error; + } + Runtime.throwErrorFromVM = throwErrorFromVM; + function translateError(domain, error) { + if (error instanceof Error) { + var type = domain.getClass(error.name); + if (type) { + return new type.instanceConstructor(Shumway.AVM2.translateErrorMessage(error)); + } + Shumway.Debug.unexpected('Can\'t translate error: ' + error); + } + return error; + } + Runtime.translateError = translateError; + function asIsInstanceOf(type, value) { + return type.isInstanceOf(value); + } + Runtime.asIsInstanceOf = asIsInstanceOf; + function asIsType(type, value) { + return type.isInstance(value); + } + Runtime.asIsType = asIsType; + function asAsType(type, value) { + return asIsType(type, value) ? value : null; + } + Runtime.asAsType = asAsType; + function asCoerceByMultiname(domain, multiname, value) { + true; + switch (Multiname.getQualifiedName(multiname)) { + case Multiname.Int: + return asCoerceInt(value); + case Multiname.Uint: + return asCoerceUint(value); + case Multiname.String: + return asCoerceString(value); + case Multiname.Number: + return asCoerceNumber(value); + case Multiname.Boolean: + return asCoerceBoolean(value); + case Multiname.Object: + return asCoerceObject(value); + } + return asCoerce(domain.getType(multiname), value); + } + Runtime.asCoerceByMultiname = asCoerceByMultiname; + function asCoerce(type, value) { + if (type.coerce) { + return type.coerce(value); + } + if (Shumway.isNullOrUndefined(value)) { + return null; + } + if (type.isInstance(value)) { + return value; + } else { + true; + } + } + Runtime.asCoerce = asCoerce; + function asCoerceString(x) { + if (typeof x === 'string') { + return x; + } else if (x == undefined) { + return null; + } + return x + ''; + } + Runtime.asCoerceString = asCoerceString; + function asCoerceInt(x) { + return x | 0; + } + Runtime.asCoerceInt = asCoerceInt; + function asCoerceUint(x) { + return x >>> 0; + } + Runtime.asCoerceUint = asCoerceUint; + function asCoerceNumber(x) { + return +x; + } + Runtime.asCoerceNumber = asCoerceNumber; + function asCoerceBoolean(x) { + return !(!x); + } + Runtime.asCoerceBoolean = asCoerceBoolean; + function asCoerceObject(x) { + if (x == undefined) { + return null; + } + if (typeof x === 'string' || typeof x === 'number') { + return x; + } + return Object(x); + } + Runtime.asCoerceObject = asCoerceObject; + function asDefaultCompareFunction(a, b) { + return String(a).localeCompare(String(b)); + } + Runtime.asDefaultCompareFunction = asDefaultCompareFunction; + function asCompare(a, b, options, compareFunction) { + true; + true; + var result = 0; + if (!compareFunction) { + compareFunction = asDefaultCompareFunction; + } + if (options & 1) { + a = String(a).toLowerCase(); + b = String(b).toLowerCase(); + } + if (options & 16) { + a = Shumway.toNumber(a); + b = Shumway.toNumber(b); + result = a < b ? -1 : a > b ? 1 : 0; + } else { + result = compareFunction(a, b); + } + if (options & 2) { + result *= -1; + } + return result; + } + Runtime.asCompare = asCompare; + function asAdd(l, r) { + if (typeof l === 'string' || typeof r === 'string') { + return String(l) + String(r); + } + return l + r; + } + Runtime.asAdd = asAdd; + function asHasNext2(object, index) { + if (Shumway.isNullOrUndefined(object)) { + return { + index: 0, + object: null + }; + } + object = boxValue(object); + var nextIndex = object.asNextNameIndex(index); + if (nextIndex > 0) { + return { + index: nextIndex, + object: object + }; + } + while (true) { + var object = Object.getPrototypeOf(object); + if (!object) { + return { + index: 0, + object: null + }; + } + nextIndex = object.asNextNameIndex(0); + if (nextIndex > 0) { + return { + index: nextIndex, + object: object + }; + } + } + return { + index: 0, + object: null + }; + } + Runtime.asHasNext2 = asHasNext2; + function getDescendants(object, mn) { + if (!isXMLType(object)) { + throw 'Not XML object in getDescendants'; + } + return object.descendants(mn); + } + Runtime.getDescendants = getDescendants; + function checkFilter(value) { + if (!value.class || !isXMLType(value)) { + throw 'TypeError operand of childFilter not of XML type'; + } + return value; + } + Runtime.checkFilter = checkFilter; + function initializeGlobalObject(global) { + var VM_NATIVE_BUILTIN_SURROGATES = [ + { + name: 'Object', + methods: [ + 'toString', + 'valueOf' + ] + }, + { + name: 'Function', + methods: [ + 'toString', + 'valueOf' + ] + } + ]; + var originals = global[Runtime.VM_NATIVE_BUILTIN_ORIGINALS] = createEmptyObject(); + VM_NATIVE_BUILTIN_SURROGATES.forEach(function (surrogate) { + var object = global[surrogate.name]; + originals[surrogate.name] = createEmptyObject(); + surrogate.methods.forEach(function (originalFunctionName) { + var originalFunction; + if (object.prototype.hasOwnProperty(originalFunctionName)) { + originalFunction = object.prototype[originalFunctionName]; + } else { + originalFunction = originals['Object'][originalFunctionName]; + } + originals[surrogate.name][originalFunctionName] = originalFunction; + var overrideFunctionName = Multiname.getPublicQualifiedName(originalFunctionName); + if (useSurrogates) { + global[surrogate.name].prototype[originalFunctionName] = function surrogate() { + if (this[overrideFunctionName]) { + return this[overrideFunctionName](); + } + return originalFunction.call(this); + }; + } + }); + }); + [ + 'Object', + 'Number', + 'Boolean', + 'String', + 'Array', + 'Date', + 'RegExp' + ].forEach(function (name) { + defineReadOnlyProperty(global[name].prototype, Runtime.VM_NATIVE_PROTOTYPE_FLAG, true); + }); + defineNonEnumerableProperty(global.Object.prototype, 'getNamespaceResolutionMap', getNamespaceResolutionMap); + defineNonEnumerableProperty(global.Object.prototype, 'resolveMultinameProperty', resolveMultinameProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asGetProperty', asGetProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asGetPublicProperty', asGetPublicProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asGetResolvedStringProperty', asGetResolvedStringProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asSetProperty', asSetProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asSetPublicProperty', asSetPublicProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asDefineProperty', asDefineProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asDefinePublicProperty', asDefinePublicProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asCallProperty', asCallProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asCallSuper', asCallSuper); + defineNonEnumerableProperty(global.Object.prototype, 'asGetSuper', asGetSuper); + defineNonEnumerableProperty(global.Object.prototype, 'asSetSuper', asSetSuper); + defineNonEnumerableProperty(global.Object.prototype, 'asCallPublicProperty', asCallPublicProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asCallResolvedStringProperty', asCallResolvedStringProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asConstructProperty', asConstructProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asHasProperty', asHasProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asHasTraitProperty', asHasTraitProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asDeleteProperty', asDeleteProperty); + defineNonEnumerableProperty(global.Object.prototype, 'asNextName', asNextName); + defineNonEnumerableProperty(global.Object.prototype, 'asNextValue', asNextValue); + defineNonEnumerableProperty(global.Object.prototype, 'asNextNameIndex', asNextNameIndex); + defineNonEnumerableProperty(global.Object.prototype, 'asGetEnumerableKeys', asGetEnumerableKeys); + [ + 'Array', + 'Int8Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array' + ].forEach(function (name) { + if (!(name in global)) { + log(name + ' was not found in globals'); + return; + } + defineNonEnumerableProperty(global[name].prototype, 'asGetNumericProperty', asGetNumericProperty); + defineNonEnumerableProperty(global[name].prototype, 'asSetNumericProperty', asSetNumericProperty); + defineNonEnumerableProperty(global[name].prototype, 'asGetProperty', asGetPropertyLikelyNumeric); + defineNonEnumerableProperty(global[name].prototype, 'asSetProperty', asSetPropertyLikelyNumeric); + }); + global.Array.prototype.asGetProperty = function (namespaces, name, flags) { + if (typeof name === 'number') { + return this[name]; + } + return asGetProperty.call(this, namespaces, name, flags); + }; + global.Array.prototype.asSetProperty = function (namespaces, name, flags, value) { + if (typeof name === 'number') { + this[name] = value; + return; + } + return asSetProperty.call(this, namespaces, name, flags, value); + }; + } + Runtime.initializeGlobalObject = initializeGlobalObject; + function nameInTraits(object, qn) { + if (object.hasOwnProperty(Runtime.VM_BINDINGS) && object.hasOwnProperty(qn)) { + return true; + } + var proto = Object.getPrototypeOf(object); + return proto.hasOwnProperty(Runtime.VM_BINDINGS) && proto.hasOwnProperty(qn); + } + Runtime.nameInTraits = nameInTraits; + function CatchScopeObject(domain, trait) { + if (trait) { + new Shumway.AVM2.Runtime.CatchBindings(new Shumway.AVM2.Runtime.Scope(null, this), trait).applyTo(domain, this); + } + } + Runtime.CatchScopeObject = CatchScopeObject; + var Global = function () { + function Global(script) { + this.scriptInfo = script; + script.global = this; + this.scriptBindings = new Shumway.AVM2.Runtime.ScriptBindings(script, new Shumway.AVM2.Runtime.Scope(null, this, false)); + this.scriptBindings.applyTo(script.abc.applicationDomain, this); + script.loaded = true; + } + Global.prototype.toString = function () { + return '[object global]'; + }; + Global.prototype.isExecuted = function () { + return this.scriptInfo.executed; + }; + Global.prototype.isExecuting = function () { + return this.scriptInfo.executing; + }; + Global.prototype.ensureExecuted = function () { + Shumway.AVM2.Runtime.ensureScriptIsExecuted(this.scriptInfo); + }; + return Global; + }(); + Runtime.Global = Global; + defineNonEnumerableProperty(Global.prototype, Multiname.getPublicQualifiedName('toString'), function () { + return this.toString(); + }); + var LazyInitializer = function () { + function LazyInitializer(target) { + this.target = target; + } + LazyInitializer.create = function (target) { + if (target.asLazyInitializer) { + return target.asLazyInitializer; + } + return target.asLazyInitializer = new LazyInitializer(target); + }; + LazyInitializer.prototype.getName = function () { + if (this.name) { + return this.name; + } + var target = this.target, initialize; + if (this.target instanceof ScriptInfo) { + var scriptInfo = target; + this.name = '$' + Shumway.StringUtilities.variableLengthEncodeInt32(scriptInfo.hash); + initialize = function () { + Shumway.AVM2.Runtime.ensureScriptIsExecuted(target, 'Lazy Initializer'); + return scriptInfo.global; + }; + } else if (this.target instanceof ClassInfo) { + var classInfo = target; + this.name = '$' + Shumway.StringUtilities.variableLengthEncodeInt32(classInfo.hash); + initialize = function () { + if (classInfo.classObject) { + return classInfo.classObject; + } + return classInfo.abc.applicationDomain.getProperty(classInfo.instanceInfo.name); + }; + } else { + Shumway.Debug.notImplemented(String(target)); + } + var name = this.name; + Object.defineProperty(LazyInitializer._holder, name, { + get: function () { + var value = initialize(); + Object.defineProperty(LazyInitializer._holder, name, { + value: value, + writable: true + }); + return value; + }, + configurable: true + }); + return name; + }; + LazyInitializer._holder = jsGlobal; + return LazyInitializer; + }(); + Runtime.LazyInitializer = LazyInitializer; + function forEachPublicProperty(object, fn, self) { + if (!object.asBindings) { + for (var key in object) { + fn.call(self, key, object[key]); + } + return; + } + for (var key in object) { + if (Shumway.isNumeric(key)) { + fn.call(self, key, object[key]); + } else if (Multiname.isPublicQualifiedName(key) && object.asBindings.indexOf(key) < 0) { + var name = Multiname.stripPublicQualifier(key); + fn.call(self, name, object[key]); + } + } + } + Runtime.forEachPublicProperty = forEachPublicProperty; + function wrapJSObject(object) { + var wrapper = Object.create(object); + for (var i in object) { + Object.defineProperty(wrapper, Multiname.getPublicQualifiedName(i), function (object, i) { + return { + get: function () { + return object[i]; + }, + set: function (value) { + object[i] = value; + }, + enumerable: true + }; + }(object, i)); + } + return wrapper; + } + Runtime.wrapJSObject = wrapJSObject; + function asCreateActivation(methodInfo) { + return Object.create(methodInfo.activationPrototype); + } + Runtime.asCreateActivation = asCreateActivation; + var GlobalMultinameResolver = function () { + function GlobalMultinameResolver() { + } + GlobalMultinameResolver.updateTraits = function (traits) { + for (var i = 0; i < traits.length; i++) { + var trait = traits[i]; + var name = trait.name.name; + var namespace = trait.name.getNamespace(); + if (!namespace.isDynamic()) { + GlobalMultinameResolver.hasNonDynamicNamespaces[name] = true; + if (GlobalMultinameResolver.wasResolved[name]) { + Shumway.Debug.notImplemented('We have to the undo the optimization, ' + name + ' can now bind to ' + namespace); + } + } + } + }; + GlobalMultinameResolver.loadAbc = function (abc) { + if (!Runtime.globalMultinameAnalysis.value) { + return; + } + var scripts = abc.scripts; + var classes = abc.classes; + var methods = abc.methods; + for (var i = 0; i < scripts.length; i++) { + GlobalMultinameResolver.updateTraits(scripts[i].traits); + } + for (var i = 0; i < classes.length; i++) { + GlobalMultinameResolver.updateTraits(classes[i].traits); + GlobalMultinameResolver.updateTraits(classes[i].instanceInfo.traits); + } + for (var i = 0; i < methods.length; i++) { + if (methods[i].traits) { + GlobalMultinameResolver.updateTraits(methods[i].traits); + } + } + }; + GlobalMultinameResolver.resolveMultiname = function (multiname) { + var name = multiname.name; + if (GlobalMultinameResolver.hasNonDynamicNamespaces[name]) { + return; + } + GlobalMultinameResolver.wasResolved[name] = true; + return new Multiname([ + Namespace.PUBLIC + ], multiname.name); + }; + GlobalMultinameResolver.hasNonDynamicNamespaces = createEmptyObject(); + GlobalMultinameResolver.wasResolved = createEmptyObject(); + return GlobalMultinameResolver; + }(); + Runtime.GlobalMultinameResolver = GlobalMultinameResolver; + var ActivationInfo = function () { + function ActivationInfo(methodInfo) { + this.methodInfo = methodInfo; + } + return ActivationInfo; + }(); + Runtime.ActivationInfo = ActivationInfo; + function sliceArguments(args, offset) { + if (typeof offset === 'undefined') { + offset = 0; + } + return Array.prototype.slice.call(args, offset); + } + Runtime.sliceArguments = sliceArguments; + function canCompile(mi) { + if (!mi.hasBody) { + return false; + } + if (mi.hasExceptions() && !compilerEnableExceptions.value) { + return false; + } else if (mi.code.length > compilerMaximumMethodSize.value) { + return false; + } + return true; + } + Runtime.canCompile = canCompile; + function shouldCompile(mi) { + if (!canCompile(mi)) { + return false; + } + if (mi.isClassInitializer || mi.isScriptInitializer) { + return false; + } + return true; + } + Runtime.shouldCompile = shouldCompile; + function forceCompile(mi) { + if (mi.hasExceptions()) { + return false; + } + var holder = mi.holder; + if (holder instanceof ClassInfo) { + holder = holder.instanceInfo; + } + if (holder instanceof InstanceInfo) { + var packageName = holder.name.namespaces[0].uri; + switch (packageName) { + case 'flash.geom': + case 'flash.events': + return true; + default: + break; + } + var className = holder.name.getOriginalName(); + switch (className) { + case 'com.google.youtube.model.VideoData': + return true; + } + } + return false; + } + Runtime.forceCompile = forceCompile; + Runtime.CODE_CACHE = createEmptyObject(); + function searchCodeCache(methodInfo) { + if (!Runtime.codeCaching.value) { + return; + } + var cacheInfo = Runtime.CODE_CACHE[methodInfo.abc.hash]; + if (!cacheInfo) { + warn('Cannot Find Code Cache For ABC, name: ' + methodInfo.abc.name + ', hash: ' + methodInfo.abc.hash); + Counter.count('Code Cache ABC Miss'); + return; + } + if (!cacheInfo.isInitialized) { + methodInfo.abc.scripts.forEach(function (scriptInfo) { + LazyInitializer.create(scriptInfo).getName(); + }); + methodInfo.abc.classes.forEach(function (classInfo) { + LazyInitializer.create(classInfo).getName(); + }); + cacheInfo.isInitialized = true; + } + var method = cacheInfo.methods[methodInfo.index]; + if (!method) { + if (methodInfo.isInstanceInitializer || methodInfo.isClassInitializer) { + Counter.count('Code Cache Query On Initializer'); + } else { + Counter.count('Code Cache MISS ON OTHER'); + warn('Shouldn\'t MISS: ' + methodInfo + ' ' + methodInfo.debugName); + } + Counter.count('Code Cache Miss'); + return; + } + log('Linking CC: ' + methodInfo); + Counter.count('Code Cache Hit'); + return method; + } + Runtime.searchCodeCache = searchCodeCache; + function createInterpretedFunction(methodInfo, scope, hasDynamicScope) { + var mi = methodInfo; + var hasDefaults = false; + var defaults = mi.parameters.map(function (p) { + if (p.value !== undefined) { + hasDefaults = true; + } + return p.value; + }); + var fn; + if (hasDynamicScope) { + fn = function (scope) { + var global = this === jsGlobal ? scope.global.object : this; + var args = sliceArguments(arguments, 1); + if (hasDefaults && args.length < defaults.length) { + args = args.concat(defaults.slice(args.length - defaults.length)); + } + return Shumway.AVM2.Interpreter.interpretMethod(global, methodInfo, scope, args); + }; + } else { + fn = function () { + var global = this === jsGlobal ? scope.global.object : this; + var args = sliceArguments(arguments); + if (hasDefaults && args.length < defaults.length) { + args = args.concat(defaults.slice(arguments.length - defaults.length)); + } + return Shumway.AVM2.Interpreter.interpretMethod(global, methodInfo, scope, args); + }; + } + fn.instanceConstructor = fn; + fn.debugName = 'Interpreter Function #' + vmNextInterpreterFunctionId++; + return fn; + } + Runtime.createInterpretedFunction = createInterpretedFunction; + function debugName(value) { + if (Shumway.isFunction(value)) { + return value.debugName; + } + return value; + } + Runtime.debugName = debugName; + function createCompiledFunction(methodInfo, scope, hasDynamicScope, breakpoint, deferCompilation) { + var mi = methodInfo; + var cached = searchCodeCache(mi); + if (!cached) { + var result = Compiler.compileMethod(mi, scope, hasDynamicScope); + var parameters = result.parameters; + var body = result.body; + } + var fnName = mi.name ? Multiname.getQualifiedName(mi.name) : 'fn' + compiledFunctionCount; + if (mi.holder) { + var fnNamePrefix = ''; + if (mi.holder instanceof ClassInfo) { + fnNamePrefix = 'static$' + mi.holder.instanceInfo.name.getName(); + } else if (mi.holder instanceof InstanceInfo) { + fnNamePrefix = mi.holder.name.getName(); + } else if (mi.holder instanceof ScriptInfo) { + fnNamePrefix = 'script'; + } + fnName = fnNamePrefix + '$' + fnName; + } + fnName = Shumway.StringUtilities.escapeString(fnName); + if (mi.verified) { + fnName += '$V'; + } + if (compiledFunctionCount == functionBreak.value || breakpoint) { + body = '{ debugger; \n' + body + '}'; + } + if (!cached) { + var fnSource = 'function ' + fnName + ' (' + parameters.join(', ') + ') ' + body; + } + if (traceLevel.value > 1) { + mi.trace(new IndentingWriter(), mi.abc); + } + mi.debugTrace = function () { + mi.trace(new IndentingWriter(), mi.abc); + }; + if (traceLevel.value > 0) { + log(fnSource); + } + var fn = cached || new Function('return ' + fnSource)(); + fn.debugName = 'Compiled Function #' + vmNextCompiledFunctionId++; + return fn; + } + Runtime.createCompiledFunction = createCompiledFunction; + function createFunction(mi, scope, hasDynamicScope, breakpoint) { + if (typeof breakpoint === 'undefined') { + breakpoint = false; + } + true; + if (mi.freeMethod) { + if (hasDynamicScope) { + return Shumway.AVM2.Runtime.bindFreeMethodScope(mi, scope); + } + return mi.freeMethod; + } + var fn; + if (fn = Shumway.AVM2.Runtime.checkMethodOverrides(mi)) { + true; + return fn; + } + ensureFunctionIsInitialized(mi); + totalFunctionCount++; + var useInterpreter = false; + if ((mi.abc.applicationDomain.mode === 1 || !shouldCompile(mi)) && !forceCompile(mi)) { + useInterpreter = true; + } + if (compileOnly.value >= 0) { + if (Number(compileOnly.value) !== totalFunctionCount) { + log('Compile Only Skipping ' + totalFunctionCount); + useInterpreter = true; + } + } + if (compileUntil.value >= 0) { + if (totalFunctionCount > 1000) { + log(Shumway.Debug.backtrace()); + log(Shumway.AVM2.Runtime.AVM2.getStackTrace()); + } + if (totalFunctionCount > compileUntil.value) { + log('Compile Until Skipping ' + totalFunctionCount); + useInterpreter = true; + } + } + if (useInterpreter) { + mi.freeMethod = createInterpretedFunction(mi, scope, hasDynamicScope); + } else { + compiledFunctionCount++; + if (compileOnly.value >= 0 || compileUntil.value >= 0) { + log('Compiling ' + totalFunctionCount); + } + mi.freeMethod = createCompiledFunction(mi, scope, hasDynamicScope, breakpoint, mi.isInstanceInitializer); + } + mi.freeMethod.methodInfo = mi; + if (hasDynamicScope) { + return Shumway.AVM2.Runtime.bindFreeMethodScope(mi, scope); + } + return mi.freeMethod; + } + Runtime.createFunction = createFunction; + function ensureFunctionIsInitialized(methodInfo) { + var mi = methodInfo; + if (!mi.analysis) { + mi.analysis = new Analysis(mi); + if (mi.needsActivation()) { + mi.activationPrototype = new ActivationInfo(mi); + new Shumway.AVM2.Runtime.ActivationBindings(mi).applyTo(mi.abc.applicationDomain, mi.activationPrototype); + } + var exceptions = mi.exceptions; + for (var i = 0, j = exceptions.length; i < j; i++) { + var handler = exceptions[i]; + if (handler.varName) { + var varTrait = Object.create(Trait.prototype); + varTrait.kind = 0; + varTrait.name = handler.varName; + varTrait.typeName = handler.typeName; + varTrait.holder = mi; + handler.scopeObject = new CatchScopeObject(mi.abc.applicationDomain, varTrait); + } else { + handler.scopeObject = new CatchScopeObject(undefined, undefined); + } + } + } + } + Runtime.ensureFunctionIsInitialized = ensureFunctionIsInitialized; + function getTraitFunction(trait, scope, natives) { + true; + true; + var mi = trait.methodInfo; + var fn; + if (mi.isNative()) { + var md = trait.metadata; + if (md && md.native) { + var nativeName = md.native.value[0].value; + var makeNativeFunction = getNative(nativeName); + fn = makeNativeFunction && makeNativeFunction(null, scope); + } else if (md && md.unsafeJSNative) { + fn = getNative(md.unsafeJSNative.value[0].value); + } else if (natives) { + var k = Multiname.getName(mi.name); + if (trait.isGetter()) { + fn = natives[k] ? natives[k].get : undefined; + } else if (trait.isSetter()) { + fn = natives[k] ? natives[k].set : undefined; + } else { + fn = natives[k]; + } + } + if (!fn) { + Shumway.Debug.warning('No native method for: ' + trait.kindName() + ' ' + mi.holder.name + '::' + Multiname.getQualifiedName(mi.name)); + return function (mi) { + return function () { + Shumway.Debug.warning('Calling undefined native method: ' + trait.kindName() + ' ' + mi.holder.name + '::' + Multiname.getQualifiedName(mi.name)); + }; + }(mi); + } + } else { + if (Runtime.traceExecution.value >= 2) { + log('Creating Function For Trait: ' + trait.holder + ' ' + trait); + } + fn = createFunction(mi, scope, false, false); + true; + } + if (Runtime.traceExecution.value >= 3) { + log('Made Function: ' + Multiname.getQualifiedName(mi.name)); + } + return fn; + } + Runtime.getTraitFunction = getTraitFunction; + function createClass(classInfo, baseClass, scope) { + true; + var ci = classInfo; + var ii = ci.instanceInfo; + var domain = ci.abc.applicationDomain; + var className = Multiname.getName(ii.name); + if (Runtime.traceExecution.value) { + log('Creating ' + (ii.isInterface() ? 'Interface' : 'Class') + ': ' + className + (ci.native ? ' replaced with native ' + ci.native.cls : '')); + } + var cls; + if (ii.isInterface()) { + cls = Shumway.AVM2.Runtime.Interface.createInterface(classInfo); + } else { + cls = Shumway.AVM2.Runtime.Class.createClass(classInfo, baseClass, scope); + } + if (Runtime.traceClasses.value) { + domain.loadedClasses.push(cls); + domain.traceLoadedClasses(true); + } + if (ii.isInterface()) { + return cls; + } + domain.onMessage.notify1('classCreated', cls); + if (cls.instanceConstructor && cls !== Shumway.AVM2.Runtime.Class) { + cls.verify(); + } + if (baseClass && (Multiname.getQualifiedName(baseClass.classInfo.instanceInfo.name.name) === 'Proxy' || baseClass.isProxy)) { + installProxyClassWrapper(cls); + cls.isProxy = true; + } + classInfo.classObject = cls; + createFunction(classInfo.init, scope, false, false).call(cls); + if (Runtime.sealConstTraits) { + this.sealConstantTraits(cls, ci.traits); + } + return cls; + } + Runtime.createClass = createClass; + function sealConstantTraits(object, traits) { + for (var i = 0, j = traits.length; i < j; i++) { + var trait = traits[i]; + if (trait.isConst()) { + var qn = Multiname.getQualifiedName(trait.name); + var value = object[qn]; + (function (qn, value) { + Object.defineProperty(object, qn, { + configurable: false, + enumerable: false, + get: function () { + return value; + }, + set: function () { + throwErrorFromVM(Shumway.AVM2.Runtime.AVM2.currentDomain(), 'ReferenceError', 'Illegal write to read-only property ' + qn + '.', 0); + } + }); + }(qn, value)); + } + } + } + Runtime.sealConstantTraits = sealConstantTraits; + function applyType(domain, factory, types) { + var factoryClassName = factory.classInfo.instanceInfo.name.name; + if (factoryClassName === 'Vector') { + true; + var type = types[0]; + var typeClassName; + if (!Shumway.isNullOrUndefined(type)) { + typeClassName = type.classInfo.instanceInfo.name.name.toLowerCase(); + switch (typeClassName) { + case 'int': + case 'uint': + case 'double': + case 'object': + return domain.getClass('packageInternal __AS3__.vec.Vector$' + typeClassName); + } + } + return domain.getClass('packageInternal __AS3__.vec.Vector$object').applyType(type); + } else { + return Shumway.Debug.notImplemented(factoryClassName); + } + } + Runtime.applyType = applyType; + }(AVM2.Runtime || (AVM2.Runtime = {}))); + var Runtime = AVM2.Runtime; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +var CC = Shumway.AVM2.Runtime.CODE_CACHE; +var VM_LENGTH = Shumway.AVM2.Runtime.VM_LENGTH; +var VM_IS_PROXY = Shumway.AVM2.Runtime.VM_IS_PROXY; +var VM_CALL_PROXY = Shumway.AVM2.Runtime.VM_CALL_PROXY; +var VM_NATIVE_BUILTIN_ORIGINALS = Shumway.AVM2.Runtime.VM_NATIVE_BUILTIN_ORIGINALS; +var VM_OPEN_METHOD_PREFIX = 'm'; +var VM_OPEN_SET_METHOD_PREFIX = 's'; +var VM_OPEN_GET_METHOD_PREFIX = 'g'; +var SAVED_SCOPE_NAME = '$SS'; +var originalStringReplace = String.prototype.replace; +XRegExp.install({ + natives: true +}); +var callWriter = new IndentingWriter(false, function (str) { + print(str); + }); +var objectIDs = 0; +var OBJECT_NAME = 'Object Name'; +function objectConstantName(object) { + true; + if (object.hasOwnProperty(OBJECT_NAME)) { + return object[OBJECT_NAME]; + } + if (object instanceof LazyInitializer) { + return object.getName(); + } + var name, id = objectIDs++; + if (object instanceof Global) { + name = '$G' + id; + } else if (object instanceof Multiname) { + name = '$M' + id; + } else if (isClass(object)) { + name = '$C' + id; + } else { + name = '$O' + id; + } + Object.defineProperty(object, OBJECT_NAME, { + value: name, + writable: false, + enumerable: false + }); + jsGlobal[name] = object; + return name; +} +var isClass = Shumway.AVM2.Runtime.isClass; +var isTrampoline = Shumway.AVM2.Runtime.isTrampoline; +var isMemoizer = Shumway.AVM2.Runtime.isMemoizer; +var LazyInitializer = Shumway.AVM2.Runtime.LazyInitializer; +var getNamespaceResolutionMap = Shumway.AVM2.Runtime.getNamespaceResolutionMap; +var resolveMultinameProperty = Shumway.AVM2.Runtime.resolveMultinameProperty; +var asGetPublicProperty = Shumway.AVM2.Runtime.asGetPublicProperty; +var asGetProperty = Shumway.AVM2.Runtime.asGetProperty; +var asGetPropertyLikelyNumeric = Shumway.AVM2.Runtime.asGetPropertyLikelyNumeric; +var asGetResolvedStringProperty = Shumway.AVM2.Runtime.asGetResolvedStringProperty; +var asCallResolvedStringProperty = Shumway.AVM2.Runtime.asCallResolvedStringProperty; +var asGetResolvedStringPropertyFallback = Shumway.AVM2.Runtime.asGetResolvedStringPropertyFallback; +var asSetPublicProperty = Shumway.AVM2.Runtime.asSetPublicProperty; +var asSetProperty = Shumway.AVM2.Runtime.asSetProperty; +var asSetPropertyLikelyNumeric = Shumway.AVM2.Runtime.asSetPropertyLikelyNumeric; +var asDefinePublicProperty = Shumway.AVM2.Runtime.asDefinePublicProperty; +var asDefineProperty = Shumway.AVM2.Runtime.asDefineProperty; +var asCallPublicProperty = Shumway.AVM2.Runtime.asCallPublicProperty; +var asCallProperty = Shumway.AVM2.Runtime.asCallProperty; +var asCallSuper = Shumway.AVM2.Runtime.asCallSuper; +var asSetSuper = Shumway.AVM2.Runtime.asSetSuper; +var asGetSuper = Shumway.AVM2.Runtime.asGetSuper; +var construct = Shumway.AVM2.Runtime.construct; +var asConstructProperty = Shumway.AVM2.Runtime.asConstructProperty; +var asHasProperty = Shumway.AVM2.Runtime.asHasProperty; +var asDeleteProperty = Shumway.AVM2.Runtime.asDeleteProperty; +var asGetNumericProperty = Shumway.AVM2.Runtime.asGetNumericProperty; +var asSetNumericProperty = Shumway.AVM2.Runtime.asSetNumericProperty; +var asGetDescendants = Shumway.AVM2.Runtime.asGetDescendants; +var asNextNameIndex = Shumway.AVM2.Runtime.asNextNameIndex; +var asNextName = Shumway.AVM2.Runtime.asNextName; +var asNextValue = Shumway.AVM2.Runtime.asNextValue; +var asGetEnumerableKeys = Shumway.AVM2.Runtime.asGetEnumerableKeys; +var initializeGlobalObject = Shumway.AVM2.Runtime.initializeGlobalObject; +initializeGlobalObject(jsGlobal); +var asTypeOf = Shumway.AVM2.Runtime.asTypeOf; +var publicizeProperties = Shumway.AVM2.Runtime.publicizeProperties; +var asGetSlot = Shumway.AVM2.Runtime.asGetSlot; +var asSetSlot = Shumway.AVM2.Runtime.asSetSlot; +var asHasNext2 = Shumway.AVM2.Runtime.asHasNext2; +var getDescendants = Shumway.AVM2.Runtime.getDescendants; +var checkFilter = Shumway.AVM2.Runtime.checkFilter; +var ActivationInfo = Shumway.AVM2.Runtime.ActivationInfo; +var ScopeStack = Shumway.AVM2.Runtime.ScopeStack; +var Scope = Shumway.AVM2.Runtime.Scope; +var bindFreeMethodScope = Shumway.AVM2.Runtime.bindFreeMethodScope; +var nameInTraits = Shumway.AVM2.Runtime.nameInTraits; +function resolveMultiname(object, mn, traitsOnly) { + return object.resolveMultinameProperty(mn.namespaces, mn.name, mn.flags); +} +var sliceArguments = Shumway.AVM2.Runtime.sliceArguments; +var nonProxyingHasProperty = Shumway.AVM2.Runtime.nonProxyingHasProperty; +var forEachPublicProperty = Shumway.AVM2.Runtime.forEachPublicProperty; +var wrapJSObject = Shumway.AVM2.Runtime.wrapJSObject; +var asCreateActivation = Shumway.AVM2.Runtime.asCreateActivation; +var CatchScopeObject = Shumway.AVM2.Runtime.CatchScopeObject; +var Global = Shumway.AVM2.Runtime.Global; +var canCompile = Shumway.AVM2.Runtime.canCompile; +var shouldCompile = Shumway.AVM2.Runtime.shouldCompile; +var forceCompile = Shumway.AVM2.Runtime.forceCompile; +var createInterpretedFunction = Shumway.AVM2.Runtime.createInterpretedFunction; +var debugName = Shumway.AVM2.Runtime.debugName; +var createCompiledFunction = Shumway.AVM2.Runtime.createCompiledFunction; +var getMethodOverrideKey = Shumway.AVM2.Runtime.getMethodOverrideKey; +var checkMethodOverrides = Shumway.AVM2.Runtime.checkMethodOverrides; +var makeTrampoline = Shumway.AVM2.Runtime.makeTrampoline; +var makeMemoizer = Shumway.AVM2.Runtime.makeMemoizer; +var createFunction = Shumway.AVM2.Runtime.createFunction; +var ensureFunctionIsInitialized = Shumway.AVM2.Runtime.ensureFunctionIsInitialized; +var getTraitFunction = Shumway.AVM2.Runtime.getTraitFunction; +var createClass = Shumway.AVM2.Runtime.createClass; +var sealConstantTraits = Shumway.AVM2.Runtime.sealConstantTraits; +var applyType = Shumway.AVM2.Runtime.applyType; +var throwError = Shumway.AVM2.Runtime.throwError; +var throwErrorFromVM = Shumway.AVM2.Runtime.throwErrorFromVM; +var translateError = Shumway.AVM2.Runtime.translateError; +var asIsInstanceOf = Shumway.AVM2.Runtime.asIsInstanceOf; +var asIsType = Shumway.AVM2.Runtime.asIsType; +var asAsType = Shumway.AVM2.Runtime.asAsType; +var asCoerceByMultiname = Shumway.AVM2.Runtime.asCoerceByMultiname; +var asCoerce = Shumway.AVM2.Runtime.asCoerce; +var asCoerceString = Shumway.AVM2.Runtime.asCoerceString; +var asCoerceInt = Shumway.AVM2.Runtime.asCoerceInt; +var asCoerceUint = Shumway.AVM2.Runtime.asCoerceUint; +var asCoerceNumber = Shumway.AVM2.Runtime.asCoerceNumber; +var asCoerceBoolean = Shumway.AVM2.Runtime.asCoerceBoolean; +var asCoerceObject = Shumway.AVM2.Runtime.asCoerceObject; +var asDefaultCompareFunction = Shumway.AVM2.Runtime.asDefaultCompareFunction; +var asCompare = Shumway.AVM2.Runtime.asCompare; +var asAdd = Shumway.AVM2.Runtime.asAdd; +var GlobalMultinameResolver = Shumway.AVM2.Runtime.GlobalMultinameResolver; +var Shumway; +(function (Shumway) { + (function (AVM2) { + (function (Runtime) { + Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES['static mochi.as3.MochiServices::connect'] = function () { + return; + }; + Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES['static MochiBot::track'] = function () { + return; + }; + Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES['com.midasplayer.debug.DebugLog::trace'] = function (msg) { + log(msg); + }; + Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES['com.midasplayer.engine.comm.DebugGameComm::getGameData'] = function () { + return '\ntrue\ntrue\nfalse\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\nCandy crushed\nbest ever\nscored {0} in one game\nAll Clear Created\ncrushed {0} candy in one game\nScore\nPlease register to play the full game\nLongest chain\nGame ends in {0} seconds\nSuper Stripes Created\nNo more moves!\nMega-Candy Created\nGame starts in {0} seconds\nnow\nLevel reached\nGame Over\nMatch 3 Candy of the same colour to crush them. Matching 4 or 5 in different formations generates special sweets that are extra tasty.\nYou can also combine the special sweets for additional effects by switching them with each other. Try these combinations for a taste you will not forget: \nDouble Colour Bombs Created\nmade {0} combined candy in one game\nPlay like this:\n'; + }; + Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES['com.antkarlov.Preloader::com.antkarlov:Preloader.isUrl'] = function () { + return true; + }; + Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES['static com.demonsters.debugger.MonsterDebugger::initialize'] = function () { + }; + Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES['com.spilgames.api.core.tracking.TrackConfig::getTrackers'] = function () { + return []; + }; + Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES['com.spilgames.api.components.TextFields.AutoFitTextFieldEx::com.spilgames.api.components.TextFields:AutoFitTextFieldEx.updateProperties'] = Shumway.AVM2.Runtime.VM_METHOD_OVERRIDES['com.spilgames.api.components.TextFields.AutoFitTextFieldEx::com.spilgames.api.components.TextFields:AutoFitTextFieldEx.updateTextSize'] = function () { + }; + }(AVM2.Runtime || (AVM2.Runtime = {}))); + var Runtime = AVM2.Runtime; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +var checkArguments = true; +function asCheckVectorSetNumericProperty(i, length, fixed) { + if (i < 0 || i > length || i === length && fixed || !isNumeric(i)) { + throwError('RangeError', Errors.OutOfRangeError, i, length); + } +} +function asCheckVectorGetNumericProperty(i, length) { + if (i < 0 || i >= length || !isNumeric(i)) { + throwError('RangeError', Errors.OutOfRangeError, i, length); + } +} +var TypedArrayVector = function () { + var EXTRA_CAPACITY = 4; + var INITIAL_CAPACITY = 10; + var DEFAULT_VALUE = 0; + function vector(length, fixed) { + length = length | 0; + this._fixed = !(!fixed); + this._buffer = new Int32Array(Math.max(INITIAL_CAPACITY, length + EXTRA_CAPACITY)); + this._offset = 0; + this._length = length; + } + vector.callable = function (object) { + if (object instanceof vector) { + return object; + } + var length = object.asGetProperty(undefined, 'length'); + if (length !== undefined) { + var v = new vector(length, false); + for (var i = 0; i < length; i++) { + v.asSetNumericProperty(i, object.asGetPublicProperty(i)); + } + return v; + } + unexpected(); + }; + vector.prototype.internalToString = function () { + var str = ''; + var start = this._offset; + var end = start + this._length; + for (var i = 0; i < this._buffer.length; i++) { + if (i === start) { + str += '['; + } + if (i === end) { + str += ']'; + } + str += this._buffer[i]; + if (i < this._buffer.length - 1) { + str += ','; + } + } + if (this._offset + this._length === this._buffer.length) { + str += ']'; + } + return str + ': offset: ' + this._offset + ', length: ' + this._length + ', capacity: ' + this._buffer.length; + }; + vector.prototype.toString = function () { + var str = ''; + for (var i = 0; i < this._length; i++) { + str += this._buffer[this._offset + i]; + if (i < this._length - 1) { + str += ','; + } + } + return str; + }; + vector.prototype._view = function () { + return this._buffer.subarray(this._offset, this._offset + this._length); + }; + vector.prototype._ensureCapacity = function (length) { + var minCapacity = this._offset + length; + if (minCapacity < this._buffer.length) { + return; + } + if (length <= this._buffer.length) { + var offset = this._buffer.length - length >> 2; + this._buffer.set(this._view(), offset); + this._offset = offset; + return; + } + var oldCapacity = this._buffer.length; + var newCapacity = oldCapacity * 3 >> 2; + if (newCapacity < minCapacity) { + newCapacity = minCapacity; + } + var buffer = new Int32Array(newCapacity); + buffer.set(this._buffer, 0); + this._buffer = buffer; + }; + vector.prototype.concat = function () { + notImplemented('TypedArrayVector.concat'); + }; + vector.prototype.every = function (callback, thisObject) { + for (var i = 0; i < this._length; i++) { + if (!callback.call(thisObject, this.asGetNumericProperty(i), i, this)) { + return false; + } + } + return true; + }; + vector.prototype.filter = function (callback, thisObject) { + var v = new vector(); + for (var i = 0; i < this._length; i++) { + if (callback.call(thisObject, this.asGetNumericProperty(i), i, this)) { + v.push(this.asGetNumericProperty(i)); + } + } + return v; + }; + vector.prototype.some = function (callback, thisObject) { + if (arguments.length !== 2) { + throwError('ArgumentError', Errors.WrongArgumentCountError); + } else if (!isFunction(callback)) { + throwError('ArgumentError', Errors.CheckTypeFailedError); + } + for (var i = 0; i < this._length; i++) { + if (callback.call(thisObject, this.asGetNumericProperty(i), i, this)) { + return true; + } + } + return false; + }; + vector.prototype.forEach = function (callback, thisObject) { + for (var i = 0; i < this._length; i++) { + callback.call(thisObject, this.asGetNumericProperty(i), i, this); + } + }; + vector.prototype.join = function (sep) { + notImplemented('TypedArrayVector.join'); + }; + vector.prototype.indexOf = function (searchElement, fromIndex) { + notImplemented('TypedArrayVector.indexOf'); + }; + vector.prototype.lastIndexOf = function (searchElement, fromIndex) { + notImplemented('TypedArrayVector.lastIndexOf'); + }; + vector.prototype.map = function (callback, thisObject) { + if (!isFunction(callback)) { + throwError('ArgumentError', Errors.CheckTypeFailedError); + } + var v = new vector(); + for (var i = 0; i < this._length; i++) { + v.push(callback.call(thisObject, this.asGetNumericProperty(i), i, this)); + } + return v; + }; + vector.prototype.push = function () { + this._checkFixed(); + this._ensureCapacity(this._length + arguments.length); + for (var i = 0; i < arguments.length; i++) { + this._buffer[this._offset + this._length++] = arguments[i]; + } + }; + vector.prototype.pop = function () { + this._checkFixed(); + if (this._length === 0) { + return DEFAULT_VALUE; + } + this._length--; + return this._buffer[this._offset + this._length]; + }; + vector.prototype.reverse = function () { + var l = this._offset; + var r = this._offset + this._length - 1; + var b = this._buffer; + while (l < r) { + var t = b[l]; + b[l] = b[r]; + b[r] = t; + l++; + r--; + } + }; + vector.CASEINSENSITIVE = 1; + vector.DESCENDING = 2; + vector.UNIQUESORT = 4; + vector.RETURNINDEXEDARRAY = 8; + vector.NUMERIC = 16; + function defaultCompareFunction(a, b) { + return String(a).localeCompare(String(b)); + } + function compare(a, b, options, compareFunction) { + assertNotImplemented(!(options & vector.CASEINSENSITIVE), 'CASEINSENSITIVE'); + assertNotImplemented(!(options & vector.UNIQUESORT), 'UNIQUESORT'); + assertNotImplemented(!(options & vector.RETURNINDEXEDARRAY), 'RETURNINDEXEDARRAY'); + var result = 0; + if (!compareFunction) { + compareFunction = defaultCompareFunction; + } + if (options & vector.NUMERIC) { + a = toNumber(a); + b = toNumber(b); + result = a < b ? -1 : a > b ? 1 : 0; + } else { + result = compareFunction(a, b); + } + if (options & vector.DESCENDING) { + result *= -1; + } + return result; + } + function _sort(a) { + var stack = []; + var sp = -1; + var l = 0; + var r = a.length - 1; + var i, j, swap, temp; + while (true) { + if (r - l <= 100) { + for (j = l + 1; j <= r; j++) { + swap = a[j]; + i = j - 1; + while (i >= l && a[i] > swap) { + a[i + 1] = a[i--]; + } + a[i + 1] = swap; + } + if (sp == -1) { + break; + } + r = stack[sp--]; + l = stack[sp--]; + } else { + var median = l + r >> 1; + i = l + 1; + j = r; + swap = a[median]; + a[median] = a[i]; + a[i] = swap; + if (a[l] > a[r]) { + swap = a[l]; + a[l] = a[r]; + a[r] = swap; + } + if (a[i] > a[r]) { + swap = a[i]; + a[i] = a[r]; + a[r] = swap; + } + if (a[l] > a[i]) { + swap = a[l]; + a[l] = a[i]; + a[i] = swap; + } + temp = a[i]; + while (true) { + do { + i++; + } while (a[i] < temp); + do { + j--; + } while (a[j] > temp); + if (j < i) { + break; + } + swap = a[i]; + a[i] = a[j]; + a[j] = swap; + } + a[l + 1] = a[j]; + a[j] = temp; + if (r - i + 1 >= j - l) { + stack[++sp] = i; + stack[++sp] = r; + r = j - 1; + } else { + stack[++sp] = l; + stack[++sp] = j - 1; + l = i; + } + } + } + return a; + } + vector.prototype._sortNumeric = function (descending) { + _sort(this._view()); + if (descending) { + this.reverse(); + } + }; + vector.prototype.sort = function () { + if (arguments.length === 0) { + return Array.prototype.sort.call(this._view()); + } + var compareFunction, options = 0; + if (arguments[0] instanceof Function) { + compareFunction = arguments[0]; + } else if (isNumber(arguments[0])) { + options = arguments[0]; + } + if (isNumber(arguments[1])) { + options = arguments[1]; + } + if (options & TypedArrayVector.NUMERIC) { + return this._sortNumeric(options & vector.DESCENDING); + } + Array.prototype.sort.call(this._view(), function (a, b) { + return compare(a, b, options, compareFunction); + }); + }; + vector.prototype.asGetNumericProperty = function (i) { + checkArguments && asCheckVectorGetNumericProperty(i, this._length); + return this._buffer[this._offset + i]; + }; + vector.prototype.asSetNumericProperty = function (i, v) { + checkArguments && asCheckVectorSetNumericProperty(i, this._length, this._fixed); + if (i === this._length) { + this._ensureCapacity(this._length + 1); + this._length++; + } + this._buffer[this._offset + i] = v; + }; + vector.prototype.shift = function () { + this._checkFixed(); + if (this._length === 0) { + return 0; + } + this._length--; + return this._buffer[this._offset++]; + }; + vector.prototype._checkFixed = function () { + if (this._fixed) { + throwError('RangeError', Errors.VectorFixedError); + } + }; + vector.prototype._slide = function (distance) { + this._buffer.set(this._view(), this._offset + distance); + this._offset += distance; + }; + vector.prototype.unshift = function () { + this._checkFixed(); + if (!arguments.length) { + return; + } + this._ensureCapacity(this._length + arguments.length); + this._slide(arguments.length); + this._offset -= arguments.length; + this._length += arguments.length; + for (var i = 0; i < arguments.length; i++) { + this._buffer[this._offset + i] = arguments[i]; + } + }; + vector.prototype.asGetEnumerableKeys = function () { + if (vector.prototype === this) { + return Object.prototype.asGetEnumerableKeys.call(this); + } + var keys = []; + for (var i = 0; i < this._length; i++) { + keys.push(i); + } + return keys; + }; + vector.prototype.asHasProperty = function (namespaces, name, flags) { + if (vector.prototype === this || !isNumeric(name)) { + return Object.prototype.asHasProperty.call(this, namespaces, name, flags); + } + var index = toNumber(name); + return index >= 0 && index < this._length; + }; + Object.defineProperty(vector.prototype, 'length', { + get: function () { + return this._length; + }, + set: function (length) { + length = length >>> 0; + if (length > this._length) { + this._ensureCapacity(length); + for (var i = this._offset + this._length, j = this._offset + length; i < j; i++) { + this._buffer[i] = DEFAULT_VALUE; + } + } + this._length = length; + } + }); + vector.prototype._spliceHelper = function (index, insertCount, deleteCount, args, offset) { + insertCount = clamp(insertCount, 0, args.length - offset); + deleteCount = clamp(deleteCount, 0, this._length - index); + this._ensureCapacity(this._length - deleteCount + insertCount); + var right = this._offset + index + deleteCount; + var slice = this._buffer.subarray(right, right + this._length - index - deleteCount); + this._buffer.set(slice, this._offset + index + insertCount); + this._length += insertCount - deleteCount; + for (var i = 0; i < insertCount; i++) { + this._buffer[this._offset + index + i] = args.asGetNumericProperty(offset + i); + } + }; + vector.prototype.asGetEnumerableKeys = function () { + if (vector.prototype === this) { + return Object.prototype.asGetEnumerableKeys.call(this); + } + var keys = []; + for (var i = 0; i < this._length; i++) { + keys.push(i); + } + return keys; + }; + return vector; + }(); +var typedArrayVectorTemplate = 'var EXTRA_CAPACITY=4,INITIAL_CAPACITY=10,DEFAULT_VALUE=0;function vector(a,b){a|=0;this._fixed=!!b;this._buffer=new Int32Array(Math.max(INITIAL_CAPACITY,a+EXTRA_CAPACITY));this._offset=0;this._length=a}vector.callable=function(a){if(a instanceof vector)return a;var b=a.asGetProperty(void 0,"length");if(void 0!==b){for(var c=new vector(b,!1),d=0;d>2,this._buffer.set(this._view(),b),this._offset=b):(a=3*this._buffer.length>>2,ab?1:0):f=d(a,b);c&vector.DESCENDING&&(f*=-1);return f} function _sort(a){for(var b=[],c=-1,d=0,f=a.length-1,e,g,h,k;;)if(100>=f-d){for(g=d+1;g<=f;g++){h=a[g];for(e=g-1;e>=d&&a[e]>h;)a[e+1]=a[e--];a[e+1]=h}if(-1==c)break;f=b[c--];d=b[c--]}else{k=d+f>>1;e=d+1;g=f;h=a[k];a[k]=a[e];a[e]=h;a[d]>a[f]&&(h=a[d],a[d]=a[f],a[f]=h);a[e]>a[f]&&(h=a[e],a[e]=a[f],a[f]=h);a[d]>a[e]&&(h=a[d],a[d]=a[e],a[e]=h);for(k=a[e];;){do e++;while(a[e]k);if(g=g-d?(b[++c]=e,b[++c]=f,f=g-1):(b[++c]=d, b[++c]=g-1,d=e)}return a}vector.prototype._sortNumeric=function(a){_sort(this._view());a&&this.reverse()};vector.prototype.sort=function(){if(0===arguments.length)return Array.prototype.sort.call(this._view());var a,b=0;arguments[0]instanceof Function?a=arguments[0]:isNumber(arguments[0])&&(b=arguments[0]);isNumber(arguments[1])&&(b=arguments[1]);if(b&TypedArrayVector.NUMERIC)return this._sortNumeric(b&vector.DESCENDING);Array.prototype.sort.call(this._view(),function(c,d){return compare(c,d,b,a)})}; vector.prototype.asGetNumericProperty=function(a){checkArguments&&asCheckVectorGetNumericProperty(a,this._length);return this._buffer[this._offset+a]};vector.prototype.asSetNumericProperty=function(a,b){checkArguments&&asCheckVectorSetNumericProperty(a,this._length,this._fixed);a===this._length&&(this._ensureCapacity(this._length+1),this._length++);this._buffer[this._offset+a]=b};vector.prototype.shift=function(){this._checkFixed();if(0===this._length)return 0;this._length--;return this._buffer[this._offset++]}; vector.prototype._checkFixed=function(){this._fixed&&throwError("RangeError",Errors.VectorFixedError)};vector.prototype._slide=function(a){this._buffer.set(this._view(),this._offset+a);this._offset+=a};vector.prototype.unshift=function(){this._checkFixed();if(arguments.length){this._ensureCapacity(this._length+arguments.length);this._slide(arguments.length);this._offset-=arguments.length;this._length+=arguments.length;for(var a=0;a>>=0;if(a>this._length){this._ensureCapacity(a);for(var b=this._offset+this._length,c=this._offset+a;b b ? 1 : 0; + } else { + result = compareFunction(a, b); + } + if (options & DESCENDING) { + result *= -1; + } + return result; + } + vector.prototype.sort = function (comparator) { + return this._buffer.sort(comparator); + }; + vector.prototype.asGetNumericProperty = function (i) { + checkArguments && asCheckVectorGetNumericProperty(i, this._buffer.length); + return this._buffer[i]; + }; + vector.prototype._coerce = function (v) { + if (this._type) { + return this._type.coerce(v); + } else if (v === undefined) { + return null; + } + return v; + }; + vector.prototype.asSetNumericProperty = function (i, v) { + checkArguments && asCheckVectorSetNumericProperty(i, this._buffer.length, this._fixed); + this._buffer[i] = this._coerce(v); + }; + vector.prototype.shift = function () { + this._checkFixed(); + if (this._buffer.length === 0) { + return undefined; + } + return this._buffer.shift(); + }; + vector.prototype._checkFixed = function () { + if (this._fixed) { + throwError('RangeError', Errors.VectorFixedError); + } + }; + vector.prototype.unshift = function () { + if (!arguments.length) { + return; + } + this._checkFixed(); + var items = []; + for (var i = 0; i < arguments.length; i++) { + items.push(this._coerce(arguments[i])); + } + this._buffer.unshift.apply(this._buffer, items); + }; + Object.defineProperty(vector.prototype, 'length', { + get: function () { + return this._buffer.length; + }, + set: function (length) { + length = length >>> 0; + if (length > this._buffer.length) { + for (var i = this._buffer.length; i < length; i++) { + this._buffer[i] = this._defaultValue; + } + } else { + this._buffer.length = length; + } + true; + } + }); + vector.prototype._spliceHelper = function (index, insertCount, deleteCount, args, offset) { + insertCount = clamp(insertCount, 0, args.length - offset); + deleteCount = clamp(deleteCount, 0, this._buffer.length - index); + var items = []; + for (var i = 0; i < insertCount; i++) { + items.push(this._coerce(args.asGetNumericProperty(offset + i))); + } + this._buffer.splice.apply(this._buffer, [ + index, + deleteCount + ].concat(items)); + }; + vector.prototype.asGetEnumerableKeys = function () { + if (vector.prototype === this) { + return Object.prototype.asGetEnumerableKeys.call(this); + } + var keys = []; + for (var i = 0; i < this._buffer.length; i++) { + keys.push(i); + } + return keys; + }; + vector.prototype.asHasProperty = function (namespaces, name, flags) { + if (vector.prototype === this || !isNumeric(name)) { + return Object.prototype.asHasProperty.call(this, namespaces, name, flags); + } + var index = toNumber(name); + return index >= 0 && index < this._buffer.length; + }; + return vector; + }(); +GenericVector.prototype.asGetProperty = function (namespaces, name, flags) { + if (typeof name === 'number') { + return this.asGetNumericProperty(name); + } + return asGetProperty.call(this, namespaces, name, flags); +}; +GenericVector.prototype.asSetProperty = function (namespaces, name, flags, value) { + if (typeof name === 'number') { + this.asSetNumericProperty(name, value); + return; + } + return asSetProperty.call(this, namespaces, name, flags, value); +}; +function arraySort(o, args) { + if (args.length === 0) { + return o.sort(); + } + var compareFunction, options = 0; + if (args[0] instanceof Function) { + compareFunction = args[0]; + } else if (isNumber(args[0])) { + options = args[0]; + } + if (isNumber(args[1])) { + options = args[1]; + } + o.sort(function (a, b) { + return asCompare(a, b, options, compareFunction); + }); + return o; +} +function ArrayClass(domain, scope, instanceConstructor, baseClass) { + var c = new Class('Array', Array, ApplicationDomain.passthroughCallable(Array)); + c.extendBuiltin(baseClass); + var CACHE_NUMERIC_COMPARATORS = true; + var numericComparatorCache = createEmptyObject(); + c.native = { + static: { + _pop: function _pop(o) { + return o.pop(); + }, + _reverse: function _reverse(o) { + return o.reverse(); + }, + _concat: function _concat(o, args) { + return o.concat.apply(o, args); + }, + _shift: function _shift(o) { + return o.shift(); + }, + _slice: function _slice(o, A, B) { + return o.slice(A, B); + }, + _unshift: function _unshift(o, args) { + return o.unshift.apply(o, args); + }, + _splice: function _splice(o, args) { + return o.splice.apply(o, args); + }, + _sort: function _sort(o, args) { + if (args.length === 0) { + return o.sort(); + } + var compareFunction, options = 0; + if (args[0] instanceof Function) { + compareFunction = args[0]; + } else if (isNumber(args[0])) { + options = args[0]; + } + if (isNumber(args[1])) { + options = args[1]; + } + o.sort(function (a, b) { + return asCompare(a, b, options, compareFunction); + }); + return o; + }, + _sortOn: function _sortOn(o, names, options) { + if (isString(names)) { + names = [ + names + ]; + } + if (isNumber(options)) { + options = [ + options + ]; + } + for (var i = names.length - 1; i >= 0; i--) { + var key = Multiname.getPublicQualifiedName(names[i]); + if (CACHE_NUMERIC_COMPARATORS && options[i] & SORT_NUMERIC) { + var str = 'var x = toNumber(a.' + key + '), y = toNumber(b.' + key + ');'; + if (options[i] & SORT_DESCENDING) { + str += 'return x < y ? 1 : (x > y ? -1 : 0);'; + } else { + str += 'return x < y ? -1 : (x > y ? 1 : 0);'; + } + var numericComparator = numericComparatorCache[str]; + if (!numericComparator) { + numericComparator = numericComparatorCache[str] = new Function('a', 'b', str); + } + o.sort(numericComparator); + } else { + o.sort(function (a, b) { + return asCompare(a[key], b[key], options[i] | 0); + }); + } + } + return o; + }, + _indexOf: function _indexOf(o, searchElement, fromIndex) { + return o.indexOf(searchElement, fromIndex); + }, + _lastIndexOf: function _lastIndexOf(o, searchElement, fromIndex) { + return o.lastIndexOf(searchElement, fromIndex); + }, + _every: function _every(o, callback, thisObject) { + for (var i = 0; i < o.length; i++) { + if (callback.call(thisObject, o[i], i, o) !== true) { + return false; + } + } + return false; + }, + _filter: function _filter(o, callback, thisObject) { + var result = []; + for (var i = 0; i < o.length; i++) { + if (callback.call(thisObject, o[i], i, o) === true) { + result.push(o[i]); + } + } + return result; + }, + _forEach: function _forEach(o, callback, thisObject) { + return o.forEach(callback, thisObject); + }, + _map: function _map(o, callback, thisObject) { + return o.map(callback, thisObject); + }, + _some: function _some(o, callback, thisObject) { + return o.some(callback, thisObject); + } + }, + instance: { + pop: Array.prototype.pop, + push: Array.prototype.push, + unshift: Array.prototype.unshift, + length: { + get: function length() { + return this.length; + }, + set: function length(newLength) { + this.length = newLength; + } + } + } + }; + c.coerce = function (value) { + return value; + }; + c.isInstanceOf = function (value) { + return true; + }; + return c; +} +var XMLClass, XMLListClass, QNameClass, ASXML, XML, ASXMLList, XMLList; +var isXMLType, isXMLName, XMLParser; +(function () { + function XMLEncoder(ancestorNamespaces, indentLevel, prettyPrinting) { + function visit(node, encode) { + if (node.isXML) { + switch (node.kind) { + case 'element': + return encode.element(node); + case 'attribute': + return encode.attribute(node); + case 'text': + return encode.text(node); + case 'cdata': + return encode.cdata(node); + case 'comment': + return encode.comment(node); + case 'processing-instruction': + return encode.pi(node); + } + } else if (node.isXMLList) { + return encode.list(node); + } else { + throw 'Not implemented'; + } + } + function encode(node, encoder) { + return visit(node, { + element: function (n) { + var s, a; + var ns = n.name.mn.namespaces[0]; + var prefix = ns.prefix ? ns.prefix + ':' : ''; + s = '<' + prefix + n.name.localName; + var namespaceDeclarations = []; + if (ns.prefix || ns.uri) { + namespaceDeclarations.push(ns); + } + if (prefix) { + namespaceDeclarations[ns.prefix] = true; + } + var t = n; + while (t) { + for (var i = 0; i < t.inScopeNamespaces.length; i++) { + ns = t.inScopeNamespaces[i]; + if (!namespaceDeclarations[ns.prefix]) { + namespaceDeclarations.push(ns); + namespaceDeclarations[ns.prefix] = true; + } + } + t = t.parent; + } + for (var i = 0; i < namespaceDeclarations.length; i++) { + a = namespaceDeclarations[i]; + if (a.prefix) { + s += ' xmlns:' + a.prefix + '="' + a.uri + '"'; + } else { + s += ' xmlns="' + a.uri + '"'; + } + } + for (var i = 0; i < n.attributes.length; i++) { + a = n.attributes[i]; + var ns = n.name.uri; + var prefix = n.prefix ? ns.prefix + ':' : ''; + var name = prefix + a.name.localName; + s += ' ' + name + '="' + a.value + '"'; + } + if (n.children.length) { + s += '>'; + for (var i = 0; i < n.children.length; i++) { + s += visit(n.children[i], this); + } + s += ''; + } else { + s += '/>'; + } + return s; + }, + text: function (text) { + return escapeAttributeValue(text.value); + }, + attribute: function (n) { + return escapeAttributeValue(n.value); + }, + cdata: function (n) { + }, + comment: function (n) { + }, + pi: function (n) { + }, + doctype: function (n) { + }, + list: function (n) { + var s = ''; + for (var i = 0; i < n.children.length; i++) { + if (i > 0) { + s += '\n'; + } + s += toXMLString(n.children[i], []); + } + return s; + } + }); + } + this.encode = encode; + } + function escapeAttributeValue(v) { + return v.replace('&', '&').replace('<', '<').replace('>', '>'); + } + XMLParser = function XMLParser() { + function parseXml(s, sink) { + var i = 0, scopes = [ + { + space: 'default', + xmlns: '', + namespaces: { + 'xmlns': 'http://www.w3.org/2000/xmlns/', + 'xml': 'http://www.w3.org/XML/1998/namespace' + } + } + ]; + function trim(s) { + return s.replace(/^\s+/, '').replace(/\s+$/, ''); + } + function resolveEntities(s) { + return s.replace(/&([^;]+);/g, function (all, entity) { + if (entity.substring(0, 2) === '#x') { + return String.fromCharCode(parseInt(entity.substring(2), 16)); + } else if (entity.substring(0, 1) === '#') { + return String.fromCharCode(parseInt(entity.substring(1), 10)); + } + switch (entity) { + case 'lt': + return '<'; + case 'gt': + return '>'; + case 'amp': + return '&'; + } + throw 'Unknown entity: ' + entity; + }); + } + function isWhitespacePreserved() { + for (var j = scopes.length - 1; j >= 0; --j) { + if (scopes[j].space === 'preserve') { + return true; + } + } + return false; + } + function lookupDefaultNs() { + for (var j = scopes.length - 1; j >= 0; --j) { + if (scopes[j].hasOwnProperty('xmlns')) { + return scopes[j].xmlns; + } + } + } + function lookupNs(prefix) { + for (var j = scopes.length - 1; j >= 0; --j) { + if (scopes[j].namespaces.hasOwnProperty(prefix)) { + return scopes[j].namespaces[prefix]; + } + } + throw 'Unknown namespace: ' + prefix; + } + function getName(name, resolveDefaultNs) { + var j = name.indexOf(':'); + if (j >= 0) { + var namespace = lookupNs(name.substring(0, j)); + var prefix = name.substring(0, j); + var localName = name.substring(j + 1); + return { + name: namespace + '::' + localName, + localName: localName, + prefix: prefix, + namespace: namespace + }; + } else if (resolveDefaultNs) { + return { + name: name, + localName: name, + prefix: '', + namespace: lookupDefaultNs() + }; + } else { + return { + name: name, + localName: name, + prefix: '', + namespace: '' + }; + } + } + var whitespaceMap = { + '10': true, + '13': true, + '9': true, + '32': true + }; + function isWhitespace(s, index) { + return s.charCodeAt(index) in whitespaceMap; + } + function parseContent(s, start) { + var pos = start, name, attributes = []; + function skipWs() { + while (pos < s.length && isWhitespace(s, pos)) { + ++pos; + } + } + while (pos < s.length && !isWhitespace(s, pos) && s.charAt(pos) !== '>' && s.charAt(pos) !== '/') { + ++pos; + } + name = s.substring(start, pos); + skipWs(); + while (pos < s.length && s.charAt(pos) !== '>' && s.charAt(pos) !== '/' && s.charAt(pos) !== '?') { + skipWs(); + var attrName = '', attrValue = ''; + while (pos < s.length && !isWhitespace(s, pos) && s.charAt(pos) !== '=') { + attrName += s.charAt(pos); + ++pos; + } + skipWs(); + if (s.charAt(pos) !== '=') + throw '\'=\' expected'; + ++pos; + skipWs(); + var attrEndChar = s.charAt(pos); + if (attrEndChar !== '"' && attrEndChar !== '\'') + throw 'Quote expected'; + var attrEndIndex = s.indexOf(attrEndChar, ++pos); + if (attrEndIndex < 0) + throw new 'Unexpected EOF[6]'(); + attrValue = s.substring(pos, attrEndIndex); + attributes.push({ + name: attrName, + value: resolveEntities(attrValue) + }); + pos = attrEndIndex + 1; + skipWs(); + } + return { + name: name, + attributes: attributes, + parsed: pos - start + }; + } + while (i < s.length) { + var ch = s.charAt(i); + var j = i; + if (ch === '<') { + ++j; + var ch2 = s.charAt(j), q, name; + switch (ch2) { + case '/': + ++j; + q = s.indexOf('>', j); + if (q < 0) { + throw 'Unexpected EOF[1]'; + } + name = getName(s.substring(j, q), true); + sink.endElement(name); + scopes.pop(); + j = q + 1; + break; + case '?': + ++j; + var content = parseContent(s, j); + if (s.substring(j + content.parsed, j + content.parsed + 2) != '?>') { + throw 'Unexpected EOF[2]'; + } + sink.pi(content.name, content.attributes); + j += content.parsed + 2; + break; + case '!': + if (s.substring(j + 1, j + 3) === '--') { + q = s.indexOf('-->', j + 3); + if (q < 0) { + throw 'Unexpected EOF[3]'; + } + sink.comment(s.substring(j + 3, q)); + j = q + 3; + } else if (s.substring(j + 1, j + 8) === '[CDATA[') { + q = s.indexOf(']]>', j + 8); + if (q < 0) { + throw 'Unexpected EOF[4]'; + } + sink.cdata(s.substring(j + 8, q)); + j = q + 3; + } else if (s.substring(j + 1, j + 8) === 'DOCTYPE') { + var q2 = s.indexOf('[', j + 8), complexDoctype = false; + q = s.indexOf('>', j + 8); + if (q < 0) { + throw 'Unexpected EOF[5]'; + } + if (q2 > 0 && q > q2) { + q = s.indexOf(']>', j + 8); + if (q < 0) { + throw 'Unexpected EOF[7]'; + } + complexDoctype = true; + } + var doctypeContent = s.substring(j + 8, q + (complexDoctype ? 1 : 0)); + sink.doctype(doctypeContent); + j = q + (complexDoctype ? 2 : 1); + } else { + throw 'Unknown !tag'; + } + break; + default: + var content = parseContent(s, j); + var isClosed = false; + if (s.substring(j + content.parsed, j + content.parsed + 2) === '/>') { + isClosed = true; + } else if (s.substring(j + content.parsed, j + content.parsed + 1) !== '>') { + throw 'Unexpected EOF[2]'; + } + var scope = { + namespaces: [] + }; + var contentAttributes = content.attributes; + for (q = 0; q < contentAttributes.length; ++q) { + var attribute = contentAttributes[q]; + var attributeName = attribute.name; + if (attributeName.substring(0, 6) === 'xmlns:') { + var prefix = attributeName.substring(6); + var uri = attribute.value; + scope.namespaces[prefix] = trim(uri); + scope.namespaces.push({ + uri: uri, + prefix: prefix + }); + delete contentAttributes[q]; + } else if (attributeName === 'xmlns') { + var uri = attribute.value; + scope.namespaces['xmlns'] = trim(uri); + scope.namespaces.push({ + uri: uri, + prefix: '' + }); + delete contentAttributes[q]; + } else if (attributeName.substring(0, 4) === 'xml:') { + scope[attributeName.substring(4)] = trim(attribute.value); + } else if (attributeName.substring(0, 3) === 'xml') { + throw 'Invalid xml attribute'; + } else { + } + } + scopes.push(scope); + var attributes = []; + for (q = 0; q < contentAttributes.length; ++q) { + attribute = contentAttributes[q]; + if (attribute) { + attributes.push({ + name: getName(attribute.name, false), + value: attribute.value + }); + } + } + sink.beginElement(getName(content.name, true), attributes, scope, isClosed); + j += content.parsed + (isClosed ? 2 : 1); + if (isClosed) + scopes.pop(); + break; + } + } else { + do { + if (++j >= s.length) + break; + } while (s.charAt(j) !== '<'); + var text = s.substring(i, j); + var isWs = text.replace(/^\s+/, '').length === 0; + if (!isWs || isWhitespacePreserved()) { + sink.text(resolveEntities(text), isWs); + } + } + i = j; + } + } + this.parseFromString = function (s, mimeType) { + var currentElement = new XML('element', '', '', ''); + var elementsStack = []; + parseXml(s, { + beginElement: function (name, attrs, scope, isEmpty) { + var parent = currentElement; + elementsStack.push(parent); + currentElement = createNode('element', name.namespace, name.localName, name.prefix); + for (var i = 0; i < attrs.length; ++i) { + var rawAttr = attrs[i]; + var attr = createNode('attribute', rawAttr.name.namespace, rawAttr.name.localName, rawAttr.name.prefix); + attr.value = rawAttr.value; + currentElement.attributes.push(attr); + } + var namespaces = scope.namespaces; + for (var i = 0; i < namespaces.length; ++i) { + var rawNs = namespaces[i]; + var ns = ASNamespace.createNamespace(rawNs.uri, rawNs.prefix); + currentElement.inScopeNamespaces.push(ns); + } + parent.insert(parent.length(), currentElement); + if (isEmpty) { + currentElement = elementsStack.pop(); + } + }, + endElement: function (name) { + currentElement = elementsStack.pop(); + }, + text: function (text, isWhitespace) { + var node = createNode('text', '', ''); + node.value = text; + currentElement.insert(currentElement.length(), node); + }, + cdata: function (text) { + var node = createNode('text', '', ''); + node.value = text; + currentElement.insert(currentElement.length(), node); + }, + comment: function (text) { + }, + pi: function (name, attrs) { + }, + doctype: function (text) { + } + }); + return currentElement; + }; + function createNode(kind, uri, name, prefix) { + return new XML(kind, uri, name, prefix); + } + }; + var xmlParser = new XMLParser(); + isXMLType = function isXMLType(val) { + return val.isXML || val.isXMLList; + }; + function toString(node) { + if (typeof node === 'object' && node !== null) { + switch (node.kind) { + case 'text': + case 'attribute': + return node.value; + default: + if (node.hasSimpleContent()) { + var str = ''; + node.children.forEach(function (v, i) { + str += toString(v); + }); + return str; + } + return toXMLString(node); + } + } else { + return String(node); + } + } + function toXMLString(node, ancestorNamespaces, indentLevel) { + return new XMLEncoder(ancestorNamespaces, indentLevel, true).encode(node); + } + function toXML(v) { + if (v === null) { + throw new TypeError(formatErrorMessage(Errors.ConvertNullToObjectError)); + } else if (v === undefined) { + throw new TypeError(formatErrorMessage(Errors.ConvertUndefinedToObjectError)); + } else if (v.isXML) { + return v; + } else if (v.isXMLList) { + if (v.length() === 1) { + return v.children[0]; + } + throw new TypeError(formatErrorMessage(Errors.XMLMarkupMustBeWellFormed)); + } else { + var x = xmlParser.parseFromString(String(v)); + if (x.length() === 0) { + var x = new XML('text'); + return x; + } else if (x.length() === 1) { + x.children[0].parent = null; + return x.children[0]; + } + throw 'SyntaxError in ToXML'; + } + } + var defaultNamespace = ''; + function toXMLList(value) { + if (value === null) { + throw new TypeError(formatErrorMessage(Errors.ConvertNullToObjectError)); + } else if (value === undefined) { + throw new TypeError(formatErrorMessage(Errors.ConvertUndefinedToObjectError)); + } else if (value instanceof XML) { + var xl = new XMLList(value.parent, value.name); + xl.append(value); + return xl; + } else if (value instanceof XMLList) { + return value; + } else { + var s = '' + String(value) + ''; + var x = new ASXML(s); + var xl = new XMLList(); + for (var i = 0; i < x.length(); i++) { + var v = x.children[i]; + v.parent = null; + xl.append(v); + } + return xl; + } + } + function toAttributeName(v) { + if (v === undefined || v === null || typeof v === 'boolean' || typeof v === 'number') { + throw 'TypeError: invalid operand to ToAttributeName()'; + } else if (isXMLType(v)) { + v = toString(v); + } else if (v instanceof Object && v !== null) { + if (v instanceof QName) { + return new QName(v.uri, v.localName, true); + } + v = toString(v); + } + if (typeof v === 'string') { + var ns = new ASNamespace(); + var qn = new QName(ns, v, true); + } else { + } + return qn; + } + function toXMLName(mn) { + return new QName(mn); + } + function getDefaultNamespace(scope) { + while (scope) { + var obj = scope.object; + if (obj.defaultNamepsace !== undefined) { + return obj.defaultNamespace; + } + scope = scope.parent; + } + var ns = ASNamespace.createNamespace('', ''); + return ns; + } + isXMLName = function isXMLName(v) { + try { + var qn = new QName(v); + } catch (e) { + return false; + } + return true; + }; + function asGetProperty(namespaces, name, flags, isMethod) { + var mn = isNumeric(name) ? toNumber(name) : name instanceof QName ? name.mn : new Multiname(namespaces ? namespaces : [ + ASNamespace.PUBLIC + ], name, flags); + return this.getProperty(mn, isMethod); + } + function asSetProperty(namespaces, name, flags, value) { + var mn = isNumeric(name) ? toNumber(name) : name instanceof QName ? name.mn : new Multiname(namespaces ? namespaces : [ + ASNamespace.PUBLIC + ], name, flags); + this.setProperty(mn, value); + } + function asHasProperty(namespaces, name, flags) { + var mn = isNumeric(name) ? toNumber(name) : name instanceof QName ? name.mn : new Multiname(namespaces ? namespaces : [ + ASNamespace.PUBLIC + ], name, flags); + return this.hasProperty(mn); + } + function asCallProperty(namespaces, name, flags, isLex, args) { + var receiver = isLex ? null : this; + var property = this.asGetProperty(namespaces, name, flags, true); + if (!property) { + return this.toString().asCallProperty(namespaces ? namespaces : [ + ASNamespace.PUBLIC + ], name, flags, isLex, args); + } + return property.apply(receiver, args); + } + var ATTR_NAME = 1; + var ELEM_NAME = 2; + var ANY_NAME = 4; + var ANY_NAMESPACE = 8; + function nameKind(mn) { + var flags = 0; + if (mn.isAttribute()) { + flags |= ATTR_NAME; + } else { + flags |= ELEM_NAME; + } + if (mn.isAnyName()) { + flags |= ANY_NAME; + } + if (mn.isAnyNamespace()) { + flags |= ANY_NAMESPACE; + } + return flags; + } + XMLClass = function XMLClass(runtime, scope, instanceConstructor, baseClass) { + var FLAG_IGNORE_COMMENTS = 1; + var FLAG_IGNORE_PROCESSING_INSTRUCTIONS = 2; + var FLAG_IGNORE_WHITESPACE = 4; + var FLAG_PRETTY_PRINTING = 8; + ASXML = function (value) { + if (!(this instanceof ASXML)) { + if (value instanceof ASXML) { + return value; + } + return new ASXML(value); + } + if (value === null || value === undefined) { + value = ''; + } + var x = toXML(value); + if (isXMLType(value)) { + x = x.deepCopy(); + } + return x; + }; + XML = function (kind, uri, name, prefix) { + if (kind === undefined) { + kind = 'text'; + } + if (uri === undefined) { + uri = ''; + } + if (name === undefined) { + name = ''; + } + this.init(kind, uri, name, prefix); + }; + var c = new Class('XML', ASXML, ApplicationDomain.passthroughCallable(ASXML)); + c.flags = FLAG_IGNORE_COMMENTS | FLAG_IGNORE_PROCESSING_INSTRUCTIONS | FLAG_IGNORE_WHITESPACE | FLAG_PRETTY_PRINTING; + c.prettyIndent = 2; + c.extend(baseClass); + var Xp = XML.prototype = ASXML.prototype; + Xp.init = function init(kind, uri, name, prefix) { + this.name = new QName(new Multiname([ + new ASNamespace(prefix, uri) + ], name)); + this.kind = kind; + this.parent = null; + this.inScopeNamespaces = []; + switch (kind) { + case 'element': + this.attributes = []; + this.children = []; + break; + case 'attribute': + case 'text': + this.value = ''; + break; + default: + break; + } + return this; + }; + Xp.length = function () { + if (!this.children) { + return 0; + } + return this.children.length; + }; + Xp.canHandleProperties = true; + Xp.deepCopy = function () { + return new ASXML(toXMLString(this)); + }; + Xp.resolveValue = function resolveValue() { + return this; + }; + Xp.hasSimpleContent = function hasSimpleContent() { + if (this.kind === 'comment' || this.kind === 'processing-instruction') { + return false; + } + var result = true; + if (this.children) { + this.children.forEach(function (v) { + if (v.kind === 'element') { + result = false; + } + }); + } + return result; + }; + Xp.asGetEnumerableKeys = function asGetEnumerableKeys() { + if (Xp === this) { + return Object.prototype.asGetEnumerableKeys.call(this); + } + var keys = []; + this.children.forEach(function (v, i) { + keys.push(v.name); + }); + return keys; + }; + function setAttribute(node, name, value) { + if (node.nodeType === Node.DOCUMENT_NODE) { + node.childNodes[0].setAttribute(name, value); + } else if (node.nodeType === Node.ELEMENT_NODE) { + node.setAttribute(name, value); + } else { + throw 'error or unhandled case in setAttribute'; + } + } + Xp.setProperty = function (p, v) { + var x, i, c, n; + x = this; + if (p === p >>> 0) { + throw 'TypeError in XML.prototype.setProperty(): invalid property name ' + p; + } + if (x.kind === 'text' || x.kind === 'comment' || x.kind === 'processing-instruction' || x.kind === 'attribute') { + return; + } + if (!v || !v.isXML && !v.isXMLList || v.kind === 'text' || v.kind === 'attribute') { + c = toString(v); + } else { + c = v.deepCopy(); + } + n = toXMLName(p); + if (n.isAttr) { + if (!this.attributes) { + return; + } + this.attributes.forEach(function (v, i, o) { + if (v.name === n.localName) { + delete o[i]; + } + }); + var a = new XML('attribute', n.uri, n.localName); + a.value = v; + a.parent = this; + this.attributes.push(a); + return; + } + var isValidName = isXMLName(n); + if (!isValidName && n.localName !== '*') { + return; + } + var i = undefined; + var primitiveAssign = !isXMLType(c) && n.localName !== '*'; + for (var k = x.length() - 1; k >= 0; k--) { + if ((n.isAny || x.children[k].kind === 'element' && x.children[k].name.localName === n.localName) && (n.uri === null || x.children[k].kind === 'element' && x.children[k].name.uri === n.uri)) { + if (i !== undefined) { + x.deleteByIndex(String(i)); + } + i = k; + } + } + if (i === undefined) { + i = x.length(); + if (primitiveAssign) { + if (n.uri === null) { + var name = new QName(getDefaultNamespace(scope), n); + } else { + var name = new QName(n); + } + var y = new XML('element', name.uri, name.localName, name.prefix); + y.parent = x; + var ns = name.getNamespace(); + x.replace(String(i), y); + y.addInScopeNamespace(ns); + } + } + if (primitiveAssign) { + x.children[i].children = []; + var s = toString(c); + if (s !== '') { + x.children[i].replace('0', s); + } + } else { + x.replace(String(i), c); + } + return; + }; + Xp.asGetProperty = asGetProperty; + Xp.asGetResolvedStringProperty = asGetResolvedStringPropertyFallback; + Xp.asSetProperty = asSetProperty; + Xp.asHasProperty = asHasProperty; + Xp.asCallProperty = asCallProperty; + Xp.getProperty = function (mn, isMethod) { + if (isMethod) { + var resolved = Multiname.isQName(mn) ? mn : this.resolveMultinameProperty(mn.namespaces, mn.name, mn.flags); + return this[Multiname.getQualifiedName(resolved)]; + } + if (!Multiname.isQName(mn) && isNumeric(mn)) { + if (Number(0) === 0) { + return this; + } + return null; + } + var x = this; + var name = toXMLName(mn); + var xl = new XMLList(x, name); + var flags = nameKind(name.mn); + var anyName = flags & ANY_NAME; + var anyNamespace = flags & ANY_NAMESPACE; + if (flags & ATTR_NAME) { + if (x.attributes) { + x.attributes.forEach(function (v, i) { + if ((anyName || v.name.localName === name.localName) && (anyNamespace || v.name.uri === name.uri)) { + xl.append(v); + } + }); + } + } else { + x.children.forEach(function (v, i) { + if ((anyName || v.kind === 'element' && v.name.localName === name.localName) && (anyNamespace || v.kind === 'element' && v.name.uri === name.uri)) { + xl.append(v); + } + }); + } + return xl; + }; + Xp.hasProperty = function (mn, isMethod) { + if (isMethod) { + var resolved = Multiname.isQName(mn) ? mn : this.resolveMultinameProperty(mn.namespaces, mn.name, mn.flags); + return !(!this[Multiname.getQualifiedName(resolved)]); + } + if (!Multiname.isQName(mn) && isNumeric(mn)) { + if (Number(0) === 0) { + return true; + } + return false; + } + var name = toXMLName(mn); + var flags = nameKind(name.mn); + var anyName = flags & ANY_NAME; + var anyNamespace = flags & ANY_NAMESPACE; + if (flags & ATTR_NAME) { + return this.attributes.some(function (v, i) { + if ((anyName || v.name.localName === name.localName) && (anyNamespace || v.name.uri === name.uri)) { + return true; + } + }); + if (x.attributes) { + x.attributes.forEach(function (v, i) { + if ((anyName || v.name.localName === name.localName) && (anyNamespace || v.name.uri === name.uri)) { + xl.append(v); + } + }); + } + } else { + if (this.children.some(function (v, i) { + if ((anyName || v.kind === 'element' && v.name.localName === name.localName) && (anyNamespace || v.kind === 'element' && v.name.uri === name.uri)) { + return true; + } + })) { + return true; + } + var resolved = Multiname.isQName(mn) ? mn : this.resolveMultinameProperty(mn.namespaces, mn.name, mn.flags); + return !(!this[Multiname.getQualifiedName(resolved)]); + } + }; + Xp.delete = function (key, isMethod) { + notImplemented('XML.[[Delete]]'); + }; + Xp.deleteByIndex = function (p) { + var x = this; + var i = p >>> 0; + if (String(i) !== String(p)) { + throw 'TypeError in XML.prototype.deleteByIndex(): invalid index ' + p; + } + if (p < x.length()) { + if (x.children[p]) { + x.children[p].parent = null; + delete x.children[p]; + for (q = i + 1; q < x.length(); q++) { + x.children[q - 1] = x.children[q]; + } + x.children.length = x.children.length - 1; + } + } + }; + Xp.isXML = true; + Xp.insert = function insert(p, v) { + var x, s, i, n; + x = this; + if (x.kind === 'text' || x.kind === 'comment' || x.kind === 'processing-instruction' || x.kind === 'attribute') { + return; + } + i = p >>> 0; + if (String(p) !== String(i)) { + throw 'TypeError in XML.prototype.insert(): invalid property name ' + p; + } + if (x.kind === 'element') { + var a = x; + while (a) { + if (a === v) { + throw 'Error in XML.prototype.insert()'; + } + a = a.parent; + } + } + if (x.isXMLList) { + n = x.length(); + if (n === 0) { + return; + } + } else { + n = 1; + } + for (var j = x.length() - 1; j >= i; j--) { + x[j + n] = x[j]; + } + if (x.isXMLList) { + n = v.length(); + for (var j = 0; j < n; j++) { + v.children[j].parent = x; + x[i + j] = v[j]; + } + } else { + v.parent = x; + x.children[i] = v; + } + }; + Xp.replace = function (p, v) { + var x, s; + x = this; + if (x.kind === 'text' || x.kind === 'comment' || x.kind === 'processing-instruction' || x.kind === 'attribute') { + return; + } + var i = p >>> 0; + if (String(p) !== String(i)) { + throw 'TypeError in XML.prototype.replace(): invalid name ' + p; + } + if (i >= x.length()) { + p = String(x.length()); + } + if (v.kind === 'element') { + var a = x; + while (a) { + if (a === v) { + throw 'Error in XML.prototype.replace()'; + } + a = a.parent; + } + } + if (v.kind === 'element' || v.kind === 'text' || v.kind === 'comment' || v.kind === 'processing-instruction') { + v.parent = x; + if (x[p]) { + x.children[p].parent = null; + } + x.children[p] = v; + } else if (x.isXMLList) { + x.deleteByIndex(p); + x.insert(p, v); + } else { + s = toString(v); + t = new XML(); + t.parent = x; + t.value = s; + if (x[p]) { + x.children[p].parent = null; + } + x.children[p] = t; + } + }; + Xp.addInScopeNamespace = function (ns) { + var x, s; + x = this; + if (x.kind === 'text' || x.kind === 'comment' || x.kind === 'processing-instruction' || x.kind === 'attribute') { + return; + } + if (ns.prefix !== undefined) { + if (ns.prefix === '' && x.name.uri === '') { + return; + } + var match = null; + x.inScopeNamespaces.forEach(function (v, i) { + if (v.prefix === ns.prefix) { + match = v; + } + }); + if (match !== null && match.uri !== ns.uri) { + x.inScopeNamespaces.forEach(function (v, i) { + if (v.prefix === match.prefix) { + x.inScopeNamespaces[i] = ns; + } + }); + } + if (x.name.prefix === ns.prefix) { + x.name.prefix = undefined; + } + x.attributes.forEach(function (v, i) { + if (v.name.prefix === ns.name.prefix) { + v.name.prefix = undefined; + } + }); + } + }; + Xp.descendants = function (name) { + name = toXMLName(name); + var x = this; + var xl = new XMLList(); + if (x.kind !== 'element') { + return xl; + } + if (name.isAttr) { + this.attributes.forEach(function (v, i) { + if (name.isAny || name.localName === v.name.localName) { + xl.append(v); + } + }); + } else { + this.children.forEach(function (v, i) { + if (name.isAny || name.localName === v.name.localName) { + xl.append(v); + } + }); + } + this.children.forEach(function (v, i) { + xl.append(v.descendants(name)); + }); + return xl; + }; + Xp.comments = function () { + var x = this; + var xl = new XMLList(x, null); + x.children.forEach(function (v, i) { + if (v.kind === 'comment') { + xl.append(v); + } + }); + return xl; + }; + Xp.text = function () { + var x = this; + var xl = new XMLList(x, null); + x.children.forEach(function (v, i) { + if (v.kind === 'text') { + xl.append(v); + } + }); + return xl; + }; + c.native = { + static: { + ignoreComments: { + get: function ignoreComments() { + return getBitFlags(c.flags, FLAG_IGNORE_COMMENTS); + }, + set: function ignoreComments(newIgnore) { + c.flags = setBitFlags(c.flags, FLAG_IGNORE_COMMENTS, newIgnore); + } + }, + ignoreProcessingInstructions: { + get: function ignoreProcessingInstructions() { + return getBitFlags(c.flags, FLAG_IGNORE_PROCESSING_INSTRUCTIONS); + }, + set: function ignoreProcessingInstructions(newIgnore) { + c.flags = setBitFlags(c.flags, FLAG_IGNORE_PROCESSING_INSTRUCTIONS, newIgnore); + } + }, + ignoreWhitespace: { + get: function ignoreWhitespace() { + return getBitFlags(c.flags, FLAG_IGNORE_WHITESPACE); + }, + set: function ignoreWhitespace(newIgnore) { + c.flags = setBitFlags(c.flags, FLAG_IGNORE_WHITESPACE, newIgnore); + } + }, + prettyPrinting: { + get: function prettyPrinting() { + return getBitFlags(c.flags, FLAG_PRETTY_PRINTING); + }, + set: function prettyPrinting(newPretty) { + c.flags = setBitFlags(c.flags, FLAG_PRETTY_PRINTING, newPretty); + } + }, + prettyIndent: { + get: function prettyIndent() { + return c.prettyIndent; + }, + set: function prettyIndent(newIndent) { + c.prettyIndent = newIndent; + } + } + }, + instance: { + toString: function () { + return toString(this); + }, + hasOwnProperty: function hasOwnProperty(P) { + somewhatImplemented('XML.hasOwnProperty'); + return this.hasProperty(P); + }, + propertyIsEnumerable: function propertyIsEnumerable(P) { + notImplemented('XML.propertyIsEnumerable'); + }, + addNamespace: function addNamespace(ns) { + notImplemented('XML.addNamespace'); + }, + appendChild: function appendChild(child) { + var children = this.getProperty('*'); + children.setProperty(children.length(), child); + return this; + }, + attribute: function attribute(name) { + return this.getProperty(toAttributeName(name)); + }, + attributes: function attributes() { + return this.getProperty(toAttributeName('*')); + }, + child: function child(name) { + return this.getProperty(name); + }, + childIndex: function childIndex() { + notImplemented('XML.childIndex'); + }, + children: function children() { + var list = new XMLList(); + Array.prototype.push.apply(list.children, this.children); + return list; + }, + comments: function comments() { + return this.comments(); + }, + contains: function contains(value) { + notImplemented('XML.contains'); + }, + copy: function copy() { + return this.deepCopy(); + }, + descendants: function descendants(name) { + if (name === undefined) { + name = '*'; + } + return this.descendants(name); + }, + elements: function elements(name) { + var x = this; + var any = false; + if (name === undefined) { + name = '*'; + any = true; + } + var name = toXMLName(name); + var xl = new XMLList(this.parent, name); + x.children.forEach(function (v, i) { + if (v.kind === 'element' && (any || v.name.localName === name.localName) && (name.uri === null || v.kind === 'element' && v.name.uri === name.uri)) { + xl.append(v); + } + }); + return xl; + }, + hasComplexContent: function hasComplexContent() { + notImplemented('XML.hasComplexContent'); + }, + hasSimpleContent: function hasSimpleContent() { + return this.hasSimpleContent(); + }, + inScopeNamespaces: function inScopeNamespaces() { + notImplemented('XML.inScopeNamespaces'); + }, + insertChildAfter: function insertChildAfter(child1, child2) { + notImplemented('XML.insertChildAfter'); + }, + insertChildBefore: function insertChildBefore(child1, child2) { + notImplemented('XML.insertChildBefore'); + }, + localName: function localName() { + return this.name.localName; + }, + name: function name() { + return this.name; + }, + _namespace: function _namespace(prefix, argc) { + somewhatImplemented('XML._namespace()'); + return this.name.uri; + }, + namespaceDeclarations: function namespaceDeclarations() { + return new XMLList(); + }, + nodeKind: function nodeKind() { + return this.kind; + }, + normalize: function normalize() { + notImplemented('XML.normalize'); + }, + parent: function parent() { + notImplemented('XML.parent'); + }, + processingInstructions: function processingInstructions(name) { + notImplemented('XML.processingInstructions'); + }, + prependChild: function prependChild(value) { + notImplemented('XML.prependChild'); + }, + removeNamespace: function removeNamespace(ns) { + notImplemented('XML.removeNamespace'); + }, + replace: function replace(propertyName, value) { + var c, x, s, i; + x = this; + if (x.kind === 'text' || x.kind === 'comment' || x.kind === 'processing-instruction' || x.kind === 'attribute') { + return x; + } + if (!isXMLType(value)) { + c = value.toString(); + } else { + c = value.deepCopy(); + } + var i = propertyName >>> 0; + if (String(propertyName) === String(i)) { + x.replace(propertyName, c); + return x; + } + n = new QName(propertyName); + i = undefined; + for (k = x.length() - 1; k >= 0; k--) { + var v = x.children[k]; + if (n.isAny || v.kind === 'element' && v.name.localName === n.localName && (n.uri === null || v.kind === 'element' && v.name.uri === n.uri)) { + if (i !== undefined) { + x.deleteByIndex(String(i)); + } + i = k; + } + } + if (i !== undefined) { + x.replace(i.toString(), c); + } + return x; + }, + setChildren: function setChildren(value) { + notImplemented('XML.setChildren'); + }, + setLocalName: function setLocalName(name) { + notImplemented('XML.setLocalName'); + }, + setName: function setName(name) { + notImplemented('XML.setName'); + }, + setNamespace: function setNamespace(ns) { + notImplemented('XML.setNamespace'); + }, + text: function text() { + return this.text(); + }, + toXMLString: function () { + return toXMLString(this); + }, + notification: function notification() { + notImplemented('XML.notification'); + }, + setNotification: function setNotification(f) { + notImplemented('XML.setNotification'); + } + } + }; + return c; + }; + XMLListClass = function XMLListClass(runtime, scope, instanceConstructor, baseClass) { + ASXMLList = function (value) { + if (!(this instanceof ASXMLList)) { + return callXMLList(value); + } + return constructXMLList(value); + }; + function callXMLList(v) { + if (v === null || v === undefined) { + v = ''; + } + return toXMLList(v); + } + function constructXMLList(val) { + if (val === null || val === undefined) { + val = ''; + } + if (val.isXMLList) { + var xl = new XMLList(); + xl.append(val); + return xl; + } + return toXMLList(val); + } + XMLList = function (targetObject, targetProperty) { + this.targetObject = targetObject ? targetObject : null; + this.targetProperty = targetProperty ? targetProperty : null; + this.children = []; + }; + var c = new Class('XMLList', ASXMLList, ApplicationDomain.passthroughCallable(ASXMLList)); + c.extend(baseClass); + var XLp = XMLList.prototype = ASXMLList.prototype; + XLp.canHandleProperties = true; + XLp.hasSimpleContent = function hasSimpleContent() { + if (this.length() === 0) { + return true; + } else if (this.length() === 1) { + return toXML(this).hasSimpleContent(); + } + var result = true; + this.children.forEach(function (v) { + if (v.kind === 'element') { + result = false; + } + }); + return result; + }; + XLp.asGetProperty = asGetProperty; + XLp.asGetResolvedStringProperty = asGetResolvedStringPropertyFallback; + XLp.asSetProperty = asSetProperty; + XLp.asHasProperty = asHasProperty; + XLp.asCallProperty = asCallProperty; + XLp.setProperty = function (mn, v, isMethod) { + var x, i, r; + x = this; + i = mn >>> 0; + if (String(mn) === String(i)) { + var targetObject = this.targetObject; + var targetProperty = this.targetProperty; + if (targetObject !== null) { + r = targetObject.resolveValue(); + if (r === null) { + return; + } + } else { + r = null; + } + if (i >= x.length()) { + if (r && r.isXMLList) { + if (r.length !== 1) { + return; + } else { + r = r.children[0]; + } + } + if (r && r.kind !== 'element') { + return; + } + var y = new XML(); + y.parent = r; + y.name = x.targetProperty; + if (targetProperty === null || targetProperty.localName === '*') { + y.name = null; + y.kind = 'text'; + } else if (targetProperty.isAttr) { + var attributeExists = r.getProperty(y.name); + if (attributeExists.length() > 0) { + return; + } + r.kind = 'attribute'; + } else { + y.kind = 'element'; + } + i = x.length(); + if (y.kind !== 'attribute') { + if (r !== null) { + if (i > 0) { + var j = 0; + while (j < r.length() - 1 && r.children[j] !== x.children[i - 1]) { + j++; + } + } else { + var j = r.length() - 1; + } + r.insert(String(j + 1), y); + } + if (v.isXML) { + y.name = v.name; + } else if (v.isXMLList) { + y.name = v.targetProperty; + } + } + x.append(y); + } + if (!v.isXML && !v.isXMLList || v.kind === 'text' || v.kind === 'attribute') { + v = toString(v); + } + if (x.children[i].kind === 'attribute') { + var z = toAttributeName(x.children[i].name); + x.children[i].parent.setProperty(z, v); + var attr = x.children[i].parent.getProperty(z); + x.children[i] = attr.children[0]; + } else if (v.isXMLList) { + var c = v.deepCopy(); + var parent = x.children[i].parent; + if (parent !== null) { + var q; + parent.children.some(function (v, p) { + if (v == x.children[i]) { + q = p; + return true; + } + }); + parent.replace(q, c); + c.children.forEach(function (v, j) { + c.children[j] = parent.children[q >>> 0 + j]; + }); + } + if (c.length() === 0) { + for (var j = x + 1; j < x.length() - 1; j++) { + x.children[String(j - 1)] = x.children[j]; + } + } else { + for (var j = x.length() - 1; j >= i + 1; j--) { + x.children[String(j + c.length() - 1)] = x.children[j]; + } + } + for (var j = 0; j < c.length(); j++) { + x.children[i + j] = c.children[j]; + } + } else if (v.isXML || (k = x.children[i].kind) === 'text' || k === 'comment' || k === 'processing-instruction') { + var parent = x.children[i].parent; + if (parent !== null) { + var q; + parent.children.some(function (v, p) { + if (v == x.children[i]) { + q = p; + return true; + } + }); + parent.replace(q, v); + var v = parent.children[q]; + } + if (typeof v === 'string') { + var t = new XML('text'); + t.parent = x; + t.value = v; + x.children[i] = t; + } else { + x.children[i] = v; + } + } else { + x.children[i].setProperty('*', v); + } + } else if (x.length() <= 1) { + if (x.length() === 0) { + r = x.resolveValue(); + if (r === null || r.length() !== 1) { + return; + } + x.append(r); + } + x.children[0].setProperty(mn, v); + } + }; + XLp.getProperty = function (mn, isMethod) { + if (isMethod) { + var resolved = Multiname.isQName(mn) ? mn : this.resolveMultinameProperty(mn.namespaces, mn.name, mn.flags); + return this[Multiname.getQualifiedName(resolved)]; + } + var x = this; + var i = mn >>> 0; + if (String(mn) === String(i)) { + return x.children[mn]; + } + var name = toXMLName(mn); + var xl = new XMLList(this, name); + x.children.forEach(function (v, i) { + var xl2; + if (v.kind === 'element') { + xl2 = v.getProperty(mn); + if (xl2.length() > 0) { + xl.append(xl2); + } + } + }); + return xl; + }; + XLp.hasProperty = function (mn, isMethod) { + if (isMethod) { + var resolved = Multiname.isQName(mn) ? mn : this.resolveMultinameProperty(mn.namespaces, mn.name, mn.flags); + return !(!this[Multiname.getQualifiedName(resolved)]); + } + var x = this; + var i = mn >>> 0; + if (String(mn) === String(i)) { + return !(!x.children[mn]); + } + var name = toXMLName(mn); + return this.children.some(function (v, i) { + var xl2 = v.getProperty(mn); + if (xl2.length() > 0) { + return true; + } + }); + }; + XLp.delete = function (key, isMethod) { + }; + XLp.append = function (val) { + if (val.isXMLList) { + this.targetObject = val.targetObject; + this.targetProperty = val.targetProperty; + if (val.length() === 0) { + return; + } + for (var i = 0; i < val.length(); i++) { + this.children.push(val.children[i]); + } + } else if (val.isXML) { + this.children.push(val); + } + }; + XLp.length = function () { + return this.children.length; + }; + XLp.resolve = function () { + var base = this.targetObject.resolveValue(); + if (base === null) { + return null; + } + var target = this.targetObject.getProperty(this.targetProperty); + if (base.length === 0) { + notImplemented('XMLList.resolve'); + base.setProperty(this.targetProperty, ''); + target = base.getProperty(this.targetProperty); + return target; + } + }; + XLp.deepCopy = function () { + var xl = new XMLList(); + this.children.forEach(function (v, i) { + xl.children[i] = v.deepCopy(); + }); + return xl; + }; + XLp.descendants = function (name) { + var xl = new XMLList(null); + this.children.forEach(function (v, i) { + if (v.kind === 'element') { + xl.append(v.descendants(name)); + } + }); + return xl; + }; + XLp.resolveValue = function resolveValue() { + if (this.length() > 0) { + return this; + } + var x = this; + var name = x.name; + var targetObject = x.targetObject; + var targetProperty = x.targetProperty; + if (targetObject === null || targetProperty === null || name.isAttr || name.isAny) { + return null; + } + var base = targetObject.resolveValue(); + if (base === null) { + return null; + } + var target = base.getProperty(targetProperty); + if (target.length() === 0) { + if (base.isXMLList && base.length() > 1) { + return null; + } + base.setProperty(targetProperty, ''); + target = base.getProperty(targetProperty); + } + return target; + }; + XLp.asGetEnumerableKeys = function asGetEnumerableKeys() { + if (XLp === this) { + return Object.prototype.asGetEnumerableKeys.call(this); + } + var keys = []; + this.children.forEach(function (v, i) { + keys.push(i); + }); + return keys; + }; + c.native = { + instance: { + init: function () { + } + } + }; + XLp.isXMLList = true; + c.native = { + static: {}, + instance: { + toString: function () { + return toString(this); + }, + hasOwnProperty: function hasOwnProperty(P) { + somewhatImplemented('XMLList.hasOwnProperty'); + return this.hasProperty(P); + }, + propertyIsEnumerable: function propertyIsEnumerable(P) { + notImplemented('XMLList.propertyIsEnumerable'); + }, + attribute: function attribute(name) { + return this.getProperty(toAttributeName(name)); + }, + attributes: function attributes() { + return this.getProperty(toAttributeName('*')); + }, + child: function child(propertyName) { + notImplemented('XMLList.child'); + }, + children: function children() { + var list = new XMLList(); + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + Array.prototype.push.apply(list.children, child.children); + } + return list; + }, + comments: function comments() { + var x = this; + var xl = new XMLList(x, null); + x.children.forEach(function (v, i) { + if (v.kind === 'element') { + xl.append(v.comments()); + } + }); + return xl; + }, + contains: function contains(value) { + for (var i = 0; i < this.children.length; i++) { + if (this.children[i] === value) { + return true; + } + } + return false; + }, + copy: function copy() { + return this.deepCopy(); + }, + descendants: function descendants(name) { + return this.descendants(name === undefined ? '*' : name); + }, + elements: function elements(name) { + var x = this; + var any = false; + if (name === undefined) { + name = '*'; + any = true; + } + var name = toXMLName(name); + var xl = new XMLList(x, name); + x.children.forEach(function (v, i) { + if (v.kind === 'element') { + xl.append(v.comments()); + } + }); + return xl; + }, + hasComplexContent: function hasComplexContent() { + notImplemented('XMLList.hasComplexContent'); + }, + hasSimpleContent: function hasSimpleContent() { + return this.hasSimpleContent(); + }, + length: function length() { + return this.children.length; + }, + name: function name() { + return toXML(this).name; + }, + normalize: function normalize() { + notImplemented('XMLList.normalize'); + }, + parent: function parent() { + notImplemented('XMLList.parent'); + }, + processingInstructions: function processingInstructions(name) { + notImplemented('XMLList.processingInstructions'); + }, + text: function text() { + var x = this; + var xl = new XMLList(x, null); + x.children.forEach(function (v, i) { + if (v.kind === 'text' || v.kind === 'element') { + xl.append(v.text()); + } + }); + return xl; + }, + toXMLString: function () { + return toXMLString(this); + }, + addNamespace: function addNamespace(ns) { + notImplemented('XMLList.addNamespace'); + }, + appendChild: function appendChild(child) { + toXML(this).appendChild(child); + return this; + }, + childIndex: function childIndex() { + notImplemented('XMLList.childIndex'); + }, + inScopeNamespaces: function inScopeNamespaces() { + notImplemented('XMLList.inScopeNamespaces'); + }, + insertChildAfter: function insertChildAfter(child1, child2) { + notImplemented('XMLList.insertChildAfter'); + }, + insertChildBefore: function insertChildBefore(child1, child2) { + notImplemented('XMLList.insertChildBefore'); + }, + nodeKind: function nodeKind() { + return toXML(this).kind; + }, + _namespace: function _namespace(prefix, argc) { + notImplemented('XMLList._namespace'); + }, + localName: function localName() { + notImplemented('XMLList.localName'); + }, + namespaceDeclarations: function namespaceDeclarations() { + somewhatImplemented('XMLList.prototype.namespaceDeclarations()'); + return new XMLList(); + }, + prependChild: function prependChild(value) { + notImplemented('XMLList.prependChild'); + }, + removeNamespace: function removeNamespace(ns) { + notImplemented('XMLList.removeNamespace'); + }, + replace: function replace(propertyName, value) { + toXML(this).replace(propertyName, value); + return this; + }, + setChildren: function setChildren(value) { + notImplemented('XMLList.setChildren'); + }, + setLocalName: function setLocalName(name) { + notImplemented('XMLList.setLocalName'); + }, + setName: function setName(name) { + notImplemented('XMLList.setName'); + }, + setNamespace: function setNamespace(ns) { + notImplemented('XMLList.setNamespace'); + } + } + }; + return c; + }; + QNameClass = function QNameClass(runtime, scope, instanceConstructor, baseClass) { + QName = function QName(ns, name, isAttr) { + if (!(this instanceof QName)) { + if (name === undefined && ns instanceof QName) { + return ns; + } else { + return new QName(ns, name); + } + } + if (name === undefined) { + name = ns; + ns = undefined; + } + if (typeof ns === 'string' || ns instanceof QName) { + ns = new ASNamespace(ns); + } + var mn; + if (name instanceof QName) { + if (ns === undefined) { + mn = name.mn; + } else { + mn = new Multiname([ + ns + ], name.mn.getName()); + } + } else if (name instanceof Multiname) { + if (ns === undefined) { + if (name.isQName() || name.isAnyName() || name.isAnyNamespace()) { + mn = name; + } else { + mn = new Multiname([ + getDefaultNamespace(scope) + ], name.getName(), name.flags); + } + } else { + mn = new Multiname([ + ns + ], name.getName(), name.flags); + } + } else if (name === '*') { + mn = new Multiname([], null, isAttr ? Multiname.ATTRIBUTE : 0); + } else if (name === '@*') { + mn = new Multiname([], null, Multiname.ATTRIBUTE); + } else { + ns = ns === undefined ? getDefaultNamespace(scope) : ns; + if (name === undefined) { + mn = new Multiname([ + ns + ], ''); + } else { + mn = new Multiname([ + ns + ], toString(name), isAttr ? Multiname.ATTRIBUTE : 0); + } + } + this.mn = mn; + this.isAny = mn.isAnyName(); + this.isAnyNamespace = mn.isAnyNamespace(); + this.isAttr = mn.isAttribute(); + }; + var c = new Class('QName', QName, ApplicationDomain.passthroughCallable(QName)); + c.extend(baseClass); + QNp = QName.prototype; + defineNonEnumerableGetter(QNp, 'localName', function () { + if (!this._localName) { + this._localName = this.isAny ? '*' : this.mn.getName(); + } + return this._localName; + }); + defineNonEnumerableGetter(QNp, 'uri', function () { + if (!this._uri) { + var ns = this.mn.namespaces[0]; + this._uri = ns && ns.uri ? ns.uri : this.isAny || this.isAnyNamespace ? null : ''; + } + return this._uri; + }); + defineNonEnumerableGetter(QNp, 'prefix', function () { + return this.mn.namespaces[0].prefix; + }); + defineNonEnumerableSetter(QNp, 'prefix', function (prefix) { + this.mn.namespaces[0].prefix = prefix; + }); + QNp.getNamespace = function (isns) { + if (this.uri === null) { + throw 'TypeError in QName.prototype.getNamespace()'; + } + if (!isns) { + isns = []; + } + var ns; + for (var i = 0; i < isns.length; i++) { + if (this.uri === isns[i].uri) { + ns = isns[i]; + } + } + if (!ns) { + ns = ASNamespace.createNamespace(this.uri); + } + return ns; + }; + c.native = { + static: {}, + instance: { + localName: { + get: function localName() { + return this.localName; + } + }, + uri: { + get: function uri() { + return this.uri; + } + } + } + }; + return c; + }; +}()); +var AMFUtils = function AMFUtilsClosure() { + var AMF0_NUMBER_MARKER = 0; + var AMF0_BOOLEAN_MARKER = 1; + var AMF0_STRING_MARKER = 2; + var AMF0_OBJECT_MARKER = 3; + var AMF0_NULL_MARKER = 5; + var AMF0_UNDEFINED_MARKER = 6; + var AMF0_REFERENCE_MARKER = 7; + var AMF0_ECMA_ARRAY_MARKER = 8; + var AMF0_OBJECT_END_MARKER = 9; + var AMF0_STRICT_ARRAY_MARKER = 10; + var AMF0_DATE_MARKER = 11; + var AMF0_LONG_STRING_MARKER = 12; + var AMF0_XML_MARKER = 15; + var AMF0_TYPED_OBJECT_MARKER = 16; + var AMF0_AVMPLUS_MARKER = 17; + function writeString(ba, s) { + if (s.length > 65535) { + throw 'AMF short string exceeded'; + } + if (!s.length) { + ba.writeByte(0); + ba.writeByte(0); + return; + } + var bytes = utf8decode(s); + ba.writeByte(bytes.length >> 8 & 255); + ba.writeByte(bytes.length & 255); + for (var i = 0; i < bytes.length; i++) { + ba.writeByte(bytes[i]); + } + } + function readString(ba) { + var byteLength = ba.readByte() << 8 | ba.readByte(); + if (!byteLength) { + return ''; + } + var buffer = new Uint8Array(byteLength); + for (var i = 0; i < byteLength; i++) { + buffer[i] = ba.readByte(); + } + return utf8encode(buffer); + } + function writeDouble(ba, value) { + var buffer = new ArrayBuffer(8); + var view = new DataView(buffer); + view.setFloat64(0, value, false); + for (var i = 0; i < buffer.byteLength; i++) { + ba.writeByte(view.getUint8(i)); + } + } + function readDouble(ba) { + var buffer = new ArrayBuffer(8); + var view = new DataView(buffer); + for (var i = 0; i < buffer.byteLength; i++) { + view.setUint8(i, ba.readByte()); + } + return view.getFloat64(0, false); + } + function setAvmProperty(obj, propertyName, value) { + obj.asSetPublicProperty(propertyName, value); + } + var amf0 = { + write: function (ba, obj) { + switch (typeof obj) { + case 'boolean': + ba.writeByte(AMF0_BOOLEAN_MARKER); + ba.writeByte(obj ? 1 : 0); + break; + case 'number': + ba.writeByte(AMF0_NUMBER_MARKER); + writeDouble(ba, obj); + break; + case 'undefined': + ba.writeByte(AMF0_UNDEFINED_MARKER); + break; + case 'string': + ba.writeByte(AMF0_STRING_MARKER); + writeString(ba, obj); + break; + case 'object': + if (obj === null) { + ba.writeByte(AMF0_NULL_MARKER); + } else if (Array.isArray(obj)) { + ba.writeByte(AMF0_ECMA_ARRAY_MARKER); + ba.writeByte(obj.length >>> 24 & 255); + ba.writeByte(obj.length >> 16 & 255); + ba.writeByte(obj.length >> 8 & 255); + ba.writeByte(obj.length & 255); + forEachPublicProperty(obj, function (key, value) { + writeString(ba, key); + this.write(ba, value); + }, this); + ba.writeByte(0); + ba.writeByte(0); + ba.writeByte(AMF0_OBJECT_END_MARKER); + } else { + ba.writeByte(AMF0_OBJECT_MARKER); + forEachPublicProperty(obj, function (key, value) { + writeString(ba, key); + this.write(ba, value); + }, this); + ba.writeByte(0); + ba.writeByte(0); + ba.writeByte(AMF0_OBJECT_END_MARKER); + } + return; + } + }, + read: function (ba) { + var marker = ba.readByte(); + switch (marker) { + case AMF0_NUMBER_MARKER: + return readDouble(ba); + case AMF0_BOOLEAN_MARKER: + return !(!ba.readByte()); + case AMF0_STRING_MARKER: + return readString(ba); + case AMF0_OBJECT_MARKER: + var obj = {}; + while (true) { + var key = readString(ba); + if (!key.length) + break; + setAvmProperty(obj, key, this.read(ba)); + } + if (ba.readByte() !== AMF0_OBJECT_END_MARKER) { + throw 'AMF0 End marker is not found'; + } + return obj; + case AMF0_NULL_MARKER: + return null; + case AMF0_UNDEFINED_MARKER: + return undefined; + case AMF0_ECMA_ARRAY_MARKER: + var obj = []; + obj.length = ba.readByte() << 24 | ba.readByte() << 16 | ba.readByte() << 8 | ba.readByte(); + while (true) { + var key = readString(ba); + if (!key.length) + break; + setAvmProperty(obj, key, this.read(ba)); + } + if (ba.readByte() !== AMF0_OBJECT_END_MARKER) { + throw 'AMF0 End marker is not found'; + } + return obj; + case AMF0_STRICT_ARRAY_MARKER: + var obj = []; + obj.length = ba.readByte() << 24 | ba.readByte() << 16 | ba.readByte() << 8 | ba.readByte(); + for (var i = 0; i < obj.length; i++) { + obj[i] = this.read(ba); + } + return obj; + case AMF0_AVMPLUS_MARKER: + return readAmf3Data(ba, {}); + default: + throw 'AMF0 Unknown marker ' + marker; + } + } + }; + var AMF3_UNDEFINED_MARKER = 0; + var AMF3_NULL_MARKER = 1; + var AMF3_FALSE_MARKER = 2; + var AMF3_TRUE_MARKER = 3; + var AMF3_INTEGER_MARKER = 4; + var AMF3_DOUBLE_MARKER = 5; + var AMF3_STRING_MARKER = 6; + var AMF3_XML_DOC_MARKER = 7; + var AMF3_DATE_MARKER = 8; + var AMF3_ARRAY_MARKER = 9; + var AMF3_OBJECT_MARKER = 10; + var AMF3_XML_MARKER = 11; + var AMF3_BYTEARRAY_MARKER = 12; + var AMF3_VECTOR_INT_MARKER = 13; + var AMF3_VECTOR_UINT_MARKER = 14; + var AMF3_VECTOR_DOUBLE_MARKER = 15; + var AMF3_VECTOR_OBJECT_MARKER = 16; + var AMF3_DICTIONARY_MARKER = 17; + function readU29(ba) { + var b1 = ba.readByte(); + if ((b1 & 128) === 0) { + return b1; + } + var b2 = ba.readByte(); + if ((b2 & 128) === 0) { + return (b1 & 127) << 7 | b2; + } + var b3 = ba.readByte(); + if ((b3 & 128) === 0) { + return (b1 & 127) << 14 | (b2 & 127) << 7 | b3; + } + var b4 = ba.readByte(); + return (b1 & 127) << 22 | (b2 & 127) << 15 | (b3 & 127) << 8 | b4; + } + function writeU29(ba, value) { + if ((value & 4294967168) === 0) { + ba.writeByte(value & 127); + } else if ((value & 4294950912) === 0) { + ba.writeByte(128 | value >> 7 & 127); + ba.writeByte(value & 127); + } else if ((value & 4292870144) === 0) { + ba.writeByte(128 | value >> 14 & 127); + ba.writeByte(128 | value >> 7 & 127); + ba.writeByte(value & 127); + } else if ((value & 3221225472) === 0) { + ba.writeByte(128 | value >> 22 & 127); + ba.writeByte(128 | value >> 15 & 127); + ba.writeByte(128 | value >> 8 & 127); + ba.writeByte(value & 255); + } else { + throw 'AMF3 U29 range'; + } + } + function readUTF8vr(ba, caches) { + var u29s = readU29(ba); + if (u29s === 1) { + return ''; + } + var stringsCache = caches.stringsCache || (caches.stringsCache = []); + if ((u29s & 1) === 0) { + return stringsCache[u29s >> 1]; + } + var byteLength = u29s >> 1; + var buffer = new Uint8Array(byteLength); + for (var i = 0; i < byteLength; i++) { + buffer[i] = ba.readByte(); + } + var value = utf8encode(buffer); + stringsCache.push(value); + return value; + } + function writeUTF8vr(ba, value, caches) { + if (value === '') { + ba.writeByte(1); + return; + } + var stringsCache = caches.stringsCache || (caches.stringsCache = []); + var index = stringsCache.indexOf(value); + if (index >= 0) { + writeU29(ba, index << 1); + return; + } + stringsCache.push(value); + var bytes = utf8decode(value); + writeU29(ba, 1 | bytes.length << 1); + for (var i = 0; i < bytes.length; i++) { + ba.writeByte(bytes[i]); + } + } + function readAmf3Data(ba, caches) { + var marker = ba.readByte(); + switch (marker) { + case AMF3_NULL_MARKER: + return null; + case AMF3_UNDEFINED_MARKER: + return undefined; + case AMF3_FALSE_MARKER: + return false; + case AMF3_TRUE_MARKER: + return true; + case AMF3_INTEGER_MARKER: + return readU29(ba); + case AMF3_DOUBLE_MARKER: + return readDouble(ba); + case AMF3_STRING_MARKER: + return readUTF8vr(ba, caches); + case AMF3_DATE_MARKER: + return new Date(readDouble(ba)); + case AMF3_OBJECT_MARKER: + var u29o = readU29(ba); + if ((u29o & 1) === 0) { + return caches.objectsCache[u29o >> 1]; + } + if ((u29o & 4) !== 0) { + throw 'AMF3 Traits-Ext is not supported'; + } + var traits, objectClass; + if ((u29o & 2) === 0) { + traits = caches.traitsCache[u29o >> 2]; + objectClass = traits.class; + } else { + traits = {}; + var aliasName = readUTF8vr(ba, caches); + traits.className = aliasName; + objectClass = aliasName && aliasesCache.names[aliasName]; + traits.class = objectClass; + traits.isDynamic = (u29o & 8) !== 0; + traits.members = []; + var slots = objectClass && objectClass.instanceBindings.slots; + for (var i = 0, j = u29o >> 4; i < j; i++) { + var traitName = readUTF8vr(ba, caches); + var slot = null; + for (var j = 1; slots && j < slots.length; j++) { + if (slots[j].name.name === traitName) { + slot = slots[j]; + break; + } + } + traits.members.push(slot ? Multiname.getQualifiedName(slot.name) : Multiname.getPublicQualifiedName(traitName)); + } + (caches.traitsCache || (caches.traitsCache = [])).push(traits); + } + var obj = objectClass ? objectClass.createInstance() : {}; + (caches.objectsCache || (caches.objectsCache = [])).push(obj); + for (var i = 0; i < traits.members.length; i++) { + var value = readAmf3Data(ba, caches); + obj[traits.members[i]] = value; + } + if (traits.isDynamic) { + while (true) { + var key = readUTF8vr(ba, caches); + if (!key.length) + break; + var value = readAmf3Data(ba, caches); + setAvmProperty(obj, key, value); + } + } + return obj; + case AMF3_ARRAY_MARKER: + var u29o = readU29(ba); + if ((u29o & 1) === 0) { + return caches.objectsCache[u29o >> 1]; + } + var obj = []; + (caches.objectsCache || (caches.objectsCache = [])).push(obj); + var densePortionLength = u29o >> 1; + while (true) { + var key = readUTF8vr(ba, caches); + if (!key.length) + break; + var value = readAmf3Data(ba, caches); + setAvmProperty(obj, key, value); + } + for (var i = 0; i < densePortionLength; i++) { + var value = readAmf3Data(ba, caches); + setAvmProperty(obj, i, value); + } + return obj; + default: + throw 'AMF3 Unknown marker ' + marker; + } + } + function writeCachedReference(ba, obj, caches) { + var objectsCache = caches.objectsCache || (caches.objectsCache = []); + var index = objectsCache.indexOf(obj); + if (index < 0) { + objectsCache.push(obj); + return false; + } + writeU29(ba, index << 1); + return true; + } + function writeAmf3Data(ba, obj, caches) { + switch (typeof obj) { + case 'boolean': + ba.writeByte(obj ? AMF3_TRUE_MARKER : AMF3_FALSE_MARKER); + break; + case 'number': + if (obj === (obj | 0)) { + ba.writeByte(AMF3_INTEGER_MARKER); + writeU29(ba, obj); + } else { + ba.writeByte(AMF3_DOUBLE_MARKER); + writeDouble(ba, obj); + } + break; + case 'undefined': + ba.writeByte(AMF3_UNDEFINED_MARKER); + break; + case 'string': + ba.writeByte(AMF3_STRING_MARKER); + writeUTF8vr(ba, obj, caches); + break; + case 'object': + if (obj === null) { + ba.writeByte(AMF3_NULL_MARKER); + } else if (Array.isArray(obj)) { + ba.writeByte(AMF3_ARRAY_MARKER); + if (writeCachedReference(ba, obj, caches)) + break; + var densePortionLength = 0; + while (densePortionLength in obj) { + ++densePortionLength; + } + writeU29(ba, densePortionLength << 1 | 1); + forEachPublicProperty(obj, function (i, value) { + if (isNumeric(i) && i >= 0 && i < densePortionLength) { + return; + } + writeUTF8vr(ba, i, caches); + writeAmf3Data(ba, value, caches); + }); + writeUTF8vr(ba, '', caches); + for (var j = 0; j < densePortionLength; j++) { + writeAmf3Data(ba, obj[j], caches); + } + } else if (obj instanceof Date) { + ba.writeByte(AMF3_DATE_MARKER); + if (writeCachedReference(ba, obj, caches)) + break; + writeU29(ba, 1); + writeDouble(ba, obj.valueOf()); + } else { + ba.writeByte(AMF3_OBJECT_MARKER); + if (writeCachedReference(ba, obj, caches)) + break; + var isDynamic = true; + var objectClass = obj.class; + if (objectClass) { + isDynamic = !objectClass.classInfo.instanceInfo.isSealed(); + var aliasName = aliasesCache.classes.get(objectClass) || ''; + var traits, traitsCount; + var traitsCache = caches.traitsCache || (caches.traitsCache = []); + var traitsInfos = caches.traitsInfos || (caches.traitsInfos = []); + var traitsRef = traitsCache.indexOf(objectClass); + if (traitsRef < 0) { + var slots = objectClass.instanceBindings.slots; + traits = []; + var traitsNames = []; + for (var i = 1; i < slots.length; i++) { + var slot = slots[i]; + if (!slot.name.getNamespace().isPublic()) { + continue; + } + traits.push(Multiname.getQualifiedName(slot.name)); + traitsNames.push(slot.name.name); + } + traitsCache.push(objectClass); + traitsInfos.push(traits); + traitsCount = traitsNames.length; + writeU29(ba, (isDynamic ? 11 : 3) + (traitsCount << 4)); + writeUTF8vr(ba, aliasName, caches); + for (var i = 0; i < traitsCount; i++) { + writeUTF8vr(ba, traitsNames[i], caches); + } + } else { + traits = traitsInfos[traitsRef]; + traitsCount = traits.length; + writeU29(ba, 1 + (traitsRef << 2)); + } + for (var i = 0; i < traitsCount; i++) { + writeAmf3Data(ba, obj[traits[i]], caches); + } + } else { + writeU29(ba, 11); + writeUTF8vr(ba, '', caches); + } + if (isDynamic) { + forEachPublicProperty(obj, function (i, value) { + writeUTF8vr(ba, i, caches); + writeAmf3Data(ba, value, caches); + }); + writeUTF8vr(ba, '', caches); + } + } + return; + } + } + var aliasesCache = { + classes: new WeakMap(), + names: Object.create(null) + }; + var amf3 = { + write: function (ba, obj) { + writeAmf3Data(ba, obj, {}); + }, + read: function (ba) { + return readAmf3Data(ba, {}); + } + }; + return { + encodings: [ + amf0, + null, + null, + amf3 + ], + aliasesCache: aliasesCache + }; + }(); +function ProxyClass(runtime, scope, instanceConstructor, baseClass) { + function ProxyConstructor() { + somewhatImplemented('Proxy'); + } + var c = new Class('Proxy', ProxyConstructor, ApplicationDomain.coerceCallable(ProxyConstructor)); + c.extendBuiltin(baseClass); + return c; +} +var proxyTrapQns = { + 'getProperty': null, + 'setProperty': null, + 'hasProperty': null, + 'callProperty': null + }; +for (var name in proxyTrapQns) { + proxyTrapQns[name] = VM_OPEN_METHOD_PREFIX + Multiname.getQualifiedName(new Multiname([ + ASNamespace.PROXY + ], name)); +} +function isProxyObject(obj) { + return obj[VM_IS_PROXY]; +} +function nameFromQualifiedName(qn) { + if (isNumeric(qn)) { + return qn; + } + var mn = Multiname.fromQualifiedName(qn); + if (mn === undefined) { + return undefined; + } + return mn.name; +} +function hasNonProxyingCaller() { + var caller = arguments.callee; + var maxDepth = 5; + var domain; + for (var i = 0; i < maxDepth && caller; i++) { + if (caller === nonProxyingHasProperty) { + return true; + } + caller = caller.caller; + } + return false; +} +function installProxyClassWrapper(cls) { + var TRACE_PROXY = false; + if (TRACE_PROXY) { + print('proxy wrapping, class: ' + cls); + } + var instanceConstructor = cls.instanceConstructor; + function construct() { + if (TRACE_PROXY) { + print('proxy create, class: ' + cls); + } + var target = Object.create(instanceConstructor.prototype); + var proxy = Proxy.create({ + get: function (o, qn) { + if (qn === VM_IS_PROXY) { + TRACE_PROXY && print('proxy check'); + return true; + } + if (qn === VM_CALL_PROXY) { + TRACE_PROXY && print('proxy get caller'); + return function apply(mn, receiver, args) { + receiver = receiver ? target : null; + if (TRACE_PROXY) { + print('proxy call, class: ' + target.class + ', mn: ' + mn + 'hasNonProxyingCallerr: ' + hasNonProxyingCaller()); + } + var resolved = Multiname.isQName(mn) ? mn : target.resolveMultinameProperty(mn.namespaces, mn.name, mn.flags); + var qn = resolved ? Multiname.getQualifiedName(resolved) : Multiname.getPublicQualifiedName(mn.name); + if (!nameInTraits(target, qn)) { + return target[proxyTrapQns.callProperty](mn.name, args); + } + if (TRACE_PROXY) { + TRACE_PROXY && print('> proxy pass through ' + resolved); + } + if (target.asOpenMethods && target.asOpenMethods[qn]) { + return target.asOpenMethods[qn].apply(o, args); + } + return undefined; + }; + } + if (TRACE_PROXY) { + print('proxy get, class: ' + target.class + ', qn: ' + qn + 'hasNonProxyingCallerr: ' + hasNonProxyingCaller()); + } + if (!hasNonProxyingCaller()) { + var name = nameFromQualifiedName(qn); + if (name !== undefined && !nameInTraits(target, qn)) { + return target[proxyTrapQns.getProperty](name); + } + } + if (target.asOpenMethods && target.asOpenMethods[qn]) { + return bindSafely(target.asOpenMethods[qn], o); + } + TRACE_PROXY && print('> proxy pass through ' + qn); + return target[qn]; + }, + set: function (o, qn, value) { + if (TRACE_PROXY) { + print('proxy set, class: ' + target.class + ', qn: ' + qn + 'hasNonProxyingCallerr: ' + hasNonProxyingCaller()); + } + if (!hasNonProxyingCaller()) { + var name = nameFromQualifiedName(qn); + if (name !== undefined && !nameInTraits(target, qn)) { + target[proxyTrapQns.setProperty](name, value); + return; + } + } + TRACE_PROXY && print('> proxy pass through ' + qn); + target[qn] = value; + }, + has: function (qn) { + if (TRACE_PROXY) { + print('proxy has, class: ' + target.class + ', qn: ' + qn + 'hasNonProxyingCallerr: ' + hasNonProxyingCaller()); + } + if (!hasNonProxyingCaller()) { + var name = nameFromQualifiedName(qn); + if (name !== undefined && !nameInTraits(target, qn)) { + return target[proxyTrapQns.hasProperty](name); + } + } + return qn in target; + }, + hasOwn: function (qn) { + if (TRACE_PROXY) { + print('proxy hasOwn, class: ' + target.class + ', qn: ' + qn + 'hasNonProxyingCallerr: ' + hasNonProxyingCaller()); + } + if (!hasNonProxyingCaller()) { + var name = nameFromQualifiedName(qn); + if (name !== undefined && !nameInTraits(target, qn)) { + return target[proxyTrapQns.hasProperty](name); + } + } + TRACE_PROXY && print('> proxy pass through ' + qn); + return !(!Object.getOwnPropertyDescriptor(target, qn)); + }, + enumerate: function () { + notImplemented('enumerate'); + }, + keys: function () { + notImplemented('keys'); + } + }, instanceConstructor.prototype); + instanceConstructor.apply(proxy, sliceArguments(arguments, 0)); + return proxy; + } + cls.instanceConstructor = construct; +} +function DictionaryClass(domain, scope, instanceConstructor, baseClass) { + function ASDictionary(weakKeys) { + this.weakKeys = weakKeys; + this.map = new WeakMap(); + if (!weakKeys) { + this.keys = []; + } + this.primitiveMap = createEmptyObject(); + } + var c = new Class('Dictionary', ASDictionary, ApplicationDomain.passthroughCallable(ASDictionary)); + c.extendNative(baseClass, ASDictionary); + function makePrimitiveKey(key) { + if (typeof key === 'string' || typeof key === 'number') { + return key; + } + return undefined; + } + var prototype = ASDictionary.prototype; + defineNonEnumerableProperty(prototype, 'asGetProperty', function asGetProperty(namespaces, name, flags, isMethod) { + var key = makePrimitiveKey(name); + if (key !== undefined) { + return this.primitiveMap[key]; + } + return this.map.get(Object(name)); + }); + defineNonEnumerableProperty(prototype, 'asGetResolvedStringProperty', asGetResolvedStringPropertyFallback); + defineNonEnumerableProperty(prototype, 'asSetProperty', function asSetProperty(namespaces, name, flags, value) { + var key = makePrimitiveKey(name); + if (key !== undefined) { + this.primitiveMap[key] = value; + return; + } + this.map.set(Object(name), value); + if (!this.weakKeys && this.keys.indexOf(name) < 0) { + this.keys.push(name); + } + }); + defineNonEnumerableProperty(prototype, 'asCallProperty', function asCallProperty(namespaces, name, flags, isLex, args) { + notImplemented('asCallProperty'); + }); + defineNonEnumerableProperty(prototype, 'asHasProperty', function asHasProperty(namespaces, name, flags, nonProxy) { + var key = makePrimitiveKey(name); + if (key !== undefined) { + return key in this.primitiveMap; + } + return this.map.has(Object(name)); + }); + defineNonEnumerableProperty(prototype, 'asDeleteProperty', function asDeleteProperty(namespaces, name, flags) { + var key = makePrimitiveKey(name); + if (key !== undefined) { + delete this.primitiveMap[key]; + } + this.map.delete(Object(name)); + var i; + if (!this.weakKeys && (i = this.keys.indexOf(name)) >= 0) { + this.keys.splice(i, 1); + } + return true; + }); + defineNonEnumerableProperty(prototype, 'asGetEnumerableKeys', function () { + if (prototype === this) { + return Object.prototype.asGetEnumerableKeys.call(this); + } + var primitiveMapKeys = []; + for (var k in this.primitiveMap) { + primitiveMapKeys.push(k); + } + if (this.weakKeys) { + return primitiveMapKeys; + } + return primitiveMapKeys.concat(this.keys); + }); + c.native = { + instance: { + init: function () { + } + } + }; + return c; +} +function debugBreak(message) { + debugger; + print('\x1b[91mdebugBreak: ' + message + '\x1b[0m'); +} +var NativeASNamespace; +var natives = function () { + var C = ApplicationDomain.passthroughCallable; + var CC = ApplicationDomain.constructingCallable; + function ObjectClass(applicationDomain, scope, instanceConstructor, baseClass) { + var c = new Class('Object', Object, C(Object)); + c.native = { + instance: { + isPrototypeOf: Object.prototype.isPrototypeOf, + hasOwnProperty: function (name) { + if (name === undefined) { + return false; + } + name = Multiname.getPublicQualifiedName(name); + if (Object.prototype.hasOwnProperty.call(this, name)) { + return true; + } + return Object.getPrototypeOf(this).hasOwnProperty(name); + }, + propertyIsEnumerable: function (name) { + if (name === undefined) { + return false; + } + name = Multiname.getPublicQualifiedName(name); + return Object.prototype.propertyIsEnumerable.call(this, name); + } + }, + static: { + _setPropertyIsEnumerable: function _setPropertyIsEnumerable(obj, name, isEnum) { + name = Multiname.getPublicQualifiedName(name); + var descriptor = Object.getOwnPropertyDescriptor(obj, name); + descriptor.enumerable = false; + Object.defineProperty(obj, name, descriptor); + } + } + }; + c.dynamicPrototype = c.traitsPrototype = Object.prototype; + c.setDefaultProperties(); + c.defaultValue = null; + c.coerce = function (value) { + return asCoerceObject(value); + }; + c.isInstanceOf = function (value) { + if (value === null) { + return false; + } + return true; + }; + c.isInstance = function (value) { + if (value === null || value === undefined) { + return false; + } + return true; + }; + return c; + } + function ClassClass(runtime, scope, instanceConstructor, baseClass) { + var c = Class; + c.debugName = 'Class'; + c.prototype.extendBuiltin.call(c, baseClass); + c.coerce = function (value) { + return value; + }; + c.isInstanceOf = function (value) { + return true; + }; + c.isInstance = function (value) { + return value instanceof c.instanceConstructor; + }; + return c; + } + function BooleanClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('Boolean', Boolean, C(Boolean)); + c.extendBuiltin(baseClass); + c.native = { + instance: { + toString: Boolean.prototype.toString, + valueOf: Boolean.prototype.valueOf + } + }; + c.coerce = Boolean; + c.isInstanceOf = function (value) { + return typeof value === 'boolean' || value instanceof Boolean; + }; + c.isInstance = function (value) { + if (typeof value === 'boolean' || value instanceof Boolean) { + return true; + } + return false; + }; + return c; + } + function FunctionClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('Function', Function, C(Function)); + c.extendBuiltin(baseClass); + c.native = { + instance: { + prototype: { + get: function () { + return this.prototype; + }, + set: function (p) { + this.prototype = p; + } + }, + length: { + get: function () { + if (this.hasOwnProperty(VM_LENGTH)) { + return this.asLength; + } + return this.length; + } + }, + call: Function.prototype.call, + apply: Function.prototype.apply + } + }; + c.coerce = function (value) { + return value; + }; + c.isInstanceOf = function (value) { + return typeof value === 'function'; + }; + c.isInstance = function (value) { + return typeof value === 'function'; + }; + return c; + } + function MethodClosure($this, fn) { + var bound = bindSafely(fn, $this); + defineNonEnumerableProperty(this, 'call', bound.call.bind(bound)); + defineNonEnumerableProperty(this, 'apply', bound.apply.bind(bound)); + } + MethodClosure.prototype = { + toString: function () { + return 'function Function() {}'; + } + }; + function MethodClosureClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('MethodClosure', MethodClosure); + c.extendBuiltin(baseClass); + return c; + } + function StringClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('String', String, C(String)); + c.extendBuiltin(baseClass); + var Sp = String.prototype; + c.native = { + instance: { + length: { + get: function () { + return this.length; + } + }, + indexOf: Sp.indexOf, + lastIndexOf: Sp.lastIndexOf, + charAt: Sp.charAt, + charCodeAt: Sp.charCodeAt, + concat: Sp.concat, + localeCompare: Sp.localeCompare, + match: function (re) { + if (re === void 0 || re === null) { + return null; + } else { + if (re instanceof RegExp && re.global) { + var matches = [], m; + while (m = re.exec(this)) { + matches.push(m[0]); + } + return matches; + } + if (!(re instanceof RegExp) && !(typeof re === 'string')) { + re = String(re); + } + return this.match(re); + } + }, + replace: Sp.replace, + search: function (re) { + if (re === void 0) { + return -1; + } else { + return this.search(re); + } + }, + slice: Sp.slice, + split: Sp.split, + substr: Sp.substr, + substring: Sp.substring, + toLowerCase: Sp.toLowerCase, + toLocaleLowerCase: Sp.toLocaleLowerCase, + toUpperCase: function () { + var str = Sp.toUpperCase.apply(this); + var str = str.replace(/\u039C/g, String.fromCharCode(181)); + return str; + }, + toLocaleUpperCase: function () { + var str = Sp.toLocaleUpperCase.apply(this); + var str = str.replace(/\u039C/g, String.fromCharCode(181)); + return str; + }, + toString: Sp.toString, + valueOf: Sp.valueOf + }, + static: String + }; + c.isInstance = function (value) { + return value !== null && value !== undefined && typeof value.valueOf() === 'string'; + }; + c.coerce = function (value) { + if (value === null || value === undefined) { + return null; + } + return String(value); + }; + c.isInstanceOf = function (value) { + return Object(value) instanceof String; + }; + c.isInstance = function (value) { + return Object(value) instanceof String; + }; + return c; + } + function VectorClass(domain, scope, instanceConstructor, baseClass) { + return createVectorClass(undefined, baseClass); + } + function ObjectVectorClass(domain, scope, instanceConstructor, baseClass) { + return createVectorClass(domain.getClass('Object'), baseClass); + } + function IntVectorClass(domain, scope, instanceConstructor, baseClass) { + return createVectorClass(domain.getClass('int'), baseClass); + } + function UIntVectorClass(domain, scope, instanceConstructor, baseClass) { + return createVectorClass(domain.getClass('uint'), baseClass); + } + function DoubleVectorClass(domain, scope, instanceConstructor, baseClass) { + return createVectorClass(domain.getClass('Number'), baseClass); + } + function createVectorClass(type, baseClass) { + var V; + if (type) { + var className = 'Vector$' + type.classInfo.instanceInfo.name.name; + switch (className) { + case 'Vector$int': + V = Int32Vector; + break; + case 'Vector$uint': + V = Uint32Vector; + break; + case 'Vector$Number': + V = Float64Vector; + break; + case 'Vector$Object': + V = GenericVector; + break; + default: + unexpected(); + break; + } + } else { + V = GenericVector.applyType(null); + } + var Vp = V.prototype; + var cls = new Class(className, V, C(V.callable)); + if (V === GenericVector) { + cls.applyType = function (type) { + return cls; + }; + } + cls.extendWrapper(baseClass, V); + cls.native = { + instance: { + fixed: { + get: function () { + return this._fixed; + }, + set: function (v) { + this._fixed = v; + } + }, + length: { + get: function () { + return this.length; + }, + set: function setLength(length) { + this.length = length; + } + }, + push: Vp.push, + pop: Vp.pop, + shift: Vp.shift, + unshift: Vp.unshift, + _reverse: Vp.reverse, + _filter: Vp.filter, + _map: Vp.map, + newThisType: function newThisType() { + return new cls.instanceConstructor(); + }, + _spliceHelper: function _spliceHelper(insertPoint, insertCount, deleteCount, args, offset) { + return this._spliceHelper(insertPoint, insertCount, deleteCount, args, offset); + } + }, + static: { + _some: function (o, callback, thisObject) { + return o.some(callback, thisObject); + }, + _every: function (o, callback, thisObject) { + return o.every(callback, thisObject); + }, + _forEach: function (o, callback, thisObject) { + return o.forEach(callback, thisObject); + }, + _sort: arraySort + } + }; + cls.vectorType = type; + cls.coerce = function (value) { + return value; + }; + cls.isInstanceOf = function (value) { + return true; + }; + cls.isInstance = function (value) { + if (value === null || typeof value !== 'object') { + return false; + } + if (!this.instanceConstructor.vectorType && value.class.vectorType) { + return true; + } + return this.instanceConstructor.prototype.isPrototypeOf(value); + }; + return cls; + } + function NumberClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('Number', Number, C(Number)); + c.extendBuiltin(baseClass); + c.native = { + instance: Number.prototype + }; + c.defaultValue = Number(0); + c.isInstance = function (value) { + return value !== null && value !== undefined && typeof value.valueOf() === 'number'; + }; + c.coerce = Number; + c.isInstanceOf = function (value) { + return Object(value) instanceof Number; + }; + c.isInstance = function (value) { + return Object(value) instanceof Number; + }; + return c; + } + function Int(x) { + return x | 0; + } + function boxedInt(x) { + return Object(x | 0); + } + function intClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('int', boxedInt, C(Int)); + c.extendBuiltin(baseClass); + c.defaultValue = 0; + c.coerce = Int; + c.isInstanceOf = function (value) { + return false; + }; + c.isInstance = function (value) { + if (value instanceof Number) { + value = value.valueOf(); + } + return (value | 0) === value; + }; + return c; + } + function Uint(x) { + return x >>> 0; + } + function boxedUint(x) { + return Object(x >>> 0); + } + function uintClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('uint', boxedUint, C(Uint)); + c.extend(baseClass); + c.defaultValue = 0; + c.isInstanceOf = function (value) { + return false; + }; + c.isInstance = function (value) { + if (value instanceof Number) { + value = value.valueOf(); + } + return value >>> 0 === value; + }; + c.coerce = Uint; + return c; + } + function MathClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('Math'); + c.native = { + static: Math + }; + return c; + } + function DateClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('Date', Date, C(Date)); + c.extendBuiltin(baseClass); + c.native = { + instance: Date.prototype, + static: Date + }; + return c; + } + function makeErrorClass(name) { + var ErrorDefinition = { + __glue__: { + script: { + instance: { + message: 'public message', + name: 'public name' + } + }, + native: { + instance: { + getStackTrace: function () { + somewhatImplemented('Error.getStackTrace()'); + return AVM2.getStackTrace(); + } + }, + static: { + getErrorMessage: getErrorMessage + } + } + } + }; + return function (runtime, scope, instanceConstructor, baseClass) { + var c = new Class(name, instanceConstructor); + c.extend(baseClass); + if (name === 'Error') { + c.link(ErrorDefinition); + c.linkNatives(ErrorDefinition); + } + return c; + }; + } + function RegExpClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('RegExp', XRegExp, C(XRegExp)); + c.extendBuiltin(baseClass); + RegExpClass.exec = function exec() { + var result = this.exec.apply(this, arguments); + if (!result) { + return result; + } + var keys = Object.keys(result); + for (var i = 0; i < keys.length; i++) { + var k = keys[i]; + if (!isNumeric(k)) { + if (result[k] === undefined) { + result[k] = ''; + } + } + } + publicizeProperties(result); + return result; + }; + RegExpClass.test = function test() { + return this.exec.apply(this, arguments) !== null; + }; + c.native = { + instance: { + global: { + get: function () { + return this.global; + } + }, + source: { + get: function () { + return this.source; + } + }, + ignoreCase: { + get: function () { + return this.ignoreCase; + } + }, + multiline: { + get: function () { + return this.multiline; + } + }, + lastIndex: { + get: function () { + return this.lastIndex; + }, + set: function (i) { + this.lastIndex = i; + } + }, + dotall: { + get: function () { + return this.dotall; + } + }, + extended: { + get: function () { + return this.extended; + } + }, + exec: RegExpClass.exec, + test: RegExpClass.test + } + }; + return c; + } + function NamespaceClass(runtime, scope, instanceConstructor, baseClass) { + NativeASNamespace = function NativeASNamespace(prefixValue, uriValue) { + if (uriValue === undefined) { + uriValue = prefixValue; + prefixValue = undefined; + } + var prefix, uri; + if (prefixValue === undefined) { + if (uriValue === undefined) { + prefix = ''; + uri = ''; + } else if (typeof uriValue === 'object') { + prefix = uriValue.prefix; + if (uriValue instanceof ASNamespace) { + uri = uriValue.uri; + } else if (uriValue instanceof QName) { + uri = uriValue.uri; + } + } else { + uri = uriValue + ''; + if (uri === '') { + prefix = ''; + } else { + prefix = undefined; + } + } + } else { + if (typeof uriValue === 'object' && uriValue instanceof QName && uriValue.uri !== null) { + uri = uriValue.uri; + } else { + uri = uriValue + ''; + } + if (uri === '') { + if (prefixValue === undefined || prefixValue + '' === '') { + prefix = ''; + } else { + throw 'type error'; + } + } else if (prefixValue === undefined || prefixValue === '') { + prefix = undefined; + } else if (false && !isXMLName(prefixValue)) { + prefix = undefined; + } else { + prefix = prefixValue + ''; + } + } + return ASNamespace.createNamespace(uri, prefix); + }; + var c = new Class('Namespace', NativeASNamespace, C(NativeASNamespace)); + c.extendNative(baseClass, ASNamespace); + var Np = ASNamespace.prototype; + c.native = { + instance: { + prefix: { + get: Np.getPrefix + }, + uri: { + get: Np.getURI + } + } + }; + return c; + } + function JSONClass(runtime, scope, instanceConstructor, baseClass) { + function transformJSValueToAS(value) { + if (typeof value !== 'object') { + return value; + } + var keys = Object.keys(value); + var result = value instanceof Array ? [] : {}; + for (var i = 0; i < keys.length; i++) { + result.asSetPublicProperty(keys[i], transformJSValueToAS(value[keys[i]])); + } + return result; + } + function transformASValueToJS(value) { + if (typeof value !== 'object') { + return value; + } + var keys = Object.keys(value); + var result = value instanceof Array ? [] : {}; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var jsKey = key; + if (!isNumeric(key)) { + jsKey = Multiname.getNameFromPublicQualifiedName(key); + } + result[jsKey] = transformASValueToJS(value[key]); + } + return result; + } + function ASJSON() { + } + var c = new Class('JSON', ASJSON, C(ASJSON)); + c.extend(baseClass); + c.native = { + static: { + parseCore: function parseCore(text) { + return transformJSValueToAS(JSON.parse(text)); + }, + stringifySpecializedToString: function stringifySpecializedToString(value, replacerArray, replacerFunction, gap) { + return JSON.stringify(transformASValueToJS(value), replacerFunction, gap); + } + } + }; + return c; + } + function CapabilitiesClass(runtime, scope, instanceConstructor, baseClass) { + function Capabilities() { + } + var c = new Class('Capabilities', Capabilities, C(Capabilities)); + c.extend(baseClass); + c.native = { + static: { + playerType: { + get: function () { + return 'AVMPlus'; + } + } + } + }; + return c; + } + function FileClass(runtime, scope, instanceConstructor, baseClass) { + function File() { + } + var c = new Class('File', File, C(File)); + c.extend(baseClass); + c.native = { + static: { + exists: function (filename) { + notImplemented('File.exists'); + return false; + }, + read: function (filename) { + return snarf(filename); + }, + write: function (filename, data) { + notImplemented('File.write'); + return true; + }, + readByteArray: function (filename) { + var ByteArrayClass = AVM2.currentDomain().getClass('flash.utils.ByteArray'); + var data = ByteArrayClass.createInstance(); + data.writeRawBytes(snarf(filename, 'binary')); + return data; + }, + writeByteArray: function (filename, bytes) { + write('bin/' + filename, bytes.getBytes()); + return true; + } + } + }; + return c; + } + function ShumwayClass(runtime, scope, instanceConstructor, baseClass) { + function Shumway() { + } + var c = new Class('Shumway', Shumway, C(Shumway)); + c.extend(baseClass); + c.native = { + static: { + info: function (x) { + console.info(x); + }, + json: function (x) { + return JSON.stringify(x); + }, + eval: function (x) { + return eval(x); + }, + debugger: function (x) { + debugger; + } + } + }; + return c; + } + function constant(x) { + return function () { + return x; + }; + } + function ByteArrayClass(runtime, scope, instanceConstructor, baseClass) { + var BA = function () { + ByteArray.call(this); + }; + var BAp = BA.prototype = Object.create(ByteArray.prototype); + var c = new Class('ByteArray', BA, C(BA)); + c.extendBuiltin(baseClass); + BAp.asGetNumericProperty = function (i) { + if (i >= this.length) { + return undefined; + } + return this.uint8v[i]; + }; + BAp.asSetNumericProperty = function (i, v) { + var len = i + 1; + this.ensureCapacity(len); + this.uint8v[i] = v; + if (len > this.length) { + this.length = len; + } + }; + BAp.readUTF = function readUTF() { + return this.readUTFBytes(this.readShort()); + }; + BAp.readUTFBytes = function readUTFBytes(length) { + var pos = this.position; + if (pos + length > this.length) { + throwEOFError(); + } + this.position += length; + return utf8encode(new Int8Array(this.a, pos, length)); + }; + BAp.writeUTF = function writeUTF(str) { + var bytes = utf8decode(str); + this.writeShort(bytes.length); + this.writeRawBytes(bytes); + }; + BAp.writeUTFBytes = function writeUTFBytes(str) { + var bytes = utf8decode(str); + this.writeRawBytes(bytes); + }; + BAp.toString = function toString() { + return utf8encode(new Int8Array(this.a, 0, this.length)); + }; + c.native = { + instance: { + length: { + get: function () { + return this.length; + }, + set: function setLength(length) { + var cap = this.a.byteLength; + if (length > cap) { + this.ensureCapacity(length); + } + this.length = length; + this.position = clamp(this.position, 0, this.length); + } + }, + bytesAvailable: { + get: function () { + return this.length - this.position; + } + }, + position: { + get: function () { + return this.position; + }, + set: function (p) { + this.position = p; + } + }, + endian: { + get: function () { + return this.le ? 'littleEndian' : 'bigEndian'; + }, + set: function (e) { + this.le = e === 'littleEndian'; + } + }, + objectEncoding: { + get: function () { + return this.objectEncoding; + }, + set: function (v) { + this.objectEncoding = v; + } + }, + writeBytes: BAp.writeBytes, + writeBoolean: BAp.writeBoolean, + writeByte: BAp.writeByte, + writeShort: BAp.writeShort, + writeInt: BAp.writeInt, + writeUnsignedInt: BAp.writeUnsignedInt, + writeFloat: BAp.writeFloat, + writeDouble: BAp.writeDouble, + writeMultiByte: BAp.writeMultiByte, + writeObject: function writeObject(v) { + return AMFUtils.encodings[this.objectEncoding].write(this, v); + }, + writeUTF: BAp.writeUTF, + writeUTFBytes: BAp.writeUTFBytes, + readBoolean: BAp.readBoolean, + readByte: BAp.readByte, + readBytes: BAp.readBytes, + readUnsignedByte: BAp.readUnsignedByte, + readShort: BAp.readShort, + readUnsignedShort: BAp.readUnsignedShort, + readInt: BAp.readInt, + readUnsignedInt: BAp.readUnsignedInt, + readFloat: BAp.readFloat, + readDouble: BAp.readDouble, + readMultiByte: BAp.readMultiByte, + readObject: function readObject() { + return AMFUtils.encodings[this.objectEncoding].read(this); + }, + readUTF: BAp.readUTF, + readUTFBytes: BAp.readUTFBytes, + toString: BAp.toString, + clear: BAp.clear, + _compress: BAp.compress, + _uncompress: BAp.uncompress + }, + static: { + defaultObjectEncoding: { + get: function () { + return ByteArray.DEFAULT_OBJECT_ENCODING; + }, + set: function (e) { + ByteArray.DEFAULT_OBJECT_ENCODING = e; + } + } + } + }; + return c; + } + function DomainClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('File', instanceConstructor, C(instanceConstructor)); + c.extend(baseClass); + c.native = { + instance: { + init: function (base) { + this.base = base; + this.nativeObject = new ApplicationDomain(AVM2.instance, base ? base.nativeObject : null); + }, + loadBytes: function (byteArray, swfVersion) { + this.nativeObject.executeAbc(new AbcFile(byteArray.readRawBytes())); + }, + getClass: function (className) { + return this.nativeObject.getClass(className); + } + }, + static: { + currentDomain: { + get: function () { + var domain = Object.create(instanceConstructor.prototype); + domain.nativeObject = AVM2.currentDomain(); + return domain; + } + } + } + }; + return c; + } + function SystemClass(runtime, scope, instanceConstructor, baseClass) { + var c = new Class('System', instanceConstructor, C(instanceConstructor)); + c.extend(baseClass); + c.native = { + static: { + swfVersion: { + get: function () { + return 19; + } + }, + apiVersion: { + get: function () { + return 26; + } + }, + getArgv: function () { + return []; + }, + getRunmode: function () { + return 'mixed'; + } + } + }; + return c; + } + function bugzilla(n) { + switch (n) { + case 574600: + return true; + } + return false; + } + return { + print: constant(print), + notImplemented: constant(notImplemented), + debugBreak: constant(debugBreak), + bugzilla: constant(bugzilla), + decodeURI: constant(decodeURI), + decodeURIComponent: constant(decodeURIComponent), + encodeURI: constant(encodeURI), + encodeURIComponent: constant(encodeURIComponent), + isNaN: constant(isNaN), + isFinite: constant(isFinite), + parseInt: constant(parseInt), + parseFloat: constant(parseFloat), + escape: constant(escape), + unescape: constant(unescape), + isXMLName: constant(typeof isXMLName !== 'undefined' ? isXMLName : function () { + notImplemented('Chrome doesn\'t support isXMLName.'); + }), + Function: Function, + String: String, + Array: Array, + Number: Number, + Boolean: Boolean, + Math: Math, + Date: Date, + RegExp: RegExp, + Object: Object, + ObjectClass: ObjectClass, + Class: ClassClass, + NamespaceClass: NamespaceClass, + FunctionClass: FunctionClass, + MethodClosureClass: MethodClosureClass, + BooleanClass: BooleanClass, + StringClass: StringClass, + NumberClass: NumberClass, + intClass: intClass, + uintClass: uintClass, + ArrayClass: ArrayClass, + VectorClass: VectorClass, + ObjectVectorClass: ObjectVectorClass, + IntVectorClass: IntVectorClass, + UIntVectorClass: UIntVectorClass, + DoubleVectorClass: DoubleVectorClass, + ByteArrayClass: ByteArrayClass, + ProxyClass: ProxyClass, + ErrorClass: makeErrorClass('Error'), + DefinitionErrorClass: makeErrorClass('DefinitionError'), + EvalErrorClass: makeErrorClass('EvalError'), + RangeErrorClass: makeErrorClass('RangeError'), + ReferenceErrorClass: makeErrorClass('ReferenceError'), + SecurityErrorClass: makeErrorClass('SecurityError'), + SyntaxErrorClass: makeErrorClass('SyntaxError'), + TypeErrorClass: makeErrorClass('TypeError'), + URIErrorClass: makeErrorClass('URIError'), + VerifyErrorClass: makeErrorClass('VerifyError'), + UninitializedErrorClass: makeErrorClass('UninitializedError'), + ArgumentErrorClass: makeErrorClass('ArgumentError'), + DateClass: DateClass, + MathClass: MathClass, + RegExpClass: RegExpClass, + DictionaryClass: DictionaryClass, + XMLClass: XMLClass, + XMLListClass: XMLListClass, + QNameClass: QNameClass, + JSONClass: JSONClass, + ShumwayClass: ShumwayClass, + CapabilitiesClass: CapabilitiesClass, + FileClass: FileClass, + DomainClass: DomainClass, + SystemClass: SystemClass, + getQualifiedClassName: constant(function (value) { + if (value === null) { + return 'null'; + } else if (value === undefined) { + return 'void'; + } + switch (typeof value) { + case 'number': + if ((value | 0) === value) { + return 'int'; + } + return 'Number'; + case 'string': + return 'String'; + case 'boolean': + return 'Boolean'; + case 'object': + if (value instanceof Date) { + return 'Date'; + } + var cls; + if (value instanceof Class) { + cls = value; + } else if (value.class) { + cls = value.class; + } else if (value.classInfo) { + cls = value; + } + if (cls) { + var name = cls.classInfo.instanceInfo.name; + var uri = name.namespaces[0].uri; + if (uri) { + return uri + '::' + name.name; + } + return name.name; + } + break; + } + return notImplemented(value + ' (' + typeof value + ')'); + }), + getQualifiedSuperclassName: constant(function (value) { + switch (typeof value) { + case 'number': + case 'string': + case 'boolean': + return 'Object'; + case 'function': + return 'Function'; + case 'object': + if (value instanceof Date) { + return 'Object'; + } + var cls; + if (value.class) { + cls = value.class; + } else if (value.classInfo) { + cls = value; + } + if (cls && cls.baseClass) { + var name = cls.baseClass.classInfo.instanceInfo.name; + var uri = name.namespaces[0].uri; + if (uri) { + return uri + '::' + name.name; + } + return name.name; + } + return 'Object'; + } + return notImplemented(value + ' (superOf ' + typeof value + ')'); + }), + getDefinitionByName: constant(function (name) { + var simpleName = String(name).replace('::', '.'); + return AVM2.currentDomain().getClass(simpleName); + }), + describeTypeJSON: constant(describeTypeJSON), + original: jsGlobal[VM_NATIVE_BUILTIN_ORIGINALS] + }; + function describeTypeJSON(o, flags) { + var Flags = { + HIDE_NSURI_METHODS: 1, + INCLUDE_BASES: 2, + INCLUDE_INTERFACES: 4, + INCLUDE_VARIABLES: 8, + INCLUDE_ACCESSORS: 16, + INCLUDE_METHODS: 32, + INCLUDE_METADATA: 64, + INCLUDE_CONSTRUCTOR: 128, + INCLUDE_TRAITS: 256, + USE_ITRAITS: 512, + HIDE_OBJECT: 1024 + }; + var declaredByKey = publicName('declaredBy'); + var metadataKey = publicName('metadata'); + var accessKey = publicName('access'); + var uriKey = publicName('uri'); + var nameKey = publicName('name'); + var typeKey = publicName('type'); + var returnTypeKey = publicName('returnType'); + var valueKey = publicName('value'); + var keyKey = publicName('key'); + var parametersKey = publicName('parameters'); + var optionalKey = publicName('optional'); + var cls = o.classInfo ? o : Object.getPrototypeOf(o).class; + true; + var info = cls.classInfo; + var description = {}; + description[nameKey] = unmangledQualifiedName(info.instanceInfo.name); + description[publicName('isDynamic')] = cls === o ? true : !(info.instanceInfo.flags & CONSTANT_ClassSealed); + description[publicName('isStatic')] = cls === o; + description[publicName('isFinal')] = cls === o ? true : !(info.instanceInfo.flags & CONSTANT_ClassFinal); + if (flags & Flags.INCLUDE_TRAITS) { + description[publicName('traits')] = addTraits(cls, flags); + } + var metadata = null; + if (info.metadata) { + metadata = Object.keys(info.metadata).map(function (key) { + return describeMetadata(info.metadata[key]); + }); + } + description[metadataKey] = metadata; + return description; + function publicName(str) { + return Multiname.getPublicQualifiedName(str); + } + function unmangledQualifiedName(mn) { + var name = mn.name; + var namespace = mn.namespaces[0]; + if (namespace && namespace.uri) { + return namespace.uri + '::' + name; + } + return name; + } + function describeMetadata(metadata) { + var result = {}; + result[nameKey] = metadata.name; + result[valueKey] = metadata.value.map(function (value) { + var val = {}; + val[keyKey] = value.key; + val[valueKey] = value.value; + return value; + }); + return result; + } + function addTraits(cls, flags) { + var includedMembers = [ + flags & Flags.INCLUDE_VARIABLES, + flags & Flags.INCLUDE_METHODS, + flags & Flags.INCLUDE_ACCESSORS, + flags & Flags.INCLUDE_ACCESSORS + ]; + var includeBases = flags & Flags.INCLUDE_BASES; + var includeMetadata = flags & Flags.INCLUDE_METADATA; + var obj = {}; + var basesVal = obj[publicName('bases')] = includeBases ? [] : null; + if (flags & Flags.INCLUDE_INTERFACES) { + var interfacesVal = obj[publicName('interfaces')] = []; + if (flags & Flags.USE_ITRAITS) { + for (var key in cls.implementedInterfaces) { + var ifaceName = cls.implementedInterfaces[key].name; + interfacesVal.push(unmangledQualifiedName(ifaceName)); + } + } + } else { + obj[publicName('interfaces')] = null; + } + var variablesVal = obj[publicName('variables')] = flags & Flags.INCLUDE_VARIABLES ? [] : null; + var accessorsVal = obj[publicName('accessors')] = flags & Flags.INCLUDE_ACCESSORS ? [] : null; + var methodsVal = obj[publicName('methods')] = flags & Flags.INCLUDE_METHODS ? [] : null; + var encounteredAccessors = {}; + var addBase = false; + while (cls) { + var className = unmangledQualifiedName(cls.classInfo.instanceInfo.name); + if (includeBases && addBase) { + basesVal.push(className); + } else { + addBase = true; + } + if (flags & Flags.USE_ITRAITS) { + describeTraits(cls.classInfo.instanceInfo.traits); + } else { + describeTraits(cls.classInfo.traits); + } + cls = cls.baseClass; + } + function describeTraits(traits) { + true; + for (var i = 0; traits && i < traits.length; i++) { + var t = traits[i]; + if (!includedMembers[t.kind] || !t.name.getNamespace().isPublic() && !t.name.uri) { + continue; + } + var name = unmangledQualifiedName(t.name); + if (encounteredAccessors[name]) { + var val = encounteredAccessors[name]; + val[accessKey] = 'readwrite'; + if (t.kind === TRAIT_Getter) { + val[typeKey] = unmangledQualifiedName(t.methodInfo.returnType); + } + continue; + } + var val = {}; + if (includeMetadata && t.metadata) { + var metadataVal = val[metadataKey] = []; + for (var key in t.metadata) { + metadataVal.push(describeMetadata(t.metadata[key])); + } + } else { + val[metadataKey] = null; + } + val[declaredByKey] = className; + val[uriKey] = t.name.uri === undefined ? null : t.name.uri; + val[nameKey] = name; + if (!t.typeName && !(t.methodInfo && t.methodInfo.returnType)) { + continue; + } + val[t.kind === TRAIT_Method ? returnTypeKey : typeKey] = unmangledQualifiedName(t.kind === TRAIT_Slot ? t.typeName : t.methodInfo.returnType); + switch (t.kind) { + case TRAIT_Slot: + val[accessKey] = 'readwrite'; + variablesVal.push(val); + break; + case TRAIT_Method: + var parametersVal = val[parametersKey] = []; + var parameters = t.methodInfo.parameters; + for (var j = 0; j < parameters.length; j++) { + var param = parameters[j]; + var paramVal = {}; + paramVal[typeKey] = param.type ? unmangledQualifiedName(param.type) : '*'; + paramVal[optionalKey] = 'value' in param; + parametersVal.push(paramVal); + } + methodsVal.push(val); + break; + case TRAIT_Getter: + case TRAIT_Setter: + val[accessKey] = t.kind === TRAIT_Getter ? 'read' : 'write'; + accessorsVal.push(val); + encounteredAccessors[name] = val; + break; + default: + break; + } + } + } + return obj; + } + } + }(); +function getNative(path) { + var chain = path.split('.'); + var v = natives; + for (var i = 0, j = chain.length; i < j; i++) { + v = v && v[chain[i]]; + } + true; + return v; +} +var disassemblerOptions = systemOptions.register(new OptionSet('Disassembler Options')); +var filter = disassemblerOptions.register(new Option('f', 'filter', 'string', 'SpciMsmNtu', '[S]ource, constant[p]ool, [c]lasses, [i]nstances, [M]etadata, [s]cripts, [m]ethods, multi[N]ames, S[t]atistics, [u]tf')); +function traceArray(writer, name, array, abc) { + if (array.length === 0) { + return; + } + writer.enter(name + ' {'); + array.forEach(function (a, idx) { + a.trace(writer, abc); + }); + writer.leave('}'); +} +AbcFile.prototype.trace = function trace(writer) { + if (filter.value.indexOf('p') >= 0) { + this.constantPool.trace(writer); + } + if (filter.value.indexOf('N') >= 0) { + this.constantPool.traceMultinamesOnly(writer); + } + if (filter.value.indexOf('c') >= 0) { + traceArray(writer, 'classes', this.classes); + } + if (filter.value.indexOf('i') >= 0) { + traceArray(writer, 'instances', this.instances); + } + if (filter.value.indexOf('M') >= 0) { + traceArray(writer, 'metadata', this.metadata); + } + if (filter.value.indexOf('s') >= 0) { + traceArray(writer, 'scripts', this.scripts); + } + if (filter.value.indexOf('m') >= 0) { + traceArray(writer, 'methods', this.methods, this); + } + if (filter.value.indexOf('S') >= 0) { + traceSource(writer, this); + } + if (filter.value.indexOf('t') >= 0) { + traceStatistics(writer, this); + } + if (filter.value.indexOf('u') >= 0) { + print(JSON.stringify({ + strings: this.constantPool.strings, + positionAfterUTFStrings: this.constantPool.positionAfterUTFStrings + }, null, 2)); + } +}; +ConstantPool.prototype.trace = function (writer) { + writer.enter('constantPool {'); + for (var key in this) { + if (key === 'namespaces') { + writer.enter('namespaces {'); + this.namespaces.forEach(function (ns, i) { + writer.writeLn(('' + i).padRight(' ', 3) + (ns ? ns.toString() : '*')); + }); + writer.leave('}'); + } else if (this[key] instanceof Array) { + writer.enter(key + ' ' + this[key].length + ' {'); + writer.writeArray(this[key]); + writer.leave('}'); + } + } + writer.leave('}'); +}; +ConstantPool.prototype.traceMultinamesOnly = function (writer) { + writer.writeArray(this.multinames, null, true); +}; +ClassInfo.prototype.trace = function (writer) { + writer.enter('class ' + this + ' {'); + traceArray(writer, 'traits', this.traits); + writer.leave('}'); +}; +MetaDataInfo.prototype.trace = function (writer) { + writer.enter(this + ' {'); + this.value.forEach(function (item) { + writer.writeLn((item.key ? item.key + ': ' : '') + '"' + item.value + '"'); + }); + writer.leave('}'); +}; +InstanceInfo.prototype.trace = function (writer) { + writer.enter('instance ' + this + ' {'); + traceArray(writer, 'traits', this.traits); + writer.leave('}'); +}; +ScriptInfo.prototype.trace = function (writer) { + writer.enter('script ' + this + ' {'); + traceArray(writer, 'traits', this.traits); + writer.leave('}'); +}; +Trait.prototype.trace = function (writer) { + if (this.metadata) { + for (var key in this.metadata) { + if (this.metadata.hasOwnProperty(key)) { + this.metadata[key].trace(writer); + } + } + } + writer.writeLn(this); +}; +function traceAbc(writer, abc) { + abc.trace(writer); +} +function traceOperand(operand, abc, code) { + var value = 0; + switch (operand.size) { + case 's08': + value = code.readS8(); + break; + case 'u08': + value = code.readU8(); + break; + case 's16': + value = code.readS16(); + break; + case 's24': + value = code.readS24(); + break; + case 'u30': + value = code.readU30(); + break; + case 'u32': + value = code.readU32(); + break; + default: + true; + break; + } + var description = ''; + switch (operand.type) { + case '': + break; + case 'I': + description = abc.constantPool.ints[value]; + break; + case 'U': + description = abc.constantPool.uints[value]; + break; + case 'D': + description = abc.constantPool.doubles[value]; + break; + case 'S': + description = abc.constantPool.strings[value]; + break; + case 'N': + description = abc.constantPool.namespaces[value]; + break; + case 'CI': + description = abc.classes[value]; + break; + case 'M': + return abc.constantPool.multinames[value]; + default: + description = '?'; + break; + } + return operand.name + ':' + value + (description === '' ? '' : ' (' + description + ')'); +} +function traceOperands(opcode, abc, code, rewind) { + rewind = rewind || false; + var old = code.position; + var str = ''; + if (opcode.operands === null) { + str = 'null'; + } else { + opcode.operands.forEach(function (op, i) { + str += traceOperand(op, abc, code); + if (i < opcode.operands.length - 1) { + str += ', '; + } + }); + } + if (rewind) { + code.seek(old); + } + return str; +} +MethodInfo.prototype.trace = function trace(writer) { + var abc = this.abc; + writer.enter('method' + (this.name ? ' ' + this.name : '') + ' {'); + writer.writeLn('flags: ' + getFlags(this.flags, 'NEED_ARGUMENTS|NEED_ACTIVATION|NEED_REST|HAS_OPTIONAL||NATIVE|SET_DXN|HAS_PARAM_NAMES'.split('|'))); + writer.writeLn('parameters: ' + this.parameters.map(function (x) { + return (x.type ? Multiname.getQualifiedName(x.type) + '::' : '') + x.name; + })); + if (!this.code) { + writer.leave('}'); + return; + } + var code = new AbcStream(this.code); + traceArray(writer, 'traits', this.traits); + writer.enter('code {'); + while (code.remaining() > 0) { + var bc = code.readU8(); + var opcode = opcodeTable[bc]; + var str, defaultOffset, offset, count; + str = ('' + code.position).padRight(' ', 6); + switch (bc) { + case OP_lookupswitch: + str += opcode.name + ': defaultOffset: ' + code.readS24(); + var caseCount = code.readU30(); + str += ', caseCount: ' + caseCount; + for (var i = 0; i < caseCount + 1; i++) { + str += ' offset: ' + code.readS24(); + } + writer.writeLn(str); + break; + default: + if (opcode) { + str += opcode.name.padRight(' ', 20); + if (!opcode.operands) { + true; + } else { + if (opcode.operands.length > 0) { + str += traceOperands(opcode, abc, code); + } + writer.writeLn(str); + } + } else { + true; + } + break; + } + } + writer.leave('}'); + writer.leave('}'); +}; +var SourceTracer = function () { + function literal(value) { + if (value === undefined) { + return 'undefined'; + } else if (value === null) { + return 'null'; + } else if (typeof value === 'string') { + return '"' + value + '"'; + } else { + return String(value); + } + } + function getSignature(mi, excludeTypesAndDefaultValues) { + return mi.parameters.map(function (x) { + var str = x.name; + if (!excludeTypesAndDefaultValues) { + if (x.type) { + str += ':' + x.type.getName(); + } + if (x.value !== undefined) { + str += ' = ' + literal(x.value); + } + } + return str; + }).join(', '); + } + function SourceTracer(writer) { + this.writer = writer; + } + SourceTracer.prototype = { + traceTraits: function traceTraits(traits, isStatic, inInterfaceNamespace) { + var writer = this.writer; + var tracer = this; + traits.forEach(function (trait) { + var str; + var accessModifier = Multiname.getAccessModifier(trait.name); + var namespaceName = trait.name.namespaces[0].uri; + if (namespaceName) { + if (namespaceName === 'http://adobe.com/AS3/2006/builtin') { + namespaceName = 'AS3'; + } + if (accessModifier === 'public') { + str = inInterfaceNamespace === namespaceName ? '' : namespaceName; + } else { + str = accessModifier; + } + } else { + str = accessModifier; + } + if (isStatic) { + str += ' static'; + } + if (trait.isSlot() || trait.isConst()) { + tracer.traceMetadata(trait.metadata); + if (trait.isConst()) { + str += ' const'; + } else { + str += ' var'; + } + str += ' ' + trait.name.getName(); + if (trait.typeName) { + str += ':' + trait.typeName.getName(); + } + if (trait.value) { + str += ' = ' + literal(trait.value); + } + writer.writeLn(str + ';'); + } else if (trait.isMethod() || trait.isGetter() || trait.isSetter()) { + tracer.traceMetadata(trait.metadata); + var mi = trait.methodInfo; + if (trait.attributes & ATTR_Override) { + str += ' override'; + } + if (mi.isNative()) { + str += ' native'; + } + str += ' function'; + str += trait.isGetter() ? ' get' : trait.isSetter() ? ' set' : ''; + str += ' ' + trait.name.getName(); + str += '(' + getSignature(mi) + ')'; + str += mi.returnType ? ':' + mi.returnType.getName() : ''; + if (true) { + var className; + var prefix = ''; + if (trait.holder instanceof ClassInfo) { + className = trait.holder.instanceInfo.name; + if (className.namespaces[0].uri) { + prefix += className.namespaces[0].uri + '::'; + } + prefix += className.getName(); + prefix += '$/'; + } else if (trait.holder instanceof InstanceInfo) { + className = trait.holder.name; + if (className.namespaces[0].uri) { + prefix += className.namespaces[0].uri + '::'; + } + prefix += className.getName(); + prefix += '/'; + } else { + prefix = 'global/'; + } + var getSet = trait.isGetter() ? 'get ' : trait.isSetter() ? 'set ' : ''; + if (!mi.isNative()) { + } + } + if (mi.isNative()) { + writer.writeLn(str + ';'); + } else { + if (inInterfaceNamespace) { + writer.writeLn(str + ';'); + } else { + writer.writeLn(str + ' { notImplemented("' + trait.name.getName() + '"); }'); + } + } + } else if (trait.isClass()) { + var className = trait.classInfo.instanceInfo.name; + writer.enter('package ' + className.namespaces[0].uri + ' {\n'); + tracer.traceMetadata(trait.metadata); + tracer.traceClass(trait.classInfo); + writer.leave('\n}'); + tracer.traceClassStub(trait); + } else { + notImplemented(); + } + }); + }, + traceClassStub2: function traceClassStub(trait) { + var writer = this.writer; + var ci = trait.classInfo; + var ii = ci.instanceInfo; + var name = ii.name.getName(); + var native = trait.metadata ? trait.metadata.native : null; + if (!native) { + return false; + } + writer.writeLn('Cut and paste the following into `native.js\' and edit accordingly'); + writer.writeLn('8< --------------------------------------------------------------'); + writer.enter('natives.' + native.cls + ' = function ' + native.cls + '(runtime, scope, instanceConstructor, baseClass) {'); + writer.writeLn('var c = new Class("' + name + '", instanceConstructor, ApplicationDomain.passthroughCallable(instanceConstructor));'); + writer.writeLn('c.extend(baseClass);\n'); + function traceTraits(traits, isStatic) { + var nativeMethodTraits = []; + traits.forEach(function (trait, i) { + if (trait.isMethod() || trait.isGetter() || trait.isSetter()) { + if (trait.methodInfo.isNative()) { + nativeMethodTraits.push(trait); + } + } + }); + nativeMethodTraits.forEach(function (trait, i) { + var mi = trait.methodInfo; + var traitName = trait.name.getName(); + writer.writeLn('// ' + traitName + ' :: ' + (mi.parameters.length ? getSignature(mi) : 'void') + ' -> ' + (mi.returnType ? mi.returnType.getName() : 'any')); + var prop; + if (trait.isGetter()) { + prop = '"get ' + traitName + '"'; + } else if (trait.isSetter()) { + prop = '"set ' + traitName + '"'; + } else { + prop = traitName; + } + writer.enter(prop + ': function ' + traitName + '(' + getSignature(mi, true) + ') {'); + writer.writeLn(' notImplemented("' + name + '.' + traitName + '");'); + writer.leave('}' + (i === nativeMethodTraits.length - 1 ? '' : ',\n')); + }); + } + writer.enter('c.nativeStatics = {'); + traceTraits(ci.traits, true); + writer.leave('};\n'); + writer.enter('c.nativeMethods = {'); + traceTraits(ii.traits); + writer.leave('};\n'); + writer.writeLn('return c;'); + writer.leave('};'); + writer.writeLn('-------------------------------------------------------------- >8'); + return true; + }, + traceClassStub: function traceClassStub(trait) { + var writer = this.writer; + var ci = trait.classInfo; + var ii = ci.instanceInfo; + var className = ii.name.getName(); + var native = trait.metadata ? trait.metadata.native : null; + writer.writeLn('Cut and paste the following glue and edit accordingly.'); + writer.writeLn('Class ' + ii); + writer.writeLn('8< --------------------------------------------------------------'); + var uri = ii.name.namespaces[0].uri; + writer.enter('var ' + className + 'Definition = (function () {'); + function maxTraitNameLength(traits) { + var length = 0; + traits.forEach(function (t) { + length = Math.max(t.name.name.length, length); + }); + return length; + } + function quote(s) { + return '\'' + s + '\''; + } + function filterTraits(traits, isNative) { + function isMethod(x) { + return x.isMethod() || x.isGetter() || x.isSetter(); + } + return { + properties: traits.filter(function (trait) { + return !isNative && !isMethod(trait); + }), + methods: traits.filter(function (trait) { + return isMethod(trait) && isNative === trait.methodInfo.isNative(); + }) + }; + } + function writeTraits(traits, isNative, isStatic) { + traits = filterTraits(traits, isNative); + var methods = []; + var gettersAndSetters = createEmptyObject(); + traits.methods.forEach(function (trait, i) { + var traitName = trait.name.getName(); + if (trait.isGetter() || trait.isSetter()) { + if (!gettersAndSetters[traitName]) { + gettersAndSetters[traitName] = []; + } + gettersAndSetters[traitName].push(trait); + } else { + methods.push(trait); + } + }); + function writeTrait(trait, writeComma) { + var mi = trait.methodInfo; + var traitName = trait.name.getName(); + var signature = '// (' + (mi.parameters.length ? getSignature(mi) : 'void') + ') -> ' + (mi.returnType ? mi.returnType.getName() : 'any'); + var propertyName = traitName; + if (trait.isGetter()) { + propertyName = 'get'; + } else if (trait.isSetter()) { + propertyName = 'set'; + } + writer.enter(propertyName + ': function ' + traitName + '(' + getSignature(mi, true) + ') { ' + signature); + writer.writeLn('notImplemented("' + className + '.' + traitName + '");'); + if (!isStatic) { + if (trait.isGetter()) { + writer.writeLn('return this._' + traitName + ';'); + } else if (trait.isSetter()) { + writer.writeLn('this._' + traitName + ' = ' + mi.parameters[0].name + ';'); + } + } + writer.leave('}' + (writeComma ? ',' : '')); + } + for (var i = 0; i < methods.length; i++) { + writeTrait(methods[i], i < methods.length - 1); + } + var keyValues = toKeyValueArray(gettersAndSetters); + for (var j = 0; j < keyValues.length; j++) { + writer.enter(keyValues[j][0] + ': {'); + var list = keyValues[j][1]; + for (var i = 0; i < list.length; i++) { + writeTrait(list[i], i < list.length - 1); + } + writer.leave('}' + (j < keyValues.length - 1 ? ',' : '')); + } + traits.properties.forEach(function (trait, i) { + var traitName = trait.name.getName(); + var last = i === traits.properties.length - 1; + if (trait.name.getNamespace().isPublic()) { + writer.writeLn(traitName + ': ' + quote('public ' + trait.name.name) + (last ? '' : ',')); + } + }); + } + writer.enter('return {'); + writer.writeLn('// (' + getSignature(ii.init, false) + ')'); + writer.writeLn('__class__: "' + uri + '.' + className + '",'); + writer.enter('initialize: function () {'); + writer.leave('},'); + writer.enter('__glue__: {'); + writer.enter('native: {'); + writer.enter('static: {'); + writeTraits(ci.traits, true, true); + writer.leave('},'); + writer.enter('instance: {'); + writeTraits(ii.traits, true); + writer.leave('}'); + writer.leave('},'); + writer.enter('script: {'); + writer.writeLn('instance: Glue.ALL'); + writer.leave('}'); + writer.leave('}'); + writer.leave('};'); + writer.leave('}).call(this);'); + writer.writeLn('-------------------------------------------------------------- >8'); + return true; + }, + traceClass: function traceClass(ci) { + var writer = this.writer; + var ii = ci.instanceInfo; + var name = ii.name; + var str = Multiname.getAccessModifier(name); + if (ii.isFinal()) { + str += ' final'; + } + if (!ii.isSealed()) { + str += ' dynamic'; + } + str += ii.isInterface() ? ' interface ' : ' class '; + str += name.getName(); + if (ii.superName && ii.superName.getName() !== 'Object') { + str += ' extends ' + ii.superName.getName(); + } + if (ii.interfaces.length) { + str += ' implements ' + ii.interfaces.map(function (x) { + return x.getName(); + }).join(', '); + } + writer.enter(str + ' {'); + if (!ii.isInterface()) { + writer.writeLn('public function ' + name.getName() + '(' + getSignature(ii.init) + ') {}'); + } + var interfaceNamespace; + if (ii.isInterface()) { + interfaceNamespace = name.namespaces[0].uri + ':' + name.name; + } + this.traceTraits(ci.traits, true, interfaceNamespace); + this.traceTraits(ii.traits, false, interfaceNamespace); + writer.leave('}'); + }, + traceMetadata: function traceMetadata(metadata) { + var writer = this.writer; + for (var key in metadata) { + if (metadata.hasOwnProperty(key)) { + if (key.indexOf('__') === 0) { + continue; + } + writer.writeLn('[' + key + '(' + metadata[key].value.map(function (m) { + var str = m.key ? m.key + '=' : ''; + return str + '"' + m.value + '"'; + }).join(', ') + ')]'); + } + } + } + }; + return SourceTracer; + }(); +function traceSource(writer, abc) { + var tracer = new SourceTracer(writer); + abc.scripts.forEach(function (script) { + tracer.traceTraits(script.traits); + }); +} +function traceStatistics(writer, abc) { + var libraryClassCounter = new Shumway.Metrics.Counter(true); + var librarySuperClassCounter = new Shumway.Metrics.Counter(true); + var libraryMethodCounter = new Shumway.Metrics.Counter(true); + var libraryProperties = new Shumway.Metrics.Counter(true); + var definedClasses = {}; + var definedMethods = {}; + var definedProperties = {}; + abc.classes.forEach(function (x) { + var className = x.instanceInfo.name.name; + definedClasses[className] = true; + }); + abc.scripts.forEach(function (s) { + s.traits.forEach(function (t) { + if (t.isClass()) { + var superClassName = t.classInfo.instanceInfo.superName ? t.classInfo.instanceInfo.superName.name : '?'; + if (!(superClassName in definedClasses)) { + librarySuperClassCounter.count(superClassName); + } + t.classInfo.traits.forEach(function (st) { + if (st.isMethod()) { + definedMethods[st.name.name] = true; + } else { + definedProperties[st.name.name] = true; + } + }); + t.classInfo.instanceInfo.traits.forEach(function (it) { + if (it.isMethod() && !(it.attributes & ATTR_Override)) { + definedMethods[it.name.name] = true; + } else { + definedProperties[it.name.name] = true; + } + }); + } + }); + }); + var opCounter = new Shumway.Metrics.Counter(true); + abc.methods.forEach(function (m) { + if (!m.code) { + return; + } + function readOperand(operand) { + var value = 0; + switch (operand.size) { + case 's08': + value = code.readS8(); + break; + case 'u08': + value = code.readU8(); + break; + case 's16': + value = code.readS16(); + break; + case 's24': + value = code.readS24(); + break; + case 'u30': + value = code.readU30(); + break; + case 'u32': + value = code.readU32(); + break; + default: + true; + break; + } + var description = ''; + switch (operand.type) { + case '': + break; + case 'I': + description = abc.constantPool.ints[value]; + break; + case 'U': + description = abc.constantPool.uints[value]; + break; + case 'D': + description = abc.constantPool.doubles[value]; + break; + case 'S': + description = abc.constantPool.strings[value]; + break; + case 'N': + description = abc.constantPool.namespaces[value]; + break; + case 'CI': + description = abc.classes[value]; + break; + case 'M': + description = abc.constantPool.multinames[value]; + break; + default: + description = '?'; + break; + } + return description; + } + var code = new AbcStream(m.code); + while (code.remaining() > 0) { + var bc = code.readU8(); + var op = opcodeTable[bc]; + var operands = null; + if (op) { + opCounter.count(op.name); + if (op.operands) { + operands = op.operands.map(readOperand); + } + switch (bc) { + case OP_call: + case OP_callmethod: + continue; + case OP_callproperty: + case OP_callproplex: + case OP_callpropvoid: + case OP_callstatic: + case OP_callsuper: + case OP_callsupervoid: + if (operands[0] && !(operands[0].name in definedMethods)) { + libraryMethodCounter.count(operands[0].name); + } + break; + case OP_constructprop: + if (operands[0] && !(operands[0].name in definedClasses)) { + libraryClassCounter.count(operands[0].name); + } + break; + case OP_getproperty: + case OP_setproperty: + if (operands[0] && !(operands[0].name in definedProperties)) { + libraryProperties.count(operands[0].name); + } + break; + } + } + } + }); + writer.writeLn(JSON.stringify({ + definedClasses: definedClasses, + definedMethods: definedMethods, + definedProperties: definedProperties, + libraryClasses: libraryClassCounter.counts, + librarySuperClasses: librarySuperClassCounter.counts, + libraryMethods: libraryMethodCounter.counts, + libraryProperties: libraryProperties.counts, + operations: opCounter.counts + }, null, 2)); +} +var Shumway; +(function (Shumway) { + (function (AVM2) { + var OP = Shumway.AVM2.ABC.OP; + var Scope = Shumway.AVM2.Runtime.Scope; + var asCoerceByMultiname = Shumway.AVM2.Runtime.asCoerceByMultiname; + var asGetSlot = Shumway.AVM2.Runtime.asGetSlot; + var asSetSlot = Shumway.AVM2.Runtime.asSetSlot; + var asHasNext2 = Shumway.AVM2.Runtime.asHasNext2; + var asCoerce = Shumway.AVM2.Runtime.asCoerce; + var asCoerceString = Shumway.AVM2.Runtime.asCoerceString; + var asAsType = Shumway.AVM2.Runtime.asAsType; + var asTypeOf = Shumway.AVM2.Runtime.asTypeOf; + var asIsInstanceOf = Shumway.AVM2.Runtime.asIsInstanceOf; + var asIsType = Shumway.AVM2.Runtime.asIsType; + var applyType = Shumway.AVM2.Runtime.applyType; + var createFunction = Shumway.AVM2.Runtime.createFunction; + var createClass = Shumway.AVM2.Runtime.createClass; + var getDescendants = Shumway.AVM2.Runtime.getDescendants; + var checkFilter = Shumway.AVM2.Runtime.checkFilter; + var asAdd = Shumway.AVM2.Runtime.asAdd; + var translateError = Shumway.AVM2.Runtime.translateError; + var asCreateActivation = Shumway.AVM2.Runtime.asCreateActivation; + var sliceArguments = Shumway.AVM2.Runtime.sliceArguments; + var boxValue = Shumway.ObjectUtilities.boxValue; + var popManyInto = Shumway.ArrayUtilities.popManyInto; + var construct = Shumway.AVM2.Runtime.construct; + var Multiname = Shumway.AVM2.ABC.Multiname; + var ScopeStack = function () { + function ScopeStack(parent) { + this.parent = parent; + this.stack = []; + this.isWith = []; + } + ScopeStack.prototype.push = function (object, isWith) { + this.stack.push(object); + this.isWith.push(!(!isWith)); + }; + ScopeStack.prototype.get = function (index) { + return this.stack[index]; + }; + ScopeStack.prototype.clear = function () { + this.stack.length = 0; + this.isWith.length = 0; + }; + ScopeStack.prototype.pop = function () { + this.isWith.pop(); + this.stack.pop(); + }; + ScopeStack.prototype.topScope = function () { + if (!this.scopes) { + this.scopes = []; + } + var parent = this.parent; + for (var i = 0; i < this.stack.length; i++) { + var object = this.stack[i], isWith = this.isWith[i], scope = this.scopes[i]; + if (!scope || scope.parent !== parent || scope.object !== object || scope.isWith !== isWith) { + scope = this.scopes[i] = new Scope(parent, object, isWith); + } + parent = scope; + } + return parent; + }; + return ScopeStack; + }(); + function popNameInto(stack, mn, out) { + out.flags = mn.flags; + if (mn.isRuntimeName()) { + out.name = stack.pop(); + } else { + out.name = mn.name; + } + if (mn.isRuntimeNamespace()) { + out.namespaces = [ + stack.pop() + ]; + } else { + out.namespaces = mn.namespaces; + } + } + var Interpreter = function () { + function Interpreter() { + } + Interpreter.interpretMethod = function ($this, method, savedScope, methodArgs) { + true; + Counter.count('Interpret Method'); + var abc = method.abc; + var ints = abc.constantPool.ints; + var uints = abc.constantPool.uints; + var doubles = abc.constantPool.doubles; + var strings = abc.constantPool.strings; + var methods = abc.methods; + var multinames = abc.constantPool.multinames; + var domain = abc.applicationDomain; + var exceptions = method.exceptions; + var locals = [ + $this + ]; + var stack = [], scopeStack = new ScopeStack(savedScope); + var parameterCount = method.parameters.length; + var argCount = methodArgs.length; + var value; + for (var i = 0; i < parameterCount; i++) { + var parameter = method.parameters[i]; + if (i < argCount) { + value = methodArgs[i]; + } else { + value = parameter.value; + } + if (parameter.type && !parameter.type.isAnyName()) { + value = asCoerceByMultiname(domain, parameter.type, value); + } + locals.push(value); + } + if (method.needsRest()) { + locals.push(sliceArguments(methodArgs, parameterCount)); + } else if (method.needsArguments()) { + locals.push(sliceArguments(methodArgs, 0)); + } + var bytecodes = method.analysis.bytecodes; + var object, index, multiname, result, a, b, args = [], mn = Multiname.TEMPORARY; + interpretLabel: + for (var pc = 0, end = bytecodes.length; pc < end;) { + try { + var bc = bytecodes[pc]; + var op = bc.op; + switch (op | 0) { + case 3: + throw stack.pop(); + case 4: + popNameInto(stack, multinames[bc.index], mn); + stack.push(stack.pop().asGetSuper(savedScope, mn.namespaces, mn.name, mn.flags)); + break; + case 5: + value = stack.pop(); + popNameInto(stack, multinames[bc.index], mn); + stack.pop().asSetSuper(savedScope, mn.namespaces, mn.name, mn.flags, value); + break; + case 8: + locals[bc.index] = undefined; + break; + case 12: + b = stack.pop(); + a = stack.pop(); + pc = !(a < b) ? bc.offset : pc + 1; + continue; + case 24: + b = stack.pop(); + a = stack.pop(); + pc = a >= b ? bc.offset : pc + 1; + continue; + case 13: + b = stack.pop(); + a = stack.pop(); + pc = !(a <= b) ? bc.offset : pc + 1; + continue; + case 23: + b = stack.pop(); + a = stack.pop(); + pc = a > b ? bc.offset : pc + 1; + continue; + case 14: + b = stack.pop(); + a = stack.pop(); + pc = !(a > b) ? bc.offset : pc + 1; + continue; + case 22: + b = stack.pop(); + a = stack.pop(); + pc = a <= b ? bc.offset : pc + 1; + continue; + case 15: + b = stack.pop(); + a = stack.pop(); + pc = !(a >= b) ? bc.offset : pc + 1; + continue; + case 21: + b = stack.pop(); + a = stack.pop(); + pc = a < b ? bc.offset : pc + 1; + continue; + case 16: + pc = bc.offset; + continue; + case 17: + pc = !(!stack.pop()) ? bc.offset : pc + 1; + continue; + case 18: + pc = !stack.pop() ? bc.offset : pc + 1; + continue; + case 19: + b = stack.pop(); + a = stack.pop(); + pc = a == b ? bc.offset : pc + 1; + continue; + case 20: + b = stack.pop(); + a = stack.pop(); + pc = a != b ? bc.offset : pc + 1; + continue; + case 25: + b = stack.pop(); + a = stack.pop(); + pc = a === b ? bc.offset : pc + 1; + continue; + case 26: + b = stack.pop(); + a = stack.pop(); + pc = a !== b ? bc.offset : pc + 1; + continue; + case 27: + index = stack.pop(); + if (index < 0 || index >= bc.offsets.length) { + index = bc.offsets.length - 1; + } + pc = bc.offsets[index]; + continue; + case 28: + scopeStack.push(boxValue(stack.pop()), true); + break; + case 29: + scopeStack.pop(); + break; + case 30: + index = stack.pop(); + stack[stack.length - 1] = boxValue(stack[stack.length - 1]).asNextName(index); + break; + case 35: + index = stack.pop(); + stack[stack.length - 1] = boxValue(stack[stack.length - 1]).asNextValue(index); + break; + case 50: + result = asHasNext2(locals[bc.object], locals[bc.index]); + locals[bc.object] = result.object; + locals[bc.index] = result.index; + stack.push(!(!result.index)); + break; + case 32: + stack.push(null); + break; + case 33: + stack.push(undefined); + break; + case 36: + case 37: + stack.push(bc.value); + break; + case 44: + stack.push(strings[bc.index]); + break; + case 45: + stack.push(ints[bc.index]); + break; + case 46: + stack.push(uints[bc.index]); + break; + case 47: + stack.push(doubles[bc.index]); + break; + case 38: + stack.push(true); + break; + case 39: + stack.push(false); + break; + case 40: + stack.push(NaN); + break; + case 41: + stack.pop(); + break; + case 42: + stack.push(stack[stack.length - 1]); + break; + case 43: + object = stack[stack.length - 1]; + stack[stack.length - 1] = stack[stack.length - 2]; + stack[stack.length - 2] = object; + break; + case 48: + scopeStack.push(boxValue(stack.pop()), false); + break; + case 64: + stack.push(createFunction(methods[bc.index], scopeStack.topScope(), true)); + break; + case 65: + popManyInto(stack, bc.argCount, args); + object = stack.pop(); + stack[stack.length - 1] = stack[stack.length - 1].apply(object, args); + break; + case 66: + popManyInto(stack, bc.argCount, args); + stack[stack.length - 1] = construct(stack[stack.length - 1], args); + break; + case 71: + return; + case 72: + if (method.returnType) { + return asCoerceByMultiname(domain, method.returnType, stack.pop()); + } + return stack.pop(); + case 73: + popManyInto(stack, bc.argCount, args); + object = stack.pop(); + savedScope.object.baseClass.instanceConstructorNoInitialize.apply(object, args); + break; + case 74: + popManyInto(stack, bc.argCount, args); + popNameInto(stack, multinames[bc.index], mn); + object = boxValue(stack[stack.length - 1]); + object = object.asConstructProperty(mn.namespaces, mn.name, mn.flags, args); + stack[stack.length - 1] = object; + break; + case 75: + Shumway.Debug.notImplemented('OP.callsuperid'); + break; + case 76: + case 70: + case 79: + popManyInto(stack, bc.argCount, args); + popNameInto(stack, multinames[bc.index], mn); + result = boxValue(stack.pop()).asCallProperty(mn.namespaces, mn.name, mn.flags, op === 76, args); + if (op !== 79) { + stack.push(result); + } + break; + case 69: + case 78: + popManyInto(stack, bc.argCount, args); + popNameInto(stack, multinames[bc.index], mn); + result = stack.pop().asCallSuper(savedScope, mn.namespaces, mn.name, mn.flags, args); + if (op !== 78) { + stack.push(result); + } + break; + case 83: + popManyInto(stack, bc.argCount, args); + stack[stack.length - 1] = applyType(domain, stack[stack.length - 1], args); + break; + case 85: + object = {}; + for (var i = 0; i < bc.argCount; i++) { + value = stack.pop(); + object[Multiname.getPublicQualifiedName(stack.pop())] = value; + } + stack.push(object); + break; + case 86: + object = []; + popManyInto(stack, bc.argCount, args); + object.push.apply(object, args); + stack.push(object); + break; + case 87: + true; + stack.push(asCreateActivation(method)); + break; + case 88: + stack[stack.length - 1] = createClass(abc.classes[bc.index], stack[stack.length - 1], scopeStack.topScope()); + break; + case 89: + popNameInto(stack, multinames[bc.index], mn); + stack.push(getDescendants(stack.pop(), mn)); + break; + case 90: + true; + stack.push(exceptions[bc.index].scopeObject); + break; + case 94: + case 93: + popNameInto(stack, multinames[bc.index], mn); + stack.push(scopeStack.topScope().findScopeProperty(mn.namespaces, mn.name, mn.flags, domain, op === 93, false)); + break; + case 96: + multiname = multinames[bc.index]; + object = scopeStack.topScope().findScopeProperty(multiname.namespaces, multiname.name, multiname.flags, domain, true, false); + stack.push(object.asGetProperty(multiname.namespaces, multiname.name, multiname.flags)); + break; + case 104: + case 97: + value = stack.pop(); + popNameInto(stack, multinames[bc.index], mn); + boxValue(stack.pop()).asSetProperty(mn.namespaces, mn.name, mn.flags, value); + break; + case 98: + stack.push(locals[bc.index]); + break; + case 99: + locals[bc.index] = stack.pop(); + break; + case 100: + stack.push(savedScope.global.object); + break; + case 101: + stack.push(scopeStack.get(bc.index)); + break; + case 102: + popNameInto(stack, multinames[bc.index], mn); + stack[stack.length - 1] = boxValue(stack[stack.length - 1]).asGetProperty(mn.namespaces, mn.name, mn.flags); + break; + case 106: + popNameInto(stack, multinames[bc.index], mn); + stack[stack.length - 1] = boxValue(stack[stack.length - 1]).asDeleteProperty(mn.namespaces, mn.name, mn.flags); + break; + case 108: + stack[stack.length - 1] = asGetSlot(stack[stack.length - 1], bc.index); + break; + case 109: + value = stack.pop(); + object = stack.pop(); + asSetSlot(object, bc.index, value); + break; + case 112: + stack[stack.length - 1] = stack[stack.length - 1] + ''; + break; + case 131: + case 115: + stack[stack.length - 1] |= 0; + break; + case 136: + case 116: + stack[stack.length - 1] >>>= 0; + break; + case 132: + case 117: + stack[stack.length - 1] = +stack[stack.length - 1]; + break; + case 129: + case 118: + stack[stack.length - 1] = !(!stack[stack.length - 1]); + break; + case 120: + stack[stack.length - 1] = checkFilter(stack[stack.length - 1]); + break; + case 128: + stack[stack.length - 1] = asCoerce(domain.getType(multinames[bc.index]), stack[stack.length - 1]); + break; + case 130: + break; + case 133: + stack[stack.length - 1] = asCoerceString(stack[stack.length - 1]); + break; + case 135: + stack[stack.length - 2] = asAsType(stack.pop(), stack[stack.length - 1]); + break; + case 137: + object = stack[stack.length - 1]; + stack[stack.length - 1] = object == undefined ? null : object; + break; + case 144: + stack[stack.length - 1] = -stack[stack.length - 1]; + break; + case 145: + ++stack[stack.length - 1]; + break; + case 146: + ++locals[bc.index]; + break; + case 147: + --stack[stack.length - 1]; + break; + case 148: + --locals[bc.index]; + break; + case 149: + stack[stack.length - 1] = asTypeOf(stack[stack.length - 1]); + break; + case 150: + stack[stack.length - 1] = !stack[stack.length - 1]; + break; + case 151: + stack[stack.length - 1] = ~stack[stack.length - 1]; + break; + case 160: + stack[stack.length - 2] = asAdd(stack[stack.length - 2], stack.pop()); + break; + case 161: + stack[stack.length - 2] -= stack.pop(); + break; + case 162: + stack[stack.length - 2] *= stack.pop(); + break; + case 163: + stack[stack.length - 2] /= stack.pop(); + break; + case 164: + stack[stack.length - 2] %= stack.pop(); + break; + case 165: + stack[stack.length - 2] <<= stack.pop(); + break; + case 166: + stack[stack.length - 2] >>= stack.pop(); + break; + case 167: + stack[stack.length - 2] >>>= stack.pop(); + break; + case 168: + stack[stack.length - 2] &= stack.pop(); + break; + case 169: + stack[stack.length - 2] |= stack.pop(); + break; + case 170: + stack[stack.length - 2] ^= stack.pop(); + break; + case 171: + stack[stack.length - 2] = stack[stack.length - 2] == stack.pop(); + break; + case 172: + stack[stack.length - 2] = stack[stack.length - 2] === stack.pop(); + break; + case 173: + stack[stack.length - 2] = stack[stack.length - 2] < stack.pop(); + break; + case 174: + stack[stack.length - 2] = stack[stack.length - 2] <= stack.pop(); + break; + case 175: + stack[stack.length - 2] = stack[stack.length - 2] > stack.pop(); + break; + case 176: + stack[stack.length - 2] = stack[stack.length - 2] >= stack.pop(); + break; + case 177: + stack[stack.length - 2] = asIsInstanceOf(stack.pop(), stack[stack.length - 1]); + break; + case 178: + stack[stack.length - 1] = asIsType(domain.getType(multinames[bc.index]), stack[stack.length - 1]); + break; + case 179: + stack[stack.length - 2] = asIsType(stack.pop(), stack[stack.length - 1]); + break; + case 180: + stack[stack.length - 2] = boxValue(stack.pop()).asHasProperty(null, stack[stack.length - 1]); + break; + case 192: + stack[stack.length - 1] = (stack[stack.length - 1] | 0) + 1; + break; + case 193: + stack[stack.length - 1] = (stack[stack.length - 1] | 0) - 1; + break; + case 194: + locals[bc.index] = (locals[bc.index] | 0) + 1; + break; + case 195: + locals[bc.index] = (locals[bc.index] | 0) - 1; + break; + case 196: + stack[stack.length - 1] = ~stack[stack.length - 1]; + break; + case 197: + stack[stack.length - 2] = stack[stack.length - 2] + stack.pop() | 0; + break; + case 198: + stack[stack.length - 2] = stack[stack.length - 2] - stack.pop() | 0; + break; + case 199: + stack[stack.length - 2] = stack[stack.length - 2] * stack.pop() | 0; + break; + case 208: + case 209: + case 210: + case 211: + stack.push(locals[op - 208]); + break; + case 212: + case 213: + case 214: + case 215: + locals[op - 212] = stack.pop(); + break; + case 239: + case 240: + case 241: + break; + default: + Shumway.Debug.notImplemented(Shumway.AVM2.opcodeName(op)); + } + pc++; + } catch (e) { + if (exceptions.length < 1) { + throw e; + } + e = translateError(domain, e); + for (var i = 0, j = exceptions.length; i < j; i++) { + var handler = exceptions[i]; + if (pc >= handler.start && pc <= handler.end && (!handler.typeName || domain.getType(handler.typeName).isInstance(e))) { + stack.length = 0; + stack.push(e); + scopeStack.clear(); + pc = handler.offset; + continue interpretLabel; + } + } + throw e; + } + } + }; + return Interpreter; + }(); + AVM2.Interpreter = Interpreter; + }(Shumway.AVM2 || (Shumway.AVM2 = {}))); + var AVM2 = Shumway.AVM2; +}(Shumway || (Shumway = {}))); +Shumway.AVM2.Runtime.enableVerifier.value = true; +release = true; +var avm2Root = SHUMWAY_ROOT + 'avm2/'; +var builtinPath = avm2Root + 'generated/builtin/builtin.abc'; +var avm1Path = avm2Root + 'generated/avm1lib/avm1lib.abc'; +var BinaryFileReader = function binaryFileReader() { + function constructor(url, responseType) { + this.url = url; + this.responseType = responseType || 'arraybuffer'; + } + constructor.prototype = { + readAll: function (progress, complete) { + var url = this.url; + var xhr = new XMLHttpRequest(); + var async = true; + xhr.open('GET', this.url, async); + xhr.responseType = this.responseType; + if (progress) { + xhr.onprogress = function (event) { + progress(xhr.response, event.loaded, event.total); + }; + } + xhr.onreadystatechange = function (event) { + if (xhr.readyState === 4) { + if (xhr.status !== 200 && xhr.status !== 0) { + unexpected('Path: ' + url + ' not found.'); + complete(null, xhr.statusText); + return; + } + complete(xhr.response); + } + }; + xhr.send(null); + }, + readAsync: function (ondata, onerror, onopen, oncomplete, onhttpstatus) { + var xhr = new XMLHttpRequest({ + mozSystem: true + }); + var url = this.url; + xhr.open(this.method || 'GET', url, true); + var isNotProgressive; + try { + xhr.responseType = 'moz-chunked-arraybuffer'; + isNotProgressive = xhr.responseType !== 'moz-chunked-arraybuffer'; + } catch (e) { + isNotProgressive = true; + } + if (isNotProgressive) { + xhr.responseType = 'arraybuffer'; + } + xhr.onprogress = function (e) { + if (isNotProgressive) + return; + ondata(new Uint8Array(xhr.response), { + loaded: e.loaded, + total: e.total + }); + }; + xhr.onreadystatechange = function (event) { + if (xhr.readyState === 2 && onhttpstatus) { + onhttpstatus(url, xhr.status, xhr.getAllResponseHeaders()); + } + if (xhr.readyState === 4) { + if (xhr.status !== 200 && xhr.status !== 0) { + onerror(xhr.statusText); + } + if (isNotProgressive) { + var buffer = xhr.response; + ondata(new Uint8Array(buffer), { + loaded: buffer.byteLength, + total: buffer.byteLength + }); + } + if (oncomplete) { + oncomplete(); + } + } else if (xhr.readyState === 2 && onopen) { + onopen(); + } + }; + xhr.send(null); + } + }; + return constructor; + }(); +var libraryAbcs; +function grabAbc(abcName) { + var entry = libraryScripts[abcName]; + if (entry) { + var offset = entry.offset; + var length = entry.length; + return new AbcFile(new Uint8Array(libraryAbcs, offset, length), abcName); + } + return null; +} +var avm2; +function createAVM2(builtinPath, libraryPath, avm1Path, sysMode, appMode, next) { + avm2 = new AVM2(sysMode, appMode, loadAVM1); + var builtinAbc, avm1Abc; + AVM2.loadPlayerglobal(libraryPath.abcs, libraryPath.catalog).then(function () { + new BinaryFileReader(builtinPath).readAll(null, function (buffer) { + builtinAbc = new AbcFile(new Uint8Array(buffer), 'builtin.abc'); + executeAbc(); + }); + }); + function loadAVM1(next) { + new BinaryFileReader(avm1Path).readAll(null, function (buffer) { + avm1Abc = new AbcFile(new Uint8Array(buffer), 'avm1.abc'); + ; + avm2.systemDomain.executeAbc(avm1Abc); + next(); + }); + } + function executeAbc() { + avm2.builtinsLoaded = false; + avm2.systemDomain.onMessage.register('classCreated', Stubs.onClassCreated); + avm2.systemDomain.executeAbc(builtinAbc); + avm2.builtinsLoaded = true; + console.info(JSON.stringify(Counter.toJSON())); + console.timeEnd('Load AVM2'); + next(avm2); + } +} +{ + var MAX_SNAP_DRAW_SCALE_TO_CACHE = 8; + var CACHE_SNAP_DRAW_AFTER = 3; + var BitmapDefinition = function () { + function setBitmapData(value) { + if (this._bitmapData) { + this._bitmapData._changeNotificationTarget = null; + } + this._bitmapData = value; + if (this._bitmapData) { + this._bitmapData._changeNotificationTarget = this; + } + if (value) { + var canvas = value._drawable; + this._bbox = { + xMin: 0, + yMin: 0, + xMax: canvas.width * 20, + yMax: canvas.height * 20 + }; + } else { + this._bbox = { + xMin: 0, + yMin: 0, + xMax: 0, + yMax: 0 + }; + } + this._drawableChanged(); + this._invalidateBounds(); + this._invalidateTransform(); + } + return { + __class__: 'flash.display.Bitmap', + draw: function (ctx, ratio, colorTransform) { + if (!this._bitmapData) { + return; + } + var scaledImage; + ctx.save(); + if (this._pixelSnapping === 'auto' || this._pixelSnapping === 'always') { + var transform = this._getConcatenatedTransform(null, true); + var EPSILON = 0.001; + var aInt = Math.abs(Math.round(transform.a)); + var dInt = Math.abs(Math.round(transform.d)); + var snapPixels; + if (aInt >= 1 && aInt <= MAX_SNAP_DRAW_SCALE_TO_CACHE && dInt >= 1 && dInt <= MAX_SNAP_DRAW_SCALE_TO_CACHE && Math.abs(Math.abs(transform.a) / aInt - 1) <= EPSILON && Math.abs(Math.abs(transform.d) / dInt - 1) <= EPSILON && Math.abs(transform.b) <= EPSILON && Math.abs(transform.c) <= EPSILON) { + if (aInt === 1 && dInt === 1) { + snapPixels = true; + } else { + var sizeKey = aInt + 'x' + dInt; + if (this._snapImageCache.size !== sizeKey) { + this._snapImageCache.size = sizeKey; + this._snapImageCache.hits = 0; + this._snapImageCache.image = null; + } + if (++this._snapImageCache.hits === CACHE_SNAP_DRAW_AFTER) { + this._cacheSnapImage(sizeKey, aInt, dInt); + } + scaledImage = this._snapImageCache.image; + snapPixels = !(!scaledImage); + } + } else { + snapPixels = false; + } + if (snapPixels) { + ctx.setTransform(transform.a < 0 ? -1 : 1, 0, 0, transform.d < 0 ? -1 : 1, transform.tx / 20 | 0, transform.ty / 20 | 0); + } + } + colorTransform.setAlpha(ctx, true); + ctx.imageSmoothingEnabled = ctx.mozImageSmoothingEnabled = this._smoothing; + ctx.drawImage(scaledImage || this._bitmapData._getDrawable(), 0, 0); + ctx.imageSmoothingEnabled = ctx.mozImageSmoothingEnabled = false; + ctx.restore(); + traceRenderer.value && frameWriter.writeLn('Bitmap.draw() snapping: ' + this._pixelSnapping + ', dimensions: ' + this._bitmapData._drawable.width + ' x ' + this._bitmapData._drawable.height); + }, + _drawableChanged: function () { + this._invalidate(); + this._snapImageCache.image = null; + this._snapImageCache.hints = 0; + }, + _cacheSnapImage: function (sizeKey, xScale, yScale) { + Counter.count('Cache scaled image'); + var original = this._bitmapData._getDrawable(); + var canvas = document.createElement('canvas'); + canvas.width = xScale * original.width; + canvas.height = yScale * original.height; + var ctx = canvas.getContext('2d'); + ctx.imageSmoothingEnabled = ctx.mozImageSmoothingEnabled = this._smoothing; + ctx.drawImage(original, 0, 0, original.width, original.height, 0, 0, canvas.width, canvas.height); + var cache = this._snapImageCache; + var image = document.createElement('img'); + cache._tmp = [ + canvas, + image + ]; + if ('toBlob' in canvas) { + canvas.toBlob(function (blob) { + if (cache.size !== sizeKey) { + return; + } + image.onload = function () { + URL.revokeObjectURL(blob); + if (cache.size === sizeKey) { + cache.image = image; + } + }; + image.src = URL.createObjectURL(blob); + }); + } else { + image.onload = function () { + if (cache.size === sizeKey) { + cache.image = image; + } + }; + image.src = canvas.toDataURL(); + } + }, + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + ctor: function (bitmapData, pixelSnapping, smoothing) { + if (pixelSnapping === 'never' || pixelSnapping === 'always') { + this._pixelSnapping = pixelSnapping; + } else { + this._pixelSnapping = 'auto'; + } + this._smoothing = !(!smoothing); + this._snapImageCache = { + hits: 0, + size: '', + image: null + }; + if (!bitmapData && this.symbol) { + var symbol = this.symbol; + bitmapData = new flash.display.BitmapData(symbol.width, symbol.height, true, 0); + bitmapData._ctx.imageSmoothingEnabled = this._smoothing; + bitmapData._ctx.mozImageSmoothingEnabled = this._smoothing; + bitmapData._ctx.drawImage(symbol.img, 0, 0); + bitmapData._ctx.imageSmoothingEnabled = false; + bitmapData._ctx.mozImageSmoothingEnabled = false; + } + setBitmapData.call(this, bitmapData || null); + }, + pixelSnapping: { + get: function pixelSnapping() { + return this._pixelSnapping; + }, + set: function pixelSnapping(value) { + this._pixelSnapping = value; + } + }, + smoothing: { + get: function smoothing() { + return this._smoothing; + }, + set: function smoothing(value) { + this._smoothing = value; + } + }, + bitmapData: { + get: function bitmapData() { + return this._bitmapData; + }, + set: setBitmapData + } + } + } + } + }; + }.call(this); +} +var CACHE_DRAWABLE_AFTER = 10; +var BitmapDataDefinition = function () { + function replaceRect(ctx, x, y, w, h, alpha) { + if (alpha < 255) { + ctx.clearRect(x, y, w, h); + } + if (alpha > 0) { + ctx.fillRect(x, y, w, h); + } + } + var def = { + __class__: 'flash.display.BitmapData', + initialize: function () { + this._changeNotificationTarget = null; + this._locked = false; + this._requested = 0; + this._cache = null; + if (this.symbol) { + this._img = this.symbol.img; + this._skipCopyToCanvas = this.symbol.skipCopyToCanvas; + } + }, + _checkCanvas: function () { + if (this._drawable === null) + throw ArgumentError(); + }, + ctor: function (width, height, transparent, backgroundColor) { + if (this._img) { + width = this._img.naturalWidth || this._img.width; + height = this._img.naturalHeight || this._img.height; + } else if (isNaN(width + height) || width <= 0 || height <= 0) { + throwError('ArgumentError', Errors.ArgumentError); + } + this._transparent = transparent === undefined ? true : !(!transparent); + this._backgroundColor = backgroundColor === undefined ? 4294967295 : backgroundColor; + if (!this._transparent) { + this._backgroundColor |= 4278190080; + } + if (this._skipCopyToCanvas) { + this._drawable = this._img; + } else { + var canvas = document.createElement('canvas'); + this._ctx = canvas.getContext('2d'); + canvas.width = width | 0; + canvas.height = height | 0; + this._drawable = canvas; + if (!this._transparent || !this._img && this._backgroundColor) { + this.fillRect(new flash.geom.Rectangle(0, 0, width | 0, height | 0), this._backgroundColor); + } + if (this._img) { + this._ctx.drawImage(this._img, 0, 0); + } + } + }, + dispose: function () { + this._ctx = null; + this._drawable.width = 0; + this._drawable.height = 0; + this._drawable = null; + }, + draw: function (source, matrix, colorTransform, blendMode, clipRect, smoothing) { + this._checkCanvas(); + var ctx = this._ctx; + ctx.save(); + ctx.beginPath(); + if (clipRect && clipRect.width > 0 && clipRect.height > 0) { + ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); + ctx.clip(); + } + if (matrix) { + ctx.transform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty); + } + ctx.globalCompositeOperation = getBlendModeName(blendMode); + ctx.imageSmoothingEnabled = ctx.mozImageSmoothingEnabled = !(!smoothing); + if (flash.display.BitmapData.class.isInstanceOf(source)) { + ctx.drawImage(source._drawable, 0, 0); + } else { + new RenderVisitor(source, ctx, null, true).startFragment(matrix); + } + ctx.imageSmoothingEnabled = ctx.mozImageSmoothingEnabled = false; + ctx.restore(); + this._invalidate(); + }, + fillRect: function (rect, color) { + this._checkCanvas(); + if (!this._transparent) { + color |= 4278190080; + } + var ctx = this._ctx; + ctx.fillStyle = argbUintToStr(color); + replaceRect(ctx, rect.x, rect.y, rect.width, rect.height, color >>> 24 & 255); + this._invalidate(); + }, + getPixel: function (x, y) { + this._checkCanvas(); + var data = this._ctx.getImageData(x, y, 1, 1).data; + return dataToRGB(data); + }, + getPixel32: function (x, y) { + this._checkCanvas(); + var data = this._ctx.getImageData(x, y, 1, 1).data; + return dataToARGB(data); + }, + _invalidate: function (changeRect) { + if (changeRect) { + somewhatImplemented('BitmapData._invalidate(changeRect)'); + } + if (this._locked) { + return; + } + if (this._changeNotificationTarget) { + this._changeNotificationTarget._drawableChanged(); + } + this._requested = 0; + this._cache = null; + }, + _getDrawable: function () { + if (this._img === this._drawable) { + return this._drawable; + } + this._requested++; + if (this._requested >= CACHE_DRAWABLE_AFTER) { + if (!this._cache) { + Counter.count('Cache drawable'); + var img = document.createElement('img'); + if ('toBlob' in this._drawable) { + this._drawable.toBlob(function (blob) { + img.src = URL.createObjectURL(blob); + img.onload = function () { + URL.revokeObjectURL(blob); + }; + }); + } else { + img.src = this._drawable.toDataURL(); + } + this._cache = img; + } + if (this._cache.width > 0) { + return this._cache; + } + } + return this._drawable; + }, + setPixel: function (x, y, color) { + this.fillRect({ + x: x, + y: y, + width: 1, + height: 1 + }, color | 4278190080); + this._invalidate(); + }, + setPixel32: function (x, y, color) { + this.fillRect({ + x: x, + y: y, + width: 1, + height: 1 + }, color); + this._invalidate(); + }, + copyPixels: function copyPixels(sourceBitmapData, sourceRect, destPoint, alphaBitmapData, alphaPoint, mergeAlpha) { + if (alphaBitmapData) { + notImplemented('BitmapData.copyPixels w/ alpha'); + } + var w = sourceRect.width; + var h = sourceRect.height; + var sx = sourceRect.x; + var sy = sourceRect.y; + var dx = destPoint.x; + var dy = destPoint.y; + var offsetx = -Math.min(0, sx, dx); + var offsety = -Math.min(0, sy, dy); + var correctionw = Math.min(0, this._ctx.canvas.width - dx - w, sourceBitmapData._drawable.width - sx - w) - offsetx; + var correctionh = Math.min(0, this._ctx.canvas.height - dy - h, sourceBitmapData._drawable.height - sy - h) - offsety; + if (!mergeAlpha) { + this._ctx.clearRect(dx, dy, w, h); + } + if (w + correctionw > 0 && h + correctionh > 0) { + this._ctx.drawImage(sourceBitmapData._drawable, sx + offsetx, sy + offsety, w + correctionw, h + correctionh, dx + offsetx, dy + offsety, w + correctionw, h + correctionh); + } + this._invalidate(); + }, + lock: function lock() { + this._locked = true; + }, + unlock: function unlock(changeRect) { + this._locked = false; + this._invalidate(changeRect); + }, + clone: function () { + this._checkCanvas(); + var bd = new flash.display.BitmapData(this._drawable.width, this._drawable.height, true, 0); + bd._ctx.drawImage(this._drawable, 0, 0); + return bd; + }, + scroll: function (x, y) { + this._checkCanvas(); + this._ctx.draw(this._drawable, x, y); + this._ctx.save(); + var color = this._img ? 0 : this._backgroundColor; + if (!this._transparent) { + color |= 4278190080; + } + var alpha = color >>> 24 & 255; + this._ctx.fillStyle = argbUintToStr(color); + var w = this._drawable.width; + var h = this._drawable.height; + if (x > 0) { + replaceRect(this._ctx, 0, 0, x, h, alpha); + } else if (x < 0) { + replaceRect(this._ctx, w + x, 0, -x, h, alpha); + } + if (y > 0) { + replaceRect(this._ctx, 0, 0, w, y, alpha); + } else if (y < 0) { + replaceRect(this._ctx, h + y, w, -y, alpha); + } + this._ctx.restore(); + this._invalidate(); + }, + get width() { + return this._drawable.width; + }, + get height() { + return this._drawable.height; + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + ctor: def.ctor, + fillRect: def.fillRect, + dispose: def.dispose, + getPixel: def.getPixel, + getPixel32: def.getPixel32, + setPixel: def.setPixel, + setPixel32: def.setPixel32, + copyPixels: def.copyPixels, + lock: def.lock, + unlock: def.unlock, + draw: def.draw, + clone: def.clone, + scroll: def.scroll, + width: desc(def, 'width'), + height: desc(def, 'height') + } + } + }; + return def; + }.call(this); +function dataToRGB(data) { + return data[0] << 16 | data[1] << 8 | data[2]; +} +function dataToARGB(data) { + return data[3] << 24 | dataToRGB(data); +} +var DisplayObjectDefinition = function () { + var blendModes; + var nextInstanceId = 1; + function generateName() { + return 'instance' + nextInstanceId++; + } + var broadcastedEvents = { + advanceFrame: false, + enterFrame: true, + constructChildren: false, + frameConstructed: true, + executeFrame: false, + exitFrame: true, + render: true + }; + var point = { + x: 0, + y: 0 + }; + var def = { + __class__: 'flash.display.DisplayObject', + initialize: function () { + var blendModeClass = flash.display.BlendMode.class; + this._alpha = 1; + this._animated = false; + this._bbox = null; + this._bitmap = null; + this._blendMode = blendModeClass.NORMAL; + this._bounds = { + xMin: 0, + xMax: 0, + yMin: 0, + yMax: 0, + invalid: true + }; + this._cacheAsBitmap = false; + this._children = []; + this._clipDepth = null; + this._currentTransform = { + a: 1, + b: 0, + c: 0, + d: 1, + tx: 0, + ty: 0 + }; + this._concatenatedTransform = { + a: 1, + b: 0, + c: 0, + d: 1, + tx: 0, + ty: 0, + invalid: true + }; + this._current3DTransform = null; + this._cxform = null; + this._graphics = null; + this._filters = []; + this._loader = null; + this._mouseChildren = true; + this._mouseOver = false; + this._mouseX = 0; + this._mouseY = 0; + this._name = null; + this._opaqueBackground = null; + this._owned = false; + this._parent = null; + this._rotation = 0; + this._rotationCos = 1; + this._rotationSin = 0; + this._scale9Grid = null; + this._scaleX = 1; + this._scaleY = 1; + this._stage = null; + this._visible = true; + this._hidden = false; + this._wasCachedAsBitmap = false; + this._destroyed = false; + this._maskedObject = null; + this._scrollRect = null; + this._invalid = false; + this._region = null; + this._level = -1; + this._index = -1; + this._depth = -1; + this._isContainer = false; + this._invisible = false; + this._zindex = 0; + blendModes = [ + blendModeClass.NORMAL, + blendModeClass.NORMAL, + blendModeClass.LAYER, + blendModeClass.MULTIPLY, + blendModeClass.SCREEN, + blendModeClass.LIGHTEN, + blendModeClass.DARKEN, + blendModeClass.DIFFERENCE, + blendModeClass.ADD, + blendModeClass.SUBTRACT, + blendModeClass.INVERT, + blendModeClass.ALPHA, + blendModeClass.ERASE, + blendModeClass.OVERLAY, + blendModeClass.HARDLIGHT, + blendModeClass.SHADER + ]; + var s = this.symbol; + if (s) { + this._animated = s.animated || false; + this._bbox = s.bbox || null; + this._blendMode = this._resolveBlendMode(s.blendMode); + this._children = s.children || []; + this._clipDepth = s.clipDepth || null; + this._cxform = s.cxform || null; + this._loader = s.loader || null; + this._name = s.name || null; + this._owned = s.owned || false; + this._parent = s.parent || null; + this._level = isNaN(s.level) ? -1 : s.level; + this._index = isNaN(s.index) ? -1 : s.index; + this._depth = isNaN(s.depth) ? -1 : s.depth; + this._root = s.root || null; + this._stage = s.stage || null; + var scale9Grid = s.scale9Grid; + if (scale9Grid) { + this._scale9Grid = new flash.geom.Rectangle(scale9Grid.left, scale9Grid.top, scale9Grid.right - scale9Grid.left, scale9Grid.bottom - scale9Grid.top); + } + var matrix = s.currentTransform; + if (matrix) { + this._setTransformMatrix(matrix, false); + } + } + this._accessibilityProperties = null; + var self = this; + this._onBroadcastMessage = function (type) { + var listeners = self._listeners; + if (listeners[type]) { + self._dispatchEvent(type); + } + }; + }, + _addEventListener: function addEventListener(type, listener, useCapture, priority) { + if (broadcastedEvents[type] === false) { + avm2.systemDomain.onMessage.register(type, listener); + return; + } + if (type in broadcastedEvents && !this._listeners[type]) { + avm2.systemDomain.onMessage.register(type, this._onBroadcastMessage); + } + this._addEventListenerImpl(type, listener, useCapture, priority); + }, + _removeEventListener: function addEventListener(type, listener, useCapture) { + if (broadcastedEvents[type] === false) { + avm2.systemDomain.onMessage.unregister(type, listener); + return; + } + this._removeEventListenerImpl(type, listener, useCapture); + if (type in broadcastedEvents && !this._listeners[type]) { + avm2.systemDomain.onMessage.unregister(type, this._onBroadcastMessage); + } + }, + _resolveBlendMode: function (blendModeNumeric) { + return blendModes[blendModeNumeric] || flash.display.BlendMode.class.NORMAL; + }, + _getConcatenatedTransform: function (targetCoordSpace, toDeviceSpace) { + var stage = this._stage; + if (this === this._stage) { + return toDeviceSpace ? this._concatenatedTransform : this._currentTransform; + } + if (targetCoordSpace === this._parent) { + return this._currentTransform; + } + var invalidNode = null; + var m, m2, targetCoordMatrix; + var currentNode = this; + while (currentNode !== stage) { + if (currentNode._concatenatedTransform.invalid) { + invalidNode = currentNode; + } + if (currentNode === targetCoordSpace) { + targetCoordMatrix = currentNode._concatenatedTransform; + } + currentNode = currentNode._parent; + } + if (invalidNode) { + if (this._parent === stage) { + m = this._concatenatedTransform; + m2 = this._currentTransform; + m.a = m2.a; + m.b = m2.b; + m.c = m2.c; + m.d = m2.d; + m.tx = m2.tx; + m.ty = m2.ty; + } else { + var stack = []; + var currentNode = this; + while (currentNode !== invalidNode) { + stack.push(currentNode); + currentNode = currentNode._parent; + } + var node = invalidNode; + do { + var parent = node._parent; + m = node._concatenatedTransform; + m2 = node._currentTransform; + if (parent) { + if (parent !== stage) { + var m3 = parent._concatenatedTransform; + m.a = m2.a * m3.a + m2.b * m3.c; + m.b = m2.a * m3.b + m2.b * m3.d; + m.c = m2.c * m3.a + m2.d * m3.c; + m.d = m2.d * m3.d + m2.c * m3.b; + m.tx = m2.tx * m3.a + m3.tx + m2.ty * m3.c; + m.ty = m2.ty * m3.d + m3.ty + m2.tx * m3.b; + } + } else { + m.a = m2.a; + m.b = m2.b; + m.c = m2.c; + m.d = m2.d; + m.tx = m2.tx; + m.ty = m2.ty; + } + m.invalid = false; + var nextNode = stack.pop(); + var children = node._children; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (child !== nextNode) { + child._concatenatedTransform.invalid = true; + } + } + node = nextNode; + } while (node); + } + } else { + m = this._concatenatedTransform; + } + if (targetCoordSpace && targetCoordSpace !== this._stage) { + m2 = targetCoordMatrix || targetCoordSpace._getConcatenatedTransform(null, false); + var a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0; + if (m2.b || m2.c) { + var det = 1 / (m2.a * m2.d - m2.b * m2.c); + a = m2.d * det; + b = -m2.b * det; + c = -m2.c * det; + d = m2.a * det; + tx = -(a * m2.tx + c * m2.ty); + ty = -(b * m2.tx + d * m2.ty); + } else { + a = 1 / m2.a; + d = 1 / m2.d; + tx = m2.tx * -a; + ty = m2.ty * -d; + } + return { + a: a * m.a + c * m.b, + b: b * m.a + d * m.b, + c: a * m.c + c * m.d, + d: b * m.c + d * m.d, + tx: a * m.tx + c * m.ty + tx, + ty: b * m.tx + d * m.ty + ty + }; + } + if (toDeviceSpace && stage) { + m2 = stage._concatenatedTransform; + return { + a: m.a * m2.a, + b: m.b * m2.d, + c: m.c * m2.a, + d: m.d * m2.d, + tx: m.tx * m2.a + m2.tx, + ty: m.ty * m2.d + m2.ty + }; + } + return m; + }, + _applyCurrentTransform: function (pt) { + var m = this._getConcatenatedTransform(null, false); + var x = pt.x; + var y = pt.y; + pt.x = m.a * x + m.c * y + m.tx | 0; + pt.y = m.d * y + m.b * x + m.ty | 0; + }, + _applyConcatenatedInverseTransform: function (pt) { + var m = this._getConcatenatedTransform(null, false); + var det = 1 / (m.a * m.d - m.b * m.c); + var x = pt.x - m.tx; + var y = pt.y - m.ty; + pt.x = (m.d * x - m.c * y) * det | 0; + pt.y = (m.a * y - m.b * x) * det | 0; + }, + _hitTest: function (use_xy, x, y, useShape, hitTestObject) { + if (use_xy) { + point.x = x; + point.y = y; + this._applyConcatenatedInverseTransform(point); + var b = this._getContentBounds(); + if (!(point.x >= b.xMin && point.x < b.xMax && point.y >= b.yMin && point.y < b.yMax)) { + return false; + } + if (!useShape || !this._graphics) { + return true; + } + if (this._graphics) { + var subpaths = this._graphics._paths; + for (var i = 0, n = subpaths.length; i < n; i++) { + var path = subpaths[i]; + if (path.isPointInPath(point.x, point.y)) { + return true; + } + if (path.strokeStyle) { + var strokePath = path._strokePath; + if (!strokePath) { + strokePath = path.strokePath(path.drawingStyles); + path._strokePath = strokePath; + } + if (strokePath.isPointInPath(point.x, point.y)) { + return true; + } + } + } + } + var children = this._children; + for (var i = 0, n = children.length; i < n; i++) { + var child = children[i]; + if (child._hitTest && child._hitTest(true, x, y, true, null)) { + return true; + } + } + return false; + } + var b1 = this.getBounds(this._stage); + var b2 = hitTestObject.getBounds(hitTestObject._stage); + x = Math.max(b1.xMin, b2.xMin); + y = Math.max(b1.yMin, b2.yMin); + var width = Math.min(b1.xMax, b2.xMax) - x; + var height = Math.min(b1.yMax, b2.yMax) - y; + return width > 0 && height > 0; + }, + _invalidate: function () { + this._invalid = true; + }, + _invalidateBounds: function () { + var currentNode = this; + while (currentNode && !currentNode._bounds.invalid) { + currentNode._bounds.invalid = true; + currentNode = currentNode._parent; + } + }, + _invalidateTransform: function () { + this._concatenatedTransform.invalid = true; + if (this._parent) { + this._parent._invalidateBounds(); + } + }, + _setTransformMatrix: function (matrix, convertToTwips) { + var a = matrix.a; + var b = matrix.b; + var c = matrix.c; + var d = matrix.d; + var tx, ty; + if (convertToTwips) { + tx = matrix.tx * 20 | 0; + ty = matrix.ty * 20 | 0; + } else { + tx = matrix.tx; + ty = matrix.ty; + } + var angle = a !== 0 ? Math.atan(b / a) : b > 0 ? Math.PI / 2 : -Math.PI / 2; + this._rotation = angle * 180 / Math.PI; + this._rotationCos = Math.cos(angle); + this._rotationSin = Math.sin(angle); + var sx = Math.sqrt(a * a + b * b); + this._scaleX = a > 0 ? sx : -sx; + var sy = Math.sqrt(d * d + c * c); + this._scaleY = d > 0 ? sy : -sy; + var transform = this._currentTransform; + transform.a = a; + transform.b = b; + transform.c = c; + transform.d = d; + transform.tx = tx; + transform.ty = ty; + this._invalidateTransform(); + }, + get accessibilityProperties() { + return this._accessibilityProperties; + }, + set accessibilityProperties(val) { + this._accessibilityProperties = val; + }, + get alpha() { + return this._alpha; + }, + set alpha(val) { + if (val === this._alpha) { + return; + } + this._invalidate(); + this._alpha = val; + this._animated = false; + }, + get blendMode() { + return this._blendMode; + }, + set blendMode(val) { + if (blendModes.indexOf(val) >= 0) { + this._blendMode = val; + } else { + throwError('ArgumentError', Errors.InvalidEnumError, 'blendMode'); + } + this._animated = false; + }, + get cacheAsBitmap() { + return this._cacheAsBitmap; + }, + set cacheAsBitmap(val) { + this._cacheAsBitmap = this._filters.length ? true : val; + this._animated = false; + }, + get filters() { + return this._filters; + }, + set filters(val) { + if (val.length) { + if (!this._filters.length) + this._wasCachedAsBitmap = this._cacheAsBitmap; + this._cacheAsBitmap = true; + } else { + this._cacheAsBitmap = this._wasCachedAsBitmap; + } + this._filters = val; + this._animated = false; + }, + get height() { + var bounds = this._getContentBounds(); + var t = this._currentTransform; + return Math.abs(t.b) * (bounds.xMax - bounds.xMin) + Math.abs(t.d) * (bounds.yMax - bounds.yMin) | 0; + }, + set height(val) { + if (val < 0) { + return; + } + var u = Math.abs(this._rotationCos); + var v = Math.abs(this._rotationSin); + var bounds = this._getContentBounds(); + var baseHeight = v * (bounds.xMax - bounds.xMin) + u * (bounds.yMax - bounds.yMin); + if (!baseHeight) { + return; + } + var baseWidth = u * (bounds.xMax - bounds.xMin) + v * (bounds.yMax - bounds.yMin); + this.scaleX = this.width / baseWidth; + this.scaleY = val / baseHeight; + }, + get loaderInfo() { + return this._loader && this._loader._contentLoaderInfo || this._parent.loaderInfo; + }, + get mask() { + return this._mask; + }, + set mask(val) { + if (this._mask === val) { + return; + } + this._invalidate(); + if (val && val._maskedObject) { + val._maskedObject.mask = null; + } + this._mask = val; + if (val) { + val._maskedObject = this; + } + this._animated = false; + }, + get name() { + return this._name || (this._name = generateName()); + }, + set name(val) { + this._name = val; + }, + get mouseX() { + if (!this._stage) { + return 0; + } + point.x = this._stage._mouseX; + point.y = this._stage._mouseY; + this._applyConcatenatedInverseTransform(point); + return point.x; + }, + get mouseY() { + if (!this._stage) { + return 0; + } + point.x = this._stage._mouseX; + point.y = this._stage._mouseY; + this._applyConcatenatedInverseTransform(point); + return point.y; + }, + get opaqueBackground() { + return this._opaqueBackground; + }, + set opaqueBackground(val) { + this._opaqueBackground = val; + this._animated = false; + }, + get parent() { + return this._index > -1 ? this._parent : null; + }, + get root() { + return this._stage && this._stage._root; + }, + get rotation() { + return this._rotation; + }, + set rotation(val) { + val %= 360; + if (val > 180) { + val -= 360; + } + if (val === this._rotation) + return; + this._invalidate(); + this._invalidateTransform(); + this._rotation = val; + var u, v; + switch (val) { + case 0: + case 360: + u = 1, v = 0; + break; + case 90: + case -270: + u = 0, v = 1; + break; + case 180: + case -180: + u = -1, v = 0; + break; + case 270: + case -90: + u = 0, v = -1; + break; + default: + var angle = this._rotation / 180 * Math.PI; + u = Math.cos(angle); + v = Math.sin(angle); + break; + } + this._rotationCos = u; + this._rotationSin = v; + var m = this._currentTransform; + m.a = u * this._scaleX; + m.b = v * this._scaleX; + m.c = -v * this._scaleY; + m.d = u * this._scaleY; + this._animated = false; + }, + get rotationX() { + return 0; + }, + set rotationX(val) { + somewhatImplemented('DisplayObject.rotationX'); + }, + get rotationY() { + return 0; + }, + set rotationY(val) { + somewhatImplemented('DisplayObject.rotationY'); + }, + get rotationZ() { + return this.rotation; + }, + set rotationZ(val) { + this.rotation = val; + somewhatImplemented('DisplayObject.rotationZ'); + }, + get stage() { + return this._stage; + }, + get scaleX() { + return this._scaleX; + }, + set scaleX(val) { + if (val === this._scaleX) + return; + this._invalidate(); + this._invalidateTransform(); + this._scaleX = val; + var m = this._currentTransform; + m.a = this._rotationCos * val; + m.b = this._rotationSin * val; + this._animated = false; + }, + get scaleY() { + return this._scaleY; + }, + set scaleY(val) { + if (val === this._scaleY) + return; + this._invalidate(); + this._invalidateTransform(); + this._scaleY = val; + var m = this._currentTransform; + m.c = -this._rotationSin * val; + m.d = this._rotationCos * val; + this._animated = false; + }, + get scaleZ() { + return 1; + }, + set scaleZ(val) { + somewhatImplemented('DisplayObject.scaleZ'); + }, + get scale9Grid() { + return this._scale9Grid; + }, + set scale9Grid(val) { + somewhatImplemented('DisplayObject.scale9Grid'); + this._scale9Grid = val; + this._animated = false; + }, + get scrollRect() { + return this._scrollRect; + }, + set scrollRect(val) { + somewhatImplemented('DisplayObject.scrollRect'); + this._scrollRect = val; + }, + get transform() { + return new flash.geom.Transform(this); + }, + set transform(val) { + var transform = this.transform; + transform.colorTransform = val.colorTransform; + if (val.matrix3D) { + transform.matrix3D = val.matrix3D; + } else { + transform.matrix = val.matrix; + } + }, + get visible() { + return this._visible; + }, + set visible(val) { + if (val === this._visible) + return; + this._invalidate(); + this._visible = val; + this._animated = false; + }, + get width() { + var bounds = this._getContentBounds(); + var t = this._currentTransform; + return Math.abs(t.a) * (bounds.xMax - bounds.xMin) + Math.abs(t.c) * (bounds.yMax - bounds.yMin) | 0; + }, + set width(val) { + if (val < 0) { + return; + } + var u = Math.abs(this._rotationCos); + var v = Math.abs(this._rotationSin); + var bounds = this._getContentBounds(); + var baseWidth = u * (bounds.xMax - bounds.xMin) + v * (bounds.yMax - bounds.yMin); + if (!baseWidth) { + return; + } + var baseHeight = v * (bounds.xMax - bounds.xMin) + u * (bounds.yMax - bounds.yMin); + this.scaleY = this.height / baseHeight; + this.scaleX = val / baseWidth; + }, + get x() { + return this._currentTransform.tx; + }, + set x(val) { + if (val === this._currentTransform.tx) { + return; + } + this._invalidate(); + this._invalidateTransform(); + this._currentTransform.tx = val; + this._animated = false; + }, + get y() { + return this._currentTransform.ty; + }, + set y(val) { + if (val === this._currentTransform.ty) { + return; + } + this._invalidate(); + this._invalidateTransform(); + this._currentTransform.ty = val; + this._animated = false; + }, + get z() { + return 0; + }, + set z(val) { + somewhatImplemented('DisplayObject.z'); + }, + _getContentBounds: function () { + var bounds = this._bounds; + if (bounds.invalid) { + var bbox = this._bbox; + var xMin = Number.MAX_VALUE; + var xMax = Number.MIN_VALUE; + var yMin = Number.MAX_VALUE; + var yMax = Number.MIN_VALUE; + if (bbox) { + xMin = bbox.xMin; + xMax = bbox.xMax; + yMin = bbox.yMin; + yMax = bbox.yMax; + } else { + var children = this._children; + var numChildren = children.length; + for (var i = 0; i < numChildren; i++) { + var child = children[i]; + if (!flash.display.DisplayObject.class.isInstanceOf(child)) { + continue; + } + var b = child.getBounds(this); + var x1 = b.xMin; + var y1 = b.yMin; + var x2 = b.xMax; + var y2 = b.yMax; + xMin = Math.min(xMin, x1, x2); + xMax = Math.max(xMax, x1, x2); + yMin = Math.min(yMin, y1, y2); + yMax = Math.max(yMax, y1, y2); + } + if (this._graphics) { + var b = this._graphics._getBounds(true); + if (b.xMin !== b.xMax && b.yMin !== b.yMax) { + var x1 = b.xMin; + var y1 = b.yMin; + var x2 = b.xMax; + var y2 = b.yMax; + xMin = Math.min(xMin, x1, x2); + xMax = Math.max(xMax, x1, x2); + yMin = Math.min(yMin, y1, y2); + yMax = Math.max(yMax, y1, y2); + } + } + } + if (xMin === Number.MAX_VALUE) { + xMin = xMax = yMin = yMax = 0; + } + bounds.xMin = xMin; + bounds.xMax = xMax; + bounds.yMin = yMin; + bounds.yMax = yMax; + bounds.invalid = false; + } + return bounds; + }, + _getRegion: function getRegion(targetCoordSpace) { + var b; + var filters = this._filters; + if (filters.length) { + var xMin = Number.MAX_VALUE; + var xMax = Number.MIN_VALUE; + var yMin = Number.MAX_VALUE; + var yMax = Number.MIN_VALUE; + if (this._graphics) { + b = this._graphics._getBounds(true); + if (b) { + xMin = b.xMin; + xMax = b.xMax; + yMin = b.yMin; + yMax = b.yMax; + } + } + var children = this._children; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + b = children[i]._getRegion(this); + if (b.xMin < xMin) { + xMin = b.xMin; + } + if (b.xMax > xMax) { + xMax = b.xMax; + } + if (b.yMin < yMin) { + yMin = b.yMin; + } + if (b.yMax > yMax) { + yMax = b.yMax; + } + } + if (xMin === Number.MAX_VALUE) { + return { + xMin: 0, + xMax: 0, + yMin: 0, + yMax: 0 + }; + } + b = { + xMin: xMin, + xMax: xMax, + yMin: yMin, + yMax: yMax + }; + for (var i = 0; i < filters.length; i++) { + filters[i]._updateFilterBounds(b); + } + } else { + b = this._graphics ? this._graphics._getBounds(true) : this._getContentBounds(); + } + return this._getTransformedRect(b, targetCoordSpace); + }, + getBounds: function (targetCoordSpace) { + return this._getTransformedRect(this._getContentBounds(), targetCoordSpace); + }, + _getTransformedRect: function (rect, targetCoordSpace) { + if (!targetCoordSpace || targetCoordSpace === this) { + return rect; + } + var xMin = rect.xMin; + var xMax = rect.xMax; + var yMin = rect.yMin; + var yMax = rect.yMax; + if (xMax - xMin === 0 || yMax - yMin === 0) { + return { + xMin: 0, + yMin: 0, + xMax: 0, + yMax: 0 + }; + } + var m = targetCoordSpace && !flash.display.DisplayObject.class.isInstanceOf(targetCoordSpace) ? targetCoordSpace : this._getConcatenatedTransform(targetCoordSpace, false); + var x0 = m.a * xMin + m.c * yMin + m.tx | 0; + var y0 = m.b * xMin + m.d * yMin + m.ty | 0; + var x1 = m.a * xMax + m.c * yMin + m.tx | 0; + var y1 = m.b * xMax + m.d * yMin + m.ty | 0; + var x2 = m.a * xMax + m.c * yMax + m.tx | 0; + var y2 = m.b * xMax + m.d * yMax + m.ty | 0; + var x3 = m.a * xMin + m.c * yMax + m.tx | 0; + var y3 = m.b * xMin + m.d * yMax + m.ty | 0; + var tmp = 0; + if (x0 > x1) { + tmp = x0; + x0 = x1; + x1 = tmp; + } + if (x2 > x3) { + tmp = x2; + x2 = x3; + x3 = tmp; + } + xMin = x0 < x2 ? x0 : x2; + xMax = x1 > x3 ? x1 : x3; + if (y0 > y1) { + tmp = y0; + y0 = y1; + y1 = tmp; + } + if (y2 > y3) { + tmp = y2; + y2 = y3; + y3 = tmp; + } + yMin = y0 < y2 ? y0 : y2; + yMax = y1 > y3 ? y1 : y3; + return { + xMin: xMin, + yMin: yMin, + xMax: xMax, + yMax: yMax + }; + }, + hitTestObject: function (obj) { + return this._hitTest(false, 0, 0, false, obj); + }, + hitTestPoint: function (x, y, shapeFlag) { + return this._hitTest(true, x, y, shapeFlag, null); + }, + destroy: function () { + if (this._destroyed) { + return; + } + this._destroyed = true; + this.cleanupBroadcastListeners(); + }, + cleanupBroadcastListeners: function () { + var listenerLists = this._listeners; + for (var type in listenerLists) { + avm2.systemDomain.onMessage.unregister(type, this._onBroadcastMessage); + } + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + root: desc(def, 'root'), + stage: desc(def, 'stage'), + name: desc(def, 'name'), + parent: desc(def, 'parent'), + mask: desc(def, 'mask'), + visible: desc(def, 'visible'), + x: { + get: function x() { + return this.x / 20; + }, + set: function x(value) { + this.x = value * 20 | 0; + } + }, + y: { + get: function y() { + return this.y / 20; + }, + set: function y(value) { + this.y = value * 20 | 0; + } + }, + z: { + get: function z() { + return this.z / 20; + }, + set: function z(value) { + this.z = value * 20 | 0; + } + }, + scaleX: desc(def, 'scaleX'), + scaleY: desc(def, 'scaleY'), + scaleZ: desc(def, 'scaleZ'), + mouseX: { + get: function mouseX() { + return this.mouseX / 20; + }, + set: function mouseX(value) { + this.mouseX = value * 20 | 0; + } + }, + mouseY: { + get: function mouseY() { + return this.mouseY / 20; + }, + set: function mouseY(value) { + this.mouseY = value * 20 | 0; + } + }, + rotation: desc(def, 'rotation'), + rotationX: desc(def, 'rotationX'), + rotationY: desc(def, 'rotationY'), + rotationZ: desc(def, 'rotationZ'), + alpha: desc(def, 'alpha'), + width: { + get: function width() { + return this.width / 20; + }, + set: function width(value) { + this.width = value * 20 | 0; + } + }, + height: { + get: function height() { + return this.height / 20; + }, + set: function height(value) { + this.height = value * 20 | 0; + } + }, + _hitTest: function (use_xy, x, y, useShape, hitTestObject) { + x = x * 20 | 0; + y = y * 20 | 0; + return this._hitTest(use_xy, x, y, useShape, hitTestObject); + }, + cacheAsBitmap: desc(def, 'cacheAsBitmap'), + opaqueBackground: desc(def, 'opaqueBackground'), + scrollRect: desc(def, 'scrollRect'), + filters: desc(def, 'filters'), + blendMode: desc(def, 'blendMode'), + transform: desc(def, 'transform'), + scale9Grid: desc(def, 'scale9Grid'), + loaderInfo: desc(def, 'loaderInfo'), + accessibilityProperties: desc(def, 'accessibilityProperties'), + globalToLocal: function (pt) { + point.x = pt.x * 20 | 0; + point.y = pt.y * 20 | 0; + this._applyConcatenatedInverseTransform(point); + return new flash.geom.Point(point.x / 20, point.y / 20); + }, + localToGlobal: function (pt) { + point.x = pt.x * 20 | 0; + point.y = pt.y * 20 | 0; + this._applyCurrentTransform(point); + return new flash.geom.Point(point.x / 20, point.y / 20); + }, + getBounds: function (targetCoordSpace) { + var bounds = this.getBounds(targetCoordSpace); + return new flash.geom.Rectangle(bounds.xMin / 20, bounds.yMin / 20, (bounds.xMax - bounds.xMin) / 20, (bounds.yMax - bounds.yMin) / 20); + }, + getRect: function (targetCoordSpace) { + somewhatImplemented('DisplayObject.getRect'); + var bounds = this.getBounds(targetCoordSpace); + return new flash.geom.Rectangle(bounds.xMin / 20, bounds.yMin / 20, (bounds.xMax - bounds.xMin) / 20, (bounds.yMax - bounds.yMin) / 20); + } + } + } + }; + return def; + }.call(this); +var DisplayObjectContainerDefinition = function () { + var def = { + get mouseChildren() { + return this._mouseChildren; + }, + set mouseChildren(val) { + this._mouseChildren = val; + }, + get numChildren() { + return this._children.length; + }, + get tabChildren() { + return this._tabChildren; + }, + set tabChildren(val) { + this._tabChildren = val; + }, + get textSnapshot() { + notImplemented(); + }, + addChild: function (child) { + return this.addChildAt(child, this._children.length); + }, + addChildAt: function (child, index) { + if (child === this) { + throwError('ArgumentError', Errors.CantAddSelfError); + } + if (child._parent === this) { + return this.setChildIndex(child, index); + } + var children = this._children; + if (index < 0 || index > children.length) { + throwError('RangeError', Errors.ParamRangeError); + } + if (child._index > -1) { + var LoaderClass = avm2.systemDomain.getClass('flash.display.Loader'); + if (LoaderClass.isInstanceOf(child._parent)) { + def.removeChild.call(child._parent, child); + } else { + child._parent.removeChild(child); + } + } + if (!this._sparse) { + for (var i = children.length; i && i > index; i--) { + children[i - 1]._index++; + } + } + children.splice(index, 0, child); + child._invalidateTransform(); + child._owned = false; + child._parent = this; + child._stage = this._stage; + child._index = index; + child._dispatchEvent('added', undefined, true); + if (this._stage) { + this._stage._addToStage(child); + } + return child; + }, + areInaccessibleObjectsUnderPoint: function (pt) { + notImplemented(); + }, + contains: function (child) { + return child._parent === this; + }, + getChildAt: function (index) { + var children = this._children; + if (index < 0 || index > children.length) { + throwError('RangeError', Errors.ParamRangeError); + } + var child = children[index]; + if (!flash.display.DisplayObject.class.isInstanceOf(child)) { + return null; + } + return child; + }, + getChildByName: function (name) { + var children = this._children; + for (var i = 0, n = children.length; i < n; i++) { + var child = children[i]; + if (child.name === name) { + return this.getChildAt(i); + } + } + return null; + }, + getChildIndex: function (child) { + if (child._parent !== this) { + throwError('ArgumentError', Errors.NotAChildError); + } + return this._sparse ? this._children.indexOf(child) : child._index; + }, + getObjectsUnderPoint: function (pt) { + notImplemented(); + }, + removeChild: function (child) { + if (child._parent !== this) { + throwError('ArgumentError', Errors.NotAChildError); + } + return this.removeChildAt(this.getChildIndex(child)); + }, + removeChildAt: function (index) { + var children = this._children; + if (index < 0 || index >= children.length) { + throwError('RangeError', Errors.ParamRangeError); + } + var child = children[index]; + child._dispatchEvent('removed', undefined, true); + if (this._stage) { + this._stage._removeFromStage(child); + } + if (!this._sparse) { + for (var i = children.length; i && i > index; i--) { + children[i - 1]._index--; + } + } + children.splice(index, 1); + child._invalidateTransform(); + child._owned = false; + child._parent = null; + child._index = -1; + return child; + }, + setChildIndex: function (child, index) { + if (child._parent !== this) { + throwError('ArgumentError', Errors.NotAChildError); + } + var currentIndex = this.getChildIndex(child); + if (currentIndex === index) { + return; + } + var children = this._children; + if (index < 0 || index > children.length) { + throwError('RangeError', Errors.ParamRangeError); + } + children.splice(currentIndex, 1); + children.splice(index, 0, child); + if (!this._sparse) { + var i = currentIndex < index ? currentIndex : index; + while (i < children.length) { + children[i]._index = i++; + } + } + child._owned = false; + child._invalidate(); + return child; + }, + removeChildren: function (beginIndex, endIndex) { + beginIndex = arguments.length < 1 ? 0 : beginIndex | 0; + endIndex = arguments.length < 2 ? 2147483647 : endIndex | 0; + var numChildren = this._children.length; + if (beginIndex < 0 || endIndex < 0 || endIndex < beginIndex) { + throwError('RangeError', Errors.ParamRangeError); + } + if (numChildren === 0) { + return; + } + if (endIndex > numChildren - 1) { + endIndex = numChildren - 1; + } + var count = endIndex - beginIndex + 1; + while (count--) { + this.removeChildAt(beginIndex); + } + }, + swapChildren: function (child1, child2) { + if (child1._parent !== this || child2._parent !== this) { + throwError('ArgumentError', Errors.NotAChildError); + } + this.swapChildrenAt(this.getChildIndex(child1), this.getChildIndex(child2)); + }, + swapChildrenAt: function (index1, index2) { + var children = this._children; + var numChildren = children.length; + if (index1 < 0 || index1 > numChildren || index2 < 0 || index2 > numChildren) { + throwError('RangeError', Errors.ParamRangeError); + } + var child1 = children[index1]; + var child2 = children[index2]; + children[index1] = child2; + children[index2] = child1; + child1._index = index2; + child2._index = index1; + child1._owned = false; + child2._owned = false; + child1._invalidate(); + child2._invalidate(); + }, + destroy: function () { + if (this._destroyed) { + return; + } + this._destroyed = true; + this._children.forEach(function (child) { + if (child.destroy) { + child.destroy(); + } + }); + this.cleanupBroadcastListeners(); + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.initialize = function () { + this._mouseChildren = true; + this._tabChildren = true; + this._sparse = false; + this._isContainer = true; + }; + def.__glue__ = { + native: { + instance: { + numChildren: desc(def, 'numChildren'), + tabChildren: desc(def, 'tabChildren'), + mouseChildren: desc(def, 'mouseChildren'), + textSnapshot: desc(def, 'textSnapshot'), + addChild: def.addChild, + addChildAt: def.addChildAt, + removeChild: def.removeChild, + removeChildAt: def.removeChildAt, + getChildIndex: def.getChildIndex, + setChildIndex: def.setChildIndex, + getChildAt: def.getChildAt, + getChildByName: def.getChildByName, + contains: def.contains, + swapChildrenAt: def.swapChildrenAt, + swapChildren: def.swapChildren, + removeChildren: def.removeChildren + } + } + }; + return def; + }.call(this); +var FrameLabelDefinition = function () { + return { + __class__: 'flash.display.FrameLabel', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + ctor: function ctor(name, frame) { + this._name = name; + this._frame = frame; + }, + name: { + get: function name() { + return this._name; + } + }, + frame: { + get: function frame() { + return this._frame; + } + } + } + } + } + }; + }.call(this); +var GraphicsDefinition = function () { + var GRAPHICS_PATH_WINDING_EVEN_ODD = 'evenOdd'; + var GRAPHICS_PATH_WINDING_NON_ZERO = 'nonZero'; + var def = { + __class__: 'flash.display.Graphics', + initialize: function () { + this._paths = []; + this.beginPath(); + this._bitmap = null; + this._parent = 0; + this.bbox = null; + this.strokeBbox = null; + }, + _invalidate: function () { + this.bbox = null; + this.strokeBbox = null; + this._parent._invalidate(); + this._parent._invalidateBounds(); + }, + beginPath: function () { + var oldPath = this._currentPath; + if (oldPath && (oldPath.commands.length === 0 || oldPath.commands.length === 1 && oldPath.commands[0] === SHAPE_MOVE_TO)) { + return; + } + var path = this._currentPath = new ShapePath(null, null); + this._paths.push(path); + if (oldPath) { + path.fillStyle = oldPath.fillStyle; + path.lineStyle = oldPath.lineStyle; + path.fillRule = oldPath.fillRule; + } + }, + _drawPathObject: function (path) { + if (path.__class__ === 'flash.display.GraphicsPath') + this.drawPath(path.commands, path.data, path.winding); + else if (path.__class__ === 'flash.display.GraphicsTrianglePath') + this.drawTriangles(path.vertices, path.indices, path.uvtData, path.culling); + }, + draw: function (ctx, clip, ratio, colorTransform) { + var paths = this._paths; + for (var i = 0; i < paths.length; i++) { + paths[i].draw(ctx, clip, ratio, colorTransform); + } + }, + beginFill: function (color, alpha) { + if (alpha === undefined) + alpha = 1; + this.beginPath(); + this._currentPath.fillStyle = alpha ? { + style: rgbIntAlphaToStr(color, alpha) + } : null; + }, + beginGradientFill: function (type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPos) { + var style = createGradientStyle(type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPos); + this.beginPath(); + this._currentPath.fillStyle = style; + }, + beginBitmapFill: function (bitmap, matrix, repeat, smooth) { + this.beginPath(); + repeat = repeat !== false; + this._currentPath.fillStyle = createPatternStyle(bitmap, matrix, repeat, !(!smooth)); + }, + clear: function () { + this._invalidate(); + this._paths = []; + this._currentPath = null; + this.beginPath(); + }, + copyFrom: function (sourceGraphics) { + notImplemented('Graphics#copyFrom'); + }, + cubicCurveTo: function (cp1x, cp1y, cp2x, cp2y, x, y) { + this._invalidate(); + this._currentPath.cubicCurveTo(cp1x * 20 | 0, cp1y * 20 | 0, cp2x * 20 | 0, cp2y * 20 | 0, x * 20 | 0, y * 20 | 0); + }, + curveTo: function (cpx, cpy, x, y) { + this._invalidate(); + this._currentPath.curveTo(cpx * 20 | 0, cpy * 20 | 0, x * 20 | 0, y * 20 | 0); + }, + drawCircle: function (x, y, radius) { + var radius2 = radius * 2; + this.drawRoundRect(x - radius, y - radius, radius2, radius2, radius2, radius2); + }, + drawEllipse: function (x, y, width, height) { + this.drawRoundRect(x, y, width, height, width, height); + }, + drawPath: function (commands, data, winding) { + this._invalidate(); + this.beginPath(); + this._currentPath.fillRule = winding || GRAPHICS_PATH_WINDING_EVEN_ODD; + this._currentPath.commands = commands; + this._currentPath.data = data; + }, + drawRect: function (x, y, w, h) { + if (isNaN(w + h)) + throwError('ArgumentError', Errors.InvalidParamError); + this._invalidate(); + this._currentPath.rect(x * 20 | 0, y * 20 | 0, w * 20 | 0, h * 20 | 0); + }, + drawRoundRect: function (x, y, w, h, ellipseWidth, ellipseHeight) { + if (isNaN(w + h + ellipseWidth) || ellipseHeight !== undefined && isNaN(ellipseHeight)) { + throwError('ArgumentError', Errors.InvalidParamError); + } + this._invalidate(); + if (ellipseHeight === undefined) { + ellipseHeight = ellipseWidth; + } + x = x * 20 | 0; + y = y * 20 | 0; + w = w * 20 | 0; + h = h * 20 | 0; + if (!ellipseHeight || !ellipseWidth) { + this._currentPath.rect(x, y, w, h); + return; + } + var radiusX = ellipseWidth / 2 * 20 | 0; + var radiusY = ellipseHeight / 2 * 20 | 0; + var hw = w / 2 | 0; + var hh = h / 2 | 0; + if (radiusX > hw) { + radiusX = hw; + } + if (radiusY > hh) { + radiusY = hh; + } + if (hw === radiusX && hh === radiusY) { + if (radiusX === radiusY) + this._currentPath.circle(x + radiusX, y + radiusY, radiusX); + else + this._currentPath.ellipse(x + radiusX, y + radiusY, radiusX, radiusY); + return; + } + var right = x + w; + var bottom = y + h; + var xlw = x + radiusX; + var xrw = right - radiusX; + var ytw = y + radiusY; + var ybw = bottom - radiusY; + this._currentPath.moveTo(right, ybw); + this._currentPath.curveTo(right, bottom, xrw, bottom); + this._currentPath.lineTo(xlw, bottom); + this._currentPath.curveTo(x, bottom, x, ybw); + this._currentPath.lineTo(x, ytw); + this._currentPath.curveTo(x, y, xlw, y); + this._currentPath.lineTo(xrw, y); + this._currentPath.curveTo(right, y, right, ytw); + this._currentPath.lineTo(right, ybw); + }, + drawRoundRectComplex: function (x, y, w, h, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius) { + if (isNaN(w + h + topLeftRadius + topRightRadius + bottomLeftRadius + bottomRightRadius)) { + throwError('ArgumentError', Errors.InvalidParamError); + } + this._invalidate(); + x = x * 20 | 0; + y = y * 20 | 0; + w = w * 20 | 0; + h = h * 20 | 0; + if (!topLeftRadius && !topRightRadius && !bottomLeftRadius && !bottomRightRadius) { + this._currentPath.rect(x, y, w, h); + return; + } + topLeftRadius = topLeftRadius * 20 | 0; + topRightRadius = topRightRadius * 20 | 0; + bottomLeftRadius = bottomLeftRadius * 20 | 0; + bottomRightRadius = bottomRightRadius * 20 | 0; + var right = x + w; + var bottom = y + h; + var xtl = x + topLeftRadius; + this._currentPath.moveTo(right, bottom - bottomRightRadius); + this._currentPath.curveTo(right, bottom, right - bottomRightRadius, bottom); + this._currentPath.lineTo(x + bottomLeftRadius, bottom); + this._currentPath.curveTo(x, bottom, x, bottom - bottomLeftRadius); + this._currentPath.lineTo(x, y + topLeftRadius); + this._currentPath.curveTo(x, y, xtl, y); + this._currentPath.lineTo(right - topRightRadius, y); + this._currentPath.curveTo(right, y, right, y + topRightRadius); + this._currentPath.lineTo(right, bottom - bottomRightRadius); + }, + drawTriangles: function (vertices, indices, uvtData, cullingStr) { + if (vertices === null || vertices.length === 0) { + return; + } + var numVertices = vertices.length / 2; + var numTriangles = 0; + if (indices) { + if (indices.length % 3) { + throwError('ArgumentError', Errors.InvalidParamError); + } else { + numTriangles = indices.length / 3; + } + } else { + if (vertices.length % 6) { + throwError('ArgumentError', Errors.InvalidParamError); + } else { + numTriangles = vertices.length / 6; + } + } + var numStrides = 0; + if (uvtData) { + if (uvtData.length == numVertices * 2) { + numStrides = 2; + } else if (uvtData.length == numVertices * 3) { + numStrides = 3; + } else { + throwError('ArgumentError', Errors.InvalidParamError); + } + } + var culling = 0; + if (cullingStr === 'none') { + culling = 0; + } else if (cullingStr === 'negative') { + culling = -1; + } else if (cullingStr === 'positive') { + culling = 1; + } else { + throwError('ArgumentError', Errors.InvalidEnumError, 'culling'); + } + notImplemented('Graphics#drawTriangles'); + }, + endFill: function () { + this.beginPath(); + this._currentPath.fillStyle = null; + }, + lineBitmapStyle: function (bitmap, matrix, repeat, smooth) { + this.beginPath(); + this._currentPath.lineStyle = createPatternStyle(bitmap, matrix, repeat, smooth); + }, + lineGradientStyle: function (type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPos) { + var style = createGradientStyle(type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPos); + this.beginPath(); + this._currentPath.lineStyle = style; + }, + lineStyle: function (width, color, alpha, pxHinting, scale, cap, joint, mlimit) { + this.beginPath(); + if (width) { + if (alpha === undefined) + alpha = 1; + if (mlimit === undefined) + mlimit = 3; + this._currentPath.lineStyle = { + style: rgbIntAlphaToStr(color, alpha), + lineCap: cap || 'round', + lineJoin: cap || 'round', + width: width * 20 | 0, + miterLimit: mlimit * 2 + }; + } else { + this._currentPath.lineStyle = null; + } + }, + lineTo: function (x, y) { + this._invalidate(); + this._currentPath.lineTo(x * 20 | 0, y * 20 | 0); + }, + moveTo: function (x, y) { + this._currentPath.moveTo(x * 20 | 0, y * 20 | 0); + }, + _getBounds: function (includeStroke) { + var bbox = includeStroke ? this.strokeBbox : this.bbox; + if (bbox) { + return bbox; + } + var subpaths = this._paths; + var xMins = [], yMins = [], xMaxs = [], yMaxs = []; + for (var i = 0, n = subpaths.length; i < n; i++) { + var path = subpaths[i]; + if (path.commands.length) { + var b = path.getBounds(includeStroke); + if (b) { + xMins.push(b.xMin); + yMins.push(b.yMin); + xMaxs.push(b.xMax); + yMaxs.push(b.yMax); + } + } + } + if (xMins.length === 0) { + bbox = { + xMin: 0, + yMin: 0, + xMax: 0, + yMax: 0 + }; + } else { + bbox = { + xMin: Math.min.apply(Math, xMins), + yMin: Math.min.apply(Math, yMins), + xMax: Math.max.apply(Math, xMaxs), + yMax: Math.max.apply(Math, yMaxs) + }; + } + if (includeStroke) { + this.strokeBbox = bbox; + } else { + this.bbox = bbox; + } + return bbox; + } + }; + def.__glue__ = { + native: { + instance: { + beginFill: def.beginFill, + beginGradientFill: def.beginGradientFill, + beginBitmapFill: def.beginBitmapFill, + beginFillObject: def.beginFillObject, + beginStrokeObject: def.beginStrokeObject, + clear: def.clear, + copyFrom: def.copyFrom, + cubicCurveTo: def.cubicCurveTo, + curveTo: def.curveTo, + drawCircle: def.drawCircle, + drawEllipse: def.drawEllipse, + drawPath: def.drawPath, + drawRect: def.drawRect, + drawRoundRect: def.drawRoundRect, + drawRoundRectComplex: def.drawRoundRectComplex, + drawTriangles: def.drawTriangles, + endFill: def.endFill, + lineBitmapStyle: def.lineBitmapStyle, + lineGradientStyle: def.lineGradientStyle, + lineStyle: def.lineStyle, + moveTo: def.moveTo, + lineTo: def.lineTo + } + } + }; + return def; + }.call(this); +function createPatternStyle(bitmap, matrix, repeat, smooth) { + var repeatStyle = repeat === false ? 'no-repeat' : 'repeat'; + var pattern = factoryCtx.createPattern(bitmap._drawable, repeatStyle); + var transform = matrix ? { + a: matrix.a, + b: matrix.b, + c: matrix.c, + d: matrix.d, + e: matrix.tx, + f: matrix.ty + } : { + a: 1, + b: 0, + c: 0, + d: 1, + e: 0, + f: 0 + }; + return { + style: pattern, + transform: transform, + smooth: smooth + }; +} +function createGradientStyle(type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPos) { + type === null || type === undefined && throwError('TypeError', Errors.NullPointerError, 'type'); + colors === null || type === undefined && throwError('TypeError', Errors.NullPointerError, 'colors'); + if (!(type === 'linear' || type === 'radial')) { + throwError('ArgumentError', Errors.InvalidEnumError, 'type'); + } + var colorStops = []; + for (var i = 0, n = colors.length; i < n; i++) { + colorStops.push({ + ratio: ratios[i] / 255, + color: rgbIntAlphaToStr(colors[i], alphas[i]) + }); + } + var gradientConstructor; + if (type === 'linear') { + gradientConstructor = buildLinearGradientFactory(colorStops); + } else { + gradientConstructor = buildRadialGradientFactory(focalPos || 0, colorStops); + } + var scale = 819.2; + var transform = matrix ? { + a: scale * matrix.a, + b: scale * matrix.b, + c: scale * matrix.c, + d: scale * matrix.d, + e: matrix.tx, + f: matrix.ty + } : { + a: scale, + b: 0, + c: 0, + d: scale, + e: 0, + f: 0 + }; + return { + style: gradientConstructor, + transform: transform + }; +} +function drawGraphicsData(data) { + if (data === null) { + return; + } + for (var i = 0; i < data.length; i++) { + var item = data[i]; + if (flash.display.IGraphicsPath.class.isInstanceOf(item)) { + this._drawPathObject(item); + } else if (flash.display.IGraphicsStroke.class.isInstanceOf(item)) { + this.beginStrokeObject(item); + } else if (flash.display.IGraphicsFill.class.isInstanceOf(item)) { + this.beginFillObject(item); + } + } +} +var InteractiveObjectDefinition = function () { + var def = { + initialize: function () { + this._contextMenu = null; + this._doubleClickEnabled = false; + this._focusRect = null; + this._mouseEnabled = true; + this._tabEnabled = false; + }, + get accessibilityImplementation() { + return null; + }, + set accessibilityImplementation(val) { + somewhatImplemented('accessibilityImplementation'); + }, + get contextMenu() { + somewhatImplemented('contextMenu'); + return this._contextMenu; + }, + set contextMenu(val) { + somewhatImplemented('contextMenu'); + this._contextMenu = val; + }, + get doubleClickEnabled() { + return this._doubleClickEnabled; + }, + set doubleClickEnabled(val) { + this._doubleClickEnabled = val; + }, + get focusRect() { + return this._focusRect; + }, + set focusRect(val) { + this._focusRect = val; + }, + get mouseEnabled() { + return this._mouseEnabled; + }, + set mouseEnabled(val) { + this._mouseEnabled = val; + }, + get needsSoftKeyboard() { + return false; + }, + set needsSoftKeyboard(val) { + notImplemented(); + }, + get softKeyboardInputAreaOfInterest() { + return null; + }, + set softKeyboardInputAreaOfInterest(val) { + notImplemented(); + }, + get tabEnabled() { + return this._tabEnabled; + }, + set tabEnabled(val) { + var old = this._tabEnabled; + this._tabEnabled = val; + if (old !== val) { + var Event = flash.events.Event; + this._dispatchEvent(new Event('tabEnabledChange', false, false)); + } + }, + requestSoftKeyboard: function () { + notImplemented(); + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + tabEnabled: desc(def, 'tabEnabled'), + tabIndex: { + get: function tabIndex() { + return this._tabIndex; + }, + set: function tabIndex(index) { + this._tabIndex = index; + } + }, + focusRect: desc(def, 'focusRect'), + mouseEnabled: desc(def, 'mouseEnabled'), + doubleClickEnabled: desc(def, 'doubleClickEnabled'), + accessibilityImplementation: desc(def, 'accessibilityImplementation'), + softKeyboardInputAreaOfInterest: desc(def, 'softKeyboardInputAreaOfInterest'), + needsSoftKeyboard: desc(def, 'needsSoftKeyboard'), + contextMenu: desc(def, 'contextMenu'), + requestSoftKeyboard: def.requestSoftKeyboard + } + } + }; + return def; + }.call(this); +var $RELEASE = false; +var LoaderDefinition = function () { + var WORKERS_ENABLED = true; + var LOADER_PATH = true ? 'shumway-worker.js' : 'swf/resourceloader.js'; + var head = document.head; + head.insertBefore(document.createElement('style'), head.firstChild); + var style = document.styleSheets[0]; + var def = { + __class__: 'flash.display.Loader', + initialize: function () { + this._contentLoaderInfo = new flash.display.LoaderInfo(); + this._contentLoaderInfo._loader = this; + this._dictionary = {}; + this._dictionaryResolved = {}; + this._displayList = null; + this._timeline = []; + this._lastPromise = null; + this._uncaughtErrorEvents = null; + this._worker = null; + var abc = AVM2.currentAbc(); + if (abc && abc.env.loader) { + this._contentLoaderInfo._loaderURL = abc.env.loader._contentLoaderInfo._url; + } + }, + _commitData: function (data) { + switch (data.command) { + case 'init': + this._init(data.result); + break; + case 'progress': + this._updateProgress(data.result); + break; + case 'complete': + var frameConstructed = new Promise(function (resolve) { + avm2.systemDomain.onMessage.register('frameConstructed', function waitForFrame(type) { + if (type === 'frameConstructed') { + resolve(); + avm2.systemDomain.onMessage.unregister('frameConstructed', waitForFrame); + } + }); + }); + this._contentLoaderInfo._dispatchEvent('parsed'); + Promise.all([ + frameConstructed, + this._lastPromise + ]).then(function () { + this._content._complete = true; + this._contentLoaderInfo._dispatchEvent('complete'); + }.bind(this)); + var stats = data.stats; + if (stats) { + TelemetryService.reportTelemetry(stats); + } + this._worker && this._worker.terminate(); + break; + case 'empty': + this._lastPromise = Promise.resolve(); + break; + case 'error': + this._contentLoaderInfo._dispatchEvent('ioError', flash.events.IOErrorEvent); + break; + default: + if (data.id === 0) + break; + if (data.isSymbol) + this._commitSymbol(data); + else if (data.type === 'frame') + this._commitFrame(data); + else if (data.type === 'image') + this._commitImage(data); + break; + } + }, + _updateProgress: function (state) { + var loaderInfo = this._contentLoaderInfo; + loaderInfo._bytesLoaded = state.bytesLoaded || 0; + loaderInfo._bytesTotal = state.bytesTotal || 0; + var event = new flash.events.ProgressEvent('progress', false, false, loaderInfo._bytesLoaded, loaderInfo._bytesTotal); + loaderInfo._dispatchEvent(event); + }, + _buildFrame: function (currentDisplayList, timeline, promiseQueue, frame, frameNum) { + var loader = this; + var dictionary = loader._dictionary; + var dictionaryResolved = loader._dictionaryResolved; + var displayList = {}; + var depths = []; + var cmds = frame.depths; + if (currentDisplayList) { + var currentDepths = currentDisplayList.depths; + for (var i = 0; i < currentDepths.length; i++) { + var depth = currentDepths[i]; + if (cmds[depth] === null) { + continue; + } + displayList[depth] = currentDisplayList[depth]; + depths.push(depth); + } + } + for (var depth in cmds) { + var cmd = cmds[depth]; + if (!cmd) { + continue; + } + if (cmd.move) { + var oldCmd = cmd; + cmd = cloneObject(currentDisplayList[depth]); + for (var prop in oldCmd) { + var val = oldCmd[prop]; + if (val) { + cmd[prop] = val; + } + } + } + if (cmd.symbolId) { + var itemPromise = dictionary[cmd.symbolId]; + if (itemPromise && !dictionaryResolved[cmd.symbolId]) { + promiseQueue.push(itemPromise); + } + cmd = cloneObject(cmd); + Object.defineProperty(cmd, 'symbolInfo', { + get: function (dictionaryResolved, symbolId) { + return function () { + return dictionaryResolved[symbolId]; + }; + }(dictionaryResolved, cmd.symbolId) + }); + } + if (!displayList[depth]) { + depths.push(depth); + } + displayList[depth] = cmd; + } + depths.sort(sortNumeric); + displayList.depths = depths; + var i = frame.repeat; + while (i--) { + timeline.push(displayList); + } + return displayList; + }, + _commitFrame: function (frame) { + var abcBlocks = frame.abcBlocks; + var actionBlocks = frame.actionBlocks; + var initActionBlocks = frame.initActionBlocks; + var exports = frame.exports; + var symbolClasses = frame.symbolClasses; + var sceneData = frame.sceneData; + var loader = this; + var dictionary = loader._dictionary; + var loaderInfo = loader._contentLoaderInfo; + var timeline = loader._timeline; + var frameNum = timeline.length + 1; + var framePromiseResolve; + var framePromise = new Promise(function (resolve) { + framePromiseResolve = resolve; + }); + var labelName = frame.labelName; + var prevPromise = this._lastPromise; + this._lastPromise = framePromise; + var promiseQueue = [ + prevPromise + ]; + this._displayList = this._buildFrame(this._displayList, timeline, promiseQueue, frame, frameNum); + var framesLoaded = timeline.length; + if (frame.bgcolor) + loaderInfo._backgroundColor = frame.bgcolor; + else if (isNullOrUndefined(loaderInfo._backgroundColor)) + loaderInfo._backgroundColor = { + red: 255, + green: 255, + blue: 255, + alpha: 255 + }; + Promise.all(promiseQueue).then(function () { + if (abcBlocks && loader._isAvm2Enabled) { + var appDomain = avm2.applicationDomain; + for (var i = 0, n = abcBlocks.length; i < n; i++) { + var abc = new AbcFile(abcBlocks[i].data, 'abc_block_' + i); + abc.env.loader = loader; + if (abcBlocks[i].flags) { + appDomain.loadAbc(abc); + } else { + appDomain.executeAbc(abc); + } + } + } + if (symbolClasses && loader._isAvm2Enabled) { + var symbolClassesPromises = []; + for (var i = 0, n = symbolClasses.length; i < n; i++) { + var asset = symbolClasses[i]; + var symbolPromise = dictionary[asset.symbolId]; + if (!symbolPromise) + continue; + symbolPromise.then(function (className) { + return function symbolPromiseResolved(symbolInfo) { + symbolInfo.className = className; + avm2.applicationDomain.getClass(className).setSymbol(symbolInfo.props); + }; + }(asset.className)); + symbolClassesPromises.push(symbolPromise); + } + return Promise.all(symbolClassesPromises); + } + if (exports && !loader._isAvm2Enabled) { + var exportPromises = []; + for (var i = 0, n = exports.length; i < n; i++) { + var asset = exports[i]; + var symbolPromise = dictionary[asset.symbolId]; + if (!symbolPromise) + continue; + symbolPromise.then(function (className) { + return function symbolPromiseResolved(symbolInfo) { + loader._avm1Context.addAsset(className, symbolInfo.props); + }; + }(asset.className)); + exportPromises.push(symbolPromise); + } + return Promise.all(exportPromises); + } + }).then(function () { + var root = loader._content; + var labelMap; + if (!root) { + var parent = loader._parent; + true; + var rootInfo = loader._dictionaryResolved[0]; + var rootClass = avm2.applicationDomain.getClass(rootInfo.className); + root = rootClass.createAsSymbol({ + framesLoaded: framesLoaded, + loader: loader, + parent: parent || loader, + index: parent ? 0 : -1, + level: parent ? 0 : -1, + timeline: timeline, + totalFrames: rootInfo.props.totalFrames, + stage: loader._stage, + complete: frame.complete + }); + if (!loader._isAvm2Enabled) { + var avm1Context = loader._avm1Context; + var _root = root; + if (parent && parent !== loader._stage) { + var parentLoader = parent.loaderInfo._loader; + while (parentLoader._parent && parentLoader._parent !== loader._stage) { + parentLoader = parentLoader._parent.loaderInfo._loader; + } + if (parentLoader._isAvm2Enabled) { + somewhatImplemented('AVM1Movie'); + this._worker && this._worker.terminate(); + return; + } + _root = parentLoader._content; + } + var as2Object = _root._getAS2Object(); + avm1Context.globals.asSetPublicProperty('_root', as2Object); + avm1Context.globals.asSetPublicProperty('_level0', as2Object); + avm1Context.globals.asSetPublicProperty('_level1', as2Object); + var parameters = loader.loaderInfo._parameters; + for (var paramName in parameters) { + if (!(paramName in as2Object)) { + as2Object[paramName] = parameters[paramName]; + } + } + } + var isRootMovie = parent && parent == loader._stage && loader._stage._children.length === 0; + if (isRootMovie) { + parent._frameRate = loaderInfo._frameRate; + parent._stageHeight = loaderInfo._height; + parent._stageWidth = loaderInfo._width; + parent._root = root; + parent._setup(); + } else { + loader._children.push(root); + } + var labels; + labelMap = root.symbol.labelMap = createEmptyObject(); + if (sceneData) { + var scenes = []; + var startFrame; + var endFrame = root.symbol.totalFrames - 1; + var sd = sceneData.scenes; + var ld = sceneData.labels; + var i = sd.length; + while (i--) { + var s = sd[i]; + startFrame = s.offset; + labels = []; + var j = ld.length; + while (j--) { + var lbl = ld[j]; + if (lbl.frame >= startFrame && lbl.frame <= endFrame) { + labelMap[lbl.name] = lbl.frame + 1; + labels.unshift(new flash.display.FrameLabel(lbl.name, lbl.frame - startFrame + 1)); + } + } + var scene = new flash.display.Scene(s.name, labels, endFrame - startFrame + 1); + scene._startFrame = startFrame + 1; + scene._endFrame = endFrame + 1; + scenes.unshift(scene); + endFrame = startFrame - 1; + } + root.symbol.scenes = scenes; + } else { + labels = []; + if (labelName) { + labelMap[labelName] = frameNum; + labels.push(new flash.display.FrameLabel(labelName, frameNum)); + } + var scene = new flash.display.Scene('Scene 1', labels, root.symbol.totalFrames); + scene._startFrame = 1; + scene._endFrame = root.symbol.totalFrames; + root.symbol.scenes = [ + scene + ]; + } + if (loader._stage) { + loader._stage._children[0] = root; + } + rootClass.instanceConstructor.call(root); + loader._content = root; + } else { + root._framesLoaded = framesLoaded; + if (labelName && root._labelMap) { + if (root._labelMap[labelName] === undefined) { + root._labelMap[labelName] = frameNum; + for (var i = 0, n = root.symbol.scenes.length; i < n; i++) { + var scene = root.symbol.scenes[i]; + if (frameNum >= scene._startFrame && frameNum <= scene._endFrame) { + scene.labels.push(new flash.display.FrameLabel(labelName, frameNum - scene._startFrame)); + break; + } + } + } + } + } + if (frame.startSounds) { + root._registerStartSounds(frameNum, frame.startSounds); + } + if (frame.soundStream) { + root._initSoundStream(frame.soundStream); + } + if (frame.soundStreamBlock) { + root._addSoundStreamBlock(frameNum, frame.soundStreamBlock); + } + if (!loader._isAvm2Enabled) { + var avm1Context = loader._avm1Context; + if (initActionBlocks) { + for (var i = 0; i < initActionBlocks.length; i++) { + var spriteId = initActionBlocks[i].spriteId; + var actionsData = initActionBlocks[i].actionsData; + root.addFrameScript(frameNum - 1, function (actionsData, spriteId, state) { + if (state.executed) + return; + state.executed = true; + return executeActions(actionsData, avm1Context, this._getAS2Object()); + }.bind(root, actionsData, spriteId, { + executed: false + })); + } + } + if (actionBlocks) { + for (var i = 0; i < actionBlocks.length; i++) { + var block = actionBlocks[i]; + root.addFrameScript(frameNum - 1, function (block) { + return function () { + return executeActions(block, avm1Context, this._getAS2Object()); + }; + }(block)); + } + } + } + if (frameNum === 1) + loaderInfo._dispatchEvent(new flash.events.Event('init', false, false)); + framePromiseResolve(frame); + }); + }, + _commitImage: function (imageInfo) { + var loader = this; + var imgPromiseResolve; + var imgPromise = this._lastPromise = new Promise(function (resolve) { + imgPromiseResolve = resolve; + }); + var img = new Image(); + imageInfo.props.img = img; + img.onload = function () { + var Bitmap = avm2.systemDomain.getClass('flash.display.Bitmap'); + var BitmapData = avm2.systemDomain.getClass('flash.display.BitmapData'); + var props = imageInfo.props; + props.parent = loader._parent; + props.stage = loader._stage; + props.skipCopyToCanvas = true; + var bitmapData = BitmapData.createAsSymbol(props); + BitmapData.instanceConstructor.call(bitmapData, 0, 0, true, 4294967295); + var image = Bitmap.createAsSymbol(bitmapData); + Bitmap.instanceConstructor.call(image, bitmapData); + image._parent = loader; + loader._children.push(image); + loader._invalidateBounds(); + loader._content = image; + imgPromiseResolve(imageInfo); + var loaderInfo = loader._contentLoaderInfo; + loaderInfo._width = image.width; + loaderInfo._height = image.height; + loaderInfo._dispatchEvent('init'); + }; + img.src = URL.createObjectURL(imageInfo.data); + imageInfo.data = null; + }, + _commitSymbol: function (symbol) { + var dictionary = this._dictionary; + var dictionaryResolved = this._dictionaryResolved; + if ('updates' in symbol) { + dictionary[symbol.id].then(function (s) { + for (var i in symbol.updates) { + s.props[i] = symbol.updates[i]; + } + }); + return; + } + var className = 'flash.display.DisplayObject'; + var dependencies = symbol.require; + var promiseQueue = []; + var props = { + symbolId: symbol.id, + loader: this + }; + var symbolPromiseResolve; + var symbolPromise = new Promise(function (resolve) { + symbolPromiseResolve = resolve; + }); + if (dependencies && dependencies.length) { + for (var i = 0, n = dependencies.length; i < n; i++) { + var dependencyId = dependencies[i]; + var dependencyPromise = dictionary[dependencyId]; + if (dependencyPromise && !dictionaryResolved[dependencyId]) + promiseQueue.push(dependencyPromise); + } + } + switch (symbol.type) { + case 'button': + var states = {}; + for (var stateName in symbol.states) { + var characters = []; + var displayList = {}; + var state = symbol.states[stateName]; + var depths = Object.keys(state); + for (var i = 0; i < depths.length; i++) { + var depth = depths[i]; + var cmd = state[depth]; + var characterPromise = dictionary[cmd.symbolId]; + if (characterPromise && !dictionaryResolved[cmd.symbolId]) { + promiseQueue.push(characterPromise); + } + characters.push(characterPromise); + displayList[depth] = Object.create(cmd, { + symbolInfo: { + get: function (dictionaryResolved, symbolId) { + return function () { + return dictionaryResolved[symbolId]; + }; + }(dictionaryResolved, cmd.symbolId) + } + }); + } + depths.sort(sortNumeric); + displayList.depths = depths; + states[stateName] = { + className: 'flash.display.Sprite', + props: { + loader: this, + timeline: [ + displayList + ] + } + }; + } + className = 'flash.display.SimpleButton'; + props.states = states; + props.buttonActions = symbol.buttonActions; + break; + case 'font': + var charset = fromCharCode.apply(null, symbol.codes); + if (charset) { + style.insertRule('@font-face{font-family:"' + symbol.uniqueName + '";' + 'src:url(data:font/opentype;base64,' + btoa(symbol.data) + ')' + '}', style.cssRules.length); + if (!/Mozilla\/5.0.*?rv:(\d+).*? Gecko/.test(window.navigator.userAgent)) { + var testDiv = document.createElement('div'); + testDiv.setAttribute('style', 'position: absolute; top: 0; right: 0;visibility: hidden; z-index: -500;font-family:"' + symbol.uniqueName + '";'); + testDiv.textContent = 'font test'; + document.body.appendChild(testDiv); + var fontPromise = new Promise(function (resolve) { + setTimeout(function () { + resolve(); + document.body.removeChild(testDiv); + }, 200); + }); + promiseQueue.push(fontPromise); + } + } + className = 'flash.text.Font'; + props.name = symbol.name; + props.uniqueName = symbol.uniqueName; + props.charset = symbol.charset; + props.bold = symbol.bold; + props.italic = symbol.italic; + props.metrics = symbol.metrics; + this._registerFont(className, props); + break; + case 'image': + var img = new Image(); + var imgPromiseResolve; + var imgPromise = new Promise(function (resolve) { + imgPromiseResolve = resolve; + }); + img.onload = function () { + if (symbol.mask) { + var maskCanvas = document.createElement('canvas'); + maskCanvas.width = symbol.width; + maskCanvas.height = symbol.height; + var maskContext = maskCanvas.getContext('2d'); + maskContext.drawImage(img, 0, 0); + var maskImageData = maskContext.getImageData(0, 0, symbol.width, symbol.height); + var maskImageDataBytes = maskImageData.data; + var symbolMaskBytes = symbol.mask; + var length = maskImageData.width * maskImageData.height; + for (var i = 0, j = 3; i < length; i++, j += 4) { + maskImageDataBytes[j] = symbolMaskBytes[i]; + } + maskContext.putImageData(maskImageData, 0, 0); + props.img = maskCanvas; + } + imgPromiseResolve(); + }; + img.src = URL.createObjectURL(symbol.data); + promiseQueue.push(imgPromise); + className = 'flash.display.Bitmap'; + props.img = img; + props.width = symbol.width; + props.height = symbol.height; + break; + case 'label': + var drawFn = new Function('c,r,ct', symbol.data); + className = 'flash.text.StaticText'; + props.bbox = symbol.bbox; + props.draw = drawFn; + break; + case 'text': + props.bbox = symbol.bbox; + props.html = symbol.html; + if (symbol.type === 'label') { + className = 'flash.text.StaticText'; + } else { + className = 'flash.text.TextField'; + props.tag = symbol.tag; + props.variableName = symbol.variableName; + } + break; + case 'shape': + className = symbol.morph ? 'flash.display.MorphShape' : 'flash.display.Shape'; + props.bbox = symbol.bbox; + props.strokeBbox = symbol.strokeBbox; + props.paths = symbol.paths; + props.dictionaryResolved = dictionaryResolved; + break; + case 'sound': + if (!symbol.pcm && !PLAY_USING_AUDIO_TAG) { + var decodePromiseResolve; + var decodePromise = new Promise(function (resolve) { + decodePromiseResolve = resolve; + }); + MP3DecoderSession.processAll(symbol.packaged.data, function (props, pcm, id3tags, error) { + props.pcm = pcm || new Uint8Array(0); + decodePromiseResolve(); + if (error) { + console.error('ERROR: ' + error); + } + }.bind(null, props)); + promiseQueue.push(decodePromise); + } + className = 'flash.media.Sound'; + props.sampleRate = symbol.sampleRate; + props.channels = symbol.channels; + props.pcm = symbol.pcm; + props.packaged = symbol.packaged; + break; + case 'binary': + props.data = symbol.data; + break; + case 'sprite': + var displayList = null; + var frameCount = symbol.frameCount; + var labelMap = {}; + var frameNum = 1; + var frames = symbol.frames; + var timeline = []; + var startSoundRegistrations = []; + for (var i = 0, n = frames.length; i < n; i++) { + var frame = frames[i]; + var frameNum = timeline.length + 1; + if (frame.labelName) { + labelMap[frame.labelName] = frameNum; + } + if (frame.startSounds) { + startSoundRegistrations[frameNum] = frame.startSounds; + for (var j = 0; j < frame.startSounds.length; j++) { + var soundId = frame.startSounds[j].soundId; + var itemPromise = dictionary[soundId]; + if (itemPromise && !dictionaryResolved[soundId]) { + promiseQueue.push(itemPromise); + } + } + } + displayList = this._buildFrame(displayList, timeline, promiseQueue, frame, frameNum); + } + var frameScripts = {}; + if (!this._isAvm2Enabled) { + if (symbol.frameScripts) { + var data = symbol.frameScripts; + for (var i = 0; i < data.length; i += 2) { + var frameNum = data[i] + 1; + var block = data[i + 1]; + var script = function (block, loader) { + return function () { + var avm1Context = loader._avm1Context; + return executeActions(block, avm1Context, this._getAS2Object()); + }; + }(block, this); + if (!frameScripts[frameNum]) + frameScripts[frameNum] = [ + script + ]; + else + frameScripts[frameNum].push(script); + } + } + } + className = 'flash.display.MovieClip'; + props.timeline = timeline; + props.framesLoaded = frameCount; + props.labelMap = labelMap; + props.frameScripts = frameScripts; + props.totalFrames = frameCount; + props.startSoundRegistrations = startSoundRegistrations; + break; + } + dictionary[symbol.id] = symbolPromise; + Promise.all(promiseQueue).then(function () { + var symbolInfo = { + className: className, + props: props + }; + dictionaryResolved[symbol.id] = symbolInfo; + symbolPromiseResolve(symbolInfo); + }); + }, + _registerFont: function (className, props) { + this._vmPromise.then(function () { + var fontClass = avm2.applicationDomain.getClass(className); + var font = fontClass.createAsSymbol(props); + fontClass.instanceConstructor.call(font); + }); + }, + _init: function (info) { + var loader = this; + var loaderInfo = loader._contentLoaderInfo; + loaderInfo._swfVersion = info.swfVersion; + var bbox = info.bbox; + loaderInfo._width = bbox.xMax - bbox.xMin; + loaderInfo._height = bbox.yMax - bbox.yMin; + loaderInfo._frameRate = info.frameRate; + var vmPromiseResolve, vmPromiseReject; + var vmPromise = new Promise(function (resolve, reject) { + vmPromiseResolve = resolve; + vmPromiseReject = reject; + }); + vmPromise.resolve = vmPromiseResolve; + vmPromise.reject = vmPromiseReject; + var documentPromise = new Promise(function (resolve) { + vmPromise.then(function () { + var rootInfo = { + className: 'flash.display.MovieClip', + props: { + totalFrames: info.frameCount + } + }; + loader._dictionaryResolved[0] = rootInfo; + resolve(rootInfo); + }); + }); + loader._dictionary[0] = documentPromise; + loader._lastPromise = documentPromise; + loader._vmPromise = vmPromise; + loader._isAvm2Enabled = info.fileAttributes.doAbc; + this._setup(); + }, + _load: function (request, checkPolicyFile, applicationDomain, securityDomain, requestedContentParent, parameters, deblockingFilter, allowCodeImport, imageDecodingPolicy) { + if (flash.net.URLRequest.class.isInstanceOf(request)) { + this._contentLoaderInfo._url = request._url; + } + var worker; + if (WORKERS_ENABLED) { + worker = new Worker(SHUMWAY_ROOT + LOADER_PATH); + } else { + worker = new ResourceLoader(window); + } + var loader = this; + loader._worker = worker; + worker.onmessage = function (evt) { + if (evt.data.type === 'exception') { + avm2.exceptions.push({ + source: 'parser', + message: evt.data.message, + stack: evt.data.stack + }); + } else { + loader._commitData(evt.data); + } + }; + if (flash.net.URLRequest.class.isInstanceOf(request)) { + var session = FileLoadingService.createSession(); + session.onprogress = function (data, progress) { + worker.postMessage({ + data: data, + progress: progress + }); + }; + session.onerror = function (error) { + loader._commitData({ + command: 'error', + error: error + }); + }; + session.onopen = function () { + worker.postMessage('pipe:'); + }; + session.onclose = function () { + worker.postMessage({ + data: null + }); + }; + session.open(request._toFileRequest()); + } else { + worker.postMessage(request); + } + }, + _setup: function () { + var loader = this; + var stage = loader._stage; + if (loader._isAvm2Enabled) { + var mouseClass = avm2.systemDomain.getClass('flash.ui.Mouse'); + mouseClass._stage = stage; + loader._vmPromise.resolve(); + return; + } + if (!avm2.loadAVM1) { + loader._vmPromise.reject('AVM1 loader is not found'); + return; + } + var loaded = function () { + var loaderInfo = loader._contentLoaderInfo; + var avm1Context = new AS2Context(loaderInfo._swfVersion); + avm1Context.stage = stage; + loader._avm1Context = avm1Context; + avm1lib.AS2Key.class.$bind(stage); + avm1lib.AS2Mouse.class.$bind(stage); + stage._addEventListener('frameConstructed', avm1Context.flushPendingScripts.bind(avm1Context), false, Number.MAX_VALUE); + loader._vmPromise.resolve(); + }; + if (avm2.isAVM1Loaded) { + if (AS2Context.instance) { + loader._avm1Context = AS2Context.instance; + loader._vmPromise.resolve(); + } else { + loaded(); + } + } else { + avm2.isAVM1Loaded = true; + avm2.loadAVM1(loaded); + } + }, + get contentLoaderInfo() { + return this._contentLoaderInfo; + }, + get content() { + somewhatImplemented('Loader.content'); + return this._content; + } + }; + def.__glue__ = { + native: { + instance: { + content: Object.getOwnPropertyDescriptor(def, 'content'), + contentLoaderInfo: Object.getOwnPropertyDescriptor(def, 'contentLoaderInfo'), + _getJPEGLoaderContextdeblockingfilter: function (context) { + return 0; + }, + _load: def._load, + _loadBytes: function _loadBytes(bytes, checkPolicyFile, applicationDomain, securityDomain, requestedContentParent, parameters, deblockingFilter, allowLoadBytesCodeExecution, imageDecodingPolicy) { + this._load(bytes.a, checkPolicyFile, applicationDomain, securityDomain, requestedContentParent, parameters, deblockingFilter, allowLoadBytesCodeExecution, imageDecodingPolicy); + }, + _unload: function _unload(halt, gc) { + somewhatImplemented('Loader._unload, do we even need to do anything here?'); + }, + _close: function _close() { + somewhatImplemented('Loader._close'); + }, + _getUncaughtErrorEvents: function _getUncaughtErrorEvents() { + somewhatImplemented('Loader._getUncaughtErrorEvents'); + return this._uncaughtErrorEvents; + }, + _setUncaughtErrorEvents: function _setUncaughtErrorEvents(value) { + somewhatImplemented('Loader._setUncaughtErrorEvents'); + this._uncaughtErrorEvents = value; + } + } + } + }; + return def; + }.call(this); +var LoaderInfoDefinition = function () { + function dispatchEvent(event) { + notImplemented('LoaderInfo.dispatchEvent'); + } + return { + __class__: 'flash.display.LoaderInfo', + initialize: function () { + this._actionScriptVersion = null; + this._backgroundColor = null; + this._bytes = null; + this._bytesLoaded = 0; + this._bytesTotal = 0; + this._content = null; + this._contentType = null; + this._frameRate = null; + this._height = null; + this._loader = null; + this._loaderURL = null; + this._swfVersion = null; + this._url = null; + this._width = null; + this._uncaughtErrorEvents = null; + }, + __glue__: { + native: { + static: { + getLoaderInfoByDefinition: function getLoaderInfoByDefinition(object) { + notImplemented('LoaderInfo.getLoaderInfoByDefinition'); + } + }, + instance: { + _getArgs: function _getArgs() { + var params = this._parameters; + var mangled = {}; + for (var k in params) { + mangled[Multiname.getPublicQualifiedName(k)] = params[k]; + } + return mangled; + }, + _getUncaughtErrorEvents: function _getUncaughtErrorEvents() { + somewhatImplemented('Loader._getUncaughtErrorEvents'); + return this._uncaughtErrorEvents; + }, + _setUncaughtErrorEvents: function _setUncaughtErrorEvents(value) { + somewhatImplemented('Loader._setUncaughtErrorEvents'); + this._uncaughtErrorEvents = value; + }, + loaderURL: { + get: function loaderURL() { + return this._loaderURL; + } + }, + url: { + get: function url() { + return this._url; + } + }, + isURLInaccessible: { + get: function isURLInaccessible() { + return this._isURLInaccessible; + } + }, + bytesLoaded: { + get: function bytesLoaded() { + return this._bytesLoaded; + } + }, + bytesTotal: { + get: function bytesTotal() { + return this._bytesTotal; + } + }, + applicationDomain: { + get: function applicationDomain() { + return new flash.system.ApplicationDomain(avm2.applicationDomain); + } + }, + swfVersion: { + get: function swfVersion() { + return this._swfVersion; + } + }, + actionScriptVersion: { + get: function actionScriptVersion() { + return this._actionScriptVersion; + } + }, + frameRate: { + get: function frameRate() { + return this._frameRate; + } + }, + width: { + get: function width() { + return this._width; + } + }, + height: { + get: function height() { + return this._height; + } + }, + contentType: { + get: function contentType() { + return this._contentType; + } + }, + sharedEvents: { + get: function sharedEvents() { + return this._sharedEvents; + } + }, + parentSandboxBridge: { + get: function parentSandboxBridge() { + return this._parentSandboxBridge; + }, + set: function parentSandboxBridge(door) { + this._parentSandboxBridge = door; + } + }, + childSandboxBridge: { + get: function childSandboxBridge() { + return this._childSandboxBridge; + }, + set: function childSandboxBridge(door) { + this._childSandboxBridge = door; + } + }, + sameDomain: { + get: function sameDomain() { + return this._sameDomain; + } + }, + childAllowsParent: { + get: function childAllowsParent() { + return this._childAllowsParent; + } + }, + parentAllowsChild: { + get: function parentAllowsChild() { + return this._parentAllowsChild; + } + }, + loader: { + get: function loader() { + return this._loader; + } + }, + content: { + get: function content() { + return this._loader._content; + } + }, + bytes: { + get: function bytes() { + return this._bytes; + } + } + } + }, + script: { + instance: scriptProperties('public', [ + 'swfVersion', + 'bytesTotal', + 'bytesLoaded', + 'parameters', + 'uncaughtErrorEvent' + ]) + } + } + }; + }.call(this); +var MorphShapeDefinition = function () { + var def = { + __class__: 'flash.display.MorphShape', + initialize: function () { + var graphics = this._graphics = new flash.display.Graphics(); + var s = this.symbol; + if (s && s.paths) { + graphics._paths = s.paths; + graphics.bbox = s.bbox; + graphics.strokeBbox = s.strokeBbox; + if (this._stage && this._stage._quality === 'low' && !graphics._bitmap) + graphics._cacheAsBitmap(this._bbox); + } + } + }; + def.__glue__ = { + native: { + instance: { + graphics: { + get: function () { + return this._graphics; + } + } + } + } + }; + return def; + }.call(this); +var MovieClipDefinition = function () { + var def = { + __class__: 'flash.display.MovieClip', + initialize: function () { + this._playHead = 1; + this._currentFrame = 1; + this._currentFrameLabel = null; + this._currentLabel = null; + this._currentScene = 0; + this._enabled = true; + this._frameScripts = {}; + this._framesLoaded = 1; + this._isPlaying = false; + this._labelMap = {}; + this._sceneFrameMap = {}; + this._sceneMap = {}; + this._scenes = null; + this._timeline = null; + this._totalFrames = 1; + this._startSoundRegistrations = []; + this._allowFrameNavigation = true; + this._complete = true; + var s = this.symbol; + if (s) { + this._timeline = s.timeline || null; + this._framesLoaded = s.framesLoaded || 1; + this._labelMap = Object.create(s.labelMap || null); + this._frameScripts = Object.create(s.frameScripts || null); + this._totalFrames = s.totalFrames || 1; + this._startSoundRegistrations = s.startSoundRegistrations || []; + this._scenes = s.scenes || null; + this._complete = s.complete === false ? false : true; + var map = this._labelMap; + for (var name in map) { + var frame = map[name]; + if (frame == 1) { + this._currentFrameLabel = this._currentLabel = name; + } + } + } + this._enterFrame(1); + var self = this; + this._onExecuteFrame = function onExecuteFrame() { + self._removeEventListener('executeFrame', onExecuteFrame); + self._allowFrameNavigation = false; + self._callFrame(self._currentFrame); + self._allowFrameNavigation = true; + if (self._playHead !== self._currentFrame) { + self._gotoFrame(self._playHead, true); + } + self._postConstructChildren(); + }; + this._addEventListener('executeFrame', this._onExecuteFrame); + if (this._complete && this._totalFrames <= 1) { + return this; + } + this._onAdvanceFrame = function onAdvanceFrame() { + var frameNum = self._playHead + 1; + if (self._complete && frameNum > self._totalFrames) { + frameNum = 1; + } else if (frameNum > self._framesLoaded) { + return; + } + self._updateDisplayList(frameNum); + if (self._sparse) { + self._addEventListener('constructChildren', self._onConstructChildren); + } + self._startSounds(frameNum); + self._enterFrame(frameNum); + if (frameNum in self._frameScripts) { + self._addEventListener('executeFrame', self._onExecuteFrame); + } + }; + this._onConstructChildren = function onConstructChildren() { + self._removeEventListener('constructChildren', onConstructChildren); + self._constructChildren(); + }; + this.play(); + }, + _updateDisplayList: function (nextFrameNum) { + this._destructChildren(nextFrameNum); + this._declareChildren(nextFrameNum); + }, + _declareChildren: function declareChildren(nextFrameNum) { + var currentFrame = this._currentFrame; + if (nextFrameNum === currentFrame) { + return; + } + var timeline = this._timeline; + var nextDisplayList = timeline[nextFrameNum - 1]; + if (nextDisplayList === timeline[currentFrame - 1]) { + return; + } + var prevDisplayListItem = null; + var currentDisplayListItem = this._currentDisplayList; + var children = this._children; + var depths = nextDisplayList.depths; + var index = children.length; + var i = depths.length; + while (i--) { + var depth = depths[i], depthInt = depth | 0; + while (currentDisplayListItem && currentDisplayListItem.depth > depthInt) { + prevDisplayListItem = currentDisplayListItem; + currentDisplayListItem = currentDisplayListItem.next; + } + var currentChild = null; + if (currentDisplayListItem && currentDisplayListItem.depth === depthInt) { + currentChild = currentDisplayListItem.obj; + if (currentChild && currentChild._owned) { + index = this.getChildIndex(currentChild); + } + } + var currentCmd = currentDisplayListItem && currentDisplayListItem.depth === depthInt ? currentDisplayListItem.cmd : null; + var nextCmd = nextDisplayList[depth]; + if (!nextCmd || nextCmd === currentCmd) { + continue; + } + if (currentCmd && currentChild && nextCmd.symbolId === currentCmd.symbolId && nextCmd.ratio === currentCmd.ratio) { + if (currentChild._animated) { + currentChild._invalidate(); + if (nextCmd.hasMatrix) { + currentChild._setTransformMatrix(nextCmd.matrix, false); + } + if (nextCmd.hasCxform) { + currentChild._cxform = nextCmd.cxform; + } + if (nextCmd.clip) { + currentChild._clipDepth = nextCmd.clipDepth; + } + if (nextCmd.hasName) { + currentChild.name = nextCmd.name; + } + if (nextCmd.blend) { + currentChild._blendMode = this._resolveBlendMode(nextCmd.blendMode); + } + } + currentDisplayListItem.cmd = nextCmd; + continue; + } + var newDisplayListItem = this._addTimelineChild(nextCmd, index); + newDisplayListItem.next = currentDisplayListItem; + if (prevDisplayListItem) { + prevDisplayListItem.next = newDisplayListItem; + } else { + this._currentDisplayList = newDisplayListItem; + } + prevDisplayListItem = newDisplayListItem; + } + }, + _destructChildren: function destructChildren(nextFrameNum) { + var currentFrame = this._currentFrame; + if (nextFrameNum === currentFrame) { + return; + } + var timeline = this._timeline; + var nextDisplayList = timeline[nextFrameNum - 1]; + if (nextDisplayList === timeline[currentFrame - 1]) { + return; + } + var prevEntry = null; + var currentEntry = this._currentDisplayList; + var toRemove = null; + while (currentEntry) { + var depth = currentEntry.depth; + var currentCmd = currentEntry.cmd; + var nextCmd = nextDisplayList[depth]; + if (!nextCmd || nextCmd.symbolId !== currentCmd.symbolId || nextCmd.ratio !== currentCmd.ratio) { + var nextDisplayListItem = currentEntry.next; + if (prevEntry) { + prevEntry.next = nextDisplayListItem; + } else { + this._currentDisplayList = nextDisplayListItem; + } + currentEntry.next = toRemove; + toRemove = currentEntry; + currentEntry = nextDisplayListItem; + } else { + prevEntry = currentEntry; + currentEntry = currentEntry.next; + } + } + while (toRemove) { + var child = toRemove.obj; + if (child && child._owned) { + this._sparse = true; + this.removeChild(child); + child.destroy(); + if (child._isPlaying) { + child.stop(); + } + } + toRemove = toRemove.next; + } + }, + _gotoFrame: function gotoFrame(frameNum, execute) { + var enterFrame = frameNum !== this._currentFrame; + if (this._allowFrameNavigation || !this._loader._isAvm2Enabled) { + if (enterFrame) { + this._updateDisplayList(frameNum); + this._enterFrame(frameNum); + } + this._constructChildren(); + if (this._loader._isAvm2Enabled && this.loaderInfo._swfVersion >= 10) { + if (enterFrame) { + this._addEventListener('executeFrame', this._onExecuteFrame); + } + var domain = avm2.systemDomain; + domain.broadcastMessage('frameConstructed'); + domain.broadcastMessage('executeFrame'); + domain.broadcastMessage('exitFrame'); + return; + } + if (enterFrame && (execute || !this._loader._isAvm2Enabled)) { + this._callFrame(frameNum); + } + this._postConstructChildren(); + return; + } + if (enterFrame) { + this._playHead = frameNum; + } + }, + _enterFrame: function navigate(frameNum) { + if (frameNum === this._currentFrame) { + return; + } + this._currentFrameLabel = null; + if (frameNum === 1) { + this._currentLabel = null; + } + var map = this._labelMap; + for (var name in map) { + if (map[name] === frameNum) { + this._currentFrameLabel = this._currentLabel = name; + break; + } + } + if (this._scenes) { + var scenes = this._scenes; + for (var j = 0, n = scenes.length; j < n; j++) { + var scene = scenes[j]; + if (frameNum >= scene._startFrame && frameNum <= scene._endFrame) { + this._currentScene = j; + break; + } + } + } + this._playHead = this._currentFrame = frameNum; + }, + _callFrame: function callFrame(frame) { + if (isNaN(frame)) { + frame = this._labelMap[frame]; + if (frame === undefined) { + return; + } + } + if (frame in this._frameScripts) { + var scripts = this._frameScripts[frame]; + try { + for (var i = 0, n = scripts.length; i < n; i++) { + scripts[i].call(this); + } + } catch (e) { + var AVM2_ERROR_TYPE = 2; + TelemetryService.reportTelemetry({ + topic: 'error', + error: AVM2_ERROR_TYPE + }); + if (false) { + console.error('error ' + e + ', stack: \n' + e.stack); + } + this.stop(); + throw e; + } + } + }, + _gotoButtonState: function gotoButtonState(stateName) { + if (this._enabled) { + this.gotoLabel('_' + stateName); + } + }, + _getAbsFrameNum: function (frameNum, sceneName) { + if (frameNum < 1) { + frameNum = 1; + } + if (sceneName && this._scenes && this._scenes.length > 1) { + var scenes = this._scenes; + for (var i = 0; i < scenes.length; i++) { + var scene = scenes[i]; + if (scene.name === sceneName) { + frameNum += scene._startFrame - 1; + if (frameNum > scene._endFrame) { + frameNum = scene._endFrame; + } + break; + } + } + } + if (frameNum > this._framesLoaded) { + return this._framesLoaded; + } + return frameNum; + }, + _registerStartSounds: function (frameNum, starts) { + this._startSoundRegistrations[frameNum] = starts; + }, + _initSoundStream: function (streamInfo) { + this._soundStream = new MovieClipSoundStream(streamInfo, this); + }, + _addSoundStreamBlock: function (frameNum, streamBlock) { + this._soundStream.appendBlock(frameNum, streamBlock); + }, + _startSounds: function (frameNum) { + var starts = this._startSoundRegistrations[frameNum]; + if (starts) { + var sounds = this._sounds || (this._sounds = {}); + var loader = this.loaderInfo._loader; + for (var i = 0; i < starts.length; i++) { + var start = starts[i]; + var symbolId = start.soundId; + var info = start.soundInfo; + var sound = sounds[symbolId]; + if (!sound) { + var symbolInfo = loader._dictionaryResolved[symbolId]; + if (!symbolInfo) + continue; + var symbolClass = avm2.systemDomain.findClass(symbolInfo.className) ? avm2.systemDomain.getClass(symbolInfo.className) : avm2.applicationDomain.getClass(symbolInfo.className); + var soundObj = symbolClass.createAsSymbol(symbolInfo.props); + symbolClass.instanceConstructor.call(soundObj); + sounds[symbolId] = sound = { + object: soundObj + }; + } + if (sound.channel) { + sound.channel.stop(); + sound.channel = null; + } + if (!info.stop) { + var loops = info.hasLoops ? info.loopCount : 0; + sound.channel = sound.object.play(0, loops); + } + } + } + if (this._soundStream) { + this._soundStream.playFrame(frameNum); + } + }, + _getAS2Object: function () { + if (!this.$as2Object) { + if (this._avm1SymbolClass) { + var nativeObject = this, nativeObjectClass = this._avm1SymbolClass; + var constructWrapper = function () { + this.init(nativeObject); + nativeObjectClass.call(this); + }; + constructWrapper.prototype = Object.create(nativeObjectClass.prototype); + constructWrapper.instanceConstructor = constructWrapper; + constructWrapper.debugName = 'avm1 '; + construct(constructWrapper); + } else { + new avm1lib.AS2MovieClip(this); + } + } + return this.$as2Object; + }, + get currentFrame() { + var frameNum = this._currentFrame; + return this._scenes ? frameNum - this.currentScene._startFrame + 1 : frameNum; + }, + get currentFrameLabel() { + return this._currentFrameLabel; + }, + get currentLabel() { + return this._currentLabel; + }, + get currentLabels() { + if (this._scenes) { + return this._scenes[this._currentScene].labels; + } else { + var labels = []; + var map = this._labelMap; + for (var name in map) { + labels.push(new flash.display.FrameLabel(name, map[name])); + } + return labels; + } + }, + get currentScene() { + return this._scenes ? this._scenes[this._currentScene] : new flash.display.Scene('', this.currentLabels, this._framesLoaded); + }, + get enabled() { + return this._enabled; + }, + set enabled(val) { + this._enabled = val; + }, + get framesLoaded() { + return this._framesLoaded; + }, + get totalFrames() { + return this._totalFrames; + }, + get scenes() { + return this._scenes || [ + new flash.display.Scene('', this.currentLabels, this._framesLoaded) + ]; + }, + get trackAsMenu() { + return false; + }, + set trackAsMenu(val) { + notImplemented(); + }, + addFrameScript: function () { + var frameScripts = this._frameScripts; + for (var i = 0, n = arguments.length; i < n; i += 2) { + var frameNum = arguments[i] + 1; + var fn = arguments[i + 1]; + if (!fn) { + continue; + } + var scripts = frameScripts[frameNum]; + if (scripts) { + scripts.push(fn); + } else { + frameScripts[frameNum] = [ + fn + ]; + } + if (frameNum === this._currentFrame) { + this._addEventListener('executeFrame', this._onExecuteFrame); + } + } + }, + gotoAndPlay: function (frame, scene) { + this.play(); + if (isNaN(frame)) { + this.gotoLabel(frame); + } else { + this._gotoFrame(this._getAbsFrameNum(frame, scene)); + } + }, + gotoAndStop: function (frame, scene) { + this.stop(); + if (isNaN(frame)) { + this.gotoLabel(frame); + } else { + this._gotoFrame(this._getAbsFrameNum(frame, scene)); + } + }, + gotoLabel: function (labelName) { + var frameNum = this._labelMap[labelName]; + if (frameNum !== undefined) { + this._gotoFrame(frameNum); + } + }, + isPlaying: function () { + return this._isPlaying; + }, + nextFrame: function () { + this.stop(); + if (this._currentFrame < this._framesLoaded) { + this._gotoFrame(this._currentFrame + 1); + } + }, + nextScene: function () { + if (this._scenes && this._currentScene < this._scenes.length - 1) { + this._gotoFrame(this._scenes[this._currentScene + 1]._startFrame); + } + }, + play: function () { + if (this._isPlaying || this._complete && this._totalFrames <= 1) { + return; + } + this._isPlaying = true; + this._addEventListener('advanceFrame', this._onAdvanceFrame); + }, + prevFrame: function () { + this.stop(); + if (this._currentFrame > 1) { + this._gotoFrame(this._currentFrame - 1); + } + }, + prevScene: function () { + if (this._scenes && this._currentScene > 0) { + this._gotoFrame(this._scenes[this._currentScene - 1]._startFrame); + } + }, + stop: function () { + if (!this._isPlaying || this._complete && this._totalFrames <= 1) { + return; + } + this._isPlaying = false; + this._removeEventListener('advanceFrame', this._onAdvanceFrame); + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + currentFrame: desc(def, 'currentFrame'), + framesLoaded: desc(def, 'framesLoaded'), + totalFrames: desc(def, 'totalFrames'), + trackAsMenu: desc(def, 'trackAsMenu'), + scenes: desc(def, 'scenes'), + currentScene: desc(def, 'currentScene'), + currentLabel: desc(def, 'currentLabel'), + currentFrameLabel: desc(def, 'currentFrameLabel'), + enabled: desc(def, 'enabled'), + isPlaying: desc(def, 'isPlaying'), + play: def.play, + stop: def.stop, + nextFrame: def.nextFrame, + prevFrame: def.prevFrame, + gotoAndPlay: def.gotoAndPlay, + gotoAndStop: def.gotoAndStop, + addFrameScript: def.addFrameScript, + prevScene: def.prevScene, + nextScene: def.nextScene + } + } + }; + return def; + }.call(this); +var MovieClipSoundStream = function () { + var MP3_MIME_TYPE = 'audio/mpeg'; + function openMediaSource(soundStream, mediaSource) { + var sourceBuffer; + try { + sourceBuffer = mediaSource.addSourceBuffer(MP3_MIME_TYPE); + soundStream.mediaSource = mediaSource; + soundStream.sourceBuffer = sourceBuffer; + soundStream.rawFrames.forEach(function (data) { + sourceBuffer.appendBuffer(data); + }); + delete soundStream.rawFrames; + } catch (e) { + console.error('MediaSource mp3 playback is not supported: ' + e); + } + } + function syncTime(element, movieClip) { + var initialized = false; + var startMediaTime, startRealTime; + element.addEventListener('timeupdate', function (e) { + if (!initialized) { + startMediaTime = element.currentTime; + startRealTime = performance.now(); + initialized = true; + movieClip._stage._frameScheduler.startTrackDelta(); + return; + } + var mediaDelta = element.currentTime - startMediaTime; + var realDelta = performance.now() - startRealTime; + movieClip._stage._frameScheduler.setDelta(realDelta - mediaDelta * 1000); + }); + element.addEventListener('pause', function (e) { + movieClip._stage._frameScheduler.endTrackDelta(); + initialized = false; + }); + element.addEventListener('seeking', function (e) { + movieClip._stage._frameScheduler.endTrackDelta(); + initialized = false; + }); + } + function MovieClipSoundStream(streamInfo, movieClip) { + this.movieClip = movieClip; + this.data = { + sampleRate: streamInfo.sampleRate, + channels: streamInfo.channels + }; + this.seekIndex = []; + this.position = 0; + var isMP3 = streamInfo.format === 'mp3'; + if (isMP3 && PLAY_USING_AUDIO_TAG) { + var element = document.createElement('audio'); + element.preload = 'metadata'; + element.loop = false; + syncTime(element, movieClip); + if (element.canPlayType(MP3_MIME_TYPE)) { + this.element = element; + if (typeof MediaSource !== 'undefined') { + var mediaSource = new MediaSource(); + mediaSource.addEventListener('sourceopen', openMediaSource.bind(null, this, mediaSource)); + element.src = URL.createObjectURL(mediaSource); + } else { + console.warn('MediaSource is not supported'); + } + this.rawFrames = []; + return; + } + } + var totalSamples = streamInfo.samplesCount * streamInfo.channels; + this.data.pcm = new Float32Array(totalSamples); + if (isMP3) { + var soundStream = this; + soundStream.decoderPosition = 0; + soundStream.decoderSession = new MP3DecoderSession(); + soundStream.decoderSession.onframedata = function (frameData) { + var position = soundStream.decoderPosition; + soundStream.data.pcm.set(frameData, position); + soundStream.decoderPosition = position + frameData.length; + }.bind(this); + soundStream.decoderSession.onerror = function (error) { + console.error('ERROR: MP3DecoderSession: ' + error); + }; + } + } + MovieClipSoundStream.prototype = { + appendBlock: function (frameNum, streamBlock) { + var streamPosition = this.position; + this.seekIndex[frameNum] = streamPosition + streamBlock.seek * this.data.channels; + this.position = streamPosition + streamBlock.samplesCount * this.data.channels; + if (this.sourceBuffer) { + this.sourceBuffer.appendBuffer(streamBlock.data); + return; + } + if (this.rawFrames) { + this.rawFrames.push(streamBlock.data); + return; + } + var decoderSession = this.decoderSession; + if (decoderSession) { + decoderSession.pushAsync(streamBlock.data); + } else { + this.data.pcm.set(streamBlock.pcm, streamPosition); + } + }, + playFrame: function (frameNum) { + if (isNaN(this.seekIndex[frameNum])) { + return; + } + var PAUSE_WHEN_OF_SYNC_GREATER = 1; + var PLAYBACK_ADJUSTMENT = 0.25; + var element = this.element; + if (element) { + var soundStreamData = this.data; + var time = this.seekIndex[frameNum] / soundStreamData.sampleRate / soundStreamData.channels; + if (!this.channel && (this.movieClip._complete || this.sourceBuffer)) { + if (!this.sourceBuffer) { + var blob = new Blob(this.rawFrames); + element.src = URL.createObjectURL(blob); + } + var symbolClass = flash.media.SoundChannel.class; + var channel = symbolClass.createAsSymbol({ + element: element + }); + symbolClass.instanceConstructor.call(channel); + this.channel = channel; + this.expectedFrame = 0; + this.waitFor = 0; + } else if (this.sourceBuffer || !isNaN(element.duration)) { + if (this.mediaSource && this.movieClip._complete) { + this.mediaSource.endOfStream(); + this.mediaSource = null; + } + var elementTime = element.currentTime; + if (this.expectedFrame !== frameNum) { + if (element.paused) { + element.play(); + element.addEventListener('playing', function setTime(e) { + element.removeEventListener('playing', setTime); + element.currentTime = time; + }); + } else { + element.currentTime = time; + } + } else if (this.waitFor > 0) { + if (this.waitFor <= time) { + if (element.paused) { + element.play(); + } + this.waitFor = 0; + } + } else if (elementTime - time > PAUSE_WHEN_OF_SYNC_GREATER) { + console.warn('Sound is faster than frames by ' + (elementTime - time)); + this.waitFor = elementTime - PLAYBACK_ADJUSTMENT; + element.pause(); + } else if (time - elementTime > PAUSE_WHEN_OF_SYNC_GREATER) { + console.warn('Sound is slower than frames by ' + (time - elementTime)); + element.currentTime = time + PLAYBACK_ADJUSTMENT; + } + this.expectedFrame = frameNum + 1; + } + } else if (!this.sound) { + var symbolClass = flash.media.Sound.class; + var sound = symbolClass.createAsSymbol(this.data); + symbolClass.instanceConstructor.call(sound); + var channel = sound.play(); + this.sound = sound; + this.channel = channel; + } + } + }; + return MovieClipSoundStream; + }(); +var NativeMenuDefinition = function () { + return { + __class__: 'flash.display.NativeMenu', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: {} + } + } + }; + }.call(this); +var NativeMenuItemDefinition = function () { + return { + __class__: 'flash.display.NativeMenuItem', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + enabled: { + get: function enabled() { + somewhatImplemented('NativeMenuItem.enabled'); + return this._enabled; + }, + set: function enabled(isSeparator) { + somewhatImplemented('NativeMenuItem.enabled'); + this._enabled = isSeparator; + } + } + } + } + } + }; + }.call(this); +var SceneDefinition = function () { + return { + __class__: 'flash.display.Scene', + initialize: function () { + this._startFrame = 1; + this._endFrame = 1; + }, + __glue__: { + native: { + static: {}, + instance: {} + }, + script: { + static: {}, + instance: { + name: { + get: function name() { + notImplemented('Scene.name'); + return this._name; + } + }, + labels: { + get: function labels() { + notImplemented('Scene.labels'); + return this._labels; + } + }, + numFrames: { + get: function numFrames() { + notImplemented('Scene.numFrames'); + return this._numFrames; + } + } + } + } + } + }; + }.call(this); +var ShaderDefinition = function () { + return { + __class__: 'flash.display.Shader', + initialize: function () { + this._data = null; + }, + __glue__: { + native: { + static: {}, + instance: { + data: { + get: function data() { + return this._data; + }, + set: function data(p) { + this._data = p; + } + }, + precisionHint: { + get: function precisionHint() { + return this._precisionHint; + }, + set: function precisionHint(p) { + this._precisionHint = p; + } + } + } + }, + script: { + instance: Glue.ALL + } + } + }; + }.call(this); +var ShaderDataDefinition = function () { + return { + __class__: 'flash.display.ShaderData', + initialize: function () { + this._byteCode = null; + }, + __glue__: { + native: { + static: {}, + instance: { + _setByteCode: function _setByteCode(code) { + this._byteCode = code; + } + } + }, + script: { + instance: Glue.ALL + } + } + }; + }.call(this); +var ShapeDefinition = function () { + var def = { + __class__: 'flash.display.Shape', + initialize: function () { + var graphics = this._graphics = new flash.display.Graphics(); + graphics._parent = this; + var s = this.symbol; + if (s && s.paths) { + graphics._paths = s.paths; + for (var i = 0; i < s.paths.length; i++) { + s.paths[i] = finishShapePath(s.paths[i], s.dictionaryResolved); + } + graphics.bbox = s.bbox; + graphics.strokeBbox = s.strokeBbox; + if (this._stage && this._stage._quality === 'low' && !graphics._bitmap) + graphics._cacheAsBitmap(this._bbox); + this.ratio = s.ratio || 0; + } + } + }; + def.__glue__ = { + native: { + instance: { + graphics: { + get: function () { + return this._graphics; + } + } + } + } + }; + return def; + }.call(this); +var SimpleButtonDefinition = function () { + var AVM1KeyCodeMap = [ + 0, + 37, + 39, + 36, + 35, + 45, + 46, + 0, + 8, + 0, + 0, + 0, + 0, + 13, + 38, + 40, + 33, + 34, + 9, + 27 + ]; + var AVM1MouseTransitionEvents = [ + 0, + 0, + 1, + 128, + 64, + 0, + 0, + 32, + 2, + 0, + 0, + 4, + 256, + 16, + 8, + 0 + ]; + return { + __class__: 'flash.display.SimpleButton', + initialize: function () { + this._useHandCursor = true; + this._enabled = true; + this._trackAsMenu = false; + this._upState = null; + this._overState = null; + this._downState = null; + this._hitTestState = null; + this._currentButtonState = 'up'; + this._mouseChildren = false; + this._buttonMode = true; + this._prevAvm1StateCode = 0; + this._avm1StateCode = 0; + this._avm1MouseEvents = null; + this._isContainer = true; + var s = this.symbol; + if (s) { + var states = s.states; + if (states.down) { + this._downState = this._constructState(states.down, this); + } + if (states.hitTest) { + this._hitTestState = this._constructState(states.hitTest, this); + } + if (states.over) { + this._overState = this._constructState(states.over, this); + } + if (states.up) { + this._upState = this._constructState(states.up, this); + } + } + if (this._loader && !this._loader._isAvm2Enabled && s && s.buttonActions) { + this._addEventListener('addedToStage', function (e) { + this._initAvm1Events(s.buttonActions); + }.bind(this), false); + } + }, + _constructState: function constructState(symbolInfo) { + var symbolClass = avm2.systemDomain.findClass(symbolInfo.className) ? avm2.systemDomain.getClass(symbolInfo.className) : avm2.applicationDomain.getClass(symbolInfo.className); + var instance = symbolClass.createAsSymbol(symbolInfo.props); + symbolClass.instanceConstructor.call(instance); + if (instance._children.length === 1) { + instance = instance._children[0]; + instance._parent = null; + instance._index = -1; + } + return instance; + }, + _updateButton: function updateButton() { + var state = null; + switch (this._currentButtonState) { + case 'up': + state = this._upState; + break; + case 'over': + state = this._overState; + break; + case 'down': + state = this._downState; + break; + } + if (!state) { + return; + } + var currentChild = this._children[0]; + if (currentChild) { + if (currentChild === state) { + return; + } + if (this._stage) { + this._stage._removeFromStage(currentChild); + } + currentChild._invalidateTransform(); + } + if (!state) { + this._children.shift(); + return; + } + this._children[0] = state; + state._parent = this; + state._invalidateTransform(); + if (this._stage) { + this._stage._addToStage(state); + } + }, + _gotoButtonState: function gotoButtonState(buttonState) { + this._invalidateBounds(); + this._currentButtonState = buttonState; + this._updateButton(); + if (this._avm1MouseEvents) { + this._processAvm1MouseEvents(this._avm1MouseEvents); + } + }, + _getRegion: function getRegion(targetCoordSpace) { + if (!this._hitTestState) { + return { + xMin: 0, + yMin: 0, + xMax: 0, + yMax: 0 + }; + } + var b = this._hitTestState.getBounds(null); + return this._getTransformedRect(b, targetCoordSpace); + }, + _getAS2Object: function () { + if (!this.$as2Object) { + new avm1lib.AS2Button(this); + } + return this.$as2Object; + }, + _initAvm1Events: function (buttonActions) { + var loader = this._loader; + var avm1Context = loader._avm1Context; + var keyEvents = null; + for (var i = 0; i < buttonActions.length; i++) { + var buttonAction = buttonActions[i]; + var fn = function (actionBlock) { + return executeActions(actionBlock, avm1Context, this._getAS2Object()); + }.bind(this.parent, buttonAction.actionsData); + var mouseEventFlags = buttonAction.mouseEventFlags; + if (mouseEventFlags) { + var mouseEvents = this._avm1MouseEvents || (this._avm1MouseEvents = []); + mouseEvents.push({ + flags: mouseEventFlags, + listener: fn + }); + } + var keyPress = buttonAction.keyPress; + if (keyPress) { + keyEvents = keyEvents || (keyEvents = []); + keyEvents.push({ + keyCode: AVM1KeyCodeMap[keyPress] || 0, + charCode: keyPress, + listener: fn + }); + } + } + if (keyEvents) { + var keyListener = function (e) { + for (var i = 0; i < keyEvents.length; i++) { + var keyEvent = keyEvents[i]; + if (keyEvent.keyCode ? keyEvent.keyCode === e.keyCode : keyEvent.charCode === e.charCode) { + keyEvent.listener(); + } + } + }; + var KeyboardEventClass = flash.events.KeyboardEvent; + this.stage._addEventListener(KeyboardEventClass.class.KEY_DOWN, keyListener, false); + this._addEventListener('removedFromStage', function (stage) { + stage._removeEventListener(KeyboardEventClass.class.KEY_DOWN, keyListener, false); + }.bind(this, this.stage), false); + } + }, + _processAvm1MouseEvents: function (mouseEvents) { + var prevAvm1StateCode = this._avm1StateCode; + var avm1StateCode = (this._currentButtonState === 'down' ? 1 : 0) | (this._currentButtonState !== 'up' ? 2 : 0); + if (prevAvm1StateCode !== avm1StateCode) { + this._prevAvm1StateCode = prevAvm1StateCode; + this._avm1StateCode = avm1StateCode; + var flag = AVM1MouseTransitionEvents[prevAvm1StateCode << 2 | avm1StateCode]; + for (var i = 0; i < mouseEvents.length; i++) { + var mouseEvent = mouseEvents[i]; + if ((mouseEvent.flags & flag) !== 0) { + mouseEvent.listener(); + } + } + } + }, + __glue__: { + native: { + instance: { + _updateButton: function _updateButton() { + this._updateButton(); + }, + useHandCursor: { + get: function useHandCursor() { + return this._useHandCursor; + }, + set: function useHandCursor(value) { + this._useHandCursor = value; + } + }, + enabled: { + get: function enabled() { + return this._enabled; + }, + set: function enabled(value) { + this._enabled = value; + } + }, + trackAsMenu: { + get: function trackAsMenu() { + notImplemented('SimpleButton.trackAsMenu'); + return this._trackAsMenu; + }, + set: function trackAsMenu(value) { + notImplemented('SimpleButton.trackAsMenu'); + this._trackAsMenu = value; + } + }, + upState: { + get: function upState() { + return this._upState; + }, + set: function upState(value) { + this._upState = value; + this._updateButton(); + } + }, + overState: { + get: function overState() { + return this._overState; + }, + set: function overState(value) { + this._overState = value; + this._updateButton(); + } + }, + downState: { + get: function downState() { + return this._downState; + }, + set: function downState(value) { + this._downState = value; + this._updateButton(); + } + }, + hitTestState: { + get: function hitTestState() { + return this._hitTestState; + }, + set: function hitTestState(value) { + if (value === this._hitTestState) { + return; + } + this._invalidate(); + this._hitTestState = value; + } + }, + soundTransform: { + get: function soundTransform() { + notImplemented('SimpleButton.soundTransform'); + return this._soundTransform; + }, + set: function soundTransform(value) { + notImplemented('SimpleButton.soundTransform'); + this._soundTransform = value; + } + } + } + } + } + }; + }.call(this); +var SpriteDefinition = function () { + var def = { + __class__: 'flash.display.Sprite', + initialize: function () { + this._buttonMode = false; + this._hitArea = null; + this._useHandCursor = true; + this._hitTarget = null; + this._currentDisplayList = null; + var s = this.symbol; + if (s) { + this._graphics = s.graphics || new flash.display.Graphics(); + if (s.timeline) { + var displayList = s.timeline[0]; + if (displayList) { + var depths = displayList.depths; + for (var i = 0; i < depths.length; i++) { + var cmd = displayList[depths[i]]; + if (cmd) { + var displayListItem = this._addTimelineChild(cmd); + displayListItem.next = this._currentDisplayList; + this._currentDisplayList = displayListItem; + } + } + } + } + } else { + this._graphics = new flash.display.Graphics(); + } + this._graphics._parent = this; + }, + _addTimelineChild: function addTimelineChild(cmd, index) { + var symbolInfo = cmd.symbolInfo; + var props = Object.create(symbolInfo.props); + props.symbolId = cmd.symbolId; + props.depth = cmd.depth; + if (cmd.clip) { + props.clipDepth = cmd.clipDepth; + } + if (cmd.hasCxform) { + props.cxform = cmd.cxform; + } + if (cmd.hasMatrix) { + props.currentTransform = cmd.matrix; + } + if (cmd.hasName) { + props.name = cmd.name; + } + if (cmd.hasRatio) { + props.ratio = cmd.ratio / 65535; + } + if (cmd.blend) { + props.blendMode = cmd.blendMode; + } + var displayListItem = { + cmd: cmd, + depth: cmd.depth, + className: symbolInfo.className, + props: props, + events: cmd.events, + obj: null + }; + if (index !== undefined) { + this._children.splice(index, 0, displayListItem); + } else { + this._children.push(displayListItem); + } + this._sparse = true; + return displayListItem; + }, + _constructChildren: function () { + if (!this._sparse) { + return; + } + var loader = this._loader; + var children = this._children; + for (var i = 0; i < children.length; i++) { + var displayListItem = children[i]; + Counter.count('constructChild'); + if (flash.display.DisplayObject.class.isInstanceOf(displayListItem)) { + displayListItem._index = i; + } else { + var symbolClass = avm2.systemDomain.findClass(displayListItem.className) ? avm2.systemDomain.getClass(displayListItem.className) : avm2.applicationDomain.getClass(displayListItem.className); + var props = Object.create(displayListItem.props); + var name = props.name; + props.animated = true; + props.owned = true; + props.parent = this; + props.stage = this._stage; + if (this._level > -1) { + props.level = this._level + 1; + } + props.index = i; + var instance = symbolClass.createAsSymbol(props); + if (name) { + this[Multiname.getPublicQualifiedName(name)] = instance; + } + symbolClass.instanceConstructor.call(instance); + if (flash.display.BitmapData.class.isInstanceOf(instance)) { + var bitmapData = instance; + instance = flash.display.Bitmap.class.createAsSymbol(props); + flash.display.Bitmap.class.instanceConstructor.call(instance, bitmapData); + } + if (!loader._isAvm2Enabled) { + this._initAvm1Bindings(instance, name, displayListItem.events); + instance._dispatchEvent('init'); + instance._dispatchEvent('construct'); + instance._needLoadEvent = true; + } else { + instance._dispatchEvent('load'); + } + instance._dispatchEvent('added', undefined, true); + if (this._stage) { + this._stage._addToStage(instance); + } + children[i] = instance; + displayListItem.obj = instance; + } + } + this._sparse = false; + }, + _postConstructChildren: function () { + var loader = this._loader; + if (!loader || loader._isAvm2Enabled) { + return; + } + var children = this._children; + for (var i = 0; i < children.length; i++) { + var instance = children[i]; + if (instance._needLoadEvent) { + instance._needLoadEvent = false; + instance._dispatchEvent('load'); + } + } + }, + _duplicate: function (name, depth, initObject) { + var loader = this._loader; + var parent = this._parent; + var children = parent._children; + var symbolClass = this.class; + var symbolInfo = this.symbol; + var props = Object.create(symbolInfo); + props.name = name; + props.parent = parent; + props.depth = depth; + var instance = symbolClass.createAsSymbol(props); + if (name && loader && !loader._isAvm2Enabled && !parent.asHasProperty(undefined, name, 0, false)) { + parent.asSetPublicProperty(name, instance); + } + symbolClass.instanceConstructor.call(instance); + instance._index = children.length; + children.push(instance); + if (!loader._isAvm2Enabled) { + parent._initAvm1Bindings(instance, name, symbolInfo && symbolInfo.events); + instance._dispatchEvent('init'); + instance._dispatchEvent('construct'); + } + instance._dispatchEvent('load'); + instance._dispatchEvent('added'); + if (this._stage) { + instance._invalidate(); + } + return instance; + }, + _insertChildAtDepth: function (child, depth) { + this.addChild(child); + var name = child._name; + var loader = this._loader; + if (name && loader && !loader._isAvm2Enabled && !this._getAS2Object().asHasProperty(undefined, name, 0, true)) { + this._getAS2Object().asSetPublicProperty(name, child._getAS2Object()); + } + }, + _initAvm1Bindings: function (instance, name, events) { + var loader = this._loader; + var avm1Context = loader._avm1Context; + var symbolProps = instance.symbol; + if (symbolProps && symbolProps.variableName) { + instance._getAS2Object().asSetPublicProperty('variable', symbolProps.variableName); + } + if (events) { + var eventsBound = []; + for (var i = 0; i < events.length; i++) { + var event = events[i]; + if (event.eoe) { + break; + } + var fn = function (actionBlock) { + return executeActions(actionBlock, avm1Context, this._getAS2Object()); + }.bind(instance, event.actionsData); + for (var eventName in event) { + if (eventName.indexOf('on') !== 0 || !event[eventName]) + continue; + var avm2EventName = eventName[2].toLowerCase() + eventName.substring(3); + if (avm2EventName === 'enterFrame') { + avm2EventName = 'frameConstructed'; + } + var avm2EventTarget = instance; + if (avm2EventName === 'mouseDown' || avm2EventName === 'mouseUp' || avm2EventName === 'mouseMove') { + avm2EventTarget = this._stage; + } + avm2EventTarget._addEventListener(avm2EventName, fn, false); + eventsBound.push({ + name: avm2EventName, + fn: fn, + target: avm2EventTarget + }); + } + } + if (eventsBound.length > 0) { + instance._addEventListener('removed', function (eventsBound) { + for (var i = 0; i < eventsBound.length; i++) { + eventsBound[i].target._removeEventListener(eventsBound[i].name, eventsBound[i].fn, false); + } + }.bind(instance, eventsBound), false); + } + } + if (name && this._getAS2Object && instance._getAS2Object) { + this._getAS2Object().asSetPublicProperty(name, instance._getAS2Object()); + } + }, + _gotoButtonState: function gotoButtonState(stateName) { + }, + get buttonMode() { + return this._buttonMode; + }, + set buttonMode(val) { + this._buttonMode = val; + }, + get graphics() { + return this._graphics; + }, + get hitArea() { + return this._hitArea; + }, + set hitArea(val) { + if (this._hitArea === val) { + return; + } + if (val && val._hitTarget) { + val._hitTarget.hitArea = null; + } + this._hitArea = val; + if (val) { + val._hitTarget = this; + } + }, + get soundTransform() { + notImplemented(); + }, + set soundTransform(val) { + notImplemented(); + }, + get useHandCursor() { + return this._useHandCursor; + }, + set useHandCursor(val) { + this._useHandCursor = val; + if (this._stage) { + this._stage._mouseMoved = true; + } + }, + startDrag: function (lockCenter, bounds) { + notImplemented(); + }, + startTouchDrag: function (touchPointID, lockCenter, bounds) { + notImplemented(); + }, + stopDrag: function () { + notImplemented(); + }, + stopTouchDrag: function (touchPointID) { + notImplemented(); + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + graphics: desc(def, 'graphics'), + buttonMode: desc(def, 'buttonMode'), + dropTarget: desc(def, 'dropTarget'), + startDrag: def.startDrag, + stopDrag: def.stopDrag, + startTouchDrag: def.startTouchDrag, + stopTouchDrag: def.stopTouchDrag, + constructChildren: def._constructChildren, + hitArea: desc(def, 'hitArea'), + useHandCursor: desc(def, 'useHandCursor'), + soundTransform: desc(def, 'soundTransform') + } + } + }; + return def; + }.call(this); +var StageDefinition = function () { + return { + __class__: 'flash.display.Stage', + initialize: function () { + this._frameRate = 24; + this._scaleMode = 'showAll'; + this._align = ''; + this._stageWidth = 0; + this._stageHeight = 0; + this._quality = 'high'; + this._color = 4294967295; + this._stage = this; + this._deferRenderEvent = false; + this._focus = null; + this._showDefaultContextMenu = true; + this._displayState = 'normal'; + this._colorCorrection = 'default'; + this._stageFocusRect = true; + this._fullScreenSourceRect = null; + this._wmodeGPU = false; + this._root = null; + this._qtree = null; + this._invalidRegions = new RegionCluster(); + this._mouseMoved = false; + this._mouseTarget = this; + this._mouseEvents = []; + this._cursor = 'auto'; + this._stageVideos = []; + this._concatenatedTransform.invalid = false; + }, + _setup: function setup(ctx, options) { + this._qtree = new QuadTree(0, 0, this._stageWidth, this._stageHeight, null); + this._invalid = true; + }, + _addToStage: function addToStage(displayObject) { + displayObject._stage = this; + var parent = displayObject._parent; + displayObject._level = parent._level + 1; + displayObject._invalid = true; + var children = displayObject._children; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (child._stage === null) { + this._addToStage(child); + } + } + displayObject._dispatchEvent('addedToStage'); + }, + _removeFromStage: function removeFromStage(displayObject) { + var children = displayObject._children; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (child._stage) { + this._removeFromStage(children[i]); + } + } + displayObject._dispatchEvent('removedFromStage'); + displayObject._stage = null; + displayObject._level = -1; + if (displayObject._region) { + this._qtree.remove(displayObject._region); + this._invalidRegions.insert(displayObject._region); + displayObject._region = null; + } + }, + _processInvalidations: function processInvalidations(refreshStage) { + var qtree = this._qtree; + var invalidRegions = this._invalidRegions; + var stack = []; + var zindex = 0; + var children = this._children; + var i = children.length; + while (i--) { + var child = children[i]; + if (refreshStage) { + child._invalid = true; + } + child._invisible = !child._visible; + stack.push(child); + } + while (stack.length) { + var node = stack.pop(); + var m = node._concatenatedTransform; + var children = node._children; + var i = children.length; + while (i--) { + var child = children[i]; + if (!flash.display.DisplayObject.class.isInstanceOf(child)) { + continue; + } + if (node._invalid) { + child._invalid = true; + } + if (m.invalid) { + child._concatenatedTransform.invalid = true; + } + child._invisible = node._invisible || !child._visible; + stack.push(child); + } + if (node._level && m.invalid) { + var m2 = node._currentTransform; + var m3 = node._parent._concatenatedTransform; + m.a = m2.a * m3.a + m2.b * m3.c; + m.b = m2.a * m3.b + m2.b * m3.d; + m.c = m2.c * m3.a + m2.d * m3.c; + m.d = m2.d * m3.d + m2.c * m3.b; + m.tx = m2.tx * m3.a + m3.tx + m2.ty * m3.c; + m.ty = m2.ty * m3.d + m3.ty + m2.tx * m3.b; + m.invalid = false; + } + var invalidRegion = node._region; + var currentRegion = node._getRegion(m); + var hidden = node._invisible || !currentRegion || currentRegion.xMax - currentRegion.xMin === 0 || currentRegion.yMax - currentRegion.yMin === 0 || currentRegion.xMax <= 0 || currentRegion.xMin >= this._stageWidth || currentRegion.yMax <= 0 || currentRegion.yMin >= this._stageHeight; + if (node._invalid) { + if (invalidRegion) { + invalidRegions.insert(invalidRegion); + } + if (!hidden && (!invalidRegion || currentRegion.xMin !== invalidRegion.xMin || currentRegion.yMin !== invalidRegion.yMin || currentRegion.xMax !== invalidRegion.xMax || currentRegion.yMax !== invalidRegion.yMax)) { + invalidRegions.insert(currentRegion); + } + } + if (hidden) { + if (invalidRegion) { + qtree.remove(invalidRegion); + node._region = null; + } + } else if (invalidRegion) { + invalidRegion.xMin = currentRegion.xMin; + invalidRegion.xMax = currentRegion.xMax; + invalidRegion.yMin = currentRegion.yMin; + invalidRegion.yMax = currentRegion.yMax; + qtree.update(invalidRegion); + } else { + currentRegion.obj = node; + qtree.insert(currentRegion); + node._region = currentRegion; + } + node._zindex = zindex++; + } + var invalidPath = new ShapePath(); + if (refreshStage) { + invalidPath.rect(0, 0, this._stageWidth, this._stageHeight); + invalidRegions.reset(); + return invalidPath; + } + var redrawRegions = invalidRegions.retrieve(); + for (var i = 0; i < redrawRegions.length; i++) { + var region = redrawRegions[i]; + var xMin = region.xMin - region.xMin % 20 - 40; + var yMin = region.yMin - region.yMin % 20 - 40; + var xMax = region.xMax - region.xMax % 20 + 80; + var yMax = region.yMax - region.yMax % 20 + 80; + var intersectees = qtree.retrieve(xMin, xMax, yMin, yMax); + for (var j = 0; j < intersectees.length; j++) { + var item = intersectees[j]; + item.obj._invalid = true; + } + invalidPath.rect(xMin, yMin, xMax - xMin, yMax - yMin); + } + invalidRegions.reset(); + return invalidPath; + }, + _handleMouseButtons: function () { + if (this._mouseEvents.length === 0) { + return; + } + var eventType = this._mouseEvents.shift(); + switch (eventType) { + case 'mousedown': + if (this._mouseTarget._buttonMode) { + this._mouseTarget._gotoButtonState('down'); + } + this._mouseTarget._dispatchEvent('mouseDown'); + break; + case 'mouseup': + if (this._mouseTarget._buttonMode) { + this._mouseTarget._gotoButtonState('over'); + } + this._mouseTarget._dispatchEvent('mouseUp'); + break; + } + }, + _handleMouse: function handleMouse() { + var mouseX = this._mouseX; + var mouseY = this._mouseY; + var candidates = this._qtree.retrieve(mouseX, mouseX, mouseY, mouseY); + var objectsUnderMouse = []; + for (var i = 0; i < candidates.length; i++) { + var item = candidates[i]; + var displayObject = item.obj; + var isUnderMouse = false; + if (flash.display.SimpleButton.class.isInstanceOf(displayObject)) { + if (!displayObject._enabled) { + continue; + } + var hitArea = displayObject._hitTestState; + hitArea._parent = displayObject; + isUnderMouse = hitArea._hitTest(true, mouseX, mouseY, true); + hitArea._parent = null; + } else { + isUnderMouse = displayObject._hitTest(true, mouseX, mouseY, true); + } + if (isUnderMouse) { + var currentNode = displayObject; + var lastEnabled = null; + if (!flash.display.InteractiveObject.class.isInstanceOf(currentNode)) { + lastEnabled = currentNode; + currentNode = currentNode._parent; + } + do { + if (!currentNode._mouseEnabled) { + lastEnabled = null; + } else if (lastEnabled === null) { + lastEnabled = currentNode; + } + currentNode = currentNode._parent; + } while (currentNode); + objectsUnderMouse.push(lastEnabled); + } + } + var target; + if (objectsUnderMouse.length) { + objectsUnderMouse.sort(sortByZindex); + var i = objectsUnderMouse.length; + while (i--) { + target = null; + var currentNode = objectsUnderMouse[i]; + if (!flash.display.InteractiveObject.class.isInstanceOf(currentNode)) { + var j = i; + while (j--) { + if (objectsUnderMouse[j]._parent === currentNode._parent && flash.display.InteractiveObject.class.isInstanceOf(objectsUnderMouse[j])) { + currentNode = objectsUnderMouse[j]; + i = j; + } + } + } + do { + if (flash.display.InteractiveObject.class.isInstanceOf(currentNode)) { + if ((!target || !currentNode._mouseChildren) && !currentNode._hitArea) { + target = currentNode; + } + } + currentNode = currentNode._parent; + } while (currentNode); + if (target !== objectsUnderMouse[i] && flash.display.SimpleButton.class.isInstanceOf(target)) { + continue; + } + break; + } + } + if (!target) { + target = this; + } else if (target._hitTarget) { + target = target._hitTarget; + } + if (target === this._mouseTarget) { + target._dispatchEvent('mouseMove'); + } else { + if (this._mouseTarget._buttonMode) { + this._mouseTarget._gotoButtonState('up'); + } + this._mouseTarget._dispatchEvent('mouseOut'); + var nodeLeft = this._mouseTarget; + var containerLeft = nodeLeft._parent; + var nodeEntered = target; + var containerEntered = nodeEntered._parent; + var cursor = 'auto'; + while (nodeLeft._level >= 0 && nodeLeft !== containerEntered) { + if (nodeLeft._hasEventListener('rollOut')) { + nodeLeft._dispatchEvent('rollOut'); + } + nodeLeft = nodeLeft._parent; + } + while (nodeEntered._level >= 0 && nodeEntered !== containerLeft) { + if (nodeEntered._hasEventListener('rollOver')) { + nodeEntered._dispatchEvent('rollOver'); + } + if (nodeEntered._buttonMode && nodeEntered._useHandCursor) { + cursor = 'pointer'; + } + nodeEntered = nodeEntered._parent; + } + if (target._buttonMode) { + target._gotoButtonState('over'); + } + target._dispatchEvent('mouseOver'); + this._mouseTarget = target; + this._cursor = cursor; + } + }, + _as2SetLevel: function (level, loader) { + somewhatImplemented('Stage._as2SetLevel'); + this.addChild(loader); + }, + __glue__: { + native: { + instance: { + invalidate: function invalidate() { + this._invalid = true; + this._deferRenderEvent = true; + }, + isFocusInaccessible: function isFocusInaccessible() { + notImplemented('Stage.isFocusInaccessible'); + }, + set_displayState: function set_displayState(value) { + somewhatImplemented('Stage.set_displayState'); + this._displayState = value; + }, + get_simulatedFullScreenWidth: function get_simulatedFullScreenWidth() { + notImplemented('Stage.get_simulatedFullScreenWidth'); + }, + get_simulatedFullScreenHeight: function get_simulatedFullScreenHeight() { + notImplemented('Stage.get_simulatedFullScreenHeight'); + }, + removeChildAt: function removeChildAt(index) { + notImplemented('Stage.removeChildAt'); + }, + swapChildrenAt: function swapChildrenAt(index1, index2) { + notImplemented('Stage.swapChildrenAt'); + }, + requireOwnerPermissions: function requireOwnerPermissions() { + somewhatImplemented('Stage.requireOwnerPermissions'); + }, + frameRate: { + get: function frameRate() { + return this._frameRate; + }, + set: function frameRate(value) { + this._frameRate = value; + } + }, + scaleMode: { + get: function scaleMode() { + return this._scaleMode; + }, + set: function scaleMode(value) { + this._scaleMode = value; + this._invalid = true; + } + }, + align: { + get: function align() { + return this._align; + }, + set: function align(value) { + this._align = value; + this._invalid = true; + } + }, + stageWidth: { + get: function stageWidth() { + return this._stageWidth / 20; + }, + set: function stageWidth(value) { + notImplemented('Stage.stageWidth'); + this._stageWidth = value * 20 | 0; + } + }, + stageHeight: { + get: function stageHeight() { + return this._stageHeight / 20; + }, + set: function stageHeight(value) { + notImplemented('Stage.stageHeight'); + this._stageHeight = value * 20 | 0; + } + }, + showDefaultContextMenu: { + get: function showDefaultContextMenu() { + return this._showDefaultContextMenu; + }, + set: function showDefaultContextMenu(value) { + somewhatImplemented('Stage.showDefaultContextMenu'); + this._showDefaultContextMenu = value; + } + }, + focus: { + get: function focus() { + return this._focus; + }, + set: function focus(newFocus) { + somewhatImplemented('Stage.focus'); + this._focus = newFocus; + } + }, + colorCorrection: { + get: function colorCorrection() { + return this._colorCorrection; + }, + set: function colorCorrection(value) { + notImplemented('Stage.colorCorrection'); + this._colorCorrection = value; + } + }, + colorCorrectionSupport: { + get: function colorCorrectionSupport() { + return false; + } + }, + stageFocusRect: { + get: function stageFocusRect() { + return this._stageFocusRect; + }, + set: function stageFocusRect(on) { + somewhatImplemented('Stage.stageFocusRect'); + this._stageFocusRect = on; + } + }, + quality: { + get: function quality() { + return this._quality; + }, + set: function quality(value) { + somewhatImplemented('Stage.stageFocusRect'); + this._quality = value; + } + }, + displayState: { + get: function displayState() { + return this._displayState; + }, + set: function displayState(value) { + this._displayState = value; + } + }, + simulatedDisplayState: { + get: function simulatedDisplayState() { + notImplemented('Stage.simulatedDisplayState'); + return this._simulatedDisplayState; + }, + set: function simulatedDisplayState(value) { + notImplemented('Stage.simulatedDisplayState'); + this._simulatedDisplayState = value; + } + }, + fullScreenSourceRect: { + get: function fullScreenSourceRect() { + return this._fullScreenSourceRect; + }, + set: function fullScreenSourceRect(value) { + notImplemented('Stage.fullScreenSourceRect'); + this._fullScreenSourceRect = value; + } + }, + simulatedFullScreenSourceRect: { + get: function simulatedFullScreenSourceRect() { + notImplemented('Stage.simulatedFullScreenSourceRect'); + return this._simulatedFullScreenSourceRect; + }, + set: function simulatedFullScreenSourceRect(value) { + notImplemented('Stage.simulatedFullScreenSourceRect'); + this._simulatedFullScreenSourceRect = value; + } + }, + stageVideos: { + get: function stageVideos() { + somewhatImplemented('Stage.stageVideos'); + return this._stageVideos; + } + }, + stage3Ds: { + get: function stage3Ds() { + notImplemented('Stage.stage3Ds'); + return this._stage3Ds; + } + }, + color: { + get: function color() { + return this._color; + }, + set: function color(color) { + this._color = color; + this._invalid = true; + } + }, + fullScreenWidth: { + get: function fullScreenWidth() { + notImplemented('Stage.fullScreenWidth'); + return this._fullScreenWidth; + } + }, + fullScreenHeight: { + get: function fullScreenHeight() { + notImplemented('Stage.fullScreenHeight'); + return this._fullScreenHeight; + } + }, + wmodeGPU: { + get: function wmodeGPU() { + somewhatImplemented('Stage.wmodeGPU'); + return this._wmodeGPU; + } + }, + softKeyboardRect: { + get: function softKeyboardRect() { + notImplemented('Stage.softKeyboardRect'); + return this._softKeyboardRect; + } + }, + allowsFullScreen: { + get: function allowsFullScreen() { + return false; + } + }, + displayContextInfo: { + get: function displayContextInfo() { + notImplemented('Stage.displayContextInfo'); + return this._displayContextInfo; + } + } + } + } + } + }; + }.call(this); +{ + var EventDefinition = function () { + return { + __class__: 'flash.events.Event', + initialize: function () { + this._stopPropagation = false; + this._stopImmediatePropagation = false; + this._isDefaultPrevented = false; + this._target = null; + this._currentTarget = null; + this._eventPhase = 2; + }, + __glue__: { + native: { + instance: { + ctor: function ctor(type, bubbles, cancelable) { + Counter.count('Event: ' + type); + this._type = type; + this._bubbles = bubbles; + this._cancelable = cancelable; + }, + stopPropagation: function stopPropagation() { + this._stopPropagation = true; + }, + stopImmediatePropagation: function stopImmediatePropagation() { + this._stopImmediatePropagation = this._stopPropagation = true; + }, + preventDefault: function preventDefault() { + if (this._cancelable) + this._isDefaultPrevented = true; + }, + isDefaultPrevented: function isDefaultPrevented() { + return this._isDefaultPrevented; + }, + type: { + get: function type() { + return this._type; + } + }, + bubbles: { + get: function bubbles() { + return this._bubbles; + } + }, + cancelable: { + get: function cancelable() { + return this._cancelable; + } + }, + target: { + get: function target() { + return this._target; + } + }, + currentTarget: { + get: function currentTarget() { + return this._currentTarget; + } + }, + eventPhase: { + get: function eventPhase() { + return this._eventPhase; + } + } + } + }, + script: { + static: Glue.ALL, + instance: { + clone: 'open public clone' + } + } + } + }; + }.call(this); +} +var EventDispatcherDefinition = function () { + var mouseEvents = { + click: true, + contextMenu: true, + doubleClick: true, + middleClick: true, + middleMouseDown: true, + middleMouseUp: true, + mouseDown: true, + mouseMove: true, + mouseOut: true, + mouseOver: true, + mouseUp: true, + mouseWheel: true, + releaseOutside: true, + rightClick: true, + rightMouseDown: true, + rightMouseUp: true, + rollOut: false, + rollOver: false + }; + function doDispatchEvent(dispatcher, event, eventClass, bubbles) { + var target = dispatcher._target; + var type = event._type || event; + var listeners = dispatcher._listeners[type]; + if (bubbles || typeof event === 'string' && mouseEvents[event] || event._bubbles) { + var ancestors = []; + var currentNode = target._parent; + while (currentNode) { + if (currentNode._hasEventListener(type)) { + ancestors.push(currentNode); + } + currentNode = currentNode._parent; + } + if (!listeners && !ancestors.length) { + return true; + } + var keepPropagating = true; + var i = ancestors.length; + while (i-- && keepPropagating) { + var currentTarget = ancestors[i]; + var queue = currentTarget._captureListeners[type]; + keepPropagating = processListeners(queue, event, eventClass, bubbles, target, currentTarget, 1); + } + if (listeners && keepPropagating) { + keepPropagating = processListeners(listeners, event, eventClass, bubbles, target); + } + for (var i = 0; i < ancestors.length && keepPropagating; i++) { + var currentTarget = ancestors[i]; + var queue = currentTarget._listeners[type]; + keepPropagating = processListeners(queue, event, eventClass, bubbles, target, currentTarget, 3); + } + } else if (listeners) { + processListeners(listeners, event, eventClass, bubbles, target); + } + return !event._isDefaultPrevented; + } + function processListeners(queue, event, eventClass, bubbles, target, currentTarget, eventPhase) { + if (queue) { + queue = queue.slice(); + var needsInit = true; + try { + for (var i = 0; i < queue.length; i++) { + var item = queue[i]; + var methodInfo = item.handleEvent.methodInfo; + if (methodInfo) { + if (methodInfo.parameters.length) { + if (!methodInfo.parameters[0].isUsed) { + item.handleEvent(); + continue; + } + } + } + if (needsInit) { + if (typeof event === 'string') { + if (eventClass) { + event = new eventClass(event); + } else { + if (mouseEvents[event]) { + event = new flash.events.MouseEvent(event, mouseEvents[event]); + if (target._stage) { + event._localX = target.mouseX; + event._localY = target.mouseY; + } + } else { + event = new flash.events.Event(event); + } + } + } else if (event._target) { + event = event.clone(); + } + event._target = target; + event._currentTarget = currentTarget || target; + event._eventPhase = eventPhase || 2; + needsInit = false; + } + item.handleEvent(event); + if (event._stopImmediatePropagation) { + break; + } + } + } catch (e) { + avm2.exceptions.push({ + source: 'avm2', + message: e.message, + stack: e.stack + }); + throw e; + } + } + return !event._stopPropagation; + } + return { + __class__: 'flash.events.EventDispatcher', + initialize: function () { + this._target = this; + this._listeners = {}; + this._captureListeners = {}; + }, + _addEventListenerImpl: function addEventListenerImpl(type, listener, useCapture, priority) { + if (typeof listener !== 'function') { + throwError('TypeError', Errors.CheckTypeFailedError, listener, 'Function'); + } + var listeners = useCapture ? this._captureListeners : this._listeners; + var queue = listeners[type]; + var listenerObj = { + handleEvent: listener, + priority: priority || 0 + }; + if (queue) { + var level = queue.length; + var i = level; + while (i--) { + var item = queue[i]; + if (item.handleEvent === listener) { + return; + } + if (priority > item.priority) { + level = i; + } + } + queue.splice(level, 0, listenerObj); + } else { + listeners[type] = [ + listenerObj + ]; + } + }, + _addEventListener: function addEventListener(type, listener, useCapture, priority) { + this._addEventListenerImpl(type, listener, useCapture, priority); + }, + _removeEventListenerImpl: function removeEventListenerImpl(type, listener, useCapture) { + if (typeof listener !== 'function') { + throwError('TypeError', Errors.CheckTypeFailedError, listener, 'Function'); + } + var listeners = useCapture ? this._captureListeners : this._listeners; + var queue = listeners[type]; + if (queue) { + for (var i = 0; i < queue.length; i++) { + var item = queue[i]; + if (item.handleEvent === listener) { + queue.splice(i, 1); + if (!queue.length) { + listeners[type] = null; + } + return; + } + } + } + }, + _removeEventListener: function removeEventListener(type, listener, useCapture) { + this._removeEventListenerImpl(type, listener, useCapture); + }, + _hasEventListener: function hasEventListener(type) { + return this._listeners[type] || this._captureListeners[type]; + }, + _dispatchEvent: function dispatchEvent(event, eventClass, bubbles) { + doDispatchEvent(this, event, eventClass, bubbles); + }, + __glue__: { + native: { + instance: { + ctor: function ctor(target) { + this._target = target || this; + }, + addEventListener: function addEventListener(type, listener, useCapture, priority, useWeakReference) { + this._addEventListener(type, listener, useCapture, priority); + }, + removeEventListener: function removeEventListener(type, listener, useCapture) { + this._removeEventListener(type, listener, useCapture); + }, + hasEventListener: function hasEventListener(type) { + return this._hasEventListener(type); + }, + willTrigger: function willTrigger(type) { + var currentNode = this._target; + do { + if (currentNode._hasEventListener(type)) { + return true; + } + } while (currentNode = currentNode._parent); + return false; + }, + dispatchEventFunction: function dispatchEventFunction(event) { + return doDispatchEvent(this, event); + } + } + } + } + }; + }.call(this); +var KeyboardEventDefinition = function () { + return { + __class__: 'flash.events.KeyboardEvent', + __glue__: { + native: { + instance: { + updateAfterEvent: function updateAfterEvent() { + notImplemented('KeyboardEvent.updateAfterEvent'); + }, + charCode: { + get: function charCode() { + return this._charCode; + }, + set: function charCode(value) { + this._charCode = value; + } + }, + ctrlKey: { + get: function ctrlKey() { + return this._ctrlKey; + }, + set: function ctrlKey(value) { + this._ctrlKey = value; + } + }, + altKey: { + get: function altKey() { + return this._altKey; + }, + set: function altKey(value) { + this._altKey = value; + } + }, + shiftKey: { + get: function shiftKey() { + return this._shiftKey; + }, + set: function shiftKey(value) { + this._shiftKey = value; + } + } + } + }, + script: { + static: Glue.ALL, + instance: { + keyCode: 'public keyCode' + } + } + } + }; + }.call(this); +var MouseEventDefinition = function () { + return { + __class__: 'flash.events.MouseEvent', + initialize: function () { + this._localX = NaN; + this._localY = NaN; + }, + __glue__: { + native: { + instance: { + updateAfterEvent: function updateAfterEvent() { + }, + getStageX: function getStageX() { + if (this._target) { + var m = this._target._getConcatenatedTransform(null, false); + var x = m.a * this._localX + m.c * this._localY + m.tx; + return x / 20; + } + return this._localX / 20; + }, + getStageY: function getStageY() { + if (this._target) { + var m = this._target._getConcatenatedTransform(null, false); + var y = m.d * this._localY + m.b * this._localX + m.ty; + return y / 20; + } + return this._localY / 20; + }, + localX: { + get: function localX() { + return this._localX / 20; + }, + set: function localX(value) { + this._localX = value * 20 | 0; + } + }, + localY: { + get: function localY() { + return this._localY / 20; + }, + set: function localY(value) { + this._localY = value * 20 | 0; + } + } + } + }, + script: { + static: Glue.ALL + } + } + }; + }.call(this); +var TextEventDefinition = function () { + return { + __class__: 'flash.events.TextEvent', + __glue__: { + native: { + instance: { + copyNativeData: function copyNativeData(other) { + notImplemented('TextEvent.copyNativeData'); + } + } + } + } + }; + }.call(this); +var TimerEventDefinition = function () { + return { + __class__: 'flash.events.TimerEvent', + __glue__: { + native: { + instance: { + updateAfterEvent: function updateAfterEvent() { + notImplemented('TimerEvent.updateAfterEvent'); + } + } + } + } + }; + }.call(this); +{ + var ExternalInterfaceDefinition = function () { + function getAvailable() { + return true; + } + var initialized = false; + var registeredCallbacks = {}; + function callIn(functionName, args) { + if (!registeredCallbacks.hasOwnProperty(functionName)) + return; + return registeredCallbacks[functionName](functionName, args); + } + return { + __class__: 'flash.external.ExternalInterface', + initialize: function () { + }, + __glue__: { + native: { + static: { + _initJS: function _initJS() { + if (initialized) + return; + TelemetryService.reportTelemetry({ + topic: 'feature', + feature: EXTERNAL_INTERFACE_FEATURE + }); + initialized = true; + FirefoxCom.initJS(callIn); + }, + _getPropNames: function _getPropNames(obj) { + var keys = []; + forEachPublicProperty(obj, function (key) { + keys.push(key); + }); + return keys; + }, + _addCallback: function _addCallback(functionName, closure, hasNullCallback) { + FirefoxCom.request('externalCom', { + action: 'register', + functionName: functionName, + remove: hasNullCallback + }); + if (hasNullCallback) { + delete registeredCallbacks[functionName]; + } else { + registeredCallbacks[functionName] = closure; + } + }, + _evalJS: function _evalJS(expression) { + return FirefoxCom.requestSync('externalCom', { + action: 'eval', + expression: expression + }); + }, + _callOut: function _callOut(request) { + return FirefoxCom.requestSync('externalCom', { + action: 'call', + request: request + }); + }, + available: { + get: getAvailable + }, + objectID: { + get: function objectID() { + return FirefoxCom.requestSync('externalCom', { + action: 'getId' + }); + } + }, + activeX: { + get: function activeX() { + return false; + } + } + }, + instance: {} + } + } + }; + }.call(this); +} +{ + var BevelFilterDefinition = function () { + var def = { + __class__: 'flash.filters.BevelFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + } + }; + def.__glue__ = {}; + return def; + }.call(this); +} +var BitmapFilterDefinition = function () { + var def = { + __class__: 'flash.filters.BitmapFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + } + }; + def.__glue__ = {}; + return def; + }.call(this); +var BlurFilterDefinition = function () { + return { + __class__: 'flash.filters.BlurFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + var bx = this._blurX * this._quality * 20; + var by = this._blurY * this._quality * 20; + bounds.xMin -= bx; + bounds.xMax += bx; + bounds.yMin -= by; + bounds.yMax += by; + }, + __glue__: { + native: { + static: {}, + instance: { + blurX: { + get: function blurX() { + return this._blurX; + }, + set: function blurX(value) { + this._blurX = value; + } + }, + blurY: { + get: function blurY() { + return this._blurY; + }, + set: function blurY(value) { + this._blurY = value; + } + }, + quality: { + get: function quality() { + return this._quality; + }, + set: function quality(value) { + this._quality = value; + } + } + } + } + } + }; + }.call(this); +var ColorMatrixFilterDefinition = function () { + return { + __class__: 'flash.filters.ColorMatrixFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + }, + __glue__: { + native: { + instance: { + matrix: { + get: function matrix() { + return this._matrix; + }, + set: function matrix(value) { + this._matrix = value; + } + } + } + } + } + }; + }.call(this); +var ConvolutionFilterDefinition = function () { + var def = { + __class__: 'flash.filters.ConvolutionFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + } + }; + def.__glue__ = {}; + return def; + }.call(this); +var DisplacementMapFilterDefinition = function () { + var def = { + __class__: 'flash.filters.DisplacementMapFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + } + }; + def.__glue__ = {}; + return def; + }.call(this); +var DropShadowFilterDefinition = function () { + return { + __class__: 'flash.filters.DropShadowFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + var a = this._angle * Math.PI / 180; + var dy = Math.sin(a) * this._distance; + var dx = Math.cos(a) * this._distance; + var bx = this._blurX * this._quality * 20; + var by = this._blurY * this._quality * 20; + bounds.xMin -= bx - (dx > 0 ? 0 : dx); + bounds.xMax += bx + Math.abs(dx); + bounds.yMin -= by - (dy > 0 ? 0 : dy); + bounds.yMax += by + Math.abs(dy); + }, + __glue__: { + native: { + instance: { + distance: { + get: function distance() { + return this._distance; + }, + set: function distance(value) { + this._distance = value; + } + }, + angle: { + get: function angle() { + return this._angle; + }, + set: function angle(value) { + this._angle = value; + } + }, + color: { + get: function color() { + return this._color; + }, + set: function color(value) { + this._color = value; + } + }, + alpha: { + get: function alpha() { + return this._alpha; + }, + set: function alpha(value) { + this._alpha = value; + } + }, + blurX: { + get: function blurX() { + return this._blurX; + }, + set: function blurX(value) { + this._blurX = value; + } + }, + blurY: { + get: function blurY() { + return this._blurY; + }, + set: function blurY(value) { + this._blurY = value; + } + }, + hideObject: { + get: function hideObject() { + return this._hideObject; + }, + set: function hideObject(value) { + this._hideObject = value; + } + }, + inner: { + get: function inner() { + return this._inner; + }, + set: function inner(value) { + this._inner = value; + } + }, + knockout: { + get: function knockout() { + return this._knockout; + }, + set: function knockout(value) { + this._knockout = value; + } + }, + quality: { + get: function quality() { + return this._quality; + }, + set: function quality(value) { + this._quality = value; + } + }, + strength: { + get: function strength() { + return this._strength; + }, + set: function strength(value) { + this._strength = value; + } + } + } + } + } + }; + }.call(this); +var GlowFilterDefinition = function () { + return { + __class__: 'flash.filters.GlowFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + var bx = this._blurX * this._quality * 20; + var by = this._blurY * this._quality * 20; + bounds.xMin -= bx; + bounds.xMax += bx; + bounds.yMin -= by; + bounds.yMax += by; + }, + __glue__: { + native: { + static: {}, + instance: { + color: { + get: function color() { + return this._color; + }, + set: function color(value) { + this._color = value; + } + }, + alpha: { + get: function alpha() { + return this._alpha; + }, + set: function alpha(value) { + this._alpha = value; + } + }, + blurX: { + get: function blurX() { + return this._blurX; + }, + set: function blurX(value) { + this._blurX = value; + } + }, + blurY: { + get: function blurY() { + return this._blurY; + }, + set: function blurY(value) { + this._blurY = value; + } + }, + inner: { + get: function inner() { + return this._inner; + }, + set: function inner(value) { + this._inner = value; + } + }, + knockout: { + get: function knockout() { + return this._knockout; + }, + set: function knockout(value) { + this._knockout = value; + } + }, + quality: { + get: function quality() { + return this._quality; + }, + set: function quality(value) { + this._quality = value; + } + }, + strength: { + get: function strength() { + return this._strength; + }, + set: function strength(value) { + this._strength = value; + } + } + } + } + } + }; + }.call(this); +var GradientBevelFilterDefinition = function () { + var def = { + __class__: 'flash.filters.GradientBevelFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + } + }; + def.__glue__ = {}; + return def; + }.call(this); +var GradientGlowFilterDefinition = function () { + var def = { + __class__: 'flash.filters.GradientGlowFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + } + }; + def.__glue__ = {}; + return def; + }.call(this); +var ShaderFilterDefinition = function () { + var def = { + __class__: 'flash.filters.ShaderFilter', + initialize: function () { + }, + _updateFilterBounds: function (bounds) { + } + }; + def.__glue__ = {}; + return def; + }.call(this); +{ + var ColorTransformDefinition = function () { + return { + __class__: 'flash.geom.ColorTransform', + __glue__: { + script: { + instance: Glue.ALL + } + } + }; + }.call(this); +} +var MatrixDefinition = function () { + return { + __class__: 'flash.geom.Matrix', + __glue__: { + script: { + instance: Glue.ALL + } + } + }; + }.call(this); +var Matrix3DDefinition = function () { + var precision = 1e-7; + var transposeTransform = new Uint32Array([ + 0, + 4, + 8, + 12, + 1, + 5, + 9, + 13, + 2, + 6, + 10, + 14, + 3, + 7, + 11, + 15 + ]); + function getRotationMatrix(theta, u, v, w, a, b, c) { + var u2 = u * u, v2 = v * v, w2 = w * w; + var L2 = u2 + v2 + w2, L = Math.sqrt(L2); + u /= L; + v /= L; + w /= L; + u2 /= L2; + v2 /= L2; + w2 /= L2; + var cos = Math.cos(theta), sin = Math.sin(theta); + return new flash.geom.Matrix3D([ + u2 + (v2 + w2) * cos, + u * v * (1 - cos) + w * sin, + u * w * (1 - cos) - v * sin, + 0, + u * v * (1 - cos) - w * sin, + v2 + (u2 + w2) * cos, + v * w * (1 - cos) + u * sin, + 0, + u * w * (1 - cos) + v * sin, + v * w * (1 - cos) - u * sin, + w2 + (u2 + v2) * cos, + 0, + (a * (v2 + w2) - u * (b * v + c * w)) * (1 - cos) + (b * w - c * v) * sin, + (b * (u2 + w2) - v * (a * u + c * w)) * (1 - cos) + (c * u - a * w) * sin, + (c * (u2 + v2) - w * (a * u + b * v)) * (1 - cos) + (a * v - b * u) * sin, + 1 + ]); + } + return { + __class__: 'flash.geom.Matrix3D', + initialize: function () { + }, + __glue__: { + native: { + static: { + interpolate: function interpolate(thisMat, toMat, percent) { + notImplemented('Matrix3D.interpolate'); + } + }, + instance: { + ctor: function ctor(v) { + this._matrix = new Float32Array(16); + if (v && v.length >= 16) { + this.copyRawDataFrom(v, 0, false); + } else { + this.identity(); + } + }, + clone: function clone() { + return new flash.geom.Matrix3D(this._matrix); + }, + copyToMatrix3D: function copyToMatrix3D(dest) { + dest._matrix.set(this._matrix); + }, + append: function append(lhs) { + var ma = lhs._matrix, mb = this._matrix, m = this._matrix; + var ma11 = ma[0], ma12 = ma[4], ma13 = ma[8], ma14 = ma[12], ma21 = ma[1], ma22 = ma[5], ma23 = ma[9], ma24 = ma[13], ma31 = ma[2], ma32 = ma[6], ma33 = ma[10], ma34 = ma[14], ma41 = ma[3], ma42 = ma[7], ma43 = ma[11], ma44 = ma[15]; + var mb11 = mb[0], mb12 = mb[4], mb13 = mb[8], mb14 = mb[12], mb21 = mb[1], mb22 = mb[5], mb23 = mb[9], mb24 = mb[13], mb31 = mb[2], mb32 = mb[6], mb33 = mb[10], mb34 = mb[14], mb41 = mb[3], mb42 = mb[7], mb43 = mb[11], mb44 = mb[15]; + m[0] = ma11 * mb11 + ma12 * mb21 + ma13 * mb31 + ma14 * mb41; + m[1] = ma21 * mb11 + ma22 * mb21 + ma23 * mb31 + ma24 * mb41; + m[2] = ma31 * mb11 + ma32 * mb21 + ma33 * mb31 + ma34 * mb41; + m[3] = ma41 * mb11 + ma42 * mb21 + ma43 * mb31 + ma44 * mb41; + m[4] = ma11 * mb12 + ma12 * mb22 + ma13 * mb32 + ma14 * mb42; + m[5] = ma21 * mb12 + ma22 * mb22 + ma23 * mb32 + ma24 * mb42; + m[6] = ma31 * mb12 + ma32 * mb22 + ma33 * mb32 + ma34 * mb42; + m[7] = ma41 * mb12 + ma42 * mb22 + ma43 * mb32 + ma44 * mb42; + m[8] = ma11 * mb13 + ma12 * mb23 + ma13 * mb33 + ma14 * mb43; + m[9] = ma21 * mb13 + ma22 * mb23 + ma23 * mb33 + ma24 * mb43; + m[10] = ma31 * mb13 + ma32 * mb23 + ma33 * mb33 + ma34 * mb43; + m[11] = ma41 * mb13 + ma42 * mb23 + ma43 * mb33 + ma44 * mb43; + m[12] = ma11 * mb14 + ma12 * mb24 + ma13 * mb34 + ma14 * mb44; + m[13] = ma21 * mb14 + ma22 * mb24 + ma23 * mb34 + ma24 * mb44; + m[14] = ma31 * mb14 + ma32 * mb24 + ma33 * mb34 + ma34 * mb44; + m[15] = ma41 * mb14 + ma42 * mb24 + ma43 * mb34 + ma44 * mb44; + }, + prepend: function prepend(rhs) { + var ma = this._matrix, mb = rhs._matrix, m = this._matrix; + var ma11 = ma[0], ma12 = ma[4], ma13 = ma[8], ma14 = ma[12], ma21 = ma[1], ma22 = ma[5], ma23 = ma[9], ma24 = ma[13], ma31 = ma[2], ma32 = ma[6], ma33 = ma[10], ma34 = ma[14], ma41 = ma[3], ma42 = ma[7], ma43 = ma[11], ma44 = ma[15]; + var mb11 = mb[0], mb12 = mb[4], mb13 = mb[8], mb14 = mb[12], mb21 = mb[1], mb22 = mb[5], mb23 = mb[9], mb24 = mb[13], mb31 = mb[2], mb32 = mb[6], mb33 = mb[10], mb34 = mb[14], mb41 = mb[3], mb42 = mb[7], mb43 = mb[11], mb44 = mb[15]; + m[0] = ma11 * mb11 + ma12 * mb21 + ma13 * mb31 + ma14 * mb41; + m[1] = ma21 * mb11 + ma22 * mb21 + ma23 * mb31 + ma24 * mb41; + m[2] = ma31 * mb11 + ma32 * mb21 + ma33 * mb31 + ma34 * mb41; + m[3] = ma41 * mb11 + ma42 * mb21 + ma43 * mb31 + ma44 * mb41; + m[4] = ma11 * mb12 + ma12 * mb22 + ma13 * mb32 + ma14 * mb42; + m[5] = ma21 * mb12 + ma22 * mb22 + ma23 * mb32 + ma24 * mb42; + m[6] = ma31 * mb12 + ma32 * mb22 + ma33 * mb32 + ma34 * mb42; + m[7] = ma41 * mb12 + ma42 * mb22 + ma43 * mb32 + ma44 * mb42; + m[8] = ma11 * mb13 + ma12 * mb23 + ma13 * mb33 + ma14 * mb43; + m[9] = ma21 * mb13 + ma22 * mb23 + ma23 * mb33 + ma24 * mb43; + m[10] = ma31 * mb13 + ma32 * mb23 + ma33 * mb33 + ma34 * mb43; + m[11] = ma41 * mb13 + ma42 * mb23 + ma43 * mb33 + ma44 * mb43; + m[12] = ma11 * mb14 + ma12 * mb24 + ma13 * mb34 + ma14 * mb44; + m[13] = ma21 * mb14 + ma22 * mb24 + ma23 * mb34 + ma24 * mb44; + m[14] = ma31 * mb14 + ma32 * mb24 + ma33 * mb34 + ma34 * mb44; + m[15] = ma41 * mb14 + ma42 * mb24 + ma43 * mb34 + ma44 * mb44; + }, + invert: function invert() { + var d = this.determinant; + if (Math.abs(d) < precision) { + return false; + } + d = 1 / d; + var m = this._matrix; + var m11 = m[0], m12 = m[1], m13 = m[2], m14 = m[3], m21 = m[4], m22 = m[5], m23 = m[6], m24 = m[7], m31 = m[8], m32 = m[9], m33 = m[10], m34 = m[11], m41 = m[12], m42 = m[13], m43 = m[14], m44 = m[15]; + m[0] = d * (m22 * (m33 * m44 - m43 * m34) - m32 * (m23 * m44 - m43 * m24) + m42 * (m23 * m34 - m33 * m24)); + m[1] = -d * (m12 * (m33 * m44 - m43 * m34) - m32 * (m13 * m44 - m43 * m14) + m42 * (m13 * m34 - m33 * m14)); + m[2] = d * (m12 * (m23 * m44 - m43 * m24) - m22 * (m13 * m44 - m43 * m14) + m42 * (m13 * m24 - m23 * m14)); + m[3] = -d * (m12 * (m23 * m34 - m33 * m24) - m22 * (m13 * m34 - m33 * m14) + m32 * (m13 * m24 - m23 * m14)); + m[4] = -d * (m21 * (m33 * m44 - m43 * m34) - m31 * (m23 * m44 - m43 * m24) + m41 * (m23 * m34 - m33 * m24)); + m[5] = d * (m11 * (m33 * m44 - m43 * m34) - m31 * (m13 * m44 - m43 * m14) + m41 * (m13 * m34 - m33 * m14)); + m[6] = -d * (m11 * (m23 * m44 - m43 * m24) - m21 * (m13 * m44 - m43 * m14) + m41 * (m13 * m24 - m23 * m14)); + m[7] = d * (m11 * (m23 * m34 - m33 * m24) - m21 * (m13 * m34 - m33 * m14) + m31 * (m13 * m24 - m23 * m14)); + m[8] = d * (m21 * (m32 * m44 - m42 * m34) - m31 * (m22 * m44 - m42 * m24) + m41 * (m22 * m34 - m32 * m24)); + m[9] = -d * (m11 * (m32 * m44 - m42 * m34) - m31 * (m12 * m44 - m42 * m14) + m41 * (m12 * m34 - m32 * m14)); + m[10] = d * (m11 * (m22 * m44 - m42 * m24) - m21 * (m12 * m44 - m42 * m14) + m41 * (m12 * m24 - m22 * m14)); + m[11] = -d * (m11 * (m22 * m34 - m32 * m24) - m21 * (m12 * m34 - m32 * m14) + m31 * (m12 * m24 - m22 * m14)); + m[12] = -d * (m21 * (m32 * m43 - m42 * m33) - m31 * (m22 * m43 - m42 * m23) + m41 * (m22 * m33 - m32 * m23)); + m[13] = d * (m11 * (m32 * m43 - m42 * m33) - m31 * (m12 * m43 - m42 * m13) + m41 * (m12 * m33 - m32 * m13)); + m[14] = -d * (m11 * (m22 * m43 - m42 * m23) - m21 * (m12 * m43 - m42 * m13) + m41 * (m12 * m23 - m22 * m13)); + m[15] = d * (m11 * (m22 * m33 - m32 * m23) - m21 * (m12 * m33 - m32 * m13) + m31 * (m12 * m23 - m22 * m13)); + return true; + }, + identity: function identity() { + var m = this._matrix; + m[0] = m[5] = m[10] = m[15] = 1; + m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0; + }, + decompose: function decompose(orientationStyle) { + notImplemented('Matrix3D.decompose'); + }, + recompose: function recompose(components, orientationStyle) { + notImplemented('Matrix3D.recompose'); + }, + appendTranslation: function appendTranslation(x, y, z) { + var m = this._matrix; + var m41 = m[3], m42 = m[7], m43 = m[11], m44 = m[15]; + m[0] += x * m41; + m[1] += y * m41; + m[2] += z * m41; + m[4] += x * m42; + m[5] += y * m42; + m[6] += z * m42; + m[8] += x * m43; + m[9] += y * m43; + m[10] += z * m43; + m[12] += x * m44; + m[13] += y * m44; + m[14] += z * m44; + }, + appendRotation: function appendRotation(degrees, axis, pivotPoint) { + this.append(getRotationMatrix(degrees / 180 * Math.PI, axis.x, axis.y, axis.z, pivotPoint ? pivotPoint.x : 0, pivotPoint ? pivotPoint.y : 0, pivotPoint ? pivotPoint.z : 0)); + }, + appendScale: function appendScale(xScale, yScale, zScale) { + var m = this._matrix; + m[0] *= xScale; + m[1] *= yScale; + m[2] *= zScale; + m[4] *= xScale; + m[5] *= yScale; + m[6] *= zScale; + m[8] *= xScale; + m[9] *= yScale; + m[10] *= zScale; + m[12] *= xScale; + m[13] *= yScale; + m[14] *= zScale; + }, + prependTranslation: function prependTranslation(x, y, z) { + var m = this._matrix; + var m11 = m[0], m12 = m[4], m13 = m[8], m14 = m[12], m21 = m[1], m22 = m[5], m23 = m[9], m24 = m[13], m31 = m[2], m32 = m[6], m33 = m[10], m34 = m[14], m41 = m[3], m42 = m[7], m43 = m[11], m44 = m[15]; + m[12] += m11 * x + m12 * y + m13 * z; + m[13] += m21 * x + m22 * y + m23 * z; + m[14] += m31 * x + m32 * y + m33 * z; + m[15] += m41 * x + m42 * y + m43 * z; + }, + prependRotation: function prependRotation(degrees, axis, pivotPoint) { + this.prepend(getRotationMatrix(degrees / 180 * Math.PI, axis.x, axis.y, axis.z, pivotPoint ? pivotPoint.x : 0, pivotPoint ? pivotPoint.y : 0, pivotPoint ? pivotPoint.z : 0)); + }, + prependScale: function prependScale(xScale, yScale, zScale) { + var m = this._matrix; + m[0] *= xScale; + m[1] *= xScale; + m[2] *= xScale; + m[3] *= xScale; + m[4] *= yScale; + m[5] *= yScale; + m[6] *= yScale; + m[7] *= yScale; + m[8] *= zScale; + m[9] *= zScale; + m[10] *= zScale; + m[11] *= zScale; + }, + transformVector: function transformVector(v) { + var m = this._matrix; + var x = v.x, y = v.y, z = v.z; + return new flash.geom.Vector3D(m[0] * x + m[4] * y + m[8] * z + m[12], m[1] * x + m[5] * y + m[9] * z + m[13], m[2] * x + m[6] * y + m[10] * z + m[14]); + }, + deltaTransformVector: function deltaTransformVector(v) { + var m = this._matrix; + var x = v.x, y = v.y, z = v.z; + return new flash.geom.Vector3D(m[0] * x + m[4] * y + m[8] * z, m[1] * x + m[5] * y + m[9] * z, m[2] * x + m[6] * y + m[10] * z); + }, + transformVectors: function transformVectors(vin, vout) { + var m = this._matrix; + var m11 = m[0], m12 = m[4], m13 = m[8], m14 = m[12], m21 = m[1], m22 = m[5], m23 = m[9], m24 = m[13], m31 = m[2], m32 = m[6], m33 = m[10], m34 = m[14], m41 = m[3], m42 = m[7], m43 = m[11], m44 = m[15]; + for (var i = 0; i < vin.length - 2; i += 3) { + var x = vin.asGetNumericProperty(i), y = vin.asGetNumericProperty(i + 1), z = vin.asGetNumericProperty(i + 2); + vout.push(m11 * x + m12 * y + m13 * z + m14); + vout.push(m21 * x + m22 * y + m23 * z + m24); + vout.push(m31 * x + m32 * y + m33 * z + m34); + } + }, + transpose: function transpose() { + var m = this._matrix; + var tmp; + tmp = m[1]; + m[1] = m[4]; + m[4] = tmp; + tmp = m[2]; + m[2] = m[8]; + m[5] = tmp; + tmp = m[3]; + m[3] = m[12]; + m[12] = tmp; + tmp = m[6]; + m[6] = m[9]; + m[9] = tmp; + tmp = m[7]; + m[7] = m[13]; + m[13] = tmp; + tmp = m[11]; + m[11] = m[14]; + m[14] = tmp; + }, + pointAt: function pointAt(pos, at, up) { + notImplemented('Matrix3D.pointAt'); + }, + interpolateTo: function interpolateTo(toMat, percent) { + notImplemented('Matrix3D.interpolateTo'); + }, + copyFrom: function copyFrom(sourceMatrix3D) { + this._matrix.set(sourceMatrix3D._matrix); + }, + copyRawDataTo: function copyRawDataTo(vector, index, transpose) { + var m = this._matrix; + if (transpose) { + for (var i = 0, j = index | 0; i < 16; i++, j++) { + vector.asSetNumericProperty(j, m[transposeTransform[i]]); + } + } else { + for (var i = 0, j = index | 0; i < 16; i++, j++) { + vector.asSetNumericProperty(j, m[i]); + } + } + }, + copyRawDataFrom: function copyRawDataFrom(vector, index, transpose) { + var m = this._matrix; + if (transpose) { + for (var i = 0, j = index | 0; i < 16; i++, j++) { + m[transposeTransform[i]] = vector.asGetNumericProperty(j) || 0; + } + } else { + for (var i = 0, j = index | 0; i < 16; i++, j++) { + m[i] = vector.asGetNumericProperty(j) || 0; + } + } + }, + copyRowTo: function copyRowTo(row, vector3D) { + var offset = row | 0; + var m = this._matrix; + vector3D.x = m[offset]; + vector3D.y = m[offset + 4]; + vector3D.z = m[offset + 8]; + vector3D.w = m[offset + 12]; + }, + copyColumnTo: function copyColumnTo(column, vector3D) { + var offset = column << 2; + var m = this._matrix; + vector3D.x = m[offset]; + vector3D.y = m[offset + 1]; + vector3D.z = m[offset + 2]; + vector3D.w = m[offset + 3]; + }, + copyRowFrom: function copyRowFrom(row, vector3D) { + var offset = row | 0; + var m = this._matrix; + m[offset] = vector3D.x; + m[offset + 4] = vector3D.y; + m[offset + 8] = vector3D.z; + m[offset + 12] = vector3D.w; + }, + copyColumnFrom: function copyColumnFrom(column, vector3D) { + var offset = column << 2; + var m = this._matrix; + m[offset] = vector3D.x; + m[offset + 1] = vector3D.y; + m[offset + 2] = vector3D.z; + m[offset + 3] = vector3D.w; + }, + rawData: { + get: function rawData() { + var result = new Float64Vector(); + this.copyRawDataTo(result, 0, false); + return result; + }, + set: function rawData(v) { + this.copyRawDataFrom(v, 0, false); + } + }, + position: { + get: function position() { + var m = this._matrix; + return new flash.geom.Vector3D(m[12], m[13], m[14]); + }, + set: function position(pos) { + var m = this._matrix; + m[12] = pos.x; + m[13] = pos.y; + m[14] = pos.z; + } + }, + determinant: { + get: function determinant() { + var m = this._matrix; + var m11 = m[0], m12 = m[4], m13 = m[8], m14 = m[12], m21 = m[1], m22 = m[5], m23 = m[9], m24 = m[13], m31 = m[2], m32 = m[6], m33 = m[10], m34 = m[14], m41 = m[3], m42 = m[7], m43 = m[11], m44 = m[15]; + var d; + d = m11 * (m22 * (m33 * m44 - m43 * m34) - m32 * (m23 * m44 - m43 * m24) + m42 * (m23 * m34 - m33 * m24)) - m21 * (m12 * (m33 * m44 - m43 * m34) - m32 * (m13 * m44 - m43 * m14) + m42 * (m13 * m34 - m33 * m14)) + m31 * (m12 * (m23 * m44 - m43 * m24) - m22 * (m13 * m44 - m43 * m14) + m42 * (m13 * m24 - m23 * m14)) - m41 * (m12 * (m23 * m34 - m33 * m24) - m22 * (m13 * m34 - m33 * m14) + m32 * (m13 * m24 - m23 * m14)); + return d; + } + } + } + }, + script: { + instance: Glue.ALL + } + } + }; + }.call(this); +var PointDefinition = function () { + return { + __class__: 'flash.geom.Point', + __glue__: { + script: { + static: Glue.ALL, + instance: Glue.ALL + } + } + }; + }.call(this); +var RectangleDefinition = function () { + return { + __class__: 'flash.geom.Rectangle', + __glue__: { + script: { + instance: Glue.ALL + } + } + }; + }.call(this); +var TransformDefinition = function () { + var def = { + __class__: 'flash.geom.Transform', + get colorTransform() { + var cxform = this._target._cxform; + if (cxform) { + return new flash.geom.ColorTransform(cxform.redMultiplier / 256, cxform.greenMultiplier / 256, cxform.blueMultiplier / 256, cxform.alphaMultiplier / 256, cxform.redOffset, cxform.greenOffset, cxform.blueOffset, cxform.alphaOffset); + } else { + return new flash.geom.ColorTransform(); + } + }, + set colorTransform(val) { + var CTClass = avm2.systemDomain.getClass('flash.geom.ColorTransform'); + if (!CTClass.isInstanceOf(val)) { + throwError('TypeError', Errors.CheckTypeFailedError, val, 'flash.geom.ColorTransform'); + } + this._target._cxform = { + redMultiplier: val.redMultiplier * 256, + greenMultiplier: val.greenMultiplier * 256, + blueMultiplier: val.blueMultiplier * 256, + alphaMultiplier: val.alphaMultiplier * 256, + redOffset: val.redOffset, + greenOffset: val.greenOffset, + blueOffset: val.blueOffset, + alphaOffset: val.alphaOffset + }; + this._target._invalidate(); + }, + get concatenatedColorTransform() { + var cxform = this.colorTransform; + cxform.concat(this._target.parent.transform.concatenatedColorTransform); + return cxform; + }, + get concatenatedMatrix() { + if (this._target._current3DTransform) { + return null; + } + var m = this._target._getConcatenatedTransform(null, false); + return new flash.geom.Matrix(m.a, m.b, m.c, m.d, m.tx / 20, m.ty / 20); + }, + get matrix() { + if (this._target._current3DTransform) { + return null; + } + var m = this._target._currentTransform; + return new flash.geom.Matrix(m.a, m.b, m.c, m.d, m.tx / 20, m.ty / 20); + }, + set matrix(val) { + if (!flash.geom.Matrix.class.isInstanceOf(val)) { + throwError('TypeError', Errors.CheckTypeFailedError, val, 'flash.geom.Matrix'); + } + var target = this._target; + target._invalidate(); + target._setTransformMatrix(val, true); + target._current3DTransform = null; + target._animated = false; + }, + get matrix3D() { + var m = this._target._current3DTransform; + return m && m.clone(); + }, + set matrix3D(val) { + var Matrix3DClass = avm2.systemDomain.getClass('flash.geom.Matrix3D'); + if (!Matrix3DClass.isInstanceOf(val)) { + throwError('TypeError', Errors.CheckTypeFailedError, val, 'flash.geom.Matrix3D'); + } + var raw = val.rawData; + this.matrix = new flash.geom.Matrix(raw.asGetPublicProperty(0), raw.asGetPublicProperty(1), raw.asGetPublicProperty(4), raw.asGetPublicProperty(5), raw.asGetPublicProperty(12), raw.asGetPublicProperty(13)); + this._target._current3DTransform = val; + }, + ctor: function (target) { + this._target = target; + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + colorTransform: desc(def, 'colorTransform'), + concatenatedColorTransform: desc(def, 'concatenatedColorTransform'), + concatenatedMatrix: desc(def, 'concatenatedMatrix'), + matrix: desc(def, 'matrix'), + matrix3D: desc(def, 'matrix3D'), + ctor: def.ctor + } + } + }; + return def; + }.call(this); +var Vector3DDefinition = function () { + return { + __class__: 'flash.geom.Vector3D', + initialize: function () { + }, + __glue__: { + script: { + instance: Glue.ALL + } + } + }; + }.call(this); +{ + var ID3InfoDefinition = function () { + return { + __glue__: { + script: { + instance: { + songName: 'public songName', + genre: 'public genre', + artist: 'public artist', + track: 'public track', + album: 'public album', + year: 'public year', + comment: 'public comment' + } + } + } + }; + }.call(this); +} +var MicrophoneDefinition = function () { + return { + __class__: 'flash.media.Microphone', + initialize: function () { + }, + __glue__: { + native: { + static: { + getMicrophone: function getMicrophone(index) { + notImplemented('Microphone.getMicrophone'); + }, + getEnhancedMicrophone: function getEnhancedMicrophone(index) { + notImplemented('Microphone.getEnhancedMicrophone'); + }, + names: { + get: function names() { + notImplemented('Microphone.names'); + } + }, + isSupported: { + get: function isSupported() { + notImplemented('Microphone.isSupported'); + } + } + }, + instance: { + setSilenceLevel: function setSilenceLevel(silenceLevel, timeout) { + notImplemented('Microphone.setSilenceLevel'); + }, + setUseEchoSuppression: function setUseEchoSuppression(useEchoSuppression) { + notImplemented('Microphone.setUseEchoSuppression'); + }, + setLoopBack: function setLoopBack(state) { + notImplemented('Microphone.setLoopBack'); + }, + gain: { + set: function gain(gain) { + notImplemented('Microphone.gain'); + this._gain = gain; + }, + get: function gain() { + notImplemented('Microphone.gain'); + return this._gain; + } + }, + rate: { + set: function rate(rate) { + notImplemented('Microphone.rate'); + this._rate = rate; + }, + get: function rate() { + notImplemented('Microphone.rate'); + return this._rate; + } + }, + codec: { + set: function codec(codec) { + notImplemented('Microphone.codec'); + this._codec = codec; + }, + get: function codec() { + notImplemented('Microphone.codec'); + return this._codec; + } + }, + framesPerPacket: { + get: function framesPerPacket() { + notImplemented('Microphone.framesPerPacket'); + return this._framesPerPacket; + }, + set: function framesPerPacket(frames) { + notImplemented('Microphone.framesPerPacket'); + this._framesPerPacket = frames; + } + }, + encodeQuality: { + get: function encodeQuality() { + notImplemented('Microphone.encodeQuality'); + return this._encodeQuality; + }, + set: function encodeQuality(quality) { + notImplemented('Microphone.encodeQuality'); + this._encodeQuality = quality; + } + }, + noiseSuppressionLevel: { + get: function noiseSuppressionLevel() { + notImplemented('Microphone.noiseSuppressionLevel'); + return this._noiseSuppressionLevel; + }, + set: function noiseSuppressionLevel(level) { + notImplemented('Microphone.noiseSuppressionLevel'); + this._noiseSuppressionLevel = level; + } + }, + enableVAD: { + get: function enableVAD() { + notImplemented('Microphone.enableVAD'); + return this._enableVAD; + }, + set: function enableVAD(enable) { + notImplemented('Microphone.enableVAD'); + this._enableVAD = enable; + } + }, + activityLevel: { + get: function activityLevel() { + notImplemented('Microphone.activityLevel'); + return this._activityLevel; + } + }, + index: { + get: function index() { + notImplemented('Microphone.index'); + return this._index; + } + }, + muted: { + get: function muted() { + notImplemented('Microphone.muted'); + return this._muted; + } + }, + name: { + get: function name() { + notImplemented('Microphone.name'); + return this._name; + } + }, + silenceLevel: { + get: function silenceLevel() { + notImplemented('Microphone.silenceLevel'); + return this._silenceLevel; + } + }, + silenceTimeout: { + get: function silenceTimeout() { + notImplemented('Microphone.silenceTimeout'); + return this._silenceTimeout; + } + }, + useEchoSuppression: { + get: function useEchoSuppression() { + notImplemented('Microphone.useEchoSuppression'); + return this._useEchoSuppression; + } + }, + soundTransform: { + get: function soundTransform() { + notImplemented('Microphone.soundTransform'); + return this._soundTransform; + }, + set: function soundTransform(sndTransform) { + notImplemented('Microphone.soundTransform'); + this._soundTransform = sndTransform; + } + }, + enhancedOptions: { + get: function enhancedOptions() { + notImplemented('Microphone.enhancedOptions'); + return this._enhancedOptions; + }, + set: function enhancedOptions(options) { + notImplemented('Microphone.enhancedOptions'); + this._enhancedOptions = options; + } + } + } + }, + script: { + instance: Glue.ALL + } + } + }; + }.call(this); +var PLAY_USING_AUDIO_TAG = true; +var SoundDefinition = function () { + function getAudioDescription(soundData, onComplete) { + var audioElement = document.createElement('audio'); + if (!audioElement.canPlayType(soundData.mimeType)) { + onComplete({ + duration: 0 + }); + return; + } + audioElement.preload = 'metadata'; + var blob = new Blob([ + soundData.data + ], { + type: soundData.mimeType + }); + audioElement.src = URL.createObjectURL(blob); + audioElement.load(); + audioElement.addEventListener('loadedmetadata', function () { + onComplete({ + duration: this.duration * 1000 + }); + }); + } + var def = { + initialize: function initialize() { + this._playQueue = []; + this._url = null; + this._length = 0; + this._bytesTotal = 0; + this._bytesLoaded = 0; + this._id3 = new flash.media.ID3Info(); + var s = this.symbol; + if (s) { + var soundData = {}; + if (s.pcm) { + soundData.sampleRate = s.sampleRate; + soundData.channels = s.channels; + soundData.pcm = s.pcm; + soundData.end = s.pcm.length; + } + soundData.completed = true; + if (s.packaged) { + soundData.data = s.packaged.data.buffer; + soundData.mimeType = s.packaged.mimeType; + } + var _this = this; + getAudioDescription(soundData, function (description) { + _this._length = description.duration; + }); + this._soundData = soundData; + } + TelemetryService.reportTelemetry({ + topic: 'feature', + feature: SOUND_FEATURE + }); + }, + close: function close() { + somewhatImplemented('Sound.close'); + }, + extract: function extract(target, length, startPosition) { + notImplemented('Sound.extract'); + }, + _load: function _load(request, checkPolicyFile, bufferTime) { + if (!request) { + return; + } + var _this = this; + var stream = this._stream = new flash.net.URLStream(); + var ByteArrayClass = avm2.systemDomain.getClass('flash.utils.ByteArray'); + var data = ByteArrayClass.createInstance(); + var dataPosition = 0; + var mp3DecodingSession = null; + var soundData = { + completed: false + }; + stream._addEventListener('progress', function (event) { + _this._bytesLoaded = event[Multiname.getPublicQualifiedName('bytesLoaded')]; + _this._bytesTotal = event[Multiname.getPublicQualifiedName('bytesTotal')]; + if (!PLAY_USING_AUDIO_TAG && !mp3DecodingSession) { + mp3DecodingSession = decodeMP3(soundData, function (duration, final) { + if (_this._length === 0) { + _this._soundData = soundData; + _this._playQueue.forEach(function (item) { + item.channel._playSoundDataViaChannel(soundData, item.startTime); + }); + } + _this._length = final ? duration * 1000 : Math.max(duration, mp3DecodingSession.estimateDuration(_this._bytesTotal)) * 1000; + }); + } + var bytesAvailable = stream.bytesAvailable; + stream.readBytes(data, dataPosition, bytesAvailable); + if (mp3DecodingSession) { + mp3DecodingSession.pushData(new Uint8Array(data.a, dataPosition, bytesAvailable)); + } + dataPosition += bytesAvailable; + _this._dispatchEvent(event); + }); + stream._addEventListener('complete', function (event) { + _this._dispatchEvent(event); + soundData.data = data.a; + soundData.mimeType = 'audio/mpeg'; + soundData.completed = true; + if (PLAY_USING_AUDIO_TAG) { + _this._soundData = soundData; + getAudioDescription(soundData, function (description) { + _this._length = description.duration; + }); + _this._playQueue.forEach(function (item) { + item.channel._playSoundDataViaAudio(soundData, item.startTime); + }); + } + if (mp3DecodingSession) { + mp3DecodingSession.close(); + } + }); + stream.load(request); + }, + loadCompressedDataFromByteArray: function loadCompressedDataFromByteArray(bytes, bytesLength) { + notImplemented('Sound#loadCompressedDataFromByteArray'); + }, + loadPCMFromByteArray: function loadPCMFromByteArray(bytes, samples, format, stereo, sampleRate) { + notImplemented('Sound#loadPCMFromByteArray'); + }, + play: function play(startTime, loops, soundTransform) { + startTime = startTime || 0; + loops = loops || 0; + var channel = new flash.media.SoundChannel(); + channel._sound = this; + channel._soundTransform = isNullOrUndefined(soundTransform) ? new flash.media.SoundTransform() : soundTransform; + this._playQueue.push({ + channel: channel, + startTime: startTime + }); + if (this._soundData) { + if (PLAY_USING_AUDIO_TAG) + channel._playSoundDataViaAudio(this._soundData, startTime, loops); + else + channel._playSoundDataViaChannel(this._soundData, startTime, loops); + } + return channel; + }, + get bytesLoaded() { + return this._bytesLoaded; + }, + get bytesTotal() { + return this._bytesTotal; + }, + get id3() { + return this._id3; + }, + get isBuffering() { + notImplemented('Sound#isBuffering'); + }, + get isURLInaccessible() { + notImplemented('Sound#isURLInaccessible'); + }, + get length() { + return this._length; + }, + get url() { + return this._url; + } + }; + function decodeMP3(soundData, ondurationchanged) { + var currentSize = 8000; + var pcm = new Float32Array(currentSize); + var position = 0; + var lastTimeRatio = 0; + var durationEstimationData = { + estimateBitRate: true, + bitRateSum: 0, + bitRateCount: 0, + metadataSize: 0, + averageBitRate: 0 + }; + var mp3DecoderSession = new MP3DecoderSession(); + mp3DecoderSession.onframedata = function (frame, channels, sampleRate, bitRate) { + if (durationEstimationData.estimateBitRate) { + var FramesToEstimate = 200; + if (durationEstimationData.bitRateCount < FramesToEstimate) { + durationEstimationData.bitRateSum += bitRate; + durationEstimationData.bitRateCount++; + } else { + durationEstimationData.estimateBitRate = false; + } + this.averageBitRate = durationEstimationData.bitRateSum / durationEstimationData.bitRateCount; + } + if (frame.length === 0) + return; + if (!position) { + soundData.sampleRate = sampleRate, soundData.channels = channels; + soundData.pcm = pcm; + } + if (position + frame.length >= currentSize) { + do { + currentSize *= 2; + } while (position + frame.length >= currentSize); + var newPcm = new Float32Array(currentSize); + newPcm.set(pcm); + pcm = soundData.pcm = newPcm; + } + pcm.set(frame, position); + soundData.end = position += frame.length; + lastTimeRatio = 1 / soundData.sampleRate / soundData.channels; + ondurationchanged(position * lastTimeRatio, false); + }; + mp3DecoderSession.onid3tag = function (data) { + durationEstimationData.metadataSize += data.length; + }, mp3DecoderSession.onclosed = function () { + ondurationchanged(position * lastTimeRatio, true); + }; + var completed = false; + return { + pushData: function (data) { + mp3DecoderSession.pushAsync(data); + }, + estimateDuration: function (fileSize) { + return Math.max(0, (fileSize - durationEstimationData.metadataSize) * 8 / durationEstimationData.averageBitRate); + }, + close: function () { + mp3DecoderSession.close(); + } + }; + } + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + close: def.close, + extract: def.extract, + _load: def._load, + loadCompressedDataFromByteArray: def.loadCompressedDataFromByteArray, + loadPCMFromByteArray: def.loadPCMFromByteArray, + play: def.play, + bytesLoaded: desc(def, 'bytesLoaded'), + bytesTotal: desc(def, 'bytesTotal'), + id3: desc(def, 'id3'), + isBuffering: desc(def, 'isBuffering'), + isURLInaccessible: desc(def, 'isURLInaccessible'), + length: desc(def, 'length'), + url: desc(def, 'url') + } + } + }; + return def; + }.call(this); +var SoundChannelDefinition = function () { + return { + initialize: function () { + this._element = null; + this._position = 0; + this._leftPeak = 0; + this._rightPeak = 0; + this._pcmData = null; + this._soundTransform = new flash.media.SoundTransform(); + this._soundMixerClass = avm2.systemDomain.getClass('flash.media.SoundMixer'); + var s = this.symbol; + if (s) { + this._element = s.element || null; + } + if (this._element) { + this._registerWithSoundMixer(); + } + }, + _registerWithSoundMixer: function () { + this._soundMixerClass.native.static._registerChannel(this); + }, + _unregisterWithSoundMixer: function () { + this._soundMixerClass.native.static._unregisterChannel(this); + }, + _applySoundTransform: function () { + var volume = this._soundTransform._volume; + if (this._soundMixerClass._soundTransform) { + volume *= this._soundMixerClass._soundTransform._volume; + } + volume *= this._soundMixerClass.native.static._getMasterVolume(); + if (this._element) { + this._element.volume = clamp(volume, 0, 1); + } + if (this._audioChannel) { + } + }, + _playSoundDataViaChannel: function (soundData, startTime, loops) { + this._registerWithSoundMixer(); + var self = this; + var startPosition = Math.round(startTime / 1000 * soundData.sampleRate) * soundData.channels; + var position = startPosition; + this._position = startTime; + this._audioChannel = createAudioChannel(soundData.sampleRate, soundData.channels); + this._audioChannel.ondatarequested = function (e) { + var end = soundData.end; + if (position >= end && soundData.completed) { + self._unregisterWithSoundMixer(); + self._audioChannel.stop(); + self._dispatchEvent(new flash.events.Event('soundComplete', false, false)); + return; + } + var left = e.count; + var data = e.data; + var source = soundData.pcm; + do { + var count = Math.min(end - position, left); + for (var j = 0; j < count; j++) { + data[j] = source[position++]; + } + left -= count; + if (position >= end) { + if (!loops) + break; + loops--; + position = startPosition; + } + } while (left > 0); + self._position = position / soundData.sampleRate / soundData.channels * 1000; + }; + this._audioChannel.start(); + this._applySoundTransform(); + }, + _playSoundDataViaAudio: function (soundData, startTime, loops) { + if (!soundData.mimeType) + return; + this._registerWithSoundMixer(); + this._position = startTime; + var self = this; + var lastCurrentTime = 0; + var element = document.createElement('audio'); + if (!element.canPlayType(soundData.mimeType)) { + console.error('ERROR: "' + soundData.mimeType + '" ' + 'type playback is not supported by the browser'); + return; + } + element.preload = 'metadata'; + element.loop = loops > 0; + var blob = new Blob([ + soundData.data + ], { + type: soundData.mimeType + }); + element.src = URL.createObjectURL(blob); + element.addEventListener('loadeddata', function loaded() { + element.currentTime = startTime / 1000; + element.play(); + }); + element.addEventListener('timeupdate', function timeupdate() { + var currentTime = element.currentTime; + if (loops && lastCurrentTime > currentTime) { + --loops; + if (!loops) + element.loop = false; + if (currentTime < startTime / 1000) + element.currentTime = startTime / 1000; + } + self._position = (lastCurrentTime = currentTime) * 1000; + }); + element.addEventListener('ended', function ended() { + self._unregisterWithSoundMixer(); + self._dispatchEvent(new flash.events.Event('soundComplete', false, false)); + self._element = null; + }); + this._element = element; + this._applySoundTransform(); + }, + __glue__: { + native: { + static: {}, + instance: { + stop: function stop() { + if (this._element) { + this._unregisterWithSoundMixer(); + this._element.pause(); + } + if (this._audioChannel) { + this._unregisterWithSoundMixer(); + this._audioChannel.stop(); + } + }, + 'position': { + get: function position() { + return this._position; + } + }, + 'leftPeak': { + get: function leftPeak() { + return this._leftPeak; + } + }, + 'rightPeak': { + get: function rightPeak() { + return this.rightPeak; + } + }, + 'soundTransform': { + get: function soundTransform() { + somewhatImplemented('SoundChannel.soundTransform'); + return new flash.media.SoundTransform(this._soundTransform._volume, this._soundTransform.pan); + }, + set: function soundTransform(soundTransform) { + somewhatImplemented('SoundChannel.soundTransform'); + this._soundTransform = isNullOrUndefined(soundTransform) ? new flash.media.SoundTransform() : soundTransform; + this._applySoundTransform(); + } + } + } + }, + script: { + instance: scriptProperties('public', [ + 'stop' + ]) + } + } + }; + }.call(this); +function createAudioChannel(sampleRate, channels) { + if (WebAudioChannel.isSupported) + return new WebAudioChannel(sampleRate, channels); + else + error('PCM data playback is not supported by the browser'); +} +function AudioResampler(sourceRate, targetRate) { + this.sourceRate = sourceRate; + this.targetRate = targetRate; + this.tail = []; + this.sourceOffset = 0; +} +AudioResampler.prototype = { + ondatarequested: function (e) { + }, + getData: function (channelsData, count) { + var k = this.sourceRate / this.targetRate; + var offset = this.sourceOffset; + var needed = Math.ceil((count - 1) * k + offset) + 1; + var sourceData = []; + for (var channel = 0; channel < channelsData.length; channel++) + sourceData.push(new Float32Array(needed)); + var e = { + data: sourceData, + count: needed + }; + this.ondatarequested(e); + for (var channel = 0; channel < channelsData.length; channel++) { + var data = channelsData[channel]; + var source = sourceData[channel]; + for (var j = 0; j < count; j++) { + var i = j * k + offset; + var i1 = i | 0, i2 = Math.ceil(i) | 0; + var source_i1 = i1 < 0 ? this.tail[channel] : source[i1]; + if (i1 === i2) { + data[j] = source_i1; + } else { + var alpha = i - i1; + data[j] = source_i1 * (1 - alpha) + source[i2] * alpha; + } + } + this.tail[channel] = source[needed - 1]; + } + this.sourceOffset = (count - 1) * k + offset - (needed - 1); + } +}; +function WebAudioChannel(sampleRate, channels) { + var context = WebAudioChannel.context; + if (!context) { + if (typeof AudioContext !== 'undefined') + context = new AudioContext(); + else + context = new webkitAudioContext(); + WebAudioChannel.context = context; + } + this.context = context; + this.contextSampleRate = context.sampleRate || 44100; + this.channels = channels; + this.sampleRate = sampleRate; + if (this.contextSampleRate != sampleRate) { + this.resampler = new AudioResampler(sampleRate, this.contextSampleRate); + this.resampler.ondatarequested = function (e) { + this.requestData(e.data, e.count); + }.bind(this); + } +} +WebAudioChannel.prototype = { + start: function () { + var source = this.context.createScriptProcessor ? this.context.createScriptProcessor(2048, 0, this.channels) : this.context.createJavaScriptNode(2048, 0, this.channels); + var self = this; + source.onaudioprocess = function (e) { + var channelsData = []; + for (var i = 0; i < self.channels; i++) + channelsData.push(e.outputBuffer.getChannelData(i)); + var count = channelsData[0].length; + if (self.resampler) { + self.resampler.getData(channelsData, count); + } else { + var e = { + data: channelsData, + count: count + }; + self.requestData(channelsData, count); + } + }; + source.connect(this.context.destination); + this.source = source; + }, + stop: function () { + this.source.disconnect(this.context.destination); + }, + requestData: function (channelsData, count) { + var channels = this.channels; + var buffer = new Float32Array(count * channels); + var e = { + data: buffer, + count: buffer.length + }; + this.ondatarequested(e); + for (var j = 0, p = 0; j < count; j++) { + for (var i = 0; i < channels; i++) + channelsData[i][j] = buffer[p++]; + } + } +}; +WebAudioChannel.isSupported = function () { + return typeof AudioContext !== 'undefined' || typeof webkitAudioContext != 'undefined'; +}(); +var SoundMixerDefinition = function () { + var masterVolume = 1; + var registeredChannels = []; + return { + __class__: 'flash.media.SoundMixer', + initialize: function () { + }, + __glue__: { + native: { + static: { + _registerChannel: function _registerChannel(channel) { + registeredChannels.push(channel); + }, + _unregisterChannel: function _unregisterChannel(channel) { + var index = registeredChannels.indexOf(channel); + if (index >= 0) + registeredChannels.splice(index, 1); + }, + _getMasterVolume: function _getMasterVolume() { + return masterVolume; + }, + _setMasterVolume: function _setMasterVolume(volume) { + masterVolume = volume; + registeredChannels.forEach(function (channel) { + channel._applySoundTransform(); + }); + }, + stopAll: function stopAll() { + registeredChannels.forEach(function (channel) { + channel.stop(); + }); + registeredChannels = []; + }, + computeSpectrum: function computeSpectrum(outputArray, FFTMode, stretchFactor) { + somewhatImplemented('SoundMixer.computeSpectrum'); + var data = new Float32Array(1024); + for (var i = 0; i < 1024; i++) { + data[i] = Math.random(); + } + outputArray.writeRawBytes(data); + outputArray.position = 0; + }, + areSoundsInaccessible: function areSoundsInaccessible() { + notImplemented('SoundMixer.areSoundsInaccessible'); + }, + bufferTime: { + get: function bufferTime() { + notImplemented('SoundMixer.bufferTime'); + }, + set: function bufferTime(pA) { + notImplemented('SoundMixer.bufferTime'); + } + }, + soundTransform: { + get: function soundTransform() { + somewhatImplemented('SoundMixer.soundTransform'); + return isNullOrUndefined(this._soundTransform) ? new flash.media.SoundTransform() : new flash.media.SoundTransform(this._soundTransform._volume, this._soundTransform.pan); + }, + set: function soundTransform(soundTransform) { + somewhatImplemented('SoundMixer.soundTransform'); + this._soundTransform = isNullOrUndefined(soundTransform) ? new flash.media.SoundTransform() : soundTransform; + registeredChannels.forEach(function (channel) { + channel._applySoundTransform(); + }); + } + }, + audioPlaybackMode: { + get: function audioPlaybackMode() { + notImplemented('SoundMixer.audioPlaybackMode'); + }, + set: function audioPlaybackMode(pA) { + notImplemented('SoundMixer.audioPlaybackMode'); + } + }, + useSpeakerphoneForVoice: { + get: function useSpeakerphoneForVoice() { + notImplemented('SoundMixer.useSpeakerphoneForVoice'); + }, + set: function useSpeakerphoneForVoice(pA) { + notImplemented('SoundMixer.useSpeakerphoneForVoice'); + } + } + }, + instance: {} + } + } + }; + }.call(this); +var SoundTransformDefinition = function () { + return { + __class__: 'flash.media.SoundTransform', + initialize: function () { + }, + _updateTransform: function () { + somewhatImplemented('SoundTransform._updateTransform'); + }, + __glue__: { + native: { + static: {}, + instance: { + volume: { + get: function volume() { + return this._volume; + }, + set: function volume(volume) { + this._volume = volume; + this._updateTransform(); + } + }, + leftToLeft: { + get: function leftToLeft() { + return this._leftToLeft; + }, + set: function leftToLeft(leftToLeft) { + this._leftToLeft = leftToLeft; + this._updateTransform(); + } + }, + leftToRight: { + get: function leftToRight() { + return this._leftToRight; + }, + set: function leftToRight(leftToRight) { + this._leftToRight = leftToRight; + this._updateTransform(); + } + }, + rightToRight: { + get: function rightToRight() { + return this._rightToRight; + }, + set: function rightToRight(rightToRight) { + this._rightToRight = rightToRight; + this._updateTransform(); + } + }, + rightToLeft: { + get: function rightToLeft() { + return this._rightToLeft; + }, + set: function rightToLeft(rightToLeft) { + this._rightToLeft = rightToLeft; + this._updateTransform(); + } + } + } + }, + script: { + instance: { + pan: 'public pan' + } + } + } + }; + }.call(this); +var StageVideoDefinition = function () { + return { + __class__: 'flash.media.StageVideo', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + attachNetStream: function attachNetStream(netStream) { + notImplemented('StageVideo.attachNetStream'); + }, + attachCamera: function attachCamera(theCamera) { + notImplemented('StageVideo.attachCamera'); + }, + viewPort: { + get: function viewPort() { + notImplemented('StageVideo.viewPort'); + return this._viewPort; + }, + set: function viewPort(rect) { + notImplemented('StageVideo.viewPort'); + this._viewPort = rect; + } + }, + pan: { + set: function pan(point) { + notImplemented('StageVideo.pan'); + this._pan = point; + }, + get: function pan() { + notImplemented('StageVideo.pan'); + return this._pan; + } + }, + zoom: { + set: function zoom(point) { + notImplemented('StageVideo.zoom'); + this._zoom = point; + }, + get: function zoom() { + notImplemented('StageVideo.zoom'); + return this._zoom; + } + }, + depth: { + set: function depth(depth) { + notImplemented('StageVideo.depth'); + this._depth = depth; + }, + get: function depth() { + notImplemented('StageVideo.depth'); + return this._depth; + } + }, + videoWidth: { + get: function videoWidth() { + notImplemented('StageVideo.videoWidth'); + return this._videoWidth; + } + }, + videoHeight: { + get: function videoHeight() { + notImplemented('StageVideo.videoHeight'); + return this._videoHeight; + } + }, + colorSpaces: { + get: function colorSpaces() { + notImplemented('StageVideo.colorSpaces'); + return this._colorSpaces; + } + } + } + } + } + }; + }.call(this); +var VideoDefinition = function () { + function burnHole(ctx, x, y, width, height) { + ctx.save(); + ctx.beginPath(); + ctx.rect(0, 0, width, height); + ctx.clip(); + ctx.clearRect(0, 0, width, height); + ctx.restore(); + } + var def = { + initialize: function initialize() { + TelemetryService.reportTelemetry({ + topic: 'feature', + feature: VIDEO_FEATURE + }); + }, + attachNetStream: function (netStream) { + if (this._netStream === netStream) { + return; + } + if (this._netStream) { + this._netStream._videoReady.then(function (element) { + this._element = null; + if (this._added) { + element.remove(); + this._added = false; + } + }.bind(this)); + } + this._netStream = netStream; + if (!netStream) { + return; + } + netStream._videoReady.then(function (element) { + this._element = element; + netStream._videoMetadataReady.then(function (url) { + this._element.width = this._videoWidth = this._element.videoWidth; + this._element.height = this._videoHeight = this._element.videoHeight; + if (this.stage) { + this.stage._invalid = true; + } + }.bind(this)); + }.bind(this)); + }, + ctor: function (width, height) { + if (!width || width < 0) + width = 320; + if (!height || height < 0) + height = 240; + this._bbox = { + xMin: 0, + yMin: 0, + xMax: width * 20, + yMax: height * 20 + }; + this._initialWidth = this._videoWidth = width; + this._initialHeight = this._videoHeight = height; + this._netStream = null; + this._element = null; + this._added = false; + }, + draw: function (ctx, ratio, ct, parentCtxs) { + if (!this._element) { + return; + } + if (!this._added && this._stage) { + this._stage._domContainer.appendChild(this._element); + this._added = true; + } + var width = this._initialWidth; + var height = this._initialHeight; + var matrix = this._getConcatenatedTransform(null, true); + var scaleFactor = this.stage && this.stage._contentsScaleFactor || 1; + var a = matrix.a / scaleFactor; + var b = matrix.b / scaleFactor; + var c = matrix.c / scaleFactor; + var d = matrix.d / scaleFactor; + var e = matrix.tx / 20 / scaleFactor; + var f = matrix.ty / 20 / scaleFactor; + if (width > 0 && height > 0) { + burnHole(ctx, 0, 0, width, height); + parentCtxs.forEach(function (ctx) { + ctx.save(); + ctx.setTransform(a, b, c, d, e, f); + burnHole(ctx, 0, 0, width, height); + ctx.restore(); + }); + } + var sx = width / this._videoWidth; + var sy = height / this._videoHeight; + var cssTransform = 'transform: matrix(' + sx * a + ',' + sx * b + ',' + sy * c + ',' + sy * d + ',' + e + ',' + f + ');'; + if (this._currentCssTransform !== cssTransform) { + this._currentCssTransform = cssTransform; + this._element.setAttribute('style', 'position: absolute; top:0; left:0; z-index: -100;transform-origin: 0px 0px 0;' + cssTransform + '-webkit-transform-origin: 0px 0px 0; -webkit-' + cssTransform); + } + } + }; + def.__glue__ = { + native: { + instance: { + attachNetStream: def.attachNetStream, + ctor: def.ctor, + smoothing: { + get: function smoothing() { + return this._smoothing; + }, + set: function smoothing(value) { + somewhatImplemented('Video.smoothing'); + this._smoothing = value; + } + }, + videoHeight: { + get: function videoHeight() { + return this._videoHeight; + } + }, + videoWidth: { + get: function videoWidth() { + return this._videoWidth; + } + } + } + } + }; + return def; + }.call(this); +{ + var FileFilterDefinition = function () { + return { + __class__: 'flash.net.FileFilter', + initialize: function () { + this._description = null; + this._extension = null; + this._macType = null; + }, + __glue__: { + native: { + static: {}, + instance: { + description: { + get: function description() { + return this._description; + }, + set: function description(value) { + this._description = value; + } + }, + extension: { + get: function extension() { + return this._extension; + }, + set: function extension(value) { + this._extension = value; + } + }, + macType: { + get: function macType() { + return this._macType; + }, + set: function macType(value) { + this._macType = value; + } + } + } + } + } + }; + }.call(this); +} +var LocalConnectionDefinition = function () { + return { + __class__: 'flash.net.LocalConnection', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + close: function close() { + notImplemented('LocalConnection.close'); + }, + connect: function connect(connectionName) { + notImplemented('LocalConnection.connect'); + }, + send: function send(connectionName, methodName) { + notImplemented('LocalConnection.send'); + }, + allowDomain: function allowDomain() { + notImplemented('LocalConnection.allowDomain'); + }, + allowInsecureDomain: function allowInsecureDomain() { + notImplemented('LocalConnection.allowInsecureDomain'); + }, + domain: { + get: function domain() { + somewhatImplemented('LocalConnection.domain'); + var url = FileLoadingService.resolveUrl('/'); + var m = /:\/\/(.+?)[:?#\/]/.exec(url); + return m && m[1]; + } + }, + client: { + get: function client() { + notImplemented('LocalConnection.client'); + return this._client; + }, + set: function client(client) { + notImplemented('LocalConnection.client'); + this._client = client; + } + }, + isPerUser: { + get: function isPerUser() { + notImplemented('LocalConnection.isPerUser'); + return this._isPerUser; + }, + set: function isPerUser(newValue) { + notImplemented('LocalConnection.isPerUser'); + this._isPerUser = newValue; + } + } + } + } + } + }; + }.call(this); +var NetConnectionDefinition = function () { + var defaultObjectEncoding = 3; + return { + __class__: 'flash.net.NetConnection', + initialize: function () { + TelemetryService.reportTelemetry({ + topic: 'feature', + feature: NETCONNECTION_FEATURE + }); + }, + _invoke: function (index, args) { + var simulated = false, result; + switch (index) { + case 2: + simulated = true; + break; + } + (simulated ? somewhatImplemented : notImplemented)('NetConnection._invoke (' + index + ')'); + return result; + }, + __glue__: { + native: { + static: { + defaultObjectEncoding: { + get: function defaultObjectEncoding() { + return defaultObjectEncoding; + }, + set: function defaultObjectEncoding(version) { + somewhatImplemented('NetConnection.defaultObjectEncoding'); + return defaultObjectEncoding; + } + } + }, + instance: { + ctor: function ctor() { + this._uri = null; + this._connected = false; + this._client = null; + this._proxyType = 'none'; + this._objectEncoding = defaultObjectEncoding; + }, + connect: function connect(command) { + var NetStatusEvent = flash.events.NetStatusEvent; + somewhatImplemented('NetConnection.connect'); + this._uri = command; + if (!command) { + this._connected = true; + this._dispatchEvent(new NetStatusEvent(NetStatusEvent.class.NET_STATUS, false, false, wrapJSObject({ + level: 'status', + code: 'NetConnection.Connect.Success' + }))); + } else { + this._dispatchEvent(new NetStatusEvent(NetStatusEvent.class.NET_STATUS, false, false, wrapJSObject({ + level: 'status', + code: 'NetConnection.Connect.Failed' + }))); + } + }, + call: function call(command, responder) { + notImplemented('NetConnection.call'); + }, + connected: { + get: function connected() { + return this._connected; + } + }, + uri: { + get: function uri() { + return this._uri; + } + }, + client: { + get: function client() { + return this._client; + }, + set: function client(object) { + this._client = object; + } + }, + objectEncoding: { + get: function objectEncoding() { + return this._objectEncoding; + }, + set: function objectEncoding(version) { + somewhatImplemented('NetConnection.objectEncoding'); + this._objectEncoding = version; + } + }, + proxyType: { + get: function proxyType() { + return this._proxyType; + }, + set: function proxyType(ptype) { + notImplemented('NetConnection.proxyType'); + this._proxyType = ptype; + } + }, + connectedProxyType: { + get: function connectedProxyType() { + notImplemented('NetConnection.connectedProxyType'); + return this._connectedProxyType; + } + }, + usingTLS: { + get: function usingTLS() { + somewhatImplemented('NetConnection.usingTLS'); + return false; + } + }, + protocol: { + get: function protocol() { + notImplemented('NetConnection.protocol'); + return this._protocol; + } + }, + maxPeerConnections: { + get: function maxPeerConnections() { + notImplemented('NetConnection.maxPeerConnections'); + return this._maxPeerConnections; + }, + set: function maxPeerConnections(maxPeers) { + notImplemented('NetConnection.maxPeerConnections'); + this._maxPeerConnections = maxPeers; + } + }, + nearID: { + get: function nearID() { + notImplemented('NetConnection.nearID'); + return this._nearID; + } + }, + farID: { + get: function farID() { + notImplemented('NetConnection.farID'); + return this._farID; + } + }, + nearNonce: { + get: function nearNonce() { + notImplemented('NetConnection.nearNonce'); + return this._nearNonce; + } + }, + farNonce: { + get: function farNonce() { + notImplemented('NetConnection.farNonce'); + return this._farNonce; + } + }, + unconnectedPeerStreams: { + get: function unconnectedPeerStreams() { + notImplemented('NetConnection.unconnectedPeerStreams'); + return this._unconnectedPeerStreams; + } + }, + invoke: function invokeWithArgsArray(index) { + return this._invoke(index, Array.prototype.slice.call(arguments, 1)); + }, + invokeWithArgsArray: function invokeWithArgsArray(index, p_arguments) { + return this._invoke.call(this, index, p_arguments); + } + } + } + } + }; + }.call(this); +var USE_MEDIASOURCE_API = false; +var NetStreamDefinition = function () { + return { + __class__: 'flash.net.NetStream', + initialize: function () { + }, + _invoke: function (index, args) { + var simulated = false, result; + var videoElement = this._videoElement; + switch (index) { + case 4: + this._videoState.bufferTime = args[0]; + simulated = true; + break; + case 202: + switch (args[1]) { + case 'pause': + simulated = true; + if (videoElement) { + if (args[3] !== false && !videoElement.paused) { + videoElement.pause(); + } else if (args[3] !== true && videoElement.paused) { + videoElement.play(); + } + videoElement.currentTime = args[4] / 1000; + } + break; + case 'seek': + simulated = true; + if (videoElement && !videoElement.paused) { + videoElement.currentTime = args[3] / 1000; + } + break; + } + break; + case 300: + result = videoElement ? videoElement.currentTime : 0; + simulated = true; + break; + case 302: + result = this._videoState.bufferTime; + simulated = true; + break; + case 303: + result = videoElement ? videoElement.duration : 0; + simulated = true; + break; + case 305: + result = this._videoState.buffer === 'full' ? 100 : this._videoState.buffer === 'progress' ? 50 : 0; + simulated = true; + break; + case 306: + result = 100; + simulated = true; + break; + } + (simulated ? somewhatImplemented : notImplemented)('NetStream._invoke (' + index + ')'); + return result; + }, + _createVideoElement: function (url) { + function notifyPlayStart(e) { + if (netStream._videoState.started) { + return; + } + netStream._videoState.started = true; + netStream._dispatchEvent(new NetStatusEvent(NetStatusEvent.class.NET_STATUS, false, false, wrapJSObject({ + code: 'NetStream.Play.Start', + level: 'status' + }))); + } + function notifyPlayStop(e) { + netStream._videoState.started = false; + netStream._dispatchEvent(new NetStatusEvent(NetStatusEvent.class.NET_STATUS, false, false, wrapJSObject({ + code: 'NetStream.Play.Stop', + level: 'status' + }))); + } + function notifyBufferFull(e) { + netStream._videoState.buffer = 'full'; + netStream._dispatchEvent(new NetStatusEvent(NetStatusEvent.class.NET_STATUS, false, false, wrapJSObject({ + code: 'NetStream.Buffer.Full', + level: 'status' + }))); + } + function notifyProgress(e) { + netStream._videoState.buffer = 'progress'; + } + function notifyBufferEmpty(e) { + netStream._videoState.buffer = 'empty'; + netStream._dispatchEvent(new NetStatusEvent(NetStatusEvent.class.NET_STATUS, false, false, wrapJSObject({ + code: 'NetStream.Buffer.Empty', + level: 'status' + }))); + } + function notifyError(e) { + var code = e.target.error.code === 4 ? 'NetStream.Play.NoSupportedTrackFound' : e.target.error.code === 3 ? 'NetStream.Play.FileStructureInvalid' : 'NetStream.Play.StreamNotFound'; + netStream._dispatchEvent(new NetStatusEvent(NetStatusEvent.class.NET_STATUS, false, false, wrapJSObject({ + code: code, + level: 'error' + }))); + } + function notifyMetadata(e) { + netStream._videoMetadataReady.resolve({ + videoWidth: element.videoWidth, + videoHeight: element.videoHeight + }); + if (netStream._client) { + var data = {}; + data.asSetPublicProperty('width', element.videoWidth); + data.asSetPublicProperty('height', element.videoHeight); + data.asSetPublicProperty('duration', element.duration); + netStream._client.asCallPublicProperty('onMetaData', [ + data + ]); + } + } + var NetStatusEvent = flash.events.NetStatusEvent; + var netStream = this; + if (/\.mp4$/i.test(url) && /Intel Mac OS X.*?Firefox\/\d+/.test(window.navigator.userAgent)) { + url = 'http://videos-cdn.mozilla.net/brand/Mozilla_2011_Story.webm'; + } + var element = document.createElement('video'); + element.preload = 'metadata'; + element.src = url; + element.addEventListener('play', notifyPlayStart); + element.addEventListener('ended', notifyPlayStop); + element.addEventListener('loadeddata', notifyBufferFull); + element.addEventListener('progress', notifyProgress); + element.addEventListener('waiting', notifyBufferEmpty); + element.addEventListener('loadedmetadata', notifyMetadata); + element.addEventListener('error', notifyError); + element.play(); + this._videoElement = element; + this._videoReady.resolve(element); + }, + __glue__: { + script: { + instance: scriptProperties('public', [ + 'appendBytes', + 'appendBytesAction' + ]) + }, + native: { + static: {}, + instance: { + ctor: function ctor(connection, peerID) { + somewhatImplemented('NetStream.ctor'); + this._contentTypeHint = null; + this._mediaSource = null; + this._checkPolicyFile = true; + this._videoElement = null; + var videoReadyResolve, videoReadyReject; + this._videoReady = new Promise(function (resolve, reject) { + videoReadyResolve = resolve; + videoReadyReject = reject; + }); + this._videoReady.resolve = videoReadyResolve; + this._videoReady.reject = videoReadyReject; + var videoMetadataReadyResolve, videoMetadataReadyReject; + this._videoMetadataReady = new Promise(function (resolve, reject) { + videoMetadataReadyResolve = resolve; + videoMetadataReadyReject = reject; + }); + this._videoMetadataReady.resolve = videoMetadataReadyResolve; + this._videoMetadataReady.reject = videoMetadataReadyReject; + this._videoState = { + started: false, + buffer: 'empty', + bufferTime: 0.1 + }; + }, + onResult: function onResult(streamId) { + notImplemented('NetStream.onResult'); + }, + dispose: function dispose() { + notImplemented('NetStream.dispose'); + }, + play: function play(url) { + var isMediaSourceEnabled = USE_MEDIASOURCE_API; + if (isMediaSourceEnabled && typeof MediaSource === 'undefined') { + console.warn('MediaSource API is not enabled, falling back to regular playback'); + isMediaSourceEnabled = false; + } + if (!isMediaSourceEnabled) { + somewhatImplemented('NetStream.play'); + this._createVideoElement(FileLoadingService.resolveUrl(url)); + return; + } + var mediaSource = new MediaSource(); + mediaSource.addEventListener('sourceopen', function (e) { + this._mediaSource = mediaSource; + }.bind(this)); + mediaSource.addEventListener('sourceend', function (e) { + this._mediaSource = null; + }.bind(this)); + this._createVideoElement(window.URL.createObjectURL(mediaSource)); + if (!url) { + return; + } + var request = new flash.net.URLRequest(url); + request._checkPolicyFile = this._checkPolicyFile; + var stream = new flash.net.URLStream(); + stream._addEventListener('httpStatus', function (e) { + var responseHeaders = e.asGetPublicProperty('responseHeaders'); + var contentTypeHeader = responseHeaders.filter(function (h) { + return h.asGetPublicProperty('name') === 'Content-Type'; + })[0]; + if (contentTypeHeader && contentTypeHeader.asGetPublicProperty('value') !== 'application/octet-stream') { + this._contentTypeHint = contentTypeHeader.asGetPublicProperty('value'); + } + }.bind(this)); + stream._addEventListener('progress', function (e) { + var available = stream.bytesAvailable; + var ByteArrayClass = avm2.systemDomain.getClass('flash.utils.ByteArray'); + var data = ByteArrayClass.createInstance(); + stream.readBytes(data, 0, available); + this.appendBytes(data); + }.bind(this)); + stream._addEventListener('complete', function (e) { + this.appendBytesAction('endSequence'); + }.bind(this)); + stream.load(request); + }, + play2: function play2(param) { + notImplemented('NetStream.play2'); + }, + invoke: function invoke(index) { + return this._invoke(index, Array.prototype.slice.call(arguments, 1)); + }, + invokeWithArgsArray: function invokeWithArgsArray(index, p_arguments) { + return this._invoke.call(this, index, p_arguments); + }, + appendBytes: function appendBytes(bytes) { + if (this._mediaSource) { + if (!this._mediaSourceBuffer) { + this._mediaSourceBuffer = this._mediaSource.addSourceBuffer(this._contentTypeHint); + } + this._mediaSourceBuffer.appendBuffer(new Uint8Array(bytes.a, 0, bytes.length)); + } + somewhatImplemented('NetStream.appendBytes'); + }, + appendBytesAction: function appendBytesAction(netStreamAppendBytesAction) { + if (netStreamAppendBytesAction === 'endSequence' && this._mediaSource) { + this._mediaSource.endOfStream(); + } + somewhatImplemented('NetStream.appendBytesAction'); + }, + info: { + get: function info() { + notImplemented('NetStream.info'); + return this._info; + } + }, + multicastInfo: { + get: function multicastInfo() { + notImplemented('NetStream.multicastInfo'); + return this._multicastInfo; + } + }, + soundTransform: { + get: function soundTransform() { + return this._soundTransform; + }, + set: function soundTransform(sndTransform) { + somewhatImplemented('NetStream.soundTransform'); + this._soundTransform = sndTransform; + } + }, + checkPolicyFile: { + get: function checkPolicyFile() { + return this._checkPolicyFile; + }, + set: function checkPolicyFile(state) { + this._checkPolicyFile = state; + } + }, + client: { + get: function client() { + somewhatImplemented('NetStream.client'); + return this._client; + }, + set: function client(object) { + somewhatImplemented('NetStream.client'); + this._client = object; + } + }, + objectEncoding: { + get: function objectEncoding() { + notImplemented('NetStream.objectEncoding'); + return this._objectEncoding; + } + }, + multicastPushNeighborLimit: { + get: function multicastPushNeighborLimit() { + notImplemented('NetStream.multicastPushNeighborLimit'); + return this._multicastPushNeighborLimit; + }, + set: function multicastPushNeighborLimit(neighbors) { + notImplemented('NetStream.multicastPushNeighborLimit'); + this._multicastPushNeighborLimit = neighbors; + } + }, + multicastWindowDuration: { + get: function multicastWindowDuration() { + notImplemented('NetStream.multicastWindowDuration'); + return this._multicastWindowDuration; + }, + set: function multicastWindowDuration(seconds) { + notImplemented('NetStream.multicastWindowDuration'); + this._multicastWindowDuration = seconds; + } + }, + multicastRelayMarginDuration: { + get: function multicastRelayMarginDuration() { + notImplemented('NetStream.multicastRelayMarginDuration'); + return this._multicastRelayMarginDuration; + }, + set: function multicastRelayMarginDuration(seconds) { + notImplemented('NetStream.multicastRelayMarginDuration'); + this._multicastRelayMarginDuration = seconds; + } + }, + multicastAvailabilityUpdatePeriod: { + get: function multicastAvailabilityUpdatePeriod() { + notImplemented('NetStream.multicastAvailabilityUpdatePeriod'); + return this._multicastAvailabilityUpdatePeriod; + }, + set: function multicastAvailabilityUpdatePeriod(seconds) { + notImplemented('NetStream.multicastAvailabilityUpdatePeriod'); + this._multicastAvailabilityUpdatePeriod = seconds; + } + }, + multicastFetchPeriod: { + get: function multicastFetchPeriod() { + notImplemented('NetStream.multicastFetchPeriod'); + return this._multicastFetchPeriod; + }, + set: function multicastFetchPeriod(seconds) { + notImplemented('NetStream.multicastFetchPeriod'); + this._multicastFetchPeriod = seconds; + } + }, + multicastAvailabilitySendToAll: { + get: function multicastAvailabilitySendToAll() { + notImplemented('NetStream.multicastAvailabilitySendToAll'); + return this._multicastAvailabilitySendToAll; + }, + set: function multicastAvailabilitySendToAll(value) { + notImplemented('NetStream.multicastAvailabilitySendToAll'); + this._multicastAvailabilitySendToAll = value; + } + }, + farID: { + get: function farID() { + notImplemented('NetStream.farID'); + return this._farID; + } + }, + nearNonce: { + get: function nearNonce() { + notImplemented('NetStream.nearNonce'); + return this._nearNonce; + } + }, + farNonce: { + get: function farNonce() { + notImplemented('NetStream.farNonce'); + return this._farNonce; + } + }, + peerStreams: { + get: function peerStreams() { + notImplemented('NetStream.peerStreams'); + return this._peerStreams; + } + }, + audioReliable: { + get: function audioReliable() { + notImplemented('NetStream.audioReliable'); + return this._audioReliable; + }, + set: function audioReliable(reliable) { + notImplemented('NetStream.audioReliable'); + this._audioReliable = reliable; + } + }, + videoReliable: { + get: function videoReliable() { + notImplemented('NetStream.videoReliable'); + return this._videoReliable; + }, + set: function videoReliable(reliable) { + notImplemented('NetStream.videoReliable'); + this._videoReliable = reliable; + } + }, + dataReliable: { + get: function dataReliable() { + notImplemented('NetStream.dataReliable'); + return this._dataReliable; + }, + set: function dataReliable(reliable) { + notImplemented('NetStream.dataReliable'); + this._dataReliable = reliable; + } + }, + audioSampleAccess: { + get: function audioSampleAccess() { + notImplemented('NetStream.audioSampleAccess'); + return this._audioSampleAccess; + }, + set: function audioSampleAccess(reliable) { + notImplemented('NetStream.audioSampleAccess'); + this._audioSampleAccess = reliable; + } + }, + videoSampleAccess: { + get: function videoSampleAccess() { + notImplemented('NetStream.videoSampleAccess'); + return this._videoSampleAccess; + }, + set: function videoSampleAccess(reliable) { + notImplemented('NetStream.videoSampleAccess'); + this._videoSampleAccess = reliable; + } + }, + useHardwareDecoder: { + get: function useHardwareDecoder() { + notImplemented('NetStream.useHardwareDecoder'); + return this._useHardwareDecoder; + }, + set: function useHardwareDecoder(v) { + notImplemented('NetStream.useHardwareDecoder'); + this._useHardwareDecoder = v; + } + }, + useJitterBuffer: { + get: function useJitterBuffer() { + notImplemented('NetStream.useJitterBuffer'); + return this._useJitterBuffer; + }, + set: function useJitterBuffer(value) { + notImplemented('NetStream.useJitterBuffer'); + this._useJitterBuffer = value; + } + }, + videoStreamSettings: { + get: function videoStreamSettings() { + notImplemented('NetStream.videoStreamSettings'); + return this._videoStreamSettings; + }, + set: function videoStreamSettings(settings) { + notImplemented('NetStream.videoStreamSettings'); + this._videoStreamSettings = settings; + } + } + } + } + } + }; + }.call(this); +var ObjectEncodingDefinition = function () { + return { + __class__: 'flash.net.ObjectEncoding', + initialize: function () { + }, + __glue__: { + native: { + static: { + dynamicPropertyWriter: { + get: function dynamicPropertyWriter() { + notImplemented('ObjectEncoding.dynamicPropertyWriter'); + }, + set: function dynamicPropertyWriter(object) { + notImplemented('ObjectEncoding.dynamicPropertyWriter'); + } + } + }, + instance: {} + } + } + }; + }.call(this); +var ResponderDefinition = function () { + var def = { + ctor: function (result, status) { + } + }; + def.__glue__ = { + native: { + instance: { + ctor: def.ctor + } + } + }; + return def; + }.call(this); +var SharedObjectDefinition = function () { + var _defaultObjectEncoding = 3; + var sharedObjects = createEmptyObject(); + function invokeWithArgsArray(index, args) { + var simulated = false, result; + switch (index) { + case 4: + result = JSON.stringify(this._data).length - 2; + simulated = true; + break; + case 6: + this._data = {}; + sessionStorage.removeItem(this._path); + simulated = true; + break; + case 2: + sessionStorage.setItem(this._path, JSON.stringify(this._data)); + simulated = true; + result = true; + break; + case 3: + simulated = true; + break; + } + (simulated ? somewhatImplemented : notImplemented)('SharedObject.invoke (' + index + ')'); + return result; + } + return { + __class__: 'flash.net.SharedObject', + initialize: function () { + this._path = null; + this._data = null; + this._objectEncoding = _defaultObjectEncoding; + TelemetryService.reportTelemetry({ + topic: 'feature', + feature: SHAREDOBJECT_FEATURE + }); + }, + __glue__: { + native: { + static: { + deleteAll: function deleteAll(url) { + notImplemented('SharedObject.deleteAll'); + }, + getDiskUsage: function getDiskUsage(url) { + notImplemented('SharedObject.getDiskUsage'); + }, + getLocal: function getLocal(name, localPath, secure) { + var path = (localPath || '') + '/' + name; + if (sharedObjects[path]) { + return sharedObjects[path]; + } + var so = new flash.net.SharedObject(); + so._path = path; + var data = sessionStorage.getItem(path); + so._data = data ? JSON.parse(data) : {}; + return so; + }, + getRemote: function getRemote(name, remotePath, persistence, secure) { + notImplemented('SharedObject.getRemote'); + }, + defaultObjectEncoding: { + get: function defaultObjectEncoding() { + return _defaultObjectEncoding; + }, + set: function defaultObjectEncoding(version) { + _defaultObjectEncoding = version; + } + } + }, + instance: { + setDirty: function setDirty(propertyName) { + somewhatImplemented('SharedObject.setDirty'); + }, + invoke: function invoke(index) { + return invokeWithArgsArray.call(this, index, Array.prototype.slice.call(arguments, 1)); + }, + invokeWithArgsArray: function invokeWithArgsArray(index, args) { + return invokeWithArgsArray.call(this, index, args); + }, + data: { + get: function data() { + return this._data; + } + }, + objectEncoding: { + get: function objectEncoding() { + return this._objectEncoding; + }, + set: function objectEncoding(version) { + this._objectEncoding = version; + } + }, + client: { + get: function client() { + notImplemented('SharedObject.client'); + return this._client; + }, + set: function client(object) { + notImplemented('SharedObject.client'); + this._client = object; + } + } + } + } + } + }; + }.call(this); +var SocketDefinition = function () { + return { + __class__: 'flash.net.Socket', + initialize: function () { + this._connected = false; + }, + __glue__: { + native: { + static: {}, + instance: { + internalGetSecurityErrorMessage: function internalGetSecurityErrorMessage(host, port) { + somewhatImplemented('Socket.internalGetSecurityErrorMessage'); + return 'SecurityErrorEvent'; + }, + internalConnect: function internalConnect(host, port) { + somewhatImplemented('Socket.internalConnect'); + throwError('SecurityError', Errors.SocketConnectError, host, port); + }, + didFailureOccur: function didFailureOccur() { + somewhatImplemented('Socket.didFailureOccur'); + return true; + }, + readBytes: function readBytes(bytes, offset, length) { + notImplemented('Socket.readBytes'); + }, + writeBytes: function writeBytes(bytes, offset, length) { + notImplemented('Socket.writeBytes'); + }, + writeBoolean: function writeBoolean(value) { + notImplemented('Socket.writeBoolean'); + }, + writeByte: function writeByte(value) { + notImplemented('Socket.writeByte'); + }, + writeShort: function writeShort(value) { + notImplemented('Socket.writeShort'); + }, + writeInt: function writeInt(value) { + notImplemented('Socket.writeInt'); + }, + writeUnsignedInt: function writeUnsignedInt(value) { + notImplemented('Socket.writeUnsignedInt'); + }, + writeFloat: function writeFloat(value) { + notImplemented('Socket.writeFloat'); + }, + writeDouble: function writeDouble(value) { + notImplemented('Socket.writeDouble'); + }, + writeMultiByte: function writeMultiByte(value, charSet) { + notImplemented('Socket.writeMultiByte'); + }, + writeUTF: function writeUTF(value) { + notImplemented('Socket.writeUTF'); + }, + writeUTFBytes: function writeUTFBytes(value) { + notImplemented('Socket.writeUTFBytes'); + }, + readBoolean: function readBoolean() { + notImplemented('Socket.readBoolean'); + }, + readByte: function readByte() { + notImplemented('Socket.readByte'); + }, + readUnsignedByte: function readUnsignedByte() { + notImplemented('Socket.readUnsignedByte'); + }, + readShort: function readShort() { + notImplemented('Socket.readShort'); + }, + readUnsignedShort: function readUnsignedShort() { + notImplemented('Socket.readUnsignedShort'); + }, + readInt: function readInt() { + notImplemented('Socket.readInt'); + }, + readUnsignedInt: function readUnsignedInt() { + notImplemented('Socket.readUnsignedInt'); + }, + readFloat: function readFloat() { + notImplemented('Socket.readFloat'); + }, + readDouble: function readDouble() { + notImplemented('Socket.readDouble'); + }, + readMultiByte: function readMultiByte(length, charSet) { + notImplemented('Socket.readMultiByte'); + }, + readUTF: function readUTF() { + notImplemented('Socket.readUTF'); + }, + readUTFBytes: function readUTFBytes(length) { + notImplemented('Socket.readUTFBytes'); + }, + internalClose: function internalClose() { + notImplemented('Socket.internalClose'); + }, + flush: function flush() { + notImplemented('Socket.flush'); + }, + writeObject: function writeObject(object) { + notImplemented('Socket.writeObject'); + }, + readObject: function readObject() { + notImplemented('Socket.readObject'); + }, + bytesAvailable: { + get: function bytesAvailable() { + notImplemented('Socket.bytesAvailable'); + return this._bytesAvailable; + } + }, + connected: { + get: function connected() { + somewhatImplemented('Socket.connected'); + return this._connected; + } + }, + objectEncoding: { + get: function objectEncoding() { + notImplemented('Socket.objectEncoding'); + return this._objectEncoding; + }, + set: function objectEncoding(version) { + notImplemented('Socket.objectEncoding'); + this._objectEncoding = version; + } + }, + endian: { + get: function endian() { + notImplemented('Socket.endian'); + return this._endian; + }, + set: function endian(type) { + notImplemented('Socket.endian'); + this._endian = type; + } + }, + bytesPending: { + get: function bytesPending() { + notImplemented('Socket.bytesPending'); + return this._bytesPending; + } + } + } + }, + script: { + instance: Glue.ALL + } + } + }; + }.call(this); +var URLLoaderDefinition = function () { + return { + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: {} + }, + script: { + static: {}, + instance: { + data: 'public data', + dataFormat: 'public dataFormat', + bytesTotal: 'public bytesTotal', + bytesLoaded: 'public bytesLoaded', + load: 'public load' + } + } + } + }; + }.call(this); +var URLRequestDefinition = function () { + function toFileLoadingServiceRequest() { + var obj = {}; + obj.url = this._url; + obj.method = this._method; + obj.checkPolicyFile = this._checkPolicyFile; + if (this._data) { + obj.mimeType = this._contentType; + var ByteArrayClass = avm2.systemDomain.getClass('flash.utils.ByteArray'); + if (ByteArrayClass.isInstanceOf(this._data)) { + obj.data = new Uint8Array(this._data.a, 0, this._data.length); + } else { + var data = this._data.asGetPublicProperty('toString').call(this._data); + if (this._method === 'GET') { + var i = obj.url.lastIndexOf('?'); + obj.url = (i < 0 ? obj.url : obj.url.substring(0, i)) + '?' + data; + } else { + obj.data = data; + } + } + } + return obj; + } + var def = { + initialize: function () { + this._url = null; + this._method = 'GET'; + this._data = null; + this._digest = null; + this._contentType = 'application/x-www-form-urlencoded'; + this._requestHeaders = null; + this._checkPolicyFile = true; + this._toFileRequest = toFileLoadingServiceRequest; + }, + setMethod: function (val) { + this._method = val; + }, + setRequestHeaders: function (val) { + this._requestHeaders = val; + }, + get contentType() { + return this._contentType; + }, + set contentType(val) { + this._contentType = val; + }, + get data() { + return this._data; + }, + set data(val) { + this._data = val; + }, + get digest() { + return this._digest; + }, + set digest(val) { + this._digest = val; + }, + get method() { + return this._method; + }, + set method(method) { + this._method = method; + }, + get requestHeaders() { + return this._requestHeaders; + }, + set requestHeaders(requestHeaders) { + this._requestHeaders = requestHeaders; + }, + get url() { + return this._url; + }, + set url(val) { + this._url = val; + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + setMethod: def.setMethod, + setRequestHeaders: def.setRequestHeaders, + contentType: desc(def, 'contentType'), + data: desc(def, 'data'), + digest: desc(def, 'digest'), + method: desc(def, 'method'), + requestHeaders: desc(def, 'requestHeaders'), + url: desc(def, 'url') + } + } + }; + return def; + }.call(this); +var URLStreamDefinition = function () { + var def = { + initialize: function () { + this._stream = null; + this._connected = false; + this._littleEndian = false; + }, + close: function close() { + this._session.close(); + }, + load: function load(request) { + var session = FileLoadingService.createSession(); + var self = this; + var initStream = true; + session.onprogress = function (data, progressState) { + if (initStream) { + initStream = false; + var length = Math.max(progressState.bytesTotal, data.length); + var buffer = new ArrayBuffer(length); + self._stream = new Stream(buffer, 0, 0, length); + } else if (self._stream.end + data.length > self._stream.bytes.length) { + var length = self._stream.end + data.length; + var buffer = new ArrayBuffer(length); + var newStream = new Stream(buffer, 0, 0, length); + newStream.push(self._stream.bytes.subarray(0, self._stream.end)); + self._stream = newStream; + } + self._stream.push(data); + var ProgressEventClass = avm2.systemDomain.getClass('flash.events.ProgressEvent'); + self._dispatchEvent(ProgressEventClass.createInstance([ + 'progress', + false, + false, + progressState.bytesLoaded, + progressState.bytesTotal + ])); + }; + session.onerror = function (error) { + self._connected = false; + if (!self._stream) { + self._stream = new Stream(new ArrayBuffer(0), 0, 0, 0); + } + self._dispatchEvent(new flash.events.IOErrorEvent(flash.events.IOErrorEvent.class.IO_ERROR, false, false, error)); + }; + session.onopen = function () { + self._connected = true; + self._dispatchEvent(new flash.events.Event('open', false, false)); + }; + session.onhttpstatus = function (location, httpStatus, httpHeaders) { + var HTTPStatusEventClass = avm2.systemDomain.getClass('flash.events.HTTPStatusEvent'); + var URLRequestHeaderClass = avm2.systemDomain.getClass('flash.net.URLRequestHeader'); + var httpStatusEvent = HTTPStatusEventClass.createInstance([ + 'httpStatus', + false, + false, + httpStatus + ]); + var headers = []; + httpHeaders.split(/(?:\n|\r?\n)/g).forEach(function (h) { + var m = /^([^:]+): (.*)$/.exec(h); + if (m) { + headers.push(URLRequestHeaderClass.createInstance([ + m[1], + m[2] + ])); + if (m[1] === 'Location') { + location = m[2]; + } + } + }); + httpStatusEvent.asSetPublicProperty('responseHeaders', headers); + httpStatusEvent.asSetPublicProperty('responseURL', location); + self._dispatchEvent(httpStatusEvent); + }; + session.onclose = function () { + self._connected = false; + if (!self._stream) { + self._stream = new Stream(new ArrayBuffer(0), 0, 0, 0); + } + self._dispatchEvent(new flash.events.Event('complete', false, false)); + }; + session.open(request._toFileRequest()); + this._session = session; + }, + readBoolean: function readBoolean() { + notImplemented('URLStream.readBoolean'); + }, + readByte: function readByte() { + var stream = this._stream; + stream.ensure(1); + return stream.bytes[stream.pos++]; + }, + readBytes: function readBytes(bytes, offset, length) { + if (length < 0) + throw 'Invalid length argument'; + var stream = this._stream; + if (!length) + length = stream.remaining(); + else + stream.ensure(length); + bytes.writeRawBytes(stream.bytes.subarray(stream.pos, stream.pos + length), offset, length); + stream.pos += length; + }, + readDouble: function readDouble() { + notImplemented('URLStream.readDouble'); + }, + readFloat: function readFloat() { + notImplemented('URLStream.readFloat'); + }, + readInt: function readInt() { + notImplemented('URLStream.readInt'); + }, + readMultiByte: function readMultiByte(length, charSet) { + notImplemented('URLStream.readMultiByte'); + }, + readObject: function readObject() { + notImplemented('URLStream.readObject'); + }, + readShort: function readShort() { + notImplemented('URLStream.readShort'); + }, + readUTF: function readUTF() { + return this.readUTFBytes(this.readUnsignedShort()); + }, + readUTFBytes: function readUTFBytes(length) { + if (length < 0) + throw 'Invalid length argument'; + var stream = this._stream; + stream.ensure(length); + var str = utf8encode(stream.bytes.subarray(stream.pos, stream.pos + length)); + stream.pos += length; + return str; + }, + readUnsignedByte: function readUnsignedByte() { + notImplemented('URLStream.readUnsignedByte'); + }, + readUnsignedInt: function readUnsignedInt() { + notImplemented('URLStream.readUnsignedInt'); + }, + readUnsignedShort: function readUnsignedShort() { + var stream = this._stream; + stream.ensure(2); + var result = stream.getUint16(stream.pos, this._littleEndian); + stream.pos += 2; + return result; + }, + get bytesAvailable() { + return this._stream.remaining(); + }, + get connected() { + return this._connected; + }, + get endian() { + return this._littleEndian ? 'littleEndian' : 'bigEndian'; + }, + set endian(val) { + this._littleEndian = val == 'littleEndian'; + }, + get objectEncoding() { + notImplemented('URLStream.objectEncoding'); + }, + set objectEncoding(val) { + notImplemented('URLStream.objectEncoding'); + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + close: def.close, + load: def.load, + readBoolean: def.readBoolean, + readByte: def.readByte, + readBytes: def.readBytes, + readDouble: def.readDouble, + readFloat: def.readFloat, + readInt: def.readInt, + readMultiByte: def.readMultiByte, + readObject: def.readObject, + readShort: def.readShort, + readUTF: def.readUTF, + readUTFBytes: def.readUTFBytes, + readUnsignedByte: def.readUnsignedByte, + readUnsignedInt: def.readUnsignedInt, + readUnsignedShort: def.readUnsignedShort, + bytesAvailable: desc(def, 'bytesAvailable'), + connected: desc(def, 'connected'), + endian: desc(def, 'endian'), + objectEncoding: desc(def, 'objectEncoding') + } + } + }; + return def; + }.call(this); +{ + var ApplicationDomainDefinition = function () { + return { + __class__: 'flash.system.ApplicationDomain', + initialize: function () { + }, + __glue__: { + native: { + static: { + currentDomain: { + get: function currentDomain() { + return new flash.system.ApplicationDomain(AVM2.currentDomain()); + } + }, + MIN_DOMAIN_MEMORY_LENGTH: { + get: function MIN_DOMAIN_MEMORY_LENGTH() { + notImplemented('ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH'); + } + } + }, + instance: { + ctor: function ctor(parentDomainOrNativeObject) { + if (parentDomainOrNativeObject instanceof ApplicationDomain) { + this.nativeObject = parentDomainOrNativeObject; + return; + } + var parentNativeObject = parentDomainOrNativeObject ? parentDomainOrNativeObject.nativeObject : AVM2.currentDomain().system; + this.nativeObject = new ApplicationDomain(parentNativeObject.vm, parentNativeObject); + }, + getDefinition: function getDefinition(name) { + var simpleName = name.replace('::', '.'); + return this.nativeObject.getProperty(Multiname.fromSimpleName(simpleName), true, true); + }, + hasDefinition: function hasDefinition(name) { + if (name === undefined) { + return false; + } + var simpleName = name.replace('::', '.'); + return !(!this.nativeObject.findDomainProperty(Multiname.fromSimpleName(simpleName), false, false)); + }, + getQualifiedDefinitionNames: function getQualifiedDefinitionNames() { + notImplemented('ApplicationDomain.getQualifiedDefinitionNames'); + }, + parentDomain: { + get: function parentDomain() { + var base = this.nativeObject.base; + if (!base) { + return undefined; + } + return new flash.system.ApplicationDomain(base); + } + }, + domainMemory: { + get: function domainMemory() { + notImplemented('ApplicationDomain.domainMemory'); + return this._domainMemory; + }, + set: function domainMemory(mem) { + notImplemented('ApplicationDomain.domainMemory'); + this._domainMemory = mem; + } + } + } + }, + script: { + static: Glue.ALL, + instance: Glue.ALL + } + } + }; + }.call(this); +} +var CapabilitiesDefinition = function () { + var def = {}; + var os; + var userAgent = window.navigator.userAgent; + if (userAgent.indexOf('Macintosh') > 0) { + os = 'Mac OS 10.5.2'; + } else if (userAgent.indexOf('Windows') > 0) { + os = 'Windows XP'; + } else if (userAgent.indexOf('Linux') > 0) { + os = 'Linux'; + } else if (/(iPad|iPhone|iPod|Android)/.test(userAgent)) { + os = 'iPhone3,1'; + } else { + notImplemented(); + } + def.__glue__ = { + native: { + static: { + version: { + get: function version() { + return 'SHUMWAY 10,0,0,0'; + }, + enumerable: true + }, + os: { + get: function () { + return os; + }, + enumerable: true + }, + serverString: { + get: function () { + var str = toKeyValueArray({ + OS: os + }).map(function (pair) { + return pair[0] + '=' + encodeURIComponent(pair[1]); + }).join('&'); + somewhatImplemented('Capabilities.serverString: ' + str); + return str; + } + }, + hasAccessibility: { + get: function hasAccessibility() { + somewhatImplemented('Capabilities.hasAccessibility'); + return false; + } + }, + isDebugger: { + get: function isDebugger() { + return false; + } + }, + screenResolutionX: { + get: function screenResolutionX() { + return window.screen.width; + } + }, + screenResolutionY: { + get: function screenResolutionY() { + return window.screen.height; + } + }, + manufacturer: { + get: function manufacturer() { + somewhatImplemented('Capabilities.manufacturer'); + return 'Mozilla Research'; + } + }, + language: { + get: function language() { + somewhatImplemented('Capabilities.language'); + return 'en'; + } + }, + playerType: { + get: function playerType() { + somewhatImplemented('Capabilities.playerType'); + return 'PlugIn'; + } + } + } + }, + script: { + static: scriptProperties('public', [ + 'version', + 'os' + ]) + } + }; + return def; + }.call(this); +var FSCommandDefinition = function () { + var def = {}; + function fscommand(command, parameters) { + console.log('FSCommand: ' + command + '; ' + parameters); + switch (command.toLowerCase()) { + case 'quit': + renderingTerminated = true; + return; + case 'debugger': + debugger; + return; + default: + break; + } + } + def.__glue__ = { + native: { + static: { + _fscommand: fscommand + } + } + }; + return def; + }.call(this); +var SecurityDefinition = function () { + var _exactSettings; + return { + __class__: 'flash.system.Security', + initialize: function () { + }, + __glue__: { + native: { + static: { + allowDomain: function allowDomain() { + somewhatImplemented('Security.allowDomain ["' + Array.prototype.join.call(arguments, '", "') + '"]'); + }, + allowInsecureDomain: function allowInsecureDomain() { + somewhatImplemented('Security.allowInsecureDomain'); + }, + loadPolicyFile: function loadPolicyFile(url) { + somewhatImplemented('Security.loadPolicyFile'); + }, + duplicateSandboxBridgeInputArguments: function duplicateSandboxBridgeInputArguments(toplevel, args) { + notImplemented('Security.duplicateSandboxBridgeInputArguments'); + }, + duplicateSandboxBridgeOutputArgument: function duplicateSandboxBridgeOutputArgument(toplevel, arg) { + notImplemented('Security.duplicateSandboxBridgeOutputArgument'); + }, + showSettings: function showSettings(panel) { + notImplemented('Security.showSettings'); + }, + exactSettings: { + get: function () { + return _exactSettings; + }, + set: function (value) { + _exactSettings = value; + } + }, + disableAVM1Loading: { + get: function disableAVM1Loading() { + notImplemented('Security.disableAVM1Loading'); + }, + set: function disableAVM1Loading(value) { + notImplemented('Security.disableAVM1Loading'); + } + }, + sandboxType: { + get: function () { + somewhatImplemented('Security.sandboxType'); + return 'remote'; + } + }, + pageDomain: { + get: function pageDomain() { + somewhatImplemented('Security.pageDomain'); + var pageHost = FileLoadingService.resolveUrl('/'); + var parts = pageHost.split('/'); + parts.pop(); + return parts.pop(); + } + } + } + } + } + }; + }.call(this); +var SecurityDomainDefinition = function () { + return { + __class__: 'flash.system.SecurityDomain', + initialize: function () { + }, + _currentDomain: null, + __glue__: { + native: { + static: { + currentDomain: { + get: function () { + return this._currentDomain; + } + } + }, + instance: { + ctor_impl: function ctor_impl() { + notImplemented('SecurityDomain.ctor_impl'); + }, + domainID: { + get: function domainID() { + notImplemented('SecurityDomain.domainID'); + return this._domainID; + } + } + } + } + } + }; + }.call(this); +var SystemDefinition = function () { + return { + __class__: 'flash.system.System', + initialize: function () { + }, + __glue__: { + native: { + static: { + setClipboard: function setClipboard(string) { + FirefoxCom.request('setClipboard', string); + TelemetryService.reportTelemetry({ + topic: 'feature', + feature: CLIPBOARD_FEATURE + }); + }, + pause: function pause() { + somewhatImplemented('System.pause'); + }, + resume: function resume() { + somewhatImplemented('System.resume'); + }, + exit: function exit(code) { + somewhatImplemented('System.exit'); + renderingTerminated = true; + }, + gc: function gc() { + somewhatImplemented('System.gc'); + }, + pauseForGCIfCollectionImminent: function pauseForGCIfCollectionImminent(imminence) { + notImplemented('System.pauseForGCIfCollectionImminent'); + }, + disposeXML: function disposeXML(node) { + notImplemented('System.disposeXML'); + }, + ime: { + get: function ime() { + notImplemented('System.ime'); + } + }, + totalMemoryNumber: { + get: function totalMemoryNumber() { + if (performance.memory) { + return performance.memory.usedJSHeapSize; + } + return 0; + } + }, + freeMemory: { + get: function freeMemory() { + notImplemented('System.freeMemory'); + } + }, + privateMemory: { + get: function privateMemory() { + return 0; + } + }, + processCPUUsage: { + get: function processCPUUsage() { + notImplemented('System.processCPUUsage'); + } + }, + useCodePage: { + get: function useCodePage() { + somewhatImplemented('System.useCodePage'); + return false; + }, + set: function useCodePage(value) { + notImplemented('System.useCodePage'); + } + }, + vmVersion: { + get: function vmVersion() { + somewhatImplemented('System.vmVersion'); + return '1.0 shumway'; + } + }, + swfVersion: { + get: function () { + return 19; + } + }, + apiVersion: { + get: function () { + return 26; + } + }, + getArgv: function () { + return []; + }, + getRunmode: function () { + return 'mixed'; + } + }, + instance: {} + } + } + }; + }.call(this); +{ + var FontDefinition = function () { + var fonts = []; + var fontsByUniqueName = Object.create(null); + var fontsByNameStyleType = Object.create(null); + var _deviceFontMetrics; + var def = { + __class__: 'flash.text.Font', + initialize: function () { + var s = this.symbol; + if (s) { + this._fontName = s.name || null; + this._uniqueName = s.uniqueName; + if (s.bold) { + if (s.italic) { + this._fontStyle = 'boldItalic'; + } else { + this._fontStyle = 'bold'; + } + } else if (s.italic) { + this._fontStyle = 'italic'; + } else { + this._fontStyle = 'regular'; + } + var metrics = s.metrics; + metrics.height = metrics.ascent + metrics.descent + metrics.leading; + this._metrics = metrics; + this._fontType = 'embedded'; + fonts.push(this); + fontsByUniqueName[this._uniqueName] = this; + var ident = this._fontName.toLowerCase() + '_' + this._fontStyle + '_embedded'; + fontsByNameStyleType[ident] = this; + } + }, + get fontName() { + return this._fontName; + }, + get fontStyle() { + return this._fontStyle; + }, + get fontType() { + return this._fontType; + }, + hasGlyphs: function hasGlyphs(str) { + return true; + }, + getFont: function (name, style, embedded) { + var ident = name.toLowerCase() + '_' + style + (embedded ? '_embedded' : '_device'); + var font = fontsByNameStyleType[ident]; + if (font) { + return font; + } + font = new flash.text.Font(); + font._fontName = font._uniqueName = name; + font._fontStyle = style; + font._fontType = 'device'; + var metrics = deviceFontMetrics()[name]; + if (!metrics) { + metrics = deviceFontMetrics().serif; + font._fontName = font._uniqueName = 'serif'; + } + font._metrics = { + ascent: metrics[0], + descent: metrics[1], + leading: metrics[2] + }; + font._metrics.height = metrics[0] + metrics[1] + metrics[2]; + fontsByNameStyleType[ident] = font; + return font; + }, + getFontByUniqueName: function (name) { + return fontsByUniqueName[name]; + } + }; + function enumerateFonts(device) { + return fonts.slice(); + } + function registerFont(font) { + somewhatImplemented('Font.registerFont'); + } + function deviceFontMetrics() { + if (_deviceFontMetrics) { + return _deviceFontMetrics; + } + var userAgent = window.navigator.userAgent; + if (userAgent.indexOf('Windows') > -1) { + _deviceFontMetrics = DEVICE_FONT_METRICS_WIN; + } else if (/(Macintosh|iPad|iPhone|iPod|Android)/.test(userAgent)) { + _deviceFontMetrics = DEVICE_FONT_METRICS_MAC; + } else { + _deviceFontMetrics = DEVICE_FONT_METRICS_LINUX; + } + return _deviceFontMetrics; + } + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + fontName: desc(def, 'fontName'), + fontStyle: desc(def, 'fontStyle'), + fontType: desc(def, 'fontType'), + hasGlyphs: def.hasGlyphs + }, + static: { + enumerateFonts: enumerateFonts, + registerFont: registerFont + } + } + }; + return def; + }.call(this); + var DEVICE_FONT_METRICS_WIN = { + 'serif': [ + 1, + 0.25, + 0 + ], + 'sans-serif': [ + 1, + 0.25, + 0 + ], + 'monospace': [ + 1, + 0.25, + 0 + ], + 'birch std': [ + 0.9167, + 0.25, + 0 + ], + 'blackoak std': [ + 1, + 0.3333, + 0 + ], + 'chaparral pro': [ + 0.8333, + 0.3333, + 0 + ], + 'chaparral pro light': [ + 0.8333, + 0.3333, + 0 + ], + 'charlemagne std': [ + 0.9167, + 0.25, + 0 + ], + 'cooper std black': [ + 0.9167, + 0.25, + 0 + ], + 'giddyup std': [ + 0.8333, + 0.3333, + 0 + ], + 'hobo std': [ + 1.0833, + 0.3333, + 0 + ], + 'kozuka gothic pro b': [ + 1, + 0.4167, + 0 + ], + 'kozuka gothic pro el': [ + 1.0833, + 0.25, + 0 + ], + 'kozuka gothic pro h': [ + 1, + 0.4167, + 0 + ], + 'kozuka gothic pro l': [ + 1, + 0.3333, + 0 + ], + 'kozuka gothic pro m': [ + 1.0833, + 0.3333, + 0 + ], + 'kozuka gothic pro r': [ + 1, + 0.3333, + 0 + ], + 'kozuka mincho pro b': [ + 1.0833, + 0.25, + 0 + ], + 'kozuka mincho pro el': [ + 1.0833, + 0.25, + 0 + ], + 'kozuka mincho pro h': [ + 1.1667, + 0.25, + 0 + ], + 'kozuka mincho pro l': [ + 1.0833, + 0.25, + 0 + ], + 'kozuka mincho pro m': [ + 1.0833, + 0.25, + 0 + ], + 'kozuka mincho pro r': [ + 1.0833, + 0.25, + 0 + ], + 'mesquite std': [ + 0.9167, + 0.25, + 0 + ], + 'minion pro cond': [ + 1, + 0.3333, + 0 + ], + 'minion pro med': [ + 1, + 0.3333, + 0 + ], + 'minion pro smbd': [ + 1, + 0.3333, + 0 + ], + 'myriad arabic': [ + 1, + 0.4167, + 0 + ], + 'nueva std': [ + 0.75, + 0.25, + 0 + ], + 'nueva std cond': [ + 0.75, + 0.25, + 0 + ], + 'ocr a std': [ + 0.8333, + 0.25, + 0 + ], + 'orator std': [ + 1.0833, + 0.25, + 0 + ], + 'poplar std': [ + 0.9167, + 0.25, + 0 + ], + 'prestige elite std': [ + 0.9167, + 0.25, + 0 + ], + 'rosewood std regular': [ + 0.8333, + 0.3333, + 0 + ], + 'stencil std': [ + 1, + 0.3333, + 0 + ], + 'trajan pro': [ + 1, + 0.25, + 0 + ], + 'kozuka gothic pr6n b': [ + 1.4167, + 0.4167, + 0 + ], + 'kozuka gothic pr6n el': [ + 1.4167, + 0.3333, + 0 + ], + 'kozuka gothic pr6n h': [ + 1.4167, + 0.4167, + 0 + ], + 'kozuka gothic pr6n l': [ + 1.4167, + 0.3333, + 0 + ], + 'kozuka gothic pr6n m': [ + 1.5, + 0.3333, + 0 + ], + 'kozuka gothic pr6n r': [ + 1.4167, + 0.3333, + 0 + ], + 'kozuka mincho pr6n b': [ + 1.3333, + 0.3333, + 0 + ], + 'kozuka mincho pr6n el': [ + 1.3333, + 0.3333, + 0 + ], + 'kozuka mincho pr6n h': [ + 1.4167, + 0.3333, + 0 + ], + 'kozuka mincho pr6n l': [ + 1.3333, + 0.3333, + 0 + ], + 'kozuka mincho pr6n m': [ + 1.3333, + 0.3333, + 0 + ], + 'kozuka mincho pr6n r': [ + 1.3333, + 0.3333, + 0 + ], + 'letter gothic std': [ + 1, + 0.25, + 0 + ], + 'minion pro': [ + 1, + 0.3333, + 0 + ], + 'myriad hebrew': [ + 0.8333, + 0.3333, + 0 + ], + 'myriad pro': [ + 0.9167, + 0.25, + 0 + ], + 'myriad pro cond': [ + 0.9167, + 0.25, + 0 + ], + 'myriad pro light': [ + 1, + 0.25, + 0 + ], + 'marlett': [ + 1, + 0, + 0 + ], + 'arial': [ + 1, + 0.25, + 0 + ], + 'arabic transparent': [ + 1, + 0.25, + 0 + ], + 'arial baltic': [ + 1, + 0.25, + 0 + ], + 'arial ce': [ + 1, + 0.25, + 0 + ], + 'arial cyr': [ + 1, + 0.25, + 0 + ], + 'arial greek': [ + 1, + 0.25, + 0 + ], + 'arial tur': [ + 1, + 0.25, + 0 + ], + 'batang': [ + 0.8333, + 0.1667, + 0 + ], + 'batangche': [ + 0.8333, + 0.1667, + 0 + ], + 'gungsuh': [ + 0.8333, + 0.1667, + 0 + ], + 'gungsuhche': [ + 0.8333, + 0.1667, + 0 + ], + 'courier new': [ + 1, + 0.25, + 0 + ], + 'courier new baltic': [ + 1, + 0.25, + 0 + ], + 'courier new ce': [ + 1, + 0.25, + 0 + ], + 'courier new cyr': [ + 1, + 0.25, + 0 + ], + 'courier new greek': [ + 1, + 0.25, + 0 + ], + 'courier new tur': [ + 1, + 0.25, + 0 + ], + 'daunpenh': [ + 0.6667, + 0.6667, + 0 + ], + 'dokchampa': [ + 1.4167, + 0.5833, + 0 + ], + 'estrangelo edessa': [ + 0.75, + 0.3333, + 0 + ], + 'euphemia': [ + 1.0833, + 0.3333, + 0 + ], + 'gautami': [ + 1.1667, + 0.8333, + 0 + ], + 'vani': [ + 1.0833, + 0.75, + 0 + ], + 'gulim': [ + 0.8333, + 0.1667, + 0 + ], + 'gulimche': [ + 0.8333, + 0.1667, + 0 + ], + 'dotum': [ + 0.8333, + 0.1667, + 0 + ], + 'dotumche': [ + 0.8333, + 0.1667, + 0 + ], + 'impact': [ + 1.0833, + 0.25, + 0 + ], + 'iskoola pota': [ + 1, + 0.3333, + 0 + ], + 'kalinga': [ + 1.0833, + 0.5, + 0 + ], + 'kartika': [ + 1, + 0.4167, + 0 + ], + 'khmer ui': [ + 1.0833, + 0.3333, + 0 + ], + 'lao ui': [ + 1, + 0.25, + 0 + ], + 'latha': [ + 1.0833, + 0.4167, + 0 + ], + 'lucida console': [ + 0.75, + 0.25, + 0 + ], + 'malgun gothic': [ + 1, + 0.25, + 0 + ], + 'mangal': [ + 1.0833, + 0.3333, + 0 + ], + 'meiryo': [ + 1.0833, + 0.4167, + 0 + ], + 'meiryo ui': [ + 1, + 0.25, + 0 + ], + 'microsoft himalaya': [ + 0.5833, + 0.4167, + 0 + ], + 'microsoft jhenghei': [ + 1, + 0.3333, + 0 + ], + 'microsoft yahei': [ + 1.0833, + 0.3333, + 0 + ], + 'mingliu': [ + 0.8333, + 0.1667, + 0 + ], + 'pmingliu': [ + 0.8333, + 0.1667, + 0 + ], + 'mingliu_hkscs': [ + 0.8333, + 0.1667, + 0 + ], + 'mingliu-extb': [ + 0.8333, + 0.1667, + 0 + ], + 'pmingliu-extb': [ + 0.8333, + 0.1667, + 0 + ], + 'mingliu_hkscs-extb': [ + 0.8333, + 0.1667, + 0 + ], + 'mongolian baiti': [ + 0.8333, + 0.25, + 0 + ], + 'ms gothic': [ + 0.8333, + 0.1667, + 0 + ], + 'ms pgothic': [ + 0.8333, + 0.1667, + 0 + ], + 'ms ui gothic': [ + 0.8333, + 0.1667, + 0 + ], + 'ms mincho': [ + 0.8333, + 0.1667, + 0 + ], + 'ms pmincho': [ + 0.8333, + 0.1667, + 0 + ], + 'mv boli': [ + 1.1667, + 0.25, + 0 + ], + 'microsoft new tai lue': [ + 1, + 0.4167, + 0 + ], + 'nyala': [ + 0.9167, + 0.3333, + 0 + ], + 'microsoft phagspa': [ + 1.0833, + 0.25, + 0 + ], + 'plantagenet cherokee': [ + 1, + 0.4167, + 0 + ], + 'raavi': [ + 1.0833, + 0.6667, + 0 + ], + 'segoe script': [ + 1.0833, + 0.5, + 0 + ], + 'segoe ui': [ + 1, + 0.25, + 0 + ], + 'segoe ui semibold': [ + 1, + 0.25, + 0 + ], + 'segoe ui light': [ + 1, + 0.25, + 0 + ], + 'segoe ui symbol': [ + 1, + 0.25, + 0 + ], + 'shruti': [ + 1.0833, + 0.5, + 0 + ], + 'simsun': [ + 0.8333, + 0.1667, + 0 + ], + 'nsimsun': [ + 0.8333, + 0.1667, + 0 + ], + 'simsun-extb': [ + 0.8333, + 0.1667, + 0 + ], + 'sylfaen': [ + 1, + 0.3333, + 0 + ], + 'microsoft tai le': [ + 1, + 0.3333, + 0 + ], + 'times new roman': [ + 1, + 0.25, + 0 + ], + 'times new roman baltic': [ + 1, + 0.25, + 0 + ], + 'times new roman ce': [ + 1, + 0.25, + 0 + ], + 'times new roman cyr': [ + 1, + 0.25, + 0 + ], + 'times new roman greek': [ + 1, + 0.25, + 0 + ], + 'times new roman tur': [ + 1, + 0.25, + 0 + ], + 'tunga': [ + 1.0833, + 0.75, + 0 + ], + 'vrinda': [ + 1, + 0.4167, + 0 + ], + 'shonar bangla': [ + 0.8333, + 0.5, + 0 + ], + 'microsoft yi baiti': [ + 0.8333, + 0.1667, + 0 + ], + 'tahoma': [ + 1, + 0.1667, + 0 + ], + 'microsoft sans serif': [ + 1.0833, + 0.1667, + 0 + ], + 'angsana new': [ + 0.9167, + 0.4167, + 0 + ], + 'aparajita': [ + 0.75, + 0.4167, + 0 + ], + 'cordia new': [ + 0.9167, + 0.5, + 0 + ], + 'ebrima': [ + 1.0833, + 0.5, + 0 + ], + 'gisha': [ + 0.9167, + 0.25, + 0 + ], + 'kokila': [ + 0.8333, + 0.3333, + 0 + ], + 'leelawadee': [ + 0.9167, + 0.25, + 0 + ], + 'microsoft uighur': [ + 1.0833, + 0.5, + 0 + ], + 'moolboran': [ + 0.6667, + 0.6667, + 0 + ], + 'symbol': [ + 1, + 0.25, + 0 + ], + 'utsaah': [ + 0.8333, + 0.4167, + 0 + ], + 'vijaya': [ + 1.0833, + 0.25, + 0 + ], + 'wingdings': [ + 0.9167, + 0.25, + 0 + ], + 'andalus': [ + 1.3333, + 0.4167, + 0 + ], + 'arabic typesetting': [ + 0.8333, + 0.5, + 0 + ], + 'simplified arabic': [ + 1.3333, + 0.5, + 0 + ], + 'simplified arabic fixed': [ + 1, + 0.4167, + 0 + ], + 'sakkal majalla': [ + 0.9167, + 0.5, + 0 + ], + 'traditional arabic': [ + 1.3333, + 0.5, + 0 + ], + 'aharoni': [ + 0.75, + 0.25, + 0 + ], + 'david': [ + 0.75, + 0.25, + 0 + ], + 'frankruehl': [ + 0.75, + 0.25, + 0 + ], + 'fangsong': [ + 0.8333, + 0.1667, + 0 + ], + 'simhei': [ + 0.8333, + 0.1667, + 0 + ], + 'kaiti': [ + 0.8333, + 0.1667, + 0 + ], + 'browallia new': [ + 0.8333, + 0.4167, + 0 + ], + 'lucida sans unicode': [ + 1.0833, + 0.25, + 0 + ], + 'arial black': [ + 1.0833, + 0.3333, + 0 + ], + 'calibri': [ + 0.9167, + 0.25, + 0 + ], + 'cambria': [ + 0.9167, + 0.25, + 0 + ], + 'cambria math': [ + 3.0833, + 2.5, + 0 + ], + 'candara': [ + 0.9167, + 0.25, + 0 + ], + 'comic sans ms': [ + 1.0833, + 0.3333, + 0 + ], + 'consolas': [ + 0.9167, + 0.25, + 0 + ], + 'constantia': [ + 0.9167, + 0.25, + 0 + ], + 'corbel': [ + 0.9167, + 0.25, + 0 + ], + 'franklin gothic medium': [ + 1, + 0.3333, + 0 + ], + 'gabriola': [ + 1.1667, + 0.6667, + 0 + ], + 'georgia': [ + 1, + 0.25, + 0 + ], + 'palatino linotype': [ + 1.0833, + 0.3333, + 0 + ], + 'segoe print': [ + 1.25, + 0.5, + 0 + ], + 'trebuchet ms': [ + 1.0833, + 0.4167, + 0 + ], + 'verdana': [ + 1, + 0.1667, + 0 + ], + 'webdings': [ + 1.0833, + 0.5, + 0 + ], + 'lucida bright': [ + 0.9167, + 0.25, + 0 + ], + 'lucida sans': [ + 0.9167, + 0.25, + 0 + ], + 'lucida sans typewriter': [ + 0.9167, + 0.25, + 0 + ], + 'gentium basic': [ + 0.8333, + 0.25, + 0 + ], + 'dejavu serif condensed': [ + 0.9167, + 0.25, + 0 + ], + 'arimo': [ + 1, + 0.25, + 0 + ], + 'dejavu sans condensed': [ + 0.9167, + 0.25, + 0 + ], + 'dejavu sans': [ + 0.9167, + 0.25, + 0 + ], + 'dejavu sans light': [ + 0.9167, + 0.25, + 0 + ], + 'opensymbol': [ + 0.8333, + 0.1667, + 0 + ], + 'gentium book basic': [ + 0.8333, + 0.25, + 0 + ], + 'dejavu sans mono': [ + 0.9167, + 0.25, + 0 + ], + 'dejavu serif': [ + 0.9167, + 0.25, + 0 + ], + 'calibri light': [ + 0.9167, + 0.25, + 0 + ] + }; + var DEVICE_FONT_METRICS_MAC = { + 'al bayan plain': [ + 1, + 0.5, + 0 + ], + 'al bayan bold': [ + 1, + 0.5833, + 0 + ], + 'american typewriter': [ + 0.9167, + 0.25, + 0 + ], + 'american typewriter bold': [ + 0.9167, + 0.25, + 0 + ], + 'american typewriter condensed': [ + 0.9167, + 0.25, + 0 + ], + 'american typewriter condensed bold': [ + 0.9167, + 0.25, + 0 + ], + 'american typewriter condensed light': [ + 0.8333, + 0.25, + 0 + ], + 'american typewriter light': [ + 0.9167, + 0.25, + 0 + ], + 'andale mono': [ + 0.9167, + 0.25, + 0 + ], + 'apple symbols': [ + 0.6667, + 0.25, + 0 + ], + 'arial bold italic': [ + 0.9167, + 0.25, + 0 + ], + 'arial bold': [ + 0.9167, + 0.25, + 0 + ], + 'arial italic': [ + 0.9167, + 0.25, + 0 + ], + 'arial hebrew': [ + 0.75, + 0.3333, + 0 + ], + 'arial hebrew bold': [ + 0.75, + 0.3333, + 0 + ], + 'arial': [ + 0.9167, + 0.25, + 0 + ], + 'arial narrow': [ + 0.9167, + 0.25, + 0 + ], + 'arial narrow bold': [ + 0.9167, + 0.25, + 0 + ], + 'arial narrow bold italic': [ + 0.9167, + 0.25, + 0 + ], + 'arial narrow italic': [ + 0.9167, + 0.25, + 0 + ], + 'arial rounded mt bold': [ + 0.9167, + 0.25, + 0 + ], + 'arial unicode ms': [ + 1.0833, + 0.25, + 0 + ], + 'avenir black': [ + 1, + 0.3333, + 0 + ], + 'avenir black oblique': [ + 1, + 0.3333, + 0 + ], + 'avenir book': [ + 1, + 0.3333, + 0 + ], + 'avenir book oblique': [ + 1, + 0.3333, + 0 + ], + 'avenir heavy': [ + 1, + 0.3333, + 0 + ], + 'avenir heavy oblique': [ + 1, + 0.3333, + 0 + ], + 'avenir light': [ + 1, + 0.3333, + 0 + ], + 'avenir light oblique': [ + 1, + 0.3333, + 0 + ], + 'avenir medium': [ + 1, + 0.3333, + 0 + ], + 'avenir medium oblique': [ + 1, + 0.3333, + 0 + ], + 'avenir oblique': [ + 1, + 0.3333, + 0 + ], + 'avenir roman': [ + 1, + 0.3333, + 0 + ], + 'avenir next bold': [ + 1, + 0.3333, + 0 + ], + 'avenir next bold italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next demi bold': [ + 1, + 0.3333, + 0 + ], + 'avenir next demi bold italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next heavy': [ + 1, + 0.3333, + 0 + ], + 'avenir next heavy italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next medium': [ + 1, + 0.3333, + 0 + ], + 'avenir next medium italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next regular': [ + 1, + 0.3333, + 0 + ], + 'avenir next ultra light': [ + 1, + 0.3333, + 0 + ], + 'avenir next ultra light italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed bold': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed bold italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed demi bold': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed demi bold italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed heavy': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed heavy italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed medium': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed medium italic': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed regular': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed ultra light': [ + 1, + 0.3333, + 0 + ], + 'avenir next condensed ultra light italic': [ + 1, + 0.3333, + 0 + ], + 'ayuthaya': [ + 1.0833, + 0.3333, + 0 + ], + 'baghdad': [ + 0.9167, + 0.4167, + 0 + ], + 'bangla mn': [ + 0.9167, + 0.6667, + 0 + ], + 'bangla mn bold': [ + 0.9167, + 0.6667, + 0 + ], + 'bangla sangam mn': [ + 0.9167, + 0.4167, + 0 + ], + 'bangla sangam mn bold': [ + 0.9167, + 0.4167, + 0 + ], + 'baskerville': [ + 0.9167, + 0.25, + 0 + ], + 'baskerville bold': [ + 0.9167, + 0.25, + 0 + ], + 'baskerville bold italic': [ + 0.9167, + 0.25, + 0 + ], + 'baskerville italic': [ + 0.9167, + 0.25, + 0 + ], + 'baskerville semibold': [ + 0.9167, + 0.25, + 0 + ], + 'baskerville semibold italic': [ + 0.9167, + 0.25, + 0 + ], + 'big caslon medium': [ + 0.9167, + 0.25, + 0 + ], + 'brush script mt italic': [ + 0.9167, + 0.3333, + 0 + ], + 'chalkboard': [ + 1, + 0.25, + 0 + ], + 'chalkboard bold': [ + 1, + 0.25, + 0 + ], + 'chalkboard se bold': [ + 1.1667, + 0.25, + 0 + ], + 'chalkboard se light': [ + 1.1667, + 0.25, + 0 + ], + 'chalkboard se regular': [ + 1.1667, + 0.25, + 0 + ], + 'chalkduster': [ + 1, + 0.25, + 0 + ], + 'charcoal cy': [ + 1, + 0.25, + 0 + ], + 'cochin': [ + 0.9167, + 0.25, + 0 + ], + 'cochin bold': [ + 0.9167, + 0.25, + 0 + ], + 'cochin bold italic': [ + 0.9167, + 0.25, + 0 + ], + 'cochin italic': [ + 0.9167, + 0.25, + 0 + ], + 'comic sans ms': [ + 1.0833, + 0.25, + 0 + ], + 'comic sans ms bold': [ + 1.0833, + 0.25, + 0 + ], + 'copperplate': [ + 0.75, + 0.25, + 0 + ], + 'copperplate bold': [ + 0.75, + 0.25, + 0 + ], + 'copperplate light': [ + 0.75, + 0.25, + 0 + ], + 'corsiva hebrew': [ + 0.6667, + 0.3333, + 0 + ], + 'corsiva hebrew bold': [ + 0.6667, + 0.3333, + 0 + ], + 'courier': [ + 0.75, + 0.25, + 0 + ], + 'courier bold': [ + 0.75, + 0.25, + 0 + ], + 'courier bold oblique': [ + 0.75, + 0.25, + 0 + ], + 'courier oblique': [ + 0.75, + 0.25, + 0 + ], + 'courier new bold italic': [ + 0.8333, + 0.3333, + 0 + ], + 'courier new bold': [ + 0.8333, + 0.3333, + 0 + ], + 'courier new italic': [ + 0.8333, + 0.3333, + 0 + ], + 'courier new': [ + 0.8333, + 0.3333, + 0 + ], + 'biaukai': [ + 0.8333, + 0.1667, + 0 + ], + 'damascus': [ + 0.5833, + 0.4167, + 0 + ], + 'damascus bold': [ + 0.5833, + 0.4167, + 0 + ], + 'decotype naskh': [ + 1.1667, + 0.6667, + 0 + ], + 'devanagari mt': [ + 0.9167, + 0.6667, + 0 + ], + 'devanagari mt bold': [ + 0.9167, + 0.6667, + 0 + ], + 'devanagari sangam mn': [ + 0.9167, + 0.4167, + 0 + ], + 'devanagari sangam mn bold': [ + 0.9167, + 0.4167, + 0 + ], + 'didot': [ + 0.9167, + 0.3333, + 0 + ], + 'didot bold': [ + 1, + 0.3333, + 0 + ], + 'didot italic': [ + 0.9167, + 0.25, + 0 + ], + 'euphemia ucas': [ + 1.0833, + 0.25, + 0 + ], + 'euphemia ucas bold': [ + 1.0833, + 0.25, + 0 + ], + 'euphemia ucas italic': [ + 1.0833, + 0.25, + 0 + ], + 'futura condensed extrabold': [ + 1, + 0.25, + 0 + ], + 'futura condensed medium': [ + 1, + 0.25, + 0 + ], + 'futura medium': [ + 1, + 0.25, + 0 + ], + 'futura medium italic': [ + 1, + 0.25, + 0 + ], + 'gb18030 bitmap': [ + 1, + 0.6667, + 0 + ], + 'geeza pro': [ + 0.9167, + 0.3333, + 0 + ], + 'geeza pro bold': [ + 0.9167, + 0.3333, + 0 + ], + 'geneva': [ + 1, + 0.25, + 0 + ], + 'geneva cy': [ + 1, + 0.25, + 0 + ], + 'georgia': [ + 0.9167, + 0.25, + 0 + ], + 'georgia bold': [ + 0.9167, + 0.25, + 0 + ], + 'georgia bold italic': [ + 0.9167, + 0.25, + 0 + ], + 'georgia italic': [ + 0.9167, + 0.25, + 0 + ], + 'gill sans': [ + 0.9167, + 0.25, + 0 + ], + 'gill sans bold': [ + 0.9167, + 0.25, + 0 + ], + 'gill sans bold italic': [ + 0.9167, + 0.25, + 0 + ], + 'gill sans italic': [ + 0.9167, + 0.25, + 0 + ], + 'gill sans light': [ + 0.9167, + 0.25, + 0 + ], + 'gill sans light italic': [ + 0.9167, + 0.25, + 0 + ], + 'gujarati mt': [ + 0.9167, + 0.6667, + 0 + ], + 'gujarati mt bold': [ + 0.9167, + 0.6667, + 0 + ], + 'gujarati sangam mn': [ + 0.8333, + 0.4167, + 0 + ], + 'gujarati sangam mn bold': [ + 0.8333, + 0.4167, + 0 + ], + 'gurmukhi mn': [ + 0.9167, + 0.25, + 0 + ], + 'gurmukhi mn bold': [ + 0.9167, + 0.25, + 0 + ], + 'gurmukhi sangam mn': [ + 0.9167, + 0.3333, + 0 + ], + 'gurmukhi sangam mn bold': [ + 0.9167, + 0.3333, + 0 + ], + 'helvetica': [ + 0.75, + 0.25, + 0 + ], + 'helvetica bold': [ + 0.75, + 0.25, + 0 + ], + 'helvetica bold oblique': [ + 0.75, + 0.25, + 0 + ], + 'helvetica light': [ + 0.75, + 0.25, + 0 + ], + 'helvetica light oblique': [ + 0.75, + 0.25, + 0 + ], + 'helvetica oblique': [ + 0.75, + 0.25, + 0 + ], + 'helvetica neue': [ + 0.9167, + 0.25, + 0 + ], + 'helvetica neue bold': [ + 1, + 0.25, + 0 + ], + 'helvetica neue bold italic': [ + 1, + 0.25, + 0 + ], + 'helvetica neue condensed black': [ + 1, + 0.25, + 0 + ], + 'helvetica neue condensed bold': [ + 1, + 0.25, + 0 + ], + 'helvetica neue italic': [ + 0.9167, + 0.25, + 0 + ], + 'helvetica neue light': [ + 1, + 0.25, + 0 + ], + 'helvetica neue light italic': [ + 0.9167, + 0.25, + 0 + ], + 'helvetica neue medium': [ + 1, + 0.25, + 0 + ], + 'helvetica neue ultralight': [ + 0.9167, + 0.25, + 0 + ], + 'helvetica neue ultralight italic': [ + 0.9167, + 0.25, + 0 + ], + 'herculanum': [ + 0.8333, + 0.1667, + 0 + ], + 'hiragino kaku gothic pro w3': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino kaku gothic pro w6': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino kaku gothic pron w3': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino kaku gothic pron w6': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino kaku gothic std w8': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino kaku gothic stdn w8': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino maru gothic pro w4': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino maru gothic pron w4': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino mincho pro w3': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino mincho pro w6': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino mincho pron w3': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino mincho pron w6': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino sans gb w3': [ + 0.9167, + 0.0833, + 0 + ], + 'hiragino sans gb w6': [ + 0.9167, + 0.0833, + 0 + ], + 'hoefler text black': [ + 0.75, + 0.25, + 0 + ], + 'hoefler text black italic': [ + 0.75, + 0.25, + 0 + ], + 'hoefler text italic': [ + 0.75, + 0.25, + 0 + ], + 'hoefler text ornaments': [ + 0.8333, + 0.1667, + 0 + ], + 'hoefler text': [ + 0.75, + 0.25, + 0 + ], + 'impact': [ + 1, + 0.25, + 0 + ], + 'inaimathi': [ + 0.8333, + 0.4167, + 0 + ], + 'headlinea regular': [ + 0.8333, + 0.1667, + 0 + ], + 'pilgi regular': [ + 0.8333, + 0.25, + 0 + ], + 'gungseo regular': [ + 0.8333, + 0.25, + 0 + ], + 'pcmyungjo regular': [ + 0.8333, + 0.25, + 0 + ], + 'kailasa regular': [ + 1.0833, + 0.5833, + 0 + ], + 'kannada mn': [ + 0.9167, + 0.25, + 0 + ], + 'kannada mn bold': [ + 0.9167, + 0.25, + 0 + ], + 'kannada sangam mn': [ + 1, + 0.5833, + 0 + ], + 'kannada sangam mn bold': [ + 1, + 0.5833, + 0 + ], + 'kefa bold': [ + 0.9167, + 0.25, + 0 + ], + 'kefa regular': [ + 0.9167, + 0.25, + 0 + ], + 'khmer mn': [ + 1, + 0.6667, + 0 + ], + 'khmer mn bold': [ + 1, + 0.6667, + 0 + ], + 'khmer sangam mn': [ + 1.0833, + 0.6667, + 0 + ], + 'kokonor regular': [ + 1.0833, + 0.5833, + 0 + ], + 'krungthep': [ + 1, + 0.25, + 0 + ], + 'kufistandardgk': [ + 0.9167, + 0.5, + 0 + ], + 'lao mn': [ + 0.9167, + 0.4167, + 0 + ], + 'lao mn bold': [ + 0.9167, + 0.4167, + 0 + ], + 'lao sangam mn': [ + 1, + 0.3333, + 0 + ], + 'apple ligothic medium': [ + 0.8333, + 0.1667, + 0 + ], + 'lihei pro': [ + 0.8333, + 0.1667, + 0 + ], + 'lisong pro': [ + 0.8333, + 0.1667, + 0 + ], + 'lucida grande': [ + 1, + 0.25, + 0 + ], + 'lucida grande bold': [ + 1, + 0.25, + 0 + ], + 'malayalam mn': [ + 1, + 0.4167, + 0 + ], + 'malayalam mn bold': [ + 1, + 0.4167, + 0 + ], + 'malayalam sangam mn': [ + 0.8333, + 0.4167, + 0 + ], + 'malayalam sangam mn bold': [ + 0.8333, + 0.4167, + 0 + ], + 'marion bold': [ + 0.6667, + 0.3333, + 0 + ], + 'marion italic': [ + 0.6667, + 0.3333, + 0 + ], + 'marion regular': [ + 0.6667, + 0.3333, + 0 + ], + 'marker felt thin': [ + 0.8333, + 0.25, + 0 + ], + 'marker felt wide': [ + 0.9167, + 0.25, + 0 + ], + 'menlo bold': [ + 0.9167, + 0.25, + 0 + ], + 'menlo bold italic': [ + 0.9167, + 0.25, + 0 + ], + 'menlo italic': [ + 0.9167, + 0.25, + 0 + ], + 'menlo regular': [ + 0.9167, + 0.25, + 0 + ], + 'microsoft sans serif': [ + 0.9167, + 0.25, + 0 + ], + 'monaco': [ + 1, + 0.25, + 0 + ], + 'gurmukhi mt': [ + 0.8333, + 0.4167, + 0 + ], + 'mshtakan': [ + 0.9167, + 0.25, + 0 + ], + 'mshtakan bold': [ + 0.9167, + 0.25, + 0 + ], + 'mshtakan boldoblique': [ + 0.9167, + 0.25, + 0 + ], + 'mshtakan oblique': [ + 0.9167, + 0.25, + 0 + ], + 'myanmar mn': [ + 1, + 0.4167, + 0 + ], + 'myanmar mn bold': [ + 1, + 0.4167, + 0 + ], + 'myanmar sangam mn': [ + 0.9167, + 0.4167, + 0 + ], + 'nadeem': [ + 0.9167, + 0.4167, + 0 + ], + 'nanum brush script': [ + 0.9167, + 0.25, + 0 + ], + 'nanumgothic': [ + 0.9167, + 0.25, + 0 + ], + 'nanumgothic bold': [ + 0.9167, + 0.25, + 0 + ], + 'nanumgothic extrabold': [ + 0.9167, + 0.25, + 0 + ], + 'nanummyeongjo': [ + 0.9167, + 0.25, + 0 + ], + 'nanummyeongjo bold': [ + 0.9167, + 0.25, + 0 + ], + 'nanummyeongjo extrabold': [ + 0.9167, + 0.25, + 0 + ], + 'nanum pen script': [ + 0.9167, + 0.25, + 0 + ], + 'optima bold': [ + 0.9167, + 0.25, + 0 + ], + 'optima bold italic': [ + 0.9167, + 0.25, + 0 + ], + 'optima extrablack': [ + 1, + 0.25, + 0 + ], + 'optima italic': [ + 0.9167, + 0.25, + 0 + ], + 'optima regular': [ + 0.9167, + 0.25, + 0 + ], + 'oriya mn': [ + 0.9167, + 0.25, + 0 + ], + 'oriya mn bold': [ + 0.9167, + 0.25, + 0 + ], + 'oriya sangam mn': [ + 0.8333, + 0.4167, + 0 + ], + 'oriya sangam mn bold': [ + 0.8333, + 0.4167, + 0 + ], + 'osaka': [ + 1, + 0.25, + 0 + ], + 'osaka-mono': [ + 0.8333, + 0.1667, + 0 + ], + 'palatino bold': [ + 0.8333, + 0.25, + 0 + ], + 'palatino bold italic': [ + 0.8333, + 0.25, + 0 + ], + 'palatino italic': [ + 0.8333, + 0.25, + 0 + ], + 'palatino': [ + 0.8333, + 0.25, + 0 + ], + 'papyrus': [ + 0.9167, + 0.5833, + 0 + ], + 'papyrus condensed': [ + 0.9167, + 0.5833, + 0 + ], + 'plantagenet cherokee': [ + 0.6667, + 0.25, + 0 + ], + 'raanana': [ + 0.75, + 0.25, + 0 + ], + 'raanana bold': [ + 0.75, + 0.25, + 0 + ], + 'hei regular': [ + 0.8333, + 0.1667, + 0 + ], + 'kai regular': [ + 0.8333, + 0.1667, + 0 + ], + 'stfangsong': [ + 0.8333, + 0.1667, + 0 + ], + 'stheiti': [ + 0.8333, + 0.1667, + 0 + ], + 'heiti sc light': [ + 0.8333, + 0.1667, + 0 + ], + 'heiti sc medium': [ + 0.8333, + 0.1667, + 0 + ], + 'heiti tc light': [ + 0.8333, + 0.1667, + 0 + ], + 'heiti tc medium': [ + 0.8333, + 0.1667, + 0 + ], + 'stkaiti': [ + 0.8333, + 0.1667, + 0 + ], + 'kaiti sc black': [ + 1.0833, + 0.3333, + 0 + ], + 'kaiti sc bold': [ + 1.0833, + 0.3333, + 0 + ], + 'kaiti sc regular': [ + 1.0833, + 0.3333, + 0 + ], + 'stsong': [ + 0.8333, + 0.1667, + 0 + ], + 'songti sc black': [ + 1.0833, + 0.3333, + 0 + ], + 'songti sc bold': [ + 1.0833, + 0.3333, + 0 + ], + 'songti sc light': [ + 1.0833, + 0.3333, + 0 + ], + 'songti sc regular': [ + 1.0833, + 0.3333, + 0 + ], + 'stxihei': [ + 0.8333, + 0.1667, + 0 + ], + 'sathu': [ + 0.9167, + 0.3333, + 0 + ], + 'silom': [ + 1, + 0.3333, + 0 + ], + 'sinhala mn': [ + 0.9167, + 0.25, + 0 + ], + 'sinhala mn bold': [ + 0.9167, + 0.25, + 0 + ], + 'sinhala sangam mn': [ + 1.1667, + 0.3333, + 0 + ], + 'sinhala sangam mn bold': [ + 1.1667, + 0.3333, + 0 + ], + 'skia regular': [ + 0.75, + 0.25, + 0 + ], + 'symbol': [ + 0.6667, + 0.3333, + 0 + ], + 'tahoma negreta': [ + 1, + 0.1667, + 0 + ], + 'tamil mn': [ + 0.9167, + 0.25, + 0 + ], + 'tamil mn bold': [ + 0.9167, + 0.25, + 0 + ], + 'tamil sangam mn': [ + 0.75, + 0.25, + 0 + ], + 'tamil sangam mn bold': [ + 0.75, + 0.25, + 0 + ], + 'telugu mn': [ + 0.9167, + 0.25, + 0 + ], + 'telugu mn bold': [ + 0.9167, + 0.25, + 0 + ], + 'telugu sangam mn': [ + 1, + 0.5833, + 0 + ], + 'telugu sangam mn bold': [ + 1, + 0.5833, + 0 + ], + 'thonburi': [ + 1.0833, + 0.25, + 0 + ], + 'thonburi bold': [ + 1.0833, + 0.25, + 0 + ], + 'times bold': [ + 0.75, + 0.25, + 0 + ], + 'times bold italic': [ + 0.75, + 0.25, + 0 + ], + 'times italic': [ + 0.75, + 0.25, + 0 + ], + 'times roman': [ + 0.75, + 0.25, + 0 + ], + 'times new roman bold italic': [ + 0.9167, + 0.25, + 0 + ], + 'times new roman bold': [ + 0.9167, + 0.25, + 0 + ], + 'times new roman italic': [ + 0.9167, + 0.25, + 0 + ], + 'times new roman': [ + 0.9167, + 0.25, + 0 + ], + 'trebuchet ms bold italic': [ + 0.9167, + 0.25, + 0 + ], + 'trebuchet ms': [ + 0.9167, + 0.25, + 0 + ], + 'trebuchet ms bold': [ + 0.9167, + 0.25, + 0 + ], + 'trebuchet ms italic': [ + 0.9167, + 0.25, + 0 + ], + 'verdana': [ + 1, + 0.25, + 0 + ], + 'verdana bold': [ + 1, + 0.25, + 0 + ], + 'verdana bold italic': [ + 1, + 0.25, + 0 + ], + 'verdana italic': [ + 1, + 0.25, + 0 + ], + 'webdings': [ + 0.8333, + 0.1667, + 0 + ], + 'wingdings 2': [ + 0.8333, + 0.25, + 0 + ], + 'wingdings 3': [ + 0.9167, + 0.25, + 0 + ], + 'yuppy sc regular': [ + 1.0833, + 0.3333, + 0 + ], + 'yuppy tc regular': [ + 1.0833, + 0.3333, + 0 + ], + 'zapf dingbats': [ + 0.8333, + 0.1667, + 0 + ], + 'zapfino': [ + 1.9167, + 1.5, + 0 + ] + }; + var DEVICE_FONT_METRICS_LINUX = { + 'kacstfarsi': [ + 1.0831, + 0.5215, + 0 + ], + 'meera': [ + 0.682, + 0.4413, + 0 + ], + 'freemono': [ + 0.8023, + 0.2006, + 0 + ], + 'undotum': [ + 1.0029, + 0.2808, + 0 + ], + 'loma': [ + 1.1634, + 0.4814, + 0 + ], + 'century schoolbook l': [ + 1.0029, + 0.3209, + 0 + ], + 'kacsttitlel': [ + 1.0831, + 0.5215, + 0 + ], + 'undinaru': [ + 1.0029, + 0.2407, + 0 + ], + 'ungungseo': [ + 1.0029, + 0.2808, + 0 + ], + 'garuda': [ + 1.3238, + 0.6017, + 0 + ], + 'rekha': [ + 1.1232, + 0.2808, + 0 + ], + 'purisa': [ + 1.1232, + 0.5215, + 0 + ], + 'dejavu sans mono': [ + 0.9628, + 0.2407, + 0 + ], + 'vemana2000': [ + 0.8825, + 0.8424, + 0 + ], + 'kacstoffice': [ + 1.0831, + 0.5215, + 0 + ], + 'umpush': [ + 1.2837, + 0.682, + 0 + ], + 'opensymbol': [ + 0.8023, + 0.2006, + 0 + ], + 'sawasdee': [ + 1.1232, + 0.4413, + 0 + ], + 'urw palladio l': [ + 1.0029, + 0.3209, + 0 + ], + 'freeserif': [ + 0.9227, + 0.3209, + 0 + ], + 'kacstdigital': [ + 1.0831, + 0.5215, + 0 + ], + 'ubuntu condensed': [ + 0.9628, + 0.2006, + 0 + ], + 'unpilgi': [ + 1.0029, + 0.4413, + 0 + ], + 'mry_kacstqurn': [ + 1.4442, + 0.7221, + 0 + ], + 'urw gothic l': [ + 1.0029, + 0.2407, + 0 + ], + 'dingbats': [ + 0.8424, + 0.1605, + 0 + ], + 'urw chancery l': [ + 1.0029, + 0.3209, + 0 + ], + 'phetsarath ot': [ + 1.0831, + 0.5215, + 0 + ], + 'tlwg typist': [ + 0.8825, + 0.4012, + 0 + ], + 'kacstletter': [ + 1.0831, + 0.5215, + 0 + ], + 'utkal': [ + 1.2035, + 0.6418, + 0 + ], + 'dejavu sans light': [ + 0.9628, + 0.2407, + 0 + ], + 'norasi': [ + 1.2436, + 0.5215, + 0 + ], + 'dejavu serif condensed': [ + 0.9628, + 0.2407, + 0 + ], + 'kacstone': [ + 1.2436, + 0.6418, + 0 + ], + 'liberation sans narrow': [ + 0.9628, + 0.2407, + 0 + ], + 'symbol': [ + 1.043, + 0.3209, + 0 + ], + 'nanummyeongjo': [ + 0.9227, + 0.2407, + 0 + ], + 'untitled1': [ + 0.682, + 0.5616, + 0 + ], + 'lohit gujarati': [ + 0.9628, + 0.4012, + 0 + ], + 'liberation mono': [ + 0.8424, + 0.3209, + 0 + ], + 'kacstart': [ + 1.0831, + 0.5215, + 0 + ], + 'mallige': [ + 1.0029, + 0.682, + 0 + ], + 'bitstream charter': [ + 1.0029, + 0.2407, + 0 + ], + 'nanumgothic': [ + 0.9227, + 0.2407, + 0 + ], + 'liberation serif': [ + 0.9227, + 0.2407, + 0 + ], + 'dejavu sans condensed': [ + 0.9628, + 0.2407, + 0 + ], + 'ubuntu': [ + 0.9628, + 0.2006, + 0 + ], + 'courier 10 pitch': [ + 0.8825, + 0.3209, + 0 + ], + 'nimbus sans l': [ + 0.9628, + 0.3209, + 0 + ], + 'takaopgothic': [ + 0.8825, + 0.2006, + 0 + ], + 'wenquanyi micro hei mono': [ + 0.9628, + 0.2407, + 0 + ], + 'dejavu sans': [ + 0.9628, + 0.2407, + 0 + ], + 'kedage': [ + 1.0029, + 0.682, + 0 + ], + 'kinnari': [ + 1.3238, + 0.5215, + 0 + ], + 'tlwgmono': [ + 0.8825, + 0.4012, + 0 + ], + 'standard symbols l': [ + 1.043, + 0.3209, + 0 + ], + 'lohit punjabi': [ + 1.2035, + 0.682, + 0 + ], + 'nimbus mono l': [ + 0.8424, + 0.2808, + 0 + ], + 'rachana': [ + 0.682, + 0.5616, + 0 + ], + 'waree': [ + 1.2436, + 0.4413, + 0 + ], + 'kacstposter': [ + 1.0831, + 0.5215, + 0 + ], + 'khmer os': [ + 1.2837, + 0.7622, + 0 + ], + 'freesans': [ + 1.0029, + 0.3209, + 0 + ], + 'gargi': [ + 0.9628, + 0.2808, + 0 + ], + 'nimbus roman no9 l': [ + 0.9628, + 0.3209, + 0 + ], + 'dejavu serif': [ + 0.9628, + 0.2407, + 0 + ], + 'wenquanyi micro hei': [ + 0.9628, + 0.2407, + 0 + ], + 'ubuntu light': [ + 0.9628, + 0.2006, + 0 + ], + 'tlwgtypewriter': [ + 0.9227, + 0.4012, + 0 + ], + 'kacstpen': [ + 1.0831, + 0.5215, + 0 + ], + 'tlwg typo': [ + 0.8825, + 0.4012, + 0 + ], + 'mukti narrow': [ + 1.2837, + 0.4413, + 0 + ], + 'ubuntu mono': [ + 0.8424, + 0.2006, + 0 + ], + 'lohit bengali': [ + 1.0029, + 0.4413, + 0 + ], + 'liberation sans': [ + 0.9227, + 0.2407, + 0 + ], + 'unbatang': [ + 1.0029, + 0.2808, + 0 + ], + 'kacstdecorative': [ + 1.1232, + 0.5215, + 0 + ], + 'khmer os system': [ + 1.2436, + 0.6017, + 0 + ], + 'saab': [ + 1.0029, + 0.682, + 0 + ], + 'kacsttitle': [ + 1.0831, + 0.5215, + 0 + ], + 'mukti narrow bold': [ + 1.2837, + 0.4413, + 0 + ], + 'lohit hindi': [ + 1.0029, + 0.5215, + 0 + ], + 'kacstqurn': [ + 1.0831, + 0.5215, + 0 + ], + 'urw bookman l': [ + 0.9628, + 0.2808, + 0 + ], + 'kacstnaskh': [ + 1.0831, + 0.5215, + 0 + ], + 'kacstscreen': [ + 1.0831, + 0.5215, + 0 + ], + 'pothana2000': [ + 0.8825, + 0.8424, + 0 + ], + 'ungraphic': [ + 1.0029, + 0.2808, + 0 + ], + 'lohit tamil': [ + 0.8825, + 0.361, + 0 + ], + 'kacstbook': [ + 1.0831, + 0.5215, + 0 + ] + }; + DEVICE_FONT_METRICS_MAC.__proto__ = DEVICE_FONT_METRICS_WIN; + DEVICE_FONT_METRICS_LINUX.__proto__ = DEVICE_FONT_METRICS_MAC; +} +var StaticTextDefinition = function () { + var def = { + __class__: 'flash.text.StaticText', + initialize: function () { + var s = this.symbol; + if (s) { + this.draw = s.draw; + } + }, + get text() { + return this._text; + }, + set text(val) { + this._text = val; + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + text: desc(def, 'text') + } + } + }; + return def; + }.call(this); +var StyleSheetDefinition = function () { + return { + __class__: 'flash.text.StyleSheet', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + _update: function _update() { + somewhatImplemented('StyleSheet._update'); + }, + _parseCSSInternal: function _parseCSSInternal(cssText) { + somewhatImplemented('StyleSheet._parseCSSInternal'); + return null; + }, + _parseCSSFontFamily: function _parseCSSFontFamily(fontFamily) { + notImplemented('StyleSheet._parseCSSFontFamily'); + }, + _parseColor: function _parseColor(color) { + notImplemented('StyleSheet._parseColor'); + }, + _styles: { + get: function _styles() { + return this.__styles; + }, + set: function _styles(styles) { + somewhatImplemented('StyleSheet._styles'); + this.__styles = styles; + } + } + } + } + } + }; + }.call(this); +var TextFieldDefinition = function () { + var def = { + __class__: 'flash.text.TextField', + initialize: function () { + this._bbox = { + xMin: 0, + yMin: 0, + xMax: 2000, + yMax: 2000 + }; + var initialFormat = { + align: 'LEFT', + face: 'serif', + size: 12, + letterspacing: 0, + kerning: 0, + color: 0, + leading: 0 + }; + this._content = new TextFieldContent(initialFormat); + this._type = 'dynamic'; + this._embedFonts = false; + this._selectable = true; + this._autoSize = 'none'; + this._scrollV = 1; + this._maxScrollV = 1; + this._bottomScrollV = 1; + this._drawingOffsetH = 0; + this._background = false; + this._border = false; + this._backgroundColor = 16777215; + this._backgroundColorStr = '#ffffff'; + this._borderColor = 0; + this._borderColorStr = '#000000'; + var s = this.symbol; + if (!s) { + this._currentTransform.tx -= 40; + this._currentTransform.ty -= 40; + this._content.resolveFont(initialFormat, false); + this.text = ''; + return; + } + var tag = s.tag; + var bbox = tag.bbox; + this._currentTransform.tx += bbox.xMin; + this._currentTransform.ty += bbox.yMin; + this._bbox.xMax = bbox.xMax - bbox.xMin; + this._bbox.yMax = bbox.yMax - bbox.yMin; + if (tag.hasLayout) { + initialFormat.size = tag.fontHeight / 20; + initialFormat.leading = (tag.leading | 0) / 20; + } + if (tag.hasColor) { + initialFormat.color = rgbaObjToStr(tag.color); + } + if (tag.hasFont) { + var font = FontDefinition.getFontByUniqueName(tag.font); + initialFormat.font = font; + initialFormat.face = font._fontName; + initialFormat.bold = font.symbol.bold; + initialFormat.italic = font.symbol.italic; + initialFormat.str = this._content.makeFormatString(initialFormat); + } + this._content.multiline = !(!tag.multiline); + this._content.wordWrap = !(!tag.wordWrap); + this._embedFonts = !(!tag.useOutlines); + this._selectable = !tag.noSelect; + this._border = !(!tag.border); + switch (tag.align) { + case 1: + initialFormat.align = 'right'; + break; + case 2: + initialFormat.align = 'center'; + break; + case 3: + initialFormat.align = 'justified'; + break; + default: + } + if (tag.initialText) { + if (tag.html) { + this.htmlText = tag.initialText; + } else { + this.text = tag.initialText; + } + } else { + this.text = ''; + } + }, + _getAS2Object: function () { + if (!this.$as2Object) { + new avm1lib.AS2TextField(this); + } + return this.$as2Object; + }, + replaceText: function (begin, end, str) { + var text = this._content.text; + this.text = text.substring(0, begin) + str + text.substring(end); + }, + draw: function (ctx, ratio, colorTransform) { + this.ensureDimensions(); + var bounds = this._bbox; + var width = bounds.xMax / 20; + var height = bounds.yMax / 20; + if (width <= 0 || height <= 0) { + return; + } + ctx.save(); + ctx.beginPath(); + ctx.rect(0, 0, width + 1, height + 1); + ctx.clip(); + if (this._background) { + colorTransform.setFillStyle(ctx, this._backgroundColorStr); + ctx.fill(); + } + if (this._border) { + colorTransform.setStrokeStyle(ctx, this._borderColorStr); + ctx.lineCap = 'square'; + ctx.lineWidth = 1; + ctx.strokeRect(0.5, 0.5, width | 0, height | 0); + } + ctx.closePath(); + if (this._content.lines.length === 0) { + ctx.restore(); + return; + } + ctx.translate(2, 2); + ctx.save(); + colorTransform.setAlpha(ctx); + var runs = this._content._textRuns; + var offsetY = this._content.lines[this._scrollV - 1].y; + for (var i = 0; i < runs.length; i++) { + var run = runs[i]; + if (run.type === 'f') { + ctx.restore(); + ctx.font = run.format.str; + colorTransform.setFillStyle(ctx, run.format.color); + ctx.save(); + colorTransform.setAlpha(ctx); + } else { + if (run.y < offsetY) { + continue; + } + ctx.fillText(run.text, run.x - this._drawingOffsetH, run.y - offsetY); + } + } + ctx.restore(); + ctx.restore(); + }, + invalidateDimensions: function () { + this._invalidate(); + this._invalidateBounds(); + this._dimensionsValid = false; + }, + ensureDimensions: function () { + if (this._dimensionsValid) { + return; + } + var bounds = this._bbox; + var combinedAlign = this._content.calculateMetrics(bounds, this._embedFonts); + this._scrollV = 1; + this._maxScrollV = 1; + this._bottomScrollV = 1; + var autoSize = this._autoSize; + if (autoSize === 'none') { + var maxVisibleY = (bounds.yMax - 80) / 20; + if (this._content.textHeight > maxVisibleY) { + var lines = this._content.lines; + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + if (line.y + line.height > maxVisibleY) { + this._maxScrollV = i + 1; + this._bottomScrollV = i === 0 ? 1 : i; + break; + } + } + } + } else { + var width = Math.max(bounds.xMax / 20 - 4, 1); + var targetWidth = this._content.textWidth; + var align = combinedAlign; + var diffX = 0; + if (align !== 'mixed') { + switch (autoSize) { + case 'left': + break; + case 'center': + diffX = width - targetWidth >> 1; + break; + case 'right': + diffX = width - targetWidth; + } + if (align === 'left') { + this._drawingOffsetH = 0; + } else { + var offset; + switch (autoSize) { + case 'left': + offset = width - targetWidth; + break; + case 'center': + offset = diffX << 1; + break; + case 'right': + offset = diffX; + break; + } + if (align === 'center') { + offset >>= 1; + } + this._drawingOffsetH = offset; + } + this._invalidateTransform(); + this._currentTransform.tx += diffX * 20 | 0; + bounds.xMax = (targetWidth * 20 | 0) + 80; + } + bounds.yMax = (this._content.textHeight * 20 | 0) + 80; + console.log(bounds.yMax); + this._invalidateBounds(); + } + this._dimensionsValid = true; + }, + get text() { + return this._content.text; + }, + set text(val) { + this._content.text = val; + this.invalidateDimensions(); + }, + get htmlText() { + return this._content.htmlText; + }, + set htmlText(val) { + this._content.htmlText = val; + this.invalidateDimensions(); + }, + get defaultTextFormat() { + var format = this._content.defaultTextFormat; + return new flash.text.TextFormat().fromObject(format); + }, + set defaultTextFormat(val) { + this._content.defaultTextFormat = val.toObject(); + this.invalidateDimensions(); + }, + getTextFormat: function (beginIndex, endIndex) { + return this.defaultTextFormat; + }, + setTextFormat: function (format, beginIndex, endIndex) { + this.defaultTextFormat = format; + if (this.text === this.htmlText) { + this.text = this.text; + } + this.invalidateDimensions(); + }, + get x() { + this.ensureDimensions(); + return this._currentTransform.tx; + }, + set x(val) { + if (val === this._currentTransform.tx) { + return; + } + this._invalidate(); + this._invalidateBounds(); + this._invalidateTransform(); + this._currentTransform.tx = val; + }, + get width() { + this.ensureDimensions(); + return this._bbox.xMax; + }, + set width(value) { + if (value < 0) { + return; + } + this._bbox.xMax = value; + this.invalidateDimensions(); + }, + get height() { + this.ensureDimensions(); + return this._bbox.yMax; + }, + set height(value) { + if (value < 0) { + return; + } + this._bbox.yMax = value; + this._invalidate(); + }, + _getContentBounds: function () { + this.ensureDimensions(); + return this._bbox; + }, + _getRegion: function getRegion(targetCoordSpace) { + return this._getTransformedRect(this._getContentBounds(), targetCoordSpace); + }, + getLineMetrics: function (lineIndex) { + this.ensureDimensions(); + if (lineIndex < 0 || lineIndex >= this._content.lines.length) { + throwError('RangeError', Errors.ParamRangeError); + } + var line = this._content.lines[lineIndex]; + var format = line.largestFormat; + var metrics = format.font._metrics; + var size = format.size; + var ascent = metrics.ascent * size + 0.49999 | 0; + var descent = metrics.descent * size + 0.49999 | 0; + var leading = metrics.leading * size + 0.49999 + line.leading | 0; + return new flash.text.TextLineMetrics(line.x + 2, line.width, line.height, ascent, descent, leading); + }, + getCharBoundaries: function getCharBoundaries(index) { + somewhatImplemented('TextField.getCharBoundaries'); + return new flash.geom.Rectangle(0, 0, 0, 0); + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + text: desc(def, 'text'), + defaultTextFormat: desc(def, 'defaultTextFormat'), + draw: def.draw, + htmlText: desc(def, 'htmlText'), + replaceText: def.replaceText, + getTextFormat: def.getTextFormat, + setTextFormat: def.setTextFormat, + getCharBoundaries: def.getCharBoundaries, + autoSize: { + get: function autoSize() { + return this._autoSize; + }, + set: function autoSize(value) { + if (this._autoSize === value) { + return; + } + this._autoSize = value; + this.invalidateDimensions(); + } + }, + multiline: { + get: function multiline() { + return this._content.multiline; + }, + set: function multiline(value) { + if (this._content.multiline === value) { + return; + } + this._content.multiline = value; + this.invalidateDimensions(); + } + }, + textColor: { + get: function textColor() { + return this._content.textColor; + }, + set: function textColor(value) { + if (this._content.textColor === value) { + return; + } + this._content.textColor = value; + this._invalidate(); + } + }, + selectable: { + get: function selectable() { + return this._selectable; + }, + set: function selectable(value) { + somewhatImplemented('TextField.selectable'); + this._selectable = value; + } + }, + wordWrap: { + get: function wordWrap() { + return this._content.wordWrap; + }, + set: function wordWrap(value) { + if (this._content.wordWrap === value) { + return; + } + this._content.wordWrap = value; + this.invalidateDimensions(); + } + }, + textHeight: { + get: function textHeight() { + this.ensureDimensions(); + return this._content.textHeight; + } + }, + textWidth: { + get: function textWidth() { + this.ensureDimensions(); + return this._content.textWidth; + } + }, + length: { + get: function length() { + return this.text.length; + } + }, + numLines: { + get: function numLines() { + this.ensureDimensions(); + return this._content.lines.length; + } + }, + getLineMetrics: function (lineIndex) { + return this.getLineMetrics(lineIndex); + }, + setSelection: function (beginIndex, endIndex) { + somewhatImplemented('TextField.setSelection'); + }, + scrollV: { + get: function scrollV() { + return this._scrollV; + }, + set: function scrollV(value) { + this.ensureDimensions(); + value = Math.max(1, Math.min(this._maxScrollV, value)); + this._scrollV = value; + } + }, + bottomScrollV: { + get: function bottomScrollV() { + this.ensureDimensions(); + if (this._scrollV === 1) { + return this._bottomScrollV; + } + var maxVisibleY = (this._bbox.yMax - 80) / 20; + var lines = this._content.lines; + var offsetY = lines[this._scrollV - 1].y; + for (var i = this._bottomScrollV; i < lines.length; i++) { + var line = lines[i]; + if (line.y + line.height + offsetY > maxVisibleY) { + return i + 1; + } + } + } + }, + maxScrollV: { + get: function maxScrollV() { + this.ensureDimensions(); + return this._maxScrollV; + } + }, + maxScrollH: { + get: function maxScrollH() { + this.ensureDimensions(); + return Math.max(this._content.textWidth - this._bbox.xMax / 20 + 4, 0); + } + }, + background: { + get: function background() { + return this._background; + }, + set: function background(value) { + if (this._background === value) { + return; + } + this._background = value; + this._invalidate(); + } + }, + backgroundColor: { + get: function backgroundColor() { + return this._backgroundColor; + }, + set: function backgroundColor(value) { + if (this._backgroundColor === value) { + return; + } + this._backgroundColor = value; + this._backgroundColorStr = rgbIntAlphaToStr(value, 1); + if (this._background) { + this._invalidate(); + } + } + }, + border: { + get: function border() { + return this._border; + }, + set: function border(value) { + if (this._border === value) { + return; + } + this._border = value; + this._invalidate(); + } + }, + borderColor: { + get: function borderColor() { + return this._borderColor; + }, + set: function borderColor(value) { + if (this._borderColor === value) { + return; + } + this._borderColor = value; + this._borderColorStr = rgbIntAlphaToStr(value, 1); + if (this._border) { + this._invalidate(); + } + } + }, + type: { + get: function borderColor() { + return this._type; + }, + set: function borderColor(value) { + somewhatImplemented('TextField.type'); + this._type = value; + } + }, + embedFonts: { + get: function embedFonts() { + return this._embedFonts; + }, + set: function embedFonts(value) { + this.invalidateDimensions(); + this._embedFonts = value; + } + }, + condenseWhite: { + get: function condenseWhite() { + return this._content.condenseWhite; + }, + set: function condenseWhite(value) { + somewhatImplemented('TextField.condenseWhite'); + this._content.condenseWhite = value; + } + }, + sharpness: { + get: function sharpness() { + return this._sharpness; + }, + set: function sharpness(value) { + somewhatImplemented('TextField.sharpness'); + this._sharpness = value; + } + } + } + } + }; + return def; + }.call(this); +function TextFieldContent(initialFormat) { + this.defaultTextFormat = initialFormat; + this.textWidth = 0; + this.textHeight = 0; + this.condenseWhite = false; + this.wordWrap = false; + this.multiline = false; + this.textColor = null; + this._text = ''; + this._htmlText = ''; + this._createTrunk(); + this._textRuns = null; + this._htmlParser = document.createElement('p'); + this._measureCtx = document.createElement('canvas').getContext('2d'); +} +TextFieldContent.knownNodeTypes = { + 'BR': true, + 'LI': true, + 'P': true, + 'B': true, + 'I': true, + 'FONT': true, + 'TEXTFORMAT': true, + 'U': true, + 'A': true, + 'IMG': true, + 'SPAN': true +}; +TextFieldContent.WRAP_OPPORTUNITIES = { + ' ': true, + '.': true, + '-': true, + '\t': true +}; +TextFieldContent.TextLine = function (y) { + this.x = 0; + this.width = 0; + this.y = y; + this.height = 0; + this.leading = 0; + this.runs = []; + this.largestFormat = null; +}; +TextFieldContent.prototype = { + get text() { + return this._text; + }, + set text(val) { + val = val + ''; + if (this._text === val) { + return; + } + var lines = []; + var lineOffset = 0; + for (var index = 0; index < val.length;) { + var char = val[index]; + if (char === '\r' || char === '\n') { + lines.push(val.substring(lineOffset, index)); + lineOffset = index; + if (char === '\r' && val[index + 1] === '\n') { + index++; + } + } + index++; + } + lines.push(val.substring(lineOffset, index)); + this._createTrunk(); + this._text = val; + this._htmlText = val; + this._tree.children[0].children[0] = { + type: 'plain-text', + lines: lines + }; + }, + get htmlText() { + return this._htmlText; + }, + set htmlText(val) { + if (this._htmlText === val) { + return; + } + this.defaultTextFormat.bold = false; + this.defaultTextFormat.italic = false; + this._parseHtml(val); + }, + calculateMetrics: function (bounds, embedFonts) { + var initialFormat = this.defaultTextFormat; + this.resolveFont(initialFormat, embedFonts); + this.lines = []; + this._textRuns = [ + { + type: 'f', + format: initialFormat + } + ]; + var width = Math.max(bounds.xMax / 20 - 4, 1); + var height = Math.max(bounds.yMax / 20 - 4, 1); + var state = { + ctx: this._measureCtx, + w: width, + h: height, + maxLineWidth: 0, + formats: [ + initialFormat + ], + currentFormat: initialFormat, + line: new TextFieldContent.TextLine(0), + wordWrap: this.wordWrap, + combinedAlign: null, + textColor: this.textColor, + embedFonts: embedFonts + }; + this._collectRuns(state, this._tree); + this._finishLine(state, false); + this.textWidth = state.maxLineWidth | 0; + this.textHeight = state.line.y | 0; + return state.combinedAlign; + }, + makeFormatString: function (format) { + var boldItalic = ''; + if (format.italic) { + boldItalic += 'italic'; + } + if (format.bold) { + boldItalic += ' bold'; + } + return boldItalic + ' ' + format.size + 'px ' + (format.font._uniqueName || format.font._fontName); + }, + resolveFont: function (format, embedded) { + var face = format.face.toLowerCase(); + if (face === '_sans') { + face = 'sans-serif'; + } else if (face === '_serif') { + face = 'serif'; + } else if (face === '_typewriter') { + face = 'monospace'; + } + var style; + if (format.bold) { + if (format.italic) { + style = 'boldItalic'; + } else { + style = 'bold'; + } + } else if (format.italic) { + style = 'italic'; + } else { + style = 'regular'; + } + var font = FontDefinition.getFont(face, style, embedded); + format.font = font; + }, + _parseHtml: function (val) { + this._htmlParser.innerHTML = val; + var rootElement = this._htmlParser.childNodes.length !== 1 ? this._htmlParser : this._htmlParser.childNodes[0]; + this._text = ''; + this._htmlText = val; + this._createTrunk(); + if (rootElement.nodeType === 3) { + this._convertNode(rootElement, this._tree.children[0].children); + } + var initialNodeList = [ + rootElement + ]; + var attributes; + var format; + var key; + if (initialNodeList.length == 1 && rootElement.localName.toUpperCase() == 'P') { + attributes = this._extractAttributes(rootElement); + format = this._tree.format; + for (key in attributes) { + format[key] = attributes[key]; + } + initialNodeList = rootElement.childNodes; + rootElement = rootElement.childNodes[0]; + } + if (initialNodeList.length == 1 && rootElement.localName.toUpperCase() == 'FONT') { + attributes = this._extractAttributes(rootElement); + format = this._tree.children[0].format; + for (key in attributes) { + format[key] = attributes[key]; + } + initialNodeList = rootElement.childNodes; + } + this._convertNodeList(initialNodeList, this._tree.children[0].children); + }, + _createTrunk: function () { + var initialFormat = this.defaultTextFormat; + this._tree = { + type: 'SPAN', + format: { + ALIGN: initialFormat.align + }, + children: [] + }; + var fontAttributes = { + FACE: initialFormat.face, + LETTERSPACING: initialFormat.letterSpacing, + KERNING: initialFormat.kerning, + LEADING: initialFormat.leading, + COLOR: initialFormat.color + }; + this._tree.children[0] = { + type: 'FONT', + format: fontAttributes, + children: [] + }; + }, + _convertNode: function (input, destinationList) { + if (!(input.nodeType === 1 || input.nodeType === 3) || input.prefix) { + return; + } + var node; + if (input.nodeType === 3) { + var text = input.textContent; + node = { + type: 'text', + text: text, + format: null, + children: null + }; + this._text += text; + destinationList.push(node); + return; + } + var nodeType = input.localName.toUpperCase(); + if (!TextFieldContent.knownNodeTypes[nodeType] || this.multiline === false && (nodeType === 'P' || nodeType === 'BR')) { + if (nodeType === 'SBR') { + destinationList.push({ + type: 'BR', + text: null, + format: null, + children: null + }); + } + this._convertNodeList(input.childNodes, destinationList); + return; + } + node = { + type: nodeType, + text: null, + format: this._extractAttributes(input), + children: [] + }; + this._convertNodeList(input.childNodes, node.children); + destinationList.push(node); + }, + _convertNodeList: function (from, to) { + var childCount = from.length; + for (var i = 0; i < childCount; i++) { + this._convertNode(from[i], to); + } + }, + _extractAttributes: function (node) { + var attributesList = node.attributes; + var attributesMap = {}; + for (var i = 0; i < attributesList.length; i++) { + var attr = attributesList[i]; + if (attr.prefix) { + continue; + } + attributesMap[attr.localName.toUpperCase()] = attr.value; + } + return attributesMap; + }, + _collectRuns: function (state, node) { + var formatNode = false; + var blockNode = false; + switch (node.type) { + case 'plain-text': + var lines = node.lines; + for (var i = 0; i < lines.length; i++) { + this._addRunsForText(state, lines[i]); + if (i < lines.length - 1) { + this._finishLine(state, true); + } + } + return; + case 'text': + this._addRunsForText(state, node.text); + return; + case 'BR': + this._finishLine(state, true); + return; + case 'LI': + case 'P': + this._finishLine(state, false); + this._pushFormat(state, node); + blockNode = true; + break; + case 'B': + case 'I': + case 'FONT': + case 'TEXTFORMAT': + this._pushFormat(state, node); + formatNode = true; + break; + case 'U': + case 'A': + case 'IMG': + case 'SPAN': + default: + } + for (var i = 0; i < node.children.length; i++) { + var child = node.children[i]; + this._collectRuns(state, child); + } + if (formatNode) { + this._popFormat(state); + } + if (blockNode) { + this._finishLine(state, true); + } + }, + _addRunsForText: function (state, text) { + if (!text) { + return; + } + if (!state.wordWrap) { + this._addTextRun(state, text, state.ctx.measureText(text).width); + return; + } + while (text.length) { + var width = state.ctx.measureText(text).width; + var availableWidth = state.w - state.line.width; + if (availableWidth <= 0) { + this._finishLine(state, false); + availableWidth = state.w - state.line.width; + } + if (width <= availableWidth) { + this._addTextRun(state, text, width); + break; + } else { + var offset = text.length / width * availableWidth | 0; + while (state.ctx.measureText(text.substr(0, offset)).width < availableWidth && offset < text.length) { + offset++; + } + var wrapOffset = offset; + while (wrapOffset > -1) { + if (TextFieldContent.WRAP_OPPORTUNITIES[text[wrapOffset]]) { + wrapOffset++; + break; + } + wrapOffset--; + } + if (wrapOffset === -1) { + if (state.line.width > 0) { + this._finishLine(state, false); + continue; + } + while (state.ctx.measureText(text.substr(0, offset)).width > availableWidth) { + offset--; + } + if (offset === 0) { + offset = 1; + } + wrapOffset = offset; + } + var runText = text.substr(0, wrapOffset); + width = state.ctx.measureText(runText).width; + this._addTextRun(state, runText, width); + if (state.wordWrap) { + this._finishLine(state, false); + } + text = text.substr(wrapOffset); + } + } + }, + _addTextRun: function (state, text, width) { + if (text.length === 0) { + return; + } + var line = state.line; + var format = state.currentFormat; + var size = format.size; + var run = { + type: 't', + text: text, + x: line.width + }; + this._textRuns.push(run); + state.line.runs.push(run); + line.width += width | 0; + if (line.leading === 0 && format.leading > line.leading) { + line.leading = format.leading; + } + if (!line.largestFormat || size > line.largestFormat.size) { + line.largestFormat = format; + } + }, + _finishLine: function (state, forceNewline) { + var line = state.line; + if (line.runs.length === 0) { + if (forceNewline) { + var format = state.currentFormat; + state.line.y += format.font._metrics.height * format.size + format.leading | 0; + } + return; + } + var runs = line.runs; + var format = line.largestFormat; + var baselinePos = line.y + format.font._metrics.ascent * format.size; + for (var i = runs.length; i--;) { + runs[i].y = baselinePos; + } + var align = (state.currentFormat.align || '').toLowerCase(); + if (state.combinedAlign === null) { + state.combinedAlign = align; + } else if (state.combinedAlign !== align) { + state.combinedAlign = 'mixed'; + } + if (align === 'center' || align === 'right') { + var offset = Math.max(state.w - line.width, 0); + if (align === 'center') { + offset >>= 1; + } + for (i = runs.length; i--;) { + runs[i].x += offset; + } + } + line.height = format.font._metrics.height * format.size + line.leading | 0; + state.maxLineWidth = Math.max(state.maxLineWidth, line.width); + this.lines.push(line); + state.line = new TextFieldContent.TextLine(line.y + line.height); + }, + _pushFormat: function (state, node) { + var attributes = node.format; + var format = Object.create(state.formats[state.formats.length - 1]); + var fontChanged = false; + switch (node.type) { + case 'P': + if (attributes.ALIGN === format.align) { + return; + } + format.align = attributes.ALIGN; + break; + case 'B': + format.bold = true; + fontChanged = true; + break; + case 'I': + format.italic = true; + fontChanged = true; + break; + case 'FONT': + if (attributes.COLOR !== undefined) { + format.color = attributes.COLOR; + } + if (attributes.FACE !== undefined) { + format.face = attributes.FACE; + fontChanged = true; + } + if (attributes.SIZE !== undefined) { + format.size = parseFloat(attributes.SIZE); + } + if (attributes.LETTERSPACING !== undefined) { + format.letterspacing = parseFloat(attributes.LETTERSPACING); + } + if (attributes.KERNING !== undefined) { + format.kerning = attributes.KERNING && true; + } + case 'TEXTFORMAT': + if (attributes.LEADING !== undefined) { + format.leading = parseFloat(attributes.LEADING); + } + if (attributes.INDENT !== undefined) { + state.line.x = attributes.INDENT; + state.line.width += attributes.INDENT | 0; + } + break; + default: + warning('Unknown format node encountered: ' + node.type); + return; + } + if (state.textColor !== null) { + format.color = rgbIntAlphaToStr(state.textColor, 1); + } + if (fontChanged) { + this.resolveFont(format, state.embedFonts); + } + format.str = this.makeFormatString(format); + state.formats.push(format); + this._textRuns.push({ + type: 'f', + format: format + }); + state.currentFormat = format; + state.ctx.font = format.str; + }, + _popFormat: function (state) { + state.formats.pop(); + var format = state.currentFormat = state.formats[state.formats.length - 1]; + this._textRuns.push({ + type: 'f', + format: format + }); + state.ctx.font = state.str; + } +}; +var TextFormatDefinition = function () { + var measureTextField; + return { + __class__: 'flash.text.TextFormat', + initialize: function () { + }, + fromObject: function (obj) { + this._font = obj.face || null; + this._size = typeof obj.size === 'number' ? obj.size : null; + this._color = typeof obj.color === 'number' ? obj.color : null; + this._bold = typeof obj.bold === 'boolean' ? obj.bold : null; + this._italic = typeof obj.italic === 'boolean' ? obj.italic : null; + this._underline = typeof obj.underline === 'boolean' ? obj.underline : null; + this._url = obj.url || null; + this._target = obj.target || null; + this._align = obj.align || null; + this._leftMargin = typeof obj.leftMargin === 'number' ? obj.leftMargin : null; + this._rightMargin = typeof obj.rightMargin === 'number' ? obj.rightMargin : null; + this._indent = typeof obj.indent === 'number' ? obj.indent : null; + this._leading = typeof obj.leading === 'number' ? obj.leading : null; + return this; + }, + toObject: function () { + return { + face: this._font || 'serif', + size: this._size || 12, + color: this._color || 0, + bold: this._bold || false, + italic: this._italic || false, + underline: this._underline || false, + url: this._url, + target: this._target, + align: this._align || 'left', + leftMargin: this._leftMargin || 0, + rightMargin: this._rightMargin || 0, + indent: this._indent || 0, + leading: this._leading || 0 + }; + }, + as2GetTextExtent: function (text, width) { + if (!measureTextField) { + measureTextField = new flash.text.TextField(); + measureTextField._multiline = true; + } + if (!isNaN(width) && width > 0) { + measureTextField.width = width + 4; + measureTextField._wordWrap = true; + } else { + measureTextField._wordWrap = false; + } + measureTextField.defaultTextFormat = this; + measureTextField.text = text; + measureTextField.ensureDimensions(); + var result = {}; + var textWidth = measureTextField._textWidth; + var textHeight = measureTextField._textHeight; + result.asSetPublicProperty('width', textWidth); + result.asSetPublicProperty('height', textHeight); + result.asSetPublicProperty('textFieldWidth', textWidth + 4); + result.asSetPublicProperty('textFieldHeight', textHeight + 4); + var metrics = measureTextField.getLineMetrics(0); + result.asSetPublicProperty('ascent', metrics.asGetPublicProperty('ascent')); + result.asSetPublicProperty('descent', metrics.asGetPublicProperty('descent')); + return result; + }, + __glue__: { + native: { + static: {}, + instance: { + align: { + get: function align() { + return this._align; + }, + set: function align(value) { + this._align = value; + } + }, + blockIndent: { + get: function blockIndent() { + return this._blockIndent; + }, + set: function blockIndent(value) { + this._blockIndent = value; + } + }, + bold: { + get: function bold() { + return this._bold; + }, + set: function bold(value) { + this._bold = value; + } + }, + bullet: { + get: function bullet() { + return this._bullet; + }, + set: function bullet(value) { + this._bullet = value; + } + }, + color: { + get: function color() { + return this._color; + }, + set: function color(value) { + this._color = value; + } + }, + display: { + get: function display() { + return this._display; + }, + set: function display(value) { + this._display = value; + } + }, + font: { + get: function font() { + return this._font; + }, + set: function font(value) { + this._font = value; + } + }, + indent: { + get: function indent() { + return this._indent; + }, + set: function indent(value) { + this._indent = value; + } + }, + italic: { + get: function italic() { + return this._italic; + }, + set: function italic(value) { + this._italic = value; + } + }, + kerning: { + get: function kerning() { + return this._kerning; + }, + set: function kerning(value) { + this._kerning = value; + } + }, + leading: { + get: function leading() { + return this._leading; + }, + set: function leading(value) { + this._leading = value; + } + }, + leftMargin: { + get: function leftMargin() { + return this._leftMargin; + }, + set: function leftMargin(value) { + this._leftMargin = value; + } + }, + letterSpacing: { + get: function letterSpacing() { + return this._letterSpacing; + }, + set: function letterSpacing(value) { + this._letterSpacing = value; + } + }, + rightMargin: { + get: function rightMargin() { + return this._rightMargin; + }, + set: function rightMargin(value) { + this._rightMargin = value; + } + }, + size: { + get: function size() { + return this._size; + }, + set: function size(value) { + this._size = value; + } + }, + tabStops: { + get: function tabStops() { + return this._tabStops; + }, + set: function tabStops(value) { + this._tabStops = value; + } + }, + target: { + get: function target() { + return this._target; + }, + set: function target(value) { + this._target = value; + } + }, + underline: { + get: function underline() { + return this._underline; + }, + set: function underline(value) { + this._underline = value; + } + }, + url: { + get: function url() { + return this._url; + }, + set: function url(value) { + this._url = value; + } + } + } + } + } + }; + }.call(this); +var ContentElementDefinition = function () { + return { + __class__: 'flash.text.engine.ContentElement', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + textBlock: { + get: function textBlock() { + notImplemented('ContentElement.textBlock'); + return this._textBlock; + } + }, + textBlockBeginIndex: { + get: function textBlockBeginIndex() { + notImplemented('ContentElement.textBlockBeginIndex'); + return this._textBlockBeginIndex; + } + }, + elementFormat: { + get: function elementFormat() { + return this._elementFormat; + }, + set: function elementFormat(value) { + somewhatImplemented('ContentElement.elementFormat'); + this._elementFormat = value; + } + }, + eventMirror: { + get: function eventMirror() { + return this._eventMirror; + }, + set: function eventMirror(value) { + somewhatImplemented('ContentElement.eventMirror'); + this._eventMirror = value; + } + }, + groupElement: { + get: function groupElement() { + notImplemented('ContentElement.groupElement'); + return this._groupElement; + } + }, + rawText: { + get: function rawText() { + notImplemented('ContentElement.rawText'); + return this._rawText; + } + }, + text: { + get: function text() { + notImplemented('ContentElement.text'); + return this._text; + } + }, + textRotation: { + get: function textRotation() { + return this._textRotation; + }, + set: function textRotation(value) { + somewhatImplemented('ContentElement.textRotation'); + this._textRotation = value; + } + } + } + } + } + }; + }.call(this); +var ElementFormatDefinition = function () { + return { + __class__: 'flash.text.engine.ElementFormat', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + getFontMetrics: function getFontMetrics() { + notImplemented('ElementFormat.getFontMetrics'); + }, + alignmentBaseline: { + get: function alignmentBaseline() { + return this._alignmentBaseline; + }, + set: function alignmentBaseline(alignmentBaseline) { + somewhatImplemented('ElementFormat.alignmentBaseline'); + this._alignmentBaseline = alignmentBaseline; + } + }, + alpha: { + get: function alpha() { + return this._alpha; + }, + set: function alpha(value) { + somewhatImplemented('ElementFormat.alpha'); + this._alpha = value; + } + }, + baselineShift: { + get: function baselineShift() { + return this._baselineShift; + }, + set: function baselineShift(value) { + somewhatImplemented('ElementFormat.baselineShift'); + this._baselineShift = value; + } + }, + breakOpportunity: { + get: function breakOpportunity() { + return this._breakOpportunity; + }, + set: function breakOpportunity(opportunityType) { + somewhatImplemented('ElementFormat.breakOpportunity'); + this._breakOpportunity = opportunityType; + } + }, + color: { + get: function color() { + return this._color; + }, + set: function color(value) { + somewhatImplemented('ElementFormat.color'); + this._color = value; + } + }, + dominantBaseline: { + get: function dominantBaseline() { + return this._dominantBaseline; + }, + set: function dominantBaseline(dominantBaseline) { + somewhatImplemented('ElementFormat.dominantBaseline'); + this._dominantBaseline = dominantBaseline; + } + }, + fontDescription: { + get: function fontDescription() { + return this._fontDescription; + }, + set: function fontDescription(value) { + somewhatImplemented('ElementFormat.fontDescription'); + this._fontDescription = value; + } + }, + digitCase: { + get: function digitCase() { + return this._digitCase; + }, + set: function digitCase(digitCaseType) { + somewhatImplemented('ElementFormat.digitCase'); + this._digitCase = digitCaseType; + } + }, + digitWidth: { + get: function digitWidth() { + return this._digitWidth; + }, + set: function digitWidth(digitWidthType) { + somewhatImplemented('ElementFormat.digitWidth'); + this._digitWidth = digitWidthType; + } + }, + ligatureLevel: { + get: function ligatureLevel() { + return this._ligatureLevel; + }, + set: function ligatureLevel(ligatureLevelType) { + somewhatImplemented('ElementFormat.ligatureLevel'); + this._ligatureLevel = ligatureLevelType; + } + }, + fontSize: { + get: function fontSize() { + return this._fontSize; + }, + set: function fontSize(value) { + somewhatImplemented('ElementFormat.fontSize'); + this._fontSize = value; + } + }, + kerning: { + get: function kerning() { + return this._kerning; + }, + set: function kerning(value) { + somewhatImplemented('ElementFormat.kerning'); + this._kerning = value; + } + }, + locale: { + get: function locale() { + return this._locale; + }, + set: function locale(value) { + somewhatImplemented('ElementFormat.locale'); + this._locale = value; + } + }, + textRotation: { + get: function textRotation() { + return this._textRotation; + }, + set: function textRotation(value) { + somewhatImplemented('ElementFormat.textRotation'); + this._textRotation = value; + } + }, + trackingRight: { + get: function trackingRight() { + return this._trackingRight; + }, + set: function trackingRight(value) { + somewhatImplemented('ElementFormat.trackingRight'); + this._trackingRight = value; + } + }, + trackingLeft: { + get: function trackingLeft() { + return this._trackingLeft; + }, + set: function trackingLeft(value) { + somewhatImplemented('ElementFormat.trackingLeft'); + this._trackingLeft = value; + } + }, + typographicCase: { + get: function typographicCase() { + return this._typographicCase; + }, + set: function typographicCase(typographicCaseType) { + somewhatImplemented('ElementFormat.typographicCase'); + this._typographicCase = typographicCaseType; + } + }, + locked: { + get: function locked() { + notImplemented('ElementFormat.locked'); + return this._locked; + }, + set: function locked(value) { + notImplemented('ElementFormat.locked'); + this._locked = value; + } + } + } + } + } + }; + }.call(this); +var FontDescriptionDefinition = function () { + return { + __class__: 'flash.text.engine.FontDescription', + initialize: function () { + }, + __glue__: { + native: { + static: { + isFontCompatible: function isFontCompatible(fontName, fontWeight, fontPosture) { + notImplemented('FontDescription.isFontCompatible'); + }, + isDeviceFontCompatible: function isDeviceFontCompatible(fontName, fontWeight, fontPosture) { + notImplemented('FontDescription.isDeviceFontCompatible'); + } + }, + instance: { + renderingMode: { + get: function renderingMode() { + return this._renderingMode; + }, + set: function renderingMode(value) { + somewhatImplemented('FontDescription.renderingMode'); + this._renderingMode = value; + } + }, + fontLookup: { + get: function fontLookup() { + return this._fontLookup; + }, + set: function fontLookup(value) { + somewhatImplemented('FontDescription.fontLookup'); + this._fontLookup = value; + } + }, + fontName: { + get: function fontName() { + return this._fontName; + }, + set: function fontName(value) { + somewhatImplemented('FontDescription.fontName'); + this._fontName = value; + } + }, + fontPosture: { + get: function fontPosture() { + return this._fontPosture; + }, + set: function fontPosture(value) { + somewhatImplemented('FontDescription.fontPosture'); + this._fontPosture = value; + } + }, + fontWeight: { + get: function fontWeight() { + return this._fontWeight; + }, + set: function fontWeight(value) { + somewhatImplemented('FontDescription.fontWeight'); + this._fontWeight = value; + } + }, + cffHinting: { + get: function cffHinting() { + return this._cffHinting; + }, + set: function cffHinting(value) { + somewhatImplemented('FontDescription.cffHinting'); + this._cffHinting = value; + } + }, + locked: { + get: function locked() { + notImplemented('FontDescription.locked'); + return this._locked; + }, + set: function locked(value) { + notImplemented('FontDescription.locked'); + this._locked = value; + } + } + } + }, + script: { + static: {}, + instance: {} + } + } + }; + }.call(this); +var GroupElementDefinition = function () { + return { + __class__: 'flash.text.engine.GroupElement', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + getElementAt: function getElementAt(index) { + notImplemented('GroupElement.getElementAt'); + }, + setElements: function setElements(value) { + somewhatImplemented('GroupElement.setElements'); + this._elements = value; + }, + groupElements: function groupElements(beginIndex, endIndex) { + notImplemented('GroupElement.groupElements'); + }, + ungroupElements: function ungroupElements(groupIndex) { + notImplemented('GroupElement.ungroupElements'); + }, + mergeTextElements: function mergeTextElements(beginIndex, endIndex) { + notImplemented('GroupElement.mergeTextElements'); + }, + splitTextElement: function splitTextElement(elementIndex, splitIndex) { + notImplemented('GroupElement.splitTextElement'); + }, + replaceElements: function replaceElements(beginIndex, endIndex, newElements) { + notImplemented('GroupElement.replaceElements'); + }, + getElementAtCharIndex: function getElementAtCharIndex(charIndex) { + notImplemented('GroupElement.getElementAtCharIndex'); + }, + elementCount: { + get: function elementCount() { + notImplemented('GroupElement.elementCount'); + return this._elementCount; + } + } + } + } + } + }; + }.call(this); +var SpaceJustifierDefinition = function () { + return { + __class__: 'flash.text.engine.SpaceJustifier', + initialize: function () { + this._letterSpacing = false; + this._optimumSpacing = 1; + this._minimumSpacing = 0.5; + this._maximumSpacing = 1.5; + }, + __glue__: { + native: { + static: {}, + instance: { + cloneSpacing: function cloneSpacing(justifier) { + somewhatImplemented('SpaceJustifier.cloneSpacing'); + justifier._optimumSpacing = this._optimumSpacing; + justifier._minimumSpacing = this._minimumSpacing; + justifier._maximumSpacing = this._maximumSpacing; + }, + letterSpacing: { + get: function letterSpacing() { + return this._letterSpacing; + }, + set: function letterSpacing(value) { + somewhatImplemented('SpaceJustifier.letterSpacing'); + this._letterSpacing = value; + } + }, + minimumSpacing: { + get: function minimumSpacing() { + return this._minimumSpacing; + }, + set: function minimumSpacing(value) { + somewhatImplemented('SpaceJustifier.minimumSpacing'); + this._minimumSpacing = value; + } + }, + optimumSpacing: { + get: function optimumSpacing() { + return this._optimumSpacing; + }, + set: function optimumSpacing(value) { + somewhatImplemented('SpaceJustifier.optimumSpacing'); + this._optimumSpacing = value; + } + }, + maximumSpacing: { + get: function maximumSpacing() { + return this._maximumSpacing; + }, + set: function maximumSpacing(value) { + somewhatImplemented('SpaceJustifier.maximumSpacing'); + this._maximumSpacing = value; + } + } + } + } + } + }; + }.call(this); +var TextBlockDefinition = function () { + return { + __class__: 'flash.text.engine.TextBlock', + initialize: function () { + this._firstLine = null; + this._lastLine = null; + }, + __glue__: { + native: { + static: {}, + instance: { + getTextJustifier: function getTextJustifier() { + return this._textJustifier; + }, + setTextJustifier: function setTextJustifier(value) { + somewhatImplemented('TextBlock.setTextJustifier'); + this._textJustifier = value; + }, + getTabStops: function getTabStops() { + return this._tabStops; + }, + setTabStops: function setTabStops(value) { + somewhatImplemented('TextBlock.setTabStops'); + this._tabStops = value; + }, + findNextAtomBoundary: function findNextAtomBoundary(afterCharIndex) { + notImplemented('TextBlock.findNextAtomBoundary'); + }, + findPreviousAtomBoundary: function findPreviousAtomBoundary(beforeCharIndex) { + notImplemented('TextBlock.findPreviousAtomBoundary'); + }, + findNextWordBoundary: function findNextWordBoundary(afterCharIndex) { + notImplemented('TextBlock.findNextWordBoundary'); + }, + findPreviousWordBoundary: function findPreviousWordBoundary(beforeCharIndex) { + notImplemented('TextBlock.findPreviousWordBoundary'); + }, + getTextLineAtCharIndex: function getTextLineAtCharIndex(charIndex) { + notImplemented('TextBlock.getTextLineAtCharIndex'); + }, + DoCreateTextLine: function DoCreateTextLine(previousLine, width, lineOffset, fitSomething, reuseLine) { + somewhatImplemented('TextBlock.DoCreateTextLine'); + if (previousLine) { + return null; + } + var textLine = new flash.text.engine.TextLine(); + textLine._textBlock = this; + textLine._specifiedWidth = width; + textLine._rawTextLength = 0; + textLine._textWidth = 0; + textLine._textHeight = 0; + textLine._ascent = 0; + textLine._descent = 0; + textLine._unjustifiedTextWidth = 0; + textLine._validity = 'valid'; + textLine._previousLine = null; + textLine._nextLine = null; + this._firstLine = textLine; + this._lastLine = textLine; + return textLine; + }, + releaseLineCreationData: function releaseLineCreationData() { + notImplemented('TextBlock.releaseLineCreationData'); + }, + releaseLines: function releaseLines(firstLine, lastLine) { + notImplemented('TextBlock.releaseLines'); + }, + dump: function dump() { + notImplemented('TextBlock.dump'); + }, + applyNonLinearFontScaling: { + get: function applyNonLinearFontScaling() { + return this._applyNonLinearFontScaling; + }, + set: function applyNonLinearFontScaling(value) { + somewhatImplemented('TextBlock.applyNonLinearFontScaling'); + this._applyNonLinearFontScaling = value; + } + }, + baselineFontDescription: { + get: function baselineFontDescription() { + return this._baselineFontDescription; + }, + set: function baselineFontDescription(value) { + somewhatImplemented('TextBlock.baselineFontDescription'); + this._baselineFontDescription = value; + } + }, + baselineFontSize: { + get: function baselineFontSize() { + return this._baselineFontSize; + }, + set: function baselineFontSize(value) { + somewhatImplemented('TextBlock.baselineFontSize'); + this._baselineFontSize = value; + } + }, + baselineZero: { + get: function baselineZero() { + return this._baselineZero; + }, + set: function baselineZero(value) { + somewhatImplemented('TextBlock.baselineZero'); + this._baselineZero = value; + } + }, + content: { + get: function content() { + return this._content; + }, + set: function content(value) { + somewhatImplemented('TextBlock.content'); + this._content = value; + } + }, + bidiLevel: { + get: function bidiLevel() { + return this._bidiLevel; + }, + set: function bidiLevel(value) { + somewhatImplemented('TextBlock.bidiLevel'); + this._bidiLevel = value; + } + }, + firstInvalidLine: { + get: function firstInvalidLine() { + notImplemented('TextBlock.firstInvalidLine'); + return this._firstInvalidLine; + } + }, + firstLine: { + get: function firstLine() { + somewhatImplemented('TextBlock.firstLine'); + return this._firstLine; + } + }, + lastLine: { + get: function lastLine() { + somewhatImplemented('TextBlock.lastLine'); + return this._lastLine; + } + }, + textLineCreationResult: { + get: function textLineCreationResult() { + notImplemented('TextBlock.textLineCreationResult'); + return this._textLineCreationResult; + } + }, + lineRotation: { + get: function lineRotation() { + return this._lineRotation; + }, + set: function lineRotation(value) { + somewhatImplemented('TextBlock.lineRotation'); + this._lineRotation = value; + } + } + } + } + } + }; + }.call(this); +var TextElementDefinition = function () { + return { + __class__: 'flash.text.engine.TextElement', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + replaceText: function replaceText(beginIndex, endIndex, newText) { + somewhatImplemented('TextElement.replaceText'); + var text = this._text || ''; + this._text = text.slice(0, beginIndex) + newText + text.slice(endIndex); + }, + text: { + set: function text(value) { + somewhatImplemented('TextElement.text'); + this._text = value; + } + } + } + } + } + }; + }.call(this); +var TextJustifierDefinition = function () { + return { + __class__: 'flash.text.engine.TextJustifier', + initialize: function () { + this._locale = null; + this._lineJustification = null; + }, + __glue__: { + native: { + static: {}, + instance: { + setLocale: function setLocale(value) { + somewhatImplemented('TextJustifier.setLocale'); + this._locale = value; + }, + locale: { + get: function locale() { + return this._locale; + } + }, + lineJustification: { + get: function lineJustification() { + return this._lineJustification; + }, + set: function lineJustification(value) { + somewhatImplemented('TextJustifier.lineJustification'); + this._lineJustification = value; + } + } + } + } + } + }; + }.call(this); +var TextLineDefinition = function () { + return { + __class__: 'flash.text.engine.TextLine', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + getAtomIndexAtPoint: function getAtomIndexAtPoint(stageX, stageY) { + notImplemented('TextLine.getAtomIndexAtPoint'); + }, + getAtomIndexAtCharIndex: function getAtomIndexAtCharIndex(charIndex) { + notImplemented('TextLine.getAtomIndexAtCharIndex'); + }, + getAtomBounds: function getAtomBounds(atomIndex) { + notImplemented('TextLine.getAtomBounds'); + }, + getAtomBidiLevel: function getAtomBidiLevel(atomIndex) { + notImplemented('TextLine.getAtomBidiLevel'); + }, + getAtomTextRotation: function getAtomTextRotation(atomIndex) { + notImplemented('TextLine.getAtomTextRotation'); + }, + getAtomTextBlockBeginIndex: function getAtomTextBlockBeginIndex(atomIndex) { + notImplemented('TextLine.getAtomTextBlockBeginIndex'); + }, + getAtomTextBlockEndIndex: function getAtomTextBlockEndIndex(atomIndex) { + notImplemented('TextLine.getAtomTextBlockEndIndex'); + }, + getAtomCenter: function getAtomCenter(atomIndex) { + notImplemented('TextLine.getAtomCenter'); + }, + getAtomWordBoundaryOnLeft: function getAtomWordBoundaryOnLeft(atomIndex) { + notImplemented('TextLine.getAtomWordBoundaryOnLeft'); + }, + getAtomGraphic: function getAtomGraphic(atomIndex) { + notImplemented('TextLine.getAtomGraphic'); + }, + getBaselinePosition: function getBaselinePosition(baseline) { + notImplemented('TextLine.getBaselinePosition'); + }, + dump: function dump() { + notImplemented('TextLine.dump'); + }, + textBlock: { + get: function textBlock() { + notImplemented('TextLine.textBlock'); + return this._textBlock; + } + }, + hasGraphicElement: { + get: function hasGraphicElement() { + notImplemented('TextLine.hasGraphicElement'); + return this._hasGraphicElement; + } + }, + hasTabs: { + get: function hasTabs() { + notImplemented('TextLine.hasTabs'); + return this._hasTabs; + } + }, + nextLine: { + get: function nextLine() { + somewhatImplemented('TextLine.nextLine'); + return this._nextLine; + } + }, + previousLine: { + get: function previousLine() { + somewhatImplemented('TextLine.previousLine'); + return this._previousLine; + } + }, + ascent: { + get: function ascent() { + somewhatImplemented('TextLine.ascent'); + return this._ascent; + } + }, + descent: { + get: function descent() { + somewhatImplemented('TextLine.descent'); + return this._descent; + } + }, + textHeight: { + get: function textHeight() { + somewhatImplemented('TextLine.textHeight'); + return this._textHeight; + } + }, + textWidth: { + get: function textWidth() { + somewhatImplemented('TextLine.textWidth'); + return this._textWidth; + } + }, + totalAscent: { + get: function totalAscent() { + notImplemented('TextLine.totalAscent'); + return this._totalAscent; + } + }, + totalDescent: { + get: function totalDescent() { + notImplemented('TextLine.totalDescent'); + return this._totalDescent; + } + }, + totalHeight: { + get: function totalHeight() { + notImplemented('TextLine.totalHeight'); + return this._totalHeight; + } + }, + textBlockBeginIndex: { + get: function textBlockBeginIndex() { + notImplemented('TextLine.textBlockBeginIndex'); + return this._textBlockBeginIndex; + } + }, + rawTextLength: { + get: function rawTextLength() { + somewhatImplemented('TextLine.rawTextLength'); + return this._rawTextLength; + } + }, + specifiedWidth: { + get: function specifiedWidth() { + somewhatImplemented('TextLine.specifiedWidth'); + return this._specifiedWidth; + } + }, + unjustifiedTextWidth: { + get: function unjustifiedTextWidth() { + somewhatImplemented('TextLine.unjustifiedTextWidth'); + return this._unjustifiedTextWidth; + } + }, + validity: { + get: function validity() { + return this._validity; + }, + set: function validity(value) { + somewhatImplemented('TextLine.validity'); + this._validity = value; + } + }, + atomCount: { + get: function atomCount() { + notImplemented('TextLine.atomCount'); + return this._atomCount; + } + }, + mirrorRegions: { + get: function mirrorRegions() { + notImplemented('TextLine.mirrorRegions'); + return this._mirrorRegions; + } + } + } + } + } + }; + }.call(this); +{ + var ContextMenuDefinition = function () { + return { + __class__: 'flash.ui.ContextMenu', + initialize: function () { + }, + __glue__: { + native: { + static: { + _checkSupported: function _checkSupported() { + notImplemented('ContextMenu._checkSupported'); + } + }, + instance: { + cloneLinkAndClipboardProperties: function cloneLinkAndClipboardProperties(c) { + notImplemented('ContextMenu.cloneLinkAndClipboardProperties'); + }, + builtInItems: { + get: function builtInItems() { + somewhatImplemented('ContextMenu.builtInItems'); + return this._builtInItems; + }, + set: function builtInItems(value) { + somewhatImplemented('ContextMenu.builtInItems'); + this._builtInItems = value; + } + }, + customItems: { + get: function customItems() { + somewhatImplemented('ContextMenu.customItems'); + return this._customItems; + }, + set: function customItems(value) { + somewhatImplemented('ContextMenu.customItems'); + this._customItems = value; + } + }, + link: { + get: function link() { + notImplemented('ContextMenu.link'); + return this._link; + }, + set: function link(value) { + notImplemented('ContextMenu.link'); + this._link = value; + } + }, + clipboardMenu: { + get: function clipboardMenu() { + notImplemented('ContextMenu.clipboardMenu'); + return this._clipboardMenu; + }, + set: function clipboardMenu(value) { + notImplemented('ContextMenu.clipboardMenu'); + this._clipboardMenu = value; + } + }, + clipboardItems: { + get: function clipboardItems() { + notImplemented('ContextMenu.clipboardItems'); + return this._clipboardItems; + }, + set: function clipboardItems(value) { + notImplemented('ContextMenu.clipboardItems'); + this._clipboardItems = value; + } + } + } + } + } + }; + }.call(this); +} +var ContextMenuItemDefinition = function () { + return { + __class__: 'flash.ui.ContextMenuItem', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + caption: { + get: function caption() { + somewhatImplemented('ContextMenuItem.caption'); + return this._caption; + }, + set: function caption(value) { + somewhatImplemented('ContextMenuItem.caption'); + this._caption = value; + } + }, + separatorBefore: { + get: function separatorBefore() { + somewhatImplemented('ContextMenuItem.separatorBefore'); + return this._separatorBefore; + }, + set: function separatorBefore(value) { + somewhatImplemented('ContextMenuItem.separatorBefore'); + this._separatorBefore = value; + } + }, + visible: { + get: function visible() { + somewhatImplemented('ContextMenuItem.visible'); + return this._visible; + }, + set: function visible(value) { + somewhatImplemented('ContextMenuItem.visible'); + this._visible = value; + } + } + } + } + } + }; + }.call(this); +var ShumwayKeyboardListener = { + _lastKeyCode: 0, + _captureKeyPress: false, + _charCodeMap: [], + focus: null, + handleEvent: function (domEvt) { + var keyCode = domEvt.keyCode; + if (domEvt.type === 'keydown') { + this._lastKeyCode = keyCode; + this._captureKeyPress = keyCode === 8 || keyCode === 9 || keyCode === 13 || keyCode === 32 || keyCode >= 48 && keyCode <= 90 || keyCode > 145; + if (this._captureKeyPress) { + return; + } + this._charCodeMap[keyCode] = 0; + } else if (domEvt.type === 'keypress') { + if (this._captureKeyPress) { + keyCode = this._lastKeyCode; + this._charCodeMap[keyCode] = domEvt.charCode; + } else { + return; + } + } + if (this.focus) { + this.focus._dispatchEvent(new flash.events.KeyboardEvent(domEvt.type === 'keyup' ? 'keyUp' : 'keyDown', true, false, domEvt.type === 'keyup' ? this._charCodeMap[keyCode] : domEvt.charCode, domEvt.type === 'keyup' ? domEvt.keyCode : this._lastKeyCode, domEvt.keyLocation, domEvt.ctrlKey, domEvt.altKey, domEvt.shiftKey)); + } + } + }; +window.addEventListener('keydown', ShumwayKeyboardListener); +window.addEventListener('keypress', ShumwayKeyboardListener); +window.addEventListener('keyup', ShumwayKeyboardListener); +var KeyboardDefinition = function () { + var def = { + get capsLock() { + return false; + }, + get hasVirtualKeyboard() { + return false; + }, + get numLock() { + return false; + }, + get physicalKeyboardType() { + return 'alphanumeric'; + }, + get isAccessible() { + return true; + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + script: { + static: scriptProperties('public', [ + 'A', + 'ALTERNATE', + 'AUDIO', + 'B', + 'BACK', + 'BACKQUOTE', + 'BACKSLASH', + 'BACKSPACE', + 'BLUE', + 'C', + 'CAPS_LOCK', + 'CHANNEL_DOWN', + 'CHANNEL_UP', + 'COMMA', + 'COMMAND', + 'CONTROL', + 'D', + 'DELETE', + 'DOWN', + 'DVR', + 'E', + 'END', + 'ENTER', + 'EQUAL', + 'ESCAPE', + 'EXIT', + 'F', + 'F1', + 'F10', + 'F11', + 'F12', + 'F13', + 'F14', + 'F15', + 'F2', + 'F3', + 'F4', + 'F5', + 'F6', + 'F7', + 'F8', + 'F9', + 'FAST_FORWARD', + 'G', + 'GREEN', + 'GUIDE', + 'H', + 'HELP', + 'HOME', + 'I', + 'INFO', + 'INPUT', + 'INSERT', + 'J', + 'K', + 'KEYNAME_BEGIN', + 'KEYNAME_BREAK', + 'KEYNAME_CLEARDISPLAY', + 'KEYNAME_CLEARLINE', + 'KEYNAME_DELETE', + 'KEYNAME_DELETECHAR', + 'KEYNAME_DELETELINE', + 'KEYNAME_DOWNARROW', + 'KEYNAME_END', + 'KEYNAME_EXECUTE', + 'KEYNAME_F1', + 'KEYNAME_F10', + 'KEYNAME_F11', + 'KEYNAME_F12', + 'KEYNAME_F13', + 'KEYNAME_F14', + 'KEYNAME_F15', + 'KEYNAME_F16', + 'KEYNAME_F17', + 'KEYNAME_F18', + 'KEYNAME_F19', + 'KEYNAME_F2', + 'KEYNAME_F20', + 'KEYNAME_F21', + 'KEYNAME_F22', + 'KEYNAME_F23', + 'KEYNAME_F24', + 'KEYNAME_F25', + 'KEYNAME_F26', + 'KEYNAME_F27', + 'KEYNAME_F28', + 'KEYNAME_F29', + 'KEYNAME_F3', + 'KEYNAME_F30', + 'KEYNAME_F31', + 'KEYNAME_F32', + 'KEYNAME_F33', + 'KEYNAME_F34', + 'KEYNAME_F35', + 'KEYNAME_F4', + 'KEYNAME_F5', + 'KEYNAME_F6', + 'KEYNAME_F7', + 'KEYNAME_F8', + 'KEYNAME_F9', + 'KEYNAME_FIND', + 'KEYNAME_HELP', + 'KEYNAME_HOME', + 'KEYNAME_INSERT', + 'KEYNAME_INSERTCHAR', + 'KEYNAME_INSERTLINE', + 'KEYNAME_LEFTARROW', + 'KEYNAME_MENU', + 'KEYNAME_MODESWITCH', + 'KEYNAME_NEXT', + 'KEYNAME_PAGEDOWN', + 'KEYNAME_PAGEUP', + 'KEYNAME_PAUSE', + 'KEYNAME_PREV', + 'KEYNAME_PRINT', + 'KEYNAME_PRINTSCREEN', + 'KEYNAME_REDO', + 'KEYNAME_RESET', + 'KEYNAME_RIGHTARROW', + 'KEYNAME_SCROLLLOCK', + 'KEYNAME_SELECT', + 'KEYNAME_STOP', + 'KEYNAME_SYSREQ', + 'KEYNAME_SYSTEM', + 'KEYNAME_UNDO', + 'KEYNAME_UPARROW', + 'KEYNAME_USER', + 'L', + 'LAST', + 'LEFT', + 'LEFTBRACKET', + 'LIVE', + 'M', + 'MASTER_SHELL', + 'MENU', + 'MINUS', + 'N', + 'NEXT', + 'NUMBER_0', + 'NUMBER_1', + 'NUMBER_2', + 'NUMBER_3', + 'NUMBER_4', + 'NUMBER_5', + 'NUMBER_6', + 'NUMBER_7', + 'NUMBER_8', + 'NUMBER_9', + 'NUMPAD', + 'NUMPAD_0', + 'NUMPAD_1', + 'NUMPAD_2', + 'NUMPAD_3', + 'NUMPAD_4', + 'NUMPAD_5', + 'NUMPAD_6', + 'NUMPAD_7', + 'NUMPAD_8', + 'NUMPAD_9', + 'NUMPAD_ADD', + 'NUMPAD_DECIMAL', + 'NUMPAD_DIVIDE', + 'NUMPAD_ENTER', + 'NUMPAD_MULTIPLY', + 'NUMPAD_SUBTRACT', + 'O', + 'P', + 'PAGE_DOWN', + 'PAGE_UP', + 'PAUSE', + 'PERIOD', + 'PLAY', + 'PREVIOUS', + 'Q', + 'QUOTE', + 'R', + 'RECORD', + 'RED', + 'REWIND', + 'RIGHT', + 'RIGHTBRACKET', + 'S', + 'SEARCH', + 'SEMICOLON', + 'SETUP', + 'SHIFT', + 'SKIP_BACKWARD', + 'SKIP_FORWARD', + 'SLASH', + 'SPACE', + 'STOP', + 'STRING_BEGIN', + 'STRING_BREAK', + 'STRING_CLEARDISPLAY', + 'STRING_CLEARLINE', + 'STRING_DELETE', + 'STRING_DELETECHAR', + 'STRING_DELETELINE', + 'STRING_DOWNARROW', + 'STRING_END', + 'STRING_EXECUTE', + 'STRING_F1', + 'STRING_F10', + 'STRING_F11', + 'STRING_F12', + 'STRING_F13', + 'STRING_F14', + 'STRING_F15', + 'STRING_F16', + 'STRING_F17', + 'STRING_F18', + 'STRING_F19', + 'STRING_F2', + 'STRING_F20', + 'STRING_F21', + 'STRING_F22', + 'STRING_F23', + 'STRING_F24', + 'STRING_F25', + 'STRING_F26', + 'STRING_F27', + 'STRING_F28', + 'STRING_F29', + 'STRING_F3', + 'STRING_F30', + 'STRING_F31', + 'STRING_F32', + 'STRING_F33', + 'STRING_F34', + 'STRING_F35', + 'STRING_F4', + 'STRING_F5', + 'STRING_F6', + 'STRING_F7', + 'STRING_F8', + 'STRING_F9', + 'STRING_FIND', + 'STRING_HELP', + 'STRING_HOME', + 'STRING_INSERT', + 'STRING_INSERTCHAR', + 'STRING_INSERTLINE', + 'STRING_LEFTARROW', + 'STRING_MENU', + 'STRING_MODESWITCH', + 'STRING_NEXT', + 'STRING_PAGEDOWN', + 'STRING_PAGEUP', + 'STRING_PAUSE', + 'STRING_PREV', + 'STRING_PRINT', + 'STRING_PRINTSCREEN', + 'STRING_REDO', + 'STRING_RESET', + 'STRING_RIGHTARROW', + 'STRING_SCROLLLOCK', + 'STRING_SELECT', + 'STRING_STOP', + 'STRING_SYSREQ', + 'STRING_SYSTEM', + 'STRING_UNDO', + 'STRING_UPARROW', + 'STRING_USER', + 'SUBTITLE', + 'T', + 'TAB', + 'U', + 'UP', + 'V', + 'VOD', + 'W', + 'X', + 'Y', + 'YELLOW', + 'Z', + 'CharCodeStrings' + ]) + }, + native: { + instance: { + capsLock: desc(def, 'capsLock'), + hasVirtualKeyboard: desc(def, 'hasVirtualKeyboard'), + numLock: desc(def, 'numLock'), + physicalKeyboardType: desc(def, 'physicalKeyboardType'), + isAccessible: desc(def, 'isAccessible') + } + } + }; + return def; + }.call(this); +var MouseDefinition = function () { + var def = { + __class__: 'flash.ui.Mouse' + }; + function hide() { + } + function show() { + } + function registerCursor() { + notImplemented(); + } + function unregisterCursor() { + notImplemented(); + } + def.__glue__ = { + native: { + static: { + cursor: { + get: function () { + return 'auto'; + }, + set: function () { + notImplemented(); + } + }, + supportsCursor: { + get: function () { + return true; + } + }, + supportsNativeCursor: { + get: function () { + return true; + } + }, + hide: hide, + show: show, + registerCursor: registerCursor, + unregisterCursor: unregisterCursor + } + } + }; + return def; + }.call(this); +var MouseCursorDataDefinition = function () { + return { + __class__: 'flash.ui.MouseCursorData', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + data: { + get: function data() { + notImplemented('MouseCursorData.data'); + return this._data; + }, + set: function data(data) { + notImplemented('MouseCursorData.data'); + this._data = data; + } + }, + hotSpot: { + get: function hotSpot() { + notImplemented('MouseCursorData.hotSpot'); + return this._hotSpot; + }, + set: function hotSpot(data) { + notImplemented('MouseCursorData.hotSpot'); + this._hotSpot = data; + } + }, + frameRate: { + get: function frameRate() { + notImplemented('MouseCursorData.frameRate'); + return this._frameRate; + }, + set: function frameRate(data) { + notImplemented('MouseCursorData.frameRate'); + this._frameRate = data; + } + } + } + } + } + }; + }.call(this); +{ + var DictionaryDefinition = function () { + return { + __class__: 'flash.utils.Dictionary', + initialize: function () { + }, + __glue__: { + native: { + static: {}, + instance: { + init: function init(weakKeys) { + notImplemented('Dictionary.init'); + } + } + } + } + }; + }.call(this); +} +var TimerDefinition = function () { + var def = { + __class__: 'flash.utils.Timer', + initialize: function () { + this._running = false; + } + }; + def.__glue__ = { + native: { + instance: { + running: { + get: function () { + return this._running; + } + }, + _start: function (delay, closure) { + this._running = true; + this.interval = setInterval(closure, delay); + }, + stop: function () { + this._running = false; + clearInterval(this.interval); + }, + _tick: function () { + if (!this._running) { + return; + } + this._dispatchEvent(new flash.events.TimerEvent('timer', true, false)); + } + } + } + }; + return def; + }.call(this); +{ + var AccessibilityDefinition = function () { + return { + __class__: 'flash.accessibility.Accessibility', + initialize: function () { + }, + __glue__: { + native: { + static: { + sendEvent: function sendEvent(source, childID, eventType, nonHTML) { + notImplemented('Accessibility.sendEvent'); + }, + updateProperties: function updateProperties() { + notImplemented('Accessibility.updateProperties'); + }, + active: { + get: function active() { + somewhatImplemented('Accessibility.active'); + return false; + } + } + }, + instance: {} + } + } + }; + }.call(this); +} +{ + var AS2ButtonDefinition = function () { + var def = { + __class__: 'avm1lib.AS2Button', + initialize: function () { + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + _as3Object: { + get: function () { + return this.$nativeObject; + } + }, + _init: function init(nativeButton) { + Object.defineProperty(this, '$nativeObject', { + value: nativeButton + }); + nativeButton.$as2Object = this; + initDefaultListeners(this); + } + } + }, + script: { + instance: Glue.ALL + } + }; + return def; + }.call(this); +} +var AS2GlobalsDefinition = function () { + var def = { + __class__: 'avm1lib.AS2Globals', + initialize: function () { + flash.text.TextFormat.prototype.asDefinePublicProperty('getTextExtent', { + value: TextFormatDefinition.as2GetTextExtent, + writable: false, + enumerable: false, + configurable: false + }); + } + }; + def.__glue__ = { + native: { + instance: { + ASSetPropFlags: function ASSetPropFlags(obj, children, flags, allowFalse) { + }, + _addToPendingScripts: function _addToPendingScripts(subject, fn, args) { + AS2Context.instance.addToPendingScripts(function () { + fn.apply(subject, args); + }); + }, + _setLevel: function _setLevel(level, loader) { + AS2Context.instance.stage._as2SetLevel(level, loader); + }, + trace: function (expression) { + var trace = avm2.applicationDomain.getProperty(Multiname.fromSimpleName('trace'), true, true); + trace(expression); + } + }, + static: { + _addInternalClasses: function _addInternalClasses(proto) { + proto.asSetPublicProperty('Object', Stubs.Object); + proto.asSetPublicProperty('Function', Stubs.Function); + proto.asSetPublicProperty('Array', Stubs.Array); + proto.asSetPublicProperty('Number', Stubs.Number); + proto.asSetPublicProperty('Math', avm2.systemDomain.getClass('Math')); + proto.asSetPublicProperty('Boolean', Stubs.Boolean); + proto.asSetPublicProperty('Date', Stubs.Date); + proto.asSetPublicProperty('RegExp', Stubs.RegExp); + proto.asSetPublicProperty('String', Stubs.String); + } + } + }, + script: { + instance: Glue.ALL + } + }; + return def; + }.call(this); +var AS2MovieClipDefinition = function () { + var def = { + __class__: 'avm1lib.AS2MovieClip', + initialize: function () { + }, + _insertChildAtDepth: function _insertChildAtDepth(mc, depth) { + return this.$nativeObject._insertChildAtDepth(mc, depth); + }, + _duplicate: function _duplicate(name, depth, initObject) { + return this.$nativeObject._duplicate(name, depth, initObject); + }, + _constructSymbol: function constructSymbol(symbolId, name) { + var theClass = AS2Context.instance.classes && AS2Context.instance.classes[symbolId]; + var symbolProps = AS2Context.instance.assets[symbolId]; + var symbolClass = flash.display.MovieClip.class; + var mc = symbolClass.createAsSymbol(symbolProps); + mc._avm1SymbolClass = theClass; + symbolClass.instanceConstructor.call(mc); + this.$nativeObject.addChild(mc); + return mc; + }, + _gotoLabel: function (label) { + this.$nativeObject.gotoLabel(label); + }, + _callFrame: function callFrame(frame) { + this.$nativeObject._callFrame(frame); + }, + init: function init(nativeMovieClip) { + if (!nativeMovieClip) { + return; + } + Object.defineProperty(this, '$nativeObject', { + value: nativeMovieClip + }); + nativeMovieClip.$as2Object = this; + initDefaultListeners(this); + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + _as3Object: { + get: function () { + return this.$nativeObject; + } + }, + _init: def.init, + _insertChildAtDepth: def._insertChildAtDepth, + _duplicate: def._duplicate, + _constructSymbol: def._constructSymbol, + _callFrame: def._callFrame, + _gotoLabel: def._gotoLabel + } + }, + script: { + instance: Glue.ALL + } + }; + return def; + }.call(this); +var AS2MovieClipLoaderDefinition = function () { + var def = { + __class__: 'avm1lib.AS2MovieClipLoader', + initialize: function () { + }, + get _bytesLoaded() { + return this.$nativeObject._contentLoaderInfo._bytesLoaded; + } + }; + var desc = Object.getOwnPropertyDescriptor; + def.__glue__ = { + native: { + instance: { + $nativeObject: { + get: function () { + return this.$nativeObject; + } + }, + _bytesLoaded: desc(def, '_bytesLoaded') + } + }, + script: { + instance: Glue.ALL + } + }; + return def; + }.call(this); +var AS2TextFieldDefinition = function () { + var def = { + __class__: 'avm1lib.AS2TextField', + initialize: function () { + this._variable = ''; + } + }; + def.__glue__ = { + native: { + instance: { + variable: { + get: function () { + return this._variable; + }, + set: function (name) { + if (name === this._variable) { + return; + } + this._variable = name; + var instance = this.$nativeObject; + var hasPath = name.indexOf('.') >= 0 || name.indexOf(':') >= 0; + var clip; + if (hasPath) { + var targetPath = name.split(/[.:\/]/g); + name = targetPath.pop(); + if (targetPath[0] == '_root' || targetPath[0] === '') { + clip = instance.root._getAS2Object(); + targetPath.shift(); + if (targetPath[0] === '') { + targetPath.shift(); + } + } else { + clip = instance._parent._getAS2Object(); + } + while (targetPath.length > 0) { + var childName = targetPath.shift(); + clip = clip.asGetPublicProperty(childName) || clip[childName]; + if (!clip) { + throw new Error('Cannot find ' + childName + ' variable'); + } + } + } else { + clip = instance._parent._getAS2Object(); + } + if (!clip.asHasProperty(undefined, name, 0)) { + clip.asSetPublicProperty(name, instance.text); + } + instance._addEventListener('advanceFrame', function () { + instance.text = '' + clip.asGetPublicProperty(name); + }); + } + }, + _as3Object: { + get: function () { + return this.$nativeObject; + } + }, + _init: function init(nativeTextField) { + Object.defineProperty(this, '$nativeObject', { + value: nativeTextField + }); + nativeTextField.$as2Object = this; + initDefaultListeners(this); + } + } + }, + script: { + instance: Glue.ALL + } + }; + return def; + }.call(this); +var AS2UtilsDefinition = function () { + var def = { + __class__: 'avm1lib.AS2Utils', + initialize: function () { + } + }; + function installObjectMethods() { + var c = Stubs.Object, p = c.asGetPublicProperty('prototype'); + c.asSetPublicProperty('registerClass', function registerClass(name, theClass) { + var classes = AS2Context.instance.classes || (AS2Context.instance.classes = {}); + classes[name] = theClass; + }); + p.asDefinePublicProperty('addProperty', { + value: function addProperty(name, getter, setter) { + if (typeof name !== 'string' || name === '') { + return false; + } + if (typeof getter !== 'function') { + return false; + } + if (typeof setter !== 'function' && setter !== null) { + return false; + } + this.asDefinePublicProperty(name, { + get: getter, + set: setter || undefined, + configurable: true, + enumerable: true + }); + return true; + }, + writable: false, + enumerable: false, + configurable: false + }); + } + def.__glue__ = { + native: { + static: { + getAS2Object: function (nativeObject) { + return nativeObject && nativeObject._getAS2Object ? nativeObject._getAS2Object() : null; + }, + addProperty: function (obj, propertyName, getter, setter, enumerable) { + obj.asDefinePublicProperty(propertyName, { + get: getter, + set: setter || undefined, + enumerable: enumerable, + configurable: true + }); + }, + resolveTarget: function (target_mc) { + return AS2Context.instance.resolveTarget(target_mc); + }, + resolveLevel: function (level) { + return AS2Context.instance.resolveLevel(level); + }, + currentStage: { + get: function () { + return AS2Context.instance.stage; + } + }, + _installObjectMethods: installObjectMethods + } + } + }; + return def; + }.call(this); +function initDefaultListeners(thisArg) { + var defaultListeners = thisArg.asGetPublicProperty('$defaultListeners'); + if (!defaultListeners) { + return; + } + for (var i = 0; i < defaultListeners.length; i++) { + var p = defaultListeners[i]; + p.asGetPublicProperty('setter').call(thisArg, p.value); + } +} +function bindNativeClassDefinition(nativeName, definition) { + natives[nativeName] = function (domain, scope, instanceConstructor, baseClass) { + var c = new Class(undefined, instanceConstructor, ApplicationDomain.coerceCallable); + c.extend(baseClass); + c.linkNatives(definition); + return c; + }; +} +var Stubs = new function () { + var that = this; + var definitions = createEmptyObject(); + var DEFAULT_DEFINITION = { + __glue__: { + script: { + instance: Glue.ALL, + static: Glue.ALL + } + } + }; + this.getClassNames = function () { + return Object.keys(definitions); + }; + this.onClassCreated = function (eventType, cls) { + var classOriginalName = cls.classInfo.instanceInfo.name.getOriginalName(); + if (classOriginalName in definitions) { + cls.link(definitions[classOriginalName] || DEFAULT_DEFINITION); + } + }; + function makeStub(container, classSimpleName, shortName) { + Object.defineProperty(container, shortName, { + get: function () { + var cls = avm2.systemDomain.getClass(classSimpleName); + true; + Object.defineProperty(container, shortName, { + value: cls.instanceConstructor, + writable: false + }); + return container[shortName]; + }, + configurable: true + }); + } + [ + 'Boolean', + 'Date', + 'String', + 'Function', + 'Object', + 'Number', + 'Math', + 'Array', + 'RegExp' + ].forEach(function (classSimpleName) { + makeStub(that, classSimpleName, classSimpleName); + }); + [ + 'Error', + 'DefinitionError', + 'EvalError', + 'RangeError', + 'ReferenceError', + 'SecurityError', + 'SyntaxError', + 'TypeError', + 'URIError', + 'VerifyError', + 'UninitializedError', + 'ArgumentError' + ].forEach(function (classSimpleName) { + makeStub(that, classSimpleName, classSimpleName); + }); + function M(classSimpleName, nativeName, definition) { + return { + classSimpleName: classSimpleName, + nativeName: nativeName, + definition: definition + }; + } + [ + M('flash.display.DisplayObject', 'DisplayObjectClass', DisplayObjectDefinition), + M('flash.display.InteractiveObject', 'InteractiveObjectClass', InteractiveObjectDefinition), + M('flash.display.DisplayObjectContainer', 'ContainerClass', DisplayObjectContainerDefinition), + M('flash.display.Sprite', 'SpriteClass', SpriteDefinition), + M('flash.display.MovieClip', 'MovieClipClass', MovieClipDefinition), + M('flash.display.Shape', 'ShapeClass', ShapeDefinition), + M('flash.display.Bitmap', 'BitmapClass', BitmapDefinition), + M('flash.display.BitmapData', 'BitmapDataClass', BitmapDataDefinition), + M('flash.display.Stage', 'StageClass', StageDefinition), + M('flash.display.Loader', 'LoaderClass', LoaderDefinition), + M('flash.display.LoaderInfo', 'LoaderInfoClass', LoaderInfoDefinition), + M('flash.display.Graphics', 'GraphicsClass', GraphicsDefinition), + M('flash.display.SimpleButton', 'SimpleButtonClass', SimpleButtonDefinition), + M('flash.display.MorphShape', 'MorphShapeClass', MorphShapeDefinition), + M('flash.display.NativeMenu', 'MenuClass', NativeMenuDefinition), + M('flash.display.NativeMenuItem', 'MenuItemClass', NativeMenuItemDefinition), + M('flash.display.FrameLabel', 'FrameLabelClass', FrameLabelDefinition), + M('flash.display.Scene'), + M('flash.display.BlendMode'), + M('flash.display.Shader', 'ShaderClass', ShaderDefinition), + M('flash.display.ShaderData', 'ShaderDataClass', ShaderDataDefinition), + M('flash.filters.BevelFilter', 'BevelFilterClass', BevelFilterDefinition), + M('flash.filters.BitmapFilter', 'BitmapFilterClass', BitmapFilterDefinition), + M('flash.filters.BlurFilter', 'BlurFilterClass', BlurFilterDefinition), + M('flash.filters.ColorMatrixFilter', 'ColorMatrixFilterClass', ColorMatrixFilterDefinition), + M('flash.filters.ConvolutionFilter', 'ConvolutionFilterClass', ConvolutionFilterDefinition), + M('flash.filters.DisplacementMapFilter', 'DisplacementMapFilterClass', DisplacementMapFilterDefinition), + M('flash.filters.DropShadowFilter', 'DropShadowFilterClass', DropShadowFilterDefinition), + M('flash.filters.GlowFilter', 'GlowFilterClass', GlowFilterDefinition), + M('flash.filters.GradientBevelFilter', 'GradientBevelFilterClass', GradientBevelFilterDefinition), + M('flash.filters.GradientGlowFilter', 'GradientGlowFilterClass', GradientGlowFilterDefinition), + M('flash.filters.ShaderFilter', 'ShaderFilterClass', ShaderFilterDefinition), + M('flash.geom.Point', 'PointClass', PointDefinition), + M('flash.geom.Rectangle', 'RectangleClass', RectangleDefinition), + M('flash.geom.Matrix', 'MatrixClass', MatrixDefinition), + M('flash.geom.Matrix3D', 'Matrix3DClass', Matrix3DDefinition), + M('flash.geom.Vector3D', 'Vector3DClass', Vector3DDefinition), + M('flash.geom.Transform', 'TransformClass', TransformDefinition), + M('flash.geom.ColorTransform', 'ColorTransformClass', ColorTransformDefinition), + M('flash.events.EventDispatcher', 'EventDispatcherClass', EventDispatcherDefinition), + M('flash.events.Event', 'EventClass', EventDefinition), + M('flash.events.IOErrorEvent'), + M('flash.events.NetStatusEvent'), + M('flash.events.KeyboardEvent', 'KeyboardEventClass', KeyboardEventDefinition), + M('flash.events.MouseEvent', 'MouseEventClass', MouseEventDefinition), + M('flash.events.TextEvent', 'TextEventClass', TextEventDefinition), + M('flash.events.TimerEvent', 'TimerEventClass', TimerEventDefinition), + M('flash.events.ProgressEvent'), + M('flash.events.NetStatusEvent'), + M('flash.external.ExternalInterface', 'ExternalInterfaceClass', ExternalInterfaceDefinition), + M('flash.ui.ContextMenu', 'ContextMenuClass', ContextMenuDefinition), + M('flash.ui.ContextMenuItem', 'ContextMenuItemClass', ContextMenuItemDefinition), + M('flash.ui.Keyboard', 'KeyboardClass', KeyboardDefinition), + M('flash.ui.Mouse', 'MouseClass', MouseDefinition), + M('flash.ui.MouseCursorData', 'MouseCursorDataClass', MouseCursorDataDefinition), + M('flash.text.Font', 'FontClass', FontDefinition), + M('flash.text.TextField', 'TextFieldClass', TextFieldDefinition), + M('flash.text.StaticText', 'StaticTextClass', StaticTextDefinition), + M('flash.text.StyleSheet', 'StyleSheetClass', StyleSheetDefinition), + M('flash.text.TextFormat', 'TextFormatClass', TextFormatDefinition), + M('flash.text.TextLineMetrics'), + M('flash.text.engine.ContentElement', 'ContentElementClass', ContentElementDefinition), + M('flash.text.engine.ElementFormat', 'ElementFormatClass', ElementFormatDefinition), + M('flash.text.engine.FontDescription', 'FontDescriptionClass', FontDescriptionDefinition), + M('flash.text.engine.GroupElement', 'GroupElementClass', GroupElementDefinition), + M('flash.text.engine.SpaceJustifier', 'SpaceJustifierClass', SpaceJustifierDefinition), + M('flash.text.engine.TextBlock', 'TextBlockClass', TextBlockDefinition), + M('flash.text.engine.TextElement', 'TextElementClass', TextElementDefinition), + M('flash.text.engine.TextJustifier', 'TextJustifierClass', TextJustifierDefinition), + M('flash.text.engine.TextLine', 'TextLineClass', TextLineDefinition), + M('flash.media.Sound', 'SoundClass', SoundDefinition), + M('flash.media.SoundChannel', 'SoundChannelClass', SoundChannelDefinition), + M('flash.media.SoundMixer', 'SoundMixerClass', SoundMixerDefinition), + M('flash.media.SoundTransform', 'SoundTransformClass', SoundTransformDefinition), + M('flash.media.Video', 'VideoClass', VideoDefinition), + M('flash.media.ID3Info', 'ID3InfoClass', ID3InfoDefinition), + M('flash.media.Microphone', 'MicrophoneClass', MicrophoneDefinition), + M('flash.net.FileFilter', 'FileFilterClass', FileFilterDefinition), + M('flash.net.NetConnection', 'NetConnectionClass', NetConnectionDefinition), + M('flash.net.NetStream', 'NetStreamClass', NetStreamDefinition), + M('flash.net.Responder', 'ResponderClass', ResponderDefinition), + M('flash.net.URLRequest', 'URLRequestClass', URLRequestDefinition), + M('flash.net.URLStream', 'URLStreamClass', URLStreamDefinition), + M('flash.net.URLLoader', 'URLLoaderClass', URLLoaderDefinition), + M('flash.net.SharedObject', 'SharedObjectClass', SharedObjectDefinition), + M('flash.net.ObjectEncoding', 'ObjectEncodingClass', ObjectEncodingDefinition), + M('flash.net.LocalConnection', 'LocalConnectionClass', LocalConnectionDefinition), + M('flash.net.Socket', 'SocketClass', SocketDefinition), + M('flash.net.URLVariables'), + M('packageInternal flash.system.FSCommand', 'FSCommandClass', FSCommandDefinition), + M('flash.system.Capabilities', 'CapabilitiesClass', CapabilitiesDefinition), + M('flash.system.System', 'SystemClass', SystemDefinition), + M('flash.system.Security', 'SecurityClass', SecurityDefinition), + M('flash.system.SecurityDomain', 'SecurityDomainClass', SecurityDomainDefinition), + M('flash.system.ApplicationDomain', 'ApplicationDomainClass', ApplicationDomainDefinition), + M('flash.accessibility.Accessibility', 'AccessibilityClass', AccessibilityDefinition), + M('flash.utils.Timer', 'TimerClass', TimerDefinition), + M('avm1lib.AS2Utils', 'AS2Utils', AS2UtilsDefinition), + M('avm1lib.AS2Broadcaster'), + M('avm1lib.AS2Key'), + M('avm1lib.AS2Mouse'), + M('avm1lib.AS2MovieClip', 'AS2MovieClip', AS2MovieClipDefinition), + M('avm1lib.AS2Button', 'AS2Button', AS2ButtonDefinition), + M('avm1lib.AS2TextField', 'AS2TextField', AS2TextFieldDefinition), + M('avm1lib.AS2Stage'), + M('avm1lib.AS2System'), + M('avm1lib.AS2Color'), + M('avm1lib.AS2Globals', 'AS2Globals', AS2GlobalsDefinition), + M('avm1lib.AS2MovieClipLoader', 'AS2MovieClipLoader', AS2MovieClipLoaderDefinition) + ].forEach(function (m) { + var className = Multiname.fromSimpleName(m.classSimpleName); + var path = className.getOriginalName().split('.'); + var container = this; + for (var i = 0, j = path.length - 1; i < j; i++) { + if (!container[path[i]]) { + container[path[i]] = {}; + } + container = container[path[i]]; + } + makeStub(container, m.classSimpleName, path[path.length - 1]); + if (m.nativeName) { + bindNativeClassDefinition(m.nativeName, m.definition); + } + definitions[className.getOriginalName()] = m.definition; + }); + }(); +natives['FlashUtilScript::getAliasName'] = function (domain, scope, instanceConstructor, baseClass) { + return function getAliasName(value) { + return value.debugName; + }; +}; +natives['FlashUtilScript::getDefinitionByName'] = natives.getDefinitionByName; +natives['FlashUtilScript::getTimer'] = function GetTimerMethod(domain, scope, instanceConstructor, baseClass) { + var start = Date.now(); + return function getTimer() { + return Date.now() - start; + }; +}; +natives['FlashUtilScript::escapeMultiByte'] = function EscapeMultiByteMethod(domain, scope, instanceConstructor, baseClass) { + return escape; +}; +natives['FlashUtilScript::unescapeMultiByte'] = function UnescapeMultiByteMethod(domain, scope, instanceConstructor, baseClass) { + return unescape; +}; +natives['FlashNetScript::navigateToURL'] = function GetNavigateToURLMethod(domain, scope, instanceConstructor, baseClass) { + return function navigateToURL(request, window_) { + if (request === null || request === undefined) { + throwError('TypeError', Errors.NullPointerError, 'request'); + } + var RequestClass = avm2.systemDomain.getClass('flash.net.URLRequest'); + if (!RequestClass.isInstanceOf(request)) { + throwError('TypeError', Errors.CheckTypeFailedError, request, 'flash.net.URLRequest'); + } + var url = request.url; + if (/^fscommand:/i.test(url)) { + var fscommand = avm2.applicationDomain.getProperty(Multiname.fromSimpleName('flash.system.fscommand'), true, true); + fscommand.call(null, url.substring('fscommand:'.length), window_); + return; + } + var targetWindow = window_ || '_parent'; + window.open(FileLoadingService.resolveUrl(url), targetWindow); + }; +}; +natives['FlashNetScript::sendToURL'] = function GetSendToURLMethod(domain, scope, instanceConstructor, baseClass) { + return function sendToURL(request) { + if (request === null || request === undefined) { + throwError('TypeError', Errors.NullPointerError, 'request'); + } + var RequestClass = avm2.systemDomain.getClass('flash.net.URLRequest'); + if (!RequestClass.isInstanceOf(request)) { + throwError('TypeError', Errors.CheckTypeFailedError, request, 'flash.net.URLRequest'); + } + var session = FileLoadingService.createSession(); + session.onprogress = function () { + }; + session.open(request); + }; +}; +natives['Toplevel::registerClassAlias'] = function GetRegisterClassAliasMethod(domain, scope, instance, baseClass) { + return function registerClassAlias(aliasName, classObject) { + if (!aliasName) { + throwError('TypeError', Errors.NullPointerError, 'aliasName'); + } + if (!classObject) { + throwError('TypeError', Errors.NullPointerError, 'classObject'); + } + AMFUtils.aliasesCache.classes.set(classObject, aliasName); + AMFUtils.aliasesCache.names[aliasName] = classObject; + }; +}; +natives['Toplevel::getClassByAlias'] = function GetGetClassByAliasMethod(domain, scope, instance, baseClass) { + return function getClassByAlias(aliasName) { + if (!aliasName) { + throwError('TypeError', Errors.NullPointerError, 'aliasName'); + } + var classObject = AMFUtils.aliasesCache.names[aliasName]; + if (!classObject) { + throwError('ReferenceError', Errors.ClassNotFoundError, aliasName); + } + return classObject; + }; +};